def visit_typedecl(self, node): """ Visit a node. """ if node.declname in self.names: c_gen = c_generator.CGenerator() pins = {} operators = DEFAULT_OPERATORS operators[ast.BitOr] = lambda a, b: a | b operators[ast.LShift] = lambda a, b: a << b operators[ast.RShift] = lambda a, b: a << b evaluator = SimpleEval(DEFAULT_OPERATORS) for pin in node.type.values.enumerators: expr = c_gen.visit(pin.value) if "(int)" in expr: expr = expr.replace('(int)', '') if expr in pins: pins[pin.name] = pins[expr] else: pins[pin.name] = evaluator.eval(expr.strip()) return pins
def evaluate_context(self, context, verbose=True, allowed_missing=()): evaluator = SimpleEval( functions={ **DEFAULT_FUNCTIONS, 'log': np.log, 'log2': np.log2, 'log10': np.log10, 'sqrt': np.sqrt, 'abs': np.abs, 'ord': ord, }) evaluator.names.update(context) evaluator.names.update(self._constants) allowed_missing = set(allowed_missing) for name, code in self._evaluables.items(): try: result = evaluator.eval(code) if isinstance(code, str) else code except NameNotDefined as error: if error.name in allowed_missing: allowed_missing.add(name) log.debug(f'Skipped evaluating: {name}') continue else: raise if verbose: log.debug(f'Evaluated: {name} = {repr(result)}') evaluator.names[name] = context[name] = result
def __init__( self, card_pile_id, mat_center, mat_size, mat_boundary, card_size, card_offset, mat_color, size_scaler, update_event_handle, per_deck_cards, #initial_num_of_decks=None, face_down=True, enable_generation=None, num_of_decks_per_generation=1, enable_auto_distribution=None, destination_piles_and_cards=None, title_property=None, other_properties=None, *args, **kwargs): super().__init__(card_pile_id, mat_center, mat_size, mat_boundary, card_size, card_offset, mat_color, size_scaler, sorting_rule=None, auto_sort_setting=None, enable_sort_button=False, enable_recover_last_removed_cards=False, update_event_handle=update_event_handle, title_property=title_property, other_properties=other_properties, *args, **kwargs) self._simple_eval = SimpleEval() self.enable_auto_distribution = enable_auto_distribution self._destination_piles_and_cards = destination_piles_and_cards self._ui_destination_piles_and_cards = {} self.per_deck_cards = per_deck_cards #self.initial_num_of_decks=initial_num_of_decks self._enable_generation = enable_generation self._num_of_decks_per_generation = num_of_decks_per_generation self._ui_num_of_decks_per_generation = None self._enable_auto_distribution = enable_auto_distribution self._per_deck_cards = per_deck_cards self.face_down = face_down self._generation_button = None self._auto_distribution_button = None self.setup_vertical_ui_elements()
def __init__(self): super().__init__() # Create a sandboxed evaluator allowing to use the Q object, # and the "|", "&" and "~" operators. # See: https://github.com/danthedeckie/simpleeval self.evaluator = SimpleEval( functions={"Q": Q}, operators={ ast.BitOr: operator.or_, ast.BitAnd: operator.and_, ast.Invert: operator.invert, }, )
def parse_entry(self, parsed_data): if parsed_data[0] == 0: # concatenation if len(parsed_data) == 1: return element = parsed_data[1] remainder = parsed_data[2:] remainder.insert(0, 0) if type(element) is str: result = None for result in self.parse_entry(remainder): yield element + result if result is None: yield element else: element_result = None for element_result in self.parse_entry(element): remainder_result = None for remainder_result in self.parse_entry(remainder): yield element_result + remainder_result if remainder_result is None: yield element_result if element_result is None: for remainder_result in self.parse_entry(remainder): yield remainder_result elif parsed_data[0] == 1: # random choice [a,b,c] element = parsed_data[random.randint(1, len(parsed_data) - 1)] if type(element) is not str: for result in self.parse_entry(element): yield result else: yield element elif parsed_data[0] == 2: # multiple response {a,b,c} for element in parsed_data[1:]: if type(element) is str: yield element else: for result in self.parse_entry(element): yield result elif parsed_data[0] == 3: # dynamic variable ${variable} variable_name = parsed_data[1] if type(variable_name) is not str: variable_name = next(self.parse_entry(variable_name), '') evaluator = SimpleEval(names=self.variables.copy(), functions=EVAL_FUNCTIONS, operators=EVAL_OPERATORS) evaluator.names['variables'] = evaluator.names evaluator.functions['eval'] = evaluator.eval try: yield str(evaluator.eval(variable_name)) except GeneratorExit: pass except: yield '[Error: {0}]'.format(''.join(traceback.format_exception_only(sys.exc_info()[0], sys.exc_info()[1])).strip())
def eval_statements(statement, variable_context): """Evaluates math statements and returns the value args statement: a simple python-like math statement variable_context: a dict with variable names as key and assigned values as dict values """ # variable values should be numbers var_types = set(type(value) for value in variable_context.values()) if not var_types.issubset(set([int, float, long])): raise InvalidExpression evaluator = SimpleEval(operators=SAFE_OPERATORS, names=variable_context) return evaluator.eval(statement)
def eval_statements(statement, variable_context): """Evaluates math statements and returns the value args statement: a simple python-like math statement variable_context: a dict with variable names as key and assigned values as dict values """ # variable values should be numbers var_types = set(type(value) for value in variable_context.values()) if not var_types.issubset({int, float, long, Decimal, date, datetime, NoneType, bool}): raise InvalidExpression evaluator = SimpleEval(operators=SAFE_OPERATORS, names=variable_context, functions=FUNCTIONS) return evaluator.eval(statement)
class AnswerSelector: _operators = { ast.Add: operator.add, ast.Sub: operator.sub, ast.Mult: operator.mul, ast.Div: operator.truediv } _evaluator = SimpleEval(operators=_operators) @classmethod def get_and_validate_answer(cls, source_id: str, text: str) -> int: question = get_object_or_404(Question, source_id=source_id) cls._validate_formula(text) cls._validate_numbers(question.numbers, text) return cls._evaluator.eval(text) @staticmethod def _validate_formula(text: str): non_formula_text = re.search(r'[^ ()*+\-/0-9]', text) if non_formula_text is not None: raise UnknownCommandException @staticmethod def _validate_numbers(numbers: tuple, text: str): text_numbers = re.split(r'[^0-9]', text) text_numbers = filter(None, text_numbers) text_numbers = (int(text) for text in text_numbers) numbers = sorted(numbers) text_numbers = sorted(text_numbers) if numbers != text_numbers: raise UnknownCommandException
def test_functions_are_disallowed_in_expressions(self): DISALLOWED = [type, isinstance, eval, getattr, setattr, help, repr, compile, open] if simpleeval.PYTHON3: exec('DISALLOWED.append(exec)') # exec is not a function in Python2... for f in simpleeval.DISALLOW_FUNCTIONS: assert f in DISALLOWED DF = simpleeval.DEFAULT_FUNCTIONS.copy() for x in DISALLOWED: simpleeval.DEFAULT_FUNCTIONS = DF.copy() with self.assertRaises(FeatureNotAvailable): s = SimpleEval() s.functions['foo'] = x s.eval('foo(42)') simpleeval.DEFAULT_FUNCTIONS = DF.copy()
class DRYTest(unittest.TestCase): """ Stuff we need to do every test, let's do here instead.. Don't Repeat Yourself. """ def setUp(self): """ initialize a SimpleEval """ self.s = SimpleEval() def t(self, expr, shouldbe): # pylint: disable=invalid-name """ test an evaluation of an expression against an expected answer """ return self.assertEqual(self.s.eval(expr), shouldbe)
def test_functions_are_disallowed_at_init(self): DISALLOWED = [type, isinstance, eval, getattr, setattr, help, repr, compile, open] if simpleeval.PYTHON3: exec('DISALLOWED.append(exec)') # exec is not a function in Python2... for f in simpleeval.DISALLOW_FUNCTIONS: assert f in DISALLOWED for x in DISALLOWED: with self.assertRaises(FeatureNotAvailable): s = SimpleEval(functions ={'foo': x})
def test_no_names(self): # does not work on current Py3, True et al. are keywords now self.s.eval('True') # with self.assertRaises(NameNotDefined): s = SimpleEval(names={}) if sys.version_info < (3, ): with self.assertRaises(NameNotDefined): s.eval('True') else: s.eval('True')
class BooleanQueryType(click.ParamType): name = "query" def __init__(self): super().__init__() # Create a sandboxed evaluator allowing to use the Q object, # and the "|", "&" and "~" operators. # See: https://github.com/danthedeckie/simpleeval self.evaluator = SimpleEval( functions={"Q": Q}, operators={ ast.BitOr: operator.or_, ast.BitAnd: operator.and_, ast.Invert: operator.invert, }, ) def convert(self, value, param, ctx) -> Q: try: return self.evaluator.eval(value) # 🤯 except Exception as exc: raise click.BadParameter(str(exc))
def setUp(self): """ initialize a SimpleEval """ self.s = SimpleEval()
#!/usr/bin/env python3 # -*- coding: utf-8 -*- __author__ = 'ipetrash' # pip install simpleeval from simpleeval import SimpleEval my_functions = { 'dict': dict, 'list': list, 'set': set, 'tuple': tuple, 'str': str, 'sorted': sorted, } my_eval = SimpleEval(functions=my_functions) print(my_eval.eval('dict(a="1", b=2)["a"]')) # "1" print(my_eval.eval('list("123")[0]')) # "1" print(my_eval.eval('sorted(set("12213"))[0]')) # "1" print(my_eval.eval('tuple("123")[0]')) # "1" print(my_eval.eval('str(123)[0]')) # "1" print(my_eval.eval('sorted("43198")[0]')) # "1" print() print(my_eval.eval('"1234567890"[:3]')) # 123 print(my_eval.eval('list("1234567890")[:3]')) # ['1', '2', '3'] print(my_eval.eval('"+".join(list("1234567890")[:3])')) # 1+2+3
def test_no_operators(self): self.s.eval('1+2') with self.assertRaises(OperatorNotDefined): s = SimpleEval(operators={}) s.eval('1+2')
import ast import operator as op SUPPORTED_OPERATORS = { ast.Add: op.add, ast.Sub: op.sub, } print(simple_eval("2 + 2 - 1", operators=SUPPORTED_OPERATORS)) # 3 try: print(simple_eval( "2 + 2 * 2", operators=SUPPORTED_OPERATORS)) # KeyError: <class '_ast.Mult'> except Exception as e: print(repr(e)) print() s = SimpleEval(operators=SUPPORTED_OPERATORS) # # OR: # s = SimpleEval() # s.operators = SUPPORTED_OPERATORS print(s.eval("2 + 2 - 1")) # 3 try: print(s.eval("2 + 2 * 2")) # KeyError: <class '_ast.Mult'> except Exception as e: print(repr(e))
def setUp(self): ''' initialize a SimpleEval ''' self.s = SimpleEval()
def __init__(self, app, setup_data, custom_functions={}): #we keep the 'main' application class to call some functions there self.app=app #load the config self.setup_data=setup_data self.cfg=Configer(path+self.setup_data['basic']['config_file']) #setup the window for the launcher wp = WindowProperties.getDefault() wp.setFixedSize(True) wp.setFullscreen(False) wp.setUndecorated(self.setup_data['basic']['undecorated']) wp.setOrigin(-2,-2) wp.setTitle(self.setup_data['basic']['title']) wp.setSize(self.setup_data['basic']['window_size'][0],self.setup_data['basic']['window_size'][1]) base.openMainWindow(props = wp) base.win.setCloseRequestEvent('exit_program') #a root node for ell the widgets self.root=pixel2d.attachNewNode('launcher_root') #set the bacground image self.background=DirectFrame(frameSize=_rec2d(self.setup_data['basic']['window_size'][0],self.setup_data['basic']['window_size'][1]), frameColor=(1,1,1, 1), frameTexture=path+self.setup_data['basic']['background'], parent=self.root) _resetPivot(self.background) self.background.setPos(_pos2d(0,0)) #some vars used later self.last_click_time=0.0 self.shouldExit =False self.last_button=None self.last_select_button=None self.last_select=None self.last_button_group=0 self.fonts={} self.buttons=[] self.last_slider_config_name=None self.last_slider_name=None #make the needed buttons #needed for the updater part... self.update_label=self.makeLabel("", 'wait') x=self.setup_data['basic']["window_size"][0]/2 x-=self.setup_data['style']['default']["size"][0]/2 y=self.setup_data['basic']["window_size"][1]-self.setup_data['style']['default']["size"][1]*1.5 pos=[x,y] self.update_done_button=self.makeButton(self.setup_data['basic']['msg']['ok'], {"style": "default","pos": pos,"func": "updateDone()"}) self.update_done_button.hide() #needed for the loadscreen self.loading_label=self.makeLabel(self.setup_data['basic']['msg']['loading'], 'loading') #needed for the slider screen self.slider = DirectSlider(frameSize=_rec2d(self.setup_data['style']['slider']["size"][0]*0.8, self.setup_data['style']['slider']["size"][1]), range=(0.0,1.0), value=0.5, thumb_relief=DGG.FLAT, thumb_frameTexture=path+self.setup_data['style']['slider']['thumb_img'], thumb_frameSize=(self.setup_data['style']['slider']['thumb_size'][0]/2, -self.setup_data['style']['slider']['thumb_size'][0]/2, -self.setup_data['style']['slider']['thumb_size'][1]/2, self.setup_data['style']['slider']['thumb_size'][1]/2), frameTexture=path+self.setup_data['style']['slider']['img'], frameVisibleScale=(1.25,1), command=self.setSliderValue, parent=self.root) x=self.setup_data['basic']["window_size"][0]/2 x+=(self.setup_data['style']['slider']["size"][0]*0.8)/2 y=self.setup_data['basic']["window_size"][1]/2 y+=self.setup_data['style']['slider']["size"][1]/2 self.slider.setPos(_pos2d(x,y)) self.slider.setTransparency(TransparencyAttrib.MDual) self.slider.hide() self.slider_done_button=self.makeButton(self.setup_data['basic']['msg']['ok'], {"style": "default","pos": pos,"func": "sliderDone()"}) self.slider_done_button.hide() self.slider_label=self.makeLabel("") #needed for key input self.key_input_label=self.makeLabel("") self.key_input_current_label=self.makeLabel("", "key_input") self.key_input_done=self.makeButton(self.setup_data['basic']['msg']['ok'], {"style": "default","pos": pos,"func": "keyInputDone()"}) self.key_input_done.hide() #the rest self.select_screens={} self.select_names={} self.select_labels={} for select_group in self.setup_data["select"]: self.select_screens[select_group]=[] self.select_names[select_group]={} for label in self.setup_data["select"][select_group]: self.select_names[select_group][self.setup_data["select"][select_group][label]]=label self.select_screens[select_group].append(self.makeSelectButton(label)) self.packSelectButtons(self.select_screens[select_group]) i=0 for button_group in self.setup_data["buttons"]: self.buttons.append({}) for button_name in button_group: self.buttons[i][button_name]=self.makeButton(button_name, button_group[button_name]) if i != 0: self.buttons[i][button_name].hide() i+=1 #SimpleEval stuff names={'None': None} functions={ 'Vec3':Vec3, 'startGame':self.startGame, 'exitGame':self.exitGame, 'updateGame':self.updateGame, 'updateDone':self.updateDone, 'toggleButtonGroup':self.toggleButtonGroup, 'showButton':self.showButton, 'select':self.showSelectScreen, 'slide':self.showSlideScreen, 'key':self.showKeyInputScreen, 'keyInputDone':self.keyInputDone, 'sliderDone':self.sliderDone, 'selectItem':self.selectItem, 'saveConfig':self.saveConfig } for key in custom_functions: functions[key]=custom_functions[key] self.simple_eval = SimpleEval(names=names, functions=functions) #events self.accept('exit_program',self.exitGame) base.buttonThrowers[0].node().setButtonDownEvent('buttonDown') self.accept('buttonDown', self.getKey) #tasks taskMgr.add(self.update, 'launcher_update')
class Launcher (DirectObject): def __init__(self, app, setup_data, custom_functions={}): #we keep the 'main' application class to call some functions there self.app=app #load the config self.setup_data=setup_data self.cfg=Configer(path+self.setup_data['basic']['config_file']) #setup the window for the launcher wp = WindowProperties.getDefault() wp.setFixedSize(True) wp.setFullscreen(False) wp.setUndecorated(self.setup_data['basic']['undecorated']) wp.setOrigin(-2,-2) wp.setTitle(self.setup_data['basic']['title']) wp.setSize(self.setup_data['basic']['window_size'][0],self.setup_data['basic']['window_size'][1]) base.openMainWindow(props = wp) base.win.setCloseRequestEvent('exit_program') #a root node for ell the widgets self.root=pixel2d.attachNewNode('launcher_root') #set the bacground image self.background=DirectFrame(frameSize=_rec2d(self.setup_data['basic']['window_size'][0],self.setup_data['basic']['window_size'][1]), frameColor=(1,1,1, 1), frameTexture=path+self.setup_data['basic']['background'], parent=self.root) _resetPivot(self.background) self.background.setPos(_pos2d(0,0)) #some vars used later self.last_click_time=0.0 self.shouldExit =False self.last_button=None self.last_select_button=None self.last_select=None self.last_button_group=0 self.fonts={} self.buttons=[] self.last_slider_config_name=None self.last_slider_name=None #make the needed buttons #needed for the updater part... self.update_label=self.makeLabel("", 'wait') x=self.setup_data['basic']["window_size"][0]/2 x-=self.setup_data['style']['default']["size"][0]/2 y=self.setup_data['basic']["window_size"][1]-self.setup_data['style']['default']["size"][1]*1.5 pos=[x,y] self.update_done_button=self.makeButton(self.setup_data['basic']['msg']['ok'], {"style": "default","pos": pos,"func": "updateDone()"}) self.update_done_button.hide() #needed for the loadscreen self.loading_label=self.makeLabel(self.setup_data['basic']['msg']['loading'], 'loading') #needed for the slider screen self.slider = DirectSlider(frameSize=_rec2d(self.setup_data['style']['slider']["size"][0]*0.8, self.setup_data['style']['slider']["size"][1]), range=(0.0,1.0), value=0.5, thumb_relief=DGG.FLAT, thumb_frameTexture=path+self.setup_data['style']['slider']['thumb_img'], thumb_frameSize=(self.setup_data['style']['slider']['thumb_size'][0]/2, -self.setup_data['style']['slider']['thumb_size'][0]/2, -self.setup_data['style']['slider']['thumb_size'][1]/2, self.setup_data['style']['slider']['thumb_size'][1]/2), frameTexture=path+self.setup_data['style']['slider']['img'], frameVisibleScale=(1.25,1), command=self.setSliderValue, parent=self.root) x=self.setup_data['basic']["window_size"][0]/2 x+=(self.setup_data['style']['slider']["size"][0]*0.8)/2 y=self.setup_data['basic']["window_size"][1]/2 y+=self.setup_data['style']['slider']["size"][1]/2 self.slider.setPos(_pos2d(x,y)) self.slider.setTransparency(TransparencyAttrib.MDual) self.slider.hide() self.slider_done_button=self.makeButton(self.setup_data['basic']['msg']['ok'], {"style": "default","pos": pos,"func": "sliderDone()"}) self.slider_done_button.hide() self.slider_label=self.makeLabel("") #needed for key input self.key_input_label=self.makeLabel("") self.key_input_current_label=self.makeLabel("", "key_input") self.key_input_done=self.makeButton(self.setup_data['basic']['msg']['ok'], {"style": "default","pos": pos,"func": "keyInputDone()"}) self.key_input_done.hide() #the rest self.select_screens={} self.select_names={} self.select_labels={} for select_group in self.setup_data["select"]: self.select_screens[select_group]=[] self.select_names[select_group]={} for label in self.setup_data["select"][select_group]: self.select_names[select_group][self.setup_data["select"][select_group][label]]=label self.select_screens[select_group].append(self.makeSelectButton(label)) self.packSelectButtons(self.select_screens[select_group]) i=0 for button_group in self.setup_data["buttons"]: self.buttons.append({}) for button_name in button_group: self.buttons[i][button_name]=self.makeButton(button_name, button_group[button_name]) if i != 0: self.buttons[i][button_name].hide() i+=1 #SimpleEval stuff names={'None': None} functions={ 'Vec3':Vec3, 'startGame':self.startGame, 'exitGame':self.exitGame, 'updateGame':self.updateGame, 'updateDone':self.updateDone, 'toggleButtonGroup':self.toggleButtonGroup, 'showButton':self.showButton, 'select':self.showSelectScreen, 'slide':self.showSlideScreen, 'key':self.showKeyInputScreen, 'keyInputDone':self.keyInputDone, 'sliderDone':self.sliderDone, 'selectItem':self.selectItem, 'saveConfig':self.saveConfig } for key in custom_functions: functions[key]=custom_functions[key] self.simple_eval = SimpleEval(names=names, functions=functions) #events self.accept('exit_program',self.exitGame) base.buttonThrowers[0].node().setButtonDownEvent('buttonDown') self.accept('buttonDown', self.getKey) #tasks taskMgr.add(self.update, 'launcher_update') def disable(self): #destroy all buttons for button_group in self.buttons: for button_name in button_group: button_group[button_name].destroy() for button_group in self.select_screens: for button in self.select_screens[button_group]: button.destroy() for label in self.select_labels: self.select_labels[label].destroy() self.key_input_label.destroy() self.key_input_current_label.destroy() self.key_input_done.destroy() self.update_done_button.destroy() self.loading_label.destroy() self.update_label.destroy() self.background.destroy() #ignore all events self.ignoreAll() #remove task taskMgr.remove('launcher_update') #remove root node self.root.removeNode() #clear data del self.select_names del self.setup_data del self.last_click_time del self.shouldExit del self.last_button del self.last_select_button del self.last_select del self.last_button_group del self.fonts del self.buttons del self.last_slider_config_name del self.last_slider_name def getKey(self, keyname): self.last_key=keyname self.key_input_current_label['text']=keyname def renderSomeFrames(self, frames=1): for i in range(frames): base.graphicsEngine.renderFrame() def startGame(self): self.toggleButtonGroup(-1) self.loading_label.show() #print "starting game" self.app.startGame() def hide(self): self.root.hide() def updateDone(self): self.toggleButtonGroup(0) self.update_done_button.hide() self.update_label['text']="" self.update_label.hide() def updateGame(self, wait_txt): url=self.setup_data['basic']['update_url'] self.downloadUpdates(url) self.toggleButtonGroup(-1) self.update_label.show() self.update_label['text'] def downloadUpdates(self, url): self.files_to_download=[] self.http = HTTPClient() self.channel = self.http.makeChannel(True) self.files_to_download.append({'url':url, 'target':path+'update.json'}) self.channel.beginGetDocument(DocumentSpec(url)) self.channel.downloadToFile(Filename(path+'update.json')) self.update_label['text']+=self.setup_data['basic']['msg']['collect'] #add a task that will do the lifting taskMgr.add(self.downloadTask, 'downloadTask') def downloadTask(self, task): if self.files_to_download: if self.channel.run(): #print 'running...' return task.cont else: if not self.channel.isDownloadComplete(): #print "Error downloading file." self.update_label['text']+=self.setup_data['basic']['msg']['download_error'] self.update_label['text']+="\n"+str(self.channel.getStatusString()) else: #if the downloaded file is named 'update.json' #we get the files and urls there and add them to #the download quene last_file=self.files_to_download[0]['target'] #print "downloaded", last_file self.update_label['text']+=self.setup_data['basic']['msg']['download_ok'] +last_file self.renderSomeFrames(8) if last_file == path+'update.json': with open(path+'update.json') as f: try: file_list=json.load(f) #print "loaded json file" except: #print "Error reading file" self.update_label['text']+=self.setup_data['basic']['msg']['read_error'] #we only download files on the list that we don't have (by name) for f in file_list: #print f if not os.path.exists(path+f['target']): self.files_to_download.append({'url':f['url'], 'target':path+f['target']}) #if it's a zipfile we extract elif is_zipfile(last_file): #print "extracting" self.update_label['text']+=self.setup_data['basic']['msg']['unzip'] self.renderSomeFrames(8) with ZipFile(last_file) as zf: zf.extractall(Filename(path).toOsSpecific()) #remove zero sized files self.update_label['text']+=self.setup_data['basic']['msg']['clean_up'] self.renderSomeFrames(8) for dirpath, dirs, files in os.walk(path): for file in files: full_path = Filename(os.path.join(dirpath, file)).toOsSpecific() #print full_path if os.stat(full_path).st_size == 0: os.remove(full_path) else: self.update_label['text']+=path+last_file self.update_label['text']+="\n - not a zip file!" #remove the last file from the list and get a next one self.files_to_download.pop(0) if self.files_to_download: next_file=self.files_to_download[0] #print "next_file", next_file self.channel.beginGetDocument(DocumentSpec(next_file['url'])) self.channel.downloadToFile(Filename(next_file['target'])) return task.cont #print "done" self.update_label['text']+=self.setup_data['basic']['msg']['done'] self.update_done_button.show() return task.done def update(self, task): #calling exit from a sequence will crash the game if self.shouldExit: self.app.exit() return task.cont def exe(self, command): if command: command=command.split(";") for cmd in command: try: #print cmd self.simple_eval.eval(cmd.strip()) except Exception as e: print e def runClickAnim(self, button): old_pos=button.getPos() new_pos=old_pos+_pos2d(0, 3) Sequence(LerpPosInterval(button, 0.05,new_pos),LerpPosInterval(button, 0.05,old_pos)).start() def onButtonClick(self, button, func, event=None): time=globalClock.getFrameTime() if (time-self.last_click_time) >0.11: self.last_button=button self.runClickAnim(button) Sequence(Wait(0.1),Func(self.exe, func)).start() self.last_click_time=time def doNothing(self, arg=None): print "nop" def saveConfig(self): self.toggleButtonGroup(0) config_file=path+self.setup_data['basic']['config_file'] self.cfg.saveConfig(config_file) def exitGame(self): #self.app.exit() self.shouldExit=True def showButton(self, group, button_name): self.buttons[group][button_name].show() def selectItem(self, button_name): #set the new value in the cfg self.cfg.setCfgValueFromString(self.last_select, self.setup_data['select'][self.last_select][button_name]) #print self.cfg[self.last_select] #update the button self.last_select_button['text']=self.last_select_button.getPythonTag("name")+" "+button_name #hide the select screen self.hideSelectScreen() #show the last group self.toggleButtonGroup(self.last_button_group) def setSliderValue(self): if self.last_slider_config_name: round_to=self.setup_data['slide'][self.last_slider_config_name]["round"] mini=self.setup_data['slide'][self.last_slider_config_name]["min"] maxi=self.setup_data['slide'][self.last_slider_config_name]["max"] self.slider_value=mini+self.slider['value']*(maxi-mini) if round_to==0: self.slider_value=int(self.slider_value) else: self.slider_value=round(self.slider_value,round_to) self.slider_label['text']=self.last_slider_name+'\n'+str(self.slider_value) def sliderDone(self): self.toggleButtonGroup(self.last_button_group) self.slider_label.hide() self.slider.hide() self.slider_done_button.hide() self.buttons[self.last_button_group][self.last_slider_name]['text']=self.last_slider_name+str(self.slider_value) self.cfg[self.last_slider_config_name]=self.slider_value cmd="slide('"+self.last_slider_config_name+"', '"+self.last_slider_name+"', "+str(self.slider_value)+")" self.buttons[self.last_button_group][self.last_slider_name].bind(DGG.B1PRESS, self.onButtonClick, [self.buttons[self.last_button_group][self.last_slider_name], cmd]) def showSlideScreen(self, config_name, name, value): self.last_slider_config_name=config_name self.last_slider_name=name for button_group in self.buttons: for button_name in button_group: button_group[button_name].hide() self.slider_label.show() self.slider_label['text']=name self.slider.show() self.slider_done_button.show() mini=self.setup_data['slide'][self.last_slider_config_name]["min"] maxi=self.setup_data['slide'][self.last_slider_config_name]["max"] self.slider['value']=float(value)/float(maxi-mini) self.setSliderValue() def showSelectScreen(self, screen): self.last_select=screen self.last_select_button=self.last_button for button_group in self.buttons: for button_name in button_group: button_group[button_name].hide() for button in self.select_screens[screen]: button.show() for label in self.select_labels: if label == screen: self.select_labels[label].show() else: self.select_labels[label].hide() def keyInputDone(self): self.toggleButtonGroup(self.last_button_group) self.key_input_label.hide() self.key_input_current_label.hide() self.key_input_done.hide() self.buttons[self.last_button_group][self.last_key_name]['text']=self.last_key_name+self.last_key self.cfg[self.last_key_config_name]=self.last_key cmd="key('"+self.last_key_config_name+"', '"+self.last_key_name+"', '"+self.last_key+"')" self.buttons[self.last_button_group][self.last_key_name].bind(DGG.B1PRESS, self.onButtonClick, [self.buttons[self.last_button_group][self.last_key_name], cmd]) def showKeyInputScreen(self, config_name, name, value): self.last_key_config_name=config_name self.last_key_name=name for button_group in self.buttons: for button_name in button_group: button_group[button_name].hide() self.key_input_label.show() self.key_input_current_label.show() self.key_input_done.show() self.key_input_label['text']=self.setup_data['basic']['msg']['new_key'].format(name) self.key_input_current_label['text']=value def hideSelectScreen(self): for screen in self.select_screens: for button in self.select_screens[screen]: button.hide() for label in self.select_labels: self.select_labels[label].hide() def toggleButtonGroup(self, group): self.last_button_group=group i=0 for button_group in self.buttons: for button_name in button_group: if i==group: button_group[button_name].show() else: button_group[button_name].hide() i+=1 def getFont(self, font_name, font_size): if font_name in self.fonts: if font_size in self.fonts[font_name]: font=self.fonts[font_name][font_size] else: font=self.addFontSize(font_name, font_size) else: font=self.addFont(font_name, font_size) return font def addFont(self, font_name, font_size): font=loader.loadFont(path+font_name) font.setPixelsPerUnit(font_size) font.setMinfilter(Texture.FTNearest ) font.setMagfilter(Texture.FTNearest ) self.fonts[font_name]={font_size:font} return font def addFontSize(self, font_name, font_size): #a bit of a hack to get a font of any size font=self.fonts[font_name].itervalues().next() new_font=font.makeCopy() new_font.setPixelsPerUnit(font_size) self.fonts[font_name][font_size]=new_font return new_font def getTextAlign(self, align): a=align.strip().lower() if a == 'center': return TextNode.ACenter elif a == 'left': return TextNode.ALeft elif a == 'right': return TextNode.ARight elif a == 'boxed_left': return TextNode.ABoxedLeft elif a == 'boxed_right': return TextNode.ABoxedRight elif a == 'boxed_center': return TextNode.ABoxedCenter else: return TextNode.ALeft def packSelectButtons(self, button_list): label_y=self.setup_data['style']["label"]["size"][1] x_offset=0 y_offset=0 button_x=self.setup_data['style']["select"]["size"][0] button_y=self.setup_data['style']["select"]["size"][1] window_x=self.setup_data['basic']["window_size"][0] window_y=self.setup_data['basic']["window_size"][1]+label_y button_count=len(button_list) last_row_x_offset=0 #how many buttons can I fit side by side? buttons_per_row=window_x/button_x #how much space is left unused? x_offset=(window_x%button_x)/2 #can all the buttons fit in one row? if button_count <= buttons_per_row: y_offset=window_y/2-button_y/2 row_count=1 x_offset+=(window_x-(button_count*button_x))/2 else: row_count=button_count/buttons_per_row if button_count%buttons_per_row != 0: row_count+=1 y_offset=(window_y-((row_count)*button_y))/2 if y_offset<0 or x_offset<0: print "(warning) Select buttons can't fit the window" #is the last row full? if row_count > 1 and buttons_per_row*row_count > button_count: last_row_x_offset=(buttons_per_row*row_count-button_count)*button_x/2 #start packing the buttons i=0 row=-1 for button in button_list: column=i%buttons_per_row if column==0: row+=1 x=x_offset+button_x*column y=y_offset+button_y*row if row==row_count-1: #this is the last row x+=last_row_x_offset button.setPos(_pos2d(x,y)) i+=1 def makeLabel(self, name, style_name="label"): style=self.setup_data['style'][style_name] button=self.makeStyleButton(style) button['state'] = DGG.DISABLED button['text']=name x=self.setup_data['basic']["window_size"][0]/2 x-=style["size"][0]/2 button.setPos(_pos2d(x,0)) button.hide() return button def makeSelectButton(self, name): style=self.setup_data['style']["select"] button=self.makeStyleButton(style) button['text']=name button.bind(DGG.B1PRESS, self.onButtonClick, [button, "selectItem('"+name+"')"]) button.hide() return button def makeButton(self, name, config): style=self.setup_data['style'][config["style"]] button=self.makeStyleButton(style) button['text']=name button.setPos(_pos2d(config["pos"][0], config["pos"][1])) if "select" in config: self.select_labels[config["select"]]=self.makeLabel(name) current_value=self.cfg.getCfgValueAsString(config["select"]) if current_value in self.select_names[config["select"]]: label_txt=self.select_names[config["select"]][current_value] else: label_txt=current_value +"*" button['text']=name+" "+label_txt button.bind(DGG.B1PRESS, self.onButtonClick, [button, "select('"+config["select"]+"')"]) button.setPythonTag("name", name) elif "slide" in config: current_value=self.cfg.getCfgValueAsString(config["slide"]) if current_value == "None": current_value=str(self.setup_data['slide'][config["slide"]]['default']) self.cfg[config["slide"]]=self.setup_data['slide'][config["slide"]]['default'] button['text']+=current_value button.bind(DGG.B1PRESS, self.onButtonClick, [button, "slide('"+config["slide"]+"', '"+name+"', "+current_value+")"]) elif "key" in config: current_value=self.cfg.getCfgValueAsString(config["key"]) if current_value == "None": current_value=str(self.setup_data['key'][config["key"]]) self.cfg[config["key"]]=current_value button['text']+=current_value button.bind(DGG.B1PRESS, self.onButtonClick, [button, "key('"+config["key"]+"', '"+name+"', '"+current_value+"')"]) elif "func" in config: button.bind(DGG.B1PRESS, self.onButtonClick, [button,config["func"] ]) return button def makeStyleButton(self, config): align=self.getTextAlign(config["text_align"]) if align in (TextNode.ACenter, TextNode.ABoxedCenter): text_offset=[ -config["size"][0]/2+config["text_offset"][0], config["size"][1]/2+config["text_offset"][1] ] elif align in (TextNode.ALeft, TextNode.ABoxedLeft): text_offset=[ -config["size"][0]+config["text_offset"][0], config["size"][1]/2+config["text_offset"][1] ] else: text_offset=[ +config["text_offset"][0], config["size"][1]/2+config["text_offset"][1] ] button=DirectFrame(frameSize=_rec2d(config["size"][0],config["size"][1]), frameColor=(1,1,1, 1), frameTexture=path+config["img"], text_font=self.getFont(config["font"],config["text_size"]), text=" ", text_scale=config["text_size"], text_align=align, text_pos=text_offset, text_fg=config["text_color"], state=DGG.NORMAL, parent=self.root) _resetPivot(button) button.setTransparency(TransparencyAttrib.MDual) return button
print( simple_eval("abs(sin(3) * cos(3))", functions={ 'sin': math.sin, 'cos': math.cos, 'abs': abs })) # 0.13970774909946293 def my_md5(value): import hashlib return hashlib.md5(bytes(value, 'utf-8')).hexdigest() print(simple_eval("md5('Hello World!')", functions={'md5': my_md5})) # ed076287532e86365e841e92bfc50d8c print(simple_eval("list('1234')", functions={'list': list})) # ['1', '2', '3', '4'] print() # Using SimpleEval class from simpleeval import SimpleEval my_eval = SimpleEval() my_eval.names['a'] = 2 my_eval.functions['square'] = lambda x: x * x print(my_eval.eval('1 + 1 * a')) # 3 print(my_eval.eval('square(1 + 1 * a)')) # 9
#!/usr/bin/env python3 # -*- coding: utf-8 -*- __author__ = 'ipetrash' # pip install simpleeval from simpleeval import simple_eval my_functions = { 'my_pos': lambda: { 'x': 12, 'y': 10 }, 'map': map, 'str': str, } print(simple_eval('my_pos()["x"] * my_pos()["y"]', functions=my_functions)) # 120 print(simple_eval('"x".join(map(str, my_pos().values()))', functions=my_functions)) # 12x10 print() # OR: from simpleeval import SimpleEval my_eval = SimpleEval(functions=my_functions) print(my_eval.eval('my_pos()["x"] * my_pos()["y"]')) # 120 print(my_eval.eval('"x".join(map(str, my_pos().values()))')) # 12x10
# Compound types (dict, tuple, list, set) in general just work if you pass them in as named objects. # If you want to allow creation of these, the EvalWithCompoundTypes class works. Just replace any use of # SimpleEval with that. # """ # pip install simpleeval from simpleeval import simple_eval, SimpleEval, EvalWithCompoundTypes # SimpleEval and simple_eval NOT WORK with compound types try: print(simple_eval('[1, 2, 3, 4]')) except Exception as e: print(e) # Sorry, List is not available in this evaluator try: my_eval = SimpleEval() print(my_eval.eval('[1, 2, 3, 4]')) except Exception as e: print(e) # Sorry, List is not available in this evaluator print() # Compound Types my_compound_types_eval = EvalWithCompoundTypes() my_compound_types_eval.functions['len'] = len # list print(my_compound_types_eval.eval('[1, 2, 3, 4]')) # [1, 2, 3, 4] print(my_compound_types_eval.eval('[1, 2] + [3, 4]')) # [1, 2, 3, 4] print(my_compound_types_eval.eval('len([1, 2, 3, 4])')) # 4 print(my_compound_types_eval.eval('[1, 2, 1, 3, 4].count(1)')) # 2