I wanted to give an update here on the Criminal Justician series of blogs I have posted on the American Society of Evidence Based Policing (ASEBP) website. These include:
- Denver’s STAR Program and Disorder Crime Reductions
- Assessing whether Denver’s STAR alternative mental health responders can be expected to decrease a large number of low-level disorder crimes.
- Violent crime interventions that are worth it
- Two well-vetted methods – hot spots policing and focused deterrence – are worth the cost for police to implement to reduce violent crime.
- Evidence Based Oversight on Police Use of Force
- Collecting data in conjunction with clear administrative policies has strong evidence it overall reduces officer use of force.
- We don’t know what causes widespread crime trends
- While we can identify whether crime is rising or falling, retrospectively identifying what caused those ups and downs is much more difficult.
- I think scoop and run is a good idea
- Keeping your options open is typically better than restricting them. Police should have the option to take gun shot wound victims directly to the emergency room when appropriate.
- One (well done) intervention is likely better than many
- Piling on multiple interventions at once makes it impossible to tell if a single component is working, and is likely to have diminishing returns.
Going forward I will do a snippet on here, and refer folks to the ASEBP website. You need to sign up to be able to read that content – but it is an organization that is worth joining (besides for just reading my takes on science around policing topics).
So my CRIME De-Coder LLC has a focus on the merger of data science and policing. But I have a bit of wider potential application. Besides statistical analysis in different subject areas, one application I think will be of wider interest to public and private sector agencies is my experience in process automation. These often look like boring things – automating generating a report, sending an email, updating a dashboard, etc. But they can take substantial human labor, and automating also has the added benefit of making a process more robust.
As an example, I needed to submit my website as a PDF file to obtain a copyright. To do this, you need to take screenshots of your website and all its subsequent pages. Googling on this for selenium and python, the majority of the current solutions are out of date (due to changes in the Chrome driver in selenium over time). So here is the solution I scripted up the morning I wanted to submit the copyright – it took about 2 hours total in debugging. Note that this produces real screenshots of the website, not the print to pdf (which looks different).
It is short enough for me to just post the entire script here in a blog post:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options
import time
from PIL import Image
import os
home = 'https://crimede-coder.com/'
url_list = [home,
home + 'about',
home + 'blog',
home + 'contact',
home + 'services/ProgramAnalysis',
home + 'services/PredictiveAnalytics',
home + 'services/ProcessAutomation',
home + 'services/WorkloadAnalysis',
home + 'services/CrimeAnalysisTraining',
home + 'services/CivilLitigation',
home + 'blogposts/2023/ServicesComparisons']
res_png = []
def save_screenshot(driver, url, path, width):
driver.get(url)
# Ref: https://stackoverflow.com/a/52572919/
original_size = driver.get_window_size()
#required_width = driver.execute_script('return document.body.parentNode.scrollWidth')
required_width = width
required_height = driver.execute_script('return document.body.parentNode.scrollHeight')
driver.set_window_size(required_width,required_height)
#driver.save_screenshot(path) # has scrollbar
driver.find_element(By.TAG_NAME, 'body').screenshot(path) # avoids scrollbar
driver.set_window_size(original_size['width'], original_size['height'])
options = Options()
options.headless = True
driver = webdriver.Chrome(options=options)
for url in url_list:
driver.get(url)
if url == home:
name = "index.png"
else:
res_url = url.replace(home,"").replace("/","_")
name = res_url + ".png"
time.sleep(1)
res_png.append(name)
save_screenshot(driver,url,name,width=1400)
driver.quit()
# Now appending to PDF file
images = [Image.open(f).convert('RGB') for f in res_png if f[-3:] == 'png']
i1 = images.pop(0)
i1.save(r'Website.pdf', save_all=True, append_images=images)
# Now removing old PNG files
for f in res_png:
os.remove(f)
One of the reasons I want to expand knowledge of coding practices into policing (as well as other public sector fields) is that this simple of a thing doesn’t make sense for me to package up and try to monetize. The IP involved in a 2 hour script is not worth that much. I realize most police departments won’t be able to take the code above and actually use it – it is better for your agency to simply do a small contract with me to help you automate the boring stuff.
I believe this is in large part a better path forward for many public sector agencies, as opposed to buying very expensive Software-as-a-Service solutions. It is better to have a consultant to provide a custom solution for your specific agency, than to spend money on some big tool and hope your specific problems fit their mold.