#!/usr/bin/env python
# coding: utf-8

# In[1]:

# -*- coding: utf-8 -*-
"""
Created on Tue Jan 26 16:35:58 2021

@author: Malcor
"""

# Python program to convert text
# file to JSON
import os
import base64
import boto3
from flask import Flask, request
import PIL
import json
import os
import csv
client = boto3.client('s3')
#client = boto3.client(
#    's3',
#    aws_access_key_id=ACCESS_KEY,
#    aws_secret_access_key=SECRET_KEY,
#    aws_session_token=SESSION_TOKEN
#)

UPLOAD_FOLDER = './static/jason/'
app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER

def upload_files(file_name, bucket, object_name= None, args= None):
    if object_name is None:
        object_name = file_name
    response = client.upload_file(file_name, bucket, object_name, ExtraArgs = args)
    print(response)

def make_json(csvFilePath, jsonFilePath):
            i = 0
            # create a dictionary
            data = {}

            # Open a csv reader called DictReader
            with open(csvFilePath) as csvf:
                csvReader = csv.DictReader(csvf)

                # Convert each row into a dictionary
                # and add it to data
                for rows in csvReader:

                    # Assuming a column named 'No' to
                    # be the primary key

                    data[i] = rows
                    i += 1
                    #print(i)

            # Open a json writer, and use the json.dumps()
            # function to dump data
#            with open(jsonFilePath, 'w', encoding='utf-8') as jsonf:
                csvf.write(json.dumps(data, indent=4))
# In[3]:

@app.route('/depot', methods=['GET', 'POST'])
def txt_to_json():

    if not os.path.isdir(app.config['UPLOAD_FOLDER']):

        os.makedirs(app.config['UPLOAD_FOLDER'])

    # the file to be converted
    path_origin = request.files['file']
    noms_du_fichier = request.files['file'].filename
    print(noms_du_fichier)
    # resultant dictionary
    dict1 = {}
    L=[]

    path_origin.save(os.path.join(app.config['UPLOAD_FOLDER'], noms_du_fichier))

    prepa_extension = os.path.splitext(noms_du_fichier)
    extension = prepa_extension[1]

    if extension == '.jpg':

        data = {}
        with open('./static/jason/' + noms_du_fichier, mode='rb') as file:
            img = file.read()
        pouet = './photo_test.jpg'
        extension = os.path.splitext(pouet)

        print(extension[-1])
        data['file.filename'] = base64.encodebytes(img).decode('utf-8')
        nom_du_fichier_propre = os.path.splitext(noms_du_fichier)[0]
        out_file = open('./static/jason/' + nom_du_fichier_propre + ".json", "w")
        json.dump(data, out_file, indent = 4)
        out_file.close()
        upload_files('./static/jason/' + nom_du_fichier_propre + ".json", 'fil-rouge-storage', nom_du_fichier_propre + ".json")
        return ('Conversion réussie !')

    if extension == '.txt':

        with open('./static/jason/' + noms_du_fichier) as fh:
            # count variable for employee id creation
            l=0
            for m, line in enumerate(fh):
                if m == 0:
                    L = list(line.strip().split())

                else :
                    fields=len(L)
                    # reading line by line from the text file
                    description = list( line.strip().split())
                    # for output see below
                    print(description)

            		# for automatic creation of id for each employee
                    sno ='key_No'+str(l)

            		# loop variable
                    i = 0
            		# intermediate dictionary
                    dict2 = {}
                    while i<fields:

            				# creating dictionary for each employee
                            dict2[str(L[i])]= description[i]
                            i = i + 1

            		# appending the record of each employee to
            		# the main dictionary
                    dict1[sno]= dict2
                    l = l + 1

        # creating json file
        nom_du_fichier_propre = os.path.splitext(noms_du_fichier)[0]
        out_file = open('./static/jason/' + nom_du_fichier_propre + ".json", "w")
        json.dump(dict1, out_file, indent = 4)
        out_file.close()
        upload_files('./static/jason/' + nom_du_fichier_propre + ".json", 'fil-rouge-storage', nom_du_fichier_propre + ".json")
        return ('Conversion réussie !')

    if extension == '.csv':
                make_json('./static/jason/' + noms_du_fichier, './static/jason/' + nom_du_fichier_propre + ".json")
                upload_files('./static/jason/' + nom_du_fichier_propre + ".json", 'fil-rouge-storage', nom_du_fichier_propre + ".json")
                return ('Conversion réussie !')

if __name__ == "__main__":
        app.run(host='0.0.0.0', port=5000)


import time
import board
import digitalio
from PIL import Image, ImageDraw, ImageFont
import adafruit_ssd1306

import subprocess

# Define the Reset Pin
oled_reset = digitalio.DigitalInOut(board.D4)

# Change these
# to the right size for your display!
WIDTH = 128
HEIGHT = 32  # Change to 64 if needed
BORDER = 5

# Use for I2C.
i2c = board.I2C()
oled = adafruit_ssd1306.SSD1306_I2C(WIDTH, HEIGHT, i2c, addr=0x3C, reset=oled_reset)

# Use for SPI
# spi = board.SPI()
# oled_cs = digitalio.DigitalInOut(board.D5)
# oled_dc = digitalio.DigitalInOut(board.D6)
# oled = adafruit_ssd1306.SSD1306_SPI(WIDTH, HEIGHT, spi, oled_dc, oled_reset, oled_cs)

# Clear display.
oled.fill(0)
oled.show()

# Create blank image for drawing.
# Make sure to create image with mode '1' for 1-bit color.
image = Image.new("1", (oled.width, oled.height))

# Get drawing object to draw on image.
draw = ImageDraw.Draw(image)

padding = -2
top = padding
bottom = oled.height-padding
x = 0

font = ImageFont.load_default()

while True:

    # Draw a black filled box to clear the image.
    draw.rectangle((0,0,oled.width,oled.height), outline=0, fill=0)

    # Shell scripts for system monitoring from here : https://unix.stackexchange.com/questions/119126/command-to-display-memory-usage-disk-usage-and-cpu-load
    cmd = "hostname -I | cut -d\' \' -f1"
    IP = subprocess.check_output(cmd, shell = True )
    cmd = "top -bn1 | grep load | awk '{printf \"CPU Load: %.2f\", $(NF-2)}'"
    CPU = subprocess.check_output(cmd, shell = True )
    cmd = "free -m | awk 'NR==2{printf \"Mem: %s/%sMB %.2f%%\", $3,$2,$3*100/$2 }'"
    MemUsage = subprocess.check_output(cmd, shell = True )
    cmd = "df -h | awk '$NF==\"/\"{printf \"Disk: %d/%dGB %s\", $3,$2,$5}'"
    Disk = subprocess.check_output(cmd, shell = True )

    # Write two lines of text.

    draw.text((x, top),       "IP: " + str(IP)[2:-3],  font=font, fill=255)
    draw.text((x, top+8),     str(CPU)[2:-1], font=font, fill=255)
    draw.text((x, top+16),    str(MemUsage)[2:-1],  font=font, fill=255)
    draw.text((x, top+25),    str(Disk)[2:-1],  font=font, fill=255)

    # Display image.
    oled.image(image)
    oled.show()
    time.sleep(.1)


############################################################
#
# craft_poisons_fc.py
# Feature Collision Attack
# June 2020
#
# Reference: A. Shafahi, W. R. Huang, M. Najibi, O. Suciu, C. Studer,
#     T. Dumitras, and T. Goldstein. Poison frogs! targeted clean-label
#     poisoning attacks on neural networks.
#     In Advances in Neural Information Processing Systems, pages 6103-6113, 2018.
############################################################
import argparse
import copy
import os
import pickle
import sys

import torch
import torchvision
import torchvision.transforms as transforms

sys.path.append(os.path.realpath("."))
from learning_module import get_transform
from learning_module import (
    TINYIMAGENET_ROOT,
    to_log_file,
    now,
    normalize_data,
    un_normalize_data,
    load_model_from_checkpoint,
)
from tinyimagenet_module import TinyImageNet

def main(args):
    """Main function to generate the FC poisons
    inputs:
        args:           Argparse object
    reutrn:
        void
    """
    print(now(), "craft_poisons_fc.py main() running.")

    craft_log = "craft_log.txt"
    to_log_file(args, args.output, craft_log)

    # Set device
    device = "cuda" if torch.cuda.is_available() else "cpu"

    ####################################################
    #               Dataset
    if args.dataset.lower() == "cifar10":
        transform_test = get_transform(args.normalize, False)
        trainset = torchvision.datasets.CIFAR10(
            root="./data", train=True, download=True, transform=transform_test
        )
        testset = torchvision.datasets.CIFAR10(
            root="./data", train=False, download=True, transform=transform_test
        )
    elif args.dataset.lower() == "tinyimagenet_first":
        transform_test = get_transform(args.normalize, False, dataset=args.dataset)
        trainset = TinyImageNet(
            TINYIMAGENET_ROOT,
            split="train",
            transform=transform_test,
            classes="firsthalf",
        )
        testset = TinyImageNet(
            TINYIMAGENET_ROOT,
            split="val",
            transform=transform_test,
            classes="firsthalf",
        )
    elif args.dataset.lower() == "tinyimagenet_last":
        transform_test = get_transform(args.normalize, False, dataset=args.dataset)
        trainset = TinyImageNet(
            TINYIMAGENET_ROOT,
            split="train",
            transform=transform_test,
            classes="lasthalf",
        )
        testset = TinyImageNet(
            TINYIMAGENET_ROOT,
            split="val",
            transform=transform_test,
            classes="lasthalf",
        )
    elif args.dataset.lower() == "tinyimagenet_all":
        transform_test = get_transform(args.normalize, False, dataset=args.dataset)
        trainset = TinyImageNet(
            TINYIMAGENET_ROOT,
            split="train",
            transform=transform_test,
            classes="all",
        )
        testset = TinyImageNet(
            TINYIMAGENET_ROOT,
            split="val",
            transform=transform_test,
            classes="all",
        )
    else:
        print("Dataset not yet implemented. Exiting from craft_poisons_fc.py.")
        sys.exit()
    ###################################################

    ####################################################
    #          Craft and insert poison image
    feature_extractors = []
    for i in range(len(args.model)):
        feature_extractors.append(
            load_model_from_checkpoint(
                args.model[i], args.model_path[i], args.pretrain_dataset
            )
        )

    for i in range(len(feature_extractors)):
        for param in feature_extractors[i].parameters():
            param.requires_grad = False
        feature_extractors[i].eval()
        feature_extractors[i] = feature_extractors[i].to(device)

    with open(args.poison_setups, "rb") as handle:
        setup_dicts = pickle.load(handle)
    setup = setup_dicts[args.setup_idx]

    target_img_idx = (
        setup["target index"] if args.target_img_idx is None else args.target_img_idx
    )
    base_indices = (
        setup["base indices"] if args.base_indices is None else args.base_indices
    )
    # Craft poisons
    poison_iterations = args.crafting_iters
    poison_perturbation_norms = []

    # get single target
    target_img, target_label = testset[target_img_idx]

    # get multiple bases
    base_imgs = torch.stack([trainset[i][0] for i in base_indices])
    base_labels = torch.LongTensor([trainset[i][1] for i in base_indices])

    # log target and base details
    to_log_file("base indices: " + str(base_indices), args.output, craft_log)
    to_log_file("base labels: " + str(base_labels), args.output, craft_log)
    to_log_file("target_label: " + str(target_label), args.output, craft_log)
    to_log_file("target_index: " + str(target_img_idx), args.output, craft_log)

    # fill list of tuples of poison images and labels
    poison_tuples = []
    target_img = (
        un_normalize_data(target_img, args.dataset) if args.normalize else target_img
    )
    beta = 4.0 if args.normalize else 0.1

    base_tuples = list(zip(base_imgs, base_labels))
    for base_img, label in base_tuples:
        # unnormalize the images for optimization
        b_unnormalized = (
            un_normalize_data(base_img, args.dataset) if args.normalize else base_img
        )
        objective_vals = [10e8]
        step_size = args.step_size

        # watermarking
        x = copy.deepcopy(b_unnormalized)
        x = args.watermark_coeff * target_img + (1 - args.watermark_coeff) * x

        # feature collision optimization
        done_with_fc = False
        i = 0
        while not done_with_fc and i < poison_iterations:
            x.requires_grad = True
            if args.normalize:
                mini_batch = torch.stack(
                    [
                        normalize_data(x, args.dataset),
                        normalize_data(target_img, args.dataset),
                    ]
                ).to(device)
            else:
                mini_batch = torch.stack([x, target_img]).to(device)

            loss = 0
            for feature_extractor in feature_extractors:
                feats = feature_extractor.penultimate(mini_batch)
                loss += torch.norm(feats[0, :] - feats[1, :]) ** 2
            grad = torch.autograd.grad(loss, [x])[0]
            x_hat = x.detach() - step_size * grad.detach()
            if not args.l2:
                pert = (x_hat - b_unnormalized).clamp(-args.epsilon, args.epsilon)
                x_new = b_unnormalized + pert
                x_new = x_new.clamp(0, 1)
                obj = loss

            else:
                x_new = (
                    x_hat.detach() + step_size * beta * b_unnormalized.detach()
                ) / (1 + step_size * beta)
                x_new = x_new.clamp(0, 1)
                obj = beta * torch.norm(x_new - b_unnormalized) ** 2 + loss

            if obj > objective_vals[-1]:
                step_size *= 0.2

            else:
                if torch.norm(x - x_new) / torch.norm(x) < 1e-5:
                    done_with_fc = True
                x = copy.deepcopy(x_new)
                objective_vals.append(obj)
            i += 1
        poison_tuples.append((transforms.ToPILImage()(x), label.item()))
        poison_perturbation_norms.append(
            torch.max(torch.abs(x - b_unnormalized)).item()
        )
        x.requires_grad = False
    ####################################################

    ####################################################
    #        Save Poisons
    print(now(), "Saving poisons...")
    if not os.path.isdir(args.poisons_path):
        os.makedirs(args.poisons_path)
    with open(os.path.join(args.poisons_path, "poisons.pickle"), "wb") as handle:
        pickle.dump(poison_tuples, handle, protocol=pickle.HIGHEST_PROTOCOL)
    with open(
        os.path.join(args.poisons_path, "perturbation_norms.pickle"), "wb"
    ) as handle:
        pickle.dump(poison_perturbation_norms, handle, protocol=pickle.HIGHEST_PROTOCOL)
    with open(os.path.join(args.poisons_path, "base_indices.pickle"), "wb") as handle:
        pickle.dump(base_indices, handle, protocol=pickle.HIGHEST_PROTOCOL)
    with open(os.path.join(args.poisons_path, "target.pickle"), "wb") as handle:
        pickle.dump(
            (transforms.ToPILImage()(target_img), target_label),
            handle,
            protocol=pickle.HIGHEST_PROTOCOL,
        )
    to_log_file("poisons saved.", args.output, craft_log)
    ####################################################

    print(now(), "craft_poisons_fc.py done.")
    return

if __name__ == "__main__":

    parser = argparse.ArgumentParser(description="Feature Collision Poison Attack")
    parser.add_argument(
        "--model", default=["resnet18"], nargs="+", type=str, help="model for training"
    )
    parser.add_argument("--dataset", default="CIFAR10", type=str, help="dataset")
    parser.add_argument(
        "--pretrain_dataset", default="CIFAR100", type=str, help="dataset"
    )
    parser.add_argument(
        "--model_path",
        default=["pretrained_models/ResNet18_CIFAR100_A.pth"],
        nargs="+",
        type=str,
        help="Model path",
    )
    parser.add_argument("--normalize", dest="normalize", action="store_true")
    parser.add_argument("--no-normalize", dest="normalize", action="store_false")
    parser.set_defaults(normalize=True)
    parser.add_argument(
        "--output", default="output_default", type=str, help="output subdirectory"
    )
    parser.add_argument(
        "--crafting_iters",
        default=120,
        type=int,
        help="How many iterations when crafting poison?",
    )
    parser.add_argument(
        "--watermark_coeff", default=0.3, type=float, help="Opacity of watermark."
    )
    parser.add_argument(
        "--step_size", default=0.001, type=float, help="Step size in optimization"
    )
    parser.add_argument(
        "--l2", action="store_true", help="use l-2 constrained version of attack."
    )
    parser.add_argument(
        "--epsilon", default=8 / 255, type=float, help="poison perturbation allowance"
    )
    parser.add_argument(
        "--poisons_path",
        default="poison_examples/fc_poisons",
        type=str,
        help="Where to save the poisons?",
    )
    parser.add_argument(
        "--poison_setups",
        type=str,
        default="poison_setups_transfer_learning.pickle",
        help="poison setup pickle file",
    )
    parser.add_argument("--setup_idx", type=int, default=0, help="Which setup to use")
    parser.add_argument(
        "--target_img_idx",
        default=None,
        type=int,
        help="Index of the target image in the claen set.",
    )
    parser.add_argument(
        "--base_indices", nargs="+", default=None, type=int, help="which base images"
    )

    args = parser.parse_args()

    main(args)


import nltk
from nltk.corpus import stopwords
from nltk.corpus import sentiwordnet as swn

class DictionarySentiment(object):
    def __init__(self, trainData, l, r):
        self.tweets, self.labels = trainData['TweetText'], trainData['Sentiment']
        self.data = trainData
        self.l = l
        self.r = r
        self.wnl = nltk.WordNetLemmatizer()
        self.sw = stopwords.words('english')

    def classify(self, message):
        message = message.strip()
        #message = ''.join([char for char in message if char not in '@#"\''])
        message = " ".join([word for word in message.split()
                            if 'http' not in word
                            ])

        sentences = nltk.sent_tokenize(message)
        stokens = [nltk.word_tokenize(sent) for sent in sentences]
        stokens = [sent for sent in stokens if sent not in self.sw]

        taggedlist = []
        for stoken in stokens:
            taggedlist.append(nltk.pos_tag(stoken))

        score_list = []
        for idx, taggedsent in enumerate(taggedlist):
            score_list.append([])
            for idx2, t in enumerate(taggedsent):
                lemmatized = self.wnl.lemmatize(t[0])
                if t[1].startswith('NN'):
                    newtag = 'n'
                elif t[1].startswith('JJ'):
                    newtag = 'a'
                elif t[1].startswith('V'):
                    newtag = 'v'
                elif t[1].startswith('R'):
                    newtag = 'r'
                else:
                    newtag = ''
                if (newtag != ''):
                    synsets = list(swn.senti_synsets(lemmatized, newtag))
                    score = 0
                    if (len(synsets) > 0):
                        for syn in synsets:
                            score += syn.pos_score() - syn.neg_score()
                        score_list[idx].append(score / len(synsets))

        ans = 0

        for score_sent in score_list:
            if (len(score_sent) != 0):
                ans += sum([word_score for word_score in score_sent]) / len(score_sent)

        if ans > self.r:
            return 'positive'
        if ans < self.l:
            return 'negative'
        return 'neutral'

    def predict(self, testData):
        result = []

        for i, row in testData.iterrows():
            result.append(self.classify(row['TweetText']))

        return result


import os
import requests
import datetime
from dateutil.relativedelta import relativedelta

translations = {"Ю": "S", "С": "N", "З": "W", "В": "E", "м": "m", "с": "s"}

def getSimpleParts(source, beginning, ending):
    data = ""
    BrIndex = source.find("
")
    positiveIndex = source.find("")
    # if positive Found
    nullIndex = source.find("label_icon label_small screen_icon")
    if nullIndex != -1:
        data = "null"
    elif positiveIndex != -1:
        startIndex = source.find("")
        endIndex = source.find(ending, startIndex)
        data = source[startIndex + len("") : endIndex]
    # if
 is not found
    elif BrIndex == -1:
        startIndex = source.find(beginning)
        endIndex = source.find(ending, startIndex)
        data = source[startIndex + len(beginning) : endIndex]
    # if
 is found (there won't be other conditins here)
    else:
        BrSpanIndex = source.find("	")
        data = source[BrIndex + len("
") : BrSpanIndex]
    return data

def russianWindNotationsToEnglish(source):
    data = ""
    for str in source:
        isFound = False
        savedValue = ""
        for key in translations:
            if key == str:
                isFound = True
                savedValue = translations[key]
        data += savedValue if isFound else str

    return data

# if it exists, delete it
if os.path.exists("dataset.csv"):
    os.remove("dataset.csv")

# save current Date
currentDate = datetime.date.today()

# open file in append Mode (why not)
with open("dataset.csv", "a") as dataset:
    for day in range(30):
        currentDate -= (
            relativedelta(months=0) if (day == 0) else relativedelta(months=1)
        )

        response = requests.get(
            f"https://www.gismeteo.ru/diary/4980/{currentDate.year}/{currentDate.month}/",
            headers={
                "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"
            },
        )

        startIndex = response.text.find("
")
        endIndex = response.text.find("
", startIndex)
        finalString = response.text[startIndex : endIndex + len("
")]

        currentposition = 0
        appendData = []

        while True:
            toBeAppended = ""

            startCenter = finalString.find('
', currentposition)
            if startCenter == -1:
                break
            endCenter = finalString.find("
", startCenter)
            currentposition = endCenter + len("
")
            finalCenter = finalString[startCenter : endCenter + len("
")]

            arr = []
            incremental = 0

            while finalCenter.find("<td", incremental) != -1:
                beginningIndex = finalCenter.find("<td", incremental)
                endingIndex = finalCenter.find("	", beginningIndex)
                incremental = endingIndex
                string = finalCenter[beginningIndex : endingIndex + len("	")]
                arr.append(string)

            # date
            toBeAppended += f"{currentDate.year}/{currentDate.month}" + ","
            # 0 counter
            toBeAppended += getSimpleParts(arr[0], "", "	") + ","
            # 1D temp
            toBeAppended += (
                getSimpleParts(arr[1], "", "	")
                + ","
            )
            # 2D pressure
            toBeAppended += getSimpleParts(arr[2], "", "	") + ","
            # 5D wind
            toBeAppended += (
                russianWindNotationsToEnglish(
                    getSimpleParts(arr[5], "", "	")
                )
                + ","
            )
            # 6N temp
            toBeAppended += (
                getSimpleParts(arr[6], "", "	")
                + ","
            )
            # 7N pressure
            toBeAppended += getSimpleParts(arr[7], "", "	") + ","
            # 10N wind
            toBeAppended += (
                russianWindNotationsToEnglish(
                    getSimpleParts(arr[10], "", "	")
                )
                + "\n"
            )
            appendData.append(toBeAppended)

        for item in appendData:
            dataset.write(item)


from typing import List, Optional, Sequence, Union

import torch
import torch as to
from torch.distributions.bernoulli import Bernoulli
from torch.distributions.multivariate_normal import MultivariateNormal
from torch.distributions.normal import Normal
from torch.distributions.uniform import Uniform

import pyrado
from pyrado.utils.bijective_transformation import BijectiveTransformation, SqrtTransformation
from pyrado.utils.input_output import print_cbt

class DomainParam:
    """Class to store and manage (probably multiple) domain parameter a.k.a. physics parameter a.k.a. simulator parameter"""

    def __init__(
        self,
        name: Union[str, List[str]],
        clip_lo: Optional[Union[int, float]] = -pyrado.inf,
        clip_up: Optional[Union[int, float]] = pyrado.inf,
        roundint: bool = False,
    ):
        """
        Constructor, also see the constructor of DomainRandomizer.

        :param name: name of the parameter; can be a list of names if this domain parameters supports multiple
                     parameters, e.g., if the distribution respects correlations; this is usually not the case and the
                     only known subclass with this behavior is :py:class:`SelfPacedDomainParam`
        :param clip_lo: lower value for clipping
        :param clip_up: upper value for clipping
        :param roundint: flags if the parameters should be rounded and converted to an integer
        """
        if not isinstance(name, (str, list)):
            raise pyrado.TypeErr(given=name, expected_type=(str, list))

        self.name = name
        self.mean = None  # to be set by subclass
        self.clip_lo = clip_lo
        self.clip_up = clip_up
        self.roundint = roundint
        self.distr = None  # no randomization by default

    def __eq__(self, other):
        """Check if two `DomainParam` are equal by comparing all attributes defined in `get_field_names()`."""
        if not isinstance(other, DomainParam):
            raise pyrado.TypeErr(given=other, expected_type=DomainParam)

        for fn in self.get_field_names():
            if getattr(self, fn) != getattr(other, fn):
                return False
        return True

    def get_field_names(self) -> List[str]:
        """Get union of all hyper-parameters of all domain parameter distributions."""
        return ["name", "clip_lo", "clip_up", "roundint"]

    def adapt(self, domain_distr_param: str, domain_distr_param_value: Union[float, int, to.Tensor]):
        """
        Update this domain parameter.

        .. note::
            This function should by called by the subclasses' `adapt()` function.

        :param domain_distr_param: distribution parameter to update, e.g. mean or std
        :param domain_distr_param_value: new value of the distribution parameter
        """
        if domain_distr_param not in self.get_field_names():
            raise pyrado.KeyErr(
                msg=f"The domain parameter {self.name} does not have a domain distribution parameter "
                f"called {domain_distr_param}!"
            )
        setattr(self, domain_distr_param, domain_distr_param_value)

    def sample(self, num_samples: int = 1) -> Union[List[to.Tensor], List[List[to.Tensor]]]:
        """
        Generate new domain parameter values.

        :param num_samples: number of samples (sets of new parameter values)
        :return: list of tensors containing the new parameter values or list of list of tensors containing the new
                 values for each parameter separately; the outer list is for different parameters, the inner list is for
                 the number of samples
        """
        if not isinstance(num_samples, int):
            raise pyrado.TypeErr(given=num_samples, expected_type=int)
        if num_samples <= 0:
            raise pyrado.ValueErr(given=num_samples, g_constraint="0")

        if self.distr is None:
            raise RuntimeError("Trying to sample a domain parameter without a specified distribution!")

        # Draw num_samples samples (rsample is not implemented for Bernoulli)
        sample_tensor = self.distr.sample(sample_shape=to.Size([num_samples]))

        # Clip the values
        sample_tensor = to.clamp(sample_tensor, self.clip_lo, self.clip_up)

        # Round values to integers if desired
        if self.roundint:
            sample_tensor = to.round(sample_tensor).to(to.int32)

        # Convert the large tensor into a list of small tensors
        return list(sample_tensor)

class UniformDomainParam(DomainParam):
    """Domain parameter sampled from a normal distribution"""

    def __init__(self, mean: Union[int, float, to.Tensor], halfspan: Union[int, float, to.Tensor], **kwargs):
        """
        Constructor

        :param mean: nominal parameter value
        :param halfspan: half interval
        :param kwargs: forwarded to `DomainParam` constructor
        """
        super().__init__(**kwargs)

        self.mean = mean
        self.halfspan = halfspan
        self.distr = Uniform(self.mean - self.halfspan, self.mean + self.halfspan, validate_args=True)

    def get_field_names(self) -> List[str]:
        return ["name", "mean", "halfspan", "clip_lo", "clip_up", "roundint"]

    def adapt(self, domain_distr_param: str, domain_distr_param_value: Union[float, int]):
        # Set the attributes
        super().adapt(domain_distr_param, domain_distr_param_value)

        # Re-create the distribution, otherwise the changes will have no effect
        try:
            self.distr = Uniform(self.mean - self.halfspan, self.mean + self.halfspan, validate_args=True)
        except ValueError as err:
            print_cbt(
                f"Inputs that lead to the ValueError from PyTorch Distributions:"
                f"\ndomain_distr_param = {domain_distr_param}\n"
                f"low = {self.mean - self.halfspan}\nhigh = {self.mean + self.halfspan}"
            )
            raise err

class NormalDomainParam(DomainParam):
    """Domain parameter sampled from a normal distribution"""

    def __init__(self, mean: Union[int, float, to.Tensor], std: Union[int, float, to.Tensor], **kwargs):
        """
        Constructor

        :param mean: nominal parameter value
        :param std: standard deviation
        :param kwargs: forwarded to `DomainParam` constructor
        """
        super().__init__(**kwargs)

        self.mean = mean
        self.std = std
        self.distr = Normal(self.mean, self.std, validate_args=True)

    def get_field_names(self) -> List[str]:
        return ["name", "mean", "std", "clip_lo", "clip_up", "roundint"]

    def adapt(self, domain_distr_param: str, domain_distr_param_value: Union[float, int]):
        # Set the attributes
        super().adapt(domain_distr_param, domain_distr_param_value)

        # Re-create the distribution, otherwise the changes will have no effect
        try:
            self.distr = Normal(self.mean, self.std, validate_args=True)
        except ValueError as err:
            print_cbt(
                f"Inputs that lead to the ValueError from PyTorch Distributions:"
                f"\ndomain_distr_param = {domain_distr_param}\nloc = {self.mean}\nscale = {self.std}"
            )
            raise err

class MultivariateNormalDomainParam(DomainParam):
    """Domain parameter sampled from a normal distribution"""

    def __init__(self, mean: Union[int, float, to.Tensor], cov: Union[list, to.Tensor], **kwargs):
        """
        Constructor

        :param mean: nominal parameter value
        :param cov: covariance
        :param kwargs: forwarded to `DomainParam` constructor
        """
        super().__init__(**kwargs)

        self.mean = to.as_tensor(mean, dtype=to.get_default_dtype()).view(-1)
        self.cov = to.as_tensor(cov, dtype=to.get_default_dtype())
        if not self.cov.ndim == 2:
            raise pyrado.ShapeErr(msg="The covariance needs to be given as a matrix!")
        self.distr = MultivariateNormal(self.mean, self.cov, validate_args=True)

    def get_field_names(self) -> List[str]:
        return ["name", "mean", "cov", "clip_lo", "clip_up", "roundint"]

    def adapt(self, domain_distr_param: str, domain_distr_param_value: to.Tensor):
        if domain_distr_param == "cov" and domain_distr_param_value < 0:
            raise pyrado.ValueErr(given_name="cov", ge_constraint="0")

        # Set the attributes
        super().adapt(domain_distr_param, domain_distr_param_value)

        # Re-create the distribution, otherwise the changes will have no effect
        try:
            self.distr = MultivariateNormal(self.mean, self.cov, validate_args=True)
        except ValueError as err:
            print_cbt(
                f"Inputs that lead to the ValueError from PyTorch Distributions:"
                f"\ndomain_distr_param = {domain_distr_param}\nloc = {self.mean}\ncov = {self.cov}"
            )
            raise err

class BernoulliDomainParam(DomainParam):
    """Domain parameter sampled from a Bernoulli distribution"""

    def __init__(self, val_0: Union[int, float], val_1: Union[int, float], prob_1: float, **kwargs):
        """
        Constructor

        :param val_0: value of event 0
        :param val_1: value of event 1
        :param prob_1: probability of event 1, equals 1 - probability of event 0
        :param kwargs: forwarded to `DomainParam` constructor
        """
        super().__init__(**kwargs)

        self.val_0 = val_0
        self.val_1 = val_1
        self.prob_1 = prob_1
        self.mean = val_0 * (1 - prob_1) + val_1 * prob_1
        self.distr = Bernoulli(self.prob_1, validate_args=True)

    def get_field_names(self) -> List[str]:
        return ["name", "mean", "val_0", "val_1", "prob_1", "clip_lo", "clip_up", "roundint"]

    def adapt(self, domain_distr_param: str, domain_distr_param_value: Union[float, int]):
        # Set the attributes
        super().adapt(domain_distr_param, domain_distr_param_value)

        # Re-create the distribution, otherwise the changes will have no effect
        try:
            self.distr = Bernoulli(self.prob_1, validate_args=True)
        except ValueError as err:
            print_cbt(
                f"Inputs that lead to the ValueError from PyTorch Distributions:"
                f"\ndomain_distr_param = {domain_distr_param}\nprobs = {self.prob_1}"
            )
            raise err

    def sample(self, num_samples: int = 1) -> List[to.Tensor]:
        """
        Generate new domain parameter values.

        :param num_samples: number of samples (sets of new parameter values)
        :return: list of tensors containing the new parameter values
        """
        if not isinstance(num_samples, int):
            raise pyrado.TypeErr(given=num_samples, expected_type=int)
        if num_samples <= 0:
            raise pyrado.ValueErr(given=num_samples, g_constraint="0")

        if self.distr is None:
            raise RuntimeError("Trying to sample a domain parameter without a specified distribution!")

        # Draw num_samples samples (rsample is not implemented for Bernoulli)
        sample_tensor = self.distr.sample(sample_shape=to.Size([num_samples]))

        # Sample_tensor contains either 0 or 1
        sample_tensor = (to.ones_like(sample_tensor) - sample_tensor) * self.val_0 + sample_tensor * self.val_1

        # Clip the values
        sample_tensor = to.clamp(sample_tensor, self.clip_lo, self.clip_up)

        # Round values to integers if desired
        if self.roundint:
            sample_tensor = to.round(sample_tensor).to(to.int32)

        # Convert the large tensor into a list of small tensors
        return list(sample_tensor)

class SelfPacedDomainParam(DomainParam):
    def __init__(
        self,
        name: List[str],
        target_mean: to.Tensor,
        target_cov_flat: to.Tensor,
        init_mean: to.Tensor,
        init_cov_flat: to.Tensor,
        clip_lo: float,
        clip_up: float,
    ):
        """
        Constructor

        :param name: names of the parameters
        :param target_mean: target means of the contextual distribution
        :param target_cov_flat: target covariances of the contextual distribution
        :param init_mean: initial mean of the contextual distribution
        :param init_cov_flat: initial covariances of the contextual distribution
        :param clip_lo: lowest values to allow for sampling
        """

        if not isinstance(name, list):
            raise pyrado.TypeErr(given_name="name", expected_type=list, given=type(name))
        if not (target_mean.shape == init_mean.shape):
            raise pyrado.ShapeErr(msg="Target and init mean should have same shape!")
        if not (target_cov_flat.shape == init_cov_flat.shape):
            raise pyrado.ShapeErr(msg="Target and init standard deviations should have same shape!")

        super().__init__(name=name, clip_lo=clip_lo, clip_up=clip_up)

        self.target_mean = target_mean.double()
        self.target_cov_chol = target_cov_flat.double().sqrt().diag()
        self.context_mean = init_mean.double()
        self.context_cov_chol = init_cov_flat.double().sqrt().diag()

        self.init_mean = self.context_mean.detach().clone()
        self.init_cov_chol = self.context_cov_chol.detach().clone()

        self.dim = target_mean.shape[0]

        self._target_distr = MultivariateNormal(self.target_mean, self.target_cov, validate_args=True)
        self._context_distr = MultivariateNormal(self.context_mean, self.context_cov, validate_args=True)

    def get_field_names(self) -> Sequence[str]:
        """Get union of all hyper-parameters of all domain parameter distributions."""
        return ["context_mean", "context_cov_chol"]

    @staticmethod
    def make_broadening(
        name: List[str],
        mean: List[float],
        init_cov_portion: float = 0.001,
        target_cov_portion: float = 0.1,
        clip_lo: float = -pyrado.inf,
        clip_up: float = pyrado.inf,
    ) -> "SelfPacedDomainParam":
        """
        Creates a self-paced domain parameter having the same initial and target mean, but a larger variance on the
        target distribution.

        :param name: names of the parameters
        :param mean: means of the contextual distribution
        :param init_cov_portion: percentage of the mean the initial variance should be set to
        :param target_cov_portion: percentage of the mean the target variance should be set to
        :param clip_lo: lowest values to allow for sampling
        :param clip_up: highest values to allow for sampling
        """
        if not (len(mean) == len(name)):
            raise pyrado.ValueErr(msg="mean must have same length as names")
        mean = to.tensor(mean)
        return SelfPacedDomainParam(
            name=name,
            target_mean=mean,
            target_cov_flat=target_cov_portion * mean.abs(),
            init_mean=mean,
            init_cov_flat=init_cov_portion * mean.abs(),
            clip_lo=clip_lo,
            clip_up=clip_up,
        )

    @property
    def target_distr(self) -> MultivariateNormal:
        """Get the target distribution."""
        return self._target_distr

    @property
    def context_distr(self) -> MultivariateNormal:
        """Get the current contextual distribution."""
        return self._context_distr

    @property
    def target_cov(self) -> to.Tensor:
        """Get the target covariance matrix."""
        return self.target_cov_chol @ self.target_cov_chol.T

    @property
    def context_cov(self) -> to.Tensor:
        """Get the current covariance matrix."""
        return self.context_cov_chol @ self.context_cov_chol.T

    def adapt(self, domain_distr_param: str, domain_distr_param_value: to.Tensor):
        """
        Update this domain parameter.

        :param domain_distr_param: distribution parameter to update, e.g. mean or cov
        :param domain_distr_param_value: new value of the distribution parameter
        """

        # Set the attributes
        super().adapt(domain_distr_param, domain_distr_param_value)

        # Re-create the distributions, otherwise the changes will have no effect
        if domain_distr_param in ["context_mean", "context_cov_chol"]:
            try:
                self._context_distr = MultivariateNormal(self.context_mean, self.context_cov, validate_args=True)
            except ValueError as err:
                print_cbt(
                    f"Inputs that lead to the ValueError from PyTorch Distributions:\n"
                    f"init_distribution; domain_distr_param = {domain_distr_param}\nloc = {self.context_mean}\ncov = {self.context_cov}"
                )
                raise err

    def sample(self, num_samples: int = 1) -> List[to.tensor]:
        """Samples `num_samples` samples of the current context distribution."""

        if not (num_samples > 0):
            raise pyrado.ValueErr(given_name="num_samples", g_constraint=0)

        samples = self._context_distr.sample((num_samples,))
        valid = torch.logical_and(self.clip_lo <= samples, samples <= self.clip_up)
        while not valid.all():
            resamples = self._context_distr.sample((num_samples,))
            mask = torch.logical_not(valid)
            samples[mask] = resamples[mask]
            valid = torch.logical_and(self.clip_lo <= samples, samples <= self.clip_up)
        return list([list(sample) for sample in samples.T])


import sympy
import numpy as np
def Hessen(x):
    f = "(x2-x1**2)**2+(1-x1)**2"
    vars = sympy.symbols('x1 x2')
    x1= sympy.symbols('x1')
    x2= sympy.symbols('x2')
    f = sympy.sympify([f])
    H = sympy.zeros(len(vars),len(vars))
    for i ,fi in enumerate(f):
        for j,r in enumerate(vars):
            for k,s in enumerate(vars):
                H[j,k] = sympy.diff(sympy.diff(fi,r), s)
    H = H.subs({x1:x[0],x2:x[1]})
    return np.array(H)
def objfun(x):
    return (x[1,0]-x[0,0]**2)**2+(1-x[0,0])**2
def gradobjfun(x):
    return np.array([[4*x[0,0]**3-4*x[0,0]*x[1,0]+2*x[0,0]-2],[2*x[1,0]-2*x[0,0]**2]])
def phi(alpha):
    Dk = np.linalg.inv(Hessen(x))
    gk = gradobjfun(x)
    dk = -1.0*np.dot(Dk,gk)
    return objfun(x+alpha*dk)
def GoldenSearch(x):
    epsilon = 1e-5
    tua = 0.618;ak = 0;bk = 2
    while True:
        if bk - ak < epsilon:
            alpha = (ak+bk)/2
            return alpha
        else:
            landa = ak + (1-tua)*(bk - ak)
            miu = ak + tua*(bk - ak)
            flanda = phi(landa)
            fmiu = phi(miu)
            if flanda>fmiu:
                ak = landa
            else:
                bk = miu
def Quasi_Newton_methods(x,epsilon):
    k = 0
    Dk = np.linalg.inv(Hessen(x))
    x0 = x
    rho = 0.5
    while True:
        gk = gradobjfun(x0)
        if np.linalg.norm(gk) < epsilon:
            return np.hstack((x0[0],x0[1])),objfun(x0),k
        dk = -1.0*np.dot(Dk,gk)
        alpha = GoldenSearch(x0)
        x = x0 + alpha*dk
        sk = x - x0
        yk = gradobjfun(x) - gk
        if np.dot(sk.T,yk)[0,0] > 0:
            ak = np.dot(sk,sk.T)
            bk = np.dot(sk.T,yk)[0,0]
            ck = np.dot(np.dot(np.dot(Dk,yk),yk.T),Dk)
            dk = np.dot(np.dot(yk.T,Dk),yk)[0,0]
            Dk = Dk + ak/bk - ck/dk
        x0 = x
        k += 1

if __name__ == "__main__":
    epsilon = float(input("阀值："))
    x = np.array([[3],[2]])
    x_min, f_min, k = Quasi_Newton_methods(x,epsilon)
    print("x_min:",x_min)
    print("f_min:",f_min)
    print("迭代数:",k)


import math
import random
import numpy as np
import pandas as pd
import nltk

def split_to_sentences(data):
    """
    Split data by line break "\n"

    Args:
        data: str

    Returns:
        A list of sentences
    """
    # Splitting data by line break
    sentences = data.split('\n')

    sentences = [s.strip() for s in sentences] # removing leading and trailing spaces from each sentence
    sentences = [s for s in sentences if len(s) > 0] # dropping sentences if they are empty strings

    return sentences

def tokenize_sentences(sentences):
    """
    Tokenize sentences into tokens (words)

    Args:
        sentences: List of strings

    Returns:
        List of lists of tokens
    """

    # Initializing the list of lists of tokenized sentences
    tokenized_sentences = []

    # Going through each sentence
    for sentence in sentences:
        sentence = sentence.lower() # converting to lowercase letters
        tokenized = nltk.word_tokenize(sentence) # converting into a list of words
        tokenized_sentences.append(tokenized) # appending the list of words to the list of lists

    return tokenized_sentences

def get_tokenized_data(data):
    """
    Make a list of tokenized sentences

    Args:
        data: String

    Returns:
        List of lists of tokens
    """

    # Getting the sentences by splitting up the data
    sentences = split_to_sentences(data)

    # Getting the list of lists of tokens by tokenizing the sentences
    tokenized_sentences = tokenize_sentences(sentences)

    return tokenized_sentences

def count_words(tokenized_sentences):
    """
    Count the number of word appearence in the tokenized sentences

    Args:
        tokenized_sentences: List of lists of strings

    Returns:
        dict that maps word (str) to the frequency (int)
    """

    word_counts = {}

    # Looping through each sentence
    for sentence in tokenized_sentences:
        # Going through each token in the sentence
        for token in sentence:
            # If the token is not in the dictionary yet, setting the count to 1
            if token not in word_counts:
                word_counts[token] = 1

            # If the token is already in the dictionary, incrementing the count by 1
            else:
                word_counts[token] += 1

    return word_counts

def get_words_with_nplus_frequency(tokenized_sentences, count_threshold):
    """
    Find the words that appear N times or more

    Args:
        tokenized_sentences: List of lists of sentences
        count_threshold: minimum number of occurrences for a word to be in the closed vocabulary.

    Returns:
        List of words that appear N times or more
    """
    # Initializing an empty list to contain the words that appear at least 'count_threshold' times.
    closed_vocab = []

    # Getting the word counts of the tokenized sentences
    word_counts = count_words(tokenized_sentences)

    # Looping through word-count key-value pairs
    for word, cnt in word_counts.items():
        if cnt >= count_threshold: # checking that the count is equal or more than the threshold
            closed_vocab.append(word) # appending the word to the list

    return closed_vocab

def replace_oov_words_by_unk(tokenized_sentences, vocabulary, unknown_token="<unk>"):
    """
    Replace words not in the given vocabulary with '<unk>' token.

    Args:
        tokenized_sentences: List of lists of strings
        vocabulary: List of strings that we will use
        unknown_token: A string representing unknown (out-of-vocabulary) words

    Returns:
        List of lists of strings, with words not in the vocabulary replaced
    """

    # Place vocabulary into a set for faster search
    vocabulary = set(vocabulary)

    # Initializing a list that will hold the sentences after less frequent words are replaced by the unknown token
    replaced_tokenized_sentences = []

    # Going through each sentence
    for sentence in tokenized_sentences:

        # Initializing the list that will contain a single sentence with "unknown_token" replacements
        replaced_sentence = []

        # Going through each token in the sentence
        for token in sentence:
            if token in vocabulary: # checking if the token is in the closed vocabulary
                replaced_sentence.append(token) # appending the word to the replaced sentence
            else:
                replaced_sentence.append(unknown_token) # otherwise, appending the unknown token

        # Appending the list of tokens to the list of lists
        replaced_tokenized_sentences.append(replaced_sentence)

    return replaced_tokenized_sentences

def preprocess_data(train_data, test_data, count_threshold):
    """
    Preprocess data, i.e.,
        - Find tokens that appear at least N times in the training data.
        - Replace tokens that appear less than N times by "<unk>" both for training and test data.
    Args:
        train_data, test_data: List of lists of strings.
        count_threshold: Words whose count is less than this are
                      treated as unknown.

    Returns:
        Tuple of
        - training data with low frequent words replaced by "<unk>"
        - test data with low frequent words replaced by "<unk>"
        - vocabulary of words that appear n times or more in the training data
    """

    # Getting the closed vocabulary using the training data
    vocabulary = get_words_with_nplus_frequency(train_data, count_threshold)

    # For the training data, replacing less common words with "<unk>"
    train_data_replaced = replace_oov_words_by_unk(train_data, vocabulary, unknown_token="<unk>")

    # For the testing data, replacing less common words with "<unk>"
    test_data_replaced = replace_oov_words_by_unk(test_data, vocabulary, unknown_token="<unk>")

    return train_data_replaced, test_data_replaced, vocabulary

def count_n_grams(data, n, start_token='<s>', end_token = '<e>'):
    """
    Count all n-grams in the data

    Args:
        data: List of lists of tokens
        n: number of tokens in a sequence for the n-gram model

    Returns:
        A dictionary that maps a tuple of n-words to its frequency
    """

    # Initializing dictionary of n-grams and their counts
    n_grams = {}

    # Going through each sentence in the data
    for sentence in data:

        # Prepending start token n times, and  appending <e> one time (kind of padding for this model)
        sentence = [start_token] * n + sentence + [end_token]

        # Convert list to tuple so that the sequence of words can be used as a key in the dictionary
        sentence = tuple(sentence)

        for i in range(len(sentence) - n + 1): # looping through tokens to get the n-grams

            # Getting the n-gram from i to i+n
            n_gram = sentence[i:i+n]

            # Checking if the n-gram is in the dictionary
            if n_gram in n_grams:
                n_grams[n_gram] += 1 # incrementing the count for this n-gram
            else:
                n_grams[n_gram] = 1 # initializing this n-gram count to 1

    return n_grams

def estimate_probability(word, previous_n_gram, n_gram_counts, n_plus1_gram_counts, vocabulary_size, k=1.0):
    """
    Estimate the probabilities of a next word using the n-gram counts with k-smoothing

    Args:
        word: next word
        previous_n_gram: A sequence of words of length n
        n_gram_counts: Dictionary of counts of n-grams
        n_plus1_gram_counts: Dictionary of counts of (n+1)-grams
        vocabulary_size: number of words in the vocabulary
        k: positive constant, smoothing parameter

    Returns:
        A probability
    """
    # Converting list to tuple to use it as a dictionary key
    previous_n_gram = tuple(previous_n_gram)

    # If the previous n-gram exists in the dictionary of n-gram counts, we get its count; otherwise, we set the count to zero
    previous_n_gram_count = n_gram_counts.get(previous_n_gram, 0)

    # Calculating the denominator using the count of the previous n gram and applying k-smoothing
    denominator = previous_n_gram_count + k * vocabulary_size

    # Defining n plus 1 gram as the previous n-gram plus the current word as a tuple
    n_plus1_gram = previous_n_gram + (word,)

    # Setting the count to the count in the dictionary; otherwise, 0 if not in the dictionary
    n_plus1_gram_count = n_plus1_gram_counts.get(n_plus1_gram, 0)

    # Defining the numerator using the count of the n-gram plus current word and applying smoothing
    numerator = n_plus1_gram_count + k

    # Calculating the probability as the numerator divided by denominator
    probability = numerator / denominator

    return probability

def estimate_probabilities(previous_n_gram, n_gram_counts, n_plus1_gram_counts, vocabulary, k=1.0):
    """
    Estimate the probabilities of next words using the n-gram counts with k-smoothing

    Args:
        previous_n_gram: A sequence of words of length n
        n_gram_counts: Dictionary of counts of n-grams
        n_plus1_gram_counts: Dictionary of counts of (n+1)-grams
        vocabulary: List of words
        k: positive constant, smoothing parameter

    Returns:
        A dictionary mapping from next words to the probability.
    """

    # Converting list to tuple to use it as a dictionary key
    previous_n_gram = tuple(previous_n_gram)

    # Adding <e> <unk> to the vocabulary
    vocabulary = vocabulary + ["<e>", "<unk>"]
    vocabulary_size = len(vocabulary)

    probabilities = {} # initializing the dictionary where we will store the word with each probability
    for word in vocabulary:
        probability = estimate_probability(word, previous_n_gram, n_gram_counts, n_plus1_gram_counts, vocabulary_size, k=k) # estimating probability of word
        probabilities[word] = probability # the value of the word (key) will be the probability itself

    return probabilities

def suggest_a_word(previous_tokens, n_gram_counts, n_plus1_gram_counts, vocabulary, k=1.0, start_with=None):
    """
    Get suggestion for the next word

    Args:
        previous_tokens: The sentence you input where each token is a word. Must have length > n
        n_gram_counts: Dictionary of counts of n-grams
        n_plus1_gram_counts: Dictionary of counts of (n+1)-grams
        vocabulary: List of words
        k: positive constant, smoothing parameter
        start_with: If not None, specifies the first few letters of the next word

    Returns:
        A tuple of
          - string of the most likely next word
          - corresponding probability
    """

    # Length of previous words
    n = len(list(n_gram_counts.keys())[0])

    # From the words that the user already typed, getting the most recent 'n' words as the previous n-gram
    previous_n_gram = previous_tokens[-n:]

    # Estimating the probabilities that each word in the vocabulary is the next word
    probabilities = estimate_probabilities(previous_n_gram, n_gram_counts, n_plus1_gram_counts, vocabulary, k=k)

    # Initializing suggested word to None; this will be set to the word with highest probability
    suggestion = None

    # Initializing the highest word probability to 0; this will be set to the highest probabilityof all words to be suggested
    max_prob = 0

    # Looping through every word and probability
    for word, prob in probabilities.items():

        # If the optional start_with string is set
        if start_with != None:
            if word.startswith(start_with) is False: # checking if the beginning of the word does not match with the letters in 'start_with'
                continue # if they don't match, skip this word and move onto the next word

        if prob > max_prob: # checking if this word's probability is greater than the current maximum probability
            suggestion = word # the suggestion becomes the word itself
            max_prob = prob # saving the new maximum probability

    return suggestion, max_prob

def get_suggestions(previous_tokens, n_gram_counts_list, vocabulary, k=1.0, start_with=None):
    """
    Get suggestions from the input sequence

    Args:
        previous_tokens: The sentence you input where each token is a word. Must have length > n
        n_gram_counts_list: List of dictionaries with n-gram counts
        vocabulary: List of words
        k: positive constant, smoothing parameter
        start_with: If not None, specifies the first few letters of the next word

    Returns:
        A list of suggestions in the form of a tuple for each entry (suggestion, probability)
    """
    model_counts = len(n_gram_counts_list)
    suggestions = []
    for i in range(model_counts-1):
        n_gram_counts = n_gram_counts_list[i] # getting n-gram counts of each model
        n_plus1_gram_counts = n_gram_counts_list[i+1] # getting n-gram plus 1 counts of each model

        suggestion = suggest_a_word(previous_tokens, n_gram_counts, n_plus1_gram_counts, vocabulary, k=k, start_with=start_with) # getting suggestion
        suggestions.append(suggestion) # appending to suggestions
    return suggestions


from . import jbEcho
from . import jbFields

import re

cols = "id,key"

# ====================================================
# Return the current column confifguration as a string.
# ====================================================
def columns():
    return cols

# ====================================================
# Append the current column selection to a search URL
# ====================================================
def appendToUrl( url ):
    # select * does nothing to the URL
    if cols == "*":
        return url

    # otherwise, append something ...
    url = url + "&fields="

    ids = list()
    for col in cols.split(","):
        ids.append( jbFields.findIdByEasy( col ) )

    return url + ",".join( ids )

# ==================================================
# Print or set the columns that will be selected
# ==================================================
def columnsf( ins ):
    global cols

    # Add columns to the string
    if len(ins) > 1 and ins[0] == '+':
        if cols == "*":
            cols = ins[1]
        else:
            cols = cols + "," + ",".join(ins[1:])
        columnsParsef( cols.split(",") )

    # Remove a column from the string
    elif len(ins) > 1 and ins[0] == '-':
        arr = cols.split( "," )
        j = 1

        # Set any existing column which matches an input to the empty string. Then reparse the array.
        while j < len(ins):
            i = 0
            while i < len(arr):
                if arr[i] == ins[j]:
                    arr[i] = ''
                i = i + 1
            j = j + 1

        columnsParsef( arr )

    elif len(ins) == 1 and ins[0] == "--":
        cols = "*"

    # Parse the ins as individual columns
    elif len(ins) > 0:
        columnsParsef( ins )

    jbEcho.echo( "Columns are %s" % cols )

# ==========================================================================
# Parse the arguments and produce a columns string for the SELECT parameter
# ==========================================================================
def columnsParsef( ins ):
    global cols
    cols = ""

    # Take all the params into an uber string separated by spaces
    joined = " ".join( ins )

    # Split this string by commas and spaces again. This allows for inconsistent
    # inputs, e.g. "columns a,b, c d" can be handled.
    for c in re.split( ",| ", joined ):
        if ( len(c) > 0 ):
            cols = cols + c + ","

    # Trim that pesky trailing comma
    cols = cols[:-1]


import logging
from telethon import sync, TelegramClient, events
from telethon.tl.types import InputPeerChannel
from telethon.tl.types import InputPeerUser
from telethon.tl.functions.channels import InviteToChannelRequest
from telethon.errors.rpcerrorlist import PeerFloodError, UserPrivacyRestrictedError, FloodWaitError
import time
import traceback
import datetime
import os
import json

def get_group_by_id(groups, group_id):
    for group in groups:
        if (group_id == int(group['group_id'])):
            return group
    return None

root_path = os.path.dirname(os.path.abspath(__file__))
print(root_path)

start_time = datetime.datetime.now()
logging.basicConfig(level=logging.WARNING)

with open('config.json', 'r', encoding='utf-8') as f:
    config = json.loads(f.read())

account = config['account']
print("Total account: " + str(len(account)))
folder_session = 'session/'

# group target
group_target_id = int(config['group_target'])
# group source
group_source_id = int(config['group_source'])
# date_online_from
from_date_active = '19700101'
if 'from_date_active' in config:
    from_date_active = config['from_date_active']

# list client
clients = []

api_id = account['api_id']
api_hash = account['api_hash']
phone = account['phone']

client = TelegramClient(folder_session + phone, api_id, api_hash)

client.connect()

if client.is_user_authorized():
    print(phone + ' login success')
    clients.append({
        'phone': phone,
        'client': client
    })
else:
    print(phone + ' login fail')

filter_clients = []

for my_client in clients:
    phone = my_client['phone']
    path_group = root_path + '/data/group/' + phone + '.json'
    if os.path.isfile(path_group):

        with open(path_group, 'r', encoding='utf-8') as f:
            groups = json.loads(f.read())

        current_target_group = get_group_by_id(groups, group_target_id)

        if current_target_group:
            group_access_hash = int(current_target_group['access_hash'])
            target_group_entity = InputPeerChannel(
                group_target_id, group_access_hash)

            path_group_user = root_path + '/data/user/' + \
                phone + "_" + str(group_source_id) + '.json'
            if os.path.isfile(path_group_user):
                # add target_group_entity key value
                my_client['target_group_entity'] = target_group_entity
                with open(path_group_user, encoding='utf-8') as f:
                    my_client['users'] = json.loads(f.read())

                filter_clients.append(my_client)
            else:
                print('This account with phone ' +
                      str(phone) + ' is not in source group')
        else:
            print('This account with phone ' +
                  str(phone) + ' is not in target group')
    else:
        print(
            'This account with phone do not have data. Please run get_data or init_session')

# run
previous_count = 0
count_add = 0

try:
    with open(root_path + '/current_count.txt') as f:
        previous_count = int(f.read())
except Exception as e:
    pass

print('From index: ' + str(previous_count))
total_client = len(filter_clients)

total_user = filter_clients[0]['users'].__len__()

i = 0
while i < total_user:

    # previous run
    if i < previous_count:
        i += 1
        continue

    # count_add if added 35 user
    if count_add % (35 * total_client) == (35 * total_client - 1):
        print('sleep 15 minute')
        time.sleep(15 * 60)

    total_client = filter_clients.__len__()
    print("remain client: " + str(total_client))
    if total_client == 0:
        with open(root_path + '/current_count.txt', 'w') as g:
            g.write(str(i))
            g.close()

        print('END: accounts is empty')
        break

    current_index = count_add % total_client
    print("current_index: " + str(current_index))
    current_client = filter_clients[current_index]
    client = current_client['client']
    user = current_client['users'][i]

    if user['date_online'] != 'online' and user['date_online'] < from_date_active:
        i += 1
        print('User ' + user['user_id'] + ' has time active: ' +
              user['date_online'] + ' is overdue')
        continue

    target_group_entity = current_client['target_group_entity']

    try:
        print('add member: ' + user['user_id'])
        user_to_add = InputPeerUser(
            int(user['user_id']), int(user['access_hash']))
        client(InviteToChannelRequest(target_group_entity, [user_to_add]))
        print('Add member ' + user['user_id'] + ' success')
        count_add += 1
        print('sleep: ' + str(120 / total_client))
        time.sleep(120 / total_client)

    except PeerFloodError as e:
        print("Error Fooling cmnr")
        traceback.print_exc()
        print("remove client: " + current_client['phone'])
        client.disconnect()
        filter_clients.remove(current_client)

        # not increate i
        continue
    except UserPrivacyRestrictedError:
        print("Error Privacy")
    except:
        print("Error other")
    # break

    i += 1

with open(root_path + '/current_count.txt', 'w') as g:
    g.write(str(i))
    g.close()
print("disconnect")
for cli in clients:
    cli['client'].disconnect()
end_time = datetime.datetime.now()
print("total: " + str(count_add))
print("total time: " + str(end_time - start_time))


from django.shortcuts import render
import json
from rest_framework_jwt.utils import jwt_decode_handler
from django.views.decorators.csrf import csrf_exempt
from django.http import JsonResponse, HttpResponse
from .database.orderOFdiagram import orderDate

from collections import Counter
import json
import datetime
from .database import analiticsQuery,TopClient
from .consts import  getinterval,GetJsonDSOC,getmaxel, CountSumOfDict
# Create your views here.

@csrf_exempt
def TopClients(request):

    body = json.loads(request.body)
    userID = jwt_decode_handler(body["access"])['sub']
    date_start = body['datastart']
    date_end = body['dataend']
    statistic = TopClient.GetTopClient(analiticsQuery.GetCompany(userID),date_start,date_end)
    data = []
    for i in statistic:
        block_data = {
            'client': i[0],
            'count': i[1],
            'sum': i[2],
        }
        data.append(block_data)

    return JsonResponse(
        {'count': len(statistic),
            'data': data },
        headers={
            "Access-Control-Allow-Origin": "*"
        }
    )

@csrf_exempt
def analytics(request):
    body = json.loads(request.body)
    userID = jwt_decode_handler(body["access"])

    date_start = body['datastart']
    date_end = body['dataend']

    statistic = analiticsQuery.getAnaliz(analiticsQuery.GetCompany(userID['sub']),date_start,date_end)
    data = []
    all_sum =0
    for i in statistic:
        block_data = {
            'name': i[0],
            'total': i[1],
            'avg':float(i[2]),
            "workload":  float(i[3])
        }
        data.append(block_data)
        all_sum+=i[1]

    return JsonResponse(
    {
        'sum':all_sum,
        'count': len(statistic),
        'data': data
    },
        headers={
            "Access-Control-Allow-Origin": "*"
        }
    )

@csrf_exempt
def diagram(request):
    body = json.loads(request.body)
    userID = jwt_decode_handler(body["access"])['sub']
    print(analiticsQuery.GetCompany(userID))
    date_start = body['datastart']
    date_end = body['dataend']

    dates = getinterval(date_start,date_end)
    statistic = orderDate(analiticsQuery.GetCompany(userID),date_start,date_end)
    station_list = []
    for j in statistic:
        if not (j[0] in station_list):
            station_list.append(j[0])
    print(station_list)

    i = 0

    masvalue = [[]* 1 for _ in range((len(station_list)))]
    dailyIncomeMas  = [[] * 1 for _ in range((len(station_list)))]
    print(masvalue)
    negr = []
    hui = []
    formated_dates= []
    for date in dates:

        formated_dates.append( date[5:])
        for stat in statistic:

            if str(stat[1].date()) == date:
                hui.append(stat[0])

                negr.append({
                    f'{stat[0]}': stat[2]
                })
                print(stat)
                i += 1
        print(negr)
        if hui == []:
            j = 0
            for x in station_list:
                masvalue[j].append(0)
                dailyIncomeMas[j].append(0)
                j += 1
        else:
            j = 0
            sumOrders = CountSumOfDict(station_list,negr)
            for x in station_list:
                carwarshIndex = station_list.index(x)
                counts = Counter(hui)
                masvalue[j].append(counts[x])
                dailyIncomeMas[j].append(sumOrders[carwarshIndex][x])
                j += 1

        hui = []
        negr=[]
    print(dailyIncomeMas)
    print(getmaxel(masvalue))
    #orders.append( GetJsonDSOC(date,hui, station_list))

    return JsonResponse(
        { 'stationList': station_list,
            'dates': formated_dates,
            'values': masvalue,
            'maxEl': getmaxel(masvalue),
            'dailyIncomes' : dailyIncomeMas,
            'maxIncome': getmaxel(dailyIncomeMas)
          },
        headers={
            "Access-Control-Allow-Origin": "*"
        }
    )


# Pode correr o programa sem argumentos:
#   python3 shop
# ou passando outros ficheiros de produtos como argumento:
#   python3 shop produtos1.txt ...

def loadDataBase(fname, produtos):
    """Lê dados do ficheiro fname e atualiza/acrescenta a informação num
    dicionário de produtos com o formato {código: (nome, secção, preço, iva), ...}.
    """
    x = open(fname)
    x.readline()
    for line in x:
        line = line.split("%\n")[0].split(";")
        line[-1] = int(line[-1]) / 100
        line[-2] = float(line[-2])
        produtos[line[0]] = tuple(line[1:])
    return produtos

def registaCompra(produtos):
    """Lê códigos de produtos (ou códigos e quantidades),
    mostra nome, quantidade e preço final de cada um,
    e devolve dicionário com {codigo: quantidade, ...}
    """
    dic = {}
    while 1:
        c = input("Code? ")
        if c == "":
            break
        a = c.split()
        if a[0] in produtos:
            if not a[0] in dic:
                dic[a[0]] = 0
            if len(a) == 1:
                dic[a[0]] += 1
                q = 1
            else:
                dic[a[0]] += int(a[-1])
                q = int(a[-1])
            p = round((produtos[a[0]][-1] + 1) * produtos[a[0]][-2] * q, 2)
            print(produtos[a[0]][0], q, p)
    return dic

def fatura(produtos, nfatura):
    """Imprime a fatura de uma dada compra."""
    while len(nfatura) > 0:
        f = int(input("Numero compra? "))
        if 0 < f <= len(nfatura):
            compra = nfatura[f - 1]
            tb = 0
            tiva = 0
            a = []
            for i in compra.keys():
                if not produtos[i][1] in a:
                    a.append(produtos[i][1])
            for n in a:
                print(n)
                for i in compra:
                    if produtos[i][1] == n:
                        p = round((produtos[i][-1] + 1) * produtos[i][-2] * compra[i], 2)
                        tb += produtos[i][-2] * compra[i]
                        tiva += (produtos[i][-1]) * produtos[i][-2] * compra[i]
                        iva = int(produtos[i][-1] * 100)
                        print("{:>4} {:<30s} ({:>2}%) {:>10}".format(compra[i], produtos[i][0], iva, p))
            print("{:>41} {:>10}".format("Total bruto:", round(tb, 2)))
            print("{:>41} {:>10}".format("Total IVA:", round(tiva, 2)))
            print("{:>41} {:>10}".format("Total liquido:", round(tb + tiva, 2)))
            break

def main(args):
    # produto guarda a informação da base de dados numa forma conveniente.
    produtos = {'p1': ('Ketchup.', 'Mercearia Salgado', 1.59, 0.23)}
    # Carregar base de dados principal
    loadDataBase("produtos.txt", produtos)
    # Juntar bases de dados opcionais (Não altere)
    for arg in args:
        loadDataBase(arg, produtos)

    # Use este código para mostrar o menu e ler a opção repetidamente
    MENU = "(C)ompra (F)atura (S)air ? "
    repetir = True
    nfatura = []
    while repetir:
        # Utilizador introduz a opção com uma letra minúscula ou maiúscula
        op = input(MENU).upper()
        # Processar opção
        if op == "C":
            # Esta opção regista os produtos de uma compra
            compra = registaCompra(produtos)
            nfatura.append(compra)
        elif op == "F":
            fatura(produtos, nfatura)
        elif op == "S":
            break

            # Aqui pode acrescentar a compra a uma estrutura de dados adequada...
        # Acrescente outras opções aqui...

    print("Obrigado!")

# Não altere este código / Do not change this code
import sys

if __name__ == "__main__":
    main(sys.argv[1:])


#!/usr/bin/env python3
# -*- coding: utf-8 -*-

# Multithreaded simple HTTP directory server.
#
# The files can optionally be aes-256-cbc encrypted in a way that's compatible with:
#   openssl enc -aes-256-cbc -d -in encrypted.data -out decrypted.data

import argparse
import hashlib
import os
import sys
from threading import Thread
from socketserver import ThreadingMixIn
from http.server import HTTPServer, SimpleHTTPRequestHandler
from Crypto.Cipher import AES

from malcolm_utils import str2bool, eprint, EVP_KEY_SIZE, PKCS5_SALT_LEN, OPENSSL_ENC_MAGIC, EVP_BytesToKey

###################################################################################################
args = None
debug = False
script_name = os.path.basename(__file__)
script_path = os.path.dirname(os.path.realpath(__file__))
orig_path = os.getcwd()

###################################################################################################
#
class HTTPHandler(SimpleHTTPRequestHandler):
    # return full path based on server base path and requested path
    def translate_path(self, path):
        path = SimpleHTTPRequestHandler.translate_path(self, path)
        relpath = os.path.relpath(path, os.getcwd())
        fullpath = os.path.join(self.server.base_path, relpath)
        return fullpath

    # override do_GET so that files are encrypted, if requested
    def do_GET(self):
        global debug
        global args

        fullpath = self.translate_path(self.path)

        if (not args.encrypt) or os.path.isdir(fullpath):
            # unencrypted, just use default implementation
            SimpleHTTPRequestHandler.do_GET(self)

        else:
            # encrypt file transfers
            if os.path.isfile(fullpath) or os.path.islink(fullpath):
                self.send_response(200)
                self.send_header('Content-type', 'application/octet-stream')
                self.send_header('Content-Disposition', f'attachment; filename={os.path.basename(fullpath)}.encrypted')
                self.end_headers()
                salt = os.urandom(PKCS5_SALT_LEN)
                key, iv = EVP_BytesToKey(EVP_KEY_SIZE, AES.block_size, hashlib.sha256, salt, args.key.encode('utf-8'))
                cipher = AES.new(key, AES.MODE_CBC, iv)
                encrypted = b""
                encrypted += OPENSSL_ENC_MAGIC
                encrypted += salt
                self.wfile.write(encrypted)
                with open(fullpath, 'rb') as f:
                    padding = b''
                    while True:
                        chunk = f.read(cipher.block_size)
                        if len(chunk) < cipher.block_size:
                            remaining = cipher.block_size - len(chunk)
                            padding = bytes([remaining] * remaining)
                        self.wfile.write(cipher.encrypt(chunk + padding))
                        if padding:
                            break

            else:
                self.send_error(404, "Not Found")

###################################################################################################
#
class ThreadingHTTPServer(ThreadingMixIn, HTTPServer):
    def __init__(self, base_path, server_address, RequestHandlerClass=HTTPHandler):
        self.base_path = base_path
        HTTPServer.__init__(self, server_address, RequestHandlerClass)

###################################################################################################
#
def serve_on_port(path: str, port: int):
    server = ThreadingHTTPServer(path, ("", port))
    print(f"serving {path} at port {port}")
    server.serve_forever()

###################################################################################################
# main
def main():
    global args
    global debug
    global orig_path

    defaultDebug = os.getenv('EXTRACTED_FILE_HTTP_SERVER_DEBUG', 'false')
    defaultEncrypt = os.getenv('EXTRACTED_FILE_HTTP_SERVER_ENCRYPT', 'false')
    defaultPort = int(os.getenv('EXTRACTED_FILE_HTTP_SERVER_PORT', 8440))
    defaultKey = os.getenv('EXTRACTED_FILE_HTTP_SERVER_KEY', 'quarantined')
    defaultDir = os.getenv('EXTRACTED_FILE_HTTP_SERVER_PATH', orig_path)

    parser = argparse.ArgumentParser(
        description=script_name, add_help=False, usage='{} <arguments>'.format(script_name)
    )
    parser.add_argument(
        '-v',
        '--verbose',
        dest='debug',
        type=str2bool,
        nargs='?',
        const=True,
        default=defaultDebug,
        metavar='true|false',
        help=f"Verbose/debug output ({defaultDebug})",
    )
    parser.add_argument(
        '-p',
        '--port',
        dest='port',
        help=f"Server port ({defaultPort})",
        metavar='<port>',
        type=int,
        default=defaultPort,
    )
    parser.add_argument(
        '-d',
        '--directory',
        dest='serveDir',
        help=f'Directory to serve ({defaultDir})',
        metavar='<directory>',
        type=str,
        default=defaultDir,
    )
    parser.add_argument(
        '-e',
        '--encrypt',
        dest='encrypt',
        type=str2bool,
        nargs='?',
        const=True,
        default=defaultEncrypt,
        metavar='true|false',
        help=f"Encrypt files with aes-256-cbc ({defaultEncrypt})",
    )
    parser.add_argument(
        '-k',
        '--key',
        dest='key',
        help="File encryption key",
        metavar='<str>',
        type=str,
        default=defaultKey,
    )
    try:
        parser.error = parser.exit
        args = parser.parse_args()
    except SystemExit:
        parser.print_help()
        exit(2)

    debug = args.debug
    if debug:
        eprint(os.path.join(script_path, script_name))
        eprint("Arguments: {}".format(sys.argv[1:]))
        eprint("Arguments: {}".format(args))
    else:
        sys.tracebacklimit = 0

    Thread(target=serve_on_port, args=[args.serveDir, args.port]).start()

###################################################################################################
if __name__ == '__main__':
    main()


"""Training an saving of a Tensorflow RNN model using LSTM cells
 to differentiate between true and false embedded reber grammars"""

import rebergood as rbg
import reberbad as rbb
import numpy as np
import tensorflow as tf

dataset_size = 10000
true_percent = 0.5
true_count = int(dataset_size*true_percent)
false_count = dataset_size - true_count

# Generate the dataset of strings and corresponding labels
dataset = np.zeros(shape=[0, 2])
for i in range(true_count):
    unit = np.array((rbg.embedded_reber(), 0))
    dataset = np.vstack((dataset, unit))

for j in range(false_count):
    unit = np.array((rbb.embedded_reber_bad(), 1))
    dataset = np.vstack((dataset, unit))

rand_indices = np.random.permutation(dataset_size)
dataset = dataset[rand_indices]

# Split into strings and labels
X_dat = dataset[:, 0]
y_dat = dataset[:, 1]
max_len = max([len(i) for i in X_dat])

# converts string into a sparse matrix
def sparserizer(word, length= -20):
    if length == -20:
        length = len(word)
    sparse = np.zeros(shape=[7, length])

    for i in range(len(word)):
        letter = word[i]
        sparsecol = sparse[:, i]
        if letter == "B":
            sparsecol[0] = 1
        if letter == "E":
            sparsecol[1] = 1
        if letter == "P":
            sparsecol[2] = 1
        if letter == "S":
            sparsecol[3] = 1
        if letter == "T":
            sparsecol[4] = 1
        if letter == "V":
            sparsecol[5] = 1
        if letter == "X":
            sparsecol[6] = 1

    return sparse

# converts a batch of strings into a sparse matrix
def batch_sparse(dataset, batch_size, batch_num):
    words = X_dat[batch_size * batch_num:batch_size * batch_num + batch_size]
    y = y_dat[batch_size * batch_num:batch_size * batch_num + batch_size]
    lens = [len(s) for s in words]
    length = max_len
    sparse_table = np.zeros(shape=[0, 7])
    for word in words:
        sparse_table = np.vstack((sparse_table, sparserizer(word, length).transpose()))

    sparse_table = np.reshape(sparse_table, [-1, length, 7])
    return sparse_table, y, lens

# Building the Tensorflow Graph

learning_rate = 0.001

X = tf.placeholder(tf.float32, [None, max_len, 7])
y = tf.placeholder(tf.int32, [None])
lens = tf.placeholder(tf.int32, [None])
basic_cell = tf.contrib.rnn.GRUCell(num_units=170)
outputs, states = tf.nn.dynamic_rnn(basic_cell, X, dtype=tf.float32, sequence_length=lens)

logits = tf.layers.dense(states, 2)
xentropy = tf.nn.sparse_softmax_cross_entropy_with_logits(labels=y,
                                                          logits=logits)
loss = tf.reduce_mean(xentropy)
optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate)
training_op = optimizer.minimize(loss)
correct = tf.nn.in_top_k(logits, y, 1)
accuracy = tf.reduce_mean(tf.cast(correct, tf.float32))

init = tf.global_variables_initializer()
saver = tf.train.Saver()

# Preparing the execution phase
n_epochs = 100
batch_size = 40
num_batches = dataset_size // batch_size

with tf.Session() as sess:
    init.run()
    for epoch in range(n_epochs):
        for iteration in range(num_batches - 2):
            X_batch, y_batch, lens_batch = batch_sparse(X_dat, batch_size, iteration)
            sess.run(training_op, feed_dict={X: X_batch, y: y_batch, lens: lens_batch})
        acc_train = accuracy.eval(feed_dict={X: X_batch, y: y_batch, lens: lens_batch})
        X_test, y_test, lens_test = batch_sparse(X_dat, batch_size, num_batches - 1)
        acc_test = accuracy.eval(feed_dict={X: X_test, y: y_test, lens: lens_test})
        print(epoch, "Train accuracy:", acc_train, "Test accuracy:", acc_test)

    saver.save(sess, "my_reber_model")


# Write a class called Admin that inherits from  User class in Exercise 9-5.
# Add an attribute, privileges, that stores a list of strings like
# "can add post", "can delete post", "can ban user", and so on.
# Write a method called show_privileges() that lists the admin’s privileges.
# Create an instance of Admin, and call your method.

class User:
    """A class that prints user's first and last name."""
    def __init__(
            self, first_name, last_name,
            username, email, location):
        """Initialize the user."""
        self.first_name = first_name.title()
        self.last_name = last_name.title()
        self.username = username
        self.email = email
        self.location = location.title()
        self.login_attempts = 0

    def describe_user(self):
        """Display a summary of the user's information."""
        print("\n" + self.first_name + " " + self.last_name)
        print(" Username: " + self.username)
        print(" Email: " + self.email)
        print(" Location: " + self.location)

    def greet_user(self):
        """Display a personalized greeting to the user."""
        print("\nWelcome back, " + self.username + "!")

    def increment_login_attempts(self):
        """Add the amount of times a user tried to login."""
        self.login_attempts += 1

    def reset_login_attempts(self):
        """Reset login attempts to 0."""
        self.login_attempts = 0

class Admin(User):
    """A user with administrative privileges."""

    def __init__(
            self, first_name, last_name,
            username, email, location):
        """
        Initialize attributes of the parent class.
        Then initialize attributes specific to the adminsitrator.
        """
        super().__init__(
                first_name, last_name,
                username, email, location)
        self.privileges = []

    def show_privileges(self):
        """Print a list of admin privileges."""
        print("\nThe adminstrator has the following privileges:")
        for privilege in self.privileges:
            print("- " + privilege.capitalize() + ";")

felipe = Admin('felipe', 'sebben', 'f_sebben', 'fsebben@k.com', 'porto alegre')
felipe.describe_user()

felipe.privileges = [
    'can add post',
    'can delete post',
    'can delete user',
    ]
felipe.show_privileges()


googleAccHolder = {"Somphors", "Kimhour", "Sothea", "Sovann", "Kimsours"}
fbAccHolder = {"Vatana", "Kimhour", "Sothea", "Ratana", "Hinayo", "Ryuto"}
msAccHolder = {"Ryuto", "Kimhour", "Piseth", "Ratana", "Hinayo"}

#People who only use google
googleAccHolderOnly = googleAccHolder - fbAccHolder
print(f"People who have only google acc: {googleAccHolderOnly}")

#People who only use fb

fbAccHolderOnly = fbAccHolder - googleAccHolder
print(f"People who have only Fb acc: {fbAccHolderOnly}")

# #people who have both google and facebook acc
# googleAndFbAccHolder = googleAccHolder.intersection(fbAccHolder)
# print(googleAndFbAccHolder)
#
# #People who only have Acc in google not in fb
# googleAccHolderOnly = googleAccHolder.difference(googleAndFbAccHolder)
# print(f"People who have google acc and don't have Fb acc:  {googleAccHolderOnly}")
#
#
# FbAccHolderOnly =fbAccHolder.difference(googleAccHolder)
# print(f"People who have Fb acc and don't have Google acc: {FbAccHolderOnly}")


# NxN 시험관, 바이러스 매 초 상하좌우로 증식, 낮은 번호의 바이러스부터 우선순위
# 시간동안(for) 낮은 번호부터 증식 시작. 바이러스가 있거나 matrix 범위 이상이면 stop.
# 바이러스 종류별 좌표 추가

n, k = map(int, input().split())
matrix = []
for _ in range(n):
    matrix.append(list(map(int, input().split())))
s, x, y = map(int, input().split())

# 상 하 좌 우
dx = [-1, 1, 0, 0]  # 위아래
dy = [0, 0, -1, 1]  # 좌우

# 바이러스 좌표 dict. initial
virus = {}
for i in range(k):
    virus[i+1] = []
for i in range(n):
    for j in range(n):
        if matrix[i][j] != 0:
            virus[matrix[i][j]].append((i,j))

def move(cord):
    x, y = cord
    v_num = matrix[x][y]
    for i in range(4):
        n_x = x+dx[i]
        n_y = y+dy[i]
        if n_x == n or n_y == n or n_x < 0 or n_y < 0:
            continue
        if matrix[n_x][n_y] == 0:
            matrix[n_x][n_y] = v_num
            virus[v_num].append((n_x, n_y))

for _ in range(s):
    for idx in sorted(virus.keys()):
        for cord in virus[idx]:
            move(cord)

# answer. initial cord = (1,1)
print(matrix[x-1][y-1])


#!/usr/bin/env Python
from sys import argv
import itertools
import math

with open(argv[1],'r') as in_file:
  in_data = in_file.read().splitlines()
in_file.closed

n =int(in_data[0])

permute = []
for i in range(n):
  permute.append(i+1)

with open("enumerating_gene_orders_output.txt",'w') as out_file:
  out_file.write(str(math.factorial(n))+"\n")
  for i in set(itertools.permutations(permute)):
    for j in i:
      out_file.write(str(j)+" ")
    out_file.write("\n")
out_file.closed


import base.invoke.tasks.run
import invoke
import re
import sys
import yaml

@invoke.task
def update_base():
    invoke.run('git pull https://github.com/fogies/web-jekyll-base.git master', encoding=sys.stdout.encoding)
    invoke.run('git pull https://github.com/fogies/invoke-base.git master', encoding=sys.stdout.encoding)

@invoke.task
def update_dependencies():
    # Parameters to keep everything silent
    params_silent = {
        # Some of the commands output characters that cause Unicode errors on Windows,
        # so we set an encoding that will help the command line behave
        'encoding': sys.stdout.encoding,
        'hide': 'both',
        'warn': True
    }

    # Parse our config
    with open('_base_config.yml') as f:
        base_config_yaml = yaml.safe_load(f)

    # Python dependencies
    print('Checking Python dependencies')

    # Ensure we have a current version of pip (e.g., as needed by pip-tools)
    pip_version_desired = base_config_yaml['config']['python']['pip_version']
    result = invoke.run('pip --disable-pip-version-check show pip', **params_silent)
    base.invoke.tasks.run.check_result(result, 'check pip version')

    pip_version_current = re.search('^Version: ([\d.]+)', result.stdout, re.MULTILINE).group(1)
    if pip_version_current != pip_version_desired:
        result = invoke.run(
            'python -m pip install --upgrade pip=={}'.format(
                pip_version_desired
            ),
            **params_silent
        )
        base.invoke.tasks.run.check_result(result, 'update pip version')

    # Ensure we have pip-tools, which will be in our requirements file
    # pip-sync also currently does not respect options in the requirements file,
    # so installing the entire file ensures pip-sync only needs to delete
    result = invoke.run('pip --disable-pip-version-check install -r requirements3.txt', **params_silent)
    base.invoke.tasks.run.check_result(result, 'install pip requirements')
    # Ensure we have exactly our dependencies
    result = invoke.run('pip-sync requirements3.txt', **params_silent)
    base.invoke.tasks.run.check_result(result, 'sync pip requirements')

    # Node dependencies
    if base_config_yaml['config'].get('node', {}).get('required', False):
        print('Checking Node.js dependencies')
        result = invoke.run('npm install', **params_silent)
        base.invoke.tasks.run.check_result(result, 'install Node.js dependencies')

    # Ruby dependencies
    if base_config_yaml['config'].get('ruby', {}).get('required', False):
        print('Checking Ruby dependencies')

        # Check we have the correct Bundler version
        bundler_version_desired = base_config_yaml['config']['ruby']['bundler_version']

        result = invoke.run('gem list -i bundler -v {}'.format(bundler_version_desired), **params_silent)
        # expected to fail if the desired version is not installed
        if result.failed:
            result = invoke.run('gem install bundler -v {}'.format(bundler_version_desired), **params_silent)
            base.invoke.tasks.run.check_result(result, 'install bundler')

        # And only the correct Bundler version
        # Expected to fail if no other versions of bundler are installed
        invoke.run('gem uninstall bundler -v "!={}"'.format(bundler_version_desired), **params_silent)

        # Check we have our Ruby dependencies
        result = invoke.run('bundle check', **params_silent)
        # expected to fail if we are missing dependencies
        if result.failed:
            result = invoke.run('bundle install', **params_silent)
            base.invoke.tasks.run.check_result(result, 'bundle install')


# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def reverse(self, head, left, right):
        prev = None
        current = head

        while left <= right:
            temp = current.next
            current.next = prev
            prev = current
            current = temp
            left+=1

        return prev, head, current

    def reverseKGroup(self, head: Optional[ListNode], k: int) -> Optional[ListNode]:

        if k == 1 or not head:
            return head

        s_head = ListNode(0, head)

        current = s_head
        left, right = 1, 0

        while current.next:
            node = current

            for j in range(k):
                node = node.next
                if not node:
                    break
                right += 1

            if right % k == 0:
                new_head, new_tail, tail_next = self.reverse(current.next, left, right)
                current.next = new_head
                new_tail.next = tail_next
                current = new_tail
                left+=k

            else:
                break

        return s_head.next


import socket, threading

def accept_client():
    while True:
        #accept
        cli_sock, cli_add = ser_sock.accept()
        CONNECTION_LIST.append(cli_sock)
        thread_client = threading.Thread(target = broadcast_usr, args=[cli_sock])
        thread_client.start()

def broadcast_usr(cli_sock):
    while True:
        try:
            data = cli_sock.recv(1024)
            if data:
               b_usr(cli_sock, data)
        except Exception as x:
            pass

def b_usr(cs_sock, msg):
    for client in CONNECTION_LIST:
        if client != cs_sock:
            client.send(msg)
if __name__ == "__main__":
    CONNECTION_LIST = []
    ser_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # bind
    HOST = 'localhost'
    PORT = 5060
    ser_sock.bind((HOST, PORT))
    # listen
    ser_sock.listen(1)
    print('Chat server started on port : ' + str(PORT))
    thread_ac = threading.Thread(target = accept_client)
    thread_ac.start()