import re
import pytest
from click.testing import CliRunner
from commands.validate import cli as validate

@pytest.mark.validation
class TestValidate:

    @pytest.mark.datafiles('tests/neoload_projects/example_1/default.yaml')
    def test_success(self, datafiles):
        file_path = datafiles.listdir()[0]
        runner = CliRunner()
        result = runner.invoke(validate, [str(file_path), '--refresh'])
        assert 'Yaml file is valid' in str(result.output)
        assert result.exit_code == 0

    @pytest.mark.datafiles('tests/neoload_projects/example_1/default.yaml')
    def test_no_refresh(self, datafiles):
        file_path = datafiles.listdir()[0]
        runner = CliRunner()
        result = runner.invoke(validate, [str(file_path)])
        assert 'Yaml file is valid' in str(result.output)
        assert result.exit_code == 0

    @pytest.mark.datafiles('tests/neoload_projects/invalid_to_schema.yaml')
    def test_error(self, datafiles):
        file_path = datafiles.listdir()[0]
        runner = CliRunner()
        result = runner.invoke(validate, [str(file_path), '--refresh'])
        assert 'Wrong Yaml structure' in str(result.output)
        assert 'Additional properties are not allowed (\'ifyourelookingforcutthroat\' was unexpected)' in str(
            result.output)
        assert 'On instance:\n{\'name\': \'NeoLoad-CLI-example-2_0' in str(result.output)
        assert result.exit_code == 1

    @pytest.mark.datafiles('tests/neoload_projects/example_1/default.yaml')
    def test_bad_schema(self, datafiles):
        file_path = datafiles.listdir()[0]
        runner = CliRunner()
        result = runner.invoke(validate, [str(file_path), '--schema-url', 'https://www.neotys.com/', '--refresh'])
        assert 'Error: This is not a valid json schema file' in str(result.output)
        assert 'Expecting value: line 1 column 1' in str(result.output)
        assert result.exit_code == 1

    def test_no_argument(self):
        runner = CliRunner()
        result = runner.invoke(validate)
        assert re.compile(".*Error: Missing argument [\"']FILE[\"'].*", re.DOTALL).match(result.output) is not None
        assert result.exit_code == 2

    @pytest.mark.slow
    @pytest.mark.datafiles('tests/neoload_projects/example_1/default.yaml')
    def test_bad_schema_url(self, datafiles):
        file_path = datafiles.listdir()[0]
        runner = CliRunner()
        result = runner.invoke(validate, [str(file_path), '--schema-url', 'http://invalid.fr', '--refresh'])
        assert 'Max retries exceeded with url' in str(result.output)
        assert 'Failed to establish a new connection' in str(result.output)
        assert 'Error getting the schema from the url: http://invalid.fr' in str(result.output)
        assert result.exit_code == 1


import unittest
import requests
import json
import mgr_functions

class TestQueryOrder(unittest.TestCase):
    def setUp(self):
        self.url = "http://172.16.17.148:8080/hzhotel/mgrweb-api/order/queryOrder"

    def testQueryOrder(self):
        token = mgr_functions.get_token()
        order_date = json.dumps({"head": {"token": token, "channel": "", "clientId": ""},
                                "currentPage": 1, "contactMobile": "", "orderNo": "", "pageSize": 10})
        headers = {
            'Content-Type': "application/json"
        }

        response = requests.request('POST', self.url, data=order_date, headers=headers)
        self.result = response.json()
        self.head = self.result['head']
        print(self.result['msg'])
        self.assertEqual(0, self.result['code'])

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


# TestGame.py
#
# Copyright (C) 2016 Abhijit Patel Here
#
# This program is free software; you can redistribute it
# and/or modify it under the terms of the GNU General
# Public License as published by the Free Software
# Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will
# be useful, but WITHOUT ANY WARRANTY; without even
# the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE.  See the GNU General Public
# License for more details.
#
# You should have received a copy of the GNU General
# Public License along with this program; if not, write
# to the Free Software Foundation, Inc., 51 Franklin
# St, Fifth Floor, Boston, MA 02110-1301  USA
#wormgame
import random, pygame, sys
from pygame.locals import *
from gi.repository import Gtk
FPS = 15
WINDOWWIDTH = 1000
WINDOWHEIGHT = 680
CELLSIZE = 20
assert WINDOWWIDTH % CELLSIZE == 0, "Window width must be a multiple of cell size."
assert WINDOWHEIGHT % CELLSIZE == 0, "Window height must be a multiple of cell size."
CELLWIDTH = int(WINDOWWIDTH / CELLSIZE)
CELLHEIGHT = int(WINDOWHEIGHT / CELLSIZE)

WHITE     = (255, 255, 255)
BLACK     = (  0,   0,   0)
RED       = (255,   0,   0)
GREEN     = (  0, 255,   0)
DARKGREEN = (  0, 155,   0)
DARKGRAY  = ( 40,  40,  40)
BGCOLOR = BLACK
BROWN     = (200, 128, 0)
BLUE      = (0, 0, 255)

UP = 'up'
DOWN = 'down'
LEFT = 'left'
RIGHT = 'right'
UP = 'up'
DOWN = 'down'
LEFT = 'left'
RIGHT = 'right'
FPSCLOCK= None
DISPLAYSURF=None
BASICFONT=None
HEAD = 0
HEAD = 0

def main():

    pygame.init()

    game = wormgame()

    game.run()

class wormgame:
    def __init__(self):
        pass
    def run(self):
        global FPSCLOCK, DISPLAYSURF, BASICFONT, WINDOWWIDTH, WINDOWHEIGHT
        DISPLAYSURF = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT))
        BASICFONT = pygame.font.Font('freesansbold.ttf', 18)
        pygame.display.set_caption('Wormy')
        FPSCLOCK = pygame.time.Clock()
        showStartScreen()
        startx = random.randint(2, CELLWIDTH - 6)
        starty = random.randint(1, 4)
        wormCoords = [{'x': startx,     'y': starty},
                      {'x': startx - 1, 'y': starty},
                      {'x': startx - 2, 'y': starty}]
        direction = RIGHT
        #showStartScreen()
        # Start the apple in a random place.
        apple = getRandomLocation()

        while True: # main game loop
            while Gtk.events_pending():
                Gtk.main_iteration()
            for event in pygame.event.get(): # event handling loop
                if event.type == QUIT:
                    terminate()
                elif event.type == pygame.KEYDOWN:

                    if (event.key == K_LEFT or event.key == K_a) and direction != RIGHT:
                        direction = LEFT
                    elif (event.key == K_RIGHT or event.key == K_d) and direction != LEFT:
                        direction = RIGHT
                    elif (event.key == K_UP or event.key == K_w) and direction != DOWN:
                        direction = UP
                    elif (event.key == K_DOWN or event.key == K_s) and direction != UP:
                        direction = DOWN
                    elif event.key == K_ESCAPE:
                        terminate()

            if wormCoords[HEAD]['x'] in range(12,32) and wormCoords[HEAD]['y'] == 22:
                showGameOverScreen() # game over
                is_true = True
                while is_true:
                     while Gtk.events_pending():
                         Gtk.main_iteration()

                     for event in pygame.event.get():

                        if event.type == pygame.KEYDOWN:

                           startx = random.randint(5, CELLWIDTH - 10)
                           starty = random.randint(29, CELLHEIGHT - 2)
                           wormCoords = [{'x': startx,     'y': starty},
                                         {'x': startx - 1, 'y': starty},
                                         {'x': startx - 2, 'y': starty}]
                           direction = RIGHT
                           apple = getRandomLocation()
                           is_true = False

            elif wormCoords[HEAD]['x'] in range(18,38) and wormCoords[HEAD]['y'] == 12:
                showGameOverScreen() # game over
                is_true = True
                while is_true:
                     while Gtk.events_pending():
                         Gtk.main_iteration()

                     for event in pygame.event.get():

                        if event.type == pygame.KEYDOWN:

                           startx = random.randint(5, CELLWIDTH - 10)
                           starty = random.randint(29, CELLHEIGHT - 3)
                           wormCoords = [{'x': startx,     'y': starty},
                                         {'x': startx - 1, 'y': starty},
                                         {'x': startx - 2, 'y': starty}]
                           direction = RIGHT
                           apple = getRandomLocation()
                           is_true = False
            elif wormCoords[HEAD]['x'] in range(12,44) and wormCoords[HEAD]['y'] == 6:
                showGameOverScreen() # game over
                is_true = True
                while is_true:
                     while Gtk.events_pending():
                         Gtk.main_iteration()

                     for event in pygame.event.get():

                        if event.type == pygame.KEYDOWN:

                           startx = random.randint(5, CELLWIDTH - 5)
                           starty = random.randint(29, CELLHEIGHT - 2)
                           wormCoords = [{'x': startx,     'y': starty},
                                         {'x': startx - 1, 'y': starty},
                                         {'x': startx - 2, 'y': starty}]
                           direction = RIGHT
                           apple = getRandomLocation()
                           is_true = False
            elif wormCoords[HEAD]['x'] in range(6,44) and wormCoords[HEAD]['y'] == 28:
                showGameOverScreen() # game over
                is_true = True
                while is_true:
                     while Gtk.events_pending():
                         Gtk.main_iteration()

                     for event in pygame.event.get():

                        if event.type == pygame.KEYDOWN:

                           startx = random.randint(5, CELLWIDTH - 10)
                           starty = random.randint(29, CELLHEIGHT - 3)
                           wormCoords = [{'x': startx,     'y': starty},
                                         {'x': startx - 1, 'y': starty},
                                         {'x': startx - 2, 'y': starty}]
                           direction = RIGHT
                           apple = getRandomLocation()
                           is_true = False

            elif wormCoords[HEAD]['x'] == 6 and wormCoords[HEAD]['y'] in range(6,28):
                showGameOverScreen() # game over
                is_true = True
                while is_true:
                     while Gtk.events_pending():
                          Gtk.main_iteration()
                     for event in pygame.event.get():

                        if event.type == pygame.KEYDOWN:

                            startx = random.randint(5, CELLWIDTH - 10)
                            starty = random.randint(29, CELLHEIGHT - 3)
                            wormCoords = [{'x': startx,     'y': starty},
                                          {'x': startx - 1, 'y': starty},
                                          {'x': startx - 2, 'y': starty}]
                            direction = RIGHT
                            apple = getRandomLocation()
                            is_true = False
            elif wormCoords[HEAD]['x'] == 12 and wormCoords[HEAD]['y'] in range(12,22):
                showGameOverScreen() # game over
                is_true = True
                while is_true:
                     while Gtk.events_pending():
                          Gtk.main_iteration()
                     for event in pygame.event.get():

                        if event.type == pygame.KEYDOWN:

                           startx = random.randint(3, CELLWIDTH - 5)
                           starty = random.randint(1, 5)
                           wormCoords = [{'x': startx,     'y': starty},
                                         {'x': startx - 1, 'y': starty},
                                         {'x': startx - 2, 'y': starty}]
                           direction = RIGHT
                           apple = getRandomLocation()
                           is_true = False
            elif wormCoords[HEAD]['x'] == 38 and wormCoords[HEAD]['y'] in range(12,22):
                showGameOverScreen() # game over

                is_true = True
                while is_true:
                     while Gtk.events_pending():
                          Gtk.main_iteration()
                     for event in pygame.event.get():

                        if event.type == pygame.KEYDOWN:

                           startx = random.randint(2, 7)
                           starty = random.randint(1, 5)
                           wormCoords = [{'x': startx,     'y': starty},
                                         {'x': startx - 1, 'y': starty},
                                         {'x': startx - 2, 'y': starty}]
                           direction = RIGHT
                           apple = getRandomLocation()
                           is_true = False

            elif wormCoords[HEAD]['x'] == 44 and wormCoords[HEAD]['y'] in range(6,22):
                showGameOverScreen() # game over

                is_true = True
                while is_true:
                     while Gtk.events_pending():
                          Gtk.main_iteration()
                     for event in pygame.event.get():

                        if event.type == pygame.KEYDOWN:

                           startx = random.randint(3, CELLWIDTH - 5)
                           starty = random.randint(29, CELLHEIGHT - 2)
                           wormCoords = [{'x': startx,     'y': starty},
                                         {'x': startx - 1, 'y': starty},
                                         {'x': startx - 2, 'y': starty}]
                           direction = RIGHT
                           apple = getRandomLocation()
                           is_true = False
            for wormBody in wormCoords[1:]:
                if wormBody['x'] == wormCoords[HEAD]['x'] and wormBody['y'] == wormCoords[HEAD]['y']:
                    showGameOverScreen() # game over
                    is_true = True
                    while is_true:
                     while Gtk.events_pending():
                        Gtk.main_iteration()
                     for event in pygame.event.get():

                        if event.type == pygame.KEYDOWN:

                          startx = random.randint(5, CELLWIDTH - 10)
                          starty = random.randint(29, CELLHEIGHT - 2)
                          wormCoords = [{'x': startx,     'y': starty},
                                        {'x': startx - 1, 'y': starty},
                                        {'x': startx - 2, 'y': starty}]
                          direction = RIGHT
                          apple = getRandomLocation()
                          is_true = False
            # check if worm has eaten an apply
            if wormCoords[HEAD]['x'] == apple['x'] and wormCoords[HEAD]['y'] == apple['y']:
                # don't remove worm's tail segment
                apple = getRandomLocation() # set a new apple somewhere
            else:
                del wormCoords[-1] # remove worm's tail segment

            # move the worm by adding a segment in the direction it is moving
            if wormCoords[HEAD]['x'] == CELLWIDTH:
                   wormCoords[HEAD]['x'] = 0

            if wormCoords[HEAD]['x'] == -1:
                   wormCoords[HEAD]['x'] = CELLWIDTH

            if wormCoords[HEAD]['y'] == CELLHEIGHT:
                   wormCoords[HEAD]['y'] = 0

            if wormCoords[HEAD]['y'] == -1:
                   wormCoords[HEAD]['y'] = CELLHEIGHT

            if direction == UP:
                newHead = {'x': wormCoords[HEAD]['x'], 'y': wormCoords[HEAD]['y'] - 1}
            elif direction == DOWN:
                newHead = {'x': wormCoords[HEAD]['x'], 'y': wormCoords[HEAD]['y'] + 1}
            elif direction == LEFT:
                newHead = {'x': wormCoords[HEAD]['x'] - 1, 'y': wormCoords[HEAD]['y']}
            elif direction == RIGHT:
                newHead = {'x': wormCoords[HEAD]['x'] + 1, 'y': wormCoords[HEAD]['y']}
            wormCoords.insert(0, newHead)
            DISPLAYSURF.fill(WHITE)

            drawWorm(wormCoords)
            drawApple(apple)
            drawwalls()
            drawScore(len(wormCoords) - 3)
            pygame.display.update()
            FPSCLOCK.tick(FPS)

def drawPressKeyMsg():
     pressKeySurf = BASICFONT.render('Press a key to play.', True, BLACK)
     pressKeyRect = pressKeySurf.get_rect()
     pressKeyRect.topleft = (WINDOWWIDTH - 200, WINDOWHEIGHT - 30)
     DISPLAYSURF.blit(pressKeySurf, pressKeyRect)

def checkForKeyPress():

     for event1 in pygame.event.get():

       if event1.type == pygame.KEYUP:

         return True
def showGameOverScreen():
     gameOverFont = pygame.font.Font('freesansbold.ttf', 150)
     gameSurf = gameOverFont.render('Game', True, BLACK)
     overSurf = gameOverFont.render('Over', True, BLACK)
     gameRect = gameSurf.get_rect()
     overRect = overSurf.get_rect()
     gameRect.midtop = (WINDOWWIDTH / 2, 10)
     overRect.midtop = (WINDOWWIDTH / 2, gameRect.height + 10 + 25)

     DISPLAYSURF.blit(gameSurf, gameRect)
     DISPLAYSURF.blit(overSurf, overRect)
     drawPressKeyMsg()
     pygame.display.update()
     pygame.time.wait(500)
     return

def showStartScreen():
     snakefont = pygame.font.Font('freesansbold.ttf', 100)
     snakesurf1 = snakefont.render('Wormy', True, BLUE)
     snakesurf2 = snakefont.render('Game!', True, BLUE)
     movx = WINDOWWIDTH / 2
     movy = 50
     DISPLAYSURF.fill(WHITE)
     snakerect1 = snakesurf1.get_rect()
     snakerect1.topright = (movx,movy)
     DISPLAYSURF.blit(snakesurf1,snakerect1)
     snakerect2 = snakesurf2.get_rect()
     snakerect2.topright = (movx,movy+100)
     DISPLAYSURF.blit(snakesurf2,snakerect2)

     drawPressKeyMsg()
     movx += 10
     movy = 50

     pygame.display.update()
     FPSCLOCK.tick(10)
     si_true = True
     while si_true:
          while Gtk.events_pending():
                Gtk.main_iteration()
          for event in pygame.event.get():

                if event.type == pygame.KEYUP:
                    si_true = False
                    return

def terminate():
     pygame.quit()
     sys.exit()

def getRandomLocation():
    p = random.randint(0, CELLWIDTH - 1)
    q = random.randint(0, CELLHEIGHT - 1)
    if p in range(12,32) and q == 22:
       p = 5
       q = random.randint(0, CELLHEIGHT - 1)
    if p in range(18,38) and q == 12:
       p = 2
       q = random.randint(0, CELLHEIGHT - 1)
    if p in range(12,44) and q == 6:
       p = 25
       q = random.randint(13, 21)
    if p in range(6,44) and q == 28:
       p = 27
       q = random.randint(13, 19)
    elif p == 6 and q in range(6,28):
       p = 46
       q = random.randint(0, CELLHEIGHT - 1)
    elif p == 12 and q in range(12,22):
       p = 47
       q = random.randint(0, CELLHEIGHT - 1)
    elif p == 38 and q in range(12,22):
       p = 48
       q = random.randint(0, CELLHEIGHT - 1)
    elif p == 44 and q in range(6,22):
       p = 22
       q = random.randint(14, 20)
    else:
        p=p
        q=q
    return {'x': p, 'y': q}

def drawScore(score):
    scoreSurf = BASICFONT.render('Score: %s' % (score), True, BLACK)
    scoreRect = scoreSurf.get_rect()
    scoreRect.topleft = (WINDOWWIDTH - 120, 10)
    DISPLAYSURF.blit(scoreSurf, scoreRect)

def drawwalls():
    wallsrect = pygame.Rect(120, 120, CELLSIZE, 440)
    pygame.draw.rect(DISPLAYSURF, BROWN, wallsrect)

    wallsrecta = pygame.Rect(240, 240, CELLSIZE, 200)
    pygame.draw.rect(DISPLAYSURF, BROWN, wallsrecta)

    wallsrectb = pygame.Rect(120, 560, 760, CELLSIZE)
    pygame.draw.rect(DISPLAYSURF, BROWN, wallsrectb)

    wallsrectc = pygame.Rect(240, 440, 400, CELLSIZE)
    pygame.draw.rect(DISPLAYSURF, BROWN, wallsrectc)

    wallsrectc = pygame.Rect(240, 120, 640, CELLSIZE)
    pygame.draw.rect(DISPLAYSURF, BROWN, wallsrectc)

    wallsrectc = pygame.Rect(880, 120, CELLSIZE, 320)
    pygame.draw.rect(DISPLAYSURF, BROWN, wallsrectc)

    wallsrectc = pygame.Rect(360, 240, 400, CELLSIZE)
    pygame.draw.rect(DISPLAYSURF, BROWN, wallsrectc)

    wallsrectc = pygame.Rect(760, 240, CELLSIZE, 200)
    pygame.draw.rect(DISPLAYSURF, BROWN, wallsrectc)

def drawWorm(wormCoords):
    for coord in wormCoords:
        x = coord['x'] * CELLSIZE
        y = coord['y'] * CELLSIZE
        wormSegmentRect = pygame.Rect(x, y, CELLSIZE, CELLSIZE)
        pygame.draw.rect(DISPLAYSURF, GREEN, wormSegmentRect)
        wormInnerSegmentRect = pygame.Rect(x + 3, y + 3, CELLSIZE -6 , CELLSIZE - 6)
        pygame.draw.rect(DISPLAYSURF, BLUE, wormInnerSegmentRect)

def drawApple(apple):
    x = apple['x'] * CELLSIZE
    y = apple['y'] * CELLSIZE
    appleRect = pygame.Rect(x, y, CELLSIZE, CELLSIZE)
    pygame.draw.rect(DISPLAYSURF, RED, appleRect)

if __name__ == '__main__':
    main()


from tkinter import *
from tkinter import ttk
from tkinter.ttk import Frame, Button
from PIL import Image as PilImage
from PIL import ImageTk
from docxtpl import DocxTemplate
from tkinter import messagebox as mb
from tkinter.scrolledtext import ScrolledText
import docx as dc

from collections import Counter
from openpyxl import load_workbook
import re

class Window4:
    def __init__(self, parent, width, height, title="Генератор Рабочей программы дисциплины", resizable=(False, False),
                 icon=r"main.ico"):
        self.root = Toplevel(parent)
        self.root.title(title)
        self.root.geometry(f"{width}x{height}+200+200")
        self.root.resizable(resizable[0], resizable[1])
        self.root.config(bg="#1f4b99")

        img = PilImage.open('images/add_png.png')
        img = img.resize((18, 18), PilImage.ANTIALIAS)
        self.photo_image = ImageTk.PhotoImage(img)

        img3 = PilImage.open('images/help_png.png')
        img3 = img3.resize((18, 18), PilImage.ANTIALIAS)
        self.photo_image3 = ImageTk.PhotoImage(img3)

        self.root.iconbitmap('images/osu2.ico')

        self.frm_form = LabelFrame(self.root, relief=SUNKEN, borderwidth=3, text="Планируемые результаты обучения")
        self.frm_form.pack(fill=X, ipadx=30, ipady=30, padx=10)

        self.label_text1 = Label(self.frm_form,
                                 text=
                                 "Добавьте несколько компетенций с помощью кнопки 'Добавить'"
                                 " и сохраните изменения").pack()
        self.label_text = Label(self.frm_form, text="Код компетенции").pack()

        self.combobox = ttk.Combobox(self.frm_form, values=[
            'УК-1',
            'УК-2',
            'УК-3',
            'УК-4',
            'УК-5',
            'УК-1',
            'УК-6','УК-7','УК-8','УК-9','ОПК-1','ОПК-2','ОПК-3','ОПК-4','ПК-1','ПК-2','ПК-3','ПК-4','ПК-5','ПК-6','ПК-7','ПК-8',
            'ПК-9','ПК-10','ПК-11','ПК-12','ПК-13','ПК-14',
            'ПК-15','ПК-16','ПК-20','ПК-21','ПК-22','ПК-23','ПК-24'])
        self.combobox.pack()

        self.frm_buttons = Frame(self.root)
        self.frm_buttons.pack(fill=X, ipadx=5, ipady=5)

        self.btn_submit = Button(self.frm_buttons, text="Добавить", image=self.photo_image, compound=LEFT,
                                 command=self.add_zuv)
        self.btn_submit.pack(side=LEFT, padx=10, ipadx=10)

        self.btn_clear = Button(self.frm_buttons, text="Сохранить", command=self.save_zuv)
        self.btn_clear.pack(side=LEFT, padx=10, ipadx=10)

        self.btn_help = Button(self.frm_buttons, image=self.photo_image3)
        self.btn_help.pack(side=LEFT, padx=10, ipadx=10)

        self.f_top = Frame(self.frm_form)  # frame для текста
        self.f_mid = Frame(self.frm_form)
        self.f_bot = Frame(self.frm_form)

        self.text_edit = ScrolledText(self.f_top, width=5, height=1, font=("Times New Roman", 11), wrap=WORD)
        self.label_text = Label(self.frm_form, text="Описание компетенции").pack()
        self.text_edit2 = ScrolledText(self.f_top, width=45, height=10, font=("Times New Roman", 11), wrap=WORD)
        self.text_edit3 = ScrolledText(self.f_mid, width=5, height=1, font=("Times New Roman", 11), wrap=WORD)
        self.text_edit4 = ScrolledText(self.f_mid, width=45, height=10, font=("Times New Roman", 11), wrap=WORD)

        self.f_top.pack()
        self.f_mid.pack()

        self.text_edit.pack(side=LEFT)
        self.text_edit2.pack(side=LEFT)
        self.text_edit3.pack(side=LEFT)
        self.text_edit4.pack(side=LEFT)

        self.filename1 = "data/Компетенции.xlsx"

        self.spisok_kod = []
        self.description_zuv = []
        zuv = []

        self.add_kod_zuv_spisok = []
        self.add_zuv_spisok = []

        self.spisok_z = []
        self.spisok_u = []
        self.spisok_v = []

        self.zuv1 = []
        self.zuv2 = []
        self.zuv3 = []

        self.wb = load_workbook(self.filename1)
        self.sheet = self.wb['Лист1']
        self.parcing()

    def parcing(self):
        for row in self.sheet['A1':'A34']:
            string = ''
            for cell in row:
                string = string + str(cell.value)
                your_string = string
            self.spisok_kod.append(your_string)

        for row in self.sheet['B1':'B34']:
            string = ''
            for cell in row:
                string = string + str(cell.value)
                your_string = string
            self.description_zuv.append(your_string)

        for row in self.sheet['C1':'C5']:
            string = ''
            for cell in row:
                string = string + str(cell.value)
                your_string = string
            self.zuv1.append(your_string)

        for row in self.sheet['D1':'D5']:
            string = ''
            for cell in row:
                string = string + str(cell.value)
                your_string = string
            self.zuv2.append(your_string)

        for row in self.sheet['E1':'E5']:
            string = ''
            for cell in row:
                string = string + str(cell.value)
                your_string = string
            self.zuv3.append(your_string)

        # self.text_edit.insert(1.0, self.description_zuv)
        # print(self.description_zuv[0])

    def add_zuv(self):
        self.text_edit.delete(1.0, END)
        self.text_edit2.delete(1.0, END)

        self.text_edit.insert(1.0, self.combobox.get())
        self.text_edit2.insert(1.0, self.description_zuv[self.combobox.current()])
        self.text_edit3.insert(2.0, self.combobox.get())
        self.text_edit4.insert(2.0, self.description_zuv[self.combobox.current()] + '\n\n')

        self.add_kod_zuv_spisok.append(self.combobox.get())
        self.add_zuv_spisok.append(self.description_zuv[self.combobox.current()])
        self.spisok_z.append(self.zuv1[self.combobox.current()])
        self.spisok_u.append(self.zuv2[self.combobox.current()])
        self.spisok_v.append(self.zuv3[self.combobox.current()])
    def save_zuv(self):
        doc = DocxTemplate("data/RPD3.docx")

        context = {'description1': self.add_zuv_spisok[0], 'kod_komp1': self.add_kod_zuv_spisok[0],
                   'description2': self.add_zuv_spisok[1], 'kod_komp2': self.add_kod_zuv_spisok[1],
                   'zuv1_1': self.spisok_z[0], 'zuv1_2': self.spisok_u[0], 'zuv1_3': self.spisok_v[0],
                   'zuv2_1': self.spisok_z[1], 'zuv2_2': self.spisok_u[0], 'zuv2_3': self.spisok_v[0]
                   }
        doc.render(context)
        doc.save("готовые программы/рабочая программа.docx")
        mb.showinfo("Внимание", "Планируемые результаты обучения сформированы")


"""
使用numpy实现卷积核的运算
"""
import numpy as np
import cv2

def concolve(datMat, kernel):
    """
    :param datMat: 要处理的数据
    :param kernel: 卷积核
    :return:处理完的数据
    """
    # 获取形状
    m = datMat.shape[0]
    n = datMat.shape[1]
    km = kernel.shape[0]
    kn = kernel.shape[1]
    # 创建全“1”数组
    newMat = np.ones((m, n), dtype=np.uint8)
    tempMat = np.ones((km, kn), dtype=np.uint8)

    for row in range(m - km + 1):
        for col in range(n - kn + 1):
            for m_k in range(km):
                for n_k in range(kn):
                    tempMat[m_k, n_k] = datMat[(row + m_k), (col + n_k)] * kernel[m_k, n_k]
            newMat[row, col] = np.sum(tempMat)

    return newMat

Core = np.array(((-0.1, 2, 0.1),
                (-0.2, 0, 0.2),
                (1, -2, -1)), dtype=np.uint8)
imgCore = np.array(((-0.1, 2, 0.1, 0),
                    (-0.2, 0, 0.2, 0),
                    (1, -2, -1, 0),
                    (0, 0, 0, 0)), dtype=np.uint8)

img = cv2.imread('./picture.jpg')
img = cv2.resize(img, (640, 480))
# cv2.imshow('Demo_0', img)
img_nov = cv2.filter2D(img, -1, Core)
cv2.imshow('Demo_1', img_nov)
img_nov = concolve(imgCore, Core)

cv2.waitKey(0)
cv2.destroyAllWindows()


"""Verify that a climate file is well formed."""
import sys
import datetime

def main(argv):
    """Run for a given file."""
    fn = argv[1]
    lines = open(fn).readlines()
    tokens = lines[4].strip().split()
    syear = int(tokens[4])
    # simyears = int(tokens[5])
    linenum = 15
    yesterday = datetime.date(syear - 1, 12, 31)
    while linenum < len(lines):
        tokens = lines[linenum].split()
        if len(tokens) < 4:
            print("linenum: %s has len(tokens): %s" % (linenum, len(tokens)))
            sys.exit()
        thisdate = datetime.date(
            int(tokens[2]), int(tokens[1]), int(tokens[0])
        )
        if (thisdate - yesterday) != datetime.timedelta(days=1):
            print(
                "linenum: %s has date: %s, not %s"
                % (linenum, thisdate, yesterday + datetime.timedelta(days=1))
            )
            sys.exit()
        yesterday = thisdate
        lastprecip = -1
        for _ in range(int(tokens[3])):
            linenum += 1
            tokens = lines[linenum].split()
            if len(tokens) != 2:
                print("linenum: %s has bad token count" % (linenum,))
                sys.exit()
            tm = float(tokens[0])
            if tm < 0 or tm >= 24:
                print("linenum: %s has bad time: %s" % (linenum, tokens[0]))
                sys.exit()
            precip = float(tokens[1])
            if precip < 0 or precip >= 350:
                print("linenum: %s has bad precip: %s" % (linenum, tokens[1]))
                sys.exit()
            if precip <= lastprecip:
                print(
                    "linenum: %s has decreasing precip: %s, last %s"
                    % (linenum, tokens[1], lastprecip)
                )
                sys.exit()
            lastprecip = precip
        linenum += 1

if __name__ == "__main__":
    main(sys.argv)


from qiskit import QuantumCircuit,QuantumRegister,ClassicalRegister
from qiskit import Aer,IBMQ
from qiskit import execute
from qiskit.tools import visualization
from qiskit.tools.visualization import circuit_drawer, plot_histogram
import matplotlib.pyplot as plt
from executeCircuit import execute_locally,extractClassical
import random as r
from qAlgorithms import QMF
import math
import random
import numpy as np
import sys
from qiskit.aqua.components.initial_states import Custom

#######################################################################
############ QMF TEST FOR A UNIFORM SUPERPOSITION STATE ###############
########################## FUNCTIONAL #################################
#######################################################################

n = 4 # quantum state will have 2**n superposition states
superpositions = 2**n
maximum_expected = superpositions-1

#IN THIS CASE THE MAXIMUM WILL BE |1111> = 15

qstate = QuantumRegister(n,name="qstate") #quantum register that contains the superposition
new_qr = QuantumRegister(n,name="new_qr") #qantum register for qmf measuring test
qc = QuantumCircuit(qstate,new_qr)

qc.h(qstate)
qc.h(new_qr) #new_qr will be measured as |0001> = 1

'''
	INIT PARAMS FOR THE QUANTUM MAXIMUM FINDING ALG

__init__(self, circuit=None,search_register=None,num_iterations=None, max_index=None, extra_registers=None,size=None):

#############################################################################################
	IF WITH A UNIFORM SUPERPOSITION STATE LIKE qstate WE CHOOSE INITIAL index = 0 or 1,
	WHAT HAPPENS IS THAT THE ORACLE WILL MARK ABOUT N-1 OR N-2 TERMS IN THE SUPERPOSITION
	AND SO, THE AVERAGE WILL BECOME NEGATIVE, AND THE INVERSION ABOUT MEAN OPERATOR WILL
	NOT WORK PROPERLY, MEANING THAT THE PROBABILITY OF COLLAPSING INTO 0 OR 1 INSTEAD OF
	OF AN ACTUAL SOLUTION WILL BECOME LARGER AND LARGER MAKING REACHING THE MAXIMUM IMPOSSIBLE
	IN THESE CASES RANDOMLY CHOOSING AN INTIAL GUESS, IS THE BEST STRATEGY FOR ACHIEVING
	THE MAXIMUM.
##############################################################################################
'''

index = int(sys.argv[1])
alg = QMF(circuit=qc,search_register=qstate,size=superpositions,max_index=index,extra_registers=[new_qr])

Backend = Aer.get_backend('qasm_simulator')
maximum, top_measurement = alg.run(backend=Backend,shots=1024)

#measured_val = result['result']
#maximum = result['top_measurement']

print("MAXIMUM SHOULD BE |",np.binary_repr(maximum_expected,n),"> = %d" % maximum_expected)
print("MAXIMUM ACHIEVED - %d\n" % maximum)
print("TOP MEASUREMENT\n",top_measurement)

#######################################################################
############ QMF TEST FOR AN ARBITRAY CUSTOM INTIAL STATE #############
########################## FUNCTIONAL #################################
#######################################################################
'''
state vector array - > numpy array [[Real,imaginary], ... ] for all superposition state
For n=4 qubits the first term encodes the amplitude of the state |0000> the second term encodes |0001> and so one.

For n=4 i'll create the state = |s> = 1/sqrt(2) ( |0100> + |0010> ) and QMF should return
|0100> = 4 as the maximum value within the state.
'''

state=[]
for i in range(2**n):
	if i == 4 or i == 2:
		state.append(complex(1/math.sqrt(2),0.0))
	else:
		state.append(complex(0.0,0.0))

state = np.asarray(state)

quantum_state = Custom(n,state_vector=state)

index = int(sys.argv[1])
alg = QMF(initial_state=quantum_state,search_register=qstate,size=superpositions,max_index=index)

Backend = Aer.get_backend('qasm_simulator')
maximum, top_measurement = alg.run(backend=Backend,shots=1024)

#measured_val = result['result']
#maximum = result['top_measurement']

print("MAXIMUM SHOULD BE |0100> = 4\n")
print("MAXIMUM ACHIEVED - %d\n" % maximum)
print("TOP MEASUREMENT\n",top_measurement)

###########################################################################
############ QMF TEST FOR A STATE THATS NOT IN SUPERPOSITION ##############
########################## FUNCTIONAL #####################################
###########################################################################
'''
Test if the quantum maximum finding algorithm can find the maximum in a register
tht's not in superposition, qstate, however it is conditioned by another register, h_state, that's in superposition.

qc has 2 CNOT gates , the result should be |psi> = |11>|11> , giving the maximum on the qstate register of |qstate> = |11> = 3
'''
h_state = QuantumRegister(2,name="hstate")
qstate = QuantumRegister(2,name="qstate")
qc= QuantumCircuit(h_state,qstate)

h_size = 4

qc.h(h_state)
qc.cx(h_state[0],qstate[0])
qc.cx(h_state[1],qstate[1])

alg = QMF(circuit=qc,search_register=qstate,size=h_size,extra_registers=[h_state],draw_circuit=True)

Backend = Aer.get_backend('qasm_simulator')
maximum, top_measurement = alg.run(backend=Backend,shots=1024)

#measured_val = result['result']
#maximum = result['top_measurement']

print("MAXIMUM SHOULD BE |1> = 1\n")
print("MAXIMUM ACHIEVED - %d\n" % maximum)
print("TOP MEASUREMENT\n",top_measurement)


from TexasHoldemConstants import *
from TexasHoldemDeck import *
from Player import *
from TexasHoldemComparisonEngine import *
from random import randint
import time

import pymongo
from bson.objectid import ObjectId

class TexasHoldem:
    def __init__(self,
            humans=0,
            bots=2,
            ante=0,
            buyIn=None,
            minimumFirstBet=10,
            statisticsMode=False,
            clearDB=False,
            pymongoClientHost="localhost",
            pymongoClientPort=27017,
            autoStart=True,
            verbose=False,
            debug=False,
            showBotCards=False,
            readable=False,
            readTime=3
        ):

        if(buyIn is None):
            buyIn = 500

        self.Verbose = verbose
        self.Debug = debug
        self.ShowBotCards = (self.Verbose and showBotCards)
        self.Readable = readable
        self.ReadTime = readTime
        self.PlayerCount = humans + bots
        self.Humans = humans
        self.Bots = bots
        self.BUY_IN = buyIn
        self.MINIMUM_FIRST_BET = minimumFirstBet
        self.Deck = TexasHoldemDeck()
        self.FlopCards = []
        self.TurnCard = None
        self.RiverCard = None
        self.CommunityCards = []
        self.Pot = 0
        self.Rounds = 0
        self.Comparison = TexasHoldemComparisonEngine()
        self.StatisticsMode = statisticsMode
        self.PymongoClientHost = pymongoClientHost
        self.PymongoClientPort = pymongoClientPort
        self.PymongoClient = pymongo.MongoClient(self.PymongoClientHost, self.PymongoClientPort)
        self.PymongoDB = self.PymongoClient.texasholdem
        self.GameId = None
        self.RoundId = None
        self.HumansInRound = 0
        self.FirstBetMade = False
        self.MinimumBet = 0

        if self.Debug:
            self.Verbose = True

        if clearDB:
            self.PymongoDB.hands.drop()
            self.PymongoDB.winning_hands.drop()
            self.PymongoDB.split_hands.drop()
            self.PymongoDB.losing_hands.drop()
            self.PymongoDB.games.drop()
            self.PymongoDB.rounds.drop()

        if(autoStart):
            self.NewGame()

    def CanShowCards(self, player):
        if self.HumansInRound <= 0:
            return True

        if player.IsHuman():
            return True

        if player.IsBot() and self.ShowBotCards:
            return True

        if self.RoundSection == SHOWDOWN:
            return True

        return False

    def __str__(self):
        s = "\nGame Status: \n"

        if(len(self.FlopCards) > 0):
            s += "Flop: "
            for c in range(len(self.FlopCards)):
                card = self.FlopCards[c]
                s += str(card)
                if(not c == len(self.FlopCards)-1):
                    s += ', '
            s += "\n"

        if(self.TurnCard is not None):
            s += "Turn: " + str(self.TurnCard) + "\n"

        if(self.RiverCard is not None):
            s += 'River: ' + str(self.RiverCard) + "\n"

        if(len(self.Players) > 0):
            s += '\n'
            for p in range(len(self.Players)):
                player = self.Players[p]
                s += player.Name + ' (' + str(player.Chips) + '): '
                if self.CanShowCards(player):
                    for c in range(len(player.Hand)):
                        s += str(player.Hand[c])
                        if(not c == len(player.Hand) - 1):
                            s += ', '

                    if(player.HandValue >= HIGH_CARD):
                        s += ' (' + str(self.Comparison.HandValueString(player.HandValue)) + ')'

                if(player.Folded):
                    s += ' [FOLDED]'

                s += '\n'

        return s

    def AddPlayer(self, name=None, buyIn=None, controlled=False):
        playerNumber = len(self.Players)

        if(buyIn is None):
            buyIn = self.BUY_IN

        if(name is None):
            name = "Player " + str(playerNumber+1)

        self.Players.append(Player(playerNumber=playerNumber, name=name, chips=buyIn, controlled=controlled))

    def Deal(self):
        if self.Verbose:
            print("-------------------------------- DEAL -----------------------------------------")

        for r in range(2):
            for i in range(len(self.Players)):
                player = self.Players[i]
                card = self.Deck.DrawCardFromTop()
                player.TakeCard(card)

                if(self.Verbose and self.CanShowCards(player)):
                    print(player.Name + ' dealt ' + str(card))

    def PlayerBet(self, player):
        if self.Debug and self.Verbose:
            print(player.Name, ' is making a player bet')

        bet = 0
        if player.Chips > 1:
            if player.IsHuman():
                while bet < self.MINIMUM_FIRST_BET:
                    betInput = input(player.Name + ', place a bet: ')
                    bet = int(betInput)

                    if bet > player.Chips:
                        bet = player.Chips

                    if bet < self.MINIMUM_FIRST_BET and self.Verbose:
                        print(player.Name, ', you must bet at least: ', self.MINIMUM_FIRST_BET)
            else:
                while bet < 1 or bet > player.Chips:
                    minBet = self.MinimumBet
                    maxBet = self.MinimumBet + int(0.5*player.Chips) + 1
                    bet = randint(minBet, maxBet)

                    if self.Debug and self.Verbose:
                        print('Min Bet: ', minBet, ', Max Bet: ', maxBet, ', Bet: ', bet)
        else:
            bet = player.Chips

            if self.Debug and self.Verbose:
                print(player.Name, ' only has ', bet, ' chips to bet')

        self.Pot += player.PlaceBet(bet)
        self.MinimumBet = bet

        self.FirstBetMade = True

        if self.Verbose:
            print(player.Name, ' bets ', bet)

    def PlayerCall(self, player):
        self.Pot += player.Call(self.MinimumBet)

        if self.Verbose:
            print(player.Name, ' calls')

    def PlayerCheck(self, player):
        player.Check()

        if self.Verbose:
            print(player.Name, ' checks')

    def PlayerRaise(self, player):
        if self.Debug and self.Verbose:
            print('Player has chosen to raise')

        if player.Chips > self.MinimumBet:
            raiseChips = 0
            if player.IsHuman():
                while raiseChips <= 0:
                    raiseChips = int(input(player.Name + ', enter the amount you would like to raise by: '))
            else:
                while raiseChips < 1 or raiseChips > (player.Chips):
                    minRaise = self.MinimumBet + 1
                    maxRaise = player.Chips
                    raiseChips = randint(minRaise, maxRaise)

                    if self.Debug and self.Verbose:
                        print('Min Raise: ', minRaise, ', Max Raise: ', maxRaise, ', Actual Raise: ', raiseChips)

            self.Pot += player.Raise(self.MinimumBet, raiseChips)
            self.MinimumBet = self.MinimumBet + raiseChips

            if self.Verbose:
                print(player.Name, ' raises by ', raiseChips)
        else:
            # assume they meant 'call'
            self.Pot += player.Call(self.MinimumBet)

            if self.Verbose:
                print('Player could not raise, called instead')

    def PlayerFold(self, player):
        player.Fold()

        if player.IsHuman():
            self.HumansInRound -= 1

        if self.Verbose:
            print(player.Name, ' folds')

    def TakeBets(self):
        if self.Verbose:
            print("------------------------------- TAKING BETS ------------------------------------")

        self.FirstBetMade = False
        doneBetting = False
        self.MinimumBet = 0
        # while not doneBetting:

        if self.Debug and self.Verbose:
            print('About to take first round of bets')

        for p in range(len(self.Players)):
            player = self.Players[p]

            if not player.Folded:
                if not self.FirstBetMade:
                    if self.Debug and self.Verbose:
                        print('Have not made first bet')

                    # options are to bet, check
                    check = False
                    if player.IsHuman():
                        checkBet = input(player.Name + ' check or bet? (K/b)')
                        if checkBet == 'k' or checkBet == 'K' or checkBet == 'c' or checkBet == 'C':
                            check = True
                    else:
                        check = (randint(0, 10) == 5)

                    if check and not self.StatisticsMode:
                        self.PlayerCheck(player)
                    else:
                        self.PlayerBet(player)
                else:
                    if self.Debug and self.Verbose:
                        print('We have made the first bet')

                    # options are to call, raise, check, or fold
                    calls = False
                    raises = False
                    checks = False
                    folds = True

                    if player.IsHuman():
                        callRaiseCheckFold = input(player.Name + ', would you like to call, raise, check, or fold? (C/r/k/f)')
                        if callRaiseCheckFold == 'C' or callRaiseCheckFold == 'c':
                            calls = True
                        elif callRaiseCheckFold == 'R' or callRaiseCheckFold == 'r':
                            raises = True
                        elif callRaiseCheckFold == 'K' or callRaiseCheckFold == 'k':
                            checks = True
                    else:
                        calls = (randint(0, 1) == 1)
                        raises = (randint(0, 1) == 1)
                        checks = (randint(0, 1) == 1)

                    if calls or self.StatisticsMode:
                        self.PlayerCall(player)
                    elif raises:
                        self.PlayerRaise(player)
                    elif checks:
                        self.PlayerCheck(player)
                    else:
                        self.PlayerFold(player)

        if not self.EverybodyFolded():
            for p in range(len(self.Players)):
                if self.EverybodyFolded():
                    break
                else:
                    player = self.Players[p]
                    if (not player.Folded) and player.Checked:
                        if not self.FirstBetMade:
                            # options are to bet or fold
                            bets = False
                            if player.IsHuman():
                                betFold = input(player.Name + ', either bet or fold (B/f): ')
                                if betFold == 'B' or betFold == 'b':
                                    bets = True
                                else:
                                    bets = False
                            else:
                                bets = (randint(0, 1) == 1)

                            if bets or self.StatisticsMode:
                                self.PlayerBet(player)
                            else:
                                self.PlayerFold(player)

                        else:
                            # options are call, raise, fold
                            calls = False
                            raises = False
                            checks = False
                            folds = True

                            if player.IsHuman():
                                callRaiseFold = input(player.Name + ', would you like to call, raise, or fold? (C/r/k/f)')
                                if callRaiseFold == 'C' or callRaiseFold == 'c':
                                    calls = True
                                elif callRaiseFold == 'R' or callRaiseFold == 'r':
                                    raises = True
                            else:
                                calls = (randint(0, 1) == 1)
                                raises = (randint(0, 1) == 1)

                            if calls or self.StatisticsMode:
                                self.PlayerCall(player)
                            elif raises:
                                self.PlayerRaise(player)
                            else:
                                self.PlayerFold(player)

            if not self.EverybodyFolded():
                for p in range(len(self.Players)):
                    if self.EverybodyFolded():
                        break
                    else:
                        player = self.Players[p]
                        if not (player.Bet >= self.MinimumBet or player.Folded):
                            # if they aren't up to bet, they need to meet the raise
                            calls = False
                            if player.IsHuman():
                                callFold = input(player.Name + ', either call the raise amount or fold (C/f): ')

                                if callFold == 'C' or callFold == 'c':
                                    calls = True

                            else:
                                calls = (randint(0, 1) == 1)

                            if calls or self.StatisticsMode:
                                self.PlayerCall(player)
                            else:
                                self.PlayerFold(player)

        # now set all of the checked players back to normal Status
        for p in range(len(self.Players)):
            self.Players[p].Checked = False
            self.Players[p].Bet = 0

    def Flop(self):
        if self.Verbose:
            print("------------------------------------ FLOP -------------------------------------")

        self.Deck.BurnCard()
        for c in range(3):
            card = self.Deck.DrawCardFromTop()
            self.FlopCards.append(card)

            if self.Verbose:
                print('Flop Card ' + str(c) + ': ' + str(card))

        self.UpdateCommunityCards()

    def Turn(self):
        if self.Verbose:
            print("------------------------------------- TURN -------------------------------------")

        self.Deck.BurnCard()
        self.TurnCard = self.Deck.DrawCardFromTop()
        self.UpdateCommunityCards()

        if self.Verbose:
            print('Turn Card: ' + str(self.TurnCard))

    def River(self):
        if self.Verbose:
            print("--------------------------------- RIVER -----------------------------------------")

        self.Deck.BurnCard()
        self.RiverCard = self.Deck.DrawCardFromTop()
        self.UpdateCommunityCards()

        if self.Verbose:
            print('River Card: ' + str(self.RiverCard))

    def UpdateCommunityCards(self):
        self.CommunityCards = []
        if(len(self.FlopCards) > 0):
            for c in range(len(self.FlopCards)):
                self.CommunityCards.append(self.FlopCards[c])

            if(not self.TurnCard is None):
                self.CommunityCards.append(self.TurnCard)

                if(not self.RiverCard is None):
                    self.CommunityCards.append(self.RiverCard)

    def SortPlayersByHandValue(self):
        n = len(self.Players)

        swapped = False
        for i in range(n):
            swapped = False
            for j in range(0, n-1):
                shouldSwap = False

                if(self.Players[j].HandValue > self.Players[j+1].HandValue):
                    shouldSwap = True
                else:
                    if(self.Players[j].HandValue == self.Players[j+1].HandValue):
                        handComparison = self.Comparison.CompareHandValue(self.Players[j].Hand, self.Players[j+1].Hand, self.CommunityCards, self.Players[j].HandValue)
                        if(handComparison == 1):
                            shouldSwap = True
                        elif(handComparison == 0):
                            self.Players[j].SameHandValueAs = self.Players[j+1].PlayerNumber
                            self.Players[j+1].SameHandValueAs = self.Players[j].PlayerNumber

                if(shouldSwap):
                    tempPlayer = self.Players[j+1]
                    self.Players[j+1] = self.Players[j]
                    self.Players[j] = tempPlayer
                    swapped = True

            if not swapped:
                break

        for i in range(n):
            swapped = False
            for j in range(0, n-1):
                shouldSwap = False

                if(self.Players[j+1].Folded):
                    shouldSwap = True

                if(shouldSwap):
                    tempPlayer = self.Players[j+1]
                    self.Players[j+1] = self.Players[j]
                    self.Players[j] = tempPlayer
                    swapped = True

            if not swapped:
                break

        self.Players = self.Players[::-1]

    def Showdown(self):
        if self.Verbose:
            print("----------------------------- SHOWDOWN ----------------------------------------")

        highestPlayer = None

        for p in range(len(self.Players)):
            player = self.Players[p]
            handValue = self.Comparison.HandValue(player.Hand, self.CommunityCards)
            self.Players[p].HandValue = handValue

        self.SortPlayersByHandValue()

        leader = self.Players[0]
        winners = []
        winners.append(leader)
        p = 1
        while p < len(self.Players):
            player = self.Players[p]
            if(player.SameHandValueAs == leader.PlayerNumber):
                winners.append(player)

            p += 1

        return winners

    def EverybodyFolded(self):
        playersFolded = 0
        p = 0
        while p < len(self.Players):
            if self.Players[p].Folded:
                playersFolded += 1

            p += 1

        if(playersFolded >= len(self.Players) - 1):
            return True
        else:
            return False

    def NewGame(self):
        self.Deck = TexasHoldemDeck()
        self.FlopCards = []
        self.TurnCard = None
        self.RiverCard = None
        self.CommunityCards = []
        self.Pot = 0
        self.Rounds = 0

        names = [
            'Josh',
            'Janae',
            'Michelle',
            'Tyson',
            'Chollin'
        ]

        self.Players = []
        for i in range(self.Bots):
            r = randint(0, len(names)-1)
            name = names[r]
            names.pop(r)
            self.AddPlayer(name=name)

        for i in range(self.Humans):
            r = randint(0, len(names)-1)
            name = names[r]
            names.pop(r)
            # self.AddPlayer(name=name, controlled=True)
            self.AddPlayer(name=name, controlled=True)

        self.PlayersOut = []

        if self.StatisticsMode:
            self.GameId = self.PymongoDB.games.insert_one({
                'players': len(self.Players)
            }).inserted_id

        self.Play()

    def CommunityCardsToJSON(self):
        json = {}
        json['flop'] = {}
        if self.FlopCards[0] and self.FlopCards[1] and self.FlopCards[2]:
            json['flop']['0'] = self.FlopCards[0].ToJSON()
            json['flop']['1'] = self.FlopCards[1].ToJSON()
            json['flop']['2'] = self.FlopCards[2].ToJSON()

        if self.TurnCard:
            json['turn'] = self.TurnCard.ToJSON()

        if self.RiverCard:
            json['river'] = self.RiverCard.ToJSON()

        return json

    def Wait(self):
        if(self.ReadTime < 1):
            input('')
        else:
            time.sleep(self.ReadTime)

    def Play(self):
        self.Rounds = 0

        while True:
            if(self.StatisticsMode):
                roundPlayers = []
                for p in range(len(self.Players)):
                    roundPlayers.append(self.Players[p])

                self.RoundId = self.PymongoDB.rounds.insert_one({
                    'players': len(self.Players),
                    'gameId': self.GameId
                }).inserted_id

            self.HumansInRound = 0
            for p in range(len(self.Players)):
                player = self.Players[p]
                if player.IsHuman():
                    self.HumansInRound += 1

            # self.AnteUp()

            self.RoundSection = DEAL
            self.Deal()
            self.TakeBets()
            if self.Verbose:
                print(self)
                if self.Readable:
                    self.Wait()

            if not self.EverybodyFolded():
                self.RoundSection = FLOP
                self.Flop()
                self.TakeBets()
                if self.Verbose:
                    print(self)
                    if(self.Readable):
                        self.Wait()

            if not self.EverybodyFolded():
                self.RoundSection = TURN
                self.Turn()
                self.TakeBets()
                if self.Verbose:
                    print(self)
                    if self.Readable:
                        self.Wait()

            if not self.EverybodyFolded():
                self.RoundSection = RIVER
                self.River()
                self.TakeBets()
                if self.Verbose:
                    print(self)
                    if self.Readable:
                        self.Wait()

            if not self.EverybodyFolded():
                self.RoundSection = SHOWDOWN
                roundWinners = self.Showdown()[:]
                if self.Verbose:
                    print(self)
                    if self.Readable:
                        self.Wait()

                numWinners = len(roundWinners)

                extraChips = self.Pot % numWinners
                self.Pot -= extraChips
                distributedChips = self.Pot / numWinners

                for p in range(len(roundWinners)):
                    player = roundWinners[p]
                    player.Chips += distributedChips

                if numWinners > 1:
                    for p in range(len(roundWinners)):
                        splitter = roundWinners[p]
                        if self.StatisticsMode:
                            self.PymongoDB.split_hands.insert_one({
                                'player': splitter.ToJSON(),
                                'community': self.CommunityCardsToJSON(),
                                'splitAmong': numWinners,
                                'playersPlayed': len(self.Players),
                                'everybodyFolded': False,
                                'gameId': self.GameId,
                                'roundId': self.RoundId
                        })
                else:
                    winner = roundWinners[0]
                    if self.StatisticsMode:
                        self.PymongoDB.winning_hands.insert_one({
                            'player': winner.ToJSON(),
                            'community': self.CommunityCardsToJSON(),
                            'playersPlayed': len(self.Players),
                            'everybodyFolded': False,
                            'gameId': self.GameId,
                            'roundId': self.RoundId
                        })

                    winner.Chips += self.Pot

                for p in range(len(self.Players)):
                    player = self.Players[p]

                    isWinner = False
                    for w in range(len(roundWinners)):
                        if player.PlayerNumber == roundWinners[w].PlayerNumber:
                            isWinner = True
                            break

                    if not isWinner and self.StatisticsMode:
                        self.PymongoDB.losing_hands.insert_one({
                            'player': player.ToJSON(),
                            'community': self.CommunityCardsToJSON(),
                            'playersPlayed': len(self.Players),
                            'everybodyFolded': False,
                            'gameId': self.GameId,
                            'roundId': self.RoundId
                        })
            else:
                for p in range(len(self.Players)):
                    if not self.Players[p].Folded:
                        roundWinner = self.Players[p]
                        break

                roundWinner.Chips += self.Pot

                if self.StatisticsMode:
                    print(self.EverybodyFolded())
                    self.PymongoDB.winning_hands.insert_one({
                        'player': roundWinner.ToJSON(),
                        'community': self.CommunityCardsToJSON(),
                        'playersPlayed': len(self.Players),
                        'everybodyFolded': True,
                        'gameId': self.GameId,
                        'roundId': self.RoundId
                    })

            # reset everything for the next round
            self.FlopCards = []
            self.TurnCard = None
            self.RiverCard = None
            self.CommunityCards = []
            self.Deck = TexasHoldemDeck()
            self.Pot = 0

            p = 0
            while p < len(self.Players):
                player = self.Players[p]
                if(player.Chips <= 0):
                    self.PlayersOut.append(player)
                    self.Players.pop(p)
                    if self.Verbose:
                        print(player.Name, ' is out')

                p += 1

            if len(self.Players) > 1:
                for p in range(len(self.Players)):
                    self.Players[p].ResetHand()
                    self.Players[p].Folded = False
                    self.Players[p].Checked = False
                    self.Players[p].SameHandValueAs = -1
            else:
                break

            self.Rounds += 1
            if self.Verbose:
                print(self)

        self.Winner = self.Players[0]
        if self.Verbose:
            print("------------------------------- GAME OVER -------------------------------------")
            print('Winner: ')
            print(self.Winner)
        if self.StatisticsMode:
            self.PymongoDB.games.update_one(
                {'_id': self.GameId},
                {
                    '$set': {
                        'winner': self.Winner.ToJSON()
                    }
                }
            )

# print("-------------------------------------------------------------------------------")

th = TexasHoldem(humans=1, bots=2, statisticsMode=False, autoStart=True, clearDB=False, verbose=True, readable=True, readTime=-1, debug=False)
# th = TexasHoldem(humans=0, bots=4, statisticsMode=True, clearDB=False, verbose=False, readable=False, readTime=-1, debug=False, autoStart=False)
# c = 0
# while c < 50000:
#     th.NewGame()
#     if c % 100 == 0:
#         print('game', c, 'rounds', th.Rounds, 'winner', th.Winner.Name)
#     c += 1


import argparse
import os

import torch
from torchtext import data, datasets
import torch.nn as nn
import torch.optim as optim
import torch.nn.functional as F
import torchvision
import torchvision.transforms as transforms
from torchvision.utils import save_image,  make_grid

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

from tqdm import tqdm

SEED = 1234
torch.manual_seed(SEED)
torch.backends.cudnn.deterministic = True

# Prevent matplotlib can't run in a non-interactive mode
import matplotlib
matplotlib.use('Agg')

#VAE MODEL

class VAE(nn.Module):
    def __init__(self, x_dim, h_dim1, h_dim2, z_dim):
        super(VAE, self).__init__()

        #Encoding layers
        self.fc1 = nn.Linear(x_dim, h_dim1)
        self.fc2 = nn.Linear(h_dim1, h_dim2)
        self.fc3_mu = nn.Linear(h_dim2, z_dim)
        self.fc3_log_var = nn.Linear(h_dim2, z_dim)

        #Decoding layers
        self.fc4 = nn.Linear(z_dim, h_dim2)
        self.fc5 = nn.Linear(h_dim2, h_dim1)
        self.fc6 = nn.Linear(h_dim1, x_dim)

    def encoder(self, x):
    	h = F.relu(self.fc1(x))
    	h = F.relu(self.fc2(h))
    	mu = self.fc3_mu(h)
    	log_var = self.fc3_log_var(h)
    	return mu, log_var

    def reparameterize(self, mu, log_var):
    	std = torch.exp(0.5*log_var) # standard deviation
    	eps = torch.randn_like(std)
    	sample = mu + eps * log_var
    	return sample

    def decoder(self, z):
    	h = F.relu(self.fc4(z))
    	h = F.relu(self.fc5(h))
    	reconstruction = torch.sigmoid(self.fc6(h))
    	return reconstruction

    def forward(self, x):
    	mu, log_var = self.encoder(x.view(-1, 784))
    	z = self.reparameterize(mu, log_var)
    	return self.decoder(z), mu, log_var

def main():

	transform = transforms.Compose([
	                    transforms.ToTensor(),
	])

	# MNIST DATASET

	train_dataset = torchvision.datasets.MNIST(root='./DATA_MNIST',train=True, transform=transform, download=True)
	test_dataset = torchvision.datasets.MNIST(root='./DATA_MNIST',train=False, transform=transform, download = True)

	train_loader = torch.utils.data.DataLoader(dataset=train_dataset, batch_size=BATCH_SIZE, shuffle=True)
	test_loader = torch.utils.data.DataLoader(dataset=test_dataset,  batch_size=BATCH_SIZE, shuffle=False)

	# Model +  Loss function
	# z_dim = 2!
	model = VAE(x_dim=784, h_dim1= 512, h_dim2=256, z_dim=2).to(device)
	optimizer = optim.Adam(model.parameters(), lr=LEARNING_RATE)

	# Print Loss Result
	train_losses = []
	train_losses_BCE = []
	train_losses_KLD = []

	test_losses = []
	test_losses_BCE = []
	test_losses_KLD = []

	epoch_list = []
	for epoch in range(EPOCHS):
		print(f"Epoch {epoch+1} of {EPOCHS}")
		train_epoch_loss_BCE, train_epoch_loss_KLD, train_epoch_loss = train(model, optimizer, train_loader)
		test_epoch_loss_BCE, test_epoch_loss_KLD, test_epoch_loss = evaluate(model, optimizer, test_loader, BATCH_SIZE, epoch)
		train_losses.append(train_epoch_loss)
		train_losses_BCE.append(train_epoch_loss_BCE)
		train_losses_KLD.append(train_epoch_loss_KLD)
		test_losses.append(test_epoch_loss)
		test_losses_BCE.append(test_epoch_loss_BCE)
		test_losses_KLD.append(test_epoch_loss_KLD)
		epoch_list.append(epoch+1)
		print(f"Train Loss: {train_epoch_loss:.4f}, Test Loss: {test_epoch_loss:.4f}, Test BCE Loss: {test_epoch_loss_BCE:.4f}, Test KLD Loss: {train_epoch_loss_KLD:.4f}")

	fig = plt.figure()
	plt.plot(epoch_list, train_losses, color='black', label = "train loss")
	plt.plot(epoch_list, test_losses, color='red', label = "test loss")
	plt.legend(loc='best', prop={'size': 10})
	plt.xlabel('Epoch')
	plt.ylabel('Reconstruction Loss and KL Divergence')
	plt.title('VAE_MNIST_Reconstruction_Loss_and_KL_Divergence')
	plt.savefig(f"1VAE_MNIST_final_loss_epoch_2.png")
	plt.close()

	fig = plt.figure()
	plt.plot(epoch_list, train_losses_BCE, color='black', label = "train loss")
	plt.plot(epoch_list, test_losses_BCE, color='red', label = "test loss")
	plt.legend(loc='best', prop={'size': 10})
	plt.xlabel('Epoch')
	plt.ylabel('Binary Cross Entropy')
	plt.title('VAE_MNIST_Reconstruction_Loss')
	plt.savefig(f"1VAE_MNIST_BCE_loss_epoch_2.png")
	plt.close()

	fig = plt.figure()
	plt.plot(epoch_list, train_losses_KLD, color='black', label = "train loss")
	plt.plot(epoch_list, test_losses_KLD, color='red', label = "test loss")
	plt.legend(loc='best', prop={'size': 10})
	plt.xlabel('Epoch')
	plt.ylabel(' KL Divergence')
	plt.title('VAE_MNIST_KL_Divergence')
	plt.savefig(f"1VAE_MNIST_KLD_loss_epoch_2.png")
	plt.close()

def loss_function(recon_x, x, mu, log_var):
	BCE = F.binary_cross_entropy(recon_x, x.view(-1, 784), reduction = 'sum')
	# VAE Gaussian KL Divergence
	KLD = -0.5 * torch.sum(1+ log_var - mu.pow(2) - log_var.exp())

	return BCE, KLD, BCE + KLD

def train(model, optimizer, train_loader):
	model.train()
	running_loss = 0.0
	running_loss_BCE = 0.0
	running_loss_KLD = 0.0
	for batch_idx, (images, _ ) in tqdm(enumerate(train_loader), total = int(len(train_loader.dataset) / BATCH_SIZE)):
		images = images.to(device)
		images = images.reshape(-1, 784)
		optimizer.zero_grad()
		recon_batch, mu, log_var = model(images)
		BCE_loss, KLD_loss, final_loss = loss_function(recon_batch, images, mu, log_var)
		final_loss.backward()
		running_loss += final_loss.item()
		running_loss_BCE += BCE_loss.item()
		running_loss_KLD += KLD_loss.item()
		optimizer.step()
	train_loss = running_loss/len(train_loader.dataset)
	train_loss_BCE = running_loss_BCE/len(train_loader.dataset)
	train_loss_KLD = running_loss_KLD/len(train_loader.dataset)
	return train_loss_BCE, train_loss_KLD, train_loss

def evaluate(model, optimizer, test_loader, batch_size, epoch):
	model.eval()
	running_loss = 0.0
	running_loss_BCE = 0.0
	running_loss_KLD = 0.0
	with torch.no_grad():
		for batch_idx, (images, _ ) in enumerate(test_loader):
			images = images.to(device)
			images = images.reshape(-1, 784)
			recon_batch, mu, log_var = model(images)
			BCE_loss, KLD_loss, final_loss = loss_function(recon_batch, images, mu, log_var)
			running_loss += final_loss.item()
			running_loss_BCE += BCE_loss.item()
			running_loss_KLD += KLD_loss.item()

			if batch_idx == int(len(test_loader.dataset)/batch_size) - 1:
					recon_batch_ = recon_batch.view(batch_size, 1, 28, 28)[:64]
					generated_img = make_grid(recon_batch_, padding =2, normalize = True)
					save_generator_image(generated_img, f"./1IMAGE_VAE_MNIST_2/epoch{epoch+1}.png")

					# if epoch == EPOCHS-1:
					# 	image_batch = images.view(batch_size, 1, 28, 28)[:64]
					# 	real_img = make_grid(image_batch, padding =2, normalize = True)
					# 	save_generator_image(real_img, f"./IMAGE_MNIST/epoch{epoch+1}.png")

	test_loss = running_loss/len(test_loader.dataset)
	test_loss_BCE = running_loss_BCE/len(test_loader.dataset)
	test_loss_KLD = running_loss_KLD/len(test_loader.dataset)
	return test_loss_BCE, test_loss_KLD, test_loss

# to save the images generated by the generator
def save_generator_image(image, path):
    save_image(image, path)

if __name__=="__main__":

			# Arguement Parser
			parser = argparse.ArgumentParser()
			parser.add_argument("--gpu", default="0", type=str)
			args = parser.parse_args()

			os.environ["CUDA_DEVICE_ORDER"]="PCI_BUS_ID"
			os.environ["CUDA_VISIBLE_DEVICES"]=args.gpu
			device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

			# HYPER-PARAMETERS
			BATCH_SIZE = 128
			EPOCHS = 200
			LEARNING_RATE = 1e-3

			# latent vector z dimension = 2

			main()


# basic packages #
import os
import numpy as np
import tensorflow as tf
tf.logging.set_verbosity(tf.logging.ERROR)
import pickle
# trial generation and network building #

import sys
sys.path.append('.')
from utils import tools

from task_and_network.task import generate_trials
from task_and_network.network import Model

def gen_task_info(hp,
                log,
                model_dir,
                rules,
                return_trial_store=False,):
    task_info_file = model_dir+'/task_info.pkl'
    if os.path.isfile(task_info_file):
        with open(task_info_file,'rb') as tinfr:
            task_info = pickle.load(tinfr)
    else:
        task_info = dict()

    trial_store = dict()

    print("Epoch information:")
    for rule in rules:
        task_info[rule] = dict()
        trial_store[rule] = generate_trials(rule, hp, 'test', noise_on=False)

        n_stims = len([ep for ep in trial_store[rule].epochs.keys() if 'stim' in ep])
        stim_loc_log_len = int(len(trial_store[rule].input_loc)/n_stims)
        task_info[rule]['in_loc'] = np.array([np.argmax(i) for i in trial_store[rule].input_loc[:stim_loc_log_len]])
        if n_stims != 1:
            for nst in range(2,n_stims+1):
                task_info[rule]['in_loc_'+str(nst)] = \
                    np.array([np.argmax(i) for i in trial_store[rule].input_loc[(nst-1)*stim_loc_log_len:nst*stim_loc_log_len]])

        task_info[rule]['in_loc_set'] = sorted(set(task_info[rule]['in_loc']))
        task_info[rule]['epoch_info'] = trial_store[rule].epochs
        print('\t'+rule+':')
        for e_name, e_time in task_info[rule]['epoch_info'].items():
            print('\t\t'+e_name+':',e_time)

    with open(task_info_file,'wb') as tinf:
        pickle.dump(task_info, tinf)

    if return_trial_store:
        return trial_store

def compute_H_(hp, model_dir, rule, trial_num, trial=None, task_mode='test'):

    if trial is None:
        trial = generate_trials(rule, hp, task_mode, noise_on=False)

    sub_dir = model_dir+'/'+str(trial_num)+'/'
    model = Model(sub_dir, hp=hp)
    with tf.Session() as sess:
        model.restore()
        feed_dict = tools.gen_feed_dict(model, trial, hp)
        h = sess.run(model.h, feed_dict=feed_dict)
    return h

def compute_H(
            hp,
            log,
            model_dir,
            rules=None,
            trial_list=None,
            recompute=False,
            save_H_pickle=True,
            ):

    if rules is not None:
        rules = rules
    else:
        rules = hp['rule_trains']

    if trial_list is None:
        trial_list = log['trials']
    elif isinstance(trial_list, list):
        trial_list = trial_list

    trial_store = gen_task_info(hp,log,model_dir,rules,True,)

    for rule in rules:
        if isinstance(trial_list, dict):
            temp_list = list()
            for value in trial_list[rule].values():
                temp_list += value
            temp_list = sorted(set(temp_list))
        elif isinstance(trial_list, list):
            temp_list = trial_list

        for trial_num in temp_list:
            H_file = model_dir+'/'+str(trial_num)+'/H_'+rule+'.pkl'
            if recompute or not os.path.isfile(H_file):
                H_ = compute_H_(hp, model_dir, rule, trial_num, trial = trial_store[rule])
                with open(H_file,'wb') as wh:
                    pickle.dump(H_,wh)

def Get_H(hp,model_dir,trial_num,rule,save_H=False,task_mode='test',):

    H_file = model_dir+'/'+str(trial_num)+'/H_'+rule+'.pkl'

    if os.path.isfile(H_file):
        with open(H_file,'rb') as hf:
            H = pickle.load(hf)

    else:
        H = compute_H_(hp, model_dir, rule, trial_num, trial=None, task_mode=task_mode)
        if save_H:
            with open(H_file,'wb') as wh:
                pickle.dump(H,wh)
    return H


from utils import Logger
import scipy.signal
import signal
import numpy as np

"""

    Adapted from code written by Patrick Coady (pat-coady.github.io)

"""

class Agent(object):
    def __init__(self,policy,val_func,env,input_normalizer,logger,policy_episodes=20,policy_steps=10,gamma1=0.0,gamma2=9.995,lam=0.98,
                    normalize_advantages=True,use_tdlam=False,use_timestep=False,monitor=None, animate=False):
        self.env = env
        self.monitor = monitor
        self.policy_steps = policy_steps
        self.logger = logger
        self.use_tdlam = use_tdlam
        self.use_timestep = use_timestep
        self.policy = policy
        self.val_func = val_func
        self.input_normalizer = input_normalizer
        self.policy_episodes = policy_episodes
        self.animate = animate
        self.normalize_advantages = normalize_advantages
        self.gamma1 = gamma1
        self.gamma2 = gamma2

        self.lam = lam
        self.global_steps = 0

        """

            Args:
                policy:                 policy object with update() and sample() methods
                val_func:               value function object with fit() and predict() methods
                env:                    environment
                input_normalizer:       scaler object with apply(), reverse(), and update() methods
                logger:                 Logger object

                policy_episodes:        number of episodes collected before update
                policy_steps:           minimum number of steps before update
                    (will update when either episodes > policy_episodes or steps > policy_steps)

                gamma:                  discount rate
                lam:                    lambda for GAE calculation
                normalize_advantages:   boolean, normalizes advantages if True
                use_tdlam:              boolean, True uses TD lambda target for value function, else Monte Carlo
                use_timestep:           boolean, True enables time step feature which sometimes works better than a
                                        low discount rate for continuing tasks with per-step rewards (like Mujoco envs)
                monitor:                A monitor object like RL_stats to plot interesting stats as learning progresses
                                        Monitor object implements update_episode() and show() methods
                animate:                boolean, True uses env.render() method to animate episode

        """

    def run_episode(self):
        """

        Returns: 4-tuple of NumPy arrays
            observes: shape = (episode len, obs_dim)
            actions: shape = (episode len, act_dim)
            rewards: shape = (episode len,)
            unscaled_obs: useful for training scaler, shape = (episode len, obs_dim)
        """
        obs = self.env.reset()
        observes, actions, rewards1, rewards2, unscaled_obs  =  [], [], [], [], []
        done = False
        step = 0.0
        while not done:
            if self.animate:
                self.env.render()
            obs = obs.astype(np.float64).reshape((1, -1))
            unscaled_obs.append(obs.copy())
            if self.input_normalizer is not None:
                obs = self.input_normalizer.apply(obs)
            if self.use_timestep:
                obs = np.append(obs, [[step]], axis=1)  # add time step feature
            observes.append(obs)
            action, env_action = self.policy.sample(obs)# .reshape((1, -1)).astype(np.float64) #[:,0:-1])
            actions.append(action)
            obs, reward, done, reward_info = self.env.step(env_action)
            reward1 = reward[0]
            reward2 = reward[1]
            if not isinstance(reward1, float):
                reward1 = np.asscalar(reward1)
            if not isinstance(reward1, float):
                reward2 = np.asscalar(reward2)
            rewards1.append(reward1)
            rewards2.append(reward2)
            step += 1e-3  # increment time step feature
        #logger.log({'Score': sum_rewards})
        return (np.concatenate(observes), np.concatenate(actions), np.array(rewards1, dtype=np.float64),
                np.array(rewards2, dtype=np.float64), np.concatenate(unscaled_obs))

    def run_policy(self,episode_cnt,warmup=False):
        """ Run policy and collect data for a minimum of min_steps and min_episodes
        Args:
            episode_cnt: current episode number, used for logging stats

        Returns: list of trajectory dictionaries, list length = number of episodes
            'observes' : NumPy array of states from episode
            'actions' : NumPy array of actions from episode
            'rewards' : NumPy array of (un-discounted) rewards from episode
            'unscaled_obs' : NumPy array of (un-discounted) rewards from episode
        """
        total_steps = 0
        e_cnt = 0
        trajectories = []
        #for e in range(self.policy_episodes):
        while e_cnt <= self.policy_episodes or total_steps < self.policy_steps:
            observes, actions, rewards1, rewards2, unscaled_obs  = self.run_episode()
            if self.monitor is not None and not warmup:
                self.monitor.update_episode(np.sum(rewards1) + np.sum(rewards2),  observes.shape[0])
            total_steps += observes.shape[0]
            trajectory = {'observes': observes,
                          'actions': actions,
                          'rewards1': rewards1,
                          'rewards2': rewards2,
                          'unscaled_obs': unscaled_obs}
            trajectories.append(trajectory)
            e_cnt += 1
        unscaled = np.concatenate([t['unscaled_obs'] for t in trajectories])
        if self.input_normalizer is not None:
            self.input_normalizer.update(unscaled)  # update running statistics for scaling observations

        self.add_value(trajectories)  # add estimated values to episodes
        self.add_disc_sum_rew(trajectories, self.gamma1, self.gamma2)  # calculated discounted sum of Rs
        self.add_gae(trajectories, self.gamma1, self.gamma2, self.lam)  # calculate advantage
        # concatenate all episodes into single NumPy arrays
        observes, actions, advantages, disc_sum_rew = self.build_train_set(trajectories)

        if not warmup:
            self.policy.update(observes, actions, advantages, self.logger)  # update policy
            self.val_func.fit(observes, disc_sum_rew, self.logger)  # update value function
            self.log_batch_stats(observes, actions, advantages, disc_sum_rew, episode_cnt)
            self.global_steps += total_steps
            self.logger.log({'_MeanReward': np.mean([t['rewards1'].sum() + t['rewards2'].sum() for t in trajectories]),
                         '_StdReward': np.std([t['rewards1'].sum() + t['rewards2'].sum() for t in trajectories]),
                         '_MinReward': np.min([t['rewards1'].sum() + t['rewards2'].sum()  for t in trajectories]),
                         'Steps': total_steps,
                         'TotalSteps' : self.global_steps})
            if self.monitor is not None:
                self.monitor.show()
        return trajectories

    def train(self,train_episodes, train_samples=None):
        _ = self.run_policy(-1,warmup=True)
        print('*** SCALER WARMUP COMPLETE *** ')
        print(np.sqrt(self.input_normalizer.vars))
        episode = 0

        if train_samples is not None:
            while self.global_steps < train_samples:
                trajectories = self.run_policy(episode)
                self.logger.write(display=True)
                episode += len(trajectories)
        else:
            while episode < train_episodes:
                trajectories = self.run_policy(episode)
                self.logger.write(display=True)
                episode += len(trajectories)

    def discount(self,x, gamma):
        """ Calculate discounted forward sum of a sequence at each point """
        return scipy.signal.lfilter([1.0], [1.0, -gamma], x[::-1])[::-1]

    def add_disc_sum_rew(self,trajectories, gamma1, gamma2):
        """ Adds discounted sum of rewards to all time steps of all trajectories

        Args:
            trajectories: as returned by run_policy()
            gamma: discount

        Returns:
            None (mutates trajectories dictionary to add 'disc_sum_rew')
        """
        for trajectory in trajectories:
            if gamma1 < 0.999:  # don't scale for gamma ~= 1
                rewards1 = trajectory['rewards1'] * (1 - gamma1)
            else:
                rewards1 = trajectory['rewards1']

            if gamma2 < 0.999:  # don't scale for gamma ~= 1
                rewards2 = trajectory['rewards2'] * (1 - gamma2)
            else:
                rewards2 = trajectory['rewards2']

            disc_sum_rew1 = self.discount(rewards1, gamma1)
            disc_sum_rew2 = self.discount(rewards2, gamma2)

            trajectory['disc_sum_rew'] = disc_sum_rew1 + disc_sum_rew2

    def add_value(self,trajectories):
        """ Adds estimated value to all time steps of all trajectories

        Args:
            trajectories: as returned by run_policy()
            val_func: object with predict() method, takes observations
                and returns predicted state value

        Returns:
            None (mutates trajectories dictionary to add 'values')
        """
        for trajectory in trajectories:
            observes = trajectory['observes']
            values = self.val_func.predict(observes)
            trajectory['values'] = values

    def add_gae(self,trajectories, gamma1, gamma2, lam):
        """ Add generalized advantage estimator.
        https://arxiv.org/pdf/1506.02438.pdf

        Args:
            trajectories: as returned by run_policy(), must include 'values'
                key from add_value().
            gamma: reward discount
            lam: lambda (see paper).
                lam=0 : use TD residuals
                lam=1 : A =  Sum Discounted Rewards - V_hat(s)

        Returns:
            None (mutates trajectories dictionary to add 'advantages')
        """
        for trajectory in trajectories:
            advantages = trajectory['disc_sum_rew'] - trajectory['values']
            trajectory['advantages'] = advantages

    def build_train_set(self,trajectories):
        """

        Args:
            trajectories: trajectories after processing by add_disc_sum_rew(),
                add_value(), and add_gae()

        Returns: 4-tuple of NumPy arrays
            observes: shape = (N, obs_dim)
            actions: shape = (N, act_dim)
            advantages: shape = (N,)
            disc_sum_rew: shape = (N,)
        """
        observes = np.concatenate([t['observes'] for t in trajectories])
        actions = np.concatenate([t['actions'] for t in trajectories])
        disc_sum_rew = np.concatenate([t['disc_sum_rew'] for t in trajectories])
        advantages = np.concatenate([t['advantages'] for t in trajectories])
        # normalize advantages
        if self.normalize_advantages:
            advantages = (advantages - advantages.mean()) / (advantages.std() + 1e-6)
        else:
            advantages = advantages - advantages.mean()

        return observes, actions, advantages, disc_sum_rew

    def log_batch_stats(self,observes, actions, advantages, disc_sum_rew, episode):
        """ Log various batch statistics """
        self.logger.log({'_mean_obs': np.mean(observes),
                '_min_obs': np.min(observes),
                '_max_obs': np.max(observes),
                '_std_obs': np.mean(np.var(observes, axis=0)),
                '_mean_act': np.mean(actions),
                '_min_act': np.min(actions),
                '_max_act': np.max(actions),
                '_std_act': np.mean(np.var(actions, axis=0)),
                '_mean_adv': np.mean(advantages),
                '_min_adv': np.min(advantages),
                '_max_adv': np.max(advantages),
                '_std_adv': np.var(advantages),
                '_mean_discrew': np.mean(disc_sum_rew),
                '_min_discrew': np.min(disc_sum_rew),
                '_max_discrew': np.max(disc_sum_rew),
                '_std_discrew': np.var(disc_sum_rew),
                '_Episode': episode
            })


#from doo.doo import Thread2
from mp.utils import normr,almostEq
from mp.geom import angBetween
from numpy import eye,dot,diag,cross,zeros
from numpy.random import randn
import logging; L = logging.Logger(__file__)
L.setLevel(logging.DEBUG)
from nibabel.quaternions import angle_axis2mat,mat2quat,quat2angle_axis

def getState(thread):
    "get position and orientation of ends"
    xyz = thread.getXYZ()
    s0,s1,e1,e0 = xyz.T[[0,1,-2,-1]]
    return s0,normr(s1-s0),e0,normr(e0-e1)

def setOrs(thread,pos1,or1,pos2,or2):
    "set orientation of ends"
    old_pos1,old_or1,old_pos2,old_or2 = getState(thread)
    thread.applyMotion(pos1-old_pos1,minRot(or1,old_or1),
                       pos2-old_pos2,minRot(or2,old_or2))

def applyTwist(thread,twist1,twist2):
    "twist the ends"
    _,or1,_,or2 = getState(thread)
    thread.applyMotion(zeros(3),angle_axis2mat(twist1,or1),zeros(3),angle_axis2mat(twist2,or2))

def minRot(ax1,ax2):
    "find the rotation matrix that takes ax1 to ax2"
    if almostEq(ax1,ax2):
        L.debug("minRot: same vector")
        return eye(3)
    elif almostEq(ax1,-ax2):
        L.debug("minRot: opp vector")
        return -diag([-1,-1,0])
    else:
        ax_rot = cross(ax2,ax1)
        return angle_axis2mat(angBetween(ax1,ax2),ax_rot)

def infTwist(xyz):
    pts = xyz.T
    ors = normr(pts[1:] - pts[:-1])

    start2end_rope = eye(3)
    for (or1,or2) in zip(ors[:-1],ors[1:]):
        start2end_rope = dot(minRot(or2,or1),start2end_rope)

    assert almostEq(dot(start2end_rope,ors[0]),ors[-1])
    end2start_min = minRot(ors[0],ors[-1])

    twist_mat = dot(end2start_min,start2end_rope)
    ang,_ = quat2angle_axis(mat2quat(twist_mat))
    return ang

def test_infTwist():
    xyz = randn(3,100)
    infTwist(xyz)

def test_minRot():
    for _ in xrange(100):
        x1 = normr(randn(3))
        x2 = normr(randn(3))
        assert almostEq(x1,dot(minRot(x1,x2),x2))

if __name__ == "__main__":
    test_minRot()
    test_infTwist()


from django.contrib import admin

# Register your models here.
from .models import Task

def change_status(modeladmin, request, queryset):
    queryset.update(task_status='Complete')

change_status.short_description = "Mark selected tasks as complete"

class TaskAdmin(admin.ModelAdmin):
    list_display = ('task_name', 'task_status', 'task_priority', 'target_date')
    list_filter = ('task_status', 'task_priority', 'target_date')
    search_fields = ['task_name', 'task_status', 'task_priority']
    # list_editable = ['task_status']
    actions = [change_status]

admin.site.register(Task, TaskAdmin)


"""
README
===============================================================================
This is an adapter to represent axographio objects as neo objects.

axographio is a file i/o Python module that can read in axograph ".axgx" files.
It is available under a BSD-3-Clause license and can be installed from pip.
The following file types are supported:

 - AXGX/AXGD (Axograph X file format)

Based on stimfitio.pyfrom neo.io

11 JUL 2018, W. Hart, Swinburne University, Australia
"""

# needed for python 3 compatibility
from __future__ import absolute_import

from datetime import datetime
import os
import sys

import numpy as np
import quantities as pq

from neo.io.baseio import BaseIO
from neo.core import Block, Segment, AnalogSignal

try:
    import axographio
except ImportError as err:
    HAS_AXOGRAPHIO = False
    AXOGRAPHIO_ERR = err
else:
    HAS_AXOGRAPHIO = True
    AXOGRAPHIO_ERR = None

class AxographIO(BaseIO):
    """
    Class for converting an Axographio object to a Neo object.
    Provides a standardized representation of the data as defined by the neo
    project; this is useful to explore the data with an increasing number of
    electrophysiology software tools that rely on the Neo standard.

    axographio is a file i/o Python module that can read in axograph ".axgx" files.
    It is available under a BSD-3-Clause license and can be installed from pip.
    The following file types are supported:

    - AXGX/AXGD (Axograph X file format)

    Example usage:
        >>> import neo
        >>> neo_obj = neo.io.AxographIO("file.axgx")
        or
        >>> import axographio
        >>> axo_obj = axographio.read("file.axgx")
        >>> neo_obj = neo.io.AxographIO(axo_obj)
    """

    is_readable = True
    is_writable = False

    supported_objects = [Block, Segment, AnalogSignal]
    readable_objects = [Block]
    writeable_objects = []

    has_header = False
    is_streameable = False

    read_params = {Block: []}
    write_params = None

    name = 'AXOGRAPH'
    extensions = ['axgx', 'axgd']

    mode = 'file'

    def __init__(self, filename=None):
        """
        Arguments:
            filename : Either a filename or an axographio object
        """
        if not HAS_AXOGRAPHIO:
            raise AXOGRAPHIO_ERR

        BaseIO.__init__(self)

        if hasattr(filename, 'lower'):
            self.filename = filename
            self.axo_obj = None
        else:
            self.axo_obj = filename
            self.filename = None

    def read_block(self, **kargs):
        if self.filename is not None:
            self.axo_obj = axographio.read(self.filename)

        # Build up the block
        blk = Block()

        blk.rec_datetime = None
        if self.filename is not None:
            # modified time is not ideal but less prone to
            # cross-platform issues than created time (ctime)
            blk.file_datetime = datetime.fromtimestamp(os.path.getmtime(self.filename))

            # store the filename if it is available
            blk.file_origin = self.filename

        # determine the channel names and counts
        _, channel_ordering = np.unique(self.axo_obj.names[1:], return_index=True)
        channel_names = np.array(self.axo_obj.names[1:])[np.sort(channel_ordering)]
        channel_count = len(channel_names)

        # determine the time signal and sample period
        sample_period = self.axo_obj.data[0].step * pq.s
        start_time = self.axo_obj.data[0].start * pq.s

        # Attempt to read units from the channel names
        channel_unit_names = [x.split()[-1].strip('()') for x in channel_names]
        channel_units = []

        for unit in channel_unit_names:
            try:
                channel_units.append(pq.Quantity(1, unit))
            except LookupError:
                channel_units.append(None)

        # Strip units from channel names
        channel_names = [' '.join(x.split()[:-1]) for x in channel_names]

        # build up segments by grouping axograph columns
        for seg_idx in range(1, len(self.axo_obj.data), channel_count):
            seg = Segment(index=seg_idx)

            # add in the channels
            for chan_idx in range(0, channel_count):
                signal = pq.Quantity(
                    self.axo_obj.data[seg_idx + chan_idx], channel_units[chan_idx])
                analog = AnalogSignal(signal,
                                      sampling_period=sample_period, t_start=start_time,
                                      name=channel_names[chan_idx], channel_index=chan_idx)
                seg.analogsignals.append(analog)

            blk.segments.append(seg)

        blk.create_many_to_one_relationship()

        return blk