vancauwe commited on
Commit
995b526
·
1 Parent(s): 88563b5

feat: validation for follow up events

Browse files
.gitignore CHANGED
@@ -8,6 +8,7 @@ __pycache__/
8
  #Data
9
  test/data/**
10
  data/**
 
11
 
12
  # C extensions
13
  *.so
 
8
  #Data
9
  test/data/**
10
  data/**
11
+ app/assets/tmp_json/**
12
 
13
  # C extensions
14
  *.so
app/assets/json_tmp/tmp_wounded_dead.json DELETED
@@ -1 +0,0 @@
1
- {"circumstance_radio": true, "circumstance": "collision with a means of transport", "cirumstance_type": {"type": "boat", "option_dropdown_label": "NA", "open_field_label": "NA", "extra_label": "NA"}, "behavior_radio": "Yes", "behaviors_observed": ["Crash, Falling From The Sky", "Diarrhea"], "physical_radio": "Yes", "physical_type_head": "head", "physical_anomaly_type_head": ["Injury", "Parasites"], "physical_type_legs": "legs", "physical_anomaly_type_legs": ["Missing Limb"], "fe_fe_collection": "no", "fe_fe_recipient": "local museum", "fe_fe_name_recipient": "reserve", "fe_fe_radio": "unknown", "fe_fe_answer": "police call", "fe_fe_collection_ref": "ref"}
 
 
app/classes.py CHANGED
@@ -3,19 +3,19 @@ from typing import Literal, List, Union, Optional
3
 
4
  from behavior.class_behavior import Behaviors
5
  from circumstances.class_circumstance import Circumstances
6
- from physical.class_physical import PhysicalAnomaly
7
  from follow_up.class_follow_up import FollowUpEvents
8
  from geolocalisation.class_geolocalisation import Geolocalisation
9
 
10
  class Wounded(BaseModel):
11
  circumstances: Circumstances
12
  behaviors: List[Behaviors]
13
- physical_anomalies: List[PhysicalAnomaly]
14
  follow_up_events: List[FollowUpEvents]
15
 
16
  class Dead(BaseModel):
17
  circumstances: List[Circumstances]
18
- physical_anomalies: List[PhysicalAnomaly]
19
  follow_up_events: List[FollowUpEvents]
20
 
21
  class Image(BaseModel):
 
3
 
4
  from behavior.class_behavior import Behaviors
5
  from circumstances.class_circumstance import Circumstances
6
+ from physical.class_physical import PhysicalAnomalies
7
  from follow_up.class_follow_up import FollowUpEvents
8
  from geolocalisation.class_geolocalisation import Geolocalisation
9
 
10
  class Wounded(BaseModel):
11
  circumstances: Circumstances
12
  behaviors: List[Behaviors]
13
+ physical_anomalies: List[PhysicalAnomalies]
14
  follow_up_events: List[FollowUpEvents]
15
 
16
  class Dead(BaseModel):
17
  circumstances: List[Circumstances]
18
+ physical_anomalies: List[PhysicalAnomalies]
19
  follow_up_events: List[FollowUpEvents]
20
 
21
  class Image(BaseModel):
app/follow_up/class_follow_up.py CHANGED
@@ -6,22 +6,22 @@ from typing import Literal, Union, Optional, List
6
  # Animal collected event
7
  class AnimalCollectedEvent(BaseModel):
8
  type: Literal['animal collected']
9
- option: Literal['Yes', 'No']
10
 
11
  # Recipient event
12
  class RecipientEvent(BaseModel):
13
  type: Literal['recipient']
14
- option: Literal['Veterinary', 'Care center', 'Local Museum', 'National Museum', 'Other']
15
-
16
  # Radiography event
17
  class RadiographyEvent(BaseModel):
18
  type: Literal['radiography']
19
- option: Literal['Yes', 'No', 'Unknown']
20
 
21
  # Given answer event
22
  class GivenAnswerEvent(BaseModel):
23
  type: Literal['given answer']
24
- option: Literal[
25
  'Nothing',
26
  'Complaint against X',
27
  'Complaint',
@@ -33,7 +33,7 @@ class GivenAnswerEvent(BaseModel):
33
 
34
  # Name of recipient/museum (open text field)
35
  class NameOfRecipientEvent(BaseModel):
36
- type: Literal['name of recipient / museum']
37
  name: str # Open text field for entering the name
38
 
39
  # Collection reference (open text field)
 
6
  # Animal collected event
7
  class AnimalCollectedEvent(BaseModel):
8
  type: Literal['animal collected']
9
+ collected: Literal['Yes', 'No']
10
 
11
  # Recipient event
12
  class RecipientEvent(BaseModel):
13
  type: Literal['recipient']
14
+ recipient: Literal['Veterinary', 'Care center', 'Local Museum', 'National Museum', 'Other']
15
+
16
  # Radiography event
17
  class RadiographyEvent(BaseModel):
18
  type: Literal['radiography']
19
+ radiography: Literal['Yes', 'No', 'Unknown']
20
 
21
  # Given answer event
22
  class GivenAnswerEvent(BaseModel):
23
  type: Literal['given answer']
24
+ answer: Literal[
25
  'Nothing',
26
  'Complaint against X',
27
  'Complaint',
 
33
 
34
  # Name of recipient/museum (open text field)
35
  class NameOfRecipientEvent(BaseModel):
36
+ type: Literal['recipient name']
37
  name: str # Open text field for entering the name
38
 
39
  # Collection reference (open text field)
app/follow_up/followup_events.py CHANGED
@@ -40,7 +40,7 @@ def create_fe_answer_dropdown(followup_config, visible, elem_id):
40
  return fe_answer_dropdown
41
 
42
  def save_fe(value, key):
43
- add_data_tmp("wounded_dead", key.lower(), value.lower())
44
 
45
 
46
 
 
40
  return fe_answer_dropdown
41
 
42
  def save_fe(value, key):
43
+ add_data_tmp("wounded_dead", "followup " + key.lower(), value.lower())
44
 
45
 
46
 
app/main_multianimal.py CHANGED
@@ -210,21 +210,21 @@ with gr.Blocks(theme=theme, css=css) as demo:
210
 
211
  # ---------------------------------------------------------
212
  # Follow Up Events Wounded
213
- fe_collection_dropdown_wounded.select(save_fe, inputs=[fe_collection_dropdown_wounded, gr.Textbox("fe_collection", visible=False)])
214
- fe_recepient_dropdown_wounded.select(save_fe, inputs=[fe_recepient_dropdown_wounded, gr.Textbox("fe_recipient", visible=False)])
215
- fe_radio_dropdown_wounded.select(save_fe, inputs=[fe_radio_dropdown_wounded, gr.Textbox("fe_radio", visible=False)])
216
- fe_answer_dropdown_wounded.select(save_fe, inputs=[fe_answer_dropdown_wounded, gr.Textbox("fe_answer", visible=False)])
217
- fe_name_recipient_wounded.input(save_fe, inputs=[fe_name_recipient_wounded, gr.Textbox("fe_name_recipient", visible=False)])
218
- fe_collection_ref_wounded.input(save_fe, inputs=[fe_collection_ref_wounded, gr.Textbox("fe_collection_ref", visible=False)])
219
 
220
  # ---------------------------------------------------------
221
  # Follow Up Events Dead
222
- fe_collection_dropdown_dead.select(save_fe, inputs=[fe_collection_dropdown_dead, gr.Textbox("fe_collection", visible=False)])
223
- fe_recepient_dropdown_dead.select(save_fe, inputs=[fe_recepient_dropdown_dead, gr.Textbox("fe_recipient", visible=False)])
224
- fe_radio_dropdown_dead.select(save_fe, inputs=[fe_radio_dropdown_dead, gr.Textbox("fe_radio", visible=False)])
225
- fe_answer_dropdown_dead.select(save_fe, inputs=[fe_answer_dropdown_dead, gr.Textbox("fe_answer", visible=False)])
226
- fe_name_recipient_dead.input(save_fe, inputs=[fe_name_recipient_dead, gr.Textbox("fe_name_recipient", visible=False)])
227
- fe_collection_ref_dead.input(save_fe, inputs=[fe_collection_ref_dead, gr.Textbox("fe_collection_ref", visible=False)])
228
 
229
  # ---------------------------------------------------------
230
  # Add One Individual's Data to the Dataframe
 
210
 
211
  # ---------------------------------------------------------
212
  # Follow Up Events Wounded
213
+ fe_collection_dropdown_wounded.select(save_fe, inputs=[fe_collection_dropdown_wounded, gr.Textbox("animal collected", visible=False)])
214
+ fe_recepient_dropdown_wounded.select(save_fe, inputs=[fe_recepient_dropdown_wounded, gr.Textbox("recipient", visible=False)])
215
+ fe_radio_dropdown_wounded.select(save_fe, inputs=[fe_radio_dropdown_wounded, gr.Textbox("radiography", visible=False)])
216
+ fe_answer_dropdown_wounded.select(save_fe, inputs=[fe_answer_dropdown_wounded, gr.Textbox("given answer", visible=False)])
217
+ fe_name_recipient_wounded.input(save_fe, inputs=[fe_name_recipient_wounded, gr.Textbox("recipient name", visible=False)])
218
+ fe_collection_ref_wounded.input(save_fe, inputs=[fe_collection_ref_wounded, gr.Textbox("collection reference", visible=False)])
219
 
220
  # ---------------------------------------------------------
221
  # Follow Up Events Dead
222
+ fe_collection_dropdown_dead.select(save_fe, inputs=[fe_collection_dropdown_dead, gr.Textbox("animal collected", visible=False)])
223
+ fe_recepient_dropdown_dead.select(save_fe, inputs=[fe_recepient_dropdown_dead, gr.Textbox("recipient", visible=False)])
224
+ fe_radio_dropdown_dead.select(save_fe, inputs=[fe_radio_dropdown_dead, gr.Textbox("radiography", visible=False)])
225
+ fe_answer_dropdown_dead.select(save_fe, inputs=[fe_answer_dropdown_dead, gr.Textbox("given answer", visible=False)])
226
+ fe_name_recipient_dead.input(save_fe, inputs=[fe_name_recipient_dead, gr.Textbox("recipient name", visible=False)])
227
+ fe_collection_ref_dead.input(save_fe, inputs=[fe_collection_ref_dead, gr.Textbox("collection reference", visible=False)])
228
 
229
  # ---------------------------------------------------------
230
  # Add One Individual's Data to the Dataframe
app/validation_submission/validation.py CHANGED
@@ -3,6 +3,7 @@ from classes import Report
3
  from circumstances.class_circumstance import Circumstances
4
  from behavior.class_behavior import Behaviors
5
  from physical.class_physical import PhysicalAnomalies
 
6
 
7
  def get_fields(data_dict, keyword):
8
  extract = {}
@@ -20,14 +21,7 @@ def validate_individual():
20
  validate_individual()
21
  pass
22
 
23
-
24
- def validate_circumstance(data):
25
- circumstance_raw = get_fields(data, "circumstance")
26
- circumstance_formatted = process_circumstance(circumstance_raw)
27
- if not Circumstances(**circumstance_formatted).validate():
28
- print("Validation failed for the circumstance.")
29
- else:
30
- return Circumstances(**circumstance_formatted)
31
 
32
  def process_circumstance(data):
33
  fields_to_check = ["option_dropdown", "open_field", "extra"]
@@ -48,14 +42,6 @@ def process_circumstance(data):
48
  # "circumstance_option_dropdown": "Traffic/Trade"}
49
  return data
50
 
51
- def validate_behavior(data):
52
- behaviors_raw = get_fields(data, "behaviours")
53
- behaviors_formatted = process_behaviors(behaviors_raw)
54
- if not Behaviors(**behaviors_formatted).validate():
55
- print("Validation failed for the behaviours.")
56
- else:
57
- return Behaviors(**behaviors_formatted)
58
-
59
  def process_behaviors(data):
60
  # INPUT :
61
  #"behaviors_radio": true,
@@ -75,18 +61,11 @@ def process_behaviors(data):
75
  data["behaviors_type"] = behaviors
76
  return data
77
 
78
- def validate_physical(data):
79
- physical_raw = get_fields(data, "physical")
80
- physical_formatted = process_physical(physical_raw)
81
- if not PhysicalAnomalies(**physical_formatted).validate():
82
- print("Validation failed for the physical anomalies.")
83
- else:
84
- return PhysicalAnomalies(**physical_formatted)
85
-
86
  def process_physical(data):
87
  # INPUT
88
  # "physical_type_feathers": "feathers",
89
  # "physical_anomaly_type_feathers": ["Blood", "Swelling"]}
 
90
  # OUTPUT
91
  # "physical_radio": "Yes",
92
  # "physical_anomalies_type": [
@@ -98,11 +77,87 @@ def process_physical(data):
98
  # "type": "body",
99
  # "anomaly_type": "fluffed up"
100
  # },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
101
 
102
- pass
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
103
 
104
  def validate_follow_up(data):
105
- pass
 
 
 
 
 
106
 
107
  def validate_individual():
108
  individual = get_json_one_individual()
 
3
  from circumstances.class_circumstance import Circumstances
4
  from behavior.class_behavior import Behaviors
5
  from physical.class_physical import PhysicalAnomalies
6
+ from follow_up.class_follow_up import FollowUpEvents
7
 
8
  def get_fields(data_dict, keyword):
9
  extract = {}
 
21
  validate_individual()
22
  pass
23
 
24
+ #### PROCESS FUNCTIONS
 
 
 
 
 
 
 
25
 
26
  def process_circumstance(data):
27
  fields_to_check = ["option_dropdown", "open_field", "extra"]
 
42
  # "circumstance_option_dropdown": "Traffic/Trade"}
43
  return data
44
 
 
 
 
 
 
 
 
 
45
  def process_behaviors(data):
46
  # INPUT :
47
  #"behaviors_radio": true,
 
61
  data["behaviors_type"] = behaviors
62
  return data
63
 
 
 
 
 
 
 
 
 
64
  def process_physical(data):
65
  # INPUT
66
  # "physical_type_feathers": "feathers",
67
  # "physical_anomaly_type_feathers": ["Blood", "Swelling"]}
68
+
69
  # OUTPUT
70
  # "physical_radio": "Yes",
71
  # "physical_anomalies_type": [
 
77
  # "type": "body",
78
  # "anomaly_type": "fluffed up"
79
  # },
80
+ body_parts= ["beak", "body", "legs", "feathers", "head"]
81
+ anomalies=[]
82
+ reformatted = {}
83
+ reformatted["physical_radio"] = data["physical_radio"]
84
+ for body_part in body_parts:
85
+ anomaly = {}
86
+ for key, val in data.items():
87
+ if "type_"+ body_part in key:
88
+ anomaly["type"] = val
89
+ elif "anomaly_type_"+ body_part in key:
90
+ anomaly["anomaly_type"] = val
91
+ anomalies.append(anomaly)
92
+ reformatted["physical_anomalies_type"] = anomalies
93
+ return reformatted
94
 
95
+ def process_followup(data):
96
+ # "follow_up_events": [
97
+ # {
98
+ # "type": "animal collected",
99
+ # "option": "Yes"
100
+ # },
101
+ # {
102
+ # "type": "recipient",
103
+ # "option": "Veterinary",
104
+ # "name_recipient": "Dr. Jane Smith"
105
+ # },
106
+ # {
107
+ # "type": "radiography",
108
+ # "option": "Unknown"
109
+ # },
110
+ # {
111
+ # "type": "given answer",
112
+ # "option": "Discussion with the speaker"
113
+ # },
114
+ # {
115
+ # "type": "collection reference",
116
+ # "reference": "Specimen ID: 12345, Collected on 2023-09-15"
117
+ # }
118
+ # ]
119
+ followup_events = []
120
+ for key, val in data.items():
121
+ followup_event={}
122
+ type = key.split("followup")[-1]
123
+ option = type.split(" ")[-1]
124
+ followup_event["type"] = type
125
+ followup_event[option] = val
126
+ followup_events.append(followup_event)
127
+ return followup_events
128
+
129
+ #### VALIDATION FUNCTIONS
130
+ def validate_circumstance(data):
131
+ circumstance_raw = get_fields(data, "circumstance")
132
+ circumstance_formatted = process_circumstance(circumstance_raw)
133
+ if not Circumstances(**circumstance_formatted).validate():
134
+ print("Validation failed for the circumstance.")
135
+ else:
136
+ return Circumstances(**circumstance_formatted)
137
+
138
+ def validate_behavior(data):
139
+ behaviors_raw = get_fields(data, "behaviours")
140
+ behaviors_formatted = process_behaviors(behaviors_raw)
141
+ if not Behaviors(**behaviors_formatted).validate():
142
+ print("Validation failed for the behaviours.")
143
+ else:
144
+ return Behaviors(**behaviors_formatted)
145
+
146
+ def validate_physical(data):
147
+ physical_raw = get_fields(data, "physical")
148
+ physical_formatted = process_physical(physical_raw)
149
+ if not PhysicalAnomalies(**physical_formatted).validate():
150
+ print("Validation failed for the physical anomalies.")
151
+ else:
152
+ return PhysicalAnomalies(**physical_formatted)
153
 
154
  def validate_follow_up(data):
155
+ followup_raw = get_fields(data, "followup")
156
+ followup_formatted = process_followup(followup_raw)
157
+ if not FollowUpEvents(**followup_formatted).validate():
158
+ print("Validation failed for the follow-up events.")
159
+ else:
160
+ return FollowUpEvents(**followup_formatted)
161
 
162
  def validate_individual():
163
  individual = get_json_one_individual()