#!/usr/bin/env python3
"""Access to SAM and BAM files through htslib"""

import collections
import ctypes
import logging
import os
import os.path

from pyhtslib.hts_internal import *  # NOQA
from pyhtslib.bam_internal import *  # NOQA
from pyhtslib.tabix_internal import *  # NOQA

__author__ = 'Manuel Holtgrewe <manuel.holtgrewe@bihealth.de>'

class BAMIndexException(Exception):
    """Raised when there is a problem with a BAMIndex file"""

class BAMFileException(Exception):
    """Raised when there is a problem with a BAMFile file"""

class BAMHeaderTargetInfo:
    """Information (name, length) for the reference/target sequence"""

    def __init__(self, name, length):
        #: name of the target/reference
        self.name = name
        #: length of the target/reference
        self.length = length

    def __eq__(self, other):
        return (self.name == other.name and self.length == other.length)

    def __repr__(self):
        return 'BAMHeaderTargetInfo({}, {})'.format(
            repr(self.name), self.length)

class BAMHeaderRecord:
    """Header record"""

    def __init__(self, key, tags):
        #: type of the header record
        self.key = key
        #: tags of the header record, ordered dict of ``str`` to ``str``
        #: mappings
        self.tags = collections.OrderedDict(tags)

    def for_sam_header(self):
        """Return SAM header line representation, excluding line ending"""
        def f(item):
            return '{}:{}'.format(*item)
        return '@{}\t{}'.format(self.key,
                                '\t'.join(map(f, self.tags.items())))

    def from_sam_header(line):
        arr = line.strip().split('\t')
        key = arr[0][1:]
        items = [entry.split(':', 1) for entry in arr[1:]]
        return BAMHeaderRecord(key, items)

    def __eq__(self, other):
        return self.key == other.key and self.tags == other.tags

    def __repr__(self):
        return 'BAMHeaderRecord({}, {})'.format(repr(self.key), self.tags)

class BAMHeaderComment:
    """Comments that can also appear in the header"""

    def __init__(self, text):
        #: comment text
        self.text = text

    def for_sam_header(self):
        """Return SAM header line representation, excluding line ending"""
        return '@CO\t' + self.text

    @staticmethod
    def from_sam_header(line):
        return BAMHeaderComment(line.strip().split('\t', 1)[1])

    def __eq__(self, other):
        return self.text == other.text

    def __repr__(self):
        return 'BAMHeaderComment.format({})'.format(self.text)

class BAMHeader:
    """Information stored in the BAM header"""

    @staticmethod
    def _read_from_file(file_ptr):
        return BAMHeader(_sam_hdr_read(file_ptr))

    def __init__(self, struct_ptr=None):
        #: pointer to internal representation
        self.struct_ptr = struct_ptr
        #: internal representation
        self.struct = struct_ptr[0] if struct_ptr else None
        #: target/reference informations [(name, length)]
        self.target_infos = []
        #: list of ``BAMHeaderRecord and ``BAMComment``
        self.header_records = []

        self._fill_from_struct()

    def _fill_from_struct(self):
        """Fill BAM header from self.struct if given"""
        if not self.struct:
            return  # nothing given
        s = self.struct
        # read the list of (name, length) pairs
        for i in range(self.struct.n_targets):
            self.target_infos.append(
                BAMHeaderTargetInfo(s.target_name[i].decode('utf-8'),
                                    s.target_len[i]))
        # parse headers from the text
        recs = self.header_records
        for line in s.text.decode('utf-8').splitlines(True):
            if line.startswith('@CO'):
                recs.append(BAMHeaderComment.from_sam_header(line))
            else:
                recs.append(BAMHeaderRecord.from_sam_header(line))

    def free(self):
        """Free structs associated with the header

        If you use ``BAMFile`` as a context manager (using ``with``) then
        this function is called automatically when the context is left.
        """
        if not self.struct_ptr:
            return  # not set
        _bam_hdr_destroy(self.struct_ptr)
        self.struct_ptr = None
        self.struct = None

    def to_sam_header(self):
        """Return SAM header representation"""
        def f(entry):
            return entry.to_sam_header()
        return '\n'.join(map(f, self.header_record))

class CIGARElement:
    """CIGAR element"""

    def __init__(self, count, operation):
        #: CIGAR count
        self.count = count
        #: CIGAR operation
        self.operation = operation

    def __repr__(self):
        return 'CIGARElement({}, {})'.format(
            self.count, repr(self.operation))

    def __str__(self):
        return '{}{}'.format(self.count, self.operation)

class BAMAuxTagParser:
    """Helper for parsing aux field tags from BAM records"""
    # TODO(holtgrewe): This probably works better using ctypes.string_at and
    # then performing all parsing in native Python.

    def __init__(self, struct_ptr, aux, aux_len):
        self.struct_ptr = struct_ptr
        self.aux = aux
        self.aux_len = aux_len
        self.keys = self.get_keys()

    def get_keys(self):
        """Get keys"""
        def aux_type2size(t):
            DIR = {'A': 1, 'c': 1, 'C': 1, 's': 2, 'S': 2, 'i': 4, 'I': 4,
                   'f': 4, 'd': 8, 'Z': 'Z', 'H': 'H', 'B': 'B'}
            return DIR.get(t, 0)

        def skip_aux(s):
            # skip the type
            def deref(s):
                return ctypes.c_char.from_address(s).value
            size = aux_type2size(deref(s).decode('utf-8'))
            # print('c={}, size={}'.format(deref(s), size), file=sys.stderr)
            s += 1
            if size in ['Z', 'H']:
                while deref(s) != b'\x00':
                    s += 1
                return s + 1
            elif size == 'B':
                size = aux_type2size(deref(s).decode('utf-8'))
                s += 1
                n = ctypes.c_uint32(0)
                ctypes.memmove(ctypes.byref(n), s, 4)
                return s + size * n.value
            elif size == 0:
                raise BAMFileException('Problem parsing auxiliary fields!')
            else:
                return s + size

        result = []
        s = ctypes.addressof(self.aux.contents)
        while s < ctypes.addressof(self.aux.contents) + self.aux_len:
            c1 = ctypes.c_char.from_address(s).value.decode('utf-8')
            c2 = ctypes.c_char.from_address(s + 1).value.decode('utf-8')
            result.append('{}{}'.format(c1, c2))
            # print('result={}'.format(result), file=sys.stderr)
            s = skip_aux(s + 2)
        return result

    def __call__(self):
        result = collections.OrderedDict()
        for key in self.keys:
            # print('key={}'.format(key), file=sys.stderr)
            ptr = _bam_aux_get(self.struct_ptr, key.encode('utf-8'))
            # print('ptr={}'.format(ptr), file=sys.stderr)
            t = chr(ptr[0])
            # print('t={}'.format(t), file=sys.stderr)
            if t in ['c', 'C', 's', 'S', 'i', 'I']:
                result[key] = _bam_aux2i(ptr)
            elif t in ['d', 'f']:
                result[key] = _bam_aux2f(ptr)
            elif t in ['A']:
                result[key] = _bam_aux2A(ptr)
            elif t in ['Z', 'H']:
                result[key] = ctypes.string_at(
                    ctypes.addressof(_bam_aux2Z(ptr).contents)).decode('utf-')
            else:
                # TODO(holtgrewe): finish for arrays
                print('WARNING: unknown type {}'.format(t), file=sys.stderr)
                result[key] = None
        return result

class BAMRecordImpl:
    """Information extracted from C internals of ``BAMRecord``"""

    @staticmethod
    def from_struct(ptr, header):
        """Return ``BAMRecordImpl`` from internal C structure"""
        qname = _bam_get_qname(ptr).value.decode('utf-8')
        flag = ptr[0].core.flag
        tid = ptr[0].core.tid
        ref = header.target_infos[ptr[0].core.tid].name
        pos = ptr[0].core.pos
        end_pos = _bam_endpos(ptr)
        mapq = ptr[0].core.qual
        cigar = BAMRecordImpl._cigar(ptr)
        mtid = ptr[0].core.mtid
        mref = header.target_infos[ptr[0].core.mtid].name
        mpos = ptr[0].core.mpos
        isize = ptr[0].core.isize
        _l_qseq = ptr[0].core.l_qseq
        _seq_ptr = ctypes.cast(_bam_get_seq(ptr),
                               ctypes.POINTER(ctypes.c_uint8))
        seq = ''.join([_BAM_SEQ_STR[_bam_seqi(_seq_ptr, i)]
                       for i in range(_l_qseq)])
        _qual_ptr = _bam_get_qual(ptr)
        qual = ''.join([chr(ord('!') + _qual_ptr[i]) for i in range(_l_qseq)])
        # TODO(holtgrewe): make parsing of tags lazy
        tags = BAMAuxTagParser(ptr, _bam_get_aux(ptr), _bam_get_l_aux(ptr))()

        return BAMRecordImpl(qname, flag, tid, ref, pos, end_pos, mapq, cigar,
                             mtid, mref, mpos, isize, seq, qual, tags)

    @staticmethod
    def _cigar(ptr):
        def to_ce(cigar):
            return CIGARElement(_bam_cigar_oplen(cigar),
                                _bam_cigar_opchr(cigar))

        cigar_arr = _bam_get_cigar(ptr)
        return [to_ce(cigar_arr[i]) for i in range(ptr[0].core.n_cigar)]

    def __init__(self, qname, flag, r_id, ref, begin_pos, end_pos, mapq,
                 cigar, r_id_next, ref_next, pos_next, tlen, seq, qual,
                 tags):
        #: read name (QNAME)
        self.qname = qname
        #: numeric flag (FLAG)
        self.flag = flag
        #: reference id of fragment's alignment (RID)
        self.r_id = r_id
        #: reference name of the alignment
        self.ref = ref
        #: begin position of the alignment (POS)
        self.begin_pos = begin_pos
        #: 0-base end position of alignment (inferred from ``begin_pos``
        #: and ``cigar``
        self.end_pos = end_pos
        #: mapping quality (MAPQ)
        self.mapq = mapq
        #: CIGAR string
        self.cigar = cigar
        #: reference id of next fragment's alignment
        self.r_id_next = r_id_next
        #: reference name of next fragment's alignment
        self.ref_next = ref_next
        #: 0-based position of next fragment's alignment
        self.pos_next = pos_next
        #: template length (TLEN)
        self.tlen = tlen
        #: sequence string (SEQ)
        self.seq = seq
        #: quality string (QUAL)
        self.qual = qual
        #: tags, as ``OrderedDict``
        self.tags = tags

    @property
    def is_paired(self):
        return (self.flag & _BAM_FPAIRED) != 0

    @property
    def is_proper_pair(self):
        return (self.flag & _BAM_FPROPER_PAIR) != 0

    @property
    def is_unmapped(self):
        return (self.flag & _BAM_UNMAP) != 0

    @property
    def is_mate_unmapped(self):
        return (self.flag & _BAM_MUNMAP) != 0

    @property
    def is_reversed(self):
        return (self.flag & _BAM_FREVERSE) != 0

    @property
    def is_mate_reversed(self):
        return (self.flag & _BAM_FMREVERSE) != 0

    @property
    def is_first(self):
        return (self.flag & _BAM_FREAD1) != 0

    @property
    def is_last(self):
        return (self.flag & _BAM_FREAD2) != 0

    @property
    def is_secondary(self):
        return (self.flag & _BAM_FSECONDARY) != 0

    @property
    def is_qc_fail(self):
        return (self.flag & _BAM_FQC_FAIL) != 0

    @property
    def is_duplicate(self):
        return (self.flag & _BAM_FDUPLICATE) != 0

    @property
    def is_supplementary(self):
        return (self.flag & _BAM_FSUPPLEMENTARY) != 0

class BAMRecord:
    """Record from a BAM file"""

    def __init__(self, struct_ptr=None, header=None, impl=None):
        #: pointer to wrapped C struct
        self.struct_ptr = struct_ptr
        #: wrapped C struct
        self.struct = None
        if self.struct_ptr:
            self.struct = self.struct_ptr[0]
        #: ``BAMHeader`` for references
        self.header = header
        #: ``BAMRecordImpl`` instance used for the representation
        self.impl = impl

    def detach(self):
        """Return copy that is detached from the underlying C object

        The only way of obtaining ``BAMRecord``s is through iterating
        ``BAMFile`` objects, either through an index or not.  For efficiency,
        the reading reuses the same buffer for reading.  If you want to keep a
        ``BAMRecord`` around for longer than the current iteration then you
        have to obtain a copy that is independent of the current buffer
        through the use of ``detach()``.
        """
        impl = self.impl
        if not impl:
            impl = BAMRecordImpl.from_struct(self.struct_ptr, self.header)
        self.impl = None
        return BAMRecord(impl=impl)

    def _reset(self):
        """Reset Python side, as if freshly constructed"""
        self.impl = None

    def __getattr__(self, name):
        """Delegation to self.impl if set, auto-set from struct"""
        if not self.impl and not self.struct:
            raise AttributeError('self.impl is None and cannot rebuild from '
                                 'None self.struct')
        elif not self.impl and self.struct:
            self.impl = BAMRecordImpl.from_struct(self.struct_ptr, self.header)
        return getattr(self.impl, name)

class BAMFileIter:
    """Iterate over a ``BAMFile``

    Do not use directly but by iterating over ``BAMFile``.  Iteration must
    be completed or ``close()`` must be called to prevent resource leaks.
    """

    def __init__(self, bam_file):
        #: the ``BAMFile`` to iterate through
        self.bam_file = bam_file
        #: buffer for readin in the file itself
        self.struct_ptr = _bam_init1()
        #: pointer to buffer for reading in the file record by record
        self.struct = self.struct_ptr[0]
        #: ``BAMRecord`` meant for consumption by the user
        self.record = BAMRecord(self.struct_ptr, self.bam_file.header)

    def __next__(self):
        r = _sam_read1(self.bam_file.struct_ptr,
                       self.bam_file.header.struct_ptr,
                       ctypes.byref(self.struct))
        if r >= 0:
            # successfully read record from file
            self.record._reset()
            return self.record
        else:
            # end of file or something went wrong
            self.close()
            if r < -1:
                tpl = 'truncated file {}'
                raise BAMFileException(tpl.format(self.bam_file.path))
            else:
                self.close()
                raise StopIteration

    def close(self):
        if self.struct_ptr:
            _bam_destroy1(self.struct_ptr)
            self.struct_ptr = None
            self.struct = None

# TODO(holtgrewe): we probably want to differentiate BAM/CRAM and SAM.gz with
# two classes
class BAMIndexIter:
    """Iterate over query results from a ``BAMIndex``

    Do not use directly but by iterating over query result of``BAMIndex``.
    Iteration must be completed or ``close()`` must be called to prevent
    resource leaks.
    """

    def __init__(self, bam_index, itr):
        #: the ``BAMIndex`` to iterate through
        self.bam_index = bam_index
        #: the ``BAMFile`` used
        self.bam_file = self.bam_index.bam_file
        #: buffer for reading in the file itself
        self.struct_ptr = _bam_init1()
        #: pointer to buffer for reading in the file record by record
        self.struct = self.struct_ptr[0]
        #: pointer to iterator struct to for iteration
        self.itr_ptr = itr
        #: iterator struct to use for iteration
        self.itr = self.itr_ptr[0]
        #: ``BAMRecord`` meant for consumption by the user
        self.record = BAMRecord(self.struct_ptr, self.bam_file.header)
        # buffer to use in case of SAM.gz
        self._buffer = None
        if not self.bam_index.is_bam_or_cram:
            self._buffer = _kstring_t(0, 0, None)

    def __iter__(self):
        return self

    def __next__(self):
        if self.bam_index.is_bam_or_cram:
            r = _sam_itr_next(self.bam_file.struct_ptr,
                              self.itr_ptr,
                              ctypes.byref(self.struct))
        else:
            r = _tbx_itr_next(self.bam_file.struct_ptr,
                              self.bam_index.struct_ptr,
                              self.itr_ptr,
                              ctypes.byref(self._buffer))
        if r >= 0:
            # attempt to parse SAM, if SAM
            if not self.bam_index.is_bam_or_cram:
                _sam_parse1(ctypes.byref(self._buffer),
                            self.bam_file.header.struct_ptr,
                            ctypes.byref(self.struct))
            # successfully read record from file
            self.record._reset()
            return self.record
        else:
            # end of file or something went wrong
            self.close()
            if r < -1:
                tpl = 'truncated file {}'
                raise BAMFileException(tpl.format(self.bam_file.path))
            else:
                self.close()
                raise StopIteration

    def close(self):
        if self.struct_ptr:
            _bam_destroy1(self.struct_ptr)
            self.struct_ptr = None
            self.struct = None
        if self._buffer:
            self._buffer.free_p()
            self._buffer = None
        if self.itr_ptr and self.bam_index.is_bam_or_cram:
            _sam_itr_destroy(self.itr_ptr)
            self.itr_ptr = None
            self.itr = None
        elif self.itr_ptr and not self.bam_index.is_bam_or_cram:
            _tbx_itr_destroy(self.itr_ptr)
            self.itr_ptr = None
            self.itr = None

class BAMFile:
    """Wrapper for SAM/BAM/CRAM access

    It's strongly recommended to use as a context manager or through
    ``BAMIndex``.
    """

    def __init__(self, path):
        #: path to BAM file
        self.path = path
        #: wrapped C struct
        self.struct = None
        #: pointer to C struct
        self.struct_ptr = None
        #: representation of BAM header
        self.header = None

        # collection of iterators, we will call close() on all of them
        # in our own close to ensure that all memory is freed
        self.iterators = []

    def open(self):
        """Open file and read header"""
        if self.struct_ptr:
            return  # already open
        # open file and store handles
        self.struct_ptr = _hts_open(self.path.encode('utf-8'), 'r')
        self.struct = self.struct_ptr[0]
        # read header
        self.header = BAMHeader._read_from_file(self.struct_ptr)

    def close(self):
        """Close file again and free header and other data structures

        This function is idempotent
        """
        self.header.free()
        if self.struct_ptr:
            _hts_close(self.struct_ptr)
            self.struct_ptr = None
            self.struct = None
        for it in self.iterators:
            it.close()
        self.iterators = []

    def __iter__(self):
        self.iterators.append(BAMFileIter(self))
        return self.iterators[-1]

    def __enter__(self):
        self.open()
        return self

    def __exit__(self, exc_type, exc_value, traceback):
        self.close()

class BAMIndex:
    """Random-access access to BAM file"""

    @staticmethod
    def build(path, bai_path=None):
        assert False, 'Implement me!'

    @staticmethod
    def _get_index_ext(path):
        if path.endswith('.sam.gz'):
            return '.tbi'
        elif path.endswith('.bam'):
            return '.bai'
        else:
            tpl = 'Not a valid alignment file extension: {}'
            raise BAMIndexException(tpl.format(path))

    def __init__(self, path, bai_path=None, require_index=True,
                 auto_load=True, auto_build=False):
        #: path to BAM file
        self.path = path
        #: path to BAI (BAM index) file
        self.bai_path = bai_path or path + BAMIndex._get_index_ext(path)
        #: whether or not an index is required on construction
        self.require_index = require_index
        #: whether or not to automatically load the index
        self.auto_load = auto_load
        #: whether or not to automatically build the index
        self.auto_build = auto_build
        #: whether or not is BAM/CRAM (alternative is SAM+tabix)
        self.is_bam_or_cram = not self.path.endswith('.sam.gz')

        #: the ``BAMFile`` to use for reading
        self.bam_file = BAMFile(self.path)
        self.bam_file.open()

        # collection of iterators, we will call close() on all of them
        # in our own close to ensure that all memory is freed
        self.iterators = []

        #: wrapped C struct
        self.struct = None
        #: pointer to C struct
        self.struct_ptr = None

        self._check_auto_build()
        self._check_auto_load()
        self._check_require_index()

    def _check_file_ages(self):
        mtime_file = os.path.getmtime(self.path)
        mtime_index = os.path.getmtime(self.bai_path)
        if mtime_file > mtime_index:
            tpl = 'The file {} is older than the index file {}'
            raise BAMIndexException(tpl.format(self.path, self.bai_path))

    def _check_auto_build(self):
        if not self.auto_build:
            return
        logging.debug('auto-building index for {}'.format(self.path))
        if not os.path.exists(self.bai_path):
            BAMIndex.build(self.path, bai_path=self.bai_path)

    def _check_auto_load(self):
        if not self.auto_load:
            return
        if os.path.exists(self.bai_path):
            # check that the index is not older than the file, this is a
            # common source of errors
            self._check_file_ages()
            # load index
            self.load()
        else:
            tpl = 'Index {} required for {} for loading but not found.'
            raise BAMIndexException(tpl.format(self.bai_path, self.path))

    def _check_require_index(self):
        if not self.require_index:
            return
        if not os.path.exists(self.bai_path):
            tpl = 'BAM index required for {} but not found.'
            raise BAMIndexException(tpl.format(self.path))

    # TODO(holtgrewe): fix exception display if not region_string
    def query(self, region_str=None, seq=None, begin=None, end=None):
        if (region_str is None and
                (seq is None or begin is None or end is None)):
            raise BAMIndexException(
                'You have to either give region_str or seq/begin/end')
        if not self.is_bam_or_cram:
            if region_str:
                ptr = _tbx_itr_querys(self.struct_ptr,
                                      region_str.encode('utf-8'))
            else:
                ptr = _tbx_itr_queryi(self.struct_ptr, seq, begin, end)
        else:
            if region_str:
                ptr = _sam_itr_querys(self.struct_ptr,
                                      self.bam_file.header.struct_ptr,
                                      region_str.encode('utf-8'))
            else:
                ptr = _sam_itr_queryi(self.struct_ptr, seq, begin, end)
        if not ptr:
            tpl = 'Could not jump to {}'
            raise BAMIndexException(tpl.format(region_str))
        return BAMIndexIter(self, ptr)

    def load(self):
        self.close(close_file=False)
        if not self.is_bam_or_cram and self.bai_path:
            self.struct_ptr = _tbx_index_load2(self.path.encode('utf-8'),
                                               self.bai_path.encode('utf-8'))
            if not self.struct_ptr:
                tpl = 'Could not load tabix index {} for {}'
                raise BAMIndexException(tpl.format(self.bai_path, self.path))
        elif not self.is_bam_or_cram and not self.bai_path:
            self.struct_ptr = _tbx_index_load(self.path.encode('utf-8'))
            if not self.struct_ptr:
                tpl = 'Could not load tabix index for {}'
                raise BAMIndexException(tpl.format(self.path))
        elif self.bai_path:
            self.struct_ptr = _sam_index_load2(self.bam_file.struct_ptr,
                                               self.path.encode('utf-8'),
                                               self.bai_path.encode('utf-8'))
            if not self.struct_ptr:
                tpl = 'Could not load BAM/CRAM index {} for {}'
                raise BAMIndexException(tpl.format(self.bai_path, self.path))
        else:
            self.struct_ptr = _sam_index_load(self.bam_file.struct_ptr,
                                              self.path.encode('utf-8'))
            if not self.struct_ptr:
                tpl = 'Could not load BAM/CRAM index for {}'
                raise BAMIndexException(tpl.format(self.path))
        self.struct = self.struct_ptr[0]

    def close(self, close_file=True):
        if self.struct_ptr:
            if self.path.endswith('.sam.gz'):
                _tbx_destroy(self.struct_ptr)
            else:
                _hts_idx_destroy(self.struct_ptr)
            self.struct = None
            self.struct_ptr = None
        if close_file:
            self.bam_file.close()
        for it in self.iterators:
            it.close()
        self.iterators = []

    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_value, traceback):
        self.close(close_file=True)


# -*- coding: utf-8 -*-
import math
import random
import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
from sopt.SGA import SGA

from utils.MyCount import C

def Compare(a,b):
    length = len(a)
    Mysum = 0
    for i in range(length):
        temp= (a[i]-b[i])*(a[i]-b[i])
        Mysum += temp
    com = math.sqrt(Mysum)
    return com

def algorithm_function(beta):
    anomaly = []
    normal = []
    Beta = beta[0]
    for i in dataset:
        temp = []
        for item in centroids:
            temp.append(Compare(i,item))
        if 10*min(temp) > Beta:
            anomaly.append(i)
        if 10*min(temp) < Beta:
            normal.append(i)

    score = len(normal)/(len(normal)+len(anomaly))
    print(score)
    Main_anomaly = anomaly
    Main_normal = normal
    mycount.vaildCount(anomaly,normal)
    if 0 < score <= 0.96:
        return score
    elif score > 0.97:
        return 0.9
    else:
        return 0.1

if __name__ == "__main__":
    mycount = C()
    # dataset = np.random.rand(500, 2)  # 随机生成500个二维[0,1)平面点
    X_outliers = np.random.uniform(low=-4, high=4, size=(20, 2))
    X = 0.3 * np.random.randn(100, 2)

    Y = 0.5 * np.random.randn(100, 2)

    # Z = 0.8 * np.random.randn(100, 2)
    # Y = np.append(X-2,Y,axis=0)
    # Y = np.append(X+1.2,Z-2.5,axis=0)
    X_train = np.r_[X + 2.3, Y -1]

    dataset = np.append(X_train,X_outliers,axis=0)

    for i in dataset:
        plt.scatter(i[0],i[1], c='g')
    plt.xlim(xmax=5,xmin=-5)
    plt.ylim(ymax=5,ymin=-5)
    plt.show()

    # estimator = KMeans(n_clusters=3)#构造聚类器
    # estimator.fit(dataset)#聚类
    # label_pred = estimator.labels_ #获取聚类标签
    # centroids = estimator.cluster_centers_ #获取聚类中心
    # import matplotlib.pyplot as plt
    # plt.figure(figsize=(8,10))
    # colors = ['b', 'g','r']
    # markers = ['o', 's','d']
    # for i,l in enumerate(label_pred):
    #     plt.plot(dataset[i][0],dataset[i][1],color=colors[l],marker=markers[l],ls='None')
    # print(centroids)
    # plt.plot(centroids[0][0],centroids[0][1],color = 'r',marker = 'o',ls='None')
    # plt.plot(centroids[1][0],centroids[1][1],color = 'r',marker = 'o',ls='None')
    # plt.show()

    # import matplotlib.pyplot as plt
    # from scipy.spatial.distance import cdist
    # K=range(1,10)
    # meandistortions=[]
    # for k in K:
    #     kmeans=KMeans(n_clusters=k)
    #     kmeans.fit(dataset)
    #     meandistortions.append(sum(np.min(cdist(
    #         X,kmeans.cluster_centers_,"euclidean"),axis=1))/X.shape[0])
    # K_list = {}
    # print(meandistortions)
    # for i in range(0,len(meandistortions)):
    #     K_list[i] = meandistortions[i-1]- meandistortions[i]
    #
    # K_list = sorted(K_list.items(), key=lambda item:item[1], reverse=True)
    # a = K_list[0]
    # plt.plot(K,meandistortions,'bx-')
    # plt.xlabel('k')
    # plt.ylabel(u'平均畸变程度')
    # plt.title('best k is '+ str(a[0]+1))
    # plt.show()

    #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    Main_anomaly = []
    Main_normal = []
    sga = SGA.SGA(func = algorithm_function,func_type = 'max',variables_num = 2,
                  lower_bound = [1,2],upper_bound = [10,5],generations = 2,
                  binary_code_length = 10)
    sga.run()
    algorithm_function(sga.global_best_point)

    # normal_df, outlier_df = mycount.getInfo()
    Main_anomaly = mycount.final_anomalys_DF
    Main_normal = mycount.final_nomalys_DF
    # print('anomaly',Main_anomaly)
    # print('normal', Main_normal)

    import matplotlib.pyplot as plt
    plt.figure()
    for i in Main_anomaly:
        print(i)
        plt.scatter(i[0],i[1],c='r')
    for i in Main_normal:
        plt.scatter(i[0],i[1],c='g')
    plt.show()


from collections import deque

n = int(input())

def dfs(n):
    queue = deque(range(1, 10))
    if n < 10:
        return n
    count = 9
    while count < n:
        num = queue.popleft()
        last_digit = num % 10
        for i in range(last_digit):
            new_num = num * 10 + i
            queue.append(new_num)
            count += 1
            if count == n:
                return new_num
    return -1

if n >= 1023:
    print(-1)
else:
    print(dfs(n))


import argparse

def read(filename, columns, header=0):
    result = {}
    with open(filename, 'r') as f:
        line = None
        for i in range(0, header):
            line = f.readline().strip()
        if not columns:
            line = f.readline().strip()
            fields = line.strip().split("\t")
            r = []
            for i in range(1, len(columns)):
                r.append(fields[int(columns[i])])
            result[columns[0]] = r
            while line:
                fields = line.split("\t")
                r = []
                for i in range(1, len(columns)):
                    r.append(fields[int(columns[i])])
                result[columns[0]] = r
                line = f.readline().strip()
        else:
            line = f.readline().strip()
            fields = line.split("\t")
            while line:
                fields = line.split("\t")
                result[fields[0]] = fields[1:]
                line = f.readline().strip()
        return result

def join(source_file_1, source_file_2, header, columns, output_file, default=["NA"]):
    cols = columns.split('/')
    if "*" == cols[0]:
        data = read(source_file_1, None, int(header))
    else:
        data = read(source_file_1, cols[0].split(","), int(header))

    if "*" == cols[1]:
        data2 = read(source_file_2, columns, int(header))
    else:
        data2 = read(source_file_2, cols[0].split(","), int(header))

    with open(output_file, 'w') as fout:
        for key in data.keys():
            if key in data2.keys():
                fout.write(key + "\t" + "\t".join(data[key])+ "\t" + "\t".join(data2[key]) + "\n")
            else:
                fout.write(key + "\t" + "\t".join(data[key]) + "\t" + "\t".join(default) + "\n")

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description="Intersect 2 files based on gene name. ")
    parser.add_argument('--source_file_1', help="A source file delimited by tab ", action='store', dest='source_file_1')
    parser.add_argument('--source_file_2', help="a second source file", action='store', dest='source_file_2')
    parser.add_argument('--header', help="number of lines", action='store', dest='header')
    parser.add_argument('--columns', help="a needed columns", action='store', dest='columns')
    parser.add_argument('--output_file', help='The output file', action='store', dest='output_file')

    args = parser.parse_args()

    join(args.source_file_1, args.source_file_2, args.header, args.columns, args.output_file)


import sys
def solution(A):
    # write your code in Python 2.7
    minval=sys.maxint
    maxsumending=maxsum=-sys.maxint
    for a in A[1:-1]:
        if a<minval:
            minval=a
        if maxsumending+a-minval<0:
            maxsumending = 0
            minval=0
        else:
            maxsumending=maxsumending+a
        maxsum=max(maxsumending-minval,maxsum)
    return maxsum


"""
Choose two large primes 𝑝 and 𝑞.
Let 𝑛=𝑝⋅𝑞.
Choose 𝑒 such that 𝑔𝑐𝑑(𝑒,𝜑(𝑛))=1 (where 𝜑(𝑛)=(𝑝−1)⋅(𝑞−1)).
Find 𝑑 such that 𝑒⋅𝑑≡1mod𝜑(𝑛).
In other words, 𝑑 is the modular inverse of 𝑒, (𝑑≡𝑒−1mod𝜑(𝑛)).
"""
from Crypto.Util.number import getPrime
from Crypto.Random.random import randrange
from Crypto.Hash import SHA256
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
import codecs
class textbook_rsa():
    key_log = {}
    def key_gen(self, length):
        e = 65537
        sub = 5
        if length < sub:
            sub = -5
        p = getPrime(length)
        q = getPrime(length-sub)

        n = p * q
        alpha_n = (p-1) * (q-1)
        d = pow(e,-1,alpha_n)
        self.key_log[(e,n)] = (d,n)
        return (e,n)

    """
    RSA En/decryption
    • to encrypt a message M the sender:
    • obtains public key of recipient PU={e,n}
    • computes: C = M**e mod n, where 0≤M<n
    """
    def encrypt(self, M, pk):
        e = pk[0]
        n = pk[1]
        C = pow(M,e,n)
        return C
    """
    • to decrypt the ciphertext C the owner:
    • uses their private key PR={d,n}
    • computes: M = C**d mod n
    • note that the message
    """
    def decrypt(self, C, pk):
        pr_k = None
        try:
            pr_k = self.key_log[pk]
        except:
            pr_k = None

        if pr_k == None:
            print("Could not decrypt C")
            return None
        else:
            d = pk[0]
            n = pk[1]
            M = pow(C,d,n)
        return M

def test_rsa():
    t_rsa = textbook_rsa()
    my_pk = t_rsa.key_gen(256)
    m = 721011081081113211610410511532105115329732116101115116 #Hello this is a test
    print("Message:", m)
    c = t_rsa.encrypt(m, my_pk)
    c_d = t_rsa.decrypt(c, my_pk)
    if m == c_d:
        print("Decrypted:", c_d)
    else:
        print("RSA NOT WORKING")

#c’ = F(c)
def F(c,e,n):
    return pow(2,e,n)

def malleability_test():
    t_rsa = textbook_rsa()
    alice_pk = t_rsa.key_gen(16)
    #Alice sends (e,n) public key
    e = alice_pk[0]
    n = alice_pk[1]

    #Bob computes
    bob_s = randrange(n)
    c = pow(bob_s,e,n)#Bob sends c

    #Mallory c' = F(c)
    c_prime = F(c,e,n)

    #Alice
    d = t_rsa.key_log[alice_pk][0]
    a_s = pow(c_prime,d,n)

    k = SHA256.new()
    k.update(bytes(a_s))
    a_iv = k.digest()[16:32]
    a_message = "Hi Bob!".encode()
    a_aes = AES.new(k.digest()[:16],AES.MODE_CBC,IV=a_iv)
    c0 = a_aes.encrypt(pad(a_message, AES.block_size))
    #Alice sends c0

    #Mallory
    m_s = 2
    k_m = SHA256.new()
    k_m.update(bytes(m_s))
    m_iv = k_m.digest()[16:32]
    m_aes = AES.new(k_m.digest()[:16],AES.MODE_CBC,IV=m_iv)
    mess = unpad(m_aes.decrypt(c0), block_size=AES.block_size)
    print("Mallory got:",mess)

malleability_test()


import numpy as _np
from collections import defaultdict as _dfdict
import nxmultilayer as nxm

def multilayer_DCSBM_network(partition, mu=0.1, k_min=5, k_max=70, t_k=-2, degrees=None):
    """
    Generate multilayer benchmark networks with planted community structure using a DCSBM model. The mixing parameter
    `mu` determines the strength of the planted community structure. For `mu=0`, all edges are constrained to fall
    within communities. For `mu>0`, a fraction `mu` of edges is sampled independently of the planted communities.
    For `mu=1`, all edges are independent of the planted communities and the generated network has no community structure.

    The expected degrees are sampled from a truncated powerlaw distribution.

    The sampled multilayer network is returned as a MultilayerGraph which adds some functionality on top of a NetworkX
    Graph (see https://github.com/LJeub/nxMultilayerNet )

    :param partition: Partition to plant
    :param mu: Fraction of random edges (default: 0.1)
    :param k_min: Minimum cutoff for distribution of expected degrees
    :param k_max: Maximum cutoff for distribution of expected degrees
    :param t_k: Exponent for distribution of expected degrees
    :param degrees: (Optional) specify degree sequence as mapping of state-node -> degree (if specified, `k_min`,
                    `k_max`, and `t_k` have no effect and the specified degrees are used instead)

    :return: generated multilayer network
    """
    layer_partitions = _dfdict(dict)
    neighbors = _dfdict(set)
    if isinstance(partition, _np.ndarray):
        for node, p in _np.ndenumerate(partition):
            layer_partitions[tuple(node[1:])][tuple(node)] = p
    else:
        for node, p in partition.items():
            layer_partitions[tuple(node[1:])][tuple(node)] = p

    fixed_degrees = degrees

    for p in layer_partitions.values():
        n_nodes = len(p)
        nodes_l = list(p.keys())
        if fixed_degrees is None:
            degrees = power_law_sample(n_nodes, t=t_k, x_max=k_max, x_min=k_min)
        else:
            degrees = _np.array([fixed_degrees[node] for node in nodes_l])
        # random edges
        no_partition = _np.zeros(n_nodes, dtype=int)
        block_matrix = build_block_matrix(no_partition, degrees * mu)
        neighbors = block_model_sampler(block_matrix=block_matrix, partition=no_partition, degrees=degrees * mu,
                                        neighbors=neighbors, nodes=nodes_l)
        # community edges
        p_l = _np.fromiter(p.values(), dtype=int)
        block_matrix = build_block_matrix(p_l, degrees * (1 - mu))
        neighbors = block_model_sampler(block_matrix=block_matrix, partition=p_l, degrees=degrees * (1 - mu),
                                        neighbors=neighbors, nodes=nodes_l)
    multinet = nxm.MultilayerGraph(n_aspects=len(nodes_l[0])-1)
    if isinstance(partition, _np.ndarray):
        for node, p in _np.ndenumerate(partition):
            multinet.add_node(node, mesoset=p)
    else:
        for node, p in partition.items():
            multinet.add_node(node, mesoset=p)

    for node1, adj in neighbors.items():
        for node2 in adj:
            multinet.add_edge(node1, node2)

    return multinet

class IdentityMap:
    def __getitem__(self, item):
        return item

def block_model_sampler(block_matrix, partition, degrees, neighbors=None, nodes=IdentityMap()):
    max_reject = 100
    partition = _np.array(partition)
    degrees = _np.array(degrees)
    n_nodes = len(partition)
    if n_nodes != len(degrees):
        raise ValueError('length mismatch between partition and node degrees')

    n_groups = max(partition)+1

    # look up map for group memberships
    partition_map = [[] for _ in range(n_groups)]
    for i, g in enumerate(partition):
        partition_map[g].append(i)

    group_sizes = [len(g) for g in partition_map]

    sigma = [degrees[g] / sum(degrees[g]) for g in partition_map]

    if neighbors is None:
        neighbors = _dfdict(set)

    for g1 in range(n_groups):
        for g2 in range(g1,n_groups):
            w = block_matrix[g1,g2]
            if w > 0:
                m = _np.random.poisson(w)
                if g1 == g2:
                    dense = 2*m > group_sizes[g1]*(group_sizes[g1]-1)
                    m = int(_np.ceil(m / 2))
                else:
                    dense = 2*m > group_sizes[g1]*group_sizes[g2]

                if dense:
                    probabilities = w * _np.outer(sigma[g1], sigma[g2])
                    probabilities[probabilities > 1] = 1
                    if g1 == g2:
                        for i in range(group_sizes[g1]):
                            ni = _np.extract(probabilities[i, i + 1:] > _np.random.rand(1, group_sizes[g1] - i - 1),
                                             _np.arange(i + 1, group_sizes[g1]))
                            for j in ni:
                                neighbors[nodes[partition_map[g1][i]]].add(nodes[partition_map[g2][j]])
                                neighbors[nodes[partition_map[g2][j]]].add(nodes[partition_map[g1][i]])
                    else:
                        for i in range(group_sizes[g1]):
                            ni = _np.flatnonzero(probabilities[i, :] > _np.random.rand([1, group_sizes[g2]]))
                            for j in ni:
                                neighbors[nodes[partition_map[g1][i]]].add(nodes[partition_map[g2][j]])
                                neighbors[nodes[partition_map[g2][j]]].add(nodes[partition_map[g1][i]])

                else:
                    for e in range(m):
                        is_neighbor = True
                        reject_count = 0
                        while is_neighbor and reject_count <= max_reject:
                            node1 = nodes[_np.random.choice(partition_map[g1], 1, p=sigma[g1])[0]]
                            node2 = nodes[_np.random.choice(partition_map[g2], 1, p=sigma[g2])[0]]
                            is_neighbor = node1 in neighbors[node2] or node1 == node2
                            reject_count += 1
                        if reject_count > max_reject:
                            print('rejection threshold reached')
                            break
                        neighbors[node1].add(node2)
                        neighbors[node2].add(node1)

    return neighbors

def build_block_matrix(partition, degrees):
    nc = max(partition) + 1
    block_matrix = _np.zeros([nc, nc])
    for i, g in enumerate(partition):
        block_matrix[g, g] += degrees[i]
    return block_matrix

def power_law_sample(n, t, x_min, x_max):
    y = _np.random.rand(n)
    if t != -1:
        return ((x_max**(t+1) - x_min**(t+1)) * y + x_min**(t+1))**(1/(t+1))
    else:
        return x_min*(x_max/x_min)**y


class Rectangulo:
    def __init__(self,largo,ancho):
        self.largo=largo
        self.ancho=ancho

    def area(self):
        area=self.largo*self.ancho
        return area

r1=Rectangulo(10,5)
area=r1.area()
print(f"El area del rectangulo es {area}")


#-*-coding:utf-8-*-
import numpy as np
import os
import pickle

import torch
from anakin.utils.logger import logger
from anakin.utils.etqdm import etqdm
from collections import defaultdict

class HO3DData:
    def __init__(self, **cfg):
        # ======== HO3D default >>>>>>>>>>>>>>>>>
        self.raw_size = (640, 480)
        self.reorder_idxs = np.array([0, 13, 14, 15, 16, 1, 2, 3, 17, 4, 5, 6, 18, 10, 11, 12, 19, 7, 8, 9, 20])
        # this camera extrinsic has no translation
        # and this is the reason transforms in following code just use rotation part
        self.cam_extr = np.array([
            [1, 0, 0, 0],
            [0, -1, 0, 0],
            [0, 0, -1, 0],
            [0, 0, 0, 1],
        ]).astype(np.float32)
        self.name = "HO3D"
        self.data_split = cfg["DATA_SPLIT"]
        self.data_root = cfg["DATA_ROOT"]
        self.root = os.path.join(self.data_root, self.name)

        # <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
        self.load_dataset()

    def load_dataset(self):
        if self.split_mode == "paper":
            seq_frames, subfolder = self._load_seq_frames()
            logger.info(f"{self.name} {self.data_split} set has frames {len(seq_frames)}")
        else:
            raise NotImplementedError()
        annot_mapping, seq_idx = self._load_annots(seq_frames=seq_frames,
                                                   subfolder=subfolder)

        annotations = {"seq_idx": seq_idx, "annot_mapping": annot_mapping}
        self.seq_idx = annotations["seq_idx"]
        self.annot_mapping = annotations["annot_mapping"]
        self.sample_idxs = list(range(len(self.seq_idx)))

    def _load_seq_frames(self, subfolder=None, seqs=None, trainval_idx=6000):
        if self.split_mode == "paper":
            if self.data_split in ["train", "trainval", "val"]:
                info_path = os.path.join(self.root, "train.txt")
                subfolder = "train"
            elif self.data_split == "test":
                info_path = os.path.join(self.root, "evaluation.txt")
                subfolder = "evaluation"
            else:
                assert False
            with open(info_path, "r") as f:
                lines = f.readlines()
            seq_frames = [line.strip().split("/") for line in lines]
        else:
            assert False
        return seq_frames, subfolder

    def _load_annots(self, seq_frames=None, subfolder="train"):
        if seq_frames is None:
            seq_frames = []
        seq_idx = []
        annot_mapping = defaultdict(list)
        seq_counts = defaultdict(int)
        annot_save = dict()
        for idx_count, (seq, frame_idx) in enumerate(etqdm(seq_frames)):
            seq_folder = os.path.join(self.root, subfolder, seq)
            meta_folder = os.path.join(seq_folder, "meta")
            rgb_folder = os.path.join(seq_folder, "rgb")

            meta_path = os.path.join(meta_folder, f"{frame_idx}.pkl")

            with open(meta_path, "rb") as p_f:
                annot_load = pickle.load(p_f)
            if annot_load["handJoints3D"].size == 3:
                annot_save["camMat"] = annot_load["camMat"]
                #annot_save["handBoundingBox"] = annot_load["handBoundingBox"]
                annot_save["handTrans"] = annot_load["handJoints3D"]
                annot_save["handJoints3D"] = annot_load["handJoints3D"][np.newaxis, :].repeat(21, 0)
                annot_save["handPose"] = np.zeros(48, dtype=np.float32)
                annot_save["handBeta"] = np.zeros(10, dtype=np.float32)

            img_path = os.path.join(rgb_folder, f"{frame_idx}.png")
            annot_save["img"] = img_path
            annot_save["frame_idx"] = frame_idx

            annot_mapping[seq].append(annot_save)
            seq_idx.append((seq, seq_counts[seq]))
            seq_counts[seq] += 1

        return annot_mapping, seq_idx


def solution(x):
    answer = False
    sum = 0
    n = x
    while n > 0:
        sum += n % 10
        n = n//10
    if (x / sum).is_integer():
        return True
    return answer

print(solution(10))


from Prac_06.guitar import Guitar

my_guitar = []
str1 = ""
name = str(input("Name: "))
year = int(input("Year: "))
cost = float(input("Cost: "))

while name != "":
    print("{} ({}) : ${:,} added.".format(name, year, cost))
    str1 = str1 + name + "," + str(year) + "," + str(cost)
    my_guitar.append(str1)
    name = str(input("Name: "))
    if name == "":
        break;
    year = int(input("Year: "))
    cost = float(input("Cost: "))

for i in range(len(my_guitar)):
    guitar = my_guitar[i].split(",")
    guitar = Guitar(guitar[0], int(guitar[1]), guitar[2])
    print("Guitar {}: {:>10} ({}), worth ${:>15}".format(i+1, guitar.get_name(), guitar.get_year(), guitar.get_cost()), end="")
    guitar.get_age()
    if guitar.is_vintage() == True:
        print("(Vintage)", end="\n")
    else:
        print("", end="\n")


#!/usr/bin/env python3

#SmartMob
#Infrared Avoidance Sensor Module with Enable

import RPi.GPIO as GPIO

SignalPin = 16 # change to the pin you want to use
EnablePin = 18 # change to the pin you want to use

def setup():
    GPIO.setmode(GPIO.BOARD) # set GPIO by pin numbers
    GPIO.setup(SignalPin, GPIO.IN, pull_up_down=GPIO.PUD_UP)
    GPIO.setup(EnablePin, GPIO.OUT)
    GPIO.output(EnablePin, 0)

def detect(): # returns 1 if obstacle is detected
    try:
        edge = GPIO.wait_for_edge(SignalPin, GPIO.FALLING) # you can add a time limit as a
        if edge is None:                                     # third argument in ms
            print("Time out ocurred")
            return 0
        else:
            print("Obstacle found")
            return 1

    except KeyboardInterrupt:
        terminate()
        return 0

def enable():
    GPIO.output(EnablePin, 1)

def disable():
    GPIO.output(EnablePin, 0)

def terminate():
    GPIO.cleanup() # releases resources


from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework import status

from api.models import TodoApp
from api.serializers import TodoAppSerializers

class TodoApi(APIView):

    def get(self, request, format=None):
        candidate = TodoApp.objects.all()
        serializer = TodoAppSerializers(candidate, many=True)
        return Response({'status':'success','todoitems':serializer.data}, status=status.HTTP_200_OK)

    def post(self, request, format=None):
        serializer = TodoAppSerializers(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response({'msg':'uploaded','status':'success','candidate':serializer.data}, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    def delete(self, request, pk=None, format=None):
        id = pk
        print(type(id))
        item = TodoApp.objects.get(pk=id)
        item.delete()
        return Response({'msg':'uploaded','status':'success'}, status=status.HTTP_201_CREATED)


from oslo_config import cfg
from oslo_log import log
from oslo_utils import excutils
from oslo_utils import strutils
import tenacity

from ironic.common import cinder
from ironic.common import exception
from ironic.common.i18n import _
from ironic.common import states
from ironic.drivers import base
from ironic.drivers import utils
from ironic import objects

CONF = cfg.CONF

LOG = log.getLogger(__name__)

# NOTE(TheJulia): Sets containing known valid types that align with
# _generate_connector() and the volume connection information spec.
VALID_ISCSI_TYPES = ('iqn',)
# TODO(TheJulia): FCoE?
VALID_FC_TYPES = ('wwpn', 'wwnn')

class CinderStorage(base.StorageInterface):
    """A storage_interface driver supporting Cinder."""

    def get_properties(self):
        """Return the properties of the interface.

        :returns: dictionary of <property name>:<property description> entries.
        """
        return {}

    def _fail_validation(self, task, reason,
                         exception=exception.InvalidParameterValue):
        msg = (_("Failed to validate cinder storage interface for node "
                 "%(node)s. %(reason)s") %
               {'node': task.node.uuid, 'reason': reason})
        LOG.error(msg)
        raise exception(msg)

    def _validate_connectors(self, task):
        """Validate connector information helper.

        Enumerates through all connector objects, and identifies if
        iSCSI or Fibre Channel connectors are present.

        :param task: The task object.
        :raises InvalidParameterValue: If iSCSI is identified and
                                       iPXE is disabled.
        :raises StorageError: If the number of wwpns is not equal to
                              the number of wwnns
        :returns: Dictionary containing iscsi_found and fc_found
                  keys with boolean values representing if the
                  helper found that connector type configured
                  for the node.
        """

        node = task.node
        iscsi_uuids_found = []
        wwpn_found = 0
        wwnn_found = 0
        ipxe_enabled = False
        if 'ipxe_boot' in task.driver.boot.capabilities:
            ipxe_enabled = True

        for connector in task.volume_connectors:
            if (connector.type in VALID_ISCSI_TYPES
                    and connector.connector_id is not None):
                iscsi_uuids_found.append(connector.uuid)
                if not ipxe_enabled:
                    msg = _("The [pxe]/ipxe_enabled option must "
                            "be set to True or the boot interface "
                            "must be set to ``ipxe`` to support network "
                            "booting to an iSCSI volume.")
                    self._fail_validation(task, msg)

            if (connector.type in VALID_FC_TYPES
                    and connector.connector_id is not None):
                # NOTE(TheJulia): Unlike iSCSI with cinder, we have no need
                # to warn about multiple IQN entries, since we are able to
                # submit multiple fibre channel WWPN entries.
                if connector.type == 'wwpn':
                    wwpn_found += 1
                if connector.type == 'wwnn':
                    wwnn_found += 1
        if len(iscsi_uuids_found) > 1:
            LOG.warning("Multiple possible iSCSI connectors, "
                        "%(iscsi_uuids_found)s found, for node %(node)s. "
                        "Only the first iSCSI connector, %(iscsi_uuid)s, "
                        "will be utilized.",
                        {'node': node.uuid,
                         'iscsi_uuids_found': iscsi_uuids_found,
                         'iscsi_uuid': iscsi_uuids_found[0]})
        if wwpn_found != wwnn_found:
            msg = _("Cinder requires both wwnn and wwpn entries for FCoE "
                    "connections. There must be a wwpn entry for every wwnn "
                    "entry. There are %(wwpn)d wwpn entries and %(wwnn)s wwnn "
                    "entries.") % {'wwpn': wwpn_found, 'wwnn': wwnn_found}
            self._fail_validation(task, msg, exception.StorageError)
        return {'fc_found': wwpn_found >= 1,
                'iscsi_found': len(iscsi_uuids_found) >= 1}

    def _validate_targets(self, task, found_types, iscsi_boot, fc_boot):
        """Validate target information helper.

        Enumerates through all target objects and identifies if
        iSCSI or Fibre Channel targets are present, and matches the
        connector capability of the node.

        :param task: The task object.
        :param found_types: Dictionary containing boolean values returned
                            from the _validate_connectors helper method.
        :param iscsi_boot: Boolean value indicating if iSCSI boot operations
                           are available.
        :param fc_boot: Boolean value indicating if Fibre Channel boot
                        operations are available.
        :raises: InvalidParameterValue
        """

        for volume in task.volume_targets:
            if volume.volume_id is None:
                msg = (_("volume_id missing from target %(id)s.") %
                       {'id': volume.uuid})
                self._fail_validation(task, msg)

            # NOTE(TheJulia): We should likely consider incorporation
            # of the volume boot_index field, however it may not be
            # relevant to the checks we perform here as in the end a
            # FC volume "attached" to a node is a valid configuration
            # as well.
            # TODO(TheJulia): When we create support in nova to record
            # that a volume attachment is going to take place, we will
            # likely need to match the driver_volume_type field to
            # our generic volume_type field. NB The LVM driver appears
            # to not use that convention in cinder, as it is freeform.
            if volume.volume_type == 'fibre_channel':
                if not fc_boot and volume.boot_index == 0:
                    msg = (_("Volume target %(id)s is configured for "
                             "'fibre_channel', however the capability "
                             "'fibre_channel_boot' is not set on node.") %
                           {'id': volume.uuid})
                    self._fail_validation(task, msg)
                if not found_types['fc_found']:
                    msg = (_("Volume target %(id)s is configured for "
                             "'fibre_channel', however no Fibre Channel "
                             "WWPNs are configured for the node volume "
                             "connectors.") %
                           {'id': volume.uuid})
                    self._fail_validation(task, msg)

            elif volume.volume_type == 'iscsi':
                if not iscsi_boot and volume.boot_index == 0:
                    msg = (_("Volume target %(id)s is configured for "
                             "'iscsi', however the capability 'iscsi_boot' "
                             "is not set for the node.") %
                           {'id': volume.uuid})
                    self._fail_validation(task, msg)
                if not found_types['iscsi_found']:
                    msg = (_("Volume target %(id)s is configured for "
                             "'iscsi', however no iSCSI connectors are "
                             "configured for the node.") %
                           {'id': volume.uuid})
                    self._fail_validation(task, msg)
            else:
                # NOTE(TheJulia); The note below needs to be updated
                # whenever support for additional volume types are added.
                msg = (_("Volume target %(id)s is of an unknown type "
                         "'%(type)s'. Supported types: 'iscsi' or "
                         "'fibre_channel'") %
                       {'id': volume.uuid, 'type': volume.volume_type})
                self._fail_validation(task, msg)

    def validate(self, task):
        """Validate storage_interface configuration for Cinder usage.

        In order to provide fail fast functionality prior to nodes being
        requested to enter the active state, this method performs basic
        checks of the volume connectors, volume targets, and operator
        defined capabilities. These checks are to help ensure that we
        should have a compatible configuration prior to activating the
        node.

        :param task: The task object.
        :raises: InvalidParameterValue If a misconfiguration or mismatch
                 exists that would prevent storage the cinder storage
                 driver from initializing attachments.
        """

        found_types = self._validate_connectors(task)
        node = task.node
        iscsi_boot = strutils.bool_from_string(
            utils.get_node_capability(node, 'iscsi_boot'))
        fc_boot = strutils.bool_from_string(
            utils.get_node_capability(node, 'fibre_channel_boot'))

        # Validate capability configuration against configured volumes
        # such that we raise errors for missing connectors if the
        # boot capability is defined.
        if iscsi_boot and not found_types['iscsi_found']:
            valid_types = ', '.join(VALID_ISCSI_TYPES)
            msg = (_("In order to enable the 'iscsi_boot' capability for "
                     "the node, an associated volume_connector type "
                     "must be valid for iSCSI (%(options)s).") %
                   {'options': valid_types})
            self._fail_validation(task, msg)

        if fc_boot and not found_types['fc_found']:
            valid_types = ', '.join(VALID_FC_TYPES)
            msg = (_("In order to enable the 'fibre_channel_boot' capability "
                     "for the node, an associated volume_connector type must "
                     "be valid for Fibre Channel (%(options)s).") %
                   {'options': valid_types})
            self._fail_validation(task, msg)

        self._validate_targets(task, found_types, iscsi_boot, fc_boot)

    def attach_volumes(self, task):
        """Informs the storage subsystem to attach all volumes for the node.

        :param task: The task object.
        :raises: StorageError If an underlying exception or failure
                              is detected.
        """
        node = task.node
        targets = [target.volume_id for target in task.volume_targets]

        # If there are no targets, then we have nothing to do.
        if not targets:
            return

        connector = self._generate_connector(task)
        try:
            connected = cinder.attach_volumes(task, targets, connector)
        except exception.StorageError as e:
            with excutils.save_and_reraise_exception():
                LOG.error("Error attaching volumes for node %(node)s: "
                          "%(err)s", {'node': node.uuid, 'err': e})
                self.detach_volumes(task, connector=connector,
                                    aborting_attach=True)

        if len(targets) != len(connected):
            LOG.error("The number of volumes defined for node %(node)s does "
                      "not match the number of attached volumes. Attempting "
                      "detach and abort operation.", {'node': node.uuid})
            self.detach_volumes(task, connector=connector,
                                aborting_attach=True)
            raise exception.StorageError(("Mismatch between the number of "
                                          "configured volume targets for "
                                          "node %(uuid)s and the number of "
                                          "completed attachments.") %
                                         {'uuid': node.uuid})

        for volume in connected:
            # Volumes that were already attached are
            # skipped. Updating target volume properties
            # for these volumes is nova's responsibility.
            if not volume.get('already_attached'):
                volume_uuid = volume['data']['ironic_volume_uuid']
                targets = objects.VolumeTarget.list_by_volume_id(task.context,
                                                                 volume_uuid)

                for target in targets:
                    target.properties = volume['data']
                    target.save()

    def detach_volumes(self, task, connector=None, aborting_attach=False):
        """Informs the storage subsystem to detach all volumes for the node.

        This action is retried in case of failure.

        :param task: The task object.
        :param connector: The dictionary representing a node's connectivity
                          as defined by _generate_connector(). Generated
                          if not passed.
        :param aborting_attach: Boolean representing if this detachment
                                was requested to handle aborting a
                                failed attachment
        :raises: StorageError If an underlying exception or failure
                              is detected.
        """
        # TODO(TheJulia): Ideally we should query the cinder API and reconcile
        # or add any missing volumes and initiate detachments.
        node = task.node
        targets = [target.volume_id for target in task.volume_targets]

        # If there are no targets, then we have nothing to do.
        if not targets:
            return

        if not connector:
            connector = self._generate_connector(task)

        @tenacity.retry(
            retry=tenacity.retry_if_exception_type(exception.StorageError),
            stop=tenacity.stop_after_attempt(CONF.cinder.action_retries + 1),
            wait=tenacity.wait_fixed(CONF.cinder.action_retry_interval),
            reraise=True)
        def detach_volumes():
            try:
                # NOTE(TheJulia): If the node is in ACTIVE state, we can
                # tolerate failures detaching as the node is likely being
                # powered down to cause a detachment event.
                allow_errors = (task.node.provision_state == states.ACTIVE
                                or aborting_attach and outer_args['attempt']
                                > 0)
                cinder.detach_volumes(task, targets, connector,
                                      allow_errors=allow_errors)
            except exception.StorageError as e:
                with excutils.save_and_reraise_exception():
                    # NOTE(TheJulia): In the event that the node is not in
                    # ACTIVE state, we need to fail hard as we need to ensure
                    # all attachments are removed.
                    if aborting_attach:
                        msg_format = ("Error on aborting volume detach for "
                                      "node %(node)s: %(err)s.")
                    else:
                        msg_format = ("Error detaching volume for "
                                      "node %(node)s: %(err)s.")
                    msg = (msg_format) % {'node': node.uuid,
                                          'err': e}
                    if outer_args['attempt'] < CONF.cinder.action_retries:
                        outer_args['attempt'] += 1
                        msg += " Re-attempting detachment."
                        LOG.warning(msg)
                    else:
                        LOG.error(msg)

        # NOTE(mjturek): This dict is used by detach_volumes to determine
        # if this is the last attempt. This is a dict rather than an int
        # so that it is mutable by the inner function. In python3 this is
        # possible with the 'nonlocal' keyword which is unfortunately not
        # available in python2.
        outer_args = {'attempt': 0}
        detach_volumes()

    def should_write_image(self, task):
        """Determines if deploy should perform the image write-out.

        :param task: The task object.
        :returns: True if the deployment write-out process should be
                  executed.
        """
        # NOTE(TheJulia): There is no reason to check if a root volume
        # exists here because if the validation has already been passed
        # then we know that there should be a volume. If there is an
        # image_source, then we should expect to write it out.
        instance_info = task.node.instance_info
        if 'image_source' not in instance_info:
            for volume in task.volume_targets:
                if volume['boot_index'] == 0:
                    return False
        return True

    def _generate_connector(self, task):
        """Generate cinder connector value based upon the node.

        Generates cinder compatible connector information for the purpose of
        attaching volumes. Translation: We need to tell the storage where and
        possibly how we can connect.

        Supports passing iSCSI information in the form of IP and IQN records,
        as well as Fibre Channel information in the form of WWPN addresses.
        Fibre Channel WWNN addresses are also sent, however at present in-tree
        Cinder drivers do not utilize WWNN addresses.

        If multiple connectors exist, the request will be filed with
        MultiPath IO being enabled.

        A warning is logged if an unsupported volume type is encountered.

        :params task: The task object.

        :returns: A dictionary data structure similar to:
                    {'ip': ip,
                     'initiator': iqn,
                     'multipath: True,
                     'wwpns': ['WWN1', 'WWN2']}
        :raises: StorageError upon no valid connector record being identified.
        """
        data = {}
        valid = False
        for connector in task.volume_connectors:
            if 'iqn' in connector.type and 'initiator' not in data:
                data['initiator'] = connector.connector_id
                valid = True
            elif 'ip' in connector.type and 'ip' not in data:
                data['ip'] = connector.connector_id
            # TODO(TheJulia): Translate to, or generate an IQN.
            elif 'wwpn' in connector.type:
                data.setdefault('wwpns', []).append(connector.connector_id)
                valid = True
            elif 'wwnn' in connector.type:
                data.setdefault('wwnns', []).append(connector.connector_id)
                valid = True
            else:
                # TODO(jtaryma): Add handling of type 'mac' with MAC to IP
                #                translation.
                LOG.warning('Node %(node)s has a volume_connector (%(uuid)s) '
                            'defined with an unsupported type: %(type)s.',
                            {'node': task.node.uuid,
                             'uuid': connector.uuid,
                             'type': connector.type})
        if not valid:
            valid_types = ', '.join(VALID_FC_TYPES + VALID_ISCSI_TYPES)
            msg = (_('Insufficient or incompatible volume connection '
                     'records for node %(uuid)s. Valid connector '
                     'types: %(types)s') %
                   {'uuid': task.node.uuid, 'types': valid_types})
            LOG.error(msg)
            raise exception.StorageError(msg)

        # NOTE(TheJulia): Hostname appears to only be used for logging
        # in cinder drivers, however that may not always be true, and
        # may need to change over time.
        data['host'] = task.node.uuid
        if len(task.volume_connectors) > 1 and len(data) > 1:
            data['multipath'] = True

        return data


# https://www.acmicpc.net/problem/15824

import sys

input = sys.stdin.readline
MOD = 1000000007

def power(a: int, b: int) -> int:
    result = 1

    while b:
        if b & 1:
            result = result * a % MOD
        b >>= 1
        a *= a
        a %= MOD

    return result

N = int(input())
arr = sorted(map(int, input().split()))
positive = negative = 0

for i in range(N):
    positive += arr[i] % MOD * power(2, i) % MOD
    negative += arr[i] % MOD * power(2, N - i - 1) % MOD

print((positive - negative) % MOD)

15824_너_봄에는_캡사이신이_맛있단다.py


from pukeko.operators import factory
import pytest

@pytest.mark.skip(reason="Notは廃止された")
def test_format():
    target = {
        "name": "not",
        "operands": [1],
    }

    operator = factory.create(target["name"])
    assert operator.format(target) == r"~%1"


import pyaudio
import wave
import os
import time
import sys
import board
import paho.mqtt.client as mqtt
from datetime import datetime
import json
from array import array

FORMAT=pyaudio.paInt16
CHANNELS=2
RATE=44100
CHUNK=100024
RECORD_SECONDS=15

THINGSBOARD_HOST = 'iot.ceisufro.cl'
ACCESS_TOKEN = '####'

# Data capture and upload interval in seconds. Less interval will eventually hang the DHT22.
INTERVAL=2

sensor_data = {'estado': False,'ruido':0, 'fecha':'date'}

next_reading = time.time()

client = mqtt.Client()

# Set access token
client.username_pw_set(ACCESS_TOKEN)

# Connect to ThingsBoard using default MQTT port and 60 seconds keepalive interval
#client.connect(THINGSBOARD_HOST, 8080, 60)
client.connect(THINGSBOARD_HOST, 1883, 60)

client.loop_start()

audio=pyaudio.PyAudio() #instantiate the pyaudio

        #recording prerequisites
stream=audio.open(format=FORMAT,channels=CHANNELS,
                  rate=RATE,
                  input=True,
                  frames_per_buffer=CHUNK)
frames=[]

SERVER = 'smtp-mail.outlook.com'
FROM = "proyectomonitordci@outlook.com"
TO = ["proyectomonitordci@yopmail.com"]

SUBJECT = "Alerta!"
TEXT = "Se registra un ruido muy fuerte\n Revisar: http://localhost:8081/"

message = """From: %s\r\nTo: %s\r\nSubject: %s\r\n\

%s
""" % (FROM, ", ".join(TO), SUBJECT, TEXT)

# Send the mail
import smtplib
try:
    server = smtplib.SMTP('smtp-mail.outlook.com', 587)
except Exception as e:
    print(e)
    server = smtplib.SMTP_SSL('smtp-mail.outlook.com', 465)
server.ehlo()
server.starttls()
server.login("proyectomonitordci@outlook.com", "PASSWORD")

while True:
    for i in range(0,int(RATE/CHUNK*RECORD_SECONDS)):

        data=stream.read(CHUNK)
        data_chunk=array('h',data)
        vol=max(data_chunk)
        if(vol>=16000):
            estado = True
            ruido=vol
            print("Se registra ruido")
            sensor_data['estado'] = estado
            sensor_data['ruido'] = vol
            fecha = datetime.now()
            fecha = fecha.strftime("%b %d %Y %H:%M:%S")
            sensor_data['fecha'] = fecha
            print(u"Estado: {:g}, Ruido: {:g}, Fecha: ".format(estado,ruido))
            print(fecha)
            print(message)
            server.sendmail(FROM, TO, message)

            frames.append(data)
            client.publish('v1/devices/me/telemetry', json.dumps(sensor_data), 1)
            next_reading += INTERVAL
            sleep_time = next_reading-time.time()
            if sleep_time > 0:

                    time.sleep(sleep_time)
        else:
            estado=False
            print("nothing")
        print("\n")

client.loop_stop()
client.disconnect()


import os
import time
#CLS
def clear_screen():
    os.system('cls' if os.name == 'nt' else 'clear')
#CETAK
def cetak(isi,total):
    clear_screen()
    print("[Belum ada daftar belanja]")
    cetak2(isi,total)
#CETAK1
def cetak1(isi,total):
    clear_screen()
    print("Daftar belanjaan saat ini:")
    for ini in isi:
        print("- "+ini)
    print("--Total harga = Rp",total)
    print("")
    cetak2(isi,total)
#CETAK2
def cetak2(isi,total):
    print("--Toko Percetakan--")
    print("[1] Cetak Spanduk")
    print("[2] Cetak Stiker")
    print("[3] Cetak Brosur")
    print("[4] Cetak Poster")
    print("[5] Cetak Kalender")
    print("[0] Edit daftar")
    print("[#] Enter untuk keluar")
    print("[99] Ambil diskon")
    cetak = str(input("Masukkan pilihan : "))
    if cetak == '0':
        edit_daftar(isi,total)
    elif cetak == '1':
        cetak_spanduk(isi,total)
    elif cetak == '2':
        cetak_stiker(isi,total)
    elif cetak == '3':
        cetak_brosur(isi,total)
    elif cetak == '4':
        cetak_poster(isi,total)
    elif cetak == '5':
        cetak_kalender(isi,total)
    elif cetak == '99':
        ambil_diskon(isi,total)
    else:
        print("\nTerimakasih sudah menggunakan program kami...")
        time.sleep(3)
        exit()
#EDIT_DAFTAR
def edit_daftar(isi,total):
    clear_screen()
    print("Daftar belanjaan saat ini:")
    i = 0
    for ini in isi:
        i += 1
        print(i,ini)
    print("\n--Edit daftar--")
    print("[1] Mengganti daftar belanja")
    print("[2] Menghapus daftar belanja")
    print("[3] Sorting   daftar belanja")
    print("[4] Min & Max daftar belanja")
    print("[5] Menambah  daftar belanja")
    print("[6] Menghapus banyaknya daftar")
    print("[7] Menambah dengan nomor daftar")
    print("[8] Menghitung banyak daftar")
    print("[9] Menghapus semua daftar")
    print("[0] Kembali")
    edit = str(input("Masukkan pilihan edit: "))
    if edit == '0':
        clear_screen()
        cetak1(isi,total)
    elif edit == '1':
        clear_screen()
        print("Daftar belanjaan saat ini:")
        i = 0
        for ini in isi:
            i += 1
            print(i,ini)
        print("\n--Ganti daftar--")
        gnt = int(input("Masukkan nomor daftar: "))
        gant = gnt-1
        print("Daftar yang di ganti :\n{0} {1}".format(gnt,isi[gant]))
        ganti = str(input("Masukkan daftar baru : "))
        isi[gant] = ganti
        print("\nDaftar belanja baru :")
        j = 0
        for ini in isi:
            j += 1
            print(j,ini)
        input("\nTekan Enter untuk kembali...")
        edit_daftar(isi,total)
    elif edit == '2':
        clear_screen()
        print("Daftar belanjaan saat ini:")
        i = 0
        for ini in isi:
            i += 1
            print(i,ini)
        print("\n--Hapus daftar--")
        nmr = int(input("Masukkan nomor list : "))
        nomor = nmr-1
        print("Data yang di hapus :\n{0} {1}".format(nmr,isi[nomor]))
        isi.pop(nomor)
        print("\nDaftar belanja baru :")
        j = 0
        for ini in isi:
            j += 1
            print(j,ini)
        input("\nTekan Enter untuk kembali...")
        edit_daftar(isi,total)
    elif edit == '3':
        clear_screen()
        print("Daftar belanjaan saat ini:")
        i = 0
        for ini in isi:
            i += 1
            print(i,ini)
        print("\n--Sorting daftar--")
        print("[1] Ascending")
        print("[2] Descending")
        sort = str(input("Masukkan pilihan sorting : "))
        if sort == '1':
            isi.sort()
            print("\nDaftar belanja baru :")
            j = 0
            for ini in isi:
                j += 1
                print(j,ini)
            input("\nTekan Enter untuk kembali...")
            edit_daftar(isi,total)
        elif sort == '2':
            isi.sort()
            isi.reverse()
            print("\nDaftar belanja baru :")
            k = 0
            for ini in isi:
                k += 1
                print(k,ini)
            input("\nTekan Enter untuk kembali...")
            edit_daftar(isi,total)
        else:
            print("Input tidak valid!")
            input("\nTekan Enter untuk kembali...")
            edit_daftar(isi,total)
    elif edit == '4':
        clear_screen()
        print("Daftar belanjaan saat ini:")
        i = 0
        for ini in isi:
            i += 1
            print(i,ini)
        print("\n--Min & Max--")
        print("[1] Mencari nilai min")
        print("[2] Mencari nilai max")
        cari = str(input("Masukkan pilihan : "))
        if cari == '1':
            kecil = min(isi)
            print("Nilai min = "+kecil)
            input("\nTekan Enter untuk kembali...")
            edit_daftar(isi,total)
        elif cari == '2':
            besar = max(isi)
            print("Nilai max = "+besar)
            input("\nTekan Enter untuk kembali...")
            edit_daftar(isi,total)
        else:
            print("Input tidak valid!")
            input("\nTekan Enter untuk kembali...")
            edit_daftar(isi,total)
    elif edit == '5':
        clear_screen()
        print("Daftar belanjaan saat ini:")
        i = 0
        for ini in isi:
            i += 1
            print(i,ini)
        print("\n--Menambah daftar--")
        berenti = False
        j = 1
        data_baru = []
        while (not berenti):
            data_baru = str(input("Masukkan daftar ke-{0} ".format(j)))
            isi.extend([data_baru])
            j += 1
            ask = input("Input 0 jika cukup : ")
            if ask == '0':
                berenti = True
        print("\nDaftar belanja baru :")
        k = 0
        for ini in isi:
            k += 1
            print(k,ini)
        input("\nTekan Enter untuk kembali...")
        edit_daftar(isi,total)
    elif edit == '6':
        clear_screen()
        print("Daftar belanjaan saat ini:")
        i = 0
        for ini in isi:
            i += 1
            print(i,ini)
        print("\n--Menghapus banyak daftar--")
        hapus1 = int(input("Menghapus dari daftar  : "))
        hapus = hapus1-1
        hapus2 = int(input("Menghapus hingga daftar: "))
        del isi[hapus:hapus2]
        print("\nDaftar belanja baru :")
        j = 0
        for ini in isi:
            j += 1
            print(j,ini)
        input("\nTekan Enter untuk kembali...")
        edit_daftar(isi,total)
    elif edit == '7':
        clear_screen()
        print("Daftar belanjaan saat ini:")
        i = 0
        for ini in isi:
            i += 1
            print(i,ini)
        print("\n--Menambah dengan nomor daftar--")
        tambah = int(input("Masukkan nomor daftar : "))
        tambah1 = tambah-1
        tambah2 = str(input("Masukkan daftar baru  : "))
        isi.insert(tambah1,tambah2)
        print("\nDaftar belanja baru :")
        j = 0
        for ini in isi:
            j += 1
            print(j,ini)
        input("\nTekan Enter untuk kembali...")
        edit_daftar(isi,total)
    elif edit == '9':
        clear_screen()
        print("Daftar belanjaan saat ini:")
        i = 0
        for ini in isi:
            i += 1
            print(i,ini)
        print("\n--Menghapus semua daftar--")
        print("Konfirmasi:")
        yakin = str(input("Yakin ingin menghapus semua daftar? (y/t) "))
        if yakin == 'y':
            print("Menghapus daftar...")
            time.sleep(2)
            isi.clear()
            total = 0
            print("Daftar berhasil dhapus!")
            input("\nTekan Enter untuk kembali...")
            cetak(isi,total)
        elif yakin == 't':
            print("Menghapus semua daftar dibatalkan.")
            input("\nTekan Enter untuk kembali...")
            edit_daftar(isi,total)
        else:
            print("Input tidak valid!")
            input("\nTekan Enter untuk kembali...")
            edit_daftar(isi,total)
    elif edit == '8':
        clear_screen()
        print("Daftar belanjaan saat ini:")
        i = 0
        for ini in isi:
            i += 1
            print(i,ini)
        print("\n--Menghitung banyak daftar--")
        print("Banyak daftar belanjaan ada : ",len(isi))
        input("\nTekan Enter untuk kembali...")
        edit_daftar(isi,total)
    else:
        print("Input tidak valid!")
        input("\nTekan Enter untuk kembali...")
        edit_daftar(isi,total)
#CETAK_SPANDUK
def cetak_spanduk(isi,total):
    clear_screen()
    print("--Cetak Spanduk--")
    print("Jenis spanduk:")
    print("[1] Spanduk Flexi Cina")
    print("[2] Spanduk Flexi Korea")
    print("[0] Kembali")
    spanduk = str(input("Masukkan jenis spanduk : "))
    if spanduk == '0':
        clear_screen()
        cetak2(isi,total)
    elif spanduk == '1':
        print("\nFlexi Cina 280gsm")
        print("Harga spanduk 20k/meter")
        ukuran = int(input("Panjang spanduk : "))
        print("\nDaftar belanja baru:")
        harga_spanduk = lambda ukuran: ukuran*20000
        spanduk1 = ("Flexi Cina  260gsm ; {0} Meter      ; Harga Rp.{1}".format(ukuran,harga_spanduk(ukuran)))
        isi.append(spanduk1)
        for ini in isi:
            print("- "+ini)
        total = total+harga_spanduk(ukuran)
        print("--Total harga = Rp",total)
        input("\nTekan Enter untuk kembali...")
        cetak1(isi,total)
    elif spanduk == '2':
        print("\nFlexi Korea 440gsm")
        print("Harga spanduk 45k/meter")
        ukuran = int(input("Panjang spanduk : "))
        print("\nDaftar belanja baru:")
        harga_spanduk = lambda ukuran : ukuran*45000
        spanduk2 = ("Flexi Korea 440gsm ; {0} Meter      ; Harga Rp.{1}".format(ukuran,harga_spanduk(ukuran)))
        isi.append(spanduk2)
        for ini in isi:
            print("- "+ini)
        total = total+harga_spanduk(ukuran)
        print("--Total harga = Rp",total)
        input("\nTekan Enter untuk kembali...")
        cetak1(isi,total)
    else:
        print("Input tidak valid!")
        input("\nTekan Enter untuk kembali...")
        cetak_spanduk(isi,total)
#CETAK_STIKER
def cetak_stiker(isi,total):
    clear_screen()
    print("--Cetak Stiker--")
    print("Jenis stiker:")
    print("Ukuran A3+")
    print("[1] Stiker Bontax")
    print("[2] Stiker Vinyl Doff")
    print("[3] Stiker Transparan")
    print("[0] Kembali")
    stiker = str(input("Pilih jenis stiker : "))
    if stiker == '0':
        clear_screen()
        cetak2(isi,total)
    elif stiker == '1':
        print("\nStiker Bontax")
        print("Uk. A3+ 5k/lembar")
        lembar = int(input("Berapa lembar : "))
        print("\nDaftar belanja baru:")
        harga_lembar = lambda lembar: lembar*5000
        stiker1 = ("Stiker Bontax  A3+ ; {0} Lembar     ; Harga Rp.{1}".format(lembar,harga_lembar(lembar)))
        isi.append(stiker1)
        for ini in isi:
            print("- "+ini)
        total = total+harga_lembar(lembar)
        print("--Total harga = Rp",total)
        input("\nTekan Enter untuk kembali...")
        cetak1(isi,total)
    elif stiker == '2':
        print("\nStiker Vinyl Doff")
        print("Uk. A3+ 7k/lembar")
        lembar = int(input("Berapa lembar : "))
        print("\nDaftar belanja baru:")
        harga_lembar = lambda lembar: lembar*7000
        stiker2 = ("Stiker Vinyl   A3+ ; {0} Lembar     ; Harga Rp.{1}".format(lembar,harga_lembar(lembar)))
        isi.append(stiker2)
        for ini in isi:
            print("- "+ini)
        total = total+harga_lembar(lembar)
        print("--Total harga = Rp",total)
        input("\nTekan Enter untuk kembali...")
        cetak1(isi,total)
    elif stiker == '3':
        print("\nStiker Transparan")
        print("Uk. A3+ 10k/lembar")
        lembar = int(input("Berapa lembar : "))
        print("\nDaftar belanja baru:")
        harga_lembar = lambda lembar: lembar*10000
        stiker3 = ("Stiker Transp. A3+ ; {0} Lembar     ; Harga Rp.{1}".format(lembar,harga_lembar(lembar)))
        isi.append(stiker3)
        for ini in isi:
            print("- "+ini)
        total = total+harga_lembar(lembar)
        print("--Total harga = Rp",total)
        input("\nTekan Enter untuk kembali...")
        cetak1(isi,total)
    else:
        print("Input tidak valid!")
        input("\nTekan Enter untuk kembali...")
        cetak_stiker(isi,total)
#CETAK_BROSUR
def cetak_brosur(isi,total):
    clear_screen()
    print("--Cetak Brosur--")
    print("Jenis Brosur:")
    print("[1] Art Paper 100gr")
    print("[2] Art Paper 120gr")
    print("[3] Art Paper 150gr")
    print("[0] Kembali")
    brosur = str(input("Masukkan jenis brosur : "))
    if brosur == '0':
        clear_screen()
        cetak2(isi,total)
    elif brosur == '1':
        brosur = "Brosur 100gr A5"
        brosurs1 = 420000
        brosurs2 = 422500
        print("\nBrosur 100gr Uk. A5")
        print("Opsi cetak:")
        print("[1] 1 sisi")
        print("[2] 2 sisi")
        print("[0] Kembali")
        sisi = int(input("Masukkan sisi : "))
        if sisi == 0:
            cetak_brosur(isi,total)
        elif sisi == 1:
            sisi1(isi,total,brosurs1,brosur)
        elif sisi == 2:
            sisi2(isi,total,brosurs2,brosur)
        else:
            print("Input tidak valid!")
            input("\nTekan Enter untuk kembali...")
            cetak_brosur(isi,total)
    elif brosur == '2':
        brosur = "Brosur 120gr A5"
        brosurs1 = 432000
        brosurs2 = 434250
        print("\nBrosur 120gr Uk. A5")
        print("Opsi cetak:")
        print("[1] 1 sisi")
        print("[2] 2 sisi")
        print("[0] Kembali")
        sisi = int(input("Masukkan sisi : "))
        if sisi == 0:
            clear_screen()
            cetak_brosur(isi,total)
        elif sisi == 1:
            sisi1(isi,total,brosurs1,brosur)
        elif sisi == 2:
            sisi2(isi,total,brosurs2,brosur)
        else:
            print("Input tidak valid!")
            input("\nTekan Enter untuk kembali...")
            cetak_brosur(isi,total)
    elif brosur == '3':
        brosur = "Brosur 150gr A5"
        brosurs1 = 445000
        brosurs2 = 447500
        print("\nBrosur 120gr Uk. A5")
        print("Opsi cetak:")
        print("[1] 1 sisi")
        print("[2] 2 sisi")
        print("[0] Kembali")
        sisi = int(input("Masukkan sisi : "))
        if sisi == 0:
            clear_screen()
            cetak_brosur(isi,total)
        elif sisi == 1:
            sisi1(isi,total,brosurs1,brosur)
        elif sisi == 2:
            sisi2(isi,total,brosurs2,brosur)
        else:
            print("Input tidak valid!")
            input("\nTekan Enter untuk kembali...")
            cetak_brosur(isi,total)
    else:
        print("Input tidak valid!")
        input("\nTekan Enter untuk kembali...")
        cetak_brosur(isi,total)
#BROSUR_S1
def sisi1(isi,total,brosurs1,brosur):
    print("==========")
    print(brosur,"1 sisi")
    print("1 rim = Rp",brosurs1,"/500lbr")
    rim = int(input("Masukkan banyak rim : "))
    print("\nDaftar belanja baru:")
    harga_brosur = lambda rim: rim*brosurs1
    sisi1 = (brosur+"    ; {0} Rim 1 sisi ; Harga Rp.{1}".format(rim,harga_brosur(rim)))
    isi.append(sisi1)
    for ini in isi:
        print("- "+ini)
    total = total+harga_brosur(rim)
    print("--Total harga = Rp",total)
    input("\nTekan Enter untuk kembali...")
    cetak1(isi,total)
#BROSUR_S2
def sisi2(isi,total,brosurs2,brosur):
    print("==========")
    print(brosur,"2 sisi")
    print("1 rim = Rp",brosurs2,"/500lbr")
    rim = int(input("Masukkan banyak rim : "))
    print("\nDaftar belanja baru:")
    harga_brosur = lambda rim: rim*brosurs2
    sisi2 = (brosur+"    ; {0} Rim 2 sisi ; Harga Rp.{1}".format(rim,harga_brosur(rim)))
    isi.append(sisi2)
    for ini in isi:
        print("- "+ini)
    total = total+harga_brosur(rim)
    print("--Total harga = Rp",total)
    input("\nTekan Enter untuk kembali...")
    cetak1(isi,total)
#
#CETAK_POSTER
def cetak_poster(isi,total):
    clear_screen()
    print("--Cetak Poster--")
    print("Jenis Poster:")
    print("Ukuran A3+")
    print("[1] Art Paper 210gr")
    print("[2] Art Paper 230gr")
    print("[3] Art Paper 260gr")
    print("[0] Kembali")
    poster = str(input("Pilih jenis poster : "))
    if poster == '0':
        clear_screen()
        cetak2(isi,total)
    elif poster == '1':
        print("\nPoster Art Paper 210gr")
        print("Uk. A3+ 5k/lembar")
        lembar = int(input("Berapa lembar : "))
        print("\nDaftar belanja baru:")
        harga_lembar = lambda lembar: lembar*5000
        poster1 = ("Poster 210gr A3+   ; {0} Lembar     ; Harga Rp.{1}".format(lembar,harga_lembar(lembar)))
        isi.append(poster1)
        for ini in isi:
            print("- "+ini)
        total = total+harga_lembar(lembar)
        print("--Total harga = Rp",total)
        input("\nTekan Enter untuk kembali...")
        cetak1(isi,total)
    elif poster == '2':
        print("\nPoster Art Paper 230gr")
        print("Uk. A3+ 7k/lembar")
        lembar = int(input("Berapa lembar : "))
        print("\nDaftar belanja baru:")
        harga_lembar = lambda lembar: lembar*7000
        poster2 = ("Poster 230gr A3+   ; {0} Lembar     ; Harga Rp.{1}".format(lembar,harga_lembar(lembar)))
        isi.append(poster2)
        for ini in isi:
            print("- "+ini)
        total = total+harga_lembar(lembar)
        print("--Total harga = Rp",total)
        input("\nTekan Enter untuk kembali...")
        cetak1(isi,total)
    elif poster == '3':
        print("\nPoster Art Paper 260gr")
        print("Uk. A3+ 10k/lembar")
        lembar = int(input("Berapa lembar : "))
        print("\nDaftar belanja baru:")
        harga_lembar = lambda lembar: lembar*10000
        poster3 = ("Poster 260gr A3+   ; {0} Lembar     ; Harga Rp.{1}".format(lembar,harga_lembar(lembar)))
        isi.append(poster3)
        for ini in isi:
            print("- "+ini)
        total = total+harga_lembar(lembar)
        print("--Total harga = Rp",total)
        input("\nTekan Enter untuk kembali...")
        cetak1(isi,total)
    else:
        print("Input tidak valid!")
        input("\nTekan Enter untuk kembali...")
        cetak_poster(isi,total)
#
#CETAK_KALENDER
def cetak_kalender(isi,total):
    clear_screen()
    print("--Cetak Kalender--")
    print("Pilihan Kalender:")
    print("Ukuran A3+")
    print("[1] Art Paper 120gr (12-2 lbr)")
    print("[2] Art Paper 260gr (1 lbr)")
    print("[0] Kembali")
    kalender = str(input("Pilih jenis kalender : "))
    if kalender == '0':
        clear_screen()
        cetak2(isi,total)
    elif kalender == '1':
        print("\nKalender Art Paper 120gr")
        print("Klep plat seng")
        print("[1] 12 Lembar ; [2] 6 Lembar")
        print("[3] 4  Lembar ; [4] 3 Lembar")
        print("[5] 2  Lembar ;")
        print("[0] Kembali")
        lembar = str(input("Masukkan pilihan : "))
        if lembar == '0':
            cetak_kalender(isi,total)
        elif lembar == '1':
            print("==========")
            print("Kalender 12 lembar")
            print("Art Paper 120gr A3+")
            print("1 Kalender 12lbr = Rp.22680")
            lembar = int(input("Masukkan banyak kalender : "))
            harga_kalender = lambda lembar: lembar*22680
            lembar1 = ("{0} Kalender 120gr   ; 12 lembar A3+; Harga Rp.{1}".format(lembar,harga_kalender(lembar)))
            print("\nDaftar belanja baru:")
            isi.append(lembar1)
            for ini in isi:
                print("- "+ini)
            total = total+harga_kalender(lembar)
            print("--Total harga = Rp",total)
            input("\nTekan Enter untuk kembali...")
            cetak1(isi,total)
        elif lembar == '2':
            print("==========")
            print("Kalender 6 lembar")
            print("Art Paper 120gr A3+")
            print("1 Kalender 6lbr = Rp.12720")
            lembar = int(input("Masukkan banyak kalender : "))
            harga_kalender = lambda lembar: lembar*12720
            lembar2 = ("{0} Kalender 120gr   ; 6 lembar A3+ ; Harga Rp.{1}".format(lembar,harga_kalender(lembar)))
            print("\nDaftar belanja baru:")
            isi.append(lembar2)
            for ini in isi:
                print("- "+ini)
            total = total+harga_kalender(lembar)
            print("--Total harga = Rp",total)
            input("\nTekan Enter untuk kembali...")
            cetak1(isi,total)
        elif lembar == '3':
            print("==========")
            print("Kalender 4 lembar")
            print("Art Paper 120gr A3+")
            print("1 Kalender 4lbr = Rp.9360")
            lembar = int(input("Masukkan banyak kalender : "))
            harga_kalender = lambda lembar: lembar*9360
            lembar3 = ("{0} Kalender 120gr   ; 4 lembar A3+ ; Harga Rp.{1}".format(lembar,harga_kalender(lembar)))
            print("\nDaftar belanja baru:")
            isi.append(lembar3)
            for ini in isi:
                print("- "+ini)
            total = total+harga_kalender(lembar)
            print("--Total harga = Rp",total)
            input("\nTekan Enter untuk kembali...")
            cetak1(isi,total)
        elif lembar == '4':
            print("==========")
            print("Kalender 3 lembar")
            print("Art Paper 120gr A3+")
            print("1 Kalender 3lbr = Rp.7200")
            lembar = int(input("Masukkan banyak kalender : "))
            harga_kalender = lambda lembar: lembar*7200
            lembar4 = ("{0} Kalender 120gr   ; 3 lembar A3+ ; Harga Rp.{1}".format(lembar,harga_kalender(lembar)))
            print("\nDaftar belanja baru:")
            isi.append(lembar4)
            for ini in isi:
                print("- "+ini)
            total = total+harga_kalender(lembar)
            print("--Total harga = Rp",total)
            input("\nTekan Enter untuk kembali...")
            cetak1(isi,total)
        elif lembar == '5':
            print("==========")
            print("Kalender 2 lembar")
            print("Art Paper 120gr A3+")
            print("1 Kalender 3lbr = Rp.5400")
            lembar = int(input("Masukkan banyak kalender : "))
            harga_kalender = lambda lembar: lembar*5400
            lembar5 = ("{0} Kalender 120gr   ; 3 lembar A3+ ; Harga Rp.{1}".format(lembar,harga_kalender(lembar)))
            print("\nDaftar belanja baru:")
            isi.append(lembar5)
            for ini in isi:
                print("- "+ini)
            total = total+harga_kalender(lembar)
            print("--Total harga = Rp",total)
            input("\nTekan Enter untuk kembali...")
            cetak1(isi,total)
        else:
            print("Input tidak valid!")
            input("\nTekan Enter untuk kembali...")
            cetak_kalender(isi,total)
    elif kalender == '2':
            print("==========")
            print("Kalender 1 lembar")
            print("Lubang mata ayam")
            print("Art Paper 260gr A3+")
            print("1 Kalender 1lbr = Rp.3840")
            kalend = int(input("Masukkan banyak kalender : "))
            harga_kalender = lambda lembar: lembar*3840
            kalend2 = ("{0} Kalender 260gr   ; 1 lembar A3+ ; Harga Rp.{1}".format(kalend,harga_kalender(kalend)))
            print("\nDaftar belanja baru:")
            isi.append(kalend2)
            for ini in isi:
                print("- "+ini)
            total = total+harga_kalender(kalend)
            print("--Total harga = Rp",total)
            input("\nTekan Enter untuk kembali...")
            cetak1(isi,total)
    else:
        print("Input tidak valid!")
        input("\nTekan Enter untuk kembali...")
        cetak_kalender(isi,total)
#DISKON
def ambil_diskon(isi,total):
    clear_screen()
    print("--Total harga belanjaan anda = Rp",total)
    print("\n--Ambil Diskon--")
    print("(1) Diskon 20% minimal total belanja Rp.100K")
    print("(2) Diskon 29% minimal total belanja Rp.230K")
    print("(3) Diskon 50% minimal total belanja Rp.500K")
    print("[0] Kembali")
    diskon = str(input("Ambil diskon : "))
    if diskon == '0':
        clear_screen()
        cetak2(isi,total)
    elif diskon == '1':
        if total > 230000:
            print("Belanjaan anda lebih dari Rp.230k")
            print("Anda disarankan mengambil diskon 29%/15%!")
            input("\nTekan Enter untuk kembali...")
            ambil_diskon(isi,total)
        elif total >= 100000:
            total1 = total
            print("\n--Total harga saat ini = Rp",total1)
            total = (lambda x:x*20/100)(total1)
            print("--Total harga baru     = Rp",total)
            print("- Anda berhasil mendapat diskon 20%!")
            input("\nTekan Enter untuk kembali...")
            cetak1(isi,total)
        else:
            print("Tidak dapat mengambil diskon!")
            print("Belanjaan anda kurang dari Rp.100k")
            input("\nTekan Enter untuk kembali...")
            cetak1(isi,total)
    elif diskon == '2':
        if total > 500000:
            print("Belanjaan anda lebih dari Rp.500k")
            print("Anda disarankan mengambil diskon 50%!")
            input("\nTekan Enter untuk kembali...")
            ambil_diskon(isi,total)
        elif total >= 230000:
            total1 = total
            print("\n--Total harga saat ini = Rp",total1)
            total = (lambda x:x*29/100)(total1)
            print("--Total harga baru     = Rp",total)
            print("- Anda berhasil mendapat diskon 29%!")
            input("\nTekan Enter untuk kembali...")
            cetak1(isi,total)
        else:
            print("Tidak dapat mengambil diskon!")
            print("Belanjaan anda kurang dari Rp.230k")
            input("\nTekan Enter untuk kembali...")
            ambil_diskon(isi,total)
    elif diskon == '3':
        if total >= 500000:
            total1 = total
            print("\n--Total harga saat ini = Rp",total1)
            total = (lambda x:x*50/100)(total1)
            print("--Total harga baru     = Rp",total)
            print("- Anda berhasil mendapat diskon 50%!")
            input("\nTekan Enter untuk kembali...")
            cetak1(isi,total)
        else:
            print("Tidak dapat mengambil diskon!")
            print("Belanjaan anda kurang dari Rp.500k")
            input("\nTekan Enter untuk kembali...")
            ambil_diskon(isi,total)
    else:
        print("Input tidak valid!")
        input("\nTekan Enter untuk kembali...")
        ambil_diskon(isi,total)
#MAIN
if __name__ == "__main__":
    clear_screen()
    print("    --SHIAN PRINTINIG--    ")
    print("by Rausyanfikr ; 2009106020")
    time.sleep(2)
    isi = []
    total = 0
    clear_screen()
    cetak(isi,total)