Source code for pyNastran.bdf.cards.expand_card

"""
defines:
 - expand_thru
 - expand_thru_by

"""
from __future__ import (nested_scopes, generators, division, absolute_import,
                        print_function, unicode_literals)
from typing import  List, Union
from six import string_types

from pyNastran.utils.numpy_utils import integer_types
from pyNastran.bdf.bdf_interface.assign_type import interpret_value


[docs]def expand_thru(fields, set_fields=True, sort_fields=False): # type: (List[str], bool, bool) -> List[int] """ Expands a list of values of the form [1,5,THRU,9,13] to be [1,5,6,7,8,9,13] Parameters ---------- fields : List[int/str] the fields to expand set_fields : bool; default=True Should the fields be converted to a set and then back to a list? This is useful for [2, 'THRU' 5, 1] sort_fields : bool; default=False Should the fields be sorted at the end? """ # ..todo: should this be removed...is the field capitalized when read in? if isinstance(fields, integer_types): return [fields] #elif isinstance(fields[0], integer_types): # don't use this [1, 'THRU', 10] #return fields elif len(fields) == 1: return [int(fields[0])] fields = [field.upper() if isinstance(field, string_types) else field for field in fields] out = [] nfields = len(fields) i = 0 while i < nfields: if isinstance(fields[i], string_types) and fields[i] == 'THRU': istart = int(fields[i - 1]) iend = int(fields[i + 1]) # adding 1 to iend for the range offset for j in range(istart+1, iend + 1): out.append(j) i += 2 else: out.append(int(fields[i])) i += 1 if set_fields: out = list(set(out)) if sort_fields: out.sort() return out
[docs]def expand_thru_by(fields, set_fields=True, sort_fields=True, require_int=True, allow_blanks=False): # type: (List[str], bool, bool, bool, bool) -> List[int] """ Expands a list of values of the form [1,5,THRU,9,BY,2,13] to be [1,5,7,9,13] Parameters ---------- fields : List[int/str] the fields to expand set_fields : bool; default=True Should the fields be converted to a set and then back to a list to remove duplicates? This is useful for [2, 'THRU' 5, 1] sort_fields : bool; default=False Should the fields be sorted at the end? require_int : bool; default=True True : all data must be integers False : floats are allowed (e.g., DDVAL) allow_blanks : bool; default=Fals True : blank/Nones are ignored (e.g., NSM1/NSML1) False : crash .. todo:: not tested Notes ----- used for QBDY3 and what else ??? """ if require_int: func = int else: func = interpret_value # ..todo: should this be removed...is the field capitalized when read in? fields = [field.upper() if isinstance(field, string_types) else field for field in fields] if len(fields) == 1: return [func(fields[0])] out = [] nfields = len(fields) i = 0 by = 1 while i < nfields: #print('fields[i]=%r' % fields[i]) is_blank = ( allow_blanks and ( (isinstance(fields[i], string_types) and fields[i].strip() == '') or fields[i] is None) ) if is_blank: #print('blank=%s' % fields[i]) i += 1 continue if fields[i] == 'THRU': by = 1 by_case = False if i + 2 < nfields and fields[i + 2] == 'BY': by = func(fields[i + 3]) else: by = 1 by_case = True min_value = func(fields[i - 1]) max_value = func(fields[i + 1]) max_range = int((max_value - min_value) // by + 1) # max range value for j in range(0, max_range): # +1 is to include final point value = min_value + by * j out.append(value) out.append(max_value) if by_case: # null/standard case # A thru B i += 2 else: # BY case # A thru B by C i += 4 else: out.append(func(fields[i])) i += 1 if set_fields: out = list(set(out)) if sort_fields: out.sort() return out