"""下载指标数据"""

import re
import json
from json.decoder import JSONDecodeError

import scrapy
import pymysql
from scrapy import signals
from scrapy.spidermiddlewares.httperror import HttpError
from twisted.internet.error import DNSLookupError
from twisted.internet.error import TimeoutError, TCPTimedOutError
from twisted.internet.error import ConnectionRefusedError
from twisted.web._newclient import ResponseNeverReceived

from ..utils.dbman import query_sql
from ..items import IndicatorDataItem

class IndicatorDataSpider(scrapy.Spider):

    name = 'indicators_data'

    data_pat = re.compile(r'(?<=ld\+json">).*?(?=</)', re.DOTALL)

    @classmethod
    def from_crawler(cls, crawler, *args, **kwargs):
        spider = super(IndicatorDataSpider, cls).from_crawler(
            crawler, *args, **kwargs
        )
        crawler.signals.connect(spider.spider_opened, signals.spider_opened)
        crawler.signals.connect(spider.spider_closed, signals.spider_closed)
        return spider

    def spider_opened(self, spider):
        self.logger.info('Opening spider %s...', spider.name)
        conn = pymysql.connect(**self.settings['DBARGS'])
        with conn.cursor() as cursor:
            self.countries = query_sql(
                cursor, 'select id, code, url from macro_data_country')
        conn.close()

    def spider_closed(self, spider):
        self.logger.info('Closing spider %s...', spider.name)

    def start_requests(self):
        for it in self.countries:
            yield scrapy.Request(
                it['url'],
                callback=self.parse,
                errback=self.errback_scraping,
                meta={'country_id': it['id'], 'country_code': it['code']}
            )

    def parse(self, response):
        """通过'更多'进入指标详情页"""
        indicators = response.xpath("//*[@class='indicator-column']/li")
        for each in indicators:
            name = each.xpath('./h3/text()').extract_first()
            url = each.xpath('./a/@href').extract_first()
            if name and url:
                yield scrapy.Request(
                    url,
                    callback=self.query_indicators_data,
                    errback=self.errback_scraping,
                    meta={
                        'name': name,
                        'country_id': response.meta['country_id'],
                        'country_code': response.meta['country_code']
                    },
                )

    def query_indicators_data(self, response):
        """查询指标数据"""
        entries = response.xpath("//*[@class='two-column']/li")
        for it in entries:
            title = it.xpath('./h3/text()').extract_first()
            if not title:
                continue
            for each in it.xpath('./ul/li'):
                name = each.xpath('./a/text()').extract_first()
                url = each.xpath('./a/@href').extract_first()
                yield scrapy.Request(
                    url,
                    callback=self.parse_indicators_data,
                    errback=self.errback_scraping,
                    meta={
                        'country_code': response.meta['country_code'],
                        'country_id': response.meta['country_id'],
                        'indicators': [3, name.strip(), title.strip()],
                        'url': url
                    }
                )

    def parse_indicators_data(self, response):
        """json-ld数据解析（待研究）"""
        try:
            data = re.search(self.data_pat, response.text).group()
            jdata = json.loads(data)
            entries = jdata[
                '@graph'][0]['mainEntity']['csvw:tableSchema']['csvw:columns']
            result = []
            for each in entries:
                title = each['csvw:name']
                values = [it['csvw:value'] for it in each['csvw:cells']]
                values.insert(0, title)
                for i in range(len(values)):
                    values[i] = values[i].replace(
                        '\xa0', ' ').replace(',', '|#|')
                result.append(values)
            yield IndicatorDataItem(
                country_code=response.meta['country_code'],
                country_id=response.meta['country_id'],
                indicator_id=response.meta['indicators'],
                url=response.meta['url'], data=zip(*result)
            )
        except (AttributeError, JSONDecodeError, KeyError):
            pass

    def errback_scraping(self, failure):
        req_url = failure.request.url
        if failure.check(HttpError):
            response = failure.value.response
            self.logger.error('HttpError %s on %s', response.status, req_url)
        elif failure.check(DNSLookupError):
            self.logger.error('DNSLookupError on %s', req_url)
        elif failure.check(ConnectionRefusedError):
            self.logger.error('ConnectionRefusedError on %s', req_url)
        elif failure.check(TimeoutError, TCPTimedOutError):
            self.logger.error('TimeoutError on %s', req_url)
        elif failure.check(ResponseNeverReceived):
            self.logger.error('ResponseNeverReceived on %s', req_url)
        else:
            self.logger.error('UnpectedError on %s', req_url)
            self.logger.error(repr(failure))


from django.shortcuts import render
from django.http import HttpResponse
from django.shortcuts import redirect
from django.core.urlresolvers import reverse
from myadmin.models import Types,Goods,Orders,Detail
from django.core.paginator import Paginator
from PIL import Image
import time,json,os
#=========商品类别

#浏览商品
def type_index(request,pIndex=1):
	#执行数据查询,并放置模板中
	list = Types.objects.extra(select = {'_has':'concat(path,id)'}).order_by('_has')
	#遍历查询结果,为每个结果对象追加一个pname属性,目的用于缩进标题
	for ob in list:
		ob.pname = '...'*(ob.path.count(',')-1)
	#context = {'typeslist':list}
	#判断并封装搜索学生信息
	where = []
	if request.GET.get('name','') != '':
		list = list.filter(name__contains=request.GET['name'])
		where.append('name='+request.GET['name'])
	#传入数据和页的大小来创建对象
	p = Paginator(list,10)
	#判断页号没有初始值时初始化1
	if pIndex == '':
		pIndex = '1'
	pIndex = int(pIndex) #类型转换int
	list2 = p.page(pIndex)#获取当前页数据
	plist = p.page_range#获取页码信息
	#封装分页信息
	context = {'stulist':list2,'plist':plist,'pIndex':pIndex,'where':where}
	return render(request,'myadmin/types/index.html',context)
#添加商品
def type_add(request,tid):
	#获取父类别信息,若没有则默认为根类别信息
	if tid == '0':
		context = {'pid':0,'path':'0,','name':'根类别'}
	else:
		ob = Types.objects.get(id=tid)
		context = {'pid':ob.id,'path':ob.path+str(ob.id)+',','name':ob.name}
	return render(request,'myadmin/types/add.html',context)

#执行商品类别信息添加
def type_insert(request):
	try:
		ob = Types()
		ob.name = request.POST['name']
		ob.pid = request.POST['pid']
		ob.path = request.POST['path']
		ob.save()
		print(1)
		context = {'info':'添加成功'}
	except:
		context = {'info':'添加失败'}
	return render(request,'myadmin/info.html',context)

#执行商品类别信息删除
def type_del(request,tid):
	try:
		#获取被删除商品的子类别信息量,若有数据,就禁止删除当前的类别
		row = Types.objects.filter(pid=tid).count()
		if row > 0:
			context = {'info':'删除失败,此类别还有子类别'}
			return render(request,'myadmin/info.html',context)
		else:
			ob = Types.objects.get(id=tid)
			ob.delete()
			context = {'info':'删除成功'}
	except:
		context = {'info':'删除失败!'}
	return render(request,'myadmin/info.html',context)

#商品信息编辑表单
def type_edit(request,tid):
	ob = Types.objects.get(id=tid)
	context = {'type':ob}
	return render(request,'myadmin/types/edit.html',context)
#执行商品信息编辑
def type_update(request,tid):
	try:
		ob = Types.objects.get(id=tid)
		ob.name = request.POST['name']
		ob.save()
		context = {'info':'修改成功'}
	except:
		context = {'info':'修改失败'}
	return render(request,'myadmin/info.html',context)

#==============商品信息管理

#商品信息浏览
def goods_index(request,pIndex=1):
	#执行数据查询,并放置到模板中
	list = Goods.objects.all()
	for ob in list:
		ty = Types.objects.get(id = ob.typeid)
		ob.typename = ty.name
	# context = {'goodslist':list}
	#判断并封装搜索学生信息
	where = []
	if request.GET.get('goods','') != '':
		list = list.filter(goods__contains=request.GET['goods'])
		where.append('name='+request.GET['goods'])
	p = Paginator(list,6)
	#判断页号没有初始值时初始化1
	if pIndex == '':
		pIndex = '1'
	pIndex = int(pIndex) #类型转换int
	list2 = p.page(pIndex)#获取当前页数据
	plist = p.page_range#获取页码信息
	#封装分页信息
	context = {'goodslist':list2,'plist':plist,'pIndex':pIndex,'where':where}
	# return render(request,'myadmin/types/index.html',context)
	return render(request,'myadmin/goods/index.html',context)

#商品信息添加
def goods_add(request):
	#获取商品类别信息
	list = Types.objects.extra(select={'_has':'concat(path,id)'}).order_by('_has')
	context = {'typelist':list}
	return render(request,'myadmin/goods/add.html',context)
#执行商品信息添加
def goods_insert(request):
	# try:
	#判断并执行图片上传
	myfile = request.FILES.get('pic',None)
	if not myfile:
		return HttpResponse('没有上传信息')
	#以时间戳命名一个新的图片名称
	filename = str(time.time())+'.'+myfile.name.split('.').pop()
	# destination = open(os.path.join('./static/goods',filename),'wb+')
	destination = open(os.path.join("./static/myadmin/goods/",filename),'wb+')
	for chunk in myfile.chunks():
		destination.write(chunk)
	destination.close()

	#执行图片缩放
	im = Image.open('./static/myadmin/goods/'+filename)
	#缩放375*375
	im.thumbnail((375,375))
	#把缩放的图像用jpeg格式保存
	im.save('./static/myadmin/goods/'+filename,'jpeg')
	#缩放220*220
	im.thumbnail((220,220))
	#把缩放的图像用jpeg格式保存
	im.save('./static/myadmin/goods/m_'+filename,'jpeg')
	#缩放100*100
	im.thumbnail((100,100))
	#把缩放的图像用jpeg格式保存
	im.save('./static/myadmin/goods/s_'+filename,'jpeg')

	#获取信息并执行添加
	ob = Goods()
	ob.goods = request.POST['goods']
	ob.typeid = request.POST['typeid']
	ob.company = request.POST['company']
	ob.price = request.POST['price']
	ob.store = request.POST['store']
	ob.descr = request.POST['descr']
	ob.picname = filename
	ob.state = 1
	ob.addtime = time.time()
	ob.save()
	context = {'info':'添加成功'}
	# except:
	# 	context = {'info':'添加失败'}
	return render(request,'myadmin/info.html',context)

#删除商品信息
def goods_del(request,gid):
	try:
		ob = Goods.objects.get(id=gid)
		#执行图片删除
		os.remove('./static/myadmin/goods/'+ob.picname)
		os.remove('./static/myadmin/goods/m_'+ob.picname)
		os.remove('./static/myadmin/goods/s_'+ob.picname)
		#执行信息删除
		ob.delete()
		context = {'info':'删除成功!'}
	except:
		context = {'info':'删除失败!'}
	return render(request,'myadmin/info.html',context)

#编辑商品信息表单
def goods_edit(request,gid):
	try:
		#获取要编辑的信息
		ob = Goods.objects.get(id=gid)
		#获取商品信息类别
		list = Types.objects.extra(select={'_has':'concat(path,id)'}).order_by('_has')
		#放置信息加载模板
		context = {'typelist':list,'goods':ob}
		return render(request,'myadmin/goods/edit.html',context)
	except:
		context = {'info':'没有找到要修改的信息'}
	return render(request,'myadmin/info.html',context)

#执行编辑商品信息
def goods_update(request,gid):
	try:
		#判断是否有文件上传
		#执行图片的上传
		myfile = request.FILES.get("pic",None)
		if not myfile:
			ob = Goods.objects.get(id= gid)
			ob.goods = request.POST['goods']
			ob.typeid = request.POST['typeid']
			ob.company = request.POST['company']
			ob.price = request.POST['price']
			ob.store = request.POST['store']
			ob.descr = request.POST['descr']
			ob.state = request.POST['state']
			ob.addtime= time.time()
			ob.save()
		else:
			ob = Goods.objects.get(id= gid)
			os.remove('./static/myadmin/goods/'+ob.picname)
			os.remove('./static/myadmin/goods/m_'+ob.picname)
			os.remove('./static/myadmin/goods/s_'+ob.picname)
			filename = str(time.time())+"."+myfile.name.split('.').pop()
			destination = open("./static/myadmin/goods/"+filename,"wb+")
			for chunk in myfile.chunks():      # 分块写入文件
				destination.write(chunk)
			destination.close()

			#执行图片缩放
			im = Image.open('./static/myadmin/goods/'+filename)
			#缩放375*375
			im.thumbnail((375,375))
			#把缩放的图像用jpeg格式保存
			im.save('./static/myadmin/goods/'+filename,'jpeg')
			#缩放220*220
			im.thumbnail((220,220))
			#把缩放的图像用jpeg格式保存
			im.save('./static/myadmin/goods/m_'+filename,'jpeg')
			#缩放100*100
			im.thumbnail((100,100))
			#把缩放的图像用jpeg格式保存
			im.save('./static/myadmin/goods/s_'+filename,'jpeg')

			ob.goods = request.POST['goods']
			ob.typeid = request.POST['typeid']
			ob.company = request.POST['company']
			ob.price = request.POST['price']
			ob.store = request.POST['store']
			ob.descr = request.POST['descr']
			ob.picname = filename
			ob.state = request.POST['state']
			ob.addtime= time.time()
			ob.save()
		context = {'info':'修改成功！'}
	except:
		context = {'info':'修改失败！'}
	return render(request,"myadmin/info.html",context)

#=======订单信息管理
#订单信息浏览
def orders_index(request,pIndex=1):
	list = Orders.objects.all()
	#判断并封装搜索学生信息
	where = []
	if request.GET.get('linkman','') != '':
		list = list.filter(linkman__contains=request.GET['linkman'])
		where.append('linkman='+request.GET['linkman'])
	#传入数据和页的大小来创建对象
	p = Paginator(list,10)
	#判断页号没有初始值时初始化1
	if pIndex == '':
		pIndex = '1'
	pIndex = int(pIndex) #类型转换int
	list2 = p.page(pIndex)#获取当前页数据
	plist = p.page_range#获取页码信息
	#封装分页信息
	context = {'orderslist':list2,'plist':plist,'pIndex':pIndex,'where':where}
	return render(request,'myadmin/orders/index.html',context)

#订单信息编辑
def orders_edit(request,rid):
	orders = Orders.objects.get(id=rid)
	context = {'orders':orders}
	return render(request,'myadmin/orders/edit.html',context)

#执行订单信息编辑
def orders_update(request,rid):
	try:
		ob = Orders.objects.get(id=rid)
		ob.status = request.POST['status']
		ob.save()
		context = {'info':'修改成功!'}
	except:
		context = {'info':'修改失败！'}
	return render(request,'myadmin/info.html',context)

#订单详情页
def orders_detail(request,rid):
	detail = Detail.objects.filter(orderid=rid)
	for ob in detail:
		dt = Goods.objects.get(id=ob.goodsid)
		ob.picname = dt.picname
	context = {'detaillist':detail}
	return render(request,'myadmin/orders/detail.html',context)


import pytest
from Trees.Binary_tree import BinaryTree, Node
from challengs.breadth_first_traversal.tree_breadth_first import *

def test_exists():
    assert breadth_first

def test_tree_empty():
    """
    test empty tree
    """
    actual = breadth_first(None)
    expected = []
    assert actual == expected

def test_one_node():
    """
    test tree with one node
    """
    tree = BinaryTree()
    tree.root = Node(2)
    expected = [2]
    actual = breadth_first(tree)
    assert actual == expected

def test_five_node():
    """
    test tree with one node
    """
    tree = BinaryTree()
    tree.root = Node(2)
    tree.root.left = Node(3)
    tree.root.left.left = Node(4)
    tree.root.left.right = Node(5)
    tree.root.right = Node(6)
    expected = [2, 3, 6, 4, 5]
    actual = breadth_first(tree)
    assert actual == expected

def test_our_example(tree):
    """
    test our example in the code challenge requirement
    """
    actual = breadth_first(tree)
    expected = [2, 7, 5, 2, 6, 9, 5, 11, 4]
    assert actual == expected

###########
# fixture
###########
@pytest.fixture
def tree():
    tree = BinaryTree()
    tree.root = Node(2)
    tree.root.left = Node(7)
    tree.root.left.left = Node(2)
    tree.root.left.right = Node(6)
    tree.root.left.right.left = Node(5)
    tree.root.left.right.right = Node(11)
    tree.root.right = Node(5)
    tree.root.right.right = Node(9)
    tree.root.right.right.left = Node(4)
    return tree


from __future__ import annotations

import asyncio
import typing

import aiohttp

from server import logger

if typing.TYPE_CHECKING:
    from server.tsuserver import TsuserverDR

class MasterServerClient():
    """
    Worker that advertises the server's presence to the AO master server.
    """

    def __init__(self, server: TsuserverDR):
        """
        Create a new master server client.

        Parameters
        ----------
        server : TsuserverDR
            Instance of the server that is meant to be advertised.
        """

        self.server = server
        self._period_length = 20
        self._announced_success = False
        self._session: aiohttp.ClientSession = None

        self._ms_ip: str = self.server.config['masterserver_ip']
        self._own_port: int = self.server.config['port']
        self._own_name: str = self.server.config['masterserver_name']
        self._own_description: str = self.server.config['masterserver_description']

    def _get_server_content(self) -> typing.Dict[str, typing.Any]:
        """
        Prepare contents of the server's status that the master server expects in an advertisement.

        Returns
        -------
        typing.Dict[str, typing.Any]
            Contents of the server's status
        """

        port = self._own_port
        players = self.server.get_player_count()
        name = self._own_name
        description = self._own_description

        content = {
            "port": port,
            "players": players,
            "name": name,
            "description": description
        }
        return content

    async def _post_json(self,
                         content: typing.Dict[str, typing.Any]) -> typing.Tuple[bool, typing.Dict]:
        """
        Send content that can be coerced into JSON format to the master server, and return the
        response it returns.

        Parameters
        ----------
        content : typing.Dict[str, typing.Any]
            Content to send.

        Returns
        -------
        typing.Tuple[bool, typing.Dict]
            - If the master server accepted the advertisement, this will be `(True, dict())`.
            - If instead the master server rejected the advertisement, this will be
              `(False, reason)`, where `reason` is why the master server rejected.
            - If instead some error was raised, this will be `(False, {"local": ex})`, where `ex`
              is what the error was.
        """

        try:
            async with self._session.post(self._ms_ip, json=content) as response:
                j = await response.json(content_type=None)
                return response.ok, j
        except Exception as ex:  # pylint: disable=broad-except
            return False, {"local": ex}

    async def _advertise(self) -> typing.Tuple[bool, typing.Dict]:
        """
        Attempt to advertise to the master server the current server status, and return the
        response it returns.

        Returns
        -------
        typing.Tuple[bool, typing.Dict]
            - If the master server accepted the advertisement, this will be `(True, dict())`.
            - If instead the master server rejected the advertisement, this will be
              `(False, reason)`, where `reason` is why the master server rejected.
            - If instead some error was raised, this will be `(False, {"local": ex})`, where `ex`
              is what the error was.
        """

        async with aiohttp.ClientSession() as self._session:
            if not self._announced_success:
                logger.log_pdebug('Establishing connection with the master server...')
            content = self._get_server_content()
            task = asyncio.create_task(self._post_json(content))
            val = await asyncio.gather(*[task], return_exceptions=True)
            return val[0]

    async def connect(self):
        """
        Make the worker start trying to open sessions to the master server client to advertise
        the server's existence. Sessions are refreshed every 20 seconds.

        Logging to console about the attempt are made if any of these are true:
        1. Worker failed to reach the master server, or
        2. Worker reached the master server, but the master server rejected the advertisement, or.
        3. Worker reached the master server, the master server accepted the advertisement, and
        logging such a message would not be an immediate duplicate of a message logged because of
        this case.
        """

        while True:
            try:
                ad_ok, ad_content = await self._advertise()
            except asyncio.exceptions.TimeoutError:
                logger.log_pdebug(f"Unable to connect to the master server, retrying in "
                                  f"{self._period_length} seconds.")
                self._announced_success = False
            else:
                if ad_ok:
                    if not self._announced_success:
                        self._announced_success = True
                        logger.log_pdebug("Advertised to the master server.")
                else:
                    logger.log_pdebug(f"Failed to advertise to the master server: {ad_content}.")
                    self._announced_success = False
            await asyncio.sleep(self._period_length)

    async def shutdown(self):
        """
        Explicitly shut down the connection to the master server if one is active.
        """

        if self._session:
            await self._session.close()


def resumemusic():
    root.PauseButton.grid()
    root.ResumeButton.grid_remove()
    mixer.music.unpause()

def volumeUp():
    vol=mixer.music.get_volume()
    mixer.music.set_volume(vol+0.1)
def volumeDown():

    vol=mixer.music.get_volume()
    mixer.music.set_volume(vol-0.1)
def stopMusic():
    mixer.music.stop()
def playmusic():
    ad=audiotrack.get()
    mixer.music.load(ad)
    mixer.music.play()

def pausemusic():
    mixer.music.pause()
    root.ResumeButton.grid()
    root.PauseButton.grid_remove()
def musicurl():
    dd= filedialog.askopenfilename()
    audiotrack.set(dd)
def createwidthes():
    pass

    ################################## Labels
    TrackLabel = Label(root, text='Select Audio Track:', background='lightskyblue', font=('ariel', 15, 'italic bold'))
    TrackLabel.grid(row=0, column=0, padx=20, pady=20)
    ##################################Entry box
    TrackLabelEntry = Entry(root, font=('ariel', 16, 'italic bold'), width=35,textvariable=audiotrack)
    TrackLabelEntry.grid(row=0, column=1, padx=20, pady=20)
    #######################################################################Buttons
    BrowseButton = Button(root, text='Search', bg='deeppink', font=('ariel', 13, 'italic bold'), width=20, bd=5,
                          activebackground='purple4',command=musicurl)
    BrowseButton.grid(row=0, column=2, padx=20, pady=20)

    PlayButton = Button(root, text='Play', bg='green2', font=('ariel', 13, 'italic bold'), width=20, bd=5,
                        activebackground='purple4',command=playmusic)
    PlayButton.grid(row=1, column=0, padx=20, pady=20)

    root.PauseButton = Button(root, text='Pause', bg='Yellow', font=('ariel', 13, 'italic bold'), width=20, bd=5,
                         activebackground='purple4',command=pausemusic)
    root.PauseButton.grid(row=1, column=1, padx=20, pady=20)
    root.ResumeButton = Button(root, text='Resume', bg='Yellow', font=('ariel', 13, 'italic bold'), width=20, bd=5,
                         activebackground='purple4',command=resumemusic)
    root.ResumeButton.grid(row=1, column=1, padx=20, pady=20)
    root.ResumeButton.grid_remove()
    root.mutebutton=Button(root,text='Mute',width=100,bg='orange',activebackground='purple4',bd=5)
    root.mutebutton.grid(row=3,column=3)

    VolumeupButton = Button(root, text='Volumeup', bg='Blue', font=('ariel', 13, 'italic bold'), width=20, bd=5,
                            activebackground='purple4',command=volumeUp)
    VolumeupButton.grid(row=1, column=2, padx=20, pady=20)

    StopButton = Button(root, text='Stop', bg='Red', font=('ariel', 13, 'italic bold'), width=20, bd=5,
                        activebackground='purple4',command=stopMusic)
    StopButton.grid(row=2, column=0, padx=20, pady=20)

    VolumedownButton = Button(root, text='Volumedown', bg='Blue', font=('ariel', 13, 'italic bold'), width=20, bd=5,
                              activebackground='purple4',command=volumeDown)
    VolumedownButton.grid(row=2, column=2, padx=20, pady=20)

#################################################################################################
from tkinter import *
from tkinter import filedialog
from pygame import mixer

root = Tk()
root.geometry('1100x500+200+50')
root.title("sandy music player")
root.resizable(False, False)
root.configure(bg='lightskyblue')
#########################################################################################Global variable
audiotrack = StringVar()
###########################################################################################Create slider
ss = 'Devloped By Sandy'
count = 0
text = ''
SliderLabel = Label(root, text=ss, bg='lightskyblue', font=('ariel', 40, 'italic bold'))
SliderLabel.grid(row=3, column=0, padx=20, pady=20, columnspan=3)

def IntroLabelTRick():
    global count, text
    if (count >= len(ss)):
        count = -1
        text = ''
        SliderLabel.configure(text=text)
    else:
        text = text + ss[count]
        SliderLabel.configure(text=text)
    count += 1
    SliderLabel.after(200, IntroLabelTRick)

IntroLabelTRick()
mixer.init()

createwidthes()

root.mainloop()


import os
from setuptools import setup, find_packages

def read(fname):
    return open(os.path.join(os.path.dirname(__file__), fname)).read()

setup(
    name="deepar",

    description="DeepAR project structure.",

    author="Subhashini Tripuraneni",

    packages=find_packages(exclude=['data', 'figures', 'output', 'notebooks']),

    long_description=read('README.md'),
)


import numpy as np
import pandas as pd
import h5py
from pylds.models import DefaultPoissonLDS, DefaultLDS
from pickle import dump
from sklearn.model_selection import train_test_split

min_segment = 0.5
lfads_dt = 0.01
bin_size = 50 #time step for lds, in ms
thresh = 0.2 #threshold of summed absolute value of lfads controller outputs
D_latent = 10 #
test_size = 50 #number of holdout segment
random_state = 5
default_std = 100 #default smoothing std, miliseconds
pad_interval = True

def split_segments(counts):
    print("spit function entered")
    train_counts, test_counts = train_test_split(counts, test_size=test_size, random_state=random_state)

    return train_counts, test_counts

def get_forward_prediction(model, test_counts):

    predicted_counts = []
    for segment in test_counts:
        p = np.zeros_like(segment)
        obs_init = segment[0,:]
        state_t, _, _, _ = np.linalg.lstsq(model.C, obs_init)
        p[0,:] = model.C.dot(state_t)
        for t in range(1, p.shape[0]):
            state_t = model.A.dot(state_t)
            p[t,:] = state_t.dot(model.C.T)

        predicted_counts.append(p)

    return predicted_counts

def train_model(df, co, n_steps, filename=None, bin_size=bin_size):

    counts = segment_spike_counts(df, co, bin_size)
    train_counts, test_counts = split_segments(counts)

    n_neurons = df.neural.shape[1]
    model = DefaultPoissonLDS(n_neurons, D_latent)
    for segment in train_counts:
        model.add_data(segment)

    ll = np.zeros(n_steps)
    for i in range(n_steps):
        model.EM_step()
        ll[i] = model.log_likelihood()

    try:
        if filename is not None:
            dump(model, open(filename, 'wb'))
    except:
        pass

    return model, ll

def train_model_gaussian(df, co, n_steps, filename=None, bin_size=bin_size):

    counts = segment_spike_counts(df, co, bin_size)
    train_counts, test_counts = split_segments(counts)

    n_neurons = df.neural.shape[1]
    model = DefaultPoissonLDS(n_neurons, D_latent)
    for segment in train_counts:
        model.add_data(segment)

    ll = np.zeros(n_steps)
    for i in range(n_steps):
        model.EM_step()
        ll[i] = model.log_likelihood()

    try:
        if filename is not None:
            dump(model, open(filename, 'wb'))
    except:
        pass

    return model, ll

def bin_dataframe(df, bin_size, smooth=False, std=default_std):
    '''if smooth, then downsample according to bin_size'''
    if smooth:
        n_stds = 3
        winsize = n_stds * std * 2 #multiple of 2 for n_stds on each side of the window
        if pad_interval:
            min_periods = None
        else:
            min_periods = 1

        return df.rolling(winsize, win_type='gaussian', min_periods=min_periods).sum(std=std).dropna(axis=0).values[::bin_size]
    else:
        return df.rolling(bin_size).sum().values[bin_size-1::bin_size]

def get_trial_segments(signal, thresh, min_segment_idx=None):
    '''Returns two arrays representing the indices of the endpoints of segments where
    signal is less than thresh. If min_segment is given, then only the segments with length
    greater than min_segment are returned'''

    starts = np.where(np.logical_and(signal[:-1] > thresh, signal[1:] <= thresh))[0] + 1
    if signal[0] <= thresh:
        starts = np.insert(starts, 0, 0)

    stops = np.where(np.logical_and(signal[:-1] <= thresh, signal[1:] > thresh))[0] + 1

    if signal[-1] <= thresh:
        stops = np.append(stops, len(signal))

    if min_segment_idx is not None:
        include_idx = stops - starts >= min_segment_idx
        starts = starts[include_idx]
        stops = stops[include_idx]

    return starts, stops

def segment_spike_counts(df, co, bin_size=bin_size, smooth=False, std=default_std):
    '''Gets spike counts for segments with minimum length autonomous'''

    assert df.index[-1][0]+1==co.shape[0]
    abs_co = np.abs(co).sum(axis=2)
    min_segment_idx = int(min_segment/lfads_dt)
    counts = []
    for i in range(co.shape[0]):
        starts, stops = get_trial_segments(abs_co[i,:], thresh, min_segment_idx=min_segment_idx)
        for start, stop in zip(starts, stops):
            if start*lfads_dt <= 6*std/1000:
                continue
            if pad_interval:
                padded_start_t = start*lfads_dt - 6*std/1000
                padded_stop_t = stop*lfads_dt
                if padded_start_t < 0:
                    import pdb;pdb.set_trace()
                segment_spikes = df.loc[i].neural.loc[padded_start_t:padded_stop_t]
                binned = bin_dataframe(segment_spikes, bin_size, smooth, std=std)
                counts.append(binned)
            else:
                segment_spikes = df.loc[i].neural.loc[start*lfads_dt:stop*lfads_dt]
                binned = bin_dataframe(segment_spikes, bin_size, smooth, std=std)
                counts.append(binned)

        print('Trial %d of %d processed'%(i+1, co.shape[0]))

    return counts

def random_intervals(df, n_intervals, interval_len, trial_len, bin_size=bin_size, smooth=False, std=default_std):

    '''
    Parameters
    df: data frame containing experiment data
    n_intervals: number of intervals
    interval_len: length of intervals to sample (in seconds)
    trial_len: length of trial given to lfads
    bin_size: bin_size in number of samples (ms)
    '''
    #making sure interval_len is integer multiple of bin_size
    assert (interval_len/(bin_size/1000))%1 == 0

    #cutting out spikes after end of trial
    df=df.groupby('trial').apply(lambda _df: bin_dataframe(_df.loc[_df.index[0][0]].loc[:trial_len].neural, bin_size, smooth, std=std))
    spikes = np.concatenate(df.values)
    k = 0
    intervals = np.zeros((n_intervals, int(interval_len/(bin_size/1000)), spikes.shape[1]))
    bin_size_s = bin_size/1000 #bin_size in seconds
    while k < n_intervals:
        start_idx = np.random.random_integers(0, spikes.shape[0])
        start_t = start_idx * bin_size_s
        stop_t = start_t + interval_len
        # don't use interval if trial boundary in interval
        if np.floor((stop_t-bin_size_s)/(trial_len-bin_size_s)) > np.floor((start_t-bin_size_s)/(trial_len-bin_size_s)):
            continue

        stop_idx = int(np.round(stop_t/(bin_size/1000)))
        interval = spikes[start_idx:stop_idx,:]
        # don't use interval if it overlaps with already sampled interval
        if np.any(np.isnan(interval)):
            continue

        intervals[k, :, :] = interval

        spikes[start_idx:stop_idx,:] = np.nan
        k += 1

    return intervals

if __name__=='__main__':
    trial_type = 'all'
    data_filename = '../data/intermediate/rockstar.p'
    lfads_filename = "/home/pmalonis/lfads_analysis/data/model_output/rockstar_8QTVEk_%s.h5"%trial_type
    with h5py.File(lfads_filename, 'r') as h5file:
        co = np.array(h5file['controller_outputs'])

    df = pd.read_pickle(data_filename)


"""twennyson URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/2.1/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

from app import views as app_views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', app_views.index, name='index'),
    path('register/', app_views.register, name='register'),
    path('auth/<int:id>/', app_views.auth, name='auth'),
    path('delete/<int:id>/', app_views.delete, name='delete'),
    path('callback/', app_views.callback, name='callback'),
    path('dashboard/', app_views.dashboard, name='dashboard'),
    path('delete-account/<int:id>/', app_views.delete_account, name='delete-account'),
]


#-----------------------------------------------------
import time
from time import sleep as ret
import serial

#p=serial.serial_for_url('loop://', timeout=1)
#KC705 en puerto ttyUSB2

p = serial.Serial(
    #Configurar con el puerto
    port='/dev/ttyUSB2',
    baudrate=9600,
    parity=serial.PARITY_NONE,
    stopbits=serial.STOPBITS_ONE,
    bytesize=serial.EIGHTBITS
)

p.isOpen()
p.timeout=10
print("\nTimeout: ",p.timeout)

# Enviar un string de n bytes
def enviar(dat):
    p.write(dat.encode())
    print("Enviados {} Bytes".format(len(dat)))
    return

# recibir y desempaquetar bytes
def recibir():
    fromUart=p.read(64).decode()
    print(fromUart)
    return

# Panel inicial
print("\nUartKC705 v2020r1")
print("-"*40)
print("\nLectura: cualquier letra")
print("\nTerminar conexion: exit\n")

while(True):
    #pide y limpia el dato
    data=input("toKcarla705$_: ").lower().strip()
    #salir
    if(data=='exit'): break
    #enviar
    else:
        while True:
            #enviar(data)
            #ret(0.1)
            recibir()
            ret(0.1)

#TERMINAR CON Ctrl+C


import igraph as ig
from igraph import *
import matplotlib.pyplot as plt

def breadth_first_search(graph, start_vertex):
    queue = []
    visited = set()

    queue.append(start_vertex)
    visited.add(start_vertex)
    traversal_edge=[]
    while queue:
        traverse=Graph()
        current_vertex = queue.pop(0)
        #print(current_vertex)
        try:
            neighbors = graph[current_vertex]
        except KeyError:
            pass
        for neighbor in neighbors:
            # names=[0]
            if neighbor not in visited:
                # names+=[neighbor]
                traversal_edge+=[(current_vertex,neighbor)]
                print(traversal_edge)
                traverse=ig.Graph(edges=traversal_edge)
                # traverse.vs['name']=names
                queue.append(neighbor)
                visited.add(neighbor)
                traverse.layout(layout='auto')
                # visual_style = {}
                # visual_style["vertex_label"] = traverse.vs["name"]
                fig, ax = plt.subplots()
                ig.plot(traverse, target=ax)
                plt.show()

#graph creation
vertex=[0,1,2,3,4]
edges = [(0, 1), (0, 2), (0, 3), (1, 3), (1, 2), (3, 4), (2, 4)]
g=Graph()
g= ig.Graph(edges=edges)
g.vs['name']=vertex

el=g.get_edgelist()
edge_dict={}
for edge in edges:
    parent,child = edge
    if parent not in edge_dict:
        edge_dict[parent] = []
    edge_dict[parent].append(child)

print(edge_dict)
start_vertex = 0

print("Breadth-First Search starting from vertex", start_vertex)
breadth_first_search(edge_dict, start_vertex)

# #plotting
# g.layout(layout='auto')
# visual_style = {} #visual attributes of the graph
# visual_style["vertex_label"] = g.vs["name"]
# fig, ax = plt.subplots()
# ig.plot(g, target=ax,**visual_style)
# plt.show()


import inspect
import typing
from typing import Any, Callable, TypeVar

from dependency_injector import wiring

__all__ = ["inject", "ProvideDI"]

F = TypeVar("F", bound=Callable[..., Any])  # noqa: VNE001

ProvideDI = wiring.Provide

def _is_dependency(arg: Any) -> bool:
    """Verify that the given argument is a wiring `Marker` from `dependency-injector`."""
    return getattr(arg, "__IS_MARKER__", False)

def get_inject_annotations(function: F) -> dict[str, Any]:
    """Get function's DI annotations."""
    return {
        name: annotation
        for name, annotation in typing.get_type_hints(function, include_extras=True).items()
        if any(_is_dependency(arg) for arg in typing.get_args(annotation))
    }

def clear_wrapper(wrapper: F) -> F:
    """Remove DI parameters from the given function."""
    inject_annotations = get_inject_annotations(wrapper)
    signature = inspect.signature(wrapper)
    new_params = tuple(
        parameter
        for parameter in signature.parameters.values()
        if parameter.name not in inject_annotations
    )
    wrapper.__signature__ = signature.replace(parameters=new_params)
    for name in inject_annotations:
        del wrapper.__annotations__[name]
    return wrapper

def inject(function: F) -> F:
    """Inject DI provider into function."""
    wrapper = wiring.inject(function)
    wrapper = clear_wrapper(wrapper)
    return wrapper


from functools import reduce
from itertools import chain

def lmap(f, l):
	return list(map(f, l))

def split_on_nl(xs):
	stuff = [[]]
	for x in xs:
		if x == "\n":
			stuff.append([])
			continue
		stuff[-1].append(x)

	return stuff

def p_boards(bs):
	for b in bs:
		for l in b:
			print(l)
		print()

def mark_cell(cell, call):
	(num, res) = cell
	if num == call:
		return (num, True)
	return cell

def mark(bs, call):
	for i, _ in enumerate(bs):
		bs[i] = lmap(lambda col: lmap(lambda cel: mark_cell(cel, call), col), bs[i])

def check_if_wins(board):
	# horizontal
	for row in board:
		winning_row = True
		for c in row:
			if c[1] == False:
				winning_row = False
		if winning_row:
			# print("doublefuck")
			return True

	# list transpose nicked from so again
	for col in list(map(list, zip(*board))):
		winning_col = True
		for c in col:
			if c[1] == False:
				winning_col = False
		if winning_col:
			# print("fuck")
			return True
	return False

def num_if_false(cell):
	(num, res) = cell
	if res == False:
		return num
	return 0

def calc1(calls, boards):
	for c in calls:
		mark(boards, c)

		for board in boards:
			if check_if_wins(board):
				flatboard = chain(*board)
				total = reduce(lambda l, r: l + num_if_false(r), flatboard, 0)
				p_boards([board])
				# print(list(flatboard))
				# print(board)
				print(total, c)
				print(total * c)
				return

def calc2(calls, boards):
	final = None
	last = None
	for i, c in enumerate(calls):
		mark(boards, c)

		for board in boards.copy():
			if check_if_wins(board):
				boards.remove(board)
		if len(boards) == 1:
			final = boards[0]
			last = i
			break

	last += 1
	while not check_if_wins(boards[0]):
		mark(boards, calls[last])
		last += 1

	flatboard = chain(*boards[0])
	total = reduce(lambda l, r: l + num_if_false(r), flatboard, 0)
	print(total, calls[last-1])
	print(total * calls[last-1])

with open("ch.txt") as file:
	lines = file.readlines()

	calls = lmap(int, lines[0].split(","))
	rest = split_on_nl(lines[2:])
	rest = lmap(lambda s: lmap(lambda t: t.split(), s), rest)
	boards = lmap(lambda s: lmap(lambda t: lmap(lambda u: (int(u), False), t), s), rest)

	print(calls)
	print()

	# calc1(calls, boards)
	calc2(calls, boards)


# ---
# jupyter:
#   jupytext:
#     formats: ipynb,py:hydrogen
#     text_representation:
#       extension: .py
#       format_name: hydrogen
#       format_version: '1.3'
#       jupytext_version: 1.14.5
#   kernelspec:
#     display_name: flying-discs
#     language: python
#     name: flyingdiscs
# ---

# %%
from dataclasses import dataclass

import matplotlib.pyplot as plt
from flying_discs.morrison.base import MorrisonBaseCalculator
from flying_discs.morrison.constants import (
    HannahConstants,
    HummelConstants,
    MorrisonUltrastar,
    MorrisonUltrastarCode,
    PottsCrowtherConstants,
    StilleyCarstensConstants,
    YasudaConstants,
)

# %%
@dataclass
class Experiment:
    angle_of_attack: float
    v0: float
    direction = 0
    deltaT = 0.033

experiments = [Experiment(0, 12), Experiment(2.5, 12), Experiment(5, 12), Experiment(7.5, 12), Experiment(10, 12)]

constants = {
    "Morrison": MorrisonUltrastar(),
    "MorrisonCode": MorrisonUltrastarCode(),
    "Hummel": HummelConstants(),
    "PottsCrowther": PottsCrowtherConstants(),
    "Yasuda": YasudaConstants(),
    "StilleyCarstens": StilleyCarstensConstants(),
    "Hannah": HannahConstants(),
}

START_HEIGHT = 1  # start height in meters
for i, experiment in enumerate(experiments):
    fig = plt.figure(figsize=(20, 11))
    ax = fig.add_subplot(len(experiments), 1, i + 1)
    for constant_name, constant in constants.items():
        disc = MorrisonBaseCalculator(constant)
        throw = disc.calculate_trajectory(START_HEIGHT, experiment.v0, experiment.angle_of_attack, experiment.deltaT)
        ax.plot(throw.trajectory.X, throw.trajectory.Z, label=constant_name)
        ax.set_xlabel("Distance x [m]")
        ax.set_ylabel("Height z [m]")
        ax.grid()
    plt.legend(prop={"size": 8}, loc=1)
    plt.title(f"Angle of Attack: {experiment.angle_of_attack}deg, V0: {experiment.v0}m/s", loc="left")
    plt.show()

# %%


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

import config

import elasticsearch
import hashlib
import json
import pyjq
import requests
import sys

from flask import jsonify, request, Flask, Response
from urllib.parse import urlencode

application = app = Flask(__name__)

@app.route('/<id>', methods=['GET'])
def root_get(id):
	try:
		es = elasticsearch.Elasticsearch([config.elasticsearch['uri']], verify_certs=False)
		return es.get(index=config.elasticsearch['index'], id=id)['_source']
	except elasticsearch.exceptions.NotFoundError:
		return jsonify({'reason': 'Not Found'}), 404

@app.route('/', methods=['POST'])
def root_post():
	data = request.json
	id = hashlib.sha1()
	try:
		id.update(('%s: (%s, %s); %s'%(data['description'], data['latitude'], data['longitude'], data['timestamp'])).encode())
	except KeyError:
		print(data)
		return jsonify({'reason': 'Bad Request'}), 400
	es = elasticsearch.Elasticsearch([config.elasticsearch['uri']], verify_certs=False)
	es.indices.create(index=config.elasticsearch['index'], ignore=[400])
	es.index(
		index=config.elasticsearch['index'],
		id='0x%s' % id.hexdigest(),
		document=data)
	return jsonify({'id': '0x%s' % id.hexdigest()})

@app.route('/last',          methods=['GET'])
@app.route('/last/<format>', methods=['GET'])
def last(format=None):
	if format == 'svg':
		return Response('''<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg"><style>circle {fill: %s;}</style><circle cx="50" cy="50" r="47"/></svg>''' % (_search()[0]['naivecolor']), mimetype='image/svg+xml')
	return Response(json.dumps(_search()[0]), mimetype='application/json')

@app.route('/search', methods=['GET', 'POST'])
def search():
	return Response(json.dumps(_search()), mimetype='application/json')

def _search():
	query = '{"query": {"match_all": {}}, "size": 1, "sort": [{"timestamp": {"order": "desc"}}]}'
	if request.data:
		query = request.data
	es = elasticsearch.Elasticsearch([config.elasticsearch['uri']], verify_certs=False)
	response = es.search(index=config.elasticsearch['index'], body=query)
	return pyjq.all(".hits.hits[]._source", response)

@app.route('/ping', methods=['GET'])
def ping():
	try:
		if elasticsearch.Elasticsearch([config.elasticsearch['uri']], verify_certs=False).ping():
			return jsonify({'result': 'pong'})
		1/0
	except:
		return jsonify({'result': 'oops'}), 500

@app.route('/_cat/<endpoint>', methods=['GET'])
def _cat(endpoint=None):
	r = requests.get('%s/_cat/%s?%s' % (config.elasticsearch['uri'], endpoint, urlencode(request.args)), verify=False)
	return r.text

if __name__ == "__main__":
	app.debug = config.debug
	app.run(**config.flask)


#This is the main script for the Schlieren Autoencoder

import pytorch_lightning as pl
import yaml

from core.data import getDataset
from core.model import CNNAutoencoder
from utilities.utils import save_json

from torchsummary import summary
import cv2
import matplotlib.pyplot as plt
import pprint

class dic2struc():
    def __init__(self, my_dict):
        for key in my_dict:
            setattr(self, key, my_dict[key])

def load_config(filepath):
    with open(filepath, 'r') as stream:
        try:
            trainer_params = yaml.safe_load(stream)
            return trainer_params
        except yaml.YAMLError as exc:
            print(exc)

def seed(cfg):
    torch.manual_seed(cfg.seed)
    if cfg.if_cuda:
        torch.cuda.manual_seed(cfg.seed)

def main():
    #config_filepath = str(sys.argv[1])
    config_filepath = 'config_file.yaml'
    cfg = load_config(filepath=config_filepath)
    pprint.pprint(cfg)
    cfg = dic2struc(cfg)

    #Data module
    my_datamodule = getDataset(
                    train_dir=cfg.train_dir,
                    val_dir = cfg.val_dir,
                    test_dir = cfg.test_dir,
                    pred_dir = cfg.pred_dir,
                    start = cfg.start,
                    stop = cfg.stop,
                    step = cfg.step,
                    height = cfg.height,
                    width = cfg.width,
                    num_workers = cfg.num_workers,
                    batch_size = cfg.train_batch)

    #Create an instance of the CNNae model
    my_model = CNNAutoencoder()

    #Train model
    if cfg.if_cuda:
        trainer = pl.Trainer(max_epochs = cfg.epochs, accelerator="gpu", strategy="ddp", devices=cfg.num_devices, num_nodes=cfg.num_nodes)
    else:
        trainer = pl.Trainer(max_epochs = cfg.epochs, accelerator="cpu", strategy="ddp", devices=cfg.num_devices, num_nodes=cfg.num_nodes)

    print("Initializing training stage...")
    trainer.fit(model = my_model, datamodule = my_datamodule)
    print("Training stage completed!")

    #Predict
    print("Initializing prediction stage...")
    preds = trainer.predict(model = my_model, datamodule = my_datamodule)
    print("Prediction stage completed!")

    predictions = {}
    predictions["latent"] = []
    predictions["reconstructed"] = []
    predictions["metadata"] = {'fps': 1/cfg.step, 'start': cfg.start, 'stop': cfg.stop, 'height': cfg.height, 'width':cfg.width}
    for (rec, lat) in preds:
        predictions["latent"].append(lat)
        predictions["reconstructed"].append(rec)

    #Save results
    print("Saving results to json file...")
    save_json(cfg.model_name, predictions, True)
    print("Saved!")

if __name__ == '__main__':

    main()


import numpy as np
from sklearn.linear_model import LinearRegression

def moving_average(a):
  return np.cumsum(a) / np.arange(1,len(a)+1)

def convergence_trace(x, mean):
  return np.sum([
    np.abs(moving_average(x[:,i]) - mu)
    for i, mu in enumerate(mean)
  ], axis=0)

def joint_conv_trace(chains, grid):
  joint, index = join_chains(chains)
  means = grid.means.mean(axis=0)
  return index, convergence_trace(joint, means)

def conv_fit(index, errors, cutoff=0.1, burnin=100):
  start = np.argwhere(index > burnin)[0][0]
  lg_ery = np.log10(errors[start:])
  lg_idx = np.log10(index[start:]).reshape((len(lg_ery), 1))
  lreg = LinearRegression()
  lreg.fit(lg_idx, lg_ery)
  score = lreg.score(lg_idx, lg_ery)
  return lreg.coef_[0], lreg.intercept_, score

def join_chains(chains):
  length = sum(len(c) for c, i in chains)
  progress = np.zeros(len(chains)).astype(int)

  samples = np.empty((length, chains[0][0].shape[1]))
  indexes = np.empty(length)
  for i in range(length):
    mini = float('inf')
    minc = None
    for ch, ci in enumerate(progress):
      chain, index = chains[ch]
      if ci >= len(chain):
        continue
      elif index[ci] < mini:
        mini = index[ci]
        minc = ch
    samples[i] = chains[minc][0][progress[minc]]
    indexes[i] = chains[minc][1][progress[minc]]
    progress[minc] += 1

  for ch, ci in enumerate(progress):
    assert(ci == len(chains[ch][0]))

  return samples, indexes

if __name__ == '__main__':
  np.testing.assert_array_equal(moving_average([1,3,5]), [1,2,3])
  pts = np.array([[1,2],[3,2],[5,-1]])
  mus = np.array([2,2])
  np.testing.assert_array_equal(convergence_trace(pts, mus), [1,0,2])

  chains = [
    (
      np.array([[10],[10],[10]]),
      np.array([1,4,9])
    ),
    (
      np.array([[8],[8],[8]]),
      np.array([1,3,7])
    ),
    (
      np.array([[6],[6],[6]]),
      np.array([2,5,6])
    )
  ]

  s, i = join_chains(chains)
  np.testing.assert_array_equal(s,
      [[10],[8],[6],[8],[10],[6],[6],[8],[10]])
  np.testing.assert_array_equal(i,
      [1,1,2,3,4,5,6,7,9])


from typing import Union, List, Dict

import numpy as np

from rp_interface.utils import DataType
from rp_interface.red_pitaya import RedPitaya
from rp_interface.red_pitaya_register import Register, MuxedRegister
from rp_interface.red_pitaya_parameter import RedPitayaParameter
from rp_interface.red_pitaya_module import RedPitayaModule

class SumModule(RedPitayaModule):
    '''
    Defines an interface to a conditional adder stage and the following coarse_gain_and_limiter
    Sums inputs adder_width based on the status of their corresponding bits. The result can then be divided by
    up to a factor 2**adder_width (to avoid saturation). If the summed outputs exceed the allowed range,
    it will saturate.

    This module defines the following controls:
        - add0
        - add1
        - ...
        - add{adder_width}
        - divide_by
    '''
    # This one's slightly awkward because not all sum modules will be identical
    # Instead, grow the controls dict as much as necessary at every init
    # and overload get_settings_dict() to only read as far as necessary
    _parameters = {
        'divide_by': '_divide_by_parameter.value'
    }
    _submodules = []

    def __init__(self,
                 red_pitaya: Union[RedPitaya, str],
                 add_select_register: Union[Register, MuxedRegister],
                 divide_by_register: Union[Register, MuxedRegister],
                 adder_width: int = None,
                 input_names: List = None
                 ):
        super().__init__(red_pitaya=red_pitaya)

        self._add_select_register = add_select_register
        self._divide_by_register = divide_by_register

        if adder_width is None:
            adder_width = self._add_select_register.n_bits
        self.adder_width = adder_width
        divide_by_width = int(np.ceil((np.log2(self.adder_width))))
        max_divide_by = 2**divide_by_width

        if input_names is None:
            input_names = {i: f'In{i}' for i in range(self.adder_width)}
        self.input_names = input_names

        if len(input_names) != self.adder_width:
            raise RuntimeError('Incorrect length {} for input names. Expected {}'.format(
                    len(self.input_names),
                    self.adder_width
                )
            )

        if self.adder_width > self._add_select_register.n_bits:
            raise RuntimeError('Register is too small for adder_width {}'.format(self.adder_width))

        self._define_add_select_register_locations()
        self._define_add_select_parameters()

        self._divide_by_parameter = RedPitayaParameter(
            red_pitaya=self.rp,
            register=self._divide_by_register,
            name='Divide by',
            dtype=DataType.UNSIGNED_INT,
            in_range=lambda val: (1 <= val <= max_divide_by),
            write_data=lambda val: int(divide_by_width-np.log2(val)),
            read_data=lambda reg: 2**(divide_by_width-reg)
        )

        # grow the controls dict as required:
        # add elements of the form  {'add0': '_add0_parameter.value'}
        for i in range(self.adder_width):
            property_name = 'add{}'.format(i)
            property_path = '_add{}_parameter.value'.format(i)
            if property_name not in self._parameters:
                self._parameters[property_name] = property_path
        self._attach_properties()  # redefine controls

    def _define_add_select_register_locations(self):
        '''
        Breaks apart self._add_select_register into individual controls
        '''
        for i in range(self.adder_width):
            attr_name = '_add{}_register'.format(i)
            reg = MuxedRegister(
                gpio_write_address=self._add_select_register.gpio_write_address,
                gpio_read_address=self._add_select_register.gpio_read_address,
                register_address=self._add_select_register.register_address,
                n_bits=1,
                lsb_location=self._add_select_register.lsb_location + i
            )
            setattr(self, attr_name, reg)

    def _define_add_select_parameters(self):
        '''
        Defines controls
        '''
        for i in range(self.adder_width):
            control_attr_name = '_add{}_parameter'.format(i)
            register_attr_name = '_add{}_register'.format(i)
            register = getattr(self, register_attr_name)
            control = RedPitayaParameter(
                red_pitaya=self.rp,
                register=register,
                name='Add {} enable'.format(i),
                dtype=DataType.BOOL,
            )
            setattr(self, control_attr_name, control)

    def get_settings_dict(self) -> Dict:
        properties_dict = {'divide_by': getattr(self, 'divide_by')}

        # add elements of the form  {'add0': '_add0_parameter.value'}
        for i in range(self.adder_width):
            property_name = 'add{}'.format(i)
            properties_dict[property_name] = getattr(self, property_name)

        return {
            'properties': properties_dict,
            'submodules': {}
        }

    @property
    def add_select_list(self):
        '''
        Returns a list of booleans, stating whether input n is summed or not
        '''
        # Invert order of string, and select adder_width first values
        add_select_string = self.rp.read_register(self._add_select_register, dtype='bits')[::-1][:self.adder_width]
        return [bool(int(enable)) for enable in add_select_string]

    def __str__(self):
        # Build addition string
        added_inputs = [name for name, enable in zip(self.input_names.values(), self.add_select_list) if enable]
        if len(added_inputs) == 0:
            return "no output"
        if self._divide_by_parameter.value == 1:
            return ' + '.join(added_inputs)
        return "({add_string})/{divide_by}".format(
            add_string=' + '.join(added_inputs),
            divide_by=self._divide_by_parameter.value
        )

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


# -*- coding: utf-8 -*-
# @Time    : 2019/2/1 10:58
# @Author  : HuangHao
# @Email   : 812116298@qq.com
# @File    : networks.py

import torch
import torch.nn as nn
from torch.autograd import Variable

cfg = {
    'VGG11': [64, 'M', 128, 'M', 256, 256, 'M', 512, 512, 'M', 512, 512, 'M'],
    'VGG13': [64, 64, 'M', 128, 128, 'M', 256, 256, 'M', 512, 512, 'M', 512, 512, 'M'],
    'VGG16': [64, 64, 'M', 128, 128, 'M', 256, 256, 256, 'M', 512, 512, 512, 'M', 512, 512, 512, 'M'],
    'VGG19': [64, 64, 'M', 128, 128, 'M', 256, 256, 256, 256, 'M', 512, 512, 512, 512, 'M', 512, 512, 512, 512, 'M'],
}

# 模型需继承nn.Module
class VGG(nn.Module):
# 初始化参数：
    def __init__(self, vgg_name):
        super(VGG, self).__init__()
        self.input = nn.Linear(5000, 1024)
        self.features = self._make_layers(cfg[vgg_name])
        self.classifier = nn.Linear(16384, 5)

# 模型计算时的前向过程，也就是按照这个过程进行计算
    def forward(self, x):
        out = self.input(x).view(-1, 1, 1024)
        out = self.features(out)
        out = out.view(out.size(0), -1)
        out = self.classifier(out)
        return out

    def _make_layers(self, cfg):
        layers = []
        in_channels = 1
        for x in cfg:
            if x == 'M':
                layers += [nn.MaxPool1d(kernel_size=2, stride=2)]
            else:
                layers += [nn.Conv1d(in_channels, x, kernel_size=3, padding=1),
                           nn.BatchNorm1d(x),
                           nn.ReLU(inplace=True)]
                in_channels = x
        layers += [nn.AvgPool1d(kernel_size=1, stride=1)]
        return nn.Sequential(*layers)

# net = VGG('VGG11')
# x = torch.randn(2,3,32,32)
# print(net)
class MyCNN(nn.Module):
    def __init__(self):
        super(MyCNN, self).__init__()
        self.input = nn.Linear(5000, 1024)
        self.conv = self._make_layers()
        self.output = nn.Linear(64*1024, 5)

    def forward(self, x):
        out = self.input(x).view(-1, 1, 1024)
        out = self.conv(out).view(out.size(0), -1)
        out = self.output(out)

        return out

    def _make_layers(self):
        layers = []
        layers += [nn.Conv1d(1, 64, kernel_size=3, padding=1),
            nn.BatchNorm1d(64),
            nn.ReLU(inplace=True)]
        layers += [nn.Conv1d(64, 64, kernel_size=3, padding=1),
                   nn.BatchNorm1d(64),
                   nn.ReLU(inplace=True)]

        return nn.Sequential(*layers)

class MyDNN(nn.Module):
    def __init__(self):
        super(MyDNN, self).__init__()
        self.input = nn.Linear(5000, 1024)
        self.dnn1 = nn.Linear(1024, 512)
        self.dnn2 = nn.Linear(512, 256)
        self.dnn3 = nn.Linear(256, 128)
        self.dnn4 = nn.Linear(128, 64)
        self.output = nn.Linear(64, 5)

    def forward(self, x):
        out = self.input(x)
        out = self.dnn1(out)
        out = self.dnn2(out)
        out = self.dnn3(out)
        out = self.dnn4(out)
        out = self.output(out)

        return out


'''
    The pypeline logger will duplicate the functionality of the integrated dripline logger.  It is meant to serve as an alternative for instances when the loggers are broken. It could also be useful for things that need to be logged but which are not actual dripline channels.
'''
from __future__ import print_function, absolute_import
# system libraries
from time import sleep
import logging
# custom libs
from pypeline import DripInterface

class logger:
    '''
        The logger class does simple, brute force, logging. When started it will log one channel and a prescribed interval indefinately.
    '''

    def __init__(self, **kwargs):
        logging.info('initializing a logger')
        if kwargs:
            self.SetupChannel(**kwargs)
        if 'start' in kwargs:
            if kwargs['start']:
                self.__call__()

    def __call__(self, **kwargs):
        logging.info('starting a logger loop')
        self.StartLogLoop()

    def SetupChannel(self, **kwargs):
        '''
            Configure this logger with a pypeline DripInterface instance, channel, etc. For now, the only supported logging mode is a dripline channel which supports a "get" verb. This could be expanded in the future if deemed useful. This is probably where this should happen.

            Inputs:
                valid kwargs are:
                    pype_url -> a url for a DripInterface instance __init__
                    channel -> name of the channel to log
                    interval -> approximate time between logging of values [seconds]
        '''
        valid_kwargs = {'pype_url', 'channel', 'interval', 'start'}
        if kwargs and not set(kwargs.keys()).issubset(valid_kwargs):
            raise KeyError('invalid keyword arugment')
        for kwarg in kwargs:
            if kwarg == 'start':
                continue
            if kwarg == 'pype_url':
                self.pype = DripInterface(kwargs[kwarg])
                continue
            setattr(self, kwarg, kwargs[kwarg])

    def StartLogLoop(self):
        '''
            Begin continuous logging. This is a blocking function call.
        '''
        while True:
            self._LogChannel()
            sleep(self.interval)

    def _LogChannel(self):
        '''
            so here, self.pype.Get could be changed to self.AcquireMethod which is part of the configuration, it could then log non-dripline things, if that is useful.
        '''
        get_result = self.pype.Get(self.channel).Wait()
        logging.info('logging %s', self.channel)
        log = {'sensor':self.channel,
               'uncal_val':str(get_result.Result()),
               'cal_val':str(get_result.Final()),
               'timestamp':str(get_result.TimeStamp()),}
        self.pype.LogValue(**log)


# Header (모듈 Import하는 작업)
import pygame, sys
from pygame.locals import*   # 유용한 상수들을 선언없이 사용하기 위해 필수 ex) quit, exit 등

# Initail 문 (무한반복문 이전 문장들, 전역변수 한번 초기화, 몇몇함수 한번 호출, 주로 색상같은 전역변수들)
white = (255,255,255)       # 색상 변수 선언
red = (255,0,0)             # 색상 변수 선언
green = (0,255,0)           # 색상 변수 선언
pygame.init()               # 나중에 사용할 함수를 위해 가장 앞서서 호출되어야 함
pygame.display.set_caption("Hello World Project")
myScreen = pygame.display.set_mode((640,480))                         # 캔버스 생성 (640 x 480 크기)
myTextFont = pygame.font.Font("HoonWhitecatR.ttf",32)                 # 해당 폰트로 32 크기로 설정
myText = myTextFont.render("Hello World!", True, red, green)          # render함수는 텍스트 내용과 색상을 정할수 있다
myTextArea = myText.get_rect()                                        # get_rect() 함수는 텍스트의 폰트 크기와 텍스트 크기 고려 적절한 직사각형 공간을 반환
myTextArea.center = (320, 240)

# Always 문 (무한반복문, 전역변수 계속 업데이트, 몇몇함수 계속 호출)
while True:
    myScreen.fill(white)                     # fill 함수는 캔버스를 단색으로 채우는 기능
    myScreen.blit(myText, myTextArea)        # blit 함수는 특정 객체를 특정 위치에 그리는 기능, blit이 fill 다음에 수행되어야 함

# Event 문 (모든 이벤트를 체크하는 반복문)
    for event in pygame.event.get():         # pygame.event.get() 함수는 Always문에서 발생한 이벤트들의 배열을 반환, 시간순으로 정렬
        if event.type == QUIT:
            pygame.quit()
            sys.exit()

    pygame.display.update()            # 일반적으로 다른 변수/함수의 처리가 끝난 이후에 호출, 처리의 결과물을 스크린에 출력하는 함수
                                       # 이함수가 Always 문 마지막에 실행되지 않으면, 출력되는 화면과 게임 내부 데이터가 서로 일치하지 않음


from flask import *
from flaskext.mysql import MySQL
from random import *
from datetime import *
from datetime import datetime
from datetime import date
import os
import string
import requests
import math
import time
import requests
import json

app = Flask(__name__,template_folder ='template')

app.secret_key = os.urandom(34)

app.config['MYSQL_DATABASE_USER'] = 'root'
app.config['MYSQL_DATABASE_PASSWORD'] = 'lallantiwari'
app.config['MYSQL_DATABASE_DB'] = 'frappe'
app.config['MYSQL_DATABASE_HOST'] = 'localhost'
mysql = MySQL(app)

#--------------------------------------------------------------------------------------------------

#MySQL Query Driver function

#Query can be directly passed as an argument without setting the coonection and committing the output

def mysql_query(sql):
	connection = mysql.connect()
	cursor = connection.cursor()
	if sql.strip().split(' ')[0].lower() == "select" :
		print(sql)
		cursor.execute(sql)
		print(cursor._executed)

		columns = [column[0] for column in cursor.description]
		results = []
		for row in cursor.fetchall():
			results.append(dict(zip(columns, row)))
		data = results
		cursor.close()
		connection.close()
		return data
	if sql.strip().split(' ')[0].lower() != "select" :
		cursor.execute(sql)
		print(cursor._executed)
		connection.commit()
		cursor.close()
		connection.close()
		return None

# How to use this function
# --> mysql_query("Select * from user_master;")
# --> mysql_query(" select * from user_master where emailid='{}';".format(email))

#Mysql Function Ended

#--------------------------------------------------------------------------------------------

#---------------------------------------------------------------------------------------------

#Code For Library management

#----------------------------------------------------------------------------------------------

#********************************************************************************************

#Function to display and import book details

@app.route('/',methods=['GET','POST'])
def book():
	bdata=mysql_query("SELECT * from books")
	if request.method=="POST":
		#----------------------------------------------------------------------------------------
		#add button for importing data from api
		if 'add' in request.form:
			#using try-catch statement for catching any exception
			try:
				no=request.form['nbooks']
				#converting the string value to integer
				no=int(no)
				#--------------------------------------
				title=request.form['title']
				author=request.form['author']
				isbn=request.form['isbn']
				pub=request.form['publisher']
				full_data=[]
				#Calculating how many time api should run
				page=no/20
				bno=math.ceil(page)
				#----------------------------------------
				#loop for importing data as per requirement and appending it into a list
				for i in range(1,bno+1):
					data=[]
					req=requests.get("https://frappe.io/api/method/frappe-library?page={}&title={}&authors={}&isbn={}&publisher={}".format(i,title,author,isbn,pub))
					data=req.json()
					full_data.append(data)
				#loop for iterating through the data fetched from the api
				for x in full_data:
					for i in range(0,no):
						bid=x['message'][i]['bookID']
						print(bid)
						#checking if the imported value already exists in the database or not
						check=mysql_query("SELECT book_id from books where book_id={}".format(bid))
						#if the details does not exists in the database
						if len(check)==0:
							connection = mysql.connect()
							cursor = connection.cursor()
							#Using normal cursor connection instead of mysql function for escaping aphostrphes
							#---------------------------------------------------------------------------------
							sql="INSERT INTO books(book_id,title,authors,average_rating,isbn,isbn13,language_code,num_pages,ratings_count,text_reviews_count,publication_date,publisher) VALUES(%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)"
							#Date converted into yyyy-mm-dd fromat
							time=datetime.strptime(x['message'][i]['publication_date'],'%m/%d/%Y')
							sqldt=(x['message'][i]['bookID'],x['message'][i]['title'],x['message'][i]['authors'],x['message'][i]['average_rating'],x['message'][i]['isbn'],x['message'][i]['isbn13'],x['message'][i]['language_code'],x['message'][i]['  num_pages'],x['message'][i]['ratings_count'],x['message'][i]['text_reviews_count'],time,x['message'][i]['publisher'])
							cursor.execute(sql,sqldt)
							connection.commit()
						#-------------------------------------------------------------------------------------
						#Stock Management is done through the api data :- Depending of the repeated details
						#If the details exists in the database
						else:
							#if the details exists then the stock of the book will be increamented by 1
							mysql_query("UPDATE books set stock=stock+1 where book_id={}".format(bid))
							mysql_query("UPDATE books set total=total+1 where book_id={}".format(bid))
					#flash is used to give notification or warning to the user by flashing the entered message with its category
					flash('Books Data fetched Successfully','success')
				return redirect(url_for('book'))
			except:
				flash('Sufficient data was not found','warning')
				return redirect(url_for('book'))
		#----------------------------------------------------------------------------------------
		#Del button for deleting data from database
		if 'del' in request.form:
			bid=request.form['del']
			#fetching return dates of issued books
			tdata=mysql_query("SELECT return_date from transaction where book_id={}".format(bid))
			#-------------------------------------
			#if the book is not reuturned than its details cannot be deleted
			if len(tdata)==0:
				flash('Cannot Delete ! Book is Already Issued ','warning')
			#if the book is returned then the details can be deleted
			else:
				mysql_query("DELETE from books where book_id={}".format(bid))
				flash('Book Data Deleted Successfully !','success')
			return redirect(url_for('book'))
		#----------------------------------------------------------------------------------------
		#Update button for updating books details
		if 'update' in request.form:
			bid=request.form['update']
			title=request.form['title']
			author=request.form['author']
			arating=request.form['rating']
			isbn=request.form['isbn']
			isbn13=request.form['isbn13']
			lcode=request.form['lcode']
			npage=request.form['pages']
			rcount=request.form['rcount']
			treview=request.form['treview']
			pdate=request.form['pdate']
			pub=request.form['publisher']
			connection = mysql.connect()
			cursor = connection.cursor()
			query="UPDATE books set title=%s,authors=%s,average_rating=%s,isbn=%s,isbn13=%s,language_code=%s,num_pages=%s,ratings_count=%s,text_reviews_count=%s,publication_date=%s,publisher=%s where book_id=%s"
			values=(title,author,arating,isbn,isbn13,lcode,npage,rcount,treview,pdate,pub,bid)
			cursor.execute(query,values)
			connection.commit()
			return redirect(url_for('book'))

	return render_template('book_details.html',bdata=bdata)

#**********************************************************************************************

#Function for displaying member details

@app.route('/member_details',methods=['GET','POST'])
def member():
	mdata=mysql_query("SELECT * from members")
	#----------------------------------------------------------------------------------------
	#del button for deleting the member data from the database
	if request.method=="POST":
		if 'del' in request.form:
			mid=request.form['del']
			check=mysql_query("SELECT book_id from transaction where member_id={} and return_date is Null".format(mid))
			if len(check)==0:
				mysql_query("DELETE from members where members.member_id={}".format(mid))
				flash('Member Delete Successfully !','success')
			else:
				flash('Cannot Delete Member ! Issued book is not returned','danger')
			return redirect(url_for('member'))
		#----------------------------------------------------------------------------------------
		#update for updating member Data into the database
		if 'update' in request.form:
			mid=request.form['update']
			name=request.form['name']
			phone=request.form['number']
			address=request.form['address']
			mysql_query("UPDATE members SET member_name='{}',member_phone={},member_address='{}' where member_id={}".format(name,phone,address,mid))
			flash('Member Details Updated Successfully !','success')
			return redirect(url_for('member'))
		#----------------------------------------------------------------------------------------
		#add button for adding new member into the database
		if 'add' in request.form:
			name=request.form['name']
			phone=request.form['number']
			email=request.form['email']
			address=request.form['address']
			#Checking if details are already available in the database or not
			edata=mysql_query("SELECT member_id from members where member_email='{}' OR member_phone='{}' ".format(email,phone))
			#---------------------------------------------------------------------
			#If details does not exists than new member will be added to the database
			if len(edata)==0:
				mysql_query("INSERT INTO members(member_name,member_phone,member_address,member_email) value('{}',{},'{}','{}')".format(name,phone,address,email))
				flash('Member Registered Successfully !','success')
			#if details already exists than it will give a warning
			else:
				flash('Member Already Exists !','warning')
			return redirect(url_for('member'))
		#----------------------------------------------------------------------------------------
		#Settle button to settle the outstanding amount of the member
		if 'settle' in request.form:
			amount=request.form['amount']
			mid=request.form['member']
			print(amount)
			mysql_query("UPDATE members set outstanding_amount=outstanding_amount-{},total_amount=total_amount+{} where member_id={}".format(amount,amount,mid))
			flash('Outstanding Amount Settled Successfully !', 'success')
			return redirect(url_for('transaction'))

	return render_template('member_details.html',mdata=mdata)

#************************************************************************************************

#Function For managing book issue and return

@app.route('/book_issued',methods=['GET','POST'])
def transaction():
	tdata=mysql_query("SELECT * from transaction join members using(member_id) join books using(book_id) order by transaction_id DESC")
	mdata=mysql_query("SELECT * from members")
	bdata=mysql_query("SELECT * from books")
	#----------------------------------------------------------------------------------------
	if request.method=="POST":
		#issueb button for issuing book to the members
		if "issueb" in request.form:
			name=request.form['name']
			book=request.form['book']
			tdate=date.today()
			#After fetching the details checking if the required book is in stock or not
			bstock=mysql_query("SELECT stock from books where book_id={}".format(book))
			#Checking the outstanding amount of the member who is issuing the book
			outstanding=mysql_query("SELECT outstanding_amount from members where member_id={}".format(name))
			#Checking if the earlier issued book is returned or not
			returnb=mysql_query("SELECT return_date from transaction where member_id={} order by transaction_id DESC limit 1".format(name))
			noissue=mysql_query("SELECT transaction_id from transaction where member_id={}".format(name))
			#condition to check if the book is in stock
			if bstock[0]['stock']>=1:
				#Earlier issued book is returned or not, or no book is issued yet
				if len(noissue)==0 or returnb[0]['return_date'] is not None:
					#if the oustanding amount is less than 500 or not
					if outstanding[0]['outstanding_amount']<500:
						#if the user meets all the condition then the book will be issued
						mysql_query("INSERT INTO transaction(book_id,member_id,issue_date) values({},{},'{}')".format(book,name,tdate))
						mysql_query("UPDATE books set stock=stock-1 where book_id={}".format(book))
						flash("Book Issued Successfully !",'success')
					#Flashing message for exceeding outstanding amount
					else :
						flash('Outstanding amount is exceeding Rs.500','warning')
				#Flashing message for book not returned
				else:
					flash('Prior issued book is not returned','warning')
			#Flashing message for book is out of stock
			else:
				flash('Book is out of stock', 'warning')
			return redirect(url_for('transaction'))
		#----------------------------------------------------------------------------------------
		#return button for returning the book
		if 'return' in request.form:
			tid=request.form['return']
			bid=request.form['book']
			mid=request.form['member']
			rdate=date.today()
			rent=request.form['rent']
			paid=request.form['paid']
			mid=request.form['member']
			#checking if the book rent is paid at the time of returning the book or not
			#--------------------------------------------------------------------------
			#If the rent is paid at the time of returning book
			if paid=="yes":
				#return date is set
				mysql_query("UPDATE transaction set return_date='{}',rent={},rent_paid='{}' where transaction_id={}".format(rdate,rent,paid,tid))
				#the total amount paid by user will be updated
				mysql_query("UPDATE members set total_amount=total_amount+{} where member_id={}".format(rent,mid))
				#updating the book stocks
				mysql_query("UPDATE books set stock=stock+1 where book_id={}".format(bid))
				flash('Book returned Successfully and rent is paid', 'success')
			#if the rent is not paid at the time of returning the book
			elif paid=="no":
				#outstanding amount is fechted from database
				amt=mysql_query("SELECT outstanding_amount from members where members.member_id={}".format(mid))
				rent1=int(rent)
				final_amt=rent1+amt[0]['outstanding_amount']
				#if the outstanding is getting greater the 500 when not paying the rent at the time
				#of the return then the book cannot be returned member has to settle the outstanding amount
				if final_amt<500:
					mysql_query("UPDATE transaction set return_date='{}',rent={} where transaction_id={}".format(rdate,rent,tid))
					mysql_query("UPDATE members set outstanding_amount=outstanding_amount+{} where member_id={}".format(rent,mid))
					flash('Book returned Successfully and rent is not paid', 'info')
					mysql_query("UPDATE books set stock=stock+1 where book_id={}".format(bid))
				else:
					flash('Cannot Return Book ! Outstanding amount is exceeding 500','danger')
			return redirect(url_for('transaction'))
		#----------------------------------------------------------------------------------------
		#settle button to settle the outstanding amount
		if 'settle' in request.form:
			amount=request.form['amount']
			tid=request.form['settle']
			mid=request.form['member']
			print(amount)
			mysql_query("UPDATE members set outstanding_amount=outstanding_amount-{},total_amount=total_amount+{} where member_id={}".format(amount,amount,mid))
			flash('Outstanding Amount Settled Successfully !','success')
			mysql_query("UPDATE transaction set rent_paid='yes' where member_id=(select member_id from members where outstanding_amount=0 and member_id={})".format(mid))
			return redirect(url_for('transaction'))

	return render_template('transaction_details.html',tdata=tdata,mdata=mdata,bdata=bdata)

#---------------------------------------------------------------------------------------------

#Code For Library management Ended

#----------------------------------------------------------------------------------------------

#**********************************************************************************************

#---------------------------------------------------------------------------------------------

#Code For Report generation

#----------------------------------------------------------------------------------------------

#Function for Generating reports

@app.route('/reports',methods=['GET','POST'])
def report():
	if request.method=="POST":
		if 'report1' in request.form:
			mname=[]
			tvalue=[]
			maxdata=mysql_query("SELECT * from members order by total_amount DESC")
			#converting values into list for the chart
			for x in maxdata:
				mname.append(x['member_name'])
				tvalue.append(x['total_amount'])
			return render_template('reports.html',maxdata=maxdata,mname=mname,tvalue=tvalue)
		#the most popular book is taken out on the total issued number
		if 'report2' in request.form:
			tissue=[]
			bname=[]
			bookdata=mysql_query("SELECT b.book_id,b.title,b.authors,b.publication_date,b.stock,b.total,b.publisher,count(t.book_id) from transaction t,books b where b.book_id = t.book_id group by t.book_id order by count(t.book_id) DESC")
			#converting values into list for the chart
			for i in bookdata:
				tissue.append(i['count(t.book_id)'])
				bname.append(i['title'])
			return render_template('reports.html',bookdata=bookdata,tissue=tissue,bname=bname)
	return render_template('reports.html')

#---------------------------------------------------------------------------------------------

#Code For Report generation Ended

#----------------------------------------------------------------------------------------------

#**********************************************************************************************

#--------------------------------------------------------------------------------------------

# For accessing the login page and to view book details use '/login' after the local host address

#---------------------------------------------------------------------------------------------
#Function for Guest view
@app.route('/login',methods=['GET','POST'])
def login():
	if request.method=="POST":
		if 'check' in request.form:
			email=request.form['email']
			data=mysql_query("SELECT member_id from members where member_email='{}'".format(email))
			if data:
				return redirect(url_for('checkbooks'))
			else:
				print("wrong data entered")
	return render_template('login.html')

#Function for showing book details for the guest view users
@app.route('/checkbooks',methods=['GET','POST'])
def checkbooks():
	bdata=mysql_query("SELECT * from books")
	return render_template('checkbooks.html',bdata=bdata)

#--------------------------------------------------------------------------------------------

# Login code ended

#---------------------------------------------------------------------------------------------

if __name__ == "__main__":
	app.run(debug = True)


import datetime
import re
import random
import telebot
import requests

bot = telebot.TeleBot('5703927521:AAG4acGXZHxvhlwpGO6FID7BSFhA2bNrUEw', parse_mode=None)

def log(message):
    with open('log.txt', 'a', encoding='utf-8') as data:
        data.writelines(message.text + ' ' + str(datetime.datetime.now()) + '\n')

def start_msg(message):
    bot.send_message(message.chat.id, f'Hi {message.from_user.first_name}! Welcome!\n'+
    'Choose your destiny by hitting / to see what commands you can use here')

def hello_msg(message):
    bot.send_message(message.chat.id, f'Hi {message.from_user.first_name}!')

def cat(message):
    bot.send_sticker(message.chat.id, random_cat())

def weather_msg(message):
    weather = requests.get("https://wttr.in/?0T")
    bot.send_message(message.chat.id, weather.text)

def random_cat():
    cat_ids = ['CAACAgIAAxkBAAEX9KhjHO5Z0vU1g4DvLHQCqFiHufv3OQAChwUAAiMFDQABE-Nhq6tbXOMpBA',
               'CAACAgIAAxkBAAEX9NdjHPOzfzF63cUVLB9So3NCjSH72wACQQUAAiMFDQABH6kfFQphJ-spBA',
               'CAACAgIAAxkBAAEX9N9jHPP2fbzHJidlFejedmEJhsiu1gACewUAAiMFDQABFvB5J76cyUcpBA',
               'CAACAgIAAxkBAAEX9ONjHPQbO959QfIbYnkjfeqV07dsWwACUAUAAiMFDQABSHMtZmr4rZ4pBA']
    return random.choice(cat_ids)

def math_msg(message):
    equation = message.text.replace('/math', '')
    eq_result = "".join(equation.split())
    if re.match('^([-+]?([(]?[0-9][)]?[+-/*]?))*$', eq_result):
        try:
            bot.send_message(message.chat.id,f"{equation} = {eval(eq_result)}")
        except:
            bot.send_message(message.chat.id,'Ooops error calculating')
    else:
            bot.send_message(message.chat.id,'Wrong pattern')

game_on = False
def guess_game(message):
    global my_number
    global game_on
    game_on = True
    my_number = random.randint(1, 1000)
    invite = bot.send_message(message.chat.id, "Let's play a guessing game! Guess the number I think about from 1 to 1000")

def guess_check(message, my_number):
    global game_on
    guess = int(message.text)
    if guess > 1000:
        bot.send_message(message.chat.id, "My number is lower than 1000")
    elif guess > my_number:
        bot.send_message(message.chat.id, "Lower!")
        game_on = True
    elif guess < my_number:
        bot.send_message(message.chat.id, "Higher!")
        game_on = True
    elif guess == my_number:
        bot.send_message(message.chat.id, "Yay, you got it, that was my number!")
        game_on = False
    else:
        bot.send_message(message.chat.id, "What even is this?")
        game_on = True

@bot.message_handler(content_types=["text", "sticker"])
def main_function(message):
    log(message)
    global game_on
    global my_number
    text = message.text
    if 'start' in text.lower():
        start_msg(message)
    elif 'hello' in text.lower():
        hello_msg(message)
    elif 'cat' in text.lower() :
        cat(message)
    elif 'math' in text.lower():
        invite = bot.send_message(message.chat.id, 'Alright, hit me up with your maths!')
        bot.register_next_step_handler(invite, math_msg)
    elif 'weather' in text.lower():
        weather_msg(message)
    elif text.isdigit() and game_on is True:
        guess_check(message, my_number)
    elif 'game' in text.lower() and game_on is False:
        guess_game(message)

print('server start')
bot.polling(none_stop=True, interval=0)


#!/usr/bin/env python3

import os
from typing import Any

import discord
from discord.ext import commands

import writer_bot.stories
import writer_bot.utils

_log = writer_bot.utils.Logger()

class Bot(commands.Bot):
    def __init__(
        self,
        story_forum_id: int,
        profile_forum_id: int,
        google_api_key: str,
        *args: Any,
        **kwargs: Any
    ) -> None:
        super().__init__(*args, **kwargs)
        self._story_forum_id = story_forum_id
        self._profile_forum_id = profile_forum_id
        self._google_api_key = google_api_key

    async def on_ready(self) -> None:
        await self.add_cog(
            writer_bot.stories.Stories(
                self, self._story_forum_id, self._profile_forum_id, self._google_api_key
            )
        )
        await self.tree.sync()
        _log.info("Connected as user: %s", self.user)

def get_token(var: str) -> str:
    file = os.getenv(var)
    if not file:
        raise ValueError("%s environment variable not set" % var)

    with open(file, encoding="utf-8") as f:
        return f.read().strip()

def get_forum_id(name: str) -> int:
    raw = os.getenv(name)
    if not raw:
        raise ValueError("%s environment variable not set" % name)
    try:
        return int(raw)
    except ValueError as e:
        raise ValueError("%s is not an int" % name) from e

def main() -> None:
    token = get_token("TOKEN_FILE")
    google_api_key = get_token("GOOGLE_API_KEY_FILE")
    story_forum_id = get_forum_id("STORY_FORUM_ID")
    profile_forum_id = get_forum_id("PROFILE_FORUM_ID")

    intents = discord.Intents.default()
    intents.message_content = True
    intents.members = True

    client = Bot(story_forum_id, profile_forum_id, google_api_key, [], intents=intents)

    client.run(token, root_logger=True)

if __name__ == "__main__":
    main()


import pytest
import json

from django.db import connection
from django.test.client import Client
from django.conf import settings

from opencontext_py.apps.ocitems.octypes import models
from opencontext_py.apps.searcher.solrsearcher.models import SolrSearch
from opencontext_py.apps.searcher.solrsearcher.makejsonld import MakeJsonLd

settings.ALLOWED_HOSTS += ['testserver']

def test_hello():
    """
    a hello world test -- will get rid of once I'm more confident of understanding all these pieces
    """
    assert True

def test_main_page():
    """
    load up the homepage
    """

    client = Client()

    response = client.get('/', follow=True)
    assert response.status_code == 200

def test_ssearch():

    client = Client()

    response = client.get('/subjects-search/.json?response=geo-project', follow=True)
    assert response.status_code == 200

def test_project_context():

    client = Client()
    response = client.get('/contexts/projects/3FAAA477-5572-4B05-8DC1-CA264FE1FC10.json', follow=True)
    assert response.status_code == 200

def test_index_solr_doc():

    from opencontext_py.apps.indexer.reindex import SolrReIndex
    uuids = ['3FAAA477-5572-4B05-8DC1-CA264FE1FC10']
    sri = SolrReIndex()
    sri.reindex_uuids(uuids)

def test_other_pages():
    """
    a basic way to test functionality of the overall system by loading various pages
    """

    pages_to_test = [
        '/about',
        '/projects-search/',
        '/subjects-search/#1/-10/13/6/any/Google-Satellite',
        '/search/#2/45.0/0.0/6/any/Google-Satellite',
        '/projects/3FAAA477-5572-4B05-8DC1-CA264FE1FC10'
    ]

    client = Client()

    bad_status_codes = {}

    for page in pages_to_test:
        response = client.get(page,follow=True)
        if response.status_code >= 400:
            bad_status_codes[page] = response.status_code

    if bad_status_codes:
        print (bad_status_codes)
        assert False
    else:
        assert True

def test_num_octypes():
    assert models.OCtype.objects.count() > 0

def test_json_feed():
    spatial_context = 'dc-coverage=loc-sh-sh85025408'
    request_dict_json = json.dumps({'dc-coverage': ['loc-sh-sh85025408'],
       'path': False})

    solr_s = SolrSearch()
    solr_s.is_bot = False  # True if bot detected
    solr_s.do_bot_limit = False  # Toggle limits on facets for bots
    solr_s.do_context_paths = False
    solr_s.item_type_limit = 'projects'

    if solr_s.solr is not False:
        response = solr_s.search_solr(request_dict_json)
        m_json_ld = MakeJsonLd(request_dict_json)
        m_json_ld.base_search_link = '/projects-search/'
        m_json_ld.request_full_path = 'http://octest.raymondyee.net/projects-search.json'
        m_json_ld.spatial_context = spatial_context
        json_ld = m_json_ld.convert_solr_json(response.raw_content)
        print (json.dumps(json_ld, indent=4))

def test_projects_feed():
    spatial_context = None
    request_dict_json = json.dumps({'path': False, 'a': ['c']})

    solr_s = SolrSearch()
    solr_s.is_bot = False  # True if bot detected
    solr_s.do_bot_limit = False  # Toggle limits on facets for bots
    solr_s.do_context_paths = False
    solr_s.item_type_limit = 'projects'

    if solr_s.solr is not False:
        response = solr_s.search_solr(request_dict_json)
        m_json_ld = MakeJsonLd(request_dict_json)
        m_json_ld.base_search_link = '/projects-search/'
        m_json_ld.request_full_path = '/projects-search/'
        m_json_ld.spatial_context = spatial_context
        json_ld = m_json_ld.convert_solr_json(response.raw_content)
        assert json_ld['totalResults'] > 0

def my_custom_sql():

    """
    example of a custom sql query to run for testing
    """

    query = """
-- mediafiles associated with San Diego project?
-- now I can get 251
SELECT COUNT(*)
FROM oc_mediafiles AS media
WHERE
  media.project_uuid = '3FAAA477-5572-4B05-8DC1-CA264FE1FC10' AND
  media.file_type = 'oc-gen:fullfile';
"""
    with connection.cursor() as cursor:
        cursor.execute(query)
        row = cursor.fetchone()

    return row

def test_custom_sql():
    row = my_custom_sql()
    assert row[0] == 251


"""
Landing Page Module's Controllers
"""
from flask import Blueprint, render_template, request, send_from_directory, session
import time

from app import DB as db, REDIS as redis, REDIS_QUEUE as rqueue

from app.mod_tweet.forms import TweetForm

from app.mod_tweet.models import Tweet
from app.mod_auth.models import User

from app.mod_landing_page.tasks import bg_insert_tweet

from common import pretty_result, code

MOD_LANDING_PAGE = Blueprint('landing_page', __name__, url_prefix='/')

def insert_tweet(text, username):
    print(f"Inserting a Tweet")
    start = time.time()

    user = User.query.filter_by(name=username).first()
    tweet = Tweet(text, user=user)
    print(f"Creating a Tweet object: {tweet}")
    # tweet.insert()
    db.session.add(tweet)
    db.session.commit()

    end = time.time()
    time_elapsed = end - start
    return f"Stored to Database in {time_elapsed} ms"

@MOD_LANDING_PAGE.route('', methods=['GET', 'POST'])
def landing_page():
    """
    Return a HTML of Landing Page.
    """
    username = session['username']
    form = TweetForm(request.form)
    if form.validate_on_submit():
        task = rqueue.enqueue(bg_insert_tweet, form.tweet.data, username)
        form.tweet.data = ""
    tweets = Tweet.query.order_by(Tweet.id.desc()).limit(5)
    return render_template("landing_page/landing_page.html", username=username, tweets=tweets, form=form)

@MOD_LANDING_PAGE.route('/tweet', methods=['GET', 'POST'])
def get_tweet():
    """
    Return tweets
    """
    if request.method == 'GET':
        query_tweets = Tweet.query.order_by(Tweet.id.desc()).limit(5)
        tweets = []
        for query_tweet in query_tweets:
            tweets.append({
                'tweet': query_tweet.text,
                'username': query_tweet.get_username(),
                'user_id': query_tweet.user_id,
            })
        return pretty_result(code.OK, data=tweets)
    else:
        result = insert_tweet(request.form['text'], request.form['username'])
        return result

@MOD_LANDING_PAGE.route('/robots.txt', methods=['GET', 'POST'])
def robots():
    """
    Return robot.txt file.
    """
    return send_from_directory('static/', filename='robots.txt')