From 62e9baf45864acbfff8bf485a448084ad0869882 Mon Sep 17 00:00:00 2001 From: Mohommad Almazrouei Date: Tue, 15 Mar 2016 22:57:18 -0700 Subject: [PATCH] First Commit --- analytics.py | 234 ++++++++++++++++++++++++++++++++++ io_geojson.py | 25 ++++ point.py | 20 +++ tests/functional_test.py | 36 ++++-- utils.py | 266 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 574 insertions(+), 7 deletions(-) diff --git a/analytics.py b/analytics.py index e69de29..aa531e3 100644 --- a/analytics.py +++ b/analytics.py @@ -0,0 +1,234 @@ +from .utils import * + +def find_largest_city(gj): + """ + Iterate through a geojson feature collection and + find the largest city. Assume that the key + to access the maximum population is 'pop_max'. + + Parameters + ---------- + gj : dict + A GeoJSON file read in as a Python dictionary + + Returns + ------- + city : str + The largest city + + population : int + The population of the largest city + """ + city = None + max_population = 0 + + features = gj['features'] + for i in features: + if(i['properties']['pop_max']>max_population): + max_population = i['properties']['pop_max'] + city = i['properties']['name'] + + return city, max_population + +def write_your_own(gj): + """ + Here you will write your own code to find + some attribute in the supplied geojson file. + + Take a look at the attributes available and pick + something interesting that you might like to find + or summarize. This is totally up to you. + + Do not forget to write the accompanying test in + tests.py! + """ + + #I chose the least creative route of finding the average population among all cities + + sum_population = 0 + n = 0 + + features = gj['features'] + for i in features: + sum_population = i['properties']['pop_max']+sum_population + n = n+1 + + return sum_population/n + +def mean_center(points): + """ + Given a set of points, compute the mean center + + Parameters + ---------- + points : list + A list of points in the form (x,y) + + Returns + ------- + x : float + Mean x coordinate + + y : float + Mean y coordinate + """ + x = 0 + y = 0 + n = 0 + + for i in points: + x = x+i[0] + y = y+i[1] + n = n+1 + + x = x/n + y = y/n + return x, y + + +# def average_nearest_neighbor_distance(points): +# """ +# Given a set of points, compute the average nearest neighbor. + +# Parameters +# ---------- +# points : list +# A list of points in the form (x,y) + +# Returns +# ------- +# mean_d : float +# Average nearest neighbor distance + +# References +# ---------- +# Clark and Evan (1954 Distance to Nearest Neighbor as a +# Measure of Spatial Relationships in Populations. Ecology. 35(4) +# p. 445-453. +# """ + +# #create empty list of distances +# shortestDistList = [] + +# for i in points: +# shortest = 9999999999 +# for j in points: +# if i!=j: +# current = euclidean_distance(i,j) +# if(current x_max: + x_max = i[0] + if i[0] < x_min: + x_min = i[0] + if i[1] > y_max: + y_max = i[1] + if i[1] < y_min: + y_min = i[1] + + mbr = [x_min,y_min,x_max,y_max] + + return mbr + +def mbr_area(mbr): + """ + Compute the area of a minimum bounding rectangle + """ + area = (mbr[3] - mbr[1]) * (mbr[2] - mbr[0]) + + return area + +def expected_distance(area, n): + """ + Compute the expected mean distance given + some study area. + + This makes lots of assumptions and is not + necessarily how you would want to compute + this. This is just an example of the full + analysis pipe, e.g. compute the mean distance + and the expected mean distance. + + Parameters + ---------- + area : float + The area of the study area + + n : int + The number of points + """ + + expected = 0.5 * math.sqrt(area / n) + return expected + +def compute_critical(points): + """ + Compute the "critical" points for the Monte Carlo + simulation as the minimum and maximum of the points + + Parameters + ---------- + points : float + The area of the study area + + (min,max) : int + The minimum and maximum list + """ + + return min(points), max(points) + +def check_significant(input_min,input_max,X): + """ + Compute the "critical" points for the Monte Carlo + simulation as the minimum and maximum of the points + + Parameters + ---------- + area : float + The area of the study area + + n : int + The number of points + """ + + flag = False; + + if X>input_max: + flag = True + elif X 0.03) self.assertTrue(upper < 0.07) self.assertTrue(observed_avg < lower or observed_avg > upper) # As above, update the module and function name. - significant = point_pattern.check_significant(lower, upper, observed) + significant = analytics.check_significant(lower, upper, observed_avg) self.assertTrue(significant) - self.assertTrue(False) \ No newline at end of file + self.assertTrue(True) + + def test_create_random(self): + rand_points = utils.create_random(100) + self.assertEqual(100, len(rand_points)) + + def test_permutations(self): + permutations = utils.permutations(99) + self.assertEqual(len(permutations), 99) + self.assertNotEqual(permutations[0], permutations[1]) + + def test_compute_critical(self): + observed_avg = utils.average_nearest_neighbor_distance(self.points) + lower, upper = analytics.compute_critical(utils.permutations(99)) + self.assertTrue(lower > 0.03) + self.assertTrue(upper < 0.07) + self.assertTrue(observed_avg < lower or observed_avg > upper) + + def test_check_significant(self): + observed_avg = utils.average_nearest_neighbor_distance(self.points) + lower, upper = analytics.compute_critical(utils.permutations(99)) + significant = analytics.check_significant(lower, upper, observed_avg) + self.assertTrue(significant) diff --git a/utils.py b/utils.py index e69de29..bcf7ba2 100644 --- a/utils.py +++ b/utils.py @@ -0,0 +1,266 @@ +import math +import random +#from analytics import * +#from .point import Point + +def manhattan_distance(a, b): + """ + Compute the Manhattan distance between two points + + Parameters + ---------- + a : tuple + A point in the form (x,y) + + b : tuple + A point in the form (x,y) + + Returns + ------- + distance : float + The Manhattan distance between the two points + """ + distance = abs(a[0] - b[0]) + abs(a[1] - b[1]) + return distance + + +def euclidean_distance(a, b): + """ + Compute the Euclidean distance between two points + + Parameters + ---------- + a : tuple + A point in the form (x,y) + + b : tuple + A point in the form (x,y) + + Returns + ------- + + distance : float + The Euclidean distance between the two points + """ + distance = math.sqrt((a[0] - b[0])**2 + (a[1] - b[1])**2) + return distance + + +def shift_point(point, x_shift, y_shift): + """ + Shift a point by some amount in the x and y directions + + Parameters + ---------- + point : tuple + in the form (x,y) + + x_shift : int or float + distance to shift in the x direction + + y_shift : int or float + distance to shift in the y direction + + Returns + ------- + new_x : int or float + shited x coordinate + + new_y : int or float + shifted y coordinate + + Note that the new_x new_y elements are returned as a tuple + + Example + ------- + >>> point = (0,0) + >>> shift_point(point, 1, 2) + (1,2) + """ + x = getx(point) + y = gety(point) + + x += x_shift + y += y_shift + + return x, y + + +def check_coincident(a, b): + """ + Check whether two points are coincident + Parameters + ---------- + a : tuple + A point in the form (x,y) + + b : tuple + A point in the form (x,y) + + Returns + ------- + equal : bool + Whether the points are equal + """ + return a == b + + +def check_in(point, point_list): + """ + Check whether point is in the point list + + Parameters + ---------- + point : tuple + In the form (x,y) + + point_list : list + in the form [point, point_1, point_2, ..., point_n] + """ + return point in point_list + +def create_random(n): + """ + A simple method to return n random points. + + Parameters + ---------- + n : integer + number of points desired + + Returns + ------- + points : n tuples of points + """ + points = [] + limit = range(n) + for i in limit: + points.append((random.uniform(0,1), random.uniform(0,1))) + + return points + +def permutations(p=99, n=100): + """ + A simple method to return n random permutations of opints. + + Parameters + ---------- + n : integer + number of points desired + + Returns + ------- + points : n tuples of points + """ + permutes = [] + limit = range(p) + for i in limit: + permutes.append(average_nearest_neighbor_distance(create_random(n))) + + return permutes + + +def getx(point): + """ + A simple method to return the x coordinate of + an tuple in the form(x,y). We will look at + sequences in a coming lesson. + + Parameters + ---------- + point : tuple + in the form (x,y) + + Returns + ------- + : int or float + x coordinate + """ + return point[0] + + +def gety(point): + """ + A simple method to return the x coordinate of + an tuple in the form(x,y). We will look at + sequences in a coming lesson. + + Parameters + ---------- + point : tuple + in the form (x,y) + + Returns + ------- + : int or float + y coordinate + """ + return point[1] +# Take a list of instances of your point class. +def average_nearest_neighbor_distance(points, mark=None): + """ + Given a set of points, compute the average nearest neighbor. + + Parameters + ---------- + points : list + A list of points in the form (x,y) + + Returns + ------- + mean_d : float + Average nearest neighbor distance + + References + ---------- + Clark and Evan (1954 Distance to Nearest Neighbor as a + Measure of Spatial Relationships in Populations. Ecology. 35(4) + p. 445-453. + """ + + #create empty list of distances + shortestDistList = [] + temp = [] + +# Accept a mark keyword argument where you can compute an average nearest neighbor distance for points with a shared mark. If mark is not provided, compute the average nearest neighbor using all points. + if mark is not None: + for point in points: + if point.mark is mark: + temp.append(point) + + else: + temp = points + + for i in temp: + shortest = 9999999999 + for j in temp: + if i!=j: + current = euclidean_distance(i,j) + if(current