# -*- coding: utf-8 -*-
"""A class to clean the dataset."""
import re
from datetime import datetime

class BaselinerClean:
    def __init__(
            self, num_atleast_rating, size_subset,
            date_from, date_to, domain_label):
        """initialize  parameter.
        Args:
            num_atleast_rating:
                For each user, it rated at least 'num_atleast_rating' items.
            size_subset:
                The number of observation we want to choose.
            date_from:
                The starting date of ratings.
            date_to:
                The end date of ratings.
            domain_label:
                Add a domain label to the original dataset.
        """
        self.num_atleast_rating = num_atleast_rating
        self.size_subset = size_subset
        self.period = range(date_from, date_to + 1)
        self.label = domain_label

    def parse_time(self, s):
        """convert unix timestamp to readable date.
        Args:
            s: unix timestamp (string)
        Returns:
            datetime
        """
        return datetime.fromtimestamp(float(s))

    def parse_line(self, iterators):
        """parse a line.
        Args:
            iterators: data in lines with format: 'uid, iid, rating, datetime'.
        Returns:
            (uid, [iid + domain_label, rating, datetime])
        """
        for line in iterators:
            splitted_line = re.split('\\s+', line)
            parsed_time = self.parse_time(splitted_line[3])
            if parsed_time.year in self.period:
                yield (
                    splitted_line[0], (
                        splitted_line[1] + self.label,
                        float(splitted_line[2]), parsed_time))

    def parse_data(self, originalRDD):
        """parse the dataset."""
        return originalRDD.mapPartitions(self.parse_line)

    def take_partial_data(self, dataRDD):
        """take partial data to do the computation."""
        return dataRDD.take(self.size_subset)

    def remove_invalid(self, iterators):
        """remove invalid rating, e.g., old or duplicate.
        iterators is a set of line in the form of [uid, (iid, rating, time)*].
        """
        def check_invalid(line, tmpdict):
            """check data and update invalid data.
            e.g., we only use latest data.
            """
            iid, rating, time = line
            if time > tmpdict[iid][2]:
                tmpdict[iid] = line
            return tmpdict

        for uid, ratings in iterators:
            tmpdict = {}
            for token in ratings:
                # token: in the form of (iid, rating, time)
                if token[0] in tmpdict.keys():
                    tmpdict = check_invalid(token, tmpdict)
                else:
                    tmpdict[token[0]] = token
            yield uid, list(tmpdict.values())

    def filter_data(self, dataRDD):
        """filter the invalid data.
        e.g., 1. duplicate data; 2. same uid, iid, but with different rating.
        """
        seq_op = (lambda a, b: a + [b])
        comb_op = (lambda a, b: a + b)
        groupedRDD = dataRDD.aggregateByKey([], seq_op, comb_op)
        return groupedRDD.mapPartitions(self.remove_invalid)

    def clean_data(self, filteredRDD):
        """remove users who have low rating frequency."""
        return filteredRDD.filter(
            lambda line: len(line[1]) >= self.num_atleast_rating)


#!/usr/bin/env python
# -*- coding: utf-8 -*-

import numpy as np
from scipy.spatial import distance_matrix

class OEM_batch:
    """
    On line Elastic Similarity class

    Parameters
    ----------
    R : 1-D array_like
        time series pattern
    w : float
        On-line similarity measure memory. Must be between 0 and 1.
    rateX : float, optional, default: 1
        Reference Time series generate_files rate
    rateY : float, optional, default: None
        Query Time series generate_files rate. If rateY = None it takes rateX value
    dist : string, optional, default: 'euclidean'
        cost function
        OPTIONS:
        'euclidean': np.sqrt((x_i - y_j)**2)
        'edr':       1 if abs(x_i - y_j) >= epsilon else 0
        'edit':      1 if x_i != y_j else 0
        'erp':       abs(x_i - y_j) if abs(x_i - y_j) >= epsilon else 0
    epsilon : float, optional, default: None
        edr threshold parameter
    """

    def __init__(self, R, w, dist='euclidean', epsilon=None):

        if dist in ['euclidean', 'edr', 'erp', 'edit', 'euclidean_new']:
            self.dist = dist
        else:
            raise ValueError('Not valid dist value')

        if isinstance(R, (np.ndarray)) and R.size > 2:
            self.R = R

        if (w >= 0) and (w <= 1):
            self.w = w
        else:
            raise ValueError('w must be between 0 and 1')

        if (epsilon is None) and (dist in ['edr', 'erp']):
            raise ValueError(
                'for dist edr or erp epsilon must be a non negative float')
        elif (epsilon is not None) and epsilon < 0:
            raise ValueError('epsilon must be a non negative float')
        self.epsilon = epsilon

    def init_dist(self, S):
        """
        Initial Similarity Measure

        Parameters
        ----------
        S : 1-D array_like
            Array containing time series observations

        Returns
        -------
        dist: float
            Elastic Similarity Measure between R (pattern time series) and S (query time series)
        """

        if isinstance(S, (np.ndarray)) and S.size > 2:
            pass
        else:
            raise ValueError('S time series must have more than 2 instances')

        # Compute point-wise distance
        if self.dist == 'euclidean':
            RS = self.__euclidean(self.R, S)
        if self.dist == 'euclidean_new':
            RS = self.__euclidean_new(self.R, S)
        elif self.dist == 'edr':
            RS = self.__edr(self.R, S, self.epsilon)
        elif self.dist == 'erp':
            RS = self.__erp(self.R, S, self.epsilon)
        elif self.dist == 'edit':
            RS = self.__edit(self.R, S)

        # compute recursive distance matrix using dynamic programing
        r, s = np.shape(RS)

        # Solve first row
        for j in range(1, s):
            RS[0, j] += self.w * RS[0, j - 1]

        # Solve first column
        for i in range(1, r):
            RS[i, 0] += RS[i - 1, 0]

        # Solve the rest
        for i in range(1, r):
            for j in range(1, s):
                RS[i, j] += np.min([RS[i - 1, j], self.w *
                                    RS[i - 1, j - 1], self.w * RS[i, j - 1]])

        # save statistics
        self.dtwR = RS[:, -1]

        return RS

    def update_dist(self, Y):
        '''
        Add new observations to query time series

        Parameters
        ----------
        Y : array_like or float
            new query time series observation(s)

        Returns
        -------
        dist : float
            Updated distance

        Warning: the time series have to be non-empty
        (at least composed by a single measure)

          -----------
        R | RS | RY |
          -----------
            S    Y
        '''

        if isinstance(Y, (np.ndarray)):
            pass
        else:
            Y = np.array([Y])

        # Solve RY
        dtwRY = self._solveRY(Y, self.dtwR)

        # Save statistics
        self.dtwR = dtwRY

        return dtwRY

    def __euclidean(self, X, Y):
        Y_tmp, X_tmp = np.meshgrid(Y, X)
        XY = np.sqrt((X_tmp - Y_tmp)**2)
        return XY

    def __euclidean_new(self, X, Y):
        return distance_matrix(X, Y, p=2)**2

    def __edr(self, X, Y, epsilon):
        Y_tmp, X_tmp = np.meshgrid(Y, X)
        XY = 1.0 * (abs(X_tmp - Y_tmp) < epsilon)
        return XY

    def __erp(self, X, Y, epsilon):
        Y_tmp, X_tmp = np.meshgrid(Y, X)
        XY = abs(X_tmp - Y_tmp)
        XY[XY < epsilon] = 0
        return XY

    def __edit(self, X, Y):
        Y_tmp, X_tmp = np.meshgrid(Y, X)
        XY = 1.0 * (X_tmp == Y_tmp)
        return XY

    def _solveRY(self, Y, dtwR):
        '''
        R, Y: to (partial) time series
         -----------
        R|prev| RY |
         -----------
           S    Y

        dtwR: partial solutions of DTW(R,S)
        iniI: Index of the first point of R in the complete time series
        iniJ: Index of the first point of Y in the complete time series

        * Warning *: R and Y have to be nonempty (partial) series
        '''

        # Compute point-wise distance
        if self.dist == 'euclidean':
            RY = self.__euclidean(self.R, Y)
        if self.dist == 'euclidean_new':
            RY = self.__euclidean_new(self.R, Y)
        elif self.dist == 'edr':
            RY = self.__edr(self.R, Y, self.epsilon)
        elif self.dist == 'erp':
            RY = self.__erp(self.R, Y, self.epsilon)
        elif self.dist == 'edit':
            RY = self.__edit(self.R, Y)

        r, n = np.shape(RY)

        # First first column
        RY[0, 0] += self.w * dtwR[0]
        for i in range(1, r):
            RY[i, 0] += np.min([
                RY[i - 1, 0], self.w * dtwR[i - 1], self.w * dtwR[i]])

        # Solve first row
        for j in range(1, n):
            RY[0, j] += self.w * RY[0, j - 1]

        # Solve the rest
        for j in range(1, n):
            for i in range(1, r):
                RY[i, j] += np.min([RY[i - 1, j], self.w *
                                    RY[i - 1, j - 1], self.w * RY[i, j - 1]])

        return RY[:, -1]


import json
import sys

datoteka = sys.argv[1]
players = []
with open(datoteka, 'r') as f:
    players = (json.load(f))

#print(players)

godine = float(input())
pozicija = int(input())

visina = -1

for player in players:
    if(int(player['visina']) >= 200):
        player['pozicija'] = 5
    elif(int(player['visina']) >= 190):
        player['pozicija'] = 3
    else:
        player['pozicija'] = 1

for player in players:
    if(int(player['godine'] <= godine) and int(player['pozicija']) == pozicija and int(player['visina']) > visina):
        visina = int(player['visina'])
print(visina)


import torch
import torch.nn as nn
import torch.nn.functional as F
from torch import distributions as dist
from torch.autograd import Function
import numpy as np
import math

# from torch_geometric.nn.pool import voxel_grid
import logging

def maxpool(x, dim=-1, keepdim=False):
    out, _ = x.max(dim=dim, keepdim=keepdim)
    return out

# Resnet Blocks
class ResnetBlockFC(nn.Module):
    ''' Fully connected ResNet Block class.

    Args:
        size_in (int): input dimension
        size_out (int): output dimension
        size_h (int): hidden dimension
    '''

    def __init__(self, size_in, size_out=None, size_h=None):
        super().__init__()
        # Attributes
        if size_out is None:
            size_out = size_in

        if size_h is None:
            size_h = min(size_in, size_out)

        self.size_in = size_in
        self.size_h = size_h
        self.size_out = size_out
        # Submodules
        self.fc_0 = nn.Linear(size_in, size_h)
        self.fc_1 = nn.Linear(size_h, size_out)
        self.actvn = nn.ReLU()

        if size_in == size_out:
            self.shortcut = None
        else:
            self.shortcut = nn.Linear(size_in, size_out, bias=False)
        # Initialization
        nn.init.zeros_(self.fc_1.weight)

    def forward(self, x):
        net = self.fc_0(self.actvn(x))
        dx = self.fc_1(self.actvn(net))

        if self.shortcut is not None:
            x_s = self.shortcut(x)
        else:
            x_s = x

        return x_s + dx

class ResnetPointnet(nn.Module):
    ''' PointNet-based encoder network with ResNet blocks.
    Args:
        c_dim (int): dimension of latent code c
        dim (int): input points dimension
        hidden_dim (int): hidden dimension of the network
    '''

    def __init__(self, c_dim=128, dim=3, VAE=False):
        super().__init__()
        self.c_dim = c_dim
        self.vae = VAE

        hidden_dim=128

        self.fc_pos = nn.Linear(dim, 2*hidden_dim)
        self.block_0 = ResnetBlockFC(2*hidden_dim, hidden_dim)
        self.block_1 = ResnetBlockFC(2*hidden_dim, hidden_dim)
        self.block_2 = ResnetBlockFC(2*hidden_dim, hidden_dim)
        self.block_3 = ResnetBlockFC(2*hidden_dim, hidden_dim)
        self.block_4 = ResnetBlockFC(2*hidden_dim, hidden_dim)

        if self.vae:
            self.fc_mean = nn.Linear(hidden_dim, c_dim)
            self.fc_std = nn.Linear(hidden_dim, c_dim)
            torch.nn.init.constant_(self.fc_mean.weight,0)
            torch.nn.init.constant_(self.fc_mean.bias, 0)
            torch.nn.init.constant_(self.fc_std.weight, 0)
            torch.nn.init.constant_(self.fc_std.bias, -10)
            self.fc_c = None
        else:
            self.fc_c = nn.Linear(hidden_dim, c_dim)
            self.fc_mean = None
            self.fc_std = None

        self.actvn = nn.ReLU()
        self.pool = maxpool

    def name(self):
        if self.vae:
            return "ResNetPointNet_VAE"
        else:
            return "ResNetPointNet"

    def forward(self, p):
        batch_size, T, D = p.size()

        # # output size: B x T X F
        net = self.fc_pos(p)
        net = self.block_0(net)
        pooled = self.pool(net, dim=1, keepdim=True).expand(net.size())
        net = torch.cat([net, pooled], dim=2)

        net = self.block_1(net)
        pooled = self.pool(net, dim=1, keepdim=True).expand(net.size())
        net = torch.cat([net, pooled], dim=2)

        net = self.block_2(net)
        pooled = self.pool(net, dim=1, keepdim=True).expand(net.size())
        net = torch.cat([net, pooled], dim=2)

        net = self.block_3(net)
        pooled = self.pool(net, dim=1, keepdim=True).expand(net.size())
        net = torch.cat([net, pooled], dim=2)

        net = self.block_4(net)

        # Recude to  B x F
        net = self.pool(net, dim=1)

        if self.vae:
            c_mean = self.fc_mean(self.actvn(net))
            c_std = self.fc_std(self.actvn(net))
            return c_mean,c_std
        else:
            c = self.fc_c(self.actvn(net))
            return c, None


import json
cache_name = "vgmusic_downloads"
games_file = "games.json"
genres_file = "genres.json"
themes_file = "themes.json"
debug_print = True
games = None
genres = None
themes = None

# backwards compatability. This function was used back when the game database was a python dictionary :puke:
# now its a very lovely json file!
def verify():
    global games, themes, genres
    if games == None:
        with open(games_file) as file:
            games = json.loads(file.read())

#if __name__ == "__main__":
#    try:
#        verify()
#        print("This file is configured correctly!")
#    except AssertionError as e:
#        print("Failed to verify.")
#        print(str(e))


from abc import ABCMeta, abstractmethod

from lib.devices import get_metrics_names

class Connector(object):

    __metaclass__ = ABCMeta

    def __init__(self, publishers, buffer_size, step_size, device_name, device_port, device_mac=None):

      self.metrics = get_metrics_names(device_name)
      self.device = None
      self.device_port = device_port
      self.device_name = device_name
      self.device_mac = device_mac

      self.buffers = {metric: ConnectorBuffer(buffer_size, step_size, publishers[metric].publish) for metric in self.metrics}
      self.publishers = publishers

    @abstractmethod
    def connect_device(self):
      """

      :return:
      """

class ConnectorBuffer(object):

  def __init__(self, buffer_size, step_size, callback):
    self.buffer_size = buffer_size
    self.step_size = step_size
    self.callback = callback
    self.message_buffer = []

    self.count = 0

  def write(self, datum):
    """
    add one data point to the buffer

    :param datum:
    :return:
    """
    self.message_buffer.append(datum)
    self.count += 1

    # print(len(self.message_buffer), self.count, self.step_size, self.buffer_size)

    # if len(self.message_buffer) % self.buffer_size == 0:
    if self.count >= self.step_size and len(self.message_buffer) >= self.buffer_size:
      self.callback(self.message_buffer[-self.buffer_size:])
      self.message_buffer = self.message_buffer[-self.buffer_size:]
      self.count = 0


from collections import defaultdict
class Solution:
    def subarraySum(self, nums: List[int], k: int) -> int:
        d = defaultdict(lambda:0)
        d[0] =1
        s =0
        res =0
        for i in range(len(nums)):
            s+=nums[i]
            if d[s-k]>0:
                res+=d[s-k]
            d[s]+=1
        return res


from typing import List

class NumMatrix:

    def __init__(self, matrix: List[List[int]]):
        self.matrix = matrix
        self.cache = {}

    def sumRegion(self, row1: int, col1: int, row2: int, col2: int) -> int:
        if (row1, col1, row2, col2) in self.cache:
            return self.cache[(row1, col1, row2, col2)]
        else:
            s = sum([sum([self.matrix[row][col] for col in range(col1, col2+1)])
                     for row in range(row1, row2+1)])
            self.cache[(row1, col1, row2, col2)] = s
            return s

# Your NumMatrix object will be instantiated and called as such:
# obj = NumMatrix(matrix)
# param_1 = obj.sumRegion(row1,col1,row2,col2)


import os
import shutil
import wx
import editor.constants as constants

from wx.lib.scrolledpanel import ScrolledPanel
from editor.wxUI.baseTreeControl import BaseTreeControl
from editor.colourPalette import ColourPalette as Colours
from editor.utils.exceptionHandler import try_execute

# icons / thumbnails names
FOLDER_ICON = constants.FILE_EXTENSIONS_ICONS_PATH + "\\" + "folder16.png"

PY_FILE_ICON = constants.FILE_EXTENSIONS_ICONS_PATH + "\\" + "pyFile32.png"
USER_MOD_ICON = constants.FILE_EXTENSIONS_ICONS_PATH + "\\" + "pyFile32.png"
ED_TOOL_ICON = constants.FILE_EXTENSIONS_ICONS_PATH + "\\" + "pyFile32.png"

TXT_FILE_ICON = constants.FILE_EXTENSIONS_ICONS_PATH + "\\" + "textFileIcon.png"

EGG_FILE_ICON = constants.FILE_EXTENSIONS_ICONS_PATH + "\\" + "pandaIcon.png"

SOUND_FILE_ICON = constants.FILE_EXTENSIONS_ICONS_PATH + "\\" + "file_extension_sound.png"
TEXT_FILE_ICON = constants.FILE_EXTENSIONS_ICONS_PATH + "\\" + "file_extension_txt.png"
IMAGE_FILE_ICON = constants.FILE_EXTENSIONS_ICONS_PATH + "\\" + "file_extension_bmp.png"
VIDEO_FILE_ICON = constants.FILE_EXTENSIONS_ICONS_PATH + "\\" + "file_extension_video.png"

COLLAPSE_ICON = constants.FILE_EXTENSIONS_ICONS_PATH + "\\" + "page_white.png"
EXPAND_ICON = constants.FILE_EXTENSIONS_ICONS_PATH + "\\" + "page_white.png"

GENERIC_FILE_ICON = constants.FILE_EXTENSIONS_ICONS_PATH + "\\" + "page_white.png"

# icons for some common file extensions all other will have a generic file icon
EXTENSIONS = {"folder": FOLDER_ICON,

              "egg": EGG_FILE_ICON,
              "bam": EGG_FILE_ICON,
              "pz": EGG_FILE_ICON,

              "tiff": IMAGE_FILE_ICON,
              "tga": IMAGE_FILE_ICON,
              "jpg": IMAGE_FILE_ICON,
              "png": IMAGE_FILE_ICON,

              "py": PY_FILE_ICON,
              "txt": TXT_FILE_ICON,

              "mp4": VIDEO_FILE_ICON,
              "mp3": IMAGE_FILE_ICON,

              "generic": GENERIC_FILE_ICON,
              }

# event ids for different event types
EVT_NEW_DIR = wx.NewId()
EVT_RENAME_ITEM = wx.NewId()
EVT_DUPLICATE_ITEM = wx.NewId()
EVT_REMOVE_ITEM = wx.NewId()
EVT_SHOW_IN_EXPLORER = wx.NewId()

EVT_CREATE_PY_MOD = wx.NewId()
EVT_CREATE_TXT_FILE = wx.NewId()
EVT_CREATE_P3D_USER_MOD = wx.NewId()
EVT_CREATE_ED_TOOL = wx.NewId()

EVT_LOAD_MODEL = wx.NewId()
EVT_LOAD_ACTOR = wx.NewId()

EVT_APPEND_LIBRARY = wx.NewId()
EVT_IMPORT_ASSETS = wx.NewId()

def build_menu(menu, items):
    for i in range(len(items)):
        _items = items[i]

        if _items == "":
            menu.AppendSeparator()
            continue

        menu_item = wx.MenuItem(menu, _items[0], _items[1])
        # menu_item.SetBitmap(wx.Bitmap('exit.png'))
        menu.Append(menu_item)

class _ResourceBrowser(ScrolledPanel):
    def __init__(self, *args, **kwargs):
        ScrolledPanel.__init__(self, *args, **kwargs)

        self.wx_main = args[0]

        self.resource_browser = ResourceBrowser(self, self.wx_main)

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.resource_browser, 1, wx.EXPAND)

        self.SetSizer(sizer)
        self.Layout()
        self.SetupScrolling()

class ResourceBrowser(BaseTreeControl):
    def __init__(self, parent, wx_main, *args, **kwargs):
        BaseTreeControl.__init__(self, parent, *args, **kwargs)

        self.wx_main = wx_main
        constants.object_manager.add_object("ProjectBrowser", self)
        self.organize_tree = True  # organize a tree based on file_extensions

        # ---------------------------------------------------------------------------- #
        self.SetBackgroundColour(Colours.NORMAL_GREY)
        self.SetWindowStyleFlag(wx.BORDER_SUNKEN)

        agw_win_styles = wx.TR_DEFAULT_STYLE | wx.TR_SINGLE | wx.TR_MULTIPLE | wx.TR_HIDE_ROOT
        agw_win_styles |= wx.TR_TWIST_BUTTONS  # | wx.TR_NO_LINES

        self.SetAGWWindowStyleFlag(agw_win_styles)
        self.SetIndent(10)
        self.SetSpacing(10)

        self.SetBorderPen(wx.Pen((0, 0, 0), 0, wx.TRANSPARENT))
        self.EnableSelectionGradient(True)
        self.SetGradientStyle(True)
        self.SetFirstGradientColour(wx.Colour(46, 46, 46))
        self.SetSecondGradientColour(wx.Colour(123, 123, 123))

        # ---------------------------------------------------------------------------- #
        self.image_index = {}  # associates an extension which indexes into tree image_list
        self.image_list = wx.ImageList(16, 16)  # create an image list for tree control to use

        i = 0
        for ext in EXTENSIONS.keys():
            self.image_index[ext] = i
            icon_bitmap = wx.Bitmap(EXTENSIONS[ext])  # create a bitmap
            self.image_list.Add(icon_bitmap)  # and append it to image list
            i = i + 1

        # and one finally for generic file icon
        icon_bitmap = wx.Bitmap(GENERIC_FILE_ICON)
        self.image_list.Add(icon_bitmap)

        self.SetImageList(self.image_list)
        # ---------------------------------------------------------------------------- #

        self.root_node = self.AddRoot("RootNode", image=self.image_index["folder"], data="")
        self.root_path = ""

        # for drag drop operations
        self.mouse_left_down = False
        self.is_dragging = False

        # ---------------------------------------------------------------------------- #
        self.libraries = {}  # all current loaded libraries
        self.resources = {}  # maps and saves all loaded resources e.g [py] = {all .py resources}...
        self.name_to_item = {}  # maps a file's or directory's name to it's corresponding tree item
        # e.g. name_to_item[file_name] = item

        # ---------------------------------------------------------------------------- #
        # file menus associates a file extension with, or an extension with a function,
        # which creates its menus, to be used in popup menus
        self.file_menus = {
            "directory": [self.create_add_menu_items, self.create_generic_menu_items],
            "py": [self.create_generic_menu_items],
            "txt": [self.create_generic_menu_items],
            "generic": [self.create_generic_menu_items],
            "pz": [self.create_3d_model_menu_items, self.create_generic_menu_items],
            "egg": [self.create_3d_model_menu_items, self.create_generic_menu_items],
            "fbx": [self.create_3d_model_menu_items, self.create_generic_menu_items],
            "obj": [self.create_3d_model_menu_items, self.create_generic_menu_items]
        }

        self.event_map = {
            EVT_NEW_DIR: (self.on_file_op, "add_folder"),
            EVT_RENAME_ITEM: (self.on_file_op, "rename_item"),
            EVT_DUPLICATE_ITEM: (self.on_file_op, "duplicate"),
            EVT_REMOVE_ITEM: (self.on_file_op, "remove_item"),
            EVT_SHOW_IN_EXPLORER: (self.on_file_op, "show_in_explorer"),

            EVT_CREATE_PY_MOD: (self.create_asset, "py_mod"),
            EVT_CREATE_TXT_FILE: (self.create_asset, "txt_file"),
            EVT_CREATE_P3D_USER_MOD: (self.create_asset, "p3d_user_mod"),
            EVT_CREATE_ED_TOOL: (self.create_asset, "p3d_ed_tool"),

            EVT_LOAD_MODEL: (self.load_model, None),
            EVT_LOAD_ACTOR: (self.load_actor, None),

            EVT_APPEND_LIBRARY: (self.append_library, None),
            EVT_IMPORT_ASSETS: (self.import_assets, None),
        }

        # bind event handlers with corresponding method calls
        self.Bind(wx.EVT_TREE_ITEM_EXPANDED, self.on_item_expanded)
        self.Bind(wx.EVT_TREE_ITEM_COLLAPSED, self.on_item_collapsed)
        self.Bind(wx.EVT_TREE_SEL_CHANGED, self.on_item_selected)
        self.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self.on_item_activated)

        # self.Bind(wx.EVT_LEFT_DOWN, self.on_evt_left_down)
        # self.Bind(wx.EVT_LEFT_UP, self.on_evt_left_up)
        # self.Bind(wx.EVT_MOTION, self.on_evt_mouse_move)

        self.Bind(wx.EVT_TREE_ITEM_RIGHT_CLICK, self.create_popup_menu)
        self.Bind(wx.EVT_MENU, self.on_select_context)

    files_and_extensions = {}  # temporarily saves all files with same extensions when organizing tree
    tmp_selections = []

    # ----------------- All methods bounded to different tree events ----------------- #
    def on_item_expanded(self, event):
        event.Skip()

    def on_item_collapsed(self, event):
        event.Skip()

    def on_item_selected(self, evt):
        selections = []
        for item in self.GetSelections():
            name = self.GetItemText(item)
            data = self.GetItemData(item)
            selections.append((name, data))

        constants.obs.trigger("SelectTreeItem", selections)
        evt.Skip()

    def on_item_activated(self, evt):
        item_path = self.GetItemData(self.GetSelection())
        if os.path.isfile(item_path) and item_path.split(".")[-1] == "py":
            pass
            # self.open_file(item_path)
        evt.Skip()

    def create_popup_menu(self, evt):
        selections = self.GetSelections()

        if len(selections) > 1:
            item_ext = "generic"
        else:
            item = selections[0]
            item_path = self.GetItemData(item)
            item_text = self.GetItemText(item)
            item_ext = item_text.split(".")[-1]  # file_extension
            is_item_dir = os.path.isdir(item_path)

            if is_item_dir:
                item_ext = "directory"
            elif item_ext not in self.file_menus.keys():
                item_ext = "generic"

        popup_menu = wx.Menu()

        for func in self.file_menus[item_ext]:
            func(popup_menu)

        self.PopupMenu(popup_menu, evt.GetPoint())
        popup_menu.Destroy()

        evt.Skip()

    def on_select_context(self, event):
        if event.GetId() in self.event_map.keys():
            foo = self.event_map[event.GetId()][0]
            args = self.event_map[event.GetId()][1]
            foo(args)

        event.Skip()

    # ---------------------- All methods for building tree items ---------------------- #
    def create_or_rebuild_tree(self, path, rebuild_event: bool):
        """rebuild a tree from scratch from argument path or rebuild tree from libraries if rebuild_event"""
        if not rebuild_event:
            # print("ResourceBrowser --> Building resources")

            assert os.path.exists(path), "error: path does not exist"
            assert os.path.isdir(path), "error: path is not a directory"

            self.libraries.clear()
            self.resources.clear()
            self.name_to_item.clear()
            self.DeleteChildren(self.GetRootItem())

            self.root_path = path

            # create a key for each know file type
            for ext in EXTENSIONS.keys():
                self.resources[ext] = []

            # setup a default project library
            parent_item = self.AppendItem(self.root_node, "Project", data=path, image=self.image_index["folder"])
            self.name_to_item["Project"] = parent_item
            self.libraries["Project"] = path

            self.UnselectAll()
            self.create_tree_from_dir(dir_path=path, parent=parent_item)
            self.ExpandAll()
        else:
            # print("ResourceBrowser --> Rebuilding resources")

            selection = self.GetSelection()
            if selection:
                selection = self.GetItemText(selection)
            self.UnselectAll()

            self.DeleteChildren(self.GetRootItem())  # delete all children
            self.resources.clear()  # unload all resources

            # save the root parent item before clearing name_to_items
            parent = self.name_to_item["Project"]
            self.name_to_item.clear()
            self.name_to_item["Project"] = parent
            del parent

            # create a key for each know file type
            for ext in EXTENSIONS.keys():
                self.resources[ext] = []

            # recreate all the libraries
            for key in self.libraries.keys():
                path = self.libraries[key]
                parent_item = self.AppendItem(self.root_node, key, data=path, image=self.image_index["folder"])
                self.create_tree_from_dir(path, parent_item)

            self.ExpandAll()
            self.Refresh()

    def create_tree_from_dir(self, dir_path=None, parent=None):
        def append_item(_file_path, _file_name):
            extension = _file_path.split(".")[-1]

            if extension in EXTENSIONS:
                icon = self.image_index[extension]
            else:
                icon = self.image_index["generic"]

            # make sure extension exists otherwise add a new key
            if extension in self.resources.keys():
                pass
            else:
                self.resources[extension] = []

            __item = self.AppendItem(parent, file, data=file_path, image=icon)
            self.name_to_item[file] = __item
            self.resources[extension].append(_file_path)
            # self.SetItemTextColour(item, wx.Colour(255, 255, 190, 255))

        dir_files = os.listdir(dir_path)

        tmp_files = []
        folders = []
        for _item in dir_files:
            is_file = os.path.isfile(dir_path + "/" + _item)
            if is_file:
                tmp_files.append(_item)
            else:
                folders.append(_item)

        self.files_and_extensions.clear()
        self.organize(tmp_files)

        tmp = []
        for key in self.files_and_extensions.keys():
            tmp += self.files_and_extensions[key]
        tmp += folders
        dir_files = tmp

        for file in dir_files:
            file_path = dir_path + "/" + file

            if os.path.isdir(file_path) and file != "__pycache__":
                item = self.AppendItem(parent, file, data=file_path, image=self.image_index["folder"])
                # self.SetItemTextColour(item, wx.Colour(255, 255, 190, 255))
                self.Expand(item)
                self.name_to_item[file] = item

                self.create_tree_from_dir(file_path, item)

            elif os.path.isfile(file_path) and file != "__init__":
                append_item(file_path, file)

    def organize(self, _files):
        while len(_files) != 0:
            _file = _files.pop()
            extension = _file.split(".")[-1]
            if extension not in self.files_and_extensions.keys():
                self.files_and_extensions[extension] = []
            self.files_and_extensions[extension].append(_file)
            self.organize(_files)

    def append_library(self, name, path):
        self.libraries[name] = path
        return True

    # ----------------- All methods for building context menus ----------------- #
    def create_add_menu_items(self, parent_menu):
        # add objects menu
        objects_items = [
            (EVT_CREATE_PY_MOD, "&Python Module", None),
            (EVT_CREATE_P3D_USER_MOD, "&User Module", None),
            (EVT_CREATE_ED_TOOL, "&Editor Plugin", None),
            (EVT_CREATE_TXT_FILE, "&Text File", None),
            (EVT_NEW_DIR, "&New Folder", None)
        ]
        objects_menu = wx.Menu()
        build_menu(objects_menu, objects_items)
        parent_menu.Append(wx.ID_ANY, "Add", objects_menu)

        # import assets menu
        import_assets_item = wx.MenuItem(parent_menu, EVT_IMPORT_ASSETS, "Import Assets")
        parent_menu.Append(import_assets_item)
        parent_menu.AppendSeparator()

        # show in explorer menu
        library_items = [(EVT_SHOW_IN_EXPLORER, "&Show In Explorer", None)]
        build_menu(parent_menu, library_items)

    def create_3d_model_menu_items(self, parent_menu):
        menu_items = [(EVT_LOAD_MODEL, "&Load Model", None),
                      (EVT_LOAD_ACTOR, "&Load Actor", None)]
        build_menu(parent_menu, menu_items)

    def create_generic_menu_items(self, parent_menu):
        menu_items = [(EVT_RENAME_ITEM, "&Rename", None),
                      (EVT_REMOVE_ITEM, "&Remove", None),
                      (EVT_DUPLICATE_ITEM, "&Duplicate", None)]
        build_menu(parent_menu, menu_items)

    # ----------------- file explorer operations ----------------- #
    def on_file_op(self, op, *args, **kwargs):
        def can_perform_operation():
            if self.GetSelection() == self.GetRootItem():
                return False
            return True

        if op == "add_folder":
            curr_dir = self.GetItemData(self.GetSelection())
            self.add_dir(curr_dir)

        elif op == "show_in_explorer":
            self.show_in_explorer(self.GetItemData(self.GetSelection()))

        elif op == "rename_item" and can_perform_operation():
            self.rename_item()

        elif op == "duplicate" and can_perform_operation():
            self.duplicate()

        elif op == "remove_item" and can_perform_operation():
            self.remove_item()

    def do_drag_drop(self, src_item: str, target_item: str):
        src_file = self.GetItemData(src_item)
        target_dir = self.GetItemData(target_item)

        # move a source file to target directory, the source file and target directory must exist,
        """src=source file, target=target directory"""
        # make sure source is a file & target directory exists
        if not os.path.isfile(src_file) or not os.path.isdir(target_dir):
            print("file move operation failed")
            return False

        # generate a new target file path, to move src_file to, by combining target_dir with src_file_name
        target_file = target_dir + "/" + src_file.split("/")[-1]

        # ---------------TO:DO---------------
        # make sure the target_file already does not exist, if it does exist then ask
        # user for a file overwrite operation
        if os.path.isfile(target_file):
            msg = "file {0} already exists in directory {1}".format(src_file, target_dir)
            print(msg)
            return

        shutil.move(src_file, target_file)
        # print("from {0} <==TO==> {1}".format(src_file, target_dir))
        return True

    @staticmethod
    def show_in_explorer(path):
        path = os.path.realpath(path)
        os.startfile(path)

    @staticmethod
    def add_dir(curr_directory):
        """adds a new directory and returns it"""

        def on_ok(_new_dir_name):
            if _new_dir_name == "":
                return

            curr_dir = curr_directory
            new_dir = curr_dir + "/" + _new_dir_name
            os.mkdir(new_dir)
            return _new_dir_name

        wx_main = constants.object_manager.get("WxMain")
        dm = wx_main.dialogue_manager
        dm.create_dialog("TextEntryDialog", "New Directory", dm, descriptor_text="Enter name", ok_call=on_ok)

    def rename_item(self):
        def on_ok(text):
            if text == "" or text in self.name_to_item:
                print("FileRenameError: incorrect name entry or name already exits")
                return

            selection = self.GetSelection()

            old_dir_path = self.GetItemData(selection)
            old_dir_name = old_dir_path.split("/")[-1]
            new_dir = old_dir_path[:len(old_dir_path) - len(old_dir_name) - 1]
            new_dir = new_dir + "/" + text

            # if the selected item is a library item, then remove existing library entry,
            # and create a new one with existing data as of original entry
            item_text = self.GetItemText(selection)
            if item_text in self.libraries.keys():
                # also make sure libraries does not have an existing entry matching new text
                if text not in self.libraries.keys():
                    del self.libraries[item_text]
                    self.libraries[text] = old_dir_path
                else:
                    print("ProjectBrowser: rename op failed")
            else:
                os.rename(old_dir_path, new_dir)
                self.SetItemData(self.GetSelection(), new_dir)

            # update tree controls
            self.SetItemText(self.GetSelection(), text)

        dm = self.wx_main.dialogue_manager
        dm.create_dialog("TextEntryDialog",
                         "Rename Item", dm, descriptor_text="Rename Selection", ok_call=on_ok,
                         initial_text=self.GetItemText(self.GetSelection()))

    def duplicate(self, *args):
        def get_unique_file_name(_file_name, _ext, _original):
            """Provided a file_name, it's extension and original file this function returns
            a unique file_name with same name, extension and path as of original"""

            is_name_unique = False
            counter = 0
            max_count = 5

            _unique_name = ""

            head, tail = os.path.split(_original)

            while not is_name_unique:

                # to break free from while loop
                counter += 1
                if counter > max_count:
                    break

                # create a unique file name by adding a number to original file name
                _unique_name = _file_name + str(counter) + _ext
                if not os.path.exists(head + "//" + _unique_name):
                    is_name_unique = True

            if is_name_unique:
                return _unique_name
            return False

        def _duplicate(original_file, new_file_name):
            head, tail = os.path.split(original_file)  # name and path of original file
            _new_file = head + "//" + new_file_name  # path of original + new file's name
            shutil.copy(original_file, _new_file)
            print("duplicated {0}".format(_new_file))

        selections = self.GetSelections()

        if len(selections) > 20:
            print("max 20 duplicates allowed...!")
            return

        for sel in selections:
            path = self.GetItemData(sel)
            if os.path.isdir(path):
                pass

            item = self.GetItemText(sel)
            file_name, extension = os.path.splitext(item)  # get file_name and extension

            unique_name = get_unique_file_name(file_name, extension, path)  # get a unique file name
            if unique_name:
                try_execute(_duplicate, path, unique_name)

    def remove_item(self, *args):
        def on_ok():
            selections = self.GetSelections()
            for item in selections:
                item_text = self.GetItemText(item)
                item_path = self.GetItemData(item)

                if item_text == "Project":
                    print("cannot remove project path...!")
                    continue

                if item_text in self.libraries.keys():
                    del self.libraries[item_text]
                    constants.obs.trigger("OnRemoveLibrary", item_path)
                else:
                    result = try_execute(os.remove, item_path)

                    if result:
                        del self.name_to_item[item_text]  # remove from name_to_items
                        self.Delete(item)

        dm = self.wx_main.dialogue_manager
        dm.create_dialog("YesNoDialog", "Delete Item", dm, descriptor_text="Confirm remove selection(s) ?",
                         ok_call=on_ok)

    def create_asset(self, _type):
        def on_ok(text):
            if text == "":
                return

            path = self.GetItemData(self.GetSelection())
            path = path + "/" + text

            if os.path.exists(path):
                print("path already exists...!")
                return

            constants.obs.trigger("CreateAsset", _type, path)

        wx_main = constants.object_manager.get("WxMain")
        dm = wx_main.dialogue_manager
        dm.create_dialog("TextEntryDialog", "CreateNewAsset", dm, descriptor_text="New Asset Name", ok_call=on_ok)

    def load_model(self, *args):
        constants.obs.trigger("WxEvent", constants.ui_Evt_Load_Model, self.GetItemPyData(self.GetSelection()))

    def load_actor(self, *args):
        constants.obs.trigger("WxEvent", constants.ui_Evt_Load_Actor, self.GetItemPyData(self.GetSelection()))

    def import_assets(self, *args):
        def create_wild_card(wild_card=""):
            for ext in EXTENSIONS:
                wild_card += "*" + "." + ext + ";"
            return wild_card

        def copy_item(src_item, _dst):
            shutil.copyfile(src_item, _dst)

        # create wildcard from supported extensions
        wd = "import assets |"
        wd = create_wild_card(wd)

        style = wx.FD_OPEN | wx.FD_FILE_MUST_EXIST | wx.FD_MULTIPLE
        with wx.FileDialog(self, "Import Assets", style=style) as fileDialog:

            if fileDialog.ShowModal() == wx.ID_CANCEL:
                return  # the user changed their mind

            # Proceed to import the selected files
            selected_file_paths = fileDialog.GetPaths()  # paths of all selected files
            target_destination = self.GetItemData(self.GetSelection())  # destination to copy to

            for path in selected_file_paths:
                file_name = path.split("\\")[-1]  # get file name
                new_path = target_destination + "\\" + file_name  # create a new path

                if os.path.exists(new_path):
                    print("copy error file {0} already exists...!".format(file_name))
                    pass

                try_execute(copy_item, path, new_path)  # copy file from path to new_path

    def get_selected_path(self):
        """Get the selected path"""
        sel = self.GetSelection()
        path = self.GetItemPyData(sel)
        return path

    def get_selected_paths(self):
        """Get a list of selected paths"""
        selections = self.GetSelections()
        paths = [self.GetItemPyData(sel) for sel in selections]
        return paths

    def get_item_by_name(self, item_name=""):
        if self.name_to_item.__contains__(item_name):
            return self.name_to_item[item_name]
        return None


# Import necessary modules and classes
from flask import Blueprint, render_template, request, flash, redirect, url_for, jsonify
from flask_login import login_required, current_user
from .models import Post, User, Comment, Like  # Import models from your application
from . import db  # Import the database instance

# Create a Blueprint for this set of views
views = Blueprint("views", __name__)

# Route for the home page
@views.route("/")
@views.route("/home")
@login_required  # Ensure the user is logged in to access this page
def home():
    # Query all posts from the database
    posts = Post.query.all()
    return render_template("home.html", user=current_user, posts=posts)

# Route for creating a new post
@views.route("/create-post", methods=['GET', 'POST'])
@login_required  # Ensure the user is logged in to create a post
def create_post():
    if request.method == "POST":
        text = request.form.get('text')

        if not text:
            flash('Post cannot be empty', category='error')
        else:
            # Create a new post and add it to the database
            post = Post(text=text, author=current_user.id)
            db.session.add(post)
            db.session.commit()
            flash('Post created!', category='success')
            return redirect(url_for('views.home'))

    return render_template('create_post.html', user=current_user)

# Route for deleting a post
@views.route("/delete-post/<id>")
@login_required  # Ensure the user is logged in to delete a post
def delete_post(id):
    post = Post.query.filter_by(id=id).first()

    if not post:
        flash("Post does not exist.", category='error')
    elif current_user.id != post.id:
        flash('You do not have permission to delete this post.', category='error')
    else:
        # Delete the post from the database
        db.session.delete(post)
        db.session.commit()
        flash('Post deleted.', category='success')

    return redirect(url_for('views.home'))

# Route for viewing posts by a specific user
@views.route("/posts/<username>")
@login_required  # Ensure the user is logged in to view posts
def posts(username):
    user = User.query.filter_by(username=username).first()

    if not user:
        flash('No user with that username exists.', category='error')
        return redirect(url_for('views.home'))

    posts = user.posts
    return render_template("posts.html", user=current_user, posts=posts, username=username)

# Route for creating a comment on a post
@views.route("/create-comment/<post_id>", methods=['POST'])
@login_required  # Ensure the user is logged in to create a comment
def create_comment(post_id):
    text = request.form.get('text')

    if not text:
        flash('Comment cannot be empty.', category='error')
    else:
        post = Post.query.filter_by(id=post_id)
        if post:
            # Create a new comment and add it to the database
            comment = Comment(text=text, author=current_user.id, post_id=post_id)
            db.session.add(comment)
            db.session.commit()
        else:
            flash('Post does not exist.', category='error')

    return redirect(url_for('views.home'))

# Route for deleting a comment
@views.route("/delete-comment/<comment_id>")
@login_required  # Ensure the user is logged in to delete a comment
def delete_comment(comment_id):
    comment = Comment.query.filter_by(id=comment_id).first()

    if not comment:
        flash('Comment does not exist.', category='error')
    elif current_user.id != comment.author and current_user.id != comment.post.author:
        flash('You do not have permission to delete this comment.', category='error')
    else:
        # Delete the comment from the database
        db.session.delete(comment)
        db.session.commit()

    return redirect(url_for('views.home'))

# Route for liking/unliking a post
@views.route("/like-post/<post_id>", methods=['POST'])
@login_required  # Ensure the user is logged in to like/unlike a post
def like(post_id):
    post = Post.query.filter_by(id=post_id).first()
    like = Like.query.filter_by(author=current_user.id, post_id=post_id).first()

    if not post:
        return jsonify({'error': 'Post does not exist.'}, 400)
    elif like:
        # User already liked the post, so unlike it
        db.session.delete(like)
        db.session.commit()
    else:
        # User is liking the post
        like = Like(author=current_user.id, post_id=post_id)
        db.session.add(like)
        db.session.commit()

    # Return JSON response with the number of likes and whether the user has liked the post
    return jsonify({"likes": len(post.likes), "liked": current_user.id in map(lambda x: x.author, post.likes)})

# Route for changing the user's password
@views.route('/change_password', methods=['GET'])
@login_required
def change_password():
    user = current_user
    return render_template('change_password.html',user=user)


from setuptools import find_packages, setup

with open("README.md", encoding='utf-8') as f:
    long_description = f.read()

with open('requirements.txt') as f:
    requirements = f.readlines()

setup(name='MEDprofiles',
      version='0.1.0',
      description='Python module for treatment and visualization of medical data.',
      long_description=long_description,
      long_description_content_type="text/markdown",
      author='Sarah Denis',
      author_email='dens1704@usherbrooke.ca',
      url='https://github.com/MEDomics-UdeS/MEDprofiles',
      packages=find_packages(),
      install_requires=requirements
      )


import cv2
import random
import numpy as np
import pandas as pd
import skimage as sk
from skimage import util
from skimage import transform
from scipy.ndimage import rotate
import matplotlib.pyplot as plt
import matplotlib.image as imgsave

def random_rotation(image, xy):
    angle = int(random.uniform(-90, 90))
    im_rot = rotate(image, angle)
    org_center = (np.array(image.shape[:2][::-1])-1)/2.
    rot_center = (np.array(im_rot.shape[:2][::-1])-1)/2.
    org = xy-org_center
    a = np.deg2rad(angle)
    new_x, new_y = np.array([org[:, 0]*np.cos(a) + org[:, 1]*np.sin(a),
            -org[:, 0]*np.sin(a) + org[:, 1]*np.cos(a)])

    return cv2.resize(im_rot, (96, 96)), (new_x + rot_center[0]) * 96/im_rot.shape[0], (new_y + rot_center[1]) * 96/im_rot.shape[0]

def random_noise(image_array, xy):
    ''' Adds random noise to the image. '''

    return sk.util.random_noise(image_array), xy[:, 0], xy[:, 1]

def vertical_flip(image_array, xy):
    ''' Retuns vertically flipped image. '''

    angle = 180
    im_rot = rotate(image, angle)
    org_center = (np.array(image.shape[:2][::-1])-1)/2.
    rot_center = (np.array(im_rot.shape[:2][::-1])-1)/2.
    org = xy-org_center
    a = np.deg2rad(angle)
    new_x, new_y = np.array([org[:, 0]*np.cos(a) + org[:, 1]*np.sin(a),
            -org[:, 0]*np.sin(a) + org[:, 1]*np.cos(a)])

    return cv2.resize(im_rot, (96, 96)), (new_x + rot_center[0]) * 96/im_rot.shape[0], (new_y + rot_center[1]) * 96/im_rot.shape[0]

available_transformations = {
    'rotate': random_rotation,
    'noise': random_noise,
    'vertical_flip': vertical_flip
}

training = pd.read_csv('./data/training.csv')
training = training.dropna()

training['Image'] = training['Image'].apply(lambda x: np.fromstring(x, dtype=int, sep=' ').reshape((96,96)))

X_train = np.asarray([training['Image']], dtype=np.uint8).reshape(training.shape[0], 96, 96)
y_train = training.drop(['Image'], axis=1).to_numpy()

X_augmented = []
Y_augmented = []
for image, label in zip(X_train, y_train):

    # Randomly selecting how many transformations to occur for each image.
    num_transformations_to_apply = random.randint(1, len(available_transformations))

    num_of_transformations_occured = 0

    label = np.resize(label, (15, 2))
    image = image/255.0

    while (num_of_transformations_occured <= num_transformations_to_apply):

        # Randomly selecting which transformation to do.
        key = random.choice(list(available_transformations))
        transformed_image, x, y = available_transformations[key](image, label)

        # transformed_image = cv2.resize(transformed_image, (96, 96))

        num_of_transformations_occured += 1
        new_label = label.copy()
        new_label[:, 0], new_label[:, 1] = x, y
        # print(transformed_image.shape, image.shape)

        X_augmented.append(transformed_image.flatten())
        Y_augmented.append(new_label.flatten())
    X_augmented.append(image.flatten())
    Y_augmented.append(label.flatten())

transformed_df = pd.DataFrame(Y_augmented, columns=training.columns.difference(['Image']))
transformed_df['Image'] = X_augmented
transformed_df['Image'] = [' '.join(list(map(str, i))) for i in transformed_df['Image']]
transformed_df.to_csv('data_set.csv')


# Databricks notebook source
import os
import pandas as pd
import numpy as np
import base64
from tensorflow import keras
import seaborn as sns

from keras.applications.vgg16 import VGG16
from tensorflow.keras.applications.resnet_v2 import ResNet50V2
from sklearn.preprocessing import minmax_scale
from sklearn.metrics import classification_report
from IPython.display import HTML

# COMMAND ----------

container ="data1"
data_path = f"abfss://{container}@capstone2023cuhk.dfs.core.windows.net/"
df_2021 = spark.read.csv(os.path.join(data_path, "AML-data", "Actual_Data_2021-2022", "ITEM_MATCHING_2021_BOOKS.csv"), header=True)
df_2022 = spark.read.csv(os.path.join(data_path, "AML-data", "Actual_Data_2021-2022", "ITEM_MATCHING_2022_BOOKS.csv"), header=True)
df_2021 = df_2021.toPandas()
df_2022 = df_2022.toPandas()

# Img
df_img_2021 = pd.DataFrame(dbutils.fs.ls("/FileStore/Bookimages"))
df_img_2021["PRODUCT_ID"] = df_img_2021["name"].apply(lambda x: x.replace(".jpg", ""))
df_img_2022 = pd.DataFrame(dbutils.fs.ls("/FileStore/Bookimages2022"))
df_img_2022["PRODUCT_ID"] = df_img_2022["name"].apply(lambda x: x.replace(".jpg", ""))

# COMMAND ----------

# Get only usable img: size != 807
df_img_2021 = df_img_2021[df_img_2021["size"] != 807]
df_img_2022 = df_img_2022[df_img_2022["size"] != 807]

df_img_2021 = df_img_2021[["PRODUCT_ID", "name"]]
df_img_2022 = df_img_2022[["PRODUCT_ID", "name"]]

df_2021 = df_2021[df_2021['PRICE']!='0']
df_2021 = df_2021[~df_2021['QTY_SALES'].isin([None, 'MBI       '])]
df_2022 = df_2022[df_2022['PRICE']!='0']
df_2022 = df_2022[~df_2022['QTY_SALES'].isin([None, 'MBI       '])]

df_2021["QTY_SALES"] = df_2021["QTY_SALES"].astype("int64")
df_2022["QTY_SALES"] = df_2022["QTY_SALES"].astype("int64")
df_2021["STD_SALES"] = minmax_scale(df_2021["QTY_SALES"], feature_range=(0, 1), axis=0, copy=True)
df_2022["STD_SALES"] = minmax_scale(df_2022["QTY_SALES"], feature_range=(0, 1), axis=0, copy=True)
# Remove outlier
# df_2021 = df_2021[df_2021['STD_SALES'] < df_2021["STD_SALES"].quantile(0.85)]

# COMMAND ----------

# Pre-processing
df_2021["PRODUCT_ID"] = df_2021["PRODUCT_ID"].apply(lambda x: x.strip())
df_2022["PRODUCT_ID"] = df_2022["PRODUCT_ID"].apply(lambda x: x.strip())

# COMMAND ----------

df_train = df_2021[["PRODUCT_ID", "QTY_SALES", "STD_SALES"]].merge(df_img_2021, on="PRODUCT_ID")
df_test = df_2022[["PRODUCT_ID", "QTY_SALES", "STD_SALES"]].merge(df_img_2022, on="PRODUCT_ID")

# COMMAND ----------

def categorizeSales(threshold, n):
    return "1" if n >= threshold else "0"

df_train["QTY_SALES"] = df_train["STD_SALES"].apply(lambda x: categorizeSales(0.1, x))
df_test["QTY_SALES"] = df_test["STD_SALES"].apply(lambda x: categorizeSales(0.1, x))

# COMMAND ----------

# ResNet50V2
predict_datagen = keras.preprocessing.image.ImageDataGenerator(rescale=1./255)

pred_train_generator=predict_datagen.flow_from_dataframe(
    dataframe=df_train,
    directory="/dbfs/FileStore/Bookimages/",
    x_col="name",
    y_col="QTY_SALES",
    batch_size=32,
    class_mode="binary",
    target_size=(224,224))

pred_test_generator=predict_datagen.flow_from_dataframe(
    dataframe=df_test,
    directory="/dbfs/FileStore/Bookimages2022/",
    x_col="name",
    y_col="QTY_SALES",
    batch_size=32,
    class_mode="binary",
    target_size=(224,224))

# COMMAND ----------

base_model = ResNet50V2(weights='imagenet')

# COMMAND ----------

train_pred = base_model.predict(pred_train_generator,pred_train_generator.n//pred_train_generator.batch_size)
test_pred = base_model.predict(pred_test_generator,pred_test_generator.n//pred_test_generator.batch_size)

# COMMAND ----------

df_train_output = df_train.copy(deep=True)
df_train_output["pred"] = keras.applications.resnet50.decode_predictions(
    train_pred, top=1
)
df_train_output = df_train_output[["PRODUCT_ID", "pred"]]

df_test_output = df_test.copy(deep=True)
df_test_output["pred"] = keras.applications.resnet50.decode_predictions(
    test_pred, top=1
)
df_test_output = df_test_output[["PRODUCT_ID", "pred"]]

# COMMAND ----------

train_cls_table_csv = "resnet50v2_train_output.csv"
test_cls_table_csv = "resnet50v2_test_output.csv"

df_train_output.to_csv("/tmp/{}".format(train_cls_table_csv), index=False)
df_test_output.to_csv("/tmp/{}".format(test_cls_table_csv), index=False)

# COMMAND ----------

dbutils.fs.cp("file:/tmp/{}".format(train_cls_table_csv), "dbfs:/FileStore/output/{}".format(train_cls_table_csv))
dbutils.fs.cp("file:/tmp/{}".format(test_cls_table_csv), "dbfs:/FileStore/output/{}".format(test_cls_table_csv))

# COMMAND ----------

def csv_download_button(df, fname):
    csv = df.to_csv(index=False) #if no filename is given, a string is returned
    b64 = base64.b64encode(csv.encode()).decode()
    href = f'Download CSV File: {fname}'
    display(HTML(href))

# COMMAND ----------

csv_download_button(df_train_output, train_cls_table_csv)
csv_download_button(df_test_output, test_cls_table_csv)

# COMMAND ----------

display(dbutils.fs.ls("/FileStore/output"))

# COMMAND ----------

csv_download_button(df_2021, "df_2021.csv")
csv_download_button(df_2022, "df_2022.csv")

# COMMAND ----------


from nltk.tokenize import RegexpTokenizer
from nltk.corpus import stopwords
import pandas as pd
import nltk
from nltk.tokenize.treebank import TreebankWordDetokenizer
import os.path

class CsvSettings():
    isdata_exist = False

    def csv_parser(self):
        nltk.download('stopwords')

        stop_words = set(stopwords.words('english'))
        regexp = RegexpTokenizer('\w+')

        data = pd.read_csv("rows.csv")

        data.drop(columns=["Date received", "Sub-product", "Sub-issue",
                           "Consumer complaint narrative", "Company public response", "Tags",
                           "Consumer consent provided?", "Submitted via", "Date sent to company",
                           "Company response to consumer", "Timely response?", "Consumer disputed?"],
                  inplace=True, axis=1)

        # Null kayıtların silinmesi
        data = data.dropna()

        for column in data.columns:
            data[column] = data[column].astype(str).str.lower()
            data[column] = data[column].apply(regexp.tokenize)
            data[column] = data[column].apply(
                lambda x: [item for item in x if item not in stop_words])
            data[column] = data[column].apply(
                lambda x: ' '.join([item for item in x if len(item) > 1]))
            data[column] = data[column].astype(
                str).str.replace(r'[^\w\s]+', "", regex=True)

        data = data.dropna()

        data.to_csv("new_rows.csv")

    def use_new_rows(self):

        if (os.path.isfile("new_rows.csv")):
            self.isdata_exist = True
            data = pd.read_csv("new_rows.csv", index_col=0,
                               dtype={'Complaint ID': 'str'})
            print("Dosya kullanıma hazır.")
            return data
        else:
            print("Dosya Oluşturulmamış.\nYeni dosya oluşturluyor.\nLütfen bekleyiniz.. ")
            self.csv_parser()
            return self.use_new_rows()

    def get_column_names(self):
        data = self.use_new_rows()
        if (self.isdata_exist):
            data_top = data.columns.values.tolist()
            print("Sütunlar", data_top)
            return data_top
        else:
            print("Sütunlar bulunamadı çünkü dosya oluşturulmamış")


#Mia Katz
#10.24.18
#Fractals Project
#On my honor, I've neither given nor received unauthorized aid
#The first project is a Mandelbrot, with an ombre pattern replacing anywhere that doesn't escape. It is layered with a small checkerboard for an added effect.
#The second is a Julia with a blurred filter over it. It also has some alternating color stripes
#The third is a mandelbrot divided into four squares. Two of them are very patterned, and the other two have a gradient and a smoothing filter over them!
#Sources: https://lodev.org/cgtutor/juliamandelbrot.html for learning what the Julia set actually is, https://docs.python-guide.org/scenarios/imaging/ for help with Filters, and https://pillow.readthedocs.io/en/5.2.x/reference/ImageFilter.html for even more about the filters. https://www.atopon.org/mandel/# for the zooms on the mandelbrot, and https://www.cs.unm.edu/~stharding/julia/julia.html for the Julia shapes

from PIL import Image, ImageFilter
xa, xb = 0.3038888888, 0.35888888 #This changes the zoom
ya, yb = 0.545, 0.6
jxa, jxb = -0.6, 0.4
imgx, imgy = 512, 512

maxIt = 256

image = Image.new("RGB", (imgx, imgy)) #First Mandelbrot
julia = Image.new("RGB", (imgx, imgy)) #Second Mandelbrot
two = Image.new("RGB", (imgx, imgy)) #Third Mandelbrot

for y in range(imgy):
	cy = y * (yb-ya)/(imgy-1) + ya
	for x in range(imgx):
		cx = x * (xb-xa)/(imgx-1) + xa
		c = complex(cx, cy)
		z = 0
		for i in range(maxIt):
			if abs(z) >= 2.0:
				break
			z = z**2 + c

		if (x%2 == 0 and y%2 == 0) or (x%2 != 0 and y%2 != 0): #These loops here make the checkerboard on the first Mandelbrot
			if 254 > i:
				image.putpixel((x, y), ((i*6)%256, i, 50))
			else: #The checkerboard is also ombre, though very slightly!
				image.putpixel((x, y), (int(y/2), int((y+x)/4), int(x/2)))
		elif 254< i: #This one controls the ombre type effect
			image.putpixel((x,y), (int(x/2), 0, int(y/2)))
		else:
			image.putpixel((x, y), ((i*12)%256, i, (i*86)%256))
print("Mandelbrot 1 Complete") #Completion tracking

d = 0.2314190881763527 #This is the zoom on the Julia. I chose to work with the Julia as I loved the spiral-type patterns, and it was much easier to comprehend due to the work on the Mandelbrot.
e = - 0.5322770541082162
c = complex(d,e)
xa, xb = .245, .345
ya, yb = 0.813, 0.913
maxIt = 256
cy = 0
cx = 0
for y in range(imgy):
	cy = y * (yb-ya)/(imgy-1) + ya
	for x in range(imgx):
		cx = x * (xb-xa)/(imgx-1) + xa
		z = complex(cx, cy)
		for i in range(maxIt):
			if abs(z) >= 2.0:
				break
			z = z**2 + c
		if x< 103 or 206<=x<306 or x>409: #This adds the blue and purple stripes
			julia.putpixel((x,y),(i, 12, (i*68)%256))
		else: #yellow and green stripe
			julia.putpixel((x,y), (i*68%256, i, 12))

print("Julia Complete")

xa, xb = -1.9425254, -1.9425244 #Second mandelbrot zoom, this one is much smaller
ya, yb = -0.0000132425, -0.000012279805

for y in range(imgy):
	cy = y * (yb-ya)/(imgy-1) + ya
	for x in range(imgx):
		cx = x * (xb-xa)/(imgx-1) + xa
		c = complex(cx, cy)
		z = 0
		for i in range(maxIt):
			if abs(z) >= 2.0:
				break
			z = z**2 + c
		if (x > 256 and y > 256) or (x<256 and y<256): #These blocks are the heavily patterned parts of the image. I just picked some random numbers and also used a slight blue gradient on them. It's not the most apparent though, but it was before I separated the picture into the four corners.
			two.putpixel((x, y), ((i*48)%256, (i*1982)%256, int(x/2)))
		else: #This loop is for the gradient corners.
			two.putpixel((x,y), (i, int(y/2), int(x/2)))

print("Done!")
ju = julia.filter(ImageFilter.BLUR) #This blurs the Julia, and I imported ImageFilter from PIL to achieve that.
image.show()
ju.show()
tu = two.filter(ImageFilter.SMOOTH) #This is another filter from PIL's ImageFilter. It was originally set to Emboss, but smooth really emphasized the colors.
tu.show()


# Authour: Samantha Preisig
# File: main.py (driver)
# Brief: creates DynamoDB tables and runs CLI

import configparser
import os
import sys
import boto3
import readline
from botocore.exceptions import ClientError

# Import custom files/modules
import global_vars
from create_table import build_json, create_table
from cli_commands import *

# Purpose: initializing global variables declared in global_vars.py. These
# variables are made global to all modules in the current directory
def set_globals():
    global_vars.init() # Declaring global variables

    # Initialization
    global_vars.dict_tables = {
        "shortlist_area.csv": {"table_name": "spreisig_shortlist_area", "key_columns": ["ISO3"], "columns": []},
        "shortlist_capitals.csv": {"table_name": "spreisig_shortlist_capitals", "key_columns": ["ISO3"], "columns": []},
        "shortlist_curpop.csv": {"table_name": "spreisig_shortlist_curpop", "key_columns": ["Country Name"], "columns": []},
        "shortlist_gdppc.csv": {"table_name": "spreisig_shortlist_gdppc", "key_columns": ["Country Name"], "columns": []},
        "shortlist_languages.csv": {"table_name": "spreisig_shortlist_languages", "key_columns": ["ISO3"], "columns": []},
        "un_shortlist.csv": {"table_name": "spreisig_un_shortlist", "key_columns": ["ISO3"], "columns": []},
        "shortlist_economic": {"table_name": "spreisig_economic", "key_columns": ["Country Name"], "columns": []},
        "shortlist_non_economic": {"table_name": "spreisig_non_economic", "key_columns": ["ISO3"], "columns": []}
    }
    global_vars.data_dir = "data/"
    global_vars.json_dir = global_vars.data_dir+"json/"
    global_vars.help_dir = "help/"
    global_vars.add_records_file = global_vars.data_dir+"add_records.txt"
    global_vars.delete_records_file = global_vars.data_dir+"delete_records.txt"
    global_vars.missing_info_file = global_vars.data_dir+"missing_info.txt"

# Purpose: establishes an AWS session by parsing config file (S5-S3.conf) and setting
# up client and resources
def config_and_setup():
    # AWS access key id and secret access key information found in configuration file (S5-S3.conf)
    config = configparser.ConfigParser()
    config.read("S5-S3.conf")
    aws_access_key_id = config['default']['aws_access_key_id']
    aws_secret_access_key = config['default']['aws_secret_access_key']

    try:
        # Establish an AWS session
        session = boto3.Session(
            aws_access_key_id=aws_access_key_id,
            aws_secret_access_key=aws_secret_access_key
        )
        # Set up client and resources
        dynamodb_res = session.resource('dynamodb', region_name='ca-central-1')
        dynamodb_client = session.client('dynamodb', region_name='ca-central-1')
        return dynamodb_res, dynamodb_client

    except ClientError as e:
        if e.response['Error']['Code'] == 'EntityAlreadyExists':
            print("User already exists")
        else:
            print("Unexpected error: %s" % e)

# Purpose: iterates through data/ directory and converts each csv files to
# json, placing each converted json file into data/json/ directory. After
# all csv files have been converted to json files, create_tables() is called
# to create spreisig_economic and spreisig_non_economic tables containing organized
# information using the converted json files
# Params:
#   - dynamodb_res: high-level abstraction for AWS services requests
#   - dynamodb_client: low-level interface for AWS services requests
def build_tables(dynamodb_res, dynamodb_client):
    filenames = os.listdir(global_vars.data_dir)

    # Removing filenames within the data directory that are not csv files
    filenames.remove(global_vars.add_records_file.replace(global_vars.data_dir, ''))
    filenames.remove(global_vars.delete_records_file.replace(global_vars.data_dir, ''))
    filenames.remove(global_vars.missing_info_file.replace(global_vars.data_dir, ''))
    filenames.remove("json")
    filenames.remove("README.md")

    # Looping through each csv file within the data directory and calling build_json to
    # convert the csv file into a json file
    for filename in filenames:
        table_name = ("spreisig_"+filename).replace('.csv', '')
        build_json(table_name, global_vars.data_dir+filename)
    # Creating economic and non-economic tables
    create_table(dynamodb_res, dynamodb_client, "spreisig_economic")
    create_table(dynamodb_res, dynamodb_client, "spreisig_non_economic")

# Purpose: DRIVER
# Initializes global variables, establishes AWS session, builds economic and non-economic
# tables, and launches CLI for table manipulation and report production
def main():
    # Setting global variables, AWS configuration, and initial bulk creation of tables
    set_globals()
    dynamodb_res, dynamodb_client = config_and_setup()
    build_tables(dynamodb_res, dynamodb_client)

    # CLI
    print("\nWelcome to Sam's custom AWS CLI\nFor help command, type `help`\nTo stop CLI, type `quit`\n")
    while True:
        cli = input("> ").split()
        command = cli[0]
        args = cli[1:]

        if(command == "help"):
            cmd_help(args)

        elif(command == "create_table"):
            cmd_create_table(dynamodb_res, dynamodb_client, args)

        elif(command == "delete_table"):
            cmd_delete_table(dynamodb_client, args)

        elif(command == "add_data"):
            cmd_add_data()
            build_tables(dynamodb_res, dynamodb_client) # Rebuilding tables with updated csv files

        elif(command == "add_records"):
            cmd_add_record(dynamodb_res)

        elif(command == "delete_records"):
            cmd_delete_record(dynamodb_res)

        elif(command == "dump"):
            cmd_dump(dynamodb_res, dynamodb_client, args)

        elif(command == "build_report"):
            cmd_build_report(dynamodb_res, args)

        elif(command == "quit"):
            break

        else:
            print("Not a valid command. Enter `help` for a list of valid commands")

if __name__ == "__main__":
    main()


import csv
import re
import pandas as pd
import seaborn as sb
import matplotlib.pyplot as plt

# Create CSV file and writer
f = open('data.csv', 'w', newline='')
writer = csv.writer(f)

# Regex matches for temp and time
regex = re.compile(": (\d*\.\d*),.*: (\d*)")

# Trying to take care not to load the whole file into memory at once
# in case of larger files with waveforms
with open("data.txt") as data:
    # Go through each line of data.txt
    for line in data:
        # See if it matches with regex
        for match in regex.finditer(line):
            # Write a new row with regex matches
            writer.writerow([match.group(1),match.group(2)])

#Close writer and CSV file, data.csv
f.close()

# Read data.csv, defining column names and setting index column set to 'ms'.
# Files should normally not be large enough to require chunksize...
data = pd.read_csv('data.csv', names=['temp', 'ms'], index_col='ms')

# Rewrite time column to panda timedelta milliseconds
data.index = pd.to_timedelta(data.index, unit='ms')

# Resample to calculate mean temperature and number of events every 30 minutes
resamp = data.resample('30min').agg({'temp': ['mean', 'std', 'count']})

# Flattens multiindex columns and fixes names
resamp.columns = resamp.columns.map('_'.join)

print(resamp)

resamp.to_csv('result.csv')

sb.set_style("darkgrid")

fig, ax =plt.subplots(1,3)

res = sb.lineplot(x='ms', y='temp_mean', data=resamp, ci='temp_std', ax=ax[0])

res.set(xlabel='Time [ms]', ylabel='Mean temperature [°C]')

res2 = sb.lineplot(x='ms', y='temp_count', data=resamp, ax=ax[1], ci='sd')

res2.set(xlabel='Time [ms]', ylabel='# events pr 30 minutes')

res3 = sb.scatterplot(x='temp_count', y='temp_mean', data=resamp, ax=ax[2])

res3.set(xlabel='# events pr 30 minutes', ylabel='Mean temperature [°C]')

plt.show()

fig.savefig("result.pdf", bbox_inches='tight')


N = int(input())

from collections import Counter

C = Counter()
for i in range(N):
    a,b = map(int,input().split())
    C[a]+=1
    C[a+b]-=1

days = sorted(C.keys())
# ans[i] i人ログインしている日数
ans= [0] *(N+1)
prev_day = 0
cnt = 0
for curr_day in days:
    ans[cnt] += curr_day-prev_day
    cnt += C[curr_day]
    prev_day = curr_day
print(*ans[1:])


# -*- coding: gb18030 -*-
#
# $Id: StatWindow.py,fangpengjun Exp $

"""
implement StoreWindow
"""
from Time import Time
from bwdebug import *
from guis import *
import BigWorld
from LabelGather import labelGather
from guis.common.Window import Window
from guis.controls.ODPagesPanel import ODPagesPanel
from guis.general.tradewindow.WareItem import WareItem
from guis.controls.ODComboBox import ODComboBox
from guis.controls.ComboBox import ComboItem
from guis.controls.TextBox import TextBox
from guis.controls.StaticText import StaticText
from guis.controls.ButtonEx import HButtonEx
from guis.controls.ListItem import MultiColListItem
from guis.controls.CheckBox import CheckBoxEx
import event.EventCenter as ECenter
from GUIFacade import MerchantFacade
from config.client.msgboxtexts import Datas as mbmsgs
import csstatus
import csdefine
import csconst
import GUIFacade
import Const
import ShareTexts

g_chs_class = { csdefine.CLASS_FIGHTER	: ShareTexts.PROFESSION_FIGHTER,
			csdefine.CLASS_SWORDMAN	: ShareTexts.PROFESSION_SWORD,
			csdefine.CLASS_ARCHER	: ShareTexts.PROFESSION_ARCHER,
			csdefine.CLASS_MAGE		: ShareTexts.PROFESSION_MAGIC,
		}

class TongSpecialShop( Window ):
	"""
	帮会特殊商城
	"""

	_cc_items_rows = ( 6, 2 )

	_item_dragMark = DragMark.TONG_SPECIAL_ITEM

	def __init__( self ):
		wnd = GUI.load( "guis/general/tongabout/specialshop/wnd.gui" )
		uiFixer.firstLoadFix( wnd )
		Window.__init__( self, wnd )
		self.posZSegment = ZSegs.L4
		self.activable_ = True
		self.escHide_ 	= True
		self.__memberInfos = {}
		self.__selPost = 0
		self.__selProf = 0
		self.__offlineChecked = True
		self.__pyMsgBox = None
		self.__triggers = {}
		self.__registerTriggers()
		self.__initialize( wnd )

	def __initialize( self, wnd ):
		itemsBg = wnd.itemsBg												# 商品面板
		self.__pageItemsPanel = ODPagesPanel( itemsBg.itemsPanel, itemsBg.pgIdxBar )			#商品购买界面
		self.__pageItemsPanel.onViewItemInitialized.bind( self.__initInvoiceItem )
		self.__pageItemsPanel.onDrawItem.bind( self.__drawInvoiceItem )
		self.__pageItemsPanel.selectable = True
		self.__pageItemsPanel.onItemSelectChanged.bind( self.__onItemSelectedChange )
		self.__pageItemsPanel.viewSize = self._cc_items_rows

		self.__pyLbGold = StaticText( wnd.moneyPanel.lbGold )
		self.__pyLbGold.text = ""
		self.__pyLbSilver = StaticText( wnd.moneyPanel.lbSilver )
		self.__pyLbSilver.text = ""
		self.__pyLbCopper = StaticText( wnd.moneyPanel.lbCoin )
		self.__pyLbCopper.text = ""

		cdtPanel = wnd.conditPanel
		self.__pyTbName = TextBox( cdtPanel.tbName.box )						#名称输入框
		self.__pyTbName.inputMode = InputMode.COMMON
		self.__pyTbName.text = ""
		self.__pyTbName.onTextChanged.bind( self.__onChangeName )
		self.__pyTbName.text = ""

		self.__pyTbMin = TextBox( cdtPanel.tbMin.box )							#最小输入
		self.__pyTbMin.inputMode = InputMode.INTEGER
		self.__pyTbMin.filterChars = ['-', '+']
		self.__pyTbMin.onTextChanged.bind( self.__onChangeMin )
		self.__pyTbMin.text = ""

		self.__pyTbMax = TextBox( cdtPanel.tbMax.box )							#最大输入
		self.__pyTbMax.inputMode = InputMode.INTEGER
		self.__pyTbMax.filterChars = ['-', '+']
		self.__pyTbMax.onTextChanged.bind( self.__onChangeMax )
		self.__pyTbMax.text = ""

		self.__pyCBPost = ODComboBox( cdtPanel.cbPost )							#职务下拉菜单
		self.__pyCBPost.autoSelect = False
		self.__pyCBPost.pyBox_.foreColor = ( 236, 215, 157, 255 )
		self.__pyCBPost.pyBox_.text = labelGather.getText( "TongAbout:SpecialShop", "post" )
		self.__pyCBPost.onItemSelectChanged.bind( self.__onPostSelected )
		duties = Const.TONG_GRADE_MAPPING.keys()
		duties.sort( reverse = True )
		for duty in duties:
			if duty == 0:continue
			dutyName = Const.TONG_GRADE_MAPPING.get( duty, "" )
			if len( dutyName ) <= 0:continue
			self.__pyCBPost.addItem( dutyName )
#		self.__pyCBPost.selItem = Const.TONG_GRADE_MAPPING[self.__selPost]

		self.__pyCBProf = ODComboBox( cdtPanel.cbProf )							#职业下拉菜单
		self.__pyCBProf.autoSelect = False
		self.__pyCBProf.pyBox_.foreColor = ( 236, 215, 157, 255 )
		self.__pyCBProf.pyBox_.text = labelGather.getText( "TongAbout:SpecialShop", "prof" )
		self.__pyCBProf.onItemSelectChanged.bind( self.__onProfSelected )
		profs = g_chs_class.keys()
		profs.sort()
		for prof in profs:
			profName = g_chs_class.get( prof )
			if profName is None:continue
			self.__pyCBProf.addItem( profName )
#		self.__pyCBProf.selItem = g_chs_class[self.__selProf]

		self.__pyBtnSearch = HButtonEx( cdtPanel.btnSearch )						#搜索
		self.__pyBtnSearch.setExStatesMapping( UIState.MODE_R4C1 )
		self.__pyBtnSearch.onLClick.bind( self.__onSearch )
		labelGather.setPyBgLabel( self.__pyBtnSearch, "TongAbout:SpecialShop", "reaschBtn" )

		self.__pyBtnReset = HButtonEx( cdtPanel.btnReset )							#重置
		self.__pyBtnReset.setExStatesMapping( UIState.MODE_R4C1 )
		self.__pyBtnReset.onLClick.bind( self.__onReset )
		labelGather.setPyBgLabel( self.__pyBtnReset, "TongAbout:SpecialShop", "resetBtn" )

		self.__pyCKOffline = CheckBoxEx( cdtPanel.ckOffline ) 			#是否离线
		self.__pyCKOffline.checked = True
		self.__pyCKOffline.onCheckChanged.bind( self.__onOfflineCheck )
		labelGather.setPyLabel( self.__pyCKOffline.pyText_, "TongAbout:SpecialShop", "showOffline" )

		memPanel = wnd.memberPanel					#成员面板
		self.__pyCndBtns = {}
		for name, child in memPanel.children:
			if not name.startswith( "cndBtn_" ):continue
			index = int( name.split( "_" )[-1] )
			pyCndBtn = HButtonEx( child )
			pyCndBtn.setExStatesMapping( UIState.MODE_R3C1 )
			pyCndBtn.isSort = True
			pyCndBtn.sortByCnd = False
			pyCndBtn.sortIndex = index
			pyCndBtn.onLClick.bind( self.__sortByCnd )
			labelGather.setPyBgLabel( pyCndBtn, "TongAbout:SpecialShop", "cnd_%d"%index )
			self.__pyCndBtns[index] = pyCndBtn

		self.__pageMembersPanel = ODPagesPanel( memPanel.itemsPanel, memPanel.pgIdxBar )			#帮会成员列表
		self.__pageMembersPanel.onViewItemInitialized.bind( self.__initMemberItem )
		self.__pageMembersPanel.onDrawItem.bind( self.__drawMemberItem )
		self.__pageMembersPanel.ownerDraw = True
		self.__pageMembersPanel.selectable = True
		self.__pageMembersPanel.onItemSelectChanged.bind( self.__onMemberSeleted )
		self.__pageMembersPanel.viewSize = (10, 1)

		self.__pyBtnConfirm = HButtonEx( wnd.btnConfirm )
		self.__pyBtnConfirm.setExStatesMapping( UIState.MODE_R4C1 )
		labelGather.setPyBgLabel( self.__pyBtnConfirm, "TongAbout:SpecialShop", "confirm" )
		self.__pyBtnConfirm.onLClick.bind( self.__onConfirm )
		self.__pyBtnConfirm.enable = False

		labelGather.setPyLabel( self.pyLbTitle_,"TongAbout:SpecialShop", "title" )
		labelGather.setLabel( itemsBg.title.stTitle, "TongAbout:SpecialShop", "invioceList" )
		labelGather.setLabel( cdtPanel.title.stTitle, "TongAbout:SpecialShop", "invioceAssign" )
		labelGather.setLabel( cdtPanel.cdtRangeText, "TongAbout:SpecialShop", "searchrange" )
		labelGather.setLabel( cdtPanel.nameText, "TongAbout:SpecialShop", "name" )

	def __initInvoiceItem( self, pyViewItem ):
		"""
		初始化商品
		"""
		item = GUI.load( "guis/general/tradewindow/item.gui" )
		uiFixer.firstLoadFix( item )
		pyInvoice = WareItem( item, self._item_dragMark, self )
		pyViewItem.pyInvoice = pyInvoice
		pyViewItem.addPyChild( pyInvoice )
		pyViewItem.dragFocus = False
		pyInvoice.left = 0
		pyInvoice.top = 0

	def __drawInvoiceItem( self, pyViewItem ):
		"""
		重置商品信息
		"""
		itemInfo = pyViewItem.pageItem
		pyInvoice = pyViewItem.pyInvoice
		pyViewItem.focus = itemInfo is not None
		pyInvoice.crossFocus = itemInfo is not None
		pyInvoice.selected = pyViewItem.selected
		pyInvoice.update( itemInfo )

	def __initMemberItem( self, pyViewItem ):
		"""
		初始化成员
		"""
		pyMember = MemberItem()
		pyMember.focus = False
		pyViewItem.addPyChild( pyMember )
		pyViewItem.focus = True
		pyMember.pos = -1.0, 1
		pyViewItem.pyItem = pyMember

	def __drawMemberItem( self, pyViewItem ):
		"""
		设置成员信息
		"""
		pyMember = pyViewItem.pyItem
		itemInfo = pyViewItem.pageItem
		pyMember.setMemberInfo( itemInfo )
		pyViewItem.focus = itemInfo is not None
		pyMember.crossFocus = itemInfo is not None
		pyViewItem.visible = itemInfo is not None
		pyMember.selected = pyViewItem.selected

	# ----------------------------------------------------------------
	# private
	# ----------------------------------------------------------------
	def __registerTriggers( self ) :
		self.__triggers["EVT_ON_TRADE_WITH_TONG_SPECIAL_CHAPMAN"] = self.__onShopShow
		self.__triggers["EVT_ON_TONG_SEPCIAL_ITEM_ADDED"] = self.__onAddSpecialItem
		self.__triggers["EVT_ON_TONG_SEPCIAL_ITEM_AMOUNT_CHANGED"] = self.__onItemAmountChanged
		self.__triggers["EVT_ONTRADE_STATE_LEAVE"] = self.__onStateLeave
		self.__triggers["EVT_ON_TOGGLE_TONG_MONEY_CHANGE"] = self.__onTongMoneyChanged
		self.__triggers["EVT_ON_TOGGLE_TONG_UPDATE_ONLINE_STATE"] = self.__onMemberOnlineStateChanged
		self.__triggers["EVT_ON_TOGGLE_TONG_UPDATE_CONTRIBUTE"] = self.__onContributeChange
		self.__triggers["EVT_ON_TOGGLE_TONG_UPDATE_TCONTRIBUTE"] = self.__onTContributeChange

		for key in self.__triggers :
			GUIFacade.registerEvent( key, self )

	def __deregisterTriggers( self ) :
		for key in self.__triggers :
			GUIFacade.unregisterEvent( key, self )
	# ---------------------------------------------------------------
	def __onShopShow( self, chapman ):
		"""
		显示商店界面
		"""
		player = BigWorld.player()
		self.__onReset( self.__pyBtnReset )
		self.__setTongCanUseMoney( player.tong_getCanUseMoney() )
		self.show()

	def __onAddSpecialItem( self, index, invoiceInfo, tradeObj = "" ):
		"""
		商店添加商品
		"""
		itemInfo = ItemInfo( index, invoiceInfo, tradeObj )
		if not itemInfo in self.__pageItemsPanel.items:
			self.__pageItemsPanel.addItem( itemInfo )

	def __onItemAmountChanged( self, index, itemInfo, tradeObject ):
		"""
		物品数量改变
		"""
		if index < 1:
			return
		else:
			for pyViewItem in self.__pageItemsPanel.pyViewItems:
				pyInvoice = pyViewItem.pyInvoice
				if pyInvoice.index == index:
					itemInfo = ItemInfo( index, itemInfo, tradeObject )
					pyInvoice.update( itemInfo )
					break

	def __onStateLeave( self, state ):
		"""
		离开交易状态
		"""
		if state == csdefine.TRADE_CHAPMAN:
			GUIFacade.tradeOverWithNPC()
			self.hide()
			BigWorld.player().tradeState = csdefine.TRADE_NONE

	def __onTongMoneyChanged( self, money ):
		"""
		帮会资金改变
		"""
		money = BigWorld.player().tong_getCanUseMoney()
		if money <= 0:
			money = 0
		self.__setTongCanUseMoney( money )

	def __setTongCanUseMoney( self, money ):
		"""
		设置可用资金
		"""
		gold = money/10000
		sliver = ( money/100 )%100
		copper = ( money%100 )%100
		self.__pyLbGold.text = str( gold )
		self.__pyLbSilver.text = str( sliver )
		self.__pyLbCopper.text = str( copper )

	def __onMemberOnlineStateChanged( self, memberDBID, isOnline ):
		"""
		帮会成员在线状态改变
		"""
		stateText = ""
		if isOnline:
			stateText = labelGather.getText( "TongAbout:SpecialShop", "online" )
		else:
			stateText = labelGather.getText( "TongAbout:SpecialShop", "offline" )
		self.__onMemberInfoChange( memberDBID, 7, 6, stateText )

	def __onContributeChange( self, memberID, contribute ):
		"""
		成员帮贡改变
		"""
		self.__onMemberInfoChange( memberDBID, 5, 4, contribute )

	def __onTContributeChange( self, memberDBID, totalContribute ):
		"""
		成员总帮贡改变
		"""
		self.__onMemberInfoChange( memberDBID, 6, 5, totalContribute )

	def __onMemberInfoChange( self, memberDBID, infoIndex, colIndex, infoValue ):
		"""
		帮会成员属性值统一更新接口
		"""
		for pyViewItem in self.__pageMembersPanel.pyViewItems:
			member = pyViewItem.pageItem
			if member is None:continue
			if member[0] == memberDBID:
				member = self.__memberInfos.get( memberDBID )
				if member is None:return
				member[infoIndex] = str( infoValue )
				pyMember = pyViewItem.pyItem
				pyMember.pyCols[colIndex].text = str( infoValue )

	def __onItemSelectedChange( self, index ):
		"""
		选取某个商品
		"""
		if index < 0: return
		itemInfo = self.__pageItemsPanel.selItem
		if itemInfo is None:return
		baseInfo = itemInfo.baseInfo
		baseItem = baseInfo.baseItem
		memberInfo = self.__pageMembersPanel.selItem
		self.__pyBtnConfirm.enable = itemInfo is not None and memberInfo is not None

	def __onMemberSeleted( self, index ):
		"""
		选择帮会成员
		"""
		if index < 0: return
		memberInfo = self.__pageMembersPanel.selItem
		for pyViewItem in self.__pageMembersPanel.pyViewItems:
			member = pyViewItem.pageItem
			if member is None:continue
			pyMember = pyViewItem.pyItem
			pyMember.selected = member[0] == memberInfo[0]
		itemInfo = self.__pageItemsPanel.selItem
		self.__pyBtnConfirm.enable = memberInfo is not None and itemInfo is not None

	def __onChangeName( self ):
		"""
		姓名改变
		"""
		pass

	def __onChangeMin( self ):
		"""
		最小值改变
		"""
		pass

	def __onChangeMax( self ):
		"""
		最大值改变
		"""
		pass

	def __onPostSelected( self, index ):
		"""
		职务选择
		"""
		if index < 0:return
		post_map = {0:csdefine.TONG_DUTY_CHIEF, 1:csdefine.TONG_DUTY_DEPUTY_CHIEF, 2:csdefine.TONG_DUTY_TONG, 3:csdefine.TONG_DUTY_MEMBER}
		self.__selPost = post_map.get( index )

	def __onProfSelected( self, index ):
		"""
		职业选择
		"""
		if index < 0:return
		prof_map = {0:csdefine.CLASS_FIGHTER, 1:csdefine.CLASS_SWORDMAN, 2:csdefine.CLASS_ARCHER, 3:csdefine.CLASS_MAGE}
		self.__selProf = prof_map.get( index )

	def __onSearch( self, pyBtn ):
		"""
		搜索
		"""
		if pyBtn is None:return
		player = BigWorld.player()
		memberName = self.__pyTbName.text
		min = 0
		max = 0
		minText = self.__pyTbMin.text
		maxText =  self.__pyTbMax.text
		if len( minText ) > 0:
			min = int( minText )
		if len( maxText ) > 0:
			max = int( maxText )
		if min > max:
			if self.__pyMsgBox is not None:
				self.__pyMsgBox.visible = False
				self.__pyMsgBox = None
			self.__pyMsgBox = showMessage( mbmsgs[0x11b1],"", MB_OK, None, pyOwner = self )
			return
		self.__pageMembersPanel.clearItems()
		members = player.tong_memberInfos
		for dbid, member in members.items():
			prof = member._class&csdefine.RCMASK_CLASS
			if not self.__offlineChecked and not member.isOnline():
				continue
			if min > 0 and member._contribute < min:
				continue
			if max > 0 and member._contribute > max:
				continue
			if self.__selPost > 0 and self.__selPost != member._grade:
				continue
			if self.__selProf > 0 and self.__selProf != prof:
				continue
			if len( memberName ) > 0 and member._name != memberName:
				continue
			memberInfo = [dbid, member._name, member._level, prof, member._grade, str(member._contribute), str(member._totalContribute), member._isOnline]
			self.__pageMembersPanel.addItem( memberInfo )

	def __onReset( self, pyBtn ):
		"""
		重置
		"""
		if pyBtn is None:return
		self.__pyTbName.text = ""
		self.__pyTbMin.text = ""
		self.__pyTbMax.text = ""
		self.__selPost = 0
		self.__selProf = 0
		self.__offlineChecked = True
		self.__pyCBPost.pyBox_.text = labelGather.getText( "TongAbout:SpecialShop", "post" )
		self.__pyCBProf.pyBox_.text = labelGather.getText( "TongAbout:SpecialShop", "prof" )
		self.__pyCKOffline.checked = self.__offlineChecked
		player = BigWorld.player()
		self.__memberInfos = {}
		self.__pageMembersPanel.clearItems()
		self.__pyTbName.tabStop = True
		for dbid, member in player.tong_memberInfos.items():
			if not dbid in self.__memberInfos:
				prof = member._class&csdefine.RCMASK_CLASS
				memberInfo = [dbid, member._name, member._level, prof, member._grade, str(member._contribute), str(member._totalContribute), member._isOnline]
				self.__memberInfos[dbid] = memberInfo
				self.__pageMembersPanel.addItem( memberInfo )

	def __onOfflineCheck( self, checked ):
		"""
		是否显示离线
		"""
		self.__offlineChecked = checked
		if checked:
			self.__showAlls()
		else:
			self.__showOnlines()

	def __showAlls( self ):
		"""
		显示全部
		"""
		self.__pageMembersPanel.clearItems()
		onlineMembers = []
		offlineMembers = []
		members = BigWorld.player().tong_memberInfos
		for dbid, member in members.iteritems():
			if member.isOnline():
				onlineMembers.append( member )
			else:
				offlineMembers.append( member )
		onlineMembers.sort( key = lambda n: n.getGrade(), reverse = True )
		offlineMembers.sort( key = lambda n: n.getGrade(), reverse = True )
		allMembers = onlineMembers + offlineMembers
		for member in allMembers:
			prof = member._class&csdefine.RCMASK_CLASS
			memberInfo = [dbid, member._name, member._level, prof, member._grade, str(member._contribute), str(member._totalContribute), member._isOnline]
			self.__pageMembersPanel.addItem( memberInfo )

	def __showOnlines( self ):
		"""
		显示在线
		"""
		self.__pageMembersPanel.clearItems()
		onlineMembers = []
		members = BigWorld.player().tong_memberInfos
		for dbid, member in members.iteritems():
			if member.isOnline():
				onlineMembers.append( member )
		onlineMembers.sort( key = lambda n: n.getGrade(), reverse = True )
		for member in onlineMembers:
			prof = member._class&csdefine.RCMASK_CLASS
			memberInfo = [dbid, member._name, member._level, prof, member._grade, str(member._contribute), str(member._totalContribute), member._isOnline]
			self.__pageMembersPanel.addItem( memberInfo )

	def __sortByCnd( self, pyCnd ):
		"""
		按条件排序
		"""
		if pyCnd is None:return
		sortIndex = pyCnd.sortIndex + 1
		flag = pyCnd.sortByCnd and True or False
		self.__pageMembersPanel.sort( key = lambda item : item[sortIndex], reverse = flag )
		pyCnd.sortByCnd = not pyCnd.sortByCnd

	def __onConfirm( self, pyBtn ):
		"""
		确认分配
		"""
		if pyBtn is None:return
		chapman = MerchantFacade.chapman
		memInfo = self.__pageMembersPanel.selItem
		itemInfo = self.__pageItemsPanel.selItem
		itemName = itemInfo.baseInfo.name_()
		amount = 1
		if chapman and chapman.__class__.__name__ == "TongSpecialChapman":
			def query( rs_id ):
				if rs_id == RS_OK:
					chapman.cell.sellArrayTo( memInfo[0], [itemInfo.index], [amount] )
		if self.__pyMsgBox is not None:
			self.__pyMsgBox.visible = False
			self.__pyMsgBox = None
		self.__pyMsgBox = showMessage( mbmsgs[0x11b0] %( itemName, memInfo[1] ),"", MB_OK_CANCEL, query, pyOwner = self )

	# ----------------------------------------------------------
	#public
	# ---------------------------------------------------------
	def onEvent( self, eventMacro, *args ) :
		"""
		respond base triggering
		"""
		self.__triggers[eventMacro]( *args )

	def onLeaveWorld( self ):
		self.hide()

	def show( self ):
		Window.show( self )

	def hide( self ):
		if rds.statusMgr.isInWorld() :
			GUIFacade.tradeOverWithNPC()
			BigWorld.player().tradeState = csdefine.TRADE_NONE
		self.__pageItemsPanel.clearItems()
		self.__pageMembersPanel.clearItems()
		self.__memberInfos = {}
		Window.hide( self )

# ------------------------------------------------------------------------------------------
# 帮会成员信息列表
class MemberItem( MultiColListItem ):

	_ITEM = None

	def __init__( self ):
		if MemberItem._ITEM is None:
			MemberItem._ITEM = GUI.load( "guis/general/tongabout/specialshop/membitem.gui" )
		item = util.copyGuiTree( MemberItem._ITEM )
		uiFixer.firstLoadFix( item )
		MultiColListItem.__init__( self, item )
		self.commonBackColor = ( 255, 255, 255, 255 )
		self.selectedBackColor = ( 255, 255, 255, 255 )
		self.highlightBackColor = ( 255, 255, 255, 255 )
		self._selected = False

	def setMemberInfo( self, member ):
		"""
		更新成员信息
		"""
		if member is None:return
		online = member[-1]
		state = labelGather.getText( "TongAbout:SpecialShop", "online" )
		self.pyCols[-1].foreColor = (255, 248, 158, 255)
		if not online:
			self.pyCols[-1].foreColor = ( 128, 128, 128, 255 )
			state = labelGather.getText( "TongAbout:SpecialShop", "offline" )
		levelText = "%d级"%member[2]
		profName = g_chs_class.get( member[3], "" )
		dutyName = Const.TONG_GRADE_MAPPING.get( member[4], "" )
		self.setTextes( member[1],
					levelText,
					profName,
					dutyName,
					member[5],
					member[6],
					state
		 )

	def onStateChanged_( self, state ) :
		"""
		状态改变时调用
		"""
		elements = self.getGui().elements
		for element in elements.values():
			element.visible = state in [ UIState.HIGHLIGHT, UIState.SELECTED ]

	def onMouseEnter_( self ):
		MultiColListItem.onMouseEnter_( self )
		if self.selected:return
		self.setState( UIState.HIGHLIGHT )

	def onMouseLeave_( self ):
		MultiColListItem.onMouseLeave_( self )
		if self.selected:return
		self.setState( UIState.COMMON )

	def _select( self ):
		self.setState( UIState.HIGHLIGHT )

	def _deselect( self ):
		self.setState( UIState.COMMON )

	def _getSelected( self ):
		return self._selected

	def _setSelected( self, selected ):
		if selected:
			self._select()
		else:
			self._deselect()
		self._selected = selected

	selected = property( _getSelected, _setSelected )

class ItemInfo:
	def __init__( self, index, baseInfo, npcName = "" ):
		self.index = index
		self.baseInfo = baseInfo
		self.npcName = npcName
		self.uid = -1

	def update( self, uid, itemInfo ):
		self.uid = uid
		self.baseInfo = itemInfo