from abc import abstractmethod
from audioop import bias

from loguru import logger
import numpy as np
import pandas as pd
import torch
import torch.nn as nn

from src.methods.utils import confidence_interval
from src.utils import set_device, plot_task

from src.adv_train import RCNN, modify_data

class AbstractMetaLearner(nn.Module):
    """
    Abstract class for meta-learning models. Extensions of this class must define the set_forward function.
    """

    def __init__(self,
                 model_func,
                 transportation=None,
                 use_test_query=False,
                 use_train_query=False,
                 training_stats=None,
                 adv_train_config=None,
                 **args
                 ):
        """

        Args:
            model_func (src.backbones object): backbone model initialized
            training_stats (Statistics): training statistics of the model, updated during training

        """
        super(AbstractMetaLearner, self).__init__()
        # importing inside class to avoid cyclic import
        from src.adv_train import transductive_adv_loss

        self.args = args
        self.report_ray = args.get("report_ray", False)
        self.n_episodes = args.get('n_episodes')
        self.feature = model_func
        self.training_stats = training_stats
        self.transportation_module = transportation
        self.use_test_query = use_test_query
        self.use_train_query = use_train_query
        self.loss_fn = nn.CrossEntropyLoss()
        self.adv_train_config = adv_train_config

        if self.use_test_query and (self.adv_train_config is not None):
            self.transductive_loss_fn = transductive_adv_loss
        else:
            self.transductive_loss_fn = None

        if 'ANIL' in args.get("model_name"):
            self.feature.cls = set_device(
                                nn.Linear(self.feature.final_feat_dim, args.get("n_way"), bias=True)
                                )
            self.meta_learner = set_device(self.build_metalearner(args.get("base_lr")))

    @abstractmethod
    def set_forward(self, support_images, support_labels, query_images):
        """
        Predict query set labels using information from support set labelled images.
        Must be implemented in all classes extending AbstractMetaLearner.
        Args:
            support_images (torch.Tensor): shape (number_of_support_set_images, **image_shape)
            support_labels (torch.Tensor): artificial support set labels in range (0, n_way)
            query_images (torch.Tensor): shape (number_of_query_set_images, **image_shape)

        Returns:
            torch.Tensor: shape(n_query*n_way, n_way), classification prediction for each query data
        """
        pass

    def fit_on_task(
        self, support_images, support_labels,
        query_images, query_labels,
        optimizer,
    ):
        """
        Perform a forward pass and a backward pass on one episode.
        Args:
            support_images (torch.Tensor): shape (number_of_support_set_images, **image_shape)
            support_labels (torch.Tensor): artificial support set labels in range (0, n_way)
            query_images (torch.Tensor): shape (number_of_query_set_images, **image_shape)
            query_labels (torch.Tensor): artificial query set labels in range (0, n_way)
            optimizer (torch.optim.Optimizer): model optimizer

        Returns:
            tuple(torch.Tensor, torch.Tensor): detached from the computational graph
                - shape(n_query*n_way, n_way), classification prediction for each query data
                - shape(,), training loss
        """
        optimizer.zero_grad()
        scores = self.set_forward(support_images, support_labels, query_images)
        loss = self.loss_fn(scores, query_labels)
        loss.backward()
        optimizer.step()

        return scores.detach(), loss.detach().item()

    def extract_features(self, support_images, query_images, feature_ext=None):
        """
        Computes the features vectors of the support and query sets
        Args:
            support_images (torch.Tensor): shape (n_support_images, **image_dim) input data
            query_images (torch.Tensor): shape (n_query_images, **image_dim) input data

        Returns:
            Tuple(torch.Tensor, torch.Tensor): features vectors of the support and query sets, respectively of shapes
            (n_support_images, features_dim) and (n_query_images, features_dim)
        """
        # Set to CUDA if available
        support_images = set_device(support_images)
        query_images = set_device(query_images)

        if feature_ext is not None:
            z_support = feature_ext.forward(support_images)
            z_query = feature_ext.forward(query_images)
        else:
            z_support = self.feature.forward(support_images)
            z_query = self.feature.forward(query_images)

        return z_support, z_query

    @staticmethod
    def get_prototypes(features, labels):
        """
        Compute a prototype for each class.
        Args:
            features (torch.Tensor): shape[n_images, feature_dim], feature vectors
            labels (torch.Tensor): shape[n_images], label corresponding to each feature vector
        Returns:
            torch.Tensor: prototypes. shape[number_of_unique_values_in_labels, feature_dim]
        """

        n_way = len(torch.unique(labels))
        # Prototype i is the mean of all instances of features corresponding to labels == i
        return torch.cat(
            [features[torch.nonzero(labels == label)].mean(0) for label in range(n_way)]
        )

    @staticmethod
    def evaluate(scores, query_labels):
        """
        Predict labels of query images and returns the number of correct top1 predictions
        Args:
            scores (torch.Tensor): shape (number_of_query_set_images, n_way)
            query_labels (torch.Tensor): artificial query set labels in range (0, n_way)

        Returns:
            float: classification accuracy in [0,1]
        """

        topk_scores, topk_labels = scores.data.topk(1, 1, True, True)
        top1_correct = float((topk_labels[:, 0] == query_labels).sum())
        return float(top1_correct) / len(query_labels)

    @staticmethod
    def get_task_perf(
        task_id, classification_scores, labels, class_ids, source_id, target_id
    ):
        """
        Records the classification results for each query instance.
        Args:
            task_id (int): index of the task
            classification_scores (torch.Tensor): predicted classification scores
            labels (torch.Tensor): ground truth labels
            class_ids (list[int]): indices of the classes composing the current classification task
            source_id (int): index of the source domain for this task
            target_id (int): index of the target domain for this task

        Returns:
            pd.DataFrame: for each couple (query, class), gives classification score, class_id,
                ground truth query label, current task id and source and target domain,
        """
        return pd.concat(
            [
                pd.DataFrame(
                    {
                        "task_id": task_id,
                        "source_domain": source_id,
                        "target_domain": target_id,
                        "image_id": i,
                        "true_label": int(class_ids[labels[i]]),
                        "predicted_label": [
                            int(class_ids[label])
                            for label in range(classification_scores.shape[1])
                        ],
                        "score": classification_scores[i],
                    }
                )
                for i in range(labels.shape[0])
            ]
        )

    def plot_adv_task(self, adv_tasks, epoch):
        NUM_TASKS_TO_PLOT = 15
        episodes = list(adv_tasks.keys())
        try:
            episodes_to_plot = np.round(np.linspace(0, len(episodes)-1, NUM_TASKS_TO_PLOT)).astype(int)
        except:
            episodes_to_plot = np.round(np.linspace(0, len(episodes)-1, 10)).astype(int)
        for idx in episodes_to_plot:
            data = adv_tasks[episodes[idx]]
            if "query_before" and "query_after" in data:
                key_before = "query_before"
                title_before = "Query - Before Adversarial Projection"
                key_after = "query_after"
                title_after = "Query - After Adversarial Projection"
            elif "support_before" in data and "support_after" in data:
                key_before = "support_before"
                title_before = "Support - Before Adversarial Projection"
                key_after = "support_after"
                title_after = "Support - After Adversarial Projection"

            plot_task(data[key_before][0], data[key_before][1],
                        self.args["plot_path"], epoch, idx, key_before,
                        data["nrow"], data["ncol"], title_before
                        )
            plot_task(data[key_after][0], data[key_after][1],
                        self.args["plot_path"], epoch, idx, key_after,
                        data["nrow"], data["ncol"], title_after
                        )

    def adv_project(self, mode, episode_index, support_images, support_labels, query_images, query_labels, loss_fn):
        adv_tasks = {}
        if self.adv_train_config["{}_project_task".format(mode)] != 0:
            if self.args.get("plot_perturbed", False):
                adv_tasks[episode_index] = {"query_before": (query_images, query_labels),
                                            "nrow" : self.args["n_way"],
                                            "ncol" : self.args["n_target"]
                                            }

            query_images = RCNN(query_images, self.adv_train_config)
            query_images = modify_data(self,
                                    support_images,
                                    support_labels,
                                    query_images,
                                    query_labels,
                                    loss_fn,
                                    self.adv_train_config | {'project_task': self.adv_train_config["{}_project_task".format(mode)]}
                                    )

            if self.args.get("plot_perturbed", False):
                adv_tasks[episode_index]["query_after"] = (query_images, query_labels)

        if self.adv_train_config["{}_project_task".format(mode)] != 1:
            if self.args.get("plot_perturbed", False):
                adv_tasks[episode_index] = {"support_before": (support_images, query_labels),
                                            "nrow" : self.args["n_way"],
                                            "ncol" : self.args["n_source"]
                                            }

            support_images = RCNN(support_images, self.adv_train_config)
            support_images = modify_data(self,
                                        support_images,
                                        support_labels,
                                        query_images,
                                        query_labels,
                                        loss_fn,
                                        self.adv_train_config | {'project_task': self.adv_train_config["{}_project_task".format(mode)]}
                                        )

            if self.args.get("plot_perturbed", False):
                adv_tasks[episode_index]["support_after"] = (support_images, query_labels)

            # update adv learning rate
            if self.adv_train_config.get("adv_lr_sched", None) is not None:
                self.adv_train_config["lr"] = self.adv_train_config["adv_lr_sched"].step(
                                                                self.adv_train_config["lr"]
                                                            )

        return support_images, support_labels, query_images, query_labels, adv_tasks

    def train_loop(self, epoch, train_loader, optimizer):
        """
        Executes one training epoch
        Args:
            epoch (int): current epoch
            train_loader (DataLoader): loader of a given number of episodes
            optimizer (torch.optim.Optimizer): model optimizer

        Returns:
            tuple(float, float): resp. average loss and classification accuracy
        """
        print_freq = self.n_episodes
        adv_tasks = {}
        loss_list = []
        acc_list = []
        for episode_index, (
            support_images,
            support_labels,
            query_images,
            query_labels,
            _,
            _,
            _,
        ) in enumerate(train_loader):
            query_labels = set_device(query_labels)
            support_labels = set_device(support_labels)

            adv_prob = np.random.random()
            if self.use_train_query and \
              (self.adv_train_config is not None) and \
              (adv_prob > 1.0-self.args.get("adv_proj_prob", 0.5)):
                loss_fn = self.loss_fn
                support_images, support_labels, query_images, query_labels, adv_tasks = self.adv_project(
                    'train', episode_index, support_images, support_labels, query_images, query_labels, loss_fn
                )

            self.train()

            scores, loss_value = self.fit_on_task(
                support_images, support_labels,
                query_images, query_labels,
                optimizer,
            )

            loss_list.append(loss_value)

            acc_list.append(self.evaluate(scores, query_labels) * 100)

            if episode_index % print_freq == print_freq - 1:
                logger.info(
                    "Epoch {epoch} | Batch {episode_index}/{n_batches} | Accuracy {acc} | Loss {loss}".format(
                        epoch=epoch,
                        episode_index=episode_index + 1,
                        n_batches=len(train_loader),
                        loss=np.asarray(loss_list).mean(),
                        acc=np.asarray(acc_list).mean()
                    )
                )
        if self.args.get("plot_perturbed", False) and len(adv_tasks):
            self.plot_adv_task(adv_tasks, epoch)
        return np.asarray(loss_list), np.asarray(acc_list)

    def eval_loop(self, test_loader):
        """

        Args:
            test_loader (DataLoader): loader of a given number of episodes

        Returns:
            tuple(float, float, pd.DataFrame): resp. average loss and classification accuracy,
                and advanced evaluation statistics
        """
        acc_all = []
        loss_all = []
        evaluation_stats = []

        n_tasks = len(test_loader)
        for episode_index, (
            support_images,
            support_labels,
            query_images,
            query_labels,
            class_ids,
            source_domain,
            target_domain,
        ) in enumerate(test_loader):

            query_labels = set_device(query_labels)
            support_labels = set_device(support_labels)

            if self.use_test_query and \
              (self.adv_train_config is not None):
                loss_fn = self.transductive_loss_fn
                support_images, support_labels, query_images, query_labels, adv_tasks = self.adv_project(
                    'test', episode_index, support_images, support_labels, query_images, query_labels, loss_fn
                )

            scores = self.set_forward(
                support_images, support_labels, query_images
            ).detach()

            loss_value = self.loss_fn(scores, query_labels).detach().item()

            evaluation_stats.append(
                self.get_task_perf(
                    episode_index,
                    scores.cpu(),
                    query_labels.cpu().detach(),
                    class_ids,
                    source_domain,
                    target_domain,
                )
            )

            loss_all.append(loss_value)

            acc_all.append(self.evaluate(scores, query_labels) * 100)

        evaluations_stats_df = pd.concat(evaluation_stats, ignore_index=True)
        acc_all = np.asarray(acc_all)
        acc_mean = np.mean(acc_all)
        acc_std = np.std(acc_all)
        logger.info(
            "%d Test Accuracy = %4.2f%% +- %4.2f%%"
            % (n_tasks, acc_mean, confidence_interval(acc_std, n_tasks))
        )

        return np.asarray(loss_all), acc_all, evaluations_stats_df


import json

import graphene
from graphene_django import DjangoObjectType
from graphene_django.filter import DjangoFilterConnectionField

from helpers.constants import EventStatus
from helpers.utils import enum_to_dict
from services.authentication import GraphqlAuthentication

from .models import Event, FantasyPlayer, Marblelympics, PlayerEntry, Team

class TeamNode(DjangoObjectType):
    class Meta:
        model = Team
        interfaces = (graphene.relay.Node,)
        exclude_fields = ('image')
        filter_fields = {
            'name': ['exact', 'icontains', 'istartswith'],
            'ml_participated': ['exact'],
        }

class MLNode(DjangoObjectType):
    player_count = graphene.Int()

    class Meta:
        model = Marblelympics
        interfaces = (graphene.relay.Node,)
        filter_fields = {
            'active': ['exact'],
        }

    def resolve_player_count(self, info, **kwargs):
        return self.player_count

class SelectionNode(graphene.ObjectType):
    position = graphene.Int()
    team = graphene.Field(TeamNode)

class EventNode(DjangoObjectType):
    status = graphene.Int()
    entry_count = graphene.Int()
    results = graphene.List(SelectionNode)

    class Meta:
        model = Event
        interfaces = (graphene.relay.Node,)
        exclude_fields = ('scoring_status')
        filter_fields = {
            'ml__active': ['exact'],
        }

    def resolve_entry_count(self, info, **kwargs):
        return self.entry_count

    def resolve_results(self, info, **kwargs):
        results = json.loads(self.results)
        return [
            SelectionNode(
                position=int(position),
                team=Team.objects.get(name=name),
            )
            for position, name in results.items()
        ]

class FantasyPlayerNode(DjangoObjectType):
    class Meta:
        model = FantasyPlayer
        interfaces = (graphene.relay.Node,)
        filter_fields = {
            'marblelympics__active': ['exact'],
        }

class PlayerEntryNode(DjangoObjectType):
    selections = graphene.List(SelectionNode)

    class Meta:
        model = PlayerEntry
        interfaces = (graphene.relay.Node,)
        filter_fields = {
            'player__marblelympics__active': ['exact'],
        }

    def resolve_selections(self, info, **kwargs):
        selections = json.loads(self.selections)
        return [
            SelectionNode(
                position=int(position),
                team=Team.objects.get(name=name),
            )
            for position, name in selections.items()
        ]

class Query(graphene.ObjectType):
    team = graphene.relay.Node.Field(TeamNode)
    teams = DjangoFilterConnectionField(TeamNode)
    marblelympics = DjangoFilterConnectionField(MLNode)
    event = graphene.relay.Node.Field(EventNode)
    events = DjangoFilterConnectionField(EventNode)
    fplayer = graphene.relay.Node.Field(FantasyPlayerNode)
    fplayers = DjangoFilterConnectionField(FantasyPlayerNode)
    fplayer_entry = graphene.relay.Node.Field(PlayerEntryNode)
    fplayer_entries = DjangoFilterConnectionField(PlayerEntryNode)

class UpsertPlayerEntry(graphene.relay.ClientIDMutation):
    entry = graphene.Field(PlayerEntryNode)

    class Input:
        event_number = graphene.Int()
        team_1 = graphene.String()
        team_2 = graphene.String()
        team_3 = graphene.String()

    def mutate_and_get_payload(self, info, **input):
        user = GraphqlAuthentication.get_user(self, info, **input)
        player = user.player

        ml = Marblelympics.objects.filter(active=True).first()
        if not ml:
            raise Exception("No active ML")

        event = Event.objects.filter(
            ml=ml,
            number=input.get('event_number'),
        ).first()
        if not event:
            raise Exception(f"No event #{input.get('event_number')} in {ml}")
        if enum_to_dict(EventStatus).get(event.status, 1) == 'LOCKED':
            raise Exception(f"Event is locked")

        fplayer = FantasyPlayer.objects.filter(
            player=player,
            marblelympics=ml,
        ).first()
        if not fplayer:
            fplayer = FantasyPlayer.objects.create(
                player=player,
                marblelympics=ml,
            )

        entry = PlayerEntry.objects.filter(
            event=event, player=fplayer
        ).first() or PlayerEntry()

        entry.event = event
        entry.player = fplayer
        entry.selections = json.dumps(
            {
                '1': input.get('team_1') or '',
                '2': input.get('team_2') or '',
                '3': input.get('team_3') or '',
            }
        )
        entry.save()

        return UpsertPlayerEntry(entry=entry)

class Mutation(graphene.AbstractType):
    upsert_player_entry = UpsertPlayerEntry.Field()


import cv2
import imutils
import numpy as np
import pytesseract

# select video device
cap = cv2.VideoCapture(0)

while True:
    _, frame = cap.read()

    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    # apply filter and localization
    bfilter = cv2.bilateralFilter(gray, 11, 17, 17)  # Noise reduction
    edged = cv2.Canny(bfilter, 30, 200)  # Edge detection

    # find contours and apply mask
    keypoints = cv2.findContours(edged.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
    contours = imutils.grab_contours(keypoints)
    contours = sorted(contours, key=cv2.contourArea, reverse=True)[:10]

    location = None
    for contour in contours:
        approx = cv2.approxPolyDP(contour, 10, True)
        if len(approx) == 4:
            location = approx
            break
    # loop over our contours
    for contour in contours:
        # approximate the contour
        peri = cv2.arcLength(contour, True)
        approx = cv2.approxPolyDP(contour, 0.018 * peri, True)

        # if our approximated contour has four points, then
        # we can assume that we have found our screen
        if len(approx) == 4:
            location = approx
            break

    if location is None:
        detected = 0
        # print("No contour detected")
    else:
        detected = 1

    if detected == 1:
        cv2.drawContours(frame, [location], -1, (0, 255, 0), 3)

        mask = np.zeros(gray.shape, np.uint8)
        new_image = cv2.drawContours(mask, [location], 0, 255, 255)
        new_image = cv2.bitwise_and(frame, frame, mask=mask)

        # Now crop
        (x, y) = np.where(mask == 255)
        (topx, topy) = (np.min(x), np.min(y))
        (bottomx, bottomy) = (np.max(x), np.max(y))
        Cropped = gray[topx:bottomx + 1, topy:bottomy + 1]

        # Read the number plate
        text = pytesseract.image_to_string(Cropped, config='--psm 11')
        print("Detected Number is:", text)

    cv2.imshow("Camera", frame)

    if cv2.waitKey(1) == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()


from django.urls import path
from . import views
from django.conf.urls.static import static
from django.conf import settings

app_name = 'toko'

urlpatterns = [
     path('', views.HomeListView.as_view(), name = 'home'),
     path('product/<slug>/', views.ProductDetailView.as_view(), name='produk-detail'),
     path('checkout/', views.CheckoutView.as_view(), name='checkout'),
     path('add-to-cart/<slug>/', views.add_to_cart, name='add-to-cart'),
     path('remove_from_cart/<slug>/', views.remove_from_cart, name='remove-from-cart'),
     path('order-summary/', views.OrderSummaryView.as_view(), name='order-summary'),
     path('payment/<payment_method>', views.PaymentView.as_view(), name='payment'),
     path('paypal-return/', views.paypal_return, name='paypal-return'),
     path('paypal-cancel/', views.paypal_cancel, name='paypal-cancel'),
     path('about', views.about, name = "about"),
     path('contact', views.contact, name = "contact"),
     path('faq', views.faq, name = "faq"),
]

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


import argparse
import warnings

import termcolor
import torch

import models as model_module
import datasets as dataset_module
import models.loss as loss_module
import optimizers as optim_module
from trainer.trainer import Trainer
from torch.nn import DataParallel
import wandb
from config_parser import ConfigParser
from utils.utils import text_collate

parser = argparse.ArgumentParser()
parser.add_argument("--resume", default=False, action="store_true", help="resume training?")
parser.add_argument("--config", default="./config/bart.json", type=str, help="path to config file")
args = parser.parse_args()

def train(args):
    config = ConfigParser(args)

    device = 'cuda' if torch.cuda.is_available() else 'cpu'
    model = config.init_obj(model_module, "arch")
    if config['arch']['type'] == 'LSTMSentimentAnalysis':
        tokenizer = None
        collate_fn = None
    else:
        tokenizer = model.tokenizer
        collate_fn = lambda batch: text_collate(batch, tokenizer, device, max_seq_length=config['max_seq_length'])
    model = DataParallel(model).to(device)

    print(f"Model: {config['name']}, num params: {sum(p.numel() for p in model.parameters())}")

    train_set = config.init_obj(dataset_module, "train_set")
    test_set = config.init_obj(dataset_module, "test_set")

    train_loader = config.init_obj(torch.utils.data, "train_loader", dataset=train_set, collate_fn=collate_fn)
    test_loader = config.init_obj(torch.utils.data, "test_loader", dataset=test_set, collate_fn=collate_fn)

    optimizer = config.init_obj(optim_module, "optimizer", model.parameters())
    if isinstance(optimizer, optim_module.SAM):
        lr_scheduler = optim_module.get_lr_scheduler(optimizer.base_optimizer, config, train_loader)
    else:
        lr_scheduler = optim_module.get_lr_scheduler(optimizer, config, train_loader)
    criterion = config.init_obj(loss_module, "criterion")

    trainer = Trainer(model=model,
                      config=config,
                      criterion=criterion,
                      optimizer=optimizer,
                      device=device,
                      train_loader=train_loader,
                      test_loader=test_loader,
                      lr_scheduler=lr_scheduler,
                      logger=True)
    trainer.train(resume=args.resume)

if __name__ == "__main__":
    wandb.init(project="BART-sentiment-analysis")
    warnings.filterwarnings('ignore')
    train(args)


import site
site.addsitedir("../../../PDFNetC/Lib")
import sys
from PDFNetPython import *

sys.path.append("../../LicenseKey/PYTHON")
from LicenseKey import *

def main():
    PDFNet.Initialize(LicenseKey)

    # Relative path to the folder containing the test files.
    input_path = "../../TestFiles/"
    output_path = "../../TestFiles/Output/"

	# Sample 1 - Split a PDF document into multiple pages
    print("_______________________________________________")
    print("Sample 1 - Split a PDF document into multiple pages...")
    print("Opening the input pdf...")
    in_doc=PDFDoc(input_path + "newsletter.pdf")
    in_doc.InitSecurityHandler()

    page_num = in_doc.GetPageCount()
    i = 1
    while i<=page_num:
        new_doc=PDFDoc()
        new_doc.InsertPages(0, in_doc, i, i, PDFDoc.e_none)
        new_doc.Save(output_path + "newsletter_split_page_" + str(i) + ".pdf", SDFDoc.e_remove_unused)
        print("Done. Result saved in newsletter_split_page_" + str(i) + ".pdf")
        new_doc.Close()
        i = i + 1

    # Close the open document to free up document memory sooner than waiting for the
    # garbage collector
    in_doc.Close()

    # Sample 2 - Merge several PDF documents into one
    print("_______________________________________________")
    print("Sample 2 - Merge several PDF documents into one...")
    new_doc=PDFDoc()
    new_doc.InitSecurityHandler()

    page_num = 15
    i = 1
    while i <= page_num:
        print("Opening newsletter_split_page_" + str(i) + ".pdf")
        in_doc=PDFDoc(output_path + "newsletter_split_page_" + str(i) + ".pdf")
        new_doc.InsertPages(i, in_doc, 1, in_doc.GetPageCount(), PDFDoc.e_none)
        in_doc.Close()
        i = i + 1

    new_doc.Save(output_path + "newsletter_merge_pages.pdf", SDFDoc.e_remove_unused)
    print("Done. Result saved in newsletter_merge_pages.pdf");

    # Close the open document to free up document memory sooner than waiting for the
    # garbage collector
    in_doc.Close()

    # Sample 3 - Delete every second page
    print("_______________________________________________")
    print("Sample 3 - Delete every second page...")
    print("Opening the input pdf...")
    in_doc = PDFDoc(input_path +  "newsletter.pdf")
    in_doc.InitSecurityHandler();
    page_num = in_doc.GetPageCount()

    while page_num >= 1:
        itr = in_doc.GetPageIterator(page_num)
        in_doc.PageRemove(itr)
        page_num = page_num - 2

    in_doc.Save(output_path +  "newsletter_page_remove.pdf", 0)
    print("Done. Result saved in newsletter_page_remove.pdf...")

    # Close the open document to free up document memory sooner than waiting for the
    # garbage collector
    in_doc.Close()

    # Sample 4 - Inserts a page from one document at different
    # locations within another document
    print("_______________________________________________")
    print("Sample 4 - Insert a page at different locations...")
    print("Opening the input pdf...")

    in1_doc = PDFDoc(input_path +  "newsletter.pdf")
    in1_doc.InitSecurityHandler()
    in2_doc = PDFDoc(input_path +  "fish.pdf")
    in2_doc.InitSecurityHandler()

    src_page = in2_doc.GetPageIterator()
    dst_page = in1_doc.GetPageIterator()
    page_num = 1
    while dst_page.HasNext():
        if page_num % 3 == 0:
            in1_doc.PageInsert(dst_page, src_page.Current())
        page_num = page_num + 1
        dst_page.Next()
    in1_doc.Save(output_path +  "newsletter_page_insert.pdf", 0)
    print("Done. Result saved in newsletter_page_insert.pdf...")

    # Close the open document to free up document memory sooner than waiting for the
    # garbage collector
    in1_doc.Close()
    in2_doc.Close()

    # Sample 5 - Replicate pages within a single document
    print("_______________________________________________")
    print("Sample 5 - Replicate pages within a single document...")
    print("Opening the input pdf...")

    doc = PDFDoc(input_path + "newsletter.pdf")
    doc.InitSecurityHandler()

    # Replicate the cover page three times (copy page #1 and place it before the
    # seventh page in the document page sequence)
    cover = doc.GetPage(1)
    p7 = doc.GetPageIterator(7)
    doc.PageInsert(p7, cover)
    doc.PageInsert(p7, cover)
    doc.PageInsert(p7, cover)

    # Replicate the cover page two more times by placing it before and after
    # existing pages.
    doc.PagePushFront(cover);
    doc.PagePushBack(cover)

    doc.Save(output_path +  "newsletter_page_clone.pdf", 0)
    print("Done. Result saved in newsletter_page_clone.pdf...")
    doc.Close()

    # Sample 6 - Use ImportPages() in order to copy multiple pages at once
    # in order to preserve shared resources between pages (e.g. images, fonts,
    # colorspaces, etc.)
    print("_______________________________________________")
    print("Sample 6 - Preserving shared resources using ImportPages...")
    print("Opening the input pdf...")
    in_doc = PDFDoc(input_path +  "newsletter.pdf")
    in_doc.InitSecurityHandler()
    new_doc = PDFDoc()
    copy_pages = VectorPage()
    itr = in_doc.GetPageIterator()
    while itr.HasNext():
        copy_pages.push_back(itr.Current())
        itr.Next()

    imported_pages = new_doc.ImportPages(copy_pages)
    i = iter(imported_pages)
    for x in i:
        new_doc.PagePushFront(x)    # Order pages in reverse order.
        # Use PagePushBack() if you would like to preserve the same order.

    new_doc.Save(output_path +  "newsletter_import_pages.pdf", 0)

    # Close the open document to free up document memory sooner than waiting for the
    # garbage collector
    in_doc.Close()
    new_doc.Close()

    PDFNet.Terminate()

    print("Done. Result saved in newsletter_import_pages.pdf...\n")
    print("Note that the output file size is less than half the size")
    print("of the file produced using individual page copy operations")
    print("between two documents")

if __name__ == '__main__':
    main()


import pyttsx3
import speech_recognition as sr
import datetime
import wikipedia
import os

import webbrowser

engine = pyttsx3.init('sapi5')
voices = engine.getProperty('voices')
#print(voices[0].id)
engine.setProperty('voice',voices[1].id)

def wishMe():
    hour = int(datetime.datetime.now().hour)
    if hour>=0 and hour<12:
        speak("Good Morning")
    elif hour>=12 and hour<18:
        speak("Good Afternoon")
    else:
        speak("Good Evening")
    speak(" Sir Im Jarvis")

def speak(audio):
    engine.say(audio)
    engine.runAndWait()

def takeCommand():
    r=sr.Recognizer()
    with sr.Microphone() as source:
        print("hearing....")
        r.pause_threshold = 1
        audio = r.listen(source)

    try:
        print("recognizing")
        query = r.recognize_google(audio, language = 'en-in')
        print(f"user said: {query}\n")

    except Exception as e:
        # print(e) hiding error

        print("can you please speak again sir")
        return "None"
        #return string none
    return query

if __name__ == "__main__":

    wishMe()
    speak("yash is a good f boy")
    print("hi")
    query = takeCommand().lower()

    if 'wikepedia' in query:
        speak("searching wiki")
        query = query.replace("wikipedia","")
        results = wikipedia.summary(query, sentences=2)
        speak("according to wiki")
        print(results)
        speak(results)

    elif 'open' in query:
        if 'youtube' in query:
            webbrowser.open("youtube.com")
        elif 'google' in query:
            webbrowser.open("google.com")
        elif 'facebook' in query:
            webbrowser.open("fb.com")
        elif 'instagram' in query:
            webbrowser.open("instagram.com")
        elif 'facebook' in query:
            webbrowser.open("fb.com")


from __future__ import (absolute_import, division, print_function,
                        unicode_literals) # python 2 as python 3
import numpy as np
from astropy.table import Table#, Column
from astropy.time import Time, TimeDelta
from astropy.units import Quantity

# create an astrotable with a column of integers
n_obs = 10 # number of rows
n_obs_start = 1 # start counting at 1
astro_table = Table()
obs_id = np.arange(n_obs_start, n_obs_start + n_obs)
astro_table['OBS_ID'] = obs_id

# try Time and TimeDelta columns

# start time
# random points between the start of 2010 and the end of 2014
datestart = Time('2010-01-01 00:00:00', format='iso', scale='utc')
dateend = Time('2015-01-01 00:00:00', format='iso', scale='utc')
time_start = Time((dateend.mjd - datestart.mjd)*np.random.random(len(obs_id)) + datestart.mjd, format='mjd', scale='utc').iso
astro_table['TSTART'] = time_start

# on time: 30 min
ontime = TimeDelta(30.*60.*np.ones_like(obs_id), format='sec')
#col_ontime = Column(name='ONTIME', data=ontime) #faulty!
#astro_table.add_column(col_ontime)
astro_table['ONTIME'] = ontime #works fine, but still no unit showing in the column
# ref: https://github.com/astropy/astropy/issues/3832

# try Quantity instead of TimeDelta quantity

# livetime: 25 min
livetime = Quantity(25.*60.*np.ones_like(obs_id), 'second')
astro_table['LIVETIME'] = livetime

print("astro_table")
print(astro_table)

print()

print("type time col", type(astro_table['TSTART']))
print("type timedelta col", type(astro_table['ONTIME']))
print("type quantity col", type(astro_table['LIVETIME']))

# read columns from the table
#import IPython; IPython.embed() # before error line
time_col = Time(astro_table['TSTART']) # works fine
timedelta_col = TimeDelta(astro_table['ONTIME']) # used to give an error
quantity_col = TimeDelta(astro_table['LIVETIME']) # works fine

print()

#print(time_col.__dict__)
#print(timedelta_col.__dict__) # used to be faulty
#print(quantity_col.__dict__)

print(repr(time_col))
print(repr(timedelta_col)) # used to be faulty
print(repr(quantity_col))


import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.distributions as tdist
from network.mobilenet import mobilenet_v2
import numpy as np

class NetForecaster(nn.Module):
    def __init__(self, batch_size=8, ND=3, hidden_size=256, input_size=300, input_num_frame=3):
        super(NetForecaster, self).__init__()
        # some hypeparameters
        self.batch_size = batch_size
        self.ND = ND
        self.input_size = input_size
        self.input_num_frame = input_num_frame
        self.hidden_size = hidden_size
        self.tanh = nn.Tanh()
        self.representation = None

        # allocate model parameters
        self.backbone = mobilenet_v2(num_classes=hidden_size)
        self.backbone_pva = nn.Sequential(
            nn.Linear(3 * ND + 2, 128),
            nn.Tanh(),
            nn.Linear(128, 256),
            nn.Tanh(),
            nn.Linear(256, hidden_size),
            nn.Tanh(),
        )
        self.fc1 = nn.Linear(hidden_size * 2, hidden_size)
        self.final_p = nn.Sequential(
            nn.Linear(hidden_size, hidden_size // 2),
            nn.Tanh(),
            nn.Linear(hidden_size // 2, hidden_size // 4),
            nn.Tanh(),
            nn.Linear(hidden_size // 4, ND),
        )
        self.final_v = nn.Sequential(
            nn.Linear(hidden_size, hidden_size // 2),
            nn.Tanh(),
            nn.Linear(hidden_size // 2, hidden_size // 4),
            nn.Tanh(),
            nn.Linear(hidden_size // 4, ND),
        )
        self.final_a = nn.Sequential(
            nn.Linear(hidden_size, hidden_size // 2),
            nn.Tanh(),
            nn.Linear(hidden_size // 2, hidden_size // 4),
            nn.Tanh(),
            nn.Linear(hidden_size // 4, ND),
        )

    def forward(self, x, pos, vel, acc, agent_angle_y, agent_angle_xz):
        # resort the three frames along batch dimension
        x = x.view(self.batch_size, self.input_num_frame * 3, self.input_size, self.input_size)

        # do forward through CNN
        x = self.tanh(self.backbone(x))

        # do forward through FC on agent's position
        agent_angle_y = agent_angle_y.unsqueeze(1)
        agent_angle_xz = agent_angle_xz.unsqueeze(1)
        inp_pva = torch.cat([pos, vel, acc, agent_angle_y, agent_angle_xz], dim=1)
        out_pva = self.backbone_pva(inp_pva)

        # concat image_rep with pos_rep
        x = torch.cat((x, out_pva), dim=1)

        # do one more FC
        output = self.tanh(self.fc1(x))
        self.representation = output.clone()
        output_p = self.final_p(output).view(self.batch_size, self.ND)
        output_v = self.final_v(output).view(self.batch_size, self.ND)
        output_a = self.final_a(output).view(self.batch_size, self.ND)
        return output_p, output_v, output_a, self.representation

    def forecast(self, pos, v, a, t):
        output = []
        for _ in range(t):
            pos = pos + v
            v = v + a
            output.append(pos)
        output = torch.cat(output, 0)
        return output

class NetPolicy(nn.Module):
    def __init__(self, batch_size=8, n_dims=3, hidden_size=256, AD=41):
        super(NetPolicy, self).__init__()
        # some hypeparameters
        self.batch_size = batch_size
        self.n_dims = n_dims
        self.hidden_size = hidden_size
        self.AD = AD
        self.Tanh = nn.Tanh()
        self.representation = None

        # allocate model parameters
        self.backbone = nn.Sequential(
                nn.Linear(3 * n_dims, 64),
                nn.Tanh(),
                nn.Linear(64, 128),
                nn.Tanh(),
                nn.Linear(128, hidden_size),
                nn.Tanh(),
            )
        self.embed = nn.Linear(hidden_size * 2, hidden_size)
        self.final_v = nn.Sequential(
            nn.Linear(hidden_size, hidden_size // 2),
            nn.Tanh(),
            nn.Linear(hidden_size // 2, hidden_size // 4),
            nn.Tanh(),
            nn.Linear(hidden_size // 4, 1),
        )
        self.final_a = nn.Sequential(
            nn.Linear(hidden_size, hidden_size // 2),
            nn.Tanh(),
            nn.Linear(hidden_size // 2, hidden_size // 4),
            nn.Tanh(),
            nn.Linear(hidden_size // 4, n_dims),
        )
        self.final_a2 = nn.Sequential(
            nn.Linear(hidden_size, hidden_size // 2),
            nn.Tanh(),
            nn.Linear(hidden_size // 2, hidden_size // 4),
            nn.Tanh(),
            nn.Linear(hidden_size // 4, n_dims),
            nn.Softplus(),
        )

    def forward(self, x, r):
        self.representation = self.backbone(x)
        if r.shape[0] != len(self.representation):
            r = r.repeat(len(self.representation), 1)
        self.representation = torch.cat((r, self.representation), dim=1)
        self.representation = self.Tanh(self.embed(self.representation))
        action_dist = self.final_a(self.representation)
        action_dist_2 = self.final_a2(self.representation) + 0.001
        value = self.final_v(self.representation)
        return value, action_dist, action_dist_2

class DroneModel(nn.Module):
    def __init__(self, batch_size=8, n_dims=1, hidden_size=0, frequency=0.02, cuda=False, gpu_id=0):
        super(DroneModel, self).__init__()
        # some hypeparameters
        self.batch_size = batch_size
        self.n_dims = n_dims
        self.vel = torch.zeros(batch_size, n_dims)
        self.frequency = frequency
        self.cuda_enable = cuda
        if self.cuda_enable:
            self.vel = self.vel.cuda(gpu_id)
        self.gpu_id = gpu_id

    def forward(self, x):
        x = x.view(self.batch_size, -1, self.n_dims)
        if self.vel.shape[0] != self.batch_size:
            self.vel = self.vel.repeat(self.batch_size, 1)
        self.vel += x[:, 1, :]
        s = (x[:, 0, :] + self.vel * self.frequency)
        return s

    def reset_vel(self):
        self.vel = torch.zeros(self.batch_size, self.n_dims)
        if self.cuda_enable:
            self.vel = self.vel.cuda(self.gpu_id)


from define import *

@app.route('/dept', methods=['GET','POST'])
def dept():
    deptform = Deptform()
    dept_name = deptform.deptname.data
    dept_class = deptform.deptclass.data
    dept_bed = deptform.deptbed.data
    deptifexist = Department.query.filter_by(name=dept_name).first()
    if deptform.submit.data and deptform.is_submitted():
        if deptifexist:
            flash('科室已存在')
        else:
            try:
                new_dept = Department(name=dept_name, classname = dept_class, bednumber = dept_bed)
                db.session.add(new_dept)
                db.session.commit()
                flash('科室添加成功')
            except BaseException as e:
                print(e)
                flash('添加科室失败,回滚数据')
                db.session.rollback()
    elif deptform.submit2.data and deptform.is_submitted():
        if deptifexist:
            try:
                Department.query.filter(Department.name == dept_name).delete()
                # del_dept = Department(name=dept_name, classname = dept_class, bednumber = dept_bed)
                # db.session.delete(del_dept)
                db.session.commit()
                flash('删除科室成功')
            except Exception as e:
                print(e)
                flash('删除科室失败,回滚数据')
                db.session.rollback()
    elif deptform.submit3.data and deptform.is_submitted():
        if deptifexist:
            try:
                # mod_data=Department.query.filter_by(Department.name == dept_name).first()
                # deptifexist.name=dept_name
                deptifexist.classname = dept_class
                deptifexist.bednumber = dept_bed
                db.session.commit()
                flash('修改科室成功')
            except Exception as e:
                print(e)
                flash('修改科室失败,回滚数据')
                db.session.rollback()
    depts = Department.query.all()
    return render_template('dept.html', depts=depts, deptform=deptform)

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


import os
import sys
import numpy as np

sys.path.append(f"JPG_Decoder")
from JPG_Decoder.jpg_decoder import JPGImage

import pickle
import base64
import zlib

def pack(v):
    return zlib.compress(base64.b64encode(pickle.dumps(v)))

def unpack(v):
    return pickle.loads(base64.b64decode(zlib.decompress(v)))

fpath="cropped"
imgl=os.listdir(fpath)
# out_path="DCresults"

def getDC(file):
    with open(file,"rb") as f:
        jpg=JPGImage(f)
        jpg.read_header()
        jpg.read_data()
        jpg.decode_huffman_data()
        return jpg.DC
result={}
for img in imgl:
    if img.endswith(".jpg") and "Green" in img:
        dc=getDC(os.path.join(fpath,img))
        result[img]=dc
        print(img)

with open("Button_results","wb") as f:
    f.write(pack(result))