"""
A simple script to log changes in a folder using watchdog library
Default path = script location, stop run = keyboard interrupt
"""

import time

from watchdog.events import PatternMatchingEventHandler
from watchdog.observers import Observer

def main():
    try:
        my_observer = Observer()
        my_observer.schedule(my_event_handler, path, recursive=go_recursively)
        my_observer.start()
        try:
            while True:
                time.sleep(1)
        except KeyboardInterrupt:
            my_observer.stop()
            my_observer.join()
    except ValueError:
        pass

def on_created(event):
    print(f"- {event.src_path} has been created!")

def on_deleted(event):
    print(f" - someone deleted {event.src_path}!")

def on_modified(event):
    print(f"- {event.src_path} has been modified")

def on_moved(event):
    print(f"- someone moved {event.src_path} to {event.dest_path}")

if __name__ == "__main__":
    patterns = "*"
    ignore_patterns = ""
    ignore_directories = False
    case_sensitive = True
    my_event_handler = PatternMatchingEventHandler(patterns, ignore_patterns, ignore_directories, case_sensitive)
    my_event_handler.on_created = on_created
    my_event_handler.on_deleted = on_deleted
    my_event_handler.on_modified = on_modified
    my_event_handler.on_moved = on_moved
    path = "."
    go_recursively = True
    main()


# -*- coding: utf-8 -*-
import os
os.chdir('D:\Kaggle\Shelter Animal Outcomes')
import pandas as pd
import numpy as np
from importlib import reload
import data_preprocessing as dp
import prepare_for_model as pfm
import other_functions as of
import explanatory_analysis as ea
import sklearn.linear_model as lr
from sklearn.metrics import log_loss, confusion_matrix
from sklearn import cross_validation as cv

reload(of)
reload(pfm)
reload(ea)
reload(dp)
data = pd.read_csv('train.csv')
dp.preprocess(data, is_prediction = False, path = 'values_to_keep')
data2 = pfm.prepare(data)
y = data.OutcomeType
timeInc = True
model_col = [c for c in data2.columns if not 'AnimalType_' in c \
            and (timeInc or (not 'Year_' in c and
                             not 'Month_' in c and
                             not 'Day_' in c and
                             not 'DayOfWeek_' in c and
                             not 'Hour_' in c)) ]
## prepare model for dogs ###########################################
X_train, X_test, y_train, y_test = cv.train_test_split(
    data2.loc[data2.AnimalType_Dog == 1,model_col],
    y[data2.AnimalType_Dog == 1],
    test_size=0.0, random_state=13)
# test of C parameters
Cs = np.power(10,np.linspace(-10, 3, 10))
scores = of.cv_and_plot(X_train,y_train,Cs,'plots' )
# test parameters closer to minimum
Cs_2 = np.linspace(0.03, 2, 10)
scores_2 = of.cv_and_plot(X_train,y_train,Cs_2,'plots' )
# fitting model to whole training dataset
model_dog = lr.LogisticRegression(penalty = 'l1', C = 0.25, n_jobs = 4)
model_dog.fit(X_train,y_train)
# validation model
test_pre = model_dog.predict(X_test)
test_pro = model_dog.predict_proba(X_test)
confusion_matrix(y_test, test_pre)
ld = log_loss(y_test,test_pro)
# plotting coefficients
coefs = pd.DataFrame(model_dog.coef_, columns = X_train.columns)
for c in data.columns:
    ea.plot(c,coefs, model_dog.classes_, 'results')

## prepare model for cats #############################################
# test of C parameters
X_train_cat, X_test_cat, y_train_cat, y_test_cat = cv.train_test_split(
    data2.loc[data2.AnimalType_Dog == 0,model_col],
    y[data2.AnimalType_Dog == 0],
    test_size=0, random_state=13)
# first test of parameters
Cs = np.power(10,np.linspace(-10, 3, 10))
scores = of.cv_and_plot(X_train_cat,y_train_cat,Cs,'plots' )
# second test of parameters
Cs_2 = np.linspace(0.05, 1, 10)
scores_2 = of.cv_and_plot(X_train_cat,y_train_cat,Cs_2,'plots' )

Cs_3 = np.linspace(0.10, 0.5, 10)
scores_3 = of.cv_and_plot(X_train_cat,y_train_cat,Cs_3,'plots')
# model
model_cat = lr.LogisticRegression(penalty = 'l1', C = 0.25, n_jobs = 4)
model_cat.fit(X_train_cat,y_train_cat)
# coefficients
coefs_cat = pd.DataFrame(model_cat.coef_, columns = X_train_cat.columns)
for c in data.columns:
    ea.plot(c,coefs_cat, model_cat.classes_, 'results_cat')

test_pre_cat = model_cat.predict(X_test_cat)
test_pro_cat = model_cat.predict_proba(X_test_cat)
confusion_matrix(y_test_cat, test_pre_cat)
lc = log_loss(y_test_cat,test_pro_cat)
(lc * y_test_cat.shape[0] + ld * y_test.shape[0])/(y_test_cat.shape[0] +  y_test.shape[0])

# kaggle test data
eval_data = pd.read_csv('test.csv')
dp.preprocess(eval_data, is_prediction = True, path = 'values_to_keep')
eval_data2 = pfm.prepare(eval_data, model_dummies_names = data2.columns)
eval_pro_dog = model_dog.predict_proba(eval_data2.loc[eval_data2.AnimalType_Dog == 1, model_col])
eval_pro_cat = model_cat.predict_proba(eval_data2.loc[eval_data2.AnimalType_Dog == 0, model_col])
eval_pro_dog = pd.DataFrame(eval_pro_dog, columns = model_dog.classes_)
eval_pro_cat = pd.DataFrame(eval_pro_cat, columns = model_cat.classes_)

eval_pro_dog.insert(0,'ID',eval_data.loc[eval_data2.AnimalType_Dog == 1, 'ID'].values)
eval_pro_cat.insert(0,'ID',eval_data.loc[eval_data2.AnimalType_Dog == 0, 'ID'].values)

result = pd.concat([eval_pro_dog, eval_pro_cat]).sort_values(by = 'ID')
result.to_csv('submission1.csv', index = False)


from flask import Blueprint, render_template, request, flash, jsonify, redirect
from flask_login import login_required, current_user
from .models import Upload
import os
from . import db
import json
import paramiko
import time
#from .tasks import send_and_process_fastq

host = 'calc.cod.phystech.edu'
secret = 'Gq~#aCztH%6A}u'
username = 'kumondorova.a'
port = 22

views = Blueprint('views', __name__)

@views.route('/', methods=['GET', 'POST'])
@login_required
def home():
    if request.method == 'POST':
        uploaded_file = request.files['file_upload']
        if uploaded_file.filename != '':
            uploaded_file.save(f'./uploads/{uploaded_file.filename}')

            if 1==1:
                new_file = Upload(filename=uploaded_file.filename, user_id=current_user.id,status=0 )  #providing the schema for the note
                db.session.add(new_file) #adding the note to the database
                db.session.commit()
                flash('Файл загружен', category='success')

    return render_template("home.html", user=current_user)

@views.route('/send/<int:id>')
def send(id):
    file_to_cluster = Upload.query.get_or_404(id)
    dir = f"uploads/{file_to_cluster.filename}"
    abs_dir = os.path.abspath(dir)
    #send_and_process_fastq.apply_async(args = [host, username, secret, port, file_to_cluster], countdown=210)

    #flash(list(db.session.query(Upload).all()), category='success')
    #flash(list(db.session.query(Upload).filter(Upload.status == 0).all()),category='success')
    return redirect('/')

@views.route('/delete/<int:id>')
def delete(id):
    update_to_delete = Upload.query.get_or_404(id)

    try:
        db.session.delete(update_to_delete)
        db.session.commit()
        #update_to_delete.filename Дает имя файла с расширением
        return redirect('/')

    except:
        return "Возникла проблема в удалении загруженного файла"

@views.route('/ks.rsmu',methods=['GET', 'POST'] )
def find():

    return redirect('/')


#! /Users/xiaotongli/anaconda3/bin/python
# -*- coding: utf-8 -*-
# @Time    : 10/12/18 6:07 PM
# @Author  : Xiaotong Li
# @School  : University of California, Santa Cruz
# @FileName: groupStrings.py
# @Software: PyCharm

class Solution:
    def groupStrings(self, strings):
        """
        :type strings: List[str]
        :rtype: List[List[str]]
        """
        dictionary = {}
        for i in strings:
            hs = self.strHash(i)
            if hs not in dictionary.keys():
                dictionary[hs] = [str(i)]
            else:
                self.insertStr(dictionary[hs], str(i))
        return [dictionary[key] for key in dictionary.keys()]

    def strHash(self, astring):
        hslist = [(ord(i) - ord(astring[0])) % 26 for i in astring]
        return tuple(hslist)

    def insertStr(self, alist, astring):
        i = 0
        while i < len(alist) and ord(astring[0]) > ord(alist[i][0]):
            i += 1
        if i == len(alist):
            alist.append(astring)
        else:
            alist[:] = alist[0:i] + [astring] + alist[i:]


#! /usr/bin/env python
######################################################################
#
# Name: stagestatus.py
#
# Purpose: Python class StageStatus (used by project.py script).
#          This class contains information about project stage status.
#
# Created: 12-Dec-2014  Herbert Greenlee
#
######################################################################

from __future__ import absolute_import
from __future__ import print_function
import os
import project_utilities
import larbatch_posix

# Project status class.

class StageStatus:

    # Constructor.

    def __init__(self, stage):

        # Default values.

        self.stage = stage               # Stage name.
        self.exists = False              # Does bookdir exist?
        self.nfile = 0                   # Number of good art files.
        self.nev = 0                     # Number of good art events.
        self.nana = 0                    # Number of good non-art root files.
        self.nerror = 0                  # Number of workers with errors.
        self.nmiss = 0                   # Number of unprocessed input files.

        # Update data.

        self.update()

    # Update data for this stage.

    def update(self):

        bookdir = self.stage.bookdir

        # Test whether output directory exists.

        if larbatch_posix.exists(bookdir):

            # Output directory exists.

            self.exists = True
            self.nfile = 0
            self.nev = 0
            self.nana = 0
            self.nerror = 0
            self.nmiss = 0

            # Count good files and events.

            eventsfile = os.path.join(bookdir, 'events.list')
            if larbatch_posix.exists(eventsfile):
                lines = larbatch_posix.readlines(eventsfile)
                for line in lines:
                    words = line.split()
                    if len(words) >= 2:
                        self.nfile = self.nfile + 1
                        self.nev = self.nev + int(words[1])

            # Count good files analysis root files.

            filesana = os.path.join(bookdir, 'filesana.list')
            if larbatch_posix.exists(filesana):
                lines = larbatch_posix.readlines(filesana)
                for line in lines:
                    self.nana = self.nana + 1

            # Count errors.

            badfile = os.path.join(bookdir, 'bad.list')
            if larbatch_posix.exists(badfile):
                lines = larbatch_posix.readlines(badfile)
                for line in lines:
                    if line.strip():
                        self.nerror += 1

            # Count missing files.

            missingfile = os.path.join(bookdir, 'missing_files.list')
            if larbatch_posix.exists(missingfile):
                lines = larbatch_posix.readlines(missingfile)
                for line in lines:
                    if line.strip():
                        self.nmiss += 1

        else:

            # Output directory does not exist.

            self.exists = False


# 30-topshiriq
a=int(input("To'rt burchakning A tomonnini kiriting:"))
b=int(input("To'rt burchakning B tomonnini kiriting:"))
c=int(input("Kvadratning C tomonnini kiriting:"))
i=0
j=0
while (a-c>=0):
    i=i+1
    a=a-c
while b-c>=0:
    j=j+1
    b=b-c
print("{} ta tomini {} ga teng  kvadrat joylashtirish mumkin.".format(j*i,c))


import pandas as pd
import requests
import time
import numpy as np

# see all columns in a wide DataFrame
pd.set_option('display.max_column', None)

# collecting data from url
nba_stats = 'https://stats.nba.com/stats/leagueLeaders?LeagueID=00&PerMode=PerGame&Scope=S&Season=2022-23&SeasonType=Regular%20Season&StatCategory=PTS'

r = requests.get(url=nba_stats).json()

# defining rows and headers and creating table
table_header = r['resultSet']['headers']
table_rows = r['resultSet']['rowSet']
pd.DataFrame(table_rows,columns=table_header)

df_cols = ['Year','Season_Type'] + table_header
df = pd.DataFrame(columns=df_cols)
season_type = ['Regular%20Season','Playoffs']
years = ['2022-23']#,'2011-12','2012-13','2013-14','2014-15','2015-16','2016-17','2017-18','2018-19','2019-20','2020-21','2021-22','2022-23']

headers = {
    'Accept': '*/*',
    'Accept-Encoding': 'gzip, deflate, br',
    'Accept-Language': 'en-US,en;q=0.9',
    'Connection': 'keep-alive',
    'Host': 'stats.nba.com',
    'Origin': 'https://www.nba.com',
    'Referer': 'https://www.nba.com/',
    'Sec-Ch-Ua': '"Chromium";v="116", "Not)A;Brand";v="24", "Google Chrome";v="116"',
    'Sec-Ch-Ua-Mobile': '?0',
    'Sec-Ch-Ua-Platform': '"Windows"',
    'Sec-Fetch-Dest': 'empty',
    'Sec-Fetch-Mode': 'cors',
    'Sec-Fetch-Site': 'same-site',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36'
}

begin_loop = time.time()

for y in years:
    for s in season_type:
        api_url = 'https://stats.nba.com/stats/leagueLeaders?LeagueID=00&PerMode=PerGame&Scope=S&Season='+y+'&SeasonType='+s+'&StatCategory=PTS'
        r = requests.get(url=api_url, headers=headers).json()
        temp_df1 = pd.DataFrame(table_rows,columns=table_header)
        temp_df2 = pd.DataFrame({'Year':[y for i in range(len(temp_df1))],
                                'Season_Type':[s for i in range(len(temp_df1))]})
        temp_df3 = pd.concat([temp_df2,temp_df1],axis=1)
        df = pd.concat([df, temp_df3], axis=0)
        print(f'Finished scraping data for {y} {s}.')

print(f'Process Completed. Total run time: {round((time.time()-begin_loop)/60,2)}')
df.to_excel('2022-23_data.xlsx', index=False)


from farm.logging import Logger

class AbstractFlagSubmitter:
    def __init__(self):
        self.logger = Logger('FlagSubmitter')

    async def send_flags(self, flags):
        raise NotImplementedError('Can\'t send flags: %s doesn\'t specify send_flags(flags)' % self.__class__.__name__)


from pysam import VariantFile
import argparse
import os.path as path
import pandas as pd
import configparser

# Get chrom pos ref alt from location file
def locations_from_file(filename):
    result = pd.read_csv(filename)[["chrom","pos","ref","alt"]].values
    return result

# Get variant at position from bcf filename
# For bcf files fetch takes 0 based positions
def get_variant(chrom, pos, ref, alt, bcf_filename_template):
    contig = f"chr{chrom}"
    bcf_filename = bcf_filename_template.format(chrom=chrom)
    bcf_in = VariantFile(bcf_filename)
    results = list()
    header = bcf_in.header
    for rec in bcf_in.fetch(contig, int(pos)-1, int(pos)):
        if (rec.pos == int(pos) and
                rec.ref == ref and
                rec.alts[0] == alt):
            results.append(rec)
    bcf_in.close()
    return (header, results)

# Combine dosages and write to outputfile
def get_dosages(location_filename, output_filename, bcf_filename_template):
    dat = locations_from_file(location_filename)
    results = [get_variant(*info,bcf_filename_template) for info in dat]

    # Check that the samples in the files are in the same order
    samples_in_first_vcf = list(results[0][0].samples)
    sample_orders_are_identical = all([list(x[0].samples)
                                       == samples_in_first_vcf for x in results])
    # We are not using pandas just in case the file is large.
    if sample_orders_are_identical:
        with open(output_filename, "wt") as fout:
            samples_str  =",".join(samples_in_first_vcf)
            header=f"variant,{samples_str}\n"
            fout.write(header)
            for ((_, res), info) in zip(results, dat):
                if len(res) == 1:
                    rec = res[0]
                    if len(rec.alts) > 1:
                        raise NameError("Multi-allelic")
                    name =":".join([rec.chrom, str(rec.pos), rec.ref, rec.alts[0]])
                    gts = [rec.samples[s]["GT"] for s in samples_in_first_vcf]
                    dosages = [str(sum(x)) if (-1 not in x) else "" for x in gts]
                    dosages_str = ",".join(dosages)
                    out = f"{name},{dosages_str}\n"
                    fout.write(out)
                elif len(res) > 1:
                    raise NameError(f"Something is off multiple results for variant: {info}")
                else:
                    print(f"No results were found for {info}")
    else:
        raise NameError("Sample order/ samples are not the same between all the files used can't do merge")

def get_counts(dosages_filename, locations_filename, dictionary_csv, counts_output_filename):
    dosages = pd.read_csv(dosages_filename).set_index("variant")
    nwd_ids = dosages.apply(lambda x: list(dosages.columns[x != 0]), axis=1)
    df = pd.DataFrame( { "nwd_ids": nwd_ids, "counts": nwd_ids.apply(len)})

    dict_df = pd.read_csv(dictionary_csv)[["framid", "NWD_ID"]]
    dict_df = dict_df.loc[~dict_df.NWD_ID.isna()]

    my_dict = dict(zip(dict_df["NWD_ID"],dict_df["framid"]))

    df["framids"] = df.nwd_ids.apply(lambda x: [str(my_dict[y]) for y in x])
    df["nwd_ids"] = df.nwd_ids.apply(";".join)
    df["framids"] = df.framids.apply(";".join)

    popseq = pd.read_csv(locations_filename)
    popseq["variant"] = popseq.apply(lambda x: "chr" + ":".join(map(str,x[["chrom","pos","ref","alt"]])),axis=1)
    result_df = popseq.set_index("variant").join(df, how="left")
    result_df.to_csv(counts_output_filename)

def main():
    parser = argparse.ArgumentParser(description="Get bcf file with variants defined in input file")
    parser.add_argument('input', metavar='FILE',
                        help="File with variants csv with cols variant,Amino acid,spid,chrom,pos,ref,alt,bcftoolsQuery")
    parser.add_argument('--output_prefix', '-o', metavar='OUTPUT_PREFIX',
                        help="Output directory")

    parser.add_argument('--config', '-c', metavar='CONFIG_FILE',
                        help="configuration file", default="generate_ror.config")

    # Get args
    args = parser.parse_args()
    locations_filename = args.input
    # Read config file
    config = configparser.ConfigParser()
    config.read(args.config)
    dictionary_csv = config["config"]["dictionary"]
    bcf_filename_template = config["config"]["bcf_template"]

    if not path.exists(dictionary_csv):
        raise NameError("Dictionary file does not exist")
    test_bcf = bcf_filename_template.format(chrom=1)
    if not path.exists(test_bcf):
        raise NameError(f"BCF file for chromosome 1 does not exist: {test_bcf}")

    # Construct output filenames
    locations_filename = args.input
    output_dosages_filename = f"{args.output_prefix}_dosages.csv"
    counts_filename = f"{args.output_prefix}_counts.csv"

    # Get dosage file
    get_dosages(locations_filename, output_dosages_filename,bcf_filename_template)

    # Get counts file
    get_counts(output_dosages_filename, locations_filename, dictionary_csv, counts_filename)


from utils.utils import calculate_rectangles, get_room_dims, get_security_dist, get_table_dims
from utils.draw_utils import create_diagram
from rectpack import newPacker

def run(room_size_split, security_distance, table_sizes, draw=True):
    for room_size in room_size_split:
        _opt_room_size = [dim + security_distance for dim in room_size]
        rectangles = calculate_rectangles(_opt_room_size, security_distance, table_sizes)
        packer = newPacker()
        for r in rectangles:
            packer.add_rect(*r)
        packer.add_bin(*_opt_room_size)
        packer.pack()
        if draw:
            create_diagram(packer[0], security_distance, room_size, 'diagram'+str(room_size))
        else:
            for box in packer[0]:
                print(box)

if __name__=='__main__':
    print('Welcome to the restaurant optimiser!')
    print('Hope this can help you! Remember all units are in m.')

    restaurant_list = []
    i = 1
    while True:
        restaurant_list.append(get_room_dims(i))
        _continue = input('Are there any more spaces?(n/y): ')
        _continue = _continue or 'n'
        i += 1
        if _continue=='n':
            break
    security = get_security_dist()

    table_list = []
    while True:
        table_list.append(get_table_dims())
        _continue = input('Are there any more table sizes?(n/y): ')
        _continue = _continue or 'n'
        if _continue=='n':
            break
    _draw = input('Do you want to save the outcome as png images?(y/n): ')
    _draw = _draw or 'y'

    if _draw=='y':
        draw = True
        print('We are gonna save it in your current location.')
    elif _draw=='n':
        draw = False
        print('Here is your result!')
    run(restaurant_list, float(security), table_list, draw)


'''
Assign Mice to Holes

There are N Mice and N holes that are placed in a straight line. Each hole can accomodate only 1 mouse.
The positions of Mice are denoted by array A and the position of holes are denoted by array B.
A mouse can stay at his position, move one step right from x to x + 1, or move one step left from x to x − 1. Any of these moves consumes 1 minute.
Assign mice to holes so that the time when the last mouse gets inside a hole is minimized.

Problem Constraints
1 <= N <= 10^5
-10^9 <= A[i], B[i] <= 10^9

Example Input
Input 1:

 A = [-4, 2, 3]
 B = [0, -2, 4]
Input 2:

 A = [-2]
 B = [-6]

Example Output
Output 1:

 2
Output 2:

 4
'''
# we need to put ith mouse in the closest hole so
# sort the mice pos arr and the hole arr
# ans = max(ans, abs(b[i]-a[i])), will give the max time
class Solution:
    def mice(self, a, b):
        a.sort()
        b.sort()
        ans = float('-inf')
        for i in range(len(a)):
            ans = max(ans, abs(b[i]-a[i]))
        return ans
# TC O(n*log n)
# SC O(1)


import base64

from hash import Hasher
import threading
from crypto2.utils.matrices import mult_matrix, def_pitrix, subs_matrix
from ecc import Curve

def psuedo_combine(a, b):
    for i in range(64):
        a[i] ^= b[a[i] & 63]
    return a

class KeyScheduler:
    def __init__(self, generator_hash, rounds, blocks):
        self.__rounds__ = rounds
        self.__blocks__ = blocks

        self.__key_hash__ = base64.b64decode(generator_hash)

        self.__matrix__, self.__inv_matrix__ = self.def_matrices()
        self.__block_starts__ = None

    def block_keys(self, block_start):
        __block_keys__ = [block_start]
        for i in range(self.__rounds__ * 2):
            __block_keys__.append(psuedo_combine(__block_keys__[-1], block_start)[:])
        return __block_keys__[0:-1]

    def gen_block_starts(self):
        if self.__block_starts__:
            return self.__block_starts__

        self.__block_starts__ = []

        for i in range(self.__blocks__):
            if i == 0:
                self.__block_starts__.append(self.__key_hash__)
            else:
                """
                This provides high resistance to quantum and traditional attacks, but is very expensive
                I decided pitrix should be non-linear enough, with a few other combinations and sboxes to form a light-
                weight hash function of sufficient strength for a key scheduler
                """
                self.__block_starts__.append(
                    mult_matrix(subs_matrix(psuedo_combine(self.__block_starts__[-1], self.__key_hash__)), def_pitrix())
                )

        return self.__block_starts__

    def def_matrices(self):
        return 1, 2

def encrypt(key_hash, data, rounds=4):
    # This ensures that the KeyScheduler is unique per file/key combo
    # It also reduces memory attack potential for pass the hash
    hasher = Hasher(key_hash)
    hasher.hash(data)
    generator_hash = int(hasher.digest(as_b64=True)[2:])  # sooooo we need to only play with 62 bytes

    ks_hash = KeyScheduler(key_hash, rounds=rounds, blocks=1)
    ks_data = KeyScheduler(generator_hash, rounds=rounds, blocks=len(data)//62 + 1)
    blocks = data
    output = None
    curve = Curve()

    # Encrypt generator hash
    for i in range(rounds):
        h = curve.point_addition(curve.encode_point(5))

    """
    encrypt(key_scheduler_hash as ks, file_hash as h):
        for rounds min 4:
            h = ECC.add( h as ecc.point, ks.next as ecc.point)
        for rounds min 4:
            h = ks.matrix_mult(h as matrix)
            h += ks.next

        h, -1 -> encrypted

    encrypt(key_scheduler as ks, data as data):
        ks.generate_starts(data#), block, block# -> queue
        encrypted;

        queue -> get(ks, block)
            for rounds min 4:
                block = ECC.add( block as ecc.point, ks.next as ecc.point)
            for rounds min 4:
                block = ks.matrix_mult(block as matrix)
                block += ks.next
            block, block# -> encrypted

        return order(encrypted)
    """

    pass

def decrypt(key_hash, encrypted, rounds=4):
    """
    key_scheduler_hash(key_hash, rounds, reverse)
    file_hash:
        decrypt(encrypted[0] as e, key_scheduler_hash as ks):
            for rounds min 4:
                e += ks.next
                e = ks.matrix_mult_inv(e as matrix)
            for rounds min 4:
                e = ECC.add( e as ecc.point, ks.next as ecc.point)

    key_scheduler(key_hash, file_hash, rounds, reverse)

    decrypt(key_scheduler as ks, encrypted as e):
        ks.generate_starts(e#), e, e# -> queue
        decrypted;

        queue -> get(ks, block)
            for rounds min 4:
                block += ks.next
                block = ks.matrix_mult(block as matrix)
            for rounds min 4:
                block = ECC.add( block as ecc.point, ks.next as ecc.point)
            block, block# -> decrypted

    if file_hash(decrypted) == file_hash:
        return decrypted
    else:
        raise("Error in ")
    """

    pass

"""
def encryption(p, ks, r):

    for R in range(r-1):
        p = shift_rows(xor_2d_matrices(matrix_mult(p, enc), ks.get_key()))

    return xor_2d_matrices(matrix_mult(p, enc), ks.get_key())

def decryption(p, ks, r):

    p = matrix_mult(xor_2d_matrices(p, ks.get_key()), dec)

    for R in range(r-1):
        p = matrix_mult(xor_2d_matrices(inv_shift_rows(p), ks.get_key()), dec)

    return p
"""

c = Curve()
v= 65189726
p = c.encode_point(v)
d = c.decode_point(p)
print(v==d, v, p, d)


# -*- coding: utf-8 -*-

from collections import defaultdict
from abc import ABC,abstractmethod
import inspect
import os
import json
from os import environ, listdir, makedirs
from os.path import dirname, expanduser, isdir, join, splitext

"""Base class for all the energy predictors."""

class BasePredictor(ABC):
    @abstractmethod
    def fit(self, X, y):
        """Fit predictor.
        Parameters
        ----------
        X : {ndarray, sparse matrix} of shape (n_samples, n_features)
            The input samples.

        y : ndarray of shape (n_samples,)
            The input target value. ( meter readings)

        Returns
        -------
        self : object
            Fitted estimator.

        """
        pass

    @abstractmethod
    def predict(self, X):
        """
        Parameters
        ----------
        X : {array-like, sparse matrix} of shape (n_samples, n_features)
            For kernel="precomputed", the expected shape of X is
            (n_samples_test, n_samples_train).
        Returns
        -------
        y_pred : ndarray of shape (n_samples,)
        """
        pass

    @classmethod
    def _get_param_names(cls):
        """Get parameter names for the predictor"""
        # fetch the constructor or the original constructor before
        # deprecation wrapping if any
        init = getattr(cls.__init__, "deprecated_original", cls.__init__)
        if init is object.__init__:
            # No explicit constructor to introspect
            return []

        # introspect the constructor arguments to find the model parameters
        # to represent
        init_signature = inspect.signature(init)
        # Consider the constructor parameters excluding 'self'
        parameters = [
            p
            for p in init_signature.parameters.values()
            if p.name != "self" and p.kind != p.VAR_KEYWORD
        ]
        for p in parameters:
            if p.kind == p.VAR_POSITIONAL:
                raise RuntimeError(
                    "scikit-learn estimators should always "
                    "specify their parameters in the signature"
                    " of their __init__ (no varargs)."
                    " %s with constructor %s doesn't "
                    " follow this convention." % (cls, init_signature)
                )
        # Extract and sort argument names excluding 'self'
        return sorted([p.name for p in parameters])

    def get_params(self, deep=True):
        """
        Get parameters for the predictor.

        Parameters
        ----------
        deep : bool, default=True
            If True, will return the parameters for this estimator and
            contained subobjects that are estimators.
        Returns
        -------
        params : dict
            Parameter names mapped to their values.
        """
        out = dict()
        for key in self._get_param_names():
            value = getattr(self, key)
            if deep and hasattr(value, "get_params"):
                deep_items = value.get_params().items()
                out.update((key + "__" + k, val) for k, val in deep_items)
            out[key] = value
        return out

    def set_params(self, **params):
        """
        Set the parameters of the predictor.

        Parameters
        ----------
        **params : dict
            Estimator parameters.
        Returns
        -------
        self : estimator instance
            Estimator instance.
        """
        if not params:
            # Simple optimization to gain speed (inspect is slow)
            return self
        valid_params = self.get_params(deep=True)

        nested_params = defaultdict(dict)  # grouped by prefix
        for key, value in params.items():
            key, delim, sub_key = key.partition("__")
            if key not in valid_params:
                raise ValueError(
                    "Invalid parameter %s for estimator %s. "
                    "Check the list of available parameters "
                    "with `estimator.get_params().keys()`." % (key, self)
                )

            if delim:
                nested_params[key][sub_key] = value
            else:
                setattr(self, key, value)
                valid_params[key] = value

        for key, sub_params in nested_params.items():
            valid_params[key].set_params(**sub_params)

        return self

    def reset(self):
       """A method for reseting the predictor"""
       new = self.__class__(**self.get_params())
       return new

    def load_params(self, json_file):
      """A method to load kaggle competition configurations.

      Parameters
      -----------
      json_file : str
      Name of the json file containing the configuration.

      Returns
      ---------
      A new model instance with the new parameters.

      """

      module_path = dirname(__file__)
      with open(join(module_path, "model_configurations", json_file)) as json_data:
         config = json.load(json_data)

      link = config["link"]
      m = config["model"]
      print(f"model : {m}")
      print(f"reference:{link}" )
      self = self.__class__(**config["params"])
      print("params loaded")

      return self


import cv2 as cv
import numpy as np

noise = cv.imread('diamondsquare.png')
maps = cv.imread('bounding.jpg')
noise_gry = cv.cvtColor(noise, cv.COLOR_BGR2GRAY)
map_gry = cv.cvtColor(maps, cv.COLOR_BGR2GRAY)

cv.namedWindow("images", cv.WINDOW_NORMAL)
cv.imshow('images', map_gry)
cv.waitKey()

newImg = map_gry * (150/255) + noise_gry * (105/255)
newImg = np.rint(newImg).astype(np.uint8)
cv.imshow('images', newImg)
cv.imwrite('combinedImage.jpg', newImg)
cv.waitKey()


""" Behaviours to enable calendarish event extension to dexterity content
types.

"""

from zope import schema
from zope.component import adapts
from zope.interface import implements, alsoProvides
from plone.directives import form
from plone.app.event import messageFactory as _
from plone.dexterity.interfaces import IDexterityContent

# TODO: create different, minimalist behaviors for every aspect of an event.
# ILocationAware, IAttendee, IContact, IRecurrence

class IEvent(form.Schema):
    """Add tags to content
    """

    form.fieldset(
            'event',
            label=_(u'label_fieldset_event', default=u'Event'),
            fields=(
                'start',
                'end',
                'timezone',
                'recurrence',
                'whole_day',
                'location',
                'attendees',
                'event_url',
                'contact_name',
                'contact_email',
                'contact_phone',
                ),
        )

    start = schema.Datetime(
        title = _(u'label_start', default=u'Event start date'),
        description = _(u'help_start', default=u'Date and Time, when the event begins.'),
        required = True
        )

    end = schema.Datetime(
        title = _(u'label_end', default=u'Event end date'),
        description = _(u'help_end', default=u'Date and Time, when the event ends.'),
        required = True
        )

    timezone = schema.TextLine(
        title = _(u'label_timezone', default=u'Timezone'),
        description = _(u'help_timezone', default=u'Timezone of the event'),
        required = True,
        )

    recurrence = schema.TextLine(
        title = _(u'label_recurrence', default=u'Recurrence'),
        description = _(u'help_recurrence', default=u'RFC5545 compatible recurrence definition'),
    )

    whole_day = schema.Bool(
        title = _(u'label_whole_day', default=u'Whole Day'),
        description = _(u'help_whole_day', default=u'Event lasts whole day'),
        )

    location = schema.TextLine(
        title = _(u'label_location', default=u'Location'),
        description = _(u'help_location', default=u'Location of the event'),
        )

    attendees = schema.Text(
        title = _(u'label_attendees', default=u'Attendees'),
        description = _(u'help_attendees', default=u'List of attendees'),
        )

    event_url = schema.TextLine(
        title = _(u'label_event_url', default=u'Event Url'),
        description = _(u'help_event_url', default=u'Website of the event'),
        )

    contact_name = schema.TextLine(
        title = _(u'label_contact_name', default=u'Contact Name'),
        description = _(u'help_contact_name', default=u'Name of a person to contact about this event.'),
        )

    contact_email = schema.TextLine(
        title = _(u'label_contact_email', default=u'Contact Email'),
        description = _(u'help_contact_email', default=u'Email address to contact about this event.'),
        )

    contact_phone = schema.TextLine(
        title = _(u'label_contact_phone', default=u'Contact Phone'),
        description = _(u'help_contact_phone', default=u'Phone number to contact about this event.'),
        )

alsoProvides(IEvent, form.IFormFieldProvider)

class EventBase(object):
    """ This adapter acts as a Base Adapter for more specific Event Behaviors.
    """
    implements(IEvent)
    adapts(IDexterityContent)

    def __init__(self, context):
        self.context = context


#!/usr/bin/env python2
# -*- coding: utf-8 -*-
"""
Created on Thu Aug 30 15:44:08 2018

@author: wenzhiwang
"""

import pandas as pd

import numpy as np

import os

os.getcwd()

# read play, download, search
df_play = pd.read_csv('play_ds.csv')

df_play.head()

df_download = pd.read_csv('down_ds.csv')

df_download['download'] = 1

# I don't look at different time windows for simplicity

df_download.drop(['device','date'],axis = 1, inplace = True)

df_down = df_download.groupby(['uid','song_id']).agg('sum')

df_down.reset_index(inplace = True)

# filter out records with negative time

df_play['play_time'] = pd.to_numeric(df_play.play_time, errors='coerce')

df_play = df_play[ (df_play.play_time >= 0) & ( df_play.song_length >0) ]

df_play.dropna(inplace = True)

df_play.drop(['device','date'],axis = 1,inplace = True)

df_play_u_song = df_play.groupby(['uid','song_id']).agg('sum')

df_play_u_song.reset_index(inplace = True)

df_play_u_song['play'] = df_play_u_song.play_time/df_play_u_song.song_length

df_play_u_song = df_play_u_song[df_play_u_song.play <= 1]

# Merge download and play dataset
df = pd.merge(df_play_u_song,df_down, on = ['uid','song_id'], how = 'outer')

df.drop(['play_time','song_length'], axis = 1, inplace = True)

df.head()

# Compute implicit review score
df['score'] = 0

def Rating(df):

    if df[0] >= 5:
        return 7

    elif df[0] < 5 and df[0] >= 1 and df[1] > 0 :
        return 6

    elif df[0] < 5 and df[0] >= 1 and np.isnan(df[1]):
        return 5

    elif np.isnan(df[0]) and df[1] >= 0.8:
        return 4

    elif np.isnan(df[0]) and df[1] >= 0.6 and df[1] < 0.8 :
        return 3

    elif np.isnan(df[0]) and df[1] >= 0.3 and df[1] < 0.6 :
        return 2

    else:
        return 1

df.rename(columns = {'download':0, 'play': 1}, inplace = True)

df['score'] = df[[0,1]].apply(Rating,axis = 1)

df.drop([0,1], axis = 1, inplace = True)

## downsample the whold dataset

df_final = df[np.random.random(df.shape) < 0.005]

df_utility = pd.pivot_table(data=df_final,
                            values='score',
                            index='uid',
                            columns='song_id',
                            fill_value=0)

# Item-Item Similarity Matrix
item_sim_mat = cosine_similarity(df_utility.T)

least_to_most_sim_indexes = np.argsort(item_sim_mat, axis=1)

# Neighborhoods
neighborhood_size = 75
neighborhoods = least_to_most_sim_indexes[:, -neighborhood_size:]

# Let's pick a lucky user
user_id = df_utility.index[100]

n_users = df_utility.shape[0]
n_items = df_utility.shape[1]

start_time = time()

items_rated_by_this_user = df_utility.loc[user_id].nonzero()[0]

# Just initializing so we have somewhere to put rating preds
out = np.zeros(n_items)
for item_to_rate in range(n_items):
    relevant_items = np.intersect1d(neighborhoods[item_to_rate],
                                    items_rated_by_this_user,
                                    assume_unique=True)  # assume_unique speeds up intersection op

    out[item_to_rate] = np.dot(df_utility.loc[user_id][list(relevant_items)].values ,\
        item_sim_mat[item_to_rate, list(relevant_items)] )/ \
        item_sim_mat[item_to_rate, list(relevant_items)].sum()

pred_ratings = np.nan_to_num(out)

print(pred_ratings)

print("Execution time: %f seconds" % (time()-start_time))

# Recommend n business
n = 10

# Get item indexes sorted by predicted rating
item_index_sorted_by_pred_rating = list(np.argsort(pred_ratings))[::-1]

# Find items that have been rated by user
items_rated_by_this_user = df_utility.loc[user_id].nonzero()[0]

# We want to exclude the items that have been rated by user
unrated_items_by_pred_rating = [item for item in item_index_sorted_by_pred_rating
                                if item not in items_rated_by_this_user]

unrated_items_by_pred_rating[:n]

## NFM and UVC

ratings_mat = np.mat(df_utility.values)

from sklearn.decomposition import NMF

def fit_nmf(M,k):
    nmf = NMF(n_components=k)
    nmf.fit(M)
    W = nmf.transform(M);
    H = nmf.components_;
    err = nmf.reconstruction_err_
    return W,H,err

# decompose
W,H,err = fit_nmf(ratings_mat,200)

print(err)

print(W.shape,H.shape)

# reconstruct
ratings_mat_fitted = W.dot(H)
errs = np.array((ratings_mat-ratings_mat_fitted).flatten()).squeeze()
mask = np.array(ratings_mat.flatten()).squeeze()>0

mse = np.mean(errs[mask]**2)
average_abs_err = abs(errs[mask]).mean()
print(mse)
print(average_abs_err)

# get recommendations for one user
# user_id = df_utility.index[100]

user_id = 100
n = 10

pred_ratings = ratings_mat_fitted[user_id,:]
item_index_sorted_by_pred_rating = list(np.argsort(pred_ratings))[::-1]

items_rated_by_this_user = ratings_mat[user_id].nonzero()[1]

unrated_items_by_pred_rating = [item for item in item_index_sorted_by_pred_rating
                                if item not in items_rated_by_this_user]

unrated_items_by_pred_rating[:n]

### check errors
# truth
ratings_true = ratings_mat[user_id, items_rated_by_this_user]
# prediction
ratings_pred = pred_ratings[items_rated_by_this_user]
print(list(zip(np.array(ratings_true).squeeze(),ratings_pred)))

err_one_user = ratings_true-ratings_pred

print(err_one_user)

print(abs(err_one_user).mean())

######## Let's try UVD

from sklearn.decomposition import TruncatedSVD

def fit_uvd(M,k):
    # use TruncatedSVD to realize UVD
    svd = TruncatedSVD(n_components=k, n_iter=7, random_state=0)
    svd.fit(M)

    V = svd.components_
    U = svd.transform(M) # effectively, it's doing: U = M.dot(V.T)
    # we can ignore svd.singular_values_ for our purpose

    # why we can do this?
    # recall:
    # SVD start from u*s*v=M => u*s=M*v.T, where M*v.T is our transformation above
    # to get U in UVD
    # so the above U is effectively u*s in SVD
    # that's why U*V = u*s*v = M our original matrix
    # there are many ways to understand it!
    # here we by-passed singular values.

    return U,V, svd

# decompose
U,V,svd = fit_uvd(ratings_mat,200)

print(U.shape,V.shape)

# reconstruct
ratings_mat_fitted = U.dot(V) # U*V

# recall: U = M.dot(V.T), then this is M.dot(V.T).dot(V)
# original M is transformed to new space, then transformed back
# this is another way to understand it!

# calculate errs
errs = np.array((ratings_mat-ratings_mat_fitted).flatten()).squeeze()
mask = np.array((ratings_mat).flatten()).squeeze()>0

mse = np.mean(errs[mask]**2)
average_abs_err = abs(errs[mask]).mean()
print(mse)
print(average_abs_err)

# compare with another way to reconstruct matrix
# with the above "tranformed to the new space and back" language
# without the UV language, we can do:

# reconstruct M with inverse_transform
ratings_mat_fitted_2 = svd.inverse_transform(svd.transform(ratings_mat))
ratings_mat_fitted = U.dot(V)
print(sum(sum(ratings_mat_fitted - ratings_mat_fitted_2)))
# they are just equivalent!!

# get recommendations for one user
user_id = 100
n = 10

pred_ratings = ratings_mat_fitted[user_id,:]
item_index_sorted_by_pred_rating = list(np.argsort(pred_ratings))[::-1]

items_rated_by_this_user = ratings_mat[user_id].nonzero()[1]

unrated_items_by_pred_rating = [item for item in item_index_sorted_by_pred_rating
                                if item not in items_rated_by_this_user]

unrated_items_by_pred_rating[:n]

### check errors
# truth
ratings_true = ratings_mat[user_id, items_rated_by_this_user]
# prediction
ratings_pred = pred_ratings[items_rated_by_this_user]
print(list(zip(np.array(ratings_true).squeeze(),ratings_pred)))

err_one_user = ratings_true-ratings_pred
print(err_one_user)

print(abs(err_one_user).mean())


import pygame as pg

class Viewport(object):
    """A simple viewport/camera to handle scrolling and zooming a surface."""

    def __init__(self, base_map, view_size=(800, 800)):
        """The base_map argument should be a pygame.Surface object.
            Works best with view_size[0] == view_size[1]"""
        self.base_map = base_map
        self.base_rect = self.base_map.get_rect()
        self.zoom_levels = {}
        for i in range(10):
            self.zoom_levels[i] = (self.base_rect.width // 2**i,
                                             self.base_rect.height // 2**i)
        self.zoom_level = 0
        self.max_zoom = len(self.zoom_levels) - 1
        self.view_size = view_size
        self.zoom_rect = pg.Rect((0, 0), self.zoom_levels[self.zoom_level])
        self.scroll_margin = 20
        self.scroll_speed = 5
        self.scroll([0, 0])

    def scroll(self, offset):
        """Move self.room_rect by offset and update image."""
        self.zoom_rect.move_ip(offset)
        self.zoom_rect.clamp_ip(self.base_rect)
        self.zoom_image()

    def zoom_image(self):
        """Set self.zoomed_image to the properly scaled subsurface."""
        subsurface = self.base_map.subsurface(self.zoom_rect)
        self.zoomed_image = pg.transform.scale(subsurface, self.view_size)

    def get_map_pos(self, screen_pos):
        """Takes in a tuple of screen coordinates and returns a tuple of
            the screen_position translated to the proper map coordinates
            for the current zoom level."""
        view_width, view_height = self.view_size
        x, y = screen_pos
        x_scale = self.zoom_levels[self.zoom_level][0] / float(view_width)
        y_scale = self.zoom_levels[self.zoom_level][1] / float(view_height)
        mapx = self.zoom_rect.left + (x * x_scale)
        mapy = self.zoom_rect.top + (y * y_scale)
        return mapx, mapy

    def get_zoom_rect(self, mapx, mapy):
        """Return a Rect of the current zoom resolution centered at mapx, mapy."""
        zoom_rect = pg.Rect((0, 0), self.zoom_levels[self.zoom_level])
        zoom_rect.center = (mapx, mapy)
        zoom_rect.clamp_ip(self.base_rect)
        return zoom_rect

    def get_event(self, event):
        """Respond to MOUSEBUTTONDOWN events, zooming in on
            left click and out on right click."""
        if event.button == 1:
            if self.zoom_level < self.max_zoom:
                mapx, mapy = self.get_map_pos(event.pos)
                self.zoom_level += 1
                self.zoom_rect = self.get_zoom_rect(mapx, mapy)
                self.zoom_image()

        elif event.button == 3:
            if self.zoom_level > 0:
                mapx, mapy = self.get_map_pos(event.pos)
                self.zoom_level -= 1
                self.zoom_rect = self.get_zoom_rect(mapx, mapy)
                self.zoom_image()

    def update(self, surface=None):
        """Check for scrolling each frame."""
        if surface:
            self.base_map = surface
        mouse_pos = pg.mouse.get_pos()
        offset = [0, 0]
        if mouse_pos[0] < self.scroll_margin:
            offset[0] -= self.scroll_speed
        elif mouse_pos[0] > self.view_size[0] - self.scroll_margin:
            offset[0] += self.scroll_speed
        if mouse_pos[1] < self.scroll_margin:
            offset[1] -= self.scroll_speed
        elif mouse_pos[1] > self.view_size[1] - self.scroll_margin:
            offset[1] += self.scroll_speed
        if offset != [(0, 0)]:
            self.scroll(offset)

    def draw(self, surface):
        surface.blit(self.zoomed_image, (0, 0))


#Problem Statement: Swapping of raster bands

#step 1: We will load this raster and swap the order of the first and second bands.
#Then, we will add it to the map. To do this, we need to perform the following steps:
filepath="/home/abhishek/Desktop/M.Sc-GIS/data/FalseColor.tif"
layer=QgsRasterLayer(filepath,"FalseColor","gdal")

#step 2: ow, we must access the layer renderer in order to manipulate the order of the
#bands displayed. Note that this change does not affect the underlying data:
ren=layer.renderer()

#step 3: Next, we will set the red band to band 2:
ren.setRedBand(2)

#step 4:Now, we will set the green band to band 1:
ren.setGreenBand(1)

#step 5: add the altererd raster layer to the map
QgsProject.instance().addMapLayers([layer])


import pandas as pd
import time
import os
import json
import sys
import datetime

os.chdir(r"/Users/bholmes/Desktop/DeleteMeSoon/orus/JSON/hl7json/")
listOfFiles = os.listdir('.')

alltests = set()

sourceList = list()
source = ""
healthOrgList = list()
healthOrg = ""
reportIdList = list()
reportId = ""
MRNList = list()
MRN = ""
firstNameList = list()
firstName = ""
lastNameList = list()
lastName = ""
middleNameList = list()
middleName = ""
DOBList = list()
DOB = ""
genderList = list()
gender = ""
testTypeList = list()
testType = ""
resultList = list()
result = ""
orderedDateList = list()
orderedDate = ""

isLargeSample = False

for sampleJSON in listOfFiles:
    with open(sampleJSON) as json_file:
        print(sampleJSON)
        data = json.load(json_file)
        if len(data['patient_identification']) != 1:
            print("THE ASSUMPTION WAS WRONG, THERE CAN BE MORE THAN ONE PATIENT")
        firstName = data['patient_identification'][0]['patient_name']['name_first']
        lastName = data['patient_identification'][0]['patient_name']['name_last']

        # Names are probably difficult to get just right, and might have a low return on investment.
        # If we're getting MRN, don't worry about name TOO much.
        try:
            middleName = data['patient_identification'][0]['patient_name']['name_middle']
        except:
            middleName = ""
        if len(' '.split(firstName)) == 2:
            middleName = ' '.split(firstName)[1]
            firstName = ' '.split(firstName)[0]

        gender = data['patient_identification'][0]['administrative_sex']['identifier']
        mrn = data['patient_identification'][0]['patient_identifier_list']['id_number']
        DOB = data['patient_identification'][0]['date_time_of_birth']
        # Kind of making the decision that hour/minute/second doesn't matter for DOB. Could be wrong? Probably not.
        DOBobj = datetime.datetime.strptime(DOB, '%Y-%m-%dT%H:%M:%S.%fZ')
        new_format = "%Y-%m-%d"
        DOB = DOBobj.strftime(new_format)
        source = data['message_header'][0]['receiving_facility']
        healthOrg = data['message_header'][0]['sending_facility']
        reportId = data['message_header'][0]['message_control_id']
        testType = data['observation_request'][0]['universal_service_identifier']['text']

        for i in range(0, len(data['observation_result'])):
            result = ""
            # There are two kinds of results - one in which there are a number of observations together
            # with units, and another in which there is one large observation. We'll try to get the
            # individual units of the list, and, failing
            try:
                result = result + data['observation_result'][i]['observation_identifier']['original_text'] + " - "
                result = result + data['observation_result'][i]['observation_value'] + " "
                result = result + data['observation_result'][i]['units']['alternate_identifier']
            except:
                result = data['observation_result'][i]['observation_value']
                isLargeSample = True

            if isLargeSample:
                isLargeSample = False
                sourceList.append(source)
                healthOrgList.append(healthOrg)
                reportIdList.append(reportId)
                MRNList.append(MRN)
                firstNameList.append(firstName)
                middleNameList.append(middleName)
                lastNameList.append(lastName)
                DOBList.append(DOB)
                genderList.append(gender)
                testTypeList.append(testType)
                resultList.append(result)
                orderedDateList.append(orderedDate)

        source = ""
        healthOrg = ""
        reportId = ""
        MRN = ""
        firstName = ""
        middleName = ""
        lastName = ""
        DOB = ""
        gender = ""
        testType = ""
        result = ""
        orderedDate = ""

unformedDataFrame = pd.DataFrame(list(zip(reportIdList, sourceList, healthOrgList, MRNList, firstNameList,
                                          middleNameList, lastNameList, DOBList, genderList, testTypeList,
                                          orderedDateList, resultList)),
                                                            columns=['ReportId', 'Source', 'healthOrg', 'MRN',
                                                                 'firstName', 'middleName', 'lastName', 'DOB',
                                                                 'gender', 'testType', 'testOrderDate', 'result'])

#export_csv = unformedDataFrame.to_csv ('~/Desktop/DeleteMeSoon/LungAdenocarcinomaJson.csv', index=False)


import urcparse, pydub, sys

version = 1

args = sys.argv

data = urcparse.parse(open(args[1], "r").read())

print("URC to Audio Compiler v" + str(version))

exportf = data.metadata["ExportFile"]
music = pydub.AudioSegment.from_file(data.metadata["BaseFile"])

print(data.__soundlist__)
print(data.events)
print(str(data.events[0]))
sounds = {}

# open("log.json", "w").write(json.dumps(dict(data)))

for sound in data.sounds:
    sounds[sound.path] = pydub.AudioSegment.from_file(sound.path)

print(sounds)

# print offsets and how many bars they have
warningBars = []
for i in range(0, len(data.timeChanges)):
    if i != 0:
        ms_num = data.timeChanges[i].offset - data.timeChanges[i - 1].offset
        qnote = data.timeChanges[i - 1].bar_len() / 4
        bnum = data.timeChanges[i - 1].bar_num(ms_num)
        remainingBar = ms_num - (data.timeChanges[i - 1].bar_len() * (int(bnum) or 1))
        # print the number of bars for the previous offset
        print("\t" + str(bnum) + " bars (" + str(ms_num) + "/" + str(
            data.timeChanges[i - 1].bar_len() * (int(bnum) or 1)) + " ms)")
        if qnote > remainingBar > 0:
            warningBars.append([int(bnum) + data.timeChanges[i - 1].startBar, remainingBar, int(qnote)])

    print(str(data.timeChanges[i]))

print("")
for i in warningBars:
    print("!!! Bar " + str(i[0]) + " is " + str(i[1]) + " ms long! (Quarter note is " + str(i[2]) + " ms)")

for i in data.events:
    gain = 0
    if i.has_param("gain"):
        gain = int(i.params["gain"])
    music = music.overlay(sounds[i.event], position=i.time, gain_during_overlay=gain)

music.export(out_f=exportf, format="mp3")


from setuptools import setup, find_packages

def calculate_version(inputfile):
    version_list =  [x.split('\'')[1] for x in open(inputfile, 'r')
                     if x.startswith('__version__')]
    if version_list:
        return version_list[0]
    else:
        return '1.0'

package_version = calculate_version('./pdxSPA/_version.py')

setup(
    name='pdxSPA',
    version=package_version,
    author='Xi Cheng',
    author_email='chengxi0237@sjtu.edu.cn,',
    packages=find_packages(),
    install_requires=[
        'Click',
        'numpy',
        'pandas',
    ],

    entry_points="""
    [console_scripts]
    pdxSPA=pdxSPA.cli:main
    """,

    description='SPA (Shared Peptides Allocation) for quantifying the MS data from the PDX models.',
    license='GPL-3.0',
    classifiers=[
        'Intended Audience :: Proteomics',
        'Operating System :: POSIX :: Linux',
        'Programming Language :: Python',
        'Programming Language :: Python :: 2.7',
        'Programming Language :: Python :: 3.4',
        'Programming Language :: Python :: 3.5',
        'Programming Language :: Python :: 3.6',
    ],
    url='https://github.com/cathy0237/pdxSPA.git',

)


#import tensorflow as tf
from FER2013_Input import FER2013_Input
import csv
import numpy as np
import tensorflow as tf
from PIL import Image
from numpy import array
from scipy.misc import toimage
from resizeimage import resizeimage
#from tensorflow.examples.tutorials.mnist import input_data
#mnist = input_data.read_data_sets("/tmp/data/", one_hot = True)

n_classes = 7
batch_size = 128

x = tf.placeholder('float', [None, 42, 42])
y = tf.placeholder('float')#Ali

keep_rate = 0.8
keep_prob = tf.placeholder(tf.float32)

def conv2d(x,W):
     #The strides parameter dictates the movement of the window, 1 pixel at a time
     return tf.nn.conv2d(x,W, strides=[1,1,1,1], padding='SAME')

def maxpool2d(x):
     #Pooling Window Size = 2x2
     #Strides= 2; 2 pixels at a time
     return tf.nn.max_pool(x, ksize=[1,2,2,1], strides=[1,2,2,1], padding='SAME')

def convolutional_neural_network(x):
     weights = {
     # 5x5 convoltuion, 1 input image, 32 outputs
     'W_conv1': tf.Variable(tf.random_normal([5,5,1,32])),
     # 4x4 convoltuion, 32 inputs, 32 outputs
     'W_conv2': tf.Variable(tf.random_normal([4,4,32,32])),
     # 5x5 convoltuion, 32 inputs, 32 outputs
     'W_conv3': tf.Variable(tf.random_normal([5,5,32,64])),
     'W_fc1': tf.Variable(tf.random_normal([6*6*64, 3072])),
     'W_fc2': tf.Variable(tf.random_normal([3072, 7]))
     }
     biases = {
         'b_conv1' : tf.Variable(tf.random_normal([32])),
         'b_conv2' : tf.Variable(tf.random_normal([32])),
         'b_conv3' : tf.Variable(tf.random_normal([64])),
         'b_fc1' : tf.Variable(tf.random_normal([3072])),
         'b_fc2' : tf.Variable(tf.random_normal([7]))
     }

     x = tf.reshape(x, shape=[-1, 42, 42, 1])
     #Image42x42 = Image.fromarray(np.uint8(x))
     #toimage(Image42x42).show()

     conv1 = tf.nn.relu(conv2d(x, weights['W_conv1']) + biases['b_conv1'])
     conv1 = maxpool2d(conv1)

     conv2 = tf.nn.relu(conv2d(conv1, weights['W_conv2']) + biases['b_conv2'])
     conv2 = maxpool2d(conv2)

     conv3 = tf.nn.relu(conv2d(conv2, weights['W_conv3']) + biases['b_conv3'])
     conv3 = maxpool2d(conv3)

     #The image by now is 6x6
     fc1 = tf.reshape(conv3, [-1, 6*6*64])
     #fc1 = tf.reshape(fc1, [-1, 6*6*64])
     fc1 = tf.nn.relu(tf.matmul(fc1, weights['W_fc1']) + biases['b_fc1'])

    #not sure if we should reshape fc2
     fc2 = tf.reshape(fc1,[-1,3072])
     fc2 = tf.nn.relu(tf.matmul(fc1, weights['W_fc2']) + biases['b_fc2'])
     fc2 = tf.nn.dropout(fc2, keep_rate)
     return fc2

def train_neural_network(x):
     fer = FER2013_Input('/home/alaa/Desktop/GP/')
     #training_data
     #training_labels, training_images = fer.FER2013_Training_Set();
     #training_images = tf.image.resize_images(training_images, [42, 42])
     prediction = convolutional_neural_network(x)#Ali

     cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y, logits=prediction))#Ali
     optimizer = tf.train.GradientDescentOptimizer(0.00001).minimize(cost)

     hm_epochs = 32
     with tf.Session() as sess:
        #training_images = tf.image.resize_images(training_images, (42, 42))
        sess.run(tf.global_variables_initializer())#Ali
        #training_images = tf.image.resize_images(training_images, (42, 42))
		#Ali
        for epoch in range(hm_epochs):
            epoch_loss = 0
            for batchNum in range(int((28709+batch_size)/batch_size)):
                epoch_y, epoch_x = fer.Get_batch(batchNum, 'Training')

                _, c = sess.run([optimizer, cost], feed_dict={x: epoch_x, y: epoch_y})
                epoch_loss += c
                #print('Hello')

            print('Epoch', epoch+1, 'completed out of',hm_epochs,'loss:',epoch_loss)

        correct = tf.equal(tf.argmax(prediction, 1), tf.argmax(y, 1))
        #print('Correct in training: ',correct)
        testing_labels, testing_images = fer.FER2013_Testing_Set()
        accuracy = tf.reduce_mean(tf.cast(correct, 'float'))
        print('Accuracy:',accuracy.eval({x:testing_images, y:testing_labels}))

train_neural_network(x)


from datetime import datetime, timedelta

class AccountsController(object):
    #Creates an object to access user account limits and payments
    #This will return jsons of whether or not to accept an users deposit

    def __init__(self):

        #Initialize limits for deposits and accounts_json
        #accounts_json keys -> 'customer_id'
        #accounts_json will record user transaction limits

        self.accounts_json = {}
        self.daily_deposit_limit = 5000
        self.weekly_deposit_limit = 20000
        self.daily_loads = 3

    def processUserLoad(self, customer_json):
        #The main function for processing deposit attempts
        #Does a check if customer_id is an integer string
        #Then runs all the checks for daily load quota, daily amount deposit quota,
        #weekly amount deposit quota, and then updates accounts_json records if successful

        customer_id = customer_json['customer_id']
        load_id = customer_json['id']
        load_amount = self.convertLoadAmountToNum(customer_json['load_amount'])
        date_time = customer_json['time']
        response_json = {'id' : load_id, 'customer_id' : customer_id, 'accepted' : True}

        if not self.checkCustomerID(customer_id):
            response_json['accepted'] = False
            return response_json

        if customer_id not in self.accounts_json:
            self.addNewUser(customer_id)

        last_load_date = self.checkLastLoad(customer_id)
        num_days_difference, diff_week_check = self.compareLoadDates(customer_id, last_load_date, date_time)

        #Reset amounts used before running check if the last deposit was
        self.checkImplementResets(customer_id, num_days_difference, diff_week_check)

        #Check boolean if we are going over daily deposit amount
        if not self.compareDailyDollarAmount(customer_id, load_amount):
            response_json['accepted'] = False
            return response_json

        #Check boolean if we have done too many deposits today
        if not self.compareDailyLoadAmounts(customer_id):
            response_json['accepted'] = False
            return response_json

        #Check boolean if we are going over weekly deposit amount
        if not self.compareWeeklyDollarAmount(customer_id, load_amount):
            response_json['accepted'] = False
            return response_json

        self.updateUserRecords(customer_id, date_time, load_id, load_amount)
        return response_json

    def addNewUser(self, customer_id):
        #Initializes a new user in the accounts_json
        #accounts_json[customer_id] keys -> 'last_load_date' -> str
        #                                   'current_weekly_deposit_amount' -> float
        #                                   'current_daily_deposit_amount' -> float
        #                                   'current_daily_loads' -> int
        #                                   'load_ids' -> list

        self.accounts_json[customer_id] = {'last_load_date': '', 'current_weekly_deposit_amount' : 0,
                                            'current_daily_deposit_amount' : 0,
                                            'current_daily_loads' : 0, 'load_ids' : []}

    def compareLoadDates(self, customer_id, last_load_date, current_load_date):
        """We need to truncate the dates to midnight as its about checking if the load dates
        are on different days rather than just 24 hours. This also applies for the weekly truncate
        as it's not about being in a 7-day rolling interval but being in a different week
        truncated on mondays.

        We return the amount of days difference between last deposit and current attempt and also
        a boolean if it's a different week"""

        if last_load_date == '':
            self.updateUserLastLoadDate(customer_id, current_load_date)
            last_load_date = current_load_date

        current_time = self.processDate(current_load_date)
        last_load_time = self.processDate(last_load_date)

        current_time_trunc = datetime(current_time.year, current_time.month, current_time.day)
        last_load_time_trunc = datetime(last_load_time.year, last_load_time.month, last_load_time.day)

        last_load_time_trunc_weekly = last_load_time_trunc - timedelta(days = last_load_time_trunc.weekday())
        if (current_time_trunc - last_load_time_trunc_weekly).days >= 7:
            diff_week_check = True
        else:
            diff_week_check = False

        num_days_difference = (current_time_trunc - last_load_time_trunc).days

        return num_days_difference, diff_week_check

    def compareDailyDollarAmount(self, customer_id, current_deposit) -> bool:
        #The check if current deposit plus daily deposits already used is higher than weekly limit

        current_dollar_quota = self.daily_deposit_limit - self.checkDailyAmountDeposited(customer_id)
        if current_deposit <= current_dollar_quota:
            return True
        else:
            return False

    def compareDailyLoadAmounts(self, customer_id) -> bool:
        #The check if we have space for one more deposit in our daily load quota

        current_daily_load_quota = self.daily_loads - self.checkDailyLoadsDone(customer_id)
        if current_daily_load_quota >= 1:
            return True
        else:
            return False

    def compareWeeklyDollarAmount(self, customer_id, current_deposit) -> bool:
        #The check if current deposit plus weekly deposits already used is higher than weekly limit

        current_dollar_quota = self.weekly_deposit_limit - self.checkWeeklyAmountDeposited(customer_id)
        if current_deposit <= current_dollar_quota:
            return True
        else:
            return False

    def updateUserRecords(self, customer_id, load_date, load_id, deposit_amount):
        #This function just updates all user records in accounts_json for the successful deposit

        self.updateUserLastLoadDate(customer_id, load_date)
        self.updateUserWeeklyDepositAmount(customer_id, deposit_amount)
        self.updateUserDailyDepositAmount(customer_id, deposit_amount)
        self.updateLoads(customer_id, load_id)

    def updateUserLastLoadDate(self, customer_id, load_date):
        #Checks if this is the first deposit record then replaces
        #Also double checks if the new date is after the old one before replacing the last load date

        if self.accounts_json[customer_id]['last_load_date'] == '':
            self.accounts_json[customer_id]['last_load_date'] = load_date

        elif self.processDate(load_date) >= self.processDate(self.accounts_json[customer_id]['last_load_date']):
            self.accounts_json[customer_id]['last_load_date'] = load_date

        else:
            return {'status' : 'error', 'reason' : 'load date was given non-chronologically'}

        return {'status' : 'success', 'reason' : ''}

    def updateUserWeeklyDepositAmount(self, customer_id, deposit_amount):
        #Double check if the deposit amount is too high
        #If not, adds to the current weekly deposit amount used so far

        if deposit_amount <= self.weekly_deposit_limit:
            self.accounts_json[customer_id]['current_weekly_deposit_amount'] += deposit_amount
        else:
            return {'status' : 'error', 'reason' : 'deposit amount received was higher than weekly quota'}

        return {'status' : 'success', 'reason' : ''}

    def updateUserDailyDepositAmount(self, customer_id, deposit_amount):
        #Double check if the deposit amount is too high
        #If not, adds to the current daily deposit amount used so far

        if deposit_amount <= self.daily_deposit_limit:
            self.accounts_json[customer_id]['current_daily_deposit_amount'] += deposit_amount
        else:
            return {'status' : 'error', 'reason' : 'deposit amount received was higher than daily quota'}

        return {'status' : 'success', 'reason' : ''}

    def updateLoads(self, customer_id, load_id):
        #Double check if the current_daily_loads is being bypassed
        #Update the daily load counts if a deposit succeeds

        if self.accounts_json[customer_id]['current_daily_loads'] >= 3:
            return {'status' : 'error', 'reason' : 'current daily loads is already at 3 or more'}
        else:
            self.accounts_json[customer_id]['current_daily_loads'] += 1
            self.accounts_json[customer_id]['load_ids'].append(load_id)

        return {'status' : 'success', 'reason' : ''}

    def checkImplementResets(self, customer_id, num_days, diff_week_check):
        #The first check is for daily resets if the last deposit was on another day
        #The second check is if the last deposit was in another week truncated on mondays

        if num_days >= 1:
            self.resetDailyAmountDeposited(customer_id)
            self.resetDailyLoadsDone(customer_id)

        if diff_week_check:
            self.resetWeeklyAmountDeposited(customer_id)

    def resetDailyAmountDeposited(self, customer_id):
        self.accounts_json[customer_id]['current_daily_deposit_amount'] = 0

    def resetWeeklyAmountDeposited(self, customer_id):
        self.accounts_json[customer_id]['current_weekly_deposit_amount'] = 0

    def resetDailyLoadsDone(self, customer_id):
        self.accounts_json[customer_id]['current_daily_loads'] = 0

    def convertLoadAmountToNum(self, load_amount) -> float:
        #converts the currency string '$343.43' into float
        return float(load_amount[1:])

    def processDate(self, date_time) -> datetime:
        #processes date_time into datetime object for manipulation
        return datetime.strptime(date_time, "%Y-%m-%dT%H:%M:%SZ")

    def checkLastLoad(self, customer_id) -> str:
        #check last deposit date of user
        return self.accounts_json[customer_id]['last_load_date']

    def checkWeeklyAmountDeposited(self, customer_id) -> float:
        #check the current weekly amount user has used
        return self.accounts_json[customer_id]['current_weekly_deposit_amount']

    def checkDailyAmountDeposited(self, customer_id) -> float:
        #check the current daily amount user has used
        return self.accounts_json[customer_id]['current_daily_deposit_amount']

    def checkDailyLoadsDone(self, customer_id) -> int:
        return self.accounts_json[customer_id]['current_daily_loads']

    def checkLoadIDs(self, customer_id) -> list:
        #Pull record of load_ids in the form of list
        #Ie. ['34', '54656', ...]
        return self.accounts_json[customer_id]['load_ids']

    def checkCustomerID(self, customer_id) -> bool:
        #This checks if we were given a integer string for customer_id
        return str.isdigit(customer_id)


"""
This file contains extra hpy tests in addition to the ones which are in
test/_vendored.

The idea is that during development, sometimes it is useful to write tests
about certain specific features/code paths/corner cases which are not covered
(yet!) by the official hpy tests, so this is a place to collect them.

Once the development phase is finished, please move these tests to the main
hpy repo, and then copy them back here via ./update_vendored.sh.
"""

from pypy.module._hpy_universal.test._vendored.support import HPyTest

class TestExtra(HPyTest):
    pass

    """
    Additional tests to write:

      - check the .readonly field of HPyDef_MEMBER (and also the corresponding
        flag for the PyMemberDef cpy_compat case)

    ListBuilder:

      - in the C code there is logic to delay the MemoryError until we call
        ListBuilder_Build, but it is not tested

      - ListBuilder_Cancel is not tested

    """
    def test_import_failure(self):
        import pytest
        with pytest.raises(RuntimeError):
            self.make_module("""
                HPy_MODINIT(test)
                static HPy init_test_impl(HPyContext *ctx)
                {
                    HPyErr_SetString(ctx, ctx->h_RuntimeError, "foo");
                    return HPyLong_FromLong(ctx, 42);
                }
            """, name='test')

    def test_import_bad_module(self):
        import pytest
        with pytest.raises(SystemError):
            self.make_module("""
                HPy_MODINIT(test)
                static HPy init_test_impl(HPyContext *ctx)
                {
                    return HPy_NULL;
                }
            """, name='test')

    def test_HPyModule_Create(self):
        mod = self.make_module("""
            HPyDef_METH(f, "f", f_impl, HPyFunc_NOARGS)
            static HPy f_impl(HPyContext *ctx, HPy self)
            {
                HPyModuleDef def = {
                    .m_name = "foo",
                    .m_doc = "Some doc",
                    .m_size = -1,
                };
                return HPyModule_Create(ctx, &def);
            }
            @EXPORT(f)
            @INIT
        """)
        m = mod.f()
        assert m.__name__ == "foo"
        assert m.__doc__ == "Some doc"
        assert m.__package__ is None
        assert m.__loader__ is None
        assert m.__spec__ is None
        assert set(vars(m).keys()) == {
            '__name__', '__doc__', '__package__', '__loader__', '__spec__'}

class TestExtraCPythonCompatibility(HPyTest):
    # these tests are run with cpyext support, see conftest.py
    USE_CPYEXT = True


# 자바에서는 메서드라고 불리는게 파이썬에는 함수라 부른다.
# 매게변수(parameter) 함수에서 정의되어 사용되는 변수(인자라고도 부른다.)
# 인수(argument) 함수를 호출할 때 건네주는 변수

def add(a, b): # a, b는 매개변수(parameter)
    return a + b
print(add(3, 4)) # 3, 4는 인수(argument)
print("=" * 50)

# 예제
a = 1 # 여기서 a는 전역변수
def vartest(a): # 여기서 a는 지역변수
    a = a + 1

vartest(a)
print(a)
print("=" * 50)

# 예제
def add2(a, b):
    result = a + b
    return result;
print(add2(10, 15))
print("=" * 50)

# 클래스는 설계도 그 설계도에 의헤 만들어지는게 객체, 클래스는 명은 맨 앞글자를 대문자로 설정하는것이 관례이다.
# 객체는 값(변수)과 행동(함수, 자바에서는 메세드)이 있다.
class FourCal:

    # 생성자 : 클래스에서 무조건 인스턴스를 찍어내는 시점에 가장 먼저 실행이 된다.
    def __init__(self, first, second):
        self.first = first
        self.second = second

    def add(self): # 여기서 self는 a.setDat를 가리킨다. 이유는 처음 클래스를 사용할 객체를 만들 때 self를 a라고 지정했기 때문.
        result = self.first + self.second
        return result

# a = FourCal() TypeError: FourCal.__init__() missing 2 required positional arguments: 'first' and 'second'
# 위 오류는 생성자에는 2개의 인자를 받고 시작하는데 위 코드는 인수를 지정해주지 않아서 오류가 발생하였다.
a = FourCal(4, 2) # 자바로 치면 FourCal a = new FourCal(); 이다.
print(a.add())

# 클래스의 상속 : 어떤 클래스를 만들 때 다른 클래스의 기능을 물려받을 수 있게 만드는 것이다.
class MultFourCal(FourCal):
    def pow(self):
        re = self.first ** self.second
        return  re

b = MultFourCal(4,2)
print(b.pow())
print("=" * 50)
class Family:
    lastName = '김'

a = Family()
b = Family()

print(a.lastName)
print(b.lastName)


# -*- coding: utf-8 -*-

from __future__ import annotations

from matplotlib.figure import Figure
import matplotlib.pyplot as plt
import numpy as np

from ..configuration import PLOT_PARAMETERS, FEATURE_CLUSTER_COLORS
from ..util import interpolate
from ..language_model import LanguageModel
from .util import index_to_position

def get_position_numbers(language_model: LanguageModel) -> np.ndarray:
    position_numbers = np.array([
        index_to_position(language_model, index)
        for index
        in range(len(language_model.positional_vectors))
    ])
    return position_numbers

def gamma_forward(x):
    return np.sign(x) * np.abs(x)**PLOT_PARAMETERS['axis_gamma']

def gamma_inverse(x):
    return np.sign(x) * np.abs(x)**(1.0 / PLOT_PARAMETERS['axis_gamma'])

def plot_position_importance(*language_models: LanguageModel) -> Figure:
    if len(language_models) < 1:
        message = 'Expected at least one language model, got {}'
        message = message.format(len(language_models))
        raise ValueError(message)
    fig, ax = plt.subplots(1, 1)
    for language_model in language_models:
        importance = language_model.position_importance
        X = get_position_numbers(language_model)
        Y = importance.data
        ax.scatter(X, Y, zorder=2)
        X, Y = interpolate(X, gamma_forward(Y))
        label = language_model.friendly_name
        ax.plot(X, gamma_inverse(Y), label=label.capitalize(), zorder=3)
    ax.legend()
    ax.set_yscale('function', functions=(gamma_forward, gamma_inverse))
    return fig

def plot_clustered_positional_features(language_model: LanguageModel) -> Figure:
    X = get_position_numbers(language_model)
    absolute_positional_features = np.abs(language_model.positional_vectors).T
    positional_feature_clusters = language_model.positional_feature_clusters
    labels = [
        *[
            label
            for label
            in FEATURE_CLUSTER_COLORS
            if label in positional_feature_clusters
        ],
        *sorted([
            label
            for label, _
            in positional_feature_clusters
            if label not in FEATURE_CLUSTER_COLORS
        ]),
    ]
    cmap = plt.get_cmap()
    fig, ax = plt.subplots(1, 1)
    for label in labels:
        color = cmap(FEATURE_CLUSTER_COLORS[label])
        indexes = positional_feature_clusters[label]
        cluster_size = len(indexes)
        linewidth = plt.rcParams['lines.linewidth'] / cluster_size**PLOT_PARAMETERS['line_gamma']
        for Y in absolute_positional_features[indexes]:
            ax.plot(*interpolate(X, Y), color=color, linewidth=linewidth, alpha=PLOT_PARAMETERS['line_alpha'])
        Y = np.mean(absolute_positional_features[indexes], axis=0)
        label = '{} features ({})'.format(label, cluster_size)
        ax.scatter(X, Y, color=color, zorder=2)
        ax.plot(*interpolate(X, Y), label=label.capitalize(), color=color, zorder=3)
    ax.legend()
    return fig


#stable
#T.C.->O(nlogn)
def merge_sort(arr):

    def merge(arr, L,M,R):
        left, right = arr[L:M+1], arr[M+1: R+1]
        i,j,k = L,0,0
        while j < len(left) and k <len(right):
            if left[j] <=right[k]:
                arr[i] = left[j]
                i +=1
                j +=1

            else:
                arr[i] = right[k]
                i += 1
                k += 1

        while j < len(left):
            arr[i] = left[j]
            i +=1
            j +=1

        while k < len(right):
            arr[i] =right[k]
            i +=1
            k +=1

    def split_array(arr,l,r):
        if l==r:
            return arr
        mid = l+ (r-l)//2
        split_array(arr, l, mid)
        split_array(arr, mid+1, r)
        merge(arr,l,mid,r)

    return split_array(arr, 0, len(arr)-1)

if __name__ == '__main__':
    arr = [5,3,2,1]
    val = merge_sort(arr)
    print(val)


# Advent of code 2022, by Ghostkeeper

def read_cargo_stacks(input):
	"""
	From the start of the input, read the cargo on the cargo stacks.
	:param input: A puzzle input, starting with cargo stacks.
	:return: A number of stacks, each a list with items in it (of a single character).
	"""
	num_stacks = int(len(input[0]) / 4)  # One space and 3 characters per stack, so divide by 4.
	stacks = [[] for _ in range(num_stacks)]  # Create empty stacks.

	for line in input:
		if line[0] == " ":  # End of stack input data.
			break
		for i in range(num_stacks):
			item = line[i * 4 + 1]
			if item == " ":  # Empty, the stack isn't this high.
				continue
			stacks[i].insert(0, item)  # Put at bottom of stack.
	return stacks


# Common training-related configs that are designed for "tools/train_net.py"
# You can use your own instead, together with your own train_net.py
train = dict(
    # Directory where output files are written to
    output_dir="./output",
    # The initialize checkpoint to be loaded
    init_checkpoint="",
    # The total training iterations
    max_iter=90000,
    # options for Automatic Mixed Precision
    amp=dict(enabled=False),
    # options for DistributedDataParallel
    ddp=dict(
        broadcast_buffers=False,
        find_unused_parameters=False,
        fp16_compression=False,
    ),
    # options for Gradient Clipping during training
    clip_grad=dict(
        enabled=False,
        params=dict(
            max_norm=0.1,
            norm_type=2,
        ),
    ),
    # training seed
    seed=-1,
    # options for Fast Debugging
    fast_dev_run=dict(enabled=False),
    # options for PeriodicCheckpointer, which saves a model checkpoint
    # after every `checkpointer.period` iterations,
    # and only `checkpointer.max_to_keep` number of checkpoint will be kept.
    checkpointer=dict(period=5000, max_to_keep=100),
    # run evaluation after every `eval_period` number of iterations
    eval_period=5000,
    # output log to console every `log_period` number of iterations.
    log_period=20,
    # logging training info to Wandb
    # note that you should add wandb writer in `train_net.py``
    wandb=dict(
        enabled=False,
        params=dict(
            dir="./wandb_output",
            project="detrex",
            name="detrex_experiment",
        )
    ),
    # model ema
    model_ema=dict(
        enabled=False,
        decay=0.999,
        device="",
        use_ema_weights_for_eval_only=False,
    ),
    # the training device, choose from {"cuda", "cpu"}
    device="cuda",
    # ...
)


# ! /usr/bin/python3
"""### Provide tools for placing and getting blocks and more.
This module contains functions to:
* Request the build area as defined in-world
* Run Minecraft commands
* Get the name of a block at a particular coordinate
* Place blocks in the world
"""
__all__ = ['Interface', 'requestBuildArea', 'requestPlayerArea', 'runCommand',
           'isBuffering', 'setBuffering', 'getBufferLimit', 'setBufferLimit',
           'isCaching', 'setCaching', 'getCacheLimit', 'setCacheLimit',
           'getBlock', 'fill', 'setBlock', 'sendBlocks']
__version__ = "v4.2_dev"

from collections import OrderedDict
from random import choice

from collections import OrderedDict
from random import choice

import lib.direct_interface as di
import numpy as np
from lib.lookup import TCOLORS
from lib.worldLoader import WorldSlice

class OrderedByLookupDict(OrderedDict):
    """Limit size, evicting the least recently looked-up key when full.
    Taken from
    https://docs.python.org/3/library/collections.html?highlight=ordereddict#collections.OrderedDict
    """

    def __init__(self, maxsize, *args, **kwds):
        self.maxsize = maxsize
        super().__init__(*args, **kwds)

    # inherited __repr__ from OrderedDict is sufficient

    def __getitem__(self, key):
        value = super().__getitem__(key)
        self.move_to_end(key)
        return value

    def __setitem__(self, key, value):
        if key in self:
            self.move_to_end(key)
        super().__setitem__(key, value)
        if self.maxsize > 0 and len(self) > self.maxsize:
            oldest = next(iter(self))
            del self[oldest]

class Interface():
    """**Provides tools for interacting with the HTML interface**.
    All function parameters and returns are in local coordinates.
    """

    def __init__(self, x=0, y=0, z=0,
                 buffering=False, bufferlimit=1024,
                 caching=False, cachelimit=8192):
        """**Initialise an interface with offset and buffering**."""
        self.offset = x, y, z
        self.__buffering = buffering
        self.bufferlimit = bufferlimit
        self.buffer = []    # buffer is in global coordinates
        self.caching = caching
        # cache is in global coordinates
        self.cache = OrderedByLookupDict(cachelimit)
        # Interface.cache.maxsize to change size

    def __del__(self):
        """**Clean up before destruction**."""
        self.sendBlocks()

    # __repr__ displays the class well enough so __str__ is omitted
    def __repr__(self):
        """**Represent the Interface as a constructor**."""
        return "Interface(" \
            f"{self.offset[0]}, {self.offset[1]}, {self.offset[2]}, " \
            f"{self.__buffering}, {self.bufferlimit}, " \
            f"{self.caching}, {self.cache.maxsize})"

    def getBlock(self, x, y, z):
        """**Return the name of a block in the world**.
        Takes local coordinates, works with global coordinates
        """
        x, y, z = self.local2global(x, y, z)

        if self.caching and (x, y, z) in self.cache:
            return self.cache[(x, y, z)]

        if self.caching and globalWorldSlice is not None:
            dx, dy, dz = global2buildlocal(x, y, z)  # convert for decay index
            if not checkOutOfBounds(x, y, z) and not globalDecay[dx][dy][dz]:
                block = globalWorldSlice.getBlockAt(x, y, z)
                self.cache[(x, y, z)] = block
                return block
        response = di.getBlock(x, y, z)
        if self.caching:
            self.cache[(x, y, z)] = response

        return response

    def fill(self, x1, y1, z1, x2, y2, z2, replaceBlock):
        """**Fill the given region with the given block**.
        Supports sequences of block strings for random texturing
        Works with local coordinates
        """
        from lib.toolbox import loop3d
        textured = False
        if type(replaceBlock) != str:
            textured = True

        for x, y, z in loop3d(x1, y1, z1, x2, y2, z2):
            if textured:
                self.setBlock(x, y, z, choice(replaceBlock))
            else:
                self.setBlock(x, y, z, replaceBlock)

    def replace(self, x1, y1, z1, x2, y2, z2, searchBlock, replaceBlock):
        """**Replace searchBlock with replaceBlock**.
        Supports sequences of block strings for random texturing
        Works with local coordinates
        """
        from lib.toolbox import loop3d
        textured = False
        if type(replaceBlock) != str:
            textured = True

        for x, y, z in loop3d(x1, y1, z1, x2, y2, z2):
            if self.getBlock(x, y, z) == searchBlock:
                if textured:
                    self.setBlock(x, y, z, choice(replaceBlock))
                else:
                    self.setBlock(x, y, z, replaceBlock)

    def setBlock(self, x: int, y: int, z: int, blockStr: str):
        """**Place a block in the world depending on buffer activation**.
        Takes local coordinates, works with local and global coordinates
        """
        if self.__buffering:
            response = self.placeBlockBatched(x, y, z, blockStr,
                                              self.bufferlimit)
        else:
            response = self.placeBlock(x, y, z, blockStr)

        # switch to global coordinates
        x, y, z = self.local2global(x, y, z)
        if self.caching:
            self.cache[(x, y, z)] = blockStr
        # mark block as decayed
        if not checkOutOfBounds(x, y, z) and globalDecay is not None:
            x, y, z = global2buildlocal(x, y, z)
            globalDecay[x][y][z] = True

        return response

    def placeBlock(self, x, y, z, blockStr):
        """**Place a single block in the world directly**.
        Takes local coordinates, works with global coordinates
        """
        x, y, z = self.local2global(x, y, z)
        result = di.setBlock(x, y, z, blockStr)
        if not result.isnumeric():
            print(f"{TCOLORS['orange']}Warning: Server returned error "
                  f"upon placing block:\n\t{TCOLORS['CLR']}{result}")
        return result

    # ----------------------------------------------------- block buffers

    def isBuffering(self):
        """**Get self.__buffering**."""
        return self.__buffering

    def setBuffering(self, value):
        """**Set self.__buffering**."""
        self.__buffering = value
        if not self.__buffering:
            self.sendBlocks()

    def getBufferLimit(self):
        """**Get self.bufferlimit**."""
        return self.bufferlimit

    def setBufferLimit(self, value):
        """**Set self.bufferlimit**."""
        self.bufferlimit = value

    def isCaching(self):
        """**Get self.caching**."""
        return self.caching

    def setCaching(self, value=False):
        """**Set self.caching**."""
        self.caching = value

    def getCacheLimit(self):
        """**Get maximum cache size**."""
        return self.cache.maxsize

    def setCacheLimit(self, value=8192):
        """**Set maximum cache size**."""
        self.cache.maxsize = value

    def placeBlockBatched(self, x, y, z, blockStr, limit=50):
        """**Place a block in the buffer and send once limit is exceeded**.
        Takes local coordinates and works with global coordinates
        """
        x, y, z = self.local2global(x, y, z)

        self.buffer.append((x, y, z, blockStr))
        if len(self.buffer) >= limit:
            return self.sendBlocks()
        else:
            return None

    def sendBlocks(self, x=0, y=0, z=0, retries=5):
        """**Send the buffer to the server and clear it**.
        Since the buffer contains global coordinates
            no conversion takes place in this function
        """
        if self.buffer == []:
            return
        response = di.sendBlocks(self.buffer, x, y, z, retries).split('\n')
        if all(map(lambda val: val.isnumeric(), response)):  # no errors
            self.buffer = []
        else:
            print(f"{TCOLORS['orange']}Warning: Server returned error upon "
                  f"sending block buffer:\n\t{TCOLORS['CLR']}{repr(response)}")

    # ----------------------------------------------------- utility functions

    def local2global(self, x, y, z):
        """**Translate local to global coordinates**."""
        result = []
        if x is not None:
            result.append(x + self.offset[0])
        if y is not None:
            result.append(y + self.offset[1])
        if z is not None:
            result.append(z + self.offset[2])
        return result

    def global2local(self, x, y, z):
        """**Translate global to local coordinates**."""
        result = []
        if x is not None:
            result.append(x - self.offset[0])
        if y is not None:
            result.append(y - self.offset[1])
        if z is not None:
            result.append(z - self.offset[2])
        return result

        #------------ caranha functions

def makeBuildArea(width = 128, height = 128):
    runCommand("execute at @p run setbuildarea ~{} 0 ~{} ~{} 256 ~{}".format(int(-1*width/2), int(-1*height/2), int(width/2), int(height/2)))
    buildArea = requestBuildArea()
    x1 = buildArea["xFrom"]
    z1 = buildArea["zFrom"]
    x2 = buildArea["xTo"]
    z2 = buildArea["zTo"]
    return (x1, z1, x2 - x1, z2 - z1)

def setSignText(x, y, z, line1 = "", line2 = "", line3 = "", line4 = ""):
    l1 = 'Text1:\'{"text":"'+line1+'"}\''
    l2 = 'Text2:\'{"text":"'+line2+'"}\''
    l3 = 'Text3:\'{"text":"'+line3+'"}\''
    l4 = 'Text4:\'{"text":"'+line4+'"}\''
    blockNBT = "{"+l1+","+l2+","+l3+","+l4+"}"
    runCommand("data merge block {} {} {} ".format(x, y, z) + blockNBT)
    return(runCommand("data merge block {} {} {} ".format(x, y, z) + blockNBT))

def addItemChest(x, y, z, items, places=[]):
    if len(places) == 0:
        places = list(range(len(items)))
    for id, v in enumerate(items):
        id = places[id]
        command = "replaceitem block {} {} {} {} {} {}".format(x, y, z,
                                                               "container."+str(id),
                                                               v[0],
                                                               v[1])
        runCommand(command)
def makeBookItem(text, title = "", author = "", desc = ""):
    booktext = "pages:["
    while len(text) > 0:
        page = text[:15*23]
        text = text[15*23:]
        bookpage = "'{\"text\":\""
        while len(page) > 0:
            line = page[:23]
            page = page[23:]
            bookpage += line+"\\\\n"
        bookpage += "\"}',"
        booktext += bookpage
    booktext = booktext + "],"
    booktitle = "title:\""+title+"\","
    bookauthor = "author:\""+author+"\","
    bookdesc = "display:{Lore:[\""+desc+"\"]}"
    return "written_book{"+booktext+booktitle+bookauthor+bookdesc+"}"

def runCommand(command):
    """**Run a Minecraft command in the world**."""
    return di.runCommand(command)

def setBuildArea(x1, y1, z1, x2, y2, z2):
    runCommand(f"setbuildarea {x1} {y1} {z1} {x2} {y2} {z2}")
    return requestBuildArea()

def requestBuildArea():
    """**Return the current building area**.
    Will reset anything dependant on the build area.
    """
    global globalBuildArea

    x1, _, z1, x2, _, z2 = globalBuildArea = di.requestBuildArea()

    if globalWorldSlice is not None:
        resetGlobalDecay()

    return globalBuildArea

def requestPlayerArea(dx=128, dz=128):
    """**Return the building area surrounding the player**."""
    # Correcting for offset from player position
    runCommand("execute at @p run setbuildarea "
               f"~{-dx//2} 0 ~{-dz//2} ~{dx//2} 256 ~{dz//2}")
    return requestBuildArea()

# ========================================================= global interface

globalWorldSlice = None
globalDecay = None
globalBuildArea = requestBuildArea()

globalinterface = Interface()

def makeGlobalSlice():
    """**Instantiate a global WorldSlice and refresh building area**."""
    global globalWorldSlice
    x1, y1, z1, x2, y2, z2 = requestBuildArea()
    globalWorldSlice = WorldSlice(x1, z1, x2, z2, heightmapTypes=["MOTION_BLOCKING_NO_LEAVES"])
    resetGlobalDecay()

def getBlock(x, y, z):
    """**Global getBlock**."""
    return globalinterface.getBlock(x, y, z)

def fill(x1, y1, z1, x2, y2, z2, replaceBlock):
    """**Global fill**."""
    return globalinterface.fill(x1, y1, z1, x2, y2, z2, replaceBlock)

def replace(x1, y1, z1, x2, y2, z2, searchBlock, replaceBlock):
    """**Global replace**."""
    return globalinterface.replace(x1, y1, z1, x2, y2, z2,
                                   searchBlock, replaceBlock)

def setBlock(x, y, z, blockStr):
    """**Global setBlock**."""
    return globalinterface.setBlock(x, y, z, blockStr)

# ----------------------------------------------------- block buffers

def isCaching():
    """**Global isCaching**."""
    return globalinterface.caching

def setCaching(value=False):
    """**Global setCaching**."""
    globalinterface.caching = value

def getCacheLimit():
    """**Global getCacheLimit**."""
    return globalinterface.cache.maxsize

def setCacheLimit(value=8192):
    """**Global setCacheLimit**."""
    globalinterface.cache.maxsize = value

def isBuffering():
    """**Global isBuffering**."""
    return globalinterface.isBuffering()

def setBuffering(val):
    """**Global setBuffering**."""
    globalinterface.setBuffering(val)

def getBufferLimit():
    """**Global getBufferLimit**."""
    return globalinterface.getBufferLimit()

def setBufferLimit(val):
    """**Global setBufferLimit**."""
    globalinterface.setBufferLimit(val)

def sendBlocks(x=0, y=0, z=0, retries=5):
    """**Global sendBlocks**."""
    return globalinterface.sendBlocks(x, y, z, retries)

# ----------------------------------------------------- utility functions

def global2buildlocal(x, y, z):
    """**Convert global coordinates to ones relative to the build area**."""
    x0, y0, z0, _, _, _ = globalBuildArea
    return x - x0, y - y0, z - z0

def checkOutOfBounds(x, y, z, warn=True):
    """**Check whether a given coordinate is outside the build area**."""
    x1, y1, z1, x2, y2, z2 = globalBuildArea
    if not (x1 <= x <= x2 and y1 <= y <= y2 and z1 <= z <= z2):
        if warn:
            # building outside the build area can be less efficient
            print(f"{TCOLORS['orange']}WARNING: Block at {x, y, z} is outside "
                  f"the build area!{TCOLORS['CLR']}")
        return True
    return False

def resetGlobalDecay():
    global globalDecay
    x1, _, z1, x2, _, z2 = globalBuildArea
    globalDecay = np.zeros((x2 - x1, 256, z2 - z1), dtype=bool)