From 5cd3f24b5b7ffd9d944e27f313f9f38a6852600f Mon Sep 17 00:00:00 2001 From: pkadambi Date: Tue, 15 Mar 2016 18:42:32 -0700 Subject: [PATCH 01/13] added code --- analytics.py | 112 +++++++++++++++++++++++++++++++++++++++ io_geojson.py | 23 ++++++++ tests/functional_test.py | 61 +++++++++++++++------ tests/point_test.py | 66 +++++++++++++++++++++++ utils.py | 55 +++++++++++++++++++ 5 files changed, 302 insertions(+), 15 deletions(-) create mode 100644 tests/point_test.py diff --git a/analytics.py b/analytics.py index e69de29..d7eb68c 100644 --- a/analytics.py +++ b/analytics.py @@ -0,0 +1,112 @@ +import random +import math + +import utils + +def p_perms(p=99,n=100,mark=None): + mean_nn_dist = [] + for i in range(p): + temp=utils.create_n_rand_pts(100) + temp1=average_nearest_neighbor_distance(temp) + mean_nn_dist.append(temp1); + + return mean_nn_dist + +def p_perms_marks(p=99,n=100,marks=None): + marks=['mercury', 'venus', 'earth', 'mars'] + mean_nn_dist = [] + for i in range(p): + temp=utils.create_marked_rand_pts(100,marks) + #print(temp.) + temp1=average_nearest_neighbor_distance_marks(temp,marks) + mean_nn_dist.append(temp1) + + return mean_nn_dist + +def monte_carlo_critical_bound_check(lb,ub,obs): + return obsub + +def minimum_bounding_rectangle(points): + xmin=points[1][0] + ymin=points[1][1] + xmax=points[1][0] + ymax=points[1][1] + + for i in points: + curr_x=i[0] + curr_y=i[1] + if curr_x < xmin: + xmin= curr_x + elif curr_x > xmax: + xmax= curr_x + + if curr_y < ymin: + ymin= curr_y + elif curr_y > ymax: + ymax= curr_y + mbr = [xmin,ymin,xmax,ymax] + + return mbr + +def find_largest_city(gj): + maximum=0; + features=gj['features'] + + for i in features: + if (i['properties']['pop_max']>maximum): + maximum=i['properties']['pop_max'] + city=i['properties']['nameascii'] + return city, maximum + + +def write_your_own(gj): + features=gj['features'] + count = 0 + for i in features: + if(' ' in i['properties']['name']): + count= count+1 + + return count + +def mean_center(points): + x_tot=0 + y_tot=0 + + for i in points: + x_tot+=i[0] + y_tot+=i[1] + + x = x_tot/len(points) + y = y_tot/len(points) + + return x, y + +def average_nearest_neighbor_distance_marks(points,mark=None): + mean_d = 0 + for i in range(len(points)): + dist_nearest=1e9 + for j in range(len(points)): + temp_p1 = (points[i].x, points[i].y) + temp_p2 = (points[j].x, points[j].y) + dist = utils.euclidean_distance(temp_p1, temp_p2) + if temp_p1 == temp_p2: + continue + elif dist < dist_nearest: + dist_nearest = dist; + mean_d += dist_nearest; + mean_d=mean_d/(len(points)) + return mean_d + +def average_nearest_neighbor_distance(points): + mean_d = 0 + for i in points: + dist_nearest=1e9 + for j in points: + dist = utils.euclidean_distance(i, j) + if i==j: + continue + elif dist < dist_nearest: + dist_nearest = dist; + mean_d += dist_nearest; + mean_d=mean_d/(len(points)) + return mean_d \ No newline at end of file diff --git a/io_geojson.py b/io_geojson.py index e69de29..15c85aa 100644 --- a/io_geojson.py +++ b/io_geojson.py @@ -0,0 +1,23 @@ +import json +def read_geojson(input_file): + """ + Read a geojson file + + Parameters + ---------- + input_file : str + The PATH to the data to be read + + Returns + ------- + gj : dict + An in memory version of the geojson + """ + + with open(input_file, 'r') as f: + gj=json.load(f) + + # Please use the python json module (imported above) + # to solve this one. + + return gj diff --git a/tests/functional_test.py b/tests/functional_test.py index 596af78..b551d68 100644 --- a/tests/functional_test.py +++ b/tests/functional_test.py @@ -1,10 +1,10 @@ import random import unittest -from .. import analytics -from .. import io_geojson -from .. import utils - +import analytics +import io_geojson +import utils +import point class TestFunctionalPointPattern(unittest.TestCase): @@ -12,8 +12,9 @@ def setUp(self): random.seed(12345) i = 0 self.points = [] + self.marks=['mercury','venus','earth','mars'] while i < 100: - seed = (round(random.random(),2), round(random.random(),2)) + seed = (round(random.random(),2), round(random.random(),2),random.choice(self.marks)) self.points.append(seed) n_additional = random.randint(5,10) i += 1 @@ -22,14 +23,13 @@ def setUp(self): for j in range(n_additional): x_offset = random.randint(0,10) / 100 y_offset = random.randint(0,10) / 100 - pt = (round(seed[0] + x_offset, 2), round(seed[1] + y_offset,2)) + pt = (round(seed[0] + x_offset, 2), round(seed[1] + y_offset,2),random.choice(self.marks)) self.points.append(pt) i += 1 if i == 100: break if i == 100: break - def test_point_pattern(self): """ This test checks that the code can compute an observed mean @@ -38,30 +38,61 @@ def test_point_pattern(self): nearest neighbor distance computed using a random realization of the point process. """ - random.seed() # Reset the random number generator using system time + random.seed(3673673) # Reset the random number generator using system time + # I do not know where you have moved avarege_nearest_neighbor_distance, so update the point_pattern module + observed_avg = analytics.average_nearest_neighbor_distance(self.points) + self.assertAlmostEqual(0.037507819095864134, observed_avg, 3) + + # Again, update the point_pattern module name for where you have placed the point_pattern module + # Also update the create_random function name for whatever you named the function to generate + # random points + rand_points = utils.create_n_rand_pts(100) + self.assertEqual(100, len(rand_points)) + + # As above, update the module and function name. + permutations = analytics.p_perms(99) + self.assertEqual(len(permutations), 99) + self.assertNotEqual(permutations[0], permutations[1]) + + # As above, update the module and function name. + lower, upper = utils.critical_pts(permutations) + self.assertTrue(lower > 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 = analytics.monte_carlo_critical_bound_check(lower, upper, 0) + self.assertTrue(significant) + + self.assertTrue(True) + + def test_marks(self): + random.seed(942323) # Reset the random number generator using system time # I do not know where you have moved avarege_nearest_neighbor_distance, so update the point_pattern module - observed_avg = point_pattern.average_nearest_neighbor_distance(self.points) - self.assertAlmostEqual(0.027, observed_avg, 3) + observed_avg = analytics.average_nearest_neighbor_distance(self.points) + self.assertAlmostEqual(0.037507819095864134, observed_avg, 3) # Again, update the point_pattern module name for where you have placed the point_pattern module # Also update the create_random function name for whatever you named the function to generate # random points - rand_points = point_pattern.create_random(100) + rand_points = utils.create_marked_rand_pts(100,self.marks) self.assertEqual(100, len(rand_points)) # As above, update the module and function name. - permutations = point_pattern.permutations(99) + permutations = analytics.p_perms_marks(99,self.marks) self.assertEqual(len(permutations), 99) + #print(permutations) self.assertNotEqual(permutations[0], permutations[1]) # As above, update the module and function name. - lower, upper = point_pattern.compute_critical(permutations) + lower, upper = utils.critical_pts(permutations) self.assertTrue(lower > 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.monte_carlo_critical_bound_check(lower, upper, 0) self.assertTrue(significant) - self.assertTrue(False) \ No newline at end of file + self.assertTrue(True) + \ No newline at end of file diff --git a/tests/point_test.py b/tests/point_test.py new file mode 100644 index 0000000..1a58744 --- /dev/null +++ b/tests/point_test.py @@ -0,0 +1,66 @@ +''' +Created on Mar 14, 2016 + +@author: Prad +''' +import random +import unittest +from point import Point + + +class TestFunctionalPointPattern(unittest.TestCase): + def test_set_point(self): + testPoint=Point(1,4) + self.assertTrue(testPoint.x==1 and testPoint.y==4) + + def test_coincidence(self): + testPoint=Point(1,4) + self.assertTrue(testPoint.check_if_coincident((1,4))) + + def test_shift(self): + testPoint=Point(1,4) + shift_x=10 + shift_y=10 + testPoint.shift_point(shift_x,shift_y) + self.assertEqual((testPoint.x,testPoint.y),(11,14)) + + def test_marked(self): + mark_list=['mercury', 'venus', 'earth', 'mars'] + point_list=[] + mer_count=0 + v_count=0 + e_count=0 + mar_count=0 + random.seed(43523) + for i in range(1,20): + curr_choice=random.choice(mark_list) + point_list.append(Point(1,1,curr_choice)) + if(curr_choice=='mercury'): + mer_count+=1 + elif(curr_choice=='venus'): + v_count+=1 + elif(curr_choice=='earth'): + e_count+=1 + else: + mar_count+=1 + mer_count_check=0 + v_count_check=0 + e_count_check=0 + mar_count_check=0 + + for i in range(1,20): + curr_mark=point_list.pop().mark + if(curr_mark=='mercury'): + mer_count_check+=1 + elif(curr_mark=='venus'): + v_count_check+=1 + elif(curr_mark=='earth'): + e_count_check+=1 + elif(curr_mark=='mars'): + mar_count_check+=1 + + self.assertEqual(mer_count,mer_count_check) + self.assertEqual(v_count, v_count_check) + self.assertEqual(e_count, e_count_check) + self.assertEqual(mar_count,mar_count_check) + \ No newline at end of file diff --git a/utils.py b/utils.py index e69de29..2089aac 100644 --- a/utils.py +++ b/utils.py @@ -0,0 +1,55 @@ +import math +import random +import point +from point import Point + + +def create_n_rand_pts(n): + n_pts = [(random.uniform(0,1), random.uniform(0,1)) for i in range(n)] + return n_pts + +def create_marked_rand_pts(n,marks=None): + n_pts=[] + for i in range(n): + chosen_mark=random.choice(marks) + temppt=point.Point(random.uniform(0,1), random.uniform(0,1),chosen_mark) + #print(temppt.x) + n_pts.append(temppt) + return n_pts + +def critical_pts(distances): + return min(distances), max(distances) + +def euclidean_distance(a, b): + distance = math.sqrt((a[0] - b[0])**2 + (a[1] - b[1])**2) + return distance + +def shift_point(point, x_shift, y_shift): + x = getx(point) + y = gety(point) + x += x_shift + y += y_shift + return x, y + +def expected_distance(area, n): + return 0.5*(math.sqrt(area/n)) + +def check_coincident(a, b): + return a == b + +def check_in(point, point_list): + return point in point_list + +def getx(point): + return point[0] + +def gety(point): + return point[1] + +def mbr_area(mbr): + return (mbr[3]-mbr[1])*(mbr[2]-mbr[0]) + +def manhattan_distance(a, b): + distance = abs(a[0] - b[0]) + abs(a[1] - b[1]) + return distance + From 7f830efa7622c4bd4fac15d93d7bed8b18313259 Mon Sep 17 00:00:00 2001 From: pkadambi Date: Tue, 15 Mar 2016 18:50:34 -0700 Subject: [PATCH 02/13] Update functional_test.py --- tests/functional_test.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/functional_test.py b/tests/functional_test.py index b551d68..98cd1f9 100644 --- a/tests/functional_test.py +++ b/tests/functional_test.py @@ -1,10 +1,10 @@ import random import unittest -import analytics -import io_geojson -import utils -import point +from .. import analytics +from .. io_geojson +from .. utils +from .. point class TestFunctionalPointPattern(unittest.TestCase): @@ -95,4 +95,4 @@ def test_marks(self): self.assertTrue(significant) self.assertTrue(True) - \ No newline at end of file + From 70868b358e159003db47c136279e90543f778778 Mon Sep 17 00:00:00 2001 From: pkadambi Date: Tue, 15 Mar 2016 18:50:59 -0700 Subject: [PATCH 03/13] Update point_test.py --- tests/point_test.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/point_test.py b/tests/point_test.py index 1a58744..220426c 100644 --- a/tests/point_test.py +++ b/tests/point_test.py @@ -5,7 +5,7 @@ ''' import random import unittest -from point import Point +from .point import Point class TestFunctionalPointPattern(unittest.TestCase): @@ -63,4 +63,4 @@ def test_marked(self): self.assertEqual(v_count, v_count_check) self.assertEqual(e_count, e_count_check) self.assertEqual(mar_count,mar_count_check) - \ No newline at end of file + From 1046f4926e17a953c8e2033aa7c86e365211ca63 Mon Sep 17 00:00:00 2001 From: pkadambi Date: Tue, 15 Mar 2016 18:54:06 -0700 Subject: [PATCH 04/13] Update functional_test.py --- tests/functional_test.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/functional_test.py b/tests/functional_test.py index 98cd1f9..5b9dca4 100644 --- a/tests/functional_test.py +++ b/tests/functional_test.py @@ -2,9 +2,9 @@ import unittest from .. import analytics -from .. io_geojson -from .. utils -from .. point +from .. import io_geojson +from .. import utils +from .. import point class TestFunctionalPointPattern(unittest.TestCase): From 99e67220ede3d9ed532c677dd7852ab8fd378e94 Mon Sep 17 00:00:00 2001 From: pkadambi Date: Tue, 15 Mar 2016 18:57:48 -0700 Subject: [PATCH 05/13] Update analytics.py --- analytics.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/analytics.py b/analytics.py index d7eb68c..8b05ff6 100644 --- a/analytics.py +++ b/analytics.py @@ -1,7 +1,7 @@ import random import math -import utils +import .utils def p_perms(p=99,n=100,mark=None): mean_nn_dist = [] @@ -109,4 +109,4 @@ def average_nearest_neighbor_distance(points): dist_nearest = dist; mean_d += dist_nearest; mean_d=mean_d/(len(points)) - return mean_d \ No newline at end of file + return mean_d From 3903916022b8d485ac8ba697dad985ae4c55d800 Mon Sep 17 00:00:00 2001 From: pkadambi Date: Tue, 15 Mar 2016 18:59:55 -0700 Subject: [PATCH 06/13] Update point.py --- point.py | 135 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 135 insertions(+) diff --git a/point.py b/point.py index e69de29..8b94e85 100644 --- a/point.py +++ b/point.py @@ -0,0 +1,135 @@ +import math # I am guessing that you will need to use the math module +import json # I would like you to use the JSON module for reading geojson (for now) +from math import sqrt +import utils + +class Point(): + def __init__(self, x=0, y=0, mark=[]): + self.x = x + self.y = y + self.mark = mark + + def read_geojson(self,input_file): + with open(input_file, 'r') as f: + gj=json.load(f) + + # Please use the python json module (imported above) + # to solve this one. + + return gj + + def check_if_coincident(self,secondPoint): + return utils.check_coincident((self.x,self.y),secondPoint) + + def shiftPoint(self, x_shift, y_shift): + return utils.shift_point((self.x,self.y),x_shift,y_shift) + + def shift_point(self,x_shift, y_shift): + self.x += x_shift + self.y += y_shift + return self.x, self.y + +def find_largest_city(gj): + maximum=0; + features=gj['features'] + + for i in features: + if (i['properties']['pop_max']>maximum): + maximum=i['properties']['pop_max'] + city=i['properties']['nameascii'] + return city, maximum + +def write_your_own(gj): + #Calculate the number of citues with two-word names + features=gj['features'] + count = 0 + for i in features: + if(' ' in i['properties']['name']): + count= count+1 + + return count + +def mean_center(points): + x_tot=0 + y_tot=0 + + for i in points: + x_tot+=i[0] + y_tot+=i[1] + + x = x_tot/len(points) + y = y_tot/len(points) + + return x, y + +def average_nearest_neighbor_distance(points): + mean_d = 0 + for i in points: + dist_nearest=1e9 + for j in points: + dist = euclidean_distance(i, j) + if i==j: + continue + elif dist < dist_nearest: + dist_nearest = dist; + mean_d += dist_nearest; + mean_d=mean_d/(len(points)) + return mean_d + +def minimum_bounding_rectangle(points): + #set initial params + xmin=points[1][0] + ymin=points[1][1] + xmax=points[1][0] + ymax=points[1][1] + + for i in points: + curr_x=i[0] + curr_y=i[1] + if curr_x < xmin: + xmin= curr_x + elif curr_x > xmax: + xmax= curr_x + + if curr_y < ymin: + ymin= curr_y + elif curr_y > ymax: + ymax= curr_y + mbr = [xmin,ymin,xmax,ymax] + + return mbr + +def mbr_area(mbr): + return (mbr[3]-mbr[1])*(mbr[2]-mbr[0]) + +def expected_distance(area, n): + return 0.5*(sqrt(area/n)) + +def manhattan_distance(a, b): + distance = abs(a[0] - b[0]) + abs(a[1] - b[1]) + return distance + +def euclidean_distance(a, b): + distance = math.sqrt((a[0] - b[0])**2 + (a[1] - b[1])**2) + return distance + +def shift_point(point, x_shift, y_shift): + x = point + y = gety(point) + + x += x_shift + y += y_shift + + return x, y + +def check_coincident(a, b): + return a == b + +def check_in(point, point_list): + return point in point_list + +def getx(point): + return point[0] + +def gety(point): + return point[1] From 062224d5c3bd9ced3c4626ca8251d6aac8145f4d Mon Sep 17 00:00:00 2001 From: pkadambi Date: Tue, 15 Mar 2016 19:00:05 -0700 Subject: [PATCH 07/13] Update point.py --- point.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/point.py b/point.py index 8b94e85..5df30e3 100644 --- a/point.py +++ b/point.py @@ -1,7 +1,7 @@ import math # I am guessing that you will need to use the math module import json # I would like you to use the JSON module for reading geojson (for now) from math import sqrt -import utils +import .utils class Point(): def __init__(self, x=0, y=0, mark=[]): From 56d9e09330ed784f1eb7c74b2117444474601250 Mon Sep 17 00:00:00 2001 From: pkadambi Date: Tue, 15 Mar 2016 19:00:27 -0700 Subject: [PATCH 08/13] Update utils.py --- utils.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/utils.py b/utils.py index 2089aac..803d467 100644 --- a/utils.py +++ b/utils.py @@ -1,7 +1,7 @@ import math import random -import point -from point import Point +import .point +from .point import Point def create_n_rand_pts(n): From c1dc862392484e8be24a3649e869045ba24729dd Mon Sep 17 00:00:00 2001 From: pkadambi Date: Tue, 15 Mar 2016 19:03:28 -0700 Subject: [PATCH 09/13] Update analytics.py --- analytics.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/analytics.py b/analytics.py index 8b05ff6..60e7e68 100644 --- a/analytics.py +++ b/analytics.py @@ -1,7 +1,7 @@ import random import math -import .utils +from . import utils def p_perms(p=99,n=100,mark=None): mean_nn_dist = [] From e14502a7869381ff0ec573463a625b1fe09f1215 Mon Sep 17 00:00:00 2001 From: pkadambi Date: Tue, 15 Mar 2016 19:03:45 -0700 Subject: [PATCH 10/13] Update point.py --- point.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/point.py b/point.py index 5df30e3..7330b96 100644 --- a/point.py +++ b/point.py @@ -1,7 +1,7 @@ import math # I am guessing that you will need to use the math module import json # I would like you to use the JSON module for reading geojson (for now) from math import sqrt -import .utils +from . import utils class Point(): def __init__(self, x=0, y=0, mark=[]): From b95e27f5d85c4f641164f4d540698efd740eba7a Mon Sep 17 00:00:00 2001 From: pkadambi Date: Tue, 15 Mar 2016 19:04:06 -0700 Subject: [PATCH 11/13] Update utils.py --- utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils.py b/utils.py index 803d467..4c16857 100644 --- a/utils.py +++ b/utils.py @@ -1,6 +1,6 @@ import math import random -import .point +from . import point from .point import Point From bf052785613690f945e524994cd534bcfd1814ac Mon Sep 17 00:00:00 2001 From: pkadambi Date: Tue, 15 Mar 2016 19:11:30 -0700 Subject: [PATCH 12/13] Update point_test.py --- tests/point_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/point_test.py b/tests/point_test.py index 220426c..8acaede 100644 --- a/tests/point_test.py +++ b/tests/point_test.py @@ -5,7 +5,7 @@ ''' import random import unittest -from .point import Point +from ..point import Point class TestFunctionalPointPattern(unittest.TestCase): From 9c2d4e08963120af5f1de2829302ead106c84049 Mon Sep 17 00:00:00 2001 From: pkadambi Date: Wed, 16 Mar 2016 00:19:07 -0700 Subject: [PATCH 13/13] Update analytics.py --- analytics.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/analytics.py b/analytics.py index 60e7e68..db1ca31 100644 --- a/analytics.py +++ b/analytics.py @@ -84,7 +84,7 @@ def mean_center(points): def average_nearest_neighbor_distance_marks(points,mark=None): mean_d = 0 for i in range(len(points)): - dist_nearest=1e9 + dist_nearest=math.inf for j in range(len(points)): temp_p1 = (points[i].x, points[i].y) temp_p2 = (points[j].x, points[j].y) @@ -100,7 +100,7 @@ def average_nearest_neighbor_distance_marks(points,mark=None): def average_nearest_neighbor_distance(points): mean_d = 0 for i in points: - dist_nearest=1e9 + dist_nearest=math.inf for j in points: dist = utils.euclidean_distance(i, j) if i==j: