def _attempt_to_commit(name, level, statute):
     if (level == "misdemeanor class a"
             or level == "felony class c") and "attempt to commit" in name:
         question_string = "Was the underlying conduct a sex crime?"
         charge_type_by_level = ChargeClassifier._classification_by_level(
             level, statute).ambiguous_charge_type[0]
         options = {"Yes": SexCrime(), "No": charge_type_by_level}
         return ChargeClassifier._build_ambiguous_charge_type_with_question(
             question_string, options)
     if level == "felony class b" and "attempt to commit" in name:
         question_string = "Was this a drug-related charge?"
         drug_crime_question_string = "Was the underlying substance marijuana?"
         drug_crime_options = {
             "Yes": MarijuanaEligible(),
             "No": FelonyClassB()
         }
         drug_crime_classification = ChargeClassifier._build_ambiguous_charge_type_with_question(
             drug_crime_question_string, drug_crime_options)
         drug_crime_question_id = f"{question_string}-Yes-{drug_crime_classification.question.question_id}"  # type: ignore
         drug_crime_question = replace(drug_crime_classification.question,
                                       question_id=drug_crime_question_id)
         charge_types = drug_crime_classification.ambiguous_charge_type + [
             PersonFelonyClassB()
         ]
         question = Question(
             question_string,
             question_string,
             {
                 "Yes":
                 Answer(question=drug_crime_question),
                 "No":
                 Answer(edit={"charge_type": PersonFelonyClassB.__name__}),
             },
         )
         return AmbiguousChargeTypeWithQuestion(charge_types, question)
Example #2
0
 def create(charge_id, **kwargs) -> Tuple[AmbiguousCharge, Optional[Question]]:
     case_number = kwargs["case_number"]
     violation_type = kwargs["violation_type"]
     name = kwargs["name"]
     statute = ChargeCreator.__strip_non_alphanumeric_chars(kwargs["statute"])
     level = kwargs["level"]
     chapter = ChargeCreator._set_chapter(kwargs["statute"])
     section = ChargeCreator.__set_section(statute)
     disposition = kwargs.get("disposition")
     ambiguous_charge_type_with_questions = ChargeClassifier(
         violation_type, name, statute, level, chapter, section, disposition
     ).classify()
     kwargs["date"] = datetime.date(datetime.strptime(kwargs["date"], "%m/%d/%Y"))
     kwargs["_chapter"] = chapter
     kwargs["_section"] = section
     kwargs["statute"] = statute
     kwargs["ambiguous_charge_id"] = f"{case_number}-{charge_id}"
     classifications = ambiguous_charge_type_with_questions.ambiguous_charge_type
     question = ambiguous_charge_type_with_questions.question
     options = ambiguous_charge_type_with_questions.options
     assert len(classifications) == len(options) if options else True
     ambiguous_charge = []
     options_dict = {}
     for i, classification in enumerate(classifications):
         uid = f"{case_number}-{charge_id}-{i}"
         charge_dict = {**kwargs, "id": uid}
         charge = from_dict(data_class=classification, data=charge_dict)
         ambiguous_charge.append(charge)
         if options:
             options_dict[options[i]] = uid
     if question:
         ambiguous_charge_id = ambiguous_charge[0].ambiguous_charge_id
         return ambiguous_charge, Question(ambiguous_charge_id, question, options_dict)
     else:
         return ambiguous_charge, None
Example #3
0
def test_disambiguate_endpoint_with_diverted_answer(record_with_single_duii):
    ambiguous_record = record_with_single_duii[1]
    answers = {
        "CASEJD1-1":
        Question(
            ambiguous_charge_id="CASEJD1-1",
            case_number="CASEJD1",
            question=
            "Was the charge dismissed pursuant to a court-ordered diversion program?",
            options={
                "Yes": "CASEJD1-1-0",
                "No": "CASEJD1-1-1"
            },
            answer="CASEJD1-1-0",
        )
    }
    questions = json.loads(json.dumps(answers))
    unknown_dispositions = record_with_single_duii[3]
    questions, record = Search.disambiguate_record(ambiguous_record, questions)
    record_summary = RecordSummarizer.summarize(record, questions,
                                                unknown_dispositions)
    response_data = {"record": record_summary}
    response_as_dict = json.loads(
        json.dumps(response_data, cls=ExpungeModelEncoder))
    assert response_as_dict == DIVERTED_RESPONSE
Example #4
0
 def _manufacture_delivery(name, level, statute):
     if any([
             manu_del_keyword in name
             for manu_del_keyword in ["delivery", "manu/del", "manufactur"]
     ]):
         if any([
                 schedule_2_keyword in name for schedule_2_keyword in
             ["2", "ii", "heroin", "cocaine", "meth"]
         ]):
             if level == "Felony Unclassified":
                 question_string = "Was the charge for an A Felony or B Felony?"
                 options = {
                     "A Felony": FelonyClassA(),
                     "B Felony": FelonyClassB()
                 }
                 return ChargeClassifier._build_ambiguous_charge_type_with_question(
                     question_string, options)
         elif any([
                 schedule_3_keyword in name
                 for schedule_3_keyword in ["3", "iii", "4", " iv"]
         ]):
             return ChargeClassifier._classification_by_level(
                 level, statute)
         else:
             # The name contains either a "1" or no schedule number, and thus is possibly a marijuana charge.
             question_string = "Was the underlying substance marijuana?"
             charge_types_with_question = ChargeClassifier._classification_by_level(
                 level, statute)
             if level == "Felony Unclassified":
                 felony_unclassified_question_id = (
                     f"{question_string}-No-{charge_types_with_question.question.question_id}"
                 )
                 felony_unclassified_question = replace(
                     charge_types_with_question.question,
                     question_id=felony_unclassified_question_id)
                 charge_types = [
                     MarijuanaEligible()
                 ] + charge_types_with_question.ambiguous_charge_type
                 question = Question(
                     question_string,
                     question_string,
                     {
                         "Yes":
                         Answer(edit={
                             "charge_type": MarijuanaEligible.__name__
                         }),
                         "No":
                         Answer(question=felony_unclassified_question),
                     },
                 )
                 return AmbiguousChargeTypeWithQuestion(
                     charge_types, question)
             elif level == "Felony Class A" or level == "Felony Class B":
                 charge_type = charge_types_with_question.ambiguous_charge_type[
                     0]
                 options = {"Yes": MarijuanaEligible(), "No": charge_type}
                 return ChargeClassifier._build_ambiguous_charge_type_with_question(
                     question_string, options)
 def _build_ambiguous_charge_type_with_question(
         question: str,
         options: Dict[str, ChargeType]) -> AmbiguousChargeTypeWithQuestion:
     options_dict = {}
     charge_types = []
     for key, value in options.items():
         charge_types.append(value)
         options_dict[key] = Answer(
             edit={"charge_type": value.__class__.__name__})
     return AmbiguousChargeTypeWithQuestion(
         charge_types, Question(question, question, options_dict))
 def _handle_pcs_and_manufacture_delivery(name, level, statute,
                                          schedule_2_handler):
     if any([
             schedule_2_keyword in name for schedule_2_keyword in
         ["2", "ii", "heroin", "cocaine", "meth"]
     ]):
         return schedule_2_handler(level)
     elif any([
             schedule_3_keyword in name
             for schedule_3_keyword in ["3", "iii", "4", " iv"]
     ]):
         return ChargeClassifier._classification_by_level(level, statute)
     else:
         # The name contains either a "1" or no schedule number, and thus is possibly a marijuana charge.
         question_string = "Was the underlying substance marijuana?"
         charge_types_with_question = ChargeClassifier._classification_by_level(
             level, statute)
         if level == "felony unclassified":
             felony_unclassified_question_id = (
                 f"{question_string}-No-{charge_types_with_question.question.question_id}"
             )
             felony_unclassified_question = replace(
                 charge_types_with_question.question,
                 question_id=felony_unclassified_question_id)
             charge_types = [
                 MarijuanaManufactureDelivery()
             ] + charge_types_with_question.ambiguous_charge_type
             question = Question(
                 question_string,
                 question_string,
                 {
                     "Yes":
                     Answer(edit={
                         "charge_type":
                         MarijuanaManufactureDelivery.__name__
                     }),
                     "No":
                     Answer(question=felony_unclassified_question),
                 },
             )
             return AmbiguousChargeTypeWithQuestion(charge_types, question)
         elif level == "felony class a" or level == "felony class b":
             charge_type = charge_types_with_question.ambiguous_charge_type[
                 0]
             options = {
                 "Yes": MarijuanaManufactureDelivery(),
                 "No": charge_type
             }
             return ChargeClassifier._build_ambiguous_charge_type_with_question(
                 question_string, options)
def test_disambiguate_endpoint_with_diverted_answer(record_with_single_duii):
    ambiguous_record = record_with_single_duii[1]
    answers = {
        "CASEJD1-1":
        Question(
            ambiguous_charge_id="CASEJD1-1",
            question=
            "Was the charge dismissed pursuant to a court-ordered diversion program?",
            options={
                "Yes": "CASEJD1-1-0",
                "No": "CASEJD1-1-1"
            },
            answer="CASEJD1-1-0",
        )
    }
    questions = json.loads(json.dumps(answers))
    response = Disambiguate.build_response(ambiguous_record, questions)
    response_as_dict = json.loads(response)
    assert response_as_dict == DIVERTED_RESPONSE
 def _build_case(
     oeci_case: OeciCase, new_charges: List[Charge]
 ) -> Tuple[AmbiguousCase, List[QuestionSummary]]:
     ambiguous_charges: List[AmbiguousCharge] = []
     questions: List[QuestionSummary] = []
     for oeci_charge in oeci_case.charges:
         ambiguous_charge_id = oeci_charge.ambiguous_charge_id
         charge_dict = {
             "name": oeci_charge.name,
             "statute": oeci_charge.statute,
             "level": oeci_charge.level,
             "date": oeci_charge.date,
             "disposition": oeci_charge.disposition,
             "probation_revoked": oeci_charge.probation_revoked,
             "balance_due_in_cents": oeci_charge.balance_due_in_cents,
             "case_number": oeci_case.summary.case_number,
             "violation_type": oeci_case.summary.violation_type,
             "birth_year": oeci_case.summary.birth_year,
             "edit_status": EditStatus(oeci_charge.edit_status),
         }
         if oeci_charge.disposition.status == DispositionStatus.UNKNOWN:
             charge_dict.pop("disposition")
             ambiguous_charge_dismissed, question_dismissed = ChargeCreator.create(
                 ambiguous_charge_id,
                 **charge_dict,
                 disposition=DispositionCreator.create(
                     date_class.today(), "dismissed"),
             )
             ambiguous_charge_convicted, question_convicted = ChargeCreator.create(
                 ambiguous_charge_id,
                 **charge_dict,
                 disposition=DispositionCreator.create(
                     date_class.future(), "convicted"),
             )
             if RecordCreator._disposition_question_is_irrelevant(
                     ambiguous_charge_convicted,
                     ambiguous_charge_dismissed):
                 ambiguous_charges.append(ambiguous_charge_dismissed)
                 question = RecordCreator._append_ambiguous_charge_id_to_question_id(
                     question_dismissed, ambiguous_charge_id
                 ) if question_dismissed else None  # type: ignore # TODO: Fix type
             else:
                 ambiguous_charges.append(ambiguous_charge_dismissed +
                                          ambiguous_charge_convicted)
                 disposition_question_text = "Choose the disposition"
                 question_id_prefix = ambiguous_charge_id + disposition_question_text
                 dismissed_option = RecordCreator._build_option(
                     question_dismissed, "Dismissed",
                     f"{question_id_prefix}-dismissed")
                 convicted_option = RecordCreator._build_option(
                     question_convicted, "Convicted",
                     f"{question_id_prefix}-convicted")
                 probation_revoked_option = RecordCreator._build_probation_revoked_option(
                     question_convicted, f"{question_id_prefix}-revoked")
                 unknown_option = {"Unknown": Answer()}
                 question = Question(
                     question_id_prefix,
                     disposition_question_text,
                     {
                         **dismissed_option,
                         **convicted_option,
                         **probation_revoked_option,
                         **unknown_option
                     },
                 )
         else:
             ambiguous_charge, maybe_question = ChargeCreator.create(
                 ambiguous_charge_id, **charge_dict)
             ambiguous_charges.append(ambiguous_charge)
             question = RecordCreator._append_ambiguous_charge_id_to_question_id(
                 maybe_question, ambiguous_charge_id
             ) if maybe_question else None  # type: ignore # TODO: Fix type
         if question:
             question_summary = QuestionSummary(
                 ambiguous_charge_id, oeci_case.summary.case_number,
                 question)
             questions.append(question_summary)
     ambiguous_charges += [[charge] for charge in new_charges]
     ambiguous_case: AmbiguousCase = []
     for charges in product(*ambiguous_charges):
         possible_case = Case(oeci_case.summary, charges=tuple(charges))
         ambiguous_case.append(possible_case)
     return ambiguous_case, questions