from __future__ import absolute_import, division, print_function

# Copyright 2010 University of California
# All rights reserved

# This is an approximate mimic of the NSSegmentedControl in Cocoa.  The
# Apple control has many more styles than this, but the basic functionality
# is the same, with three selection modes (any, one, or none).  Either
# labels, bitmaps, or both are supported.

# TODO:
#   - Windows bugs
#   - additional styles?

import wx
from six.moves import range

SEGBTN_ROUNDED_CORNERS = 1
SEGBTN_VERTICAL = 2
SEGBTN_HORIZONTAL = 4
SEGBTN_INVERT_BITMAP = 8
SEGBTN_HIGHLIGHT = 16
SEGBTN_RADIO_ALLOW_NONE = 32

SEGBTN_DEFAULT_STYLE = SEGBTN_HORIZONTAL|SEGBTN_ROUNDED_CORNERS

if wx.Platform == '__WXMAC__' :
  _DEFAULT_PADDING = 8
elif wx.Platform == '__WXGTK__' :
  _DEFAULT_PADDING = 6
else :
  _DEFAULT_PADDING = 6

class SegmentedControl(wx.Control):
  def __init__(self,
                parent,
                id=wx.ID_ANY,
                pos=wx.DefaultPosition,
                size=wx.DefaultSize,
                style=SEGBTN_DEFAULT_STYLE,
                name=wx.ButtonNameStr,
                border=0,
                pad=_DEFAULT_PADDING):
    wx.Control.__init__(self, parent, id, pos=pos, size=size,
      style=wx.NO_BORDER,
      name=name)
    self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)
    self.InheritAttributes()
    self.segments = []
    self.values = [] # for radio and toggle versions
    self._clicked_segment = None
    self._padding = _DEFAULT_PADDING
    self._border = border
    self._style = style
    self._border_color = (0, 0, 0)
    if wx.Platform == '__WXGTK__' :
      self.SetFont(wx.Font(12, wx.FONTFAMILY_DEFAULT, wx.NORMAL, wx.NORMAL))

    # Event Handlers
    self.Bind(wx.EVT_PAINT, lambda evt: self.__DrawButtons())
    self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnErase)
    #self.Bind(wx.EVT_SET_FOCUS, self.OnFocus)
    #self.Bind(wx.EVT_KILL_FOCUS, self.OnKillFocus)
    self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
    self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp)
    #self.Bind(wx.EVT_LEFT_DCLICK, lambda evt: self.ToggleState())
    self.Bind(wx.EVT_ENTER_WINDOW, self.OnEnter)
    self.Bind(wx.EVT_LEAVE_WINDOW, self.OnLeave)
    self.Bind(wx.EVT_MOTION, self.OnMotion)

  def AddSegment(self, label="", bitmap=None):
    if label == "" and bitmap is None :
      raise RuntimeError("Must specify either a label or a bitmap or both "+
        "for SegmentControl.AddSegment().")
    self.segments.append((label, bitmap))
    self.values.append(False)

  def InsertSegment(self, index, label="", bitmap=None):
    if label == "" and bitmap is None :
      raise RuntimeError("Must specify either a label or a bitmap or both "+
        "for SegmentControl.InsertSegment().")
    self.segments.insert(index, (label, bitmap))
    self.values.append(True)

  def Realize(self):
    self.SetSize(self.DoGetBestSize())

  def SetBorderColor(self, color):
    self._border_color = color

  def DoGetBestSize(self):
    dc = wx.ClientDC(self)
    dc.SetFont(self.GetFont())
    n_seg = len(self.segments)
    buf = 1
    if n_seg == 0 :
      (w, h) = dc.GetTextExtent("XXX")
      w += self._padding * 2
      h += self._padding * 2
    else :
      txt_w, txt_h = self.__OverallSegmentContentSize(dc)
      seg_w = txt_w + (2 * self._padding)
      seg_h = txt_h + (2 * self._padding)
      if self._style & SEGBTN_VERTICAL :
        w = seg_w + 2
        h = 1 + ((seg_h + buf) * n_seg)
      else :
        w = 1 + ((seg_w + buf) * n_seg)
        h = seg_h + 2
    w += (self._border * 2)
    h += (self._border * 2)
    return (w, h)

  def __OverallSegmentContentSize(self, dc):
    max_h = 0
    max_w = 0
    for (label, bitmap) in self.segments :
      (text_w, text_h) = (0, 0)
      (bmp_w, bmp_h) = (0, 0)
      if label != "" :
        (text_w, text_h) = dc.GetTextExtent(label)
      if bitmap is not None :
        (bmp_w, bmp_h) = bitmap.GetSize()
      if label != "" and bitmap is not None :
        seg_w = max(text_w, bmp_w)
        seg_h = text_h + bmp_h + 2
      elif label != "" :
        (seg_w, seg_h) = (text_w, text_h)
      else :
        (seg_w, seg_h) = (bmp_w, bmp_h)
      if seg_h > max_h :
        max_h = seg_h
      if seg_w > max_w :
        max_w = seg_w
    return (max_w, max_h)

  def __DrawButtons(self):
    dc = wx.AutoBufferedPaintDCFactory(self)
    if wx.Platform == '__WXMSW__' :
      dc.SetBackground(wx.Brush(self.GetParent().GetBackgroundColour()))
      dc.Clear()
    gc = wx.GCDC(dc)
    gc.SetBackgroundMode(wx.TRANSPARENT)
    gc.SetFont(self.GetFont())

    (w, h) = self.GetSize() #DoGetBestSize()
    w -= (self._border * 2)
    h -= (self._border * 2)
    n_seg = len(self.segments)
    rgc = gc.GetGraphicsContext()
    if self._style & SEGBTN_VERTICAL :
      # XXX a smaller gradient looks better for vertical controls
      gradient_brush = rgc.CreateLinearGradientBrush(0, 0, w, 0, (240,240,240),
        (200,200,200))
    else :
      gradient_brush = rgc.CreateLinearGradientBrush(0, 0, 0, h, (250,250,250),
        (185,185,185))
    rgc.SetBrush(gradient_brush)
    border_pen = wx.Pen(self._border_color, 1)
    # XXX wx.GCDC on GTK draws thin black lines as thicker dark grey lines
    # due to antialiasing.
    if wx.Platform == '__WXGTK__' :
      gc.SetPen(wx.TRANSPARENT_PEN)
      dc.SetPen(border_pen)
      dc.SetBrush(wx.TRANSPARENT_BRUSH)
    else :
      gc.SetPen(border_pen)
    if self._style & SEGBTN_ROUNDED_CORNERS :
      gc.DrawRoundedRectangle(self._border, self._border, w, h, 3)
      if wx.Platform == '__WXGTK__' :
        dc.DrawRoundedRectangle(self._border, self._border, w, h, 3)
    else :
      gc.DrawRectangle(self._border, self._border, w, h)
      if wx.Platform == '__WXGTK__' :
        dc.DrawRectangle(self._border, self._border, w, h)
    gc.SetPen(wx.TRANSPARENT_PEN)
    gc.SetBrush(wx.TRANSPARENT_BRUSH)
    if n_seg == 0 :
      gc.SetTextForeground('red')
      gc.DrawText("XXX", self._padding, self._padding)
    else :
      gc.SetTextForeground('black')
      gc.SetPen(wx.Pen('black', 1)) #BLACK_PEN)
      buf = 1
      (txt_w, txt_h) = self.__OverallSegmentContentSize(gc)
      if self._style & SEGBTN_VERTICAL :
        seg_w = w - 2
        seg_h = ((h - 1) / n_seg) - buf
      else :
        seg_w = ((w - 1) / n_seg) - buf
        seg_h = h -  2
      current_x = 1 + self._border
      current_y = 1 + self._border
      for i, (label, bitmap) in enumerate(self.segments):
        gc.SetPen(border_pen)
        dc.SetPen(border_pen)
        (txt_x, txt_y) = (self._padding + 1, self._padding + 1)
        if self._style & SEGBTN_VERTICAL :
          if i > 0 :
            dc.DrawLine(int(self._border), int(current_y), int(w + self._border - 1),
              int(current_y))
            current_y += 1
          txt_y += current_y
          txt_x += self._border
        else :
          if i > 0 :
            dc.DrawLine(int(current_x), int(self._border + 1), int(current_x),
              int(h + self._border - 1))
            current_x += 1
          txt_x += current_x
          txt_y += self._border
        if ((self.HasCapture() and i == self._clicked_segment) or
             self.values[i] == True):
          xo = current_x + (seg_w / 2)
          yo = current_y + (seg_h / 2)
          radius  = max(seg_w, seg_h) - 1
          brush = rgc.CreateRadialGradientBrush(xo, yo, xo, yo, radius,
            (220,220,220), (120,120,120))
          rgc.SetBrush(brush)
          gc.SetPen(wx.TRANSPARENT_PEN)
          if self._style & SEGBTN_ROUNDED_CORNERS and (i == 0 or i == n_seg):
            gc.DrawRoundedRectangle(int(current_x), int(current_y), int(seg_w), int(seg_h), 1)
          else :
            gc.DrawRectangle(int(current_x), int(current_y), int(seg_w), int(seg_h))
          #gc.DrawRectangle(current_x, current_y, total_w, total_h)
        rgc.SetBrush(gradient_brush)
        gc.SetBrush(wx.TRANSPARENT_BRUSH)
        gc.SetPen(wx.BLACK_PEN)
        label_w, label_h = gc.GetTextExtent(label)
        if bitmap is not None :
          (img_w, img_h) = bitmap.GetSize()
          img_x, img_y = txt_x, txt_y
          if label != "" :
            if wx.Platform == '__WXGTK__' :
              img_y -= 4
            extra_h_space = seg_w - img_w - (self._padding * 2)
            extra_v_space = seg_w - img_h - label_h - (self._padding * 2)
          else :
            extra_h_space = seg_w - img_w - (self._padding * 2)
            extra_v_space = seg_h - img_h - (self._padding * 2)
          if extra_h_space > 0 :
            img_x += extra_h_space / 2
          if extra_v_space > 0 :
            img_y += extra_v_space / 2
          gc.DrawBitmap(bitmap, img_x, img_y, bitmap.GetMask() != None)
          txt_y += img_h
          if (wx.Platform == '__WXMSW__'):
            txt_y -= 2
        if label != "" :
          #print seg_w, label_w
          extra_w = seg_w - label_w - (self._padding*2)
          if extra_w > 0 :
            txt_x += extra_w / 2
          extra_h = seg_h - label_h - (self._padding*2)
          if extra_h > 0 :
            txt_y += extra_h / 2
          gc.DrawText(label, int(txt_x), int(txt_y))
        if self._style & SEGBTN_VERTICAL :
          current_y += seg_h
        else :
          current_x += seg_w

  def HandleClick(self):
    pass

  def HitTest(self, event):
    x, y = event.GetPositionTuple()
    dc = wx.ClientDC(self)
    n_seg = len(self.segments)
    buf = 1
    (w, h) = self.DoGetBestSize()
    if self._style & SEGBTN_VERTICAL :
      seg_w = w - 2
      seg_h = ((h - 1) / n_seg) - buf
    else :
      seg_w = ((w - 1) / n_seg) - buf
      seg_h = h -  2
    if n_seg == 0 :
      return None
    elif (x < 1 or x > (w - 1)) or (y < 1 or y > (h-1)):
      return None
    elif self._style & SEGBTN_VERTICAL :
      current_y = 1
      for i in range(n_seg):
        max_y = current_y + seg_h
        if y > current_y and y < max_y :
          return i
        current_y = max_y
    else :
      current_x = 1
      for i in range(n_seg):
        max_x = current_x + seg_w -1
        if x >= current_x and x < max_x :
          return i
        current_x = max_x + 2
    return None

  def OnLeftDown(self, event):
    segment_id = self.HitTest(event)
    self._have_mouse = True
    self._clicked_segment = segment_id
    self.CaptureMouse()
    self.SetFocus()
    self.Refresh()

  def OnLeftUp(self, event):
    if self.HasCapture():
      self.ReleaseMouse()
    segment_id = self.HitTest(event)
    if segment_id is not None and segment_id == self._clicked_segment :
      self.HandleClick()
    self._clicked_segment = None
    self.Refresh()

  def OnEnter(self, event):
    if event.LeftDown():
      self.CaptureMouse()
      self.Refresh()

  def OnLeave(self, event):
    pass
    if self.HasCapture():
      self.ReleaseMouse()
      self.Refresh()
#      self._clicked_segment = None

  def OnMotion(self, event):
    return
    if not self.IsEnabled():
      return
    x,y = event.GetPositionTuple()
    w,h = self.GetClientSizeTuple()
    if (x<0 or y<0 or x>=w or y>=h) and self.HasCapture():
      #self._clicked_segment = None
      print(-3)
      self.ReleaseMouse()
      self.Refresh()
      return
    elif event.LeftDown():
      print(-2)
      self.CaptureMouse()
      self.Refresh()
      return
    event.Skip()

  def OnErase(self, event):
    pass

  def OnFocus(self, event):
    pass

  def OnKillFocus(self, event):
    pass

class SegmentedButtonControl(SegmentedControl):
  def HandleClick(self):
    bevt = wx.CommandEvent(wx.wxEVT_COMMAND_BUTTON_CLICKED, self.GetId())
    bevt.SetEventObject(self)
    bevt.SetString(self.GetLabel())
    bevt.SetClientData(self._clicked_segment)
    wx.PostEvent(self.GetParent(), bevt)
    self._clicked_segment = None

class SegmentedRadioControl(SegmentedControl):
  def HandleClick(self):
    index = self._clicked_segment
    assert index >= 0
    if self.values[index] == True and self._style & SEGBTN_RADIO_ALLOW_NONE :
      self.values[index] = False
    elif not self.values[index] :
      self.SetSelection(index)
    bevt = wx.CommandEvent(wx.wxEVT_COMMAND_RADIOBUTTON_SELECTED, self.GetId())
    bevt.SetEventObject(self)
    bevt.SetString(self.GetLabel())
    bevt.SetClientData(self.GetSelection())
    wx.PostEvent(self.GetParent(), bevt)
    self._clicked_segment = None

  def GetSelection(self):
    assert self.values.count(True) <= 1
    if True in self.values :
      return self.values.index(True)
    return -1

  def SetSelection(self, index):
    self.values = [False] * len(self.segments)
    self.values[index] = True

class SegmentedToggleControl(SegmentedControl):
  def HandleClick(self):
    index = self._clicked_segment
    assert index >= 0
    old_value = self.values[index]
    self.values[index] = not old_value
    bevt = wx.CommandEvent(wx.wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, self.GetId())
    bevt.SetEventObject(self)
    bevt.SetString(self.GetLabel())
    bevt.SetClientData(self._clicked_segment)
    wx.PostEvent(self.GetParent(), bevt)
    self._clicked_segment = None

  def GetValue(self, index):
    return self.values[index]

  def SetValue(self, index, value):
    self.values[index] = value

#-----------------------------------------------------------------------
if __name__ == "__main__" :
  def OnButton(evt):
    print("Button clicked: %d" % evt.GetClientData())
  def OnRadio(evt):
    print("Radio button selection: %d" % evt.GetClientData())
  def OnToggle(evt):
    index = evt.GetClientData()
    print("Toggle button clicked: %d, %s" % (index,
      evt.GetEventObject().GetValue(index)))
  try :
    from wxtbx import bitmaps
  except ImportError :
    bitmaps = None
  app = wx.App(0)
  frame = wx.Frame(None, -1, "Test frame")
  toolbar = frame.CreateToolBar()
  panel = wx.Panel(frame, -1, size=(640,480))
  sizer = wx.BoxSizer(wx.HORIZONTAL)
  panel.SetSizer(sizer)
  v_sizer = wx.BoxSizer(wx.VERTICAL)
  btn = SegmentedButtonControl(panel,
    style=SEGBTN_HORIZONTAL) #|SEGBTN_AUTOSIZE)
  btn.AddSegment("Prev")
  btn.AddSegment("Home")
  btn.AddSegment("Search")
  btn.AddSegment("Help")
  btn.AddSegment("Next")
  frame.Bind(wx.EVT_BUTTON, OnButton, btn)
  v_sizer.Add(wx.StaticText(panel, -1, "Standard buttons"), 0, wx.ALL, 5)
  v_sizer.Add(btn, 0, wx.ALL, 5)
  sizer.Add(v_sizer)
  if True :
    tbtn = SegmentedButtonControl(toolbar,
      style=SEGBTN_HORIZONTAL|SEGBTN_ROUNDED_CORNERS,
      border=4)
    tbtn.AddSegment("Prev")
    tbtn.AddSegment("Home")
    tbtn.AddSegment("Search")
    tbtn.AddSegment("Help")
    tbtn.AddSegment("Next")
    tbtn.Realize()
    (w,h) = tbtn.GetSize()
    toolbar.SetToolBitmapSize((h,h))
    frame.Bind(wx.EVT_BUTTON, OnButton, tbtn)
    toolbar.AddControl(tbtn)
    #toolbar.AddControl(wx.Button(toolbar, -1, "Hello"))
    btn2 = SegmentedRadioControl(panel)
    btn2.AddSegment("Rotate")
    btn2.AddSegment("Pan")
    btn2.AddSegment("Zoom")
    btn2.SetSelection(0)
    frame.Bind(wx.EVT_RADIOBUTTON, OnRadio, btn2)
    v_sizer.Add(wx.StaticText(panel, -1, "Radio buttons"), 0, wx.ALL, 5)
    v_sizer.Add(btn2, 0, wx.ALL, 5)
    btn3 = SegmentedToggleControl(panel)
    btn3.AddSegment("Maps")
    btn3.AddSegment("Models")
    btn3.AddSegment("Selection")
    btn3.Realize()
    frame.Bind(wx.EVT_TOGGLEBUTTON, OnToggle, btn3)
    v_sizer.Add(wx.StaticText(panel, -1, "Toggle buttons"), 0, wx.ALL, 5)
    v_sizer.Add(btn3, 0, wx.ALL, 5)
    if (bitmaps is not None) and (bitmaps.icon_lib is not None):
      bmp1 = bitmaps.fetch_icon_bitmap("actions", "1leftarrow", 16)
      bmp2 = bitmaps.fetch_icon_bitmap("actions", "gohome", 16)
      bmp3 = bitmaps.fetch_icon_bitmap("actions", "viewmag", 16)
      bmp4 = bitmaps.fetch_icon_bitmap("actions", "1rightarrow", 16)
      btn4 = SegmentedButtonControl(panel)
      btn4.AddSegment(bitmap=bmp1)
      btn4.AddSegment(bitmap=bmp2)
      btn4.AddSegment(bitmap=bmp3)
      btn4.AddSegment(bitmap=bmp4)
      v_sizer.Add(wx.StaticText(panel, -1, "Bitmap buttons"), 0, wx.ALL, 5)
      v_sizer.Add(btn4, 0, wx.ALL, 5)
      frame.Bind(wx.EVT_BUTTON, OnButton, btn4)
      btn5 = SegmentedButtonControl(panel,
        style=SEGBTN_ROUNDED_CORNERS)
      btn5.AddSegment(label="Back", bitmap=bmp1)
      btn5.AddSegment(label="Home", bitmap=bmp2)
      btn5.AddSegment(label="Search", bitmap=bmp3)
      btn5.AddSegment(label="Next", bitmap=bmp4)
      btn5.SetFont(wx.Font(9, wx.FONTFAMILY_DEFAULT, wx.NORMAL, wx.NORMAL))
      v_sizer.Add(wx.StaticText(panel, -1, "Bitmaps and text"), 0, wx.ALL, 5)
      v_sizer.Add(btn5, 0, wx.ALL, 5)
      frame.Bind(wx.EVT_BUTTON, OnButton, btn5)
    vbtn1 = SegmentedButtonControl(panel,
      style=SEGBTN_VERTICAL)
    vbtn1.AddSegment("Up")
    vbtn1.AddSegment("Home")
    vbtn1.AddSegment("Search")
    vbtn1.AddSegment("Down")
    frame.Bind(wx.EVT_BUTTON, OnButton, vbtn1)
    sizer.Add(vbtn1, 0, wx.ALL, 20)
    vbtn2 = SegmentedButtonControl(panel,
      style=SEGBTN_VERTICAL|SEGBTN_ROUNDED_CORNERS,
      border=8)
    vbtn2.AddSegment("Up")
    vbtn2.AddSegment("Home")
    vbtn2.AddSegment("Search")
    vbtn2.AddSegment("Down")
    frame.Bind(wx.EVT_BUTTON, OnButton, vbtn2)
    sizer.Add(vbtn2, 0, wx.ALL, 20)
  sizer.Layout()
  sizer.Fit(panel)
  frame.Fit()
  toolbar.Realize()
  frame.Show()
  app.MainLoop()


#!/usr/bin/env python
# coding=utf-8

import tkinter as tk

window = tk.Tk()
window.title('Radiobutton')
window.geometry('300x200')

var = tk.StringVar()
l = tk.Label(
    window,
    bg='yellow',
    width = 20,
    text = 'empty'
)
l.pack()

def print_selection():
    l.config(text='you have selected ' + var.get())

list_ = ['A', 'B', 'C', 'D']
for i in list_:
    r1 = tk.Radiobutton(
        window,
        bg = 'yellow',
        text = 'Option {}'.format(i),
        variable = var, value= i, # 当鼠标选中其中一个选项，把value的值A放到变量var中，然后赋值给variable
        command = print_selection,
    )
    r1.pack()

window.mainloop()


import frappe
from frappe_notification import (
    NotificationClientNotFound,
    InvalidRequest,
    get_active_notification_client)
from typing import Optional
from frappe_notification.utils.cursor_paginator import CursorPaginator, \
    CursorPaginatorExecutionArgs, CursorPaginatorSortBy, CursorPaginatorSortByField, \
    CursorPaginatorSortByDirection

class NotificationLogsFilters(frappe._dict):
    channel: Optional[str]
    channel_id: Optional[str]
    user_identifier: Optional[str]

class NotificationLogsSortByEnum(CursorPaginatorSortByField):
    CREATION = "outbox.creation"

class NotificationLogSortBy(CursorPaginatorSortBy):
    field: NotificationLogsSortByEnum

class GetNotificationLogsExecutionArgs(CursorPaginatorExecutionArgs):
    before: Optional[str]
    after: Optional[str]
    first: Optional[int]
    last: Optional[int]
    sort_by: Optional[NotificationLogSortBy]
    filters: NotificationLogsFilters

def get_notification_logs(args: GetNotificationLogsExecutionArgs):
    filters = args.pop('filters', None)

    # TODO: Find a better way to resolve these values..
    sort_by = args.pop("sort_by", None)
    if sort_by:
        sort_by = NotificationLogSortBy({
            "direction": CursorPaginatorSortByDirection[sort_by.get("direction")],
            "field": NotificationLogsSortByEnum[sort_by.get("field")]
        })
        args["sort_by"] = sort_by

    r = CursorPaginator(
        doctype="Notification Outbox",
        skip_process_filters=True,
        count_resolver=get_notification_logs_count_resolver,
        node_resolver=get_notification_logs_node_resolver,
        default_sorting_fields=["outbox.creation"],
        default_sorting_direction="desc",
        extra_args={"filters": filters}
    )
    return r.execute(args)

def get_notification_logs_count_resolver(paginator: CursorPaginator, filters):
    client = get_active_notification_client()
    if not client:
        raise NotificationClientNotFound()
    notification_filters = paginator.extra_args.get("filters") if paginator.extra_args else None
    conditions = get_notifications_logs_filters(NotificationLogsFilters(notification_filters or {}))

    return frappe.db.sql(f"""
    SELECT
        count(distinct(outbox.name))
    FROM
        `tabNotification Outbox` outbox
    JOIN `tabNotification Outbox Recipient Item` recipient_item
        ON recipient_item.parent = outbox.name AND recipient_item.parenttype = 'Notification Outbox'
    WHERE
        outbox.notification_client = %(client)s
        AND outbox.docstatus = 1
        {conditions}
        AND recipient_item.status = 'Success'
        """, {
        "client": client
    }, as_list=1, debug=0)[0][0]

def get_notification_logs_node_resolver(paginator: CursorPaginator, filters, fields, sorting_fields,
                                        sort_dir, limit):
    client = get_active_notification_client()
    if not client:
        raise NotificationClientNotFound()

    extra_sorting_fields = f", {', '.join(sorting_fields)}"
    order_by = ', '.join([f'{x} {sort_dir}' for x in sorting_fields])

    notification_filters = paginator.extra_args.get("filters") if paginator.extra_args else None
    conditions = get_notifications_logs_filters(NotificationLogsFilters(notification_filters or {}),
                                                filters)

    return frappe.db.sql(f"""
    SELECT
        outbox.name as outbox,
        recipient_item.name as outbox_recipient_row,
        outbox.subject,
        outbox.content,
        recipient_item.time_sent,
        recipient_item.user_identifier,
        recipient_item.channel,
        recipient_item.channel_id,
        recipient_item.seen
        {extra_sorting_fields}
    FROM
        `tabNotification Outbox` outbox
    JOIN `tabNotification Outbox Recipient Item` recipient_item
        ON recipient_item.parent = outbox.name AND recipient_item.parenttype = 'Notification Outbox'
    WHERE
        outbox.notification_client = %(client)s
        AND outbox.docstatus = 1
        {conditions}
        AND recipient_item.status = "Success"
    ORDER BY {order_by}
    LIMIT %(limit_page_length)s
    """, {
        "client": client,
        "limit_page_length": limit
    }, as_dict=1, debug=0)

def get_notifications_logs_filters(filters: NotificationLogsFilters, cursor_filters=None):
    channel = filters.channel
    channel_id = filters.channel_id
    user_identifier = filters.user_identifier

    if not ((channel and channel_id) or user_identifier):
        raise InvalidRequest(message=frappe._(
            "Please specify either (channel, channel_id) or user_identifier"
        ))

    conditions = []

    if cursor_filters:
        conditions.extend(cursor_filters)

    if channel:
        conditions.append(f"recipient_item.channel = '{channel}'")

    if channel_id:
        conditions.append(f"recipient_item.channel_id = '{channel_id}'")

    if user_identifier:
        conditions.append(f"recipient_item.user_identifier = '{user_identifier}'")

    return f' AND {" AND ".join(conditions)}' if len(conditions) else ""


from django.db import models
from django.contrib.postgres.fields import ArrayField
from django.core.exceptions import ValidationError

from users.models import CustomUser

MODEL_AUTHOR_NAMES = ['edit_suggestion_author', 'author', ]

class VotableMixin(models.Model):
    thumbs_up_array = ArrayField(models.IntegerField(), default=list)
    thumbs_down_array = ArrayField(models.IntegerField(), default=list)

    class ErrorMessages:
        ONE_USER_ONE_VOTE = 'An user can vote only once'
        USER_DIDNT_VOTE = "User didn't vote"
        USER_VOTE_OWN_REVIEW = 'Same user not allowed to vote on own resource'

    class Meta:
        abstract = True

    def _get_author(self):
        for author_field_name in MODEL_AUTHOR_NAMES:
            if hasattr(self, author_field_name):
                return getattr(self, author_field_name)
        raise AttributeError('Cannot find model author field')

    @property
    def thumbs_up(self):
        return len(self.thumbs_up_array)

    @property
    def thumbs_down(self):
        return len(self.thumbs_down_array)

    def _validate_vote(self, user: CustomUser, vote: str):
        if user == self._get_author():
            raise ValidationError(self.ErrorMessages.USER_VOTE_OWN_REVIEW)
        if user.pk in self.thumbs_up_array:
            self.cancel_vote(user)
            if vote == 'up':
                return 'cancel'
        if user.pk in self.thumbs_down_array:
            self.cancel_vote(user)
            if vote == 'down':
                return 'cancel'

    def cancel_vote(self, user: CustomUser):
        author = self._get_author()
        if user.pk in self.thumbs_up_array:
            self.thumbs_up_array.remove(user.pk)
            self.save()
            user.cancel_thumb_up()
            author.positive_score -= 1
        elif user.pk in self.thumbs_down_array:
            self.thumbs_down_array.remove(user.pk)
            self.save()
            user.cancel_thumb_down()
            author.negative_score -= 1
        else:
            raise ValidationError(self.ErrorMessages.USER_DIDNT_VOTE)

    def vote_up(self, user: CustomUser):
        author = self._get_author()
        if self._validate_vote(user, 'up') != 'cancel':
            self.thumbs_up_array.append(user.pk)
            author.positive_feedback()
            user.thumb_up()
        self.save()

    def vote_down(self, user: CustomUser):
        author = self._get_author()
        if self._validate_vote(user, 'down') != 'cancel':
            self.thumbs_down_array.append(user.pk)
            author.negative_feedback()
            user.thumb_down()
        self.save()


import os
os.environ['CUDA_VISIBLE_DEVICES'] = '1,5'
import torch
import torch.distributed as dist
import torch.nn as nn
import torch.optim as optim
import torch.multiprocessing as mp
import wandb
from testing_multi import train
import pickle
import datetime
import random
import pdb
import argparse
import socket

wandb.login()

sweep_id = 'test'
world_size = 2
num_gpus = 2
#

def find_free_port():
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 绑定到一个临时端口
    sock.bind(('localhost', 0))
    # 获取绑定后的端口号
    port = sock.getsockname()[1]
    # 关闭socket
    sock.close()
    # 返回闲置端口号
    return port

def main():
    with wandb.init(config = None):
        config = wandb.config
        print(config)
        config_dict = config._items

        current_time = datetime.datetime.now()
        formatted_time = current_time.strftime("%Y-%m-%d_%H-%M-%S_%f")

        unique_filename = f"output_{formatted_time}.pkl"
        with open(unique_filename, 'wb') as file:
            pickle.dump(config_dict, file)
        print(unique_filename)

        port = find_free_port()
        ddp_add = 'tcp://127.0.0.1:' + str(port)

        print(ddp_add)

        args = {}
        args['config_file_name'] = unique_filename
        args['world_size'] = world_size
        args['ddp_address'] = ddp_add

        # 启动多进程训练
        mp.spawn(
            train,
            nprocs=num_gpus,
            args=(args,)
        )

if __name__ == '__main__':

    wandb.agent(sweep_id, main, project='FYS_test_multi_gpu')


import sys
sys.stdin = open('swea_15036_input.txt', 'r')

def asdf(n, g):
    global flag
    if flag > 0:
        return
    if n == g:
        flag += 1
        return
    for i in range(len(arr)):
        if arr[n][i] == 1 and visit[i] == 0:
            visit[i] = 1
            asdf(i, g)
            visit[i] = 0

T = int(input())
for test_case in range(1, T + 1):
    v, e = map(int, input().split())
    arr = [[0]*(v+1) for _ in range(v+1)]
    visit = [0] * (v+1)
    for i in range(e):
        y, x = map(int, input().split())
        arr[y-1][x-1] = 1
    s, g = map(int, input().split())
    flag = 0
    visit[s-1] = 1
    asdf(s-1, g-1)
    if flag > 0:
        print(f'#{test_case} 1')
    else:
        print(f'#{test_case} 0')


file_get = "get"
file_post = "post"

print("Debug: Get file")
print(open(file_get).read().split("\n"))
print("\nDebug: Post file")
print(open(file_post).read().split("\n"))

def parse_proto(line):
    # Try return except raise(invalid format)
    http_method, path, http_ver = line.split(" ")
    return http_method, path, http_ver

def parse_req(data):
    header = {}
    body = ""
    for i, line in enumerate(data):
        if not line:
            break
        section, value = line.split(": ")
        header.update({section: value})
    for line in data[i:]:
        if line:
            body = line
            break
    return header, line

def parse_body(data):
    pass

def handle(data):
    print("\nDebug: Getting HTTP protocol information")
    http_method, http_path, http_ver = parse_proto(data[0])
    print("Debug: http method: " + http_method)
    print("Debug: path: " + http_path)
    print("Debug: version: " + http_ver)
    print("Debug: Getting header and request")
    header, body = parse_req(data[1:])
    print("Debug: header")
    print(header)
    print("Debug: body")
    print(body)

def run():
    data_get = open(file_get).read().split("\n")
    data_post = open(file_post).read().split("\n")
    handle(data_get)
    handle(data_post)

if __name__ == "__main__":
    run()


from django.shortcuts import get_object_or_404, redirect, render
from .models import Blog
# Create your views here.

def home(request):
    if 'user' not in request.session:
        return redirect('/')
    username=request.session['user']
    blogs = Blog.objects.all()
    print(username)
    return render(request, 'home.html', {
        'blogs': blogs,
        'user': username
    })

def profile(request):
    if 'user' not in request.session:
        return redirect('/')
    username=request.session['user']
    blogs=Blog.objects.filter(username=username)
    return render(request, 'profile.html', {
        'blogs': blogs,
        'user': username
    })

def addblogs(request):
    if 'user' not in request.session:
        return redirect('/')
    username=request.session['user']
    if request.method=='POST':
        title=request.POST['title']
        description=request.POST['description']
        blog=Blog(username=username,title=title,description=description)
        blog.save()
        return redirect('profile')
    else:
        return render(request,'addblog.html',{
            'user': username
        })

def blogPage(request,id):
    if 'user' not in request.session:
        return redirect('/')
    username=request.session['user']
    blog=Blog.objects.get(id=id)
    return render(request,'BlogPage.html',{ 'blog': blog , 'user':username })

def editBlog(request,id):
    if 'user' not in request.session:
        return redirect('/')

    if request.method == 'POST':
        title=request.POST['title']
        description=request.POST['description']
        Blog.objects.filter(id=id).update(title=title,description=description)
        return redirect('home')

    blog=Blog.objects.get(id=id)
    return render(request,'editBlog.html',{ 'blog': blog })

def deleteBlog(request,id):
    if 'user' not in request.session:
            return redirect('/')

    if request.method == 'POST':
        blog=Blog.objects.get(id=id)
        blog.delete()
        return redirect('home')


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Mon Sep 16 22:54:22 2019

@author: rajdua
"""

import numpy as np
from sklearn.linear_model import LogisticRegression
from sklearn.naive_bayes import GaussianNB
from sklearn.ensemble import RandomForestClassifier, VotingClassifier
from sklearn.ensemble import AdaBoostClassifier
from sklearn.datasets import make_classification
from sklearn.ensemble import ExtraTreesClassifier
from sklearn.tree import DecisionTreeClassifier

clf1 = LogisticRegression(solver='lbfgs', multi_class='multinomial',
                           random_state=1)
clf2 = RandomForestClassifier(n_estimators=50, random_state=1)
clf3 = GaussianNB()
clf4 = AdaBoostClassifier(n_estimators=100, random_state=0)
clf5 = DecisionTreeClassifier(max_depth=None, min_samples_split=2,
     random_state=0)
clf6 = ExtraTreesClassifier(n_estimators=10, max_depth=None,
     min_samples_split=2, random_state=0)

X = train
X = X.drop(columns  = 'Id')

y = X['Response']

# X = X.fillna(0)
X = X.fillna(X.median())

X = X.drop(columns = 'Response')

scaler = StandardScaler()
scaler.fit(X)
X = scaler.transform(X)

eclf1 = VotingClassifier(estimators=[
         ('lr', clf1), ('rf', clf2), ('gnb', clf3), ('ada', clf4), ('T', clf5)], voting='hard')
eclf1 = eclf1.fit(X, y)
eclf1.score(X,y)

test_noID = test.drop(columns = ['Id'])
# test_noID = test_noID.fillna(0)
test_noID = test_noID.fillna(test_noID.median())
test_noID = test_noID.drop(columns = 'Response')

scaler = StandardScaler()
scaler.fit(test_noID)
test_noID = scaler.transform(test_noID)

# test_noID = test_noID[['Product_Info_4', 'Ins_Age', 'Ht', 'Wt', 'BMI',
#      'Employment_Info_1', 'Employment_Info_4', 'Employment_Info_6',
#      'Insurance_History_5', 'Family_Hist_2', 'Family_Hist_3',
#      'Family_Hist_4', 'Family_Hist_5']]

predictions_test = eclf1.predict(test_noID)

test['Response'] = predictions_test

submission = test[['Id', 'Response']]
submission.set_index('Id', inplace = True)
submission.to_csv('Ef4.csv', float_format='%.0f')

eclf2 = VotingClassifier(estimators=[
         ('lr', clf1), ('rf', clf2), ('gnb', clf3)],
         voting='soft')
eclf2 = eclf2.fit(X, y)
eclf2 = eclf2.score(X, y)
eclf3 = VotingClassifier(estimators=[
        ('lr', clf1), ('rf', clf2), ('gnb', clf3)],
        voting='soft', weights=[2,1,1],
        flatten_transform=True)
eclf3 = eclf3.fit(X, y)
eclf3.score(X,y)


"""This runner is responsible for listening to users loans getting marked unpaid
and banning the borrower.
"""
from lblogging import Level
from lbshared.lazy_integrations import LazyIntegrations
from lbshared.responses import get_response
import perms.manager
import utils.reddit_proxy
from pypika import PostgreSQLQuery as Query, Table, Parameter
import time
from .utils import listen_event
from functools import partial

LOGGER_IDEN = 'runners/ban_unpaid.py'
RPIDEN = 'ban_unpaid'

def main():
    version = time.time()

    with LazyIntegrations(logger_iden=LOGGER_IDEN) as itgs:
        itgs.logger.print(Level.DEBUG, 'Successfully booted up')
        # Close logger

    with LazyIntegrations(logger_iden=LOGGER_IDEN) as itgs:
        listen_event(itgs, 'loans.unpaid', partial(handle_loan_unpaid, version))

def handle_loan_unpaid(version, body):
    time.sleep(5)  # give the transaction some time to complete
    loan_unpaid_event_id = body['loan_unpaid_event_id']

    with LazyIntegrations(logger_iden=LOGGER_IDEN) as itgs:
        itgs.logger.print(Level.DEBUG, 'Detected loan unpaid event: {}', loan_unpaid_event_id)
        loan_unpaid_events = Table('loan_unpaid_events')
        loans = Table('loans')
        usrs = Table('users')
        borrowers = usrs.as_('borrowers')
        lenders = usrs.as_('lenders')

        itgs.read_cursor.execute(
            Query.from_(loan_unpaid_events)
            .join(loans).on(loans.id == loan_unpaid_events.loan_id)
            .join(borrowers).on(borrowers.id == loans.borrower_id)
            .join(lenders).on(lenders.id == loans.lender_id)
            .select(borrowers.username, lenders.username)
            .where(loan_unpaid_events.id == Parameter('%s'))
            .get_sql(),
            (loan_unpaid_event_id,)
        )
        row = itgs.read_cursor.fetchone()
        if row is None:
            itgs.logger.print(
                Level.WARN, 'Loan unpaid event {} did not exist!', loan_unpaid_event_id)
            return
        (username, lender_username) = row
        itgs.logger.print(
            Level.TRACE,
            'Ensuring /u/{} is moderator or banned from unpaid event {}',
            username, loan_unpaid_event_id
        )
        info = perms.manager.fetch_info(itgs, username, RPIDEN, version)
        if info is None:
            itgs.logger.print(
                Level.INFO,
                '/u/{} defaulted on a loan then deleted their account.',
                username
            )
            return
        if info['borrow_banned']:
            itgs.logger.print(
                Level.DEBUG,
                '/u/{} defaulted on a loan but they are already banned.',
                username
            )
            return
        if info['borrow_moderator']:
            itgs.logger.print(
                Level.INFO,
                '/u/{} defaulted on a loan but is a moderator - no ban',
                username
            )
            return
        if info['borrow_approved_submitter']:
            itgs.logger.print(
                Level.INFO,
                '/u/{} defaulted on a loan but is an approved submitter - no ban',
                username
            )
            # easy to forget about approved submitters
            utils.reddit_proxy.send_request(
                itgs, RPIDEN, version, 'compose',
                {
                    'recipient': '/r/borrow',
                    'subject': 'Approved Submitter Unpaid Loan',
                    'body': (
                        '/u/{} defaulted on a loan but did not get banned since they are '
                        + 'an approved submitter.'
                    ).format(username)
                }
            )
            return

        itgs.logger.print(
            Level.TRACE,
            'Banning /u/{} because they defaulted on a loan',
            username
        )

        substitutions = {
            'borrower_username': username,
            'lender_username': lender_username
        }

        utils.reddit_proxy.send_request(
            itgs, RPIDEN, version, 'ban_user',
            {
                'subreddit': 'borrow',
                'username': username,
                'message': get_response(itgs, 'unpaid_ban_message', **substitutions),
                'note': get_response(itgs, 'unpaid_ban_note', **substitutions)
            }
        )
        itgs.logger.print(
            Level.INFO,
            'Banned /u/{} on /r/borrow - failed to repay loan with /u/{}',
            username,
            lender_username
        )
        perms.manager.flush_cache(itgs, username)


def __calculate_volume(self):

        """!

        @brief Calculates volume of current spatial block.

        @details If empty dimension is detected (where all points has the same value) then such dimension is ignored

                  during calculation of volume.

        @return (double) Volume of current spatial block.

        """

        volume = 0.0

        for i in range(0, len(self.__max_corner)):

            side_length = self.__max_corner[i] - self.__min_corner[i]

            if side_length != 0.0:

                if volume == 0.0: volume = side_length

                else: volume *= side_length

        return volume


import sys
sys.stdin = open("input_5185.txt","r")

def hexToBin(hexV):
    #1. 16진수를 10진수
    if hexV.isdigit():
        numV = int(hexV)
    else:
        numV = ord(hexV) - ord('A') + 10
    #2. 10진수를 2진수 문자열
    # numV의 j번째 비트를 확인 numV & 1<<j
    res  = ''
    for j in range(3, -1, -1):
        if numV & 1 << j:
            res += '1'
        else:
            res += '0'
    return res

TC = int(input())
for tc in range(1, TC + 1):
    N, M = input().split()

    res = ''
    for i in range(int(N)):
        res += hexToBin(M[i])

    print('#{} {}'.format(tc, res))


import torch
from dgl.nn.pytorch import RelGraphConv
import torch.nn.functional as F

class EmbeddingLayer(torch.nn.Module):
    def __init__(self, num_nodes, h_dim):
        super(EmbeddingLayer, self).__init__()
        self.embedding = torch.nn.Embedding(num_nodes, h_dim)

    def forward(self, g, h, r, norm):
        return self.embedding(h.squeeze())

class BaseRGCN(torch.nn.Module):
    def __init__(self, num_nodes, h_dim, out_dim, num_rels, num_bases, hidden_layers=1, dropout=0):
        super(BaseRGCN, self).__init__()
        self.num_nodes = num_nodes
        self.h_dim = h_dim
        self.out_dim = out_dim
        self.num_rels = num_rels
        self.num_bases = None if num_bases < 0 else num_bases
        self.hidden_layers = hidden_layers
        self.dropout = dropout

        self.layers = self.build_model()

    def build_model(self):
        layers = torch.nn.ModuleList()

        input_layer = self.build_input_layer()
        if input_layer is not None:
            layers.append(input_layer)

        for index in range(self.hidden_layers):
            hidden_layer = self.build_hidden_layer(index)
            layers.append(hidden_layer)

        output_layer = self.build_output_layer()
        if output_layer is not None:
            layers.append(output_layer)

        return layers

    def build_input_layer(self):
        return None

    def build_hidden_layer(self, index):
        raise NotImplementedError

    def build_output_layer(self):
        return None

    def forward(self, g, h, r, norm):
        for layer in self.layers:
            h = layer(g, h, r, norm)
        return h

class RGCN(BaseRGCN):
    def build_input_layer(self):
        return EmbeddingLayer(self.num_nodes, self.h_dim)

    def build_hidden_layer(self, index):
        act = F.relu if index < self.hidden_layers - 1 else None
        return RelGraphConv(in_feat=self.h_dim,
                            out_feat=self.h_dim,
                            num_rels=self.num_rels,
                            regularizer='bdd',
                            num_bases=self.num_bases,
                            activation=act,
                            self_loop=True,
                            dropout=self.dropout)

class LinkPredict(torch.nn.Module):
    def __init__(self, num_nodes, h_dim, num_rels, num_bases=-1, num_hidden_layers=1, dropout=0, reg_param=0):
        super(LinkPredict, self).__init__()
        self.rgcn = RGCN(num_nodes=num_nodes,
                         h_dim=h_dim,
                         out_dim=h_dim,
                         num_rels=num_rels * 2,
                         num_bases=num_bases,
                         hidden_layers=num_hidden_layers,
                         dropout=dropout)
        self.reg_param = reg_param
        self.w_relation = torch.nn.Parameter(torch.Tensor(num_rels, h_dim))
        torch.nn.init.xavier_uniform_(self.w_relation, gain=torch.nn.init.calculate_gain('relu'))

    def forward(self, g, h, r, norm):
        """
        :param g: the graph
        :param h: input node ids [v, 1]
        :param r: edge type tensor [e]
        :param norm: edge normalizer tensor [e, 1]
        :return: new node features [v, d]
        """
        return self.rgcn(g, h, r, norm)

    def calc_loss(self, output, triplets, labels):
        """
        :param output: output features of each node
        :param triplets: triplets is a list of data samples (positive and negative)
        :param labels: labels indicating positive or negative
        :return:
        """
        scores = self.calc_score(output, triplets)
        return F.binary_cross_entropy_with_logits(scores, labels) + self.reg_param * (
                    torch.mean(output.pow(2)) + torch.mean(self.w_relation.pow(2)))

    def calc_score(self, output, triplets):
        sub = output[triplets[:, 0]]  # [triple num, dim]
        obj = output[triplets[:, 2]]  # [triple num, dim]
        r = self.w_relation[triplets[:, 1]]  # [triple num, dim]
        # DistMult: sub.T@diag(r)@obj
        score = torch.sum(sub * r * obj, dim=1)  # [triple num]
        return score

    def get_rank(self, output, subj, rel, obj, label, filtered=True):
        """
        calculate ranks of predictions in a mini-batch
        :param output: embedding of each entity: [num_ent, dim]
        :param subj: subject id [batch-size]
        :param rel: relation id
        :param obj: object id
        :param label: indicate valid tails corresponding to head and relation pairs [batch-size, num-ent]
        :param filtered: weather filtered
        :return: rank: [batch-size]
        """
        batch_obj = output[subj] * self.w_relation[rel]
        score = batch_obj @ output.transpose(0, 1)  # [batch_size, dim] @ [dim, entity_num]
        score = torch.sigmoid(score)
        batch_range = torch.arange(score.shape[0])
        if filtered:
            target_score = score[batch_range, obj]
            score = torch.where(label.byte(), torch.zeros_like(score).to(score.device),
                                score)  # filter out other objects with same sub&rel pair
            score[batch_range, obj] = target_score
        rank = 1 + torch.argsort(torch.argsort(score, dim=1, descending=True), dim=1, descending=False)[
            batch_range, obj]
        return rank


import os
import sys

try:
    from photofilmstrip._scmInfo import SCM_REV  # IGNORE:F0401
except ImportError:
    SCM_REV = "src"

if getattr(sys, "frozen", False):
    APP_DIR = os.path.dirname(os.path.abspath(sys.argv[0]))
else:
    APP_DIR = os.path.join(os.path.dirname(os.path.abspath(sys.argv[0])), "..")

VERSION_SUFFIX = 'b4'

APP_NAME = "PhotoFilmStrip"
APP_VERSION = "4.0.0"
APP_VERSION_SUFFIX = "%s%s" % (APP_VERSION, VERSION_SUFFIX)
APP_VERSION_FULL = "%s-%s" % (APP_VERSION_SUFFIX, SCM_REV)
APP_SLOGAN = "PhotoFilmStrip - Creates movies out of your pictures."
APP_DESCRIPTION = """\
PhotoFilmStrip creates movies out of your pictures in just 3 steps. First select your photos, customize the motion path and render the video. There are several output possibilities for VCD, SVCD, DVD up to FULL-HD.
"""
APP_URL = "http://www.photofilmstrip.org"
DEVELOPERS = ["Jens Göpfert"]
TRANSLATORS = ["Teza Lprod - http://lprod.org", "geogeo - http://www.geogeo.gr"]


import ir.node
from backend.cppcode.nodegenerator.nodegenerator import NodeGenerator

class Split(NodeGenerator):
    @classmethod
    def accept(cls, node: ir.node.Node):
        return isinstance(node, ir.node.base.Split)

    @property
    def code(self):
        fmt = ""
        for i in range(len(self.outputs)):
            if i > 0:
                fmt += "    "
            fmt += (
                "auto {outputs["
                + str(i)
                + "]} = tfcc::base::slice({inputs[0]}, {node.axis}, {inputs[0]}.shape({node.axis}) / {count} * "
                + str(i)
            )
            fmt += ", {inputs[0]}.shape({node.axis}) / {count} * " + str(i + 1) + ");\n"
        return fmt.format(count=len(self.outputs), **self.fmt_dict)


import sqlite3
import http.client
import urllib
import os
import yaml
import argparse
import sys
import logging

from sqlite3 import Error
from datetime import datetime

#
# Templates
#
BASE_TEMPLATE = '''Hi,

%%ONGOING%%
%%DUE_DATE%%'''
ONGOING_TEMPLATE = '''=== Ongoing tasks: ===
%%ONGOING_TASK%%'''
DUEDATE_TEMPLATE = '''=== Due date: ===
%%DUEDATE_TASK%%'''
#
# end of Templates
#

__version__ = 0.6  # alpha
log = logging.getLogger('mtt_notify')

TAG_ID = 13  # "ongoing" tag
DUE_DATE_THRESHOLD_DAYS = 7

class Configuration:
    app_name = ''
    config_full_path = ''
    config = []

    def __init__(self, app_name, provided_config_path=""):
        self.app_name = app_name

        if not provided_config_path:
            config_known_paths = [
                f'{os.getcwd()}/{app_name}.yaml',
                f'/etc/{app_name}/{app_name}.yaml',
                f'/etc/{app_name}.yaml',
                f'/usr/local/etc/{app_name}/{app_name}.yaml',
                f'/usr/local/etc/{app_name}.yaml',
            ]
        else:
            config_known_paths = [provided_config_path]

        for config_path in config_known_paths:
            if not os.path.exists(config_path):
                continue
            else:
                self.config_full_path = config_path
                break

        if not self.config_full_path:
            raise Exception('Configuration file not found')

        if not self._load_configuration():
            raise Exception('Configuration error')

    def _load_configuration(self):

        if len(self.config) > 0:
            return self.config

        file_handler = open(self.config_full_path, 'r')

        try:
            self.config = yaml.full_load(file_handler)
            # return self.config
            return True
        # except IOError:
        #     # log.error('Config file does not exist')
        #     return []
        except yaml.parser.ParserError:
            raise Exception('Config syntax error')

    def __getitem__(self, item):
        return self.config[item]

def create_connection(db_file):
    """ create a database connection to the SQLite database
        specified by db_file
    :param db_file: database file
    :return: Connection object or None
    """
    conn = None
    try:
        conn = sqlite3.connect(db_file)
    except Error as e:
        print(e)

    return conn

def main(args=None):
    if args is None:
        args = sys.argv[1:]

    log.setLevel(logging.INFO)
    fh = logging.StreamHandler(sys.stdout)
    fh.setFormatter(logging.Formatter('%(message)s'))
    log.addHandler(fh)

    parser = argparse.ArgumentParser(
        description='\033[93m[[ {} ]]\033[0m tool v{}'.format('myTinyTodo Notifier', __version__),
    )

    parser.add_argument('-d', '--debug', dest='debug', action='store_true', default=False,
                        help='causes the tool to print debugging messages about its progress')
    parser.add_argument('-s', '--silent', dest='silent', action='store_true', default=False,
                        help='do not output general info but errors, useful for crontab')
    parser.add_argument('--disable-notification', dest='disable_notify', action='store_true', default=False,
                        help='do not send actual notification, useful for debugging')
    parser.add_argument('-c', '--config-path', type=str, dest='config_path', required=False,
                        help=f'custom configuration file path')

    args = parser.parse_args(args)

    if args.silent is True:
        log.setLevel(logging.CRITICAL)

    if args.debug is True:
        log.setLevel(logging.DEBUG)
        log.debug("Debug message mode is enabled")

    conf = Configuration('mtt_notify', args.config_path)
    # todo:
    #   conf.defaults({'api': 'api.pushover.net:443'})
    conn = create_connection(conf['database_path'])

    # todo:
    #     FIX THIS EXCEPTION! Config class should ask politely to provide missing config options
    #     Traceback (most recent call last):
    #     File "/home/stan/apps/mtt_notify.py", line 199, in <module>
    #       main()
    #     File "/home/stan/apps/mtt_notify.py", line 191, in main
    #       "token": conf['pushover_token'],
    #     File "/home/stan/apps/mtt_notify.py", line 82, in __getitem__
    #       return self.config[item]
    #   KeyError: 'pushover_token'
    #

    with conn:
        cursor = conn.cursor()

        log.debug('[>] Searching SQLITE for the DUE DATE tasks...')
        cursor.execute(f'''
            SELECT * FROM mtt_todolist
            WHERE compl = 0
            AND duedate IS NOT null
            AND (
                duedate > DATE('now', '-{DUE_DATE_THRESHOLD_DAYS} days')
                OR duedate <= DATE('now')
            )
        ''')
        rows = cursor.fetchall()

        log.info('[*] DUE DATE tasks:')
        tasks_duedate = []
        for row in rows:
            log.debug(f"ROW: {row}")  # print(row)
            # https://docs.python.org/3/library/datetime.html
            # datetime.strptime('2015-05-16', '%Y-%m-%d')
            dt_obj = datetime.strptime(f"{row[13]} 23:59", '%Y-%m-%d %H:%M')
            # currently supported: 1. "due" 2. "EXPIRED" . -----> To add support "DUE TODAY" <-----
            message = f"- \"{row[7]}\" {'due' if dt_obj >= datetime.now() else 'EXPIRED'} on {dt_obj:%A, %B %e} ({dt_obj:%m/%d})"
            log.debug(f"LINE: \"{message}\"")
            tasks_duedate.append(message)

        log.debug('[>] Searching SQLITE for the tag: (Searching for the tag "ongoing")')
        cursor.execute('''
            SELECT * FROM mtt_tag2task
            INNER JOIN mtt_todolist
                ON mtt_todolist.id = mtt_tag2task.task_id
            WHERE mtt_tag2task.tag_id = ? and mtt_todolist.compl = 0
        ''', (TAG_ID,))

        rows = cursor.fetchall()
        task_tag = []

        log.info(f"[*] Tagged tasks:")
        for row in rows:
            log.info(f"Task \"{row[10]}\" has \"{row[14]}\" tag")
            task_tag.append(f"- {row[10]}")

        if not tasks_duedate and not task_tag:
            return True

        # Todo:
        #   - check jinja
        ONGOING_STR = ONGOING_TEMPLATE.replace('%%ONGOING_TASK%%', "\n".join(task_tag)) if task_tag else ''
        DUEDATE_STR = DUEDATE_TEMPLATE.replace('%%DUEDATE_TASK%%', "\n".join(tasks_duedate)) if tasks_duedate else ''
        BASE_STR = BASE_TEMPLATE.replace('%%ONGOING%%', ONGOING_STR).replace('%%DUE_DATE%%', DUEDATE_STR)

        log.debug(f"[*] The notification below is about to send out:\n"
                  f"========== [START] ==========\n"
                  f"{BASE_STR}\n"
                  f"========== [END] ==========")

        if args.disable_notify is True:
            log.info("[!] Not notifying because instructed to do so")
        else:
            # Todo:
            #   - check html support
            #   - change priority to "High Priority (1)" (NOT Emergency Priority (2)) when due date is expired
            conn = http.client.HTTPSConnection("api.pushover.net:443")
            conn.request("POST", "/1/messages.json",
                         urllib.parse.urlencode({
                             "token": conf['pushover_token'],
                             "user": conf['pushover_user'],
                             "message": BASE_STR,
                         }), {"Content-type": "application/x-www-form-urlencoded"})
            conn.getresponse()

if __name__ == '__main__':
    main()


import cv2
import numpy as np
from matplotlib import pyplot as plt
from argparse import ArgumentParser

parser = ArgumentParser()
parser.add_argument("--UseRANSAC", type=int, default=0)
parser.add_argument("--image1", type=str, default='fmdata/myleft.jpg')
parser.add_argument("--image2", type=str, default='fmdata/myright.jpg')
# parser.add_argument("--image1", type=str, default='fmdata/old_building_1.jpg')
# parser.add_argument("--image2", type=str, default='fmdata/old_building_2.jpg')
# parser.add_argument("--image1", type=str, default='fmdata/rushmore_1.jpg')
# parser.add_argument("--image2", type=str, default='fmdata/rushmore_2.jpg')
args = parser.parse_args()

print(args)

# function to normalize the points
# Normalization as specified in Hartley's Normalized Eight-Point Algorithm"
def normalizePoints(pts):
    num_pts = np.shape(pts)[0]
    result = np.hstack((pts, np.ones((num_pts, 1))))
    # shifting the coords to the centroid: (1/sqrt(2))* difference between points & mean val/total num points (std dev)
    pts_shift = np.sqrt(2) / np.std(pts)
    # constructing the normalization matrix norm_mat row by row
    row1 = [pts_shift, 0, -pts_shift * np.mean(pts[:, 0])]
    row2 = [0, pts_shift, -pts_shift * np.mean(pts[:, 1])]
    row3 = [0, 0, 1]
    norm_mat = np.vstack((row1, row2, row3))
    result = np.matmul(norm_mat, result.T).T
    return result, norm_mat

def FM_by_normalized_8_point(pts1, pts2):
    # F, _ = cv2.findFundamentalMat(pts1,pts2,  cv2.FM_8POINT )
    # num of pts
    n = np.shape(pts1)[0]
    # Normalizing the point coordinates
    norm_pts1, norm_mat1 = normalizePoints(pts1)
    norm_pts2, norm_mat2 = normalizePoints(pts2)

    # Initialize the N x 9 matrix A
    A = np.zeros((n, 9))
    # building the matrix equation
    for i in range(n):
        # coefficients in the equation
        x = norm_pts1[i, 0]
        x_prime = norm_pts2[i, 0]
        y = norm_pts1[i, 1]
        y_prime = norm_pts2[i, 1]
        A[i] = [x * x_prime,
                x * y_prime,
                x,
                y * x_prime,
                y * y_prime,
                y,
                x_prime,
                y_prime,
                1]
    ua, sa, va = np.linalg.svd(A)
    E = va[-1].reshape(3, 3)
    ue, se, ve = np.linalg.svd(E)
    # Enforce Rank 2
    se[2] = 0
    # Calculating Fundamental Matrix F
    F = np.matmul(ue, np.matmul(np.diag(se), ve))
    # Un-Normalizing F
    F = np.matmul(norm_mat1.T, np.matmul(F, norm_mat2))
    F = F.T
    # to check with built-in implementation
    # F, _ = cv2.findFundamentalMat(pts1, pts2, cv2.FM_8POINT)
    return F

def FM_by_RANSAC(pts1, pts2):
    # F:  fundmental matrix
    # mask:   whetheter the points are inliers
    # np.random.seed(39)
    # total number of inliers
    inlier_total = 0
    # num of pairs of points
    num_pairs = 8
    total_points = np.shape(pts1)[0]
    threshold = 0.05
    # number of iterations for ransac
    N = 2000
    # fundamental matrix
    F = np.zeros((3, 3))
    # initialize inlier mask
    mask = np.zeros(total_points)
    for i in np.arange(N):
        rand_pts = np.random.permutation(total_points)

        # two sets of points x and x'
        x = np.zeros((num_pairs, 2))
        x_prime = np.zeros((num_pairs, 2))

        # inlier count
        inlier_mask = np.zeros(total_points)
        num_of_inliers = 0

        # assigning 8 point pairs
        for m in np.arange(0, num_pairs):
            x[m] = pts1[rand_pts[m]]
            x_prime[m] = pts2[rand_pts[m]]

        # get fundamental matrix using these 8 pairs with the normalized 8pt algorithm above
        F_ransac = FM_by_normalized_8_point(x, x_prime)
        F_ransac = F_ransac.T

        # adding 1s to maintain dimensionality
        x = np.hstack((pts1, np.ones((total_points, 1))))
        x_prime = np.hstack((pts2, np.ones((total_points, 1))))

        # error calculations, x_prime.T * F * x = 0
        err = np.multiply(x_prime.T, np.matmul(F_ransac, x.T))
        # find absolute value of errors
        errors = np.fabs(np.sum(err, axis=0))

        for k in np.arange(total_points):
            if errors[k] < threshold:
                inlier_mask[k] = 1
                num_of_inliers += 1

        if num_of_inliers > inlier_total:
            inlier_total = num_of_inliers
            F = F_ransac
            mask = inlier_mask

    # to check with built in implementation
    # F, mask = cv2.findFundamentalMat(pts1, pts2, cv2.FM_RANSAC)
    return F, mask

img1 = cv2.imread(args.image1, 0)
img2 = cv2.imread(args.image2, 0)

sift = cv2.xfeatures2d.SIFT_create()

# find the keypoints and descriptors with SIFT
kp1, des1 = sift.detectAndCompute(img1, None)
kp2, des2 = sift.detectAndCompute(img2, None)

# FLANN parameters
FLANN_INDEX_KDTREE = 0
index_params = dict(algorithm=FLANN_INDEX_KDTREE, trees=5)
search_params = dict(checks=50)

flann = cv2.FlannBasedMatcher(index_params, search_params)
matches = flann.knnMatch(des1, des2, k=2)

good = []
pts1 = []
pts2 = []

# ratio test as per Lowe's paper
for i, (m, n) in enumerate(matches):
    if m.distance < 0.8 * n.distance:
        good.append(m)
        pts2.append(kp2[m.trainIdx].pt)
        pts1.append(kp1[m.queryIdx].pt)

pts1 = np.int32(pts1)
pts2 = np.int32(pts2)

F = None
if args.UseRANSAC:
    F, mask = FM_by_RANSAC(pts1, pts2)
    # We select only inlier points
    pts1 = pts1[mask.ravel() == 1]
    pts2 = pts2[mask.ravel() == 1]
else:
    F = FM_by_normalized_8_point(pts1, pts2)

def drawlines(img1, img2, lines, pts1, pts2):
    ''' img1 - image on which we draw the epilines for the points in img2
        lines - corresponding epilines '''
    r, c = img1.shape
    img1 = cv2.cvtColor(img1, cv2.COLOR_GRAY2BGR)
    img2 = cv2.cvtColor(img2, cv2.COLOR_GRAY2BGR)
    for r, pt1, pt2 in zip(lines, pts1, pts2):
        color = tuple(np.random.randint(0, 255, 3).tolist())
        x0, y0 = map(int, [0, -r[2] / r[1]])
        x1, y1 = map(int, [c, -(r[2] + r[0] * c) / r[1]])
        img1 = cv2.line(img1, (x0, y0), (x1, y1), color, 1)
        img1 = cv2.circle(img1, tuple(pt1), 5, color, -1)
        img2 = cv2.circle(img2, tuple(pt2), 5, color, -1)
    return img1, img2

# Find epilines corresponding to points in second image,  and draw the lines on first image
lines1 = cv2.computeCorrespondEpilines(pts2.reshape(-1, 1, 2), 2, F)
lines1 = lines1.reshape(-1, 3)
img5, img6 = drawlines(img1, img2, lines1, pts1, pts2)
plt.subplot(121), plt.imshow(img5)
plt.subplot(122), plt.imshow(img6)
plt.show()

# Find epilines corresponding to points in first image, and draw the lines on second image
lines2 = cv2.computeCorrespondEpilines(pts1.reshape(-1, 1, 2), 1, F)
lines2 = lines2.reshape(-1, 3)
img3, img4 = drawlines(img2, img1, lines2, pts2, pts1)
plt.subplot(121), plt.imshow(img4)
plt.subplot(122), plt.imshow(img3)
plt.show()


county = df_county_data["County Name"]
pov_rate = df_county_data["Poverty Rate"]
x_axis = np.arange(len(pov_rate))
# Create a bar chart based upon the above data
tick_locations = [value for value in x_axis]
# plt.xticks(tick_locations, county, rotation= 90)
plt.bar(x_axis, pov_rate, color="r", align="center")
plt.title("County Poverty Rates")
plt.xlabel("Counties")
plt.ylabel("Poverty Rates")
plt.text(140, 30, "Note:\nPoverty Rates for all counties in NJ, NY, & PA.")

# Save an image of the chart and print it to the screen
plt.savefig("Images/County_Poverty_Rates.png", bbox_inches = "tight")
plt.show()


# -*- coding:utf-8 -*-
"""
@Author       : xupingmao
@email        : 578749341@qq.com
@Date         : 2023-02-01 23:15:02
@LastEditors  : xupingmao
@LastEditTime : 2023-02-05 13:45:55
@FilePath     : /xnoted:/projects/learn-python/src/storage/my_kv.py
@Description  : 键值对存储，基于Bitcask模型
"""

import json
import os
import datetime
import time
import threading
import fnmatch
from bkv.mem_store import MemoryKvStore, SqliteMemStore
from bkv import utils

class StoreItem:
    def __init__(self):
        self.k = ""
        self.v = ""
        self.d = 0 # 删除标记

class StoreMeta:
    def __init__(self):
        self.version = ""
        self.create_time = ""
        self.data_file = ""

def format_datetime(value=None, format='%Y-%m-%d %H:%M:%S'):
    """格式化日期时间
    >>> format_datetime(0)
    '1970-01-01 08:00:00'
    """
    if value == None:
        return time.strftime(format)
    elif isinstance(value, datetime.datetime):
        return value.strftime(format)
    else:
        st = time.localtime(value)
        return time.strftime(format, st)

class MetaFile:

    meta_version = "1.0.0"
    default_data_file = "data-0.txt"

    def __init__(self, db_dir="./data"):
        meta_file = "./meta.txt"
        self.db_dir = db_dir
        self.meta_file = os.path.join(db_dir, meta_file)
        self.load_meta_file()

    def load_meta_file(self):
        if not os.path.exists(self.db_dir):
            os.makedirs(self.db_dir)

        if not os.path.exists(self.meta_file):
            with open(self.meta_file, "w+"):
                pass

        with open(self.meta_file, "r+") as read_fp:
            json_text = read_fp.read()
            if json_text.strip() == "":
                self.meta = self.create_meta()
            else:
                self.meta = self._load_meta(json_text)
            assert self.meta.version == self.meta_version, "broken meta"

    def create_meta(self):
        with open(self.meta_file, "w+") as fp:
            meta = StoreMeta()
            meta.version = self.meta_version
            meta.data_file = self.default_data_file
            meta.create_time = format_datetime()
            fp.write(json.dumps(meta.__dict__))
            fp.flush()
            return meta

    def _load_meta(self, json_str):
        json_dict = json.loads(json_str)
        item = StoreMeta()
        item.__dict__.update(json_dict)
        if item.data_file == "":
            item.data_file = "data-0.txt"
        return item

    def save(self):
        with open(self.meta_file, "w+") as fp:
            fp.write(json.dumps(self.meta.__dict__))

    def create_new_data_file(self):
        for i in range(100):
            fname = "data-%d.txt" % i
            fpath = os.path.join(self.db_dir, fname)
            if not os.path.exists(fpath):
                return fname
        raise Exception("too many store files")

    def delete_old_data_files(self):
        for i in range(100):
            fname = "data-%d.txt" % i
            fpath = os.path.join(self.db_dir, fname)
            if os.path.exists(fpath) and fname != self.meta.data_file:
                print("found old data file:", fname)

class DataFile:
    """db存储，管理1个存储文件"""

    def __init__(self, db_dir="./data", data_file="./data-1.txt", **kw):
        self.last_pos = 0
        self.db_dir = db_dir
        self.mem_store_type = kw.get("mem_store_type", "bisect")

        if self.mem_store_type == "sqlite":
            self.mem_store = SqliteMemStore()
        else:
            self.mem_store = MemoryKvStore(default_value=0)

        self.data_file = data_file
        self.print_load_stats = kw.get("print_load_stats", False)
        self.load_data_file()
        self.lock = threading.RLock()

    def load_data_file(self):
        if not os.path.exists(self.db_dir):
            os.makedirs(self.db_dir)

        fpath = os.path.join(self.db_dir, self.data_file)
        if not os.path.exists(fpath):
            with open(fpath, "w+") as fp:
                pass

        qps_counter = utils.QpsCounter()
        with open(fpath, "r+") as fp:
            count = 0
            while True:
                pos = fp.tell()
                line = fp.readline()
                if line.strip() == "":
                    break
                line_data = self._load_item(line)
                key = line_data.k
                if line_data.d == 1:
                    # 已删除
                    self.mem_store.delete(key)
                else:
                    self.mem_store.put(key, pos)

                count+=1
                if self.print_load_stats and count % 10000 == 0:
                    qps_counter.set_count(count)
                    mem_info = utils.memory_info()
                    keys = len(self.mem_store)
                    rss = mem_info.rss/1024/1024
                    qps = qps_counter.qps()
                    print(f"keys:({keys}), memory:({rss:.2f}MB), qps:({qps//1})")

        self.write_fp = open(fpath, "a+")
        self.last_pos = self.write_fp.tell()

    def _load_item(self, json_str):
        json_dict = json.loads(json_str)
        item = StoreItem()
        item.__dict__.update(json_dict)
        return item

    def write(self, key="", val="", delete=0):
        # TODO 优化下编码器，增加校验和删除标记
        self.write_fp.seek(self.last_pos)
        item = StoreItem()
        item.k = key
        item.v = val
        item.d = delete
        self.write_fp.write(json.dumps(item.__dict__))
        self.write_fp.write("\n")
        # TODO 提供更多flush策略
        self.write_fp.flush()
        self.last_pos = self.write_fp.tell()

    def close(self):
        self.write_fp.close()

    def get(self, key):
        pos_int = self.mem_store.get(key)
        if pos_int == None:
            return None
        self.write_fp.seek(pos_int)
        line_str = self.write_fp.readline()
        return json.loads(line_str).get("v")

    def put(self, key, val):
        # TODO 把data文件切割成多个文件，写满一个文件后自动切换到新的文件
        pos_int = self.write_fp.tell()
        exist = self.get(key)
        if exist == val:
            # 没变化
            return
        with self.lock:
            self.mem_store.put(key, pos_int)
            self.write(key, val)

    def delete(self, key):
        exist = self.get(key)
        if exist == None:
            # 已经删除
            return
        with self.lock:
            self.mem_store.delete(key)
            self.write(key=key, delete=1)

    def count(self):
        return len(self.mem_store)

    def avg_key_len(self):
        length = 0
        for key, pos in self.mem_store:
            length += len(key)
        return length / len(self.mem_store)

    def keys(self, key, limit=100):
        result = []
        for store_key, pos in self.mem_store:
            if fnmatch.fnmatch(store_key, key):
                result.append(store_key)
                if len(result) >= limit:
                    break
        return result

    def delete_file(self):
        self.write_fp.close()
        fpath = os.path.join(self.db_dir, self.data_file)
        os.remove(fpath)


from random import randint
from random import sample
from random import shuffle
import numpy as np
import pprint
import concurrent.futures
import ast
from contextlib import redirect_stdout
import itertools

# storage=[]
# result = []
# perfect = []
# on = True
# # for i in range(len(square_1)):
# #     for j in range(len(square_1[i])):
# #         square_1[i][j] = randint(1,100)
# while on:
#     square_1 = np.array(sample(range(1,100),9))
#     square_1 = square_1.reshape((3,3))
#     storage.append(square_1[0][0]+square_1[0][1]+square_1[0][2])
#     storage.append(square_1[1][0]+square_1[1][1]+square_1[1][2])
#     storage.append(square_1[2][0]+square_1[2][1]+square_1[2][2])
#     storage.append(square_1[0][0]+square_1[1][0]+square_1[2][0])
#     storage.append(square_1[0][1]+square_1[1][1]+square_1[2][1])
#     storage.append(square_1[0][2]+square_1[1][2]+square_1[2][2])
#     storage.append(square_1[0][0]+square_1[1][1]+square_1[2][2])
#     storage.append(square_1[0][2]+square_1[1][1]+square_1[2][0])
#     if len(set(storage))==2:
#         result.append(square_1)
#         print(result)
#         on = False
#     if len(set(storage))==1:
#         perfect.append(square_1)
#         print(perfect)
#         on = False

def makeList():
    s=[i for i in range(1,150)]
    res = {}
    for i in range(15,150):
        temp =[]
        for index,j in enumerate(s):
            l,r = index+1, len(s)-1
            diff = i-j
            if diff < 0:
                break
            while l<r:
                if s[l]+s[r] > diff:
                    r-=1
                elif s[l]+s[r]< diff:
                    l+=1
                else:
                    temp.append([j,s[l],s[r]])
                    r-=1
        res[i]= temp
    with open("output.txt", "w") as external_file:
        pprint.pprint(res, stream= external_file)
        external_file.close()

def perfect ():
    with open('output.txt','r') as f:
        permu_list = ast.literal_eval(f.read())
    s = permu_list[50]
    result = []
    perfect = []
    on = True
    target = 50
    while on:
        flag = False
        p = sample(range(len(s)),3)
        shuffle(s[p[0]])
        shuffle(s[p[1]])
        x = [target-s[p[0]][0]-s[p[1]][0],target-s[p[0]][1]-s[p[1]][1],target-s[p[0]][2]-s[p[1]][2]]
        for i in x:
            if i < 0:
                flag = True
        if flag == True:
            continue
        square_1 = np.array([s[p[0]],s[p[1]],x])
        storage =[]
        storage.append(square_1[0][0]+square_1[1][0]+square_1[2][0])
        storage.append(square_1[0][1]+square_1[1][1]+square_1[2][1])
        storage.append(square_1[0][2]+square_1[1][2]+square_1[2][2])
        storage.append(square_1[0][0]+square_1[1][1]+square_1[2][2])
        storage.append(square_1[0][2]+square_1[1][1]+square_1[2][0])
        if len(set(storage))==1:
            perfect.append(square_1)

def nearlyPerfect ():
    with open('output.txt','r') as f:
        permu_list = ast.literal_eval(f.read())
    s = permu_list[117]
    perfect = []
    on = True
    target = 117
    while on:
        flag = False
        p = sample(range(len(s)),3)
        shuffle(s[p[0]])
        shuffle(s[p[1]])
        x = [target-s[p[0]][0]-s[p[1]][0],target-s[p[0]][1]-s[p[1]][1],target-s[p[0]][2]-s[p[1]][2]]
        for i in x:
            if i < 0:
                flag = True
        if flag == True:
            continue

        square_1 = np.array([s[p[0]],s[p[1]],x])

        storage =[]
        storage.append(square_1[2][0]+square_1[2][1]+square_1[2][2])
        storage.append(square_1[0][0]+square_1[1][0]+square_1[2][0])
        storage.append(square_1[0][1]+square_1[1][1]+square_1[2][1])
        storage.append(square_1[0][2]+square_1[1][2]+square_1[2][2])
        storage.append(square_1[0][0]+square_1[1][1]+square_1[2][2])
        storage.append(square_1[0][2]+square_1[1][1]+square_1[2][0])

        if len(set(storage))==1: #or (len(set(storage))==2 and abs(list(set(storage))[0]-list(set(storage))[1]) == 1):
            perfect.append(square_1)

        else:
            continue

        #start of second square
        linear=square_1.flatten()
        if len(set(linear)) != len(linear):
            continue
        if 0 in linear:
            continue

        # match_specific = left_top of the number
        square_2_ref_1 = int(square_1[2][0])
        square_2_ref_2 = int(square_1[2][1])
        match = 0

        flag_3 = True
        for i in range(16,len(permu_list)):
            for j in permu_list[i]:
                if square_2_ref_1 in j:
                    if square_2_ref_2 in j:
                        match = j
                        match_specific = match.copy()
                        match_specific.remove(square_2_ref_1)
                        match_specific.remove(square_2_ref_2)
                        if match_specific not in linear and (match_specific[0]>int(square_1[2][0]) or match_specific[0]>int(square_1[2][1])):
                            flag_3 = False
                            square_2_target = i
                            break
            if flag_3 == False:
                break
        if flag_3 == True:
            continue
        square_2_s = permu_list[square_2_target]
        flag_2 = False
        #add first row to linear
        linear = np.append(linear,match_specific[0])
        #check for duplicate in the second row
        x = 0
        for z in permu_list[square_2_target]:
            if len(linear.tolist()+z) ==  len(set(linear.tolist()+z)):
                square_2_secondrow = z
                for m in list(itertools.permutations(square_2_secondrow)):
                    if len(m) != 3:
                        continue
                    square_2_x = [square_2_target-match_specific[0]-m[0],square_2_target-int(square_1[2][0])-m[1],square_2_target-int(square_1[2][1])-m[2]]
                    #check for duplicates and negative
                    # with open('out_2.txt', 'a') as f:
                    #     with redirect_stdout(f):
                    #         print(square_2_target,square_2_secondrow,linear,square_2_x)
                    flag = False
                    for i in square_2_x:
                        if i <= 0:
                            flag = True
                            break
                        if i in linear:
                            flag = True
                            break
                    if flag == False:

                        square_2 = np.array([[match_specific[0],square_1[2][0],square_1[2][1]],m,square_2_x])
                        #print(square_2_target,square_1,square_2)
                        #starts to filter for right last row
                        sqaure_2_storage =[]
                        sqaure_2_storage.append(square_2[2][0]+square_2[2][1]+square_2[2][2])
                        sqaure_2_storage.append(square_2[0][0]+square_2[1][0]+square_2[2][0])
                        sqaure_2_storage.append(square_2[0][1]+square_2[1][1]+square_2[2][1])
                        sqaure_2_storage.append(square_2[0][2]+square_2[1][2]+square_2[2][2])
                        sqaure_2_storage.append(square_2[0][0]+square_2[1][1]+square_2[2][2])
                        sqaure_2_storage.append(square_2[0][2]+square_2[1][1]+square_2[2][0])

                        if len(set(sqaure_2_storage))==1 or (len(set(sqaure_2_storage))==2 and abs(list(set(sqaure_2_storage))[0]-list(set(sqaure_2_storage))[1]) == 1):
                            perfect.append(square_2)
                        else:
                            continue
                        linear = np.append(linear,m)
                        linear = np.append(linear,square_2_x)
                        linear = linear.flatten()
                        if len(set(linear)) != len(linear):
                            continue
                        if 0 in linear:
                            continue
                        #finish on second square
                        square_3_ref_1 = int(square_2[1][2])
                        square_3_ref_2 = int(square_2[2][2])

                        #find top left for square_3
                        flag_4 = True
                        for i in range(16,len(permu_list)):
                            for j in permu_list[i]:
                                if square_3_ref_1 in j:
                                    if square_3_ref_2 in j:
                                        match = j
                                        match_specific = match.copy()
                                        match_specific.remove(square_3_ref_1)
                                        match_specific.remove(square_3_ref_2)
                                        if len(match_specific) != 1:
                                            continue
                                        if match_specific not in linear and (match_specific[0]>square_3_ref_1 or match_specific[0]>square_3_ref_2):
                                            flag_4 = False
                                            square_3_target = i
                                            break
                            if flag_4 == False:
                                break
                        linear = np.append(linear,match_specific[0])
                        for z in permu_list[square_3_target]:
                            if len(linear.tolist()+z) ==  len(set(linear.tolist()+z)):
                                square_3_secondrow = z
                                for j in list(itertools.permutations(square_3_secondrow)):
                                    if len(j) != 3:
                                        continue
                                    square_3_x = [square_3_target-match_specific[0]-j[0],square_3_target-square_3_ref_2-j[1],square_3_target-square_3_ref_1-j[2]]
                                    #check for duplicates and negative
                                    # with open('out_2.txt', 'a') as f:
                                    #     with redirect_stdout(f):
                                    #         print(square_2_target,square_2_secondrow,linear,square_2_x)
                                    flag = False
                                    for i in square_3_x:
                                        if i <= 0:
                                            flag = True
                                            break
                                        if i in linear:
                                            flag = True
                                            break
                                    if flag == False:

                                        square_3 = np.array([[match_specific[0],square_2[2][2],square_2[1][2]],j,square_3_x])

                                        #print(square_2_target,square_1,square_2)
                                        #starts to filter for right last row
                                        sqaure_3_storage =[]
                                        sqaure_3_storage.append(square_3[2][0]+square_3[2][1]+square_3[2][2])
                                        sqaure_3_storage.append(square_3[0][0]+square_3[1][0]+square_3[2][0])
                                        sqaure_3_storage.append(square_3[0][1]+square_3[1][1]+square_3[2][1])
                                        sqaure_3_storage.append(square_3[0][2]+square_3[1][2]+square_3[2][2])
                                        sqaure_3_storage.append(square_3[0][0]+square_3[1][1]+square_3[2][2])
                                        sqaure_3_storage.append(square_3[0][2]+square_3[1][1]+square_3[2][0])

                                        if len(set(sqaure_3_storage))==1: #or (len(set(sqaure_3_storage))==2 and abs(list(set(sqaure_3_storage))[0]-list(set(sqaure_3_storage))[1]) == 1):
                                            perfect.append(square_3)

                                        else:
                                            continue
                                        linear = np.append(linear,j)
                                        linear = np.append(linear,square_3_x)
                                        linear = linear.flatten()
                                        if len(set(linear)) != len(linear):
                                            continue
                                        if 0 in linear:
                                            continue
                                        # print(sum(linear))
                                        # print(square_1,"\n", square_2, "\n", square_3)
                                        #end of the thrid square
                                        # square_4_target = int(square_1[1][2])+int(square_1[2][2])+int(square_3[1][2])

                                        # for k in permu_list[square_4_target]:
                                        #     if int(square_3[2][2]) in k:
                                        #         #+1 is to compensate for square_3[2][2] which was already appearing in linear
                                        #         if len(linear.tolist()+k) ==  len(set(linear.tolist()+k))+1:

                                        #             square_4_secondrow = k
                                        #             square_4_secondrow_without = square_4_secondrow.copy()
                                        #             square_4_secondrow.remove(int(square_3[2][2]))
                                        #             for l in list(itertools.permutations(square_4_secondrow_without)):
                                        #                 square_4_x = [square_4_target-int(square_3[1][2])-int(square_3[2][2]),square_4_target-int(square_1[1][2])-l[0],square_4_target-int(square_1[2][2])-l[1]]
                                        #                 flag = False
                                        #                 for i in square_4_x:
                                        #                     if i <= 0:
                                        #                         flag = True
                                        #                         break
                                        #                     if i in linear:
                                        #                         flag = True
                                        #                         break
                                        #                 if flag == False:
                                        #                     square_4 = np.array([[square_3[1][2],square_1[2][2],square_1[1][2]],[square_3[2][2],l[0],l[1]],square_4_x])

                                        #                     #starts to filter for right last row
                                        #                     sqaure_4_storage =[]
                                        #                     sqaure_4_storage.append(square_4[2][0]+square_4[2][1]+square_4[2][2])
                                        #                     sqaure_4_storage.append(square_4[0][0]+square_4[1][0]+square_4[2][0])
                                        #                     sqaure_4_storage.append(square_4[0][1]+square_4[1][1]+square_4[2][1])
                                        #                     sqaure_4_storage.append(square_4[0][2]+square_4[1][2]+square_4[2][2])
                                        #                     sqaure_4_storage.append(square_4[0][0]+square_4[1][1]+square_4[2][2])
                                        #                     sqaure_4_storage.append(square_4[0][2]+square_4[1][1]+square_4[2][0])

                                        #                     if len(set(sqaure_4_storage))==1 or (len(set(sqaure_4_storage))==2 and abs(list(set(sqaure_4_storage))[0]-list(set(sqaure_4_storage))[1]) == 1):
                                        #                         perfect.append(square_4)

                                        #                     else:
                                        #                         continue
                                        #                     linear = np.append(linear,square_4_secondrow_without)
                                        #                     linear = np.append(linear,square_4_x)
                                        #                     linear = linear.flatten()

                                        #                     if len(set(linear)) != len(linear):
                                        #                         continue
                                        #                     if 0 in linear:
                                        #                         continue
                                        square_4_target = int(square_1[1][2])+int(square_1[2][2])+int(square_3[1][2])
                                        square_4  = [[square_3[1][2],square_1[2][2],square_1[1][2]],[square_3[2][2]],[square_4_target-int(square_3[1][2])-square_3[2][2]]]
                                        square_4[1].append(square_4_target-int(square_1[1][2])-square_4[2][0])
                                        linear = np.append(linear, square_4[1][1])
                                        linear = np.append(linear, square_4[2][0])
                                        print(square_4)
                                        if len(set(linear.tolist())) == len(linear.tolist()):

                                            print("1 \n", square_1, "2 \n", square_2, "3 \n", square_3, "4 \n", square_4)
                                            on = False
                                        else:
                                            continue
                                        #print("1 \n", square_1, "2 \n", square_2, "3 \n", square_3, "4 \n", square_4)

def main():
    with concurrent.futures.ProcessPoolExecutor() as executor:
        results = [executor.submit(nearlyPerfect) for _ in range(8)]
        for f in concurrent.futures.as_completed(results):
            print(f.result())
if __name__ == '__main__':
    main()


import wave
import random

import cv2
import pyaudio
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import cm

import librosa
import librosa.display

def record(label, num, istrain):
    if(istrain):
        filename = "data/wav/train/{0}/{1}.wav".format(label, num)
    else:
        filename = "data/wav/test/{0}/{1}.wav".format(label, num)

    RATE = 48000
    CHANNELS = 1
    FORMAT = pyaudio.paInt16
    CHUNK = 1024
    REC_TIME=1.5 # 1.5s
    audio = pyaudio.PyAudio()
    stream = audio.open(
        rate=RATE,
        channels=CHANNELS,
        format=FORMAT,
        input=True,
        output=False,
        frames_per_buffer=CHUNK
    )

    numOfData = RATE * REC_TIME

    data_sound = []

    for i in range(0, int(numOfData/CHUNK)):
        data_sound.append(stream.read(CHUNK))

    stream.stop_stream()
    stream.close()
    audio.terminate()

    with wave.open(filename, mode="wb") as wf:
        wf.setnchannels(CHANNELS)
        wf.setframerate(RATE)
        wf.setsampwidth(audio.get_sample_size(FORMAT))
        wf.writeframes(b''.join(data_sound))

def saveasimage(label, num, istrain):
    fig = plt.figure()
    ax = fig.add_subplot(111)
    ax.axis("off")

    if(istrain):
        wavfilepath = "data/wav/train/{0}/{1}.wav".format(label, num)
    else:
        wavfilepath = "data/wav/test/{0}/{1}.wav".format(label, num)

    y, sr = librosa.load(wavfilepath, dtype=np.int16)

    n_fft = 512
    S = np.abs(librosa.stft(y, n_fft=n_fft))

    S_db = librosa.amplitude_to_db(S, ref=np.max)

    min_var = -80
    max_var = 0
    img = librosa.display.specshow(S_db, sr=sr, vmin=min_var, vmax=max_var, cmap=cm.hsv, ax=ax)
    fig.set_tight_layout(True)

    if(istrain):
        imgfilepath = "data/images/train/{0}/{1}.png".format(label, num)
    else:
        imgfilepath = "data/images/test/{0}/{1}.png".format(label, num)

    fig.savefig(imgfilepath, bbox_inches="tight", pad_inches=0)

def main():
    words = ["denki", "tsukete", "keshite", "senpuki", "eakon"]
    counter = [0]*len(words)

    istrain = False
    numOfData = 35
    while True:
        id = random.randint(0,len(words)-1)
        if(sum(counter)//len(words) == numOfData ):
            break

        if(counter[id] < numOfData):
            img = np.full((300, 400, 3), random.randint(0, 255), np.uint8)
            cv2.putText(img, words[id], (100, 100), cv2.FONT_HERSHEY_SIMPLEX, 2.0, (0, 0, 255), thickness=5)
            cv2.imshow("img", img)
            cv2.waitKey(1)

            record(label=words[id], num=counter[id], istrain=istrain)
            saveasimage(label=words[id], num=counter[id], istrain=istrain)
            counter[id] +=1

        print("電気 : {0} つけて : {1} 消して : {2} 扇風機 : {3} エアコン : {4}".format(counter[0], counter[1], counter[2], counter[3], counter[4]))

if __name__ == '__main__':
	main()


def get_run_time_period(run_steps):
  """
  This method finds the time range which covers all the Run_Steps

  :param run_steps: list of Run_Step objects
  :return: tuple of start and end timestamps
  """
  init_ts_start = get_standardized_timestamp('now', None)
  ts_start = init_ts_start
  ts_end = '0'
  for run_step in run_steps:
    if run_step.ts_start and run_step.ts_end:
      if run_step.ts_start < ts_start:
        ts_start = run_step.ts_start
      if run_step.ts_end > ts_end:
        ts_end = run_step.ts_end
  if ts_end == '0':
    ts_end = None
  if ts_start == init_ts_start:
    ts_start = None
  logger.info('get_run_time_period range returned ' + str(ts_start) + ' to ' + str(ts_end))
  return ts_start, ts_end


from os import error
from flask import Flask,jsonify,request
app=Flask(__name__)
task=[
    {
        'id':1,
        'contact':u"123456789",
        'Name':u"Raju",
        'done':False

    },
    {
        'id':2,
        'contact':u"987654321",
        'Name':u"rahul",
        'done':False
    }
]
@app.route("/add-data",methods=["POST"])
def addtask():
    if(not request.json):
        return jsonify({
            'status':'error',
            'message':'please provide data'

        },400)
    task2={
        'id':task[-1]["id"]+1,
        'contact':request.json["contact"],
        'Name':request.json.get("Name",""),
        'done':False
    }
    task.append(task2)
    return jsonify({
        'status':'success',
        'message':'task added'

    })
@app.route("/get-data")
def gettask():
    return jsonify({
        'data':task

        })
if(__name__=="__main__"):
    app.run(debug=True)


from selenium import webdriver
from selenium.webdriver.firefox.options import Options
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from time import sleep
import datetime
import sys
import os

### Dirige le navigateur vers le planning de la classe ###
def go_to_youtube(browser):
    browser.get('https://www.youtube.com/?hl=fr&gl=FR')
    while True:
        try:
            WebDriverWait(browser,10).until(EC.presence_of_element_located((By.ID, "primary")))
            break
        except:
            sleep(3)

### Lance la recherche de vidéo youtube par mots clés ###
def search(browser, mots_cles):
    m_c = mots_cles.replace(" ", "+")
    browser.get('https://www.youtube.com/results?search_query={}'.format(m_c))
    sleep(2)
    while True:
        try:
            WebDriverWait(browser,10).until(EC.presence_of_element_located((By.ID, "button")))
            break
        except:
            sleep(3)

    user_data = browser.find_elements_by_xpath('//*[@id="video-title"]')
    links = []
    titles = []
    for i in user_data:
            links.append(i.get_attribute('href'))
            titles.append(i.get_attribute('title'))
    print(links[0])
    print(links[1])
    print(links[2])
    print(mots_cles)

### Navigation vers Youtube afin de faire notre recherche ###
options = Options()
options.headless = True
browser = webdriver.Firefox(options=options, executable_path=r'/root/geckodriver')
go_to_youtube(browser)
search(browser, sys.argv[1])

### Nettoyage ###
browser.close()
os.system('pkill firefox')


import sys; input = sys.stdin.readline

N = int(input())
s = input().rstrip()
p = 0

for i in range(N):
    m, t = -1, '_'
    for c in "RGB":
        if s.find(c, p)>m:
            m = s.find(c, p)
            t = c
    print(t, end="")
    p = m+1


'''
주어지는 데이터셋을 불러온 뒤 Token화 시키는 코드
'''

from Mydataset import MyDataset
import pickle

class Set_Dataset_to_Token():
    def __init__(self, args):
        super(Set_Dataset_to_Token, self).__init__()

        data_file_path = '%s/%s_dataset.pkl'%(args.data_path, args.dataset)
        with open(data_file_path, "rb") as f:
            self.dataset = pickle.load(f)

        self.model_name = args.model_name

        tokenizer_file_path = '%s/%s_%s.pkl'%(args.model_path, args.model_name, 'tokenizer')

            # Load the model from the file using pickle
        with open(tokenizer_file_path, "rb") as f:
            self.tokenizer = pickle.load(f)

    def forward(self, args, train_eval = None):

        self.train_eval = train_eval

        if train_eval != 'train':
            self.train_eval = 'validation'

        self.datasets = self.dataset[self.train_eval]

            # for line in self.dataset[self.train_eval]:
        idx, linetext, label =  self.datasets['idx'], self.datasets['sentence'], self.datasets['label']
        encoding = self.tokenizer(linetext,
                                add_special_tokens=True,
                                padding= 'max_length',  # 'max_length'
                                max_length= args.max_seq_length,  # args.max_seq_length
                                truncation=True,
                                return_attention_mask=True,
                                return_tensors='pt')  # 왜인지 encoded_plus를 쓰면 버그뜸...
        args.max_seq_length = encoding['input_ids'].shape[1]

        self.data = MyDataset(args, encoding, labels = label)
        # if self.train_eval is not 'test':
        return self.data, linetext
        # else:
        #     return self.data

    def __len__(self):
        return len(self.data)

    # def __getitem__(self, idx):
    #     text, label = self.data[idx]
    #     input_ids = self.tokenizer.encode(text, add_special_tokens=True)
    #     attention_mask = [1] * len(input_ids)
    #     return torch.tensor(input_ids), torch.tensor(attention_mask), torch.tensor(label)


import psycopg2

def connect_db():
    conn = psycopg2.connect(dbname="postgis_test")
    return conn

def get_rows(conn,tablename):
    cur = conn.cursor()
    cur.execute("SELECT * FROM "+tablename+" ;")
    rows = cur.fetchall()
    conn.commit()
    conn.close()
    cur.close()
    return rows

def add_rows(conn,post_id,user_id,post,lat,lon):
    cur = conn.cursor()
   # latlon = "ST_GeomFromText('POINT("+lat+" "+lon+")', 4326)"
    coordinates = "POINT(%s %s)" % (lon, lat)

    #point = ppygis.ST_MakePoint(lat,lon)
    #statement = "INSERT INTO posts (post_id, user_id,post,geom) VALUES (%s, %s, %s, %s)",(post_id,user_id,post,ppygis.ST_GeomFromText(ppygis.ST_MakePoint(point),4326))
    #print statement
    cur.execute("INSERT INTO posts (post_id, user_id,post,geom) VALUES (%s, %s, %s, ST_GeomFromText(%s,4326))",(post_id,user_id,post,coordinates))
    conn.commit()
    conn.close()
    cur.close()

def get_nearest_neighbor(conn,lat,lon):
    cur = conn.cursor()
    coordinates = "POINT(%s %s)" % (lon,lat)

    cur.execute("SELECT ST_X(geom), ST_Y(geom), post,user_id FROM posts WHERE ST_Distance_Sphere(geom, ST_MakePoint(%s,%s)) <= 2 * 1609.34 LIMIT 10",(lon,lat))
    rows = cur.fetchall()
    #print rows
    conn.close()
    cur.close()
    return rows

def get_user_name(conn,user_id):
    cur = conn.cursor()
    cur.execute("SELECT USERNAME FROM USERS WHERE ID ="+str(user_id))
    rows = cur.fetchall()
    #print rows
    conn.close()
    if len(rows)>0:
        return rows[0][0]
    else:
        return ""

#print get_user_name(connect_db(),3)
#print get_nearest_neighbor(connect_db(),34.0220826,-118.2839521)


def post_attachment(session, thread_id, attachments):
    """
    Add a message to a thread
    """
    files = []
    filenames = []
    for attachment in attachments:
        files.append(attachment['file'])
        filenames.append(attachment['filename'])
    message_data = {
        'attachments[]': filenames,
    }

    # POST /api/messages/0.1/threads/{thread_id}/messages/
    endpoint = 'threads/{}/messages'.format(thread_id)
    response = make_post_request(session, endpoint,
                                 form_data=message_data, files=files)
    json_data = response.json()
    if response.status_code == 200:
        return Message(json_data['result'])
    else:
        raise MessageNotCreatedException(message=json_data['message'],
                                         error_code=json_data['error_code'],
                                         request_id=json_data['request_id'])


broi_bitcoins = int(input())
broi_kitaiski_iuana = float(input())
commision = float(input())

bitcoins_to_bgn = broi_bitcoins * 1168
kitaiski_iuana_to_usd = broi_kitaiski_iuana * 0.15
usd_to_bgn = kitaiski_iuana_to_usd * 1.76

total_in_bgn = bitcoins_to_bgn + usd_to_bgn
total_in_eur = total_in_bgn / 1.95

commision = total_in_eur * commision / 100

total_after_commision = total_in_eur - commision
print(f'{total_after_commision:.2f}')


from __future__ import print_function, division

import io
import sys
import struct
import tempfile

if __name__ == '__main__':
    filename = 'dumped-fromstorage.ISP2'
    serial_input = io.open(
        filename,
        mode='rb',
        buffering=io.DEFAULT_BUFFER_SIZE
    )
    outwrapper = tempfile.NamedTemporaryFile(prefix=filename, suffix='.ISP2', delete=False)
    outwrapper.close()
    swapped_output = io.open(outwrapper.name, mode='w+b')
    bytecount = 0
    try:
        while 1:
            inword = serial_input.read(2)
            if len(inword) != 2:
                raise BufferError("Reached end of stream" if len(inword) == 0 else "Lonely byte")
            bytecount = bytecount + 2
            outword = struct.unpack(u'<H', inword)
            swapped_output.write(struct.pack(u'>H', outword[0]))
    except BufferError as oops:
        print(u'Wrote {} bytes to {}'.format(bytecount, outwrapper.name), file=sys.stdout)