def parse(text, run_label): script = Script(text) script.parse() script_parser = script.script_parser run_obj = script_parser.runs.get(run_label) parameters = run_obj.mechanism_obj.parameters return run_obj, parameters
def run(text): script_obj = Script(text) script_obj.parse() script_output = script_obj.run() script_obj.postproc(script_output) script_obj.plot(block=False) return script_obj, script_output
def parse(text): script = Script(text) script.parse() script_parser = script.script_parser runs = script_parser.runs nruns = len(runs.runs) if nruns != 1: phases = script_parser.phases.phases for phaselbl, phase in phases.items(): if not phase.is_parsed: phase.parse(script_parser.parameters, script_parser.variables) world = World(phases, list(phases.keys())) else: run = list(runs.runs.values())[0] world = run.world return world, script
def plot_thread(self): try: if self.simulation_data is None: raise Exception("No simulation data to plot.") script = self.scriptField.text_box.get("1.0", "end-1c") script_obj = Script(script) script_obj.parse() except Exception as ex: self.handle_exception(ex) return self.progress = Progress(self.script_obj) self.progress.start() # self.start_progress_job = self.root.after(1000, self.progress.start) self.simulation_thread = threading.Thread(target=self.plot) self.simulation_thread.daemon = True # So that the thread dies if main program exits self.simulation_thread.start() self.check_job = self.root.after(100, self.handle_simulation_end)
def simulate_thread(self, event=None): try: script = self.scriptField.text_box.get("1.0", "end-1c") self.script_obj = Script(script) self.script_obj.parse() msg = self.script_obj.check_deprecated_syntax() if msg is not None: WarningDlg(msg) except Exception as ex: self.handle_exception(ex) return self.progress = Progress(self.script_obj) self.progress.start() # self.start_progress_job = self.root.after(1000, self.progress.start) self.simulation_thread = threading.Thread(target=self.simulate) self.simulation_thread.daemon = True # So that the thread dies if main program exits self.simulation_thread.start() self.check_job = self.root.after(100, self.handle_simulation_end)
def parse(text, name): script = Script(text) script.parse() return script.script_parser.parameters.val[name]
def parse(text): script = Script(text) script.parse() return script.script_parser.parameters.val[TRACE]
def parse(text): script = Script(text) script.parse() return script.script_parser.parameters.val[N_SUBJECTS]
def parse(text): script = Script(text) script.parse() return script.script_parser.parameters.val[MECHANISM_NAME]
def parse(text): script = Script(text) script.parse() return script.script_parser.parameters.val[RESPONSE_REQUIREMENTS]
def parse(text): script = Script(text) script.parse() return script.script_parser.parameters.val[DISCOUNT]
class Gui(): def __init__(self): self.file_path = None self.last_open_folder = None self.simulation_data = None # A ScriptOutput object self.script_obj = None # className appears (at least) in Ubuntu sidebar "tooltip" (app name) self.root = tk.Tk(className=TITLE) self.progress = None self.root.style = ttk.Style() self.root.style.theme_use( "alt") # ('clam', 'alt', 'default', 'classic') self.set_title() self.scriptLabel = None self.scriptField = None self._create_widgets() self._bind_accelerators() # Set icon icon_file = util.resource_path('Lemur-icon.gif') img = tk.PhotoImage(file=icon_file) self.root.tk.call('wm', 'iconphoto', self.root._w, img) self.root.minsize(width=500, height=600) self.root.protocol("WM_DELETE_WINDOW", self.file_quit) # When run in bundle, display licene dialog box is_bundle = getattr(sys, 'frozen', False) if is_bundle: LicenseDlg(self) self.root.mainloop() self.root.quit() def _add_recent_file(self, file_to_add): current_list = read_recent_files_file() if file_to_add in current_list: new_list = [file_to_add] + [ file for file in current_list if file != file_to_add ] else: new_list = [file_to_add] + current_list if len(new_list) > NUMBER_OF_RECENT_FILES: new_list = new_list[0:NUMBER_OF_RECENT_FILES] write_recent_files_file(new_list) self._update_recent_files_menu(new_list) def _update_recent_files_menu(self, new_list=None, init=False): if new_list is None: new_list = read_recent_files_file() self._create_recent_files_menu(init) for recent_file in new_list: lbl = recent_file.replace('/', SEP) self.recent_files_menu.add_command(label=lbl, command=partial( self.file_open_recent, recent_file)) self.recent_files_menu.add_separator() self.recent_files_menu.add_command(label="Clear Items", command=self.clear_recent_files) def clear_recent_files(self): write_recent_files_file(list()) self._update_recent_files_menu() def _create_recent_files_menu(self, init=False): OPEN_RECENT = "Open Recent" if not init: self.file_menu.delete(OPEN_RECENT) self.recent_files_menu = tk.Menu(self.file_menu, tearoff=0) self.file_menu.insert_cascade(2, label=OPEN_RECENT, menu=self.recent_files_menu, underline=0, command=self.file_open_recent) def _create_widgets(self): # The frame containing the widgets frame = tk.Frame(self.root) # The menu bar self.menu_bar = tk.Menu(self.root, tearoff=0) # The File menu self.file_menu = tk.Menu( self.menu_bar, tearoff=0) # tearoff = 0: can't be separated from window self.file_menu.add_command(label="New", underline=0, command=self.file_new, accelerator="Ctrl+N") self.file_menu.add_command(label="Open...", underline=0, command=self.file_open, accelerator="Ctrl+O") self._update_recent_files_menu(new_list=None, init=True) self.file_menu.add_command(label="Save", underline=0, command=self.file_save, accelerator="Ctrl+S") self.file_menu.add_command(label="Save As...", underline=1, command=self.file_save_as) self.file_menu.add_separator() self.file_menu.add_command(label="Exit", underline=1, command=self.file_quit) self.menu_bar.add_cascade(label="File", underline=0, menu=self.file_menu) # The Edit menu edit_menu = tk.Menu( self.menu_bar, tearoff=0) # tearoff = 0: can't be seperated from window edit_menu.add_command(label="Undo", underline=0, command=self.undo, accelerator="Ctrl+Z") edit_menu.add_command(label="Redo", underline=0, command=self.redo, accelerator="Ctrl+Y") self.menu_bar.add_cascade(label="Edit", underline=0, menu=edit_menu) # The Run menu run_menu = tk.Menu( self.menu_bar, tearoff=0) # tearoff = 0: can't be seperated from window run_menu.add_command(label="Simulate and Plot", underline=0, command=self.simulate_thread, accelerator="F5") run_menu.add_command(label="Plot", underline=0, command=self.plot_thread) self.menu_bar.add_cascade(label="Run", underline=0, menu=run_menu) # The Help menu help_menu = tk.Menu( self.menu_bar, tearoff=0) # tearoff = 0: can't be seperated from window help_menu.add_command(label="Documentation (offline)", underline=0, command=self.open_documentation_offline, accelerator="F1") help_menu.add_command(label="Documentation (online)", underline=0, command=self.open_documentation_online) help_menu.add_command(label="License", underline=0, command=self.open_licensedlg) self.menu_bar.add_cascade(label="Help", underline=0, menu=help_menu) self.root.config(menu=self.menu_bar) # The label # lbltxt = "Place your script in the box below or open a text file" # lbltxt = "Simulate: F5, Open: Ctrl+O, Save: Ctrl+S, New: Ctrl+N" # scriptLabel = tk.Label(frame, text=lbltxt) # scriptLabel.pack() # side="top", anchor="w") # The LineNumberedTextBox widget lntb_frame = tk.Frame(frame) self.scriptField = LineNumberedTextBox(lntb_frame) lntb_frame.pack(side="top", anchor="w", fill=BOTH, expand=YES) # XXX # self.scriptField.text_box.insert(1.0, """mechanism: ga # stimulus_elements: e1, e2 # behaviors: b1, b2 # @PHASE phase1 stop:e1=10 # L1 e1 | L2 # L2 e2 | L1 # @run phase1 # @vplot e1->b1""") # End XXX # The Quit button # quitButton = tk.Button(frame, text="Quit", command=self.quit) # quitButton.pack(side="right") button_frame = tk.Frame(frame) # The Close All button closefigButton = ttk.Button(button_frame, text="Close Figures", command=self.close_figs) closefigButton.pack(side="right") # The Simulate button self.simButton = ttk.Button(button_frame, text="Simulate and Plot", command=self.simulate_thread) self.simButton.pack(side="left") # The Plot button self.plotButton = ttk.Button(button_frame, text="Plot", command=self.plot_thread) self.plotButton.pack(side="left") button_frame.pack(side="top", anchor="w", fill=BOTH, expand=NO) # button_frame.pack_propagate(False) # The message log field self.msgField = tk.scrolledtext.ScrolledText(frame, height=2) self.msgField.insert( 1.0, "Welcome to Learning Simulator!\nThis is the message log.") self.msgField.pack(side="top", anchor="w", fill=BOTH, expand=NO) self.msgField.config( state=DISABLED, borderwidth=3, font="{Lucida Sans Typewriter} 10", # foreground="green", background="gray70", # insertbackground="white", # cursor # selectforeground="green", # selection # selectbackground="gray50", # #008000", wrap=tk.WORD, # use word wrapping # width=64, # undo=True, # Tk 8.4 ) frame.pack(fill=BOTH, expand=YES) def simulate_thread(self, event=None): try: script = self.scriptField.text_box.get("1.0", "end-1c") self.script_obj = Script(script) self.script_obj.parse() msg = self.script_obj.check_deprecated_syntax() if msg is not None: WarningDlg(msg) except Exception as ex: self.handle_exception(ex) return self.progress = Progress(self.script_obj) self.progress.start() # self.start_progress_job = self.root.after(1000, self.progress.start) self.simulation_thread = threading.Thread(target=self.simulate) self.simulation_thread.daemon = True # So that the thread dies if main program exits self.simulation_thread.start() self.check_job = self.root.after(100, self.handle_simulation_end) def handle_simulation_end(self): if self.progress.done: assert (not self.simulation_thread.is_alive()) self.simulation_thread.join() self.root.after_cancel(self.check_job) if self.progress.exception is not None: if not isinstance(self.progress.exception, InterruptedSimulation): self.progress.close_dlg() self.handle_exception(self.progress.exception, self.progress.exception_traceback) elif self.progress.done: # This will also close the progress dialog box try: self.script_obj.plot(progress=self.progress) except AttributeError as ex: self.progress.close_dlg() self.handle_exception(ex, traceback.format_exc()) else: assert (self.simulation_thread.is_alive()) self.check_job = self.root.after(100, self.handle_simulation_end) def simulate(self): try: self.simulation_data = self.script_obj.run(self.progress) self.script_obj.postproc(self.simulation_data, self.progress) except Exception as ex: self.progress.exception = ex self.progress.exception_traceback = traceback.format_exc() finally: self.progress.set_done(True) # return None # XXX perhaps not needed? for threading def _select_line(self, lineno): start = f"{lineno}.0" end = f"{lineno}.{tk.END}" self.scriptField.text_box.tag_add(tk.SEL, start, end) def enable_simulation_controls(self, enable=True): state = "normal" if not enable: state = DISABLED self.simButton.config(state=state) self.plotButton.config(state=state) self.menu_bar.entryconfig("Run", state=state) def plot_thread(self): try: if self.simulation_data is None: raise Exception("No simulation data to plot.") script = self.scriptField.text_box.get("1.0", "end-1c") script_obj = Script(script) script_obj.parse() except Exception as ex: self.handle_exception(ex) return self.progress = Progress(self.script_obj) self.progress.start() # self.start_progress_job = self.root.after(1000, self.progress.start) self.simulation_thread = threading.Thread(target=self.plot) self.simulation_thread.daemon = True # So that the thread dies if main program exits self.simulation_thread.start() self.check_job = self.root.after(100, self.handle_simulation_end) def plot(self): try: self.script_obj.postproc(self.simulation_data, self.progress) except Exception as ex: self.progress.exception = ex self.progress.exception_traceback = traceback.format_exc() finally: self.progress.set_done(True) def close_figs(self): plt.close("all") def handle_exception(self, ex, stack_trace=None): if isinstance(ex, ParseException): self._select_line(ex.lineno) self.close_figs() err_msg = str(ex) if err_msg.startswith("[Errno "): rindex = err_msg.index("] ") err_msg = err_msg[(rindex + 2):] elif (not isinstance(ex, ParseException)) and (not isinstance( ex, EvalException)): err_msg = type( ex).__name__ + ": " + err_msg # Prepend e.g. "KeyError: " if stack_trace is None: stack_trace = traceback.format_exc() ErrorDlg("Error", err_msg, stack_trace) def handle_exception_old(self, ex): # err_msg = ex.args[0] err_msg = str(ex) # if len(ex.args) == 2: # err_msg = "{0} {1}".format(err_msg, ex.args[1]) # # err_msg = err_msg + ex.args[1] messagebox.showerror("Error", err_msg) # def file_open(self): # filename = filedialog.askopenfilename() # # filename = "C:/Python/Python36-32/_Markus/scriptexempel2.txt" # XXX # file = open(filename, "r") # self.scriptField.delete("1.0", "end-1c") # self.scriptField.insert("1.0", file.read()) # self.scriptField.mark_set("insert", "1.0") # file.close() # Make sure you close the file when done def save_changes(self): if self.scriptField.text_box.edit_modified(): msg = "This document has been modified. Do you want to save changes?" save_changes = messagebox.askyesnocancel("Save?", msg) if save_changes is None: # Cancel return False elif save_changes is True: # Yes self.file_save() return True def file_new(self, event=None): save_changes = self.save_changes() if not save_changes: return self.scriptField.text_box.delete(1.0, "end") self.scriptField.text_box.edit_modified(False) self.scriptField.text_box.edit_reset() self.file_path = None self.set_title() def file_open_recent(self, recent_file): self._fill_textbox(recent_file) self._add_recent_file(recent_file) def file_open(self, event=None): save_changes = self.save_changes() if not save_changes: return if self.last_open_folder is None: initialdir = '.' else: initialdir = self.last_open_folder filepath = filedialog.askopenfilename(filetypes=FILETYPES, initialdir=initialdir) if filepath is not None and len(filepath) != 0: self._fill_textbox(filepath) self._add_recent_file(filepath) def _fill_textbox(self, filepath): try: with open(filepath, encoding='utf-8') as f: file_contents = f.read() except UnicodeDecodeError: # with open(filepath, encoding='utf-8', errors='ignore') as f: with open(filepath, encoding='utf-16') as f: file_contents = f.read() except FileNotFoundError as ex: self.handle_exception(ex) return # Set current text to file contents self.scriptField.text_box.delete(1.0, "end") self.scriptField.text_box.insert(1.0, file_contents) self.scriptField.text_box.edit_modified(False) self.scriptField.text_box.mark_set("insert", "1.0") self.scriptField.text_box.redraw_line_numbers() self.file_path = filepath self.last_open_folder = os.path.dirname(filepath) self.set_title() def file_open_textbox(self, event=None): """ To override default behavior of <Control-O> which inserts a new line in the textbox. """ self.file_open(event) return "break" def file_save(self, event=None): self.file_save_as(filepath=self.file_path) def file_save_as(self, filepath=None, event=None): if filepath is None: filepath = filedialog.asksaveasfilename(filetypes=FILETYPES) if len( filepath ) == 0: # Empty tuple or empty string is returned if cancelled return # "cancelled" else: if ('.' not in filepath) and (not filepath.endswith(".txt")): filepath = filepath + ".txt" try: with open(filepath, 'wb') as f: text = self.scriptField.text_box.get(1.0, "end-1c") f.write(bytes(text, 'UTF-8')) self.scriptField.text_box.edit_modified(False) self.file_path = filepath self.set_title() self._add_recent_file(filepath) return # "saved" except IOError as e: self.handle_exception(e) return # "cancelled" def file_quit(self, event=None): save_changes = self.save_changes() if not save_changes: return self.close_figs() # self.root.destroy() # sys.exit(0) # Workaround for tk bug that clipboard is not appended to os clipboard after app exit # (Issue #29) self.root.after(200, self.root.destroy) self.root.mainloop() def set_title(self, event=None): if self.file_path is not None: # title = os.path.basename(self.file_path) title = os.path.abspath(self.file_path) else: title = "Untitled" self.root.title(title + " - " + TITLE) def _bind_accelerators(self): self.root.bind("<Control-n>", self.file_new) self.root.bind("<Control-N>", self.file_new) self.root.bind("<Control-o>", self.file_open) self.root.bind("<Control-O>", self.file_open) self.root.bind("<Control-s>", self.file_save) self.root.bind("<Control-S>", self.file_save) self.scriptField.bind("<Control-O>", self.file_open_textbox) self.scriptField.bind("<Control-o>", self.file_open_textbox) # self.root.bind_class("Text", ",<Control-z>", self.undo) # self.root.bind_class("Text", ",<Control-Z>", self.undo) # self.root.bind_class("Text", ",<Control-y>", self.redo) # self.root.bind_class("Text", ",<Control-Y>", self.redo) self.root.bind("<F5>", self.simulate_thread) self.root.bind("<F1>", self.open_documentation_offline) def undo(self, event=None): self.scriptField.undo() def redo(self, event=None): self.scriptField.redo() def open_documentation_offline(self, event=None): url = f".{SEP}docs{SEP}_build{SEP}html{SEP}index.html" webbrowser.open(url, new=True) def open_documentation_online(self, event=None): url = "https://learningsimulator.readthedocs.io/en/latest/" webbrowser.open(url, new=True) def open_licensedlg(self): LicenseDlg(self, include_agree_buttons=False)
def parse(text): script = Script(text) script.parse() return script.script_parser.parameters.val[STIMULUS_ELEMENTS]
def parse(text): script = Script(text) script.parse() return script.script_parser.parameters.val[BEHAVIORS]
def parse(text): script = Script(text) script.parse() return script.script_parser.variables.values