-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #306 from Blueprints-org/305-feature-request-abc-e…
…xposure-class Add ABCEnumMeta to be able to create Abstract Enum classes + Refactor Exposure classes and adjust tests
- Loading branch information
Showing
9 changed files
with
612 additions
and
256 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,166 @@ | ||
"""Module for the concrete exposure classes | ||
according to Table 4.1 from NEN-EN 1992-1-1: Chapter 4 - Durability and cover to reinforcement. | ||
""" | ||
|
||
from abc import abstractmethod | ||
from enum import Enum | ||
from functools import total_ordering | ||
from typing import NamedTuple, Type, TypeVar | ||
|
||
from blueprints.utils.abc_enum_meta import ABCEnumMeta | ||
|
||
T = TypeVar("T", bound="Exposure") | ||
|
||
|
||
@total_ordering | ||
class Exposure(Enum, metaclass=ABCEnumMeta): | ||
"""Parent class for individual exposure classes. | ||
This class handles the ordering/comparison operations, that's why it is decorated with total_ordering (As recommended by PEP8). | ||
On top of that, it handles a couple of methods which will be used by its subclasses. | ||
""" | ||
|
||
def __eq__(self, other: object) -> bool: | ||
"""Definition of '==' operator for the comparison of the severity of the exposure classifications. | ||
Parameters | ||
---------- | ||
self : Exposure/ subclass of Exposure | ||
First argument for the comparison. | ||
other : object | ||
Second argument for the comparison. | ||
Raises | ||
------ | ||
TypeError | ||
If different types are being compared. | ||
Returns | ||
------- | ||
Boolean | ||
True if both arguments are of the same severity (In this case they will both be literally the same). | ||
""" | ||
if isinstance(other, self.__class__): | ||
_self_severity = int(self.value[-1]) if self.value != "Not applicable" else 0 | ||
_other_severity = int(other.value[-1]) if other.value != "Not applicable" else 0 | ||
return _self_severity == _other_severity | ||
raise TypeError("Only the same exposure class types can be compared with each other!") | ||
|
||
def __gt__(self, other: object) -> bool: | ||
"""Definition of '>' operator for the comparison of the severity of the exposure classifications. | ||
Parameters | ||
---------- | ||
self : Exposure/ subclass of Exposure | ||
First argument for the comparison. | ||
other : object | ||
Second argument for the comparison. | ||
Raises | ||
------ | ||
TypeError | ||
If different types are being compared. | ||
Returns | ||
------- | ||
Boolean | ||
True if the first argument is more severe than the second argument. | ||
""" | ||
if isinstance(other, self.__class__): | ||
_self_severity = int(self.value[-1]) if self.value != "Not applicable" else 0 | ||
_other_severity = int(other.value[-1]) if other.value != "Not applicable" else 0 | ||
return _self_severity > _other_severity | ||
raise TypeError("Only the same exposure class types can be compared with each other!") | ||
|
||
@classmethod | ||
def options(cls: Type[T]) -> list[str]: | ||
"""Return all the possible options within a subclass. | ||
Returns | ||
------- | ||
list[str] | ||
all the possible class designations within a specific exposure class | ||
""" | ||
return [m._value_ for m in cls.__members__.values()] | ||
|
||
@staticmethod | ||
@abstractmethod | ||
def exposure_class_description() -> str: | ||
"""Description of subclasses to be implemented in each subclass. | ||
Returns | ||
------- | ||
str | ||
description of the specific exposure class | ||
""" | ||
|
||
@abstractmethod | ||
def description_of_the_environment(self) -> str: | ||
"""Description of the environment based on the instance. | ||
Returns | ||
------- | ||
str | ||
description of the environment based on the instance | ||
""" | ||
|
||
|
||
@total_ordering | ||
class CarbonationBase(Exposure): | ||
"""Enum Class which indicates the classification of corrosion induced by carbonation.""" | ||
|
||
|
||
@total_ordering | ||
class ChlorideBase(Exposure): | ||
"""Enum Class which indicates the classification of corrosion induced by chlorides other than by sea water.""" | ||
|
||
|
||
@total_ordering | ||
class ChlorideSeawaterBase(Exposure): | ||
"""Enum Class which indicates the classification of corrosion induced by chlorides from sea water.""" | ||
|
||
|
||
@total_ordering | ||
class FreezeThawBase(Exposure): | ||
"""Enum Class which indicates the classification of freeze/thaw attack with or without de-icing agents.""" | ||
|
||
|
||
@total_ordering | ||
class ChemicalBase(Exposure): | ||
"""Enum Class which indicates the classification of chemical attack.""" | ||
|
||
|
||
class ExposureClassesBase(NamedTuple): | ||
"""Parent class which serves as a container for the Exposure classes. | ||
Exposure classes related to environmental conditions in accordance with EN 206-1 | ||
""" | ||
|
||
carbonation: CarbonationBase | ||
chloride: ChlorideBase | ||
chloride_seawater: ChlorideSeawaterBase | ||
freeze: FreezeThawBase | ||
chemical: ChemicalBase | ||
|
||
@property | ||
def no_risk(self) -> bool: | ||
"""Check if all exposure classes are 'Not applicable'. | ||
This represents X0 class designation according to table 4.1 from NEN-EN 1992-1-1+C2:2011. | ||
Returns | ||
------- | ||
bool | ||
True if all exposure classes are 'Not applicable' | ||
""" | ||
return all(exposure_class.value == "Not applicable" for exposure_class in self) | ||
|
||
def __str__(self) -> str: | ||
"""String representation of the ExposureClasses object. | ||
Returns | ||
------- | ||
str | ||
String representation of the ExposureClasses object | ||
""" | ||
return "X0" if self.no_risk else ", ".join(enum.value for enum in self if enum.value != "Not applicable") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
"""Utils blueprint.""" |
Oops, something went wrong.