#!/usr/bin/env python3

# reproducible results
import numpy as np
import random as rn
import tensorflow as tf
np.random.seed(1337)
rn.seed(1337)
tf.set_random_seed(1337)
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'
os.environ['PYTHONHASHSEED'] = '0'
from keras import backend as bke
s = tf.Session(graph=tf.get_default_graph())
bke.set_session(s)

# the rest of imports
import sys, random, gc, keras
sys.path.append('../Lib/')
sys.dont_write_bytecode = True
from sklearn.metrics import f1_score
from keras.callbacks import EarlyStopping
from sklearn.model_selection import train_test_split

# ignore sklearn warnings
def warn(*args, **kwargs):
  pass
import warnings
warnings.warn = warn

def sample(params):
  """Sample a configuration from param space"""

  config = {}

  for param, value in params.items():
    if hasattr(value, 'rvs'):
      # this is a scipy.stats distribution
      config[param] = value.rvs()
    else:
      # this is a tuple
      config[param] = random.choice(value)

  return config

def run(
  make_model,  # function that returns a keras model
  fixed_args,  # make_model and other fixed arguments
  param_space, # possible hyperparameter values
  x_train,     # training examples
  y_train,     # training labels
  x_val=None,  # validation examples
  y_val=None,  # validation labels
  n=100,       # number of iterations
  verbose=0):  # suppress output
  """Random search"""

  # need a validation set?
  if x_val == None:
    x_train, x_val, y_train, y_val = \
      train_test_split(x_train, y_train, test_size=0.2)

  # configurations and their scores
  config2score = {}

  for i in range(n):

    # prevent OOM errors
    gc.collect()
    bke.clear_session()

    config = sample(param_space)
    args = config.copy()
    args.update(fixed_args)

    model = make_model(args)

    erstop = EarlyStopping(
      monitor='val_loss',
      min_delta=0,
      patience=2,
      restore_best_weights=True)

    optim = getattr(keras.optimizers, args['optimizer'])
    model.compile(
      loss=args['loss'],
      optimizer=optim(lr=10**args['log10lr']),
      metrics=['accuracy'])

    model.fit(
      x_train,
      y_train,
      validation_data=(x_val, y_val),
      epochs=args['epochs'],
      batch_size=args['batch'],
      verbose=0,
      callbacks=[erstop])

    # add effective number of epochs to config
    if erstop.stopped_epoch > 0:
      config['epochs'] = erstop.stopped_epoch - 1
    else:
      config['epochs'] = 0

    # probability for each class; (test size, num of classes)
    distribution = model.predict(x_val)

    # turn into an indicator matrix
    distribution[distribution < 0.5] = 0
    distribution[distribution >= 0.5] = 1

    f1 = f1_score(y_val, distribution, average='macro')
    config2score[tuple(config.items())] = f1

    if verbose == 1:
      print('[%d] %s' % (i + 1, config))
      print('[%d] score: %.3f' % (i + 1, f1))

  return config2score

if __name__ == "__main__":

  pass


from app.Operation import Operation, OperationMenu

class TensorOperation(Operation):
    def __init__(self, operand0, operand1, operator):
        super().__init__(operand0, operand1, operator)

class TensorOperationMenu(OperationMenu):
    def __init__(self):
        pass

    def getOperations(self):

        import torch

        operations = {
            'Addition': torch.add,
            'Subtraction': torch.sub,
            'Multiplication': torch.mul,
            'Division': torch.div,
            'True Division': torch.true_divide,
            'Floor Division': torch.floor_divide,
            'Remainder': torch.remainder,
            'Modulo': torch.fmod,
            'Power': torch.pow,
            'Less Than': torch.lt,
            'Less Than or Equal To': torch.le,
            'Greater Than': torch.gt,
            'Greater Than or Equal To': torch.ge,
            'Equal': torch.eq,
            'Not Equal': torch.ne,
            'Maximum': torch.max,
            'Minimum': torch.min,
            'Element-wise Maximum': torch.maximum,
            'Element-wise Minimum': torch.minimum,
            'Copysign': torch.copysign,
            'Arc Tangent 2': torch.atan2,
            'Euclidean Distance': torch.dist,
            'Inner Product': torch.inner,
            'Kronecker Product': torch.kron,
        }

        return operations


from keras import callbacks
import os
import numpy as np

class MyEarlyStop(callbacks.Callback):
    def __init__(self, model, path):
        self.model = model
        self.path = path
        self.best_mae = float("inf")
        self.best_area = float("inf")
        self.best_ery = float("inf")
        self.best_sca = float("inf")
        self.best_ind = float("inf")
        self.best_pasi = float("inf")

    def on_epoch_end(self, epoch, logs=None):
        print(logs)
        scoreA = logs.get('val_scoreA_score_metric')
        scoreB = logs.get("val_scoreB_score_metric")

        mae = (scoreA + scoreB) / 2.0

        global EPOCH
        EPOCH = epoch

        if mae < self.best_mae:
            print("\nValidation mae decreased from {} to {}, saving model".format(self.best_mae, mae))
            print("\nsave model to " + os.path.join(self.path, "epoch=" + str(epoch) + "_" + "mae=" + str(round(mae, 4)) + '.h5'))
            filelist = os.listdir(self.path)
            h5list = [elem for elem in filelist if os.path.splitext(elem)[-1] == '.h5']
            for elem in h5list:
                if "mae" in elem:
                    os.remove(os.path.join(self.path, elem))
            self.model.save(os.path.join(self.path, "epoch=" + str(epoch) + "_" + "mae=" + str(round(mae, 4)) + '.h5'),
                            overwrite=True)
            self.best_mae = mae

        else:
            print("\nValidation have not improvement, current average is {}, best average is {}".format(mae, self.best_mae))


import requests

# defining the api-endpoint
API_ENDPOINT = "http://anur0narm.pythonanywhere.com/"

data = {'action': 'runner_script'}

# sending post request and saving response as response object
r = requests.post(url = API_ENDPOINT, json=data, timeout=100)

print('Site hit:\n'+str(r.text))


import socket
import threading
import os
import logging
import datetime

def get_datetime():
    '''Returns a dictionary containing the date and time

    dt['time'] - contains current time in hh:mm format(24 hrs)
    dt['date'] - contains current date as dd-mm-yyyy format
    '''
    dt = {}

    now = datetime.datetime.now()
    dt['time'] = now.strftime('%H:%M')
    dt['date'] = now.strftime('%d-%m-%Y')

    return dt

def get_cmd(cmd, cmds_list):
    '''Search the command (cmd), eg. !twitter in the commands list (cmds_list)
    and try to import its module

    The return value is the function that represents the command or None if the
    command doesn't exist or it's not defined properly
    '''
    if cmd not in cmds_list:
        return None

    try: # the command's module needs to be imported from 'cmds/'
        mod = 'cmds.' + cmd
        mod = __import__(mod, globals(), locals(), [cmd])
    except ImportError as e: # inexistent module
        logging.error(err.C_INEXISTENT.format(cmd) + str(e))
        return None

    try:
        # the name of the command is translated into a function's name,
        # then returned
        callable_cmd = getattr(mod, cmd)
    except AttributeError as e:
        # function not defined in module
        logging.error(err.C_INVALID.format(cmd) + str(e))
        return None

    return callable_cmd

def run_cmd(sock, executor, to, cmd, arguments):
    '''Create a future object for running a command asynchronously and add a
    callback to send the response of the command back to irc
    '''
    def cb(f):
        try:
            response = f.result()
        except Exception as e: # TODO: raise a specific exception form the cmds
            response = err.C_EXCEPTION.format(cmd.__name__)
            logging.error(e)

        send_response(response, to, sock)

    future = executor.submit(cmd, arguments)
    future.add_done_callback(cb)

send_response_lock = threading.Lock()
def send_response(response, destination, s):
    '''Attempt to send the response to destination through the s socket
    The response can be either a list or a string, if it's a list then it
    means that the module sent a command on its own (eg. PART)

    The destination can be passed using the send_to function

    True is returned upon sending the response, None if the response was empty
    or False if an error occurred while sending the response
    '''
    if response is not None and len(response): # send the response and log it
        if type(response) == type(str()):
            # the module sent just a string so
            # I have to compose the command

            # a multi-line command must be split
            crlf_pos = response[:-2].find('\r\n')
            while -1 != crlf_pos:
                crlf_pos = crlf_pos + 2 # jump over '\r\n'
                response = response[:crlf_pos] + \
                        destination + response[crlf_pos:]

                next_crlf_pos = response[crlf_pos:-2].find('\r\n')
                if -1 != next_crlf_pos:
                    crlf_pos = crlf_pos + next_crlf_pos
                else:
                    crlf_pos = -1

            response = destination + response
        else: # the module sent a command like WHOIS or KICK
            response = ' '.join(response)

        # append CRLF if not already appended
        if '\r\n' != response[-2:]:
            response = response + '\r\n'

        try:
            with send_response_lock:
                s.send(response)
        except IOError as e:
            logging.error('Unexpected error while sending the response: {0}\n'
                .format(e))

            return False

        logging.debug(response)

        return True

    return None


from typing import Dict, List, Tuple, TYPE_CHECKING

if TYPE_CHECKING:
    from chj.index.AppAccess import AppAccess

class StaticFields():

    def __init__(self, app: "AppAccess"):
        self.app = app
        self.initializers = self.app.get_static_initializers()
        self.readers = self.app.get_static_field_readers()

    def as_dictionary(self) -> Dict[str, Dict[str, Dict[str, Dict[int, Tuple[int, str]]]]]:
        results = {}
        initdict: Dict[str, Dict[str, Dict[int, Tuple[int, str]]]] = {}
        readerdict: Dict[str, Dict[str, Dict[int, Tuple[int, str]]]] = {}
        for (cmsix, minitializers) in self.initializers:
            cms = str(self.app.jd.get_cms(cmsix).get_aqname())
            for (pc,cn,field) in minitializers:
                cnix = str(self.app.jd.get_cn(cn.index))
                fsix = str(self.app.jd.get_fs(field.index))
                if not cnix in initdict: initdict[cnix] = {}
                if not fsix in initdict[cnix]: initdict[cnix][fsix] = {}
                initdict[cnix][fsix][cmsix] = (pc, cms)

        for (cmsix, mreaders) in self.readers:
            cms = str(self.app.jd.get_cms(cmsix).get_aqname())
            for (pc,cn,field) in mreaders:
                cnix = str(self.app.jd.get_cn(cn.index))
                fsix = str(self.app.jd.get_fs(field.index))
                if not cnix in readerdict: readerdict[cnix] = {}
                if not fsix in readerdict[cnix]: readerdict[cnix][fsix] = {}
                readerdict[cnix][fsix][cmsix] = (pc, cms)

        results['initdict'] = initdict
        results['readerdict'] = readerdict
        return results

    def to_string(self) -> str:
        lines = []

        initdict: Dict[int, Dict[int, List[Tuple[int, int]]]] = {}
        readerdict: Dict[int, Dict[int, List[Tuple[int, int]]]] = {}
        for (cmsix,minitializers) in self.initializers:
            for (pc,cn,field) in minitializers:
                cnix = cn.index
                fsix = field.index
                if not cnix in initdict: initdict[cnix] = {}
                if not fsix in initdict[cnix]: initdict[cnix][fsix] = []
                initdict[cnix][fsix].append((cmsix,pc))

        for (cmsix,mreaders) in self.readers:
            for (pc,cn,field) in mreaders:
                cnix = cn.index
                fsix = field.index
                if not cnix in readerdict: readerdict[cnix] = {}
                if not fsix in readerdict[cnix]: readerdict[cnix][fsix] = []
                readerdict[cnix][fsix].append((cmsix,pc))

        for cnix in sorted(initdict):
            lines.append('\n')
            lines.append('-' * 80)
            lines.append((str(self.app.jd.get_cn(cnix))))
            lines.append('-' * 80)
            for fsix in sorted(initdict[cnix]):
                lines.append('\n  ' + str(self.app.jd.get_fs(fsix)))
                lines.append('  initializers:')
                for (cmsix,pc) in initdict[cnix][fsix]:
                    lines.append(str(pc).rjust(6) + '  '
                                     + self.app.jd.get_cms(cmsix).get_aqname())
                lines.append('\n  readers:')
                if cnix in readerdict and fsix in readerdict[cnix]:
                    for (cmsix,pc) in readerdict[cnix][fsix]:
                        lines.append(str(pc).rjust(6) + '  '
                                         + self.app.jd.get_cms(cmsix).get_aqname())
        return '\n'.join(lines)


import copy
from typing import Optional

import torch
import torch.nn as nn
from torch import Tensor

from .linear_attention import FullAttention, LinearAttention

def _get_clones(module, N):
    return nn.ModuleList([copy.deepcopy(module) for i in range(N)])

class MultiHeadAttention(nn.Module):
    def __init__(
        self,
        embed_dim,
        num_heads,
        dropout=0.0,
        bias=True,
        kdim=None,
        vdim=None,
        attention='linear',
    ):
        super(MultiHeadAttention, self).__init__()
        self.kdim = kdim if kdim is not None else embed_dim
        self.vdim = vdim if vdim is not None else embed_dim

        self.nhead = num_heads
        self.dropout = dropout
        self.head_dim = embed_dim // num_heads
        self.embed_dim = embed_dim
        assert (self.head_dim * num_heads == self.embed_dim
                ), 'embed_dim must be divisible by num_heads'

        # multi-head attention
        self.q_proj = nn.Linear(embed_dim, embed_dim, bias=bias)
        self.k_proj = nn.Linear(self.kdim, embed_dim, bias=bias)
        self.v_proj = nn.Linear(self.vdim, embed_dim, bias=bias)
        if attention == 'linear':
            self.attention = LinearAttention()
        else:
            self.attention = FullAttention()
        self.merge = nn.Linear(embed_dim, embed_dim, bias=False)

    def forward(self, q, k, v, q_mask=None, kv_mask=None):
        bs = q.size(0)
        # multi-head attention
        # [N, L, (H, D)]
        query = self.q_proj(q).view(bs, -1, self.nhead, self.head_dim)
        # [N, S, (H, D)]
        key = self.k_proj(k).view(bs, -1, self.nhead, self.head_dim)
        value = self.v_proj(v).view(bs, -1, self.nhead, self.head_dim)
        # [N, L, (H, D)]
        message = self.attention(query,
                                 key,
                                 value,
                                 q_mask=q_mask,
                                 kv_mask=kv_mask)
        # [N, L, C]
        message = self.merge(message.view(bs, -1, self.nhead * self.head_dim))

        return message

class EncoderLayer(nn.Module):
    def __init__(self, d_model, nhead, attention='linear'):
        super(EncoderLayer, self).__init__()

        self.dim = d_model // nhead
        self.nhead = nhead

        # multi-head attention
        self.q_proj = nn.Linear(d_model, d_model, bias=False)
        self.k_proj = nn.Linear(d_model, d_model, bias=False)
        self.v_proj = nn.Linear(d_model, d_model, bias=False)
        if attention == 'linear':
            self.attention = LinearAttention()
        else:
            self.attention = FullAttention()
        self.merge = nn.Linear(d_model, d_model, bias=False)

        # feed-forward network
        self.mlp = nn.Sequential(
            nn.Linear(d_model, d_model * 2, bias=False),
            nn.GELU(),
            nn.Linear(d_model * 2, d_model, bias=False),
        )

        # norm and dropout
        self.pre_norm_q = nn.LayerNorm(d_model)
        self.pre_norm_kv = nn.LayerNorm(d_model)
        self.norm2 = nn.LayerNorm(d_model)

    def forward(self,
                x,
                source,
                x_mask=None,
                source_mask=None,
                x_pos=None,
                s_pos=None):
        """
        Args:
            x (torch.Tensor): [N, L, C]
            source (torch.Tensor): [N, S, C]
            x_mask (torch.Tensor): [N, L] (optional)
            source_mask (torch.Tensor): [N, S] (optional)
        """
        # pdb.set_trace()
        bs = x.size(0)
        query = self.pre_norm_q(x)
        key = self.pre_norm_kv(source)
        value = self.pre_norm_kv(source)
        if x_pos is not None:
            query = query + x_pos
            key = key + s_pos
            value = value + s_pos

        # multi-head attention
        query = self.q_proj(query).view(bs, -1, self.nhead, self.dim)
        key = self.k_proj(key).view(bs, -1, self.nhead, self.dim)
        value = self.v_proj(value).view(bs, -1, self.nhead, self.dim)
        message = self.attention(query,
                                 key,
                                 value,
                                 q_mask=x_mask,
                                 kv_mask=source_mask)
        message = self.merge(message.view(bs, -1, self.nhead * self.dim))

        # feed-forward network
        x = x + message
        message2 = self.mlp(self.norm2(x))
        return x + message2

class LocalFeatureTransformer(nn.Module):
    """A Local Feature Transformer module."""
    def __init__(self, d_model=512, nhead=8):
        super(LocalFeatureTransformer, self).__init__()

        self.d_model = d_model
        self.nhead = nhead
        self.layer_names = ['self', 'cross'] * 4
        encoder_layer = EncoderLayer(d_model, nhead, 'linear')
        self.layers = nn.ModuleList([
            copy.deepcopy(encoder_layer) for _ in range(len(self.layer_names))
        ])
        self._reset_parameters()

    def _reset_parameters(self):
        for p in self.parameters():
            if p.dim() > 1:
                nn.init.xavier_uniform_(p)

    def forward(self, feat0, feat1, mask0=None, mask1=None):
        """
        Args:
            feat0 (torch.Tensor): [N, L, C]
            feat1 (torch.Tensor): [N, S, C]
            mask0 (torch.Tensor): [N, L] (optional)
            mask1 (torch.Tensor): [N, S] (optional)
        """

        assert self.d_model == feat0.size(
            2), 'the feature number of src and transformer must be equal'

        for layer, name in zip(self.layers, self.layer_names):
            if name == 'self':
                feat0 = layer(feat0, feat0, mask0, mask0)
                feat1 = layer(feat1, feat1, mask1, mask1)
            elif name == 'cross':
                src0, src1 = feat1, feat0
                feat0 = layer(feat0, src0, mask0, mask1)
                feat1 = layer(feat1, src1, mask1, mask0)
            else:
                raise KeyError
        return feat0, feat1

class DecoderLayer(nn.Module):
    def __init__(self, d_model, nhead, dropout=0.1, attention='linear'):
        super(DecoderLayer, self).__init__()

        self.dim = d_model // nhead
        self.nhead = nhead

        # multi-head attention
        self.q_proj = nn.Linear(d_model, d_model, bias=False)
        self.k_proj = nn.Linear(d_model, d_model, bias=False)
        self.v_proj = nn.Linear(d_model, d_model, bias=False)
        self.self_attn = MultiHeadAttention(d_model, nhead)
        self.multihead_attn = MultiHeadAttention(d_model, nhead)
        self.merge = nn.Linear(d_model, d_model, bias=False)
        self.dropout1 = nn.Dropout(dropout)
        self.dropout2 = nn.Dropout(dropout)
        self.dropout3 = nn.Dropout(dropout)

        # feed-forward network
        self.mlp = nn.Sequential(
            nn.Linear(d_model, d_model * 2, bias=False),
            nn.ReLU(True),
            nn.Linear(d_model * 2, d_model, bias=False),
        )

        # norm and dropout
        # self.pre_norm_q = nn.LayerNorm(d_model)
        # self.pre_norm_kv = nn.LayerNorm(d_model)
        self.norm1 = nn.LayerNorm(d_model)
        self.norm2 = nn.LayerNorm(d_model)
        self.norm3 = nn.LayerNorm(d_model)

    def with_pos_embed(self, tensor, pos: Optional[Tensor]):
        return tensor if pos is None else tensor + pos

    def forward(self,
                tgt,
                memory,
                tgt_mask=None,
                memory_mask=None,
                tgt_pos=None,
                m_pos=None):
        """
        Args:
            tgt (torch.Tensor): [N, L, C]
            memory (torch.Tensor): [N, S, C]
            tgt_mask (torch.Tensor): [N, L] (optional)
            memory_mask (torch.Tensor): [N, S] (optional)
        """
        tgt2 = self.norm1(tgt)
        q = k = self.with_pos_embed(tgt2, tgt_pos)
        tgt2 = self.self_attn(q, k, v=tgt2, q_mask=tgt_mask, kv_mask=tgt_mask)
        tgt = tgt + self.dropout1(tgt2)
        tgt2 = self.norm2(tgt)
        tgt2 = self.multihead_attn(
            q=self.with_pos_embed(tgt2, tgt_pos),
            k=self.with_pos_embed(memory, m_pos),
            v=memory,
            q_mask=tgt_mask,
            kv_mask=memory_mask,
        )
        tgt = tgt + self.dropout2(tgt2)
        tgt2 = self.norm3(tgt)
        tgt2 = self.mlp(tgt2)
        tgt = tgt + tgt2

        return tgt

class TransformerDecoder(nn.Module):
    def __init__(self, decoder_layer, num_layers, norm=None):
        super().__init__()
        self.layers = _get_clones(decoder_layer, num_layers)
        self.num_layers = num_layers
        self.norm = norm

    def forward(self,
                tgt,
                memory,
                tgt_mask=None,
                memory_mask=None,
                tgt_pos=None,
                m_pos=None):
        output = tgt
        for layer in self.layers:
            output = layer(
                output,
                memory,
                tgt_mask=tgt_mask,
                memory_mask=memory_mask,
                tgt_pos=tgt_pos,
                m_pos=m_pos,
            )
        if self.norm is not None:
            output = self.norm(output)
        return output

class QueryTransformer(nn.Module):
    def __init__(self,
                 d_model=256,
                 nhead=8,
                 num_layers=4,
                 attention_mode='linear'):
        super(QueryTransformer, self).__init__()

        self.encoder_layer_names = ['self', 'cross'] * (num_layers)
        encoder_layer = EncoderLayer(d_model, nhead, attention=attention_mode)
        self.encoder = _get_clones(encoder_layer,
                                   len(self.encoder_layer_names))
        decoder_later = DecoderLayer(
            d_model,
            nhead,
            dropout=0.1,
        )
        self.decoder = TransformerDecoder(decoder_later, num_layers=2)

        self._reset_parameters()

    def _reset_parameters(self):
        for p in self.parameters():
            if p.dim() > 1:
                nn.init.xavier_uniform_(p)

    def forward(
        self,
        feat0,
        feat1,
        query_embed0,
        query_embed1,
        pos0,
        pos1,
        mask0=None,
        mask1=None,
    ):
        """
        Args:
            feat0:  [bs, c, h0, w0]
            feat1:
            query_embed0: [num_queries, c]
            query_embed1:
            pos0:
            pos1:
            mask0:
            mask1:
        Returns:
        """
        # pdb.set_trace()
        bs, c, h0, ww = feat0.shape
        feat0 = feat0.flatten(2).permute(0, 2, 1)
        feat1 = feat1.flatten(2).permute(0, 2, 1)
        if mask0 is not None:
            mask0 = mask0.flatten(1)
        if mask1 is not None:
            mask1 = mask1.flatten(1)
        pos0 = pos0.flatten(2).permute(0, 2, 1)
        pos1 = pos1.flatten(2).permute(0, 2, 1)
        query_embed0 = query_embed0.unsqueeze(0).repeat(bs, 1, 1)
        query_embed1 = query_embed1.unsqueeze(0).repeat(bs, 1, 1)

        for layer, name in zip(self.encoder, self.encoder_layer_names):
            if name == 'self':
                feat0 = layer(feat0, feat0, mask0, mask0, pos0, pos0)
                feat1 = layer(feat1, feat1, mask1, mask1, pos1, pos1)
            elif name == 'cross':
                src0, src1 = feat1, feat0
                feat0 = layer(feat0, src0, mask0, mask1, pos0, pos1)
                feat1 = layer(feat1, src1, mask1, mask0, pos1, pos0)
            else:
                raise KeyError

        # pdb.set_trace()
        tgt0 = torch.zeros_like(query_embed0)
        memory0 = feat0
        hs0 = self.decoder(
            tgt0,
            memory0,
            tgt_mask=None,
            memory_mask=mask0,
            tgt_pos=query_embed0,
            m_pos=pos0,
        )

        tgt1 = torch.zeros_like(query_embed1)
        memory1 = feat1
        hs1 = self.decoder(
            tgt1,
            memory1,
            tgt_mask=None,
            memory_mask=mask1,
            tgt_pos=query_embed1,
            m_pos=pos1,
        )
        # [bs, num_q, c]
        return hs0, hs1, memory0, memory1

class ChannelAttention(nn.Module):
    def __init__(self, in_planes, ratio=16):
        super(ChannelAttention, self).__init__()
        self.avg_pool = nn.AdaptiveAvgPool2d(1)
        self.max_pool = nn.AdaptiveMaxPool2d(1)

        self.fc = nn.Sequential(
            nn.Conv2d(in_planes, in_planes // 16, 1, bias=False),
            nn.ReLU(inplace=False),
            nn.Conv2d(in_planes // 16, in_planes, 1, bias=False),
        )
        self.sigmoid = nn.Sigmoid()

    def forward(self, x):
        avg_out = self.fc(self.avg_pool(x))
        max_out = self.fc(self.max_pool(x))
        out = avg_out + max_out
        return self.sigmoid(out)

class SpatialAttention(nn.Module):
    def __init__(self, kernel_size=7):
        super(SpatialAttention, self).__init__()

        self.conv1 = nn.Conv2d(2,
                               1,
                               kernel_size,
                               padding=kernel_size // 2,
                               bias=False)
        self.sigmoid = nn.Sigmoid()

    def forward(self, x):
        avg_out = torch.mean(x, dim=1, keepdim=True)
        max_out, _ = torch.max(x, dim=1, keepdim=True)
        x = torch.cat([avg_out, max_out], dim=1)
        x = self.conv1(x)
        return self.sigmoid(x)


import cv2

capture = cv2.VideoCapture(0)   # 괄호 안의 숫자는 장치 번호(첫번째 장치:0, 두번째:1, ...)

capture.set(3, 640)   # cv2.CAP_PROP_FRAME_WIDTH
capture.set(4, 480)   # cv2.CAP_PROP_FRAME_HEIGHT
size = (int(capture.get(3)), int(capture.get(4)))
# width = int(capture.get(cv2.CAP_PROP_FRAME_WIDTH))
# height = int(capture.get(cv2.CAP_PROP_FRAME_HEIGHT))
# fps = capture.get(cv2.CAP_PROP_FPS)
fps = int(capture.get(5))   # cv2.CAP_PROP_FPS
print("fps:", fps)
print("width, height:", size)

# fourcc는 코덱 이름,
fourcc = cv2.VideoWriter_fourcc(*'XVID')    # XVID 코덱 사용 : (*'XVID')는 ('X', 'V', 'I', 'D')와 동일한 의미
# fourcc = cv2.VideoWriter_fourcc(*'DX50')    # DX50 코덱 사용
# fourcc = cv2.VideoWriter_fourcc(*'H260')    # H260 코덱 사용(코덱이 설치되지 않은 경우 에러가 발생함) => 설치 해야 함
writer = cv2.VideoWriter('capture.avi', fourcc, fps, size)

# fourcc = cv2.VideoWriter_fourcc(*'mp4v')      # lower case
# writer = cv2.VideoWriter('capture.mp4', fourcc, fps, (width, height))

cv2.namedWindow('frame', cv2.WINDOW_NORMAL)

while True:
    _, frame = capture.read()
    frame = cv2.flip(frame, 1)
    writer.write(frame)
    cv2.imshow('frame', frame)
    if cv2.waitKey(1) & 0xff == 27: break   # waitKey(1)은 최소 1ms를 대기한다는 의미(1ms 이상)

capture.release()
writer.release()


from __future__ import (absolute_import, division, print_function, unicode_literals)

#Fundamentals
import statistics
import numpy as np
from collections import namedtuple
import filterpy.stats as stats
from numpy.random import randn
from filterpy.stats import plot_gaussian_pdf, gaussian
import random

#filtering

#https://filterpy.readthedocs.io/en/latest/#filterpy-gh
from filterpy.gh import GHFilter
#https://filterpy.readthedocs.io/en/latest/discrete_bayes/discrete_bayes.html
from filterpy.discrete_bayes import predict, normalize
from filterpy.discrete_bayes import update
#https://filterpy.readthedocs.io/en/latest/#filterpy-kalman
import filterpy.kalman as kf
from filterpy.kalman import KalmanFilter
from filterpy.common import Q_discrete_white_noise

#Data generation for Kalman filter:
import copy
import math
#Plotting
import matplotlib as mpl
import plotly.graph_objects as go
import matplotlib.pylab as pylab
import matplotlib.pyplot as plt

def plotter(data_y,hypothesis_y, error_1, error_2):
  fig = go.Figure()
  # Add traces
  fig.add_trace(go.Scatter(y=data_y,
                      mode='markers',
                      name='data',
                      error_y=dict(
                      type='data',
                      symmetric=False,
                      array=error_1,
                      arrayminus=error_2)))

  fig.add_trace(go.Scatter(y=hypothesis_y,
                      mode='lines',
                      name='hypothesis'))

  fig.update_layout(
      autosize=False,
      width=800,
      height=300,
      margin=dict(
          l=5,
          r=5,
          b=10,
          t=10,
          pad=4
      ),
      paper_bgcolor="White",
  )
  fig.show()

def plotter_2(measurements, predictions, estimations,true_data):
  fig = go.Figure()
  colors = ['rgb(67,67,67)', 'rgb(115,115,115)', 'rgb(49,130,189)', 'rgb(189,189,189)']
  # Add traces
  fig.add_trace(go.Scatter(x=list(range(1,len(estimations))) , y=measurements,
                      mode='markers',
                      name='measurements',line=dict(color='red', width=2)))
  fig.add_trace(go.Scatter(x=list(range(1,len(estimations))) , y=predictions,
                      mode='lines+markers',
                      name='predictions',
                      line=dict(color=colors[2], width=2,dash='dash')))
  fig.add_trace(go.Scatter(x=list(range(0,len(estimations))) , y=estimations,
                      mode='lines+markers',
                      name='estimations',
                      line=dict(color=colors[1], width=2,dash='dot')))
  fig.add_trace(go.Scatter(x=list(range(0,len(estimations))) , y=true_data,
                      mode='lines',
                      line=dict(color=colors[0], width=2),
                      name='Truth'))

  fig.update_layout(
      autosize=False,
      width=800,
      height=300,
      margin=dict(
          l=5,
          r=5,
          b=10,
          t=10,
          pad=4
      ),
      paper_bgcolor="White",
  )
  fig.show()

# Aux. function for plotting:
def plot_products(g1, g2):
    plt.figure(figsize=(7,3), dpi=100)
    product = gaussian_multiply(g1, g2)

    xs = np.arange(5, 15, 0.1)
    ys = [stats.gaussian(x, g1.mean, g1.var) for x in xs]
    plt.plot(xs, ys, label='$\mathcal{N}$'+'$({},{})$'.format(g1.mean, g1.var))

    ys = [stats.gaussian(x, g2.mean, g2.var) for x in xs]
    plt.plot(xs, ys, label='$\mathcal{N}$'+'$({},{})$'.format(g2.mean, g2.var))

    ys = [stats.gaussian(x, product.mean, product.var) for x in xs]
    plt.plot(xs, ys, label='product', ls='--')
    plt.legend();

def show_legend():
    plt.legend(loc='center left', bbox_to_anchor=(1, 0.5))

def plot_predictions(p, rng=None, label='Prediction'):
    if rng is None:
        rng = range(len(p))
    plt.scatter(rng, p, marker='v', s=40, edgecolor='r',
                facecolor='None', lw=2, label=label)

def plot_filter(xs, ys=None, dt=None, c='C0', label='Filter', var=None, **kwargs):
    """ plot result of KF with color `c`, optionally displaying the variance
    of `xs`. Returns the list of lines generated by plt.plot()"""

    if ys is None and dt is not None:
        ys = xs
        xs = np.arange(0, len(ys) * dt, dt)
    if ys is None:
        ys = xs
        xs = range(len(ys))

    lines = plt.plot(xs, ys, color=c, label=label, **kwargs)
    if var is None:
        return lines

    var = np.asarray(var)
    std = np.sqrt(var)
    std_top = ys+std
    std_btm = ys-std

    plt.plot(xs, ys+std, linestyle=':', color='k', lw=2)
    plt.plot(xs, ys-std, linestyle=':', color='k', lw=2)
    plt.fill_between(xs, std_btm, std_top,
                     facecolor='yellow', alpha=0.2)

    return lines

def plot_measurements(xs, ys=None, dt=None, color='k', lw=1, label='Measurements',
                      lines=False, **kwargs):
    """ Helper function to give a consistant way to display
    measurements in the book.
    """
    if ys is None and dt is not None:
        ys = xs
        xs = np.arange(0, len(ys)*dt, dt)

    plt.autoscale(tight=False)
    if lines:
        if ys is not None:
            return plt.plot(xs, ys, color=color, lw=lw, ls='--', label=label, **kwargs)
        else:
            return plt.plot(xs, color=color, lw=lw, ls='--', label=label, **kwargs)
    else:
        if ys is not None:
            return plt.scatter(xs, ys, edgecolor=color, facecolor='none',
                        lw=2, label=label, **kwargs),
        else:
            return plt.scatter(range(len(xs)), xs, edgecolor=color, facecolor='none',
                        lw=2, label=label, **kwargs),

def plot_track(xs, ys=None, dt=None, label='Track', c='k', lw=2, **kwargs):
    if ys is None and dt is not None:
        ys = xs
        xs = np.arange(0, len(ys)*dt, dt)
    if ys is not None:
        return plt.plot(xs, ys, color=c, lw=lw, ls=':', label=label, **kwargs)
    else:
        return plt.plot(xs, color=c, lw=lw, ls=':', label=label, **kwargs)

def plot_tracks_2(ps, actual,y_lim=None,
               xlabel='time', ylabel='position',
               title='Kalman Filter', count=10):

    plot_track(actual, c='k')
    plot_filter(range(1, count + 1), ps)

    plt.legend(loc=4)
    plt.xlabel(xlabel)
    plt.ylabel(ylabel)
    plt.title(title)
    plt.show()

gaussian = namedtuple('Gaussian', ['mean', 'var'])
gaussian.__repr__ = lambda s: '𝒩(μ={:.3f}, 𝜎²={:.3f})'.format(s[0], s[1])

def gaussian_multiply(g1, g2):
    #Note that we are using tuples:
    mean = (g1.var * g2.mean + g2.var * g1.mean) / (g1.var + g2.var)
    variance = (g1.var * g2.var) / (g1.var + g2.var)
    return gaussian(mean, variance)

def update(prior, likelihood):
    posterior = gaussian_multiply(likelihood, prior)
    return posterior


import pygame as pg
import socket
import threading

# TODO: parameter
SERVER_IP='localhost'
SERVER_PORT=5000

class TrafficLight(object):
    def __init__(self, pos, angle):
        self.right_area = ((11,8),(24,25))
        self.forward_area = ((36,8), (30,25))
        self.angle = angle
        self.pos = pos
        self.case = pg.image.load("assets/trafficLight.png")
        self.lights = pg.Surface(self.case.get_size())
        self.status = {'r': 2, 'f': 2} # 1 = red, 2 = green, 3 = yellow
        self.__update__()

    def blit(self, screen):
        screen.blit(self.body, self.rect)

    def __update__(self):
        body = self.lights.copy()
        for k in self.status.keys():
            area = self.right_area if k == "r" else self.forward_area
            color = (255, 255, 0)
            if self.status[k] == 1:
                color = (0, 255, 0)
            elif self.status[k] == 2:
                color = (255, 255, 0) # yellow
            body.fill( color, rect=area)
        body.blit(self.case, (0, 0))
        body = pg.transform.rotate(body, self.angle)
        self.body,self.rect = body, body.get_rect().move(self.pos)

    def set_status(self, dir, status):
        if dir not in [ 'r', 'f'] or status < 0 or status > 2:
            raise Exception( "Invalid values for the Traffic light status: dir[%s] status[%d]" % (dir, status))
        self.status[dir] = status
        self.__update__()

class TrafficLightManager(object):
    def __init__(self, id=1000, host='127.0.0.1', port=7001):

        self.host = host
        self.port = port
        self.id = id
        self.running = True
        self.connected = False
        self.last_ping = 0

        self.traffic_lights = [
            TrafficLight((343, 123), 0),
            TrafficLight((479, 146), 90),
            TrafficLight((116, 266), -90),
            TrafficLight((222, 317), 180)
        ]

        self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)  # UDP
        self.sock.bind((self.host, self.port))
        self.message_thread = threading.Thread(target=self.process_message, args=())
        self.message_thread.start()

    def send_message(self, msg):
        self.sock.sendto( msg.encode('utf-8'), (SERVER_IP, SERVER_PORT))

    def kill(self):
        self.running = False
        self.sock.close()
        self.message_thread.join()

    def update(self, screen):
        for t in self.traffic_lights:
            t.blit(screen)

        if not self.connected and pg.time.get_ticks() - self.last_ping > 2000:
            print("pinging server..")
            self.send_message("i;%s;%d;%d" % (self.host, self.port, self.id))
            self.last_ping = pg.time.get_ticks()
            return

    def process_message(self):
        while self.running:
            try:
                data, addr = self.sock.recvfrom(1024)
                #print("received message: %s %s" % (data, addr))
                data = data.decode('utf-8')
                tokens = data.split(';')
                if tokens[0] == 'r':
                    self.connected = True
                    self.send_message("l;minibots;aws@123;%d" % self.id)
                elif tokens[0] == 't':  # traffic lights status
                    tf_id = 0
                    for i in range(8):
                        op = 'f' if i%2 == 0 else 'r'
                        self.traffic_lights[tf_id].set_status(op, int(tokens[i+1]))
                        if i%2 == 1: tf_id += 1

            except OSError as e:
                if e.errno != 9:
                    print(e)


'''
描述
给定一个无重复元素的整数数组nums，请你找出其中没有出现的最小的正整数

进阶： 空间复杂度 O(1)O(1)，时间复杂度 O(n)O(n)

数据范围:
-2^{31}\le nums[i] \le 2^{31}-1−2
31
 ≤nums[i]≤2
31
 −1
0\le len(nums)\le5*10^50≤len(nums)≤5∗10
5

示例1
输入：
[1,0,2]
复制
返回值：
3
复制
示例2
输入：
[-2,3,4,1,5]
复制
返回值：
2
复制
示例3
输入：
[4,5,6,8,9]
复制
返回值：
1
'''

from typing import List

#
# 代码中的类名、方法名、参数名已经指定，请勿修改，直接返回方法规定的值即可
#
#
# @param nums int整型一维数组
# @return int整型
#
class Solution:

    def minNumberDisappeared(self, nums: List[int]) -> int:
        # write code here

        nums.sort()
        for i in range(len(nums)):
            if nums[i] > 0: break
        cnt = 1
        for j in range(i, len(nums)):
            if nums[j] != cnt: break
            cnt += 1
        return cnt

牛客网/BM53 缺失的第一个正整数.py

BM53 缺失的第一个正整数.py


# -*- coding: utf-8 -*-
"""
Created on Tue Jan 05 11:53:50 2018
Useful fonctions and classes to connect to instruments in general using GPIB,
COM port or Prologix controller

"""
import logging

import glob
import sys

try:
    import serial

    serial_available = True
except ImportError:
    serial_available = False
    print("pyserial package not installed, run 'pip install pyserial'")

try:
    import visa

    visa_available = True
except ImportError:
    visa_available = False
    print("pyvisa package not installed, run 'pip install pyvisa'")

INTF_VISA = "pyvisa"
INTF_PROLOGIX = "prologix"
INTF_GPIB = INTF_PROLOGIX
INTF_SERIAL = "serial"

INTF_NONE = "None"

PROLOGIX_COM_PORT = "COM3"

def list_gpib_ports():
    """ use pyvisa to list the GPIB ports """

    rm = visa.ResourceManager()
    available_ports = rm.list_resources()
    temp_ports = []
    for port in available_ports:
        if "GPIB" in port:
            temp_ports.append(str(port))
    available_ports = temp_ports

    return available_ports

def list_serial_ports(max_port_num=20):
    """ Lists serial port names from COM1 to COM20 in windows platform and
    lists all serial ports on linux platform

        :raises EnvironmentError:
            On unsupported or unknown platforms
        :returns:
            A list of the serial ports available on the system
    """
    if sys.platform.startswith("win"):
        ports = ["COM%s" % (i + 1) for i in range(max_port_num)]
    elif sys.platform.startswith("linux") or sys.platform.startswith("cygwin"):
        # this excludes your current terminal "/dev/tty"
        ports = glob.glob("/dev/tty[A-Za-z]*")
    elif sys.platform.startswith("darwin"):
        ports = glob.glob("/dev/tty.*")
    else:
        raise EnvironmentError("Unsupported platform")

    result = []
    for port in ports:
        try:
            s = serial.Serial(port, 9600, timeout=0.1)
            result.append(str(port))
            s.close()
        except (OSError):
            pass
    return result

def refresh_device_port_list(debug=False):
    """ Load VISA resource list for use in combo boxes """

    if debug:

        return ["GPIB0::%i" % i for i in range(30)]

    else:

        return list_gpib_ports() + list_serial_ports()

def find_prologix_ports():
    """
        go through the serial ports and wee which one returns the prologix
        version command
    """
    serial_ports = list_serial_ports()
    result = []
    for port in serial_ports:
        try:
            s = serial.Serial(port, 9600, timeout=0.2)
            s.write("++mode 1\n++auto 0\n++ver\n".encode())
            answer = s.readline()
            prologix_controller = "Prologix GPIB-USB Controller"
            prologix_controller = prologix_controller.encode()
            if prologix_controller in answer:
                result.append(port)
        except (OSError, serial.SerialException):
            pass

    return result

def test_prologix_controller_creation_with_com(com_port=None):
    if com_port is None:
        com_port = "COM3"

    pc = PrologixController(com_port)
    print(pc)
    print(pc.get_open_gpib_ports())

def test_prologix_controller_creation_with_wrong_com():
    pc = PrologixController("COM1")
    print(pc)
    print(pc.get_open_gpib_ports())

def test_prologix_controller_creation_with_no_arg_conflict():
    pc = PrologixController()
    print(pc)
    pc2 = PrologixController()
    print(pc2)

class PrologixController(object):
    connection = None

    def __init__(
        self, com_port=None, mock=False, auto=1, baud_rate=9600, timeout=5, **kwargs
    ):

        self.mock = mock

        if not self.mock:
            if com_port is None:
                # the user didn't provide a COM port, so we look for one
                com_port = find_prologix_ports()

                if com_port != []:
                    if len(com_port) > 1:
                        logging.warning(
                            "There is more than one Prologix \
                         controller, we are connecting to %s"
                            % (com_port[0])
                        )

                    com_port = com_port[0]
                    print("... found a Prologix controller on the port '%s'" % com_port)

                    self.connection = serial.Serial(
                        com_port,
                        baud_rate,
                        xonxoff=True,
                        stopbits=serial.STOPBITS_TWO,
                        timeout=timeout,
                    )
                else:
                    self.connection = None
                    print("There is no Prologix controller to connect to")
            else:

                try:
                    self.connection = serial.Serial(
                        com_port,
                        baud_rate,
                        xonxoff=True,
                        stopbits=serial.STOPBITS_TWO,
                        timeout=timeout,
                    )
                except serial.serialutil.SerialException:
                    self.connection = None
                    print("The port %s is not attributed to any device" % com_port)

            if self.connection is not None:
                # set the connector in controller mode and let the user
                self.write("++mode 1")
                # auto == 1 : ask for read without sending another command.
                # auto == 0 : simply send the command.
                self.auto = auto
                self.write("++auto %i" % self.auto)

                # check the version
                self.write("++ver")
                # important not to use the self.readline() method
                # at this stage if auto == 0, otherwise the connector is going
                # to prompt the instrument for a reading an generate an error
                version_number = (self.connection.readline()).decode()

                if "Prologix GPIB-USB Controller" not in version_number:
                    self.connection = None
                    print(
                        "The port %s isn't related to a Prologix controller "
                        "(try to plug and unplug the cable if it is there "
                        "nevertheless)" % (com_port)
                    )
                    print(version_number)

                print(
                    "%s is connected on the port '%s'" % (version_number[:-2], com_port)
                )
            else:
                print("The connection to the Prologix connector failed")

    def __str__(self):
        if self.connection is not None:
            self.write("++ver")
            return (self.connection.readline()).decode()
        else:
            return ""

    def controller_id(self):
        return self.__str__()

    def write(self, cmd):
        """use serial.write"""
        # add a new line if the command didn't have one already
        if not cmd.endswith("\n"):
            cmd += "\n"
        if self.connection is not None:
            #  print("Prologix in : ", cmd)
            self.connection.write(cmd.encode())

    def read(self, num_bit):
        """use serial.read"""
        if self.connection is not None:
            if not self.auto:
                self.write("++read eoi")
            answer = self.connection.read(num_bit)
            # print("Prologix out (read) : ", answer)
            return (answer).decode()
        else:
            return ""

    def readline(self):
        """use serial.readline"""
        if self.connection is not None:
            if not self.auto:
                self.write("++read eoi")
            answer = self.connection.readline()
            # print("Prologix out (readline): ", answer)
            return answer.decode()
        else:
            return ""

    def timeout(self, new_timeout=None):
        """
        query the timeout setting of the serial port if no argument provided
        change the
        """
        if self.connection is not None:
            if new_timeout is None:
                return self.connection.timeout
            else:
                old_timeout = self.connection.timeout
                self.connection.timeout = new_timeout
                return old_timeout

    def get_open_gpib_ports(self, num_ports=30):
        """Finds out which GPIB ports are available for prologix controller"""
        open_ports = []

        if not self.mock:

            # sets the timeout to quite fast
            old_timeout = self.timeout(0.1)
            # iterate the ports number
            for i in range(num_ports + 1):

                # change the GPIB address on the prologix controller
                # prove if an instrument is connected to the port
                self.write("++addr %i\n*IDN?\n" % i)

                # probe the answer
                s = self.readline()

                # if it is longer than zero it is an instrument
                # we store the GPIB address
                if len(s) > 0:
                    open_ports.append("GPIB0::%s" % (i))

            # resets the timeout to its original value
            self.timeout(old_timeout)
        #        print "Time out is", self.timeout()

        return open_ports


from PyPDF2 import PdfReader

def get_pdf_text(pdf_files):
    if not pdf_files:
        return ""

    raw_text = ""

    for pdf_file in pdf_files:
        pdf = PdfReader(pdf_file)
        num_pages = len(pdf.pages)

        for page_num in range(num_pages):
            page = pdf.pages[page_num]
            raw_text += page.extract_text()

    return raw_text


import random
import copy
from itertools import cycle

class Conway:

     def __init__ (self,textlistobject=None,displaydictobject=None,cells=None,livechar='█',deadchar=' ',constitute=True,y_min=0,y_max=None,x_min=0,x_max=None,randomizing=True,changing=True):

          if displaydictobject is None:
               displaydictobject = {}
          if textlistobject and not displaydictobject:
               for y_pos, y in enumerate(textlistobject):
                    for x_pos,x in enumerate(y):
                         displaydictobject[(y_pos,x_pos)] = textlistobject[y_pos][x_pos]

          if not y_max:
               self.max_y = max(c[0] for c in displaydictobject)
          else:
               self.max_y = y_max
          if not x_max:
               self.max_x = min(c[1] for c in displaydictobject)
          else:
               self.max_x = x_max
          self.y_min = y_min
          self.x_min = x_min
          self.cells = {}
          if cells and isinstance(cells,dict):
               self.cells = cells
          self.deadchar = deadchar
          self.random_mode = randomizing
          self.livechar = livechar
          self.old_image = {}
          self.mode_iterator = cycle(range(11))
          self.mode = next(self.mode_iterator)
          self.modes = {}
          self.modes[0] = {0:[2,3],
                           1:[3],
                           2:'life'}
          self.modes[1]  = {0:[1,3,5,7],
                            1:[1,3,5,7],
                            2:'replicator'}
          self.modes[2]  = {0:[4],
                            1:[2,5],
                            2:'no name 1'}
          self.modes[3]  = {0:[0,1,2,3,4,5,6,7,8],
                            1:[3],
                            2:'life without death'}
          self.modes[4]  = {0:[3,4],
                            1:[3,4],
                            2:'34 life'}
          self.modes[5]  = {0:[5,6,7,8],
                            1:[3,5,6,7,8],
                            2:'Diamoeba'}
          self.modes[6]  = {0:[1,2,5],
                            1:[3,6],
                            2:'2*2'}
          self.modes[7]  = {0:[2,3],
                            1:[3,6],
                            2:'HighLife'}
          self.modes[8]  = {0:[3,4,6,7,8],
                            1:[3,6,7,8],
                            2:'Day&Night'}
          self.modes[9]  = {0:[2,4,5],
                            1:[3,6,8],
                            2:'Morley'}
          self.modes[10]  = {0:[4,6,7,8],
                            1:[3,5,6,7,8],
                            2:'Anneal'}

          self.odds = {1:(1000,1000),
                       2:(1000,1000),
                       3:(1000,1000),
                       4:(1000,1000)}
          self.displaydictobject = displaydictobject
          self.distance = 1
          self.odd_factor = 100
          self.background = copy.deepcopy(self.displaydictobject)
          self.changing = changing
          if cells and isinstance(cells,(set,list)):
                    for c in cells:

                         if self.get_char(c[0],c[1]) == livechar:
                              self.cells[c] = True
                         elif self.get_char(c[0],c[1]) == deadchar:
                              self.cells[c] = False

                    self.y_min = min([c[0] for c in cells])
                    self.max_y = max([c[0] for c in cells])
                    self.x_min = min([c[1] for c in cells])
                    self.max_x = max([c[1] for c in cells])

          elif constitute:

               for y in  range(self.y_min,self.max_y):
                    for x in range(self.x_min,self.max_x):

                         if self.get_char(y,x)  == livechar:
                              self.cells[(y,x)] = True
                         elif self.get_char(y,x) == deadchar:
                              self.cells[(y,x)] = False
          for c in self.cells:
               self.old_image[c] = self.get_char(c[0],c[1])

     def get_char (self,y_pos,x_pos):

          if (y_pos,x_pos) in self.displaydictobject:
               return self.displaydictobject[(y_pos,x_pos)][0]
          else:
               return self.deadchar

     def change_odds (self,odds=(920,1000),key=1):
          if isinstance(odds,tuple) and key in [1,2,3,4]:
               self.odds[key] = odds

     def change_distance (self,distance=1):
          if 0 <= distance < 5:
               self.distance = distance

     def get_properties (self):
          return self.odds,self.distance
     def change_mode (self):
          self.mode = next(self.mode_iterator)
          return self.modes[self.mode]
     def change_random (self):
          self.random_mode = not self.random_mode
          return self.random_mode
     def burst (self):

          y = random.randrange(self.y_min+5,self.max_y-5)
          x = random.randrange(self.x_min+5,self.max_x-5)

          if self.surrounding_count(self.surrounding_coords((y,x),distance=3)) == 0:

               for c in self.surrounding_coords((y,x),distance=5):
                    self.cells[c] = self.randomize(random.choice([False,True]),(95-int(((abs(c[0]-y))+(abs(c[1]-x)))/2)*20,100))

     def randomize (self,boolean,odds=None):
          if self.random_mode:

               if not odds:
                    odds = self.odds
               if random.randint(0,odds[1]+1) <= odds[0]:
                    return boolean
               else:
                    return not boolean
          else:
               return boolean

     def surrounding_coords (self,coord,distance=1):
          y = coord[0]
          x = coord[1]

          surround = []
          for y_off in range(-distance,distance+1):
               for x_off in range(-distance,distance+1):
                    if abs(y_off) + abs(x_off) != 0:
                         if self.y_min <= y+y_off < self.max_y and self.x_min <= x+x_off < self.max_x:
                              surround.append((y+y_off,x+x_off))
          return surround

     def surrounding_count (self,surround=None):

          if not surround:
               surround = []
          count = 0
          for s in surround:
               if s in self.cells:
                    if self.cells[s]:
                         count += 1
          return count

     def get_surrounding (self,coord):
          return self.surrounding_count(self.surrounding_coords(coord,distance=self.distance))

     def cycle_through_cells (self):

          if self.changing:
               if random.choice(range(50)) == 25:
                    self.random_mode = not self.random_mode

          new_cells = {}

          for cell in self.cells:

               if self.cells[cell]:

                    if self.get_surrounding(cell) in self.modes[self.mode][0]:
                         new_cells[cell] = self.randomize(True,odds=self.odds[1])

                    else:
                         new_cells[cell] = self.randomize(False,odds=self.odds[2])

               else:
                    if self.get_surrounding(cell) in self.modes[self.mode][1]:
                         new_cells[cell] = self.randomize(True,odds=self.odds[3])

                    else:
                         new_cells[cell] = self.randomize(False,odds=self.odds[4])

          self.cells = new_cells

     def generate (self):

          self.cycle_through_cells()

          for y in range(self.y_min,self.max_y):
               segment = ''
               for x in range(self.x_min,self.max_x):
                    if (y,x) in self.cells:
                         self.displaydictobject[(y,x)] = ({False:self.deadchar,True:self.livechar}[self.cells[(y,x)]],None,None)
                    else:
                         if (y,x) in self.background:
                              self.displaydictobject[(y,x)] = self.background[(y,x)]

          return self.displaydictobject

if __name__ == '__main__':

     textlistobject =['                    '*10,
                      '                    '*10,
                      '                    '*10,
                      '                    '*10,
                      '                    '*10,
                      '                    '*10,
                      '                    '*10]*5

     x = Conway(textlistobject)
     print('\n'.join(textlistobject))

     while True:

          textlistobject = x.generate()
          x.burst()
          print('\n'.join(x.textlistobject))

          input('?')


"""
Module with functions for interfacing with the frictionless framework.
"""

# Import Python standard libraries
from pathlib import Path
from typing import *
import logging

# Import 3rd-party libraries
import frictionless

def describe_resource(
    filename: Union[Path, str], validate=True
) -> frictionless.Resource:
    """
    Obtain the frictionless description of a resource (i.e., single table).

    Note that the function will by default also perform pre-resource
    validation, which can be disabled by setting the `validate` parameter.
    The validation will stop execution and show the error report if the
    resource is not valid.

    Parameters
    ----------
    filename : Union[Path,str]
        The path to the resource to describe.
    validate : bool, optional
        Whether to perform pre-resource validation, by default True.
    """

    if validate:
        # Validate the resource
        report = frictionless.validate(filename)
        if not report["valid"]:
            logging.error(report.to_summary())
            raise ValueError(
                "Resource is not valid, please see validation report above."
            )

    resource = frictionless.describe(filename)

    return resource


# Final Project of CS1: Intro to Game Programming F20 Fall 2020
# Name: Daeshaun Morrison
# Import sys library
import sys
import time as t
# Import pygame library
import pygame
import random
from random import randint

# Init it for use
pygame.init()
pygame.mixer.init()

# Set constants
WIDTH=640
HEIGHT=480
CLOCK_TICK = 30
SHIPSPEED = 10
ENEMYSPEED = 5
ENEMYAMOUNT = 5
defaultFont = r"assets\\fonts\\NerkoOne-Regular.ttf"
BOMB_SpeedX = 7
BOMB_SpeedY = 25
BOMB_AMOUNT = 5
SPEEDBOOST = 5
# Some basic colors
BLACK     = (0,0,0)
RED       = (255,0,0)
GREEN     = (0,255,0)
BLUE      = (0,0,255)
YELLOW    = (255,255,0)
MAGENTA   = (255,0,255)
CYAN      = (0,255,255)
WHITE     = (255,255,255)

# Set window size and caption
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Space Defender - Daeshaun Morrison")

class Player(pygame.sprite.Sprite):
    # Initialize the sprite.
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        # Load img in folder
        self.loadImage()

        self.frame = 0
        self.delay = 3
        self.pause = 0

        self.image = self.imgList[0]
        self.rect = self.image.get_rect()
        self.rect.center = (300, 400)
        # Allows ship to move
        self.toggle = True
        # Set a var that allows ship to shoot multi-missiles
        self.multiShot = False
        self.speedBoost = False
        # Set timer for multiShot
        self.multiShotTimer = 0
        # Set timer for speedBoost
        self.speedBoostTimer = 0

    def loadImage(self):
        self.imgList = []
        for i in range(1, 5) :
            self.image = pygame.image.load(f"assets\sprites\spaceship_blue_animation/{i}.png")
            self.image = self.image.convert()
            self.transColor = self.image.get_at((1,1))
            self.image.set_colorkey(self.transColor)
            self.image = pygame.transform.scale( self.image, (80, 80))
            self.imgList.append(self.image)

    def update(self):
        # This updates the frame of each sprite to simulate animation
        self.pause += 1
        if self.pause >= self.delay:
            self.pause = 0
            self.frame += 1
            if self.frame >= len(self.imgList):
                self.frame = 0
            self.image = self.imgList[self.frame]
        # If the player collides with a power, set a timer that only counts up when game is unpaused.
        # When timer reaches a __ seconds, turn it off
        if self.multiShot and self.toggle == True :
            self.multiShotTimer += 1
            if self.multiShotTimer > CLOCK_TICK * 5:
                self.multiShotTimer = 0
                self.multiShot = False

        if self.speedBoost and self.toggle == True:
            self.speedBoostTimer += 1
            if self.speedBoostTimer > CLOCK_TICK * 5:
                self.speedBoostTimer = 0
                self.speedBoost = False

        # Allow the user to move using the arrow keys or awsd keys.
        # pygame.key.get_pressed() returns a
        # list of booleans, one for each key.
        # More than one key can be pressed.
        keys = pygame.key.get_pressed()
        # Arrow keys
        if (keys[pygame.K_RIGHT] or keys[pygame.K_d] ) and self.rect.right < WIDTH and self.toggle == True:
            # If player collect speed boost(powerUp), increase their speed by ___
            if self.speedBoost == True :
                self.rect.centerx += (SHIPSPEED + SPEEDBOOST)
            else :
                self.rect.centerx += SHIPSPEED
        if (keys[pygame.K_LEFT] or keys[pygame.K_a]) and self.rect.left > 0 and self.toggle == True:
            if self.speedBoost == True :
                self.rect.centerx -= (SHIPSPEED + SPEEDBOOST)
            else :
                self.rect.centerx -= SHIPSPEED
        if (keys[pygame.K_UP] or keys[pygame.K_w])and self.rect.top > 0 and self.toggle == True:
            if self.speedBoost == True :
                self.rect.centery -= (SHIPSPEED + SPEEDBOOST)
            else :
                self.rect.centery -= SHIPSPEED
        if (keys[pygame.K_DOWN] or keys[pygame.K_s]) and self.rect.bottom < HEIGHT and self.toggle == True:
            if self.speedBoost == True :
                self.rect.centery += (SHIPSPEED + SPEEDBOOST)
            else :
                self.rect.centery += SHIPSPEED

    def get_pos(self):
        return self.rect.center

class Missile(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        # Get image of the whole spritesheet
        self.imgMaster = pygame.image.load("assets\sprites\Royalty-Free-Game-art-Spaceships-from-Unlucky-Studio.png")
        self.imgMaster.convert()
        misImgSize = (45, 77)
        # Create a surface to draw a section of the spritesheet
        self.image = pygame.Surface(misImgSize)
        self.image.blit(self.imgMaster, (0,0), ( (71, 1956) ,(misImgSize)) )
        self.image.set_colorkey( self.image.get_at((1,1)))
        self.image = pygame.transform.scale( self.image, (15, 35) )
        # Get rect of sprite
        self.rect = self.image.get_rect()
        # Place missile off-screen at first
        self.rect.center = (-100, 100)
        self.dx = 0
        self.dy = 0
        # Allows it to move
        self.toggle = True

    def fire(self, player_pos):
            self.rect.center = player_pos  # Move Bomb to player.
            self.dy = -BOMB_SpeedY              # Set its velocity.

    def fireRight(self, player_pos):
            self.rect.center = player_pos
            # Rotate it to make it look like it's going to the right
            self.image = pygame.transform.rotate(self.image, 345)
            self.dy = -BOMB_SpeedY
            self.dx = BOMB_SpeedX

    def fireLeft(self, player_pos):
            self.rect.center = player_pos
            # Rotate it to make it look like it's going to the left
            self.image = pygame.transform.rotate(self.image, 15)
            self.dy = -BOMB_SpeedY
            self.dx = -BOMB_SpeedX

    def update(self):
        if self.toggle:
            self.rect.centerx += self.dx
            self.rect.centery += self.dy
            # Remove sprite when it's off-screen to save memory
            if self.rect.bottom < 0:
                self.reset()
        else:
            self.rect.centerx -= 0
            self.rect.centery -= 0

    def get_pos(self):
        return self.rect.center

    def reset(self):
        self.kill()

class Enemy(pygame.sprite.Sprite):
    def __init__(self, position, speed):
        pygame.sprite.Sprite.__init__(self)
        # Load img in folder
        self.loadImage()

        self.frame = 0
        self.delay = 3
        self.pause = 0

        self.image = self.imgList[0]
        self.rect = self.image.get_rect()
        self.rect.center = position
        (self.speedX, self.speedY) = speed
        # Allows ship to move
        self.toggle = True

    def loadImage(self):
        self.imgList = []

        for i in range(1, 9) :
            self.image = pygame.image.load(f"assets\sprites\Enemy_animation\{i}.png")
            self.image = self.image.convert()
            self.transColor = self.image.get_at((1,1))
            self.image.set_colorkey(self.transColor)
            self.image = pygame.transform.scale( self.image, (80, 80))
            self.image = pygame.transform.rotate(self.image, 180)
            self.imgList.append(self.image)

    def update(self):
        # This updates the frame of each sprite to simulate animation
        self.pause += 1
        if self.pause >= self.delay:
            self.pause = 0
            self.frame += 1
            if self.frame >= len(self.imgList):
                self.frame = 0
            self.image = self.imgList[self.frame]

        if self.toggle:
            self.rect.center = (self.rect.centerx + self.speedX, self.rect.centery + self.speedY)
            if self.rect.left < 0:
                self.speedX = abs(self.speedX)
            if self.rect.right > WIDTH :
                self.speedX = -1 * abs(self.speedX)
            if self.rect.top < 0:
                self.speedY = abs(self.speedY)
            if self.rect.top > HEIGHT:
                self.rect.bottom = 0
        else :
            self.rect.center = (self.rect.centerx + (self.speedX - self.speedX), self.rect.centery + (self.speedY - self.speedY))

    def reset(self):
        self.kill()

    def get_pos(self):
        return self.rect.center

class Boss(pygame.sprite.Sprite):
    def __init__(self, position, speed):
        # Get image of the whole spritesheet
        pygame.sprite.Sprite.__init__(self)
        self.imgMaster = pygame.image.load("assets\sprites\Royalty-Free-Game-art-Spaceships-from-Unlucky-Studio.png")
        self.imgMaster.convert()
        misImgSize = (237, 230)
        # Create a surface to draw a section of the spritesheet
        self.image = pygame.Surface(misImgSize)
        self.image.blit(self.imgMaster, (0,0), ( (216, 880) ,(misImgSize)) )
        self.image.set_colorkey( self.image.get_at((1,1)))
        self.image = pygame.transform.scale( self.image, (100, 100))
        (self.speedX, self.speedY) = speed
        # Get rect of sprite
        self.rect = self.image.get_rect()
        self.rect.center = position
        # Count hits recieved
        self.hit = 0
        # delay on shots
        self.shoot_delay = 0
        # Allows ship to move
        self.toggle = True

    def update(self):
        if self.toggle:
            # Set a shoot delay. Count to X(30 tick), then reset the timer.
            # The timer is used to tell the program to shoot a enemyMissile from
            # Boss shoots a missile every X amount of seconds.
            # CLOCK_TICK = 1 second
            self.shoot_delay += 1
            if self.shoot_delay > (CLOCK_TICK * 3):
                self.shoot_delay = 0
            # Move it each time update runs. Ex. If CLOCK_TICK = 30,
            # the update runs 30x per second(30FPS)
            self.rect.center = (self.rect.centerx + self.speedX, self.rect.centery + self.speedY)
            if self.rect.left < 0:
                self.speedX = abs(self.speedX)
            if self.rect.right > WIDTH :
                self.speedX = -1 * abs(self.speedX)
            if self.rect.top < 0:
                self.speedY = abs(self.speedY)
            if self.rect.top > HEIGHT:
                self.rect.bottom = 0
        else :
            self.rect.center = (self.rect.centerx + (self.speedX - self.speedX), self.rect.centery + (self.speedY - self.speedY))

    def reset(self):
        self.kill()

    def get_pos(self):
        return self.rect.center

class EnemyMissile(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        # Get image of the whole spritesheet
        self.imgMaster = pygame.image.load("assets\sprites\Royalty-Free-Game-art-Spaceships-from-Unlucky-Studio.png")
        self.imgMaster.convert()
        misImgSize = (45, 77)
        # Create a surface to draw a section of the spritesheet
        self.image = pygame.Surface(misImgSize)
        self.image.blit(self.imgMaster, (0,0), ( (163, 1956) ,(misImgSize)) )
        self.image.set_colorkey( self.image.get_at((1,1)))
        self.image = pygame.transform.scale( self.image, (15, 35) )
        self.image = pygame.transform.rotate(self.image, 180)
        # Get rect of sprite
        self.rect = self.image.get_rect()
        # Place missile off-screen at first
        self.rect.center = (-100, 100)
        self.dx = 0
        self.dy = 0
        # Allows it to move
        self.toggle = True

    def fire(self, enemy_pos):
            # Move Bomb to an enemy
            self.rect.center = enemy_pos
            # Set its velocity to shot it
            self.dy = 10

    def fireRight(self, enemy_pos):
            self.rect.center = enemy_pos
            # Rotate it to make it look like it's going to the right
            self.image = pygame.transform.rotate(self.image, 15)
            self.dy = 10
            self.dx = 5

    def fireLeft(self, enemy_pos):
            self.rect.center = enemy_pos
            # Rotate it to make it look like it's going to the left
            self.image = pygame.transform.rotate(self.image, 345)
            self.dy = 10
            self.dx = -5

    def update(self):
        if self.toggle:
            self.rect.centerx += self.dx
            self.rect.centery += self.dy
            # Remove sprite when it's off-screen to save memory
            if self.rect.top > HEIGHT:
                self.reset()
        else:
            self.rect.centerx += 0
            self.rect.centery += 0

    def get_pos(self):
        return self.rect.center

    def reset(self):
        self.kill()

class Explosion(pygame.sprite.Sprite):
    def __init__(self, position):
        pygame.sprite.Sprite.__init__(self)
        self.imgMaster = pygame.image.load("assets\sprites\Royalty-Free-Game-art-Spaceships-from-Unlucky-Studio.png")
        self.imgMaster.convert()
        misImgSize = (105, 111)
        # Create a surface to draw a section of the spritesheet
        self.image = pygame.Surface(misImgSize)
        self.image.blit(self.imgMaster, (0,0), ( (416, 2530) ,(misImgSize)) )
        self.image.set_colorkey( self.image.get_at((1,1)))
        self.image = pygame.transform.scale( self.image, (50, 50))
        # Get rect of sprite
        self.rect = self.image.get_rect()
        # Place missile off-screen at first
        self.rect.center = position
        self.delay = 0

    def update(self):
        self.delay += 1
        if self.delay == CLOCK_TICK:
            self.kill()

class MultiShotPowerUp(pygame.sprite.Sprite):
    def __init__(self, position, speed):
        pygame.sprite.Sprite.__init__(self)
        # Get image of the whole spritesheet
        self.imgMaster = pygame.image.load("assets\sprites\powerUpSpriteSheet.png")
        self.imgMaster.convert()
        misImgSize = (135, 100)
        # Create a surface to draw a section of the spritesheet
        self.image = pygame.Surface(misImgSize)
        self.image.blit(self.imgMaster, (0,0), ( (656, 37),(misImgSize)) )
        self.image.set_colorkey( self.image.get_at((1,1)))
        self.image = pygame.transform.scale( self.image, (40, 40) )
        self.image = pygame.transform.rotate(self.image, 237)
        # Get rect of sprite
        self.rect = self.image.get_rect()
        # Place missile off-screen at first
        self.rect.center = position
        (self.dx, self.dy) = speed
        # Allows it to move
        self.toggle = True
        # Set what type of powerUp it is
        self.powerUpType = "multiShot"

    def update(self):
        if self.toggle:
            # Move it each time update runs. Ex. If CLOCK_TICK = 30,
            # the update runs 30x per second(30FPS)
            self.rect.center = (self.rect.centerx + self.dx, self.rect.centery + self.dy)
            if self.rect.left < 0:
                self.dx = abs(self.dx)
            if self.rect.right > WIDTH :
                self.dx = -1 * abs(self.dx)
            if self.rect.top < 0:
                self.dy = abs(self.dy)
            # Remove sprite when it's off-screen to save memory
            if self.rect.top > HEIGHT:
                self.reset()
        else:
            self.rect.centerx += 0
            self.rect.centery += 0

    def get_pos(self):
        return self.rect.center

    def reset(self):
        self.kill()

class SpeedPowerUp(pygame.sprite.Sprite):
    def __init__(self, position, speed):
        pygame.sprite.Sprite.__init__(self)
        # Get image of the whole spritesheet
        self.imgMaster = pygame.image.load("assets\sprites\powerUpSpriteSheet.png")
        self.imgMaster.convert()
        misImgSize = (131, 125)
        # Create a surface to draw a section of the spritesheet
        self.image = pygame.Surface(misImgSize)
        self.image.blit(self.imgMaster, (0,0), ( (0, 37),(misImgSize)) )
        self.image.set_colorkey( self.image.get_at((1,1)))
        self.image = pygame.transform.scale( self.image, (40, 40) )
        # Get rect of sprite
        self.rect = self.image.get_rect()
        # Place missile off-screen at first
        self.rect.center = position
        (self.dx, self.dy) = speed
        # Allows it to move
        self.toggle = True
        # Set what type of powerUp it is
        self.powerUpType = "speedBoost"

    def update(self):
        if self.toggle:
            # Move it each time update runs. Ex. If CLOCK_TICK = 30,
            # the update runs 30x per second(30FPS)
            self.rect.center = (self.rect.centerx + self.dx, self.rect.centery + self.dy)
            if self.rect.left < 0:
                self.dx = abs(self.dx)
            if self.rect.right > WIDTH :
                self.dx = -1 * abs(self.dx)
            if self.rect.top < 0:
                self.dy = abs(self.dy)
            # Remove sprite when it's off-screen to save memory
            if self.rect.top > HEIGHT:
                self.reset()
        else:
            self.rect.centerx += 0
            self.rect.centery += 0

    def get_pos(self):
        return self.rect.center

    def reset(self):
        self.kill()

class Label(pygame.sprite.Sprite):
    def __init__(self, textStr, center, fontName, fontSize, textColor):
        pygame.sprite.Sprite.__init__(self)
        self.text = textStr
        self.center = center
        self.font = pygame.font.Font(fontName, fontSize)
        self.textColor = textColor
    # self.update() - Render the text on the label and any changes to it.
    def update(self):
        self.image = self.font.render(self.text, 1, self.textColor)
        self.rect = self.image.get_rect()
        self.rect.center = self.center

def titleScreen():
    # Construct a background
    background = pygame.image.load("assets\\background\Space_Parallax.png")
    # Convert for better preformance
    background = background.convert()
    background = pygame.transform.scale(background, screen.get_size())
    # screen.blit(background, (0, 0))
    moveY = 0
    # Construct labels for title, objective and controls.
    # It stays until user proceeds or quits game.
    # Adding them to a group is one step needs to update any changes made to them and collision detection
    title = Label("Space Defenders!", ( (WIDTH//2), (HEIGHT//2) ), defaultFont, 25, WHITE)
    goal = Label("Fight off alien ships as long as possible to gain the highest score!", ( (WIDTH//2), ((HEIGHT//2) + 30) ), defaultFont, 23, WHITE)
    instr = Label("Move using arrow keys and use spacebar to shoot", ( (WIDTH//2), (HEIGHT//2) + 60), defaultFont, 25, WHITE)
    startGametxt = Label("Click to start!", ( (WIDTH//2), (HEIGHT//2) + 90), defaultFont, 25, WHITE)
    labelGroup = pygame.sprite.Group(title, goal, instr, startGametxt)
    # Set FPS of the game
    clock = pygame.time.Clock()
    # Set a loop that keeps running until user quits or proceeds
    keepGoing = True
    while keepGoing:
        # Set FPS of the game - 30 frames per second/tick
        clock.tick(CLOCK_TICK)
        # Create Scrolling background
        rel_moveY = moveY % background.get_rect().height
        screen.blit(background, (0, rel_moveY - background.get_rect().height))
        if rel_moveY < HEIGHT:
            screen.blit(background, (0, rel_moveY))
        moveY += 1
        # Handle any events
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                keepGoing = False
            if event.type == pygame.MOUSEBUTTONDOWN:
                keepGoing = False
        # Update the display
        labelGroup.update()
        # Draw the display
        labelGroup.draw(screen)
        # Put it to the screen
        pygame.display.flip()

def game():
    # Construct a background
    background = pygame.image.load("assets\\background\Space_Parallax.png")
    # Convert for better preformance
    background = background.convert()
    background = pygame.transform.scale(background, screen.get_size())
    # screen.blit(background, (0, 0))
    moveY = 0
    # Play music when game starts
    pygame.mixer.music.load("assets\sounds\POL-galactic-trek-short.wav")
    pygame.mixer.music.play(-1) # play continuously
    # Set volume, scaled from 0 to 1
    pygame.mixer.music.set_volume(0.1)
    # Create a necessary objects
    player = Player()
    explodeSound = pygame.mixer.Sound("assets\sounds\\16-bit-explosion_120bpm_C_major.wav")
    tickCount = 0
    highScore = 0
    level = 0
    highScoreLabel = Label(f"Highscore: {highScore}", (100, 50), defaultFont, 25, WHITE)
    levelLabel = Label(f"Level: {level}", ((WIDTH - 100), 50), defaultFont, 25, WHITE)
    pausedLabel = Label(f"", ((WIDTH//2), (HEIGHT//2)), defaultFont, 65, WHITE)
    # Add them to groups
    playerGroup = pygame.sprite.Group(player)
    missileGroup = pygame.sprite.Group()
    powerUpGroup = pygame.sprite.Group()
    enemyGroup = pygame.sprite.Group()
    enemyMissileGroup = pygame.sprite.Group()
    bossGroup = pygame.sprite.Group()
    allEnemyGroup = pygame.sprite.Group(enemyGroup, bossGroup)
    labelGroup = pygame.sprite.Group(highScoreLabel, levelLabel, pausedLabel)
    # - a variable that tells if the user won
    win = False
    # Pause
    pause = False
    # - Set FPS of the game
    clock = pygame.time.Clock()
    #  - Set a loop that keeps running until user quits or proceeds
    keepGoing = True
    while keepGoing:
        # Set FPS of the game - 30 frames per second/tick
        clock.tick(CLOCK_TICK)
        # Every 30 ticks is a second
        tickCount += 1
        # Create Scrolling background
        rel_moveY = moveY % background.get_rect().height
        screen.blit(background, (0, rel_moveY - background.get_rect().height))
        if rel_moveY < HEIGHT:
            screen.blit(background, (0, rel_moveY))
        moveY += 1
        # Set a var that will be a rand interger from X to X
        powerUpChance = randint(1, 100)
        # If it "powerUpChance" is X, spawn it. This will it a X% spawn rate
        if powerUpChance == 1 and pause == False :
            positionX = randint( 0, WIDTH)
            positionY = randint( 0, 50 )
            speedX = randint(3, 5)
            speedY = randint(3, 5)
            multiShotPowerUp = MultiShotPowerUp((positionX, positionY), (speedX, speedY))
            powerUpGroup.add(multiShotPowerUp)

        if powerUpChance == 1 and pause == False :
            positionX = randint( 0, WIDTH)
            positionY = randint( 0, 50 )
            speedX = randint(3, 5)
            speedY = randint(3, 5)
            speedPowerUp = SpeedPowerUp((positionX, positionY), (speedX, speedY))
            powerUpGroup.add(speedPowerUp)

        # Create New list of enemy for each level
        if len(enemyGroup) == 0 and len(bossGroup) == 0:
            level += 1
            levelLabel.text = f"Level: {level}"
            # Every 15 lvls, spawn 2 bosses
            if level % 15 == 0:
                for i in range(2):
                    positionX = randint( 0, WIDTH)
                    positionY = randint( 20, 50 )
                    speedX = random.choice([-10, 10])
                    speedY = 0
                    boss = Boss((positionX, positionY), (speedX, speedY))
                    bossGroup.add(boss)
            elif level % 5 == 0:
                positionX = randint( 0, WIDTH)
                positionY = randint( 20, 50 )
                speedX = random.choice([-10, 10])
                speedY = 0
                boss = Boss((positionX, positionY), (speedX, speedY))
                bossGroup.add(boss)
            else :
                for i in range(ENEMYAMOUNT):
                    positionX = randint( 0, WIDTH)
                    positionY = randint( -20, 0 )
                    speedX = randint(-ENEMYSPEED, ENEMYSPEED)
                    speedY = randint(3, ENEMYSPEED)
                    eachEnemy = Enemy((positionX, positionY), (speedX, speedY))
                    enemyGroup.add(eachEnemy)
        # Pause everything in the game. Game is paused if "paused == True", otherwise run.
        # Also put "paused" text in the middle of screen when "paused == True"
        if pause == True:
            pausedLabel.text = f"Paused"
            player.toggle = False
            for eachPowerUp in powerUpGroup:
                eachPowerUp.toggle = False
            for eachEnemy in enemyGroup:
                eachEnemy.toggle = False
            for eachBoss in bossGroup:
                eachBoss.toggle = False
            for missile in missileGroup:
                missile.toggle = False
            for enemyMissile in enemyMissileGroup:
                enemyMissile.toggle = False
        else:
            pausedLabel.text = f""
            player.toggle = True
            for eachPowerUp in powerUpGroup:
                eachPowerUp.toggle = True
            for eachEnemy in enemyGroup:
                eachEnemy.toggle = True
            for eachBoss in bossGroup:
                eachBoss.toggle = True
            for missile in missileGroup:
                missile.toggle = True
            for enemyMissile in enemyMissileGroup:
                enemyMissile.toggle = True
        # Handle any events
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                keepGoing = False
            if event.type == pygame.KEYDOWN:
                # Space-bar shoots missile
                # If player gets power up, shoot 3 missiles!
                if event.key == pygame.K_SPACE and pause == False and player.multiShot == True:
                    # 1st missile
                    missile = Missile()
                    missileGroup.add(missile)
                    missile.fire(player.get_pos())
                    # 2nd missile
                    missile2 = Missile()
                    missileGroup.add(missile2)
                    missile2.fireRight(player.get_pos())
                    # 3rd missile
                    missile3 = Missile()
                    missileGroup.add(missile3)
                    missile3.fireLeft(player.get_pos())
                elif event.key == pygame.K_SPACE and pause == False:
                    missile = Missile()
                    missileGroup.add(missile)
                    missile.fire(player.get_pos())
                # "P" pauses the game
                if event.key == pygame.K_p and pause == False:
                    pause = True
                elif event.key == pygame.K_p and pause == True:
                    pause = False
        #### Check collisions or any other actions
        # Make a list of enemies, adding them into it when they collide with a missile
        deadEnemy = []
        resetMisList = []

        for eachEnemy in enemyGroup:
            tickCounts = randint(1, 100)
            if tickCounts == 1 and eachEnemy.toggle == True:
                enemyMissile = EnemyMissile()
                enemyMissileGroup.add(enemyMissile)
                enemyMissile.fire(eachEnemy.get_pos())

            if pygame.sprite.spritecollide(eachEnemy, missileGroup, False):
                highScore += 25
                highScoreLabel.text = f"Highscore: {highScore}"
                explodeSound.play()
                explosion = Explosion(eachEnemy.get_pos())
                labelGroup.add(explosion)
                deadEnemy.append(eachEnemy)

        for eachBoss in bossGroup:
            if eachBoss.shoot_delay == 30 and eachEnemy.toggle == True:
                enemyMissile = EnemyMissile()
                enemyMissileGroup.add(enemyMissile)
                enemyMissile.fire(eachBoss.get_pos())
                # Second missile that shoots at an angle
                enemyMissile2 = EnemyMissile()
                enemyMissileGroup.add(enemyMissile2)
                enemyMissile2.fireRight(eachBoss.get_pos())
                # Third missile that shoots at an angle
                enemyMissile3 = EnemyMissile()
                enemyMissileGroup.add(enemyMissile3)
                enemyMissile3.fireLeft(eachBoss.get_pos())

            if pygame.sprite.spritecollide(eachBoss, missileGroup, False):
                eachBoss.hit += 1
                explodeSound.play()
                # If hit X amount of times... add it to add deadEnemy so it can be deleted
                if eachBoss.hit == 20:
                    highScore += 750
                    highScoreLabel.text = f"Highscore: {highScore}"
                    explodeSound.play()
                    explosion = Explosion(eachBoss.get_pos())
                    labelGroup.add(explosion)
                    deadEnemy.append(eachBoss)

        for missile in missileGroup:
            if pygame.sprite.spritecollide(missile, enemyGroup, False) :
                explodeSound.play()
                resetMisList.append(missile)

        for eachPowerUp in powerUpGroup:
            if pygame.sprite.spritecollide(eachPowerUp, playerGroup, False) :
                if eachPowerUp.powerUpType == "multiShot" :
                    # Player hits a power up, allow it to shoot multiple missiles
                    # Set the multishot timer to 0 if the player gets a power up while already
                    # powered up
                    player.multiShot = True
                    player.multiShotTimer = 0
                    eachPowerUp.reset()

                elif eachPowerUp.powerUpType == "speedBoost" :
                    # Player hits this power up, get speed boost
                    # Set the multishot timer to 0 if the player gets a power up while already
                    # powered up
                    player.speedBoost = True
                    player.speedBoostTimer = 0
                    eachPowerUp.reset()
        # Then remove enemy from group
        # If enemy was removed too soon. The the loop above wouldn't detech any collisions
        for eachEnemy in deadEnemy:
            eachEnemy.reset()
        # Then remove missile from group
        for eachMis in resetMisList:
            eachMis.reset()
        # End game if player collides with an enemy
        if pygame.sprite.spritecollide(player, enemyGroup, True) :
            keepGoing = False
        # End game if player collides with an enemy's missile
        if pygame.sprite.spritecollide(player, enemyMissileGroup, True) :
            keepGoing = False
        # Player wins if they get to lvl X
        if level == 50:
            keepGoing = False
            win = True
        # Update and draw/render all the groups
        playerGroup.update()
        missileGroup.update()
        powerUpGroup.update()
        enemyGroup.update()
        enemyMissileGroup.update()
        bossGroup.update()
        allEnemyGroup.update()
        labelGroup.update()

        playerGroup.draw(screen)
        missileGroup.draw(screen)
        powerUpGroup.draw(screen)
        enemyGroup.draw(screen)
        enemyMissileGroup.draw(screen)
        bossGroup.draw(screen)
        allEnemyGroup.draw(screen)
        labelGroup.draw(screen)

        pygame.display.flip()

    return (win, highScore)

def playAgain(winLose):
    # Construct a background
    background = pygame.Surface(screen.get_size())
    # Convert for better preformance
    background = background.convert()
    # Set background color
    background.fill( (0, 0, 0) )
    screen.blit(background, (0, 0))

    # Get from variable "game()" and check if it's true or false.
    # winLose = True, user won.  winLose = False, user lost.
    winOrLose = winLose[0]
    highScore = winLose[1]

    if winOrLose == True :
        gameResult = Label("You Won!", ( (WIDTH//2), (HEIGHT//2)), defaultFont, 25, BLUE)
        highScoreTxt = Label(f"Highscore: {highScore}", ( (WIDTH//2), (HEIGHT//2) + 30), defaultFont, 25, BLUE)
        playAgainTxt = Label("Play again(Y/N)", ( (WIDTH//2), (HEIGHT//2) + 60), defaultFont, 25, BLUE)
    else:
        gameResult = Label("You Lost!", ( (WIDTH//2), (HEIGHT//2)), defaultFont, 25, RED)
        highScoreTxt= Label(f"Highscore: {highScore}", ( (WIDTH//2), (HEIGHT//2) + 30), defaultFont, 25, RED)
        playAgainTxt= Label("Play again(Y/N)", ( (WIDTH//2), (HEIGHT//2) + 60), defaultFont, 25, RED)

    labelGroup = pygame.sprite.Group(gameResult, playAgainTxt, highScoreTxt)

    replay = False
    # Set FPS of the game
    clock = pygame.time.Clock()
    # Set a loop that keeps running until user quits or proceeds
    keepGoing = True
    while keepGoing:
        # Set FPS of the game - 30 frames per second/tick
        clock.tick(CLOCK_TICK)
        # Handle any events
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                keepGoing = False
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_y:
                    keepGoing = False
                    replay = True
                if event.key == pygame.K_n:
                    keepGoing = False
                    replay = False
                if event.key == pygame.K_q:
                    keepGoing = False
                    replay = False
                    sys.exit()

        labelGroup.clear(screen, background)

        labelGroup.update()

        labelGroup.draw(screen)

        pygame.display.flip()

    return replay

def endCredits():
    # Construct a background
    background = pygame.Surface(screen.get_size())
    # Convert for better preformance
    background = background.convert()
    # Set background color
    background.fill( (0, 0, 0) )
    screen.blit(background, (0, 0))

    endCreditsTxt1 = Label("I hope you enjoyed playing!", ( (WIDTH//2), (HEIGHT//2)), defaultFont, 25, WHITE)
    endCreditsTxt2 = Label("By Daeshaun Morrison", ( (WIDTH//2), (HEIGHT//2) + 30), defaultFont, 25, WHITE)

    labelGroup = pygame.sprite.Group(endCreditsTxt1, endCreditsTxt2)

    # Set FPS of the game
    clock = pygame.time.Clock()
    # Set a loop that runs for a set amount of secounds, 5 in this case.
    keepGoing = True
    frames = 0

    while keepGoing == True:
        clock.tick(CLOCK_TICK)

        frames = frames + 1
        if frames == 150:
            keepGoing = False

        labelGroup.clear(screen, background)

        labelGroup.update()

        labelGroup.draw(screen)

        pygame.display.flip()

def main():
    #####
    titleScreen()

    replay = True
    while replay == True:
      result = game()
      replay = playAgain(result)

    endCredits()

main()
pygame.quit()


from django.contrib import admin, messages
from django.http import HttpResponse
from django.utils.text import slugify

from .tito import export_participants_to_csv
from .models import Batch, Participant

@admin.register(Participant)
class ParticipantAdmin(admin.ModelAdmin):
    list_display = ['pk', 'first_name', 'last_name', 'email', 'ticket_type', 'batch', 'created_at']
    list_display_links = ['pk', 'first_name', 'last_name', 'email']
    list_filter = ['ticket_type', 'batch']
    search_fields = ['first_name', 'last_name', 'email']
    readonly_fields = ['created_at']

@admin.register(Batch)
class BatchAdmin(admin.ModelAdmin):
    list_display = ['pk', 'name', 'tickets', 'assigned_at', 'created_at']
    list_display_links = ['pk', 'name']
    readonly_fields = ['created_at', 'assigned_at']
    actions = ['assign_participants', 'export_to_csv']

    def assign_participants(self, request, queryset):
        if len(queryset) != 1 or queryset[0].assigned:
            msg = 'Action available only for one, unassigned Batch'
            self.message_user(request, msg, level=messages.ERROR)
            return

        batch = queryset[0]
        assigned_participants = batch.assign_participants()

        msg = '%d participants assigned to %s' % (assigned_participants, batch)
        level = messages.SUCCESS if assigned_participants == batch.tickets else messages.WARNING
        self.message_user(request, msg, level=level)

    def export_to_csv(self, request, queryset):
        if len(queryset) != 1 or not queryset[0].assigned:
            msg = 'Action available only for one, assigned Batch'
            self.message_user(request, msg, level=messages.ERROR)
            return

        batch = queryset[0]
        participants = batch.participants.order_by('email')
        csv = export_participants_to_csv(participants)

        response = HttpResponse(csv, content_type='text/csv')
        response['Content-Disposition'] = 'attachment; filename="%s.csv"' % slugify(batch)
        return response


from scrapy import Request,Spider
from ..items import _1919Item
from pymongo import MongoClient
from scrapy.exceptions import CloseSpider
import logging

logger = logging.getLogger(__name__)

class DetailSpider(Spider):
    name = 'detail_spider'
    start_urls = []

    def __init__(self):
        conn = MongoClient(host='114.112.107.58', port=27017)
        db = conn['_1919']
        self.col = db['detail_urls']

    def start_requests(self):
        cursor = self.col.find({},no_cursor_timeout=True).batch_size(10)
        for data in cursor:
            if data:
                yield Request(url=data['detail_url'],callback=self.parse_detail)

    def parse_detail(self, response):
        if not response.status == 200:
            logger.info("http error!!!")
            raise CloseSpider
        if response.status == 400:
            logger.info("抓取失败！！！")
            raise CloseSpider
        item = _1919Item()
        item['price'] = response.xpath('//em[@class="details-pri"]/text()').extract_first(default=None)
        item['name'] = response.xpath('//div[@class="pcc-title"]/h1/text()').extract_first().replace('\t','')
        shop = {}
        shop['name'] = response.xpath('//div[@class="product-cr-title"]/h1/text()').extract_first().replace('""','')
        shop['url'] = response.xpath('//div[@class="product-cr-adLogo"]/a/@href').extract_first()
        if shop:
            item['shop'] = shop
        else:
            item['shop'] = {}
        category = response.xpath('//div[@class="dGuide"]//text()').extract()
        category = ''.join(category)
        if category:
            item['category'] = category.replace('\n', '').replace('\t', '').replace(' ', '')
        item['source_url'] = response.url
        images = []
        datas = response.xpath('//div[@id="imageMenu"]/ul/li')
        for data in datas:
            img_json = {}
            img_json['url'] = data.xpath('img/@src').extract_first()
            img_json['md5'] = '********************************'
            images.append(img_json)
        item['images'] = images
        detail_list = []
        for data in response.xpath('//div[@class="intro-cont com-size"]'):
            str = data.xpath('span//text()').extract()
            detail = {}
            detail['key'] = str[0].replace('：', '')
            detail['value'] = str[-1]
            detail_list.append(detail)
        if detail_list:
            item['detail'] = detail_list
        else:
            item['detail'] = []
        print(item)
        yield item


# 모델 불러오기
# pip install tensorflow==2.9.1
from PIL import Image
import os, glob, numpy as np
import tensorflow as tf
import joblib
from tensorflow.python.keras.models import load_model, model_from_json

# model.json 파일 열기
class Cnn_Model():
    cnt = 0
    def __init__(self,img_path):
        # 객체를 여러번 불러올 필요는 없으므로 최초에 한번 만들 놓겠음
        if Cnn_Model.cnt == 0:
            json_file = open("static/saved_models/catdog_model.json", "r")
            loaded_model_json = json_file.read()
            json_file.close()
            # json파일로부터 model 로드하기
            Cnn_Model.loaded_model = model_from_json(loaded_model_json)
            # 로드한 model에 weight 로드하기
            Cnn_Model.loaded_model.load_weights("static/saved_models/model.h5")
            print("Loaded model from disk")
            Cnn_Model.loaded_model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
            Cnn_Model.categories = joblib.load("static/saved_models/categories.pkl")
            Cnn_Model.cnt += 1
        self.origindir = img_path

    def cnn_model(self):
        x_test = []
        img = Image.open(self.origindir)
        img = img.convert("RGB")
        img = img.resize((64, 64))
        data = np.asarray(img)
        x_test.append(data)
        X = np.array(x_test)
        X = X.astype(float) / 255
        prediction = Cnn_Model.loaded_model.predict(X)
        pp = np.argmax(prediction)
        category = Cnn_Model.categories[pp]
        return category