On the 1st July I will begin a month long journey to visit EVERY Wimpy restaurant in the UK. This is a charity event where I hope to raise both money and awareness for the Teenage Cancer Trust, a charity I have personal experience with. Wimpy was the first fast food restaurant in the UK and celebrates its 70th birthday this year. It was the biggest fast food chain in the UK for many years, and at one point had over 500 restaurants. If you’re interested in finding out about about my motivations, please visit my website, which I deployed using the Wolfram Cloud.
Today, there are 65 Wimpys scattered across the UK and to visit these locations in a timely manner is a logistical nightmare. Thankfully, with the Wolfram Language I am able to create tools to generate the information I need to optimize my route.
Today, there are 65 Wimpys scattered across the UK and to visit these locations in a timely manner is a logistical nightmare. Thankfully, with the Wolfram Language I am able to create tools to generate the information I need to optimize my route.
First, I need to get some data on the restaurants. Using the Wimpy’s API, I am able to do this easily.
In[]:=
readData=URLRead["https://wimpy.uk.com/api/locations?all=true"]
Out[]=
HTTPResponse
The data is in the form of a JSON. I make each entry an Association for convenience later.
In[]:=
jsonData=Association@@@ImportString[readData["Body"],"JSON"];
There are a number of fields for each Wimpy
In[]:=
Short[Union[Flatten[Keys/@jsonData]]]
Out[]//Short=
{accountId,additionalHoursText,address,address2,attire,bioListIds,bioListsLabel,75,yextDisplayLng,yextRoutableLat,yextRoutableLng,yextWalkableLat,yextWalkableLng,zip}
I am only interested in the longitude, latitude, address and opening times. The data needs to be processed so that it can be used more readily in the Wolfram Language. I can make a function which can extract out the longitude and latitude for the given restaurants data.
In[]:=
makeGeoPosition[x_Association]:=Module {lat,lng}, lat=Lookup[x,"yextRoutableLat"]; lng=Lookup[x,"yextRoutableLng"]; GeoPosition[{lat,lng}]
The opening times data is slightly more complicated. The hours data is a single string. Days are in the form day:openingtime:closingtime, where the day is numerical form of the day of the week (Sunday is 1, Monday is 2, ...). The string can be parsed with the following.
In[]:=
dayKeys=1"Sunday",2"Monday",3"Tuesday",4"Wednesday",5"Thursday",6"Friday",7"Saturday";
In[]:=
split[str_String]:=ToExpression/@StringSplit[str,{":",","}];
In[]:=
openingTimes[str_String]:=<|Map[dayKeys[#[[1]]]-><|"Open"->TimeObject[#[[2;;3]]],"Close"->TimeObject[#[[4;;5]]]|>&,Partition[split[str],5]]|>
Now that I have my helper functions I can write create a Dataset with only the data I require.
In[]:=
wimpyData=DatasetMap <| "Id"->#id, "OpeningTimes"->openingTimes[#["hours"]], "GeoPosition"->makeGeoPosition[#], "Address"-><| "Street"->#["address"], "City"->#["city"], "County"->#["state"], "Postcode"->#["zip"] |> |>&, jsonData
Out[]=
To minimize my travel time, I want to get to find the shortest tour of all the Wimpys. Using just the GeoPosition I use FindShortestTour.
In[]:=
allGeoPositions=Normal[wimpyData[All,"GeoPosition"]];
In[]:=
wimpyTour=FindShortestTour[allGeoPositions][[2]]
Out[]=
{1,3,15,31,12,5,48,50,60,14,17,30,40,16,32,59,28,29,20,11,45,8,24,62,39,10,55,44,22,33,38,63,46,23,58,42,4,52,56,9,47,37,61,53,19,18,26,41,36,49,34,27,21,35,13,43,51,6,57,54,7,2,25,1}
The tour above is in positional form. A route between one Wimpy to the next would be 2 adjacent values of wimpyTour. Feed these values into allGeoPositions and you get a start and end GeoPosition. For the first route it looks like this.
In[]:=
route1={allGeoPositions[[wimpyTour[[1]]]],allGeoPositions[[wimpyTour[[2]]]]}
Out[]=
{GeoPosition[{51.3718,-0.486553}],GeoPosition[{51.4336,-0.464569}]}
I can make a travel route using TravelDirections, which can give us step by step instructions and a path.
In[]:=
travel1=TravelDirections[route1]
Out[]=
TravelDirectionsData
In[]:=
travel1["Dataset"]
Out[]=
This is how it looks on a map.
For a full list of all routes I can use MovingMap to give me every positional pair.
Which I can feed into allGeoPositions.
Now all I need to do is Map these values with TravelDirections to get every route.
Now all I need to do is plot my route using GeoGraphics. The following gives a basic black line style to each path.
I also want a GeoMarker for each restaurant location, with a ToolTip that shows the address and opening times.
Finally I use GeoGraphics to show these elements on a map. Note: For full functionality you need to download this notebook and use the Wolfram App on the desktop.
And that’s it, I now have my route!
Appendix
I’ve been developing a set of tools on GitHub called WimpyCodingTools, which has a lot more functionality. It still needs a lot of work but it’s already providing me a lot of value. I plan to cover this in future posts but if you fancy taking a look, please do. Here are some things I’ve found while looking at this data.
Wimpy’s which are in a 20 mile radius of London:
Total travel distance for the tour:
Longest distance to travel in single journey
Total driving time:
The most northern and southern Wimpy:
Let me know if you have any other interesting facts you can get from this data, or if my code can be improved in any way. Thanks for reading!
CITE THIS NOTEBOOK
CITE THIS NOTEBOOK
How I plan to visit EVERY Wimpy Restaurant in the UK
by Anthony Zupnik
Wolfram Community, STAFF PICKS, June 10, 2024
https://community.wolfram.com/groups/-/m/t/3189664
by Anthony Zupnik
Wolfram Community, STAFF PICKS, June 10, 2024
https://community.wolfram.com/groups/-/m/t/3189664