#!/usr/bin/env python2

import wx
import os
import ast

class MainWindow(wx.Frame):
  def __init__(self, parent, title):
    self.dirname=''

    # A "-1" in the size parameter instructs wxWidgets to use the default size.
    # In this case, we select 200px width and the default height.
    wx.Frame.__init__(self, parent, title=title, size=(910,700))

    # Setting up the menu.
    filemenu= wx.Menu()
    menuOpen = filemenu.Append(wx.ID_OPEN, "&Open"," Open a file to edit")
    menuSaveAs = filemenu.Append(wx.ID_SAVE, "&SaveAs"," Save a file")
    menuAbout= filemenu.Append(wx.ID_ABOUT, "&About"," Information about this program")
    menuExit = filemenu.Append(wx.ID_EXIT,"E&xit"," Terminate the program")

    # Creating the menubar.
    menuBar = wx.MenuBar()
    menuBar.Append(filemenu,"&File") # Adding the "filemenu" to the MenuBar
    self.SetMenuBar(menuBar)  # Adding the MenuBar to the Frame content.

    # Events for menu
    self.Bind(wx.EVT_MENU, self.OnOpen, menuOpen)
    self.Bind(wx.EVT_MENU, self.OnSaveAs, menuSaveAs)
    self.Bind(wx.EVT_MENU, self.OnExit, menuExit)
    self.Bind(wx.EVT_MENU, self.OnAbout, menuAbout)

    # generate a ScrolledWindow
    self.sWin = wx.ScrolledWindow(self, wx.ID_ANY)
    self.sWin.SetScrollbars(0, 1, 0, 1)
    self.sWin.EnableScrolling(False, True)

    # Statusbar in the bottom of the window
    self.CreateStatusBar()

    #####
    # Following stuff is hardcoded until I figure config files out
    self.OptElements = [["BS_465",[380.,440.],[490.,1800.]],\
                        ["BS_555",[380.,530.],[580.,1800.]],\
                        ["BS_680",[380.,660.],[700.,1800.]],\
                        ["BS_950",[380.,900.],[1000.,1800.]],\
                        ["MI_001",[380.,1800.],[1e99,-1e99]],\
                        ["MI_002",[380.,1800.],[1e99,-1e99]],\
                        ["WI_001",[1e99,-1e99],[380.,1800.]],\
                        ["WI_002",[1e99,-1e99],[380.,1800.]]]
    # Instruments
    self.Instruments = ["VBI", "VTF", "ViSP", "DL-NIRSP"]
    # VBI specific
    self.VBI_cams = 2
    self.VBI_BS  = [[["CL2","R"],["CL2a","R"]],[["CL2","T"],["CL3","R"],["CL3a","T"]]]
    self.VBI_wave = [[393.3, 430.5, 450.4, 486.1], [656.3, 668.4, 705.1, 789.1]]
    self.VBI_modes = {"SingleImage @ 3s" : 10, \
                      "ReconstructedImage @ 3s" : 960}

    # VTF specific
    self.VTF_BS  = [["CL2","T"],["CL3","R"],["CL3a","R"]]
    self.VTF_wave = [525.0, 630.2, 656.3, 854.2]
    self.VTF_modes = {"UnbinnedPolarimetric Mode" : 2880., \
                      "UnbinnedSpectral Mode" : 1920., \
                      "BinnedPolarimetric Mode" : 720., \
                      "BinnedSpectral Mode" : 480., \
                      "Filtergraph Mode" : 960.}

    # ViSP specific
    self.ViSP_cams = 3
    self.VISP_BS = [[["CL2","R"],["CL2a","T"]],[["CL2","R"],["CL2a","T"]],[["CL2","R"],["CL2a","T"]]]
    self.ViSP_modes = {"FastCadence (low pol. precision)" : 211., \
                       "MedCadence (med. pol. precision)" : 27., \
                       "SlowCadence (high pol. precision)" : 9, \
                       "VeryFastCadence (intensity only)" : 528.}

    # DL-NIRSP specific
    self.DLN_cams = 3
    self.DLN_BS  = [[["CL2","T"],["CL3","T"]],[["CL2","T"],["CL3","T"]],[["CL2","T"],["CL3","T"]]]
    self.DLN_wave = [[789.0, 854.2],[1074.7, 1083.0],[1430.0, 1565.0]]
    self.DLN_modes = {"FastCadence (low pol. precision)" : 67., \
                      "MedCadence (med. pol. precision)" : 46., \
                      "SlowCadence (high pol. precision)" : 7.}
    #
    #####

    # Setup the GUI elements
    sizer = wx.GridBagSizer(9, 9)
    rowcount = 0

    self.InstLabels = []
    for i in self.Instruments:
      self.InstLabels.append(wx.StaticText(self.sWin, wx.ID_ANY, label=i, style=wx.ALIGN_LEFT))

    ### VBI
    sizer.Add(self.InstLabels[0], (rowcount, 0), (1,9), wx.ALIGN_CENTER)
    rowcount += 1

    self.VBI_cl = [] # camera labels
    self.VBI_wb = [list() for i in range(self.VBI_cams)] # wavelength check boxes
    self.VBI_ml = [list() for i in range(self.VBI_cams)] # camera mode lists
    self.VBI_pr = [list() for i in range(self.VBI_cams)] # priorities
    priority_label = []                                  # priority label
    # Create the widgets
    for i in range(self.VBI_cams):
      self.VBI_cl.append(wx.StaticText(self.sWin, wx.ID_ANY, label="Camera %i"%(i+1), style=wx.ALIGN_CENTER))
      priority_label.append(wx.StaticText(self.sWin, wx.ID_ANY, label="Priority:", style=wx.ALIGN_RIGHT))
      for j in self.VBI_wave[i]:
        self.VBI_wb[i].append(wx.CheckBox(self.sWin, wx.ID_ANY, label="%i nm"%(j)))
        self.VBI_ml[i].append(wx.ComboBox(self.sWin, wx.ID_ANY, size=(150,25), choices=[a for a in self.VBI_modes], style=wx.CB_DROPDOWN | wx.CB_READONLY))
        self.VBI_pr[i].append(wx.TextCtrl(self.sWin, wx.ID_ANY, value="1", size=(150,25)))
    # Add widgets to window
    for i in range(self.VBI_cams):
      sizer.Add(self.VBI_cl[i], (rowcount,0), (2,1), wx.ALIGN_LEFT)
      sizer.Add(priority_label[i], (rowcount+2,0), (1,1), wx.ALIGN_RIGHT)
      for j in range(len(self.VBI_wave[i])):
        self.VBI_ml[i][j].SetSelection(0)
        sizer.Add(self.VBI_wb[i][j], (rowcount, j+1), (1,1), wx.ALL)
        sizer.Add(self.VBI_ml[i][j], (rowcount+1, j+1), (1,1), wx.ALL)
        sizer.Add(self.VBI_pr[i][j], (rowcount+2, j+1), (1,1), wx.ALL)
      rowcount += 3

    ### VTF
    sizer.Add(self.InstLabels[1], (rowcount, 0), (1,9), wx.ALIGN_CENTER)
    rowcount += 1

    self.VTF_wb = [] # wavelength check box
    self.VTF_ml = [] # camera mode list
    self.VTF_cl = [] # camera label
    self.VTF_pr = [] # priorities
    priority_label = [] # priority label
    # Create the widgets
    self.VTF_cl.append(wx.StaticText(self.sWin, wx.ID_ANY, label="Cameras", style=wx.ALIGN_LEFT))
    priority_label.append(wx.StaticText(self.sWin, wx.ID_ANY, label="Priority:", style=wx.ALIGN_RIGHT))
    for i in self.VTF_wave:
      self.VTF_wb.append(wx.CheckBox(self.sWin, wx.ID_ANY, label="%i nm"%(i)))
      self.VTF_pr.append(wx.TextCtrl(self.sWin, wx.ID_ANY, value="1", size=(150,25)))
    self.VTF_ml.append(wx.ComboBox(self.sWin, wx.ID_ANY, size=(150,25), choices=[a for a in self.VTF_modes], style=wx.CB_DROPDOWN | wx.CB_READONLY)) # indent to allow per wavelength setting
    # Add widgets to window
    sizer.Add(self.VTF_cl[0], (rowcount,0), (2,1), wx.ALL)
    sizer.Add(priority_label[0], (rowcount+2,0), (1,1), wx.ALIGN_RIGHT)
    for i in range(len(self.VTF_wave)):
      sizer.Add(self.VTF_wb[i], (rowcount, i+1), (1,1), wx.ALL)
      sizer.Add(self.VTF_pr[i], (rowcount+2, i+1), (1,1), wx.ALL)
    self.VTF_ml[0].SetSelection(0)                                    # indent & change 0 for i to allow per wavelength setting
    sizer.Add(self.VTF_ml[0], (rowcount+1, 1), (1,4), wx.EXPAND)      # indent & change 0 for i to allow per wavelength setting (and 1->i+1)
    rowcount += 3

    ### ViSP
    sizer.Add(self.InstLabels[2], (rowcount, 0), (1,9), wx.ALIGN_CENTER)
    rowcount += 1

    self.ViSP_wl = [] # wavelength labels
    self.ViSP_cb = [] # camera check box
    self.ViSP_ti = [] # wavelength text input
    self.ViSP_ml = [] # camera mode list
    self.ViSP_pr = [] # priorities
    priority_label = [] # priority label
    # Create the widgets
    for i in range(self.ViSP_cams):
      self.ViSP_wl.append(wx.StaticText(self.sWin, wx.ID_ANY, label="wavelength [nm]:", style=wx.ALIGN_RIGHT))
      self.ViSP_cb.append(wx.CheckBox(self.sWin, wx.ID_ANY, label="Camera %i"%(i+1)))
      self.ViSP_ti.append(wx.TextCtrl(self.sWin, wx.ID_ANY, size=(150,25)))
      self.ViSP_pr.append(wx.TextCtrl(self.sWin, wx.ID_ANY, value="1", size=(150,25)))
      priority_label.append(wx.StaticText(self.sWin, wx.ID_ANY, label="Priority:", style=wx.ALIGN_RIGHT))
    self.ViSP_ml.append(wx.ComboBox(self.sWin, wx.ID_ANY, size=(150,25), choices=[a for a in self.ViSP_modes], style=wx.CB_DROPDOWN | wx.CB_READONLY))
    # Add widgets to window
    for i in range(self.ViSP_cams):
      sizer.Add(self.ViSP_cb[i], (rowcount+i, 0), (1,1), wx.ALL)
      sizer.Add(self.ViSP_wl[i], (rowcount+i, 1), (1,1), wx.ALIGN_RIGHT)
      sizer.Add(self.ViSP_ti[i], (rowcount+i, 2), (1,1), wx.ALL)
      sizer.Add(self.ViSP_pr[i], (rowcount+i, 5), (1,1), wx.ALL)
      sizer.Add(priority_label[i], (rowcount+i,4), (1,1), wx.ALIGN_RIGHT)
    rowcount += self.ViSP_cams
    self.ViSP_ml[0].SetSelection(0)
    sizer.Add(self.ViSP_ml[0], (rowcount, 0), (1,3), wx.EXPAND)
    rowcount += 1

    ### DL-NIRSP
    sizer.Add(self.InstLabels[3], (rowcount, 0), (1,9), wx.ALIGN_CENTER)
    rowcount += 1

    self.DLN_cb = [] # camera check box
    self.DLN_rb = [list() for i in range(self.DLN_cams)] # wavelength radio buttons
    self.DLN_ml = [] # camera mode list
    self.DLN_pr = [] # priorities
    priority_label = [] # priority label
    # Create the widgets
    for i in range(self.DLN_cams):
      self.DLN_cb.append(wx.CheckBox(self.sWin, wx.ID_ANY, label="Camera %i"%(i+1)))
      for j in range(len(self.DLN_wave[i])):
        if j == 0:
          self.DLN_rb[i].append(wx.RadioButton(self.sWin, wx.ID_ANY, label="%i nm"%(self.DLN_wave[i][j]), style=wx.RB_GROUP))
        else:
          self.DLN_rb[i].append(wx.RadioButton(self.sWin, wx.ID_ANY, label="%i nm"%(self.DLN_wave[i][j])))
      self.DLN_pr.append(wx.TextCtrl(self.sWin, wx.ID_ANY, value="1", size=(150,25)))
      priority_label.append(wx.StaticText(self.sWin, wx.ID_ANY, label="Priority:", style=wx.ALIGN_RIGHT))
    self.DLN_ml.append(wx.ComboBox(self.sWin, wx.ID_ANY, size=(150,25), choices=[a for a in self.DLN_modes], style=wx.CB_DROPDOWN | wx.CB_READONLY))
    # Add widgets to window
    for i in range(self.DLN_cams):
      sizer.Add(self.DLN_cb[i], (rowcount+i, 0), (1,1), wx.ALL)
      for j in range(len(self.DLN_wave[i])):
        sizer.Add(self.DLN_rb[i][j], (rowcount+i, j+1), (1,1), wx.ALL)
      sizer.Add(self.DLN_pr[i], (rowcount+i, 5), (1,1), wx.ALL)
      sizer.Add(priority_label[i], (rowcount+i,4), (1,1), wx.ALIGN_RIGHT)
    rowcount += self.DLN_cams
    self.DLN_ml[0].SetSelection(0)
    sizer.Add(self.DLN_ml[0], (rowcount, 0), (1,4), wx.EXPAND)
    rowcount += 1

    # Analyze button
    analyze = wx.Button(self.sWin, wx.ID_ANY, label="Analyze Configuration")
    sizer.Add(analyze, (rowcount+1,0), (1,6), wx.EXPAND)
    self.Bind(wx.EVT_BUTTON, self.OnAnalyze, analyze)
    rowcount += 1

    self.sWin.SetSizerAndFit(sizer)
    self.Centre()

  def OnAbout(self,e):
    # Create a message dialog box
    dlg = wx.MessageDialog(self, "Daniel K. Inouye Solar Telescope\n\nInstrument Configuration Analyzer\n\n\nBrought to you by:\nRoberto Cassini\nHector Socas-Navarro\nFriedrich Woeger\n\nExtended Python Implementation:\nFriedrich Woeger", "About this program", wx.OK)
    dlg.ShowModal() # Shows it
    dlg.Destroy() # finally destroy it when finished.

  def OnExit(self,e):
    self.Close(True)  # Close the frame.

  def OnOpen(self,e):
    """ Open a file"""
    dlg = wx.FileDialog(self, "Open Config file", "", "",\
          "cfg files (*.cfg)|*.cfg", wx.FD_OPEN | wx.FD_FILE_MUST_EXIST)
    if dlg.ShowModal() == wx.ID_OK:
      self.filename = dlg.GetFilename()
      self.dirname = dlg.GetDirectory()
      f = open(os.path.join(self.dirname, self.filename), 'r')
      # read the Configuration and convert to a list
      fileinput = f.read()
      Configuration = ast.literal_eval(fileinput)
      f.close()
      # apply the list to widgets
      self.ApplyConfiguration(Configuration)
    dlg.Destroy()

  def OnSaveAs(self,e):
    """ Open a file"""
    dlg = wx.FileDialog(self, "Save Config file as", "", "untitled.cfg", \
          "cfg files (*.cfg)|*.cfg", wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT)
    if dlg.ShowModal() == wx.ID_OK:
      self.filename = dlg.GetFilename()
      self.dirname = dlg.GetDirectory()
      f = open(os.path.join(self.dirname, self.filename), 'w')
      # Get & Write the Configuration
      Configuration = self.CreateConfiguration()
      f.write("%s"%(Configuration))
      f.close()
    dlg.Destroy()

  def OnAnalyze(self,e):
    # Read configuration from GUI
    Configuration = self.CreateConfiguration()
    try:
      # go on to compute feasibility
      analyzedConfiguration = self.ComputeConfig(Configuration)
      # now display the results
      self.GenerateSummary(analyzedConfiguration[0], analyzedConfiguration[1])
    except:
      # print error message
      self.ErrorMsg("Did you activate any instrument camera for evaluation?")
      return

  def ErrorMsg(self, text):
    dlg = wx.MessageDialog(self, text, "Error", wx.OK)
    dlg.ShowModal() # Shows it
    dlg.Destroy()   # finally destroy it when finished.

  def CreateConfiguration(self):
    OutPutConfiguration = []
    # OutPutConfiguration will be a vector of input configurations for
    # individual instrument cameras. The structure is a such:
    # [
    #   [
    #    InsCamName,
    #    [BeamSplitters as seen by cameras (see above)],
    #    [selected wavelengths],
    #    [data rate (set by selected mode) for each wavelength],
    #    [priority for each wavelength]
    #   ],
    #   ...next camera...
    # ]

    # some variables
    CamConfiguration = []
    CamWavelengths = []
    CamPriority = []
    CamModes = []
    CamModesRate = []

    # get info for VBI
    for i in range(self.VBI_cams):
      for j in range(len(self.VBI_wave[i])):
        if self.VBI_wb[i][j].GetValue():
          CamWavelengths.append(self.VBI_wave[i][j])
          CamModes.append(self.VBI_ml[i][j].GetStringSelection())
          CamPriority.append(float(self.VBI_pr[i][j].GetLineText(0)))
      if CamWavelengths != []:
        CamConfiguration.append("VBI%i"%(i+1))
        CamConfiguration.append(list(self.VBI_BS[i]))
        CamConfiguration.append(list(CamWavelengths))
        for mod in CamModes:
          CamModesRate.append(self.VBI_modes[mod])
        CamConfiguration.append(list(CamModesRate))
        CamConfiguration.append(list(CamPriority))
        #####
        OutPutConfiguration.append(CamConfiguration)
      CamConfiguration = []
      CamWavelengths = []
      CamPriority = []
      CamModes = []
      CamModesRate = []

    # get info for VTF
    for j in range(len(self.VTF_wave)):
      if self.VTF_wb[j].GetValue():
        CamWavelengths.append(self.VTF_wave[j])
        CamModes.append(self.VTF_ml[0].GetStringSelection())       # change 0 for j to allow per wavelength setting
        CamPriority.append(float(self.VTF_pr[j].GetLineText(0)))
    if CamWavelengths != []:
      CamConfiguration.append("VTF")
      CamConfiguration.append(list(self.VTF_BS))
      CamConfiguration.append(list(CamWavelengths))
      for mod in CamModes:
        CamModesRate.append(self.VTF_modes[mod])
      CamConfiguration.append(list(CamModesRate))
      CamConfiguration.append(list(CamPriority))
      #####
      OutPutConfiguration.append(CamConfiguration)
    CamConfiguration = []
    CamWavelengths = []
    CamPriority = []
    CamModes = []
    CamModesRate = []

    # get info for ViSP
    for i in range(self.ViSP_cams):
      if self.ViSP_cb[i].GetValue():
        try:
          CamWavelengths.append(float(self.ViSP_ti[i].GetLineText(0)))
        except:
          self.ErrorMsg("Did you enter a value in the activated ViSP wavelength field?")
        CamModes.append(self.ViSP_ml[0].GetStringSelection())
        CamPriority.append(float(self.ViSP_pr[i].GetLineText(0)))
      if CamWavelengths != []:
        CamConfiguration.append("ViSP%i"%(i+1))
        CamConfiguration.append(list(self.VISP_BS[i]))
        CamConfiguration.append(list(CamWavelengths))
        for mod in CamModes:
          CamModesRate.append(self.ViSP_modes[mod])
        CamConfiguration.append(list(CamModesRate))
        CamConfiguration.append(list(CamPriority))
        #####
        OutPutConfiguration.append(CamConfiguration)
      CamConfiguration = []
      CamWavelengths = []
      CamPriority = []
      CamModes = []
      CamModesRate = []

    # get info for DL-NIRSP
    for i in range(self.DLN_cams):
      if (self.DLN_cb[i].GetValue()):
        for j in range(len(self.DLN_wave[i])):
          if self.DLN_rb[i][j].GetValue():
            CamWavelengths.append(self.DLN_wave[i][j])
            CamModes.append(self.DLN_ml[0].GetStringSelection())
            CamPriority.append(float(self.DLN_pr[i].GetLineText(0)))
      if CamWavelengths != []:
        CamConfiguration.append("DLN%i"%(i+1))
        CamConfiguration.append(list(self.DLN_BS[i]))
        CamConfiguration.append(list(CamWavelengths))
        for mod in CamModes:
          CamModesRate.append(self.DLN_modes[mod])
        CamConfiguration.append(list(CamModesRate))
        CamConfiguration.append(list(CamPriority))
        #####
        OutPutConfiguration.append(CamConfiguration)
      CamConfiguration = []
      CamWavelengths = []
      CamPriority = []
      CamModes = []
      CamModesRate = []

    return OutPutConfiguration

  def ApplyConfiguration(self, Configuration):
    # take Configuration and set widgets up
    for cfg in Configuration:
      if "VBI" in cfg[0]:
        for i in range(self.VBI_cams):
          # camera requested?
          if str(i+1) in cfg[0]:
            # clear checkboxes
            for j in range(len(self.VBI_wb[i])):
              self.VBI_wb[i][j].SetValue(False)
            # number of wavelength, weights & modes should be the same
            for num in range(len(cfg[2])):
              for j in range(len(self.VBI_wave[i])):
                if cfg[2][num] == self.VBI_wave[i][j]:
                  # set checkbox
                  self.VBI_wb[i][j].SetValue(True)
                  # set mode
                  idx1 = list(self.VBI_modes.values()).index(cfg[3][num])
                  idx2 = self.VBI_ml[i][j].FindString(list(self.VBI_modes.keys())[idx1])
                  self.VBI_ml[i][j].SetSelection(idx2)
                  # set priorities
                  self.VBI_pr[i][j].Clear()
                  self.VBI_pr[i][j].SetValue(str(cfg[4][num]))
      elif "VTF" in cfg[0]:
        # clear checkboxes
        for j in range(len(self.VTF_wb)):
          self.VTF_wb[j].SetValue(False)
        # number of wavelength, weights & modes should be the same
        for num in range(len(cfg[2])):
          for j in range(len(self.VTF_wave)):
            if cfg[2][num] == self.VTF_wave[j]:
              # set checkbox
              self.VTF_wb[j].SetValue(True)
              # set mode
              idx1 = list(self.VTF_modes.values()).index(cfg[3][num])
              idx2 = self.VTF_ml[0].FindString(list(self.VTF_modes.keys())[idx1]) # change 0 to j to allow for setting per wavelength
              self.VTF_ml[0].SetSelection(idx2)                                   # change 0 to j to allow for setting per wavelength
              # set priority
              self.VTF_pr[j].Clear()
              self.VTF_pr[j].SetValue(str(cfg[4][num]))
      elif "ViSP" in cfg[0]:
        for i in range(self.ViSP_cams):
          # camera requested?
          if str(i+1) in cfg[0]:
            # clear checkbox
            self.ViSP_cb[i].SetValue(False)
            # number of wavelength & weights should be the same (one element)
            for num in range(len(cfg[2])):
              # set checkbox
              self.ViSP_cb[i].SetValue(True)
              # set wavelength
              self.ViSP_ti[i].Clear()
              self.ViSP_ti[i].SetValue(str(cfg[2][num]))
              # set priority
              self.ViSP_pr[i].Clear()
              self.ViSP_pr[i].SetValue(str(cfg[4][num]))
              # set mode
              idx1 = list(self.ViSP_modes.values()).index(cfg[3][num])
              idx2 = self.ViSP_ml[0].FindString(list(self.ViSP_modes.keys())[idx1])
              self.ViSP_ml[0].SetSelection(idx2)
      elif "DLN" in cfg[0]:
        for i in range(self.DLN_cams):
          # camera requested?
          if str(i+1) in cfg[0]:
            # clear checkbox
            self.DLN_cb[i].SetValue(False)
            # number of wavelength & weights should be the same (one element)
            for num in range(len(cfg[2])):
              # set wavelength
              for j in range(len(self.DLN_wave[i])):
                if cfg[2][num] == self.DLN_wave[i][j]:
                  self.DLN_rb[i][j].SetValue(True)
              # set checkbox
              self.DLN_cb[i].SetValue(True)
              # set priority
              self.DLN_pr[i].Clear()
              self.DLN_pr[i].SetValue(str(cfg[4][num]))
              # set mode
              idx1 = list(self.DLN_modes.values()).index(cfg[3][num])
              idx2 = self.DLN_ml[0].FindString(list(self.DLN_modes.keys())[idx1])
              self.DLN_ml[0].SetSelection(idx2)

  def ComputeConfig(self, Configuration):
    aConfiguration = list(Configuration)
    # aConfiguration is now a vector of input configurations for
    # individual instrument cameras. The structure is a such:
    # [
    #   [
    #    InsCamName,
    #    [BeamSplitters as seen by cameras (see above)],
    #    [selected wavelengths],
    #    [data rate (set by selected mode) for each wavelength],
    #    [priority for each wavelength],
    #    [[[success/fail for each wavelength], [[lambdamin,lambdamax], ...]]] # for each viable unique and optimal configuration
    #   ],
    #   ...next camera...
    # ]

    # Metric Variable
    merit_global = 0

    # Equip the Coude locations with the Optical Elements (only one of each)
    for CL2 in self.OptElements:
      for CL2a in self.OptElements:
        if (CL2a[0] != CL2[0]):
          for CL3 in self.OptElements:
            if (CL3[0] != CL2a[0] and CL3[0] != CL2[0]):
              for CL3a in self.OptElements:
                if (CL3a[0] != CL3[0] and CL3a[0] != CL2a[0] and CL3a[0] != CL2[0]):
                  # local merit
                  merit_local = 0
                  # loop through requested camera configurations
                  for cfg in Configuration:
                    # loop through coude locations as seen by the individual cameras
                    # establish therby the 'seen' wavelength range
                    lambdamin = -1e99
                    lambdamax =  1e99
                    for ele in cfg[1]:
                      if (ele[0] == "CL2"):
                        if (ele[1] == "R"):
                          lambdamin = max(CL2[1][0], lambdamin)
                          lambdamax = min(CL2[1][1], lambdamax)
                        elif (ele[1] == "T"):
                          lambdamin = max(CL2[2][0], lambdamin)
                          lambdamax = min(CL2[2][1], lambdamax)
                      if (ele[0] == "CL2a"):
                        if (ele[1] == "R"):
                          lambdamin = max(CL2a[1][0], lambdamin)
                          lambdamax = min(CL2a[1][1], lambdamax)
                        elif (ele[1] == "T"):
                          lambdamin = max(CL2a[2][0], lambdamin)
                          lambdamax = min(CL2a[2][1], lambdamax)
                      if (ele[0] == "CL3"):
                        if (ele[1] == "R"):
                          lambdamin = max(CL3[1][0], lambdamin)
                          lambdamax = min(CL3[1][1], lambdamax)
                        elif (ele[1] == "T"):
                          lambdamin = max(CL3[2][0], lambdamin)
                          lambdamax = min(CL3[2][1], lambdamax)
                      if (ele[0] == "CL3a"):
                        if (ele[1] == "R"):
                          lambdamin = max(CL3a[1][0], lambdamin)
                          lambdamax = min(CL3a[1][1], lambdamax)
                        elif (ele[1] == "T"):
                          lambdamin = max(CL3a[2][0], lambdamin)
                          lambdamax = min(CL3a[2][1], lambdamax)
                    for wave in range(len(cfg[2])):
                      if (float(cfg[2][wave]) >= lambdamin and \
                          float(cfg[2][wave]) <= lambdamax):
                        merit_local += cfg[4][wave]
                  if merit_global < merit_local:
                    merit_global = merit_local
                    OptConfig = []
                    OptConfig = [[CL2,CL2a,CL3,CL3a]]
                  elif (merit_local > 0 and merit_global == merit_local):
                    OptConfig.append([CL2,CL2a,CL3,CL3a])

    # list capturing the results for each optimal configuration
    result = [list() for i in range(len(Configuration))]
    # Go through all viable configurations that are unique
    for ocfg in OptConfig:
      # loop through coude optical elements as seen by the individual cameras
      # establish therby the 'seen' wavelength range
      for cfg in range(len(Configuration)):
        lambdamin = -1e99
        lambdamax =  1e99
        for ele in Configuration[cfg][1]:
          if (ele[0] == "CL2"):
            if (ele[1] == "R"):
              lambdamin = max(ocfg[0][1][0], lambdamin)
              lambdamax = min(ocfg[0][1][1], lambdamax)
            elif (ele[1] == "T"):
              lambdamin = max(ocfg[0][2][0], lambdamin)
              lambdamax = min(ocfg[0][2][1], lambdamax)
          if (ele[0] == "CL2a"):
            if (ele[1] == "R"):
              lambdamin = max(ocfg[1][1][0], lambdamin)
              lambdamax = min(ocfg[1][1][1], lambdamax)
            elif (ele[1] == "T"):
              lambdamin = max(ocfg[1][2][0], lambdamin)
              lambdamax = min(ocfg[1][2][1], lambdamax)
          if (ele[0] == "CL3"):
            if (ele[1] == "R"):
              lambdamin = max(ocfg[2][1][0], lambdamin)
              lambdamax = min(ocfg[2][1][1], lambdamax)
            elif (ele[1] == "T"):
              lambdamin = max(ocfg[2][2][0], lambdamin)
              lambdamax = min(ocfg[2][2][1], lambdamax)
          if (ele[0] == "CL3a"):
            if (ele[1] == "R"):
              lambdamin = max(ocfg[3][1][0], lambdamin)
              lambdamax = min(ocfg[3][1][1], lambdamax)
            elif (ele[1] == "T"):
              lambdamin = max(ocfg[3][2][0], lambdamin)
              lambdamax = min(ocfg[3][2][1], lambdamax)
        # prepare for output
        feasibility  = []
        for wave in Configuration[cfg][2]:
          if (float(wave) >= lambdamin and float(wave) <= lambdamax):
            feasibility.append(1)
          else:
            feasibility.append(0)
        result[cfg].append([feasibility,[lambdamin,lambdamax]])

    ###
    # Reorder OptConfig and result to be lists of unique optimal configurations
    # by multiplexing non-unique ones, i.e. combine the ones that lead to the
    # same successful light distribution in each channel
    ###
    # initialize the list of unique and non-unique feasible Optical Coude Configurations
    # the first entry is always unique
    uniqueOptConfig = [[OptConfig[0]]]
    uniqueFeas = [[[res[0][0],[res[0][1]]]] for res in result]
    # loops to determine wavelength unique and non-unique Optical Coude Configurations
    # (only if there is more than one, of course)
    if (len(OptConfig) > 1):
      for i in range(1, len(OptConfig)):
        # compare
        for j in range(len(uniqueOptConfig)):
          for k in range(len(result)):
            if result[k][i][0] == uniqueFeas[k][j][0]:
              uFlag = True
            else:
              uFlag = False
          # multiplex (to the right position), if non-unique
          if uFlag:
            uniqueOptConfig[j].append(OptConfig[i])
            for k in range(len(result)):
              uniqueFeas[k][j][1].append(result[k][i][1])
            break
        # add if unique
        if (uFlag == False):
          uniqueOptConfig.append([OptConfig[i]])
          for k in range(len(result)):
            uniqueFeas[k].append([result[k][i][0],[result[k][i][1]]])

    for cfg in range(len(aConfiguration)):
      aConfiguration[cfg].append(uniqueFeas[cfg])

    return [aConfiguration, uniqueOptConfig]

  def GenerateSummary(self, aConfiguration, uOptConfig):
    result = "="*65+"\n"
    result += "The following Coude Optics configurations [CL2, CL2a, CL3, CL3a] deliver the highest ranking:\n"
    result += "="*65+"\n"

    for h in range(len(uOptConfig)):
      aBwidth = 0                             # aggregate Bandwidth
      for uocfg in uOptConfig[h]:
        result+= "["+uocfg[0][0]+","+uocfg[1][0]+","+\
                     uocfg[2][0]+","+uocfg[3][0]+"]; "
      result += "\n\n"
      for cfg in aConfiguration:
        # test if the wavelength was feasible, compute rate
        bWidth = 0
        tstr1="success: "
        tstr2="fail:    "
        for j in range(len(cfg[5][h][0])):
          if (cfg[5][h][0][j] == 1):
            if (bWidth < cfg[3][j]):
              bWidth = cfg[3][j]
            tstr1 += "%i; "%(cfg[2][j])
          else:
            tstr2 += "%i; "%(cfg[2][j])
        aBwidth += bWidth
        if (cfg[5][h][1][0][1] > cfg[5][h][1][0][0]):
          result+="::"+cfg[0]+":: waverange [nm]: [%i"%(cfg[5][h][1][0][0])+",%i]"%(cfg[5][h][1][0][1])+"\n"
          result+="-----> Max. Data Rate (successful diagnostics): %i MB/s\n"%(bWidth)
        else:
          result+="::"+cfg[0]+":: Channel receives no light!\n"
        result+= "     "+tstr1+"\n"
        result+= "     "+tstr2+"\n"
      result+="\nAggregate Bandwidth (max. 3500-4000 MB/s): %i MB/s\n"%(aBwidth)
      result += "="*65+"\n"

    # dlg = wx.MessageDialog(self, result, caption="Result of Analysis")
    dlg = outputDialog(None, title="Result of Analysis", message=result)
    dlg.ShowModal() # Shows it
    dlg.Destroy() # finally destroy it when finished.

class outputDialog(wx.Dialog):
  def __init__(self, *args, **kw):
    # save the value of the message keyword, if it exists.
    # remove the keyword before going on to the single inheritance super()
    if "message" in kw:
      self.message = kw["message"]
      kw = {key: value for key, value in kw.items() if key is not "message"}
    super(outputDialog, self).__init__(*args, **kw)
    self.outputWin()

  def outputWin(self):
    t = wx.TextCtrl(self, size=(800,600), style=wx.TE_MULTILINE | wx.TE_READONLY)
    ds= t.GetDefaultStyle()
    ds.SetFontSize(9)
    ds.SetFontFamily(wx.FONTFAMILY_MODERN)
    t.SetDefaultStyle(ds)
    t.WriteText(self.message)

    saveButton = wx.Button(self, label="Save")
    saveButton.Bind(wx.EVT_BUTTON, self.OnSave)
    exitButton = wx.Button(self, label="Exit")
    exitButton.Bind(wx.EVT_BUTTON, self.OnExit)

    sizer = wx.GridBagSizer(10, 10)
    sizer.Add(t, pos=(0,0), span=(9,10), flag=wx.EXPAND | wx.ALIGN_CENTER)
    sizer.Add(saveButton, pos=(9,7), span=(1,1), flag=wx.ALIGN_RIGHT)
    sizer.Add(exitButton, pos=(9,8), span=(1,1), flag=wx.ALIGN_RIGHT)

    sizer.RecalcSizes()
    self.SetSizerAndFit(sizer)

  def OnExit(self, event):
    self.Close(True)  # Close the frame.

  def OnSave(self, event):
    """ Open a file"""
    dlg = wx.FileDialog(self, "Save Config file as", "", "untitled.txt", \
          "txt files (*.txt)|*.txt", wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT)
    if dlg.ShowModal() == wx.ID_OK:
      self.filename = dlg.GetFilename()
      self.dirname = dlg.GetDirectory()
      f = open(os.path.join(self.dirname, self.filename), 'w')
      # Write the Output
      f.write(self.message)
      f.close()
    dlg.Destroy()

class DKISTApp(wx.App):
  def OnInit(self):
    frame = MainWindow(None, "DKIST")
    frame.Show(True)
    self.SetTopWindow(frame)
    return True

def calc():
  app = DKISTApp(0)
  app.MainLoop()

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


from pyspark import SparkContext, SparkConf

conf = SparkConf().setAppName("part").setMaster("local[*]")
sc = SparkContext(conf = conf)

def Func(lines):

    lines = lines.split("|")
    return  lines[2],lines[3]

def Funcc(lines):

    lines = lines.split("|")
    return  lines[3],float(lines[7])

text = sc.textFile("part.tbl")
text1 = text.map(Func)
text2 = text.map(Funcc)

sort1 = text1.distinct().sortBy(lambda x:x[0], ascending=True).sortBy(lambda y:y[1], ascending = True)
sort2 = text2.sortBy(lambda x:x[0], ascending=True)
price = sort2.reduceByKey(lambda x,y: x+y).collect()

original_text = sort1.collect()
count_by_key = sort2.countByKey()

print("Manufacturer and Brands:")
for line in original_text:
    print(line)

print("Number of Items of each Brand")
print(count_by_key)

print("Total Sale Price of each Brand")
print(price)


#    This script is part of pyroglancer (https://github.com/SridharJagannathan/pyroglancer).
#    Copyright (C) 2020 Sridhar Jagannathan
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.

"""Module contains functions to handle mesh data."""

from cloudvolume import CloudVolume
from cloudvolume import Mesh
import json
import navis
import numpy as np
import os

def _generate_mesh(x):
    """Generate mesh (of cloudvolume class) for given navis volume.

    Parameters
    ----------
    x :             Navis Volume

    Returns
    -------
    mesh :      Cloud volume mesh
    """
    mesh = Mesh(segid=x.id, vertices=x.vertices, faces=x.faces)

    return mesh

def to_ngmesh(x):
    """Generate mesh (of cloudvolume class) for given volume.

    Parameters
    ----------
    volume :             Navis Volume | List

    Returns
    -------
    mesh :      Cloud volume mesh
    """
    volumeidlist, volumedatasource, volumenamelist = ([] for i in range(3))

    if not isinstance(x, list):
        x = [x]

    if all(isinstance(volume, navis.core.volumes.Volume) for volume in x):
        for volumeelement in x:
            volumedata = _generate_mesh(volumeelement)
            volumedata.segid = volumeelement.id
            volumedatasource.append(volumedata)
            volumeidlist.append(volumeelement.id)
            volumenamelist.append(volumeelement.name)

    return volumedatasource, volumeidlist, volumenamelist

def _to_precomputed(mesh):
    """Convert mesh to precomputed format."""
    vertex_index_format = [np.uint32(mesh.vertices.shape[0]),
                           mesh.vertices, mesh.faces]

    return b''.join([array.tobytes('C') for array in vertex_index_format])

def uploadmeshes(volumedatasource, volumeidlist, volumenamelist, path, layer_name):
    """Upload mesh (of cloudvolume class) to a local server.

    Parameters
    ----------
    volumedatasource :     List containing cloud volume meshes
    volumeidlist :    List containing the segids(volume id)
    volumenamelist :   List containing the names of volumes
    path :           path to the local data server
    layer_name:      name of layer/path to add to

    Returns
    -------
    cv :     cloudvolume class object
    """
    info = {"@type": "neuroglancer_legacy_mesh",
            'scales': [1, 1, 1],
            }
    path = 'file://' + path + '/precomputed/' + layer_name
    cv = CloudVolume(path, info=info)

    cv.mesh.meta.info['@type'] = 'neuroglancer_legacy_mesh'
    cv.mesh.meta.info['segment_name_map'] = 'segment_names'
    cv.mesh.meta.info['segment_properties'] = 'segment_properties'
    cv.mesh.meta.commit_info()

    files = [os.path.join(cv.mesh.meta.mesh_path, str(vol.segid)) for vol in volumedatasource]
    volumeids = [str(vol.segid) for vol in volumedatasource]

    for fileidx in range(len(files)):
        fullfilepath = str(files[fileidx])  # files[fileidx]
        print(files[fileidx])
        fullfilepath = os.path.join(cv.basepath, os.path.basename(path), fullfilepath)
        uploadvol = Mesh(
            vertices=volumedatasource[fileidx].vertices, faces=volumedatasource[fileidx].faces,
            segid=None)
        precomputed_mesh = _to_precomputed(uploadvol)
        print('Seg id is:', str(volumeids[fileidx]))
        print('Full filepath:', fullfilepath)
        with open(fullfilepath, 'wb') as f:
            f.write(precomputed_mesh)

        manifestinfo = {
            "fragments": [str(volumeids[fileidx])]}
        manifestfilepath = str(files[fileidx]) + ':' + str(0)  # files[fileidx]
        manifestfilepath = os.path.join(cv.basepath, os.path.basename(path), manifestfilepath)
        with open(manifestfilepath, 'w') as f:
            json.dump(manifestinfo, f)

    # create the file for segment_properties
    allvolproplist = {"id": "label",
                      "type": "label",
                      "values": volumenamelist}

    volinfo = {"@type": "neuroglancer_segment_properties",
               "inline": {"ids": list(map(str, volumeidlist)),
                          "properties": [allvolproplist]}}
    volfilepath = os.path.join(cv.basepath, os.path.basename(path), os.path.join(cv.mesh.meta.mesh_path),
                               'segment_properties')
    if not os.path.exists(volfilepath):
        os.makedirs(volfilepath)
        print('creating:', volfilepath)
    volinfofile = os.path.join(volfilepath, 'info')
    with open(volinfofile, 'w') as volinfofile:
        json.dump(volinfo, volinfofile)

    # create the file for segment_names
    volumenamedict = dict(zip(map(str, volumeidlist), volumenamelist))
    volnamemap = {"@type": "neuroglancer_segment_name_map",
                  "map": volumenamedict}
    volnamefilepath = os.path.join(cv.basepath, os.path.basename(path), os.path.join(cv.mesh.meta.mesh_path),
                                   'segment_names')
    if not os.path.exists(volnamefilepath):
        os.makedirs(volnamefilepath)
        print('creating:', volnamefilepath)
    volnamemapfile = os.path.join(volnamefilepath, 'info')
    with open(volnamemapfile, 'w') as volnamemapfile:
        json.dump(volnamemap, volnamemapfile)


from flask import Flask, request
from twilio.twiml.messaging_response import MessagingResponse
import serial
app = Flask(__name__)
ser = serial.Serial('/dev/ttyACM0')
@app.route("/sms", methods=['GET', 'POST'])
def sms_ahoy_reply():
    """Respond to incoming messages with a friendly SMS."""
    # Start our response
    resp = MessagingResponse()
    messageBody = request.form['Body']
    listOfWords = messageBody.split()
    print(listOfWords)
    i = 0
    while i < len(listOfWords):
      sendMePls(listOfWords[i], listOfWords[i+1])
      print('{0}, {1} :'.format(listOfWords[i], listOfWords[i+1]))
      i+=2

    messageReply = 'Succ'
    # Add a message
    resp.message(messageReply)

    return str(resp)

def sendMePls(arg1, arg2):
   arg1 = arg1.lower()
   if arg1 == 'forward':
      ser.write(bytearray([0, int(arg2)]))
      print('{1},{0}'.format(arg1, arg2))
   elif arg1 == 'back':
      ser.write(bytearray([1, int(arg2)]))
      print('{1},{0}'.format(arg1, arg2))
   elif arg1 == 'left':
      ser.write(bytearray([3, int(arg2)]))
      print('{1},{0}'.format(arg1, arg2))
   elif arg1 == 'right':
      ser.write(bytearray([2, int(arg2)]))
      print('{1},{0}'.format(arg1, arg2))
   elif arg1 == 'lift':
      ser.write(bytearray([5, int(arg2)]))
      print('{1},{0}'.format(arg1, arg2))
   elif arg1 == 'grab':
      ser.write(bytearray([4, int(arg2)]))
      print('{1},{0}'.format(arg1, arg2))
   return

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


from django.http import HttpResponse
from django.shortcuts import render
from rango.models import Category
from rango.models import Page
from rango.forms import CategoryForm
from rango.forms import PageForm

def index(request):
    category_list = Category.objects.order_by('-likes')[:5]
    page_list = Page.objects.order_by('-views')[:5]

    context_dict = {'categories':category_list,'pages':page_list}
    return render(request, 'rango/index.html', context=context_dict)

def about(request):
    print(request.method)
    print(request.user)
    return render(request,'rango/about.html',{})

def show_category(request,category_name_slug):
    # 创建上下文字典，稍后传给模板渲染引擎
    context_dict = {}

    try:
        # 能通过传入的分类别名找到对应的分类吗？
        # 如果找不到，.get() 方法抛出 DoesNotExist 异常
        # 因此 .get() 方法返回一个模型实例或抛出异常
        category = Category.objects.get(slug=category_name_slug)
        # 检索关联的所有网页
        # 注意，filter() 返回一个网页对象列表或空列表
        pages = Page.objects.filter(category=category)

        # 把得到的列表赋值给模板上下文中名为 pages 的键
        context_dict['pages'] = pages
        # 也把从数据库中获取的 category 对象添加到上下文字典中
        # 我们将在模板中通过这个变量确认分类是否存在
        context_dict['category'] = category
    except Category.DoesNotExist:
        # 没找到指定的分类时执行这里
        # 什么也不做
        # 模板会显示消息，指明分类不存在
        context_dict['category'] = None
        context_dict['pages'] = None
    # 渲染响应，返回给客户端
    return render(request, 'rango/category.html', context_dict)

def add_category(request):
    form = CategoryForm()
    if request.method == 'POST':
        form = CategoryForm(request.POST)
        if form.is_valid():
            form.save(commit=True)
            return index(request)
    else:
        print(form.errors)
    return render(request, 'rango/add_category.html', {'form': form})

def add_page(request,category_name_slug):
    try:
        category = Category.objects.get(slug=category_name_slug)
    except Category.DoesNotExist:
        category = None

    form = PageForm()
    if request.method == 'POST':
        form = PageForm(request.POST)
        if form.is_valid():
            if category:
                page = form.save(commit=False)
                page.category = category
                Page.views = 0
                page.save()
                return show_category(request,category_name_slug)

        else:
            print(form.errors)

    context_dict = {'form':form,'category':category}
    return render(request,'rango/add_page.html',context_dict)


# -*- coding: utf-8 -*-
# This repo is licensed under the Apache License, Version 2.0 (the "License")
#
# Copyright (c) 2014-2021 Megvii Inc. All rights reserved.
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT ARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
from megengine.data.dataset import COCO, Objects365, PascalVOC

data_mapper = dict(
    coco=COCO,
    objects365=Objects365,
    voc=PascalVOC,
)


# Create your views here.
from django.conf.urls import url,include
from django.contrib import admin
from . import views

urlpatterns = [

    url(r'^$' , views.home, name = 'homescreen'),
    url(r'^home/$' , views.loggedin, name = 'loggedin'),
    url(r'^timestamp/$' , views.timestamp, name = 'timestamp'),
url(r'^assignwork/$' , views.assignwork, name = 'assignwork'),
url(r'^assigned_work/$' , views.assignedwork, name = 'assignedwork'),
url(r'^loggout/$' , views.loggout, name = 'loggout'),
# url(r'^work/(?P<text_id>[0-9]+)/$', views.text_append, name=''),
url(r'^work/$' , views.work, name = 'work'),
]


import asyncio
import time
import concurrent.futures as cf
import random

async def func():
    #async def func(n):
    #return [n ** i for i in range(2,22,2)]
    return [random.randint(1,1000000) for i in range(1,1000000)]

async def main(*args):
    """
    await passes function control back to the event loop

    async def g():
        Pause here and come back to g() when f() is ready
        r = await f()
        return r
    """
    #coros = [func(i) for i in args]
    coros = [func() for i in range(2)]
    r = await asyncio.gather(*coros)
    print(r)

if __name__ == '__main__':
    start = time.perf_counter()
    #a = [2, 3, 4]
    #asyncio.run(main(*a))
    asyncio.run(main())
    print(f'executed {(time.perf_counter() - start):.4f}')


from tkinter import *
root = Tk()
canvas = Canvas(root)
canvas.pack()

def round_rectangle(x1, y1, x2, y2, radius=15, **kwargs):

    points = [x1+radius, y1,
              x1+radius, y1,
              x2-radius, y1,
              x2-radius, y1,
              x2, y1,
              x2, y1+radius,
              x2, y1+radius,
              x2, y2-radius,
              x2, y2-radius,
              x2, y2,
              x2-radius, y2,
              x2-radius, y2,
              x1+radius, y2,
              x1+radius, y2,
              x1, y2,
              x1, y2-radius,
              x1, y2-radius,
              x1, y1+radius,
              x1, y1+radius,
              x1, y1]

    return canvas.create_polygon(points, **kwargs, smooth=True)

my_rectangle = round_rectangle(50, 50, 150, 80, radius=20, fill="blue")

root.mainloop()


# -*- coding: utf-8 -*-
import logging
import datetime
from openerp import api, models
from openerp.tools import DEFAULT_SERVER_DATE_FORMAT

EVENT_CATEGORY_REMINDER_REF = 'pdf_crm_extensions.calendar_event_category_reminder'
_EMAIL_TEMPLATE_REMINDER = 'pdf_schedule_reminder.email_template_reminder'

__author__ = 'Rui Coelho'
_logger = logging.getLogger(__name__)

class calendar_event(models.Model):
    _inherit = 'calendar.event'

    @api.model
    def send_reminders_by_email(self):
        """Send the emails for today's reminders."""
        category_reminder = self.env.ref(EVENT_CATEGORY_REMINDER_REF)
        email_template_ref = self.env.ref(_EMAIL_TEMPLATE_REMINDER)

        reminders = self.search([('categ_ids', 'in', [category_reminder.id]), ('start', '=', datetime.date.today().strftime(DEFAULT_SERVER_DATE_FORMAT))])
        for reminder in reminders:
            reminder_owners_email = []
            for partner_id in reminder.partner_ids:
                user_id = self.env['res.users'].search([('partner_id', '=', partner_id.id)])
                reminder_owners_email.append(user_id.email if user_id else '')

            email_to = ','.join(reminder_owners_email)
            _logger.info('Sending email about reminder #%s to %s', reminder.id, ','.join(email_to))
            web_base_url = self.env['ir.config_parameter'].get_param('web.base.url')
            self.env['email.template'].with_context({'lang': 'pt_PT', 'web_base_url': web_base_url, 'email_to': email_to}).browse(email_template_ref.id).send_mail(reminder.id, True, False)


import pygame, math
from random import randint
from projectile import *
#from enemy      import *
#from player     import *
#from hud        import *

class Game():
    def __init__(self, screen):
        #initialize all variables
        self.BLACK = (0, 0, 0)
        self.WHITE = (255, 255, 255)
        self.RED = (255, 0, 0)
        self.BLUE = (0, 0, 255)
        self.screen = screen
        self.SCREEN_WIDTH  = self.screen.get_width()
        self.SCREEN_HEIGHT = self.screen.get_height()

    def play(self):
#        difficulty = 1
        tick = 0
        done = False
        all_sprites_list = pygame.sprite.Group()
        block_list = pygame.sprite.Group()
        bullet_list = pygame.sprite.Group()
        player_collisions = []
        clock = pygame.time.Clock()
        score = 0
        player = Player()
        player.rect.x = self.SCREEN_WIDTH / 2
        player.rect.y = self.SCREEN_HEIGHT / 2
        enemy_spawn_freq = 60# / difficulty

        all_sprites_list.add(player)

        while not done:
            # --- Event Processing
            tick += 1
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    done = True

                elif event.type == pygame.MOUSEBUTTONDOWN:
                    # Fire a bullet if the user clicks the mouse button

                    # Get the mouse position
                    pos = pygame.mouse.get_pos()

                    mouse_x = pos[0]
                    mouse_y = pos[1]

                    bullet = Projectile(player.rect, pos, 5, 5, (0,0,0))
                    # Add the bullet to the lists
                    all_sprites_list.add(bullet)
                    bullet_list.add(bullet)

            if tick % enemy_spawn_freq == 0:
                e = create_enemy()
                block_list.add(e)
                all_sprites_list.add(e)

                # Call the update() method on all the sprites
            all_sprites_list.update()

                # Calculate mechanics for each bullet
            for bullet in bullet_list:
                # See if it hit a block
                block_hit_list = pygame.sprite.spritecollide(bullet, block_list, True)

                    # For each block hit, remove the bullet and add to the score
                for block in block_hit_list:
                    bullet_list.remove(bullet)
                    all_sprites_list.remove(bullet)
                    score += 1
                    #check for player collisions
            player_collisions = pygame.sprite.spritecollide(player, block_list, True)
            if len(player_collisions) > 0:
                        #player got hit
                done = True
                # Clear the screen
            self.screen.fill(self.WHITE)

            # Draw all the sprites
            all_sprites_list.draw(self.screen)

            #draw score
            text_to_screen(self.screen, "Score: {0}".format(score), 0, 0)

            pygame.display.flip()

            clock.tick(60)


import cv2
import numpy as np

def density_image(pts, shape, sigma):
    padding = int((sigma - .8) / .3 + 1)

    # Filter out points which are too far away
    mask = (-padding <= pts[:, 1]) & (pts[:, 1] < shape[0] + padding) \
         & (-padding <= pts[:, 0]) & (pts[:, 0] < shape[1] + padding)
    pts_x, pts_y = pts.T[:, mask, None, None]
    yg, xg = np.ogrid[: shape[0], : shape[1]]
    peaks = np.exp(-(  (pts_y - yg) ** 2 \
                     + (pts_x - xg) ** 2) \
                   / (2 * sigma ** 2)) \
            / (2 * np.pi * sigma ** 2)

    # Compute density
    density = peaks.sum(axis=0)
    return density


#!/usr/bin/python3

import os

FULL_FILE_NAME = 'data_example/heap_data/'
INPUT_PREF = 'input'
OUTPUT_PREF = 'ext_output'
FILES_PATTERN = ['_01_10.txt', '_03_10.txt', '_05_100.txt',
                 '_07_100.txt', '_09_1000.txt', '_11_1000.txt',
                 '_02_10.txt', '_04_10.txt', '_06_100.txt',
                 '_08_100.txt', '_10_1000.txt', '_12_1000.txt', ]

class BinHeap:

    def __init__(self):
        self.heap_list = [0]
        self.current_size = 0

    def get_head(self):
        if self.current_size > 0:
            return self.heap_list[1]

    def perc_up(self, i):
        raise NotImplementedError

    def insert(self, k):
        self.heap_list.append(k)
        self.current_size = self.current_size + 1
        self.perc_up(self.current_size)

    def perc_down(self, i):
        raise NotImplementedError

    def del_min(self):
        retval = self.heap_list[1]
        self.heap_list[1] = self.heap_list[self.current_size]
        self.current_size = self.current_size - 1
        self.heap_list.pop()
        self.perc_down(1)
        return retval

    def build_heap(self, alist):
        i = len(alist) // 2
        self.current_size = len(alist)
        self.heap_list = [0] + alist[:]
        while i > 0:
            self.perc_down(i)
            i = i - 1

class HeapHight(BinHeap):

    def perc_up(self, i):
        while i // 2 > 0:
            if self.heap_list[i] < self.heap_list[i // 2]:
                tmp = self.heap_list[i // 2]
                self.heap_list[i // 2] = self.heap_list[i]
                self.heap_list[i] = tmp
            i = i // 2

    def min_child(self, i):
        if i * 2 + 1 > self.current_size:
            return i * 2
        else:
            if self.heap_list[i*2] < self.heap_list[i*2+1]:
                return i * 2
            else:
                return i * 2 + 1

    def perc_down(self, i):
        while (i * 2) <= self.current_size:
            mc = self.min_child(i)
            if self.heap_list[i] > self.heap_list[mc]:
                tmp = self.heap_list[i]
                self.heap_list[i] = self.heap_list[mc]
                self.heap_list[mc] = tmp
            i = mc

class HeapLow(BinHeap):

    def perc_up(self, i):
        while i // 2 > 0:
            if self.heap_list[i] > self.heap_list[i // 2]:
                tmp = self.heap_list[i // 2]
                self.heap_list[i // 2] = self.heap_list[i]
                self.heap_list[i] = tmp
            i = i // 2

    def min_child(self, i):
        if i * 2 + 1 > self.current_size:
            return i * 2
        else:
            if self.heap_list[i*2] > self.heap_list[i*2+1]:
                return i * 2
            else:
                return i * 2 + 1

    def perc_down(self, i):
        while (i * 2) <= self.current_size:
            mc = self.min_child(i)
            if self.heap_list[i] < self.heap_list[mc]:
                tmp = self.heap_list[i]
                self.heap_list[i] = self.heap_list[mc]
                self.heap_list[mc] = tmp
            i = mc

class MainHeap:
    def __init__(self):
        self.heap_low = HeapLow()
        self.heap_height = HeapHight()
        self.medians = []

    def build_heap(self, item):
        self.medians = []
        l_head = self.heap_low.get_head()
        h_head = self.heap_height.get_head()
        if l_head and item < l_head:
            self.heap_low.insert(item)
        elif h_head and item > h_head:
            self.heap_height.insert(item)
        else:
            self.heap_height.insert(item)

        # Balance heap sizes
        if self.heap_low.current_size - self.heap_height.current_size > 1:
            tmp = l_head
            self.heap_height.insert(tmp)
            self.heap_low.del_min()

        if self.heap_height.current_size - self.heap_low.current_size > 1:
            tmp = self.heap_height.get_head()
            self.heap_low.insert(tmp)
            self.heap_height.del_min()

        l_heap_len = len(self.heap_low.heap_list[1:])
        h_heap_len = len(self.heap_height.heap_list[1:])
        if (l_heap_len + h_heap_len) % 2 == 0:
            self.medians.extend([self.heap_low.heap_list[1],
                                 self.heap_height.heap_list[1]])
        elif l_heap_len > h_heap_len:
            self.medians.append(self.heap_low.heap_list[1])
        else:
            self.medians.append(self.heap_height.heap_list[1])
        return [self.medians, self.heap_low.heap_list[1:],
                self.heap_height.heap_list[1:]]

def read_input_data(input_file):
    heap = MainHeap()
    with open(input_file) as i_file:
        data = i_file.readlines()
    result = []
    for item in data[1:]:
        result.append(heap.build_heap(int(item.strip())))
    return result

def read_output(output_file,
                medians_header='Medians: ',
                h_low_header='H_low: ',
                h_high_header='H_high: '):
    result = []
    item = []
    with open(output_file) as o_file:
        line = o_file.readline()
        while line:
            line = line.strip()
            if len(line) == 0:
                result.append(item)
                item = []
            elif line.startswith(medians_header):
                item.append([int(m) for m in line.strip(medians_header).split()])
            elif line.startswith(h_low_header):
                h_lows = line.strip(h_low_header)[1:-1].split(',')
                item.append([int(m) for m in h_lows if m])
            elif line.startswith(h_high_header):
                h_highs = line.strip(h_high_header)[1:-1].split(',')
                item.append([int(m) for m in h_highs if m])
            line = o_file.readline()
    return result

if __name__ == '__main__':
    abs_dirname = os.path.join(os.path.dirname(__file__), FULL_FILE_NAME)
    for f_name in FILES_PATTERN:
        full_f_name = os.path.join(abs_dirname, INPUT_PREF + f_name)
        result = read_input_data(full_f_name)
        full_f_name = os.path.join(abs_dirname, OUTPUT_PREF + f_name)
        out_result = read_output(full_f_name)
        assert result == out_result


# -*- coding: utf-8 -*-
##############################################################################
#
#    OpenERP, Open Source Management Solution
#    Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU Affero General Public License as
#    published by the Free Software Foundation, either version 3 of the
#    License, or (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU Affero General Public License for more details.
#
#    You should have received a copy of the GNU Affero General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################

from openerp.osv import fields, osv
from openerp.tools.translate import _
from openerp.tools.safe_eval import safe_eval as eval
import openerp.addons.decimal_precision as dp

class product_template(osv.osv):
    _inherit = "product.template"

    _columns = {
                'framework':fields.selection([('Medication','Medication'),('Merchandise','Merchandise'),('Service','Service'),('Template','Template')], 'Framework'),
                'schedule':fields.integer('Schedule'),
                'tag_commisionable':fields.boolean('Commissionable'),
                'dogs':fields.boolean('Dogs'),
                'cats':fields.boolean('Cats'),
                'horse':fields.boolean('Horse'),
                'cattle':fields.boolean('Cattle'),
                'birds':fields.boolean('Birds'),
                'swine':fields.boolean('Swine'),
                'small_mammals':fields.boolean('Rabits Rodents small mammals'),
                'ferrets':fields.boolean('Ferrets'),
                'liamas':fields.boolean('Liamas'),
                'reptiles':fields.boolean('Reptiles'),
                'camel_ides':fields.boolean('Camel Ides'),
                'zoo_exotic':fields.boolean('Zoo Exotic'),
                'goats':fields.boolean('Goats'),
                'investigation_type':fields.selection([('Antech-Refrence','Antech-Refrence'),('Idexx-Refrence','Idexx-Refrence')], 'Investigation Type'),

                }


from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import os
import json

import tensorflow as tf
import numpy as np
import pdb
from qa_model import Encoder, QASystem, Decoder
from os.path import join as pjoin

import logging

logging.basicConfig(level=logging.INFO)

tf.app.flags.DEFINE_float("learning_rate", 0.0001, "Learning rate.")
tf.app.flags.DEFINE_float("max_gradient_norm", 6.6, "Clip gradients to this norm.")
tf.app.flags.DEFINE_float("dropout", 0.5, "Fraction of units randomly kept on non-recurrent connections.")
tf.app.flags.DEFINE_integer("batch_size", 20, "Batch size to use during training.")
tf.app.flags.DEFINE_integer("epochs", 15, "Number of epochs to train.")
tf.app.flags.DEFINE_integer("state_size", 100, "Size of each model layer.")
tf.app.flags.DEFINE_integer("output_size", 256, "The output size of your model.") #766
tf.app.flags.DEFINE_integer("embedding_size", 300, "Size of the pretrained vocabulary.")
tf.app.flags.DEFINE_string("data_dir", "data/squad", "SQuAD directory (default ./data/squad)")
tf.app.flags.DEFINE_string("train_dir", "train", "Training directory to save the model parameters (default: ./train).")
tf.app.flags.DEFINE_string("load_train_dir", "", "Training directory to load model parameters from to resume training (default: {train_dir}).")
tf.app.flags.DEFINE_string("log_dir", "log", "Path to store log and flag files (default: ./log)")
tf.app.flags.DEFINE_string("optimizer", "adamax", "adam / sgd")
tf.app.flags.DEFINE_integer("print_every", 1, "How many iterations to do per print.")
tf.app.flags.DEFINE_integer("keep", 0, "How many checkpoints to keep, 0 indicates keep all.")
tf.app.flags.DEFINE_string("vocab_path", "data/squad/vocab.dat", "Path to vocab file (default: ./data/squad/vocab.dat)")
tf.app.flags.DEFINE_string("embed_path", "", "Path to the trimmed GLoVe embedding (default: ./data/squad/glove.trimmed.{embedding_size}.npz)")
tf.app.flags.DEFINE_integer("max_length", 20, "max_lenth of the question.")

FLAGS = tf.app.flags.FLAGS

def initialize_model(session, model, train_dir):
    ckpt = tf.train.get_checkpoint_state(train_dir)
    v2_path = ckpt.model_checkpoint_path + ".index" if ckpt else ""
    if ckpt and (tf.gfile.Exists(ckpt.model_checkpoint_path) or tf.gfile.Exists(v2_path)):
        logging.info("Reading model parameters from %s" % ckpt.model_checkpoint_path)
        saver = tf.train.Saver()
        saver.restore(session, ckpt.model_checkpoint_path)
    else:
        logging.info("Created model with fresh parameters.")
        session.run(tf.global_variables_initializer())
        logging.info('Num params: %d' % sum(v.get_shape().num_elements() for v in tf.trainable_variables()))
    return model

def initialize_vocab(vocab_path):
    if tf.gfile.Exists(vocab_path):
        rev_vocab = []
        with tf.gfile.GFile(vocab_path, mode="rb") as f:
            rev_vocab.extend(f.readlines())
        rev_vocab = [line.strip('\n') for line in rev_vocab]
        vocab = dict([(x, y) for (y, x) in enumerate(rev_vocab)])
        return vocab, rev_vocab
    else:
        raise ValueError("Vocabulary file %s not found.", vocab_path)

def get_normalized_train_dir(train_dir):
    """
    Adds symlink to {train_dir} from /tmp/cs224n-squad-train to canonicalize the
    file paths saved in the checkpoint. This allows the model to be reloaded even
    if the location of the checkpoint files has moved, allowing usage with CodaLab.
    This must be done on both train.py and qa_answer.py in order to work.
    """
    global_train_dir = '/tmp/cs224n-squad-train'
    if os.path.exists(global_train_dir):
        os.unlink(global_train_dir)
    if not os.path.exists(train_dir):
        os.makedirs(train_dir)
    os.symlink(os.path.abspath(train_dir), global_train_dir)
    return global_train_dir

def load_and_pad_val_data(q_path, c_path, a_path):
    fq, fc, fa = open(q_path), open(c_path), open(a_path)
    ans = []
    question = []
    ques_mask = []
    context = []
    context_mask = []
    mask_c_vec = []

    for _ in range(4284):
        q, c, a = fq.readline(), fc.readline(), fa.readline()
        q = map(int, q.strip().split(' '))
        c = map(int, c.strip().split(' '))
        a = map(int, a.strip().split(' '))
        if (a[0] > a[1]): continue
        if (max(a) >= FLAGS.output_size) or (len(q) > FLAGS.max_length):
            continue
        ques_mask.append(len(q))
        if len(c) > FLAGS.output_size:
            c = c[:FLAGS.output_size]
        context_mask.append(len(c))
        vec = []
        vec.extend([True] * len(c))
        ans.append(a)
        if len(q) < FLAGS.max_length:
            q.extend([0] * (FLAGS.max_length - len(q)))
        question.append(q)
        if len(c) < FLAGS.output_size:
            vec.extend([False] * (FLAGS.output_size - len(c)))
            c.extend([0] * (FLAGS.output_size - len(c)))
        context.append(c)
        mask_c_vec.append(vec)
    return (question, ques_mask, context, context_mask, ans, len(ans), mask_c_vec)

def batch_generator(question_path, context_path, answer_path, batch_size, max_length_q, max_length_c):
    question_info = open(question_path)
    context_info = open(context_path)
    answer_info = open(answer_path)
    q_batch = []
    mask_q = []
    ans = []
    c_batch = []
    mask_c = []
    mask_c_vec = []
    size_of_dataset = 81386
    for __ in range(size_of_dataset):
        q, c, a = question_info.readline(), context_info.readline(), answer_info.readline()
        q = map(int, q.strip().split(' '))
        c = map(int, c.strip().split(' '))
        a = map(int, a.strip().split(' '))
        if (a[0] > a[1]): continue
        if (max(a) >= FLAGS.output_size) or (len(q) > FLAGS.max_length):
            continue
        mask_q.append(len(q))
        if len(c) > FLAGS.output_size:
            c = c[:FLAGS.output_size]
        mask_c.append(len(c))
        vec = []
        vec.extend([True] * len(c))
        ans.append(a)
        if len(q) < max_length_q:
            q.extend([0] * (max_length_q - len(q)))
        q_batch.append(q)
        if len(c) < max_length_c:
            vec.extend([False] * (max_length_c - len(c)))
            c.extend([0] * (max_length_c - len(c)))
        c_batch.append(c)
        mask_c_vec.append(vec)
        if len(ans) == batch_size:
            batch = (q_batch, mask_q, c_batch, mask_c, ans, mask_c_vec)
            yield batch
            q_batch = []
            mask_q = []
            ans = []
            c_batch = []
            mask_c = []
            mask_c_vec = []

def main(_):

    # Do what you need to load datasets from FLAGS.data_dir
    # load all in once, maybe better to try batch by batch
    question_path = "./data/squad/train.ids.question"
    context_path = "./data/squad/train.ids.context"
    answer_path = "./data/squad/train.span"

    val_q = "./data/squad/val.ids.question"
    val_c = "./data/squad/val.ids.context"
    val_a = "./data/squad/val.span"

    embed_path = FLAGS.embed_path or pjoin("data", "squad", "glove.trimmed.{}.npz".format(FLAGS.embedding_size))
    vocab_path = FLAGS.vocab_path or pjoin(FLAGS.data_dir, "vocab.dat")

    # embeddings is a matrix of shape [vocab_size, embedding_size]
    embeddings = np.load(embed_path)['glove'].astype(np.float32)
    val_data = load_and_pad_val_data(val_q, val_c, val_a)

    # vocab is the mapping from word -> token id
    # rev_vocab is the reverse mapping, from id -> word
    vocab, rev_vocab = initialize_vocab(vocab_path)

    # someone posted that the max length of question is 766
    info = (question_path, context_path, answer_path, FLAGS.batch_size, FLAGS.max_length, FLAGS.output_size)
    '''
    batch_gen = batch_generator(question_path, context_path, answer_path, FLAGS.batch_size, FLAGS.max_length, FLAGS.output_size)
    i = 0;
    while True:
        batch_gen.next()
        i += 1
        logging.info(i)
    '''

    encoder = Encoder(size=FLAGS.state_size, vocab_dim=FLAGS.embedding_size)
    decoder = Decoder(output_size=FLAGS.output_size)

    qa = QASystem(encoder, decoder, FLAGS, embeddings)

    if not os.path.exists(FLAGS.log_dir):
        os.makedirs(FLAGS.log_dir)
    file_handler = logging.FileHandler(pjoin(FLAGS.log_dir, "log.txt"))
    logging.getLogger().addHandler(file_handler)

    print(vars(FLAGS))
    with open(os.path.join(FLAGS.log_dir, "flags.json"), 'w') as fout:
        json.dump(FLAGS.__flags, fout)

    with tf.Session() as sess:
        load_train_dir = get_normalized_train_dir(FLAGS.load_train_dir or FLAGS.train_dir)
        initialize_model(sess, qa, load_train_dir)

        save_train_dir = get_normalized_train_dir(FLAGS.train_dir)
        qa.train(sess, batch_generator, info, save_train_dir, val_data, rev_vocab)
        #qa.evaluate_answer(sess, dataset, vocab, FLAGS.evaluate, log=True)

if __name__ == "__main__":
    tf.app.run()


import torch

def get_opts(model, model_name):
    if model_name == 'GCN':
        return torch.optim.Adam([
            dict(params=model.conv1.parameters(), weight_decay=5e-4),
            dict(params=model.conv2.parameters(), weight_decay=0)
        ], lr=0.01)  # Only perform weight-decay on first convolution.
#         return torch.optim.Adam(model.parameters(), lr=0.005, weight_decay=5e-4)
    elif model_name == 'GraphSage':
        return torch.optim.Adam(model.parameters(), lr=0.01, weight_decay=5e-4)
    else:
        return torch.optim.Adam(model.parameters(), lr=0.005, weight_decay=5e-4)

def process_mask(data):
    train_mask = []
    val_mask = []
    test_mask = []
    train_num = sum(data.train_mask)
    val_num = sum(data.val_mask)
    test_num = sum(data.test_mask)
    for i in range(len(data.x)):
        if i < test_num:
            test_mask.append(True)
        else:
            test_mask.append(False)
        if test_num <= i < test_num + val_num:
            val_mask.append(True)
        else:
            val_mask.append(False)
        if (test_num + val_num) <= i < (test_num + val_num + train_num):
            train_mask.append(True)
        else:
            train_mask.append(False)
    data.train_mask = torch.tensor(train_mask)
    data.val_mask = torch.tensor(val_mask)
    data.test_mask = torch.tensor(test_mask)

    return data


#!/usr/bin/env python2
# XXX: Refactor to a comand line tool and remove pylint disable
"""Build expression time course."""
from __future__ import absolute_import, division, print_function

import argparse
import gzip
import json
from collections import Counter

import numpy as np
from six import iteritems

import utils

parser = argparse.ArgumentParser(description="Build expression time course.")
parser.add_argument("expression_files", nargs="+", help="gene expression files")
parser.add_argument("--names", nargs="+", help="expression names")
parser.add_argument("--mean", action="store_true", help="group by time and average")
args = parser.parse_args()

if args.names and len(args.names) != len(args.expression_files):
    raise AttributeError("Names length must match files length.")

files = args.expression_files
progress = 0
series = {"timePoints": [], "genes": {}}

# Read time points from file names
times = []
if args.names:
    for name in args.names:
        ndx = name.lower().find("hr")
        if ndx > 0:
            try:
                times.append(int(name[ndx + 2 : ndx + 4]))
            except Exception:
                try:
                    times.append(int(name[ndx - 2 : ndx]))
                except Exception:
                    pass
    if len(times) > 0 and len(times) != len(files):
        raise AttributeError("Found some times but not for all time points.")

if len(times) == 0:
    times = range(len(files))

def is_gzipped(f):
    """Check if file gzipped."""
    with open(f, "rb") as rpkm_file:
        magic = rpkm_file.read(2)

    return magic == "\037\213"

# Go through files
for t, f in sorted(zip(times, files)):
    myopen = utils.gzopen if is_gzipped(f) else open

    with myopen(f) as rpkm_file:
        rpkm_file.readline()  # skip first line

        # TODO: see above
        series["timePoints"].append(t)

        # Go through lines and parse them
        for line in rpkm_file:
            entry = line.split()
            gene = entry[0]
            value = float(entry[1])

            # Add gene if missing
            if gene not in series["genes"]:
                series["genes"][gene] = []

            # Set values from previous experiment to 0 if missing and add value
            series["genes"][gene].extend(
                [0] * (len(series["timePoints"]) - 1 - len(series["genes"][gene]))
            )
            series["genes"][gene].append(value)

    # Print progress
    progress += 1.0 / len(files)
    print('{{"proc.progress":{0}}}'.format(progress))

# Add 0s at the end of genes if values are missing
for gene in series["genes"]:
    series["genes"][gene].extend(
        [0] * (len(series["timePoints"]) - len(series["genes"][gene]))
    )

# Average time points for replicates
if args.mean:
    tp, tp_counts = zip(*sorted(iteritems(Counter(series["timePoints"]))))
    for gene in series["genes"]:
        s = 0
        tp_averages = []
        for c in tp_counts:
            tp_averages.append(np.mean(series["genes"][gene][s : s + c]))
            s += c

        series["genes"][gene] = tp_averages
    series["timePoints"] = tp

# Print result in json
etcjson = '{"etc":%s}' % json.dumps(series, separators=(",", ":"))
gzip.open("etc.json.gz", "wb").write(etcjson)

with open("etc.json", "w") as out_json:
    out_json.write(json.dumps(series, separators=(",", ":")))


# uncompyle6 version 3.7.4
# Python bytecode 2.7 (62211)
# Decompiled from: Python 3.6.9 (default, Apr 18 2020, 01:56:04)
# [GCC 8.4.0]
# Embedded file name: /home/reshef/.virtualenvs/appsflyer/lib/python2.7/site-packages/dictmapper/mapper.py
# Compiled at: 2012-03-18 06:41:29
import inspect

class Mapping(object):
    creation_counter = 0

    def __init__(self, query=None, name=None, static_value=None, default=None, transform=None):
        self.creation_order = Mapping.creation_counter
        Mapping.creation_counter += 1
        self.name = name
        self.default = default
        self.transform = transform if transform else (lambda x: x)
        if query and static_value:
            raise AttributeError('Define either query or static_value')
        if query:
            if callable(query):
                self._do_mapping = lambda context: query(context)
            else:
                self.query_list = query.split('/')
                self.query_list_len = len(self.query_list)
        self.static_value = static_value

    @staticmethod
    def _value_or_call(obj):
        if callable(obj):
            return obj()
        return obj

    def map(self, context):
        return self._do_mapping(context)

    def _do_mapping(self, context):
        if self.static_value:
            return self.static_value
        else:
            current_context = context
            for i, e in enumerate(self.query_list, 1):
                current_context = current_context.get(e)
                if i == self.query_list_len or not current_context:
                    if current_context is not None:
                        return self.transform(current_context)
                    return Mapping._value_or_call(self.default)

            return

class MapperMeta(type):

    def __new__(meta, classname, bases, classDict):
        cls = type.__new__(meta, classname, bases, classDict)
        cls.mappings = sorted(inspect.getmembers(cls, lambda o: isinstance(o, Mapping)), key=lambda i: i[1].creation_order)
        for name, mapping in cls.mappings:
            if isinstance(mapping, Mapping):
                if not mapping.name:
                    mapping.name = name

        cls.nb_mappings = len(cls.mappings)
        return cls

class MapperBase(object):
    __metaclass__ = MapperMeta

class Mapper(MapperBase):

    def headers(self):
        return [ n.capitalize().replace('_', ' ') for n, v in self.mappings ]

    def map(self, inp):
        """
        Performs mapping on a sequence of dict objects and returns the corresponding rows:
        >>> class TestMapper(Mapper):
        >>>     name = Mapping('name')
        >>>     value = Mapping('value')
        >>> mapper = TestMapper()
        >>> res = mapper.map([{'name': 'test name', 'value': 'test value'}, {'name': 'test name 2', 'value': 'test value 2'}])
        returns
        [('test name', 'test value'), ('test name 2', 'test value 2')]
        """
        result = []
        for record in inp:
            row = []
            for _, mapping in self.mappings:
                row.append(mapping.map(record))

            result.append(row)

        return result


strawberries_price = float(input())
raspberries_price = strawberries_price / 2
oranges_price = raspberries_price * 0.60
bananas_price = raspberries_price * .20

bananas = float(input())
oranges = float(input())
raspberries = float(input())
strawberries = float(input())

raspberries_sum = raspberries * raspberries_price
strawberries_sum = strawberries * strawberries_price
bananas_sum = bananas * bananas_price
oranges_sum = oranges * oranges_price

sum_total = strawberries_sum + oranges_sum + raspberries_sum + bananas_sum
print(sum_total)


#!/data/home/henry/anaconda3/bin/python3.6
# -*- coding: utf-8 -*-
# @File  : Figure_bar.py
# @Author: Hanzhaohui
# @Date  : 2018/9/17
# @Desc  : 对给定区域的月平均数据做bar图
# 分析数据来源于Read_area_average.py

# ****************************************************
import matplotlib
matplotlib.use('Qt5Agg')
from Tools.Filter_tools import *
from Tools.Class_time import Time_slice
from Tools.Class_Figure import MonthBar  # 主要用来画ww3图的类
# ****************************************************
# 用户自定义
Ymin = 2005
Ymax = 2009
Mmin = 1
Mmax = 12

# lat: 45~65  lon: 310~350
lon1 = 320
lon2 = 330
lat1 = 55
lat2 = 60

# ****************************************************
# 待读取文件名
npz = f'data/Read_area_average_{lon1}-{lon2}_{lat1}-{lat2}.npz'
w = np.load(npz)
# 待保存图片
fig_file = f'figure/Figure_bar_{lon1}-{lon2}_{lat1}-{lat2}.png'
# ****************************************************
# 读取数据
timex0 = w['timex']
# 待读取文件列表
Muv_tar0, Muv_toc0 = np.array([]), np.array([])
Msuvstr_tar0, Msuvstr_toc0 = np.array([]), np.array([])
Mwpi_tar0, Mwpi_toc0 = np.array([]), np.array([])
Mtimex0 = np.array([])
# range(Y,Y)为空矩阵，不循环，因此Ymin-1
for Y in range(Ymin - 1, Ymax):
    Y += 1
    if Y == Ymin:
        mo_min = Mmin
    else:
        mo_min = 1
    if Y == Ymax:
        mo_max = Mmax
    else:
        mo_max = 12
    for M in range(mo_min - 1, mo_max):
        M += 1
        print('')
        print('*' * 40)
        print('Y= ', Y,' M= ',M)
        Time=Time_slice() # 时间切片类
        IM1,IM2=Time.cut_month(timex0,Y,M) # 获取每月在timex中的索引
        # 读取数据
        for var in w.keys():
            f1 = f'{var}=w[var][IM1:IM2]'
            f2 = f'{var}=np.mean({var})'
            f3 = f'{var}0=np.append({var}0,{var})'
            f4 = f'M{var}0=np.append(M{var}0,{var})'
            exec(f1) # Muv_tar=w[var][IM1:IM2]
            exec(f2) # Muv_tar=np.mean(Muv_tar)
            if var == 'suvstr_toc':
                exec(f4) # Muv_tar0=np.append(Muv_tar0,Muv_tar)
            else:
                exec(f3)
Y1=Ymax-Ymin + 1
uv_tarx = Muv_tar0.reshape(Y1, 12)
uv_tocx = Muv_toc0.reshape(Y1, 12)
suvstr_tarx = Msuvstr_tar0.reshape(Y1, 12)
suvstr_tocx = Msuvstr_toc0.reshape(Y1, 12)
wpi_tarx = Mwpi_tar0.reshape(Y1, 12)
wpi_tocx = Mwpi_toc0.reshape(Y1, 12)

uv = MonthBar(uv_tarx, uv_tocx, 'uv')
uv.bar(show=1)
# uv.savefig(dpi=200)

suvstr = MonthBar(suvstr_tarx, suvstr_tocx, 'suvstr')
suvstr.bar(show=1)
# suvstr.savefig(dpi=200)

wpi = MonthBar(wpi_tarx, wpi_tocx, 'wpi')
wpi.bar(show=1)
# wpi.savefig(dpi=200)


# Use open to open file "foo.txt" for reading
file = open("foo.txt", "r")
# Print all the lines in the file
content = file.read()
print(content)
# Close the file
file.close()

# Use open to open file "bar.txt" for writing
file = open("foo.txt", "w")
# Use the write() method to write three lines to the file
file.write('Hello\n')
file.write('world,\n')
file.write('Python')
# Close the file
file.close()


"""jth-compile

Usage:
    jth-compile <source_path> [-o <output_path> -p]
    jth-compile <source_path> [-c | -a ]
    jth-compile -i

Arguments:
    <source_path>  Path to source file.

Options:
    -o --output <output_path>  Path to output executable file.
    -p --preserve              Don't delete intermediate output files.
    -c --compile               Compile, but do not assemble or link.
    -a --assemble              Compile and assemble, but do not link.
    -i --interactive           Interactively parse input programs and print
                               their ASTs.
"""

import os

import docopt  # type: ignore

from ._core import compile_file
from ._parse import parse, tokenize

def run() -> None:
    args = docopt.docopt(__doc__)

    if args['--interactive']:
        while True:
            source = input('> ')
            print(parse(tokenize(source)))
    else:
        assert os.path.isfile(args['<source_path>'])
        compile_file(
            args['<source_path>'],
            args['--output'],
            args['--compile'],
            args['--assemble'],
            args['--preserve']
        )


from myuw_selenium.test.textbook_card_lp_c import *
from myuw_selenium.test.card_tests_c import create_test_from_test

test_data = [
    # Card Hidden
    { 'date':'2013-03-26', 'user':'javerage', 'test_name':'before_grade_submission_deadline', 'test':NoCardShownTest },
    { 'date':'2013-04-08', 'user':'eight',    'test_name':'after_first_week_of_quarter',      'test':NoCardShownTest },
    { 'date':'2013-03-22', 'user':'jbothell', 'test_name':'before_end_of_finals_week',        'test':NoCardShownTest },
    { 'date':'2013-07-26', 'user':'javerage', 'test_name':'summer_b_term_no_card',            'test':NoCardShownTest },

    # Card Shown
    { 'date':'2013-03-27', 'user':'javerage', 'test_name':'after_grade_submission_deadline', 'test':CardShownTest },
    { 'date':'2013-04-01', 'user':'eight',    'test_name':'first_week_of_quarter',           'test':CardShownTest },
    { 'date':'2013-04-07', 'user':'jbothell', 'test_name':'first_week_of_quarter',           'test':CardShownTest },

    # Correct Course
    {'user':'javerage', 'date':'2013-04-05', 'test_name':'javerage_course', 'courses':['PHYS 121 A', 'PHYS 121 AC', 'PHYS 121 AQ', 'TRAIN 100 A', 'TRAIN 101 A'],                                              'test':CoursesTest },
    {'user':'jbothell', 'date':'2013-04-05', 'test_name':'jbothell_course', 'courses':['BISSEB 259 A', 'BCWRIT 500 A', 'BESS 102 A', 'BESS 102 AB'],                                                           'test':CoursesTest },
    {'user':'jnew',     'date':'2013-04-05', 'test_name':'jnew_course',     'courses':['TRAIN 101 A'],                                                                                'test':CoursesTest },
    {'user':'eight',    'date':'2013-04-05', 'test_name':'eight_course',    'courses':['PHYS 121 A', 'PHYS 121 AC', 'PHYS 121 AQ', 'TRAIN 100 A', 'TRAIN 101 A', 'ASL 101 A', 'ROLING 310 A', 'ARCTIC 200 A'], 'test':CoursesTest },

    # Correct Book Counts
    {'user':'javerage', 'date':'2013-04-05', 'test_name':'javerage_book_count', 'courses':{'PHYS 121 A':0 , 'PHYS 121 AC':0, 'PHYS 121 AQ':2, 'TRAIN 100 A':0, 'TRAIN 101 A':0},                                                   'test':BookCountTest },
    {'user':'jbothell', 'date':'2013-04-05', 'test_name':'jbothell_book_count', 'courses':{'BISSEB 259 A':1, 'BCWRIT 500 A':1, 'BESS 102 A':1, 'BESS 102 AB':0},                                                                   'test':BookCountTest },
    {'user':'jnew',     'date':'2013-04-05', 'test_name':'jnew_book_count',     'courses':{'TRAIN 101 A':1},                                                                                'test':BookCountTest },
    {'user':'eight',    'date':'2013-04-05', 'test_name':'eight_book_count',    'courses':{'PHYS 121 A':0, 'PHYS 121 AC':1, 'PHYS 121 AQ':0, 'TRAIN 100 A':0, 'TRAIN 101 A':0, 'ASL 101 A':0, 'ROLING 310 A':0, 'ARCTIC 200 A':1}, 'test':BookCountTest },

    # Correct Course Colors
    {'user':'javerage', 'date':'2013-04-05', 'test_name':'javerage_color', 'courses':['PHYS 121 A', 'PHYS 121 AC', 'PHYS 121 AQ', 'TRAIN 100 A', 'TRAIN 101 A'],                                              'test':CourseColorTest },
    {'user':'jbothell', 'date':'2013-04-05', 'test_name':'jbothell_color', 'courses':['BISSEB 259 A', 'BCWRIT 500 A', 'BESS 102 A', 'BESS 102 AB'],                                                           'test':CourseColorTest },
    {'user':'jnew',     'date':'2013-04-05', 'test_name':'jnew_color',     'courses':['TRAIN 101 A'],                                                                                'test':CourseColorTest },
    {'user':'eight',    'date':'2013-04-05', 'test_name':'eight_color',    'courses':['PHYS 121 A', 'PHYS 121 AC', 'PHYS 121 AQ', 'TRAIN 100 A', 'TRAIN 101 A', 'ASL 101 A', 'ROLING 310 A', 'ARCTIC 200 A'], 'test':CourseColorTest },

    # Full Page Textbook Link
    {'user':'javerage', 'date':'2013-04-05', 'test_name':'javerage_full_page', 'test':FullPageLink },

    # No Full Page Textbook Link
    {'user':'javerage', 'date':'2013-10-01', 'test_name':'javerage_no_full_page', 'test':NoFullPageLink }
]

for test in test_data:
    card_tests = create_test_from_test(test)

    index = 1
    for test_class in card_tests:
        vars()['test_' + test['test_name'] + '_' + str(index)] = test_class
        index += 1

del vars()['test_class']


import os
import json
from django.core.management.base import BaseCommand
from opencivicdata.core.models import Post

class Command(BaseCommand):
    help = 'make JSON files for boundaries'

    def add_arguments(self, parser):
        parser.add_argument('year', help='year')
        parser.add_argument('--state', help='name of state')

    def handle(self, *args, **options):
        dump_divisions(options['year'], options['state'])

def dump_divisions(year, state=None):
    if state:
        posts = Post.objects.filter(organization__jurisdiction__name=state)
    else:
        posts = Post.objects.filter(organization__classification__in=('upper', 'lower',
                                                                      'legislature'))
    short_year = year[-2:]
    for post in posts:
        division_id = post.division_id
        try:
            boundary = post.division.geometries.get(boundary__set__slug__in=(
                f'sldl-{short_year}', f'sldu-{short_year}', 'nh-12')).boundary
        except Exception:
            print(division_id, 'does not exist')
            continue

        output = {
            'division_id': division_id,
            'year': year,
            'metadata': boundary.metadata,
            'centroid': json.loads(boundary.centroid.geojson),
            'extent': boundary.extent,
            # shape is about 8 times larger
            'shape': json.loads(boundary.simple_shape.geojson),
        }

        filename = f'{year}/{division_id}.json'

        try:
            os.makedirs(os.path.dirname(filename))
        except OSError:
            pass

        with open(filename, 'w') as f:
            json.dump(output, f, sort_keys=True, indent=1)


from functools import reduce
from Taxon import Taxon
from core.QuasiType import QuasiType

class TaxonOverload(Taxon):
	type = 'overload'

	def addItem(self, taxon, pos = -1):
		# При включении в ovrtload функция лишается имени. Иначе появляются проблемы при построении пути getPathExt
		# Компенсация имени производится в TaxonFunc.getName()
		taxon.name = ''
		super().addItem(taxon, pos)

	def getImplementationByKey(self, overloadKey):
		for item in self.items:
			if item.overloadKey == overloadKey:
				return item
		self.throwError('Not found overload key %s' % overloadKey)

	def getOverloadKey(self, item):
		if item.overloadKey:
			return item.overloadKey
		maxKey = 0
		for tx in self.items:
			if tx.overloadKey:
				maxKey = max(maxKey, tx.overloadKey)
		for tx in self.items:
			if not tx.overloadKey:
				maxKey += 1
				tx.overloadKey = maxKey
		return item.overloadKey

	def getCountOfName(self, name):
		return reduce(lambda acc, taxon: acc + (1 if taxon.getName() == name else 0), self.items, 0)

	@staticmethod
	def findSuitablePure(qtArguments, functions):
		"""
		qtArguments = список квази-типов для аргументов вызывающего выращения (фактических параметров)
		functions = список таксонов типа TaxonFunc
		result =
			None - значит не готово
			'NoSuitable' = 'No suitable _method_ found for fname(type, type)'

		"""
		if None in qtArguments:
			return None
		nArgs = len(qtArguments)
		# Собрать список функций, которые подходят по количеству параметров, с учетом дефолтных значений
		possibleFuncs = []
		for func in functions:
			params = func.getParamsList()
			if len(params) != nArgs:
				# У функции число параметров должно точно соответствовать количеству аргументов.
				# Дефолтные параметры для перегруженных функций запрещены.
				continue
			qtList = [param.buildQuasiType() for param in params]
			if None in qtList:
				return None
			possibleFuncs.append((func, qtList))
		# Если не подошел ни один вариант
		if len(possibleFuncs) == 0:
			return 'NoSuitable'
		# Теперь нужно проверить соответствие
		matches = []
		for func, qtList in possibleFuncs:
			resList = []
			for i, qtArg in enumerate(qtArguments):
				res, err = QuasiType.matchTaxons(qtList[i], qtArg)
				if err:
					break
				resList.append(res)
			else:
				matches.append((func, resList))
		if len(matches) == 0:
			return 'NoSuitable'
		# Если найдено одно соответствие, то задача выполнена
		if len(matches) == 1:
			return matches[0][0]

		# Если вариантов несколько то сначала пробуем найти точное соответствие
		exacts = []
		for func, matchList in matches:
			for res in matchList:
				if res not in ('exact', 'constExact'):
					break
			else:
				exacts.append(func)
		if len(exacts) == 1:
			# Найден один вариант, точно соответствующий по параметрам
			return exacts[0]

		if len(exacts) > 1:
			# Несколько точно подходящих вариантов
			return 'NoSuitable'

		# Точных соответствий нет. Попробуем найти лучшее соответствие
		weights = {'exact': 10, 'constExact': 10, 'upcast': 1, 'constUpcast': 1}
		priors = []
		for func, matchList in matches:
			weight = 0
			for res in matchList:
				weight += weights[res]
			priors.append((func, weight))
		# Сортировка по весу
		priors.sort(key = lambda pair: pair[1])
		# Если первые два равны по весу, то ошибка
		if priors[0][1] == priors[1][1]:
			return 'NoSuitable'
		return priors[0][0]


# -*- coding:utf-8 -*-
#!/usr/bin/env python
"""
Date: 2021/9/21 16:19
Desc: 巨潮资讯-数据中心-专题统计-股东股本-实际控制人持股变动
http://webapi.cninfo.com.cn/#/thematicStatistics
"""
import time

import pandas as pd
import requests
from py_mini_racer import py_mini_racer

js_str = """
    function mcode(input) {
                var keyStr = "ABCDEFGHIJKLMNOP" + "QRSTUVWXYZabcdef" + "ghijklmnopqrstuv"   + "wxyz0123456789+/" + "=";
                var output = "";
                var chr1, chr2, chr3 = "";
                var enc1, enc2, enc3, enc4 = "";
                var i = 0;
                do {
                    chr1 = input.charCodeAt(i++);
                    chr2 = input.charCodeAt(i++);
                    chr3 = input.charCodeAt(i++);
                    enc1 = chr1 >> 2;
                    enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
                    enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
                    enc4 = chr3 & 63;
                    if (isNaN(chr2)) {
                        enc3 = enc4 = 64;
                    } else if (isNaN(chr3)) {
                        enc4 = 64;
                    }
                    output = output + keyStr.charAt(enc1) + keyStr.charAt(enc2)
                            + keyStr.charAt(enc3) + keyStr.charAt(enc4);
                    chr1 = chr2 = chr3 = "";
                    enc1 = enc2 = enc3 = enc4 = "";
                } while (i < input.length);

                return output;
            }
"""

def stock_hold_control_cninfo(symbol: str = "全部") -> pd.DataFrame:
    """
    巨潮资讯-数据中心-专题统计-股东股本-实际控制人持股变动
    http://webapi.cninfo.com.cn/#/thematicStatistics
    :param symbol: choice of {"单独控制", "实际控制人", "一致行动人", "家族控制", "全部"}; 从 2010 开始
    :type symbol: str
    :return: 实际控制人持股变动
    :rtype: pandas.DataFrame
    """
    symbol_map = {
        "单独控制": "069001",
        "实际控制人": "069002",
        "一致行动人": "069003",
        "家族控制": "069004",
        "全部": "",
    }
    url = "http://webapi.cninfo.com.cn/api/sysapi/p_sysapi1033"
    random_time_str = str(int(time.time()))
    js_code = py_mini_racer.MiniRacer()
    js_code.eval(js_str)
    mcode = js_code.call("mcode", random_time_str)
    headers = {
        "Accept": "*/*",
        "Accept-Encoding": "gzip, deflate",
        "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8",
        "Cache-Control": "no-cache",
        "Content-Length": "0",
        "Host": "webapi.cninfo.com.cn",
        "mcode": mcode,
        "Origin": "http://webapi.cninfo.com.cn",
        "Pragma": "no-cache",
        "Proxy-Connection": "keep-alive",
        "Referer": "http://webapi.cninfo.com.cn/",
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36",
        "X-Requested-With": "XMLHttpRequest",
    }
    params = {
        "ctype": symbol_map[symbol],
    }
    r = requests.post(url, headers=headers, params=params)
    data_json = r.json()
    temp_df = pd.DataFrame(data_json["records"])
    temp_df.columns = [
        "控股比例",
        "控股数量",
        "证券简称",
        "实际控制人名称",
        "直接控制人名称",
        "控制类型",
        "证券代码",
        "变动日期",
    ]
    temp_df = temp_df[
        [
            "证券代码",
            "证券简称",
            "变动日期",
            "实际控制人名称",
            "控股数量",
            "控股比例",
            "直接控制人名称",
            "控制类型",
        ]
    ]
    temp_df["变动日期"] = pd.to_datetime(temp_df["变动日期"]).dt.date
    temp_df["控股数量"] = pd.to_numeric(temp_df["控股数量"])
    temp_df["控股比例"] = pd.to_numeric(temp_df["控股比例"])
    return temp_df

if __name__ == "__main__":
    stock_hold_control_cninfo_df = stock_hold_control_cninfo(symbol="全部")
    print(stock_hold_control_cninfo_df)