-
Notifications
You must be signed in to change notification settings - Fork 30
/
common_functions.py
148 lines (116 loc) · 4.03 KB
/
common_functions.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
from math import ceil, floor
import datetime
import re
from typing import Callable
import numpy as np
def ts_to_date(timestamp: float) -> str:
return str(datetime.datetime.fromtimestamp(timestamp)).replace(' ', 'T')
def flatten(lst: list) -> list:
'''
flattens list of lists
'''
return [y for x in lst for y in x]
def round_up(n: float, d: int = 0):
try:
iter(n)
return np.ceil(n * 10**d) / 10**d
except:
return ceil(n * 10**d) / (10**d)
def round_dn(n: float, d: int = 0):
try:
iter(n)
return np.floor(n * 10**d) / 10**d
except:
return floor(n * 10**d) / (10**d)
def increment_by_precision(val: float, precision: float) -> float:
return round(val + 10**-precision, precision)
def decrement_by_precision(val: float, precision: float) -> float:
return round(val - 10**-precision, precision)
def calc_new_ema(prev_val: float,
new_val: float,
prev_ema: float,
span: float = None,
alpha: float = None,
n_steps: int = 1) -> float:
if n_steps <= 0:
return prev_ema
if alpha is None:
if span is None:
raise Exception('please specify alpha or span')
alpha = 2 / (span + 1)
if n_steps == 1:
return prev_ema * (1 - alpha) + new_val * alpha
else:
return calc_new_ema(prev_val,
new_val,
prev_ema * (1 - alpha) + prev_val * alpha,
alpha=alpha,
n_steps=n_steps - 1)
def ts_to_day(timestamp: float) -> str:
return str(datetime.datetime.fromtimestamp(timestamp))[:10]
def ts_to_date(timestamp: float) -> str:
return str(datetime.datetime.fromtimestamp(timestamp)).replace(' ', 'T')
def remove_elem(lst: [], elem):
'''
returns new list, first occurrence of elem removed
'''
try:
i = lst.index(elem)
return lst[:i] + lst[i + 1:]
except(ValueError):
return lst
def sort_dict_keys(d):
if type(d) == list:
return [sort_dict_keys(e) for e in d]
if type(d) != dict:
return d
return {key: sort_dict_keys(d[key]) for key in sorted(d)}
def strs_to_floats(d):
if type(d) == list:
return list(map(strs_to_floats, d))
if type(d) == bool:
return d
if type(d) != dict:
try:
return float(d)
except(ValueError):
return d
return {key: strs_to_floats(d[key]) for key in d}
def remove_duplicates(dict_list: [dict], key: str = None, sort: bool = False) -> [dict]:
try:
seen = set()
dup_removed = []
if key is not None:
dict_list_ = sorted(dict_list, key=lambda x: x['id']) if sort else dict_list
for d in dict_list_:
if d[key] not in seen:
dup_removed.append(d)
seen.add(d[key])
else:
if sort:
print('warning: will not sort dict_list without key')
for d in dict_list:
d_items = tuple(sorted(d.items()))
if d_items not in seen:
dup_removed.append(d)
seen.add(d_items)
return dup_removed
except:
print('error in remove duplicates')
print(dict_list)
raise Exception
def partition_sorted(lst: list, condition: Callable):
'''
takes sorted list
returns tuple: (list0 where condition == False and list1 where condition == True)
'''
for i in range(len(lst)):
if condition(lst[i]):
return lst[:i], lst[i:]
return lst, []
def format_float(num, rounding: int = -1):
return np.format_float_positional(num if rounding == -1 else round(num, rounding), trim='-')
def multiple_replace(string: str, rep_dict: dict) -> str:
pattern = re.compile("|".join([re.escape(k) for k in sorted(rep_dict, key=len, reverse=True)]),
flags=re.DOTALL)
return pattern.sub(lambda x: rep_dict[x.group(0)], string)