Source code for bulkdata.field
import re
try:
from pyNastran.bdf.field_writer_8 import print_field_8
from pyNastran.bdf.field_writer_16 import print_field_16
except ImportError:
from .pyNastran.bdf.field_writer_8 import print_field_8
from .pyNastran.bdf.field_writer_16 import print_field_16
rx_REAL_pat = r"""
[-+]? # optional sign
(?:
(?: \d* \. \d+ ) # .1 .12 .123 etc 9.1 etc 98.1 etc
|
(?: \d+ \.? ) # 1. 12. 123. etc 1 12 123 etc
)
# followed by optional exponent part if desired
(?:
(?: [Ee]? [+-]?) \d+
)
?
"""
rx_REAL = re.compile(rx_REAL_pat, re.VERBOSE)
rx_INT = re.compile(r"^[-+]?([1-9]\d*|0)$")
def _force_E(real_field):
# if no "E" or "e", insert it
return re.sub("(?<!^)(?<![E|e])[+-]", r"E\g<0>", real_field)
def _is_match(rx, field):
field = field.strip()
try:
return rx.match(field).group(0) == field
except (TypeError, IndexError, AttributeError):
return False
[docs]def is_integer_field(field):
return _is_match(rx_INT, field)
[docs]def is_real_field(field):
return _is_match(rx_REAL, field)
[docs]def read_integer_field(field):
return int(field)
[docs]def read_real_field(field):
return float(_force_E(field))
[docs]def read_field(field):
"""Convert `field` string to value
"""
if is_integer_field(field):
return read_integer_field(field)
if is_real_field(field):
return read_real_field(field)
else:
return field.strip()
[docs]def write_field(value, fieldspan=1):
"""Convert `value` to field string
"""
width = fieldspan * 8
if isinstance(value, str):
return value[:width].strip()
elif width == 8:
return print_field_8(value).strip()
elif width == 16:
return print_field_16(value).strip()
else:
raise ValueError("non-character field entries "
"cannot span more than 2 fields, "
"but fieldspan is {}".format(fieldspan))
[docs]class Field:
def __init__(self, value, fieldspan=1):
self.span = fieldspan
self.value = value
@property
def width(self):
return self.span * 8
[docs] def is_blank(self):
return not self.raw.strip()
def __eq__(self, other):
if isinstance(other, Field):
return self.raw == other.raw
elif isinstance(other, str):
return self.raw == other
else:
return self.value == other
def __str__(self):
return self.raw
def __repr__(self):
return "{}('{}')".format(self.__class__.__name__, self.raw)
def __bool__(self):
return not self.is_blank()
@property
def value(self):
if self._value_change:
self._value = read_field(self.raw)
return self._value
@value.setter
def value(self, new_value):
self.raw = write_field(new_value, fieldspan=self.span)
self._value_change = True
[docs]class LargeField(Field):
def __init__(self, value, fieldspan=2):
super().__init__(value, fieldspan)
[docs] def split(self, fieldspan=1):
"""Split into Fields with given `fieldspan`
"""
fieldwidth = fieldspan * 8
fields = []
for start in range(0, len(self.raw), fieldwidth):
stop = start + fieldwidth
fields.append(Field(self.raw[start:stop], fieldspan))
return fields
[docs] @classmethod
def join(cls, fields):
large_str = "".join([field.raw for field in fields])
return cls(large_str, fieldspan=len(fields))