Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions brel/brel_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,13 @@ def get_unit(self) -> UnitCharacteristic | None:
"""
return cast(UnitCharacteristic, self.get_characteristic(Aspect.UNIT))

def has_noncore_dimensions(self) -> bool:
"""
Check if the context has (user-defined) dimensions.
:returns bool: True if the context has dimensions, False otherwise.
"""
return any(not aspect.is_core() for aspect in self.__aspects)

# Internal methods
def _add_characteristic(self, characteristic: ICharacteristic) -> None:
"""
Expand Down
7 changes: 7 additions & 0 deletions brel/brel_fact.py
Original file line number Diff line number Diff line change
Expand Up @@ -254,3 +254,10 @@ def convert_to_dict(
dict_to_return[value_literal] = self.__value

return dict_to_return

def is_core(self) -> bool:
"""
Check if the fact has (user-defined) non-core dimensions.
:returns bool: True if the fact has non-core dimensions, False otherwise.
"""
return not self.get_context().has_noncore_dimensions()
29 changes: 29 additions & 0 deletions brel/brel_filing.py
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,12 @@ def get_infos(self) -> List[ErrorInstance]:
return self.get_errors_by_severity(Severity.INFO)

# second class citizens
def get_all_core_facts(self) -> list[Fact]:
"""
:return list[Fact]: a list of all [`Fact`](../facts/facts.md) objects in the filing that have no non-core dimensions.
"""
return [fact for fact in self.get_all_facts() if fact.is_core()]

def get_all_concepts(self) -> list[Concept]:
"""
:returns list[Concept]: a list of all concepts in the filing.
Expand Down Expand Up @@ -412,6 +418,17 @@ def generate_fact_table_pandas_df(
"""
return self.__generate_pandas_df_from_elements(self.get_all_facts(), **kwargs)

def generate_core_fact_table_pandas_df(
self, **kwargs: Unpack[OutputParams]
) -> pd.DataFrame:
"""
Converts the filing to a pandas DataFrame.
:return pandas.DataFrame: the filing as a pandas DataFrame.
"""
return self.__generate_pandas_df_from_elements(
self.get_all_core_facts(), **kwargs
)

def generate_fact_table_spark_df(self) -> tuple[sql.DataFrame, sql.SparkSession]:
"""
Converts the filing to a spark DataFrame.
Expand All @@ -422,6 +439,18 @@ def generate_fact_table_spark_df(self) -> tuple[sql.DataFrame, sql.SparkSession]
# spark.parallelize()
return spark.createDataFrame(df), spark

def generate_core_fact_table_spark_df(
self,
) -> tuple[sql.DataFrame, sql.SparkSession]:
"""
Converts the filing to a spark DataFrame.
:return pyspark.sql.DataFrame: the filing as a spark DataFrame.
"""
spark = sql.SparkSession.builder.getOrCreate()
df = self.generate_core_fact_table_pandas_df()
# spark.parallelize()
return spark.createDataFrame(df), spark

def generate_components_as_pandas_df(
self, **kwargs: Unpack[OutputParams]
) -> pd.DataFrame:
Expand Down
3 changes: 3 additions & 0 deletions tests/core_tests/test_fact.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,13 @@ def test_qname_getters():
assert "period" in fact_str, "Expected 'period' to be in fact dict"
assert "entity" in fact_str, "Expected 'entity' to be in fact dict"
assert "unit" not in fact_str, "Expected 'unit' not to be in fact dict"
assert fact.is_core(), "Expected True as fact has no dimensions."

# check if parsing a false fact as bool works
fact = filing.get_facts_by_concept_name("dei:AmendmentFlag")[0]
assert str(fact) == "false", "Expected 'false' as fact value is 'false'"
assert bool(fact) == False, "Expected False as fact value is 'false'"
assert fact.is_core(), "Expected True as fact has no dimensions."

# check for an integer fact
fact = filing.get_facts_by_concept_name("us-gaap:GrossProfit")[0]
Expand All @@ -66,6 +68,7 @@ def test_qname_getters():
assert int(fact) > 1000000, "Expected apples gross profit to be > 1M"
assert isinstance(fact.get_value(), float), "Expected float as fact value is float"
assert float(fact) > 1000000, "Expected apples gross profit to be > 1M"
assert fact.is_core(), "Expected True as fact has no dimensions."
try: # check if parsing a false fact as bool works
bool(fact)
assert False, "Expected ValueError as fact value is not a bool"
Expand Down
6 changes: 6 additions & 0 deletions tests/core_tests/test_filing.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ def test_filing_getters():
# check get_all_facts(). it should return a list of facts
facts = filing.get_all_facts()
assert_list_of_type(facts, Fact)
assert len(facts) == 13, f"Expected 13 facts, got {len(facts)}"

# check get_all_core_facts(). it should return a list of core facts
core_facts = filing.get_all_core_facts()
assert_list_of_type(core_facts, Fact)
assert len(core_facts) == 12, f"Expected 12 core facts, got {len(core_facts)}"

# check if get_all_report_elements(). it should return a list of report elements
report_elements = filing.get_all_report_elements()
Expand Down
Loading