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 -*-
#
# 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)


"""
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)


#!/usr/bin/env python3
# -*- coding: UTF-8 -*-

"""key.py: Handles the keysubmissions for groups"""

import json
import os
import sqlite3
import sys
import string

import auth
from httperror import HTTPError

RETURN_HEADERS = []

def __do_get():
    RETURN_HEADERS.append('Status: 403')
    return "This script is NOT get-able"

def __do_post():
    postdata = sys.stdin.read()
    try:
        postdata = json.loads(postdata)
    except json.JSONDecodeError:
        RETURN_HEADERS.append('Status: 400')
        return "Malformed Request. Data not JSON-decodable"

    if 'action' in postdata and postdata['action'] == 'submitkey':
        return __submitkey(postdata)

    if 'action' in postdata and postdata['action'] == 'groupstatus':
        return __groupstatus(postdata)

    RETURN_HEADERS.append('Status: 500')
    return "Not implemented"

def __submitkey(postdata):
    if not 'authtoken' in postdata or not 'key' in postdata:
        raise HTTPError("Missing Required Attributes")

    return submitkey(postdata['authtoken'], postdata['key'])

def cleanstring(dirtystring):
    cleanstring = dirtystring.lower().strip()
    printable = set(string.printable)
    cleanstring = ''.join(filter(lambda x: x in printable, cleanstring))
    return cleanstring

def submitkey(authtoken, key):
    """Verifies a key, and submits it. Returns the groups status"""
    group = auth.verify_token(authtoken)
    if group is None:
        raise HTTPError("Invalid Authtoken, please relogin", 401)

    group_status = json.loads(groupstate(authtoken))
    if int(group_status['remain_guess']) < 1:
        raise HTTPError(groupstate(authtoken), 403)

    key = cleanstring(key)

    database = sqlite3.connect('database.sqlite3')
    submitted = database.execute(('SELECT count() FROM claims'
                                  ' WHERE groupname=:groupname AND key=:key'),
                                 {"groupname": group, "key": key}).fetchone()[0]

    if submitted != 0:
        raise HTTPError(groupstate(authtoken), 410)

    badkey = database.execute(('SELECT count() FROM badkeys'
                               ' WHERE groupname=:groupname AND key=:key'),
                              {"groupname": group, "key": key}).fetchone()[0]

    if badkey != 0:
        raise HTTPError(groupstate(authtoken), 410)

    keyexist = database.execute('SELECT count() FROM keys WHERE LOWER(key)=:key',
                                {'key': key}).fetchone()[0]
    if keyexist == 0:
        database.execute('INSERT INTO badkeys(groupname, key) values(:groupname, :key)',
                         {'groupname': group, 'key': key})
        database.commit()
        raise HTTPError(groupstate(authtoken), 400)

    database.execute('INSERT INTO claims(groupname, key) values(:groupname, :key)',
                     {'groupname': group, 'key': key})
    database.commit()

    return groupstate(authtoken)

def __groupstatus(request):
    if not 'authtoken' in request:
        raise HTTPError("Missing Authtoken")

    status = groupstate(request['authtoken'])
    if status is None:
        raise HTTPError("Authtoken is not valid. Please relogin")

    return status

def groupstate(authtoken):
    """Calculates the groups state, and returns it as a json-string"""
    group = auth.verify_token(authtoken)
    if group is None:
        return None

    database = sqlite3.connect('database.sqlite3')
    status = database.execute(('SELECT count(),'
                               ' strftime("%s", datetime(min(submittime), "+10 minute"))'
                               ' FROM badkeys WHERE'
                               ' groupname=:groupname AND '
                               ' submittime > datetime("now", "-10 minute")'),
                              {"groupname": group}).fetchone()

    returnvalue = {
    "group": group,
    "points": get_all_points(),
        "remain_guess": 3 - status[0],
        "time_to_new_guess": int(status[1]) if (type(status[1]) == str) else None
    }

    return json.dumps(returnvalue)

def get_all_points():
    """Retrieves a calculated list of all groups points"""
    database = sqlite3.connect('database.sqlite3')
    allclaims = database.execute(('select cl.groupname, cl.catchtime, ke.key,'
                                  ' ke.first, ke.second, ke.third, ke.other'
                                  ' from claims as cl inner join keys as ke'
                                  ' on (ke.key == cl.key collate nocase)'
                                  ' order by ke.key asc, cl.catchtime asc;'))
    allrows = allclaims.fetchall()

    groups = {}
    key = None
    num_in_key = 0
    for row in allrows:
        _key = row[2]
        _group = row[0]
        _point1 = row[3]
        _point2 = row[4]
        _point3 = row[5]
        _point = row[6]

        if _key != key:
            num_in_key = 0
            key = _key

        if not _group in groups:
            groups[_group] = 0

        num_in_key = num_in_key + 1
        if num_in_key == 1:
            groups[_group] = groups[_group] + _point1
        elif num_in_key == 2:
            groups[_group] = groups[_group] + _point2
        elif num_in_key == 3:
            groups[_group] = groups[_group] + _point3
        else:
            groups[_group] = groups[_group] + _point

    returnvalue = []
    for group in groups.keys():
        returnvalue.append({"name": group, "score": groups[group]})

    return returnvalue

def __main():
    if not 'REQUEST_METHOD' in os.environ:
        raise HTTPError("Missing REQUEST_METHOD")

    if os.environ['REQUEST_METHOD'] == 'GET':
        return __do_get()

    if os.environ['REQUEST_METHOD'] == 'POST':
        return __do_post()

    raise HTTPError("Undhandled REQUEST_METHOD")

if __name__ == '__main__':
    try:
        RESPONSE = __main()
    except HTTPError as err:
        if err.status:
            RETURN_HEADERS.append('Status: %d' % err.status)
        else:
            RETURN_HEADERS.append('Status: 400')
        RESPONSE = err.message

    NUM_HEADERS = len(RETURN_HEADERS)
    if NUM_HEADERS == 0:
        print('Status: 200')
    else:
        for header in RETURN_HEADERS:
            print(header)
    print('Content-Length: %d' % len(RESPONSE))
    print()
    print(RESPONSE)


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


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))


from typing import Any, Dict
import os
import sys

from forte.data.caster import MultiPackBoxer
from forte.data.data_pack import DataPack
from forte.data.multi_pack import MultiPack
from forte.data.readers import OntonotesReader, DirPackReader
from forte.data.readers.deserialize_reader import MultiPackDirectoryReader
from forte.pipeline import Pipeline
from forte.processors.base import MultiPackProcessor, MultiPackWriter
from forte.processors.writers import PackNameJsonPackWriter
from fortex.nltk import NLTKWordTokenizer, NLTKPOSTagger, NLTKSentenceSegmenter
from ft.onto.base_ontology import EntityMention, CrossDocEntityRelation

class PackCopier(MultiPackProcessor):
    """
    Copy the text from existing pack to a new pack.
    """

    def _process(self, input_pack: MultiPack):
        from_pack: DataPack = input_pack.get_pack(self.configs.copy_from)
        copy_pack: DataPack = input_pack.add_pack(self.configs.copy_to)

        copy_pack.set_text(from_pack.text)

        if from_pack.pack_name is not None:
            copy_pack.pack_name = from_pack.pack_name + "_copy"
        else:
            copy_pack.pack_name = "copy"

        ent: EntityMention
        for ent in from_pack.get(EntityMention):
            EntityMention(copy_pack, ent.begin, ent.end)

    @classmethod
    def default_configs(cls) -> Dict[str, Any]:
        return {"copy_from": "default", "copy_to": "duplicate"}

class ExampleCoreferencer(MultiPackProcessor):
    """
    Mark some example coreference relations.
    """

    def _process(self, input_pack: MultiPack):
        pack_i = input_pack.get_pack("default")
        pack_j = input_pack.get_pack("duplicate")

        for ent_i, ent_j in zip(
            pack_i.get(EntityMention), pack_j.get(EntityMention)
        ):
            link = CrossDocEntityRelation(input_pack, ent_i, ent_j)
            link.rel_type = "coreference"
            input_pack.add_entry(link)

class ExampleCorefCounter(MultiPackProcessor):
    def __init__(self):
        super().__init__()
        self.coref_count = 0

    def _process(self, input_pack: MultiPack):
        rels = list(input_pack.get_entries_of(CrossDocEntityRelation))
        self.coref_count += len(rels)

    def finish(self, _):
        print(f"Found {self.coref_count} pairs in the multi packs.")

def pack_example(input_path, output_path):
    """
    This example read data from input path and serialize to output path.
    Args:
        input_path:
        output_path:

    Returns:

    """
    print("Pack serialization example.")
    nlp = Pipeline[DataPack]()

    nlp.set_reader(OntonotesReader())
    nlp.add(NLTKSentenceSegmenter())
    nlp.add(NLTKWordTokenizer())
    nlp.add(NLTKPOSTagger())

    # This is a simple writer that serialize the result to the current
    # directory and will use the DocID field in the data pack as the file name.
    nlp.add(
        PackNameJsonPackWriter(),
        {
            "output_dir": output_path,
            "indent": 2,
            "overwrite": True,
        },
    )

    nlp.run(input_path)

def multi_example(input_path, output_path):
    """
    This example reads data from input path, and write multi pack output
    to output path.

    Args:
        input_path:
        output_path:

    Returns:

    """
    print("Multi Pack serialization example.")

    print(
        "We first read the data, and add multi-packs to them, and then "
        "save the results."
    )
    coref_pl = Pipeline()
    coref_pl.set_reader(DirPackReader())
    coref_pl.add(MultiPackBoxer())
    coref_pl.add(PackCopier())
    coref_pl.add(ExampleCoreferencer())
    coref_pl.add(ExampleCorefCounter())

    coref_pl.add(
        MultiPackWriter(),
        config={
            "output_dir": output_path,
            "indent": 2,
            "overwrite": True,
        },
    )

    coref_pl.run(input_path)

    print(
        "We can then load the saved results, and see if everything is OK. "
        "We should see the same number of multi packs there. "
    )
    reading_pl = Pipeline()
    reading_pl.set_reader(
        MultiPackDirectoryReader(),
        config={
            "multi_pack_dir": os.path.join(output_path, "multi"),
            "data_pack_dir": os.path.join(output_path, "packs"),
        },
    )
    reading_pl.add(ExampleCorefCounter())
    reading_pl.run()

def main(data_path: str):
    pack_output = "pack_out"
    multipack_output = "multi_out"

    pack_example(data_path, pack_output)
    multi_example(pack_output, multipack_output)

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


budget = float(input())
number_nights = int(input())
price_one_night = float(input())
percent_more_expenses = int(input())/100

if number_nights > 7:
    price_one_night *= 0.95
total = (number_nights * price_one_night) + (percent_more_expenses * budget)

left_needed_money = abs(budget - total)

if budget >= total:
    print(f"Ivanovi will be left with {left_needed_money:.2f} leva after vacation.")
else:
    print(f"{left_needed_money:.2f} leva needed.")


import numpy as np
from PIL import Image
img=Image.open("tiger.jpg")
img=np.array(img)

def rgb2gray(rgb):
    return np.dot(rgb, [0.299, 0.587, 0.114])

img=rgb2gray(img)
row=img.shape[0]
col=img.shape[1]
print(row)
print(col)
# img.resize(1200,1920);
# row=img.shape[0]
# col=img.shape[1]
# print(row)
# print(col)
Image.fromarray(img).show()

filtered_image=[]
new_row=row/3
new_col=col/3
filter=[[1,1,1],
        [1,1,1],
        [1,1,1]]
for i in range(0,row,3):
	lis=[]
	for j in range(0,col,3):
		val=0
		for k in range(3):
			for l in range(3):
				val+=img[i+k][j+l]
		lis.append(val/9)
	filtered_image.append(lis)
filtered_image=np.array(filtered_image)
print(filtered_image)
print(filtered_image.shape[0])
print(filtered_image.shape[1])

Image.fromarray(filtered_image).show()


#!/usr/bin/env python

bundle = ['sqlite3', 'ssl', 'crypto', 'ffi', 'expat', 'tcl8', 'tk8', 'gdbm',
          'lzma', 'tinfo', 'tinfow', 'ncursesw', 'panelw', 'ncurses', 'panel',
          'panelw']

import os
from os.path import dirname, relpath, join, exists, basename, realpath
from shutil import copy, copytree
import sys
from glob import glob
from subprocess import check_output, check_call

def get_deps_darwin(binary):
    deps = {}
    output = check_output(['otool', '-L', binary])
    output = output.splitlines()
    output = output[1:]  # first line is binary name
    for line in output:
        path = line.strip().split()[0]
        if (not path or
                not path.startswith('/usr/local/') or
                basename(path) == basename(binary)):
            continue

        needed = basename(path)

        deps[needed] = path
        deps.update(get_deps(path))

    return deps

def get_deps(binary):
    if sys.platform == 'darwin':
        return get_deps_darwin(binary)

    deps = {}
    output = check_output(['ldd', binary])
    for line in output.splitlines():
        if '=>' not in line:
            continue
        line = line.strip()
        needed, path = line.split(' => ')
        if path == 'not found':
            raise ValueError('Broken dependency in ' + binary)
        path = path.split(' ')[0]
        if not path:
            continue

        if needed[3:].split('.', 1)[0] not in bundle:
            continue

        deps[needed] = path
        deps.update(get_deps(path))

    return deps

def gather_deps(binaries):
    deps = {}
    for binary in binaries:
        deps.update(get_deps(binary))

    return deps

def copy_deps(deps):
    copied = {}

    for needed, path in deps.items():
        bname = basename(path)

        copy(realpath(path), 'lib/' + bname)
        copied[path] = 'lib/' + bname

        if not exists('lib/' + needed):
            os.symlink(bname, 'lib/' + needed)

    return copied

def rpath_binaries(binaries):
    rpaths = {}

    for binary in binaries:
        check_call(['chmod', 'a+w', binary])
        if sys.platform == 'darwin':
            rpath = join('@executable_path', relpath('lib', dirname(binary)))
            check_call(['install_name_tool', '-add_rpath', rpath, binary])

            # change path for deps, this deps call is sorta redundant, but we
            # don't have this dependency info in the passed in data...
            deps = get_deps(binary)
            for dep, path in deps.items():
                rpath = join('@rpath', dep)
                if rpath != path:
                    print('Set RPATH of {0} for {1} to {2}'.format(binary, path, rpath))
                    check_call(['install_name_tool', '-change', path, rpath, binary])

        else:
            rpath = join('$ORIGIN', relpath('lib', dirname(binary)))
            check_call(['patchelf', '--set-rpath', rpath, binary])

        rpaths[binary] = rpath

    return rpaths

def make_portable():
    exts = ['so']
    if sys.platform == 'darwin':
        exts = ['dylib', 'so']

    binaries = glob('bin/libpypy*.' + exts[0])
    if not binaries:
        raise ValueError('Could not find bin/libpypy*.%s in "%s"' % (exts[0], os.getcwd()))
    for ext in exts:
        binaries.extend(glob('lib_pypy/*_cffi.pypy*.' + ext))
        binaries.extend(glob('lib_pypy/_pypy_openssl*.' + ext))
        binaries.extend(glob('lib_pypy/_tkinter/*_cffi.pypy*.' + ext))

    deps = gather_deps(binaries)

    copied = copy_deps(deps)

    for path, item in copied.items():
        print('Copied {0} to {1}'.format(path, item))

    binaries.extend(copied.values())

    rpaths = rpath_binaries(binaries)
    for binary, rpath in rpaths.items():
        print('Set RPATH of {0} to {1}'.format(binary, rpath))

    # copy tcl/tk shared files, search /usr and copy the containing dir...
    found_tk = found_tcl = False
    for path, dirs, files in os.walk('/usr'):
        if not found_tk and 'tk.tcl' in files:
            print('Found tk shared files at: %s' % (path))
            found_tk = True
            copytree(path, 'lib/tk')
        if not found_tcl and 'init.tcl' in files:
            print('Found tcl shared files at: %s' % (path))
            found_tcl = True
            copytree(path, 'lib/tcl')

    return deps

if __name__ == '__main__':
    try:
        os.chdir(sys.argv[1])
    except:
        print('Call as %s <path/to/pypy/topdir' % sys.argv[0])
        exit(-1)

    try:
        os.mkdir('lib')
    except OSError:
        pass

    make_portable()


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)


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 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)


class Node:
    def __init__(self, ip, type=None, target=False):
        self.ip = ip
        self.hostname = ip
        #node is default, we expect to work with 'endnode', 'router', ...
        self.type = type
        self.target = target
        self.plugins = {}

    def addPluginResults(self, name,lines):
        self.plugins[name] = lines

class EndNode:
    def __init__(self, localIp, targetIp, nodeId, ttl_recv):
        self.targetIp = targetIp
        self.endnodeId = nodeId
        self.status = 0
        self.times_processed = 0
        #self.hops = {}
        self.routes = {}
        self.addHop(0,localIp,localIp)
        self.distance = self.detDistance(ttl_recv)

    def addHop(self,hop,ip,localIp):
        route = 0
        if hop  > 255:
            route,hop = divmod(hop,256)
        if not self.routes.has_key(route):
                self.routes[route] = {}
                if localIp:
                    self.routes[route][0] = localIp
        self.routes[route][hop] = ip

    def detDistance(self,ttl_recv):
        if ttl_recv > 128:
            return 255 - ttl_recv
        elif ttl_recv <= 64:
            return 64 - ttl_recv
        else:
            return 128 - ttl_recv

def cleanRoute(route):
    from sendPacket import isValidIp

    #set cursor to last item
    last = route.keys().__reversed__().next()
    at_end = True
    cursors = range(1,last+1)
    cursors.reverse()

    for cursor in cursors:
        if not route.has_key(cursor -1):
            #route[cursor-1] = "unknown_%s.%d"%(nodeId,cursor-1)
            #we replace this line to link a unknown step to the following step.
            if isValidIp( route[cursor] ):
                route[cursor-1] = "unknown_%s.%d"%(route[cursor],cursor-1)
                at_end = False
            else:
                route[cursor-1] = route[cursor]
                #route.pop(cursor)
                at_end = False
        elif (route[cursor] == route[cursor-1] and at_end):
            #we have 2 times same ip in route at the end delete last
            route.pop(cursor)
        else:
            #We have an existing hop before this one and it is not similar to next hop
            at_end = False
    return(route)

def uniq(alist):    # Fastest without order preserving
    set = {}
    map(set.__setitem__, alist, [])
    return set.keys()


pkgname = "libqmi"
pkgver = "1.34.0"
pkgrel = 0
build_style = "meson"
configure_args = [
    "-Dqrtr=true",
    "-Dintrospection=true",
]
hostmakedepends = [
    "bash-completion",
    "glib-devel",
    "gobject-introspection",
    "help2man",
    "libgudev-devel",
    "libmbim-devel",
    "libqrtr-glib-devel",
    "meson",
    "pkgconf",
]
makedepends = ["glib-devel", "libgudev-devel", "linux-headers"]
pkgdesc = "QMI modem protocol helper library"
maintainer = "q66 <q66@chimera-linux.org>"
license = "GPL-2.0-or-later AND LGPL-2.1-or-later"
url = "https://www.freedesktop.org/wiki/Software/libqmi"
source = f"https://gitlab.freedesktop.org/mobile-broadband/libqmi/-/archive/{pkgver}/libqmi-{pkgver}.tar.gz"
sha256 = "8690d25b4d110b6df28b31da0a8bf16c7e966d31abcfeeb854f2753451e7a400"

@subpackage("libqmi-devel")
def _devel(self):
    return self.default_devel()


# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models, migrations

class Migration(migrations.Migration):

    dependencies = [
        ('community', '0001_initial'),
    ]

    operations = [
        migrations.AlterModelOptions(
            name='usergiallorosso',
            options={'verbose_name': 'Usuario Giallorosso', 'verbose_name_plural': 'Usuarios Giallorossos'},
        ),
    ]


date = "Monday 2019-03-18"

time = "10:05:34 AM"

average_astronaut_mass_kg = 80.7

fuel_mass_kg = 760000

ship_mass_kg = 74842.31

fuel_level = "100%"

num_astronauts_in_crew = int(input("Enter number of astronauts in crew: "))

crew_status = input("Enter crew status, Ready or Not Ready: ")

total_mass_of_crew = num_astronauts_in_crew * average_astronaut_mass_kg

total_mass_of_ship = total_mass_of_crew + ship_mass_kg + fuel_mass_kg

dashes = "-------------------"

print(f"> LAUNCH CHECKLIST\n{dashes}\nDate: {date}\nTime: {time}\n\n{dashes}\n> SHIP INFO\n{dashes}")

print(f"* Crew: {num_astronauts_in_crew}\n* Crew Status: {crew_status}\n* Fuel Level: {fuel_level}\n\n")

print(f"{dashes}\n> MASS DATA\n{dashes}\n* Crew: {total_mass_of_crew} kg\n* Fuel: {fuel_mass_kg} kg")
print(f"* Spaceship: {ship_mass_kg} kg\n* Total Mass: {total_mass_of_ship} kg")


class Solution:
    def average(self,A,B,start,end):
        sum = 0
        for i in range(start, end):
            sum += A[i]
        return sum/B

    def solve1(self, A, B):
        least_avg = 999999999
        min_idx = 0
        for i in range(len(A)-B+1):
            j = i+B
            temp = self.average(A,B,i,j)
            if least_avg > temp:
                least_avg = temp
                min_idx = i
        return min_idx

    def solve(self, A, B):
        least_sum = sum(A[:B])
        axu = []
        axu.append((least_sum, 0, B-1))
        for i in range(B, len(A)):
            least_sum = least_sum+A[i]-A[i-B]
            print(least_sum, end = " ")
            axu.append((least_sum,i-B+1, i))

        avg = axu[0][0]/B
        idx = axu[0][1]
        for i in range(1, len(axu)):
            if axu[i][0]/B < avg:
                avg = axu[i][0]/B
                idx = axu[i][1]
        return idx,avg

    def solve1(self, A, B):
        next_sum = sum(A[:B])
        idx = 0
        min_avg = next_sum/B
        for i in range(B, len(A)):
            next_sum = next_sum + A[i] - A[i-B]
            print(next_sum, end=" ")
            if min_avg > next_sum/B:
                min_avg = next_sum/B
                idx = i-B+1

        return idx, min_avg

A = [ 18, 11, 16, 19, 11, 9, 8, 15, 3, 10, 9, 20, 1, 19 ]
B = 1

A1=[3, 7, 90, 20, 10, 50, 40]
B1=3

A2=[3, 7, 5, 20, -10, 0, 12]
B2=2

A3 =[ 15, 7, 11, 7, 9, 8, 18, 1, 16, 18, 6, 1, 1, 4, 18 ]
B3 = 6

print(Solution().solve(A3, B3))
print(Solution().solve1(A3, B3))

01. Arrays/Subarray with least average.py