import pygame
import math
from queue import PriorityQueue

WIDTH = 800
WIN = pygame.display.set_mode((WIDTH, WIDTH))
pygame.display.set_caption("A* Path Finding Algorithm")

RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 255, 0)
YELLOW = (255, 255, 0)
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
PURPLE = (128, 0, 128)
ORANGE = (255, 165, 0)
GREY = (128, 128, 128)
TURQOISE = (64, 224, 208)

class Node:
	def __init__(self, row, col, width, total_rows):
		self.row = row
		self.col = col
		self.x = row * width
		self.y = col * width
		self.color = WHITE
		self.neighbors = []
		self.width = width
		self.total_rows = total_rows

	def get_position(self):
		return self.row, self.col

	def is_closed(self):
		return self.color == RED

	def is_open(self):
		return self.color == GREEN

	def is_barrier(self):
		return self.color == BLACK

	def is_start(self):
		return self.color == ORANGE

	def is_end(self):
		return self.color == PURPLE

	def reset(self):
		self.color = WHITE

	def make_start(self):
		self.color = ORANGE

	def make_closed(self):
		self.color = RED

	def make_open(self):
		self.color = GREEN

	def make_barrier(self):
		self.color = BLACK

	def make_end(self):
		self.color = TURQOISE

	def make_path(self):
		self.color = PURPLE

	def draw(self, win):
		pygame.draw.rect(win, self.color, (self.x, self.y, self.width, self.width))

	def update_neighbors(self, grid):
		self.neighbors = []
		if self.row < self.total_rows - 1 and not grid[self.row + 1][self.col].is_barrier(): # down
			self.neighbors.append(grid[self.row + 1][self.col])

		if self.row > 0 and not grid[self.row - 1][self.col].is_barrier(): # up
			self.neighbors.append(grid[self.row - 1][self.col])

		if self.col < self.total_rows - 1 and not grid[self.row][self.col + 1].is_barrier(): # right
			self.neighbors.append(grid[self.row][self.col + 1])

		if self.row > 0 and not grid[self.row][self.col - 1].is_barrier(): # left
			self.neighbors.append(grid[self.row ][self.col - 1])

	def __lt__(self, other):
		return False

def h(p1, p2):
	x1, y1 = p1
	x2, y2 = p2
	return abs(x1 - x2) + abs(y1 - y2)

def reconstruct_path(came_from, current, draw):
	# traversing from end node to the start
	while current in came_from:
		current = came_from[current]
		current.make_path()
		draw() # will call current.draw()

def algorithm(draw, grid, start, end):
	count = 0
	open_set = PriorityQueue()
	open_set.put((0, count, start))	# Begin with start node in open set, format is (f_score, count, node) where priority queue uses f_score to determine minimum node
	came_from = {}	# Keeps track of what nodes came from where
	g_score = {node: float("inf") for row in grid for node in row} # keeps track of current shortest distance from start to end node
	g_score[start] = 0
	f_score = {node: float("inf") for row in grid for node in row} # keeps track of predicted distance from start to end node
	f_score[start] = h(start.get_position(), end.get_position())	# using heuristic distance

	open_set_hash = {start}	# helps us see if something is in the open_set

	while not open_set.empty():
		for event in pygame.event.get():
			if event.type == pygame.QUIT:
				pygame.quit()

		current = open_set.get()[2] # [2] gets the node
		open_set_hash.remove(current)

		if current == end:
			reconstruct_path(came_from, end, draw)
			end.make_end()
			return True # Found end node

		for neighbor in current.neighbors: # Go through every neighbor
			temp_g_score = g_score[current] + 1

			if temp_g_score < g_score[neighbor]: # if calculated g_score is less than the g_score they had when they were previously found
				# update neighbor
				came_from[neighbor] = current
				g_score[neighbor] = temp_g_score
				f_score[neighbor] = temp_g_score + h(neighbor.get_position(), end.get_position()) # formula for f_score is f_score = g_score + h_score
				if neighbor not in open_set_hash: # if neighbor was not previously found
					count += 1
					open_set.put((f_score[neighbor], count, neighbor))
					open_set_hash.add(neighbor)
					neighbor.make_open()

		draw()

		if current != start:
			current.make_closed()

	return False

def make_grid(rows, width):
	grid = []
	gap = width // rows
	for i in range(rows):
		grid.append([])
		for j in range(rows):
			node = Node(i, j, gap, rows)
			grid[i].append(node)

	return grid

def draw_grid(win, rows, width):
	gap = width // rows
	for i in range(rows):
		pygame.draw.line(win, GREY, (0, i * gap), (width, i * gap)) # Drawing horizontal lines
		for j in range(rows):
			pygame.draw.line(win, GREY, (j * gap, 0), (j * gap, width)) # Drawing vertical lines

def draw(win, grid, rows, width):
	win.fill(WHITE)

	for row in grid:
		for node in row:
			node.draw(win)

	draw_grid(win, rows, width)
	pygame.display.update()	# need to tell pygame to show what we've just drawn

def get_clicked_position(position, rows, width):
	gap = width // rows
	y, x = position

	# Node positions are normalized in the grid so must
	# divide to get proper indices within grid
	row = y // gap
	col = x // gap

	return row, col

def main(win, width):
	ROWS = 50 # Can be changed for a bigger grid
	grid = make_grid(ROWS, width)

	start = None
	end = None

	run = True
	while run:
		draw(win, grid, ROWS, width)
		for event in pygame.event.get():
			if event.type == pygame.QUIT:
				run = False

			if pygame.mouse.get_pressed()[0]: # If left mouse button pressed
				position = pygame.mouse.get_pos()
				row, col = get_clicked_position(position, ROWS, width)
				node = grid[row][col]
				if not start and node != end: # Ensures end node is not erased
					start = node
					start.make_start()

				elif not end and node != start: # Ensures end node is not erased
					end = node
					end.make_end()

				elif node != end and node != start:
					node.make_barrier()

			elif pygame.mouse.get_pressed()[2]: # If right mouse button pressed
				position = pygame.mouse.get_pos()
				row, col = get_clicked_position(position, ROWS, width)
				node = grid[row][col]
				node.reset()
				if node == start:
					start = None
				elif node == end:
					end = None

			if event.type == pygame.KEYDOWN:
				if event.key == pygame.K_SPACE and start and end: # If space is pressed
					for row in grid:
						for node in row:
							node.update_neighbors(grid)

					algorithm(lambda: draw(win, grid, ROWS, width), grid, start, end) # initializes the pathfinder
					# passing in lambda expression so we can just call draw() within algorithm
					# since the values of win, grid, ROWS, and width are lost due to how scope works

				if event.key == pygame.K_c:
					# clear entire grid and restart
					start = None
					end = None
					grid = make_grid(ROWS, width)

	pygame.quit()

main(WIN, WIDTH)


# -*- coding: utf-8 -*-
"""
Created on Wed Jun 29 13:50:25 2022S

@author: chggo
"""

# Get .h5 files from all the zip files given in the "path"

import os
from zipfile import ZipFile
from modules.logger import logger
from .H5Reader import H5Reader

class dump_helper_with_labels():
    def __init__(self,path):

       self.path=path

    def getlabels(self):

        F=[]

        for item in os.listdir(self.path):
            if item=='DumpFP':
                dd=self.unZip(os.path.join(self.path,'DumpFP'),l=1)
                if dd is not None:
                    F.append(dd)

            elif item=='DumpTP':
                dd=self.unZip(os.path.join(self.path,'DumpTP'),l=0)
                if dd is not None:
                    F.append(dd)

            elif item=='DumpUnsure':
                dd=self.unZip(os.path.join(self.path,'DumpUnsure'),l=None)
                if dd is not None:
                    F.append(dd)
        return(F)

    def unZip(self,p,l=None):

        fold=[]
        j=0
        label=[]
        ZipName=[]
        dictn=None
        dup_loc=[]
        dup_recut=[]

        for item in os.listdir(p):                # loop through items in dir
            if item.endswith('.zip'):                # check for ".zip" extension
                file_name=os.path.join(p,item)
                zip_ref = ZipFile(file_name)         # create zipfile object
                listOfFiles = zip_ref.namelist()
                count=0
                opd=os.path.dirname
                logger.info('{} zipfile is opened'.format(j))
                for f in listOfFiles :

                    if f.endswith('.h5') and opd(f)=='data/lossOfCutDetected':

                         f2=zip_ref.open(f)
                         dup_loc.append(f2)
                         count=count+1
                    elif f.endswith('.h5') and opd(f)=='data/lossOfCutRecut':

                         f2=zip_ref.open(f)
                         dup_recut.append(f2)
                         count=count+1
                if count !=2 :                            #(more than 2 .h5 files in any folder)

                    logger.info('-------------------------------------------------------------------')
                    logger.info('Number of .h5 file in dump {} is {}'.format(j,count))

                emp=self.empty(dup_loc[-1],j)
                emp1=self.empty(dup_recut[-1],j)
                if emp==False and emp1 ==False:

                    # append only last two elements to fix more than 2 .h5 files error
                    fold.append(dup_loc[-1])
                    fold.append(dup_recut[-1])

                    label.append(l)
                    ZipName.append(item)

                j=j+1
                zip_ref.close()
        dictn={'fold':fold,'label':label,'ZipName':ZipName}

        return(dictn)

    def createFolder(self):

        foldTest=0
        F=self.getlabels()
        logger.info('total zip files read from FP:{}'.format(len(F[0]['fold'])/2))
        logger.info('total zip files read from TP : {}'.format(len(F[1]['fold'])/2))
        logger.info('total zip files read from UnSure:{}'.format(len(F[2]['fold'])/2))

        if len(F)==1:
            fold=(F[0]['fold'])
            labels=(F[0]['label'])
            ZipName=(F[0]['ZipName'])
        elif len(F)==2:
            fold=F[0]['fold']+F[1]['fold']
            labels=F[0]['label']+F[1]['label']
            ZipName=F[0]['ZipName']+F[1]['ZipName']
        elif len(F)==3:
            fold=F[0]['fold']+F[1]['fold']
            labels=F[0]['label']+F[1]['label']
            ZipName=F[0]['ZipName']+F[1]['ZipName']
            foldTest=F[2]['fold']
            zipTest=F[2]['ZipName']

        return(fold,labels,foldTest,ZipName,zipTest)

    def empty(self,fold1,dumpNum,setLimit=90):

        emp=False
        H5File=H5Reader(fold1)
        h5=H5File.readH5()

        ecat=h5['ecat']

        if ecat.shape[0]<setLimit:
            emp=True
            logger.info('discard dump {}'.format(dumpNum))

        return(emp)


# ---
# jupyter:
#   jupytext:
#     formats: ipynb,py:percent
#     text_representation:
#       extension: .py
#       format_name: percent
#       format_version: '1.3'
#       jupytext_version: 1.10.2
#   kernelspec:
#     display_name: Python 3
#     language: python
#     name: python3
# ---

# %% [markdown]
# ### What is DCT (discrete cosine transformation) ?
#
# - This notebook creates arbitrary consumption functions at both 1-dimensional and 2-dimensional grids and illustrate how DCT approximates the full-grid function with different level of accuracies.
# - This is used in [DCT-Copula-Illustration notebook](DCT-Copula-Illustration.ipynb) to plot consumption functions approximated by DCT versus original consumption function at full grids.
# - Written by Tao Wang
# - June 19, 2019

# %% code_folding=[0, 11]
# Setup
def in_ipynb():
    try:
        if str(type(get_ipython())) == "<class 'ipykernel.zmqshell.ZMQInteractiveShell'>":
            return True
        else:
            return False
    except NameError:
        return False

# Determine whether to make the figures inline (for spyder or jupyter)
# vs whatever is the automatic setting that will apply if run from the terminal
if in_ipynb():
    # # # matplotlib inline generates a syntax error when run from the shell
    # so do this instead
    get_ipython().run_line_magic('matplotlib', 'inline')
else:
    from matplotlib.pyplot import ion
    ion()
    get_ipython().run_line_magic('matplotlib', 'auto')

# %%
# Import tools
import scipy.fftpack as sf  # scipy discrete fourier transform
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import numpy.linalg as lag
from scipy import misc
from matplotlib import cm

# %% code_folding=[]
## DCT in 1 dimension

grids= np.linspace(0,100,100)   # this represents the grids on which consumption function is defined.i.e. m or k

c =grids + 50*np.cos(grids*2*np.pi/40)  # this is an arbitrary example of a function to be approximated
c_dct = sf.dct(c,norm='ortho') # set norm =ortho is important
ind=np.argsort(abs(c_dct))[::-1]   # get indices of dct coefficients(absolute value) in descending order

# %% code_folding=[0]
## DCT in 1 dimension for difference accuracy levels

fig = plt.figure(figsize=(5,5))
fig.suptitle('DCT compressed c function with different accuracy levels')
lvl_lst = np.array([0.5,0.9,0.99])
plt.plot(c,'r*',label='c at full grids')
c_dct = sf.dct(c,norm='ortho')  # set norm =ortho is important
ind=np.argsort(abs(c_dct))[::-1]
for idx in range(len(lvl_lst)):
    i = 1 # starts the loop that finds the needed indices so that an target level of approximation is achieved
    while lag.norm(c_dct[ind[0:i]].copy())/lag.norm(c_dct) < lvl_lst[idx]:
        i = i + 1
    needed = i
    print("For accuracy level of "+str(lvl_lst[idx])+", "+str(needed)+" basis functions used")
    c_dct_rdc=c.copy()
    c_dct_rdc[ind[needed+1:]] = 0
    c_approx = sf.idct(c_dct_rdc)
    plt.plot(c_approx,label=r'c approx at ${}$'.format(lvl_lst[idx]))
plt.legend(loc=0)

print("Looks like the figure is mislabeled - green is 0.5, orange is 0.9, blue is 0.99")

# %% code_folding=[0]
## Blockwise DCT. For illustration but not used in BayerLuetticke.
## But it illustrates how doing dct in more finely divided blocks give a better approximation
### "regions" might be a better term than "blocks"
### If you are worried that the dct functions may not be good globally but fine locally
### then allow independent approximations of different regions

size = c.shape
c_dct = np.zeros(size)
c_approx=np.zeros(size)

fig = plt.figure(figsize=(10,10))
fig.suptitle('DCT compressed c function with different number of basis funcs')
nbs_lst = np.array([20,50])
plt.plot(c,'r*',label='c at full grids')
for i in range(len(nbs_lst)):
    delta = np.int(size[0]/nbs_lst[i])
    for pos in np.r_[:size[0]:delta]:
        c_dct[pos:(pos+delta)] = sf.dct(c[pos:(pos+delta)],norm='ortho')
        c_approx[pos:(pos+delta)]=sf.idct(c_dct[pos:(pos+delta)])
    plt.plot(c_dct,label=r'Nb of blocks= ${}$'.format(nbs_lst[i]))
plt.legend(loc=0)

# %% code_folding=[0]
# DCT in 2 dimensions

def dct2d(x):
    x0 = sf.dct(x.copy(),axis=0,norm='ortho')
    x_dct = sf.dct(x0.copy(),axis=1,norm='ortho')
    return x_dct
def idct2d(x):
    x0 = sf.idct(x.copy(),axis=1,norm='ortho')
    x_idct= sf.idct(x0.copy(),axis=0,norm='ortho')
    return x_idct

# arbitrarily generate a consumption function at different grid points
grid0=20
grid1=20
grids0 = np.linspace(0,20,grid0)
grids1 = np.linspace(0,20,grid1)

c2d = np.zeros([grid0,grid1])

# create an arbitrary c functions at 2-dimensional grids
for i in range(grid0):
    for j in range(grid1):
        c2d[i,j]= grids0[i]*grids1[j] - 50*np.sin(grids0[i]*2*np.pi/40)+10*np.cos(grids1[j]*2*np.pi/40)

## do dct for 2-dimensional c at full grids
c2d_dct=dct2d(c2d)

## convert the 2d to 1d for easier manipulation
c2d_dct_flt = c2d_dct.flatten(order='F')
ind2d = np.argsort(abs(c2d_dct_flt.copy()))[::-1] # get indices of dct coefficients(abosolute value)
                                              #   in the decending order

# %% code_folding=[0]
# DCT in 2 dimensions for different levels of accuracy

fig = plt.figure(figsize=(15,10))
fig.suptitle('DCT compressed c function with different accuracy levels')
lvl_lst = np.array([0.999,0.99,0.9,0.8,0.5])
ax=fig.add_subplot(2,3,1)
ax.imshow(c2d)
ax.set_title(r'$1$')

for idx in range(len(lvl_lst)):
    i = 1
    while lag.norm(c2d_dct_flt[ind2d[:i]].copy())/lag.norm(c2d_dct_flt) < lvl_lst[idx]:
        i += 1
    needed = i
    print("For accuracy level of "+str(lvl_lst[idx])+", "+str(needed)+" basis functions are used")
    c2d_dct_rdc=c2d_dct.copy()
    idx_urv = np.unravel_index(np.sort(ind2d[needed+1:]),(grid0,grid1),order='F')
    c2d_dct_rdc[idx_urv] = 0
    c2d_approx = idct2d(c2d_dct_rdc)
    ax = fig.add_subplot(2,3,idx+2)
    ax.set_title(r'${}$'.format(lvl_lst[idx]))
    ax.imshow(c2d_approx)

# %% code_folding=[0]
## surface plot of c at full grids and dct approximates with different accuracy levels

fig = plt.figure(figsize=(15,10))
fig.suptitle('DCT compressed c function in different accuracy levels')
lvl_lst = np.array([0.999,0.99,0.9,0.8,0.5])
ax=fig.add_subplot(2,3,1,projection='3d')
ax.plot_surface(grids0,grids1,c2d,cmap=cm.coolwarm)
ax.set_title(r'$1$')

for idx in range(len(lvl_lst)):
    i = 1
    while lag.norm(c2d_dct_flt[ind2d[:i]].copy())/lag.norm(c2d_dct_flt) < lvl_lst[idx]:
        i += 1
    needed = i
    print("For accuracy level of "+str(lvl_lst[idx])+", "+str(needed)+" basis functions are used")
    c2d_dct_rdc=c2d_dct.copy()
    idx_urv = np.unravel_index(ind2d[needed+1:],(grid0,grid1))
    c2d_dct_rdc[idx_urv] = 0
    c2d_approx = idct2d(c2d_dct_rdc)
    ax = fig.add_subplot(2,3,idx+2,projection='3d')
    ax.set_title(r'${}$'.format(lvl_lst[idx]))
    ax.plot_surface(grids0,grids1,c2d_approx,cmap=cm.coolwarm)

# %% code_folding=[0]
# surface plot of absoulte value of differences of c at full grids and approximated

fig = plt.figure(figsize=(15,10))
fig.suptitle('Differences(abosolute value) of DCT compressed with c at full grids in different accuracy levels')
lvl_lst = np.array([0.999,0.99,0.9,0.8,0.5])
ax=fig.add_subplot(2,3,1,projection='3d')
c2d_diff = abs(c2d-c2d)
ax.plot_surface(grids0,grids1,c2d_diff,cmap=cm.coolwarm)
ax.set_title(r'$1$')
for idx in range(len(lvl_lst)):
    i = 1
    while lag.norm(c2d_dct_flt[ind2d[:i]].copy())/lag.norm(c2d_dct_flt) < lvl_lst[idx]:
        i += 1
    needed = i
    print("For accuracy level of "+str(lvl_lst[idx])+", "+str(needed)+" basis functions are used")
    c2d_dct_rdc=c2d_dct.copy()
    idx_urv = np.unravel_index(ind2d[needed+1:],(grid0,grid1))
    c2d_dct_rdc[idx_urv] = 0
    c2d_approx = idct2d(c2d_dct_rdc)
    c2d_approx_diff = abs(c2d_approx - c2d)
    ax = fig.add_subplot(2,3,idx+2,projection='3d')
    ax.set_title(r'${}$'.format(lvl_lst[idx]))
    ax.plot_surface(grids0,grids1,c2d_approx_diff,cmap= 'OrRd',linewidth=1)
    ax.view_init(20, 90)


# 트럭 n개 지나감 순서 변경 x
# 다리의 길이는 w 단위 길이 이며, 단위 시간에 하나의 단위길이만큼 이동 가능.
# 동시에 올라가있는 트럭은 최대 하중인 L보다 작을 것.
# 큐로 풀 수 있는데 배열? 을 두개 만들어야함.
# 1. 입력된 배열
# 2. 다리 길이만한 배열

# 도착하면 0으로 바꾸고 배열에 있는 숫자와 더해서 몇인지 판별 후 하중 아래면 넣는다.
# 그리고 다음 배열로 고고

from collections import deque

N, W, L = map(int, input().split())
# N : 다리를 건너는 트럭 수
# W : 다리 길이
# L : 최대 하중

trucks = deque(list(map(int, input().split())))
bridge = [0]*W

i = 0
time = 0
while trucks:
    bridge[i] = 0
    if (sum(bridge) + trucks[0]) <= L:
        bridge[i] = trucks.popleft()
    i = (i + 1) % W
    time += 1

print(time + W)


# utf-8
import numpy as np
from random import shuffle
import matplotlib.ticker as ticker
import matplotlib.pyplot as plt

def testAndTrain(iteration, trainingData, testingData, shuffleVal):
    global onevsTwo, twoVsThree, oneVsThree
    print("\n\n" + "Binary classifier" + "\n\n")
    # Declare variables to store the results.
    test1In1vs2TP = test1In1vs2FP = 0
    test1In3vs1TP = test1In3vs1FP = 0

    test2In1vs2TP = test2In1vs2FP = 0
    test2In2vs3TP = test2In2vs3FP = 0

    test3In2vs3TP = test3In2vs3FP = 0
    test3In3vs1TP = test3In3vs1FP = 0

    # create a binary perceptron to compare class 1 and class 2.
    onevsTwo = perceptTrain(iteration, trainingData, 1, 2, shuffleVal)
    # create a binary perceptron to compare class 2 and class 3.
    twoVsThree = perceptTrain(iteration, trainingData, 2, 3, shuffleVal)
    # create a binary perceptron to compare class 1 and class 3.
    oneVsThree = perceptTrain(iteration, trainingData, 1, 3, shuffleVal)

    # test each data and compute the TP or FP
    for features, Class in testingData:
        # If the record we are processing is either class 1 or class 2
        if Class == 1 or Class == 2:
            # test,if the activation is above 0 then the record is predicted in class 1
            if (np.dot(onevsTwo[0], features) + onevsTwo[1]) > 0:
                # if the actual class was 1 then we predicted correctly
                if Class == 1:
                    test1In1vs2TP += 1
                # else we predicted falsely
                else:
                    test1In1vs2FP += 1
                # else its the opposite class (class 2)
            else:
                # if it was the other class we predicted correctly
                if Class == 2:
                    test2In1vs2TP += 1
                # else we predicted falsely
                else:
                    test2In1vs2FP += 1

            # If the record we are processing is either class 2 or class 3
        if Class == 2 or Class == 3:
            # test the network if the activation is above 0 then the record is predicted in class 2
            if (np.dot(twoVsThree[0], features) + twoVsThree[1]) > 0:
                # if the actual class was 2 then we predicted correctly
                if Class == 2:
                    test2In2vs3TP += 1
                # else we predicted falsely
                else:
                    test2In2vs3FP += 1
                # else if the actual class was 3 then we predicted correctly
            else:
                if Class == 3:
                    test3In2vs3TP += 1
                # else we predicted falsely
                else:
                    test3In2vs3FP += 1

            # if the class we are testing is either 3 or 1
        if Class == 3 or Class == 1:
            # test the network if the activation is above 0 then the record is predicted in class 1
            if (np.dot(oneVsThree[0], features) + oneVsThree[1]) > 0:
                # if the class was actually 1 then we predicted correctly
                if Class == 1:
                    test1In3vs1TP += 1
                # else we predicted falsely
                else:
                    test1In3vs1FP += 1
            # else if the actual class was 3 then we predicted correctly
            else:
                if Class == 3:
                    test3In3vs1TP += 1
                # else we predicted falsely.
                else:
                    test3In3vs1FP += 1

    # print the accuracy for network 1 vs 2.
    print(printTestAccuracy(test1In1vs2TP, test1In1vs2FP, test2In1vs2FP, test2In1vs2TP, "1", "2"))
    # print the weights for network 1 vs 2
    print("\tWeights of 1 vs 2 = [%0.2f, %0.2f, %.2f, %.2f]    Bias = %.0f\n\n" % (
        onevsTwo[0][0], onevsTwo[0][1], onevsTwo[0][2], onevsTwo[0][3], onevsTwo[1]))

    # print the accuracy for network 2 vs 3.
    print(printTestAccuracy(test2In2vs3TP, test2In2vs3FP, test3In2vs3FP, test3In2vs3TP, "2", "3"))
    # print the weights for network 2 vs 3
    print("\tWeights of 2 vs 3 = [%0.2f, %0.2f, %.2f, %.2f]    Bias = %.0f\n\n" % (
        twoVsThree[0][0], twoVsThree[0][1], twoVsThree[0][2], twoVsThree[0][3], twoVsThree[1]))

    # print the accuracy for network 1 vs 3.
    print(printTestAccuracy(test3In3vs1TP, test3In3vs1FP, test1In3vs1FP, test1In3vs1TP, "3", "1"))
    # print the weights for network 1 vs 3
    print("\tWeights of 1 vs 3 = [%0.2f, %0.2f, %.2f, %.2f]    Bias = %.0f\n\n" % (
        oneVsThree[0][0], oneVsThree[0][1], oneVsThree[0][2], oneVsThree[0][3], oneVsThree[1]))

    # print and draw graph for accuracy on training data
    accuracy1 = onevsTwo[2]
    accuracy2 = twoVsThree[2]
    accuracy3 = oneVsThree[2]

    print("Accuracy during training class 1 vs 2")
    graph(accuracy1, iteration, "1 vs 2")
    print(accuracy1)
    print("Accuracy during training class 2 vs 3")
    graph(accuracy2, iteration, "2 vs 3")
    print(accuracy2)
    print("Accuracy during training class 3 vs 1")
    graph(accuracy3, iteration, "3 vs 1")
    print(accuracy3)

    return

def perceptTrain(maxIter, Data, ClassN, ClassN2, shuffleVal):
    # initialise weights to 0
    accuracy = []
    weights = np.array([0, 0, 0, 0])
    # initialise bias to 0
    bias = 0
    # run system for maxIter times
    for i in range(0, maxIter):
        mistakes = 0
        # shuffle the data
        if shuffleVal == 1:
            shuffle(Data)
        # for each data split on features and class
        for features, classN in Data:
            # if the data class is either of the two class we want to distinguish
            if classN == ClassN or classN == ClassN2:
                # set the tempclass to be 1 if it is the first class
                # else set it to -1.
                tempSetNum = 1 if classN == ClassN else -1
                # perform matrix multiplication on features and weights, add the bias (activation term)
                a = np.dot(weights, features) + bias
                if tempSetNum * a <= 0:
                    # update the weights and bias.
                    weights = np.add(weights, np.multiply(tempSetNum, features))
                    bias += tempSetNum
                    mistakes += 1
        # return the weights and bias
        r = round((len(traindata) - mistakes) / len(traindata), 2)
        accuracy.append(r)
    return weights, bias, accuracy

# read file x and output an array containing a numpy array of the features and the class of the data
def readFile(x):
    # open the file
    file = open(x, "r")
    # get all the lines
    lines = file.readlines()
    # close the file
    file.close()
    # create a new array
    data = []
    # for every metadata
    for val in lines:
        # split it on ","
        a = val.split(",")
        # get the class
        a[4] = a[4][6:7]
        c = []
        # add all features to an empty array
        for val2 in range(0, len(a) - 1):
            c.append(float(a[val2]))
        # convert the array to a numpy array
        c = np.array(c)
        temp = [c, int(a[4])]
        data.append(temp)
    return data

def printTestAccuracy(TP, FP, FN, TN, index1, index2):
    accuracy = (TP + TN) / (TP + FP + FN + TN)
    print("Classification " + index1 + " vs " + index2 + "\n" +
          "\ttest Accuracy\t\t" + str(accuracy))
    return

def graph(data, episode_count, title):
    time_intervals = np.arange(1, episode_count + 1, 1)
    ax = plt.axes()
    ax.plot(time_intervals, data, 'r', linewidth=0.5)
    loc = ticker.MultipleLocator(base=1.0)
    # this locator puts ticks at regular intervals
    ax.xaxis.set_major_locator(loc)
    plt.xlabel("Iteration")
    plt.ylabel("Accuracy")
    plt.title(title)
    plt.grid(True)
    plt.show()
    return

# runs all tests including binary training, binary testing
with np.errstate(over='ignore'):
    # ShuffleVal, if this is set to 1 will shuffle data .
    shuffleval = 1
    # iterations, how many times to repeatedly pass our data through test method.
    iterations = 20
    # get the training data and store it in an array.
    traindata = readFile("train.data")
    # get the training data and store it in an array.
    testdata = readFile("test.data")
    testAndTrain(iterations, traindata, testdata, shuffleval)


from time import sleep

import tweepy

from config import auth
from get_city_csv import get_city

api = tweepy.API(auth)

try:
    api.verify_credentials()
    print("Authentication OK")
    while True:
        tweet = get_city()
        print(tweet)
        api.update_status(tweet)
        sleep(3600)
except:
    print("Error during authentication")


import itertools
import sys
from collections import deque
from heapq import heappush, heappop
from math import sqrt

input = sys.stdin

def bfs():
    while q:
        x, y, cost = q.popleft()
        for dx, dy in (-1, 0), (1, 0), (0, -1), (0, 1):
            nx, ny = x + dx, y + dy
            if nx < 0 or nx >= n or ny < 0 or ny >= m or visited[nx][ny] or board[nx][ny] == 0: continue
            visited[nx][ny] = True
            q.append((nx, ny, cost + 1))
            dist[nx][ny] = dist[x][y] + 1

if __name__ == '__main__':
    n, m = map(int, input.readline().split())
    board = [[int(x) for x in input.readline().split()] for _ in range(n)]
    q = deque()
    visited = [[False] * m for _ in range(n)]
    dist = [[0] * m for _ in range(n)]
    for i in range(n):
        for j in range(m):
            if board[i][j] == 2:
                q.append((i, j, 0))
                visited[i][j] = True

    bfs()
    for i in range(n):
        for j in range(m):
            if board[i][j] == 1 and dist[i][j] == 0:
                print(-1, end=" ")
            elif board[i][j] == 0:
                print(0, end=" ")
            else:
                print(dist[i][j], end=" ")
        print("")


from typing import Awaitable
from aiogram import Router, Bot, types, F
from aiogram.filters import Command
from aiogram.fsm.context import FSMContext
from aiogram.utils.keyboard import ReplyKeyboardBuilder

from utils.texts import TranslationTexts as texts
from tgtypes.db_user import DbUser

router = Router()

def create_default_keyboard():
    kb = ReplyKeyboardBuilder()
    kb.button(text=texts.HELLO_ADD_BOT_BUTTON.value)
    result_kb = kb.as_markup()
    result_kb.resize_keyboard = True
    result_kb.input_field_placeholder = texts.HELLO_HINT.value
    return result_kb

@router.message(Command(commands=["start"]))
async def command_start_handler(
    message: types.Message,
    state: FSMContext,
    bot: Bot,
    user: DbUser
) -> None:
    if not user.db.pm_referer and message.text and message.text.startswith("/start"):
        user.db.pm_referer = message.text[7:]
    kb = create_default_keyboard()
    await message.answer(texts.HELLO.value, reply_markup=kb)
    return


from pathlib import Path

def RfileSearch(pathlist):

    if len(pathlist) == 0:
        return []
    else:
        if pathlist[0].is_file():
            return [pathlist[0]] + RfileSearch(pathlist[1:])
        else:
            return RfileSearch(list(pathlist[0].iterdir())) + RfileSearch(pathlist[1:])

def getSearchOption():

    interest = input("Enter option (N,E,<,> followed by name, extension or size): ").split()
    valid_input = ['N','E','<','>']

    if (interest[0] == 'T'):
        while(interest[0] == 'T' and len(interest) < 2):
            print("ERROR")
            interest = input("Enter again: ").split()
        nInterest = list(map(str, interest[1:]))
        interest = [interest[0], ' '.join(nInterest)]

    elif (interest[0] != 'A' or interest[0] != 'T'):
        while (len(interest) != 2 or interest[0] not in valid_input):
            print("ERROR")
            interest = input("").split()

    return interest

def getPaths():

    pathTd = input("Enter mode and path (R/D <path>): ").split()

    while ((len(pathTd) != 2) or (not Path(pathTd[1]).exists())):
        print("ERROR")
        pathTd = input("Enter again: ").split()

    (mode, path) = (pathTd[0],Path(pathTd[1]))

    if mode == "D":
        files = list(path.iterdir())
    else:
        files = RfileSearch(list(path.iterdir()))
        files.sort(key = lambda x: str(x).count("/"))

    final_files = []

    for i in files:
        if str(i).split('/')[-1][0] != '.':
            final_files.append(i)

    return final_files

def requiredFiles(interest, files):

    output = []
    if interest[0] == 'A':
        for i in files:
            output.append(i)

    elif interest[0] == 'N':
        interest[1] = str(interest[1])
        for i in files:
            if i.name[:len(interest[1])] == interest[1]:
                      output.append(i)

    elif interest[0] == 'E':
        interest[1] = str(interest[1])
        if ('.' in interest[1]):
            interest[1] = interest[1].replace('.','')
        for i in files:
            if i.suffix[1:] == interest[1]:
                output.append(i)

    elif interest[0] == 'T':
        interest[1] = str(interest[1])

        for i in files:
            try:
                infile = i.open('r')
                for lines in infile:
                    if interest[1] in lines:
                        output.append(i)
            except:
                continue

    elif interest[0] == '>':
        try:
            value = int(interest[1])
            for i in files:
                if i.stat().st_size > value:
                    output.append(i)
        except ValueError:
            raise ValueError

    elif interest[0] == '<':
        try:
            value = int(interest[1])
            for i in files:
                if i.stat().st_size < value:
                    output.append(i)
        except ValueError:
            raise ValueError

    return output

def getAction():

    action = input("Enter option: ")
    while ((action != 'F') and (action != 'D') and (action != 'T')):
        print ("ERROR")
        action = input("Enter again: ")

    return action

def main():

    files = getPaths()

    interest = getSearchOption()

    result = requiredFiles(interest, files)

    if len(result) != 0:
        for i in result:
            print(i)

        choice = getAction()

        if (choice == 'F'):
            for i in result:
                try:
                    infile = i.open('r')
                    print(infile.readline().strip())
                    infile.close()
                except:
                    print("NOT A TEXT")

        if (choice == 'D'):
            for i in result:
                infile = i.open('r')
                newP = Path(str(i) + '.dup')
                outfile = newP.open('w')
                for line in infile:
                    outfile.write(line)
                infile.close()
                outfile.close()

        if (choice == 'T'):
            for i in result:
                i.touch()

if __name__ == '__main__':
    main()


""" Definitions of blocks, and the genesis block. """

from datetime import datetime
from binascii import hexlify, unhexlify

import json
import logging

import src.utils as utils

from .config import *
from .merkle import merkle_tree
from .crypto import get_hasher

__all__ = ['Block']

class Block:
    """
    A block: a container for all the data associated with a block.

    To figure out whether the block is valid on top of a block chain, there are a few `verify`
    methods. Without calling these, you must assume the block was crafted maliciously.

    :ivar hash: The hash value of this block.
    :vartype hash: bytes
    :ivar id: The ID of this block. Genesis-Block has the ID '0'.
    :vartype id: int
    :ivar prev_block_hash: The hash of the previous block.
    :vartype prev_block_hash: bytes
    :ivar merkle_root_hash: The hash of the merkle tree root of the transactions in this block.
    :vartype merkle_root_hash: bytes
    :ivar time: The time when this block was created.
    :vartype time: datetime
    :ivar nonce: The nonce in this block that was required to achieve the proof of work.
    :vartype nonce: int
    :ivar height: The height (accumulated target) of this block.
    :vartype height: int
    :ivar received_time: The time when we received this block.
    :vartype received_time: datetime
    :ivar target: The target of this block.
    :vartype target: int
    :ivar transactions: The list of transactions in this block.
    :vartype transactions: List[Transaction]
    """

    # TODO: Check if  "id" is really needed. Should be the same as "height".

    def __init__(self, prev_block_hash, time, nonce, height, received_time, target, transactions,
                 merkle_root_hash=None, id=None):
        self.id = id
        self.prev_block_hash = prev_block_hash
        self.merkle_root_hash = merkle_root_hash
        self.time = time
        self.nonce = nonce
        self.height = height
        self.received_time = received_time
        self.target = target
        self.transactions = transactions
        self._hash = self._get_hash()

    @property
    def hash(self):
        return self._hash

    @hash.setter
    def hash(self, value):
        self._hash = value

    def to_json_compatible(self):
        """ Returns a JSON-serializable representation of this object. """
        val = {}
        val['id'] = self.id
        val['hash'] = hexlify(self._hash).decode()
        val['prev_block_hash'] = hexlify(self.prev_block_hash).decode()
        val['merkle_root_hash'] = hexlify(self.merkle_root_hash).decode()
        val['time'] = self.time.strftime("%Y-%m-%dT%H:%M:%S.%f UTC")
        val['nonce'] = self.nonce
        val['height'] = self.height
        val['target'] = self.target
        val['transactions'] = [t.to_json_compatible() for t in self.transactions]
        return val

    @classmethod
    def from_json_compatible(cls, val):
        """ Create a new block from its JSON-serializable representation. """
        from .transaction import Transaction
        return cls(unhexlify(val['prev_block_hash']),
                   datetime.strptime(val['time'], "%Y-%m-%dT%H:%M:%S.%f UTC"),
                   int(val['nonce']),
                   int(val['height']),
                   datetime.utcnow(),
                   int(val['target']),
                   [Transaction.from_json_compatible(t) for t in list(val['transactions'])],
                   unhexlify(val['merkle_root_hash']),
                   int(val['id']))

    @classmethod
    def create(cls, chain_difficulty: int, prev_block: 'Block', transactions: list, ts=None):
        """
        Create a new block for a certain blockchain, containing certain transactions.
        """
        tree = merkle_tree(transactions)
        difficulty = chain_difficulty
        id = prev_block.height + 1
        if ts is None:
            ts = datetime.utcnow()
        if ts <= prev_block.time:
            ts = prev_block.time + timedelta(microseconds=1)
        return Block(prev_block.hash, ts, 0, prev_block.height + 1,
                     None, difficulty, transactions, tree.get_hash(), id)

    def __str__(self):
        return json.dumps(self.to_json_compatible(), indent=4)

    def get_partial_hash(self):
        """
        Computes a hash over the contents of this block, except for the nonce. The proof of
        work can use this partial hash to efficiently try different nonces. Other uses should
        use `hash` to get the complete hash.
        """
        hasher = get_hasher()
        hasher.update(self.prev_block_hash)
        hasher.update(self.merkle_root_hash)
        hasher.update(self.time.strftime("%Y-%m-%dT%H:%M:%S.%f UTC").encode())
        hasher.update(utils.int_to_bytes(self.target))
        return hasher

    def finish_hash(self, hasher):
        """
        Finishes the hash in `hasher` with the nonce in this block. The proof of
        work can use this function to efficiently try different nonces. Other uses should
        use `hash` to get the complete hash in one step.
        """
        hasher.update(utils.int_to_bytes(self.nonce))
        return hasher.digest()

    def _get_hash(self):
        """ Compute the hash of the header data. This is not necessarily the received hash value for this block! """
        hasher = self.get_partial_hash()
        return self.finish_hash(hasher)

    def verify_merkle(self):
        """ Verify that the merkle root hash is correct for the transactions in this block. """
        return merkle_tree(self.transactions).get_hash() == self.merkle_root_hash

    def verify_proof_of_work(self):
        """ Verify the proof of work on a block. """
        return int.from_bytes(self._hash, 'big') < self.target

    def verify_difficulty(self):
        """ Verifies that the hash value is correct and fulfills its target promise. """
        if not self.verify_proof_of_work():
            logging.warning("block does not satisfy proof of work")
            return False
        return True

    def verify_prev_block(self, prev_block: 'Block', chain_target: int):
        """ Verifies that the previous block pointer points to the head of the given blockchain and target and height are correct. """
        if prev_block.hash != self.prev_block_hash:
            logging.warning("Previous block is not head of the block chain.")
            return False

        if self.target != chain_target:
            logging.warning("Block has wrong target.")
            return False
        if prev_block.height + 1 != self.height:
            logging.warning("Block has wrong height.")
            return False
        return True

    def verify_block_transactions(self, unspent_coins: dict, reward: int):
        """ Verifies that all transaction in this block are valid in the given blockchain. """
        mining_rewards = []
        all_inputs = []
        for t in self.transactions:
            all_inputs += t.inputs
            if t.inputs[0].is_coinbase:
                if len(mining_rewards) > 1:
                    logging.warning("block has more than one coinbase transaction")
                    return False
                mining_rewards.append(t)

            if not t.validate_tx(unspent_coins):
                return False

        fees = sum(t.get_transaction_fee(unspent_coins) for t in self.transactions)
        actual_reward_and_fees = sum(t.amount for t in mining_rewards[0].targets)

        if actual_reward_and_fees > reward + fees:
            warn = "{} is different than specified({})".format(actual_reward_and_fees, reward+fees)
            logging.error(warn)
            return False

        if not self._verify_input_consistency(all_inputs):
            return False

        return True

    def _verify_input_consistency(self, tx_inputs: 'List[TransactionInputs]'):
        """"Verify that all the transactions in the transaction list are not spending from a same input transaction and index"""
        tx_inp = [(i.transaction_hash, i.output_idx) for i in tx_inputs]
        return len(tx_inp) == len(set(tx_inp))

    def verify_time(self, head_time: datetime):
        """
        Verifies that blocks are not from far in the future, but a bit younger
        than the head of `chain`.
        """
        if self.time - timedelta(hours=2) > datetime.utcnow():
            logging.warning("discarding block because it is from the far future")
            return False
        if self.time <= head_time:
            logging.warning("discarding block because it is younger than its predecessor")
            return False
        return True

    def verify(self, prev_block: 'Block', chain_difficulty: int, unspent_coins: dict, chain_indices: dict, reward: int):
        """
        Verifies that this block contains only valid data and can be applied on top of the block
        chain `chain`.
        """
        assert self._hash not in chain_indices
        if self.height == 0:
            logging.warning("only the genesis block may have height=0")
            return False

        return self.verify_difficulty() and self.verify_merkle() and self.verify_prev_block(prev_block,
                                                                                chain_difficulty) \
               and self.verify_time(prev_block
                                    .time) and self.verify_block_transactions(unspent_coins, reward)


from __future__ import division
import ipywidgets as ipw
import ase
from ase.units import *

def get_start_widget(appbase, jupbase):

    def on_drop_changed(c):
        global factor
        lu, ru = drop.value.split(" <=> ")
        left.description = lu
        right.description = ru
        factor = eval("(%s) / (%s)"%(lu, ru))
        on_left_changed(None)

    def on_left_changed(c):
        right.value = left.value * factor

    def on_right_changed(c):
        left.value = right.value / factor

    left = ipw.FloatText(value=1.0)
    left.observe(on_left_changed, names="value")
    right = ipw.FloatText()
    right.observe(on_right_changed, names="value")

    options = ['Hartree <=> eV', 'Hartree <=> kcal/mol', 'Bohr <=> Angstrom']
    drop = ipw.Dropdown(options=options)
    drop.observe(on_drop_changed)

    on_drop_changed(None)

    return ipw.HBox([drop, left, right])

#EOF


import pygame
import sys

from map import Map
from settings import AMOUNT_OF_ROWS, AMOUNT_OF_COLUMNS, BACKGROUND_COLOR, SCREEN_WIDTH, SCREEN_HEIGHT, FPS

clock = pygame.time.Clock()
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))

game_map = Map(AMOUNT_OF_ROWS, AMOUNT_OF_COLUMNS)

game_map.draw(screen)

while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()

    screen.fill(BACKGROUND_COLOR)

    game_map.update()
    game_map.draw(screen)

    clock.tick(FPS)


"""
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Coset Enumeration using Todd-Coxeter Algorithm
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Reference:
    [1] "Handbook of Computational Group Theory", Holt, D., Eick, B., O'Brien, E.
    [2] "Computation with finitely presented groups", Charles C.Sims.
    [3] GAP doc at "https://www.gap-system.org/Manuals/doc/ref/chap47.html".
    [4] Ken Brown's code at "http://www.math.cornell.edu/~kbrown/toddcox/".

"""

class CosetTable:
    """
    Let G = < X | R > be a finitely presented group and H be a subgroup of
    G with |G:H| < inf. The coset table T of G/H is a 2D array with rows
    indexed by the right cosets of G/H and columns indexed by the generators
    of G and their inverses. The entry of T at row k and column x (x is a
    generator or the inverse of a generator) records the right action of
    coset k by x: T[k][x] = kx. If T[k][x] is not defined yet we set it to
    None. When the algorithm terminates all entries in the table are
    assigned a non-negative integer, all rows scan correctly under all words
    in R and the first row scans correctly under all generators of H.
    """

    def __init__(self, gens, rels, subgens=(), coxeter=True):
        """
        :param gens: a 1D list of integers that represents the generators,
            e.g. [0, 1, 2] for [a, b, c]

        :param rels: a 2D list of integers that represents the relators R,
            e.g. [[0, 0], [1, 1, 1], [0, 2]*3] for a^2 = b^3 = (ac)^3 = 1

        :param subgens: a 2D list of integers that represents the subgroup generators,
            e.g. [[0, 2]] for < ac >.

        :param coxeter: whether this is a Coxeter group. If false then the inverse of
            the generators are also included as generators, otherwise they are not.

        we use a list p to hold the equivalence classes of the cosets,
        p[k] = l means k and l really represent the same coset. It's always
        true that p[k] <= k, if p[k] = k then we call k "alive" otherwise we call
        k "dead". All cosets are created "alive", but as the algorithm runs
        some of them may be declared to "dead" and their rows are deleted from
        the table (we do not explicitly free the memory of these row but keep
        in mind that they do not belong to our table).

        A "dead" coset arise when an `coincidence` is found, and while handling
        this coincidence more coincidences may also be found, so we use a queue
        q to hold them.
        """
        self.coxeter = coxeter
        if coxeter:
            self.inv = lambda x: x
        else:
            self.inv = lambda x: x - 1 if x % 2 else x + 1
        self.A = gens
        self.R = rels  # relations R between the generators
        self.H = subgens  # generators of H
        self.p = [0]  # initially we only have the 0-th coset H
        self.q = []  # a queue holds all dead cosets to be processed.
        self.table = [[None] * len(self.A)]

    def __getitem__(self, item):
        return self.table.__getitem__(item)

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

    def is_alive(self, coset):
        """Check if a coset is alive.
        """
        return self.p[coset] == coset

    def is_defined(self, coset, x):
        """Check if an entry is defined.
        """
        return self[coset][x] is not None

    def undefine(self, coset, x):
        self[coset][x] = None

    def define(self, coset, x):
        """
        To define a new coset we need to:
        1. Append a new empty row to the table.
        2. Fill the two entries.
        3. Add this new coset to `p`.
        """
        n = len(self.table)
        self.table.append([None] * len(self.A))
        self[coset][x] = n
        self[n][self.inv(x)] = coset
        self.p.append(n)

    def rep(self, coset):
        """Find the minimal equivalent representative of a given coset
        and modify `p` along the way.
        """
        m = coset
        while m != self.p[m]:
            m = self.p[m]

        j = coset
        while j != self.p[j]:
            j, self.p[j] = self.p[j], m

        return m

    def merge(self, coset1, coset2):
        """
        Merge two equivalent cosets. The larger one is declared to "dead"
        and is added to the queue `q` to be processed later on.
        """
        s = self.rep(coset1)
        t = self.rep(coset2)
        if s != t:
            s, t = min(s, t), max(s, t)
            self.p[t] = s
            self.q.append(t)

    def scan_and_fill(self, coset, word):
        """
        Scan the row of a coset under a given word.
        1. Firstly we start from the left and scan forward to the right as
           far as possible.
           (1a) If it completes correctly then it yields no
                information, do nothing.
           (1b) If it completes incorrectly then a coincidence
                is found, process it.
           (1c) If it does not complete, go to step 2.
        2. Then we start from the right and scan backward to the left as far
           as possible until it "meets" the forward scan `f`. Let this scan
           results in coset `b`.
           (2a) if `f` and `b` overlap, then a coincidence
                is found, process it.
           (2b) if `f` and `b` are about to meet (with a length 1 gap between)
                then a deduction is found, fill in the two new entries.
           (2c) else the scan is incomplete, define a new coset
                and continue scanning forward.
        """
        f = coset
        b = coset
        i = 0
        j = len(word) - 1
        while True:
            # scan forward as far as possible.
            while i <= j and self.is_defined(f, word[i]):
                f = self[f][word[i]]
                i += 1
            # if complete
            if i > j:
                # if complete incorrectly a coincidence is found, process it.
                if f != b:
                    self.coincidence(f, b)
                # else the scan yields no information
                return

            # if scan forward is not completed then scan backward as
            # far as possible until it meets the forward scan.
            while j >= i and self.is_defined(b, self.inv(word[j])):
                b = self[b][self.inv(word[j])]
                j -= 1

            # if f and b overlap then a coincidence is found.
            if j < i:
                self.coincidence(f, b)
                return
            # if f and b are about to meet a deduction is found.
            elif j == i:
                self[f][word[i]] = b
                self[b][self.inv(word[i])] = f
                return
            # else define a new coset and continue scanning forward.
            else:
                self.define(f, word[i])

    def coincidence(self, coset1, coset2):
        """
        Process a coincidence. When two cosets are found to be equivalent
        the larger one is deleted: we need to copy all information in its
        row to the equivalent row and modify all entries it occurs in the
        table. During this process new coincidences may be found and they
        are also processed. The subtle thing here is that we must keep
        filling/deleting entries in pairs, i.e. we must make sure the table
        always satisfy table[k][x] = l <===> table[l][y] = k (y = inv(x)).
        """
        self.merge(coset1, coset2)
        # at this stage the queue contains only one item,
        # but new items may be added to it later.
        while len(self.q) > 0:
            e = self.q.pop(0)
            for x in self.A:
                if self.is_defined(e, x):
                    f = self[e][x]
                    y = self.inv(x)
                    # the entry (f, y) in the row f is also deleted since we
                    # must make sure all entries in the table come in pairs.
                    self.undefine(f, y)
                    # copy the information at (e, x) to (e1, x),
                    # but is (e1, x) already defined?
                    e1 = self.rep(e)
                    f1 = self.rep(f)
                    # if (e1, x) is already defined then
                    # a new coincidence is found.
                    if self.is_defined(e1, x):
                        self.merge(f1, self.table[e1][x])
                    elif self.is_defined(f1, y):
                        self.merge(e1, self.table[f1][y])
                    else:
                        # else (e1, x) is not defined, copy the information
                        # at (e, x) to (e1, x).
                        self[e1][x] = f1
                        self[f1][y] = e1
                        # keep in mind all changes come in pairs,
                        # so we also copy the information at (f, y) to (f1, y).

    def hlt(self):
        """Run the HLT strategy (Haselgrove, Leech and Trotter).
        """
        for word in self.H:
            self.scan_and_fill(0, word)

        current = 0
        while current < len(self.table):
            for rel in self.R:
                if not self.is_alive(current):
                    break
                self.scan_and_fill(current, rel)

            if self.is_alive(current):
                for x in self.A:
                    if not self.is_defined(current, x):
                        self.define(current, x)
            current += 1

    def compress(self):
        """
        Delete all dead cosets in the table. The live cosets are renumbered and
        their entries are also updated.
        """
        ind = -1
        for coset in range(len(self)):
            if self.is_alive(coset):
                ind += 1
                if ind != coset:
                    for x in self.A:
                        y = self[coset][x]
                        if y == coset:
                            self[ind][x] = ind
                        else:
                            self[ind][x] = y
                            self[y][self.inv(x)] = ind

        self.p = list(range(ind + 1))
        self.table = self.table[: len(self.p)]

    def swap(self, k, l):
        """
        Swap two live cosets in the table. It's called in the `standardize()`
        method after the table is compressed, but it also works for
        non-compressed table.
        """
        for x in self.A:
            # swap the two rows k and l.
            self[k][x], self[l][x] = self[l][x], self[k][x]
            # modify all k/l in the table.
            for coset in range(len(self)):
                # this check is not required for a compressed table.
                if self.is_alive(coset):
                    if self[coset][x] == k:
                        self[coset][x] = l
                    elif self[coset][x] == l:
                        self[coset][x] = k

    def standardize(self):
        """Rearrange the cosets in the table to a standard form.
        """
        # the next coset we want to encounter in the table.
        next_coset = 1
        for coset in range(len(self)):
            for x in self.A:
                y = self[coset][x]
                if y >= next_coset:
                    if y > next_coset:
                        self.swap(y, next_coset)
                    next_coset += 1
                    if next_coset == len(self) - 1:
                        return

    def run(self, standard=False):
        self.hlt()
        self.compress()
        if standard:
            self.standardize()

    def get_words(self):
        """
        Return the list of all words in this table. This method must be called
        when the table is already compressed.
        """
        from collections import deque

        gens = self.A if self.coxeter else self.A[::2]
        result = [None] * len(self)
        result[0] = ()
        q = deque([0])
        while q:
            coset = q.popleft()
            for x in gens:
                new_coset = self[coset][x]
                if result[new_coset] is None:
                    result[new_coset] = result[coset] + (x,)
                    q.append(new_coset)
        return result


import json
from socket import timeout

class Point:
    def __init__(self, row, column):
        self._row = row
        self._column = column

    @property
    def row(self):
        return self._row

    @property
    def column(self):
        return self._column

    def serialize(self):
        return {"row": self._row, "column": self._column}

class Player:
    def __init__(self, id, socket, name, group, teammate, coordinate):
        self._id = id
        self._socket = socket
        self._name = name
        self._group = group
        self._teammate = teammate
        self._coordinate = coordinate

    @property
    def id(self):
        return self._id

    @property
    def socket(self):
        return self._socket

    @property
    def name(self):
        return self._name

    @property
    def group(self):
        return self._group

    @property
    def teammate(self):
        return self._teammate

    @property
    def coordinate(self):
        return self._coordinate

    @coordinate.setter
    def coordinate(self, coordinate):
        self._coordinate = coordinate

    def serialize(self):
        return {
            "id": self._id,
            "name": self._name,
            "group": self._group,
            "coordinate": self._coordinate.serialize(),
            "teammate": self._teammate,
        }

class Cell:
    def __init__(self, coordinate: Point):
        self._coordinate = coordinate
        self._player = None

    @property
    def coordinate(self):
        return self._coordinate

    @property
    def player(self):
        return self._player

    @player.setter
    def player(self, player):
        self._player = player

    def serialize(self):
        return {
            "coordinate": self._coordinate.serialize(),
            "player": self._player.serialize(),
        }

class Game:
    def __init__(self, players: list):
        self._height = 13
        self._width = 13
        self._cycle = 1
        self._turn = -1
        self._grid = []

        for i in range(self._height):
            for j in range(self._width):
                self._grid.append((Cell(Point(i, j))))

        self._players = players
        self._walls = {}

    @property
    def cycle(self):
        return self._cycle

    @property
    def turn(self):
        return self._turn

    @property
    def grid(self):
        return self._grid

    @property
    def players(self):
        return self._players

    @property
    def walls(self):
        return self._walls

    def adjacents(self, cell):
        adjs = []
        adjR = [0, 0, 1, -1]
        adjC = [1, -1, 0, 0]
        dir = ['R', 'L', 'D', 'U']
        for i in range(4):
            if cell.coordinate in self._walls.keys():
                if dir[i] in self._walls[cell.coordinate]:
                    continue
            new_cell = Cell(Point(cell.coordinate.row + adjR[i], cell.coordinate.column + adjC[i]))
            if 0 <= new_cell.coordinate.row < self._height and 0 <= new_cell.coordinate.column < self._width:
                adjs.append((dir[i], new_cell))
        return adjs

    @staticmethod
    def index(row, column):
        return row*13+column

    def run(self):
        win = False
        if self._cycle == 1:
            res = {
                "type": "NOP",
                "turn": 0
            }
            for p, conn in self._players:
                conn.send((json.dumps(res) + '\n').encode())
                print(res)
            print("Sent NOP to all for the first time")

        else:
            l = [0, 2, 1, 3]
            player, conn = self._players[l[self._turn]]
            res = {"player": player.id}
            conn.settimeout(20)
            try:
                data = conn.recv(1024)
                str_data = json.loads(data.decode())
                type_ = str_data['type']
                print(str_data)
                res['turn'] = l[(self._turn + 1) % 4]

                if type_ == 'MOVE':
                    res['type'] = type_
                    action = str_data['action']
                    res['action'] = action
                    player_cell = self._grid[Game.index(player.coordinate.row, player.coordinate.column)]
                    adjs = self.adjacents(player_cell)
                    print(adjs)
                    for act, cell in adjs:
                        print(act, action)
                        if action == act:
                            self._grid[self.index(player.coordinate.row, player.coordinate.column)].player = None
                            player.coordinate = cell.coordinate
                            self._grid[self.index(cell.coordinate.row, cell.coordinate.column)] = player
                            print(player.coordinate.row, player.coordinate.column)
                            if player.coordinate.row == 6 and player.coordinate.column == 6:
                                res['type'] = "WIN"
                                res['group'] = player.group
                                win = True

                elif type_ == 'BLOCK':
                    res['type'] = type_
                    point1 = Point(str_data['point1']['row'], str_data['point1']['column'])
                    point2 = Point(str_data['point2']['row'], str_data['point2']['column'])
                    print(point1.row, point1.column, " ", point2.row, point2.column)

                    if point1 not in self._walls.keys():
                        self._walls[point1] = []
                    if point2 not in self._walls.keys():
                        self._walls[point2] = []

                    if point1.row == point2.row + 1:
                        self._walls[point1].append('U')
                        self._walls[point2].append('D')

                    elif point1.row == point2.row - 1:
                        self._walls[point1].append('D')
                        self._walls[point2].append('U')

                    elif point1.column == point2.column + 1:
                        self._walls[point1].append('L')
                        self._walls[point1].append('R')

                    elif point1.column == point2.column - 1:
                        self._walls[point1].append('R')
                        self._walls[point1].append('L')

                    res['point1'] = point1.serialize()
                    res['point2'] = point2.serialize()

                for p, conn in self._players:
                    conn.send((json.dumps(res) + '\n').encode())
                    print(json.dumps(res))

                if win:
                    return

            except:
                print("timeout")
                res = {
                    "type": "NOP",
                    "turn": l[(self._turn + 1) % 4],
                }
                for p, conn in self._players:
                    conn.send((json.dumps(res) + '\n').encode())

        self._turn = (self._turn + 1) % 4
        self._cycle += 1
        self.run()


from datetime import datetime
import pandas as pd
from nltk.sentiment.vader import SentimentIntensityAnalyzer as SIA
import re
import matplotlib.pyplot as plt
import seaborn as sns

import nltk
nltk.download('vader_lexicon')

def date_time(df):
    df['tweet_date'] = df['tweet_dt'].apply(lambda x: datetime.strptime(x,'%Y-%m-%d'))
    df['dt'] = pd.to_datetime(df['tweet_date'])
    return df

def sia_analysis(df):

    sid = SIA()
    df['sentiments'] = df['body'].apply(lambda x: sid.polarity_scores(' '.join(re.findall(r'\w+',x.lower()))))
    df['Positive Sentiment'] = df['sentiments'].apply(lambda x: x['pos']+1*(10**-6))
    df['Neutral Sentiment']= df['sentiments'].apply(lambda x: x['neu']+1*(10**-6))
    df['Negative Sentiment']= df['sentiments'].apply(lambda x: x['neg']+1*(10**-6))

    df.drop(columns=['sentiments'],inplace=True)

    return df

def plot_sentiments(df, title):

    plt.figure(figsize=(20,10))
    plt.title('Distribution Of Sentiments Across Our Tweets about '+ title,fontsize=19,fontweight='bold')
    sns.kdeplot(df['Negative Sentiment'],bw_method=0.1,label = 'Negative')
    sns.kdeplot(df['Positive Sentiment'],bw_method=0.1,label = 'Positive')
    sns.kdeplot(df['Neutral Sentiment'],bw_method=0.1,label = 'Neutral')
    plt.xlabel('Sentiment scores')
    plt.legend()
    plt.show()

def create_df_sent(df):

    df_original = df.copy()
    # Saving the maximum values between the three sentiments and their respective class
    df_sentiment = pd.DataFrame()
    df_sentiment['Max_SentimentCol'] = df[['Negative Sentiment','Positive Sentiment','Neutral Sentiment']].idxmax(axis=1)
    df_sentiment['Max_SentimentValue'] = df[['Negative Sentiment','Positive Sentiment','Neutral Sentiment']].max(axis=1)
    # df_sentiment = df_sentiment.drop(['Negative Sentiment','Positive Sentiment','Neutral Sentiment'], axis=1)

    # Union of new dataframe and original one
    # df_new = df_sentiment.join(df_original)
    return df_sentiment

#TRASFORMANDO IN DATE LE STRINGHE PER POTER RAGGRUPARE LA MEDIA DEI VALORI MASSIMI DI SENTIMENT SCORE PER CATEGORIA (POS,NEG,NEUTRAL) E MESE
def plot_sent_distribution(df_new, title = 'no-title', no_plot = True):

    list_YM = [i.split(" ")[0][:-3] for i in  list(df_new['tweet_dt'])]
    list_Year = [i.split(" ")[0][0:4] for i in  list(df_new['tweet_dt'])]
    list_Month = [i.split(" ")[0][5:7] for i in  list(df_new['tweet_dt'])]

    df_new['YM'] = list_YM
    df_new['Year'] = list_Year
    df_new['Month'] = list_Month

    #create a monthly dataframe
    df_mean = df_new.groupby(['Max_SentimentCol', 'YM', 'Year', 'Month']).mean()
    df_mean = df_mean[['Max_SentimentValue']].reset_index()
    df_mean.sort_values(by='YM',inplace=True)

    if not no_plot:
        sns.set(rc={'figure.figsize':(40,10)})
        ax = sns.lineplot(data=df_mean, x = 'YM', y='Max_SentimentValue',hue='Max_SentimentCol',palette='viridis',legend='full',lw=3)
        xticks = ax.xaxis.get_major_ticks()
        for i in range(len(xticks)):
            if i%2==1:
                xticks[i].set_visible(False)

        plt.legend(bbox_to_anchor=(1, 1))
        plt.title('Distribution of the sentiment score over time by ' + title)
        plt.ylabel('Mean Sentiment Score')
        plt.xlabel('Year-Month')
        plt.xticks(rotation=45)
        plt.show()

    return


from PyQt5.QtWidgets import (
    QWidget, QGridLayout, QHBoxLayout, QVBoxLayout,
    QPushButton, QLabel, QLineEdit, QCheckBox, QSizePolicy
)
from PyQt5.QtCore import QThread, pyqtSignal
import xml.etree.ElementTree as ET
from time import sleep
import os
from TraditionalParamTuning.myPackage.func import mkdir
from TraditionalParamTuning.myPackage.set_btn_enable import set_btn_enable

class PushAndSaveBlock(QWidget):
    alert_info_signal = pyqtSignal(str, str)
    get_and_set_param_value_signal = pyqtSignal()
    capture_signal = pyqtSignal(str)
    push_to_camera_signal = pyqtSignal(bool, str)

    def __init__(self):
        super().__init__()
        self.setup_UI()
        self.setup_controller()

    def setup_UI(self):
        VLayout = QVBoxLayout(self)

        title_wraper = QHBoxLayout()
        label_title = QLabel("Push and Save")
        label_title.setStyleSheet("background-color:rgb(74, 115, 140);")
        # 設定水平大小策略為 Expanding
        label_title.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
        # label_title.setStyleSheet("background-color:rgb(72, 72, 72);")
        title_wraper.addWidget(label_title)
        VLayout.addLayout(title_wraper)

        gridLayout = QGridLayout()

        label = QLabel("資料夾名稱")
        label.setToolTip("要存入的資料夾名稱，如果不填，預設會存在FIH-tool資料夾裡\n此設定只與下方的拍照按鈕功能有關")
        gridLayout.addWidget(label, 0, 0)

        self.lineEdits_dir_name = QLineEdit()
        gridLayout.addWidget(self.lineEdits_dir_name, 0, 1)

        label = QLabel("圖片檔名")
        label.setToolTip("要存入的圖片檔名(不須加上.jpg)，如果不填，預設會存成.jpg\n此設定只與下方的拍照按鈕功能有關")
        gridLayout.addWidget(label, 1, 0)

        self.lineEdits_img_name = QLineEdit()
        gridLayout.addWidget(self.lineEdits_img_name, 1, 1)

        VLayout.addLayout(gridLayout)

        self.btn_set_to_xml = QPushButton("寫入")
        self.btn_set_to_xml.setToolTip("將UI介面上的參數值寫入到project裡")
        VLayout.addWidget(self.btn_set_to_xml)

        self.btn_push_phone = QPushButton("推到手機")
        self.btn_push_phone.setToolTip("將project推到手機")
        VLayout.addWidget(self.btn_push_phone)

        self.btn_capture = QPushButton("拍照")
        self.btn_capture.setToolTip("讓手機拍照，並且存成上面設定的 資料夾名稱/圖片檔名")
        VLayout.addWidget(self.btn_capture)

        self.btn_push_phone_capture = QPushButton("寫入 + 推到手機 + 拍照")
        self.btn_push_phone_capture.setToolTip("將上面三種功能結合")
        VLayout.addWidget(self.btn_push_phone_capture)

        self.btn_input_param = QPushButton("使用文本框輸入參數")
        self.btn_input_param.setToolTip("可將csv的參數直接複製到此，輸入後點寫入按鈕，即可寫入到project")
        VLayout.addWidget(self.btn_input_param)

    def setup_controller(self):
        self.btn_set_to_xml.clicked.connect(self.get_and_set_param_value_signal.emit)
        self.btn_push_phone.clicked.connect(lambda: self.push_phone(is_capture=False, is_set_to_xml=False))
        self.btn_push_phone_capture.clicked.connect(lambda: self.push_phone(is_capture=True, is_set_to_xml=True))
        self.btn_capture.clicked.connect(self.do_capture)

    def get_saved_path(self):
        dir_name = self.lineEdits_dir_name.text()
        img_name = self.lineEdits_img_name.text()

        if dir_name=="": dir_name="."
        mkdir(dir_name)

        return "{}/{}".format(dir_name, img_name)

    def push_phone(self, is_capture, is_set_to_xml):
        saved_path = "./"
        if is_capture:
            saved_path = self.get_saved_path()
            if os.path.exists(saved_path+".jpg"):
                self.alert_info_signal.emit("檔名重複", "檔名\n"+saved_path+".jpg\n已存在，請重新命名")
                return
        if is_set_to_xml:
            self.get_and_set_param_value_signal.emit()

        self.push_to_camera_signal.emit(is_capture, saved_path)

    def set_all_enable(self, b):
        set_btn_enable(self.btn_set_to_xml, b)
        set_btn_enable(self.btn_capture, b)
        set_btn_enable(self.btn_push_phone, b)
        set_btn_enable(self.btn_push_phone_capture, b)
        set_btn_enable(self.btn_input_param, b)

    def do_capture(self):
        print("PushAndSaveBlock do_capture")
        saved_path = self.get_saved_path()
        if os.path.exists(saved_path+".jpg"):
            self.alert_info_signal.emit("檔名重複", "檔名\n"+saved_path+".jpg\n已存在，請重新命名")
            return
        self.capture_signal.emit(saved_path)


from datetime import datetime
from app import app
from flask_sqlalchemy import SQLAlchemy

db = SQLAlchemy(app)

class Storm(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(100), nullable=False)
    description = db.Column(db.Text)
    created = db.Column(db.DateTime, default=datetime.now)
    code = db.Column(db.String(50), unique=True)
    ideas = db.relationship('Idea', backref="storm", lazy="dynamic")

    def __repr__(self):
        return f'<Storm id: {self.id}, name: "{self.name}">'

class Idea(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    text = db.Column(db.Text)
    color = db.Column(db.String(20))
    storm_id = db.Column(db.Integer, db.ForeignKey("storm.id"))
    created = db.Column(db.DateTime, default=datetime.now)

    def __repr__(self):
        return f'<Idea id: {self.id}'


import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd

def main():

    df = {'Protein':[],
            'Score':[],
            'Position':[]}

    h = open('Grich_and_QNrich_LCD-Sup35_Fusion_Sequences_PAPA_RESULTS.tsv')
    header = h.readline()
    for line in h:
        prot, high_score, position, papa_scores, fold_index = line.rstrip().split('\t')
        papa_scores = papa_scores[1:-1].split(' ')
        papa_scores = [float(x) for x in papa_scores]
        i = 0
        for score in papa_scores:
            df['Protein'].append(prot)
            df['Score'].append(score)
            df['Position'].append( i )
            i += 1

    plotting(df)

def plotting(df):

    prots = ['Npl3', 'Ynl208W_Grich', 'Ynl208W_QNrich', 'Rnq1', 'Ure2']
    colors = ['0.85', '0.65', '0.45', '0.0']

    df = pd.DataFrame.from_dict(df)

    for prot in prots:
        color_index = 0
        min_val = 10    # PLACEHOLDER INITIALIZATION VALUE
        for variant in ['_WT', '_+2hyd', '_+4hyd', '_+6hyd']:
            temp_df = df[df['Protein'] == prot+variant]
            sns.lineplot(x='Position', y='Score', data=temp_df, color=colors[color_index])
            color_index += 1
            if min(temp_df['Score']) < min_val:
                min_val = min(temp_df['Score'])

        max_val = max(temp_df['Score'])

        plt.xlim(0, 56)
        plt.ylim(min_val-0.02, max_val+0.02)
        plt.xlabel('Position', fontname='Arial', fontsize=12)
        plt.ylabel('Prion Propensity', fontname='Arial', fontsize=12)
        plt.xticks(fontname='Arial', fontsize=10)
        plt.yticks(fontname='Arial', fontsize=10)
        title, *remainder = prot.split('_')
        plt.title(title, fontname='Arial', fontsize=14)

        fig = plt.gcf()
        fig.set_size_inches(6, 4)

        plt.savefig(prot + '_mPAPA_scores.tiff', bbox_inches='tight', dpi=600)
        plt.close()

if __name__ == '__main__':
    main()


from flask_restless import APIManager
from app import db
from app import app
from flask import Blueprint,json,request
import base64

class Produto(db.Model):
    id = db.Column(db.Integer, primary_key = True)
    nome = db.Column(db.String(200))
    descricao = db.Column(db.String(400))
    imagem = db.Column(db.BLOB)
    valor = db.Column(db.Float(200))
    fator = db.Column(db.Enum('A','B','C', name='fator'))

class Cliente(db.Model):
    id=db.Column(db.Integer,primary_key=True)
    nome=db.Column(db.String(200))
    imagem=db.Column(db.LargeBinary(4000))

    def __init__ (self,id,nome,imagem):

        self.id=id
        self.nome=nome
        self.imagem=imagem

db.drop_all()
db.create_all()

manager = APIManager(app,flask_sqlalchemy_db=db)
incluir_produto = manager.create_api_blueprint(Produto,methods=['GET','POST'],url_prefix='/v0',max_results_per_page=10,
                                               results_per_page=10)

inc_produtos = Blueprint('produtos',__name__)
@inc_produtos.route('/produtos', methods=['POST'])
def incluir_produtos():
    if not request.json or not 'nome' in request.json:
        return 400
    print(request.json['id'])
    print(request.json['nome'])
    print(request.json['imagem'])
    imagem = request.json['imagem']
    img = base64.b64decode(imagem)

    print(img)
    cli = Cliente(id=request.json['id'],nome=request.json['nome'],imagem=img)
    db.session.add(cli)
    db.session.commit()
    #req=request.get_json(silent=True,force=True)

    #id_produto=req['id']
    #nome_produto=req['nome']
    #desc_produto=req['descricao']
    #imagem_produto=req['imagem']
    #imagem_produto.decode("utf-8")
    #valor_produto=req['valor']
    #fator_produto=req['fator']
    #print(id_produto,nome_produto,imagem_produto)
    #cli = Cliente(id='id_produto',nome="nome_produto",imagem="imagem_produto")

    #print(cli)

    #print(req['id'])
    #print(req['nome'])
    #print("Request:")
    #print(json.dumps(req,indent=4))
    return "testes"


import cv2

def main():

    img = cv2.imread("img.jpg", cv2.IMREAD_GRAYSCALE)
    height, width = img.shape[:2]
    histogram = [0] * 256

    for i in range(height):
        for j in range(width):
            # Piksel değerini histograma ekle
            histogram[img[i, j]] += 1

    for i in range(256):
        cv2.line(histogram_img, (i, 0), (i, histogram[i]), (0, 255, 0), 1)

    cv2.imshow("Histogram", histogram_img)
    cv2.waitKey(0)


from typing import List

class Solution:
    @staticmethod
    def rle(lst: List[int]) -> List[int]:
        prev = None
        length = 0
        result = list()
        for current in lst:
            if current == prev:
                length += 1
            else:
                result.append(length)
                length = 1
            prev = current
        result.append(length)
        return result

    @staticmethod
    def count_seq(rle_value: int) -> int:
        if rle_value < 2:
            return 0
        return rle_value * (rle_value - 1) // 2

    def numberOfArithmeticSlices(self, A: List[int]) -> int:
        if len(A) < 3:
            return 0
        diff = [p - q for p, q in zip(A, A[1:])]
        rle = self.rle(diff)
        return sum(self.count_seq(rle_val) for rle_val in rle)


#!/usr/bin/env python

import tweepy, time, os, sys, yaml

PROJDIR = sys.path[0]
# Load twitter credentials for this bot from config file
BOTCRED_FILE = '%s/.twurlrc' % os.path.expanduser('~')
with open(BOTCRED_FILE, 'r') as credfile:
	full_config = yaml.load(credfile)
	api_key = api_key = full_config['profiles']['cloudeverynoun'].keys()[0]
	bot_creds = full_config['profiles']['cloudeverynoun'][api_key]

CONSUMER_KEY = bot_creds['consumer_key']
CONSUMER_SECRET = bot_creds['consumer_secret']
ACCESS_KEY = bot_creds['token']
ACCESS_SECRET = bot_creds['secret']

auth = tweepy.OAuthHandler(CONSUMER_KEY, CONSUMER_SECRET)
auth.set_access_token(ACCESS_KEY, ACCESS_SECRET)
api = tweepy.API(auth)

filename = '%s/nouns_to_tweet.txt' % PROJDIR
with open(filename, 'r') as fin:
    data = fin.read().splitlines(True)
    tweet_text = 'cloud ' + data[0]

with open(filename, 'w') as fout:
    fout.writelines(data[1:])

api.update_status(status=tweet_text.title())


#! /usr/bin/python3
import rospy
from shared_msgs.msg import auto_control_msg, final_thrust_msg, thrust_status_msg, thrust_command_msg, controller_msg
from sensor_msgs.msg import Imu
from std_msgs.msg import Float32, String
import numpy as np
import Complex_1
import thrust_mapping
import json
from dynamic_reconfigure.server import Server
from control.cfg import ROV_COMConfig

desired_p = [0.0,0.0,0.0,0.0,0.0,0.0]
desired_thrusters = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0,0.0,0.0]
desired_p_unramped = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
locked_dims_list = [False, False, False, False, False, False]
disabled_list = [False, False, False, False, False, False, False, False]
inverted_list = [0, 0, 0, 0, 0, 0, 0, 0]
MAX_CHANGE = .1
# watch dog stuff
last_packet_time = 0.0
is_timed_out = False
# timout in ms
WATCHDOG_TIMEOUT = 10

def _pilot_command(comm):
    global desired_p  # desired thrust from pilot
    global disabled_list  # disabled thrusters
    global inverted_list  # inverted thrusters
    global desired_p_unramped
    #print (comm.desired_thrust)
    desired_p = comm.desired_thrust
    # disabled_list = comm.disable_thrusters
    # inverted_list = comm.inverted

def ramp(index):
    if (abs(desired_p_unramped[index] - desired_thrusters[index]) > MAX_CHANGE):
        if (desired_p_unramped[index] - desired_thrusters[index] > 0):
            desired_thrusters[index] += MAX_CHANGE
            #print(index, "ramping", desired_thrusters[index])
        else:
            desired_thrusters[index] -= MAX_CHANGE
        return
    else:
        desired_thrusters[index] = desired_p_unramped[index]
def _updateRamp(msg):
    stuff = json.loads(msg.data)
    MAX_CHANGE = stuff['ramp']
    print(MAX_CHANGE)

def on_loop():
    global new_auto_data
    global is_timed_out
    global last_packet_time
    global desired_thrusters
    global desired_p_unramped
    for i in range(0, 6):
        desired_thrust_final[i] = desired_p[i]

    # calculate thrust
    #pwm_values = c.calculate(desired_thrust_final, disabled_list, False)
    desired_p_unramped = tm.thrustVectorToPWM(tm.calculateThrusterOutput(desired_thrust_final))
    # invert relevant values
    #for i in range(8):
    #    if inverted_list[i] == 1:
    #        pwm_values[i] = pwm_values[i] * (-1)
    for i in range(0,8):
        ramp(i)
    pwm_values = desired_thrusters
    #print(desired_p_unramped)
    # assign values to publisher messages for thurst control and status
    tcm = final_thrust_msg()
    # val = float of range(-1, 1)
    # if int8: (val * 127.5) - 0.5 will give range -128 to 127
    # if uint8: (val + 1) * 127.5 will give 0 to 255
    thrusters = [127,127,127,127,127,127,127,127]
    for i in range(0,8):
        thrusters[i] = int((pwm_values[i] + 1) * 127.5)
    tcm.thrusters = thrusters
    # tcm.thrusters[0] = int((pwm_values[0] + 1) * 127.5)
    # tcm.thrusters[0] = int((pwm_values[1] + 1) * 127.5)
    # tcm.thrusters[0] = int((pwm_values[2] + 1) * 127.5)
    # tcm.thrusters[0] = int((pwm_values[3] + 1) * 127.5)
    # tcm.vfl = int((pwm_values[4] + 1) * 127.5)
    # tcm.vfr = int((pwm_values[5] + 1) * 127.5)
    # tcm.vbr = int((pwm_values[6] + 1) * 127.5)
    # tcm.vbl = int((pwm_values[7] + 1) * 127.5)

    tsm = thrust_status_msg()
    tsm.status = pwm_values
    # publish data
    thrust_pub.publish(tcm)
    status_pub.publish(tsm)
def updateCOM(config, level):
    rospy.loginfo("""Reconfigure Request: {ROV_X}, {ROV_Y}, {ROV_Z}""".format(**config))
    return config

if __name__ == "__main__":
    '''
    Note that this file is only set up for using 8 thrusters.
    '''

    # initialize node and rate
    rospy.init_node('thrust_control')
    srv = Server(ROV_COMConfig, updateCOM)
    rate = rospy.Rate(50)  # 20 hz

    # initialize subscribers
    comm_sub = rospy.Subscriber('/thrust_command', thrust_command_msg, _pilot_command)
    #ramp_sub = rospy.Subscriber('/ramp', String, _updateRamp)
    # controller_sub = rospy.Subscriber('/surface/controller',controller_msg, _teleop)
    #controller_sub = rospy.Subscriber('gamepad_listener', controller_msg, _teleop)
    # initialize publishers
    thrust_pub = rospy.Publisher('final_thrust',
                                 final_thrust_msg, queue_size=10)
    status_pub = rospy.Publisher('thrust_status',
                                 thrust_status_msg, queue_size=10)

    # define variable for class Complex to allow calculation of thruster pwm values
    c = Complex_1.Complex()
    tm = thrust_mapping.ThrustMapper()
    desired_thrust_final = [0, 0, 0, 0, 0, 0]

    while not rospy.is_shutdown():
        on_loop()
        rate.sleep()


import httplib
import logging
from utils.exceptions import HttpRequestException

LOG = logging.getLogger(__name__)

class HttpRequestHandler(object):
    def __init__(self, url, auth_token):
        """ Initialize the Http Request Handler.

        :param url: url of the request recipient
        :param auth_token: authentication token to pass
        in the x-auth-token header
        """
        self.auth_token = auth_token
        address = url.split("http://")[1].split(":")
        self.conn = httplib.HTTPConnection(host=address[0], port=address[1])

    def _send_request(self, method, url, headers, body,
                     ignore_result_body=False):
        """Perform an HTTP request.

        :param method: the HTTP method to use
        :param url: the URL to send request to
        :param headers: request header
        :param body: request body
        :param ignore_result_body: the body of the result will be ignored
        """
        if self.auth_token:
            headers.setdefault('x-auth-token', self.auth_token)

        LOG.debug('\n%(method)s request to: http://%(server)s:%(port)s'
                  '%(url)s \nheaders: %(headers)s'
                  % {'method': method,
                     'server': self.conn.host,
                     'port': self.conn.port,
                     'url': url,
                     'headers': repr(headers)})
        self.conn.request(method, url, body, headers)

        response = self.conn.getresponse()
        # process response
        code = response.status
        code_description = httplib.responses[code]
        logging.debug('Response: %(code)s %(description)s'
                      % {'code': code,
                         'description': code_description})

        if code is not 200:
            raise HttpRequestException(code, code_description, response.read())

        if ignore_result_body:
            # consume response in order to perform another request
            # in the case of ignoring response body
            response.read()
        return response


from django.urls import include, path
from rest_framework.routers import DefaultRouter

from . import views

v1_router = DefaultRouter()
v1_router.register('users', views.UserViewSet, 'users')

urlpatterns = [
    path('v1/', include(v1_router.urls)),
    path('v1/auth/email/', views.get_confirmation_code),
    path('v1/auth/token/', views.get_token),
]