HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythonMinor

Finding all restaurants at given lat/long in Python

Submitted by: @import:stackexchange-codereview··
0
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

Solution

Descriptive names

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 list


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

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


Becomes:

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 2

It 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 + places


With 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 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
return 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.