import tkinter as tk
from tkinter import *
import csv
from datetime import date

app = tk.Tk()
today = date.today()
today = today.strftime("%Y-%m-%d")
app.title("Trackr")
i = 0
inning = 1
side = 'Top'
balls = 0
strikes = 0
outs = 0
lastPitcher = ''
awayLineup = ['', '', '', '', '', '', '', '','']
homeLineup = ['', '', '', '', '', '', '', '','']
awayPos = 0
homePos = 0
KorBB = ''
def ButtonAction():
    global i, strikes, balls, outs, inning, side, lastPitcher, awayPos, homePos, awayLineup, homeLineup, KorBB
    KorBB = ''
    #GET PITCH DETAILS
    pitcher = entryPitcher.get()
    pitcherTeam = entryPTeam.get()
    pitcherHand = pHand.get()
    date = entryDate.get()
    batter = entryBatter.get()
    batterTeam = entryBTeam.get()
    batterHand = bHand.get()
    pitch = taggedPitch.get()
    velo = entryVelo.get()
    pitchCall = pitchResult.get()
    result = hitResult.get()
    hit = hitType.get()
    note = entryNote.get()
    taggedPitch.set('')
    entryVelo.delete(0, 'end')
    pitchResult.set('')
    hitResult.set('')
    hitType.set('')
    entryNote.delete(0, 'end')
    if strikes == 2 and (pitchCall == 'StrikeCalled' or pitchCall == 'StrikeSwinging'):
        KorBB = 'Strikeout'
    if balls == 3 and pitchCall == 'BallCalled':
        KorBB = 'Walk'
    #CREATE/WRITE TO CSV
    if i == 0:
        with open(str(today + "pitching.csv"), 'w', newline='') as f:
            colnames = ['Pitcher', 'PitcherTeam', 'PitcherSide', 'Batter', 'BatterTeam', 'BatterSide', 'Date', 'TaggedPitchType',
            'RelSpeed', 'Balls', 'Strikes', 'PitchCall', 'PlayResult', 'HitType', 'PlateLocSide', 'PlateLocHeight', 'Note', 'KorBB']
            w = csv.DictWriter(f, fieldnames=colnames)
            w.writeheader()
            w.writerow({'Pitcher':pitcher, 'PitcherTeam':pitcherTeam, 'PitcherSide':pitcherHand, 'Batter':batter, 'BatterTeam':batterTeam, 'BatterSide':batterHand,
            'Date':date, 'TaggedPitchType':pitch, 'RelSpeed':velo, 'Balls':balls, 'Strikes':strikes, 'PitchCall':pitchCall, 'PlayResult':result, 'HitType':hit,
            'PlateLocSide':PlateLocSide, 'PlateLocHeight':PlateLocHeight, 'Note':note, 'KorBB':KorBB})
            i = i + 1
    else:
        with open(str(today + "pitching.csv"), 'a') as q:
            nWriter = csv.writer(q)
            nWriter.writerow([pitcher, pitcherTeam, pitcherHand, batter, batterTeam, batterHand, date, pitch, velo, balls, strikes, pitchCall,
            result, hit, PlateLocSide, PlateLocHeight, note, KorBB])
            i = i + 1
    #COUNT CHANGES
    if pitchCall == 'StrikeCalled' or pitchCall == 'StrikeSwinging':
        strikes = strikes + 1
    if pitchCall == 'FoulBall' and strikes < 2:
        strikes = strikes + 1
    if pitchCall == 'BallCalled':
        balls = balls + 1
    #STRIKEOUT/WALK CHECK
    if strikes == 3:
        KorBB = 'Strikeout'
        outs = outs + 1
        strikes = 0
        balls = 0
        if side == "Top":
            awayLineup[awayPos] = batter
            awayPos = awayPos + 1
            if awayPos == 9:
                awayPos = 0
            entryBatter.delete(0,'end')
            entryBatter.insert(0, awayLineup[awayPos])
        if side == 'Bottom':
            homeLineup[homePos] = batter
            homePos = homePos + 1
            if homePos == 9:
                homePos = 0
            entryBatter.delete(0,'end')
            entryBatter.insert(0, homeLineup[homePos])
        bHand.set('')
    if balls == 4:
        KorBB = 'Walk'
        strikes = 0
        balls = 0
        if side == "Top":
            awayLineup[awayPos] = batter
            awayPos = awayPos + 1
            if awayPos == 9:
                awayPos = 0
            entryBatter.delete(0,'end')
            entryBatter.insert(0, awayLineup[awayPos])
        if side == 'Bottom':
            homeLineup[homePos] = batter
            homePos = homePos + 1
            if homePos == 9:
                homePos = 0
            entryBatter.delete(0,'end')
            entryBatter.insert(0, homeLineup[homePos])
        bHand.set('')
    #HBP OPTION
    if pitchCall == 'HitByPitch':
        strikes = 0
        balls = 0
        if side == "Top":
            awayLineup[awayPos] = batter
            awayPos = awayPos + 1
            if awayPos == 9:
                awayPos = 0
            entryBatter.delete(0,'end')
            entryBatter.insert(0, awayLineup[awayPos])
        if side == 'Bottom':
            homeLineup[homePos] = batter
            homePos = homePos + 1
            if homePos == 9:
                homePos = 0
            entryBatter.delete(0,'end')
            entryBatter.insert(0, homeLineup[homePos])
        bHand.set('')
    #BALL IN PLAY CHANGES
    if pitchCall == "InPlay":
        strikes = 0
        balls = 0
        if side == "Top":
            awayLineup[awayPos] = batter
            awayPos = awayPos + 1
            if awayPos == 9:
                awayPos = 0
            entryBatter.delete(0,'end')
            entryBatter.insert(0, awayLineup[awayPos])
        if side == 'Bottom':
            homeLineup[homePos] = batter
            homePos = homePos + 1
            if homePos == 9:
                homePos = 0
            entryBatter.delete(0,'end')
            entryBatter.insert(0, homeLineup[homePos])
        bHand.set('')
    #OUT(S) CHANGES
    if result == 'Out' or result == 'FieldersChoice':
        outs = outs + 1
    if result == 'DoublePlay':
        outs = outs + 2
    if result == 'TriplePlay':
        outs = outs + 3
    #INNING CHANGES (TOP)
    if outs > 2 and side == 'Top':
        strikes = 0
        balls = 0
        if inning == 1 and side == "Top":
            lastPitcher = entryPitcher.get()
        else:
            finishedInningPitcher = entryPitcher.get()
            entryPitcher.insert(0, lastPitcher)
            lastPitcher = finishedInningPitcher
        entryPitcher.delete(0, 'end')
        pTeam = entryPTeam.get()
        entryPTeam.delete(0, 'end')
        entryPTeam.insert(0, entryBTeam.get())
        entryBTeam.delete(0, 'end')
        entryBTeam.insert(0, pTeam)
        entryBatter.delete(0, 'end')
        pHand.set('')
        outs = 0
        side = 'Bottom'
    #INNING CHANGE (BOTTOM)
    if outs > 2 and side == 'Bottom':
        balls = 0
        strikes = 0
        finishedInningPitcher = entryPitcher.get()
        entryPitcher.insert(0, lastPitcher)
        lastPitcher = finishedInningPitcher
        entryPitcher.delete(0, 'end')
        pTeam = entryPTeam.get()
        entryPTeam.delete(0, 'end')
        entryPTeam.insert(0, entryBTeam.get())
        entryBTeam.delete(0, 'end')
        entryBTeam.insert(0, pTeam)
        entryBatter.delete(0, 'end')
        pHand.set('')
        outs = 0
        side = 'Top'
        inning = inning + 1
    labelCount.config(text = str('Balls: ' + str(balls) + " | Strikes: " + str(strikes)))
    labelOuts.config(text = str("Outs: " + str(outs)))
    labelInning.config(text = str("Inning: " + side + " of the " + str(inning)))

#PICKOFF/CAUGHT STEALING BUTTON
def Pickoff():
    global outs, strikes, balls, inning, side, lastPitcher
    outs = outs + 1
    #INNING CHANGES (TOP)
    if outs > 2 and side == 'Top':
        strikes = 0
        balls = 0
        if inning == 1 and side == "Top":
            lastPitcher = entryPitcher.get()
        else:
            finishedInningPitcher = entryPitcher.get()
            entryPitcher.insert(0, lastPitcher)
            lastPitcher = finishedInningPitcher
        entryPitcher.delete(0, 'end')
        pTeam = entryPTeam.get()
        entryPTeam.delete(0, 'end')
        entryPTeam.insert(0, entryBTeam.get())
        entryBTeam.delete(0, 'end')
        entryBTeam.insert(0, pTeam)
        entryBatter.delete(0, 'end')
        pHand.set('')
        outs = 0
        side = 'Bottom'
    #INNING CHANGE (BOTTOM)
    if outs > 2 and side == 'Bottom':
        balls = 0
        strikes = 0
        finishedInningPitcher = entryPitcher.get()
        entryPitcher.insert(0, lastPitcher)
        lastPitcher = finishedInningPitcher
        entryPitcher.delete(0, 'end')
        pTeam = entryPTeam.get()
        entryPTeam.delete(0, 'end')
        entryPTeam.insert(0, entryBTeam.get())
        entryBTeam.delete(0, 'end')
        entryBTeam.insert(0, pTeam)
        entryBatter.delete(0, 'end')
        pHand.set('')
        outs = 0
        side = 'Top'
        inning = inning + 1
    labelCount.config(text = str('Balls: ' + str(balls) + " | Strikes: " + str(strikes)))
    labelOuts.config(text = str("Outs: " + str(outs)))
    labelInning.config(text = str("Inning: " + side + " of the " + str(inning)))

#UNDO BUTTON
def Undo():
    f = open(str(today + "pitching.csv"), 'w')
    lines = f.readlines()
    lines = lines[:-1]
    cWriter = csv.writer(f, newline = '')
    for line in lines:
        cWriter.writerow(line)

pHand = tk.StringVar(app)
bHand = tk.StringVar(app)
taggedPitch = tk.StringVar(app)
pitchResult = tk.StringVar(app)
hitResult = tk.StringVar(app)
hitType = tk.StringVar(app)

#APP FRAME CREATION
canvas = tk.Canvas(app,height = 1400, width = 700 )
canvas.pack()

frame = tk.Frame(app, bg = 'steel blue')
frame.place(relwidth=1, relheight=1)

#LABEL/MENUS/ENTRY BOX CREATION
labelCount = tk.Label(frame, text = str('Balls: ' + str(balls) + " | Strikes: " + str(strikes)), bg = 'steel blue')
labelCount.pack()
labelOuts = tk.Label(frame, text = str("Outs: " + str(outs)), bg = 'steel blue')
labelOuts.pack()
labelInning = tk.Label(frame, text = str("Inning: " + side + " of the " + str(inning)), bg = 'steel blue')
labelInning.pack()

labelPitcher = tk.Label(frame, text = "Pitcher Name", bg = "steel blue")
labelPitcher.pack()
entryPitcher = tk.Entry(frame, bg = 'gray')
entryPitcher.pack()

labelPitcherTeam = tk.Label(frame, text = "Pitcher's Team", bg = "steel blue")
labelPitcherTeam.pack()
entryPTeam = tk.Entry(frame, bg = 'gray')
entryPTeam.pack()

labelPitcherHand = tk.Label(frame, text = "Pitcher's Handedness", bg = "steel blue")
labelPitcherHand.pack()
entryPHand = tk.OptionMenu(frame, pHand, *['Right', 'Left'])
entryPHand.pack()

labelDate = tk.Label(frame, text = "Date (Year-Month-Day)", bg='steel blue')
labelDate.pack()
entryDate = tk.Entry(frame, bg = 'gray')
entryDate.insert(0, str(today))
entryDate.pack()

labelBatter = tk.Label(frame, text = "Batter Name", bg = "steel blue")
labelBatter.pack()
entryBatter = tk.Entry(frame, bg = 'gray')
entryBatter.pack()

labelBatterTeam = tk.Label(frame, text = "Batter's Team", bg = "steel blue")
labelBatterTeam.pack()
entryBTeam = tk.Entry(frame, bg = 'gray')
entryBTeam.pack()

labelBatterHand = tk.Label(frame, text = "Batter's Handedness", bg = "steel blue")
labelBatterHand.pack()
entryBHand = tk.OptionMenu(frame, bHand, *['Right', 'Left'])
entryBHand.pack()

labelPitch = tk.Label(frame, text = "Pitch Type", bg = 'steel blue')
labelPitch.pack()
entryPitch = tk.OptionMenu(frame, taggedPitch,*['Fastball', 'Curveball', 'ChangeUp', 'Slider', 'Cutter', 'Sinker', 'Knuckleball','Other'])
entryPitch.pack()

labelVelo = tk.Label(frame, text = "Release Speed", bg = "steel blue")
labelVelo.pack()
entryVelo = tk.Entry(frame, bg = 'gray')
entryVelo.pack()

labelPitchCall = tk.Label(frame, text = "Pitch Result", bg = 'steel blue')
labelPitchCall.pack()
entryPitchCall = tk.OptionMenu(frame, pitchResult,*['StrikeCalled', 'StrikeSwinging', 'BallCalled', 'FoulBall', 'InPlay', 'HitByPitch', 'Other'])
entryPitchCall.pack()

labelResult = tk.Label(frame, text = "Play Result", bg = "steel blue")
labelResult.pack()
entryResult = tk.OptionMenu(frame, hitResult, *['Single', 'Double', 'Triple', 'HomeRun', 'Out', 'DoublePlay','TriplePlay', 'Error', 'FieldersChoice', 'Other'])
entryResult.pack()

labelHitType = tk.Label(frame, text = "Hit Type", bg = "steel blue")
labelHitType.pack()
entryHitType = tk.OptionMenu(frame, hitType, *['Groundball', 'LineDrive', 'FlyBall', 'PopUp', 'Bunt'])
entryHitType.pack()

labelNote = tk.Label(frame, text = "Notes", bg = 'steel blue')
labelNote.pack()
entryNote = tk.Entry(frame, bg = "gray")
entryNote.pack()

#PITCH LOCATION
zone = tk.PhotoImage(file = "StrikeZoneSAU.png")
labelZone = Label(frame, image = zone)
labelZone.place(x=74, y=70)
pitchLoc = Label(frame, text = "", bg = "steel blue")
pitchLoc.place(x=105, y=625)
def callback(e):
    global PlateLocSide, PlateLocHeight
    horz = e.x
    height = e.y
    if horz < 390 and horz > 70:
        PlateLocSide= round(((horz-229)/52.5), 3)
        PlateLocHeight = round(((438-height)/65.85), 3)
        pitchLoc.config(text="Pitch was located " + str(PlateLocHeight) + "ft. high and " + str(PlateLocSide) + "ft. from " +
        "the middle of the plate")
app.bind('<Button-3>', callback)

button = tk.Button(frame, text = "Store Pitch", bg = "steel blue", fg = 'black', command = ButtonAction)
button.pack()

pickoff = tk.Button(frame, text = 'Pickoff/Caught Stealing', bg = "steel blue", fg = 'black', command = Pickoff)
pickoff.pack()

undo = tk.Button(frame, text = "Undo Last Pitch", bg = "yellow", fg = 'black', command=Undo)
undo.pack()

app.mainloop()


from biocell import *
from init_area import Coordinates
#####################################################
#      <entryConditions>
#         <entryCondition type="location" molecule="biomass">
#            <coordinates x="0" y="157.5" z="0"/>
#            <coordinates x="10" y="202.5" z="180"/>
#            <param name="value"> 0.1 </param>
#            <param name="time" unit="hour">5</param>
#         </entryCondition>
#      </entryConditions>
#####################################################
#####################################################
# entryCondition
#####################################################
class EntryCondition( ParamHolder ):

    def __init__( self ):
        ParamHolder.__init__( self )
        self.addAttribute( Param( "type", "str", "location", True ) )
        self.addAttribute( Param( "molecule", "str", "", True ) )
        self.addParam( Param( "value", "float", 0.0, True ) )
        self.addParam( Param( "timestep","int", 0, True ) )
        self.mCoordinates = ItemHolder( Coordinates )

        self.mPrivateNumberHiddenParams = [ "value", "timestep" ]
        self.mPrivateBoolHiddenParams = [  ]
        self.mPrivateStringHiddenParams = [ "type", "molecule" ]
        self.mPrivateHiddenParams = self.mPrivateNumberHiddenParams + self.mPrivateBoolHiddenParams + self.mPrivateStringHiddenParams
        self.mHiddenParams = self.mHiddenParams + self.mPrivateHiddenParams
        return

    def getCoordinates( self ):
        return self.mCoordinates

    def getBioModelH( self, indent, depth ):
        lines = [ ]
        return "\n".join( lines )

    def getInitializeBioModel( self, parent_varname, container_name, indent, depth ):
        varname = "entry_condition"
        lines = [ ]
        lines.append( (depth*indent) + "{" )
        depth += 1

        lines.append( (depth*indent) + "EntryCondition *%s = new EntryCondition( );" % (varname, ) )
        lines.append( ParamHolder.getInitializeBioModel( self, varname, indent, depth ) )
        s = self.getInitializeBioModelSetDataMembers( varname, "->", indent, depth,
                                                      self.mPrivateBoolHiddenParams,
                                                      self.mPrivateNumberHiddenParams,
                                                      self.mPrivateStringHiddenParams )
        lines.append( s )

        s = (depth*indent) + "%s%sset%s( %s );" % (varname, "->", "AgentSpecies", parent_varname, )
        lines.append( s )

        coordinate_container_name = "%s->getCoordinates()" % ( varname, )
        for i in range( len( self.mCoordinates ) ):
            lines.append( self.mCoordinates[ i ].getInitializeBioModel( coordinate_container_name, indent, depth ) )

        lines.append( (depth*indent) + "%s.push_back( %s );" % (container_name, varname, ) )
        depth -= 1;
        lines.append( (depth*indent) + "}" )
        return "\n".join( lines )

    def __str__(self):
        s  = "<entryCondition" + self.formatAttributes() + ">\n"
        s += ParamHolder.__str__( self )
        s += str( self.mCoordinates )
        s += "</entryCondition>\n"
        return s

    def __repr__(self):
        return str(self)

def main():
    print( "FIXME: no tester for " + str( __file__ ) )
    return

if __name__ == "__main__":
    main()


'''
Created on Aug 16, 2017

@author: sumanth-3058
'''

class ZCRMException(Exception):
    '''
    This is the custom exception class for handling for Client Library exceptions
    '''
    message = 'Error occurred for {url}. Error Code: {code} Response error_content: {error_content}. Error Details::{error_details}'

    def __init__(self, url, status_code, err_message,exception_code='error',details=None,content=None):
        self.url = url
        self.status_code = status_code
        self.error_content = content
        self.error_message=err_message
        self.error_code=exception_code
        self.error_details=details
        Exception.__init__(self,status_code)

    def __str__(self):
        return self.message.format(url=self.url,code=self.status_code,error_content=self.error_content,error_details=self.error_details)

import logging
logger=logging.getLogger('Client_Library')
class Logger(object):
    '''
    This class is to log the exceptions onto console
    '''
    @staticmethod
    def add_log(message,level=None,exception=None):
        logger.setLevel(logging.DEBUG)
        console_handler = logging.StreamHandler()
        # create formatter and add it to the handlers
        formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
        try:
            from .Utility import ZCRMConfigUtil
        except ImportError:
            from Utility import ZCRMConfigUtil
        log_path=ZCRMConfigUtil.config_prop_dict['applicationLogFilePath']
        if log_path is not None and log_path.strip()!="":
            import os
            log_path=os.path.join(log_path,'client_library.log')
            file_handler=logging.FileHandler(log_path)
            file_handler.setLevel(logging.DEBUG)
            file_handler.setFormatter(formatter)
            logger.addHandler(file_handler)

        console_handler.setLevel(logging.DEBUG)
        console_handler.setFormatter(formatter)
        # add the handlers to the logger
        logger.addHandler(console_handler)

        if(exception!=None):
            message+='; Exception Message::'+exception.__str__()
        if(level==logging.ERROR):
            logger.error(message)
        elif(level==logging.INFO or level==logging.DEBUG):
            logger.debug(message)
        elif(level==logging.WARNING):
            logger.warning(message)


from __future__ import print_function, division

import numpy as np
from scipy.stats import poisson

class PoissonMixture:
    def __init__(self, pi=0.5, max_iters=100, tol=1e-3):
        self.pi = pi
        self.max_iters = max_iters
        self.tol = tol

    @property
    def mask(self):
        if hasattr(self, '_mask'):
            return self._mask
        m = (self.p > 0.5)
        self._mask = m
        return m

    def fit(self, x, verbose=False):
        self.x = x

        max_iters = self.max_iters
        tol = self.tol

        pi = self.pi

        # randomly initialize p
        p = np.random.binomial(1, pi, size=x.shape)

        # calculate initial mus
        mu1 = np.sum(x*p/np.sum(p))
        mu2 = np.sum(x*(1-p)/np.sum(1-p))

        logp1 = poisson.logpmf(x, mu1) + np.log(pi)
        logp2 = poisson.logpmf(x, mu2) + np.log1p(-pi)

        ma = np.maximum(logp1, logp2)
        logp = np.log(np.exp(logp1 - ma) + np.exp(logp2 - ma)) + ma
        logp_next = np.sum(logp)
        logp_cur = -np.inf

        p = np.exp(logp1 - ma)/(np.exp(logp1 - ma) + np.exp(logp2 - ma))
        pi = np.mean(p)

        if verbose:
            print('iter {} | logp {} | pi {} | mu1 {} | mu2 {}'.format(0, logp_next, pi, mu1, mu2))

        # iterate
        for i in range(max_iters):
            if (logp_next - logp_cur) < tol:
                break

            logp_cur = logp_next

            # estimate mu
            mu1 = np.sum(x*p)/np.sum(p)
            mu2 = np.sum(x*(1-p))/np.sum(1-p)

            # estimate p
            logp1 = poisson.logpmf(x, mu1) + np.log(pi)
            logp2 = poisson.logpmf(x, mu2) + np.log1p(-pi)

            ma = np.maximum(logp1, logp2)
            logp = np.log(np.exp(logp1 - ma) + np.exp(logp2 - ma)) + ma
            logp_next = np.sum(logp)

            p = np.exp(logp1 - ma)/(np.exp(logp1 - ma) + np.exp(logp2 - ma))
            pi = np.mean(p)

            if verbose:
                print('iter {} | logp {} | pi {} | mu1 {} | mu2 {}'.format(i+1, logp_next, pi, mu1, mu2))

        # if mu2 > mu1, flip pi
        if mu2 > mu1:
            p = 1-p
            pi = 1-pi

            temp = mu1
            mu1 = mu2
            mu2 = temp

        self.pi = pi
        self.p = p
        self.mu1 = mu1
        self.mu2 = mu2

        if verbose:
            print('terminated after {} iterations, final logp change = {}'.format(i+1, (logp_next-logp_cur)))

        return self


from utils import *

# atomic units
hbar = 1.0
m = 1.0
# set precision of numerical approximation
steps = 2000

# set depths and widths of wells and the well separation
W = 1
D = 25.0
B = 0.05
Vinf = 20
Opacity = 1/2

# set length variable for xvec
A = 2.0*((2*W)+B)
# divide by two so a separation from -B to B is of input size
B = B/2.0
# create x-vector from -A to A
xvec = np.linspace(-A, A, steps, dtype=np.float_)
# get step size
h = xvec[1]-xvec[0]
# create the potential from step function
U = -D* (step_func(xvec+W+B)-step_func(xvec+B) + step_func(xvec-B)-step_func(xvec-W-B)) + Vinf*(1-0)*(step_func(xvec+B) - step_func(xvec-B))
# create Laplacian via 3-point finite-difference method
Laplacian = (-2.0*np.diag(np.ones(steps))+np.diag(np.ones(steps-1), 1)
             + np.diag(np.ones(steps-1), -1))/(float)(h**2)
# create the Hamiltonian
Hamiltonian = np.zeros((steps, steps))
[i, j] = np.indices(Hamiltonian.shape)
Hamiltonian[i == j] = U
Hamiltonian += (-0.5)*((hbar**2)/m)*Laplacian
# diagonalize the Hamiltonian yielding the wavefunctions and energies
E, V = diagonalize_hamiltonian(Hamiltonian)
# determine number of energy levels to plot (n)
n = 0
while E[n] < 0:
    n += 1
# print output
output(['Well Widths', 'Well Depths', 'Well Separation'], [W, D, B*2], E, n)
# create plot
finite_well_plot(E, V, xvec, steps, n, U)


import serial
import time
import glob

def hotplug(f):
    def decor(*args):
        if _ser is None:
            reconnect()
        try:
            ret = f(*args)
            _ser.flush()
            return ret
        except:
            close()
            raise
        return None
    return decor

def reconnect():
    global _ser
    close()
    for dev in glob.glob("/dev/serial/by-path/*"):
        ser = serial.Serial(dev, 9600, timeout=2)
        ser.setDTR(False)
        time.sleep(0.1)
        ser.setDTR(True)
        try:
            if "connected" in ser.readline().decode("utf-8"):
                print("Established")
                _ser = ser
                return
        except:
            pass

def close():
    global _ser
    try:
        _ser.close()
    except:
        pass
    del _ser
    _ser = None

@hotplug
def set_led_mode(mode):
    global _led
    _ser.write(("l%db" % mode).encode())
    _led = mode

@hotplug
def get_led_mode():
    global _led
    _ser.write('a'.encode())
    mode = int.from_bytes(_ser.read(), byteorder='big')
    if _led is not mode:
        set_led_mode(_led)
        _ser.write('a'.encode())
        _led = int.from_bytes(_ser.read(), byteorder='big')
    return _led

@hotplug
def toggle_led():
    set_led_mode(int(get_led_mode()) + 1)

@hotplug
def move_motor(axis, amount):
    _pos[axis] += amount
    _ser.write(('m%d%s%dg' % (axis, "+" if amount > 0 else "", amount)).encode())

def calibrate_motors(vals):
    global _pos
    _pos = vals

def get_pos(axis):
    return _pos[axis]

_ser = None
_led = 0
_pos = [0, 0, 0]
reconnect()


# -*- coding: utf-8 -*-
"""
Created on Mon Apr 23 15:39:28 2018

@author: avarfolomeev
"""
import struct
from collections import namedtuple
from glob import glob
import os.path
import numpy as np
import matplotlib.pyplot as plt

from pyquaternion import Quaternion
import math

import navpy

from ROS_ts import ROS_ts

IMUstruct_string = 'BBBBiixxxxdddddddddddddddddddii';
_billion = 1000000000;

def unpack_IMUdata(data):
    keys = [
    'bIMU', 'bFix', 'bTwist', 'bTimeRef',
    'ts_s', 'ts_ns',
    'Qx', 'Qy', 'Qz', 'Qw',
    'AVx', 'AVy',  'AVz',
    'LAx', 'LAy', 'LAz',
    'Lat', 'Lon',  'Alt',
    'TwLx', 'TwLy', 'TwLz',
    'TwAx', 'TwAy', 'TwAz',
    'Tref_s', 'Tref_ns']
    a = struct.unpack(IMUstruct_string,data);
    d = dict(zip(keys,a));

    if (not d['bFix']):
        d['Lat'] = d['Lon'] = d['Alt'] = None;

    if (not d['bIMU']):
        d['Qx'] = d['Qy'] = d['Qz'] = d['Qw'] = None;
        d['AVx'] = d['AVy'] =  d['AVz'] = None;
        d['LAx'] = d['LAy'] = d['LAz'] = None;

    if (not d['bTwist']):
        d['TwLx'] = d['TwLy'] = d['TwLz'] = None;
        d['TwAx'] = d['TwAy'] = d['TwAz'] = None;

    if (not d['bTimeRef']):
        d['Tref_s'] = d['Tref_ns'] = None;

    return d

def read_IMUdata(path):
    imu_path = os.path.join(path, '*.imu');

    imu_files = sorted(glob(imu_path));

    IMUdata = [];
    for fname in imu_files:
        data = np.fromfile(fname,dtype=np.int8);
        IMUdata.append(unpack_IMUdata(data));

    return IMUdata;

def read_IMUfile(filename):

    RECORDSIZE = struct.calcsize(IMUstruct_string);
    IMUdata = [];
    filesize = os.path.getsize(filename);
    nrecords = filesize//RECORDSIZE;

    file = open(filename,'rb')

    for i in range(nrecords):
        data = np.fromfile(file,dtype=np.int8,count=RECORDSIZE);
        _d = unpack_IMUdata(data);
        if (_d['bFix'] and _d['bIMU'] and _d['bTimeRef']):
            IMUdata.append(_d);
    file.close();
    return np.array(IMUdata);

def extract_position(IMUdata):
    bFix = np.array([(d['bFix'] & d['bIMU']) == 1  for d in IMUdata]);
    Pos = [(d['Lat'], d['Lon'], d['Alt']) for d in np.array(IMUdata)[bFix]];
    return np.array(Pos)

def extract_linacc(IMUdata):
    bFix = np.array([(d['bFix'] & d['bIMU']) == 1  for d in IMUdata]);
    acc = [(d['LAx'], d['LAy'], d['LAz']) for d in np.array(IMUdata)[bFix]];

    return np.array( acc )

def extract_quaternion(IMUdata):
    bFix = np.array([(d['bFix'] & d['bIMU']) == 1  for d in IMUdata]);
    Q = [Quaternion(d['Qw'], d['Qx'], d['Qy'], d['Qz']) for d in np.array(IMUdata)[bFix]]
    return np.array( Q )

def extract_ts(IMUdata):
    bFix = np.array([(d['bFix'] & d['bIMU']) == 1  for d in IMUdata]);
    ts  = [d['ts_s'] * _billion + d['ts_ns'] for d in np.array(IMUdata)[bFix]];
    return np.array(ts);

def extract_time_ref(IMUdata):
    bFix = np.array([(d['bFix'] & d['bIMU'])==1 for d in IMUdata]);
    ts  = [d['Tref_s'] * _billion + d['Tref_ns'] for d in np.array(IMUdata)[bFix]];
    return np.array(ts);

    #only linear - there were no angle velocities :(
def extract_twist(IMUdata):
    bTwist = np.array([d['bTwist']==1 for d in IMUdata]);

    twL = [(d['TwLx'],d['TwLy'],d['TwLz']) for d in np.array(IMUdata)[bTwist]];
    return np.array(twL)

#утащил из википедии
def quat_to_euler_angle(q):
    return quaternion_to_euler_angle(q[0], q[1], q[2], q[3])

def quaternion_to_euler_angle(w, x, y, z):
	ysqr = y * y

	t0 = +2.0 * (w * x + y * z)
	t1 = +1.0 - 2.0 * (x * x + ysqr)
	X = math.atan2(t0, t1)

	t2 = +2.0 * (w * y - z * x)
	t2 = +1.0 if t2 > +1.0 else t2
	t2 = -1.0 if t2 < -1.0 else t2
	Y = math.asin(t2)

	t3 = +2.0 * (w * z + x * y)
	t4 = +1.0 - 2.0 * (ysqr + z * z)
	Z = math.atan2(t3, t4)

	return (X, Y, Z)

def extract_euler(IMUdata):
    bFix = np.array([(d['bFix'] & d['bIMU']) == 1  for d in IMUdata]);
    e = [quaternion_to_euler_angle(d['Qw'], d['Qx'], d['Qy'], d['Qz']) for d in np.array(IMUdata)[bFix]]
    return np.array( e )

def extract_yaw_pitch_roll(IMUdata):
    q = extract_quaternion(IMUdata);
    ypr = [q0.yaw_pitch_roll for q0 in q]
    return np.array( ypr )

def lla2ecef(lla):
    ecef = [ navpy.lla2ecef(pos[0],pos[1],pos[2]) for pos in lla];
    return np.array(ecef);

def lla2ned(lla, ref=None):
    if (ref == None):
        ref = lla[0,:3];
    ned = [ navpy.lla2ned(pos[0],pos[1],pos[2], ref[0], ref[1], ref[2]) for pos in lla];
    return np.array(ned);

def lla2enu(lla, ref=None):
    ned = lla2ned(lla, ref);
    enu = ned[:,[1,0,2]];
    enu [:,2] = 0 - enu[:,2];
    return enu;

def ned2lla(ned, ref):
    lla = navpy.ned2lla(ned, ref[0], ref[1], ref[2]);
    return np.array(lla).transpose();

def enu2lla(enu, ref):
    ned = enu[:,[1,0,2]];
    ned [:,2] = 0 - ned[:,2];
    return (ned2lla(ned,ref));

#%%
def save_matrix(filename, mat):
        with open(filename, 'wt') as out_file:

            for row in range (mat.shape[0]):
                for col in range (mat.shape[1]):
                    out_file.writelines("{} ".format(mat[row,col]))
                out_file.write("\r\n")
        out_file.close();


class Solution(object):
    """
    Merge two sorted array.
    BUT do not return anything. Rather, change the nums1.
    num1 contains nums1 element followed by 0's with the length n.
    """
    def merge(self, nums1, m, nums2, n):
        """
        :type nums1: List[int]
        :type m: int
        :type nums2: List[int]
        :type n: int
        :rtype: None Do not return anything, modify nums1 in-place instead.
        """

        f, s = m - 1, n - 1
        p = len(nums1) - 1
        while f >= 0 and s >= 0:
            if nums1[f] > nums2[s]:
                nums1[p] = nums1[f]
                f -= 1
            else:
                nums1[p] = nums2[s]
                s -= 1
            p -= 1

        # If f != -1, you don't need to do anything because it's already filled out.
        # Only when s != -1, you need to do extra.
        if s != -1:
            # Since the current s position is not included in nums1, you need to include it by s + 1
            nums1[:s + 1] = nums2[:s + 1]


import Tkinter as tk
from HikeBuddy import HikeBuddy
from Database import Database
TITLE_FONT = ("Helvetica", 14, "bold")
db = Database()
class BeWeaveApp(tk.Tk):
    """Author: Thomas Schmidt\n
    Date: 3/5/2017\n
    Author: Evan Pernu\n
    UW NetID: epernu\n
    Date: 3/14/2017\n
    This is the main app that controls each frame."""

    def __init__(self, hikes, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)

        #This container stacks a bunch of frames on top of each other
        #The one we want visible will be raised above the others
        container = tk.Frame(self)
        container.pack(side="top", fill="both", expand=True)
        container.grid_rowconfigure(0, weight=1)
        container.grid_columnconfigure(0, weight=1)

        self.title("Hike Away")
        self.frames = {}
        self.frames["VotePage"] = VotePage(hikes,parent=container, controller=self)
        self.frames["HomePage"] = HomePage(hikes, parent=container, controller=self)

        self.frames["VotePage"].grid(row=0, column=0, sticky="nsew")
        self.frames["HomePage"].grid(row=0, column=0, sticky="nsew")

        self.show_frame("HomePage")

    def show_frame(self, page_name):
        """Show a frame for the given page name"""
        frame = self.frames[page_name]
        frame.tkraise()

class HomePage(tk.Frame):
    """Author: Thomas Schmidt\n
    Date: 3/5/2017\n
    Author: Evan Pernu\n
    UW NetID: epernu\n
    Date: 3/11/2017\n
    This is the HomePage Class that will show the home page screen once the user has logged in."""

    def __init__(self, hikes, parent, controller):
        tk.Frame.__init__(self, parent)
        self.controller = controller

        label = tk.Label(self, text="Welcome!", font=TITLE_FONT)
        label.pack(side="top", fill="x", pady=10)

        button2 = tk.Button(self, text=hikes[0].name, width=28,
                            command=lambda: controller.show_frame("VotePage"))
        button4 = tk.Button(self, text=hikes[1].name, width=28,
                            command=lambda: controller.show_frame("VotePage"))

        button2.pack(pady=5)
        button4.pack(pady=5)
        button = tk.Button(self, text=hikes[2].name, width=28,
                           command=lambda: controller.show_frame("VotePage"))
        button.pack()

class VotePage(tk.Frame):
    """Author: Thomas Schmidt\n
    Date: 3/5/2017\n
    Author: Evan Pernu\n
    UW NetID: epernu\n
    Date: 3/11/2017\n
    This is the HomePage Class that will show the home page screen once the user has logged in."""

    def __init__(self, hikes, parent, controller):
        tk.Frame.__init__(self, parent)
        self.controller = controller
        self.parent = parent
        db.add_user_hike(1, hikes[0].trail_id, None)
        label = tk.Label(self, text="How Hard Was \nThe Hike", font=TITLE_FONT)
        label.pack(side="top", fill="x", pady=10)

        button2 = tk.Button(self, text="Too Hard", width=16,
                            command=lambda: self.too_hard(hikes[0]))
        button4 = tk.Button(self, text="Perfect", width=16,
                            command=lambda: self.perfect(hikes[0]))
        button2.pack(pady=5)
        button4.pack(pady=5)

        button = tk.Button(self, text="Too Easy", width=16,
                           command=lambda: self.too_easy(hikes[0]))
        button.pack()

    def too_hard(self, hike):
        db.update_user_hike(1, hike.trail_id, 1)
        # db.add_user_hike(1, hike.trail_id)
        db.update_usr_lvl(1, hike.trail_id)
        self.parent.destroy()
        self.destroy()
        self.controller.destroy()
    def perfect(self, hike):
        db.update_user_hike(1, hike.trail_id, 0)
        # db.add_user_hike(1, hike.trail_id)
        db.update_usr_lvl(1, hike.trail_id)
        self.parent.destroy()
        self.destroy()
        self.controller.destroy()
    def too_easy(self, hike):
        db.update_user_hike(1, hike.trail_id, -1)
        # db.add_user_hike(1, hike.trail_id)
        db.update_usr_lvl(1, hike.trail_id)
        self.parent.destroy()
        self.destroy()
        self.controller.destroy()

sample = HikeBuddy()
hikes = sample.find_suggestions()

app = BeWeaveApp(hikes)
app.mainloop()


import matplotlib
import matplotlib.pyplot as plt

from structural_tools.datafile_content import DatafileContent
from analyzers.mmt_density_profile import mmt_density_profile

if __name__ == '__main__':
    multip = 10

    fnames_300 = ['na_mmt_300_diffusion/na_mmt.{0}000.data'.format(i)
        for i in range(501, 751)]
    fnames_500 = ['na_mmt_500_diffusion/na_mmt.{0}000.data'.format(i)
        for i in range(501, 751)]

    # 721 -- 732
    old_coords = {
        atom['atom_id']: {
            'x': atom['x'],
            'y': atom['y']
        } for atom in DatafileContent(fnames_300[0]).atoms[720:732]
    }

    Ns300 = [0]
    for fname in fnames_300:
        print(fname)

        dfc = DatafileContent(fname)
        new_coords = {
            atom['atom_id']: {
                'x': atom['x'],
                'y': atom['y']
            } for atom in dfc.atoms[720:732]
        }
        lx = dfc.xhi - dfc.xlo
        ly = dfc.yhi - dfc.ylo

        n = Ns300[-1]
        for k in new_coords.keys():
            dx = abs(new_coords[k]['x'] - old_coords[k]['x'])
            dy = abs(new_coords[k]['y'] - old_coords[k]['y'])
            dx = min(dx, abs(lx - dx))
            dy = min(dy, abs(ly - dy))
            if dx > 1 or dy > 1:
                n += 1
                #print(k, dx, dy)

        Ns300.append(n)
        old_coords = new_coords

    ##########

    old_coords = {
        atom['atom_id']: {
            'x': atom['x'],
            'y': atom['y']
        } for atom in DatafileContent(fnames_500[0]).atoms[720:732]
    }

    Ns500 = [0]
    for fname in fnames_500:
        print(fname)

        dfc = DatafileContent(fname)
        new_coords = {
            atom['atom_id']: {
                'x': atom['x'],
                'y': atom['y']
            } for atom in dfc.atoms[720:732]
        }
        lx = dfc.xhi - dfc.xlo
        ly = dfc.yhi - dfc.ylo

        n = Ns500[-1]
        for k in new_coords.keys():
            dx = abs(new_coords[k]['x'] - old_coords[k]['x'])
            dy = abs(new_coords[k]['y'] - old_coords[k]['y'])
            dx = min(dx, abs(lx - dx))
            dy = min(dy, abs(ly - dy))
            if dx > 1 or dy > 1:
                n += 1
                #print(k, dx, dy)

        Ns500.append(n)
        old_coords = new_coords

    #print(Ns)

    fig = plt.figure()
    plt.xlabel('Время, фс')
    plt.ylabel('Количество перескоков')

    line300, = plt.plot(range(len(Ns300)), Ns300, color='k')
    line500, = plt.plot(range(len(Ns500)), Ns500, color='r')

    matplotlib.pyplot.legend([line300, line500], ['300 К', '500 К'],
        loc="upper left")

    fig.savefig('jumps.pdf')

    print('done!')


import cv2
import gdal
import numpy as np
import shutil
import random
from typing import Union
from tqdm import tqdm
from pathlib import Path
from skimage.util.shape import view_as_windows

class DatasetProducing(object):

    def __init__(self, raster: gdal.Dataset,
                       pos: np.ndarray,
                       reso: float,
                       n_class: int=None,
                       seed: int=None,
                       alpha: float=0.6):
        """ Initialization

        # Args:
            raster (gdal.Dataset): image
            n_class (int, optional): class number. Defaults to None.
            seed (int, optional): random seed. Defaults to None.
            alpha (float, optional): blending alpha value.
        """
        super().__init__()
        assert 0 <= alpha <= 1

        self.ds = raster
        self.pos = pos
        self.reso = reso
        self.n_class = n_class

        # image and label visualization
        np.random.seed(seed if seed is not None else np.random.randint(2**31))
        self.lb_color = np.random.randint(256, size=(self.n_class, 3))
        self.alpha = alpha

    def split(self, size: int, ratio: float, filter: tuple=None, windows: np.ndarray=None):
        """Splitting the images into blocks

        # Args:
            size (int): block size
            ratio (float): overlapping ratio
            filter (tuple, optional): coverage ratio lower/upper bound. (Defaults to None.)
        """
        height, width = self.ds.RasterYSize, self.ds.RasterXSize
        stride = int(size * (1 - ratio))

        assert size <= height and size <= width
        assert 0 <= ratio < 1

        self.im_tiles = np.empty((0, size, size, 3), dtype=np.uint8)
        self.lb_tiles = np.empty((0, size, size), dtype=np.uint8)

        if len(windows):
            for win in windows:
                coords = self._win_size_trim(win, width, height)
                im, lb = self._label_image_generate(coords)
                _im = view_as_windows(im, (size, size, 3), stride)
                self.im_tiles = np.concatenate((self.im_tiles, _im.reshape(-1, *(size, size, 3))))
                _lb = view_as_windows(lb, (size, size), stride)
                self.lb_tiles = np.concatenate((self.lb_tiles, _lb.reshape(-1, *(size, size))))
        else:
            im, lb = self._label_image_generate()
            self.im_tiles = view_as_windows(im, (size, size, 3), stride)
            self.im_tiles = self.im_tiles.reshape(-1, *(size, size, 3))
            self.lb_tiles = view_as_windows(lb, (size, size), stride)
            self.lb_tiles = self.lb_tiles.reshape(-1, *(size, size))

        if filter is not None:
            assert len(filter) == 2
            self._filter_by_coverage(filter)

    def save(self, split_ratio: float=0.8, filename: str='', save_dir: Union[str, Path]=''):
        assert isinstance(save_dir, (str, Path)) or save_dir is None
        assert 0.5 <= split_ratio <= 1, "Split Ratio must in rnage [0.5, 1]."

        self.save_dir = Path(save_dir) if save_dir else Path.cwd()
        self.save_dir = self.save_dir.joinpath('PascalVOC')
        if self.save_dir.exists(): shutil.rmtree(str(self.save_dir))

        self.save_dir.joinpath('JPEGImages').mkdir(parents=True)
        self.save_dir.joinpath('SegmentationClass').mkdir(parents=True)
        self.save_dir.joinpath('VisualImages').mkdir(parents=True)

        idx, fns = 0, []
        with tqdm(total=len(self.im_tiles)) as pbar:
            for im, lb in zip(self.im_tiles, self.lb_tiles):
                if np.max(im) == 0: continue
                vs = self._label_visualization(im, lb)
                fns.append(f'{filename}_{idx}')
                cv2.imwrite(str(self.save_dir.joinpath('JPEGImages', f'{fns[-1]}.png')), im)
                cv2.imwrite(str(self.save_dir.joinpath('SegmentationClass', f'{fns[-1]}.png')), lb)
                cv2.imwrite(str(self.save_dir.joinpath('VisualImages', f'{fns[-1]}.png')), vs)
                idx += 1
                pbar.update(1)

        self.save_train_val(fns, split_ratio)

    def save_train_val(self, fns: list, ratio: float):
        """ Splitting the training and validation
        data through image name by specified ratio

        # Args:
            fns (list): filenames
            ratio (float): train and validation split ratio
        """
        det_dir = self.save_dir.joinpath('ImageSets/Segmentation')
        det_dir.mkdir(parents=True)

        train_num = int(len(fns) * ratio)
        random.shuffle(fns)
        with open(str(det_dir.joinpath('train.txt')), 'w') as file:
            file.writelines('\n'.join(fns[:train_num]))
        with open(str(det_dir.joinpath('val.txt')), 'w') as file:
            file.writelines('\n'.join(fns[train_num:]))

    def _filter_by_coverage(self, filter: tuple):
        """ Filter the mask by coverage """
        l_b, u_b = filter
        assert 0 <= l_b < u_b <= 1

        def coverage_ratio(mask):
            if np.max(mask) == 0: return 0
            area = mask.shape[0] * mask.shape[1]
            return np.count_nonzero(mask)/area

        new_im_tiles = []
        new_lb_tiles = []

        for im, lb in zip(self.im_tiles, self.lb_tiles):
            if l_b <= coverage_ratio(lb) <= u_b:
                new_im_tiles.append(im)
                new_lb_tiles.append(lb)

        self.im_tiles = np.array(new_im_tiles).astype('uint8')
        self.lb_tiles = np.array(new_lb_tiles).astype('uint8')

    def _label_visualization(self, im, lb):
        vs = np.zeros_like(im)
        for lb_class in range(self.n_class):
            vs[lb == lb_class] = self.lb_color[lb_class]
        vs[lb == 0] = im[lb == 0]
        return (vs*self.alpha + im*(1-self.alpha)).astype('uint8')

    def _win_size_trim(self, win, width, height):
        x1, y1, x2, y2 = win
        x1 = max(0, x1)
        y1 = max(0, y1)
        x2 = min(width, x2)
        y2 = min(height, y2)
        return x1, y1, x2 ,y2

    def _label_image_generate(self, coords: list=None):
        palm_radius = 1.5 # unit: meter

        if coords is None:
            im = self.ds.ReadAsArray()[:3]
            im = np.moveaxis(im, 0, -1)[..., ::-1]
            lb = np.zeros((self.ds.RasterYSize, self.ds.RasterXSize), dtype='uint8')
            for x, y in self.pos:
                cv2.circle(lb, (x, y),
                    int(palm_radius / self.reso),
                    (1,), -1, cv2.LINE_AA)
        else:
            x1, y1, x2, y2 = list(map(int, coords))
            x_in_range = np.logical_and(self.pos[:,0] >= x1, self.pos[:,0] < x2)
            y_in_range = np.logical_and(self.pos[:,1] >= y1, self.pos[:,1] < y2)
            pos_in_win = self.pos[np.logical_and(x_in_range, y_in_range)]

            im = self.ds.ReadAsArray(x1, y1, x2-x1, y2-y1)[:3]
            im = np.moveaxis(im, 0, -1)[..., ::-1]
            lb = np.zeros((y2 - y1, x2 - x1), dtype='uint8')

            for x, y in pos_in_win:
                cv2.circle(lb, (x-x1, y-y1),
                    int(palm_radius / self.reso),
                    (1,), -1, cv2.LINE_AA)

        return im, lb

if __name__ == "__main__":
    im = cv2.imread('_1.tif', -1)
    mask = (cv2.imread('_1_mask.png', -1) / 255).astype('uint8')
    db = DatasetProducing(im, mask)
    db.split(800, 0.9)
    db.save(filename='_1')


import copy
import random

class Hat:
    def __init__(self, **kwargs):
        self.contents = []
        for color, count in kwargs.items():
            self.contents.extend([color] * count)

    def draw(self, num_balls):
        if num_balls >= len(self.contents):
            return self.contents
        else:
            drawn_balls = random.sample(self.contents, num_balls)
            for ball in drawn_balls:
                self.contents.remove(ball)
            return drawn_balls

def experiment(hat, expected_balls, num_balls_drawn, num_experiments):
    success_count = 0
    for _ in range(num_experiments):
        hat_copy = copy.deepcopy(hat)
        drawn_balls = hat_copy.draw(num_balls_drawn)
        drawn_dict = {}

        for ball in drawn_balls:
            if ball in drawn_dict:
                drawn_dict[ball] += 1
            else:
                drawn_dict[ball] = 1

        for color, count in expected_balls.items():
            if color not in drawn_dict or drawn_dict[color] < count:
                break
        else:
            success_count += 1

    return success_count / num_experiments


# everything you'll need is imported:
from view import terminal_view
from model.sales import sales
from controller import common

""" Sales module

Data table structure:
    * id (string): Unique and random generated identifier
        at least 2 special characters (except: ';'), 2 number, 2 lower and 2 upper case letters)
    * title (string): Title of the game sold
    * price (number): The actual sale price in USD
    * month (number): Month of the sale
    * day (number): Day of the sale
    * year (number): Year of the sale
"""

def run():
    """
    Starts this module and displays its menu.
     * User can access default special features from here.
     * User can go back to main menu from here.

    Returns:
        None
    """

    table = sales.get_sales_table_from_file()
    title_list = ["ID", "Title","Price", "Month", "Day", "Year"]
    options = ["View records",
               "Add record",
               "Remove record",
               "Update record",
               "What is the id of the item that was sold for the lowest price?",
               "Which items are sold between two given dates?"]

    choice = None
    while choice != "0":
        choice = terminal_view.get_choice_inner_menu(options, "Sales manager")
        if choice == "1":
            terminal_view.print_table(table, title_list)
        elif choice == "2":
            record = terminal_view.get_inputs(title_list[1::],"Please provide new item data")
            table = sales.add(table, record)
        elif choice == "3":
            id_to_delete_table = terminal_view.get_inputs(["ID"],"Item to delete")
            id_to_delete = id_to_delete_table[0]
            table = sales.remove(table, id_to_delete)
        elif choice == "4":
            records = terminal_view.get_inputs(title_list,"Edit item")
            record_id = records[0]
            table = sales.update(table, record_id, records)
        elif choice == "5":
            lowest_price = sales.get_lowest_price_item_id(table)
            description = ["ID of item that was sold for the lowest price:"]
            value = [[lowest_price]]
            terminal_view.print_table(value, description)
        elif choice == "6":
            day_from_input = terminal_view.get_inputs(["Day from"],"")
            while not day_from_input[0].isdigit():
                day_from_input = terminal_view.get_inputs(["Your input is not digit. Choose correct day from range 1-31"],"")
            while day_from_input[0].isdigit():
                while int(day_from_input[0]) > 31 or int(day_from_input[0]) < 1:
                    day_from_input = terminal_view.get_inputs(["Choose correct day from range 1-31"],"")
                    while not day_from_input[0].isdigit():
                        day_from_input = terminal_view.get_inputs(["Your input is not digit. Choose correct day from range 1-31"],"")
                break
            day_from = day_from_input[0]

            month_from_input = terminal_view.get_inputs(["Month from"],"")
            while not month_from_input[0].isdigit():
                month_from_input = terminal_view.get_inputs(["Your input is not digit. Choose correct month from range 1-12"],"")
            while month_from_input[0].isdigit():
                while not int(month_from_input[0]) < 13 or not int(month_from_input[0]) > 0:
                    month_from_input = terminal_view.get_inputs(["Choose correct month from range 1-12"],"")
                    while not month_from_input[0].isdigit():
                        month_from_input = terminal_view.get_inputs(["Your input is not digit. Choose correct month from range 1-12"],"")
                break
            month_from = month_from_input[0]

            year_from_input = terminal_view.get_inputs(["Year from"],"")
            while not year_from_input[0].isdigit():
                year_from_input = terminal_view.get_inputs(["Your input is not digit. Choose correct year"],"")
            while year_from_input[0].isdigit():
                while not int(year_from_input[0]) > 0:
                    year_from_input = terminal_view.get_inputs(["Choose correct year"],"")
                    while not year_from_input[0].isdigit():
                        year_from_input = terminal_view.get_inputs(["Your input is not digit. Choose correct year"],"")
                break
            year_from = year_from_input[0]

            day_to_input = terminal_view.get_inputs(["Day to"],"")
            while not day_to_input[0].isdigit():
                day_to_input = terminal_view.get_inputs(["Your input is not digit. Choose correct day from range 1-31"],"")
            while day_to_input[0].isdigit():
                while not int(day_to_input[0]) < 32 or not int(day_to_input[0]) > 0:
                    day_to_input = terminal_view.get_inputs(["Choose correct day from range 1-31"],"")
                    while not day_to_input[0].isdigit():
                        day_to_input = terminal_view.get_inputs(["Your input is not digit. Choose correct day from range 1-31"],"")
                break
            day_to = day_to_input[0]

            month_to_input = terminal_view.get_inputs(["Month to"],"")
            while not month_to_input[0].isdigit():
                month_to_input = terminal_view.get_inputs(["Your input is not digit. Choose correct month from range 1-12"],"")
            while month_to_input[0].isdigit():
                while not int(month_to_input[0]) < 13 or not int(month_to_input[0]) > 0:
                    month_to_input = terminal_view.get_inputs(["Choose correct month from range 1-12"],"")
                    while not month_to_input[0].isdigit():
                        month_to_input = terminal_view.get_inputs(["Your input is not digit. Choose correct month from range 1-12"],"")
                break
            month_to = month_to_input[0]

            year_to_input = terminal_view.get_inputs(["Year to"],"")
            while not year_to_input[0].isdigit():
                year_to_input = terminal_view.get_inputs(["Your input is not digit. Choose correct year"],"")
            while year_to_input[0].isdigit():
                while not int(year_to_input[0]) > 0 or not int(year_to_input[0]) > int(year_from):
                    year_to_input = terminal_view.get_inputs(["You can't choose year before 'Year from' value. Put correct year"],"")
                    while not year_to_input[0].isdigit():
                        year_to_input = terminal_view.get_inputs(["Your input is not digit. Choose correct year"],"")
                break
            year_to = year_to_input[0]

            items_sold_by_date = sales.get_items_sold_between(table, month_from, day_from, year_from, month_to, day_to, year_to)
            terminal_view.print_table(items_sold_by_date,title_list)
        elif choice != "0":
            terminal_view.print_error_message("There is no such choice.")


from ModFcfif.Fcfif import MotorDevice
from ModFcfif.Fcfif import ActionMotor
from ModFcfif.Fcfif import DeviceUnion

from ModFcfif.Fcfif import MotorPosUnit

from pyfcs.core.api import (
        BaseDeviceSetup, ParamProperty,
        ParamProperty,  parser,
        setup_method, payload_maker, payload_parser,
        register_device, create_mal_if
    )

__all__ = ['MotorSetup', 'MotorCommand', 'MotorAsyncCommand']

# quick create a MalIf class
MotorMalIf = create_mal_if(
        MotorDevice, DeviceUnion.getMotor, DeviceUnion.setMotor,
        action = ( 'getAction', 'setAction'),
        pos = ( 'getPos', 'setPos'),
        enc = ( 'getEnc', 'setEnc'),
        unit = ( 'getUnit', 'setUnit'),
        name = ( 'getName', 'setName'),
        speed = ( 'getSpeed', 'setSpeed'),

    )

# This device class is registered at the end of this file
class MotorSetup(BaseDeviceSetup):
    devtype = "motor"
    MalIf = MotorMalIf

    # ~~~~~~~~~~~~~~~  Parameters ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    action = ParamProperty( parser.EnumNameParser( ActionMotor),
                    description = "Motor action.",
                    required = True
                    )
    pos = ParamProperty( parser.FloatParser(),
                    description = "Motor position in user units.",
                    )
    enc = ParamProperty( parser.IntParser(),
                    description = "Motor position in encoders.",
                    )
    unit = ParamProperty( parser.EnumNameParser(MotorPosUnit),
                    description = "Motor position unit.",
                    )
    name = ParamProperty( parser.StringParser(),
                    description = "Motor named position.",
                    )
    speed = ParamProperty( parser.FloatParser(),
                    description = "Motor speed.",
                    )

    # ~~~~~~~~~~~~~~~ Setup/Payload Methods  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    @setup_method
    @payload_parser(action= 'MOVE_ABS', unit= 'UU')
    def move_abs_pos(self, pos):
        """ move_abs_pos

        Args:
            pos (float) : Motor position in user units.
        """
        self.pos = pos

        self.action = "MOVE_ABS"
        self.unit = "UU"

    @payload_maker(action= 'MOVE_ABS', unit= 'UU')
    def dump_move_abs_pos(self):
        """ dump payload when action= 'MOVE_ABS', unit= 'UU'
        """
        return {
            "action" : "MOVE_ABS",
            "unit" : "UU",

            "pos" : self.pos,
        }

    @setup_method
    @payload_parser(action= 'MOVE_ABS', unit= 'ENC')
    def move_abs_enc(self, enc):
        """ move_abs_enc

        Args:
            enc (int) : Motor position in encoders.
        """
        self.enc = enc

        self.action = "MOVE_ABS"
        self.unit = "ENC"

    @payload_maker(action= 'MOVE_ABS', unit= 'ENC')
    def dump_move_abs_enc(self):
        """ dump payload when action= 'MOVE_ABS', unit= 'ENC'
        """
        return {
            "action" : "MOVE_ABS",
            "unit" : "ENC",

            "enc" : self.enc,
        }

    @setup_method
    @payload_parser(action= 'MOVE_REL', unit= 'UU')
    def move_rel_pos(self, pos):
        """ move_rel_pos

        Args:
            pos (float) : Motor position in user units.
        """
        self.pos = pos

        self.action = "MOVE_REL"
        self.unit = "UU"

    @payload_maker(action= 'MOVE_REL', unit= 'UU')
    def dump_move_rel_pos(self):
        """ dump payload when action= 'MOVE_REL', unit= 'UU'
        """
        return {
            "action" : "MOVE_REL",
            "unit" : "UU",

            "pos" : self.pos,
        }

    @setup_method
    @payload_parser(action= 'MOVE_REL', unit= 'ENC')
    def move_rel_enc(self, enc):
        """ move_rel_enc

        Args:
            enc (int) : Motor position in encoders.
        """
        self.enc = enc

        self.action = "MOVE_REL"
        self.unit = "ENC"

    @payload_maker(action= 'MOVE_REL', unit= 'ENC')
    def dump_move_rel_enc(self):
        """ dump payload when action= 'MOVE_REL', unit= 'ENC'
        """
        return {
            "action" : "MOVE_REL",
            "unit" : "ENC",

            "enc" : self.enc,
        }

    @payload_parser(action= 'MOVE_ABS')
    def _move_abs(self, unit , __0__, *args):
        raise ValueError("un-complete payload")

    @payload_parser(action= 'MOVE_REL')
    def _move_rel(self, unit , __0__, *args):
        raise ValueError("un-complete payload")

    @setup_method
    @payload_parser(action= 'MOVE_BY_SPEED')
    def move_by_speed(self, speed):
        """ move_by_speed

        Args:
            speed (float) : Motor speed.
        """
        self.speed = speed

        self.action = "MOVE_BY_SPEED"

    @payload_maker(action= 'MOVE_BY_SPEED')
    def dump_move_by_speed(self):
        """ dump payload when action= 'MOVE_BY_SPEED'
        """
        return {
            "action" : "MOVE_BY_SPEED",

            "speed" : self.speed,
        }

    @setup_method
    @payload_parser(action= 'MOVE_BY_NAME')
    def move_name_pos(self, name):
        """ move_name_pos

        Args:
            name (str) : Motor named position.
        """
        self.name = name

        self.action = "MOVE_BY_NAME"

    @payload_maker(action= 'MOVE_BY_NAME')
    def dump_move_name_pos(self):
        """ dump payload when action= 'MOVE_BY_NAME'
        """
        return {
            "action" : "MOVE_BY_NAME",

            "name" : self.name,
        }

    def _set_pos(self, pos_or_enc, unit):
        self.unit = unit
        if unit == "UU":
            self.pos = pos_or_enc
        else:
            self.enc = pos_or_enc

    @setup_method
    def move_abs(self, pos_or_enc: float, unit: str ="UU"):
        """ move in absolute a motor

        Args:
            pos_or_enc (float): position in user unit or encoder according to unit
            unit (str,optional): "UU" (default) or "ENC"
        """
        self.action = "MOVE_ABS"
        self._set_pos( pos_or_enc, unit)

    @setup_method
    def move_rel(self, pos_or_enc:float , unit: str ="UU"):
        """ move in relatif a motor

        Args:
            pos_or_enc (float): position in user unit or encoder according to unit
            unit (str,optional): "UU" (default) or "ENC"
        """
        self.action = "MOVE_REL"
        self._set_pos( pos_or_enc, unit)

    @setup_method
    def move(self, pos_or_enc:float , type:str = "abs", unit: str ="uu"):
        """ move to a target position

        Args:
            pos_or_enc (float): target position in user unit or encoder according to unit
            type (str, optional): Type of movement - absolute ("abs", default) or relative ("rel") case unsensitive
            unit (str, optional): User units ("uu") or encoders ("enc") case unsensitive

        """
        type = type.lower()
        unit = unit.lower()
        if type == "rel":
            self.action = "MOVE_REL"
        elif type == "abs":
            self.action = "MOVE_ABS"
        else:
            raise ValueError(f"provided movement type is unknown, expecting 'rel','REL', 'abs' or 'ABS' got {type!r}" )
        if unit == "uu":
            self.unit = "UU"
            self.pos = pos_or_enc
        elif unit == "enc":
            self.unit = "ENC"
            self.enc = pos_or_enc
        else:
            raise ValueError(f"provided unit is unknown, expecting 'uu', 'UU', 'enc' or 'ENC' got {unit!r}" )

# register the device. This will create the Command and AsyncCommand classes
motor_classes = register_device( MotorSetup )
MotorCommand = motor_classes.Command
MotorAsyncCommand = motor_classes.AsyncCommand


##################################################
### import                                     ###
##################################################
# custom lib
import src.execute as execute
import src.log as log
import src.utils as utils

# define setting
description = 'ADD YOUR DESCRIPTION'
corpus_config_name = 'REPLACE_WITH_YOUR_DATASET_NAME'
pipeline_config_list = [['RFR', '0']]
lang_config_name = 'REPLACE_WITH_YOUR_LANGUAGE_CONFIG_NAME'

if __name__ == '__main__':
    logger = log.init_logger(__file__, __name__, "DEBUG")
    execute.basic(corpus_config_name, pipeline_config_list, lang_config_name)


from datetime import datetime, timedelta
import requests
from bs4 import BeautifulSoup
import re
import json

def parse_product(link):
    products = list()
    product = dict()
    resp = requests.get(link, verify=False).text
    soup = BeautifulSoup(resp, "html.parser")
    # Firstly Grab Vendor
    scripts = soup.findAll("script")
    for script in scripts:
        try:
            if not "inventory_quantity" in script.text:
                continue

            # qty = re.search('(?<=inventory_quantity":)(.*?)(?=\,)', script.text).group(0)
            # identity = re.search('(?<=id":)(.*?)(?=\,)', script.text).group(0)
            vendor = re.search('(?<=vendor":)(.*?)(?=\,)'.replace("\v", "v"), script.text).group(0)
            # name = re.search('(?<=name":)(.*?)(?=\,)'.replace("\n", "n"), script.text).group(0)

            product['vendor'] = str(re.sub('[^A-Za-z0-9]+', '', vendor)).lower()

            # product = {
            #     "name": name.replace('"', ''),
            #     "identity": identity,
            #     "quantity": qty,
            #     "vendor": str(re.sub('[^A-Za-z0-9]+', '', vendor)).lower(),
            # }
            break
        except AttributeError:
            product = hail_mary(soup)

    # Kieran's script
    vendor = product.get('vendor')
    try:
        varients = get_variants(resp)
        ids = list()
        for varient in varients:
            if varient['id'] in ids:
                continue
            product = {
                "name": varient['name'],
                "identity": varient['id'],
                "quantity": varient['inventory_quantity'],
                "vendor": vendor,
            }
            products.append(product)
            ids.append(varient['id'])
        if products:
            return products
    except:
        pass
    # Secondly Find Products from Forms
    forms = soup.findAll("form")
    for form in forms:
        if form.get("data-product"):
            try:
                data = json.loads(form.get("data-product"))
            except Exception as e:
                continue
            variants = data['variants']
            for variant in variants:
                product = {
                    "name": variant['name'],
                    "identity": str(variant['id']),
                    "quantity": variant['inventory_quantity'],
                    "vendor": data['vendor'],
                }
                products.append(product)

    # Thirdly Find Products from Divs
    divs = soup.findAll("div", {"class": "product-json"})
    for div in divs:
        data = json.loads(div.text)
        variants = data['variants']
        for variant in variants:
            product = {
                "name": variant['name'],
                "identity": str(variant['id']),
                "quantity": variant['inventory_quantity'],
                "vendor": data['vendor'],
            }
            products.append(product)

    # Forthly Find Products from Spans
    spans = soup.findAll("span", {"class": "product-json"})
    for span in spans:
        data = json.loads(span.text)
        variants = data['variants']
        for variant in variants:
            product = {
                "name": variant['name'],
                "identity": str(variant['id']),
                "quantity": variant['inventory_quantity'],
                "vendor": data['vendor'],
            }
            products.append(product)

    # Final option - In the case that Kieran's script not working.
    if not products:
        for script in scripts:
            try:
                if not "inventory_quantity" in script.text:
                    continue

                qty = re.search('(?<=inventory_quantity":)(.*?)(?=\,)', script.text).group(0)
                identity = re.search('(?<=id":)(.*?)(?=\,)', script.text).group(0)
                vendor = re.search('(?<=vendor":)(.*?)(?=\,)'.replace("\v", "v"), script.text).group(0)
                name = re.search('(?<=name":)(.*?)(?=\,)'.replace("\n", "n"), script.text).group(0)

                product = {
                    "name": name.replace('"', ''),
                    "identity": identity,
                    "quantity": qty,
                    "vendor": str(re.sub('[^A-Za-z0-9]+', '', vendor)).lower(),
                }
                products.append(product)
                break
            except AttributeError:
                product = hail_mary(soup)
                if not product:
                    products.append[product]
    return products

def depth(starts, finishes):
    depth = 1
    startind = 0
    finind = 0
    tups = []
    finishes = [x for x in finishes if x > starts[0]]
    curstart = starts[startind]
    while True:
        if startind == (len(starts) - 1):
            tups.append((starts[0], finishes[0]))
            break
        if starts[startind + 1] < finishes[finind]:
            depth += 1
            startind += 1
        else:
            depth -= 1
            finind += 1
            if depth == 0:
                tups.append((curstart, finishes[finind - 1]))
                starts = starts[startind + 1:]
                finishes = finishes[finind:]
                startind = 0
                finind = 0
                depth = 1
                curstart = starts[startind]
    return tups

def get_variants(resp):
    body = resp
    s = [x.start() for x in re.finditer('{', body)]
    f = [x.start() for x in re.finditer('}', body)]
    pairs = depth(s,f)
    idquants = []
    for x, y in pairs:
        try:
            if x+1 == y:
                continue
            bodysec = body[x:y+1]
            if "inventory_quantity" not in bodysec:
                continue
            testjson = json.loads(bodysec)
            if 'variants' in testjson.keys():
                for variant in testjson['variants']:
                    idquants.append(variant)
            elif 'inventory_quantity' in testjson.keys():
                idquants.append(testjson)
            elif 'product' in testjson.keys():
                product = testjson['product']
                if 'inventory_quantity' in product.keys():
                    idquants.append(product)
                if 'variants' in product.keys():
                    for variant in product['variants']:
                        if 'inventory_quantity' in variant.keys():
                            idquants.append(variant)
            else:
                print(testjson.keys())
                print()
        except:
            return idquants
    return idquants

def hail_mary(soup):
    try:
        s = str(soup)
        qty = re.search('(?<=inventory_quantity":)(.*?)(?=\,)', s).group(0)
        identity = re.search('(?<=id":)(.*?)(?=\,)', s).group(0)
        vendor = re.search('(?<=vendor":)(.*?)(?=\,)'.replace("\v", "v"), s).group(0)
        name = re.search('(?<=name":)(.*?)(?=\,)'.replace("\n", "n"), s).group(0)

        product = {
            "name": name.replace('"', ''),
            "id": identity,
            "vendor": str(re.sub('[^A-Za-z0-9]+', '', vendor)).lower(),
        }
    except AttributeError:
        return dict()
    return product


from vulture import Vulture

from prospector.encoding import CouldNotHandleEncoding, read_py_file
from prospector.message import Location, Message, make_tool_error_message
from prospector.tools.base import ToolBase

class ProspectorVulture(Vulture):
    def __init__(self, found_files):
        Vulture.__init__(self, verbose=False)
        self._files = found_files
        self._internal_messages = []
        self.file = None
        self.filename = None

    def scavenge(self, _=None, __=None):
        # The argument is a list of paths, but we don't care
        # about that as we use the found_files object. The
        # argument is here to explicitly acknowledge that we
        # are overriding the Vulture.scavenge method.
        for module in self._files.python_modules:
            try:
                module_string = read_py_file(module)
            except CouldNotHandleEncoding as err:
                self._internal_messages.append(
                    make_tool_error_message(
                        module,
                        "vulture",
                        "V000",
                        message=f"Could not handle the encoding of this file: {err.encoding}",
                    )
                )
                continue
            self.file = module
            self.filename = module
            try:
                self.scan(module_string, filename=module)
            except TypeError:
                self.scan(module_string)

    def get_messages(self):
        all_items = (
            ("unused-function", "Unused function %s", self.unused_funcs),
            ("unused-property", "Unused property %s", self.unused_props),
            ("unused-variable", "Unused variable %s", self.unused_vars),
            ("unused-attribute", "Unused attribute %s", self.unused_attrs),
        )

        vulture_messages = []
        for code, template, items in all_items:
            for item in items:
                try:
                    filename = item.file
                except AttributeError:
                    filename = item.filename
                if hasattr(item, "lineno"):
                    lineno = item.lineno  # for older versions of vulture
                else:
                    lineno = item.first_lineno
                loc = Location(filename, None, None, lineno, -1)
                message_text = template % item
                message = Message("vulture", code, loc, message_text)
                vulture_messages.append(message)

        return self._internal_messages + vulture_messages

class VultureTool(ToolBase):
    def __init__(self):
        ToolBase.__init__(self)
        self._vulture = None
        self.ignore_codes = ()

    def configure(self, prospector_config, found_files):
        self.ignore_codes = prospector_config.get_disabled_messages("vulture")

    def run(self, found_files):
        vulture = ProspectorVulture(found_files)
        vulture.scavenge()
        return [message for message in vulture.get_messages() if message.code not in self.ignore_codes]


# -*- coding: UTF-8 -*-
"""
apollo multitask for tensorflow
resNet(base network)+refineDet+SCNN for lane seg and detect.
@author: xie wei

"""
from model.VGG import VGG
from model.layers_group import *
from model.l2_normalization import l2_normalization

class RefineDet_Model(object):
    def __init__(self,anchors,anchor_ratios,anchor_steps,
                 img_size, det_num_class=2,num_anchors=9,
                training=True,keep_prob=0.5,w_summary=True,
                 name='RefineDet',reuse=False):
        self.img_size = img_size
        self.training = training
        self.name = name
        self.w_summary = w_summary
        self.keep_prob = keep_prob
        self.det_num_class = det_num_class
        self.num_anchors = num_anchors
        self.reuse = reuse
        self.use_bn = False
        self.anchors = anchors
        self.anchor_ratios=anchor_ratios
        self.anchor_steps = anchor_steps
        self.prior_scaling = [0.1, 0.1, 0.2, 0.2]
        self.arm_source_layers = ['conv4_3_norm', 'conv5_3_norm', 'fc7', 'conv6_2']
        self.odm_source_layers = ['P3', 'P4', 'P5', 'P6']
        self.normalizations = [10, 8, -1, -1]

    def ResBody(self,inputs,block_name, out2a, out2b, out2c, stride, use_branch1, dilation=1,name=None):
        # with tf.variable_scope(name):
            conv_prefix = 'res{}_'.format(block_name)
            if use_branch1:
                branch_name = 'branch1'
                branch1 = conv_bn(inputs, out2c, 1, stride, 'SAME', self.training, self.w_summary,
                                  '{}{}'.format(conv_prefix, branch_name))
            else:
                branch1 = inputs
            branch_name = 'branch2a'
            branch2a = conv_bn_relu(inputs, out2a, 1, stride, 'SAME', self.training, self.w_summary,
                                    '{}{}'.format(conv_prefix, '{}{}'.format(conv_prefix, branch_name)))
            branch_name = 'branch2b'
            if dilation == 1:
                branch2b = conv_bn_relu(branch2a, out2b, 3, 1, 'SAME', self.training, self.w_summary,
                                    '{}{}'.format(conv_prefix, branch_name))
            else:
                branch2b = astrous_conv_bn_relu(branch2a, out2b, 3, rate=dilation, pad='SAME', w_summary=False,
                                     is_training=self.training,bias=False, name='astrous_conv_bn')
            branch_name = 'branch2c'
            branch2c = conv_bn(branch2b, out2c, 1, 1, 'SAME', self.training, self.w_summary,
                              '{}{}'.format(conv_prefix, branch_name))
            res_name = 'res{}'.format(block_name)
            net = add_relu(branch1, branch2c, name=res_name)
            return net

    def AddExtraLayers(self,name):
        with tf.variable_scope(name):
            self.arm_source_layers.reverse()
            if(self.use_bn):
                self.end_logits['conv6_1'] = conv_bn_relu(self.end_logits['fc7'], 256, 1, 1, 'SAME', self.training, self.w_summary, name='conv6_1')
                self.end_logits['conv6_2'] = conv_bn_relu(self.end_logits['conv6_1'], 512, 3, 2, 'SAME', self.training,self.w_summary, name='conv6_2')
            else:
                self.end_logits['conv6_1'] = conv_relu(self.end_logits['fc7'], 256, 1, 1, 'SAME', self.training, self.w_summary, name='conv6_1')
                self.end_logits['conv6_2'] = conv_relu(self.end_logits['conv6_1'], 512, 3, 2, 'SAME', self.training,self.w_summary, name='conv6_2')

            TL6_1 = conv_relu(self.end_logits['conv6_2'], 256, 3, 1, 'SAME',self.training, self.w_summary, name='TL6_1')
            TL6_2 = conv_relu(TL6_1, 256, 3, 1, 'SAME', self.training, self.w_summary, name='TL6_2')
            self.end_logits['P6'] = conv_relu(TL6_2, 256, 3, 1, 'SAME', self.training, self.w_summary, name='P6')
            P6_up = deconv2d(self.end_logits['P6'], 256, 2,2, 'SAME',self.training,False,bias=False, name='P6_up')

            TL5_1 = conv_relu(self.end_logits['fc7'], 256, 3, 1, 'SAME',self.training, self.w_summary, name='TL5_1')
            TL5_2 = conv(TL5_1, 256, 3, 1, 'SAME', self.training, self.w_summary, name='TL5_2')
            Elt5 = add_relu(P6_up,TL5_2,'Elt5')
            self.end_logits['P5'] = conv_relu(Elt5, 256, 3, 1, 'SAME',self.training, self.w_summary, name='P5')
            P5_up = deconv2d(self.end_logits['P5'], 256, 2, 2, 'SAME', self.training, False, bias=False, name='P5_up')

            self.end_logits['conv5_3_norm'] = l2_normalization(self.end_logits['conv5_3'],'conv5_3_norm',scaling=True,scale_initializer=tf.constant_initializer(8))
            TL4_1 = conv_relu(self.end_logits['conv5_3_norm'], 256, 3, 1, 'SAME',self.training, self.w_summary, name='TL4_1')
            TL4_2 = conv(TL4_1, 256, 3, 1, 'SAME', self.training, self.w_summary, name='TL4_2')
            Elt4 = add_relu(P5_up,TL4_2,'Elt4')
            self.end_logits['P4'] = conv_relu(Elt4, 256, 3, 1, 'SAME',self.training, self.w_summary, name='P4')
            P4_up = deconv2d(self.end_logits['P4'], 256, 2, 2, 'SAME', self.training, False, bias=False, name='P4_up')

            self.end_logits['conv4_3_norm'] = l2_normalization(self.end_logits['conv4_3'],'conv4_3_norm',scaling=True,scale_initializer=tf.constant_initializer(10))
            TL3_1 = conv_relu(self.end_logits['conv4_3_norm'], 256, 3, 1, 'SAME',self.training, self.w_summary, name='TL3_1')
            TL3_2 = conv(TL3_1, 256, 3, 1, 'SAME', self.training, self.w_summary, name='TL3_2')
            Elt3 = add_relu(P4_up,TL3_2,'Elt3')
            self.end_logits['P3'] = conv_relu(Elt3, 256, 3, 1, 'SAME',self.training, self.w_summary, name='P3')

    # def AddExtraLayers(self,name):
    #     with tf.variable_scope(name):
    #         if(self.use_bn):
    #             self.end_logits['conv6_1'] = conv_bn_relu(self.end_logits['fc7'], 256, 1, 1, 'SAME', self.training, self.w_summary, name='conv6_1')
    #             self.end_logits['conv6_2'] = conv_bn_relu(self.end_logits['conv6_1'], 512, 3, 2, 'SAME', self.training,self.w_summary, name='conv6_2')
    #         else:
    #             self.end_logits['conv6_1'] = conv_relu(self.end_logits['fc7'], 256, 1, 1, 'SAME', self.training, self.w_summary, name='conv6_1')
    #             self.end_logits['conv6_2'] = conv_relu(self.end_logits['conv6_1'], 512, 3, 2, 'SAME', self.training,self.w_summary, name='conv6_2')
    #
    #         self.arm_source_layers.reverse()
    #         self.normalizations.reverse()
    #
    #         num_p = 6
    #         for index, layer in enumerate(self.arm_source_layers):
    #             from_layer = layer
    #             net = self.end_logits[from_layer]
    #
    #             '''l2_norm'''
    #             if self.normalizations:
    #                 if self.normalizations[index] != -1:
    #                     norm_name = "{}_norm".format(layer)
    #
    #                     self.end_logits[norm_name] = l2_normalization(net,norm_name,scaling=True)
    #                     net = self.end_logits[norm_name]
    #                     self.arm_source_layers[index] = norm_name
    #
    #             out_layer = "TL{}_{}".format(num_p, 1)
    #             net = conv_relu(net, 256, 3, 1, 'SAME',self.training, self.w_summary, name=out_layer)
    #
    #             if num_p == 6:
    #                 out_layer = "TL{}_{}".format(num_p, 2)
    #                 net = conv_relu(net, 256, 3, 1, 'SAME', self.training, self.w_summary,name=out_layer)
    #                 out_layer = "P{}".format(num_p)
    #                 pnet = conv_relu(net, 256, 3, 1, 'SAME', self.training, self.w_summary,name=out_layer)
    #             else:
    #                 out_layer = "TL{}_{}".format(num_p, 2)
    #                 net = conv(net, 256, 3, 1, 'SAME', self.training, self.w_summary, name=out_layer)
    #                 out_layer = "P{}_up".format(num_p + 1)
    #                 upnet = deconv2d(pnet, 256, 2,2, 'SAME',self.training,False,bias=False, name=out_layer)
    #                 net = add_relu(net,upnet,'Elt'+str(num_p))
    #                 out_layer = "P{}".format(num_p)
    #                 pnet = conv_relu(net, 256, 3, 1, 'SAME', self.training, self.w_summary, name=out_layer)
    #             self.end_logits["P" + str(num_p)] = pnet
    #             num_p = num_p - 1

    def CreateRefineDetHead(self,
                            from_layers,
                            from_layers2,
                            sizes,
                            ratios,
                            steps,
                            num_classes,
                            kernel_size):
        logist = {}
        clssfications = []
        localisations = []
        for i,layer in enumerate(from_layers):
            # Number of anchors.
            num_anchors = len(ratios[i])
            # Location.
            num_loc_pred = num_anchors * 4
            loc_pred = conv(self.end_logits[layer],num_loc_pred,kernel_size,1,'SAME',self.training,name='conv_loc_arm_'+layer)

            # Class prediction.
            num_cls_pred = num_anchors * 2
            cls_pred = conv(self.end_logits[layer], num_cls_pred, kernel_size, 1, 'SAME', self.training, name='conv_cls_arm_'+layer)

            clssfications.append(cls_pred)
            localisations.append(loc_pred)
        clssfications2 = []
        localisations2 = []
        for i,layer in enumerate(from_layers2):
            # Number of anchors.
            num_anchors = len(ratios[i])
            # Location.
            num_loc_pred = num_anchors * 4
            loc_pred = conv(self.end_logits[layer],num_loc_pred,kernel_size,1,'SAME',self.training,name='conv_loc_odm_'+layer)

            # Class prediction.
            num_cls_pred = num_anchors * num_classes
            cls_pred = conv(self.end_logits[layer], num_cls_pred, kernel_size, 1, 'SAME', self.training, name='conv_cls_odm_'+layer)

            clssfications2.append(cls_pred)
            localisations2.append(loc_pred)

        logist['arm'] = [clssfications,localisations]
        logist['odm'] = [clssfications2,localisations2]

        return logist

    def refine_det(self,name='refineDet'):
        with tf.variable_scope(name):
            share_location = True
            flip = True
            clip = False
            self.AddExtraLayers('AddExtLayers')
            self.arm_source_layers.reverse()
            self.normalizations.reverse()
            loc_conf_layers = self.CreateRefineDetHead( self.arm_source_layers,
                                                        self.odm_source_layers,
                                                        self.anchors,
                                                        self.anchor_ratios,
                                                        self.anchor_steps,
                                                        self.det_num_class,3)
            return loc_conf_layers

    def buildModel(self,inputs):
        self.end_logits = VGG(inputs,"VGG",self.training,self.w_summary,self.keep_prob,self.reuse)
        det_logits = self.refine_det('refineDet')

        return det_logits


import csv

rows = []
with open('example_write_csv.csv', 'r') as file:
    reader = csv.reader(file)
    header = next(reader)
    print(header)
    for row in reader:
        print(row)
        rows.append(row)

# transpose of list of lists
print('Transpose:')
columns = [list(tuple_column) for tuple_column in zip(*rows)]
for name,col in zip(header,columns):
    print(name, col)