"""make tensorflow graphs for evaluating, minimizing, and finding critical points on
quadratic forms and neural network loss surfaces.
"""
from collections import namedtuple
import tensorflow as tf
import numpy as np

from . import generic

QuadraticForm = namedtuple("QuadraticForm", ["graph", "graph_dictionary"])

DEFAULTS = {"learning_rate":0.1, # courtesy of Moritz Hardt and Ilya Sutskever
            "newton_rate":1,
            "fudge_factor":0.0,
            "inverse_method":"fudged",
            "gradient_norm_min_rate":0.1}

def make(matrix, initial_values, hyperparameters):
    """make a tensorflow graph to evaluate, minimize, and find critical points
    on the surface 0.5*x.transpose().dot(matrix).dot(x),
    the quadratic form on x defined by matrix.

    the input to the matrix is initialized to initial_values
    and the hyperparameters of the minimizer and critical point finder
    are determined by the hyperparameters argument.
    """

    assert matrix.shape[0] == matrix.shape[1], "only square matrices can be quadratic forms"
    assert matrix.shape[0] == len(initial_values), "initial_values and matrix must match shape"

    dimension = matrix.shape[0]

    graph = tf.Graph()

    with graph.as_default():
        quadratic_form = tf.constant(matrix, name='quadratic_form')

        inputs = tf.get_variable("inputs", shape=[dimension], dtype=tf.float32,
                                initializer = tf.constant_initializer(initial_values))

        input_vector = tf.reshape(inputs, (dimension, 1))

        output = 0.5*tf.squeeze(tf.matmul(input_vector,
                                  tf.matmul(quadratic_form, input_vector),
                                      transpose_a=True,
                                  name='output'),
                        name='squeezed_output')

        graph_dictionary = {"inputs": inputs,
                           "output": output,}

        generic.add_gradient_ops(output, inputs, graph_dictionary)
        generic.add_hess_ops(output, inputs, graph_dictionary)

        generic.add_optimizer(output, inputs, hyperparameters, graph_dictionary)
        generic.add_crit_finder(output, inputs, dimension, hyperparameters, graph_dictionary)

    return QuadraticForm(graph, graph_dictionary)

## convenience functions for interacting with quadratic form graphs

def generate_initial_values(N, scaling_factor=None):
    """generate a vector of scaled random normal values.
    scaling_factor defaults to 1/sqrt(N).
    """
    if scaling_factor is None:
        scaling_factor = 1/np.sqrt(N)

    return scaling_factor*np.random.standard_normal(size=N).astype(np.float32)

def run_algorithm(quadratic_form, algorithm, num_steps):
    """run algorithm on quadratic form and return the resulting outputs and values
    """
    graph, graph_dictionary = quadratic_form

    with graph.as_default():
        with tf.Session() as sess:
            tf.global_variables_initializer().run()
            graph_dictionary["inputs"].initializer.run()
            for _ in range(num_steps):
                sess.run(graph_dictionary["step_"+algorithm])
            output = sess.run(graph_dictionary["output"])
            values = graph_dictionary["inputs"].eval()

    return output, values

def get_result(result_key, input_vector, quadratic_form_graph):
    """return the result of applying quadratic_form_graph.graph_dictionary["result_key"] on input_vector
    """

    graph, graph_dictionary = quadratic_form_graph
    result_op = graph_dictionary[result_key]
    input_placeholders = graph_dictionary["inputs"]

    input_feed_dict = make_feed_dict(input_placeholders, input_vector)

    result = run_op(graph, result_op, input_feed_dict)

    return result

def run_op(graph, op, input_feed_dict):
    """run a given op on a given graph with feed_dict input_feed_dict
    """

    with graph.as_default():
        with tf.Session() as sess:
            result = sess.run(op, feed_dict = input_feed_dict)

    return result

def make_feed_dict(input_placeholders, input_vector):
    """make a feed_dict for a quadratic_form_graph
    """

    feed_dict = {input_placeholders:input_vector}

    return feed_dict

## functions for generating various random matrices

def generate_gaussian(N):
    """generate an N by N gaussian random matrix with variance N
    """
    return 1/np.sqrt(N)*np.random.standard_normal(size=(N,N)).astype(np.float32)

def generate_symmetric(N):
    """generate an N by N symmetric gaussian random matrix with variance N
    """
    base_matrix = generate_gaussian(N)
    return (1/np.sqrt(2))*(base_matrix+base_matrix.T)

def generate_wishart(N, k=1):
    """generate an N by N wishart random matrix with rank min(N,k)
    """
    self_outer_product = lambda x: x.dot(x.T)
    wishart_random_matrix = 1/k*self_outer_product(np.random.standard_normal(size=(N,k))).astype(np.float32)

    return wishart_random_matrix

def generate_negative_wishart(N, k=1):
    """generate an N by N negative wishart random matric with rank min(N,k)
    """
    wishart_random_matrix = generate_wishart(N, k)
    negative_wishart_random_matrix = -1*wishart_random_matrix

    return negative_wishart_random_matrix

Finding Critical Points with Newton's Method/crit_finder/graphs/quadratics.py


import click
import sys
import configparser
from osc import OSCDeployer
from api import APIManager

config = configparser.ConfigParser()
c = config.read('../config.cfg')
if not c:
    print('Could not find Config file')
    sys.exit()

osc_deployer = OSCDeployer(
    config.get('basic', 'node_base_url'),
    config.get('basic', 'odbl_image'),
    config.get('basic', 'mongo_image'),
    config.get('basic', 'oc_project'),
    config.get('basic', 'authority_node'),
)
api_manager = APIManager(
    config.get('basic', 'dataset_folder'),
    config.get('basic', 'authority_node'),
    config.get('basic', 'node_base_url')
)

@click.group()
def cli():
    """Welcome to the ODBl CLI Tool"""
    pass

@cli.group()
def deploy():
    """Deployment Commands"""
    pass

@cli.group()
def setup():
    """Setup Commands"""
    pass

@cli.group()
def validate():
    """Validate and Evaluation Commands"""
    pass

@deploy.command(help='Deploy ODBL nodes', name='init')
@click.option('-c', '--count', 'count', type=int, default=3, help='Number of nodes')
def init_nodes(count):
    osc_deployer.deploy(count)

@deploy.command(help='Remove ODBL nodes', name='remove')
@click.option('-c', '--count', 'count', type=int, default=3, help='Number of nodes')
def remove_nodes(count):
    osc_deployer.remove(count)

@deploy.command(help='Manage an extra ODBL node', name='extra')
@click.option('-o', '--operation', 'operation',
              type=click.Choice(['init', 'remove'], case_sensitive=False), required=True)
def manage_extra(operation):
    if operation == 'init':
        osc_deployer.extra_node()
    if operation == 'remove':
        osc_deployer.remove_extra_node()

@deploy.command(help='Manage an Authority Node', name='authority')
@click.option('-o', '--operation', 'operation',
              type=click.Choice(['init', 'remove'], case_sensitive=False), required=True)
def manage_authority(operation):
    if operation == 'init':
        osc_deployer.deploy_authority()
    if operation == 'remove':
        osc_deployer.remove_authority()

@deploy.command(help='Manage Node01', name='node01')
@click.option('-o', '--operation', 'operation',
              type=click.Choice(['init', 'remove'], case_sensitive=False), required=True)
def manage_node01(operation):
    if operation == 'init':
        osc_deployer.deploy_node01()
    if operation == 'remove':
        osc_deployer.remove_node01()

@deploy.command(help='Manage Nodes', name='manage')
@click.option('-o', '--operation', 'operation',
              type=click.Choice(['deactivate', 'activate'], case_sensitive=False), required=True)
@click.option('-n', '--node', 'nodes', multiple=True, required=True)
def manage_nodes(operation, nodes):
    nodes = list(nodes)
    if operation == 'deactivate':
        osc_deployer.deactivate_nodes(nodes)
    if operation == 'activate':
        osc_deployer.reactivate_nodes(nodes)

@setup.command(help='Setup all nodes', name='all')
@click.option('-c', '--count', 'count', type=int, default=3, help='Number of nodes')
@click.option('-p', '--publisher', 'publisher', type=str, help='Publisher URI', multiple=True)
def setup_nodes(count, publisher):
    if publisher:
        api_manager.setup(list(publisher))
    else:
        api_manager.setup(api_manager.get_base_urls(count))

@setup.command(help='Reset all nodes', name='reset')
@click.option('-c', '--count', 'count', type=int, default=3, help='Number of nodes')
@click.option('-p', '--publisher', 'publisher', type=str, help='Publisher URI', multiple=True)
def reset_nodes(count, publisher):
    if publisher:
        api_manager.reset(list(publisher))
    else:
        api_manager.reset(api_manager.get_base_urls(count))

@setup.command(help='Reset all nodes', name='single')
@click.option('-u', '--url', 'url', type=str, required=True, help='URL of the node')
def setup_single_node(url):
    api_manager.setup_single(url)

@validate.command(help='Check the online state of all nodes', name='online')
@click.option('-c', '--count', 'count', type=int, default=3, help='Number of nodes')
@click.option('-p', '--publisher', 'publisher', type=str, help='Publisher URI', multiple=True)
def setup_nodes(count, publisher):
    if publisher:
        api_manager.online(list(publisher))
    else:
        api_manager.online(api_manager.get_base_urls(count))

@validate.command(help='Check the blockchain state of all nodes', name='chain')
@click.option('-c', '--count', 'count', type=int, default=3, help='Number of nodes')
@click.option('-p', '--publisher', 'publisher', type=str, help='Publisher URI', multiple=True)
def setup_nodes(count, publisher):
    if publisher:
        api_manager.chain(list(publisher))
    else:
        api_manager.chain(api_manager.get_base_urls(count))

@validate.command(help='Issue transactions', name='transaction')
@click.option('-f', '--folder', 'folder', type=str, help='Name of the folder', multiple=True, required=True)
@click.option('-s', '--start', 'start', type=int, help='Starting point of datasets', default=0)
@click.option('-m', '--max', 'max_datasets', type=int, help='Maximum datasets', default=100000000)
def setup_nodes(folder, start, max_datasets):
    folder = list(folder)
    api_manager.load_datasets(folder, start, max_datasets)

if __name__ == '__main__':
    cli()
    deploy()
    setup()
    validate()


import json
import math
import random
import argparse

from tqdm import tqdm

from deepref import config
from deepref.framework.train import Training
from deepref.dataset.dataset import Dataset

class CrossValidation():
    def __init__(self, dataset:Dataset, folds:int=10):
        self.dataset = dataset
        self.folds = folds
        self.training_sets_splitted = []
        self.validation_sets_splitted = []
        self.metrics = []

    def set_seed(self, seed):
        random.seed(seed)

    def split_random(self):
        self.set_seed(config.SEED)
        train_sentences = self.dataset.train_sentences + self.dataset.val_sentences
        random.shuffle(train_sentences)
        val_sentences_length = len(train_sentences) // self.folds
        for f in range(self.folds):
            self.validation_sets_splitted.append(train_sentences[f*val_sentences_length:(f+1)*val_sentences_length])
            self.training_sets_splitted.append(train_sentences[:f*val_sentences_length]+train_sentences[(f+1)*val_sentences_length:])

    def validate(self, hparams):
        self.split_random()
        accuracies, micro_f1, macro_f1 = [], [], []
        for f in tqdm(range(self.folds)):
            self.dataset.train_sentences = self.training_sets_splitted[f]
            self.dataset.val_sentences = self.validation_sets_splitted[f]

            assert (len(self.dataset.val_sentences) + len(self.dataset.train_sentences)) // self.folds == len(self.dataset.val_sentences)

            train = Training(self.dataset, hparams)
            result = train.train()
            accuracies.append(result["acc"])
            micro_f1.append(result["micro_f1"])
            macro_f1.append(result["macro_f1"])

        avg_acc = sum(accuracies) / self.folds
        sd_acc = math.sqrt(sum([math.pow(acc - avg_acc, 2) for acc in accuracies]) / self.folds)
        avg_micro_f1 = sum(micro_f1) / self.folds
        sd_micro_f1 = math.sqrt(sum([math.pow(m - avg_micro_f1, 2) for m in micro_f1]) / self.folds)
        avg_macro_f1 = sum(macro_f1) / self.folds
        sd_macro_f1 = math.sqrt(sum([math.pow(m - avg_macro_f1, 2) for m in macro_f1]) / self.folds)

        return {"acc": {"avg":avg_acc, "sd": sd_acc}, "micro_f1": {"avg": avg_micro_f1, "sd": sd_micro_f1}, "macro_f1": {"avg": avg_macro_f1, "sd": sd_macro_f1}}

if __name__ == '__main__':
    parser = argparse.ArgumentParser()

    # # Data
    parser.add_argument('-d','--dataset', default="semeval2010", choices=config.DATASETS,
                help='Dataset. If not none, the following args can be ignored')

    args = parser.parse_args()

    with open(config.HPARAMS_FILE_PATH.format(args.dataset), 'r') as f:
        hparams = json.load(f)

    dataset = Dataset(args.dataset)
    dataset.load_dataset_csv()

    cv = CrossValidation(dataset)
    results = cv.validate(hparams)
    print(results)


import cv2
import os
from os import path
from pathlib import Path

# filepath = '../../../projects/vode/CCD/Normal/000004.mp4'
filepath = '/Users/kimminchae/Desktop/CNN/k400/'
# vidcap = cv2.VideoCapture(filepath)

file_names = os.listdir('/Users/kimminchae/Desktop/CNN/k400/')
file_list = list(file_names)

for file in file_list:
    video_names = os.listdir('/Users/kimminchae/Desktop/CNN/k400/' + file + '/')
    video_list = list(video_names)
    for video in video_list:
        count = 0
        file_num = 0
        str = video.split('.')
        vidcap = cv2.VideoCapture(filepath + file + '/' + video)
        print(filepath + file + '/' + video)
        while(vidcap.isOpend()):

            ret, image = vidcap.read()

            if count % 2 == 0:
                dir_path = Path("../../../projects/vode/data/video_segment/kinetics400_100/test/" + file)
                if dir_path.is_dir() == True:
                    video_path = Path("../../../projects/vode/data/video_segment/kinetics400_100/test/" + file + '/' + str[0])
                    if video_path.is_dir() == True:
                        cv2.imwrite("../../../projects/vode/data/video_segment/kinetics400_100/test/" + file + '/' + str[0] + "/" + "%d.jpg" %file_num, image)
                        file_num += 1
                    else:
                        os.makedirs("../../../projects/vode/data/video_segment/kinetics400_100/test/" + file + '/' + str[0])
                        cv2.imwrite("../../../projects/vode/data/video_segment/kinetics400_100/test/" + file + '/' + str[0] + "/" + "%d.jpg" %file_num, image)
                        file_num += 1
                else:
                    os.makedirs("../../../projects/vode/data/video_segment/kinetics400_100/test/" + file)
                    os.makedirs("../../../projects/vode/data/video_segment/kinetics400_100/test/" + file + '/' + str[0])
                    cv2.imwrite("../../../projects/vode/data/video_segment/kinetics400_100/test/" + file + '/' + str[0] + "/" + "%d.jpg" %file_num, image)
                    file_num += 1
            count += 1

            if file_num == 100:
                print("Saved " + file + "Done")
                break


"""Some methods for loading and analysing spike trains."""
import pylab

def load_spikes_csv(spikefname, ch, unit):
  """
  Load the spike timestamps from a csv file. The file is expected to have three columns: channel, unit and timestamp
  (This is the default format that data is exported in from Plexon's offline sorter)

  Inputs:
    spikefname     - name of csv file
    ch             - channel number
    unit           - unit number
  Outputs:
    array          - pylab array of timestamps
  """
  sdata = pylab.csv2rec(spikefname, names=['channel','unit','timestamp'])
  idx = pylab.find((sdata['channel'] == ch) & (sdata['unit'] == unit))
  return sdata['timestamp'][idx]

def poisson_train(rate, duration):
  """Return time stamps from a simulated poisson process at given rate and over given duration. The granularity is 1ms.
  We break up duration into N bins of 1ms size. The probability of there being an event (spike) in a given bin is the
  same as the rate in kHz. We generate N uniformly distributed random numbers and use that to decide if a given bin has
  a spike or not.

  Inputs:
    rate - In Hz
    duration - in s
  Output:
    Array of time stamps in s
  """
  p = rate/1000.0 #Probablity is rate (s-1) * bin size (s)
  N = int(duration*1000) #One bin per ms
  r = pylab.random(N)
  idx = pylab.find(r < p)
  return idx/1000.

def correlated_poisson_train(rate, duration, r):
  """Return time stamps from two simulated poisson processes at given rates and over given duration.

  The granularity is 1ms
  Inputs:
    rate - In Hz
    duration - in s
  Output:
    Array of time stamps in s
  """

def section_spike_train(timestamps, start_times, zero_times, end_times):
  """Break up a spike train into sections based on the times passed.

  Inputs:
    Note: all time units should be in the same units as the timestamp time units

    timestamps  - timestamps of the spikes
    start_times - z x 1 Array of absolute start times
    zero_times  - z x 1 Array of absolute reference times
    end_times   - z x 1 Array of absolute end times

  Output:
    sections    - List of z arrays containing timestamps references to the zero_times
  """
  sections = [None] * len(zero_times)
  for n, (st,zt,et) in enumerate(zip(start_times, zero_times, end_times)):
    idx = pylab.find((timestamps > st) & (timestamps < et))
    sections[n] = timestamps[idx] - zt

  return sections

def window_spike_train(timestamps, start_time=0, zero_times=0, end_time=None, window_len=1, subwindow_len=None):
  """Break up a spike train into windows and subwindows marching outwards from zero_time.

  * = zero
  | = window boundary
  - = subwindow

  --|----|----|*|----|----|----|----|--

  Inputs:
    Note:
      1. All time units should be in the same units as the timestamp time units
      2. The zero_times should be in ascending order, otherwise the results will be wrong. The algorithm is made efficient by marching along the timestamps sequentially.

    timestamps - timestamps of the spikes
    start_time - time rel to zero_time we end our windows (needs to be <= 0).
                 If zero, means no pre windows.
                 If None, means prewindows stretch to begining of data
                 The start_time is extended to include an integer number of windows
    zero_times  - reference time. Can be a zx1 array, in which case will give us an array of windows. If scalar
                 will only give one set of windows.
    end_time   - time rel to zero_time we end our windows (needs to >= 0)
                 If zero, means no post-windows
                 If None, means post-windows stretch to end of data
                 The end_time is extended to include an integer number of windows
    window_len - Length of each window.
    subwindow_len - There can be multiple subwindows within a window
                    If subwindow_len is none, subwindow_len is made the same as window_len
  Output:
    window_edges - (w + 1 ) array of times, where w is the number of windows
    windows      - (z x w x 2) array of times.
                    z - number of epochs (size of zero_time array)
                    w - number of windows
                    0 - start idx of timestamps
                    1 - end idx of timestamps
                    If zero_time is a scalar, windows is 2D
    sub_windows  - (z x w x s x 2) array of times.
                    s - number of sub windows
                    If zero_time is a scalar, sub_windows is 3D
  """
  from math import ceil
  def march(timestamps, zero_time, start_idx, window_edges, subwindow_len, n_windows, n_sub_windows):
    """Repeatedly finding indexes from the same array that fit within the current window would be criminally
    inefficient. We make things a little less time consuming by keeping a running index.
    """
    window_edges_abs = window_edges + zero_time

    windows = pylab.ones((n_windows,2)) * -1
    subwindows = pylab.ones((n_windows,n_sub_windows,2)) * -1

    while timestamps[start_idx] <= window_edges_abs[0]:
      start_idx += 1
      if start_idx == timestamps.size:
        break

    end_idx = start_idx
    for widx in xrange(n_windows):
      if start_idx == timestamps.size:
        break
      window_start = window_edges_abs[widx]
      window_end = window_edges_abs[widx+1]
      twst = start_idx
      for swidx in xrange(n_sub_windows):
        if end_idx == timestamps.size:
          break
        subwindow_end = window_start + subwindow_len*(swidx+1)
        subwindow_end = min(window_end, subwindow_end) #This is needed so we synchronise the end of subwindows and windows
        while timestamps[end_idx] <= subwindow_end:
          end_idx += 1
          if end_idx == timestamps.size:
            break
        subwindows[widx, swidx, :] = [twst, end_idx]
        twst = end_idx

      windows[widx,:] = [start_idx,end_idx]
      start_idx = end_idx

    return window_edges, windows, subwindows, end_idx

  if subwindow_len is None:
    subwindow_len = window_len

  if pylab.isscalar(zero_times):
    zero_times = [zero_times]

  if start_time is None:
    start_time = timestamps[0] - max(zero_times)
  if end_time is None:
    end_time = timestamps[-1] - min(zero_times)

  n_pre_windows = int(ceil(-start_time / float(window_len)))
  n_post_windows = int(ceil(end_time / float(window_len)))
  n_windows = n_pre_windows + n_post_windows
  n_sub_windows = int(ceil(window_len / float(subwindow_len)))
  window_edges = (pylab.arange(n_windows+1) - n_pre_windows) * window_len

  all_windows = []
  all_subwindows = []
  start_idx = 0
  for this_zero_time in zero_times:
    window_edges, windows, subwindows, start_idx = march(timestamps, this_zero_time, start_idx, window_edges, subwindow_len, n_windows, n_sub_windows)
    all_windows.append(windows)
    all_subwindows.append(subwindows)

  all_windows = pylab.array(all_windows)
  all_subwindows = pylab.array(all_subwindows)

  return window_edges, all_windows, all_subwindows

def psth(timestamps, start_time=0, zero_times=0, end_time=None, bin_len=1):
  """Given the time stamps compute the peristimulus time histogram giving mean spikes per bin per epoch. The rate, of
  course, is simply the mean spike count divided by the bin size
  Inputs:
    timestamps - the spike timestamps
    start_time - time rel to zero_time we end our windows (needs to be <= 0).
                 If zero, means no pre windows.
                 If None, means prewindows stretch to begining of data
                 The start_time is extended to include an integer number of bins
    zero_times  - reference time. Can be a zx1 array, in which case will give us an array of windows. If scalar
                 will only give one set of windows.
    end_time   - time rel to zero_time we end our windows (needs to >= 0)
                 If zero, means no post-windows
                 If None, means post-windows stretch to end of data
                 The end_time is extended to include an integer number of bins
    bin_len    - size of bin
  Outputs:
    t - time vector
    be - bin edges
    meanhist - mean spike count/bin/epoch
    stdhist  - sd of the spike count/bin/epoch
    ratehist - meanhist/bin_len

  Can be plotted by doing pylab.plot(t, meanhist)
  """
  window_edges, windows, subwindows = window_spike_train(timestamps, start_time, zero_times, end_time, window_len=bin_len)
  bins = pylab.linspace(0, range, nbins+1) #We are doing bin edges

  isihist = pylab.zeros((windows.shape[1], nbins))
  for m in xrange(windows.shape[0]):
    for n in xrange(windows.shape[1]):
      hist,be = pylab.histogram(isi[windows[m,n,0]:windows[m,n,1]], bins, density=True)
      isihist[n,:] += hist

  t = (window_edges[1:] + window_edges[:-1])/2
  return t, be, isihist/windows.shape[0]

def isi_histogram(timestamps, start_time=0, zero_times=0, end_time=None, window_len=1, range=.2, nbins=11):
  """Given the time stamps compute the isi histogram with a jumping window.
  Inputs:
    timestamps - the spike timestamps
    start_time - time rel to zero_time we end our windows (needs to be <= 0).
                 If zero, means no pre windows.
                 If None, means prewindows stretch to begining of data
                 The start_time is extended to include an integer number of windows
    zero_times  - reference time. Can be a zx1 array, in which case will give us an array of windows. If scalar
                 will only give one set of windows.
    end_time   - time rel to zero_time we end our windows (needs to >= 0)
                 If zero, means no post-windows
                 If None, means post-windows stretch to end of data
                 The end_time is extended to include an integer number of windows
    window_len - length of window to look at isi (in same units as time stamps)
    range - maximum isi
    nbins - number of bins in the histogram
  Outputs:
    t - time vector
    be - bin edges
    isihist - the histogram matrix. Normalized for each time slice

  (Can be plotted by doing pylab.pcolor(t, be, isihist.T,vmin=0,vmax=1, cmap=pylab.cm.gray_r))
  """
  window_edges, windows, subwindows = window_spike_train(timestamps, start_time, zero_times, end_time, window_len=window_len)
  isi = pylab.diff(timestamps)

  if windows.shape[1]:
    windows[:,-1,1] -= 1 #we have one less isi sample than timestamps

  bins = pylab.linspace(0, range, nbins+1) #We are doing bin edges

  isihist = pylab.zeros((windows.shape[1], nbins))
  for m in xrange(windows.shape[0]):
    for n in xrange(windows.shape[1]):
      hist,be = pylab.histogram(isi[windows[m,n,0]:windows[m,n,1]], bins, density=True)
      isihist[n,:] += hist

  t = (window_edges[1:] + window_edges[:-1])/2
  return t, be, isihist/windows.shape[0]

def spikecv(timestamps, start_time=0, zero_times=0, end_time=None, window_len=.1):
  """Given the time stamps compute the coefficient of variation with a jumping window.
  Returns cv and rate as an array.
  Inputs:
    timestamps - the spike timestamps
    start_time - time rel to zero_time we end our windows (needs to be <= 0).
                 If zero, means no pre windows.
                 If None, means prewindows stretch to begining of data
                 The start_time is extended to include an integer number of windows
    zero_times  - reference time. Can be a zx1 array, in which case will give us an array of windows. If scalar
                 will only give one set of windows.
    end_time   - time rel to zero_time we end our windows (needs to >= 0)
                 If zero, means no post-windows
                 If None, means post-windows stretch to end of data
                 The end_time is extended to include an integer number of windows
    window_len - length of window to look at spikes (in same units as time stamps)

  Outputs:
    t  - time of the center of the window
    cv
    rate - in inverse units of timestamp
  """

  window_edges, windows, subwindows = window_spike_train(timestamps, start_time, zero_times, end_time, window_len=window_len)
  isi = pylab.diff(timestamps)
  if windows.shape[1]:
    windows[:,-1,1] -= 1 #we have one less isi sample than timestamps

  t = pylab.zeros(windows.shape[1])
  cv = pylab.zeros(windows.shape[1])
  rate = pylab.zeros(windows.shape[1])

  for n in xrange(windows.shape[1]):
    collected_isi = pylab.array([])
    for m in xrange(windows.shape[0]):
      #CV computation
      collected_isi = pylab.concatenate((collected_isi, isi[windows[m,n,0]:windows[m,n,1]]))

    if collected_isi.size > 0:
      mean = collected_isi.mean()
      std = collected_isi.std()
      cv[n] = std/mean
      rate[n] = 1./mean
    else:
      cv[n] = 0
      rate[n] = 0

    #t[n] = window_len * (n + .5)
  t = (window_edges[1:] + window_edges[:-1])/2
  return t, cv, rate

def spikefano(timestamps, start_time=0, zero_times=0, end_time=None, window_len=.1, subwindow_len=None):
  """Given the time stamps compute the fano factor with a jumping window.
  Inputs:
    timestamps - the spike timestamps
    window_len - length of window to look at ff (same units as timestamps). One window gets us one ff estimate
                 The fano factor is the LS fit of fano_windows (variance,mean) points
    subwindow_len - length of one spike count computation window

  Outputs:
    t   - time array
    ff  - fano factors
  """
  window_edges, windows, subwindows = window_spike_train(timestamps, start_time, zero_times, end_time, window_len=window_len, subwindow_len=subwindow_len)
  t = pylab.zeros(windows.shape[1])
  ff = pylab.zeros(windows.shape[1])
  for n in xrange(windows.shape[1]):
    spk_count = pylab.zeros(subwindows.shape[1]*subwindows.shape[2])
    for m in xrange(subwindows.shape[0]):#Epochs
      for l in xrange(subwindows.shape[2]):#Subwindows
        #FF computation
        sbw0 = subwindows[m,n,l,0]
        sbw1 = subwindows[m,n,l,1]
        spk_count[m*subwindows.shape[2]+l] = sbw1 - sbw0

    mean = spk_count.mean()
    std = spk_count.std()
    ff[n] = std**2/mean
    t[n] = window_len * (n+.5)

  return t, ff

def spike_triggered_histogram(tsA, tsB, window_len, range, nbins):
  """Given two spike trains compute their spike triggered spike histogram.
  Inputs:
    tsA, tsB - the two spike train timestamps. tsA is the reference train
    window_len - length of window over which to compute the histogram
    range - the time range over which to compute the histogram
    nbins - how many bins to make the histogram
  Outputs:
    t - time vector
    be - bin edges
    spkhist - the histogram matrix. Normalized for each time slice

  (Can be plotted by doing pylab.pcolor(t, be, spkhist.T,vmin=0,vmax=1, cmap=pylab.cm.gray_r))
  """

  bins = pylab.linspace(range[0], range[1], nbins+1) #We are doing bin edges
  epochs = window_spike_train(tsA, window_len)

  idxBlo = 0 #Just a device to help us speed up operations
  idxBhi = 0
  t = pylab.zeros(len(epochs))
  spkhist = pylab.zeros((len(epochs), nbins))
  for n, epoch in enumerate(epochs):
    #Cycle through timestamps in this window
    thishist = pylab.zeros(nbins)
    these_ts = tsA[epoch[0]:epoch[1]]
    for j in xrange(these_ts.size):
      this_ts = these_ts[j]
      while (tsB[idxBlo] - this_ts > range[0]) & (idxBlo > 0):
        idxBlo -= 1
      while (tsB[idxBlo] - this_ts < range[0]) & (idxBlo < tsB.size - 1):
        idxBlo += 1
      while (tsB[idxBhi] - this_ts > range[1]) & (idxBhi > 0):
        idxBhi -= 1
      while (tsB[idxBhi] - this_ts < range[1]) & (idxBhi < tsB.size - 1):
        idxBhi += 1
      h,be = pylab.histogram(tsB[idxBlo:idxBhi+1] - this_ts, bins)
      thishist += h
    thishist /= thishist.max()
    spkhist[n,:] = thishist
    t[n] = window_len * (n + .5)

  return t, be, spkhist

def spikecount_correlation(tsA, tsB, start_time=0, zero_times=0, end_time=None, window_len=.1, subwindow_len=None):
  """Given the time stamps compute the spike count correlation with a jumping window.
  Inputs:
    tsA, tsB - the two spike train timestamps.
    start_time - time rel to zero_time we end our windows (needs to be <= 0).
                 If zero, means no pre windows.
                 If None, means prewindows stretch to begining of data
                 The start_time is extended to include an integer number of windows
    zero_times  - reference time. Can be a zx1 array, in which case will give us an array of windows. If scalar
                 will only give one set of windows.
    end_time   - time rel to zero_time we end our windows (needs to >= 0)
                 If zero, means no post-windows
                 If None, means post-windows stretch to end of data
                 The end_time is extended to include an integer number of windows
    window_len - length of window to look at isi (in same units as time stamps)
    subwindow_len - length of one spike count computation window

  Outputs:
    t  - time array
    r  -  the correlation vector
  """
  def correl_single_window(sbwA, sbwB):
    """sbwA and sbwB are obtained as subwindowsA[:,n,:,:], with n marching through all the windows.
    Indexes - 0 -> epochs
              1 -> subwindows
              2 -> start/stop

    """
    N0 = sbwA.shape[0]
    N1 = sbwA.shape[1]
    spk_countA = pylab.zeros((N0,N1))
    spk_countB = pylab.zeros((N0,N1))
    for n in xrange(N0): #Epochs
      for m in xrange(N1): #subwindows
        spk_countA[n,m] = sbwA[n,m,1] - sbwA[n,m,0]
        spk_countB[n,m] = sbwB[n,m,1] - sbwB[n,m,0]

    spk_countA = spk_countA.flatten() - spk_countA.mean()
    spk_countB = spk_countB.flatten() - spk_countB.mean()
    R = pylab.corrcoef(spk_countA, spk_countB)
    if R.size:
      r = R[0,1]
    else:
      r = 0
    return r

  window_edgesA, windowsA, subwindowsA =\
    window_spike_train(tsA, start_time=start_time, zero_times=zero_times, end_time=end_time, window_len=window_len, subwindow_len=subwindow_len)
  window_edgesB, windowsB, subwindowsB =\
    window_spike_train(tsB, start_time=start_time, zero_times=zero_times, end_time=end_time, window_len=window_len, subwindow_len=subwindow_len)

  #The only time we will have different numbers of windows is when zero_times is scalar, end_time is None and the two
  #trains are of different lengths
  wmin = min(windowsA.shape[1],windowsB.shape[1])
  #print wmin
  r = pylab.zeros(wmin)
  for n in xrange(wmin):
    #computation of r
    sbwA = subwindowsA[:,n,:,:]
    sbwB = subwindowsB[:,n,:,:]
    r[n] = correl_single_window(sbwA, sbwB)

  t = (window_edgesA[1:] + window_edgesA[:-1])/2
  return t, r

if __name__ == "__main__":
  zeros = pylab.arange(2, 40, 4)
  ts = pylab.array([])
  #Test window_spike_train, repeated several times
  #1 second silence
  #1 second 100Hz fixed
  #1 second silence
  #1 second 100Hz poisson
  for n in xrange(zeros.size):
    tsf = pylab.arange(0,1,.01) + zeros[n] - 1 #100 points spaced at .01 with 500ms of silence at the start
    tsp = poisson_train(rate=100, duration=1) + zeros[n] + 1
    ts = pylab.concatenate((ts,tsf,tsp))

  for start_time,zero_time,end_time in zip([0,-2],[0, zeros],[None,2]):
    pylab.figure()
    t, be, isihist = isi_histogram(ts, start_time=start_time, zero_times=zero_time, end_time=end_time, window_len=.1, range=.02, nbins=21)
    pylab.subplot(4,1,1)
    pylab.pcolor(t, be, isihist.T,vmin=0,vmax=1, cmap=pylab.cm.gray_r)
    pylab.ylabel('isi')
    t, cv, rate = spikecv(ts, start_time=start_time, zero_times=zero_time, end_time=end_time, window_len=.1)
    pylab.subplot(4,1,2)
    pylab.plot(t,cv)
    pylab.ylabel('cv')
    pylab.setp(pylab.gca(), 'xlim', [0, t.max()], 'ylim', [0,2])
    pylab.subplot(4,1,3)
    pylab.plot(t,rate)
    pylab.ylabel('Hz')
    pylab.setp(pylab.gca(), 'xlim', [0, t.max()], 'ylim', [0,200])
    t, ff = spikefano(ts, start_time=start_time, zero_times=zero_time, end_time=end_time, window_len=.1, subwindow_len=.005)
    pylab.subplot(4,1,4)
    pylab.plot(t,ff)
    pylab.ylabel('FF (s)')
    pylab.setp(pylab.gca(), 'xlim', [0, t.max()], 'ylim', [0,2])


#같은 크기의 이미지 블렝딩 실험

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

large_img = cv2.imread("./ex_image.png")
watermark = cv2.imread("./ex_image_logo.png")

print("large_image_size >> ", large_img.shape)
print("watermark image size >>", watermark.shape)

# cv2.imshow("image large", large_img)
# cv2.imshow("watermark", watermark)
# cv2.waitKey(0)

img1 = cv2.resize(large_img, (800,600))
img2 = cv2.resize(watermark, (800,600))

print("img1 resize >>", img1.shape)
print("img2 resize >>", img2.shape)

#혼합 진행
blended = cv2.addWeighted(img1, 1, img2, 1, 0)
cv2.imshow("image show", blended)
cv2.waitKey(0)


import logging
import argparse
import time
from threading import Thread
from mujoco_viewer import MujocoViewer
import sys
import pathlib
parent = pathlib.Path(__file__).parent.resolve()
sys.path.insert(1, str(parent))
sys.path.insert(1, str(parent / 'src'))
sys.path.insert(1, str(parent / 'src/optimisers'))
import utils
from src.optimisers.discovered_optimisers import all_optimisers
from src.panda import Panda
from src.results import ModelReductionResult

def reset_simulation():
    simulator.reset()
    mujoco_viewer.data = simulator.data
    mujoco_viewer.model = simulator.model

def infinitely_execute_trajectory_in_simulation(trajectory):
    while not keyboard_interrupted:
        reset_simulation()
        for arm_controls, gripper_controls in trajectory:
            while is_paused and not keyboard_interrupted:
                if keyboard_interrupted:
                    return
                continue
            simulator.execute_control(arm_controls, gripper_controls)
            time.sleep(simulator.timestep)
        time.sleep(1)

def visualise(trajectory):
    global keyboard_interrupted, mujoco_viewer
    keyboard_interrupted = False

    mujoco_viewer = MujocoViewer(simulator.model, simulator.data, width=700,
                                 height=500, title=f'Solving {args.model_filename}',
                                 hide_menus=True)

    main_thread = Thread(target=infinitely_execute_trajectory_in_simulation, args=(trajectory,))
    main_thread.start()

    global is_paused
    is_paused = False
    try:
        while mujoco_viewer.is_alive:
            is_paused = mujoco_viewer._paused
            mujoco_viewer.render()
            if args.show_names:
                utils.draw_object_names(mujoco_viewer, simulator)
    except KeyboardInterrupt:
        print('Quitting')

    keyboard_interrupted = True
    mujoco_viewer.close()
    main_thread.join()

def arg_parser():
    available_planners = ", ".join(list(all_optimisers.keys()))

    parser = argparse.ArgumentParser(description='Trajectory Optimiser Demo')
    parser.add_argument('model_filename', help='file name of the MuJoCo model to load.')
    parser.add_argument('optimiser_name', help=f'provide optimiser name (options: {available_planners}).')
    parser.add_argument('-g', '--group-num', type=int, default=5, help=f'number of objects in group')
    parser.add_argument('-s', '--save', action='store_true', help='save results and optimised trajectory to disk.')
    parser.add_argument('-v', '--view-solution', action='store_true', help='visualise the final trajectory.')
    parser.add_argument('-i', '--view-initial', action='store_true', help='visualise the initial trajectory.')
    parser.add_argument('-n', '--show-names', action='store_true', help='visualise the initial trajectory.')
    parser.add_argument('--debug', action='store_true', help='run in debug mode, printing useful information to screen.')

    return parser.parse_args()

if __name__ == '__main__':
    args = arg_parser()

    keyboard_interrupted, mujoco_viewer = None, None

    logging_level = logging.DEBUG if args.debug else logging.ERROR
    logging.basicConfig(level=logging_level, format='%(message)s')

    # Create simulator from model_filename with a Robot class instance.
    simulator = utils.create_simulator(args.model_filename, Panda)

    # Factory for generating an optimiser from the optimiser_name using the
    # `simulator` object as the base simulator for the optimisation. Optimiser will
    # create copies of the `simulator` and will not change the state of that
    # specific object during optimisation.
    trajectory_optimiser = utils.optimiser_factory(args.optimiser_name, simulator)

    if args.group_num:
        trajectory_optimiser.group_size = args.group_num

    if args.view_initial:
        visualise(trajectory_optimiser.initial_trajectory)
    else:
        initial_trajectory = trajectory_optimiser.initial_trajectory
        optimisation_result = trajectory_optimiser.optimise(initial_trajectory)
        utils.print_optimisation_result(optimisation_result)

        if args.save:
            utils.save_data_to_file(args.model_filename, optimisation_result)
        if args.view_solution:
            visualise(optimisation_result.models[-1].best_trajectory)


from machine import Pin, PWM, Timer, ADC, unique_id
import dht
import _thread
from umqtt.simple import MQTTClient
import ubinascii

#already imported on boot.py
#import time
#from network import WLAN

# screen /dev/tty.usbserial-01E4EE42  115200
# screen /dev/tty.usbserial-01E4EDCA  115200
# ampy --port /dev/tty.usbserial-01E4EE42 --baud 115200 put boot.py
# ampy --port /dev/tty.usbserial-01E4EDCA --baud 115200 put boot.py
# ampy --port /dev/tty.usbserial-01E4EDCA --baud 115200 put main.py

ldr   = ADC(Pin(34))
soil  = ADC(Pin(33))
relay = Pin(23, mode=Pin.OUT)
sev   = Pin(22, mode=Pin.OUT)
led   = Pin(13, mode=Pin.OUT)
d     = dht.DHT11(Pin(32))

ldr.atten (ADC.ATTN_11DB)       #Full range: 3.3v
soil.atten(ADC.ATTN_11DB)       #Full range: 3.3v

def led_flash():
  for x in range(1,10):
    led(1)
    time.sleep(0.2)
    led(0)
    time.sleep(0.2)

led_flash()

def pump(t):    #t=time of watering
    relay(1)
    time.sleep(t)
    relay(0)

def LDR_get():  #return LDR reading
  return ldr.read()

def Soil_get(): #return soil moisture
  return soil.read()

def rotate(n,t):   #rotate the plant n degree
  sevro=PWM (sev,freq=100)
  if n== 1:
    sevro.duty(90)
  else:
    sevro.duty(180)
  time.sleep(t/10)
  sevro.duty(0)

def get_temp(): #return air temp
  try:
    d.measure()
    return d.temperature()
  except OSError:
    print("OSError,will return 20")
    return 20
def get_humidity(): #return humidity
  try:
    d.measure()
    return d.humidity()
  except OSError:
    print("OSError,will return 50%")
    return 50

DLTS_P=1/43200
SOIL_P=1/4096
TEMP_P=1/20
CONS_O=4

MQTT_watered=False
MQTT_rotated=False

dlt=0 #s
h,m,s=8,54,0#daily watering time and reset dlt

def daily_light_time(valve=3400): #valve is around 3000
  global dlt
  while True:
    if LDR_get()>valve:
      dlt+=1
      time.sleep(1)
      print("today's light time = ",dlt,"s")

# I call it quaternary control，what a genius idea!
position =0
counter  =0

def auto_rotate(count=3,delay=3600):
  global position
  global counter
  global MQTT_rotated
  if counter < count:
    counter+=1
  else:
    counter=0
    time.sleep(delay)#will rotate after 1h
    if position <3:
      rotate(0,1)
      position+=1
    else:
      rotate(1,14) #back to start position
      position=0
    MQTT_rotated=True
  #print(counter,position)

def daily_watering():
  global dlt,MQTT_watered
  while True:
    time.sleep(0.5)#reduce loop times
    if time.localtime()[3]==h and time.localtime()[4]==m and time.localtime()[5]==s:
      time_watering=Soil_get()*SOIL_P + get_temp()*TEMP_P + dlt * DLTS_P + CONS_O
      pump(time_watering)
      dlt=0
      print("dlt reset!")
      MQTT_watered=True
      auto_rotate()

def update_watering_time(t):
  global h,m,s
  s=t%100
  m=t//100%100
  h=t//10000%100
  print('Watering time updated! New watering time is ',h,m,s)

def update_DLTS(DLTS):
  global DLTS_P
  DLTS_P=1/DLTS
  print('DLT Parameter updated, New parameter is',DLTS_P)

def update_SOIL(SOIL):
  global SOIL_P
  SOIL_P=1/SOIL
  print('SOIL Parameter updated, New parameter is',SOIL_P)

def update_TEMP(TEMP):
  global TEMP_P
  TEMP_P=1/TEMP
  print('TEMP Parameter updated, New parameter is',TEMP_P)

def update_CONS(CONS):
  global CONS_O
  CONS_O=CONS
  print('CONS Parameter updated, New parameter is',CONS_O)

#MQTT
mqtt_server = '192.168.100.4' #192.168.100.4
client_id = ubinascii.hexlify(unique_id())
topic_pub = b'pot_log'

topic_time= b'pot_time'
topic_dlts= b'pot_dlts'
topic_soil= b'pot_soil'
topic_temp= b'pot_temp'
topic_cons= b'pot_cons'

def sub_cb(topic, msg):
  print((topic, msg))
  if topic == topic_time:
    update_watering_time(int.from_bytes(msg,"big"))
  if topic == topic_dlts:
    update_DLTS(int.from_bytes(msg,"big"))
  if topic == topic_soil:
    update_SOIL(int.from_bytes(msg,"big"))
  if topic == topic_temp:
    update_TEMP(int.from_bytes(msg,"big"))
  if topic == topic_cons:
    update_CONS(int.from_bytes(msg,"big"))

  """
  # declaring byte value
  byte_val = b'\x00\x01'
  # converting to int
  # byteorder is big where MSB is at start
  int_val = int.from_bytes(byte_val, "big")
  # printing int equivalent
  print(int_val)
  """

def connect_and_subscribe():
  global client_id, mqtt_server
  global topic_cons, topic_soil, topic_temp, topic_time,topic_dlts
  client = MQTTClient(client_id, mqtt_server)
  client.set_callback(sub_cb)
  client.connect()
  client.subscribe(topic_time)
  client.subscribe(topic_dlts)
  client.subscribe(topic_soil)
  client.subscribe(topic_temp)
  client.subscribe(topic_cons)
  print('Connected to %s MQTT broker' % mqtt_server)
  return client

def mqtt_thread():
  global MQTT_watered,MQTT_rotated
  last_log = 0
  message_interval = 5 #1800 # send current soil moistrue and ldr reading to mqtt server every 30 min
  while True:
    try:
      client = connect_and_subscribe()
      while True:
        try:
          client.check_msg()
          if (time.time() - last_log) > message_interval:
            msg = b'Soil Moisture :%d' % Soil_get() + b'Light :%d' % LDR_get() + b'Light times:%d' % dlt
            client.publish(topic_pub, msg)
            last_log = time.time()
          if MQTT_watered:
            msg = b'Watered'
            client.publish(topic_pub, msg)
            MQTT_watered=False
          if MQTT_rotated:
            msg = b'Rotated'
            client.publish(topic_pub, msg)
            MQTT_rotated=False
        except OSError as e:
          print("Error: disconnected")
          break
    except OSError as e:
      print('Failed to connect to MQTT broker. Reconnecting...')
    time.sleep(1)

thread1= _thread.start_new_thread(daily_light_time, ())
if wlan.isconnected():
  thread2= _thread.start_new_thread(mqtt_thread,())
daily_watering() #watering thread


"""
Python implementation of
insertion sort algorithm.

Running time: O(n**2)
"""

def insertion_sort(alist):
   for index in range(1, len(alist)):

     current_val = alist[index]
     pos = index

     while pos > 0 and alist[pos - 1] > current_val:
         alist[pos]=alist[pos - 1]
         pos = pos - 1

     alist[pos ] = current_val


import pandas as pd

# Read the first CSV file
movies_df = pd.read_csv('data/movies.csv')

# Read the second CSV file
ratings_df = pd.read_csv('data/ratings.csv')

# Merge the two dataframes based on the movieId column
merged_df = pd.merge(ratings_df, movies_df[['movieId', 'title']], on='movieId', how='left')

# Rename the movieId column to title
merged_df.rename(columns={'title': 'movie_title'}, inplace=True)

# remove uneeded columns
merged_df.drop(["timestamp"], axis=1, inplace=True)

# reduce size
merged_df = merged_df[(merged_df['movieId'] >= 1) & (merged_df['movieId'] <= 1000)]

# Save the merged dataframe to a new CSV file
merged_df.to_csv('data/merged_ratings.csv', index=False)


#
import matplotlib.pyplot as plt
import pandas as pd

from dir_balance_sheet.balance_sheet import BSesRead
from errorhandler import Error, ErrorList
from widget_helper import Result, Graph, DisplayInfo

class AnalysisBS:
    def __init__(self, di: DisplayInfo, read_type: str):
        self.result = Result()
        self.di = di
        # Get Balance Sheet data
        self.bs_collection = BSesRead(di, read_type)
        if self.bs_collection.result.exec_continue:
            print('Balance Sheet Data (' + str(self.bs_collection.result.result_data) + ') set completed!')
            # Prepare Result Class
            self.result = Result()
        else:
            pass

    # class Inquiry:
    def inquiry(self) -> Result:
        self.result.action_name = 'Inquiry Balance Sheet'
        self.result.result_type = 'dataframe'
        self.result.result_data = self.bs_collection.bses.get(self.di.company + '.T')
        if self.result.exec_continue is False:
            er = Error(ValueError, self.di.company, 'Hit No Data')
            e_list = ErrorList().add_list(er)
            self.result.error_list = e_list
            self.result.exec_continue = False
        # result.to_excel('./test.xlsx')
        return self.result

    # class Graph:
    def analysis_graph(self, di):
        bs = self.bs_collection.bses.get(di.company + '.T')

        # Calc Profit Ratio
        ratio_1 = bs.T['Total Stockholder Equity'] / bs.T['Total Assets'] * 100  # 自己資本比率
        ratio_2 = bs.T['Total Current Assets'] / bs.T['Total Current Liabilities'] * 100  # 流動比率

        print("Ratio 1")
        print(ratio_1)
        print('Ratio 2')
        print(ratio_2)

        # Generate Graph
        x = ratio_1.index
        y_1 = ratio_1.values
        y_2 = ratio_2.values

        fig, ax = plt.subplots()
        ax.set_title('Ratio Graph')
        ax.set_xlabel('Date')
        ax.set_ylabel('Percentage')
        ax.plot(x, y_1, label='Capital adequacy ratio')
        ax.plot(x, y_2, label='Current ratio')
        ax.legend()
        plt.show()

    def generate_ranking(self):
        ratios_1 = self.bs_collection.total_stockholder_equity / \
                   self.bs_collection.total_assets * 100  # 自己資本比率
        ratios_2 = self.bs_collection.total_current_assets / \
                   self.bs_collection.total_current_liabilities  # 流動比率

        average_pr1 = ratios_1.mean(numeric_only=True)
        average_pr2 = ratios_2.mean(numeric_only=True)
        average_pr = pd.DataFrame()
        average_pr.insert(0, 'Capital adequacy ratio', average_pr1)
        average_pr.insert(1, 'Current Ratio', average_pr2)
        average_pr = average_pr.sort_values('Capital adequacy ratio', ascending=False)
        average_pr = average_pr.head(10)

        print(average_pr)

        # generate Graph Object
        g = Graph()
        g.set_title('Capital Adequacy Ratio Ranking Graph (Top10)')
        # bar1
        g.set_x_label('Company')
        g.set_y_label('Average %')
        g.set_data_label('Capital adequacy ratio')
        g.set_data(average_pr['Capital adequacy ratio'])
        # bar2
        g.set_x_label('Company')
        g.set_y_label('Average %')
        g.set_data_label('Current Ratio (1/100)')
        g.set_data(average_pr['Current Ratio'])

        # Generate Result Class
        self.result.action_name = 'generate Capital Adequacy Ratio ranking'
        self.result.result_type = 'bar graph'
        self.result.result_data = g
        self.result.exec_continue = True
        return self.result


#!/usr/bin/env python3

def paper_needed(l, w, h):
    print(f"paper_needed: Got l={l}, w={w}, h={h}")
    sides = [l*w, w*h, h*l]
    return 2 * sum(sides) + min(sides)

def ribbon_needed(l, w, h):
    print(f"ribbon_needed: Got l={l}, w={w}, h={h}")
    # The ribbon needed is the perimeter of the smallest face, plus
    # a length equal to the volume for the bow.
    return 2 * (l + w + h) - 2 * max([l, w, h]) + l * w * h

def sum_dimensions(f):
    with open("input.txt") as input_file:
        return sum(
            map(
                lambda x: f(*x),
                map(
                    lambda x: map(int, x.strip().split("x")),
                    input_file,
                ),
            ),
        )

def main():
    print(f"Total wrapping paper needed: {sum_dimensions(paper_needed)} sq. ft.")
    print(f"Ribbon needed: {sum_dimensions(ribbon_needed)} ft.")

if __name__ == "__main__":
    main()


from urllib import urlencode

from twisted.internet.defer import inlineCallbacks, returnValue

from zope.interface import implements

from vumi.errors import VumiError
from vumi.tests.helpers import IHelper, generate_proxies
from vumi.transports.tests.helpers import TransportHelper
from vumi.utils import http_request_full

class HttpRpcTransportHelperError(VumiError):
    """Error raised when the HttpRpcTransportHelper encouters an error."""

class HttpRpcTransportHelper(object):
    """
    Test helper for subclasses of
    :class:`~vumi.transports.httprpc.HttpRpcTransport`.

    Adds support for making HTTP requests to the HTTP RPC transport to the
    base :class:`~vumi.transports.tests.helpers.TransportHelper`.

    :param dict request_defaults: Default URL parameters for HTTP requests.

    Other parameters are the same as for
    :class:`~vumi.transports.tests.helpers.TransportHelper`.
    """

    implements(IHelper)

    def __init__(self, transport_class, use_riak=False, request_defaults=None,
                 **msg_helper_args):
        self._transport_helper = TransportHelper(
            transport_class, use_riak=use_riak, **msg_helper_args)

        if request_defaults is None:
            request_defaults = {}
        self.request_defaults = request_defaults
        self.transport_url = None

        generate_proxies(self, self._transport_helper)

    def setup(self, *args, **kw):
        return self._transport_helper.setup(*args, **kw)

    def cleanup(self):
        return self._transport_helper.cleanup()

    @inlineCallbacks
    def get_transport(self, config, cls=None, start=True):
        transport = yield self._transport_helper.get_transport(
            config, cls=cls, start=True)
        self.transport_url = transport.get_transport_url(config['web_path'])
        returnValue(transport)

    def mk_request_raw(self, suffix='', params=None, data=None, method='GET'):
        """
        Make an HTTP request, ignoring this helper's ``request_defaults``.

        :param str suffix: Suffix to add to the transport's URL.
        :param dict params: A dictionary of URL parameters to append to the URL
                            as a query string or None for no URL parameters.
        :param str data: Request body or None for no request body.
        :param str method: HTTP method to use for the request.

        :raises HttpRpcTransportHelperError:
            When invoked before calling :meth:`get_transport`.
        """
        if self.transport_url is None:
            raise HttpRpcTransportHelperError(
                "call .get_transport() before making HTTP requests.")
        url = self.transport_url + suffix
        if params is not None:
            url += '?%s' % urlencode(params)
        return http_request_full(url, data=data, method=method)

    def mk_request(self, _suffix='', _data=None, _method='GET', **kw):
        """
        Make an HTTP request.

        :param str _suffix: Suffix to add to the transport's URL.
        :param str _data: Request body or None for no request body.
        :param str _method: HTTP method to use for the request.
        :param \*\*kw: URL query string parameters.

        :raises HttpRpcTransportHelperError:
            When invoked before calling :meth:`get_transport`.

        The ``_`` prefixes on the function parameter names are to
        make accidental clashes with URL query parameter names less
        likely.
        """
        params = self.request_defaults.copy()
        params.update(kw)
        return self.mk_request_raw(
            suffix=_suffix, params=params, data=_data, method=_method)


#!/usr/bin/python3
from sympy import *
import matplotlib.pyplot as plt
import re
import math
import numpy as np
import time
np.set_printoptions(suppress=True)

x = Symbol('x')
b = Function('b')(x)
g = Function('g')(x)

def new_coef(gamma, beta, coef_minus2, coef_minus1, coef):
    return expand(simplify(gamma*coef_minus2 + beta*coef_minus1 + 2*gamma*coef_minus1.diff(x)\
            +beta*coef.diff(x)+gamma*coef.diff(x,2)))
def new_coef_first(gamma, beta, coef):
    return expand(simplify(beta*coef.diff(x)+gamma*coef.diff(x,2)))
def new_coef_second(gamma, beta, coef_minus1, coef):
    return expand(simplify(beta*coef_minus1 + 2*gamma*coef_minus1.diff(x)\
            +beta*coef.diff(x)+gamma*coef.diff(x,2)))
def new_coef_last(gamma, beta, coef_minus2):
    return lambda x: gamma(x)*coef_minus2(x)
def new_coef_last(gamma, beta, coef_minus2):
    return expand(simplify(gamma*coef_minus2 ))
def new_coef_second_to_last(gamma, beta, coef_minus2, coef_minus1):
    return expand(simplify(gamma*coef_minus2 + beta*coef_minus1 + 2*gamma*coef_minus1.diff(x)))

def set_to_zero(expression):
    expression = expression.subs(Derivative(b, x, x, x), 0)
    expression = expression.subs(Derivative(b, x, x), 0)
    expression = expression.subs(Derivative(g, x, x, x, x), 0)
    expression = expression.subs(Derivative(g, x, x, x), 0)
    return expression

def sum_of_coef(expression):
    sum_of_coef = 0
    for i in str(expression).split(' + '):
        if i[0:1] == '(':
            i = i[1:]
        integers = re.findall(r'\b\d+\b', i)
        if len(integers) > 0:
            length_int = len(integers[0])
            if i[0:length_int] == integers[0]:
                sum_of_coef += int(integers[0])
            else:
                sum_of_coef += 1
        else:
            sum_of_coef += 1
    return sum_of_coef
power = 4
charar = np.zeros((power, power*2), dtype=Symbol)
coef_sum_array = np.zeros((power, power*2))
charar[0,0] = b
charar[0,1] = g
coef_sum_array[0,0] = 1
coef_sum_array[0,1] = 1
for i in range(1, power):
    #print(i)
    for j in range(0, (i+1)*2):
        #print(j, ':')
        #start_time = time.time()
        if j == 0:
            charar[i,j] = set_to_zero(new_coef_first(g, b, charar[i-1, j]))
        elif j == 1:
            charar[i,j] = set_to_zero(new_coef_second(g, b, charar[i-1, j-1], charar[i-1, j]))
        elif j == (i+1)*2-2:
            charar[i,j] = set_to_zero(new_coef_second_to_last(g, b, charar[i-1, j-2], charar[i-1, j-1]))
        elif j == (i+1)*2-1:
            charar[i,j] = set_to_zero(new_coef_last(g, b, charar[i-1, j-2]))
        else:
            charar[i,j] = set_to_zero(new_coef(g, b, charar[i-1, j-2], charar[i-1, j-1], charar[i-1, j]))
        #print("--- %s seconds for expression---" % (time.time() - start_time))
        #start_time = time.time()
        coef_sum_array[i,j] = sum_of_coef(charar[i,j])
        #print("--- %s seconds for coeffiecients---" % (time.time() - start_time))

pprint(coef_sum_array)


#!/usr/bin/python3

from sys import argv

def argument():
    arg_str = "arguments"
    ifna = "."
    length = len(argv) - 1
    if (length == 1):
        arg_str = "argument"
    if (length - 1 >= 0):
        ifna = ":"
    print("{} {}{}".format(length, arg_str, ifna))

    for index, arg in enumerate(argv):
        if (index > 0):
            print("{}: {}".format(index, arg))

if __name__ == "__main__":
    argument()


# Standard library
from __future__ import division
import re
import os
from io import StringIO
from math import exp
from collections import namedtuple
import timeit
import json
import itertools

# Conda packages
import pandas
import scipy.spatial.distance
import numpy as np
import matplotlib.pyplot as plt

# From https://doi.org/10.1039/b801115j
# Covalent radii in angstrom, used to determine bonding
covalent_radius = {
    'H':0.31,
    'He':0.28,
    'Li':1.28,
    'Be':0.96,
    'B':0.84,
    'C':0.76, # sp3 hybridization, sp2: 0.73 sp: 0.69
    'N':0.71,
    'O':0.66,
    'F':0.57,
    'Ne':0.58,
    'Na':1.66,
    'Mg':1.41,
    'Al':1.21,
    'Si':1.11,
    'P':1.07,
    'S':1.05,
    'Cl':1.02,
    'Ar':1.06,
    'K':2.03,
    'Ca':1.76,
    'Sc':1.70,
    'Ti':1.60,
    'V':1.53,
    'Cr':1.39,
    'Mn':1.39, # l.s.; h.s.: 1.61
    'Fe':1.32, # l.s.; h.s.: 1.52
    'Co':1.26, # l.s.; h.s.: 1.50
    'Ni':1.24,
    'Cu':1.32,
    'Zn':1.22,
    'Ga':1.22,
    'Ge':1.20,
    'As':1.19,
    'Se':1.20,
    'Br':1.20,
    'Kr':1.16,
    'Rb':2.20,
    'Sr':1.95,
    'Y':1.90,
    'Zr':1.75,
    'Nb':1.64,
    'Mo':1.54,
    'Tc':1.47,
    'Ru':1.46,
    'Rh':1.42,
    'Pd':1.39,
    'Ag':1.45,
    'Cd':1.44,
    'In':1.42,
    'Sn':1.39,
    'Sb':1.39,
    'Te':1.38,
    'I':1.39,
    'Xe':1.40,
    'Cs':2.44,
    'Ba':2.15,
    'La':2.07,
    'Ce':2.04,
    'Pr':2.03,
    'Nd':2.01,
    'Pm':1.99,
    'Sm':1.98,
    'Eu':1.98,
    'Gd':1.96,
    'Tb':1.94,
    'Dy':1.92,
    'Ho':1.92,
    'Er':1.89,
    'Tm':1.90,
    'Yb':1.87,
    'Lu':1.87,
    'Hf':1.75,
    'Ta':1.70,
    'W':1.62,
    'Re':1.51,
    'Os':1.44,
    'Ir':1.41,
    'Pt':1.36,
    'Au':1.36,
    'Hg':1.32,
    'Tl':1.45,
    'Pb':1.46,
    'Bi':1.48,
    'Po':1.40,
    'At':1.50,
    'Rn':1.50,
    'Fr':2.60,
    'Ra':2.21,
    'Ac':2.15,
    'Th':2.06,
    'Pa':2.00,
    'U':1.96,
    'Np':1.90,
    'Pu':1.87,
    'Am':1.80,
    'Cm':1.69
}
# Construct the complete list of possible lengths of bonds. If a distance between atoms is less
# than the sum of covalent radii of the two atoms forming the possible bond, it is considered
# to be covalently bonded.
bond_distances = {
    (k1, k2): covalent_radius[k1] + covalent_radius[k2] for k1, k2 in itertools.combinations(covalent_radius.keys(), 2)
}
# Also put in the backwards pair (O,H instead of H,O)
for keys, d in bond_distances.copy().items():
    bond_distances[tuple(reversed(keys))] = d
# Also put in the atoms with themselves (e.g., C,C)
for key in covalent_radius.keys():
    bond_distances[(key, key)] = 2*covalent_radius[key]

def get_seg_DataFrame(COSMO_contents):
    # Read in the information.  Look for (X, Y, Z), and search to the end of the line, then capture until
    # you get to a pair of two end-of-line characters, or an eol character followed by the end of string
    if "DMol3/COSMO Results" in COSMO_contents:
        sdata = re.search(r"\(X, Y, Z\)[\sa-zA-Z0-9\[\]/]+\n(.+)(\n\n|$)", COSMO_contents, re.DOTALL).group(1).rstrip()
        table_assign = ['n','atom','x / a.u.','y / a.u.','z / a.u.','charge / e','area / A^2','charge/area / e/A^2','potential']
    elif "Gaussian COSMO output" in COSMO_contents:
        # Gaussian09: same unit (Bohr in G09) as Dmol3 but format is different
        sdata = re.search(r"\(X, Y, Z\)[\sa-zA-Z0-9\[\]/\#\n]+\#\n([\s\S]+)", COSMO_contents, re.DOTALL).group(1).rstrip()
        table_assign = ['n','atom','x / a.u.','y / a.u.','z / a.u.','charge / e','area / A^2','charge/area / e/A^2','potential']
    elif "GAMESS/COSab RESULTS" in COSMO_contents:
        # GAMESS: same unit (Bohr in GAMESS/COSab) as Dmol3 but format is different
        sdata = re.search(r"\(X, Y, Z\)[\sa-zA-Z0-9\(\)\./\*]+\n([\s0-9\-\n.]+)(=+)", COSMO_contents, re.DOTALL).group(1).rstrip()
        table_assign = ['n','atom','x / a.u.','y / a.u.','z / a.u.','charge / e','area / A^2','charge/area / e/A^2','potential']
    # Annotate the columns appropriately with units(!)
    return pandas.read_csv(StringIO(sdata), names=table_assign, sep=r'\s+',engine= 'python')

def get_atom_DataFrame(COSMO_contents):
    # Read in the information
    if "DMol3/COSMO Results" in COSMO_contents:
        sdata = re.search(r"!DATE[a-zA-Z0-9:\s]+\n(.+)end\s+\nend", COSMO_contents, re.DOTALL).group(1)
        table_assign = ['atomidentifier','x / A','y / A','z / A','?1','?2','?3','atom','?4']
    elif "Gaussian COSMO output" in COSMO_contents:
        # Gaussian09: same unit as Dmol3 (Angstrom in G09) but format is slightly different
        sdata = re.search(r"!DATE[a-zA-Z0-9:\s]*\n(.+)end\s*\nend", COSMO_contents, re.DOTALL).group(1)
        table_assign = ['atomidentifier','x / A','y / A','z / A','?1','?2','?3','atom','?4']
    elif "GAMESS/COSab RESULTS" in COSMO_contents:
        # GAMESS: same unit (Angstrom in GAMESS) as Dmol3 but format is different
        sdata = re.search(r"EQUILIBRIUM GEOMETRY[\sa-zA-Z0-9\(\)\./\*\n]+\-+\n(\s[\s\S]+)\n\n\n", COSMO_contents, re.DOTALL).group(1)
        table_assign = ['atom','charge','x / A','y / A','z / A']
    # Annotate the columns appropriately with units(!)
    return pandas.read_csv(StringIO(sdata), names=table_assign, sep=r'\s+',engine = 'python')

def get_area_volume(COSMO_contents):
    # Read in the information
    if "DMol3/COSMO Results" in COSMO_contents:
        area = float(re.search(r"Total surface area of cavity \(A\*\*2\)     =(.+)\n", COSMO_contents).group(1).strip())
        volume = float(re.search(r"Total volume of cavity \(A\*\*3\)           =(.+)\n", COSMO_contents).group(1).strip())
    elif "Gaussian COSMO output" in COSMO_contents:
        # Gaussian09: "area" = area of the solute cavity surface (in Bohr^2)
        # Gaussian09: "volume" = volume enclosed by the solute cavity surface (in Bohr^3)
        area = float(re.search(r"area  =(.+)\n", COSMO_contents).group(1).strip())*(0.52917721067)**2
        volume = float(re.search(r"volume=(.+)\n", COSMO_contents).group(1).strip())*(0.52917721067)**3
    elif "GAMESS/COSab RESULTS" in COSMO_contents:
        # GAMESS: units of area and volume are same as DMol3
        area = float(re.search(r"Total surface area of cavity \(A\*\*2\)\s+=(.+)\n", COSMO_contents).group(1).strip())
        volume = float(re.search(r"Total volume of cavity \(A\*\*3\)\s+=(.+)\n", COSMO_contents).group(1).strip())

    return area, volume

def weightbin_sigmas(sigmavals, sigmas_grid):
    """
    """
    # Regular grid, so every bin is of same width
    bin_width = sigmas_grid[1] - sigmas_grid[0]

    psigmaA = np.zeros_like(sigmas_grid)
    for sigma, area in sigmavals:
        # Check sigma
        if sigma < np.min(sigmas_grid):
            raise ValueError('Sigma [{0:g}] is less than minimum of grid [{1}]'.format(sigma, np.min(sigmas_grid)))
        if sigma > np.max(sigmas_grid):
            raise ValueError('Sigma [{0:g}] is greater than maximum of grid [{1}]'.format(sigma, np.max(sigmas_grid)))
        # The index to the left of the point in sigma
        left = int((sigma-sigmas_grid[0])/bin_width)
        # Weighted distance from the left edge of the cell to the right side
        w_left = (sigmas_grid[left+1]-sigma)/bin_width
        # Add the area into the left and right nodes of the bin, each part weighted by the value
        # of sigma, if equal to the left edge of the bin, then the w_left=1, if the right side,
        # w_left = 0
        psigmaA[left] += area*w_left
        psigmaA[left+1] += area*(1.0-w_left)
    return psigmaA

Dmol3COSMO = namedtuple('Dmol3COSMO',['sigmas','psigmaA_nhb','psigmaA_OH','psigmaA_OT','df_atom','meta'])
DispersiveValues = namedtuple('DispersiveValues',['dispersion_flag', 'dispersive_molecule', "Nbonds", 'has_COOH'])

class Dmol3COSMOParser(object):

    def __init__(self, inpath, num_profiles = 3, averaging = None):

        # Open the COSMO file and read in its contents
        COSMO_contents = open(inpath).read()

        # Parse the COSMO file and get metadata
        self.df = get_seg_DataFrame(COSMO_contents)
        self.df_atom = get_atom_DataFrame(COSMO_contents)
        self.area_A2, self.volume_A3 = get_area_volume(COSMO_contents)

        averaging_options = ['Hsieh','Mullins']
        if averaging not in averaging_options:
            raise ValueError('averaging[' + averaging + '] not in '+str(averaging_options))

        self.num_profiles = num_profiles
        self.averaging = averaging

        # Convert coordinates in a.u. (actually, bohr) to Angstroms
        for field in ['x','y','z']:
            self.df[field + ' / A'] = self.df[field + ' / a.u.']*0.52917721067 # https://physics.nist.gov/cgi-bin/cuu/Value?bohrrada0
        # Calculate the effective circular radius for this segment patch from its area
        self.df['rn / A']  = (self.df['area / A^2']/np.pi)**0.5
        self.df['rn^2 / A^2'] = self.df['rn / A']**2

        # Recalculate the charge density here because the vaues in COSMO file are unneccssarily truncated
        self.sigma = np.array(self.df['charge / e']/self.df['area / A^2'])
        self.rn2 = np.array(self.df['rn^2 / A^2'])

        assert(int(self.df.iloc[-1].n) == len(self.rn2))

        # Calculate the distances between each pair of segments in a euclidean sense
        XA = np.c_[self.df['x / A'], self.df['y / A'], self.df['z / A']]
        self.dist_mat_squared = scipy.spatial.distance.cdist(XA, XA, 'euclidean')**2

        # Calculate the distances between each atom center in a euclidean sense
        XA = np.c_[self.df_atom['x / A'], self.df_atom['y / A'], self.df_atom['z / A']]
        self.dist_mat_atom = scipy.spatial.distance.cdist(XA, XA, 'euclidean')

        # Set a flag if the molecule is water; water is treated specially in some cases
        self.is_water = self.df_atom.atom.tolist().count('H') == 2 and self.df_atom.atom.tolist().count('O') == 1 and len(self.df_atom) == 3

        # Calculate the dispersive values
        self.disp = self.get_dispersive_values()

        # Tag each atom with its hydrogen bonding class
        self.df_atom['hb_class'] = self.get_HB_classes_per_atom()

        # Store the number of bonds in the DataFrame
        self.df_atom['Nbonds'] = self.disp.Nbonds

        # Average the charge densities on each segment
        self.sigma_averaged = self.average_sigmas(self.sigma)

        # Split up the profiles
        self.sigma_nhb, self.sigma_OH, self.sigma_OT = self.split_profiles(self.sigma_averaged, self.num_profiles)

    def get_bonds(self, i):
        """
        Get the list of tuples of (j, atom_name_j) of things that are bonded to this atom
        """
        bonds = []
        atom_name_i = self.df_atom.atom.iloc[i]

        if len(self.df_atom) == 2:
            # Special case diatomic molecules, in which case the other
            # atom in the bond is the other atom of the molecule
            bonds.append((1-i, self.df_atom.atom.iloc[1-i]))
        else:
            for j, distance in enumerate(self.dist_mat_atom[i]):
                if i == j: continue # atom cannot bond to itself
                atom_name_j = self.df_atom.atom.iloc[j]
                if distance < 1.15*bond_distances[(atom_name_i, atom_name_j)]:
                    bonds.append((j, atom_name_j))
        return bonds

    def get_HB_classes_per_atom(self):
        # Determine the hydrogen bonding class of each atom
        # Options are:
        #
        # 1) nhb: the atom is not a candidate to hydrogen bond
        # 2) OH: the atom is either the oxygen or the hydrogen in a OH hydrogen-bonding group
        # 3) OT: the atom is N,F, or an oxygen that is not part of an OH bonding group
        #
        # Loop over each atom-atom pair, and determine if it is a candidate for hydrogen bonding
        hydrogen_bonding_atoms = []
        for i in range(len(self.df_atom)):
            atom_name_i = self.df_atom.atom.iloc[i]
            if atom_name_i in ['N','F']:
                # Definite hydrogen bonding atom, cannot be in OH class,
                # so we are done, set it to OT
                hydrogen_bonding_atoms.append('OT')

            elif atom_name_i in ['O','H']:
                # If hydrogen is bonded to O, N, or F, then it is hydrogen-bonding,
                # otherwise not.  The determination of OT or OH hydrogen-bonding class
                # depends on the atom that the hydrogen is bonded to.
                #
                atom_type = 'NHB'
                for j, distance in enumerate(self.dist_mat_atom[i]):
                    if i == j:
                        continue

                    js, atom_name_js = zip(*self.get_bonds(i))

                    # It's OH because an OH bond is found
                    if (atom_name_i == 'H' and 'O' in atom_name_js) or (atom_name_i == 'O' and 'H' in atom_name_js):
                        atom_type = 'OH'
                        break

                    # It's OT because it's an oxygen bonded to something other than H
                    if atom_name_i == 'O':
                        atom_type = 'OT'
                        break

                    # It's OT because H is bonded to F or N
                    if atom_name_i == 'H' and ('F' in atom_name_js or 'N' in atom_name_js):
                        atom_type = 'OT'
                        break

                hydrogen_bonding_atoms.append(atom_type)

            else:
                # Definite non-hydrogen-bonding
                hydrogen_bonding_atoms.append('NHB')
        return hydrogen_bonding_atoms

    def get_dispersive_values(self):
        """
        Calculate the dispersive parameters needed for the COSMO-SAC-dsp
        model.

        Returns:
            vals (DispersiveValues): Instance of DispersiveValues namedtuple
        """

        # Determine the dispersive energy parameter of each atom
        dispersive_parameter_lib = {
            'C(sp3)': 115.7023,
            'C(sp2)': 117.4650,
            'C(sp)': 66.0691,
            '-O-': 95.6184,
            '=O': -11.0549,
            'N(sp3)': 15.4901,
            'N(sp2)': 84.6268,
            'N(sp)': 109.6621,
            'F': 52.9318,
            'Cl': 104.2534,
            'H(OH)': 19.3477,
            'H(NH)': 141.1709,
            'H(water)': 58.3301,
            'H(other)': 0
        }

        dispersive_molecule = 0
        invalid_atom = False
        has_COOH = False
        Natom_nonzero = 0
        dispersion_flag = 'NHB'
        Nbonds = []
        for i in range(len(self.df_atom)):
            dispersive_parameter = None
            atom_name_i = self.df_atom.atom.iloc[i]
            bonds = self.get_bonds(i)
            if len(bonds) == 0 and len(self.df_atom):
                raise ValueError("Atom "+atom_name_i+" in a polyatomic molecule has no bonds, this is not good.")
            # print(i, atom_name_i, bonds)
            Nbonds.append(len(bonds))

            if atom_name_i == 'C':
                if len(bonds) == 4:
                    dispersive_parameter = dispersive_parameter_lib['C(sp3)']
                elif len(bonds) == 3:
                    dispersive_parameter = dispersive_parameter_lib['C(sp2)']
                elif len(bonds) == 2:
                    dispersive_parameter = dispersive_parameter_lib['C(sp)']
                # If C is double-bonded to an O and single-bonded to the other O, then a candidate for
                # being a carboxyl group, let's dig deeper
                #
                # First, we see if the carbon is bonded to two oxygens
                js, atom_name_js = zip(*bonds)
                if len(bonds) == 3 and atom_name_js.count('O') == 2:
                    # If either O is bonded to C and an H, and nothing else, then we are in a carboxyl group
                    for j, atom_name_j in bonds:
                        if not atom_name_j == 'O': continue
                        ks, atom_name_ks = zip(*self.get_bonds(j))
                        if sorted(atom_name_ks) == ['C','H']:
                            has_COOH = True
                            break
            elif atom_name_i == 'N':
                if len(bonds) == 3:
                    dispersive_parameter = dispersive_parameter_lib['N(sp3)']
                elif len(bonds) == 2:
                    dispersive_parameter = dispersive_parameter_lib['N(sp2)']
                elif len(bonds) == 1:
                    dispersive_parameter = dispersive_parameter_lib['N(sp)']
                else:
                    raise ValueError('N with a funny number of bonds: '+len(bonds))
            elif atom_name_i == 'O':
                if len(bonds) == 2:
                    dispersive_parameter = dispersive_parameter_lib['-O-']
                elif len(bonds) == 1:
                    dispersive_parameter = dispersive_parameter_lib['=O']
                else:
                    raise ValueError('O with a funny number of bonds: '+len(bonds))
            elif atom_name_i == 'F':
                dispersive_parameter = dispersive_parameter_lib['F']
            elif atom_name_i == 'Cl':
                dispersive_parameter = dispersive_parameter_lib['Cl']
            elif atom_name_i == 'H':
                js, atom_name_js = zip(*bonds)
                if self.is_water:
                    dispersive_parameter = dispersive_parameter_lib['H(water)']
                elif 'O' in atom_name_js:
                    dispersive_parameter = dispersive_parameter_lib['H(OH)']
                elif 'N' in atom_name_js:
                    dispersive_parameter = dispersive_parameter_lib['H(NH)']
                else:
                    dispersive_parameter = None
            else:
                # The atom is unmatched, therefore we will return an invalid number
                # because we don't know what to do about this, but we still
                # need to calculate the number of atoms, so don't exit
                invalid_atom = True
                dispersive_parameter = np.nan

            if dispersive_parameter is not None:
                Natom_nonzero += 1
                dispersive_molecule += dispersive_parameter

        # If the number of atoms with non-zero dispersion parameters is greater than
        # zero, then we divide by the number of nonzero parameters, otherwise not
        # because that would be a division by zero
        if Natom_nonzero > 0:
            dispersive_molecule /= Natom_nonzero

        # If at least one atom is invalid, return an invalid number
        if invalid_atom:
            dispersive_molecule = np.nan

        # Determine the HB-DONOR-ACCEPTOR or HB-ACCEPTOR flags
        possble_Hbonders = ['O', 'N', 'F']
        if any([(atom in set(self.df_atom.atom)) for atom in possble_Hbonders]):
            Hbond = False
            for i in range(len(self.df_atom)):
                atom_name_i = self.df_atom.atom.iloc[i]
                if atom_name_i in possble_Hbonders:
                    bonds = self.get_bonds(i)
                    js, atom_name_js = zip(*bonds)
                    if 'H' in atom_name_js:
                        Hbond = True
            if not Hbond:
                dispersion_flag = 'HB-ACCEPTOR'
            else:
                dispersion_flag = 'HB-DONOR-ACCEPTOR'

        return DispersiveValues(dispersion_flag, dispersive_molecule, Nbonds, has_COOH)

    def average_sigmas(self, sigmavals):
        """
        Calculate the averaged charge densities on each segment, in e/\AA^2
        """

        # This code also works, kept for demonstration purposes, but the vectorized
        # numpy code is much faster, if a bit harder to understand
        # def calc_sigma_m(m):
        #     increments = rn2*r_av2/(rn2+r_av2)*np.exp(-f_decay*dist_mat_squared[m,:]/(rn2+r_av2))
        #     return np.sum(increments*sigma)/np.sum(increments)
        # def calc_sigma_m_mat(m):
        #     increments = THEMAT[m,:]
        #     return np.sum(increments*sigma)/np.sum(increments)

        if self.averaging == 'Mullins':
            self.r_av2 = 0.8176300195**2  # [A^2]  # Also equal to ((7.5/pi)**0.5*0.52917721092)**2
            self.f_decay = 1.0
        elif self.averaging == 'Hsieh':
            self.r_av2 = (7.25/np.pi) # [A^2]
            self.f_decay = 3.57
        else:
            raise ValueError("??")

        THEMAT = np.exp(-self.f_decay*self.dist_mat_squared/(self.rn2+self.r_av2))*self.rn2*self.r_av2/(self.rn2+self.r_av2)
        return np.sum(THEMAT*sigmavals, axis=1)/np.sum(THEMAT,axis=1)

    def split_profiles(self, sigmavals, num_profiles):
        """
        Split the samples into
        """

        if num_profiles == 1:
            sigma_nhb = [(s,a) for s,a in zip(sigmavals,  self.df['area / A^2'])]
            sigma_OH = None
            sigma_OT = None
        elif num_profiles == 3:

            indices = np.array(self.df.atom.astype(int)-1)
            self.df['atom_name'] = self.df_atom.atom[indices].reset_index(drop=True)
            self.df['hb_class'] = self.df_atom.hb_class[indices].reset_index(drop=True)

            # N.B. : The charge density in sigmavals is the averaged charge density,
            # not the charge density of the segment itself!!
            mask_OH = (
                ((self.df.atom_name == 'O') & (sigmavals > 0.0) & (self.df.hb_class == 'OH'))
                |
                ((self.df.atom_name == 'H') & (sigmavals < 0.0) & (self.df.hb_class == 'OH'))
            )
            mask_OT = (
                (self.df.atom_name.isin(['O', 'N', 'F']) & (sigmavals > 0.0) & (self.df.hb_class == 'OT'))
                |
                ((self.df.atom_name == 'H') & (sigmavals < 0.0) & (self.df.hb_class == 'OT'))
            )
            mask_nhb = ~(mask_OT | mask_OH)
            sigma_nhb = np.c_[sigmavals[mask_nhb], self.df[mask_nhb]['area / A^2']]
            sigma_OH = np.c_[sigmavals[mask_OH], self.df[mask_OH]['area / A^2']]
            sigma_OT = np.c_[sigmavals[mask_OT], self.df[mask_OT]['area / A^2']]
        else:
            raise ValueError('Number of profiles [{0}] is invalid'.format(num_profiles))
        return sigma_nhb, sigma_OH, sigma_OT

    def get_meta(self):
        """
        Return a dictionary with the metadata about this set of sigma profiles
        """
        return {
            'name': '?',
            'CAS': '?',
            'area [A^2]': self.area_A2,
            'volume [A^3]': self.volume_A3,
            'r_av [A]': self.r_av2**0.5,
            'f_decay': self.f_decay,
            'sigma_hb [e/A^2]': 0.0084,
            'averaging': self.averaging
        }

    def get_outputs(self):

        # The points where the surface-charge density
        # will be evaluated, -0.025 to 0.025, in increments of 0.001
        bin_width = 0.001
        sigmas = np.arange(-0.025, 0.025+0.0001, bin_width) # [e/A^2]
        meta = self.get_meta()

        if self.num_profiles == 1:
            psigmaA = weightbin_sigmas(self.sigma_nhb, sigmas)
            # print('cumulative time after reweighting', timeit.default_timer()-tic,'s')
            assert(abs(sum(psigmaA)-meta['area [A^2]']) < 0.001)
            return Dmol3COSMO(sigmas, psigmaA, None, None, self.df_atom, self.get_meta())

        elif self.num_profiles == 3:
            psigmaA_nhb = weightbin_sigmas(self.sigma_nhb, sigmas)
            psigmaA_OH = weightbin_sigmas(self.sigma_OH, sigmas)
            psigmaA_OT = weightbin_sigmas(self.sigma_OT, sigmas)
            sigma_0 = 0.007 # [e/A^2]

            psigmaA_hb = psigmaA_OT + psigmaA_OH

            P_hb = 1 - np.exp(-sigmas**2/(2*sigma_0**2))
            psigmaA_OH *= P_hb
            psigmaA_OT *= P_hb

            psigmaA_nhb = psigmaA_nhb + psigmaA_hb*(1-P_hb)

            dispersion_flag = 'NHB'

            # Determine dispersion flag for the molecule
            if self.is_water:
                dispersion_flag = 'H2O'
            elif self.disp.has_COOH:
                dispersion_flag = 'COOH'
            else:
                dispersion_flag = self.disp.dispersion_flag

            meta['disp. flag'] = dispersion_flag
            meta['disp. e/kB [K]'] = self.disp.dispersive_molecule
            # print('cumulative time after reweighting', timeit.default_timer()-tic,'s')
            return Dmol3COSMO(sigmas, psigmaA_nhb, psigmaA_OH, psigmaA_OT, self.df_atom, meta)

def read_Dmol3(**kwargs):
    """
    A convenience function that will pass all arguments along to class and then return the outputs
    """
    return Dmol3COSMOParser(**kwargs).get_outputs()

def overlay_profile(sigmas, psigmaA, path):
    for profile in psigmaA:
        plt.plot(sigmas, profile, 'o-', mfc='none')
        print(np.c_[sigmas, profile])
    df = pandas.read_csv(path, names= ['charge/area / e/A^2', 'p(sigma)*A / A^2'], skiprows = 4, sep = ' ')
    plt.plot(df['charge/area / e/A^2'], df['p(sigma)*A / A^2'], '^-', mfc='none')
    plt.xlabel(r'$\sigma$ / e/A$^2$')
    plt.ylabel(r'$p(\sigma)A_i$ / A$^2$')
    plt.show()

Delaware_template = """# meta: {meta:s}
# Rows are given as: sigma [e/A^2] followed by a space, then psigmaA [A^2]
# In the case of three sigma profiles, the order is NHB, OH, then OT
"""

def write_sigma(dmol, ofpath, header = 'Delaware', force = True):

    if header == 'Delaware':
        out = Delaware_template.format(meta = json.dumps(dmol.meta))
    else:
        raise ValueError("Bad header option")
    summ = 0
    for profile in [dmol.psigmaA_nhb, dmol.psigmaA_OH, dmol.psigmaA_OT]:
        if profile is not None:
            for ir in range(profile.shape[0]):
                out += '{0:0.3f} {1:17.14e}\n'.format(dmol.sigmas[ir], profile[ir])
                summ += profile[ir]

    if os.path.exists(ofpath) and not force:
        raise ValueError("File [{0:s}] already exists and force has not been requested".format(ofpath))

    with open(ofpath,'w') as fp:
        fp.write(out)

if __name__ == '__main__':
    import argparse
    parser = argparse.ArgumentParser(description='Generate a sigma profile from a COSMO file')
    parser.add_argument('--inpath', type=str, required=True, nargs=1, help='The path to the cosmo file that is to be processed')
    parser.add_argument('--outpath', type=str, required=True, nargs=1, help='The path to the sigma profile file that is to be generated')
    parser.add_argument('--n', type=int, nargs=1, required=True, choices=[1,3], help='The number of profiles to generate, either 1 or 3')
    parser.add_argument('--averaging', type=str, nargs=1, required=True, choices=['Hsieh','Mullins'], help="The scheme used to do averaging of profiles, either 'Mullins' to use f_decay = 1 and r_av = 0.8176300195 A or 'Hsieh' to use f_decay = 3.57 and r_av = sqrt(7.25/pi)")

    args = parser.parse_args()
    # args = parser.parse_args('--n 3 --averaging Hsieh --inpath UD/cosmo/ZPTVNYMJQHSSEA-UHFFFAOYSA-N.cosmo --outpath ZPTVNYMJQHSSEA-UHFFFAOYSA-N.sigma'.split(' '))  # For testing

    # For DMol3 .cosmo file test (ethanol)
    #args = parser.parse_args('--n 3 --averaging Hsieh --inpath DMol3_TEST/LFQSCWFLJHTTHZ-UHFFFAOYSA-N.cosmo --outpath DMol3_TEST/LFQSCWFLJHTTHZ-UHFFFAOYSA-N.sigma'.split(' '))  # For testing
    # For gaussian09 .cosmo file test
    #args = parser.parse_args('--n 3 --averaging Hsieh --inpath GAUSSIAN09_TEST/ethanol.cosmo --outpath GAUSSIAN09_TEST/ethanol.sigma'.split(' '))
    # For GAMESS .gout (including cosmo data) file test
    #args = parser.parse_args('--n 3 --averaging Hsieh --inpath GAMESS_TEST/ETHANOL.gout --outpath GAMESS_TEST/ETHANOL.sigma'.split(' '))

    try:
        dmol = read_Dmol3(inpath = args.inpath[0], num_profiles=args.n[0], averaging=args.averaging[0])
        write_sigma(dmol, args.outpath[0])
    except BaseException as BE:
        print(BE)
        print(args)


import logging

log = logging.getLogger(__name__)

from genaf_snp.views import *

class LocusViewer(object):

    def __init__(self, request):
        self.request = request
        self.dbh = get_dbhandler()
        self.locus = None

    @m_roles( PUBLIC )
    def index(self):

        loci = self.dbh.get_loci()

        html = div()[ h2('Loci') ]

        table, code = generate_locus_table(loci, self.request)
        html.add(table)

        return render_to_response('genaf_base:templates/generics/page.mako',
            {   'content': str(html),
                'code': code,
            },  request = self.request)

    @m_roles( PUBLIC )
    def view(self):
        pass

def generate_locus_table(loci, request):

    table_body = tbody()

    not_guest = not request.user.has_roles( GUEST )

    for locus in loci:
        table_body.add(
            tr(
                td(literal('<input type="checkbox" name="locus-ids" value="%d" />' % locus.id)
                    if not_guest else ''),
                td( a(locus.refseq) ),
                td( a(locus.position) ),
                td( a(locus.code) ),
                td( a(locus.ref) ),
                td( a(locus.alt) ),
            )
        )

    locus_table = table(class_='table table-condensed table-striped')[
        thead(
            tr(
                th('', style="width: 2em"),
                th('Refseq'),
                th('Position'),
                th('Code'),
                th('Ref'),
                th('Alt'),
            )
        )
    ]

    locus_table.add( table_body )

    html = div(locus_table)
    code = ''

    return html, code


from django.shortcuts import render

# Create your views here.
from django.http import HttpResponse
from django.contrib.auth.decorators import login_required
from django.shortcuts import get_object_or_404, render

from dcodex.util import get_request_dict
import logging

from .models import *

def index(request):
    return HttpResponse("Hello, world. You're at the DCodex Carlson index.")

def location_siglum( request, location_id, siglum_text ):
    location = get_object_or_404(Location, id=location_id)
    sublocations = location.sublocation_set.all()
    siglum = get_object_or_404(Siglum, name=siglum_text)
    collation = location.collation_set.first()

    siglum = get_object_or_404(Siglum, name=siglum_text)

    verse_labels = location.closest_verse_labels().all()

    transcription = None
    manuscript = None
    bible_verse = None
    if siglum.witness.manuscript and len(verse_labels) > 0:
        manuscript = siglum.witness.manuscript
        bible_verse = verse_labels[0].bible_verse()
        transcription = manuscript.transcription( bible_verse )

    attestation = siglum.witness.get_attestation( sublocation=sublocation, parallel=parallel, corrector=corrector )

    return render(request, 'dcodex_carlson/location.html', {'location': location, 'manuscript':manuscript, 'bible_verse':bible_verse, 'transcription':transcription, 'sublocations': sublocations, 'siglum':siglum, 'witness':siglum.witness, 'parallel':None, 'verse_labels':verse_labels,} )

def location_siglum_parallel( request, location_id, siglum_text, parallel_code ):
    location = get_object_or_404(Location, id=location_id)
    sublocations = location.sublocation_set.all()
    siglum = get_object_or_404(Siglum, name=siglum_text)
    parallel = get_object_or_404(Parallel, code=parallel_code)
    verse_labels = [verse_label for verse_label in location.closest_verse_labels().all() if verse_label.parallel == parallel]

    transcription = None
    manuscript = None
    bible_verse = None
    if siglum.witness.manuscript and len(verse_labels) > 0:
        manuscript = siglum.witness.manuscript
        bible_verse = verse_labels[0].bible_verse()
        transcription = manuscript.transcription( bible_verse )

    return render(request, 'dcodex_carlson/location.html', {'location': location, 'manuscript':manuscript, 'bible_verse':bible_verse,'transcription':transcription, 'sublocations': sublocations, 'siglum':siglum, 'witness':siglum.witness, 'parallel':parallel, 'verse_labels':verse_labels,} )

def location( request, location_id ):
    location = get_object_or_404(Location, id=location_id)
    sublocations = location.sublocation_set.all()

    return render(request, 'dcodex_carlson/location.html', {'location': location, 'sublocations': sublocations} )

def attestations( request ):
    request_dict = get_request_dict(request)

    reading_code = request_dict.get('code')
    sublocation_id = request_dict.get('sublocation_id')
    sublocation = get_object_or_404(SubLocation, id=sublocation_id)

    parallels = sublocation.get_parallels()
    html = ""
    for parallel in parallels:
        parallel_switch = ""
        if parallel:
            parallel_switch = "/%s " % parallel.code
        html += "<div>" + str(parallel_switch) + sublocation.code_attestations_string(reading_code, parallel) + "</div>"

    return HttpResponse(html)

def set_attestation( request ):
    request_dict = get_request_dict(request)

    reading_code = request_dict.get('code')
    corrector = request_dict.get('corrector')

    sublocation_id = request_dict.get('sublocation_id')
    sublocation = get_object_or_404(SubLocation, id=sublocation_id)

    witness_id = request_dict.get('witness_id')
    witness = get_object_or_404(Witness, id=witness_id)

    parallel = None
    parallel_id = request_dict.get('parallel_id')
    parallel_code = request_dict.get('parallel_code')
    if parallel_id:
        parallel = get_object_or_404(Parallel, id=parallel_id)
    elif parallel_code:
        parallel = get_object_or_404(Parallel, code=parallel_code)

    logger = logging.getLogger(__name__)

    logger.error("Parallel in view")
    logger.error(parallel)

    response = witness.set_attestation( sublocation=sublocation, code=reading_code, parallel=parallel, corrector=corrector )
    return HttpResponse("OK" if response else "FAIL")

def set_text( request ):
    request_dict = get_request_dict(request)

    corrector = request_dict.get('corrector')

    sublocation_id = request_dict.get('sublocation_id')
    sublocation = get_object_or_404(SubLocation, id=sublocation_id)

    witness_id = request_dict.get('witness_id')
    witness = get_object_or_404(Witness, id=witness_id)

    parallel = None
    parallel_id = request_dict.get('parallel_id')
    parallel_code = request_dict.get('parallel_code')
    if parallel_id:
        parallel = get_object_or_404(Parallel, id=parallel_id)
    elif parallel_code:
        parallel = get_object_or_404(Parallel, code=parallel_code)

    logger = logging.getLogger(__name__)

    logger.error("Parallel in view")
    logger.error(parallel)

    attestation = witness.get_attestation( sublocation=sublocation, parallel=parallel, corrector=corrector )
    if attestation:
        attestation.text = request_dict.get('text')
        attestation.save()
        return HttpResponse("OK")

    return HttpResponse("FAIL")


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Mon Dec  6 09:46:53 2021

@author: hsienmingliu
"""

# filepath = input()
filepath = input()
string_list = list()
length_list = list()
length_set = set()

def read_file(filepath):
    global string_list
    punctuation = '。，、；：「」『』（）─？！─…﹏《》〈〉．～　,.; !"#$%&\'()*+,-./:;<=>?@[]^_`{¦}~ \n'
    with open (filepath ,"r", encoding="utf-8") as f:
        for line in f:
            counter = 0
            for char in line:
                if char not in punctuation:
                    counter += 1

            string_list.append([line.strip(), counter])
            length_list.append(counter)

    return string_list

def result_output():
    global process_list, length_list, length_set, big3_list
    process_list = sorted(string_list, key = lambda i: -i[1])
    length_list.sort(reverse=True)
    length_set = set(length_list)
    length_set = sorted(length_set, reverse=True)
    big3_list = length_set[0:3]

    for i in big3_list:
        for row in process_list:
            if row[1] == i:
                print(row[1], end=" ")
                print(row[0], end="")
                print()

def main():
    read_file(filepath)
    result_output()

if __name__ == "__main__":
    main()


import pygame

class Player(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        self.y_pos = 300
        self.gravity = 0
        self.jump_round = False
        self.player_index = 0
        self.player_walk_1 = pygame.image.load('./graphics/Player/player_walk_1.png').convert_alpha()
        self.player_walk_2 = pygame.image.load('./graphics/Player/player_walk_2.png').convert_alpha()
        self.player_jump = pygame.image.load('./graphics/Player/jump.png').convert_alpha()
        self.player_frames = [self.player_walk_1, self.player_walk_2]
        self.image = self.player_frames[self.player_index]
        self.rect = self.image.get_rect(midbottom=(80, self.y_pos))
        self.jump_sound = pygame.mixer.Sound('./audio/jump.mp3')
        self.jump_sound.set_volume(0.1)

    def player_input(self):
        """Keep track the player's pressed button"""
        keys = pygame.key.get_pressed()
        if keys[pygame.K_SPACE] and not self.jump_round:
            self.jump_round = True
            self.gravity = -20
            self.jump_sound.play()

    def apply_gravity(self):
        self.gravity += 1
        self.rect.y += self.gravity
        if self.rect.bottom >= self.y_pos:
            self.rect.bottom = self.y_pos
            self.jump_round = False

    def animation_state(self):
        """Animation of the player"""
        if self.rect.bottom < self.y_pos:self.image = self.player_jump
        else:
            self.player_index += 0.1
            if self.player_index >= len(self.player_frames):self.player_index = 0
            self.image = self.player_frames[int(self.player_index)]

    def update(self):
        self.player_input()
        self.apply_gravity()
        self.animation_state()


from typing import Optional, List

import tensorflow as tf

from src.model.layers.conv import bottleneck_conv2d
from src.model.losses.cascade import reconstruction_loss
from src.model.network import NetworkOutput
from src.model.predefined.ic_net_backbone import ICNetBackbone

class ICNetAutoEncoder(ICNetBackbone):

    def __init__(self,
                 output_classes: int,
                 image_mean: Optional[List[float]] = None,
                 ignore_labels: Optional[List[int]] = None,
                 config: Optional[dict] = None):
        super().__init__(
            output_classes=3,
            image_mean=image_mean,
            ignore_labels=None,
            config=config)

    def training_pass(self, x: tf.Tensor, y: tf.Tensor) -> tf.Operation:
        if self._image_mean is not None:
            y -= self._image_mean
        y = tf.math.divide(y, 255.0)
        nodes_to_return = ['conv_sub4', 'conv_sub2', 'conv6_cls']
        model_output = self.feed_forward(
            x=x,
            is_training=True,
            nodes_to_return=nodes_to_return)
        conv_sub4 = model_output['conv_sub4']
        conv_sub2 = model_output['conv_sub2']
        conv6_cls = model_output['conv6_cls']
        conv_sub4_cls = bottleneck_conv2d(
            x=conv_sub4,
            num_filters=self._output_classes,
            activation=None,
            name='conv_sub4_cls'
        )
        conv_sub2_cls = bottleneck_conv2d(
            x=conv_sub2,
            num_filters=self._output_classes,
            activation=None,
            name='conv_sub2_cls'
        )
        cls_outputs = [conv_sub4_cls, conv_sub2_cls, conv6_cls]
        cls_weights = [self._labmda_1, self._lambda_2, self._lambda_3]
        return reconstruction_loss(
            cascade_output_nodes=cls_outputs,
            y=y,
            loss_weights=cls_weights)

    def infer(self, x: tf.Tensor) -> NetworkOutput:
        y_dash = super().infer(x)
        y_dash = y_dash * 255.0
        if self._image_mean is not None:
            y_dash += self._image_mean
        return tf.cast(y_dash, dtype=tf.uint8)