import argparse
import dataio
import torch
import random
import textwrap

def predict(model_type, model, batch, max_steps, set_rs=None):
    if model_type == "seq2seq_rnn":
        return model.greedy_predict(
            batch.encoder_inputs, batch.encoder_input_length,
            max_steps=max_steps)
    elif model_type == "seq2seq_rnn_rs":
        rs = batch.decoder_inputs[1].data[:,0]
        if set_rs is not None:
            rs.fill_(set_rs)

        return model.greedy_predict(
            batch.encoder_inputs, batch.encoder_input_length,
            max_steps=max_steps,
            extra_inputs=rs)
    elif model_type == "seq2seq_rnn_ts":
        ts = batch.decoder_inputs[1].data[:,0]
        if set_rs is not None:
            ts.fill_(set_rs)

        return model.greedy_predict(
            batch.encoder_inputs, batch.encoder_input_length,
            max_steps=max_steps,
            extra_inputs=ts)

    else:
        raise Exception("Bad model type: {}".format(model_type))

if __name__ == "__main__":
    parser = argparse.ArgumentParser("Eval seq2seq.")

    parser.add_argument("--data", required=True)

    parser.add_argument("--model", required=True)
    parser.add_argument("--max-steps", required=False, default=100, type=int)

    parser.add_argument("--gpu", default=-1, type=int, required=False)
    parser.add_argument("--batch-size", required=False, type=int, default=4)
    parser.add_argument("--set-rs", default=None, required=False, type=int)

    args = parser.parse_args()

#    random.seed(args.seed)
#    torch.manual_seed(args.seed)
    model = torch.load(args.model, map_location=lambda storage, loc: storage)

    vocab_src = model.get_meta("encoder_vocab")
    vocab_tgt = model.get_meta("decoder_vocab")

    model_type = model.get_meta("model_type")

    if model_type == "seq2seq_rnn":
        data = dataio.read_seq2seq_dataset(
            args.data, 0, vocab_src, 1, vocab_tgt,
            skip_header=True, batch_size=args.batch_size, gpu=args.gpu)
    elif model_type == "seq2seq_rnn_rs":
        data = dataio.read_seq2seq_rs_dataset(
            args.data, 0, vocab_src, 1, vocab_tgt,
            max_steps=model.get_meta("max_steps"), skip_header=True,
            batch_size=args.batch_size, gpu=args.gpu)
    elif model_type == "seq2seq_rnn_ts":
        data = dataio.read_seq2seq_ts_dataset(
            args.data, 0, vocab_src, 1, vocab_tgt,
            max_steps=model.get_meta("max_steps"), skip_header=True,
            batch_size=args.batch_size, gpu=args.gpu)

    if args.gpu > -1:
        #with torch.cuda.device(args.gpu):
            #torch.cuda.manual_seed(args.seed)
        model.cuda(args.gpu)

    model.eval()

    import random
    random.seed(34535)

    for batch in data.iter_batch():
        inputs = vocab_src.inv_lookup_matrix(batch.encoder_inputs[0].data)
        targets = vocab_tgt.inv_lookup_matrix(batch.target.data)
#        predictions = predict(
#            model_type, model, batch, max_steps=args.max_steps,
#            set_rs=args.set_rs)
#        predicted_targets = vocab_tgt.inv_lookup_matrix(predictions)

        beam_size = 64
        if model.get_meta("model_type") == "seq2seq_rnn":
            batch_beam_predictions = model.beam_search(
                batch.encoder_inputs, batch.encoder_input_length, beam_size=beam_size)
        else:
            batch_size = batch.target.size(0)
            rs = batch.decoder_inputs[1].data.new(batch_size * beam_size)

            for b in range(batch_size):
                #rs[b * beam_size: (b+1) * beam_size].fill_(batch.decoder_inputs[1].data[b,0])
                rs[b * beam_size: (b+1) * beam_size].fill_(args.set_rs)

            batch_beam_predictions = model.beam_search(
                batch.encoder_inputs, batch.encoder_input_length, extra_inputs=rs, beam_size=beam_size)

        print("")
        for i, input_tokens in enumerate(inputs):
            input_string = "           input: {}".format(
                " ".join(input_tokens))

            print(textwrap.fill(input_string, subsequent_indent=" " * 18))
            expected_string = " expected output: {}".format(
                " ".join(targets[i]))
            print(textwrap.fill(expected_string, subsequent_indent=" " * 18))
            #predicted_string = "predicted output: {}".format(
            #    " ".join(predicted_targets[i]))
            #print(textwrap.fill(predicted_string, subsequent_indent=" " * 18))
            #print("")
            beam_predictions = batch_beam_predictions[i]

            for score, beam_prediction in beam_predictions[:10]:
                if score == float("-inf"): continue
                print(score)
                print(beam_prediction)

            #attention = predictions.attention[i]
            #attention_vals, attention_idxs = torch.sort(attention, 1, True)
            x = input()

#            if x == "p":
#                for j, token in enumerate(predicted_targets[i]):
#                    print(predicted_targets[i][:j+1])
#                    for k in range(3):
#                        if attention_vals[j,k] == 0:
#                            break
#                        weight = attention_vals[j,k]
#                        index = attention_idxs[j,k]
#
#                        print(weight, index, input_tokens[index])
#                    print("")
#
#                input()


import sys

import folium
import joblib
import numpy as np
import tensorflow as tf
from matplotlib import pyplot as plt
from sklearn.metrics.pairwise import polynomial_kernel
from tqdm import tqdm

from lstmwgan import WGANGP
from preprocessing.utils import decodeTrajectories

latent_dim = 100
n_epochs = 30
n_samples = 100

if __name__ == '__main__':
    real_trajectories = np.load('data/preprocessed/train_gl.npy', allow_pickle=True)
    real_trajectories = real_trajectories[:n_samples]
    gen_inputs = []
    random_latent_vectors = noise = tf.random.normal((tf.shape(real_trajectories)[0], latent_dim), 0, 1)
    gen_inputs.append(real_trajectories)
    gen_inputs.append(random_latent_vectors)
    gan = WGANGP()
    gan.generator.load_weights('parameters/G_model_gl_' + str(n_epochs) + '.h5')  # params/G_model_100.h5
    generated_trajectories = gan.generator(gen_inputs).numpy()
    scaler = joblib.load("preprocessing/scaler.pkl")
    gen_lat, gen_lng = decodeTrajectories(generated_trajectories, scaler)
    points = list(zip(gen_lat, gen_lng))
    # my_map = folium.Map(location=[46.3615142, 6.399388], zoom_start=10)
    my_map = folium.Map(location=[39.9075, 116.39723], zoom_start=14)
    folium.PolyLine(points, color="red", weight=2.5, opacity=1).add_to(my_map)
    my_map.save(f"MDC_gen.html")
    print("Plot created")

    # -----------------HEATMAP-------------------
    xLabel = "Longitude"
    yLabel = "Latitude"
    real_lat, real_lng = decodeTrajectories(real_trajectories, scaler)
    heatmap, xedges, yedges = np.histogram2d(gen_lng, gen_lat, bins=20)
    heatmap2, xedges2, yedges2 = np.histogram2d(real_lng, real_lat, bins=20)

    extent = [0, 50, 0, 50]
    fig, (ax1, ax2) = plt.subplots(ncols=2)
    im1 = ax1.imshow(heatmap.T, extent=extent, origin='lower')
    im2 = ax2.imshow(heatmap2.T, extent=extent, origin='lower')
    plt.show()

    # -----------------MMD-------------------
    """
    def compute_kernel(x, y):
        x_size = tf.shape(x)[0]
        y_size = tf.shape(y)[0]
        dim = tf.shape(x)[1]
        tiled_x = tf.tile(tf.reshape(x, tf.stack([x_size, 1, dim])), tf.stack([1, y_size, 1]))
        tiled_y = tf.tile(tf.reshape(y, tf.stack([1, y_size, dim])), tf.stack([x_size, 1, 1]))
        return tf.exp(-tf.reduce_mean(tf.square(tiled_x - tiled_y), axis=2) / tf.cast(dim, tf.float32))

    def compute_mmd(x, y):  # [batch_size, z_dim] [batch_size, z_dim]
        x_kernel = compute_kernel(x, x)
        y_kernel = compute_kernel(y, y)
        xy_kernel = compute_kernel(x, y)
        return tf.reduce_mean(x_kernel) + tf.reduce_mean(y_kernel) - 2 * tf.reduce_mean(xy_kernel)

    real_trajectories = np.float32(real_trajectories)
    mmds = []
    for index in range(0, n_samples):
        mmd = compute_mmd(real_trajectories[index], generated_trajectories[index])
        mmds.append(mmd.numpy())
    mean_mmd = np.mean(mmds)
    print(mean_mmd)
"""

    def polynomial_mmd_averages(codes_g, codes_r, n_subsets=50, subset_size=1000,
                                ret_var=True, output=sys.stdout, **kernel_args):
        m = min(codes_g.shape[0], codes_r.shape[0])
        mmds = np.zeros(n_subsets)
        if ret_var:
            vars = np.zeros(n_subsets)
        choice = np.random.choice

        with tqdm(range(n_subsets), desc='MMD', file=output) as bar:
            for i in bar:
                g = codes_g[choice(len(codes_g), subset_size, replace=False)]
                r = codes_r[choice(len(codes_r), subset_size, replace=False)]
                o = polynomial_mmd(g, r, **kernel_args, var_at_m=m, ret_var=ret_var)
                if ret_var:
                    mmds[i], vars[i] = o
                else:
                    mmds[i] = o
                bar.set_postfix({'mean': mmds[:i + 1].mean()})
        return (mmds, vars) if ret_var else mmds

    def polynomial_mmd(codes_g, codes_r, degree=3, gamma=None, coef0=1,
                       var_at_m=None, ret_var=True):
        # use  k(x, y) = (gamma <x, y> + coef0)^degree
        # default gamma is 1 / dim
        X = codes_g
        Y = codes_r

        K_XX = polynomial_kernel(X, degree=degree, gamma=gamma, coef0=coef0)
        K_YY = polynomial_kernel(Y, degree=degree, gamma=gamma, coef0=coef0)
        K_XY = polynomial_kernel(X, Y, degree=degree, gamma=gamma, coef0=coef0)

        return _mmd2_and_variance(K_XX, K_XY, K_YY,
                                  var_at_m=var_at_m, ret_var=ret_var)

    def _sqn(arr):
        flat = np.ravel(arr)
        return flat.dot(flat)

    def _mmd2_and_variance(K_XX, K_XY, K_YY, unit_diagonal=False,
                           mmd_est='unbiased', block_size=1024,
                           var_at_m=None, ret_var=True):
        # based on
        # https://github.com/dougalsutherland/opt-mmd/blob/master/two_sample/mmd.py
        # but changed to not compute the full kernel matrix at once
        m = K_XX.shape[0]
        assert K_XX.shape == (m, m)
        assert K_XY.shape == (m, m)
        assert K_YY.shape == (m, m)
        if var_at_m is None:
            var_at_m = m

        # Get the various sums of kernels that we'll use
        # Kts drop the diagonal, but we don't need to compute them explicitly
        if unit_diagonal:
            diag_X = diag_Y = 1
            sum_diag_X = sum_diag_Y = m
            sum_diag2_X = sum_diag2_Y = m
        else:
            diag_X = np.diagonal(K_XX)
            diag_Y = np.diagonal(K_YY)

            sum_diag_X = diag_X.sum()
            sum_diag_Y = diag_Y.sum()

            sum_diag2_X = _sqn(diag_X)
            sum_diag2_Y = _sqn(diag_Y)

        Kt_XX_sums = K_XX.sum(axis=1) - diag_X
        Kt_YY_sums = K_YY.sum(axis=1) - diag_Y
        K_XY_sums_0 = K_XY.sum(axis=0)
        K_XY_sums_1 = K_XY.sum(axis=1)

        Kt_XX_sum = Kt_XX_sums.sum()
        Kt_YY_sum = Kt_YY_sums.sum()
        K_XY_sum = K_XY_sums_0.sum()

        if mmd_est == 'biased':
            mmd2 = ((Kt_XX_sum + sum_diag_X) / (m * m)
                    + (Kt_YY_sum + sum_diag_Y) / (m * m)
                    - 2 * K_XY_sum / (m * m))
        else:
            assert mmd_est in {'unbiased', 'u-statistic'}
            mmd2 = (Kt_XX_sum + Kt_YY_sum) / (m * (m - 1))
            if mmd_est == 'unbiased':
                mmd2 -= 2 * K_XY_sum / (m * m)
            else:
                mmd2 -= 2 * (K_XY_sum - np.trace(K_XY)) / (m * (m - 1))

        if not ret_var:
            return mmd2

        Kt_XX_2_sum = _sqn(K_XX) - sum_diag2_X
        Kt_YY_2_sum = _sqn(K_YY) - sum_diag2_Y
        K_XY_2_sum = _sqn(K_XY)

        dot_XX_XY = Kt_XX_sums.dot(K_XY_sums_1)
        dot_YY_YX = Kt_YY_sums.dot(K_XY_sums_0)

        m1 = m - 1
        m2 = m - 2
        zeta1_est = (
                1 / (m * m1 * m2) * (
                _sqn(Kt_XX_sums) - Kt_XX_2_sum + _sqn(Kt_YY_sums) - Kt_YY_2_sum)
                - 1 / (m * m1) ** 2 * (Kt_XX_sum ** 2 + Kt_YY_sum ** 2)
                + 1 / (m * m * m1) * (
                        _sqn(K_XY_sums_1) + _sqn(K_XY_sums_0) - 2 * K_XY_2_sum)
                - 2 / m ** 4 * K_XY_sum ** 2
                - 2 / (m * m * m1) * (dot_XX_XY + dot_YY_YX)
                + 2 / (m ** 3 * m1) * (Kt_XX_sum + Kt_YY_sum) * K_XY_sum
        )
        zeta2_est = (
                1 / (m * m1) * (Kt_XX_2_sum + Kt_YY_2_sum)
                - 1 / (m * m1) ** 2 * (Kt_XX_sum ** 2 + Kt_YY_sum ** 2)
                + 2 / (m * m) * K_XY_2_sum
                - 2 / m ** 4 * K_XY_sum ** 2
                - 4 / (m * m * m1) * (dot_XX_XY + dot_YY_YX)
                + 4 / (m ** 3 * m1) * (Kt_XX_sum + Kt_YY_sum) * K_XY_sum
        )
        var_est = (4 * (var_at_m - 2) / (var_at_m * (var_at_m - 1)) * zeta1_est
                   + 2 / (var_at_m * (var_at_m - 1)) * zeta2_est)

        return mmd2, var_est

    output = {}
    generated_trajectories = np.reshape(generated_trajectories,
                                        [generated_trajectories.shape[0], generated_trajectories.shape[1]])
    real_trajectories = np.reshape(real_trajectories,
                                   [real_trajectories.shape[0], real_trajectories.shape[1]])
    ret = polynomial_mmd_averages(
        generated_trajectories, real_trajectories, degree=3, gamma=None,
        coef0=1, ret_var=False,
        n_subsets=100, subset_size=100)
    if False:
        output['mmd2'], output['mmd2_var'] = mmd2s, vars = ret
    else:
        output['mmd2'] = mmd2s = ret
    print("mean MMD^2 estimate:", mmd2s.mean())
    # print("std MMD^2 estimate:", mmd2s.std())
    # print("MMD^2 estimates:", mmd2s, sep='\n')


#!/usr/bin/env python
# -*- coding: utf-8 -*-
'''
:py:mod:`rect.py` Rectify the pressure grid
-------------------------------------------

Converts a NetCDF file from sigma coordinates to pressure coordinates,
then interpolates all arrays to a rectified pressure grid. The user
can choose between linear interpolation (slow) and cubic interpolation
(really, really slow).

'''

from __future__ import division, print_function, absolute_import, unicode_literals
from .utils import array
from .constants import PREF
import numpy as np
from scipy.interpolate import interp1d
from scipy.io import netcdf
import sys

__all__ = ['Rectify']

def Rectify(file, interpolation = 'linear', rect_file = None):
  '''

  '''

  # Open the file
  f = netcdf.netcdf_file(file)

  # Get the variables we need to modify
  pfvars = []
  phvars = []
  newvars = {}
  for name in list(f.variables.keys()):
    if f.variables[name].dimensions == ('time', 'pfull', 'lat', 'lon'):
      pfvars.append(name)
    elif f.variables[name].dimensions == ('time', 'phalf', 'lat', 'lon'):
      phvars.append(name)

  # Create the true irregular pressure grid from the sigma coordinate
  # This is a 4D array (time, pressure, lat, lon). Units are mb.
  print("Computing new pressure grid...")
  pfull_ = np.stack([f.variables['ps'][:] * p / PREF for p in f.variables['pfull'][:]], axis = 1)
  phalf_ = np.stack([f.variables['ps'][:] * p / PREF for p in f.variables['phalf'][:]], axis = 1)

  # Rectify pfull
  pfull = np.nanmedian(pfull_, axis = (0,2,3))
  phalf = np.nanmedian(phalf_, axis = (0,2,3))

  # Get the dimensions
  ntime = f.variables['time'].shape[0]
  nlat = f.variables['lat'].shape[0]
  nlon = f.variables['lon'].shape[0]

  # Rectify each of the 4D phalf variables and interpolate to the pfull grid
  newvars.update({'phalf': phalf, 'phalf_unit': np.array('mb'), 'phalf_dims': np.array(['phalf']), 'phalf_desc': np.array('True half-pressure grid')})
  for n, name in enumerate(phvars):
    var_old = np.array(f.variables[name][:])
    var_new = np.zeros((ntime, len(pfull), nlat, nlon))
    for i in range(ntime):
      sys.stdout.write('\rVariable %d/%d: Processing time %d/%d...' % (n + 1, len(pfvars) + len(phvars), i + 1, ntime))
      sys.stdout.flush()
      for k in range(nlat):
        for l in range(nlon):
          var_new[i,:,k,l] = interp1d(phalf_[i,:,k,l], var_old[i,:,k,l], kind=interpolation,
                                      bounds_error=False, fill_value="extrapolate")(pfull)
    newvars.update({name: var_new})
    newvars.update({name + '_unit': np.array(f.variables[name].units.decode('utf-8'))})
    newvars.update({name + '_dims': np.array(['time', 'pfull', 'lat', 'lon'])})
    newvars.update({name + '_desc': np.array(f.variables[name].long_name.decode('utf-8'))})

  # Rectify each of the 4D pfull variables
  newvars.update({'pfull': pfull, 'pfull_unit': np.array('mb'), 'pfull_dims': np.array(['pfull']), 'pfull_desc': np.array('True pressure grid')})
  for n, name in enumerate(pfvars):
    var = np.array(f.variables[name][:])
    for i in range(ntime):
      sys.stdout.write('\rVariable %d/%d: Processing time %d/%d...' % (len(phvars) + n + 1, len(pfvars) + len(phvars), i + 1, ntime))
      sys.stdout.flush()
      for k in range(nlat):
        for l in range(nlon):
          var[i,:,k,l] = interp1d(pfull_[i,:,k,l], var[i,:,k,l], kind=interpolation,
                                  bounds_error=False, fill_value="extrapolate")(pfull)
    newvars.update({name: var})
    newvars.update({name + '_unit': np.array(f.variables[name].units.decode('utf-8'))})
    newvars.update({name + '_dims': np.array(['time', 'pfull', 'lat', 'lon'])})
    newvars.update({name + '_desc': np.array(f.variables[name].long_name.decode('utf-8'))})

  # Close original file
  f.close()

  # Create a new NetCDF file with just the rectified grids
  if rect_file is None:
    rect_file = '%s.rect.npz' % file[:-3]
  print("\nSaving to `%s`..." % rect_file)
  np.savez(rect_file, **newvars)

  f.close()
  print("Done!")


import voxelpy.mc.colors as clrs
import pyglet

mcolors = clrs.create_colors()

_vertices = (
    (0, 0, 1),  # vertex 0
    (1, 0, 1),  # vertex 1
    (1, 1, 1),  # vertex 2
    (0, 1, 1),  # vertex 3
    (1, 0, 0),  # vertex 4
    (0, 0, 0),  # vertex 5
    (0, 1, 0),  # vertex 6
    (1, 1, 0),  # vertex 7
)
_indices = (
    0, 1, 2, 3,  # top face
    4, 5, 6, 7,  # bottom face
    1, 4, 7, 2,  # left face
    5, 0, 3, 6,  # right face
    3, 2, 7, 6,  # down face
    5, 4, 1, 0   # up face
)

def build_chunk(chunk):
    vertices = []
    colors = []
    indices = []
    offsetx = chunk.chunkX << 4
    offsety = chunk.chunkY << 4
    offsetz = chunk.chunkZ << 4

    count = 0
    # Loop through each voxel
    for x in range(0, 16):
        nx = x + offsetx
        for y in range(0, 16):
            ny = y + offsety
            for z in range(0, 16):
                voxel_type = chunk[x, y, z]
                if voxel_type > 0:
                    nz = z + offsetz

                    rendertop = True if z == 15 else chunk[x, y, z + 1] == 0
                    renderbottom = True if z == 0 else chunk[x, y, z - 1] == 0
                    renderleft = True if x == 15 else chunk[x + 1, y, z] == 0
                    renderright = True if x == 0 else chunk[x - 1, y, z] == 0
                    renderdown = True if y == 15 else chunk[x, y + 1, z] == 0
                    renderup = True if y == 0 else chunk[x, y - 1, z] == 0
                    render = [rendertop, renderbottom, renderleft, renderright, renderdown, renderup]

                    renderamt = sum(render)
                    if renderamt == 0:
                        continue
                    for vertex in _vertices:
                        vertices += [vertex[0] + nx, vertex[1] + ny, vertex[2] + nz]

                    if voxel_type < len(mcolors) + 1:
                        color = mcolors[voxel_type - 1]
                        # if color == (256, 256, 256) or color == (255, 255, 255):
                        #     print(voxel_type)
                        #     print(color)
                        colors += [color[0], color[1], color[2]] * 8
                    else:
                        colors += [0, 256, 0] * 8

                    for i in range(len(render)):
                        if render[i]:
                            for j in range(i*4, i*4 + 4):
                                indices.append(_indices[j] + count * 8)
                    count += 1
    return vertices, colors, indices


import json
x="""
INSERT INTO CASA_DOCS VALUES('clusterMembership',\
'{"onlineState":"ONLINE","cluster_name":"vRealize Cluster Node",\
"is_ha_enabled":false,"ha_transition_state":"NONE",\
"initialization_state":
"HAMID","remove_node_state":"NONE",\
"document_time":1428095436668,"online_state":
"ONLINE","online_state_time":1428095436668,\
"online_state_reason":"","cluster_members":[],\
"admin_slices":[],"installation_state":"DONE",\
"slices":{"c5f388d7-ca3d-426d-917d-300b0cc13ad8":\
{"slice_uuid":"c5f388d7-ca3d-426d-917d-300b0cc13ad8",\
"is_admin_node":true,"ip_address":"vrops60vm-1.vcloud.local",\
"slice_name":"vRealize Cluster Node","membership_state":null},\
"e14ca978-2eb7-456a-b320-64937514e713":\
{"slice_uuid":"e14ca978-2eb7-456a-b320-64937514e713",\
"is_admin_node":false,"ip_address":"vrops60vm-3.vcloud.local",\
"slice_name":"vrops60vm-3.vcloud.local","membership_state":null},\
"e5633355-5b7a-4d3c-ae00-8a1547377b78":{"slice_uuid":\
"e5633355-5b7a-4d3c-ae00-8a1547377b78","is_admin_node":false,\
"ip_address":"vrops60vm-2.vcloud.local","slice_name":\
"vrops60vm-2.vcloud.local","membership_state":null}}}')
"""

def remove_node(x):
    store={}
    newdic={}
    p="c5f388d7-ca3d-426d-917d-300b0cc13ad8"
    replace_line = x.replace("INSERT INTO CASA_DOCS VALUES('clusterMembership','", "")
    stripped_line=replace_line.replace("')", "")
    json_line = json.loads(stripped_line)#it's dictionary now
    for k,v in json_line.items():
        print(k, ">>>:", v)
        json_line["onlineState"]="OFFLINE"
        #json_line.update("initialization_state","remove_node_state","installation_state")="NONE"
        json_line["initialization_state"]["remove_node_state"]["installation_state"]="NONE"
        #json_line["remove_node_state"]="NONE"
        #json_line["installation_state"]="NONE"
        if k=="slices":
            for newk, newv in v.items():
                newdic[newk]=newv
    for k, v in list(json_line.items()):
        if k=="slices":
            for newk, newv in list(v.items()):
                if newk==p:
                    del v[newk]
    print(json_line)

    for k, v in newdic.items():
        print(k, "->", v)
    print("/"*75)
    for i in list(newdic.keys()):
        if i ==p:
            del newdic[i]
    print(newdic)
    print("*"*75)
    for i in json_line["slices"]:
        # Get UUID
        slice_uuid = json_line["slices"][i]["slice_uuid"]#["is_admin_node"]
        # Get IP Address
        ip_address = json_line["slices"][i]["ip_address"]
        # Create entry in Dict Object
        store[slice_uuid] = ip_address

    return "INSERT INTO CASA_DOCS VALUES('clusterMembership','"+str(json_line)+"')"
##d = {1: 'a', 2: '', 3: 'b', 4: '', 5: '', 6: 'c'}
##for k, v in list(d.items()):
##    if v =="a":
##        del d[k]

print(remove_node(x))
#remove node from casaDB;base on KB2114077 step 12

def remove_corrupted_node(path):
    x=path
    line=x.replace("INSERT INTO CASA_DOCS VALUES('clusterMembership','", "")
    r_line=line.replace("')", "")
    j_line = json.loads(r_line)
    for k,v in list(j_line.items()):
        j_line["onlineState"]="OFFLINE"
        j_line["initialization_state"]="NONE"
        j_line["remove_node_state"]="NONE"
        j_line["installation_state"]="NONE"
        if k=="slices":
            for newk,newv in list(v.items()):
                if newk == p:#assume p in corrupted node uuid
                    del v[newk]
    return "INSERT INTO CASA_DOCS VALUES('clusterMembership','"+str(j_line)+"')"


# List Comprehension 3
# -------------------- #
# ðŸ’ª This exercise is HARD
# Instructions:
# Take a look inside file1.txt and file2.txt. They each contain a bunch of numbers, each number on a new line.
# You are going to create a list called result which contains the numbers that are common in both files.

# e.g. if file1.txt contained:
# 1
# 2
# 3

# and file2.txt contained:
# 2
# 3
# 4

# result = [2, 3]
# IMPORTANT: The result should be a list that contains Integers, not Strings.

with open("file1.txt") as file:
    file_1_data = file.readlines()

with open("file2.txt") as file:
    file_2_data = file.readlines()

result = [int(num) for num in file_1_data if num in file_2_data]

print(result)

# Output ==>
# [3, 6, 5, 33, 12, 7, 42, 13]


"""
* 역순 연결리스트
연결 리스트를 뒤집어라
Input : 1->2->3->4->5->NULL
Output : 5->4->3->2->1->NULL
"""
# Definition for singly-linked list.
class ListNode:
    def __init__(self, val=0, next=None):
        self.val = val
        self.next = next

    def print_list(self):
        cur = self
        while cur:
            print(cur.val, end='->')
            cur = cur.next

class Solution:
    # 재귀 구조로 뒤집기
    def reverseList(self, head: ListNode) -> ListNode:
        # prev : 리턴할 값
        def reverse(node: ListNode, prev: ListNode = None):
            if not node:
                return prev
            # next : 노드의 다음 값
            next, node.next = node.next, prev
            return reverse(next, node)

        return reverse(head)

if __name__ == '__main__':
    solution = Solution()
    param = ListNode(1, ListNode(2, ListNode(3)))
    print(solution.reverseList(param).print_list())


# Dmitry Kisler © 2019
# www.dkisler.com

import os
import sys
import logging
import requests
import inspect
import time

class getLogger:
    """Logger class to log and interrupt the process on the error"""

    def __init__(self,
                 logger="logs",
                 webhook_url=None,
                 kill=False):
        """Instantiate logger

            Args:
                logger: logger name
                webhook_url: url to push webhook
                kill: flag to terminate the process on the error
        """
        logging.basicConfig(level=logging.INFO,
                            format='%(asctime)s.%(msecs)03d [%(levelname)-5s] [%(name)-12s] %(message)s',
                            datefmt='%Y-%m-%d %H:%M:%S')

        self.logger_name = logger
        self.logs = logging.getLogger(self.logger_name)
        self.kill = kill
        self.webhook_url = webhook_url

    @classmethod
    def get_line(cls):
        """Returns the current line number"""
        return inspect.currentframe().f_back.f_lineno

    def _send_webhook(self,
                      msg: str,
                      is_error=True):
        """Function to push a webhook to slack channel

            Args:
                msg: log message
                is_error: flag to signal if message is the error message
        """
        if self.webhook_url is None:
            return

        color = "#ff003a"
        level = "ERROR"
        if not is_error:
            color = "#36a64f"
            level = "INFO"

        body = {
            "attachments": [
                {
                    "color": color,
                    "author_name": self.logger_name,
                    "title": level,
                    "text": msg,
                    "ts": int(time.time())
                }
            ]
        }

        try:
            res = requests.post(url=self.webhook_url,
                                headers={"Content-type": "application/json"},
                                json=body)
            if res.status_code > 200:
                self.logs.error("Cannot push webhook using provided URL")
                self.webhook_url = None
        except Exception as ex:
            self.logs.error("Cannot push webhook using provided URL")
            self.webhook_url = None

    def send(self,
             msg: str,
             lineno=None,
             kill=None,
             is_error=True,
             webhook=False):
        """Send a message into the logging output

            Args:
                msg: log message
                lineno: line number in the code where log send was triggered
                kill: flag to terminate the process on the error
                is_error: flag to signal if message is the error message
                webhook: flag to post message as the webhook post request
        """
        if lineno:
            msg = f"[line: {lineno}] {msg}"
        if is_error:
            self.logs.error(msg)
            self._send_webhook(msg,
                               is_error=is_error)
            if (kill if kill is not None else self.kill):
                sys.exit(1)
        else:
            self.logs.info(msg)
            if webhook:
                self._send_webhook(msg,
                                   is_error=is_error)
            if kill:
                sys.exit(0)


# the product of an integer and all the integers below it; e.g. factorial four ( 4! ) is equal to 24.

n=int(input("Enter the number :"))
result=1
for i in range(n,0, -1):
    result=result*i
print("factorial of", n ,"is",result)

# factorial using function recursion..

# def factorial(a):
#     if a==1:
#         return 1
#     else:
#         return a*factorial(a-1)    #n*(n-1)(n-2)....
# print(factorial(6))

# recursion


#question - find the longest word and print the word and length of the z
# question - remove the nth index element from the string
name = "My Name is Sahil Nagpal and I love Programming"
arr = name.split(" ")
counter=0
word=""
for y in arr:
    if len(y)>counter:
        counter=len(y)
        word=y
print("the length and the longest word is: ",word,counter)

print("Array",arr)
updatedString=arr.pop(int(input("enter the index number to be removed :")))
print("new string is :",arr)


import telebot
from telebot import types
import random
import os
import re

user_token = "5832700201:AAGd1AXiVDXTi9hdUzdAhsUNTzPDHSekDnQ"
user_images_folder = r"C:\Users\nsrod\Pictures\images"
user_images_folder = re.sub(r'\\', '/', user_images_folder)
user_audio_folder = r"C:\Users\nsrod\Music\audio"
user_audio_folder = re.sub(r'\\', '/', user_audio_folder)

class Bot:
    def __init__(self, token, images_folder, audio_folder):
        self.bot = telebot.TeleBot(token)
        self.images_folder = images_folder
        self.audio_folder = audio_folder

    def start(self):
        @self.bot.message_handler(commands=['start'])
        def handle_start(message):
            keyboard = types.ReplyKeyboardMarkup(True)
            keyboard.add('Аудио')
            keyboard.add('GitHub Link')
            self.bot.send_message(
                text="Чем могу быть полезен?",
                chat_id=message.chat.id,
                reply_markup=keyboard
            )

        @self.bot.message_handler(func=lambda message: "изображение" in message.text.lower())
        def send_random_image(message):
            image_files = [f for f in os.listdir(self.images_folder)]

            if image_files:
                random_image = random.choice(image_files)
                image_path = os.path.join(self.images_folder, random_image)

                with open(image_path, 'rb') as image_file:
                    self.bot.send_photo(message.chat.id, image_file)

        @self.bot.message_handler(func=lambda message: "аудио" in message.text.lower())
        def send_random_sound(message):
            sound_files = [f for f in os.listdir(self.audio_folder)]
            if sound_files:
                random_sound = random.choice(sound_files)
                sound_path = os.path.join(self.audio_folder, random_sound)

                with open(sound_path, 'rb') as sound_file:
                    self.bot.send_voice(message.chat.id, sound_file)

        @self.bot.message_handler(func=lambda message: "link" in message.text.lower())
        def send_github_link(message):
            self.bot.send_message(text='github.com/delf1nder/OOP_laba_1', chat_id=message.chat.id)
        self.bot.polling(none_stop=True)

if __name__ == "__main__":
    my_bot = Bot(user_token, user_images_folder, user_audio_folder)
    my_bot.start()


__author__ = "T06G06"

import unittest
from tester_base import TesterBase, captured_output
from pokemon_base import PokemonBase
from pokemon import Charmander, Bulbasaur, Squirtle, MissingNo
from poke_team import PokeTeam
from battle import Battle

class TestPokeTeam(unittest.TestCase):
    def test_choose_team(self):
        team = PokeTeam("Alder")

        # test Exception when battle mode not in {0,1,2}
        with self.assertRaises(Exception):
            team.choose_team(4)

        # test Exception when criterion not in {"lvl", "hp", "attack", "defence", "speed",None}:
        with self.assertRaises(Exception):
            team.choose_team(4)

        # test Exception for pokemon limit
        with captured_output("1 1 1 1") as (inp, out, err):
                team.choose_team(0)

    def test_assign_team(self):

        # testing for battle mode 0 team assignment
        team = PokeTeam("Alder")
        with captured_output("0 3 1") as (inp, out, err):
            team.choose_team(0)
        team.assign_team(0,3,1,0)
        self.assertEqual(str(team),"Bulbasaur's HP = 9 and level = 1, Bulbasaur's HP = 9 and level = 1, Bulbasaur's HP = 9 and level = 1, Squirtle's HP = 8 and level = 1")

        # testing for battle mode 1 team assignment
        team1 = PokeTeam("May")
        with captured_output("1 1 0") as (inp, out, err):
            team1.choose_team(1)
        team1.assign_team(1,1,0,0)
        self.assertEqual(str(team1),"Charmander's HP = 7 and level = 1, Bulbasaur's HP = 9 and level = 1")

        # !! battle mode 2 not tested
        team2 = PokeTeam("May")

        with captured_output("2 1 3") as (inp, out, err):
            team2.choose_team(2,"hp")
        team2.assign_team(2,1,0,0)
        self.assertEqual(str(team2),"Bulbasaur's HP = 9 and level = 1, Charmander's HP = 7 and level = 1, Charmander's HP = 7 and level = 1")

    def test__len__(self):
        team = PokeTeam("Jane")
        with captured_output("1 2 0") as (inp, out, err):
            team.choose_team(1)
        team.assign_team(1,2,0,0)
        self.assertEqual(team.__len__(), 3)

    def test__str__(self):
        team = PokeTeam("Matt")
        with captured_output("1 3 0") as (inp, out, err):
            team.choose_team(1)
        team.assign_team(1,3,0,0)
        self.assertEqual(team.__str__(), "Charmander's HP = 7 and level = 1, Bulbasaur's HP = 9 and level = 1, Bulbasaur's HP = 9 and level = 1, Bulbasaur's HP = 9 and level = 1")

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


# -*- coding: utf-8 -*-
# @Author: durban.zhang
# @Date:   2019-11-11 11:25:10
# @Last Modified by:   durban.zhang
# @Last Modified time: 2019-12-06 09:15:41

import os
from flask import (
    Blueprint, flash, g, redirect,
    request, render_template,
    url_for,
    current_app,
    send_from_directory
)

from werkzeug import secure_filename
from werkzeug.exceptions import abort
from baby.views.auth import login_required
from baby.db import get_db
from baby.exception import InvalidUsage

bp = Blueprint('blog', __name__, url_prefix='/post')

def get_posts(page, pagesize):
    db = get_db()
    posts = db.execute(
        'SELECT p.id, pc.category_id, c.name AS category_name,'
        ' p.title, p.body, p.created, p.author_id, u.username'
        ' FROM post p'
        ' JOIN user u ON p.author_id = u.id'
        ' JOIN post_category pc ON pc.post_id = p.id'
        ' JOIN category c ON c.id = pc.category_id'
        ' ORDER BY p.created DESC'
        ' LIMIT ?, ?', ((page - 1) * pagesize, pagesize)
    ).fetchall()

    for n, p in enumerate(posts):
        o = dict(p)

        o['tag'] = db.execute(
            'SELECT name FROM tag WHERE post_id = ?', (o['id'],)).fetchall()

        current_app.logger.info(o)
        posts[n] = o

    prev_page = (page - 1) if (page - 1) else ''
    next_page = (page + 1) if len(posts) >= pagesize else ''

    return posts, page, prev_page, next_page, pagesize

@bp.route('/item')
def index_item():
    page = request.args.get('page', 1, type=int)
    page = int(page)
    pagesize = 5

    posts, page, prev_page, next_page, pagesize = get_posts(page, pagesize)

    return render_template(
        'blog/index_item.j2',
        posts=posts,
        page=page,
        prev_page=prev_page,
        next_page=next_page,
        pagesize=pagesize
    )

@bp.route('/')
def index():
    page = request.args.get('page', 1, type=int)
    page = int(page)
    pagesize = 5

    posts, page, prev_page, next_page, pagesize = get_posts(page, pagesize)

    return render_template(
        'blog/index.j2',
        posts=posts,
        page=page,
        prev_page=prev_page,
        next_page=next_page,
        pagesize=pagesize
    )

@bp.route('/create', methods=['GET', 'POST'])
@login_required
def create():
    if request.method == 'POST':
        title = request.form['title'] if 'title' in request.form else ''
        body = request.form['body'] if 'body' in request.form else ''
        date = request.form['date'] if 'date' in request.form else ''
        tag = request.form['tag'] if 'tag' in request.form else ''
        category_id = request.form[
            'category_id'] if 'category_id' in request.form else ''

        error = None

        if not title:
            error = 'Title is required'
        elif not category_id:
            error = 'Category is required'
        elif not tag:
            error = 'Tag is required'

        if error is not None:
            flash(error)
        else:
            db = get_db()
            cur = db.cursor()
            cur.execute(
                'INSERT INTO post (title, body, author_id, the_date)'
                ' VALUES (?,?,?,?)',
                (title, body, g.user['id'], date)
            )

            db.commit()

            # tag insert
            insert_id = cur.lastrowid
            tags = tag.split(',')

            cur.executemany(
                'INSERT INTO tag (post_id, name)'
                ' VALUES (?,?)', tag_generator(insert_id, tags)
            )

            db.commit()

            # category insert
            cur.execute(
                'INSERT INTO post_category (post_id, category_id)'
                ' VALUES (?,?)',
                (insert_id, category_id)
            )

            db.commit()

            return redirect(url_for('blog.index'))

    category = get_category()

    return render_template(
        'blog/create.j2',
        category=category
    )

def tag_generator(insert_id, tags):
    for c in tags:
        yield (insert_id, c)

def get_category():
    db = get_db()
    category = db.execute('SELECT * FROM category ORDER BY id DESC').fetchall()

    return category

def get_post(id, check_author=True):
    db = get_db()

    post = db.execute(
        'SELECT p.id, pc.category_id,'
        ' the_date, title, body, p.created, author_id, username'
        ' FROM post p'
        ' JOIN user u ON p.author_id = u.id'
        ' JOIN post_category pc ON pc.post_id = p.id'
        ' WHERE p.id = ?',
        (id,)
    ).fetchone()

    if post is None:
        abort(404, "Post id {0} doesn't exist".format(id))

    if check_author and post['author_id'] != g.user['id']:
        abort(403)

    post = dict(post)

    tags = db.execute(
        'SELECT name FROM tag WHERE post_id = ?', (post['id'],)).fetchall()

    post['tag'] = ','.join((x['name'] for x in tags))

    current_app.logger.info(post)
    return post

@bp.route('/<int:id>/update', methods=['GET', 'POST'])
@login_required
def update(id):
    post = get_post(id)

    if request.method == 'POST':
        title = request.form['title'] if 'title' in request.form else ''
        body = request.form['body'] if 'body' in request.form else ''
        date = request.form['date'] if 'date' in request.form else ''
        tag = request.form['tag'] if 'tag' in request.form else ''
        category_id = request.form[
            'category_id'] if 'category_id' in request.form else ''
        error = None

        if not title:
            error = 'Title is required'
        elif not category_id:
            error = 'Category is request'
        elif not tag:
            error = 'Tag is required'

        if error is not None:
            flash(error)
        else:
            db = get_db()
            cur = db.cursor()
            cur.execute(
                'UPDATE post SET title = ?, body = ?, the_date = ?'
                ' WHERE id = ?',
                (title, body, date, id)
            )

            db.commit()

            # 清空原来的关联
            # 建立新的关联
            #

            cur.execute(
                'DELETE FROM tag WHERE post_id = ?', (id,)
            )

            tags = tag.split(',')
            cur.executemany(
                'INSERT INTO tag (post_id, name)'
                ' VALUES (?,?)', tag_generator(id, tags)
            )

            cur.execute(
                'UPDATE post_category SET category_id = ?'
                ' WHERE post_id = ?',
                (category_id, id,))

            db.commit()

            return redirect(url_for('blog.index'))

    category = get_category()

    return render_template(
        'blog/update.j2',
        post=post,
        category=category
    )

@bp.route('/<int:id>/delete', methods=['GET', 'POST'])
@login_required
def delete(id):
    get_post(id)
    db = get_db()
    db.execute(
        'DELETE FROM post where id = ?', (id,)
    )
    db.commit()
    return redirect(url_for('blog.index'))

@bp.route('/<int:id>/show', methods=['GET'])
def show(id):
    post = get_post(id, False)

    return render_template('blog/show.j2', post=post)

@bp.route('/tag/<string:name>', methods=['GET'])
def tag(name):
    db = get_db()
    posts = db.execute(
        'SELECT p.id, title, body, p.created, author_id, username'
        ' FROM tag AS t'
        ' JOIN post AS p ON p.id = t.post_id'
        ' JOIN user u ON p.author_id = u.id'
        ' WHERE t.name = ?'
        ' ORDER BY p.created DESC', (name,)
    ).fetchall()

    for n, p in enumerate(posts):
        o = dict(p)

        o['tag'] = db.execute(
            'SELECT name FROM tag WHERE post_id = ?', (o['id'],)).fetchall()

        current_app.logger.info(o)
        posts[n] = o

        return render_template('blog/tag.j2', posts=posts)

@bp.route('/read', methods=['GET'])
def read_sum():
    raise InvalidUsage('read sum function developing...', status_code=404)

def allowed_file(filename):
    return '.' in filename and \
        filename.rsplit('.', 1)[1].lower() in current_app.config[
            'UPLOAD_ALLOWED_EXTENSIONS']

def allowed_length(length):
    return length <= current_app.config[
        'UPLOAD_MAX_LENGTH']

@bp.route('/icon', methods=['GET', 'POST'])
@login_required
def icon():
    if request.method == 'POST':
        print(request.files)
        if 'icon' not in request.files:
            flash('No file part')
            return redirect(request.url)

        file = request.files['icon']
        if file.filename == '':
            flash('No selected file')
            return redirect(request.url)

        if file and \
                allowed_file(file.filename) and \
                allowed_length(file.content_length):
            filename = secure_filename(file.filename)
            file.save(os.path.join(current_app.config['UPLOAD_DIR'], filename))
            return redirect(url_for('blog.uploaded_icon', filename=filename))
    else:
        return render_template('blog/icon.j2')

@bp.route('/uploaded/icon/<string:filename>', methods=['GET'])
def uploaded_icon(filename):
    return send_from_directory(current_app.config['UPLOAD_DIR'], filename)


from telethon import events, Button, custom
import os,re
from ULTRAX import ID
from telethon.tl.custom import Button
from telethon import events, errors, custom, functions
@tgbot.on(events.InlineQuery(pattern=r"restart"))
async def inline_id_handler(event: events.InlineQuery.Event):
 LEGEND = event.builder
 X= [[custom.Button.inline("🔥 RESTART 🔥",data="restart")]]
 query = event.text
 result = LEGEND.article("LEGEND",text="REPO AND SUPPORT",buttons=X,link_preview=False)
 await event.answer([result])

from telethon import Button, custom, events
import os, re, sys, asyncio
@tgbot.on(events.callbackquery.CallbackQuery(data=re.compile(b'restart')))
async def restart(event):
  if event.sender_id == bot.me.id or event.sender_id == ID:
    await event.edit("Ya wait....Your Bot is being restarted...\nPlease Wait...")
    await asyncio.sleep(2)
    await event.edit("Restarting the Heroku connection.....")
    await asyncio.sleep(2)
    await event.edit("Yay!! Restarted your bot succesfully..\n✅✅")
    os.execl(sys.executable, sys.executable, *sys.argv)
    quit ()
  else:
    pro = "ρℓєαѕє ∂єρℓσу уσυ σωη υℓтяα χ υѕєявσт"
    await event.answer(pro, alert=True)


from django.contrib.auth import get_user_model
from django.contrib.auth.models import Permission
from django.test import TestCase

from lava_scheduler_app.models import (
    GroupDevicePermission,
    GroupDeviceTypePermission,
    TestJob,
)
from lava_server.backends import GroupPermissionBackend, is_object_supported
from tests.lava_scheduler_app.test_submission import TestCaseWithFactory

User = get_user_model()

class BackendAuthTest(TestCaseWithFactory):
    def setUp(self):
        super().setUp()
        self.group = self.factory.make_group()
        self.user = self.factory.make_user()
        self.user.groups.add(self.group)

        self.definition = self.factory.make_job_data_from_file(
            "qemu-pipeline-first-job.yaml"
        )
        self.device_type = self.factory.make_device_type(name="qemu")
        self.device = self.factory.make_device(
            device_type=self.device_type, hostname="qemu-1"
        )
        self.job = TestJob.from_yaml_and_user(self.definition, self.user)
        self.backend = GroupPermissionBackend()

    def tearDown(self):
        super().tearDown()
        GroupDeviceTypePermission.objects.all().delete()
        GroupDevicePermission.objects.all().delete()

    def test_is_object_supported(self):
        self.assertTrue(is_object_supported(self.device))
        self.assertTrue(is_object_supported(self.device_type))
        self.assertFalse(is_object_supported(self.user))
        self.assertFalse(is_object_supported(self.group))
        self.assertFalse(is_object_supported(self.job))

    def test_is_object_supported_none(self):
        self.assertFalse(is_object_supported(None))

    def test_get_all_permissions(self):
        GroupDevicePermission.objects.assign_perm(
            "view_device", self.group, self.device
        )
        self.assertEqual(
            {"view_device"},
            set(self.backend.get_all_permissions(self.user, self.device)),
        )
        GroupDevicePermission.objects.assign_perm(
            "change_device", self.group, self.device
        )
        self.assertEqual(
            {"change_device", "submit_to_device", "view_device"},
            set(self.backend.get_all_permissions(self.user, self.device)),
        )

        GroupDeviceTypePermission.objects.assign_perm(
            "view_devicetype", self.group, self.device_type
        )
        self.assertEqual(
            {"view_devicetype"},
            set(self.backend.get_all_permissions(self.user, self.device_type)),
        )
        GroupDeviceTypePermission.objects.assign_perm(
            "change_devicetype", self.group, self.device_type
        )
        self.assertEqual(
            {"change_devicetype", "view_devicetype", "submit_to_devicetype"},
            self.backend.get_all_permissions(self.user, self.device_type),
        )

    def test_has_perm(self):
        GroupDevicePermission.objects.assign_perm(
            "change_device", self.group, self.device
        )
        self.assertTrue(
            self.backend.has_perm(
                self.user, "lava_scheduler_app.change_device", self.device
            )
        )
        self.assertTrue(
            self.backend.has_perm(
                self.user, "lava_scheduler_app.submit_to_device", self.device
            )
        )
        self.assertFalse(
            self.backend.has_perm(
                self.user, "lava_scheduler_app.view_devicetype", self.device_type
            )
        )

    def test_has_global_perm(self):
        user = self.factory.make_user()
        user.user_permissions.add(Permission.objects.get(codename="change_device"))
        self.assertTrue(
            self.backend.has_perm(user, "lava_scheduler_app.change_device", self.device)
        )

    def test_has_perm_wrong_app_label(self):
        with TestCase.assertRaises(self, ValueError):
            self.backend.has_perm(
                self.user, "lava_results_app.change_device", self.device
            )


import sys
from itertools import combinations
input = sys.stdin.readline

def solution(n, m, array) :
    summation = 0
    for i in range(1, n+1) :
        summation += 2**i
    # 1. 팀원 리스트 생성
    team = []
    # 2.
    for arr in array :
        # 2-1. 각 팀원이 풀 수 있는 문제 비트화하기
        temp = 0b0000000000
        for num in arr[1:] :
            temp |= (1<<num)
        team.append(temp)
    # 3.
    for k in range(1, m+1) :
        # 3-1. 팀원 조합 구하기
        combination = list(combinations(team, k))
        # 3-2.
        for comb in combination :
            temp = 0b0000000000
            for c in comb :
                temp |= c
            # 모든 문제를 풀 수 있을 경우 결과 출력
            if temp == summation :
                print(k)
                exit()
    # 4. -1 출력
    print(-1)

if __name__ == "__main__":
    n, m = map(int, input().split())
    array = [list(map(int, input().split())) for _ in range(m)]
    solution(n, m, array)


import pytest
import trio

from libp2p.tools.factories import HostFactory
from libp2p.tools.interop.utils import connect

@pytest.mark.trio
async def test_connect(security_protocol, p2pds):
    async with HostFactory.create_batch_and_listen(
        1, security_protocol=security_protocol
    ) as hosts:
        p2pd = p2pds[0]
        host = hosts[0]
        assert len(await p2pd.control.list_peers()) == 0
        # Test: connect from Py
        await connect(host, p2pd)
        assert len(await p2pd.control.list_peers()) == 1
        # Test: `disconnect` from Py
        await host.disconnect(p2pd.peer_id)
        assert len(await p2pd.control.list_peers()) == 0
        # Test: connect from Go
        await connect(p2pd, host)
        assert len(host.get_network().connections) == 1
        # Test: `disconnect` from Go
        await p2pd.control.disconnect(host.get_id())
        await trio.sleep(0.01)
        assert len(host.get_network().connections) == 0


def ec2():
    print('Processing EC2 Instances')

    instances = boto3.resource('ec2').instances.all()
    for instance in instances:
        tags = [t for t in instance.tags or [] if t['Key'] in COPYABLE]
        if not tags:
            continue

        # Tag the EBS Volumes
        for vol in instance.volumes.all():
            print('Updating tags for {}'.format(vol.id))
            vol.create_tags(Tags=tags)

        # Tag the Elastic Network Interfaces
        for eni in instance.network_interfaces:
            print('Updating tags for {}'.format(eni.id))
            eni.create_tags(Tags=tags)

def elb():
    print('Processing ELB Instances')

    def filter(i):
        return (i.get('RequesterId') == 'amazon-elb' and
                i['Description'].startswith('ELB') and
                '/' not in i['Description'])

    tags = _get_elb_tags('elb')
    for interface in _network_interfaces(filter):
        name = interface['Description'].split(' ')[1]
        if name not in tags:
            continue
        _tag_network_interface(interface['NetworkInterfaceId'], tags[name])


import os
from subprocess import Popen, PIPE, call

class Shape:

    def __init__(self,
                 central_atom=0,
                 code=1,
                 custom_atom_list=None):

        self._code = code
        self._central_atom = central_atom
        self._custom_atom_list = custom_atom_list

        # Check if shape is in system path
        if not call("type shape", shell=True, stdout=PIPE, stderr=PIPE) == 0:
            print ('shape binary not found')
            exit()

    @property
    def code(self):
        return self._code

    @property
    def central_atom(self):
        return self._central_atom

    @property
    def custom_atom_list(self):
        return self._custom_atom_list

def _create_shape_file(molecule, input_data):

    code = input_data.code
    central_atom = input_data.central_atom
    atoms_list = input_data.custom_atom_list

    if isinstance(atoms_list, type(None)):
        atoms_list = range(molecule.get_number_of_atoms())

    if central_atom == 0:
        ligands = len(atoms_list)
    else:
        ligands = len(atoms_list) - 1

    temp_file_name = 'shape' + '_' + str(os.getpid()) + '.dat'

    shape_input_file = open(temp_file_name, 'w')

    shape_input_file.write('{0} {1}\n'.format(ligands, central_atom))
    shape_input_file.write('{0}\n'.format(code))

    shape_input_file.write('montemodes\n')

    for i in atoms_list:
        line = str(list(molecule.get_atomic_elements()[i]) +
                   list(molecule.get_coordinates()[i])
        ).strip('[]').replace(',', '').replace("'", "")
        shape_input_file.write(line + '\n')

    return shape_input_file

def get_shape(molecule, input_data):

    shape_input_file = _create_shape_file(molecule, input_data)
    shape_input_file.close()
    shape_process = Popen('shape ' + shape_input_file.name, stdout=PIPE, shell=True)
    shape_process.wait()

    measure = float(open(shape_input_file.name[:-4]+'.tab','r').readlines()[-1].split()[-1])

    os.remove(shape_input_file.name)
    os.remove(shape_input_file.name[:-4]+'.tab')

    return measure

def get_shape_trajectory(trajectory, input_data):
    symmetry_list = []
    for molecule in trajectory[1:]:
        symmetry_list.append(get_shape(molecule, input_data))

    return symmetry_list

def get_info(vertices=None):

    shape_process = Popen('shape +', stdout=PIPE, shell=True)
    (output, err) = shape_process.communicate()
    shape_process.wait()

    list = output.split('\n')
    indices = [(i, x.split()[1]) for i, x in enumerate(list) if "Vertices" in x]

    vertices_info = {}
    for index, v in indices:
        vertex_info = []
        j = 1
        while j > 0:
            if list[index+j] == '':
                break
            line = list[index+j].split()
            line[3:] = [' '.join(line[3:])]
            line[1] = int(line[1])
            vertex_info.append(line)
            j += 1
        vertices_info[v] = vertex_info

    if vertices is not None:
        return vertices_info[str(vertices)]

    return vertices_info

if __name__ == '__main__':

    import montemodes.functions.reading as io_monte

   # molecule = io_monte.reading_from_gzmat_file('../test.gzmat')
    molecule = io_monte.reading_from_xyz_file('../../test.xyz')
  #  molecule = io_monte.reading_from_txyz_file('../../Data/ethane.txyz')
    shape_input = Shape(code=1)

    print(get_shape(molecule, shape_input))


"""
Allows users to track their computation graph for visualization. Data is "tracked" by wrapping it in a `GraphData`
object, which acts as a passthrough wrapper that records the op that created the data and the values of the data that
should be visualized. Function calls are "tracked" by `GraphOp` objects, which record the function that was called
and the arguments it was given. Finally, containers are "tracked" with `GraphContainer` objects, which record their
contents.

See viz.md for underlying principles and concepts.
"""
import wrapt
import inspect
from collections import deque

class Nestable:
    """A parent class to `GraphOp` and `GraphContainer`, representing an object which might be nested in a hierarchy of
    containers."""
    def __init__(self):
        # Each `Nestable` may have either 0 or 1 containers, though that container might have many items and a
        # container of its own. Containers should also be `Nestable` instances.
        self.container = None

    def get_outermost_parent(self):
        """Returns the first `Nestable` with no container, found by iterating through this `Nestable`'s container
        hierarchy.

        The "outermost parent" of a `Nestable` n is the first `Nestable` with no container found in the hierarchy of
        n. This could be n itself, if n has no container.

        Returns:
            (Nestable): This instance's outermost parent.
        """
        return self if self.container is None else self.container.get_outermost_parent()

# ======================================================================================================================
# Graph operations.
# -----------------
# A `GraphOp` object records a single function call and is created whenever a function wrapped by an `OpGenerator`
# object is called.
# ======================================================================================================================

class GraphOp(Nestable):
    """A record of a single function execution."""
    def __init__(self, fn, args, kwargs):
        """Constructor.

        Args:
            fn (Callable): The function executed in the op.
            args (tuple): A sequence of positional arguments that were passed to the function at execution.
            kwargs (dict): A dictionary of keyword arguments passed to the function at execution.
        """
        super(GraphOp, self).__init__()
        self.fn = fn

        try:
            self.fn_name = fn.__name__
        except AttributeError:
            self.fn_name = fn.__class__.__name__

        # built-in functions don't have signatures, so we make them up
        try:
            if hasattr(fn, 'forward'):
                # `getfullargspec` will work on PyTorch modules, but won't get arg names. Need to get from `forward`
                # directly.
                fn_spec = inspect.getfullargspec(fn.forward)
            else:
                fn_spec = inspect.getfullargspec(fn)
            arg_names = fn_spec.args
            varargs = fn_spec.varargs
        except TypeError:
            arg_names = ['{}[{}]'.format(self.fn_name, i) for i in range(len(args))]
            varargs = 'args'

        arg_names = arg_names[(len(arg_names) - len(args)):] + [varargs for _ in range(len(args) - len(arg_names))]

        # Pytorch modules don't have a `__name__` field
        try:
            self.name = self.fn.__name__
        except AttributeError:
            self.name = self.fn.__class__.__name__

        # Arguments which were tracked via a call to `track_data()` (that is, should be shown in the graph) have a
        # `GraphData` object associated with them. We only record these objects (if they exist) in `self.args`,
        # as these contain all of the information needed to visualize the data in the client. Untracked objects are
        # represented by `None` to maintain position.
        self.args = self._make_arg_list(args, arg_names)

        # Only k-v pairs where the value is "tracked" are saved in `self.kwargs`.
        kwarg_keys = list(kwargs.keys())
        self.kwargs = self._make_arg_list([kwargs[k] for k in kwarg_keys], kwarg_keys)

        # A `GraphOp` object always has temporal level 0, so any new temporal container will be able to encapsulate
        # it (unless it is already in a temporal container of the same level). The concept is explained more in the
        # Containers section.
        self.temporal_level = 0

        self.outputs = []

    def _make_arg_list(self, args, arg_names):
        # len(args) == len(arg_names)
        arg_list = []
        for i, arg in enumerate(args):
            if has_graphdata(arg):
                arg_list.append([arg_names[i], get_graphdata(arg)])
            elif hasattr(arg, '__iter__'):
                arg_list.append([arg_names[i], [get_graphdata(obj) for obj in arg if has_graphdata(obj)]])
            else:
                arg_list.append([arg_names[i]])
        return arg_list

    def get_tracked_args(self):
        """Return a list of all recorded positional and keyword arguments that are wrapped in `GraphData`.

        This is used to build the DAG, collecting all `GraphData` inputs so that their ancestors can be iterated over
        and added to the graph.

        Returns:
            (list): All positional and keyword argument values that are tracked in `GraphData`.
        """
        tracked_args = []
        for arg_list in [self.args, self.kwargs]:
            tracked_args.extend([arg[1] for arg in arg_list if len(arg) > 1 and not isinstance(arg[1], list)])
            for arg in arg_list:
                if len(arg) > 1 and isinstance(arg[1], list):
                    tracked_args.extend([arg_item for arg_item in arg[1] if arg_item is not None])
        return tracked_args

# ======================================================================================================================
# Graph data.
# -----------
# A `GraphData` object records a single immutable function input or output in the computation graph. `GraphData` can
# be used as if they were their wrapped object.
# ======================================================================================================================

class GraphData:
    """A record of a tracked function input or output."""
    def __init__(self, obj, props_to_surface=None, creator_op=None, creator_pos=-1):
        """Constructor. Stores the properties of the tracked object which should be visualized in the graph.

        `GraphData` is a "dumb" container, simply recording internally an object which was input or output to a
        `GraphOp` or tracked via `track_data()`. `obj` should be immutable; if it changes, then the graph will be
        rendered incorrectly.

        Args:
            obj (object): The immutable object wrapped by the `GraphData`.
            props_to_surface (dict or None): A dict whose keys are user-selected names and whose values are the names
                of attributes of the wrapped Python object. The value of the named attribute will be shown under the
                user-selected name when the `GraphData` is inspected in the client. See
                `GraphData.surface_prop_in_client()` for more info and `OpGenerator.__call__()` for an example of usage.
            creator_op (GraphOp): The `GraphOp` which created the wrapped object.
            creator_pos (int): The position of the object in the `creator_op`'s output tuple.
        """
        self.obj = obj
        self.creator_op = creator_op
        self.creator_pos = creator_pos
        self.props_to_surface = dict()
        if props_to_surface is not None:
            for name_in_client, attr_name in props_to_surface.items():
                self.surface_prop_in_client(name_in_client, attr_name)

    def surface_prop_in_client(self, name_in_client, attr_name):
        """Add a new property to the `GraphData`'s visualization in the client.

        The client by default does not show all attributes of the wrapped object; this is helpful for objects like
        `torch.Variable`, which have many unnecessary fields. These fields also do not have names that are useful for
        the client to see. Instead, the `GraphData` object maintains a dictionary mapping descriptive property names
        to names of the wrapped object's attributes. When the `GraphData` is visualized, only these attribute values
        are shown, and under the user-selected name.

        Args:
            name_in_client (str): The property name, as will be shown in the client.
            attr_name (str or None): The name of the wrapped Python object's attribute, whose value will be shown
                associated with `name_in_client`. A value of `None` will associate the wrapped object itself with
                `name_in_client`, rather than a single one of its attributes.
        """
        self.props_to_surface[name_in_client] = attr_name

    def get_visualization_dict(self):
        """Returns a mapping of user-selected names to attributes of the wrapped Python object.

        The dict values will not be string names of the attributes, but rather the values of the attributes themselves.

        Returns:
            (dict): A dict of the form {user-selected name: value to visualize}.
        """
        return {
            key: getattr(self.obj, attr) if attr is not None else self.obj
            for key, attr in self.props_to_surface.items()
        }

# ======================================================================================================================
# Graph containers.
# -----------------
# A `GraphContainer` groups together `GraphOp` and other `GraphContainer` objects to provide abstraction in
# visualization. Containers are either abstractive, which collapses a subnetwork into a "black box" function,
# or temporal, which conceals everything outside of it, showing only the single "flow" it contains. See viz.md for
# information about the difference between the two, as well as the concept of "temporal subdivision" and "temporal
# level".
# ======================================================================================================================

# TODO handle paralellism
class GraphContainer(Nestable):
    """Represents a collection of grouped `GraphOp` and `GraphContainer` objects."""
    def __init__(self, contents, name='null', temporal_level=0, temporal_step=-1):
        """Constructor.
        Args:
            contents (set): A list of `GraphOp` and `GraphContainer` objects grouped by the instance,
                or None if no items are grouped yet.
            temporal_level (int): The temporal "height" of the container. Abstractive containers have temporal level
                0, and temporal containers have level > 0. New temporal containers can encapsulate only containers of
                level `temporal_level-1`.
        """
        super(GraphContainer, self).__init__()
        self.contents = contents
        self.temporal_level = temporal_level
        self.height = max([getattr(c, 'height', 0) + 1 for c in self.contents])
        self.temporal_step = temporal_step
        self.fn_name = name

def _build_abstractive_container(outputs, inputs, container_name):
    """Creates an abstractive container enveloping all ops between the container's proposed outputs and inputs.

    Builds the DAG backwards from the outputs in a breadth-first search, stopping beams at any encountered
    `GraphData` which is in the set of inputs. Whenever a new `GraphOp` is found during search, its outermost parent
    is added to the new container (see the definition of "outermost parent" in `Nestable.get_outermost_parent()`. After
    search terminates, all of the new container's contents have their `container` field updated to point to the new
    container.

    Args:
        outputs (list): `GraphData` objects which serve as the outputs of the new abstractive container.
        inputs (set): `GraphData` objects which serve as the inputs of the new abstractive container.
        container_name (str): The name that should be shown when the container is collapsed in the client.
    """
    contents = set()
    ops_checked = set()
    data_to_check = deque(outputs)
    while len(data_to_check) > 0:
        data = data_to_check.popleft()
        if data in inputs:
            continue
        creator_op = data.creator_op
        if creator_op is not None and creator_op not in ops_checked:
            outermost_parent = creator_op.get_outermost_parent()
            contents.add(outermost_parent)
            data_to_check.extend(creator_op.get_tracked_args())
            ops_checked.add(creator_op)
    container = GraphContainer(contents, name=container_name)
    # Update newly contained objects after iterating through the graph to prevent the new container from containing
    # itself (consider ops op1, op2, which share container c1. We are adding a new container c2. If we update the
    # container of op1 during iteration, then c1's container becomes c2. When we check op2, its outermost container
    # is now c2, meaning c2's container would become c2).
    for item in container.contents:
        item.container = container

# ======================================================================================================================
# Public API.
# -----------------
# The canonical ways of creating `GraphData`, `GraphOp`, and `GraphContainer` instances. Instances should not be
# directly created, and should be created only using the following methods.
# ======================================================================================================================

def track_data(obj, props_to_surface, creator_op=None, creator_pos=-1):
    """Creates a `GraphData` object which records the properties of `obj` and allows it to be shown in the graph.

    Any object which is not the output of a tracked function (see `OpGenerator`) is not, by default, shown in the
    computation graph. Leaf data nodes can be added to the graph via `track_data()`.

    Args:
        obj (object): Python object to add to the graph.
        props_to_surface (dict or None): A dict whose keys are user-selected names and whose values are the names
            of attributes of the wrapped Python object. The value of the named attribute will be shown under the
            user-selected name when the `GraphData` is inspected in the client. See
            `GraphData.surface_prop_in_client()` for more info and `OpGenerator.__call__()` for an example of usage.
        creator_op (GraphOp or None): The `GraphOp` object recording the function call which outputted `obj`. If
            `obj` is a leaf, `creator_op = None`.

    Returns:
        (GraphData): A wrapped version of the object, which can be used as if it were unwrapped.
    """
    try:
        obj.xnode_graphdata = GraphData(obj, props_to_surface, creator_op, creator_pos)
    except AttributeError:
        # Built-in types, like `dict` and `list`, cannot have new properties added to them unless subclassed
        class WrapperClass(type(obj)):
            pass
        obj = WrapperClass(obj)
        obj.xnode_graphdata = GraphData(obj, props_to_surface, creator_op, creator_pos)
    return obj

def has_graphdata(obj):
    """Returns `True` if an object has an associated `GraphData` object.

    Objects which are tracked in the computation graph via a call to `track_data()` have `GraphData` objects associated
    with them to contain information about the op which created the object and how it should be rendered.

    Args:
        obj (object): An object which might be tracked (and, thus, have a `GraphData` object).

    Returns:

    """
    try:
        return hasattr(obj, 'xnode_graphdata')
    except NotImplementedError:
        # PyTorch variables throw a NotImplementedError if you do a `getattr` on a non-existent attribute,
        # which breaks hasattr.
        return False

def get_graphdata(obj):
    """Returns the `GraphData` object associated with an object.

    This function assumes that `has_graphdata(obj) == True`.

    Args:
        obj (object): An object which has been tracked

    Returns:

    """
    return getattr(obj, 'xnode_graphdata')

class OpGenerator(wrapt.ObjectProxy):
    """Wraps a callable object, creating a `GraphOp` whenever called and wrapping each output in a `GraphData`."""
    def __init__(self, obj, output_props_to_surface=None):
        """Constructor.

        Args:
            obj (callable): A callable object, such as a function, whose executions should be recorded in the
                computation graph.
            output_props_to_surface (list or None): A dict determining what properties of each `GraphData`
                created by the callable should be surfaced in visualization. The i-th entry of `output_props_to_surface`
                is passed to the i-th output of the callable. For example:
                `
                a, b = Foo(), Foo()  # Foo is any arbitrary class
                a.prop1 = 10
                b.prop2 = 5

                def f(x, y):
                  new_x = Foo()
                  new_x.prop1 += 10
                  new_y = Foo()
                  new_y.prop2 -= 5
                  return new_x, new_y

                c = OpGenerator(f, output_props_to_surface=[{'Arbitrary Value': 'prop1'}, {'Another Value': 'prop2'}])
                x, y = c(a, b)  # x and y are GraphData wrappers around Foo instances
                `
                Now, when `x` is visualized and inspected in the client, it shows "Arbitrary Value": 10. When `y` is
                visualized and inspected, it shows "Another Value": 0. For functions whose outputs have different
                types under different conditions, or may output different numbers of values,
                setting `output_props_to_surface` to `None` will leave all `GraphData` outputs without any fields
                visualized. Fields can then be set after creation with `GraphData.surface_prop_in_client()`.
        """
        super(OpGenerator, self).__init__(obj)
        # wrapt requires all wrapper properties to start with _self_
        self._self_output_props = output_props_to_surface

    def __call__(self, *args, **kwargs):
        """Executes the wrapped function and creates a `GraphOp` recording the execution.

        A single `GraphOp` is created to record the function's execution. The wrapped function should not in its
        internals create any additional `GraphOp` objects; functions which create more `GraphOp` objects should be
        wrapped with `AbstractContainerGenerator` instead.

        Args:
            args (tuple): A sequence of positional arguments to pass to the wrapped function.
            kwargs (dict): Keyword arguments to pass to the wrapped function.

        Returns:
            The outputs of the wrapped function, each wrapped in a `GraphData` instance.
        """
        # TODO: should we dive into sequences and look for nested GraphData? If not, torch.cat doesn't really work
        # (since it takes as argument a list), but could be made to work with a wrapper that takes in any number of
        # inputs and collects them into a list before calling cat. If we do, how do we know when to stop diving,
        # and what do we do about output_props?
        ret = self.__wrapped__(*args, **kwargs)
        multiple_returns = isinstance(ret, tuple) and len(ret) > 1
        op = GraphOp(self.__wrapped__, args, kwargs)
        # TODO handle passthrough returns
        if multiple_returns:
            ret_graphdata = tuple([track_data(r,
                                     self._self_output_props[i] if self._self_output_props is not None else None,
                                     creator_op=op,
                                     creator_pos=i)
                          for i, r in enumerate(ret)])
        else:
            ret_graphdata = track_data(ret,
                              self._self_output_props[0] if self._self_output_props is not None else None,
                              creator_op=op,
                              creator_pos=0)
        op.outputs = ret_graphdata if isinstance(ret_graphdata, tuple) else (ret_graphdata, )
        return ret_graphdata

class AbstractContainerGenerator(wrapt.ObjectProxy):
    """Wraps a callable object, causing all `GraphOp` and `GraphContainer` objects created during its execution to be
    contained in a new abstractive `GraphContainer`."""
    def __call__(self, *args, **kwargs):
        """Executes the wrapped function and nests every `GraphOp` and `GraphContainer` it creates inside a new
        `GraphContainer`.

        `AbstractContainerGenerator` expects that its wrapped function contains (perhaps further nested within other
        functions) some `OpGenerator` functions that will produce `GraphOp` objects when called. Further, it expects
        that at least some of the inputs and outputs of the wrapped function have `GraphData` objects.
        These objects are then used to identify every `GraphOp` that exists between the inputs and the outputs in the
        DAG, and wraps their outermost parents in a new abstractive container.

        Args:
            args (tuple): Positional arguments to the wrapped function.
            kwargs (dict): Keyword arguments to the wrapped function.

        Returns:
            The unchanged output of the wrapped function.
        """
        inputs = set(get_graphdata(obj) for obj in args + tuple(kwargs.values()) if has_graphdata(obj))
        ret = self.__wrapped__(*args, **kwargs)
        output_graphdata = [get_graphdata(obj) for obj in ret if has_graphdata(obj)] \
            if isinstance(ret, tuple) and len(ret) > 1 else [get_graphdata(ret)]
        _build_abstractive_container(output_graphdata, inputs, self.get_fn_name())
        return ret

    def get_fn_name(self):
        try:
            return self.__wrapped__.__name__
        except AttributeError:
            return self.__wrapped__.__class__.__name__

def tick(output, temporal_level):
    """Create a temporal container extending backwards from output and encapsulating any outer-level op or container
    with `temporal_level`.

    Every op and container has a temporal level; abstractive containers and ops have level 0, and temporal containers
    have level > 0. Temporal containers of level n contain only items of temporal level n-1. If
    `output`'s outermost parent (see `Nestable.get_outermost_parent()` for definition) is of temporal level
    lower than  `temporal_level`, then `_tick(output, temporal_level-1)` is called before execution. This ensures that
    the concept of "temporal subdivision" is maintained, and that temporal containers only contain items at exactly one
    level below them.

    Args:
        output (GraphData): A `GraphData` from which to build the new temporal container.
        temporal_level (int): The temporal level of ops and containers that should be encapsulated by the new temporal
            container.
    """
    output = get_graphdata(output)
    if output.creator_op is not None \
            and output.creator_op.get_outermost_parent().temporal_level < temporal_level:
        tick(output, temporal_level - 1)

    contents = set()
    ops_checked = set()
    ops_to_check = deque([output.creator_op])
    max_temporal_step = -1

    while len(ops_to_check) > 0:
        op = ops_to_check.popleft()
        if op not in ops_checked and op is not None:
            ops_checked.add(op)
            highest = op.get_outermost_parent()
            assert highest.temporal_level >= temporal_level
            if highest.temporal_level == temporal_level:
                contents.add(highest)
                ops_to_check.extend([arg.creator_op for arg in op.get_tracked_args()])
            else:
                max_temporal_step = max(max_temporal_step, highest.temporal_step)
    container = GraphContainer(contents, temporal_level=temporal_level+1, temporal_step=max_temporal_step+1)
    # Update container fields of new container's contents after iteration to prevent premature exiting (consider ops
    # op1, op2, which are in temporal container c1 of level 1. We now are adding a temporal container c2 of height 2. If
    # we update the container of c1 during iteration, then when iteration reaches op2, its outermost parent would be
    # c2. Thus,it would not be enqueued and its ancestors would not be added to c2).
    for item in container.contents:
        item.container = container


# Origin: RhinoSecurityLabs, Pacu <https://github.com/RhinoSecurityLabs/pacu>
# Purpose: Utilities and additional session contextualized config settings
#

import contextlib
import os

from typing import Optional, cast, Callable, Generator, IO, Any
from pathlib import Path
from stratustryke import settings

active_session: Optional[Callable] = None

class StratustrykeException(Exception):
    pass

class FrameworkError(Exception):
	def __init__(self, msg):
		self.msg = msg

	def __str__(self):
		return repr(self.msg)

class FrameworkConfigurationError(FrameworkError):
	pass

class FrameworkRuntimeError(FrameworkError):
	pass

def strip_lines(text: str) -> str:
    '''
    Remove newline characters and tabs from supplied string.
    :param: text <str> string to remove newlines and tabs from.
    :rtype: <str> input string without newlines or tabs
    '''
    out = []
    for line in text.splitlines():
        out.append(line.split('\t '))
    return ' '.join(out)

def home_dir() -> Path:
    '''
    Get stratustryke app home directory
    :rtype: <Path> home directory of stratustryke app
    '''
    path = Path('~/.local/share/stratustryke').expanduser().absolute()
    os.makedirs(path, exist_ok=True, mode=0o700)
    return path

def stratustryke_dir() -> Path:
    '''
    Get directory stratustryke resides in
    :rtype: <Path> Path to directory stratustryke is in
    '''
    # e.g., /home/user/Tools/Git/Strautstryke/strautstryke
    return Path(__file__).parents[1]

def sqlite_filepath() -> Path:
    path = home_dir()/'stratustryke.sqlite'
    return path

def session_dir() -> Path:
    '''
    Returns directory for the current stratustryke session
    :rtype: <Path> path to the current stratustryke session's directory
    '''
    if not active_session:
        raise UserWarning('No session_name designated.')

    # e.g., /home/user/.local/share/stratustryke/mysession
    p = (home_dir()/cast(Callable, active_session)().name).absolute()
    # Create session dir if it doesn't exist
    os.makedirs(p, exist_ok=True)
    return p

def downloads_dir() -> Path:
    '''
    Returns directory downloads should be sent to for the current session
    :rtype: <Path> Path to current session's download directory
    '''
    # e.g., /home/user/.local/share/stratustryke/mysession/downloads
    p = (session_dir()/'downloads').absolute()
    # Create download dir if it doesn't exist
    os.makedirs(p, exist_ok=True)
    return p

def custom_modules_dir() -> Path:
    '''
    Returns path to directory where users can place custom modules
    :rtype: <Path> Path to custom user modules directory
    '''
    p = (stratustryke_dir()/'user_modules').absolute()
    os.makedirs(p, exist_ok=True)
    return p

def module_data_dir(mod: str) -> Path:
    '''
    Returns directory for specific modules data
    :param: mod: <str> module name
    :rtype: <Path> Path to module-specific directory for a session
    '''
    # e.g., /home/user/.stratustryke/mysession/modules/aws_whoami
    p = (home_dir()/'modules'/mod).absolute()
    os.makedirs(p, exist_ok=True)
    return p

@contextlib.contextmanager
def save(file_name: str, mode: str = 'w', header: Optional[str] = None, **kwargs) -> Generator[IO[Any], None, None]:
    '''
    Save text contents to a session's download directory
    :param: file_name: <str> name of file to write
    :param: mode: <str> file I/O mode [default: \'w\']
    :param: header: <str> string to write before text content (useful for CSVs)
    :rtype: <Generator> File I/O generator
    '''
    p = Path(downloads_dir()) / file_name
    p.parent.mkdir(parents=True, exist_ok=True, mode=0o700)

    with open(str(p), mode, **kwargs) as f:
        if header and not p.exists():
            f.write(header + '\n')
        try:
            yield f
        finally:
            f.close()


from .SpinCore_pp import (
    pause,
    configureRX,
    configureTX,
    init_ppg,
    stop_ppg,
    ppg_element,
    runBoard,
    load,
    getData,
    stopBoard,
    tune,
    adc_offset
)
from .config_parser_fn import configuration
from .calc_vdlist import vdlist_from_relaxivities, return_vdlist
from .process_first_arg import process_args

__all__ = [
    "SpinCore_pp",
    "adc_offset",
    "configuration",
    "configureRX",
    "configureTX",
    "getData",
    "init_ppg",
    "load",
    "pause",
    "ppg_element",
    "process_args",
    "return_vdlist",
    "runBoard",
    "stopBoard",
    "stop_ppg",
    "tune",
    "vdlist_from_relaxivities",
]


from setuptools import setup, find_packages
import codecs
import os

here = os.path.abspath(os.path.dirname(__file__))

with codecs.open(os.path.join(here, "SIMPLEREADME.md"), encoding="utf-8") as fh:
    long_description = "\n" + fh.read()

VERSION = '0.0.8'
DESCRIPTION = 'A library that helps you build dlt pipelines by side stepping the dlt library and making your code interactive'

# Setting up
setup(
    name="dlt_sidestep",
    version=VERSION,
    author="Michael Gardner",
    author_email="gardnmi@gmail.com",
    description=DESCRIPTION,
    long_description_content_type="text/markdown",
    long_description=long_description,
    packages=find_packages(),
    install_requires=[''],
    keywords=['python', 'databricks', 'dlt', 'delta live tables'],
    classifiers=[
        "Development Status :: 5 - Production/Stable",
        "Intended Audience :: Developers",
        "Programming Language :: Python :: 3",
        "Operating System :: Unix",
        "Operating System :: MacOS :: MacOS X",
        "Operating System :: Microsoft :: Windows",
    ]
)


#!/usr/bin/python
from datetime import datetime
import time
import argparse
import logging
import sys
from os import getenv
import requests
from petadmin import Environment

log = logging.getLogger(__name__)
env = Environment('check_status')

env.configure_logger(log)

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('target', action='store', help='Target of check: local or remote')
    parser.add_argument('-fail', help='Simulate a fail', action='store_true')

    args = parser.parse_args()

    log.info('Running %s', ' '.join(sys.argv))

    target = args.target

    if target == 'local':
        url = 'http://192.168.0.200/wordpress/wp-content/plugins/crowbank/status.php'
    else:
        url = 'http://dev.crowbankkennels.co.uk/wp-content/plugins/crowbank/status.php'

    sql = "select ws_state, ws_lasttransfer from vwwebsite_state where ws_iscurrent = 1"
    cursor = env.get_cursor()

    cursor.execute(sql)

    last_fail = 0

    for row in cursor:
        previous_status = row[0]
        previous_lasttransfer = row[1]

    now = datetime.now()
    r = requests.get(url)
    status = r.json()

    age = status['age']
    lasttransfer_text = status['lasttransfer']['date']
    system_status = status['status']

    in_date_format = '%Y-%m-%d %H:%M:%S.%f'
    date_format = '%Y-%m-%d %H:%M:%S'
    lasttransfer = datetime.strptime(lasttransfer_text, in_date_format)
    lasttransfer_text = lasttransfer.strftime(date_format)

    new_status = 'Loaded'

    if age > 1200:
        new_status = 'Obsolete'
        log.error('Data age on %s system is %d seconds, last transfer on %s' % (target, age, lasttransfer))

    if system_status != 'Loaded':
        new_status = system_status
        log.error('Status on %s system is %s' % (target, system_status))

    if new_status == 'Loaded':
        if args.fail:
            new_status = 'Fail'
            log.error('Simulated fail on %s system' % target)
        else:
            log.info('Status on %s system is good. Last transfer, %d seconds ago, at %s' % (target, age, lasttransfer))

    if target == 'remote':
        send_email = (new_status != previous_status) or (lasttransfer != previous_lasttransfer)

        sql = "execute pset_website_state '%s', '%s', %d, '%s'" % (new_status, r, send_email, lasttransfer_text)

        env.execute(sql)

        if send_email:
            body = 'Remote system status changed from %s to %s. Last successful transfer was %s, %d seconds ago' % (previous_status, new_status, lasttransfer_text, age)
            subject = 'Remote system updated to %s' % new_status

            send_to = env.email_logs
            env.send_email(send_to, body, subject, body)

    env.close()

if __name__ == '__main__':
    main()


from collections import defaultdict

#Program to count number of words in a sentence
sentence = "The red fox jumped over the fence and ran to the zoo for food"
words = sentence.split()

word_dict = {}
for word in words:
    if word in word_dict:
        word_dict[word]= word_dict[word]+1
    else:
        word_dict[word] = 1

print(word_dict)

for w,c in word_dict.items():
    print(f"Word Count: {w} => {c}")

'''
{'The': 1, 'red': 1, 'fox': 1, 'jumped': 1, 'over': 1, 'the': 2, 'fence': 1, 'and': 1, 'ran': 1, 'to': 1, 'zoo': 1, 'for': 1, 'food': 1}
Word Count: The => 1
Word Count: red => 1
Word Count: fox => 1
Word Count: jumped => 1
Word Count: over => 1
Word Count: the => 2
Word Count: fence => 1
Word Count: and => 1
Word Count: ran => 1
Word Count: to => 1
Word Count: zoo => 1
Word Count: for => 1
Word Count: food => 1
'''

#Same problem with default_dict
'''
The defaultdict will automatically assign zero as the value to any key it doesn’t already have in it.
We add one so it makes more sense and it will also increment if the word appears multiple times in the sentence.
'''
sentence = "The red fox jumped over the fence and ran to the zoo for food"
words = sentence.split()
word_dict = default_dict(int)
for word in words:
  word_dict[word]+= 1

print(word_dict)

'''
defaultdict(<class 'int'>,
            {'The': 1,
             'and': 1,
             'fence': 1,
             'food': 1,
             'for': 2,
             'jumped': 1,
             'over': 1,
             'ran': 1,
             'red': 1,
             'the': 2,
             'to': 1,
             'zoo': 1})
'''


from scene import Scene
from textwrap import dedent
from stats_inventory import Person, Inventory

class Armory(Scene):

  def enter(self):
    print(dedent("""You enter the armory! Along the wall are
    several Buzz Sticks. A Club with an electrical shock\n
      """))

    print(dedent("""There are doors 'forward' and 'port'."""))
    choice = input("> ")
    while choice.lower() != "quit":
      choice = choice.lower()
      if "forward" in choice or choice == 'f':
        return 'bridge'
      elif "port" in choice or choice == 'p':
        return 'engineroom'
      elif "buzz" in choice or "stick" in choice:
        myRoot = Inventory.item.insertKey("Buzz Stick")
        print("Your inventory:")
        Inventory.item.inOrder(myRoot)
      elif "inventory" in choice or choice == 'i':
        myRoot = Inventory.item.insertKey("Lincoln Head Penny 1909 VBS")
        print("Your inventory:")
        Inventory.item.inOrder(myRoot)
      choice = input("\nThere are doors 'forward' and 'port'. > ")


# solution from 'Dive into Python3'

roman_numeral_map = (
    ('M', 1000),
    ('CM', 900),
    ('D', 500),
    ('CD', 400),
    ('C', 100),
    ('XC', 90),
    ('L', 50),
    ('XL', 40),
    ('X', 10),
    ('IX', 9),
    ('V', 5),
    ('IV', 4),
    ('I', 1))

class Solution:
    # @return an integer

    def romanToInt(self, s):
        """convert Roman numeral to integer"""
        result = 0
        index = 0
        for numeral, integer in roman_numeral_map:
            while s[index:index + len(numeral)] == numeral:
                result += integer
                index += len(numeral)
                return result


import pytest
import requests

@pytest.mark.duckduckgo
@pytest.mark.restapi
def test_duckduckgo():

    #Arrange
   # url = 'https://api.duckduckgo.com/?q=python+programming&format=json'
    url = 'https://pocketfactory-qa.ssidecisions.com/'

    #Act
    response = requests.get(url)
    #body = response.json()

    #Assert
    assert response.status_code == 200
    #assert 'Python' in body['AbstractText']


from words import words
import random
import string
from hangman_visual import hanged_man

def valid_word(words):
    word = random.choice(words)
    while '-' in word or ' ' in word:
        word = random.choice(words)

    return word.upper()

def hangman():

    alphabet = set(string.ascii_uppercase)
    word = valid_word(words)
    word_letters = set(word) #letter in word
    used_letter = set() #letters we've guessed
    lives = 7

    while len(word) > 0 and lives > 0:

        # ' '.join() makes it string [a, b , c] --> 'a b c'
        print(f"'You have {lives} lives, and have used these letters: {' '.join(used_letter)}")
        # W - R D
        word_list = [letter if letter in used_letter else '-' for letter in word]
        print('Current word: ', ''.join(word_list))
        print(hanged_man[lives])
        # user input
        user_inpt_letter = input("Guess a letter: ").upper()
        if user_inpt_letter in alphabet - used_letter:
            used_letter.add(user_inpt_letter)
            if user_inpt_letter in word_letters:
                word_letters.remove(user_inpt_letter)
            else:
                lives = lives - 1
                print(f"Your letter { user_inpt_letter }, is not in the word.")
        elif user_inpt_letter in used_letter:
            print("You've already guessed that. Try Again!")
        else:
            print("Invalid Character. Try again. ")

    if lives == 0:
        print(f"You died, sorry! The word was {word}")
        print(hanged_man[lives])
    else:
        print(f"Yay, you have guessed the {word}")

hangman()


# -*- coding: utf-8 -*-
"""
Created on Thu Feb 13 14:30:28 2020

@author: abz1e14
"""
from pandas import read_excel
from statsmodels.formula.api import ols
series = read_excel('Bank.xls', sheet_name='Data2', header=0,
                     squeeze=True, dtype=float)

#reading the basic variables
DEOM = series.DEOM
AAA = series.AAA
Tto4 = series.Tto4
D3to4 = series.D3to4

#Regression model(s)
formula = 'DEOM ~ AAA + Tto4 + D3to4'

#Ordinary Least Squares (OLS)
results = ols(formula, data=series).fit()
print(results.summary())

# Here the main table is the second one,
# where all the statistics of the individual variables
# are given.

LearningResource/Forecasting/Chapter 4 Data and Codes 2023/Chapter 4 Demonstrations Material/IndividualSignificanceBank.py


class Solution(object):
    def smallestDivisor(self, nums, threshold):
        """
        :type nums: List[int]
        :type threshold: int
        :rtype: int
        """
        low, high = 1, max(nums)
        def meetThres(divisor):
            ans = 0
            for n in nums:
                ans += n//divisor
                if n%divisor > 0:
                    ans += 1
            return ans <= threshold
        while low + 1 < high:
            mid = (low + high)/2
            if meetThres(mid):
                high = mid
            else:
                low = mid
        if meetThres(low):
            return low
        else:
            return high


"""
API to interact with email services (via courier)
"""
from config import COURIER_API_TOKEN
import utils
from trycourier import Courier
from .communications_mapping import COMMS_TO_EVENT_MAP
import config

@utils.logged
class Notifier:
    def __init__(self):
        self.client = Courier(auth_token=COURIER_API_TOKEN)

    def notify(
        self, comms_name, recipient_id, data, profile=None, idempotency_key=None
    ):
        """Send communications via courier"""
        event_id = COMMS_TO_EVENT_MAP[comms_name]
        resp = self.client.send(
            event=event_id,
            recipient=recipient_id,
            data=data,
            profile=profile,
            idempotency_key=idempotency_key,
        )
        return resp

    def notify_organizer(self, message):
        """Send communications via courier"""
        event_id = COMMS_TO_EVENT_MAP["generic_organizer_notification"]
        resp = self.client.send(
            event=event_id,
            recipient="organizer",
            data={"message": message},
            profile=config.ADMIN_NOTIFICATION_PROFILE,
            idempotency_key=None,
        )
        return resp

    def replace_or_create_profile(self, recipient_id, profile):
        """Create or replace profile"""
        resp = self.client.replace_profile(recipient_id, profile)
        return resp

    def update_or_create_profile(self, recipient_id, profile):
        """Create or update profile"""
        resp = self.client.merge_profile(recipient_id, profile)
        return resp


from abc import ABC, abstractmethod
from typing import Any, Generic

import bpy
from mathutils import Vector

from ..blendutil import set_active_layer_collection
from ..datamodel import CellBlock, IVector, T_state

C = bpy.context
D = bpy.data

class CellBlockView(ABC, Generic[T_state]):
    __slots__ = (
        '_cells', '_block_name', '_cell_size', '_padding', '_collection', '_meshes')

    def __init__(self,
        cells: CellBlock[T_state],
        block_name: str,
        size: float,
        padding: float
    ):
        self._cells = cells
        self._block_name = block_name
        self._cell_size = size
        self._padding = padding
        self._meshes: dict[IVector, Any] = {}

        # Create a collection for the cell block and set it active
        self._collection = D.collections.new(block_name)
        C.scene.collection.children.link(self._collection)
        set_active_layer_collection(block_name)

        # Create the individual cells
        self.make_meshes()

    def make_meshes(self):
        """Creates a mesh for each cell in the cell block.

        Cells are added to the currently active layer collection.
        """
        sx, sy, sz = self._cells.size
        box = self._cell_size + (self._padding * 2)
        center = Vector((
            (sx * box) / 2,
            (sy * box) / 2,
            (sz * box) / 2
        ))
        offset = Vector((
            (box / 2) - center.x,
            (box / 2) - center.y,
            (box / 2) - center.z
        ))

        for xyz in self._cells:
            grid_x, grid_y, grid_z = xyz
            x = (grid_x * box) + offset.x
            y = (grid_y * box) + offset.y
            z = (grid_z * box) + offset.z
            self.add_cell_view(self._cell_size, Vector((x, y, z)))
            cube = C.object
            cube.name = self._cells.name_of(xyz)
            self._meshes[xyz] = cube

    @property
    def cells(self) -> CellBlock[T_state]:
        return self._cells

    @property
    def name(self) -> str:
        return self._block_name

    @property
    def collection(self) -> Any:
        return self._collection

    @property
    def meshes(self) -> dict[IVector, Any]:
        return self._meshes

    def update(self):
        """Update the cells to match the states of the backing cell block."""
        for (xyz, mesh) in self._meshes.items():
            state = self._cells[xyz]
            self.update_cell_view(mesh, state)

    @abstractmethod
    def add_cell_view(self, size: float, location: Vector) -> None:
        """Adds a Blender object to the active layer collection that will
        represent a grid cell.

        Args:
            size: The size of the object in Blender units.
            location: The location of the object in Blender space.
        """

    @abstractmethod
    def update_cell_view(self, cell_view: Any, state: T_state) -> None:
        """Updates the given Blender object using the given ``state``.

        Args:
            cell_view: The Blender object to adjust.
            state: The state to inform the adjustment.
        """