-
Notifications
You must be signed in to change notification settings - Fork 0
/
DelegateFunc.py
130 lines (118 loc) · 5.09 KB
/
DelegateFunc.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
class DelegateFunc:
'''Function wrapper to delay execution
Allows functions to be composed and combined with
binary operations, producing a new function.
Carries around a string which gives a rough
representation of the resulting function
'''
def __init__(self,func,string):
self.func=func
self.string=string
def __call__(self, val):
try:
return self.func(val)
except AttributeError:
newfunc= lambda x: self.func(val(x))
newstring=self.string +'('+val.string+')'
return DelegateFunc(newfunc,newstring)
def __str__(self):
return self.string
def __add__(self, other):
try:
newfunc=lambda x: self.func(x)+other.func(x)
if other.string=='0.0' or other.string=='0':
if self.string=='0.0' or self.string=='0':
newstring='0'
else:
newstring=self.string
elif self.string=='0.0' or self.string=='0':
newstring=other.string
else:
newstring=self.string+"+"+other.string
return DelegateFunc(newfunc,newstring)
except AttributeError:
newfunc = lambda x: other+self.func(x)
if str(other)=='0' or str(other)=='0.0':
newstring = self.string
elif self.string=='0' or self.string=='0.0':
newstring=str(other)
else:
newstring=self.string+"+"+str(other)
return DelegateFunc(newfunc, newstring)
def __radd__(self, other):
return self+other
def __neg__(self):
newfunc=lambda x: -self.func(x)
newstring='-('+self.string+')'
return DelegateFunc(newfunc,newstring)
def __mul__(self, other):
try:
newfunc=lambda x: self.func(x)*other.func(x)
if len(self.string)<=len(other.string):
newstring=self.string+'*('+other.string+')'
if any((s == str(self) for s in ('0.0', '0', '-0.0', '-0'))):
newstring='0'
else:
newstring=other.string+'*('+self.string+')'
if any((s == str(other) for s in ('0.0', '0', '-0.0', '-0'))):
newstring='0'
return DelegateFunc(newfunc,newstring)
except AttributeError:
newfunc = lambda x: other*self.func(x)
if any((s == str(self) for s in ('0.0', '0', '-0.0', '-0'))):
newstring = '0'
elif str(other)=='1.0' or str(other)=='1':
newstring=self.string
elif str(other)=='-1.0' or str(other)=='-1':
newstring='-('+self.string+')'
elif any((s==str(other) for s in ('0.0','0','-0.0','-0'))):
newstring='0'
else:
newstring = str(other)+"*("+self.string+")"
return DelegateFunc(newfunc, newstring)
def __rmul__(self, other):
return self*other
def __truediv__(self, other):
try:
newfunc=lambda x: self.func(x)/other.func(x)
newstring = "("+self.string + ')/(' + other.string + ')'
if any((s == str(self) for s in ('0.0', '0', '-0.0', '-0'))):
newstring = '0'
elif any((s == str(other) for s in ('0.0', '0', '-0.0', '-0'))):
newstring='inf'
return DelegateFunc(newfunc, newstring)
except AttributeError:
newfunc = lambda x: self.func(x)/other
if any((s == str(self) for s in ('0.0', '0', '-0.0', '-0'))):
newstring = '0'
elif str(other)=='1.0' or str(other)=='1':
newstring=self.string
elif str(other)=='-1.0' or str(other)=='-1':
newstring='-('+self.string+')'
elif any((s==str(other) for s in ('0.0','0','-0.0','-0'))):
newstring='inf'
else:
newstring = "("+self.string+")/"+str(other)
return DelegateFunc(newfunc, newstring)
def __rtruediv__(self, other):
try:
newfunc = lambda x: other.func(x) / other.func(x)
newstring = "(" + other.string + ')/(' + self.string + ')'
if any((s == str(other) for s in ('0.0', '0', '-0.0', '-0'))):
newstring = '0'
elif any((s == str(self) for s in ('0.0', '0', '-0.0', '-0'))):
newstring = 'inf'
return DelegateFunc(newfunc, newstring)
except AttributeError:
newfunc = lambda x: other/self.func(x)
if any((s == str(other) for s in ('0.0', '0', '-0.0', '-0'))):
newstring = '0'
elif str(other) == '1.0' or str(other) == '1':
newstring = "1/("+self.string+")"
elif str(other) == '-1.0' or str(other) == '-1':
newstring = '-1/(' + self.string + ')'
elif any((s == str(self) for s in ('0.0', '0', '-0.0', '-0'))):
newstring = 'inf'
else:
newstring = str(other)+"/(" + self.string + ")"
return DelegateFunc(newfunc, newstring)