chiark / gitweb /
0c968ceaed9439aa62638f6d008fc1bab8eef616
[cura.git] / Cura / fabmetheus_utilities / geometry / geometry_utilities / evaluate.py
1 """
2 Evaluate expressions.
3
4 """
5
6 from __future__ import absolute_import
7 #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module.
8 import __init__
9
10 from fabmetheus_utilities.geometry.geometry_utilities.evaluate_elements import setting
11 from fabmetheus_utilities.vector3 import Vector3
12 from fabmetheus_utilities import archive
13 from fabmetheus_utilities import euclidean
14 from fabmetheus_utilities import gcodec
15 from fabmetheus_utilities import settings
16 import math
17 import os
18 import sys
19 import traceback
20
21
22 __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
23 __credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
24 __date__ = '$Date: 2008/02/05 $'
25 __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
26
27
28 globalModuleFunctionsDictionary = {}
29
30
31 def addPrefixDictionary(dictionary, keys, value):
32         'Add prefixed key values to dictionary.'
33         for key in keys:
34                 dictionary[key.lstrip('_')] = value
35
36 def addQuoteWord(evaluatorWords, word):
37         'Add quote word and remainder if the word starts with a quote character or dollar sign, otherwise add the word.'
38         if len(word) < 2:
39                 evaluatorWords.append(word)
40                 return
41         firstCharacter = word[0]
42         if firstCharacter == '$':
43                 dotIndex = word.find('.', 1)
44                 if dotIndex > -1:
45                         evaluatorWords.append(word[: dotIndex])
46                         evaluatorWords.append(word[dotIndex :])
47                         return
48         if firstCharacter != '"' and firstCharacter != "'":
49                 evaluatorWords.append(word)
50                 return
51         nextQuoteIndex = word.find(firstCharacter, 1)
52         if nextQuoteIndex < 0 or nextQuoteIndex == len(word) - 1:
53                 evaluatorWords.append(word)
54                 return
55         nextQuoteIndex += 1
56         evaluatorWords.append(word[: nextQuoteIndex])
57         evaluatorWords.append(word[nextQuoteIndex :])
58
59 def addToPathsRecursively(paths, vector3Lists):
60         'Add to vector3 paths recursively.'
61         if vector3Lists.__class__ == Vector3 or vector3Lists.__class__ .__name__ == 'Vector3Index':
62                 paths.append([ vector3Lists ])
63                 return
64         path = []
65         for vector3List in vector3Lists:
66                 if vector3List.__class__ == list:
67                         addToPathsRecursively(paths, vector3List)
68                 elif vector3List.__class__ == Vector3:
69                         path.append(vector3List)
70         if len(path) > 0:
71                 paths.append(path)
72
73 def addValueToEvaluatedDictionary(elementNode, evaluatedDictionary, key):
74         'Get the evaluated dictionary.'
75         value = getEvaluatedValueObliviously(elementNode, key)
76         if value == None:
77                 valueString = str(elementNode.attributes[key])
78                 print('Warning, addValueToEvaluatedDictionary in evaluate can not get a value for:')
79                 print(valueString)
80                 evaluatedDictionary[key + '__Warning__'] = 'Can not evaluate: ' + valueString.replace('"', ' ').replace( "'", ' ')
81         else:
82                 evaluatedDictionary[key] = value
83
84 def addVector3ToElementNode(elementNode, key, vector3):
85         'Add vector3 to xml element.'
86         elementNode.attributes[key] = '[%s,%s,%s]' % (vector3.x, vector3.y, vector3.z)
87
88 def compareExecutionOrderAscending(module, otherModule):
89         'Get comparison in order to sort modules in ascending execution order.'
90         if module.globalExecutionOrder < otherModule.globalExecutionOrder:
91                 return -1
92         if module.globalExecutionOrder > otherModule.globalExecutionOrder:
93                 return 1
94         if module.__name__ < otherModule.__name__:
95                 return -1
96         return int(module.__name__ > otherModule.__name__)
97
98 def convertToPaths(dictionary):
99         'Recursively convert any ElementNodes to paths.'
100         if dictionary.__class__ == Vector3 or dictionary.__class__.__name__ == 'Vector3Index':
101                 return
102         keys = getKeys(dictionary)
103         if keys == None:
104                 return
105         for key in keys:
106                 value = dictionary[key]
107                 if value.__class__.__name__ == 'ElementNode':
108                         if value.xmlObject != None:
109                                 dictionary[key] = getFloatListListsByPaths(value.xmlObject.getPaths())
110                 else:
111                         convertToPaths(dictionary[key])
112
113 def convertToTransformedPaths(dictionary):
114         'Recursively convert any ElementNodes to paths.'
115         if dictionary.__class__ == Vector3 or dictionary.__class__.__name__ == 'Vector3Index':
116                 return
117         keys = getKeys(dictionary)
118         if keys == None:
119                 return
120         for key in keys:
121                 value = dictionary[key]
122                 if value.__class__.__name__ == 'ElementNode':
123                         if value.xmlObject != None:
124                                 dictionary[key] = value.xmlObject.getTransformedPaths()
125                 else:
126                         convertToTransformedPaths(dictionary[key])
127
128 def executeLeftOperations( evaluators, operationLevel ):
129         'Evaluate the expression value from the numeric and operation evaluators.'
130         for negativeIndex in xrange( - len(evaluators), - 1 ):
131                 evaluatorIndex = negativeIndex + len(evaluators)
132                 evaluators[evaluatorIndex].executeLeftOperation( evaluators, evaluatorIndex, operationLevel )
133
134 def executeNextEvaluatorArguments(evaluator, evaluators, evaluatorIndex, nextEvaluator):
135         'Execute the nextEvaluator arguments.'
136         if evaluator.value == None:
137                 print('Warning, executeNextEvaluatorArguments in evaluate can not get a evaluator.value for:')
138                 print(evaluatorIndex)
139                 print(evaluators)
140                 print(evaluator)
141                 return
142         nextEvaluator.value = evaluator.value(*nextEvaluator.arguments)
143         del evaluators[evaluatorIndex]
144
145 def executePairOperations(evaluators, operationLevel):
146         'Evaluate the expression value from the numeric and operation evaluators.'
147         for negativeIndex in xrange(1 - len(evaluators), - 1):
148                 evaluatorIndex = negativeIndex + len(evaluators)
149                 evaluators[evaluatorIndex].executePairOperation(evaluators, evaluatorIndex, operationLevel)
150
151 def getBracketEvaluators(bracketBeginIndex, bracketEndIndex, evaluators):
152         'Get the bracket evaluators.'
153         return getEvaluatedExpressionValueEvaluators(evaluators[bracketBeginIndex + 1 : bracketEndIndex])
154
155 def getBracketsExist(evaluators):
156         'Evaluate the expression value.'
157         bracketBeginIndex = None
158         for negativeIndex in xrange( - len(evaluators), 0 ):
159                 bracketEndIndex = negativeIndex + len(evaluators)
160                 evaluatorEnd = evaluators[ bracketEndIndex ]
161                 evaluatorWord = evaluatorEnd.word
162                 if evaluatorWord in ['(', '[', '{']:
163                         bracketBeginIndex = bracketEndIndex
164                 elif evaluatorWord in [')', ']', '}']:
165                         if bracketBeginIndex == None:
166                                 print('Warning, bracketBeginIndex in evaluateBrackets in evaluate is None.')
167                                 print('This may be because the brackets are not balanced.')
168                                 print(evaluators)
169                                 del evaluators[ bracketEndIndex ]
170                                 return
171                         evaluators[ bracketBeginIndex ].executeBracket(bracketBeginIndex, bracketEndIndex, evaluators)
172                         evaluators[ bracketBeginIndex ].word = None
173                         return True
174         return False
175
176 def getBracketValuesDeleteEvaluator(bracketBeginIndex, bracketEndIndex, evaluators):
177         'Get the bracket values and delete the evaluator.'
178         evaluatedExpressionValueEvaluators = getBracketEvaluators(bracketBeginIndex, bracketEndIndex, evaluators)
179         bracketValues = []
180         for evaluatedExpressionValueEvaluator in evaluatedExpressionValueEvaluators:
181                 bracketValues.append( evaluatedExpressionValueEvaluator.value )
182         del evaluators[ bracketBeginIndex + 1: bracketEndIndex + 1 ]
183         return bracketValues
184
185 def getCapitalizedSuffixKey(prefix, suffix):
186         'Get key with capitalized suffix.'
187         if prefix == '' or prefix.endswith('.'):
188                 return prefix + suffix
189         return prefix + suffix[:1].upper()+suffix[1:]
190
191 def getDictionarySplitWords(dictionary, value):
192         'Get split line for evaluators.'
193         if getIsQuoted(value):
194                 return [value]
195         for dictionaryKey in dictionary.keys():
196                 value = value.replace(dictionaryKey, ' ' + dictionaryKey + ' ')
197         dictionarySplitWords = []
198         for word in value.split():
199                 dictionarySplitWords.append(word)
200         return dictionarySplitWords
201
202 def getElementNodeByKey(elementNode, key):
203         'Get the xml element by key.'
204         if key not in elementNode.attributes:
205                 return None
206         word = str(elementNode.attributes[key]).strip()
207         evaluatedLinkValue = getEvaluatedLinkValue(elementNode, word)
208         if evaluatedLinkValue.__class__.__name__ == 'ElementNode':
209                 return evaluatedLinkValue
210         print('Warning, could not get ElementNode in getElementNodeByKey in evaluate for:')
211         print(key)
212         print(evaluatedLinkValue)
213         print(elementNode)
214         return None
215
216 def getElementNodeObject(evaluatedLinkValue):
217         'Get ElementNodeObject.'
218         if evaluatedLinkValue.__class__.__name__ != 'ElementNode':
219                 print('Warning, could not get ElementNode in getElementNodeObject in evaluate for:')
220                 print(evaluatedLinkValue.__class__.__name__)
221                 print(evaluatedLinkValue)
222                 return None
223         if evaluatedLinkValue.xmlObject == None:
224                 print('Warning, evaluatedLinkValue.xmlObject is None in getElementNodeObject in evaluate for:')
225                 print(evaluatedLinkValue)
226                 return None
227         return evaluatedLinkValue.xmlObject
228
229 def getElementNodesByKey(elementNode, key):
230         'Get the xml elements by key.'
231         if key not in elementNode.attributes:
232                 return []
233         word = str(elementNode.attributes[key]).strip()
234         evaluatedLinkValue = getEvaluatedLinkValue(elementNode, word)
235         if evaluatedLinkValue.__class__.__name__ == 'ElementNode':
236                 return [evaluatedLinkValue]
237         if evaluatedLinkValue.__class__ == list:
238                 return evaluatedLinkValue
239         print('Warning, could not get ElementNodes in getElementNodesByKey in evaluate for:')
240         print(key)
241         print(evaluatedLinkValue)
242         print(elementNode)
243         return []
244
245 def getEndIndexConvertEquationValue( bracketEndIndex, evaluatorIndex, evaluators ):
246         'Get the bracket end index and convert the equation value evaluators into a string.'
247         evaluator = evaluators[evaluatorIndex]
248         if evaluator.__class__ != EvaluatorValue:
249                 return bracketEndIndex
250         if not evaluator.word.startswith('equation.'):
251                 return bracketEndIndex
252         if evaluators[ evaluatorIndex + 1 ].word != ':':
253                 return bracketEndIndex
254         valueBeginIndex = evaluatorIndex + 2
255         equationValueString = ''
256         for valueEvaluatorIndex in xrange( valueBeginIndex, len(evaluators) ):
257                 valueEvaluator = evaluators[ valueEvaluatorIndex ]
258                 if valueEvaluator.word == ',' or valueEvaluator.word == '}':
259                         if equationValueString == '':
260                                 return bracketEndIndex
261                         else:
262                                 evaluators[ valueBeginIndex ] = EvaluatorValue( equationValueString )
263                                 valueDeleteIndex = valueBeginIndex + 1
264                                 del evaluators[ valueDeleteIndex : valueEvaluatorIndex ]
265                         return bracketEndIndex - valueEvaluatorIndex + valueDeleteIndex
266                 equationValueString += valueEvaluator.word
267         return bracketEndIndex
268
269 def getEvaluatedBoolean(defaultValue, elementNode, key):
270         'Get the evaluated boolean.'
271         if elementNode == None:
272                 return defaultValue
273         if key in elementNode.attributes:
274                 return euclidean.getBooleanFromValue(getEvaluatedValueObliviously(elementNode, key))
275         return defaultValue
276
277 def getEvaluatedDictionaryByCopyKeys(copyKeys, elementNode):
278         'Get the evaluated dictionary by copyKeys.'
279         evaluatedDictionary = {}
280         for key in elementNode.attributes.keys():
281                 if key in copyKeys:
282                         evaluatedDictionary[key] = elementNode.attributes[key]
283                 else:
284                         addValueToEvaluatedDictionary(elementNode, evaluatedDictionary, key)
285         return evaluatedDictionary
286
287 def getEvaluatedDictionaryByEvaluationKeys(elementNode, evaluationKeys):
288         'Get the evaluated dictionary.'
289         evaluatedDictionary = {}
290         for key in elementNode.attributes.keys():
291                 if key in evaluationKeys:
292                         addValueToEvaluatedDictionary(elementNode, evaluatedDictionary, key)
293         return evaluatedDictionary
294
295 def getEvaluatedExpressionValue(elementNode, value):
296         'Evaluate the expression value.'
297         try:
298                 return getEvaluatedExpressionValueBySplitLine(elementNode, getEvaluatorSplitWords(value))
299         except:
300                 print('Warning, in getEvaluatedExpressionValue in evaluate could not get a value for:')
301                 print(value)
302                 traceback.print_exc(file=sys.stdout)
303                 return None
304
305 def getEvaluatedExpressionValueBySplitLine(elementNode, words):
306         'Evaluate the expression value.'
307         evaluators = []
308         for wordIndex, word in enumerate(words):
309                 nextWord = ''
310                 nextWordIndex = wordIndex + 1
311                 if nextWordIndex < len(words):
312                         nextWord = words[nextWordIndex]
313                 evaluator = getEvaluator(elementNode, evaluators, nextWord, word)
314                 if evaluator != None:
315                         evaluators.append(evaluator)
316         while getBracketsExist(evaluators):
317                 pass
318         evaluatedExpressionValueEvaluators = getEvaluatedExpressionValueEvaluators(evaluators)
319         if len( evaluatedExpressionValueEvaluators ) > 0:
320                 return evaluatedExpressionValueEvaluators[0].value
321         return None
322
323 def getEvaluatedExpressionValueEvaluators(evaluators):
324         'Evaluate the expression value from the numeric and operation evaluators.'
325         for evaluatorIndex, evaluator in enumerate(evaluators):
326                 evaluator.executeCenterOperation(evaluators, evaluatorIndex)
327         for negativeIndex in xrange(1 - len(evaluators), 0):
328                 evaluatorIndex = negativeIndex + len(evaluators)
329                 evaluators[evaluatorIndex].executeRightOperation(evaluators, evaluatorIndex)
330         executeLeftOperations(evaluators, 200)
331         for operationLevel in [80, 60, 40, 20, 15]:
332                 executePairOperations(evaluators, operationLevel)
333         executeLeftOperations(evaluators, 13)
334         executePairOperations(evaluators, 12)
335         for negativeIndex in xrange(-len(evaluators), 0):
336                 evaluatorIndex = negativeIndex + len(evaluators)
337                 evaluators[evaluatorIndex].executePairOperation(evaluators, evaluatorIndex, 10)
338         for evaluatorIndex in xrange(len(evaluators) - 1, -1, -1):
339                 evaluators[evaluatorIndex].executePairOperation(evaluators, evaluatorIndex, 0)
340         return evaluators
341
342 def getEvaluatedFloat(defaultValue, elementNode, key):
343         'Get the evaluated float.'
344         if elementNode == None:
345                 return defaultValue
346         if key in elementNode.attributes:
347                 return euclidean.getFloatFromValue(getEvaluatedValueObliviously(elementNode, key))
348         return defaultValue
349
350 def getEvaluatedInt(defaultValue, elementNode, key):
351         'Get the evaluated int.'
352         if elementNode == None:
353                 return None
354         if key in elementNode.attributes:
355                 try:
356                         return getIntFromFloatString(getEvaluatedValueObliviously(elementNode, key))
357                 except:
358                         print('Warning, could not evaluate the int.')
359                         print(key)
360                         print(elementNode.attributes[key])
361         return defaultValue
362
363 def getEvaluatedIntByKeys(defaultValue, elementNode, keys):
364         'Get the evaluated int by keys.'
365         for key in keys:
366                 defaultValue = getEvaluatedInt(defaultValue, elementNode, key)
367         return defaultValue
368
369 def getEvaluatedLinkValue(elementNode, word):
370         'Get the evaluated link value.'
371         if word == '':
372                 return ''
373         if getStartsWithCurlyEqualRoundSquare(word):
374                 return getEvaluatedExpressionValue(elementNode, word)
375         return word
376
377 def getEvaluatedString(defaultValue, elementNode, key):
378         'Get the evaluated string.'
379         if elementNode == None:
380                 return defaultValue
381         if key in elementNode.attributes:
382                 return str(getEvaluatedValueObliviously(elementNode, key))
383         return defaultValue
384
385 def getEvaluatedValue(defaultValue, elementNode, key):
386         'Get the evaluated value.'
387         if elementNode == None:
388                 return defaultValue
389         if key in elementNode.attributes:
390                 return getEvaluatedValueObliviously(elementNode, key)
391         return defaultValue
392
393 def getEvaluatedValueObliviously(elementNode, key):
394         'Get the evaluated value.'
395         value = str(elementNode.attributes[key]).strip()
396         if key == 'id' or key == 'name' or key == 'tags':
397                 return value
398         return getEvaluatedLinkValue(elementNode, value)
399
400 def getEvaluator(elementNode, evaluators, nextWord, word):
401         'Get the evaluator.'
402         if word in globalSplitDictionary:
403                 return globalSplitDictionary[word](elementNode, word)
404         firstCharacter = word[: 1]
405         if firstCharacter == "'" or firstCharacter == '"':
406                 if len(word) > 1:
407                         if firstCharacter == word[-1]:
408                                 return EvaluatorValue(word[1 : -1])
409         if firstCharacter == '$':
410                 return EvaluatorValue(word[1 :])
411         dotIndex = word.find('.')
412         functions = elementNode.getXMLProcessor().functions
413         if dotIndex > -1 and len(word) > 1:
414                 if dotIndex == 0 and word[1].isalpha():
415                         return EvaluatorAttribute(elementNode, word)
416                 if dotIndex > 0:
417                         untilDot = word[: dotIndex]
418                         if untilDot in globalModuleEvaluatorDictionary:
419                                 return globalModuleEvaluatorDictionary[untilDot](elementNode, word)
420                 if len(functions) > 0:
421                         if untilDot in functions[-1].localDictionary:
422                                 return EvaluatorLocal(elementNode, word)
423         if firstCharacter.isalpha() or firstCharacter == '_':
424                 if len(functions) > 0:
425                         if word in functions[-1].localDictionary:
426                                 return EvaluatorLocal(elementNode, word)
427                 wordElement = elementNode.getElementNodeByID(word)
428                 if wordElement != None:
429                         if wordElement.getNodeName() == 'class':
430                                 return EvaluatorClass(wordElement, word)
431                         if wordElement.getNodeName() == 'function':
432                                 return EvaluatorFunction(wordElement, word)
433                 return EvaluatorValue(word)
434         return EvaluatorNumeric(elementNode, word)
435
436 def getEvaluatorSplitWords(value):
437         'Get split words for evaluators.'
438         if value.startswith('='):
439                 value = value[len('=') :]
440         if len(value) < 1:
441                 return []
442         global globalDictionaryOperatorBegin
443         uniqueQuoteIndex = 0
444         word = ''
445         quoteString = None
446         quoteDictionary = {}
447         for characterIndex in xrange(len(value)):
448                 character = value[characterIndex]
449                 if character == '"' or character == "'":
450                         if quoteString == None:
451                                 quoteString = ''
452                         elif quoteString != None:
453                                 if character == quoteString[: 1]:
454                                         uniqueQuoteIndex = getUniqueQuoteIndex(uniqueQuoteIndex, value)
455                                         uniqueToken = getTokenByNumber(uniqueQuoteIndex)
456                                         quoteDictionary[uniqueToken] = quoteString + character
457                                         character = uniqueToken
458                                         quoteString = None
459                 if quoteString == None:
460                         word += character
461                 else:
462                         quoteString += character
463         beginSplitWords = getDictionarySplitWords(globalDictionaryOperatorBegin, word)
464         global globalSplitDictionaryOperator
465         evaluatorSplitWords = []
466         for beginSplitWord in beginSplitWords:
467                 if beginSplitWord in globalDictionaryOperatorBegin:
468                         evaluatorSplitWords.append(beginSplitWord)
469                 else:
470                         evaluatorSplitWords += getDictionarySplitWords(globalSplitDictionaryOperator, beginSplitWord)
471         for evaluatorSplitWordIndex, evaluatorSplitWord in enumerate(evaluatorSplitWords):
472                 for quoteDictionaryKey in quoteDictionary.keys():
473                         if quoteDictionaryKey in evaluatorSplitWord:
474                                 evaluatorSplitWords[evaluatorSplitWordIndex] = evaluatorSplitWord.replace(quoteDictionaryKey, quoteDictionary[quoteDictionaryKey])
475         evaluatorTransitionWords = []
476         for evaluatorSplitWord in evaluatorSplitWords:
477                 addQuoteWord(evaluatorTransitionWords, evaluatorSplitWord)
478         return evaluatorTransitionWords
479
480 def getFloatListFromBracketedString( bracketedString ):
481         'Get list from a bracketed string.'
482         if not getIsBracketed( bracketedString ):
483                 return None
484         bracketedString = bracketedString.strip().replace('[', '').replace(']', '').replace('(', '').replace(')', '')
485         if len( bracketedString ) < 1:
486                 return []
487         splitLine = bracketedString.split(',')
488         floatList = []
489         for word in splitLine:
490                 evaluatedFloat = euclidean.getFloatFromValue(word)
491                 if evaluatedFloat != None:
492                         floatList.append( evaluatedFloat )
493         return floatList
494
495 def getFloatListListsByPaths(paths):
496         'Get float lists by paths.'
497         floatListLists = []
498         for path in paths:
499                 floatListList = []
500                 for point in path:
501                         floatListList.append( point.getFloatList() )
502         return floatListLists
503
504 def getIntFromFloatString(value):
505         'Get the int from the string.'
506         floatString = str(value).strip()
507         if floatString == '':
508                 return None
509         dotIndex = floatString.find('.')
510         if dotIndex < 0:
511                 return int(value)
512         return int( round( float(floatString) ) )
513
514 def getIsBracketed(word):
515         'Determine if the word is bracketed.'
516         if len(word) < 2:
517                 return False
518         firstCharacter = word[0]
519         lastCharacter = word[-1]
520         if firstCharacter == '(' and lastCharacter == ')':
521                 return True
522         return firstCharacter == '[' and lastCharacter == ']'
523
524 def getIsQuoted(word):
525         'Determine if the word is quoted.'
526         if len(word) < 2:
527                 return False
528         firstCharacter = word[0]
529         lastCharacter = word[-1]
530         if firstCharacter == '"' and lastCharacter == '"':
531                 return True
532         return firstCharacter == "'" and lastCharacter == "'"
533
534 def getKeys(repository):
535         'Get keys for repository.'
536         repositoryClass = repository.__class__
537         if repositoryClass == list or repositoryClass == tuple:
538                 return range(len(repository))
539         if repositoryClass == dict:
540                 return repository.keys()
541         return None
542
543 def getLocalAttributeValueString(key, valueString):
544         'Get the local attribute value string with augmented assignment.'
545         augmentedStatements = '+= -= *= /= %= **='.split()
546         for augmentedStatement in augmentedStatements:
547                 if valueString.startswith(augmentedStatement):
548                         return key + augmentedStatement[: -1] + valueString[len(augmentedStatement) :]
549         return valueString
550
551 def getMatchingPlugins(elementNode, namePathDictionary):
552         'Get the plugins whose names are in the attribute dictionary.'
553         matchingPlugins = []
554         namePathDictionaryCopy = namePathDictionary.copy()
555         for key in elementNode.attributes:
556                 dotIndex = key.find('.')
557                 if dotIndex > - 1:
558                         keyUntilDot = key[: dotIndex]
559                         if keyUntilDot in namePathDictionaryCopy:
560                                 pluginModule = archive.getModuleWithPath( namePathDictionaryCopy[ keyUntilDot ] )
561                                 del namePathDictionaryCopy[ keyUntilDot ]
562                                 if pluginModule != None:
563                                         matchingPlugins.append( pluginModule )
564         return matchingPlugins
565
566 def getNextChildIndex(elementNode):
567         'Get the next childNode index.'
568         for childNodeIndex, childNode in enumerate( elementNode.parentNode.childNodes ):
569                 if childNode == elementNode:
570                         return childNodeIndex + 1
571         return len( elementNode.parentNode.childNodes )
572
573 def getPathByKey(defaultPath, elementNode, key):
574         'Get path from prefix and xml element.'
575         if key not in elementNode.attributes:
576                 return defaultPath
577         word = str(elementNode.attributes[key]).strip()
578         evaluatedLinkValue = getEvaluatedLinkValue(elementNode, word)
579         if evaluatedLinkValue.__class__ == list:
580                 return getPathByList(evaluatedLinkValue)
581         elementNodeObject = getElementNodeObject(evaluatedLinkValue)
582         if elementNodeObject == None:
583                 return defaultPath
584         return elementNodeObject.getPaths()[0]
585
586 def getPathByList(vertexList):
587         'Get the paths by list.'
588         if len(vertexList) < 1:
589                 return Vector3()
590         if vertexList[0].__class__ != list:
591                 vertexList = [vertexList]
592         path = []
593         for floatList in vertexList:
594                 vector3 = getVector3ByFloatList(floatList, Vector3())
595                 path.append(vector3)
596         return path
597
598 def getPathByPrefix(elementNode, path, prefix):
599         'Get path from prefix and xml element.'
600         if len(path) < 2:
601                 print('Warning, bug, path is too small in evaluate in setPathByPrefix.')
602                 return
603         pathByKey = getPathByKey([], elementNode, getCapitalizedSuffixKey(prefix, 'path'))
604         if len( pathByKey ) < len(path):
605                 for pointIndex in xrange( len( pathByKey ) ):
606                         path[pointIndex] = pathByKey[pointIndex]
607         else:
608                 path = pathByKey
609         path[0] = getVector3ByPrefix(path[0], elementNode, getCapitalizedSuffixKey(prefix, 'pathStart'))
610         path[-1] = getVector3ByPrefix(path[-1], elementNode, getCapitalizedSuffixKey(prefix, 'pathEnd'))
611         return path
612
613 def getPathsByKey(defaultPaths, elementNode, key):
614         'Get paths by key.'
615         if key not in elementNode.attributes:
616                 return defaultPaths
617         word = str(elementNode.attributes[key]).strip()
618         evaluatedLinkValue = getEvaluatedLinkValue(elementNode, word)
619         if evaluatedLinkValue.__class__ == dict or evaluatedLinkValue.__class__ == list:
620                 convertToPaths(evaluatedLinkValue)
621                 return getPathsByLists(evaluatedLinkValue)
622         elementNodeObject = getElementNodeObject(evaluatedLinkValue)
623         if elementNodeObject == None:
624                 return defaultPaths
625         return elementNodeObject.getPaths()
626
627 def getPathsByLists(vertexLists):
628         'Get paths by lists.'
629         vector3Lists = getVector3ListsRecursively(vertexLists)
630         paths = []
631         addToPathsRecursively(paths, vector3Lists)
632         return paths
633
634 def getRadiusArealizedBasedOnAreaRadius(elementNode, radius, sides):
635         'Get the areal radius from the radius, number of sides and cascade radiusAreal.'
636         if elementNode.getCascadeBoolean(False, 'radiusAreal'):
637                 return radius
638         return radius * euclidean.getRadiusArealizedMultiplier(sides)
639
640 def getSidesBasedOnPrecision(elementNode, radius):
641         'Get the number of polygon sides.'
642         return int(math.ceil(math.sqrt(0.5 * radius / setting.getPrecision(elementNode)) * math.pi))
643
644 def getSidesMinimumThreeBasedOnPrecision(elementNode, radius):
645         'Get the number of polygon sides, with a minimum of three.'
646         return max(getSidesBasedOnPrecision(elementNode, radius), 3)
647
648 def getSidesMinimumThreeBasedOnPrecisionSides(elementNode, radius):
649         'Get the number of polygon sides, with a minimum of three.'
650         sides = getSidesMinimumThreeBasedOnPrecision(elementNode, radius)
651         return getEvaluatedFloat(sides, elementNode, 'sides')
652
653 def getSplitDictionary():
654         'Get split dictionary.'
655         global globalSplitDictionaryOperator
656         splitDictionary = globalSplitDictionaryOperator.copy()
657         global globalDictionaryOperatorBegin
658         splitDictionary.update( globalDictionaryOperatorBegin )
659         splitDictionary['and'] = EvaluatorAnd
660         splitDictionary['false'] = EvaluatorFalse
661         splitDictionary['False'] = EvaluatorFalse
662         splitDictionary['or'] = EvaluatorOr
663         splitDictionary['not'] = EvaluatorNot
664         splitDictionary['true'] = EvaluatorTrue
665         splitDictionary['True'] = EvaluatorTrue
666         splitDictionary['none'] = EvaluatorNone
667         splitDictionary['None'] = EvaluatorNone
668         return splitDictionary
669
670 def getStartsWithCurlyEqualRoundSquare(word):
671         'Determine if the word starts with round or square brackets.'
672         return word.startswith('{') or word.startswith('=') or word.startswith('(') or word.startswith('[')
673
674 def getTokenByNumber(number):
675         'Get token by number.'
676         return '_%s_' % number
677
678 def getTransformedPathByKey(defaultTransformedPath, elementNode, key):
679         'Get transformed path from prefix and xml element.'
680         if key not in elementNode.attributes:
681                 return defaultTransformedPath
682         value = elementNode.attributes[key]
683         if value.__class__ == list:
684                 return value
685         word = str(value).strip()
686         evaluatedLinkValue = getEvaluatedLinkValue(elementNode, word)
687         if evaluatedLinkValue.__class__ == list:
688                 return getPathByList(evaluatedLinkValue)
689         elementNodeObject = getElementNodeObject(evaluatedLinkValueClass)
690         if elementNodeObject == None:
691                 return defaultTransformedPath
692         return elementNodeObject.getTransformedPaths()[0]
693
694 def getTransformedPathByPrefix(elementNode, path, prefix):
695         'Get path from prefix and xml element.'
696         if len(path) < 2:
697                 print('Warning, bug, path is too small in evaluate in setPathByPrefix.')
698                 return
699         pathByKey = getTransformedPathByKey([], elementNode, getCapitalizedSuffixKey(prefix, 'path'))
700         if len( pathByKey ) < len(path):
701                 for pointIndex in xrange( len( pathByKey ) ):
702                         path[pointIndex] = pathByKey[pointIndex]
703         else:
704                 path = pathByKey
705         path[0] = getVector3ByPrefix(path[0], elementNode, getCapitalizedSuffixKey(prefix, 'pathStart'))
706         path[-1] = getVector3ByPrefix(path[-1], elementNode, getCapitalizedSuffixKey(prefix, 'pathEnd'))
707         return path
708
709 def getTransformedPathsByKey(defaultTransformedPaths, elementNode, key):
710         'Get transformed paths by key.'
711         if key not in elementNode.attributes:
712                 return defaultTransformedPaths
713         value = elementNode.attributes[key]
714         if value.__class__ == list:
715                 return getPathsByLists(value)
716         word = str(value).strip()
717         evaluatedLinkValue = getEvaluatedLinkValue(elementNode, word)
718         if evaluatedLinkValue.__class__ == dict or evaluatedLinkValue.__class__ == list:
719                 convertToTransformedPaths(evaluatedLinkValue)
720                 return getPathsByLists(evaluatedLinkValue)
721         elementNodeObject = getElementNodeObject(evaluatedLinkValue)
722         if elementNodeObject == None:
723                 return defaultTransformedPaths
724         return elementNodeObject.getTransformedPaths()
725
726 def getUniqueQuoteIndex( uniqueQuoteIndex, word ):
727         'Get uniqueQuoteIndex.'
728         uniqueQuoteIndex += 1
729         while getTokenByNumber(uniqueQuoteIndex) in word:
730                 uniqueQuoteIndex += 1
731         return uniqueQuoteIndex
732
733 def getUniqueToken(word):
734         'Get unique token.'
735         uniqueString = '@#!'
736         for character in uniqueString:
737                 if character not in word:
738                         return character
739         uniqueNumber = 0
740         while True:
741                 for character in uniqueString:
742                         uniqueToken = character + str(uniqueNumber)
743                         if uniqueToken not in word:
744                                 return uniqueToken
745                         uniqueNumber += 1
746
747 def getVector3ByDictionary( dictionary, vector3 ):
748         'Get vector3 by dictionary.'
749         if 'x' in dictionary:
750                 vector3 = getVector3IfNone(vector3)
751                 vector3.x = euclidean.getFloatFromValue(dictionary['x'])
752         if 'y' in dictionary:
753                 vector3 = getVector3IfNone(vector3)
754                 vector3.y = euclidean.getFloatFromValue(dictionary['y'])
755         if 'z' in dictionary:
756                 vector3 = getVector3IfNone(vector3)
757                 vector3.z = euclidean.getFloatFromValue( dictionary['z'] )
758         return vector3
759
760 def getVector3ByDictionaryListValue(value, vector3):
761         'Get vector3 by dictionary, list or value.'
762         if value.__class__ == Vector3 or value.__class__.__name__ == 'Vector3Index':
763                 return value
764         if value.__class__ == dict:
765                 return getVector3ByDictionary(value, vector3)
766         if value.__class__ == list:
767                 return getVector3ByFloatList(value, vector3)
768         floatFromValue = euclidean.getFloatFromValue(value)
769         if floatFromValue ==  None:
770                 return vector3
771         vector3.setToXYZ(floatFromValue, floatFromValue, floatFromValue)
772         return vector3
773
774 def getVector3ByFloatList(floatList, vector3):
775         'Get vector3 by float list.'
776         if len(floatList) > 0:
777                 vector3 = getVector3IfNone(vector3)
778                 vector3.x = euclidean.getFloatFromValue(floatList[0])
779         if len(floatList) > 1:
780                 vector3 = getVector3IfNone(vector3)
781                 vector3.y = euclidean.getFloatFromValue(floatList[1])
782         if len(floatList) > 2:
783                 vector3 = getVector3IfNone(vector3)
784                 vector3.z = euclidean.getFloatFromValue(floatList[2])
785         return vector3
786
787 def getVector3ByMultiplierPrefix( elementNode, multiplier, prefix, vector3 ):
788         'Get vector3 from multiplier, prefix and xml element.'
789         if multiplier == 0.0:
790                 return vector3
791         oldMultipliedValueVector3 = vector3 * multiplier
792         vector3ByPrefix = getVector3ByPrefix(oldMultipliedValueVector3.copy(), elementNode, prefix)
793         if vector3ByPrefix == oldMultipliedValueVector3:
794                 return vector3
795         return vector3ByPrefix / multiplier
796
797 def getVector3ByMultiplierPrefixes( elementNode, multiplier, prefixes, vector3 ):
798         'Get vector3 from multiplier, prefixes and xml element.'
799         for prefix in prefixes:
800                 vector3 = getVector3ByMultiplierPrefix( elementNode, multiplier, prefix, vector3 )
801         return vector3
802
803 def getVector3ByPrefix(defaultVector3, elementNode, prefix):
804         'Get vector3 from prefix and xml element.'
805         value = getEvaluatedValue(None, elementNode, prefix)
806         if value != None:
807                 defaultVector3 = getVector3ByDictionaryListValue(value, defaultVector3)
808         prefix = archive.getUntilDot(prefix)
809         x = getEvaluatedFloat(None, elementNode, prefix + '.x')
810         if x != None:
811                 defaultVector3 = getVector3IfNone(defaultVector3)
812                 defaultVector3.x = x
813         y = getEvaluatedFloat(None, elementNode, prefix + '.y')
814         if y != None:
815                 defaultVector3 = getVector3IfNone(defaultVector3)
816                 defaultVector3.y = y
817         z = getEvaluatedFloat(None, elementNode, prefix + '.z')
818         if z != None:
819                 defaultVector3 = getVector3IfNone(defaultVector3)
820                 defaultVector3.z = z
821         return defaultVector3
822
823 def getVector3ByPrefixes( elementNode, prefixes, vector3 ):
824         'Get vector3 from prefixes and xml element.'
825         for prefix in prefixes:
826                 vector3 = getVector3ByPrefix(vector3, elementNode, prefix)
827         return vector3
828
829 def getVector3FromElementNode(elementNode):
830         'Get vector3 from xml element.'
831         vector3 = Vector3(
832                 getEvaluatedFloat(0.0, elementNode, 'x'),
833                 getEvaluatedFloat(0.0, elementNode, 'y'),
834                 getEvaluatedFloat(0.0, elementNode, 'z'))
835         return getVector3ByPrefix(vector3, elementNode, 'cartesian')
836
837 def getVector3IfNone(vector3):
838         'Get new vector3 if the original vector3 is none.'
839         if vector3 == None:
840                 return Vector3()
841         return vector3
842
843 def getVector3ListsRecursively(floatLists):
844         'Get vector3 lists recursively.'
845         if len(floatLists) < 1:
846                 return Vector3()
847         firstElement = floatLists[0]
848         if firstElement.__class__ == Vector3:
849                 return floatLists
850         if firstElement.__class__ != list:
851                 return getVector3ByFloatList(floatLists, Vector3())
852         vector3ListsRecursively = []
853         for floatList in floatLists:
854                 vector3ListsRecursively.append(getVector3ListsRecursively(floatList))
855         return vector3ListsRecursively
856
857 def getVisibleObjects(archivableObjects):
858         'Get the visible objects.'
859         visibleObjects = []
860         for archivableObject in archivableObjects:
861                 if archivableObject.getVisible():
862                         visibleObjects.append(archivableObject)
863         return visibleObjects
864
865 def processArchivable(archivableClass, elementNode):
866         'Get any new elements and process the archivable.'
867         if elementNode == None:
868                 return
869         elementNode.xmlObject = archivableClass()
870         elementNode.xmlObject.setToElementNode(elementNode)
871         elementNode.getXMLProcessor().processChildNodes(elementNode)
872
873 def processCondition(elementNode):
874         'Process the xml element condition.'
875         xmlProcessor = elementNode.getXMLProcessor()
876         if elementNode.xmlObject == None:
877                 elementNode.xmlObject = ModuleElementNode(elementNode)
878         if elementNode.xmlObject.conditionSplitWords == None:
879                 return
880         if len(xmlProcessor.functions ) < 1:
881                 print('Warning, the (in) element is not in a function in processCondition in evaluate for:')
882                 print(elementNode)
883                 return
884         if int(getEvaluatedExpressionValueBySplitLine(elementNode, elementNode.xmlObject.conditionSplitWords)) > 0:
885                 xmlProcessor.functions[-1].processChildNodes(elementNode)
886         else:
887                 elementNode.xmlObject.processElse(elementNode)
888
889 def removeIdentifiersFromDictionary(dictionary):
890         'Remove the identifier elements from a dictionary.'
891         euclidean.removeElementsFromDictionary(dictionary, ['id', 'name', 'tags'])
892         return dictionary
893
894 def setAttributesByArguments(argumentNames, arguments, elementNode):
895         'Set the attribute dictionary to the arguments.'
896         for argumentIndex, argument in enumerate(arguments):
897                 elementNode.attributes[argumentNames[argumentIndex]] = argument
898
899 def setFunctionLocalDictionary(arguments, function):
900         'Evaluate the function statement and delete the evaluators.'
901         function.localDictionary = {'_arguments' : arguments}
902         if len(arguments) > 0:
903                 firstArgument = arguments[0]
904                 if firstArgument.__class__ == dict:
905                         function.localDictionary = firstArgument
906                         return
907         if 'parameters' not in function.elementNode.attributes:
908                 return
909         parameters = function.elementNode.attributes['parameters'].strip()
910         if parameters == '':
911                 return
912         parameterWords = parameters.split(',')
913         for parameterWordIndex, parameterWord in enumerate(parameterWords):
914                 strippedWord = parameterWord.strip()
915                 keyValue = KeyValue().getByEqual(strippedWord)
916                 if parameterWordIndex < len(arguments):
917                         function.localDictionary[keyValue.key] = arguments[parameterWordIndex]
918                 else:
919                         strippedValue = keyValue.value
920                         if strippedValue == None:
921                                 print('Warning there is no default parameter in getParameterValue for:')
922                                 print(strippedWord)
923                                 print(parameterWords)
924                                 print(arguments)
925                                 print(function.elementNode.attributes)
926                         else:
927                                 strippedValue = strippedValue.strip()
928                         function.localDictionary[keyValue.key.strip()] = strippedValue
929         if len(arguments) > len(parameterWords):
930                 print('Warning there are too many initializeFunction parameters for:')
931                 print(function.elementNode.attributes)
932                 print(parameterWords)
933                 print(arguments)
934
935 def setLocalAttribute(elementNode):
936         'Set the local attribute if any.'
937         if elementNode.xmlObject != None:
938                 return
939         for key in elementNode.attributes:
940                 if key[: 1].isalpha():
941                         value = getEvaluatorSplitWords(getLocalAttributeValueString(key, elementNode.attributes[key].strip()))
942                         elementNode.xmlObject = KeyValue(key, value)
943                         return
944         elementNode.xmlObject = KeyValue()
945
946
947 class BaseFunction:
948         'Class to get equation results.'
949         def __init__(self, elementNode):
950                 'Initialize.'
951                 self.elementNode = elementNode
952                 self.localDictionary = {}
953                 self.xmlProcessor = elementNode.getXMLProcessor()
954
955         def __repr__(self):
956                 'Get the string representation of this Class.'
957                 return str(self.__dict__)
958
959         def getReturnValue(self):
960                 'Get return value.'
961                 self.getReturnValueWithoutDeletion()
962                 del self.xmlProcessor.functions[-1]
963                 return self.returnValue
964
965         def processChildNodes(self, elementNode):
966                 'Process childNodes if shouldReturn is false.'
967                 for childNode in elementNode.childNodes:
968                         if self.shouldReturn:
969                                 return
970                         self.xmlProcessor.processElementNode(childNode)
971
972
973 class ClassFunction(BaseFunction):
974         'Class to get class results.'
975         def getReturnValueByArguments(self, *arguments):
976                 'Get return value by arguments.'
977                 setFunctionLocalDictionary(arguments, self)
978                 return self.getReturnValue()
979
980         def getReturnValueWithoutDeletion(self):
981                 'Get return value without deleting last function.'
982                 self.returnValue = None
983                 self.shouldReturn = False
984                 self.xmlProcessor.functions.append(self)
985                 self.processChildNodes(self.elementNode)
986                 return self.returnValue
987
988
989 class ClassObject:
990         'Class to hold class attributes and functions.'
991         def __init__(self, elementNode):
992                 'Initialize.'
993                 self.functionDictionary = elementNode.xmlObject.functionDictionary
994                 self.selfDictionary = {}
995                 for variable in elementNode.xmlObject.variables:
996                         self.selfDictionary[variable] = None
997
998         def __repr__(self):
999                 'Get the string representation of this Class.'
1000                 return str(self.__dict__)
1001
1002         def _getAccessibleAttribute(self, attributeName):
1003                 'Get the accessible attribute.'
1004                 if attributeName in self.selfDictionary:
1005                         return self.selfDictionary[attributeName]
1006                 if attributeName in self.functionDictionary:
1007                         function = self.functionDictionary[attributeName]
1008                         function.classObject = self
1009                         return function.getReturnValueByArguments
1010                 return None
1011
1012         def _setAccessibleAttribute(self, attributeName, value):
1013                 'Set the accessible attribute.'
1014                 if attributeName in self.selfDictionary:
1015                         self.selfDictionary[attributeName] = value
1016
1017
1018 class EmptyObject:
1019         'An empty object.'
1020         def __init__(self):
1021                 'Do nothing.'
1022                 pass
1023
1024
1025 class Evaluator:
1026         'Base evaluator class.'
1027         def __init__(self, elementNode, word):
1028                 'Set value to none.'
1029                 self.value = None
1030                 self.word = word
1031
1032         def __repr__(self):
1033                 'Get the string representation of this Class.'
1034                 return str(self.__dict__)
1035
1036         def executeBracket( self, bracketBeginIndex, bracketEndIndex, evaluators ):
1037                 'Execute the bracket.'
1038                 pass
1039
1040         def executeCenterOperation(self, evaluators, evaluatorIndex):
1041                 'Execute operator which acts on the center.'
1042                 pass
1043
1044         def executeDictionary(self, dictionary, evaluators, keys, evaluatorIndex, nextEvaluator):
1045                 'Execute the dictionary.'
1046                 del evaluators[evaluatorIndex]
1047                 enumeratorKeys = euclidean.getEnumeratorKeys(dictionary, keys)
1048                 if enumeratorKeys.__class__ == list:
1049                         nextEvaluator.value = []
1050                         for enumeratorKey in enumeratorKeys:
1051                                 if enumeratorKey in dictionary:
1052                                         nextEvaluator.value.append(dictionary[enumeratorKey])
1053                                 else:
1054                                         print('Warning, key in executeKey in Evaluator in evaluate is not in for:')
1055                                         print(enumeratorKey)
1056                                         print(dictionary)
1057                         return
1058                 if enumeratorKeys in dictionary:
1059                         nextEvaluator.value = dictionary[enumeratorKeys]
1060                 else:
1061                         print('Warning, key in executeKey in Evaluator in evaluate is not in for:')
1062                         print(enumeratorKeys)
1063                         print(dictionary)
1064
1065         def executeFunction(self, evaluators, evaluatorIndex, nextEvaluator):
1066                 'Execute the function.'
1067                 pass
1068
1069         def executeKey(self, evaluators, keys, evaluatorIndex, nextEvaluator):
1070                 'Execute the key index.'
1071                 if self.value.__class__ == str:
1072                         self.executeString(evaluators, keys, evaluatorIndex, nextEvaluator)
1073                         return
1074                 if self.value.__class__ == list:
1075                         self.executeList(evaluators, keys, evaluatorIndex, nextEvaluator)
1076                         return
1077                 if self.value.__class__ == dict:
1078                         self.executeDictionary(self.value, evaluators, keys, evaluatorIndex, nextEvaluator)
1079                         return
1080                 getAccessibleDictionaryFunction = getattr(self.value, '_getAccessibleDictionary', None)
1081                 if getAccessibleDictionaryFunction != None:
1082                         self.executeDictionary(getAccessibleDictionaryFunction(), evaluators, keys, evaluatorIndex, nextEvaluator)
1083                         return
1084                 if self.value.__class__.__name__ != 'ElementNode':
1085                         return
1086                 del evaluators[evaluatorIndex]
1087                 enumeratorKeys = euclidean.getEnumeratorKeys(self.value.attributes, keys)
1088                 if enumeratorKeys.__class__ == list:
1089                         nextEvaluator.value = []
1090                         for enumeratorKey in enumeratorKeys:
1091                                 if enumeratorKey in self.value.attributes:
1092                                         nextEvaluator.value.append(getEvaluatedExpressionValue(self.value, self.value.attributes[enumeratorKey]))
1093                                 else:
1094                                         print('Warning, key in executeKey in Evaluator in evaluate is not in for:')
1095                                         print(enumeratorKey)
1096                                         print(self.value.attributes)
1097                         return
1098                 if enumeratorKeys in self.value.attributes:
1099                         nextEvaluator.value = getEvaluatedExpressionValue(self.value, self.value.attributes[enumeratorKeys])
1100                 else:
1101                         print('Warning, key in executeKey in Evaluator in evaluate is not in for:')
1102                         print(enumeratorKeys)
1103                         print(self.value.attributes)
1104
1105         def executeLeftOperation(self, evaluators, evaluatorIndex, operationLevel):
1106                 'Execute operator which acts from the left.'
1107                 pass
1108
1109         def executeList(self, evaluators, keys, evaluatorIndex, nextEvaluator):
1110                 'Execute the key index.'
1111                 del evaluators[evaluatorIndex]
1112                 enumeratorKeys = euclidean.getEnumeratorKeys(self.value, keys)
1113                 if enumeratorKeys.__class__ == list:
1114                         nextEvaluator.value = []
1115                         for enumeratorKey in enumeratorKeys:
1116                                 intKey = euclidean.getIntFromValue(enumeratorKey)
1117                                 if self.getIsInRange(intKey):
1118                                         nextEvaluator.value.append(self.value[intKey])
1119                                 else:
1120                                         print('Warning, key in executeList in Evaluator in evaluate is not in for:')
1121                                         print(enumeratorKey)
1122                                         print(self.value)
1123                         return
1124                 intKey = euclidean.getIntFromValue(enumeratorKeys)
1125                 if self.getIsInRange(intKey):
1126                         nextEvaluator.value = self.value[intKey]
1127                 else:
1128                         print('Warning, key in executeList in Evaluator in evaluate is not in for:')
1129                         print(enumeratorKeys)
1130                         print(self.value)
1131
1132         def executePairOperation(self, evaluators, evaluatorIndex, operationLevel):
1133                 'Operate on two evaluators.'
1134                 pass
1135
1136         def executeRightOperation( self, evaluators, evaluatorIndex ):
1137                 'Execute operator which acts from the right.'
1138                 pass
1139
1140         def executeString(self, evaluators, keys, evaluatorIndex, nextEvaluator):
1141                 'Execute the string.'
1142                 del evaluators[evaluatorIndex]
1143                 enumeratorKeys = euclidean.getEnumeratorKeys(self.value, keys)
1144                 if enumeratorKeys.__class__ == list:
1145                         nextEvaluator.value = ''
1146                         for enumeratorKey in enumeratorKeys:
1147                                 intKey = euclidean.getIntFromValue(enumeratorKey)
1148                                 if self.getIsInRange(intKey):
1149                                         nextEvaluator.value += self.value[intKey]
1150                                 else:
1151                                         print('Warning, key in executeString in Evaluator in evaluate is not in for:')
1152                                         print(enumeratorKey)
1153                                         print(self.value)
1154                         return
1155                 intKey = euclidean.getIntFromValue(enumeratorKeys)
1156                 if self.getIsInRange(intKey):
1157                         nextEvaluator.value = self.value[intKey]
1158                 else:
1159                         print('Warning, key in executeString in Evaluator in evaluate is not in for:')
1160                         print(enumeratorKeys)
1161                         print(self.value)
1162
1163         def getIsInRange(self, keyIndex):
1164                 'Determine if the keyIndex is in range.'
1165                 if keyIndex == None:
1166                         return False
1167                 return keyIndex >= -len(self.value) and keyIndex < len(self.value)
1168
1169
1170 class EvaluatorAddition(Evaluator):
1171         'Class to add two evaluators.'
1172         def executePair( self, evaluators, evaluatorIndex ):
1173                 'Add two evaluators.'
1174                 leftIndex = evaluatorIndex - 1
1175                 rightIndex = evaluatorIndex + 1
1176                 if leftIndex < 0:
1177                         print('Warning, no leftKey in executePair in EvaluatorAddition for:')
1178                         print(evaluators)
1179                         print(evaluatorIndex)
1180                         print(self)
1181                         del evaluators[evaluatorIndex]
1182                         return
1183                 if rightIndex >= len(evaluators):
1184                         print('Warning, no rightKey in executePair in EvaluatorAddition for:')
1185                         print(evaluators)
1186                         print(evaluatorIndex)
1187                         print(self)
1188                         del evaluators[evaluatorIndex]
1189                         return
1190                 rightValue = evaluators[rightIndex].value
1191                 evaluators[leftIndex].value = self.getOperationValue(evaluators[leftIndex].value, evaluators[rightIndex].value)
1192                 del evaluators[ evaluatorIndex : evaluatorIndex + 2 ]
1193
1194         def executePairOperation(self, evaluators, evaluatorIndex, operationLevel):
1195                 'Operate on two evaluators.'
1196                 if operationLevel == 20:
1197                         self.executePair(evaluators, evaluatorIndex)
1198
1199         def getEvaluatedValues(self, enumerable, keys, value):
1200                 'Get evaluatedValues.'
1201                 if enumerable.__class__ == dict:
1202                         evaluatedValues = {}
1203                         for key in keys:
1204                                 evaluatedValues[key] = self.getOperationValue(value, enumerable[key])
1205                         return evaluatedValues
1206                 evaluatedValues = []
1207                 for key in keys:
1208                         evaluatedValues.append(self.getOperationValue(value, enumerable[key]))
1209                 return evaluatedValues
1210
1211         def getOperationValue(self, leftValue, rightValue):
1212                 'Get operation value.'
1213                 leftKeys = getKeys(leftValue)
1214                 rightKeys = getKeys(rightValue)
1215                 if leftKeys == None and rightKeys == None:
1216                         return self.getValueFromValuePair(leftValue, rightValue)
1217                 if leftKeys == None:
1218                         return self.getEvaluatedValues(rightValue, rightKeys, leftValue)
1219                 if rightKeys == None:
1220                         return self.getEvaluatedValues(leftValue, leftKeys, rightValue)
1221                 leftKeys.sort(reverse=True)
1222                 rightKeys.sort(reverse=True)
1223                 if leftKeys != rightKeys:
1224                         print('Warning, the leftKeys are different from the rightKeys in getOperationValue in EvaluatorAddition for:')
1225                         print('leftValue')
1226                         print(leftValue)
1227                         print(leftKeys)
1228                         print('rightValue')
1229                         print(rightValue)
1230                         print(rightKeys)
1231                         print(self)
1232                         return None
1233                 if leftValue.__class__ == dict or rightValue.__class__ == dict:
1234                         evaluatedValues = {}
1235                         for leftKey in leftKeys:
1236                                 evaluatedValues[leftKey] = self.getOperationValue(leftValue[leftKey], rightValue[leftKey])
1237                         return evaluatedValues
1238                 evaluatedValues = []
1239                 for leftKey in leftKeys:
1240                         evaluatedValues.append(self.getOperationValue(leftValue[leftKey], rightValue[leftKey]))
1241                 return evaluatedValues
1242
1243         def getValueFromValuePair(self, leftValue, rightValue):
1244                 'Add two values.'
1245                 return leftValue + rightValue
1246
1247
1248 class EvaluatorEqual(EvaluatorAddition):
1249         'Class to compare two evaluators.'
1250         def executePairOperation(self, evaluators, evaluatorIndex, operationLevel):
1251                 'Operate on two evaluators.'
1252                 if operationLevel == 15:
1253                         self.executePair(evaluators, evaluatorIndex)
1254
1255         def getBooleanFromValuePair(self, leftValue, rightValue):
1256                 'Compare two values.'
1257                 return leftValue == rightValue
1258
1259         def getValueFromValuePair(self, leftValue, rightValue):
1260                 'Get value from comparison.'
1261                 return self.getBooleanFromValuePair(leftValue, rightValue)
1262
1263
1264 class EvaluatorSubtraction(EvaluatorAddition):
1265         'Class to subtract two evaluators.'
1266         def executeLeft( self, evaluators, evaluatorIndex ):
1267                 'Minus the value to the right.'
1268                 leftIndex = evaluatorIndex - 1
1269                 rightIndex = evaluatorIndex + 1
1270                 leftValue = None
1271                 if leftIndex >= 0:
1272                         leftValue = evaluators[leftIndex].value
1273                 if leftValue != None:
1274                         return
1275                 rightValue = evaluators[rightIndex].value
1276                 if rightValue == None:
1277                         print('Warning, can not minus.')
1278                         print(evaluators[rightIndex].word)
1279                 else:
1280                         evaluators[rightIndex].value = self.getNegativeValue(rightValue)
1281                 del evaluators[evaluatorIndex]
1282
1283         def executeLeftOperation(self, evaluators, evaluatorIndex, operationLevel):
1284                 'Minus the value to the right.'
1285                 if operationLevel == 200:
1286                         self.executeLeft(evaluators, evaluatorIndex)
1287
1288         def getNegativeValue( self, value ):
1289                 'Get the negative value.'
1290                 keys = getKeys(value)
1291                 if keys == None:
1292                         return self.getValueFromSingleValue(value)
1293                 for key in keys:
1294                         value[key] = self.getNegativeValue(value[key])
1295                 return value
1296
1297         def getValueFromSingleValue( self, value ):
1298                 'Minus value.'
1299                 return -value
1300
1301         def getValueFromValuePair(self, leftValue, rightValue):
1302                 'Subtract two values.'
1303                 return leftValue - rightValue
1304
1305
1306 class EvaluatorAnd(EvaluatorAddition):
1307         'Class to compare two evaluators.'
1308         def executePairOperation(self, evaluators, evaluatorIndex, operationLevel):
1309                 'Operate on two evaluators.'
1310                 if operationLevel == 12:
1311                         self.executePair(evaluators, evaluatorIndex)
1312
1313         def getBooleanFromValuePair(self, leftValue, rightValue):
1314                 'And two values.'
1315                 return leftValue and rightValue
1316
1317         def getValueFromValuePair(self, leftValue, rightValue):
1318                 'Get value from comparison.'
1319                 return self.getBooleanFromValuePair(leftValue, rightValue)
1320
1321
1322 class EvaluatorAttribute(Evaluator):
1323         'Class to handle an attribute.'
1324         def executeFunction(self, evaluators, evaluatorIndex, nextEvaluator):
1325                 'Execute the function.'
1326                 executeNextEvaluatorArguments(self, evaluators, evaluatorIndex, nextEvaluator)
1327
1328         def executeRightOperation( self, evaluators, evaluatorIndex ):
1329                 'Execute operator which acts from the right.'
1330                 attributeName = self.word[1 :]
1331                 previousIndex = evaluatorIndex - 1
1332                 previousEvaluator = evaluators[previousIndex]
1333                 if previousEvaluator.value.__class__ == dict:
1334                         from fabmetheus_utilities.geometry.geometry_utilities.evaluate_enumerables import dictionary_attribute
1335                         self.value = dictionary_attribute._getAccessibleAttribute(attributeName, previousEvaluator.value)
1336                 elif previousEvaluator.value.__class__ == list:
1337                         from fabmetheus_utilities.geometry.geometry_utilities.evaluate_enumerables import list_attribute
1338                         self.value = list_attribute._getAccessibleAttribute(attributeName, previousEvaluator.value)
1339                 elif previousEvaluator.value.__class__ == str:
1340                         from fabmetheus_utilities.geometry.geometry_utilities.evaluate_enumerables import string_attribute
1341                         self.value = string_attribute._getAccessibleAttribute(attributeName, previousEvaluator.value)
1342                 else:
1343                         attributeKeywords = attributeName.split('.')
1344                         self.value = previousEvaluator.value
1345                         for attributeKeyword in attributeKeywords:
1346                                 self.value = getattr(self.value, '_getAccessibleAttribute', None)(attributeKeyword)
1347                 if self.value == None:
1348                         print('Warning, EvaluatorAttribute in evaluate can not get a getAccessibleAttributeFunction for:')
1349                         print(attributeName)
1350                         print(previousEvaluator.value)
1351                         print(self)
1352                         return
1353                 del evaluators[previousIndex]
1354
1355
1356 class EvaluatorBracketCurly(Evaluator):
1357         'Class to evaluate a string.'
1358         def executeBracket(self, bracketBeginIndex, bracketEndIndex, evaluators):
1359                 'Execute the bracket.'
1360                 for evaluatorIndex in xrange(bracketEndIndex - 3, bracketBeginIndex, - 1):
1361                         bracketEndIndex = getEndIndexConvertEquationValue(bracketEndIndex, evaluatorIndex, evaluators)
1362                 evaluatedExpressionValueEvaluators = getBracketEvaluators(bracketBeginIndex, bracketEndIndex, evaluators)
1363                 self.value = {}
1364                 for evaluatedExpressionValueEvaluator in evaluatedExpressionValueEvaluators:
1365                         keyValue = evaluatedExpressionValueEvaluator.value
1366                         self.value[keyValue.key] = keyValue.value
1367                 del evaluators[bracketBeginIndex + 1: bracketEndIndex + 1]
1368
1369
1370 class EvaluatorBracketRound(Evaluator):
1371         'Class to evaluate a string.'
1372         def __init__(self, elementNode, word):
1373                 'Set value to none.'
1374                 self.arguments = []
1375                 self.value = None
1376                 self.word = word
1377
1378         def executeBracket( self, bracketBeginIndex, bracketEndIndex, evaluators ):
1379                 'Execute the bracket.'
1380                 self.arguments = getBracketValuesDeleteEvaluator(bracketBeginIndex, bracketEndIndex, evaluators)
1381                 if len( self.arguments ) < 1:
1382                         return
1383                 if len( self.arguments ) > 1:
1384                         self.value = self.arguments
1385                 else:
1386                         self.value = self.arguments[0]
1387
1388         def executeRightOperation( self, evaluators, evaluatorIndex ):
1389                 'Evaluate the statement and delete the evaluators.'
1390                 previousIndex = evaluatorIndex - 1
1391                 if previousIndex < 0:
1392                         return
1393                 evaluators[ previousIndex ].executeFunction( evaluators, previousIndex, self )
1394
1395
1396 class EvaluatorBracketSquare(Evaluator):
1397         'Class to evaluate a string.'
1398         def executeBracket( self, bracketBeginIndex, bracketEndIndex, evaluators ):
1399                 'Execute the bracket.'
1400                 self.value = getBracketValuesDeleteEvaluator(bracketBeginIndex, bracketEndIndex, evaluators)
1401
1402         def executeRightOperation( self, evaluators, evaluatorIndex ):
1403                 'Evaluate the statement and delete the evaluators.'
1404                 previousIndex = evaluatorIndex - 1
1405                 if previousIndex < 0:
1406                         return
1407                 if self.value.__class__ != list:
1408                         return
1409                 evaluators[ previousIndex ].executeKey( evaluators, self.value, previousIndex, self )
1410
1411
1412 class EvaluatorClass(Evaluator):
1413         'Class evaluator class.'
1414         def __init__(self, elementNode, word):
1415                 'Set value to none.'
1416                 self.elementNode = elementNode
1417                 self.value = None
1418                 self.word = word
1419
1420         def executeFunction(self, evaluators, evaluatorIndex, nextEvaluator):
1421                 'Execute the function.'
1422                 if self.elementNode.xmlObject == None:
1423                         self.elementNode.xmlObject = FunctionVariable(self.elementNode)
1424                 nextEvaluator.value = ClassObject(self.elementNode)
1425                 initializeFunction = None
1426                 if '_init' in self.elementNode.xmlObject.functionDictionary:
1427                         function = self.elementNode.xmlObject.functionDictionary['_init']
1428                         function.classObject = nextEvaluator.value
1429                         setFunctionLocalDictionary(nextEvaluator.arguments, function)
1430                         function.getReturnValue()
1431                 del evaluators[evaluatorIndex]
1432
1433
1434 class EvaluatorComma(Evaluator):
1435         'Class to join two evaluators.'
1436         def executePairOperation(self, evaluators, evaluatorIndex, operationLevel):
1437                 'Operate on two evaluators.'
1438                 if operationLevel != 0:
1439                         return
1440                 previousIndex = evaluatorIndex - 1
1441                 if previousIndex < 0:
1442                         evaluators[evaluatorIndex].value = None
1443                         return
1444                 if evaluators[previousIndex].word == ',':
1445                         evaluators[evaluatorIndex].value = None
1446                         return
1447                 del evaluators[evaluatorIndex]
1448
1449
1450 class EvaluatorConcatenate(Evaluator):
1451         'Class to join two evaluators.'
1452         def executePairOperation(self, evaluators, evaluatorIndex, operationLevel):
1453                 'Operate on two evaluators.'
1454                 if operationLevel != 80:
1455                         return
1456                 leftIndex = evaluatorIndex - 1
1457                 if leftIndex < 0:
1458                         del evaluators[evaluatorIndex]
1459                         return
1460                 rightIndex = evaluatorIndex + 1
1461                 if rightIndex >= len(evaluators):
1462                         del evaluators[ leftIndex : rightIndex ]
1463                         return
1464                 leftValue = evaluators[leftIndex].value
1465                 rightValue = evaluators[rightIndex].value
1466                 if leftValue.__class__ == rightValue.__class__ and (leftValue.__class__ == list or rightValue.__class__ == str):
1467                         evaluators[leftIndex].value = leftValue + rightValue
1468                         del evaluators[ evaluatorIndex : evaluatorIndex + 2 ]
1469                         return
1470                 if leftValue.__class__ == list and rightValue.__class__ == int:
1471                         if rightValue > 0:
1472                                 originalList = leftValue[:]
1473                                 for copyIndex in xrange( rightValue - 1 ):
1474                                         leftValue += originalList
1475                                 evaluators[leftIndex].value = leftValue
1476                                 del evaluators[ evaluatorIndex : evaluatorIndex + 2 ]
1477                         return
1478                 if leftValue.__class__ == dict and rightValue.__class__ == dict:
1479                         leftValue.update(rightValue)
1480                         evaluators[leftIndex].value = leftValue
1481                         del evaluators[ evaluatorIndex : evaluatorIndex + 2 ]
1482                         return
1483                 del evaluators[ leftIndex : evaluatorIndex + 2 ]
1484
1485
1486 class EvaluatorDictionary(Evaluator):
1487         'Class to join two evaluators.'
1488         def executePairOperation(self, evaluators, evaluatorIndex, operationLevel):
1489                 'Operate on two evaluators.'
1490                 if operationLevel != 10:
1491                         return
1492                 leftEvaluatorIndex = evaluatorIndex - 1
1493                 if leftEvaluatorIndex < 0:
1494                         print('Warning, leftEvaluatorIndex is less than zero in EvaluatorDictionary for:')
1495                         print(self)
1496                         print(evaluators)
1497                         return
1498                 rightEvaluatorIndex = evaluatorIndex + 1
1499                 if rightEvaluatorIndex >= len(evaluators):
1500                         print('Warning, rightEvaluatorIndex too high in EvaluatorDictionary for:')
1501                         print(rightEvaluatorIndex)
1502                         print(self)
1503                         print(evaluators)
1504                         return
1505                 evaluators[rightEvaluatorIndex].value = KeyValue(evaluators[leftEvaluatorIndex].value, evaluators[rightEvaluatorIndex].value)
1506                 del evaluators[ leftEvaluatorIndex : rightEvaluatorIndex ]
1507
1508
1509 class EvaluatorDivision(EvaluatorAddition):
1510         'Class to divide two evaluators.'
1511         def executePairOperation(self, evaluators, evaluatorIndex, operationLevel):
1512                 'Operate on two evaluators.'
1513                 if operationLevel == 40:
1514                         self.executePair(evaluators, evaluatorIndex)
1515
1516         def getValueFromValuePair(self, leftValue, rightValue):
1517                 'Divide two values.'
1518                 return leftValue / rightValue
1519
1520
1521 class EvaluatorElement(Evaluator):
1522         'Element evaluator class.'
1523         def __init__(self, elementNode, word):
1524                 'Set value to none.'
1525                 self.elementNode = elementNode
1526                 self.value = None
1527                 self.word = word
1528
1529         def executeCenterOperation(self, evaluators, evaluatorIndex):
1530                 'Execute operator which acts on the center.'
1531                 dotIndex = self.word.find('.')
1532                 if dotIndex < 0:
1533                         print('Warning, EvaluatorElement in evaluate can not find the dot for:')
1534                         print(functionName)
1535                         print(self)
1536                         return
1537                 attributeName = self.word[dotIndex + 1 :]
1538                 moduleName = self.word[: dotIndex]
1539                 if moduleName in globalModuleFunctionsDictionary:
1540                         self.value = globalModuleFunctionsDictionary[moduleName](attributeName, self.elementNode)
1541                         return
1542                 pluginModule = None
1543                 if moduleName in globalElementNameSet:
1544                         pluginModule = archive.getModuleWithPath(archive.getElementsPath(moduleName))
1545                 if pluginModule == None:
1546                         print('Warning, EvaluatorElement in evaluate can not get a pluginModule for:')
1547                         print(moduleName)
1548                         print(self)
1549                         return
1550                 getAccessibleAttributeFunction = pluginModule._getAccessibleAttribute
1551                 globalModuleFunctionsDictionary[moduleName] = getAccessibleAttributeFunction
1552                 self.value = getAccessibleAttributeFunction(attributeName, self.elementNode)
1553
1554         def executeFunction(self, evaluators, evaluatorIndex, nextEvaluator):
1555                 'Execute the function.'
1556                 executeNextEvaluatorArguments(self, evaluators, evaluatorIndex, nextEvaluator)
1557
1558
1559 class EvaluatorFalse(Evaluator):
1560         'Class to evaluate a string.'
1561         def __init__(self, elementNode, word):
1562                 'Set value to zero.'
1563                 self.value = False
1564                 self.word = word
1565
1566
1567 class EvaluatorFunction(Evaluator):
1568         'Function evaluator class.'
1569         def __init__(self, elementNode, word):
1570                 'Set value to none.'
1571                 self.elementNode = elementNode
1572                 self.value = None
1573                 self.word = word
1574
1575         def executeFunction(self, evaluators, evaluatorIndex, nextEvaluator):
1576                 'Execute the function.'
1577                 if self.elementNode.xmlObject == None:
1578                         if 'return' in self.elementNode.attributes:
1579                                 value = self.elementNode.attributes['return']
1580                                 self.elementNode.xmlObject = getEvaluatorSplitWords(value)
1581                         else:
1582                                 self.elementNode.xmlObject = []
1583                 self.function = Function(self.elementNode )
1584                 setFunctionLocalDictionary(nextEvaluator.arguments, self.function)
1585                 nextEvaluator.value = self.function.getReturnValue()
1586                 del evaluators[evaluatorIndex]
1587
1588
1589 class EvaluatorFundamental(Evaluator):
1590         'Fundamental evaluator class.'
1591         def executeCenterOperation(self, evaluators, evaluatorIndex):
1592                 'Execute operator which acts on the center.'
1593                 dotIndex = self.word.find('.')
1594                 if dotIndex < 0:
1595                         print('Warning, EvaluatorFundamental in evaluate can not find the dot for:')
1596                         print(functionName)
1597                         print(self)
1598                         return
1599                 attributeName = self.word[dotIndex + 1 :]
1600                 moduleName = self.word[: dotIndex]
1601                 if moduleName in globalModuleFunctionsDictionary:
1602                         self.value = globalModuleFunctionsDictionary[moduleName](attributeName)
1603                         return
1604                 pluginModule = None
1605                 if moduleName in globalFundamentalNameSet:
1606                         pluginModule = archive.getModuleWithPath(archive.getFundamentalsPath(moduleName))
1607                 else:
1608                         underscoredName = '_' + moduleName
1609                         if underscoredName in globalFundamentalNameSet:
1610                                 pluginModule = archive.getModuleWithPath(archive.getFundamentalsPath(underscoredName))
1611                 if pluginModule == None:
1612                         print('Warning, EvaluatorFundamental in evaluate can not get a pluginModule for:')
1613                         print(moduleName)
1614                         print(self)
1615                         return
1616                 getAccessibleAttributeFunction = pluginModule._getAccessibleAttribute
1617                 globalModuleFunctionsDictionary[moduleName] = getAccessibleAttributeFunction
1618                 self.value = getAccessibleAttributeFunction(attributeName)
1619
1620         def executeFunction(self, evaluators, evaluatorIndex, nextEvaluator):
1621                 'Execute the function.'
1622                 executeNextEvaluatorArguments(self, evaluators, evaluatorIndex, nextEvaluator)
1623
1624
1625 class EvaluatorGreaterEqual( EvaluatorEqual ):
1626         'Class to compare two evaluators.'
1627         def getBooleanFromValuePair(self, leftValue, rightValue):
1628                 'Compare two values.'
1629                 return leftValue >= rightValue
1630
1631
1632 class EvaluatorGreater( EvaluatorEqual ):
1633         'Class to compare two evaluators.'
1634         def getBooleanFromValuePair(self, leftValue, rightValue):
1635                 'Compare two values.'
1636                 return leftValue > rightValue
1637
1638
1639 class EvaluatorLessEqual( EvaluatorEqual ):
1640         'Class to compare two evaluators.'
1641         def getBooleanFromValuePair(self, leftValue, rightValue):
1642                 'Compare two values.'
1643                 return leftValue <= rightValue
1644
1645
1646 class EvaluatorLess( EvaluatorEqual ):
1647         'Class to compare two evaluators.'
1648         def getBooleanFromValuePair(self, leftValue, rightValue):
1649                 'Compare two values.'
1650                 return leftValue < rightValue
1651
1652
1653 class EvaluatorLocal(EvaluatorElement):
1654         'Class to get a local variable.'
1655         def executeCenterOperation(self, evaluators, evaluatorIndex):
1656                 'Execute operator which acts on the center.'
1657                 functions = self.elementNode.getXMLProcessor().functions
1658                 if len(functions) < 1:
1659                         print('Warning, there are no functions in EvaluatorLocal in evaluate for:')
1660                         print(self.word)
1661                         return
1662                 attributeKeywords = self.word.split('.')
1663                 self.value = functions[-1].localDictionary[attributeKeywords[0]]
1664                 for attributeKeyword in attributeKeywords[1 :]:
1665                         self.value = self.value._getAccessibleAttribute(attributeKeyword)
1666
1667
1668 class EvaluatorModulo( EvaluatorDivision ):
1669         'Class to modulo two evaluators.'
1670         def getValueFromValuePair(self, leftValue, rightValue):
1671                 'Modulo two values.'
1672                 return leftValue % rightValue
1673
1674
1675 class EvaluatorMultiplication( EvaluatorDivision ):
1676         'Class to multiply two evaluators.'
1677         def getValueFromValuePair(self, leftValue, rightValue):
1678                 'Multiply two values.'
1679                 return leftValue * rightValue
1680
1681
1682 class EvaluatorNone(Evaluator):
1683         'Class to evaluate None.'
1684         def __init__(self, elementNode, word):
1685                 'Set value to none.'
1686                 self.value = None
1687                 self.word = str(word)
1688
1689
1690 class EvaluatorNot(EvaluatorSubtraction):
1691         'Class to compare two evaluators.'
1692         def executeLeftOperation(self, evaluators, evaluatorIndex, operationLevel):
1693                 'Minus the value to the right.'
1694                 if operationLevel == 13:
1695                         self.executeLeft(evaluators, evaluatorIndex)
1696
1697         def getValueFromSingleValue( self, value ):
1698                 'Minus value.'
1699                 return not value
1700
1701
1702 class EvaluatorNotEqual( EvaluatorEqual ):
1703         'Class to compare two evaluators.'
1704         def getBooleanFromValuePair(self, leftValue, rightValue):
1705                 'Compare two values.'
1706                 return leftValue != rightValue
1707
1708
1709 class EvaluatorNumeric(Evaluator):
1710         'Class to evaluate a string.'
1711         def __init__(self, elementNode, word):
1712                 'Set value.'
1713                 self.value = None
1714                 self.word = word
1715                 try:
1716                         if '.' in word:
1717                                 self.value = float(word)
1718                         else:
1719                                 self.value = int(word)
1720                 except:
1721                         print('Warning, EvaluatorNumeric in evaluate could not get a numeric value for:')
1722                         print(word)
1723                         print(elementNode)
1724
1725
1726 class EvaluatorOr( EvaluatorAnd ):
1727         'Class to compare two evaluators.'
1728         def getBooleanFromValuePair(self, leftValue, rightValue):
1729                 'Or two values.'
1730                 return leftValue or rightValue
1731
1732
1733 class EvaluatorPower(EvaluatorAddition):
1734         'Class to power two evaluators.'
1735         def executePairOperation(self, evaluators, evaluatorIndex, operationLevel):
1736                 'Operate on two evaluators.'
1737                 if operationLevel == 60:
1738                         self.executePair(evaluators, evaluatorIndex)
1739
1740         def getValueFromValuePair(self, leftValue, rightValue):
1741                 'Power of two values.'
1742                 return leftValue ** rightValue
1743
1744
1745 class EvaluatorSelf(EvaluatorElement):
1746         'Class to handle self.'
1747         def executeCenterOperation(self, evaluators, evaluatorIndex):
1748                 'Execute operator which acts on the center.'
1749                 functions = self.elementNode.getXMLProcessor().functions
1750                 if len(functions) < 1:
1751                         print('Warning, there are no functions in executeCenterOperation in EvaluatorSelf in evaluate for:')
1752                         print(self.elementNode)
1753                         return
1754                 function = functions[-1]
1755                 attributeKeywords = self.word.split('.')
1756                 self.value = function.classObject
1757                 for attributeKeyword in attributeKeywords[1 :]:
1758                         self.value = self.value._getAccessibleAttribute(attributeKeyword)
1759
1760
1761 class EvaluatorTrue(Evaluator):
1762         'Class to evaluate a string.'
1763         def __init__(self, elementNode, word):
1764                 'Set value to true.'
1765                 self.value = True
1766                 self.word = word
1767
1768
1769 class EvaluatorValue(Evaluator):
1770         'Class to evaluate a string.'
1771         def __init__(self, word):
1772                 'Set value to none.'
1773                 self.value = word
1774                 self.word = str(word)
1775
1776
1777 class Function(BaseFunction):
1778         'Class to get equation results.'
1779         def __init__(self, elementNode):
1780                 'Initialize.'
1781                 self.elementNode = elementNode
1782                 self.evaluatorSplitLine = elementNode.xmlObject
1783                 self.localDictionary = {}
1784                 self.xmlProcessor = elementNode.getXMLProcessor()
1785
1786         def getReturnValueWithoutDeletion(self):
1787                 'Get return value without deleting last function.'
1788                 self.returnValue = None
1789                 self.xmlProcessor.functions.append(self)
1790                 if len(self.evaluatorSplitLine) < 1:
1791                         self.shouldReturn = False
1792                         self.processChildNodes(self.elementNode)
1793                 else:
1794                         self.returnValue = getEvaluatedExpressionValueBySplitLine(self.elementNode, self.evaluatorSplitLine)
1795                 return self.returnValue
1796
1797
1798 class FunctionVariable:
1799         'Class to hold class functions and variable set.'
1800         def __init__(self, elementNode):
1801                 'Initialize.'
1802                 self.functionDictionary = {}
1803                 self.variables = []
1804                 self.processClass(elementNode)
1805
1806         def addToVariableSet(self, elementNode):
1807                 'Add to variables.'
1808                 setLocalAttribute(elementNode)
1809                 keySplitLine = elementNode.xmlObject.key.split('.')
1810                 if len(keySplitLine) == 2:
1811                         if keySplitLine[0] == 'self':
1812                                 variable = keySplitLine[1]
1813                                 if variable not in self.variables:
1814                                         self.variables.append(variable)
1815
1816         def processClass(self, elementNode):
1817                 'Add class to FunctionVariable.'
1818                 for childNode in elementNode.childNodes:
1819                         self.processFunction(childNode)
1820                 if 'parentNode' in elementNode.attributes:
1821                         self.processClass(elementNode.getElementNodeByID(elementNode.attributes['parentNode']))
1822
1823         def processFunction(self, elementNode):
1824                 'Add function to function dictionary.'
1825                 if elementNode.getNodeName() != 'function':
1826                         return
1827                 idKey = elementNode.attributes['id']
1828                 if idKey in self.functionDictionary:
1829                         return
1830                 self.functionDictionary[idKey] = ClassFunction(elementNode)
1831                 for childNode in elementNode.childNodes:
1832                         self.processStatement(childNode)
1833
1834         def processStatement(self, elementNode):
1835                 'Add self statement to variables.'
1836                 if elementNode.getNodeName() == 'statement':
1837                         self.addToVariableSet(elementNode)
1838                 for childNode in elementNode.childNodes:
1839                         self.processStatement(childNode)
1840
1841
1842 class KeyValue:
1843         'Class to hold a key value.'
1844         def __init__(self, key=None, value=None):
1845                 'Get key value.'
1846                 self.key = key
1847                 self.value = value
1848
1849         def __repr__(self):
1850                 'Get the string representation of this KeyValue.'
1851                 return str(self.__dict__)
1852
1853         def getByCharacter( self, character, line ):
1854                 'Get by character.'
1855                 dotIndex = line.find( character )
1856                 if dotIndex < 0:
1857                         self.key = line
1858                         self.value = None
1859                         return self
1860                 self.key = line[: dotIndex]
1861                 self.value = line[dotIndex + 1 :]
1862                 return self
1863
1864         def getByDot(self, line):
1865                 'Get by dot.'
1866                 return self.getByCharacter('.', line )
1867
1868         def getByEqual(self, line):
1869                 'Get by dot.'
1870                 return self.getByCharacter('=', line )
1871
1872
1873 class ModuleElementNode:
1874         'Class to get the in attribute, the index name and the value name.'
1875         def __init__( self, elementNode):
1876                 'Initialize.'
1877                 self.conditionSplitWords = None
1878                 self.elseElement = None
1879                 if 'condition' in elementNode.attributes:
1880                         self.conditionSplitWords = getEvaluatorSplitWords( elementNode.attributes['condition'] )
1881                 else:
1882                         print('Warning, could not find the condition attribute in ModuleElementNode in evaluate for:')
1883                         print(elementNode)
1884                         return
1885                 if len( self.conditionSplitWords ) < 1:
1886                         self.conditionSplitWords = None
1887                         print('Warning, could not get split words for the condition attribute in ModuleElementNode in evaluate for:')
1888                         print(elementNode)
1889                 nextIndex = getNextChildIndex(elementNode)
1890                 if nextIndex >= len( elementNode.parentNode.childNodes ):
1891                         return
1892                 nextElementNode = elementNode.parentNode.childNodes[ nextIndex ]
1893                 lowerLocalName = nextElementNode.getNodeName().lower()
1894                 if lowerLocalName != 'else' and lowerLocalName != 'elif':
1895                         return
1896                 xmlProcessor = elementNode.getXMLProcessor()
1897                 if lowerLocalName not in xmlProcessor.namePathDictionary:
1898                         return
1899                 self.pluginModule = archive.getModuleWithPath( xmlProcessor.namePathDictionary[ lowerLocalName ] )
1900                 if self.pluginModule == None:
1901                         return
1902                 self.elseElement = nextElementNode
1903
1904         def processElse(self, elementNode):
1905                 'Process the else statement.'
1906                 if self.elseElement != None:
1907                         self.pluginModule.processElse( self.elseElement)
1908
1909
1910 globalCreationDictionary = archive.getGeometryDictionary('creation')
1911 globalDictionaryOperatorBegin = {
1912         '||' : EvaluatorConcatenate,
1913         '==' : EvaluatorEqual,
1914         '>=' : EvaluatorGreaterEqual,
1915         '<=' : EvaluatorLessEqual,
1916         '!=' : EvaluatorNotEqual,
1917         '**' : EvaluatorPower }
1918 globalModuleEvaluatorDictionary = {}
1919 globalFundamentalNameSet = set(archive.getPluginFileNamesFromDirectoryPath(archive.getFundamentalsPath()))
1920 addPrefixDictionary(globalModuleEvaluatorDictionary, globalFundamentalNameSet, EvaluatorFundamental)
1921 globalElementNameSet = set(archive.getPluginFileNamesFromDirectoryPath(archive.getElementsPath()))
1922 addPrefixDictionary(globalModuleEvaluatorDictionary, globalElementNameSet, EvaluatorElement)
1923 globalModuleEvaluatorDictionary['self'] = EvaluatorSelf
1924 globalSplitDictionaryOperator = {
1925         '+' : EvaluatorAddition,
1926         '{' : EvaluatorBracketCurly,
1927         '}' : Evaluator,
1928         '(' : EvaluatorBracketRound,
1929         ')' : Evaluator,
1930         '[' : EvaluatorBracketSquare,
1931         ']' : Evaluator,
1932         ',' : EvaluatorComma,
1933         ':' : EvaluatorDictionary,
1934         '/' : EvaluatorDivision,
1935         '>' : EvaluatorGreater,
1936         '<' : EvaluatorLess,
1937         '%' : EvaluatorModulo,
1938         '*' : EvaluatorMultiplication,
1939         '-' : EvaluatorSubtraction }
1940 globalSplitDictionary = getSplitDictionary() # must be after globalSplitDictionaryOperator