示例#1
0
class MainForm(wx.Frame):
    # ----------------------------------------------------------------------
    def __init__(self):
        self.data_io = DataIO()
        self.input = None
        self.content_data = None
        self.execute_data, self.prior_1, self.prior_2, self.leave = None, None, None, None
        wx.Frame.__init__(self,
                          None,
                          wx.ID_ANY,
                          "Customer Segmentation",
                          size=(800, 640))

        self.panel = wx.Panel(self, wx.ID_ANY)
        status = self.CreateStatusBar()

        self.sizer = wx.BoxSizer(wx.VERTICAL)

        file_label = wx.StaticText(self.panel, -1, "Input:", (30, 20))
        self.InputPathTextBox = wx.TextCtrl(self.panel,
                                            -1,
                                            "",
                                            size=(200, -1),
                                            pos=(100, 21))
        self.browse_btn = wx.Button(self.panel, -1, "Browse", pos=(310, 20))
        self.Bind(wx.EVT_BUTTON, self.onOpenFile, self.browse_btn)

        # output_label = wx.StaticText(self.panel, -1, "Ket qua:", (30, 50))
        # self.OutputPathTextBox = wx.TextCtrl(self.panel, -1, "", size=(200, -1), pos=(100, 47))

        self.execute_btn = wx.Button(self.panel,
                                     -1,
                                     "Phân tích",
                                     pos=(400, 20))
        self.Bind(wx.EVT_BUTTON, self.onExecute, self.execute_btn)
        self.execute_btn.Disable()

        inform_label = wx.StaticText(self.panel, -1, "Tổng quát:", (30, 60))
        self.inform_txt = wx.TextCtrl(self.panel,
                                      -1,
                                      "",
                                      style=wx.TE_MULTILINE | wx.TE_READONLY,
                                      size=(463, 70),
                                      pos=(100, 60))

        self.prior1_btn = wx.Button(self.panel,
                                    -1,
                                    "Nhóm Ưu tiên 1",
                                    pos=(98, 140))
        self.Bind(wx.EVT_BUTTON, self.onOpenPrior1, self.prior1_btn)
        self.prior1_btn.Disable()

        self.prior2_btn = wx.Button(self.panel,
                                    -1,
                                    "Nhóm Ưu tiên 2",
                                    pos=(210, 140))
        self.Bind(wx.EVT_BUTTON, self.onOpenPrior2, self.prior2_btn)
        self.prior2_btn.Disable()

        self.leave_btn = wx.Button(self.panel,
                                   -1,
                                   "Dự đoán rời mạng",
                                   pos=(320, 140))
        self.Bind(wx.EVT_BUTTON, self.onOpenLeave, self.leave_btn)
        self.leave_btn.Disable()

        self.total_btn = wx.Button(self.panel,
                                   -1,
                                   "Toàn bộ các nhóm",
                                   pos=(443, 140))
        self.Bind(wx.EVT_BUTTON, self.onOpenTotal, self.total_btn)
        self.total_btn.Disable()

        self.chart_btn = wx.Button(self.panel, -1, "Biểu đồ", pos=(580, 140))
        self.Bind(wx.EVT_BUTTON, self.onOpenChart, self.chart_btn)
        self.chart_btn.Disable()

        self.save_btn = wx.Button(self.panel, -1, "Export", pos=(680, 140))
        self.Bind(wx.EVT_BUTTON, self.onSaveFile, self.save_btn)
        self.save_btn.Disable()

        self.data_grid = grid.Grid(self.panel, size=(780, 400), pos=(5, 180))
        self.data_grid.CreateGrid(20, 10)

        self.panel.SetSizer(self.sizer)

    def onOpenFile(self, event):
        dlg = wx.FileDialog(
            self,
            message="Choose a file",
            defaultDir='../data/',
            defaultFile="",
            wildcard="Excel files (*.xlsx, *.xls)|*.xlsx; *.xls",
            style=wx.FD_OPEN | wx.FD_CHANGE_DIR | wx.FD_FILE_MUST_EXIST)
        if dlg.ShowModal() == wx.ID_OK:
            path = dlg.GetPaths()
            # print("You chose the following file:", path)
            self.InputPathTextBox.ChangeValue(path[0])
            self.input = path[0]
            data = self.data_io.import_data(path[0])
            self.content_data = self.fill_grid_data(data)
            self.execute_btn.Enable()
            self.prior1_btn.Disable()
            self.prior2_btn.Disable()
            self.leave_btn.Disable()
            self.total_btn.Disable()
            self.chart_btn.Disable()
            self.save_btn.Disable()
            self.inform_txt.ChangeValue('')
        dlg.Destroy()

    def onOpenPrior1(self, event):
        self.fill_grid_data(self.prior_1)

    def onOpenPrior2(self, event):
        self.fill_grid_data(self.prior_2)

    def onOpenLeave(self, event):
        self.fill_grid_data(self.leave)

    def onOpenTotal(self, event):
        self.fill_grid_data(self.execute_data)

    def onSaveFile(self, event):
        dlg = wx.FileDialog(
            self,
            message="Save as",
            defaultDir='../data/',
            defaultFile="",
            wildcard="Excel files (*.xlsx, *.xls)|*.xlsx; *.xls",
            style=wx.FD_SAVE)
        if dlg.ShowModal() == wx.ID_OK:
            path = dlg.GetPaths()[0]
            self.data_io.export_data(self.execute_data, path)
            # print("You chose the following file:", self.path)
        dlg.Destroy()

    def onExecute(self, event):
        if not self.content_data:
            msg = "You have an error.\nPlease reopen data file"
            self.show_error_dialog(msg, "ERROR", wx.OK | wx.ICON_EXCLAMATION)
        else:

            executed_data, prior_1, prior_2, leave = classify(
                self.content_data)
            self.execute_data = executed_data
            self.fill_grid_data(self.execute_data)
            self.prior_1 = prior_1
            self.prior_2 = prior_2
            self.leave = leave

            nums = len(self.content_data) - 1
            summary = 'Tổng số thuê bao: {}\n'.format(
                len(self.content_data) - 1)
            rate = 100 * (len(self.prior_1) - 1) / nums
            summary += 'Số thuê bao ưu tiên 1: {0} ({1:.2f}%)\n'.format(
                len(self.prior_1) - 1, round(rate, 2))
            rate = 100 * (len(self.prior_2) - 1) / nums
            summary += 'Số thuê bao ưu tiên 2: {0} ({1:.2f}%)\n'.format(
                len(self.prior_2) - 1, round(rate, 2))
            rate = 100 * (len(self.prior_1) - 1) / nums
            summary += 'Số thuê bao dự đoán rời mạng: {0} ({1:.2f}%)'.format(
                len(self.leave) - 1, round(rate, 2))
            self.inform_txt.ChangeValue(summary)
            self.prior1_btn.Enable()
            self.prior2_btn.Enable()
            self.leave_btn.Enable()
            self.total_btn.Enable()
            self.save_btn.Enable()
            self.chart_btn.Enable()
            # else:
            #     msg = "Something error. Please try again."
            #     self.show_error_dialog(msg, "ERROR", wx.OK | wx.ICON_EXCLAMATION)

    def onOpenChart(self, event):
        self.draw()

    def show_error_dialog(self, msg, title, style):
        dlg = wx.MessageDialog(parent=None,
                               message=msg,
                               caption=title,
                               style=style)
        dlg.ShowModal()
        dlg.Destroy()

    def fill_grid_data(self, data):
        # print(data[11])
        current_nrows, new_nrows = (self.data_grid.GetNumberRows(), len(data))
        if current_nrows < new_nrows:
            self.data_grid.AppendRows(new_nrows - current_nrows)
        elif current_nrows > new_nrows:
            self.data_grid.DeleteRows(new_nrows, current_nrows - new_nrows)
        current_ncols, new_ncols = (self.data_grid.GetNumberCols(),
                                    len(data[0]))
        if current_ncols < new_ncols:
            self.data_grid.AppendCols(new_ncols - current_ncols)
        elif current_ncols > new_ncols:
            self.data_grid.DeleteCols(new_ncols, current_ncols - new_ncols)

        for i in range(new_ncols):
            self.data_grid.SetCellValue(0, i, str(data[0][i]))

        for row in range(1, new_nrows):
            for col in range(new_ncols):
                self.data_grid.SetCellValue(row, col, str(data[row][col]))
        return data

    def draw(self):
        labels = ['Nhóm Ưu tiên 1', 'Nhóm Ưu tiên 2', 'Dự đoán rời mạng']
        sizes = [
            len(self.prior_1) - 1,
            len(self.prior_2) - 1,
            len(self.leave) - 1
        ]
        explode = (0, 0, 0.1)

        fig, ax = plt.subplots()
        fig.canvas.set_window_title('Biểu đồ')
        plt.title('Tỉ lệ các nhóm thuê bao')
        ax.pie(sizes,
               explode=explode,
               labels=labels,
               autopct='%1.1f%%',
               shadow=True,
               startangle=90)
        ax.axis('equal')

        plt.tight_layout()
        plt.show()