file handling the lineand if this leaves us with an empty line (and providing we are not in the middle of narrative)we simply skip to the next line this means that the number of blank lines between incidents doesn' matterbut that we preserve any blank lines that are in narrative texts if the narrative is not none we know that we are in narrative if the line is the narrative end marker we know that we have not only finished reading the narrativebut also finished reading all the data for the current incident in this case we put the narrative text into the data dictionary (having removed the indentation with the textwrap dedent(function)and providing we have the nine pieces of data we needwe create new incident and store it in the dictionary then we clear the data dictionary and reset the narrative variable ready for the next record on the other handif the line isn' the narrative end markerwe append it to the narrative--including the newline that was stripped off at the beginning elif (not data and line[ ="[and line[- ="]")data["report_id"line[ :- if the narrative is none then we are at either new report id or are reading some other data we could be at new report id only if the data dictionary is empty (because it starts that way and because we clear it after reading each incident)and if the line begins with and ends with if this is the case we put the report id into the data dictionary this means that this elif condition will not be true again until the data dictionary is next cleared elif "=in linekeyvalue line split("=" if key ="date"data[keydatetime datetime strptime(value"% -% -% "date(elif key ="pilot_percent_hours_on_type"data[keyfloat(valueelif key ="pilot_total_hours"data[keyint(valueelif key ="midair"data[keybool(int(value)elsedata[keyvalue elif line =narrative_start "narrative "elseraise keyerror("parsing error on line { }formatlino)