#How many Sundays fell on the first of the month during the twentieth century (1 Jan 1901 to 31 Dec 2000)?
#1 Jan 1900 was a Monday.

months = ['jan', 'feb', 'mar', 'apr', 'may', 'jun', 'jul', 'aug','sep','oct', 'nov', 'dec']

def make_calendar(year):
    calendar = {}
    for i in months:
        if i == "feb" and year != "leap":
            calendar[i] = 28
        elif i == "feb" and year == "leap":
            calendar[i] = 29
        elif i == "apr" or i == 'jun' or i == 'sep' or i == 'nov':
            calendar[i] = 30
        else:
            calendar[i] = 31
    return calendar

def count_sundays():
    countS = 0
    sunday = 7 #initialize the first sunday as 7th of Jan, 1901
    for years in range(1, 100):
        if (years+1900 != 2000) or ((years+1900) % 4 != 0):
            calendar = make_calendar("normal") #go create a calender of normal years
        else:
            calendar = make_calendar("leap") #go create a calendar of leap years
        for month in months:
            while sunday <= calendar[month]:
                sunday += 7
            sunday = sunday - calendar[month]
            if sunday == 1:
                countS += 1
        print(sunday)
    return countS

print(count_sundays())


from requests import get
from scrapy import Selector

response = get("https://fr.wikipedia.org/wiki/Guerre_d%27Alg%C3%A9rie")
source = None
if response.status_code == 200 :
    source = response.text

if source :
    selector = Selector(text=source)
    titles = selector.css("div.toc ul > li")
    for title in titles:
        level = title.css("span.tocnumber::text").extract_first()
        name = title.css("span.toctext::text").extract_first()
        print(level + " " + name)


import os

class Directory:
    def __init__(self, full_path, pages):
        self.full_path = full_path
        self.dirname = os.path.basename(full_path)
        self.pages = pages

        self.title = self.dirname.replace('_', ' ').title()
        # If the index.md file has a title other than Index, use it
        for page in pages:
            if page.filename == 'index' and page.title != 'Index':
                self.title = page.title

    def __repr__(self):
        return "%s: %s. Pages:" % (self.full_path, self.title) + ", ".join(map(str, self.pages))

class Page:
    def __init__(self, full_path):
        self.full_path = full_path
        self.filename, _ = os.path.splitext(os.path.basename(full_path))

        # If an h1 is defined in the document, use that as the title
        file = open(full_path)
        first_line = file.readline()
        if first_line.startswith('# '):
            self.title = first_line[1:].strip()
        else:
            # Otherwise, fall back on the filename, unslugifed
            self.title = self.filename.replace('-', ' ').title()

    def __repr__(self):
        return "%s: %s" % (self.title, self.full_path)


# 移到'Laszlo'并得到他的秘密号码。
hero.moveXY(30, 13)
las = hero.findNearestFriend().getSecret()

# 向 Laszlo 的数字中加7就能得到 Erzsebet的号码
# 移到'Erzsebet'并说出她的魔法数字。
erz = las + 7
hero.moveXY(17, 26)
hero.say(erz)

# 将 Erzsebet 的数字除以 4 得到 Simoyi 的数字。
# 去'Simony'并告诉他他的电话号码。
sim = erz / 4
hero.moveXY(30, 39)
hero.say(sim)
# 将 Simonyi 的数字乘以 Laszlo 的数字得到 Agata 的数字。
aga = sim * las
hero.moveXY(43, 26)
hero.say(aga)
# 去'Agata'并告诉她她的电话号码。


import json

from nose.tools import ok_, eq_, assert_is_not_none

try:
    from mock import Mock, patch
except ImportError:
    from unittest.mock import Mock, patch

try:
    from httplib import OK
except:
    from http.client import OK

from uuid import uuid4
from time import sleep

from config import *
from application import application
from utils import background_smtp_send

base_url = '/api/v{}'.format(API_VERSION)

auth_hdr = {
    'X-Auth-Token': API_SECRET
}

application.testing = True
app = application.test_client()

class Country():
    def __init__(self, name, alpha2):
        self.name = name
        self.alpha2 = alpha2

class ASN():
    def __init__(self, alpha2, service, name):
        self.alpha2 = alpha2
        self.service = service
        self.name = name

class Domains():
    def __init__(self, alpha2, service, name):
        self.alpha2 = alpha2
        self.service = service
        self.name = name

class Service():
    def __init__(self, alpha2, default, name):
        self.alpha2 = alpha2
        self.default = default
        self.name = name

@patch('utils.smtplib')
def test_background_smtp_send_returns_thread(mock):
    smtplib = Mock()
    mock.return_value = smtplib
    smtplib.smtp = None
    smtplib.ehlo = None
    smtplib.login = None
    smtplib.sendmail = None
    smtplib.quit = None
    process = background_smtp_send(
        subject='{} payment of {} Satoshi received from {}'.format(
            'btc-testnet',
            '100000',
            uuid4().hex
        ),
        preamble='Bitcoin payment notification',
        body=json.dumps(
            {
                'webhook': {
                    'hello': 'world'
                },
                'api_response': {'hello': 'world'}
            }
        )
    )
    assert_is_not_none(process)
    eq_(process.is_alive(), True)
    while process.is_alive(): sleep(0.1)

def test_country_endpoint_returns_correct_alpha2():
    def check_country_alpha2_by_country_name(country):
        response = app.get(
            '{}/country/{}'.format(
                base_url,
                country.name
            ),
            headers=auth_hdr
        )
        ok_(response.status_code == OK)
        eq_(country.alpha2, response.data.decode())

    for country in [
        Country('United Kingdom', 'GB'),
        Country('United States', 'US')
    ]: yield check_country_alpha2_by_country_name, country

def test_asn_endpoint_returns_correct_asns_for_service():
    def check_asns_by_service(asn):
        response = app.get(
            '{}/alpha/{}/asns/{}'.format(
                base_url,
                asn.alpha2,
                asn.service
            ),
            headers=auth_hdr
        )
        ok_(response.status_code == OK)
        eq_(asn.name, response.data.decode())

    for asn in [
        ASN('GB', 'iplayer', 'AS2818'),
        ASN('US', 'netflix', 'AS2906')
    ]: yield check_asns_by_service, asn

def test_asn_endpoint_returns_correct_domains_for_service():
    def check_domains_by_service(domain):
        response = app.get(
            '{}/alpha/{}/domains/{}'.format(
                base_url,
                domain.alpha2,
                domain.service
            ),
            headers=auth_hdr
        )
        ok_(response.status_code == OK)
        assert domain.name in (response.data.decode()).split(' ')

    for domain in [
        ASN('GB', 'iplayer', 'bbc.co.uk'),
        ASN('US', 'netflix', 'netflix.com')
    ]: yield check_domains_by_service, domain

def test_service_endpoint_returns_correct_services():
    def check_available_services_by_alpha2(service):
        response = app.get(
            '{}/alpha/{}/services/default/{}'.format(
                base_url,
                service.alpha2,
                service.default
            ),
            headers=auth_hdr
        )
        ok_(response.status_code == OK)
        assert service.name in (response.data.decode()).split(' ')

    for service in [
        Service('GB', '1', 'common'),
        Service('US', '1', 'common'),
        Service('US', '0', 'netflix'),
        Service('GB', '0', 'iplayer')
    ]: yield check_available_services_by_alpha2, service


import os
import pyautogui
import cv2
import numpy as np
import time
import win32gui
import win32con

def GetDevicesList():
    list = os.popen("adb devices").read().split('\n')
    deviceList = []
    for temp in list:
        if len(temp.split()) > 1:
            if temp.split()[1] == 'device':
                deviceList.append(temp.split()[0])
    print('本次共扫描出 {} 个设备 ：{} '.format(len(deviceList),deviceList))
    return deviceList

def Boot_Grid_AndroidScreen(deviceList):
    window_dic = {}
    Screen_Height = 960
    screen_count = 0
    for device in deviceList:
        print("%s的投屏" % device)
        command = "scrcpy -m {} --power-off-on-close -w --window-borderless --window-title {} --bit-rate 4M -S -s {}".format(
            Screen_Height, device, device)
        t = os.popen(command)
        time.sleep(2)
        h = win32gui.FindWindow(None, device)
        rect = win32gui.GetWindowRect(h)
        app_x = rect[2] - rect[0]
        app_y = rect[3] - rect[1]
        screen_id = (screen_count // ((1920 // app_y) * (1080 // app_x)))
        screen_xcoor = (screen_count % (1920 // app_y)) * app_y + 1920 * screen_id
        screen_ycoor = (screen_count % ((1920 // app_y) * (1080 // app_x))) // (1920 // app_y) * app_x
        win32gui.SetWindowPos(h, win32con.TRANSPARENT, screen_xcoor - 1920, screen_ycoor, rect[2] - rect[0],
                              rect[3] - rect[1],
                              win32con.SWP_SHOWWINDOW)
        # window_dic[device] = {'pid': h}
        screen_count += 1

def swap_test():
    pass

if __name__ == '__main__':
    # print(GetDevicesList())
    Boot_Grid_AndroidScreen(GetDevicesList())
    swap_test()

"""
adb shell pm list packages -3  查看三方应用

adb shell am start com.netease.g67/com.netease.game.MessiahNativeActivity            启动暗黑

adb shell am force-stop com.netease.g67

adb shell input keyboard text "abc"  模拟输入

adb shell input tap 500 500  模拟点击

adb shell input swipe 500 300 400 300  模拟滑动  （x,y）->(x,y)

adb shell input swipe 500 300 100 300 500
adb shell input swipe 100 300 100 300 50000

adb shell input tap 600 800

"""


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Sat Mar 20 21:29:31 2021

@author: skibbe
"""

import numpy as np
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.multiprocessing as mp
#from . import tools as tls
from pw import tools as tls
import math
#mp.set_start_method('spawn')
#import pw.tools as pw_tools

class batch_mat():

    def __init__(self,
                 dim,
                  dtype = torch.float32,
                  device="cpu"):
       self.dtype = dtype
       self.device = device
       if dim == 2:
            self.identity = torch.tensor([[1,0,0],
                             [0,1,0],
                             [0,0,1]],dtype = torch.float32,device=device)
       else:
            self.identity = torch.tensor([[1,0,0,0],
                           [0,1,0,0],
                           [0,0,1,0],
                           [0,0,0,1]],dtype = torch.float32,device=device)

       self.dim = dim

    def batch_identity(self,batch_size):
        return self.identity[None,:,:].repeat([batch_size,1,1])

    def ext_vec(self,x):
        return torch.cat((tls.tt(x),torch.ones(x.shape[0],1,device=x.device,dtype=x.dtype)),dim=1)[:,:,None]

    def transl_mat(self,x):
        dim = x.shape[1]
        batch_size = x.shape[0]
        mat = torch.zeros([batch_size,dim+1,dim+1],device=self.device,dtype=self.dtype)
        #print(mat.shape)
        #print(x.shape)
        mat[:,-1,:dim] = x[:,:]
        for d in range(dim+1):
            mat[:,d,d] = 1
        return mat

    def batch_diag(self,vec):
        assert(False)
        mat = self.ext_vec(vec)
        return torch.einsum('exy,bxd->bxy',self.identity[None,:,:],mat)

    #def batch_mm_diag(self,matA,vecB):
    #    matB = self.ext_vec(vecB.to(device=self.device))
    #    return torch.einsum('bxy,bxd->bxy',matA,matB)

    #batch_mm = lambda matA,matB : torch.einsum('bzx,byz->bxy',matA,matB)
    def batch_mm(self,matA,matB):
        return torch.matmul(matA,matB)
        #return torch.einsum('bxz,bzy->bxy',matA,matB)
    #batch_mult_diag = lambda matA,matB :  torch.einsum('bxy,bxd->bxy',matA,extvec(matB))

    def batch_m_inverse(self,mat):
        return torch.linalg.inv(matA,matB)
        #mat_ = torch.zeros(mat.shape,dtype=mat.dtype,device=mat.device)
        #for b in mat.shape[0]:
        #    mat_[b,...] = torch.inverse(mat[b,...])
        #return mat_

    def diag_mat(self,aug_scales):
        num_batches = aug_scales.shape[0]
        assert(aug_scales.shape[1] == self.dim)
        scale_mat = torch.zeros([num_batches,self.dim+1,self.dim+1],dtype = self.dtype,device=self.device)
        for a in range(aug_scales.shape[1]):
            scale_mat[:,a,a] = aug_scales[:,a]
        scale_mat[:,-1,-1] = 1
        return scale_mat

    def quat2rot(self,aug_rotations_):
        aug_rotations = aug_rotations_.clone()
        num_batches = aug_rotations.shape[0]
        if aug_rotations.shape[1] == 4:
            rotate = tls.tt(aug_rotations)
            #rotate[:,:3] = 0
            #rotate[:,0] = 1
            #rotate[:,3] = math.pi/2.0
            rotate[:,:3]= aug_rotations[:,:3]/torch.norm(aug_rotations[:,:3],dim=1, keepdim=True)
            #print(rotate[0,:3])
            qr = torch.cos(rotate[:,3]/2.0)
            sin_ = torch.sin(rotate[:,3]/2.0)
            qi = rotate[:,0] * sin_
            qj = rotate[:,1] * sin_
            qk = rotate[:,2] * sin_
            rot_mat = torch.zeros([num_batches,4,4],dtype = self.dtype,device=self.device)
            rot_mat[:,0,0] = 1.0-2.0*(qj**2+qk**2)
            rot_mat[:,0,1] = 2*(qi*qj+qk*qr)
            rot_mat[:,0,2] = 2*(qi*qk-qj*qr)

            rot_mat[:,1,0] = 2*(qi*qj-qk*qr)
            rot_mat[:,1,1] = 1-2*(qi**2+qk**2)
            rot_mat[:,1,2] = 2*(qj*qk+qi*qr)

            rot_mat[:,2,0] = 2*(qi*qk+qj*qr)
            rot_mat[:,2,1] = 2*(qj*qk-qi*qr)
            rot_mat[:,2,2] = 1-2*(qi**2+qj**2)
            rot_mat[:,3,3] = 1
        else:
            rotate = torch.squeeze(tls.tt(aug_rotations))
            rot_mat = torch.zeros([num_batches,3,3],dtype = self.dtype,device=self.device)
            rot_mat[:,0,0] = torch.cos(rotate)
            rot_mat[:,0,1] = torch.sin(rotate)
            rot_mat[:,1,0] = -rot_mat[:,0,1]
            rot_mat[:,1,1] = rot_mat[:,0,0]
            rot_mat[:,2,2] = 1
            #rot_mat = torch.tensor([[math.cos(rotate),math.sin(rotate),0],[-math.sin(rotate),math.cos(rotate),0],[0,0,1]],dtype = torch.float32,device=aug_device)

        return rot_mat


"""
The format table for standard sizes and alignments.
"""

# Note: we follow Python 2.5 in being strict about the ranges of accepted
# values when packing.

import struct

from rpython.rlib.objectmodel import specialize
from rpython.rlib.rarithmetic import r_uint, r_longlong, r_ulonglong
from rpython.rlib.rstruct import ieee
from rpython.rlib.rstruct.error import StructError, StructOverflowError
from rpython.rlib.unroll import unrolling_iterable
from rpython.rlib.buffer import StringBuffer
from rpython.rlib import rarithmetic
from rpython.rlib.buffer import CannotRead, CannotWrite
from rpython.rtyper.lltypesystem import rffi

USE_FASTPATH = True    # set to False by some tests
ALLOW_SLOWPATH = True  # set to False by some tests
ALLOW_FASTPATH = True  # set to False by some tests

native_is_bigendian = struct.pack("=i", 1) == struct.pack(">i", 1)
native_is_ieee754 = float.__getformat__('double').startswith('IEEE')

@specialize.memo()
def pack_fastpath(TYPE):
    """
    Create a fast path packer for TYPE. The packer returns True is it succeded
    or False otherwise.
    """
    @specialize.argtype(0)
    def do_pack_fastpath(fmtiter, value):
        size = rffi.sizeof(TYPE)
        if (not USE_FASTPATH or
            fmtiter.bigendian != native_is_bigendian or
            not native_is_ieee754):
            raise CannotWrite
        #
        # typed_write() might raise CannotWrite
        fmtiter.wbuf.typed_write(TYPE, fmtiter.pos, value)
        if not ALLOW_FASTPATH:
            # if we are here it means that typed_write did not raise, and thus
            # the fast path was actually taken
            raise ValueError("fastpath not allowed :(")
        fmtiter.advance(size)
    #
    @specialize.argtype(0)
    def do_pack_fastpath_maybe(fmtiter, value):
        try:
            do_pack_fastpath(fmtiter, value)
        except CannotWrite:
            if not ALLOW_SLOWPATH:
                raise ValueError("fastpath not taken :(")
            return False
        else:
            return True
    #
    return do_pack_fastpath_maybe

def pack_pad(fmtiter, count):
    fmtiter.wbuf.setzeros(fmtiter.pos, count)
    fmtiter.advance(count)

def pack_char(fmtiter):
    string = fmtiter.accept_str_arg()
    if len(string) != 1:
        raise StructError("expected a string of length 1")
    c = string[0]   # string->char conversion for the annotator
    fmtiter.wbuf.setitem(fmtiter.pos, c)
    fmtiter.advance(1)

def pack_bool(fmtiter):
    c = '\x01' if fmtiter.accept_bool_arg() else '\x00'
    fmtiter.wbuf.setitem(fmtiter.pos, c)
    fmtiter.advance(1)

def _pack_string(fmtiter, string, count):
    pos = fmtiter.pos
    if len(string) < count:
        n = len(string)
        fmtiter.wbuf.setslice(pos, string)
        fmtiter.wbuf.setzeros(pos+n, count-n)
    else:
        assert count >= 0
        fmtiter.wbuf.setslice(pos, string[:count])
    fmtiter.advance(count)

def pack_string(fmtiter, count):
    string = fmtiter.accept_str_arg()
    _pack_string(fmtiter, string, count)

def pack_pascal(fmtiter, count):
    string = fmtiter.accept_str_arg()
    prefix = len(string)
    if prefix >= count:
        prefix = count - 1
        if prefix < 0:
            raise StructError("bad '0p' in struct format")
    if prefix > 255:
        prefix = 255
    fmtiter.wbuf.setitem(fmtiter.pos, chr(prefix))
    fmtiter.advance(1)
    _pack_string(fmtiter, string, count-1)

def pack_halffloat(fmtiter):
    size = 2
    fl = fmtiter.accept_float_arg()
    try:
        result = ieee.pack_float(fmtiter.wbuf, fmtiter.pos,
                                 fl, size, fmtiter.bigendian)
    except OverflowError:
        raise StructOverflowError("float too large for format 'e'")
    else:
        fmtiter.advance(size)
        return result

def make_float_packer(TYPE):
    size = rffi.sizeof(TYPE)
    def packer(fmtiter):
        fl = fmtiter.accept_float_arg()
        if TYPE is not rffi.FLOAT and pack_fastpath(TYPE)(fmtiter, fl):
            return
        # slow path
        try:
            result = ieee.pack_float(fmtiter.wbuf, fmtiter.pos,
                                     fl, size, fmtiter.bigendian)
        except OverflowError:
            assert size == 4
            raise StructOverflowError("float too large for format 'f'")
        else:
            fmtiter.advance(size)
            return result
    return packer

# ____________________________________________________________

native_int_size = struct.calcsize("l")

def min_max_acc_method(size, signed):
    if signed:
        min = -(2 ** (8*size-1))
        max = (2 ** (8*size-1)) - 1
        if size <= native_int_size:
            accept_method = 'accept_int_arg'
            min = int(min)
            max = int(max)
        else:
            accept_method = 'accept_longlong_arg'
            min = r_longlong(min)
            max = r_longlong(max)
    else:
        min = 0
        max = (2 ** (8*size)) - 1
        if size < native_int_size:
            accept_method = 'accept_int_arg'
        elif size == native_int_size:
            accept_method = 'accept_uint_arg'
            min = r_uint(min)
            max = r_uint(max)
        else:
            accept_method = 'accept_ulonglong_arg'
            min = r_ulonglong(min)
            max = r_ulonglong(max)
    return min, max, accept_method

def make_int_packer(size, signed, _memo={}):
    key = size, signed
    try:
        return _memo[key]
    except KeyError:
        pass
    min, max, accept_method = min_max_acc_method(size, signed)
    if size > 1:
        plural = "s"
    else:
        plural = ""
    errormsg = "argument out of range for %d-byte%s integer format" % (size,
                                                                       plural)
    unroll_revrange_size = unrolling_iterable(range(size-1, -1, -1))
    TYPE = get_rffi_int_type(size, signed)

    def pack_int(fmtiter):
        method = getattr(fmtiter, accept_method)
        value = method()
        if not min <= value <= max:
            raise StructError(errormsg)
        #
        if pack_fastpath(TYPE)(fmtiter, value):
            return
        #
        pos = fmtiter.pos + size - 1
        if fmtiter.bigendian:
            for i in unroll_revrange_size:
                x = (value >> (8*i)) & 0xff
                fmtiter.wbuf.setitem(pos-i, chr(x))
        else:

            for i in unroll_revrange_size:
                fmtiter.wbuf.setitem(pos-i, chr(value & 0xff))
                value >>= 8
        fmtiter.advance(size)

    _memo[key] = pack_int
    return pack_int

# ____________________________________________________________

@specialize.memo()
def unpack_fastpath(TYPE):
    @specialize.argtype(0)
    def do_unpack_fastpath(fmtiter):
        size = rffi.sizeof(TYPE)
        buf, pos = fmtiter.get_buffer_and_pos()
        if not USE_FASTPATH:
            raise CannotRead
        #
        if not ALLOW_FASTPATH:
            raise ValueError("fastpath not allowed :(")
        # typed_read does not do any bound check, so we must call it only if
        # we are sure there are at least "size" bytes to read
        if fmtiter.can_advance(size):
            result = buf.typed_read(TYPE, pos)
            fmtiter.advance(size)
            return result
        else:
            # this will raise StructError
            fmtiter.advance(size)
            assert False, 'fmtiter.advance should have raised!'
    return do_unpack_fastpath

@specialize.argtype(0)
def unpack_pad(fmtiter, count):
    fmtiter.read(count)

@specialize.argtype(0)
def unpack_char(fmtiter):
    fmtiter.appendobj(fmtiter.read(1))

@specialize.argtype(0)
def unpack_bool(fmtiter):
    c = ord(fmtiter.read(1)[0])
    fmtiter.appendobj(bool(c))

@specialize.argtype(0)
def unpack_string(fmtiter, count):
    fmtiter.appendobj(fmtiter.read(count))

@specialize.argtype(0)
def unpack_pascal(fmtiter, count):
    if count == 0:
        raise StructError("bad '0p' in struct format")
    data = fmtiter.read(count)
    end = 1 + ord(data[0])
    if end > count:
        end = count
    fmtiter.appendobj(data[1:end])

@specialize.argtype(0)
def unpack_halffloat(fmtiter):
    data = fmtiter.read(2)
    fmtiter.appendobj(ieee.unpack_float(data, fmtiter.bigendian))

def make_ieee_unpacker(TYPE):
    @specialize.argtype(0)
    def unpack_ieee(fmtiter):
        size = rffi.sizeof(TYPE)
        if fmtiter.bigendian != native_is_bigendian or not native_is_ieee754:
            # fallback to the very slow unpacking code in ieee.py
            data = fmtiter.read(size)
            fmtiter.appendobj(ieee.unpack_float(data, fmtiter.bigendian))
            return
        ## XXX check if the following code is still needed
        ## if not str_storage_supported(TYPE):
        ##     # this happens e.g. on win32 and ARM32: we cannot read the string
        ##     # content as an array of doubles because it's not properly
        ##     # aligned. But we can read a longlong and convert to float
        ##     assert TYPE == rffi.DOUBLE
        ##     assert rffi.sizeof(TYPE) == 8
        ##     return unpack_longlong2float(fmtiter)
        try:
            # fast path
            val = unpack_fastpath(TYPE)(fmtiter)
        except CannotRead:
            # slow path: we should arrive here only if we could not unpack
            # because of alignment issues. So we copy the slice into a new
            # string, which is guaranteed to be properly aligned, and read the
            # float/double from there
            input = fmtiter.read(size)
            val = StringBuffer(input).typed_read(TYPE, 0)
        fmtiter.appendobj(float(val))
    return unpack_ieee

@specialize.argtype(0)
def unpack_longlong2float(fmtiter):
    from rpython.rlib.rstruct.runpack import runpack
    from rpython.rlib.longlong2float import longlong2float
    s = fmtiter.read(8)
    llval = runpack('q', s) # this is a bit recursive, I know
    doubleval = longlong2float(llval)
    fmtiter.appendobj(doubleval)

unpack_double = make_ieee_unpacker(rffi.DOUBLE)
unpack_float = make_ieee_unpacker(rffi.FLOAT)

# ____________________________________________________________

def get_rffi_int_type(size, signed):
    for TYPE in rffi.platform.numbertype_to_rclass:
        if (rffi.sizeof(TYPE) == size and
            rarithmetic.is_signed_integer_type(TYPE) == signed):
            return TYPE
    raise KeyError("Cannot find an int type size=%d, signed=%d" % (size, signed))

def make_int_unpacker(size, signed, _memo={}):
    try:
        return _memo[size, signed]
    except KeyError:
        pass
    if signed:
        if size <= native_int_size:
            inttype = int
        else:
            inttype = r_longlong
    else:
        if size < native_int_size:
            inttype = int
        elif size == native_int_size:
            inttype = r_uint
        else:
            inttype = r_ulonglong
    unroll_range_size = unrolling_iterable(range(size))
    TYPE = get_rffi_int_type(size, signed)

    @specialize.argtype(0)
    def unpack_int_fastpath_maybe(fmtiter):
        if fmtiter.bigendian != native_is_bigendian or not native_is_ieee754:
            return False
        try:
            intvalue = unpack_fastpath(TYPE)(fmtiter)
        except CannotRead:
            return False
        if not signed and size < native_int_size:
            intvalue = rarithmetic.intmask(intvalue)
        intvalue = inttype(intvalue)
        fmtiter.appendobj(intvalue)
        return True

    @specialize.argtype(0)
    def unpack_int(fmtiter):
        if unpack_int_fastpath_maybe(fmtiter):
            return
        # slow path
        if not ALLOW_SLOWPATH:
            # we enter here only on some tests
            raise ValueError("fastpath not taken :(")
        intvalue = inttype(0)
        s = fmtiter.read(size)
        idx = 0
        if fmtiter.bigendian:
            for i in unroll_range_size:
                x = ord(s[idx])
                if signed and i == 0 and x >= 128:
                    x -= 256
                intvalue <<= 8
                intvalue |= inttype(x)
                idx += 1
        else:
            for i in unroll_range_size:
                x = ord(s[idx])
                if signed and i == size - 1 and x >= 128:
                    x -= 256
                intvalue |= inttype(x) << (8*i)
                idx += 1
        fmtiter.appendobj(intvalue)

    _memo[size, signed] = unpack_int
    return unpack_int

# ____________________________________________________________

standard_fmttable = {
    'x':{ 'size' : 1, 'pack' : pack_pad, 'unpack' : unpack_pad,
          'needcount' : True },
    'c':{ 'size' : 1, 'pack' : pack_char, 'unpack' : unpack_char},
    's':{ 'size' : 1, 'pack' : pack_string, 'unpack' : unpack_string,
          'needcount' : True },
    'p':{ 'size' : 1, 'pack' : pack_pascal, 'unpack' : unpack_pascal,
          'needcount' : True },
    'e':{ 'size' : 2, 'pack' : pack_halffloat,
                    'unpack' : unpack_halffloat},
    'f':{ 'size' : 4, 'pack' : make_float_packer(rffi.FLOAT),
                    'unpack' : unpack_float},
    'd':{ 'size' : 8, 'pack' : make_float_packer(rffi.DOUBLE),
                    'unpack' : unpack_double},
    '?':{ 'size' : 1, 'pack' : pack_bool, 'unpack' : unpack_bool},
    }

for c, size in [('b', 1), ('h', 2), ('i', 4), ('l', 4), ('q', 8)]:
    standard_fmttable[c] = {'size': size,
                            'pack': make_int_packer(size, True),
                            'unpack': make_int_unpacker(size, True)}
    standard_fmttable[c.upper()] = {'size': size,
                                    'pack': make_int_packer(size, False),
                                    'unpack': make_int_unpacker(size, False)}


# JIT (Just in Time) Derleyicisi ile Flax module :

class MLP(nn.Module):
  features: Sequence[int]

  @nn.compact
  def __call__(self, inputs):
    x = inputs
    for i, feat in enumerate(self.features):
      # JIT the Module (it's __call__ fn by default.)
      x = nn.jit(nn.Dense)(feat, name=f'layers_{i}')(x)
      if i != len(self.features) - 1:
        x = nn.relu(x)
    return x

key1, key2 = random.split(random.PRNGKey(3), 2)
x = random.uniform(key1, (4,4))

model = MLP(features=[3,4,5])
init_variables = model.init(key2, x)
y = model.apply(init_variables, x)

print('initialized parameter shapes:\n', jax.tree_util.tree_map(jnp.shape, unfreeze(init_variables)))
print('output:\n', y)

# Vmap (vectorization map) Derleyicisi ile module :
class RawDotProductAttention(nn.Module):
  attn_dropout_rate: float = 0.1
  train: bool = False

  @nn.compact
  def __call__(self, query, key, value, bias=None, dtype=jnp.float32):
    assert key.ndim == query.ndim
    assert key.ndim == value.ndim

    n = query.ndim
    attn_weights = lax.dot_general(
        query, key,
        (((n-1,), (n - 1,)), ((), ())))
    if bias is not None:
      attn_weights += bias
    norm_dims = tuple(range(attn_weights.ndim // 2, attn_weights.ndim))
    attn_weights = jax.nn.softmax(attn_weights, axis=norm_dims)
    attn_weights = nn.Dropout(self.attn_dropout_rate)(attn_weights,
                                                      deterministic=not self.train)
    attn_weights = attn_weights.astype(dtype)

    contract_dims = (
        tuple(range(n - 1, attn_weights.ndim)),
        tuple(range(0, n  - 1)))
    y = lax.dot_general(
        attn_weights, value,
        (contract_dims, ((), ())))
    return y

class DotProductAttention(nn.Module):
  qkv_features: Optional[int] = None
  out_features: Optional[int] = None
  train: bool = False

  @nn.compact
  def __call__(self, inputs_q, inputs_kv, bias=None, dtype=jnp.float32):
    qkv_features = self.qkv_features or inputs_q.shape[-1]
    out_features = self.out_features or inputs_q.shape[-1]

    QKVDense = functools.partial(
      nn.Dense, features=qkv_features, use_bias=False, dtype=dtype)
    query = QKVDense(name='query')(inputs_q)
    key = QKVDense(name='key')(inputs_kv)
    value = QKVDense(name='value')(inputs_kv)

    y = RawDotProductAttention(train=self.train)(
        query, key, value, bias=bias, dtype=dtype)

    y = nn.Dense(features=out_features, dtype=dtype, name='out')(y)
    return y

class MultiHeadDotProductAttention(nn.Module):
  qkv_features: Optional[int] = None
  out_features: Optional[int] = None
  batch_axes: Sequence[int] = (0,)
  num_heads: int = 1
  broadcast_dropout: bool = False
  train: bool = False
  @nn.compact
  def __call__(self, inputs_q, inputs_kv, bias=None, dtype=jnp.float32):
    qkv_features = self.qkv_features or inputs_q.shape[-1]
    out_features = self.out_features or inputs_q.shape[-1]

    # Tekli Dikkat boyutundan Çoklu Dikkat (Multi-Headed) boyutuna geçiş.
    Attn = nn.vmap(DotProductAttention,
                   in_axes=(None, None, None),
                   out_axes=2,
                   axis_size=self.num_heads,
                   variable_axes={'params': 0},
                   split_rngs={'params': True,
                               'dropout': not self.broadcast_dropout})

    # Vmap batch boyutları arasında.
    for axis in reversed(sorted(self.batch_axes)):
      Attn = nn.vmap(Attn,
                     in_axes=(axis, axis, axis),
                     out_axes=axis,
                     variable_axes={'params': None},
                     split_rngs={'params': False, 'dropout': False})

    # vmap ile sınıflandırılmış girdiler.
    y = Attn(qkv_features=qkv_features // self.num_heads,
             out_features=out_features,
             train=self.train,
             name='attention')(inputs_q, inputs_kv, bias)

    return y.mean(axis=-2)

key1, key2, key3, key4 = random.split(random.PRNGKey(0), 4)
x = random.uniform(key1, (3, 13, 64))

model = functools.partial(
  MultiHeadDotProductAttention,
  broadcast_dropout=False,
  num_heads=2,
  batch_axes=(0,))

init_variables = model(train=False).init({'params': key2}, x, x)
print('initialized parameter shapes:\n', jax.tree_util.tree_map(jnp.shape, unfreeze(init_variables)))

y = model(train=True).apply(init_variables, x, x, rngs={'dropout': key4})
print('output:\n', y.shape)


from webiopi.clients import *
from time import sleep

# Create a WebIOPi client
client = PiHttpClient("192.168.1.83")
#client = PiMixedClient("192.168.1.234")
#client = PiCoapClient("192.168.1.234")
#client = PiMulticastClient()

client.setCredentials("webiopi","Webiopi2016")

# RPi native GPIO
#gpio = NativeGPIO(client)
#gpio.setFunction(25, "out")
#state = True

# DAC named "dac1"
#dac = DAC(client, "dac1")

# ADC named "adc1"
#adc = ADC(client, "adc1")
#value = 0.0

# Temperature sensor named "temp0"
temp = Temperature(client, "temp0")

while True:
    # Retrieve temperature
    t = temp.getCelsius()
    print("Temperature = %.2f Celsius" % t)

    sleep(1)


import math

def test():
    a, b, c = [8, 5, 7]
    triangle_type(a, b, c)

def triangle_type(a: float, b: float, c: float):
    if a + b > c and a + c > b and b + c > a:
        cos_a = round(math.degrees(math.acos(float(a**2 + c**2 - b**2) / float(2*a*c))))
        cos_b = round(math.degrees(math.acos(float(a**2 + b**2 - c**2) / float(2*a*b))))
        cos_c = round(180 - cos_a - cos_b)
        if cos_c < 90 and cos_b < 90 and cos_a < 90:
            return 1
        elif cos_c == 90 or cos_b == 90 or cos_a == 90:
            return 2
        else:
            return 3
    else:
        return 0

test()