Skip to content

Instantly share code, notes, and snippets.

@Andrej730
Created July 17, 2023 11:52
Show Gist options
  • Save Andrej730/12be000d592b882a952d697e65953891 to your computer and use it in GitHub Desktop.
Save Andrej730/12be000d592b882a952d697e65953891 to your computer and use it in GitHub Desktop.
generate_bolts_yml.py
from pathlib import Path
from pprint import pprint
def find_nth_overlapping(haystack, needle, n=1):
start = haystack.find(needle)
while start >= 0 and n > 1:
start = haystack.find(needle, start+1)
n -= 1
return start
def process_table_data(table_data, x_split=1):
lines = table_data.splitlines()
test_spaces_amount = lines[0].strip().count(' ')
output_lines = []
for line in lines:
line = line.strip()
# print(line, '___', line.count('x'))
if x_split > 0:
if line.count('x') == x_split:
previous_line_part = line[:find_nth_overlapping(line, 'x', x_split) +2]
else:
line = previous_line_part + line
# print(f'previous line: {previous_line_part}')
output_lines.append(line.split())
current_spaces_count = line.count(' ')
if current_spaces_count != test_spaces_amount:
raise Exception(f'Line: {line} have {current_spaces_count} spaces. First line had {test_spaces_amount} spaces.\nFirst line: {lines[0]}')
return output_lines
def check_final_data(headers, value_types, output_lines):
# print(len(headers), len(value_types), len(output_lines[0]))
assert len(headers) == len(value_types) and len(value_types) == len(output_lines[0]), 'Headers, value_types and columns of data should be consistent.'
assert len(headers) == len((set(headers))), f"Headers shouldn't have duplicates. Duplicates: {[i for i in set(headers) if headers.count(i) > 1]}"
# US C Type
def get_us_c_type_data():
headers = [
"type", "h", "b", "tw", "tf", "sf", "r1", "r2"
]
value_types = [
"", "in", "in", "in", "in", "%", "in", "in"
]
table_data = """C15X50 15.0 3.72 0.716 0.650 16.67 0.719 0.185
C15X40 15.0 3.52 0.520 0.650 16.67 0.7 0.195
C15X33.9 15.0 3.40 0.400 0.650 16.67 0.688 0.2
C12X30 12.0 3.17 0.510 0.501 16.67 0.54 0.129
C12X25 12.0 3.05 0.387 0.501 16.67 0.527 0.135
C12X20.7 12.0 2.94 0.282 0.501 16.67 0.517 0.14
C10X30 10.0 3.03 0.673 0.436 16.67 0.508 0.1
C10X25 10.0 2.89 0.526 0.436 16.67 0.493 0.106
C10X20 10.0 2.74 0.379 0.436 16.67 0.479 0.113
C10X15.3 10.0 2.60 0.240 0.436 16.67 0.465 0.12
C9X20 9.00 2.65 0.448 0.413 16.67 0.529 0.105
C9X15 9.00 2.49 0.285 0.413 16.67 0.512 0.112
C9X13.4 9.00 2.43 0.233 0.413 16.67 0.508 0.115
C8X18.75 8.00 2.53 0.487 0.390 16.67 0.502 0.098
C8X13.75 8.00 2.34 0.303 0.390 16.67 0.484 0.106
C8X11.5 8.00 2.26 0.220 0.390 16.67 0.476 0.11
C7X14.75 7.00 2.30 0.419 0.366 16.67 0.465 0.095
C7X12.25 7.00 2.19 0.314 0.366 16.67 0.455 0.1
C7X9.8 7.00 2.09 0.210 0.366 16.67 0.444 0.105
C6X13 6.00 2.16 0.437 0.343 16.67 0.435 0.089
C6X10.5 6.00 2.03 0.314 0.343 16.67 0.424 0.095
C6X8.2 6.00 1.92 0.200 0.343 16.67 0.412 0.1
C5X9 5.00 1.89 0.325 0.320 16.67 0.392 0.089
C5X6.7 5.00 1.75 0.190 0.320 16.67 0.379 0.095
C4X7.25 4.00 1.72 0.321 0.296 16.67 0.437 0.083
C4X6.25 4.00 1.65 0.247 0.296 16.67 0.429 0.086
C4X5.4 4.00 1.58 0.184 0.296 16.67 0.424 0.09
C4X4.5 4.00 1.52 0.125 0.296 16.67 0.418 0.092
C3X6 3.00 1.60 0.356 0.273 16.67 0.409 0.076
C3X5 3.00 1.50 0.258 0.273 16.67 0.4 0.081
C3X4.1 3.00 1.41 0.170 0.273 16.67 0.391 0.085
C3X3.5 3.00 1.37 0.132 0.273 16.67 0.387 0.087"""
output_lines = process_table_data(table_data, x_split=0)
check_final_data(headers, value_types, output_lines)
headers_filter = headers[1:]
return output_lines, headers, headers_filter
# ===============================================
# profile_path, profile_data, data_headers, headers_filter
profiles_data = [
('data/profile_c/cbeam_c_imp.yaml', *get_us_c_type_data()),
]
def get_yaml_line(element_name, element_data, name_width=25, data_width=10):
element_data_str = ','.join([str(i).rjust(data_width) for i in element_data])
line = f'{(element_name+":").ljust(name_width)} [{element_data_str} ]\n'
return line
def get_yaml_header(element_name, element_data, name_width=25, data_width=10):
element_data_str = ' '.join([str(i).rjust(data_width) for i in element_data])
line = f'{("#"+element_name+":").ljust(name_width)} [{element_data_str} ]\n'
return line
base_path = Path(__file__).parent
for profile_data in profiles_data:
print(f'Processing {profile_data[0]}')
profile_path, profile_data, data_headers, headers_filter = profile_data
data_indices = [i for i in range(len(data_headers)) if data_headers[i] in headers_filter]
# sort data the same way as headers
data_indices = sorted(data_indices, key=lambda x: headers_filter.index(data_headers[x]))
assert len(data_indices) == len(headers_filter), "Amount of data columns the expected amount (header_filter)"
profile_path = base_path / Path(profile_path)
profile_path.parent.mkdir(exist_ok=True, parents=True)
lines = []
lines.append(get_yaml_header('type', headers_filter))
for data_row in profile_data:
profile_type = data_row[0]
yml_data = [data_row[i] for i in data_indices]
line = get_yaml_line(profile_type, yml_data)
lines.append(line)
def all_lines_have_the_space_at(char_i):
return all(line[char_i] == ' ' for line in lines)
def remove_character_from_lines(char_i):
for i in range(len(lines)):
line = lines[i]
lines[i] = line[:char_i] + line[char_i+1:]
# clean up unnecessary spaces
char_i = -1
while True:
if char_i >= len(lines[0]) - 1:
break
char_i += 1
cur_char = lines[0][char_i]
if cur_char != ' ':
continue
if not all_lines_have_the_space_at(char_i):
continue
char_i += 1
while all_lines_have_the_space_at(char_i):
remove_character_from_lines(char_i)
with open(profile_path, 'w') as file_output:
for line in lines:
file_output.write(line)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment