Source code for crime

import pandas as pd
import geopandas as gpd
import random

from typing import List


[docs]class Crime: def __init__(self, bounds: gpd.GeoDataFrame, crime_api: pd.DataFrame): """Initial x y values for crimes. Crime xy values are taken from the data.police.uk API and selected based on the extent of the bounds polygon. To determine whether points fall within the polygon bounds, the function gpd.within() is used. Args: bounds (gpd.GeoDataFrame): Input bounds polygon. crime_api (pd.DataFrame): xy coordinates for bounds extent from police api. """ # takes bounds from main.py self.bounds = bounds self.crime_api = crime_api # initial variables self.col = "Red" self.solved = 0 # loop to take random crime point from api that falls within bounds # polygon while True: # int to find random row in dataframe from api i = random.randint(0, len(self.crime_api) - 1) x = self.crime_api['x'].loc[i] y = self.crime_api['y'].loc[i] # convert point to geodatafame df = pd.DataFrame({'x': [x], 'y': [y]}) geom = gpd.points_from_xy(df.x, df.y) gdf = gpd.GeoDataFrame(df, geometry=geom) # find if point falls within polygon within = int(gdf.within(self.bounds)) # while loop breaks only if point is within if within == 1: self.x = gdf['x'] self.y = gdf['y'] self.geom = gdf['geometry'] break
[docs] def distance_between(self, agent) -> int: """Euclidean distance between two geographic points. The output represents the distance referring to the geographic unit of the projection used. Args: agent (Police): A police object with coordinates xy. Returns: int: Distance with values associated with the projection. DOCTESTS: >>> a = pd.DataFrame(); b = pd.DataFrame() >>> a.x = 1; a.y = 1 >>> b.x = 1; b.y = 1 >>> Crime.distance_between(a, b) 0.0 >>> a = pd.DataFrame(); b = pd.DataFrame() >>> a.x = 10; a.y = 1 >>> b.x = 1; b.y = 1 >>> Crime.distance_between(a, b) 9.0 >>> a = pd.DataFrame(); b = pd.DataFrame() >>> a.x = 1; a.y = 1 >>> b.x = 1; b.y = 10 >>> Crime.distance_between(a, b) 9.0 """ return ((self.x - agent.x)**2 + (self.y - agent.y)**2)**0.5
[docs] def solve(self, police_list): """Solve a crime by proximity to police. A crime is determined to be solved if within a specified distance from a police officer, and given a random 50% chance. Args: police_list ([TODO:type]): [TODO:description] """ # solve a crime if police is within a certain distance for pol in police_list: distance = float(self.distance_between(pol)) if distance < 500: self.col = "Green" self.solved = 1