Simplify, simplify
08/26/2006 13:40 Filed in: PolicePro
A New York police department ran into a problem with
their Uniform Crime Reporting this month when they
had no arrests of anyone under 18 for the month. The
error trap I had for that situation was in the wrong
place in a very long and obtuse script, written eight
years ago and just brought along as is into the
subsequent updates and rewrites of PolicePro.
So I'm looking at this thing and trying to figure out where the break is, and of course when you do this, you inevitably just get stuck and miss the obvious: this so-called script was a disaster, and while it had been sort of modularized (calling two external scripts to handle the actual Print events of the two reports it produces, Over 17 and Under 18 arrests), the modules were broken out in the wrong places and missed the whole point of doing it in the first place.
The only way out of stuff like this is to step back, hit the Delete button, and start all over again writing the routines. And Part Two of that, the important part, is that when you're doing stuff in (hopefully) logical modules or sequences, you need to work from the bottom up instead of from the top down! The Top Down approach has you trying to get the whole grand sequence in some kind of order, creating pieces to handle the If branches as they arise. That's how I originally wrote this, and that's what was wrong with the damn thing.
Bottom up means you start at the basic steps: write routines for extracting the Over and Under 18 stuff, THEN tie it all together into something that runs at the mouseclick or is called from an even further up script.
And in the end, clarity! What was once this (calling two poorly thought out subscripts for the Print events and one to end up at the proper Admin menu):
#Called by UCR Reporting script
Set Error Capture (On)
Enter Browse Mode [ ]
Go to Layout ["Arrest List" (Arrests)]
Enter Find Mode
#Set criteria for arrests over 18 this date range.
Set Field [Arrests::Arrest_Date; Prefs::gLastDate]
Set Field [Arrests::Age; ">17"]
Set Field [Arrests::UCR_Crime_Type_Flag_Calc; 0]
Perform Find
#
If [Get (LastError) = 0]
#No errors occurred, and the report for Over 18 is run.
Perform Script ["Print UCR Arrests Over 18 - 2"]
#Now set Find Criteria for arrests under 18 this date range.
Enter Find Mode
Set Field [Arrests::Arrest_Date; Prefs::gLastDate]
Set Field [Arrests::Age; "<18"]
Set Field [Arrests::UCR_Crime_Type_Flag_Calc; 0]
Perform Find
#
If [Get(LastError) = 0]
Perform Script ["Print UCR Arrests Under 18 - 3"]
Perform Script ["Switch To Administrative Menu"]
#
Else
#No arrest records over 18 found for this date range.
#Run through the Under 18 FInd criteria and Find again.
Show Custom Dialog ["No arrests over 18 were found. The script will run the Under 18 report only."]
Enter Find Mode
Set Field [Arrests::Arrest_Date; Prefs::gLastDate]
Set Field [Arrests::Age; "<18"]
Set Field [Arrests::UCR_Crime_Type_Flag_Calc; 0]
Perform Find
#
If [Get(LastError) = 0]
Perform Script ["Print UCR Arrests Under 18 - 3"]
Perform Script ["Switch To Administrative Menu"]
#
Else
Show Custom Dialog ["No records were found for arrests under 18."]
End If
End If
End If
#
Perform Script ["Switch To Adminstrative Menu"]
Became this:
#8/23/2006 dwl
#Called by UCR Reporting script.
#----------------------------------------------------
Set Error Capture [On]
Enter Browse Mode
Perform Script ["Print UCR Arrests Over 18 - 2"]
Perform Script ["Print UCR Arrests Under 18 - 3"]
Perform Script ["Switch To Administrative Menu"]
Well, THAT'S a little easier to understand! By way of making excuses for myself, I'll restate that I wrote this mess back in 1997 or 1998, and that when I did the big rewrite, I just shoved the existing UCR stuff in As Is because it worked, and I had just finished defining 845 UCR related fields from scratch and by hand. So there it lay, quiet and messy, until a slow arrest month brought it onto my desktop again.
The new script calls the same two subscripts as before, but this time the Set Field and Find steps - and the Error Captures - are in THOSE scripts where they should have been all along. They're exacty the same except for the Find criteria on the Age field and the layout they go to for the Print step.
This thing was the Filemaker developer's version of getting hit by a bus while sporting old underwear. When you get to the emergency room, everyone has a good laugh at your expense. So now on the rare occasions I don't have much to do, I guess I'll be revisiting what's left of the old pre 2004 code and seeing what other horrors lurk there. Just because it works don't mean it's pretty!
So I'm looking at this thing and trying to figure out where the break is, and of course when you do this, you inevitably just get stuck and miss the obvious: this so-called script was a disaster, and while it had been sort of modularized (calling two external scripts to handle the actual Print events of the two reports it produces, Over 17 and Under 18 arrests), the modules were broken out in the wrong places and missed the whole point of doing it in the first place.
The only way out of stuff like this is to step back, hit the Delete button, and start all over again writing the routines. And Part Two of that, the important part, is that when you're doing stuff in (hopefully) logical modules or sequences, you need to work from the bottom up instead of from the top down! The Top Down approach has you trying to get the whole grand sequence in some kind of order, creating pieces to handle the If branches as they arise. That's how I originally wrote this, and that's what was wrong with the damn thing.
Bottom up means you start at the basic steps: write routines for extracting the Over and Under 18 stuff, THEN tie it all together into something that runs at the mouseclick or is called from an even further up script.
And in the end, clarity! What was once this (calling two poorly thought out subscripts for the Print events and one to end up at the proper Admin menu):
#Called by UCR Reporting script
Set Error Capture (On)
Enter Browse Mode [ ]
Go to Layout ["Arrest List" (Arrests)]
Enter Find Mode
#Set criteria for arrests over 18 this date range.
Set Field [Arrests::Arrest_Date; Prefs::gLastDate]
Set Field [Arrests::Age; ">17"]
Set Field [Arrests::UCR_Crime_Type_Flag_Calc; 0]
Perform Find
#
If [Get (LastError) = 0]
#No errors occurred, and the report for Over 18 is run.
Perform Script ["Print UCR Arrests Over 18 - 2"]
#Now set Find Criteria for arrests under 18 this date range.
Enter Find Mode
Set Field [Arrests::Arrest_Date; Prefs::gLastDate]
Set Field [Arrests::Age; "<18"]
Set Field [Arrests::UCR_Crime_Type_Flag_Calc; 0]
Perform Find
#
If [Get(LastError) = 0]
Perform Script ["Print UCR Arrests Under 18 - 3"]
Perform Script ["Switch To Administrative Menu"]
#
Else
#No arrest records over 18 found for this date range.
#Run through the Under 18 FInd criteria and Find again.
Show Custom Dialog ["No arrests over 18 were found. The script will run the Under 18 report only."]
Enter Find Mode
Set Field [Arrests::Arrest_Date; Prefs::gLastDate]
Set Field [Arrests::Age; "<18"]
Set Field [Arrests::UCR_Crime_Type_Flag_Calc; 0]
Perform Find
#
If [Get(LastError) = 0]
Perform Script ["Print UCR Arrests Under 18 - 3"]
Perform Script ["Switch To Administrative Menu"]
#
Else
Show Custom Dialog ["No records were found for arrests under 18."]
End If
End If
End If
#
Perform Script ["Switch To Adminstrative Menu"]
Became this:
#8/23/2006 dwl
#Called by UCR Reporting script.
#----------------------------------------------------
Set Error Capture [On]
Enter Browse Mode
Perform Script ["Print UCR Arrests Over 18 - 2"]
Perform Script ["Print UCR Arrests Under 18 - 3"]
Perform Script ["Switch To Administrative Menu"]
Well, THAT'S a little easier to understand! By way of making excuses for myself, I'll restate that I wrote this mess back in 1997 or 1998, and that when I did the big rewrite, I just shoved the existing UCR stuff in As Is because it worked, and I had just finished defining 845 UCR related fields from scratch and by hand. So there it lay, quiet and messy, until a slow arrest month brought it onto my desktop again.
The new script calls the same two subscripts as before, but this time the Set Field and Find steps - and the Error Captures - are in THOSE scripts where they should have been all along. They're exacty the same except for the Find criteria on the Age field and the layout they go to for the Print step.
This thing was the Filemaker developer's version of getting hit by a bus while sporting old underwear. When you get to the emergency room, everyone has a good laugh at your expense. So now on the rare occasions I don't have much to do, I guess I'll be revisiting what's left of the old pre 2004 code and seeing what other horrors lurk there. Just because it works don't mean it's pretty!
|
Bethlehem
08/11/2006 10:53 Filed in: Cops
Yesterday afternoon, at the end of the most sensational case and trial in a long time in upstate New York, their son Christopher Porco was found guilty of the murder of his father and attempted murder of his mother, who - mercifully - has no recollection of the attack.
This case is a terrible tragedy for everyone concerned, with plenty of "collateral damage" inflicted both by circumstance and by the actions of the defense team. Seeking a scapegoat, the defense attacked the Bethlehem police department and particularly one detective who worked the case and conveniently - for them - died during the investigation. It was not long before that detective in particular became the corrupt, manipulative and vengeful bad cop, and his family along with his memory were tarnished in the news - pretty much constantly.
Well, they got an intelligent jury who looked at the evidence - which was in fact the result of an outstanding investigation by the Bethlehem cops and the New York State Police and their amazing forensic team - and not only found Porco guilty, but vindicated the Bethlehem cops and gave their detectives, alive and deceased, their good names back. The circumstantial case that the cops and the Albany County DA's office put together is a textbook of intelligent detective work and thinking outside the box on occasion. Nice job.
The Albany Times_Union's coverage and summary of the case is pretty good, too, and includes the timeline put together by the prosecution that put the jury over the top. We did plenty of timeline cases in my detective days as well - they're a damn good way to turn a bunch of information into a compelling story.
Kudos to all the cops in this caper, and wishes for some sort of peace and hope for Mrs. Porco and her other son, Jonathan.
Copcast
08/01/2006 16:06 Filed in: Cops
Greg advised me several weeks ago about Copcast, a weekly podcast on
police culture, police news and technology. It
is uploaded every Sunday, the work of Mack
Pettigrew and Rich Schumaker, cops from Ontario,
Canada and Salem, Virginia. These guys mix
general police banter with training
announcements, guest discussions, technology
news, and, unfortunately, weekly updates on
police deaths across the US and Canada.
Copcast is an intelligent and entertaining effort by working cops who know their subjects. You can even subscribe to the podcasts on iTunes and put them on an iPod for something to listen to on the night shift, if you're a midnight marauder! I worked nights as a patrol cop and a sergeant for years - in those days, we didn't even have AM radios in the police cars. Times change...
I don't know either one of the Copcast guys, and have no affiliation with them - just feel it's worth listening to and wish them well.
Copcast is an intelligent and entertaining effort by working cops who know their subjects. You can even subscribe to the podcasts on iTunes and put them on an iPod for something to listen to on the night shift, if you're a midnight marauder! I worked nights as a patrol cop and a sergeant for years - in those days, we didn't even have AM radios in the police cars. Times change...
I don't know either one of the Copcast guys, and have no affiliation with them - just feel it's worth listening to and wish them well.