Skip to content

Commit

Permalink
Merge pull request #161 from BIH-CEI/154-rename-compliance-literals
Browse files Browse the repository at this point in the history
renamed compliance from soft and hard to lenient and strict
  • Loading branch information
frehburg authored Oct 8, 2024
2 parents cc943f5 + 938989b commit 92f79c1
Show file tree
Hide file tree
Showing 11 changed files with 39 additions and 39 deletions.
2 changes: 1 addition & 1 deletion notebooks/erdri_cds_definition_in_code.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -802,7 +802,7 @@
" genetic_diagnosis_column= \"6.2. Genetic diagnosis\",\n",
" undiagnosed_case_column= None,\n",
" \n",
" compliance='soft' # 'soft' or 'hard'\n",
" compliance='lenient' # 'lenient' or 'strict'\n",
")"
],
"metadata": {
Expand Down
2 changes: 1 addition & 1 deletion src/phenopacket_mapper/data_standards/code.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class Coding:
def parse_coding(
coding_str: str,
resources: List[CodeSystem],
compliance: Literal['soft', 'hard'] = 'soft'
compliance: Literal['lenient', 'strict'] = 'lenient'
) -> 'Coding':
"""Parsed a string representing a coding to a Coding object
Expand Down
22 changes: 11 additions & 11 deletions src/phenopacket_mapper/data_standards/data_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ def get_field_ids(self) -> List[str]:
def load_data(
self,
path: Union[str, Path],
compliance: Literal['soft', 'hard'] = 'soft',
compliance: Literal['lenient', 'strict'] = 'lenient',
**kwargs
) -> 'DataSet':
"""Loads data from a file using a DataModel definition
Expand Down Expand Up @@ -285,16 +285,16 @@ def load_data_using_data_model(
path: Union[str, Path],
data_model: 'DataModel',
column_names: Dict[str, str],
compliance: Literal['soft', 'hard'] = 'soft',
compliance: Literal['lenient', 'strict'] = 'lenient',
) -> 'DataSet':
"""Loads data from a file using a DataModel definition
:param path: Path to formatted csv or excel file
:param data_model: DataModel to use for reading the file
:param column_names: A dictionary mapping from the id of each field of the `DataField` to the name of a
column in the file
:param compliance: Compliance level to enforce when reading the file. If 'soft', the file can have extra fields
that are not in the DataModel. If 'hard', the file must have all fields in the DataModel.
:param compliance: Compliance level to enforce when reading the file. If 'lenient', the file can have extra fields
that are not in the DataModel. If 'strict', the file must have all fields in the DataModel.
:return: List of DataModelInstances
"""
from phenopacket_mapper.pipeline import load_data_using_data_model
Expand All @@ -315,14 +315,14 @@ class DataModelInstance:
:ivar row_no: The id of the instance, i.e. the row number
:ivar data_model: The `DataModel` object that defines the data model for this instance
:ivar values: A list of `DataFieldValue` objects, each adhering to the `DataField` definition in the `DataModel`
:ivar compliance: Compliance level to enforce when validating the instance. If 'soft', the instance can have extra
fields that are not in the DataModel. If 'hard', the instance must have all fields in the
:ivar compliance: Compliance level to enforce when validating the instance. If 'lenient', the instance can have extra
fields that are not in the DataModel. If 'strict', the instance must have all fields in the
DataModel.
"""
row_no: Union[int, str]
data_model: DataModel
values: List[DataFieldValue]
compliance: Literal['soft', 'hard'] = 'soft'
compliance: Literal['lenient', 'strict'] = 'lenient'

def __post_init__(self):
self.validate()
Expand All @@ -338,9 +338,9 @@ def validate(self) -> bool:
error_msg = f"Instance values do not comply with their respective fields' valuesets. (row {self.row_no})"
for v in self.values:
if not v.validate():
if self.compliance == 'hard':
if self.compliance == 'strict':
raise ValueError(error_msg)
elif self.compliance == 'soft':
elif self.compliance == 'lenient':
warnings.warn(error_msg)
return False
else:
Expand All @@ -352,9 +352,9 @@ def validate(self) -> bool:
if len(missing_fields := (is_required - fields_present)) > 0:
error_msg = (f"Required fields are missing in the instance. (row {self.row_no}) "
f"\n(missing_fields={', '.join(missing_fields)})")
if self.compliance == 'hard':
if self.compliance == 'strict':
raise ValueError(error_msg)
elif self.compliance == 'soft':
elif self.compliance == 'lenient':
warnings.warn(error_msg)
return False
else:
Expand Down
2 changes: 1 addition & 1 deletion src/phenopacket_mapper/data_standards/date.py
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ def from_iso_8601(iso_8601: str) -> Union['Date', None]:
def parse_date(
date_str: str,
default_first: Literal["day", "month"] = "day",
compliance: Literal['soft', 'hard'] = 'soft',
compliance: Literal['lenient', 'strict'] = 'lenient',
) -> 'Date':
"""Parse a date string into a Date object
Expand Down
2 changes: 1 addition & 1 deletion src/phenopacket_mapper/data_standards/value_set.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ def parse_value_set(
value_set_name: str = "",
value_set_description: str = "",
resources: List[CodeSystem] = None,
compliance: Literal['hard', 'soft'] = 'soft',
compliance: Literal['strict', 'lenient'] = 'lenient',
) -> 'ValueSet':
"""Parses a value set from a string representation
Expand Down
6 changes: 3 additions & 3 deletions src/phenopacket_mapper/pipeline/input.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ def load_data_using_data_model(
path: Union[str, Path],
data_model: DataModel,
column_names: Dict[str, str],
compliance: Literal['soft', 'hard'] = 'soft',
compliance: Literal['lenient', 'strict'] = 'lenient',
) -> DataSet:
"""Loads data from a file using a DataModel definition
Expand All @@ -160,8 +160,8 @@ def load_data_using_data_model(
:param data_model: DataModel to use for reading the file
:param column_names: A dictionary mapping from the id of each field of the `DataField` to the name of a
column in the file
:param compliance: Compliance level to enforce when reading the file. If 'soft', the file can have extra fields
that are not in the DataModel. If 'hard', the file must have all fields in the DataModel.
:param compliance: Compliance level to enforce when reading the file. If 'lenient', the file can have extra fields
that are not in the DataModel. If 'strict', the file must have all fields in the DataModel.
:return: List of DataModelInstances
"""
if isinstance(path, Path):
Expand Down
4 changes: 2 additions & 2 deletions src/phenopacket_mapper/utils/parsing/parse_coding.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
def parse_coding(
coding_str: str,
resources: List[CodeSystem],
compliance: Literal['soft', 'hard'] = 'soft'
compliance: Literal['lenient', 'strict'] = 'lenient'
) -> Coding:
"""Parsed a string representing a coding to a Coding object
Expand Down Expand Up @@ -56,7 +56,7 @@ def parse_coding(
if code_system:
return Coding(system=code_system, code=code)
else:
if compliance == 'hard':
if compliance == 'strict':
raise ValueError(f"Code system with namespace prefix '{namespace_prefix}' not found in resources.")
else:
print(f"Warning: Code system with namespace prefix '{namespace_prefix}' not found in resources.")
Expand Down
10 changes: 5 additions & 5 deletions src/phenopacket_mapper/utils/parsing/parse_data_type.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
def parse_data_type(
type_str: str,
resources: List[CodeSystem],
compliance: Literal['soft', 'hard'] = 'soft'
compliance: Literal['lenient', 'strict'] = 'lenient'
) -> List[Union[Any, CodeSystem, type, str]]:
"""Parses a string representing of one or multiple data types or code systems to a list of `type` in Python
Expand All @@ -26,8 +26,8 @@ def parse_data_type(
inclusion in the list passed as the `resources` parameter) to indicate that codes or terms from that resource are
permittable.
When `compliance` is set to `'soft'` (default), this method only issues warnings if a data type is unrecognized and
adds a literal to the list of allowed data types. When `compliance` is set to `'hard'`, it throws a `ValueError` in
When `compliance` is set to `'lenient'` (default), this method only issues warnings if a data type is unrecognized and
adds a literal to the list of allowed data types. When `compliance` is set to `'strict'`, it throws a `ValueError` in
the case described above.
E.g.
Expand Down Expand Up @@ -56,7 +56,7 @@ def parse_data_type(
def parse_single_data_type(
type_str: str,
resources: List[CodeSystem],
compliance: Literal['soft', 'hard'] = 'soft'
compliance: Literal['lenient', 'strict'] = 'lenient'
) -> Union[Any, CodeSystem, type, str]:
"""Parses a string representing a data type to the `type` in Python
Expand All @@ -82,7 +82,7 @@ def parse_single_data_type(
return type_

# if nothing has matched
if compliance == 'soft':
if compliance == 'lenient':
print(f"Warning: The type {type_str} could not be parsed to a type or resource. If it refers to a resource,"
f" please add it to the list of resources. Otherwise, check your file.")
return type_str
Expand Down
10 changes: 5 additions & 5 deletions src/phenopacket_mapper/utils/parsing/parse_date.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
def parse_date(
date_str: str,
default_first: Literal["day", "month"] = "day",
compliance: Literal['soft', 'hard'] = 'soft',
compliance: Literal['lenient', 'strict'] = 'lenient',
) -> Optional[Date]:
"""Parse a date string into a Date object
Expand Down Expand Up @@ -90,7 +90,7 @@ def parse_date(
return Date(year=parse_int(units[2]), month=month, day=day)

else:
if compliance == 'hard':
if compliance == 'strict':
raise ValueError(f"Invalid date string '{date_str}': no separators found")
else:
warnings.warn(f"Invalid date string '{date_str}': could not be parsed, returning None")
Expand All @@ -102,10 +102,10 @@ def _wrapper__most_likely_date_and_month(
str1: str,
full_date_str: str,
default_first: Literal["day", "month"] = "day",
compliance: Literal['soft', 'hard'] = 'soft'
compliance: Literal['lenient', 'strict'] = 'lenient'
) -> Tuple[int, int]:
"""
Wrapper for _return_most_likely_date_and_month that raises an error if the compliance is set to 'hard'
Wrapper for _return_most_likely_date_and_month that raises an error if the compliance is set to 'strict'
returns the day and month from the most likely date and month from two strings
Expand All @@ -117,7 +117,7 @@ def _wrapper__most_likely_date_and_month(
:return: the day and month from the most likely date and month from two strings
"""
result = _return_most_likely_date_and_month(str0, str1, full_date_str, default_first)
if result['inference'] and compliance == 'hard':
if result['inference'] and compliance == 'strict':
raise ValueError(f"Invalid date string '{full_date_str}': unclear which unit of time is first")
day = result['day']
month = result['month']
Expand Down
8 changes: 4 additions & 4 deletions src/phenopacket_mapper/utils/parsing/parse_value.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
def parse_value(
value_str: str,
resources: List[CodeSystem],
compliance: Literal['hard', 'soft'] = 'soft'
compliance: Literal['strict', 'lenient'] = 'lenient'
) -> Union[Coding, CodeableConcept, CodeSystem, str, bool, int, float, Date, type]:
"""Parses a string representing a value to the appropriate type
Expand All @@ -27,15 +27,15 @@ def parse_value(

# parsing as a date
try:
value = parse_date(date_str=value_str, compliance='hard')
value = parse_date(date_str=value_str, compliance='strict')
except ValueError:
pass
else:
return value

# parsing as a coding
try:
value = parse_coding(coding_str=value_str, resources=resources, compliance='hard')
value = parse_coding(coding_str=value_str, resources=resources, compliance='strict')
except ValueError:
pass
else:
Expand All @@ -50,7 +50,7 @@ def parse_value(
else:
return value

if compliance == 'hard':
if compliance == 'strict':
raise ValueError(f"Could not parse value: {value_str}")
else:
print(f"Warning: Could not parse value: {value_str}")
Expand Down
10 changes: 5 additions & 5 deletions src/phenopacket_mapper/utils/parsing/parse_value_set.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ def parse_value_set(
value_set_name: str = "",
value_set_description: str = "",
resources: List[CodeSystem] = None,
compliance: Literal['hard', 'soft'] = 'soft',
compliance: Literal['strict', 'lenient'] = 'lenient',
) -> ValueSet:
"""Parses a value set from a string representation
Expand All @@ -25,7 +25,7 @@ def parse_value_set(
:return: A ValueSet object as defined by the string representation
"""
if not isinstance(value_set_str, str) or not value_set_str:
if compliance == 'hard':
if compliance == 'strict':
raise ValueError(f"value_set_str must be a string, not {type(value_set_str)} ({value_set_str})")
else:
return ValueSet(elements=[Any], description=value_set_description)
Expand All @@ -43,15 +43,15 @@ def parse_value_set(

# parsing as a data type
try:
# compliance is set to 'hard' because we want to raise an error if the element is not recognized
element = parse_single_data_type(type_str=element_str, resources=resources, compliance='hard')
# compliance is set to 'strict' because we want to raise an error if the element is not recognized
element = parse_single_data_type(type_str=element_str, resources=resources, compliance='strict')
except ValueError: # parsing as type failed, parsing as a value
element = parse_value(value_str=element_str, resources=resources)

if element is not None:
elements.append(element)
else:
if compliance == 'hard':
if compliance == 'strict':
raise ValueError(f"Could not parse element: {element_str}")
else:
elements.append(element_str)
Expand Down

0 comments on commit 92f79c1

Please sign in to comment.