""" Models for media_partner app. """

from django.core.exceptions import ValidationError
from django.db import models
from django.utils.translation import ugettext_lazy as _

from consumer.models import Consumer
from market.models import Site

class MediaPartner(Consumer):
    """
    A MediaPartner inherits Consumer and can have 2 user_types.
    1.) media_group_partner (Media Group User)
       media_group_partner is a user of a MediaGroup
    2.) affiliate_partner (Affiliate User)
        affiliate_partner is a user of an Affiliate
    """
    def __unicode__(self):
        # Needs to return unicode string or validation will fail.
        return self.email or ''

class MediaGroup(models.Model):
    """ A MediaGroup is the Corporate Radio Partner. Example: ClearChannel """
    media_group_partner = models.ManyToManyField(MediaPartner,
        related_name='media_groups')
    name = models.CharField(max_length=50)
    contact_name = models.CharField(max_length=50)
    contact_phone = models.CharField(max_length=10)
    contact_email = models.CharField(max_length=255)

    def __unicode__(self):
        return self.name

class Medium(models.Model):
    """ A medium example could be 'radio' or 'cable'. """
    name = models.CharField(max_length=50)

    def __unicode__(self):
        return self.name

class Affiliate(models.Model):
    """ An Affiliate is a sub group of Media Groups.
    Example: Clear Channel of the Hudson Valley
    """
    name = models.CharField(max_length=50)
    affiliate_partner = models.ManyToManyField(MediaPartner,
        related_name='affiliates')
    media_group = models.ForeignKey(MediaGroup, related_name='affiliates',
        null=True, blank=True)
    contact_name = models.CharField(max_length=50)
    contact_phone = models.CharField(max_length=10)
    contact_email = models.CharField(max_length=255)
    address1 = models.CharField('Address 1', max_length=50,
        null=True, blank=True)
    address2 = models.CharField('Address 2', max_length=50,
        null=True, blank=True)
    city = models.CharField('City', max_length=50, null=True,
        blank=True)
    state_province = models.CharField('State/Province',
        max_length=2, null=True, blank=True)
    zip_postal = models.CharField('Zip/Postal', max_length=9,
        null=True, blank=True)
    free_coupons = models.IntegerField(default=0)
    medium = models.ForeignKey(Medium, related_name='affiliates')
    site = models.ForeignKey(Site, related_name='affiliates')

    def __unicode__(self):
        return (str(self.id) + ' - ' + self.name)

class MediaPieShare(models.Model):
    """
    Affiliates have MediaPieShares.
    """
    affiliate = models.ForeignKey(Affiliate, related_name='media_pie_shares')
    share = models.FloatField()
    site = models.ForeignKey(Site, related_name='media_pie_shares')
    start_date = models.DateField('Start Date')
    end_date = models.DateField('End Date', null=True, blank=True)

    def __unicode__(self):
        return self.affiliate.name

    def clean(self):
        if self.end_date:
            if self.start_date > self.end_date:
                raise ValidationError(_("""Please check your dates.  You can't
                    end a share before it starts"""))
            if self.start_date == self.end_date:
                raise ValidationError(_("""Please check your dates.  Start and
                    end dates can't be equal."""))
        self.clean_all_media_pie_shares()
        self.check_shares_less_than_one()
        return self

    def clean_all_media_pie_shares(self):
        """
        Do all appropriate cleaning on all the media pie shares.
        """
        media_pie_shares = MediaPieShare.objects.filter(affiliate=self.affiliate)
        for media_pie_share in media_pie_shares:
            start_date = media_pie_share.start_date
            end_date = media_pie_share.end_date
            if self.id != media_pie_share.id:
                if end_date is None:
                    self.compare_share_has_no_end_date(start_date)
                else:
                    self.compare_share_has_end_date(start_date, end_date)
        return self

    def compare_share_has_no_end_date(self, start_date):
        """
        Compare these 2 shares. The share getting compared has an no
        end date.
        """
        if self.end_date is None:
            raise ValidationError(_("""Only one active share allowed
                 in a given time period for a give affiliate."""))
        else:
            if self.end_date > start_date:
                raise ValidationError(_("""You can't set the end
                    date greater than another shares start date."""))
            if self.end_date == start_date:
                raise ValidationError(_("""You can't set the end
                    date equal to another shares start date."""))
        return self

    def compare_share_has_end_date(self, start_date, end_date):
        """
        Compare these 2 shares. The share getting compared has an end date.
        """
        if self.start_date >= start_date and self.start_date <= end_date:
            raise ValidationError(_("""This affiliates shares can't
                overlap."""))
        if self.end_date:
            if start_date >= self.start_date and start_date <= self.end_date:
                raise ValidationError(_("""This affiliates shares
                    can't overlap."""))
            if self.start_date <= start_date and self.end_date >= end_date:
                raise ValidationError(_("""This share can't start
                    before another share start and end after the
                    other share ends."""))
            if self.end_date <= end_date and self.start_date >= start_date:
                raise ValidationError(_("""You can't start and end a
                     share in the middle of another shares running
                     time."""))
        else:
            if self.start_date < end_date:
                raise ValidationError(_("""You can't set the start
                    date less than another shares end date."""))
            if self.start_date == end_date:
                raise ValidationError(_("""This start date can not
                    be equal to share# %s's end date.""" %
                    str(self.id)))
        return self

    def check_shares_less_than_one(self):
        """
        Check to ensure total active shares don't add up to over 1 which is 100%.
        """
        media_pie_shares = MediaPieShare.objects.filter(site=self.site).order_by('start_date')
        # Total active shares for this site:
        total_shares = 0
        for media_pie_share in media_pie_shares:
            if self.id != media_pie_share.id:
                if self.end_date:
                    if (media_pie_share.start_date <= self.start_date and media_pie_share.end_date is None) or \
                    (media_pie_share.start_date <= self.start_date and media_pie_share.end_date >= self.start_date) or \
                    (self.start_date <= media_pie_share.start_date and self.end_date >= media_pie_share.start_date):
                        total_shares = total_shares + media_pie_share.share
                else:
                    if (media_pie_share.end_date is None) or \
                    (self.start_date <= media_pie_share.start_date) or \
                    (self.start_date >= media_pie_share.start_date and self.start_date <= media_pie_share.end_date):
                        total_shares = total_shares + media_pie_share.share
        total_shares += self.share
        if total_shares > 1:
            raise ValidationError(_("""Can't have active shares adding up to over
                100%. If shares for this affiliate are changing, please give the
                older shares that are changing an end date."""))
        return self

    def save(self, *args, **kwargs):
        self.clean()
        super(MediaPieShare, self).save(*args, **kwargs)
        return self

class Outlet(models.Model):
    """
    An Outlet could be an Affiliate sub groups... Like 'WRRV' radio station would
    be an example of an Outlet.
    """
    name = models.CharField(max_length=25)
    affiliate = models.ForeignKey(Affiliate, related_name='outlets')
    band = models.CharField(choices=(('AM','AM'),('FM','FM')), max_length=2)
    frequency = models.CharField(max_length=5)
    format = models.CharField(max_length=25)
    slogan = models.TextField(max_length=50)
    website = models.CharField(max_length=255)
    logo = models.ImageField(upload_to='logos')

    def __unicode__(self):
        return self.name


import numpy as np

#最小二乘法求解
def least_square(feature, label):
    '''
    最小二乘法
    :param feature: 特征
    :param label:  标签
    :return:  w(mat) 回归系数
    '''
    w = (feature.T * feature).I * feature.T * label
    return w

#Armijo搜索
#损失函数计算
def get_error(feature, label, w):
    '''
    计算误差
    :param feature: 特征
    :param label:  标签
    :param w: 参数
    :return:损失函数
    '''
    return (label - feature * w).T * (label - feature * w ) / 2

#最小m值得计算
def get_min_m(feature, label, sigma, delta, d, w, g):
    '''
    计算步长中最小的值m
    :param feature: 特征
    :param label: 标签
    :param sigma:   全局牛顿法的参数
    :param delta:  全局牛顿法的参数
    :param d: 负的一阶导数除以二阶导数值
    :param w:
    :param g: 一阶导数值
    :return: m 最小m值
    '''
    m = 0
    while True:
        w_new = w + pow(sigma, m) * d
        left = get_error(feature, label, w_new)
        right = get_error(feature, label, w) + delta * pow(sigma, m) * g.T * d
        if left <= right :
            break
        else:
            m +=1
    return m

#一阶导数
def first_derivativ(feature, label, w):
    '''计算一阶导函数的值
    input:  feature(mat):特征
            label(mat):标签
    output: g(mat):一阶导数值
    '''
    m, n = np.shape(feature)
    g = np.mat(np.zeros((n, 1)))
    for i in range(m):
        err = label[i, 0] - feature[i, ] * w
        for j in range(n):
            g[j, ] -= err * feature[i, j]
    return g

#二阶导数
def second_derivative(feature):
    '''计算二阶导函数的值
    input:  feature(mat):特征
    output: G(mat):二阶导数值
    '''
    m, n = np.shape(feature)
    G = np.mat(np.zeros((n, n)))
    for i in range(m):
        x_left = feature[i, ].T
        x_right = feature[i, ]
        G += x_left * x_right
    return G

#全局牛顿法
def newton(feature, label, iterMax, sigma, delta):
    '''
    牛顿法
    :param feature: 特征
    :param label:  标签
    :param iterMax:  最大迭代次数
    :param sigma:    参数
    :param delta:    参数
    :return:  w 回归系数
    '''
    n = np.shape(feature)[1]
    w = np.mat(np.zeros((n,1)))
    it = 0
    while it <= iterMax:
        g = first_derivativ(feature, label, w) # 一阶导数
        G = second_derivative(feature) #二阶导数

        d = -G.I * g
        m = get_min_m(feature, label, sigma, delta, d, w, g)#得到最小的m
        w = w + pow(sigma, m) * d
        if it % 10  == 0 :
            print("\t---- itration: " + str(it) + " , error: " + str(get_error(feature, label, w)[0, 0]))
        it += 1
    return w

def load_data(file_path):
    '''导入数据
    input:  file_path(string):训练数据
    output: feature(mat):特征
            label(mat):标签
    '''
    f = open(file_path)
    feature = []
    label = []
    for line in f.readlines():
        feature_tmp = []
        lines = line.strip().split("\t")
        feature_tmp.append(1)  # x0
        for i in range(len(lines) - 1):
            feature_tmp.append(float(lines[i]))
        feature.append(feature_tmp)
        label.append(float(lines[-1]))
    f.close()
    return np.mat(feature), np.mat(label).T

def save_model(file_name, w):
    '''保存最终的模型
    input:  file_name(string):要保存的文件的名称
            w(mat):训练好的线性回归模型
    '''
    f_result = open(file_name, "w")
    m, n = np.shape(w)
    for i in range(m):
        w_tmp = []
        for j in range(n):
            w_tmp.append(str(w[i, j]))
        f_result.write("\t".join(w_tmp) + "\n")
    f_result.close()

if __name__ == "__main__":
    # 1、导入数据集
    print("----------- 1.load data ----------")
    feature, label = load_data("train_data.txt")
    # 2.1、最小二乘求解
    print("----------- 2.training ----------")
    # print("\t ---------- least_square ----------")
    # w_ls = least_square(feature, label)
    # 2.2、牛顿法
    print("\t ---------- newton ----------")
    w_newton = newton(feature, label, 50, 0.1, 0.5)
    # 3、保存最终的结果
    print("----------- 3.save result ----------")
    save_model("weights", w_newton)


"""mysite URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/3.0/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  path('', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.urls import include, path
    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path, re_path
from django.conf import settings
from django.conf.urls.static import static
from django.views.static import serve
from anon import views as anon_views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('anonuser/', anon_views.test),
    path('auth/', anon_views.get_auth_token, name='get-auth'),
    path('data/', anon_views.get_user_data, name='get-data'),
    re_path(r'^$', serve, kwargs={
        'path': 'index.html', 'document_root': 'www/dist'}),
    re_path(r'^(?P<path>.*)$', serve, {
        'document_root': 'www/dist',
    }),
    path('recent/', anon_views.get_recent, name='get-recent'),
]

if settings.DEBUG:
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)


from typing import List, Dict
from dataclasses import dataclass, field
from enum import Enum, auto
from os import linesep
from copy import deepcopy
from textwrap import dedent

class Direction(Enum):
    UP = auto()
    RIGHT = auto()
    DOWN = auto()
    LEFT = auto()

def opposite(direction: Direction) -> Direction:
    if direction == Direction.UP:
        return Direction.DOWN
    elif direction == Direction.RIGHT:
        return Direction.LEFT
    elif direction == Direction.DOWN:
        return Direction.UP
    else:  # elif direction == Direction.LEFT:
        return Direction.RIGHT

@dataclass
class Edge:
    edge_data: List[str]
    free: bool = field(default=True)

@dataclass
class Tile:
    tile_id: int
    tile_data: List[List[str]]
    edges: Dict[Direction, Edge] = field(init=False)

    def __post_init__(self) -> None:
        self.edges = make_edges(self)

    def __repr__(self) -> str:
        tile_repr = ""
        tile_repr += f"Tile: {self.tile_id}"
        tile_repr += linesep
        for row in self.tile_data:
            tile_repr += "".join(row)
            tile_repr += linesep
        return tile_repr

def make_edges(tile: Tile) -> Dict[Direction, Edge]:
    tile_data: List[List[str]] = tile.tile_data
    up_edge_data: List[str] = []
    for index in range(0, len(tile_data[0])):
        up_edge_data.append(tile_data[0][index])
    up_edge = Edge(up_edge_data)

    down_edge_data: List[str] = []
    for index in range(0, len(tile_data[len(tile_data) - 1])):
        down_edge_data.append(tile_data[len(tile_data) - 1][index])
    down_edge = Edge(down_edge_data)

    right_edge_data: List[str] = []
    for index in range(0, len(tile_data[len(tile_data) - 1])):
        right_edge_data.append(tile_data[index][len(tile_data) - 1])
    right_edge = Edge(right_edge_data)

    left_edge_data: List[str] = []
    for index in range(0, len(tile_data[len(tile_data) - 1])):
        left_edge_data.append(tile_data[index][0])
    left_edge = Edge(left_edge_data)
    return {
        Direction.UP: up_edge,
        Direction.RIGHT: right_edge,
        Direction.DOWN: down_edge,
        Direction.LEFT: left_edge,
    }

def flip_horizontal(tile: Tile) -> Tile:
    tile_data = deepcopy(tile.tile_data)
    for index in range(0, len(tile_data)):
        tile_data[index].reverse()
    return Tile(tile.tile_id, tile_data)

def flip_vertical(tile: Tile) -> Tile:
    tile_data = deepcopy(tile.tile_data)
    tile_data.reverse()
    return Tile(tile.tile_id, tile_data)

def rotate(tile: Tile) -> Tile:
    tile_data = deepcopy(tile.tile_data)
    list_of_tuples = zip(*tile_data[::-1])
    tile_data = [list(elem) for elem in list_of_tuples]
    return Tile(tile.tile_id, tile_data)

tile_variants_cache: Dict[int, List[Tile]] = {}

def make_tile_variants(tile: Tile) -> List[Tile]:
    if tile.tile_id in tile_variants_cache:
        return tile_variants_cache[tile.tile_id]

    tile_variants: List[Tile] = []
    base_variants: List[Tile] = []

    base_variants.append(tile)
    base_variants.append(flip_horizontal(tile))
    base_variants.append(flip_vertical(tile))

    for base_variant in base_variants:
        base_variant_rotated = base_variant
        for _ in range(0, 4):
            base_variant_rotated = rotate(base_variant_rotated)
            tile_variants.append(base_variant_rotated)

    duplicates: List[int] = []
    for tile_variant_index in range(0, len(tile_variants) - 1):
        for another_tile_variant_index in range(
            tile_variant_index + 1, len(tile_variants)
        ):
            if (
                tile_variants[tile_variant_index].tile_data
                == tile_variants[another_tile_variant_index].tile_data
            ):
                duplicates.append(another_tile_variant_index)

    tile_variants_without_dupes = [
        i for j, i in enumerate(tile_variants) if j not in duplicates
    ]
    tile_variants_cache[tile.tile_id] = tile_variants_without_dupes
    return tile_variants_without_dupes

def solve() -> str:
    file = open("input.txt", "r")
    tiles: List[Tile] = []
    tile_id: int
    tile_data: List[List[str]] = []
    while True:
        line = file.readline()
        if line == linesep or line == "":
            tile = Tile(tile_id, deepcopy(tile_data))
            tiles.append(tile)
            tile_data.clear()
            if line == "":
                break
        elif "Tile" in line:
            splitted = line.split(" ")
            tile_id = int(splitted[1].split(":")[0])
        else:
            tile_data.append(list(line.strip()))

    result = 1
    for tile in tiles:
        possible_appends = 0
        for tile_edge_direction in tile.edges:
            tile_edge = tile.edges[tile_edge_direction]
            for another_tile in tiles:
                if tile.tile_id == another_tile.tile_id:
                    continue
                for another_tile_variant in make_tile_variants(another_tile):
                    for (
                        another_tile_variant_edge_direction
                    ) in another_tile_variant.edges:
                        another_tile_variant_edge = another_tile_variant.edges[
                            another_tile_variant_edge_direction
                        ]
                        if (
                            opposite(tile_edge_direction)
                            == another_tile_variant_edge_direction
                            and tile_edge.edge_data
                            == another_tile_variant_edge.edge_data
                        ):
                            possible_appends += 1
        if possible_appends == 2:
            result *= tile.tile_id
    return str(result)

def main() -> None:
    print(solve())

if __name__ == "__main__":
    main()


class Solution(object):
    def merge(self, nums1, m, nums2, n):
        """
        :type nums1: List[int]
        :type m: int
        :type nums2: List[int]
        :type n: int
        :rtype: None Do not return anything, modify nums1 in-place instead.
        """
        merged = []
        i = 0
        k = 0
        while(i < m):
            merged.append(nums1[i])
            i+=1
        while(k < n):
            merged.append(nums2[k])
            k+=1
        merged = sorted(merged)
        for i in range(len(nums1)):
            nums1[i] = merged[i]

        return None


import sublime, sublime_plugin, re
import os
import string

from pprint import pprint

def initial():
	# rootFolder = [sublime.active_window().folders()[0]]; #root folder
	global rootFolder
	global compenentsPaths
	global templatesPaths
	global complexTemplatesPaths
	global ajaxPaths
	global compenentsList
	global templatesList
	global ajaxList
	global complexTemplatesList
	global window

	window = sublime.active_window()
	rootFolder = sublime.active_window().folders(); #root folder
	compenentsPaths = [
		["bitrix", "components","$namespace", "$component", "$|file|component.php|class.php"],
		["local", "components","$namespace", "$component", "$|file|component.php|class.php"]
	];
	templatesPaths = [
		["bitrix", "templates","$siteTemplate", "components", "$namespace", "$component", "$template", "template.php"],
		["bitrix", "components","$namespace", "$component", "templates", "$template", "template.php"],
		["local", "templates","$siteTemplate", "components", "$namespace", "$component", "$template", "template.php"],
		["local", "components","$namespace", "$component", "templates", "$template", "template.php"]
	];
	complexTemplatesPaths = [
		["bitrix", "components","$namespace", "$component", "templates", "$template", "$name"],
		["bitrix", "templates","$siteTemplate", "components", "$namespace", "$component", "$template", "$name"],
		["local", "components","$namespace", "$component", "templates", "$template", "$name"],
		["local", "templates","$siteTemplate", "components", "$namespace", "$component", "$template", "$name"]
	];
	ajaxPaths = [
		["ajax", "$name"],
		["ajaxtools", "$name"]
	]

	#initial (can be skipped, or left the only one)
	# compenentsList = [];
	# templatesList = [];
	# ajaxList = [];
	# complexTemplatesList = [];

def pathsToPaths(ar):
	initial()
	paths = []
	for sar in ar:
		paths += arrayToPath(sar)
	# pprint(paths)
	# paths = filter(lambda x: os.path.isfile(x["path"]), paths);
	return paths

def arrayToPath(ar):
	paths = []
	rootFolder = sublime.active_window().folders(); #root folder

	for root in rootFolder:
		paths.append({"path": root})
	opath = paths[0];
	for folder in ar:
		nextpaths = [];
		for opath in paths:
			path = opath["path"]
			if ("$|" == folder[:2]):
				split = folder.split('|')
				propname = split[1]
				pathVariants = split[2:]
				for subpath in pathVariants:
					osubpath = opath.copy()
					osubpath[propname] = subpath
					osubpath["path"] = os.path.join(path, subpath)
					nextpaths.append(osubpath)
				else:
					print("not a folder " + path);
					pass
			elif ("$" == folder[0]):
				propname = folder[1:]
				if os.path.isdir(path):
					for subpath in os.listdir(path):
						osubpath = opath.copy()
						osubpath[propname] = subpath
						osubpath["path"] = os.path.join(path, subpath)
						nextpaths.append(osubpath)
				else:
					print("not a folder " + path);
					pass
			else:
				opath["path"] = os.path.join(path, folder)
				nextpaths.append(opath)
		paths = nextpaths
	return paths;

rootFolder = sublime.active_window().folders(); #root folder
compenentsPaths = [
	["bitrix", "components","$namespace", "$component", "$|file|component.php|class.php"],
	["local", "components","$namespace", "$component", "$|file|component.php|class.php"]
];
templatesPaths = [
	["bitrix", "templates","$siteTemplate", "components", "$namespace", "$component", "$template", "template.php"],
	["bitrix", "components","$namespace", "$component", "templates", "$template", "template.php"],
	["local", "templates","$siteTemplate", "components", "$namespace", "$component", "$template", "template.php"],
	["local", "components","$namespace", "$component", "templates", "$template", "template.php"]
];
complexTemplatesPaths = [
	["bitrix", "components","$namespace", "$component", "templates", "$template", "$name"],
	["bitrix", "templates","$siteTemplate", "components", "$namespace", "$component", "$template", "$name"],
	["local", "components","$namespace", "$component", "templates", "$template", "$name"],
	["local", "templates","$siteTemplate", "components", "$namespace", "$component", "$template", "$name"]
];
ajaxPaths = [["ajax", "$name"], ["ajaxtools", "$name"]]

#initial (can be skipped, or left the only one)
# compenentsList = pathsToPaths(compenentsPaths);
# templatesList = pathsToPaths(templatesPaths);
# ajaxList = pathsToPaths(ajaxPaths);
# complexTemplatesList = [];

compenentsList = [];
templatesList = [];
ajaxList = [];
complexTemplatesList = [];

def parseInclude(self):
	for region in self.view.sel():
		line = self.view.line(region)
		lineContents = self.view.substr(line)

		# looking for that function
		while not re.match('.*\$APPLICATION.*->.*IncludeComponent.*\(.*',lineContents):
			region = sublime.Region(line.a-1,line.a-1)
			line = self.view.line(region)
			lineContents = self.view.substr(line)
			if line.a < 5 :
				break;

		# connecting until we get two first parameters
		while lineContents.count(',') != 2:
			region = sublime.Region(line.b+1,line.b+1)
			line = self.view.line(region)
			lineContents += self.view.substr(line)
			if (";" in lineContents) or ("?>" in lineContents):
				break;

		# reg to extract data
		parser = re.search ('.*IncludeComponent.*["|\'](.*):(.*)["|\'].*,.*["|\'](.*)[\'|"].*', lineContents)

		# answer formilising
		data = {"namespace": parser.group(1), "component": parser.group(2), "template": parser.group(3)}
		#  if template is empty
		# TODO: if template equals false, and if template in another folder
		if data['template'] == '':
			data['template'] = '.default'
		return data;
def parseAjax(self):
	for region in self.view.sel():
		line = self.view.line(region)
		lineContents = self.view.substr(line)

		# one line only
		while not re.match('.*\$\.ajax[\s]*\([\s]*{.*',lineContents):
			region = sublime.Region(line.a-1,line.a-1)
			line = self.view.line(region)
			lineContents = self.view.substr(line)
			if line.a < 5 :
				break;

		# connecting until we get two first parameters
		while lineContents.count(',') != 1:
			region = sublime.Region(line.b+1,line.b+1)
			line = self.view.line(region)
			lineContents += self.view.substr(line)
			if (";" in lineContents) or ("?>" in lineContents):
				break;

		# reg to extract data
		parser = re.search ('.*url.*:.*["|\'](.*)["|\'].*,.*', lineContents)

		# answer formilising
		data = {"url": parser.group(1)}
		return data;
def parsePhpInclude(self):
	for region in self.view.sel():
		line = self.view.line(region)
		lineContents = self.view.substr(line)

		# one line only
		while not re.match('.*(require|include).*',lineContents):
			region = sublime.Region(line.a-1,line.a-1)
			line = self.view.line(region)
			lineContents = self.view.substr(line)
			if line.a < 5 :
				break;
		# reg to extract data
		parser = re.search ('.*[requre|include].*\(.*["|\'](.*)["|\'].*\).*', lineContents)
		# answer formilising
		data = {"file": parser.group(1)}
		return data;
def parseWord(self):
	for region in self.view.sel():
		selected = region;
		while not re.match('[\."\'\s]',self.view.substr(sublime.Region(selected.a-1,selected.a))):
			selected = sublime.Region(selected.a-1,selected.b);
			if selected.a < 5 :
				break;

		while not re.match('[\."\'\s]',self.view.substr(sublime.Region(selected.b,selected.b+1))):
			selected = sublime.Region(selected.a,selected.b+1);
			if selected.b > 20000 :
				break;

		# answer formilising
		data = {"class": self.view.substr(selected)}
		return data;

#	lists
class BitrixComponentsListCommand(sublime_plugin.WindowCommand):
	def run(self):
		global compenentsList;
		compenentsList = pathsToPaths(compenentsPaths);
		compenentsList = [c for c in compenentsList if os.path.isfile(c['path'])]
		panelList = []
		panelList[:] = [c["namespace"]+":"+c["component"]+" "+c["file"] for c in compenentsList]
		window.show_quick_panel(panelList, self.on_chosen)
	def on_chosen(self, index):
		if index == -1: return
		# if not isView(self.vid):
		# 	sublime.status_message('You are in a different view.')
		# 	return
		window.open_file(compenentsList[index]["path"])
class BitrixTemplatesListCommand(sublime_plugin.WindowCommand):
	def run(self):
		global templatesList;
		templatesList = pathsToPaths(templatesPaths);
		# pprint(templatesList)
		panelList = []
		for t in templatesList:
			if "siteTemplate" in t.keys():
				niceName = t["siteTemplate"]+"/"+t["namespace"]+":"+t["component"]+":"+t["template"]
			else:
				niceName = t["namespace"]+":"+t["component"]+":"+t["template"]
			panelList.append(niceName)
		window.show_quick_panel(panelList, self.on_chosen)
	def on_chosen(self, index):
		if index == -1: return
		# if not isView(self.vid):
		# 	sublime.status_message('You are in a different view.')
		# 	return
		# pprint(templatesList)
		window.open_file(templatesList[index]["path"])
class BitrixComplexTemplatesListCommand(sublime_plugin.WindowCommand):
	def run(self):
		global complexTemplatesList, templatesList;
		nonCompex = [];
		nonCompex[:] = [t["component"] for t in templatesList if os.path.isfile(t["path"])]
		complexTemplatesList[:] = [c for c in pathsToPaths(complexTemplatesPaths) if c["component"] not in nonCompex]
		panelList = []
		for t in complexTemplatesList:
			if "siteTemplate" in t.keys():
				niceName = t["siteTemplate"]+"/"+t["namespace"]+":"
			else:
				niceName = t["namespace"]+":"
			if t["template"] == ".default":
				niceName += t["component"]
			else:
				niceName += t["component"]+":"+t["template"]
			niceName += " - " + t["name"]
			panelList.append(niceName)
		window.show_quick_panel(panelList, self.on_chosen)
	def on_chosen(self, index):
		if index == -1: return
		# if not isView(self.vid):
		# 	sublime.status_message('You are in a different view.')
		# 	return
		window.open_file(complexTemplatesList[index]["path"])
class BitrixAjaxListCommand(sublime_plugin.WindowCommand):
	def run(self):
		global ajaxList;
		ajaxList = pathsToPaths(ajaxPaths);
		panelList[:] = [c["name"] for c in ajaxList]
		window.show_quick_panel(panelList, self.on_chosen)
	def on_chosen(self, index):
		if index == -1: return
		if not isView(self.vid):
			sublime.status_message('You are in a different view.')
			return
		# pprint(ajaxList)
		window.open_file(ajaxList[index]["path"])
class BitrixPagesListCommand(sublime_plugin.WindowCommand):
	def getPathList(self):
		window = sublime.active_window();
		curFolder = window.folders()[0];

		pathList = [];
		if os.path.exists(curFolder):
			pathList += map(lambda x: x, os.listdir(curFolder));
			pathList = list(filter(lambda x: '.' not in x, pathList)); # remove .git and ect
			ignore = ['bitrix','upload','html','desktop_app'];
			pathList = list(filter(lambda x: x not in ignore, pathList));

			pathList = list(filter(lambda x: os.path.isfile(
				os.path.join(curFolder,x,"index.php")) , pathList));

		return sorted(pathList);
	def run(self):
		window = sublime.active_window();
		curFolder = window.folders()[0];
		window.show_quick_panel(self.getPathList(), self.on_chosen)
	def on_chosen(self, index):
		window = sublime.active_window();
		curFolder = window.folders()[0];
		if index == -1: return
		# if not isView(self.vid):
		# 	sublime.status_message('You are in a different view.')
		# 	return
		item = os.path.join(self.getPathList()[index],"index.php");
		openFile(item);
class BitrixHtmlListCommand(sublime_plugin.WindowCommand):
	def getPathList(self):
		window = sublime.active_window();
		curFolder = window.folders()[0];
		html = os.path.join(curFolder, "html");

		pathList = [];
		if os.path.exists(html):
			for root, dirs, files in os.walk(html, topdown=False):
				relativeRoot = root.replace(html,'',1)[1:];
				for name in files:
					if re.match(".*\.php",name):
						pathList += [os.path.join(relativeRoot,name)];

		return sorted(pathList);
	def run(self):
		window = sublime.active_window();
		curFolder = window.folders()[0];
		window.show_quick_panel(self.getPathList(), self.on_chosen)
	def on_chosen(self, index):
		window = sublime.active_window();
		curFolder = window.folders()[0];
		if index == -1: return
		# if not isView(self.vid):
		# 	sublime.status_message('You are in a different view.')
		# 	return
		item = os.path.join("html",self.getPathList()[index]);
		openFile(item);

#	in text open
class BitrixPhpOpenCommand(sublime_plugin.TextCommand):
	def run(self, edit):
		window = sublime.active_window()
		curFolder = window.folders()[0]
		data = parsePhpInclude(self)

		if data['file'][0] == "/":
			print("TODO: absolute path by php")
			# filePath = curFolder + data["file"]
		else:
			filePath = os.path.join(window.extract_variables()["file_path"],data['file']);
			window.open_file(filePath)
		# print(filePath)
class BitrixAjaxOpenCommand(sublime_plugin.TextCommand):
	def run(self, edit):
		window = sublime.active_window()
		curFolder = window.folders()[0]
		data = parseAjax(self)

		if data['url'][0] == "/":
			filePath = os.path.join(curFolder, data['url']);

			createFileFromTemplate(filePath, 'ajax.php', '');
			# print(filePath)
			window.open_file(filePath)
		else:
			print("Not looking as part of site: " + data['url'])
class BitrixGetComponentPathCommand(sublime_plugin.TextCommand):
	def run(self, edit):
		window = sublime.active_window()
		curFolder = window.folders()[0]
		data = parseInclude(self)

		componentPath = os.path.join(curFolder,'bitrix','components',data['namespace'],data['component']);
		componentFile = os.path.join(componentPath,"component.php");
		# print(componentFile)
		window.open_file(componentFile)
class BitrixGetComponentTemplatePathCommand(sublime_plugin.TextCommand):
	def run(self, edit):
		window = sublime.active_window()
		curFolder = window.folders()[0]
		data = parseInclude(self)

		componentPath = os.path.join(curFolder,'bitrix','components',data['namespace'],data['component']);
		templatePath = os.path.join(componentPath,"templates");
		templateFile = os.path.join(templatePath,data['template'],"template.php");
		# print(templateFile)
		window.open_file(templateFile)

# create new component
class BitrixNewComponentCommand(sublime_plugin.TextCommand):
	def run(self, edit):
		window = sublime.active_window()
		curFolder = window.folders()[0]
		data = parseInclude(self)

		componentPath = curFolder + '/local/components/'+data['namespace']+'/'+data['component']+"/"
		templatePath = componentPath + "templates/" + data['template'] + '/'

		# works only if no such folders
		if not os.path.exists(templatePath):
			# making folders
			os.makedirs(templatePath)

			# path relative to site dir
			cC = componentPath + "class.php"
			cP = componentPath + ".parameters.php"
			cD = componentPath + ".description.php"
			cT = templatePath  + "template.php"

			# path to site dir
			__location__ = os.path.realpath(
				os.path.join(os.getcwd(), os.path.dirname(__file__)))

			# join to get absolute paths
			eC = os.path.join(__location__, 'cC.php')
			eP = os.path.join(__location__, 'cP.php')
			eD = os.path.join(__location__, 'cD.php')
			eT = os.path.join(__location__, 'cT.php')

			# creating php files
			file = open(cC, 'a')
			file.close()
			file = open(cP, 'a')
			file.close()
			file = open(cD, 'a')
			file.close()
			file = open(cT, 'a')
			file.close()

			# filling em with templates
			with open(eC) as f:
				lines = f.readlines()
				# lines = [l for l in lines if "ROW" in l]
				with open(cC, "w") as f1:
					f1.writelines(lines)
			with open(eD) as f:
				lines = f.readlines()
				# insert code here to change #name# to smthg
				with open(cD, "w") as f1:
					f1.writelines(lines)
			with open(eP) as f:
				lines = f.readlines()
				with open(cP, "w") as f1:
					f1.writelines(lines)
			with open(eT) as f:
				lines = f.readlines()
				with open(cT, "w") as f1:
					f1.writelines(lines)

			# opening for edition
			window.open_file(cC)
			window.open_file(cT)

# utils
def createFileFromTemplate(filePath, templatePath, replaceArray):
	folder = os.path.basename(filePath);
	# if not os.path.exists(folder):
	# 	os.makedirs(folder)
	# plugin folder
	__location__ = os.path.realpath(os.path.join(os.getcwd(), os.path.dirname(__file__)))
	templateFile = os.path.join(__location__, templatePath)
	if not os.path.isfile(filePath):
		# create file
		file = open(filePath, 'a')
		file.close()
		# fill from template
		with open(templateFile) as f:
			lines = f.readlines()
			with open(filePath, "w") as f1:
				f1.writelines(lines)

def openFile(path):
	window = sublime.active_window();
	curFolder = window.folders()[0];
	if path[0] == '/':
		path = path[1:];
	path = os.path.join(curFolder,path);
	window.open_file(path);

def BitrixOpenFileFromSelectedList(index):
	if index == -1: return
	window.open_file(selectedList[index]["path"])

#	open const files
class BitrixOpenHeaderCommand(sublime_plugin.TextCommand):
	def run(self, edit):
		global selectedList;
		selectedList = pathsToPaths([
			["$|folder|bitrix|local", "templates","$template", "header.php"],
		])
		panelList = [c["folder"]+" : "+c["template"] for c in selectedList]
		window.show_quick_panel(panelList, BitrixOpenFileFromSelectedList)
class BitrixOpenFooterCommand(sublime_plugin.TextCommand):
	def run(self, edit):
		global selectedList;
		selectedList = pathsToPaths([
			["$|folder|bitrix|local", "templates","$template", "footer.php"],
		])
		panelList = [c["folder"]+" : "+c["template"] for c in selectedList]
		window.show_quick_panel(panelList, BitrixOpenFileFromSelectedList)
class BitrixOpenStylesheetCommand(sublime_plugin.TextCommand):
	def run(self, edit):
		global selectedList;
		selectedList = pathsToPaths([
			["$|folder|bitrix|local", "templates","$template", "template_styles.css"],
			["$|folder|bitrix|local", "templates","$template", "css", "$|file|custom.css|style.css"],
		])
		selectedList = [c for c in selectedList if os.path.exists(c["path"])]
		panelList = []
		for c in selectedList:
			if 'file' in c:
				panelList.append(c["folder"]+" : "+c["template"]+"/css/"+c['file'])
			else:
				panelList.append(c["folder"]+" : "+c["template"]+"/template_styles.css")
		window.show_quick_panel(panelList, BitrixOpenFileFromSelectedList)
class BitrixOpenJsCommand(sublime_plugin.TextCommand):
	def run(self, edit):
		global selectedList;
		selectedList = pathsToPaths([
			["$|folder|bitrix|local", "templates","$template", "js", "$|file|main.js|ajax.js|custom.js"],
		])
		selectedList = [c for c in selectedList if os.path.exists(c["path"])]
		panelList = [c["folder"]+" : "+c["template"]+"/js/"+c["file"] for c in selectedList]
		window.show_quick_panel(panelList, BitrixOpenFileFromSelectedList)
class BitrixOpenInitCommand(sublime_plugin.TextCommand):
	def run(self, edit):
		global selectedList;
		selectedList = pathsToPaths([
			["$|folder|bitrix|local", "php_interface", "init.php"],
		])
		selectedList = [c for c in selectedList if os.path.exists(c["path"])]
		panelList = [c["folder"] for c in selectedList]
		if len(selectedList) == 1:
			openFile(selectedList[0]["path"])
		else:
			window.show_quick_panel(panelList, BitrixOpenFileFromSelectedList)

#	in component menu
class BitrixTemplateMenuCommand(sublime_plugin.WindowCommand):
	def getPathList(self):
		window = sublime.active_window();
		curFolder = window.folders()[0];
		view = window.active_view();
		file = view.file_name();
		templateFolder = os.path.dirname(file);
		# print(os.path.basename(os.path.dirname(templateFolder)));

		pathList = [];
		files = filter(lambda x: os.path.isfile(os.path.join(templateFolder,x)), os.listdir(templateFolder));
		pathList += filter(lambda x: x != os.path.basename(file), files);
		# pprint(pathList);
		if os.path.basename(os.path.dirname(templateFolder)) == "templates":
			componentPath = os.path.dirname(os.path.dirname(templateFolder));
			if os.path.exists(componentPath):
				componentFiles = filter(lambda x: os.path.isfile(os.path.join(componentPath,x)), os.listdir(componentPath));
				pathList += map(lambda x: '../../'+x, componentFiles);

		if "template.php" in os.listdir(templateFolder):
			if "component_epilog.php" not in os.listdir(templateFolder):
				pathList += ["create:component_epilog.php"]
			if "result_modifier.php" not in os.listdir(templateFolder):
				pathList += ["create:result_modifier.php"]
		return pathList;
	def run(self):
		window = sublime.active_window();
		window.show_quick_panel(self.getPathList(), self.on_chosen)
	def on_chosen(self, index):
		window = sublime.active_window();
		curFolder = window.folders()[0];
		view = window.active_view();
		file = view.file_name();
		templateFolder = os.path.dirname(file);
		if index == -1: return
		# if not isView(self.vid):
		# 	sublime.status_message('You are in a different view.')
		# 	return
		el = self.getPathList()[index];
		if "create:" not in el :
			while '../' in el :
				el = el[3:];
				templateFolder = os.path.dirname(templateFolder);
			window.open_file(os.path.join(templateFolder,el));
		else:
			el=el.split(":")[1];
			createFileFromTemplate(os.path.join(templateFolder,el), 't'+el[0].upper()+'.php', '');
			window.open_file(os.path.join(templateFolder,el));
class BitrixComponentMenuCommand(sublime_plugin.WindowCommand):
	def getPathList(self):
		window = sublime.active_window();
		curFolder = window.folders()[0];
		view = window.active_view();
		file = view.file_name();
		componentFolder = os.path.dirname(file);
		templateFolder = os.path.join(componentFolder,"templates");
		pathList = [];
		pathList += filter(lambda x: os.path.isfile(os.path.join(componentFolder,x)), os.listdir(componentFolder));
		if os.path.exists(templateFolder):
			tmplList = os.listdir(templateFolder);
			for template in tmplList:
				curDir = os.path.join(templateFolder,template);
				fList = filter(lambda x: os.path.isfile(os.path.join(curDir,x)), os.listdir(curDir));
				pathList += map(lambda x: "templates/"+template+"/"+x, fList);
		return pathList;
	def run(self):
		window = sublime.active_window();
		# curFolder = window.folders()[0];
		# self.getPathList();
		window.show_quick_panel(self.getPathList(), self.on_chosen)
	def on_chosen(self, index):
		window = sublime.active_window();
		curFolder = window.folders()[0];
		view = window.active_view();
		file = view.file_name();
		componentFolder = os.path.dirname(file);
		templateFolder = os.path.join(componentFolder,"templates");
		curFolder = os.path.dirname(file);
		if index == -1: return
		# if not isView(self.vid):
		# 	sublime.status_message('You are in a different view.')
		# 	return
		el = self.getPathList()[index];
		if "create:" not in el :
			while '../' in el :
				el = el[3:];
				templateFolder = os.path.dirname(templateFolder);
			# pprint(curFolder +el);
			window.open_file(os.path.join(curFolder,el));
		else:
			el=el.split(":")[1];
			createFileFromTemplate(os.path.join(templateFolder,el), 't'+el[0].upper()+'.php', '');
			window.open_file(os.path.join(templateFolder,el));

# already not needed
class BitrixOpenClassCommand(sublime_plugin.TextCommand):
	def run(self, edit):
		window = sublime.active_window()
		curFolder = window.folders()[0]
		data = parseWord(self)
		# print(data)
		# window.open_file(filePath)
		openFile('/bitrix/templates/main/template_styles.css');
		search = '\.'+data['class']+'[\s]*[{]([^}]*)[}]';
		fResult = window.active_view().find(search,0);
		window.active_view().show_at_center(fResult);


import cv2
import matplotlib.pyplot as plt
import numpy as np
import math
import heapq as hq
import time
from collections import defaultdict
def obstacle_space(width,height,canvas,robot_radius,clearance):
    obstacle_matrix = {}
    '''
    Creating a obstacle space with clearance of 5mm in the map and
    initialising all the coordinates in obstacle space with a cost of -1 and
    all coordinates in free space with a cost of 'inf' initially.

    The factor of offset that should be multiplied in the line equation is calculated by comparing
    the y-intercepts of two parallel lines.
    '''
    if(robot_radius > 5 or robot_radius < 0):
        robot_radius = 5
    if(clearance > 5 or clearance < 0):
        clearance = 5
    offset  = robot_radius+clearance
    for x in range(width):
        for y in range(height):
          #Obstacle map and matrix formation with offset consideration
           # #First Rectangle
            r1c = (x+offset>=100 and x-offset<=150) and (y+offset>=0 and y-offset<=100)
            #second Rectangle
            r2c = (x+offset>=100 and x-offset<=150) and (y+offset>=150 and y-offset<=250)
            #Hexagon, representing as sides 's'
            s1c = (x+(1.18*offset)-235>=0)
            s2c = (y+(offset*1.18)+0.576*(x) -223.07 >=0)
            s3c = (0.569*(x)-y-(1.18*offset)-120.90<=0)
            s4c = (x-offset-364.95 <=0)
            s5c = (0.577*(x)+y-(1.18*offset)-373.21<=0)
            s6c = (0.576*(x)-y+(1.18*offset)+26.923 >=0)
            #triangle
            l1c = (x+offset-460>=0)
            l2c = (2*(x)-(2.816*offset)-y-895<=0)
            l3c = (2*(x)-(2.816*offset)+y-1145<=0)
            if(r1c or r2c or (s1c and s2c and s3c and s4c and s5c and s6c) or (l1c and l2c and l3c)):
                obstacle_matrix[(x,y)] = -1
                canvas[y,x] = (0,120,255)
            #Creating Boundary with clearance of 5mm
            elif(((y-offset <=0) or (y-250+offset >=0))) :
                obstacle_matrix[(x,y)] = -1
                canvas[y,x] = (0,120,255)
            elif(((x-offset <=0) or (x-600+offset >=0))) :
                obstacle_matrix[(x,y)] = -1
                canvas[y,x] = (0,120,255)
            else:
                obstacle_matrix[(x,y)] = math.inf

          #Highlight the original obstacles without clearance with different colour
            # #First Rectangle
            r1 = (x>=100 and x<=150) and (y>=0 and y<=100)
            #second Rectangle
            r2 = (x>=100 and x<=150) and (y>=150 and y<=250)
            #Hexagon, representing as sides 's'
            s1 = (x-235>=0)
            s2 = (y+0.576*x -223.07 >=0)
            s3 = (0.569*x-y-120.90<=0)
            s4 = (x-364.95 <=0)
            s5 = (0.577*x+y-373.21<=0)
            s6 = (0.576*x-y+26.923 >=0)
            #triangle
            l1 = (x-460>=0)
            l2 = (2*x- y-895<=0)
            l3 = (2*x+y-1145<=0)
            if(r1 or r2 or (s1 and s2 and s3 and s4 and s5 and s6) or (l1 and l2 and l3)):
                canvas[y,x] = (0,0,255)
    # plt.imshow(canvas)
    return obstacle_matrix,canvas
def get_start_goal_inputs(obstacle_matrix):

    while True:
        print("Enter the x-coordinate of start node")
        start_x = int(input())
        print("Enter the y-coordinate of start node")
        start_y = int(input())
        if((start_x <= 0 or start_x > 599) ):
            print("The X-coordinate of start node is out of the map. Please enter the coordinates again")
        elif((start_y <= 0 or start_y >249)):
            print("The Y-coordinate of start node is out of the map. Please enter the coordinates again")
        elif(obstacle_matrix[(start_x,250-start_y)] == -1):
            print("The entered start node falls in obstacle space")
        else:
            break
    while True:
        print("Initial Orientation of start node of robot(Angle in multiple of 30)")
        start_angle = int(input())
        if(start_angle %3 != 0):
            print("Please enter correct angle ")
        else:
            if(start_angle <30 ):
                start_angle = 360+start_angle
            break
    while True:
        print("Enter the x-coordinate of goal node")
        goal_x = int(input())
        print("Enter the y-coordinate of goal node")
        goal_y = int(input())
        if(goal_x <= 0 or goal_x >599):
            print("The X-coordinate of start node is out of the map. Please enter the coordinates again")
        elif(goal_y <= 0 and goal_y > 249):
            print("The Y-coordinate of start node is out of the map. Please enter the coordinates again")
        elif(obstacle_matrix[(goal_x,250-goal_y)] == -1):
            print("The entered goal node falls in obstacle space")
        else:
            break
    while True:
        print("Goal Orientation of goal node of robot(Angle in multiple of 30)")
        goal_angle = int(input())
        if(goal_angle %3 != 0):
            print("Please enter correct angle ")
        else:
            if(goal_angle <30 ):
                goal_angle = 360+goal_angle
            break
    return (start_x,start_y,start_angle,goal_x,goal_y,goal_angle)
def get_robot_inputs():
    while True:
        print("Enter the radius of the robot (0-5)")
        robot_radius = int(input())
        if(robot_radius>=0):
            break
    while True:
        print("Enter the clearance of the robot (0-5)")
        clearance = int(input())
        if(clearance>=0):
            break
    while True:
        print("Enter the step-size of the robot (1-10)")
        step_size = int(input())
        if(step_size<1 or step_size>10):
            print("Please enter valid step_size")
        else:
            break
    return robot_radius,clearance,step_size
'''
5 Move Actions with thetas in {0,30,60,-30,-60}
For Each move action, theta is added to current angle and the coordinates of the new node are found out.
Each movie action also checks whether the node is in obstacle space or not.
'''
def move_0(obstacle_matrix,current_node,step):
    flag = True
    current_node = list(current_node)
    temp_new_node = current_node.copy()
    new_angle = temp_new_node[2] + 0
    if(new_angle < 0):
        new_angle = new_angle+360
    new_x = round((temp_new_node[0] + (step*np.cos(np.radians(new_angle))))*2)/2
    new_y = round((temp_new_node[1] + (step*np.sin(np.radians(new_angle))))*2)/2
    if((round(new_x) >0 and round(new_x) < 600) and (round(new_y) >0 and round(new_y) < 250) and (obstacle_matrix[(int(round(new_x)),int(round(new_y)))] != -1)):
        flag =  True
    else:
        flag = False
        new_node = (new_x,new_y,new_angle)
        return flag,new_node
    new_node = (new_x,new_y,new_angle)
    return flag,new_node
def move_plus_30(obstacle_matrix,current_node,step):
    flag = True
    current_node = list(current_node)
    temp_new_node = current_node.copy()
    new_angle = temp_new_node[2] + 30
    if(new_angle < 0):
        new_angle = new_angle+360
    new_x = round((temp_new_node[0] + (step*np.cos(np.radians(new_angle))))*2)/2
    new_y = round((temp_new_node[1] + (step*np.sin(np.radians(new_angle))))*2)/2
    if((round(new_x) >0 and round(new_x) < 600) and (round(new_y) >0 and round(new_y) < 250) and (obstacle_matrix[(int(round(new_x)),int(round(new_y)))] != -1)):
        flag =  True
    else:
        flag = False
        new_node = (new_x,new_y,new_angle)
    new_node = (new_x,new_y,new_angle)
    return flag,new_node
def move_plus_60(obstacle_matrix,current_node,step):
    flag = True
    current_node = list(current_node)
    temp_new_node = current_node.copy()
    new_angle = temp_new_node[2] + 60
    if(new_angle < 0):
        new_angle = new_angle+360
    new_x = round((temp_new_node[0] + (step*np.cos(np.radians(new_angle))))*2)/2
    new_y = round((temp_new_node[1] + (step*np.sin(np.radians(new_angle))))*2)/2
    if((round(new_x) >0 and round(new_x) < 600) and (round(new_y) >0 and round(new_y) < 250) and (obstacle_matrix[(int(round(new_x)),int(round(new_y)))] != -1)):
        flag =  True
    else:
        flag = False
        new_node = (new_x,new_y,new_angle)
        return flag,new_node
    new_node = (new_x,new_y,new_angle)
    return flag,new_node
def move_minus_30(obstacle_matrix,current_node,step):
    flag = True
    current_node = list(current_node)
    temp_new_node = current_node.copy()
    new_angle = temp_new_node[2] -30
    if(new_angle < 0):
        new_angle = new_angle+360
    new_x = round((temp_new_node[0] + (step*np.cos(np.radians(new_angle))))*2)/2
    new_y = round((temp_new_node[1] + (step*np.sin(np.radians(new_angle))))*2)/2
    if((round(new_x) >0 and round(new_x) < 600) and (round(new_y) >0 and round(new_y) < 250) and (obstacle_matrix[(int(round(new_x)),int(round(new_y)))] != -1)):
        flag =  True
    else:
        flag = False
        new_node = (new_x,new_y,new_angle)
        return flag,new_node
    new_node = (new_x,new_y,new_angle)
    return flag,new_node
def move_minus_60(obstacle_matrix,current_node,step):
    flag = True
    current_node = list(current_node)
    temp_new_node = current_node.copy()
    new_angle = temp_new_node[2] - 60
    if(new_angle < 0):
        new_angle = new_angle+360
    new_x = round((temp_new_node[0] + (step*np.cos(np.radians(new_angle))))*2)/2
    new_y = round((temp_new_node[1] + (step*np.sin(np.radians(new_angle))))*2)/2
    if((round(new_x) >0 and round(new_x) < 600) and (round(new_y) >0 and round(new_y) < 250) and (obstacle_matrix[(int(round(new_x)),int(round(new_y)))] != -1)):
        flag =  True
    else:
        flag = False
        new_node = (new_x,new_y,new_angle)
        return flag,new_node
    new_node = (new_x,new_y,new_angle)
    return flag,new_node
'''
This Function Calculates the cost to goal between current and goal nodes using Euclidean Distance Formula
'''
def cost_2_goal(start_x,start_y,goal_x,goal_y):
    point_1 = np.array((start_x,start_y))
    point_2 = np.array((goal_x,goal_y))
    cost = np.linalg.norm(point_1-point_2)
    return cost
'''
To check whether the node is already visited. If so, returns true and updates the total cost if its less
'''
def check_duplicate(new_node,visited_matrix):
    if(new_node[0] > 599 or new_node[1] > 249):
        return True
    angle = new_node[2]
    if(angle>=360):
        angle%=360
    if(visited_matrix[int(new_node[0]*2)][int(new_node[1]*2)][int(angle/30)] == 0):
        visited_matrix[int(new_node[0]*2)][int(new_node[1]*2)][int(angle/30)] = 1
        return False,visited_matrix
    else:

        return True,visited_matrix

def astar(obstacle_matrix,start_x,start_y,start_theta,goal_x,goal_y,goal_theta,step):
    visited_matrix = np.zeros((1200,500,12))
    closed_list = {} #List of nodes explored
    open_list = []
    explored_dict = defaultdict(list) #Used for node explore visualisation where each key is a parent node with all child nodes appended
    child_parent_dict = {} #Used for backtracking and to get the optimal path
    parent_node = (start_x,start_y,start_theta)
    initial_cost_2_come = 0
    initial_cost_2_goal = cost_2_goal(start_x,start_y,goal_x,goal_y)
    total_cost = initial_cost_2_come+initial_cost_2_goal
    hq.heapify(open_list)
    hq.heappush(open_list,[total_cost,initial_cost_2_come,parent_node,(start_x,start_y,start_theta)])
    count = 0
    goal_reached = False
    explored_dict[parent_node].append((parent_node))
    while(len(open_list)>0):
        cn=hq.heappop(open_list)
        current_node = cn[3]
        parent_node = cn[2]
        current_cost2c = cn[1]
        current_total_cost = cn[0]
        closed_list[current_node] = cn[2]
        explored_dict[(int(parent_node[0]),int(parent_node[1]),int(parent_node[2]))].append((int(current_node[0]),int(current_node[1]),int(current_node[2])))
        child_parent_dict[((current_node[0]),(current_node[1]))] = ((parent_node[0]),(parent_node[1]))
        goal_check_distance = np.sqrt(((goal_y-current_node[1])**2)+((goal_x-current_node[0])**2))
        if(goal_check_distance<1.5):
            goal_reached = True
            print("Goal Reached, Starting Back Track")
            break
        action_set = {move_0:"move_zero",move_plus_30:"move_plus_thirty",move_plus_60:"move_plus_sixty",move_minus_30:"move_minus_thirty",move_minus_60:"move_minus_60"}

        for action,action_value in action_set.items():
            flag,new_node = action(obstacle_matrix,current_node,step)
            if(flag):
                if(new_node not in closed_list):
                    check_duplicate_flag,visited_matrix = check_duplicate(new_node,visited_matrix)
                    if(check_duplicate_flag):
                        for i in open_list:
                            if (new_node == i[3]):
                                cost = current_cost2c+step+cost_2_goal(new_node[0],new_node[1],goal_x,goal_y)
                                if(cost < i[0]):
                                    i[0] = cost
                                    i[1] = step+current_cost2c
                                    i[2] = cn[2]
                                    hq.heapify(open_list)
                                    child_parent_dict[(int(new_node[0]),int(new_node[1]))] = (int(current_node[0]),int(current_node[1]))
                                break
                    else:
                        cost = current_cost2c+step+cost_2_goal(new_node[0],new_node[1],goal_x,goal_y)
                        c2c = current_cost2c+step
                        node_to_push = [cost,c2c,current_node,new_node]
                        hq.heappush(open_list,node_to_push)
                        # explored_dict[(int(current_node[0]),int(current_node[1]),int(current_node[2]))].append((int(new_node[0]),int(new_node[1]),int(new_node[2])))
                        hq.heapify(open_list)

        count += 1
    return(child_parent_dict,goal_reached,closed_list,explored_dict,closed_list)
'''
Backtracking using the child parent dictionary relationship got from the exploration
'''
def back_track(child_parent_dict,start_x,start_y,start_theta,goal_x,goal_y,goal_theta):
    start = (start_x,start_y)
    optimal_list = []
    optimal_list.append((goal_x,goal_y))
    if((float(goal_x),float(goal_y)) in child_parent_dict.keys()):
        current = (float(goal_x),float(goal_y))
    else:
        last_key = list(child_parent_dict)[-1]
        current = last_key
    while(start!=current):
        if (current in child_parent_dict.keys()):
            optimal_list.append(child_parent_dict[current])
            current = child_parent_dict[current]
        else:
            break
    return optimal_list[::-1]
'''
Visualizing and saving the video using OpenCV
'''
def visualise(canvas,optimal_list,explored_dict,closed_list,child_parent_dict):
    fourcc = cv2.VideoWriter_fourcc(*'XVID')
    out = cv2.VideoWriter('A-Star.avi',fourcc,250,(canvas.shape[1],canvas.shape[0]))
    # for key,value in child_parent_dict.items():
    #     cv2.arrowedLine(canvas, (int(value[0]),int(value[1])), (int(key[0]),int(key[1])), (255,255,255), 1,tipLength=0.5)
    #     out.write(canvas)
    for key,values in explored_dict.items():
        for i in values:
            pt1 = key[:2]
            pt2 = i[:2]
            cv2.arrowedLine(canvas, pt1, pt2, (255,255,255), 1,tipLength=0.5)
        # cv2.imshow("Exploration",canvas)
        out.write(canvas)
        cv2.waitKey(1)
    # for key,value in closed_list.items():
    #     parent_pt = (int(value[0]),int(value[1]))
    #     child_pt = (int(key[0]),int(key[1]))
    #     cv2.arrowedLine(canvas, parent_pt, child_pt, (255,255,255), 1)
    #     out.write(canvas)
    for i in range(len(optimal_list)-1):
        pt1 = (int(optimal_list[i][0]),int(optimal_list[i][1]))
        pt2 = (int(optimal_list[i+1][0]),int(optimal_list[i+1][1]))
        cv2.line(canvas, pt1, pt2, (0,255,0), 1,cv2.LINE_AA)
        # cv2.imshow("Optimal",canvas)
        # cv2.waitKey(1)
        out.write(canvas)
    for i in range(500):
        out.write(canvas)
    out.release()
    cv2.destroyAllWindows()
    plt.imshow(canvas)
def main():
    canvas = np.ones((250,600,3),dtype='uint8')
    robot_radius,clearance,step_size = get_robot_inputs()
    obstacle_matrix,canvas = obstacle_space(600,250,canvas,robot_radius,clearance)
    start_x,start_y,start_theta,goal_x,goal_y,goal_theta = get_start_goal_inputs(obstacle_matrix)

    # #Changing the y-coordinates in relation to image coordinates
    start_y = 250-start_y
    goal_y = 250-goal_y
    print(f"The start node selected : {(start_x,start_y,start_theta)}. The goal node selected : {(goal_x,goal_y,goal_theta)}")
    start_time = time.time()
    child_parent_dict,goal_reached,closed_list,explored_dict,closed_list = astar(obstacle_matrix,start_x,start_y,start_theta,goal_x,goal_y,goal_theta,step_size)
    end_time = time.time()
    print(f"Time Taken By the Algorithm : {end_time - start_time} seconds")
    if(goal_reached == False):
        print("No Goal Found")
        return
    print("The length of visited or explored list",len(closed_list))
    optimal_list = back_track(child_parent_dict,start_x,start_y,start_theta,goal_x,goal_y,goal_theta)
    print("The Optimal Path Node:",optimal_list)
    visualise(canvas,optimal_list,explored_dict,closed_list,child_parent_dict)
if __name__ == '__main__':

    main()


import json
import re
import math
import csv

# Como cada linea es un documento, los separa por lineas usando \n como marcador. Crea un array de documentos
def readDocs(filename):
  with open(filename, "r") as documentos:
    file = documentos.read()
    documentos = file.split("\n")

    return documentos

# Version para la lista de lematizacion, lo lee como un diccionario JSON y crea una lista de tuplas de dos elementos
# para que sea más fácil usarlo como queremos
def readLema(filename):
  with open(filename, "r") as doc:
    data = json.load(doc)

  listaTuplas = [(key, value) for key, value in data.items()]

  return listaTuplas

def readCSV(filename):
  datos = []

  with open(filename, newline='') as tabla:
    csvReader = csv.reader(tabla)
    next(csvReader)

    for fila in csvReader:
      datos.append([int(fila[0]), fila[1], int(fila[2]), float(fila[3]), float(fila[4])])

  return datos

# Funcion para limpiar el documento de stop words, le pasamos la lista de stopwords leida con readDocs
# y el documento que queremos limpiar, busca las palabras que no coinciden y las mete en un array de palabras que luego une
def clearStopWords(documento, stopWords):

  palabras = documento.split()

  filtered_words = [word for word in palabras if word.lower() not in stopWords]

  cleanDoc = ' '.join(filtered_words)

  return cleanDoc

# Version de la limpieza de stopwords que recorre la lista de palabras buscando las que coinciden con el primer elemento
# de las tuplas de la lista de lematización para reemplazarlo por el segundo.
def lematizacion(cleanDoc, listaLematizacion):
  palabras = cleanDoc.split()

  for i in range(len(palabras)):

    word = palabras[i].lower()

    for lema, sustituto in listaLematizacion:
      if word == lema:
        palabras[i] = sustituto

  updatedDoc = ' '.join(palabras)

  return updatedDoc

def separarPalabras(texto):
  # Utiliza una expresión regular para encontrar palabras (secuencias de letras y apóstrofes)
  palabras = re.findall(r'\b\w+\b', texto)
  return palabras

def agregarTerminosConjunto(conjuntoTerminos, arrayTerminos):
  for palabra in arrayTerminos:
    conjuntoTerminos.add(palabra)
  return conjuntoTerminos

def convertirAMinusculas(cadenas):
  # Aplica lower() a cada cadena en el vector
  cadenasMinusculas = [cadena.lower() for cadena in cadenas]
  return cadenasMinusculas

# Cuenta cuántas veces aparece el término en el documento
def calcularTF(termino, documento):
  tf = documento.count(termino)
  return tf

def calcularIDF(termino, palabrasPorDocumentos):
  # Cuenta cuántos documentos contienen la termino
  numeroDocumentosConTermino = sum(1 for documento in palabrasPorDocumentos if termino in documento)
  # Calcula el IDF utilizando el logaritmo neperiano
  idf = math.log(len(palabrasPorDocumentos) / (numeroDocumentosConTermino))
  return idf

def crearTablaDocumento(tabla, nombreArchivo):
  # Abre el archivo en modo de escritura
  with open(nombreArchivo, mode='w', newline='') as archivo_csv:
    # Crea un escritor CSV
    escritor = csv.writer(archivo_csv)
    # Escribe la fila de encabezado
    escritor.writerow(["Índice del término", "Término", "TF", "IDF", "TF-IDF"])

    # Escribe las filas de datos desde la tabla
    for fila in tabla:
      escritor.writerow(fila)

def crearTablaCoseno(tabla, nombreCoseno):

  with open(nombreCoseno, mode="w", newline='') as tabla_coseno:

    escritor = csv.writer(tabla_coseno)

    escritor.writerow(["Primer Documento", "Segundo Documento", "Similaridad Coseno"])

    for fila in tabla:
      escritor.writerow(fila)

def calcularCoseno(doc1, doc2):
  magnitud1 = math.sqrt(sum(termino[1]**2 for termino in doc1))
  magnitud2 = math.sqrt(sum(termino[1]**2 for termino in doc2))

  norm1 = [(termino[0], termino[1]/magnitud1) for termino in doc1]
  norm2 = [(termino[0], termino[1]/magnitud2) for termino in doc2]

  similaridad = 0

  for termino in norm1:
    for otherTermino in norm2:
      if termino[0] == otherTermino[0]:
        similaridad += (termino[1] * otherTermino[1])

  return similaridad

def terminoPerteneceMatriz(termino, matriz):
  for fila in matriz:
    if termino == fila[1]:
      return True
  return False


import yeti
import asyncio

class DriveAuto(yeti.Module):

    def module_init(self):
        self.drivetrain = self.engine.get_module("advanced_drive")
        self.intake = self.engine.get_module("advanced_intake")
        self.debug.set_code((True, False, False), "disabled")
        self.debug.set_auto_steps(4)

    @yeti.singleton
    async def autonomous_init(self):
        print("CHARGE!")
        self.drivetrain.reset_encoders()
        self.debug.set_auto_progress(0)
        await self.intake.wait_for_setpoint(0)
        self.debug.set_auto_progress(1)
        await self.drivetrain.drive_straight_to(10, -0.65)
        self.debug.set_auto_progress(2)
        # Release ball
        await self.intake.run_intake_for(1, 10)
        self.debug.set_auto_progress(3)


# coding=utf-8
# Program:
#         封装滚动条常用操作的一些公共方法
# Histroy:
# 2017/10/29 Royfans First release
from selenium import webdriver
import time
class Scrollaction(object):
    """

    """
    def __init__(self, driver):
        self.driver = driver
    # 滚动到最顶部
    def scroll_top(self):
        js = "window.scrollTo(0,0)"
        self.driver.execute_script(js)
    # 滚动到最底部
    def scroll_bottom(self):
        js = "window.scrollTo(0,document.body.scrollHeight)"
        self.driver.execute_script(js)
    # 聚焦元素
    def scroll_id(self,id):
        target = driver.find_element_by_id(id)
        self.driver.execute_script("arguments[0].scrollIntoView();", target)

if __name__ == "__main__":
    driver = webdriver.Chrome()
    sa = Scrollaction()
    driver.get("http://www.cnblogs.com/yoyoketang/p/6128655.html")
    time.sleep(3)
    sa.scroll_bottom()
    time.sleep(2)
    sa.scroll_top()
    time.sleep(2)
    driver.close()


import os
import random
import cv2
import numpy as np
import pickle
from sklearn.utils import shuffle
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report
from sklearn.svm import SVC
import imgaug as ia
import imgaug.augmenters as iaa
ia.seed(1)

path ='datasets/classify'
labels = os.listdir(os.path.join(path))

dic = {}
for k,l in enumerate(labels):
    dic[k]=l
print(dic)
dic_invert = {v:k for k,v in dic.items()}
print(dic_invert)

augmentation = iaa.Sequential([
    # 1. Flip
    iaa.Fliplr(0.5),
    iaa.Flipud(0.5),
    # 2. Linearcontrast
    iaa.LinearContrast((0.8, 1.2)),
    # 3. Perform methods below only sometimes
    iaa.Sometimes(0.5,
    # 4. GaussianBlur
    iaa.GaussianBlur((0.0, 3.0))
    )
    ])

N = 2000
X = []
y = [] #0,1,2,3,4
for k,label in enumerate(labels):
    images = os.listdir(os.path.join(path,label))
    m = len(images)
    n = N//m
    for image in images:
        img = cv2.imread(os.path.join(path,label,image),0)
        imgs = np.array([ img for _ in range(n)],dtype=np.uint8)
        imaugs = augmentation(images=imgs)
        for aug in imaugs:
            X.append(aug)
            y.append(k)

X = np.array(X).reshape(len(X),-1)
# shuffle
X,y = shuffle(X,y)
# norm
X = X/255.0
y = np.array(y)

# split
X_train, X_val, y_train, y_val = train_test_split(X,y)
print("X_train",X_train.shape)
print("X_val",X_val.shape)
print("y_train",y_train.shape)
print("y_val",y_val.shape)

svc = SVC(kernel='linear',gamma='auto') #linear,rbf
svc.fit(X_train, y_train)

pred = svc.predict(X_val)

print("Accuracy on unknown data is",classification_report(y_val,pred))

# save the model to disk
filename = 'model/classify/model.sav'
pickle.dump(svc, open(filename, 'wb'))


import os
import pytest
from selenium import webdriver
from . import config, credentials

# Em um novo projeto, o que mudaria seria apenas os valores default e help (explicação) abaixo
def pytest_addoption(parser):
    parser.addoption('--baseurl',
                     action='store',
                     default='https://the-internet.herokuapp.com',
                     help='endereço dos site alvo do teste'
                     )
    parser.addoption('--host',
                     action='store',
                     default='saucelabs',
                     help='ambiente em que vou executar os testes'
                     )
    parser.addoption('--browser',
                     action='store',
                     default='chrome',
                     help='navegador padrão'
                     )
    parser.addoption('--browserversion',
                     action='store',
                     default='97.0',
                     help='versão do navegador padrão'
                     )
    parser.addoption('--platform',
                     action='store',
                     default='Windows 10',
                     help='Versão do Sistema Operacional'
                     )

@pytest.fixture
def driver(request):
    config.baseurl = request.config.getoption('--baseurl')
    config.host = request.config.getoption('--host')
    config.browser = request.config.getoption('--browser')
    config.browserversion = request.config.getoption('--browserversion')
    config.platform = request.config.getoption('--platform')

    # Configuração para executar no SauceLabs (Nuvem)
    if config.host == 'saucelabs':
        test_name = request.node.name  # adicionar o nome do teste baseado no script
        capabilities = {
            'browserName': config.browser,
            'browserVersion': config.browserversion,
            'platformName': config.platform,
            'sauce:options': {
                'name': test_name  # nome do teste conforme acima
            }
        }
        # credenciais
        _credentials = credentials.SAUCE_USERNAME + ':' + credentials.SAUCE_ACCESS_KEY
        _url = 'https://' + _credentials + '@ondemand.us-west-1.saucelabs.com:443/wd/hub'

        # chamada para o SauceLabs
        driver_ = webdriver.Remote(_url, capabilities)

    else:  # configuração para execução local / localhost

        # no Chrome
        if config.browser == 'chrome':
            _chromedriver = os.path.join(os.getcwd(), 'vendor', 'chromedriver.exe')
            if os.path.isfile(_chromedriver):
                driver_ = webdriver.Chrome(_chromedriver)  # vai usar o driver dentro da pasta vendor
            else:
                driver_ = webdriver.Chrome()  # vai usar o chromedriver apontado nas variaveis de ambiente
        # no Firefox
        elif config.browser == 'firefox':
            _geckodriver = os.path.join(os.getcwd(), 'vendor', 'geckodriver.exe')
            if os.path.isfile(_geckodriver):
                driver_ = webdriver.Firefox(_geckodriver)  # vai usar o driver dentro da pasta vendor
            else:
                driver_ = webdriver.Firefox()  # vai usar o geckodriver apontado nas variaveis de ambiente

    def quit():  # sub-função para finalizar o objeto do Selenium
        # atualização do status de passou ou falhou
        # regra para marcar se passou ou falho baseado no retorno da requisição
        sauce_result = 'failed' if request.node.rep_call.failed else 'passed'
        # executar um script no SauceLabs que sinaliza para o nosso terminal o resultado baseado na regra
        driver_.execute_script('sauce:job-result={}'.format(sauce_result))
        # desliga o Selenium
        driver_.quit()

    # configura a requisição para que ela execute a subfunção de quit ao finalizar a requisição/job
    request.addfinalizer(quit)

    # retorna o Selenium turbinado (com essas novas configurações e regras) - Sobreposição
    return driver_

# configurar o gatilho para a geração do relatório
@pytest.hookimpl(hookwrapper=True, tryfirst=True)  # ativa o gatilho e no momento da inicialização da requisição
def pytest_runtest_makereport(item, call):
    outcome = yield
    rep = outcome.get_result()  # variavel de relatório que irá guardar o resultado

    # atributos do relatório
    setattr(item, 'rep_' + rep.when, rep)


import numpy as np

# internal

# 1. Global vars ===============================================================

# 1.1 Classes ------------------------------------------------------------------
class TSTrapeze():     # simple way of generating a trapezoid time series from parts

    def __init__(self, t_start=None, t_rise=None, t_fall=None, t_end=None, h=None):
        self.t_start = t_start  # [sec] time from zero to the start of the trapeze
        self.t_rise  = t_rise   # [sec] time from t_start to reaching 'h1'
        self.t_fall  = t_fall   # [sec] time from 'h1' to 'h2'
        self.t_end   = t_end    # [sec] time from 'h2' to end of trapezoid
        self.h_1     = h        # [cm] starting height
        self.h_2     = h        # [cm] ending height

    def check(self):
        flag   = True   # false == not ok
        string = ''     # accumulated string

        if (self.t_start >= self.t_rise):
            string += '\n- t_start >= t_rise'
            flag = False

        if (self.t_rise >= self.t_fall):
            string += '\n- t_rise >= t_fall'
            flag = False

        if (self.t_fall >= self.t_end):
            string += '\n- t_fall >= t_end'
            flag = False

        if not(flag):
            print('ts_trapeze: error in set data')
            print(string)
            print(self.to_info_string())
            exit(255)

    def to_info_string(self):
        string = ''
        string += '\n'
        string += '\nt_start: ' + self.t_start
        string += '\nt_rise:  ' + self.t_rise
        string += '\nt_fall:  ' + self.t_fall
        string += '\nt_end:   ' + self.t_end
        string += '\nh_1:     ' + self.h_1
        string += '\nh_2:     ' + self.h_2

        return string

    def conv_to_arrays(self, override_array):

        arr_y = np.array([0.0, self.h_1, self.h_2, 0.0])
        arr_x = np.array([self.t_start, self.t_start + self.t_rise, self.t_start +
                          self.t_rise + self.t_fall, self.t_start + self.t_rise + self.t_fall + self.t_end])

        return arr_x, arr_y

    def set_variable_value(self, var, val):
        """
        Given the variable, sets a corresponding value
        """
        if (var == 'h1'):
            self.h_1 = val

        elif (var == 'h2'):
            self.h_2 = val

        elif (var == 'h'):
            self.h_1 = val
            self.h_2 = val

        elif (var == 't_start'):
            self.t_start = val

        elif (var == 't_rise'):
            self.t_rise = val

        elif (var == 't_fall'):
            self.t_fall = val

        elif (var == 't_end'):
            self.t_end = val

        else:
            print('\nError: ts_trapeze.set_variable_value:')
            print('Unknown variable target:', var)
            exit(255)

    def combine_trapeze(self, ts_trapeze):
        """
        Overwrites the entries in the 'main' ts_trapeze with content from the second one,
        if it has data.
        """
        if not(ts_trapeze.h_1 is None):
            self.h_1 = ts_trapeze.h_1

        if not(ts_trapeze.h_2 is None):
            self.h_2 = ts_trapeze.h_2

        if not(ts_trapeze.t_start is None):
            self.t_start = ts_trapeze.t_start

        if not(ts_trapeze.t_rise is None):
            self.t_rise = ts_trapeze.t_rise

        if not(ts_trapeze.t_fall is None):
            self.t_fall = ts_trapeze.t_fall

        if not(ts_trapeze.t_end is None):
            self.t_end = ts_trapeze.t_end

# 2. Functions =================================================================

# 3. Main Exec =================================================================


from pyfr.backends.base.generator import BaseGPUKernelGenerator

class OpenCLKernelGenerator(BaseGPUKernelGenerator):
    _lid = ('get_local_id(0)', 'get_local_id(1)')
    _gid = 'get_global_id(0)'
    _shared_prfx = '__local'
    _shared_sync = 'work_group_barrier(CLK_GLOBAL_MEM_FENCE)'

    def _render_spec(self):
        # We first need the argument list; starting with the dimensions
        kargs = [f'int {d}' for d in self._dims]

        # Now add any scalar arguments
        kargs.extend(f'{sa.dtype} {sa.name}' for sa in self.scalargs)

        # Finally, add the vector arguments
        for va in self.vectargs:
            if va.intent == 'in':
                kargs.append(f'__global const {va.dtype}* restrict '
                             f'{va.name}_v')
            else:
                kargs.append(f'__global {va.dtype}* restrict {va.name}_v')

            # Views
            if va.isview:
                kargs.append(f'__global const int* restrict {va.name}_vix')

                if va.ncdim == 2:
                    kargs.append('__global const int* restrict '
                                 f'{va.name}_vrstri')
            # Arrays
            elif self.needs_ldim(va):
                kargs.append(f'int ld{va.name}')

        # Determine the work group size for the kernel
        wgs = (*self.block1d, 1, 1) if self.ndim == 1 else (*self.block2d, 1)
        wgs = ', '.join(str(s) for s in wgs)
        kattrs = f'__kernel __attribute__((reqd_work_group_size({wgs})))'

        return '{0} void {1}({2})'.format(kattrs, self.name, ', '.join(kargs))


# https://leetcode.com/problems/copy-list-with-random-pointer/
# A linkedlist with random pointer to a node in list
# Copy linked list, use a copy to store new copy of node,
# Use second loop to set random pointer for new copied node
class RandomListNode(object):
    def __init__(self, x):
        self.label = x
        self.next = None
        self.random = None

class Solution(object):
    # Runtime O(n), space O(n)
    def copyRandomList(self, head):
        if not head:
            return None

        cache = {}
        curr = head

        newHead = RandomListNode(0)
        prev = newHead

        while curr:
            node = RandomListNode(curr.label)
            cache[curr] = node

            prev.next = node
            prev = node
            curr = curr.next

        curr = head
        while curr:
            node = cache[curr]
            random = cache.get(curr.random)
            node.random = random
            curr = curr.next
        return newHead.next

    # 3 steps: - 1: link node.next to copy, and copy.next to next
    # - 2: link copy node to its random, node.next.random = node.random.next
    # - 3: restore previous list: node.next = node.next.next
    def copyRandomList2(self, head):
        curr = head

        # Step 1
        while curr:
            nextNode = curr.next
            curr.next = RandomListNode(curr.label)
            curr.next.next = nextNode
            curr = nextNode

        # Step 2
        curr = head
        while curr:
            curr.next.random = curr.random
            curr = curr.next.next

        # Step 3
        curr = head
        newHead = RandomListNode(0)
        prev = newHead

        while curr:
            copy = curr.next
            nextNode = copy.next

            curr.next = nextNode
            prev.next = copy

            prev = prev.next
            curr = curr.next
        return newHead.next


'''
Descripttion: 业务管理系统
version: 1.0.0
Author: 邵佳泓
Date: 2022-07-13 13:00:59
LastEditors: 邵佳泓
LastEditTime: 2022-07-14 12:48:28
FilePath: /server/app/managers/visualize_manager/sentiment_manager.py
'''
from http import HTTPStatus
from flask_restx import Namespace, Resource, fields, reqparse
from flask_jwt_extended import jwt_required
from app.model import News, SenAna
from app.managers.model import standardmodel
from app.utils.limiter import limiter

sentiment_ns = Namespace('sentiment', description='情感度管理')
sentiment_ns.models[standardmodel.name] = standardmodel
sentiment_model = sentiment_ns.model(
    'sentimentmodel', {
        'name': fields.String(required=True, description='情感倾向'),
        'value': fields.Float(required=True, description='数量'),
    })
model = sentiment_ns.model(
    'sentimentinfo', {
        'code': fields.Integer(required=True, description='状态码'),
        'message': fields.String(required=True, description='状态信息'),
        'success': fields.Boolean(required=True, description='是否成功'),
        'data': fields.List(fields.List(fields.Nested(sentiment_model))),
    })
parser = reqparse.RequestParser(bundle_errors=True)
parser.add_argument('articleSource',
                    type=str,
                    location='args',
                    action="split",
                    default='',
                    help='articleSource用于绘制子图')

parser.add_argument('Authorization',
                    type=str,
                    location='headers',
                    nullable=False,
                    required=True,
                    help='Authorization不能为空')

@sentiment_ns.route('')
@sentiment_ns.response(int(HTTPStatus.BAD_REQUEST), "Validation error.", standardmodel)
@sentiment_ns.response(int(HTTPStatus.INTERNAL_SERVER_ERROR), "Internal server error.",
                       standardmodel)
@sentiment_ns.response(int(HTTPStatus.TOO_MANY_REQUESTS), "visit too fast.", standardmodel)
class SentimentInfo(Resource):
    '''
    Author: 邵佳泓
    msg: 情感信息
    '''
    decorators = [jwt_required(), limiter.limit('20/minute'), limiter.limit('1000/day')]

    @sentiment_ns.expect(parser)
    @sentiment_ns.marshal_with(model)
    def get(self):
        '''
        Author: 邵佳泓
        msg: 情感信息
        param {*} self
        '''
        request_data = parser.parse_args()
        article_sources = request_data.get('articleSource')
        if article_sources == '':
            attitudes = SenAna.query.with_entities(SenAna.attitude).distinct().all()
            data = [[{
                'name': attitude[0],
                'value': SenAna.query.filter_by(attitude=attitude[0]).count()
            } for attitude in attitudes]]
            return {'code': 0, 'message': '情感数据查询成功', 'success': True, 'data': data}
        else:
            data = []
            for article_source in article_sources:
                attitudes = SenAna.query.with_entities(SenAna.attitude).distinct().all()
                data.append([{
                    'name':
                    attitude[0],
                    'value':
                    SenAna.query.join(News, SenAna.newsid == News.newsid).filter(
                        SenAna.attitude == attitude[0],
                        News.articleSource == article_source).count()
                } for attitude in attitudes])
            return {'code': 0, 'message': '情感数据查询成功', 'success': True, 'data': data}


# Import of all the libraries we need to work

import sys
from altair.vegalite.v4.api import value
sys.path.insert(0, "/home/apprenant/Documents/Brief-Emotion-Analysis-Text/")
import pandas as pd
import numpy as np
import warnings
warnings.filterwarnings("ignore")
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.model_selection import cross_val_score
from sklearn.metrics import accuracy_score

from src.functions import *
import joblib
filename_randomforest = "random_forest.sav"

#### Etape 1

# Import of our databases
emotion_final, text_emotion = import_database()

# Database 1

# Encoding of the emotion column
label_encoding(emotion_final, [(emotion_final['label'] == "sadness") | (emotion_final['label'] == "fear") | (emotion_final['label'] == "anger"), (emotion_final['label'] == "love") | (emotion_final['label'] == "surprise") | (emotion_final['label'] == "happy")], [0, 1])

# Division of our data by using train_test_split
X_train9, X_test9, y_train9, y_test9 = variables_selection(emotion_final['text'], emotion_final['binary_emotion'])

# Vectorization of our data
vectorizer9 = vectorize_data(CountVectorizer, emotion_final['text'], None)

# Transformation of our data in order to use our model on it
text_train9, text_test9 = transform_training_data(vectorizer9, X_train9, X_test9)

# Building of our model
model9 = define_model(RandomForestClassifier(random_state=42), text_train9, y_train9)

# Predictions of target values for the testing data
y_pred9, y_proba9, dataframe9 = predict_model(model9, text_test9, X_test9)

# Calculation of the train scores
train_score1 = calculate_score(model9, text_train9, y_train9)
train_score2 = calculate_score(model9, text_test9, y_test9)

# Database 2

# Encoding of the emotion column
label_encoding(text_emotion, [(text_emotion['label'] == "empty") | (text_emotion['label'] == "sadness") | (text_emotion['label'] == "worry") | (text_emotion['label'] == "hate") | (text_emotion['label'] == "boredom") | (text_emotion['label'] == "anger"), (text_emotion['label'] == "enthusiasm") | (text_emotion['label'] == "neutral") | (text_emotion['label'] == "surprise") | (text_emotion['label'] == "love") | (text_emotion['label'] == "fun") | (text_emotion['label'] == "happiness") | (text_emotion['label'] == "relief")] ,[0, 1])

# Division of our data by using train_test_split
X_train10, X_test10, y_train10, y_test10 = variables_selection(text_emotion['text'], text_emotion['binary_emotion'])

# Vectorization of our data
vectorizer10 = vectorize_data(CountVectorizer, text_emotion['text'], None)

# Transformation of our data in order to use our model on it
text_train10, text_test10 = transform_training_data(vectorizer10, X_train10, X_test10)

# Building of our model
model10 = define_model(RandomForestClassifier(random_state=42), text_train10, y_train10)

# Predictions of target values for the testing data
y_pred10, y_proba10, dataframe10 = predict_model(model10, text_test10, X_test10)

# Calculation of the train scores
train_score3 = calculate_score(model10, text_train10, y_train10)
train_score4 = calculate_score(model10, text_test10, y_test10)

#### Etape 2

# Concatenation of the two databases
new_emotion_text = concat_databases(emotion_final, text_emotion)
new_emotion_text["label"].replace({'happiness': 'happy'}, inplace=True)

# Encoding of the emotion column
label_encoding(new_emotion_text, [(new_emotion_text['label'] == "empty") | (new_emotion_text['label'] == "sadness") | (new_emotion_text['label'] == "worry") | (new_emotion_text['label'] == "hate") | (new_emotion_text['label'] == "boredom") | (new_emotion_text['label'] == "anger") | new_emotion_text['label'] == "fear", (new_emotion_text['label'] == "enthusiasm") | (new_emotion_text['label'] == "neutral") | (new_emotion_text['label'] == "surprise") | (new_emotion_text['label'] == "love") | (new_emotion_text['label'] == "fun") | (new_emotion_text['label'] == "happy") | (new_emotion_text['label'] == "relief")] ,[0, 1])

# Division of our data by using train_test_split
X_train11, X_test11, y_train11, y_test11 = variables_selection(new_emotion_text['text'], new_emotion_text['binary_emotion'])

# Vectorization of our data
vectorizer11 = vectorize_data(CountVectorizer, new_emotion_text['text'], None)

# Transformation of our data in order to use our model on it
text_train11, text_test11 = transform_training_data(vectorizer11, X_train11, X_test11)

# Building of our model
model11 = define_model(RandomForestClassifier(random_state=42), text_train11, y_train11)

# Predictions of target values for the testing data
y_pred11, y_proba11, dataframe11 = predict_model(model11, text_test11, X_test11)

# Calculation of the train scores
train_score5 = calculate_score(model11, text_train11, y_train11)
train_score6 = calculate_score(model11, text_test11, y_test11)

#### Etape 3

# Selection of the trained datas and the tested datas
X_rf, y_rf, X_test12, y_test12 = step3_variables(emotion_final, text_emotion)

# Vectorization of our data
vectorizer12 = vectorize_data(CountVectorizer, X_rf, X_test12, 1)

# Transformation of our data in order to use our model on it
text_train12, text_test12 = transform_training_data(vectorizer12, X_rf, X_test12)

# Building of our model
model12 = define_model(RandomForestClassifier(random_state=42), text_train12, y_rf)

# Predictions of target values for the testing data
y_pred12, y_proba12, dataframe12 = predict_model(model12, text_test12, X_test12)

# Calculation of the part of correctly predicted results
accuracy9 = calculate_accuracy_score(y_test12, y_pred12)

# Saving of the useful objects for our Streamlit app
joblib.dump([dataframe9, dataframe10, dataframe11, dataframe12, train_score1, train_score2, train_score3, train_score4, train_score5, train_score6, accuracy9], filename_randomforest)


import dataclasses
from inspect import isfunction
from math import isnan
from typing import Any
from typing import Union

from fvalues import F

JSONValue = Union[
    str, int, float, bool, None, list["JSONValue"], dict[str, "JSONValue"]
]

def to_json_value(x: Any) -> JSONValue:
    if isinstance(x, dict):
        return {
            k if isinstance(k, str) else repr(k): to_json_value(v) for k, v in x.items()
        }
    if isinstance(x, (list, tuple, set)):
        return [to_json_value(v) for v in x]
    if isinstance(x, F):
        return {"__fstring__": to_json_value(x.parts)}
    if hasattr(x, "dict") and callable(x.dict):
        try:
            x = x.dict()
        except TypeError:  # raised if wrong number of arguments
            pass
        else:
            return to_json_value(x)
    if dataclasses.is_dataclass(x):
        return to_json_value(dataclasses.asdict(x))
    if isfunction(x):
        return dict(class_name=x.__class__.__name__, name=x.__name__)
    if isinstance(x, float):
        return None if isnan(x) else x
    if isinstance(x, (int, str, bool, type(None))):
        return x
    return repr(x)


class Room:
    def __init__(self,name,owner,weight,length,height):
        self.name=name
        self.owner=owner

        self.__weight=weight
        self.__length=length
        self.__height=height

    def tell_area(self):
        return self.__weight * self.__length * self.__height

r=Room('卫生间','alex',10,10,10)

# print(r.tell_area())

print(r.tell_area())

3面向对象编程/面向对象&网络编程基础/网络编程入门&FTP服务开发实战/第一章面向对象/19 封装与扩展性.py

19 封装与扩展性.py


class Vertex(object):

    def __init__(self, node):
        self.node = node
        self.neighbor = {}
        self.status = "unvisited"
        self.step = 0

    def __str__(self):
        return str(self.node) + ":" + self.status

    def add_neighbor(self, new_node, weight=0):
        if isinstance(new_node, Vertex) and new_node.node not in self.neighbor.keys():
            self.neighbor[new_node] = weight
            return True
        else:
            return False

class Queue(object):

    def __init__(self):
        self.array=[]

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

    def is_empty(self):
        return len(self)==0

    def enqueue(self,i):
        self.array.append(i)

    def dequeue(self):
        return self.array.pop(0)

class Edge(object):

    def __init__(self, vertex1, vertex2, weight=0):
        self.points={vertex1, vertex2}
        self.weight = weight
        vertex1.add_neighbor(vertex2, weight)
        vertex2.add_neighbor(vertex1, weight)

    def __lt__(self, others):
        return self.weight < others.weight

    def __contains__(self, vertex):
        return vertex in self.points

    def __eq__(self, others):
        if self.points == others.points and self.weight == others.weight:
            return True
        else:
            return False

    def __str__(self):
        vertex1, vertex2 = list(self.points)
        return str(vertex1)+ ":" + str(vertex2) + ":" + str(self.weight)

class MinHeap(object):

    def parent(self,j):
        return (j-1)//2

    def left(self,j):
        return 2*j+1

    def right(self,j):
        return 2*j+2

    def has_left(self,j):
        return self.left(j) < len(self.data)

    def has_right(self,j):
        return self.right(j) < len(self.data)

    def swap(self,i,j):
        self.data[i] , self.data[j] = self.data[j], self.data[i]

    def upheap(self,j):
        parent = self.parent(j)
        if (j>0) and (j <= (len(self.data)-1)):
            if self.data[j] < self.data[parent]:
                self.swap(j, parent)
            self.upheap(parent)

    def downheap(self,j):
        if self.has_left(j):
            left=self.left(j)
            small_child=left

            if self.has_right(j):
                right=self.right(j)
                if self.data[right] < self.data[small_child]:
                    small_child=right

            if self.data[small_child] < self.data[j]:
                self.swap(small_child, j)
                return self.downheap(small_child)

    def __init__(self):
        self.data=[]

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

    def add(self, edge):
        self.data.append(edge)
        self.upheap(len(self.data)-1)

    def remove_min(self):
        self.swap(0, len(self.data)-1)
        min_node = self.data.pop()
        self.downheap(0)
        return min_node

class Graph(object):

    def __init__(self):
        self.vertices = []
        self.edges = []

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

    def __contains__(self, class_obj):
        if isinstance(class_obj, Vertex):
            if class_obj in self.vertices:
                return True
            else:
                return False
        if isinstance(class_obj, Edge):
            if class_obj in self.edges:
                return True
            else:
                return False

    def add_vertex(self, vertex):
        if isinstance(vertex, Vertex) and vertex not in self.vertices:
            self.vertices.append(vertex)
            return True
        else:
            return False

    def add_edge(self, edge):
        if isinstance(edge, Edge):
            self.edges.append(edge)
            vertex1, vertex2 = list(edge.points)
            if vertex1 in self.vertices:
                pass
            else:
                self.vertices.append(vertex1)
            if vertex2 in self.vertices:
                pass
            else:
                self.vertices.append(vertex2)

    def draw_edge(self, vertex1, vertex2, weight=0):
        if vertex1 in self.vertices and vertex2 in self.vertices and isinstance(vertex1, Vertex) and isinstance(vertex2, Vertex):
            vertex1.add_neighbor(vertex2, weight)
            vertex2.add_neighbor(vertex1, weight)
            self.edges.append(Edge(vertex1,vertex2, weight))
            return True
        else:
            return False

    def djikstra(self, source):
        prev_step={}
        q=Queue()
        self.clear_status()
        if source in self:
            source.status = "found"
            q.enqueue(source)
            prev_step[source]=(None,0)
        while not q.is_empty():
            current_node = q.dequeue()
            if current_node.status == "found":
                for next_node in current_node.neighbor.keys():
                    if next_node.status == "unvisited":
                        next_node.status = "found"
                        q.enqueue(next_node)
                        next_node.step = current_node.step + current_node.neighbor[next_node]

                    if next_node in prev_step.keys():
                        if next_node.step < prev_step[next_node][1]:
                            prev_step[next_node] = (current_node, next_node.step)
                    else:
                        prev_step[next_node]=(current_node, next_node.step)

            current_node.status="visited"

        for keys in prev_step.keys():
            print(str(keys)+ " : " + str(prev_step[keys][0]) + " " +str(prev_step[keys][1]) )
        return

    def bfsearch(self, start_node):
        q = Queue()
        if start_node in self:
            start_node.status = "found"
            q.enqueue(start_node)
        while not q.is_empty():
            current_node = q.dequeue()
            if current_node.status == "found":
                for next_node in current_node.neighbor.keys():
                    if next_node.status == "unvisited":
                        next_node.status = "found"
                        q.enqueue(next_node)
            current_node.status = "visited"
            print(current_node)
        return

    def clear_status(self):
        for i in self.vertices:
            i.status = "unvisited"
            i.step = 0

    def dfsearch(self, start_node):
        start_node.status = "found"
        for next_node in start_node.neighbor.keys():
            if next_node.status == "unvisited":
                self.dfsearch(next_node)
        start_node.status = "visited"
        print(start_node)
        return

def prim_mst(input_graph):
    mst = Graph()

    #find minimum edge as starting point
    heap_edge = MinHeap()
    for edge in input_graph.edges:
        heap_edge.add(edge)
    start_edge = heap_edge.remove_min()
    mst.add_edge(start_edge)
    del heap_edge

    while set(mst.vertices) != set(input_graph.vertices):
        outgoing_vertices = [vertex for vertex in input_graph.vertices if vertex not in mst.vertices]
        remaining_edges = [edge for edge in input_graph.edges if edge not in mst.edges]
        heap_edge = MinHeap()
        for edge in remaining_edges:
            heap_edge.add(edge)
        new_edge = heap_edge.remove_min()
        vertex1, vertex2= list(new_edge.points)
        #check that at least one from vertex1, vertex2 in outgoing_vertices
        #keep searching if both vertex1, vertex2 not in outgoing_vertices
        '''if vertex1 in outgoing_vertices or vertex2 in outgoing_vertices:
            mst.add_edge(new_edge)
        else:
            while vertex1 not in outgoing_vertices and vertex2 not in outgoing_vertices:
                new_edge = heap_edge.remove_min()
                vertex1, vertex2 = list(new_edge.points)
            mst.add_edge(new_edge)
        '''
        while vertex1 not in outgoing_vertices and vertex2 not in outgoing_vertices:
            new_edge = heap_edge.remove_min()
            vertex1, vertex2 = list(new_edge.points)
        mst.add_edge(new_edge)
        del heap_edge
    return mst
#Notes 3/2
#Prim Minimum spanning tree algorithm
#1. Vertex class - no concern
#2. Queue class - no concern
#3. Edge class - does not mutate existing Vertex objects
#4. MinHeap class - ability to store Edge objects; property dependent on Edge object weights
#5. Graph class
#   - added edges list; must contain same elements with vertices list
#   - added add_edge function; does not mutate Vertex objects
#6. Function Prim_mst
#   - find minimum edge as the starting edge in mst; use heap structure
#   - compare set vertices
#   - create outgoing_vertices using list comprehension
#   - create remaining_edges using list comprehension

if __name__ == "__main__":
    a=Vertex('A')
    b=Vertex('B')
    c=Vertex('C')
    d=Vertex('D')
    g=Graph()
    g.add_vertex(a)
    g.add_vertex(b)
    g.add_vertex(c)
    g.add_vertex(d)
    g.draw_edge(a,b,2)
    g.draw_edge(a,c,4)
    g.draw_edge(a,d,1)
    g.draw_edge(b,c,5)
    g.draw_edge(c,d,3)
    #test case 1: shortest path using Djikstra
    g.djikstra(a)

    #testcase 2: minimum spanning tree using Prim MST
    h=prim_mst(g)
    print(h.edges[0])
    print(h.edges[1])
    print(h.edges[2])