コード例 #1
0
    def _nastran_set(self, name, cid, attrs, unique_int):
        """We go through the text that we have and make
        the needed substitution.

        name: str
        
        cid: int or str
            Specifies the id of the card.
            
        attrs: [{fieldnum: value_to_insert}]
            We may have to change a few fields for a given
            line. Those changes are stored in attrs.
            
        unique_int: int
            This integer is needed for writing out the
            continuations in the Nastran file. It must be
            unique within the file (!beware).
            
        """
        card = None
        for index, line in enumerate(self.text):
            if line.startswith(name):
                match = re.match("(?P<name>[a-zA-Z0-9*]*) +(?P<num>\d+) ",
                                 line)
                if match and \
                       (match.group("name") == name or \
                        match.group("name") == name + "*") \
                        and match.group("num") == str(cid):
                    if not card:
                        card = index
                    else:
                        raise RuntimeError("There were two cards with the " + \
                                        "same id. You don't want this. " + \
                                        "Two cards: " + match.group("name") +\
                                        " id: " + match.group("num"))

        if card is None:
            raise RuntimeError("Could not find card " + name + " with id " +
                               str(cid))

        # are we dealing with a long card?
        long_card = False
        if self.text[card].startswith(name + "*") or \
               name.endswith("*"):
            long_card = True

        offset = 16 if long_card else 8
        divisions = 6 if long_card else 10

        # parse it up
        items = []
        current_row = card
        continuation = None
        while current_row < len(self.text) and \
                  (current_row == card or self.text[current_row].startswith(" ") or \
                   (continuation and
                    self.text[current_row].replace(" ", "").startswith(continuation))):
            # in both long and short forms, the first slot is 8 characters wide
            # then the rest are either 8 or 16 wide
            last_index = 0
            for i in [8 + i * offset for i in range(divisions)]:
                items.append(self.text[current_row][last_index:i])
                last_index = i

            # continuations are in the last slot
            if len(items[-1]) > 0:
                continuation = items[-1].replace(" ", "")
                if not continuation.startswith("+") and \
                       not continuation.startswith("*"):
                    raise RuntimeError("Your continuations should start" + \
                                    "with either * or +. `" + continuation + "` is not" + \
                                    "acceptable")

            current_row += 1

        # we want to delete the row(s) from the file
        del self.text[card:current_row]

        # now we add the field with the change applied
        # we're also going to conver the field to long
        # form and add it to the end of the file
        long_format = 16
        divisions = 6

        # change the value we're supposed to change
        for attr in attrs:
            fieldnum = attr["fieldnum"]
            value = attr["value"]

            #print "supposed to change", fieldnum, "to", value

            items[fieldnum] = stringify(value, length=long_format)

        # remove the continuations
        to_remove = None
        if not long_card:
            to_remove = [i for i in range(9, len(items), 10)] + \
                        [i for i in range(10, len(items), 10)]
        else:
            to_remove = [i for i in range(5, len(items), 6)] + \
                        [i for i in range(6, len(items), 6)]

        to_remove.sort(reverse=True)
        for i in to_remove:
            del items[i]

        # write it to the end of the file
        unique_int, new_rows = _items_to_long_form(items, unique_int)

        for row in new_rows[::-1]:
            self.text.insert(card, row)

        #print "\n".join(new_rows)
        return unique_int
コード例 #2
0
    def replace(self, input_variables):
        """
        Replace the ``input_variables`` in the text with the
        corresponding values.

        input_variables: {variable_name: value}
            We want to replace the instances of ``variable_name``
            with a value. ``variable_name`` should be a string; ``value``
            should be a stringafiable object. Note that although
            the actual variables are specified, like ``%varname`` in
            the Nastran file, the variable name here should just
            be ``varname``.

        Changes ``self.text``. Running this twice should probably
        error out since it wouldn't find the variables it was meant
        to replace.

        """

        # should be an array of lines
        nastran_text = self.text

        # we want all the variables in the nastran text
        all_variables = set()

        for line in nastran_text:
            matches = re.findall(variable_match, line)
            for match in matches:
                if match in all_variables:
                    # This should be given to the user... but
                    # maybe not in stdout
                    print "There is a duplicate variable called", match
                    print "They will get the same value"
                all_variables.add(match)

        # make sure we have all the variables that are declared
        # in the file
        extras = all_variables.difference(input_variables.keys())
        if len(extras) > 0:
            raise ValueError("There are variables in the file that aren't " +\
                             "provided as input variables: " + \
                             str(extras))

        not_used = set(input_variables.keys()).difference(all_variables)
        if len(not_used) > 0:
            # we really want to be logging this to DEBUG, or equiv
            print "Hey, just a heads up. You are passing in variables " +\
                  "that are not being replaced because they are not " +\
                  "in the file. This could indicate that you made a " +\
                  "mistake, or not. The offending variables are: " + \
                  str(not_used)


        new_nastran_text = []
        for line in nastran_text:
            new_nastran_text.append(line[:])
            matches = re.findall(variable_match, line)
            for match in matches:
                # If the variable starts with ``*'', we will not
                # simply replace the 8 character block, but we
                # will just overwrite the location of the variable
                if match.startswith("*"):
                    value = str(input_variables[match])
                    if len(value) < (len(match) + 1):
                        value = value.ljust(len(match)+1)
                    start_pos = new_nastran_text[-1].find("%" + match)
                    end_pos = start_pos + len(value) # exclusive
                    new_nastran_text[-1] = new_nastran_text[-1][:start_pos] + \
                                           value + \
                                           new_nastran_text[-1][end_pos:]


                #print "replacing", match, new_nastran_text, line
                else:
                    new_nastran_text[-1] = \
                         nastran_replace_inline(new_nastran_text[-1],\
                             "%" + match, \
                             stringify(input_variables[match]))

        self.text = new_nastran_text
コード例 #3
0
    def replace(self, input_variables):
        """
        Replace the ``input_variables`` in the text with the
        corresponding values.

        input_variables: {variable_name: value}
            We want to replace the instances of ``variable_name``
            with a value. ``variable_name`` should be a string; ``value``
            should be a stringafiable object. Note that although
            the actual variables are specified, like ``%varname`` in
            the Nastran file, the variable name here should just
            be ``varname``.

        Changes ``self.text``. Running this twice should probably
        error out since it wouldn't find the variables it was meant
        to replace.

        """

        # should be an array of lines
        nastran_text = self.text

        # we want all the variables in the nastran text
        all_variables = set()

        for line in nastran_text:
            matches = re.findall(variable_match, line)
            for match in matches:
                if match in all_variables:
                    # This should be given to the user... but
                    # maybe not in stdout
                    print "There is a duplicate variable called", match
                    print "They will get the same value"
                all_variables.add(match)

        # make sure we have all the variables that are declared
        # in the file
        extras = all_variables.difference(input_variables.keys())
        if len(extras) > 0:
            raise ValueError("There are variables in the file that aren't " +\
                             "provided as input variables: " + \
                             str(extras))

        not_used = set(input_variables.keys()).difference(all_variables)
        if len(not_used) > 0:
            # we really want to be logging this to DEBUG, or equiv
            print "Hey, just a heads up. You are passing in variables " +\
                  "that are not being replaced because they are not " +\
                  "in the file. This could indicate that you made a " +\
                  "mistake, or not. The offending variables are: " + \
                  str(not_used)

        new_nastran_text = []
        for line in nastran_text:
            new_nastran_text.append(line[:])
            matches = re.findall(variable_match, line)
            for match in matches:
                # If the variable starts with ``*'', we will not
                # simply replace the 8 character block, but we
                # will just overwrite the location of the variable
                if match.startswith("*"):
                    value = str(input_variables[match])
                    if len(value) < (len(match) + 1):
                        value = value.ljust(len(match) + 1)
                    start_pos = new_nastran_text[-1].find("%" + match)
                    end_pos = start_pos + len(value)  # exclusive
                    new_nastran_text[-1] = new_nastran_text[-1][:start_pos] + \
                                           value + \
                                           new_nastran_text[-1][end_pos:]

                #print "replacing", match, new_nastran_text, line
                else:
                    new_nastran_text[-1] = \
                         nastran_replace_inline(new_nastran_text[-1],\
                             "%" + match, \
                             stringify(input_variables[match]))

        self.text = new_nastran_text