Example #1
0
class GameManager(object):
    
    @classmethod
    def for_options(cls, options):
        subclasses = LeafSubclassRetriever(cls).value()
        manager_class = filter(lambda subclass: subclass.handles(options),
                               subclasses)[0]
        return manager_class(options)
    
    @classmethod
    def handles(cls, options):
        raise NotImplementedError('Subclass responsibility')    
    
    def __init__(self, options):
        self.options = options
        self.judge = Judge(self)
        
    def get_programs(self):
        return [self.options.prog1, self.options.prog2]      
        
    def start(self):
        self.judge.run()
        
    def end(self):
        logging.log(logging.INFO,
                    'Batalla finalizada! Mostrando resultados...')        
        self.display_results()        
    
    def process_actions(self, actions):
        raise NotImplementedError('Subclass responsibility')
    
    def process_soldiers(self, soldiers):
        raise NotImplementedError('Subclass responsibility')
    
    def display_results(self):
        raise NotImplementedError('Subclass responsibility')
Example #2
0
#!/usr/bin/env python

import sys, os

try:
    from judge import Judge
    from judge import STDIO, FILE
except:
    path = os.path.realpath(__file__)
    path = os.path.split(path)[0]
    path = os.path.join(path, "..")
    path = os.path.join(path, "..")
    sys.path.append(path)
    from judge import Judge
    from judge import STDIO, FILE

if __name__=="__main__":
    judge = Judge()
    judge.add_test(["sh", "1.sh",], "11",       style=STDIO)
    judge.add_test(["sh", "2.sh",], "17",       style=STDIO)
    judge.add_test(["sh", "3.sh",], "b\ne",     style=STDIO)
    judge.add_test(["sh", "4.sh",], "4.out",    style=FILE)
    judge.run()
Example #3
0
class Prog(QtGui.QMainWindow):
    """This is the MAIN program, this is the start point,
     nothing should be calle from doutside of this class.
    
    Arguments:
        QtGui.QMainWindow {QMainWindow object } -- QMainWindow legacy
    
    Returns:
        [None] -- Just run until it closed
    """
    def __init__(self):
        super().__init__(None)

        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.timer = QtCore.QTimer(self)

        #set up the log tab
        logTextBox = QTextEditLogger(self)

        logTextBox.setFormatter(
            logging.Formatter(
                '"%(asctime)s - %(levelname)s \t- %(module)s \t- %(funcName)s ::  %(message)s"'
            ))
        logging.getLogger().addHandler(logTextBox)
        layout_log = QtWidgets.QVBoxLayout()
        layout_log.addWidget(logTextBox.widget)
        self.ui.tab_log.setLayout(layout_log)
        logger.info("--- Start ---")
        logger.info("Python : " + str(sys.version))
        logger.info("Prog  version : " + str(__version__))
        logger.info("-------")

        #Set up variable
        self.flight = None
        self.visualizer_3d = None
        self.judge = None
        self.load_judge_file()

        #add Action
        self.ui.actionOpen.triggered.connect(self.open_pickle_file)
        self.ui.actionSave_as.triggered.connect(self.save_pickle_file)
        self.ui.actionimport.triggered.connect(self.import_log_window)
        self.ui.actionVersion.triggered.connect(self.about_popup)
        self.ui.actionHelp.triggered.connect(self.openUrl_help)
        self.ui.actiondebug_open.triggered.connect(self.debug)

        self.ui.treeWidget.itemClicked.connect(self.onTreeItemClicked)
        self.ui.treeWidget.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
        self.ui.treeWidget.customContextMenuRequested.connect(self.openMenu)

        #setup Qtree
        self.ui.treeWidget.setHeaderLabels(["Name", "Kind", "Id"])

        #setup table view detail section
        self.ui.model = QtGui.QStandardItemModel(self)
        self.ui.tableView.setModel(self.ui.model)
        self.ui.model.dataChanged.connect(self.on_datachange_model)

        #setup iteractive console
        ## build an initial namespace for console commands to be executed in (this is optional;
        ## the user can always import these modules manually)
        namespace = {'prog': self, "Kind": Kind}
        ## initial text to display in the console
        text = " This is an interactive python console \n the following namespace are imported:\n" + str(
            list(namespace.keys())) + " \n  Go, play."

        self.c = pyqtgraph.console.ConsoleWidget(namespace=namespace,
                                                 text=text)
        mainLayout_console = QtWidgets.QVBoxLayout()
        mainLayout_console.addWidget(self.c)
        self.ui.tab_console.setLayout(mainLayout_console)
        logger.info(" interactive console ready")

    def debug(self):
        ''' only use for speed up de developement
        '''
        self.open_pickle_file(
            "samples/Flight2_gourdon_v0-2-0.pkl")  #linux path

    def load_judge_file(self, judge_path="judge1.json"):
        try:
            self.judge = Judge(judge_path)
        except Exception as ex:
            logger.error(ex)

    def open_pickle_file(self, filename=None):
        """Function to import a file already saved, format is classic python pickle .pkl
        
        Keyword Arguments:
            filename {[str]} -- if a path is given the browse dialog do not open ( use for debug function) (default: {None})
        
        Returns:
            [None] -- But saved the nex loaded flight in the main self.Flight object.
        """

        if filename == False:
            filename = QtGui.QFileDialog.getOpenFileName(
                self, 'Open pickler File', "", 'Pickle Files (*.pkl)')

        if isinstance(filename, tuple):
            filename = filename[0]
        if filename:
            try:
                logger.info(" importing : " + str(filename))
                self.file_name = filename
                self.id = 0
                with open(filename, 'rb') as pickle_file:
                    self.flight = pickle.load(pickle_file)

                #Check for version of the opened file
                if hasattr(self.flight, 'flight_version'):
                    if int(self.flight.flight_version
                           ) < __pickle_file_version__:
                        logger.info(" !! Importing Old file format: " +
                                    str(self.flight.flight_version) +
                                    " current is: " +
                                    str(__pickle_file_version__))
                else:
                    logger.info(
                        " !! Importing a file without flight_version info: version can not be checked "
                    )

                self.update_project_tree()

            except Exception as ex:
                logger.error(ex)

    def save_pickle_file(self):
        """Save the current self.Flight object to a pickle file. (.pkl)
        """
        try:
            tuple_saved_file = QtGui.QFileDialog.getSaveFileName(
                self, 'Save File', '', 'Pickle(*.pkl)')
            name_saved_file = tuple_saved_file[0] + '.pkl'
            logger.info("Saving as : " + name_saved_file[0] + '.pkl')
            with open(name_saved_file, "wb") as f:
                pickle.dump(self.flight, f)

        except Exception as ex:
            logger.error(ex)

    def import_log_window(self):
        """Function will display a other dialog to fill for loading a raw  log file
        the dialog will auto close when the import is finish.
        """
        widget_import_new = import_log_diaglog()
        widget_import_new.exec_()
        logger.debug("back in main prog")
        try:  # try to copy the flight object from the dialog windows to the main Flight object
            self.flight = widget_import_new.imported_Flight
            self.update_project_tree()
        except Exception as ex:
            logger.warning(ex)

    def about_popup(self):
        """ About section 
        Display various info for debug and system details
        TODO ; having a better list of the enviroment module and their version.
        """

        # from https://stackoverflow.com/questions/54447535/how-to-fix-typeerror-in-qtwidgets-qmessagebox-for-popup-messag
        cwd = os.path.dirname(os.path.abspath(__file__))

        log_content = getSystemInfo()

        msg = QtWidgets.QMessageBox()
        msg.setIcon(QtWidgets.QMessageBox.Information)
        msg.setText("Version : " + str(__version__) + "\n"
                    "pkl file version: " + str(log_file_name) + "\n"
                    "Log file name: " + str(__pickle_file_version__) + "\n"
                    "curent working directory: " + str(cwd))
        msg.setInformativeText(
            "More info on :\nhttps://github.com/fredvol/paralogger ")
        msg.setWindowTitle("About")
        msg.setDetailedText(log_content)
        msg.setStandardButtons(
            QtWidgets.QMessageBox.Ok)  #| QtWidgets.QMessageBox.Cancel)

        retval = msg.exec_()

    def openUrl_help(self):
        """Open github page in browser
        """
        url = QtCore.QUrl('https://github.com/fredvol/paralogger')
        if not QtGui.QDesktopServices.openUrl(url):
            QtGui.QMessageBox.warning(self, 'Open Url', 'Could not open url')

    ### TREE VIEW  ###
    # Tree view will display the flight and all the sections attach to.

    def update_project_tree(self):
        """repopulated the tree view , to show modif.
        """
        logger.info("update_project_tree")
        tw = self.ui.treeWidget
        tw.clear()
        if self.flight != None:
            l1 = QtWidgets.QTreeWidgetItem(
                [self.flight.glider, "--", self.flight.id])

            for sect in self.flight.sections:
                l1_child = QtWidgets.QTreeWidgetItem([
                    str(sect.start) + " - " + str(sect.end),
                    str(sect.kind.value), sect.id
                ])
                l1.addChild(l1_child)

            tw.addTopLevelItem(l1)
            tw.expandAll()
        else:
            logger.info(" Flight  is empty, nothing to display")

    def get_level_from_index(self, indexes):
        """Return the level in the treeview
        level 0 = Flight
        level 1 = Section
        
        Arguments:
            indexes {[QModelIndex]} -- not realy clear for me !
        
        Returns:
            level [Int]  -- The level of the cliked item
        """

        if len(indexes) > 0:
            level = 0
            index = indexes[0]
            while index.parent().isValid():
                index = index.parent()
                level += 1
        else:
            level = -1

        return level

    @QtCore.pyqtSlot(QtWidgets.QTreeWidgetItem, int)
    def onTreeItemClicked(self, it, col):
        """function trigered when an object is cliked on the tree view
        This a central function which dispath the work to the other objects .
        
        Arguments:
            it {QTreeWidgetItem} -- item cliked
            col {int} -- index of  columns cliked
        """

        indexes = self.ui.treeWidget.selectedIndexes()

        level = self.get_level_from_index(indexes)

        if level >= 0:  # if a Flight or a Section
            uid = it.text(2)  # The text of the node.
            logger.debug("clicked: " + str(it) + ", " + str(col) + ", " +
                         str(uid) + " level: " + str(level))
        else:
            uid = None

        #Job dispatching
        if level == 0:  # flight  level
            self.populate(uid, level)
            self.display_tab_Table(None)

        elif level == 1:  # section level
            #update all tabs
            self.display_tab_graph(uid)
            self.display_tab_Table(uid)
            self.display_tab_3D(uid)
            self.display_tab_analysis(uid)

            self.populate(uid, level)

    def openMenu(self, position):
        """Open contextual menu in tree View widget
        
        Arguments:
            position {[type]} -- [description]
        """
        indexes = self.ui.treeWidget.selectedIndexes()
        item = self.ui.treeWidget.itemAt(position)

        menu = QtWidgets.QMenu()

        level = self.get_level_from_index(indexes)
        if level > 0 and item != None:
            uid = item.text(2)  # The UId of teh object

        if level == 0:  # Flight
            action_add = menu.addAction(self.tr("Add Section"))
            action_add.triggered.connect(self.add_section)
            action_refresh = menu.addAction(self.tr("Refresh"))
            action_refresh.triggered.connect(self.update_project_tree)

            action_export_csv = menu.addAction('Export CSV')
            action_export_csv.triggered.connect(
                lambda: self.export_df(expformat="csv"))

            action_export_xls = menu.addAction('Export XLSX')
            action_export_xls.triggered.connect(
                lambda: self.export_df(expformat="xlsx"))

            action_export_xls = menu.addAction('Export device parameters')
            action_export_xls.triggered.connect(self.export_device_param)

        elif level == 1:  #Section
            action_export_csv = menu.addAction('Export CSV')
            action_export_csv.triggered.connect(
                lambda: self.export_df(uid, expformat="csv"))

            action_export_xls = menu.addAction('Export XLSX')
            action_export_xls.triggered.connect(
                lambda: self.export_df(uid, expformat="xlsx"))

            action_del = menu.addAction('Delete')
            action_del.triggered.connect(lambda: self.delete_section(uid))

            action_refresh = menu.addAction(self.tr("Refresh"))
            action_refresh.triggered.connect(self.update_project_tree)

        menu.exec_(self.ui.treeWidget.viewport().mapToGlobal(position))

    def delete_section(self, uid):
        """Delete the a Section from the self.Flight and refresh
        
        Arguments:
            uid {Str} -- Uid of the Section to delete
        """
        logger.info("delete section :" + str(uid))
        self.flight.delete_section(uid)
        self.update_project_tree()

    def add_section(self):
        """Add a section in self.Flight
        By default  there start from 0 to the end.
        """
        logger.info("add section")
        self.flight.add_general_section()
        self.update_project_tree()

    def export_device_param(self):
        """ Export the internal parameters of the PX4 
        TODO  not avaible if not PX4 filter
        """

        df_param = self.flight.data[0].device_param
        tuple_export_file = QtGui.QFileDialog.getSaveFileName(
            self, 'csv_file', '', '.csv')
        name_export_file = tuple_export_file[0] + '.csv'
        with open(name_export_file, 'w', newline="") as csv_file:
            writer = csv.writer(csv_file)
            for key, value in df_param.items():
                writer.writerow([key, value])

        logger.info("Device parameters exported : " + str(name_export_file))

    def export_df(self, uid=None, expformat="csv"):
        """Export Dataframe  in different format
        
        Keyword Arguments:
            uid {str} -- Uid of the Section to export (default: {None})
            expformat {str} -- Format to export [csv , xlsx] (default: {"csv"})
        
        If UID is None then export the flight ( maybe change to use the level info, to be consitent)
        """
        # TODO add multi sheet( xlsx) or file (csv) if multi data_file in flight
        if uid != None:  # if it is a section
            df_to_export = self.flight.apply_section(uid)
        else:  # if not section passed , then export main df
            df_to_export = self.flight.get_df_by_position(Position.PILOT)[0]
        try:
            tuple_export_file = QtGui.QFileDialog.getSaveFileName(
                self, 'Export Dataframe File', '', '.' + str(expformat))
            name_export_file = tuple_export_file[0] + '.' + str(expformat)
            if expformat == 'csv':
                df_to_export.to_csv(name_export_file)
            elif expformat == 'xlsx':
                logger.info(
                    "Exporting to Excel can take a while, coffee time ...")
                df_to_export.to_excel(name_export_file)
            logger.info("Exported as : " + name_export_file)
        except Exception as ex:
            logger.error(ex)

    #### TAB WIDGET ACTIONS ###
    # This section manage all the Tab ins the view part of the main windows.

    def display_tab_3D(self, uid):
        """Call the Tab_3d.py  and generated a 3D view .
        
        Arguments:
            uid {str} -- id of the Section to display
        Nothing append if Flight is selected, only for Sections

        TODO reload data when other section are cliked ( only display the first cliked one)
        """

        df_to_plot = self.flight.apply_section(uid)
        ####

        self.visualizer_3d = Visualizer3D(self.ui.tab_3d)
        self.visualizer_3d.animation(df_to_plot, True, timer=self.timer)
        #empty actual area if exist
        if len(self.ui.tab_3d.children()) > 0:
            layout = self.ui.tab_3d.children()[0]
            deleteItemsOfLayout(layout)

            layout.addWidget(self.visualizer_3d.area)

        else:
            mainLayout = QtWidgets.QVBoxLayout()
            mainLayout.addWidget(self.visualizer_3d.area)
            self.ui.tab_3d.setLayout(mainLayout)

    def display_tab_analysis(self, uid):
        logger.debug(" in display_tab_analysis")
        logger.debug(self.judge)

        df_to_analysis = self.flight.apply_section(uid)
        section = self.flight.section_by_id(uid)

        logger.debug(section)
        logger.debug(df_to_analysis.info())

        if self.judge != None:
            hash_judge, hash_dict_crit = self.judge.hash_state()
            self.ui.label_judge_file.setText(str(self.judge))
            self.ui.label_hash_judge_value.setText(hash_judge)
            self.ui.label_hash_crit_value.setText(hash_dict_crit)

            table_analysis = self.ui.tableWidget_analysis

            result_section = self.judge.run(df_to_analysis, section.kind.value)

            column_name = ["Test", "Value", "unit", "Grade"]
            column_count = (len(column_name))

            table_analysis.setColumnCount(column_count)

            table_analysis.setHorizontalHeaderLabels(column_name)

            for key, value in result_section.items():
                currentRowCount = table_analysis.rowCount()

                table_analysis.insertRow(currentRowCount)
                table_analysis.setItem(currentRowCount, 0,
                                       QtGui.QTableWidgetItem(str(key)))
                table_analysis.setItem(
                    currentRowCount, 1,
                    QtGui.QTableWidgetItem(str(value["value"])))
                table_analysis.setItem(
                    currentRowCount, 2,
                    QtGui.QTableWidgetItem(str(value["unit"])))
                table_analysis.setItem(
                    currentRowCount, 3,
                    QtGui.QTableWidgetItem(str(value["grade"])))

    def display_tab_Table(self, uid):
        """ Display the Pilot dataframe  in a table
        
        Arguments:
            uid {str} -- id of the Section to display

        For Flight and Section.
        ! only for dataframe  at pilot position
        TODO : Manage if no pilot position is available
        """
        try:
            if uid != None:  # if it is a section
                df_to_plot = self.flight.apply_section(uid)
            else:  # if not section passed , then plot main df
                df_to_plot = self.flight.get_df_by_position(Position.PILOT)[0]

            model = pandasTableModel(df_to_plot)
            if len(self.ui.tab_table.children()) > 0:
                self.ui.tab_table.children()[1].setModel(model)
            else:
                mainLayout = QtWidgets.QVBoxLayout()

                view = QtWidgets.QTableView()
                view.setModel(model)

                mainLayout.addWidget(view)

                self.ui.tab_table.setLayout(mainLayout)
        except Exception as ex:
            logger.warning(ex)
            pass

    def display_tab_graph(self, uid):
        """PLot different Graph 

        Arguments:
            uid {str} -- id of the Section to display
        
        Work only for Section
        TODO: Display full Flight with the section part Highlighted.
        """

        df_to_plot = self.flight.apply_section(uid)
        inside_widget = generated_layout(df_to_plot)

        #empty actual area if exist
        if len(self.ui.tab_graph.children()) > 0:
            print("layout not empty")
            layout = self.ui.tab_graph.children()[0]
            deleteItemsOfLayout(layout)
            # Old code for deleting item
            # for i in reversed(range(layout.count())):
            #     widgetToRemove = layout.itemAt(i).widget()
            #     # remove it from the layout list
            #     layout.removeWidget(widgetToRemove)
            #     # remove it from the gui
            #     widgetToRemove.setParent(None)

            layout.addWidget(inside_widget)

        else:
            mainLayout = QtWidgets.QVBoxLayout()
            mainLayout.addWidget(inside_widget)
            self.ui.tab_graph.setLayout(mainLayout)

    ## DETAILS OBJECT

    def on_datachange_model(self, signal):
        """Function use to update the self.Flight object  when a value is changed in the Detail table view
        
        Arguments:
            signal {QModelIndex} -- Index of the modified cell

        TODO block the edition of enum type ( kind , device , position) or even better implement combobox on GUI
        """
        row = signal.row()  # retrieves row of cell that was double clicked
        column = signal.column(
        )  # retrieves column of cell that was double clicked
        cell_dict = self.ui.model.itemData(
            signal)  # returns dict value of signal
        cell_value = cell_dict.get(0)  # retrieve value from dict

        uid = self.ui.model.itemData(signal.sibling(0, 1)).get(0)

        index = signal.sibling(row, 0)
        index_dict = self.ui.model.itemData(index)
        index_value = index_dict.get(0)
        logger.debug(
            'Edited Row {}, Col {} value: {} index_value: {}, uid: {}'.format(
                row, column, cell_value, index_value, uid))

        ## Update the Data model ( self.flight) from the changed done in self.ui_model
        if self.flight.id == uid:
            setattr(self.flight, index_value, cell_value)
        else:
            for sect in self.flight.sections:
                if sect.id == uid:
                    setattr(sect, index_value, cell_value)

        ## Update tree view:
        self.update_project_tree()

    def populate(self, uid, level):
        """ Add data in the Table view , via model 
        Exxtract a Dict of of a object properties.
        ! model only accepts strings - must convert.
 
        Arguments:
            uid {str} -- ID of the object to display
            level {int} -- object cliked level ( FLight or Section)
        """

        logger.debug("display_properties of: " + str(uid))
        self.ui.model.clear()  # Clear th UI model notthe self.Flight

        if level == 0:
            dict_to_display = vars(self.flight)
        elif level == 1:
            dict_to_display = vars(self.flight.section_by_id(uid))

        for name, value in dict_to_display.items():
            row = []
            cell_name = QtGui.QStandardItem(str(name))

            if isinstance(value, Kind):
                cell_value = QtGui.QStandardItem(str(value))
                # TODO  display combobox with a list of option (QItemDelegate? )

            else:
                cell_value = QtGui.QStandardItem(str(value))

            row.append(cell_name)
            row.append(cell_value)

            self.ui.model.appendRow(row)
Example #4
0
#!/usr/bin/env python

import sys, os

try:
    from judge import Judge
    from judge import STDIO, FILE
except:
    path = os.path.realpath(__file__)
    path = os.path.split(path)[0]
    path = os.path.join(path, "..")
    path = os.path.join(path, "..")
    sys.path.append(path)
    from judge import Judge
    from judge import STDIO, FILE

if __name__ == "__main__":
    judge = Judge()
    judge.add_test([
        "sh",
        "1.sh",
    ], "11", style=STDIO)
    judge.add_test([
        "sh",
        "2.sh",
    ], "17", style=STDIO)
    #judge.add_test(["sh", "3.sh",], "b\ne",     style=STDIO)
    #judge.add_test(["sh", "4.sh",], "4.out",    style=FILE)
    judge.run()
Example #5
0
path_file = "judge1.json"

jdg = Judge(path_file)

# jdg.dict_criteria = criteria_dict_book

# jdg.save_judge("judge1.json")



# %%
# jdg2=Judge()

# print(jdg2)
# jdg2.load_judge('judge1.json')

# print(jdg2)


#%% process
for sect in flight.sections:

    print("\n section:" , sect)

    #get list of criteria
    df = flight.apply_section(sect.id)
    rst_section = jdg.run(df,sect.kind.value)
    print(rst_section)

# %%