1#!/usr/local/bin/python3.8
2
3import re
4import typing as ty
5import math
6import itertools
7
8def tuple2StrWOspaces(val: tuple) -> str:
9    newStr = ','.join(['{:.6g}'.format(value) for value in val])
10    return '({0})'.format(newStr)
11
12def tryParse(val, typ=float):
13    try:
14        return typ(val)
15    except ValueError:
16        return None
17
18def funcOnList(list1: ty.Union[ty.List, ty.Tuple], list2: ty.Union[ty.List, ty.Tuple], func: ty.Callable) -> tuple:
19    """Returns [f(x[i], y[i]) : i in 1, ..., n - 1] in order with f as func
20    and x and y as list1 and 2. """
21
22    assert len(list1) == len(list2)
23    return tuple([func(list1[i], list2[i]) for i in range(len(list1))])
24
25
26def listize(str, typ, delim='()') -> list:
27    str = str.strip(delim)
28    raw_elem = str.split(',')
29    final_list = []
30    if isinstance(typ, (list, tuple)):
31        for i in range(len(raw_elem)):
32            if i < len(typ):
33                curr_typ = typ[i]
34            else:
35                curr_typ = typ[-1]
36            final_list.append(curr_typ(raw_elem[i].strip()))
37    else:
38        for elem in raw_elem:
39            final_list.append(typ(elem.strip()))
40    return final_list
41
42def twonorm(vec: ty.Iterable[ty.Union[float, int]]) -> float:
43    rawSquared = sum(map(lambda x: x*x, vec))
44    return math.sqrt(rawSquared)
45
46def tryParseKey(raw_key):
47    """Returns None if raw key is not in #.# format"""
48    # See https://regex101.com/r/6G9MZD/1/
49    # for the regex data
50    return re.fullmatch(r'^(\d+)\.(\d+)$', raw_key)
51