#--------------------------------Imports---------------------------------------#
import pygame, sys
from pygame.locals import *
import random
#--------------------------------Imports---------------------------------------#
#----------------------------------Solve Methods-------------------------------#
global solvedCells
global playerSolution
counter = 0
base = 0
playerSolution = []
solvedCells = []
for i in range(0, 81):
    playerSolution.append(' ')

def cross(A, B):
    "Cross product of elements in A and elements in B."
    return [a+b for a in A for b in B]

digits   = '123456789'
rows     = 'ABCDEFGHI'
cols     = digits
squares  = cross(rows, cols)
unitlist = ([cross(rows, c) for c in cols] +
            [cross(r, cols) for r in rows] +
            [cross(rs, cs) for rs in ('ABC','DEF','GHI') for cs in ('123','456','789')])
units = dict((s, [u for u in unitlist if s in u])
             for s in squares)
peers = dict((s, set(sum(units[s],[]))-set([s]))
             for s in squares)

def parse_grid(grid):
    """Convert grid to a dict of possible values, {square: digits}, or
    return False if a contradiction is detected."""
    values = dict((s, digits) for s in squares)
    global counter
    global base
    counter = 0
    for s,d in grid_values(grid).items():
        base = counter
        if d in digits and not assign(values, s, d):
            return False ## (Fail if we can't assign d to square s.)
##        print solvedCells#[base:counter]
##        print "--"
####        print solvedCells[j:counter][::-1], j, counter
        solvedCells[base:counter] = solvedCells[base:counter][::-1]
##        print solvedCells, base, counter
    return values

def grid_values(grid):
    "Convert grid into a dict of {square: char} with '0' or '.' or ' ' for empties."
    chars = [c for c in grid if c in digits or c in '0. ']
    assert len(chars) == 81
    return dict(zip(squares, chars))

def decodeDict(values):
    """Converts the dicts generated by the other functions into an 81 character
    string. Only returns string values of len() == 1, otherwise returns whitespace."""
    a = ''
    for r in rows:
        for c in cols:
            if len(values[r+c]) == 1:
                a = a + values[r+c]
            else:
                a = a + " "
    return a

def assign(values, s, d):
    """Eliminate all the other values (except d) from values[s] and propagate.
    Return values, except return False if a contradiction is detected."""
    peerList = []
    other_values = values[s].replace(d, '')
    global counter
    if all(eliminate(values, s, d2) for d2 in other_values):
        if [s, d, 0] not in solvedCells and [s, d, 1] not in solvedCells and [s, d, 2] not in solvedCells:
            if counter < len(solvedCells):
                counter = counter + 1
            peerList.append(d)
            for s2 in peers[s]:
                if len(values[s2]) == 1 and values[s2] not in peerList:
                    peerList.append(values[s2])
            peerList.sort()
            if ''.join(peerList) == "123456789":
                solvedCells.append([s, d, 2])
            else:
                solvedCells.append([s, d, 0])
        return values
    else:
        return False

def eliminate(values, s, d):
    """Eliminate d from values[s]; propagate when values or places <= 2.
    Return values, except return False if a contradiction is detected."""
    if d not in values[s]:
        return values ## Already eliminated
    values[s] = values[s].replace(d,'')
    ## (1) If a square s is reduced to one value d2, then eliminate d2 from the peers.
    if len(values[s]) == 0:
        return False ## Contradiction: removed last value
    elif len(values[s]) == 1:
        d2 = values[s]
        if not all(eliminate(values, s2, d2) for s2 in peers[s]):
            return False
    ## (2) If a unit u is reduced to only one place for a value d, then put it there.
    for u in units[s]:
        dplaces = [s for s in u if d in values[s]]
        if len(dplaces) == 0:
            return False ## Contradiction: no place for this value
        elif len(dplaces) == 1:
            # d can only be in one place in unit; assign it there
            if not assign(values, dplaces[0], d):
                return False
    return values

def solve(grid): return search(parse_grid(grid))

def search(values):
    "Using depth-first search and propagation, try all possible values."
    if values is False:
        return False ## Failed earlier
    if all(len(values[s]) == 1 for s in squares):
        return values ## Solved!
    ## Chose the unfilled square s with the fewest possibilities
    n,s = min((len(values[s]), s) for s in squares if len(values[s]) > 1)
    return some(search(assign(values.copy(), s, d))
                for d in values[s])

def some(seq):
    "Return some element of seq that is true."
    for e in seq:
        if e: return e
    return False

def square2Cell(squar):
    '''Takes a cell's designation (eg: A1, E5, I9) (string), returns cell number
    (eg: 0, 40, 80) (int).'''
    if squar[0] == "A": cell = -1
    elif squar[0] == "B": cell = 8
    elif squar[0] == "C": cell = 17
    elif squar[0] == "D": cell = 26
    elif squar[0] == "E": cell = 35
    elif squar[0] == "F": cell = 44
    elif squar[0] == "G": cell = 53
    elif squar[0] == "H": cell = 62
    elif squar[0] == "I": cell = 71
    return cell + int(squar[1])

def isSolved(stringGrid):
    "Checks if string representation of puzzle is complete."
    for i in range(0, len(stringGrid)):
        if stringGrid[i] == ' ':
            return False
    return True

def Coord(cellNo):
    "Takes a cell number, returns cell designation."
    a = "ABCDEFGHI"
    return a[cellNo/9] + str(cellNo % 9 + 1)

def genSol(stringGrid):
    "Accepts a string grid and generates an evolving partial solution."
    b = solve(stringGrid)
    del solvedCells[:]
    a = parse_grid(stringGrid)
    sa = list(decodeDict(a))
    sb = list(decodeDict(b))
    while not(isSolved("".join(sa))):
        i = 0
        while i < 81:
            if sa[i] != sb[i]:
                sa[i] = sb[i]
                if [Coord(i), sb[i], 0] not in solvedCells and [Coord(i), sb[i], 1] not in solvedCells and [Coord(i), sb[i], 2] not in solvedCells:
                    solvedCells.append([Coord(i), sb[i], 1])
                break
            i = i + 1
        sa = list(decodeDict(parse_grid("".join(sa))))
    return b

#----------------------------------Solve Methods-------------------------------#
#-------------------------------------Buttons!---------------------------------#

def writeButtons(mouse):
    "Reads button values 1 through 9 from the button grid."
    if mouse[0] in range(widthBuffer + 3 * cellSize, widthBuffer + 6 * cellSize) and mouse[1] in range(heightBuffer + 10 * cellSize, heightBuffer + 13 * cellSize):
        if mouse[0] in range(widthBuffer + 3 * cellSize, widthBuffer + 4 * cellSize) and mouse[1] in range(heightBuffer + 10 * cellSize, heightBuffer + 11 * cellSize):
            writeValue = "1"
        if mouse[0] in range(widthBuffer + 4 * cellSize, widthBuffer + 5 * cellSize) and mouse[1] in range(heightBuffer + 10 * cellSize, heightBuffer + 11 * cellSize):
            writeValue = "2"
        if mouse[0] in range(widthBuffer + 5 * cellSize, widthBuffer + 6 * cellSize) and mouse[1] in range(heightBuffer + 10 * cellSize, heightBuffer + 11 * cellSize):
            writeValue = "3"
        if mouse[0] in range(widthBuffer + 3 * cellSize, widthBuffer + 4 * cellSize) and mouse[1] in range(heightBuffer + 11 * cellSize, heightBuffer + 12 * cellSize):
            writeValue = "4"
        if mouse[0] in range(widthBuffer + 4 * cellSize, widthBuffer + 5 * cellSize) and mouse[1] in range(heightBuffer + 11 * cellSize, heightBuffer + 12 * cellSize):
            writeValue = "5"
        if mouse[0] in range(widthBuffer + 5 * cellSize, widthBuffer + 6 * cellSize) and mouse[1] in range(heightBuffer + 11 * cellSize, heightBuffer + 12 * cellSize):
            writeValue = "6"
        if mouse[0] in range(widthBuffer + 3 * cellSize, widthBuffer + 4 * cellSize) and mouse[1] in range(heightBuffer + 12 * cellSize, heightBuffer + 13 * cellSize):
            writeValue = "7"
        if mouse[0] in range(widthBuffer + 4 * cellSize, widthBuffer + 5 * cellSize) and mouse[1] in range(heightBuffer + 12 * cellSize, heightBuffer + 13 * cellSize):
            writeValue = "8"
        if mouse[0] in range(widthBuffer + 5 * cellSize, widthBuffer + 6 * cellSize) and mouse[1] in range(heightBuffer + 12 * cellSize, heightBuffer + 13 * cellSize):
            writeValue = "9"
        return writeValue
    return False

def clearButton(mouse):
    "Reads the Clr value from the button grid."
    if mouse[0] in range(widthBuffer + 6 * cellSize, widthBuffer + 7 * cellSize + 1) and mouse[1] in range(heightBuffer + 12 * cellSize, heightBuffer + 13 * cellSize + 1):
        return " "
    return False

def writing(a, playerSolution, value, mouse):
    "Writes 'value' to the human grid."
    if mouse[0] in range(widthBuffer, widthBuffer + 9 * cellSize) and mouse[1] in range(heightBuffer, heightBuffer + 9 * cellSize):
        cellNo = (mouse[0] - widthBuffer) // cellSize + 9 * ((mouse[1] - heightBuffer) // cellSize)
        playerSolution[cellNo] = value
        if a[cellNo] == " ":
            pygame.draw.rect(screen, (255, 255, 255), [cellHuman[cellNo][0] + 1, cellHuman[cellNo][1] + 1, cellSize-2, cellSize-2])
            font = pygame.font.Font("FreeSans.ttf", int(windowWidth * 0.015))
            text = font.render('%s' % value, 1, (150, 150, 150))
            textpos = text.get_rect()
            textpos.centerx = cellHuman[cellNo][0] + cellSize/2
            textpos.centery = cellHuman[cellNo][1] + cellSize/2
            screen.blit(text, textpos)
            pygame.display.update()
        return True
    return False

def RESET(mouse):
    if mouse[0] in range(int(windowWidth/2 + widthBuffer), int(windowWidth/2 + widthBuffer + 3 * cellSize)) and mouse[1] in range(int(heightBuffer + 10 * cellSize), int(heightBuffer + 11 * cellSize)):
        return True
    return False

def NLV(mouse):
    if mouse[0] in range(int(windowWidth/2 + widthBuffer + 6 * cellSize), int(windowWidth/2 + widthBuffer + 9 * cellSize)) and mouse[1] in range(int(heightBuffer + 10 * cellSize), int(heightBuffer + 11 * cellSize)):
        return True
    return False

def PREVIOUSPUZZLE(mouse):
    if mouse[0] in range(int(windowWidth/2 + widthBuffer), int(windowWidth/2 + widthBuffer + 3 * cellSize)) and mouse[1] in range(int(heightBuffer + 11 * cellSize + cellSize/2), int(heightBuffer + 12 * cellSize + cellSize/2)):
        return True
    return False

def NEXTPUZZLE(mouse):
    if mouse[0] in range(int(windowWidth/2 + widthBuffer  + 6 * cellSize), int(windowWidth/2 + widthBuffer  + 6 * cellSize + 3 * cellSize)) and mouse[1] in range(int(heightBuffer + 11 * cellSize + cellSize/2), int(heightBuffer + 12 * cellSize + cellSize/2)):
        return True
    return False

def RANDOMPUZZLE(mouse):
    if mouse[0] in range(int(windowWidth/2 + widthBuffer), int(windowWidth/2 + widthBuffer + 3 * cellSize)) and mouse[1] in range(int(heightBuffer + 13 * cellSize), int(heightBuffer + 14 * cellSize)):
        return True
    return False

def QUIT(mouse):
    if mouse[0] in range(int(windowWidth - 3 * cellSize), windowWidth) and mouse[1] in range(0, cellSize):
        return True
    return False
#-------------------------------------Buttons!---------------------------------#
def main():
#-----------------------------------Inits--------------------------------------#
    random.seed() ## Seeds PRNG, necessary for initialising random number generation used to load puzzles.
    pygame.init() ## Initialises Pygame module.
    global fpsLock, screen ## 'screen' is the surface that the entire interface is being rendered on. 'fpslock' is used to maintain 'fps', defined later.
    global cellHuman ## Global list runs through coordinates for each 'human' cell, i. e., cell on the left-sided grid.
    global windowHeight, windowWidth, gridColour, background, black, gridLines, gridSize, squareSize, cellSize, widthBuffer, heightBuffer, cellHuman
    windowHeight = 720 ## Min. height is 486, min. width is 972. No errors if dimensions are less, but the grids will overlap.
    windowWidth = 1280 ## Every positioning statement uses these values, so all prints will auto - readjust is these values are modified.
    fps = 60 ## Frames per second. Set at 60 because 60 is standard for games, this program doesn't really require it.
    gridColour = (255, 255, 255) ## RGB White
    background = (0, 255, 255) ## RGB Cyan
    black = (0, 0, 0) ## RBG...well, black
    gridLines = (200, 200, 200) ## RGB 'Light Gray'
    cellSize = int((int(windowHeight * 0.45)/3)/3) ## Dimensions of each puzzle
    widthBuffer = int((windowWidth / 2 - 9 * cellSize ) / 2) ## Buffer between the grids, left window margin, right window margin, and dividing line.
    heightBuffer = int((windowHeight - 9 * cellSize) / 2) ## Buffer between grids, top window margin, and bottom window margin.
    cellHuman = [[widthBuffer, heightBuffer]] ## Initialising coordinate list to the top left corner of the top left cell of the left-sided grid.

## Loop runs through top left corner of each cell of the left-sided grid, stores the coordinates as a two dimensional list in 'cellHuman'.
    i = 1
    while i < 81:
        if i % 9 == 0:
            cellHuman.append([widthBuffer, cellHuman[len(cellHuman) -1][1] + cellSize])
        else:
            cellHuman.append([cellHuman[len(cellHuman) -1][0] + cellSize, cellHuman[len(cellHuman) -1][1]])
        i = i + 1

    screen = pygame.display.set_mode((windowWidth, windowHeight))#, FULLSCREEN) ## Defines the size of the surface generated, remove the # infront of FULLSCREEN to make it, uhh, go fullscreen.
## If you get a syntax error when trying to run FULLSCREEN, count the number of brackets in the statement.
    fpsLock = pygame.time.Clock() ## Initializing the lock on fps, called during run-time event loop to tick 'fps' times per second.
    pygame.display.set_caption("Sudoku Solver") ## Window caption, unimportant if running in FULLSCREEN.
    screen.fill(background) ## Fills the entire surface with colour
## Draws rectangle where our sudoku puzzles will go, to give them a different background.
    pygame.draw.rect(screen, gridColour, [widthBuffer, heightBuffer, 9 * cellSize, 9 * cellSize])
    pygame.draw.rect(screen, gridColour, [windowWidth/2 + widthBuffer, heightBuffer, 9 * cellSize, 9 * cellSize])
#-----------------------------------Inits--------------------------------------#
#---------------------------------Draw Methods---------------------------------#
    def drawGrid():
        "Draws two 486x486 resolution, 9x9 cell grids, as well as a dividing line in the centre of the surface. The grids are each centred in their respective half of the surface."
## Loops for drawing the inner 'Light Gray' lines. Lines for the border are also drawn, but later overdrawn by black lines.
        # widthBuffer = int(widthBuffer)
        # heightBuffer = int(heightBuffer)
        # cellSize = int(cellSize)
        for x in range(widthBuffer , widthBuffer + 9 * cellSize + 1, cellSize):
            pygame.draw.line(screen, gridLines, (x, heightBuffer), (x, 9 * cellSize - 1 + heightBuffer))
        for y in range(heightBuffer, heightBuffer + 9 * cellSize + 1, cellSize):
            pygame.draw.line(screen, gridLines, (widthBuffer, y), (9 * cellSize - 1 + widthBuffer, y))

        for x in range(widthBuffer , widthBuffer + 9 * cellSize + 1, 3 * cellSize):
            pygame.draw.line(screen, black, (x, heightBuffer), (x, 9 * cellSize - 1 + heightBuffer))
        for y in range(heightBuffer, heightBuffer + 9 * cellSize + 1, 3 * cellSize):
            pygame.draw.line(screen, black, (widthBuffer, y), (9 * cellSize - 1 + widthBuffer, y))

## Drawing button grid
        pygame.draw.rect(screen, (0, 0, 0), [widthBuffer + 3 * cellSize, heightBuffer + 10 * cellSize, 3 * cellSize, 3 * cellSize])
        pygame.draw.rect(screen, (0, 0, 0), [widthBuffer + 6 * cellSize, heightBuffer + 12 * cellSize, cellSize, cellSize])

        for x in range(widthBuffer + 3 * cellSize, widthBuffer + 6 * cellSize + 1, cellSize):
            pygame.draw.line(screen, (255, 255, 255), (x, heightBuffer + 10 * cellSize), (x, heightBuffer + 13 * cellSize))
        for y in range(heightBuffer + 10 * cellSize, heightBuffer + 13 * cellSize + 1, cellSize):
            pygame.draw.line(screen, (255, 255, 255), (widthBuffer + 3 * cellSize, y), (widthBuffer + 6 * cellSize, y))
        pygame.draw.line(screen, (255, 255, 255), (widthBuffer + 6 * cellSize, heightBuffer + 13 * cellSize), (widthBuffer + 7 * cellSize, heightBuffer + 13 * cellSize))
        pygame.draw.line(screen, (255, 255, 255), (widthBuffer + 6 * cellSize, heightBuffer + 12 * cellSize), (widthBuffer + 7 * cellSize, heightBuffer + 12 * cellSize))
        pygame.draw.line(screen, (255, 255, 255), (widthBuffer + 7 * cellSize, heightBuffer + 12 * cellSize), (widthBuffer + 7 * cellSize, heightBuffer + 13 * cellSize))

        font = pygame.font.Font("FreeSans.ttf", int(windowWidth * 0.015))
        text = font.render("Clr", 1, (255, 255, 255))
        textpos = text.get_rect()
        textpos.centerx = widthBuffer + 6 * cellSize + cellSize/2
        textpos.centery = heightBuffer + 12 * cellSize + cellSize/2
        screen.blit(text, textpos)
        i = 1
        for y in range(int(heightBuffer + 10 * cellSize + cellSize/2), int(heightBuffer + 13 * cellSize), cellSize):
            for x in range(int(widthBuffer + 3 * cellSize + cellSize/2), int(widthBuffer + 6 * cellSize), cellSize):
                text = font.render('%s' % i, 1, (255, 255, 255))
                textpos = text.get_rect()
                textpos.centerx = x
                textpos.centery = y
                screen.blit(text, textpos)
                i = i + 1

## Quit
        pygame.draw.rect(screen, (0, 0, 0), [windowWidth - 3 * cellSize, 0, 3 * cellSize, cellSize])
        pygame.draw.line(screen, (255, 255, 255), (windowWidth - 3 * cellSize, 0), (windowWidth,0))
        pygame.draw.line(screen, (255, 255, 255), (windowWidth - 3 * cellSize, cellSize), (windowWidth, cellSize))
        pygame.draw.line(screen, (255, 255, 255), (windowWidth - 3 * cellSize, 0), (windowWidth - 3 * cellSize, cellSize))
        pygame.draw.line(screen, (255, 255, 255), (windowWidth - 1, 0), (windowWidth - 1, cellSize))
        text = font.render("Exit", 1, (255, 255, 255))
        textpos = text.get_rect()
        textpos.centerx = windowWidth - 2 * cellSize + cellSize/2
        textpos.centery = cellSize/2
        screen.blit(text, textpos)

## Reset Button
        pygame.draw.rect(screen, (0, 0, 0), [windowWidth/2 + widthBuffer, heightBuffer + 10 * cellSize, 3 * cellSize, cellSize])
        pygame.draw.line(screen, (255, 255, 255), (windowWidth/2 + widthBuffer, heightBuffer + 10 * cellSize), (windowWidth/2 + widthBuffer + 3 * cellSize, heightBuffer + 10 * cellSize))
        pygame.draw.line(screen, (255, 255, 255), (windowWidth/2 + widthBuffer, heightBuffer + 11 * cellSize), (windowWidth/2 + widthBuffer + 3 * cellSize, heightBuffer + 11 * cellSize))
        pygame.draw.line(screen, (255, 255, 255), (windowWidth/2 + widthBuffer, heightBuffer + 10 * cellSize), (windowWidth/2 + widthBuffer, heightBuffer + 11 * cellSize))
        pygame.draw.line(screen, (255, 255, 255), (windowWidth/2 + widthBuffer + 3 * cellSize, heightBuffer + 10 * cellSize), (windowWidth/2 + widthBuffer + 3 * cellSize, heightBuffer + 11 * cellSize))
        text = font.render("Reset", 1, (255, 255, 255))
        textpos = text.get_rect()
        textpos.centerx = windowWidth/2 + widthBuffer + cellSize + cellSize/2
        textpos.centery = heightBuffer + 10 * cellSize + cellSize/2
        screen.blit(text, textpos)

## NLV Button
        pygame.draw.rect(screen, (0, 0, 0), [windowWidth/2 + widthBuffer + 6 * cellSize, heightBuffer + 10 * cellSize, 3 * cellSize, cellSize])
        pygame.draw.line(screen, (255, 255, 255), (windowWidth/2 + widthBuffer + 6 * cellSize, heightBuffer + 10 * cellSize), (windowWidth/2 + widthBuffer + 9 * cellSize, heightBuffer + 10 * cellSize))
        pygame.draw.line(screen, (255, 255, 255), (windowWidth/2 + widthBuffer + 6 * cellSize, heightBuffer + 11 * cellSize), (windowWidth/2 + widthBuffer + 9 * cellSize, heightBuffer + 11 * cellSize))
        pygame.draw.line(screen, (255, 255, 255), (windowWidth/2 + widthBuffer + 6 * cellSize, heightBuffer + 10 * cellSize), (windowWidth/2 + widthBuffer + 6 * cellSize, heightBuffer + 11 * cellSize))
        pygame.draw.line(screen, (255, 255, 255), (windowWidth/2 + widthBuffer + 9 * cellSize, heightBuffer + 10 * cellSize), (windowWidth/2 + widthBuffer + 9 * cellSize, heightBuffer + 11 * cellSize))
        text = font.render("Next Value", 1, (255, 255, 255))
        textpos = text.get_rect()
        textpos.centerx = windowWidth/2 + widthBuffer + 7 * cellSize + cellSize/2
        textpos.centery = heightBuffer + 10 * cellSize + cellSize/2
        screen.blit(text, textpos)

## Next Puzzle Button
        pygame.draw.rect(screen, (0, 0, 0), [windowWidth/2 + widthBuffer + 6 * cellSize, heightBuffer + 11 * cellSize + cellSize/2, 3 * cellSize, cellSize])
        pygame.draw.line(screen, (255, 255, 255), (windowWidth/2 + widthBuffer + 6 * cellSize, heightBuffer + 11 * cellSize + cellSize/2), (windowWidth/2 + widthBuffer + 9 * cellSize, heightBuffer + 11 * cellSize + cellSize/2))
        pygame.draw.line(screen, (255, 255, 255), (windowWidth/2 + widthBuffer + 6 * cellSize, heightBuffer + 12 * cellSize + cellSize/2), (windowWidth/2 + widthBuffer + 9 * cellSize, heightBuffer + 12 * cellSize + cellSize/2))
        pygame.draw.line(screen, (255, 255, 255), (windowWidth/2 + widthBuffer + 6 * cellSize, heightBuffer + 11 * cellSize + cellSize/2), (windowWidth/2 + widthBuffer + 6 * cellSize, heightBuffer + 12 * cellSize + cellSize/2))
        pygame.draw.line(screen, (255, 255, 255), (windowWidth/2 + widthBuffer + 9 * cellSize, heightBuffer + 11 * cellSize + cellSize/2), (windowWidth/2 + widthBuffer + 9 * cellSize, heightBuffer + 12 * cellSize + cellSize/2))
        text = font.render("Next", 1, (255, 255, 255))
        textpos = text.get_rect()
        textpos.centerx = windowWidth/2 + widthBuffer + 7 * cellSize + cellSize/2
        textpos.centery = heightBuffer + 12 * cellSize
        screen.blit(text, textpos)

## Previous Puzzle Button
        pygame.draw.rect(screen, (0, 0, 0), [windowWidth/2 + widthBuffer, heightBuffer + 11 * cellSize + cellSize/2, 3 * cellSize, cellSize])
        pygame.draw.line(screen, (255, 255, 255), (windowWidth/2 + widthBuffer, heightBuffer + 11 * cellSize + cellSize/2), (windowWidth/2 + widthBuffer + 3 * cellSize, heightBuffer + 11 * cellSize + cellSize/2))
        pygame.draw.line(screen, (255, 255, 255), (windowWidth/2 + widthBuffer, heightBuffer + 12 * cellSize + cellSize/2), (windowWidth/2 + widthBuffer + 3 * cellSize, heightBuffer + 12 * cellSize + cellSize/2))
        pygame.draw.line(screen, (255, 255, 255), (windowWidth/2 + widthBuffer, heightBuffer + 11 * cellSize + cellSize/2), (windowWidth/2 + widthBuffer, heightBuffer + 12 * cellSize + cellSize/2))
        pygame.draw.line(screen, (255, 255, 255), (windowWidth/2 + widthBuffer + 3 * cellSize, heightBuffer + 11 * cellSize + cellSize/2), (windowWidth/2 + widthBuffer + 3 * cellSize, heightBuffer + 12 * cellSize + cellSize/2))
        text = font.render("Previous", 1, (255, 255, 255))
        textpos = text.get_rect()
        textpos.centerx = windowWidth/2 + widthBuffer + cellSize + cellSize/2
        textpos.centery = heightBuffer + 12 * cellSize
        screen.blit(text, textpos)

## Random Puzzle Button
        pygame.draw.rect(screen, (0, 0, 0), [windowWidth/2 + widthBuffer, heightBuffer + 13 * cellSize, 3 * cellSize, cellSize])
        pygame.draw.line(screen, (255, 255, 255), (windowWidth/2 + widthBuffer, heightBuffer + 13 * cellSize), (windowWidth/2 + widthBuffer + 3 * cellSize, heightBuffer + 13 * cellSize))
        pygame.draw.line(screen, (255, 255, 255), (windowWidth/2 + widthBuffer, heightBuffer + 14 * cellSize), (windowWidth/2 + widthBuffer + 3 * cellSize, heightBuffer + 14 * cellSize))
        pygame.draw.line(screen, (255, 255, 255), (windowWidth/2 + widthBuffer, heightBuffer + 13 * cellSize), (windowWidth/2 + widthBuffer, heightBuffer + 14 * cellSize))
        pygame.draw.line(screen, (255, 255, 255), (windowWidth/2 + widthBuffer + 3 * cellSize, heightBuffer + 13 * cellSize), (windowWidth/2 + widthBuffer + 3 * cellSize, heightBuffer + 14 * cellSize))
        text = font.render("Random", 1, (255, 255, 255))
        textpos = text.get_rect()
        textpos.centerx = windowWidth/2 + widthBuffer + cellSize + cellSize/2
        textpos.centery = heightBuffer + 14 * cellSize - cellSize/2
        screen.blit(text, textpos)

## Dividing line in the middle of the screen.
        pygame.draw.line(screen, black, (windowWidth/ 2, 5), (windowWidth/2, windowHeight - 5))

## Loops for drawing grid and 3x3 square outlines in black.
        for x in range(widthBuffer , widthBuffer + 9 * cellSize + 1, cellSize):
            pygame.draw.line(screen, gridLines, (windowWidth/2 + x, heightBuffer), (windowWidth/2 + x, 9 * cellSize - 1 + heightBuffer))
        for y in range(heightBuffer, heightBuffer + 9 * cellSize + 1, cellSize):
            pygame.draw.line(screen, gridLines, (windowWidth/2 + widthBuffer, y), (windowWidth/2 + 9 * cellSize - 1 + widthBuffer, y))
        for x in range(widthBuffer , widthBuffer + 9 * cellSize + 1, 3 * cellSize):
            pygame.draw.line(screen, black, (windowWidth/2 + x, heightBuffer), (windowWidth/2 + x, 9 * cellSize - 1 + heightBuffer))
        for y in range(heightBuffer, heightBuffer + 9 * cellSize + 1, 3 * cellSize):
            pygame.draw.line(screen, black, (windowWidth/2 + widthBuffer, y), (windowWidth/2 + 9 * cellSize - 1 + widthBuffer, y))
        return None

    def coorMark():
        font = pygame.font.Font("FreeSans.ttf", int(windowWidth * 0.015))
        i = 0
        while i < 9:
            text = font.render('%s' % str(i+1), 1, (0, 0, 0))
            textpos = text.get_rect()
            textpos.centerx = windowWidth/2 + cellHuman[i][0] + cellSize/2
            textpos.centery = cellHuman[i][1] - cellSize/2
            screen.blit(text, textpos)
            i = i + 1

        i = 0
        alpha = "ABCDEFGHI"
        while i < 81:
            text = font.render('%s' % alpha[int(i/9)], 1, (0, 0, 0))
            textpos = text.get_rect()
            textpos.centerx = windowWidth/2 + cellHuman[i][0] - cellSize/2
            textpos.centery = cellHuman[i][1] + cellSize/2
            screen.blit(text, textpos)
            i = i + 9

    def initGridLeft(a):
        "Initialises left-sided grid with values from a, which should be an 81 character string."
        i = 0
        font = pygame.font.Font("FreeSans.ttf", int(windowWidth * 0.015)) ## Defines text font and size, None is Pygame default.
        while i < 81:
            text = font.render('%s' % a[i], 1, (0, 0, 0)) ## String in a[i] (In this case, it is a single character) is stored in text. Other attributes are anti-aliasing (1 -> On, 0 -> Off) and colour ((0, 0, 0) is RGB Black).
            textpos = text.get_rect()
## The next bit aligns the x, y centres of the text to the centre of the grid, then blits it onto the surface.
            textpos.centerx = cellHuman[i][0] + cellSize/2
            textpos.centery = cellHuman[i][1] + cellSize/2
            screen.blit(text, textpos)
            i = i + 1

    def initGridRight(a, colour = (0, 0, 0)):
        "Initialises right-sided grid with values from a, which should be an 81 character string."
        i = 0
        font = pygame.font.Font("FreeSans.ttf", int(windowWidth * 0.015))
        while i < 81:
            text = font.render('%s' % a[i], 1, colour)
            textpos = text.get_rect()
            textpos.centerx = cellHuman[i][0] + windowWidth / 2 + cellSize/2
            textpos.centery = cellHuman[i][1] + cellSize/2
            screen.blit(text, textpos)
            i = i + 1

    def emptyGrid(a):
        "Empties grid a (0 for left grid, 1 for right grid)."
        pygame.draw.rect(screen, gridColour, [a * windowWidth/2 + widthBuffer, heightBuffer, 9 * cellSize, 9 * cellSize])
        drawGrid()

    def initCellLeft(a, i):
        "Loads a single cell entry a, into cell i on the left-sided grid."
        font = pygame.font.Font("FreeSans.ttf", int(windowWidth * 0.015))
        text = font.render('%s' % a, 1, (0, 0, 0))
        textpos = text.get_rect()
        textpos.centerx = cellHuman[i][0] + cellSize/2
        textpos.centery = cellHuman[i][1] + cellSize/2
        screen.blit(text, textpos)

    def initCellRight(a, i, colour = (0, 0, 0)):
        "Loads a single cell entry a, into cell i on the right-sided grid."
        font = pygame.font.Font("FreeSans.ttf", int(windowWidth * 0.015))
        text = font.render('%s' % a, 1, colour)
        textpos = text.get_rect()
        textpos.centerx = cellHuman[i][0] + windowWidth / 2 + cellSize/2
        textpos.centery = cellHuman[i][1] + cellSize/2
        screen.blit(text, textpos)

#---------------------------------Draw Methods---------------------------------#

## Execution starts here.
    drawGrid() ## Sets up both grids and dividing line.
    grid = []
    f = open('Puzzles.txt', 'r')
    for line in f:
        grid.append(line)
    f.close()
    puzzleNo = random.randrange(0, len(grid))
    del solvedCells[:]
    coorMark()
    a = grid[puzzleNo]
    i = 0
    playerSolution = list(a)
    b = genSol(a)
    initGridLeft(a)
    initGridRight(a)
    pygame.display.update()
    value = " "
    initGridRight(a)
    pygame.display.update()

## Event loop, keeps the everything as is until QUIT button is hit.
    while True:
        for event in pygame.event.get():
            if event.type == QUIT:
                pygame.quit()
                sys.exit()
            elif event.type == MOUSEBUTTONDOWN:
                if writeButtons(pygame.mouse.get_pos()):
                    pygame.draw.rect(screen, background, [0, 0, windowWidth/2 - 1, heightBuffer - 1])
                    pygame.draw.rect(screen, background, [windowWidth/2 + 1, cellSize + 1, windowWidth/2 - 1, heightBuffer - 2*cellSize])
                    value = writeButtons(pygame.mouse.get_pos())

                elif clearButton(pygame.mouse.get_pos()):
                    pygame.draw.rect(screen, background, [windowWidth/2 + 1, cellSize + 1, windowWidth/2 - 1, heightBuffer - 2*cellSize])
                    pygame.draw.rect(screen, background, [0, 0, windowWidth/2 - 1, heightBuffer - 1])
                    value = clearButton(pygame.mouse.get_pos())

                elif writing(a, playerSolution, value, pygame.mouse.get_pos()):
                    pygame.draw.rect(screen, background, [0, 0, windowWidth/2 - 1, heightBuffer - 1])
                    pygame.draw.rect(screen, background, [windowWidth/2 + 1, cellSize + 1, windowWidth/2 - 1, heightBuffer - 2*cellSize])
                    if ' ' not in playerSolution:
                        if "".join(playerSolution[0:81]) == decodeDict(b):
                            compMesg = "Correct Solution!"
                        else:
                            compMesg = "Sorry :( Wrong Answer"
                        font = pygame.font.Font("FreeSans.ttf", int(windowWidth * 0.015))
                        text = font.render('%s' % compMesg, 1, (0, 0, 0))
                        textpos = text.get_rect()
                        textpos.centerx = (windowWidth/2)/2
                        textpos.centery = heightBuffer/2
                        screen.blit(text, textpos)

                elif RESET(pygame.mouse.get_pos()):
                    pygame.draw.rect(screen, background, [0, 0, windowWidth/2 - 1, heightBuffer - 1])
                    pygame.draw.rect(screen, background, [windowWidth/2 + 1, cellSize + 1, windowWidth/2 - 1, heightBuffer - 2*cellSize])
                    emptyGrid(0)
                    initGridLeft(a)
                    pygame.display.update()

                elif PREVIOUSPUZZLE(pygame.mouse.get_pos()):
                    pygame.draw.rect(screen, background, [0, 0, windowWidth/2 - 1, heightBuffer - 1])
                    pygame.draw.rect(screen, background, [windowWidth/2 + 1, cellSize + 1, windowWidth/2 - 1, heightBuffer - 2*cellSize])
                    del solvedCells[:]
                    emptyGrid(0)
                    emptyGrid(1)
                    if puzzleNo == 0:
                        puzzleNo = len(grid) - 1
                    else:
                        puzzleNo = puzzleNo - 1
                    a = grid[puzzleNo]
                    i = 0
                    playerSolution = list(a)
                    b = genSol(a)
                    initGridLeft(a)
                    initGridRight(a)

                elif NEXTPUZZLE(pygame.mouse.get_pos()):
                    pygame.draw.rect(screen, background, [0, 0, windowWidth/2 - 1, heightBuffer - 1])
                    pygame.draw.rect(screen, background, [windowWidth/2 + 1, cellSize + 1, windowWidth/2 - 1, heightBuffer - 2*cellSize])
                    del solvedCells[:]
                    emptyGrid(0)
                    emptyGrid(1)
                    if puzzleNo == len(grid) - 1:
                        puzzleNo = 0
                    else:
                        puzzleNo = puzzleNo + 1
                    a = grid[puzzleNo]
                    i = 0
                    playerSolution = list(a)
                    b = genSol(a)
                    initGridLeft(a)
                    initGridRight(a)

                elif RANDOMPUZZLE(pygame.mouse.get_pos()):
                    pygame.draw.rect(screen, background, [0, 0, windowWidth/2 - 1, heightBuffer - 1])
                    pygame.draw.rect(screen, background, [windowWidth/2 + 1, cellSize + 1, windowWidth/2 - 1, heightBuffer - 2*cellSize])
                    del solvedCells[:]
                    emptyGrid(0)
                    emptyGrid(1)
                    puzzleNo = random.randrange(0, len(grid))
                    a = grid[puzzleNo]
                    i = 0
                    playerSolution = list(a)
                    b = genSol(a)
                    initGridLeft(a)
                    initGridRight(a)

                elif QUIT(pygame.mouse.get_pos()):
                    pygame.draw.rect(screen, background, [0, 0, windowWidth/2 - 1, heightBuffer - 1])
                    pygame.draw.rect(screen, background, [windowWidth/2 + 1, cellSize + 1, windowWidth/2 - 1, heightBuffer - 2*cellSize])
                    pygame.quit()
                    sys.exit()

                elif NLV(pygame.mouse.get_pos()):
                    pygame.draw.rect(screen, background, [0, 0, windowWidth/2 - 1, heightBuffer - 1])
                    pygame.draw.rect(screen, background, [windowWidth/2 + 1, cellSize + 1, windowWidth/2 - 1, heightBuffer - 2*cellSize])
                    if i >= 81:
                        break
                    while list(a)[square2Cell(solvedCells[i][0])] == solvedCells[i][1] and i < len(solvedCells):
                        i = i + 1
                    if a[square2Cell(solvedCells[i][0])] == " " and i < len(solvedCells):
                        font = pygame.font.Font("FreeSans.ttf", int(windowWidth * 0.015))
                        mesg =  solvedCells[i][1] + " in " + solvedCells[i][0]
                        if solvedCells[i][2] == 0:
                            mesg = mesg + " using elimination."
                        elif solvedCells[i][2] == 1:
                            mesg = mesg + " using backtracking."
                        else:
                            mesg = mesg + " as no value other than " + solvedCells[i][1] + " fits in that cell."
                        text = font.render('%s' % mesg, 1, (0, 0, 0))
                        textpos = text.get_rect()
                        textpos.centerx = windowWidth/2 + (windowWidth/2)/2
                        textpos.centery = heightBuffer/2
                        screen.blit(text, textpos)
                        initCellRight(solvedCells[i][1], square2Cell(solvedCells[i][0]), (150, 150, 150))
                        pygame.display.update()
                        pygame.time.delay(100) ## Change TD to Button.
                    i = i + 1
        pygame.display.update()
        fpsLock.tick(fps) ## Refreshes the screen 'fps' times per second.

if __name__ == '__main__':
    main()


from sanic import Sanic
from sanic_openapi.openapi import blueprint

# ------------------------------------------------------------ #
#  GET
# ------------------------------------------------------------ #

def test_get_docs():
    app = Sanic('test_get')

    app.blueprint(blueprint)

    request, response = app.test_client.get('/openapi/spec.json')
    print(next(response.json()))
    assert response.status == 200

test_get_docs()


from SignalModel import Signal
from LayerSelect import LayerSelect
import matplotlib.pyplot as plt
import numpy as np
import math as mt
from BlockThMethod import BlockThMethod
from ThresholdSelect import ThSelect
from BestThEstimation import BestThEstimate
from ThSearchAlgorithm import ThSearchAlgorithm
from WtProcess import DWTP
from DenoiseResult import DenoiseRsult

if __name__ == '__main__':
    s = Signal(1000)
    od1 = s.createSin(50, 60, 4)
    od2 = s.createPulse(50, 60, 4)
    od3 = s.createSpikes(4)
    ods = [od1, od2, od3]
    dnames = ['Sine', 'Pulse', 'Spike']
    gthss = []
    bsthss = []
    gthpds = []
    bsthpds =[]
    dl = 4
    for od in ods:
        dwd = DWTP(od)
        coeffs = dwd.dwtdec(wtname='db4', delevel=dl)
        gths = []
        bsths = []
        for i in range(1, len(coeffs)):
            bthe = BestThEstimate(coeffs[i], thfunction='thf3', thp=2+2*i)
            thsa = ThSearchAlgorithm()
            gth = ThSelect(coeffs[i]).DonohoThEx()
            bsth = thsa.FibonacciSearch(bthe.msesurefuction, [0, 1.5 * gth], 0.001)
            gths.append(gth)
            bsths.append(bsth)
        gthss.append(gths)
        bsthss.append(bsths)

    for i in range(len(ods)):
        dwd = DWTP(ods[i])
        coeffs = dwd.dwtdec(wtname='db4', delevel=dl)
        gths = gthss[i]
        bsths = gthss[i]
        ncoeffs1 = dwd.thprocess2(coeffs, ths=gths, thf='thf3', thps=[2+2*k for k in range(dl)])
        ncoeffs2 = dwd.thprocess2(coeffs, ths=bsths, thf='thf3', thps=[2+2*k for k in range(dl)])
        gthpd = dwd.dwtrec(ncoeffs1, wtname='db4')
        bsthpd = dwd.dwtrec(ncoeffs2, wtname='db4')
        gthpds.append(gthpd)
        bsthpds.append(bsthpd)

    gthsnrs = []
    bsthsnrs = []
    gthmses = []
    bsthmses = []
    tds = [s.createSin(50, 60, 0), s.createPulse(50, 60, 0), s.createSpikes(0)]
    for i in range(len(tds)):
        gthdr = DenoiseRsult(tds[i], gthpds[i])
        bsthdr = DenoiseRsult(tds[i], bsthpds[i])
        gthsnrs.append(gthdr.snr())
        bsthsnrs.append(bsthdr.snr())
        gthmses.append(gthdr.mse())
        bsthmses.append(bsthdr.mse())
    print('gthsnrs = {0}'.format(gthsnrs))
    print('bsthsnrs = {0}'.format(bsthsnrs))
    print('gthmses = {0}'.format(gthmses))
    print('bsthmses = {0}'.format(bsthmses))

    x = [x for x in range(1000)]
    plt.figure()
    for i in range(len(ods)):
        plt.subplot(3, 2, 2 * i + 1)
        plt.title('{0} signal processed by gth'.format(dnames[i]))
        plt.plot(x, gthpds[i])
        plt.subplot(3, 2, 2 * i + 2)
        plt.title('{0} signal processed by bsth'.format(dnames[i]))
        plt.plot(x, bsthpds[i])
    plt.tight_layout()
    plt.show()

Experiment 1 with self-definitive signal/t1.7  processing by new threshold function with different parameter.py


# -*- coding: utf-8 -*-
from __future__ import absolute_import
import json
from time import time, sleep
from os import remove, getpid
from os.path import basename
from socket import gethostname
from setproctitle import setproctitle

def process_run(name, index):
    eval("process_%s(%s)" % (name, index))

def _checkActive(mongoMq, procKey):
    hostname = gethostname()
    procData = mongoMq['process_list'].find_one({"hostname":hostname, "title": procKey},{"_id":0})
    if procData:
        mongoMq['process_list'].find_and_modify({"hostname":hostname, "title": procKey},{"$set":{"processid": getpid()}})
    else:
        return False

def process_spider(index):
    '''蜘蛛'''
    mqkey = 'spider'
    procname = "spider-%s-%s" % (mqkey, index)
    setproctitle(procname)

    from common import mongoMq
    from utils import mq as Mq
    from business.crawler import crawl

    start = time()
    while True:
        #如果停止，退出程序
        if time() - start > 10:
            if not _checkActive(mongoMq, procname[7:]): exit()
            start = time()
        row = Mq.consume('spider')
        if not row:
            sleep(10)
            continue

        crawl(row)
        Mq.finish(row['id'], 'spider')

def process_mirror(index):
    '''镜像的进程'''
    mqkey = 'mirror'
    procname = "spider-%s-%s" % (mqkey, index)
    setproctitle(procname)
    from common import mongoMq
    from utils import mq as Mq
    import business.mirror as bMirror
    start = time()
    while True:
        #如果停止，退出程序
        if time() - start > 10:
            if not _checkActive(mongoMq, procname[7:]): exit()
            start = time()
        row = Mq.consume('mirror')
        if not row:
            sleep(10)
            continue
        bMirror.generate(row['id'])
        Mq.finish(row['id'], 'mirror')

def process_notify(index):
    '''蜘蛛'''
    mqkey = 'notify'
    procname = "spider-%s-%s" % (mqkey, index)
    setproctitle(procname)

    from common import mongoMq
    from utils import mq as Mq
    import business.notify as bNotify

    start = time()
    while True:
        #如果停止，退出程序
        if time() - start > 10:
            if not _checkActive(mongoMq, procname[7:]): exit()
            start = time()
        row = Mq.consume('notify')
        if not row:
            sleep(10)
            continue

        result = bNotify.send(row['id'])
        Mq.finish(row['id'], 'notify')

def process_piping(index):
    '''数据处理'''
    mqkey = 'piping'
    procname = "spider-%s-%s" % (mqkey, index)
    setproctitle(procname)

    from common import mongoMq
    from utils import mq as Mq
    import business.piping as bPiping

    start = time()
    while True:
        #如果停止，退出程序
        if time() - start > 10:
            if not _checkActive(mongoMq, procname[7:]): exit()
            start = time()
        row = Mq.consume('piping')
        if not row:
            sleep(10)
            continue
        bPiping.piping_all(row['id'])
        Mq.finish(row['id'], 'piping')

def process_snapshot(index):
    '''数据处理'''
    mqkey = 'snapshot'
    procname = "spider-%s-%s" % (mqkey, index)
    setproctitle(procname)

    from common import mongoMq
    from utils import mq as Mq
    from utils.logger import logger
    import business.snapshot as bSnapshot

    start = time()
    while True:
        #如果停止，退出程序
        if time() - start > 10:
            if not _checkActive(mongoMq, procname[7:]): exit()
            start = time()
        row = Mq.consume('snapshot')
        logger.debug("snapshot::::%s" % json.dumps(row))
        if not row:
            sleep(10)
            continue

        bSnapshot.generate(row)
        Mq.finish(row['id'], 'snapshot')

def process_darklink(index):
    '''数据处理'''
    mqkey = 'darklink'
    procname = "spider-%s-%s" % (mqkey, index)
    setproctitle(procname)

    from common import mongoMq
    from utils import mq as Mq

    start = time()
    while True:
        #如果停止，退出程序
        if time() - start > 10:
            if not _checkActive(mongoMq, procname[7:]): exit()
            start = time()
        row = Mq.consume('darklink')
        if not row:
            sleep(10)
            continue

        bSnapshot.generate(row)
        Mq.finish(row['id'], 'darklink')

def process_qiniu(index):
    '''快照图片压缩及上传到七牛
    此程序是守护进程，可start/stop/restart
    程序完成两件事：
    1.查找新生成的快照，压缩，移动到七牛上传图片的文件夹
    2.由七牛的程序将文件上传到七牛的服务器
    '''

    mqkey = 'qiniu'
    procname = "spider-%s-%s" % (mqkey, index)
    setproctitle(procname)

    from common import mongoMq
    from utils import mq as Mq
    from utils.logger import logger
    from utils.file import qiniu_upload
    from subprocess import Popen, PIPE, STDOUT
    from config.config import PATH_TMP_SNAPSHOT

    cmdFind = 'find %s -amin +1 -type f' % PATH_TMP_SNAPSHOT
    cmdCompress = 'pngquant -f --ext .png --quality 10 %s'
    start = time()
    while True:
        #如果停止，退出程序
        if time() - start > 10:
            if not _checkActive(mongoMq, procname[7:]): exit()
            start = time()
        child = Popen(cmdFind, shell=True, close_fds=True, bufsize=-1, stdout=PIPE, stderr=STDOUT)
        output = child.stdout.read().decode()
        output = output.strip()
        if not output: continue
        files = output.split("\n")
        for localfile in files:
            logger.info(cmdCompress % localfile)
            child = Popen(cmdCompress % localfile, shell=True, close_fds=True, bufsize=-1, stdout=PIPE, stderr=STDOUT)
            output = child.stdout.read().decode()
            key = basename(localfile)
            result = qiniu_upload(key, localfile)
            if result:
                logger.info(result)
                remove(localfile)
        sleep(5)

def process_ckready(index):
    '''
    将数据转入待处理状态
    '''
    mqkey = 'ckready'
    procname = "spider-%s-%s" % (mqkey, index)
    setproctitle(procname)

    from common import mongoMq
    from utils import mq as Mq

    start = time()
    while True:
        #如果停止，退出程序
        if time() - start > 10:
            if not _checkActive(mongoMq, procname[7:]): exit()
            start = time()
        Mq.ready('spider')
        Mq.ready('mirror')
        Mq.ready('piping')
        Mq.ready('notify')
        Mq.ready('snapshot')
        sleep(10)

def process_ckfinish(index):
    '''
    检查数据是否已处理完成
    '''
    mqkey = 'ckfinish'
    procname = "spider-%s-%s" % (mqkey, index)
    setproctitle(procname)

    from common import mongoMq
    from utils import mq as Mq
    import business.task as bTask

    start = time()
    while True:
        #如果停止，退出程序
        if time() - start > 10:
            if not _checkActive(mongoMq, procname[7:]): exit()
            start = time()
        bTask.execute_finish()
        sleep(10)

def process_ckcorrect(index):
    '''
    校正数据
    '''
    mqkey = 'ckcorrect'
    procname = "spider-%s-%s" % (mqkey, index)
    setproctitle(procname)

    from common import mongoMq
    from business.devops import mq_correct

    start = time()
    while True:
        #如果停止，退出程序
        if time() - start > 10:
            if not _checkActive(mongoMq, procname[7:]): exit()
            start = time()
        mq_correct()
        sleep(10)

def process_initexec(index):
    '''校正数据'''
    mqkey = 'initexec'
    procname = "spider-%s-%s" % (mqkey, index)
    setproctitle(procname)

    from common import db, mongoMq
    import business.task as bTask

    start = time()
    while True:
        #如果停止，退出程序
        if time() - start > 10:
            if not _checkActive(mongoMq, procname[7:]): exit()
            start = time()
        rows = db.fetchall("select id from task_execute where status=0 order by id asc");
        for row in rows: bTask.execute_init(row['id'])
        sleep(10)

def process_scheduler(index):
    '''校正数据'''
    mqkey = 'scheduler'
    procname = "spider-%s-%s" % (mqkey, index)
    setproctitle(procname)

    from common import mongoMq
    from aps import ApsCheckDb

    start = time()
    while True:
        #如果停止，退出程序
        if time() - start > 10:
            if not _checkActive(mongoMq, procname[7:]): exit()
            start = time()
        ApsCheckDb()
        sleep(10)


import cv2
import datetime
import time
from utils.motion import Movement
from utils.cameraTest import findMotion
from utils.CameraRawCapture import PiVideoStream
from utils.aws_utils import AWSPredator
from utils.CameraView import CameraView
from utils.fps import FPS

def camera_control(config):
    # Pi configuration and calibration
    movement = Movement()
    movement.calibrate()
    aws_predator = AWSPredator()
    video_stream = PiVideoStream(config).start()
    time.sleep(config["camera_warmup_time"])
    remember_frame = None
    start_time = None
    summary = None
    current_count = 0
    frame_count = 0
    found = False
    fps_counter = FPS()
    show_video = CameraView(config).start()
    while True:
        fps = fps_counter.fps()
        print(fps)
        image = video_stream.read_frame()

        if(current_count == 0):
            summary = None
        remember_frame, target, summary = findMotion(image, remember_frame, config,current_count,frame_count,summary,show_video)
        current_count += 1
        if target is not None:
            remember_frame = None
            start_time = None
            summary = None
            current_count = 0
            movement.laser_on()

            inBoundries = movement.move(target['angle_x'], target['angle_y'], multiplier=10)
            movement.laser_off()
            aws_predator.detected_movement(image)
            time.sleep(0.3)
            if inBoundries is False:
                movement.center()
                time.sleep(0.3)
            else:
                found = True
        elif found is True:
            if start_time is None:
                start_time = datetime.datetime.now()
            end_time = datetime.datetime.now()
            if (end_time - start_time).total_seconds() >= 1.5:
                print("Tracking failure detected")
            if (end_time - start_time).total_seconds() >= 5.0:
                movement.center()
                time.sleep(0.3)
                summary = None
                current_count = 0
                start_time = None
                remember_frame = None
                found = False
        current_count = current_count % (frame_count+1)
        show_video.show_image("Primary", image)
        key = cv2.waitKey(1) & 0xFF
        if key == ord("q"):
            break
    video_stream.stop()
    movement.clean_up()


#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""r2pipe

This module provides an API to interact with the radare2
commandline interface from Python using a pipe.

The pipe can be connected to the parent process to run
Python scripts from the radare2 shell itself, or it can
spawn a new process, connect via HTTP to a remote r2 http
server, etc.

Some r2 commands display the information in JSON, that's
why r2pipe provides `-j` methods to directly parse it
and return a native Python object.

Example:
  $ python
  > import r2pipe
  > r = r2pipe.open("/bin/ls")
  > print(r.cmd("pd 10"))
  > print(r.cmdj("aoj")[0]['size'])
  > r.quit()
"""

import os
import re
import sys
import time
import json
import fcntl
import socket
import urllib
from io import TextIOWrapper
from subprocess import Popen, PIPE
try:
        import r2lang
except:
        r2lang = None

try:
        from .native import RCore
        has_native = True
except:
        has_native = False

VERSION = "0.9.3"

if sys.version_info >= (3, 0):
        import urllib.request
        urlopen = urllib.request.urlopen
        import urllib.error
        URLError = urllib.error.URLError
else:
        import urllib2
        urlopen = urllib2.urlopen
        URLError = urllib2.URLError
if os.name == "nt":
        from ctypes import byref, c_ulong, create_string_buffer, windll
        GENERIC_READ = 0x80000000
        GENERIC_WRITE = 0x40000000
        OPEN_EXISTING = 0x3
        INVALID_HANDLE_VALUE = -1
        PIPE_READMODE_MESSAGE = 0x2
        ERROR_PIPE_BUSY = 231
        ERROR_MORE_DATA = 234
        BUFSIZE = 4096
        szPipename = "\\\\.\\pipe\\"
        chBuf = create_string_buffer(BUFSIZE)
        cbRead = c_ulong(0)
        cbWritten = c_ulong(0)

def version():
        """Return string with the version of the r2pipe library
        """
        return VERSION

def in_rlang():
        return r2lang is not None and r2lang.cmd is not None

class open:
        """Class representing an r2pipe connection with a running radare2 instance
        """
        def __init__(self, filename='', flags=[]):
                """Open a new r2 pipe
                The 'filename' can be one of the following:

                * absolute or relative path to file
                * http://<host>:<port>/cmd to connect to an r2 webserver
                * tcp://<host>:<port> to connect to an r2 tcp server
                * #!pipe when launching it from r2 via RLang.pipe

                Args:
                        filename (str): path to filename or uri
                        flags (list of str): arguments, either in comapct form
                                ("-wdn") or sepparated by commas ("-w","-d","-n")
                Returns:
                        Returns an object with methods to interact with r2 via commands
                """
                if not filename and in_rlang():
                        self._cmd = self._cmd_rlang
                        return
                try:
                        if os.name == "nt":
                                mypipename = os.environ['r2pipe_path']
                                while 1:
                                        hPipe = windll.kernel32.CreateFileA(szPipename + mypipename, GENERIC_READ | GENERIC_WRITE, 0, None, OPEN_EXISTING, 0, None)
                                        if (hPipe != INVALID_HANDLE_VALUE):
                                                break
                                        else:
                                                print("Invalid Handle Value")
                                        if (windll.kernel32.GetLastError() != ERROR_PIPE_BUSY):
                                                print("Could not open pipe")
                                                return
                                        elif ((windll.kernel32.WaitNamedPipeA(szPipename, 20000)) == 0):
                                                print("Could not open pipe\n")
                                                return
                                windll.kernel32.WriteFile(hPipe, "e scr.color=false\n", 18, byref(cbWritten), None)
                                windll.kernel32.ReadFile(hPipe, chBuf, BUFSIZE, byref(cbRead), None)
                                self.pipe = [hPipe, hPipe]
                                self._cmd = self._cmd_pipe
                        else:
                                self.pipe = [int(os.environ['R2PIPE_IN']), int(os.environ['R2PIPE_OUT'])]
                                self._cmd = self._cmd_pipe
                        self.url = "#!pipe"
                        return
                except:
                        pass
                if filename.startswith("#!pipe"):
                        raise Exception("ERROR: Cannot use #!pipe without R2PIPE_{IN|OUT} env")
                if filename.startswith("http"):
                        self._cmd = self._cmd_http
                        self.uri = filename + "/cmd"
                elif filename.startswith("ccall://"):
                        self._cmd = self._cmd_native
                        self.uri = filename[7:]
                elif filename.startswith("tcp"):
                        r = re.match(r'tcp://(\d+\.\d+.\d+.\d+):(\d+)/?', filename)
                        if not r:
                                raise Exception("String doesn't match tcp format")
                        self._cmd = self._cmd_tcp
                        self.conn = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                        self.conn.connect((r.group(1), int(r.group(2))))
                else:
                        self._cmd = self._cmd_process
                        cmd = ["radare2", "-q0", filename]
                        cmd = cmd[:1] + flags + cmd[1:]
                        try:
                                self.process = Popen(cmd, shell=False, stdin=PIPE, stdout=PIPE)
                        except:
                                raise Exception("ERROR: Cannot find radare2 in PATH")
                        self.process.stdout.read(1)  # Reads initial \x00
                        # make it non-blocking to speedup reading
                        self.nonblocking = True
                        if self.nonblocking:
                                fd = self.process.stdout.fileno()
                                fl = fcntl.fcntl(fd, fcntl.F_GETFL)
                                fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK)

        def _cmd_process(self, cmd):
                cmd = cmd.strip().replace("\n", ";")
                if sys.version_info >= (3, 0):
                        self.process.stdin.write(bytes(cmd + '\n', 'utf-8'))
                        # XXX: Use the TextIOWrapper or we can get stuck in an endless loop!
                        r = TextIOWrapper(self.process.stdout, encoding='utf8')
                else:
                        self.process.stdin.write(cmd + '\n')
                        r = self.process.stdout
                self.process.stdin.flush()
                out = ''
                while True:
                        if self.nonblocking:
                                try:
                                        foo = r.read(4096)
                                except:
                                        continue
                        else:
                                foo = r.read(1)
                        if len(foo) > 0 and foo[-1] == '\x00':
                                out += foo[0:-1]
                                break
                        out += foo
                return out

        def _cmd_tcp(self, cmd):
                res = b''
                self.conn.sendall(str.encode(cmd, 'utf-8'))
                data = self.conn.recv(512)
                while data:
                        res += data
                        data = self.conn.recv(512)
                return res.decode('utf-8')

        def _cmd_pipe(self, cmd):
                out = ''
                cmd = cmd.strip().replace("\n", ";")
                if os.name == "nt":
                        windll.kernel32.WriteFile(self.pipe[1], cmd, len(cmd), byref(cbWritten), None)
                        while True:
                                windll.kernel32.ReadFile(self.pipe[1], chBuf, BUFSIZE, byref(cbRead), None)
                                out += chBuf.value
                                if ord(chBuf[cbRead.value - 1]) == 0:
                                        out = out[0:-1]
                                        break
                else:
                        os.write(self.pipe[1], cmd)
                        while True:
                                res = os.read(self.pipe[0], 4096)
                                if res[-1] == b'\x00':
                                        res = res[0:-1]
                                if (len(res) < 1):
                                        break
                                out += res
                                if (len(res) < 4096):
                                        break
                return out.decode('utf-8')

        def _cmd_native(self, cmd):
                cmd = cmd.strip().replace("\n", ";")
                if not has_native:
                        raise Exception('No native ctypes connector available')
                if not hasattr(self, 'native'):
                        self.native = RCore()
                        self.native.cmd_str("o " + self.uri)
                return self.native.cmd_str(cmd)

        def _cmd_rlang(self, cmd):
                return r2lang.cmd(cmd)

        def _cmd_http(self, cmd):
                try:
                        try:
                                quocmd = urllib.parse.quote(cmd)
                        except:
                                quocmd = urllib.quote(cmd)
                        response = urlopen('{uri}/{cmd}'.format(uri=self.uri, cmd=quocmd))
                        return response.read().decode('utf-8')
                except URLError:
                        pass
                return None

        def quit(self):
                """Quit current r2pipe session and kill
                """
                self.cmd("q")
                if hasattr(self, 'process'):
                        self.process.stdin.flush()
                        self.process.terminate()
                        self.process.wait()

        # r2 commands
        def cmd(self, cmd):
                """Run an r2 command return string with result
                Args:
                        cmd (str): r2 command
                Returns:
                        Returns an string with the results of the command
                """
                res = self._cmd(cmd)
                if res is not None:
                        return res.strip()
                return None

        def cmdj(self, cmd):
                """Same as cmd() but evaluates JSONs and returns an object
                Args:
                        cmd (str): r2 command
                Returns:
                        Returns a Python object respresenting the parsed JSON
                """
                try:
                        data = json.loads(self.cmd(cmd).replace('\n', ''))
                except (ValueError, KeyError, TypeError) as e:
                        sys.stderr.write("r2pipe.cmdj.Error: %s\n" % (e))
                        data = None
                return data

        def syscmd(self, cmd):
                """Executes a program and returns the output (stdout only)
                Args:
                        cmd (str): commandline shell command
                Returns:
                        Returns a string with the output
                """
                p = Popen(cmd, shell=True, stdin=PIPE, stdout=PIPE)
                out, err = p.communicate()
                return out

        def syscmdj(self, cmd):
                """Executes a program and returns an object representing the parsed JSON of the output
                Args:
                        cmd (str): commandline shell command
                Returns:
                        Returns an object constructed by parsing the JSON returned by the command
                """
                try:
                        data = json.loads(self.syscmd(cmd))
                except (ValueError, KeyError, TypeError) as e:
                        sys.stderr.write("r2pipe.syscmdj.Error %s\n" % (e))
                        data = None
                return data

# Hello World
if __name__ == "__main__":
        print("[+] Spawning r2 tcp and http servers")
        os.system("pkill r2")
        os.system("r2 -qc.:9080 /bin/ls &")
        os.system("r2 -qc=h /bin/ls &")
        time.sleep(1)
        # Test r2pipe with local process
        print("[+] Testing python r2pipe local")
        rlocal = open("/bin/ls")
        print(rlocal.cmd("pi 5"))
        # print rlocal.cmd("pn")
        info = rlocal.cmdj("ij")
        print("Architecture: " + info['bin']['machine'])

        # Test r2pipe with remote tcp process (launch it with "r2 -qc.:9080 myfile")
        print("[+] Testing python r2pipe tcp://")
        rremote = open("tcp://127.0.0.1:9080")
        disas = rremote.cmd("pi 5")
        if not disas:
                print("Error with remote tcp conection")
        else:
                print(disas)

        # Test r2pipe with remote http process (launch it with "r2 -qc=H myfile")
        print("[+] Testing python r2pipe http://")
        rremote = open("http://127.0.0.1:9090")
        disas = rremote.cmd("pi 5")
        if not disas:
                print("Error with remote http conection")
        else:
                print(disas)
        os.system("pkill -INT r2")


# coding: utf-8

"""
    Yapily API

    To access endpoints that require authentication, use your application key and secret created in the Dashboard (https://dashboard.yapily.com)  # noqa: E501

    OpenAPI spec version: 0.0.155

    Generated by: https://github.com/swagger-api/swagger-codegen.git
"""

import pprint
import re  # noqa: F401

import six

from yapily.models.account_identification import AccountIdentification  # noqa: F401,E501
from yapily.models.amount import Amount  # noqa: F401,E501
from yapily.models.payee import Payee  # noqa: F401,E501

class PaymentRequest(object):
    """NOTE: This class is auto generated by the swagger code generator program.

    Do not edit the class manually.
    """

    """
    Attributes:
      swagger_types (dict): The key is attribute name
                            and the value is attribute type.
      attribute_map (dict): The key is attribute name
                            and the value is json key in definition.
    """
    swagger_types = {
        'payment_idempotency_id': 'str',
        'payer_account_identifications': 'list[AccountIdentification]',
        'amount': 'Amount',
        'reference': 'str',
        'context_type': 'str',
        'type': 'str',
        'payment_date_time': 'datetime',
        'payee': 'Payee'
    }

    attribute_map = {
        'payment_idempotency_id': 'paymentIdempotencyId',
        'payer_account_identifications': 'payerAccountIdentifications',
        'amount': 'amount',
        'reference': 'reference',
        'context_type': 'contextType',
        'type': 'type',
        'payment_date_time': 'paymentDateTime',
        'payee': 'payee'
    }

    def __init__(self, payment_idempotency_id=None, payer_account_identifications=None, amount=None, reference=None, context_type=None, type=None, payment_date_time=None, payee=None):  # noqa: E501
        """PaymentRequest - a model defined in Swagger"""  # noqa: E501

        self._payment_idempotency_id = None
        self._payer_account_identifications = None
        self._amount = None
        self._reference = None
        self._context_type = None
        self._type = None
        self._payment_date_time = None
        self._payee = None
        self.discriminator = None

        self.payment_idempotency_id = payment_idempotency_id
        if payer_account_identifications is not None:
            self.payer_account_identifications = payer_account_identifications
        if amount is not None:
            self.amount = amount
        if reference is not None:
            self.reference = reference
        if context_type is not None:
            self.context_type = context_type
        if type is not None:
            self.type = type
        if payment_date_time is not None:
            self.payment_date_time = payment_date_time
        self.payee = payee

    @property
    def payment_idempotency_id(self):
        """Gets the payment_idempotency_id of this PaymentRequest.  # noqa: E501

        :return: The payment_idempotency_id of this PaymentRequest.  # noqa: E501
        :rtype: str
        """
        return self._payment_idempotency_id

    @payment_idempotency_id.setter
    def payment_idempotency_id(self, payment_idempotency_id):
        """Sets the payment_idempotency_id of this PaymentRequest.

        :param payment_idempotency_id: The payment_idempotency_id of this PaymentRequest.  # noqa: E501
        :type: str
        """
        if payment_idempotency_id is None:
            raise ValueError("Invalid value for `payment_idempotency_id`, must not be `None`")  # noqa: E501

        self._payment_idempotency_id = payment_idempotency_id

    @property
    def payer_account_identifications(self):
        """Gets the payer_account_identifications of this PaymentRequest.  # noqa: E501

        :return: The payer_account_identifications of this PaymentRequest.  # noqa: E501
        :rtype: list[AccountIdentification]
        """
        return self._payer_account_identifications

    @payer_account_identifications.setter
    def payer_account_identifications(self, payer_account_identifications):
        """Sets the payer_account_identifications of this PaymentRequest.

        :param payer_account_identifications: The payer_account_identifications of this PaymentRequest.  # noqa: E501
        :type: list[AccountIdentification]
        """

        self._payer_account_identifications = payer_account_identifications

    @property
    def amount(self):
        """Gets the amount of this PaymentRequest.  # noqa: E501

        :return: The amount of this PaymentRequest.  # noqa: E501
        :rtype: Amount
        """
        return self._amount

    @amount.setter
    def amount(self, amount):
        """Sets the amount of this PaymentRequest.

        :param amount: The amount of this PaymentRequest.  # noqa: E501
        :type: Amount
        """

        self._amount = amount

    @property
    def reference(self):
        """Gets the reference of this PaymentRequest.  # noqa: E501

        :return: The reference of this PaymentRequest.  # noqa: E501
        :rtype: str
        """
        return self._reference

    @reference.setter
    def reference(self, reference):
        """Sets the reference of this PaymentRequest.

        :param reference: The reference of this PaymentRequest.  # noqa: E501
        :type: str
        """

        self._reference = reference

    @property
    def context_type(self):
        """Gets the context_type of this PaymentRequest.  # noqa: E501

        :return: The context_type of this PaymentRequest.  # noqa: E501
        :rtype: str
        """
        return self._context_type

    @context_type.setter
    def context_type(self, context_type):
        """Sets the context_type of this PaymentRequest.

        :param context_type: The context_type of this PaymentRequest.  # noqa: E501
        :type: str
        """
        allowed_values = ["BILL", "GOODS", "SERVICES", "OTHER", "PERSON_TO_PERSON"]  # noqa: E501
        if context_type not in allowed_values:
            raise ValueError(
                "Invalid value for `context_type` ({0}), must be one of {1}"  # noqa: E501
                .format(context_type, allowed_values)
            )

        self._context_type = context_type

    @property
    def type(self):
        """Gets the type of this PaymentRequest.  # noqa: E501

        :return: The type of this PaymentRequest.  # noqa: E501
        :rtype: str
        """
        return self._type

    @type.setter
    def type(self, type):
        """Sets the type of this PaymentRequest.

        :param type: The type of this PaymentRequest.  # noqa: E501
        :type: str
        """
        allowed_values = ["DOMESTIC_PAYMENT", "DOMESTIC_VARIABLE_RECURRING_PAYMENT", "DOMESTIC_SCHEDULED_PAYMENT"]  # noqa: E501
        if type not in allowed_values:
            raise ValueError(
                "Invalid value for `type` ({0}), must be one of {1}"  # noqa: E501
                .format(type, allowed_values)
            )

        self._type = type

    @property
    def payment_date_time(self):
        """Gets the payment_date_time of this PaymentRequest.  # noqa: E501

        :return: The payment_date_time of this PaymentRequest.  # noqa: E501
        :rtype: datetime
        """
        return self._payment_date_time

    @payment_date_time.setter
    def payment_date_time(self, payment_date_time):
        """Sets the payment_date_time of this PaymentRequest.

        :param payment_date_time: The payment_date_time of this PaymentRequest.  # noqa: E501
        :type: datetime
        """

        self._payment_date_time = payment_date_time

    @property
    def payee(self):
        """Gets the payee of this PaymentRequest.  # noqa: E501

        :return: The payee of this PaymentRequest.  # noqa: E501
        :rtype: Payee
        """
        return self._payee

    @payee.setter
    def payee(self, payee):
        """Sets the payee of this PaymentRequest.

        :param payee: The payee of this PaymentRequest.  # noqa: E501
        :type: Payee
        """
        if payee is None:
            raise ValueError("Invalid value for `payee`, must not be `None`")  # noqa: E501

        self._payee = payee

    def to_dict(self):
        """Returns the model properties as a dict"""
        result = {}

        for attr, _ in six.iteritems(self.swagger_types):
            value = getattr(self, attr)
            if isinstance(value, list):
                result[attr] = list(map(
                    lambda x: x.to_dict() if hasattr(x, "to_dict") else x,
                    value
                ))
            elif hasattr(value, "to_dict"):
                result[attr] = value.to_dict()
            elif isinstance(value, dict):
                result[attr] = dict(map(
                    lambda item: (item[0], item[1].to_dict())
                    if hasattr(item[1], "to_dict") else item,
                    value.items()
                ))
            else:
                result[attr] = value

        return result

    def to_str(self):
        """Returns the string representation of the model"""
        return pprint.pformat(self.to_dict())

    def __repr__(self):
        """For `print` and `pprint`"""
        return self.to_str()

    def __eq__(self, other):
        """Returns true if both objects are equal"""
        if not isinstance(other, PaymentRequest):
            return False

        return self.__dict__ == other.__dict__

    def __ne__(self, other):
        """Returns true if both objects are not equal"""
        return not self == other


from flask import Flask, request, jsonify
from pprint import pprint
import json, os

app = Flask(__name__)

@app.route('/webhooks/inbound-sms', methods=['GET', 'POST'])
def inbound_sms():
    if request.is_json:
        pprint(request.get_json())
    else:
        data = dict(request.form) or dict(request.args)
        with open('response.json', 'w') as outfile:
            json.dump(data, outfile)
        os.system("python3 execute.py")
        pprint(data)
    return ('', 204)
app.run(port=3000)


import xml.etree.ElementTree as ET
from os import listdir
from os.path import isfile, join

shapes = ['capsule', 'diamond', 'freeform', 'hexagon', 'octagon', 'oval', 'pentagon',
          'rectangle', 'round', 'semi-circle', 'square', 'tear', 'trapezoid', 'triangle']
root_folder = 'images/full/'

chars_b = [chr(l) for l in range(65,91)]
chars_s = [chr(l) for l in range(97,123)]
nums = [str(l) for l in range(0,10)]
sp = ['-',',','(',')',':','+','.','/']

letters = {l:0 for l in chars_b}
for l in nums: letters[l]=0
for l in chars_s: letters[l]=0
for l in sp: letters[l]=0

for shape in shapes:
    files = [root_folder+shape+'/annotations/'+f for f in listdir(root_folder+shape+'/annotations/') if (isfile(join(root_folder+shape+'/annotations/', f)) and '.xml' in f)]
    for file in files:
        tree = ET.parse(file)
        root = tree.getroot()
        # print(root)
        for child in root:
            if child.tag == 'object':
                name = child[0].text.strip()
                # print(file)
                letters[name] += 1

output = ''
chars_b_count = [(l,letters[l]) for l in letters if l in chars_b]
chars_s_count = [(l,letters[l]) for l in letters if l in chars_s]
nums_count = [(l,letters[l]) for l in letters if l in nums]
sp_count = [(l,letters[l]) for l in letters if l in sp]

chars_b_count.sort(key=lambda x:x[1], reverse=True)
chars_s_count.sort(key=lambda x:x[1], reverse=True)
nums_count.sort(key=lambda x:x[1], reverse=True)
sp_count.sort(key=lambda x:x[1], reverse=True)

for a in chars_b_count: output += str(a[0]) + ':' + str(a[1]) + '\n'
output += '\n'
for a in chars_s_count: output += str(a[0]) + ':' + str(a[1]) + '\n'
output += '\n'
for a in nums_count: output += str(a[0]) + ':' + str(a[1]) + '\n'
output += '\n'
for a in sp_count: output += str(a[0]) + ':' + str(a[1]) + '\n'

file_write = open('all_letters_xml2.txt', 'w')
file_write.write(output)


import pyperclip
import webbrowser

dayType = input('Good morning, Josh! \nIs today a Schoolday, Workday, or Weekend?').lower()

workdayTasks = {
    'Prosser': '7:55am-10:35am',
    'Chick-Fil-A': '12:00pm-8:00pm'
    }
schooldayTasks = {
    'Prosser': '7:55am-10:35am',
    'Psychology 101': '1:00pm-2:15pm',
    'English 111': '2:30pm-3:45pm'
    }
weekendTasks = {}
adding = True
while adding:
    print('Your current tasks include: \n')

    if dayType == 'workday':
        for task, time in workdayTasks.items():
            print(task, time)
    elif dayType == 'schoolday':
        for task, time in schooldayTasks.items():
            print(task, time)
    elif dayType == 'weekend':
        for task, time in weekendTasks.items():
            print(task, time)

    cont = input('\nAre there any other tasks you would like to add?').lower()

    if cont == 'yes' or cont == 'y':
        newTask = input('Which task would you like to add?')
        newTime = input('What time period will ' + newTask + ' occupy?')

        if dayType == 'workday':
            workdayTasks[newTask] = newTime
        elif dayType == 'schoolday':
            schooldayTasks[newTask] = newTime
        elif dayType == 'weekend':
            weekendTasks[newTask] = newTime

    elif cont == 'no' or cont == 'n':
        adding = False

        copy = input('Do you want to copy your schedule to your clipboard?').lower()
        if copy == 'yes' or copy == 'y':
            if dayType == 'workday':
                clipboard = str(workdayTasks)
            elif dayType == 'schoolday':
                clipboard = str(schooldayTasks)
            elif dayType == 'weekend':
                clipboard = str(weekendTasks)

            censor = '{\'}'
            for char in censor:
                clipboard = clipboard.replace(char, '')
                clipboard = clipboard.replace(',', '\r\n')
                pyperclip.copy(clipboard)

        keep = input('Would you like to open Google Keep to Export your schedule?').lower()
        if keep == 'yes' or keep == 'y':
            print('Done. Have a nice day!')
            webbrowser.open('https://keep.google.com/')

        elif keep == 'no' or keep == 'n':
            print('Have a nice day!')

        else:
            print('Please respond with \'Yes\' or \'No.\'')