Last active
December 11, 2021 20:44
-
-
Save mdeprezzo/9effc2fc6a206523e9226beab12ad6dd to your computer and use it in GitHub Desktop.
Calculate the percentage of the zone covered by enabled shoppers (`coverage`). One shopper covers a zone if the distance among the coordinates is less than 10 km.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import math | |
def haversine(lat1, lng1, lat2, lng2): | |
p = math.pi/180 | |
a = 0.5 - math.cos((lat2-lat1)*p)/2 + math.cos(lat1*p) * math.cos(lat2*p) * (1-math.cos((lng2-lng1)*p))/2 | |
return 12742 * math.asin(math.sqrt(a)) #2*R*asin... | |
def findIndex(my_list, prop, value): | |
return next((i for i, item in enumerate(my_list) if item[prop] == value), -1) | |
def get_coverage(shopper): | |
return shopper.get('coverage') | |
locations = [ | |
{'id': 1000, 'zip_code': '37069', 'lat': 45.35, 'lng': 10.84}, | |
{'id': 1001, 'zip_code': '37121', 'lat': 45.44, 'lng': 10.99}, | |
{'id': 1001, 'zip_code': '37129', 'lat': 45.44, 'lng': 11.00}, | |
{'id': 1001, 'zip_code': '37133', 'lat': 45.43, 'lng': 11.02} | |
]; | |
shoppers = [ | |
{'id': 'S1', 'lat': 45.46, 'lng': 11.03, 'enabled': True}, | |
{'id': 'S2', 'lat': 45.46, 'lng': 10.12, 'enabled': True}, | |
{'id': 'S3', 'lat': 45.34, 'lng': 10.81, 'enabled': True}, | |
{'id': 'S4', 'lat': 45.76, 'lng': 10.57, 'enabled': True}, | |
{'id': 'S5', 'lat': 45.34, 'lng': 10.63, 'enabled': True}, | |
{'id': 'S6', 'lat': 45.42, 'lng': 10.81, 'enabled': True}, | |
{'id': 'S7', 'lat': 45.34, 'lng': 10.94, 'enabled': True} | |
]; | |
sorted = [] | |
for location in locations: | |
for shopper in shoppers: | |
distance = haversine(shopper['lat'], shopper['lng'], location['lat'], location['lng']) | |
if distance < 10: | |
index = findIndex(sorted, 'shopper_id', shopper['id']) | |
if (index < 0): | |
sorted.append({'shopper_id': shopper['id'], 'coverage': 1}) | |
else: | |
sorted[index]['coverage'] = sorted[index]['coverage'] + 1 | |
for sort in sorted: | |
sort['coverage'] = (sort['coverage']/len(locations))*100 | |
sorted.sort(key=get_coverage, reverse=True) | |
print(sorted) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment