import sys
import os
from phgl_imp import *
from .zqh_core_common_misc import IFU_CONSTS
from .zqh_core_common_misc import M_CONSTS
from .zqh_core_common_ifu_parameters import zqh_core_common_ifu_parameter
from .zqh_core_common_ifu_bundles import zqh_core_common_ifu_icache_io
from .zqh_core_common_ifu_bundles import zqh_core_common_ifu_slave_io
from zqh_tilelink.zqh_tilelink_node_module_main import zqh_tilelink_node_module

class zqh_core_common_ifu_icache_itim(zqh_tilelink_node_module):
    def set_par(self):
        super(zqh_core_common_ifu_icache_itim, self).set_par()
        self.p = zqh_core_common_ifu_parameter()

    def gen_node_tree(self):
        super(zqh_core_common_ifu_icache_itim, self).gen_node_tree()
        self.gen_node_master(
            'icache_master',
            size_min = 0,
            size_max = 64,
            bundle_p = self.p.gen_tl_bundle_p(),
            source_id_num = 1)

    def set_port(self):
        super(zqh_core_common_ifu_icache_itim, self).set_port()
        self.io.var(zqh_core_common_ifu_icache_io('fetch'))
        if (self.p.itim_size != 0):
            vmacro('USE_ITIM')
            self.io.var(zqh_core_common_ifu_slave_io('slave'))

    def main(self):
        super(zqh_core_common_ifu_icache_itim, self).main()
        self.gen_node_interface('icache_master')
        assert(self.tl_out.a.bits.p.data_bits >= self.p.inst_bits)

        tag_ecc_code = ecc_code(self.p.tag_ecc)
        data_ecc_code = ecc_code(self.p.data_ecc)

        tag_valid_bits = vec(
            'tag_valid_bits',
            gen = lambda _: reg_r(_, w = self.p.num_ways),
            n = self.p.num_sets)

        tag_array = reg_array(
            'tag_array',
            size = self.p.num_sets,
            #msb is tilelink error bit
            data_width = tag_ecc_code.width(self.p.tag_bits + 1) * self.p.num_ways,
            mask_width = self.p.num_ways)

        data_array = reg_array(
            'data_array',
            size = self.p.num_sets * (self.p.cache_block_size//self.row_bytes()),
            data_width = (data_ecc_code.width(self.p.inst_bits) *
                (self.row_bits()//self.p.inst_bits)) * self.p.num_ways,
            mask_width = self.p.num_ways)

        s1_flush = bits('s1_flush', init = 0)

        uncache_invalid_s1 = bits('uncache_invalid_s1')
        uncache_invalid_s2 = bits('uncache_invalid_s2')
        uncache_invalid_last = (
            uncache_invalid_s1
            if (self.p.mem_latency < 2) else uncache_invalid_s2)

        tag_error_invalid_s1 = bits('tag_error_invalid_s1')
        tag_error_invalid_s2 = bits('tag_error_invalid_s2')
        tag_error_invalid_last = (
            tag_error_invalid_s1
            if (self.p.mem_latency < 2) else tag_error_invalid_s2)

        data_error_invalid_s1 = bits('data_error_invalid_s1')
        data_error_invalid_s2 = bits('data_error_invalid_s2')
        data_error_invalid_last = (
            data_error_invalid_s1
            if (self.p.mem_latency < 2) else data_error_invalid_s2)

        ####
        #refill request pending info buffer
        pending_flags = vec(
            'pending_flags',
            gen = reg_r,
            n = self.p.num_flights)
        pending_reqs_addr = vec(
            'pending_reqs_addr',
            gen = lambda _: reg(_, w = self.p.max_addr_bits),
            n = self.p.num_flights)
        pending_reqs_way = vec(
            'pending_reqs_way',
            gen = lambda _: reg(_, w = self.p.num_ways),
            n = self.p.num_flights)
        pending_full = pending_flags.pack().r_and()
        pending_none_empty = pending_flags.pack().r_or()

        ####
        #flush all cache line
        req_cmd_flush = (
            self.io.fetch.req.fire() &
            (self.io.fetch.req.bits.cmd == IFU_CONSTS.FLUSH()))
        flush_flag = reg_r('flush_flag')
        with when(req_cmd_flush):
            flush_flag /= 1
        with when(flush_flag & ~pending_none_empty):
            flush_flag /= 0

        req_ready = (
            ~self.tl_out.d.fire() &
            ~uncache_invalid_last &
            ~tag_error_invalid_last &
            ~data_error_invalid_last)
        self.io.fetch.req.ready /= req_ready

        ####
        #pipeline valid and fetch address
        if (self.p.itim_size != 0):
            slave_req = ready_valid(
                'slave_req',
                gen = type(self.io.slave.req.bits),
                p = self.io.slave.req.bits.p).as_bits()
            slave_req.valid /= self.io.slave.req.valid
            slave_req.bits /= self.io.slave.req.bits
            self.io.slave.req.ready /= slave_req.ready
        slave_fire = slave_req.fire() if (self.p.itim_size != 0) else 0

        valid_s0 = self.io.fetch.req.fire() | slave_fire
        valid_s1 = reg_r(next = valid_s0) & ~s1_flush & ~self.tl_out.d.fire()
        valid_s2 = reg_r('valid_s2', next = valid_s1)
        valid_last = valid_s1 if (self.p.mem_latency < 2) else valid_s2

        is_slave_req_s0 = slave_fire
        is_slave_req_s1 = reg_r('is_slave_req_s1', next = is_slave_req_s0)
        is_slave_req_s2 = reg_r('is_slave_req_s2', next = is_slave_req_s1)
        is_slave_req_last = (
            is_slave_req_s1 if (self.p.mem_latency < 2) else is_slave_req_s2)

        is_slave_rd_s0 = (
            M_CONSTS.is_read(slave_req.bits.cmd) if (self.p.itim_size != 0) else 0)
        is_slave_rd_s1 = reg('is_slave_rd_s1', next = is_slave_rd_s0)
        is_slave_rd_s2 = reg('is_slave_rd_s2', next = is_slave_rd_s1)
        is_slave_rd_last = is_slave_rd_s1 if (self.p.mem_latency < 2) else is_slave_rd_s2

        is_slave_wr_s0 = (
            M_CONSTS.is_write(slave_req.bits.cmd) if (self.p.itim_size != 0) else 0)
        is_slave_wr_s1 = reg('is_slave_wr_s1', next = is_slave_wr_s0)
        is_slave_wr_s2 = reg('is_slave_wr_s2', next = is_slave_wr_s1)
        is_slave_wr_last = (
            is_slave_wr_s1 if (self.p.mem_latency < 2) else is_slave_wr_s2)

        is_itim_ecc_correct_s0 = bits('is_itim_ecc_correct_s0', init = 0)
        is_itim_ecc_correct_s1 = reg('is_itim_ecc_correct_s1', next = is_itim_ecc_correct_s0)
        is_itim_ecc_correct_s2 = reg('is_itim_ecc_correct_s2', next = is_itim_ecc_correct_s1)
        is_itim_ecc_correct_last = (
            is_itim_ecc_correct_s1 if (self.p.mem_latency < 2) else is_itim_ecc_correct_s2)

        addr_s0 = mux(
            is_slave_req_s0,
            slave_req.bits.addr if (self.p.itim_size != 0) else 0,
            self.io.fetch.req.bits.vaddr)
        addr_s1 = reg('addr_s1', w = self.p.max_addr_bits, next = addr_s0)
        addr_s2 = reg('addr_s2', w = self.p.max_addr_bits, next = addr_s1)
        addr_last = addr_s1 if (self.p.mem_latency < 2) else addr_s2

        req_error_s0 = mux( is_slave_req_s0, 0, self.io.fetch.req.bits.error)
        req_error_s1 = reg('req_error_s1', next = req_error_s0)
        req_error_s2 = reg('req_error_s2', next = req_error_s1)
        req_error_last = req_error_s1 if (self.p.mem_latency < 2) else req_error_s2

        addr_idx_s0 = addr_s0[self.p.idx_bits - 1 : 0]
        addr_idx_s1 = addr_s1[self.p.idx_bits - 1 : 0]
        addr_idx_s2 = addr_s2[self.p.idx_bits - 1 : 0]

        addr_line_s0 = addr_idx_s0 >> self.p.line_off_bits
        addr_line_s1 = addr_idx_s1 >> self.p.line_off_bits
        addr_line_s2 = addr_idx_s2 >> self.p.line_off_bits
        addr_line_last = addr_line_s1  if (self.p.mem_latency < 2) else addr_line_s2

        addr_tag_s1 = addr_s1[addr_s1.get_w() - 1 : self.p.idx_bits]

        addr_cacheable_s0 = bits(
            'addr_cacheable_s0',
            init = self.interface_out.manager.address_attr_check(
                addr_s0,
                lambda _: _.cacheable()))
        addr_cacheable_s1 = reg('addr_cacheable_s1', next = addr_cacheable_s0)
        addr_cacheable_s2 = reg('addr_cacheable_s2', next = addr_cacheable_s1)

        ####
        #tile link d response
        (d_first, d_last, d_done, refill_cnt) = self.interface_out.count(self.tl_out.d)
        d_req_addr = sel_bin(self.tl_out.d.bits.source, pending_reqs_addr)
        d_req_way = sel_bin(self.tl_out.d.bits.source, pending_reqs_way)
        d_req_addr_tag = d_req_addr[d_req_addr.get_w() - 1 : self.p.idx_bits]
        d_req_addr_idx = d_req_addr[self.p.idx_bits - 1 : 0]
        d_req_addr_line = d_req_addr_idx >> self.p.line_off_bits
        d_req_addr_data_base = (
            d_req_addr_line << log2_ceil(self.p.cache_block_size//self.row_bytes()))
        with when (self.tl_out.d.fire() & d_last):
            pending_flags(self.tl_out.d.bits.source, 0)

        ####
        #cache tag_array access control
        tag_array_ren = valid_s0
        tag_array_wen = self.tl_out.d.fire() & d_last
        tag_array_addr = mux(tag_array_wen, d_req_addr_line, addr_line_s0)
        tag_array_wmask = d_req_way
        tag_array_wdata = tag_ecc_code.encode(
            cat([self.tl_out.d.bits.error, d_req_addr_tag])).rep(self.p.num_ways)

        tag_array.io.en /= tag_array_ren | tag_array_wen
        tag_array.io.wmode /= tag_array_wen
        tag_array.io.addr /= tag_array_addr
        tag_array.io.wmask /= tag_array_wmask
        tag_array.io.wdata /= tag_array_wdata

        tag_array_rdata_grp = tag_array.io.rdata.grouped(
            tag_ecc_code.width(self.p.tag_bits + 1))
        tag_array_rdata_grp_decode = map(
            lambda _: tag_ecc_code.decode(_),
            tag_array_rdata_grp)

        tag_valid_s0 = cat([1, tag_valid_bits[tag_array_addr]])
        tag_valid_s1 = reg(
            w = self.p.num_ways + 1,
            next = tag_valid_s0) & ~flush_flag.rep(self.p.num_ways + 1)
        tag_valid_s2 = reg(
            'tag_valid_s2',
            w = self.p.num_ways + 1,
            next = tag_valid_s1) & ~flush_flag.rep(self.p.num_ways + 1)

        tag_match_itim_s1 = (
            0
            if (self.p.itim_size == 0) else (
                (addr_s1 >= self.p.itim_base) &
                (addr_s1 < (self.p.itim_base + self.p.itim_size))))

        tag_cmp_s1 = (
            tag_valid_s1 &
            cat([
                tag_match_itim_s1,
                cat_rvs(map(
                    lambda _: _[self.p.tag_bits - 1 : 0] == addr_tag_s1,
                    tag_array_rdata_grp))]))
        tag_cmp_s2 = reg('tag_cmp_s2', w = self.p.num_ways + 1, next = tag_cmp_s1)
        tag_cmp_last = tag_cmp_s1 if (self.p.mem_latency < 2) else tag_cmp_s2

        tag_tl_error_s1 = tag_valid_s1 & cat([
            0,
            cat_rvs(map(lambda _: _[self.p.tag_bits], tag_array_rdata_grp))])
        tag_tl_error_s2 = reg(
            'tag_tl_error_s2',
            w = self.p.num_ways + 1,
            next = tag_tl_error_s1)

        tag_error_s1 = (
            tag_valid_s1 &
            cat([
                0,
                cat_rvs(map(lambda _: _.error(), tag_array_rdata_grp_decode))]))
        tag_error_s2 = reg('tag_error_s2', w = self.p.num_ways + 1, next = tag_error_s1)

        tag_error_any_s1 = tag_error_s1.r_or()
        tag_error_any_s2 = tag_error_s2.r_or()

        tag_hit_any_s1 = tag_cmp_s1.r_or() & ~tag_error_any_s1
        tag_hit_any_s2 = tag_cmp_s2.r_or() & ~tag_error_any_s2

        tl_error_s1 = tag_tl_error_s1.r_or()
        tl_error_s2 = tag_tl_error_s2.r_or()
        tl_error_last = tl_error_s1 if (self.p.mem_latency < 2) else tl_error_s2

        miss_s1 = valid_s1 & ~tag_hit_any_s1
        miss_s2 = valid_s2 & ~tag_hit_any_s2
        miss_last = miss_s1 if (self.p.mem_latency < 2) else miss_s2

        tag_error_invalid_s1 /= valid_s1 & tag_error_any_s1
        tag_error_invalid_s2 /= valid_s2 & tag_error_any_s2

        ####
        #tag_valid_bits set or clear
        #dtim hit's data ecc error no need clean tag_bits
        with when(
            (self.tl_out.d.fire() & (d_first | d_last)) |
            uncache_invalid_last |
            tag_error_invalid_last |
            (data_error_invalid_last & ~tag_cmp_last[self.p.num_ways])):
            flush_mask = ~flush_flag.rep(self.p.num_ways)
            addr = mux(
                uncache_invalid_last | tag_error_invalid_last | data_error_invalid_last,
                addr_line_last,
                tag_array_addr)
            for i in range(self.p.num_sets):
                vb_d_last = tag_valid_bits[i] | d_req_way
                vb_d_first = tag_valid_bits[i] & ~d_req_way
                vb_d = mux(d_last, vb_d_last, vb_d_first)
                with when(addr == i):
                    #tag/data ecc error will invalid all way's valid bit
                    with when(tag_error_invalid_last | data_error_invalid_last):
                        tag_valid_bits[i] /= 0
                    with other():
                        tag_valid_bits[i] /= mux(uncache_invalid_last, 0, vb_d) & flush_mask
        with when(req_cmd_flush):
            tag_valid_bits /= 0

        ####
        #cache data_array control
        data_array_wen = self.tl_out.d.fire()
        data_array_addr = mux(
            self.tl_out.d.fire(),
            d_req_addr_data_base | refill_cnt,
            addr_s0 >> self.row_off_bits())
        data_array_wmask = d_req_way
        data_array_wdata = cat_rvs(
            map(
                lambda _: data_ecc_code.encode(_),
                self.tl_out.d.bits.data.grouped(self.p.inst_bits))).rep(self.p.num_ways)

        data_array.io.en /= valid_s0 | data_array_wen
        data_array.io.wmode /= data_array_wen
        data_array.io.addr /= data_array_addr
        data_array.io.wmask /= data_array_wmask
        data_array.io.wdata /= data_array_wdata

        #itim_data_array control
        if (self.p.itim_size != 0):
            vmacro('ITIM_SIZE', self.p.itim_size)
            itim_array = reg_array(
                'itim_array',
                size = self.p.itim_size//self.row_bytes(),
                data_width = data_ecc_code.width(
                    self.p.inst_bits) * (self.row_bits()//self.p.inst_bits),
                mask_width = 1
                )

            itim_array_wen = valid_s0 & is_slave_req_s0 & is_slave_wr_s0
            itim_array_addr = addr_s0 >> self.row_off_bits()
            itim_array_wdata = cat_rvs(
                map(
                    lambda _: data_ecc_code.encode(_),
                    slave_req.bits.data.grouped(self.p.inst_bits))).rep(self.p.num_ways)

            itim_array.io.en /= valid_s0
            itim_array.io.wmode /= itim_array_wen
            itim_array.io.addr /= itim_array_addr
            itim_array.io.wmask /= 1
            itim_array.io.wdata /= itim_array_wdata

        rdata_sel_s1 = sel_oh(
            tag_cmp_s1,
            data_array.io.rdata.grouped(
                data_ecc_code.width(self.p.inst_bits) *
                (self.row_bits()//self.p.inst_bits)) + [
                    itim_array.io.rdata if (self.p.itim_size != 0) else 0])
        rdata_sel_s2 = reg('rdata_sel_s2', w = rdata_sel_s1.get_w(), next = rdata_sel_s1)
        rdata_sel_last = rdata_sel_s1 if (self.p.mem_latency < 2) else rdata_sel_s2

        rdata_inst_sel_s1 = sel_bin(
            addr_s1[self.row_off_bits() - 1 : self.p.inst_off_bits],
            rdata_sel_s1.grouped(data_ecc_code.width(self.p.inst_bits)))
        rdata_inst_sel_s2 = reg(
            'rdata_inst_sel_s2',
            w = rdata_inst_sel_s1.get_w(),
            next = rdata_inst_sel_s1)
        rdata_inst_sel_last = (rdata_inst_sel_s1
            if (self.p.mem_latency < 2) else rdata_inst_sel_s2)

        data_decode = data_ecc_code.decode(rdata_inst_sel_s1)

        data_error_s1 = (
            tag_cmp_s1.r_or() &
            data_decode.error() &
            (~is_slave_req_s1 | is_slave_rd_s1))
        data_error_s2 = reg('data_error_s2', next = data_error_s1)
        data_error_last = data_error_s1 if (self.p.mem_latency < 2) else data_error_s2

        data_error_correctable_s1 = (
            tag_cmp_s1.r_or() &
            data_decode.correctable &
            (~is_slave_req_s1 | is_slave_rd_s1))
        data_error_correctable_s2 = reg(
            'data_error_correctable_s2',
            next = data_error_correctable_s1)
        data_error_correctable_last = (
            data_error_correctable_s1
            if (self.p.mem_latency < 2) else data_error_correctable_s2)

        data_error_invalid_s1 /= valid_s1 & data_error_s1
        data_error_invalid_s2 /= valid_s2 & data_error_s2

        hit_s1 = valid_s1 & tag_hit_any_s1 & ~data_error_s1
        hit_s2 = valid_s2 & tag_hit_any_s2 & ~data_error_s2
        hit_last = hit_s1 if (self.p.mem_latency < 2) else hit_s2

        ####
        #uncacheable fetch need invalid this cache line after hit access
        uncache_invalid_s1 /= hit_s1 & ~addr_cacheable_s1 & self.p.uc_invalid_en
        uncache_invalid_s2 /= hit_s2 & ~addr_cacheable_s2 & self.p.uc_invalid_en

        s1_flush /= 0 \
            if (self.p.mem_latency < 2) else (
                (self.io.fetch.s1_kill & ~is_slave_req_s1) |
                tag_error_invalid_last |
                data_error_invalid_last |
                miss_last)

        ####
        #tile link a channel cache refill request
        a_source = pri_lsb_enc(~pending_flags.pack())
        a_refill_way = bin2oh(
            lfsr16(increment = self.tl_out.a.fire())
            [log2_up(self.p.num_ways)-1:0]) if (self.p.num_ways > 1) else 1
        with when (self.tl_out.a.fire()):
            pending_flags(a_source, 1)
            pending_reqs_addr(a_source, addr_s2)
            pending_reqs_way(a_source, a_refill_way)
        a_address = (addr_s2 >> self.p.line_off_bits) << self.p.line_off_bits
        a_size = log2_ceil(self.p.cache_block_size)
        a_get = self.interface_out.get(a_source, a_address, a_size)[1]

        self.tl_out.a.valid /= 0
        with when(miss_s2 & ~pending_full & ~flush_flag):
            self.tl_out.a.valid /= 1
        self.tl_out.a.bits /= a_get

        ####
        #blocking d.ready if following condition happen
        self.tl_out.d.ready /= \
            ~uncache_invalid_last & \
            ~tag_error_invalid_last & \
            ~data_error_invalid_last

        ####
        #response to ifu when cache hit
        self.io.fetch.resp.valid /= hit_last & ~is_slave_req_last
        self.io.fetch.resp.bits.inst /= rdata_inst_sel_last[self.p.inst_bits - 1 : 0]
        self.io.fetch.resp.bits.pc /= addr_last
        self.io.fetch.resp.bits.xcpt /= tl_error_last | req_error_last

        self.io.fetch.valid_s1 /= valid_s1

        if (self.p.itim_size != 0):
            slave_req.ready /= req_ready
            with when(slave_req.valid):
                #slave rw access has higher priority than fetch
                self.io.fetch.req.ready /= 0

            #response to ifu_slave
            self.io.slave.resp.valid /= is_slave_req_last & ~is_itim_ecc_correct_last
            self.io.slave.resp.bits.replay /= is_slave_req_last & ~hit_last
            self.io.slave.resp.bits.data /= cat_rvs(map(
                lambda _: _[self.p.inst_bits - 1 : 0],
                rdata_sel_last.grouped(data_ecc_code.width(self.p.inst_bits))))

            ####
            #itim memory ecc correction
            itim_ecc_error_1b_s1 = tag_cmp_s1[self.p.num_ways] & data_error_correctable_s1
            itim_ecc_error_1b_s2 = tag_cmp_s2[self.p.num_ways] & data_error_correctable_s2
            itim_ecc_error_1b_last = (
                itim_ecc_error_1b_s1 if (self.p.mem_latency < 2) else itim_ecc_error_1b_s2)

            ecc_correct_req = ready_valid(
                'ecc_correct_req',
                gen = type(self.io.slave.req.bits),
                p = self.io.slave.req.bits.p).as_bits()
            ecc_correct_buf_valid = reg_r('ecc_correct_buf_valid')
            ecc_correct_buf = self.io.slave.req.bits.clone('correct_buf').as_reg()
            with when(valid_last & itim_ecc_error_1b_last):
                ecc_correct_buf_valid /= 1
                ecc_correct_buf.addr /= addr_last
                ecc_correct_buf.cmd /= M_CONSTS.M_XWR()
                ecc_correct_buf.typ /= log2_ceil(self.row_bytes())
                ecc_correct_buf.data /= cat_rvs(map(
                    lambda _: data_ecc_code.decode(_).post_correct,
                    rdata_sel_last.grouped(data_ecc_code.width(self.p.inst_bits))))
                ecc_correct_buf.mask /= bits(init = 1).rep(self.row_bytes())
            with elsewhen(ecc_correct_req.fire()):
                ecc_correct_buf_valid /= 0

            ecc_correct_req.valid /= ecc_correct_buf_valid
            ecc_correct_req.bits /= ecc_correct_buf
            ecc_correct_req.ready /= slave_req.ready
            with when(ecc_correct_req.valid):
                self.io.slave.req.ready /= 0
                slave_req.valid /= 1
                slave_req.bits /= ecc_correct_req.bits
            is_itim_ecc_correct_s0 /= ecc_correct_req.fire()

        ####
        #hpm events
        a_sop_eop = self.tl_out.sop_eop_a()
        self.io.fetch.events.refill /= self.tl_out.a.fire() & a_sop_eop.eop

    def row_bits(self):
        return self.tl_out.a.bits.p.data_bits

    def row_bytes(self):
        return self.row_bits()//8

    def row_off_bits(self):
        return log2_up(self.row_bytes())


"""
Definition for singly-linked list.
class ListNode:
    def __init__(self, x):
        self.val = x
        self.next = None
"""

class Solution:
    """
    @param: head: a ListNode
    @param: k: An integer
    @return: a ListNode
    """
    def reverseKGroup(self, head, k):
        if not head:
            return None
        if k == 0:
            return head
        tmp = head
        count = 1
        while tmp.next:
            count += 1
            tmp = tmp.next
        tmp = dummy = ListNode(0)
        dummy.next = head
        num = k
        while num <= count:
            num += k
            pre = None
            cur = dummy
            curr = head
            for i in range(k -1):
                head = head.next
            next = head.next
            head.next = None
            while curr:
                node = curr
                curr = curr.next
                node.next = pre
                pre = node
            cur.next = pre
            for i in range(k -1):
                head = head.next
            head.next = next
            dummy = head
            head = head.next
        return tmp.next


from coinor.grumpy.polyhedron2D import Polyhedron2D, Figure

from matplotlib import rcParams

from matplotlib.legend_handler import HandlerPatch
import matplotlib.patches as mpatches
import matplotlib.pyplot as plt

def make_legend_arrow(legend, orig_handle,
                      xdescent, ydescent,
                      width, height, fontsize):
    p = mpatches.FancyArrow(0, 0.5*height, width, 0,
                            length_includes_head=True,
                            head_width=0 )
    return p

rcParams["mathtext.fontset"] = 'cm'

A = [[ 1, -2],
     [-0, -1],
     [-2, -1],
     [-1, -0],
     [-1, -1],
     [1, -3],
     [0,  1],
     [1, 0]]

b = [4,
     0,
     -3,
     0,
     -2,
     3,
     4,
     8]

c = [1, -0.6]
sense = ['Max', '<=']
integerIndices = [0, 1]

#This is for the separation code
#x0 = [1, 1]
x_sep = [0, 1]

points = [[1, 1],
                 [8, 2],
                 [3, 0],
                 [2, 0]
]

locations = [[0.5, 0.7],
             [8.1, 2.1],
             [2.8, -0.35],
             [1.6, -0.4]
]

d = [[0.2, -1.4],
     [-0.5, -1],
     [-1, -1]
     ]

P = Polyhedron2D(A = A, b = b)

iter = 3

f = Figure()

for iter in [1,2,3]:

    rays = [[0,0]]

    for i, e in enumerate(points):
        if (i <= iter):
            f.add_point(e, radius = 0.05, color = 'mediumblue')
            f.add_text(locations[i], f'$x^{i}$')
            if (i != 0):
                rays.append([e[0] - points[0][0],
                             e[1] - points[0][1]])

    C = f.ax.arrow(points[0][0], points[0][1], c[0], c[1],
                   head_width = 0.15, head_length = 0.15,
                   overhang = 0.3, color = 'navy', alpha = 0.7, linewidth = 2)

    D = f.ax.arrow(points[0][0], points[0][1],
                   d[iter-1][0], d[iter-1][1],
                   head_width = 0.15, head_length = 0.15,
                   overhang = 0.3, color = 'indianred',
                   alpha = 0.7, linewidth = 2)

    a = f.ax.arrow(points[0][0], points[0][1],
                   1.2*rays[1][0], 1.2*rays[1][1],
                   head_width = 0.15, head_length = 0.15,
                   overhang = 0.3, color = 'coral',
                   alpha = 0.7, linewidth = 2)
    #linestyle = (0, (1,2))

    if (iter == 2):
        f.ax.arrow(points[0][0], points[0][1],
                   1.2*rays[2][0], 1.2*rays[2][1],
                   head_width = 0.15, head_length = 0.15,
                   overhang = 0.3, color = 'coral',
                   alpha = 0.7, linewidth = 2)

    if (iter == 3):
        f.ax.arrow(points[0][0], points[0][1],
                   1.3*rays[3][0], 1.3*rays[3][1],
                   head_width = 0.15, head_length = 0.15,
                   overhang = 0.3, color = 'coral',
                   alpha = 0.7, linewidth = 2)

    #f.ax.annotate('', xytext = (points[0][0], points[0][1]),
    #              xy = (points[0][0]+1.4*rays[2][0],
    #                    points[0][1]+1.4*rays[2][1]),
    #              arrowprops = {'arrowstyle':'->', 'linestyle':'--'},
    #               head_width = 0.2, head_length = 0.2,
    #               color = 'red', linestyle = (5, (1,10))
    #)

    p = f.add_polyhedron(P, show_int_points = True,
                         color = 'steelblue', linewidth = 2)
    if (iter > 1):
        f.ax.fill([(points[i][0] + 0.4*rays[i][0]) for i in [0,1,iter]],
                  [(points[i][1] + 0.4*rays[i][1]) for i in [0,1,iter]],
                  color = 'peachpuff')

    f.set_xlim(P.xlim)
    f.set_ylim(P.ylim)

    #red_patch = mpatches.Patch(color='red', label='The red data', lw = 0.2,
    #                           linestyle = '-')
    #plt.legend(handles=[red_patch])

    if (iter == 1):
        plt.legend([p, a, C, D], ['$\mathrm{conv}(\mathcal{S}$)',
                                  '$\mathcal{C}_1(x^0)$',
                                  '$c = d^0$', '$d^1$'],
                   handler_map={mpatches.FancyArrow : HandlerPatch(patch_func=make_legend_arrow)})
    else:
        plt.legend([p, a, C, D], ['$\mathrm{conv}(\mathcal{S}$)',
                                  '$\mathcal{C}_'+f'{iter}(x^0)$',
                                  '$c$', f'$d^{iter}$'],
                   handler_map={mpatches.FancyArrow : HandlerPatch(patch_func=make_legend_arrow)})

    plt.savefig(f'inv-iter{iter}-new.png')
    f.show()


"""Fully functional. Is capable of completely locking the parent window via wm_attributes() method,
since the main menu inherits from Tk. Second menu is defined explicitly inside the appropriate button
method. However, OOP-ing this would be relatively simple, as the Create_Toplevel() method creates a
Toplevel object anyway."""
import tkinter as tk
from tkinter import ttk

class SampleApp(tk.Tk):
    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)
        self.minsize(300, 100)
        self.button = ttk.Button(self, text="Call toplevel!", command=self.create_toplevel)
        self.button.pack(side="top")

    def create_toplevel(self):
        # THE CLUE
        self.wm_attributes("-disabled", True)
        self.focus_set()

        # Creating the toplevel dialog
        _ = Top(self)

class Top(tk.Toplevel):
    def __init__(self, master):
        super().__init__(master)
        self.master = master

        self.focus_set()
        self.minsize(300, 100)

        # Tell the window manager, this is the child widget.
        # Interesting, if you want to let the child window
        # flash if user clicks onto parent
        self.transient(self.master)

        # This is watching the window manager close button
        # and uses the same callback function as the other buttons
        # (you can use which ever you want, BUT REMEMBER TO ENABLE
        # THE PARENT WINDOW AGAIN)
        self.protocol("WM_DELETE_WINDOW", self.close)

        self.label = ttk.Label(self, text='Do you want to enable my parent window '
                                                               'again?')
        self.label.pack(side='top')

        self.toplevel_dialog_yes_button = ttk.Button(self, text='Yes',command=self.close)
        self.toplevel_dialog_yes_button.pack(side='left', fill='x', expand=True)

        self.toplevel_dialog_no_button = ttk.Button(self, text='No')
        self.toplevel_dialog_no_button.pack(side='right', fill='x', expand=True)

    def close(self):
        # IMPORTANT!
        self.master.wm_attributes("-disabled", False)  # IMPORTANT!

        self.destroy()

        # Possibly not needed, used to focus parent window again
        self.master.focus_set()
        self.master.grab_set()

if __name__ == "__main__":
    app = SampleApp()
    app.mainloop()

Tkinter GUI examples/gui structure samples/GUI structure FUNCTIONAL.py


from collections import defaultdict
import sys
import time

class GDE(object):

    """
    implements a very simple version of the hitting set algorithm behind the GDE diagnosis algorithm
    (de Kleer and Williams 1987: Diagnosing Multiple Faults). Note that there is NO predication algorithm
    /ATMS or whatsoever here.
    This code is based on the pseudo-code in "A Generalized Minimal Hitting-Set Algorithm to Handle
    Diagnosis With Behavioral Modes" (Mattias Nyberg, 2011) - Algorithm 1.
    """

    def __init__(self, oracle, handle=None, options={}):
        self.oracle = oracle
        self.options = options
        self.delta = handle
        self.scs = None
        self.min_card = options.get('min_card',1)
        self.max_card = options.get('max_card',sys.maxint)
        self.max_time = options.get('max_time',None)

    def start(self):
        max_time = self.max_time

        if max_time:
            end_time = time.time() + max_time
        else:
            end_time = None

        self.scs = list(self.oracle.get_conflict_sets())
        if not self.delta:
            self.delta = defaultdict(list)
            for c in self.scs[0]:
                self.delta[1] += [(frozenset([c]),0)]

        csi = 0
        for cs in self.scs[1:]:
            csi += 1
            self.gde(cs, csi)
            if (end_time and time.time() > end_time) or len(self.delta) == 0:
                break

        result = set()
        for lst in self.delta.values():
            for sol, _ in lst:
                result.add(frozenset(sol))
        return result

    def gde(self, c, idx):

        for card in self.delta.keys():
            if card > self.max_card:
                continue

            delta_card = self.delta[card]
#            while self.delta[card]:
            i = 0
            while i < len(delta_card):
#                if self.delta[card][0][1] >= idx:
#                    break

#                delta_i, _ = self.delta[card].pop(0) # maybe use queues here and their popleft() method
                delta_i = delta_card[i][0]

                if len(delta_i & c) == 0:
                    del delta_card[i]
                    if len(delta_i) < self.max_card:
                        for c_i in c:
                            delta_new = delta_i | frozenset([c_i])
    #                        if len(delta_new) <= self.max_card:
                            found_subset = False
                            for k in self.delta:
                                if k < len(delta_new):
                                    for delta_k, _ in self.delta[k]:
                                        if delta_k <= delta_new:
                                            found_subset = True
                                            break

                            if not found_subset:
                                self.delta[len(delta_new)].append((delta_new, idx))

                    #end for c_i
                else:
#                    self.delta[len(delta_i)].append((delta_i, idx))
                    delta_card[i] = (delta_i,idx)
                    i = i + 1


#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
References:
    http://deeplearning.net/software/theano/tutorial/using_gpu.html#testing-theano-with-gpu

python `python -c "import os, theano; print os.path.dirname(theano.__file__)"`/misc/check_blas.py
"""
import logging
import theano

# from theano import function, config, shared
import theano.tensor as T
import numpy
import time
import utool as ut

(print, rrr, profile) = ut.inject2(__name__)
logger = logging.getLogger()

def test_theano():
    vlen = 10 * 30 * 768  # 10 x #cores x # threads per core
    iters = 1000

    rng = numpy.random.RandomState(22)
    x = theano.shared(numpy.asarray(rng.rand(vlen), theano.config.floatX))
    f = theano.function([], T.exp(x))
    logger.info(f.maker.fgraph.toposort())
    t0 = time.time()
    for i in range(iters):
        r = f()
    t1 = time.time()
    logger.info('Looping %d times took' % iters, t1 - t0, 'seconds')
    logger.info('Result is', r)

    if numpy.any([isinstance(x_.op, T.Elemwise) for x_ in f.maker.fgraph.toposort()]):
        logger.info('Used the cpu')
    else:
        logger.info('Used the gpu')

if __name__ == '__main__':
    """
    python $CODE_DIR/wbia_cnn/test_theano.py
    """
    test_theano()
    # theano.test()


# -*- coding:utf-8 -*-
import os
import configparser

cp = configparser.ConfigParser()
cp.read(os.path.dirname(os.path.abspath(__file__))+'/config.ini', encoding='utf-8')

# WX_BOT相关
WX_ROBOT_ID = cp.get('WX_BOT', 'wx_robot_id')
WX_ROBOT_WORK_GROUP = str(cp.get('WX_BOT', 'wx_robot_work_group')).split(',')
WX_ROBOT_KW_REPLY = cp.get('WX_BOT', 'wx_robot_kw_reply')
WX_ROBOT_AT_KW_REPLY = cp.get('WX_BOT', 'wx_robot_at_kw_reply')
MOVIE_SEARCH_URL = cp.get('WX_BOT', 'movie_search_url')
MUSIC_SEARCH_URL = cp.get('WX_BOT', 'music_search_url')
MUSIC_COVER_URL = cp.get('WX_BOT', 'music_cover_url')
MUSIC_DETAIL_URL = cp.get('WX_BOT', 'music_detail_url')
WELCOME_IMG_URL = cp.get('WX_BOT', 'welcome_img_url')
DY_JX_URL = cp.get('WX_BOT', 'dy_jx_url')
MUSIC_VKEY_URL = 'https://u.y.qq.com/cgi-bin/musicu.fcg?-=getplaysongvkey05137740976859173&' \
                 'g_tk=5381&loginUin=0&hostUin=0&format=json&inCharset=utf8&outCharset=utf-8&' \
                 'notice=0&platform=yqq.json&needNewCode=0&data=%7B%22req%22%3A%7B%22module' \
                 '%22%3A%22CDN.SrfCdnDispatchServer%22%2C%22method%22%3A%22GetCdnDispatch' \
                 '%22%2C%22param%22%3A%7B%22guid%22%3A%22953482270%22%2C%22calltype%22%3A0%2C%22' \
                 'userip%22%3A%22%22%7D%7D%2C%22req_0%22%3A%7B%22module%22%3A%22vkey.GetVkeyServer' \
                 '%22%2C%22method%22%3A%22CgiGetVkey%22%2C%22param%22%3A%7B%22guid%22%3A%22953482270%22%2C%22' \
                 'songmid%22%3A%5B%22@songmid@%22%5D%2C%22songtype%22%3A%5B0%5D%2C%22uin%22%3A%220%22%2C%22' \
                 'loginflag%22%3A1%2C%22platform%22%3A%2220%22%7D%7D%2C%22comm%22%3A%7B%22uin%22%3A0%2C%22' \
                 'format%22%3A%22json%22%2C%22ct%22%3A24%2C%22cv%22%3A0%7D%7D'
# 新浪短地址服务
SINA_URL = str(cp.get('SHORT_URL', 'sina_url'))
SINA_KEY = str(cp.get('SHORT_URL', 'sina_appkey'))
# 天气预报接口url
WEATHER_URL = str(cp.get('WEATHER', 'weather_url'))
# 百度机器人
BOT_URL = str(cp.get('BD_BOT', 'bot_url'))
BOT_OAUTH = str(cp.get('BD_BOT', 'oauth_url'))
BOT_API_KEY = str(cp.get('BD_BOT', 'apikey'))
BOT_API_SECRET = str(cp.get('BD_BOT', 'apisecret'))
BOT_ID = str(cp.get('BD_BOT', 'service_id'))
# 关键字功能
FUNC_MAP, AT_FUNC_MAP = dict(), dict()
FUNC_KW_LIST, AT_FUNC_KW_LIST = [], []
# 配置聊天关键字功能
for f in str(WX_ROBOT_KW_REPLY).split(';'):
    kvs = str(f).split(':')
    k = kvs[0]
    for kk in k.split(','):
        if kk:
            FUNC_KW_LIST.append(kk)
            FUNC_MAP[kk] = kvs[1]
# 配置at(@)聊天关键字功能
for ff in str(WX_ROBOT_AT_KW_REPLY).split(';'):
    kvs = str(ff).split(':')
    k = kvs[0]
    for kk in k.split(','):
        if kk:
            AT_FUNC_KW_LIST.append(kk)
            AT_FUNC_MAP[kk] = kvs[1]
# func type
FUNC_TYPE_AT = 'at'
FUNC_TYPE_NL = 'normal'


from rest_framework import serializers
from .models import brandList, order, orderDetail, ratevote, scentNote, perfume, rate, cartDetail

class brandSerializer(serializers.ModelSerializer):
    class Meta:
        model = brandList
        fields = (
            "id",
            "name",
            "place",
            "route",
            "image",
        )

class scentNoteSerializer(serializers.ModelSerializer):
    class Meta:
        model = scentNote
        fields = (
            "id",
            "name",
            "description",
            "route",
            "image",
        )

class perfumeSerializer(serializers.ModelSerializer):
    scentnote = serializers.SlugRelatedField(slug_field='name', read_only=True)
    is_rated = serializers.SerializerMethodField()
    point = serializers.SerializerMethodField()
    longevity = serializers.SerializerMethodField()
    sillage = serializers.SerializerMethodField()

    def get_point(self, obj):
        try:
            return obj.point
        except:
            return None

    def get_longevity(self, obj):
        try:
            return obj.longevity
        except:
            return None

    def get_sillage(self, obj):
        try:
            return obj.sillage
        except:
            return None

    def get_is_rated(self, obj):
        try:
            return obj.isRated
        except:
            return None

    class Meta:
        model = perfume
        fields = (
            "id",
            "name",
            "sname",
            "description",
            "brand",
            "topnote",
            "midnote",
            "basenote",
            "scentnote",
            "yearofreleasing",
            'price',
            'sale',
            "point",
            "longevity",
            "sillage",
            "sex",
            'is_rated',
            "image",
        )

class rateSerializer(serializers.ModelSerializer):
    perfume_id = serializers.PrimaryKeyRelatedField(
        source='perfume', queryset=perfume.objects.all())
    perfume = serializers.StringRelatedField(read_only=True)
    user = serializers.StringRelatedField(
        default=serializers.CurrentUserDefault(), read_only=True)
    is_up_voted = serializers.SerializerMethodField()
    is_down_voted = serializers.SerializerMethodField()
    vote_id = serializers.SerializerMethodField()
    vote = serializers.SerializerMethodField()

    def get_vote(self, obj):
        try:
            return obj.vote
        except:
            return None

    def get_is_up_voted(self, obj):
        try:
            return obj.isUpVoted
        except:
            return None

    def get_is_down_voted(self, obj):
        try:
            return obj.isDownVoted
        except:
            return None

    def get_vote_id(self, obj):
        try:
            return obj.voteID
        except:
            return None

    class Meta:
        model = rate
        fields = ('perfume_id', 'perfume', 'user', 'perfumepoint', 'longevity',
                  'sillage', 'content', 'vote', 'is_up_voted', 'is_down_voted',
                  'id', 'vote_id')

class rateVoteSerializer(serializers.ModelSerializer):
    user = serializers.StringRelatedField(
        default=serializers.CurrentUserDefault(), read_only=True)

    class Meta:
        model = ratevote
        fields = (
            'rate',
            'user',
            'point',
        )

class cartDetailSerializer(serializers.ModelSerializer):
    user = serializers.StringRelatedField(
        default=serializers.CurrentUserDefault(), read_only=True)
    perfume_data = perfumeSerializer(source='perfume', read_only=True)

    def create(self, validated_data):
        user = validated_data.get("user", None)
        perfume = validated_data.get("perfume", None)
        cartItem = cartDetail.objects.filter(user=user,
                                             perfume=perfume).first()
        if cartItem is not None:
            cartItem.amount = cartItem.amount + 1
            cartItem.save()
            return cartItem
        else:
            return cartDetail.objects.create(**validated_data)

    class Meta:
        model = cartDetail
        fields = ('id', 'user', 'perfume', 'amount', 'perfume_data')

class orderDetailSerializer(serializers.ModelSerializer):
    perfume_data = perfumeSerializer(source='perfume', read_only=True)

    def create(self, validated_data):
        perfume = validated_data.get('perfume', None)
        amount = validated_data.get('amount', None)
        validated_data.update({"price": perfume.price * amount})
        return orderDetail.objects.create(**validated_data)

    class Meta:
        model = orderDetail
        fields = ('order', 'perfume', 'amount', 'price', 'perfume_data')
        read_only_fields = ('price', 'perfume_data')

class orderSerializer(serializers.ModelSerializer):
    user = serializers.StringRelatedField(
        default=serializers.CurrentUserDefault(), read_only=True)
    details = orderDetailSerializer(many=True, read_only=True)
    totalPrice = serializers.SerializerMethodField()

    def get_totalPrice(self, obj):
        try:
            return obj.totalPrice
        except:
            return None

    class Meta:
        model = order
        fields = ('id', 'user', 'status', 'createdDate', 'totalPrice',
                  'details')
        read_only_fields = ('id', 'createdDate', 'status', 'totalPrice')


from datetime import datetime

import ihm.console as ihm

def saisie_date(message, date_seuil, duree_limite=1):
    """
    Methode qui permet de saisir la date du vol

    :param message:
    :param date_seuil:
    :param duree_limite:
    :return: la date saisie
    """

    date_saisie = None
    dans1an = date_seuil.replace(year=date_seuil.year + duree_limite)
    while True:
        try:
            date_saisie = ihm.demander(
                "Saisissez la {} (AAAA-MM-JJ) :".format(message))
            date_saisie = datetime.strptime(date_saisie, '%Y-%m-%d')
            if date_saisie <= date_seuil or date_saisie > dans1an:
                raise ValueError
        except ValueError:
            ihm.afficher("Ceci n'est pas une date valide.")
            pass
        else:
            break
    ihm.afficher("Vous avez choisi le {:%d/%m/%Y}".format(date_saisie))
    return date_saisie

def saisie_aeroport(message, aeroports):
    """
    Methode qui permet de saisir un aeroport

    :param message:
    :param aeroports:
    :return:
    """

    aero = None
    while aero is None:
        code = ihm.demander(
            "Saisissez l'{} (code IATA ou ICAO ou ville) :".format(message))
        results = [x for x in aeroports
                   if x.id_code_iata == code or x.code_icao == code or
                   x.municipalite.lower().startswith(code)]
        if len(results) == 0:
            ihm.afficher("Désolé, nous n'avons pas trouvé votre aéroport !")
        elif len(results) > 1:
            aero = ihm.choisir_paginer(results, "Précisez votre choix :")
        else:
            aero = results[0]
    ihm.afficher("Vous avez choisi : {}".format(aero))
    return aero

def saisie_compagnie(compagnies):
    """
    Methode qui permet de choisir une compagnie par ses différents codes

    :param compagnies: liste des compagnies
    :return: la compagnie choisie
    """

    compagnie = None
    code = ihm.demander(
        "Tapez le code IATA (2 caractères) ou ICAO (3 caractères) :")
    results = [x for x in compagnies
               if x.id_code_iata == code or x.code_icao == code]
    if len(results) == 0:
        ihm.afficher("Désolé, nous n'avons pas trouvé votre compagnie !")
    else:
        compagnie = results[0]
    if compagnie is not None:
        ihm.afficher("Vous avez choisi la compagnie {}".format(compagnie))
    return compagnie


from os import listdir
from os.path import isfile, join
import comare
import re
import transliterate

files= [f for f in listdir("izbs") if isfile(join("izbs", f))]

result = ""
scscs = 0
for f in files:
    scscs += 1
    print(f)
    try:
        my_file = open("izbs/"+f, "r", encoding="utf-8")
        lines = my_file.readlines()
        j = 0
        for st in lines:
            if re.search("[а-яА-я]", st):
                try:
                    result = transliterate.translit(st, reversed=True)
                except:
                    x = 1
                lines[j] = result
            j+=1
        my_file.close()
        my_file = open("izbs/"+f, "w")
        for line in lines:
            my_file.write(line)
    except:
        print("Hitlar file")

# my_file = open("izbs/2999126_OK_91.obj", "r", encoding="utf-8")
# j = 0
# lines = my_file.readlines()
# # print(transliterate.translit( lines[19393], reversed=True))
# for st in lines:
#     if re.search("[а-яА-я]", st):
#         print('true')
#     result=st
#     try:
#         result = transliterate.translit(st, reversed=True)
#     except:
#         x = 1
#     lines[j] = result
#     j+=1
# my_file.close()
# my_file = open("izbs/2999126_OK_91.obj", "w")
# for line in lines:
#     my_file.write(line)
# my_file.close()

# j=0
# lines = ["жопа", "xyi", "сися"]
# for st in lines:
#     len_st = len(st)
#     if re.match("""^[а-яА-ЯёЁ][а-яё0-9 !?:;"'.,]+$""", st):
#         print(st)
#         result=""
#         for i in range(0,len_st):
#             if st[i] in alphabet:
#                 simb = dic[st[i]]
#             else:
#                 simb = st[i]
#             result = result + simb
#         lines[j] = result
#     j+=1
# print(lines)


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

"""
给定一棵二叉搜索树和其中的一个节点 node ，找到该节点在树中的中序后继。

如果节点没有中序后继，请返回 null 。

一个结点 node 的中序后继是键值比 node.val大所有的结点中键值最小的那个。

你可以直接访问结点，但无法直接访问树。每个节点都会有其父节点的引用。节点定义如下：

class Node {
    public int val;
    public Node left;
    public Node right;
    public Node parent;
}

进阶：

你能否在不访问任何结点的值的情况下解决问题?

示例 1:

输入: tree = [2,1,3], node = 1
输出: 2
解析: 1 的中序后继结点是 2 。注意节点和返回值都是 Node 类型的。
示例 2:

输入: tree = [5,3,6,2,4,null,null,1], node = 6
输出: null
解析: 该结点没有中序后继，因此返回 null 。
示例 3:

输入: tree = [15,6,18,3,7,17,20,2,4,null,13,null,null,null,null,null,null,null,null,9], node = 15
输出: 17
示例 4:

输入: tree = [15,6,18,3,7,17,20,2,4,null,13,null,null,null,null,null,null,null,null,9], node = 13
输出: 15

提示：

-10^5 <= Node.val <= 10^5
1 <= Number of Nodes <= 10^4
树中各结点的值均保证唯一。

来源：力扣（LeetCode）
链接：https://leetcode-cn.com/problems/inorder-successor-in-bst-ii
著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。
"""

# Definition for a Node.
class Node:
    def __init__(self, val):
        self.val = val
        self.left = None
        self.right = None
        self.parent = None

class Solution:
    def __init__(self):
        self.res = None
        self.mark = False

    def inorderSuccessor(self, node: 'Node') -> 'Node':
        root = self.dfs(node)
        self.dfs1(root, node)
        return self.res

    def dfs(self, node):
        if not node.parent:
            return node

        return self.dfs(node.parent)

    def dfs1(self, root, node):
        if not root:
            return
        self.dfs1(root.left, node)
        if self.mark:
            self.res = root
            self.mark = False
            return

        if root == node:
            self.mark = True
        self.dfs1(root.right, node)

算法分析和归类/树/二叉搜索树中的中序后继 II.py

二叉搜索树中的中序后继 II.py


"""
Interact with Premiere Pro using the Pymiere library.
"""
import time
import pymiere
from pymiere import wrappers

# Check for an open project
project_opened, sequence_active = wrappers.check_active_sequence(crash=False)
if not project_opened:
    raise ValueError("please open a project")

project = pymiere.objects.app.project

# Open Sequences in Premiere Pro if none are active
if not sequence_active:
    sequences = wrappers.list_sequences()
    for seq in sequences:
        project.openSequence(sequenceID=seq.sequenceID)
    # Set the first Sequence in the list as the active Sequence
    project.activeSequence = sequences[0]

# List all videos clips in the active Sequence
clips = wrappers.list_clips(project.activeSequence)

# Convert timebase in ticks per second to Frame Per Second (FPS)
fps = 1/(float(project.activeSequence.timebase)/wrappers.TICKS_PER_SECOND)
print("Sequence as a framerate of {} fps".format(fps))

# Select the first video clip in the Timeline
clips[0].setSelected(True, True)

# The following code will not work in Premiere Pro 2017 (clips were not editable at the time)
# Periodically advance the first video clip through the Timeline
start_frame = 0
end_frame = 100
for i in range(30):
    increment = i * 5
    wrappers.edit_clip(clips[0], start_frame + increment, end_frame + increment, start_frame, end_frame, fps=fps)
    time.sleep(0.1)


#!/usr/bin/python3 -B

from ktreap import *

MAX = 20
L = np.arange(MAX); random.shuffle(L)
R = np.arange(MAX)
data = list(np.stack([L, R]).T)

render(3, data)

data.pop() # removes highest prio element.
render(3, data)

plt.show()


import datetime
from flask import Flask
import sys
from flask_restful import Api, Resource, reqparse, inputs, marshal_with, fields
from flask_sqlalchemy import SQLAlchemy

parser = reqparse.RequestParser()
app = Flask(__name__)
api = Api(app)
db = SQLAlchemy(app)
app.config['SQLALCHEMY_DATABASE_URL'] = 'sqlite://events.db'

class Events(db.Model):
    __tablename__ = 'events'
    id = db.Column(db.Integer, primary_key=True)
    event = db.Column(db.String(80), nullable=False)
    date = db.Column(db.Date, nullable=False)

db.create_all()

parser.add_argument(
    'event',
    type=str,
    help='The event name is required!',
    required=True
)

parser.add_argument(
    'date',
    type=inputs.date,
    help='The event date with the correct format is required! The correct format is YYYY-MM-DD!',
    required=True
)

resource_fields = {
    'id': fields.Integer,
    'event': fields.String,
    'date': fields.String,
    'message': fields.String
}

class TodayEventResource(Resource):
    @marshal_with(resource_fields)
    def get(self):
        return Events.query.filter(Events.date == datetime.date.today()).all()

class EventResource(Resource):
    @marshal_with(resource_fields)
    def get(self):
        return Events.query.all()

    @marshal_with(resource_fields)
    def post(self):
        args = parser.parse_args()
        event = Events(event=args.event, date=args.date)
        db.session.add(event)
        db.session.commit()
        return {'message': 'The event has been added!', 'event': args.event, 'date': args.date.strftime('%Y-%m-%d')}

api.add_resource(EventResource, '/event')
api.add_resource(TodayEventResource, '/event/today')

if __name__ == '__main__':
    if len(sys.argv) > 1:
        arg_host, arg_port = sys.argv[1].split(':')
        app.run(host=arg_host, port=arg_port, debug=True)
    else:
        app.run(debug=True)

Medium-Level/Web Calendar/Stage 3 Relax/calendar_app.py


import datetime
import queue

img = queue.Queue(0)
img = queue.Queue(0)

class FPS:
    def __init__(self):
        # store the start time, end time, and total number of frames
        # that were examined between the start and end intervals
        self._start = None
        self._end = None
        self._numFrames = 0

    def start(self):
        # start the timer
        self._start = datetime.datetime.now()
        return self

    def stop(self):
        # stop the timer
        self._end = datetime.datetime.now()

    def update(self):
        # increment the total number of frames examined during the
        # start and end intervals
        self._numFrames += 1

    def elapsed(self):
        # return the total number of seconds between the start and
        # end interval
        return (self._end - self._start).total_seconds()

    def fps(self):
        # compute the (approximate) frames per second
        return self._numFrames / self.elapsed()

from threading import Thread
import cv2

class WebcamVideoStream:
    def __init__(self, src=0):
        # initialize the video camera stream and read the first frame
        # from the stream
        self.stream = cv2.VideoCapture(src)
        (self.grabbed, self.frame) = self.stream.read()

        # initialize the variable used to indicate if the thread should
        # be stopped
        self.stopped = False

    def start(self):
        # start the thread to read frames from the video stream
        Thread(target=self.update, args=()).start()
        return self

    def update(self):
        # keep looping infinitely until the thread is stopped
        while True:
            # if the thread indicator variable is set, stop the thread
            if self.stopped:
                break

            # otherwise, read the next frame from the stream
            (self.grabbed, self.frame) = self.stream.read()

    def read(self):
        # return the frame most recently read
        return self.frame

    def stop(self):
        # indicate that the thread should be stopped
        self.stopped = True

from imutils.video import WebcamVideoStream
from imutils.video import FPS
import argparse
import imutils
import cv2
import numpy as np
# construct the argument parse and parse the argumen

def onmouse(k, x, y, s, p):
    global hsv
    if k == 1:  # left mouse, print pixel at x,y
        print(hsv[y, x])

def distance_to_camera(Kwidth, focalLength, pixelWidth):
    return (Kwidth * focalLength) / pixelWidth

def contourArea(contours):

    area = []
    for i in range(0,len(contours)):
       area.append([cv2.contourArea(contours[i]),i])

    area.sort()
    if(area[len(area) - 1] >= 5 * area[0]):
        return area[len(area)-1]

    else: return 0

if __name__ == "__main__":
    ap = argparse.ArgumentParser()
    ap.add_argument("-n", "--num-frames", type=int, default=100,
                    help="# of frames to loop over for FPS test")
    ap.add_argument("-d", "--display", type=int, default=-1,
                    help="Whether or not frames should be displayed")
    args = vars(ap.parse_args())

    print("[INFO] sampling frames from webcam...")
    stream = cv2.VideoCapture(0)
    fps = FPS().start()

    # loop over some frames
    while fps._numFrames < args["num_frames"]:
        # grab the frame from the stream and resize it to have a maximum
        # width of 400 pixels
        (grabbed, frame) = stream.read()
        frame = imutils.resize(frame, width=400)

        # check to see if the frame should be displayed to our screen
        if args["display"] > 0:
            cv2.imshow("Frame", frame)
            key = cv2.waitKey(1) & 0xFF

        # update the FPS counter
        fps.update()

    # stop the timer and display FPS information
    fps.stop()
    print("[INFO] elasped time: {:.2f}".format(fps.elapsed()))
    print("[INFO] approx. FPS: {:.2f}".format(fps.fps()))

    # do a bit of cleanup
    stream.release()
    cv2.destroyAllWindows()

    print("[INFO] sampling THREADED frames from webcam...")
    lower_green = np.array([70, 50, 120])

    upper_green = np.array([120, 200, 255])

    vs = WebcamVideoStream(src=0).start()
    fps = FPS().start()
    # loop over some frames...this time using the threaded stream
    while fps._numFrames < args["num_frames"]:
        # grab the frame from the threaded video stream and resize it
        # to have a maximum width of 400 pixels
        img = vs.read()

        im2, contours, hierarchy = cv2.findContours(img.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)

        # update the FPS counter
        fps.update()

    # stop the timer and display FPS information
    fps.stop()
    print("[INFO] elasped time: {:.2f}".format(fps.elapsed()))
    print("[INFO] approx. FPS: {:.2f}".format(fps.fps()))

    # do a bit of cleanup
    cv2.destroyAllWindows()
    vs.stop()


import openpyxl
import random

def create_word(GENRENUM):

  workbook = openpyxl.load_workbook('ワードウルフ_質問データベース_No1.xlsx')

  #sheet = workbook["General"]
  sheet=workbook.worksheets[GENRENUM-1]
  print("sheet名",sheet)
  max_row_num = sheet.max_row
  word_data = []

  for i in range(2,max_row_num+1):
    word1 = sheet.cell(row=i, column=1).value #word1
    word2 = sheet.cell(row=i, column=2).value #word2
    qest1 = sheet.cell(row=i, column=3).value #質問1
    qest2 = sheet.cell(row=i, column=4).value #質問2
    qest3 = sheet.cell(row=i, column=5).value #質問3

    #if cell_value not in suppliers:
    word_data.append([word1,word2,qest1,qest2,qest3])

  #print("max_row_num==>",max_row_num,len(word_data))
  word_num = random.randint(0,len(word_data)-1)
  #print("word_num-->",word_num)
  #print("word_data[0]-->",word_data[word_num])
  #print("word_data[7][0]-->",word_data[word_num][0])
  #print("word_data[7][1]-->",word_data[word_num][1])
  # 戻り地として、重複のない乱数列とデータ一覧を戻す。
  return word_data,max_row_num

# 重複のない乱数を生成する
def rand_ints_nodup(a, b, k):
  ns = []
  while len(ns) < k:
    n = random.randint(a, b)
    if not n in ns:
      ns.append(n)
  return ns

def check_genre():
  workbook = openpyxl.load_workbook('ワードウルフ_質問データベース_No1.xlsx')
  sheets = workbook.sheetnames

  print(sheets)

  return sheets


import fileinput
from os import path
from gensim.models import KeyedVectors

from SmartAnno.gui.Workflow import logMsg

NotInitiated = 0
Initiating = 1
Initiated = 2

class GloveModel:
    glove_model = None
    status = NotInitiated

    def __init__(self, word2vec_file='models/saved/glove/glove.42B.300d.bin', vocab=1900000, vect=300):
        glove_model = None
        if GloveModel.glove_model is None and GloveModel.status == NotInitiated:
            if path.isfile(word2vec_file):
                GloveModel.status = Initiating
                logMsg('Load glove model in the backend...')
                print('Load glove model in the backend...')
                if word2vec_file.endswith('.bin'):
                    glove_model = KeyedVectors.load_word2vec_format(word2vec_file, binary=True)
                    GloveModel.status = Initiated
                else:
                    glove_model = KeyedVectors.load_word2vec_format(word2vec_file, binary=False)
                    logMsg('convert txt model to binary model...')
                    glove_model.save_word2vec_format(word2vec_file[:-3] + '.bin', binary=True)
                    GloveModel.status = Initiated
            elif path.isfile(word2vec_file[:-3] + 'txt'):
                GloveModel.status = Initiating
                logMsg('Load glove model in the backend...')
                print('Load glove model in the backend...')
                txt_model = word2vec_file[:-3] + 'txt'
                self.addDimensions(txt_model, line_to_prepend=str(vocab) + ' ' + str(vect))
                glove_model = KeyedVectors.load_word2vec_format(txt_model, binary=False)
                logMsg('convert txt model to binary model...')
                glove_model.save_word2vec_format(word2vec_file, binary=True)
                GloveModel.status = Initiated
            else:
                logMsg(("Either ", path.abspath(word2vec_file), ' or ', path.abspath(word2vec_file[:-3] + 'txt'),
                           ' exists.'))
                print(("Either ", path.abspath(word2vec_file), ' or ', path.abspath(word2vec_file[:-3] + 'txt'),
                            ' exists.'))
            GloveModel.glove_model = glove_model
        pass

    def checkModelExistance(self, word2vec_file='models/glove/glove.42B.300d.bin'):
        if path.isfile(word2vec_file) or path.isfile(word2vec_file[:-3] + 'txt'):
            return True
        else:
            return False

    def addDimensions(self, filename, line_to_prepend):
        with open(filename, 'r') as f:
            line = f.readline()
            if line.startswith(line_to_prepend):
                return
        f = fileinput.input(filename, inplace=1)
        for xline in f:
            if f.isfirstline():
                print(line_to_prepend + '\n' + xline.rstrip('\r\n'))
            else:
                print(xline.rstrip('\r\n'))
        pass


# -*- coding: utf-8 -*-
"""
Created on Fri Feb 12 11:22:31 2021

@author: VERNET Marlone

"""

#from tpmontrouge.instrument.analog_input.test.simu_ai import AnalogInputThreadSimulation
#from tpmontrouge.instrument.daqmx.analog_input import DAQmxAnalogInput

from analog_input_marlon import DAQmxAnalogInput

from time import time
import PyDAQmx
import pickle

import numpy as np
import matplotlib.pyplot as plt

import scipy.signal as scs

from IPython import get_ipython
get_ipython().run_line_magic('matplotlib','qt')

plt.rcParams.update({'font.size': 22})

#%%

folder="C:/Users/admin-si/Desktop/Faraday_2_ML/ ????? /"

RECORDING = True
number = 1
freq_ = 30

# name = f'low_noise_ut_{number}_A1000G.pkl'
name1 = f'farad_{number}f{freq_}Hz.pkl'
# name2 = f'ur_{number}A1000G.pkl'

t1 = time()

plt.ion()

""" NI parameter """
DEV = '/dev2'
sample_rate = 2000
duration = 120 # en s

channel_list = ['0'] #['0', '1', '2'] #['1', '2'] #list of the recorded channels
N_ch = len(channel_list)
block_size = sample_rate//5
N_block = 5*duration
volt_range = 1 # en Volt

""" welch method parameters """
signal_size = sample_rate*duration
n = int(np.log(signal_size)/np.log(2)) - 1
segment_size = 2**n
number_segment = int(2*signal_size/segment_size) - 1
overlap_size = int( (signal_size - segment_size)/(number_segment - 1) )

"""mode diff, single_ended"""
acquisition_mode = PyDAQmx.DAQmx_Val_Diff
# acquisition_mode = PyDAQmx.DAQmx_Val_PseudoDiff
# acquisition_mode = PyDAQmx.DAQmx_Val_RSE

fig = plt.figure(figsize=(15,15))
ax = fig.subplots(3,N_ch)

fig.show()
fig.canvas.draw()

#task = AnalogInputThreadSimulation('AI')
task = DAQmxAnalogInput(DEV)
task.start(channel_list, sample_rate, block_size, N_block, volt_range, acquisition_mode)
t0 = time()
t=0

all_in = dict() #data are recorded in a dict, each key == one channel

for i in range(N_ch):
    all_in[i] = np.array([])

for _ in range(N_block):
    t=time() - t0
    # t+=block_size/sample_rate
    data = task.get_one_block()
    for k in range(N_ch):
        all_in[k] = np.concatenate([all_in[k], data[ channel_list[k] ]])
        ax[0,k].clear()
        #ax[0].plot(all_1)
        ax[0,k].plot(data[ channel_list[k] ])
        ax[0,k].set_title('t='+str(round(t,2)))

        ax[1,k].clear()
        #ax[0].plot(all_1)
        ax[1,k].plot(all_in[ k ])
        # ax[1,k].set_title('t='+str(round(t,2)))

        if len(all_in[k]) > segment_size:
            signal = all_in[k] - np.mean(all_in[k])
            f,psd = scs.welch(signal, fs=sample_rate, nperseg=segment_size, noverlap=overlap_size)
            ax[2,k].clear()
            ax[2,k].loglog(f,psd)

    fig.canvas.draw()
    plt.pause(0.01)
task.stop()

if RECORDING == True:

    with open(folder+name1, "wb") as fp:   #Pickling
        pickle.dump(all_in, fp)

print(time() - t1)

#%%
number = 100
name = f'low_noise_ut_{number}_A1000G.pkl'

with open(folder+name_, "rb") as fp:   #Pickling
    M = pickle.load(fp)

plt.figure()
plt.plot(M)
plt.grid()
plt.show()


#!/usr/bin/env python
import tornado.escape
import tornado.ioloop
import tornado.options
import tornado.web
import tornado.websocket

class BaseHandler(tornado.web.RequestHandler):
    def get_current_user(self):
        user_json = self.get_secure_cookie("fbdemo_user")
        if not user_json: return None
        return tornado.escape.json_decode(user_json)

class FacebookOAuth(BaseHandler, tornado.auth.FacebookGraphMixin):
    @tornado.web.authenticated
    @tornado.web.asynchronous
    def get(self):
        self.facebook_request("/me/home", self._on_accounts, access_token=self.current_user["access_token"])

    def _on_accounts(self, account):
        self.write(tornado.escape.json_encode(account))

class FacebookAuthLoginHandler(BaseHandler, tornado.auth.FacebookGraphMixin):
    @tornado.web.asynchronous
    def get(self):
        my_url = (self.request.protocol + "://" + self.request.host +
                  "/auth/facebook/login?next=" +
                  tornado.escape.url_escape(self.get_argument("next", "/")))
        if self.get_argument("code", False):
            self.get_authenticated_user(
                redirect_uri=my_url,
                client_id=self.settings["facebook_api_key"],
                client_secret=self.settings["facebook_secret"],
                code=self.get_argument("code"),
                callback=self._on_auth)
            return
        self.authorize_redirect(redirect_uri=my_url,
                                client_id=self.settings["facebook_api_key"],
                                extra_params={"scope": "read_stream"})

    def _on_auth(self, user):
        if not user:
            raise tornado.web.HTTPError(500, "Facebook auth failed")
        self.set_secure_cookie("fbdemo_user", tornado.escape.json_encode(user))
        self.redirect(self.get_argument("next", "/"))

class FacebookAuthLogoutHandler(BaseHandler, tornado.auth.FacebookGraphMixin):
    def get(self):
        self.clear_cookie("fbdemo_user")
        self.redirect(self.get_argument("next", "/"))


# 영상의 명암비 조절

# 명암비(Contrast)란?
# 밝은 곳과 어두운 곳 사이에 드러나는 밝기 정도의 차이
# 컨트라스트, 대비

# 기본적인 명암비 조절 함수
# dst(x, y) = saturate(s • src(x, y))  # 입력 영상에 scaling factor를 곱해서 결과 영상의 픽셀 값으로 셋팅
# => 단점 : s의 값에 따라 영상이 어두워지거나 전체적으로 포화되어 너무 밝아질 수 있다.

# 효과적인 명암비 조절 함수
# dst(X, y) = saturate(src(x, y) + (src(x, y) - 128) • α)
# (128, 128)을 무조건 지나고 기울기가 α의 값에 조절되는 직선의 방적식 그래프. (128은 고정이 아니고 영상에 따라 처리해줘야 한다.)
# src(x, y) + (src(x, y) - 128) • α ==> (1 + α) • src(x, y) - 128α

import sys
import numpy as np
import cv2

src = cv2.imread('lenna.bmp', cv2.IMREAD_GRAYSCALE)

if src is None:
    print('Image load failed!')
    sys.exit()

alpha = 1.0  # contrast를 올릴 것이기 때문에 alpha값을 1.0으로 설정
dst = np.clip((1 + alpha) * src - 128 * alpha, 0, 255).astype(np.uint8)  # 0보다 작으면 0, 255보다 크면 255로 clipping

cv2.imshow('src', src)
cv2.imshow('dst', dst)
cv2.waitKey()

cv2.destroyAllWindows()


import warnings
from functools import partial

import numpy as np
from sklearn.utils.extmath import squared_norm

from regain.math import create_from_diagonal, fill_diagonal, get_diagonal
from regain.update_rules import update_rho
from regain.utils import Convergence

try:
    from prox_tv import tv1_1d, tvp_1d, tvgen, tvp_2d
except ImportError:
    # fused lasso prox cannot be used
    pass

def soft_thresholding(a, lamda):
    """Soft-thresholding."""
    return np.sign(a) * np.maximum(np.abs(a) - lamda, 0)

def soft_thresholding_off_diagonal(a, lamda):
    """Soft-thresholding."""
    soft = soft_thresholding(a, lamda)
    fill_diagonal(soft, get_diagonal(a))
    return soft

def soft_thresholding_vector(a, lamda):
    """Soft-thresholding for vectors."""
    return np.maximum(1 - lamda / np.linalg.norm(a, axis=-1, keepdims=True), 0) * a

def blockwise_soft_thresholding(a, lamda):
    """Proximal operator for l2 norm column-wise."""
    out = soft_thresholding_vector(a.swapaxes(-1, -2), lamda).swapaxes(-1, -2)
    return out

def blockwise_soft_thresholding_symmetric(a, lamda):
    """Proximal operator for l2 norm, for symmetric matrices (last 2 axes)."""
    col_norms = np.linalg.norm(a, axis=-2)
    out = np.matmul(
        a, create_from_diagonal((1 - lamda / col_norms) * (col_norms > lamda))
    )
    return out

def prox_linf_1d(a, lamda):
    """Proximal operator for the l-inf norm, defined as:

    min ||x||_inf + (1/2t)||x-w||^2

    Since there is no closed-form, we can minimize it with scipy.

    Matlab reference
    ------
    %% Perform prox operator:   min_x (1/2t)||x-w||^2 subject to |x|<=radius
    function [ z ] = project_1ball( z,radius )
    %  By Moreau's identity, projection onto 1-norm ball can be computed
    %  using the proximal of the conjugate problem, which is L-infinity
    %  minimization.
      z = z -  prox_infinityNorm(z,radius);
    end

    %% Perform prox operator:   min ||x||_inf + (1/2t)||x-w||^2
    function [ xk ] = prox_infinityNorm( w,t )
        N = length(w);
        wabs = abs(w);
        ws = (cumsum(sort(wabs,'descend'))- t)./(1:N)';
        alphaopt = max(ws);
        if alphaopt>0
          xk = min(wabs,alphaopt).*sign(w); % truncation step
        else
          xk = zeros(size(w)); % if t is big, then solution is zero
        end
    end
    """
    from scipy.optimize import minimize

    def f(x):
        return lamda * np.linalg.norm(x, np.inf) + 0.5 * squared_norm(a - x)

    return minimize(f, a).x

def prox_linf(a, lamda):
    """Proximal operator for l-inf norm."""
    x = np.zeros_like(a)
    for t in range(a.shape[0]):
        x[t] = np.array([prox_linf_1d(a[t, :, j], lamda) for j in range(a.shape[1])]).T
    return x

def prox_logdet(a, lamda):
    """Time-varying latent variable graphical lasso prox."""
    es, Q = np.linalg.eigh(a)
    xi = (-es + np.sqrt(np.square(es) + 4.0 / lamda)) * lamda / 2.0
    # return np.linalg.multi_dot((Q, np.diag(xi), Q.T))

    # support ndim > 2
    Xi = create_from_diagonal(xi)
    QXiQt = np.matmul(np.matmul(Q, Xi), np.swapaxes(Q, -1, -2))
    return QXiQt

def prox_logdet_ala_ma(a, lamda):
    es, Q = np.linalg.eigh(a)
    xi = (-es + np.sqrt(np.square(es) + 4.0 * lamda)) / 2.0
    # return np.linalg.multi_dot((Q, np.diag(xi), Q.T))

    # support ndim > 2
    Xi = create_from_diagonal(xi)
    QXiQt = np.matmul(np.matmul(Q, Xi), np.swapaxes(Q, -1, -2))
    return QXiQt

def prox_trace_indicator(a, lamda):
    """Time-varying latent variable graphical lasso prox."""
    es, Q = np.linalg.eigh(a)
    xi = np.maximum(es - lamda, 0)
    # return np.linalg.multi_dot((Q, np.diag(xi), Q.T))

    # support ndim > 2
    Xi = create_from_diagonal(xi)
    QXiQt = np.matmul(np.matmul(Q, Xi), np.swapaxes(Q, -1, -2))
    return QXiQt

def prox_laplacian(a, lamda):
    """Prox for l_2 square norm, Laplacian regularisation."""
    return a / (1 + 2.0 * lamda)

def prox_node_penalty(A_12, lamda, rho=1, tol=1e-4, rtol=1e-2, max_iter=500):
    """Lamda = beta / (2. * rho).

    A_12 = np.vstack((A_1, A_2))
    """
    n_time, _, n_dim = A_12.shape

    U_1 = np.full((A_12.shape[0], n_dim, n_dim), 1.0 / n_dim, dtype=float)
    U_2 = np.copy(U_1)
    Y_1 = np.copy(U_1)
    Y_2 = np.copy(U_1)

    C = np.hstack((np.eye(n_dim), -np.eye(n_dim), np.eye(n_dim)))
    inverse = np.linalg.inv(C.T.dot(C) + 2 * np.eye(3 * n_dim))

    V = np.zeros_like(U_1)
    W = np.zeros_like(U_1)
    V_old = np.zeros_like(U_1)
    W_old = np.zeros_like(U_1)

    for iteration_ in range(max_iter):
        A = (
            Y_1 - Y_2 - W - U_1 + (W.transpose(0, 2, 1) - U_2).transpose(0, 2, 1)
        ) / 2.0
        V = blockwise_soft_thresholding_symmetric(A, lamda=lamda)

        A = np.concatenate(((V + U_2).transpose(0, 2, 1), A_12), axis=1)
        D = V + U_1
        # Z = np.linalg.solve(C.T*C + eta*np.identity(3*n), - C.T*D + eta* A)
        Z = np.empty_like(A)
        for i, (A_i, D_i) in enumerate(zip(A, D)):
            Z[i] = inverse.dot(2 * A_i - C.T.dot(D_i))
        W, Y_1, Y_2 = (Z[:, i * n_dim : (i + 1) * n_dim, :] for i in range(3))

        # update residuals
        delta_U_1 = V + W - (Y_1 - Y_2)
        delta_U_2 = V - W.transpose(0, 2, 1)
        U_1 += delta_U_1
        U_2 += delta_U_2

        # diagnostics
        rnorm = np.sqrt(squared_norm(delta_U_1) + squared_norm(delta_U_2))
        snorm = rho * np.sqrt(
            squared_norm(W - W_old) + squared_norm(V + W - V_old - W_old)
        )
        check = Convergence(
            obj=np.nan,
            rnorm=rnorm,
            snorm=snorm,
            e_pri=np.sqrt(2 * V.size) * tol
            + rtol
            * max(
                np.sqrt(squared_norm(W) + squared_norm(V + W)),
                np.sqrt(squared_norm(V) + squared_norm(Y_1 - Y_2)),
            ),
            e_dual=np.sqrt(2 * V.size) * tol
            + rtol * rho * np.sqrt(squared_norm(U_1) + squared_norm(U_2)),
        )
        W_old = W.copy()
        V_old = V.copy()

        # if np.linalg.norm(delta_U_1, 'fro') < tol and \
        #         np.linalg.norm(delta_U_2, 'fro') < tol:
        if check.rnorm <= check.e_pri and check.snorm <= check.e_dual:
            break
        rho_new = update_rho(rho, rnorm, snorm, iteration=iteration_)
        # scaled dual variables should be also rescaled
        U_1 *= rho / rho_new
        U_2 *= rho / rho_new
        rho = rho_new
    else:
        warnings.warn("Node norm did not converge.")
    return Y_1, Y_2

def prox_FL(a, beta, lamda, p=1, symmetric=False, use_matlab=False, optimize=True):
    """Fused Lasso prox.

    It is calculated as the Total variation prox + soft thresholding
    on the solution, as in
    http://ieeexplore.ieee.org/abstract/document/6579659/
    """
    # if any([any(np.diag(x) < 0) for x in a]):
    #     for a_i in a:
    #         np.fill_diagonal(a_i, np.sum(np.abs(a_i), axis=1))
    if optimize:
        Y = tvgen(a, [beta], [1], [p], n_threads=32, max_iters=30)

    else:
        Y = np.empty_like(a)
        # if use_matlab:
        #     from regain.wrapper.tv_condat import wrapper
        #     func = wrapper.total_variation_condat
        # else:
        func = tv1_1d if p == 1 else partial(tvp_1d, p=p)

        if symmetric:
            x, y = np.triu_indices_from(a[0])
            b = np.vstack(a.transpose(1, 2, 0))
            upper_ind = x * a.shape[1] + y
            Z = np.zeros_like(b)
            Z[upper_ind] = [func(row, beta) for row in b[upper_ind]]

            e = np.array(np.split(Z, a.shape[1], axis=0)).transpose(2, 0, 1)
            Y = (e + e.transpose(0, 2, 1)) / (
                np.array([np.eye(a.shape[1]) for i in range(a.shape[0])]) + 1
            )
        else:
            for i in range(np.power(a.shape[1], 2)):
                solution = func(a.flat[i :: np.power(a.shape[1], 2)], beta)
                Y.flat[i :: np.power(a.shape[1], 2)] = solution

    # fused-lasso (soft-thresholding on the solution)
    Y_soft = soft_thresholding(Y, lamda)

    # restore diagonal
    for y_s, y_fv in zip(Y_soft, Y):
        np.fill_diagonal(y_s, np.diag(y_fv))
    return Y_soft

    # Y = np.empty_like(a)
    # for i in range(a.shape[1]):
    #     for j in range(i, a.shape[2]):
    #         solution = tv1_1d(a[:, i, j], beta)
    #         # fused-lasso (soft-thresholding on the solution)
    #         if i != j:
    #             solution = soft_thresholding_sign(solution, lamda)
    #         Y[:, i, j] = solution
    # return Y

    # not work
    # x = np.vstack(a.transpose((2, 1, 0)))  # each row is the time evolution
    # assert np.allclose(np.array(xx), x)
    # x = np.apply_along_axis(
    #     compose(partial(soft_thresholding_sign, lamda=lamda),
    #             partial(tv1_1d, w=beta)), 1, x)
    # # return np.array(np.vsplit(x, x.shape[1])).transpose((2, 1, 0))
    # Z = np.array(np.vsplit(x, a.shape[1]))#.transpose((2, 1, 0))


r"""Code example for a custom model, using PyTorch.

This demo shows how to use a custom model with LIT, in just a few lines of code.
We'll use a transformers model, with a minimal amount of code to implement the
LIT API. Compared to models/glue_models.py, this has fewer features, but the
code is more readable.

This demo is equivalent in functionality to simple_tf2_demo.py, but uses PyTorch
instead of TensorFlow 2. The models behave identically as far as LIT is
concerned, and the implementation is quite similar - to see changes, run:
  git diff --no-index simple_tf2_demo.py simple_pytorch_demo.py

The transformers library can load weights from either,
so you can use any saved model compatible with the underlying model class
(AutoModelForSequenceClassification). To train something for this demo, you can:
- Use quickstart_sst_demo.py, and set --model_path to somewhere durable
- Or: Use tools/glue_trainer.py
- Or: Use any fine-tuning code that works with transformers, such as
https://github.com/huggingface/transformers#quick-tour-of-the-fine-tuningusage-scripts

To run locally:
  python -m lit_nlp.examples.simple_pytorch_demo \
      --port=5432 --model_path=/path/to/saved/model

Then navigate to localhost:5432 to access the demo UI.

NOTE: this demo still uses TensorFlow Datasets (which depends on TensorFlow) to
load the data. However, the output of glue.SST2Data is just NumPy arrays and
plain Python data, and you can easily replace this with a different library or
directly loading from CSV.
"""

from collections.abc import Sequence
import sys
from typing import Optional

from absl import app
from absl import flags
from absl import logging

from lit_nlp import dev_server
from lit_nlp import server_flags
from lit_nlp.api import model as lit_model
from lit_nlp.api import types as lit_types
# Use the regular GLUE data loaders, because these are very simple already.
from lit_nlp.examples.datasets import glue
from lit_nlp.lib import file_cache
from lit_nlp.lib import utils

import torch
import transformers

# NOTE: additional flags defined in server_flags.py

FLAGS = flags.FLAGS

FLAGS.set_default("development_demo", True)

_MODEL_PATH = flags.DEFINE_string(
    "model_path",
    "https://storage.googleapis.com/what-if-tool-resources/lit-models/sst2_tiny.tar.gz",
    "Path to trained model, in standard transformers format, e.g. as "
    "saved by model.save_pretrained() and tokenizer.save_pretrained()"
)

SequenceClassifierOutput = (
    transformers.modeling_outputs.SequenceClassifierOutput
)

def _from_pretrained(cls, *args, **kw):
  """Load a transformers model in PyTorch, with fallback to TF2/Keras weights."""
  try:
    return cls.from_pretrained(*args, **kw)
  except OSError as e:
    logging.warning("Caught OSError loading model: %s", e)
    logging.warning(
        "Re-trying to convert from TensorFlow checkpoint (from_tf=True)")
    return cls.from_pretrained(*args, from_tf=True, **kw)

class SimpleSentimentModel(lit_model.Model):
  """Simple sentiment analysis model."""

  LABELS = ["0", "1"]  # negative, positive

  def __init__(self, model_name_or_path):
    self.tokenizer = transformers.AutoTokenizer.from_pretrained(
        model_name_or_path)
    model_config = transformers.AutoConfig.from_pretrained(
        model_name_or_path,
        num_labels=2,
        output_hidden_states=True,
        output_attentions=True,
    )
    # This is a just a regular PyTorch model.
    self.model = _from_pretrained(
        transformers.AutoModelForSequenceClassification,
        model_name_or_path,
        config=model_config)
    self.model.eval()

  ##
  # LIT API implementation
  def max_minibatch_size(self):
    # This tells lit_model.Model.predict() how to batch inputs to
    # predict_minibatch().
    # Alternately, you can just override predict() and handle batching yourself.
    return 32

  def predict_minibatch(self, inputs):
    # Preprocess to ids and masks, and make the input batch.
    encoded_input = self.tokenizer.batch_encode_plus(
        [ex["sentence"] for ex in inputs],
        return_tensors="pt",
        add_special_tokens=True,
        max_length=128,
        padding="longest",
        truncation="longest_first")

    # Check and send to cuda (GPU) if available
    if torch.cuda.is_available():
      self.model.cuda()
      for tensor in encoded_input:
        encoded_input[tensor] = encoded_input[tensor].cuda()
    # Run a forward pass.
    with torch.no_grad():  # remove this if you need gradients.
      out: SequenceClassifierOutput = self.model(**encoded_input)

    # Post-process outputs.
    batched_outputs = {
        "probas": torch.nn.functional.softmax(out.logits, dim=-1),
        "input_ids": encoded_input["input_ids"],
        "ntok": torch.sum(encoded_input["attention_mask"], dim=1),
        "cls_emb": out.hidden_states[-1][:, 0],  # last layer, first token
    }
    # Return as NumPy for further processing.
    detached_outputs = {k: v.cpu().numpy() for k, v in batched_outputs.items()}
    # Unbatch outputs so we get one record per input example.
    for output in utils.unbatch_preds(detached_outputs):
      ntok = output.pop("ntok")
      output["tokens"] = self.tokenizer.convert_ids_to_tokens(
          output.pop("input_ids")[1:ntok - 1])
      yield output

  def input_spec(self) -> lit_types.Spec:
    return {
        "sentence": lit_types.TextSegment(),
        "label": lit_types.CategoryLabel(vocab=self.LABELS, required=False)
    }

  def output_spec(self) -> lit_types.Spec:
    return {
        "tokens": lit_types.Tokens(),
        "probas": lit_types.MulticlassPreds(parent="label", vocab=self.LABELS,
                                            null_idx=0),
        "cls_emb": lit_types.Embeddings()
    }

def get_wsgi_app() -> Optional[dev_server.LitServerType]:
  """Returns a LitApp instance for consumption by gunicorn."""
  FLAGS.set_default("server_type", "external")
  FLAGS.set_default("demo_mode", True)
  # Parse flags without calling app.run(main), to avoid conflict with
  # gunicorn command line flags.
  unused = flags.FLAGS(sys.argv, known_only=True)
  if unused:
    logging.info(
        "simple_pytorch_demo:get_wsgi_app() called with unused "
        "args: %s", unused)
  return main([])

def main(argv: Sequence[str]) -> Optional[dev_server.LitServerType]:
  if len(argv) > 1:
    raise app.UsageError("Too many command-line arguments.")

  # Normally path is a directory; if it's an archive file, download and
  # extract to the transformers cache.
  model_path = _MODEL_PATH.value
  if model_path.endswith(".tar.gz"):
    model_path = file_cache.cached_path(
        model_path, extract_compressed_file=True)

  # Load the model we defined above.
  models = {"sst": SimpleSentimentModel(model_path)}
  # Load SST-2 validation set from TFDS.
  datasets = {"sst_dev": glue.SST2Data("validation")}

  # Start the LIT server. See server_flags.py for server options.
  lit_demo = dev_server.Server(models, datasets, **server_flags.get_flags())
  return lit_demo.serve()

if __name__ == "__main__":
  app.run(main)


r'''>>> from getting_started2 import *
    >>> hi = hello('California')
    >>> hi.greet()
    'Hello from California'
    >>> invite(hi)
    'Hello from California! Please come soon!'
    >>> hi.invite()
    'Hello from California! Please come soon!'

    >>> class wordy(hello):
    ...     def greet(self):
    ...         return hello.greet(self) + ', where the weather is fine'
    ...
    >>> hi2 = wordy('Florida')
    >>> hi2.greet()
    'Hello from Florida, where the weather is fine'
    >>> invite(hi2)
    'Hello from Florida! Please come soon!'
'''

def run(args = None):
    if args is not None:
        import sys
        sys.argv = args
    import doctest, test_getting_started2
    return doctest.testmod(test_getting_started2)

if __name__ == '__main__':
    import sys
    sys.exit(run()[0])


import logging
import serial, time
import serial.tools.list_ports

class MatrixReadException(Exception):
    """Exception raised when reading from the arduino failed"""
    pass

class MatrixProtocolException(Exception):
    """Exception raised when the arduino did not follow the communication protocol as expected"""
    pass

def get_connected_arduinos():
    ports = list(serial.tools.list_ports.comports())
    return ports

def guess_arduino():
    ports = get_connected_arduinos()
    probably_an_arduino = None
    for port in ports:
        # this is the raspberry GPIO UART, where we are not connected
        if port.device == "/dev/ttyAMA0":
            pass
        # my arduino UNO
        elif "/dev/ttyACM" in port.device:
            probably_an_arduino = port.device
        # my arduino nano
        elif "/dev/ttyUSB" in port.device:
            probably_an_arduino = port.device
    return probably_an_arduino

class MatrixSerial:
    """This class handles the communication with the arduino"""

    def __init__(self, interface: str, led_count: int, baud: int = 115200, connect: bool = False,
                 enable_arduino_connection=False):
        """
        Create new MatrixSerial, immediately connecting to the arduino.

        :param interface the device name
        :param led_count: number of leds to use
        :param baud: baud rate to be used
        :param fps the maximum fps to use for updating
        """
        # store serial config
        self.interface = interface
        self.baud = baud
        self.serial = None

        # init buffer
        self.buffer = bytearray(led_count * 3)

        self.was_connected = False

        self.enable_arduino_connection = enable_arduino_connection

        self.logger = logging.getLogger("matrixserial")

        # convenience function for immediately connecting
        if connect and enable_arduino_connection:
            self.connect()

    def connect(self, timeout: float = 4):
        """
        connect to the arduino given the current configuration

        :param timeout: the number of seconds after which the connection attempt will be aborted
        :return: true if the handshake was completed successfully, false otherwise
        :raises: ValueError Will be raised when parameter are out of range, e.g. baud rate, data bits.
        :raises: SerialException In case the device can not be found or can not be configured.
        :raises: MatrixProtocolException if the arduino does not shake hands
        :
        """
        if not self.enable_arduino_connection:
            self.logger.info("the matrix serial was started in silent mode. connect() was ignored.")
            return

        self.was_connected = True

        self.logger.info("beginning arduino connection attempt to {} which has {} LEDs".format(self.interface, self.get_led_count()))

        # begin serial connection
        self.serial = serial.Serial(self.interface, self.baud, timeout=timeout)
        self.serial.flushInput()
        self.serial.flushOutput()

        # wait for arduino reset
        time.sleep(2)

        # begin handshake
        self.serial.write(b'hello')

        # wait for response
        response = self.serial.read(3)

        if response != b'SAM' and response != b'kSA':
            self.logger.warning("Handshake failed: expected b'SAM', got " + str(response))
            raise MatrixProtocolException("Handshake failed: expected b'SAM', got " + str(response))

        self.logger.info("successfully connected to arduino")

    def stop(self):
        if self.serial is not None:
            self.serial.close()

    def get_led_count(self) -> int:
        """ Query the number of leds this serial connection is configured for """
        return len(self.buffer) // 3

    def get_buffer_length(self) -> int:
        """ Query the length of the buffer required to send data to the arduino """
        return len(self.buffer)

    @staticmethod
    def current_time_ms() -> int:
        """Helper function. Returns a timestamp in ms"""
        return int(round(time.time() * 1000))

    def update(self, data: bytearray):
        """
        Update the data sent to the connected arduino
        :param data: a bytearray containing the new data, of len
        :raises: MatrixProtocolException if the arduino did not acknowledge the updated data
        """
        # ensure correct data length
        if len(data) != len(self.buffer):
            self.logger.error(
                "Bad data length! len(data) should be " + str(len(self.buffer)) + ", is " + str(len(data)))
            raise MatrixProtocolException(
                "Bad data length! len(data) should be " + str(len(self.buffer)) + ", is " + str(len(data)))

        # copy buffer
        self.buffer[:] = data

        # trigger internal draw call
        self.__draw()

    def __draw(self):
        """
        Draw the current buffer content by sending it to the arduino as-is
        :raises: MatrixProtocolException if the arduino did not acknowledge a sent buffer
        """

        if not self.enable_arduino_connection:
            return

        # we need to wait some time before writing the next set of data. testing required for better accuracy
        time.sleep(0.009)

        # write out internal buffer to arduino
        self.serial.write(self.buffer)

        # read arduino acknowledgement char
        try:
            ack = self.serial.read(1)
        except serial.serialutil.SerialException as e:
            self.logger.exception("A serial error occurred when trying to read from the matrix!")
            raise MatrixReadException(str(e))
        else:
            # check acknowledgement char correctness
            if ack != b'k':
                self.logger.exception("No acknowledgement received, expected b'k', got " + str(ack))
                raise MatrixProtocolException("No acknowledgement received, expected b'k', got " + str(ack))


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

import state

# karma dict
KARMA = dict()

def cmd_karma(msg):
    """
    Karma command. Return string with karma of detected nick.

    @param msg  input string
    """

    global KARMA
    msg = msg.strip()

    if msg == '':
        return state.next('No name given')

    if KARMA.has_key(msg):
        return state.done(msg + "'s karma is " + str(KARMA[msg]))
    else:
        return state.done(msg + " has no karma")

def _karma_change(name, op):
    """
    Change one's karma. Should be used only by karma filter, not user.

    @param name     name to operate with
    @param op       action

    If op == ++ then increase karma by 1
    if op == -- then decrease karma by 1
    else raise ValueError. This would be critical, because op is given
    by programator --> error in program, not in user input.
    """

    global KARMA

    try:
        if op == '++':
            KARMA[name] += 1
        elif op == '--':
            KARMA[name] -= 1
        else:
            raise ValueError   # critical error (in source, not in user)
    except KeyError:
        KARMA[name] = 1 if op == '++' else -1

def filter_karma(msg):
    """
    Implement karma filter. Try catch karma commands and do appropriate
    action

    @param msg      input string
    """

    if msg.endswith('++') or msg.endswith('--'):
        # 'C++' exclusive
        if msg.lower() != 'c++' and msg[:-2].isalnum():
            _karma_change(msg[:-2], msg[-2:])
            return state.done(None)
        else:
            return state.next(msg)

# CREATE SOME UNITS


import importlib
from oslo_config import cfg

# Add default values for the database to be used for dockyard.
DATABASE_OPT = [
    cfg.StrOpt("driver",
                default="consul.consul_client.ConsulKV",
                help="Database driver for dockyard"),
    cfg.IntOpt('synchronization_time',
                default=20,
                help='Time after which data will be synced .')
]

CONF = cfg.CONF
opt_group = cfg.OptGroup(name='database',
                         title='Group for database')
CONF.register_group(opt_group)
CONF.register_opts(DATABASE_OPT, opt_group)
db_driver_loc = 'dockyard.common.stores'
db_driver_info = (('%s.%s') % (db_driver_loc, CONF.database.driver))
module_name, db = db_driver_info.rsplit(".", 1)
module = importlib.import_module(module_name)

#import synchronizer


# 실버1. 숨바꼭질
# 전혀 모르겠는데 답 보니까 코드는 짧아서 약올라
# not 구문 처음보는거같은데 진짠가

from collections import deque

N, K = map(int, input().split())
max = 100000
visited = [0] * (max+1)

def bfs():
    q = deque()
    q.append(N)
    while q:
        x = q.popleft()
        if x == K:
            print(visited[x])
            break
        for j in (x-1, x+1, x*2):
            if 0<= j <= max and not visited[j]:
                visited[j] = visited[x] + 1
                q.append(j)

bfs()


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

from utils.sent_utils import inf_batch_iterator, iterate_minibatches_indices
from utils.common_utils import log

import sklearn.linear_model as linear_model
import tensorflow as tf
import numpy as np

def linear_mapping(x, y, n_jobs=8):
  # train least square
  projection = linear_model.LinearRegression(n_jobs=n_jobs)
  projection.fit(x, y)
  return projection.predict

def mlp_mapping(x, y, epochs=30, batch_size=256, lr=1e-3, wd=1e-4,
                activation=tf.nn.relu, norm=False):
  dim = y.shape[1]
  l2_reg = tf.keras.regularizers.l2(wd)
  model = tf.keras.models.Sequential()
  model.add(tf.keras.layers.Dense(dim, activation=activation, name='reg_fc',
                                  kernel_regularizer=l2_reg))
  model.add(tf.keras.layers.Dense(dim, name='reg_output',
                                  kernel_regularizer=l2_reg))
  if norm:
    model.add(tf.keras.layers.Lambda(lambda x: tf.nn.l2_normalize(x, axis=-1),
                                     name='reg_norm'))
  model.compile(tf.keras.optimizers.Adam(lr), loss='mse', metric='mse')
  model.fit(x, y, batch_size=batch_size, verbose=1, epochs=epochs)

  def mapping(z):
    mapped = model.predict(z, batch_size=1024)
    tf.keras.backend.clear_session()
    return mapped

  return mapping

class Generator(object):
  def __init__(self, output_dim, activation=tf.nn.relu):
    self.fc1 = tf.keras.layers.Dense(output_dim, activation=activation,
                                     name='gen_fc1')
    # self.fc2 = tf.keras.layers.Dense(output_dim, activation=activation,
    #                                  name='gen_fc2')
    self.output = tf.keras.layers.Dense(output_dim, name='gen_output')

  def forward(self, x):
    x = self.fc1(x)
    # x = self.fc2(x)
    x = self.output(x)
    return x

class Discriminator(object):
  def __init__(self, output_dim, activation=tf.nn.relu):
    self.fc1 = tf.keras.layers.Dense(output_dim, activation=activation,
                                     name='disc_fc1')
    # self.fc2 = tf.keras.layers.Dense(output_dim, activation=activation,
    #                                  name='disc_fc2')
    self.output = tf.keras.layers.Dense(1, name='disc_output')

  def forward(self, y):
    y = self.fc1(y)
    # y = self.fc2(y)
    y = self.output(y)
    return y

class WGANGP(object):
  """Learn a GAN that translates x to y"""
  def __init__(self, x_dim, y_dim, lr=5e-4, lmbda=10., gamma=0., beta1=0.5,
               activation=tf.nn.relu):
    self.generator = Generator(y_dim, activation)
    self.discriminator = Discriminator(y_dim, activation)
    self.input_x = tf.placeholder(tf.float32, shape=(None, x_dim), name='x')
    self.input_y = tf.placeholder(tf.float32, shape=(None, y_dim), name='y')

    self.real_score = self.discriminator.forward(self.input_y)
    self.fake_y = self.generator.forward(self.input_x)
    self.fake_score = self.discriminator.forward(self.fake_y)

    # calculate gradient penalty
    alpha = tf.random.uniform(shape=tf.shape(self.fake_y), minval=0.,
                              maxval=1.)
    self.interpolate_y = alpha * self.input_y + self.fake_y
    grad = tf.gradients(self.discriminator.forward(self.interpolate_y),
                        [self.interpolate_y])[0]
    grad_norm = tf.norm(grad, axis=1, ord='euclidean')
    self.grad_pen = tf.reduce_mean(tf.square(grad_norm - 1))

    t_vars = tf.trainable_variables()

    self.disc_params = [v for v in t_vars if v.name.startswith('disc')]
    self.disc_optimizer = tf.train.AdamOptimizer(lr, beta1=beta1)
    self.disc_loss = tf.reduce_mean(self.fake_score) - tf.reduce_mean(
      self.real_score)
    self.disc_train_ops = self.disc_optimizer.minimize(
        self.disc_loss + lmbda * self.grad_pen, var_list=self.disc_params)

    l2_loss = tf.reduce_sum(tf.square(self.fake_y - self.input_y), axis=-1)
    self.l2_loss = tf.reduce_mean(l2_loss)

    self.gen_params = [v for v in t_vars if v.name.startswith('gen')]
    self.gen_optimizer = tf.train.AdamOptimizer(lr, beta1=beta1)
    self.gen_loss = -tf.reduce_mean(self.fake_score)
    self.gen_train_ops = self.gen_optimizer.minimize(
        self.gen_loss + gamma * self.l2_loss, var_list=self.gen_params)

  def generate(self, sess, x):
    return sess.run(self.fake_y, {self.input_x: x})

  def train_disc_one_batch(self, sess, x, y):
    d_err, _ = sess.run([self.disc_loss, self.disc_train_ops],
                        {self.input_x: x, self.input_y: y})
    return d_err

  def train_gen_one_batch(self, sess, x, y):
    g_err, l2_err, _ = sess.run([-self.gen_loss, self.l2_loss,
                                 self.gen_train_ops],
                                {self.input_x: x, self.input_y: y})
    return g_err, l2_err

def gan_mapping(x, y, lr=1e-4, lmbda=10., gamma=0., beta1=0.5,
                activation=tf.nn.relu, epoch=30, disc_iters=10,
                batch_size=128):
  n_data, x_dim = x.shape
  y_dim = y.shape[1]
  model = WGANGP(x_dim, y_dim, lr=lr, lmbda=lmbda, gamma=gamma, beta1=beta1,
                 activation=activation)

  gen_sampler = inf_batch_iterator(n_data, batch_size)
  disc_sampler = inf_batch_iterator(n_data, batch_size)
  num_batch_per_epoch = n_data // batch_size + (n_data % batch_size) != 0

  sess = tf.Session()
  sess.run(tf.global_variables_initializer())
  for e in range(epoch):
    train_d_loss = []
    train_g_loss = []
    train_l2_loss = []
    for _ in range(num_batch_per_epoch):
      # train disc first
      for _ in range(disc_iters):
        disc_idx = next(disc_sampler)
        disc_x, disc_y = x[disc_idx], y[disc_idx]
        d_err = model.train_disc_one_batch(sess, disc_x, disc_y)
        train_d_loss.append(d_err)

      gen_idx = next(gen_sampler)
      gen_x, gen_y = x[gen_idx], y[gen_idx]
      g_err, l2_err = model.train_gen_one_batch(sess, gen_x, gen_y)
      train_g_loss.append(g_err)
      train_l2_loss.append(l2_err)

    train_d_loss = np.mean(train_d_loss)
    train_g_loss = np.mean(train_g_loss)
    train_l2_loss = np.mean(train_l2_loss)
    log('Epoch: {}, disc loss: {:.4f}, gen loss: {:.4f},'
        ' l2 loss: {:.4f}'.format(
          e + 1, train_d_loss, train_g_loss, train_l2_loss))

  def mapping(z):
    mapped = []
    for idx in iterate_minibatches_indices(len(z), batch_size=2048):
      batch_mapped = model.generate(sess, z[idx])
      mapped.append(batch_mapped)

    tf.keras.backend.clear_session()
    return np.vstack(mapped)

  return mapping


# 54. Spiral Matrix
class Solution:
    def spiralOrder(self, matrix: List[List[int]]) -> List[int]:
        '''
        To make the logic clear, do all the boundaries update at the end of
        the while loop.

        Note that when processing the last row and the first column, need to
        check for duplicates.
        '''
        if not matrix or not matrix[0]:
            return []

        ans = []
        row_start, row_end = 0, len(matrix)
        col_start, col_end = 0, len(matrix[0])
        while row_start < row_end and col_start < col_end:
            # top row
            for col in range(col_start, col_end):
                ans.append(matrix[row_start][col])
            # right col
            for row in range(row_start+1, row_end):
                ans.append(matrix[row][col_end-1])
            # bottom row if not overlapped with top row
            if row_start != row_end - 1:
                for col in reversed(range(col_start, col_end-1)):
                    ans.append(matrix[row_end-1][col])
            # left col if not overlapped with right col
            if col_start != col_end - 1:
                for row in reversed(range(row_start+1, row_end-1)):
                    ans.append(matrix[row][col_start])

            row_start += 1
            row_end -= 1
            col_start += 1
            col_end -= 1

        return ans