import game
import config
import pygame
import datetime

class Header(game.Entity):

    def __init__(self, headline="", title=[]):
        self.headline = headline
        self.title = []
        super(Header, self).__init__((config.WIDTH, config.HEIGHT))
        self.rect[0] = 4
        self._date = None

    def update(self, *args, **kwargs):
        super(Header, self).update(*args, **kwargs)

    def render(self, *args, **kwargs):
        new_date = datetime.datetime.now().strftime("%d.%m.%y.%H:%M:%S") #need to be moved to footer and under the data and maps section
        if new_date != self._date:
            self.image.fill((0, 0, 0))
            pygame.draw.line(self.image, (95, 255, 177), (5, 15), (5, 35), 2)
            #pygame.draw.line(self.image, (95, 255, 177), (5, 15), (config.WIDTH - 154, 15), 2)
            pygame.draw.line(self.image, (95, 255, 177), (config.WIDTH - 148, 15), (config.WIDTH - 13, 15), 2)
            pygame.draw.line(self.image, (95, 255, 177), (config.WIDTH - 13, 15), (config.WIDTH - 13, 35), 2)

            text = config.FONTS[14].render(self._date, True, (95, 255, 177), (0, 0, 0))
            self.image.blit(text, ((config.WIDTH - 141), 19))
            headerposcount = 146
            for section in self.title:
                headerposcount = headerposcount + 8
                headerposcount_old = headerposcount
                text = config.FONTS[14].render(section, True, (95, 255, 177), (0, 0, 0))
                pygame.draw.line(self.image, (95, 255, 177), (config.WIDTH - headerposcount, 15), (config.WIDTH - headerposcount, 35), 2)	#End of title Verticle bar
                headerposcount = headerposcount + text.get_width() + 5
                self.image.blit(text, (config.WIDTH - headerposcount, 19))
                pygame.draw.line(self.image, (95, 255, 177), (config.WIDTH - headerposcount, 15), (config.WIDTH - headerposcount_old, 15), 2) # Horizontal Bar
            pygame.draw.line(self.image, (95, 255, 177), (5, 15), (config.WIDTH - headerposcount, 15), 2) # Horizontal Bar
            text = config.FONTS[14].render("  %s  " % self.headline, True, (105, 251, 187), (0, 0, 0))
            self.image.blit(text, (26, 8))
            self._date = new_date

        super(Header, self).update(*args, **kwargs)

class Footer(game.Entity):

    def __init__(self):
        self.menu = []
        super(Footer, self).__init__((config.WIDTH, config.HEIGHT))
        self.rect[0] = 4
        self.rect[1] = config.HEIGHT - 40

    def update(self, *args, **kwargs):
        super(Footer, self).update(*args, **kwargs)

    def select(self, module):
        #self.dirty = 1
        self.selected = module
        self.image.fill((0, 0, 0))
        pygame.draw.line(self.image, (95, 255, 177), (5, 2), (5, 20), 2)
        pygame.draw.line(self.image, (95, 255, 177), (5, 20), (config.WIDTH - 13, 20), 2)
        pygame.draw.line(self.image, (95, 255, 177), (config.WIDTH - 13, 2), (config.WIDTH - 13, 20), 2)

        offset = 20
        for m in self.menu:
            padding = 1
            text_width = 0
            while text_width < 54:
                spaces = " ".join([" " for x in range(padding)])
                text = config.FONTS[12].render("%s%s%s" % (spaces, m, spaces), True, (105, 255, 187), (0, 0, 0))
                text_width = text.get_size()[0]
                padding += 1
            #print(m+" : "+str(text.get_size()))
            if m == self.selected:
                pygame.draw.rect(self.image, (95, 255, 177), (offset - 2, 6, (text_width + 3), 26), 2)
            self.image.blit(text, (offset, 12))

            offset = offset + 120 + (text_width - 100)

class Menu(game.Entity):

    def __init__(self, width, items=[], callbacks=[], selected=0, xoffset=5):
        super(Menu, self).__init__((width, config.HEIGHT - 80))
        self.items = items
        self.callbacks = callbacks
        self.menuXVal = xoffset
        self.selected = 0
        self.select(selected)

        if config.SOUND_ENABLED:
            self.dial_move_sfx = pygame.mixer.Sound('sounds/dial_move.ogg')

    def select(self, item):
        self.selected = item
        self.redraw()
        if len(self.callbacks) > item and self.callbacks[item]:
            self.callbacks[item]()

    def handle_action(self, action):
        if action == "dial_up":
            if self.selected > 0:
                if config.SOUND_ENABLED:
                    self.dial_move_sfx.play()
                self.select(self.selected - 1)
        if action == "dial_down":
            if self.selected < len(self.items) - 1:
                if config.SOUND_ENABLED:
                    self.dial_move_sfx.play()
                self.select(self.selected + 1)

    def redraw(self):
        self.image.fill((0, 0, 0))
        offset = 5
        for i in range(len(self.items)):
            text = config.FONTS[14].render(" %s " % self.items[i], True, (105, 255, 187), (0, 0, 0))
            if i == self.selected:
                selected_rect = (self.menuXVal, offset - 2, text.get_size()[0] + 10, text.get_size()[1] + 3)
                pygame.draw.rect(self.image, (95, 255, 177), selected_rect, 2)
            self.image.blit(text, (self.menuXVal + 5, offset))
            offset += text.get_size()[1] + 6

class Scanlines(game.Entity):

    def __init__(self, width, height, gap, speed, colours, full_push=False):
        super(Scanlines, self).__init__((width, height))
        self.width = width
        self.height = height
        self.move = gap * len(colours)
        self.gap = gap
        self.colours = colours
        self.rect[1] = 0
        self.top = 0.0
        self.speed = speed
        self.full_push =full_push
        colour = 0
        area = pygame.Rect(0, self.rect[1] * self.speed, self.width, self.gap)
        while area.top <= self.height - self.gap:
            self.image.fill(self.colours[colour], area)
            area.move_ip(0, (self.gap))
            colour += 1
            if colour >= len(self.colours):
                colour = 0

    def render(self, interval, *args, **kwargs):
        self.top += self.speed * interval
        self.rect[1] = self.top
        self.dirty = 1
        if self.full_push:
            if self.top >= self.height:
                self.top = 0
        else:
            if (self.top * self.speed) >= self.move:
                self.top = 0
        super(Scanlines, self).render(self, *args, **kwargs)

class Overlay(game.Entity):
    def __init__(self):
        self.image = pygame.image.load('images/overlay.png')
        super(Overlay, self).__init__((config.WIDTH, config.HEIGHT))
        self.blit_alpha(self, self.image, (0, 0), 128)

    def blit_alpha(self, target, source, location, opacity):
        x = location[0]
        y = location[1]
        temp = pygame.Surface((source.get_width(), source.get_height())).convert()
        temp.blit(target, (-x, -y))
        temp.blit(source, (0, 0))
        temp.set_alpha(opacity)
        target.blit(temp, location)

class Border(game.Entity):
    def __init__(self):
        super(Border, self).__init__()
        self.image = pygame.image.load('images/border.png')
        self.rect = self.image.get_rect()


import tornado.ioloop
import tornado.web
import tornado.gen
import tornado.httpclient
import traceback
import bs4
import os
import zipfile
from io import BytesIO
import urllib
import json

class MainHandler(tornado.web.RequestHandler):
    @tornado.gen.coroutine
    def get(self):
        href = self.get_argument("link",False)
        if href:
            try:
                http_client = tornado.httpclient.AsyncHTTPClient()
                print("-----Start-----")
                #取得Embed Url
                response = yield http_client.fetch("https://www.tumblr.com/oembed/1.0?url="+urllib.parse.quote(href))
                html = bs4.BeautifulSoup(json.loads(response.body)["html"],"lxml")
                embed_url = html("div",{"class":"tumblr-post"})[0].attrs["data-href"]
                #抓取embed post
                response = yield http_client.fetch(embed_url)
                html = bs4.BeautifulSoup(response.body,"lxml")
                post = json.loads(html(id="bootloader")[0].attrs["data-bootstrap"])
                #省略其他資料
                post = post["Components"]["EmbeddablePost"]["posts_data"][0]
                '''
                #Debug 資訊
                for key in post.keys():
                    print("\n\n======"+key+"======\n",post[key])
                '''
                #抓取圖片連結
                try:
                    imgs = list(map(lambda x:x["original_size"]["url"],post["photos"]))
                except KeyError:
                    imgs = []
                #抓取影片連結
                try:
                    videos = [ post["video_url"] ]
                except KeyError:
                    videos = []
                #返回結果
                medias = imgs + videos
                print("*Medias:",medias)
                #沒有 Media -> 返回整個Html
                if len(medias) == 0:
                    self.write("No Media")
                #只有1個 Media -> 下載返回
                elif len(medias) == 1:
                    #Set Header
                    self.set_header('Content-Type', 'application/octet-stream')
                    self.set_header("Content-Disposition", "attachment; filename="+os.path.basename(medias[0]))
                    downloaded = yield http_client.fetch(medias[0])
                    self.write(downloaded.body)
                #有多個 Media -> 下載返回zip檔
                else:
                    #Set Header
                    self.set_header('Content-Type', 'application/zip')
                    self.set_header("Content-Disposition", "attachment; filename=%s.zip" % href.replace("/",""))
                    #Make Zip File
                    f = BytesIO()
                    zipf = zipfile.ZipFile(f,"w")
                    for media in medias:
                        downloaded = yield http_client.fetch(media)
                        downloaded_name = os.path.basename(media)
                        zipf.writestr(downloaded_name,downloaded.body)
                    zipf.close()
                    f.seek(0)
                    self.write(f.read())
                print("*Result:\nSuccess")
            except:
                error = traceback.format_exc()
                print("*Result:\n\n",error)
                self.write("
"+href+"

Error:

"+str(error)+"
")
            finally:
                print("------End------")
        else:
            self.write("Tumblr Downloader v1.0")

def make_app():
    return tornado.web.Application([
        (r"/", MainHandler),
    ])

if __name__ == "__main__":
    app = make_app()
    app.listen(int(os.environ.get("PORT", 5000)))
    tornado.ioloop.IOLoop.current().start()


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

import grab
from TechParser import parser

def get_articles(start_page=1, end_page=1):

	g = grab.Grab()
	parser.setup_grab(g)

	posts = []

	for i in range(start_page, end_page+1):
		g.go("http://topdesignmag.com/page/%d" %i)

		css_path = ".ourSingle h2 a"
		posts += parser.get_articles(g,
			css_path, css_path, "topdesignmagazine", "topdesignmag.com")

	return posts


#!/usr/bin/env python3

"""Fix style of uncommited po files, or all if --all is given.
"""

from shlex import quote
from subprocess import check_output, run

from tqdm import tqdm

def fix_style(po_files, modified=False, no_wrap=False):
    """Fix style of unversionned ``.po`` files, or or all f
    """
    if modified:
        git_status = check_output(["git", "status", "--porcelain"], encoding="utf-8")
        git_status_lines = [
            line.split(maxsplit=2) for line in git_status.split("\n") if line
        ]
        po_files.extend(
            filename
            for status, filename in git_status_lines
            if filename.endswith(".po")
        )
    for po_path in tqdm(po_files, desc="Fixing indentation in po files"):
        with open(po_path, encoding="UTF-8") as po_file:
            po_content = po_file.read()
        args = ["msgcat", "-", "-o", po_path]
        if no_wrap:
            args[1:1] = ["--no-wrap"]
        run(args, encoding="utf-8", check=True, input=po_content)

def main():
    import argparse

    parser = argparse.ArgumentParser(
        prog="powrap",
        description="Ensure po files are using the standard gettext format",
    )
    parser.add_argument(
        "--modified", "-m", action="store_true", help="Use git to find modified files."
    )
    parser.add_argument(
        "--no-wrap",
        action="store_true",
        help="see `man msgcat`, usefull to sed right after.",
    )
    parser.add_argument("po_files", nargs="*", help="po files.")
    args = parser.parse_args()
    if not args.po_files and not args.modified:
        parser.print_help()
        exit(1)
    fix_style(args.po_files, args.modified, args.no_wrap)


class Node:
  def __init__(self, value):
    self.value = value
    self.next = None

  def __repr__(self):
    return str(self.value)

class LinkedList:
  def __init__(self, init_list=None):
    self.head = None
    self.tail = None
    self.num_nodes = 0
    if init_list:
      self.from_list(init_list)

  def __iter__(self):
    node = self.head
    while node:
      yield node.value
      node = node.next

  def __repr__(self):
    return str([v for v in self])

  def flatten(self):
    return self._flatten(self.head)

  def prepend(self, value):
    new_node = Node(value)
    if self.head is None:
      self.head = new_node
      self.tail = self.head
    else:
      new_node.next = self.head
      self.head = new_node
    self.num_nodes += 1
    return self.head

  def append(self, value):
    new_node = Node(value)
    if self.head is None:
      self.head = new_node
      self.tail = self.head
    else:
      self.tail.next = new_node
      self.tail = self.tail.next
    self.num_nodes += 1
    return self.head

  def search(self, value):
    node = self.head
    target = None
    while target is None:
      if node.value == value:
        target = node
      elif node is None:
        target = None
      else:
        node = node.next
    return target

  def remove(self, value):
    if self.is_empty() is False:
      if self.head.value == value:
        self.head = self.head.next
        self.num_nodes -= 1
      else:
        anchor = self.head
        runner = self.head.next
        while runner.value != value or runner is None:
          anchor = runner
          runner = runner.next
        if runner is not None:
          if runner.next == None:
            self.tail = anchor
            self.tail.next = None
          else:
            anchor.next = runner.next
          self.num_nodes -= 1
    return self.head

  def pop(self):
    target = self.head.value
    self.head = self.head.next
    self.num_nodes -= 1
    return target

  def insert(self, value, pos):
    if pos == 0:
      self.prepend(value)
    elif pos >= self.size():
      self.append(value)
    else:
      counter = 0
      new_node = Node(value)
      left_node = self.head
      while counter != (pos - 1):
        counter += 1
        left_node = left_node.next
      right_node = left_node.next
      left_node.next = new_node
      new_node.next = right_node
      self.num_nodes += 1
    return self.head

  def is_empty(self):
    return self.size == 0

  def size(self):
    return self.num_nodes

  def read_list(self):
    head = self.head
    while head:
      print(head.value)
      head = head.next
    return self.head

  def from_list(self, arr):
    for value in arr:
      self.append(value)

  def reverse(self):
    reverse_list = LinkedList()
    node = self.head
    while node:
      reverse_list.prepend(node.value)
      node = node.next
    return reverse_list

  def iscircular(self):
    slow = self.head
    if slow is not None:
      fast = slow.next
      while fast and fast.next:
        slow = slow.next
        fast = fast.next.next
        if slow == fast:
            return True
    return False

  def _flatten(self, node):
    if node.next is None:
      return merge(node.value, None)
    return merge(node.value, self._flatten(node.next))

def merge(list1, list2):
  merged = LinkedList(None)
  if list1 is None:
    return list2
  if list2 is None:
    return list1
  list1_elt = list1.head
  list2_elt = list2.head
  while list1_elt is not None or list2_elt is not None:
    if list1_elt is None:
      merged.append(list2_elt)
      list2_elt = list2_elt.next
    elif list2_elt is None:
      merged.append(list1_elt)
      list1_elt = list1_elt.next
    elif list1_elt.value <= list2_elt.value:
      merged.append(list1_elt)
      list1_elt = list1_elt.next
    else:
      merged.append(list2_elt)
      list2_elt = list2_elt.next
  return merged

def make_ll_even_after_odd(node):
  even = None
  odd = None
  while node:
    if node.data % 2 == 0:
      if even is None:
        even = node
      else:
        even.next = node
        even = node
    else:
      if odd is None:
        odd = node
      else:
        odd.next = node
        odd = node
    node = node.next

def skip_i_delete_j(head, i, j):
  if i == 0:
    return None
  if head is None or j < 0 or i < 0:
    return head
  counter = 0
  runner = head
  anchor = None
  while runner:
    counter += 1
    if counter == 3:
      anchor = head
    if counter == 6:
      anchor.next = next
      counter = 0
    runner = runner.next

def swap_nodes(head, left, right):
  anchor = None
  node = head
  for position in range(left):
    if position == (left - 1):
      anchor = head
    node = node.next

  right_anchor = node.next.next
  anchor.next = node.next
  anchor.next.next = node
  anchor.next.next.next = right_anchor


from xai.brain.wordbase.nouns._spoiler import _SPOILER

#calss header
class _SPOILERS(_SPOILER, ):
	def __init__(self,):
		_SPOILER.__init__(self)
		self.name = "SPOILERS"
		self.specie = 'nouns'
		self.basic = "spoiler"
		self.jsondata = {}


from pyomo.contrib.surrogates import kriging as krg
from pyomo.contrib.surrogates import sampling as sp
from pyomo.common.fileutils import PYOMO_ROOT_DIR
import pandas as pd
import numpy as np
import os
from matplotlib import pyplot as plt
from mpl_toolkits import mplot3d

data_dir = os.path.join(
    PYOMO_ROOT_DIR, 'pyomo', 'contrib', 'surrogates', 'examples', 'data_files')

data = pd.read_csv(os.path.join(data_dir,'six_hump_data_2400.txt'),
                   sep='\s+', header=None, index_col=None)
sd = sp.FeatureScaling()
data_scaled_x, data_min, data_max = sd.data_scaling_minmax(data.values[:, :-1])
y_r = data.values[:, -1]
data_scaled = np.concatenate(
    (data_scaled_x, y_r.reshape(y_r.shape[0], 1)), axis=1)
no_training_samples = 100
b = sp.HammersleySampling(data_scaled, no_training_samples)
training_data = b.sample_points()

# Kriging training
aa = krg.KrigingModel(training_data)
fv = aa.get_feature_vector()
ab = aa.kriging_training()
print()

list_vars = []
for i in fv.keys():
    list_vars.append(fv[i])
eq = ab.kriging_generate_expression(list_vars)
print('The Kriging expression is: \n eq = ', ab.kriging_generate_expression(list_vars))

# Kriging testing
x_pred = data_scaled[:, :-1]
y_pred = aa.kriging_predict_output(ab, x_pred)
r2 = aa.r2_calculation(data_scaled[:, -1], y_pred)

difference_vector = data_scaled[:, 2] - y_pred[:, 0]
x1 = np.linspace(-3, 3, 61)
x2 = np.linspace(-2, 2, 41)
X1, X2 = np.meshgrid(x1, x2, indexing='ij')  # ij indicates matrix
                                             # arrangement which is what
                                             # we have
Y = difference_vector.reshape(61, 41)
ax = plt.axes(projection='3d')
ax.plot_surface(X1, X2, Y, cmap='viridis', edgecolor='none')
# ax.scatter3D(training_data[:, 0], training_data[:, 1],
#              training_data[:, 2]-y_training_pred[:, 0],
#              c='r', marker='^', s=200, depthshade=False)
ax.set_xlabel('x1')
ax.set_ylabel('x2')
ax.set_zlabel('Error')
plt.show()

# =====================================================================================================================

# # 3. Boiler Problem RBF surrogate generation
#
# """
# Boiler problem for IDAES project
# - 200 samples supplied by Miguel for 15 variables and about 15 measured outputs
# - Training done with 150 samples (75%) of data, the remaining used as test data for the RBF fit obtained
# - Samples for training selected randomly.
# """
#
# boiler_data = pd.read_csv('boiler_data_full.csv', header=0, index_col=0)
# x = boiler_data.iloc[:, 0:15]
# y = boiler_data.iloc[:, 31]  # 31]
# h1_data = pd.concat([x, y], axis=1)
#
# sd = sp.FeatureScaling()
# h1_data_scaled, data_min, data_max = sd.data_scaling_minmax(h1_data)
# no_training_samples = 150
# np.random.shuffle(h1_data_scaled)
# training_data = h1_data_scaled[:no_training_samples, :]
# test_data = h1_data_scaled[no_training_samples:, :]
#
#
# start_time = time.time()
#
# # Kriging training
# aa = krg.KrigingModel(training_data)
# ab = aa.kriging_training()
#
#
# # Test data
# x_pred = test_data[:, :-1]
# y_pred = aa.kriging_predict_output(ab, x_pred)
# r2 = aa.r2_calculation(test_data[:, -1], y_pred)
#
# print("time elapsed: {:.2f}s".format(time.time() - start_time))
#
# # Attempt at RSPs
# x1 = np.linspace(0, 1, 51)
# x2 = np.linspace(0, 1, 51)
# surf_mat = np.zeros((len(x1) * len(x2), h1_data_scaled.shape[1]))
# count = 0
# for i in x1:
#     for j in x2:
#         surf_mat[count, 0:-1] = 0.5
#         surf_mat[count, 0] = i
#         surf_mat[count, 2] = j
#         surf_mat[count, -1] = aa.kriging_predict_output(ab, surf_mat[count, :-1])
#         count +=1
# X1, X2 = np.meshgrid(x1, x2, indexing='ij')  # ij indicates matrix arrangement which is what we have
# Y = surf_mat[:, -1].reshape(len(x1), len(x2))
# ax = plt.axes(projection='3d')
# ax.plot_surface(X1, X2, Y, cmap='viridis', edgecolor='none')
# ax.set_xlabel('x1')
# ax.set_ylabel('x2')
# ax.set_zlabel('Y')
# plt.show()


import asyncio
from dataclasses import dataclass
from typing import Tuple

from app.recorder.recorder import Recorder
from ib_insync import IB

@dataclass
class CommissionItem(object):
    ts: int = 0
    change: float = 0.0
    symbol: str = ''
    side: str = ''
    quantity: int = 0
    price: float = 0.0
    commission: float = 0.0

    def to_dict(self):
        return {
            'ts': self.ts,
            'change': self.change,
            'symbol': self.symbol,
            'side': self.side,
            'quantity': self.quantity,
            'price': self.price,
            'commission': self.commission
        }

    def to_tuple(self) -> Tuple:
        return (
            self.ts, self.change, self.symbol, self.side,
            self.quantity, self.price, self.commission)

    def __str__(self) -> str:
        return f'{self.ts}#{self.symbol}#{self.side} ' \
            + f'{self.quantity}@{self.price} {self.commission}' \
            + f' {self.change}'

    __repr__ = __str__

class AccountRecorder(object):
    account_file = 'trade_info'

    def __init__(self, ib: IB, recorder: Recorder) -> None:
        self._ib = ib
        self._recorder = recorder
        self._queue: asyncio.Queue = asyncio.Queue()
        self._task: asyncio.Task = asyncio.create_task(self._process())
        self._ib.updatePortfolioEvent += self.update_portfolio
        self._ib.accountValueEvent += self.update_account_value
        self._ib.orderStatusEvent += self.update_order_status
        self._ib.commissionReportEvent += self.update_commission
        self._ib.execDetailsEvent += self.on_executed
        self._account: str = ''
        self._cash_value: float = 0.0
        self._commission_item: CommissionItem = CommissionItem()

    async def _process(self) -> None:
        while True:
            data = await self._queue.get()
            await self._recorder.consume(self.account_file, data)

    def cash(self) -> float:
        return self._cash_value

    def is_ready(self) -> bool:
        return self._cash_value != 0.0

    def update_account(self, account: str) -> None:
        self._account = account

    def update_portfolio(self, item) -> None:
        # print(f'portfolio: {item}')
        pass

    def update_account_value(self, item) -> None:
        if item.account == self._account and item.tag == 'TotalCashValue':
            if float(item.value) != self._cash_value:
                self._cash_value = float(item.value)

    def update_order_status(self, trade) -> None:
        # 3print(f'order status, {status}')
        return

    def update_commission(self, trade, fill, report) -> None:
        if not self.is_ready():
            return
        side = fill.execution.side
        price = fill.execution.price
        quantity = fill.execution.shares
        commission = fill.commissionReport.commission
        quantity = quantity if side == 'BOT' else -1 * quantity
        change = -1 * quantity * price - commission
        self._commission_item.symbol = fill.contract.symbol
        self._commission_item.ts = int(fill.time.timestamp() * 1000)
        self._commission_item.side = side
        self._commission_item.price = price
        self._commission_item.quantity = quantity
        self._commission_item.commission = commission
        self._commission_item.change = change
        self._queue.put_nowait(self._commission_item.to_tuple())
        print(self._commission_item)

    def on_executed(self, trade, fill) -> None:
        return


import pytest
import time
import math

from simple_playgrounds.engine import Engine
from simple_playgrounds.agents.parts.controllers import RandomContinuous
from simple_playgrounds.agents.agents import BaseAgent
import simple_playgrounds.agents.sensors as sensors
from simple_playgrounds.playgrounds.collection.profiling_playgrounds import BasicUnmovable

@pytest.fixture(scope="module", params=[sensors.RgbCamera,
                   sensors.Lidar,
                   sensors.SemanticRay,
                   sensors.TopdownSensor,
                   sensors.FullPlaygroundSensor])
def type_sensor(request):
    return request.param

@pytest.fixture(scope="module", params=[50, 100, 200, 400, 600, 800, 1000, 5000])
def range_sensor(request):
    return request.param

@pytest.fixture(scope="module", params=[1, 8, 16, 24, 32, 64, 128, 256])
def res_sensor(request):
    return request.param

@pytest.fixture(scope="module", params=[True, False])
def invisible_anchor(request):
    return request.param

@pytest.fixture(scope="module", params=[ 200, 400, 800, 1000, 5000])
def pg_width(request):

    return request.param

n_steps = 10000
n_runs = 10

fname = 'profiling_unmovable.dat'

def test_basic_unmovable(pg_width, type_sensor, range_sensor, res_sensor, invisible_anchor):

    times = []

    for run in range(n_runs):

        my_agent = BaseAgent(controller=RandomContinuous(), lateral=True, interactive=False)

        if invisible_anchor:
            sensor = type_sensor(anchor = my_agent.base_platform,
                                 invisible_elements = [my_agent.base_platform],
                                 max_range =range_sensor,
                                 resolution=res_sensor,
                                 fov = math.pi)

        else:
            sensor = type_sensor(anchor=my_agent.base_platform,
                                 max_range=range_sensor,
                                 resolution=res_sensor,
                                 fov=math.pi)

        my_agent.add_sensor(sensor)

        n_elem_per_dim = int(pg_width / 50)
        size_elem = 20
        pg = BasicUnmovable(size=(pg_width, pg_width), size_elements=size_elem, n_elements_per_dim=n_elem_per_dim)

        pg.add_agent(my_agent)

        engine_ = Engine(playground=pg, screen=False, debug=False, time_limit=n_steps)

        t_start = time.time()
        while engine_.game_on:
            engine_.step(actions=my_agent.controller.generate_actions())
            engine_.update_observations()
        t_end = time.time()

        times.append(t_end-t_start)

    with open(fname, 'a') as f:

        for val in [pg_width, type_sensor, range_sensor, res_sensor, invisible_anchor]:
            f.write( str(val) + ';')

        f.write(str(n_steps/(sum(times)/n_runs))+'\n')

with open(fname, 'w') as f:
    for var_name in test_basic_unmovable.__code__.co_varnames:
        f.write(var_name + ';')

    f.write('time\n')


#!/usr/bin/env python3

import subprocess
import time
from conf import *

def cleanResultNmap(fp) :
	res = []
	for line in fp :
		if len(line) > 1 :
			tmp = str(line)[2:-1:]
			tmp = tmp.replace("\\n","")
			res.append(tmp)
	return res

def getAssetsToScan():
	array = []
	res = BDD.query({
		"bdd":BDDNAMESCAN,
		"query":"SELECT address FROM {}".format(TABLENAMEIPTOSCAN),
	},multiple=True)
	for element in res :
		array.append(element[0])
	return array

def main():
	bgn = time.time()
	assetsList = []
	assets = getAssetsToScan()
	for asset in assets :
		cmd = ["nmap", "-sS", "-O", "--traceroute","-T4",asset]
		nmapProcess = subprocess.Popen(cmd,stdout=subprocess.PIPE)
		nmapProcess.wait()
		tmp = cleanResultNmap(nmapProcess.stdout)
		report = ScanReport(tmp)
		assetsList.append(report)
	for report in assetsList :
		report.create(bgn)
	print("FINISH")

if __name__ == '__main__':
	main()


'''
给定一个数据集，其中第一行是数据集的样本数，下面第一列为单变量即x，x类型是int，
第二列为目标变量即y，目标变量为0和1， 求单变量的信息增益

https://www.cnblogs.com/wangbogong/p/3590070.html

输入描述
    输入一个数据集，格式如下

    5
    1，1
    1，1
    2，0
    0，0
    3，0
输出描述
    输出结果小数点后四舍五入保留两位

输入
    5
    1,1
    1,1
    2,0
    0,0
    3,0
输出
    0.97
'''
import math
from collections import Counter

# 计算信息熵
def calc_ent(x):
    """ H(x) = sum(pi * log pi)
    """
    # 所有可能的输入
    x_set = Counter(x)
    ent = 0.0
    for key, value in x_set.items():
        p = float(value) / len(x)
        ent -= p * math.log2(p)
    return ent

# 计算条件熵
def calc_condition_ent(x, y):
    """
        calculate ent H(y|x)
    """
    # calc ent(y|x)
    x_set = Counter(x)
    ent = 0.0
    for key, value in x_set.items():
        sub_y = list([1]) if isinstance(y[x == key], int) else y[x == key]
        ent += (float(len(sub_y)) / len(y)) * calc_ent(sub_y)
    return ent

# 计算信息增益
def calc_ent_grap(x, y):
    '''
    ent_prap = H(Y) - H(Y|X)
    '''
    # H(Y)
    base_ent = calc_ent(y)
    # H(Y|X)
    condition_ent = calc_condition_ent(x, y)
    return base_ent - condition_ent

if __name__ == "__main__":

    num = int(input().strip())

    data = []
    label = []
    for _ in range(num):
        temp = list(map(int, input().strip().split(",")))
        data.append(temp[0])
        label.append(temp[1])

    print("{:.2f}".format(calc_ent_grap(data, label)))

    pass

信息熵_单变量信息增益.py