1 """Various utility methods for use by other PsychSim classes"""
2
3 import copy
4 import string
5 import time
6 import sys
7 from types import *
8
9 from teamwork.math.Interval import Interval
10 from Debugger import *
11 from teamwork.action.PsychActions import *
12
14 """Returns the difference in goal weights between two lists of
15 goals of the form [(goal,weight),(goal,weight),...], where
16 goal is either a PsychGoal object or a dictionary that is a
17 suitable input to the PsychGoal constructor, and weight is a
18 (possibly unnormalized) float"""
19 goalDict = {}
20
21 normalization1 = 0.0
22 for goal,weight in goalList1:
23 if type(goal) is DictType:
24 goal = PsychGoal(goal)
25 normalization1 = normalization1 + weight
26 goalDict[`goal`] = (weight,0.0)
27 normalization2 = 0.0
28 for goal,weight in goalList2:
29 if type(goal) is DictType:
30 goal = PsychGoal(goal)
31 if goalDict.has_key(`goal`):
32 goalDict[`goal`] = (goalDict[`goal`][0],weight)
33 else:
34 goalDict[`goal`] = (0.0,weight)
35 normalization2 = normalization2 + weight
36
37 total = 0.0
38 for weight1,weight2 in goalDict.values():
39 total = total + pow(weight1/normalization1-weight2/normalization2,2)
40 return total
41
43 """Takes a list of factors and generates all possible messages
44 (i.e., all possible combinations of those factors"""
45 msgList = [{}]
46 for factor in factorList:
47 for msg in msgList[:]:
48 newMsg = copy.copy(msg)
49 newMsg[factor] = 1
50 msgList.append(newMsg)
51 msgList.remove({})
52 msgList.append(None)
53 return msgList
54
56 """Takes a list of probability values and computes a noisy OR"""
57 result = -1
58 for prob in probabilities:
59 result = result * (1.0-prob)
60 return result
61
63 """Translates an action in string form into a structured
64 dictionary representation of that same action (e.g.,
65 'CLF-violence-to-UrbanPoor' becomes
66 {'actor':CLF,'type':'violence','object':UrbanPoor}"""
67 if not action:
68 action = 'wait'
69 if not isinstance(action,str):
70 action = `str`
71 components = string.split(action,'-')
72 if len(components) < 2:
73
74 return {'type':action}
75 elif len(components) < 3:
76
77 return {'actor':components[0],'type':components[1]}
78 elif len(components) < 4:
79
80 for obj in entities:
81 try:
82 if obj.name == components[2]:
83 break
84 except AttributeError:
85 pass
86 else:
87 obj = components[2]
88 return {'type':components[0],'object':obj}
89 elif len(components) < 5:
90
91 for obj in entities:
92 if obj.name == components[3]:
93 break
94 else:
95 obj = components[3]
96 return {'actor':components[0],'type':components[1],
97 'object':obj}
98 else:
99
100 for obj in entities:
101 if obj.name == components[3]:
102 break
103 else:
104 obj = components[3]
105 actionStr = string.join(components[4:],'-')
106 subAction = act2dict(actionStr,entities)
107 subAction['string'] = actionStr
108 return {'actor':components[0],'type':components[1],
109 'object':obj,'action':subAction}
110
112 """Translates a structured dictionary representation of an action
113 into a standardized string format (e.g.,
114 {'actor':CLF,'type':'violence','object':UrbanPoor} becomes
115 'CLF-violence-to-UrbanPoor'"""
116 str = action['type']
117 if action.has_key('object'):
118 obj = action['object']
119 if not type(obj) is StringType:
120 obj = obj.name
121 str = str+'-to-'+obj
122 if action.has_key('actor'):
123 actor = action['actor']
124 if not type(actor) is StringType:
125 actor = actor.name
126 str = actor+'-'+str
127 if action.has_key('action'):
128 if action['action'].has_key('string'):
129 str = str + '-' + action['action']['string']
130 else:
131 str = str + '-' + dict2act(action['action'])
132 return str
133
143
145 """Tries to convert the specified value into a float; if unable,
146 returns 0.0 (avoids nasty exceptions)"""
147 try:
148 return float(value)
149 except ValueError:
150 return 0.0
151
153 """Translates an action (in either string or dictionary form) into
154 a properly formatted observation dictionary for use by COM-MTDP
155 code"""
156 obs = {'type':'observation','content':{}}
157 if type(act) is StringType:
158 obs['content'][act] = 'yes'
159 else:
160 obs['content'][`act`] = 'yes'
161 return obs
162
164 content = '{'
165 for key in dict.keys():
166 obj = dict[key]
167 if type(obj) is FloatType:
168 content += '\n\t%s: %5.3f' % (str(key),obj)
169 elif type(obj) is StringType:
170 content += '\n\t%s: %s' % (str(key),obj)
171 elif type(obj) is InstanceType:
172 content += '\n\t%s: %s' % (str(key),str(obj))
173 elif isinstance(obj,Action):
174 content += '\n\t%s: %s' % (str(key),str(obj))
175 elif not type(obj) in [DictType,ListType,TupleType]:
176 try:
177 content += '\n\t%s: %s' % (str(key),str(obj.keys()))
178 except AttributeError:
179 content += '\n\t%s: %s' % (str(key),str(obj))
180 if depth:
181 substr = ''
182 for key in dict.keys():
183 obj = dict[key]
184 if type(obj) is DictType:
185 substr = substr + '\n' + key + ': ' + dict2str(obj,depth-1)
186 elif type(obj) is ListType:
187 substr = substr + '\n' + key + ': '
188 for index in range(len(obj)):
189 entry = obj[index]
190 if type(entry) is DictType:
191 substr = substr + '\n\t' + `index` + '. ' + \
192 dict2str(entry,depth-1)
193 else:
194 substr = substr + '\n\t' + `index` + '. ' + `entry`
195 content += substr.replace('\n','\n\t')
196 content += '}'
197 return content
198
200 """Generic debugging statement that can handle three types of
201 debug parameters: (1) Integer - prints string if debug >= level,
202 (2) Tuple (debug,result) - appends string to result if debug >=
203 level, and (3) List [debug,result,time] - if debug >= level, adds
204 string to result along with time difference between now and
205 provided time (side efffect: sets time to now)"""
206 if type(debug) is TupleType:
207 if debug[0] >= level:
208 debug[1].append(str)
209 elif type(debug) is ListType:
210 if debug[0] >= level:
211 try:
212 lastTime = debug[2]
213 newTime = time.time()
214 if lastTime:
215 diff = int((newTime-lastTime)*1000.0)
216 if diff > 0:
217 str = str + ' ('+`diff`+' ms)'
218 debug[2] = newTime
219 except IndexError:
220 pass
221 debug[1].append(str)
222 else:
223 if debug >= level:
224 print str
225
227 """Takes a file name (string) and reads a pickled Python object
228 from the file and returns it"""
229 import pickle
230
231 file = open(name,'rb')
232 try:
233 obj = pickle.load(file)
234 except AttributeError,e:
235
236 items = string.split(str(e))
237 module = items[len(items)-1]
238 module = module[1:len(module)-1]
239 raise NameError,'Unknown module: %s' % (module)
240 file.close()
241 return obj
242
244 try:
245 entity = entities[name]
246 return entity
247 except KeyError:
248 print 'Unknown entity:',name
249 return None
250
252 action = {}
253 for item in format:
254
255 if item[1]:
256
257 if len(cmd) == 0:
258 return None
259
260 if len(cmd) == 0:
261 break
262
263 if item[0] in ['actor','object']:
264 entity = extractEntity(cmd[0],entities)
265 if not entity:
266
267 if item[1]:
268
269 return None
270 else:
271
272 break
273
274 action[item[0]] = entity.name
275 elif item[0] == 'type':
276
277 if cmd[0] == 'policy':
278 act,explanation = action['actor'].applyPolicy(debug=debug)
279 debug.message(1,'Policy: '+`action`)
280 return act
281 else:
282 action[item[0]] = cmd[0]
283 if cmd[0] == 'command':
284 format += [('type',1),('object',None)]
285 else:
286 action[item[0]] = cmd[0]
287
288 cmd = cmd[1:]
289 actClass = entities.members()[0].actionClass
290 return actClass(action)
291