import importlib
import os
from collections import OrderedDict
from lib.test.evaluation.environment import env_settings
import time
import cv2 as cv

from lib.utils.lmdb_utils import decode_img
from pathlib import Path
import numpy as np
import matplotlib.pyplot as plt
from segment_anything import build_sam, SamPredictor,sam_model_registry

def show_mask(mask, ax, random_color=False):
    if random_color:
        color = np.concatenate([np.random.random(3), np.array([0.6])], axis=0)
    else:
        color = np.array([30 / 255, 144 / 255, 255 / 255, 0.6])
    h, w = mask.shape[-2:]
    mask_image = mask.reshape(h, w, 1) * color.reshape(1, 1, -1)
    ax.imshow(mask_image)

def show_points(coords, labels, ax, marker_size=375):
    pos_points = coords[labels == 1]
    neg_points = coords[labels == 0]
    ax.scatter(pos_points[:, 0], pos_points[:, 1], color='green', marker='*', s=marker_size, edgecolor='white',
               linewidth=1.25)
    ax.scatter(neg_points[:, 0], neg_points[:, 1], color='red', marker='*', s=marker_size, edgecolor='white',
               linewidth=1.25)

def show_box(box, ax):
    x0, y0 = box[0], box[1]
    w, h = box[2] - box[0], box[3] - box[1]
    ax.add_patch(plt.Rectangle((x0, y0), w, h, edgecolor='green', facecolor=(0, 0, 0, 0), lw=2))

def trackerlist(name: str, parameter_name: str, dataset_name: str, run_ids = None, display_name: str = None,
                result_only=False):
    """Generate list of trackers.
    args:
        name: Name of tracking method.
        parameter_name: Name of parameter file.
        run_ids: A single or list of run_ids.
        display_name: Name to be displayed in the result plots.
    """
    if run_ids is None or isinstance(run_ids, int):
        run_ids = [run_ids]
    return [Tracker(name, parameter_name, dataset_name, run_id, display_name, result_only) for run_id in run_ids]

def to_int(string):
    return int(os.path.basename(string)[:-4])

class Tracker:
    """Wraps the tracker for evaluation and running purposes.
    args:
        name: Name of tracking method.
        parameter_name: Name of parameter file.
        run_id: The run id.
        display_name: Name to be displayed in the result plots.
    """

    def __init__(self, name: str, parameter_name: str, dataset_name: str, run_id: int = None, display_name: str = None,
                 result_only=False):
        assert run_id is None or isinstance(run_id, int)

        self.name = name
        self.parameter_name = parameter_name
        self.dataset_name = dataset_name
        self.run_id = run_id
        self.display_name = display_name
        self.predictor = SamPredictor(sam_model_registry["vit_h"](checkpoint="").to(device="cuda"))

        env = env_settings()
        if self.run_id is None:
            self.results_dir = '{}/{}/{}'.format(env.results_path, self.name, self.parameter_name)
        else:
            self.results_dir = '{}/{}/{}_{:03d}'.format(env.results_path, self.name, self.parameter_name, self.run_id)
        if result_only:
            self.results_dir = '{}/{}'.format(env.results_path, self.name)

        tracker_module_abspath = os.path.abspath(os.path.join(os.path.dirname(__file__),
                                                              '..', 'tracker', '%s.py' % self.name))
        if os.path.isfile(tracker_module_abspath):
            tracker_module = importlib.import_module('lib.test.tracker.{}'.format(self.name))
            self.tracker_class = tracker_module.get_tracker_class()
        else:
            self.tracker_class = None

    def create_tracker(self, params):
        tracker = self.tracker_class(params, self.dataset_name)
        return tracker

    def run_sequence(self, seq, debug=None):
        """Run tracker on sequence.
        args:
            seq: Sequence to run the tracker on.
            visualization: Set visualization flag (None means default value specified in the parameters).
            debug: Set debug level (None means default value specified in the parameters).
            multiobj_mode: Which mode to use for multiple objects.
        """
        params = self.get_parameters()

        debug_ = debug
        if debug is None:
            debug_ = getattr(params, 'debug', 0)

        params.debug = debug_

        init_info = seq.init_info()

        tracker = self.create_tracker(params)

        output = self._track_sequence(tracker, seq, init_info)
        return output

    def _track_sequence(self, tracker, seq, init_info):

        output = {'target_bbox': [],
                  'time': []}
        if tracker.params.save_all_boxes:
            output['all_boxes'] = []
            output['all_scores'] = []

        def _store_outputs(tracker_out: dict, defaults=None):
            defaults = {} if defaults is None else defaults
            for key in output.keys():
                val = tracker_out.get(key, defaults.get(key, None))
                if key in tracker_out or val is not None:
                    output[key].append(val)

        image = self._read_image(seq.frames[0])

        start_time = time.time()
        out = tracker.initialize(image, init_info)
        if out is None:
            out = {}

        prev_output = OrderedDict(out)
        init_default = {'target_bbox': init_info.get('init_bbox'),
                        'time': time.time() - start_time}
        if tracker.params.save_all_boxes:
            init_default['all_boxes'] = out['all_boxes']
            init_default['all_scores'] = out['all_scores']

        _store_outputs(out, init_default)

        for frame_num, frame_path in enumerate(seq.frames[1:], start=1):
            image = self._read_image(frame_path)

            start_time = time.time()

            info = seq.frame_info(frame_num)
            info['previous_output'] = prev_output

            if len(seq.ground_truth_rect) > 1:
                info['gt_bbox'] = seq.ground_truth_rect[frame_num]
            out = tracker.track(image, info)
            prev_output = OrderedDict(out)
            _store_outputs(out, {'time': time.time() - start_time})

        for key in ['target_bbox', 'all_boxes', 'all_scores']:
            if key in output and len(output[key]) <= 1:
                output.pop(key)

        return output

    def mouse_handler(self,event, x, y, flags,param):
        if event == cv.EVENT_LBUTTONDOWN and flags ==cv.EVENT_FLAG_CTRLKEY + cv.EVENT_LBUTTONDOWN:

            self.input_point.append([x,y])
            self.input_lbael.append(int(0))
            self.samflag=True
        elif event == cv.EVENT_LBUTTONDOWN:

            self.input_point.append([x,y])
            self.input_lbael.append(int(1))
            self.samflag=True

    def run_imgdir(self, videofilepath, optional_box=None, debug=None, visdom_info=None, save_results=False,index=None):
        """Run the tracker with the vieofile.
        args:
            debug: Debug level.
        """
        img_list=os.listdir(videofilepath)
        img_list.sort(key=to_int)
        params = self.get_parameters()

        debug_ = debug
        if debug is None:
            debug_ = getattr(params, 'debug', 0)
        params.debug = debug_

        params.tracker_name = self.name
        params.param_name = self.parameter_name

        multiobj_mode = getattr(params, 'multiobj_mode', getattr(self.tracker_class, 'multiobj_mode', 'default'))

        if multiobj_mode == 'default':
            tracker = self.create_tracker(params)

        else:
            raise ValueError('Unknown multi object mode {}'.format(multiobj_mode))

        output_boxes = []

        def _build_init_info(box):
            return {'init_bbox': box}

        display_name = 'Display: ' + tracker.params.tracker_name
        if optional_box is not None:
            frame = cv.imread(videofilepath + '/' + img_list[0])
            frame_disp = frame.copy()
            color_seg = np.zeros((frame.shape[0], frame.shape[1], 3), dtype=np.uint8)
            self.predictor.set_image(cv.cvtColor(frame, cv.COLOR_BGR2RGB))
            self.input_point=[]
            self.input_lbael=[]
            self.samflag=False

            while True:
                cv.imshow(display_name,frame_disp*(1-color_seg))
                cv.setMouseCallback(display_name, self.mouse_handler)

                k=cv.waitKey(1)
                if self.samflag==True:
                    color_seg = np.zeros((frame.shape[0], frame.shape[1], 3), dtype=np.uint8)
                    masks, scores, logits = self.predictor.predict(
                        point_coords=np.array(self.input_point),
                        point_labels=np.array(self.input_lbael),
                        multimask_output=True,)
                    mask = masks[np.argmax(scores)]
                    inde = np.where(mask == True)
                    xx = inde[0].min()
                    yy = inde[1].min()
                    ww = inde[0].max() - xx
                    hh = inde[1].max() - yy
                    cv.rectangle(color_seg, [yy,xx,hh,ww],(1,1,1), 3)
                    if self.input_lbael[-1]==0:
                        cv.circle(frame_disp, (self.input_point[-1][0], self.input_point[-1][1]), 5, (0, 128, 0), -1)
                    elif self.input_lbael[-1]==1:
                        cv.circle(frame_disp, (self.input_point[-1][0], self.input_point[-1][1]), 5, (0, 0, 128), -1)
                    self.samflag=False
                if k==ord('f'):
                    break
                elif k==ord('r'):
                    frame_disp = frame.copy()
                    self.input_point = []
                    self.input_lbael = []
                    color_seg = np.zeros((frame.shape[0], frame.shape[1], 3), dtype=np.uint8)
            init_state = [yy,xx, hh, ww]
            tracker.initialize(frame, _build_init_info(init_state))
            output_boxes.append(init_state)

        else:

            cv.namedWindow(display_name, cv.WINDOW_NORMAL | cv.WINDOW_KEEPRATIO)
            cv.resizeWindow(display_name, 960, 720)

            frame = cv.imread(videofilepath + '/' + img_list[0])
            cv.imshow(display_name, frame)
            while True:

                frame_disp = frame.copy()

                cv.putText(frame_disp, 'Select target ROI and press ENTER', (20, 30), cv.FONT_HERSHEY_COMPLEX_SMALL,
                           1.5, (0, 0, 0), 1)

                x, y, w, h = cv.selectROI(display_name, frame_disp, fromCenter=False)
                init_state = [x, y, w, h]
                tracker.initialize(frame, _build_init_info(init_state))
                output_boxes.append(init_state)
                break

        for img in img_list:
            frame = cv.imread(videofilepath+'/'+img)

            if frame is None:
                break

            img_tosave = frame.copy()

            out = tracker.track(frame)
            state = [int(s) for s in out['target_bbox']]
            output_boxes.append(state)

            cv.rectangle(img_tosave, (state[0], state[1]), (state[2] + state[0], state[3] + state[1]),
                         index, 5)
            self.predictor.set_image(cv.cvtColor(frame, cv.COLOR_BGR2RGB))
            masks, scores, logits = self.predictor.predict(box=np.array([state[0],state[1],state[2] + state[0],state[3] + state[1]]), multimask_output=True, )
            mask = masks[np.argmax(scores)]
            color_seg = np.zeros((mask.shape[0], mask.shape[1], 3), dtype=np.uint8)
            color_seg[mask == True, :] = (0, 0, 255)

            cv.imshow(display_name, (img_tosave*0.5+color_seg*0.5)/255)
            key = cv.waitKey(1)

        cv.destroyAllWindows()

    def get_parameters(self):
        """Get parameters."""
        param_module = importlib.import_module('lib.test.parameter.{}'.format(self.name))
        params = param_module.parameters(self.parameter_name)
        return params

    def _read_image(self, image_file: str):
        if isinstance(image_file, str):
            im = cv.imread(image_file)
            return cv.cvtColor(im, cv.COLOR_BGR2RGB)
        elif isinstance(image_file, list) and len(image_file) == 2:
            return decode_img(image_file[0], image_file[1])
        else:
            raise ValueError("type of image_file should be str or list")


from setuptools import setup, find_packages

version = '0.0.6'

setup(name="helga-redmine",
      version=version,
      description=('redmine plugin for helga'),
      classifiers=['Development Status :: 4 - Beta',
                   'License :: OSI Approved :: MIT License',
                   'Operating System :: OS Independent',
                   'Programming Language :: Python',
                   'Topic :: Software Development :: Libraries :: Python Modules',
                   ],
      keywords='irc bot redmine',
      author='alfredo deza',
      author_email='contact [at] deza [dot] pe',
      url='https://github.com/alfredodeza/helga-redmine',
      license='MIT',
      packages=find_packages(),
      install_requires=[
          'helga>=1.7.5',
          'treq>=15.1.0',
          'twisted',
      ],
      tests_require=[
          'pytest-twisted',
      ],
      entry_points = dict(
          helga_plugins = [
              'redmine = redmine:redmine',
          ],
      ),
)


import asyncio
from datetime import datetime

from pytz import UTC
from discord import Intents, Embed, TextChannel, Role
from discord.ext.commands import Bot, Context
from discord.member import Member
from bson import ObjectId
from bson.errors import InvalidId
from gflbans.api_util import construct_ci_resp
from gflbans.discord.colors import COLOR_ERROR, COLOR_INFO
from gflbans.discord.compat import DiscordApp
from gflbans.internal.config import DISCORD_BOT_TOKEN, FORUMS_HOST, HOST, MONGO_DB, ROOT_USER
from gflbans.internal import VERSION
from subprocess import PIPE, Popen
import sys
from typing import List, Optional
from gflbans.discord.auth import checkaccess, generate_confirmation_link, get_gfl_admin, update_confirmations
from gflbans.internal.constants import NOT_AUTHED_USER, SERVER_KEY
from gflbans.internal.database.group import DGroup
from gflbans.internal.database.infraction import build_query_dict
from gflbans.internal.database.server import DServer
from gflbans.internal.flags import ALL_PERMISSIONS, PERMISSION_ADMIN_CHAT_BLOCK, PERMISSION_BAN, PERMISSION_BLOCK_CHAT, PERMISSION_BLOCK_VOICE, PERMISSION_CALL_ADMIN_BLOCK, PERMISSION_CREATE_INFRACTION, PERMISSION_MANAGE_SERVERS, PERMISSION_SCOPE_GLOBAL, PERMISSION_VIEW_AUDIT_LOG
from gflbans.internal.integrations.games import get_user_info, normalize_id
from gflbans.internal.integrations.ips import get_groups
from gflbans.internal.kv import set_var
from gflbans.internal.loader import configure_app

bot = Bot(command_prefix='g!', description=f'GFLBans v{VERSION}', intents=Intents.default())

@bot.event
async def on_ready():
    await set_var(bot.app.state.db[MONGO_DB], 'bot.name', bot.user.name)
    await set_var(bot.app.state.db[MONGO_DB], 'bot.avatar', str(bot.user.avatar_url))
    asyncio.get_running_loop().create_task(update_confirmations(bot))

def run_shell(command: List[str]) -> str:
    return Popen(command, stdout=PIPE).communicate()[0].decode('utf-8')

@bot.command(name='status')
#@requireaccess(access=PERMISSION_VIEW_AUDIT_LOG)
async def status(ctx: Context):
    if not await checkaccess(ctx, access=PERMISSION_VIEW_AUDIT_LOG):
        return

    uname = run_shell(['uname', '-a'])
    memory = run_shell(['free', '-h'])
    iostat = run_shell(['iostat', '-c'])
    gflbans = f'GFLBans v{VERSION} running on Python {sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}'

    embed = Embed(colour=COLOR_INFO, title=gflbans)
    embed.add_field(name='Output of `uname -a`:', value=f'```\n{uname}\n```', inline=False)
    embed.add_field(name='Output of `free -h`:', value=f'```\n{memory}\n```', inline=False)
    embed.add_field(name='Output of `iostat -c`:', value=f'```\n{iostat}\n```', inline=False)
    embed.set_footer(text=f'GFLBans {VERSION}', icon_url=f'https://{HOST}/static/images/gflbans256.png')
    await ctx.reply(embed=embed)

@bot.command(name='testconfirm')
async def confirmlink(ctx: Context):
    adm = await get_gfl_admin(ctx.bot.app, ctx.author)

    if not await checkaccess(ctx, access=PERMISSION_VIEW_AUDIT_LOG, adm=adm):
        return

    await generate_confirmation_link(ctx, adm.ips_id, 'pass', [])

@bot.command(name='cantrunthis')
async def impossible_command(ctx: Context):
    if not await checkaccess(ctx, access=214748364787534789457893807592387905432):
        return
    await ctx.reply('You should not see this!')

@bot.command(name='whoami')
async def whois(ctx: Context, target: Member = None):
    if target is None:
        target = ctx.author

    adm = await get_gfl_admin(ctx.bot.app, target)

    if adm is None:
        return await ctx.reply(embed=Embed(colour=COLOR_ERROR, title='Good Question!', description=f'I do not know who you are!\n\nCould not find an admin associated with your Discord account. Add your Discord account as a login method to https://{FORUMS_HOST}'))

    privilege_str = f'{adm.name} has permission flags {adm.permissions}'

    groups = await get_groups(ctx.bot.app)

    id_to_name = {}

    for grp in groups:
        id_to_name[grp['id']] = grp['name']

    if adm.permissions == 0:
        pass
    elif adm.ips_id == ROOT_USER:
        privilege_str += f':\n\nGFLBans Root User ({ALL_PERMISSIONS})\n'
    else:
        privilege_str += ':\n\n'

    if adm.db is not None:
        di = False
        for grp in adm.db.groups:
            di = True
            dg = await DGroup.find_one_from_query(ctx.bot.app.state.db[MONGO_DB], {'ips_group': grp})

            if dg is None or grp not in id_to_name:
                continue

            privilege_str += f'{id_to_name[grp]} ({dg.privileges})\n'

    if not di or adm.db is None:
        privilege_str += 'No Group (0)'

    em = Embed(colour=COLOR_INFO, title=adm.name, url=f'https://{FORUMS_HOST}/profile/{adm.ips_id}-user/', description=privilege_str)
    if adm.avatar:
        em.set_thumbnail(url=f'https://{HOST}/file/uploads/{adm.avatar.gridfs_file}/{adm.avatar.file_name}')

    em.set_footer(text=f'GFLBans {VERSION}', icon_url=f'https://{HOST}/static/images/gflbans256.png')

    return await ctx.reply(embed=em)

_nouns = {
    'voice_block': 'Voice Chat Block',
    'chat_block': 'Text Chat Block',
    'ban': 'Ban',
    'admin_chat_block': 'Admin Chat Block',
    'call_admin_block': 'Call Admin Block',
}

@bot.command(name='check')
async def check_infractions(ctx: Context, gsid: str, service: str = 'steam', as_server: Optional[str] = None):
    if as_server:
        actor_type = SERVER_KEY
        actor_id = as_server
    else:
        actor_type = NOT_AUTHED_USER
        actor_id = 'GFLBANSDISCORD'

    gsid = await normalize_id(ctx.bot.app, service, gsid)

    q = build_query_dict(actor_type, actor_id, gs_service=service, gs_id=gsid,
                         ip=None, ignore_others=False, active_only=True)

    ci_resp = await construct_ci_resp(ctx.bot.app.state.db[MONGO_DB], q)

    ui = await get_user_info(ctx.bot.app, service, gsid)

    embed = Embed(title=f'Restrictions for {ui["name"]}', colour=COLOR_INFO)
    embed.set_thumbnail(url=ui['avatar_url'])

    for t, cs in ci_resp.dict().items():
        if not cs: continue

        exp = 'Doesn\'t Expire.'

        if 'expiration' in cs and cs['expiration']:
            exp = f'Expires {datetime.fromtimestamp(cs["expiration"], tz=UTC).strftime("%m/%d/%Y, %H:%M:%S %Z")}.'

        embed.add_field(name=_nouns[t], value=f'"{cs["reason"]}" by {cs["admin_name"]}. {exp}', inline=False)

    embed.set_footer(text=f'GFLBans {VERSION}', icon_url=f'https://{HOST}/static/images/gflbans256.png')

    await ctx.reply(embed=embed)

@bot.command(name='setupcalladmin')
async def setup_calladmin(ctx: Context, server_id: str, channel: TextChannel, role: Role):
    adm = await get_gfl_admin(ctx.bot.app, ctx.author)

    if not await checkaccess(ctx, adm=adm, access=(PERMISSION_MANAGE_SERVERS)):
        return

    try:
        srv = await DServer.from_id(ctx.bot.app.state.db[MONGO_DB], ObjectId(server_id))

        if srv is None:
            return await ctx.reply(context=f'I could not find a server with the ID `{server_id}`.')
    except InvalidId:
        server_ip = server_id.split(':')

        srv = await DServer.find_one_from_query(ctx.bot.app.state.db[MONGO_DB], {'ip': server_ip[0], 'game_port': int(server_ip[1])})

        if not srv:
            return await ctx.reply(content=f'`{server_id}` is not a valid server ID and I could not find a server with that IP.')

    wh = (await channel.create_webhook(name='Call Admin', reason='dcl_initcalladmin')).url

    await generate_confirmation_link(ctx, adm.ips_id, 'setupcalladmin', [str(srv.id), wh, str(role.id), str(channel.id)])

bc = {
    'sgag': (('voice_block', ), PERMISSION_BLOCK_VOICE),
    'smute': (('chat_block', ), PERMISSION_BLOCK_CHAT),
    'sban': (('ban', ), PERMISSION_BAN),
    'sacblock': (('admin_chat_block', ), PERMISSION_ADMIN_CHAT_BLOCK),
    'scablock': (('call_admin_block', ), PERMISSION_CALL_ADMIN_BLOCK),
    'ssilence': (('voice_block', 'chat_block'), PERMISSION_BLOCK_CHAT | PERMISSION_BLOCK_VOICE)
}

units = {
    's': 1,
    'm': 60,
    'h': 3600,
    'd': 3600 * 24,
    'w': 3600 * 24 * 7,
    'mo': 3600 * 24 * 30,
    'y': 3600 * 24 * 365
}

for a1, a2 in bc.items():
    def comp(pv):
        async def infract_generic(ctx: Context, gs_service: str, gs_id: str, duration_v: int, duration_u: Optional[str], *, reason: str):
            adm = await get_gfl_admin(ctx.bot.app, ctx.author)

            if not await checkaccess(ctx, adm=adm, access=(PERMISSION_CREATE_INFRACTION | PERMISSION_SCOPE_GLOBAL | pv[1])):
                return

            if not duration_u:
                duration_u = 'm'

            if duration_u not in units:
                await ctx.reply(content=f'I do not know what the unit \'{duration_u}\' means. Please use s, m, h, d, w, mo, or y.')
                return

            duration = duration_v * units[duration_u]

            try:
                gs_id = await normalize_id(ctx.bot.app, gs_service, gs_id)
            except ValueError:
                return await ctx.reply(content=f'I couldn\'t use the ID {gs_service}/{gs_id}. Please verify that the ID is correct.')

            # setup dcl call
            # dcl_infract(app, caller: int, gs_service: str, gs_id: str, punishments: List[str], duration: int, reason: str)
            await generate_confirmation_link(ctx, adm.ips_id, 'infract', [gs_service, gs_id, list(pv[0]), duration, reason])

        return infract_generic

    ig = comp(a2)
    bot.command(name=a1)(ig)

def start_bot(api2disc, disc2api):
    app = DiscordApp()
    configure_app(app)
    setattr(bot, 'app', app)

    bot.run(DISCORD_BOT_TOKEN)
    bot.api2disc = api2disc
    bot.disc2api = disc2api


import sys

sys.path.append('__modules')
from Customize_me import *
from config import Config
from get_tests import Build
from parse_arg import Parse_arg
from run_tests import Run
from output import Output

class Task():
  """
    Design pattern command. Will manage every task
    of the test_suit. You can add as many tasks as
    you want. You can then run them by calling the
    Task object
  """

  def __init__(self):
    """
      Init an empty task list
    """
    self.tasks = []

  def add(self, task):
    """
      Add a task in the task list
    """
    self.tasks.append(task)

  def __call__(self):
    """
      Run the tasks one by one
    """
    result = {}
  #  try:
    for task in self.tasks:
      result = task(result)
  #  except Exception as e:
  #    print e
  #  finally:
    return result

def main():

  # Prolog
  logo_print()
  prelude()

  # Create the task manager
  task = Task()

  # Add tasks
  task.add(Config())
  task.add(Parse_arg())
  task.add(Build())
  task.add(Run())
  task.add(Output())

  # Launch tasks
  result = task()

  # Call the
  epilog()

if __name__ == '__main__':
  main()


import math
import random
import functools
import operator

import torch
from torch import nn
from torch.nn import functional as F
from torch.autograd import Function

from op import FusedLeakyReLU, fused_leaky_relu, upfirdn2d, conv2d_gradfix

class PixelNorm(nn.Module):
    def __init__(self):
        super().__init__()

    def forward(self, input):
        return input * torch.rsqrt(torch.mean(input ** 2, dim=1, keepdim=True) + 1e-8)

def make_kernel(k):
    k = torch.tensor(k, dtype=torch.float32)

    if k.ndim == 1:
        k = k[None, :] * k[:, None]

    k /= k.sum()

    return k

class Upsample(nn.Module):
    def __init__(self, kernel, factor=2):
        super().__init__()

        self.factor = factor
        kernel = make_kernel(kernel) * (factor ** 2)
        self.register_buffer("kernel", kernel)

        p = kernel.shape[0] - factor

        pad0 = (p + 1) // 2 + factor - 1
        pad1 = p // 2

        self.pad = (pad0, pad1)

    def forward(self, input):
        out = upfirdn2d(input, self.kernel, up=self.factor, down=1, pad=self.pad)

        return out

class Downsample(nn.Module):
    def __init__(self, kernel, factor=2):
        super().__init__()

        self.factor = factor
        kernel = make_kernel(kernel)
        self.register_buffer("kernel", kernel)

        p = kernel.shape[0] - factor

        pad0 = (p + 1) // 2
        pad1 = p // 2

        self.pad = (pad0, pad1)

    def forward(self, input):
        out = upfirdn2d(input, self.kernel, up=1, down=self.factor, pad=self.pad)

        return out

class Blur(nn.Module):
    def __init__(self, kernel, pad, upsample_factor=1):
        super().__init__()

        kernel = make_kernel(kernel)

        if upsample_factor > 1:
            kernel = kernel * (upsample_factor ** 2)

        self.register_buffer("kernel", kernel)

        self.pad = pad

    def forward(self, input):
        out = upfirdn2d(input, self.kernel, pad=self.pad)

        return out

class EqualConv2d(nn.Module):
    def __init__(
        self, in_channel, out_channel, kernel_size, stride=1, padding=0, bias=True
    ):
        super().__init__()

        self.weight = nn.Parameter(
            torch.randn(out_channel, in_channel, kernel_size, kernel_size)
        )
        self.scale = 1 / math.sqrt(in_channel * kernel_size ** 2)

        self.stride = stride
        self.padding = padding

        if bias:
            self.bias = nn.Parameter(torch.zeros(out_channel))

        else:
            self.bias = None

    def forward(self, input):
        out = conv2d_gradfix.conv2d(
            input,
            self.weight * self.scale,
            bias=self.bias,
            stride=self.stride,
            padding=self.padding,
        )

        return out

    def __repr__(self):
        return (
            f"{self.__class__.__name__}({self.weight.shape[1]}, {self.weight.shape[0]},"
            f" {self.weight.shape[2]}, stride={self.stride}, padding={self.padding})"
        )

class EqualLinear(nn.Module):
    def __init__(
        self, in_dim, out_dim, bias=True, bias_init=0, lr_mul=1, activation=None
    ):
        super().__init__()

        self.weight = nn.Parameter(torch.randn(out_dim, in_dim).div_(lr_mul))

        if bias:
            self.bias = nn.Parameter(torch.zeros(out_dim).fill_(bias_init))

        else:
            self.bias = None

        self.activation = activation

        self.scale = (1 / math.sqrt(in_dim)) * lr_mul
        self.lr_mul = lr_mul

    def forward(self, input):
        if self.activation:
            out = F.linear(input, self.weight * self.scale)
            out = fused_leaky_relu(out, self.bias * self.lr_mul)

        else:
            out = F.linear(
                input, self.weight * self.scale, bias=self.bias * self.lr_mul
            )

        return out

    def __repr__(self):
        return (
            f"{self.__class__.__name__}({self.weight.shape[1]}, {self.weight.shape[0]})"
        )

class ModulatedConv2d(nn.Module):
    def __init__(
        self,
        in_channel,
        out_channel,
        kernel_size,
        style_dim,
        demodulate=True,
        upsample=False,
        downsample=False,
        blur_kernel=[1, 3, 3, 1],
        fused=True,
    ):
        super().__init__()

        self.eps = 1e-8
        self.kernel_size = kernel_size
        self.in_channel = in_channel
        self.out_channel = out_channel
        self.upsample = upsample
        self.downsample = downsample

        if upsample:
            factor = 2
            p = (len(blur_kernel) - factor) - (kernel_size - 1)
            pad0 = (p + 1) // 2 + factor - 1
            pad1 = p // 2 + 1

            self.blur = Blur(blur_kernel, pad=(pad0, pad1), upsample_factor=factor)

        if downsample:
            factor = 2
            p = (len(blur_kernel) - factor) + (kernel_size - 1)
            pad0 = (p + 1) // 2
            pad1 = p // 2

            self.blur = Blur(blur_kernel, pad=(pad0, pad1))

        fan_in = in_channel * kernel_size ** 2
        self.scale = 1 / math.sqrt(fan_in)
        self.padding = kernel_size // 2

        self.weight = nn.Parameter(
            torch.randn(1, out_channel, in_channel, kernel_size, kernel_size)
        )

        self.modulation = EqualLinear(style_dim, in_channel, bias_init=1)

        self.demodulate = demodulate
        self.fused = fused

    def __repr__(self):
        return (
            f"{self.__class__.__name__}({self.in_channel}, {self.out_channel}, {self.kernel_size}, "
            f"upsample={self.upsample}, downsample={self.downsample})"
        )

    def forward(self, input, style):
        batch, in_channel, height, width = input.shape

        if not self.fused:
            weight = self.scale * self.weight.squeeze(0)
            style = self.modulation(style)

            if self.demodulate:
                w = weight.unsqueeze(0) * style.view(batch, 1, in_channel, 1, 1)
                dcoefs = (w.square().sum((2, 3, 4)) + 1e-8).rsqrt()

            input = input * style.reshape(batch, in_channel, 1, 1)

            if self.upsample:
                weight = weight.transpose(0, 1)
                out = conv2d_gradfix.conv_transpose2d(
                    input, weight, padding=0, stride=2
                )
                out = self.blur(out)

            elif self.downsample:
                input = self.blur(input)
                out = conv2d_gradfix.conv2d(input, weight, padding=0, stride=2)

            else:
                out = conv2d_gradfix.conv2d(input, weight, padding=self.padding)

            if self.demodulate:
                out = out * dcoefs.view(batch, -1, 1, 1)

            return out

        # print(style.size())

        style = self.modulation(style).view(batch, 1, in_channel, 1, 1)
        weight = self.scale * self.weight * style

        if self.demodulate:
            demod = torch.rsqrt(weight.pow(2).sum([2, 3, 4]) + 1e-8)
            weight = weight * demod.view(batch, self.out_channel, 1, 1, 1)

        weight = weight.view(
            batch * self.out_channel, in_channel, self.kernel_size, self.kernel_size
        )

        if self.upsample:
            input = input.view(1, batch * in_channel, height, width)
            weight = weight.view(
                batch, self.out_channel, in_channel, self.kernel_size, self.kernel_size
            )
            weight = weight.transpose(1, 2).reshape(
                batch * in_channel, self.out_channel, self.kernel_size, self.kernel_size
            )
            out = conv2d_gradfix.conv_transpose2d(
                input, weight, padding=0, stride=2, groups=batch
            )
            _, _, height, width = out.shape
            out = out.view(batch, self.out_channel, height, width)
            out = self.blur(out)

        elif self.downsample:
            input = self.blur(input)
            _, _, height, width = input.shape
            input = input.view(1, batch * in_channel, height, width)
            out = conv2d_gradfix.conv2d(
                input, weight, padding=0, stride=2, groups=batch
            )
            _, _, height, width = out.shape
            out = out.view(batch, self.out_channel, height, width)

        else:
            input = input.view(1, batch * in_channel, height, width)
            out = conv2d_gradfix.conv2d(
                input, weight, padding=self.padding, groups=batch
            )
            _, _, height, width = out.shape
            out = out.view(batch, self.out_channel, height, width)

        return out

class NoiseInjection(nn.Module):
    def __init__(self):
        super().__init__()

        self.weight = nn.Parameter(torch.zeros(1))

    def forward(self, image, noise=None):
        if noise is None:
            batch, _, height, width = image.shape
            noise = image.new_empty(batch, 1, height, width).normal_()

        return image + self.weight * noise

class ConstantInput(nn.Module):
    def __init__(self, channel, size=4):
        super().__init__()

        self.input = nn.Parameter(torch.randn(1, channel, size, size))

    def forward(self, input):
        batch = input.shape[0]
        # print(batch)
        out = self.input.repeat(batch, 1, 1, 1)

        return out

class StyledConv(nn.Module):
    def __init__(
        self,
        in_channel,
        out_channel,
        kernel_size,
        style_dim,
        upsample=False,
        blur_kernel=[1, 3, 3, 1],
        demodulate=True,
    ):
        super().__init__()

        self.conv = ModulatedConv2d(
            in_channel,
            out_channel,
            kernel_size,
            style_dim,
            upsample=upsample,
            blur_kernel=blur_kernel,
            demodulate=demodulate,
        )

        self.noise = NoiseInjection()
        # self.bias = nn.Parameter(torch.zeros(1, out_channel, 1, 1))
        # self.activate = ScaledLeakyReLU(0.2)
        self.activate = FusedLeakyReLU(out_channel)

    def forward(self, input, style, mask = None, noise=None):
        # print('jfnksdjfdkjfkjsf')
        # print(style.size())
        out = self.conv(input, style)
        # print(out.size())
        out = self.noise(out, noise=noise)
        # out = out + self.bias
        out = self.activate(out)

        # print(out.size(), 'point22')

        if mask is not None:
          # print(mask.size(), 'mask size orig')
          bs, c, h, w = out.size()
          # print(w,h)
          # print(out.size(), 'out size in layer')
          mask = F.interpolate(mask, size = (h,w), mode = 'nearest')
          # print(mask.size(), 'mask_size dfksfkdskfksdkfs')
          mask = mask.repeat(1, c, 1,1)
          # print(mask.size(), 'mask size after unsqueeze')
          out = out*mask

        # print(out.size())

        return out

class ToRGB(nn.Module):
    def __init__(self, in_channel, style_dim, upsample=True, blur_kernel=[1, 3, 3, 1]):
        super().__init__()

        if upsample:
            self.upsample = Upsample(blur_kernel)

        self.conv = ModulatedConv2d(in_channel, 3, 1, style_dim, demodulate=False)
        self.bias = nn.Parameter(torch.zeros(1, 3, 1, 1))

    def forward(self, input, style, mask = None,  skip=None):

        out = self.conv(input, style)
        out = out + self.bias

        if skip is not None:
            skip = self.upsample(skip)

            out = out + skip
        # print(out.size())

        if mask is not None:
          bs, c, h, w = out.size()
          # print(h, w)
          mask = F.interpolate(mask, [h,w], mode = 'nearest')

          mask = mask.repeat(1, c, 1,1)
          # print(mask.size())
          out = out*mask

        return out

class Generator(nn.Module):
    def __init__(
        self,
        size,
        style_dim,
        n_mlp,
        channel_multiplier=2,
        blur_kernel=[1, 3, 3, 1],
        lr_mlp=0.01,
    ):
        super().__init__()

        self.size = size

        self.style_dim = style_dim

        self.feature_extractor = FeatureExtractor(size)
        layers = nn.ModuleList()
        layers.append(PixelNorm())
        # layers = [PixelNorm()]

        layers.append(
            EqualLinear(
                    style_dim+3, style_dim, lr_mul=lr_mlp, activation="fused_lrelu"
                ))

        for i in range(n_mlp-1):
            layers.append(
                EqualLinear(
                    style_dim, style_dim, lr_mul=lr_mlp, activation="fused_lrelu"
                )
            )

        self.style = nn.Sequential(*layers)

        self.channels = {
            4: 512,
            8: 512,
            16: 512,
            32: 512,
            64: 256 * channel_multiplier,
            128: 128 * channel_multiplier,
            256: 64 * channel_multiplier,
            512: 32 * channel_multiplier,
            1024: 16 * channel_multiplier,
        }

        self.input = ConstantInput(self.channels[4])
        self.conv1 = StyledConv(
            self.channels[4], self.channels[4], 3, style_dim, blur_kernel=blur_kernel
        )
        self.to_rgb1 = ToRGB(self.channels[4], style_dim, upsample=False)

        self.log_size = int(math.log(size, 2))
        self.num_layers = (self.log_size - 2) * 2 + 1

        self.convs = nn.ModuleList()
        self.upsamples = nn.ModuleList()
        self.to_rgbs = nn.ModuleList()
        self.noises = nn.Module()

        in_channel = self.channels[4]

        for layer_idx in range(self.num_layers):
            res = (layer_idx + 5) // 2
            shape = [1, 1, 2 ** res, 2 ** res]
            self.noises.register_buffer(f"noise_{layer_idx}", torch.randn(*shape))

        for i in range(3, self.log_size + 1):
            out_channel = self.channels[2 ** i]

            if i%2==0:
              in_channel1 = in_channel*2
            else:
              in_channel1 = in_channel #----------------------------------------hbhjbbhjbhjbb

            self.convs.append(
                StyledConv(
                    in_channel1,
                    out_channel,
                    3,
                    style_dim,
                    upsample=True,
                    blur_kernel=blur_kernel,
                )
            )

            self.convs.append(
                StyledConv(
                    out_channel, out_channel, 3, style_dim, blur_kernel=blur_kernel
                )
            )

            self.to_rgbs.append(ToRGB(out_channel, style_dim))

            in_channel = out_channel

        self.n_latent = self.log_size * 2 - 2

    def forward(
        self,
        styles,
        mask,
        target_img,
        return_latents=False,
        inject_index=None,
        truncation=1,
        truncation_latent=None,
        input_is_latent=False,
        noise=None,
        randomize_noise=False,
    ):

        # print(styles.size())
        # print(target_img.size(), 'here is the size of the tgt')

        target_features = self.feature_extractor(target_img)#.reverse()
        # target_features.reverse()

        # print(target_features)

        if not input_is_latent:
            styles = self.style(styles) #[self.style(s) for s in styles]

        # if not input_is_latent:
        # styles = [self.style(s) for s in styles]
        # print(styles.size(), 'latent_sizeggggg')

        if noise is None:
            if randomize_noise:
                noise = [None] * self.num_layers
            else:
                noise = [
                    getattr(self.noises, f"noise_{i}") for i in range(self.num_layers)
                ]

        latent = styles.unsqueeze(1).repeat(1,self.num_layers,1)

        # print(latent.size(), 'latent_sizeggggg')

        out = self.input(latent)

        out = self.conv1(out, latent[:, 0], noise=None)

        skip = self.to_rgb1(out, latent[:, 1])

        i = 1

        for conv1, noise1 in zip(
            self.convs, noise
        ):
              if (i+1)%4==0:
                feat = target_features[i//2]
                out = torch.cat((out, feat), dim = 1)

              out = conv1(out, latent[:, i], mask = mask, noise=None)

              i+=1

        out =  self.to_rgbs[-1](out, latent[:, 0])

        return out

class ConvLayer(nn.Sequential):
    def __init__(
        self,
        in_channel,
        out_channel,
        kernel_size,
        downsample=False,
        blur_kernel=[1, 3, 3, 1],
        bias=True,
        activate=True,
    ):
        layers = nn.ModuleList()

        if downsample:
            factor = 2
            p = (len(blur_kernel) - factor) + (kernel_size - 1)
            pad0 = (p + 1) // 2
            pad1 = p // 2

            layers.append(Blur(blur_kernel, pad=(pad0, pad1)))

            stride = 2
            self.padding = 0

        else:
            stride = 1
            self.padding = kernel_size // 2

        layers.append(
            EqualConv2d(
                in_channel,
                out_channel,
                kernel_size,
                padding=self.padding,
                stride=stride,
                bias=bias and not activate,
            )
        )

        if activate:
            layers.append(FusedLeakyReLU(out_channel, bias=bias))

        super().__init__(*layers)

class ResBlock(nn.Module):
    def __init__(self, in_channel, out_channel, blur_kernel=[1, 3, 3, 1]):
        super().__init__()

        self.conv1 = ConvLayer(in_channel, in_channel, 3)
        self.conv2 = ConvLayer(in_channel, out_channel, 3, downsample=True)

        self.skip = ConvLayer(
            in_channel, out_channel, 1, downsample=True, activate=False, bias=False
        )

    def forward(self, input):
        out = self.conv1(input)
        out = self.conv2(out)

        skip = self.skip(input)
        out = (out + skip) / math.sqrt(2)

        return out

class FeatureExtractor(nn.Module):
    def __init__(self, size, channel_multiplier=2, blur_kernel=[1, 3, 3, 1]):
        super().__init__()

        channels = {
            4: 512,
            8: 512,
            16: 512,
            32: 512,
            64: 256 * channel_multiplier,
            128: 128 * channel_multiplier,
            256: 64 * channel_multiplier,
            512: 32 * channel_multiplier,
            1024: 16 * channel_multiplier,
        }

        convs = nn.ModuleList()
        convs.append(ConvLayer(3, channels[size], 1))

        log_size = int(math.log(size, 2))

        in_channel = channels[size]

        for i in range(log_size, 2, -1):
            out_channel = channels[2 ** (i - 1)]

            convs.append(ResBlock(in_channel, out_channel, blur_kernel))

            in_channel = out_channel

        self.convs = convs #nn.Sequential(*convs)

    def forward(self, out):
        out_l = nn.ModuleList()
        for cn in self.convs:
          out = cn(out)
          out_l.insert(0,out)

        return out_l #, out_l

if __name__=="__main__":
    g = Generator(256, 512, 4).to('cuda')
    o = torch.ones((3,512)).to('cuda')
    tgt = torch.ones((3, 3, 256, 256)).to('cuda')
    mask = torch.ones((3,1,256,256)).to('cuda')
    im = g(o, mask, tgt)
    print(im.size(), im.device)


"""
Created on Wed Dec 19 09:19:45 2018

@author: Will
"""
#libraries
import matplotlib.pyplot as plt
import numpy
import pandas as pd
import numpy as np
from sklearn.preprocessing import OneHotEncoder, LabelEncoder
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split

#open first half
X = np.load('dna_cleaner.npy')
y = np.load('dna_clean_labels.npy')
np.where(y==2)
X = X[:1535]
y = y[:1535]
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25, random_state=0)
num_inputs = X.shape[0]
input_size = X.shape[1]

def initialize_parameters(input_size):
    weights = np.zeros(input_size,)
    bias = np.zeros(1)
    return (weights, bias)

weights, bias = initialize_parameters(input_size)

""" Forward propagartion """

def sigmoid(z): #creating the S shaped curve.
    s = 1/(1+np.exp(-z))
    return s

x_sigmoid = np.arange(-5, 5, .1)
y_sigmoid = sigmoid(x_sigmoid)

#plt.plot(x_sigmoid,y_sigmoid)
#plt.title('Sigmoid Function')
#plt.show()
#print(output)
#y_prediction = np.rint(output).astype(int)
#print(y_prediction)
#loss = -(y_train[0] * np.log(output) + (1-y_train[0])*np.log(1-output))
learning_rate = 0.001
#weights[0] = weights[0] + learning_rate * loss * X_train[0][0]
weights, bias = initialize_parameters(input_size)
outputs = sigmoid(np.dot(weights,X_train.T) + bias)
y_prediction = np.rint(outputs).astype(int) # this forces either 0 or 1

""" Backward Propagation """

cost = (-1/num_inputs) * np.sum(y_train*np.log(outputs) + (1-y_train)*np.log(1-outputs))
dw = (1/num_inputs) * np.dot(X_train.T, (outputs-y_train).T)
db = (1/num_inputs) * np.sum(outputs-y_train)
assert weights.shape == dw.shape
weights = weights - learning_rate * dw
bias = bias - learning_rate * db

""" Building model """

def model(X_train, y_train, epochs=500, learning_rate=0.1):

    num_inputs = len(X_train)

    # Create an empty array to store predictions
    y_prediction = np.empty(num_inputs)

    weights, bias = initialize_parameters(input_size)

    for i in range(epochs):

        # Now we calculate the output
        # We're doing this for all images at the same time
        image_sums = np.dot(weights, X_train.T) + bias
        # Now we have to run each output through our activation function, then convert it to a prediction
        outputs = sigmoid(image_sums)
        # Now we have to convert the outputs to predictions
        # round it to an int
        y_prediction = np.rint(outputs).astype(int)  # this forces either 0 or 1

        # Find weight and bias changes
        dw = (1/num_inputs) * np.dot(X_train.T, (outputs-y_train).T)
        dw = np.squeeze(dw)
        db = (1/num_inputs) * np.sum(outputs-y_train)
        # Update the parameters
        # Make sure the matrices are the same size
        assert weights.shape == dw.shape
        weights = weights - learning_rate * dw
        bias = bias - learning_rate * db

    parameters = {"weights": weights,
                  "bias": bias,
                  "train_predictions": y_prediction,
                  }

    return parameters

"""Test"""

results = model(X_train, y_train, epochs=300)
final_weights = results['weights']
final_bias = results['bias']
final_sums = np.dot(final_weights, X_test.T) + final_bias
final_outputs = sigmoid(final_sums)
test_predictions = np.rint(final_outputs).astype(int)
train_predictions = results['train_predictions']
print("Accuracy on training set: {:.2%}".format(1-np.mean(np.abs(train_predictions - y_train))))
print("Accuracy on testing set: {:.2%}".format(1-np.mean(np.abs(test_predictions - y_test))))


from game.level import Tile, get_available_directions, is_wall
from game.util import rate_limit, ALL_DIRECTIONS, Direction
from typing import List
import math
from math import floor
import abc

# base class for object that moves around a maze
class Mover:
    __metaclass__ = abc.ABCMeta

    def __init__(self, x, y, speed):
        self.x = x
        self.y = y
        # last block
        self.last_x = x
        self.last_y = y
        self.start_x = x
        self.start_y = y
        self.direction = Direction.RIGHT
        self.last_direction = Direction.RIGHT  # more recent non None direction
        self.speed = speed

    # as a property to enforce overriding
    @property
    @abc.abstractmethod
    def cornercut(cls) -> float:
        pass

    def step(self, dt, level_map: List[List[Tile]]):
        # keep track of the last tile we were on
        # if about to move to a new tile set last to current
        if floor(self.x + self.direction.value[0]*dt*self.speed) != floor(self.x):
            self.last_x = floor(self.x)
        if floor(self.y + self.direction.value[1]*dt*self.speed) != floor(self.y):
            self.last_y = floor(self.y)

        self.x += self.direction.value[0] * dt * self.speed
        self.y += self.direction.value[1] * dt * self.speed

        # snap to grid
        if abs(self.direction.value[0]) == 0:
            self.x = rate_limit(self.x, math.floor(self.x) + 0.5, self.speed * dt)

        if abs(self.direction.value[1]) == 0:
            self.y = rate_limit(self.y, math.floor(self.y) + 0.5, self.speed * dt)

        avalible_directions = get_available_directions(level_map, (self.x, self.y))
        if self.direction not in avalible_directions:
            self.direction = Direction.NONE

        new_dir = self.check_new_direction(level_map)
        if (
            new_dir in avalible_directions
            and abs(self.x % 1 - 0.5) < self.cornercut
            and abs(self.y % 1 - 0.5) < self.cornercut
        ):
            self.direction = new_dir

        if not self.direction is None:
            self.last_direction = self.direction

        # looping
        self.x = self.x % len(level_map[0])
        self.y = self.y % len(level_map)

    def check_collisions(self, other: "Mover"):
        return (
            self.x + 0.75 > other.x + 0.25
            and self.x + 0.25 < other.x + 0.75
            and self.y + 0.75 > other.y + 0.25
            and self.y + 0.25 < other.y + 0.75
        )

    def euc_dist(self, other: 'Mover'):
        """Returns the euclidean distance to another Mover"""
        return math.hypot(self.x-other.x, self.y-other.y)

    def man_dist(self, other: 'Mover'):
        """Returns the manhattan distance to another Mover"""
        return abs(self.x-other.x) + abs(self.y-other.y)

    def reset(self):
        self.x = self.start_x
        self.y = self.start_y
        self.direction = Direction.NONE

    # to be implimented by sub classes
    @abc.abstractmethod
    def check_new_direction(self, _) -> Direction:
        raise NotImplementedError

    @abc.abstractmethod
    def draw(self, screen, offset, grid_size):
        raise NotImplementedError


# coding: utf-8

from __future__ import absolute_import

from flask import json
from six import BytesIO

from swagger_server.models.matter_properties import MatterProperties  # noqa: E501
from swagger_server.models.matter_response import MatterResponse  # noqa: E501
from swagger_server.test import BaseTestCase

class TestFSMController(BaseTestCase):
    """FSMController integration test stubs"""

    def test_add_matter(self):
        """Test case for add_matter

        Add a new State Machine to the pool
        """
        body = MatterProperties()
        response = self.client.open(
            '/v1/matter',
            method='POST',
            data=json.dumps(body),
            content_type='application/json')
        self.assert200(response,
                       'Response body is : ' + response.data.decode('utf-8'))

    def test_get_by_id(self):
        """Test case for get_by_id

        Info for a specific Matter object
        """
        response = self.client.open(
            '/v1/matter/{Id}'.format(id=1.2),
            method='GET')
        self.assert200(response,
                       'Response body is : ' + response.data.decode('utf-8'))

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


#!/usr/bin/env python3

from typing import Any, Dict, Optional, Set

import pytorch_lightning as pl
import torch
from datasets import Dataset, DatasetDict, load_dataset
from torch.utils.data import DataLoader, WeightedRandomSampler
from transformers import AutoTokenizer

class RegionHallandDataModule(pl.LightningDataModule):
    def __init__(
        self,
        # dataset_path: str,
        tokenizer_name: str,
        max_sequence_length: int,
        batch_size: int,
        seed: int,
        val_is_test: bool = True,
        train_data_path: str = "data/rh_train.csv",
        test_data_path: str = "data/rh_test.csv",
    ):
        super().__init__()
        # self.dataset_path = dataset_path # TODO
        self.tokenizer_name = tokenizer_name
        self.max_sequence_length = max_sequence_length
        self.batch_size = batch_size
        self.seed = seed
        self.val_is_test = val_is_test
        self.train_data_path = train_data_path
        self.test_data_path = test_data_path

        self.data_loader_cache: Dict[str, DataLoader] = dict()
        self.dataset: Dataset
        self.destroyed_indices: Set[int] = set()

    def get_destroyed_labels(self):
        return []

    def prepare_data(self):
        """Download files to cache first once per node."""
        AutoTokenizer.from_pretrained(self.tokenizer_name, use_fast=True)
        split = self.get_train_test_split()
        load_dataset(
            "csv",
            split=split,
            data_files={
                'train': [self.train_data_path],
                'test': [self.test_data_path],
            },
        )

    def get_train_test_split(self):
        """Return train test split for HF datasets."""
        split = {"train": "train", "test": "test"}
        return split

    def get_and_process_dataset(self):
        tokenizer = AutoTokenizer.from_pretrained(
            self.tokenizer_name, use_fast=True
        )

        # tokenize the dataset
        def preprocess(example: Dict[str, Any], idx: int) -> Dict[str, Any]:
            encoding = tokenizer(
                example["text"],
                max_length=self.max_sequence_length,
                truncation=True,
                padding="max_length",
                return_attention_mask=True,
                return_token_type_ids=True,
            )
            encoding.update({"idx": idx})
            return encoding

        dataset: DatasetDict = DatasetDict()
        split = self.get_train_test_split()

        dataset = load_dataset(
            "csv",
            split=split,
            data_files={
                'train': [self.train_data_path],
                'test': [self.test_data_path],
            },
        )

        return dataset.map(preprocess, batched=True, with_indices=True)

    def setup(self):
        dataset = self.get_and_process_dataset()
        dataset.set_format(
            type="torch",
            columns=[
                "input_ids",
                "token_type_ids",
                "attention_mask",
                "label",
                "idx",  # To find destroyed labels
            ],
        )
        self.dataset = dataset.shuffle(seed=self.seed)

    def _create_dataloader(
        self,
        dataset_partitions: Dataset,
        split: str,
        batch_size: int,
    ):
        if split == "validation" and self.val_is_test:
            split = "test"

        dataset = dataset_partitions[split]

        # Get frequency of the labels and convert to weights
        targets = dataset['label'].type(torch.long) # index needs to be long, byte or bool (byte == uint8, long==int64)
        class_freq = torch.bincount(targets)
        class_weights = 1. / class_freq
        class_weights_all = class_weights[targets]

        sampler = WeightedRandomSampler(
            weights=class_weights_all,
            num_samples=len(class_weights_all),
            replacement=True
        )

        return DataLoader(
            dataset,
            batch_size=batch_size,
            # shuffle=False,
            num_workers=4,
            sampler=sampler,
        )

    def train_dataloader(self):
        self.data_loader_cache["train"] = self._create_dataloader(
            self.dataset, split="train", batch_size=self.batch_size
        )
        return self.data_loader_cache["train"]

    def val_dataloader(self):
        self.data_loader_cache["validation"] = self._create_dataloader(
            self.dataset, split="validation", batch_size=self.batch_size
        )
        return self.data_loader_cache["validation"]

    def test_dataloader(self):
        self.data_loader_cache["test"] = self._create_dataloader(
            self.dataset, split="test", batch_size=self.batch_size
        )
        return self.data_loader_cache["test"]


import numpy as np
from sklearn import datasets
from sklearn.metrics import f1_score
from sklearn.model_selection import train_test_split
from graphviz import Digraph

# 计算连续型数据的基尼系数
def min_gini(labels, attributes):
    centrals = []
    new_list = []
    label_set = np.unique(labels)
    for i in range(len(labels)):
        new_list.append((labels[i], attributes[i]))
    sort_list = np.copy(attributes)
    sort_list.sort()
    for i in range(len(attributes) - 1):
        centrals.append((sort_list[i] + sort_list[i + 1]) / 2)
    split_num = 0
    min_gini_num = None
    for num in centrals:
        left = []
        right = []
        for i in range(len(new_list)):
            if new_list[i][1] <= num:
                left.append(new_list[i][0])
            else:
                right.append(new_list[i][0])
        left_gini = 1
        right_gini = 1
        for label in label_set:
            if len(left) != 0:
                left_gini -= (left.count(label) / len(left)) ** 2
            if len(right) != 0:
                right_gini -= (right.count(label) / len(right)) ** 2
        gini_now = left_gini * len(left) / len(attributes) + right_gini * len(right) / len(attributes)
        if min_gini_num is None or min_gini_num > gini_now:
            min_gini_num = gini_now
            split_num = num
    return min_gini_num, split_num

class TreeNode:
    def __init__(self, attributes, labels):
        self.is_leaf = False
        self.attributes = attributes
        # 判断是否停止迭代
        if len(set(labels)) == 1:
            self.label = labels[0]
            self.is_leaf = True
        else:
            properties = []
            for i in range(attributes.shape[1]):
                gini_num, split_num = min_gini(labels, attributes[:, i])
                properties.append((i, gini_num, split_num))
            # 获取二元离散分类点
            index = np.argmin(list(map(lambda x: x[1], properties)))
            self.prop = properties[index][0]
            self.gini = properties[index][1]
            self.split_num = properties[index][2]
            left_attr = []
            left_labels = []
            right_attr = []
            right_labels = []
            for i in range(len(attributes)):
                if attributes[i][self.prop] <= self.split_num:
                    left_attr.append(attributes[i])
                    left_labels.append(labels[i])
                else:
                    right_attr.append(attributes[i])
                    right_labels.append(labels[i])
            # 递归方式生成决策树
            self.left_node = TreeNode(np.array(left_attr), left_labels)
            self.right_node = TreeNode(np.array(right_attr), right_labels)

    # 决策树绘制部分
    def add_node(self, graph, labels, class_names):

        graph.node(str(self.__hash__()), self.describe(labels, class_names), shape='box',
                   style="filled" if self.is_leaf else None, color="#CC59CC" if self.is_leaf else None,
                   fontcolor="white" if self.is_leaf else "black")
        if not self.is_leaf:
            self.left_node.add_node(graph, labels, class_names)
            self.right_node.add_node(graph, labels, class_names)
            graph.edge(str(self.__hash__()), str(self.left_node.__hash__()))
            graph.edge(str(self.__hash__()), str(self.right_node.__hash__()))

    # 添加可视化标签
    def describe(self, labels, class_names):
        description = ''
        if self.is_leaf:
            description += 'class = ' + class_names[self.label] + '\n'
        else:
            description += labels[self.prop] + ' <= ' + str(round(self.split_num, 4)) + '\n'
        description += 'samples = ' + str(len(self.attributes))
        return description

    # 计算样本结果
    def calculate_result(self, vector):
        if self.is_leaf:
            return self.label
        else:
            if vector[self.prop] <= self.split_num:
                return self.left_node.calculate_result(vector)
            else:
                return self.right_node.calculate_result(vector)

if __name__ == '__main__':
    # 获取Iris数据集
    iris = datasets.load_iris()
    labels_name = iris.feature_names
    target_name = iris.target_names
    # 获取训练集与测试集
    x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target, test_size=0.2)
    # 生成决策树
    root = TreeNode(np.array(x_train), y_train)
    # 计算Micro-F1和Macro-F1
    results = list(map(lambda x: root.calculate_result(x), x_test))
    micro_f1 = f1_score(y_test, results, average="micro")
    macro_f1 = f1_score(y_test, results, average="macro")
    print("Cart Tree Results:")
    print("Micro-F1 Score: " + str(micro_f1))
    print("Macro-F1 Score: " + str(macro_f1))
    print()
    # 绘制决策树
    g = Digraph('G', filename='decision_tree.gv', format='png')
    root.add_node(g, labels_name, target_name)
    g.view(filename="cart")
    # Random Forest Optimizing
    forests = []
    # 以10棵树为例
    k = 10
    # 抽取训练集样本以生成树
    for _ in range(k):
        x_samples, _, y_samples, _ = train_test_split(x_train, y_train, test_size=0.3)
        forests.append(TreeNode(np.array(x_samples), y_samples))
    random_forest_result = []
    # 计算Random Forest的结果
    for tree in forests:
        random_forest_result.append(list(map((lambda x: tree.calculate_result(x)), x_test)))
    random_forest_result = np.array(random_forest_result).T
    voting_result = []
    for line in random_forest_result:
        voting_result.append(np.argmax(np.bincount(line)))
    micro_f1 = f1_score(y_test, voting_result, average="micro")
    macro_f1 = f1_score(y_test, voting_result, average="macro")
    print("Random Forest Results:")
    print("Micro-F1 Score: " + str(micro_f1))
    print("Macro-F1 Score: " + str(macro_f1))


import json
import time
from pathlib import Path

import typer
from tqdm import tqdm

from back.crud.async_tag import CrudTag
from back.db.crud import CrudTagAttribute, CrudTagToken
from back.db.model import TagAttributeCreate, TagTokenCreate
from back.model.tag import TagInsert
from lib.typer import ZetsuBouTyper

def load_json(fpath: Path):
    with fpath.open(mode="r") as fp:
        data = json.load(fp)
    return data

_help = """
Manipulate the tag.
"""
app = ZetsuBouTyper(name="tag", help=_help)

@app.command()
async def dump(
    out: str = typer.Argument(..., help="The repository for the output JSON files."),
    force: bool = typer.Option(default=False, help="Overwrite the output JSON files."),
):
    """
    Dump the tag into JSON file.
    """

    out = Path(out)
    if not out.is_dir():
        return

    tags_path = out / "tag.json"
    if not force and tags_path.exists():
        return

    attrs_path = out / "attribute.json"
    if not force and attrs_path.exists():
        return

    async def get_attributes():
        print("get tag attributes ...")
        attrs = []
        skip = 0
        limit = 100
        rows = await CrudTagAttribute.get_rows_order_by_id(skip=skip, limit=limit)
        while rows:
            for row in tqdm(rows):
                attrs.append(row.model_dump())
            skip += limit
            rows = await CrudTagAttribute.get_rows_order_by_id(skip=skip, limit=limit)
        return attrs

    attrs = await get_attributes()
    with attrs_path.open(mode="w") as fp:
        json.dump(attrs, fp, indent=4, ensure_ascii=False)

    async def get_tags():
        print("get tags ...")
        crud = CrudTag()
        tags = []
        skip = 0
        limit = 100
        rows = await CrudTagToken.get_rows_order_by_id(skip=skip, limit=limit)
        while rows:
            for row in tqdm(rows):
                tag = await crud.get_interpretation_by_id(row.id)
                tags.append(tag.model_dump())
            skip += limit
            rows = await CrudTagToken.get_rows_order_by_id(skip=skip, limit=limit)
        return tags

    tags = await get_tags()
    with tags_path.open(mode="w") as fp:
        json.dump(tags, fp, indent=4, ensure_ascii=False)

@app.command()
async def load(
    attr: str = typer.Argument(..., help="The JSON file of the attributes."),
    tag: str = typer.Argument(..., help="The JSON file of the tags."),
):
    """
    Load the tag into JSON file.
    """

    async def is_ok():
        rows = await CrudTagToken.get_rows_order_by_id()
        if len(rows) > 0:
            return False
        return True

    async def insert_attr(attr_table, attr_data):
        print("insert tag attributes ...")
        for attr in tqdm(attr_data):
            name = attr["name"]
            row = await CrudTagAttribute.get_row_by_name(name)
            if row is None:
                row = await CrudTagAttribute.create(TagAttributeCreate(name=name))
            attr_table[name] = row.id

    async def insert_token(token_table, tag_data):
        print("insert tag tokens ...")
        for tag in tqdm(tag_data):
            id = tag["id"]
            name = tag["name"]
            row = await CrudTagToken.create(TagTokenCreate(name=name))
            token_table[id] = row.id

    def get_inserted_tag(token_table, attr_table, tag: dict):
        id = token_table[tag["id"]]
        name = tag["name"]
        category_ids = [token_table[c["id"]] for c in tag["categories"]]
        synonym_ids = [token_table[s["id"]] for s in tag["synonyms"]]
        attributes = {attr_table[a["name"]]: a["value"] for a in tag["attributes"]}

        return TagInsert(
            id=id,
            name=name,
            category_ids=category_ids,
            synonym_ids=synonym_ids,
            attributes=attributes,
        )

    async def insert_tag(crud: CrudTag, token_table, attr_table, tag_data):
        print("insert tags ...")
        for tag in tqdm(tag_data):
            inserted_tag = get_inserted_tag(token_table, attr_table, tag)
            await crud.insert(inserted_tag)

    attr = Path(attr)
    if not attr.exists():
        return

    tag = Path(tag)
    if not tag.exists():
        return

    ok = await is_ok()
    if not ok:
        print("TagToken table is not empty.")
        return

    attr_table = {}
    attr_data = load_json(attr)
    token_table = {}
    tag_data = load_json(tag)

    await insert_attr(attr_table, attr_data)
    print(f"tag attributes: {attr_table}")

    t1 = time.time()
    await insert_token(token_table, tag_data)
    t2 = time.time()
    crud = CrudTag()
    await insert_tag(crud, token_table, attr_table, tag_data)
    t3 = time.time()

    print(f"insert tag: {t2-t1} seconds")
    print(f"insert tag: {t3-t2} seconds")


#!/usr/bin/env python
#coding: utf-8
import os
import json
import sys
PY3K = sys.version_info[0] == 3
if not PY3K:
    import urllib2
    from urllib import urlencode
else:
    import urllib.request as urllib2
    from urllib.parse import urlencode
    raw_input = input
    _map = map
    map = lambda *a, **k: list(_map(*a, **k))
import locale
LOCALE = locale.getdefaultlocale()

HOSTKEY = None # HOSTKEY_ANCHOR

CFARG = {
    'user_auth': ("cloudflare_email", "cloudflare_pass"),
    'zone_set': ("zone_name", "subdomains", "resolve_to"),
    'zone_delete': ("zone_name",),
    'zone_list': (),
    'zone_lookup': ("zone_name",),
    'add_subdomain':("zone_name", "subdomains", "resolve_to"),
    'delete_subdomain': ("zone_name", "subdomains"),
    'ssl_verfication': ("zone",),
    'host_key_regen': (),
}
CFHOST_FILE = ".cfhost"

I18N = {
    "zone_list": "显示所有接入的域名",
    "zone_set": "接入域名",
    "zone_lookup": "显示DNS记录",
    "zone_delete": "删除接入的域名",
    "host_key_regen": "重新生成host key",
    "user_auth": "登录",
    "add_subdomain": "添加/修改DNS记录",
    "delete_subdomain": "删除DNS记录",
    "logout": "退出当前帐号",
    "ssl_verfication": "开通SSL",
    "zone_name": "根域名",
    "resolve_to": "源站地址",
    "subdomains": "子域名",
    "cloudflare_email": "邮箱",
    "cloudflare_pass": "密码",
    "zone": "根域名",
    "subdomain": "子域名",
    "Zone": "根域名",
    "User": "用户",
    "Subdomain": "子域名",
    "Resolve to": "源站地址",
    "Content": "内容",
    "Login as %s": "%s 已登录",
    "vetting": "审批中",
    "validating": "等待验证",
    "ready": "已启用",
    "none": "未知",
    "Select your action:": "选择所需的操作，输入数字：",
    "Missing required arg \"%s\". (act:%s)": "缺少参数 \"%s\". (act:%s)",
    "Login failed, msg: %s": "登录失败: %s",
    "Success! Please set CNAME record of %s to %s": "设置成功! 请将%s的CNAME记录设置为%s",
    "Domain %s has been removed from partner": "域名%s已取消接入",
    "%s (act: %s)": "报错: %s (act: %s) ",
    "Please enter your Cloudflare partner hostkey (https://partners.cloudflare.com/api-management)> ":
        "请输入 Cloudflare hostkey (https://partners.cloudflare.com/api-management)> ",
    "SSL status: %s": "SSL状态: %s",
    "Please login first. (uri: %s)": "请先登录. (uri: %s)",
    "Please login first. (act: %s)": "请先登录. (act: %s)",
    "No zone found matching %s. Please use zone_set first.": "账户中不存在域名%s, 请先添加域名",
    "SSL for domain %s has already been activated.": "域名%s已开通SSL, 无需操作",
    "??? %s": "喵喵喵？ %s",
    "Please set CNAME record of %s to %s and run this option again after record become effective":
        "请将%s的CNAME记录设置为%s, 然后在解析生效后再运行一次\"开通SSL\"",
    "Please create a file with the following content and run this option again after record become effective:":
        "请新建文件使下列URL能访问到指定的内容，然后再运行一次\"开通SSL\":",
    "Can't delete root record": "不能删除根域名",
    "Record %s is deleted": "DNS记录%s已删除",
    "Record %s is not found in zone %s": "记录%s不存在于域名%s中",
    "If you want to activate SSL, please set CNAME record of %s to %s and " \
        "run this \"ssl_verfication\" after record become effective":
            "如果需要启用SSL, 请将%s的CNAME记录设置为%s, 然后在解析生效后运行一次\"开通SSL\"",
    "Zone %s not exists or is not under user %s": "域名%s不存在，或者不属于用户%s",
    "Host key has been changed to %s": "Hostkey已更新为 %s",
}

def i18n(s):
    _ = I18N[s] if LOCALE[1] and LOCALE[1].lower() in ("utf-8", "cp936") and s in I18N else s
    if LOCALE[1].lower() == "cp936" and not PY3K: # windows with simplified Chinese locale
        return _.decode('utf-8').encode('gb18030')
    return _

def log(fmt, arg = (), level = "INFO"):
    if PY3K:
        if not (isinstance(arg, list) or isinstance(arg, tuple)):
            arg = (arg, )
        arg = tuple([a.decode('ascii') if isinstance(a, bytes) else a for a in arg])
    print("%-4s - %s" % (level, i18n(fmt) % arg))

def catch_err(func):
    def _(instance, j, *arg):
        if j['result'] == 'error':
            log("%s (act: %s)", (j['msg'].encode('utf-8'), j['request']['act'].encode('utf-8')), "ERR")
            return
        return func(instance, j, *arg)
    return _

class CF(object):
    def __init__(self):
        self.user_email = None
        self.user_key = None
        self.user_api_key = None
        if os.path.exists(CFHOST_FILE):
            r = open(CFHOST_FILE).read()
            _ = r.split(",")
            if len(_) != 3:
                try:
                    os.remove(CFHOST_FILE)
                except:
                    pass
            else:
                _ = map(lambda x:x.strip(), _)
                self.user_email, self.user_key, self.user_api_key = _
                log("Login as %s", self.user_email)

    def _hostapi(self, act, extra={}):
        if not self.user_key and act not in ("user_auth", "host_key_regen"):
            log("Please login first. (act: %s)", act, "ERR")
            return
        payload = {
            "act": act,
            "host_key": HOSTKEY,
        }
        if act not in ("user_auth", "host_key_regen"):
            payload.update({"user_key": self.user_key})
        if extra:
            payload.update(extra)
        if act in CFARG:
            for k in CFARG[act]:
                if k not in payload:
                    log("Missing required arg \"%s\". (act:%s)", (k, act), "ERR")
                    return
        if PY3K:
            payload = urlencode(payload).encode('ascii')
        else:
            payload = urlencode(payload)
        req  = urllib2.Request("https://api.cloudflare.com/host-gw.html", payload)
        r = urllib2.urlopen(req).read()
        if PY3K and isinstance(r, bytes):
            r = r.decode('ascii')
        return json.loads(r)

    def _userapi(self, uri, method="GET", extra={}):
        if not self.user_api_key:
            log("Please login first. (uri: %s)", uri, "ERR")
            return
        headers = {
            'X-Auth-Email': self.user_email,
            'X-Auth-Key': self.user_api_key,
            'Content-Type': "application/json",
        }
        if extra:
            headers.update(extra)
        opener = urllib2.build_opener(urllib2.HTTPHandler)
        req  = urllib2.Request("https://api.cloudflare.com/client/v4%s" % uri)
        for k, v in headers.items():
            req.add_header(k, v)
        req.get_method = lambda: method
        r = opener.open(req).read()
        if PY3K and isinstance(r, bytes):
            r = r.decode('ascii')
        return json.loads(r)

        return json.loads(r.read())

    def user_auth(self, arg):
        ret = self._hostapi("user_auth", arg)
        if not ret:
            return False
        if 'response' not in ret or 'user_key' not in ret['response']:
            log("Login failed, msg: %s", ret['msg'].encode('utf-8'), "ERR")
            return False
        log("Login as %s", arg['cloudflare_email'])
        self.user_key = ret['response']['user_key']
        self.user_api_key = ret['response']['user_api_key']
        if not PY3K:
            self.user_email = arg['cloudflare_email']
            self.user_key = self.user_key.encode('utf-8')
            self.user_api_key = self.user_api_key.encode('utf-8')
        open(CFHOST_FILE, "w").write("%s,%s,%s" % (self.user_email, self.user_key, self.user_api_key))
        return True

    def logout(self, *arg):
        try:
            os.remove(CFHOST_FILE)
        except:
            pass
        os._exit(0)

    def ssl_verfication(self, arg):
        r = self._userapi("/zones?name=%s&match=all" % arg['zone'])
        if len(r['result']) < 1:
            log("No zone found matching %s. Please use zone_set first.", arg['zone'], "ERR")
            return
        zone_id = r['result'][0]['id']
        r = self._userapi("/zones/%s/ssl/verification?retry=true" % zone_id)
        if len(r['result']) < 1:
            log("??? %s", r, "ERR")
            return
        if r['result'][0]['certificate_status'] == "active":
            log("SSL for domain %s has already been activated.", arg['zone'])
            return True
        verification_info = r['result'][0]['verification_info']
        if 'record_name' in verification_info: # DNS verification
            log("Please set CNAME record of %s to %s and run this option again after record become effective", (
                verification_info['record_name'].encode('utf-8'), verification_info['record_target'].encode('utf-8')))
        else: # HTTP verification
            log("Please create a file with the following content and run this option again after record become effective:")
            print("%-90s%s" % (i18n("URL"), i18n("Content")))
            print("-" * 80)
            print("\n".join(map(lambda x: "%-90s%s" % (
                    x['verification_info']['http_url'],
                    x['verification_info']['http_body']),
                r['result'])))

    def add_subdomain(self, arg):
        r = self._hostapi("zone_lookup", {"zone_name": arg['zone_name']})
        if 'hosted_cnames' not in r['response'] or not r['response']['hosted_cnames']:
            log("No zone found matching %s. Please use zone_set first.", arg['zone_name'], "ERR")
            return
        hosted = r['response']['hosted_cnames']
        # concat a real subdomain
        if arg['subdomains'] == "@":
            subdomain = arg['zone_name']
        elif arg['subdomains'].lower().endswith(arg['zone_name'].lower()):
            subdomain = arg['subdomains']
        else:
            subdomain = "%s.%s" % (arg['subdomains'], arg['zone_name'])
        hosted[subdomain] = arg['resolve_to']
        # make the subdomain to @ to avoid it being changed
        arg['resolve_to'] = hosted[arg['zone_name']]
        arg['subdomains'] = "@,%s" % (",".join(["%s:%s" % (k, v) for k, v in hosted.items() if k != arg['zone_name']]))
        r = self._hostapi("zone_set", arg)
        self._zone_set(r, subdomain)

    def delete_subdomain(self, arg):
        if arg['subdomains'] == "@":
            log("Can't delete root record", (), "ERR")
            return
        r = self._hostapi("zone_lookup", {"zone_name": arg['zone_name']})
        if 'hosted_cnames' not in r['response'] or not r['response']['hosted_cnames']:
            log("No zone found matching %s. Please use zone_set first.", arg['zone_name'], "ERR")
            return
        hosted = r['response']['hosted_cnames']
        # concat a real subdomain
        if arg['subdomains'] == "@":
            subdomain = arg['zone_name']
        elif arg['subdomains'].lower().endswith(arg['zone_name'].lower()):
            subdomain = arg['subdomains']
        else:
            subdomain = "%s.%s" % (arg['subdomains'], arg['zone_name'])
        if subdomain not in hosted:
            log("Record %s is not found in zone %s", (subdomain, arg['zone_name']))
            return
        # make the subdomain to @ to avoid it being changed
        arg['resolve_to'] = hosted[arg['zone_name']]
        arg['subdomains'] = "@,%s" % (",".join(["%s:%s" % (k, v) for k, v in hosted.items() if k != arg['zone_name'] and k != subdomain]))
        r = self._hostapi("zone_set", arg)
        log("Record %s is deleted", subdomain)

    @catch_err
    def _zone_list(self, j):
        print("%-24s%-24s" % (i18n("Zone"), i18n("User")))
        print("-" * 80)
        for z in j['response']:
            print("%-24s%-24s" % (z['zone_name'], z['user_email']))

    @catch_err
    def _zone_set(self, j, resolve=None):
        if 'forward_tos' in j['response']:
            resolve = resolve if resolve else list(j['response']['forward_tos'].keys())[0]
            cname = j['response']['forward_tos'][resolve]
            log("Success! Please set CNAME record of %s to %s", (resolve.encode('utf-8'), cname.encode('utf-8')))

    @catch_err
    def _zone_delete(self, j):
        log("Domain %s has been removed from partner", j['request']['zone_name'].encode('utf-8'))

    @catch_err
    def _zone_lookup(self, j):
        if not j['response']['zone_exists']:
            log("Zone %s not exists or is not under user %s",
                (j['request']['zone_name'].encode('utf-8'), self.user_email))
            return
        log("SSL status: %s", (i18n(j['response']['ssl_status'].encode('utf-8').decode('ascii'))))
        print("%-32s%-24s%-32s" % (i18n("Subdomain"), i18n("Resolve to"), i18n("CNAME")))
        print("-" * 80)
        tos = j['response']['forward_tos']
        hosted = j['response']['hosted_cnames']
        if not tos or not hosted:
            return
        ssl_cname, ssl_resolve_to = None, None
        for z in tos.keys():
            if hosted[z].endswith("comodoca.com"):
                ssl_cname = z.encode('utf-8')
                ssl_resolve_to = hosted[z].encode('utf-8')
                continue
            print("%-32s%-32s%-32s" % (z, hosted[z], tos[z]))
        if ssl_cname and j['response']['ssl_status'] != "ready":
            print("")
            log("If you want to activate SSL, please set CNAME record of %s to %s and " \
                "run this \"ssl_verfication\" after record become effective", (ssl_cname, ssl_resolve_to))

    @catch_err
    def _host_key_regen(self, j):
        global HOSTKEY
        HOSTKEY = j['request']['host_key']['__host_key'].encode('utf-8')
        check_hostkey(force = True)
        log("Host key has been changed to %s", HOSTKEY)

    def __getattr__(self, act, handle=True):
        if act not in CFARG:
            raise AttributeError("'CF' object has no attribute '%s'" % act)
        return lambda k={}:getattr(self, "_%s" % act)(self._hostapi(act, k))

def check_hostkey(force = False):
    global HOSTKEY
    if HOSTKEY and len(HOSTKEY) == 32 and not force:
        return
    while not HOSTKEY or len(HOSTKEY) != 32:
        HOSTKEY = raw_input(i18n("Please enter your Cloudflare partner hostkey (https://partners.cloudflare.com/api-management)> ")).strip()
    import re
    with open(__file__, "rb") as f:
        script = f.read()
    if PY3K:
        HOSTKEY = HOSTKEY.encode('ascii')
    script = re.sub(b"HOSTKEY.+HOSTKEY_ANCHOR", b"HOSTKEY = \"%s\" # HOSTKEY_ANCHOR" % HOSTKEY, script, count = 1)
    with open(__file__, 'wb') as f:
        f.write(script)

def menu(act = None):
    if not act:
        acts = [k for k in sorted(CFARG.keys()) if k != "user_auth"] + ["logout"]
        print("=" * 32)
        print(i18n("Select your action:"))
        for i in range(len(acts)):
            print("%d. %s" % (i + 1, i18n(acts[i])))
        s = raw_input("> ").strip()
        if not s.isdigit() or int(s) not in range(1, len(acts) + 1):
            return None, None
        act = acts[int(s) - 1]
    arg = {}
    if act in CFARG:
        for k in CFARG[act]:
            while True:
                arg[k] = raw_input("%s > " % i18n(k))
                if arg[k]:
                    break
    return act, arg

if __name__ == '__main__':
    try:
        check_hostkey()
        cf = CF()
        while not cf.user_key:
            act, arg = menu(act = "user_auth")
            cf.user_auth(arg)
        while True:
            act, arg = menu()
            if not act:
                continue
            getattr(cf, act)(arg)
    except (KeyboardInterrupt, EOFError):
        os._exit(0)


import os
import matplotlib.pyplot as plt

# Get the path of the directory where the program is located
dir_path = os.path.dirname(os.path.realpath(__file__))

# Prompt the user to enter the filename
filename = input("Enter the name of the file: ")
file_path = os.path.join(dir_path, filename)

# Check if the file exists
if not os.path.exists(file_path):
    print("Error: file not found.")
    exit()

# Read the contents of the file
with open(file_path, 'r') as file:
    lines = file.readlines()
    num_lines = len(lines)
    if num_lines == 0:
        print("Error: file is empty.")
        exit()

# Prompt the user to enter the starting and ending lines
start_line = int(input(f"Enter the starting line number (1 to {num_lines}): "))
end_line = int(input(f"Enter the ending line number ({start_line} to {num_lines}): "))

# Check if the line numbers are valid
if start_line < 1 or end_line > num_lines or start_line > end_line:
    print("Error: invalid line numbers.")
    exit()

# Extract the data from the selected lines
data = []
for i in range(start_line - 1, end_line):
    data.append(float(lines[i]))

# Plot the chart
plt.plot(data)
plt.xlabel('Sample number')
plt.ylabel('Value')
plt.title('Selected Data')
plt.show()