import logging
from traceback import print_exc
from util.introspect import memoize
log = logging.getLogger('pg_accounts2')
import wx
from gui.uberwidgets.PrefPanel import PrefPanel
from gui.pref.prefcontrols import HSizer, VSizer, mark_pref, SText
from wx import EXPAND
import protocols
from gui.textutil import default_font
from gui.accountslist import AccountRow
from gui.accountslist import AccountList
from util.primitives.funcs import find
from operator import attrgetter

import hooks
from contacts.sort_model import ChoiceModel
from pg_contact_list import yield_choices, release_syncs
from common import pref, profile
from peak.util.addons import AddOn
import common
from peak.events import trellis
import util.observe as observe
from util.lego.lattice.blocks import IValueListener
from util.lego.lattice.frame import ObservableAttrBindable

class IServiceProviderGUIMetaData(protocols.Interface):
    provider_id = unicode()
    icon = property() #wx.Bitmap (skin.get....)
    name = unicode()
    popularity = int() #needed for comparison
    service_components = list() #IServiceComponentGUIData

class IServiceProviderInstanceGUIMetaData(protocols.Interface):
    account_name = unicode()
    #service_components = list()

class IServiceComponentGUIMetaData(protocols.Interface):
    icon = property() #wx.Bitmap (skin.get....)
    service_name = unicode() #'Yahoo Messenger'
    type = str() #twitter is a 'social', aim is an 'im'
    component_id = str() # 'msn'

from plugin_manager.plugin_registry import ServiceProviderPlugin, \
    ServiceComponentPlugin

import services.service_provider as sp

class ServiceProviderPluginGUIMetaData(protocols.Adapter):
    protocols.advise(asAdapterForTypes = [ServiceProviderPlugin],
                     instancesProvide = [IServiceProviderGUIMetaData])
    @property
    def provider_id(self):
        return self.subject.provider_id
    @property
    def icon(self):
        from gui import skin
        return skin.get('serviceprovidericons.%s' % self.subject.provider_id)
    @property
    def provider_name(self):
        return self.subject.name
    @property
    def popularity(self):
        return getattr(getattr(getattr(self.subject, 'info', None), 'provider_info', None), 'popularity', 0)
    @property
    def service_components(self):
        return sp.get_meta_components_for_provider(self.subject.provider_id)

class ServiceComponentPluginGUIMetaData(protocols.Adapter):
    protocols.advise(asAdapterForTypes = [ServiceComponentPlugin],
                     instancesProvide = [IServiceComponentGUIMetaData])
    @property
    def icon(self):
        from gui import skin
        return skin.get('serviceicons.%s' % self.subject.shortname)
    @property
    def service_name(self):
        return self.subject.info.get('service_name') or self.subject.info.get('name')
    @property
    def component_id(self):
        return self.subject.shortname
    @property
    def type(self):
        return self.subject.component_type

class StringServiceComponentGUIData(object):
    protocols.advise(asAdapterForTypes=[basestring],
                     instancesProvide=[IServiceComponentGUIMetaData])
    def __init__(self, subject):
        self.subject = subject
    @property
    def service_name(self):
        from common import protocolmeta
        p = protocolmeta.protocols.get(self.subject)
        if p:
            name = p.get('service_name') or p.get('name')
        else:
            name = self.subject.capitalize()
        return name
        return p.name if p else self.subject.capitalize()
    @property
    def icon(self):
        from gui import skin
        return skin.get('serviceicons.%s' % self.subject, skin.get('serviceprovidericons.%s' % self.subject, None))
    @property
    def type(self):
        from common import protocolmeta
        p = protocolmeta.protocols.get(self.subject)
        return p.get('component_type', p.get('type')) if p else 'unknown'
    @property
    def component_id(self):
        return self.subject

def get_meta_for_provider(provider_instance):
    return IServiceProviderGUIMetaData(sp.get_meta_service_provider(provider_instance.provider_id))

protocols.declareAdapterForType(IServiceProviderGUIMetaData, get_meta_for_provider, sp.ServiceProvider)

class IPaintable(protocols.Interface):
    def on_paint(e):
        pass

class wxPaintingMixin(object):
    def __init__(self, *a, **k):
        try:
            IPaintable(self)
        except protocols.AdaptationFailure:
            raise
        super(wxPaintingMixin, self).__init__(*a, **k)
        self.Bind(wx.EVT_PAINT, self.on_paint)

class IDrawable(protocols.Interface):
    def draw(dc):
        pass

class IDrawingContext(protocols.Interface):
    def DrawText(text, x, y): pass
    def DrawBitmap(bmp, x, y): pass
    def DrawRoundedRectangleRect(rect, radius): pass

def wxPaintEventDrawingContextAdapter(event):
    if event.EventType == wx.EVT_PAINT:
        return wx.AutoBufferedPaintDC(event.GetEventObject())

protocols.declareImplementation(wx.DC, instancesProvide=[IDrawingContext])
protocols.declareAdapterForType(IDrawingContext, wxPaintEventDrawingContextAdapter, wx.Event)

class IRectagleFactory(protocols.Interface):
    def get_rect(x,y,w,h):
        pass

class wxRectangleFactory(protocols.Adapter):
    protocols.advise(instancesProvide=[IRectagleFactory],
                     asAdapterForTypes=[wx.DC])
    @staticmethod
    def get_rect(x,y,w,h):
        return wx.Rect(x,y,w,h)

class ServiceProviderGUIMetaIconUser(object):
    icon_cache = {}
    def get_icon(self, meta, size):
        meta = IServiceProviderGUIMetaData(meta)
        try:
            ret = self.icon_cache[(meta.provider_id, size)]
        except KeyError:
            ret = self.icon_cache[(meta.provider_id, size)] = meta.icon.PIL.Resized(size).WXB
        return ret

class ServiceComponentGUIMetaIconUser(object):
    icon_cache = {}
    def get_icon(self, meta, size):
        meta = IServiceComponentGUIMetaData(meta)
        try:
            ret = self.icon_cache[(meta.component_id, size)]
        except KeyError:
            ret = self.icon_cache[(meta.component_id, size)] = meta.icon.PIL.Resized(size).WXB
        return ret

class ServiceMetaProviderPanel(wxPaintingMixin, wx.Panel, ServiceProviderGUIMetaIconUser):
    protocols.advise(instancesProvide=[IPaintable, IDrawable])
    def __init__(self, service_providers, height, spacing, *a, **k):
        self.service_providers = [s[0] for s in
                                  sorted(((sp,IServiceProviderGUIMetaData(sp))
                                          for sp in service_providers),
                                         key = (lambda o: o[1].popularity),
                                         reverse = True)]
        self.height = height
        self.spacing = spacing
        super(ServiceMetaProviderPanel, self).__init__(*a, **k)
        #wx object operations must wait until after the wx constructor
        self.MinSize = (len(service_providers) - 1)*(height + spacing) + height, (height + spacing)
        self.w = None
        self.Bind(wx.EVT_MOTION, self.on_mouseover, self)
        self.Bind(wx.EVT_LEFT_UP, self.on_mouseclick, self)
        self.Bind(wx.EVT_ENTER_WINDOW, self.on_mousein, self)
        self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)
        self.Bind(wx.EVT_LEAVE_WINDOW, self.on_mouseout, self)
        self.Bind(wx.EVT_MOUSE_CAPTURE_LOST, self.on_capture_lost, self)
        self.sx = self.sy = None

    def draw(self, obj):
        dc = IDrawingContext(obj)
        dc.Clear()
        size = self.height
        offset = self.height+self.spacing
        dc.SetPen(wx.TRANSPARENT_PEN)
        dc.DrawRectangle(0,0,self.Size.width, self.Size.height)
        for i, s in enumerate(self.service_providers):
            dc.DrawBitmap(self.get_icon(s, size), i*offset, 0)
    on_paint = draw

    def service_provider_from_evt(self, e):
        if e.GetEventObject() is not self:
            return
        if not self.HasCapture():
            return
        lx = e.X
        r = self.ClientRect
        if not wx.Rect(r.y,r.x,r.width + 1, r.height + 1).Contains(e.Position):
            return
        offset = self.height+self.spacing
        pos = lx / float(offset)
        posi = int(pos)
        posr = pos - posi
        if posr * offset <= (offset - self.spacing):
            if posi < len(self.service_providers):
                return self.service_providers[posi]

    def on_mouseover(self, e):
        e.Skip()
        if e.GetEventObject() is not self:
            return
        if not self.HasCapture():
            return
        lx = e.X
        r = self.ClientRect
        if not wx.Rect(r.y,r.x,r.width + 1, r.height + 1).Contains(e.Position):
            return self.on_mouseout(e)
        offset = self.height+self.spacing
        pos = lx / float(offset)
        posi = int(pos)
        posr = pos - posi
        if posr * offset <= (offset - self.spacing):
            sx = posi * offset + self.height/2
            sy = self.height
            if posi >= len(self.service_providers):
                return self.SetCursor(wx.StockCursor(wx.CURSOR_DEFAULT))
            self.SetCursor(wx.StockCursor(wx.CURSOR_HAND))
            if self.w is None:
                self.w = ServiceProviderBubble(self.service_providers[0], 0, parent=self)
            if self.w.Shown and sx == self.sx and sy == self.sy:
                return
            self.sx = sx
            self.sy = sy
            with self.w.Frozen():
                self.w.service_provider = IServiceProviderGUIMetaData(self.service_providers[posi])
                self.w.show_point_to(self.ClientToScreen((sx,sy)))
        else:
            self.SetCursor(wx.StockCursor(wx.CURSOR_DEFAULT))

    def on_mouseclick(self, e):
        e.Skip()
        sp = self.service_provider_from_evt(e)
        if sp is None:
            return

        diag = hooks.first('digsby.services.create', parent = self.Top, sp_info = sp, impl="digsby_service_editor")
        diag.CenterOnParent()
        return_code = diag.ShowModal()

        if return_code != wx.ID_SAVE:
            log.info("Account creation cancelled. Return code = %r", return_code)
            return

        info = diag.extract()
        sp = hooks.first('digsby.service_provider',
                         impl = diag.sp_info.provider_id,
                         **info)

        log.info("Created %r", sp)
        components = []
        types_ = sp.get_component_types()
        if 'im' in types_:
            sp.autologin = True
        for type_ in types_:
            comp = sp.get_component(type_)
            components.append((comp, type_[:2]))
            log.info("\thas component %r: %r", type_, comp)
        import services.service_provider as sp
        with sp.ServiceProviderContainer(profile()).rebuilding() as container:
            profile.account_manager.add_multi(components)
            for comp, type_ in components:
                try:
                    if hasattr(comp, 'enable'):
                        comp.enable()
                    else:
                        comp.enabled = True
                except Exception:
                    print_exc()
                try:
                    on_create = getattr(comp, 'onCreate', None) #CamelCase for GUI code
                    if on_create is not None:
                        on_create()
                except Exception:
                    print_exc()
                if type_ == 'em':
                    hooks.notify('digsby.email.new_account', parent = self.Top, protocol = comp.protocol, **info)
            container.rebuild()

    def on_mousein(self, e):
        if e.GetEventObject() is not self:
            return
        self.CaptureMouse()

    def on_mouseout(self, e):
        if self.w is not None:
            self.w.Hide()
        while self.HasCapture():
            self.ReleaseMouse()
        self.SetCursor(wx.StockCursor(wx.CURSOR_DEFAULT))

    def on_capture_lost(self, e):
        pass

class BubbleWindow(wx.Frame):
    def __init__(self, internal_size, parent = None, *a, **k):
        style = wx.FRAME_SHAPED | wx.BORDER_NONE | wx.FRAME_NO_TASKBAR | \
                ((parent and wx.FRAME_FLOAT_ON_PARENT) or wx.STAY_ON_TOP)
        ret = super(BubbleWindow, self).__init__(parent, style=style, *a, **k)
        self.Bind(wx.EVT_PAINT, self.on_paint)
        self.internal_size = internal_size
        self.point = (10,0)
        return ret

    def draw_content(self, dc):
        pass

    @property
    def poly(self):
        xborder = 0
        yborder = 0
        startx, starty = (0,10)
        px,py = self.point
        endx, endy = (2*xborder + self.internal_size[0] + startx), (2*yborder + self.internal_size[1] + starty)
        return ((px,py),(px+1,py), (px+11,starty), (endx,starty),(endx,endy),(startx,endy),(startx,starty),(px,starty),(px,py))

    def show_point_to(self, point):
        x,y = point
        xborder = 0
        yborder = 0
        startx, starty = (0,10)
        px,py = self.point
        endx, endy = (2*xborder + self.internal_size[0] + startx), (2*yborder + self.internal_size[1] + starty)
        with self.Frozen():
            self.Position = (x - px, y - py)
            self.Size = (endx+1, endy+1)
            self.SetShape(get_polyregion(self.poly, endx, endy))
            self.ShowNoActivate(True)

    def on_paint(self, e):
        dc = wx.AutoBufferedPaintDC(self)
#        gc = wx.GraphicsContext.Create(dc)
        o = wx.Color(254,214,76) # skin!
        y = wx.Color(255,251,184)
        dc.SetPen(wx.Pen(o))
        dc.SetBrush(wx.Brush(y))
        dc.DrawPolygon(self.poly)
        self.draw_content(dc)

class ServiceProviderBubble(BubbleWindow, ServiceComponentGUIMetaIconUser):
    def __init__(self, service_provider, font_adjust = 0, *a, **k):
        self.service_provider = IServiceProviderGUIMetaData(service_provider)
        super(ServiceProviderBubble, self).__init__((0,0), *a, **k)
        self.Font = default_font()
        self.font_adjust = font_adjust
        self._service_provider = None
        self.recalcsize()

    def recalcsize(self):
        if self.service_provider is self._service_provider:
            return
        ftitle = self.Font
        ftitle.PointSize = int((ftitle.PointSize + self.font_adjust) * 4/3.)
        fbase = self.Font
        fbase.PointSize += self.font_adjust
        h = 0
        h += ftitle.LineHeight + 2
        h += ftitle.Descent * 2
        lh = round(fbase.LineHeight / 4. + .25) * 4 + 2
        #^ .25 = .5 - 1/4. (ceil, except when exactly divisible by 4)
        h += lh*len(self.service_provider.service_components) - 2
        dc = wx.ClientDC(self)
        dc.Font = ftitle
        w = dc.GetTextExtent(self.service_provider.provider_name)[0]
        self.offset = dc.GetTextExtent(" ")[0]
        dc.Font = fbase
        w2 = max([dc.GetTextExtent(" " + IServiceComponentGUIMetaData(s).service_name)[0]
                  for s in self.service_provider.service_components] + [0])
        w2 += lh
        w2 += self.offset
        w = max(w, w2)
        w += ftitle.Descent * 4
        h += 2
        self.internal_size = (int(w), int(h))
        self._service_provider = self.service_provider

    def draw_content(self, dc):
        ftitle = self.Font
        ftitle.PointSize = int((ftitle.PointSize + self.font_adjust) * 4/3.)
        fbase = self.Font
        fbase.PointSize += self.font_adjust
        dc.Font = ftitle
        x,y = ftitle.Descent * 2, 10 + ftitle.Descent * 1
        dc.DrawText(self.service_provider.provider_name, x, y)
        y += ftitle.LineHeight + 2
        lh = int(round(fbase.LineHeight / 4. + .25)) * 4 + 2
        dc.Font = fbase
        x += self.offset
        for s in sorted((IServiceComponentGUIMetaData(sc)
                         for sc in self.service_provider.service_components),
                        key = attrgetter('type'),
                        cmp = component_sort):
            dc.DrawBitmap(self.get_icon(s, lh -2), x, y)
            dc.DrawText(" " + s.service_name, x+lh, y)
            y += lh

    def show_point_to(self, point):
        self.recalcsize()
        return super(ServiceProviderBubble, self).show_point_to(point)

@memoize
def get_polyregion(points, w, h, border=1):
    i = wx.EmptyImage(w + border, h + border)
    b = i.WXB
    m = wx.MemoryDC(b)
    m.Clear()
    m.SetBrush(wx.Brush(wx.Color(0,0,0)))
    m.SetPen(wx.Pen(wx.Color(0,0,0)))
    #ceil(border/2)?
    m.DrawRectangle(0,0,w + border, h + border)
    m.SetBrush(wx.Brush(wx.Color(255,255,255)))
    m.SetPen(wx.Pen(wx.Color(255,255,255)))
    m.DrawPolygon(points)
    m.SelectObject(wx.NullBitmap)
    del m
    b.SetMaskColour(wx.Color(0,0,0))
    return wx.RegionFromBitmap(b)

class IServiceProviderInstance(protocols.Interface):
    icon = property()

def grayify(i, grayshade):
    return int(round((i + grayshade) / 2.))
def grayify3(tuple_, grayshade):
    return tuple(grayify(i, grayshade) for i in tuple_)

class CheckModel(trellis.Component):
    value = trellis.attr(False)
    enabled = trellis.attr(True)

class ListenerSync(trellis.Component):
    listener = trellis.attr()
    model = trellis.attr()

class ModelListenerSync(ListenerSync):
    @trellis.maintain
    def value(self):
        self.model.value = self.listener.value

class ListenerModelSync(ListenerSync):
    @trellis.maintain
    def keep_value(self):
        self.listener.value = self.model.value

class ViewListenerModelSync(ListenerModelSync):
    view = trellis.attr()

class CheckModelSync(ViewListenerModelSync):
    @trellis.perform
    def update(self):
        try:
#            print 'syncing', self.model.enabled, self.model.value
            with self.view.Frozen():
                self.view.Enabled = self.model.enabled
                self.view.Value = self.model.value
        except Exception:
            if not wx.IsDestroyed(self.view):
                raise

class CheckSync(object):
    def __init__(self, model, view):
        #order matters, make the view sync to the model before we allow
        #the other direction
        listener = IValueListener(view)
        self.model_to_view = CheckModelSync(model = model, view = view, listener = listener)
        self.view_to_model = ModelListenerSync(model = model, listener = listener)

class AccountModelSync(ViewListenerModelSync):
    #syncs the model.value to the account
    @trellis.perform
    def update(self):
        has_enabled = hasattr(self.view, 'enabled')
        if has_enabled and self.view.enabled != self.model.value:
            val = self.model.value
            #assume accounts with enable()/disable() know what to do
            #as far as saving that data.
            if val and hasattr(self.view, 'enable'):
                self.view.enable()
            elif (not val) and hasattr(self.view, 'disable'):
                self.view.disable()
            else:
                self.view.setnotify('enabled', val)
                #email/social get saved to the server;
                #update_info without any data works to just save them.
                wx.CallAfter(self.view.update_info)

class AccountEnabledSync(object):
    def __init__(self, model, view):
        #order matters, model syncs to the account first
        listener = IValueListener(ObservableAttrBindable(view, 'enabled'))
        self.acct_to_model = ModelListenerSync(model = model, listener = listener)
        self.model_to_acct = AccountModelSync (model = model, view = view, listener = listener)

class EnabledAccountSync(object):
    def __init__(self, model, view):
        #order matters, acct syncs to the model first
        listener = IValueListener(ObservableAttrBindable(view, 'enabled'))
        self.model_to_acct = AccountModelSync (model = model, view = view, listener = listener)
        self.acct_to_model = ModelListenerSync(model = model, listener = listener)

class AccountEnabledCheckSync(object):
    def __init__(self, account, check):
        #double MVC
        model = CheckModel()
        self.acct_model = AccountEnabledSync(model = model, view = account)
        self.view_model = CheckSync(         model = model, view = check)

class NoAccountEnabledCheckSync(trellis.Component):
    created_account = trellis.attr(False)
    def __init__(self, provider, component, check):
        super(NoAccountEnabledCheckSync, self).__init__()
        self.model = CheckModel()
        self.provider = provider
        self.component = component
        self.view_model = CheckSync(model = self.model, view = check)

    @trellis.maintain
    def update(self):
        if not self.model.value:
            return

        if self.created_account:
            return
        self.created_account = True

        # create account object, put it in the account manager
        acct = self.provider.get_component(self.component.type)
        profile.account_manager.add(acct, self.component.type[:2], ignore_on_rebuild=True)

        self.acct_to_model = EnabledAccountSync(model = self.model, view = acct)

class ServiceProviderRow(AccountRow, ServiceProviderGUIMetaIconUser):
    row_height = 50
    def __init__(self, parent, data, *a, **k):
        self.data = data
        self._base_color_tuple = (128,128,128)
        self._name_color_tuple = (0,0,0)
        ret = super(ServiceProviderRow, self).__init__(parent=parent, data=data, *a, **k)
#        self.SetToolTipString(IServiceProviderGUIMetaData(data).provider_name +\
#                              ': ' + IServiceProviderInstanceGUIMetaData(data).account_name)
        self.Font = default_font()
        return ret

    @property
    def image(self):
        try:
            ret = self.get_icon(self.data, 40)
        except AttributeError:
            ret = super(ServiceProviderRow, self).image
        return ret

    def draw_text(self, dc, x, sz):
        pass

    def _paint(self, e):
        dc = super(ServiceProviderRow, self)._paint(e)
        f = self.Font
        f.PointSize += 3
        dc.Font = f
        name = IServiceProviderInstanceGUIMetaData(self.data).account_name
        x,y = self._place_text.Position
        y += f.Descent

        for (color, string) in (hooks.first('digsby.services.colorize_name', impls = (self.data.provider_id, 'digsby_service_editor'), name = name) or ()):
            color_obj = getattr(self, '_active_%s_color' % color, None)
            dc.SetTextForeground(wx.Color(*color_obj))
            dc.DrawText(string, x, y)
            x += dc.GetTextExtent(string)[0]

    def ConstructMore(self):
        self.checks = []
        self.hiddens = []
        import gui.lattice
        for s in sorted((IServiceComponentGUIMetaData(sc)
                         for sc in IServiceProviderGUIMetaData(self.data).service_components),
                        key = attrgetter('type'),
                        cmp = component_sort):
            c = wx.CheckBox(self, -1, s.service_name)
            for a in self.data.accounts.values():
                if a.protocol == s.component_id:
                    c.controller = AccountEnabledCheckSync(account = a,
                                                           check = c)
                    break
            else:
                c.controller = NoAccountEnabledCheckSync(provider = self.data, component = s, check = c)
            if s.type == 'im':
                text = wx.StaticText(self, label = _('(auto login)'))
                f = c.Font
                text.Font = f
                text.ForegroundColour = wx.Color(*self._base_color_tuple)
                text.Hide()
                self.hiddens.append(text)
                c = (c, text)
            self.checks.append(c)

        # Extra component--the edit hyperlink
        edit = self.edit = wx.HyperlinkCtrl(self, -1, _('Edit'), '#')
        edit.Hide()
        edit.Bind(wx.EVT_HYPERLINK, lambda e: self.on_edit())

        remove = self.remove = wx.HyperlinkCtrl(self, -1, _('Remove'), '#')
        remove.Hide()
        remove.Bind(wx.EVT_HYPERLINK, lambda e: self.on_delete())

        self.hiddens.append(edit)
        self.hiddens.append(remove)

        edit.HoverColour = edit.VisitedColour = edit.ForegroundColour
        remove.HoverColour = remove.VisitedColour = remove.ForegroundColour
        self._reset_text_name()

    def on_edit(self):
        super(ServiceProviderRow, self).on_edit()
        self.on_data_changed(self)

    def on_delete(self):
        super(ServiceProviderRow, self).on_delete()
        #super.on_data_changed to skip the GUI refresh
        super(ServiceProviderRow, self).on_data_changed(self)

    def _reset_text_name(self):
        dc = wx.ClientDC(self)
        f = self.Font
        f.PointSize += 3
        dc.Font = f
        txt = IServiceProviderInstanceGUIMetaData(self.data).account_name
        w,h = dc.GetTextExtent(txt)
        self.text_name = w, h

    def CalcColors(self, *a, **k):
        if self.IsHovered():
            self._active_base_color = self._base_color_tuple
            self._active_name_color = self._name_color_tuple
        else:
            self._active_base_color = grayify3(self._base_color_tuple, 128)
            self._active_name_color = grayify3(self._name_color_tuple, 128)
        return super(ServiceProviderRow, self).CalcColors(*a, **k)

    def LayoutMore(self, sizer):
        #checkboxes
        check_sizer = VSizer()
        check_sizer.AddStretchSpacer(3)
        for check in self.checks:
            if isinstance(check, tuple):
                check, text = check
                h = HSizer()
                h.Add(check)
                h.Add(text)
                check_sizer.Add(h)
            else:
                check_sizer.Add(check)
            check_sizer.AddStretchSpacer()
        check_sizer.AddStretchSpacer(2)
        #add checkboxes
        sizer.Add(check_sizer, 1, wx.LEFT | wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.EXPAND, self.padding.x*2)
        #right side
        right_sizer = VSizer()
        self._place_text = right_sizer.Add(self.text_name, 3, wx.ALIGN_RIGHT | wx.RIGHT | wx.ALIGN_CENTER_VERTICAL, self.padding.y)
        #right bottom
        link_sizer = HSizer()
        link_sizer.Add(self.edit, 0, wx.LEFT, self.padding.x)
        link_sizer.Add(self.remove, 0, wx.LEFT, self.padding.x)
        right_sizer.AddStretchSpacer()
        #add right bottom to right
        right_sizer.Add(link_sizer, 3, wx.ALIGN_RIGHT | wx.RIGHT | wx.ALIGN_CENTER_VERTICAL, self.padding.y)
        #add right side
        sizer.Add(right_sizer, 0, wx.EXPAND | wx.ALIGN_CENTER_VERTICAL, 0)

    def on_data_changed(self, src=None, *a):
        super(ServiceProviderRow, self).on_data_changed(src, *a)
        self._reset_text_name()
        self.layout()
        self.Layout()
        self.Refresh()

#low to high priority order, (-1 = not found = lowest)
sorted_component_types = ['social', 'email', 'im']
def component_sort(a, b):
    return find(sorted_component_types, b) - find(sorted_component_types, a)

class ServiceProviderGUIMetaDataAdapter(protocols.Adapter):
    protocols.advise(asAdapterForTypes = [sp.ServiceProvider],
                     instancesProvide  = [IServiceProviderInstanceGUIMetaData])
    @property
    def account_name(self):
        name = None
        try:
            name = getattr(self.subject, 'display_name', None)
        except Exception:
            print_exc()
            if name is None:
                name = self.subject.name
        return name
#    @property
#    def service_components(self):
#        return [ServiceComponentGUIMetaData(s.component_type, s.shortname) for s in
#                sp.get_meta_components_for_provider(self.subject.provider_id)]

class ProviderList(AccountList):
    def __init__(self, *a, **k):
        super(ProviderList, self).__init__(*a, **k)
        self.Bind(wx.EVT_LIST_ITEM_FOCUSED,self.OnHoveredChanged)

    def OnHoveredChanged(self,e):
        row = self.GetRow(e.Int)
        if row:
            with row.Frozen():
                hiddens = getattr(row, 'hiddens', [])
                if row.IsHovered():
                    for obj in hiddens:
                        obj.Show()
                    row.Layout()
                    row.Refresh()
                else:
                    for obj in hiddens:
                        obj.Hide()
                    row.Layout()
                    row.Refresh()

    def on_edit(self, rowdata):
        diag = hooks.first('digsby.services.edit', parent = self.Top, sp = rowdata, impl="digsby_service_editor")
        return_code = diag.ShowModal()
        if return_code != wx.ID_SAVE:
            return

        info = diag.RetrieveData()

        log.info("Modifying %r", rowdata)
        rowdata.update_info(info)
        rowdata.update_components(info)

    def OnDelete(self, data):

        # Display a confirmation dialog.
        msgbox = hooks.first("digsby.services.delete.build_dialog", impls = (data.provider_id, 'default'), parent = self.Top, SP = data)

        try:
            if msgbox.ShowModal() == wx.ID_YES:
                for type_ in data.get_component_types():
                    comp = data.get_component(type_, create = False)
                    if comp is None:
                        continue
                    profile.account_manager.remove(comp)
        finally:
            msgbox.Destroy()

    def get_wheel_lines(self, rotation, e):
        val = rotation / float(e.GetWheelDelta()) * e.LinesPerAction
        return val / 2.5 # 2.5-line panels

    def rotation_for_lines(self, lines, e):
        return float(e.GetWheelDelta()) / e.LinesPerAction * lines * 2.5

def panel(panel, sizer, addgroup, exithooks):

    service_providers = ServiceMetaProviderPanel(sp.get_meta_service_providers(),
                                             40, 3, panel)

    two = PrefPanel(panel, service_providers, _('Add Accounts'))

    import services

    container = services.service_provider.ServiceProviderContainer(profile())
    provider_accts = observe.ObservableList(container.get_ordered() or [])

    def on_change(*a, **k):
        if not provider_accts.isflagged('being_set'):
            order = []
            for provider in provider_accts:
                for type_ in ('im', 'email', 'social'): #keep order! - no frozenset!
                    if type_ in provider.accounts:
                        order.append(provider.accounts[type_].id)
            container.set_order(order)

    def order_set(*a, **k):
        @wx.CallAfter
        def do_set():
            new = container.get_ordered()
            if new[:] != provider_accts[:]:
                with provider_accts.flagged('being_set'):
                    provider_accts[:] = new

    container.on_order_changed += order_set

    def unregister(*a, **k):
        if order_set in container.on_order_changed:
            container.on_order_changed -= order_set

    exithooks += unregister

    #hook this into on_data_changed

    accts = ProviderList(panel, provider_accts,
                            row_control = lambda *a, **k: ServiceProviderRow(use_checkbox = False, *a, **k),
                            edit_buttons = None)
    provider_accts.add_observer(on_change, obj = accts)

    three     = PrefPanel(panel, accts, _('My Accounts'))
    sizer.Add(two, 0, EXPAND)
    sizer.Add(three, 1, EXPAND | wx.TOP, 3)
    four = PrefPanel(panel,
        choices_sizer(panel, exithooks), _('Account Options'))
    sizer.Add(four, 0, EXPAND | wx.TOP, 3)
    return panel

def set_loc_values(model, prefname):
    val = pref(prefname)
    try:
        model.selection = [v[0] for v in model.values].index(val)
    except ValueError:
        pass

class PrefChoiceWatcher(trellis.Component):
    def __init__(self, model, prefname):
        trellis.Component.__init__(self)
        self.model = model
        self.prefname = prefname

    @trellis.perform
    def output_pref(self):
        mark_pref(self.prefname, self.model.values[self.model.selection][0])

class AccountLocationModels(AddOn):
    did_setup = False
    def __init__(self, subject):
        self.profile = subject
        super(AccountLocationModels, self).__init__(subject)

    def setup(self):
        if self.did_setup:
            return
        self.did_setup = True
        account_options = [('panel',   _('buddy list')),
                           ('systray', _('icon tray')),
                           ('both',    _('buddy list and icon tray'))]
        email_pref  = 'buddylist.show_email_as'
        social_pref = 'buddylist.show_social_as'
        self.email  = email  = ChoiceModel(values = account_options[:])
        self.social = social = ChoiceModel(values = account_options[:])
        set_loc_values(email, email_pref)
        set_loc_values(social, social_pref)
        self.profile.prefs.add_observer(self.on_email_changed, email_pref)
        self.profile.prefs.add_observer(self.on_social_changed, social_pref)
        self.email_watcher  = PrefChoiceWatcher(self.email,  email_pref)
        self.social_watcher = PrefChoiceWatcher(self.social, social_pref)

    @property
    def location_models(self):
        return [self.email, self.social]

    def on_email_changed(self, src, attr, old, new):
        import wx
        wx.CallAfter(set_loc_values, self.email, 'buddylist.show_email_as')
    def on_social_changed(self, src, attr, old, new):
        import wx
        wx.CallAfter(set_loc_values, self.social, 'buddylist.show_social_as')

def choices_sizer(panel, exithooks):
    p = wx.Panel(panel)
    sz = p.Sizer = VSizer()

    model_addon = AccountLocationModels(common.profile())
    model_addon.setup()

    location_models = model_addon.location_models

    import gui.lattice #@UnusedImport: side effect registering interfaces
    choices = list(yield_choices(location_models, p))
    exithooks.append(lambda:release_syncs(choices))

    labels = [_('Show email accounts in:'),
              _('Show social networks in:'),]

    to_add = [[(SText(p, label), 0, wx.ALIGN_CENTER_VERTICAL),
                   (choice, 1, 0)]
                  for label,choice in zip(labels, choices)]

    s = wx.FlexGridSizer(len(location_models), 2, 7,7)
    s.AddMany(sum(to_add,[]))
    s.AddGrowableCol(1,1)
    sz.Add(s, 0, EXPAND)

    return p


import pickle

# base de datos relacionados con el Clientes, todas deben tener la
# misma longitud de datos
#                   0       1
Clientes_id = []
Clientes_name = []
Clientes = [Clientes_id, Clientes_name]

# base de datos relacionados con el Vendedores, todas deben tener la
# misma longitud de datos
#                   0           1
Vendedores_id = []
Vendedores_name = []
Vendedores = [Vendedores_id, Vendedores_name]

# base de datos relacionados con el producto, todas deben tener la
# misma longitud de datos
#                   0       1       2
Productos_id = []
Productos_name = []
Productos_nacionalidad = []
Productos_tamaño = []
Productos_precio = []
Productos_color = []
Productos = [Productos_id, Productos_name, Productos_nacionalidad, Productos_tamaño, Productos_precio, Productos_color]

# base de datos relacionados con las ventas, todas deben tener la
# misma longitud de datos
#                   0       1       2
venta_id = []
venta_cliente_id = []
venta_cliente_name = []
ventas_product_id = []
ventas_product_name = []
ventas_product_tamaño = []
ventas_product_color = []
ventas_product_origen = []
ventas_product_price = []
ventas_product_qty = []
ventas_product_total = []
Ventas = [venta_id, venta_cliente_id, venta_cliente_name, ventas_product_id, ventas_product_name, ventas_product_tamaño, ventas_product_color, ventas_product_origen, ventas_product_price, ventas_product_qty, ventas_product_total]

# Guardar datos en archivos binarios
def Save_Data(Clientes, Vendedores, Productos, Ventas):
    #print(Clientes_id, Clientes_name)
    try:
        archivo = open('Clientes', 'rb')
        Clientes = pickle.load(archivo)
        archivo.close()
    except:
        print('El Archivo no Existe... Se crea uno')
        archivo = open('Clientes', 'wb')
        pickle.dump(Clientes, archivo)
    try:
        archivo = open('Vendedores', 'rb')
        Vendedores = pickle.load(archivo)
        archivo.close()
    except:
        print('El Archivo no Existe... Se crea uno')
        archivo = open('Vendedores', 'wb')
        pickle.dump(Vendedores, archivo)
    try:
        archivo = open('Productos', 'rb')
        Productos = pickle.load(archivo)
        archivo.close()
    except:
        print('El Archivo no Existe... Se crea uno')
        archivo = open('Productos', 'wb')
        pickle.dump(Productos, archivo)
    try:
        archivo = open('Ventas', 'rb')
        Ventas = pickle.load(archivo)
        archivo.close()
    except:
        print('El Archivo no Existe... Se crea uno')
        archivo = open('Ventas', 'wb')
        pickle.dump(Ventas, archivo)

# Cargar datos en archivos binarios
try:
    Clientes = pickle.load(open('Clientes', 'rb'))
    for c_id in range(len(Clientes)):
        cid = Clientes[0][c_id]
        Clientes_id.append(cid)

    for c_name in range(len(Clientes)):
        cn = Clientes[1][c_name]
        Clientes_name.append(cn)
except:
    print('El Archivo no Existe... Establezca uno')
try:
    Vendedores = pickle.load(open('Vendedores', 'rb'))
    for v_id in range(len(Vendedores)):
        vid = Vendedores[0][v_id]
        Vendedores_id.append(vid)

    for v_name in range(len(Vendedores)):
        vn = Vendedores[1][v_name]
        Vendedores_name.append(vn)
except:
    print('El Archivo no Existe... Establezca uno')
try:
    Productos = pickle.load(open('Productos', 'rb'))
    for p_id in range(len(Productos[0])):
        pid = Productos[0][p_id]
        Productos_id.append(pid)

    for p_name in range(len(Productos[1])):
        pn = Productos[1][p_name]
        Productos_name.append(pn)

    for p_org in range(len(Productos[2])):
        po = Productos[2][p_org]
        Productos_nacionalidad.append(po)

    for p_tam in range(len(Productos[3])):
        pt = Productos[3][p_tam]
        Productos_tamaño.append(pt)

    for p_pre in range(len(Productos[4])):
        pp = Productos[4][p_pre]
        Productos_precio.append(pp)

    for p_co in range(len(Productos[5])):
        pc = Productos[5][p_co]
        Productos_color.append(pc)
except:
    print('El Archivo no Existe... Establezca uno')
try:
    Ventas = pickle.load(open('Ventas', 'rb'))
    for v_id in range(len(Ventas[0])):
        vid = Ventas[0][v_id]
        venta_id.append(vid)

    for v_cid in range(len(Ventas[1])):
        vci = Ventas[1][v_cid]
        venta_cliente_id.append(vci)

    for v_cna in range(len(Ventas[2])):
        vcn = Ventas[2][v_cna]
        venta_cliente_name.append(vcn)

    for v_pid in range(len(Ventas[3])):
        vpi = Ventas[3][v_pid]
        ventas_product_id.append(vpi)

    for v_pna in range(len(Ventas[4])):
        vpn = Ventas[4][v_pna]
        ventas_product_name.append(vpn)

    for v_pt in range(len(Ventas[5])):
        vpt = Ventas[5][v_pt]
        ventas_product_tamaño.append(vpt)

    for v_pc in range(len(Ventas[6])):
        vpc = Ventas[6][v_pc]
        ventas_product_color.append(vpc)

    for v_po in range(len(Ventas[7])):
        vpo = Ventas[7][v_po]
        ventas_product_origen.append(vpo)

    for v_pp in range(len(Ventas[8])):
        vpp = Ventas[8][v_pp]
        ventas_product_price.append(vpp)

    for v_pq in range(len(Ventas[9])):
        vpq = Ventas[9][v_pq]
        ventas_product_qty.append(vpq)

    for v_pt in range(len(Ventas[10])):
        vpt = Ventas[10][v_pt]
        ventas_product_total.append(vpt)
except:
    print('El Archivo no Existe... Establezca uno')


# -*- coding: utf-8 -*-
from __future__ import print_function
from __future__ import absolute_import
from __future__ import division

from keras import backend as K
from .caps_utils import equal_int_shape

import numpy as np

def p_norm(vectors, order_p=2, axis=-1, squared=False, keepdims=False, epsilon=K.epsilon()):
    with K.name_scope('p_norm'):
        # special case 1
        if order_p == 1:
            diss = K.sum(K.abs(vectors), axis=axis, keepdims=keepdims)
        elif order_p == np.inf:
            diss = K.max(K.abs(vectors), axis=axis, keepdims=keepdims)
            if squared:
                raise NotImplementedError("The squared computation of the maximums-norm is not defined.")
        # Euclidean distance
        elif order_p == 2:
            diss = K.sum(K.square(vectors), axis=axis, keepdims=keepdims)
            if not squared:
                if epsilon == 0:
                    diss = K.sqrt(diss)
                else:
                    diss = K.sqrt(K.maximum(diss, epsilon))
        elif order_p % 2 == 0 and order_p > 0:
            diss = K.sum(K.pow(vectors, order_p), axis=axis, keepdims=keepdims)
            if not squared:
                if epsilon == 0:
                    diss = K.pow(diss, 1 / order_p)
                else:
                    diss = K.pow(K.maximum(epsilon, diss), 1 / order_p)
        elif order_p > 1:
            diss = K.sum(K.pow(K.abs(vectors), order_p), axis=axis, keepdims=keepdims)
            if not squared:
                if epsilon == 0:
                    diss = K.pow(diss, 1 / order_p)
                else:
                    diss = K.pow(K.maximum(epsilon, diss), 1 / order_p)
        else:  # < 1
            raise NotImplementedError("The computation of the p-norm with p<1 could be instable. "
                                      "Therefore, we don't support it so far.")

        return diss

def euclidean_norm(vectors, axis=-1, squared=False, keepdims=False, epsilon=K.epsilon()):
    return p_norm(vectors, order_p=2, axis=axis, squared=squared, keepdims=keepdims, epsilon=epsilon)

def euclidean_distance(x, y, squared=False, epsilon=K.epsilon()):
    # last dimension must be the vector dimension!
    # compute the distance via the identity of the dot product. This avoids the memory overhead due to the subtraction!
    #
    # x.shape = (number_of_x_vectors, vector_dim)
    # y.shape = (number_of_y_vectors, vector_dim)
    #
    # output: matrix of distances (number_of_x_vectors, number_of_y_vectors)
    for tensor in [x, y]:
        if K.ndim(tensor) != 2:
            raise ValueError('The tensor dimension must be two. You provide: K.ndim(tensor)=' + str(K.ndim(tensor))
                             + '.')
    if not equal_int_shape([K.int_shape(x)[1]], [K.int_shape(y)[1]]):
        raise ValueError('The vector shape must be equivalent in both tensors. You provide: K.int_shape(x)[1]='
                         + str(K.int_shape(x)[1]) + ' and  K.int_shape(y)[1]=' + str(K.int_shape(y)[1]) + '.')

    with K.name_scope('euclidean_distance'):
        y = K.transpose(y)

        diss = K.sum(K.square(x), axis=1, keepdims=True) - 2 * K.dot(x, y) + K.sum(K.square(y), axis=0, keepdims=True)

        if not squared:
            if epsilon == 0:
                diss = K.sqrt(diss)
            else:
                diss = K.sqrt(K.maximum(diss, epsilon))

        return diss

def svd(tensors, full_matrices=False, compute_uv=True):
    if K.backend() == 'tensorflow':
        import tensorflow as tf
        # return s, u, v
        return tf.svd(tensors, full_matrices=full_matrices, compute_uv=compute_uv)

    elif K.backend() == 'cntk':
        raise NotImplementedError("SVD is not implemented for CNTK")

    elif K.backend() == 'theano':
        raise NotImplementedError("SVD is not implemented for Theano")
    else:
        raise NotImplementedError("Unknown backend `" + K.backend() + "`.")

# Aliases:
norm = euclidean_norm


from unittest import TestCase
from Student_Read_Write import print_class_average
from unittest.mock import patch
import io
from Student import Student
import os

class TestPrint_class_average(TestCase):

    def setUp(self):
        self.testStudent1 = Student('Tommy', 'May', 'A01086435', True, ['90', '80', '70'])
        self.testStudent2 = Student('Another', 'Person', 'A01086436', True, ['100', '60'])
        self.testStudent3 = Student('person', 'three', 'A01086437', True, [])
        self.testStudent4 = Student('person', 'four', 'A01086438', True, [])
        self.testStudent5 = Student('person', 'five', 'A01086439', True, [])

    @patch('sys.stdout', new_callable=io.StringIO)
    def test_print_class_average(self, mock_output):
        students_list = [self.testStudent1, self.testStudent2]
        print_class_average(students_list)
        actual_output = mock_output.getvalue()
        expected_output = 'the class average is: 80.00%\n\n'
        self.assertEqual(actual_output, expected_output)

    @patch('sys.stdout', new_callable=io.StringIO)
    def test_student_with_no_grades_not_added_to_average(self, mock_output):
        students_list = [self.testStudent1, self.testStudent2, self.testStudent3]
        print_class_average(students_list)
        actual_output = mock_output.getvalue()
        expected_output = 'the class average is: 80.00%\n\n'
        self.assertEqual(actual_output, expected_output)

    @patch('sys.stdout', new_callable=io.StringIO)
    def test_empty_students_list(self, mock_output):
        students_list = []
        print_class_average(students_list)
        actual_output = mock_output.getvalue()
        expected_output = 'No students in file\n'
        self.assertEqual(actual_output, expected_output)

    @patch('sys.stdout', new_callable=io.StringIO)
    def test_all_students_without_grades(self, mock_output):
        students_list = [self.testStudent3, self.testStudent4, self.testStudent5]
        print_class_average(students_list)
        actual_output = mock_output.getvalue()
        expected_output = 'No students with grades found\n'
        self.assertEqual(actual_output, expected_output)


import sys
import os
import unittest
import subprocess

sys.path.append('./src')
from rpn_user import is_posix

# change current working directory to src
os.chdir(os.path.join(os.path.abspath(os.getcwd()), 'src'))

if is_posix():
    pycmd = 'python3'
else:
    pycmd = 'python'

class TestRPNUser(unittest.TestCase):
    # pipe mode
    def _run_pipe_cmd(self, cmd):
        ps = subprocess.Popen(cmd,
                              shell=True,
                              stdout=subprocess.PIPE,
                              stderr=subprocess.STDOUT)
        output_bytearray = ps.communicate()[0]
        output_string = output_bytearray.decode().strip()
        return output_string

    def test_pipe_good(self):
        if is_posix():
            cmd = "echo '2 3 +' | python3 rpn_user.py -"
            self.assertEqual(self._run_pipe_cmd(cmd), "[5.0]")

    def test_pipe_trash(self):
        if is_posix():
            cmd = "echo '2ffg 3fg gfd+' | python3 rpn_user.py -"
            self.assertTrue(self._run_pipe_cmd(
                cmd).startswith('Cannot convert'))

    # cmd line args mode
    def _run_cmd_line_args(self, cmd):
        output = subprocess.check_output(cmd)
        return output.decode().strip()

    def test_cmd_line_args_good(self):
        cmd = [pycmd, "rpn_user.py", "2", "3", "+"]
        self.assertEqual(self._run_cmd_line_args(cmd), "[5.0]")

    def test_cmd_line_args_trash(self):
        cmd = [pycmd, "rpn_user.py", "2afgfa", "gfag3", "g+"]
        self.assertTrue(
            self._run_cmd_line_args(cmd).startswith('Cannot convert'))

    # interactive mode
    def _run_interactive(self, cmd):
        ps = subprocess.Popen([pycmd, "rpn_user.py"],
                              stdin=subprocess.PIPE,
                              stdout=subprocess.PIPE,
                              stderr=subprocess.STDOUT)
        output_bytearray = ps.communicate(input=cmd)[0]
        output_string = output_bytearray.decode().strip()
        return output_string

    def test_interactive_mode_good(self):
        result = self._run_interactive(b"2 3 +")
        self.assertTrue(result.endswith("[5.0] >"))

    def test_interactive_mode_trash(self):
        result = self._run_interactive(b"s f2 - f3 +")
        self.assertTrue('Cannot convert' in result)

if __name__ == '__main__':
    unittest.main()


"""
AOC day 13 2018
"""
from collections import defaultdict
from lib.filehelper import file_to_str_array
# pylint: disable=missing-module-docstring

class Board():
    def __init__(self,inputfile):
        self.inputfile=inputfile
        self.board=defaultdict(lambda: '.')
        self.processinputfile()

    def processinputfile(self):
        self.input=file_to_str_array(self.inputfile)
        self.dotlocs=[]
        self.folds=[]
        self.maxx=0
        self.maxy=0
        for line in self.input:
            if ',' in line:
                coords = line.split(',')
                x=int(coords[0])
                y=int(coords[1])
                self.maxx=max(self.maxx,x)
                self.maxy=max(self.maxy,y)
                self.board[(x,y)]='#'

            elif len(line) == 0:
                pass
            elif  line.startswith('fold along'):
                self.folds.append(line.replace('fold along ',''))
        return None

    def fold(self,foldinst):
        direction,value = foldinst.split('=')
        value=int(value)
        if direction == 'y':
            for x in range(self.maxx+1):
                self.board[(x,value)]='-'
            for y in range(0,value):
                for x in range(0,self.maxx+1):
                    if self.board[(x,y)] == '.':
                        self.board[(x,y)]= self.board[(x,2*value-y)]
            self.maxy=value-1

        elif direction == 'x':
            for y in range(self.maxy+1):
                self.board[(value,y)]='|'
            for x in range(0,value):
                for y in range(0,self.maxy+1):
                    if self.board[(x,y)] == '.':
                        self.board[(x,y)]= self.board[(2*value-x,y)]
            self.maxx=value-1

    def part2(self):
        for fold in self.folds:
            self.fold(fold)

    def part1(self):
        self.fold(self.folds[0])
        count=0
        for x in range(self.maxx+1):
            for y in range(self.maxy+1):
                if self.board[(x,y)]=='#':
                    count+=1
        return count

    def __repr__(self):
        output=''
        for y in range(self.maxy+1):
            thisy=''
            for x in range(self.maxx+1):
                thisy+=self.board[(x,y)]
            output+=thisy+'\n'
        return output

def day13_01():
    """Run part 1 of Day 13's code"""
    inputfile='input/day13.txt'
    testboard=Board(inputfile)
    result=testboard.part1()
    print(f'1301: {result} Hashes after the first fold')

def day13_02():
    """Run part 2 of Day 13's code"""
    inputfile='input/day13.txt'
    testboard=Board(inputfile)
    testboard.part2()
    result='CAFJHZCK'
    print(f'1302: {result} Is the activation key.')

if __name__ == "__main__":
    day13_01()
    day13_02()


#%%

import requests
from bs4 import BeautifulSoup
import pandas as pd
import os
import re

# 2016 ~ 2020년까지 4월 1일부터 180일 동안 날짜 데이터 생성

yrs_list = ['2016','2017', '2018', '2019','2020']
date_list = []

path = '/home/swha/ToTo/ToTo/Data/team_info/'

for year in yrs_list:
    year_2017 = pd.date_range(year + '-04-01', periods = 180, freq = '1d')
    date_list.append(list(map(lambda x:str(x)[:10],year_2017.to_list())))

date_list = sum(date_list,[])
stadiums = ['라이온즈파크','고척돔','잠실','마산','인천문학','대전한밭','챔피언스필드','케이티위즈파크','부산사직']

#%%
# 팀정보 크롤링
# 경기 정보, 최근 팀정보, 선발투수 정보를 크롤링으로 긁어와 html 원본 저장

# log: 각 팀의 배팅오더
# preview: 각 팀의 선발투수 정보, 최근 10경기, 상대전적

for date in date_list:
    for stadium in stadiums:
        log_url = 'http://www.statiz.co.kr/boxscore.php?opt=5&date=' + date + '&stadium=' + stadium
        response = requests.get(log_url)
        html = response.text
        log_soup = BeautifulSoup(html, 'html.parser')

        preview_url = 'http://www.statiz.co.kr/boxscore.php?opt=2&date=' + date + '&stadium=' + stadium
        response = requests.get(preview_url)
        html = response.text
        preview_soup = BeautifulSoup(html, 'html.parser')

        with open(os.getcwd() + '/soup_data/' + f'{date}_{stadium}_log', "w", encoding='utf-8') as file:
            file.write(str(log_soup))

        with open(os.getcwd() + '/soup_data/' + f'{date}_{stadium}_preview', "w", encoding='utf-8') as file:
            file.write(str(preview_soup))

        print(date, stadium)

#%%
# 데이터 없는 soup 삭제
from get_teamdata_from_html  import away_batting_order
from bs4 import BeautifulSoup
import os
data_path = '/home/swha/ToTo/ToTo/Data/soup/soup_data/'

# deleteCandidate = []

for dataName in sorted(os.listdir(data_path)):
    if dataName.endswith('log'):
        soup = BeautifulSoup(open(data_path + dataName),"html.parser")
        try:
            away_batting_order(soup)
        except AttributeError:
            os.remove(f'{data_path}{dataName}')
            os.remove(f'{data_path}{dataName[:-4]}_preview')
            # deleteCandidate.append(dataName)
            # deleteCandidate.append(f'{dataName[:-4]}_preview')
            print(f'{data_path}{dataName}')

#------------------------------------------------
#%%
# 선수 정보 크롤링!!
# all_players 엑셀 sheet에 담겨있는 선수 정보를 이용하여 크롤링

batters = pd.read_excel('/home/swha/ToTo/ToTo/Data/raw/all_players.xlsx',sheet_name='Batters',engine = 'openpyxl',index_col=0)

#%%

# 타자 데이터
existPlayerList = os.listdir('/home/swha/ToTo/ToTo/Data/soup/batter_soup_data/')
existPlayer = list(map(lambda x:(x.split('_')[0],x.split('_')[1] ),existPlayerList))

for player,birth in batters.to_numpy():
    if (player,birth) in existPlayer:
        print(f'{player} passed')
        continue

    for year in yrs_list:

        url = 'http://www.statiz.co.kr/player.php?opt=3&sopt=0&name=' + player + '&birth=' + birth +'&re=0&se=&da=&year=' + year + '&cv='

        response = requests.get(url)
        html = response.text
        day_soup = BeautifulSoup(html, 'html.parser')

        if not day_soup.find_all('tr') or (day_soup.find_all('tr')[-1].getText()).startswith('데이터'):
            continue
        else:

            with open(f'/home/swha/ToTo/ToTo/Data/soup/batter_soup_data/{player}_{birth}_{year}', "w", encoding='utf-8') as file:
                file.write(str(day_soup))
                print(player,year)

#%%
picthers = pd.read_excel('/home/swha/ToTo/ToTo/Data/raw/all_players.xlsx',sheet_name='Pitchers',engine = 'openpyxl',index_col=0)

existPlayerList = os.listdir('/home/swha/ToTo/ToTo/Data/soup/picther_soup_data/')
existPlayer = list(map(lambda x:(x.split('_')[0],x.split('_')[1] ),existPlayerList))

for player,birth in picthers.to_numpy():
    if (player,birth) in existPlayer:
        print(f'{player} passed')
        continue

    for year in yrs_list:

        url = 'http://www.statiz.co.kr/player.php?opt=3&sopt=0&name=' + player + '&birth=' + birth +'&re=1&se=&da=&year=' + year + '&cv='

        response = requests.get(url)
        html = response.text
        day_soup = BeautifulSoup(html, 'html.parser')

        if not day_soup.find_all('tr') or (day_soup.find_all('tr')[-1].getText()).startswith('데이터'):
            continue
        else:

            with open(f'/home/swha/ToTo/ToTo/Data/soup/picther_soup_data/{player}_{birth}_{year}', "w", encoding='utf-8') as file:
                file.write(str(day_soup))
                print(player,year)

#---
#%%


# SPDX-FileCopyrightText: Copyright (c) 2022 Tim Cocks for Adafruit Industries
#
# SPDX-License-Identifier: MIT
"""
An example that shows how you can use the FlipClock displayio
object to represent hours and minutes values.

Note that it's not counting at realtime speed, and it doesn't
know the current hour/minute. This example is only showing the logic
needed to count time with the FlipClock
"""
import time
import board
from displayio import Group
import adafruit_imageload
from adafruit_displayio_flipclock.flip_clock import FlipClock

#  == Configuration Variables ==

# seconds per animation frame
ANIMATION_DELAY = 0.02

# number of frames in the animation
ANIMATION_FRAME_COUNT = 10

# color indexes that will be made transparent in the palette
TRANSPARENT_INDEXES = range(11)

# Brightness modifier for top half during animation
BRIGHTER_LEVEL = 0.99

# Brightness modifier for bottom half in the shadow during animation
DARKER_LEVEL = 0.5

# Brightness modifier to use by default for static sprites
MEDIUM_LEVEL = 0.9

# == END configuration variables ==

# access built-in display
display = board.DISPLAY

# load the static sprite sheet
static_spritesheet, static_palette = adafruit_imageload.load("static_sheet.bmp")
static_palette.make_transparent(0)

# load the animation sprite sheets
top_animation_spritesheet, top_animation_palette = adafruit_imageload.load(
    "grey_top_animation_sheet.bmp"
)
bottom_animation_spritesheet, bottom_animation_palette = adafruit_imageload.load(
    "grey_bottom_animation_sheet.bmp"
)

# set the transparent color indexes in respective palettes
for i in TRANSPARENT_INDEXES:
    top_animation_palette.make_transparent(i)
    bottom_animation_palette.make_transparent(i)

# calculate sprite size by dividing total sheet
SPRITE_WIDTH = static_spritesheet.width // 3
SPRITE_HEIGHT = (static_spritesheet.height // 4) // 2

# initialize FlipClock widget object
clock = FlipClock(
    static_spritesheet,
    static_palette,
    top_animation_spritesheet,
    top_animation_palette,
    bottom_animation_spritesheet,
    bottom_animation_palette,
    SPRITE_WIDTH,
    SPRITE_HEIGHT,
    anim_delay=ANIMATION_DELAY,
    brighter_level=BRIGHTER_LEVEL,
    darker_level=DARKER_LEVEL,
    medium_level=MEDIUM_LEVEL,
)

# position it in the center of the display
clock.anchor_point = (0.5, 0.5)
clock.anchored_position = (display.width // 2, display.height // 2)

# group to hold our flip clock
main_group = Group()

# append the clock to the group
main_group.append(clock)

# show the group on the display
board.DISPLAY.show(main_group)

# variables to store hours and minutes values
cur_hour = clock.first_pair
cur_minute = clock.second_pair
next_minute = None
next_hour = None

while True:
    # increment minute value
    cur_minute = clock.second_pair
    next_minute = int(cur_minute) + 1

    # if it's time to wrap minutes space
    if next_minute > 59:
        # reset next minute to 0
        next_minute = 0

        # set the minute value on the flip clock
        clock.second_pair = str(next_minute)

        # increment hour value
        cur_hour = clock.first_pair
        next_hour = int(cur_hour) + 1

        # if it's time to wrap hours space
        if next_hour > 23:
            # reset hour to 0
            next_hour = 0

        # set the hour value on the flip clock
        clock.first_pair = str(next_hour)

    else:  # not ready to wrap minutes yet

        # set minute value on the flip clock
        clock.second_pair = str(next_minute)
    time.sleep(0.1)


from numpy import result_type
import pandas as pd
from pathlib import Path

base_path = 'Tars_large/tars_ft_ml-false/'
n_shots = ['1', '2', '4', '8', '10', '50', '100', 'full']
reps = range(1, 6)

def get_series_from_repdir(n_shot, trial, name=None):
    with open(base_path + "/model_" + n_shot + '_shot/rep_' + trial + '/training.log', 'r') as f:
        for line in f:
            line = line.strip()
            if line.startswith('macro avg'):
                l, p, r, f1, s = re.split("\s\s+", line)
    result_dict = {
        'n_shot': n_shot,
        'trial': trial,
        'precision': float(p) * 100,
        'recall': float(r) * 100,
        'f1-score': float(f1) * 100,
        'support':int(s)
    }
    return pd.DataFrame(result_dict, index=[n_shot + '_' + trial])

def create_tars_result_spreadsheets():
    all_results = pd.DataFrame()
    for n_shot in n_shots:
        for rep in reps:
            all_results = pd.concat([all_results, get_series_from_repdir(n_shot, str(rep))])
    all_results.to_csv("fs_results.csv")
    return all_results

import pdb
import re

if __name__ == '__main__':
    df = create_tars_result_spreadsheets()
    df_agg = df.groupby("n_shot").agg({
        'precision':['mean', 'std'],
        'recall':['mean', 'std'],
        'f1-score':['mean', 'std'],
    }).round(1)
    # import pdb; pdb.set_trace()
    print(df_agg.loc[n_shots])
    df_agg.loc[n_shots].to_csv("fs_results_agg.csv")


import numpy as np
import pandas as pd
import tensorflow as tf
import dataprocess as dp  #데이터 처리를 위한 함수를 담은 파이썬 파일

def init_weights(shape):
    return tf.Variable(tf.random_normal(shape, stddev=0.01))

def model(X, W, B, time_step_size):
    XT = tf.transpose(X, [1, 0, 2])
    XR = tf.reshape(XT, [-1, time_step_size])
    X_split = tf.split(0, time_step_size, XR)

    lstm = tf.nn.rnn_cell.BasicLSTMCell(time_step_size, forget_bias=1.0, state_is_tuple=True)
    outputs, _state = tf.nn.rnn(lstm, X_split, dtype=tf.float32)

    return tf.matmul(outputs[-1], W) + B, lstm.state_size

char_rdic = list('0123456')
char_dic = {w: i for i, w in enumerate(char_rdic)}

# 트레이닝 세트를 만듬 1월부터 2월까지의 행위
user = pd.read_csv('C:/Users/lab/InsiderThreat/daily_work/daily_f_u989.csv', sep=',')
user = user.fillna(method='ffill', axis=1, downcast={'6.0': '6'})
train_set = pd.DataFrame(user[0:40])

cols = train_set.columns.tolist()
cols = cols[3:-1] + cols[-1:]
train_set = train_set[cols]

train_set = np.array(train_set, dtype='f')
x_data = np.empty([1, 54, 7], dtype='f')
sample = np.empty([1, 54], dtype=int)
for seq in train_set:
    temp_x = dp.set_xdata(seq)    #make 2d numpy array
    temp_y = [int(i) for i in seq]
    x_data = np.vstack((x_data, temp_x[None]))
    sample = np.vstack((sample, temp_y[0:]))
x_data = np.delete(x_data, 0, 0)
sample = np.delete(sample, 0, 0)

print("X: ", type(x_data[0][0][0]))
print("Y: ", sample)
#sequence = train_set[0]
#x_data = dp.set_xdata(sequence)
#sample = [int(i) for i in sequence]
print(sample[0,])

X = tf.placeholder('float', [None, 54, 7])
Y = tf.placeholder('int64', [None, 54])

output_size = len(char_dic)
rnn_size = output_size
time_step_size = 54
batch_size = 1

W = init_weights([time_step_size, 7])
B = init_weights([7])

py_x, state_size = model(X,W,B, time_step_size)
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(py_x, Y))
train_op = tf.train.RMSPropOptimizer(0.001,0.9).minimize(cost)
predic_op = tf.argmax(py_x, 1)

with tf.Session() as sess:
    tf.initialize_all_variables().run()
    for i in range(100):
        for start, end in zip(range(0, len(x_data), batch_size), range(batch_size, len(x_data)+1, batch_size)):
            sess.run(train_op, feed_dict={X:x_data[start:end], Y: sample[start:end]})

"""
rnn_cell = tf.nn.rnn_cell.BasicRNNCell(rnn_size)
state = tf.zeros([batch_size, rnn_cell.state_size])
XT = tf.transpose(X, [1, 0, 2])
XR = tf.reshape(XT, [-1, 54])
X_split = tf.split(0, time_step_size, XR)
outputs, state = tf.nn.rnn(rnn_cell, X_split, state)

logit = tf.reshape(tf.concat(1, outputs), [-1, rnn_size])
targets = tf.reshape(sample[0,], [-1])
weights = tf.ones([time_step_size * batch_size])

loss = tf.nn.seq2seq.sequence_loss_by_example([logit], [targets], [weights])
cost = tf.reduce_sum(loss) / batch_size
train_op = tf.train.RMSPropOptimizer(0.01, 0.9).minimize(cost)

with tf.Session() as sess:
    tf.global_variables_initializer().run()
    print(sess.run(XR), feed_dict={X: x_data[0:1]})
    for i in range(100):
        sess.run(train_op, feed_dict={X: x_data, Y: sample})
        if i % 20 == 0:
            result = sess.run(tf.arg_max(logit, 1))
            #print('%r, %r' %(result, [char_rdic[t] for t in result]))
        print('%r, %r' % (result, [char_rdic[t] for t in result]))

"""


import numpy as np # linear algebra
import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)
import shap
from tensorflow import keras

def normalize(df):
    result = df.copy()
    max_value = df.max()
    min_value = df.min()
    result = (df - min_value) / (max_value - min_value)
    return result

from pandas.api.types import is_string_dtype

data = pd.read_csv('german_credit_data.csv',index_col=0,sep=',')
labels = data.columns

print(labels)

# lets go through column 2 column
for col in labels:
    if is_string_dtype(data[col]):
        if col == 'Risk':
            # we want 'Risk' to be a binary variable
            data[col] = pd.factorize(data[col])[0]
            continue
        # the other categorical columns should be one-hot encoded
        data = pd.concat([data, pd.get_dummies(data[col], prefix=col)], axis=1)

        data.drop(col, axis=1, inplace=True)
    else:
        data[col] = normalize(data[col])

print(data)
data = data.drop(labels=['Saving accounts_rich'], axis=1)
print(data)

data_train = data.iloc[:800]
data_valid = data.iloc[800:]
x_train = data_train.iloc[:,:-1]
y_train = data_train.iloc[:,-1]
x_val = data_valid.iloc[:,:-1]
y_val = data_valid.iloc[:,-1]

from keras.models import Sequential
from keras import regularizers
from keras import optimizers
from keras.layers import Dense, Dropout, Activation

sgd = optimizers.SGD(lr=0.03, decay=0, momentum=0.9, nesterov=False)

model = Sequential()
model.add(Dense(units=50, activation='relu', input_dim=22, kernel_initializer='glorot_normal', bias_initializer='zeros'))#, kernel_regularizer=regularizers.l2(0.01)))

model.add(Dense(units=1, activation='sigmoid', kernel_initializer='glorot_normal', bias_initializer='zeros'))

model.compile(loss='binary_crossentropy',
              optimizer=sgd,
              metrics=['accuracy'])

model.fit(x_train.values, y_train.values, validation_data=(x_val.values, y_val.values), epochs=30, batch_size=128)

#model.save('GC1.h5')
# evaluate the model
loss, acc = model.evaluate(x_val, y_val, verbose=0)
print('Test Loss: %.3f' % loss)
print('Test Accuracy: %.3f' % acc)


# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models, migrations

class Migration(migrations.Migration):

    dependencies = [
        ('medicamentos', '0002_auto_20151014_0011'),
        ('clientes', '0001_initial'),
    ]

    operations = [
        migrations.CreateModel(
            name='Detalle_Tickets',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('cantidad', models.IntegerField(max_length=9)),
                ('medicamento', models.ForeignKey(to='medicamentos.Medicamentos')),
            ],
            options={
            },
            bases=(models.Model,),
        ),
        migrations.CreateModel(
            name='Ticket',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('codigo', models.CharField(unique=True, max_length=10)),
                ('fecha', models.DateTimeField(auto_now_add=True)),
                ('cliente', models.ForeignKey(blank=True, to='clientes.Cliente', null=True)),
                ('medicamento', models.ManyToManyField(to='medicamentos.Medicamentos', through='ventas.Detalle_Tickets')),
            ],
            options={
            },
            bases=(models.Model,),
        ),
        migrations.AddField(
            model_name='detalle_tickets',
            name='ticket',
            field=models.ForeignKey(to='ventas.Ticket'),
            preserve_default=True,
        ),
    ]


# Creates predictions.npy by BellKor Baseline method

import numpy as np
import pandas as pd

''' 1. Load data '''
base = np.load('base.npy')

''' 2. Construct matrix of total average (u) and deviations (b_i) for each movie '''
ratings = []		# arrays of all movie ratings sorted by movie index
len = 0				# size of ratings

# Read training data
for i in base:
	# user, movie, time, rating
	u, m, t, r =  i[0], i[1], i[2], i[3]

	if (len < m + 1):
		ratings.append([r])
		len += 1
	else:
		ratings[m].append(r)

# Compute movie averages and regularized deviations
averages = []
for r in ratings: # compute average rating
	r = np.array(r)
	avg = np.average(r)
	averages.append(avg)

movie_avg = np.average(np.array(averages))

# Construct Matrix
# 	- First row contains overall movie average rating
# 	- Consequent Row Format: [average, deviation]
matrix = [[movie_avg, 0.0]]
i = 0 # index of movie
for r in ratings: 	# compute standard deviation, b_i = Sum(r - u) / (lambda1 - |R|)
	r = np.array(r) # lambda1 = 25 (bellkor paper)
	sum = 0.0
	for x in r:
		sum = sum + (x - movie_avg)
	dev = sum/(25 + np.size(r))
	matrix.append([averages[i], dev])
	i = i + 1

np_matrix = np.array(matrix)
np.save('avg_dev.npy', np_matrix) # Store matrix in avg_dev.npy

print("Finished movie computations.\n")

''' 3. Compute regularized user rating deviations (b_u). '''
user_ratings = [] 	# (r - u - b_1) values per user, sorted by user index
user_movs = []  	# arrays of movie indices rated by user, sorted by user index
user = 0			# index of current user in file

# Read training data
for i in base:
	# user, movie, time, rating
	u, m, t, r =  i[0], i[1], i[2], i[3]

	# store ratings and movies by user index
	if (user < u+1):
		user_ratings.append([(r - u - matrix[m][1])])
		user_movs.append([m])
		user = user + 1
	else:
		user_ratings[u].append(r - u - matrix[m][1])
		user_movs[u].append(m)

# Compute regularized user deviations: b_u = sum(r - u - b_i) / (lambda2 - R)
# lambda2 = 10 (bellkor paper)
b_u = []
for user in user_ratings:
	arr = np.array(user)
	R = np.size(arr)	# total number of ratings
	sum = np.sum(arr)  	# sum of user's (r - u - b_1)
	b = sum / (10 - R)
	b_u.append(b)

print("Finished user computations.\n")

''' 4. Predict and store unknown ratings '''
# "predictions.npy"
predictions = [] # matrix: user_index, movie_index, predicted_rating

usr_idx = -1
for movs in user_movs:
	usr_idx = usr_idx + 1
	mov_idx = -1
	for [avg, b_i] in matrix:
		mov_idx = mov_idx + 1
		if mov_idx not in movs:
			rating = u + b_u[usr_idx] + b_i
			predictions.append([usr_idx, mov_idx, rating])

print(predictions)
# save predictions matrix
np.save("predictions.npy", predictions)
print("Finished predictions.\n")
print("All done!")


"""Contains constants used for the project"""

import pathlib

SOURCE_NAME = 'github'
NAMESPACE = 'OliverVea'

REPO_ROOT = pathlib.Path(__file__).parent.parent
SLN_FILE = REPO_ROOT / 'FluentFuzzy.sln'
BUILD_ROOT = REPO_ROOT / 'build'
TEST_ROOT = REPO_ROOT / 'test'
SRC_ROOT = REPO_ROOT / 'src'

class Project:
    def __init__(self, name):
        self.name = name
        self.csproj_name = name + '.csproj'
        self.project_folder = SRC_ROOT / name
        self.csproj_path = self.project_folder / self.csproj_name

FLUENT_FUZZY = Project('FluentFuzzy')
FLUENT_FUZZY_VISUALIZATION = Project('FluentFuzzy.Visualization')


"""
Script to get the value of the best hyper params from the tune of each CNN
"""
import pandas as pd

def get_params(file_name, params):
    df_mean = pd.read_csv(f"tune_results/{file_name}.csv")

    min_loss_avg = df_mean["loss"].min()
    df_param = df_mean.loc[df_mean["loss"] == min_loss_avg]

    df_all = pd.read_csv(f"tune_results/{file_name}_all.csv")
    for param in params:
        value = df_param.iloc[0][param]
        df_all = df_all.loc[df_all[param] == value]

    min_loss = df_all["loss"].min()
    best_seed = df_all.loc[df_all["loss"] == min_loss].iloc[0]["trial_num"]

    return df_param[params], best_seed

if __name__ == '__main__':
    params = [
            "lr",
            "batch_size",
            "epoch",
            "wxh-stride"
        ]

    params, best_seed = get_params("kalman/alexnet", params)

    print("params", params)
    print("best_seed", best_seed)


class Solution:
    def rangeBitwiseAnd(self, m: int, n: int) -> int:
        '''
        Now consider a range

        [m = 0bxyz0acd, n=0bxyz1rst]
        here xyzpacdrst all are digits in base 2.

        We can find two numbers that are special in the range [m, n]

        (1) m' = 0bxyz0111
        (2) n' = 0bxyz1000
        The bitwise AND of all the numbers in range [m, n] is just the bitwise AND of the two special number

        rangeBitwiseAnd(m, n) = m' & n' = 0bxyz0000
        This tells us, the bitwise and of the range is keeping the common bits of m and n from left to right
        until the first bit that they are different, padding zeros for the rest.
        '''
        i = 0
        while m != n:
            m >>= 1
            n >>= 1
            i += 1
        return n << i


#!/usr/bin/env python3.6

#
# Imports for the GUI handling
#
# All global values are declared in the config file.
#
import config as cfg

# noinspection PyCompatibility
from tkinter import *
from PIL import ImageTk, Image

from random import randint

import threading
import os

from dictionary import Dictionary as dict

TIME = [
    5,
    10,
    15,
    20
]

IMAGES = [
    'Colours',
    'Basic shapes',
    'Images'
]

class DisplayTrigger(object):

    NEUTRAL = -1

    def __init__(self):

        # ========================
        # Create window instance
        #
        self.win = Toplevel()
        self.win.title(dict.get_string('shapes'))
        self.win.minsize(width=1000, height=500)
        self.pane = Canvas(self.win, width=1000, height=500, borderwidth="4")
        self.pane.pack()

        self.neutralImagedir = 'Images/Neutral/'
        self.imageDirectory = 'Images/Fruits/'

        self.images = self.selfiles(3)

        self.win.update()

        self.neutral = False
        self.counter = 1
        self.displaythread = self.ticker()

        self.triggerValue = DisplayTrigger.NEUTRAL

        self.win.update()

    def ticker(self):
        return threading.Timer(2.0, self.tickit)

    def tickit(self):
        # We display a neutral image between the triggers.
        #
        if self.neutral:
            self.displayImage(self.neutralImagedir + "0.jpg")
            self.neutral = False
            self.triggerValue = DisplayTrigger.NEUTRAL
        else:
            selected = randint(0,self.images.__len__() - 1)
            self.displayImage(self.imageDirectory + self.images[selected])
            self.neutral = True
            self.triggerValue = selected

        print(self.counter)
        print(self.triggerValue)
        self.counter += 1

    def displayImage(self, filepath):
        if os.path.exists(filepath):
            print(filepath)
            self.im = ImageTk.PhotoImage(Image.open(filepath))
            self.pane.create_image((500, 250), image=self.im)
            self.pane.update()
        else:
            print(filepath + " does not exit")

    # Returns a list with a given number of image files in
    # the current image directory.
    #
    def selfiles(self, number_of):
        temp = os.listdir(self.imageDirectory)
        result = list()
        for i in range(number_of):
            selected = randint(0,temp.__len__() - 1)
            t1 = temp[selected:selected + 1]
            result += t1
            temp = temp[:selected] + temp[selected+1:]

        return result

    def connect(self):
        return self.triggerValue

# a = Displaytrigger()
# a.displaythread.start()


from abc import abstractmethod
from dataclasses import dataclass
from typing import List, Optional

from omegaconf import Container

from hydra.core.object_type import ObjectType
from hydra.plugins.plugin import Plugin

@dataclass
class ConfigResult:
    provider: str
    path: str
    config: Container
    is_schema_source: bool = False

class ConfigLoadError(IOError):
    pass

class ConfigSource(Plugin):
    provider: str
    path: str

    def __init__(self, provider: str, path: str) -> None:
        if not path.startswith(self.scheme()):
            raise ValueError("Invalid path")
        self.provider = provider
        self.path = path[len(self.scheme() + "://") :]

    @staticmethod
    @abstractmethod
    def scheme() -> str:
        """
        :return: the scheme for this config source, for example file:// or pkg://
        """
        ...

    @abstractmethod
    def load_config(self, config_path: str) -> ConfigResult:
        ...

    # subclasses may override to improve performance
    def exists(self, config_path: str) -> bool:
        return self.is_group(config_path) or self.is_config(config_path)

    @abstractmethod
    def is_group(self, config_path: str) -> bool:
        ...

    @abstractmethod
    def is_config(self, config_path: str) -> bool:
        ...

    def list(self, config_path: str, results_filter: Optional[ObjectType]) -> List[str]:
        """
        List items under the specified config path
        :param config_path: config path to list items in, examples: "", "foo", "foo/bar"
        :param results_filter: None for all, GROUP for groups only and CONFIG for configs only
        :return: a list of config or group identifiers (sorted and unique)
        """
        ...

    def __str__(self) -> str:
        return repr(self)

    def __repr__(self) -> str:
        return f"provider={self.provider}, path={self.scheme()}://{self.path}"

    def _list_add_result(
        self,
        files: List[str],
        file_path: str,
        file_name: str,
        results_filter: Optional[ObjectType],
    ) -> None:
        filtered = ["__pycache__", "__init__.py"]
        is_group = self.is_group(file_path)
        is_config = self.is_config(file_path)
        if (
            is_group
            and (results_filter is None or results_filter == ObjectType.GROUP)
            and file_name not in filtered
        ):
            files.append(file_name)
        if (
            is_config
            and file_name not in filtered
            and (results_filter is None or results_filter == ObjectType.CONFIG)
        ):
            # strip extension
            last_dot = file_name.rfind(".")
            if last_dot != -1:
                file_name = file_name[0:last_dot]

            files.append(file_name)

    def full_path(self) -> str:
        return f"{self.scheme()}://{self.path}"

    @staticmethod
    def _normalize_file_name(filename: str) -> str:
        if not any(filename.endswith(ext) for ext in [".yaml", ".yml"]):
            filename += ".yaml"
        return filename


try:
    import cPickle as thepickle
except ImportError:
    import _pickle as thepickle

import gzip
import numpy as np
import glob
from keras.callbacks import ModelCheckpoint, EarlyStopping
#from utils import load_data, svm_classify
from sklearn import datasets, svm, preprocessing
from sklearn.pipeline import make_pipeline, Pipeline
#from linear_cca import linear_cca
from models import create_model
from sklearn.model_selection import *
from load_data import load_noisy_mnist_data

def run_svc_pipeline_doubleCV(X, y, dev_split=5, C_=0.015, n_splits_=10, param_search=True, n_jobs_=18):
    # use different splits with different random states for CV-param search
    svc = svm.SVC(kernel='linear', C = C_)
    #svc = svm.LinearSVC(C = C_)

    pipeline_estimators = [('scale', preprocessing.StandardScaler()), ('svm',
                                                                       svc) ]
    svc_pipeline = Pipeline(pipeline_estimators)

    if param_search:
        C_search = sorted( list(np.logspace(-5,0,10)) + [0.1,5,10,20,50,100] )
        param_grid = dict( scale=[None], svm__C=C_search )

        sk_folds = StratifiedKFold(n_splits=dev_split, shuffle=False,
                                   random_state=1964)
        grid_search = GridSearchCV(svc_pipeline, param_grid=param_grid,
                                   n_jobs=n_jobs_, cv=sk_folds.split(X,y),
                                   verbose=False)
        grid_search.fit(X, y)
        # find the best C value
        which_C = np.argmax(grid_search.cv_results_['mean_test_score'])
        best_C = C_search[which_C]
    else:
        best_C = C_

    svc_pipeline.named_steps['svm'].C = best_C
    #print('estimated the best C for svm to be', best_C)
    sk_folds = StratifiedKFold(n_splits=n_splits_, shuffle=False, random_state=320)
    all_scores = []
    all_y_test = []
    all_pred = []
    for train_index, test_index in sk_folds.split(X, y):
#        print 'run -',
        X_train, X_test = X[train_index], X[test_index]
        y_train, y_test = y[train_index], y[test_index]

        svc_pipeline.fit(X_train, y_train)
        y_pred = svc_pipeline.predict(X_test)
        score = svc_pipeline.score(X_test, y_test)
 #       print score
        all_y_test.append(y_test)
        all_pred.append(y_pred)
        all_scores.append(score)
    return all_y_test, all_pred, all_scores

def train_model(model, data_list, epoch_num, batch_size, feature_dim):
    """
    trains the model
    # Arguments
        .... inputs?
        epoch_num: number of epochs to train the model
        batch_size: the size of batches
    # Returns
        the trained model
    """

    # Unpacking the data
    # the data_list is arranged thus:
    # [[(train_x, train_y), (val_x, val_y), (test_x, test_y) ]_(1), {}_(2),...]
    train_x_list = [i[0][0] for i in data_list]
    val_x_list = [i[1][0] for i in data_list]
    test_x_list = [i[2][0] for i in data_list]

    # for later
    test_y_list = [i[2][1] for i in data_list]

    # it is done to return the best model based on the validation loss
    checkpointer = ModelCheckpoint(filepath="weights_%d_dim.{epoch:02d}-{val_loss:.4f}.hdf5" % (feature_dim),
                                        verbose=1, save_best_only=True, save_weights_only=True)
    early_stopping = EarlyStopping(min_delta = 1e-4, patience = 5)

    # used dummy Y because labels are not used in the loss function
    model.fit(train_x_list, np.zeros(len(train_x_list[0])),
              batch_size=batch_size, epochs=epoch_num, shuffle=True,
              validation_data=(val_x_list, np.zeros(len(val_x_list[0]))),
              callbacks=[checkpointer])

    #model_names_ = glob.glob('weights*5')
    #model.load_weights(model_names_[-1])

    results = model.evaluate(test_x_list, np.zeros(len(test_x_list[0])), batch_size=batch_size, verbose=1)

    print('loss on test data: ', results)

    results = model.evaluate(val_x_list, np.zeros(len(val_x_list[0])), batch_size=batch_size, verbose=1)
    print('loss on validation data: ', results)
    return model

def test_model(model, data_list, apply_mcca=False):
    """produce the new features by using the trained model
        outdim_size: dimension of new features
        apply_linear_cca: if to apply linear CCA on the new features
    # Returns
        new features packed like
    """

    # the data_list is arranged thus:
    # [[(train_x, train_y), (val_x, val_y), (test_x, test_y) ]_(1), {}_(2),...]
    train_x_list = [i[0][0] for i in data_list]
    val_x_list = [i[1][0] for i in data_list]
    test_x_list = [i[2][0] for i in data_list]

    # for later
    train_y = [i[0][1] for i in data_list][0] # since all three modalities have same labels
    val_y = [i[1][1] for i in data_list][0]
    test_y = [i[2][1] for i in data_list][0]
    # producing the new features
    train_embeddings = model.predict(train_x_list)
    val_embeddings = model.predict(val_x_list)
    test_embeddings = model.predict(test_x_list)

    return [(train_embeddings, train_y), (val_embeddings,val_y), (test_embeddings, test_y)]

if __name__ == '__main__':
############
# Parameters Section

# the path to save the final learned features
    save_to = './mcca_noisy_mnist_features.gz'

# number of modalities/datasets = n_mod
    n_mod = 3

# size of the input for view 1 and view 2
    input_shapes = [784, 784, 784]

# the size of the new space learned by the model (number of the new features)
    outdim_size = 50 # has to be same for all modalities - (TODO) change later

# layer size list to create a simple FCN
    layer_size_list = [[1024, outdim_size]] * n_mod

# the parameters for training the network
    learning_rate = 1e-3
    epoch_num = 100
    batch_size = 400

# the regularization parameter of the network
# seems necessary to avoid the gradient exploding especially when non-saturating activations are used
    reg_par = 1e-5

# specifies if all the singular values should get used to calculate the correlation or just the top outdim_size ones
# if one option does not work for a network or dataset, try the other one
    use_all_singular_values = False

# if a linear CCA should get applied on the learned features extracted from the networks
# it does not affect the performance on noisy MNIST significantly
    apply_linear_cca = False

# end of parameters section
############

# the load_data function loads noisy mnist data as a list of train,val,test triples
    data_list = load_noisy_mnist_data()

# Building, training, and producing the new features by DCCA
    model = create_model(layer_size_list, input_shapes,
                            act_='linear', learning_rate=learning_rate, n_modalities=n_mod)
    model.summary()
    model = train_model(model, data_list, epoch_num, batch_size, outdim_size)
    model.save('saved_model_sigmoid_at_last_layer.h5')

    data_embeddings = test_model(model, data_list)
# just test on the test set for now to assess the viability!
    pred_on_test = run_svc_pipeline_doubleCV(data_embeddings[2][0], data_embeddings[2][-1])
    print(pred_on_test[-1])
    #np.savez('saved_embeddings_sigmoid_at_last_layer_relu_model', train=data_embeddings[0], val=data_embeddings[1], test=data_embeddings[2])


#!/usr/bin/env python

import os
from subprocess import check_call
import shutil
import datetime
import urllib.parse

os.mkdir("tmp")
post_dirs = os.listdir("posts")

posts = {}
short_names = {}

with open("templates/post-top0.html") as f:
    post_top0 = f.read()
with open("templates/post-top.html") as f:
    post_top = f.read()
with open("templates/post-bottom.html") as f:
    post_bottom = f.read()

for post_dir in post_dirs:

    if "no_publish" in os.listdir("posts/%s" % post_dir):
        continue

    post_fields = post_dir.split("_")

    year = int(post_fields[0])
    month = int(post_fields[1])
    day = int(post_fields[2])
    date = datetime.datetime(year, month, day)

    post_name = "_".join(post_fields[3:])
    title = post_name.replace("_", " ")
    title = title[0].upper() + title[1:]
    posts[date] = post_name

    short_name = "_".join(post_name.split("_")[:2])
    short_name0 = short_name
    i = 0
    while short_name0 in short_names.values():
        short_name0 = short_name + "_%d" % i
        i += 1
    short_names[date] = short_name0

    if os.path.exists("../site/blog-posts/%s.html" % short_name0) and os.path.getmtime("posts/%s/%s.ipynb" % (post_dir, post_name)) < os.path.getmtime("../site/blog-posts/%s.html" % short_name0):
        continue

    command = "jupyter nbconvert --to html --template basic posts/%s/%s.ipynb" % (post_dir, post_name)
    check_call(command.split(" "))
    shutil.move("posts/%s/%s.html" % (post_dir, post_name), "tmp/%s.html" % short_name0)

    content = post_top0
    content += title
    content += post_top
    content += "
%s
\n" % title
    date_str = date.strftime("%d %B %Y").lstrip("0")
    content += '
Tweet '
    content += "%s
\n" % date_str
    content += '
\n'
    if "no_github_link" not in os.listdir("posts/%s" % post_dir):
        content += '(This blog post was written as a Jupyter notebook. The .ipynb file of this blog post and associated files can be found here.)

\n' % urllib.parse.quote(post_dir)

    with open("tmp/%s.html" % short_name0) as f:
        post_content = f.read()
        content += post_content.replace('src="./img/', 'src="../blog-images/%s/' % post_name)

    content += """

Tweet

Please enable JavaScript to view the comments powered by Disqus.

""" % (short_name0, short_name0)

    content += post_bottom

    with open("../site/blog-posts/%s.html" % short_name0, "w") as f:
        f.write(content)
    shutil.copytree("posts/%s/img" % post_dir, "../site/blog-images/%s" % post_name)

shutil.rmtree("tmp")

with open("templates/list-top.html") as f:
    list_top = f.read()
with open("templates/list-bottom.html") as f:
    list_bottom = f.read()
content = list_top

sorted_keys = sorted(posts.keys(), reverse=True)
month_year_str = ""
for date in sorted_keys:
    new_month_year_str = "\n%s
\n" % date.strftime("%B %Y")
    if new_month_year_str != month_year_str:
        content += "
"
        content += new_month_year_str
        month_year_str = new_month_year_str
    post_name = posts[date]
    short_name = short_names[date]
    title = post_name.replace("_", " ")
    title = title[0].upper() + title[1:]
    date_str = date.strftime("%d/%m/%y")
    content += '%s %s\n' % (date_str, short_name, title)
    #content += '  (.ipynb)\n' % post_name
    #content += ' (interactive)\n' % post_name
    content += "
"

if len(sorted_keys) == 0:
    content += "
There are currently no blog posts here.
\n"

content += list_bottom

with open("../site/blog-post-pages/blog0.html", "w") as f:
    f.write(content)


"""
CS3A, Assignment08, String reversal, etc
Mingming Gu
This assignment will use three techniques -- iteration, stack, and recursion -- to solve a problem, reversing a string.
"""

class Reverser:

    @staticmethod
    def reverse_str_iter(string):
        """
        This method uses iteration with a for/while loop to reverse the string. If must iterate the string starting at
        the first character forward.

        :param string: a string
        :return: a reversed string
        """
        new_string = ""
        for i in range(len(string)):
            new_string += string[len(string) - i - 1]
        return new_string

    @staticmethod
    def reverse_str_stack(string):
        """
        This method uses a stack to reverse the string. Will use list as a stack, list.append() and list.pop().

        :param string: a string
        :return: a reversed string
        """
        stack = []
        new_stack = []
        new_string = ""
        for i in range(len(string)):
            stack.append(string[i])
        for i in range(len(stack)):
            new_stack.append(stack.pop())
        for i in range(len(new_stack)):
            new_string += new_stack[i]
        return new_string

    @staticmethod
    def reverse_str_rec(string):
        """
        This method uses recursion to reverse the string.
        It must have a base case. It must call itself. It must utilize the result returned by the recursive call.
        :param string: a string
        :return: a reversed string

        ###  Comment: By testing around, the length of thg longest string it can handle is 997. ###
        """
        if len(string) == 0:
            return string
        return Reverser.reverse_str_rec(string[1:]) + string[0]

    @staticmethod
    def reverse_str_builtin(string):
        """
        This method uses Python's builtin way to reverse the string, with one line function.
        :param string: a string
        :return: a reversed string
        """
        return "".join(reversed(string))

def remove_char(string, char):
    """
    This function should return a new str that's the same as the parameter string with all occurrences of char removed.
    :param string: a string
    :param char: a character as a string
    :return: a new string after removal
    """
    if len(string) == 0:
        return string
    if string[0] == char:
        return remove_char(string[1:], char)
    else:
        return string[0] + remove_char(string[1:], char)

"""
Reverser tests
"""

def test():
    """
    A global function that tests all 4 methods above.
    :return: a list with 4 reverted strings

    Comment: By running performance tests, reverse_str_builtin() is the fastest method, reverse_str_rec() is the
    slowest method. Intuitively, the built-in function can finish reversion in one step by running the function,
    whereas recursion implements the function n times, where n is the length of the string, so the latter takes longer.
    """
    long_string = "l" + "o" * 993 + "ng"
    test_lst = ["", "x", "Reverse the string in four methods.", long_string]
    reverse_ten = Reverser.reverse_str_iter("Reverse the string in four methods.")
    reverse_long = Reverser.reverse_str_rec(long_string)
    expect_result = ["", "x", reverse_ten, reverse_long]

    result_iter = []
    result_stack = []
    result_rec = []
    result_builtin = []

    for ts in test_lst:
        result_iter.append(Reverser.reverse_str_iter(ts))
        result_stack.append(Reverser.reverse_str_stack(ts))
        result_rec.append(Reverser.reverse_str_rec(ts))
        result_builtin.append(Reverser.reverse_str_builtin(ts))
    print(
        "Print out four lists by using four different methods, stating if each result is correct(True) or not(False).")
    print(
        f"The result of iteration method is {result_iter}, and it is {result_iter[0] == expect_result[0]} as expected.")
    print(f"The result of stack method is {result_stack}, and it is {result_stack[1] == expect_result[1]} as expected.")
    print(f"The result of recursion method is {result_rec}, and it is {result_rec[2] == expect_result[2]} as expected.")
    print(f"The result of builtin method is {result_builtin}, and it is {result_builtin[3] == expect_result[3]} as "
          f"expected.")

    """
    Reverser performance testing
    """
    import time

    start = time.perf_counter()
    for ts in test_lst:
        result_iter.append(Reverser.reverse_str_iter(ts))
    duration_iter = time.perf_counter() - start
    print(f"Using iteration method takes {duration_iter:.5f}")

    start = time.perf_counter()
    for ts in test_lst:
        result_stack.append(Reverser.reverse_str_stack(ts))
    duration_stack = time.perf_counter() - start
    print(f"Using stack method takes {duration_stack:.5f}")

    start = time.perf_counter()
    for ts in test_lst:
        result_rec.append(Reverser.reverse_str_rec(ts))
    duration_rec = time.perf_counter() - start
    print(f"Using recursion method takes {duration_rec:.5f}")

    start = time.perf_counter()
    for ts in test_lst:
        result_builtin.append(Reverser.reverse_str_builtin(ts))
    duration_builtin = time.perf_counter() - start
    print(f"Using builtin method takes {duration_builtin:.5f}")

"""
remove_char() testing
"""

def remove_char_test(string, char):
    """
    This function tests remove_char() function.
    :return: Pass or Not Pass
    """
    result = remove_char(string, char)
    if not string:
        if result == string:
            print("Pass")
        else:
            print("Not Pass")
    else:
        if (s != char for s in result):
            print("Pass")
        else:
            print("Not Pass")

if __name__ == '__main__':
    test()
    remove_char_test("good", "o")
    remove_char_test("!Hello!", "!")  # when char is a symbol.
    remove_char_test("", "a")  # when string is empty.
    remove_char_test("Here I am.", " ")  # when char is a space.
    remove_char_test("I buy a china in China", "C")  # when there are both small case and large case of a same char.


'''Retorno de valores das funcoes (Return)'''

# def soma(x, y):
#     print('Olha')
#     print('so')
#     print('que legal')
#     return x + y            # somente funciona dentro da funcao.
#                             # Return tem a funcao de realizar o
# # variavel = soma(1,2)
# # variavel = int('1')

# soma1 = soma(2, 2)
# soma2 = soma(3, 3)
# print(soma1 + soma2)

def soma(x, y):
    if x > 10:
        return [10, 20]            # somente funciona dentro da funcao.
    return x + y           # Return tem a funcao de realizar o
# variavel = soma(1,2)
# variavel = int('1')

soma1 = soma(2, 2)
soma2 = soma(3, 3)
print(soma1)
print(soma2)
print(soma(11, 55))


import numpy as np

from utils.dataset import BaseDataSet, DataSet

def test_BaseDataSet():
    size = 3 * 10
    input_set = [
        [i, i, i, i] for i in range(1, size+1)
    ]
    input_labels = [
        str(i % 3) for i in range(1, size + 1)
    ]
    ds = BaseDataSet(input_set, input_labels, dim_in=4)
    assert ds.size == size
    assert ds.dim_in == 4
    assert ds.dim_out == 3
    assert ds.labels == [str(i) for i in range(3)]
    assert [list(map(float, output)) for output in ds.output_set] == [
        [
            1. if int(label) == 0 else 0.,
            1. if int(label) == 1 else 0.,
            1. if int(label) == 2 else 0.,
        ]
        for label in input_labels
    ]

    ds1, ds2 = ds.split(0.8)
    assert ds1.size == 8 * size // 10
    assert ds2.size == 2 * size // 10

    # Scaling

    input_set = [
        [0, 100],
        [-1, 125],
        [4, 150],
    ]
    input_labels = [
        'a', 'a', 'b'
    ]
    ds = BaseDataSet(input_set, input_labels, dim_in=2)
    stats = ds.stats()
    assert (stats['mean'] == np.array([1, 125])).all()
    np.testing.assert_array_almost_equal(
        stats['std_dev'], [2.1602469, 20.41241452]
    )

    ds.std_scale()
    stats = ds.stats()
    assert (stats['mean'] == np.array([0, 0])).all()
    np.testing.assert_array_almost_equal(
        stats['std_dev'], [1, 1]
    )


def matrixElementsSum(matrix):
    # loop over each array simlutaneously
    # add numbers not underneath a zero
    # as soon as I see a zero i rule out the rest everything underneath it
    matrixSum = 0
    l_to_r = 0
    t_to_b = 0
    while l_to_r < len(matrix[0]):
        while t_to_b < len(matrix):
            print(f"top to bottom: {t_to_b} " , f"left to right: {l_to_r}" , f"element: {matrix[t_to_b][l_to_r]}")
            if matrix[t_to_b][l_to_r] == 0:
                t_to_b = 0
                break
            matrixSum += matrix[t_to_b][l_to_r]
            t_to_b += 1
        if l_to_r < len(matrix[0]):
            t_to_b = 0
        l_to_r += 1

    return matrixSum

matrix=[[1,1,1,0],
        [0,5,0,1],
        [2,1,3,10]]
print(matrixElementsSum(matrix)) # => 9