from django import forms

from .mixins import APIFormMixin

from utils.api.client import MarketAccessAPIClient
from utils.forms import (
    ChoiceFieldWithHelpText,
    ClearableMixin,
    DayMonthYearField,
    MultipleChoiceFieldWithHelpText,
    YesNoBooleanField,
    YesNoDontKnowBooleanField,
)

class UpdateCommercialValueForm(APIFormMixin, forms.Form):
    commercial_value = forms.IntegerField(
        min_value=0,
        max_value=1000000000000,
        localize=True,
        label="What is the value of the barrier to the affected business(es) in GBP?",
        error_messages={
            "required": "Enter a value",
            "min_value": "Enter a valid number",
            "max_value": "Enter a valid number",
        },
    )
    commercial_value_explanation = forms.CharField(
        widget=forms.Textarea,
        error_messages={"required": "Enter a value description and timescale"},
    )

    def save(self):
        client = MarketAccessAPIClient(self.token)
        client.barriers.patch(id=self.id, **self.cleaned_data)

class UpdateBarrierTitleForm(APIFormMixin, forms.Form):
    title = forms.CharField(
        label="Suggest a title for this barrier",
        help_text=(
            "Include both the title or service name and the country being "
            "exported to, for example, Import quotas for steel rods in India."
        ),
        max_length=255,
        error_messages={
            "max_length": "Title should be %(limit_value)d characters or fewer",
            "required": "Enter a title for this barrier",
        },
    )

    def save(self):
        client = MarketAccessAPIClient(self.token)
        client.barriers.patch(id=self.id, title=self.cleaned_data["title"])

class UpdateBarrierProductForm(APIFormMixin, forms.Form):
    product = forms.CharField(
        label="What product or service is being exported?",
        max_length=255,
        error_messages={
            "max_length": "Product or service should be %(limit_value)d characters or fewer",
            "required": "Enter a product or service",
        },
    )

    def save(self):
        client = MarketAccessAPIClient(self.token)
        client.barriers.patch(id=self.id, product=self.cleaned_data["product"])

class UpdateBarrierSummaryForm(APIFormMixin, forms.Form):
    summary = forms.CharField(
        label="Give us a summary of the barrier and how you found out about it",
        widget=forms.Textarea,
        error_messages={"required": "Enter a brief description for this barrier"},
    )
    is_summary_sensitive = YesNoBooleanField(
        label="Does the summary contain OFFICIAL-SENSITIVE information?",
        error_messages={
            "required": (
                "Indicate if summary contains OFFICIAL-SENSITIVE information or not"
            )
        },
    )

    def save(self):
        client = MarketAccessAPIClient(self.token)
        client.barriers.patch(
            id=self.id,
            summary=self.cleaned_data["summary"],
            is_summary_sensitive=self.cleaned_data["is_summary_sensitive"],
        )

class UpdateBarrierSourceForm(APIFormMixin, forms.Form):
    CHOICES = [
        ("COMPANY", "Company"),
        ("TRADE", "Trade association"),
        ("GOVT", "Government entity"),
        ("OTHER", "Other "),
    ]
    source = forms.ChoiceField(
        label="How did you find out about the barrier?",
        choices=CHOICES,
        widget=forms.RadioSelect,
        error_messages={"required": "Select how you became aware of the barrier"},
    )
    other_source = forms.CharField(
        label="Please specify",
        required=False,
        max_length=255,
        error_messages={
            "max_length": "Other source should be %(limit_value)d characters or fewer",
        }
    )

    def clean(self):
        cleaned_data = super().clean()
        source = cleaned_data.get("source")
        other_source = cleaned_data.get("other_source")

        if source == "OTHER":
            if not other_source and "other_source" not in self.errors:
                self.add_error(
                    "other_source", "Enter how you became aware of the barrier"
                )
        else:
            cleaned_data["other_source"] = ""

    def save(self):
        client = MarketAccessAPIClient(self.token)
        client.barriers.patch(
            id=self.id,
            source=self.cleaned_data["source"],
            other_source=self.cleaned_data["other_source"],
        )

class UpdateBarrierPriorityForm(APIFormMixin, forms.Form):
    CHOICES = [
        ("UNKNOWN", "Unknown priority"),
        ("HIGH", "High priority"),
        ("MEDIUM", "Medium priority"),
        ("LOW", "Low priority"),
    ]
    priority = forms.ChoiceField(
        label="What is the priority of the barrier?",
        choices=CHOICES,
        widget=forms.RadioSelect,
        error_messages={"required": "Select a barrier priority"},
    )
    priority_summary = forms.CharField(
        label="Why did the priority change? (optional)",
        widget=forms.Textarea,
        required=False,
    )

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        initial_priority = kwargs.get("initial", {}).get("priority")
        if initial_priority == "UNKNOWN":
            self.fields[
                "priority_summary"
            ].label = "Why did you choose this priority? (optional)"

    def save(self):
        client = MarketAccessAPIClient(self.token)
        client.barriers.patch(
            id=self.id,
            priority=self.cleaned_data["priority"],
            priority_summary=self.cleaned_data["priority_summary"],
        )

class UpdateBarrierTermForm(APIFormMixin, forms.Form):
    CHOICES = [
        (
            1,
            "A procedural, short-term barrier",
            "for example, goods stuck at the border or documentation issue",
        ),
        (2, "A long-term strategic barrier", "for example, a change of regulation",),
    ]
    term = ChoiceFieldWithHelpText(
        label="What is the scope of the barrier?",
        choices=CHOICES,
        widget=forms.RadioSelect,
        error_messages={"required": "Select a barrier scope"},
    )

    def save(self):
        client = MarketAccessAPIClient(self.token)
        client.barriers.patch(
            id=self.id, term=self.cleaned_data["term"]
        )

class UpdateBarrierEndDateForm(ClearableMixin, APIFormMixin, forms.Form):
    end_date = DayMonthYearField(
        label="End date",
        help_text=(
            "For example, 30 11 2020. If you don't know the day, please enter 1 for "
            "the first of the month."
        ),
        error_messages={"required": "Enter the end date"},
    )

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        end_date = kwargs.get("initial", {}).get("end_date")
        if end_date:
            self.fields["end_date"].label = "Change end date"

    def clean_end_date(self):
        return self.cleaned_data["end_date"].isoformat()

    def save(self):
        client = MarketAccessAPIClient(self.token)
        client.barriers.patch(
            id=self.id,
            end_date=self.cleaned_data.get("end_date"),
        )

class UpdateBarrierTagsForm(APIFormMixin, forms.Form):
    tags = MultipleChoiceFieldWithHelpText(
        label="Is this issue caused by or related to any of the following?",
        choices=[],
        required=False,
    )

    def __init__(self, tags, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields["tags"].choices = tags

    def save(self):
        client = MarketAccessAPIClient(self.token)
        client.barriers.patch(id=self.id, tags=self.cleaned_data["tags"])

class UpdateTradeDirectionForm(APIFormMixin, forms.Form):
    trade_direction = forms.ChoiceField(
        label="Which trade direction does this barrier affect?",
        choices=[],
        widget=forms.RadioSelect,
        error_messages={"required": "Select a trade direction"},
    )

    def save(self):
        client = MarketAccessAPIClient(self.token)
        client.barriers.patch(
            id=self.id, trade_direction=self.cleaned_data["trade_direction"]
        )

    def __init__(self, trade_direction_choices, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields["trade_direction"].choices = trade_direction_choices

class CausedByTradingBlocForm(forms.Form):
    caused_by_trading_bloc = YesNoDontKnowBooleanField(
        label="",
        error_messages={
            "required": (
                "Indicate if the barrier was caused by the trading bloc"
            )
        },
    )

    def __init__(self, trading_bloc, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields["caused_by_trading_bloc"].label = (
            f"Was this barrier caused by a regulation introduced by "
            f"{trading_bloc['short_name']}?"
        )
        self.fields["caused_by_trading_bloc"].help_text = (
            self.get_help_text(trading_bloc.get("code"))
        )

    def get_help_text(self, trading_bloc_code):
        help_text = {
            "TB00016": (
                "Yes should be selected if the barrier is a local application of an EU "
                "regulation. If it is an EU-wide barrier, the country location should "
                "be changed to EU in the location screen."
            )
        }
        return help_text.get(trading_bloc_code, "")

class UpdateCausedByTradingBlocForm(APIFormMixin, CausedByTradingBlocForm):
    def save(self):
        client = MarketAccessAPIClient(self.token)
        client.barriers.patch(
            id=self.id,
            caused_by_trading_bloc=self.cleaned_data["caused_by_trading_bloc"],
        )

class UpdateEconomicAssessmentEligibilityForm(APIFormMixin, forms.Form):
    economic_assessment_eligibility = YesNoBooleanField(
        label="Is the barrier eligible for an initial economic assessment?",
        error_messages={
            "required": (
                "Select yes if the barrier is eligible for an initial economic assessment"
            )
        },
    )
    economic_assessment_eligibility_summary = forms.CharField(
        label="Why is this barrier not eligible for an initial economic assessment?",
        help_text="Please explain why this barrier is not eligible",
        max_length=1500,
        widget=forms.Textarea,
        required=False,
    )

    def clean(self):
        cleaned_data = super().clean()
        economic_assessment_eligibility = cleaned_data.get("economic_assessment_eligibility")
        economic_assessment_eligibility_summary = cleaned_data.get("economic_assessment_eligibility_summary")

        if economic_assessment_eligibility is False:
            if not economic_assessment_eligibility_summary:
                self.add_error(
                    "economic_assessment_eligibility_summary",
                    "Enter why this barrier is not eligible",
                )
        else:
            cleaned_data["economic_assessment_eligibility_summary"] = ""

    def save(self):
        client = MarketAccessAPIClient(self.token)
        client.barriers.patch(
            id=self.id,
            economic_assessment_eligibility=self.cleaned_data["economic_assessment_eligibility"],
            economic_assessment_eligibility_summary=self.cleaned_data["economic_assessment_eligibility_summary"],
        )


import torch
import torch.nn as nn
import torchvision
import torchvision.transforms as T
import torch.nn.functional as F
import random
import numpy as np
from point_net import PointNet

class FusionNet(nn.Module):
    def __init__(self, num_points = 1024):
        super(FusionNet, self).__init__()
        self.pointnet = PointNet(num_points = num_points)
        self.resnet = ResNet50Features(torchvision.models.resnet50(pretrained = True))
        self.fc1 = nn.Linear(3072, 512)
        self.fc2 = nn.Linear(512, 128)
        self.fc3 = nn.Linear(128, 24)

    def forward(self, points, image):
        pointnet_global_feature, _ = self.pointnet(points)
        resnet_feature = self.resnet(image)
        fusion_feature = torch.cat((pointnet_global_feature, resnet_feature), dim = 1)
        fc1 = F.relu(self.fc1(fusion_feature))
        fc2 = F.relu(self.fc2(fc1))
        fc3 = self.fc3(fc2)
        out = fc3.view(-1, 8, 3)
        return out

class DenseFusionNet(nn.Module):
    def __init__(self, num_points = 1024, return_all = False):
        super(DenseFusionNet, self).__init__()
        self.num_points = num_points
        self.return_all = return_all
        self.pointnet = PointNet(num_points = num_points, global_feat = False)
        self.resnet = ResNet50Features(torchvision.models.resnet50(pretrained = True))
        self.fc1 = nn.Linear(3136, 512)
        self.fc2 = nn.Linear(512, 128)
        self.fc3 = nn.Linear(128, 25)
        self.softmax = nn.Softmax(dim = 1)
        self.sigmoid = nn.Sigmoid()

    def forward(self, points, image, override_return_all = None):
        pointnet_point_features = self.pointnet(points)
        resnet_feature = self.resnet(image).view(-1, 2048, 1).repeat(1, 1, self.num_points)

        fusion_feature = torch.cat((pointnet_point_features, resnet_feature), dim = 1)
        fusion_feature = torch.transpose(fusion_feature, 1, 2)
        fusion_feature = fusion_feature.contiguous()
        fusion_feature = fusion_feature.view(-1, 3136)

        fc1 = F.relu(self.fc1(fusion_feature))
        fc2 = F.relu(self.fc2(fc1))
        fc3 = self.fc3(fc2)
        out = fc3.view(-1, self.num_points, 25)

        box_offsets = out[:, :, :24].view(-1, self.num_points, 8, 3)
        scores = out[:,:,24]

        if (override_return_all is not None and override_return_all == True) or (override_return_all is None and self.return_all):
            predicted_coords = box_offsets + points.unsqueeze(2)
            return predicted_coords, scores

        confidences = self.softmax(scores)
        best_confidences, best_confidence_indices = confidences.max(dim = 1)
        best_box_offsets = box_offsets[range(box_offsets.size()[0]), best_confidence_indices, :, :]
        predicted_coords = best_box_offsets + points[range(points.size()[0]), best_confidence_indices, :].unsqueeze(1)
        return predicted_coords, best_confidences

class ResNet50Features(nn.Module):
    def __init__(self, original_model):
        super(ResNet50Features, self).__init__()
        self.features = nn.Sequential(*list(original_model.children())[:-1]) # just remove last FC layer

    def forward(self, x):
        x = self.features(x)
        x = x.view(x.size()[0], x.size()[1])
        return x


liczba = float(input("Podaj liczbę: ").replace(',','.'))

x = liczba > 10
y = liczba <= 15
z = int(liczba) % 2 == 0

print(f'''Większa od 10: {x}
Mniejsza równa 15: {y}
Podzielna przez 2: {z}
''')


#!/usr/bin/env python
# -*- coding: UTF-8 -*-
#
# Author: David R
#

import wx
import numpy as np
import cv2
import tkinter as tk
import time
import os
from skimage.feature import peak_local_max
from skimage.morphology import watershed
from scipy import ndimage
from tkinter import filedialog

# INITIALIZE PATH
saveVerify_path = []
filename = 'path.config'
if '_MEIPASS2' in os.environ:
    filename = os.path.join(os.environ['_MEIPASS2'], filenamen)
for line in open(filename):
    saveVerify_path.append(line.rstrip('\n'))
print("Save path: " + saveVerify_path[0])
print("Verify path: " + saveVerify_path[1])

detailOutput = []

class MainFrame(wx.Frame):
    def __init__(self, *args, **kwds):
        # MainFrame.__init__
        kwds["style"] = kwds.get("style", 0) | wx.CAPTION | wx.CLIP_CHILDREN | wx.CLOSE_BOX | wx.MINIMIZE_BOX | wx.SYSTEM_MENU
        wx.Frame.__init__(self, *args, **kwds)
        self.btnSettingFolder = wx.BitmapButton(self, wx.ID_ANY, wx.Bitmap("Resources\\FolderButton2.bmp", wx.BITMAP_TYPE_ANY))
        self.btnAbout = wx.BitmapButton(self, wx.ID_ANY, wx.Bitmap("Resources\\AboutButton2.bmp", wx.BITMAP_TYPE_ANY))
        self.btnHelp = wx.BitmapButton(self, wx.ID_ANY, wx.Bitmap("Resources\\HelpButton2.bmp", wx.BITMAP_TYPE_ANY))
        self.panelIO = wx.Panel(self, wx.ID_ANY)
        self.panelVerify = wx.Panel(self, wx.ID_ANY)
        self.txtCtrlWBC = wx.TextCtrl(self, wx.ID_ANY, "\n", style=wx.TE_CENTRE | wx.TE_READONLY)
        self.btnOpenFile = wx.Button(self, wx.ID_ANY, "Open File", style=wx.BORDER_NONE)
        self.btnDetection = wx.Button(self, wx.ID_ANY, "Detect", style=wx.BORDER_NONE)
        self.btnVerify = wx.Button(self, wx.ID_ANY, "Verify", style=wx.BORDER_NONE)
        self.btnVerify.Disable()
        self.btnSave = wx.Button(self, wx.ID_ANY, "Save", style=wx.BORDER_NONE)
        self.btnSave.Disable()

        self.__set_properties()
        self.__do_layout()

        self.Bind(wx.EVT_BUTTON, self.btnSettingFolder_pressed, self.btnSettingFolder)
        self.Bind(wx.EVT_BUTTON, self.btnAbout_pressed, self.btnAbout)
        self.Bind(wx.EVT_BUTTON, self.btnHelp_pressed, self.btnHelp)
        self.Bind(wx.EVT_BUTTON, self.btnOpenFile_pressed, self.btnOpenFile)
        self.Bind(wx.EVT_BUTTON, self.btnDetection_pressed, self.btnDetection)
        self.Bind(wx.EVT_BUTTON, self.btnVerify_pressed, self.btnVerify)
        self.Bind(wx.EVT_BUTTON, self.btnSave_pressed, self.btnSave)

        # DEFINE IMG PATH
        self.img_path = ''

    def __set_properties(self):
        # MainFrame.__set_properties
        self.SetTitle("Unstained WBC Detection")
        _icon = wx.NullIcon
        _icon.CopyFromBitmap(wx.Bitmap("Resources\\IconProgram.png", wx.BITMAP_TYPE_ANY))
        self.SetIcon(_icon)
        self.SetBackgroundColour(wx.Colour(204, 50, 50))
        self.btnSettingFolder.SetToolTip("Setting Folder")
        self.btnSettingFolder.SetSize(self.btnSettingFolder.GetBestSize())
        self.btnAbout.SetBackgroundColour(wx.Colour(47, 47, 47))
        self.btnAbout.SetToolTip("About")
        self.btnAbout.SetSize(self.btnAbout.GetBestSize())
        self.btnHelp.SetToolTip("Help")
        self.btnHelp.SetSize(self.btnHelp.GetBestSize())
        self.panelIO.SetMinSize((600, 450))
        self.panelIO.SetBackgroundColour(wx.Colour(255, 255, 255))
        self.panelVerify.SetMinSize((600, 450))
        self.panelVerify.SetBackgroundColour(wx.Colour(255, 255, 255))
        self.txtCtrlWBC.SetMinSize((50, 22))
        self.txtCtrlWBC.SetFont(wx.Font(12, wx.SWISS, wx.NORMAL, wx.BOLD, 0, "Bahnschrift SemiBold"))
        self.btnOpenFile.SetMinSize((295, 40))
        self.btnOpenFile.SetBackgroundColour(wx.Colour(47, 47, 47))
        self.btnOpenFile.SetForegroundColour(wx.Colour(255, 255, 255))
        self.btnOpenFile.SetFont(wx.Font(14, wx.SWISS, wx.NORMAL, wx.BOLD, 0, "Bahnschrift SemiBold"))
        self.btnOpenFile.SetToolTip("Input file citra")
        self.btnDetection.SetMinSize((295, 40))
        self.btnDetection.SetBackgroundColour(wx.Colour(47, 47, 47))
        self.btnDetection.SetForegroundColour(wx.Colour(255, 255, 255))
        self.btnDetection.SetFont(wx.Font(14, wx.SWISS, wx.NORMAL, wx.BOLD, 0, "Bahnschrift SemiBold"))
        self.btnDetection.SetToolTip("Deteksi sel darah putih")
        self.btnVerify.SetMinSize((295, 40))
        self.btnVerify.SetBackgroundColour(wx.Colour(47, 47, 47))
        self.btnVerify.SetForegroundColour(wx.Colour(255, 255, 255))
        self.btnVerify.SetFont(wx.Font(14, wx.SWISS, wx.NORMAL, wx.BOLD, 0, "Bahnschrift SemiBold"))
        self.btnVerify.SetToolTip("Verifikasi hasil deteksi")
        self.btnSave.SetMinSize((295, 40))
        self.btnSave.SetBackgroundColour(wx.Colour(47, 47, 47))
        self.btnSave.SetForegroundColour(wx.Colour(255, 255, 255))
        self.btnSave.SetFont(wx.Font(14, wx.SWISS, wx.NORMAL, wx.BOLD, 0, "Bahnschrift SemiBold"))
        self.btnSave.SetToolTip("Simpan hasil deteksi")

    def __do_layout(self):
        # MainFrame.__do_layout
        sizer_24 = wx.BoxSizer(wx.VERTICAL)
        grid_sizer_1 = wx.FlexGridSizer(0, 4, 0, 0)
        sizer_26 = wx.BoxSizer(wx.HORIZONTAL)
        sizer_1 = wx.BoxSizer(wx.HORIZONTAL)
        sizer_2 = wx.BoxSizer(wx.HORIZONTAL)
        sizer_3 = wx.BoxSizer(wx.HORIZONTAL)
        sizer_4 = wx.BoxSizer(wx.HORIZONTAL)
        sizer_6 = wx.BoxSizer(wx.HORIZONTAL)
        sizer_5 = wx.BoxSizer(wx.HORIZONTAL)
        sizer_4.Add((10, 20), 0, 0, 0)
        sizer_5.Add(self.btnSettingFolder, 0, wx.ALIGN_BOTTOM | wx.LEFT | wx.RIGHT, 5)
        sizer_4.Add(sizer_5, 1, wx.EXPAND, 0)
        bitmap_1 = wx.StaticBitmap(self, wx.ID_ANY, wx.Bitmap("Resources\\LogoProgram.png", wx.BITMAP_TYPE_ANY))
        sizer_4.Add(bitmap_1, 0, wx.ALIGN_CENTER | wx.LEFT | wx.RIGHT, 10)
        sizer_6.Add((43, 20), 0, 0, 0)
        sizer_6.Add(self.btnAbout, 0, wx.ALIGN_BOTTOM | wx.LEFT | wx.RIGHT, 5)
        sizer_6.Add(self.btnHelp, 0, wx.ALIGN_BOTTOM, 0)
        sizer_6.Add((10, 20), 0, 0, 0)
        sizer_4.Add(sizer_6, 1, wx.EXPAND, 0)
        sizer_24.Add(sizer_4, 1, wx.EXPAND, 0)
        grid_sizer_1.Add((0, 0), 0, 0, 0)
        grid_sizer_1.Add((20, 10), 0, 0, 0)
        grid_sizer_1.Add((20, 10), 0, 0, 0)
        grid_sizer_1.Add((0, 0), 0, 0, 0)
        grid_sizer_1.Add((0, 0), 0, 0, 0)
        grid_sizer_1.Add((0, 0), 0, 0, 0)
        sizer_3.Add((0, 0), 0, 0, 0)
        sizer_3.Add((0, 0), 0, 0, 0)
        sizer_3.Add((0, 0), 0, 0, 0)
        grid_sizer_1.Add(sizer_3, 1, wx.EXPAND, 0)
        grid_sizer_1.Add((0, 0), 0, 0, 0)
        grid_sizer_1.Add((10, 20), 0, 0, 0)
        grid_sizer_1.Add(self.panelIO, 1, wx.BOTTOM | wx.EXPAND | wx.LEFT | wx.RIGHT, 5)
        grid_sizer_1.Add(self.panelVerify, 1, wx.BOTTOM | wx.EXPAND | wx.LEFT | wx.RIGHT, 5)
        grid_sizer_1.Add((10, 20), 0, 0, 0)
        grid_sizer_1.Add((0, 0), 0, 0, 0)
        label_4 = wx.StaticText(self, wx.ID_ANY, "Unstained WBC Image  |", style=wx.ALIGN_RIGHT)
        label_4.SetForegroundColour(wx.Colour(255, 255, 255))
        label_4.SetFont(wx.Font(14, wx.SWISS, wx.NORMAL, wx.BOLD, 0, "Bahnschrift SemiBold"))
        sizer_2.Add(label_4, 0, wx.ALIGN_RIGHT | wx.EXPAND | wx.LEFT, 114)
        label_1 = wx.StaticText(self, wx.ID_ANY, "Detected WBC:", style=wx.ALIGN_RIGHT)
        label_1.SetForegroundColour(wx.Colour(255, 255, 255))
        label_1.SetFont(wx.Font(14, wx.SWISS, wx.NORMAL, wx.BOLD, 0, "Bahnschrift SemiBold"))
        sizer_2.Add(label_1, 0, wx.ALIGN_RIGHT | wx.LEFT | wx.RIGHT, 5)
        sizer_2.Add(self.txtCtrlWBC, 0, wx.ALIGN_CENTER | wx.LEFT | wx.RIGHT, 5)
        grid_sizer_1.Add(sizer_2, 1, wx.EXPAND, 0)
        label_5 = wx.StaticText(self, wx.ID_ANY, "Stained WBC Image", style=wx.ALIGN_CENTER)
        label_5.SetForegroundColour(wx.Colour(255, 255, 255))
        label_5.SetFont(wx.Font(14, wx.SWISS, wx.NORMAL, wx.BOLD, 0, "Bahnschrift SemiBold"))
        grid_sizer_1.Add(label_5, 0, wx.EXPAND | wx.LEFT | wx.RIGHT, 5)
        grid_sizer_1.Add((0, 0), 0, 0, 0)
        grid_sizer_1.Add((0, 0), 0, 0, 0)
        sizer_1.Add(self.btnOpenFile, 0, wx.ALIGN_CENTER | wx.ALL, 5)
        sizer_1.Add(self.btnDetection, 0, wx.ALL, 5)
        grid_sizer_1.Add(sizer_1, 1, wx.EXPAND, 0)
        sizer_26.Add(self.btnVerify, 0, wx.ALL, 5)
        sizer_26.Add(self.btnSave, 0, wx.ALL, 5)
        grid_sizer_1.Add(sizer_26, 1, wx.EXPAND, 0)
        grid_sizer_1.Add((0, 0), 0, 0, 0)
        grid_sizer_1.Add((0, 0), 0, 0, 0)
        grid_sizer_1.Add((20, 10), 0, 0, 0)
        grid_sizer_1.Add((20, 10), 0, 0, 0)
        grid_sizer_1.Add((0, 0), 0, 0, 0)
        sizer_24.Add(grid_sizer_1, 1, wx.EXPAND, 0)
        self.SetSizer(sizer_24)
        sizer_24.Fit(self)
        self.Layout()

    def btnSettingFolder_pressed(self, event):
        # OPEN FRAME SETTING
        try:
            frame = SettingFrame(None, wx.ID_ANY, "")
            frame.Show()
        except:
            event.Skip()

    def btnAbout_pressed(self, event):
        # OPEN FRAME ABOUT
        try:
            frame = AboutFrame(None, wx.ID_ANY, "")
            frame.Show()
        except:
            event.Skip()

    def btnHelp_pressed(self, event):
        # OPEN FRAME HELP
        try:
            frame = HelpFrame(None, wx.ID_ANY, "")
            frame.Show()
        except:
            event.Skip()

    def btnOpenFile_pressed(self, event):
        # ----------------------------------------------------------------------
        # -------------------- OPEN AND READ IMAGE FILE ------------------------
        # ----------------------------------------------------------------------
        #open file dialog
        tk.Tk().withdraw()
        self.img_path = filedialog.askopenfilename(title="Select Image",
                                              filetypes=[(".JPG", "*.jpg")])

        if self.img_path:
            self.btnSave.Disable()
            self.btnVerify.Disable()
            self.txtCtrlWBC.SetValue("")
            try:
                # BUAT TAMPILIN KE PANEL
                self.bmp = wx.Image(self.img_path,wx.BITMAP_TYPE_JPEG)
                (w, h) = self.bmp.GetSize() # AMBIL SIZE IMG
                (wp, hp) = self.panelIO.GetSize()

                # kondisi resize image
                if h > hp:
                    h = hp
                if w > wp:
                    w = wp

                # SCALE + CONVERT TO BITMAP
                self.bmp = self.bmp.Scale(w,h).ConvertToBitmap()

                # TARO KE PANEL
                self.obj = wx.StaticBitmap(self.panelIO, -1, self.bmp,(0,0),(wp, hp))
                self.obj.Refresh()

                # CLEAR VERIFY PANEL (setiap openfile, clear panel verify)
                (wp, hp) = self.panelVerify.GetSize()
                emptyImg = wx.Image(wp, hp, True) # create empty image (black)
                emptyImg.Replace(0,0,0,255,255,255) # replace ke 255 (white)
                self.obj = wx.StaticBitmap(self.panelVerify, -1, emptyImg.ConvertToBitmap(),(0,0),(wp, hp))
                self.obj.Refresh()

                # clear detailOutput
                detailOutput.clear()
            except:
                wx.MessageBox(message="Gagal input citra!",
                                      caption='Load Failed',
                                      style=wx.OK | wx.ICON_ERROR)

    def btnDetection_pressed(self, event):
        def detection(img_path):
            detailOutput.clear()
            try:
                img = cv2.imread(img_path, 1) # read img
                detailOutput.append(img) #DETAIL 0
                img = cv2.resize(img,None,fx=0.32, fy=0.32, interpolation = cv2.INTER_AREA) # resize img
                detectedWBC = img.copy()   # reserve for detected WBC area
##                cv2.imshow('original',img)

                # start timer
                timeExec = time.time()

                # ----------------------------------------------------------------------
                # ------------------------- GAMMA CORRECTION ---------------------------
                # ----------------------------------------------------------------------
                def adjust_gamma(image, gamma=1.0):
                    invGamma = 1.0 / gamma
                    table = np.array([((i / 255.0) ** invGamma) * 255
                                     for i in np.arange(0, 256)]).astype("uint8")

                    return cv2.LUT(image.astype(np.uint8), table.astype(np.uint8))

                gamma = 0.4   # ubah gamma value
                img = adjust_gamma(img, gamma=gamma)

                # ----------------------------------------------------------------------
                # ----------------------- Extracting Image Saturation n Filtering  -------------------------
                # ----------------------------------------------------------------------
                #-----Converting image to HSV Color model-----------------------------------
                hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

                #Split HSV
                h, s, v = cv2.split(hsv)

                #CLAHE pada Saturation
                clahe = cv2.createCLAHE(clipLimit=15.0, tileGridSize=(8,8))
                cl = clahe.apply(s)

                #Merge
                limg = cv2.merge((cl,s,v))

                #Convert to RGB
                final = cv2.cvtColor(limg, cv2.COLOR_LAB2BGR)
                detailOutput.append(final.copy()) #DETAIL 1

                # ----------------------------------------------------------------------
                # ----------------------- PRE-PROCESSING IMAGE -------------------------
                # ----------------------------------------------------------------------
                # SMOOTHING AND SHARPENING
                final = cv2.GaussianBlur(final, (5,5), 0)
                detailOutput.append(final) #DETAIL 2
                kernel = np.array([[-1,-1,-1],
                                   [-1,9,-1],
                                   [-1,-1,-1]])
                final = cv2.filter2D(final, -1, kernel)
                detailOutput.append(final.copy()) #DETAIL 3

                # GRAYSCALE, THRESHOLD, MORPHOLOGICAL OPERATION
                gray = cv2.cvtColor(final, cv2.COLOR_BGR2GRAY)
                gray = cv2.GaussianBlur(gray, (7,7), 0)
                detailOutput.append(gray.copy()) #DETAIL 4
                ret, thresh = cv2.threshold(gray,0,255,cv2.THRESH_OTSU)

                # create copy untuk var global detail
                detailOutput.append(thresh.copy()) #DETAIL 5

                # Morph Operation
                kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(3,3))
                ##kernel2 = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(5,5))
                ##opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel)
                ##close = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel2)
                dilate = cv2.dilate(thresh,kernel,iterations = 1)
                tempMorph = dilate.copy()
##                cv2.imshow('Morph', tempMorph)

                # FILLING HOLES
                _,contour,hier = cv2.findContours(tempMorph,cv2.RETR_CCOMP,cv2.CHAIN_APPROX_SIMPLE)

                for cnt in contour:
                    cv2.drawContours(tempMorph,[cnt],0,255,-1)

                detailOutput.append(tempMorph.copy()) #DETAIL 6
##                cv2.imshow('Filling Holes', tempMorph)
##                cv2.waitKey(0)
##                cv2.destroyAllWindows()

                # ----------------------------------------------------------------------
                # ---------------------- WATERSHED SEGMENTATION ------------------------
                # ----------------------------------------------------------------------
                # REMOVE NOISE
                tempMorph = cv2.morphologyEx(tempMorph,cv2.MORPH_OPEN,kernel, iterations = 2)
##                cv2.imshow('Noise Removal', tempMorph)
##                cv2.waitKey(0)
##                cv2.destroyAllWindows()

                # DISTANCE TRANSFORM USING EUCLIDEAN DISTANCE
                D = ndimage.distance_transform_edt(tempMorph)
                localMax = peak_local_max(D, indices=False, min_distance=8, labels=thresh)

                # LABELLING USING CCA AND APPLY WATERSHED
                markers = ndimage.label(localMax, structure=np.ones((3, 3)))[0]
                labels = watershed(-D, markers, mask=tempMorph)
                print("[INFO] {} unique segments found".format(len(np.unique(labels)) - 1))

                # LOOPING UNTUK SETIAP LABEL WATERSHED
                for label in np.unique(labels):
                   # jika label 0 = background, skip.
                   if label == 0:
                       continue

                   # selain label 0, maka dianggap area segmen RBC dan dijadikan hitam (blackout area)
                   mask = np.zeros(gray.shape, dtype="uint8")
                   dilate[labels == label] = 0

                detailOutput.append(dilate.copy()) #DETAIL 7
                # output image
##                cv2.imshow("Output", dilate)
##                cv2.waitKey(0)

                # ----------------------------------------------------------------------
                # ------------------------- POST-PROCESSING ----------------------------
                # ----------------------------------------------------------------------
                # CLEANING
                tempClean = dilate.copy()
                kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(15,15))
                tempClean = cv2.dilate(tempClean, kernel)
                detailOutput.append(tempClean) #DETAIL 8
                ##tempClean = cv2.morphologyEx(tempClean, cv2.MORPH_OPEN, kernel)
##                cv2.imshow("Clean", tempClean)
##                cv2.waitKey(0)

                # CROP WBC AREA DAN TAMPILKAN PADA LAYAR
                _,contours,hier = cv2.findContours(tempClean, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)

                self.WBC_Count = 0
                self.croppedWBC = []
                self.xywh = []
                for cnt in contours:
                    temp = []
                    area = cv2.contourArea(cnt)
                    cv2.drawContours(img, cnt, -1, 255, 1)
                    x, y, w, h = cv2.boundingRect(cnt)
                    ratio = float(w)/h
                    if area < 4450 or area > 11400:
                      continue
                    if ratio < 0.5 or ratio > 2.3:
                      continue
                    self.croppedWBC.append(detectedWBC[y:y+h,x:x+w])
##                  cv2.imshow("Cropped WBC" + str(WBC_Count), self.croppedWBC[WBC_Count])
##                  cv2.drawContours(detectedWBC, cnt, -1, 255, 1)
                    cv2.rectangle(detectedWBC, (x,y), (x+w,y+h), (255,0,0), 1)
                    cv2.putText(detectedWBC, "Area={}".format(self.WBC_Count+1),(x,y-3),0,0.4,(255,0,0),1)
                    temp.extend([x,y,w,h])
                    self.xywh.append(temp)
                    self.WBC_Count += 1
                print(self.xywh)
                detailOutput.append(detectedWBC) #DETAIL 9
                # end timer
                timeExec = time.time() - timeExec

                #### save ####
##                cv2.imwrite("ValidNonWBC/HasilDeteksi/" + os.path.basename(self.img_path)[:-4] + ".jpg", detectedWBC)
                # TAMPILIN AREA WBC KE PANEL DAN TXT CTRL
                if self.WBC_Count > 0:
                    # SET NILAI txtCtrlWBC (menampilkan jumlah WBC yang terdeteksi)
                    self.txtCtrlWBC.SetValue(str(self.WBC_Count))

                    # MUNCULIN KE PANEL DAN RESIZE
                    (wPanel, hPanel) = self.panelIO.GetSize()
                    detectedWBC = cv2.resize(detectedWBC,(wPanel,hPanel), interpolation = cv2.INTER_AREA)
                    ####### save hasil deteksi ########
                    cv2.imwrite("Detection Output/" + os.path.basename(self.img_path)[:-4] + ".jpg", detectedWBC)
                    ###################################
                    detectedWBC = cv2.cvtColor(detectedWBC, cv2.COLOR_BGR2RGB)
                    wxImg = wx.ImageFromBuffer(detectedWBC.shape[1], detectedWBC.shape[0], detectedWBC)
##                    wxImg = wx.Bitmap.FromBuffer(detectedWBC.shape[1], detectedWBC.shape[0], detectedWBC)
##                    wxImg = wxImg.ConvertToImage()

##                    self.bmp = wx.Image(wxImg, wx.BITMAP_TYPE_ANY)
##                    self.bmp = self.bmp.Scale(wPanel,hPanel).ConvertToBitmap()
                    wxBitmap = wxImg.ConvertToBitmap()

                    # TARO KE PANEL
                    self.obj = wx.StaticBitmap(self.panelIO, -1, wxBitmap,(0,0),(wPanel, hPanel))
                    self.obj.Refresh()
                else:
                    self.txtCtrlWBC.SetValue("0")
                    wx.MessageBox(message="Sel darah putih tidak ditemukan.",
                              caption='WBC not found',
                              style=wx.OK | wx.ICON_INFORMATION)

##                cv2.imshow("Ouput Contours", img)
##                cv2.imshow("OuputWBC Contours", detectedWBC)
##                cv2.waitKey(0)
##                cv2.destroyAllWindows()
            except:
                wx.MessageBox(message="Deteksi gagal!",
                                      caption='Detection Failed',
                                      style=wx.OK | wx.ICON_ERROR)

            # MEASURE TIME
            img_name = os.path.basename(self.img_path)
            print("---- %s seconds ----" % (timeExec))
            timestr = time.strftime("%d-%m-%Y %H:%M:%S")
            file = open("time.txt", "a")
            file.write("Image file: " + img_name + "\n")
            file.write("Testing date: " + timestr + "\n")
            file.write("Detected WBC: " + str(self.WBC_Count) +"\n")
            file.write("Execution time: " + str(timeExec) + "\n---------------------------------------------\n")
            file.close()

        # ----------------------------------------------------------------------
        # ------------------------- START DETECTION ----------------------------
        # ----------------------------------------------------------------------
        if self.img_path:
            detection(self.img_path)
            self.btnVerify.Enable()
            if self.WBC_Count > 0:
                self.btnSave.Enable()
        else:
            wx.MessageBox(message="File citra tidak ditemukan!",
                                      caption='Masukkan Citra Input',
                                      style=wx.OK | wx.ICON_ERROR)

    def btnVerify_pressed(self, event):
        def image_resize(image, width = None, height = None, inter = cv2.INTER_AREA):
            dim = None
            (h, w) = image.shape[:2]
            if width is None and height is None:
                return image
            if width is None:
                r = height / float(h)
                dim = (int(w * r), height)
                print("W", dim)
                print(dim[0])
            else:
                r = width / float(w)
                dim = (width, int(h * r))
                print("h", dim)
                print(dim[0])
            resized = cv2.resize(image, dim, interpolation = inter)
            return resized

        try:
            # ambil hanya nama img (path paling akhir)
            img_name = os.path.basename(self.img_path)
            verify_path = saveVerify_path[1] + img_name

            # load image untuk kasi rectangle area
            verifyImg = cv2.imread(verify_path)
            for i in range(len(self.xywh)):
                cv2.rectangle(verifyImg, (self.xywh[i][0],self.xywh[i][1]),
                              (self.xywh[i][0]+self.xywh[i][2],
                               self.xywh[i][1]+self.xywh[i][3]), (255,0,0), 1)

            ## save verify image (ada box) ##
            cv2.imwrite("Detection Output/" + os.path.basename(self.img_path)[:-4] + "v.jpg", verifyImg)
            ####################
            verifyImg = cv2.cvtColor(verifyImg, cv2.COLOR_BGR2RGB)

            (wp, hp) = self.panelVerify.GetSize()
            (h, w, _) = verifyImg.shape # AMBIL SIZE IMG
            print (wp,hp, w, h)
            # kondisi resize image
            if h > hp:
                h = hp
            if w > wp:
                w = wp

            # klo pake img tanpa crop
##            verifyImg = cv2.resize(verifyImg, (w,h), interpolation = cv2.INTER_AREA)
            # klo pake img dengan crop
            verifyImg = image_resize(verifyImg, height = hp)
            (h, w, _) = verifyImg.shape
            if w > wp:
                verifyImg = image_resize(verifyImg, width = wp)

            wxBuffer = wx.ImageFromBuffer(verifyImg.shape[1], verifyImg.shape[0], verifyImg)
            # SCALE + CONVERT TO BITMAP
            wxBitmap = wxBuffer.ConvertToBitmap()
            # TARO KE PANEL
            self.obj = wx.StaticBitmap(self.panelVerify, -1, wxBitmap,(0,0),(wp, hp))
            self.obj.Refresh()
        except:
            wx.MessageBox(message="Citra untuk verifikasi tidak ditemukan!",
                                      caption='Image Verify Not Found',
                                      style=wx.OK | wx.ICON_ERROR)

    def btnSave_pressed(self, event):
        try:
            save_path = saveVerify_path[0]
            img_name = os.path.basename(self.img_path) # ambil nama img (path paling belakang)
            for i in range(self.WBC_Count): # save cropped area
                cv2.imwrite(save_path + img_name + "_" + str(i) + ".jpg", self.croppedWBC[i])

            # POP-UP success
            wx.MessageBox(message="Area deteksi berhasil disimpan: " + save_path,
                                  caption='Save Success',
                                  style=wx.OK | wx.ICON_INFORMATION)
        except:
            # POP-UP fail
            wx.MessageBox(message="Gagal menyimpan hasil deteksi!",
                                  caption='Save Failed',
                                  style=wx.OK | wx.ICON_ERROR)

# end of class MainFrame

class AboutFrame(wx.Frame):
    def __init__(self, *args, **kwds):
        # AboutFrame.__init__
        kwds["style"] = kwds.get("style", 0) | wx.CAPTION | wx.CLIP_CHILDREN | wx.CLOSE_BOX | wx.SYSTEM_MENU
        wx.Frame.__init__(self, *args, **kwds)
        self.SetSize((700, 360))
        self.AboutOK = wx.Button(self, wx.ID_ANY, "OK")

        self.__set_properties()
        self.__do_layout()

        self.Bind(wx.EVT_BUTTON, self.btnAboutOK_pressed, self.AboutOK)

    def __set_properties(self):
        # AboutFrame.__set_properties
        self.SetTitle("About Unstained WBC Detection")
        _icon = wx.NullIcon
        _icon.CopyFromBitmap(wx.Bitmap("Resources\\AboutButton2.bmp", wx.BITMAP_TYPE_ANY))
        self.SetIcon(_icon)
        self.SetBackgroundColour(wx.Colour(47, 47, 47))
        self.AboutOK.SetMinSize((200, 26))
        self.AboutOK.SetFont(wx.Font(10, wx.SWISS, wx.NORMAL, wx.BOLD, 0, "Bahnschrift SemiBold"))
        self.AboutOK.SetToolTip("Back to Home")

    def __do_layout(self):
        # AboutFrame.__do_layout
        sizer_27 = wx.BoxSizer(wx.VERTICAL)
        sizer_28 = wx.BoxSizer(wx.VERTICAL)
        grid_sizer_2 = wx.GridSizer(1, 1, 0, 0)
        label_6 = wx.StaticText(self, wx.ID_ANY, "UNSTAINED WHITE BLOOD CELL DETECTION\nVersion 2.1.0 (201118) Release", style=wx.ALIGN_CENTER)
        label_6.SetBackgroundColour(wx.Colour(47, 47, 47))
        label_6.SetForegroundColour(wx.Colour(0, 127, 255))
        label_6.SetFont(wx.Font(16, wx.SWISS, wx.NORMAL, wx.BOLD, 0, "Bahnschrift"))
        sizer_28.Add(label_6, 0, wx.ALIGN_CENTER | wx.ALL | wx.EXPAND, 20)
        label_7 = wx.StaticText(self, wx.ID_ANY, "Program pendeteksian sel darah putih pada citra \npreparat tanpa pewarnaan (unstained).", style=wx.ALIGN_CENTER)
        label_7.SetBackgroundColour(wx.Colour(47, 47, 47))
        label_7.SetForegroundColour(wx.Colour(255, 255, 255))
        label_7.SetFont(wx.Font(14, wx.SWISS, wx.NORMAL, wx.BOLD, 0, "Bahnschrift"))
        sizer_28.Add(label_7, 0, wx.ALIGN_CENTER | wx.ALL, 5)
        static_line_1 = wx.StaticLine(self, wx.ID_ANY, style=wx.LI_VERTICAL)
        static_line_1.SetMinSize((550, 2))
        sizer_28.Add(static_line_1, 0, wx.ALIGN_CENTER | wx.ALL, 10)
        label_11 = wx.StaticText(self, wx.ID_ANY, "David Reynaldo\nLina", style=wx.ALIGN_CENTER)
        label_11.SetBackgroundColour(wx.Colour(47, 47, 47))
        label_11.SetForegroundColour(wx.Colour(255, 255, 255))
        label_11.SetFont(wx.Font(12, wx.SWISS, wx.NORMAL, wx.BOLD, 0, "Bahnschrift"))
        grid_sizer_2.Add(label_11, 0, wx.ALIGN_CENTER | wx.EXPAND | wx.LEFT | wx.RIGHT, 30)
        sizer_28.Add(grid_sizer_2, 0, wx.EXPAND, 0)
        label_13 = wx.StaticText(self, wx.ID_ANY, "Fakultas Teknologi Informasi - Teknik Informatika\nUniversitas Tarumanagara (2018)", style=wx.ALIGN_CENTER)
        label_13.SetBackgroundColour(wx.Colour(47, 47, 47))
        label_13.SetForegroundColour(wx.Colour(255, 255, 255))
        label_13.SetFont(wx.Font(12, wx.SWISS, wx.NORMAL, wx.BOLD, 0, "Bahnschrift"))
        sizer_28.Add(label_13, 0, wx.ALIGN_CENTER | wx.ALL, 10)
        sizer_28.Add(self.AboutOK, 0, wx.ALIGN_CENTER | wx.LEFT | wx.RIGHT | wx.TOP, 10)
        sizer_27.Add(sizer_28, 1, wx.EXPAND, 0)
        self.SetSizer(sizer_27)
        self.Layout()

    def btnAboutOK_pressed(self, event):
        self.Close()

# end of class AboutFrame

class HelpFrame(wx.Frame):
    def __init__(self, *args, **kwds):
        # HelpFrame.__init__
        kwds["style"] = kwds.get("style", 0) | wx.DEFAULT_FRAME_STYLE
        wx.Frame.__init__(self, *args, **kwds)
        self.btnDetail = wx.Button(self, wx.ID_ANY, "Detail Program")
        self.HelpOK = wx.Button(self, wx.ID_ANY, "OK")

        self.__set_properties()
        self.__do_layout()
        self.cekDeteksi()

        self.Bind(wx.EVT_BUTTON, self.btnDetail_pressed, self.btnDetail)
        self.Bind(wx.EVT_BUTTON, self.btnHelpOK_pressed, self.HelpOK)

    def cekDeteksi(self):
        if not detailOutput:
            self.btnDetail.Disable()
        else:
            self.btnDetail.Enable()

    def __set_properties(self):
        # HelpFrame.__set_properties
        self.SetTitle("Help")
        _icon = wx.NullIcon
        _icon.CopyFromBitmap(wx.Bitmap("Resources\\HelpButton2.bmp", wx.BITMAP_TYPE_ANY))
        self.SetIcon(_icon)
        self.SetBackgroundColour(wx.Colour(47, 47, 47))
        self.btnDetail.SetMinSize((200, 26))
        self.btnDetail.SetFont(wx.Font(10, wx.SWISS, wx.NORMAL, wx.BOLD, 0, "Bahnschrift SemiBold"))
        self.btnDetail.SetToolTip("Detail Program")
        self.HelpOK.SetMinSize((200, 26))
        self.HelpOK.SetFont(wx.Font(10, wx.SWISS, wx.NORMAL, wx.BOLD, 0, "Bahnschrift SemiBold"))
        self.HelpOK.SetToolTip("Back to Home")

    def __do_layout(self):
        # HelpFrame.__do_layout
        sizer_30 = wx.BoxSizer(wx.VERTICAL)
        lblHelp1 = wx.StaticText(self, wx.ID_ANY, "Petunjuk Penggunaan Program", style=wx.ALIGN_CENTER)
        lblHelp1.SetBackgroundColour(wx.Colour(47, 47, 47))
        lblHelp1.SetForegroundColour(wx.Colour(0, 127, 255))
        lblHelp1.SetFont(wx.Font(18, wx.SWISS, wx.NORMAL, wx.BOLD, 0, "Bahnschrift SemiBold"))
        sizer_30.Add(lblHelp1, 0, wx.ALIGN_CENTER | wx.ALL | wx.EXPAND, 20)
        static_line_2 = wx.StaticLine(self, wx.ID_ANY)
        sizer_30.Add(static_line_2, 0, wx.EXPAND | wx.LEFT | wx.RIGHT, 40)
        lblHelp2 = wx.StaticText(self, wx.ID_ANY, "Informasi tombol:\n- Open File\t: Memilih file citra yang ingin dideteksi\n- Detect\t\t: Proses pendeteksian sel darah putih\n- Verify\t\t: Verifikasi hasil deteksi\n- Save\t\t: Menyimpan citra output\n- About\t\t: Informasi mengenai program\n- Help\t\t: Petunjuk penggunaan program\n- Folder Setting\t: Pengaturan lokasi folder verify/save\n\nTutorial menggunakan program:\n1. Tekan tombol 'Open File' dan pilih file citra preparat sel darah tanpa pewarnaan (.jpg) yang ingin dideteksi.\n2. Kemudian tekan tombol 'Detect', maka area hasil deteksi sel darah putih akan ditampilkan.\n3. Tekan tombol verify untuk mencocokkan apakah area yang terdeteksi benar atau tidak.\n4. Tekan tombol save jika ingin menyimpan citra hasil deteksi (output).\n\nDetail program:", style=wx.ST_NO_AUTORESIZE)
        lblHelp2.SetBackgroundColour(wx.Colour(47, 47, 47))
        lblHelp2.SetForegroundColour(wx.Colour(255, 255, 255))
        lblHelp2.SetFont(wx.Font(14, wx.SWISS, wx.NORMAL, wx.NORMAL, 0, "Bahnschrift"))
        sizer_30.Add(lblHelp2, 5, wx.LEFT | wx.RIGHT | wx.TOP, 20)
        sizer_30.Add(self.btnDetail, 0, wx.LEFT | wx.RIGHT, 20)
        lblDetail = wx.StaticText(self, wx.ID_ANY, "*Lakukan deteksi terlebih dahulu untuk melihat tahapan pemrosesan program secara detail", style=wx.ST_NO_AUTORESIZE)
        lblDetail.SetBackgroundColour(wx.Colour(47, 47, 47))
        lblDetail.SetForegroundColour(wx.Colour(255, 255, 255))
        lblDetail.SetFont(wx.Font(14, wx.SWISS, wx.NORMAL, wx.NORMAL, 0, "Bahnschrift"))
        sizer_30.Add(lblDetail, 0, wx.BOTTOM | wx.LEFT | wx.RIGHT, 20)
        sizer_30.Add(self.HelpOK, 0, wx.ALIGN_CENTER | wx.BOTTOM | wx.LEFT | wx.RIGHT, 20)
        self.SetSizer(sizer_30)
        sizer_30.Fit(self)
        self.Layout()

    def btnDetail_pressed(self, event):
        detailFrame = DetailFrame(None, wx.ID_ANY, "")
        detailFrame.Show()

    def btnHelpOK_pressed(self, event):
        self.Close()

# end of class HelpFrame

class SettingFrame(wx.Frame):
    def __init__(self, *args, **kwds):
        # SettingFrame.__init__
        kwds["style"] = kwds.get("style", 0) | wx.CAPTION | wx.CLIP_CHILDREN | wx.CLOSE_BOX | wx.SYSTEM_MENU
        wx.Frame.__init__(self, *args, **kwds)
        self.SetSize((665, 335))
        self.text_ctrl_1 = wx.TextCtrl(self, wx.ID_ANY, saveVerify_path[0])
        self.btnSelectSave = wx.Button(self, wx.ID_ANY, "Select")
        self.text_ctrl_2 = wx.TextCtrl(self, wx.ID_ANY, saveVerify_path[1])
        self.btnSelectVerify = wx.Button(self, wx.ID_ANY, "Select")
        self.btnApply = wx.Button(self, wx.ID_ANY, "Apply")

        self.__set_properties()
        self.__do_layout()

        self.Bind(wx.EVT_BUTTON, self.btnSelectSave_pressed, self.btnSelectSave)
        self.Bind(wx.EVT_BUTTON, self.btnSelectVerify_pressed, self.btnSelectVerify)
        self.Bind(wx.EVT_BUTTON, self.btnApply_pressed, self.btnApply)

    def __set_properties(self):
        # SettingFrame.__set_properties
        self.SetTitle("Folder Setting")
        _icon = wx.NullIcon
        _icon.CopyFromBitmap(wx.Bitmap("Resources\\FolderBtn.bmp", wx.BITMAP_TYPE_ANY))
        self.SetIcon(_icon)
        self.SetBackgroundColour(wx.Colour(47, 47, 47))
        self.text_ctrl_1.SetMinSize((450, 30))
        self.text_ctrl_1.SetFont(wx.Font(14, wx.SWISS, wx.NORMAL, wx.NORMAL, 0, "Bahnschrift"))
        self.btnSelectSave.SetMinSize((110, 30))
        self.btnSelectSave.SetFont(wx.Font(12, wx.SWISS, wx.NORMAL, wx.BOLD, 0, "Bahnschrift SemiBold"))
        self.text_ctrl_2.SetMinSize((450, 30))
        self.text_ctrl_2.SetFont(wx.Font(14, wx.SWISS, wx.NORMAL, wx.NORMAL, 0, "Bahnschrift"))
        self.btnSelectVerify.SetMinSize((110, 30))
        self.btnSelectVerify.SetFont(wx.Font(12, wx.SWISS, wx.NORMAL, wx.BOLD, 0, "Bahnschrift SemiBold"))
        self.btnApply.SetMinSize((250, 30))
        self.btnApply.SetFont(wx.Font(12, wx.SWISS, wx.NORMAL, wx.BOLD, 0, "Bahnschrift SemiBold"))

    def __do_layout(self):
        # SettingFrame.__do_layout
        sizer_7 = wx.BoxSizer(wx.VERTICAL)
        sizer_8 = wx.BoxSizer(wx.VERTICAL)
        sizer_10 = wx.BoxSizer(wx.HORIZONTAL)
        sizer_9 = wx.BoxSizer(wx.HORIZONTAL)
        label_6 = wx.StaticText(self, wx.ID_ANY, "Pengaturan Folder", style=wx.ALIGN_CENTER)
        label_6.SetBackgroundColour(wx.Colour(47, 47, 47))
        label_6.SetForegroundColour(wx.Colour(0, 127, 255))
        label_6.SetFont(wx.Font(18, wx.SWISS, wx.NORMAL, wx.BOLD, 0, "Bahnschrift"))
        sizer_8.Add(label_6, 0, wx.ALIGN_CENTER | wx.ALL | wx.EXPAND, 20)
        static_line_2 = wx.StaticLine(self, wx.ID_ANY)
        sizer_8.Add(static_line_2, 0, wx.EXPAND | wx.LEFT | wx.RIGHT, 40)
        label_7 = wx.StaticText(self, wx.ID_ANY, "\nSave folder path :")
        label_7.SetBackgroundColour(wx.Colour(47, 47, 47))
        label_7.SetForegroundColour(wx.Colour(255, 255, 255))
        label_7.SetFont(wx.Font(14, wx.SWISS, wx.NORMAL, wx.BOLD, 0, "Bahnschrift"))
        sizer_8.Add(label_7, 0, wx.EXPAND | wx.LEFT | wx.RIGHT, 40)
        sizer_9.Add((30, 20), 0, 0, 0)
        sizer_9.Add(self.text_ctrl_1, 0, wx.LEFT | wx.RIGHT, 10)
        sizer_9.Add(self.btnSelectSave, 0, 0, 0)
        sizer_8.Add(sizer_9, 1, wx.EXPAND, 0)
        label_8 = wx.StaticText(self, wx.ID_ANY, "Verify folder path :")
        label_8.SetBackgroundColour(wx.Colour(47, 47, 47))
        label_8.SetForegroundColour(wx.Colour(255, 255, 255))
        label_8.SetFont(wx.Font(14, wx.SWISS, wx.NORMAL, wx.BOLD, 0, "Bahnschrift"))
        sizer_8.Add(label_8, 0, wx.LEFT | wx.RIGHT, 40)
        sizer_10.Add((30, 20), 0, 0, 0)
        sizer_10.Add(self.text_ctrl_2, 0, wx.LEFT | wx.RIGHT, 10)
        sizer_10.Add(self.btnSelectVerify, 0, 0, 0)
        sizer_8.Add(sizer_10, 1, wx.EXPAND, 0)
        sizer_8.Add(self.btnApply, 0, wx.ALIGN_CENTER | wx.LEFT | wx.RIGHT, 10)
        sizer_8.Add((20, 15), 0, 0, 0)
        sizer_7.Add(sizer_8, 1, wx.EXPAND, 0)
        self.SetSizer(sizer_7)
        self.Layout()

    def btnSelectSave_pressed(self, event):
        try:
            tk.Tk().withdraw()
            save_dir = filedialog.askdirectory(title="Select Save Folder")
            if save_dir:
                save_dir = save_dir + "/"
                self.text_ctrl_1.SetValue(save_dir)
        except:
            event.Skip()

    def btnSelectVerify_pressed(self, event):
        try:
            tk.Tk().withdraw()
            verify_dir = filedialog.askdirectory(title="Select Verify Image Folder")
            if verify_dir:
                verify_dir = verify_dir + "/"
                self.text_ctrl_2.SetValue(verify_dir)
        except:
            event.Skip()

    def btnApply_pressed(self, event):
        try:
            # buka dan read data path.config
            with open(filename, 'r') as file:
                data = file.readlines()

            # ubah path sesuai txtctrl
            data[0] = self.text_ctrl_1.GetValue() + "\n"
            data[1] = self.text_ctrl_2.GetValue()

            # overwrite path.config file
            with open(filename, 'w') as file:
                file.writelines(data)

            # update saveVerify_path global
            saveVerify_path[0] = data[0].rstrip()
            saveVerify_path[1] = data[1].rstrip()
        except:
            event.Skip()

        # tutup window
        self.Close()

# end of class SettingFrame

class DetailFrame(wx.Frame):
    def __init__(self, *args, **kwds):
        # DetailFrame.__init__
        kwds["style"] = kwds.get("style", 0) | wx.CAPTION | wx.CLIP_CHILDREN | wx.CLOSE_BOX | wx.MAXIMIZE_BOX | wx.MINIMIZE_BOX | wx.SYSTEM_MENU
        wx.Frame.__init__(self, *args, **kwds)
        self.SetSize((1376, 635))
        self.panel_1 = wx.Panel(self, wx.ID_ANY)
        self.panel_2 = wx.Panel(self, wx.ID_ANY)
        self.panel_3 = wx.Panel(self, wx.ID_ANY)
        self.panel_4 = wx.Panel(self, wx.ID_ANY)
        self.panel_5 = wx.Panel(self, wx.ID_ANY)
        self.panel_6 = wx.Panel(self, wx.ID_ANY)
        self.panel_7 = wx.Panel(self, wx.ID_ANY)
        self.panel_8 = wx.Panel(self, wx.ID_ANY)
        self.panel_9 = wx.Panel(self, wx.ID_ANY)
        self.panel_10 = wx.Panel(self, wx.ID_ANY)
        self.panel_13 = wx.Panel(self, wx.ID_ANY)
        self.btnBack = wx.Button(self, wx.ID_ANY, "< Back", style=wx.BORDER_NONE)
        self.panel_14 = wx.Panel(self, wx.ID_ANY)

        self.__set_properties()
        self.__do_layout()

        self.Bind(wx.EVT_BUTTON, self.btnBack_pressed, self.btnBack)

        # update panel (munculin semua image)
        self.updatePanel()

    def updatePanel(self):
        # convert semua detailoutput ke bitmap
        imgPanel = []
        (wp, hp) = self.panel_1.GetSize()
        for i in range(len(detailOutput)):
            if ((len(detailOutput[i].shape)) == 2): # cek apa img binary/bgr
                temp = cv2.cvtColor(detailOutput[i], cv2.COLOR_GRAY2RGB) # convert
            else:
                temp = cv2.cvtColor(detailOutput[i], cv2.COLOR_BGR2RGB)
            temp = cv2.resize(temp,(wp,hp), interpolation = cv2.INTER_AREA)
            temp = wx.ImageFromBuffer(temp.shape[1], temp.shape[0], temp)
            temp = temp.ConvertToBitmap()
            imgPanel.append(temp) # append list

        print(imgPanel)

        self.obj = wx.StaticBitmap(self.panel_1, -1, imgPanel[0],(0,0),(wp, hp))
        self.obj = wx.StaticBitmap(self.panel_2, -1, imgPanel[1],(0,0),(wp, hp))
        self.obj = wx.StaticBitmap(self.panel_3, -1, imgPanel[2],(0,0),(wp, hp))
        self.obj = wx.StaticBitmap(self.panel_4, -1, imgPanel[3],(0,0),(wp, hp))
        self.obj = wx.StaticBitmap(self.panel_5, -1, imgPanel[4],(0,0),(wp, hp))
        self.obj = wx.StaticBitmap(self.panel_6, -1, imgPanel[5],(0,0),(wp, hp))
        self.obj = wx.StaticBitmap(self.panel_7, -1, imgPanel[6],(0,0),(wp, hp))
        self.obj = wx.StaticBitmap(self.panel_8, -1, imgPanel[7],(0,0),(wp, hp))
        self.obj = wx.StaticBitmap(self.panel_9, -1, imgPanel[8],(0,0),(wp, hp))
        self.obj = wx.StaticBitmap(self.panel_10, -1, imgPanel[9],(0,0),(wp, hp))
        self.obj.Refresh()

    def __set_properties(self):
        # DetailFrame.__set_properties
        self.SetTitle("Detail")
        self.SetBackgroundColour(wx.Colour(165, 42, 42))
        self.panel_1.SetMinSize((260, 195))
        self.panel_1.SetBackgroundColour(wx.Colour(255, 255, 255))
        self.panel_2.SetMinSize((260, 195))
        self.panel_2.SetBackgroundColour(wx.Colour(255, 255, 255))
        self.panel_3.SetMinSize((260, 195))
        self.panel_3.SetBackgroundColour(wx.Colour(255, 255, 255))
        self.panel_4.SetMinSize((260, 195))
        self.panel_4.SetBackgroundColour(wx.Colour(255, 255, 255))
        self.panel_5.SetMinSize((260, 195))
        self.panel_5.SetBackgroundColour(wx.Colour(255, 255, 255))
        self.panel_6.SetMinSize((260, 195))
        self.panel_6.SetBackgroundColour(wx.Colour(255, 255, 255))
        self.panel_7.SetMinSize((260, 195))
        self.panel_7.SetBackgroundColour(wx.Colour(255, 255, 255))
        self.panel_8.SetMinSize((260, 195))
        self.panel_8.SetBackgroundColour(wx.Colour(255, 255, 255))
        self.panel_9.SetMinSize((260, 195))
        self.panel_9.SetBackgroundColour(wx.Colour(255, 255, 255))
        self.panel_10.SetMinSize((260, 195))
        self.panel_10.SetBackgroundColour(wx.Colour(255, 255, 255))
        self.btnBack.SetMinSize((600, 30))
        self.btnBack.SetBackgroundColour(wx.Colour(47, 47, 47))
        self.btnBack.SetForegroundColour(wx.Colour(255, 255, 255))
        self.btnBack.SetFont(wx.Font(14, wx.SWISS, wx.NORMAL, wx.BOLD, 0, "Bahnschrift SemiBold"))
        self.btnBack.SetToolTip("Back")

    def __do_layout(self):
        # DetailFrame.__do_layout
        sizer_11 = wx.BoxSizer(wx.VERTICAL)
        sizer_12 = wx.BoxSizer(wx.HORIZONTAL)
        sizer_13 = wx.BoxSizer(wx.VERTICAL)
        sizer_15 = wx.BoxSizer(wx.HORIZONTAL)
        grid_sizer_3 = wx.FlexGridSizer(0, 5, 0, 0)
        sizer_12.Add((10, 20), 0, 0, 0)
        sizer_13.Add((20, 10), 0, 0, 0)
        label_6 = wx.StaticText(self, wx.ID_ANY, "Detail Program", style=wx.ALIGN_CENTER)
        label_6.SetBackgroundColour(wx.Colour(165, 42, 42))
        label_6.SetForegroundColour(wx.Colour(255, 255, 255))
        label_6.SetFont(wx.Font(20, wx.SWISS, wx.NORMAL, wx.BOLD, 0, "Bahnschrift"))
        sizer_13.Add(label_6, 0, wx.ALIGN_CENTER | wx.ALL | wx.EXPAND, 20)
        grid_sizer_3.Add(self.panel_1, 1, wx.BOTTOM | wx.EXPAND | wx.RIGHT | wx.TOP, 5)
        grid_sizer_3.Add(self.panel_2, 1, wx.ALL | wx.EXPAND, 5)
        grid_sizer_3.Add(self.panel_3, 1, wx.ALL | wx.EXPAND, 5)
        grid_sizer_3.Add(self.panel_4, 1, wx.ALL | wx.EXPAND, 5)
        grid_sizer_3.Add(self.panel_5, 1, wx.BOTTOM | wx.EXPAND | wx.LEFT | wx.TOP, 5)
        label_5 = wx.StaticText(self, wx.ID_ANY, "1. Input Image", style=wx.ALIGN_CENTER)
        label_5.SetForegroundColour(wx.Colour(255, 255, 255))
        label_5.SetFont(wx.Font(10, wx.SWISS, wx.NORMAL, wx.BOLD, 0, "Bahnschrift SemiBold"))
        grid_sizer_3.Add(label_5, 0, wx.EXPAND, 5)
        label_7 = wx.StaticText(self, wx.ID_ANY, "2. Saturation Value", style=wx.ALIGN_CENTER)
        label_7.SetForegroundColour(wx.Colour(255, 255, 255))
        label_7.SetFont(wx.Font(10, wx.SWISS, wx.NORMAL, wx.BOLD, 0, "Bahnschrift SemiBold"))
        grid_sizer_3.Add(label_7, 0, wx.EXPAND, 5)
        label_8 = wx.StaticText(self, wx.ID_ANY, "3. Smoothing", style=wx.ALIGN_CENTER)
        label_8.SetForegroundColour(wx.Colour(255, 255, 255))
        label_8.SetFont(wx.Font(10, wx.SWISS, wx.NORMAL, wx.BOLD, 0, "Bahnschrift SemiBold"))
        grid_sizer_3.Add(label_8, 0, wx.EXPAND, 5)
        label_9 = wx.StaticText(self, wx.ID_ANY, "4. Sharpening", style=wx.ALIGN_CENTER)
        label_9.SetForegroundColour(wx.Colour(255, 255, 255))
        label_9.SetFont(wx.Font(10, wx.SWISS, wx.NORMAL, wx.BOLD, 0, "Bahnschrift SemiBold"))
        grid_sizer_3.Add(label_9, 0, wx.EXPAND, 5)
        label_10 = wx.StaticText(self, wx.ID_ANY, "5. Grayscale ", style=wx.ALIGN_CENTER)
        label_10.SetForegroundColour(wx.Colour(255, 255, 255))
        label_10.SetFont(wx.Font(10, wx.SWISS, wx.NORMAL, wx.BOLD, 0, "Bahnschrift SemiBold"))
        grid_sizer_3.Add(label_10, 0, wx.EXPAND, 5)
        grid_sizer_3.Add(self.panel_6, 1, wx.BOTTOM | wx.EXPAND | wx.RIGHT | wx.TOP, 5)
        grid_sizer_3.Add(self.panel_7, 1, wx.ALL | wx.EXPAND, 5)
        grid_sizer_3.Add(self.panel_8, 1, wx.ALL | wx.EXPAND, 5)
        grid_sizer_3.Add(self.panel_9, 1, wx.ALL | wx.EXPAND, 5)
        grid_sizer_3.Add(self.panel_10, 1, wx.BOTTOM | wx.EXPAND | wx.LEFT | wx.TOP, 5)
        label_11 = wx.StaticText(self, wx.ID_ANY, "6. Otsu Threshold", style=wx.ALIGN_CENTER)
        label_11.SetForegroundColour(wx.Colour(255, 255, 255))
        label_11.SetFont(wx.Font(10, wx.SWISS, wx.NORMAL, wx.BOLD, 0, "Bahnschrift SemiBold"))
        grid_sizer_3.Add(label_11, 0, wx.EXPAND, 5)
        label_12 = wx.StaticText(self, wx.ID_ANY, "7. Morphological Operation", style=wx.ALIGN_CENTER)
        label_12.SetForegroundColour(wx.Colour(255, 255, 255))
        label_12.SetFont(wx.Font(10, wx.SWISS, wx.NORMAL, wx.BOLD, 0, "Bahnschrift SemiBold"))
        grid_sizer_3.Add(label_12, 0, wx.EXPAND, 5)
        label_13 = wx.StaticText(self, wx.ID_ANY, "8. Watershed", style=wx.ALIGN_CENTER)
        label_13.SetForegroundColour(wx.Colour(255, 255, 255))
        label_13.SetFont(wx.Font(10, wx.SWISS, wx.NORMAL, wx.BOLD, 0, "Bahnschrift SemiBold"))
        grid_sizer_3.Add(label_13, 0, wx.BOTTOM | wx.EXPAND, 5)
        label_14 = wx.StaticText(self, wx.ID_ANY, "9. Dilation", style=wx.ALIGN_CENTER)
        label_14.SetForegroundColour(wx.Colour(255, 255, 255))
        label_14.SetFont(wx.Font(10, wx.SWISS, wx.NORMAL, wx.BOLD, 0, "Bahnschrift SemiBold"))
        grid_sizer_3.Add(label_14, 0, wx.EXPAND, 5)
        label_15 = wx.StaticText(self, wx.ID_ANY, "10. Detection", style=wx.ALIGN_CENTER)
        label_15.SetForegroundColour(wx.Colour(255, 255, 255))
        label_15.SetFont(wx.Font(10, wx.SWISS, wx.NORMAL, wx.BOLD, 0, "Bahnschrift SemiBold"))
        grid_sizer_3.Add(label_15, 0, wx.EXPAND, 5)
        sizer_13.Add(grid_sizer_3, 1, wx.EXPAND, 0)
        sizer_15.Add(self.panel_13, 1, 0, 0)
        sizer_15.Add(self.btnBack, 0, wx.TOP, 10)
        sizer_15.Add(self.panel_14, 1, 0, 0)
        sizer_13.Add(sizer_15, 1, wx.EXPAND, 0)
        sizer_13.Add((20, 10), 0, 0, 0)
        sizer_12.Add(sizer_13, 1, wx.EXPAND, 0)
        sizer_12.Add((10, 20), 0, 0, 0)
        sizer_11.Add(sizer_12, 1, wx.EXPAND, 0)
        self.SetSizer(sizer_11)
        self.Layout()

    def btnBack_pressed(self, event):
        self.Close()

# end of class DetailFrame

class MyApp(wx.App):
    def OnInit(self):
        self.locale = wx.Locale(wx.LANGUAGE_ENGLISH)
        self.frame = MainFrame(None, wx.ID_ANY, "")
        self.SetTopWindow(self.frame)
        self.frame.Show()
        return True

# end of class MyApp

if __name__ == "__main__":
    app = MyApp(0)
    app.MainLoop()


# Python standard Libraries
import time
import os.path

# ESA Snappy
from snappy import ProductIO

# Scientific Libraries
import numpy as np
import matplotlib.pyplot as plt
import joblib
from sklearn import metrics

# Self Defined Modules
from ground_truth import RosebelPixelClass3, GroundTruthBoundaries

PRODUCT_1A_PATH = "..\\data\\processed\\Rosebel_GRD\\Subset_S1A_IW_GRDH_1SDV_20170903T092838_20170903T092903_018209_01E9A9_D2A2_Orb_NR_Cal_Spk_TF_TC_Gamma.dim"
PRODUCT_1B_PATH = "..\\data\\processed\\Rosebel_GRD\\Subset_S1B_IW_GRDH_1SDV_20170902T215854_20170902T215945_007219_00CB9B_FFA6_Orb_NR_Cal_Asm_Spk_TF_TC.dim"
CLASS_LABEL_FILENAME = "..\\data\\labels\\rosebel_grd_3_class_labels_original.npy"
SAVE_DIR = "..\\results\\Rosebel_GRD\\"
PIN_EXPORT_FILEPATH = "..\\data\\pins\\rosebel_grd_pins.txt"

# PRODUCT_1A_PATH = "..\\data\\processed\\Obuasi\\Subset_S1A_IW_GRDH_1SDV_20190208T182602_20190208T182631_025842_02E01C_899E_Orb_NR_Cal_Spk_TF_TC_Gamma.dim"
# PRODUCT_1B_PATH = "..\\data\\processed\\Obuasi\\Subset_S1B_IW_GRDH_1SDV_20190209T181715_20190209T181740_014873_01BC28_A9A8_Orb_NR_Cal_Spk_TF_TC.dim"
# CLASS_LABEL_FILENAME = "..\\data\\labels\\obuasi_3_class_labels_original.npy"
# SAVE_DIR = "..\\results\\Obuasi\\"
# PIN_EXPORT_FILEPATH = "..\\data\\pins\\obuasi_pins.txt"

LABEL_PATH = "..\\data\\labels\\"
MODEL_PATH = "..\\data\\models\\"

def print_duration_string(start_time):
    t = time.time() - start_time
    print("    Completed in - " + str(int(t // 3600)) + " hours " + str(int((t // 60) % 60)) + " minutes " + str(
        int(t % 60)) + " seconds ")

def export_results(gt_labels, prediction_label, save_filepath):
    confusion_matrix = metrics.confusion_matrix(gt_labels, prediction_label)
    accuracy_score = metrics.accuracy_score(gt_labels, prediction_label)
    classification_report = metrics.classification_report(gt_labels, prediction_label)

    print("Writing results to file")
    f = open(save_filepath, "w+")
    f.write("Total labelled water pixel count:" +
            str(len(np.argwhere(np.array(labels) == RosebelPixelClass3.water.value))) + '\n')
    f.write("Total labelled mines pixel count:" +
            str(len(np.argwhere(np.array(labels) == RosebelPixelClass3.mines.value))) + '\n')
    f.write("Total labelled forest pixel count:" +
            str(len(np.argwhere(np.array(labels) == RosebelPixelClass3.forest.value))) + '\n')
    f.write("Confusion matrix: \n" + np.array_str(confusion_matrix) + '\n')
    f.write("Overall accuracy score: " + str(accuracy_score) + '\n')
    f.write("Classification report: \n" + str(classification_report) + '\n')

    for row_index in range(confusion_matrix.shape[0]):
        #  Print class prediction accuracy first
        value = confusion_matrix[row_index][row_index]
        f.write('\n' + RosebelPixelClass3(row_index + 1).name +
                ' pixel prediction accuracy: %.2f%%' % (value * 100 / sum(confusion_matrix[row_index])) + '\n')

        #  Print out incorrectness
        for col_index in range(confusion_matrix.shape[1]):
            if row_index != col_index:
                value = confusion_matrix[row_index][col_index]
                f.write(RosebelPixelClass3(row_index + 1).name + ' pixels mis-predicted as ' +
                        RosebelPixelClass3(col_index + 1).name + ': %.2f%%' % (
                                    value * 100 / sum(confusion_matrix[row_index])) + '\n')
    f.close()

if __name__ == "__main__":
    start_time = time.time()

    if os.path.exists(LABEL_PATH + "rf_1A_1B_predictions.npy"):
        rf_predictions = np.load(LABEL_PATH + "rf_1A_1B_predictions.npy")
    else:
        print("Reading product:" + PRODUCT_1A_PATH)
        p1A = ProductIO.readProduct(PRODUCT_1A_PATH)

        print('Extracting Bands')
        band_names = p1A.getBandNames()
        bands = []
        number_of_bands = 0
        for band_name in band_names:
            print(str(number_of_bands+1) + ": " + str(band_name))
            number_of_bands += 1
            bands.append(p1A.getBand(band_name))
        print("Number of bands in product: " + str(number_of_bands))

        print('Extracting Feature Data from Bands')
        features_1A = []
        for band in bands:
            w = band.getRasterWidth()
            h = band.getRasterHeight()
            x = np.zeros(w * h, np.float32)
            band.readPixels(0, 0, w, h, x)
            features_1A.append(x)
        image_width_1A = bands[0].getRasterWidth()
        image_height_1A = bands[0].getRasterHeight()
        number_of_pixels_1A = image_height_1A * image_width_1A
        print("Image width = " + str(image_width_1A))
        print("Image height = " + str(image_height_1A))
        print("Number of pixels: " + str(number_of_pixels_1A))
        features_1A = np.array(features_1A)
        features_1A = np.delete(features_1A, 2, axis=0).transpose()

        print("Reading product:" + PRODUCT_1B_PATH)
        p1B = ProductIO.readProduct(PRODUCT_1B_PATH)

        print('Extracting Bands')
        band_names = p1B.getBandNames()
        bands = []
        number_of_bands = 0
        for band_name in band_names:
            print(str(number_of_bands + 1) + ": " + str(band_name))
            number_of_bands += 1
            bands.append(p1B.getBand(band_name))
        print("Number of bands in product: " + str(number_of_bands))

        print('Extracting Feature Data from Bands')
        features_1B = []
        for band in bands:
            w = band.getRasterWidth()
            h = band.getRasterHeight()
            x = np.zeros(w * h, np.float32)
            band.readPixels(0, 0, w, h, x)
            features_1B.append(x)
        image_width_1B = bands[0].getRasterWidth()
        image_height_1B = bands[0].getRasterHeight()
        number_of_pixels_1B = image_height_1B * image_width_1B
        print("Image width = " + str(image_width_1B))
        print("Image height = " + str(image_height_1B))
        print("Number of pixels: " + str(number_of_pixels_1B))
        features_1B = np.array(features_1B)
        features_1B = np.delete(features_1B, 2, axis=0).transpose()

        if image_width_1A != image_width_1B or image_height_1A != image_height_1B:
            print("Unequal number of pixels found between products, aborting...")
            exit()

        print("Importing Random Forest model")
        rf_model = joblib.load(MODEL_PATH + "rf_R_O_M_g_model_balanced.joblib")
        print("Predicting rf assignments for Sentinel 1A and 1B products")
        rf_1A_predictions = rf_model.predict(features_1A).astype(int)
        rf_1A_proba = rf_model.predict_proba(features_1A)
        rf_1B_predictions = rf_model.predict(features_1B).astype(int)
        rf_1B_proba = rf_model.predict_proba(features_1B)

        rf_predictions = []
        for index in range(number_of_pixels_1A):
            if rf_1A_predictions[index] == RosebelPixelClass3.water.value or rf_1B_predictions[index] == RosebelPixelClass3.water.value:
                rf_predictions.append(RosebelPixelClass3.water.value)
            elif rf_1A_predictions[index] == rf_1B_predictions[index]:
                rf_predictions.append(rf_1A_predictions[index])
            else:
                # rf_predictions.append(RosebelPixelClass3.forest.value)    # for strict noise reduction
                ave_mines_confidence = (float(rf_1A_proba[index][RosebelPixelClass3.mines.value-1])
                                        + float(rf_1B_proba[index][RosebelPixelClass3.mines.value-1])) / 2.0
                if ave_mines_confidence > 0.5:
                    rf_predictions.append(RosebelPixelClass3.mines.value)
                else:
                    rf_predictions.append(RosebelPixelClass3.forest.value)

        rf_predictions = np.array(rf_predictions)
        np.save(LABEL_PATH + "rf_1A_1B_predictions.npy", rf_predictions)

    print("Loading Ground Truth for results validation")
    labels = np.load(SAVE_DIR + CLASS_LABEL_FILENAME)
    polygon_labels = []
    polygon_rfassign = []
    for index in range(number_of_pixels_1A):
        if labels[index] != RosebelPixelClass3.na.value:
            polygon_labels.append(labels[index])
            polygon_rfassign.append(rf_predictions[index])

    print("Evaluating rf prediction:")
    save_rf_results = SAVE_DIR + "results_rf.txt"
    export_results(polygon_labels, polygon_rfassign, save_rf_results)

    print("Exporting image based on rf assignments")
    rf_predictions = np.reshape(rf_predictions, (image_height_1A, image_width_1A))
    print(rf_predictions.shape)
    imgplot = plt.imshow(rf_predictions, cmap='brg')
    imgplot.write_png(SAVE_DIR + "rf_image.png")

    print_duration_string(start_time)


# 题目：一个整数，它加上100和加上268后都是一个完全平方数，请问该数是多少？
# 程序分析：在10000以内判断，将该数加上100后再开方，加上268后再开方，如果开方后的结果满足如下条件，即是结果。请看具体分析：
import math
import re
for x in range(1,10000):
	i = x+100
	j = x+268
	a = str(math.sqrt(i))
	b = str(math.sqrt(j))
	print(a,b)
	c = "."
	if a.rfind(c) is -1:
		if b.rfidall(c) is -1:
			print(x)


import decimal
import json

from django.http import JsonResponse, HttpResponseRedirect
from django.shortcuts import render
from .models import Game, Level

LEVELS = {150:1, 120:2, 100:3}

def start(request):
    print('start game')
    print(request.POST)
    Game.objects.filter(player__isnull=True).delete()

    try:
        puzzle_length = int(request.POST.get('puzzle_length'))
        # level = LEVELS[puzzle_length]
        level = Level.objects.get(id=LEVELS[puzzle_length])
        print(level)
    except:
        return JsonResponse({'code': 400, 'error': 'Invalid puzzle_length'})
    else:
        if request.user.is_authenticated:
            game = Game(player=request.user, game_type=int(request.POST.get('game_type')))
        else:
            game = Game(game_type=int(request.POST.get('game_type')))
        print('game',game)
        game.level = level
        game.save()
        print('game info', game.id)

        return JsonResponse({'code': 200, 'image': game.image.url, 'game_id': game.id, 'level': level.id,'timer':level.timer})

def win(request):
    request_unicode = request.body.decode('utf-8')
    request_body = json.loads(request_unicode)
    game = Game.objects.get(id=request_body['game_id'])
    game.result = True
    game.save()
    if game.player:
        game.player.rating += game.level.rating
        print(game.player.balance)
        print(game.level.balance / 100)
        # game.player.balance += game.player.balance * decimal.Decimal((game.level.balance / 100))
        game.player.save()
        return JsonResponse({'rating': game.player.rating})
    else:
        return JsonResponse({'rating': 0})

def theme_light(request):
    request.session['theme']  = 'light'
    return HttpResponseRedirect(request.META.get('HTTP_REFERER'))
def theme_dark(request):
    request.session['theme'] = 'dark'
    return HttpResponseRedirect(request.META.get('HTTP_REFERER'))


from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.chrome.options import Options
from selenium.common.exceptions import TimeoutException, ElementClickInterceptedException
import time
import random
from datetime import datetime
import json
from bs4 import BeautifulSoup
import os
import re

opts = Options()
opts.add_argument("user-agent=whatever you want")

opts.add_argument('--ignore-certificate-errors')
opts.add_argument('--ignore-ssl-errors')

def page_counter(file_name, url, json_data_list = [], nth_element = 0, start_page = 1):

    if os.path.isfile(file_name):
        with open(file_name, 'r') as f:
            json_data_list = json.load(f)

        start_page = int(len(json_data_list) // 20) + 1
        if len(json_data_list) >= 20:
            new_url = url + '?pagenumber=' + str(start_page)
        else:
            new_url = url

        nth_element = int(len(json_data_list) % 20)

        return new_url, json_data_list, nth_element, start_page

    else:
        with open(file_name, mode='w', encoding='utf-8') as f:
            json.dump([], f)

        new_url = url
        return new_url, json_data_list, nth_element, start_page

def Captcha_Bypass(driver):

    other_place = WebDriverWait(driver, 15).until(
        EC.presence_of_element_located((By.CLASS_NAME, "main__part1"))
    )

    cl = random.choice(['geetest_dot', 'geetest_small', 'geetest_bg', 'geetest_hook', 'geetest_h'])
    print(cl)
    captcha = WebDriverWait(driver, 15).until(
        EC.presence_of_element_located((By.CLASS_NAME, cl))
    )

    actions = ActionChains(driver)

    actions.click(other_place)

    upgrade_actions = ActionChains(driver)
    upgrade_actions.move_to_element(captcha)
    upgrade_actions.click()
    upgrade_actions.perform()

def Allow_cookies(driver):
    WebDriverWait(driver,20).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH,'//*[@id="gdpr-consent-notice"]')))
    WebDriverWait(driver,20).until(EC.element_to_be_clickable((By.XPATH, '//*[@id="save"]'))).click()

def Selenium_scraper(url, file_name, json_data_list, start_page, nth_element, driver):
    count = 0
    while True:
        try:
            Captcha_Bypass(driver)
            Allow_cookies(driver)
            break
        except:
            driver.get(url)
            count += 1
            if count == 5:
                raise TimeoutException

            continue

    driver.implicitly_wait(5)

    num_of_pages = driver.find_element_by_css_selector('.p-items:nth-child(7) a').text
    if num_of_pages == '...':
        num_of_pages = driver.find_element_by_css_selector('.p-items:nth-child(8) a').text

    if num_of_pages == '':
        try:
            num_of_pages = int(num_of_pages = int(driver.find_element_by_css_selector('.p-active+ .p-items a').text))
        except:
            num_of_pages = int(num_of_pages = int(driver.find_element_by_css_selector('.p-active a').text))

    if 'th' in num_of_pages:
        num_of_pages = int(re.search(r'\d+', num_of_pages).group())

    print('Num of pages : ', num_of_pages)

    for page in range(start_page, int(num_of_pages)+1):
        print('Page : ', page)
        names = []
        driver.implicitly_wait(5)
        #if page == 1:
        all_links = driver.find_elements_by_css_selector('a .maxtwolinerHeadline')
        if len(all_links) < 20:
            all_links = driver.find_elements_by_css_selector('.onlyLarge:nth-child(1)')

        for n in all_links:
            names.append(n.text)

        print('Length : ', len(names))
        print(names)

        if start_page != page:
            nth_element = 0

        for i, name in enumerate(names[nth_element:]):

            try:
                link = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.LINK_TEXT, name)))
            except:
                continue

            data_dict = {}
            try:
                link_header = link.get_attribute('href')
            except:
                link_header = ""

            if link_header.split('.')[-1] == 'html':
                continue

            if i == 0:
                time.sleep(15)

            link.click()

            # try:
            #     modal_popup = WebDriverWait(driver, 15).until(
            #             EC.presence_of_element_located((By.XPATH, '//*[@id="is24-expose-modal"]/div/div/div/div/div/div[2]/button'))
            #     )
            #     modal_popup.click()
            # except:
            #     pass

            driver.implicitly_wait(10)
            soup = BeautifulSoup(driver.page_source, 'lxml')

            try:
                scout_id = soup.select_one('.is24-scoutid__content').get_text(strip=True)
            except:
                scout_id = ""

            try:
                address = soup.select_one('.zip-region-and-country').get_text(strip=True)
            except:
                address = ""

            grid_dict = {}
            try:
                parameter_list = soup.select('dl.grid')
                for l in parameter_list:
                    try:
                        tag = l.select_one('dt').get_text(strip=True)
                        val = l.select_one('dd').get_text(strip=True)
                        grid_dict[tag] = val
                    except:
                        continue
            except:
                pass

            try:
                objectb = soup.select_one('.is24qa-objektbeschreibung-label').get_text(strip=True)
                objectb_text = soup.select_one('.is24qa-objektbeschreibung').get_text(strip=True)
                grid_dict[objectb] = objectb_text
            except:
                pass

            data_dict['Link_Header_Project_Name'] = name
            data_dict['State'] = url.split('/')[-2]
            data_dict['Link_Header_project_Url'] = link_header
            data_dict['Scout id'] = scout_id
            data_dict['Address'] = address
            data_dict['Timestamp'] = datetime.now()
            data_dict['Data'] = grid_dict

            json_data_list.append(data_dict)
            with open(file_name, mode='w', encoding='utf-8') as feedsjson:
                json.dump(json_data_list, feedsjson, indent=4, default=str)

            driver.back()

        next_page = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.CSS_SELECTOR, '.is24-icon-chevron-right.vertical-center')))
        next_page.click()

url_list = ["https://www.immobilienscout24.de/Suche/de/baden-wuerttemberg/grundstueck-kaufen",
            "https://www.immobilienscout24.de/Suche/de/bayern/grundstueck-kaufen",
            "https://www.immobilienscout24.de/Suche/de/berlin/berlin/grundstueck-kaufen",
            "https://www.immobilienscout24.de/Suche/de/brandenburg/grundstueck-kaufen",
            "https://www.immobilienscout24.de/Suche/de/bremen/grundstueck-kaufen",
            "https://www.immobilienscout24.de/Suche/de/hamburg/hamburg/grundstueck-kaufen",
            "https://www.immobilienscout24.de/Suche/de/hessen/grundstueck-kaufen",
            "https://www.immobilienscout24.de/Suche/de/niedersachsen/grundstueck-kaufen",
            "https://www.immobilienscout24.de/Suche/de/mecklenburg-vorpommern/grundstueck-kaufen",
            "https://www.immobilienscout24.de/Suche/de/nordrhein-westfalen/grundstueck-kaufen",
            "https://www.immobilienscout24.de/Suche/de/rheinland-pfalz/grundstueck-kaufen",
            "https://www.immobilienscout24.de/Suche/de/saarland/grundstueck-kaufen",
            "https://www.immobilienscout24.de/Suche/de/sachsen/grundstueck-kaufen",
            "https://www.immobilienscout24.de/Suche/de/sachsen-anhalt/grundstueck-kaufen",
            "https://www.immobilienscout24.de/Suche/de/schleswig-holstein/grundstueck-kaufen",
            "https://www.immobilienscout24.de/Suche/de/thueringen/grundstueck-kaufen"]

def Append_files(temp_file, main_file):
    with open(temp_file, 'r') as f:
        temp_json = json.load(f)

    if os.path.isfile(main_file):
        with open(main_file, 'r') as f:
            main_json = json.load(f)
    else:
        main_json = []

    append_json = main_json + temp_json

    with open(main_file, 'w') as f:
        json.dump(append_json, f, indent=4, default='str')

    os.remove(temp_file)

def KG():
    main_file = 'Kaufen_Grundstuck.json'

    for url in url_list:
        temp_file = 'temp_' + main_file
        while True:
            try:
                new_url, json_data_list, nth_element, start_page = page_counter(temp_file, url)

                driver = webdriver.Chrome(chrome_options=opts, executable_path=r'chromedriver.exe')
                driver.get(new_url)

                Selenium_scraper(new_url, temp_file, json_data_list, start_page, nth_element, driver)

                Append_files(temp_file, main_file)

                driver.quit()
                break

            except (TimeoutException, ElementClickInterceptedException) as exception:
                driver.quit()
                time.sleep(180)
                continue
KG()


#!/bin/python
# -*- coding: utf-8 -*-
"""
Created on Mon Sep 14 11:01:46 2018

@author: Suyong Choi (Department of Physics, Korea University suyong@korea.ac.kr)

This script applies nanoaod processing to one file
"""

import sys
import cppyy
import ROOT

if __name__=='__main__':
    from optparse import OptionParser
    parser = OptionParser(usage="%prog [options] inputDir outputDir")
    parser.add_option("-Y", "--year",  dest="json", type="string", default="", help="Select 2016, 2017, 2018 year of runs")
    parser.add_option("-J", "--json",  dest="json", type="string", default="", help="Select events using this JSON file, meaningful only for data")
    parser.add_option("--saveallbranches", dest="saveallbranches", action="store_true", default=False, help="Save all branches. False by default")
    parser.add_option("--globaltag", dest="globaltag", type="string", default="", help="Global tag to be used in JetMET corrections")

    (options, args) = parser.parse_args()
    if len(args) < 1:
        parser.print_help()
        sys.exit(1)
    infile = args[0]
    outfile = args[1]
    intreename = args[2]
    outtreename = args[3]

    # load compiled C++ library into ROOT/python
    cppyy.load_reflection_info("libnanoadrdframe.so")
    t = ROOT.TChain(intreename)
    t.Add(infile)
    aproc = ROOT.LQtopAnalyzer(t, outfile, options.year, options.json, options.globaltag)
    aproc.setupAnalysis()
    aproc.run(options.saveallbranches, outtreename)


import asyncio
import time
import functools
from escape_room_006 import *
import playground
from ex6_game_packet_types import *

from playground.common.logging import EnablePresetLogging, PRESET_VERBOSE
EnablePresetLogging(PRESET_VERBOSE)

def new_write_function(string, transport, status):
    string = string + "<EOL>\n"
    transport.write(
            GameResponsePacket(
                server_response = string,
                server_status=status
                ).__serialize__()
            )
    print(string)

class StudentServer(asyncio.Protocol):
    def __init__(self):
        print("S: server started")
        self.responses = []
        self.status = None

    #async def wait_agents(self):
    #    await asyncio.wait([asyncio.create_task(a) for a in self.game.agents])

    def connection_made(self, transport):
        print("S: connection made")
        self.transport = transport
        game = EscapeRoomGame(output=functools.partial(new_write_function, transport=self.transport, status = self.status))
        game.create_game()
        game.start()
        self.game = game
        #asyncio.create_task(self.wait_agents())
        for a in game.agents:
            asyncio.ensure_future(a)
        self.d = PacketType.Deserializer()
        print("S: packet sent")

    def connection_lost(self, ex):
        print("S: closing transport")
        self.transport.close()

    def data_received(self, data):
        self.d.update(data)
        for packet in self.d.nextPackets():
            if packet.DEFINITION_IDENTIFIER == "exercise6.jaron.command":
                print("SR: ", packet.command)
                text = packet.command

            else:
                raise ValueError()
            time.sleep(.2)
            lines = text.split("<EOL>\n")
            #if self.game.status == "playing":
            for line in lines:
                if len(line) > 0:
                    print("S: ", line)
                    self.game.command(line)
                    self.status = self.game.status

if __name__ == "__main__":
    loop = asyncio.get_event_loop()
    coro = loop.create_server(StudentServer,"", 1292)
    server = loop.run_until_complete(coro)

    try:
        loop.run_forever()
    except KeyboardInterrupt:
        pass

    server.close()
    loop.run_until_complete(server.wait_close())
    loop.close()


# -*- coding: utf-8 -*-
"""
Created on Tue May 12 10:08:59 2020
"""

import io

QUOTE = {
        "'":"'",
        '"':'"',
        }
BRACKETS = {'(': ')'}
BRACKETS_END = {')':1}
SPACE = {' ':1, '\t':1, '\r':1, '\n':1}

def quoteData(content, index):
    data = ""
    q_e = QUOTE[content[index]]
    c_len = len(content)
    escape = False
    index+=1;
    while index < c_len:
        c = content[index]
        if c == '\\':
            escape = True
        elif c == q_e:
            if(not escape):
                return data, index+1
            else:
                data += c;
        else:
            escape = False
            data += c
        index+=1
    return data, index+1

def normalData(content, index):
    data = ""
    c_len = len(content)
    while index < c_len:
        c = content[index]
        if c in SPACE:
            index +=1
            break
        elif c in BRACKETS:
            break
        elif c in BRACKETS_END:
            break
        else:
            data += c
            index+=1
    return data, index

def parseSexp(content, index = 0):
    res = []
    c_len = len(content)
    data = ""
    bracket_end = ""
    while index < c_len:
        c = content[index]
        if c in BRACKETS:
            bracket_end = BRACKETS[c]
            data, index = parseSexp(content, index+1)
            res.append(data)
        elif c in QUOTE:
            data, index = quoteData(content, index)
            res.append(data)
        elif c in SPACE:
            index+=1;
        elif c in BRACKETS_END:
            index+=1
            break
        else:
            data, index = normalData(content, index)
            res.append(data)
    return res, index

def loadKicadNet(filename):
    file = io.open(filename, "r", encoding="utf-8")
    data = file.read()
    res = parseSexp(data)
    return res[0][0]


#Begin
from tkinter import *
import math
#Create Window
root = Tk()
root.geometry('500x400+450+150')
root.title("Калькулятор")
root.resizable(False, False)
root.configure(background='#66FF00')
#Frame
rd1=Frame(root)
rd2=Frame(root) # height = 100, width = 100
rd3=Frame(root)
rd4=Frame(root)
rd5=Frame(root)
#Vars
inpt=''
inpt1=''
v=''
#Label
Tablo=Label(text=' ',bg='#FF4F00',bd=5,font=('Verdana',13,'bold'))
Tablo2=Label(text=' ',bg='#FF4F00',bd=5,font=('Verdana',13,'bold'))
MemoryTablo=Label(text='Memory: ',bg='#FF4F00',bd=5,font=('Verdana',13,'bold'))
#Entry
mc=Button(rd1,text='mc',font=("Verdana",13, "bold"), width = 5)
mr=Button(rd1,text='mr',font=("Verdana",13, "bold"), width = 5)
ms=Button(rd1,text='m-',font=("Verdana",13, "bold"), width = 5)
ma=Button(rd1,text='m+',font=("Verdana",13, "bold"), width = 5)
ya=Button(rd1,text='+/-',font=("Verdana",13, "bold"), width = 5)
m0=Button(rd2,text='00->0',font=("Verdana",13, "bold"), width = 5)
n7=Button(rd2,text='7',font=("Verdana",13, "bold"), width = 5)
n8=Button(rd2,text='8',font=("Verdana",13, "bold"), width = 5)
n9=Button(rd2,text='9',font=("Verdana",13, "bold"), width = 5)
division=Button(rd2,text='/',font=("Verdana",13, "bold"), width = 5)
remainder_of_the_division=Button(rd2,text='%',font=("Verdana",13, "bold"), width = 5)
srt=Button(rd3,text='\/-',font=("Verdana",13, "bold"), width = 5)
n4=Button(rd3,text='4',font=("Verdana",13, "bold"), width = 5)
n5=Button(rd3,text='5',font=("Verdana",13, "bold"), width = 5)
n6=Button(rd3,text='6',font=("Verdana",13, "bold"), width = 5)
multiplication=Button(rd3,text='*',font=("Verdana",13, "bold"), width = 5)
subtraction=Button(rd3,text='-',font=("Verdana",13, "bold"), width = 5)
f1=Button(rd4,text='f1',font=("Verdana",13, "bold"), width = 5)
n1=Button(rd4,text='1',font=("Verdana",13, "bold"), width = 5)
n2=Button(rd4,text='2',font=("Verdana",13, "bold"), width = 5)
n3=Button(rd4,text='3',font=("Verdana",13, "bold"), width = 5)
addition=Button(rd4,text='+',font=("Verdana",13, "bold"), width = 5)
equally=Button(rd4,text='=',font=("Verdana",13, "bold"), width = 5)
ce=Button(rd5,text='ce',font=("Verdana",13, "bold"), width = 5)
n0=Button(rd5,text='0',font=("Verdana",13, "bold"), width = 5)
n00=Button(rd5,text='00',font=("Verdana",13, "bold"), width = 5)
point=Button(rd5,text='.',font=("Verdana",13, "bold"), width = 5)
exponentiation=Button(rd5,text='^',font=("Verdana",13, "bold"), width = 5)
#Assebler
MemoryTablo.pack(expand=1)
Tablo2.pack(expand=1)
Tablo.pack(expand=1)
rd1.pack(expand=1,fill=BOTH)
mc.pack(side=LEFT,expand=1,fill=BOTH)
mr.pack(side=LEFT,expand=1,fill=BOTH)
ms.pack(side=LEFT,expand=1,fill=BOTH)
ma.pack(side=LEFT,expand=1,fill=BOTH)
ya.pack(side=LEFT,expand=1,fill=BOTH)
rd2.pack(expand=1,fill=BOTH)
m0.pack(side=LEFT,expand=1,fill=BOTH)
n7.pack(side=LEFT,expand=1,fill=BOTH)
n8.pack(side=LEFT,expand=1,fill=BOTH)
n9.pack(side=LEFT,expand=1,fill=BOTH)
division.pack(side=LEFT,expand=1,fill=BOTH)
remainder_of_the_division.pack(side=LEFT,expand=1,fill=BOTH)
rd3.pack(expand=1,fill=BOTH)
srt.pack(side=LEFT,expand=1,fill=BOTH)
n4.pack(side=LEFT,expand=1,fill=BOTH)
n5.pack(side=LEFT,expand=1,fill=BOTH)
n6.pack(side=LEFT,expand=1,fill=BOTH)
multiplication.pack(side=LEFT,expand=1,fill=BOTH)
subtraction.pack(side=LEFT,expand=1,fill=BOTH)
rd4.pack(expand=1,fill=BOTH)
f1.pack(side=LEFT,expand=1,fill=BOTH)
n1.pack(side=LEFT,expand=1,fill=BOTH)
n2.pack(side=LEFT,expand=1,fill=BOTH)
n3.pack(side=LEFT,expand=1,fill=BOTH)
addition.pack(side=LEFT,expand=1,fill=BOTH)
equally.pack(side=LEFT,expand=1,fill=BOTH)
rd5.pack(expand=1,fill=BOTH)
ce.pack(side=LEFT,expand=1,fill=BOTH)
n0.pack(side=LEFT,expand=1,fill=BOTH)
n00.pack(side=LEFT,expand=1,fill=BOTH)
point.pack(side=LEFT,expand=1,fill=BOTH)
exponentiation.pack(side=LEFT,expand=1,fill=BOTH)
#Function
def click_n1(root):
	global inpt
	inpt=str(inpt)+str(1)
	Tablo.configure(text=str(inpt))
def click_n2(root):
	global inpt
	inpt=str(inpt)+str(2)
	Tablo.configure(text=str(inpt))
def click_n3(root):
	global inpt
	inpt=str(inpt)+str(3)
	Tablo.configure(text=str(inpt))
def click_n4(root):
	global inpt
	inpt=str(inpt)+str(4)
	Tablo.configure(text=str(inpt))
def click_n5(root):
	global inpt
	inpt=str(inpt)+str(5)
	Tablo.configure(text=str(inpt))
def click_n6(root):
	global inpt
	inpt=str(inpt)+str(6)
	Tablo.configure(text=str(inpt))
def click_n7(root):
	global inpt
	inpt=str(inpt)+str(7)
	Tablo.configure(text=str(inpt))
def click_n8(root):
	global inpt
	inpt=str(inpt)+str(8)
	Tablo.configure(text=str(inpt))
def click_n9(root):
	global inpt
	inpt=str(inpt)+str(9)
	Tablo.configure(text=str(inpt))
def click_n0(root):
	global inpt
	inpt=str(inpt)+str(0)
	Tablo.configure(text=str(inpt))
def click_n00(root):
	global inpt
	inpt=str(inpt)+'00'
	Tablo.configure(text=str(inpt))
def click_point(root):
	global inpt
	inpt=str(inpt)+'.'
	Tablo.configure(text=str(inpt))
def click_ma(root):
	global inpt
	global inpt1
	global v
	global m
	m=str(inpt)
	MemoryTablo.configure(text='Memory: '+str(m))
def click_mr(root):
	global inpt
	global inpt1
	global v
	global m
	inpt=str(m)
	Tablo.configure(text=str(inpt))
def click_mc(root):
	global inpt
	global inpt1
	global v
	global m
	m=''
	MemoryTablo.configure(text='Memory: '+str(m))
def click_ms(root):
	global inpt
	global inpt1
	global v
	global m
	m=str(float(m)-float(inpt))
	MemoryTablo.configure(text='Memory: '+str(m))
def click_ac(root):
	global inpt
	global inpt1
	global v
	global m
	click_ce(root)
	m=''
	MemoryTablo.configure(text='')
def click_ce(root):
	global inpt
	global inpt1
	global v
	v=''
	inpt=''
	inpt1=''
	Tablo.configure(text=str(inpt))
	Tablo2.configure(text='')
def click_addition(root):
	global inpt
	global inpt1
	global v
	inpt1=str(inpt)
	inpt=''
	Tablo.configure(text=str(inpt))
	Tablo2.configure(text=str(inpt1+' +'))
	v='+'
def click_subtraction(root):
	global inpt
	global inpt1
	global v
	inpt1=str(inpt)
	inpt=''
	Tablo.configure(text=str(inpt))
	Tablo2.configure(text=str(inpt1+' -'))
	v='-'
def click_multiplication(root):
	global inpt
	global inpt1
	global v
	inpt1=str(inpt)
	inpt=''
	Tablo.configure(text=str(inpt))
	Tablo2.configure(text=str(inpt1+' *'))
	v='*'
def click_division(root):
	global inpt
	global inpt1
	global v
	inpt1=str(inpt)
	inpt=''
	Tablo.configure(text=str(inpt))
	Tablo2.configure(text=str(inpt1+' /'))
	v='/'
def click_remainder_of_the_division(root):
	global inpt
	global inpt1
	global v
	inpt1=str(inpt)
	inpt=''
	Tablo.configure(text=str(inpt))
	Tablo2.configure(text=str(inpt1+' %'))
	v='%'
def click_srt(root):
	global inpt
	global inpt1
	global v
	inpt1=str(inpt)
	inpt=''
	Tablo.configure(text=str(inpt))
	Tablo2.configure(text=str(inpt1+' \/-'))
	v='\/-'
def click_m0(root):
	global inpt
	inpt = inpt[:-1]
	Tablo.configure(text=str(inpt))
def click_equally(root):
	global inpt
	global inpt1
	global v
	if(v=='+'):
		if inpt == '2' and inpt1 == '2':  # Пасхалка 2 + 2 = 5000
			inpt = 5000
		elif inpt == '1' and inpt1 == '1': # Пасхалка 1 + 1 = грибы
			inpt = 'грибы'
		else:
			inpt=float(inpt1)+float(inpt)
	elif(v=='-'):
		inpt=float(inpt1)-float(inpt)
	elif(v=='*'):
		inpt=float(inpt1)*float(inpt)
	elif(v=='/'):
		inpt=float(inpt1)/float(inpt)
	elif(v=='%'):
		inpt=float(inpt1)%float(inpt)
	elif(v=='\/-'):
		inpt=float(inpt1)**(1/float(inpt))
	elif(v=="^"):
		inpt=float(inpt1)**float(inpt)
	Tablo.configure(text=str(inpt))
	Tablo2.configure(text='')
def expon(root):
	global inpt
	global inpt1
	global v
	inpt1=str(inpt)
	inpt=''
	Tablo.configure(text=str(inpt))
	Tablo2.configure(text=str(inpt1+' ^'))
	v='^'
n1.bind('<Button>',click_n1)
n2.bind('<Button>',click_n2)
n3.bind('<Button>',click_n3)
n4.bind('<Button>',click_n4)
n5.bind('<Button>',click_n5)
n6.bind('<Button>',click_n6)
n7.bind('<Button>',click_n7)
n8.bind('<Button>',click_n8)
n9.bind('<Button>',click_n9)
n0.bind('<Button>',click_n0)
n00.bind('<Button>',click_n00)
point.bind('<Button>',click_point)
ce.bind('<Button>',click_ce)
mc.bind('<Button>',click_mc)
ma.bind('<Button>',click_ma)
mr.bind('<Button>',click_mr)
ms.bind('<Button>',click_ms)
addition.bind('<Button>',click_addition)
subtraction.bind('<Button>',click_subtraction)
multiplication.bind('<Button>',click_multiplication)
division.bind('<Button>',click_division)
remainder_of_the_division.bind('<Button>',click_remainder_of_the_division)
srt.bind('<Button>',click_srt)
m0.bind('<Button>',click_m0)
equally.bind('<Button>',click_equally)
exponentiation.bind('<Button>',expon)
#Setup
root.mainloop()

Графический калькулятор на Tkinter.pyw

Графический калькулятор на Tkinter.pyw