1# -*- coding: utf-8 -*-2import sys3from typing import List4import re56awg_equiv_table = {7 '0.09': '28',8 '0.14': '26',9 '0.25': '24',10 '0.34': '22',11 '0.5': '21',12 '0.75': '20',13 '1': '18',14 '1.5': '16',15 '2.5': '14',16 '4': '12',17 '6': '10',18 '10': '8',19 '16': '6',20 '25': '4',21 '35': '2',22 '50': '1',23}2425mm2_equiv_table = {v:k for k,v in awg_equiv_table.items()}2627def awg_equiv(mm2):28 return awg_equiv_table.get(str(mm2), 'Unknown')2930def mm2_equiv(awg):31 return mm2_equiv_table.get(str(awg), 'Unknown')323334def expand(yaml_data):35 # yaml_data can be:36 # - a singleton (normally str or int)37 # - a list of str or int38 # if str is of the format '#-#', it is treated as a range (inclusive) and expanded39 output = []40 if not isinstance(yaml_data, list):41 yaml_data = [yaml_data]42 for e in yaml_data:43 e = str(e)44 if '-' in e:45 a, b = e.split('-', 1)46 try:47 a = int(a)48 b = int(b)49 if a < b:50 for x in range(a, b + 1):51 output.append(x) # ascending range52 elif a > b:53 for x in range(a, b - 1, -1):54 output.append(x) # descending range55 else: # a == b56 output.append(a) # range of length 157 except:58 output.append(e) # '-' was not a delimiter between two ints, pass e through unchanged59 else:60 try:61 x = int(e) # single int62 except Exception:63 x = e # string64 output.append(x)65 return output666768def int2tuple(inp):69 if isinstance(inp, tuple):70 output = inp71 else:72 output = (inp,)73 return output747576def flatten2d(inp):77 return [[str(item) if not isinstance(item, List) else ', '.join(item) for item in row] for row in inp]787980def tuplelist2tsv(inp, header=None):81 output = ''82 if header is not None:83 inp.insert(0, header)84 inp = flatten2d(inp)85 for row in inp:86 output = output + '\t'.join(str(remove_links(item)) for item in row) + '\n'87 return output888990def remove_links(inp):91 return re.sub(r'<[aA] [^>]*>([^<]*)</[aA]>', r'\1', inp) if isinstance(inp, str) else inp929394def clean_whitespace(inp):95 return ' '.join(inp.split()).replace(' ,', ',') if isinstance(inp, str) else inp969798def open_file_read(filename):99 # TODO: Intelligently determine encoding100 return open(filename, 'r', encoding='UTF-8')101102def open_file_write(filename):103 return open(filename, 'w', encoding='UTF-8')104105def open_file_append(filename):106 return open(filename, 'a', encoding='UTF-8')107108def aspect_ratio(image_src):109 try:110 from PIL import Image111 image = Image.open(image_src)112 if image.width > 0 and image.height > 0:113 return image.width / image.height114 sys.stderr.write(f'aspect_ratio(): Invalid image size {image.width} x {image.height}')115 # ModuleNotFoundError and FileNotFoundError are the most expected, but all are handled equally.116 except Exception as error:117 sys.stderr.write(f'aspect_ratio(): {type(error).__name__}: {error}')118 return 1 # Assume 1:1 when unable to read actual image size