patternpythonMinor
Finding all restaurants at given lat/long in Python
Viewed 0 times
restaurantsalllongpythonfindinggivenlat
Problem
This is a program I wrote to grab restaurants/bars from Google, Yelp, and Foursquare. It then ranks them more effectively based on the rating, the number of ratings, and the number of data sources using a Bayesian average. My guess is that the main method could be broken into more functions. I'm also guessing I'm missing some handy list comprehension tricks. Any suggestions?
main.py
```
import csv
import time
import foursquare
import yelp
import google
def bayesian(R, v, m, C):
"""
Computes the Bayesian average for the given parameters
:param R: Average rating for this business
:param v: Number of ratings for this business
:param m: Minimum ratings required
:param C: Mean rating across the entire list
:returns: Bayesian average
"""
# Convert to floating point numbers
R = float(R)
v = float(v)
m = float(m)
C = float(C)
return ((v / (v + m)) R + (m / (v + m)) C)
def remove_duplicate_names(full_list):
"""
Fixes issue with multiple API calls returning the same businesses
:param R: The entire unfiltered list
:returns: Filtered list
"""
names = set()
filtered_list = []
for business in full_list:
if business.name not in names:
filtered_list.append(business)
names.add(business.name)
return filtered_list
def main():
"""
Finds all the bars/restaurants in the given area. Use different
lat/long points to cover entire town since API calls have length limits.
"""
input_value = ''
locations = []
distance = input('Search Radius (meters): ')
while input_value is not 'n':
lat = input('Lat: ')
lng = input('Long: ')
locations.append((lat, lng))
input_value = raw_input('Would you like more points? (y/n) ')
venues, businesses, places = [], [], []
for lat,lng in locations:
# Retrieve all businesses for all sources
print 'Searching lat: {} long: {} ...'.format(l
main.py
```
import csv
import time
import foursquare
import yelp
import google
def bayesian(R, v, m, C):
"""
Computes the Bayesian average for the given parameters
:param R: Average rating for this business
:param v: Number of ratings for this business
:param m: Minimum ratings required
:param C: Mean rating across the entire list
:returns: Bayesian average
"""
# Convert to floating point numbers
R = float(R)
v = float(v)
m = float(m)
C = float(C)
return ((v / (v + m)) R + (m / (v + m)) C)
def remove_duplicate_names(full_list):
"""
Fixes issue with multiple API calls returning the same businesses
:param R: The entire unfiltered list
:returns: Filtered list
"""
names = set()
filtered_list = []
for business in full_list:
if business.name not in names:
filtered_list.append(business)
names.add(business.name)
return filtered_list
def main():
"""
Finds all the bars/restaurants in the given area. Use different
lat/long points to cover entire town since API calls have length limits.
"""
input_value = ''
locations = []
distance = input('Search Radius (meters): ')
while input_value is not 'n':
lat = input('Lat: ')
lng = input('Long: ')
locations.append((lat, lng))
input_value = raw_input('Would you like more points? (y/n) ')
venues, businesses, places = [], [], []
for lat,lng in locations:
# Retrieve all businesses for all sources
print 'Searching lat: {} long: {} ...'.format(l
Solution
Descriptive names
The function signature is:
But then you go a long way describing these single letter parameters in the docstring:
Most usually, descriptive code is preferred over descriptive comments / docstrings for the simple reason that having two things (code / comments) instead of one (code) doubles the maintenance effort, and if code and comments get out of sync, the code becomes extremely confusing.
Built-ins
Becomes:
The code does not care about the order of the restaurants as far as I can see, so the fact that
Function for input
Getting user input is a detail, when looking at the main structure of the program in
No
It automatically evaluates the input, it is dangerous to execute anything the user enters and universally considered bad practice. Use
The overload
Becomes:
With a clear gain in clarity.
The function signature is:
bayesian(R, v, m, C)But then you go a long way describing these single letter parameters in the docstring:
:param R: Average rating for this business
:param v: Number of ratings for this business
:param m: Minimum ratings required
:param C: Mean rating across the entire listMost usually, descriptive code is preferred over descriptive comments / docstrings for the simple reason that having two things (code / comments) instead of one (code) doubles the maintenance effort, and if code and comments get out of sync, the code becomes extremely confusing.
Built-ins
names = set()
filtered_list = []
for business in full_list:
if business.name not in names:
filtered_list.append(business)
names.add(business.name)
return filtered_listBecomes:
return list(set(business))The code does not care about the order of the restaurants as far as I can see, so the fact that
set changes order should not be a problem.Function for input
Getting user input is a detail, when looking at the main structure of the program in
main we don't care about it, so just use a function.while input_value is not 'n':
lat = input('Lat: ')
lng = input('Long: ')
locations.append((lat, lng))
input_value = raw_input('Would you like more points? (y/n) ')No
input in Python 2It automatically evaluates the input, it is dangerous to execute anything the user enters and universally considered bad practice. Use
int(raw_input(x))The overload
+ means many things in Python, one of them is adding lists:full_list = []
full_list.extend(venues)
full_list.extend(businesses)
full_list.extend(places)Becomes:
full_list = venues + businesses + placesWith a clear gain in clarity.
Code Snippets
bayesian(R, v, m, C):param R: Average rating for this business
:param v: Number of ratings for this business
:param m: Minimum ratings required
:param C: Mean rating across the entire listnames = set()
filtered_list = []
for business in full_list:
if business.name not in names:
filtered_list.append(business)
names.add(business.name)
return filtered_listreturn list(set(business))while input_value is not 'n':
lat = input('Lat: ')
lng = input('Long: ')
locations.append((lat, lng))
input_value = raw_input('Would you like more points? (y/n) ')Context
StackExchange Code Review Q#113644, answer score: 6
Revisions (0)
No revisions yet.