summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoritsGarrin <garrin.shieh@gmail.com>2024-11-05 15:41:24 -0500
committeritsGarrin <garrin.shieh@gmail.com>2024-11-05 15:41:24 -0500
commitfeb047071ab7f7a688d2f3925d07d757b4b37d7d (patch)
treef3a9d00e6ea60de7e98e945cd083cd54a7cdba5e
parent1cbe6a267628509c24d32b458363ddb74cb82838 (diff)
hi
-rw-r--r--ZestySalesman.ipynb235
-rw-r--r--utils.py23
2 files changed, 155 insertions, 103 deletions
diff --git a/ZestySalesman.ipynb b/ZestySalesman.ipynb
index 60dd19e..8e4372c 100644
--- a/ZestySalesman.ipynb
+++ b/ZestySalesman.ipynb
@@ -2,70 +2,68 @@
"cells": [
{
"cell_type": "code",
- "execution_count": 1,
"id": "initial_id",
"metadata": {
+ "collapsed": true,
"ExecuteTime": {
- "end_time": "2023-11-07T23:05:35.179983Z",
- "start_time": "2023-11-07T23:05:34.039783Z"
- },
- "collapsed": true
+ "end_time": "2024-07-02T22:37:51.219877Z",
+ "start_time": "2024-07-02T22:37:50.303317Z"
+ }
},
- "outputs": [],
"source": [
"import pandas as pd\n",
"import folium\n",
"import utils"
- ]
+ ],
+ "outputs": [],
+ "execution_count": 1
},
{
"cell_type": "code",
- "execution_count": 2,
"id": "73b780e762c9de37",
"metadata": {
"ExecuteTime": {
- "end_time": "2023-11-07T23:05:35.194166Z",
- "start_time": "2023-11-07T23:05:35.181233Z"
+ "end_time": "2024-07-02T22:37:51.229897Z",
+ "start_time": "2024-07-02T22:37:51.220757Z"
}
},
- "outputs": [],
"source": [
"# Load the data\n",
"ListA = pd.read_csv('List A.csv')\n",
"ListB = pd.read_csv('List B.csv')\n",
"ListC = pd.read_csv('List C.csv')\n",
"ListD = pd.read_csv('List D.csv')"
- ]
+ ],
+ "outputs": [],
+ "execution_count": 2
},
{
"cell_type": "code",
- "execution_count": 3,
"id": "be4c8c1d77842ef7",
"metadata": {
"ExecuteTime": {
- "end_time": "2023-11-07T23:05:35.195314Z",
- "start_time": "2023-11-07T23:05:35.193156Z"
+ "end_time": "2024-07-02T22:37:51.231873Z",
+ "start_time": "2024-07-02T22:37:51.230471Z"
}
},
- "outputs": [],
"source": [
"# Create two centroids, one in the North End and one in the Seaport District\n",
"centroids = [[42.365, -71.054], [42.351, -71.045]]\n",
"\n",
"northeastern_coordinate = \"-71.09033,42.33976\""
- ]
+ ],
+ "outputs": [],
+ "execution_count": 3
},
{
"cell_type": "code",
- "execution_count": 4,
"id": "ffe4025e97a6c6b9",
"metadata": {
"ExecuteTime": {
- "end_time": "2023-11-07T23:05:35.201800Z",
- "start_time": "2023-11-07T23:05:35.197747Z"
+ "end_time": "2024-07-02T22:37:51.235758Z",
+ "start_time": "2024-07-02T22:37:51.232888Z"
}
},
- "outputs": [],
"source": [
"# Combine the two lists and add a column to indicate the list\n",
"ListA['list'] = 'A'\n",
@@ -73,55 +71,76 @@
"ListC['list'] = 'C'\n",
"ListD['list'] = 'D'\n",
"\n",
- "TotalList = pd.concat([ListA, ListB, ListC, ListD])"
- ]
+ "#TotalList = pd.concat([ListA, ListB, ListC, ListD])\n",
+ "TotalList = pd.concat([ListA, ListB])"
+ ],
+ "outputs": [],
+ "execution_count": 4
},
{
"cell_type": "code",
- "execution_count": 5,
"id": "72657779b4484aae",
"metadata": {
"ExecuteTime": {
- "end_time": "2023-11-07T23:05:35.215762Z",
- "start_time": "2023-11-07T23:05:35.200811Z"
+ "end_time": "2024-07-02T22:37:51.238164Z",
+ "start_time": "2024-07-02T22:37:51.236334Z"
}
},
- "outputs": [],
"source": [
"# Remove all columns but name and gps\n",
"TotalList = TotalList[['name', 'gps', 'list']]"
- ]
+ ],
+ "outputs": [],
+ "execution_count": 5
},
{
"cell_type": "code",
- "execution_count": 6,
"id": "a157ffaec020a29a",
"metadata": {
"ExecuteTime": {
- "end_time": "2023-11-07T23:05:35.215916Z",
- "start_time": "2023-11-07T23:05:35.204173Z"
+ "end_time": "2024-07-02T22:37:51.356176Z",
+ "start_time": "2024-07-02T22:37:51.353712Z"
}
},
- "outputs": [],
"source": [
"# Convert the gps column to a list of lists for k-means\n",
"TotalList['gps'] = TotalList['gps'].apply(lambda x: x.strip('[]').split(','))\n",
"TotalList['gps'] = TotalList['gps'].apply(lambda x: [float(i) for i in x])"
- ]
+ ],
+ "outputs": [],
+ "execution_count": 6
},
{
"cell_type": "code",
- "execution_count": 7,
"id": "a03ebde91b87fa3b",
"metadata": {
"ExecuteTime": {
- "end_time": "2023-11-07T23:05:35.216384Z",
- "start_time": "2023-11-07T23:05:35.206794Z"
+ "end_time": "2024-07-02T22:37:52.039978Z",
+ "start_time": "2024-07-02T22:37:52.032015Z"
}
},
+ "source": [
+ "display(TotalList)"
+ ],
"outputs": [
{
"data": {
+ "text/plain": [
+ " name gps list\n",
+ "0 521 Commercial Street #525 [42.3688272, -71.0553792] A\n",
+ "1 Acorn St [42.3576234, -71.0688746] A\n",
+ "2 Arlington's Great Meadows [42.4299758, -71.2038948] A\n",
+ "3 Arthur Fiedler Statue [42.3565057, -71.0754527] A\n",
+ "4 BU Beach [42.3511927, -71.1060828] A\n",
+ ".. ... ... ...\n",
+ "31 Union Square [42.37736, -71.09476] B\n",
+ "32 University Park Commons [42.3614115, -71.1014951] B\n",
+ "33 Veggie Crust - Somerville [42.3822934, -71.1024769] B\n",
+ "34 Veggie Galaxy [42.3636597, -71.1011111] B\n",
+ "35 Warren Tavern [42.3741694, -71.0631664] B\n",
+ "\n",
+ "[98 rows x 3 columns]"
+ ],
"text/html": [
"<div>\n",
"<style scoped>\n",
@@ -184,64 +203,46 @@
" <td>...</td>\n",
" </tr>\n",
" <tr>\n",
- " <th>33</th>\n",
- " <td>The Quiet Few</td>\n",
- " <td>[42.3670906, -71.0359889]</td>\n",
- " <td>D</td>\n",
+ " <th>31</th>\n",
+ " <td>Union Square</td>\n",
+ " <td>[42.37736, -71.09476]</td>\n",
+ " <td>B</td>\n",
" </tr>\n",
" <tr>\n",
- " <th>34</th>\n",
- " <td>The Tall Ship Boston</td>\n",
- " <td>[42.3649544, -71.0414523]</td>\n",
- " <td>D</td>\n",
+ " <th>32</th>\n",
+ " <td>University Park Commons</td>\n",
+ " <td>[42.3614115, -71.1014951]</td>\n",
+ " <td>B</td>\n",
" </tr>\n",
" <tr>\n",
- " <th>35</th>\n",
- " <td>Toasted Flats</td>\n",
- " <td>[42.3711266, -71.0371343]</td>\n",
- " <td>D</td>\n",
+ " <th>33</th>\n",
+ " <td>Veggie Crust - Somerville</td>\n",
+ " <td>[42.3822934, -71.1024769]</td>\n",
+ " <td>B</td>\n",
" </tr>\n",
" <tr>\n",
- " <th>36</th>\n",
- " <td>Vega Market</td>\n",
- " <td>[42.3891835, -71.033703]</td>\n",
- " <td>D</td>\n",
+ " <th>34</th>\n",
+ " <td>Veggie Galaxy</td>\n",
+ " <td>[42.3636597, -71.1011111]</td>\n",
+ " <td>B</td>\n",
" </tr>\n",
" <tr>\n",
- " <th>37</th>\n",
- " <td>Winthrop High School</td>\n",
- " <td>[42.3803348, -70.9799864]</td>\n",
- " <td>D</td>\n",
+ " <th>35</th>\n",
+ " <td>Warren Tavern</td>\n",
+ " <td>[42.3741694, -71.0631664]</td>\n",
+ " <td>B</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
- "<p>169 rows × 3 columns</p>\n",
+ "<p>98 rows × 3 columns</p>\n",
"</div>"
- ],
- "text/plain": [
- " name gps list\n",
- "0 521 Commercial Street #525 [42.3688272, -71.0553792] A\n",
- "1 Acorn St [42.3576234, -71.0688746] A\n",
- "2 Arlington's Great Meadows [42.4299758, -71.2038948] A\n",
- "3 Arthur Fiedler Statue [42.3565057, -71.0754527] A\n",
- "4 BU Beach [42.3511927, -71.1060828] A\n",
- ".. ... ... ...\n",
- "33 The Quiet Few [42.3670906, -71.0359889] D\n",
- "34 The Tall Ship Boston [42.3649544, -71.0414523] D\n",
- "35 Toasted Flats [42.3711266, -71.0371343] D\n",
- "36 Vega Market [42.3891835, -71.033703] D\n",
- "37 Winthrop High School [42.3803348, -70.9799864] D\n",
- "\n",
- "[169 rows x 3 columns]"
]
},
"metadata": {},
"output_type": "display_data"
}
],
- "source": [
- "display(TotalList)"
- ]
+ "execution_count": 7
},
{
"cell_type": "markdown",
@@ -261,14 +262,21 @@
},
{
"cell_type": "code",
- "execution_count": 8,
"id": "ee9b3c1ecb360976",
"metadata": {
"ExecuteTime": {
- "end_time": "2023-11-07T23:06:04.963804Z",
- "start_time": "2023-11-07T23:05:35.213646Z"
+ "end_time": "2024-07-02T22:38:01.527682Z",
+ "start_time": "2024-07-02T22:37:53.433734Z"
}
},
+ "source": [
+ "# Cluster and minimize the data\n",
+ "_, routes = utils.cluster_and_optimize(TotalList, centroids, northeastern_coordinate,\n",
+ " time_diff=0.25, max_time=24, host='http://router.project-osrm.org')\n",
+ "\n",
+ "route_1_coordinates = routes[0]\n",
+ "route_2_coordinates = routes[1]"
+ ],
"outputs": [
{
"name": "stderr",
@@ -279,16 +287,43 @@
"/Users/garrinshieh/anaconda3/lib/python3.11/site-packages/sklearn/cluster/_kmeans.py:1412: RuntimeWarning: Explicit initial center position passed: performing only one init in KMeans instead of n_init=10.\n",
" super()._check_params_vs_input(X, default_n_init=10)\n"
]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "{'code': 'Ok', 'trips': [{'geometry': '{kqaG|utpLwFzHtDL|DgI`ClC_DzKtAyEaAdOsK|FdAxN`AoG{KeS`D{FSoJkFlMF{DnDrRoVnRqEoHdO~GyCpAg^md@|EsBuK{AiDlJ}KeAkGdYpJfC`A}DdYdNvF_F~GvCuE`MlCxBxHaDoEuQcf@an@_aAw{@{Zeo@jYrn@b~Ab}AlQx`@TbRwExHaEkApG_TtdA{rA~X{B|Z|o@dj@rN~BmXvHqNkd@ky@f@mQzKqZqLgQqBmBtBrXoIjXc@`VoIpOwJ}GeIxQqM{ByT|HnEHzA|QsB_E~DjOdKd@kBdFy@{KmQnAiHMrDsFpD`JlGaBcArNrFdFeHdOVlGfDaC~I|RkGs\\\\P{InNdO|B|AjHpCs@uN{Fy@sA`JnYtIBdKkGLF{M~FfAcAj]~F\\\\hFfMjExAuLaP^_L|@aG_YzGyL|Gt@hJfBfF`O{FrWzyAwEoBbCaE~Enm@gQ]i\\\\keBkCkJiR{EGmKjKiDaGlEDnKmOmI_Dbt@xFzAvInn@yJ~EqAbMnJvUqXfi@bDqGdIzIO~GqFkGrCiCwEeF|AsSm@yf@kT_FdByf@uKiHrAgSiT}CjDcJtBqKcr@n`ByYrG{RrOrHaGbHvJjCcC{AhGrKQK`E\\\\_FrKpCwGsEwBd[cG}AnCgDrBdGyOp[J|@jIzI`IgBjLz{@}HtB|HuBAvKsIK_YpAeEcVkRnVa@xPqHt@y@Sb\\\\gt@cw@`{@eMqDqGtRxK`Z_DrDdKjQQ|K`[Aa[@wBxn@yU~E_TheAuUdk@m]jxAcRiPjDyKkDxKjGzHqRzg@{d@fRsVz@qG|gAmLbl@~@tOcIxMQgJPfJxl@zLvJuBhOyVfEt@O`J_DHc@kM`K}z@jbA_xExToi@xSmbAlDqHzPsBjc@vRfc@mmAnm@yjAqDoGfKof@fLbLoIh`@mPlBfDCnJYjArIkExDjCbHnLkLtq@bm@wCy|@tRaDkRwv@oDZtBbk@jj@wD~V}[`UrAbI}]l]yIfZs_@lHoU{Ke_@', 'legs': [{'steps': [], 'summary': '', 'weight': 66.5, 'duration': 56.2, 'distance': 331.9}, {'steps': [], 'summary': '', 'weight': 109.4, 'duration': 109.4, 'distance': 620.6}, {'steps': [], 'summary': '', 'weight': 151.9, 'duration': 129.4, 'distance': 786.4}, {'steps': [], 'summary': '', 'weight': 141.4, 'duration': 118.9, 'distance': 665.7}, {'steps': [], 'summary': '', 'weight': 76.8, 'duration': 76.8, 'distance': 524.2}, {'steps': [], 'summary': '', 'weight': 210, 'duration': 210, 'distance': 1394.8}, {'steps': [], 'summary': '', 'weight': 3433.2, 'duration': 158.4, 'distance': 1083.1}, {'steps': [], 'summary': '', 'weight': 135.2, 'duration': 135.2, 'distance': 1101.4}, {'steps': [], 'summary': '', 'weight': 104.9, 'duration': 104.9, 'distance': 852}, {'steps': [], 'summary': '', 'weight': 73.1, 'duration': 73.1, 'distance': 674.7}, {'steps': [], 'summary': '', 'weight': 396.8, 'duration': 396.8, 'distance': 7456.3}, {'steps': [], 'summary': '', 'weight': 196.7, 'duration': 196.7, 'distance': 3629.5}, {'steps': [], 'summary': '', 'weight': 341.5, 'duration': 341.5, 'distance': 3566.8}, {'steps': [], 'summary': '', 'weight': 11.5, 'duration': 11.5, 'distance': 79.5}, {'steps': [], 'summary': '', 'weight': 285.4, 'duration': 285.4, 'distance': 2644.5}, {'steps': [], 'summary': '', 'weight': 96.1, 'duration': 96.1, 'distance': 641.6}, {'steps': [], 'summary': '', 'weight': 40.1, 'duration': 40.1, 'distance': 302.1}, {'steps': [], 'summary': '', 'weight': 48.6, 'duration': 48.6, 'distance': 387.9}, {'steps': [], 'summary': '', 'weight': 87.9, 'duration': 87.9, 'distance': 548.4}, {'steps': [], 'summary': '', 'weight': 123.4, 'duration': 123.4, 'distance': 893.9}, {'steps': [], 'summary': '', 'weight': 138.5, 'duration': 123, 'distance': 811.6}, {'steps': [], 'summary': '', 'weight': 78.5, 'duration': 63, 'distance': 401.9}, {'steps': [], 'summary': '', 'weight': 52.8, 'duration': 52.8, 'distance': 419.3}, {'steps': [], 'summary': '', 'weight': 68.2, 'duration': 68.2, 'distance': 501.5}, {'steps': [], 'summary': '', 'weight': 10.9, 'duration': 10.9, 'distance': 80}, {'steps': [], 'summary': '', 'weight': 67.6, 'duration': 67.6, 'distance': 439.4}, {'steps': [], 'summary': '', 'weight': 26.1, 'duration': 26.1, 'distance': 196}, {'steps': [], 'summary': '', 'weight': 149.8, 'duration': 146.7, 'distance': 1075.5}, {'steps': [], 'summary': '', 'weight': 174.8, 'duration': 171.7, 'distance': 1284.1}, {'steps': [], 'summary': '', 'weight': 99, 'duration': 99, 'distance': 707.9}, {'steps': [], 'summary': '', 'weight': 103.3, 'duration': 88.5, 'distance': 612.7}, {'steps': [], 'summary': '', 'weight': 338.7, 'duration': 304.2, 'distance': 2310.6}, {'steps': [], 'summary': '', 'weight': 273.1, 'duration': 247.7, 'distance': 2558.6}, {'steps': [], 'summary': '', 'weight': 97.8, 'duration': 97.8, 'distance': 924.5}, {'steps': [], 'summary': '', 'weight': 430.6, 'duration': 408.3, 'distance': 2982.5}, {'steps': [], 'summary': '', 'weight': 269.4, 'duration': 269.4, 'distance': 1207.2}, {'steps': [], 'summary': '', 'weight': 46.8, 'duration': 46.8, 'distance': 376.5}, {'steps': [], 'summary': '', 'weight': 44, 'duration': 44, 'distance': 344.5}, {'steps': [], 'summary': '', 'weight': 117.7, 'duration': 117.7, 'distance': 578.5}, {'steps': [], 'summary': '', 'weight': 239.7, 'duration': 239.7, 'distance': 1794.7}, {'steps': [], 'summary': '', 'weight': 139, 'duration': 125.6, 'distance': 950}, {'steps': [], 'summary': '', 'weight': 303.3, 'duration': 292.7, 'distance': 3157.8}, {'steps': [], 'summary': '', 'weight': 89.8, 'duration': 89.8, 'distance': 568.6}, {'steps': [], 'summary': '', 'weight': 80.8, 'duration': 80.8, 'distance': 472.3}, {'steps': [], 'summary': '', 'weight': 131.9, 'duration': 128.1, 'distance': 809.9}, {'steps': [], 'summary': '', 'weight': 27.5, 'duration': 27.5, 'distance': 135.9}, {'steps': [], 'summary': '', 'weight': 128, 'duration': 128, 'distance': 795.1}, {'steps': [], 'summary': '', 'weight': 17, 'duration': 13.2, 'distance': 38.8}, {'steps': [], 'summary': '', 'weight': 210, 'duration': 206.2, 'distance': 1516.1}, {'steps': [], 'summary': '', 'weight': 54.4, 'duration': 54.4, 'distance': 391.2}, {'steps': [], 'summary': '', 'weight': 54.7, 'duration': 40.7, 'distance': 234.9}, {'steps': [], 'summary': '', 'weight': 157.9, 'duration': 143.9, 'distance': 927.8}, {'steps': [], 'summary': '', 'weight': 127.2, 'duration': 127.2, 'distance': 905.6}, {'steps': [], 'summary': '', 'weight': 13.1, 'duration': 13.1, 'distance': 50.7}, {'steps': [], 'summary': '', 'weight': 153.7, 'duration': 142.8, 'distance': 938.5}, {'steps': [], 'summary': '', 'weight': 282.6, 'duration': 271.7, 'distance': 1981.5}, {'steps': [], 'summary': '', 'weight': 245.8, 'duration': 234.8, 'distance': 1581.2}, {'steps': [], 'summary': '', 'weight': 439.5, 'duration': 428.5, 'distance': 5189}, {'steps': [], 'summary': '', 'weight': 402.8, 'duration': 402.8, 'distance': 4550.8}, {'steps': [], 'summary': '', 'weight': 934.7, 'duration': 934.7, 'distance': 12430.2}, {'steps': [], 'summary': '', 'weight': 133.7, 'duration': 133.7, 'distance': 845.7}, {'steps': [], 'summary': '', 'weight': 50.8, 'duration': 50.8, 'distance': 454.3}, {'steps': [], 'summary': '', 'weight': 55.2, 'duration': 55.2, 'distance': 368.3}, {'steps': [], 'summary': '', 'weight': 263.5, 'duration': 263.5, 'distance': 1808.2}, {'steps': [], 'summary': '', 'weight': 230.9, 'duration': 230.9, 'distance': 2009.7}, {'steps': [], 'summary': '', 'weight': 443, 'duration': 443, 'distance': 4945.3}], 'weight_name': 'routability', 'weight': 14128.5, 'duration': 10557, 'distance': 95850.199999999}], 'waypoints': [{'waypoint_index': 0, 'trips_index': 0, 'hint': '9ZZdgPuWXYAQAAAAOQAAAAQAAAAAAAAALfXwQNqLykHq2No_AAAAAAgAAAAdAAAAAgAAAAAAAABYYwAAr83D-xBwhgJQzcP7SHCGAgEArw07mOnR', 'distance': 9.995831753, 'name': 'North Bennet Place', 'location': [-71.053905, 42.364944]}, {'waypoint_index': 5, 'trips_index': 0, 'hint': 'XsR5hpFy74kDAAAAEAAAAAAAAACPAAAAlkVDQMMSZEEAAAAActEAQwMAAAAQAAAAAAAAAI8AAABYYwAAzMbD-8d8hgLtx8P7O3-GAgAAzwY7mOnR', 'distance': 73.70776153, 'name': 'Commercial Street', 'location': [-71.055668, 42.368199]}, {'waypoint_index': 34, 'trips_index': 0, 'hint': '-lVdgP___38BAAAAJgAAADEAAAAGAAAAuPe1P_VeA0IVEDJCxQGrQAEAAAAmAAAAMQAAAAYAAABYYwAAnJHD-wRThgI1k8P7d1OGAgIA_wk7mOnR', 'distance': 36.027035397, 'name': 'West Cedar Street', 'location': [-71.069284, 42.357508]}, {'waypoint_index': 59, 'trips_index': 0, 'hint': 'nc1Yg3J_vIMAAAAAGAAAAAAAAAA5AQAAAAAAAHNB2EAAAAAA43GtQgAAAAAYAAAAAAAAADkBAABYYwAA-H7B-xdrhwLJg8H7GG6HAgAAfxE7mOnR', 'distance': 132.640565965, 'name': '', 'location': [-71.205128, 42.429207]}, {'waypoint_index': 33, 'trips_index': 0, 'hint': '5_pdgP___38RAAAAagAAAEgAAABBAAAAhJuYQQoOvUIPa5tCBkeKQhEAAABqAAAASAAAAEEAAABYYwAAJXvD-8dLhgKDecP7Gk-GAgUAbwQ7mOnR', 'distance': 100.603650179, 'name': 'Storrow Drive', 'location': [-71.075035, 42.355655]}, {'waypoint_index': 23, 'trips_index': 0, 'hint': 'hVVdgP___38nAAAAOAAAABEAAAAAAAAAc_AMQgDdaEGtqnRBAAAAACcAAAA4AAAAEQAAAAAAAABYYwAAUa3D-05VhgLArcP7m1SGAgEAHwQ7mOnR', 'distance': 21.884493732, 'name': 'Beacon Street', 'location': [-71.062191, 42.358094]}, {'waypoint_index': 18, 'trips_index': 0, 'hint': 'z1VdgP___38dAAAAKAAAAAUAAAAeAAAA-6HQQbBSGUH8c5ZACtMMQR0AAAAoAAAABQAAAB4AAABYYwAA3LvD-yZShgJXu8P7bVKGAgEAPwI7mOnR', 'distance': 13.497972145, 'name': 'Washington Street', 'location': [-71.058468, 42.357286]}, {'waypoint_index': 17, 'trips_index': 0, 'hint': 'W6ZdgP___38QAAAAFwAAABUAAAAdAAAA7Y5tQfNntkAFIZdBZcvMQRAAAAAXAAAAFQAAAB0AAABYYwAAE8HD-65XhgLOwMP761eGAgQAXw47mOnR', 'distance': 8.843623967, 'name': 'Devonshire Street', 'location': [-71.057133, 42.358702]}, {'waypoint_index': 1, 'trips_index': 0, 'hint': 'wthdgP___38gAAAAJQAAAAAAAAAFAAAApPnoQU1zcUAAAAAAvJGYQCAAAAAlAAAAAAAAAAUAAABYYwAANcfD-1ZxhgL1xsP7GnGGAgAADwg7mOnR', 'distance': 8.4973874, 'name': 'Prince Street', 'location': [-71.055563, 42.36527]}, {'waypoint_index': 29, 'trips_index': 0, 'hint': 'uDVegP___38NAAAAIQAAAAsAAAAAAAAAjNRCQRA0ikEcDR1BAAAAAA0AAAAhAAAACwAAAAAAAABYYwAAL4bD-7QxhgKjhsP7ZDGGAgEA_w07mOnR', 'distance': 13.053440062, 'name': 'Stanhope Street', 'location': [-71.072209, 42.34898]}, {'waypoint_index': 30, 'trips_index': 0, 'hint': 'u4tdgP___38GAAAAMgAAAAAAAAAAAAAAOFW-QDE5G0IAAAAAAAAAAAYAAAAyAAAAAAAAAAAAAABYYwAAMpfD-6k1hgItl8P7uDWGAgAAvwQ7mOnR', 'distance': 1.716409362, 'name': 'Piedmont Street', 'location': [-71.067854, 42.349993]}, {'waypoint_index': 24, 'trips_index': 0, 'hint': 'W1ZdgP___38WAAAAFwAAAAAAAAAyAAAAmfygQewAMT8AAAAA6hA0QhYAAAAXAAAAAAAAADIAAABYYwAAA6rD-z9LhgJcqcP7n0uGAgAAnw07mOnR', 'distance': 17.404100972, 'name': 'Tremont Street', 'location': [-71.063037, 42.355519]}, {'waypoint_index': 57, 'trips_index': 0, 'hint': '_j9dgOJiZYo0AAAAgwAAAOIAAABBAAAAEyEwQTgj2EHezjtCooBZQRoAAABBAAAAcQAAACEAAABYYwAAPZnC-xXOhgJRmML7Dc6GAgMAXxY7mOnR', 'distance': 19.457862614, 'name': '', 'location': [-71.132867, 42.389013]}, {'waypoint_index': 32, 'trips_index': 0, 'hint': '0FtdgP___38UAAAAPwAAAEgAAAAhAAAAW6uQQQeRGkKS7IFCJdQwQRQAAAA_AAAASAAAACEAAABYYwAA0FPD-wY1hgJ7U8P7szWGAgMAbwQ7mOnR', 'distance': 20.4541791, 'name': 'Commonwealth Avenue', 'location': [-71.085104, 42.34983]}, {'waypoint_index': 31, 'trips_index': 0, 'hint': 'T3RdgP___3-iAAAA9QAAAIcAAADgAAAAA1kHQtaniUH5EuFBU9w6QlEAAAB7AAAARAAAAHAAAABYYwAAsZbD-6xEhgLSnMP7eEaGAgEALxU7mOnR', 'distance': 138.962162697, 'name': '', 'location': [-71.067983, 42.353836]}, {'waypoint_index': 19, 'trips_index': 0, 'hint': 'sAzJi____38GAAAAHQAAAA4AAAAnAAAASMi7QCgnn0ExlUdBBrQOQgYAAAAdAAAADgAAACcAAABYYwAAVsLD-9VehgK7wcP7r16GAgEAXxU7mOnR', 'distance': 13.445931288, 'name': 'Union Street', 'location': [-71.05681, 42.360533]}, {'waypoint_index': 26, 'trips_index': 0, 'hint': 'Ny5egPEyXoAnAAAAKwAAAAoAAAAAAAAAMBgOQgJrGEKX2RVBAAAAACcAAAArAAAACgAAAAAAAABYYwAAIa_D-_RDhgKcr8P7hkSGAgEAnwc7mOnR', 'distance': 19.121839672, 'name': 'Avenue De Lafayette', 'location': [-71.061727, 42.353652]}, {'waypoint_index': 14, 'trips_index': 0, 'hint': 'C-ldgPWgFIoVAAAAIQAAAEMBAAAAAAAA9xN0QZP9skHYkGBDAAAAABUAAAAhAAAAQwEAAAAAAABYYwAAMBbE-w4vhgLZE8T7AzCGAhAAHw07mOnR', 'distance': 56.377729675, 'name': '', 'location': [-71.035344, 42.348302]}, {'waypoint_index': 21, 'trips_index': 0, 'hint': '11VdgLxEXoB7AAAAEwAAAB4BAAAiAQAA4IywQZv0UUDWlExCS9BOQj0AAAAKAAAAjwAAAJAAAABYYwAAR6fD--lWhgL-psP7-VeGAgQALxA7mOnR', 'distance': 30.806337221, 'name': 'Mount Vernon Street', 'location': [-71.063737, 42.358505]}, {'waypoint_index': 58, 'trips_index': 0, 'hint': 'CnJfgEx6X4AWAAAAAAAAAAAAAAAAAAAA_-1vQQAAAAAAAAAAAAAAABYAAAAAAAAAAAAAAAAAAABYYwAAWArC-yUnhwKSEML7JSOHAgAAHwc7mOnR', 'distance': 173.629294993, 'name': 'Ottawa Road', 'location': [-71.169448, 42.411813]}, {'waypoint_index': 56, 'trips_index': 0, 'hint': 'ry2MgP___38HAAAACgAAAA0AAAAkAAAAKImmQKvEzz_R3hZBG9cwQQcAAAAKAAAADQAAACQAAABYYwAALsHC-8LrhgLYwML7ouuGAgEAnwk7mOnR', 'distance': 7.925051729, 'name': 'Holland Street', 'location': [-71.122642, 42.39661]}, {'waypoint_index': 52, 'trips_index': 0, 'hint': 'nABdgIkDyoMPAAAAFAAAAA4AAAAAAAAAS1IyQXbvYEGggCBBAAAAAA8AAAAUAAAADgAAAAAAAABYYwAAwujC-8e4hgIi6ML7B7mGAgMAzwE7mOnR', 'distance': 14.973308394, 'name': 'Sacramento Street', 'location': [-71.11251, 42.383559]}, {'waypoint_index': 2, 'trips_index': 0, 'hint': 'nCtegP___38KAAAAFQAAAAsAAAAAAAAAxw4QQUJuG0FMSyJBAAAAAAoAAAAVAAAACwAAAAAAAABYYwAAEcfD-4lshgJ0x8P7bmyGAgIATwE7mOnR', 'distance': 8.687980263, 'name': 'Salem Street', 'location': [-71.055599, 42.364041]}, {'waypoint_index': 53, 'trips_index': 0, 'hint': 'IXZ5g____38WAAAANAAAAAQAAAAmAAAARVSBQTt9qEFhlj1AuQhXQRYAAAA0AAAABAAAACYAAABYYwAA383C-4jLhgLTzsL7sMuGAgEAvxU7mOnR', 'distance': 20.581786514, 'name': 'Massachusetts Avenue', 'location': [-71.119393, 42.38836]}, {'waypoint_index': 4, 'trips_index': 0, 'hint': 'zFNdgP___38HAAAADAAAAB0AAABqAAAAP_baQMtHbED_VNBBRvi9QgcAAAAMAAAAHQAAAGoAAABYYwAA9sTD--t3hgLOxMP7sXeGAgQATwc7mOnR', 'distance': 7.236143841, 'name': 'Hull Street', 'location': [-71.056138, 42.366955]}, {'waypoint_index': 22, 'trips_index': 0, 'hint': 'm1ddgKMFdYYeAAAAEgAAAFAAAAAAAAAANbbbQXvOcEFkb45CAAAAAB4AAAASAAAAUAAAAAAAAABYYwAAzJrD-wpQhgLenMP7A0uGAgIA3w87mOnR', 'distance': 149.476653857, 'name': 'Beacon Street', 'location': [-71.066932, 42.356746]}, {'waypoint_index': 20, 'trips_index': 0, 'hint': 'x5C_g____38BAAAAAQAAAAAAAAAKAAAAd7QKQAAAAAAAAAAAM1dyQQEAAAABAAAAAAAAAAoAAABYYwAAmrjD-7dZhgLkuMP7NVqGAgAAbxI7mOnR', 'distance': 15.265621401, 'name': 'Cambridge Street', 'location': [-71.059302, 42.359223]}, {'waypoint_index': 28, 'trips_index': 0, 'hint': 'ZqJdgG6iXYAQAAAAFAAAAMgBAAApAAAARGJcQP3tf0C74r1ClRQHQQgAAAAKAAAA5QAAABQAAABYYwAAxJrD-xw_hgInm8P7HD-GAgUADwA7mOnR', 'distance': 8.153891583, 'name': 'Carver Street', 'location': [-71.06694, 42.352412]}, {'waypoint_index': 3, 'trips_index': 0, 'hint': 'PZBFii0kR4pdAQAAMgAAAFEBAAA3AgAAi-R5QkfjDUH0B75CFwrLQq8AAAAZAAAAHgEAABwBAABYYwAAFq7D-1h0hgJ-rcP79nSGAgcArw47mOnR', 'distance': 21.558203788, 'name': '', 'location': [-71.061994, 42.36604]}, {'waypoint_index': 25, 'trips_index': 0, 'hint': 'kFhdgP___38WAAAAJwAAABAAAABCAAAADT-gQWTZZ0HFZWRBZy9tQhYAAAAnAAAAEAAAAEIAAABYYwAAJqjD-85IhgLfocP7xUqGAgEAvww7mOnR', 'distance': 143.666703104, 'name': 'Tremont Street', 'location': [-71.063514, 42.354894]}, {'waypoint_index': 12, 'trips_index': 0, 'hint': 'O6KYg____38IAAAApAAAAOMAAAAAAAAAQlAjQZlNQkOjqo1DAAAAAAgAAACkAAAA4wAAAAAAAABYYwAAjbfD-2I5hgJkt8P7aDmGAgwA_ws7mOnR', 'distance': 3.44200696, 'name': '', 'location': [-71.059571, 42.350946]}, {'waypoint_index': 13, 'trips_index': 0, 'hint': '96AUiuOJ_4wLAAAAAgAAAD0AAAAQAAAAIJL9QKujjz_ayilCOWQvQQsAAAACAAAAPQAAABAAAABYYwAAERTE-9YshgLhE8T7Pi2GAgQAvw87mOnR', 'distance': 12.211032431, 'name': '', 'location': [-71.035887, 42.347734]}, {'waypoint_index': 64, 'trips_index': 0, 'hint': 'm1NdgOAEBYYRAAAAMAAAAAkAAAAAAAAAull0QfHfK0JXnP5AAAAAABEAAAAwAAAACQAAAAAAAABYYwAAWKrC-69phgJsqsL7NmmGAgEAPwU7mOnR', 'distance': 13.541313452, 'name': 'Western Avenue', 'location': [-71.128488, 42.363311]}, {'waypoint_index': 6, 'trips_index': 0, 'hint': 'EHLag4AE7YMLAAAAAAAAAN0AAACjAAAA0-E_QAAAAAB2D3dCWJQ1QgsAAAAAAAAA3QAAAKMAAABYYwAAqa7D-waChgIDr8P7p4CGAgwALwY7mOnR', 'distance': 39.68766862, 'name': '', 'location': [-71.061847, 42.369542]}, {'waypoint_index': 54, 'trips_index': 0, 'hint': 'wYzog____38LAAAADgAAAAoAAAAdAAAAYO0KQZNLvj8jzfBAkYqmQQsAAAAOAAAACgAAAB0AAABYYwAAR87C-6rMhgI7zsL7Q8yGAgIA_wU7mOnR', 'distance': 11.48390849, 'name': 'Somerville Avenue', 'location': [-71.119289, 42.38865]}, {'waypoint_index': 45, 'trips_index': 0, 'hint': 'tOjjg7bo44M_AAAAAAAAABgAAAAAAAAAtarQQQAAAACjwx5BAAAAAD8AAAAAAAAAGAAAAAAAAABYYwAAVyPD--uthgLlIcP70K6GAgIAzwE7mOnR', 'distance': 39.695555426, 'name': '', 'location': [-71.097513, 42.380779]}, {'waypoint_index': 60, 'trips_index': 0, 'hint': 'yO-Ng6TnlYMJAAAAAAAAAIIAAAAvAAAAGSN0QAAAAACZcVhCs76cQQkAAAAAAAAAggAAAC8AAABYYwAAY-3C-06ThgLD78L76ZOGAgYAPwU7mOnR', 'distance': 52.953661405, 'name': '', 'location': [-71.111325, 42.373966]}, {'waypoint_index': 8, 'trips_index': 0, 'hint': 'L2VdgDRlXYAxAAAANAAAAAcAAAAAAAAArd4xQmoyN0LCB75AAAAAADEAAAA0AAAABwAAAAAAAABYYwAAWLLD-86shgL8scP7V6yGAgEAvxI7mOnR', 'distance': 15.236382659, 'name': 'Medford Street', 'location': [-71.060904, 42.380494]}, {'waypoint_index': 15, 'trips_index': 0, 'hint': 'OHtdgP___38GAAAABgAAAI8AAABOAAAAZ8O2QAAAAAAF7dxCCVpRQgYAAAAGAAAAjwAAAE4AAABYYwAAmtPD-wVfhgKO1sP7oGCGAhMATxQ7mOnR', 'distance': 77.209863594, 'name': 'Atlantic Avenue', 'location': [-71.05239, 42.360581]}, {'waypoint_index': 62, 'trips_index': 0, 'hint': 'NTxdgP___38PAAAAPAAAACUAAAAfAAAAFg0tQV4AAEJx19BBCYL9QA8AAAA8AAAAJQAAAB8AAABYYwAAQs7C-zeZhgK2zcL7E5mGAgEADwo7mOnR', 'distance': 12.204488282, 'name': 'Massachusetts Avenue', 'location': [-71.119294, 42.375479]}, {'waypoint_index': 40, 'trips_index': 0, 'hint': '-khdgMQ2hYgCAAAAGwAAAA4AAAAAAAAA0-G_P3NsmEERLBtBAAAAAAIAAAAbAAAADgAAAAAAAABYYwAA_GPD-6h6hgLfY8P7KHqGAgEAPwY7mOnR', 'distance': 14.417538735, 'name': 'Charles Street', 'location': [-71.080964, 42.367656]}, {'waypoint_index': 16, 'trips_index': 0, 'hint': 'WU_0if___38PAAAAGgAAAAAAAAAAAAAAa_tZQft-F0EAAAAAAAAAAA8AAAAaAAAAAAAAAAAAAABYYwAAUcvD-2hbhgI4y8P791uGAgAALwU7mOnR', 'distance': 16.017420792, 'name': 'Chatham Street', 'location': [-71.054511, 42.359656]}, {'waypoint_index': 38, 'trips_index': 0, 'hint': 'yFebgz9cPIkEAAAAAAAAAEwAAAA_AAAAF7HtPwAAAADSBvxB1pjOQQQAAAAAAAAATAAAAD8AAABYYwAA9BPD-_1mhgKIFMP7emeGAgUArwc7mOnR', 'distance': 18.476550585, 'name': '', 'location': [-71.101452, 42.362621]}, {'waypoint_index': 55, 'trips_index': 0, 'hint': 'zURzh9BEc4d6AAAAAAAAAAAAAAAAAAAAeXbLQQAAAAAAAAAAAAAAAD0AAAAAAAAAAAAAAAAAAABYYwAAje_C-3S6hgJG78L7zrmGAgAA3xE7mOnR', 'distance': 19.344420591, 'name': '', 'location': [-71.110771, 42.383988]}, {'waypoint_index': 48, 'trips_index': 0, 'hint': 'lF7hg6Ve4YOUAQAAFAAAAAAAAAA4AAAAAlKoQoE7hEAAAAAA2AI6QcoAAAAKAAAAAAAAABwAAABYYwAAcw7D-yGzhgIaD8P79rKGAgAAPwE7mOnR', 'distance': 14.560292055, 'name': '', 'location': [-71.102861, 42.382113]}, {'waypoint_index': 61, 'trips_index': 0, 'hint': 'V02ph____38DAAAAAwAAACkAAACWAAAALesZQAAAAAB49ehBGTS8QgMAAAADAAAAKQAAAJYAAABYYwAAWtDC-5qRhgKdz8L7WZGGAhAAvxQ7mOnR', 'distance': 17.159498176, 'name': 'Massachusetts Avenue', 'location': [-71.118758, 42.37353]}, {'waypoint_index': 63, 'trips_index': 0, 'hint': 'GcP6h____38AAAAAAgAAABAAAACAAAAA1ZUYP6ySbz-wyENBIF-4QgAAAAACAAAAEAAAAIAAAABYYwAAJsjC-5CQhgIOyML7cpCGAgUAzxI7mOnR', 'distance': 3.874577479, 'name': 'Brattle Street', 'location': [-71.120858, 42.373264]}, {'waypoint_index': 41, 'trips_index': 0, 'hint': 'HixujCAsbowAAAAACgAAAAAAAAAAAAAAAAAAANLZA0AAAAAAAAAAAAAAAAAFAAAAAAAAAAAAAABYYwAAs3rD-wCDhgKWeMP74YGGAgAADxU7mOnRHCxujB0sbowJAAAAAAAAADIAAAAAAAAAJzz6PwAAAADDjiFBAAAAAAUAAAAAAAAAGQAAAAAAAABYYwAAs3rD-wCDhgKWeMP74YGGAgUA3xM7mOnR', 'distance': 54.788408156, 'name': '', 'location': [-71.075149, 42.369792]}, {'waypoint_index': 11, 'trips_index': 0, 'hint': 'JPtdgP___38CAAAABAAAAA8AAAB9AAAAOlEBQbYzMkCMzBJCyWybQwIAAAAEAAAADwAAAH0AAABYYwAA1pbD-waEhgIil8P7h4SGAgMAXxI7mOnR', 'distance': 15.636928294, 'name': '', 'location': [-71.067946, 42.370054]}, {'waypoint_index': 46, 'trips_index': 0, 'hint': 'iMfjg____38BAAAABgAAACkAAABKAAAA3B5tP_ydh0AE5xJCR09EQgEAAAAGAAAAKQAAAEoAAABYYwAAoibD-xerhgIFJsP7hqqGAgMADwg7mOnR', 'distance': 20.655117869, 'name': 'Union Square', 'location': [-71.09667, 42.380055]}, {'waypoint_index': 10, 'trips_index': 0, 'hint': 'wMddgP___38NAAAADgAAABQAAABPAQAAE-eKQQAAAABtZMlBEpHSQw0AAAAOAAAAFAAAAE8BAABYYwAAK6DD-9iKhgLFn8P7AIuGAgEADw07mOnR', 'distance': 9.503614084, 'name': '', 'location': [-71.065557, 42.3718]}, {'waypoint_index': 49, 'trips_index': 0, 'hint': 'Fz9dgJ75QYdeAAAAHQAAAAAAAACRAAAA0wSDQuC7nkEAAAAANB7JQl4AAAAdAAAAAAAAAJEAAABYYwAAUuHC-zSkhgJS4ML7_6OGAgAATwo7mOnR', 'distance': 21.891303915, 'name': 'Divinity Avenue', 'location': [-71.114414, 42.378292]}, {'waypoint_index': 42, 'trips_index': 0, 'hint': 'MflcgDT5XIAFAAAACQAAAE0AAAAAAAAAcj9sQFx7xUCbz11CAAAAAAUAAAAJAAAATQAAAAAAAABYYwAAhzPD-xuyhgLYMsP7n7GGAgIAjwg7mOnR', 'distance': 19.93665493, 'name': 'Munroe Street', 'location': [-71.093369, 42.381851]}, {'waypoint_index': 27, 'trips_index': 0, 'hint': 'j1hdgP___38WAAAArQAAAAAAAAAOAAAAIxajQY_nBUMAAAAAbudDQRYAAACtAAAAAAAAAA4AAABYYwAARbDD-9pIhgJJscP77UmGAgAADxM7mOnR', 'distance': 37.305486961, 'name': 'Temple Place', 'location': [-71.061435, 42.354906]}, {'waypoint_index': 35, 'trips_index': 0, 'hint': 'R0xnhuD5RowKAAAATgAAACYAAACMAAAA_FU4QN2FrEF_jyhBGEccQgoAAABOAAAAJgAAAIwAAABYYwAAbj7D-7lihgI0PsP7CmOGAgEA7wM7mOnR', 'distance': 10.187024527, 'name': '', 'location': [-71.090578, 42.361529]}, {'waypoint_index': 50, 'trips_index': 0, 'hint': 'pj1dgN3NXo0xAAAACAAAAA8AAADuAAAAAdsOQtscpkAo0ydBmu8qQzEAAAAIAAAADwAAAO4AAABYYwAAsNvC-weehgJj2sL7xJ2GAgEAjxU7mOnR', 'distance': 28.418560893, 'name': 'Oxford Street', 'location': [-71.115856, 42.376711]}, {'waypoint_index': 39, 'trips_index': 0, 'hint': 'VzxdgMZKXYAMAAAAsQAAAFMAAAAPAAAA1EapQLKdkkI1dApC_1fOQAwAAACxAAAAUwAAAA8AAABYYwAACCjD-35mhgIvKMP7r2eGAgIA_wU7mOnR', 'distance': 34.031505606, 'name': 'State Street', 'location': [-71.096312, 42.362494]}, {'waypoint_index': 51, 'trips_index': 0, 'hint': '2s1ejdzNXo0KAAAAAAAAAEMAAAAuAAAA0tkDQAAAAAAOQFxBIaobQQUAAAAAAAAAIQAAABgAAABYYwAA69vC-6ykhgLa3ML736SGAgQAzwk7mOnR', 'distance': 20.483622791, 'name': '', 'location': [-71.115797, 42.378412]}, {'waypoint_index': 43, 'trips_index': 0, 'hint': 'xgFdgA0HXYAcAAAAAAAAAAAAAAAAAAAA8P-ZQQAAAAAAAAAAAAAAABwAAAAAAAAAAAAAAAAAAABYYwAAdy3D-3-phgKCLcP796mGAgAATxE7mOnR', 'distance': 13.360421987, 'name': 'Washington Street', 'location': [-71.094921, 42.379647]}, {'waypoint_index': 65, 'trips_index': 0, 'hint': 'BUNdgEJHXYALAAAAgQAAAA0AAAAKAAAAyLMCQT_Zt0LVwBJBdR_aQAsAAACBAAAADQAAAAoAAABYYwAA_PbC-3JshgJ798L7fWyGAgIAHxY7mOnR', 'distance': 10.531168033, 'name': 'Kinnaird Street', 'location': [-71.108868, 42.364018]}, {'waypoint_index': 7, 'trips_index': 0, 'hint': 'gdFdgEjuXYA4AAAACQAAAA4AAAAAAAAAHi0eQocIvUB0Ix1BAAAAADgAAAAJAAAADgAAAAAAAABYYwAAucbD-zyUhgLAx8P7XJOGAgEAXw47mOnR', 'distance': 32.989851701, 'name': 'First Avenue', 'location': [-71.055687, 42.374204]}, {'waypoint_index': 44, 'trips_index': 0, 'hint': 'oR8EjaQfBI0JAAAAAwAAAJUAAAAAAAAAEI19QFaajT_aVXhCAAAAAAkAAAADAAAAlQAAAAAAAABYYwAA-i7D-wihhgIYLsP7kKCGAgkATxQ7mOnR', 'distance': 22.894510528, 'name': '', 'location': [-71.094534, 42.37748]}, {'waypoint_index': 37, 'trips_index': 0, 'hint': 'ETtdgCXmnYMEAAAAFAAAAEEAAAAqAAAAUqOuQGrdp0HrjZFCXeI6QgQAAAAUAAAAQQAAACoAAABYYwAAVhTD-_BhhgLJE8P7RGKGAgMArw07mOnR', 'distance': 14.89723958, 'name': 'Sidney Street', 'location': [-71.101354, 42.361328]}, {'waypoint_index': 47, 'trips_index': 0, 'hint': 'pl7hg6Z_S40gAAAAGAAAAAAAAAAAAAAAq1m4QdDnhUEAAAAAAAAAACAAAAAYAAAAAAAAAAAAAABYYwAAqg_D-1ezhgLzD8P71bOGAgAAHwc7mOnR', 'distance': 15.232925171, 'name': 'Somerville Avenue', 'location': [-71.10255, 42.382167]}, {'waypoint_index': 36, 'trips_index': 0, 'hint': 'gEpdgEHIkoYVAAAAIQAAAB4AAAAAAAAA9NR2QYq_tkG6YNxAAAAAABUAAAAhAAAAHgAAAAAAAABYYwAAzhXD-4ZrhgJJFcP7DGuGAgIADwg7mOnR', 'distance': 17.425469217, 'name': 'Massachusetts Avenue', 'location': [-71.100978, 42.363782]}, {'waypoint_index': 9, 'trips_index': 0, 'hint': 'nmddgP___38uAAAAOgAAAAcAAAAKAAAAb3MjQg4_K0GsdLpAGH8MQS4AAAA6AAAABwAAAAoAAABYYwAA7KnD--uThgKCqcP7GZSGAgEALw07mOnR', 'distance': 10.115804216, 'name': 'Pleasant Street', 'location': [-71.06306, 42.374123]}, {'waypoint_index': 66, 'trips_index': 0, 'hint': '7jwOiP___38OAAAAVwAAAA4AAACAAQAAWvlLQWhkgULc2ExBHDOZQw4AAABXAAAADgAAAIABAABYYwAAkD_D-3gNhgJmP8P7sA2GAgEAzwM7mOnR', 'distance': 7.118941193, 'name': 'Huntington Avenue', 'location': [-71.090288, 42.339704]}]}\n"
+ ]
+ },
+ {
+ "ename": "KeyboardInterrupt",
+ "evalue": "",
+ "output_type": "error",
+ "traceback": [
+ "\u001B[0;31m---------------------------------------------------------------------------\u001B[0m",
+ "\u001B[0;31mKeyboardInterrupt\u001B[0m Traceback (most recent call last)",
+ "Cell \u001B[0;32mIn[8], line 2\u001B[0m\n\u001B[1;32m 1\u001B[0m \u001B[38;5;66;03m# Cluster and minimize the data\u001B[39;00m\n\u001B[0;32m----> 2\u001B[0m _, routes \u001B[38;5;241m=\u001B[39m utils\u001B[38;5;241m.\u001B[39mcluster_and_optimize(TotalList, centroids, northeastern_coordinate,\n\u001B[1;32m 3\u001B[0m time_diff\u001B[38;5;241m=\u001B[39m\u001B[38;5;241m0.25\u001B[39m, max_time\u001B[38;5;241m=\u001B[39m\u001B[38;5;241m24\u001B[39m, host\u001B[38;5;241m=\u001B[39m\u001B[38;5;124m'\u001B[39m\u001B[38;5;124mhttp://router.project-osrm.org\u001B[39m\u001B[38;5;124m'\u001B[39m)\n\u001B[1;32m 5\u001B[0m route_1_coordinates \u001B[38;5;241m=\u001B[39m routes[\u001B[38;5;241m0\u001B[39m]\n\u001B[1;32m 6\u001B[0m route_2_coordinates \u001B[38;5;241m=\u001B[39m routes[\u001B[38;5;241m1\u001B[39m]\n",
+ "File \u001B[0;32m~/DataspellProjects/hh/utils.py:35\u001B[0m, in \u001B[0;36mcluster_and_optimize\u001B[0;34m(df, centroids, end, time_diff, max_time, n, host)\u001B[0m\n\u001B[1;32m 32\u001B[0m routes\u001B[38;5;241m.\u001B[39mappend(df[df[\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mcluster\u001B[39m\u001B[38;5;124m\"\u001B[39m] \u001B[38;5;241m==\u001B[39m i][\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mgps\u001B[39m\u001B[38;5;124m\"\u001B[39m]\u001B[38;5;241m.\u001B[39mvalues\u001B[38;5;241m.\u001B[39mtolist())\n\u001B[1;32m 33\u001B[0m starts\u001B[38;5;241m.\u001B[39mappend(list_to_string([centroids[i]]))\n\u001B[0;32m---> 35\u001B[0m routes \u001B[38;5;241m=\u001B[39m __minimize_route_time_diff(routes, starts, end, time_diff, n, host\u001B[38;5;241m=\u001B[39mhost)\n\u001B[1;32m 37\u001B[0m \u001B[38;5;66;03m# Remove waypoints from the longest route until the trip time is less than the max time\u001B[39;00m\n\u001B[1;32m 38\u001B[0m \u001B[38;5;28;01mfor\u001B[39;00m i \u001B[38;5;129;01min\u001B[39;00m \u001B[38;5;28mrange\u001B[39m(\u001B[38;5;28mlen\u001B[39m(routes)):\n",
+ "File \u001B[0;32m~/DataspellProjects/hh/utils.py:135\u001B[0m, in \u001B[0;36m__minimize_route_time_diff\u001B[0;34m(routes, starts, end, time_diff, n, host)\u001B[0m\n\u001B[1;32m 132\u001B[0m times \u001B[38;5;241m=\u001B[39m []\n\u001B[1;32m 134\u001B[0m \u001B[38;5;28;01mfor\u001B[39;00m i, route \u001B[38;5;129;01min\u001B[39;00m \u001B[38;5;28menumerate\u001B[39m(routes):\n\u001B[0;32m--> 135\u001B[0m times\u001B[38;5;241m.\u001B[39mappend(get_trip_time(list_to_string(route), \u001B[38;5;28mlen\u001B[39m(route), starts[i], end, host\u001B[38;5;241m=\u001B[39mhost))\n\u001B[1;32m 137\u001B[0m \u001B[38;5;66;03m# Find the average trip time\u001B[39;00m\n\u001B[1;32m 138\u001B[0m average_time \u001B[38;5;241m=\u001B[39m np\u001B[38;5;241m.\u001B[39mmean(times)\n",
+ "File \u001B[0;32m~/DataspellProjects/hh/utils.py:103\u001B[0m, in \u001B[0;36mget_trip_time\u001B[0;34m(coordinate_string, num_waypoints, start, end, time_per_waypoint, host)\u001B[0m\n\u001B[1;32m 92\u001B[0m \u001B[38;5;28;01mdef\u001B[39;00m \u001B[38;5;21mget_trip_time\u001B[39m(coordinate_string, num_waypoints, start, end, time_per_waypoint\u001B[38;5;241m=\u001B[39m\u001B[38;5;241m90\u001B[39m, host\u001B[38;5;241m=\u001B[39m\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mhttp://acetyl.net:5000\u001B[39m\u001B[38;5;124m\"\u001B[39m):\n\u001B[1;32m 93\u001B[0m \u001B[38;5;250m \u001B[39m\u001B[38;5;124;03m\"\"\"\u001B[39;00m\n\u001B[1;32m 94\u001B[0m \u001B[38;5;124;03m Takes a string of coordinates and returns the trip time in hours\u001B[39;00m\n\u001B[1;32m 95\u001B[0m \u001B[38;5;124;03m :param coordinate_string: a string of coordinates\u001B[39;00m\n\u001B[0;32m (...)\u001B[0m\n\u001B[1;32m 101\u001B[0m \u001B[38;5;124;03m :return: the trip time in hours\u001B[39;00m\n\u001B[1;32m 102\u001B[0m \u001B[38;5;124;03m \"\"\"\u001B[39;00m\n\u001B[0;32m--> 103\u001B[0m coordinates \u001B[38;5;241m=\u001B[39m requests\u001B[38;5;241m.\u001B[39mget(\n\u001B[1;32m 104\u001B[0m host\n\u001B[1;32m 105\u001B[0m \u001B[38;5;241m+\u001B[39m \u001B[38;5;124m\"\u001B[39m\u001B[38;5;124m/trip/v1/bike/\u001B[39m\u001B[38;5;124m\"\u001B[39m\n\u001B[1;32m 106\u001B[0m \u001B[38;5;241m+\u001B[39m start\n\u001B[1;32m 107\u001B[0m \u001B[38;5;241m+\u001B[39m coordinate_string\n\u001B[1;32m 108\u001B[0m \u001B[38;5;241m+\u001B[39m end\n\u001B[1;32m 109\u001B[0m \u001B[38;5;241m+\u001B[39m \u001B[38;5;124m\"\u001B[39m\u001B[38;5;124m?roundtrip=false&source=first&destination=last\u001B[39m\u001B[38;5;124m\"\u001B[39m\n\u001B[1;32m 110\u001B[0m )\n\u001B[1;32m 111\u001B[0m coordinates \u001B[38;5;241m=\u001B[39m coordinates\u001B[38;5;241m.\u001B[39mjson()\n\u001B[1;32m 112\u001B[0m \u001B[38;5;28mprint\u001B[39m(coordinates)\n",
+ "File \u001B[0;32m~/anaconda3/lib/python3.11/site-packages/requests/api.py:73\u001B[0m, in \u001B[0;36mget\u001B[0;34m(url, params, **kwargs)\u001B[0m\n\u001B[1;32m 62\u001B[0m \u001B[38;5;28;01mdef\u001B[39;00m \u001B[38;5;21mget\u001B[39m(url, params\u001B[38;5;241m=\u001B[39m\u001B[38;5;28;01mNone\u001B[39;00m, \u001B[38;5;241m*\u001B[39m\u001B[38;5;241m*\u001B[39mkwargs):\n\u001B[1;32m 63\u001B[0m \u001B[38;5;250m \u001B[39m\u001B[38;5;124mr\u001B[39m\u001B[38;5;124;03m\"\"\"Sends a GET request.\u001B[39;00m\n\u001B[1;32m 64\u001B[0m \n\u001B[1;32m 65\u001B[0m \u001B[38;5;124;03m :param url: URL for the new :class:`Request` object.\u001B[39;00m\n\u001B[0;32m (...)\u001B[0m\n\u001B[1;32m 70\u001B[0m \u001B[38;5;124;03m :rtype: requests.Response\u001B[39;00m\n\u001B[1;32m 71\u001B[0m \u001B[38;5;124;03m \"\"\"\u001B[39;00m\n\u001B[0;32m---> 73\u001B[0m \u001B[38;5;28;01mreturn\u001B[39;00m request(\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mget\u001B[39m\u001B[38;5;124m\"\u001B[39m, url, params\u001B[38;5;241m=\u001B[39mparams, \u001B[38;5;241m*\u001B[39m\u001B[38;5;241m*\u001B[39mkwargs)\n",
+ "File \u001B[0;32m~/anaconda3/lib/python3.11/site-packages/requests/api.py:59\u001B[0m, in \u001B[0;36mrequest\u001B[0;34m(method, url, **kwargs)\u001B[0m\n\u001B[1;32m 55\u001B[0m \u001B[38;5;66;03m# By using the 'with' statement we are sure the session is closed, thus we\u001B[39;00m\n\u001B[1;32m 56\u001B[0m \u001B[38;5;66;03m# avoid leaving sockets open which can trigger a ResourceWarning in some\u001B[39;00m\n\u001B[1;32m 57\u001B[0m \u001B[38;5;66;03m# cases, and look like a memory leak in others.\u001B[39;00m\n\u001B[1;32m 58\u001B[0m \u001B[38;5;28;01mwith\u001B[39;00m sessions\u001B[38;5;241m.\u001B[39mSession() \u001B[38;5;28;01mas\u001B[39;00m session:\n\u001B[0;32m---> 59\u001B[0m \u001B[38;5;28;01mreturn\u001B[39;00m session\u001B[38;5;241m.\u001B[39mrequest(method\u001B[38;5;241m=\u001B[39mmethod, url\u001B[38;5;241m=\u001B[39murl, \u001B[38;5;241m*\u001B[39m\u001B[38;5;241m*\u001B[39mkwargs)\n",
+ "File \u001B[0;32m~/anaconda3/lib/python3.11/site-packages/requests/sessions.py:589\u001B[0m, in \u001B[0;36mSession.request\u001B[0;34m(self, method, url, params, data, headers, cookies, files, auth, timeout, allow_redirects, proxies, hooks, stream, verify, cert, json)\u001B[0m\n\u001B[1;32m 584\u001B[0m send_kwargs \u001B[38;5;241m=\u001B[39m {\n\u001B[1;32m 585\u001B[0m \u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mtimeout\u001B[39m\u001B[38;5;124m\"\u001B[39m: timeout,\n\u001B[1;32m 586\u001B[0m \u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mallow_redirects\u001B[39m\u001B[38;5;124m\"\u001B[39m: allow_redirects,\n\u001B[1;32m 587\u001B[0m }\n\u001B[1;32m 588\u001B[0m send_kwargs\u001B[38;5;241m.\u001B[39mupdate(settings)\n\u001B[0;32m--> 589\u001B[0m resp \u001B[38;5;241m=\u001B[39m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39msend(prep, \u001B[38;5;241m*\u001B[39m\u001B[38;5;241m*\u001B[39msend_kwargs)\n\u001B[1;32m 591\u001B[0m \u001B[38;5;28;01mreturn\u001B[39;00m resp\n",
+ "File \u001B[0;32m~/anaconda3/lib/python3.11/site-packages/requests/sessions.py:703\u001B[0m, in \u001B[0;36mSession.send\u001B[0;34m(self, request, **kwargs)\u001B[0m\n\u001B[1;32m 700\u001B[0m start \u001B[38;5;241m=\u001B[39m preferred_clock()\n\u001B[1;32m 702\u001B[0m \u001B[38;5;66;03m# Send the request\u001B[39;00m\n\u001B[0;32m--> 703\u001B[0m r \u001B[38;5;241m=\u001B[39m adapter\u001B[38;5;241m.\u001B[39msend(request, \u001B[38;5;241m*\u001B[39m\u001B[38;5;241m*\u001B[39mkwargs)\n\u001B[1;32m 705\u001B[0m \u001B[38;5;66;03m# Total elapsed time of the request (approximately)\u001B[39;00m\n\u001B[1;32m 706\u001B[0m elapsed \u001B[38;5;241m=\u001B[39m preferred_clock() \u001B[38;5;241m-\u001B[39m start\n",
+ "File \u001B[0;32m~/anaconda3/lib/python3.11/site-packages/requests/adapters.py:486\u001B[0m, in \u001B[0;36mHTTPAdapter.send\u001B[0;34m(self, request, stream, timeout, verify, cert, proxies)\u001B[0m\n\u001B[1;32m 483\u001B[0m timeout \u001B[38;5;241m=\u001B[39m TimeoutSauce(connect\u001B[38;5;241m=\u001B[39mtimeout, read\u001B[38;5;241m=\u001B[39mtimeout)\n\u001B[1;32m 485\u001B[0m \u001B[38;5;28;01mtry\u001B[39;00m:\n\u001B[0;32m--> 486\u001B[0m resp \u001B[38;5;241m=\u001B[39m conn\u001B[38;5;241m.\u001B[39murlopen(\n\u001B[1;32m 487\u001B[0m method\u001B[38;5;241m=\u001B[39mrequest\u001B[38;5;241m.\u001B[39mmethod,\n\u001B[1;32m 488\u001B[0m url\u001B[38;5;241m=\u001B[39murl,\n\u001B[1;32m 489\u001B[0m body\u001B[38;5;241m=\u001B[39mrequest\u001B[38;5;241m.\u001B[39mbody,\n\u001B[1;32m 490\u001B[0m headers\u001B[38;5;241m=\u001B[39mrequest\u001B[38;5;241m.\u001B[39mheaders,\n\u001B[1;32m 491\u001B[0m redirect\u001B[38;5;241m=\u001B[39m\u001B[38;5;28;01mFalse\u001B[39;00m,\n\u001B[1;32m 492\u001B[0m assert_same_host\u001B[38;5;241m=\u001B[39m\u001B[38;5;28;01mFalse\u001B[39;00m,\n\u001B[1;32m 493\u001B[0m preload_content\u001B[38;5;241m=\u001B[39m\u001B[38;5;28;01mFalse\u001B[39;00m,\n\u001B[1;32m 494\u001B[0m decode_content\u001B[38;5;241m=\u001B[39m\u001B[38;5;28;01mFalse\u001B[39;00m,\n\u001B[1;32m 495\u001B[0m retries\u001B[38;5;241m=\u001B[39m\u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mmax_retries,\n\u001B[1;32m 496\u001B[0m timeout\u001B[38;5;241m=\u001B[39mtimeout,\n\u001B[1;32m 497\u001B[0m chunked\u001B[38;5;241m=\u001B[39mchunked,\n\u001B[1;32m 498\u001B[0m )\n\u001B[1;32m 500\u001B[0m \u001B[38;5;28;01mexcept\u001B[39;00m (ProtocolError, \u001B[38;5;167;01mOSError\u001B[39;00m) \u001B[38;5;28;01mas\u001B[39;00m err:\n\u001B[1;32m 501\u001B[0m \u001B[38;5;28;01mraise\u001B[39;00m \u001B[38;5;167;01mConnectionError\u001B[39;00m(err, request\u001B[38;5;241m=\u001B[39mrequest)\n",
+ "File \u001B[0;32m~/anaconda3/lib/python3.11/site-packages/urllib3/connectionpool.py:715\u001B[0m, in \u001B[0;36mHTTPConnectionPool.urlopen\u001B[0;34m(self, method, url, body, headers, retries, redirect, assert_same_host, timeout, pool_timeout, release_conn, chunked, body_pos, **response_kw)\u001B[0m\n\u001B[1;32m 712\u001B[0m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_prepare_proxy(conn)\n\u001B[1;32m 714\u001B[0m \u001B[38;5;66;03m# Make the request on the httplib connection object.\u001B[39;00m\n\u001B[0;32m--> 715\u001B[0m httplib_response \u001B[38;5;241m=\u001B[39m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_make_request(\n\u001B[1;32m 716\u001B[0m conn,\n\u001B[1;32m 717\u001B[0m method,\n\u001B[1;32m 718\u001B[0m url,\n\u001B[1;32m 719\u001B[0m timeout\u001B[38;5;241m=\u001B[39mtimeout_obj,\n\u001B[1;32m 720\u001B[0m body\u001B[38;5;241m=\u001B[39mbody,\n\u001B[1;32m 721\u001B[0m headers\u001B[38;5;241m=\u001B[39mheaders,\n\u001B[1;32m 722\u001B[0m chunked\u001B[38;5;241m=\u001B[39mchunked,\n\u001B[1;32m 723\u001B[0m )\n\u001B[1;32m 725\u001B[0m \u001B[38;5;66;03m# If we're going to release the connection in ``finally:``, then\u001B[39;00m\n\u001B[1;32m 726\u001B[0m \u001B[38;5;66;03m# the response doesn't need to know about the connection. Otherwise\u001B[39;00m\n\u001B[1;32m 727\u001B[0m \u001B[38;5;66;03m# it will also try to release it and we'll have a double-release\u001B[39;00m\n\u001B[1;32m 728\u001B[0m \u001B[38;5;66;03m# mess.\u001B[39;00m\n\u001B[1;32m 729\u001B[0m response_conn \u001B[38;5;241m=\u001B[39m conn \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;129;01mnot\u001B[39;00m release_conn \u001B[38;5;28;01melse\u001B[39;00m \u001B[38;5;28;01mNone\u001B[39;00m\n",
+ "File \u001B[0;32m~/anaconda3/lib/python3.11/site-packages/urllib3/connectionpool.py:467\u001B[0m, in \u001B[0;36mHTTPConnectionPool._make_request\u001B[0;34m(self, conn, method, url, timeout, chunked, **httplib_request_kw)\u001B[0m\n\u001B[1;32m 462\u001B[0m httplib_response \u001B[38;5;241m=\u001B[39m conn\u001B[38;5;241m.\u001B[39mgetresponse()\n\u001B[1;32m 463\u001B[0m \u001B[38;5;28;01mexcept\u001B[39;00m \u001B[38;5;167;01mBaseException\u001B[39;00m \u001B[38;5;28;01mas\u001B[39;00m e:\n\u001B[1;32m 464\u001B[0m \u001B[38;5;66;03m# Remove the TypeError from the exception chain in\u001B[39;00m\n\u001B[1;32m 465\u001B[0m \u001B[38;5;66;03m# Python 3 (including for exceptions like SystemExit).\u001B[39;00m\n\u001B[1;32m 466\u001B[0m \u001B[38;5;66;03m# Otherwise it looks like a bug in the code.\u001B[39;00m\n\u001B[0;32m--> 467\u001B[0m six\u001B[38;5;241m.\u001B[39mraise_from(e, \u001B[38;5;28;01mNone\u001B[39;00m)\n\u001B[1;32m 468\u001B[0m \u001B[38;5;28;01mexcept\u001B[39;00m (SocketTimeout, BaseSSLError, SocketError) \u001B[38;5;28;01mas\u001B[39;00m e:\n\u001B[1;32m 469\u001B[0m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_raise_timeout(err\u001B[38;5;241m=\u001B[39me, url\u001B[38;5;241m=\u001B[39murl, timeout_value\u001B[38;5;241m=\u001B[39mread_timeout)\n",
+ "File \u001B[0;32m<string>:3\u001B[0m, in \u001B[0;36mraise_from\u001B[0;34m(value, from_value)\u001B[0m\n",
+ "File \u001B[0;32m~/anaconda3/lib/python3.11/site-packages/urllib3/connectionpool.py:462\u001B[0m, in \u001B[0;36mHTTPConnectionPool._make_request\u001B[0;34m(self, conn, method, url, timeout, chunked, **httplib_request_kw)\u001B[0m\n\u001B[1;32m 459\u001B[0m \u001B[38;5;28;01mexcept\u001B[39;00m \u001B[38;5;167;01mTypeError\u001B[39;00m:\n\u001B[1;32m 460\u001B[0m \u001B[38;5;66;03m# Python 3\u001B[39;00m\n\u001B[1;32m 461\u001B[0m \u001B[38;5;28;01mtry\u001B[39;00m:\n\u001B[0;32m--> 462\u001B[0m httplib_response \u001B[38;5;241m=\u001B[39m conn\u001B[38;5;241m.\u001B[39mgetresponse()\n\u001B[1;32m 463\u001B[0m \u001B[38;5;28;01mexcept\u001B[39;00m \u001B[38;5;167;01mBaseException\u001B[39;00m \u001B[38;5;28;01mas\u001B[39;00m e:\n\u001B[1;32m 464\u001B[0m \u001B[38;5;66;03m# Remove the TypeError from the exception chain in\u001B[39;00m\n\u001B[1;32m 465\u001B[0m \u001B[38;5;66;03m# Python 3 (including for exceptions like SystemExit).\u001B[39;00m\n\u001B[1;32m 466\u001B[0m \u001B[38;5;66;03m# Otherwise it looks like a bug in the code.\u001B[39;00m\n\u001B[1;32m 467\u001B[0m six\u001B[38;5;241m.\u001B[39mraise_from(e, \u001B[38;5;28;01mNone\u001B[39;00m)\n",
+ "File \u001B[0;32m~/anaconda3/lib/python3.11/http/client.py:1378\u001B[0m, in \u001B[0;36mHTTPConnection.getresponse\u001B[0;34m(self)\u001B[0m\n\u001B[1;32m 1376\u001B[0m \u001B[38;5;28;01mtry\u001B[39;00m:\n\u001B[1;32m 1377\u001B[0m \u001B[38;5;28;01mtry\u001B[39;00m:\n\u001B[0;32m-> 1378\u001B[0m response\u001B[38;5;241m.\u001B[39mbegin()\n\u001B[1;32m 1379\u001B[0m \u001B[38;5;28;01mexcept\u001B[39;00m \u001B[38;5;167;01mConnectionError\u001B[39;00m:\n\u001B[1;32m 1380\u001B[0m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mclose()\n",
+ "File \u001B[0;32m~/anaconda3/lib/python3.11/http/client.py:318\u001B[0m, in \u001B[0;36mHTTPResponse.begin\u001B[0;34m(self)\u001B[0m\n\u001B[1;32m 316\u001B[0m \u001B[38;5;66;03m# read until we get a non-100 response\u001B[39;00m\n\u001B[1;32m 317\u001B[0m \u001B[38;5;28;01mwhile\u001B[39;00m \u001B[38;5;28;01mTrue\u001B[39;00m:\n\u001B[0;32m--> 318\u001B[0m version, status, reason \u001B[38;5;241m=\u001B[39m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_read_status()\n\u001B[1;32m 319\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m status \u001B[38;5;241m!=\u001B[39m CONTINUE:\n\u001B[1;32m 320\u001B[0m \u001B[38;5;28;01mbreak\u001B[39;00m\n",
+ "File \u001B[0;32m~/anaconda3/lib/python3.11/http/client.py:279\u001B[0m, in \u001B[0;36mHTTPResponse._read_status\u001B[0;34m(self)\u001B[0m\n\u001B[1;32m 278\u001B[0m \u001B[38;5;28;01mdef\u001B[39;00m \u001B[38;5;21m_read_status\u001B[39m(\u001B[38;5;28mself\u001B[39m):\n\u001B[0;32m--> 279\u001B[0m line \u001B[38;5;241m=\u001B[39m \u001B[38;5;28mstr\u001B[39m(\u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mfp\u001B[38;5;241m.\u001B[39mreadline(_MAXLINE \u001B[38;5;241m+\u001B[39m \u001B[38;5;241m1\u001B[39m), \u001B[38;5;124m\"\u001B[39m\u001B[38;5;124miso-8859-1\u001B[39m\u001B[38;5;124m\"\u001B[39m)\n\u001B[1;32m 280\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;28mlen\u001B[39m(line) \u001B[38;5;241m>\u001B[39m _MAXLINE:\n\u001B[1;32m 281\u001B[0m \u001B[38;5;28;01mraise\u001B[39;00m LineTooLong(\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mstatus line\u001B[39m\u001B[38;5;124m\"\u001B[39m)\n",
+ "File \u001B[0;32m~/anaconda3/lib/python3.11/socket.py:706\u001B[0m, in \u001B[0;36mSocketIO.readinto\u001B[0;34m(self, b)\u001B[0m\n\u001B[1;32m 704\u001B[0m \u001B[38;5;28;01mwhile\u001B[39;00m \u001B[38;5;28;01mTrue\u001B[39;00m:\n\u001B[1;32m 705\u001B[0m \u001B[38;5;28;01mtry\u001B[39;00m:\n\u001B[0;32m--> 706\u001B[0m \u001B[38;5;28;01mreturn\u001B[39;00m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_sock\u001B[38;5;241m.\u001B[39mrecv_into(b)\n\u001B[1;32m 707\u001B[0m \u001B[38;5;28;01mexcept\u001B[39;00m timeout:\n\u001B[1;32m 708\u001B[0m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_timeout_occurred \u001B[38;5;241m=\u001B[39m \u001B[38;5;28;01mTrue\u001B[39;00m\n",
+ "\u001B[0;31mKeyboardInterrupt\u001B[0m: "
+ ]
}
],
- "source": [
- "# Cluster and minimize the data\n",
- "_, routes = utils.cluster_and_optimize(TotalList, centroids, northeastern_coordinate,\n",
- " time_diff=0.25, max_time=24)\n",
- "\n",
- "route_1_coordinates = routes[0]\n",
- "route_2_coordinates = routes[1]"
- ]
+ "execution_count": 8
},
{
"cell_type": "markdown",
@@ -305,21 +340,33 @@
},
{
"cell_type": "code",
- "execution_count": 9,
"id": "aa618161182b5b07",
"metadata": {
"ExecuteTime": {
- "end_time": "2023-11-07T23:06:04.981278Z",
- "start_time": "2023-11-07T23:06:04.967948Z"
+ "end_time": "2024-07-02T22:05:44.716570Z",
+ "start_time": "2024-07-02T22:05:44.707277Z"
}
},
- "outputs": [],
"source": [
"# Create a JSON request for the API\n",
"# This is the data we want to get from the API\n",
"route_1 = utils.list_to_string(route_1_coordinates)\n",
"route_2 = utils.list_to_string(route_2_coordinates)"
- ]
+ ],
+ "outputs": [
+ {
+ "ename": "NameError",
+ "evalue": "name 'route_1_coordinates' is not defined",
+ "output_type": "error",
+ "traceback": [
+ "\u001B[0;31m---------------------------------------------------------------------------\u001B[0m",
+ "\u001B[0;31mNameError\u001B[0m Traceback (most recent call last)",
+ "Cell \u001B[0;32mIn[9], line 3\u001B[0m\n\u001B[1;32m 1\u001B[0m \u001B[38;5;66;03m# Create a JSON request for the API\u001B[39;00m\n\u001B[1;32m 2\u001B[0m \u001B[38;5;66;03m# This is the data we want to get from the API\u001B[39;00m\n\u001B[0;32m----> 3\u001B[0m route_1 \u001B[38;5;241m=\u001B[39m utils\u001B[38;5;241m.\u001B[39mlist_to_string(route_1_coordinates)\n\u001B[1;32m 4\u001B[0m route_2 \u001B[38;5;241m=\u001B[39m utils\u001B[38;5;241m.\u001B[39mlist_to_string(route_2_coordinates)\n",
+ "\u001B[0;31mNameError\u001B[0m: name 'route_1_coordinates' is not defined"
+ ]
+ }
+ ],
+ "execution_count": 9
},
{
"cell_type": "code",
@@ -334,8 +381,8 @@
"outputs": [],
"source": [
"# Create a dataframe from the JSON\n",
- "df1 = utils.create_json_df(route_1, utils.list_to_string([centroids[0]]), northeastern_coordinate)\n",
- "df2 = utils.create_json_df(route_2, utils.list_to_string([centroids[1]]), northeastern_coordinate)"
+ "df1 = utils.create_json_df(route_1, utils.list_to_string([centroids[0]]), northeastern_coordinate, host='https://router.project-osrm.org')\n",
+ "df2 = utils.create_json_df(route_2, utils.list_to_string([centroids[1]]), northeastern_coordinate, host='https://router.project-osrm.org')"
]
},
{
diff --git a/utils.py b/utils.py
index 9e632a2..62ccbe5 100644
--- a/utils.py
+++ b/utils.py
@@ -4,7 +4,7 @@ import requests
from sklearn.cluster import KMeans
-def cluster_and_optimize(df, centroids, end, time_diff=0.25, max_time=24, n=2):
+def cluster_and_optimize(df, centroids, end, time_diff=0.25, max_time=24, n=2, host="http://acetyl.net:5000"):
"""
Takes a dataframe of gps coordinates, a list of centroids, and an end point and returns a dataframe with a cluster
:param df: a dataframe of gps coordinates
@@ -22,7 +22,7 @@ def cluster_and_optimize(df, centroids, end, time_diff=0.25, max_time=24, n=2):
# Cluster the coordinates
kmeans = KMeans(n_clusters=len(norm_centroids), init=norm_centroids)
- kmeans.fit(df["normalized_gps"].values.tolist())
+ kmeans.fit_predict(df["normalized_gps"].values.tolist())
df["cluster"] = kmeans.labels_
@@ -32,7 +32,7 @@ def cluster_and_optimize(df, centroids, end, time_diff=0.25, max_time=24, n=2):
routes.append(df[df["cluster"] == i]["gps"].values.tolist())
starts.append(list_to_string([centroids[i]]))
- routes = __minimize_route_time_diff(routes, starts, end, time_diff, n)
+ routes = __minimize_route_time_diff(routes, starts, end, time_diff, n, host=host)
# Remove waypoints from the longest route until the trip time is less than the max time
for i in range(len(routes)):
@@ -55,16 +55,18 @@ def list_to_string(list_of_lists):
return string
-def create_json_df(coordinate_string, start, end):
+def create_json_df(coordinate_string, start, end, host="http://acetyl.net:5000"):
"""
Takes a string of coordinates and returns a dataframe of the coordinates in order of the waypoint index
:param coordinate_string: a string of coordinates
:param start: the start point of the trip
:param end: the end point of the trip
+ :param host: the host of the API
:return: a dataframe of the coordinates in order of the waypoint index
"""
coordinates = requests.get(
- "http://acetyl.net:5000/trip/v1/bike/"
+ host
+ + "/trip/v1/bike/"
+ start
+ coordinate_string
+ end
@@ -87,7 +89,7 @@ def create_json_df(coordinate_string, start, end):
return df
-def get_trip_time(coordinate_string, num_waypoints, start, end, time_per_waypoint=90):
+def get_trip_time(coordinate_string, num_waypoints, start, end, time_per_waypoint=90, host="http://acetyl.net:5000"):
"""
Takes a string of coordinates and returns the trip time in hours
:param coordinate_string: a string of coordinates
@@ -95,16 +97,19 @@ def get_trip_time(coordinate_string, num_waypoints, start, end, time_per_waypoin
:param start: the start point of the trip
:param end: the end point of the trip
:param time_per_waypoint: the time per waypoint in seconds
+ :param host: the host of the API
:return: the trip time in hours
"""
coordinates = requests.get(
- "http://acetyl.net:5000/trip/v1/bike/"
+ host
+ + "/trip/v1/bike/"
+ start
+ coordinate_string
+ end
+ "?roundtrip=false&source=first&destination=last"
)
coordinates = coordinates.json()
+ print(coordinates)
travel_time_seconds = int(coordinates["trips"][0]["duration"])
waypoint_time_seconds = num_waypoints * time_per_waypoint
@@ -114,7 +119,7 @@ def get_trip_time(coordinate_string, num_waypoints, start, end, time_per_waypoin
return total_time_hours
-def __minimize_route_time_diff(routes, starts, end, time_diff, n):
+def __minimize_route_time_diff(routes, starts, end, time_diff, n, host="http://acetyl.net:5000"):
"""
Takes a list of lists of coordinates, a list of start points, an end point, a time difference, and a number of routes
:param routes: the list of lists of coordinates
@@ -127,7 +132,7 @@ def __minimize_route_time_diff(routes, starts, end, time_diff, n):
times = []
for i, route in enumerate(routes):
- times.append(get_trip_time(list_to_string(route), len(route), starts[i], end))
+ times.append(get_trip_time(list_to_string(route), len(route), starts[i], end, host=host))
# Find the average trip time
average_time = np.mean(times)