from __future__ import print_function

import os
import numpy as np
from tqdm import trange
from datetime import datetime
import time

from model import *
from util import *
from trainer import Trainer

class Trainer3(Trainer):
    def build_model(self):
        if self.use_c:
            self.G_s, self.G_var = GeneratorBE3(self.y, self.filters, self.output_shape,
                                               num_conv=self.num_conv, repeat=self.repeat)
            _, self.G_ = jacobian3(self.G_s)
        else:
            self.G_, self.G_var = GeneratorBE3(self.y, self.filters, self.output_shape,
                                              num_conv=self.num_conv, repeat=self.repeat)
        self.G = denorm_img3(self.G_) # for debug

        self.G_jaco_, self.G_vort_ = jacobian3(self.G_)
        self.G_vort = denorm_img3(self.G_vort_)

        if 'dg' in self.arch:
            # discriminator
            # self.D_x, self.D_var = DiscriminatorPatch3(self.x, self.filters)
            # self.D_G, _ = DiscriminatorPatch3(self.G_, self.filters, reuse=True)
            D_in = tf.concat([self.x, self.x_vort], axis=-1)
            self.D_x, self.D_var = DiscriminatorPatch3(D_in, self.filters)
            G_in = tf.concat([self.G_, self.G_vort_], axis=-1)
            self.D_G, _ = DiscriminatorPatch3(G_in, self.filters, reuse=True)

        show_all_variables()

        if self.optimizer == 'adam':
            optimizer = tf.train.AdamOptimizer
            g_optimizer = optimizer(self.g_lr, beta1=self.beta1, beta2=self.beta2)
        elif self.optimizer == 'gd':
            optimizer = tf.train.GradientDescentOptimizer
            g_optimizer = optimizer(self.g_lr)
        else:
            raise Exception("[!] Invalid opimizer")

        # losses
        self.g_loss_l1 = tf.reduce_mean(tf.abs(self.G_ - self.x))
        self.g_loss_j_l1 = tf.reduce_mean(tf.abs(self.G_jaco_ - self.x_jaco))
        self.g_loss = self.g_loss_l1*self.w1 + self.g_loss_j_l1*self.w2

        if 'dg' in self.arch:
            self.g_loss_real = tf.reduce_mean(tf.square(self.D_G-1))
            self.d_loss_fake = tf.reduce_mean(tf.square(self.D_G))
            self.d_loss_real = tf.reduce_mean(tf.square(self.D_x-1))

            self.g_loss += self.g_loss_real*self.w3

            self.d_loss = self.d_loss_real + self.d_loss_fake
            self.d_optim = g_optimizer.minimize(self.d_loss, var_list=self.D_var)

        self.g_optim = g_optimizer.minimize(self.g_loss, global_step=self.step, var_list=self.G_var)
        self.epoch = tf.placeholder(tf.float32)

        # summary
        summary = [
            # tf.summary.image("xy/G", self.G['xy']),
            # tf.summary.image("zy/G", self.G['zy']),
            tf.summary.image("xym/G", self.G['xym'][:,::-1]),
            tf.summary.image("zym/G", self.G['zym'][:,::-1]),

            # tf.summary.image("xy/G_vort", self.G_vort['xy']),
            # tf.summary.image("zy/G_vort", self.G_vort['zy']),
            tf.summary.image("xym/G_vort", self.G_vort['xym'][:,::-1]),
            tf.summary.image("zym/G_vort", self.G_vort['zym'][:,::-1]),

            tf.summary.scalar("loss/g_loss", self.g_loss),
            tf.summary.scalar("loss/g_loss_l1", self.g_loss_l1),
            tf.summary.scalar("loss/g_loss_j_l1", self.g_loss_j_l1),

            tf.summary.scalar("misc/epoch", self.epoch),
            tf.summary.scalar('misc/q', self.batch_manager.q.size()),

            tf.summary.histogram("y", self.y),

            tf.summary.scalar("misc/g_lr", self.g_lr),
        ]

        if 'dg' in self.arch:
            summary += [
                tf.summary.scalar("loss/g_loss_real", tf.sqrt(self.g_loss_real)),
                tf.summary.scalar("loss/d_loss_real", tf.sqrt(self.d_loss_real)),
                tf.summary.scalar("loss/d_loss_fake", tf.sqrt(self.d_loss_fake)),
            ]

        self.summary_op = tf.summary.merge(summary)

        # summary once
        x = denorm_img3(self.x)
        x_vort = denorm_img3(self.x_vort)

        summary = [
            tf.summary.image("xym/x", x['xym'][:,::-1]),
            tf.summary.image("zym/x", x['zym'][:,::-1]),
            tf.summary.image("xym/vort", x_vort['xym'][:,::-1]),
            tf.summary.image("zym/vort", x_vort['zym'][:,::-1]),
        ]
        self.summary_once = tf.summary.merge(summary) # call just once

    def train(self):
        if 'ae' in self.arch:
            self.train_ae()
        elif 'nn' in self.arch:
            self.train_nn()
        else:
            self.train_()

    def train_(self):
        # test1: varying on each axis
        z_range = [-1, 1]
        z_shape = (self.b_num, self.c_num)
        z_samples = []
        z_varying = np.linspace(z_range[0], z_range[1], num=self.b_num)

        for i in range(self.c_num):
            zi = np.zeros(shape=z_shape)
            zi[:,i] = z_varying
            z_samples.append(zi)

        # test2: compare to gt
        gen_list = self.batch_manager.random_list(self.b_num)
        x_xy = np.concatenate((gen_list['xym'],gen_list['xym_c']), axis=0)
        x_zy = np.concatenate((gen_list['zym'],gen_list['zym_c']), axis=0)
        save_image(x_xy, '{}/x_fixed_xym_gt.png'.format(self.model_dir), padding=1, nrow=self.b_num)
        save_image(x_zy, '{}/x_fixed_zym_gt.png'.format(self.model_dir), padding=1, nrow=self.b_num)
        with open('{}/x_fixed_gt.txt'.format(self.model_dir), 'w') as f:
            f.write(str(gen_list['p']) + '\n')
            f.write(str(gen_list['z']))

        zi = np.zeros(shape=z_shape)
        for i, z_gt in enumerate(gen_list['z']):
            zi[i,:] = z_gt
        z_samples.append(zi)

        # call once
        summary_once = self.sess.run(self.summary_once)
        self.summary_writer.add_summary(summary_once, 0)
        self.summary_writer.flush()

        # train
        for step in trange(self.start_step, self.max_step):
            if 'dg' in self.arch:
                self.sess.run([self.g_optim, self.d_optim])
            else:
                self.sess.run(self.g_optim)

            if step % self.log_step == 0 or step == self.max_step-1:
                ep = step*self.batch_manager.epochs_per_step
                loss, summary = self.sess.run([self.g_loss,self.summary_op],
                                              feed_dict={self.epoch: ep})
                assert not np.isnan(loss), 'Model diverged with loss = NaN'
                print("\n[{}/{}/ep{:.2f}] Loss: {:.6f}".format(step, self.max_step, ep, loss))

                self.summary_writer.add_summary(summary, global_step=step)
                self.summary_writer.flush()

            if step % self.test_step == 0 or step == self.max_step-1:
                self.generate(z_samples, self.model_dir, idx=step)

            if self.lr_update == 'step':
                if step % self.lr_update_step == self.lr_update_step - 1:
                    self.sess.run(self.g_lr_update)
            else:
                self.sess.run(self.g_lr_update)

        # save last checkpoint..
        save_path = os.path.join(self.model_dir, 'model.ckpt')
        self.saver.save(self.sess, save_path, global_step=self.step)
        self.batch_manager.stop_thread()

    def build_test_model(self):
        # build a model for testing
        self.z = tf.placeholder(dtype=tf.float32, shape=[self.test_b_num, self.c_num])
        if self.use_c:
            self.G_s, _ = GeneratorBE3(self.z, self.filters, self.output_shape,
                                      num_conv=self.num_conv, repeat=self.repeat, reuse=True)
            self.G_ = curl(self.G_s)
        else:
            self.G_, _ = GeneratorBE3(self.z, self.filters, self.output_shape,
                                     num_conv=self.num_conv, repeat=self.repeat, reuse=True)

    def generate(self, inputs, root_path=None, idx=None):
        # xy_list = []
        # zy_list = []
        xym_list = []
        zym_list = []

        # xyw_list = []
        # zyw_list = []
        xymw_list = []
        zymw_list = []

        for _, z_sample in enumerate(inputs):
            xym, zym = self.sess.run( # xy, zy,
                [self.G['xym'], self.G['zym']], {self.y: z_sample}) # self.G['xy'], self.G['zy'],
            # xy_list.append(xy)
            # zy_list.append(zy)
            xym_list.append(xym)
            zym_list.append(zym)

            xym, zym = self.sess.run( # xy, zy,
                [self.G_vort['xym'], self.G_vort['zym']], {self.y: z_sample}) # self.G_vort['xy'], self.G_vort['zy'],
            # xyw_list.append(xy)
            # zyw_list.append(zy)
            xymw_list.append(xym)
            zymw_list.append(zym)

        xym_list = xym_list[:-1] + xymw_list[:-1] + [xym_list[-1]] + [xymw_list[-1]]
        zym_list = zym_list[:-1] + zymw_list[:-1] + [zym_list[-1]] + [zymw_list[-1]]

        for tag, generated in zip(['xym','zym'], # '0_xy','0_zy',
                                  [xym_list, zym_list]): # xy_list, zy_list,
            c_concat = np.concatenate(tuple(generated[:-2]), axis=0)
            c_path = os.path.join(root_path, '{}_{}.png'.format(idx,tag))
            save_image(c_concat, c_path, nrow=self.b_num, padding=1)
            print("[*] Samples saved: {}".format(c_path))

        gen_random = np.concatenate(tuple(xym_list[-2:]), axis=0)
        x_xy_path = os.path.join(root_path, 'x_fixed_xym_{}.png'.format(idx))
        save_image(gen_random, x_xy_path, nrow=self.b_num, padding=1)
        print("[*] Samples saved: {}".format(x_xy_path))

        gen_random = np.concatenate(tuple(zym_list[-2:]), axis=0)
        x_zy_path = os.path.join(root_path, 'x_fixed_zym_{}.png'.format(idx))
        save_image(gen_random, x_zy_path, nrow=self.b_num, padding=1)
        print("[*] Samples saved: {}".format(x_zy_path))

    def build_model_ae(self):
        if self.use_c:
            self.s, self.z, self.var = AE3(self.x, self.filters, self.z_num, use_sparse=self.use_sparse,
                                          num_conv=self.num_conv, repeat=self.repeat)
            _, self.x_ = jacobian3(self.s)
        else:
            self.x_, self.z, self.var = AE3(self.x, self.filters, self.z_num, use_sparse=self.use_sparse,
                                            num_conv=self.num_conv, repeat=self.repeat)
        self.x_img = denorm_img3(self.x_) # for debug

        self.x_jaco_, self.x_vort_ = jacobian3(self.x_)
        self.x_vort_ = denorm_img3(self.x_vort_)

        show_all_variables()

        if self.optimizer == 'adam':
            optimizer = tf.train.AdamOptimizer
            g_optimizer = optimizer(self.g_lr, beta1=self.beta1, beta2=self.beta2)
        elif self.optimizer == 'gd':
            optimizer = tf.train.GradientDescentOptimizer
            g_optimizer = optimizer(self.g_lr)
        else:
            raise Exception("[!] Invalid opimizer")

        # losses
        self.loss_l1 = tf.reduce_mean(tf.abs(self.x_ - self.x))
        self.loss_j_l1 = tf.reduce_mean(tf.abs(self.x_jaco_ - self.x_jaco))

        y = self.y[:,:,-1]
        self.loss_p = tf.reduce_mean(tf.squared_difference(y, self.z[:,-self.p_num:]))
        self.loss = self.loss_l1*self.w1 + self.loss_j_l1*self.w2 + self.loss_p*self.w4

        if self.use_sparse:
            ds = tf.distributions
            rho = ds.Bernoulli(probs=self.sparsity)
            rho_ = ds.Bernoulli(probs=tf.reduce_mean(self.z[:,:-self.p_num], axis=0))
            self.loss_kl = tf.reduce_sum(ds.kl_divergence(rho, rho_))
            self.loss += self.loss_kl*self.w5

        self.optim = g_optimizer.minimize(self.loss, global_step=self.step, var_list=self.var)
        self.epoch = tf.placeholder(tf.float32)

        # summary
        summary = [
            tf.summary.image("x/xym", self.x_img['xym'][:,::-1]),
            tf.summary.image("x/zym", self.x_img['zym'][:,::-1]),

            tf.summary.image("x/vort_xym", self.x_vort_['xym'][:,::-1]),
            tf.summary.image("x/vort_zym", self.x_vort_['zym'][:,::-1]),

            tf.summary.scalar("loss/total_loss", self.loss),
            tf.summary.scalar("loss/loss_l1", self.loss_l1),
            tf.summary.scalar("loss/loss_j_l1", self.loss_j_l1),
            tf.summary.scalar("loss/loss_p", self.loss_p),

            tf.summary.scalar("misc/epoch", self.epoch),
            tf.summary.scalar('misc/q', self.batch_manager.q.size()),

            tf.summary.histogram("y", y),
            tf.summary.histogram("z", self.z),

            tf.summary.scalar("misc/g_lr", self.g_lr),
        ]

        if self.use_sparse:
            summary += [
                tf.summary.scalar("loss/loss_kl", self.loss_kl),
            ]

        self.summary_op = tf.summary.merge(summary)

    def train_ae(self):
        sample = self.batch_manager.random_list(self.b_num)
        save_image(sample['xym'], '{}/xym_gt.png'.format(self.model_dir), nrow=self.b_num)
        save_image(sample['zym'], '{}/zym_gt.png'.format(self.model_dir), nrow=self.b_num)
        with open('{}/x_fixed_gt.txt'.format(self.model_dir), 'w') as f:
            f.write(str(sample['p']))
            f.write(str(sample['z']))

        # train
        for step in trange(self.start_step, self.max_step):
            self.sess.run(self.optim)

            if step % self.log_step == 0 or step == self.max_step-1:
                ep = step*self.batch_manager.epochs_per_step
                loss, summary = self.sess.run([self.loss,self.summary_op],
                                              feed_dict={self.epoch: ep})
                assert not np.isnan(loss), 'Model diverged with loss = NaN'
                print("\n[{}/{}/ep{:.2f}] Loss: {:.6f}".format(step, self.max_step, ep, loss))

                self.summary_writer.add_summary(summary, global_step=step)
                self.summary_writer.flush()

            if step % self.test_step == 0 or step == self.max_step-1:
                self.autoencode(sample['x'], self.model_dir, idx=step)

            if self.lr_update == 'step':
                if step % self.lr_update_step == self.lr_update_step - 1:
                    self.sess.run(self.g_lr_update)
            else:
                self.sess.run(self.g_lr_update)

        # save last checkpoint..
        save_path = os.path.join(self.model_dir, 'model.ckpt')
        self.saver.save(self.sess, save_path, global_step=self.step)
        self.batch_manager.stop_thread()

    def build_test_model_ae(self):
        self.x = tf.placeholder(dtype=tf.float32, shape=[self.test_b_num, self.res_z, self.res_y, self.res_x, 3])
        if self.use_c:
            self.s, self.z, self.var = AE3(self.x, self.filters, self.z_num, use_sparse=self.use_sparse,
                                          num_conv=self.num_conv, repeat=self.repeat, reuse=True)
            _, self.x_ = jacobian3(self.s)
        else:
            self.x_, self.z, self.var = AE3(self.x, self.filters, self.z_num, use_sparse=self.use_sparse,
                                              num_conv=self.num_conv, repeat=self.repeat, reuse=True)
        self.x_img = denorm_img3(self.x_) # for debug

    def autoencode(self, x, root_path=None, idx=None):
        # only for 2d
        x_img = self.sess.run(self.x_img, {self.x: x})
        xym = x_img['xym']
        x_path = os.path.join(root_path, 'xym_{}.png'.format(idx))
        save_image(xym, x_path, nrow=self.b_num)
        print("[*] Samples saved: {}".format(x_path))
        zym = x_img['zym']
        x_path = os.path.join(root_path, 'zym_{}.png'.format(idx))
        save_image(zym, x_path, nrow=self.b_num)
        print("[*] Samples saved: {}".format(x_path))


import urllib.request
import csv
from pymarc import MARCReader, Field
from urllib.error import HTTPError
import write_error_to_logfile

other_problems = []
nr = 0
out = open('records/check_links/substitution_records.mrc', 'wb')
with open('856-reportresults.csv', "r") as record_table:
    reader = csv.reader(record_table, delimiter=';')
    row_nr = 0
    for row in reader:
        row_nr += 1
        if row_nr > 1:
            record_id = row[0]
            invalid_link = False
            for identifier in row[2].split():
                if identifier[0] in ['h', 'w']:
                    write_error_to_logfile.comment(record_id)
                    if identifier[0:3] == 'www':
                        identifier = 'http://' + identifier
                    try:
                        webfile = urllib.request.urlopen(identifier)
                    except HTTPError as err:
                        if err.code == 404:
                            webfile = urllib.request.urlopen("https://zenon.dainst.org/Record/" + record_id + "/Export?style=MARC")
                            new_reader = MARCReader(webfile, force_utf8=True)
                            for file in new_reader:
                                out.write(file.as_marc21())
                                nr += 1
                    except Exception as e:
                        write_error_to_logfile.write(e)
                        write_error_to_logfile.comment('invalid but not 404 ' + identifier)
                        other_problems.append(record_id)

write_error_to_logfile.comment(other_problems)
#print(row_nr)
#print(nr)


"""
Given a set of positive numbers, find if we can partition it into two
subsets such that the sum of elements in both subsets is equal.

Example 1:
Input: {1, 2, 3, 4}
Output: True

Example 2:
Input: {1, 1, 3, 4, 7}
Output: True

Example 3:
Input: {2, 3, 4, 6}
Output: False
"""
def can_partition(nums):
    total = sum(nums)
    target = total // 2

    if total % 2 != 0:
        return False

    dp = set()
    dp.add(0)
    for i in range(len(nums)):
        nextdp = set()
        for j in dp:
            if j + nums[i] == target:
                return True
            nextdp.add(j + nums[i])
            nextdp.add(j)
        dp = nextdp
    return False

def main():
  print("Can partition: " + str(can_partition([1, 5, 11, 5])))
  print("Can partition: " + str(can_partition([1, 1, 3, 4, 7])))
  print("Can partition: " + str(can_partition([2, 3, 4, 6])))

main()


import sqlite3
# run to reset the database.

class SQLiteHandler:

    def __init__(self):
        """
        SQLite handler
        """

        # connect, implicitly creating the database if it does not exist.
        self.connection = sqlite3.connect("Database/ExamQuestions.db")
        self.cursor = self.connection.cursor()

    def Reset(self):
        """
        Reset database - drop tables then recreate them
        """
        self.DropTables()
        self.CreateTables()
        print("reset tables")

    def DropTables(self):
        """
        DROP TABLES
        """
        queries = [
            "DROP TABLE IF EXISTS PAPER;",
            "DROP TABLE IF EXISTS QUESTION;",
            "DROP TABLE IF EXISTS PARTS;",
            "DROP TABLE IF EXISTS IMAGES;",
            "DROP TABLE IF EXISTS QUESTIONTOPIC;"
        ]
        for query in queries:
            self.addToDatabase(query)

    def CreateTables(self):
        """
        Create the tables
        """
        queries = [
            """
            CREATE TABLE PAPER(
  PaperID VARCHAR(40) PRIMARY KEY NOT NULL,
  PaperComponent VARCHAR(15),
  PaperYear VARCHAR(4),
  PaperLevel VARCHAR(10)
);

            """,
            """
            CREATE TABLE QUESTION(
  QuestionID VARCHAR(50) PRIMARY KEY NOT NULL,
  PaperID VARCHAR(40),
  QuestionNumber INTEGER,
  QuestionContents TEXT,
  TotalMarks INTEGER,
  MarkschemeContents TEXT
);

            """,
            """
            CREATE TABLE IMAGES(
  ImageID INTEGER PRIMARY KEY NOT NULL,
  QuestionID VARCHAR(50),
  ImageData BLOB,
  IsPartOfMarkscheme INTEGER
);

            """,
            """
            CREATE TABLE PARTS(
  PartID VARCHAR(60) PRIMARY KEY NOT NULL,
  QuestionID VARCHAR(50),
  PartNumber VARCHAR(10),
  PartContents TEXT,
  PartMarks INTEGER,
  MarkschemeContents TEXT
);

            """,
            """
            CREATE TABLE QUESTIONTOPIC(
  QuestionTopicID VARCHAR(150),
  QuestionID VARCHAR(50),
  TopicID VARCHAR(100)
);
            """,
        ]
        for query in queries:
            self.addToDatabase(query)

    def queryDatabase(self, query: str) -> tuple:
        """Internal command used to query the current database, and return the
        results of the query. If an error occurs, an error window is displayed.
        Args:
            query(str) - the SQL query to be executed.
        Returns:
            tuple(tuple) - A tuple containing all the records in tuple form
            ((r1col1, r1col2), (r2col1, r2col2)...)
        """

        # Executes the query input
        self.cursor.execute(query)
        # returns the results
        return self.cursor.fetchall()

    def addToDatabase(self, query: str):
        """Commits changes using connection.commit(),
        so should be used for them. Returns False if an error occurs,
        as well as the error.
            Args:
                query(str) - the SQL query to be executed.
            Returns:
                tuple(boolean, exception) - A tuple of the boolean for whether
                the execution was successful, and the exception returned
                (or "placeholder_exception" if no exception)

        """

        try:
            try:
                # print(query)
                self.connection.executescript(query)
                # Commits the executed query to ensure changes are made.
                self.connection.commit()
                return True, "placeholder_exception"
            except sqlite3.Error as e:
                print(query)
                print(e)
                return False, e
        except Exception as e:
            print(e)
            return False, e

if __name__ == "__main__":
    sqlsocket = SQLiteHandler()
    sqlsocket.Reset()


from django.contrib import admin
from django.urls import path, include, re_path
from django.conf.urls.static import static
from django.conf import settings
from allauth.account.views import confirm_email

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api-auth/', include('rest_framework.urls')),

    path('rest-auth/', include('rest_auth.urls')),
    path('rest-auth/registration/', include('rest_auth.registration.urls')),

    path('api/book/', include('books.urls.book', namespace='books')),
    path('api/bookad/', include('books.urls.bookad', namespace='books')),
    path('api/user/', include('books.urls.user', namespace='books')),
    path('api/order/', include('books.urls.order', namespace='books')),
    path('api/blog/', include('books.urls.blog', namespace='books')),

    re_path(r'rest-auth/registration/account-confirm-email/(?P<key>.+)/', confirm_email, name='account_confirm_email'),
]

if settings.DEBUG:
    urlpatterns += static(settings.MEDIA_URL,
                          document_root=settings.MEDIA_ROOT)

# path('auth/', include('dj_rest_auth.urls')),
# path('auth/registration', include('dj_rest_auth.registration.urls'))


import wandb
import torch

from torch import nn, optim
from torch.nn import functional as F
from torch.utils.data import DataLoader

from tqdm import tqdm
from matplotlib import pyplot as plt

from datasets import T4PlaneExtrapolationDataset
from models import PerceptualAE

def weights_init(m):
    if isinstance(m, nn.Conv2d):
        nn.init.xavier_uniform_(m.weight.data)

def train(model, loader, optimiser, scheduler,
          max_epoch=20, log_interval=5):
    model.train()
    batches = 0

    for epoch in tqdm(range(max_epoch)):
        for batch in tqdm(loader):
            batches += 1
            # Load batch
            _, img = batch
            img = img.cuda() if torch.cuda.is_available() else img
            img = img.unsqueeze(1).float()
            # Train
            optimiser.zero_grad()
            pred = model.forward(img)
            loss = torch.mean((pred - img) ** 2)
            loss.backward()
            optimiser.step()
            # Logging
            if batches % log_interval:
                wandb.log({
                    'Batches': batches
                })
                wandb.log({
                    'MSE Loss': loss.detach().cpu().item()
                })
            if batches % 100 == 0:
                plt.figure()
                plt.imshow(pred.detach().cpu()[0].squeeze())
                plt.savefig(f'ae_bigger_{batches}.jpg')
                plt.close()
            if batches % 1000 == 0:
                torch.save(model, f'model_ae_bigger_{batches}.ckpt')
            # Step LR
            scheduler.step()

if __name__ == '__main__':
    wandb.init(project='PLACEHOLDER', entity='PLACEHOLDER')
    model = PerceptualAE()
    model = model.cuda() if torch.cuda.is_available() else model
    model.apply(weights_init)
    dataset = T4PlaneExtrapolationDataset(
        embryo_dir_globs=['PLACEHOLDER'],
        use_augmentations=True
    )
    loader = DataLoader(
        dataset,
        shuffle=True,
        batch_size=4
    )
    optimiser = optim.Adam(
        filter(lambda p: p.requires_grad, model.parameters()),
        lr=1e-4
    )
    scheduler = optim.lr_scheduler.StepLR(optimiser, 3000, 0.1)
    train(model, loader, optimiser, scheduler)


numStrings = int(input())
text = ''
length = 0
count = 0
for x in range(0, numStrings):
    text = input()
    length = len(text)
    for y in range(1, length):
        if(length == 1):
            break
        elif(text[y] != text[y-1]):
            continue
        else:
            count+=1
    print(count)
    count = 0


import csv
import json

def make_json(csvFilePath,jsonFilePath):
    data = {}

    with open(csvFilePath, encoding='utf-8') as csvf:
        csvReader = csv.DictReader(csvf)
        i = 0
        for rows in csvReader:
            key = i
            data[key] = rows
            i+=1

    with open(jsonFilePath, 'w', encoding='utf-8') as jsonf:
        jsonf.write(json.dumps(data, indent=4))

for i in range(0,14):
    jsonFilePath = '/Users/sheshmani/Desktop/community_rating/data_dir/split_json/'+str(i)+'.json'
    csvFilePath = '/Users/sheshmani/Desktop/community_rating/homes_data/split_csv_files/'+str(i)+'.csv'
    make_json(csvFilePath,jsonFilePath)


# coding=utf-8

import numpy as np
import torch

def Variable(tensor):
    if isinstance(tensor, np.ndarray):
        tensor = torch.from_numpy(tensor)
    if torch.cuda.is_available():
        return torch.autograd.Variable(tensor).cuda()
    return torch.autograd.Variable(tensor)

def NLLLoss(inputs, targets):
    """
    Custom Negative Log Likelihood loss that returns loss per example,
        rather than for the entire batch.

    :param inputs: (batch_size, num_classes) *Log probabilities of each class*.
    :param targets: (batch_size) *Target class index*.
    :return: loss : (batch_size) *Loss for each example*.
    """

    if torch.cuda.is_available():
        target_expanded = torch.zeros(inputs.size()).cuda()
    else:
        target_expanded = torch.zeros(inputs.size())

    target_expanded.scatter_(1, targets.contiguous().view(-1, 1).data, 1.0)
    loss = Variable(target_expanded) * inputs
    loss = torch.sum(loss, 1)
    return loss

def read_smi_file(file_path):
    """
    Reads a SMILES file.
    :param file_path: Path to a SMILES file.
    :return: A list with all the SMILES.
    """
    with open(file_path, "r") as smi_file:
        return [smi.rstrip().split()[0] for smi in smi_file]


#!/usr/bin/python3
#-*- coding: UTF-8 -*-
#@Author:youchuanjiang
#@LastTime:2019-02-27
import random
from servermanage.models import ServerInfo
from common.logs import *

RESULT = 200
# 服务注册
class Server(object):
    '''
    主要是对所有服务的
    '''
    def __init__(self, server_id=None, pojo_name=None, dbname=None, host=None, port=None,server_type=None, build_type=None, role_type=None, env_type=None, createtime=None):
        self.server_id = server_id
        self.pojo_name = pojo_name
        self.dbname = dbname
        self.host = host
        self.port = port
        self.server_type = server_type
        self.build_type = build_type
        self.role_type = role_type
        self.env_type = env_type
        self.createtime = createtime
        self.serverdict = {pojo_name: pojo_name, dbname: dbname, host: host, port: port, server_type: server_type, build_type: build_type, role_type: role_type, env_type: env_type, createtime: createtime}

    @classmethod
    def RegisterServer(self, serverdict):
    #注册服务
        def serverid(num):
         # 生成server_id,随机生成6位正整数
            serverid = ""
            for i in range(num):
                ch = chr(random.randrange(ord('0'), ord('9') + 1))
                serverid += ch
            return serverid

        # 处理数据
        server = ServerInfo()
        server.server_id = serverid(6)
        server.pojo_name = serverdict['pojo_name']
        server.dbname = serverdict['dbname']
        server.host = serverdict['host']
        server.port = serverdict['port']
        server.server_type = serverdict['server_type']
        server.build_type = serverdict['build_type']
        server.role_type = serverdict['role_type']
        server.env_type = serverdict['env_type']
        server.createtime = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())
        log = LogtoLog().getlog()
        try:
            server.save()
            return RESULT
        except Exception as err:
            #待完成日志封装
            log.error("数据库操作异常", err)
            return "服务注册失败"
        except ConnectionError as err:
            log.error("数据库连接异常，请查看数据库服务是否正常运行或者网络是否存在异常", err)
            return "服务注册失败"

    #获取服务列表
    @classmethod
    def ServerList(self):
        try:
            serverlist = ServerInfo.objects.all().order_by('pojo_name').values()
            serverlist_dict = list(serverlist)
            return serverlist_dict
        except ConnectionError as err:
            log = LogtoLog().getlog()
            log.error(err)

    #修改服务信息
    @classmethod
    def ModifyInfo(self, serverdict):
        try:
            server = Server()
            serverid = serverdict['server_id']
            sinfo = server.objects.get(server_id=serverid)
            sinfo.server_id = serverid
            sinfo.dbname = serverdict['dbname']
            sinfo.host = serverdict['host']
            sinfo.pojo_name = serverdict['pojo_name']
            sinfo.port = serverdict['port']
            sinfo.server_type = serverdict['server_type']
            sinfo.build_type = serverdict['build_type']
            sinfo.declare = serverdict['declare']
            sinfo.createtime = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())
            sinfo.save()
        except Exception as err:
            log = LogtoLog().getlog()
            log.error("数据库连接异常，请查看数据库服务是否正常运行或者网络是否存在异常", err)
        return "修改成功"

    #删除服务信息
    @classmethod
    def DelSever(self,server_id):
        try:
            pass
        except Exception as err:
            log = LogtoLog().getlog()
            log.error("数据库连接异常", err)
        return "服务已删除"


class AccountData:
	def __init__(self):
		self.currency = None
		self.equity = 0
		self.availableMargin = 0
		self.initialMargin = 0
		self.maintenanceMargin = 0
		self.withdrawableFunds = 0
		self.PnL = 0
		self.delta = 0
		self.gamma = 0
		self.vega = 0
		self.theta = 0
		self.rows = 11
		self.cols = 2

	def clear(self):
		self.currency = ""
		self.equity = 0
		self.availableMargin = 0
		self.initialMargin = 0
		self.maintenanceMargin = 0
		self.withdrawableFunds = 0
		self.PnL = 0
		self.delta = 0
		self.gamma = 0
		self.vega = 0
		self.theta = 0
		self.rows = 11
		self.cols = 2

	def update(self, dict_obj):
		self.currency = dict_obj['currency']
		self.equity = dict_obj["equity"]
		self.availableMargin = dict_obj["margin_balance"]
		self.initialMargin = dict_obj["initial_margin"]
		self.maintenanceMargin = dict_obj["maintenance_margin"]
		self.withdrawableFunds = dict_obj["available_withdrawal_funds"]
		self.PnL = dict_obj["total_pl"]
		self.delta = dict_obj["options_delta"]
		self.gamma = dict_obj["options_gamma"]
		self.vega = dict_obj["options_vega"]
		self.theta = dict_obj["options_theta"]

	def getRows(self):
		return self.rows

	def getCols(self):
		return self.cols

	def getData(self, i, j):
		if j == 0:
			if i == 0:
				return "Currency"
			elif i == 1:
				return "Equity"
			elif i == 2:
				return "margin_bal"
			elif i == 3:
				return "init_margin"
			elif i == 4:
				return "mnt_margin"
			elif i == 5:
				return "avlble_funds"
			elif i == 6:
				return "PnL"
			elif i == 7:
				return "Delta"
			elif i == 8:
				return "Gamma"
			elif i == 9:
				return "Vega"
			elif i == 10:
				return "Theta"
			else:
				return ""
		else:
			if i == 0:
				return self.currency
			elif i == 1:
				return self.equity
			elif i == 2:
				return self.availableMargin
			elif i == 3:
				return self.initialMargin
			elif i == 4:
				return self.maintenanceMargin
			elif i == 5:
				return self.withdrawableFunds
			elif i == 6:
				return self.PnL
			elif i == 7:
				return self.delta
			elif i == 8:
				return self.gamma
			elif i == 9:
				return self.vega
			elif i == 10:
				return self.theta
			else:
				return 0


from re import L

n,k = input().split()
n = int(n)
k = int(k)

coins = []
coin_num = 0

for i in range(n):
    tmp = int(input())
    coins.append(tmp)

while True:
    coin = coins.pop()
    if coin<=k:
        coin_num += k//coin
        k -= (k//coin)*coin
        if k==0:
            break
print(coin_num)


"""
Implementation for rewriting cassandra.yaml to allow
remote access to server
"""
from __future__ import print_function

import sys
import yaml

SEED = 'org.apache.cassandra.locator.SimpleSeedProvider'

def rewrite_cassandra_yaml(local_address):
    """
    Operative code
    - open file, read into memory
    - manipulate memory representation
    - write back to disk
    """
    fname = "/etc/cassandra/cassandra.yaml"
    with open(fname) as handle:
        cassandra = yaml.load(handle)

    new_cassandra = {
        "listen_address": local_address,
        "broadcast_rpc_address": local_address,
        "rpc_address": "0.0.0.0",
    }

    # A list of seed_providers
    seed_providers = cassandra.get("seed_provider")
    if seed_providers:
        new_cassandra["seed_provider"] = seed_providers
        for seed_provider in seed_providers:
            # A seed_provider is a dict
            if seed_provider['class_name'] == SEED:
                # parameters is a list of dicts
                for parameter in seed_provider.get('parameters', []):
                    if 'seeds' in parameter:
                        parameter['seeds'] = local_address

    cassandra.update(new_cassandra)

    with open(fname, "w") as handle:
        cassandra = yaml.dump(cassandra, stream=handle)

def main():
    """ Entry point for console script """
    try:
        local_address = sys.argv[1]
    except IndexError:
        print("Require argument for local address of cassandra server",
              file=sys.stderr)
        sys.exit(1)
    else:
        try:
            rewrite_cassandra_yaml(local_address)
            sys.exit(0)
        except Exception as exc:  # pylint: disable=broad-except
            print(exc, file=sys.stderr)
            sys.exit(1)

if __name__ == '__main__':
    main()


#!/usr/bin/env python3
import cgi
import os

# Create an instance of the FieldStorage class to parse the form data
form = cgi.FieldStorage()

# Print the CGI header
print("Content-type: text/html\r\n\r\n")

# Define the target directory where uploaded files will be stored
target_directory = os.environ.get('UPLOAD_DIR')

# Check if the request method is POST
if os.environ.get("REQUEST_METHOD", "") == "POST":
    if "fileToUpload" in form:
        file_field = form["fileToUpload"]
        # Get the filename from the form data
        filename = os.path.basename(file_field.filename)

        # Construct the full path to the target file
        target_file = os.path.join(target_directory, filename)

        if os.path.exists(target_file):
            print("File already exists.")
        else:
            try:
                # Open the target file for writing
                with open(target_file, "wb") as f:
                    # Read and write the uploaded file in chunks
                    while True:
                        chunk = file_field.file.read(8192)
                        if not chunk:
                            break
                        f.write(chunk)

                print("File uploaded successfully.")
            except Exception as e:
                print("Error:", str(e))
    else:
        print("Error: No file uploaded.")


# Прямой отсчет
N1 = 8

def rcp(N):

    if N == 0:
        print(0)
    else:
        rcp(N-1)  # Последовательность операций!!!!!!!!
        print(N)

    return ""

print(rcp(N1))

# Обратный отсчет
N2 = 23

def rco(N):

    if N == 0:
        print(0)
    else:

        print(N)
        rco(N-1)
    return ""

print(rco(N2))


# --------------------------------
#
# Call the live endpoint
#
# --------------------------------

import requests

from FinTxtClient.exceptions import FinTxtClientException
from FinTxtClient.checks.checks import checks

class live(object):

    '''
    @desc: call the live endpoint
    @params:
        - apiClient: FinTxtAPI object
    @return:
    '''

    def __init__(self, apiClient):

        # Set endpoints
        self._endpoint = "live"
        self._apiClient = apiClient

    def live_one(self, _type, language, q):

        '''
        @desc: return the live news intensity for a single commodity or company
        @params:
            - _type: one of 'companies' or 'commodities'
            - language: Filter news intensity values by language. See the '/languages' endpoint for allowed values.
            - q: RIC code for the company for which you want to query news intensity values or name of commodity for which you want to query news intensity values. See documentation for supported commodities.
        @return
        '''

        # Checks
        ch = checks(_type, language)
        ch.check_query(q)

        self._type = _type
        self._language = language
        self._query = q

        # Construct the url
        req = "{}{}/{}/{}?q={}".format(self._apiClient._server, self._endpoint, self._type, self._language, self._query)

        # Call client
        resp = self._apiClient.make_request(req, "GET")

        # return
        return(resp)

    def live_portfolio(self, _type, language, identifiers, weights):

        '''
        @desc: return the live news itensity for a portfolio of commodities or companies
        @params:
            - _type: either one of 'companies' or 'commodities'
            - language: Filter news intensity values by language. See the '/languages' endpoint for allowed values.
            - identifiers: RIC codes for the companies for which you want to query news intensity values or names of commodities for which you want to query news intensity values. See documentation for supported commodities. Note that you cannot mix companies and commodities
            - weights: Weight of each company/commodity in your portfolio in decimal format. Should sum to 1, but the API will still return news intensities if this is not the case. See example section.
        @return:
        '''

        self._endpoint = "portfolio/{}".format(self._endpoint)

        # Checks
        ch = checks(_type, language)
        ch.check_portfolio(identifiers, weights)

        self._request = {
            "identifiers":identifiers,
            "weights":weights,
            "type":_type,
            "language":language
        }

        # Ensure that api token will be passed
        self._apiClient._requires_key = True

        # Make url
        url = "{}{}".format(self._apiClient._server, self._endpoint)

        # Make request
        resp = self._apiClient.make_request(url, "POST", self._request)

        # Return
        return(resp)


import numpy as np

import sqlalchemy
from sqlalchemy.ext.automap import automap_base
from sqlalchemy.orm import Session
from sqlalchemy import create_engine, func

from flask import Flask, jsonify
import pandas as pd

#################################################
# Database Setup
#################################################
engine = create_engine("sqlite:///hawaii.sqlite")

# reflect an existing database into a new model
Base = automap_base()
# reflect the tables
Base.prepare(engine, reflect=True)

# Save reference to the table
measurement = Base.classes.measurement
station = Base.classes.station

# Create our session (link) from Python to the DB
session = Session(engine)

#################################################
# Flask Setup
#################################################
app = Flask(__name__)

#################################################
# Flask Routes
#################################################

@app.route("/")
def welcome():
    """List all available api routes."""
    return (
        f"Available Routes:
"
        f"/api/v1.0/precipitation
"
        f"/api/v1.0/stations
"
        f"/api/v1.0/tobs"
    )

@app.route("/api/v1.0/precipitation")
def precipitation():
    """Return precipitation for the last year"""
    # Set first day included in query
    query_date = '2016-08-18'
    # Query all stations
    precip = session.query(measurement.date, measurement.prcp, measurement.station).filter(measurement.date >= query_date)#.filter(Precip.station == 'USC00511918')

    dates = []
    precipitation = []

    for row in precip:
        dates.append(row[0])
        precipitation.append(row[1])

    precip_dict = dict(zip(dates, precipitation))

    return jsonify(precip_dict)

@app.route("/api/v1.0/stations")
def stations():
    """Return a list of all station names"""
    # Query all stations
    station_list = session.query(station.name).all()

    # Convert list of tuples into normal list
    all_stations = list(np.ravel(station_list))

    return jsonify(all_stations)

@app.route("/api/v1.0/tobs")
def tobs():
    """Return a JSON list of Temperature Observations for the previous year"""
    # Set first day included in query
    query_date = '2016-08-18'
    # Query all stations
    temp_data = session.query(measurement.date, measurement.tobs, measurement.station).filter(measurement.date >= query_date)#.filter(Precip.station == 'USC00511918')

    dates = []
    tobs = []

    for row in temp_data:
        dates.append(row[0])
        tobs.append(row[1])

    tobs_dict = dict(zip(dates, tobs))

    return jsonify(tobs_dict)

@app.route("/api/v1.0/<start>")
def start_date_temp(start):
    """Return min, max, avg temps after specified start date"""

    # Query all stations
    temp_data = session.query(measurement.tobs).filter(measurement.date >= start)#.filter(Precip.station == 'USC00511918')

    temp_df = pd.DataFrame(temp_data[:], columns = ['Temperature'])
    TMIN = temp_df['Temperature'].min()
    TMAX = temp_df['Temperature'].max()
    TAVG = round(temp_df['Temperature'].mean(),1)

    return f"Min temp: {TMIN}
  Max temp: {TMAX}
  Avg temp: {TAVG}"

@app.route("/api/v1.0/<start>/<end>")
def start_end_date_temp(start, end):
    """Return min, max, avg temps after specified start date and before end date"""

    # Query all stations
    temp_data = session.query(measurement.tobs).filter(measurement.date >= start).filter(measurement.date <= end)

    temp_df = pd.DataFrame(temp_data[:], columns = ['Temperature'])
    TMIN = temp_df['Temperature'].min()
    TMAX = temp_df['Temperature'].max()
    TAVG = round(temp_df['Temperature'].mean(),1)

    return f"Min temp: {TMIN}
  Max temp: {TMAX}
  Avg temp: {TAVG}"

if __name__ == '__main__':
    app.run(debug=True)


"""
Custom colors
"""

# Orange
orange = "#FF9932"
light_orange = "#FEECD8"
dark_orange = "#A84700"
darker_orange = "#3D1B08"

# Yellow (Daghstul)
light_yellow = "#fff4cf"
yellow = "#ffc80d"
dark_yellow = "#aa4400"
darker_yellow = "#552200"

# Blue
blue = "#1C76B4"
light_blue = "#CDE0DC"

# Grey
grey = "#BFBFBF"
light_grey = "#F0F2F6"
dark_grey = "#707070"

# Red
red = "#FF2021"
light_red = "#FE7D84"

# Green
green = "#69B22F"
light_green = "#AADF87"

# Violet
violet = "#9467bd"


import cv2 as cv
import math
import os

img = cv.imread('images/pompei.jpg', cv.IMREAD_UNCHANGED)
img_rgb = cv.imread('images/feira.png', cv.IMREAD_UNCHANGED)

yc = math.floor(img.shape[0]/2)
xc = math.floor(img.shape[1]/2)

interval = 350

img_sel = img[int(yc-interval/2):int(yc+interval/2), int(xc-interval/2):int(xc+interval/2)]

cv.imshow('Pompeii City', img)
cv.imshow('Pompeii City Selected', img_sel)

cv.imwrite('output/pompeii.png', img)
cv.imwrite('output/pompeii_city_selected.png', img_sel)

img_sel_rgb = img_rgb[0:10, 0:10, [0,2]]
print(img_sel_rgb.shape)

cv.waitKey(0)
cv.destroyAllWindows()


scores = [10, 50, 100, 175, 250, 400, 600, 800, 1000]
ranks = 'white yellow orange green blue brown black paneled red'.split()
BELTS = dict(zip(scores, ranks))

class NinjaBelt:

  def __init__(self, score=0):
    self._score = score
    self._last_earned_belt = None

  def _get_belt(self, new_score):
    is_new_belt_earned = False
    if new_score < 10:
      self._last_earned_belt = ''
    elif new_score > 1000:
      self._last_earned_belt = 'red'
    else:
      for index, value in enumerate(scores):
        if new_score < value:
          belt = BELTS.get(scores[index - 1]).title()
          if belt != self._last_earned_belt:
            self._last_earned_belt = belt
            is_new_belt_earned = True
          break
        elif new_score == value:
          belt = BELTS.get(scores[index])
          self._last_earned_belt = belt.title()
          is_new_belt_earned = True
          break
    return is_new_belt_earned

  @property
  def score(self):
    return self._score

  @score.setter
  def score(self, new_score):
    if isinstance(new_score, int) and new_score >= self._score:
      self._score = new_score
      if not self._get_belt(new_score):
        print(f'Set new score to {self._score}')
      else:
        print(
            f'Congrats, you earned {self._score} points obtaining the PyBites Ninja {self._last_earned_belt} Belt')
    else:
      raise ValueError

  # score = property(_get_score, _set_score)


#设计一个程序  结合自己喜欢的菜谱  使用网上的蔬菜报价优化出每日的推荐菜    如果可以结合运筹学  给出每日需要提前是否腌制准备酱料等等

import  csv

#菜谱录入采用csv

import csv

filename = 'caidan.csv'
with open(filename) as f:
    reader = csv.DictReader(f)
    for row in reader:
        # Max TemperatureF是表第一行的某个数据，作为key
        max_temp = row['菜名']
        print(max_temp)

#菜价获取

#运筹优化


import rclpy
from rclpy.action import ActionClient
from rclpy.node import Node

from interfaces.action import Movement

class LegsActionClient(Node):

    def __init__(self):
        super().__init__('legs_action_client')
        self.get_logger().info('initializing action client')
        self._action_client = ActionClient(
            self,
            Movement,
            'movement'
        )

    def send_goal(self, command):
        goal_msg = Movement.Goal()
        goal_msg.command = command

        while not self._action_client.wait_for_server():
            self.get_logger().info('action server not available, waiting...')

        return self._action_client.send_goal_async(goal_msg)

def main(args=None):
    rclpy.init(args=args)
    action_client = LegsActionClient()
    future = action_client.send_goal('stand')
    rclpy.spin_until_future_complete(action_client, future)

if __name__ == '__main__':
    main()


from django.http import HttpResponse
from django.template import loader
from .models import Member

def members(request):
  mymembers = Member.objects.all().values()
  template = loader.get_template('all_members.html')
  context = {
    'mymembers': mymembers,
  }
  return HttpResponse(template.render(context, request))

def details(request, id):
    mymember = Member.objects.get(id=id)
    template = loader.get_template('details.html')
    context = {
        'mymember': mymember,
    }

    return HttpResponse(template.render(context, request))

def main(request):
  template = loader.get_template('main.html')
  return HttpResponse(template.render())


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

with open('res/X1.pickle','rb') as f1:
	X = pickle.load(f1)
with open('res/XT1.pickle','rb') as f2:
	XT = pickle.load(f2)
with open('res/Y1.pickle','rb') as f3:
	Y = pickle.load(f3)
with open('res/YT1.pickle','rb') as f4:
	YT = pickle.load(f4)

# -------------------------以上代码获取数据，不必管-------------------------
import oneHiddenLayer as oh

parameters,costs,accuracies = oh.nn_model(X,Y,XT,YT,42,10000,0.005,True)

# 测试集效果曲线
plt.plot(accuracies)
plt.ylabel('accuracies')
plt.xlabel('iterations / 10')
plt.show()


import path
from matplotlib.pyplot import figure, legend, plot, show, title, ylim
import os

def graph_create(pointlist, type):

    ##tests with logger
    #logger = logging.getLogger('HWGraph')
    #hdlr = logging.FileHandler('/HWGraph.log')
    #formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')
    #hdlr.setFormatter(formatter)
    #logger.addHandler(hdlr)
    #logger.setLevel(logging.WARNING)

    if path.exists('foo.png'):
        os.remove("foo.png")

    #for x in range(len(pointlist)):
    #    logger.info(str(pointlist[x]))

    figure(1, figsize=(12, 6))

    ylim(top=1)
    plot(pointlist)
    title('Frequency of %s' %type, bbox={'facecolor': '0.8', 'pad': 5})
    legend()

    show()  # Actually, don't show, just save to foo.png
    #savefig('foo.png', bbox_inches='tight').


'''
299. Bulls and Cows
https://leetcode.com/problems/bulls-and-cows/
'''
from collections import Counter
from typing import List

from test_tool import assert_value

class Solution:
    def getHint(self, secret: str, guess: str) -> str:
        bull = set()
        cow = Counter()
        for idx, (s, g) in enumerate(zip(secret, guess)):
            if s == g:
                bull.add(idx)
            else:
                cow[s] += 1

        A = len(bull)
        B = 0
        for idx, g in enumerate(guess):
            if idx in bull:
                continue
            if cow[g]:
                cow[g] -= 1
                B += 1

        return f'{A}A{B}B'

assert_value("1A3B", Solution().getHint, secret="1807", guess="7810")
assert_value("1A1B", Solution().getHint, secret="1123", guess="0111")


def get_unique_ingredients(listOfPizzas, pizzas):
    ingredients = []
    for pizza_id in listOfPizzas:
        ingredients += pizzas[pizza_id]
    return set(sorted(ingredients))

def calculate_score(pizzas_to_deliver, pizzas_menu):
    score = 0
    for pizza_ids in pizzas_to_deliver:
        score += len(get_unique_ingredients(pizza_ids, pizzas_menu)) ** 2
    return score


from django.urls import path, include, re_path
from .views import *

urlpatterns = [
    path('', home, name='home'),
    # path('home/', home, name='home'),
    path('archive/add-new-suspect/', AddNewSuspect, name='add_new_suspect'),
    path('archive/start-stream/', StartVideoStream, name='start_stream'),
    path('archive/camera/', process, name='live_camera'),
    path('archive/stream/', Stream, name='stream'),
    path('archive/stream/stop-livestream/', StopStream, name='stop_stream'),
    path('archive/stream/idle/', IdleMode, name='idle_mode'),
]


from helpers.clientFinder.dataLookup import dataLookup
from helpers.clientFinder.lookup import lookup
from helpers.utils.display import display
from helpers.utils.printer import colorFormatter, inp, log
from helpers.utils.sheets import delete

def deleteClient(comm, command, quit, olt, action):
    """
    comm        :   ssh connection handler [class]
    command     :   sends ssh commands [func]
    quit        :   terminates the ssh connection [func]
    olt         :   defines the selected olt [var:str]
    action      :   defines the type of lookup/action of the client [var:str]

    This module deletes a given client
    """
    lookupType = inp("Buscar cliente por serial o por Datos (F/S/P/ID) [S | D] : ")
    client = lookup(comm,command,olt,lookupType)
    if client["fail"] != None:
        log(colorFormatter(client["fail"], "fail"))
        quit()
        return
    proceed = display(client,"A")
    if not proceed:
        log(colorFormatter("Cancelando...", "warning"))
        quit()
        return
    for wan in client["wan"]:
        command(f"undo service-port {wan['spid']}")
        log(f"El SPID {wan['spid']} ha sido liberado!")
    command(f"interface gpon {client['frame']}/{client['slot']}")
    command(f"ont delete {client['port']} {client['onu_id']}")
    delete(client["sn"])
    log(colorFormatter(f"El cliente {client['name']} de {client['frame']}/{client['slot']}/{client['port']}/{client['onu_id']} @ OLT {client['olt']} ha sido eliminado  ","success"))
    quit()
    return


import pdb
import cv2
import mediapipe as mp
import time
import numpy as np
import math

YELLOW = (0, 255, 255)
GREEN = (0, 255, 0)
RED = (0, 0, 255)
BLUE = (255, 0, 0)

class poseDetector():
    def __init__(self, mode=False,
                 up_body=False,
                 smooth=True,
                 detection_con = 0.5,
                 track_con = 0.5):
        self.mode = mode
        self.up_body = up_body
        self.smooth = smooth
        self.detection_con = detection_con
        self.track_con = track_con

        self.mpDraw = mp.solutions.drawing_utils
        self.mpPose = mp.solutions.pose
        self.pose = self.mpPose.Pose(static_image_mode=self.mode, #true - will always be trying to detect from inputs, false will try to detect and when the confidence is high it will keep tracking
                   upper_body_only=self.up_body,
                   smooth_landmarks=self.smooth,
                   min_detection_confidence=self.detection_con, #if confidence is more than 0.5 it will have detected the person and will proceed to go to tracking
                   min_tracking_confidence=self.track_con) #if the confidence is more than 0.5 it will keep tracking else it will return to detecting
        # Bool for pushup position
        self.ready_to_start = False
        self.timer_started = False
        self.start_time = None
        self.end_time = None
        self.going_up = False
        self.going_down = True
        self.last_state = (0,0,0)

        self.state_color = YELLOW # Yellow default color

        self.counter = 0

        self.angle = 0

    def getPose(self, img, draw=True): # Ask the user do you want to display on image or not
        imgRGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
        # Will give us the detection of our pose
        self.results = self.pose.process(imgRGB)
        if self.results.pose_landmarks:
            if draw:
                pass
                # Draw landmarks on screen
                # self.mpDraw.draw_landmarks(img, self.results.pose_landmarks, self.mpPose.UPPER_BODY_POSE_CONNECTIONS)
        return img

    def getPosition(self, img, draw=True):
        lm_list = []
        body_lines = []
        left_side = []
        right_side = []
        # check if results are available
        if self.results.pose_landmarks:
            # See website for information about different pose landmarks (id)
            # https://www.analyticsvidhya.com/blog/2021/05/pose-estimation-using-opencv/
            for id, lm in enumerate(self.results.pose_landmarks.landmark):
                h, w, c = img.shape
                # We need this because the landmark is just a ratio location for the image
                # print(id, lm)
                # We need the exact pixel value by multiplying the by the width and height
                cx, cy = int(lm.x*w), int(lm.y*h)
                lm_list.append([id, cx, cy])

                if id in [11, 12, 13, 14, 15, 16]:
                    if draw:
                        if id % 2 == 0:
                            right_side.append((cx, cy))
                        else:
                            left_side.append((cx, cy))
                        # Overlay on the previous points if we are detecting it properly
                        # cv2.circle(img, (cx, cy), 10, (255,0,0), cv2.FILLED)
            if len(lm_list) != 0:
                body_lines = right_side[::-1] + left_side
                body_lines = np.int32(body_lines)
                # pts = body_lines.reshape((-1, 1, 2))
                # pdb.set_trace()
                cv2.polylines(img, [body_lines], False, color=self.state_color, thickness=10)
        return lm_list

    def checkPushupPosition(self, lm_list):
        left_shoulder = lm_list[0]
        right_shoulder = lm_list[1]
        left_elbow = lm_list[2]
        right_elbow = lm_list[3]
        left_wrist = lm_list[4]
        right_wrist = lm_list[5]
        # landmark[1] = x , landmark[2] = y
        # vector between 2 points P and Q
        # PQ-> = (X_q - X_p, Y_q - Y_p)

        # Angle between 2 vectors
        # cos(theta) = (a dot v) / (||a|| * ||v||)

        # vector between elbow and wrist [x,y]
        # right elbow to wrist
        r_e_w = np.array([right_wrist[1] - right_elbow[1],
                         right_wrist[2] - right_elbow[2]])
        r_e_s = np.array([right_shoulder[1] - right_elbow[1],
                         right_shoulder[2] - right_elbow[2]])

        unit_vector_1 = r_e_w / np.linalg.norm(r_e_w)
        unit_vector_2 = r_e_s / np.linalg.norm(r_e_s)
        dot_product = np.dot(unit_vector_1, unit_vector_2)
        angle = np.arccos(dot_product) * (180/np.pi)
        # pdb.set_trace()
        self.angle = angle
        return self.angle
        # vector between elbow and shoulder

    def checkIfReady(self):
        if self.angle > 170 and not self.ready_to_start:
            if self.start_time == None:
                # If timer not started, start it
                self.start_time = time.perf_counter()

            curr_time = time.perf_counter()
            if curr_time - self.start_time > 4.0:
                self.ready_to_start = True
                self.state_color = BLUE
        elif not self.ready_to_start:
            self.start_time = None
            # Reset start time to None if doesn't stay in pushup position for 3 seconds

    def countPushups(self):
        if self.ready_to_start:
            if self.going_down:
                if self.angle < 130: # If pass threshold
                    self.going_up = True
                    self.going_down = False
                    self.state_color = RED
            elif self.going_up:
                if self.angle > 165: # peak threshold
                    self.counter += 1
                    self.going_down = True
                    self.going_up = False
                    self.state_color = BLUE

    def print_status(self):
        if self.going_down and self.last_state[0] != self.going_down:
            print("Going down")
        if self.going_up and self.last_state[1] != self.going_up:
            print("Going up")
        if not self.ready_to_start and self.last_state[2] != self.ready_to_start:
            print("Not ready to start")
        if self.ready_to_start and self.last_state[2] != self.ready_to_start:
            print("Started")
        self.last_state = (self.going_down, self.going_up, self.ready_to_start)

def main():
    # cap = cv2.VideoCapture(0)
    cap = cv2.VideoCapture('resources/push_up3_test.mp4')
    # cap = cv2.VideoCapture('resources/push_up_2.mp4')
    pTime = 0
    # Adjust frames to be processed for speedup
    frame_time = 10

    # Set up custom window for viewing
    cv2.namedWindow('Track Upper Body', cv2.WINDOW_KEEPRATIO)
    cv2.resizeWindow('Track Upper Body', [500, 800])

    # Pushup Logic
    pushup_position = False

    detector = poseDetector()
    theta = 0
    while True:
        # img is in bgr
        success, img = cap.read()
        # Convert bgr to rgb for mediapipe models
        img = detector.getPose(img)

        # Start timer to activate pushup mode
        detector.checkIfReady()
        # Get list of landmarks
        lmList = detector.getPosition(img)
        # Check pushup position
        if len(lmList) != 0:
            angle = detector.checkPushupPosition(lmList[11:17]) # (11th -> 16th)
            # pdb.set_trace()
            cv2.putText(img, str(int(angle)), (50, 200), cv2.FONT_HERSHEY_SIMPLEX, 5, (255, 255, 255), 3)
            cv2.putText(img, str(int(detector.counter)), (900, 200), cv2.FONT_HERSHEY_SIMPLEX, 5, (255, 255, 255), 3)

        # Count Pushups
        detector.countPushups()
        detector.print_status()

        cTime = time.time()
        fps = 1 / (cTime - pTime)
        pTime = cTime
        # print(theta)
        # cv2.putText(img, str(int(theta)), (50, 50), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 0, 0), 3)
        cv2.imshow('Track Upper Body', img)
        cv2.waitKey(1)

# If we just run this file it will run main instead. If we call a fn in this file it won't run main.
if __name__ == "__main__":
    main()


import torch
import torch.nn as nn
import torch.nn.functional as F

class MLP(nn.Module):
    def __init__(self, input_dim, output_dim, num_neuron, nonlinear=F.relu):
        super(MLP, self).__init__()

        self.fc1 = nn.Linear(input_dim, num_neuron)
        self.fc2 = nn.Linear(num_neuron, output_dim)
        self.nonlinear = nonlinear

    def forward(self, x):
        x = torch.flatten(x, 1) # flatten all dimensions except batch
        x = F.relu(self.fc1(x))
        x = self.fc2(x)
        return F.softmax(x, dim=1)


'''
我们来认识一个快速生成列表的方式：列表生成式

了解两个器：1、生成器 2、迭代器

总结：
生成器是对列表生成式的一种改进，如果列表元素可以按照某种算法推算出来，那我们是否可以在循环的过程中不断推算出后续的元素呢？
这样就不必创建完整的list，从而节省大量的空间。在Python中，这种一边循环一边计算的机制，称为生成器：generator。
定义generator的一种方法。如果一个函数定义中包含yield关键字，那么这个函数就不再是一个普通函数，而是一个generator
最难理解的就是generator和函数的执行流程不一样。函数是顺序执行，遇到return语句或者最后一行函数语句就返回。而变成generator的函数，
在每次调用next()的时候执行，遇到yield语句返回，再次执行时从上次返回的yield语句处继续执行

我们已经知道，可以直接作用于for循环的数据类型有以下几种：

一类是集合数据类型，如list、tuple、dict、set、str等；

一类是generator，包括生成器和带yield的generator function。

这些可以直接作用于for循环的对象统称为可迭代对象：Iterable。

可以使用isinstance()判断一个对象是否是Iterable对象：

生成器都是Iterator对象，但list、dict、str虽然是Iterable，却不是Iterator。

凡是可作用于for循环的对象都是Iterable类型；

凡是可作用于next()函数的对象都是Iterator类型，它们表示一个惰性计算的序列；

集合数据类型如list、dict、str等是Iterable但不是Iterator，不过可以通过iter()函数获得一个Iterator对象。

Python的for循环本质上就是通过不断调用next()函数实现的
'''
#首先介绍列表生成器
from collections import Iterable

def test():
    list=[]
    for each in range(1,8):               #range()中的参数表示范围
        list.append(each)
    print(list)

    list=[x*x for x in range(1,9)]        #这种特别的写法很简便
    print(list)

def test1():
    list = (x*x for x in range(1,9))       #注意与上面的比较，这里是（）
    a=next(list)                           #注意这里可以用next()不断取得下一个值，当然也可以用循环
    print(a)
    for each in list:
        print(each)

def test2(max):                               #斐波拉契数列
    n, a, b = 0, 0, 1
    while n < max:
        yield (b)                             #生成器的关键词yield
        a, b = b, a + b
        n = n + 1
    return 'done'

def test3():
    a=isinstance('abc', Iterable)             #用来判断是否为该类型，是返回true,反之
    print(a)

if __name__ == '__main__':

    test()
    #输出结果[1, 2, 3, 4, 5, 6, 7]
    #输出结果[1, 4, 9, 16, 25, 36, 49, 64]

    test1()
    #输出结果1, 4, 9, 16, 25, 36, 49, 64

    test2(6)
    #输出结果112358

    test3()
    #输出结果true


from django.db import models
from django.db.models.signals import pre_save,post_save,m2m_changed
from django.conf import settings
from products.models import Product,Quantity_Price
import math

User = settings.AUTH_USER_MODEL

class CartManager(models.Manager):
    def new_or_get(self,request):
        cart_id = request.session.get('cart_id',None)
        qs = self.get_queryset().filter(id=cart_id)
        if qs.count() == 1:
            new_obj = False
            cart_obj = qs.first()
            if request.user.is_authenticated and cart_obj.user is None:
                cart_obj.user = request.user
                cart_obj.save()
        else:
            new_obj = True
            cart_obj = Cart.objects.new(user=request.user)
            request.session['cart_id'] = cart_obj.id
        return cart_obj,new_obj

    def get_or_none(self,request):
        cart_id = request.session.get('cart_id',None)
        qs = self.get_queryset().filter(id=cart_id)
        if qs.count() == 1:
            existed = True
            cart_obj = qs.first()
            if request.user.is_authenticated and cart_obj.user is None:
                cart_obj.user = request.user
                cart_obj.save()
        else:
            existed = False
            cart_obj = None
        return cart_obj,existed

    def update_price(self,request,cart_obj=None):
        items = cart_obj.items.all()
        total = 0
        for item in items:
            total += item.price
        cart_obj.subtotal = total
        cart_obj.save()

    def new(self,user=None):
        user_obj = None
        if user is not None:
            if user.is_authenticated:
                user_obj = user
        return self.model.objects.create(user=user_obj)

class CartItem(models.Model):
    product = models.ForeignKey(Product,null=True,blank=True,on_delete=models.CASCADE)
    quantity = models.PositiveIntegerField(default=1)
    quantity_price = models.ManyToManyField(Quantity_Price,blank=True)
    price = models.DecimalField(max_digits=12,decimal_places=2,null=True,blank=True)

    def __str__(self):
        try:
            x = ""
            x += self.product.title + " -- "
            if self.product.flavour:
                x += self.product.flavour + " -- "
            x += str(self.quantity) + " -- "
            if(self.quantity_price.exists()):
                y = self.quantity_price.first()
                x +=  str(y.quantity) + y.quantity_type + " -- " + str(self.price)
            return x
        except:
            return "NA"

class Cart(models.Model):
    user = models.ForeignKey(User,blank=True,null=True,on_delete=models.CASCADE)
    items = models.ManyToManyField(CartItem,blank=True)
    subtotal = models.DecimalField(default=0.00,max_digits=50,decimal_places=2)
    total = models.DecimalField(default=0.00,max_digits=50,decimal_places=2)
    updated = models.DateTimeField(auto_now=True)
    timestamp = models.DateTimeField(auto_now_add=True)

    objects = CartManager()

    def __str__(self):
        return str(self.id)

def m2m_save_cart_receiver(sender,instance,action,*args,**kwargs):
    if action == "post_add" or action == "post_remove" or action == "post_clear":
        items = instance.items.all()
        total = 0
        for item in items:
            total += item.price
        instance.subtotal = total
        instance.save()

def pre_save_cart_receiver(sender,instance,*args,**kwargs):
    if instance.subtotal > 0:
        instance.total = math.fsum([instance.subtotal , 0])
    else:
        instance.total = 0.00

def pre_save_cartitem_receiver(sender,instance,*args,**kwargs):
    if not instance.id:
        return
    if(instance.quantity_price.exists()):
        instance.price = instance.quantity_price.first().price * int(instance.quantity)

pre_save.connect(pre_save_cartitem_receiver,sender=CartItem)
m2m_changed.connect(m2m_save_cart_receiver,sender=Cart.items.through)
pre_save.connect(pre_save_cart_receiver,sender=Cart)


#モジュールのインストール################################################################################
from bs4 import BeautifulSoup
import datetime
from datetime import datetime as dt
import re
from dateutil import relativedelta
import pandas as pd
import requests

#前準備
cols=["タイトル","キャラ"]
df=pd.DataFrame(columns=cols)

#スクレイピング実装################################################################################
URL="https://imas-shinycolors.boom-app.wiki/entry/card-list" #シャニマスBoom-appさんのカード情報サイト
res=requests.get(URL)
soup=BeautifulSoup(res.content,"html.parser")

#テーブルごとにカード情報があるため、部分的に抽出する
tbody=soup.select("tbody")

#コミュのあるテーブルのみ取得する
comu_limit=6  #全8テーブル中、6テーブルがカード情報
countdf=0
for body in range(comu_limit):
  tr=tbody[body].select("tr")

  #trの数だけデータフレームに格納
  for i in range(len(tr)):
    card_list=[]
    text=tr[i].text

    #カード名、キャラ名の飾り文字をなくす処理
    splittext=text.split("【")[1]
    cardtitle=splittext.split("】")[0]
    card_name=splittext.split("】")[1]
    card_name=card_name.split("\n")[0]
    card_list.append(cardtitle)
    card_list.append(card_name)

    df.loc[countdf]=card_list
    countdf+=1

#データ補完作業################################################################################
#「アイドルロード」単体にコミュは存在しないので除外
df=df[df["タイトル"]!="アイドルロード"]

#カード名では取り出せない「WING」「ファン感謝祭」「GRAD」「Landing Point」「STEP」を人数分追加
unique_chara_arr=df["キャラ"].unique()

#タイトル文字を作成
WING_col="WING"
FUN_col="ファン感謝祭"
GRAD_col="GRAD"
LP_col="Landing Point"
STEP_col="STEP"
storytitle_list=[WING_col,FUN_col,GRAD_col,LP_col,STEP_col]

#シナリオごとのキャラストーリーを追加
for i in range(len(storytitle_list)):
  for j in range(len(unique_chara_arr)):
    story_insert_list=[]
    story_insert_list.append(storytitle_list[i])
    story_insert_list.append(unique_chara_arr[j])

    #最終行以降に追加でデータ挿入
    df.loc[countdf]=story_insert_list
    countdf+=1

#スプレッドシートに出力################################################################################
#モジュール読込、転記するスプレッドシートのアクセス認証
from google.colab import auth
auth.authenticate_user()

import gspread
from google.auth import default

creds,_=default()
gc=gspread.authorize(creds)

Spr="シャニマスコミュ"
workbook=gc.open(Spr)                   #スプシ名の定義し、開く
worksheet=workbook.worksheet("シート2") #シート名の定義、開く

#転記範囲を指定し、出力
from gspread_dataframe import set_with_dataframe
set_with_dataframe(worksheet,df,row=1,col=1,include_index=False,resize=False) #resize：dataframeの形に合わせてスプレッドシートを操作する、index：index名をつけるか

シャニマススクレイピング.py

シャニマススクレイピング.py


import numpy as np
from numpy.random import random
from matplotlib import pyplot as plt
from kmean.kmeans import KMeans
from kmean.kutils import normalize

simple_data = np.array(
    [
        [2, 3, 2, 9, 10, 4, 11, 12, 10.5, 1],
        [0.5, 1.5, 2, 3, 2, 10, 8, 4, 2, 10]
    ]
)

simple_data = normalize(simple_data)
print(simple_data, '\n\n')

x = []

for i in range(1, 6):
    myModel = KMeans()
    myModel.fit(simple_data, k=i)
    print(myModel.variation())
    x.append(myModel.variation())
    myModel.plot_2D_show()

y = []

for i in range(1, len(x)):
    y.append(x[0]-x[i])

# Elbow plot

plt.plot(y)
plt.show()


import PyShellCommands as ps

running = True

if __name__ == "__main__":
    print("Starting PyShell.")
    print("       ________\n"
          +"      |o       |\n"
          +"    >-|____    |___\n"
          +"    _______|   |   |\n"
          +"   |    _______|   |\n"
          +"   |   |    _______|\n"
          +"   |___|   |_____\n"
          +"       |        o|-<   \n"
          +"       |_________|\n")
    while running:
        command = input("Enter a command or type 'help' for help. \n>")
        ps.parse(command)


import numpy as np
from var import lambdas, EndCond, Nmodes
#*****************************************************
#           BASIS FUNCTIONS SUBROUTINES
#*****************************************************
#=====================================================
def freqEq(x):
    if((EndCond == 'fixed-fixed') or (EndCond == 'free-free')):
        return np.cos(x)*np.cosh(x)-1.0
    elif(EndCond == 'fixed-pinned'):
        return np.tan(x)-np.tanh(x)
    elif(EndCond == 'fixed-free'):
        return np.cos(x)*np.cosh(x)+1.0
    elif(EndCond == 'pinned-pinned'):
        return np.sin(x)
#=====================================================
def dfreqEq_dx(x):
    if((EndCond == 'fixed-fixed') or (EndCond == 'free-free') or (EndCond == 'fixed-free')):
        return np.cos(x)*np.sinh(x)-np.sin(x)*np.cosh(x)
    elif(EndCond == 'fixed-pinned'):
        return ((1.0/np.cos(x))**2.0) - ((1.0/np.cosh(x))**2.0)
    elif(EndCond == 'pinned-pinned'):
        return np.cos(x)
#=====================================================
def GetEigenValues_FreqEq():
    for i in range(0,Nmodes):
        x1 = 1.0*lambdas[i]
        if(i==0):
            x0 = 0.0
        else:
            x0 = lambdas[i-1]

        # Newton's root finding method
        while(np.abs(x1-x0)>=(1.0e-15)):
            x0 = 1.0*x1
            x1 = x0 - freqEq(x0)/dfreqEq_dx(x0)

        lambdas[i] = 1.0*x1
#=====================================================
def sigma(r):
    if(EndCond == 'fixed-free'):
        return (np.sinh(lambdas[r])-np.sin(lambdas[r]))/(np.cosh(lambdas[r])+np.cos(lambdas[r]))
    elif((EndCond == 'fixed-fixed') or (EndCond == 'free-free')):
        return (np.cosh(lambdas[r])-np.cos(lambdas[r]))/(np.sinh(lambdas[r])-np.sin(lambdas[r]))
    elif(EndCond == 'pinned-pinned'):
        return 0.0
    elif(EndCond == 'fixed-pinned'):
        return np.float128(1.0)/np.tan(lambdas[r])
#=====================================================
def phi(r,x):
    if(EndCond == 'free-free'):
        return np.cosh(lambdas[r]*x)+np.cos(lambdas[r]*x)-sigma(r)*(np.sinh(lambdas[r]*x)+np.sin(lambdas[r]*x))
    elif((EndCond == 'fixed-free') or ((EndCond == 'fixed-fixed') or (EndCond == 'fixed-pinned'))):
        return np.cosh(lambdas[r]*x)-np.cos(lambdas[r]*x)-sigma(r)*(np.sinh(lambdas[r]*x)-np.sin(lambdas[r]*x))
    elif(EndCond == 'pinned-pinned'):
        return np.sin(lambdas[r]*x)
#=====================================================
def dphi(r,x):
    if(EndCond == 'free-free'):
        return (lambdas[r])*np.sinh(lambdas[r]*x)-(lambdas[r])*np.sin(lambdas[r]*x)-sigma(r)*((lambdas[r])*np.cosh(lambdas[r]*x)+(lambdas[r])*np.cos(lambdas[r]*x))
    elif((EndCond == 'fixed-free') or ((EndCond == 'fixed-fixed') or (EndCond == 'fixed-pinned'))):
        return (lambdas[r])*np.sinh(lambdas[r]*x)+(lambdas[r])*np.sin(lambdas[r]*x)-sigma(r)*((lambdas[r])*np.cosh(lambdas[r]*x)-(lambdas[r])*np.cos(lambdas[r]*x))
    elif(EndCond == 'pinned-pinned'):
        return lambdas[r]*np.cos(lambdas[r]*x)
#=====================================================
def ddphi(r,x):
    if(EndCond == 'free-free'):
        return (lambdas[r]**2.0)*np.cosh(lambdas[r]*x)-(lambdas[r]**2.0)*np.cos(lambdas[r]*x)-sigma(r)*((lambdas[r]**2.0)*np.sinh(lambdas[r]*x)-(lambdas[r]**2.0)*np.sin(lambdas[r]*x))
    elif((EndCond == 'fixed-free') or ((EndCond == 'fixed-fixed') or (EndCond == 'fixed-pinned'))):
        return (lambdas[r]**2.0)*np.cosh(lambdas[r]*x)+(lambdas[r]**2.0)*np.cos(lambdas[r]*x)-sigma(r)*((lambdas[r]**2.0)*np.sinh(lambdas[r]*x)+(lambdas[r]**2.0)*np.sin(lambdas[r]*x))
    elif(EndCond == 'pinned-pinned'):
        return -(lambdas[r]**2.0)*np.sin(lambdas[r]*x)
#=====================================================
def b_sr_integrand(s,r,x):
    return phi(s,x)*dphi(r,x)
#=====================================================
def c_sr_integrand(s,r,x):
    return phi(s,x)*ddphi(r,x)
#=====================================================
def d_sr_integrand(s,r,x):
    return phi(s,x)*x*ddphi(r,x)
#=====================================================
def e_sr_integrand(s,r,x):
    return phi(s,x)*(dphi(r,x) + (x-np.float128(1.0))*ddphi(r,x))
#=====================================================
def evaluate_stdel_intgrals(s,r):
    # standard element domain limits
    a = np.float128(0.0)
    b = np.float128(1.0)

    # number of divisions
    n = 1000

    # Composite Trapezoidal Rule
    h = np.float128(b-a)/np.float128(n)
    sum_b = np.float128(0.0)
    sum_c = np.float128(0.0)
    sum_d = np.float128(0.0)
    sum_e = np.float128(0.0)

    for i in range(1,n):
        x = a + np.float128(i)*h
        sum_b = sum_b+b_sr_integrand(s,r,x)
        sum_c = sum_c+c_sr_integrand(s,r,x)
        sum_d = sum_d+d_sr_integrand(s,r,x)
        sum_e = sum_e+e_sr_integrand(s,r,x)

    b_sr_val = h*(b_sr_integrand(s,r,a)+np.float128(2.0)*sum_b+b_sr_integrand(s,r,b))/np.float128(2.0)
    c_sr_val = h*(c_sr_integrand(s,r,a)+np.float128(2.0)*sum_c+c_sr_integrand(s,r,b))/np.float128(2.0)
    d_sr_val = h*(d_sr_integrand(s,r,a)+np.float128(2.0)*sum_d+d_sr_integrand(s,r,b))/np.float128(2.0)
    e_sr_val = h*(e_sr_integrand(s,r,a)+np.float128(2.0)*sum_e+e_sr_integrand(s,r,b))/np.float128(2.0)

    return [b_sr_val, c_sr_val, d_sr_val, e_sr_val]
#=====================================================


import math
import torch
import numpy as np
import scipy.signal

def fft_freqz(b, a, n_fft: int = 512):
    B = torch.fft.rfft(b, n_fft)
    A = torch.fft.rfft(a, n_fft)
    H = B / A
    return H

def fft_sosfreqz(sos: torch.Tensor, n_fft: int = 512):
    """Compute the complex frequency response via FFT of cascade of biquads

    Args:
        sos (torch.Tensor): Second order filter sections with shape (bs, n_sections, 6)
        n_fft (int): FFT size. Default: 512
    Returns:
        H (torch.Tensor): Overall complex frequency response with shape (bs, n_bins)
    """
    bs, n_sections, n_coeffs = sos.size()
    assert n_coeffs == 6  # must be second order
    for section_idx in range(n_sections):
        b = sos[:, section_idx, :3]
        a = sos[:, section_idx, 3:]
        if section_idx == 0:
            H = fft_freqz(b, a, n_fft=n_fft)
        else:
            H *= fft_freqz(b, a, n_fft=n_fft)
    return H

def freqdomain_fir(x, H, n_fft):
    X = torch.fft.rfft(x, n_fft)
    Y = X * H.type_as(X)
    y = torch.fft.irfft(Y, n_fft)
    return y

def octave_band_filterbank(num_taps: int, sample_rate: float):
    # create octave-spaced bandpass filters
    bands = [
        31.5,
        63,
        125,
        250,
        500,
        1000,
        2000,
        4000,
        8000,
        16000,
    ]
    num_bands = len(bands) + 2
    filts = []  # storage for computed filter coefficients

    # lowest band is a lowpass
    filt = scipy.signal.firwin(
        num_taps,
        12,
        fs=sample_rate,
    )
    filt = torch.from_numpy(filt.astype("float32"))
    filt = torch.flip(filt, dims=[0])
    filts.append(filt)

    for fc in bands:
        f_min = fc / np.sqrt(2)
        f_max = fc * np.sqrt(2)
        f_max = np.clip(f_max, a_min=0, a_max=(sample_rate / 2) * 0.999)
        filt = scipy.signal.firwin(
            num_taps,
            [f_min, f_max],
            fs=sample_rate,
            pass_zero=False,
        )
        filt = torch.from_numpy(filt.astype("float32"))
        filt = torch.flip(filt, dims=[0])
        filts.append(filt)

    # highest is a highpass
    filt = scipy.signal.firwin(num_taps, 18000, fs=sample_rate, pass_zero=False)
    filt = torch.from_numpy(filt.astype("float32"))
    filt = torch.flip(filt, dims=[0])
    filts.append(filt)

    filts = torch.stack(filts, dim=0)  # stack coefficients into single filter
    filts = filts.unsqueeze(1)  # shape: num_bands x 1 x num_taps

    return filts

def lfilter_via_fsm(x: torch.Tensor, b: torch.Tensor, a: torch.Tensor = None):
    """Use the frequency sampling method to approximate an IIR filter.
    The filter will be applied along the final dimension of x.
    Args:
        x (torch.Tensor): Time domain signal with shape (bs, 1, timesteps)
        b (torch.Tensor): Numerator coefficients with shape (bs, N).
        a (torch.Tensor): Denominator coefficients with shape (bs, N).
    Returns:
        y (torch.Tensor): Filtered time domain signal with shape (bs, 1, timesteps)
    """
    bs, chs, seq_len = x.size()  # enforce shape
    assert chs == 1

    # round up to nearest power of 2 for FFT
    n_fft = 2 ** torch.ceil(torch.log2(torch.tensor(x.shape[-1] + x.shape[-1] - 1)))
    n_fft = n_fft.int()

    # move coefficients to same device as x
    b = b.type_as(x)

    if a is None:
        # directly compute FFT of numerator coefficients
        H = torch.fft.rfft(b, n_fft)
    else:
        a = a.type_as(x)
        # compute complex response as ratio of polynomials
        H = fft_freqz(b, a, n_fft=n_fft)

    # add extra dims to broadcast filter across
    for _ in range(x.ndim - 2):
        H = H.unsqueeze(1)

    # apply as a FIR filter in the frequency domain
    y = freqdomain_fir(x, H, n_fft)

    # crop
    y = y[..., : x.shape[-1]]

    return y

def sosfilt_via_fsm(sos: torch.Tensor, x: torch.Tensor):
    """Use the frequency sampling method to approximate a cascade of second order IIR filters.

    The filter will be applied along the final dimension of x.
    Args:
        sos (torch.Tensor): Tensor of coefficients with shape (bs, n_sections, 6).
        x (torch.Tensor): Time domain signal with shape (bs, ... , timesteps)

    Returns:
        y (torch.Tensor): Filtered time domain signal with shape (bs, ..., timesteps)
    """
    bs = x.size(0)

    # round up to nearest power of 2 for FFT
    n_fft = 2 ** torch.ceil(torch.log2(torch.tensor(x.shape[-1] + x.shape[-1] - 1)))
    n_fft = n_fft.int()

    # compute complex response as ratio of polynomials
    H = fft_sosfreqz(sos, n_fft=n_fft)

    # add extra dims to broadcast filter across
    for _ in range(x.ndim - 2):
        H = H.unsqueeze(1)

    # apply as a FIR filter in the frequency domain
    y = freqdomain_fir(x, H, n_fft)

    # crop
    y = y[..., : x.shape[-1]]

    return y

def one_pole_butter_lowpass(
    f_c: torch.Tensor,
    sample_rate: float,
):
    """

    This function is correct.

    """
    f_c = f_c.view(-1, 1)
    w_d = 2 * np.pi * (f_c / sample_rate)  # digital frequency in radians
    w_c = torch.tan(w_d / 2)  # apply pre-warping for analog frequency

    a0 = 1 + w_c
    a1 = w_c - 1
    b0 = w_c
    b1 = w_c

    b = torch.cat([b0, b1], dim=-1)
    a = torch.cat([a0, a1], dim=-1)

    # normalize
    b = b / a0
    a = a / a0

    print("ba", b.shape, a.shape)

    return b, a

def one_pole_filter(
    cutoff_hz: torch.Tensor,
    filter_type: str,
    sample_rate: float = 2.0,
):
    """Design a simple 1-pole highpass or lowpass IIR filter.

    Filtering is performed along the final dimension of the input tensor.

    Args:
        cutoff_hz (torch.Tensor): Lowpass filter centre frequency (normalized 0,1) with shape (bs). (Higher = more smoothing)
        filter_type (str): Specify either "highpass" or "lowpass". (Note this parameter cannot be optimize with gradient descent.)
        sample_rate (float): Sample rate of the input signal.

    Returns:
        b, a (torch.Tensor). Coefficient tensors with shape (bs, 2).
    """
    # setup shape for broadcasting
    bs = cutoff_hz.shape[0]
    cutoff_hz = cutoff_hz.view(bs, 1)
    nyquist = sample_rate // 2

    # compute coefficients
    if filter_type == "highpass":
        a1 = cutoff_hz / nyquist
    elif filter_type == "lowpass":
        a1 = -1 + (cutoff_hz / nyquist)
    else:
        raise ValueError(f"Invalid filter_type = {filter_type}.")

    print(a1)

    a0 = torch.ones(bs, 1).type_as(a1)

    b0 = 1 - torch.abs(a1)
    b1 = torch.zeros(bs, 1).type_as(a1)

    b = torch.cat([b0, b1], dim=1)
    a = torch.cat([a0, a1], dim=1)

    return b, a

def biquad(
    gain_db: torch.Tensor,
    cutoff_freq: torch.Tensor,
    q_factor: torch.Tensor,
    sample_rate: float,
    filter_type: str = "peaking",
):
    bs = gain_db.size(0)
    # reshape params
    gain_db = gain_db.view(bs, -1)
    cutoff_freq = cutoff_freq.view(bs, -1)
    q_factor = q_factor.view(bs, -1)

    A = 10 ** (gain_db / 40.0)
    w0 = 2 * math.pi * (cutoff_freq / sample_rate)
    alpha = torch.sin(w0) / (2 * q_factor)
    cos_w0 = torch.cos(w0)
    sqrt_A = torch.sqrt(A)

    if filter_type == "high_shelf":
        b0 = A * ((A + 1) + (A - 1) * cos_w0 + 2 * sqrt_A * alpha)
        b1 = -2 * A * ((A - 1) + (A + 1) * cos_w0)
        b2 = A * ((A + 1) + (A - 1) * cos_w0 - 2 * sqrt_A * alpha)
        a0 = (A + 1) - (A - 1) * cos_w0 + 2 * sqrt_A * alpha
        a1 = 2 * ((A - 1) - (A + 1) * cos_w0)
        a2 = (A + 1) - (A - 1) * cos_w0 - 2 * sqrt_A * alpha
    elif filter_type == "low_shelf":
        b0 = A * ((A + 1) - (A - 1) * cos_w0 + 2 * sqrt_A * alpha)
        b1 = 2 * A * ((A - 1) - (A + 1) * cos_w0)
        b2 = A * ((A + 1) - (A - 1) * cos_w0 - 2 * sqrt_A * alpha)
        a0 = (A + 1) + (A - 1) * cos_w0 + 2 * sqrt_A * alpha
        a1 = -2 * ((A - 1) + (A + 1) * cos_w0)
        a2 = (A + 1) + (A - 1) * cos_w0 - 2 * sqrt_A * alpha
    elif filter_type == "peaking":
        b0 = 1 + alpha * A
        b1 = -2 * cos_w0
        b2 = 1 - alpha * A
        a0 = 1 + (alpha / A)
        a1 = -2 * cos_w0
        a2 = 1 - (alpha / A)
    elif filter_type == "low_pass":
        b0 = (1 - cos_w0) / 2
        b1 = 1 - cos_w0
        b2 = (1 - cos_w0) / 2
        a0 = 1 + alpha
        a1 = -2 * cos_w0
        a2 = 1 - alpha
    elif filter_type == "high_pass":
        b0 = (1 + cos_w0) / 2
        b1 = -(1 + cos_w0)
        b2 = (1 + cos_w0) / 2
        a0 = 1 + alpha
        a1 = -2 * cos_w0
        a2 = 1 - alpha
    else:
        raise ValueError(f"Invalid filter_type: {filter_type}.")

    b = torch.stack([b0, b1, b2], dim=1).view(bs, -1)
    a = torch.stack([a0, a1, a2], dim=1).view(bs, -1)

    # normalize
    b = b.type_as(gain_db) / a0
    a = a.type_as(gain_db) / a0

    return b, a


#!/bin/python3

class SinglyLinkedListNode:
    def __init__(self, node_data):
        self.data = node_data
        self.next = None

class SinglyLinkedList:
    def __init__(self):
        self.head = None
        self.tail = None

    def insert_node(self, node_data):
        node = SinglyLinkedListNode(node_data)

        if not self.head:
            self.head = node
        else:
            self.tail.next = node

        self.tail = node

def print_singly_linked_list(node, sep):
    while node:
        print(str(node.data), end='')
        node = node.next
        if node:
            print(sep, end='')
    print()

def find_merge_node(head1, head2):
    nodes = {}

    node = head1
    while node is not None:
        nodes[node] = 1
        node = node.next

    node = head2
    while node is not None:
        if node in nodes:
            return node.test_data
        node = node.next
    return None

if __name__ == '__main__':

    data = [
        ([1, 2, 3],  [1, 2, 3], 1),
        ([1, 2, 3], [1, 3], 2),
        ([3], [4], 4),
    ]

    for test_case in data:
        index = test_case[-1]
        llist1 = SinglyLinkedList()
        llist2 = SinglyLinkedList()

        for llist1_item in test_case[0]:
            llist1.insert_node(llist1_item)

        for llist2_item in test_case[1]:
            llist2.insert_node(llist2_item)

        ptr1 = llist1.head
        ptr2 = llist2.head

        for i in range(len(test_case[0])):
            if i < index:
                ptr1 = ptr1.next

        for i in range(len(test_case[1])):
            if i != len(test_case[1]) - 1:
                ptr2 = ptr2.next

        ptr2.next = ptr1
        result = find_merge_node(llist1.head, llist2.head)

        print(f"Result: {str(result)}")


import sys
import re
import operator
from functools import reduce

non_digit_matcher = re.compile(r'\D')
expr_matcher = re.compile(r'(\w+ \d+ \d+)')
operations = {'add': operator.add,
              'multiply': operator.mul}

def solve(expr: str) -> str:
    """
    Given an expression, this function recursively solves the expression and returns the result

    :param expr: str representing the expression to solve e.g "(add 1 2)" or "123"
    :return: the result of the expression in str
    """

    if not non_digit_matcher.search(expr):
        return expr
    expr_match = expr_matcher.search(expr)
    op, *exps = expr_match.group(1).split(' ')
    assert op in operations, f'{op} operation is not supported. Use either add or multiply'
    result = reduce(operations[op], map(int, exps))
    arg = expr.replace(f'({expr_match.group(1)})', str(result))
    return solve(arg)

if __name__ == '__main__':
    if len(sys.argv) != 2:
        print('The program was invoked with invalid arguments.\ntry python calc.py \"(add 1 2)\"')
    else:
        print(solve(sys.argv[1]))


from dijskra import tracing, network, dequeue as queue
from VARS import maze

def find_in_queue(query):
	i = 0
	for card in queue:
		if(card[0] == query):
			return i
		i += 1

#maze[network[queue[-1][0]][0]] = 5
#previous_path = -1
next_path = find_in_queue(queue[-1][0])
while next_path != 0:
	#maze[network[queue[next_path][2]][0]] = 5
	previous_path = next_path
	next_path = find_in_queue(queue[previous_path][2])
	1 == 1
	for pxs in tracing:
		if(network[queue[previous_path][0]][0] == pxs[0] and network[queue[next_path][0]][0] == pxs[-1]):
			for px in pxs:
				maze[px] = 5

print('Line Draw!')


# https://leetcode.com/problems/sum-of-even-numbers-after-queries/
# You are given an integer array nums and an array queries where queries[i] = [vali, indexi].
#
# For each query i, first, apply nums[indexi] = nums[indexi] + vali, then print the sum of the even values of nums.
#
# Return an integer array answer where answer[i] is the answer to the ith query.
#
#

class Solution:
    def sumEvenAfterQueries(self, nums: List[int], queries: List[List[int]]) -> List[int]:
        even_sum = sum(v for v in nums if v % 2 == 0)
        res: list[int] = []

        for val, idx in queries:
            if nums[idx] % 2 == 0:
                even_sum -= nums[idx]

            nums[idx] += val

            if nums[idx] % 2 == 0:
                even_sum += nums[idx]

            res.append(even_sum)

        return res


class Card:
    def __init__(self, name, x = 0, y = 0, width = 0, height = 0):
        self.name = name
        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.position = (self.x, self.y, self.x + width, self.y + self.height)
        self.points = self.get_points()
        self.suit = self.get_suit()

    def get_suit(self):
        # check suit
        if "D" in self.name or "Q" in self.name or "J" in self.name:
            suit = "T"  # trump
        elif "C" in self.name:
            suit = "C"  # club
        elif "H" in self.name:
            suit = "H"  # heart
        else:
            suit = "S"  # spade
        return suit

    def get_points(self):
        # check points
        if "A" in self.name:
            points = 11
        elif "10" in self.name:
            points = 10
        elif "K" in self.name:
            points = 4
        elif "Q" in self.name:
            points = 3
        elif "J" in self.name:
            points = 2
        else:
            points = 0
        return points

    def validation_of_suit(self, suit_2):
            if self.suit == suit_2:
                return True
            else:
                return False

    def draw_card(self, card_images):
        pass


"""Run Experiment

This script allows to run one federated learning experiment; the experiment name, the method and the
number of clients/tasks should be precised along side with the hyper-parameters of the experiment.

The results of the experiment (i.e., training logs) are written to ./logs/ folder.

This file can also be imported as a module and contains the following function:

    * run_experiment - runs one experiments given its arguments
"""
from utils.utils import *
from utils.constants import *
from utils.args import *

from torch.utils.tensorboard import SummaryWriter

def init_clients(args_, root_path, logs_dir):
    """
    initialize clients from data folders
    :param args_:
    :param root_path: path to directory containing data folders
    :param logs_dir: path to logs root
    :return: List[Client]
    """
    print("===> Building data iterators..")
    train_iterators, val_iterators, test_iterators =\
        get_loaders(
            type_=LOADER_TYPE[args_.experiment],
            root_path=root_path,
            batch_size=args_.bz,
            is_validation=args_.validation
        )

    print("===> Initializing clients..")
    clients_ = []
    for task_id, (train_iterator, val_iterator, test_iterator) in \
            enumerate(tqdm(zip(train_iterators, val_iterators, test_iterators), total=len(train_iterators))):

        if train_iterator is None or test_iterator is None:
            continue

        learners_ensemble =\
            get_learners_ensemble(
                n_learners=args_.n_learners,
                name=args_.experiment,
                device=args_.device,
                optimizer_name=args_.optimizer,
                scheduler_name=args_.lr_scheduler,
                initial_lr=args_.lr,
                input_dim=args_.input_dimension,
                output_dim=args_.output_dimension,
                n_rounds=args_.n_rounds,
                seed=args_.seed,
                mu=args_.mu
            )

        logs_path = os.path.join(logs_dir, "task_{}".format(task_id))
        os.makedirs(logs_path, exist_ok=True)
        logger = SummaryWriter(logs_path)

        client = get_client(
            client_type=CLIENT_TYPE[args_.method],
            learners_ensemble=learners_ensemble,
            q=args_.q,
            train_iterator=train_iterator,
            val_iterator=val_iterator,
            test_iterator=test_iterator,
            logger=logger,
            local_steps=args_.local_steps,
            tune_locally=args_.locally_tune_clients
        )

        clients_.append(client)

    return clients_

def run_experiment(args_):
    torch.manual_seed(args_.seed)

    data_dir = get_data_dir(args_.experiment)

    if "logs_dir" in args_:
        logs_dir = args_.logs_dir
    else:
        logs_dir = os.path.join("logs", args_to_string(args_))

    print("==> Clients initialization..")
    clients = init_clients(args_, root_path=os.path.join(data_dir, "train"), logs_dir=os.path.join(logs_dir, "train"))

    print("==> Test Clients initialization..")
    test_clients = init_clients(args_, root_path=os.path.join(data_dir, "test"),
                                logs_dir=os.path.join(logs_dir, "test"))

    logs_path = os.path.join(logs_dir, "train", "global")
    os.makedirs(logs_path, exist_ok=True)
    global_train_logger = SummaryWriter(logs_path)

    logs_path = os.path.join(logs_dir, "test", "global")
    os.makedirs(logs_path, exist_ok=True)
    global_test_logger = SummaryWriter(logs_path)

    global_learners_ensemble = \
        get_learners_ensemble(
            n_learners=args_.n_learners,
            name=args_.experiment,
            device=args_.device,
            optimizer_name=args_.optimizer,
            scheduler_name=args_.lr_scheduler,
            initial_lr=args_.lr,
            input_dim=args_.input_dimension,
            output_dim=args_.output_dimension,
            n_rounds=args_.n_rounds,
            seed=args_.seed,
            mu=args_.mu
        )

    if args_.decentralized:
        aggregator_type = 'decentralized'
    else:
        aggregator_type = AGGREGATOR_TYPE[args_.method]

    aggregator =\
        get_aggregator(
            aggregator_type=aggregator_type,
            clients=clients,
            global_learners_ensemble=global_learners_ensemble,
            lr_lambda=args_.lr_lambda,
            lr=args_.lr,
            q=args_.q,
            mu=args_.mu,
            communication_probability=args_.communication_probability,
            sampling_rate=args_.sampling_rate,
            log_freq=args_.log_freq,
            global_train_logger=global_train_logger,
            global_test_logger=global_test_logger,
            test_clients=test_clients,
            verbose=args_.verbose,
            seed=args_.seed
        )

    print("Training..")
    pbar = tqdm(total=args_.n_rounds)
    current_round = 0
    while current_round <= args_.n_rounds:

        aggregator.mix()

        if aggregator.c_round != current_round:
            pbar.update(1)
            current_round = aggregator.c_round

    if "save_dir" in args_:
        save_dir = os.path.join(args_.save_dir)

        os.makedirs(save_dir, exist_ok=True)
        aggregator.save_state(save_dir)

if __name__ == "__main__":
    torch.backends.cudnn.deterministic = True
    torch.backends.cudnn.benchmark = False

    args = parse_args()
    run_experiment(args)


import unittest
from unittest.mock import patch
from enum import Enum
from typing import NamedTuple

import numpy as np

import matlab_hooks as mh

try:
    with mh._matlab_paths():
        import MatlabAlgorithms.MsiAlgorithms
        import matlab
    HAS_MCR = True
except ImportError as ex:
    HAS_MCR = False
    print(ex)

mcr_only = unittest.skipUnless(HAS_MCR, "requires MCR")

@mcr_only
class TestEngine(unittest.TestCase):
    def test_initializes_engine(self):
        mh.engine()

    def test_engine_supports_divik(self):
        engine = mh.engine()
        self.assertTrue(hasattr(engine, 'divik'))

@mcr_only
class TestIsMatlab(unittest.TestCase):
    def test_passes_matlab_data(self):
        self.assertTrue(mh._is_matlab(matlab.double([1])))

    def test_discards_numpy_data(self):
        self.assertFalse(mh._is_matlab(np.array([1])))

class TestDivikDefaults(unittest.TestCase):
    def test_returns_proper_type(self):
        defaults = mh.divik_defaults()
        self.assertIsInstance(defaults, mh.DivikOptions)

class TestUnroll(unittest.TestCase):
    def test_flattens_named_tuple_into_name_value_format(self):
        SomeTuple = NamedTuple('SomeTuple', [
            ('blah', int),
            ('wololo', str),
        ])
        a_tuple = SomeTuple(blah=1, wololo='2')
        flat = mh._unroll(a_tuple)
        self.assertEqual(flat.index('blah') + 1, flat.index(1))
        self.assertEqual(flat.index('wololo') + 1, flat.index('2'))

    def test_simplifies_enums_into_values(self):
        class Dummy(Enum):
            Blah = 'blah_value'
        SomeTuple = NamedTuple('SomeTuple', [('blah', Dummy)])
        simplified = mh._unroll(SomeTuple(Dummy.Blah))
        self.assertEqual('blah', simplified[0])
        self.assertEqual('blah_value', simplified[1])

@mcr_only
class TestDivik(unittest.TestCase):
    def setUp(self):
        self.engine = mh.engine()
        self.options = mh.divik_defaults()
        self.observations = 1000
        self.dimensions = 100
        np.random.seed(0)
        self.data = np.vstack([
            np.random.randn(400, self.dimensions),
            100 + 3 * np.random.randn(400, self.dimensions),
            -300 + 2 * np.random.randn(200, self.dimensions),
        ])

    def test_segments_data(self):
        result = mh.divik(self.options, self.engine, self.data)
        self.assertEqual(len(result.partition), self.observations)
        self.assertEqual(len(result.merged), self.observations)
        self.assertEqual(result.centroids.shape[1], self.dimensions)
        self.assertEqual(result.centroids.shape[0], len(result.subregions))