import tkinter as tk
try:
    import pygame
except ImportError:
    audio = None
else:
    audio = True
import sys
import random
import time

### Stopped Let's code: Tetris episode 19 by TigerhawkT3 at 00:58:42
### Use score_lines or high_score_lines to increase level and speed etc.

class Shape:
    def __init__(self, shape, key, piece, row, column, coords):
        self.shape = shape
        self.key = key
        self.piece = piece
        self._row = row
        self.kicked = False
        self._rotation_index = 0
        self.column = column
        self.coords = coords
        self.hover_time = self.spin_time = time.perf_counter()
    @property
    def row(self):
        return self._row
    @row.setter
    def row(self, x):
        if x != self._row and not self.kicked:
            self._row = x
            self.hover_time = time.perf_counter()
    @property
    def rotation_index(self):
        return self._rotation_index
    @rotation_index.setter
    def rotation_index(self, x):
        self._rotation_index = x
        self.spin_time = time.perf_counter()
    @property
    def hover(self):
        return time.perf_counter() - self.hover_time < 0.5
    @property
    def spin(self):
        return time.perf_counter() - self.spin_time < 0.5

class Tetris:
    def __init__(self, parent, audio):
        self.debug = 'debug' in sys.argv[1:]
        self.random = 'random' in sys.argv[1:]
        self.hover = 'nohover' not in sys.argv[1:]
        self.spin = 'spin' in sys.argv[1:]
        self.kick = 'kick' in sys.argv[1:]
        parent.title('Pythris')
        self.parent = parent
        self.audio = audio
        if self.audio:
            pygame.mixer.init(buffer=512)
            try:
                self.sounds = {name: pygame.mixer.Sound(name) for name in ('music.ogg',
                                                                           'settle.ogg',
                                                                           'clear.ogg',
                                                                           'lose.ogg')}
            except pygame.error as err:
                self.audio = None
                print(err)
            else:
                self.audio = {'m': True, 'e': True}
                for char in 'mMeE':
                    self.parent.bind(char, self.toggle_audio)
                self.sounds['music.ogg'].play(loops=-1)
        self.board_width = 10
        self.board_height = 24
        self.high_score = 0
        self.high_score_lines = 0
        self.width = 200
        self.height = 480
        self.square_width = self.width//10
        self.max_speed_score = 5000
        self.speed_factor = 250
        self.shapes = {'S':[['*', ''],
                            ['*', '*'],
                            ['', '*']],
                       'Z':[['', '*'],
                            ['*', '*'],
                            ['*', '']],
                       'J':[['*', '*'],
                            ['*', ''],
                            ['*', '']],
                       'L':[['*', ''],
                            ['*', ''],
                            ['*', '*']],
                       'O':[['*', '*'],
                            ['*', '*']],
                       'I':[['*'],
                            ['*'],
                            ['*'],
                            ['*']],
                       'T':[['*', '*', '*'],
                            ['', '*', '']]
                      }
        self.colours = {'S': '#6495ED',
                        'Z': '#F08080',
                        'J': '#B0C4DE',
                        'L': '#FFDAB9',
                        'O': '#DB7093',
                        'I': '#BA55D3',
                        'T': '#40E0D0'}

        for key in ('<Down>', '<Left>', '<Right>'):
            self.parent.bind(key, self.shift)

        self.parent.bind('<Up>', self.rotate)

        for key in ('a', 'A', 'd', 'D', 's', 'S'):
            self.parent.bind(key, self.snap)

        self.parent.bind('<Escape>', self.pause)

        for key in ('<Control-n>', '<Control-N>'):
            self.parent.bind(key, self.draw_board)

        for key in ('g', 'G'):
            self.parent.bind(key, self.toggle_guides)

        self.canvas = None
        self.preview_canvas = None
        self.ticking = None
        self.spawning = None
        self.guide_fill = ''
        self.score_var = tk.StringVar()
        self.score_label = tk.Label(ROOT,
                                    textvariable=self.score_var,
                                    width=25,
                                    height=5,
                                    font=('Helvetica', 12))
        self.score_label.grid(row=2, column=1, sticky="S")
        self.high_score_var = tk.StringVar()
        self.high_score_var.set('High Score:\n0 (0)')
        self.high_score_label = tk.Label(ROOT,
                                         textvariable=self.high_score_var,
                                         width=25,
                                         height=5,
                                         font=('Helvetica', 12))
        self.high_score_label.grid(row=3, column=1, sticky="N")
        self.preview_label = tk.Label(ROOT,
                                      text='Next Piece',
                                      width=25,
                                      height=5,
                                      font=('Helvetica', 12))
        self.preview_label.grid(row=0, column=1, sticky="S")
        self.draw_board()

    def tick(self):
        if self.piece_is_active and not (self.spin and self.active_piece.spin):
            self.shift()
        self.ticking = self.parent.after(self.tickrate, self.tick)

    def shift(self, event=None):
        if not self.piece_is_active:
            return
        r = self.active_piece.row
        c = self.active_piece.column
        l = len(self.active_piece.shape)
        w = len(self.active_piece.shape[0])
        direction = (event and event.keysym) or 'Down'
        # use event-keysym to check event/direction
        if direction == 'Down':
            rt = r+1  # row temporary
            ct = c  # column temporary

        elif direction == 'Left':
            rt = r
            ct = c-1
        elif direction == 'Right':
            rt = r
            ct = c+1

        success = self.check_and_move(self.active_piece.shape, rt, ct, l, w)

        if direction in 'Down' and not success and not (self.hover and self.active_piece.hover):
            self.settle()

    def draw_board(self, event=None):
        if self.ticking:
            self.parent.after_cancel(self.ticking)
        if self.spawning:
            self.parent.after_cancel(self.spawning)
        self.score_var.set('Score:\n0')
        self.board = [['' for column in range(self.board_width)]
                      for row in range(self.board_height)]
        self.field = [[None for column in range(self.board_width)] for row in range(self.board_height)]
        if self.canvas:
            self.canvas.destroy()
        self.canvas = tk.Canvas(ROOT, width=self.width, height=self.height)
        self.canvas.grid(row=0, column=0, rowspan=4)
        self.border = self.canvas.create_rectangle(2,
                                                   2,
                                                   self.width - 2,
                                                   self.height - 2,
                                                   width=2)
        self.h_separator = self.canvas.create_line(0,
                                                   self.height//6,
                                                   self.width,
                                                   self.height//6,
                                                   width=2)
        self.v_separator = self.canvas.create_line(self.width,
                                                   0,
                                                   self.width,
                                                   self.height,
                                                   width=2)
        if self.preview_canvas:
            self.preview_canvas.destroy()
        self.preview_canvas = tk.Canvas(ROOT,
                                        width=5*self.square_width,
                                        height=5*self.square_width)
        self.preview_canvas.grid(row=1, column=1)
        self.tickrate = 1000
        self.score = 0
        self.score_lines = 0
        self.piece_is_active = False
        self.paused = False
        self.bag = []
        self.preview()
        self.guides = [self.canvas.create_line(0, 0, 0, self.height),
                       self.canvas.create_line(0, 0, self.width, self.height)]
        self.spawning = self.parent.after(self.tickrate, self.spawn)
        self.ticking = self.parent.after(self.tickrate*2, self.tick)

    def toggle_guides(self, event=None):
        self.guide_fill = '' if self.guide_fill else 'black'
        self.canvas.itemconfig(self.guides[0], fill=self.guide_fill)
        self.canvas.itemconfig(self.guides[1], fill=self.guide_fill)

    def toggle_audio(self, event=None):
        if not event:
            return
        key = event.keysym.lower()
        self.audio[key] = not self.audio[key]
        if key == 'm':
            if not self.audio['m']:
                self.sounds['music.ogg'].stop()
            else:
                self.sounds['music.ogg'].play(loops=-1)

    def pause(self, event=None):
        if self.piece_is_active and not self.paused:
            self.paused = True
            self.piece_is_active = False
            self.parent.after_cancel(self.ticking)
        elif self.paused:
            self.paused = False
            self.piece_is_active = True
            self.ticking = self.parent.after(self.tickrate, self.tick)

    def print_board(self):
        for row in self.board:
            print(*(cell or ' ' for cell in row))

    def check(self, shape, r, c, l, w):
        for row, squares in zip(range(r, r+l), shape):
            for column, square in zip(range(c, c+w), squares):
                if ((row not in range(self.board_height))
                        or (column not in range(self.board_width))
                        or (square and self.board[row][column] == 'x')):
                    return
        return True

    def move(self, shape, r, c, l, w):
        square_idxs = iter(range(4))

        for row in self.board:
            row[:] = ['' if cell == '*' else cell for cell in row]

        for row, squares in zip(range(r, r+l), shape):
            for column, square in zip(range(c, c+w), squares):
                if square:
                    self.board[row][column] = square
                    square_idx = next(square_idxs)
                    coord = (column*self.square_width,
                             row*self.square_width,
                             (column+1)*self.square_width,
                             (row+1)*self.square_width)
                    self.active_piece.coords[square_idx] = coord
                    self.canvas.coords(self.active_piece.piece[square_idx], coord)
        self.active_piece.row = r
        self.active_piece.column = c
        self.active_piece.shape = shape
        self.move_guides(c, (c+w))
        if self.debug:
            self.print_board()
        return True

    def check_and_move(self, shape, r, c, l, w):
        return self.check(shape, r, c, l, w) and self.move(shape, r, c, l, w)

    def rotate(self, event=None):
        if not self.active_piece:
            return
        if len(self.active_piece.shape) == len(self.active_piece.shape[0]):
            self.active_piece.rotation_index = self.active_piece.rotation_index
            return
        r = self.active_piece.row
        c = self.active_piece.column
        l = len(self.active_piece.shape)
        w = len(self.active_piece.shape[0])
        x = c + w//2
        y = r + l//2
        direction = event.keysym
        '''if direction in ('a', 'A'):  # left
            shape = rotate_array(self.active_piece.shape, -90)
            rotation_index = (self.active_piece.rotation_index - 1) % 4
            ra, rb = self.active_piece.rotation[rotation_index]
            rotation_offsets = -ra, -rb
        else:  # right'''
        shape = rotate_array(self.active_piece.shape, 90)
        rotation_index = self.active_piece.rotation_index
        rotation_offsets = self.active_piece.rotation[rotation_index]
        rotation_index = (rotation_index + 1) % 4

        l = len(shape)
        w = len(shape[0])
        rt = y - l//2
        ct = x - w//2
        x_correction, y_correction = rotation_offsets
        rt += y_correction
        ct += x_correction

        if self.check_and_move(shape, rt, ct, l, w):
            self.active_piece.rotation_index = rotation_index
            if self.active_piece.kicked:
                self.snap()
            return

        if self.kick:
            for a, b in zip((0, 0, -1, 0, 0, -2, -1, -1, -1, -1, -2, -2, -2, -2),
                            (-1, 1, 0, -2, 2, 0, -1, 1, -2, 2, -1, 1, -2, 2)):
                    if self.check_and_move(shape, rt+a, ct+b, l, w):
                        self.active_piece.rotation_index = rotation_index
                        if not self.active_piece.kicked:
                            self.active_piece.kicked = a
                        if self.active_piece.kicked and not a:
                            self.snap()
                        return

    def settle(self):
        self.piece_is_active = False

        for row in self.board:
            row[:] = ['x' if cell == '*' else cell for cell in row]

        if self.debug:
            self.print_board()

        for (x1, y1, x2, y2), id in zip(self.active_piece.coords, self.active_piece.piece):
            self.field[y1//self.square_width][x1//self.square_width] = id

        indices = [idx for idx, row in enumerate(self.board) if all(row)]
        if indices:
            self.score += (40, 100, 300, 1200)[len(indices) - 1]
            self.score_lines += len(indices)
            self.clear(indices)
            if all(not cell for row in self.board for cell in row):
                self.score += 2000
            self.high_score = max(self.score, self.high_score)
            self.high_score_lines = max(self.score_lines, self.high_score_lines)
            self.score_var.set(f"Score:\n{self.score} ({self.score_lines})")
            self.high_score_var.set(f"High Score:\n{self.high_score} ({self.high_score_lines})")
            if self.score < self.max_speed_score:
                self.tickrate = 1000 // (self.score//self.speed_factor + 1)
        if any(any(row) for row in self.board[:4]):
            self.lose()
            return
        if self.audio['e'] and not indices:
            self.sounds['settle.ogg'].play()
        self.spawning = self.parent.after(500 if indices and self.tickrate < 500 else self.tickrate, self.spawn)

    def preview(self):
        self.preview_canvas.delete(tk.ALL)
        if not self.bag:
            if self.random:
                self.bag.append(random.choice('IJLOSTZ'))
            else:
                self.bag = random.sample('IJLOSTZ', 7)

        key = self.bag.pop()

        shape = rotate_array(self.shapes[key], random.choice((0, 90, 180, 270)))
        self.preview_piece = Shape(shape, key, [], 0, 0, [])
        width = len(shape[0])
        half = self.square_width//2

        for y, row in enumerate(shape):
            for x, cell in enumerate(row):
                if cell:
                    self.preview_piece.coords.append((self.square_width*x + half,
                                                      self.square_width*y + half,
                                                      self.square_width*(x+1) + half,
                                                      self.square_width*(y+1) + half))
                    self.preview_piece.piece.append(self.preview_canvas.create_rectangle(self.preview_piece.coords[-1],
                                                                                fill=self.colours[key],
                                                                                width=2))
        self.preview_piece.rotation_index = 0
        self.preview_piece.i_nudge = (len(shape) < len(shape[0])) and 4 in (len(shape), len(shape[0]))
        self.preview_piece.row = self.preview_piece.i_nudge
        if 3 in (len(shape), len(shape[0])):
            self.preview_piece.rotation = [(0, 0),
                                          (1, 0),
                                          (-1, 1),
                                          (0, -1)]
        else:
            self.preview_piece.rotation = [(1, -1),
                                          (0, 1),
                                          (0, 0),
                                          (-1, 0)]
        if len(shape) < len(shape[0]):
            self.preview_piece.rotation_index += 1

    def move_guides(self, left, right):
        self.canvas.coords(self.guides[0], left*self.square_width, 0, left*self.square_width, self.height)
        self.canvas.coords(self.guides[1], right*self.square_width, 0, right*self.square_width, self.height)

    def spawn(self):
        self.piece_is_active = True
        self.active_piece = self.preview_piece
        self.preview()
        width = len(self.active_piece.shape[0])
        start = (10-width)//2
        self.active_piece.column = start
        self.active_piece.start = start
        self.active_piece.coords = []
        self.active_piece.piece = []
        for y, row in enumerate(self.active_piece.shape):
            self.board[y+self.active_piece.i_nudge][start:start+width] = self.active_piece.shape[y]
            for x, cell in enumerate(row, start=start):
                if cell:
                    self.active_piece.coords.append((self.square_width*x,
                                                     self.square_width*(y+self.active_piece.i_nudge),
                                                     self.square_width*(x+1),
                                                     self.square_width*(y+self.active_piece.i_nudge+1)))
                    self.active_piece.piece.append(self.canvas.create_rectangle(self.active_piece.coords[-1],
                                                                                fill=self.colours[self.active_piece.key],
                                                                                width=2))
        self.move_guides(start, (start+width))
        if self.debug:
            self.print_board()

    def lose(self):
        self.piece_is_active = False
        if self.audio['e']:
            self.sounds['lose.ogg'].play()
        self.parent.after_cancel(self.ticking)
        self.parent.after_cancel(self.spawning)
        self.clear_iter(range(len(self.board)))

    def snap(self, event=None):
        down = {'s', 'S'}
        left = {'a', 'A'}
        right = {'d', 'D'}
        if not self.piece_is_active:
            return
        r = self.active_piece.row
        c = self.active_piece.column
        l = len(self.active_piece.shape)
        w = len(self.active_piece.shape[0])

        direction = event.keysym if event is not None else 's'

        while 1:
            if self.check(self.active_piece.shape,
                            r+(direction in down),
                            c + (direction in right) - (direction in left),
                            l,
                            w):
                r += direction in down
                c += (direction in right) - (direction in left)
            else:
                break
        self.move(self.active_piece.shape, r, c, l, w)
        if direction in down:
            self.settle()

    def clear(self, indices):
        if self.audio['e']:
            self.sounds['clear.ogg'].play()
        for idx in indices:
            self.board.pop(idx)
            self.board.insert(0, ['' for column in range(self.board_width)])
        self.clear_iter(indices)

    def clear_iter(self, indices, current_column=0):
        for row in indices:
            if row%2:
                cc = current_column
            else:
                cc = self.board_width - current_column - 1
            id = self.field[row][cc]
            self.field[row][cc] = None
            self.canvas.delete(id)
        if current_column < self.board_width-1:
            self.parent.after(50, self.clear_iter, indices, current_column+1)
        else:
            for idx, row in enumerate(self.field):
                offset = sum(r > idx for r in indices)*self.square_width
                for square in row:
                    if square:
                        self.canvas.move(square, 0, offset)
            for row in indices:
                self.field.pop(row)
                self.field.insert(0, [None for x in range(self.board_width)])

def rotate_array(array, angle, wide=False):
    '''
    Rotates a rectangular or diamond 2D array in increments of 45 degrees.
    Parameters:
        array (list): a list containing sliceable sequences, such as list, tuple, or str
        angle (int): a positive angle for rotation, in 45-degree increments.
        wide (bool): whether a passed diamond array should rotate into a wide array
            instead of a tall one (tall is the default). No effect on square matrices.
    '''
    angle = angle%360
    if angle < 1:
        return [list(row) for row in array]
    lengths = list(map(len, array))
    rect = len(set(lengths)) == 1
    width = max(lengths)
    height = sum(lengths)/width
    if wide:
        width, height = height, width
    if not rect:
        array = [list(row) for row in array]
        array = [[array[row+col].pop() for row in range(width)] for col in range(height)]
        angle += 45
    nineties, more = divmod(angle, 90)
    if nineties == 3:
        array = list(zip(*array))[::-1]
    else:
        for i in range(nineties):
            array = list(zip(*array[::-1]))
    if more:
        ab = abs(len(array)-len(array[0]))
        m = min(len(array), len(array[0]))
        tall = len(array) > len(array[0])
        array = [[array[r][c] for r,c in zip(range(row-1, -1, -1), range(row))
                 ] for row in range(1, m+1)
           ] + [[array[r][c] for r,c in zip(range(m-1+row*tall, row*tall-1, -1),
                                            range(row*(not tall), m+row*(not tall)+1))
                ] for row in range(1, ab+(not tall))
           ] + [[array[r][c] for r,c in zip(range(len(array)-1, ab*tall+row-1, -1),
                                            range(ab*(not tall)+row, len(array[0])+(not tall)))
                ] for row in range((not tall), m)
           ]
    return array

ROOT = tk.Tk()
TETRIS = Tetris(ROOT, audio)
ROOT.mainloop()


import glob
import re

from test_framework.util import (
    assert_equal,
    p2p_port,
    wait_until,
    count_log_msg
)

from test_framework.mininode import (
    NetworkThread,
    NodeConn,
    NodeConnCB,
    msg_block,
    ToHex
)

from test_framework.test_framework import BitcoinTestFramework, ChainManager
from test_framework.blocktools import create_transaction, PreviousSpendableOutput
from test_framework.script import CScript, OP_TRUE

class Send_node():
    def __init__(self, tmpdir, log, node_no, p2p_connection, rpc_connection):
        self.p2p = p2p_connection
        self.rpc = rpc_connection
        self.node_no = node_no
        self.tmpdir = tmpdir
        self.log = log

    def send_block(self, block, expect_reject = False):
        self.rpc.submitblock(ToHex(block))

        if expect_reject:
            assert(self.check_frozen_tx_log(block.hash))
        else:
            assert_equal(block.hash, self.rpc.getbestblockhash())
            assert(self.check_frozen_tx_log(block.hash) == False);

    def check_frozen_tx_log(self, hash):
        for line in open(glob.glob(self.tmpdir + f"/node{self.node_no}" + "/regtest/blacklist.log")[0]):
            if hash in line:
                self.log.debug("Found line in blacklist.log: %s", line)
                return True
        return False

    def check_log(self, line_text):
        for line in open(glob.glob(self.tmpdir + f"/node{self.node_no}" + "/regtest/bitcoind.log")[0]):
            if re.search(line_text, line) is not None:
                self.log.debug("Found line in bitcoind.log: %s", line.strip())
                return True
        return False

class FrozenTXOReindex(BitcoinTestFramework):

    def set_test_params(self):
        self.setup_clean_chain = True
        self.num_nodes = 1
        self.chain = ChainManager()
        self.block_count = 0

    def _init(self):
        node_no = 0

        # Create a P2P connections
        node = NodeConnCB()
        connection = NodeConn('127.0.0.1', p2p_port(0), self.nodes[node_no], node)
        node.add_connection(connection)

        NetworkThread().start()
        # wait_for_verack ensures that the P2P connection is fully up.
        node.wait_for_verack()

        self.chain.set_genesis_hash(int(self.nodes[node_no].getbestblockhash(), 16))
        block = self.chain.next_block(self.block_count)
        self.block_count += 1
        self.chain.save_spendable_output()
        node.send_message(msg_block(block))

        for i in range(100):
            block = self.chain.next_block(self.block_count)
            self.block_count += 1
            self.chain.save_spendable_output()
            node.send_message(msg_block(block))

        self.log.info("Waiting for block height 101 via rpc")
        self.nodes[node_no].waitforblockheight(101)

        return node

    def _create_tx(self, tx_out, unlock, lock):
        unlock_script = b'' if callable(unlock) else unlock

        return create_transaction(tx_out.tx, tx_out.n, unlock_script, 1, lock)

    def _mine_and_send_block(self, tx, node, expect_reject = False):
        block = self.chain.next_block(self.block_count)

        self.chain.update_block(self.block_count, [tx] if tx else [])

        self.log.debug(f"attempting mining block: {block.hash}")

        node.send_block(block, expect_reject)
        self.block_count += 1

        return block.hash

    def _remove_last_block(self):
        # remove last block from chain manager
        del self.chain.block_heights[self.chain.blocks[self.block_count-1].sha256]
        del self.chain.blocks[self.block_count-1]
        self.block_count -= 1
        self.chain.set_tip(self.block_count-1)

    def _mine_and_check_rejected(self, tx, node):
        self.log.info(f"Mining block with transaction {tx.hash} spending TXO {tx.vin[0].prevout.hash:064x},{tx.vin[0].prevout.n} and checking that it is rejected")
        old_tip = self.chain.tip
        rejected_block_hash = self._mine_and_send_block(tx, node, True)
        assert_equal(node.rpc.getbestblockhash(), old_tip.hash)
        assert(node.check_frozen_tx_log(self.chain.tip.hash));
        assert(node.check_log("Block was rejected because it included a transaction, which tried to spend a frozen transaction output.*"+self.chain.tip.hash));

        # remove rejected block from test node - the only remaining copy after this point is on remote node disk
        self._remove_last_block()

        return rejected_block_hash

    def _create_policy_freeze_block(self, spendable_out, node):
        freeze_tx = self._create_tx(spendable_out, b'', CScript([OP_TRUE]))
        self.log.info(f"Mining block with transaction {freeze_tx.hash} whose output will be frozen later")
        self._mine_and_send_block(freeze_tx, node)

        self.log.info(f"Freezing TXO {freeze_tx.hash},0 on policy blacklist")
        result = node.rpc.addToPolicyBlacklist({
            "funds": [
            {
                "txOut" : {
                    "txId" : freeze_tx.hash,
                    "vout" : 0
                }
            }]
        });
        assert_equal(result["notProcessed"], [])

        spend_frozen_tx = self._create_tx(PreviousSpendableOutput(freeze_tx, 0), b'', CScript([OP_TRUE]))
        self.log.info(f"Mining block with transaction {spend_frozen_tx.hash} spending frozen TXO {freeze_tx.hash},0 and checking that is accepted")
        self._mine_and_send_block(spend_frozen_tx, node)
        # block is accepted as consensus freeze is not in effect
        assert_equal(node.rpc.getbestblockhash(), self.chain.tip.hash)

    def _create_consensus_freeze_block(self, spendable_out, node):
        freeze_tx = self._create_tx(spendable_out, b'', CScript([OP_TRUE]))
        self.log.info(f"Mining block with transaction {freeze_tx.hash} whose output will be frozen later")
        self._mine_and_send_block(freeze_tx, node)

        self.log.info(f"Freezing TXO {freeze_tx.hash},0 on consensus blacklist")
        result=node.rpc.addToConsensusBlacklist({
            "funds": [
            {
                "txOut" : {
                    "txId" : freeze_tx.hash,
                    "vout" : 0
                },
                "enforceAtHeight": [{"start": 0}],
                "policyExpiresWithConsensus": False
            }]
        });
        assert_equal(result["notProcessed"], [])

        spend_frozen_tx = self._create_tx(PreviousSpendableOutput(freeze_tx, 0), b'', CScript([OP_TRUE]))

        # block is rejected as consensus freeze is in effect
        rejected_block_hash = self._mine_and_check_rejected(spend_frozen_tx, node)

        return (freeze_tx.hash, rejected_block_hash)

    def run_test(self):

        node = self._init()

        out_policy_freeze_txo = self.chain.get_spendable_output()
        out_consensus_freeze_txo = self.chain.get_spendable_output()

        send_node = Send_node(self.options.tmpdir, self.log, 0, node, self.nodes[0])
        self._create_policy_freeze_block(out_policy_freeze_txo, send_node)
        [freeze_tx_hash, rejected_block_hash] = self._create_consensus_freeze_block(out_consensus_freeze_txo, send_node)
        node_chain_info = send_node.rpc.getblockchaininfo()
        old_tip_hash = node_chain_info['bestblockhash']
        old_tip_height = node_chain_info['blocks']

        assert(rejected_block_hash != old_tip_hash)

        # Make sure that we get to the same height:
        # best block with transactions policy frozen - should get to this point
        # best block with transactions consensus frozen - should not get to this block
        self.stop_node(0)
        self.start_node(0, extra_args=["-reindex=1"])

        # Waiting for last valid block. Waiting just for old_tip_height is not enough becuase next block (to be rejected) may not be processed yet.
        send_node.rpc.waitforblockheight(old_tip_height)
        # Wait for next block to be rejected. We need to wait for the second occurrence of the same log because one rejection happens before
        wait_until(lambda: count_log_msg(self, "InvalidChainFound: invalid block="+rejected_block_hash+"  height=105", "/node0") == 2, timeout=5)

        assert_equal(send_node.rpc.getbestblockhash(), old_tip_hash)

        # Unfreeze and reconsider block to show that the block was still stored on disk
        result = self.nodes[0].clearBlacklists( { "removeAllEntries": True } )
        assert_equal(result["numRemovedEntries"], 2)

        self.stop_node(0)
        self.start_node(0, extra_args=["-reindex=1"])

        send_node.rpc.waitforblockheight(old_tip_height + 1)

        self.log.info(send_node.rpc.getblockchaininfo())
        assert_equal(send_node.rpc.getbestblockhash(), rejected_block_hash)

if __name__ == '__main__':
    FrozenTXOReindex().main()


import numpy as np
import matplotlib.pyplot as plt

def radial_kernel(x0, X, tau):
    return np.exp(np.sum((X - x0) ** 2, axis=1) / (-2 * tau * tau))

def local_regression(x0, X, Y, tau):
    # add bias term
    x0 = np.r_[1, x0]
    X = np.c_[np.ones(len(X)), X]
    # fit model: normal equations with kernel
    xw = X.T * radial_kernel(x0, X, tau)
    beta = np.linalg.pinv(xw @ X) @ xw @ Y
    # predict value
    return x0 @ beta

def generate_data():
    n = 1000
    X = np.linspace(-3, 3, num=n)
    Y = np.log(np.abs(X ** 2 - 1) + .5)
    # Y = np.sin(X) + 0.3 * np.random.randn(n)  #
    plt.scatter(X, Y, s=5, color="green")
    plt.savefig("LocalWeightedLinearRegression2-DataInitial.png")
    plt.cla()  # Clear axis
    plt.clf()  # Clear figure
    plt.close()  # Close a figure window
    # jitter X
    X += np.random.normal(scale=.1, size=n)
    plt.scatter(X, Y, s=5, color="green")
    plt.savefig("LocalWeightedLinearRegression2-DatawithGitter.png")
    plt.cla()  # Clear axis
    plt.clf()  # Clear figure
    plt.close()  # Close a figure window
    return X, Y

def create_plot(X, Y, tau):
    fig, axes = plt.subplots(3, 2, figsize=(16, 8), sharex=False, sharey=False, dpi=120)
    # plt.subplots(3, 2 ) means display data in 3 rows and 2 columns
    # Plot each axes
    for i, ax in enumerate(axes.ravel()):
        domain = np.linspace(-3, 3, num=40)
        prediction = [local_regression(x0, X, Y, tau[i]) for x0 in domain]
        ax.scatter(X, Y, s=5, color="green", label="actual")
        ax.scatter(domain, prediction, s=5, color='red', label="prediction")
        ax.set(
            title="tau=" + str(tau[i]),
            xlabel='X',
            ylabel='Y',
         )
        ax.legend(loc='best')
    plt.suptitle('Local Weight Linear regression', size=10, color='blue')
    plt.savefig("LocalWeightedLinearRegression2-DataAndPrediction.png")
    return plt

if __name__ == "__main__":
    X, Y = generate_data()
    tau = [800, 10, .1, .01, .08, .9]
    myplot = create_plot(X, Y, tau)
    myplot.show()


from Filters.BubbleFilter import BubbleFilter
from Entities.BubbleCandidate import BubbleCandidate

class ShapeFilter(BubbleFilter):
    def __init__(self, source_width, source_height, logger, min_ratio_component_area=None, min_pa_ratio=None,
                 max_pa_ratio=None, w_min=None, w_max=None, h_min=None, h_max=None):
        BubbleFilter.__init__(self, "ShapeFilter", source_width, source_height, logger)

        # using default values if value not provided
        self.min_ratio_component_area = min_ratio_component_area if min_ratio_component_area is not None else 0.45
        self.min_pa_ratio = min_pa_ratio if min_pa_ratio is not None else 0.0075
        self.max_pa_ratio = max_pa_ratio if max_pa_ratio is not None else 0.15
        self.w_min = w_min if w_min is not None else 0.005
        self.w_max = w_max if w_max is not None else 0.6
        self.h_min = h_min if h_min is not None else 0.005
        self.h_max = h_max if h_max is not None else 0.6

    def is_accepted(self, bubble_candidate: BubbleCandidate) -> bool:
        contour_area = bubble_candidate.get_contour_area()
        perimeter = bubble_candidate.get_perimeter()

        if contour_area == 0:
            self.log_reject_reason(bubble_candidate.component_id, "contour area > 0", 0, 1)
            return False

        ratio_component_area = bubble_candidate.component_area / contour_area
        if ratio_component_area < self.min_ratio_component_area:
            self.log_reject_reason(bubble_candidate.component_id, "component / contour area", ratio_component_area,
                                   self.min_ratio_component_area)

            return False

        pa_ratio = perimeter / contour_area
        if pa_ratio < self.min_pa_ratio:
            self.log_reject_reason(bubble_candidate.component_id, "min perimeter / contour area", pa_ratio,
                                   self.min_pa_ratio)
            return False

        if pa_ratio > self.max_pa_ratio:
            self.log_reject_reason(bubble_candidate.component_id, "max perimeter / contour area", pa_ratio,
                                   self.max_pa_ratio)
            return False

        x, y, w, h = bubble_candidate.get_bounding_box()

        if w < self.source_width * self.w_min:
            self.log_reject_reason(bubble_candidate.component_id, "min width", w,
                                   self.source_width * self.w_min)
            return False
        if w > self.source_width * self.w_max:
            self.log_reject_reason(bubble_candidate.component_id, "max width", w,
                                   self.source_width * self.w_max)
            return False

        if h < self.source_height * self.h_min:
            self.log_reject_reason(bubble_candidate.component_id, "min height", h,
                                   self.source_height * self.h_min)
            return False
        if h > self.source_height * self.h_max:
            self.log_reject_reason(bubble_candidate.component_id, "max height", h,
                                   self.source_height * self.h_max)
            return False

        return True


from log_parser import LogParser
from producer import KafkaProducer

if __name__ == "__main__":
    logFile = LogParser.read_log_file()
    logFileGen = LogParser.fetch_log(logFile)
    producer = KafkaProducer()
    while True:
        try:
            data = next(logFileGen)
            serialized_data = LogParser.serialize_log(data)
            print("Message is :: {}".format(serialized_data))
            producer.produce(serialized_data)
        except StopIteration:
            exit()
        except KeyboardInterrupt:
            print("Printing last message before exiting :: {}".format(serialized_data))
            exit()


import logging
from functools import partial

from datasets import load_dataset
from transformers import (
    Seq2SeqTrainer,
    Seq2SeqTrainingArguments,
    WhisperForConditionalGeneration,
    WhisperProcessor,
)

from src.callbacks import ShuffleCallback
from src.config import Config, TrainingArgumentsConfig
from src.data_collator import DataCollatorSpeechSeq2SeqWithPadding
from src.metrics import compute_metrics
from src.prepare_dataset import prepare_dataset

logging.basicConfig(level=logging.INFO)

def train():
    config = Config()
    training_args_config = TrainingArgumentsConfig()
    training_args = Seq2SeqTrainingArguments(**training_args_config.dict())

    if config.prepare_dataset:
        dataset, _ = prepare_dataset(config)
    else:
        dataset = load_dataset(config.dataset_name, config.dataset_lang)
    logging.info("Training model...")

    model = WhisperForConditionalGeneration.from_pretrained(config.model_name)
    processor = WhisperProcessor.from_pretrained(
        config.model_name, task=config.task, language=config.model_lang
    )
    compute_metrics_fn = partial(compute_metrics, processor=processor)
    trainer = Seq2SeqTrainer(
        args=training_args,
        model=model,
        train_dataset=dataset["train"],
        eval_dataset=dataset["validation"],
        data_collator=DataCollatorSpeechSeq2SeqWithPadding(processor=processor),
        compute_metrics=compute_metrics_fn,
        tokenizer=processor,
        callbacks=[ShuffleCallback()],
    )

    trainer.train()
    trainer.push_to_hub()

if __name__ == "__main__":
    train()


#!/usr/bin/env python
#
# fast_mr ->
#
# Fast molecular replacement in the spirit of fast_dp, starting from coordinate
# files and using brute force (and educated guesses) to get everything going.
#
# fast_mr - main program.

import os
import sys
import time
import shutil
import math
import traceback
from multiprocessing import Pool

from iotbx import mtz
from iotbx import pdb
from libtbx.phil import parse
from cctbx.sgtbx import space_group, space_group_symbols
from iotbx.scalepack import merge as merge_scalepack
from libtbx import introspection

if not 'FAST_EP_ROOT' in os.environ:
    raise RuntimeError('FAST_EP_ROOT not set')

fast_ep_lib = os.path.join(os.environ['FAST_EP_ROOT'], 'lib')

if not fast_ep_lib in sys.path:
    sys.path.append(fast_ep_lib)

from xml_output import write_ispyb_xml

from generate_possible_spacegroups import generate_chiral_spacegroups, \
     spacegroup_enantiomorph, spacegroup_full, sanitize_spacegroup
from run_job import run_job, run_job_cluster, is_cluster_job_finished
from fast_mr_phaser import run_phaser_cluster
from parse_pdb import pdb_file_nres

class logger:
    def __init__(self):
        self._fout = open('fast_mr.log', 'w')
        return

    def __del__(self):
        self._fout.close()
        self._cout = None
        return

    def __call__(self, _line):
        sys.stdout.write('%s\n' % _line)
        self._fout.write('%s\n' % _line)
        return

class Fast_mr:

    def __init__(self, hklin, xyzin_and_ids):

        self._hklin = os.path.abspath(hklin)
        self._xyzins = [os.path.abspath(xyzin_and_id[0])
                        for xyzin_and_id in xyzin_and_ids]
        self._ids = [xyzin_and_id[1] for xyzin_and_id in xyzin_and_ids]
        self._cpu = 2
        self._machines = 10
        self._wd = os.getcwd()
        self._log = logger()

        self._log('Using %d cpus / %d machines' % (self._cpu, self._machines))

        self._full_command_line = ' '.join(sys.argv)

        # pull information we'll need from the input MTZ file - the unit cell,
        # the pointgroup and the number of reflections in the file. select
        # first Miller array in file which has native data

        # --- SAD DATA ---

        m = mtz.object(self._hklin)
        mas = m.as_miller_arrays()

        self._data = None

        for ma in mas:
            if str(ma.observation_type()) != 'xray.amplitude':
                continue
            self._data = ma
            break

        if not self._data:
            raise RuntimeError('no intensity data found in %s' % \
                self._hklin)

        self._pointgroup = self._data.space_group().type().number()
        self._unit_cell = self._data.unit_cell().parameters()

        self._nrefl = m.n_reflections()
        self._spacegroups = generate_chiral_spacegroups(self._pointgroup)

        # write out a nice summary of the data set properties and what columns
        # were selected for analysis

        self._log('Input:       %s' % self._hklin)
        self._log('Columns:     %s' % self._data.info().label_string())
        self._log('Unit cell:   %.2f %.2f %.2f %.2f %.2f %.2f' % \
                  self._unit_cell)
        self._log('Pointgroup:  %s' % m.space_group().type().lookup_symbol())
        self._log('Resolution:  %.2f - %.2f' % self._data.resolution_range())
        self._log('Nrefl:       %d' % self._nrefl)
        self._log('Spacegroups: %s' % ' '.join(self._spacegroups))

        self._log('Input coordinate files:')
        self._nres = []
        for xyzin, _id in zip(self._xyzins, self._ids):
            nres = pdb_file_nres(xyzin)
            self._nres.append(nres)
            self._log('%40s %8d %.3f' % (os.path.split(xyzin)[1], nres, _id))

        total_nres = sum(self._nres)
        # FIXME calculate probable number of complexes in here

        self._copies = 1

        return

    def do_mr(self):
        t0 = time.time()

        cluster = True
        njobs = self._machines
        ncpu = self._cpu

        # set up N phaser jobs

        jobs = [ ]

        for spacegroup in self._spacegroups:
            wd = os.path.join(self._wd, spacegroup)
            if not os.path.exists(wd):
                os.makedirs(wd)
            commands = ['mode mr_auto',
                        'spacegroup %s' % spacegroup,
                        'hklin %s' % self._hklin,
                        'labin F=F SIGF=SIGF',
                        'root mr%s' % spacegroup]
            for j, (xyzin, _id, nres) in enumerate(
                zip(self._xyzins, self._ids, self._nres)):
                commands.append('ensemble m%d pdb %s identity %f' %
                                (j, xyzin, 100 * _id))
            for j, (xyzin, _id, nres) in enumerate(
                zip(self._xyzins, self._ids, self._nres)):
                commands.append('composition protein nres %d num %d' %
                                (nres, self._copies))
            for j, (xyzin, _id, nres) in enumerate(
                zip(self._xyzins, self._ids, self._nres)):
                commands.append('search ensemble m%d num %d' %
                                (j, self._copies))

            jobs.append((wd, commands))

        # actually execute the tasks - either locally or on a cluster, allowing
        # for potential for fewer available machines than jobs

        self._log('Running %d x phaser jobs' % len(jobs))

        pool = Pool(min(njobs, len(jobs)))

        if cluster:
            pool.map(run_phaser_cluster, jobs)
        else:
            print(1/0)

        # now look for the results
        worked = []
        for job in jobs:
            wd = job[0]
            spacegroup = os.path.split(wd)[-1]
            if os.path.exists(os.path.join(wd, 'mr%s.sol' % spacegroup)):
                worked.append(os.path.join(wd, 'mr%s.sol' % spacegroup))

        for w in worked:
            sol = open(w).read()
            for record in sol.split('\n'):
                if 'SOLU SPAC' in record:
                    spacegroup = record.replace(
                        'SOLU SPAC', '').replace(' ', '')
                if 'SOLU SET' in record:
                    tfz = float(record.replace('=', ' ').split()[5])
            print('Solution: %s %.2f' % (spacegroup, tfz))

        t1 = time.time()
        self._log('Time: %.2f' % (t1 - t0))

if __name__ == '__main__':
    xyzin_and_ids = []
    for arg in sys.argv[2:]:
        if ':' in arg:
            xyzin = arg.split(':')[0]
            _id = float(arg.split(':')[1])
            if _id > 1.0:
                _id /= 100.0
            xyzin_and_ids.append((xyzin, _id))
        else:
            xyzin_and_ids.append((arg, 1.0))

    fast_mr = Fast_mr(sys.argv[1], xyzin_and_ids)
    try:
        fast_mr.do_mr()
    except RuntimeError as e:
        fast_mr._log('*** MR: %s ***' % str(e))
        traceback.print_exc(file = open('fast_mr.error', 'w'))
        sys.exit(1)


# import modules
import timeit
import numpy as np
import matplotlib.pyplot as plt
import time

# Question 1 ------

# selection sort
def selectionsort(arr):
    for i in range(len(arr)): # outer loop to traverse array
        minInd = i # minimum index starts at i
        for j in range(i+1,len(arr)): # inner loop begins at i + 1, ends at the end
            if arr[j] < arr[minInd]: # if a smaller value is found
                minInd = j # the minimum index becomes the index that it was found
        if minInd != i: # when the min index changes
            # swap positions so that the minimum index is at the beginning of the inner loop
            temp = arr[i]
            arr[i] = arr[minInd]
            arr[minInd] = temp
    return arr # return the sorted array

# insertion sort
def insertionsort(arr):
    for i in range(len(arr)): # outer loop to traverse array
        j = i # inner loop starts at i
        while(j>0 and arr[j-1]> arr[j]): # while the value at j is greater than min and greater than 0
            # swap
            temp = arr[j]
            arr[j] = arr[j - 1]
            arr[j-1] = temp
            j -= 1 # j steps back
    return arr # return sorted array

# merge sort
def mergesort(arr):
    n = len(arr) # record array length

    # new arrays for splitting
    left = []
    right = []

    if n <= 1: # when the array length becomes 1, return the array
        return arr

    #split the array into left and right sides
    for i in range(0,n):
        if(i<(n-1)/2):
            left.append(arr[i])
        else:
            right.append(arr[i])

    leftsort = mergesort(left) # take all the left sides
    rightsort = mergesort(right) # take all the right sides

    return merge(leftsort,rightsort) # merge them back together

# helper function for merge sort, merges arrays together in sorted order
def merge(l,r):
    # numbers at the end of the arrays that tell the array to stop merging
    l.append(9999999)
    r.append(9999999)

    D = [] # merged array
    i = j = 0 # start at index 0
    while l[i] < 9999999 or r[j] < 9999999: # while not at the end of either array
        if l[i] < r[j]: # find the lower of the two values in the two arrays
            D.append(l[i]) # add it to the new array
            i = i + 1 # increase index

        else: # same as above
            D.append(r[j])
            j = j + 1
    return D # return merged array

index = [] # array for recording array size

# Question 2 ----

'''
# arrays for holding time values and numbers for sorting
sortedarr = []
reversearr = []
reversearrtwo = []
selectsortedtime = []
selectreversetime = []
insertsortedtime = []
insertreversetime = []
mergesortedtime = []
mergereversetime = []

# how many numbers in the array at the given time; used for incrementing so we don't have to keep making the ordered
# and reverse ordered arrays over and over again
sortedarrayCount = 1
reversearrayCount = 0

for i in range(1, 101): # outer loop; creates arrays of size n = 100 to n = 10000
    index.append(i*100) # add the size of the array currently being created to the list for plotting
    print(i) # progress report; displays the current size being worked on to console
    for j in range(sortedarrayCount,i*100 + 1): # creates the sorted array of size i*100
        sortedarrayCount += 1 # used so that we don't have to keep making new arrays
        sortedarr.append(j) # add the new values up to i*100
    for k in range(i*100, reversearrayCount, -1): # creates the reverse sorted array of size i*100
        reversearrayCount += 1
        reversearrtwo.append(k)
    reversearrtwo.extend(reversearr) # because it is reverse sorted, we need to add the new values to the beginning
    reversearr = list(reversearrtwo) # take that list and prep it for the next iteration i
    reversearrtwo = []

# for this section, make code that you don't want to see on the plot comments
# for example if you want a selection sort plot, make all insertion and merge sort related code comments
# if you just want to compare sorted array times, make all reverse sorted related code comments

#    selectionsorted = list(sortedarr) # duplicate sorted array
    selectionreverse = list(reversearr) # duplicate reverse sorted array
#    ssort = timeit.Timer (lambda: selectionsort(selectionsorted)) # time selection sort for sorted array
    srevt = timeit.Timer (lambda: selectionsort(selectionreverse)) # time selection sort for reverse sorted array
#    selectsortedtime.append(ssort.timeit(number=1)) # add the time to the appropriate array
    selectreversetime.append(srevt.timeit(number=1)) # same

# same as selection sort but for insertion sort

#    insertionsorted = list(sortedarr)
    insertionreverse = list(reversearr)
#    isort = timeit.Timer (lambda: insertionsort(insertionsorted))
    irevt = timeit.Timer (lambda: insertionsort(insertionreverse))
#    insertsortedtime.append(isort.timeit(number=1))
    insertreversetime.append(irevt.timeit(number=1))

# same as selection sort but for merge sort

#    mergesorted = list(sortedarr)
#    mergereverse = list(reversearr)
#    msort = timeit.Timer (lambda: mergesort(mergesorted))
#    mrevt = timeit.Timer (lambda: mergesort(mergereverse))
#    mergesortedtime.append(msort.timeit(number=1))
#    mergereversetime.append(mrevt.timeit(number=1))

# plotting the times
# for this section, make sure to call plot however many times you want to have a function on the graph
# if you want one for forward sort and reverse sort, you call it twice and label both
plt.plot(index, selectreversetime, label='Selection Sort') # selection sort function, blue line
plt.plot(index, insertreversetime, color='r', label='Insertion Sort') # insertion sort function, red line
plt.ylabel('Time') # y axis holds time
plt.xlabel('n') # x axis holds n
plt.title('Average Random Array Sort Time') # title of plot
plt.legend() # display legend
plt.show() # display plot

'''

np.random.seed(101) # seed for random number generator

# Question 4 -----
'''

selectionTotalTime = [] # array to hold all average times for selection sort
insertionTotalTime = [] # array to hold all average times for insertion sort
mergeTotalTime = [] # array to hold all average times for merge sort

for i in range(2, 101, 2): # setup for n = 200 to 10000; n = i*100 for each iteration; only every n = 200

    # arrays to hold the times for 100 permutations at size n
    selectionIndexTime = []
    insertionIndexTime = []
    mergeIndexTime = []

    index.append(i*100) # records n for the plot
    print(i) # progress report printed to console
    arr = np.random.rand(i*100) # generates an array of i*100 random numbers

    # creates 100 permutations for the random array arr and times each algorithm's sorting time for each permutation
    for j in range(0, 100):
        array = np.random.permutation(arr) # duplicate array

        selectionArr = list(array) # duplicate array
        ssort = timeit.Timer (lambda: selectionsort(selectionArr)) # time selection sort
        selectionIndexTime.append(ssort.timeit(number=1)) # add the time to the appropriate array

        # same follows for the next two algorithms
        insertionArr = list(array)
        isort = timeit.Timer (lambda: insertionsort(insertionArr))
        insertionIndexTime.append(isort.timeit(number=1))

        mergeArr = list(array)
        msort = timeit.Timer (lambda: mergesort(mergeArr))
        mergeIndexTime.append(msort.timeit(number=1))

    # variables to add up all the times for index i
    avgSelection = 0
    avgInsertion = 0
    avgMerge = 0

    # add up everything for each algorithm
    for k in range(0, 100):
        avgSelection += selectionIndexTime[k]
        avgInsertion += insertionIndexTime[k]
        avgMerge += mergeIndexTime[k]

    # calculate averages and add them to the average time array to be plotted
    selectionTotalTime.append(avgSelection/100)
    insertionTotalTime.append(avgInsertion/100)
    mergeTotalTime.append(avgMerge/100)

print('%s seconds' % (time.time() - start ))

# plotting using matplotlib

plt.plot(index, selectionTotalTime, label='Selection Sort') # selection sort function, blue line
plt.plot(index, insertionTotalTime, color='r', label='Insertion Sort') # insertion sort function, red line
plt.plot(index, mergeTotalTime, color='g', label='Merge Sort') # merge sort function, green line
plt.ylabel('Time') # y axis holds time
plt.xlabel('n') # x axis holds n
plt.title('Average Random Array Sort Time') # title of plot
plt.legend() # display legend
plt.show() # display plot
'''

'''
# Question 5 ----
arr = np.random.rand(1000000) # generate the array with n = 10^6 random numbers

selectionarr = list(arr) # duplicate array
selectionstart = time.time() # start time
selectionsort(selectionarr) # selection sort it
print('%s seconds selection' % (time.time() - selectionstart )) # print the time it took by current time - start time

# same but for insertion sort
insertionarr = list(arr)
insertionstart = time.time()
insertionsort(insertionarr)
print('%s seconds insertion' % (time.time() - insertionstart ))

# same but for merge sort
mergearr = list(arr)
mergestart = time.time()
mergesort(mergearr)
print('%s seconds merge' % (time.time() - mergestart ))
'''


# Path to scripts folder
path = "C:/Users/j_ber/root/blender_scripts/blender_modules/panels/"

# Names of python files to import
filenames = ["vertex_tools.py"]

for file in filenames:
    exec(compile(open(path + file).read(), path + file, 'exec'))


import cv2
import glob
from matplotlib import pyplot as plt
faceDet = cv2.CascadeClassifier("haarcascade_frontalface_default.xml")
faceDet_two = cv2.CascadeClassifier("haarcascade_frontalface_alt2.xml")
faceDet_three = cv2.CascadeClassifier("haarcascade_frontalface_alt.xml")
faceDet_four = cv2.CascadeClassifier("haarcascade_frontalface_alt_tree.xml")

fishface = cv2.face.FisherFaceRecognizer_create()
fishface.read('fish.xml')
emotions = ["neutral", "anger", "contempt", "disgust", "fear", "happy", "sadness", "surprise"]

for files in glob.glob("C:\\Users\\HP\\Desktop\\classify\\*"):
    gray = cv2.imread(files)
    gray  = cv2.cvtColor(gray, cv2.COLOR_BGR2GRAY)

    face = faceDet.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=10, minSize=(5, 5), flags=cv2.CASCADE_SCALE_IMAGE)
    face_two = faceDet_two.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=10, minSize=(5, 5), flags=cv2.CASCADE_SCALE_IMAGE)
    face_three = faceDet_three.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=10, minSize=(5, 5), flags=cv2.CASCADE_SCALE_IMAGE)
    face_four = faceDet_four.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=10, minSize=(5, 5), flags=cv2.CASCADE_SCALE_IMAGE)
    if len(face) == 1:
        facefeatures = face
    elif len(face_two) == 1:
        facefeatures = face_two
    elif len(face_three) == 1:
        facefeatures = face_three
    elif len(face_four) == 1:
        facefeatures = face_four
    else:
        facefeatures = ""
    for (x, y, w, h) in facefeatures:
        gray = gray[y:y+h, x:x+w]
        try:
            gray = cv2.resize(gray, (350, 350))
        except:
           pass

    plt.subplot(132)
    plt.title('img')
    plt.imshow(gray, 'gray')
    plt.xticks([])
    plt.yticks([])
    plt.show()
    Class, abc = fishface.predict(gray)
    print(emotions[Class])


import random

suits = ('Heart', 'Clubs', 'Diamond', 'Spades')
ranks = ('two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten', 'Jack', 'Queen', 'King', 'Ace')
values = {'two': 2, 'three':3, 'four': 4, 'five': 5, 'six':6, 'seven': 7, 'eight': 8, 'nine': 9, 'ten': 10, 'Jack': 11, 'Queen': 12, 'King': 13, 'Ace': 14}

class Card():

    def __init__(self, suit, rank):
        self.suit = suit
        self.rank = rank
        self.value = values[rank]

    def __str__(self):
        return self.rank + " of " + self.suit

class Deck():
    def __init__(self):
        self.cardList = []

        for suit in suits:
            for rank in ranks:
                myCard = Card(suit, rank)
                self.cardList.append(myCard)

    def randomze(self):
        random.shuffle(self.cardList)

class Player():
    def __init__(self, name, indicator, origdeck):
        self.name = name
        self.deck = []
        if indicator == 1:
            self.deck = origdeck.cardList[0:53:2]
        else:
            self.deck = origdeck.cardList[1:53:2]

print("Welcome players to the WarZone! A new deck of card is being made ready for you!")
gameDeck = Deck()
gameDeck.randomze()
player1name = input("Player 1! Give me your name: ")
player1 = Player(player1name, 1, gameDeck)
player2name = input("Player 2! Give me your name: ")
player2 = Player(player2name, 2, gameDeck)
print(f"Thank you {player1name} and {player2name}! Your cards have been alternatively distributed starting from {player1name}")
smallDeck1 = []
smallDeck2 = []
tie = False
print(f"Game has been started!")
while True:
    if (player1.deck.__len__() == 0 or player2.deck.__len__() == 0) and tie == False:
        break

    gar1 = input(f"{player1name} press space bar to place your card(s): ")
    smallDeck1.append(player1.deck.pop())
    print(smallDeck1[0])
    gar2 = input(f"{player2name} press space bar to place your card(s): ")
    smallDeck2.append(player2.deck.pop())
    print(smallDeck2[0])

    print(f"{player1name}'s {smallDeck1[0]} vs {player2name}'s {smallDeck2[0]}")

    if smallDeck1[len(smallDeck1)-1].value > smallDeck2[len(smallDeck2)-1].value:
        print(f"{player1name} won the round")
        for card in smallDeck1:
            player1.deck.append(card)
        for card in smallDeck2:
            player1.deck.append(card)
        tie = False
        smallDeck1.clear()
        smallDeck2.clear()
        random.shuffle(player1.deck)

    elif smallDeck1[len(smallDeck1)-1].value < smallDeck2[len(smallDeck2)-1].value:
        print(f"{player2name} won the round")
        for card in smallDeck1:
            player2.deck.append(card)
        for card in smallDeck2:
            player2.deck.append(card)
        tie = False
        smallDeck1.clear()
        smallDeck2.clear()
        random.shuffle(player2.deck)

    else:
        print(f"It's a draw! War has been triggered. Both players, risk in 3 more cards!:")
        risk = 2
        if len(player1.deck) < 3 or len(player2.deck)< 3:
            if(len(player1.deck) < len(player2.deck)):
                print(f"It seems like {player1name} has less than 3 cards. So, we risk {len(player1.deck)} cards only")
                risk = len(player1.deck) - 1
            else:
                print(f"It seems like {player2name} has less than 3 cards. So, we risk {len(player2.deck)} cards only")
                risk = len(player2.deck) -1

        if risk < 0:
            if len(player1.deck) < len(player2.deck):
                print(f"{player1name}, you cant continue no more! You're out of cards")
            else:
                 print(f"{player2name}, you cant continue no more! You're out of cards")
            tie = False
        else:
            i = 0
            while i < risk:
                smallDeck1.append(player1.deck.pop())
                smallDeck2.append(player2.deck.pop())
            tie = True

if len(player1.deck) == 0:
    print(f"{player2name} won the battle")
else:
    print(f"{player1name} won the battle")


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

import sys
import os.path
import argparse
import logging
from tarfile import TarFile

from thirdparty.dagflow import ParallelTask, Task, DAG, do_dag
from ontbc.common import mkdir, touch, read_tsv
from ontbc.parser import add_barcode_parser
from ontbc.config import PORECHOP_BIN, QUEUE
from ontbc import __file__, __version__, __email__, __author__

LOG = logging.getLogger(__name__)

def read_tar(file):

    a = os.path.dirname(file)

    return [os.path.join(a, i) for i in TarFile(file).getnames()]

def scan_cell(cell):

    fastqs = []
    summarys = []
    fast5s = []

    for root, dirs, files in os.walk(cell, followlinks=True, topdown=False):

        for name in files:
            path = os.path.join(root, name)
            if name.endswith(".fastq"):
                fastqs.append(path)
            elif name.endswith(".txt"):
                summarys.append(path)
            elif name.endswith(".fast5"):
                fast5s.append(path)
            elif name.endswith(".tar"):
                fast5s += read_tar(path)
            else:
                pass

    return fastqs, summarys, fast5s

def create_porechop_tasks(cell, barcodes, job_type, work_dir, out_dir):

    LOG.info("find fastq, summary and fast5 files in %r" % cell)

    fastq_fofn = os.path.join(work_dir, "fastq.fofn")
    summary_fofn = os.path.join(work_dir, "summary.fofn")
    fast5_fofn = os.path.join(work_dir, "fast5.fofn")
    find_done = os.path.join(work_dir, "find_done")

    if not os.path.exists(find_done):
        fastqs, summarys, fast5s = scan_cell(cell)

        for i, j in zip([fastq_fofn, summary_fofn, fast5_fofn], [fastqs, summarys, fast5s]):
            with open(i, "w") as fh:
                fh.write("%s\n" % "\n".join(j))

        del fastqs, summarys, fast5s
        touch(find_done)

    fastqs = [i[0] for i in read_tsv(fastq_fofn)]
    summarys = [i[0] for i in read_tsv(summary_fofn)]
    fast5s = [i[0] for i in read_tsv(fast5_fofn)]
    LOG.info("%s fastq, %s summary and %s fast5 files found" % (len(fastqs), len(summarys), len(fast5s)))

    del summarys, fast5s

    if job_type == "local":
        _option = ""
    else:
        _option = "-q %s" % ",".join(QUEUE)

    tasks = ParallelTask(
        id="bc",
        work_dir="%s/{id}" % work_dir,
        type=job_type,
        option=_option,
        script="""
{ontbc}/ontbc.py clean {{fastq}} > clean.fastq
{porechop}/porechop-runner.py -i clean.fastq -b . -t 1 --verbosity 2 --no_split > porechop.log
rm -rf clean.fastq
""".format(
            porechop=PORECHOP_BIN,
            ontbc=os.path.join(os.path.dirname(__file__), "..")
        ),
        fastq=fastqs,
    )

    summary = os.path.join(work_dir, "all.summary.txt")

    join_summary = Task(
        id="join_summary",
        work_dir=work_dir,
        type=job_type,
        script="""
less {summary} | xargs cat - > all.summary.txt
""".format(
            summary=summary_fofn
        ),
    )

    join_tasks = ParallelTask(
        id="join",
        work_dir=work_dir,
        type=job_type,
        script="""
mkdir -p {out}/{{barcode}}

if [ ! -e {{barcode}}_cat_done ]; then
    cat */{{barcode}}.fastq > {out}/{{barcode}}/{{barcode}}.fastq
    touch {{barcode}}_cat_done
fi

rm -rf */{{barcode}}.fastq

cd {out}/{{barcode}}
{ontbc}/ontbc.py filter --fastq {{barcode}}.fastq --summary {summary} --fast5 {fast5} \\
  --min_score -100 --min_length 0 --out {{barcode}}
rm {{barcode}}.filtered.fastq
mv {{barcode}}.filtered.summary.txt {{barcode}}.summary.txt
""".format(
            summary=summary,
            ontbc=os.path.join(os.path.dirname(__file__), ".."),
            fast5=fast5_fofn,
            out=out_dir
        ),
        barcode=barcodes
    )

    for i in join_tasks:
        i.set_upstream(*tasks)
        i.set_upstream(join_summary)

    return tasks, join_tasks, join_summary

def run_porechop(cell, barcodes, job_type, threads, work_dir, out_dir):

    assert os.path.isdir(cell), "%r not exist" % cell

    out_dir = mkdir(out_dir)
    work_dir = mkdir(work_dir)

    tasks, join_tasks, join_summary = create_porechop_tasks(
        cell=cell,
        barcodes=barcodes,
        job_type=job_type,
        work_dir=work_dir,
        out_dir=out_dir
    )

    dag = DAG("porechop")

    dag.add_task(*tasks)
    dag.add_task(join_summary)
    dag.add_task(*join_tasks)

    do_dag(dag, concurrent_tasks=threads, refresh_time=30)

def barcode(args):

    run_porechop(
        cell=args.cell,
        barcodes=args.barcode,
        job_type=args.job_type,
        threads=args.threads,
        work_dir=args.work_dir,
        out_dir=args.out_dir
    )

def main():
    logging.basicConfig(
        stream=sys.stderr,
        level=logging.INFO,
        format="[%(levelname)s] %(message)s"
    )

    parser = argparse.ArgumentParser(
        formatter_class=argparse.RawDescriptionHelpFormatter,
        description="""

version: %s
contact:  %s <%s>\
    """ % (__version__, " ".join(__author__), __email__))

    parser = add_barcode_parser(parser)
    args = parser.parse_args()
    barcode(args)

if __name__ == "__main__":
    main()


import argparse
import optparse
from .parser import *

def get_args():
    parser = optparse.OptionParser()

    parser.add_option('-i', '--html;',
        action="store", dest="html",
        help="html to parse")
    parser.add_option('-o', '--output',
        action="store", dest="output",
        help="place to output messages", default="messages.csv")
    parser.add_option('-s', '--show',
        action="store", dest="show",
        help="show messages as they are being written", default=True)

    options, args = parser.parse_args()
    return options, args

def main():
    options, args = get_args()
    parser = Parser(options.html, options.output, options.show)
    parser.parse_all_messages_into_single_file()

if __name__ == "__main__":
    main()


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Wed Oct  5 16:56:55 2022

@author: josephbriggs
"""
import pathlib
import argparse
import cv2

def main():
    '''
    Converts files to greyscale.
    '''

    parser = argparse.ArgumentParser(description='Convert files to greyscale.')
    parser.add_argument('--input_path', "-i", type=str,
                        help='path to the image or directory of images. \
                If converting a directory, use *')
    parser.add_argument('--output_path', "-o", type=str,
                        help='output path where images will be saved.')
    parser.add_argument('--res', "-r", type=int,
                        help='downscale factor.')

    args = parser.parse_args()

    pathlib.Path(args.output_path).mkdir(parents=True, exist_ok=True)

    # files = pathlib.Path(args.input_path).glob(r'/*.png|')
    file_extentions = ['png', 'jpeg', 'jpg']
    files = []
    for file_extension in file_extentions:
        files += pathlib.Path(args.input_path).glob(fr'*.{file_extension}')

    for file in files:
        file_name = file.name
        image = cv2.imread(str(file))
        image_gs = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
        file_name_to_save = args.output_path+"/"+file_name
        print(file_name_to_save)
        cv2.imwrite(file_name_to_save, image_gs)

    print('converted files to greyscale')

if __name__ == "__main__":

    main()


import os
import cv2
import numpy as np
import shutil
import sys
sys.path.insert(0,os.path.realpath('..'))
sys.path.insert(0,os.path.join(os.path.realpath('..'),'piano_utils'))
from tools.warper import order_points
from config import cfg
from piano_utils.networks import PSPNet
from piano_utils.util import colorize_mask
from piano_utils.keyboard import KeyBoard
from PIL import Image
from tqdm import tqdm
import shapely
from shapely.geometry import Polygon,MultiPoint
import time
from skimage.measure import label, regionprops
from collections import Counter
import json
from IPython import embed
import pickle

exp_cfg = {
        'exp_imgs':'/home/data/lj/Piano/experment/keyboard/exp_imgs',
        'tmp_dir':'/home/data/lj/Piano/experment/keyboard/tmp_dir',
        'figure_dir':'/home/data/lj/Piano/experment/keyboard_figure'
}
class HoughKeyBoard(object):
    def __init__(self):
        self.theta_thersh = 0.08

    def hough_transform(self,img):
        res = {}
        img_ori = img.copy()
        h, w = img.shape[:2]
        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        gray = cv2.GaussianBlur(gray, (5, 5), 0)
        edges = cv2.Canny(gray, 50, 150, 3)
        lines = cv2.HoughLines(edges, 1.0, np.pi / 180, 120)
        thetas = [x[0][1] for x in lines if not (x[0][1] < (np.pi / 4.) or
                  x[0][1] > (3.*np.pi/4.0))]
        dic = dict(Counter(thetas))
        theta = sorted(dic.items(), key=lambda x: x[1], reverse=True)
        if len(theta) > 0 and theta[0][1] > 1:   #---统计角度最多重复的直线
            most_theta = theta[0][0]
        else:
            return
        x_loc, y_loc, pts = [], [], []
        for line in lines:
            rho, theta = line[0]
            if abs(most_theta * 180 / np.pi - 90) > 1.5:  #--键盘是斜着的
                if abs(theta - most_theta) > self.theta_thersh:
                    continue
            else:    #---其他情况
                if not theta == most_theta:
                    continue
            pt1 = (0, max(int(rho / np.sin(theta)), 0))
            pt2 = (img_ori.shape[1], max(int((rho - img_ori.shape[1] * np.cos(theta)) / np.sin(theta)),0))
            cv2.line(img_ori, pt1, pt2, (0, 255, 0), 1)
            pts.append((pt1, pt2))
        return img_ori

def get_img_box_dict():
    img_box_dict = dict()
    file_name = '/home/data/lj/Piano/Segment/train.txt'
    with open(file_name,'r') as fr:
        items = [l.strip() for l in fr.readlines()]
    mask_lists = []
    for item in items:
        item = item.split()
        if 'tools' in item[0]:
            #mask_dir = item[0].split('/')[-2]
            continue
        else:
            mask_dir = os.path.basename(item[0]).split('_img_') [0]
        if 'segment' in item[0]:continue
        if mask_dir in mask_lists:continue
        mask_lists.append(mask_dir)
        img_mask = cv2.imread(item[1],cv2.IMREAD_GRAYSCALE)
        img_mask[img_mask==2] = 1
        img_mask[img_mask==1] = 255
        contours,_ = cv2.findContours(img_mask,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)
        assert len(contours)==1,'value wrong'
        contours = np.squeeze(contours)
        rect = order_points(contours).reshape(-1,1,2).astype(int)
        img_box_dict[mask_dir] = rect

    json_path = os.path.join(exp_cfg['exp_imgs'],'need_labels')
    json_files = [os.path.join(json_path,x) for x in os.listdir(json_path) if x.endswith('json')]
    json_files.sort()
    for json_file in json_files:
        with open(json_file,'r') as fr:
            items = json.load(fr)
        basename = os.path.basename(json_file).split('.')[0]
        points = np.array(items['shapes'][0]['points'])
        rect = order_points(points).reshape(-1,1,2).astype(int)
        img_box_dict[basename] = rect
    return img_box_dict

class KeyBoard_Exp(KeyBoard):
    def __init__(self):
        KeyBoard.__init__(self)
        print('KeyBoard load finish')

    def detect(self,img):
        image = img.convert('RGB')
        self.prediction = self.inference(img)
        contours,_ = self.find_contours(image,self.prediction)
        rect = order_points(contours).reshape(-1,1,2).astype(int)
        return rect

    def mask2image(self,image):
        image = Image.fromarray(cv2.cvtColor(image,cv2.COLOR_BGR2RGB))
        w, h = image.size
        colorized_mask = colorize_mask(self.prediction, self.palette)
        output_im = Image.new('RGB', (w*2, h))
        output_im.paste(image, (0,0))
        output_im.paste(colorized_mask, (w,0))
        output_im = cv2.cvtColor(np.asarray(output_im),cv2.COLOR_RGB2BGR)
        return output_im

def cal_iou(gt_rect, det_rect):
    #---不规则的两个四边形计算Iou,不是矩形了
    gt_rect = gt_rect.reshape(4, 2)
    poly1 = Polygon(gt_rect).convex_hull
    det_rect = det_rect.reshape(4,2)
    poly2 = Polygon(det_rect).convex_hull
    union_poly = np.concatenate((gt_rect,det_rect))
    if not poly1.intersects(poly2):
        iou = 0
    else:
        try:
            inter_area = poly1.intersection(poly2).area
            union_area = MultiPoint(union_poly).convex_hull.area
            if union_area == 0:
                iou= 0
            iou=float(inter_area) / union_area
        except shapely.geos.TopologicalError:
            print('shapely.geos.TopologicalError occured, iou set to 0')
            iou = 0
    return iou

def ensure_dir(path):
    if not os.path.exists(path):
        os.makedirs(path)

def main():
    seg_pickle_file = os.path.join(exp_cfg['tmp_dir'],'seg.pkl')
    hour_pickle_file = os.path.join(exp_cfg['tmp_dir'],'hourgh.pkl')
    path = exp_cfg['exp_imgs']
    save_seg_dir = os.path.join(exp_cfg['figure_dir'],'segment')
    save_hourgh_dir = os.path.join(exp_cfg['figure_dir'],'hourgh')
    ensure_dir(save_seg_dir)
    ensure_dir(save_hourgh_dir)

    img_files = [os.path.join(path,x) for x in os.listdir(path)]
    gt_box_dict = get_img_box_dict()

    with open(seg_pickle_file,'rb') as f1:
        seg_box_dict = pickle.load(f1)
    with open(hour_pickle_file,'rb') as f2:
        hour_box_dict = pickle.load(f2)

    seg_ious = []
    for img_mark,det_rect in seg_box_dict.items():
        gt_rect = gt_box_dict[img_mark]
        iou = cal_iou(gt_rect,det_rect)
        if iou>0.5:
            seg_ious.append(iou)
        else:print(img_mark)

    hour_detector = HoughKeyBoard()
    keyboard_net = KeyBoard_Exp()

    hour_ious = []
    for img_mark,det_rect in hour_box_dict.items():
        gt_rect = gt_box_dict[img_mark]
        iou = cal_iou(gt_rect,det_rect)
        if iou>0.5:
            hour_ious.append(iou)
        else:
            img = cv2.imread(os.path.join(path,img_mark+'.jpg'))
            img_copy = img.copy()
            img_input = Image.fromarray(cv2.cvtColor(img_copy,cv2.COLOR_BGR2RGB))
            seg_rect = keyboard_net.detect(img_input)
            for rect in det_rect:
                rect = rect[0]
                cv2.circle(img,(rect[0],rect[1]),5,(0,255,0),3)
            for rect in seg_rect:
                rect = rect[0]
                cv2.circle(img_copy,(rect[0],rect[1]),5,(0,255,0),3)
            img_copy = keyboard_net.mask2image(img_copy)
            img = hour_detector.hough_transform(img)
            cv2.imwrite(os.path.join(save_hourgh_dir,img_mark+'.jpg'),img)
            cv2.imwrite(os.path.join(save_seg_dir,img_mark+'.jpg'),img_copy)

if __name__=='__main__':
    main()


import json

# this will create a tweet, with possiblities of adding medias and replying to other tweets
def create_tweet(tas, message, media_ids = None, reply_ids = None):
	payload = {"status": message}

	if media_ids != None:
		payload["media_ids"] = media_ids

	if reply_ids != None:
		payload["in_reply_to_status_id"] = reply_ids

	r = tas.post("https://api.twitter.com/1.1/statuses/update.json", data = payload)
	resp = json.loads(r.text)

	if r.status_code == 200:
		tweet_id = resp["id"]
		return 0, (tweet_id,)

	return 1, (r.text,)

# this will delete a tweet based on a given tweet-id
def delete_tweet(tas, tweet_id):
	r = tas.delete(f"https://api.twitter.com/2/tweets/{tweet_id}")
	resp = json.loads(r.text)


import numpy as np
import time
import matplotlib.pyplot as plt

a=np.loadtxt('meas2/magnitude_0to40.0mA_freq_sweep.csv', delimiter=',')
c=np.loadtxt('meas2/phase_0to40.0mA_freq_sweep.csv', delimiter=',')
b=np.loadtxt('meas2/sweep_feq.csv', delimiter=',')

cstart=0 #start current
cstop=40E-3 # stop current
cstep=5E-3 # current step
csteps=int((cstop-cstart)/cstep)

fig, (ax0,ax1)=plt.subplots(2,1, sharex=True)
for i in range(csteps):
	current=cstart+i*cstep
	ax0.plot(b,a[:,i], label="{0:d}mA".format(int((current)*1000)))
	ax1.plot(b,c[:,i], label="{0:d}mA".format(int((current)*1000)))

ax1.set_xlabel("Larmor frequency in kHz")
ax1.axhline(y=0, color='r', ls='--')
plt.legend(prop={'size':6})
#plt.savefig('meas2/phase_amplitude.png')
plt.show()


from airflow.hooks.postgres_hook import PostgresHook
from airflow.models import BaseOperator
from airflow.utils.decorators import apply_defaults

class DataQualityOperator(BaseOperator):
    """
    Runs data quality check by passing test SQL

    Parameters
    redshift_conn_id: Redshift Connection ID
    test_sql: SQL query to run on Redshift for data validation
    expected_result: Expected result to match the test result.

    """

    ui_color = '#89DA59'

    @apply_defaults
    def __init__(self,
                 redshift_conn_id="",
                 test_sql="",
                 expected_result="",
                 *args, **kwargs):

        super(DataQualityOperator, self).__init__(*args, **kwargs)
        self.redshift_conn_id=redshift_conn_id
        self.test_sql=test_sql
        self.expected_result=expected_result

    def execute(self, context):
        self.log.info("Start data validation...")
        redshift_hook = PostgresHook(Postgres_conn_in=self.redshift_conn_id)

        self.log.info("Got credentials.")
        records=redshift_hook.get_records(self.test_sql)

        if records[0][0] != self.expected_result:
            raise ValueError(f"Data quality check failed. {records[0][0]} does not equal {self.expected_result}")
        else:
            self.log.info("Data quality check passed!!!")


CODE_OK = 200
CODE_CREATED = 201
CODE_NO_CONTENT = 204
CODE_BAD_REQUEST = 400
CODE_FORBIDDEN = 403
CODE_NOT_FOUND = 404
CODE_METHOD_NOT_ALLOWED = 405
CODE_NOT_ACCEPTABLE = 406
CODE_CONFLICT = 409

response_ok = {
    "status": "OK",
    "code": CODE_OK,
    "error": "",
    "data": "",
}

response_fail = {
    "status": "FAIL",
    "code": CODE_BAD_REQUEST,
    "error": "",
    "data": "",
}

# not used, may deprecate later
errors = {
    'UserAlreadyExistsError': {
        'message': "A user with that username already exists.",
        'status': CODE_CONFLICT,
        'extra': "NA",
    },
    'ResourceDoesNotExist': {
        'message': "A resource with that ID no longer exists.",
        'status': CODE_NOT_FOUND,
        'extra': "NA",
    },
    'InvalidParams': {
        'message': "Not valid param is given",
        'status': CODE_NOT_ACCEPTABLE,
        'extra': "NA",
    },
    'InvalidOperations': {
        'message': "Invalid operation method is given",
        'status': CODE_METHOD_NOT_ALLOWED,
        'extra': "NA",
    },
}


import numpy as np

def upper_confidence_bound(data):

	N = data.shape[0] # number of samples (Example: How many times add was shown, How many times machine was played)
	d = data.shape[1] # number of dfferent objects (Examples: Different ads, Bandit machines)

	#Ni(n) - the number of times the object 'i' was selected up until the nubmer n
	#Ri(n) - the sum of rewards of the object 'i' up to the number n

	#The idea is to have the best object at each iteration 1-n

	N_i_n = {}
	R_i_n = {}
	iter_object_selected = []
	#Setting starting values
	for i in range(d):
		N_i_n[i] = 0
		R_i_n[i] = 0

	total_results = 0

	#The main loop
	for sample in range(N):
		object_selected = 0
		max_upper_bound = 0

		for object_ in range(d):

			if N_i_n[object_] > 0:
				average_reward = R_i_n[object_]/N_i_n[object_]
				delta_of_object = np.sqrt(3/2 * np.log(sample+1) / N_i_n[object_])
				upper_bound = average_reward + delta_of_object

			else:
				upper_bound = float("+inf")

			if upper_bound > max_upper_bound:
				max_upper_bound = upper_bound
				object_selected = object_

		iter_object_selected.append(object_selected)
		N_i_n[object_selected] += 1

		reward = data[sample, object_selected]

		R_i_n[object_selected] +=  reward

		total_results +=  reward

	return iter_object_selected, total_results


#
# db.py
#
import os
import sqlite3
import time
import datetime
from flask import g
import db_init

def test_db_conn():
    dbname = os.environ.get("SEVENS_DB_NAME")

    try:
        os.remove(dbname)
    except OSError:
        pass
    """ Check if db connection can open, create and init db if doesn't already exist """
    print("********dbname: "+dbname)

    assert dbname is not None

    # If db file doesn't exist call the initialize module to create and init
    if not os.path.isfile(dbname):
        print("!!!!!!!!!dbname: "+dbname)
        db_init.init(dbname)

def get_db():
    dbname = os.environ.get("SEVENS_DB_NAME")
    assert dbname is not None

    if not hasattr(g,'sqlite_db'):
        g.sqlite_db = sqlite3.connect(dbname)
    return g.sqlite_db

def close_db():
    if hasattr(g,'sqlite_db'):
	    g.sqlite_db.close()

#     CREATE TABLE players (id INTEGER PRIMARY KEY AUTOINCREMENT, points INTEGER, name STRING);
def players_row_to_dict(row):
    players = {}
    players['id'] = row[0]
    players['points'] = row[1]
    players['name'] = row[2]
    return players

#CREATE TABLE hands (player_id INTEGER FOREIGN KEY, clubs STRING, hearts STRING, diamonds STRING, spades STRING);
def hands_row_to_dict(row):
    hands = {}
    hands['player_id'] = row[0]
    hands['clubs'] = str(row[1])
    hands['hearts'] = str(row[2])
    hands['diamonds'] = str(row[3])
    hands['spades'] = str(row[4])
    return hands

# CREATE TABLE board (cur_player_id INTEGER FOREIGN KEY, clubs STRING, hearts STRING, diamonds STRING, spades STRING);
def board_row_to_dict(row):
    board = {}
    board['cur_player_id'] = row[0]
    board['clubs'] = str(row[1])
    board['hearts'] = str(row[2])
    board['diamonds'] = str(row[3])
    board['spades'] = str(row[4])
    return board

def get_game_state():
    conn = get_db()
    curs = conn.cursor()
    rows = curs.execute ("SELECT * FROM board").fetchall()
    board = []
    for row in rows:
        b = board_row_to_dict(row)
        board.append(b)
    return board

def get_games():
    conn = get_db()
    curs = conn.cursor()
    rows = curs.execute ("SELECT * FROM games ORDER BY date").fetchall()
    games = []
    for row in rows:
        game = game_row_to_dict(row)
        games.append(game)
    return games

'''
def update_game(gameid,score,lines,user):
    conn = get_db()
    curs = conn.cursor()
    curs.execute("UPDATE games SET score=?, lines=?, user=?, haveResult=? WHERE id=?;",
                (score, lines, user, True, gameid))
    conn.commit()
    res = curs.execute("SELECT * FROM games WHERE id=?;",(gameid,)).fetchall()
    if len(res) != 0:
       return game_row_to_dict(res[0])
    else:
       return None

def add_access_log(game_id, func, method, auth, ip, user_agent):
    """ Add access log to global access_log list """
    conn = get_db()
    curs = conn.cursor()

    curs.execute("INSERT INTO accesslog (id, function, method, date, ipaddress, useragent, user) VALUES (?,?,?,?,?,?,?);", (game_id, func, method, time.time(),ip, user_agent, auth))
    conn.commit()

def get_access_logs():
    conn = get_db()
    curs = conn.cursor()
    rows = curs.execute ("SELECT * FROM accesslog ORDER BY date").fetchall()
    access_log = []
    for row in rows:
        access = accesslog_row_to_dict(row)
        access_log.append(access)
    return access_log

def get_rng_seed():
    """ Generate rng seed """
    return 0xDEADBEEF
'''


#Write a Python program to add 'ing' at the end of a given string (length should be at least 3).
# If the given string already ends with 'ing' then add 'ly' instead if the string length of the given string
# is less than 3, leave it unchanged

def add_string(str1):
    length = len(str1)

    if length > 2:
        if str1[-3:] =='ing':
           str1+= 'ly'
        else:
            str1 += 'ing'
    return str1
print(add_string('ab'))
print(add_string('abc'))
print(add_string('string'))

#Write a Python program to find the first appearance of the substring 'not' and 'poor' from a given string,
#  if 'not' follows the 'poor', replace the whole 'not'...'poor' substring with 'good'.
#  Return the resulting string

def not_poor(str1):
    snot = str1.find('not')
    spoor = str1.find('poor')

    if spoor > snot and snot>0 and spoor>0:
        str1 = str1.replace(str1[snot:(spoor+4)],'good')
        return str1
    else:
        return str1
print(not_poor('the lyrics is not that poor!'))
print(not_poor('the lyrics is poor!'))