-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathutil.py
124 lines (105 loc) · 3.48 KB
/
util.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
import os
from functools import reduce, partial
__FUNCTION_TYPE__ = type(lambda x : x)
def identity(x):
"""Return the input itself."""
return x
def constant(c):
"""Return an function which always
returns the input constant c."""
def const_function(const, *args):
return const
return partial(const_function, c)
def add(*args):
"""Return the sum of the input."""
def add2(x, y): return x + y
return reduce(add2, args)
def filterv(f, lst):
return list(filter(f, lst))
def mapv(f, *lst):
"""Return a vector of the result of map."""
return list(map(f, *lst))
def vector(*args):
"""Return a vector of input parameters."""
return args
def sequence(n, f = constant(0)):
"""Return a vector of length n, and initialize the i'th
item with f(i).By default the vector will initialized with 0."""
return [f(i) for i in range(0, n)]
def matrix(n, m, f = constant(0)):
"""Return a 2-dim vector which contains n vectors with length m.
The j's item of vector i will be initialized by f(i, j).By default,
the vector will be initialized with 0."""
return [[f(i, j) for j in range(0, m)] for i in range(0, n)]
def flat(v):
"""Return a flat vector which contains the elements of v in their
origin order.If the input is not a vector, return a vector which
only contains the input."""
if not isinstance(v, list): return [v]
if not v: return []
return reduce(add, mapv(flat, v))
def partition(v, f = identity):
"""Partition vector v by f(v[i]).
e.g. partition([1, 2, 3, 1, 2, 3], identity()) == {1 : [1, 1, 1], 2 : [2, 2], 3 : [3]}
By default, the vector will be partitioned by identity function."""
result = {}
for item in v:
key = f(item)
s = result.get(key)
if s:
s.append(item)
else:
result.update({key:[item]})
return result
def getValue(key):
"""Return a function which returns the value of key in a hash-map.
If the key do not exist, it will throw an error."""
return lambda x: x[key]
def mapValue(f, m):
"""Replace each value in hash-map m with f(value).
Return the new hash-map."""
res = {}
for key in m:
res.update({key: f(m[key])})
return res
def buildMap(*args):
"""
e.g.
x = [0, 1]
y = [2, 3]
buildMap('x', x, 'y', y) = [{'x' : 0, 'y' : 2}, {'x' : 1, 'y' : 3}]
"""
def update(m1, m2):
m1.update(m2)
map_items = len(args) >> 1
result = [{} for i in range(len(args[1]))]
for i in range(0, map_items):
key = args[i << 1]
new_item = mapv(lambda x: {key: x},
args[(i << 1) + 1])
mapv(update, result, new_item)
return result
def threadFirst(x, *functions):
"""
thread-first macro in Clojure.
"""
for f in functions:
if type(f) is list:
x = f[0](*(f[1:] + [x]))
elif type(f) is __FUNCTION_TYPE__:
x = f(x)
else:
raise Exception('unable to handle function ' + f)
return x
# This class comes from stackOverFlow
# http://stackoverflow.com/questions/431684/how-do-i-cd-in-python
# Thanks to Brian M. Hunt
class cd:
"""Context manager for changing the current working directory"""
def __init__(self, newPath):
self.newPath = os.path.expanduser(newPath)
def __enter__(self):
self.savedPath = os.getcwd()
os.chdir(self.newPath)
def __exit__(self, etype, value, traceback):
os.chdir(self.savedPath)