from src.Team import Team
from src.Fight import Fight
from src.bots.Gauntlet import getGauntlet
from copy import deepcopy
import numpy as np
import time
import csv
import pandas as pd
import os
import threading
from functools import partial
from multiprocessing import Pool, Process

MAX_DEPTH = 2
DATA_PATH = "./data_collecter/games/"

# def minmax(team1: Team, enemies: Team, depth, moves, best):

#     if depth >= MAX_DEPTH:
#         return 0
#     _, p = team1.getState()
#     for i in range(len(p)):
#         if p[i] == 1:
#             team = deepcopy(team1)
#             team.setState(i)
#             f = Fight(team, enemies)
#             cur = f.simulate()
#             cur += f.simulate()
#             cur += f.simulate()
#             cur = cur / 3
#             if cur > best[depth]:
#                 next_team = team
#                 best[depth] = cur
#                 moves[depth] = i
#     minmax(next_team, enemies, depth + 1, moves, best)
#     depth += 1

def bestMove(team1, enemies, depth):

    counter = [0]
    _, p = team1.getState()
    best_i = 0
    maxmax = -999999
    for i in range(len(p)):
        if p[i] == 1:
            maxSum = [-1000]
            t = deepcopy(team1)
            t.setState(i)
            adv = getAdvantage(t, enemies)
            if i != 68:
                DFS(t, enemies, adv, maxSum, depth + 1, counter)
            if adv + maxSum[0] > maxmax:
                best_i = i
                maxmax = adv + maxSum[0]

    return best_i, counter, maxmax

def DFS(team, enemies, sum, maxSum, depth, counter):
    counter[0] += 1
    if depth > MAX_DEPTH:
        maxSum[0] = max(maxSum[0], sum)
        return 0

    _, p = team.getState()
    for i in range(1, len(p)):
        if p[i] == 1:
            t = deepcopy(team)
            t.setState(i)
            adv = getAdvantage(t, enemies)
            if i != 68:
                DFS(t, enemies, sum + adv, maxSum, depth + 1, counter)

def getAdvantage(team, enemies):
    f = Fight(team, enemies)
    a = f.simulate()
    a += f.simulate()
    a += f.simulate()
    return a / 3

def run():
    print(f"Starting process {os.getpid()}")
    data_file = f"{DATA_PATH}_{os.getpid()}.csv"
    game = 0
    while True:
        t1 = Team()

        # enemies1 = getGauntlet(1)
        enemies1 = Team()

        round = 1
        wins = 0
        ties = 0
        move_hist = None

        while t1.alive and wins < 10:
            old_adv = -10000

            for i in range(10):
                # start_time = time.time()
                next_enemies = getGauntlet(round)
                move, numMovesChecked, maxAdv = bestMove(t1, next_enemies, 0)

                state, p = t1.getState()

                if move == 68 or (t1.money == 0 and maxAdv <= old_adv):
                    break

                state = np.append(state, p, axis=0)
                if type(move_hist) != np.ndarray:
                    move_hist = np.expand_dims(np.append(state, move), axis=0)
                else:
                    move_hist = np.append(
                        move_hist,
                        np.expand_dims(np.append(state, move), axis=0),
                        axis=0,
                    )
                # data = np.append(state, move)
                # pd.DataFrame(data.reshape(-1, len(data))).to_csv(
                #     data_file, mode="a", index=False, header=False
                # )

                s = t1.setState(move)

                # print(
                #     f"| Move {i+1:3}: {s:15} | Moves Checked: {numMovesChecked[0]:8} | Estimated Advantage: {maxAdv:10.2f} | time taken: {time.time() - start_time:4.2f}s | money: {t1.money:2} |"
                # )
                old_adv = maxAdv

            if move != 68:
                state, p = t1.getState()
                state = np.append(state, p, axis=0)
                move = 68
                t1.setState(68)
                move_hist = np.append(
                    move_hist, np.expand_dims(np.append(state, move), axis=0), axis=0
                )

            enemies1 = getGauntlet(round)
            f = Fight(t1, enemies1)
            score = f.simulate()
            if score > 0:
                wins += 1
            if score == 0:
                ties += 1
            t1.nextTurn()
            # print(f"| Round {round:4} | score: {score:4} | win number: {wins} |")

            # if round > 15:
            #     print("got past round 15")
            # if wins > 6:
            #     print(f"I won at round: {round}")
            # if not t1.alive:
            #     print(f"| got to round {round} and lost | {wins} wins | {ties} ties |")

            round += 1

        if wins > 6:
            data_file = (
                f"{DATA_PATH}/game_{game}_{os.getpid()}_round_{round}_wins_{wins}.csv"
            )
            np.savetxt(data_file, move_hist, delimiter=",")
            print(f"game {game} saved")
        game += 1
        # print(f"| got to round: {round} | number of wins: {wins} |")

def multi_run(processes):
    proc = []
    for i in range(processes):
        t = Process(target=run)
        proc.append(t)
    for i in proc:
        i.start()


from torch.utils.data import Dataset
import numpy as np
import utils.utils as utils
import h5py
import torch
import torchvision
import os

class BaseDataset(Dataset):
    def name(self):
        return 'base_dataset'

    def __init__(self, config):
        self.config = config
        self.mode = config.mode
        self.preload_image_file_name = config.preload_image_file_name
        self.is_eval = config.mode != 'Training'
        self.deep_classifier = config.deep_classifier
        self.n_eval_samples = config.n_eval_samples
        self.log_patches = config.log_patches
        self.n_subtypes = config.n_subtypes
        self.use_equalized_batch = config.use_equalized_batch
        self.test_augmentation = config.test_augmentation
        self.is_tcga = config.is_tcga
        self.preload_images = h5py.File(os.path.join(
            config.dataset_dir, config.preload_image_file_name), 'r')

        if config.mode == 'Testing':
            # Testing mode is used for evaluating model in the test dataset
            self.cur_data_ids = utils.read_data_ids(
                os.path.join(config.dataset_dir, config.test_ids_file_name))
        elif config.mode == 'Validation':
            # Validation mode is used for evaluating model in the validation dataset
            self.cur_data_ids = utils.read_data_ids(
                os.path.join(config.dataset_dir, config.val_ids_file_name))
        else:
            # Training mode is used for training model in the training dataset
            self.cur_data_ids = utils.read_data_ids(
                os.path.join(config.dataset_dir, config.train_ids_file_name))
            # also pass the validation set to evaluate model during training
            self.eval_data_ids = utils.read_data_ids(
                os.path.join(config.dataset_dir, config.val_ids_file_name))

        if self.test_augmentation:
            # evaluate GAN augmentation
            self.aug_target = h5py.File(os.path.join(
                config.dataset_dir, config.aug_target_file_name), 'r')
            self.aug_real = h5py.File(os.path.join(
                config.dataset_dir, config.aug_real_file_name), 'r')
            self.aug_fake = h5py.File(os.path.join(
                config.dataset_dir, config.aug_fake_file_name), 'r')

        if self.use_equalized_batch:
            # extract patch label beforehand
            self.label_list = []
            for cur_data_id in self.cur_data_ids:
                cur_label = utils.get_label_by_patch_id(
                    cur_data_id, is_tcga=self.is_tcga)
                self.label_list += [cur_label]
            # for fast numpy indexing
            self.label_list = np.asarray(self.label_list)
            self.cur_data_ids = np.asarray(self.cur_data_ids)

    def __len__(self):
        return len(self.cur_data_ids)

    def __getitem__(self, index):
        pass


import os
import sys
import json

if __name__ == "__main__":
    img_dir, meta_file = sys.argv[1], sys.argv[2]

    # input.txt
    input_txt, img_names = "input.txt", None
    with open(input_txt, "w") as f:
        for root, dirs, files in os.walk(img_dir, topdown=False):
            img_names = files
            for name in files:
                img_item = {
                    "image": {
                        "image_path": "images/{}".format(name),
                        "#keson_code": "FRM"
                    }
                }
                f.write(json.dumps(img_item) + "\n")

    # ground_truth.txt
    name2id, id2img, id2annos = {}, {}, {}
    with open(meta_file, "r") as f:
        metas = f.readlines()[0]
        # 'info', 'licenses', 'images', 'annotations', 'categories'
        # category start from 1
        metas = json.loads(metas)
        images, annotations, categories = metas["images"], metas["annotations"], metas["categories"]
    for image in images:
        image_id, file_name = image["id"], image["file_name"]
        if file_name not in name2id:
            name2id[file_name] = image_id
        if image_id not in id2img:
            id2img[image_id] = image
    for annotation in annotations:
        image_id = annotation["image_id"]
        if image_id not in id2annos:
            id2annos[image_id] = []
        id2annos[image_id].append(annotation)
    # generate ground_truth.txt
    with open("ground_truth.txt", "w") as f:
        for img_name in img_names:
            image_id = name2id[img_name]
            image_path = "images/{}".format(img_name)
            img_annos = id2annos[image_id]
            for img_anno in img_annos:
                x1, y1, w, h = img_anno["bbox"]
                x1, y1, x2, y2 = int(x1), int(y1), int(x1 + w), int(y1 + h)
                label = img_anno["category_id"] - 1
                gt_item = {
                    "image_path": image_path,
                    "roi": {
                        "left": x1,
                        "top": y1,
                        "width": w,
                        "height": h,
                        "#keson_code": "RCT"
                    },
                    "is_ignored": False,
                    "label": label
                }
                f.write(json.dumps(gt_item) + "\n")
    import pdb;pdb.set_trace()


import hashlib
import json
import logging
from decimal import Decimal
from functools import wraps
from typing import Callable, Optional

from django.conf import settings
from django.core.cache import caches
from helpers.json import CustomJSONEncoder
from rest_framework.request import Request
from rest_framework.response import Response
from sentry_sdk import capture_exception

logger = logging.getLogger("api_cache")

class CacheDecorator:
    """Decorator that can retrieve and save view's response."""

    def __init__(
        self, prefix=str, alias=str, timeout=int,
    ):
        self.prefix = prefix
        self.alias = alias
        self.timeout = timeout

    def __call__(self, func) -> Callable[..., Response]:
        """Handle request call."""

        @wraps(func)
        def cache_wrapper(_self, request: Request, *args, **kwargs) -> Response:
            response = self.cache_get(request, *args, **kwargs)
            if response:
                return response

            response = func(_self, request, *args, **kwargs)
            self.cache_save(response, request, *args, **kwargs)
            return response

        return cache_wrapper

    @property
    def cache(self):
        """Cache property."""
        return caches[self.alias]

    @classmethod
    def cache_build_hash(cls, request, *args, **kwargs) -> str:
        """Build hash from view's args and kwargs parameters."""
        parts = []

        for arg in args:
            parts.append(str(arg))

        kwarg_items = [(str(key), str(value)) for key, value in kwargs.items()]  # noqa: WPS221
        kwarg_items = kwarg_items + [
            (str(key), str(value)) for key, value in request.query_params.items()
        ]  # noqa: WPS221
        kwarg_items.sort()
        for key, value in kwarg_items:
            parts.append("{key}:{value}".format(key=key, value=value))

        return hashlib.sha256("-".join(parts).encode("utf-8")).hexdigest()

    def cache_build_key(self, request: Request, *args, **kwargs) -> str:
        """Build cache key, under which response will be retrieved and saved."""
        assert self.prefix, "{name}.cache_prefix cannot be empty".format(name=self.__class__.__name__)  # noqa: S101
        return "{prefix}-{lang}-{hash}".format(
            prefix=self.prefix, lang=request.LANGUAGE_CODE, hash=self.cache_build_hash(request, *args, **kwargs)
        )

    def cache_get(self, request: Request, *args, **kwargs) -> Optional[Response]:
        """Retrieve response from cache."""
        if not self.prefix:
            return None

        key = self.cache_build_key(request, *args, **kwargs)
        data = self.cache.get(key, b"")
        if data:
            try:
                data = Response(json.loads(data, parse_float=Decimal))
                logger.debug("Cache hit: %s" % request.path)
                return data
            except (TypeError, EOFError) as error:
                self.cache.delete(key)
                capture_exception(error)

    def cache_save(self, response: Response, request: Request, *args, **kwargs):
        """Save response in cache."""
        if not self.prefix:
            return

        if not isinstance(response, Response):
            return

        if response.status_code != 200:
            return

        key = self.cache_build_key(request, *args, **kwargs)
        try:
            self.cache.set(key, json.dumps(response.data, cls=CustomJSONEncoder), timeout=self.timeout)
            logger.debug("Cache saved: %s [timeout=%s]" % (request.path, self.timeout))
        except Exception as error:
            capture_exception(error)

    def cache_clear(self):
        """Clear cache for a given city."""
        for lang in dict(settings.LANGUAGES).keys():
            key = f"{self.prefix}-{lang}-*"
            self.cache.delete_pattern(key)

def cache(prefix, alias=settings.API_CACHE_ALIAS, timeout=settings.API_CACHE_TIMEOUT,) -> CacheDecorator:
    """Returns instance CacheDecorator."""
    return CacheDecorator(prefix, alias, timeout)


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

#/usr/src/examples/python-serial-2.6

import pygtk
pygtk.require('2.0')
import gtk
import pango
import gobject
import gc
import re
import shlex, subprocess
import avrList

class clCfgAVR:
	def __init__(self):
		self.selSUT=''
		self.bDefaultLock=False
		self.argsAVRdude = []
		self.reHex=re.compile('(0x)([0-9A-F]{1,2})$', re.I | re.L)
		self.reBin=re.compile('(0b)([01]{1,8})$', re.I | re.L)
		self.reDec=re.compile('([0-9]{1,3})$', re.L)
		self.devParam = avrList.devParam()
		self.uiInit()
		gtk.main()

	def uiInit(self):
		from uiMain import uiCfgAVR
		self.ui = uiCfgAVR()
		self.ui.title="AVRmate - Fusebits Calculator V.0.51"
		self.ui.uiInit()

		self.ui.mainWindow.connect("destroy", lambda w: gtk.main_quit())
		self.ui.mainWindow.connect("delete_event", gtk.main_quit)
		self.ui.cbUcSelect.connect("changed", self.ucChanged)
		self.chooseInit()
		self.ui.cbPgmSelect.connect("changed", self.pgmChanged)

		for pgmName in self.devParam.lsProgrammers:
			self.ui.lsPgmSelect.append(pgmName)
		self.ui.cbPgmSelect.set_active(0)

		self.ui.checkClk.connect("toggled", self.avrErTog)
		self.ui.checkErase.connect("toggled", self.avrErTog)
		### Begin of Tree Store ###
		self.ui.crtcbBitsValue.connect('changed', self.cbBitsChanged)
		self.ui.crtcbBitsValue.connect('editing_started', self.callSkipSelection)

		self.ui.crtxtBitsValue.connect("edited", self.byteEdited)
		self.ui.crtxtBitsValue.connect('editing_started', self.callSkipSelection)
		#self.ui.crtxtBitsValue.connect('editing_canceled', self.callSkipSelection, "Canceled", None)
		### End of Tree Store ###

		self.ui.textAvrdudeCmd.connect("icon-release", self.avrdudeIcGo)
		self.ui.textAvrdudeCmd.connect("activate", self.avrdudeGo)

		self.ui.buttonPng.connect("clicked", self.winShoot)
		self.ui.buttonTest.connect("clicked", self.treeTest)
		self.ui.buttonExit.connect("clicked", self.appExit)
		return

	def chooseInit(self):
		self.ucList=self.devParam.devParams()
		self.lnUcList=len(self.ucList)
		for ucIndex in range(self.lnUcList):
			self.ui.lsUcSelect.append([self.ucList[ucIndex]])
		#self.cbUcSelect.set_active(0)
		return
## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ##

	def defaultBit(self, bitName):
		widthConfig=self.avrBits[bitName]['Config'][0]
		if 'Default' in self.avrBits[bitName]:
			defaultConfig=self.avrBits[bitName]['Default']
		elif len(self.avrBits[bitName]['Config'][1]) ==1:
			defaultConfig=self.avrBits[bitName]['Config'][1].keys()[0]
			#print "Juppiiii.....!!!\n\t default:%s" % defaultConfig
		else:
			defaultConfig=''
			for n in range(widthConfig):
				defaultConfig+='1'
		if defaultConfig in self.avrBits[bitName]['Config'][1]:
			defaultVal=self.avrBits[bitName]['Config'][1][defaultConfig]
		else:
			defaultVal="Unknown"
		return (defaultConfig, defaultVal)

	def bitListView(self, bitName):
		setList=sorted(self.avrBits[bitName]['Config'][1].keys())
		lsmodel = gtk.ListStore(str, str)
		for item in setList:
			lsmodel.append([ self.avrBits[bitName]['Config'][1][item], item ])
		return lsmodel

	def treeFill(self, indexAVR):
		self.avrData=self.devParam.getAVR(indexAVR)
		self.avrBits=self.devParam.avrCfgBits
		self.tvBitsIter=[]
		self.ui.tsBits.clear()
		byteFuses=sorted(self.avrData['Fuses'].keys())
		for byteFuse in byteFuses:
			locIter=[]
			locIter.append( self.ui.tsBits.append(None,
					[self.ui.fsBPixbuf,
					'FuseByte%s' % (byteFuse),
					'%s FuseByte' % (byteFuse),
				'',
				'',
				None,
				False,
				True,
				byteFuse]
				))
			for bitFuse in self.avrData['Fuses'][byteFuse]:
				bitSelName=bitFuse
				if bitFuse=='SUT_SEL':
					bitFuse=self.selSUT
				if 'NameShow' in self.avrBits[bitFuse]:
					bitShowName=self.avrBits[bitFuse]['NameShow']
				else:
					bitShowName=bitFuse
				defaultFuse=self.defaultBit(bitFuse)
				modelFuse=self.bitListView(bitFuse)
				if bitFuse[0:6]=='CKSEL4':
					if 'SUT_SEL' in self.avrBits[bitFuse]:
						self.selSUT=self.avrBits[bitFuse]['SUT_SEL'][defaultFuse[0]]
					else:
						self.selSUT=''
				locIter.append(self.ui.tsBits.append(locIter[0],
					[self.ui.fsbPixbuf,
					'%s' % (bitShowName),
					self.avrBits[bitFuse]['Desc'],
					defaultFuse[1],
					defaultFuse[0],
				modelFuse,
				True,
				False,
				bitSelName]
				))

			self.tvBitsIter.append(locIter)
		locIter=[]
		locIter.append( self.ui.tsBits.append(None,
				[self.ui.lBPixbuf, 'LockByte',
				'Lock Byte',
				'',
				'',
				None,
				False,
				True,
				'Lock']
				))
		for bitLock in self.avrData['Lock']:
			defaultLock=self.defaultBit(bitLock)
			modelLock=self.bitListView(bitLock)
			locIter.append(self.ui.tsBits.append(locIter[0],
				[self.ui.lbPixbuf,
				'%s' % (bitLock),
				self.avrBits[bitLock]['Desc'],
				defaultLock[1],
				defaultLock[0],
				modelLock,
				True,
				False,
				bitLock]
			))
		self.tvBitsIter.append(locIter)

		return

	def avrdudeGo(self, widget):
		AvrdudeCmd=self.ui.textAvrdudeCmd.get_text()
		if AvrdudeCmd:
			avrdudeTargets=subprocess.Popen(
				shlex.split(AvrdudeCmd),
				stdout=subprocess.PIPE,
				stderr=subprocess.STDOUT)
				#stderr=subprocess.PIPE)
			child_stdout, child_stderr = avrdudeTargets.communicate()
			if child_stderr:
				self.errBox(message=child_stderr)
			if child_stdout:
				self.infoBox(message=child_stdout)
		return

	def avrdudeListuC(self):
		return

	def avrdudeIcGo(self, widget, icoPos, sigEvent):
		self.avrdudeGo(widget)
		return

	def callSkipSelection(self, cellrenderer, editable, path):
		#print(cellrenderer, editable, path)
		self.treeUnselect()
		return

	def cbBitsChanged(self, comboCellRenderer, cell_path, select_iter):
		bitIter = self.ui.tsBits.get_iter(cell_path)
		lSt=self.ui.tsBits.get_value(bitIter, 5) # Get ListStore saved at 5 collumn
		self.ui.tsBits.set(bitIter, 3, lSt.get_value(select_iter, 0), 4, lSt.get_value(select_iter, 1))
		self.byteUpdate(int(cell_path[0:1]))
		#self.treeUnselect()
		self.avrDudeUp()

	def byteEdited(self, cellRendererText, cell_path, newText):
		reHexTxt=self.reHex.match(newText)
		reBinTxt=self.reBin.match(newText)
		byteIt = self.ui.tsBits.get_iter(cell_path)
		if reHexTxt:
			byteVal=int(reHexTxt.group(2).upper(), 16)
		elif reBinTxt:
			byteVal=int(reBinTxt.group(2), 2)
		elif self.reDec.match(newText):
			byteVal=int(newText, 10)
		else:
			byteVal=0x100
		if byteVal in range(0x100):
			self.ui.tsBits.set(byteIt, 3,'0b{:08b}'.format(byteVal), 4, '0x{:02X}'.format(byteVal))
		self.bitsUpdate(int(cell_path[0:1]))
		self.treeUnselect()
		self.avrDudeUp()
		return

	def pgmChanged(self, widget):
		viewModel = widget.get_model()
		index = widget.get_active()
		if index > -1:
			self.avdPgm=viewModel[index][1]
			self.avdPgmPort=viewModel[index][2]
			self.avrDudeUp()
		return

	def ucChanged(self, widget):
		viewModel = widget.get_model()
		index = widget.get_active()
		if index > -1:
			self.ui.tvBits.freeze_child_notify()
			modelBits=self.ui.tvBits.get_model()
			self.ui.tvBits.set_model(None)

			# Add rows to the viewModel
			# ...
			self.treeFill(index)

			self.ui.tvBits.set_model(modelBits)
			self.ui.tvBits.thaw_child_notify()
			self.ui.tvBits.expand_all()
			self.bDefaultLock=True

		for n in range(len(self.tvBitsIter)):
			self.byteUpdate(n)
		self.avrDudeUp()
		return

	def byteUpdate(self, selectNo):
		byteIt=self.tvBitsIter[selectNo][0]
		bitCfgs=len(self.tvBitsIter[selectNo])-1
		binByteTxt=''
		for n in range(bitCfgs):
			bitIt=self.tvBitsIter[selectNo][n+1]
			bitName=self.ui.tsBits.get_value(bitIt, 8)
			bitVal=self.ui.tsBits.get_value(bitIt, 4)
			if bitName=='SUT_SEL':
				bitName=self.selSUT
				bitDesc=self.avrBits[bitName]['Desc']
				bitModel=self.bitListView(bitName)
				self.ui.tsBits.set(bitIt, 2, bitDesc, 5, bitModel)
				if not(bitVal in self.avrBits[bitName]['Config'][1].keys()):
					bitVal=self.defaultBit(bitName)[0]
					self.ui.tsBits.set_value(bitIt, 4, bitVal)
				self.ui.tsBits.set_value(bitIt, 3, self.avrBits[bitName]['Config'][1][bitVal])
			if bitName[0:6]=='CKSEL4':
				if 'SUT_SEL' in self.avrBits[bitName]:
					self.selSUT=self.avrBits[bitName]['SUT_SEL'][bitVal]
				else:
					self.selSUT=''
			binByteTxt="%s%s" % (bitVal, binByteTxt)
		byteVal=int(binByteTxt, 2)
		self.ui.tsBits.set(byteIt, 3,'0b{:08b}'.format(byteVal), 4, '0x{:02X}'.format(byteVal))
		byteName=self.ui.tsBits.get_value(byteIt, 8)
		if byteName=='Lock' and self.bDefaultLock==True:
			self.defaultLock='0x{:02X}'.format(byteVal)
			self.bDefaultLock=False
		return

	def bitsUpdate(self, selectNo):
		bDefaultSet=False
		byteIt=self.tvBitsIter[selectNo][0]
		bitCfgs=len(self.tvBitsIter[selectNo])-1
		binByteTxt=self.ui.tsBits.get_value(byteIt, 3)[2:10]
		bitPtr=8
		for n in range(bitCfgs):
			bitIt=self.tvBitsIter[selectNo][n+1]
			bitName=self.ui.tsBits.get_value(bitIt, 8)
			if bitName=='SUT_SEL':
				bitName=self.selSUT
				bitDesc=self.avrBits[bitName]['Desc']
				bitModel=self.bitListView(bitName)
				self.ui.tsBits.set(bitIt, 2, bitDesc, 5, bitModel)
			widthConfig=self.avrBits[bitName]['Config'][0]
			bitPtrB=bitPtr-widthConfig
			bitVal=binByteTxt[bitPtrB:bitPtr]
			if bitName.startswith('CKSEL4'):
				if 'SUT_SEL' in self.avrBits[bitName]:
					self.selSUT=self.avrBits[bitName]['SUT_SEL'][bitVal]
				else:
					self.selSUT=''
			setList=sorted(self.avrBits[bitName]['Config'][1].keys())
			if bitVal in setList:
				setupTxt=self.avrBits[bitName]['Config'][1][bitVal]
			else:
				bitVal, setupTxt=self.defaultBit(bitName)
				bDefaultSet=True
			self.ui.tsBits.set(bitIt, 3, setupTxt, 4, bitVal)
			bitPtr=bitPtrB
		if bitPtr>0:
			bDefaultSet=True
		if bDefaultSet:
			self.byteUpdate(selectNo)
		return

	def avrDudeUp(self):
		try:
			updateText={
				True:' -B 8',
				False:''
			}[self.ui.checkClk.get_active()]
			updateText+={
				True:' -e',
				False:''
			}[self.ui.checkErase.get_active()]
			for byteCfg in range(len(self.tvBitsIter)):
				byteIt=self.tvBitsIter[byteCfg][0]
				byteNm=self.devParam.avdCfgByte(self.ui.tsBits.get_value(byteIt, 8))
				byteVal=self.ui.tsBits.get_value(byteIt, 4)
				if byteNm=='lock' and byteVal!=self.defaultLock or byteNm!='lock':
					updateText+=' -U %s:w:%s:m' % (byteNm, byteVal)
			setText="avrdude -c %s -P %s -p %s%s" % (self.avdPgm, self.avdPgmPort, self.devParam.avdName(self.avrData['Name']), updateText)
			self.ui.textAvrdudeCmd.set_text(setText)
		except AttributeError:
			pass
		return

	def treeUnselect(self):
		mode=self.ui.tvBitsSelection.get_mode()
		self.ui.tvBitsSelection.set_mode(gtk.SELECTION_NONE)
		self.ui.tvBitsSelection.set_mode(mode)
		return

	def avrErTog(self, widget):
		self.avrDudeUp()
		return

	def treeTest(self, widget):
		return

	def appExit(self, widget):
		self.devParam.empty()
		gtk.main_quit()

	def winShoot(self, widget):
		screen = gtk.gdk.screen_get_default()
		gdk_win =screen.get_active_window()
		posX, posY, width, height  = gdk_win.get_frame_extents()
		pixbuf = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, True, 8, width, height)
		# Retrieve the pixel data from the gdk.window attribute (self.ui.mainWindow.window)
		# of the gtk.window object
		#screenshot = pixbuf.get_from_drawable(
			#self.ui.mainWindow.window,
			#self.ui.mainWindow.get_colormap(),
			#0, 0, 0, 0, width, height)

		screenshot = pixbuf.get_from_drawable(
			gtk.gdk.get_default_root_window(),
			gtk.gdk.colormap_get_system(),
			posX, posY, 0, 0, width, height)

		#gtk.FileChooser
		screenshot.save('screenshot.png', 'png')
		del screenshot
		gc.collect()
		return

	def infoBox(self, message="Known Comes...!", caption = 'Information...'):
		dlg = gtk.MessageDialog(parent=None, flags=gtk.DIALOG_DESTROY_WITH_PARENT, type=gtk.MESSAGE_INFO, buttons=gtk.BUTTONS_CLOSE, message_format=None)
		dlg.set_markup(message)
		dlg.set_title(caption)
		dlg.run()
		dlg.destroy()

	def errBox(self, message="Unknown Comes...!", caption = 'Error!'):
		dlg = gtk.MessageDialog(parent=None, flags=gtk.DIALOG_DESTROY_WITH_PARENT, type=gtk.MESSAGE_ERROR, buttons=gtk.BUTTONS_CLOSE, message_format=None)
		dlg.set_markup(message)
		dlg.set_title(caption)
		dlg.run()
		dlg.destroy()

if __name__ == "__main__":
	configAVR = clCfgAVR()


import json
import unittest
from json_formatter import flatten_json

class TestFormatter(unittest.TestCase):
    # Should handle all JSON data types
    def test_nesting(self):
        formatted_json = flatten_json(json.loads("""
        {
            "user": {
                "first": "dominik",
                "last": "rastawicki",
                "birthday": {
                    "day": 7,
                    "month": "june"
                }
            },
            "company": "mongodb"
        }
        """))

        self.assertEqual([
            '"user.first": "dominik"',
            '"user.last": "rastawicki"',
            '"user.birthday.day": 7',
            '"user.birthday.month": "june"',
            '"company": "mongodb"'
        ], formatted_json)

    # Should handle all JSON data types
    def test_data_types(self):
        formatted_json = flatten_json(json.loads("""
        {
            "data": {
                "number": 5,
                "null": null,
                "truthfulness": true
            }
        }
        """))

        self.assertEqual([
            '"data.number": 5',
            '"data.null": null',
            '"data.truthfulness": true'
        ], formatted_json)

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


import logging
import re

from django.utils.translation import ugettext_lazy as _

from horizon import tables
from horizon.templatetags.sizeformat import filesizeformat, float_format

LOG = logging.getLogger(__name__)

class StringWithPlusOperation(str):
    """Override "+" operation for string object to make."""
    def __init__(self, *args, **kwargs):
        super(StringWithPlusOperation, self).__init__(*args, **kwargs)

    def _split_str(self, string):
        """
        Split a string to two parts.
        The first group is the float number and
        the second one is a string like unit name.
        """
        result = re.search(r'^([-+]?[0-9]*\.?[0-9]+)(.*)$', string)
        if result:
            number = float(result.groups()[0])
            unit = result.groups()[1]
            return number, unit
        return None, None

    # given a number and units, convert that to bytes
    def to_bytes(self, number, unit):
        if unit=="PB":
            bytes = number * (1024 * 1024 * 1024 * 1024 * 1024)
        elif unit=="TB":
            bytes = number * (1024 * 1024 * 1024 * 1024)
        elif unit=="GB":
            bytes = number * (1024 * 1024 * 1024)
        elif unit=="MB":
            bytes = number * (1024 * 1024)
        elif unit=="KB":
            bytes = number * (1024)
        else:
            bytes = number

        return bytes

    def __radd__(self, another):
        num_x, unit_x = self._split_str(self)
        num_y = 0
        unit_y = ""

        if isinstance(another, (int, float)):
            num_y = another
        elif isinstance(another, basestring):
            num_y, unit_y = self._split_str(another)
        elif isinstance(another, self.__class__):
            num_y, unit_y = self._split_str(another.__str__())

        if num_y is None or num_x is None:
            return '-'

        unit_x = unit_x.strip()
        unit_y = unit_y.strip()

        if unit_x == unit_y:
            return "%s%s" % (num_x + num_y, unit_x)
        else:
            # convert both units to bytes
            converted_num_x = self.to_bytes(num_x, unit_x)
            converted_num_y = self.to_bytes(num_y, unit_y)

            total = converted_num_x + converted_num_y
            result = filesizeformat(total, float_format)
            return result

class StringWithPlusOperationForTime(str):
    """Override "+" operation for string object to make."""
    def __init__(self, *args, **kwargs):
        super(StringWithPlusOperationForTime, self).__init__(*args, **kwargs)

    def __radd__(self, another):
        # convert to seconds, add them and convert again
        seconds1 = sum(int(x) * 60 ** i for i, x
                        in enumerate(reversed(self.split(":"))))
        if isinstance(another, (int, float)):
            seconds2 = another
        else:
            seconds2 = sum(int(x) * 60 ** i for i, x
                        in enumerate(reversed(another.split(":"))))

        total_time = seconds1 + seconds2
        converted = "%02d:%02d:%02d" % \
            reduce(lambda a, b: divmod(a[0], b) + a[1:],
                   [(total_time,), 60, 60])

        return str(converted)

class DiskUsageFilterAction(tables.FilterAction):
    def filter(self, table, tenants, filter_string):
        q = filter_string.lower()

        def comp(tenant):
            if q in tenant.name.lower():
                return True
            return False

        return filter(comp, tenants)

def get_bytes(field_name=""):
    def transform(sample):
        field = getattr(sample, field_name, None)
        result = filesizeformat(field, float_format)
        return StringWithPlusOperation(result)
    return transform

class  DiskUsageTable(tables.DataTable):
    tenant = tables.Column("tenant", verbose_name=_("Tenant"), sortable=True)
    user = tables.Column("user", verbose_name=_("User"), sortable=True)
    instance = tables.Column("resource", verbose_name=_("Resource"), sortable=True)
    disk_read_bytes = tables.Column(get_bytes("disk_read_bytes"),
                                    verbose_name=_("Disk Read Bytes"),
                                    summation="sum",
                                    sortable=True)
    disk_read_requests = tables.Column("disk_read_requests",
                                       verbose_name=_("Disk Read Requests"),
                                       summation="sum",
                                       sortable=True)
    disk_write_bytes = tables.Column(get_bytes("disk_write_bytes"),
                                     verbose_name=_("Disk Write Bytes"),
                                     summation="sum",
                                     sortable=True)
    disk_write_requests = tables.Column("disk_write_requests",
                                        verbose_name=_("Disk Write Requests"),
                                        summation="sum",
                                        sortable=True)
    def get_object_id(self, datum):
        return datum.tenant + datum.user + datum.resource

    class Meta:
        name = "global_disk_usage"
        verbose_name = _("Global Disk Usage")
        table_actions = (DiskUsageFilterAction,)
        multi_select = False

class CpuUsageFilterAction(tables.FilterAction):
    def filter(self, table, tenants, filter_string):
        q = filter_string.lower()

        def comp(tenant):
            if q in tenant.name.lower():
                return True
            return False

        return filter(comp, tenants)

class NetworkTrafficUsageFilterAction(tables.FilterAction):
    def filter(self, table, tenants, filter_string):
        q = filter_string.lower()

        def comp(tenant):
            if q in tenant.name.lower():
                return True
            return False

        return filter(comp, tenants)

class NetworkTrafficUsageTable(tables.DataTable):
    tenant = tables.Column("tenant", verbose_name=_("Tenant"))
    user = tables.Column("user", verbose_name=_("User"), sortable=True)
    instance = tables.Column("resource",
                             verbose_name=_("Resource"),
                             sortable=True)
    network_incoming_bytes = tables.Column(get_bytes("network_incoming_bytes"),
                                   verbose_name=_("Network incoming Bytes"),
                                   summation="sum",
                                   sortable=True)
    network_incoming_packets = tables.Column("network_incoming_packets",
                            verbose_name=_("Network incoming Packets"),
                            summation="sum", sortable=True)
    network_outgoing_bytes = tables.Column(get_bytes("network_outgoing_bytes"),
                            verbose_name=_("Network Outgoing Bytes"),
                            summation="sum", sortable=True)
    network_outgoing_packets = tables.Column("network_outgoing_packets",
                            verbose_name=_("Network Outgoing Packets"),
                            summation="sum", sortable=True)

    def get_object_id(self, datum):
        return datum.tenant + datum.user + datum.resource

    class Meta:
        name = "global_network_traffic_usage"
        verbose_name = _("Global Network Traffic Usage")
        table_actions = (NetworkTrafficUsageFilterAction,)
        multi_select = False

class NetworkUsageFilterAction(tables.FilterAction):
    def filter(self, table, tenants, filter_string):
        q = filter_string.lower()

        def comp(tenant):
            if q in tenant.name.lower():
                return True
            return False

        return filter(comp, tenants)

class NetworkUsageTable(tables.DataTable):
    tenant = tables.Column("tenant", verbose_name=_("Tenant"))
    user = tables.Column("user", verbose_name=_("User"), sortable=True)
    instance = tables.Column("resource",
                             verbose_name=_("Resource"),
                             sortable=True)
    network_duration = tables.Column("network",
                                   verbose_name=_("Network Duration"),
                                   summation="sum",
                                   sortable=True)
    network_creation_requests = tables.Column("network_create",
                            verbose_name=_("Network Creation Requests"),
                            summation="sum", sortable=True)
    subnet_duration = tables.Column("subnet",
                            verbose_name=_("Subnet Duration"),
                            summation="sum", sortable=True)
    subnet_creation = tables.Column("subnet_create",
                            verbose_name=_("Subnet Creation Requests"),
                            summation="sum", sortable=True)
    port_duration = tables.Column("port",
                            verbose_name=_("Port Duration"),
                            summation="sum", sortable=True)
    port_creation = tables.Column("port_create",
                            verbose_name=_("Port Creation Requests"),
                            summation="sum", sortable=True)
    router_duration = tables.Column("router",
                            verbose_name=_("Router Duration"),
                            summation="sum", sortable=True)
    router_creation = tables.Column("router_create",
                            verbose_name=_("Router Creation Requests"),
                            summation="sum", sortable=True)
    port_duration = tables.Column("port",
                            verbose_name=_("Port Duration"),
                            summation="sum", sortable=True)
    port_creation = tables.Column("port_create",
                            verbose_name=_("Port Creation Requests"),
                            summation="sum", sortable=True)
    ip_floating_duration = tables.Column("ip_floating",
                            verbose_name=_("Floating IP Duration"),
                            summation="sum", sortable=True)
    ip_floating_creation = tables.Column("ip_floating_create",
                            verbose_name=_("Floating IP Creation Requests"),
                            summation="sum", sortable=True)

    def get_object_id(self, datum):
        return "%s%s%s" % (datum.tenant,
                           datum.user,
                           datum.resource)

    class Meta:
        name = "global_network_usage"
        verbose_name = _("Global Network Usage")
        table_actions=(NetworkUsageFilterAction,)
        multi_select = False

class ObjectStoreUsageFilterAction(tables.FilterAction):
    def filter(self, table, tenants, filter_string):
        q = filter_string.lower()

        def comp(tenant):
            if q in tenant.name.lower():
                return True
            return False

        return filter(comp, tenants)

class ObjectStoreUsageTable(tables.DataTable):
    tenant = tables.Column("tenant", verbose_name=_("Tenant"))
    user = tables.Column("user", verbose_name=_("User"), sortable=True)
    resource = tables.Column("resource",
                             verbose_name=_("Resource"),
                             sortable=True)
    storage_incoming_bytes = tables.Column(get_bytes("storage_objects_incoming_bytes"),
                           verbose_name=_("Object Storage Incoming Bytes"),
                           summation="sum", sortable=True)
    storage_outgoing_bytes = tables.Column(get_bytes("storage_objects_outgoing_bytes"),
                            verbose_name=_("Object Storage Outgoing Bytes"),
                            summation="sum", sortable=True)
    storage_objects = tables.Column("storage_objects",
                            verbose_name=_("Total Number of Objects"),
                            summation="sum", sortable=True)
    storage_objects_size = tables.Column(get_bytes("storage_objects_size"),
                            verbose_name=_("Total Size of Objects "),
                            summation="sum", sortable=True)

    def get_object_id(self, datum):
        return "%s%s%s" % (datum.tenant,
                           datum.user,
                           datum.resource)

    class Meta:
        name = "global_object_store_usage"
        verbose_name = _("Global Object Store Usage")
        table_actions = (ObjectStoreUsageFilterAction,)
        multi_select = False

def get_cpu_time(sample):
    cpu_seconds = sample.cpu / 1000000000
    formatted_time = "%02d:%02d:%02d" % \
        reduce(lambda a, b: divmod(a[0], b) + a[1:], [(cpu_seconds,), 60, 60])
    return StringWithPlusOperationForTime(formatted_time)

class CpuUsageTable(tables.DataTable):
    tenant = tables.Column("tenant", verbose_name=_("Tenant"))
    user = tables.Column("user", verbose_name=_("User"), sortable=True)
    instance = tables.Column("resource",
                             verbose_name=_("Resource"),
                             sortable=True)
    cpu = tables.Column(get_cpu_time,
                        verbose_name=_("CPU time"),
                        summation="sum",
                        sortable=True)

    def get_object_id(self, datum):
        return datum.tenant + datum.user + datum.resource

    class Meta:
        name = "global_cpu_usage"
        verbose_name = _("Global CPU Usage")
        table_actions = (CpuUsageFilterAction,)
        multi_select = False


import numpy as np
import torch

# # # refere to the pseudocode available at https://arxiv.org/src/1911.08265v2/anc/pseudocode.py

class Node(object):
    def __init__(self, prior: float):
        self.visit_count = 0
        self.prior = prior
        self.value_sum = 0
        self.children = {}
        self.hidden_state = 0
        self.reward = 0
        self.to_play = -1

    def expanded(self):
        return len(self.children) > 0

    def value(self) -> float:
        return 0 if self.visit_count == 0 else self.value_sum / self.visit_count

class MinMaxStats(object):
    def __init__(self):
        self.maximum = -float('inf')
        self.minimum = float('inf')

    def update(self, value: float):
        self.maximum = max(self.maximum, value)
        self.minimum = min(self.minimum, value)

    def normalize(self, value: float) -> float:
        if self.maximum > self.minimum:
            return (value - self.minimum) / (self.maximum - self.minimum)
        return value

class Monte_carlo_tree_search():
    def __init__(self, pb_c_base=19652, pb_c_init=1.25, discount=0.95, root_dirichlet_alpha=0.25, root_exploration_fraction=0.25):
        """
        Init the monte carlos tree search of muzero

        Parameters
        ----------
            pb_c_base (int): This is the base value used in the formula for
            calculating the exploration parameter (known as "Pb") in the MCTS
            algorithm. Pb determines the level of exploration that the algorithm
            should perform at each step, with a higher value resulting in more
            expl- oration and a lower value resulting in more exploitation.
            Defaults to 19652.

            pb_c_init (float): This is the initial value of the exploration
            parameter Pb. It determines the level of exp- loration that the
            algorithm should perform at the beginning of the search. Defaults to
            1.25.

            discount (float): This is the discount factor used in the MCTS al-
            gorithm. It determines the importance of future rewards relative to
            immediate rewards, with a hi- gher discount factor leading to a
            greater emphasis on long-term rewards. Defaults to 0.95.

            root_dirichlet_alpha (float): This is the alpha parameter of the
            Dirichlet distr- ibution used in the MCTS algorithm. The Dirichlet
            distribution is used to sample initial move probab- ilities at the
            root node of the search tree, with the alpha parameter controlling
            the level of explo- ration vs exploitation in the sampling process.
            Defaults to 0.25.

            root_exploration_fraction (float): This is the exploration fraction
            used in the MCTS algorithm. It determines the proportion of the
            sear- ch time that should be spent exploring the search tree, with a
            higher value resulting in more explora- tion and a lower value
            resulting in more exploitation. Defaults to 0.25.
        """

        self.reset(pb_c_base, pb_c_init, discount,
                   root_dirichlet_alpha, root_exploration_fraction)

    def reset(self, pb_c_base=19652, pb_c_init=1.25, discount=0.95, root_dirichlet_alpha=0.25, root_exploration_fraction=0.25):
        self.pb_c_base = pb_c_base
        self.pb_c_init = pb_c_init
        self.discount = discount
        self.root_dirichlet_alpha = root_dirichlet_alpha
        self.root_exploration_fraction = root_exploration_fraction
        self.node = None
        self.model = None
        self.overall_graph = []

    def generate_root_hidden_state(self, observation):

        self.root = Node(0)
        self.min_max_stats = MinMaxStats()
        self.root.hidden_state = self.model.representation_function_inference(
            observation)

    def set_root_to_play_with_the_play_number(self, observation):
        # Monte Carlo Tree Search (MCTS), the to_play variable represents the player
        # whose turn it is to make a move in the current position being considered. This
        # information is used to determine which player's score to update in the MCTS
        # tree, as well as which player's actions to consider when selecting the next
        # move to explore.

        #This configuration always assume the same player is in play.
        self.root.to_play = observation

    def generate_policy_and_value(self):
        policy, value = self.model.prediction_function_inference(
            self.root.hidden_state)
        return policy, value

    def expand_the_children_of_the_root_node(self, policy, player_to_play=0):
        for i in range(policy.shape[0]):
            for h in range(policy.shape[-1]):

                # if self.num_simulations == 0 :
                #     epsilon = np.random.uniform(low=1e-7, high=2e-7, size=1)[0]
                # else:
                #     epsilon = 0 # eps for policy

                self.root.children[h] = Node(prior=policy[i, h])
                self.root.children[h].to_play = self.root.to_play

    def back_propagate_initial_children(self, value, observation):
        for bnode in reversed([self.root]):
            bnode.value_sum += value if torch.equal(observation, bnode.to_play) else -value
            bnode.visit_count += 1
            self.min_max_stats.update(bnode.value())
            value = bnode.reward + self.discount * value

    def add_exploration_noise_at_the_root(self, train):
        if self.num_simulations == 0 :
            train = False

        if train:
            actions = list(self.root.children.keys())
            noise = np.random.dirichlet(
                [self.root_dirichlet_alpha] * len(actions))
            frac = self.root_exploration_fraction
            for a, n in zip(actions, noise):
                self.root.children[a].prior = self.root.children[a].prior * \
                    (1 - frac) + n * frac

    def initialize_history_node_searchpath_variable(self):
        history = []
        self.node = self.root
        search_path = [self.root]
        return history, search_path

    def ucb_score(self, parent, child):
        pb_c = np.log((parent.visit_count + self.pb_c_base + 1) / self.pb_c_base) + self.pb_c_init
        prior_score = (np.sqrt(parent.visit_count) *  pb_c * child.prior) / (child.visit_count + 1)
        if child.visit_count > 0:
            value_score = self.min_max_stats.normalize( child.reward + self.discount * child.value())
        else:
            value_score = 0

        return prior_score + value_score + np.random.uniform(low=1e-7, high=2e-7, size=1)[0]

    def select_child(self):
        _, action, child = max((self.ucb_score(self.node, child), action, child)
                               for action, child in self.node.children.items())
        return action, child

    def choice_node_to_expand_using_max_ucb_score(self, history, search_path):
        while self.node.expanded():
            action, self.node = self.select_child()
            history.append(action)
            search_path.append(self.node)
        return search_path[-2]

    def generate_reward_and_hidden_state(self, parent, history):
        reward, hidden_state = self.model.dynamics_function_inference(
            parent.hidden_state, history[-1])
        return reward, hidden_state

    def update_reward_and_hidden_state_for_the_chosen_node(self, reward, hidden_state):
        self.node.reward, self.node.hidden_state = reward, hidden_state

    def generate_policy_and_value_for_the_chosen_node(self, hidden_state):
        policy, value = self.model.prediction_function_inference(hidden_state)
        return policy, value

    def create_new_node_in_the_chosen_node_with_action_and_policy(self, policy, player_to_play=0):

        for i in range(policy.shape[0]):
            for h in range(policy.shape[-1]):
                self.node.children[h] = Node(prior=policy[i, h])
                self.node.children[h].to_play = self.root.to_play

    def back_propagate_and_update_min_max_bound(self, search_path, value):

        for bnode in reversed(search_path):
            bnode.value_sum += value if torch.equal(self.root.to_play, bnode.to_play) else -value
            bnode.visit_count += 1
            self.min_max_stats.update(bnode.value())
            value = bnode.reward + self.discount * value

    def softmax(self,x):
        return(np.exp(x - np.max(x)) / np.exp(x - np.max(x)).sum())

    def generate_action_and_policy_base_on_node_count(self):

        action = np.array(list(self.root.children.keys()))
        if self.num_simulations >= 1 :
            policy = np.array([self.root.children[u].visit_count for u in list(self.root.children.keys())], dtype=np.float64)
        else:
            policy = np.array([self.root.children[u].prior for u in list(self.root.children.keys())], dtype=np.float64)
        return policy, self.root, action

    def run(self, observation=None,  num_simulations=10, model=None, train=True):

        self.model = model

        self.num_simulations = num_simulations

        self.generate_root_hidden_state(observation)

        self.set_root_to_play_with_the_play_number(observation)

        policy, value = self.generate_policy_and_value()

        self.expand_the_children_of_the_root_node(policy)

        # self.back_propagate_initial_children(value, observation)

        self.add_exploration_noise_at_the_root(train)

        for _ in range(num_simulations):

            history, search_path = self.initialize_history_node_searchpath_variable()

            parent = self.choice_node_to_expand_using_max_ucb_score(
                history, search_path)

            reward, hidden_state = self.generate_reward_and_hidden_state(
                parent, history)

            self.update_reward_and_hidden_state_for_the_chosen_node(
                reward, hidden_state)

            policy, value = self.generate_policy_and_value_for_the_chosen_node(
                hidden_state)

            self.create_new_node_in_the_chosen_node_with_action_and_policy(
                policy)

            self.back_propagate_and_update_min_max_bound(search_path, value)

        policy, root, action = self.generate_action_and_policy_base_on_node_count()

        return policy, root, action


import os
import base64
from datetime import datetime

from flask import Blueprint, render_template, request, flash, redirect, url_for, current_app
from flask_login import current_user, login_user, logout_user, login_required

from microblog.models import db, User
from microblog.forms import LoginForm, RegistrationForm, ProfileForm

auth_bp = Blueprint('auth', __name__)

@auth_bp.route('/login', methods=['GET', 'POST'])
def login():
    form = LoginForm()

    if request.method == 'POST':
        if form.validate_on_submit():
            username = form.username.data
            user = User.query.filter_by(username=username).first()
            if user and user.check_password(form.password.data):
                user.last_login = datetime.utcnow()
                db.session.commit()
                login_user(user)
                if not os.path.exists(user.upload_dir):
                    os.mkdir(user.upload_dir)

                flash("{} başarılı bir giriş yaptın".format(form.username.data))
                next_page = request.args.get('next') or url_for('index.index')
                return redirect(next_page)
            else:
                flash("Kullanıcı adı ya da parola hatalı")
        else:
            flash("Aşağaıda belirtilen alanlar eksik")

    return render_template('auth/login.html', form=form)

@auth_bp.route('/logout')
def logout():
    logout_user()
    return redirect(url_for('auth.login'))

@auth_bp.route('/register', methods=['GET', 'POST'])
def register():
    if current_user.is_authenticated:
        flash("Zaten kayıtlısın")
        return redirect(url_for('index.index'))

    form = RegistrationForm()

    if request.method == 'POST':
        if form.validate_on_submit():
            user = User(username=form.username.data, email=form.email.data)
            user.set_password(form.password.data)
            db.session.add(user)
            db.session.commit()
            flash("Kayıtlanma başarılı. Şimdi giril yapabilirsiniz.")
            return redirect(url_for('auth.login'))

    return render_template('auth/register.html', form=form)

@auth_bp.route('/profile/edit', methods=['GET', 'POST'])
@login_required
def profile_edit():
    form = ProfileForm()

    if request.method == 'POST':
        current_user.about_me = form.about_me.data
        current_user.email_public = form.email_public.data
        if form.avatar.data:
            avatar = form.avatar.data.stream.read()
            current_user.avatar = base64.encodebytes(avatar).decode()
        db.session.commit()
        flash("Profiliniz kaydedildi")

    else:
        form.about_me.data = current_user.about_me
        form.email_public.data = current_user.email_public

    return render_template('auth/profile_edit.html', form=form)

@auth_bp.route('/profile/show/<username>')
@login_required
def profile_show(username):
    puser = User.query.filter_by(username=username).first()
    if not puser:
        flash("Böyle bir kullanıcı mevcut değil")
        return redirect(url_for('index.index'))

    return render_template('auth/profile_show.html', puser=puser)


from netaddr import IPAddress

__all__ = [
    'to_server_dict',
    'to_dns_zone_dict',
    'to_dns_record_dict'
]

def to_server_dict(server):
    public_ips = [ip['addr'] for ip in server.addresses['public']]
    private_ips = [ip['addr'] for ip in server.addresses['private']]

    # Pick out first public IPv4 and IPv6 address
    public_ipv4 = None
    public_ipv6 = None

    for ip in public_ips:
        try:
            ip_obj = IPAddress(ip)
        except Exception:
            continue

        if not ip_obj.is_private():
            if ip_obj.version == 4:
                public_ipv4 = ip
            elif ip_obj.version == 6:
                public_ipv6 = ip

    result = {
        'id': server.id,
        'name': server.name,
        'status': server.status,
        'image_id': server.image['id'],
        'flavor_id': server.flavor['id'],
        'public_ips': public_ips,
        'private_ips': private_ips,
        'public_ipv4': public_ipv4,
        'public_ipv6': public_ipv6,
        'key_name': server.key_name,
        'metadata': server.metadata
    }
    return result

def to_dns_zone_dict(zone):
    result = {
        'id': zone.id,
        'name': zone.name,
        'email_address': zone.emailAddress,
        'ttl': zone.ttl
    }
    return result

def to_dns_record_dict(record):
    result = {
        'id': record.id,
        'name': record.name,
        'type': record.type,
        'data': record.data,
        'ttl': record.ttl
    }
    return result


import sys
from awsglue.transforms import *
from awsglue.utils import getResolvedOptions
from pyspark.context import SparkContext
from awsglue.context import GlueContext
from awsglue.job import Job
from pyspark.sql import functions as f
from pyspark.sql.functions import udf
from pyspark.sql import types as t
from pyspark.sql.functions import monotonically_increasing_id
from pyspark.sql.functions import lit

args = getResolvedOptions(sys.argv, ['JOB_NAME'])
sc = SparkContext()
glueContext = GlueContext(sc)
spark = glueContext.spark_session
job = Job(glueContext)
job.init(args['JOB_NAME'], args)

similarity_tuples = glueContext.create_dynamic_frame.from_catalog(database="zappos-prod-similarity", table_name="out")

verticesDF = glueContext.create_dynamic_frame.from_catalog(database="zappos-prod-similarity", table_name="vertices").toDF()
analyzed_products = similarity_tuples.toDF().groupby(['category','subcategory','brand','productid']).agg(f.count(f.col('productid')).alias('c'))

vertices_to_process = analyzed_products \
.join(verticesDF.alias('v'), (f.col('v.category:string') == f.col('category')) \
& (f.col('v.subcategory:string') == f.col('subcategory')) \
& (f.col('v.brand:string') == f.col('brand')) \
& (f.col('v.product:string') == f.col('productid'))) \
.select(f.col('v.~id'), f.col('category'), f.col('subcategory'), f.col('brand'), f.col('productid'))

edgesDF= similarity_tuples.toDF().alias('st') \
.join(vertices_to_process.alias('vtp'), (f.col('vtp.category') == f.col('st.category')) \
& (f.col('vtp.subcategory') == f.col('st.subcategory')) \
& (f.col('vtp.brand') == f.col('st.brand')) \
& (f.col('vtp.productid') == f.col('st.productid'))) \
.join(verticesDF.alias('v'), (f.col('v.~label') == f.col('st.c_image_path'))) \
.withColumn("eid", monotonically_increasing_id()) \
.withColumn('~label', lit('similar')) \
.select(f.col('eid').alias('~id'), \
        f.col('vtp.~id').alias('~from'),\
        f.col('v.~id').alias('~to'),\
        f.col('~label'),\
        f.col('st.similarity').alias('similarity:Double')).orderBy(['vtp.~id','similarity:Double'], ascending=[1, 1])

EDGE_DATA_OUTPUT_S3_BUCKET = "s3://sagemaker-us-west-2-803235869972/sagemaker/DEMO-pytorch-siamese-network/gremlin/edges"

edgesDF = edgesDF.repartition(8)
edgesDF.write.csv(EDGE_DATA_OUTPUT_S3_BUCKET, header="true", compression="gzip", mode="overwrite")

job.commit()


import cv2
import numpy as np

img = cv2.imread("Documents/python/images/lena-1.jpg")
lr1 = cv2.pyrDown(img)
lr2 = cv2.pyrDown(lr1)
hr2 = cv2.pyrUp(lr2)

cv2.imshow("original image", img)
cv2.imshow("pyrDown1 image", lr1)
cv2.imshow("pyrDown2 image", lr2)
cv2.imshow("pyrUp 1 image", hr2)
#this image has bad quality than lr2 because during pyrdown we lise the image info

cv2.waitKey(0)
cv2.destroyAllWindows()


# -*- coding: utf-8 -*-
"""
Created on Wed May 31 12:48:30 2017

@author: Camden Ko camdenko@gmail.com
"""
import numpy as np
from random import *
from Tkinter import Tk
import csv
from tkFileDialog import askopenfilename

pvalue = []
vec = []
index = []
rawInput = []
pValues = []

numIterations = int(raw_input("# of iterations: "))
fullSize = int(raw_input("What is the total size of sample? "))
bootSize = int(raw_input("What size of subset do you wish to use? "))
numDays = int(raw_input("How many days did the experiment last? "))
endTime = int(raw_input("When does the experiment end (minutes)?"))

Tk().withdraw()
filename = askopenfilename()

dataFile = open(filename, 'r')
dataReader = csv.reader(dataFile)
for row in dataReader:      # reads in data from chosen csv file
    rawInput.append(row),

dataWidth = numDays
dataHeight = bootSize
data = np.zeros((dataWidth, dataHeight))

# proccess rawInput to open/vs not open
for row_index, row in enumerate(rawInput):
    for col_index, item in enumerate(row):
        rawInput[row_index][col_index] = int(rawInput[row_index][col_index])
        if(rawInput[row_index][col_index] < endTime):
            rawInput[row_index][col_index] = 1.0
        else:
            rawInput[row_index][col_index] = 0.0

# totalOpeners is the total number of opens
totalOpeners = np.sum(rawInput)

inputArray = np.array(rawInput)
# calculate probability between days
dayProb = inputArray.sum(axis = 0)

# calculate probability between rats
ratProb = inputArray.sum(axis = 1)

for row_index, row in enumerate(ratProb):
    ratProb[row_index] = (ratProb[row_index]) / totalOpeners

for row_index, row in enumerate(dayProb):
    dayProb[row_index] = (dayProb[row_index]) / totalOpeners

for rawIt in range(0,numIterations):
    # generate random numbers for index from 1 thru fullSize w/out replacement
    choices = np.random.choice(fullSize - 1, bootSize, replace=False)
    for rowNum in range(0, bootSize):
        for x in range(0, dataWidth):
            data[x][rowNum] = rawInput[x][rowNum]

    # data is now full of random rows of information from raw data

    iterationsOnEach = 5000
    probDist = []
    # iterating
    for iteration in range(0, iterationsOnEach):
        randArr = np.random.rand(len(ratProb), len(dayProb))
        numSequent = 0.0
        numOpens = 0.0
        for row_index, row in enumerate(randArr):
            for col_index, item in enumerate(row):
                if(randArr[row_index][col_index] >= dayProb[col_index] * ratProb[row_index] * totalOpeners):
                    randArr[row_index][col_index] = 0
                else:
                    randArr[row_index][col_index] = 1
        for row_index in range(0, len(ratProb) - 1):
            for col_index in range(0, len(dayProb)):
                if(randArr[row_index][col_index] == 1):
                    numOpens += 1.0
                    if(randArr[row_index+1][col_index] ==1):
                        numSequent += 1.0
        probDist.append(numSequent / numOpens)
    averageProbDist = sum(probDist) / len(probDist)

    # calculate the actual values
    numSequent = 0.0
    numOpens = 0.0
    for x in range(0,len(ratProb)-1):
        for y in range(0,len(dayProb)):
            if(inputArray[x][y] == 1):
                numOpens += 1
                if(rawInput[x+1][y] == 1):
                    numSequent += 1
    actualProb = numSequent / numOpens

    numDeviate = 0.0
    for iteration in range(0,iterationsOnEach):
        if abs(probDist[iteration] - averageProbDist) >= abs(actualProb - averageProbDist):
            numDeviate += 1
    pvalue.append(numDeviate/iterationsOnEach)


import json

with open('misleading.json','r') as f:
    results = json.load(f)
"""
res = {
    'margins':list(margins),
    'min_round_sizes':list(round_sizes),
    'prov_sprobs':list(prov_sprobs),
    'so_sprobs':list(so_sprobs),
    'eor_sprobs':list(eor_sprobs)
}
"""
s = "\\begin{tabular}{ |c|c|c|c|c| } \n\\hline \n misleading & margin & $n$ & Prov & SO & EOR \\\\\n\hline\n"

for i in range(len(results['misleading_limits'])):
    misleading_limit = results['misleading_limits'][i]

    s += str(misleading_limit)

    res = results['results'][i]
    margins = res['margins']
    min_round_sizes = res['min_round_sizes']
    prov_sprobs = res['prov_sprobs']
    so_sprobs = res['so_sprobs']
    eor_sprobs = res['eor_sprobs']

    for i in range(len(margins)):
        #print('margin:'+str(margins[i]))
        #print('min round size:'+str(min_round_sizes[i]))
        #print('prov sprob:'+str(prov_sprobs[i]))
        m = str(margins[i])
        r = str(min_round_sizes[i])
        t = 1000
        p = str(int(prov_sprobs[i] * t) / t)
        so = str(int(so_sprobs[i] * t) / t)
        eor = str(int(eor_sprobs[i] * t) / t)
        #s+=str(margins[i])+'&'+str()+'&'+str(prov_sprobs[i])+'&'+str(so_sprobs[i])+'&'+str(eor_sprobs[i])+'\\\\\n'
        s+='&'+m+'&'+r+'&'+p+'&'+so+'&'+eor+'\\\\\n'

s+="\hline\n\end{tabular}"

print(s)


from django.shortcuts import render, redirect,get_object_or_404, HttpResponseRedirect
from .models import Category, Photo
from django.contrib import messages

# Create your views here.
def welcome(request):

    return render(request, 'photos/base.html')
def gallery(request):

    category = request.GET.get('category')
    if category == None:
       photos = Photo.objects.all()

    else:
        photos = Photo.objects.filter(category__name__contains=category)

    categories = Category.objects.all()
    # photos = Photo.objects.all()

    context = {'categories': categories, 'photos': photos}

    return render(request, 'photos/gallery.html', context)

def viewPhoto(request, pk):
    photo = Photo.objects.get(id=pk)
    return render(request, 'photos/photo.html', {'photo':photo})

def addPhoto(request):
    categories = Category.objects.all()

    if request.method == 'POST':
        data = request.POST
        image = request.FILES.get('image')

        if data['category'] != 'none':
            category = Category.objects.get(id=data['category'])

        elif data['category_new'] != '':
            category, created = Category.objects.get_or_create(name=data['category_new'])

        else:
            category = None

        photo = Photo.objects.create(
            category=category,
            description=data['description'],
            image = image,
        )

        messages.info(request, 'Photo added successfully!')
        return redirect('gallery')

    context = {'categories': categories }

    return render(request, 'photos/add.html',context)

def deletePhoto(request, pk):

    if request.method == 'POST':
        instance = Photo.objects.get(pk =pk)
        instance.delete()
        print('photo deleted')

        messages.info(request, 'Photo deleted successfully!')

        return redirect('gallery')

    else:
        return render(request, 'photos/photo.html')

def updatePhoto(request):
    if request == 'POST':
        replace = Photo.objects.get()
        replace.update()
        print('Photo replaced!')

    else:
        return render(request, 'photos/update.html')


import os
import json
import shutil
import argparse
import datetime
from dataclasses import dataclass, asdict
from dacite import from_dict
@dataclass
class Asset:
    m_FileID: int
    m_PathID: int

@dataclass
class OneLiner:
    characterProgressTokens: list[Asset]
    worldProgressTokens: list[Asset]
    priority: int
    text: list[Asset]

@dataclass
class DialogueCycle:
    relationshipRequirement: int
    text: Asset
    oneLiners: list[OneLiner]

@dataclass
class NPCDialogueCyclesWithText:
    npc_name: str
    married_cycles: list[str]
    dating_cycles: list[str]
    general_cycles: list[str] # note these are used for dating too if you finish the dating cycles
    one_liners: list[list[str]] # one liners have requirements that I'm not extracting yet, but the progress tokens + priority should tell you when they get used

@dataclass
class NPCDialogueCycles:
    npc_name: str
    married_cycles: list[DialogueCycle]
    dating_cycles: list[DialogueCycle]
    general_cycles: list[DialogueCycle] # note these are used for dating too if you finish the dating cycles
    one_liners: list[OneLiner] # one liners have requirements that I'm not extracting yet, but the progress tokens + priority should tell you when they get used

    def process_assets(self, assets: dict[int, str]) -> NPCDialogueCyclesWithText:
        married_cycles_text = []
        for cycle in self.married_cycles:
            text = assets.get(cycle.text.m_PathID, "")
            married_cycles_text.append(text)
        date_cycles_text = []
        for cycle in self.dating_cycles:
            text = assets.get(cycle.text.m_PathID, "")
            date_cycles_text.append(text)
        general_cycles_text = []
        for cycle in self.general_cycles:
            text = assets.get(cycle.text.m_PathID, "")
            general_cycles_text.append(text)
        oneliner_text = []
        for liner in self.one_liners:
            lines = []
            for t in liner.text:
                text = assets.get(t.m_PathID, "")
                lines.append(text)
            oneliner_text.append(lines)
        return NPCDialogueCyclesWithText(
            npc_name=self.npc_name,
            married_cycles=married_cycles_text,
            dating_cycles=date_cycles_text,
            general_cycles=general_cycles_text,
            one_liners=oneliner_text
        )

def generate(extracted_folder : str, destination_folder : str, npc: str):
    npc_cycles: dict[str, NPCDialogueCycles] = {}
    npc_text: dict[str, dict[int, str]] = {}
    npc = npc.lower()
    for file in os.listdir(extracted_folder):
        file_path = os.path.join(extracted_folder, file)

        if npc != "" and not file.startswith(npc):
            continue
        if file.endswith(".json"):
            npcai = {}
            with open(file_path, "r") as f:
                npcai = json.load(f)
            npc_name = npcai["_npcName"].lower()
            dialogue_cycles = [from_dict(DialogueCycle, x) for x in npcai["_dialogueCycles"]]
            dating_cycles =[from_dict(DialogueCycle, x) for x in npcai["_datingCycles"]]
            married_cycles = [from_dict(DialogueCycle, x) for x in npcai["_marriedCycles"]]
            one_liners = [from_dict(OneLiner, x) for x in npcai["_oneLiners"]]
            data = NPCDialogueCycles(
                npc_name=npc_name,
                married_cycles=married_cycles,
                dating_cycles=dating_cycles,
                general_cycles=dialogue_cycles,
                one_liners=one_liners
            )
            npc_cycles[npc_name] = data
        elif file.endswith(".txt"):
            parts = file.split("_")
            npc_name = parts[0]
            path_id = int(parts[1])
            with open(file_path, "rt", encoding="utf-8") as f:
                contents = f.read()
                if npc_name not in npc_text:
                    npc_text[npc_name] = {}
                npc_text[npc_name][path_id] = contents

    for (npc_name, data) in npc_cycles.items():
        # find the text files
        print(f"Processing {npc_name}")
        assets = npc_text.get(npc_name, None)
        if assets is None:
            continue
        x = data.process_assets(assets=assets)
        file_path = os.path.join(destination_folder, f"{npc_name}_cycles.json")
        with open(file_path, "w") as f:
            f.write(json.dumps(asdict(x)))

# generate jsons for each npc for passing to the ai
if __name__ == "__main__":
    parser = argparse.ArgumentParser()

    date_time = datetime.datetime.now().strftime("%m%d%Y-%H%M%S")
    parser.add_argument("-o", "--output", type=str, default=f"generate-{date_time}", help="Output directory. If this folder already exists, it will be deleted!")
    parser.add_argument("-i", "--input", type=str, help="Extracted folder with all dialogue and npcai json")
    parser.add_argument("-n", "--npc", type=str, default="", help="If provided, only extract for the given npc. Else extract all npcs.")

    args = parser.parse_args()

    folder = args.output
    if os.path.exists(folder):
        print(f"Folder {folder} already exists, deleting...")
        shutil.rmtree(folder)
    os.mkdir(folder)
    generate(extracted_folder=args.input, destination_folder=folder, npc=args.npc)