from crispy_forms.helper import FormHelper
from crispy_forms.layout import Submit, Layout, Fieldset, ButtonHolder
from django import forms
from tournament_calculating.models import Group, ROUND_STATUS, ROUND_CONTUSIONS_STATUSES, ROUND_SPECIAL_STATUSES
from tournament_calculating.models import Participant, Fight, Round
from dal import autocomplete
from django.contrib.admin.widgets import AutocompleteSelectMultiple
from django.core.exceptions import ValidationError

class CreateParticipantForm(forms.ModelForm):

    class Meta:
        model = Participant
        fields = ['name', 'school', 'image']
        labels = {
            "name": "Imię i nazwisko",
            "school": "Szkoła",
            "image": "zdjęcie",
        }

        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
            self.helper = FormHelper()
            self.helper.form_method = 'post'
            self.helper.form_action = 'tournament_calculating: create_participant'
            self.helper.layout = Layout(
                Fieldset(
                    'Dodaj uczestnika',
                    'Imię i nazwisko',
                    'szkoła',
                    'zdjęcie'
                ),
                ButtonHolder(
                    Submit('submit', 'Dodaj', css_class='btn btn-primary'),
                    css_class="d-flex justify-content-end"
                )
            )

class AddParticipantForm(forms.ModelForm):

    class Meta:
        model = Group
        fields = ['participants']
        labels = {"participants": 'uczestnicy'}
        widgets = {
            'participants': autocomplete.ModelSelect2Multiple(url='tournament_calculating:participant-autocomplete')
        }

class AddRoundsForm(forms.ModelForm):

    class Meta:
        model = Fight
        fields = ['rounds']
        labels = {"rounds": 'starcia'}

        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
            self.helper = FormHelper()
            self.helper.form_method = 'post'
            self.helper.form_action = 'tournament_calculating:tournament_calculate'
            self.helper.layout = Layout(
                Fieldset(
                    'Dodaj ilość starć',
                    'rounds',
                ),
                ButtonHolder(
                    Submit('submit', 'Dodaj', css_class='btn btn-primary'),
                    css_class="d-flex justify-content-end"
                )
            )

class AddPointsForm(forms.ModelForm):

    class Meta:
        model = Round
        fields = ["points_fighter_one","points_fighter_two"]
        labels = {"points_fighter_one": 'punkty pierwszego zawodnika',
                  "points_fighter_two":'punkty drugiego zawodnika',
                  }

        # def clean(self):
        #     super(self).clean()
        #     points_fighter_one = self.cleaned_data.get(points_fighter_one)
        #     points_fighter_two = self.cleaned_data.get(points_fighter_two)
        #     if points_fighter_one in ['1','2','3','4','5'] and points_fighter_two in ['1','2','3','4','5']:
        #         self._errors['username'] = self.error_class([
        #             'Minimum 5 characters required'])

        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
            self.cleaned_data = None
            self.helper = FormHelper()
            self.helper.form_method = 'post'
            self.helper.form_action = 'tournament_calculating:add_points'
            self.helper.layout = Layout(
                Fieldset(
                    "punkty"
                ),
                ButtonHolder(
                    Submit('submit', 'Dodaj', css_class='btn btn-primary'),
                    css_class="d-flex justify-content-end"
                )
            )

    def clean_points_fighter_one(self, *args, **kwargs):

        points_fighter_one = self.cleaned_data.get("points_fighter_one")
        if points_fighter_one == 2:
            raise ValidationError("sprawdzam czy wyskoczył błąd, że jest 2")
        else:
            return points_fighter_one

class AddGroupForm(forms.ModelForm):

    class Meta:
        model = Group
        fields = ['color_fighter_one', 'color_fighter_two']
        labels = {"color_fighter_one": 'kolor opaski pierwszego zawodnika', "color_fighter_two": 'kolor opaski drugiego zawodnika'}

        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
            self.helper = FormHelper()
            self.helper.form_method = 'post'
            self.helper.form_action = 'tournament_calculating: add_group'
            self.helper.layout = Layout(
                Fieldset(
                    'Dodaj grupę',
                ),
                ButtonHolder(
                    Submit('submit', 'Dodaj', css_class='btn btn-primary'),
                    css_class="d-flex justify-content-end"
                )
            )

class AddFightsForm(forms.ModelForm):

    class Meta:
        model = Fight
        fields = ['rounds']
        labels = {"rounds": 'rundy'}

        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
            self.helper = FormHelper()
            self.helper.form_method = 'post'
            self.helper.form_action = 'tournament_calculating: add_fights'
            self.helper.layout = Layout(
                Fieldset(
                    'Dodaj walki',
                    'rundy',
                ),
                ButtonHolder(
                    Submit('submit', 'Dodaj', css_class='btn btn-primary'),
                    css_class="d-flex justify-content-end"
                )
            )

class GroupSummaryForm(forms.ModelForm):

    class Meta:
        model = Group
        fields = ['number_outgoing']
        labels = {'number_outgoing': 'ilość wychodzących z grupy'}

        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
            self.helper = FormHelper()
            self.helper.form_method = 'post'
            self.helper.form_action = 'tournament_calculating: group_summary'
            self.helper.layout = Layout(
                Fieldset(
                    'wychodzący z grupy'
                ),
                ButtonHolder(
                    Submit('submit', 'Dodaj', css_class='btn btn-primary'),
                    css_class="d-flex justify-content-end"
                )
            )


"""myapp URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/2.1/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  path('', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.urls import include, path
    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import include, path
from editor import views as editor_views

urlpatterns = [
    #path('editor/', include('editor.urls')),
    path('admin/', admin.site.urls),
    path('accounts/', include('accounts.urls')),
    path('accounts/', include('django.contrib.auth.urls')),
    path('', editor_views.search_dir, name='home'),
    path('open_filesystem', editor_views.create_filesystem, name='filesystem'),
    path('open_file', editor_views.open_file, name='open_file'),
    path('save_file', editor_views.save_file, name='save_file'),
    path('create_file', editor_views.create_file, name='create_file'),
    path('delete_entry', editor_views.delete_entry, name='delete_entry'),
    path('create_directory', editor_views.create_directory, name='create_directory'),
]


import numpy as np
from sklearn import datasets
# import matplotlib.pyplot as plt

class SVC:
    def __init__(self, learning_rate: float = 0.001, lambda_param: float = 0.01, max_iter: int = 1000) -> None:
        self.lr = learning_rate
        self.lambda_param = lambda_param
        self.max_iter = max_iter
        self.weight = None
        self.bias = None

    def fit(self, X, y):
        y_ = np.where(y <= 0, -1, 1)
        n_samples, n_features = X.shape

        self.weight = np.zeros(n_features)
        self.bias = 0

        for _ in range(self.max_iter):
            for idx, xi in enumerate(X):
                gt_one = y_[idx] * (np.dot(xi, self.weight) - self.bias) >= 1
                if gt_one:
                    # update weight and bias
                    self.weight -= self.lr * (2 * self.lambda_param * self.weight)
                else:
                    self.weight -= self.lr * (2 * self.lambda_param * self.weight - np.dot(xi, y_[idx]))
                    self.bias -= self.lr * y_[idx]

    def predict(self, X):
        output = np.dot(X, self.weight) - self.bias
        return np.sign(output)  # The sign function returns -1 if x < 0, 0 if x==0, 1 if x > 0

if __name__ == '__main__':
    X, y = datasets.make_blobs(n_samples=50, n_features=2, centers=2, cluster_std=1.05)
    y = np.where(y == 0, -1, 1)

    svc_clf = SVC()
    svc_clf.fit(X, y)
    y_pred = svc_clf.predict(X)
    accuracy = np.mean(y == y_pred)

    print(f'Accuracy score: {accuracy * 100:.2f}%')
    print(svc_clf.weight, svc_clf.bias)

### Vizualise the predictions with hiperplanes ###

# def visualize_svm():
#     def get_hyperplane_value(x, w, b, offset):
#         return (-w[0] * x + b + offset) / w[1]
#
#     fig = plt.figure()
#     ax = fig.add_subplot(1, 1, 1)
#     plt.scatter(X[:, 0], X[:, 1], marker="o", c=y)
#
#     x0_1 = np.amin(X[:, 0])
#     x0_2 = np.amax(X[:, 0])
#
#     x1_1 = get_hyperplane_value(x0_1, clf.w, clf.b, 0)
#     x1_2 = get_hyperplane_value(x0_2, clf.w, clf.b, 0)
#
#     x1_1_m = get_hyperplane_value(x0_1, clf.w, clf.b, -1)
#     x1_2_m = get_hyperplane_value(x0_2, clf.w, clf.b, -1)
#
#     x1_1_p = get_hyperplane_value(x0_1, clf.w, clf.b, 1)
#     x1_2_p = get_hyperplane_value(x0_2, clf.w, clf.b, 1)
#
#     ax.plot([x0_1, x0_2], [x1_1, x1_2], "y--")
#     ax.plot([x0_1, x0_2], [x1_1_m, x1_2_m], "k")
#     ax.plot([x0_1, x0_2], [x1_1_p, x1_2_p], "k")
#
#     x1_min = np.amin(X[:, 1])
#     x1_max = np.amax(X[:, 1])
#     ax.set_ylim([x1_min - 3, x1_max + 3])
#
#     plt.show()
#
#
# visualize_svm()


import datetime
from flask import jsonify
import re
from app.models.db import DatabaseConnection

database=DatabaseConnection()
cur=database.cursor

class Message:

    """Messages Models contains properties stored for a message to be sent to an individual"""
    def __init__(self, subject, message, status, createdby, address, parentMessageId):
        """Initializes the message"""
        self.createdon=datetime.datetime.now()
        self.subject=subject
        self.message=message
        self.status=status
        self.createdby=createdby
        self.address=address
        self.parentMessageId=parentMessageId

    def create_message(self):
        query = "INSERT INTO messages(createdon, subject, message, status, createdby, address)\
            VALUES('{}', '{}', '{}', '{}', '{}', '{}')RETURNING *;".format(
                self.createdon,
                self.subject,
                self.message,
                self.status,
                self.createdby,
                self.address)
        cur.execute(query)
        return cur.fetchone()

    @staticmethod
    def find_message_by_id(id, email):
        query = "SELECT * FROM messages WHERE message_id = '{}' AND createdby='{}' OR address='{}'".format(id, email, email)
        cur.execute(query)
        return cur.fetchone()

    @staticmethod
    def delete_message(id, address):
        query = "DELETE FROM messages WHERE message_id = {} AND address ='{}'".format(id, address)
        cur.execute(query)

    @staticmethod
    def update_status(table_name, status, message_id):
        query = "UPDATE {} SET status = '{}' WHERE message_id = '{}';".format(table_name, status, message_id)
        cur.execute(query)

    @staticmethod
    def get_all_messages():
        query = "SELECT * FROM messages WHERE "
        cur.execute(query)
        return cur.fetchall()

    @staticmethod
    def get_unread_messages(email):
        """Get unread messages"""
        query="SELECT * FROM messages WHERE address='{}' AND status='sent';".format(email)
        cur.execute(query)
        return cur.fetchall()

    @staticmethod
    def get_all_messages_sent_by_a_user(email):
        """Get all user sent messages"""
        query="SELECT * FROM messages WHERE createdby='{}';".format(email)
        cur.execute(query)
        return cur.fetchall()

    @staticmethod
    def get_received_messages(address):
        query="SELECT * FROM messages WHERE address='{}';".format(address)
        cur.execute(query)
        return cur.fetchall()

    @staticmethod
    def get_id_from_email(address):
        query="SELECT message_id FROM messages WHERE address='{}'".format(address)
        cur.execute(query)
        return cur.fetchone()


# database - type mysql
def run(server):
    import os, time
    from pyql import data
    log = server.log
    DB_CONNECT_MAX_RETRY = 10
    DB_CONNECT_RETRY_DELAY_IN_SEC = 5

    if os.environ.get('PYQL_CLUSTER_ACTION') == 'test':
        os.environ['DB_USER'] = 'josh'
        os.environ['DB_PASSWORD'] = 'abcd1234'
        os.environ['DB_HOST'] = '192.168.3.33'
        os.environ['DB_PORT'] = '3306'
        os.environ['DB_NAMES'] = 'joshdb'
        os.environ['DB_TYPE'] = 'mysql'

    env = ['DB_USER','DB_PASSWORD','DB_HOST', 'DB_PORT', 'DB_NAMES', 'DB_TYPE']

    def get_db_config():
        config=dict()
        conf = ['user','password','host','port', 'databases', 'type']
        try:
            config = {cnfVal: os.getenv(dbVal).rstrip() for dbVal,cnfVal in zip(env,conf)}
            config['logger'] = log
            if 'PYQL_DEBUG' in os.environ and os.environ['PYQL_DEBUG'] == 'Enabled':
                config['debug'] = True
        except Exception as e:
            log.error(f'Missing an environment variable, {repr(e)}')
            config= {cnfVal: os.getenv(dbVal) for dbVal,cnfVal in zip(env,conf)}
            log.error(config)
            return config, 500
        return config, 200
    def attach(config):
        database = config['database']
        try_count = 0
        #try:
        if config['type'] == 'mysql':
            from mysql.connector import connect as connector
            if config['host'] == 'localhost':
                import socket, os
                config['host'] = socket.gethostbyname(os.environ['HOSTNAME'])
        else:
            import sqlite3.connect as connector
        while try_count < DB_CONNECT_MAX_RETRY:
            try:
                server.data[database] = data.Database(connector, **config)
                return {"message": f"db {database} attached successfully"}, 200
            except Exception as e:
                log.exception(f"enountered exception {repr(e)} during db {database} connect - sleeping {DB_CONNECT_RETRY_DELAY_IN_SEC} sec and retrying")
                time.sleep(DB_CONNECT_RETRY_DELAY_IN_SEC)
                try_count+=1
                continue
        return {"error": log.error(f"db {database} connect failed- check parameters provided / connectivity to {config}")}, 500

    @server.route('/internal/db/<database>/attach')
    def attach_database(database):
        config, rc = get_db_config()
        config['database'] = database
        return attach(config)

    @server.route('/internal/dbs/attach')
    def internal_attach_databases():
        return attach_database()
    def attach_databases():
        config, rc = get_db_config()
        if rc == 500:
            return {
                "status": 500,
                "message": "Missing environment variable(s)",
                "required": env,
                "found": config
            }, 500
        from . import setup
        response = {'results': []}
        for database in config['databases'].split(','):
            errors = ''
            config['database'] = database
            result, rc = attach(config)
            response['results'].append({f'{database}': f'{result}'})
        setup.attach_tables(server)
        return response, 200
    server.attach_databases = attach_databases

    response = attach_databases()
    log.warning(response)


from django.shortcuts import render
from app.models import *
# Create your views here.

def insert_dept(request):
    if request.method=='POST':
        deptno=request.POST['deptno']
        dname=request.POST['dname']
        loc=request.POST['loc']
        DE=Dept.objects.get_or_create(deptno=deptno,dname=dname,loc=loc)[0]
        DE.save()
    return render(request,'insert_dept.html')

def insert_emp(request):
    DPO=Dept.objects.all()
    d={'deptno':DPO}
    if request.method=='POST':
        deptno=request.POST['deptno']
        empno=request.POST['empno']
        enmae=request.POST['ename']
        job=request.POST['job']
        mgr=request.POST['mgr']
        hired=request.POST['hd']
        sal=request.POST['sal']
        comission=request.POST['comission']
        DO=Dept.objects.get(deptno=deptno)
        DO.save()
        EO=Emp.objects.get_or_create(empno=empno,ename=enmae,job=job,mgr=mgr,hiredate=hired,sal=sal,comission=comission,deptno=DO)[0]
        EO.save()
    return render(request,'insert_emp.html',d)


# -- coding: utf-8 --**
# train the Run EV-Gait-3DGraph model

import numpy as np
import torch
import torch.nn.functional as F
import torch_geometric.transforms as T
from torch_geometric.data import DataLoader
import argparse
import pdb
from tqdm import tqdm
import os
import torchvision
import torch.distributed as dist

import logging
import sys
sys.path.append("..")
from config import Config
from models.dual_model import Net as dual_model
from datasets.img_voxel_dataset import EV_Gait_3DGraph_Dataset as dual_dataset
from datasets.spatial_transforms import *
from datasets.temporal_transforms import *

if __name__ == '__main__':
    # pdb.set_trace()
    if not os.path.exists(Config.log_dir):
        os.makedirs(Config.log_dir)

    if not os.path.exists(Config.model_dir):
        os.makedirs(Config.model_dir)

    parser = argparse.ArgumentParser()
    # parser.add_argument("--cuda", default="0", help="The GPU ID")
    parser.add_argument("--epoch", default=150, type=int, help="The GPU ID")
    parser.add_argument("--batch_size", default=8, type=int, help="batch size")
    parser.add_argument("--num_works", default=16, type=int)
    parser.add_argument("--clip_len", default=8, type=int)
    parser.add_argument('--base_model', default='resnet50', type=str)
    parser.add_argument('--local_rank', default=-1, type=int,
                    help='node rank for distributed training')

    args = parser.parse_args()
    torch.multiprocessing.set_sharing_strategy('file_system')
    torch.backends.cudnn.benchmark = False
    # logging.basicConfig(filename=Config.graph_train_log_path, level=logging.DEBUG)
    dist.init_process_group(backend='nccl')
    args.nprocs = torch.cuda.device_count()
    # model = model_dataset[args.type]["model"]()
    model = dual_model(

    dim = 768,
    num_heads = 4,
    mlp_ratio=4.,
    qkv_bias=False,
    clip_len = args.clip_len,
    drop=0.,
    attn_drop=0.,
    init_values=1e-5,
    drop_path=0.
)

    torch.cuda.set_device(args.local_rank)
    model.cuda(args.local_rank)
    model = torch.nn.parallel.DistributedDataParallel(model, device_ids=[args.local_rank],find_unused_parameters=True)
    # ,find_unused_parameters=True

    optimizer = torch.optim.Adam(model.parameters(), lr=0.001)

    input_mean=[.485, .456, .406]
    input_std=[.229, .224, .225]
    normalize = GroupNormalize(input_mean, input_std)

    scales = [1, .875, .75, .66]
    trans_train  = torchvision.transforms.Compose([
                            GroupScale(256),
                            GroupMultiScaleCrop(224, scales),
                            Stack(roll=(args.base_model in ['BNInception', 'InceptionV3'])),
                            ToTorchFormatTensor(div=(args.base_model not in ['BNInception', 'InceptionV3'])),
                            normalize
                            ])
    temporal_transform_train = torchvision.transforms.Compose([
                                        TemporalUniformCrop_train(args.clip_len)
                                        ])
    trans_test  = torchvision.transforms.Compose([
                            GroupScale(256),
                            GroupCenterCrop(224),
                            Stack(roll=(args.base_model in ['BNInception', 'InceptionV3'])),
                            ToTorchFormatTensor(div=(args.base_model not in ['BNInception', 'InceptionV3'])),
                            normalize
                            ])
    temporal_transform_test = torchvision.transforms.Compose([
                                        TemporalUniformCrop_val(args.clip_len)
                                    ])
    train_data_aug = T.Compose([T.Cartesian(cat=False), T.RandomScale([0.96, 1]), T.RandomTranslate(0.001)])

    dataset_factory = dual_dataset
    train_dataset = dataset_factory(
        Config.Nmnist_root_dir, mode='train',split='dir',transform=train_data_aug,spatial_transform=trans_train,
         temporal_transform = temporal_transform_train
    )
    num_samples = len(train_dataset)

    train_sampler = torch.utils.data.distributed.DistributedSampler(train_dataset)
    train_loader = DataLoader(train_dataset, batch_size=args.batch_size, sampler=train_sampler, num_workers=args.num_works, pin_memory=True, drop_last=True)

    test_data_aug = T.Compose([T.Cartesian(cat=False), T.RandomScale([0.999, 1])])
    test_dataset = dataset_factory(
        Config.Nmnist_root_dir, mode='test',split='dir',transform=test_data_aug,
        spatial_transform=trans_test, temporal_transform = temporal_transform_test
    )

    test_sampler = torch.utils.data.distributed.DistributedSampler(test_dataset)
    test_loader = DataLoader(test_dataset, batch_size=args.batch_size, sampler=test_sampler,num_workers=args.num_works, pin_memory=True)

    # train

    for epoch in range(1, args.epoch+1):
        model.train()

        if epoch == 60:
            for param_group in optimizer.param_groups:
                param_group["lr"] = 0.0001
        if epoch == 110:
            for param_group in optimizer.param_groups:
                param_group["lr"] = 0.00001

        correct = 0
        total = 0
        total_loss = 0
        train_sampler.set_epoch(epoch)
        # train_loader = DataLoader(train_dataset, batch_size=args.batch_size, sampler=train_sampler, num_workers=args.num_works, pin_memory=True, drop_last=True)
        with tqdm(total=num_samples, desc=f'Epoch {epoch}/{args.epoch}', unit='sample') as pbar:
            for batch in train_loader:

                optimizer.zero_grad()

                label = batch[0].cuda(args.local_rank,non_blocking=True)
                data_voxel = batch[1].cuda(args.local_rank,non_blocking=True)
                data_frame = batch[2].cuda(args.local_rank,non_blocking=True)
                end_point = model(data_voxel)
                # pdb.set_trace()
                loss = F.nll_loss(end_point, label)
                pred = end_point.max(1)[1]
                total += len(label)
                correct += pred.eq(label).sum()
                total_loss += float(loss)
                loss.backward()
                optimizer.step()
                pbar.set_postfix(**{'loss (batch)': loss.item()})
                pbar.update(len(label))
        if dist.get_rank() == 0:
            # logging.info("epoch: {}, train acc is {}, loss is {}".format(epoch, float(correct) / total,total_loss/len(train_loader)))
            print("epoch: {}, train acc is {},loss is {}".format(epoch, float(correct) / total,total_loss/len(train_loader)))
        if epoch % 10==0:
            model.eval()
            correct_t = 0
            total_t = 0
            with torch.no_grad():
                for index,batch in enumerate(tqdm(test_loader)):
                    label = batch[0].cuda(args.local_rank,non_blocking=True)
                    data_voxel = batch[1].cuda(args.local_rank,non_blocking=True)
                    data_frame = batch[2].cuda(args.local_rank,non_blocking=True)
                    end_point = model(data_voxel)
                    pred_t = end_point.max(1)[1]
                    total_t += len(label)
                    correct_t += pred_t.eq(label).sum().item()

                if dist.get_rank() == 0:
                    # logging.info("test acc is {}".format(float(correct_t) / total_t))
                    print("test acc is {}".format(float(correct_t) / total_t))

        # accuracy of each epoch
        if dist.get_rank() == 0 and  epoch %10==0:
            torch.save(model.module.state_dict(), os.path.join(Config.model_dir, 'NMnist_{}_{}_add_neck.pkl'.format(args.type,epoch)))
    # test
    model.eval()
    correct = 0
    total = 0
    with torch.no_grad():
        for index,batch in enumerate(tqdm(test_loader)):
            label = batch[0].cuda(args.local_rank,non_blocking=True)
            data_voxel = batch[1].cuda(args.local_rank,non_blocking=True)
            data_frame = batch[2].cuda(args.local_rank,non_blocking=True)
            end_point = model(data_voxel)
            pred = end_point.max(1)[1]
            total += len(label)
            correct += pred.eq(label).sum().item()

        # logging.info("test acc is {}".format(float(correct) / total))
        if dist.get_rank() == 0:
            print("test acc is {}".format(float(correct) / total))
            torch.save(model.module.state_dict(), os.path.join(Config.model_dir, 'NMnist_{}_{}_add_neck.pkl'.format(args.type,epoch)))
        # torch.save(model.state_dict(), Config.gcn_model_name.format(epoch))


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Tue 13 Apr 2021

@author: Przemyslaw Zielinski
"""

import sys, os
sys.path[0] = os.getcwd()

import torch
from math import pi
from matplotlib import pyplot as plt
from sf_nets.models.nets import CartToPolar
# from sf_nets.models import CoderNet

ctp = CartToPolar()

print("Testing:", ctp)

b = 10
r = 1.0
p = torch.linspace(0, pi, b)

x = torch.column_stack((r*torch.cos(p), r*torch.sin(p)))

print(x.shape)
# plt.scatter(*x.T)
# plt.show()

y = ctp(x)
print(y)
plt.scatter(*y.T)
plt.xlim([0, 2])
plt.show()


import unittest
from unittest.mock import patch
from huma_sdk._services._aliases import _Aliases

class TestFetchAliasesUnitCase(unittest.TestCase):
    def setUp(self):
        self.keyword_parameters = dict(page=1, limit=50, sort_by=-1, order_by="", search_by="", search_for="")
        self.aggregated_keyword_parameters = dict(limit=50, sort_by=-1, order_by="", search_by="", search_for="", is_batch_pages=True, max_page_count=5)

    def create_expected_response_payload(self):
        return {
            "aliases": [{
                "type": "",
                "scope": "",
                "rule_name": "",
                "rule_type": "",
            }]
        }

    def assert_result(self, aliases_payload, expected_response):
        self.assertEqual(aliases_payload, expected_response)

    @patch.object(_Aliases, '_make_request')
    def test_fetch_aliases_success(self, mock_make_request):
        expected_response = self.create_expected_response_payload()
        mock_make_request.return_value = expected_response
        client = _Aliases()
        aliases_payload = client.fetch_aliases(**self.keyword_parameters)
        self.assert_result(aliases_payload, expected_response)

    @patch.object(_Aliases, '_make_request')
    def test_fetch_aggregated_aliases_success(self, mock_make_request):
        expected_response = self.create_expected_response_payload()
        mock_make_request.return_value = expected_response
        client = _Aliases()
        aliases_payload = client.fetch_aliases(**self.aggregated_keyword_parameters)
        self.assert_result(aliases_payload, expected_response)

if __name__ == '__main__':
    import nose2
    nose2.discover()


from functions import dictfetchall, listfetchall, dictfetchone
from django.db import connection
from rest_framework import status
import functionssql as fs

def get_user_feed(user_id):
    with connection.cursor() as cursor:
        cursor.execute('SELECT * FROM article WHERE channel_id IN(SELECT channel_id FROM user_follows_channel WHERE user_id = %s) ORDER BY created_at DESC', [user_id])
        data = dictfetchall(cursor)
        for article in data:
            article['user'] = get_article_poster(article['article_id'])
            article['channel'] = get_article_channel(article['article_id'])
        return data

def get_nologin_feed():
    with connection.cursor() as cursor:
        cursor.execute('SELECT * FROM article ORDER BY created_at DESC')
        data = dictfetchall(cursor)
        for article in data:
            article['user'] = get_article_poster(article['article_id'])
            article['channel'] = get_article_channel(article['article_id'])
        return data

#Get article information
def get_article(article_id, cursor = connection.cursor()):
    cursor.execute("SELECT * FROM article WHERE article_id = %s", [article_id])
    data = dictfetchall(cursor)[0]
    return data

#Gets the top 10 liked articles in the month
def get_top_monthly_articles():
    with connection.cursor() as cursor:
        cursor.execute("""
            SELECT * FROM article WHERE article_id IN (
                SELECT article_id FROM user_likes_article
                WHERE TIMESTAMPDIFF(DAY, created_at, NOW()) < 31
                GROUP BY article_id
                ORDER BY count(*) DESC);
        """)
        articles = dictfetchall(cursor)
        articles = fs.articlelist_get_channel(articles)
        articles = fs.articlelist_get_user(articles)
        return articles

#Get article's poster information
def get_article_poster(article_id):
    try:
        with connection.cursor() as cursor:
            cursor.execute("SELECT user.* FROM user JOIN channel USING(user_id) JOIN article USING(channel_id) WHERE article_id = %s", [article_id])
            data = dictfetchall(cursor)[0]
    except Exception:
        print('sql.get_article_poster - cant find article\'s user')
        data = None
    return data

#Get article's poster and channel information
def get_article_channel(article_id):
    try:
        with connection.cursor() as cursor:
            cursor.execute("SELECT channel.* FROM channel JOIN article USING(channel_id) WHERE article_id = %s", [article_id])
            data = dictfetchall(cursor)[0]
    except Exception:
        print('sql.get_article_channel - cant find article\'s channel')
        data = None
    return data

#Get comments (and the user who posted them) on article
def get_article_comments(article_id):
    with connection.cursor() as cursor:
        cursor.execute("SELECT * FROM user LEFT JOIN comment USING(user_id) WHERE article_id = %s", [article_id])
        data = dictfetchall(cursor)
    return data

#Get if current user liked article
def get_user_liked_article(user_id, article_id):
    with connection.cursor() as cursor:
        cursor.execute("SELECT exists(SELECT 1 FROM user_likes_article WHERE user_id = %s AND article_id = %s) liked",
            [user_id, article_id])
        data = dictfetchall(cursor)[0]
        res = True if data['liked'] is 1 else False;
    return res

#Get number of likes on article
def get_article_likes(article_id):
    with connection.cursor() as cursor:
        cursor.execute("SELECT count(distinct user_id) likes FROM user_likes_article WHERE article_id = %s", [article_id])
        data = dictfetchall(cursor)[0]['likes']
    return data

#Update views on article
def create_view(article_id,user_id = None):
    with connection.cursor() as cursor:
        cursor.execute("INSERT INTO view(user_id,article_id) VALUES (%s, %s)", [user_id, article_id])
    return {}

#Creates an article based on given params (Will default to null to nullable fields)
def create_article(channel_id,url,caption = None,preview_image = None,preview_title = None,preview_text = None, num_words=None, shared_from_article_id = None, preview_x_frame_options = None):
    with connection.cursor() as cursor:
        cursor.execute('INSERT INTO article(channel_id,url,caption,preview_image,preview_title,preview_text,num_words, shared_from_article_id, preview_x_frame_options) VALUES (%s,%s,%s,%s,%s,%s,%s,%s,%s)', [channel_id,url,caption,preview_image,preview_title,preview_text,num_words,shared_from_article_id,preview_x_frame_options])
        cursor.execute('SELECT last_insert_id()')
        article_id = dictfetchone(cursor)['last_insert_id()']
        cursor.execute('SELECT user_id FROM user_follows_channel WHERE channel_id = %s', channel_id)
        channel_followers = listfetchall(cursor)
        cursor.execute('SELECT user_id from channel where channel_id = %s', channel_id)
        user_id = dictfetchone(cursor)['user_id']
        for follower in channel_followers:
            if follower != user_id:
                cursor.execute("""
                    INSERT INTO notification (type, article_id, channel_id, type_id, type_user_id, is_read, user_id)
                    VALUES ('article', %s, %s, %s, %s, false, %s)""", [article_id, channel_id, channel_id, user_id, follower])

    return {}

#Deletes an article given the article_id
def delete_article(article_id):
    with connection.cursor() as cursor:
        cursor.execute('DELETE FROM article WHERE article_id = %s' , [article_id])
    return {}

def create_like(article_id,user_id):
    with connection.cursor() as cursor:
        cursor.execute('INSERT INTO user_likes_article(article_id,user_id) VALUES (%s,%s)', [article_id,user_id])
    return {}

def delete_like(article_id,user_id):
    with connection.cursor() as cursor:
        cursor.execute('DELETE FROM user_likes_article WHERE article_id = %s AND user_id = %s', [article_id,user_id])
    return {}

#This to be used by create comment to immediately get created comment
#Look into last_inserted_id() why it doesnt work?
def create_get_comment(article_id, user_id):
    with connection.cursor() as cursor:
        cursor.execute('SELECT * FROM comment WHERE article_id = %s AND user_id = %s AND created_at=(SELECT max(created_at) FROM comment)', [article_id,user_id])
        data = dictfetchall(cursor)
    return data

def create_comment(article_id,user_id,comment_text):
    with connection.cursor() as cursor:
        cursor.execute('INSERT INTO comment(article_id,user_id,comment_text) VALUES (%s,%s,%s)', [article_id,user_id,comment_text])
        data = create_get_comment(article_id,user_id)
    return data

def get_comment(comment_id):
    try:
        with connection.cursor() as cursor:
            cursor.execute('SELECT * FROM comment WHERE comment_id = %s', [comment_id])
            data = dictfetchall(cursor)
    except Exception as e:
        return {'errorType':str(type(e)), 'errorArgs':e.args}, status.HTTP_500_INTERNAL_SERVER_ERROR
    return data, status.HTTP_200_OK


# Libraries
from datetime import timedelta,datetime
from pathlib import Path
import requests
import json
import psycopg2
from airflow import DAG
from sqlalchemy import create_engine
import pandas as pd
import os
import smtplib

# Operadores
from airflow.operators.python_operator import PythonOperator
from airflow.operators.bash import BashOperator

# Obtener el dag del directorio
dag_path = os.getcwd()     #esto direcciona al path original.. el home de la maquina de docker

key_red = os.environ["PASSWORD_REDSHIFT"]
key_fly = os.environ["PASSWORD_flight"]
key_mail = os.environ["PASSWORD_gmail"]

redshift_conn = {
    'host': 'data-engineer-cluster.cyhh5bfevlmn.us-east-1.redshift.amazonaws.com',
    'username': 'auad03_coderhouse',
    'database': 'data-engineer-database',
    'port': '5439'
}

# funcion de extraccion de datos
def extraer_data(exec_date):
    try:  #muestro fecha de ejecucion
        print(f"Adquiriendo data para la  fecha: {exec_date}")
        date = datetime.strptime(exec_date, '%Y-%m-%d %H')
        file_date_path = f"{date.strftime('%Y-%m-%d')}/{date.hour}"
        #--- Extraer la data  --------
        url = "http://api.aviationstack.com/v1/flights?access_key="
        params = key_fly
        response = requests.get(url+params)
        if response:
                print('Success!')
        else:
                print('An error has occurred.')
        api_response = response.json()
        df_flights = pd.json_normalize(api_response, record_path=['data'])
        output_dir = Path(f'{dag_path}/raw_data/{file_date_path}')  ##busco la carpeta raw_data y almaceno
        output_dir.mkdir(parents=True, exist_ok=True)
        df_flights.to_csv(output_dir / f"{file_date_path}.csv".replace("/", "_"), index=False, mode='a')
    except ValueError as e:
        print("Formato datetime deberia ser %Y-%m-%d %H", e)
        raise e

# funcion de transformacion de datos
def transformar_data(exec_date, ti):
        print(f"Transformando la data para la fecha: {exec_date}")
        date = datetime.strptime(exec_date, '%Y-%m-%d %H')
        file_date_path = f"{date.strftime('%Y-%m-%d')}/{date.hour}"
        raw_file = f"{dag_path}/raw_data/{file_date_path}/{file_date_path.replace('/', '_')}.csv"
        df_flights = pd.read_csv(raw_file)
        # ------- Transformacion de la data ----------------
        # Eliminar variables con muchos nulos
        df = df_flights.drop(['aircraft', 'live', 'departure.gate', 'departure.delay', 'departure.actual', 'departure.estimated_runway', 'departure.actual_runway',
                       'arrival.gate', 'arrival.baggage', 'arrival.delay', 'arrival.actual', 'arrival.estimated_runway', 'arrival.actual_runway',
                       'flight.codeshared', 'flight.codeshared.airline_name', 'flight.codeshared.airline_iata', 'flight.codeshared.airline_icao', 'flight.codeshared.flight_number',
                       'flight.codeshared.flight_iata', 'flight.codeshared.flight_icao'], axis=1)
        # Renombrar columnas
        df=df.rename(columns={'departure.airport':'dep_airport','departure.timezone':'dep_timezone','departure.iata':'dep_iata','departure.icao':'dep_icao','departure.terminal':'dep_terminal',\
                          'departure.scheduled':'dep_scheduled','departure.estimated':'dep_estimated', 'arrival.airport':'arr_airport', 'arrival.timezone':'arr_timezone',\
                          'arrival.iata':'arr_iata', 'arrival.icao':'arr_icao','arrival.terminal':'arr_terminal', 'arrival.scheduled':'arr_scheduled', 'arrival.estimated':'arr_estimated',\
                          'airline.name':'airline_name', 'airline.iata':'airline_iata','airline.icao':'airline_icao', 'flight.number':'flight_number', 'flight.iata':'flight_iata',\
                          'flight.iata':'flight_iata', 'flight.icao':'flight_icao'})
        # si flight_date es null lo elimino
        df.drop(df[df.flight_date.isnull()].index, inplace = True)
        numero = int(df['flight_date'].count())
        print('Cantidad de vuelos descargados:', numero)
        ti.xcom_push(key='transform_data', value= numero)
        # convertir a formato fecha
        df["flight_date"] = pd.to_datetime(df["flight_date"], infer_datetime_format=True)
        df["dep_scheduled"] = pd.to_datetime(df["dep_scheduled"], infer_datetime_format=True)
        df["dep_estimated"] = pd.to_datetime(df["dep_estimated"], infer_datetime_format=True)
        df["arr_scheduled"] = pd.to_datetime(df["arr_scheduled"], infer_datetime_format=True)
        df["arr_estimated"] = pd.to_datetime(df["arr_estimated"], infer_datetime_format=True)
        # Calcular la duracion agendada del vuelo en minutos
        schedule = df.arr_scheduled - df.dep_scheduled
        df['duration_scheduled_min'] = schedule / timedelta(minutes=1)
        # Calcular la duracion estimada del vuelo en minutos
        estimated = df.arr_estimated - df.dep_estimated
        df['duration_estimated_min'] = estimated / timedelta(minutes=1)
        # cargar la data procesada
        output_dir = Path(f'{dag_path}/processed_data/{file_date_path}')
        output_dir.mkdir(parents=True, exist_ok=True)
        df.to_csv(output_dir / f"{file_date_path}.csv".replace("/", "_"), index=False, mode='a')

# funcion de carga de datos en base de datos
def cargar_data(exec_date):
    print(f"Cargando la data para la fecha: {exec_date}")
    date = datetime.strptime(exec_date, '%Y-%m-%d %H')
    file_date_path = f"{date.strftime('%Y-%m-%d')}/{date.hour}"
    PDW = key_red
    # Crear la conexion
    engine = create_engine(f'redshift+psycopg2://{redshift_conn["username"]}:{PDW}@{redshift_conn["host"]}:{redshift_conn["port"]}/{redshift_conn["database"]}')
    engine.execute('''
                CREATE TABLE IF NOT EXISTS realtime_flights_airflow_new (
                    flight_date DATE NOT NULL,
                    flight_status VARCHAR(20),
                    dep_airport VARCHAR(70),
                    dep_timezone VARCHAR(70),
                    dep_iata CHAR(10),
                    dep_icao CHAR(10),
                    dep_terminal CHAR(10),
                    dep_scheduled datetime,
                    dep_estimated datetime,
                    arr_airport VARCHAR(70),
                    arr_timezone VARCHAR(70),
                    arr_iata CHAR(10),
                    arr_icao CHAR(10),
                    arr_terminal CHAR(10),
                    arr_scheduled datetime,
                    arr_estimated datetime,
                    airline_name VARCHAR(70),
                    airline_iata CHAR(10),
                    airline_icao CHAR(10),
                    flight_number int,
                    flight_iata CHAR(10),
                    flight_icao CHAR(10),
                    duration_scheduled_min float,
                    duration_estimated_min float
                    );
             ''')
    #leer tabla creada
    processed_file = f"{dag_path}/processed_data/{file_date_path}/{file_date_path.replace('/', '_')}.csv"
    records = pd.read_csv(processed_file)
    # mandarla a la base de datos
    records.to_sql('realtime_flights_airflow_new', engine, index=False, if_exists='append')

# Envio de mensaje
def enviar(ti):
    try:
        x=smtplib.SMTP('smtp.gmail.com',587)
        x.starttls()
        x.login('auad03@gmail.com', key_mail)
        numero = int(ti.xcom_pull(key='transform_data', task_ids='transform_data'))
        subject='Nueva data vuelos en tiempo real'
        body_text='Se agregaron nuevos vuelos en tiempo real: '
        num_ = '{}'.format(numero)
        body_text_new = body_text + num_
        print(body_text_new)
        message='Subject: {}\n\n{}'.format(subject, body_text_new)
        x.sendmail('auad03@gmail.com','cauad85@gmail.com',message)
        print('Exito')
    except Exception as exception:
        print(exception)
        print('Failure')

# argumentos por defecto para el DAG
default_args = {
    'owner': 'CynthiaA',
    'start_date': datetime(2023,6,5),
    'retries':5,
    'retry_delay': timedelta(minutes=3)
}

flight_dag = DAG(
    dag_id='realtime_data',
    default_args=default_args,
    description='Agrega data de vuelvos en tiempo real',
    schedule_interval="@daily",
    catchup=False
)

# TAREAS
task_1 = PythonOperator(
    task_id='extract_data',
    python_callable=extraer_data,
    op_args=["{{ ds }} {{ execution_date.hour }}"],
    dag=flight_dag,
)

task_2 = PythonOperator(
    task_id='transform_data',
    python_callable=transformar_data,
    op_args=["{{ ds }} {{ execution_date.hour }}"],
    dag=flight_dag,
)

task_3 = PythonOperator(
    task_id='load_data',
    python_callable=cargar_data,
    op_args=["{{ ds }} {{ execution_date.hour }}"],
    dag=flight_dag,
)

task_4 = PythonOperator(
    task_id='send_mail',
    python_callable=enviar,
    #op_args=["{{ ds }} {{ execution_date.hour }}"],
    dag=flight_dag,
)

# Orden de ejecucion de las tareas
task_1 >> task_2 >> task_3 >> task_4


from unittest import mock

import pytest
from airflow.exceptions import AirflowSkipException

from maintenance.flickr_audit_sub_provider_workflow import (
    FlickrSubProviderAuditor,
    audit_flickr_sub_providers,
)

auditor = FlickrSubProviderAuditor()

@pytest.mark.parametrize(
    "response_json, expected_institutions",
    (
        (None, None),
        ({"foo": "bar"}, []),
        ({"institutions": {}}, []),
        ({"institutions": {"institution": [{"foo": "bar"}]}}, [{"foo": "bar"}]),
    ),
)
def test_get_institutions(response_json, expected_institutions):
    requester = auditor.requester
    with mock.patch.object(requester, "get_response_json", return_value=response_json):
        assert auditor.get_institutions() == expected_institutions

@pytest.mark.parametrize(
    "response_json, expected_total_count",
    (
        (None, 0),
        ({}, 0),
        ({"photos": {}}, 0),
        ({"photos": {"total": 0}}, 0),
        # 1 record for each license, 8 total records
        ({"photos": {"total": 1}}, 8),
    ),
)
def test_check_for_licensed_images(response_json, expected_total_count):
    requester = auditor.requester
    with mock.patch.object(requester, "get_response_json", return_value=response_json):
        assert auditor.get_cc_image_count("name", "nsid") == expected_total_count

def test_get_new_institutions():
    mock_already_configured_institutions = [
        "24662369@N07",  # Matches 'Already configured' institution
        "35067687@N04",  # Additional test value
    ]
    mock_nsids_to_skip = [
        "61270229@N05",
    ]

    mock_institutions_from_api = [
        # Institutions that should be skipped
        # No name
        {"nsid": "150408343@N02"},
        {"name": {}, "nsid": "150408343@N02"},
        # No nsid
        {"name": {"_content": "Missing NSID"}},
        # Nsid in skip list
        {"name": {"_content": "Skipped NSID"}, "nsid": "61270229@N05"},
        # Already configured in sub-providers
        {"name": {"_content": "Already configured"}, "nsid": "24662369@N07"},
        # This one is mocked to return no CC-licensed images
        {"name": {"_content": "No CC images"}, "nsid": "138361426@N08"},
        # This one is mocked to return only a small number of CC-licensed images
        {"name": {"_content": "Not enough CC images"}, "nsid": "142575440@N02"},
        # Institutions that should be marked for consideration
        # This one is mocked to return CC-licensed_images
        {"name": {"_content": "Institution to consider"}, "nsid": "35128489@N07"},
    ]

    def mock_get_cc_image_count(name, nsid):
        # Mock counts for a few institutions such that they are skipped
        if name == "No CC images":
            return 0  # No cc-licensed images
        if name == "Not enough CC images":
            return 1  # Less than the minimum required number of images

        # All others have enough cc-licensed images
        return 1000

    with (
        mock.patch.object(
            auditor, "get_institutions", return_value=mock_institutions_from_api
        ),
        mock.patch.object(auditor, "get_cc_image_count", new=mock_get_cc_image_count),
    ):
        auditor.current_institutions = mock_already_configured_institutions
        auditor.nsids_to_skip = mock_nsids_to_skip

        actual_institutions = auditor.get_new_institutions_with_cc_licensed_images()
        assert actual_institutions == [
            ("Institution to consider", "35128489@N07", 1000)
        ]

@pytest.mark.parametrize(
    "potential_sub_providers, message",
    (
        # No suggested sub-providers
        pytest.param(
            [],
            "",
            marks=pytest.mark.raises(exception=AirflowSkipException),
        ),
        (
            [("NavyMedicine", "61270229@N05", 1000)],
            "NavyMedicine: 61270229@N05 _(1000 cc-licensed images)_",
        ),
        (
            [
                ("NavyMedicine", "61270229@N05", 1000),
                ("East Riding Archives", "138361426@N08", 2000),
            ],
            "NavyMedicine: 61270229@N05 _(1000 cc-licensed images)_\n"
            "East Riding Archives: 138361426@N08 _(2000 cc-licensed images)_",
        ),
    ),
)
def test_audit_flickr_sub_providers(potential_sub_providers, message):
    with mock.patch(
        "maintenance.flickr_audit_sub_provider_workflow.FlickrSubProviderAuditor.get_new_institutions_with_cc_licensed_images",
        return_value=potential_sub_providers,
    ):
        actual_message = audit_flickr_sub_providers()
        assert message in actual_message


#!/usr/bin/python3
import os
import flask
import argparse
import sys
import PIL.Image
import werkzeug.utils

app = flask.Flask("Picture factory app", static_folder=None)
cache = "cache/"

@app.route("/upload", methods = ['GET', 'POST'])
def upload():
    if flask.request.method == 'POST':
        os.system("rm -r cache/")
        os.system("mkdir cache/")

        f = flask.request.files['file']
        fname = werkzeug.utils.secure_filename(f.filename)
        sfName = os.path.join(cache, fname)
        if not sfName.endswith(".ogg"):
            f.save(sfName + "_tmp")
            os.system("ffmpeg -i '{}' '{}.ogg'".format(sfName + "_tmp", sfName))
            sfName += ".ogg"
        else:
            f.save(sfName)

        os.system("./audio_splitter.py --silence-padding 500 --silence-vol -50 --target-dir chunks {}".format(sfName))
        os.system("rm static/segments.zip")
        os.system("zip -r static/segments.zip cache")
        return flask.redirect("/segments.zip")

    return flask.render_template("upload.html")

@app.route("/segments.zip")
def segments():
    return flask.send_from_directory("static", "segments.zip")

@app.before_first_request
def init():
    app.config['MAX_CONTENT_PATH'] = 32+1000*1000
    app.config['UPLOAD_FOLDER']    = cache
    app.config['UPLOAD_ENABLED']   = os.path.isfile("./upload.enable")

if __name__ == "__main__":

    parser = argparse.ArgumentParser(description='Audio-Splitter',
                        formatter_class=argparse.ArgumentDefaultsHelpFormatter)

    # general parameters #
    parser.add_argument("-i", "--interface", default="127.0.0.1", help="Interface to listen on")
    parser.add_argument("-p", "--port",      default="5000",      help="Port to listen on")

    # startup #
    args = parser.parse_args()
    app.run(host=args.interface, port=args.port)


import pygame
import numpy as np

SCREEN_WIDTH = 900
SCREEN_HEIGHT = 600
win = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption('Snake')

pygame.font.init()
font = pygame.font.SysFont('Consolas', 25)

BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
GREEN = (0, 255, 0)
RED = (255, 0, 0)
GRAY = (100, 100, 100)
BLUE = (0, 0, 255)

GAME_WIDTH = 600
GAME_HEIGHT = 600
WIDTH = 30
SIZE = GAME_WIDTH // WIDTH

class Snake :
    def __init__(self) :
        self.arr = []
        head = (np.random.randint(1, SIZE - 1), np.random.randint(1, SIZE - 1))
        self.arr.append(head)
        self.length = 1

    def move(self, dir) :
        head = (self.arr[0][0] + dir[0], self.arr[0][1] + dir[1])
        self.arr.insert(0, head)
        self.arr.pop()

    def eat(self, food) :
        head = self.arr[0]
        return head[0] == food.i and head[1] == food.j

    def increase_size(self, food) :
        head = (food.i, food.j)
        self.arr.insert(0, head)
        self.length += 1

    def touch_wall(self) :
        head = self.arr[0]
        if head[0] < 0 or head[0] > SIZE - 1 or head[1] < 0 or head[1] > SIZE - 1 :
            return True

        return False

    def bite(self) :
        head = self.arr[0]
        for i in range(1, len(self.arr)) :
            node = self.arr[i]

            if head[0] == node[0] and head[1] == node[1] :
                return True

        return False

    def display(self) :
        for i in range(len(self.arr)) :
            node = self.arr[i]

            pygame.draw.rect(win, BLACK, (node[0] * WIDTH, node[1] * WIDTH, WIDTH, WIDTH))
            pygame.draw.rect(win, GREEN, (node[0] * WIDTH + 1, node[1] * WIDTH + 1, WIDTH - 1, WIDTH - 1))

            if i == 0 :
                pygame.draw.circle(win, BLACK,
                                  (node[0] * WIDTH + WIDTH // 2,
                                   node[1] * WIDTH + WIDTH // 2),
                                   WIDTH // 10)

class Food :
    def __init__(self, snake) :
        self.spawn(snake)

    def spawn(self, snake) :

        coord = snake.arr[0]
        while coord in snake.arr :
            self.i = np.random.randint(0, SIZE)
            self.j = np.random.randint(0, SIZE)
            coord = (self.i, self.j)

    def display(self) :
        pygame.draw.rect(win, RED, (self.i * WIDTH, self.j * WIDTH, WIDTH, WIDTH))

def pos_food_to_snake(snake, food) :
    head = snake.arr[0]

    if food.j < head[1] :
        if food.i < head[0] :
            pos = 0
        elif food.i == head [0] :
            pos = 1
        else :
            pos = 2
    elif food.j == head[1] :
        if food.i < head[0] :
            pos = 3
        elif food.i == head[0] :
            pos = 4
        else :
            pos = 5
    else :
        if food.i < head[0] :
            pos = 6
        elif food.i == head[0] :
            pos = 7
        else :
            pos = 8

    return pos

def snake_view(snake) :
    head = snake.arr[0]

    up = 0
    down = 0
    left = 0
    right = 0

    # walls -
    if head[0] == 0 :
        left = 1
    elif head[0] == SIZE - 1 :
        right = 1
    if head[1] == 0 :
        up = 1
    elif head[1] == SIZE - 1 :
        down = 1

    for i in range(len(snake.arr)) :
        node = snake.arr[i]

        if head[0] - node[0] == 1 and head[1] == node[1] :
            left = 1
        if head[0] - node[0] == -1 and head[1] == node[1] :
            right = 1
        if head[1] - node[1] == 1 and head[0] == node[0] :
            up = 1
        if head[1] - node[1] == -1 and head[0] == node[0] :
            down = 1

    return (up, down, left, right)

def find_view_index(view_index) :
    mult = 1
    ans = 0
    for ele in view_index :
        ans += ele * mult
        mult *= 2

    return ans

def find_dist(snake, food) :
    head = snake.arr[0]
    return (head[0] - food.i) ** 2 + (head[1] - food.j) ** 2

DIR_CHOICES = [(0, -1), (0, 1), (-1, 0), (1, 0)]
# dir_choice = np.random.randint(0, 4)

LEARNING_RATE = 0.1
DISCOUNT = 0.9
EPISODES = 500
MAX_FRAME_COUNT = 1000

epsilon = 1
EPSILON_DECAY = 2 / EPISODES

FOOD_REWARD = 30
DEATH_PENALTY = -100
TIME_PENALTY = -1
TOWARDS_FOOD = 1
AWAY_FROM_FOOD = -1

prev_record = 0
last_10 = [1] * 10

q_table = np.random.uniform(low = -10, high = 0, size = ((9, 16, 4)))

for episode in range(EPISODES):
    snake = Snake()
    food = Food(snake)

    run = True
    render = True
    delay = False
    DELAY_TIME = 50

    action = np.random.randint(0, 4)

    prev_dist = find_dist(snake, food)

    framecount = 0
    while run and framecount < MAX_FRAME_COUNT:

        for event in pygame.event.get() :
            if event.type == pygame.QUIT :
                run = False

        if delay :
            pygame.time.delay(DELAY_TIME)

        keys = pygame.key.get_pressed()

        if keys[pygame.K_ESCAPE] :
            quit()
        elif keys[pygame.K_SPACE] :
            pygame.time.delay(100)
            delay = not delay
        elif keys[pygame.K_UP] :
            if dir_choice != 1 :
                dir_choice = 0
        elif keys[pygame.K_DOWN] :
            if dir_choice != 0 :
                dir_choice = 1
        elif keys[pygame.K_LEFT] :
            if dir_choice != 3 :
                dir_choice = 2
        elif keys[pygame.K_RIGHT] :
            if dir_choice != 2 :
                dir_choice = 3

        pos_food = pos_food_to_snake(snake, food)
        view_snake = snake_view(snake)
        view_index = find_view_index(view_snake)

        if render :
            win.fill(BLACK)
            pygame.draw.rect(win, WHITE, (GAME_WIDTH, 0, SCREEN_WIDTH - GAME_WIDTH, SCREEN_HEIGHT))

            font = pygame.font.SysFont('Consolas', 25)

            text = font.render('Episode : ' + str(episode), True, BLACK)
            win.blit(text, (GAME_WIDTH + 10, 20))

            text = font.render('Length : ' + str(snake.length), True, BLACK)
            win.blit(text, (GAME_WIDTH + 10, 50))

            text = font.render('Epsilon : ' + str(format(epsilon, '.3f')), True, BLACK)
            win.blit(text, (GAME_WIDTH + 10, 80))

            text = font.render('Record length : ' + str(prev_record), True, BLACK)
            win.blit(text, (GAME_WIDTH + 5, 140))

            font = pygame.font.SysFont('Consolas', 20)

            text = font.render('Last 10 Avg : ' + str(sum(last_10)//10), True, BLACK)
            win.blit(text, (GAME_WIDTH + 5, 170))

            text = font.render('AI Agent Observation State -', True, BLACK)
            win.blit(text, (GAME_WIDTH + 5, 240))

            text = font.render('Position of Apple', True, BLACK)
            win.blit(text, (GAME_WIDTH + 5, 275))

            text = font.render('Obstacles surrounding head', True, BLACK)
            win.blit(text, (GAME_WIDTH + 5, 460))

            W = 30
            BOX_SEP = W + 5
            START_X = (GAME_WIDTH + SCREEN_WIDTH) // 2 - BOX_SEP * 3 // 2
            START_Y = SCREEN_HEIGHT // 2
            pos = 0
            for j in range(3) :
                for i in range(3) :
                    if pos != 4 :

                        color = BLACK
                        if pos == pos_food :
                            color = RED

                        pygame.draw.rect(win, color, (START_X + i * BOX_SEP, START_Y + j * BOX_SEP, W, W))

                    pos += 1

            W = 30
            BOX_SEP = W + 5
            START_X = (GAME_WIDTH + SCREEN_WIDTH) // 2 - BOX_SEP * 3 // 2
            START_Y = SCREEN_HEIGHT // 2 + BOX_SEP * 11 // 2
            for i in range(4) :
                color = BLACK
                if view_snake[i] == 1 :
                    color = GRAY

                if i == 0 :
                    pygame.draw.rect(win, color, (START_X + BOX_SEP, START_Y, W, W))
                elif i == 1 :
                    pygame.draw.rect(win, color, (START_X + BOX_SEP, START_Y + 2 * BOX_SEP, W, W))
                elif i == 2 :
                    pygame.draw.rect(win, color, (START_X, START_Y + BOX_SEP, W, W))
                elif i == 3 :
                    pygame.draw.rect(win, color, (START_X + 2 * BOX_SEP, START_Y + BOX_SEP, W, W))

        curr_state = (pos_food, view_index)

        prev_action = action
        if np.random.random() > epsilon :
            action = np.argmax(q_table[curr_state])
        else :
            action = np.random.randint(0, 4)

        if (action == 1 and prev_action == 0) or (action == 0 and prev_action == 1) :
            action = prev_action
        elif (action == 2 and prev_action == 3) or (action == 3 and prev_action == 2) :
            action = prev_action

        dir_choice = action
        snake.move(DIR_CHOICES[dir_choice])

        next_state = (pos_food, view_index)
        # reward = TIME_PENALTY
        curr_dist = find_dist(snake, food)

        if curr_dist < prev_dist :
            reward = TOWARDS_FOOD
        else :
            reward = AWAY_FROM_FOOD

        prev_dist = curr_dist
        if snake.length > prev_record :
            prev_record = snake.length
            delay = True

        eating = False
        if snake.eat(food) :
            eating = True
            snake.increase_size(food)
            food.spawn(snake)
            reward = FOOD_REWARD
            framecount = 0

        if snake.touch_wall() :
            run = False
            reward = DEATH_PENALTY

        if snake.bite() and not eating :
            run = False
            reward = DEATH_PENALTY

        max_future_q = np.max(q_table[next_state])
        current_q = q_table[curr_state][action]

        new_q = (1 - LEARNING_RATE) * current_q + LEARNING_RATE * (reward + DISCOUNT * max_future_q)
        q_table[curr_state][action] = new_q

        curr_state = next_state

        if render and run :
            food.display()
            snake.display()
            pygame.display.update()

        framecount += 1

    if epsilon > 0 :
        epsilon -= EPSILON_DECAY

    last_10.pop(0)
    last_10.append(snake.length)

pygame.quit()


import requests
from cardReader import CardReader

def admin(id):
    print("read in card id " + id)
    mode = input("what do you want to do? (addTokens, addTickets, charge, addUser, removeUser)")
    while mode not in ["addTokens", "addTickets", "charge", "addUser", "removeUser"]:
        mode = input("please enter a valid option (addTokens, addTickets, charge, addUser, removeUser)")
    if mode == "addTokens" or mode == "addTickets" or mode == "charge" or mode == "addUser":
        amount = input("Please enter an amount")
        name = ""
        try:
            amount = int(amount)
        except:
            print("Please enter a valid integer")
            return
        if mode == "addUser":
            name = input("Please enter a name")
        v = requests.get("https://arcade-52bs.onrender.com/" + mode, params={"id" : id, "amount" : amount, "name" : name})
        if v.text == "1":
            print("success")
        else:
            print("failure")
    elif mode == "removeUser":
        v = requests.get("https://arcade-52bs.onrender.com/removeUser", params={"id" : id})


import argparse
import init_paths
import os
from concern import webcv2
import numpy as np
import cv2
import tqdm
from PIL import Image

from detectron2.utils.logger import setup_logger
from detectron2.utils.visualizer import Visualizer
from slender_det.config import get_cfg
from slender_det.data import MetadataCatalog, build_detection_train_loader

def setup(args):
    cfg = get_cfg()
    if args.config_file:
        cfg.merge_from_file(args.config_file)
    cfg.merge_from_list(args.opts)
    cfg.freeze()
    return cfg

def parse_args(in_args=None):
    parser = argparse.ArgumentParser(description="Visualize ground-truth data")
    parser.add_argument("--config-file", metavar="FILE", help="path to config file")
    parser.add_argument("--show", action="store_true", help="show output in a window")
    parser.add_argument("--speed", action="store_true", help="test speed of the loader")
    parser.add_argument(
        "opts",
        help="Modify config options using the command-line",
        default=None,
        nargs=argparse.REMAINDER,
    )
    return parser.parse_args(in_args)

if __name__ == "__main__":
    args = parse_args()
    setup_logger(name="fvcore")
    setup_logger(name="slender_det")
    logger = setup_logger()
    logger.info("Arguments: " + str(args))
    cfg = setup(args)

    metadata = MetadataCatalog.get(cfg.DATASETS.TRAIN[0])

    def output(vis, fname):
        if args.show:
            print(fname)
            webcv2.imshow("window", vis.get_image()[:, :, ::-1])
            webcv2.waitKey()

    train_data_loader = build_detection_train_loader(cfg)
    import ipdb; ipdb.set_trace()
    for batch in tqdm.tqdm(train_data_loader):
        if args.speed:
            continue
        for per_image in batch:
            # Pytorch tensor is in (C, H, W) format
            img = per_image["image"].permute(1, 2, 0)
            if cfg.INPUT.FORMAT == "BGR":
                img = img[:, :, [2, 1, 0]]
            else:
                img = np.asarray(Image.fromarray(img, mode=cfg.INPUT.FORMAT).convert("RGB"))

            visualizer = Visualizer(img, metadata=metadata, scale=1.0)
            target_fields = per_image["instances"].get_fields()
            labels = [metadata.thing_classes[i] for i in target_fields["gt_classes"]]
            vis = visualizer.overlay_instances(
                labels=labels,
                boxes=target_fields.get("gt_boxes", None),
                masks=target_fields.get("gt_masks", None),
                keypoints=target_fields.get("gt_keypoints", None),
            )
            output(vis, str(per_image["image_id"]) + ".jpg")


# ---------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# ---------------------------------------------------------
import argparse
import json
import os
from random import randint
from time import sleep

from azureml.core import Run

class Util:

    @staticmethod
    def str2bool(v):

        if v is None:
            return False
        if isinstance(v, bool):
            return v
        if v.lower() in ('yes', 'True', 'true', 't', 'y', '1'):
            return True
        elif v.lower() in ('no', 'False', 'false', 'f', 'n', '0'):
            return False
        else:
            raise argparse.ArgumentTypeError('Boolean value expected.')

parser = argparse.ArgumentParser("split")
parser.add_argument("--node_count", default=1, type=int, help="number of nodes")
parser.add_argument("--process_count_per_node", default=1, type=int, help="number of processes per node")
parser.add_argument("--retrain_failed_models", default=False, type=Util.str2bool, help="retrain failed models only")

args, _ = parser.parse_known_args()
many_models_train = None

# Whether or not this driver has been initialized
driver_initialized = False

def _get_automl_settings():
    with open(os.path.join(os.path.dirname(os.path.realpath(__file__)), 'automl_settings.json')) as json_file:
        return json.load(json_file)

def _initialize_driver():
    print("Initializing driver")

    # Sleep this worker node for a random amount of time. This helps stagger new traffic over a
    # longer period of time so that service pods have time to auto-scale up.

    max_concurrent_runs = args.node_count * args.process_count_per_node
    traffic_ramp_up_period_in_seconds = min(max_concurrent_runs, 600)
    worker_sleep_time_in_seconds = randint(1, traffic_ramp_up_period_in_seconds)
    print("Traffic ramp up period: {} seconds".format(traffic_ramp_up_period_in_seconds))
    print("Sleeping this worker for {} seconds to stagger traffic ramp-up...".format(worker_sleep_time_in_seconds))
    sleep(worker_sleep_time_in_seconds)
    current_step_run = Run.get_context()
    from azureml.train.automl.runtime._many_models.many_models_train import \
        ManyModelsTrain
    global many_models_train
    many_models_train = ManyModelsTrain(current_step_run=current_step_run,
                                        automl_settings=_get_automl_settings(),
                                        process_count_per_node=args.process_count_per_node,
                                        retrain_failed_models=args.retrain_failed_models)
    print('many_models_train_driver._initialize_driver() done.')

def run(input_data):
    print("Invoking many_models_train_driver.run()")

    # Initiailze the driver when the first mini batch runs.
    # (This is done because the initialize call requires a sleep call to stagger new traffic ramp-up (refer to
    # the initialize method for more info). There can be a large time gap between calls to the PRS in-built init()
    # methods and the in-built run methods. For example, for large datasets, it seems possible for PRS to invoke
    # the init() methods of all workers, and then 15 minutes later, invoke the run methods of all workers. Given that,
    # the sleep call to stagger traffic ramp-up won't work as expected if invoked in the PRS in-built init() method.)
    global driver_initialized
    if not driver_initialized:
        _initialize_driver()
        driver_initialized = True

    global many_models_train
    return many_models_train.run(input_data)


import cv2 as cv
import mediapipe as mp

class poseDetector():
    def __init__(self, static_image_mode=False,
                 model_complexity=1,
                 smooth_landmarks=True,
                 enable_segmentation=False,
                 smooth_segmentation=True,
                 min_detection_confidence=0.5,
                 min_tracking_confidence=0.5):  # con - confidence

        self.static_image_mode = static_image_mode
        self.model_complexity = model_complexity
        self.smooth_landmarks = smooth_landmarks
        self.enable_segmentation = enable_segmentation
        self.smooth_segmentation = smooth_segmentation
        self.min_detection_confidence = min_detection_confidence
        self.min_tracking_confidence = min_tracking_confidence

        self.mpDraw = mp.solutions.drawing_utils
        self.mpPose = mp.solutions.pose
        self.pose = self.mpPose.Pose()

    def findPose(self, img, draw = True):

        imgRGB = cv.cvtColor(img, cv.COLOR_BGR2RGB)
        self.results = self.pose.process(imgRGB)

        if self.results.pose_landmarks:
           self.mpDraw.draw_landmarks(img, self.results.pose_landmarks, self.mpPose.POSE_CONNECTIONS)
        return img

    def findPosition(self, img, draw = True):
        lmList = []

        if self.results.pose_landmarks:

            for id, lm in enumerate(self.results.pose_landmarks.landmark):
                h, w, c = img.shape
                # find out the position of each landmark in the image,
                # given the ratio of those position in the picture
                # z is the depth, make it a positive integer, so it can be
                # compared more easily.
                cx, cy, cz = int(lm.x * w), int(lm.y * h), int(-lm.z * 100)
                lmList.append([id, cx, cy, cz])
                if draw:
                    cv.circle(img, (cx, cy), 15, (255, 0, 255), cv.FILLED)
        return lmList

def main():
    pTime = 0
    cTime = 0

    cap = cv.VideoCapture(0)
    # set the dimensions of live video
    cap.set(3, 640)
    cap.set(4, 480)
    detector = poseDetector()
    while True:
        success, img = cap.read()
        img = detector.findPose(img) #Get the model hands on the image

        lmList = detector.findPosition(img) #Collect all the positions
        if len(lmList) != 0:
            print(lmList[4])

        fps = 1 / (cTime - pTime)
        pTime = cTime

        cv.imshow("img", img)
        cv.waitKey(1)

# _name_ is a implicit variable whose value is set as __main__.
# If other files import this module, they will execute this main function first and then execute other codes
if __name__ == '__main__':
    main()


# -*- coding: utf-8 -*-
# __author__ = 'zengjing'

import web
import json
import types
import datetime
from mainapp.libs.signature import check_sig
from bson.objectid import ObjectId
from biocluster.config import Config
from mainapp.models.mongo.submit.denovo_rna.denovo_kegg_rich import DenovoKeggRich
from mainapp.models.mongo.meta import Meta
from mainapp.models.workflow import Workflow
from mainapp.controllers.project.denovo_controller import DenovoController

class KeggRichRegulate(DenovoController):
    """
    kegg富集、调控接口
    """
    def __init__(self):
        super(KeggRichRegulate, self).__init__(instant=False)

    @check_sig
    def POST(self):
        data = web.input()
        client = data.client if hasattr(data, 'client') else web.ctx.env.get('HTTP_CLIENT')
        #print data
        return_result = self.check_options(data)
        if return_result:
            info = {"success": False, "info": "+".json(return_result)}
            return json.dumps(info)
        my_param = {'analysis_type': data.analysis_type, "express_diff_id": data.express_diff_id,
                    "compare": data.compare, "submit_location": data.submit_location}
        if data.analysis_type in ["enrich", "both"]:
            my_param["correct"] = data.correct
            my_param["regulate"] = data.regulate
        params = json.dumps(my_param, sort_keys=True, separators=(',', ':'))
        name = data.compare.split(',')[0]
        compare_name = data.compare.split(',')[1]
        express_diff_info = Meta(db=self.mongodb).get_main_info(data.express_diff_id, "sg_denovo_express_diff")
        if not express_diff_info:
            info = {"success": False, "info": "express_diff_id不存在，请检查参数是否正确！"}
            return json.dumps(info)
        task_id = express_diff_info["task_id"]
        project_sn = express_diff_info["project_sn"]
        if data.analysis_type == "enrich":
            main_table_name = "KeggRich_" + str(datetime.datetime.now().strftime("%Y%m%d_%H%M%S"))
            kegg_enrich_id = DenovoKeggRich().add_kegg_rich(name=main_table_name, params=params, project_sn=project_sn, task_id=task_id)
            update_info = {str(kegg_enrich_id): "sg_denovo_kegg_enrich"}
            options = {
                "analysis_type": data.analysis_type,
                "update_info": json.dumps(update_info),
                "name": name,
                "compare_name": compare_name,
                "kegg_enrich_id": str(kegg_enrich_id),
                "kegg_table": data.express_diff_id,
                "diff_stat": data.express_diff_id,
                "all_list": data.express_diff_id,
                "correct": data.correct,
                "regulate": data.regulate
            }
            to_file = ["denovo.export_kegg_table(kegg_table)", "denovo.export_diff_express(diff_stat)", "denovo.export_all_gene_list(all_list)"]
            self.set_sheet_data(name="denovo_rna.report.kegg_rich_regulate", options=options,
                                main_table_name=main_table_name, module_type="workflow", to_file=to_file,
                                main_id=kegg_enrich_id, collection_name="sg_denovo_kegg_enrich")
        if data.analysis_type == "regulate":
            main_table_name = "KeggRegulate_" + str(datetime.datetime.now().strftime("%Y%m%d_%H%M%S"))
            kegg_regulate_id = DenovoKeggRich().add_kegg_regulate(name=main_table_name, params=params, project_sn=project_sn,
                                                            task_id=task_id)
            update_info = {str(kegg_regulate_id): "sg_denovo_kegg_regulate"}
            options = {
                "analysis_type": data.analysis_type,
                "update_info": json.dumps(update_info),
                "name": name,
                "compare_name": compare_name,
                "kegg_regulate_id": str(kegg_regulate_id),
                "kegg_table": data.express_diff_id,
                "diff_stat": data.express_diff_id
            }
            to_file = ["denovo.export_kegg_table(kegg_table)", "denovo.export_diff_express(diff_stat)"]
            self.set_sheet_data(name="denovo_rna.report.kegg_rich_regulate", options=options,
                                main_table_name=main_table_name, module_type="workflow", to_file=to_file,
                                main_id=kegg_regulate_id, collection_name="sg_denovo_kegg_regulate")
        if data.analysis_type == "both":
            main_table_name = "KeggEnrichRegulate_" + str(datetime.datetime.now().strftime("%Y%m%d_%H%M%S"))
            sort_id = DenovoKeggRich().add_kegg_pval_sort(name=main_table_name, params=params,
                                                                  project_sn=project_sn,
                                                                  task_id=task_id)
            update_info = {str(sort_id): "sg_denovo_kegg_pvalue"}
            options = {
                "analysis_type": data.analysis_type,
                "update_info": json.dumps(update_info),
                "name": name,
                "compare_name": compare_name,
                "sort_id": str(sort_id),
                "kegg_table": data.express_diff_id,
                "diff_stat": data.express_diff_id,
                "all_list": data.express_diff_id,
                "correct": data.correct,
                "regulate": data.regulate
            }
            to_file = ["denovo.export_kegg_table(kegg_table)", "denovo.export_diff_express(diff_stat)",
                       "denovo.export_all_gene_list(all_list)"]
            self.set_sheet_data(name="denovo_rna.report.kegg_rich_regulate", options=options,
                                main_table_name=main_table_name, module_type="workflow", to_file=to_file,
                                main_id=sort_id, collection_name="sg_denovo_kegg_pvalue")
        task_info = super(KeggRichRegulate, self).POST()
        return json.dumps(task_info)

    def check_options(self, data):
        """
        检查网页端传来的参数是否正确
        """
        params_name = ["analysis_type", "express_diff_id", "compare", "submit_location"]
        success = []
        for name in params_name:
            if not hasattr(data, name):
                success.append("缺少参数：%" % name)
        express_diff_id = str(data.express_diff_id)
        if not isinstance(express_diff_id, ObjectId) and not isinstance(express_diff_id, types.StringType):
            success.append("传入的express_diff_id:%不是一个ObjectId对象或字符串类型!" % express_diff_id)
        analysis_type = data.analysis_type
        if analysis_type not in ["enrich", "regulate", "both"]:
            success.append("%分析不存在" % analysis_type)
        if analysis_type in ["enrich", "both"]:
            for name in ["correct", "regulate"]:
                if not hasattr(data, name):
                    success.append("缺少参数:%" % name)
            if data.regulate not in ["up", "down", "all"]:
                success.append("上下调选择应为up/down/all")
        return success


from __future__ import print_function
import datetime
import json
import re
import pandas as pd
from nltk.tokenize import RegexpTokenizer
from nltk.corpus import stopwords
from nltk.stem import WordNetLemmatizer
import threading

filepath = "./Dataset/data4.csv"
tokenizer = RegexpTokenizer(r'\w+')
lemmatizer = WordNetLemmatizer()
stop_words = stopwords.words()

df = pd.read_csv(filepath)

li = []

# tokenizing the emails
def tokenize_emails(df, li):
    for i in range(len(df)):
        message = tokenizer.tokenize(df.iloc[i]['Content'])
        li.append(message)

# removing all stopwords in the corpus
def rem_stopwords(li):
    for i in range(len(li)):
        temp = []
        for x in range(len(li[i])):
            if(li[i][x] not in stop_words):
                temp.append(li[i][x])
        li[i] = temp

# lemmatization
def lemmatize_emails(li):
    for i in range(len(li)):
        for x in range(len(li[i])):
            li[i][x] = lemmatizer.lemmatize(li[i][x])
            if(len(li[i][x]) > 12):
                li[i].remove(li[i][x])
            if(re.search("\*.*",li[i][x])):
                li[i].remove(li[i][x])

if __name__ == "__main__":
    # creating thread
    print('[1] Reading the csv file', datetime.datetime.now())
    df = pd.read_csv(filepath)
    df.drop(['Unnamed: 0'], axis = 1, inplace = True)
    print(df.columns)

    li1 = []
    li2 = []
    li3 = []
    li4 = []
    li5 = []
    li6 = []
    li7 = []
    li8 = []

    partition = int(len(df)/8)

    print('[2] Initializing multi-thread 1 at ', datetime.datetime.now())
    t1 = threading.Thread(target=tokenize_emails, args=(df[:partition], li1,))
    t2 = threading.Thread(target=tokenize_emails, args=(df[partition:2*partition], li2,))
    t3 = threading.Thread(target=tokenize_emails, args=(df[2*partition:3*partition], li3,))
    t4 = threading.Thread(target=tokenize_emails, args=(df[3*partition:4*partition], li4,))
    t5 = threading.Thread(target=tokenize_emails, args=(df[4*partition:5*partition], li5,))
    t6 = threading.Thread(target=tokenize_emails, args=(df[5*partition:6*partition], li6,))
    t7 = threading.Thread(target=tokenize_emails, args=(df[6*partition:7*partition], li7,))
    t8 = threading.Thread(target=tokenize_emails, args=(df[7*partition:], li8,))

    print('[3] Starting threads at ', datetime.datetime.now())
    # starting thread 1
    t1.start()
    # starting thread 2
    t2.start()
    # starting thread 3
    t3.start()
    # starting thread 4
    t4.start()
    # starting thread 5
    t5.start()
    # starting thread 6
    t6.start()
    # starting thread 7
    t7.start()
    # starting thread 8
    t8.start()

    print('[4] Joining threads at ', datetime.datetime.now())
    # starting thread 1
    t1.join()
    # joining thread 2
    t2.join()
    # joining thread 3
    t3.join()
    # joining thread 4
    t4.join()
    # joining thread 5
    t5.join()
    # joining thread 6
    t6.join()
    # joining thread 7
    t7.join()
    # joining thread 8
    t8.join()

    print('[5] Initializing multi-thread 2 at ', datetime.datetime.now())
    t1 = threading.Thread(target=rem_stopwords, args=(li[:partition],))
    t2 = threading.Thread(target=rem_stopwords, args=(li[partition:2*partition],))
    t3 = threading.Thread(target=rem_stopwords, args=(li[2*partition:3*partition],))
    t4 = threading.Thread(target=rem_stopwords, args=(li[3*partition:4*partition],))
    t5 = threading.Thread(target=rem_stopwords, args=(li[4*partition:5*partition],))
    t6 = threading.Thread(target=rem_stopwords, args=(li[5*partition:6*partition],))
    t7 = threading.Thread(target=rem_stopwords, args=(li[6*partition:7*partition],))
    t8 = threading.Thread(target=rem_stopwords, args=(li[7*partition:],))

    print('[6] Starting threads at ', datetime.datetime.now())
    # starting thread 1
    t1.start()
    # starting thread 2
    t2.start()
    # starting thread 3
    t3.start()
    # starting thread 4
    t4.start()
    # starting thread 5
    t5.start()
    # starting thread 6
    t6.start()
    # starting thread 7
    t7.start()
    # starting thread 8
    t8.start()

    print('[7] Joining threads at ', datetime.datetime.now())
    # joining thread 1
    t1.join()
    # joining thread 2
    t2.join()
    # joining thread 3
    t3.join()
    # joining thread 4
    t4.join()
    # joining thread 5
    t5.join()
    # joining thread 6
    t6.join()
    # joining thread 7
    t7.join()
    # joining thread 8
    t8.join()

    print('[8] Initializing multi-thread 3 at ', datetime.datetime.now())
    t1 = threading.Thread(target=lemmatize_emails, args=(li[:partition],))
    t2 = threading.Thread(target=lemmatize_emails, args=(li[partition:2*partition],))
    t3 = threading.Thread(target=lemmatize_emails, args=(li[2*partition:3*partition],))
    t4 = threading.Thread(target=lemmatize_emails, args=(li[3*partition:4*partition],))
    t5 = threading.Thread(target=lemmatize_emails, args=(li[4*partition:5*partition],))
    t6 = threading.Thread(target=lemmatize_emails, args=(li[5*partition:6*partition],))
    t7 = threading.Thread(target=lemmatize_emails, args=(li[6*partition:7*partition],))
    t8 = threading.Thread(target=lemmatize_emails, args=(li[7*partition:],))

    print('[9] Starting threads at ', datetime.datetime.now())
    # starting thread 1
    t1.start()
    # starting thread 2
    t2.start()
    # starting thread 3
    t3.start()
    # starting thread 4
    t4.start()
    # starting thread 5
    t5.start()
    # starting thread 6
    t6.start()
    # starting thread 7
    t7.start()
    # starting thread 8
    t8.start()

    print('[10] Joining threads at ', datetime.datetime.now())
    # starting thread 1
    t1.join()
    # joining thread 2
    t2.join()
    # joining thread 3
    t3.join()
    # joining thread 4
    t4.join()
    # joining thread 5
    t5.join()
    # joining thread 6
    t6.join()
    # joining thread 7
    t7.join()
    # joining thread 8
    t8.join()

    print('[11] Creating tokenized corpus at ', datetime.datetime.now())
    li = li1 + li2 + li3 + li4 + li5 + li6 + li7 + li8

    print('[12] Removing all whitespaces in the corpus at ', datetime.datetime.now())
    # removing any whitespace in the words in the list
    for i in range(len(li)):
        for x in range(len(li[i])):
            li[i][x] = li[i][x].strip()

    print('[13] Storing the length of individual emails in the corpus at ', datetime.datetime.now())
    len_li = []
    for i in li:
        len_li.append(len(i))

    df['Tokenized'] = li

    # df.sort_values('Email_Size',inplace = True, ascending = False)
    print('[14] Storing the json in a file')

    dic = {"len_li": len_li}
    js = json.dumps(dic)

    with open("length.json", "w") as outfile:
        outfile.write(js)

    print('[15] Stored the json file')
    df.drop(['Content'], axis = 1, inplace = True)
    print('[16] Dropped the content column and storing the database')
    df.to_csv('./Dataset/data2_1.csv', index = False)
    print('[17] Done!!')


# -*- coding: utf-8 -*-
# __author__ = 'shijin'
import web
import json
import os
import unittest
import datetime
from mainapp.models.mongo.denovo_rna_v2 import DenovoRnaV2
from mbio.api.to_file.denovo_rna_v2 import *
from mainapp.libs.signature import check_sig
from mainapp.controllers.project.denovo_rna_v2_controller import DenovoRnaV2Controller

class GenesetDeleteAction(DenovoRnaV2Controller):
    def __init__(self):
        super(GenesetDeleteAction, self).__init__(instant=True)

    @check_sig
    def POST(self):
        data = web.input()
        #print data
        default_argu = ['geneset_id', "task_id"]
        for argu in default_argu:
            if not hasattr(data, argu):
                var = []
                var.append(argu)
                info = {'success': False, 'info': "Lack argument: %s" % (argu), "code": 'C1601101', "variables": var}
                return json.dumps(info)
        #print(data.geneset_id)
        if self.denovo_rna_v2.delete_geneset(data.geneset_id, data.task_id):
            task_info = {"success": True, "info": "任务运行成功."}
            task_info['content'] = {
                'ids': {
                    'id': "",
                    'name': ""
                    }}
            return json.dumps(task_info)
        else:
            task_info = {"success": False, "info": "任务运行失败.", "code": 'C1601102', "variables": ''}
            return json.dumps(task_info)

class TestFunction(unittest.TestCase):
    """
    This is test for the tool. Just run this script to do test.
    """
    def test_this(self):
        cmd = 'python /mnt/ilustre/users/sanger-dev/biocluster/bin/webapitest.py '
        cmd += 'post '
        cmd += "-fr no "
        cmd += '-c {} '.format("client03")
        cmd += "i/denovo_rna_v2/geneset_delete "
        cmd += "-b http://192.168.12.102:9090 "
        args = dict(
            task_id="denovo_rna_v2",
            task_type="1",
            # submit_location="GenesetVenn",
            geneset_ids="5a35da8ba4e1af38e6fb83d7",
        )
        arg_names, arg_values = args.keys(), args.values()
        cmd += '-n "{}" -d "{}" '.format(";".join(arg_names), ";".join(arg_values))
        print(cmd)
        os.system(cmd)

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