import random
import time

#These have to do with importing the pictures
import io
import os

import PySimpleGUI as sg

import PIL
from PIL import Image

n = 49

image = Image.open(r'C:\Users\carte\OneDrive\Desktop\Coding\Hangman\HM_' + chr(n) + '.png')
image.thumbnail((200, 200))
bio = io.BytesIO()
image.save(bio, format="PNG")

sg.theme ( 'DarkPurple' )

layout =[   [sg.Image( key="-IMAGE-")],
            [sg.Text(('')), sg.Text(size=(50,1), key='-OUTPUT-')],
            [sg.Text(('')), sg.Text(size=(50,1), key='-OUTPUT2-')],
            [sg.Text(('')), sg.Text(size=(50,1), key='-OUTPUT3-')],
            [sg.Input(key='-IN-', do_not_clear=False)],
            [sg.Button("ENTER"), sg.Exit("EXIT GAME")]]

window = sg.Window("Hangman Game", layout, margins = (150, 150),finalize=True, resizable = True)
window['-OUTPUT-'].update('Hello, please enter a word or phrase for the Hangman Game')

#Opens the window and asks for an input to play hangman
def getInput():
    valid = False
    values = ""
    length = 0

    while valid == False:
        event , values = window.read()

        #Rechecks everything after every press of enter
        if event == "ENTER":
            #Checks length everytime it loops
            length = len(values['-IN-'])

            inputString = values['-IN-']

            if (length == 0 or (has_numbers(values['-IN-']) == True)):
                #
                #Delete this at the end
                print('Invalid Entry')
                window['-OUTPUT2-'].update('Invalid Entry - No Input')
            #Need this to not get errror is the length is zero
            else:
                #Have to do this after making sure the length isnt' zero
                last_char = inputString[-1]
                if ( last_char == ' '):
                    #
                    #Delete this at the end
                    print ( "Invalid Entry - Ends with a Space" )
                    window['-OUTPUT2-'].update('Invalid Entry - Ends with a Space')
                else:
                    print('Valid Entry')
                    window['-OUTPUT2-'].update('')
                    PlayGame(values['-IN-'])
                    valid = True

        if event == sg.WIN_CLOSED or event =='EXIT GAME':
            break

def PlayGame(inputString):
    x = 0
    correctGuesses = 0
    #Refreshing the screen to the game screen
    Refresh( n )

    arr = list(inputString)
    arrGuessed = []

    correctGuesses = numSpaces(arr)

    root = arrayToList(arr, len(arr))
    String = update(root)
    window['-OUTPUT2-'].update(String)

    #Guessing Loop
    #There isn't a do while. Might have to do while(True) and break statement with the Gamewon() function
    while(correctGuesses != len(arr)):
        x = 0
        event , values = window.read()
        inVal = values['-IN-']

        guessed = alreadyGuessed(arrGuessed, inVal )

        if(event == sg.WIN_CLOSED or event =='EXIT GAME'):
            break

        elif( n == 55 ):
            newImage(n)
            GameLost(inputString)
            return 0

        elif( len(inVal) == 1 and (inVal.isdigit() == False and guessed == False)):
            arrGuessed.append(inVal)
            print(alreadyGuessed)
            print("Valid Input")
            root, x  = CheckGuess( inVal, root )

            if(x == 0):
                print("Incorrect Guess")
                newImage(n)

            window['-OUTPUT2-'].update(update(root))
            correctGuesses = correctGuesses + x
        else:
            print( "Invalid" )
    if(correctGuesses == len(arr)):
        #window['-Image-'].update("")
        window['-OUTPUT-'].update("You won the Game!")
        window['-OUTPUT2-'].update("The answer was: "+ inputString)
        window['-OUTPUT3-'].update("")
        event , values = window.read()
        event , values = window.read()

def newImage(i):
    global n
    print( n )
    n +=1
    image = Image.open(r'C:\Users\carte\OneDrive\Desktop\Coding\Hangman\HM_' + chr(n) + '.png')
    image.thumbnail((200, 200))
    bio = io.BytesIO()
    image.save(bio, format="PNG")

    window['-IMAGE-'].update(data=bio.getvalue())

def alreadyGuessed(arr, char):
    for x in arr:
        if(x == char):
            return True
    return False

#Checks if the input has numbers in ( we don't want numbers in their)
def has_numbers(inputString):
    return any(char.isdigit() for char in inputString)

#Now it will update the text.
#Needs to update the text box to get rid of it
#Needs to input my picture
def Refresh( a ):

        #HOLY FUCK I DID IT
        window['-IMAGE-'].update(data=bio.getvalue())
        window['-OUTPUT-'].update(("Please Enter a letter to guess"))

def GameLost(inputString):
        window['-OUTPUT-'].update("You fucking lost the Game!")
        window['-OUTPUT2-'].update("The answer was: "+ inputString)
        window['-OUTPUT3-'].update("You suck")
        event , values = window.read()

def playAgain():
    global n
    n = 49

#---------------------------------------------------------------------
#--------Input, Node, Checkguess, New Image Functions-----------------
#---------------------------------------------------------------------
#---------------------------------------------------------------------

# Representation of a node
class Node:
    def __init__(self, val, show = False):
        self.val = val
        self.next = None
        self.show = False

# Function to insert node
def insert(root, item):
    temp = Node(item)

    if(item == ' '):
        temp.show = True
    else:
        temp.show = False

    if (root == None):
        root = temp
    else :
        ptr = root
        while (ptr.next != None):
            ptr = ptr.next
        ptr.next = temp

    return root

def update(root):
    Str = ""

    while (root != None):
        if( root.show == True ):
            if(root.val == " "):
                Str = Str + "       " + root.val
            else:
                Str = Str + " " + root.val
        else:
            Str = Str + " _ "
        root = root.next

    return Str

def arrayToList(arr, n):
    root = None
    for i in range(0, n, 1):
        root = insert(root, arr[i])

    return root

#Finds the number of spaces in the array of characters
def numSpaces(arr):
    p = 0
    for x in arr:
        if(arr[x] == ' '):
            p += 1
    return p

def CheckGuess( char, head ):
    curr = head
    n = 0
    while( curr != None ):
        if( curr.val == char or curr.val == char.upper() or curr.val == char.lower() ):
            if( curr.show == False ):
                n = n + 1
            curr.show = True
            curr = curr.next
        else:
            curr = curr.next
    print( "You found ", n ," instances of -" , char , "-" )

    return head, n

def numSpaces(array):
    p = 0
    for x in array:
        if(x == ' '):
            p += 1
    return p

getInput()
print( "Window Closed")
window.close()


# coding:utf-8
# @Time  : 2019-04-28 11:13
# @Author: Xiawang
from utils.util import delete_requests, get_app_header

host = 'https://gate.lagou.com/v1/entry'
header = get_app_header(100018934)

def delete_orderId(orderIds):
    url = host + '/order/orderId?orderIds={orderIds}'.format(orderIds=orderIds)
    remark = '删除投递记录'
    return delete_requests(url=url, remark=remark)


"""
Entrypoints.

@author: gjorando
"""

import os
import json
from datetime import datetime
import torch
import click
from PIL import Image
import neurartist

def odd_int(value):
    value = int(value)
    if value % 2 == 0:
        raise ValueError("Odd number required")
    return value

def threshold_or_neg(value):
    value = float(value)
    if value > 1:
        raise ValueError("Value should be between 0 and 1, or negative")
    return value

def list_parameter(value_type=int):
    def list_parameter_(param_value):
        nonlocal value_type

        if param_value is None:
            result = None
        else:
            result = json.loads(param_value)
            assert isinstance(result, list), "parameter should be a list"
            for i, v in enumerate(result):
                result[i] = value_type(v)

        return result

    return list_parameter_

@click.command()
# General
@click.option(
    "--content", "-c",
    "content_path",
    required=True,
    type=click.Path(exists=True, dir_okay=False),
    help="Content image"
)
@click.option(
    "--style", "-s",
    "style_path",
    required=True,
    type=click.Path(exists=True, dir_okay=False),
    help="Style image"
)
@click.option(
    "--output", "-o",
    "output_path",
    default="./",
    type=click.Path(dir_okay=True, writable=True),
    help="Output path"
)
@click.option(
    "--size", "-S",
    "img_size",
    default=512,
    type=click.INT,
    help="Output size"
)
@click.option(
    "--epochs", "-e",
    "num_epochs",
    default=250,
    type=click.INT,
    help="Maximum number of epochs"
)
@click.option(
    "--trade-off",
    "trade_off",
    default=3,
    type=click.FLOAT,
    help="Trade-off between content (>1) and style (<1) faithfullness"
)
@click.option(
    "--init-random/--init-image",
    "random_init",
    default=False,
    help="Init optimizer either from random noise, or image (default)"
)
@click.option(
    "--init-image-path",
    "random_init_path",
    default=None,
    type=click.Path(exists=True, dir_okay=False),
    help="If --init-image is set, path to an image (default: content image)"
)
# Layers options
@click.option(
    "--content-layers",
    default=None,
    type=list_parameter(),
    help="Indexes of content layers (as a string representing a list)"
)
@click.option(
    "--style-layers",
    default=None,
    type=list_parameter(),
    help="Indexes of style layers (as a string representing a list)"
)
@click.option(
    "--content-weights",
    default=None,
    type=list_parameter(float),
    help="Content weights (as a string representing a list)"
)
@click.option(
    "--style-weights",
    default=None,
    type=list_parameter(float),
    help="Style weights (as a string representing a list)"
)
# Color control
@click.option(
    "--color-control",
    default="none",
    type=click.Choice(["histogram_matching", "luminance_only", "none"]),
    help="Color control method (default: none)"
)
@click.option(
    "--cc-luminance-only-normalize",
    "luminance_only_normalize",
    is_flag=True,
    help="For color control/luminance only method, normalize output luma"
)
# Spatial control
@click.option(
    "--content-guidance",
    "content_guidance_path",
    default=None,
    type=click.Path(exists=True, dir_okay=True, file_okay=False),
    help="Content guidance channels folder path"
)
@click.option(
    "--style-guidance",
    "style_guidance_path",
    default=None,
    type=click.Path(exists=True, dir_okay=True, file_okay=False),
    help="Style guidance channels folder path"
)
@click.option(
    "--guidance-propagation-method",
    default="simple",
    type=click.Choice(["simple", "inside", "all"]),
    help="Propagation method for guidance channels"
)
@click.option(
    "--guidance-threshold",
    default=.5,
    type=threshold_or_neg,
    help="Threshold between 0 and 1 for guidance channels thresholding, or any"
         " negative value for non thresholding"
)
@click.option(
    "--guidance-propagation-kernel-size",
    default=None,
    type=odd_int,
    help="Kernel size for propagation of guidance channels (relevant for "
         "inside and all methods)"
)
@click.option(
    "--guidance-propagation-dilation",
    default=None,
    type=click.INT,
    help="Dilation for propagation of guidance channels (relevant for "
         "inside and all methods)"
)
# Meta
@click.option(
    "--device", "-d",
    default=None,
    help="PyTorch device to use (default: cuda if available, otherwise cpu)"
)
@click.option(
    "--verbose/--quiet",
    "verbose",
    default=True,
    help="Verbose flag prints info during computation (default: verbose)"
)
@click.version_option(version=neurartist.__version__)
def main(
    content_path,
    style_path,
    output_path,
    img_size,
    num_epochs,
    trade_off,
    random_init,
    random_init_path,
    content_layers,
    style_layers,
    content_weights,
    style_weights,
    color_control,
    luminance_only_normalize,
    content_guidance_path,
    style_guidance_path,
    guidance_propagation_method,
    guidance_threshold,
    guidance_propagation_kernel_size,
    guidance_propagation_dilation,
    device,
    verbose
):
    """
    Create beautiful art using deep learning.
    """

    # Check that content_guidance_path and style_guidance_path are either both
    # None or both set
    guidance_check = int(content_guidance_path is None)
    guidance_check += int(style_guidance_path is None)
    if guidance_check not in (0, 2):
        raise ValueError(
            "content_guidance and style_guidance must be both set or both None"
        )

    # If a negative value is set, no thresholding is done
    if guidance_threshold < 0:
        guidance_threshold = None

    # If the output path is a directory, we append a generated filename
    if os.path.isdir(output_path):
        output_path = os.path.join(
            output_path,
            "{}.png".format(datetime.now().strftime('%Y-%m-%dT%H:%M:%S'))
        )

    # Automatic detection of optimal device
    if device is None:
        device = "cuda" if torch.cuda.is_available() else "cpu"

    # RuntimeError if we use a non-valid device
    torch.device(device)

    # Load and transform the input images
    content_image, style_image = neurartist.utils.load_input_images(
        content_path,
        style_path,
        img_size,
        device
    )

    # If color control mode is histogram matching, update style image
    if color_control == "histogram_matching":
        neurartist.utils.color_histogram_matching(content_image, style_image)

    # Instantiate the model
    model = neurartist.models.NeuralStyle(
        content_layers=content_layers,
        style_layers=style_layers,
        content_weights=content_weights,
        style_weights=style_weights,
        trade_off=trade_off,
        device=device
    )

    # Load guidance channels if desired
    if content_guidance_path is None:
        content_guidance = None
        style_guidance = None
    else:
        kernel_params = {}
        if guidance_propagation_kernel_size is not None:
            kernel_params["kernel_size"] = \
                (guidance_propagation_kernel_size,)*2
        if guidance_propagation_dilation is not None:
            kernel_params["dilation"] = \
                (guidance_propagation_dilation,)*2

        content_guidance = neurartist.utils.load_guidance_channels(
            content_guidance_path,
            img_size,
            model,
            method=guidance_propagation_method,
            threshold=guidance_threshold,
            kernel_parameters=kernel_params,
            fallback_channel=True,
            device=device
        )
        style_guidance = neurartist.utils.load_guidance_channels(
            style_guidance_path,
            img_size,
            model,
            method=guidance_propagation_method,
            kernel_parameters=kernel_params,
            fallback_channel=True,
            device=device
        )

    # Initialize the optimizer
    if random_init:
        # Despite what's described in the article, initializing the gradient
        # descent with a random input doesn't produce good results at all
        output = torch.randn(content_image.size()).type_as(content_image.data)
    elif random_init_path is None:
        output = content_image.clone()
    else:
        output = neurartist.utils.input_transforms(
            content_image.shape[-2:],  # Use actual content size
            device=device
        )(Image.open(random_init_path))

    # The output image is updated by backward propagation
    output.requires_grad_(True)
    optimizer = torch.optim.LBFGS([output])

    # Fetch the target style and content
    content_targets, style_targets = model.get_images_targets(
        content_image,
        style_image,
        style_guidance
    )

    if verbose:
        print(f"Device={device}")
        print(f"Content={content_path}")
        print(f"Style={style_path}")
        print(f"Output={output_path}")
        print(f"Size={img_size}")
        print(f"Epochs={num_epochs}")
        print(f"Trade-off={trade_off}")
        print(f"Random init={random_init}")
        print(f"Color control={color_control}")
        print(f"Guidance={content_guidance_path is not None}")
        if content_guidance_path is not None:
            print(f"Guidance propagation method={guidance_propagation_method}")
        print(f"Model={model}")
        print()
        print("Ctrl-C to prematurely end computations")
        print("Epoch\tContent loss\tStyle loss\tOverall")

    try:
        for i in range(num_epochs):
            # Run a forward/backward pass
            content_loss, style_loss, overall_loss = model.epoch(
                output,
                content_targets,
                style_targets,
                optimizer,
                content_guidance
            )

            if verbose:
                print("{}/{}\t{:.2f}\t{:.2f}\t{:.2f}".format(
                    str(i+1).zfill(len(str(num_epochs))),
                    num_epochs,
                    content_loss,
                    style_loss,
                    overall_loss
                ))
    except KeyboardInterrupt:  # Handle manual interruption through Ctrl-C
        if verbose:
            print("Manual interruption")

    # Convert the output image
    output_image = neurartist.utils.output_transforms()(
        output
    )

    # Luminance-only
    if color_control == "luminance_only":
        output_image = neurartist.utils.luminance_only(
            neurartist.utils.output_transforms()(
                content_image
            ),
            output_image,
            luminance_only_normalize
        )

    # Finally save the output
    output_image.save(output_path)


# -*- coding: utf-8 -*-
#
# File: setuphandlers.py
#
#
# GNU General Public License (GPL)
#

__docformat__ = 'plaintext'

from collective.contact.core.interfaces import IContactCoreParameters
from plone import api
from z3c.relationfield.relation import RelationValue
from zope import component
from zope.intid.interfaces import IIntIds

import datetime
import logging

# from plone.registry.interfaces import IRegistry

logger = logging.getLogger('collective.contact.core: setuphandlers')

def isNotCollectiveContactContentProfile(context):
    return context.readDataFile("collective_contact_core_marker.txt") is None

def isNotTestDataProfile(context):
    return context.readDataFile("collective_contact_core_test_data_marker.txt") is None

def postInstall(context):
    """Called as at the end of the setup process. """
    # the right place for your custom code
    if isNotCollectiveContactContentProfile(context):
        return
    # we CAN NOT reinstall the product using portal_quickinstaller because
    # it removes manualy added fields for dexterity types
    import traceback
    for line in traceback.format_stack():
        if 'QuickInstallerTool.py' in line and 'reinstallProducts' in line:
            raise Exception('You can not reinstall this product, use portal_setup to re-apply the relevant profile !')
    # Set default values in registry
    for name in ('person_contact_details_private', 'person_title_in_title', 'use_held_positions_to_search_person',
                 'use_description_to_search_person'):
        val = api.portal.get_registry_record(name=name, interface=IContactCoreParameters)
        if val is None:
            api.portal.set_registry_record(name=name, value=True, interface=IContactCoreParameters)
    # we need to remove the default model_source added to our portal_types
    # XXX to be done

def create_test_contact_data(portal):
    """Create test contact data in portal"""
    position_types = [{'name': u'General', 'token': u'general'},
                      {'name': u'Sergeant', 'token': u'sergeant'},
                      {'name': u'Colonel', 'token': u'colonel'},
                      {'name': u'Lieutenant', 'token': u'lieutenant'},
                      {'name': u'Captain', 'token': u'captain'},
                      {'name': u'Admiral', 'token': u'admiral'},
                      ]

    organization_types = [{'name': u'Navy', 'token': u'navy'},
                          {'name': u'Army', 'token': u'army'},
                          {'name': u'Air force', 'token': u'air_force'},
                          ]

    organization_levels = [{'name': u'Corps', 'token': u'corps'},
                           {'name': u'Division', 'token': u'division'},
                           {'name': u'Regiment', 'token': u'regiment'},
                           {'name': u'Squad', 'token': u'squad'},
                           ]
# Examples structure
# ------------------
# organizations (* = organization, £ = position)
#     * Armée de terre
#         * Corps A
#             * Division Alpha
#                 * Régiment H
#                     * Brigade LH
#                         £ Sergent
#                 £ Capitaine
#             * Division Beta
#         * Corps B
#         £ Général
#
# persons (> = person, @ = held_position)
#     > De Gaulle
#         @ Armée de terre
#         @ Général
#     > Pepper
#         @ Sergent
#     > Rambo
#         @ Brigade LH
#     > Draper
#         @ Capitaine
#         @ Division Beta

    params = {'title': u"Military directory",
              'position_types': position_types,
              'organization_types': organization_types,
              'organization_levels': organization_levels,
              }
    portal.invokeFactory('directory', 'mydirectory', **params)
    mydirectory = portal['mydirectory']

    params = {'lastname': u'De Gaulle',
              'firstname': u'Charles',
              'gender': u'M',
              'person_title': u'Général',
              'birthday': datetime.date(1901, 11, 22),
              'email': u'charles.de.gaulle@private.com',
              'country': u'France',
              'city': u"Colombey les deux églises",
              'number': u'6bis',
              'street': u'rue Jean Moulin',
              'zip_code': u'52330',
              'additional_address_details': u'bâtiment D',
              'use_parent_address': False,
              'website': 'www.charles-de-gaulle.org'
              }
    mydirectory.invokeFactory('person', 'degaulle', **params)
    degaulle = mydirectory['degaulle']

    params = {'lastname': u'Pepper',
              'gender': u'M',
              'person_title': u'Mister',
              'birthday': datetime.date(1967, 6, 1),
              'email': u'stephen.pepper@private.com',
              'phone': u'0288443344',
              'city': u'Liverpool',
              'country': u'England',
              'use_parent_address': False,
              'website': 'http://www.stephen-pepper.org'
              }
    mydirectory.invokeFactory('person', 'pepper', **params)
    pepper = mydirectory['pepper']

    params = {'lastname': u'Rambo',
              'firstname': u'John',
              'phone': u'0788556644',
              'use_parent_address': True,
              }
    mydirectory.invokeFactory('person', 'rambo', **params)
    rambo = mydirectory['rambo']

    params = {'lastname': u'Draper',
              'firstname': u'John',
              'person_title': u'Mister',
              'use_parent_address': False,
              }

    mydirectory.invokeFactory('person', 'draper', **params)
    draper = mydirectory['draper']

    params = {'title': u"Armée de terre",
              'organization_type': u'army',
              'phone': u'01000000001',
              'email': u'contact@armees.fr',
              'use_parent_address': False,
              'city': u'Paris',
              'street': u'Avenue des Champs-Élysées',
              'number': u'1',
              'zip_code': u'75008',
              'country': u'France',
              'enterprise_number': 'BE123456789',
              }
    mydirectory.invokeFactory('organization', 'armeedeterre', **params)
    armeedeterre = mydirectory['armeedeterre']

    params = {'title': u"Corps A",
              'organization_type': u'corps',
              'street': u"rue Philibert Lucot",
              'city': u'Orléans',
              'country': u'France',
              'use_parent_address': False,
              }
    armeedeterre.invokeFactory('organization', 'corpsa', **params)
    corpsa = armeedeterre['corpsa']

    params = {'title': u"Corps B",
              'organization_type': u'corps',
              'use_parent_address': True,
              }
    armeedeterre.invokeFactory('organization', 'corpsb', **params)

    params = {'title': u"Division Alpha",
              'organization_type': u'division',
              'use_parent_address': True,
              }
    corpsa.invokeFactory('organization', 'divisionalpha', **params)

    params = {'title': u"Division Beta",
              'organization_type': u'division',
              'use_parent_address': True,
              }
    corpsa.invokeFactory('organization', 'divisionbeta', **params)

    divisionalpha = corpsa['divisionalpha']
    divisionbeta = corpsa['divisionbeta']

    params = {'title': u"Régiment H",
              'organization_type': u'regiment',
              'number': u"11",
              'street': u"rue de l'harmonie",
              'city': u"Villeneuve d'Ascq",
              'zip_code': u'59650',
              'country': u'France',
              'use_parent_address': False,
              }
    divisionalpha.invokeFactory('organization', 'regimenth', **params)

    regimenth = divisionalpha['regimenth']
    params = {'title': u"Brigade LH",
              'organization_type': u'squad',
              'use_parent_address': True,
              }
    regimenth.invokeFactory('organization', 'brigadelh', **params)
    brigadelh = regimenth['brigadelh']

    params = {'title': u"Général de l'armée de terre",
              'position_type': u'general',
              'email': u'general@armees.fr',
              'use_parent_address': False,
              'city': u'Lille',
              'street': u"Rue de la Porte d'Ypres",
              'number': u'1',
              'zip_code': u'59800',
              'country': u'France',
              }
    armeedeterre.invokeFactory('position', 'general_adt', **params)

    params = {'title': u"Capitaine de la division Alpha",
              'position_type': u'captain',
              'use_parent_address': True,
              }
    divisionalpha.invokeFactory('position', 'capitaine_alpha', **params)
    capitaine_alpha = divisionalpha['capitaine_alpha']

    params = {'title': u"Sergent de la brigade LH",
              'position_type': u'sergeant',
              'cell_phone': u'0654875233',
              'email': u'brigade_lh@armees.fr',
              'im_handle': u'brigade_lh@jabber.org',
              'use_parent_address': True,
              }
    brigadelh.invokeFactory('position', 'sergent_lh', **params)
    sergent_lh = brigadelh['sergent_lh']

    intids = component.getUtility(IIntIds)

    params = {'start_date': datetime.date(1940, 5, 25),
              'end_date': datetime.date(1970, 11, 9),
              'position': RelationValue(intids.getId(armeedeterre)),
              }
    degaulle.invokeFactory('held_position', 'adt', **params)

    general_adt = armeedeterre['general_adt']
    params = {'start_date': datetime.date(1940, 5, 25),
              'end_date': datetime.date(1970, 11, 9),
              'position': RelationValue(intids.getId(general_adt)),
              'label': u"Émissaire OTAN",
              'phone': u'0987654321',
              'country': u'France',
              'use_parent_address': True,
              }
    degaulle.invokeFactory('held_position', 'gadt', **params)

    params = {'start_date': datetime.date(1980, 6, 5),
              'position': RelationValue(intids.getId(sergent_lh)),
              'email': u'sgt.pepper@armees.fr',
              'phone': u'0288552211',
              'city': u'Liverpool',
              'street': u'Water Street',
              'number': u'1',
              'zip_code': u'L3 4FP',
              'country': u'England',
              'use_parent_address': False,
              'website': 'http://www.sergent-pepper.org'
              }
    pepper.invokeFactory('held_position', 'sergent_pepper', **params)

    params = {'position': RelationValue(intids.getId(capitaine_alpha)),
              'use_parent_address': True,
              }
    draper.invokeFactory('held_position', 'captain_crunch', **params)

    params = {'position': RelationValue(intids.getId(divisionbeta)),
              'use_parent_address': True,
              }
    draper.invokeFactory('held_position', 'divisionbeta', **params)

    params = {'position': RelationValue(intids.getId(brigadelh)),
              'use_parent_address': True,
              }
    rambo.invokeFactory('held_position', 'brigadelh', **params)

def createTestData(context):
    """Create test data for collective.contact.core"""
    if isNotTestDataProfile(context):
        return
    portal = context.getSite()
    create_test_contact_data(portal)


from urllib.request import urlopen
import urllib
from selenium import webdriver
from bs4 import BeautifulSoup
import http.client
from openpyxl import Workbook
from openpyxl import load_workbook
from openpyxl.writer.excel import ExcelWriter
from openpyxl.cell.cell import ILLEGAL_CHARACTERS_RE
import json
import re
import copy
import string

http.client._MAXHEADERS = 1000

def urllib_download(IMAGE_URL, pName):
	try:
		opener = urllib.request.build_opener()
		opener.addheaders = [('User-agent', 'Mozilla/5.0')]
		urllib.request.install_opener(opener)
		urllib.request.urlretrieve(IMAGE_URL, pName.replace("/","").replace("\\","")+'.jpg')
	except:
		print('no')

def getNodeText(node):
	if(node == None):
		return ""
	else:
		return node.get_text().strip()

retryCount = 0
loadCount = 0
def getHtmlFromUrl(url, type="get", para={}):
	global retryCount
	try:
		url = urllib.parse.quote(url, safe=string.printable).replace(' ','%20')
		headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.193 Safari/537.36"}

		request_obj=urllib.request.Request(url=url)
		response_obj=urllib.request.urlopen(request_obj)
		html_code=response_obj.read()
		return html_code
	except:
		print("retry"+url)
		retryCount += 1
		print(retryCount)
		if retryCount< 5:
			getHtmlFromUrl(url)
def getRenderdHtmlFromUrl(url):
	chrome_options = webdriver.ChromeOptions()
	chrome_options.add_argument('--headless')
	chrome_options.add_argument('--disable-gpu')
	chrome_options.add_argument("window-size=1024,768")

	chrome_options.add_argument("--no-sandbox")
	browser = webdriver.Chrome(chrome_options=chrome_options)

	browser.get(url)
	return browser.page_source

def writeExcel(workSheet, headers, rowIndex, info):
	cellIndex=1
	for head in headers:
		try:
			if head in info:
				content = ILLEGAL_CHARACTERS_RE.sub(r'', info[head])
				workSheet.cell(rowIndex, cellIndex).value = content.strip()
			else:
				workSheet.cell(rowIndex, cellIndex).value = ""
			cellIndex=cellIndex+1
		except:
			print(rowIndex)

def getProductInfo(url, products):
	print(str(len(products)) + url)
	tempPinfo = {}
	productHtml = getRenderdHtmlFromUrl(url)
	if productHtml != None:
		tempPinfo["link"] = url
		sope = BeautifulSoup(productHtml, "html.parser",from_encoding="utf-8")

		nameArea = sope.find("h3",attrs={"itemprop":"name"})
		imgArea = sope.find("img",attrs={"itemprop":"image"})
		tempPinfo["name"] = getNodeText(nameArea)
		if imgArea!=None:
			src = imgArea["src"]
			if src.find("https:") < 0:
				src = "https:"+src
			urllib_download(src, tempPinfo["name"])
			tempPinfo["img"] = tempPinfo["name"]+".jpg"

		specs = sope.find_all("label",attrs={"class":"pull-left"})
		for spec in specs:
			title = getNodeText(spec)
			tempPinfo[title] = getNodeText(spec.nextSibling.nextSibling)

		products.append(tempPinfo.copy())

def getProductList(url, products):
	print(url)
	productListHtml = getRenderdHtmlFromUrl(url)
	sope = BeautifulSoup(productListHtml, "html.parser",from_encoding="utf-8")
	pros = sope.find_all("article")
	for pro in pros:
		link = pro.find("a")
		if link!=None:
			getProductInfo("https://www.001chemical.com"+link["href"], products)

excelFileName="cfmats.xlsx"
wb = Workbook()
workSheet = wb.active
products = []

# getProductInfo('https://www.001chemical.com/chem/204580-28-9', products)
# getProductList('https://www.001chemical.com/chem/organic-siliconeslist1', products)
for pageIndex in range(1, 20):
	getProductList("https://www.001chemical.com/chem/organic-siliconeslist"+str(pageIndex), products)

headers=['link','name','img','CAS Number','Catalog Number','Molecular Formula',
'Molecular Weight']
rindex = 1
for p in products:
	writeExcel(workSheet, headers, rindex, p)
	if rindex%100  == 0:
		wb.save(excelFileName)
	rindex = rindex+1
print("flish")

wb.save(excelFileName)


from edgar3.filing_13f import Filing_13F
from edgar3 import __version__
import os
import datetime
import csv
from google.cloud import storage
from distutils import util
from io import StringIO

def save_filing(fil: Filing_13F, year: int, quarter: int):

    path_with_name = f"etl-13f/processed/reports/{year}/{quarter}/{fil.accession_number}.csv"

    blob = storage_bucket.blob(path_with_name)

    si = StringIO()

    csv_writer = csv.writer(si, delimiter=",", quotechar='"', quoting=csv.QUOTE_MINIMAL)
    csv_writer.writerow(
        [
            "ManagerName",
            "CIK",
            "Street1",
            "Street2",
            "City",
            "StateOrCountry",
            "ZipCode",
            "AccessionNumber",
            "PeriodOfReport",
            "SignatureDate",
            "CUSIP",
            "SecurityName",
            "TitleOfClass",
            "ValueOfShares",
            "NumberOfShares",
            "TypeOfShares",
        ]
    )
    for holding in fil.holdings:
        csv_writer.writerow(
            [
                fil.manager_name,
                fil.cik,
                fil.street1,
                fil.street2,
                fil.city,
                fil.state_or_country,
                fil.zip_code,
                fil.accession_number,
                fil.period_of_report,
                fil.signature_date,
                holding.cusip,
                holding.name_of_issuer,
                holding.title_of_class,
                holding.value,
                holding.number,
                holding.type,
            ]
        )

    blob.upload_from_string(si.getvalue().strip("\r\n"))

def process_filing(path: str, year: int, quarter: int) -> bool:
    text = storage_bucket.blob(path).download_as_string().decode("utf-8")

    if len(text) == 0:
        print("Zero length")
        log_failed_process(path, year, quarter)
        return True  # allowed failure??
    elif text.startswith("<!DOCTYPE html>"):
        print("Invalid download")
        log_failed_process(path, year, quarter)
        return True

    fil = Filing_13F(text)

    if "13F-NT" in fil.documents:
        return True  # we don't care about these
    elif "13F-NT/A" in fil.documents:
        return True  # don't care about these either
    elif "13F-HR/A" in fil.documents:
        return True
    try:
        if fil.process():
            save_filing(fil, year, quarter)
        else:
            return False
    except Exception as e:
        print(f"Exception on {path}: {e}")
        print(path)
        log_failed_process(path, year, quarter)
        return False

    return True

def log_failed_process(path: str, year: int, quarter: int):
    file_name = path.split("/")[-1]
    new_path = f"etl-13f/failed_reports/{year}Q{quarter}_{file_name}"

    print(f"Failed on {path}, copied to {new_path}")

    storage_bucket.copy_blob(storage_bucket.blob(path), storage_bucket, new_path)

print(f"Using Edgar Version: {__version__}", flush=True)

now = datetime.datetime.now()
start_year = int(os.getenv("START_YEAR", now.year))
start_quarter = int(os.getenv("START_QUARTER", (now.month - 1) // 3 + 1))
end_year = int(os.getenv("END_YEAR", now.year))
end_quarter = int(os.getenv("END_QUARTER", (now.month - 1) // 3 + 1))
bucket_name = os.getenv("BUCKET_NAME", "farr-ai-data-lake")
force_process = bool(util.strtobool(os.getenv("FORCE_PROCESS", "False")))

print(f"Processing 13Fs for {start_year}:Q{start_quarter}-{end_year}:Q{end_quarter} into {bucket_name}", flush=True)

storage_client = storage.Client()
storage_bucket = storage_client.get_bucket(bucket_name)

for year in range(start_year, end_year + 1):

    # if we're starting, the first quarter of the year can be passed in
    if year == start_year:
        quarter_low = start_quarter
    else:
        quarter_low = 1

    # and if we're ending, the last quarter of the year can be passed in
    if year == end_year:
        quarter_high = end_quarter
    else:
        if year == now.year:
            quarter_high = (now.month - 1) // 3 + 1
        else:
            quarter_high = 4

    for quarter in range(quarter_low, quarter_high + 1):

        print(f"Processing {year}:Q{quarter}", end="", flush=True)

        base_path = f"etl-13f/reports/{year}/{quarter}"
        known_blobs = [blob.name for blob in storage_bucket.list_blobs(prefix=base_path)]

        for file in known_blobs:
            process_filing(file, year, quarter)
        print(f" {len(known_blobs)} processed", flush=True)


import csv
from ctypes import pointer
import math
from time import sleep
from unittest import result
from matplotlib import pyplot as plt
import matplotlib.animation as animation
from matplotlib.pyplot import MultipleLocator
import numpy as np

def write_csv_list_a(sk_list, path):
    with open(path,'a', newline='') as f:
        csv_f = csv.writer(f)
        csv_f.writerows(sk_list)

def write_csv_list_w(sk_list, path):
    with open(path,'w', newline='') as f:
        csv_f = csv.writer(f)
        csv_f.writerows(sk_list)

def eval_list(sk_list):
    new_sk_list = []
    for i in sk_list:
        new_sk_list.append(eval(i))
    return new_sk_list

def read_csv_list(path):
    with open(path,'r') as f:
        csv_list = []
        f_csv = csv.reader(f)
        for i in f_csv:
            csv_list.append(eval_list(i))
        return csv_list

def str_list_2_float(str_list):
    ret_list = []
    for item in str_list:
        ret_list.append(float(item))
    return ret_list

def read_csv_17_list(path, epoch):
    with open(path,'r') as f:
        f_csv = csv.reader(f)
        start_index = epoch*17
        end_index = (epoch+1)*17-1
        result_list = []
        count = 0

        for item in f_csv:
            if count >= start_index and count<=end_index:
                result_list.append(str_list_2_float(item))
            count+=1
        # print(result_list)
        return result_list

# _________________________________________________________________________________________________
# _________________________________________________________________________________________________

# print(sk_list[0][0])
# print(type(sk_list[0][0]))
# print(sk_list)
# print(len(sk_list))

# Set the cs_p P17 as the initial centre point, to entablish the whole spherical coordinates system
# Pre-set the distance of each two skeleton segment points set
# 1 shoulder centre point to left shoulder point
d_cs_l_s = 1
# 2 shoulder centre point to right shoulder point
d_cs_r_s = 1
# 3 left shoulder point to left elbow point
d_l_s_eb = 1.1
# 4 left elbow point to left wrist point
d_l_eb_w = 1.5
# 5 right shoulder point to right elbow point
d_r_s_eb = 1.1
# 6 right elbow point to right wrist point
d_r_eb_w = 1.5
# 7 shoulder centre point to nose point
d_cs_n = 1
# 8 nose point to left eye point
d_n_l_e = 0.3
# 9 nose point to rigth eye point
d_n_r_e = 0.3
# 10 left point eye to left ear point
d_l_e_er = 0.35
# 11 rigth eye point to rigth ear point
d_r_e_er = 0.35
# 12 shoulder centre point to hip centre point
d_cs_ch = 3
# 13 hip centre point to left hip point
d_ch_l_h = 0.9
# 14 hip centre point to right hip point
d_ch_r_h = 0.9
# 15 left hip point to left knee point
d_l_h_k = 1.8
# 16 right hip point to right knee point
d_r_h_k = 1.8
# 17 left knee point to left ankle point
d_l_k_a = 1.8
# 18 right knee point to right ankle point
d_r_k_a = 1.8

# COCO_PERSON_KEYPOINT_NAMES = [0'nose', 1'left_eye', 2'right_eye', 3'left_ear',
#                           4'right_ear', 5'left_shoulder', 6'right_shoulder', 7'left_elbow',
#                           8'right_elbow', 9'left_wrist', 10'right_wrist', 11'left_hip', 12'right_hip',
#                           13'left_knee', 14'right_knee', 15'left_ankle', 16'right_ankle']

# ratio_d = [0:d_cs_l_s, 1:d_cs_r_s, 2:d_l_s_eb, 3:d_l_eb_w, 4:d_r_s_eb, 5:d_r_eb_w, 6:d_cs_n, 7:d_n_l_e, 8:d_n_r_e, 9:d_l_e_er,
#             10:d_r_e_er, 11:d_cs_ch, 12:d_ch_l_h, 13:d_ch_r_h, 14:d_l_h_k, 15:d_r_h_k, 16:d_l_k_a, 17:d_r_k_a]

# Segments length set
ratio_d = [d_cs_l_s, d_cs_r_s, d_l_s_eb, d_l_eb_w, d_r_s_eb, d_r_eb_w, d_cs_n, d_n_l_e, d_n_r_e, d_l_e_er,
            d_r_e_er, d_cs_ch, d_ch_l_h, d_ch_r_h, d_l_h_k, d_r_h_k, d_l_k_a, d_r_k_a]

# Define the trainning sequence-(math.pi*0.25) < theta
seq_train_set = [[17, 5], [17, 6], [5, 7], [7, 9], [6, 8], [8, 10],
[17, 0], [0, 1], [0, 2], [1, 3], [2, 4], [17, 18], [18, 11], [18, 12],
[11, 13], [12, 14], [13, 15], [14, 16]]

# Segments available zoom ratio set:17
zr = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]

# plus or minus for the x value
plus_minus = [1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
pre_plus_minus = [1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]

# Segments max available zoom ratio set
# max_zr = [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2]

# Initail x values set
x_set = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

# Define the learning rate
lr = 0.1

# Define the sk__list of last frame
sk_list_last_d2d = []

# _________________________________________________________________________________________
# Add the addictional points P17 and P18
def add_p1718(sk_list):
    # New and add the shoulder centre and hip centre points to sk_list
    cs_x2d = (sk_list[5][0] + sk_list[6][0]) / 2
    cs_y2d = (sk_list[5][1] + sk_list[6][1]) / 2

    ch_x2d = (sk_list[11][0] + sk_list[12][0]) / 2
    ch_y2d = (sk_list[11][1] + sk_list[12][1]) / 2

    sk_list.append([cs_x2d, cs_y2d])   #P17
    sk_list.append([ch_x2d, ch_y2d])   #P18
    # print(sk_list)
    return sk_list

# ______________________________________________________________________________________________________________________
# Get 2d distance of specific two points in sk_list
def get_points_d2d(sk_list, p_in__1, p_in__2):
    return math.sqrt((sk_list[p_in__1][0] - sk_list[p_in__2][0])**2 + (sk_list[p_in__1][1] - sk_list[p_in__2][1])**2)

# ______________________________________________________________________________________________________________________
# Normalizing the 3d data
def normalizing(sk_list):
    new_sk_list = []
    central_y = sk_list[17][0]
    central_z = sk_list[17][1]

    # print(central_y)
    # print(central_z)

    for item in sk_list:
        y = item[0] - central_y
        z = item[1] - central_z
        new_sk_list.append([y, -z])

    return new_sk_list

# ______________________________________________________________________________________________________________________
# ______________________________________________________________________________________________________________________
# Transforms the sk_list from 2d to 3d
# d2d^2 = (y1-y2)^2 + (z1-z2)^2
# d3d^2 = (x1-x2)^2 + d2d^2
# x1=0, x2 = -(x1-x2) = -math.sqrt(d3d^2-d2d^2)
def sk_list_to_3d(sk_list):
    global zr
    global x_set
    global ratio_d
    global plus_minus
    global seq_train_set
    global plus_minus
    global pre_plus_minus

    d2d_17_18 = get_points_d2d(sk_list, 17, 18)
    d3d_17_18 = zr[11] * d2d_17_18

    # =============================================
    update_plus_minus(get_d2d_set(sk_list))
    # =============================================

    # print('d3d_17_18 = ', d3d_17_18)

    # Deal with the plus_minus[]
    if get_points_d2d(sk_list, 1, 3) >= get_points_d2d(sk_list, 2, 4):
        plus_minus[5] = -1
        plus_minus[6] = 1
    else:
        plus_minus[5] = 1
        plus_minus[6] = -1

    # plus_minus[11] = 1
    # plus_minus[16] = -1

    # print(len(x_set))
    for i in range(len(seq_train_set)):
        global ratio_d
        d2d_seg = get_points_d2d(sk_list, seq_train_set[i][0], seq_train_set[i][1])

        # print('ratio_d[i] = ', ratio_d[i])
        # print('ratio_d[11] = ', ratio_d[11])

        d3d_seg = zr[i] * (ratio_d[i]/ratio_d[11]) * d3d_17_18
        x_f = x_set[seq_train_set[i][0]]
        x_b =  -(math.sqrt(abs(d3d_seg**2 - d2d_seg**2)) - x_f)

        zoom = 0.25
        x_set[seq_train_set[i][1]] = -zoom*plus_minus[seq_train_set[i][1]]*x_b

    plus_minus = pre_plus_minus

    temp_list = sk_list.copy()
    for i in range(len(sk_list)):
        sk_list[i] = [x_set[i]] + temp_list[i]

    # Judge if change the bnding action of the left hip_kneee_ankle
    # x-y-z
    # y-z-x
    d1 = sk_list[11][0]-sk_list[13][0]
    d2 = sk_list[13][0]-sk_list[15][0]
    if d1 != 0 and d2 != 0:
        k_l_h_k = abs((sk_list[11][1]-sk_list[13][1]) / d1)
        k_l_k_a = abs((sk_list[13][1]-sk_list[15][1]) / d2)
        # print(k_l_h_k)
        # print(k_l_k_a)
        if k_l_h_k > k_l_k_a:
            sk_list[15][0] = -(abs(sk_list[15][0]))

    # print('sk_list[15][0] = ', sk_list[15][0], '\n')

    # Judge if change the bnding action of the right hip_kneee_ankle
    d3 = sk_list[12][0]-sk_list[14][0]
    d4 = sk_list[14][0]-sk_list[16][0]
    if d3 != 0 and d4 != 0:
        k_r_h_k = abs((sk_list[12][1]-sk_list[14][1]) / d3)
        k_r_k_a = abs((sk_list[14][1]-sk_list[16][1]) / d4)
        # print(k_r_h_k)
        # print(k_r_k_a)
        if k_r_h_k > k_r_k_a:
            sk_list[16][0] = -(abs(sk_list[16][0]))

    # Judge if change the font-back locations of the shoulder ponits
    if sk_list[5][0] >= 0:
        # sk_list[11][0] = -(abs(sk_list[11][0]))
        sk_list[11][0] = abs(sk_list[11][0])
        sk_list[6][0] = -(abs(sk_list[6][0]))
    else:
        sk_list[11][0] = -(abs(sk_list[11][0]))
        sk_list[6][0] = abs(sk_list[6][0])

    if sk_list[11][0] >= 0:
        sk_list[12][0] = -(abs(sk_list[12][0]))
    else:
        sk_list[12][0] = abs(sk_list[12][0])

    if sk_list[7][0] >= sk_list[9][0]:
        sk_list[7][0] = -(abs(sk_list[7][0]))

    if sk_list[8][0] >= sk_list[10][0]:
        sk_list[8][0] = -(abs(sk_list[8][0]))

    # print('sk_list_to_3d: sk_list = ', sk_list)
    return sk_list

# ______________________________________________________________________________________________________________________
# Get draw set
def get_draw_set(points_list, sk_list_3d):
    p_xs = []
    p_ys = []
    p_zs = []

    for i in points_list:
        # p_xs.append(1)

        p_xs.append(sk_list_3d[i][0])
        p_ys.append(sk_list_3d[i][1])
        p_zs.append(sk_list_3d[i][2])

    return [p_xs, p_ys, p_zs]

# ______________________________________________________________________________________________________________________
# Get d2d set of each segments
def get_d2d_set(sk_list):
    global seq_train_set
    sk_list_new_d2d = []

    for i in range(18):
        sk_list_new_d2d.append(get_points_d2d(sk_list, seq_train_set[i][0], seq_train_set[i][1]))

    return sk_list_new_d2d

# ______________________________________________________________________________________________________________________
# Update the plus_minus
def update_plus_minus(sk_list_new_d2d):
    global x_set
    global plus_minus
    global sk_list_last_d2d

    for i in range(19):
        if x_set[i] > 0:
            if sk_list_new_d2d[i] <= sk_list_last_d2d[i]:
                plus_minus[i] = 1
        if x_set[i] < 0:
            if sk_list_new_d2d[i] <= sk_list_last_d2d[i]:
                plus_minus[i] = -1

    sk_list_last_d2d = sk_list_new_d2d

# ______________________________________________________________________________________________________________________
# Define the ax 3d drawing constraint
def ax3d_constraint(ax, sk_list_3d):
    left_line_color = 'r'
    central_line_color = 'gold'
    right_line_color = 'lime'
    msize = 8

    # ________________________________________________
    left_n_e_er = [0, 1, 3]
    ax.plot3D(xs=get_draw_set(left_n_e_er, sk_list_3d)[0],
              ys=get_draw_set(left_n_e_er, sk_list_3d)[1],
              zs=get_draw_set(left_n_e_er, sk_list_3d)[2],
              zdir='z',
              c=left_line_color,    # line color
              marker='o',           # mark style
              mfc='cyan',           # marker facecolor
              mec='g',              # marker edgecolor
              ms=msize,             # marker size
              linewidth=3.0         # linewidth
            )

    # ________________________________________________
    right_n_e_er = [0, 0, 4]
    ax.plot3D(xs=get_draw_set(right_n_e_er, sk_list_3d)[0],
              ys=get_draw_set(right_n_e_er, sk_list_3d)[1],
              zs=get_draw_set(right_n_e_er, sk_list_3d)[2],
              zdir='z',
              c=right_line_color,   # line color
              marker='o',           # mark style
              mfc='cyan',           # marker facecolor
              mec='g',              # marker edgecolor
              ms=msize,             # marker size
              linewidth=3.0         # linewidth
            )

    # ________________________________________________
    n_cs_ch = [0, 17, 18]
    ax.plot3D(xs=get_draw_set(n_cs_ch, sk_list_3d)[0],
              ys=get_draw_set(n_cs_ch, sk_list_3d)[1],
              zs=get_draw_set(n_cs_ch, sk_list_3d)[2],
              zdir='z',
              c=central_line_color,  # line color
              marker='o',            # mark style
              mfc='cyan',            # marker facecolor
              mec='g',               # marker edgecolor
              ms=msize,              # marker size
              linewidth=3.0          # linewidth
            )

    # ________________________________________________
    l_cs_s_e_w = [17, 5, 7, 9]
    ax.plot3D(xs=get_draw_set(l_cs_s_e_w, sk_list_3d)[0],
              ys=get_draw_set(l_cs_s_e_w, sk_list_3d)[1],
              zs=get_draw_set(l_cs_s_e_w, sk_list_3d)[2],
              zdir='z',
              c=left_line_color,     # line color
              marker='o',            # mark style
              mfc='cyan',            # marker facecolor
              mec='g',               # marker edgecolor
              ms=msize,              # marker size
              linewidth=3.0          # linewidth
            )

    # ________________________________________________
    r_cs_s_e_w = [17, 6, 8, 10]
    ax.plot3D(xs=get_draw_set(r_cs_s_e_w, sk_list_3d)[0],
              ys=get_draw_set(r_cs_s_e_w, sk_list_3d)[1],
              zs=get_draw_set(r_cs_s_e_w, sk_list_3d)[2],
              zdir='z',
              c=right_line_color,    # line color
              marker='o',            # mark style
              mfc='cyan',            # marker facecolor
              mec='g',               # marker edgecolor
              ms=msize,              # marker size
              linewidth=3.0          # linewidth
            )

    # ________________________________________________
    l_ch_h_k_a = [18, 11, 13, 15]
    ax.plot3D(xs=get_draw_set(l_ch_h_k_a, sk_list_3d)[0],
              ys=get_draw_set(l_ch_h_k_a, sk_list_3d)[1],
              zs=get_draw_set(l_ch_h_k_a, sk_list_3d)[2],
              zdir='z',
              c=left_line_color,     # line color
              marker='o',            # mark style
              mfc='cyan',            # marker facecolor
              mec='g',               # marker edgecolor
              ms=msize,              # marker size
              linewidth=3.0          # linewidth
            )

    # ________________________________________________
    r_ch_h_k_a = [18, 12, 14, 16]
    ax.plot3D(xs=get_draw_set(r_ch_h_k_a, sk_list_3d)[0],
              ys=get_draw_set(r_ch_h_k_a, sk_list_3d)[1],
              zs=get_draw_set(r_ch_h_k_a, sk_list_3d)[2],
              zdir='z',
              c=right_line_color,    # line color
              marker='o',            # mark style
              mfc='cyan',            # marker facecolor
              mec='g',               # marker edgecolor
              ms=msize,              # marker size
              linewidth=3.0          # linewidth
            )

    # ________________________________________________
    n_cs_ch = [0, 17, 18]
    ax.plot3D(xs=get_draw_set(n_cs_ch, sk_list_3d)[0],
              ys=get_draw_set(n_cs_ch, sk_list_3d)[1],
              zs=get_draw_set(n_cs_ch, sk_list_3d)[2],
              zdir='z',
              c=central_line_color,  # line color
              marker='o',            # mark style
              mfc='cyan',            # marker facecolor
              mec='g',               # marker edgecolor
              ms=msize,              # marker size
              linewidth=3.0          # linewidth
            )

    # ________________________________________________
    # 设置坐标轴标题和刻度
    ax.set(
        xlabel='X',
        ylabel='Y',
        zlabel='Z',
        )

    x_major_locator = MultipleLocator(100)
    y_major_locator = MultipleLocator(300)
    ax.xaxis.set_major_locator(x_major_locator)
    ax.yaxis.set_major_locator(y_major_locator)

    # 调整视角
    ax.view_init(elev=30,    # 仰角
                 azim=-20   # 方位角
                )

    return ax

# ______________________________________________________________________________________________________________________
# Draw the skeleton
# def show3Dske(sk_list_3d):
def show3Dske(csv_path, mod):

    # print('show3Dske: sk_list_3d = ', sk_list_3d)

    fig = plt.figure()
    ax = fig.add_subplot(111, projection='3d')

    # ===================================
    # ===================================
    ax.set_box_aspect((1, 2, 5))
    # ===================================
    # ===================================

    if mod == 'p':
        sk_list_i = read_csv_17_list(csv_path, 0)
        sk_list19 = add_p1718(sk_list_i)
        # print('1 sk_list19 = ', sk_list19)
        sk_list19 = normalizing(sk_list19)
        # print('2 sk_list19 = ', sk_list19)

        sk_list_3d = sk_list_to_3d(sk_list19)
        # Save the 3D data
        path_data_3d = csv_path + '_3d.csv'
        write_csv_list_w(sk_list_3d, path_data_3d)

        ax3d_constraint(ax, sk_list_3d)

    if mod == 'v':
        def update(i):
            # print(i)
            sk_list_i = read_csv_17_list(csv_path, i)
            sk_list19 = add_p1718(sk_list_i)
            # print('1 sk_list19 = ', sk_list19)
            sk_list19 = normalizing(sk_list19)
            # print('sk_list19 = ', sk_list19)

            sk_list_3d = sk_list_to_3d(sk_list19)

            # Save the 3D data
            path_data_3d = csv_path + '_3d.csv'
            write_csv_list_a(sk_list_3d, path_data_3d)

            plt.cla()
            ax3d_constraint(ax, sk_list_3d)

        # anim = animation.FuncAnimation(fig, func=update, blit=False, interval=50, frames=600,
        anim = animation.FuncAnimation(fig, func=update, blit=False, interval=50,
                                  repeat=False, cache_frame_data=False)

        # Set here to save the result gif
        # _____________________________________
        anim.save(csv_path + '.gif')
        # _____________________________________

    plt.autoscale(False)

    # Show picture
    plt.show()

# Test()
# =============================================================================
# =============================================================================
# =============================================================================
def test_cycle():

    csv_path1 = './pictures/7.jpg.csv'
    show3Dske(csv_path1, 'p')

    # csv_path2 = './csv/3.mp4.csv'
    # show3Dske(csv_path2, 'v')

    # csv_path3 = './longvideos/1.mp4.csv'
    # show3Dske(csv_path3, 'v')

test_cycle()


import tensorflow as tf
import pandas as pd
from  tensorflow.examples.tutorials.mnist  import  input_data
import numpy as np

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

#mnist = input_data.read_data_sets('./data/', one_hot = True)
def numtolist(num):
    '将标签转化为01数组'
    r1 = np.asarray([0]*21)
    r1[20 - num] = 1
    return r1

def numto2D(a):
    '将标签转化为01数组'
    if a >= 18:
        return np.asarray([0,0,1])
    elif a >= 12:
        return np.asarray([0,1,0])
    else:
        return np.asarray([1,0,0])

def train(hidden_units_size,training_iterations):
    num_classes = 3  # 输出大小
    input_size = 32  # 输入大小
    batch_num = 10
    # hidden_units_size = 60  # 隐藏层节点数量
    # training_iterations = 20

    data = pd.read_csv("student-mat.csv")
    # print(data.head())
    # 输入数据

    # 数据类型转换 - 转换为可计算的数据类型int
    for col in data.columns:
        if (not str(data[col].dtype).startswith("int")):
            # print("Coloum Name ", col, " Type ", data[col].dtype)
            # print("Unique values for ", col, data[col].unique(), "\n")
            values = data[col].unique() # 取出该列所以可能取值
            convertor = dict(zip(values, range(len(values)))) # 定义转换函数
            data[col] = [convertor[item] for item in data[col]] # 将定性数据转为定量的数据
            # print("Coloum Name ", col, " Type ", data[col].dtype)
            # print("Unique values for ", col, data[col].unique(), "\n")

    #print(data.describe()) # 查看数据描述信息，均值,max,min
    print('Data Size ', data.shape)

    training_features = ['school', 'sex', 'age', 'address', 'famsize', 'Pstatus', 'Medu', 'Fedu','Mjob', 'Fjob', 'reason', 'guardian', 'traveltime', 'studytime',
           'failures', 'schoolsup', 'famsup', 'paid', 'activities', 'nursery',
           'higher', 'internet', 'romantic', 'famrel', 'freetime', 'goout', 'Dalc',
           'Walc', 'health', 'absences', 'G1', 'G2']
    label_feature = ['G3']
    selected_feature_data = data

    # 区分训练集和测试集
    num_data = data.shape[0]
    num_input = data.shape[1] - 1
    number_training = int(0.7 * num_data) # 训练数据个数
    number_testing = int(num_data - number_training) # 测试数据个数
    print("number of traning :",number_training)
    print("number of testing :",number_testing)

    # -- 训练数据集 --
    training_data_features = np.array(selected_feature_data.head(number_training)[training_features])
    # 转为4D
    training_data_labels = np.zeros([number_training,num_classes], dtype = float, order = 'C')
    temp_label = np.array(selected_feature_data.head(number_training)[label_feature])

    for i in range(number_training):
        label = temp_label[i] # 取出当前标签
        training_data_labels[i] = numto2D(int(label))

    # print('training:')
    # print(training_data_features[0:5])
    # print(training_data_labels[0:5])

    # -- 测试数据集 --house_info.loc[3:6]
    testing_data_features = np.array(selected_feature_data.loc[number_testing:][training_features])
    # 转为4D
    testing_data_labels = np.zeros([number_training,num_classes], dtype = float, order = 'C')
    temp_label = np.array(selected_feature_data.loc[number_testing:][label_feature])

    for i in range(number_testing):
        label = temp_label[i] # 取出当前标签
        testing_data_labels[i] = numto2D(int(label))

    # ---------------  以上，数据集已经整理好 ---------------

    # print('训练数据集特征:',training_data_features.shape)
    # print('训练数据集标签:',training_data_labels.shape)
    # print('测试数据集特征:',testing_data_features.shape)
    # print('测试数据集标签:',testing_data_labels.shape)

    # 300 20 0.05
    X = tf.placeholder(tf.float32, shape = [None, input_size])
    Y = tf.placeholder(tf.float32, shape = [None, num_classes])

    # W1 = tf.Variable(tf.random_normal ([input_size, num_classes], stddev = 0.1))
    # B1 = tf.Variable(tf.constant (0.1), [num_classes])
    #final_opt = tf.matmul(X, W1) + B1  # 输入层到隐藏层正向传播

    # 含一个隐层
    W1 = tf.Variable(tf.random_normal ([input_size, hidden_units_size], stddev = 0.1))
    B1 = tf.Variable(tf.constant (0.1), [hidden_units_size])
    W2 = tf.Variable(tf.random_normal ([hidden_units_size, num_classes], stddev = 0.1))
    B2 = tf.Variable(tf.constant (0.1), [num_classes])

    hidden_opt = tf.matmul(X, W1) + B1  # 输入层到隐藏层正向传播
    hidden_opt = tf.nn.relu(hidden_opt)  # 激活函数，用于计算节点输出值
    final_opt = tf.matmul(hidden_opt, W2) + B2  # 隐藏层到输出层正向传播

    # 对输出层计算交叉熵损失
    loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=Y, logits=final_opt))
    # 梯度下降算法，这里使用了反向传播算法用于修改权重，减小损失
    opt = tf.train.GradientDescentOptimizer(0.05).minimize(loss)

    # 初始化变量
    init = tf.global_variables_initializer()
    # 计算准确率
    correct_prediction =tf.equal (tf.argmax (Y, 1), tf.argmax(final_opt, 1))
    accuracy = tf.reduce_mean(tf.cast(correct_prediction, 'float'))

    sess = tf.Session ()
    sess.run (init)
    train_acc = []
    test_acc = []
    train_loss = []
    for i in range (training_iterations) :
        batch_input = training_data_features[i*batch_num:i*batch_num+batch_num]
        batch_labels = training_data_labels[i*batch_num:i*batch_num+batch_num]
        # 训练
        training_loss = sess.run ([opt, loss], feed_dict = {X: batch_input, Y: batch_labels})
        train_accuracy = accuracy.eval (session = sess, feed_dict = {X: batch_input,Y: batch_labels})
        test_accuracy = accuracy.eval(session=sess, feed_dict={X: testing_data_features, Y: testing_data_labels})
        train_acc.append(train_accuracy)
        test_acc.append(test_accuracy)
        train_loss.append(training_loss[1])
        print ("step : %d, training accuracy = %2f ,training loss %2f,test_accuracy %2f "% (i, train_accuracy,training_loss[1],test_accuracy))

    return  train_acc,test_acc,train_loss
    # print('testing -----')
    # test_accuracy = accuracy.eval(session=sess, feed_dict={X: testing_data_features, Y: testing_data_labels})
    # print("tesing accuracy = %2f " % (test_accuracy))

def averagenum(num):
    print(num)
    nsum = 0
    for i in range(len(num)):
        nsum += num[i]
    return nsum / len(num)

def lineplot(x_data, y_data, x_label="", y_label="", title=""):
    # Create the plot object
    _, ax = plt.subplots()    # Plot the best fit line, set the linewidth (lw), color and
    # transparency (alpha) of the line
    ax.plot(x_data, y_data, lw = 2, color = '#539caf', alpha = 1)    # Label the axes and provide a title
    ax.set_title(title)
    ax.set_xlabel(x_label)
    ax.set_ylabel(y_label)
    return ax

def plot_trendline1(x_num, y, n):
    ax1 = plt.subplot(2, 2, 1)
    plt.sca(ax1) # 选择子图1
    plt.legend()  # 添加这个才能显示图例
    x = np.linspace(1, x_num, x_num)
    plt.xticks(x)
    parameter = np.polyfit(x, y, n) # 计算趋势线
    y2 = [0]*len(y)
    for i in range(len(y)) :
        y2[i] = parameter[0] * i ** 3 + parameter[1] * i ** 2 + parameter[2] * i + 0.6
    plt.xlabel('training step', color='black')
    plt.ylabel('training accuracy', color='black')
    plt.scatter(x, y,label='training accuracy') # 画散点图
    plt.plot(x, y2, color='g',label='trendline')# 画趋势线
    plt.legend() # 添加这个才能显示图例

def plot_trendline2(x_num, y, n):
    ax2 = plt.subplot(2, 2, 2)
    plt.sca(ax2) # 选择子图2
    x = np.linspace(1, x_num, x_num)
    plt.xticks(x)
    parameter = np.polyfit(x, y, n)
    y2 = [0]*len(y)
    print(y2)
    for i in range(len(y)) :
        y2[i] = parameter[0] * i ** 3 + parameter[1] * i ** 2 + parameter[2] * i + 0.6
    avg = averagenum(y)
    # for i in range(len(y2)):
    #     y2[i] = y2[i] + avg
    print('----- training svg',avg)
    plt.xlabel('training step', color='black')
    plt.ylabel('testing accuracy', color='black')
    plt.scatter(x, y,label='testing accuracy')
    plt.plot(x, y2, color='g',label='trendline')
    plt.legend()

def plot_trendline3(x_num, y, n):
    ax3 = plt.subplot(2, 2, 3)
    plt.sca(ax3) # 选择子图3
    x = np.linspace(1, x_num, x_num)
    plt.xticks(x)
    # plt.bar(x, y, width=0.6, tick_label=x, fc='y',color='blue')
    # plt.xlabel('training step', color='black')
    # plt.ylabel('cross entropy', color='black')
    # plt.legend()
    # plt.show()
    parameter = np.polyfit(x, y, n)
    y2 = [0] * len(y)
    print(y2)
    for i in range(len(y)):
        y2[i] = parameter[0] * i ** 3 + parameter[1] * i ** 2 + parameter[2] * i + 1.2
    avg = averagenum(y)
    # for i in range(len(y2)):
    #     y2[i] = y2[i] + avg
    print('----- training svg', avg)
    plt.xlabel('training step', color='black')
    plt.ylabel('training cross entropy', color='black')
    plt.scatter(x, y, label='training cross entropy')
    plt.plot(x, y2, color='r', label='trendline')
    plt.legend()  # 添加这个才能显示图例
    plt.show()
    # plt.barh(range(len(x)), y, tick_label=x)
    # plt.show()
    # parameter = np.polyfit(x, y, n)
    # y2 = [0]*len(y)
    # print(y2)
    # for i in range(len(y)) :
    #     y2[i] = parameter[0] * i ** 3 + parameter[1] * i ** 2 + parameter[2] * i + 1.0
    # avg = averagenum(y2)
    # for i in range(len(y2)):
    #     y2[i] = y2[i] + avg
    # plt.xlabel('testing step', color='black')
    # plt.ylabel('cross entropy', color='black')
    # plt.scatter(x, y)
    # plt.plot(x, y2, color='g')
    # plt.show()

if __name__  == '__main__':
    train_acc, test_acc, train_loss = train(15, 18)
    # print(train_acc)
    # print(test_acc)
    # print(train_loss)
    # lineplot(range(28), test_acc, x_label="step", y_label="test_acc", title="")
    # lineplot(range(28), train_acc, x_label="step", y_label="train_acc", title="")
    # plt.show(lineplot(range(28), train_loss, x_label="step", y_label="train_acc", title=""))
    plot_trendline1(18, test_acc,3)
    plot_trendline2(18, train_acc, 3)
    plot_trendline3(18, train_loss, 3)
    # dotImg(range(21), test_acc)
    # dotImg(range(21), train_acc)
    # dotImg(range(21), train_loss)

   # choose step17


import os

from sanic import Sanic
from sanic_session import Session, AIORedisSessionInterface

from ..config import config, log_config
from ..container import Container
from ..adapter.blueprint import handle_exception, message_blueprint,\
    post_blueprint, file_blueprint, user_blueprint

os.makedirs(config['DATA_PATH'], 0o755, True)

app = Sanic(config['NAME'].capitalize(), log_config=log_config)
app.config.update(config)

app.error_handler.add(Exception, handle_exception)

app.static('/files', os.path.join(config['DATA_PATH'], config['UPLOAD_DIR']),
           stream_large_files=True)

app.blueprint(message_blueprint)
app.blueprint(post_blueprint)
app.blueprint(file_blueprint)
app.blueprint(user_blueprint)

@app.listener('before_server_start')
async def server_init(app, loop):
    container = Container(config, log_config)
    await container.on_init

    Session(app, AIORedisSessionInterface(
        container.cache, expiry=config['SESSION_EXPIRY']))

@app.listener('after_server_stop')
async def server_clean(app, loop):
    await Container().clean()

if __name__ == '__main__':
    app.run(host=config['HOST'], port=config['PORT'], debug=config['DEBUG'],
            auto_reload=config['AUTO_RELOAD'], access_log=config['ACCESS_LOG'],
            workers=config['WORKERS'])


from typing import List
import random

##################################

# GENERAL STUFF

class Queen():
    def __init__(self, pos: int, threats: int = -1):
        # the position of the queen on the board
        self.pos = pos
        # the number of threats on the queen
        self.threats = threats

    def __eq__(self, o: object) -> bool:
        return (self.pos == o.pos) & (self.threats == o.threats)

    def __str__(self) -> str:
        return f'Queen(pos: {self.pos}, threats: {self.threats})'

def calc_threats(queens: List[Queen]) -> List[int]:
    # check threats on same row, main diagonal and antidiagonal
    # the check for same row is obvious: [0, 2, 1, 2]
    # loop and check for duplicated of the number (position)

    # the check for the diagonal goes like this:
    # the diagonal is formed by pos, pos + 1, pos + 2, pos + 3, and so on....
    # the same for pos - 1, pos - 2, pos - 3 ....
    # for a conflict to occur on the diagonal, pos will be an increment of ouu current queen position,
    # also the increment increases by 1 when the position increse
    # example: [1, 3, 0, 2] has no conflict even though the last queen is an increment of the first queen position.
    # and that is because the increment is not constant and increses as we go further.
    # the same for why the second queen is not counted as a threat, it is not a single increment.
    # the increment changes to a decrement for other sides of the diagonal.

    length = len(queens)
    threats = [0] * length

    # check for same row threats
    col = 0
    while col < length:
        # check for +ve same row threats
        row = col + 1
        while row < length:
            if (queens[row].pos == queens[col].pos):
                threats[col] += 1
            row += 1

        # check for -ve same row threats
        row = col - 1
        while row > -1:
            if (queens[row].pos == queens[col].pos):
                threats[col] += 1
            row -= 1

        col += 1

    # check for main diagonal threats
    col = 0
    while col < length:
        # check for +ve main diagonal
        row = col + 1
        inc = 1
        while row < length:
            if queens[row].pos == queens[col].pos + inc:
                threats[col] += 1
            inc = inc + 1
            row = row + 1

        # check for -ve main diagonal
        row = col - 1
        dec = 1
        while row > -1:
            if queens[row].pos == queens[col].pos - dec:
                threats[col] += 1
            dec = dec + 1
            row = row - 1

        col += 1

    # check for antidiagonal threats
    col = 0
    while col < length:
        # check for +ve antidiagonal threats
        row = col + 1
        dec = 1
        while row < length:
            if queens[row].pos == queens[col].pos - dec:
                threats[col] += 1
            dec = dec + 1
            row = row + 1

        # check for -ve antidiagonal threats
        row = col - 1
        inc = 1
        while row > -1:
            if queens[row].pos == queens[col].pos + inc:
                threats[col] += 1
            inc = inc + 1
            row = row - 1

        col += 1

    return threats

def update_threats(queens: List[Queen], threats: List[int]) -> None:
    for i, queen in enumerate(queens):
        queen.threats = threats[i]

def copy_queens(queens: List[Queen]) -> List[Queen]:
    copy = []
    for queen in queens:
        copy.append(Queen(queen.pos, queen.threats))
    return copy

##################################

# A* STUFF

class BoardNode():
    # no. of steps default to 0 representing the initial (start) state
    def __init__(self, queens: List[Queen] = None, steps: int = 0):
        # the queens that defines the state of this board node
        # the index of the array itself represents what col we are at.
        # the value in the index represents what row we are at.
        # example: [2, 0, 1], represents:
        #   0 1 2   <- column
        # 0 - x -
        # 1 - - x
        # 2 x - -
        # ^ row
        self.queens = queens

        # total_threats "h": defines the total number of threats on the board
        total_threats = 0
        for queen in queens:
            total_threats += queen.threats
        self.total_threats = total_threats

        # steps "g": defines the number of steps taken by a queen to reach this state
        self.steps = steps
        # f = g + h
        self.cost = self.steps + self.total_threats

    def __eq__(self, o: object) -> bool:
        return self.queens == o.queens

    def __str__(self) -> str:
        str = '['
        for q in self.queens:
            str += f'{q.pos}, '
        str += ']'
        return f'BoardNode({self.cost} = {self.steps} + {self.total_threats}, queens: {str})'

def generate_states(queensList: List[Queen]) -> List[BoardNode]:
    # the goal of this function is to generate all possible moves
    # or (states), a state represents the board, hence the usage of BoardNode
    # a boardNode stores the cost of reaching (steps) it and the amount of threats in it
    # this is used to calculate its cost (cost [f] = steps [g] + h [total_threats])
    # a boardNode is generated by moving a queen, using the new positions and threats to create it.
    # after exploring all possible (vertical) moves, they all will be added to the possible_states.
    # the possible states will be used to pick the lowest cost, and then repeat.

    possible_states: List[BoardNode] = []

    # generate +ve moves
    col = 0
    while col < len(queensList):
        queens = copy_queens(queensList)

        steps = 0
        row = queens[col].pos
        while row < len(queens) - 1:
            queens[col].pos += 1
            steps += 1

            new_threats = calc_threats(queens)
            update_threats(queens, new_threats)

            qs = copy_queens(queens)
            possible_states.append(BoardNode(qs, steps))

            row += 1

        col += 1

    # generate -ve moves
    col = 0
    while col < len(queensList):
        queens = copy_queens(queensList)

        steps = 0
        row = queens[col].pos
        while row > 0:
            queens[col].pos -= 1
            steps += 1

            new_threats = calc_threats(queens)
            update_threats(queens, new_threats)
            qs = copy_queens(queens)
            possible_states.append(BoardNode(qs, steps))

            row -= 1

        col += 1

    def sortKey(e: BoardNode):
        return e.cost

    possible_states.sort(reverse=True, key=sortKey)

    return possible_states

def rand_initial_state(N: int) -> BoardNode:
    queens: List[Queen] = []
    for n in range(N):
        queens.append(Queen(random.randint(0, N - 1)))
    threats = calc_threats(queens)
    update_threats(queens, threats)
    return BoardNode(queens)

def a_star(state: BoardNode, visited_states: List[BoardNode], steps_count):
    # generate possible next moves/states
    states: List[BoardNode] = generate_states(state.queens)
    # get the move/state with lowest cost
    next_state: BoardNode = states.pop()

    # if the popped state and the one before it has equal cost (f),
    # check if the one before it has lower threats (h), if yes choose it.
    if next_state.cost == states[-1].cost:
        if states[-1].total_threats < next_state.total_threats:
            next_state = states.pop()

    # check if the goal state has been reached.
    # the goal states is defined by the threats (h) being 0
    if next_state.total_threats == 0:
        visited_states.clear()
        print('HOLAAA')
        print(f'final state: {next_state}')
        steps_count[0] += 1
        return next_state

    # check if the popped state has already been visited before
    # if yes, get the next possible state/move, and repeat.
    i = 0
    while i < len(visited_states):
        if next_state == visited_states[i]:
            if (len(states) > 0):
                next_state = states.pop()
                i = 0
                continue
        i += 1

    steps_count[0] += 1
    visited_states.append(next_state)
    return next_state

##################################

# GENETIC STUFF

MUTATE_RATE: float = 0.05
CROSSOVER_RATE: float = 1.0
MULTIPOINT: bool = False

class Solution():
    def __init__(self, queens: List[Queen]):
        # the queens define the solution/chromosome,
        # The position of each queen is a gene.
        # the queen object itself is just a wrapper class for the queen position and theeats on it.
        self.queens = queens

        # total_threats (fitness): the fitness of the solution, lower is better. 0 is solved.
        total_threats = 0
        for queen in queens:
            total_threats += queen.threats
        self.total_threats = total_threats

    def __str__(self) -> str:
        str = '['
        for q in self.queens:
            str += f'{q.pos}, '
        str += ']'
        return f'Solution(fitness: {self.total_threats}, queens: {str})'

# creates a random solution (random queen positions)
def create_solution(N) -> Solution:
    queens: List[Queen] = []
    for n in range(N):
        queens.append(Queen(random.randint(0, N - 1)))
    threats = calc_threats(queens)
    update_threats(queens, threats)
    return Solution(queens)

# returns a mutated gene (a new position for a queen)
def mutated_gene(N: int) -> int:
    return random.randint(0, N - 1)

# where the magic happens,
# depending on the passe paras it will crossover and mutate to produce a new solution out of the two passed solutions.
def mate(parent1: Solution, parent2: Solution, mutate_rate: float = MUTATE_RATE, multipoint: bool = MULTIPOINT, crossover_rate: float = CROSSOVER_RATE) -> Solution:

    child: Solution = None

    prob = random.random()

    if prob < crossover_rate:
        child = crossover(parent1, parent2, multipoint)
    else:
        child = parent1 if parent1.total_threats < parent2.total_threats else parent2

    for queen in child.queens:
        prob = random.random()
        if prob < mutate_rate:
            queen.pos = mutated_gene(len(child.queens))

    return child

# takes two solutions and crosses them over on a random point,
# this produces to children, the fittest is returned.
def crossover(parent1: Solution, parent2: Solution, multipoint: bool = False) -> Solution:
    if not multipoint:
        point: int = random.randint(0, len(parent1.queens) - 1)

        queens1: List[Queen] = copy_queens(
            parent1.queens[:point] + parent2.queens[point:])
        queens2: List[Queen] = copy_queens(
            parent2.queens[:point] + parent1.queens[point:])

        new_threats = calc_threats(queens1)
        update_threats(queens1, new_threats)
        new_threats = calc_threats(queens2)
        update_threats(queens2, new_threats)

        child1: Solution = Solution(queens1)
        child2: Solution = Solution(queens2)

        return child1 if child1.total_threats < child2.total_threats else child2

def genetic(N: int, population_size: int, generations: int, elitism: bool = True, mutate_rate: float = MUTATE_RATE, multipoint: bool = MULTIPOINT, crossover_rate: float = CROSSOVER_RATE, generation_count=[0]) -> Solution:
    generation: int = 1
    solved: bool = False
    population: List[Solution] = []

    for _ in range(population_size):
        population.append(create_solution(N))

    while (generation <= generations) & (not solved):

        # sort the population based on fitness (threats)
        population.sort(key=lambda solution: solution.total_threats)

        if population[0].total_threats == 0:
            solved = True
            print('Hola FOUND ITTTT')
            print(population[0])
            generation_count[0] = generation
            return population[0]

        new_generation: List[Solution] = []

        if elitism:
            # pass the top 10% solutions to the next generation
            top_ten = int((10 * population_size) / 100)
            new_generation.extend(population[:top_ten])

        # pick and mate parents for the next genration randomly from the top 50%
        top_fifty = int((50 * population_size) / 100)
        for _ in range(int((90 * population_size) / 100)):
            parent1 = random.choice(population[:top_fifty])
            parent2 = random.choice(population[:top_fifty])

            child = mate(parent1, parent2, mutate_rate,
                         multipoint, crossover_rate)
            new_generation.append(child)

        population = new_generation

        # print(f'gen: {generation}, {population[0]}')

        generation += 1

        generation_count[0] = generation

    population.sort(key=lambda solution: solution.total_threats)
    return population[0]

# print(genetic(8, 100, 100))


import time
import os
import numpy as np
import pyaudio
import tensorflow as tf
import speech_recognition as sr
from datetime import datetime
import wave
import threading
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
from ThreeCharacterClassicInference import ThreeCharacterClassicInference
from tts import text_to_speech

# Set seeds for reproducibility
seed = 42
tf.random.set_seed(seed)
np.random.seed(seed)

# Constants
FRAMES_PER_BUFFER = 1024
FORMAT = pyaudio.paInt16
CHANNELS = 1
RATE = 16000
TAILING_DURATION = 1.5  # Tailing audio duration in seconds
KEYWORD = "你好"

# Global variables
stop_plotting_thread = False

# Load the model
interpreter = tf.lite.Interpreter(model_path="hey_ego_44100_obama_5.tflite")
interpreter.allocate_tensors()
input_details = interpreter.get_input_details()
output_details = interpreter.get_output_details()
three_char_classic_model = ThreeCharacterClassicInference(
    model_path="3character.tflite", dictionary_path="3character_dict.pickle"
)

def get_spectrogram(waveform):
    """Convert the audio waveform to a spectrogram."""
    input_len = 66150
    waveform = waveform[:input_len]
    zero_padding = tf.zeros([input_len] - tf.shape(waveform), dtype=tf.float32)
    waveform = tf.cast(waveform, dtype=tf.float32)
    equal_length = tf.concat([waveform, zero_padding], 0)
    spectrogram = tf.signal.stft(equal_length, frame_length=512, frame_step=256)
    spectrogram = tf.abs(spectrogram)
    spectrogram = spectrogram[..., tf.newaxis]
    return spectrogram

def preprocess_audiobuffer(waveform):
    """Preprocess the audio buffer for the model."""
    waveform = waveform / 32768
    waveform = tf.convert_to_tensor(waveform, dtype=tf.float32)
    spectogram = get_spectrogram(waveform)
    spectogram = tf.expand_dims(spectogram, 0)
    return spectogram

def predict_mic(audio):
    """Predict the command from the audio."""
    start = time.time()
    spec = preprocess_audiobuffer(audio)
    interpreter.set_tensor(input_details[0]["index"], spec)
    interpreter.invoke()
    prediction = tf.nn.softmax(interpreter.get_tensor(output_details[0]["index"]))
    label_pred = np.argmax(prediction, axis=1)
    time_taken = time.time() - start
    print(prediction)
    print(label_pred)
    print(f"Predicted in: {time_taken}")
    return label_pred[0]

def save_audio_to_wav(audio_buffer, output_folder=None, rate=44100):
    """Save the audio buffer to a mono channel WAV file with a unique name."""
    output_folder = output_folder or os.getcwd()
    os.makedirs(output_folder, exist_ok=True)

    # Generate a unique name for the WAV file
    timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
    file_name = f"audio_{timestamp}.wav"
    output_file = os.path.join(output_folder, file_name)

    # Open a WAV file for writing
    with wave.open(output_file, "wb") as wav_file:
        wav_file.setnchannels(1)  # Mono channel
        wav_file.setsampwidth(
            pyaudio.get_sample_size(pyaudio.paInt16)
        )  # 16-bit samples
        wav_file.setframerate(rate)  # Set the frame rate
        wav_file.writeframes(audio_buffer.tobytes())  # Write the audio buffer data

    return output_file

# def plot_spectrogram(audio_buffer, spectrogram_func, stop_event):
#     while not stop_event.is_set():
#         # Set up the initial plot
#         fig, ax = plt.subplots()
#         spec = spectrogram_func(audio_buffer)
#         im = ax.imshow(
#             spec,
#             aspect="auto",
#             origin="lower",
#             cmap="viridis",
#             vmin=0.0,
#             vmax=1.0,
#         )
#         ax.set_xlabel("Time")
#         ax.set_ylabel("Frequency")
#         plt.colorbar(im, ax=ax)
#         ax.set_title("Spectrogram")

#         # Add a text element to display the update frequency
#         freq_text = ax.text(
#             0.01, 0.95, "", transform=ax.transAxes, fontsize=10, color="white"
#         )

#         # Update function for the plot
#         def update(frame):
#             nonlocal audio_buffer
#             start_time = time.time()
#             spec = spectrogram_func(audio_buffer)
#             im.set_data(spec)
#             im.set_clim(vmin=0.0, vmax=1.0)
#             # Calculate and display the update frequency
#             end_time = time.time()
#             update_freq = 1 / (end_time - start_time)
#             freq_text.set_text(f"{update_freq:.2f} fps")

#             return [im, freq_text]

#         # Create the animation
#         ani = FuncAnimation(fig, update, blit=True, interval=RATE / FRAMES_PER_BUFFER)

#         # Show the plot
#         plt.show()
#         if stop_event.is_set():
#             plt.close()
#             break

def plot_spectrogram(audio_buffer, spectrogram_func, stop_event):
    # Initialize the stop_event flag
    stopped = [False]

    def handle_close(evt):
        stopped[0] = True

    while not stop_event.is_set():
        # Set up the initial plot
        fig, ax = plt.subplots()
        spec = spectrogram_func(audio_buffer)
        im = ax.imshow(
            spec,
            aspect="auto",
            origin="lower",
            cmap="viridis",
            vmin=0.0,
            vmax=1.0,
        )
        ax.set_xlabel("Time")
        ax.set_ylabel("Frequency")
        plt.colorbar(im, ax=ax)
        ax.set_title("Spectrogram")

        # Add a text element to display the update frequency
        freq_text = ax.text(
            0.01, 0.95, "", transform=ax.transAxes, fontsize=10, color="white"
        )

        # Update function for the plot
        def update(frame):
            nonlocal audio_buffer
            start_time = time.time()
            spec = spectrogram_func(audio_buffer)
            im.set_data(spec)
            im.set_clim(vmin=0.0, vmax=1.0)
            # Calculate and display the update frequency
            end_time = time.time()
            update_freq = 1 / (end_time - start_time)
            freq_text.set_text(f"{update_freq:.2f} fps")

            if stopped[0]:
                return []
            return [im, freq_text]

        # Create the animation
        ani = FuncAnimation(fig, update, blit=True, interval=RATE / FRAMES_PER_BUFFER)

        # Connect the event handler
        fig.canvas.mpl_connect("close_event", handle_close)

        # Show the plot
        plt.show(block=False)

        while not stop_event.is_set() and not stopped[0]:
            fig.canvas.flush_events()
            time.sleep(0.1)

        if stop_event.is_set() or stopped[0]:
            plt.close()
            break

def record_and_detect_keyword():
    """Continuously record audio and predict the command."""
    global stop_plotting_thread
    audio_buffer = np.zeros(int(TAILING_DURATION * RATE), dtype=np.int16)
    p = pyaudio.PyAudio()
    stream = p.open(
        format=FORMAT,
        channels=CHANNELS,
        rate=RATE,
        input=True,
        frames_per_buffer=FRAMES_PER_BUFFER,
    )
    stop_event = threading.Event()
    try:
        plot_thread = threading.Thread(
            target=plot_spectrogram,
            args=(
                audio_buffer,
                lambda buf: preprocess_audiobuffer(buf).numpy().squeeze(),
                stop_event,
            ),
            daemon=True,
        )
        plot_thread.start()
        is_awake = False
        recognizer = sr.Recognizer()
        while True and not is_awake:
            data = stream.read(FRAMES_PER_BUFFER)
            new_audio = np.frombuffer(data, dtype=np.int16)

            # Update the audio buffer
            audio_buffer[:-FRAMES_PER_BUFFER] = audio_buffer[FRAMES_PER_BUFFER:]
            audio_buffer[-FRAMES_PER_BUFFER:] = new_audio

            # Save the audio buffer to a WAV file
            # output_file = save_audio_to_wav(
            #     audio_buffer, output_folder="recorded_audio"
            # )

            # Predict using the tailing audio data
            if not is_awake:
                result = predict_mic(audio_buffer)

                if result == 0:
                    print(f"Obama model detected {KEYWORD}")
                    # is_awake = True
                    audio_data = sr.AudioData(
                        audio_buffer.tobytes(), sample_rate=RATE, sample_width=2
                    )
                    try:
                        text = recognizer.recognize_google(audio_data, language="zh-CN")
                        print("You said: ", text)
                        if KEYWORD in text:
                            is_awake = True
                    except sr.UnknownValueError:
                        print("Google Speech Recognition could not understand audio")
                    except sr.RequestError as e:
                        print(
                            "Could not request results from Google Speech Recognition service; {0}".format(
                                e
                            )
                        )

            if is_awake:
                p.terminate()
                stop_event.set()

    except Exception as e:
        print(e)
        p.terminate()
        stop_event.set()

def three_char_classic_reply():
    previous_sr_text = ""
    audio_buffer = np.zeros(int(5 * RATE), dtype=np.int16)
    p = pyaudio.PyAudio()
    stream = p.open(
        format=FORMAT,
        channels=CHANNELS,
        rate=RATE,
        input=True,
        frames_per_buffer=FRAMES_PER_BUFFER,
    )
    recognizer = sr.Recognizer()
    buffers_per_second = int(RATE / FRAMES_PER_BUFFER) * 2
    idel_start_time = time.time()
    while True:
        audio_data = np.empty((buffers_per_second, FRAMES_PER_BUFFER), dtype=np.int16)
        for i in range(buffers_per_second):
            audio_data[i] = np.frombuffer(
                stream.read(FRAMES_PER_BUFFER), dtype=np.int16
            )
        audio_data = audio_data.flatten()
        audio_buffer[: -audio_data.shape[0]] = audio_buffer[audio_data.shape[0] :]
        audio_buffer[-audio_data.shape[0] :] = audio_data
        audio_data = sr.AudioData(
            audio_buffer.tobytes(), sample_rate=RATE, sample_width=2
        )
        try:
            text = recognizer.recognize_google(audio_data, language="zh-CN")
            print("You said: ", text)
            if len(text) >= 3 and text != previous_sr_text:
                previous_sr_text = text
                reply = three_char_classic_model.predict_next_3(text[0:3])
                text_to_speech(reply, "zh")
                print(f"Model reply: {reply}")
            idel_start_time = time.time()
        except sr.UnknownValueError:
            print("Google Speech Recognition could not understand audio")
        except sr.RequestError as e:
            print(
                "Could not request results from Google Speech Recognition service; {0}".format(
                    e
                )
            )
        if (time.time() - idel_start_time) > 10:
            text_to_speech("晚安寶貝兒", "zh")
            return

if __name__ == "__main__":
    text_to_speech("開始了", "zh")
    while True:
        print("start...")
        record_and_detect_keyword()
        print("awake...")
        print("Your three char classic?..")
        text_to_speech("你好呀。 請讀出你的三字經典三連音。", "zh")
        three_char_classic_reply()


from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import IsAuthenticated
from rest_framework.request import Request
from rest_framework.response import Response
from django.shortcuts import get_object_or_404

from api.utils import paginate
from message.models import Message
from message.serializer import MessageSerializer, MessageUserSerializer
from people.models import Friend
from user.models import User
from django.db.models import Q
from django.utils import timezone

@api_view(["POST"])
@permission_classes([IsAuthenticated])
def send_message(request:Request, pk):
    receiver=get_object_or_404(User, pk=pk)
    user = request.user
    message = request.data.get("message")

    if not message:
        return Response("Provide message")

    message = Message.objects.create(
        sender=user,
        receiver=receiver,
        content=message
    )

    return Response(MessageSerializer(message).data)

@api_view(["GET"])
@permission_classes([IsAuthenticated])
def get_message(request, pk):
    user = get_object_or_404(User, pk=pk)
    messages=Message.objects.filter(Q(
        Q(sender=user, receiver=request.user)|
        Q(sender=request.user, receiver=user))).order_by("-dateSend")

    paginated = paginate(messages, request, MessageSerializer)

    return Response(paginated)

@api_view(["GET"])
@permission_classes([IsAuthenticated])
def get_user_last_message(request:Request):
    user = request.user
    friends = Friend.objects.filter(user1=user)

    last_message=[]

    for friend in friends:
        message = Message.objects.filter(Q(
            Q(sender=user, receiver=friend.user2)|
            Q(sender=friend.user2, receiver=user)
        )).order_by("-dateSend").first()

        if not message:
            last_message.append({
                "friend":friend.user2,
                "content":"You can send message to your friend",
                "dateSend":timezone.now(),
                "lastSenderMe":False
            })

        else:
            last_message.append({
                "friend":friend.user2,
                "content":message.content,
                "dateSend":message.dateSend,
                "lastSenderMe":message.sender.id==user.id
            })

    paginated = paginate(last_message, request, MessageUserSerializer)

    return Response(paginated)


##############################################################################################
# File: diceSim.py
# Author: Sam Wareing
# Description: script to determine probability of dice rolls using monte carlo simulation
#
#
#
##############################################################################################
import sys
from random import randint
from collections import Counter

def simulateDiceRolls(dice, num_simulations):
	counts = Counter()
	for roll in range(num_simulations):
		counts[sum((randint(1, sides) for sides in dice))] += 1

	print("\nOUTCOME\tPROBABILITY")
	for outcome in range(len(dice), sum(dice)+1):
		print('{}\t{:0.2f}%'.format(outcome, counts[outcome]*100/num_simulations))

def usage():
    print("diceSim.py # # #....")

if __name__ == "__main__":
	print("let's sim some dice")

	if len(sys.argv) < 2:
		usage()
		exit()

	num_simulations = input("How many simulations? press enter for default 1000000 ")

	if num_simulations == "":
		num_simulations = 1000000
	else:
		num_simulations = int(num_simulations)

	n = len(sys.argv)
	dice = [int(sys.argv[i]) for i in range(1, n)]

	simulateDiceRolls(dice, num_simulations)


from selenium import webdriver
from selenium.webdriver.common.by import By
from webdriver_manager.firefox import GeckoDriverManager

browser = webdriver.Firefox(executable_path=GeckoDriverManager().install())

codigos = ['22316', '21897', '22469', '22192', '22567', '22153', '21778', '22281', '22941', '22882', '21603', '22740', '21587', '23009', '22500', '22424',
           '23167', '22423', '22816', '23103', '22592', '23317', '23067', '22804']
url = 'http://redmine.rs.dbseller.com.br/issues/'
file = open('redmines.txt', 'w')

titulos = []
descricoes = []
descr = []
for codigo in codigos:
    browser.get(url+codigo)
    file.write(browser.title)
    file.write("\n\n")
    descricao = browser.find_elements(By.CLASS_NAME, "wiki")
    resultado = descricao[1].find_elements(By.TAG_NAME, "p")
    for x in resultado:
        linha = x.get_attribute('innerHTML')
        linha = linha.replace('<br>','')
        file.write(linha+"\n")
    file.write("\n\n")
    file.write("\n\n")

browser.quit()


import os
from collections import OrderedDict

import tensorflow as tf

class KBest(tf.keras.callbacks.Callback):
    """
    A subclass of the callback preset class which implements the functionality to keep only the best k checkpoints of
    the execution (instead of the best one implemented in Tf).

    Attributes
    ----------
    output_path:    str
        Path where the checkpoints are saved
    file_loss: dict
        Dictionary where we keep the loss of each of the checkpoints saved
    k: int
        Number of checkpoints to keep

    Methods:
    ----------
    on_epoch_end(self, src_input, indices)
       At the end of each epoch, we check which of the checkpoints we need to delete (if any)
    """

    def __init__(self, output_path, k=None):
        """
        Parameters
        ----------
        output_path:    str
            Path where the checkpoints are saved
        k: int
            Number of checkpoints to keep
        """
        super().__init__()
        self.output_path = output_path
        self.files_loss = {}
        self.k = k

    def on_epoch_end(self, epoch, logs=None):
        """
        Parameters
        ----------
        epoch:    int
            Epoch number
        logs:    dict
            Dictionary with the information of the current epoch
        """

        if logs is None:
            logs = {}
        if self.k is not None:
            loss = logs["loss"]
            name = "weights." + str("{:02d}".format(self.epoch)) + '-' + str("{:.2f}".format(loss)) + '.hdf5'
            self.files_loss[name] = loss

            if len(self.files_loss) >= self.k:
                # sort by value in decreasing order
                d_descending = OrderedDict(sorted(self.files_loss.items(), key=lambda kv: kv[1], reverse=True))
                n = len(d_descending)

                # delete the len(d_descending - k) first files
                num_deletions = n - self.k
                file_delete = list(d_descending.items())[0:num_deletions]
                for name, _ in file_delete:
                    path = self.output_path + '/ckpt/' + name
                    os.remove(path)
                    del self.files_loss[name]