<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def parse_fixed_table(table_lines, heading_ignore=[], header_substitute=[], trailing_ignore=[]):
 """ Function to parse table data containing column headings in the first row and data in fixed positions in each remaining row of table data. Table columns must not contain spaces within the column name. Column headings are assumed to be left justified and the column data width is the width of the heading label plus all whitespace to the right of the label. This function will handle blank columns. Arguments: table_lines (list):
 List of strings with the first line containing column headings separated by spaces, and the remaining lines containing table data in left justified format. heading_ignore (list):
 Optional list of strings to search for at beginning of line. All lines before this line will be ignored. If specified then it must be present in the file or `ValueError` will be raised. header_substitute (list):
 Optional list of tuples containing `(old_string_value, new_string_value)` to be used to modify header values. If whitespace is present in a column it must be replaced with non-whitespace characters in order for the table to be parsed correctly. trailing_ignore (list):
 Optional list of strings to look for at the end rows of the content. Lines starting with these strings will be ignored, thereby truncating the rows of data. Returns: list: Returns a list of dict for each row of column data. Dict keys are the column headings in the same case as input. Raises: ValueError: Raised if `heading_ignore` is specified and not found in `table_lines`. Sample input:: Column1 Column2 Column3 data1 data 2 data 3 data4 data5 data6 Examples: [{'Column1': 'data1', 'Column2': 'data 2', 'Column3': 'data 3'}, {'Column1': 'data4', 'Column2': 'data5', 'Column3': 'data6'}] """

    def calc_column_indices(line, headers):
        idx = []
        for h in headers:
            i = idx[-1] + 1 if idx else 0
            idx.append(line.index(h, i))
        return idx

    first_line = calc_offset(table_lines, heading_ignore)
    try:
        last_line = len(table_lines) - calc_offset(reversed(table_lines),
                                                   trailing_ignore,
                                                   invert_search=True)
    except ValueError:
        last_line = len(table_lines)

    header = table_lines[first_line]
    if header_substitute:
        for old_val, new_val in header_substitute:
            header = header.replace(old_val, new_val)
    col_headers = header.strip().split()
    col_index = calc_column_indices(header, col_headers)

    table_data = []
    for line in table_lines[first_line + 1:last_line]:
        col_data = dict(
            (col_headers[c], line[col_index[c]:col_index[c + 1]].strip())
            for c in range(len(col_index) - 1)
        )
        col_data[col_headers[-1]] = line[col_index[-1]:].strip()
        table_data.append(col_data)

    return table_data