# ========================== Third Party libs ========================
from typing import List
import torch
from transformers import LogitsProcessor
import scipy.stats
from math import sqrt
from itertools import chain, tee
import collections
# ============================ My packages ============================
from .hash_functions import prf_lookup, seeding_scheme_lookup

class WatermarkBase:
    def __init__(
            self,
            vocab: List[int] = None,
            gamma: float = 0.5,
            delta: float = 2.0,
            seeding_scheme: str = "simple_1",
            # simple default, find more schemes in alternative_prf_schemes.py
            select_green_tokens: bool = True,
            # should always be the default if not running in legacy mode
    ):
        # patch now that None could now maybe be passed as seeding_scheme
        if seeding_scheme is None:
            seeding_scheme = "simple_1"

        self.seeding_scheme = seeding_scheme
        # Vocabulary setup
        self.vocab = vocab
        self.vocab_size = len(vocab)

        # Watermark behavior:
        self.gamma = gamma
        self.delta = delta
        self.rng = None
        self._initialize_seeding_scheme(seeding_scheme)
        # Legacy behavior:
        self.select_green_tokens = select_green_tokens

    def _initialize_seeding_scheme(self, seeding_scheme: str) -> None:
        """Initialize all internal settings of the seeding strategy from a colloquial,
        "public" name for the scheme."""
        self.prf_type, self.context_width, self.self_salt, self.hash_key = seeding_scheme_lookup(
            seeding_scheme)

    def _seed_rng(self, input_ids: torch.LongTensor) -> None:
        """Seed RNG from local context. Not batched, because the generators we use
        (like cuda.random) are not batched."""
        # Need to have enough context for seed generation
        if input_ids.shape[-1] < self.context_width:
            raise ValueError(
                f"seeding_scheme requires at least a {self.context_width} token "
                f"prefix to seed the RNG."
            )

        prf_key = prf_lookup[self.prf_type](
            input_ids[-self.context_width:], salt_key=self.hash_key
        )
        # enable for long, interesting streams of pseudorandom numbers: print(prf_key)
        self.rng.manual_seed(prf_key % (2 ** 64 - 1))  # safeguard against overflow from long

    def _get_greenlist_ids(self, input_ids: torch.LongTensor) -> torch.LongTensor:
        """Seed rng based on local context width and use this information to
        generate ids on the green list."""
        self._seed_rng(input_ids)

        greenlist_size = int(self.vocab_size * self.gamma)
        vocab_permutation = torch.randperm(
            self.vocab_size, device=input_ids.device, generator=self.rng
        )
        if self.select_green_tokens:  # directly
            greenlist_ids = vocab_permutation[:greenlist_size]  # new
        else:  # select green via red
            greenlist_ids = vocab_permutation[
                            (self.vocab_size - greenlist_size):
                            ]  # legacy behavior
        return greenlist_ids

class WatermarkLogitsProcessor(WatermarkBase, LogitsProcessor):
    """LogitsProcessor modifying model output scores in a pipe. Can be used in any HF pipeline
    to modify scores to fit the watermark, but can also be used as a standalone tool inserted
    for any model producing scores in between model outputs and next token sampler.
    """

    def __init__(self, *args, store_spike_ents: bool = False, **kwargs):
        super().__init__(*args, **kwargs)

        self.store_spike_ents = store_spike_ents
        self.spike_entropies = None
        if self.store_spike_ents:
            self._init_spike_entropies()

    def _init_spike_entropies(self):
        alpha = torch.exp(torch.tensor(self.delta)).item()
        gamma = self.gamma

        self.z_value = ((1 - gamma) * (alpha - 1)) / (1 - gamma + (alpha * gamma))
        self.expected_gl_coef = (gamma * alpha) / (1 - gamma + (alpha * gamma))

        # catch for overflow when bias is "infinite"
        if alpha == torch.inf:
            self.z_value = 1.0
            self.expected_gl_coef = 1.0

    def _get_spike_entropies(self):
        spike_ents = [[] for _ in range(len(self.spike_entropies))]
        for b_idx, ent_tensor_list in enumerate(self.spike_entropies):
            for ent_tensor in ent_tensor_list:
                spike_ents[b_idx].append(ent_tensor.item())
        return spike_ents

    def _get_and_clear_stored_spike_ents(self):
        spike_ents = self._get_spike_entropies()
        self.spike_entropies = None
        return spike_ents

    def _compute_spike_entropy(self, scores):
        # precomputed z value in init
        probs = scores.softmax(dim=-1)
        denoms = 1 + (self.z_value * probs)
        renormed_probs = probs / denoms
        sum_renormed_probs = renormed_probs.sum()
        return sum_renormed_probs

    def _calc_greenlist_mask(
            self, scores: torch.FloatTensor, greenlist_token_ids
    ) -> torch.BoolTensor:
        # Cannot lose loop, greenlists might have different lengths
        green_tokens_mask = torch.zeros_like(scores, dtype=torch.bool)
        for b_idx, greenlist in enumerate(greenlist_token_ids):
            if len(greenlist) > 0:
                green_tokens_mask[b_idx][greenlist] = True
        return green_tokens_mask

    def _bias_greenlist_logits(
            self, scores: torch.Tensor, greenlist_mask: torch.Tensor, greenlist_bias: float
    ) -> torch.Tensor:
        scores[greenlist_mask] = scores[greenlist_mask] + greenlist_bias
        return scores

    def _score_rejection_sampling(
            self, input_ids: torch.LongTensor, scores: torch.FloatTensor, tail_rule="fixed_compute"
    ) -> List[int]:
        """Generate greenlist based on current candidate next token. Reject and move on if
        necessary. Method not batched.
        This is only a partial version of Alg.3 "Robust Private Watermarking", as it always
        assumes greedy sampling. It will still (kinda)
        work for all types of sampling, but less effectively.
        To work efficiently, this function can switch between a number of rules for handling the
        distribution tail.
        These are not exposed by default.
        """
        sorted_scores, greedy_predictions = scores.sort(dim=-1, descending=True)

        final_greenlist = []
        for idx, prediction_candidate in enumerate(greedy_predictions):
            greenlist_ids = self._get_greenlist_ids(
                torch.cat([input_ids, prediction_candidate[None]], dim=0)
            )  # add candidate to prefix
            if prediction_candidate in greenlist_ids:  # test for consistency
                final_greenlist.append(prediction_candidate)

            # What follows below are optional early-stopping rules for efficiency
            if tail_rule == "fixed_score":
                if sorted_scores[0] - sorted_scores[idx + 1] > self.delta:
                    break
            elif tail_rule == "fixed_list_length":
                if len(final_greenlist) == 10:
                    break
            elif tail_rule == "fixed_compute":
                if idx == 40:
                    break
            else:
                pass  # do not break early
        return torch.as_tensor(final_greenlist, device=input_ids.device)

    def __call__(self, input_ids: torch.LongTensor, scores: torch.FloatTensor) -> torch.FloatTensor:
        """Call with previous context as input_ids, and scores for next token."""

        # this is lazy to allow us to co-locate on the watermarked model's device
        self.rng = torch.Generator(device=input_ids.device) if self.rng is None else self.rng

        # NOTE, it would be nice to get rid of this batch loop, but currently,
        # the seed and partition operations are not tensor/vectorized, thus
        # each sequence in the batch needs to be treated separately.

        list_of_greenlist_ids = [None for _ in input_ids]  # Greenlists could differ in length
        for b_idx, input_seq in enumerate(input_ids):
            if self.self_salt:
                greenlist_ids = self._score_rejection_sampling(input_seq, scores[b_idx])
            else:
                greenlist_ids = self._get_greenlist_ids(input_seq)
            list_of_greenlist_ids[b_idx] = greenlist_ids

            # logic for computing and storing spike entropies for analysis
            if self.store_spike_ents:
                if self.spike_entropies is None:
                    self.spike_entropies = [[] for _ in range(input_ids.shape[0])]
                self.spike_entropies[b_idx].append(self._compute_spike_entropy(scores[b_idx]))

        green_tokens_mask = self._calc_greenlist_mask(
            scores=scores, greenlist_token_ids=list_of_greenlist_ids
        )
        scores = self._bias_greenlist_logits(
            scores=scores, greenlist_mask=green_tokens_mask, greenlist_bias=self.delta
        )

        return scores

class WatermarkDetector(WatermarkBase):
    def __init__(
            self,
            *args,
            device: torch.device = None,
            tokenizer=None,
            z_threshold: float = 4.0,
            ignore_repeated_bigrams: bool = False,
            **kwargs,
    ):
        super().__init__(*args, **kwargs)
        # also configure the metrics returned/preprocessing options
        assert device, "Must pass device"
        assert tokenizer, "Need an instance of the generating tokenizer to perform detection"

        self.tokenizer = tokenizer
        self.device = device
        self.z_threshold = z_threshold
        self.rng = torch.Generator(device=self.device)

        if self.seeding_scheme == "simple_1":
            self.min_prefix_len = 1
        else:
            raise NotImplementedError(f"Unexpected seeding_scheme: {self.seeding_scheme}")

        self.ignore_repeated_bigrams = ignore_repeated_bigrams
        if self.ignore_repeated_bigrams:
            assert self.seeding_scheme == "simple_1", "No repeated bigram credit variant assumes " \
                                                      "the single token seeding scheme."

    def _compute_z_score(self, observed_count, T):
        # count refers to number of green tokens, T is total number of tokens
        expected_count = self.gamma
        numer = observed_count - expected_count * T
        denom = sqrt(T * expected_count * (1 - expected_count))
        z = numer / denom
        return z

    def _compute_p_value(self, z):
        p_value = scipy.stats.norm.sf(z)
        return p_value

    def _score_sequence(
            self,
            input_ids: torch.Tensor,
            return_num_tokens_scored: bool = True,
            return_num_green_tokens: bool = True,
            return_green_fraction: bool = True,
            return_green_token_mask: bool = False,
            return_z_score: bool = True,
            return_p_value: bool = True,
    ):
        if self.ignore_repeated_bigrams:
            # Method that only counts a green/red hit once per unique bigram.
            # New num total tokens scored (T) becomes the number unique bigrams.
            # We iterate over all unqiue token bigrams in the input, computing the greenlist
            # induced by the first token in each, and then checking whether the second
            # token falls in that greenlist.
            assert return_green_token_mask == False, "Can't return the green/red mask when " \
                                                     "ignoring repeats."
            bigram_table = {}
            token_bigram_generator = ngrams(input_ids.cpu().tolist(), 2)
            freq = collections.Counter(token_bigram_generator)
            num_tokens_scored = len(freq.keys())
            for idx, bigram in enumerate(freq.keys()):
                prefix = torch.tensor([bigram[0]],
                                      device=self.device)  # expects a 1-d prefix tensor on
                # the randperm device
                greenlist_ids = self._get_greenlist_ids(prefix)
                bigram_table[bigram] = True if bigram[1] in greenlist_ids else False
            green_token_count = sum(bigram_table.values())
        else:
            num_tokens_scored = len(input_ids) - self.min_prefix_len
            if num_tokens_scored < 1:
                raise ValueError((f"Must have at least {1} token to score after "
                                  f"the first min_prefix_len={self.min_prefix_len} tokens required "
                                  f"by the seeding scheme."))
            # Standard method.
            # Since we generally need at least 1 token (for the simplest scheme)
            # we start the iteration over the token sequence with a minimum
            # num tokens as the first prefix for the seeding scheme,
            # and at each step, compute the greenlist induced by the
            # current prefix and check if the current token falls in the greenlist.
            green_token_count, green_token_mask = 0, []
            for idx in range(self.min_prefix_len, len(input_ids)):
                curr_token = input_ids[idx]
                greenlist_ids = self._get_greenlist_ids(input_ids[:idx])
                if curr_token in greenlist_ids:
                    green_token_count += 1
                    green_token_mask.append(True)
                else:
                    green_token_mask.append(False)

        score_dict = dict()
        if return_num_tokens_scored:
            score_dict.update(dict(num_tokens_scored=num_tokens_scored))
        if return_num_green_tokens:
            score_dict.update(dict(num_green_tokens=green_token_count))
        if return_green_fraction:
            score_dict.update(dict(green_fraction=(green_token_count / num_tokens_scored)))
        if return_z_score:
            score_dict.update(
                dict(z_score=self._compute_z_score(green_token_count, num_tokens_scored)))
        if return_p_value:
            z_score = score_dict.get("z_score")
            if z_score is None:
                z_score = self._compute_z_score(green_token_count, num_tokens_scored)
            score_dict.update(dict(p_value=self._compute_p_value(z_score)))
        if return_green_token_mask:
            score_dict.update(dict(green_token_mask=green_token_mask))

        return score_dict

    def detect(
            self,
            text: str = None,
            tokenized_text: List[int] = None,
            return_prediction: bool = True,
            return_scores: bool = True,
            z_threshold: float = None,
            **kwargs,
    ) -> dict:

        assert (text is not None) ^ (
                tokenized_text is not None), "Must pass either the raw or tokenized string"
        if return_prediction:
            kwargs[
                "return_p_value"] = True  # to return the "confidence":=1-p of positive detections

        if tokenized_text is None:
            assert self.tokenizer is not None, (
                "Watermark detection on raw string ",
                "requires an instance of the tokenizer ",
                "that was used at generation time.",
            )
            tokenized_text = \
                self.tokenizer(text, return_tensors="pt", add_special_tokens=False)["input_ids"][
                    0].to(
                    self.device)
            if tokenized_text[0] == self.tokenizer.bos_token_id:
                tokenized_text = tokenized_text[1:]
        else:
            # try to remove the bos_tok at beginning if it's there
            if (self.tokenizer is not None) and (tokenized_text[0] == self.tokenizer.bos_token_id):
                tokenized_text = tokenized_text[1:]

        # call score method
        output_dict = {}
        score_dict = self._score_sequence(tokenized_text, **kwargs)
        if return_scores:
            output_dict.update(score_dict)
        # if passed return_prediction then perform the hypothesis test and return the outcome
        if return_prediction:
            z_threshold = z_threshold if z_threshold else self.z_threshold
            assert z_threshold is not None, "Need a threshold in order to decide outcome of detection test"
            output_dict["prediction"] = score_dict["z_score"] > z_threshold
            if output_dict["prediction"]:
                output_dict["confidence"] = 1 - score_dict["p_value"]

        return output_dict

def ngrams(sequence, n, pad_left=False, pad_right=False, pad_symbol=None):
    sequence = iter(sequence)
    if pad_left:
        sequence = chain((pad_symbol,) * (n - 1), sequence)
    if pad_right:
        sequence = chain(sequence, (pad_symbol,) * (n - 1))
    iterables = tee(sequence, n)

    for i, sub_iterable in enumerate(iterables):  # For each window,
        for _ in range(i):  # iterate through every order of ngrams
            next(sub_iterable, None)  # generate the ngrams within the window.
    return zip(*iterables)  # Unpack and flattens the iterables.

def load_detector(tokenizer, args):
    # device = "cuda" if (args.use_gpu and torch.cuda.is_available()) else "cpu"

    watermark_detector = WatermarkDetector(
        vocab=list(tokenizer.get_vocab().values()),
        gamma=args.gamma,
        seeding_scheme=args.seeding_scheme,
        device=args.device,
        tokenizer=tokenizer,
        z_threshold=args.detection_z_threshold)

    return watermark_detector


import os

os.system("clear")

def print_header():
    print("Welcome to Tic-Tac-Toe\n")

class Game:
    def __init__(self):
        self.cells = [" ", " ", " ", " ", " ", " ", " ", " ", " "]
        self.playerX = "playerX"
        self.playerO = "playerO"

    def start(self):
        print_header()
        print("  - Please Enter the Name of the Players -")
        self.playerX = str(input("Player1(X) : "))
        self.playerO = str(input("Player2(O) : "))

        while self.playerO == self.playerX:
            os.system("clear")
            print_header()
            print("  - Please Enter the Name of the Players -")
            print("Player1(X) : " + str(self.playerX))
            print("\n\"%s\" is taken, Please choose another name: " % self.playerX)
            self.playerO = str(input("Player2(O) : "))

    def display(self):
        print(" %s | %s | %s " % (self.cells[0], self.cells[1], self.cells[2]))
        print("-----------")
        print(" %s | %s | %s " % (self.cells[3], self.cells[4], self.cells[5]))
        print("-----------")
        print(" %s | %s | %s " % (self.cells[6], self.cells[7], self.cells[8]))

    def update(self, cell_no, player):  # test: cell_no ?= int, player X or O
        player = "X" if player is self.playerX else "O"
        if self.cells[cell_no] == " ":
            self.cells[cell_no] = player

    def refresh(self):
        # Clears the screen
        os.system("clear")

        # prints the header
        print_header()

        # Shows the board
        self.display()

    def is_winner(self, player):

        player = "X" if player is self.playerX else "O"
        for x, y, z in [[0, 1, 2], [3, 4, 5], [6, 7, 8], [0, 3, 6], [1, 4, 7], [2, 5, 8], [0, 4, 8], [2, 4, 6]]:
            if self.cells[x] == self.cells[y] == self.cells[z]:
                if self.cells[x] == player:  # is "X" or "O": # maybe test
                    return True

        return False

    def is_tie(self):
        for cell in self.cells:
            if cell == " ":
                return False

        return True

    def whose_turn(self):
        x = self.cells.count("X")
        o = self.cells.count("O")

        if x == o:
            return self.playerX
        else:
            return self.playerO

    def reset(self):
        self.cells = [" ", " ", " ", " ", " ", " ", " ", " ", " "]


'''
https://leetcode.com/problems/sort-an-array/
Given an array of integers nums, sort the array in ascending order.

Example 1:
Input: nums = [5,2,3,1]
Output: [1,2,3,5]
'''
'''
Time:
Space:
'''
class Solution:
    def sortArray(self, nums: List[int]) -> List[int]:
        def quicksort(nums, left, right):
            if left>=right:
                return
            pivot = nums[right]
            i = left-1
            for j in range(left, right):
                if nums[j]<=pivot:
                    i += 1
                    nums[i], nums[j] = nums[j], nums[i]
            nums[i+1], nums[right] = nums[right], nums[i+1]
            quicksort(nums, left, i)
            quicksort(nums, i+1, right)

        quicksort(nums, 0, len(nums)-1)
        return nums


# Imports python modules
from time import time, sleep

import matplotlib.pyplot as plt
import seaborn as sns

from torchvision import datasets, transforms

import torch
import torchvision
import torchvision.transforms as transforms
import torch.optim as optim
#import time
import torch.nn.functional as F
import torch.nn as nn
import matplotlib.pyplot as plt
from torchvision import models
#import helper
#import fc_model
import numpy as np
from torch import nn

from PIL import Image
import glob, os
from torch.autograd import Variable

import matplotlib.pyplot as plt
import os, random
import json
from collections import OrderedDict
#import time
# Imports functions created for this program
from get_input_args import get_input_args

#Load a pre-trained network (If you need a starting point, the VGG networks work great and are straightforward to use)
# validation function
def validate(model, test_dataloader, device, criterion):
    """
    Validate
    Parameters:
     model - model to be used
     test_dataloader - test set dataloader
     device - CPU or GPU
     criterion - criterion to be used
    Returns:
     None
    """
    model.eval()
    val_running_loss = 0.0
    val_running_correct = 0
    for int, data in enumerate(test_dataloader):
        data, target = data[0].to(device), data[1].to(device)
        output = model(data)
        loss = criterion(output, target)

        val_running_loss += loss.item()
        _, preds = torch.max(output.data, 1)
        val_running_correct += (preds == target).sum().item()

    val_loss = val_running_loss/len(test_dataloader.dataset)
    val_accuracy = 100. * val_running_correct/len(test_dataloader.dataset)

    return val_loss, val_accuracy

#Load a pre-trained network (If you need a starting point, the VGG networks work great and are straightforward to use)
# training function
def fit(model, train_dataloader, device, optimizer, criterion):
    """
    Fit
    Parameters:
     model - model to be used
     train_dataloader - training set dataloader
     device - CPU or GPU
     optimizer -  optimizer to be used
     criterion - criterion to be used
    Returns:
     None
    """
    model.train()
    train_running_loss = 0.0
    train_running_correct = 0
    for i, data in enumerate(train_dataloader):
        data, target = data[0].to(device), data[1].to(device)
        optimizer.zero_grad()
        output = model(data)
        loss = criterion(output, target)
        train_running_loss += loss.item()
        _, preds = torch.max(output.data, 1)
        train_running_correct += (preds == target).sum().item()
        loss.backward()
        optimizer.step()
    train_loss = train_running_loss/len(train_dataloader.dataset)
    train_accuracy = 100. * train_running_correct/len(train_dataloader.dataset)
    print(f'Train Loss: {train_loss:.4f}, Train Acc: {train_accuracy:.2f}')

    return train_loss, train_accuracy

def load_data(data_dir):
    """
    Load data from data directory
    Parameters:
     data_dir - data directory
    Returns:
     Dataloaders for training, testing and validation
    """
    train_dir = data_dir + '/train'
    valid_dir = data_dir + '/valid'
    test_dir = data_dir + '/test'
    # TODO: Define your transforms for the training, validation, and testing sets
    data_transforms = {
         'training' : transforms.Compose([transforms.RandomResizedCrop(224),
                                    transforms.RandomHorizontalFlip(),transforms.RandomRotation(30),
                                    transforms.ToTensor(),
                                    transforms.Normalize([0.485, 0.456, 0.406],
                                                         [0.229, 0.224, 0.225])]),

        'validation' : transforms.Compose([transforms.Resize(256),
                                      transforms.CenterCrop(224),
                                      transforms.ToTensor(),
                                      transforms.Normalize([0.485, 0.456, 0.406],
                                                           [0.229, 0.224, 0.225])]),

        'testing' : transforms.Compose([transforms.Resize(256),
                                      transforms.CenterCrop(224),
                                      transforms.ToTensor(),
                                      transforms.Normalize([0.485, 0.456, 0.406],
                                                           [0.229, 0.224, 0.225])])
    }
    print("Loading from {}".format(train_dir))
    print("Loading from {}".format(test_dir))
    print("Loading from {}".format(valid_dir))

    # TODO: Load the datasets with ImageFolder
    image_datasets = {
        'training' : datasets.ImageFolder(train_dir, transform=data_transforms['training']),
        'testing' : datasets.ImageFolder(test_dir, transform=data_transforms['testing']),
        'validation' : datasets.ImageFolder(valid_dir, transform=data_transforms['validation'])
    }

    # TODO: Using the image datasets and the trainforms, define the dataloaders
    dataloaders = {
        'training' : torch.utils.data.DataLoader(image_datasets['training'], batch_size=32, shuffle=True),
        'testing' : torch.utils.data.DataLoader(image_datasets['testing'], batch_size=32, shuffle=False),
        'validation' : torch.utils.data.DataLoader(image_datasets['validation'], batch_size=32, shuffle=True)
    }
    print("Loaded from {}".format(train_dir))
    print("Loaded from {}".format(test_dir))
    print("Loaded from {}".format(valid_dir))
    return image_datasets, dataloaders

def load_model(device, learning_rate):
    """
    Load model
    Parameters:
     device - cpu or gpu
     learning_rate - learning rate to be set
    Returns:
     Model, optimizer and criterion
    """
    #Load a pre-trained network (If you need a starting point, the VGG networks work great and are straightforward to use)
    model = models.vgg19(pretrained=True)

    classifier = nn.Sequential(OrderedDict([
                          ('fc1', nn.Linear(25088, 4096)), # First layer
                          ('relu', nn.ReLU()), # Apply activation function
                          ('fc2', nn.Linear(4096, 102)), # Output layer
                          ('output', nn.LogSoftmax(dim=1)) # Apply loss function
                          ]))
    model.classifier = classifier

    # freeze convolution weights
    for param in model.features.parameters():
        param.requires_grad = False

    model.to(device)

    # optimizer
    print("learning_rate = {}".format(learning_rate))

    optimizer = optim.SGD(model.classifier.parameters(), lr=learning_rate, momentum=0.9)
    # loss function
    criterion = nn.CrossEntropyLoss()
    return model, optimizer, criterion

def train(model, dataloaders, epoch_to_train, device, optimizer, criterion):
    """
    Train the model
    Parameters:
     model - model loaded to be trained
     dataloaders - dataloaders to get datasets
     epoch -  number of epoch to run training
     device - cpu or gpu
     optimizer - optimizer
     criterion - criterion
    Returns:
     Model
    """
    #Load a pre-trained network (If you need a starting point, the VGG networks work great and are straightforward to use)
    train_loss , train_accuracy = [], []
    val_loss , val_accuracy = [], []
    start = time()

    print("epoch_to_train = {}".format(epoch_to_train))
    for epoch in range(epoch_to_train):
        print("Starting epoch = {}".format(epoch))
        print("Fitting")
        train_epoch_loss, train_epoch_accuracy = fit(model, dataloaders['training'], device, optimizer, criterion)
        print("Validating")
        val_epoch_loss, val_epoch_accuracy = validate(model, dataloaders['testing'], device, criterion)
        print("val_epoch_accuracy = {}".format(val_epoch_accuracy))
        train_loss.append(train_epoch_loss)
        train_accuracy.append(train_epoch_accuracy)
        val_loss.append(val_epoch_loss)
        val_accuracy.append(val_epoch_accuracy)
        #stop training when accuracy exceeds 85
        if val_epoch_accuracy > 85:
            print("Exiting at epoch = {}".format(epoch))
            break
    end = time()
    print('Training time: ', (end-start)/60, ' minutes')
    return model

def validate_model(model, validation_dataloader):
    #run against validation dataset
    model.to('cpu')
    images, labels = next(iter(validation_dataloader))
    # Get the class probabilities
    ps = torch.exp(model(images))
    print(ps.shape)
    top_p, top_class = ps.topk(1, dim=1)
    # Look at the most likely classes for the first 10 examples
    print(top_class[:10,:])
    matches = top_class == labels.view(*top_class.shape)
    accuracy = torch.mean(matches.type(torch.FloatTensor))
    return accuracy

def save_checkpoint(model, image_datasets):
    model.class_to_idx = image_datasets['training'].class_to_idx
    torch.save({'arch': 'vgg19',
            'input_size': 25088,
            'output_size': 102,
            'state_dict': model.state_dict(), # Holds all the weights and biases
            'class_to_idx': model.class_to_idx},
            'model.pth')
    print("Model saved as 'model.pth'")

# Main program function defined below
def main():
    # TODO 0: Measures total program runtime by collecting start time
    start_time = time()
    # check GPU availability
    device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
    print(device)

    in_arg = get_input_args()
    print(in_arg)
#    check_command_line_arguments(in_arg)
    image_datasets, dataloaders = load_data(in_arg.data_directory)
    #model, optimizer, criterion = load_model(device, 0.001)
    model, optimizer, criterion = load_model(device, in_arg.learning_rate)
    print("Model loaded")
    print(model)
    #model = train(model, dataloaders, 9, device, optimizer, criterion)
    model = train(model, dataloaders, in_arg.epochs, device, optimizer, criterion)
    print("Model trained")
    print(model)
    print("Validating model")
    accuracy = validate_model(model, dataloaders['validation'])
    print(f'Accuracy: {accuracy.item()*100}%')
    print("Saving checkpoint")
    save_checkpoint(model, image_datasets)

    end_time = time()

    tot_time = end_time - start_time #calculate difference between end time and start time
    print("\n** Total Elapsed Runtime:",
          str(int((tot_time/3600)))+":"+str(int((tot_time%3600)/60))+":"
          +str(int((tot_time%3600)%60)) )

# Call to main function to run the program
if __name__ == "__main__":
    main()


#!/bin/python3

from exceptions import EdgeDoesNotExists, NoCompatibleConnectionFound
from itertools import combinations

import pprint

class Weight:

    def __init__(self, w):
       self.vector = w

    def __add__(self, other):
        sum = self.vector + other.vector
        return Weight(sum)

    def __sub__(self, other):
        sum = (self.vector[0] - other.vector[0], self.vector[1] - other.vector[1])
        return Weight(sum)

    def __rmul__(self, other):
        return Weight([other*entry for entry in self.vector])

    def __repr__(self) -> str:
        return f"({self.vector[0]}, {self.vector[1]})"

def GKMCondition(w1: Weight, w2: Weight, w3: Weight) -> bool:
    """
    Consider w3 = nabla_w1 w2 = w2 + c*w1
    (overloaded notation, w are weights and edges...)
    Return True if such a c exists, otherwise False

    AT THE MOMENT, IT WORKS ONLY FOR WEIGHTS IN Z^2
    """

    w = w3 - w2
    det = w.vector[0]*w1.vector[1] - w.vector[1]*w1.vector[0]

    if not det == 0: return False

    try:
        if w.vector[0] % w1.vector[0] == 0:
            return True
        else:
            return False
    except ZeroDivisionError:
        if w.vector[1] % w1.vector[1] == 0:
            return True
        else:
            return False

class Edge:

    def __init__(self, v1, v2, w = None) -> None:
        self.v1 = v1
        self.v2 = v2
        self.weight = w
        self.name = (v1,v2)
        self.hash = f"{v1}{v2}"

    def setWeight(self, w : Weight):
        self.weight = w
        return self

    def __repr__(self) -> str:
        r = ""

        return f"({self.v1},{self.v2}){r}"

    def __eq__(self, other) -> bool:
        if (self.v1 == other.v1 and self.v2 == other.v2):
            return True
        else:
            return False

    def __hash__(self):
        return hash(self.hash)

def findEdge(edges: list, v1, v2)->Edge:

    for e  in edges:
        if (e.v1 == v1 and e.v2 == v2) or (e.v1 == v2 and e.v2 == v1):
            return e

    raise EdgeDoesNotExists("Edge does not exist")

class Connection:

    def __init__(self) -> None:
        self.con = {}

    def setConnection(self, e1: Edge, e2: Edge, e3: Edge):
        self.con[e1] = { e2 : e3 }
        return self

class Graph:

    """
    In the configuration file the first column represents a vertex und the other
    columns indicate the vertex to which the former one is connected.
    """

    def __init__(self, configuration, connection = None) -> None:
        self.vertices = []
        self.edges = []
        self.connection = {}

        with open(configuration , "r") as file:
            for line in file.readlines():
                items = line.strip().split(" ")
                for item in items:
                    self.vertices.append(item) if not item in self.vertices else self.vertices
                    if not item == items[0]:
                        self.edges.append(Edge(items[0],item))

        if connection:
            with open(connection, "r") as file:
                for line in file.readlines():
                    i1 = line.split(";")[0].split(",")

                    for edge in self.edges:
                        if edge.v1 == i1[0] and edge.v2 == i1[1]:
                            e1 = edge

                    if not e1 in self.connection:
                        self.connection[e1] = {}

                    i2 = line.split(";")[1].split(",")
                    i3 = line.split(";")[2].split(",")

                    for edge in self.edges:
                        if edge.v1 == i2[0] and edge.v2 == i2[1]:
                            e2 = edge
                        if edge.v1 == i3[0] and edge.v2 == i3[1].strip():
                            e3 = edge

                    self.connection[e1][e2] = e3
                    self.connection[e1][e3] = e2

    def findEdge(self, v1, v2) -> Edge:
        e = Edge(str(v1),str(v2))
        for edge in self.edges:
            if edge == e:
                return edge
        else:
            raise EdgeDoesNotExists(f"Edge: ({e.v1},{e.v2}) does not exists!")

    def returnEdges(self, name):
        with open(f"edges_{name}.gkm", "w") as file:
            for edge in self.edges:
                file.write(f"{edge.v1},{edge.v2};\n")

    def loadWeights(self, name):
        with open(f"edges_{name}.gkm", "r") as file:
            for line in file.readlines():
                items = line.strip().split(";")
                e1 = items[0].split(",")[0]
                e2 = items[0].split(",")[1]
                w1 = items[1].split(",")[0]
                w2 = items[1].split(",")[1]

                e = self.findEdge(e1, e2)
                e.setWeight(Weight((int(w1),int(w2))))

        return self

    def connectionPath(self, e1: Edge, e2: Edge):
        """
        We start with nabla_e1 (e2)
        """
        path = []
        start = e1
        end = e2
        next = self.connection[e1][e2]
        prev = e1
        path.append(e1)

        while True:

            if next == end and self.connection[next][prev] == start:
                path.append(end)
                break

            path.append(next)
            p = next
            # nabla_next (prev)
            next = self.connection[next][prev]
            prev = p

        return path

    def emanatingEdges(self, vertex):
        edges = []

        for edge in self.edges:
            if edge.v1 == vertex or edge.v2 == vertex:
                edges.append(edge)

        return edges

    def getEpsilon(self, e1: Edge, e2: Edge):
        e3 = self.connection[e1][e2]

        w1 = e1.weight
        w2 = e2.weight
        w3 = e3.weight

        if GKMCondition(w1,w2,w3):
            return 1
        if GKMCondition(w1,(-1)*w2,w3):
            return -1

    def computeEta(self, vertex, pathEdge: Edge):
        edges = self.emanatingEdges(vertex)
        eta = -1

        for edge in edges:
            if not edge == pathEdge:
                eps = self.getEpsilon(pathEdge, edge)
                eta = eta * eps

        return eta

    def computeOrientationPath(self, path: list):
        r = 1
        for e in path:
            eta = self.computeEta(e.v1, e)
            r = r * eta
        return r

    def computeAllConnectionPaths(self):
        paths = []
        set_paths = []

        for vertex in self.vertices:
            edges = self.emanatingEdges(vertex)
            pairs = list(combinations(edges, 2))
            for pair in pairs:
                new = self.connectionPath(pair[0],pair[1])
                if not set(new) in set_paths:
                    paths.append(new)
                    set_paths.append(set(new))

        return paths

    def createConnection(self):
        for edge in self.edges:
            self.connection[edge] = {}
            initial_edges = self.emanatingEdges(edge.v1)
            terminal_edges = self.emanatingEdges(edge.v2)

            initial_edges.remove(edge)
            terminal_edges.remove(edge)

            for initial in initial_edges:
                for terminal in terminal_edges:
                    if GKMCondition(edge.weight, initial.weight,
                                    terminal.weight):
                        #print(edge, initial, terminal)
                        self.connection[edge][initial] = terminal
                        self.connection[edge][terminal] = initial
                        terminal_edges.remove(terminal)
                        break
                    elif GKMCondition(edge.weight, (-1)*initial.weight,
                                    terminal.weight):
                        #print(edge, initial, terminal)
                        self.connection[edge][initial] = terminal
                        self.connection[edge][terminal] = initial
                        terminal_edges.remove(terminal)
                        break
                    else:
                        #print(f"nabla_{edge}{initial}={terminal} violates GKM condition")
                        pass

            if self.connection[edge] == {}:
                raise NoCompatibleConnectionFound(f"No compatible connection found for edge{edge}")

def vgraph():
    vg = Graph("vgraph.gkm")

    vg.loadWeights("vgraph")
    p = [ (1,3), (3,4), (4,6), (6,7), (7,8), (8,11), (11,12), (1,12) ]
    #p = [(4,5), (5,6), (6,7), (7,9), (8,9), (7,8), (6,7), (4,6)]
    outer = [ vg.findEdge(e[0],e[1]) for e in p]
    vg.createConnection()
    print(p, vg.computeOrientationPath(outer))
    #print(vg.computeOrientationPath(outer))
    for path in vg.computeAllConnectionPaths():
        print(path, vg.computeOrientationPath(path))

def cp3():
    cp3 = Graph("cp3.gkm")
    cp3.loadWeights("cp3")
    cp3.createConnection()
    paths = cp3.computeAllConnectionPaths()
    for path in paths:
        print(path, cp3.computeOrientationPath(path))
    #connection_paths = cp3.computeAllConnectionPaths()
    #for path in connection_paths:
    #    print(cp3.computeOrientationPath(path))

def tolman():
    tolman = Graph("tolman.gkm")
    tolman.loadWeights("tolman")
    tolman.createConnection()
    pprint.pprint(tolman.connection)
    for path in tolman.computeAllConnectionPaths():
        print(path, tolman.computeOrientationPath(path))

def main():
    #cp3()
    #tolman()
    vgraph()

if __name__ == "__main__":
  main()


import os

from libvirt import libvirtError
from libvirttestapi.src import sharedmod

required_params = ('poolname', 'volname',)
optional_params = {}

def pool_lookup_by_volume(params):
    """
       test API for storagePoolLookupByVolume in class virStoragePool
    """
    logger = params['logger']
    poolname = params['poolname']
    volname = params['volname']
    logger.info("The given pool name is %s" % (poolname))
    logger.info("The given vol name is %s" % (volname))
    conn = sharedmod.libvirtobj['conn']
    pool = conn.storagePoolLookupByName(poolname)
    pre_vol = pool.storageVolLookupByName(volname)
    volpath = pre_vol.path()
    logger.info("The given volume path is %s" % (volpath))
    temp = volpath.split("/")
    temp.pop(0)
    temp.pop(-1)
    temp1 = "/" + "/".join(temp)
    if not os.path.exists(temp1):
        logger.warning("volume path file %s is not exist" % temp1)

    try:
        vol = conn.storageVolLookupByPath(volpath)
        pool_name = vol.storagePoolLookupByVolume().name()
        logger.info("The pool name is %s from API" % (pool_name))

        if not pool_name == poolname:
            return 1

    except libvirtError as e:
        logger.error("API error message: %s, error code is %s"
                     % (e.get_error_message(), e.get_error_code()))
        return 1

    return 0


#!/usr/bin/python3.4
# -*- coding: utf-8 -*-
__author__ = 'Prostakov Alexey'

import os, glob
from pymongo import MongoClient
import sys
import configparser
import smev
import logging
import protokol
import datetime

"""
Описание
**********************

Входные данные
**********************

Выходные данные
**********************

"""
logging.basicConfig(filename='tester.log', filemode='a', level=logging.DEBUG,
    format='%(asctime)s %(levelname)s: %(message)s')

def printTest(post):
    print("%s выполнено за %s сек. ошибок %s."
                % (post['name'], post['data']['Итого'], post['errors']))
    if post['errors']:
        logging.error("%s Выполнено за %s ошибок %s."
            % (post['name'], post['data']['Итого'], post['errors']))
    else:
        logging.info("%s Выполнено за %s без ошибок."
            % (post['name'], post['data']['Итого']))

def readConfig(file="config.ini"):
    '''
    :param file: имя файла конфигурации
    :return: список ИС для тестирования, словарь настроек к БД, кол-во ошибок
    '''
    err = 0
    ISList = list()
    BD = dict()
    if os.access(file, os.F_OK):
        # выполняется если найден конфигурационный файл
        config_str = open(file, encoding='utf-8', mode='r').read()
        # удалить признак кодировки
        config_str = config_str.replace(u'\ufeff', '')
        # чтение конфигурационного файла
        Config = configparser.ConfigParser()
        Config.read_string(config_str)
        sections = Config.sections()
        # читаем все секции
        for section in sections:
            i = Config[section]
            # это секция про ИС, их может быть несколько
            if section.count('IS'):
                IS = dict()
                IS['snd_name'] = i.get('name', fallback='СОЦИНФОРМТЕХ')
                IS['snd_code'] = i.get('mnemonic', fallback='SOCP01711')
                IS['oktmo'] = i.get('OKTMO', fallback='70000000')
                IS['url'] = i.get('URL', fallback='/socportal/')
                IS['adr'] = i.get('address', fallback='')
                IS['port'] = i.get('port', fallback='80')
                IS['servicecode'] = i.get('SERVICE_CODE', fallback='123456789')
                IS['SpravID'] = i.get('SpravID', fallback='1')
                IS['comment'] = i.get('comment', fallback='')
                IS['protocol'] = i.get('protocol', fallback='no')
                ISList.append(IS)
            # это про подсоединение к БД
            elif section == 'BD':
                BD['adr'] = i.get('address', fallback='')
                BD['port'] = i.get('port', fallback='27017')
                BD['BD'] = i.get('dataBase', fallback='')
                BD['protocol'] = i.get('protocol', fallback='')
        # проверим заполнение секции о БД
        if len(BD.keys()) == 0:
            print('В конфигурационном файле отсутствует обязательная секция о БД.')
            err += 1
        else:
            for key in BD.keys():
                if BD[key] == '':
                    print("Параметр %s не должен быть пустой, заполните его в конфигурационном файле %s" % (key, file))
                    err += 1
        # проверим заполнение сведений об ИС
        if len(ISList) == 0:
            print('В конфигурационном файле отсутствует обязательная секция об ИС.')
            err += 1
        else:
            for IS in ISList:
                for key in IS.keys():
                    if IS[key] == '':
                        print("В секции сведение об ИС параметр %s не должен быть пустой, заполните его в конфигурационном файле %s" % (key, file))
                        err += 1
    # нет конфигурационного файла
    else:
        print("Ошибка! Не найден конфигурационный файл")
        err = 1
    return ISList, BD, err

if __name__ == '__main__':
    logging.info("Программа запущена")
    # чтение конфигурационного файла
    ISList, BD, err = readConfig('config.ini')
    if err > 0 or ISList is None or BD is None:
        logging.critical("При чтении конфигурационного файла произошли ошибки. Программа остановлена")
        exit(1)
    else:
        logging.info("Конфигурационный файл прочитан успешно.")

    # соединяемся с БД для записи протокола
    try:
        client = MongoClient(BD['adr'], int(BD['port']))
        db = client[BD['BD']]
        collProt = db[BD['protocol']]
    except:
        logging.critical("Ошибка при соединении с БД. Программа остановлена")
        Type, Value, Trace = sys.exc_info()
        logging.critical("""Тип ошибки: %s Текст: %s""" % (Type, Value))
        exit(2)
    logging.info('Успешное соединения с БД')

    # перебираем все ИС из конф. файла
    for IS in ISList:
        err = 0
        logging.info('Обрабатываем ИС: %s' % IS['snd_name'])
        # получаем версии ПО
        IS['version'], errMsg = smev.getVersion(IS)

        if errMsg :
            logging.error(errMsg)
            continue
        if IS['protocol'] == 'yes':
            post, err1 = (protokol.getData(IS))
            err += err1
            print(post)
            if err1:
                logging.error('Получение протокола для %s не выполнено, возникли ошибки' % post['comment'])
            else:
                logging.info('Получение протокола для %s выполнено успешно' % post['comment'])
                logging.debug('Для записи подготовлено: %s' % post)
                #collProt.insert_one(post)
                logging.debug('Было записано c ID=%s' % post['_id'])
    # закрывает соединения с БД
    client.close()
    exit(0)


"""studentlife URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/4.0/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.urls import path
from career import views

urlpatterns = [
    path('index/', views.index,name="index"),
    path('login/', views.login, name="login"),
    path('contract/', views.contract, name="contract"),
    path('education/', views.education, name="education"),
    path('registation/', views.registation, name="registation"),
    path('allstu/', views.allstu, name="allstu"),
    path('about/', views.about, name="about"),
    path('bank/', views.bank, name="bank"),
    path('books/', views.books, name="books"),

]


st = open('24_2421.txt').readline()
# st = st.replace('D', ' ').split()
# print(max(len(i) for i in st))
maxx = float('-inf')
count = 1
for i in range(len(st) - 1):
    if st[i] != 'D' and st[i + 1] != 'D':
        count += 1
        maxx = max(count, maxx)
    else:
        count = 1
print(maxx)


def word_break(A, dic):
    def helper(A, buf, buf_index, pos, dic, memo):
        if pos == len(A):
            res.append(' '.join(buf[:buf_index].copy()))
            return

        #if not memo.get(pos, True):
        #    return False

        for i in range(pos, len(A)):
            sub_string = A[pos:i+1]
            if sub_string in dic:
                buf[buf_index] = sub_string
                helper(A, buf, buf_index+1, i+1, dic, memo)
                #if helper(A, buf, buf_index+1, i+1, dic, memo):
                #    return True
                #else:
                #    memo[i+1] = False

        return False

    res = []
    buf = [None] * len(A)
    memo = {}
    helper(A, buf, 0, 0, dic, memo)
    print (memo)
    return res

if __name__ == "__main__":
    print (word_break("iball", ("i", "iall", "ball")))


import numpy as np
import pandas as pd

def calculate_mad(predictions, true_values, bins, param_unit):
    if not bins:
        bins = [min(true_values) - 1, max(true_values) + 1]

    df = pd.merge(left=true_values, left_index=True, right=predictions, right_index=True)

    df.columns = ["TRUE_VALUE", "PREDICTION"]

    bins_intervals = []
    bins_sizes = []
    bins_mads = []

    for bin_index in range(0, len(bins) - 1):
        bin_min = bins[bin_index]
        bin_max = bins[bin_index + 1]
        bins_intervals.append(f"[{bin_min} {param_unit}, {bin_max} {param_unit}]")

        df_bin = df[(df["PREDICTION"] >= bin_min) & (df["PREDICTION"] < bin_max)].copy()
        bins_sizes.append(df_bin.shape[0])

        errors = df_bin["PREDICTION"] - df_bin["TRUE_VALUE"]
        mad = np.median(np.abs(errors))
        bins_mads.append(mad)

    bins_intervals.append("Full Sample")
    bins_sizes.append(df.shape[0])
    error = df["PREDICTION"] - df["TRUE_VALUE"]
    mad = np.median(np.abs(error))
    bins_mads.append(mad)

    return pd.DataFrame({"bin": bins_intervals, "objects": bins_sizes, "mad": bins_mads})


# A Floater is Prey; it updates by moving mostly in
#   a straight line, but with random changes to its
#   angle and speed, and displays as ufo.gif (whose
#   dimensions (width and height) are computed by
#   calling .width()/.height() on the PhotoImage

# THIS FLOATER CLASS UTILIZES RED OVALS INSTEAD OF ufo.gif

#from PIL.ImageTk import PhotoImage
from prey import Prey
import random

class Floater(Prey):
    radius = 5
    def __init__(self,x,y,speed,angle):
        Prey.__init__(self,x,y,Floater.radius*2,Floater.radius*2,angle,speed)

    def  update(self): # the only Prey type that overrides the Prey.update() method
        changed = random.choice([True, True, True, False, False, False, False, False, False, False])

        if changed:
            while True: #change speed
                self.set_speed(self.get_speed() + (random.random() - 0.5))
                if 3 <= self.get_speed() <= 7: break

            self.set_angle(self.get_angle() + (random.random() - 0.5)) # change angle

        self.move() #from Prey/Mobile_Simulton

    # re-purposed from Pattis's program5helper 2022
    def display(self,canvas):
        canvas.create_oval(self._x-Floater.radius      , self._y-Floater.radius,
                                self._x+Floater.radius, self._y+Floater.radius,
                                fill='#ff0000')


#!/usr/bin/env python

"""Run all tests.
"""

from glob import glob
import doctest2
import sys

def summarize(filename, statuses):
    print("=" * 30)
    print(filename)
    print("-" * 30)
    failures, tests = statuses
    print("%d tests, %d failures" % (tests, failures))
    print("=" * 30)
    print("")

if __name__ == '__main__':
    if len(sys.argv) > 1 and sys.argv[1] == '-v':
        verbose = True
    else:
        verbose = False

    summarize('doctest2.py', doctest2.testmod(doctest2))
    for filename in glob('./tests/rst/*.rst'):
        summarize(filename, doctest2.testfile(filename, verbose=verbose))


from dataclasses import dataclass
from typing import Any, List, Tuple

import hypothesis.strategies as st
import pytest
from hypothesis import given
from omegaconf import DictConfig, ListConfig
from omegaconf.errors import ValidationError

from hydra_zen import (
    DefaultBuilds,
    builds,
    hydrated_dataclass,
    instantiate,
    make_config,
    mutable_value,
)
from hydra_zen._compatibility import HYDRA_SUPPORTS_OBJECT_CONVERT

get_obj_path = DefaultBuilds._get_obj_path

def f_three_vars(x, y, z):
    return x, y, z

def wrapper(obj):
    return obj

@given(
    convert=st.sampled_from(["none", "all", "partial"]),
    recursive=st.booleans(),
    sig=st.booleans(),
    partial=st.none() | st.booleans(),
    meta=st.none() | st.just(dict(meta=1)),
    wrappers=st.none() | st.just(wrapper) | st.lists(st.just(wrapper)),
    kwargs=st.dictionaries(keys=st.sampled_from(["x", "y", "z"]), values=st.floats()),
    name=st.none() | st.sampled_from(["NameA", "NameB"]),
)
def test_builds_sets_hydra_params(
    convert, recursive, sig, partial, name, meta, wrappers, kwargs
):
    out = builds(
        f_three_vars,
        hydra_convert=convert,
        hydra_recursive=recursive,
        populate_full_signature=sig,
        zen_partial=partial,
        zen_meta=meta,
        zen_wrappers=wrappers,
        zen_dataclass={"cls_name": name},
        **kwargs,
    )

    assert out._convert_ == convert  # type: ignore
    assert out._recursive_ == recursive  # type: ignore
    if name is not None:
        assert out.__name__ == name
    else:
        assert "Builds_f_three_vars" in out.__name__

def f_for_convert(**kwargs):
    return kwargs

class NotSet:
    pass

@dataclass
class A:
    x: Any = (1, 2)

@pytest.mark.parametrize("via_hydrated_dataclass", [False, True])
@pytest.mark.parametrize(
    "convert, expected_types",
    [
        # "Passed objects are DictConfig and ListConfig"
        ("none", (DictConfig, ListConfig, DictConfig, int)),
        # default should be same as 'none'
        (NotSet, (DictConfig, ListConfig, DictConfig, int)),
        # "Passed objects are converted to dict and list, with
        #  the exception of Structured Configs (and their fields)."
        ("partial", (dict, list, DictConfig, int)),
        # "Passed objects are dicts, lists and primitives without
        # a trace of OmegaConf containers"
        ("all", (dict, list, dict, int)),
    ],
)
def test_hydra_convert(
    convert: str, expected_types: List[type], via_hydrated_dataclass: bool
):
    """Tests that the `hydra_convert` parameter produces the expected/documented
    behavior in hydra."""

    kwargs = dict(hydra_convert=convert) if convert is not NotSet else {}

    if not via_hydrated_dataclass:
        out = instantiate(
            builds(
                f_for_convert,
                a_dict=dict(x=1),
                a_list=[1, 2],
                a_struct_config=A,
                an_int=1,
                zen_convert={"dataclass": False},
                **kwargs,
            )
        )
    else:

        @hydrated_dataclass(f_for_convert, **kwargs)
        class MyConf:
            a_dict: Any = mutable_value(dict(x=1))
            a_list: Any = mutable_value([1, 2])
            a_struct_config: Any = A
            an_int: int = 1

        out = instantiate(MyConf)

    actual_types = tuple(
        type(out[i]) for i in ("a_dict", "a_list", "a_struct_config", "an_int")
    )
    assert actual_types == expected_types

    if convert in ("none", "partial", NotSet):
        expected_field_type = ListConfig
    else:
        expected_field_type = list

    assert type(out["a_struct_config"]["x"]) is expected_field_type

@pytest.mark.xfail(
    not HYDRA_SUPPORTS_OBJECT_CONVERT,
    raises=ValueError,
    reason="Hydra 1.3.0 required for _convert_ = 'object'",
)
def test_object_convert():
    Conf = make_config(
        a=builds(dict, b=1), hydra_convert="object"
    )  # should raise if local Hydra version is < 1.3.0
    assert isinstance(instantiate(Conf), Conf)

@pytest.mark.xfail(
    not HYDRA_SUPPORTS_OBJECT_CONVERT,
    raises=ValueError,
    reason="Hydra 1.3.0 required for _convert_ = 'object'",
)
def test_object_convert_hydrated():
    @hydrated_dataclass(dict, hydra_convert="object")
    class A:
        ...

    assert A._convert_ == "object"  # type: ignore

def f_for_recursive(**kwargs):
    return kwargs

@pytest.mark.parametrize("via_hydrated_dataclass", [False, True])
@pytest.mark.parametrize("recursive", [False, True, NotSet])
def test_recursive(recursive: bool, via_hydrated_dataclass: bool):
    target_path = get_obj_path(f_for_recursive)

    kwargs = dict(hydra_recursive=recursive) if recursive is not NotSet else {}

    if not via_hydrated_dataclass:
        out = instantiate(
            builds(
                f_for_recursive,
                x=builds(f_for_recursive, y=1),
                **kwargs,
            )
        )

    else:

        @hydrated_dataclass(f_for_recursive)
        class B:
            y: int = 1

        @hydrated_dataclass(f_for_recursive, **kwargs)
        class A:
            x: Any = B

        out = instantiate(A)

    if recursive is NotSet or recursive:
        assert out == {"x": {"y": 1}}
    else:
        assert out == {"x": {"_target_": target_path, "y": 1}}

def f(x: Tuple[int]):
    return x

class C:
    def __init__(self, x: int):
        self.x = x

def g(x: C):
    return x

def g2(x: List[C]):
    return x

def test_type_checking():
    conf = builds(f, populate_full_signature=True)(x=("hi",))  # type: ignore
    with pytest.raises(ValidationError):
        instantiate(conf)

    # should be ok
    instantiate(builds(f, populate_full_signature=True)(x=(1,)))

    # nested configs should get validated too
    with pytest.raises(ValidationError):
        instantiate(builds(g, x=builds(C, x="hi")))  # Invalid: `C.x` must be int

    # should be ok
    instantiate(builds(g, x=builds(C, x=1)))

    conf_C = builds(C, x=1)

    # should be ok
    instantiate(builds(g2, x=[conf_C, conf_C]))


import scrapy

### Year, rating, next pages to be done

class rogerSpider(scrapy.Spider):
    name = 'roger'
    start_urls = ['https://www.rogerebert.com/movies/A']
    def parse(self, response):
        SET_SELECTOR = '.details'

        for object in response.css(SET_SELECTOR):
                NAME_SELECTOR = 'a ::text'
                yield{
                    'name': object.css(NAME_SELECTOR).extract_first(),
                    }


import pytest
from source_shopify.source import Orders
from source_shopify.utils import EagerlyCachedStreamState as stream_state_cache

# Define the Stream class for the test
STREAM = Orders(config={"authenticator": "token"})

@pytest.mark.parametrize(
    "stream, cur_stream_state, latest_record, state_object, expected_output",
    [
        # When Full-Refresh: state_object: empty.
        (STREAM, {STREAM.cursor_field: ""}, {STREAM.cursor_field: ""}, {}, {STREAM.name: {STREAM.cursor_field: ""}}),
        (STREAM, {STREAM.cursor_field: ""}, {STREAM.cursor_field: "2021-01-01T01-01-01"}, {}, {STREAM.name: {STREAM.cursor_field: ""}}),
    ],
    ids=["Sync Started", "Sync in progress"],
)
def test_full_refresh(stream, cur_stream_state, latest_record, state_object, expected_output):
    """
    When Sync = Full-Refresh: we don't have any state yet, so we need to keep the state_object at min value, thus empty.
    """
    # create the fixure for *args based on input
    args = [stream, cur_stream_state, latest_record]
    # use the external tmp_state_object for this test
    actual = stream_state_cache.stream_state_to_tmp(*args, state_object=state_object)
    assert actual == expected_output

@pytest.mark.parametrize(
    "stream, cur_stream_state, latest_record, state_object, expected_output",
    [
        # When start the incremental refresh, assuming we have the state of STREAM.
        (
            STREAM,
            {STREAM.cursor_field: "2021-01-01T01-01-01"},
            {STREAM.cursor_field: "2021-01-05T02-02-02"},
            {},
            {STREAM.name: {STREAM.cursor_field: "2021-01-01T01-01-01"}},
        ),
        # While doing the incremental refresh, we keeping the original state, even if the state is updated during the sync.
        (
            STREAM,
            {STREAM.cursor_field: "2021-01-05T02-02-02"},
            {STREAM.cursor_field: "2021-01-10T10-10-10"},
            {},
            {STREAM.name: {STREAM.cursor_field: "2021-01-05T02-02-02"}},
        ),
    ],
    ids=["Sync Started", "Sync in progress"],
)
def test_incremental_sync(stream, cur_stream_state, latest_record, state_object, expected_output):
    """
    When Sync = Incremental Refresh: we already have the saved state from Full-Refresh sync,
    we have it passed as input to the Incremental Sync, so we need to back it up and reuse.
    """
    # create the fixure for *args based on input
    args = [stream, cur_stream_state, latest_record]
    actual = stream_state_cache.stream_state_to_tmp(*args, state_object=state_object)
    assert actual == expected_output


from cryptography.fernet import Fernet

def encrypt_message(message, key):
    fernet = Fernet(key)
    encrypted_message = fernet.encrypt(message.encode())
    return encrypted_message

def write_to_encrypted_file(file_path, content, key):
    encrypted_content = encrypt_message(content, key)
    try:
        with open(file_path, 'a') as file:
            file.write(str(encrypted_content) + '\n')
        print("Successfully wrote encrypted data to the file:", file_path)
    except IOError as e:
        print("An error occurred while writing to the file:", str(e))

def decrypt_message(encrypted_message, key):
    fernet = Fernet(key)
    decrypted_message = fernet.decrypt(encrypted_message).decode()
    return decrypted_message

def read_from_encrypted_file(file_path, key):
    try:
        with open(file_path, 'rb') as file:
            encrypted_content = file.read()
            decrypted_content = decrypt_message(encrypted_content, key)
            return decrypted_content
    except IOError as e:
        print("An error occurred while reading from the file:", str(e))
        return None


import manim

from typing import List

class GeneralPositionScene(manim.ThreeDScene):
    def construct(self):
        plane = manim.NumberPlane()
        axis_config = {
            "x_range": (-10, 10, 1),
            "y_range": (-10, 10, 1),
            "z_range": (-10, 10, 1),
        }

        axes = manim.ThreeDAxes(**axis_config)
        self.set_camera_orientation(
            phi=-130*manim.DEGREES,
            theta=10*manim.DEGREES,
            distance=10,
        )
        # circle = manim.Circle()
        # square = manim.Square()
        # square.flip(manim.RIGHT)
        # square.rotate(-3 * manim.TAU / 8)
        # circle.set_fill(manim.PINK, opacity=0.5)

        vec_coordinates: List[List[int]] = [
            [2, 2], [0, 5], [1, 3],
        ]
        vec_colors = [
            manim.ORANGE,
            manim.GREEN_C,
            manim.YELLOW_C,
        ]
        self.add(plane)
        self.add(axes)

        for vec_coords, vec_color in zip(vec_coordinates, vec_colors):
            v = manim.Vector(vec_coords)
            v.set_color(vec_color)
            # v.coordinate_label(color=manim.ORANGE)
            self.add(v)

        self.begin_ambient_camera_rotation(rate=0.1)
        self.wait(12)
        # self.play(manim.Create(square))
        # self.play(manim.Transform(square, circle))
        # self.play(manim.FadeOut(square))

class NotGeneralPositionScene(manim.ThreeDScene):
    def construct(self):
        pass


import pixiv_auth
import json
from pixivpy3 import *

api = AppPixivAPI()

def tag_fixer(tag):
    tags = []
    translated_tags = []
    for i in tag:
        translated_tags.append(i.get("translated_name"))
        tags.append(i.get("name"))

    return tags, translated_tags

def pixiv_url_fixer(img):
    pic_url = img.image_urls.medium
    pic_url = pic_url.replace("pximg.net","pixiv.cat")
    return pic_url

def access_token_renewer(refresh_token):
    access = pixiv_auth.refresh(refresh_token)
    return access

def check_access_token_valid(refresh, access):
    api.set_auth(refresh_token=refresh, access_token=access)
    user = api.user_detail("57233775")
    try:
        if user["user_id"] == "Karlhsiao":
            return False
        else:
            return True
    except:
        return True

def info_printer(title, pic_url, bookmarks, original_tags, id):
    print("[%s]" % (title))
    print("original link: https://pixiv.net/artworks/" + str(id))
    print("bookmarks: %s" % (str(bookmarks)))
    print("tags:", original_tags)
    print("link: %s" % (pic_url))
    print("")

def turn_page_bookmarks(json_result):
    next_qs = api.parse_qs(json_result.next_url)
    if next_qs == None:
        return None
    json_result = api.user_bookmarks_illust(**next_qs)
    return json_result

def is_number(x):
    try:
        x = int(x)
        return True
    except:
        return False

def find_user_settings(user):
    with open("user_settings.json", "r") as fhandle:
        user_settings = json.load(fhandle)

        for user_id in user_settings:
            try:

                if user_id["user"] == user:
                    personal_detail = user_id["personal_detail"]
                    r18allow = user_id["r18allow"]
                    pic_amount = user_id["picture_amount"]
                    p_details = user_id["print_details"]
                    favorite = user_id["favorite"]
                    like_limit = user_id["like_limit"]

                    return personal_detail, r18allow, pic_amount, p_details, favorite, like_limit

            except:
                return False

        return False

def user_registered(user_settings, user):
    for users in user_settings:
        if user == users["user"]:
            return True

    return False


#While loop
"""
while condition:
    statements

if True then run the statements and loop again
if False then end loop
"""

#Loop that sums entered numbers
n = int (input("How many numbers? "))
count = 0
sum = 0
while count < n:
    num = int(input("Enter number " + str(count + 1) + ":"))
    count += 1
    sum += n
print("Total of entered numbers:", sum)

#Infitie loop with break statement
sum = 0
while True:
    n = int(input("Please enter a positive number"))
    if n >= 0:
        break
    print("The was a negative number, please try again")

print("Thanks for entering the positive number:",n)

#For loops
"""
for count in range(start, stop , step)
    statements

Loops until count increments above stop (starts at start and increments by step)
"""

print("For loop examples")
#Simple count (0 - 9)
for i in range (10):
    print(i, end="")
print()
#count from 1 to 10
for i in range (1, 11):
    print(i, end="")
print()
#count from 0 to 9 with increments of 3
for i in range (0, 10, 3):
    print(i, end="")
print()
#For loop table
Col1 = "i"
Col2 = "x"
Col3 = "x**2"
print("Creating table:")
k = int(input("Enter row count"))
x = float(input("Enter x value"))

print("%2s | %5s | %5s"%(Col1,Col2,Col3))
for i in range(k):
    print("%2d | %5.2f | %5.2f"%(i,x * i ,(x * i) **2))


#  By submitting this assignment, I agree to the following:
#  "Aggies do not lie, cheat, or steal, or tolerate those who do"
#  "I have not given or received any unauthorized aid on this assignment"
#
# Name:        Chase Albright
# Section:     480
# Assignment:  Lab Assignment 10b
# Date:        27 October 2020

fVals = []
celsVals = []
with open('Celsius.dat', 'r') as fileC: # reading data from the celsius file
    lines = fileC.readlines() # reading each line on celsius file
    for i in lines: # for loop to read each line in file and store in list
        c = float(i.strip('\n'))  #strips the blank line
        celsVals.append(c)
    for x in celsVals: # converting in F
        f = (x*(9/5)) + 32
        fVals.append(f)

    with open('Fahrenheit.dat', 'w') as Ffile: # writing the F values into the fahrenheit file
        for temps in fVals:
            Ffile.write(str(temps)+'\n')


from .utils import create_transformer_masks
from .encoder import TransformerEncoder
from .decoder import TransformerDecoder

import torch
import torch.nn as nn

class Transformer(nn.Module):
    def __init__(self,
                 num_layers,
                 d_model, num_head,
                 intermediate_dim,
                 input_vocab_size,
                 target_vocab_size,
                 src_max_len,
                 tgt_max_len,
                 padding_idx,
                 shared_emb_layer=None, # Whether use embeeding layer from encoder
                 rate=0.1):
        super(Transformer, self).__init__()

        self.pad_idx = padding_idx

        # (vocab_size, emb_dim)
        self.embedding_layer = nn.Embedding(input_vocab_size, d_model)

        self.encoder = TransformerEncoder(num_layers, d_model, num_head,
                                          intermediate_dim,
                                          input_vocab_size,
                                          src_max_len,
                                          rate)

        if shared_emb_layer is True:
            self.shared_emb_layer = self.embedding_layer
        else:
            self.shared_emb_layer = shared_emb_layer
        print(self.shared_emb_layer)
        self.decoder = TransformerDecoder(num_layers, d_model, num_head,
                                         intermediate_dim,
                                         target_vocab_size,
                                         tgt_max_len,
                                         self.shared_emb_layer,  # share embedding
                                         rate)
        self.final_layer = nn.Linear(d_model, target_vocab_size)

    def forward(self, src, tgt, training, enc_padding_mask,
                look_ahead_mask, dec_padding_mask, cuda):
        """Forward propagate for transformer.

        Args:
          src: (batch_size, src_max_len)

        """
        # Mapping
        src = self.embedding_layer(src)

        # (batch_size, inp_seq_len, d_model)
        enc_out = self.encoder(src, training, enc_padding_mask, gpu=cuda) #.cuda()

        # if cuda:
        #     enc_out = enc_out.cuda()
        # print("type of decoder input", type(tgt))
        # print("decoder input", tgt)
        # (batch_size, tgt_seq_len, d_model)
        dec_output, dec_attn = self.decoder(x=tgt,
                                            enc_output=enc_out,
                                            training=training,
                                            look_ahead_mask=look_ahead_mask,
                                            padding_mask=dec_padding_mask,
                                            gpu=cuda)

        # (batch_size, tgt_seq_len, target_vcoab_size)
        final_output = self.final_layer(dec_output)

        return final_output, dec_attn

    def sample(self, inp, max_len, temperature, training, sos_idx, eos_idx, cuda):
        """Forward propagate for transformer.

        Args:
          inp
          max_len
          temperature
          sos_idx
          eos_idx

        Returns:
          out: (batch_size, max_len)
        """
        if torch.is_tensor(inp):
            pass
        else:
            inp = torch.tensor(inp)

        #if cuda:
        #    inp = inp.cuda()

        # Gumbel-Softmax tricks
        batch_size = inp.shape[0]
        #sampled_ids = torch.zeros(batch_size, max_len).type(torch.LongTensor)

        # (batch_size, 1)
        # Create a tensor on CPU by default
        output = torch.tensor([sos_idx]*batch_size).unsqueeze(1)
        if cuda:
            output=output.cuda()
        assert output.shape[-1] == 1

        for i in range(max_len-1):
            # enc_pad_mask, combined_mask, dec_pad_mask
            enc_padding_mask, combined_mask, dec_padding_mask = create_transformer_masks(inp, output, self.pad_idx,gpu=cuda)
            # predictions.shape == (batch_size, seq_len, vocab_size)
            predictions, _ = self.forward(inp,    # (bathc_size, 1)
                                          output,  # (batch_size, 1-TO-MAXLEN)
                                          training,
                                          enc_padding_mask,
                                          combined_mask,
                                          dec_padding_mask,
                                          cuda=cuda)

            # Select the last word from the seq_len dimension
            # (batch_size, 1, vocab_size) to (batch_size, voacb_size)
            predictions = predictions[: ,-1:, :].squeeze()
            # print("preds", predictions.shape)

            # (batch_size, 1)
            #assert inp.shape[-1] = 1
            gumbel_distribution = gumbel_softmax_sample(predictions, temperature,gpu=cuda)
            # (batch_size, vocab_size)
            # print("gumbel", gumbel_distribution.shape)

            # (batch_sizes) to (bathc_size, 1)
            predicted_idx = torch.argmax(gumbel_distribution, dim=-1).unsqueeze(1)

            # print("pred idx", predicted_idx.shape)
            output = torch.cat((output, predicted_idx), 1)

            # Update along with col
            #sampled_ids[:,i] = predicted_idx.squeeze()
        #print(sampled_ids==output[:,1:])
        return output

def sample_gumbel(shape, eps=1e-20, device=None):
    """Sample from Gumbel(0, 1)"""
    if device:
        device="cuda"
    # The drawn nosie is created by default in CPU
    noise = torch.rand(shape, device=device)
    return -torch.log(-torch.log(noise+eps)+eps)

def gumbel_softmax_sample(logits, temperature, gpu):
    """Sample from Gumbel softmax distribution.
    Reference:
        1. Gumbel distribution: https://en.wikipedia.org/wiki/Gumbel_distribution
        2. Inverse Tranform Sampling: https://en.wikipedia.org/wiki/Inverse_transform_sampling
    """
    y = logits + sample_gumbel(shape=logits.shape, device=gpu)
    return nn.functional.softmax(y/temperature, dim=-1)

if __name__ == "__main__":
    transf = Transformer(2,512,8,2048,8500, 8000,10000,6000, -100, None)

    i = torch.randint(0, 200, (64,38))
    tgt_i = torch.randint(0,200, (64, 36))

    output, attn = transf(i,
                          tgt_i,
                          training=False,
                          enc_padding_mask=None,
                          look_ahead_mask=None,
                          dec_padding_mask=None)

    print(output.shape)


from setuptools import setup
import setuptools
import os
from gnutools.utils import parent, listfiles
import numpy as np
from setuptools import Extension
def get_packages(root):
    """
    Get the list of packages availables in a root

    :param root: package root
    :return list:
    """
    root = os.path.realpath(root)
    proot = parent(root) + "/"
    py_files = [file.rsplit(proot)[1] for file in listfiles(root)]
    packages = list(np.unique([parent(file).replace("/", ".") for file in py_files]))
    # return list(np.unique([parent(file).replace("/", ".").split(".{name_root}.".format(name_root=name(root)))[1]
    #                        for file in py_files]))
    return packages

print(get_packages('/mnt/IYOProjects/IYO/kenlm-publish/kenlm'))

setup(
    name="kenlm",
    version="1.0",
    long_description="",
    include_package_data=True,
    url='https://9dw-lab.jp',
    license='9DWLab',
    author='jcadic',
    # python_requires='>=3.6' and '<3.7',
    packages=["kenlm", "kenlm.bin"],
    # setup_requires=setup_requires,
    #install_requires=install_requires,
    # extra_requires=setup_requires,
    # ext_modules=[Extension('kenlm.bin', ['kenlm/bin/lmplz'])],
    author_email='j.cadic@9dw-lab.jp',
    description='KenLM',
    # platforms="linux_debian_10_x86_64",
    classifiers=[
        "Programming Language :: Python :: 3.6",
        "License :: OSI Approved :: MIT License",
    ]
)


import os
import time
import sys
import traceback

import cv2
import torch
import timm
import numpy as np

from models.build_model import build_model
from collections import OrderedDict

def normalize(img, mean, std, max_pixel_value=255.0):
    mean = np.array(mean, dtype=np.float32)
    mean *= max_pixel_value

    std = np.array(std, dtype=np.float32)
    std *= max_pixel_value

    denominator = np.reciprocal(std, dtype=np.float32)

    img = img.astype(np.float32)
    img -= mean[:, None, None]
    img *= denominator[:, None, None]
    return img

def transforms_cv2(image, resize=(224, 224)):
    image = cv2.resize(image, resize, interpolation=cv2.INTER_LINEAR)
    image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
    image = image.transpose(2, 0, 1)
    image = normalize(image, (0.485, 0.456, 0.406), (0.229, 0.224, 0.225))
    image = torch.from_numpy(image)
    image = torch.unsqueeze(image, 0)

    return image

def main(args):
    # only use single gpu or cpu
    device = torch.device('cuda:0') if args.device=='cuda' else torch.device(args.device)
    classes = torch.load(args.checkpoint, map_location=torch.device(device))['classes']
    if args.hub == 'tv':
        model = build_model(args.net, pretrained=False, fine_tune=False, num_classes=len(classes))
    elif args.hub == 'timm':
        #print(timm.list_models(pretrained=True))
        model = timm.create_model(args.net, pretrained=False, num_classes=len(classes))
    else:
        raise NameError('Model hub only support tv or timm')
    print('Loading trained model weightes...')
    model.load_state_dict({
        k.replace('module.', ''): v for k, v in
        torch.load(args.checkpoint, map_location=torch.device(device))['model_state_dict'].items()})

    model = model.to(device)

    model.eval()

    cnt = 0
    total_used_time = 0.0
    for image_name in os.listdir(args.test_path):
        try:
            image_ = args.test_path + '/' + image_name
            image = cv2.imread(image_)
            cnt += 1
            if cnt >= 5: # warmup for gpu
                bg_time = time.time()
            image_tensor = transforms_cv2(image, resize=(args.resize, args.resize))
            input = image_tensor.to(device)
            output = model(input)
            if cnt >= 5:
                total_used_time += (time.time() - bg_time)

            index = output.detach().cpu().numpy().argmax()
            #print(output.data.cpu().numpy())
            print('{}\tpredict: {}\t{}'.format(image_, classes[index], index))
            sys.stdout.flush()

        except:
            #print(image)
            traceback.print_exc()

    print('Total test num: {}, Avg used time: {}'.format(cnt, total_used_time/(cnt-4)))

if __name__ == '__main__':
    import argparse
    parser = argparse.ArgumentParser(description='PyTorch Classification Inference')

    parser.add_argument('--test-path', default='./data/beauty', help='dataset')
    parser.add_argument('--hub', default='tv', help='model hub, from torchvision(tv) or timm')
    parser.add_argument('--net', default='resnet50', help='model name')
    parser.add_argument('--device', default='cpu', choices=['cuda', 'cpu'], help='device, cpu or cuda')
    parser.add_argument('--checkpoint', default='./checkpoints/model.pth', help='checkpoint')
    parser.add_argument('--resize', default=224, type=int, help='size of resize')

    args = parser.parse_args()

    print(args)
    main(args)


# ex43 基本的面向对象分析和设计

from sys import exit
from random import randint
from textwrap import dedent

# 场景
class Scene(object):

    def enter(self):
        print("这是一个还没配置的房间")
        print("继承并实现它")

# 引擎
class Engine(object):

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

    def play(self):
        current_scene = self.scene_map.opening_scene()
        last_scene = self.scene_map.next_scene('finished')

        while current_scene != last_scene:
            next_scene_name = current_scene.enter()
            current_scene = self.scene_map.next_scene(next_scene_name)

        current_scene.enter()

# 死亡场景
class Death(Scene):

    quips = [
        "你已死亡，你的很糟糕",
        "你妈妈以你为荣，如果他可以更聪明些",
    ]

    def enter(self):
        print(Death.quips[randint(0, len(self.quips) - 1)])
        exit(1)

# 中央广场
class CentralCorridor(Scene):

    def enter(self):
        print(dedent("""
        你遇到来自Percal25号行星的哥顿人，你要怎么做?
        - 1. 射击
        - 2. 躲开
        - 3. 讲个笑话
        """))

        action = input(">")

        if action == "射击" or action == "1":
            print("哥顿人武器比你先进，打死了你")
            return 'death'

        elif action == "躲开" or action == "2":
            print("哥顿人还是发现你，打死了你")
            return 'death'

        elif action == "讲个笑话" or action == "3":
            print("哥顿人成功被你逗笑，把你当做朋友")
            return 'laser_weapon_armory'

        else:
            print("无法识别")
            return 'central_corridor'

# 激光武器库
class LaserWeaponArmory(Scene):

    def enter(self):
        print(dedent("""
        你需要密码才能解开武器库的大门，输入三位数密码:
        """))
        # code = f"{randint(1, 9)}{randint(1, 9)}{randint(1, 9)}"
        code = "123"
        guess = input("[keypad]>")
        guesses = 0

        while guess != code and guesses < 10:
            print("BZZZZEDDD")
            guesses += 1
            guess = input("[keypad]>")

        if guess == code:
            print("你打开了了武器库，你需要拿着激光武器去主控室开启")
            return 'the_bridge'

        else:
            print(dedent("""
            密码输入错误，引发了警报装置，你被警卫打死了
            """))
            return 'death'

# 主控室
class TheBridge(Scene):

    def enter(self):
        print(dedent("""
        你已进入主控室，你要做什么
        - 1. 扔下炸弹
        - 2. 轻放炸弹
        """))

        action = input(">")

        if action == "扔下炸弹" or action == "1":
            print(dedent("""
            炸弹碰撞，引发爆炸，你被炸死了
            """))
            return 'death'

        elif action == "轻放炸弹" or action == "2":
            print(dedent("""
            你成功开启炸弹倒计时
            """))
            return 'escape_pod'

        else:
            print("无法识别")
            return 'the_bridge'

# 逃生舱
class EscapePod(Scene):

    def enter(self):
        print(dedent("""
        你进入逃生舱,面前有五个按钮来启动飞船，启动失败会引发警报
        - 请输入1-5数字
        """))
        good_pod = randint(1, 5)
        guess = input("[pod #]>")

        if int(guess) != good_pod:
            print(dedent("""
            你选择错误，触发警报，被哥顿人打死了
            """))
            return 'death'
        else:
            print(dedent("""
            你启动成功了，逃生飞船起飞了
            """))
            return 'finished'

class Finished(Scene):
    def enter(self):
        print("你成功逃离哥顿人的魔掌！，干得漂亮")
        return 'finished'

# 地图
class Map(object):

    scenes = {
        'central_corridor': CentralCorridor(),
        'laser_weapon_armory': LaserWeaponArmory(),
        'the_bridge': TheBridge(),
        'escape_pod': EscapePod(),
        'death': Death(),
        'finished': Finished(),
    }

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

    def next_scene(self, scene_name):
        val = Map.scenes.get(scene_name)
        return val

    def opening_scene(self):
        return self.next_scene(self.start_scene)

a_map = Map('central_corridor')
a_game = Engine(a_map)
a_game.play()


from django import forms

from .models import Profile
from .models import ProfileSettings

class ProfileForm(forms.ModelForm):
    class Meta:
        model=Profile
        fields=(
            'external_id',
            'name',
        )
        widgets={
            'name':forms.TextInput,
        }
class ProfileSettingsForm(forms.ModelForm):
    class Meta:
        model=ProfileSettings
        fields=(
            'external',
            'api_key',
            'secret_key',
            'subaccount_email',
            'pool_username',
        )
        widgets={
            'api_key':forms.TextInput,
            'secret_key': forms.TextInput,
            'subaccount_email': forms.TextInput,
            'pool_username': forms.TextInput,
        }


import json

from google.cloud import pubsub_v1
from constans import BUCKET_KEY_GCP
from core.format_converte import ExportMusic
from app import app
# from modelos import db

class PubSubConverter:

    def __init__(self):

        self.json_key = f'{BUCKET_KEY_GCP}/key.json'

    def subscriber_message(self):
        subscriber = pubsub_v1.SubscriberClient.from_service_account_json(self.json_key)
        subscription_path = subscriber.subscription_path("flask-test-366421", "pruebas-flask-sub")

        def callback(message: pubsub_v1.subscriber.message.Message) -> None:
            print("message:")
            print(message.data)
            value = json.loads(message.data)
            print(value)
            export = ExportMusic()
            export.export_file(value)
            message.ack()

        streaming_pull_future = subscriber.subscribe(subscription_path, callback=callback)
        print(f"Listening for messages on {subscription_path}..\n")
        with subscriber:
            try:
                # When `timeout` is not set, result() will block indefinitely,
                streaming_pull_future.result()
            except TimeoutError:
                streaming_pull_future.cancel()  # Trigger the shutdown.
                streaming_pull_future.result()


def powerSet(list_X) :
    subsets = [[]]

    for num in list_X :
        size = len(subsets)
        for temp in range(size) :
            subsets.append(subsets[temp] + [num])
    return subsets

def solution(numbers, target):
    result = 0
    cases = powerSet([i for i in range(0,len(numbers))])
    for case in cases :
        temp = numbers[:]
        for idx in range(0,len(temp)) :
            if idx in case :
                temp[idx] *= -1
        if sum(temp) == target :
            result +=1

    return result

프로그래머스/2level/잉규식 알고리즘/타겟 넘버.py


class Solution:
    def mostPoints(self, questions: List[List[int]]) -> int:
        dp = [0 for _ in range(len(questions))] # stores max score if started from that point
        dp[-1] = questions[-1][0]

        i = len(questions)-2
        dp_max = [-1 for _ in range(len(questions))] # stores max seen upto that point in reverse direction
        dp_max[-1] = questions[-1][0]

        while i >= 0:
            dp[i] = questions[i][0]
            if i+questions[i][1]+1 < len(questions):
                dp[i] += dp_max[i+questions[i][1]+1]
            dp_max[i] = max(dp[i], dp_max[i+1])
            i -= 1

        return max(dp)

# question link: https://leetcode.com/contest/weekly-contest-276/problems/solving-questions-with-brainpower/

coding-practice/Dynamic Programming/Solving Questions With Brainpower.py


class Postfix:
    def __init__(self):
        self.stack = []

    def isoperand(self, op):
        if (ord(op) >= 65 and ord(op) <= 90) or (ord(op) >= 97 and ord(op) <= 122) or (ord(op) >= 48 and ord(op) <= 57):
            return 1
        else:
            return 0

    def isoperator(self, oper):
        if oper == '+' or oper == '-' or oper == '*' or oper == '/' or oper == '$' or oper == '^':
            return 1
        else:
            return 0

    def getoperatorweight(self, op):
        weight = -1
        if op == '+' or op == '-':
            weight = 1
        elif op == '*' or op == '/':
            weight = 2
        elif op == '$' or op == '^':
            weight = 3
        return weight

    def isrightassociative(self, op):
        #only $ or ^ has right associativity
        if op == '$' or op == '^':
            return 1
        else:
            return 0

    def hashigherprecedence(self, op1, op2):
        op1weight = self.getoperatorweight(op1)
        op2weight = self.getoperatorweight(op2)

        if op1weight == op2weight:
            if self.isrightassociative(op1):
                return 0
            else:
                return 1

        if op1weight > op2weight:
            return 1
        else:
            return 0

    def infixtopostfix(self, exp):
        postfix = ""
        for i in range(len(exp)):
            if exp[i] == " ":
                continue

            elif self.isoperator(exp[i]):
                while len(self.stack) != 0 and self.stack[-1] != '(' and self.hashigherprecedence(self.stack[-1], exp[i]):
                    postfix = postfix + self.stack[-1]
                    self.stack.pop()
                self.stack.append(exp[i])

            elif self.isoperand(exp[i]):
                postfix = postfix + exp[i]

            elif exp[i] == '(':
                self.stack.append(exp[i])

            elif exp[i] == ')':
                while len(self.stack) != 0 and self.stack[-1] != '(':
                    postfix = postfix + self.stack[-1]
                    self.stack.pop()
                self.stack.pop()

        while len(self.stack) != 0:
            postfix = postfix + self.stack[-1]
            self.stack.pop()
        return postfix

if __name__ == "__main__":

    pf = Postfix()
    exp = input("Enter infix expression to convert it to postfix : ")
    print(pf.infixtopostfix(exp))


class Process:
    def __init__(self, pid, arrival_time, burst_time):
        self.pid = pid
        self.arrival_time = arrival_time
        self.burst_time = burst_time
        self.start_time = 0
        self.completion_time = 0
        self.turnaround_time = 0
        self.waiting_time = 0
        self.response_time = 0

def calculate_metrics(processes):
    total_turnaround_time = 0
    total_waiting_time = 0
    total_response_time = 0

    n = len(processes)

    for i in range(n):
        processes[i].waiting_time = processes[i].turnaround_time - processes[i].burst_time
        processes[i].response_time = processes[i].start_time - processes[i].arrival_time
        total_turnaround_time += processes[i].turnaround_time
        total_waiting_time += processes[i].waiting_time
        total_response_time += processes[i].response_time

    avg_turnaround_time = total_turnaround_time / n
    avg_waiting_time = total_waiting_time / n
    avg_response_time = total_response_time / n

    return avg_turnaround_time, avg_waiting_time, avg_response_time

if __name__ == "__main__":
    # Given input
    arrival_times = [0, 4, 5, 6]
    burst_times = [24, 3, 3, 12]

    n = len(arrival_times)

    # Processes initialization
    processes = []
    for i in range(n):
        processes.append(Process("P" + str(i + 1), arrival_times[i], burst_times[i]))

    # Sort processes by arrival time
    processes.sort(key=lambda x: x.arrival_time)

    total_turnaround_time = 0
    total_waiting_time = 0
    total_response_time = 0
    total_idle_time = 0

    for i in range(n):
        processes[i].start_time = max(processes[i - 1].completion_time if i > 0 else 0, processes[i].arrival_time)
        processes[i].completion_time = processes[i].start_time + processes[i].burst_time
        processes[i].turnaround_time = processes[i].completion_time - processes[i].arrival_time

        total_turnaround_time += processes[i].turnaround_time
        total_idle_time += processes[i].start_time - (processes[i-1].completion_time if i > 0 else 0)

    avg_turnaround_time, avg_waiting_time, avg_response_time = calculate_metrics(processes)

    # Print results
    print("\n#P\tAT\tBT\tST\tCT\tTAT\tWT\tRT\n")
    for process in processes:
        print(f"{process.pid}\t{process.arrival_time}\t{process.burst_time}\t{process.start_time}\t{process.completion_time}\t{process.turnaround_time}\t{process.waiting_time}\t{process.response_time}\n")

    cpu_utilization = ((processes[-1].completion_time - total_idle_time) / processes[-1].completion_time) * 100
    throughput = n / (processes[-1].completion_time - processes[0].arrival_time)

    print(f"Average Turnaround Time = {avg_turnaround_time:.2f}")
    print(f"Average Waiting Time = {avg_waiting_time:.2f}")
    print(f"Average Response Time = {avg_response_time:.2f}")
    print(f"CPU Utilization = {cpu_utilization:.2f}%")
    print(f"Throughput = {throughput:.2f} process/unit time")


import numpy as np
import h5py
from tqdm.auto import trange
import torch
from torch_geometric.utils import dense_to_sparse

def load_data(dpath):
    X, y = [],[]
    with h5py.File(dpath, "r") as handle:
        input = handle['input']
        Hs = input["channel_to_noise_matched"]
        Plin = 10**(np.asarray(input['PdB'][...], dtype=float)/10)
        xopt = handle['xopt'][...].astype(float)
        objval_opt = handle['objval'][...].astype(float) # or wsee

        ns, nu, _ = Hs.shape # eg:(1000,4,4)

        for hidx in range(ns):
            edge_index, h = dense_to_sparse(torch.from_numpy(Hs[hidx].astype(float)))

            x1 = np.hstack([(h.reshape((-1,1))*Plin).T, # -->(h1p1, h2p1, h3p1, ...)
                             Plin.reshape(-1,1)])
            X.append( x1 )
            y.append( xopt[hidx] )

        cinfo = {'mu': input['PA inefficency'][...].item(),
                 'Pc': input['Pc'][...].item(),
                 'edge_index': edge_index,
                 'objval_opt': objval_opt} # or wsee

    y = np.concatenate((y))
    X = np.concatenate((X))
    y = y[~np.any(np.isnan(X),-1)]
    X = X[~np.any(np.isnan(X),-1)]

    return X, y, cinfo

def load_data_unsup(dpath, **kwargs):
    # parameters; ref: https://github.com/bmatthiesen/deep-EE-opt/blob/062093fde6b3c6edbb8aa83462165265deefce1a/src/globalOpt/run_wsee.py#L30
    extract_args = lambda a, k: a if not k in kwargs else kwargs[k]
    PdB = extract_args(np.array(range(-40,10+1,1)), 'PdB')

    mu = extract_args(4.0, 'mu')
    Pc = extract_args(1.0, 'Pc')
    hxp = extract_args(True, 'hxp')
    num_stab = extract_args(0., 'num_stab')

    Plin = 10**(PdB/10)
    if hxp:
        Ph = Plin
    else:
        Ph = torch.empty(Plin.shape).fill_(1)

    X = []
    with h5py.File(dpath, "r") as handle:
        Hs = handle['input']["channel_to_noise_matched"]

        ns, nu, _ = Hs.shape # eg:(1000,4,4)

        for hidx in range(ns):
            edge_index, h = dense_to_sparse(torch.from_numpy(Hs[hidx].astype(float)))
            h += num_stab

            x1 = np.hstack([(h.reshape((-1,1))*Ph).T, # -->(h1p1, h2p1, h3p1, ...)
                             Plin.reshape(-1,1)])
            X.append( x1 )

        cinfo = {'mu': mu,
                 'Pc': Pc,
                 'edge_index': edge_index} # or wsee

    X = np.concatenate((X))
    X = X[~np.any(np.isnan(X),-1)]
    y = np.full([X.shape[0], nu], np.nan)

    return X, y, cinfo


x=9
class example:
    c=1
    def ex(self):
        self.a=5
        self.b=4

    def eq(qw):
        global x
        x=50
        print(x)

q=example()
q.ex()
q.eq()
print(q.a)
print(q.c)

y=0
def outer():
    x = "local"

    def inner():
        nonlocal x
        x = "nonlocal"
        print("inner:", x)

        def inner1():
            x=1
            print("inner1:", x)

        inner1()
        print("inner:", x)

    inner()
    print("outer:", x)
    global y
    y=1
    print(y)

outer()

class Person:
    def __init__(self, fname, lname):
        self.firstname = fname
        self.lastname = lname

    def printname(self):
        print(self.firstname, self.lastname)

class Student(Person):
    def __init__(self, fname, lname, year):
        super().__init__(fname, lname)
        self.graduationyear = year

    def printname(self1):
        print("a")

x = Person("Mike", "Olsen")
x.printname()

l=[3,5,6]
it=iter(l)
for i in it:
    print(i)

print("h")
for x in l:
    print(x)

print(dir(list))

order = 4
for i in range(-4, 0, -1):
    print(i)