#!/usr/bin/python3
# -*- coding:utf-8 -*-

remark = '''使用Beautifulsoup解析HTML'''

'''
打开百度新歌榜， http://music.baidu.com/top/new

在排名前50的歌曲中，找出其中排名上升的歌曲和演唱者

注意： 有的歌曲名里面有 "影视原声" 这样的标签， 要去掉

最终结果显示的结果如下：
我不能忘记你       :  林忆莲
等                :  严艺丹
飞天              :  云朵
粉墨              :  霍尊
春风十里不如你     :  李健

'''
#引入相关包
pythonPath = r'D:\TDdownload\Document\Python'
import os,sys,time
sys.path.append(pythonPath)
import configure as cfg
from selenium import webdriver

driver = webdriver.Chrome()

driver.implicitly_wait(20)

driver.get('http://music.baidu.com/top/new')

try:
    ele = driver.find_element_by_id('songListWrapper')
    ele2 = ele.find_elements_by_tag_name('li')
    for one in ele2:
        ele_up = one.find_element_by_css_selector('.status > i').get_attribute('class')
        #print(ele_up)
        if ele_up == 'new':
            songTitle = one.find_element_by_css_selector('.song-title > a').text
            #把括号后面的标签去掉
            idx = songTitle.find('（')
            if idx != -1:
                songName = songTitle[:idx]
            else:
                songName = songTitle
            songSinger = one.find_element_by_css_selector('.singer a').text
            print('{0:{1}<30}:\t{2}'.format(songName,chr(12288),songSinger))
    #print(ele.text)
except:
    print('get element failed!')
finally:
    driver.quit()


# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def isSubtree(self, root, subRoot):
        stack = [root]
        while stack:
            node = stack.pop()
            if node:
                if self.CheckSame(node, subRoot): return True
                stack += [node.left, node.right]
        return False

    def CheckSame(self, tree0, tree1):
        if (tree0 == None) and (tree1 == None): return True
        elif (tree0 != None) and (tree1 != None):
            return (tree0.val == tree1.val) and self.CheckSame(tree0.left, tree1.left) and self.CheckSame(tree0.right, tree1.right)
        else: return False

Solution/[572][Easy] Subtree of Another Tree.py


import os
import re
import time

from git import Repo, Git, InvalidGitRepositoryError, GitError, PushInfo
from halo import Halo

from ml_git import log
from ml_git.config import get_metadata_path
from ml_git.constants import METADATA_MANAGER_CLASS_NAME, HEAD_1, RGX_ADDED_FILES, RGX_DELETED_FILES, RGX_SIZE_FILES, \
    RGX_AMOUNT_FILES, TAG, AUTHOR, EMAIL, DATE, MESSAGE, ADDED, SIZE, AMOUNT, DELETED
from ml_git.manifest import Manifest
from ml_git.utils import get_root_path, ensure_path_exists, yaml_load, RootPathException, get_yaml_str

class MetadataRepo(object):

    def __init__(self, git, path):
        try:
            root_path = get_root_path()
            self.__path = os.path.join(root_path, path)
            self.__git = git
            ensure_path_exists(self.__path)
        except RootPathException as e:
            log.error(e, class_name=METADATA_MANAGER_CLASS_NAME)
            raise e
        except Exception as e:
            if str(e) == '\'Metadata\' object has no attribute \'_MetadataRepo__git\'':
                log.error('You are not in an initialized ml-git repository.', class_name=METADATA_MANAGER_CLASS_NAME)
            else:
                log.error(e, class_name=METADATA_MANAGER_CLASS_NAME)
            return

    def init(self):
        try:
            log.info('Metadata init [%s] @ [%s]' % (self.__git, self.__path), class_name=METADATA_MANAGER_CLASS_NAME)
            Repo.clone_from(self.__git, self.__path)
        except GitError as g:
            if 'fatal: repository \'\' does not exist' in g.stderr:
                raise GitError('Unable to find remote repository. Add the remote first.')
            elif 'Repository not found' in g.stderr:
                raise GitError('Unable to find ' + self.__git + '. Check the remote repository used.')
            elif 'already exists and is not an empty directory' in g.stderr:
                raise GitError('The path [%s] already exists and is not an empty directory.' % self.__path)
            elif 'Authentication failed' in g.stderr:
                raise GitError('Authentication failed for git remote')
            else:
                raise GitError(g.stderr)
            return

    def remote_set_url(self, repotype, mlgit_remote):
        try:
            if self.check_exists():
                repo = Repo(self.__path)
                repo.remote().set_url(new_url=mlgit_remote)
        except InvalidGitRepositoryError as e:
            log.error(e, class_name=METADATA_MANAGER_CLASS_NAME)
            raise e

    def check_exists(self):
        log.debug('Metadata check existence [%s] @ [%s]' % (self.__git, self.__path),
                  class_name=METADATA_MANAGER_CLASS_NAME)
        try:
            Repo(self.__path)
        except Exception:
            return False
        return True

    def checkout(self, sha):
        repo = Git(self.__path)
        repo.checkout(sha)

    def update(self):
        log.info('Pull [%s]' % self.__path, class_name=METADATA_MANAGER_CLASS_NAME)
        repo = Repo(self.__path)
        o = repo.remotes.origin
        o.pull('--tags')

    def commit(self, file, msg):
        log.info('Commit repo[%s] --- file[%s]' % (self.__path, file), class_name=METADATA_MANAGER_CLASS_NAME)
        repo = Repo(self.__path)
        repo.index.add([file])
        return repo.index.commit(msg)

    def tag_add(self, tag):
        repo = Repo(self.__path)
        return repo.create_tag(tag, message='Automatic tag "{0}"'.format(tag))

    @Halo(text='Pushing metadata to the git repository', spinner='dots')
    def push(self):
        log.debug('Push [%s]' % self.__path, class_name=METADATA_MANAGER_CLASS_NAME)
        repo = Repo(self.__path)
        try:
            for i in repo.remotes.origin.push(tags=True):
                if (i.flags & PushInfo.ERROR) == PushInfo.ERROR:
                    raise RuntimeError('Error on push metadata to git repository. Please update your mlgit project!')

            for i in repo.remotes.origin.push():
                if (i.flags & PushInfo.ERROR) == PushInfo.ERROR:
                    raise RuntimeError('Error on push metadata to git repository. Please update your mlgit project!')
        except GitError as e:
            err = e.stderr
            match = re.search("stderr: 'fatal:((?:.|\\s)*)'", err)
            if match:
                err = match.group(1)
                raise GitError(err)

    def fetch(self):
        try:
            log.debug(' fetch [%s]' % self.__path, class_name=METADATA_MANAGER_CLASS_NAME)
            repo = Repo(self.__path)
            repo.remotes.origin.fetch()
        except GitError as e:
            err = e.stderr
            match = re.search('stderr: \'fatal:(.*)\'', err)
            if match:
                err = match.group(1)
                log.error(err, class_name=METADATA_MANAGER_CLASS_NAME)
            else:
                log.error(err, class_name=METADATA_MANAGER_CLASS_NAME)
            return False

    def list_tags(self, spec, full_info=False):
        tags = []
        try:
            repo = Repo(self.__path)
            r_tags = repo.tags if full_info else repo.git.tag(sort='creatordate').split('\n')
            for tag in r_tags:
                if f'__{spec}__' in str(tag):
                    tags.append(tag)

        except Exception:
            log.error('Invalid ml-git repository!', class_name=METADATA_MANAGER_CLASS_NAME)
        return tags

    def delete_tag(self, tag):
        pass

    def _usrtag_exists(self, usrtag):
        repo = Repo(self.__path)
        sutag = usrtag._get()
        for tag in repo.tags:
            stag = str(tag)
            if sutag in stag:
                return True
        return False

    def _tag_exists(self, tag):
        tags = []
        repo = Repo(self.__path)
        if tag in repo.tags:
            tags.append(tag)
        model_tag = '__'.join(tag.split('__')[-3:])
        for r_tag in repo.tags:
            if model_tag == str(r_tag):
                tags.append(str(r_tag))
        return tags

    def __realname(self, path, root=None):
        if root is not None:
            path = os.path.join(root, path)
        result = os.path.basename(path)
        return result

    def list(self, title='ML Datasets'):
        metadata_path = self.__path

        prefix = 0
        if metadata_path != '/':
            if metadata_path.endswith('/'):
                metadata_path = metadata_path[:-1]
            prefix = len(metadata_path)

        output = title + '\n'
        for root, dirs, files in os.walk(metadata_path):
            if root == metadata_path:
                continue
            if '.git' in root:
                continue

            level = root[prefix:].count(os.sep)
            indent = subindent = ''
            if level > 0:
                indent = '|   ' * (level - 1) + '|-- '
            subindent = '|   ' * (level) + '|-- '
            output += '{}{}\n'.format(indent, self.__realname(root))
            # print dir only if symbolic link; otherwise, will be printed as root
            for d in dirs:
                if os.path.islink(os.path.join(root, d)):
                    output += '{}{}\n'.format(subindent, self.__realname(d, root=root))
        if output != (title + '\n'):
            print(output)
        else:
            log.error('You don\'t have any entity being managed.')
            # for f in files:
            # if 'README' in f: continue
            # if 'MANIFEST.yaml' in root: continue # TODO : check within the ML entity metadat for manifest files
            # print('{}{}'.format(subindent, self.__realname(f, root=root)))

    @staticmethod
    def metadata_print(metadata_file, spec_name):
        md = yaml_load(metadata_file)

        sections = ['dataset', 'model', 'labels']
        for section in sections:
            if section in ['model', 'dataset', 'labels']:
                try:
                    md[section]  # 'hack' to ensure we don't print something useless
                    # 'dataset' not present in 'model' and vice versa
                    print('-- %s : %s --' % (section, spec_name))
                except Exception:
                    continue
            elif section not in ['model', 'dataset', 'labels']:
                print('-- %s --' % (section))
            try:
                print(get_yaml_str(md[section]))
            except Exception:
                continue

    def sha_from_tag(self, tag):
        try:
            r = Repo(self.__path)
            return r.git.rev_list(tag).split('\n', 1)[0]
        except Exception:
            return None

    def git_user_config(self):
        r = Repo(self.__path)
        reader = r.config_reader()
        config = {}
        types = ['email', 'name']
        for type in types:
            try:
                field = reader.get_value('user', type)
                config[type] = field
            except Exception:
                config[type] = None
        return config

    def metadata_spec_from_name(self, specname):
        specs = []
        for root, dirs, files in os.walk(self.__path):
            if '.git' in root:
                continue
            if specname in root:
                specs.append(os.path.join(root, specname + '.spec'))
        return specs

    def show(self, spec):
        specs = self.metadata_spec_from_name(spec)

        for specpath in specs:
            self.metadata_print(specpath, spec)

    def get(self, categories, model_name, file=None):
        if file is None:
            full_path = os.path.join(self.__path, os.sep.join(categories), model_name, model_name)
        else:
            full_path = os.path.join(self.__path, os.sep.join(categories), model_name, file)
        log.info('Metadata GET %s' % full_path, class_name=METADATA_MANAGER_CLASS_NAME)
        if os.path.exists(full_path):
            return yaml_load(full_path)
        return None

    def reset(self):
        repo = Repo(self.__path)
        # get current tag reference
        tag = self.get_current_tag()
        # reset
        try:
            repo.head.reset(HEAD_1, index=True, working_tree=True, paths=None)
        except GitError as g:
            if 'Failed to resolve \'HEAD~1\' as a valid revision.' in g.stderr:
                log.error('There is no commit to go back. Do at least two commits.',
                          class_name=METADATA_MANAGER_CLASS_NAME)
            raise g
        # delete the associated tag
        repo.delete_tag(tag)

    def get_metadata_manifest(self, path):
        if os.path.isfile(path):
            return Manifest(path)
        return None

    def remove_deleted_files_meta_manifest(self, manifest, deleted_files):
        if manifest is not None:
            for file in deleted_files:
                manifest.rm_file(file)
            manifest.save()

    def get_current_tag(self):
        repo = Repo(self.__path)
        tag = next((tag for tag in repo.tags if tag.commit == repo.head.commit), None)
        return tag

    def __sort_tag_by_date(self, elem):
        return elem.commit.authored_date

    def get_log_info(self, spec, fullstat=False):
        tags = self.list_tags(spec, True)
        formatted = ''
        if len(tags) == 0:
            raise RuntimeError('No log found for entity [%s]' % spec)

        tags.sort(key=self.__sort_tag_by_date)

        for tag in tags:
            formatted += '\n' + self.get_formatted_log_info(tag, fullstat)

        return formatted

    def get_formatted_log_info(self, tag, fullstat):
        commit = tag.commit
        info = ''
        info += '\n{}: {}'.format(TAG, str(tag))
        info += '\n{}: {}'.format(AUTHOR, commit.author.name)
        info += '\n{}: {}'.format(EMAIL, commit.author.email)
        info += '\n{}: {}'.format(DATE, time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(commit.authored_date)))
        info += '\n{}: {}'.format(MESSAGE, commit.message)

        if fullstat:
            added, deleted, size, amount = self.get_ref_diff(tag)
            if len(added) > 0:
                added_list = list(added)
                info += '\n\n{} [{}]:\n\t{}'.format(ADDED, len(added_list), '\n\t'.join(added_list))
            if len(deleted) > 0:
                deleted_list = list(deleted)
                info += '\n\n{} [{}]:\n\t{}'.format(DELETED, len(deleted_list), '\n\t'.join(deleted_list))
            if len(size) > 0:
                info += '\n\n{}: {}'.format(SIZE, '\n\t'.join(size))
            if len(amount) > 0:
                info += '\n\n{}: {}'.format(AMOUNT, '\n\t'.join(amount))

        return info

    def get_ref_diff(self, tag):
        repo = Repo(self.__path)
        commit = tag.commit
        parents = tag.commit.parents
        added_files = []
        deleted_files = []
        size_files = []
        amount_files = []
        if len(parents) > 0:
            diff = repo.git.diff(str(parents[0]), str(commit))
            added_files = re.findall(RGX_ADDED_FILES, diff)
            deleted_files = re.findall(RGX_DELETED_FILES, diff)
            size_files = re.findall(RGX_SIZE_FILES, diff)
            amount_files = re.findall(RGX_AMOUNT_FILES, diff)

        return added_files, deleted_files, size_files, amount_files

class MetadataManager(MetadataRepo):
    def __init__(self, config, type='model'):
        self.path = get_metadata_path(config, type)
        self.git = config[type]['git']

        super(MetadataManager, self).__init__(self.git, self.path)

class MetadataObject(object):
    def __init__(self):
        pass

# TODO signed tag
# try:
#            self.repo.create_tag(self.config['tag'],
#                verify=True,
#                ref=None)
#            print('okay')
#        except:
#            print('not okay')

if __name__ == '__main__':
    r = MetadataRepo('git@github.com:example/your-mlgit-datasets.git', 'ml-git/datasets/')
    # tag = 'vision-computing__images__cifar-10__1'
    # sha = '0e4649ad0b5fa48875cdfc2ea43366dc06b3584e'
    # #r.checkout(sha)
    # #r.checkout('master')


# db_writer.py
'''Writes x-ray data into file using given information'''

import os
import json
import zipfile
from sqlite3 import connect, Binary
from calibre_plugins.xray_creator.config import __prefs__ as prefs

class DBWriter(object):
    '''Writes x-ray data into file using given information'''
    def __init__(self, filename):
        if os.path.exists(filename):
            os.remove(filename)
        self._connection = connect(filename)
        self._connection.text_factory = Binary
        self._cursor = self._connection.cursor()
        self._import_base_db()

    def save(self):
        '''Saves changes into file'''
        self._connection.commit()

    def close(self):
        '''Closes file'''
        self._connection.close()

    def _import_base_db(self):
        '''Imports base data into file'''
        self._cursor.execute('PRAGMA user_version = 1')
        self._cursor.execute('PRAGMA encoding = utf8')

        # create tables
        self._cursor.execute('CREATE TABLE type(id INTEGER, label INTEGER, singular_label INTEGER, '
                             'icon INTEGER, top_mentioned_entities TEXT, PRIMARY KEY(id))')
        self._cursor.execute('CREATE TABLE string(id INTEGER, language TEXT, text TEXT)')
        self._cursor.execute('CREATE TABLE source(id INTEGER, label INTEGER, url INTEGER, '
                             'license_label INTEGER, license_url INTEGER, PRIMARY KEY(id))')
        self._cursor.execute('CREATE TABLE occurrence(entity INTEGER, start INTEGER, length INTEGER)')
        self._cursor.execute('CREATE TABLE excerpt(id INTEGER, start INTEGER, length INTEGER, '
                             'image TEXT, related_entities TEXT, goto INTEGER, PRIMARY KEY(id))')
        self._cursor.execute('CREATE TABLE entity_excerpt(entity INTEGER, excerpt INTEGER)')
        self._cursor.execute('CREATE TABLE entity_description(text TEXT, source_wildcard TEXT, '
                             'source INTEGER, entity INTEGER, PRIMARY KEY(entity))')
        self._cursor.execute('CREATE TABLE entity(id INTEGER, label TEXT, loc_label INTEGER, '
                             'type INTEGER, count INTEGER, has_info_card TINYINT, PRIMARY KEY(id))')
        self._cursor.execute('CREATE TABLE book_metadata(srl INTEGER, erl INTEGER, has_images TINYINT, '
                             'has_excerpts TINYINT, show_spoilers_default TINYINT, num_people INTEGER, '
                             'num_terms INTEGER, num_images INTEGER, preview_images TEXT)')

        # insert base data
        with zipfile.ZipFile(prefs['plugin_path'], 'r') as template_file:
            xray_templates = json.loads(template_file.read('templates/xray_data_template.json'))

        self._insert_into_table('type', xray_templates['BASE_DB_TYPE'])
        self._insert_into_table('source', xray_templates['BASE_DB_SOURCE'])
        self._insert_into_table('entity', xray_templates['BASE_DB_ENTITY'])
        self._insert_into_table('string', xray_templates['BASE_DB_STRING'])

    def _insert_into_table(self, table_name, data):
        '''Import given data into table named table_name'''
        if len(data) == 0:
            return
        if isinstance(data, list):
            params = ['?'] * len(data[0])
            self._cursor.executemany('INSERT INTO %s VALUES (%s)' % (table_name, ','.join(params)), data)
        elif isinstance(data, tuple):
            params = ['?'] * len(data)
            self._cursor.execute('INSERT INTO %s VALUES (%s)' % (table_name, ','.join(params)), data)
        else:
            raise ValueError('data is invalid. Expected list or tuple, found %s' % type(data))

    def insert_into_book_metadata(self, data):
        '''Insert data into the book_metadata table'''
        self._insert_into_table('book_metadata', data)

    def insert_into_entity(self, data):
        '''Insert data into the entity table'''
        self._insert_into_table('entity', data)

    def insert_into_entity_description(self, data):
        '''Insert data into the entity_description table'''
        self._insert_into_table('entity_description', data)

    def insert_into_entity_excerpt(self, data):
        '''Insert data into the entity_excerpt table'''
        self._insert_into_table('entity_excerpt', data)

    def insert_into_excerpt(self, data):
        '''Insert data into the excerpt table'''
        self._insert_into_table('excerpt', data)

    def insert_into_occurrence(self, data):
        '''Insert data into the occurrence table'''
        self._insert_into_table('occurrence', data)

    def update_string(self, url):
        '''Update Goodreads url in string table'''
        self._cursor.execute('UPDATE string SET text=? WHERE id=15', (url, ))
        self._connection.commit()

    def update_type(self, type_id, data):
        '''Update top_mentioned_entities in type table'''
        if type_id != 1 and type_id != 2:
            raise ValueError('type_id %i is invalid; must be 1 or 2.' % type_id)
        self._cursor.execute('UPDATE type SET top_mentioned_entities=? WHERE id=?', (data, type_id))

    def create_indices(self):
        '''Creates default indices used by kindle'''
        self._cursor.execute('CREATE INDEX idx_entity_excerpt ON entity_excerpt(entity ASC)')
        self._cursor.execute('CREATE INDEX idx_entity_type ON entity(type ASC)')
        self._cursor.execute('CREATE INDEX idx_occurrence_start ON occurrence(start ASC)')


def _compile(words):
    if not len(words):
        return None, ''
    num = None
    if words[0].isdigit():
        num = int(words[0])
        words = words[1:]
    return num, ' '.join(words)

def _split_out_colons(terms):
    newterms = []
    for term in terms:
        if ':' in term:
            subterms = term.split(':')
            for sub in subterms:
                newterms.append(sub)
                newterms.append(':')
            newterms = newterms[:-1]
        else:
            newterms.append(term)
    return [term for term in newterms if len(term)]

#  parse user command text
def user_command(text, parse_mode='none'):
    terms = text.strip().split()
    if len(terms) == 0:
        return None
    verb = terms[0]
    if parse_mode == 'none':
        content = text.strip()[len(verb):].strip()
    elif parse_mode == 'words':
        content = terms[1:]
    return {'verb': verb, 'content': content}

"""
leaving original implementationw ith functuion name change for historical purposes
def _user_command_original(text):
    terms = text.strip().split()
    terms = _split_out_colons(terms)
    cmd = {}
    if len(terms) == 0:
        return cmd
    cmd['verb'] = terms[0]
    mode = 'directobject'
    flags = ['with', 'by', 'from', 'for', 'to', ':']
    words = []
    for term in terms[1:]:
        if mode == ':':
            words.append(term)
        elif term in flags:
            num, cmd[mode] = _compile(words)
            if not len(cmd[mode]):
                cmd.pop(mode)
            if num:
                cmd[mode+'_num'] = num
            words = []
            mode = term
        else:
            words.append(term)
    if len(words):
        num, cmd[mode] = _compile(words)
        if num:
            cmd[mode+'_num'] = num
    return cmd
"""


import numpy as np
import _pickle
import gzip

def load_mnist():
    f = gzip.open('mnist.pkl.gz', 'rb')
    train_set, valid_set, test_set = _pickle.load(f)
    f.close()
    train_data = train_set[0]
    train_data = np.reshape(train_data, (-1, 28, 28, 1))
    train_data = np.transpose(train_data, (1, 2, 3, 0)) * 255
    train_label = train_set[1]
    train_label = np.reshape(train_label, (1, -1))

    valid_data = valid_set[0]
    valid_data = np.reshape(valid_data, (-1, 28, 28, 1))
    valid_data = np.transpose(valid_data, (1, 2, 3, 0)) * 255
    valid_label = valid_set[1]
    valid_label = np.reshape(valid_label, (1, -1))

    return train_data, train_label, valid_data, valid_label


#!/usr/bin/env python3

# As the first stage of constructing a genre model, this
# uses tags from undergraduate readers to confirm genre tags
# for a set of 300-odd volumes.

# Initially, it produced three different kinds of output, a list
# of "confidentvolumes" where reader's judgment about the majority
# of pages echoed our initial prediction, a list of "errors" where
# those diverged, and a list of "dividedvolumes" where there was
# no clear majority of page genres.

# On closer examination, we became confident about the supposed
# "errors," and moved those into "confident," trusting the reader's
# judgment.

import csv, os, sys
from collections import Counter
import numpy as np
import pandas as pd

# import utils
currentdir = os.path.dirname(__file__)
libpath = os.path.join(currentdir, '../lib')
sys.path.append(libpath)

import SonicScrewdriver as utils

readers = ['donofrio', 'erickson', 'alvarez', 'flynn', 'rubio', 'barajas', 'koh', 'trondson', 'lin', 'buck', 'fleming']

sourcedir = '/Volumes/TARDIS/work/readers/'

subobjects = os.listdir(sourcedir)

subdirs = [x for x in subobjects if os.path.isdir(os.path.join(sourcedir, x))]
tagset = set()
taglist = []

paths = dict()
readerowners = dict()

for subdir in subdirs:
    thisreader = 'none'
    for reader in readers:
        if reader in subdir.lower():
            thisreader = reader
            break
    if thisreader == 'none':
        print(subdir + ' lacks a recognized reader.')
        sys.exit(0)

    wholepath = os.path.join(sourcedir, subdir, 'tags')
    if os.path.isdir(wholepath):
        tagfiles = [x for x in os.listdir(wholepath) if x.endswith('.csv')]
        for f in tagfiles:
            thispath = os.path.join(wholepath, f)
            okaytoadd = True
            with open(thispath, encoding = 'utf-8') as file:
                reader = csv.DictReader(file)
                for row in reader:
                    if 'tag' not in row or len(row['tag']) < 3:
                        okaytoadd = False
                        break

            if okaytoadd:
                tagset.add(f)
                if f not in readerowners:
                    readerowners[f] = []
                    paths[f] = []

                if thisreader not in readerowners[f]:
                    readerowners[f].append(thisreader)
                    paths[f].append(thispath)

print(len(tagset))

allfiles = tagset
# This is a list of all the filenames (note, filenames not docids)
# that we found in the /readers sourcedir.

train1 = pd.read_csv('bzipmeta.csv', dtype = 'object', index_col = 'docid')

tidx = set(train1.index.values)
for filename in allfiles:
    docid = filename.replace('.csv', '')
    if utils.dirty_pairtree(docid) not in tidx:
        print(docid)

genrestocheck = ['fic', 'poe', 'dra', 'bio', 'non']
equivalences = {'non', 'bio', 'other'}

volumesingenre = dict()
for g in genrestocheck:
    volumesingenre[g] = []
alldocids = set()

errorconditions = dict()
erroramounts = dict()
errorids = []
percentagesbydoc = dict()

for filename, owners in readerowners.items():
    path = paths[filename][0]
    if 'metadat' in filename:
        print(filename)
        continue
    docid = utils.dirty_pairtree(filename.replace('.csv', ''))
    alldocids.add(docid)
    expectedgenre = train1.loc[docid, 'sampledas']
    with open(path, encoding = 'utf-8') as f:
        reader = csv.DictReader(f)
        genrectr = Counter()
        allct = 0
        for row in reader:
            allct += 1
            genrectr[row['tag'].lower()] += 1

    genrectr['all'] = allct

    for g in genrestocheck:
        thisgenrepct = genrectr[g] / allct
        nongenre = 0
        for g1 in equivalences:
            nongenre += genrectr[g1]
        nongenrepct = nongenre / allct
        if g == expectedgenre and thisgenrepct > 0.6:
            volumesingenre[g].append(docid)
            alldocids.remove(docid)
            break
        elif g in equivalences and expectedgenre in equivalences and nongenrepct > 0.6:
            if genrectr['bio'] > genrectr['non']:
                volumesingenre['bio'].append(docid)
            else:
                volumesingenre['non'].append(docid)
            # Here it becomes important that bio precedes non in genrestocheck
            # that way bio will always get placed in bio if possible; this is just
            # a fallback
            alldocids.remove(docid)
            break
        elif g != expectedgenre and thisgenrepct > 0.6:
            # In this case, we initially created a list of "errors" to see what we were
            # getting. But the readers seemed to be reliable, so we are recategorizing
            # the "errors" as valid genre categories.

            # errorconditions[docid] = g
            # erroramounts[docid] = thisgenrepct
            alldocids.remove(docid)
            volumesingenre[g].append(docid)
            break

    percentagesbydoc[docid] = genrectr

genredfs = []
for genre, listofdocids in volumesingenre.items():
    thisgenredf = train1.loc[listofdocids, :]
    thisgenredf.loc[ : , 'volgenre'] = pd.Series([genre] * len(listofdocids), index = listofdocids)
    genredfs.append(thisgenredf)
confident = pd.concat(genredfs)
confident.to_csv('confidentvolumes.csv')

# errordf = train1.loc[errorids, : ]
# errordf.loc[ : , 'readergenre'] = pd.Series(errorconditions)
# errordf.loc[ : , 'pctofpages'] = pd.Series(erroramounts)
# errordf.to_csv('possibleerrors.csv')

leftoverids = alldocids
# renaming to make clearer
leftout = train1.loc[leftoverids, : ]

newcolumns = dict()
for g in genrestocheck:
    newcolumns[g] = pd.Series([0] * len(leftoverids), index = leftoverids)

for g in genrestocheck:
    for d in leftoverids:
        gpct = percentagesbydoc[d][g] / percentagesbydoc[d]['all']
        newcolumns[g].loc[d] = gpct

    leftout.loc[ : , g] = newcolumns[g]

leftout.to_csv('genredividedvols.csv')


#Uses python3

import sys

def is_greater_than(n, m):
    str1 = str(n) + str(m)
    str2 = str(m) + str(n)
    if int(str1) < int(str2):
        return 1
    else:
        return -1

def largest_number(a):
    result = list()
    while len(a) > 0:
        max_digit = 0
        for digit in a:
            if is_greater_than(digit, max_digit) == -1:
                max_digit = digit
        result.append(max_digit)
        a.remove(max_digit)
    res = "".join(result)
    print(res)

if __name__ == '__main__':
    inp = sys.stdin.read()
    data = inp.split()
    a = data[1:]
    largest_number(a)


'''
此代码用于使用GEEMAP从GEE批量下载全国数据，截至2023/7/6还未进行测试
Author： Lv
Date: 2023/07/06
Last coded: 2023/07/06
'''

# coding:utf-8

import argparse
import csv
import math
from multiprocessing.dummy import Pool, Lock
import os
import datetime as DATETIME
import random
import geemap
# datetime.strptime(str(a),"%Y%m%d")
import warnings
from tools import *
import tiffile as tif
warnings.simplefilter('ignore', UserWarning)
import ee
import numpy as np
import urllib3

debug = False

dates = [2017,
         2018,
         2019,
         2020,
         2021]

SEASON_DATE_RANGE= {
    'spring': [90, 120],
    'summer': [180, 210],
    'autumn': [270, 300],
    'winter': [0, 30],
    'all': [0, 360]
}

dates = [2018]
NODATA = -999

def get_period(year):
    time_0 = DATETIME.date(year, 1, 1)
    time_1 = DATETIME.date(year, 12, 30)
    return [(time_0.isoformat(), time_1.isoformat())]

def maskS2clouds(image):
    qa = image.select('QA60')

    # Bits 10 and 11 are clouds and cirrus, respectively.
    cloudBitMask = 1 << 10
    cirrusBitMask = 1 << 11

    # Both flags should be set to zero, indicating clear conditions.
    mask = qa.bitwiseAnd(cloudBitMask).eq(0)
    mask = mask.bitwiseAnd(cirrusBitMask).eq(0)
    return image.updateMask(mask).divide(10000)

def tif_file_check(file_path):
    data = tif.imread(file_path)
    data_pixels = data.shape[0] * data.shape[1]
    nodata_pixels = len(data[data <= NODATA])
    if nodata_pixels/data_pixels > 0.2:
        return 'too much nodata'
    elif nodata_pixels/data_pixels > 0.1:
        return 'much nodata'
    else:
        return 'acceptable'

class GEEDownloader:
    def __init__(self, loc_names: list = None, save_path: str = None, cloud_pct: int = 20):
        self.loc_names = loc_names
        self.save_path = save_path
        self.cloud_pct = cloud_pct

    def download_seasonal_s2(self, shp_file, year, loc_name, period_buffer=0):
        period = get_period(year)
        for season in ['spring', 'summer', 'autumn', 'winter', 'all']:
            make_dir(f"{self.save_path}/{season}")
            try:
                s2_collection = (
                    ee.ImageCollection('COPERNICUS/S2')
                    .filterBounds(shp_file)
                    .filterDate(period[0], period[1])
                    .filter(ee.Filter.dayOfYear(SEASON_DATE_RANGE[season][0]-period_buffer if SEASON_DATE_RANGE[season][0]-period_buffer >= 0 else 0,
                                                SEASON_DATE_RANGE[season][1])+period_buffer)
                    .filter(ee.Filter.lte('CLOUDY_PIXEL_PERCENTAGE', self.cloud_pct))
                    .map(maskS2clouds)
                )
                image = s2_collection.median().select(['B2', 'B3', 'B4', 'B8']).clip(shp_file)
                save_name = f"{self.save_path}/{loc_name}/{season}/{period[0].split('-')[0]}_s2.tif"
                geemap.download_ee_image(image, scale=10, region=shp_file, crs="EPSG:4326")
                tif_statu = tif_file_check(save_name)
                if tif_statu == 'acceptable' or period_buffer >= 30:
                    continue
                elif tif_statu == 'much nodata':
                    os.remove(save_name)
                    period_buffer_temp = period_buffer + 5
                    self.download_seasonal_s2(shp_file, year, loc_name, period_buffer_temp)
                else:
                    os.remove(save_name)
                    period_buffer_temp = period_buffer + 10
                    self.download_seasonal_s2(shp_file, year, loc_name, period_buffer_temp)

            except (ee.EEException, urllib3.exceptions.HTTPError) as e:
                if debug:
                    print(e)

def main(shp_path, loc_names, save_path):
    file_paths, file_names = file_name_shp(shp_path)
    for ii in range(len(file_names)):
        file_name = file_names[ii]
        file_path = file_paths[ii]
        if file_name not in loc_names:
            continue
        s2_downloader = GEEDownloader(loc_names, save_path)
        shp_file = geemap.shp_to_ee(file_path)
        s2_downloader.download_seasonal_s2(shp_file=shp_file, year=2018, loc_names=loc_names)

if __name__ == '__main__':
    loc_names = ['Beijing']
    # For users in mainland China, you need to use a VPN and configure a proxy here, because google services are not
    # accessible in China
    # For other regions, you can comment out the following
    os.environ['HTTP_PROXY'] = 'http://127.0.0.1:7890'
    os.environ['HTTPS_PROXY'] = 'http://127.0.0.1:7890'

    parser = argparse.ArgumentParser()
    parser.add_argument('--save_path', type=str, default=r"D:\try", help="Save path")
    parser.add_argument('--num_workers', type=int, default=16, help="Number of workers for multiprocessing")
    parser.add_argument('--sample_points', type=int, default=200,
                        help="Number of sampling points around the base point ")
    parser.add_argument('--cloud_pct', type=int, default=10)
    parser.add_argument('--debug', default=False)

    args = parser.parse_args()

    ee.Authenticate()
    ee.Initialize()
    # A file containing coordinates of more than 2,
    # 000 administrative units in China to provide basic sampling information. If you want to sample in other
    # countries, you can prepare a similar document
    n = args.sample_points
    # Use Gaussian sampling to keep data concentrated in urban areas as much as possible

    def worker(idx):
        idx = idx
        for loc_id in range(n):
            if args.save_path is not None:
                location_path = os.path.join(args.save_path, f'{idx:06d}')
                os.makedirs(location_path, exist_ok=True)
                sub_location_path = os.path.join(location_path, str(loc_id))
                os.makedirs(sub_location_path, exist_ok=True)
                main(shp_path = r' ', loc_names=loc_names, save_path=r'D:\Data\GEE数据文件夹\测试数据')
        return

    indices = range(len(loc_names))

    if args.num_workers == 0:
        for i in indices:
            worker(i)
    else:
        with Pool(processes=args.num_workers) as p:
            p.map(worker, indices)


# -*- coding: utf-8 -*-
"""
Created on Sun Sep 29 21:22:07 2019

@author: evan9
"""

import pandas as pd
import matplotlib.pyplot as plt

data = pd.read_csv('IRE.csv')
x = data.iloc[:, 0]
y_first = data.iloc[:, 1]
y_second = data.iloc[:, 2]
y_ratio = data.iloc[:, 3]

# In[]
fig_1 = plt.figure(figsize=(10,6))
ax_1 = fig_1.add_axes([0.1, 0.1, 0.8, 0.8])
ax_1.plot(x, y_ratio, color='blue', lw=0, marker='o')
ax_1.set_ylim([0, 1.2])
ax_1.set_xlim([0, 25])
ax_1.set_title('Time Delay/ Refractory Period', fontsize=24)
ax_1.set_xlabel('Time Interval (ms)', fontsize=16)
ax_1.set_ylabel('R1/R2 Ratio', fontsize=16)

plt.show()
fig_1.savefig('IRE ratio.png')

# In[]
fig_2 = plt.figure(figsize=(10,6))
ax_2 = fig_2.add_axes([0.1, 0.1, 0.8, 0.8])
ax_2.plot(x, y_first, color='blue', lw=0, marker='o')
ax_2.plot(x, y_second, color='red', lw=0, marker='s')
ax_2.set_title('First & Second Pulse Response', fontsize=20)
ax_2.set_xlabel('Time Interval (ms)', fontsize=16)
ax_2.set_ylabel('Response (mV)', fontsize=16)
ax_2.legend(loc=0, prop={'size': 16})

plt.show()
fig_2.savefig('IRE first second.png')


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

class BatchManager:
    #判断数据集问答对是否数量一致，判断是否有训练数据
    def __init__(self, Q, A, batch_size):
        self.Q = Q
        self.A = A
        self.batch_data = []
        self.batch_size = batch_size
        self.make_batch()

    def make_batch(self):
        #断言表达式 如果相等则正常运行，否则打印error信息
        assert len(self.Q) == len(self.A), ValueError("问答数据不一致")
        #zip方法将可迭代对象打成元组最后返回元组list，这里就是将问答组成一对一对，为的是出现相同问句时对应的不同答法，用random来随机
        self.data = list(zip(self.Q, self.A))

        assert len(self.data) > 0, ValueError("训练数据为空")
        sup = len(self.data) % self.batch_size
        sup = 0 if sup == 0 else self.batch_size - sup
        for i in range(sup):
            sup_data = random.choice(self.data)
            self.data.append(sup_data)
        print("-"*50)
        index = 0
        while True:
            if index >= len(self.data):
                break
            data = self.data[index:index+self.batch_size]
            padded_data = self.pad(data)
            index += self.batch_size
            self.batch_data.append(padded_data)

    def pad(self, data):
        Q,A = zip(*data)
        Q_max_len = max([len(i) for i in Q])
        A_max_len = max([len(i) for i in A])

        new_Q = []
        new_A = []
        for vec in Q:
            new_vec = vec + [0] * (Q_max_len-len(vec))
            new_Q.append(new_vec)

        for vec in A:
            new_vec = vec + [0] * (A_max_len-len(vec))
            new_A.append(new_vec)

        Q = np.array(new_Q)
        A = np.array(new_A)
        return [Q,A]

    def batch(self):
        for i in self.batch_data:
            yield i

#获相对取路径拼接并删除模型和训练集
def clear():
    comfire = input("确认要删除模型重新训练吗？（y/n）: ")
    if comfire in "yY":
        files_under_dir = os.listdir("model")
        for file in files_under_dir:
            try:
                os.remove(os.path.join("model", file))
            except:
                continue

        for file in ["A_vocab", "Q_vocab", "map.pkl"]:
            try:
                os.remove(os.path.join("data", file))
            except:
                continue


#The Assyrian state was composed of 27 provinces, each of which had to sumbit a fixed quota of four canonical commidities every year.
#Provinces frequently only paid a portion of their assessment. Since many of the provinces are of unclear location, one would like a
#way to calculate how similar the payment histories of any two provinces were. This program takes as imputs files containing all
#available payment data from a given province and then compares the precentage of each commodity paid by the two provinces using a
#euclidian norm.
from math import sqrt
def getPairs(filename1, filename2, com, assessments1, assessments2):
    infile1 = open(filename1, 'r')
    useful_tablets = []
    useful_amounts1 = []
    useful_amounts2 = []
    for line1 in infile1:
        line1list = line1.split('\t')
        infile2 = open(filename2, 'r')
        for line2 in infile2:
            line2list = line2.split('\t')
            if line1list[0] == line2list[0] and line1list[com] != 'x'and line1list[com] != 'x\n' and line2list[com] != 'x' and line2list[com] != 'x\n':
               useful_tablets.append(line1list[0])
               useful_amounts1.append(eval(line1list[com])/assessments1[com-1])
               useful_amounts2.append(eval(line2list[com])/assessments2[com-1])
    return useful_tablets, useful_amounts1, useful_amounts2

def main():
    Province_names = ['Arbail', 'Kilizu', 'Halahhu', 'Talmussu', 'Idu',
                      'Katmuhhu', 'Sudu', 'Taidu', 'Amasakku', 'Kulishinas',
                      'Assur', 'UpperProvince', 'LowerProvince', 'Tursan',
                      'Libbiale', 'Ninua', 'Kurda', 'Apku', 'Addarik',
                      'Karana', 'Sibanibe', 'Hissutu', 'Simi', 'Husananu',
                      'Kalhu', 'Sa-sille', 'Sumela']
    assessments_list = [['Arbail', 29530, 188, 1770, 1160,],
                        ['Kilizu', 9710, 77, 770, 580],
                        ['Halahhu', 28030, 180, 1540, 1260],
                        ['Talmussu', 13560, 77, 770, 580],
                        ['Idu', 13560, 77, 770, 580],
                        ['Katmuhhu', 27860, 187, 1870, 2150],
                        ['Sudu', 7710, 66, 660, 70],
                        ['Taidu', 0, 88, 880, 590],
                        ['Amasakku', 0, 66, 660, 670],
                        ['Kulishinas', 0, 33, 330, 320],
                        ['Assur', 0, 88, 880, 890],
                        ['UpperProvince', 0, 180, 1800, 910],
                        ['LowerProvince', 14560, 88, 880, 90],
                        ['Tursan', 17560, 110, 1100, 440],
                        ['Libbiale', 12560, 100, 1000, 90],
                        ['Ninua', 0, 20, 200, 0],
                        ['Kurda', 0, 66, 660, 470],
                        ['Apku', 0, 66, 660, 270],
                        ['Addarik', 0, 66, 660, 270],
                        ['Karana', 0, 66, 660, 270],
                        ['Sibanibe', 0, 66, 660, 270],
                        ['Hissutu', 0, 66, 660, 270],
                        ['Simi',6030, 44, 440, 310],
                        ['Husananu', 11710, 88, 880, 360],
                        ['Kalhu', 6350, 44, 440, 60],
                        ['Sa-sille', 0, 11, 110, 110],
                        ['Sumela', 0, 0, 0, 150]]
    Province1 = input("Please enter the name of the first province ")
    Province2 = input("Please enter the name of the second province ")
    index1 = Province_names.index(Province1)
    index2 = Province_names.index(Province2)
    assessments1 = assessments_list[index1][1:5]
    assessments2 = assessments_list[index2][1:5]
    filename1 =  Province1 + '.py'
    filename2 =  Province2 + '.py'
    differences = []
    commodity_list = ['grain', 'honey', 'sesame', 'fruit']
    for commodity in range(1,5):
        if assessments1[commodity-1] == 0 or assessments2[commodity-1] == 0:
            average = 0
        else:
            #print()
            #print(commodity_list[commodity-1])
            useful_tablets, useful_amounts1, useful_amounts2 = getPairs(filename1, filename2, commodity, assessments1, assessments2)
            #print("texts", '\t\t', Province1, '\t\t', Province2)
            #for i in range(len(useful_tablets)):
            #    print("{0} \t {1:0.3} \t\t {2:0.3}".format(useful_tablets[i], useful_amounts1[i], useful_amounts2[i]))
            total = 0
            for i in range(len(useful_amounts1)):
                total = total + abs(useful_amounts1[i]- useful_amounts2[i])
            average = total/len(useful_amounts1)
            differences.append(average)
        grandAverage = 0
    for i in range(len(differences)):
        grandAverage = grandAverage + differences[i]
    print("The grand average for {0} and {1} is".format(Province1, Province2),
          round(grandAverage/4,3))

main()


def two_sets(n):
  total_sum = n * (n+1) // 2

  if total_sum % 2 != 0:
    return ()

  part_sum = n * (n+1) // 4
  set1 = set()
  takeHead = True
  currentHead = 1
  currentTail = n

  while True:
    # print(part_sum, takeHead, currentHead, currentTail, set1)
    if takeHead:
      if part_sum > currentHead:
        set1.add(currentHead)
        part_sum -= currentHead
        currentHead += 1
        takeHead = False
      else:
        set1.add(part_sum)
        break
    else:
      if part_sum > currentTail:
        set1.add(currentTail)
        part_sum -= currentTail
        currentTail -= 1
        takeHead = True
      else:
        set1.add(part_sum)
        break

  return (list(set1), list(set(range(1,n+1)) - set1))

def main():
  n = int(input())
  result = two_sets(n)
  if len(result) < 2:
    print('NO')
    return
  print('YES')
  print(len(result[0]))
  print(' '.join(map(str, result[0])))
  print(len(result[1]))
  print(' '.join(map(str, result[1])))

if __name__ == "__main__":
  main()


# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

"""
    1st approach: BFS + hashtable
    - BFS the tree level by level
    - use a hashtable to store [parent, currentnode]
    - after we have done the iterating one level, check if the x, y are on the same level and have diff parents

    Time    O(n)
    Space   O(n)
    12ms beats 100%
"""

class Solution(object):
    def isCousins(self, root, x, y):
        if root == None:
            return False
        xParent = -1
        xDepth = -1
        yParent = -1
        yDepth = -1
        q = [(root, None, 0)]
        while len(q) > 0:
            node, parent, depth = q.pop(0)
            if node.val == x:
                xParent = parent
                xDepth = depth
            if node.val == y:
                yParent = parent
                yDepth = depth
            if node.left:
                q.append([node.left, node, depth + 1])
            if node.right:
                q.append([node.right, node, depth + 1])
        return xDepth == yDepth and xParent != yParent


def conflict_count(assignment):
    """Takes an assignment of the n-queens problems and returns the number of
       conflicts in the assignment"""
    conflicts = 0
    for row_1, col_1 in enumerate(assignment):
        for row_2, col_2 in enumerate(assignment[row_1 + 1:]):
            #This block is required since splicing effectively creates a new list starting at index 0
            if row_1 == 0:
                row_2 += 1
            else:
                row_2 += row_1 + 1

            dx, dy = abs(row_2 - row_1), abs(col_2 - col_1) #Find the differences

            if dx != 0 and dy != 0: #Can't divide by 0, nothing happens if numerator is 0
                if (dx / dy) == 1: #Slope, == 1 checks if the two coordinates make a diagonal
                    conflicts += 1
    return conflicts

"""Write a function conflict_count that takes a total assignment for an n-queen problem and returns the number conflicts for that assignment. We define the number of conflicts to be the number of unordered pairs of queens (objects) that threaten (attack) each other. The assignment will be given in the form of a sequence (tuple more specifically). The assignment is a permutation of numbers from 1 to n. The value of n must be inferred from the given assignment.

Hint: diagonals have a slope of 1 or -1. You want to see if abs(dx)==abs(dy)."""


import io
import os

from flask import abort
from minio import Minio, S3Error

MINIO_URL = os.environ['MINIO_URL']
MINIO_ACCESS_KEY = os.environ['MINIO_ACCESS_KEY']
MINIO_SECRET_KEY = os.environ['MINIO_SECRET_KEY']

MINIO_BUCKET_CLIENT = os.environ['MINIO_BUCKET_CLIENT']
MINIO_BUCKET_DOC = os.environ['MINIO_BUCKET_DOC']

MAX_FILE_SIZE = 200_000

client = Minio(
    MINIO_URL,
    access_key=MINIO_ACCESS_KEY,
    secret_key=MINIO_SECRET_KEY,
    secure=False
)

for bucket_name in (MINIO_BUCKET_CLIENT, MINIO_BUCKET_DOC):
    if not client.bucket_exists(bucket_name):
        client.make_bucket(bucket_name)

def save(name: str, file: io.BytesIO) -> None:
    size = file.getbuffer().nbytes

    client.put_object(
        bucket_name=MINIO_BUCKET_DOC,
        object_name=name,
        data=file,
        length=size,
        content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
    )

def get(file_id: str):
    try:
        return client.get_object(MINIO_BUCKET_CLIENT, file_id)
    except S3Error:
        return abort(404)


# @Author : bamtercelboo
# @Datetime : 2018/9/15 19:09
# @File : modelHelp.py
# @Last Modify Time : 2018/9/15 19:09
# @Contact : bamtercelboo@{gmail.com, 163.com}

"""
    FILE :  modelHelp.py
    FUNCTION : None
"""

import torch
import random
from DataUtils.Common import *
torch.manual_seed(seed_num)
random.seed(seed_num)

def prepare_pack_padded_sequence(inputs_words, seq_lengths, device=cpu_device, descending=True):
    """
    :param use_cuda:
    :param inputs_words:
    :param seq_lengths:
    :param descending:
    :return:
    """
    sorted_seq_lengths, indices = torch.sort(torch.LongTensor(seq_lengths), descending=descending)
    if device != cpu_device:
        sorted_seq_lengths, indices = sorted_seq_lengths.to(device), indices.to(device)
    _, desorted_indices = torch.sort(indices, descending=False)
    sorted_inputs_words = inputs_words[indices]
    return sorted_inputs_words, sorted_seq_lengths.cpu().numpy(), desorted_indices


"""
Implementation of Programming Project Flask API
"""
import os

from flask import Flask, request
from flask_cors import CORS
from flask_restful import Api
from recommendation import *

# enables flask
app = Flask(__name__)

# enables CORS
CORS(app)
api = Api(app)

@app.route('/movies', methods=['GET'])
def get_mov_list():
    """Return the Full Movie List"""
    return get_movie_list()

@app.route('/recommendation', methods=['GET'])
def get_recommendation():
    """
    If more than one ID is entered, creates an array from the IDs entered with commas and calls the get_list_of_recommendation method if there are no more than five IDs entered.
    """
    request_data = request.args.get('movie_id')
    if (request_data is None):
        return 'Please enter a value for the key: "movie_id"', 400
    try:
        if ',' in request_data:
            movie_ids = [int(mov) for mov in request_data.split(',')]
            if (len(movie_ids) > 5):
                return 'Only five movies can be entered at the same time', 400
        else:
            movie_ids = [int(request_data)]
        return get_list_of_recommendation(movie_ids)
    except Exception as e:
        return 'The input data is not in the correct format. The message was: ({0})'.format(e), 400

if __name__ == '__main__':
    """
configures the port and hosting for the flask api
    """
    cfg_port = os.getenv('PORT', "5000")
    app.run(host="0.0.0.0", port=cfg_port)


from django import forms
from django.forms.widgets import CheckboxSelectMultiple

from .models import Recipe

class RecipeForm(forms.ModelForm):
    class Meta:
        model = Recipe
        fields = ('title', 'description', 'cooking_time', 'tag', 'image')
        widgets = {
            'tag': CheckboxSelectMultiple(),
        }


def f(s, step):
    if s>=31: return step%2 == 0
    if step == 0: return False

    step -= 1
    t = [
            f(s+1, step),
            f(s+5, step),
            f(s*2, step)
        ]
    if step%2 != 0:
        return any(t)  # 19
    else:
        return any(t)

for s in range(1, 31):
    if f(s,3):  # Петя-Ваня-Петя
        print(s)
        break

# 3


import numpy as np
import cv2
import os
from glob import glob
vid = cv2.VideoCapture(cv2.samples.findFile("menu1.mp4"))
currentframe = 0

if not os.path.exists('data'):
    os.makedirs('data')

while (True):
    success, frame = vid.read()

    #cv2.imshow("Output", frame)
    cv2.imwrite('./data/frame' + str(currentframe) + '.jpg', frame)
    currentframe +=1

    #if cv2.waitKey(1) & 0xFF == ord('q'):
     #   break

vid.release()
cv2.destroyAllWindows()


import pandas as pd
import numpy as np
import hex_analysis as ha

## Main function
if __name__ == '__main__':

    # Load map data
    map_file = './map_data/Homefront.dat'
    out_dir = './map_analysis/Homefront/'
    map_data = ha.read_map_data(map_file)

    ## USER INPUTS
    top_n = 8 # How many locations to list
    loc = (29,-2) # Center of search
    check_radius = 4 # How far from loc to search

    # Generate list of all empty hexes were stations/outposts can be placed
    all_hexes = ha.get_coords_within_radius(loc,check_radius)
    empty_hexes = []
    for h in all_hexes:
        if not (h in map_data.index):
            empty_hexes.append(h)

    # Analyze the harvest values of each hex
    hex_vals = {}
    for h in empty_hexes:
        hex_vals[h] = ha.hex_analysis(h,map_data)

    # Analyze all hexes in range
    MF1_dict = {}
    MF2_dict = {}
    MF3_dict = {}
    MC2_dict = {}
    MC3_dict = {}
    MC4_dict = {}
    MC2_dict_noP = {}
    MC3_dict_noP = {}
    MC4_dict_noP = {}
    HD_dict = {}
    moon_dict = {}
    for h,an in hex_vals.items():
        MF1_dict[h] = an.MF['1 range']
        MF2_dict[h] = an.MF['2 range']
        MF3_dict[h] = an.MF['3 range']
        MC2_dict[h] = an.MC['2 range+Prospect']
        MC3_dict[h] = an.MC['3 range+Prospect']
        MC4_dict[h] = an.MC['4 range+Prospect']
        MC2_dict_noP[h] = an.MC['2 range']
        MC3_dict_noP[h] = an.MC['3 range']
        MC4_dict_noP[h] = an.MC['4 range']
        HD_dict[h] = an.HD['4 range']
        moon_dict[h] = an.moons

    # Sort best spots
    MF1_df = pd.DataFrame.from_dict(data=MF1_dict,orient='index')
    MF1_df.insert(loc=4,column='Total RSS',value=MF1_df[['Metal','Gas','Crystal']].sum(axis=1))
    MF1_df.sort_values(by='Total RSS',axis=0,ascending=False,inplace=True)

    MF2_df = pd.DataFrame.from_dict(data=MF2_dict,orient='index')
    MF2_df.insert(loc=4,column='Total RSS',value=MF2_df[['Metal','Gas','Crystal']].sum(axis=1))
    MF2_df.sort_values(by='Total RSS',axis=0,ascending=False,inplace=True)

    MF3_df = pd.DataFrame.from_dict(data=MF3_dict,orient='index')
    MF3_df.insert(loc=4,column='Total RSS',value=MF3_df[['Metal','Gas','Crystal']].sum(axis=1))
    MF3_df.sort_values(by='Total RSS',axis=0,ascending=False,inplace=True)

    MC2_df = pd.DataFrame.from_dict(data=MC2_dict,orient='index')
    MC2_df.insert(loc=3,column='Total RSS',value=MC2_df[['Metal','Gas','Crystal']].sum(axis=1))
    MC2_df.sort_values(by='Total RSS',axis=0,ascending=False,inplace=True)

    MC3_df = pd.DataFrame.from_dict(data=MC3_dict,orient='index')
    MC3_df.insert(loc=3,column='Total RSS',value=MC3_df[['Metal','Gas','Crystal']].sum(axis=1))
    MC3_df.sort_values(by='Total RSS',axis=0,ascending=False,inplace=True)

    MC4_df = pd.DataFrame.from_dict(data=MC4_dict,orient='index')
    MC4_df.insert(loc=3,column='Total RSS',value=MC4_df[['Metal','Gas','Crystal']].sum(axis=1))
    MC4_df.sort_values(by='Total RSS',axis=0,ascending=False,inplace=True)

    MC2np_df = pd.DataFrame.from_dict(data=MC2_dict_noP,orient='index')
    MC2np_df.insert(loc=3,column='Total RSS',value=MC2np_df[['Metal','Gas','Crystal']].sum(axis=1))
    MC2np_df.sort_values(by='Total RSS',axis=0,ascending=False,inplace=True)

    MC3np_df = pd.DataFrame.from_dict(data=MC3_dict_noP,orient='index')
    MC3np_df.insert(loc=3,column='Total RSS',value=MC3np_df[['Metal','Gas','Crystal']].sum(axis=1))
    MC3np_df.sort_values(by='Total RSS',axis=0,ascending=False,inplace=True)

    MC4np_df = pd.DataFrame.from_dict(data=MC4_dict_noP,orient='index')
    MC4np_df.insert(loc=3,column='Total RSS',value=MC4np_df[['Metal','Gas','Crystal']].sum(axis=1))
    MC4np_df.sort_values(by='Total RSS',axis=0,ascending=False,inplace=True)

    HD_df = pd.DataFrame.from_dict(data=HD_dict,orient='index',columns=['Labor'])
    HD_df.sort_values(by='Labor',axis=0,ascending=False,inplace=True)

    moon_df = pd.DataFrame.from_dict(data=moon_dict,orient='index',columns=['Moon Points'])
    moon_df.sort_values(by='Moon Points',axis=0,ascending=False,inplace=True)

    # Print results
    for i in range(top_n):
        print('MF3 spot #{}: {} RSS at ({}, {})'.format(i+1,MF3_df.iloc[i]['Total RSS'],MF3_df.index[i][0],MF3_df.index[i][1]))
    for i in range(top_n):
        print('MF2 spot #{}: {} RSS at ({}, {})'.format(i+1,MF2_df.iloc[i]['Total RSS'],MF2_df.index[i][0],MF2_df.index[i][1]))
    for i in range(top_n):
        print('MF1 spot #{}: {} RSS at ({}, {})'.format(i+1,MF1_df.iloc[i]['Total RSS'],MF1_df.index[i][0],MF1_df.index[i][1]))

    for i in range(top_n):
        print('MC4 spot  #{}: {} RSS at ({}, {})'.format(i+1,MC4np_df.iloc[i]['Total RSS'],MC4np_df.index[i][0],MC4np_df.index[i][1]))
    for i in range(top_n):
        print('MC3 spot #{}: {} RSS at ({}, {})'.format(i+1,MC3np_df.iloc[i]['Total RSS'],MC3np_df.index[i][0],MC3np_df.index[i][1]))
    for i in range(top_n):
        print('MC2 spot #{}: {} RSS at ({}, {})'.format(i+1,MC2np_df.iloc[i]['Total RSS'],MC2np_df.index[i][0],MC2np_df.index[i][1]))

    for i in range(top_n):
        print('MC4 spot w/ Prospect #{}: {} RSS at ({}, {})'.format(i+1,MC4_df.iloc[i]['Total RSS'],MC4_df.index[i][0],MC4_df.index[i][1]))
    for i in range(top_n):
        print('MC3 spot w/ Prospect #{}: {} RSS at ({}, {})'.format(i+1,MC3_df.iloc[i]['Total RSS'],MC3_df.index[i][0],MC3_df.index[i][1]))
    for i in range(top_n):
        print('MC2 spot w/ Prospect #{}: {} RSS at ({}, {})'.format(i+1,MC2_df.iloc[i]['Total RSS'],MC2_df.index[i][0],MC2_df.index[i][1]))


from django.shortcuts import render

# Create your views here.
from rest_framework.response import Response

from oauth.serializers import OauthQQUserSerializer
from oauth.utils import generic_access_token

"""
1. 获取code
2. 通过code换取token
3. 通过token 换去 openid

GET   /oauth/qq/statues/
"""

from rest_framework.views import APIView
from QQLoginTool.QQtool import OAuthQQ
from django.conf import settings
from mall import settings

class OauthQQURLView(APIView):

    def get(self,request):

        state = '/'

        #1.创建oauth对象
        #client_id=None, client_secret=None, redirect_uri=None, state=None
        oauth = OAuthQQ(client_id=settings.QQ_CLIENT_ID,
                        client_secret=settings.QQ_CLIENT_SECRET,
                        redirect_uri=settings.QQ_REDIRECT_URI,
                        state=state)

        #2.调用方法，获取url
        login_url = oauth.get_qq_url()

        return Response({"login_url":login_url})

"""
前段应该 在用户扫描完成之后,跳转到 http://www.meiduo.site:8080/oauth_callback.html?code=6E2E3F64C34ECFE29222EBC390D29196&state=test
把code 传递给后端,

GET     /oauth/qq/users/?code=xxx

# 1.我们获取到这个code, 通过接口来换去 token
# 2.有了token,就可以换取 oepnid

"""
from rest_framework import status
from .models import OAuthQQUser

class OauthQQUserView(APIView):
    def get(self,request):
        code = request.query_params.get('code')

        if code is None:
            return Response(status=status.HTTP_400_BAD_REQUEST)
        #1.我们获取到这个code，通过接口来换取token
        oauth = OAuthQQ(client_id=settings.QQ_CLIENT_ID,
                        client_secret=settings.QQ_CLIENT_SECRET,
                        redirect_uri=settings.QQ_REDIRECT_URI)

        access_token = oauth.get_access_token(code)

        #2.有token就可以换取openid
        openid = oauth.get_open_id(access_token)

        # 3. 我们需要根据openid来进行判断
        # 如果数据库中 有oepnid 则表明用户已经绑定过了
        # 如果数据库中 没有openid 则表明用户没有绑定过了,应该显示绑定界面
        try:
            qquser = OAuthQQUser.objects.get(openid=openid)

        except OAuthQQUser.DoesNotExist:
            #说明没有绑定过
            """
                        1. 需要对敏感数据进行处理
                        2. 数据还需要一个有效期
                        """
            # 我们需要对 openid进行处理
            openid = generic_access_token(openid)
            return Response({'access_token':openid})

        else:

            # 说明存在, 用户已经绑定过来了,绑定过应该登录
            # 既然是登录,则应该返回token
            # 没有异常 走 else

            from rest_framework_jwt.settings import api_settings

            jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
            jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER

            payload = jwt_payload_handler(qquser.user)
            token = jwt_encode_handler(payload)

            return Response({
                'user_id':qquser.user.id,
                'username':qquser.user.username,
                'token':token
            })

    """
    用户点击绑定按钮的时候,前端应该将 手机号,密码,openid,sms_code 发送给后端

    1. 接收数据
    2. 对数据进行校验
        2.1 校验 openid 和sms_code
        2.2 判断手机号
            如果注册过,需要判断 密码是否正确
            如果没有注册过,创建用户
    3. 保存数据
        3.1保存 user 和 openid
    4. 返回响应

    POST

    """
    def post(self,request):
        #1.接收数据
        data = request.data

        #2.对数据进行校验

            #2.1 校验open_id和sms_code
            #2.2 判断手机号
                # 如果注册过，需要判断密码是否正确
                # 如果没有注册过，创建用户
        serializer = OauthQQUserSerializer(data=data)
        serializer.is_valid(raise_exception=True)

        #3.保存数据
        qquser = serializer.save()

        #4.返回响应
        from rest_framework_jwt.settings import api_settings

        jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
        jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER

        payload = jwt_payload_handler(qquser.user)
        token = jwt_encode_handler(payload)

        return Response({
            'user_id': qquser.user.id,
            'username': qquser.user.username,
            'token': token
        })

# 加密签名
# from itsdangerous import JSONWebSignatureSerializer # 错误的
from itsdangerous import TimedJSONWebSignatureSerializer as Serializer
from django.conf import settings

# 1.创建 序列化器
#secret_key             秘钥,一般使用工程的 SECRET_KEY
# expires_in=None       有效期 单位秒
serializer = Serializer(settings.SECRET_KEY,3600)

#2.组织加密数据
data = {'openid':'123456789'}

#3.进行加密处理
token = serializer.dumps(data)

#4.对数据进行解密
serializer.loads(token)

#5.有效期
# serializer = Serializer(settings.SECRET_KEY,1)
#
# data = {'openid':'123456789'}
#
# token = serializer.dumps(data)
#
# #4.对数据进行解密
# serializer.loads(token)


import tensorflow as tf
from keras.models import Sequential, load_model
from keras.layers.core import Dense, Activation, Dropout
from keras.utils import np_utils
from keras.callbacks import CSVLogger, TensorBoard, ModelCheckpoint, EarlyStopping
import pickle
import gzip
import pandas as pd
import numpy as np
import gc
from datetime import date, datetime

from sklearn.utils import shuffle
import sklearn, random
from sklearn import preprocessing
from sklearn.preprocessing import StandardScaler
from keras.models import clone_model
from keras.models import load_model

import scipy.io as si
import argparse
import time

## Dir
runDir = "/xdisk/manojgopale/AES/dataCollection/"

np.random.seed(9)
scaler = StandardScaler()
def process_inputs (data):
	#data = pd.read_csv(dataPath, header=None)
	dataShuffle = shuffle(data)
	x_data_shuffle = dataShuffle[:,0:-1]
	y_data = dataShuffle[:,-1]
	x_data = scaler.fit_transform(x_data_shuffle)
	return x_data, y_data

## config: the configuration for which data is to be generated
## trainSize (4000) : Number of power traces per key to take
def getData(config, trainSize):

	## runDir
	runDir = "/xdisk/manojgopale/AES/dataCollection/"

	## Count for saving files
	count = 0

	## Number of keys to save in one train file
	partLen = 128
	keySize = 256

	## Create output
	inter_y = np.zeros([trainSize,1])
	inter_y[1999] = 1 ## Settting the 2000th data to be '1', which is the the AES trace

	for key in range(keySize):
		## Get 3 random samples for adding train, dev and test to the data
		index = random.sample(range(500), 3)

		## Load each key data for creating the training and testing files
		matStr = runDir + "/matResult/" +  config + "/value" + str(key) + ".mat"
		print("key=%s\nmatStr=%s\n" %(key, matStr))

		## Create intermediate datasets which will be post processed to get data
		## split into 1361 power traces
		interTrain = si.loadmat(matStr)["power"][index[0]]
		interDev =   si.loadmat(matStr)["power"][index[1]]
		interTest =  si.loadmat(matStr)["power"][index[2]]

		## Create data sets, this splits the complete data in 4000 rows with 1361 in each row
		## Each is a wondow of 1361, with step of 1
		interTrainData = interTrain[np.array([range(i, i+1361) for i in range(trainSize)])]
		interDevData =   interDev[np.array([range(i, i+1361) for i in range(trainSize)])]
		interTestData =  interTest[np.array([range(i, i+1361) for i in range(trainSize)])]

		##Append the output's at 2000th location for correct traces
		interTrainData = np.concatenate((interTrainData, inter_y), axis=1)
		interDevData =   np.concatenate((interDevData, inter_y), axis=1)
		interTestData =  np.concatenate((interTestData, inter_y), axis=1)

		## Append inter*Data to coressponding full data.
		if key == 0 or key%partLen == 0:
			fullTrain = interTrainData[:]
			fullDev = interDevData[:]
			fullTest = interTestData[:]
			print("loop1: key=%s" %(key))

		elif key%partLen == partLen-1:
			fullTrain = np.concatenate((fullTrain, interTrainData), axis=0)
			fullDev =   np.concatenate((fullDev, interDevData), axis=0)
			fullTest =  np.concatenate((fullTest, interTestData), axis=0)

			## Save files to csv, so as to use it for portability analysis
			trainSave = runDir + "/processedData/run_1_per_key/data/" + config + "/train_" + str(count) + ".csv"
			devSave   = runDir + "/processedData/run_1_per_key/data/" + config + "/dev_" + str(count) + ".csv"
			testSave  = runDir + "/processedData/run_1_per_key/data/" + config + "/test_" + str(count) + ".csv"

			##Save files
			np.savetxt(trainSave, fullTrain, fmt="%10.5f", delimiter=",")
			np.savetxt(devSave, fullTrain, fmt="%10.5f", delimiter=",")
			np.savetxt(testSave, fullTrain, fmt="%10.5f", delimiter=",")

			## Increment the count variable
			count = count + 1

			print("loop2: key=%s" %(key))
			print("\nSaved data to\n%s\n%s\n%s" %(trainSave, devSave, testSave))

		else:
			fullTrain = np.concatenate((fullTrain, interTrainData), axis=0)
			fullDev =   np.concatenate((fullDev, interDevData), axis=0)
			fullTest =  np.concatenate((fullTest, interTestData), axis=0)
			print("loop3: key=%s" %(key))

		## Clear variables
		interTrain = None
		interDev = None
		interTest = None
		interTrainData = None
		interDevData = None
		interTestData = None

	##Create final datasets
	x_train, y_train = process_inputs(fullTrain)
	x_dev, y_dev = process_inputs(fullDev)
	x_test, y_test = process_inputs(fullTest)

	##Clear fullData variables
	fullTrain = None
	fullDev = None
	fullTest = None

	print("\nCleared fullData variables\n")

	print("Shapes of datasets\nx_train=%s, y_train=%s\nx_dev=%s, y_dev=%s\nx_test=%s, y_test=%s"
	       %(x_train.shape, y_train.shape, x_dev.shape, y_dev.shape, x_test.shape, y_test.shape))

	return (x_train, y_train), (x_dev, y_dev), (x_test, y_test)

class Classifier:
	def __init__(self, resultDir: str, modelName: str, x_train, y_train, x_dev, y_dev, x_test, y_test, hiddenSize):
		""" Initialize parameters and sequential model for training
		"""
		self.resultDir = resultDir
		self.modelName = modelName
		self.x_train = x_train
		self.x_dev = x_dev
		self.x_test = x_test
		self.y_train = y_train
		self.y_dev = y_dev
		self.y_test = y_test
		self.hiddenSize = hiddenSize

		self.dropOut = 0.2

		self.model = Sequential()

		self.model.add(Dense(self.hiddenSize, input_shape=(1361,)))
		self.model.add(Activation('relu'))

		self.model.add(Dropout(self.dropOut))
		self.model.add(Dense(1))
		self.model.add(Activation('sigmoid'))

		self.model.compile(loss='binary_crossentropy', metrics=['binary_accuracy'], optimizer='adam')
		print("Model summary\n")
		print(self.model.summary())

	def train(self, batchSize):
		""" Train the model with the training data
		batchSize : batch size during trainig
		"""

		Epochs = 100

		logFile = self.resultDir + '/' + self.modelName +'.log'
		csv_logger = CSVLogger(logFile, append=True, separator="\t")

		earlyStop = EarlyStopping(monitor='val_binary_accuracy', patience=5, mode='auto', verbose=1, restore_best_weights=True)

		#filePath = self.resultDir + '/' + self.modelName + '_checkPoint_best_model.hdf5'
		### This file will include the epoch number when it gets saved.
		#repeatingFile = self.resultDir + '/' + self.modelName +'_{epoch:02d}_epoch_acc_{accVal:.2f}.hdf5'
		### By default the every_10epochs will save the model at every 10 epochs
		#checkPoint = newCallBacks.ModelCheckpoint_every_10epochs(filePath, repeatingFile, self.x_test, self.y_test , monitor='val_categorical_accuracy', verbose=1, save_best_only=True, every_10epochs=True)

		##Class weights for class imbalanced data
		## https://scikit-learn.org/stable/modules/generated/sklearn.linear_model.LogisticRegression.html
		y = self.y_train.astype(int)

		sampleSize = len(y)
		classNum = len(set(y))

		weight_0 = sampleSize/(classNum * np.bincount(y)[0])
		weight_1 = sampleSize/(classNum * np.bincount(y)[1])

		classWeight = {0: weight_0, 1: weight_1}

		self.history = self.model.fit(self.x_train, self.y_train, batch_size= batchSize, epochs=Epochs, verbose=1, shuffle= True, validation_data=(self.x_dev, self.y_dev), class_weight=classWeight, callbacks=[csv_logger, earlyStop])

	def evaluate(self):
		""" Evaluate the model on itself
		"""

		self.model_score = self.model.evaluate(self.x_test, self.y_test, batch_size=2048)
		print("%s score = %f\n" %(self.modelName, self.model_score[1]))
		return self.model_score

	def saveModel(self):
		""" Save the model
		"""
		saveStr = self.resultDir + '/' + self.modelName +'1HL_' + str(self.hiddenSize) + '_' + str(self.history.epoch[-1]+1) + 'epochs_' + str(self.dropOut).replace('.', 'p') + 'Dropout_' + '{0:.2f}'.format(self.model_score[1]*100).replace('.', 'p') + '.h5'
		print("Saving model to\n%s\n" %(saveStr))
		self.model.save(saveStr)


import unittest

from ecotricity.client.dto import MeterPoint

class TestMeterPoint(unittest.TestCase):

    def test_deserialisation(self):
        json = '{"industryId":"1234567890","fuelType":"gas"}'
        entity = MeterPoint.from_json(json)
        self.assertEqual(entity.industry_id, "1234567890")
        self.assertEqual(entity.fuel_type, "gas")


from cgitb import text
from email.mime import image
import tkinter as tk
import cryptocompare as cc
from PIL import Image,ImageTk
import time

from numpy import True_

class Convert(tk.Tk):
    def __init__(self):

        super().__init__()
        self.title('Convert')
        self.geometry('300x120')
        self.resizable(False, False)
        self.result = 0
        self.ecuacion = ''
        self.valueChange = True

        self.main_frame = tk.Frame(self)
        self.main_frame.pack()

        fecha = time.strftime('%Y-%m-%d %H:%M:%S')
        self.time_label = tk.Label(self.main_frame, text=fecha)
        self.time_label.grid(row=0, column=1, columnspan=2)
        self.after(1000, self.update_time)

        self.coin_label = tk.Label(self.main_frame, text='Coin: ')
        self.coin_label.grid(row=1, column=0)
        self.coin_entry = tk.Entry(self.main_frame, width=10, justify='center')
        self.coin_entry.grid(row=1, column=1)

        self.buttonChange = tk.Button(self.main_frame,text='coin -> currency', command=lambda: self.change())
        self.buttonChange.grid(row=1, column=2, columnspan=2)

        self.currency_label = tk.Label(self.main_frame, text='Currency: ')
        self.currency_label.grid(row=2, column=0)
        self.currency_entry = tk.Entry(self.main_frame, width=10, justify='center')
        self.currency_entry.grid(row=2, column=1)

        self.amount_currency_label = tk.Label(self.main_frame, text='amount: ')
        self.amount_currency_label.grid(row=2, column=2)
        self.amount_currency_entry = tk.Entry(self.main_frame, width=10, justify='center')
        self.amount_currency_entry.grid(row=2, column=3)

        self.button = tk.Button(self.main_frame,text="Convert", command=self.convert)
        self.button.grid(row=3, column=1, columnspan=2)

        self.ecuacion_label = tk.Label(self.main_frame, text=self.ecuacion)
        self.ecuacion_label.grid(row=4, column=0, columnspan=4)

        self.mainloop()

    def change(self):
        self.valueChange = not self.valueChange
        if self.valueChange:
            self.buttonChange.config(text='coin -> currency')

        else:
            self.buttonChange.config(text='currency -> coin')

    def update_time(self):
        self.time_label.config(text=time.strftime('%Y-%m-%d %H:%M:%S'))
        self.after(1000, self.update_time)

    def convert(self):
        self.contadorInicio = time.time()
        coin = self.coin_entry.get()
        currency = self.currency_entry.get()
        price = cc.get_price(coin, currency)
        price = price[coin.upper()][currency.upper()]

        amount_currency = self.amount_currency_entry.get()
        if self.valueChange:
            self.result = float(amount_currency) / float(price)
            self.result = round(self.result, 10)
            self.ecuacion = f'{amount_currency} {currency} = {self.result} {coin}'
        else:
            self.result = float(amount_currency) * float(price)
            self.result = round(self.result, 10)
            self.ecuacion = f'{amount_currency} {coin} = {self.result} {currency}'

        self.ecuacion_label.config(text=self.ecuacion)

# Main
if __name__ == '__main__':
    Convert()


from django.test import TestCase
from edc_dashboard.url_names import url_names

from ...wrappers import ModelWrapper
from ..models import Example, ParentExample

class TestFields(TestCase):
    @classmethod
    def setUpClass(cls):
        url_names.register("thenexturl", "thenexturl", "edc_model_wrapper")
        return super().setUpClass()

    @classmethod
    def tearDownClass(cls):
        url_names.registry.pop("thenexturl")
        super(TestFields, cls).tearDownClass()

    def test_fields_skips_example(self):
        model_obj = ParentExample.objects.create()
        wrapper = ModelWrapper(
            model_obj=model_obj, model_cls=ParentExample, next_url_name="thenexturl"
        )

        self.assertNotIn("example", dict(wrapper.field_values_as_strings))

    def test_fields_rel(self):
        model_obj = Example.objects.create()
        wrapper = ModelWrapper(
            model_obj=model_obj, model_cls=Example, next_url_name="thenexturl"
        )
        dct = wrapper.field_values_as_strings
        for k, v in dct:
            if k == "id":
                self.assertEqual(v, model_obj.pk)

    def test_fields_rel2(self):
        model_obj = ParentExample.objects.create()
        wrapper = ModelWrapper(
            model_obj=model_obj, model_cls=ParentExample, next_url_name="thenexturl"
        )
        dct = wrapper.field_values_as_strings
        for k, v in dct:
            if k == "id":
                self.assertEqual(v, model_obj.pk)


import re #import Regular expression
#Workshop 1 exercises: Getting to know Python - part I
#link for the questions:https://www.cs.helsinki.fi/u/owaltari/distsys/ws1/dist_sys_ws1.html

#1.Looping and printing
#Write code that prints every integer between 0 and 20
def wrapperFunction():# This function wrap up all the functions
	print("Workshop 1 exercises: Getting to know Python - part I")
	print("Hello, Helsinki University")
	for num in range(21):
		print(num)

	#2.Defining functions
	#Modify the previous code and define the code snippet as a function.
	#Also, put the numbers into an array instead of printing.
	#The function should take no input parameters and return an array.
	#Call the function and print the output (i.e. print(my_function()))

	def printZeroToTwenty():
		numbers = []
		for num in range(21):
			numbers.append(num)
		return numbers
	print(printZeroToTwenty())
	#3. Reverse and return

	#Define a function that takes an array as an input parameter.
	#Return a reverse array of the input array.
	#(You may also reverse the original array in-place.
	#Just make sure you know which way you're doing it.)
	def reverseArray(arr):
		newArray = []
		for i in range(len(arr)):
			newArray.append(arr[len(arr)-i-1])

		return newArray
	print(reverseArray([5,4,3,2,1]))

	#4.Writing to files
	#Define a function that:
	#Takes an array as an input parameter
	#Opens a file
	#Writes each value from the input array to the file
	#Closes the file

	def writeArrayValueIntoFile(arr):
		f = open('text-example','w')
		for i in range(len(arr)):
			f.write(str(arr[i]))
		f.close()
	writeArrayValueIntoFile([10,20,30,40,50])

	#5.Define a function that:
	#Opens a file. Give the filename as a parameter
	#Reads the file line by line and parse for an integer on each line (Beware of newline characters in line-by-line reading!)
	#Sum all integers you read from the file
	#Return the

	def openFileAndReadLineByLine():
		sum = 0
		lines = 0
		fname = input('enter file name:')
		try:
			fopen = open(fname)
		except:
			print('file was not found!')
			exit()

		for line in fopen:
			if(line):
				numbers = re.findall(r'\d+', line.strip())
				print(numbers)
				lines+=1
		for num in numbers:
			print(int(num))
			sum+=int(num)
		return "The sum is " + str(sum)
	print(openFileAndReadLineByLine())
	#6.Write a main function (wrapping everything up)
	#Define a main function and perform the following using the functions you have defined:
	#Create an array with numbers from 0 to 20i
	#Reverse the array
	#Write the array into a file
	#Read the file and calculate the sum
wrapperFunction()


import numpy as np
import matplotlib.pyplot as plt

class PathVisualizer(object):
    """Helper class to visualize the path, query and grid."""

    @staticmethod
    def viz_path(grid, query, path):
        plt.axis([0, grid.shape[0], 0, grid.shape[1]])
        plt.scatter(np.where(grid)[0] + 0.5, np.where(grid)[1] + 0.5, s=65, marker='s')

        for wp in path:
            switch = {
                0: (0, 0.25),
                1: (0.25, 0),
                2: (0, -0.25),
                3: (-0.25, 0)
            }
            plt.arrow(wp.x, wp.y, *switch[wp.orientation], width=0.02, capstyle='projecting')
            plt.text(wp.x + 0.3, wp.y + 0.3, str(wp.tuple))
            if wp == query[0]:
                plt.text(wp.x - 0.3, wp.y - 0.3, 'START')
            if wp == query[1]:
                plt.text(wp.x + 0.3, wp.y - 0.3, 'END')

        plt.ion()
        plt.show()
        raw_input("Press Enter to close plot...")
        plt.close()


from cv2 import cv2
import numpy as np
import copy
import statistics
import extract_graph
import get_graph_dimentions

img = cv2.imread('sample_graph.jpg')

x_domain, y_domain, left, right, top, bottom = get_graph_dimentions.get_dim(img)
# print(x_domain, y_domain)
# print(left, right, top, bottom)

graph = extract_graph.extract(img, left, right)
cv2.imshow('graph', graph)
cv2.waitKey(0)

# cv2.rectangle(img, (left, top), (right, bottom), (0, 255, 0))
# cv2.imshow('img', img)
# cv2.waitKey(0)

readings = {}
xy = {}

gray = cv2.cvtColor(graph, cv2.COLOR_BGR2GRAY)

for time in range(x_domain):
    bpm = 0
    x = int((time / x_domain) * (right - left))
    col = list(gray[:, x])
    pixel = min(col)
    # print(pixel)
    pts = [i for i, x in enumerate(col) if x == pixel]
    y = statistics.mean(pts)
    # print(y)
    bpm = 50 + ((bottom - y) / (bottom - top)) * y_domain
    readings[time] = bpm
    xy[x] = int(y)

# Display points
for x, y in xy.items():
    cv2.circle(graph, (x, y), 2, (0, 255, 0))

cv2.imshow('graph', graph)
cv2.waitKey(0)
cv2.destroyAllWindows()

# time = int(input("Enter time: "))
# print(readings[time], 'bpm')


def main():
    import datetime
    mes = int(input())
    mes_requerido = datetime.datetime(year=2020, month=mes, day=20)
    mes_formatado = mes_requerido.strftime('%B')
    print(mes_formatado)

if __name__ == '__ main__':
    main()


import socket
from datetime import datetime
from time import time, sleep
from numpipe import config
import matplotlib.pyplot as plt
import matplotlib as mpl

DEFAULT_DELAY = config.get_config()['notifications']['delay_default']

def get_bot_token():
    """get bot token from config file"""
    return config.get_config()['notifications']['telegram']['token']

def get_chat_id():
    """get chat ID from config file"""
    return config.get_config()['notifications']['telegram']['chat_id']

def notifications_active():
    """check whether notifications can be sent based on the config file"""
    return get_bot_token() and get_chat_id()

def generate_time_str(time):
    """convert time (in seconds) to a text string"""
    hours = int(time // 60**2)
    minutes = int((time - hours*60**2) // 60)
    seconds = int((time - hours*60**2 - minutes*60) // 1)

    ret = ''
    if hours:
        unit = 'hr' if hours == 1 else 'hrs'
        ret += f'{hours} {unit} '
    if minutes:
        unit = 'min' if minutes == 1 else 'mins'
        ret += f'{minutes} {unit} '

    if not (hours and minutes):
        unit = 'sec' if seconds == 1 else 'secs'
        ret += f'{seconds} {unit}'

    return ret.strip()

def check_idle_matplotlib(delay=DEFAULT_DELAY, check_every=.5):
    """
    Check if the user is idle based on matplotlib plot interactions (mouse move, key press, window interactions)

    Arguments:
        delay         time (in seconds) to check before declaring idle
        check_every   time (in seconds) between interaction checks
    """
    nfigures_before = len(plt.get_fignums())
    if not nfigures_before:
        raise RuntimeError('cannot check for user idleness if there are no figures')

    mouse_moved = False
    key_pressed = False
    def on_mouse_movement(event):
        nonlocal mouse_moved
        mouse_moved = True

    def on_key_press(event):
        nonlocal key_pressed
        key_pressed = True

    fig = plt.figure(nfigures_before)
    cid = fig.canvas.mpl_connect('motion_notify_event', on_mouse_movement)
    cid = fig.canvas.mpl_connect('key_press_event', on_key_press)

    t_start = time()
    while time() - t_start < 1:
        sleep(.01)
        if not plt.get_fignums():
            return

    backend = mpl.get_backend()
    qt_backends = ('Qt4Agg', 'Qt5Agg')
    if backend in qt_backends:
        x0 = fig.canvas.manager.window.x()
        y0 = fig.canvas.manager.window.y()
        w0 = fig.canvas.manager.window.size()

    t_start = time()
    while time() - t_start < delay:
        sleep(check_every)
        if len(plt.get_fignums()) != nfigures_before:
            return False
        if mouse_moved:
            return False
        if key_pressed:
            return False

        if backend in qt_backends:
            if not fig.canvas.manager.window.isActiveWindow():
                return False

            x = fig.canvas.manager.window.x()
            y = fig.canvas.manager.window.y()
            w = fig.canvas.manager.window.size()

            if x != x0 or y != y0:
                return False

            if w != w0:
                return False

    return True

def send_message(message):
    """send a text message"""
    from telegram import Bot, ParseMode
    bot = Bot(token=get_bot_token())
    bot.send_message(chat_id=get_chat_id(), text=message, parse_mode=ParseMode.MARKDOWN)

def send_message_from(message, filename):
    """send a text message with """
    from telegram import Bot, ParseMode

    host = socket.gethostname()
    message = f'*{message}*' + f'\n_{host}:{filename}_'

    bot = Bot(token=get_bot_token())
    bot.send_message(chat_id=get_chat_id(), text=message, parse_mode=ParseMode.MARKDOWN)

def send_finish_message(filename, njobs, time, num_exceptions):
    """send a text message summarizing the jobs that ran

    Arguments:
        filename     name of the python file
        njobs        number of jobs ran
        time         runtime of the jobs
        num_exceptions   number of jobs that threw exceptions
    """
    host = socket.gethostname()
    time_str = generate_time_str(time)
    tab = '    '

    if num_exceptions:
        status = f'{num_exceptions}/{njobs} failures'
    else:
        status = 'success'

    date = datetime.now().strftime("%H:%M %d-%m-%Y")

    text = f'''`Simulation finished:
{tab}filename___{filename}.py
{tab}status_____{status}
{tab}host_______{host}
{tab}njobs______{njobs}
{tab}runtime____{time_str}
{tab}date_______{date}`
'''
    send_message(text)

def send_images(filename, exempt=[]):
    """send images (from matplotlib)

    Arguments:
        filename     name of the python file (without .py extension)
        exempt       (optional) a list of figure numbers to not send
    """
    if not plt.get_fignums():
        return

    from telegram import Bot, ChatAction, InputMediaPhoto
    from io import BytesIO
    bot = Bot(token=get_bot_token())
    chat_id = get_chat_id()

    send_action = lambda: bot.send_chat_action(chat_id=chat_id, action=ChatAction.UPLOAD_PHOTO)
    send_action()
    media = []

    num_figs = 0
    t_start = time()
    for i in plt.get_fignums():
        fig = plt.figure(i)
        if fig.number in exempt:
            continue

        caption = f'{filename}-fig{i}'

        bio = BytesIO()
        bio.name = f'fig{i}.png'
        fig.savefig(bio, format='png')
        bio.seek(0)
        media.append(InputMediaPhoto(bio, caption=caption))
        plt.close(fig)

        num_figs += 1
        if num_figs == 10:
            num_figs = 0
            bot.send_media_group(chat_id, media=media)
            media = []

        if time() - t_start > 7:
            send_action()
            t_start = time()

    if num_figs:
        bot.send_media_group(chat_id, media=media)

def send_videos(anims):
    """send a set of animations

    Arguments:
        anims    list of lists of the animations (each embedded list must share the same figure)
    """
    if not anims:
        return

    from telegram import Bot
    import tempfile
    plt.close('all')

    bot = Bot(token=get_bot_token())
    chat_id = get_chat_id()

    with tempfile.TemporaryDirectory() as direc:
        for i,anim_list in enumerate(anims):
            plt.close(anim_list[0]._fig)
            filepath = f'{direc}/vid{i}.mp4'
            send_animation(bot, chat_id, anim_list, filepath)
            bot.send_video(chat_id, video=open(filepath, 'rb'))

def send_animation(bot, chat_id, anim_list, filepath, *args, **kwargs):
    """send a single animation for a given bot and chat_id

    Arguments:
        bot         telegram bot
        chat_id     telgram chat id
        anim_list   list of animations (belonging to the same figure)
        filepath    filepath the animation will be saved to
        *args       additional arguments to pass to anim.save
        **kwargs    additional key-word arguments to pass to anim.save
    """
    from telegram import ChatAction
    anim  = anim_list[0]
    send_action = lambda: bot.send_chat_action(chat_id=chat_id, action=ChatAction.UPLOAD_VIDEO)

    store_func = anim._func
    t_start = time()
    send_action()
    def wrapper(*args):
        nonlocal t_start
        if time() - t_start > 7:
            send_action()
            t_start = time()
        return store_func(*args)
    anim._func = wrapper

    anim.save(filepath, extra_anim=anim_list[1:], *args, **kwargs)
    anim._func = store_func

def send_notifications(notifications, delay=DEFAULT_DELAY, check_idle=True, idle=False):
    """send a collection of notifications

    Arguments:
        notifications      list of functions to call that send notifications (no arguments)
        delay              time (in seconds) to check if the user is idle before notifying
        check_idle         whether or not to check if the user is idle (default: True)
        idle               whether or not the user is idle now (default: False)

    """
    if not notifications_active():
        return

    if check_idle:
        idle = check_idle_matplotlib(delay=delay)

    if idle:
        for notification in notifications:
            notification()


# https://medium.com/@hiimdaosui/remove-linked-list-elements-6ec6b7560327
class RNode:
    def __init__(self, data):
        self.next = None
        # self.prev = None
        self.data = data
        self.next = None

class RecursiveLinkedList:
    def __init__(self) -> None:
        self.head = None
        self.tail = None

    def traverse(self):
        copy = self.head
        while copy is not None:
            print(copy.data)
            copy = copy.next

    def is_empty(self):
        return self.size() == 0

    def add(self, item):
        # Send in new node with data and the head node
        self.add_recur(RNode(item), self.head)

    def add_recur(self, new_node, curr):
        if self.is_empty():
            self.head = new_node
            return

        elif not curr.next:
            curr.next = new_node
            return
        return self.add_recur(new_node, curr.next)

    def size(self):
        copy = self.head
        count = 0
        while copy is not None:
            count += 1
            #print(copy.data)
            copy = copy.next
        return count

    def remove(self, key):
        """
        @param: key -> the data on the target node
        """
        # Go through the list and find the correct node
        # take a copy of the prev node and next node of the node we remove
        # set copy.prev == copy.next, target.next, target.prev
        # return the new list and update head
        # There needs to be a special case for the head node
        copy = self.head
        rest = self.head
        if copy is not None:
            if copy.data == key:
                self.head = copy.next
        while copy is not None:
            if copy.data == key:
                break
            prev = copy
            copy = copy.next
            prev.next = copy.next
            copy = None

if __name__ == '__main__':
    item = RecursiveLinkedList()
    print(item.is_empty())
    item.add("Hello")
    item.add("Hello1")
    item.add("Hello2")
    item.remove("Hello")
    item.traverse()


from calendar import monthrange

m = int(input('Month: '))
y = int(input('Year: '))

f, n = monthrange(y, m)

print(' S  T  Q  Q  S  S  D')
print('         ')

for d in range(1, n+1):
	print(f'{d:2} ', end='')
	f += 1

	if f > 6:
		f = 0
		print()
print()


import patterns, include, url

from django.contrib import admin
admin.autodiscover()

urlpatterns = patterns('',
    # Examples:
    # url(r'^$', 'djtwilio.views.home', name='home'),
    # url(r'^blog/', include('blog.urls')),

    url(r'^admin/', include(admin.site.urls)),

    # Here we add our Twilio URLs
    url(r'^sms/$', 'djtwilio.views.sms'),
    url(r'^ring/$', 'djtwilio.views.ring'),
)

# # -*- coding: utf-8 -*-
# from django_twilio.decorators import twilio_view
# from twilio.twiml.messaging_response import MessagingResponse

# @twilio_view
# def sms(request):
#     r = Response()
#     r.message('Hello from your Django app!')
#     return r


from __future__ import annotations
from typing import TYPE_CHECKING, Optional
import logging
import math

from ezdxf.math import Vec2, UCS, NULLVEC
from ezdxf.lldxf import const
from ezdxf.entities import DimStyleOverride, Dimension
from .dim_base import (
    BaseDimensionRenderer,
    get_required_defpoint,
    compile_mtext,
)

if TYPE_CHECKING:
    from ezdxf.eztypes import GenericLayoutType

__all__ = ["OrdinateDimension"]
logger = logging.getLogger("ezdxf")

class OrdinateDimension(BaseDimensionRenderer):
    # Required defpoints:
    # defpoint = origin (group code 10)
    # defpoint2 = feature location (group code 13)
    # defpoint3 = end of leader (group code 14)
    # user text location is ignored (group code 11) and replaced by default
    # location calculated by the ezdxf renderer:

    def __init__(
        self,
        dimension: Dimension,
        ucs: Optional[UCS] = None,
        override: Optional[DimStyleOverride] = None,
    ):
        # The local coordinate system is defined by origin and the
        # horizontal_direction in OCS:
        self.origin_ocs: Vec2 = get_required_defpoint(dimension, "defpoint")
        self.feature_location_ocs: Vec2 = get_required_defpoint(
            dimension, "defpoint2"
        )
        self.end_of_leader_ocs: Vec2 = get_required_defpoint(
            dimension, "defpoint3"
        )
        # Horizontal direction in clockwise orientation, see DXF reference
        # for group code 51:
        self.horizontal_dir = -dimension.dxf.get("horizontal_direction", 0.0)
        self.rotation = math.radians(self.horizontal_dir)
        self.local_x_axis = Vec2.from_angle(self.rotation)
        self.local_y_axis = self.local_x_axis.orthogonal()
        self.x_type = bool(  # x-type is set!
            dimension.dxf.get("dimtype", 0) & const.DIM_ORDINATE_TYPE
        )
        super().__init__(dimension, ucs, override)

        # Measurement directions can be opposite to local x- or y-axis
        self.leader_vec_ocs = self.end_of_leader_ocs - self.feature_location_ocs
        leader_x_vec = self.local_x_axis.project(self.leader_vec_ocs)
        leader_y_vec = self.local_y_axis.project(self.leader_vec_ocs)
        try:
            self.measurement_direction: Vec2 = leader_x_vec.normalize()
        except ZeroDivisionError:
            self.measurement_direction = Vec2(1, 0)
        try:
            self.measurement_orthogonal: Vec2 = leader_y_vec.normalize()
        except ZeroDivisionError:
            self.measurement_orthogonal = Vec2(0, 1)

        if not self.x_type:
            self.measurement_direction, self.measurement_orthogonal = (
                self.measurement_orthogonal,
                self.measurement_direction,
            )

        self.update_measurement()
        if self.tol.has_limits:
            self.tol.update_limits(self.measurement.value)

        # Text width and -height is required first, text location and -rotation
        # are not valid yet:
        self.text_box = self.init_text_box()

        # Set text location and rotation:
        self.measurement.text_location = self.get_default_text_location()
        self.measurement.text_rotation = self.get_default_text_rotation()

        # Update text box location and -rotation:
        self.text_box.center = self.measurement.text_location
        self.text_box.angle = self.measurement.text_rotation
        self.geometry.set_text_box(self.text_box)

        # Update final text location in the DIMENSION entity:
        self.dimension.dxf.text_midpoint = self.measurement.text_location

    def get_default_text_location(self) -> Vec2:
        if self.x_type:
            text_vertical_shifting_dir = -self.local_x_axis
        else:
            text_vertical_shifting_dir = self.local_y_axis

        # user text location is not supported and ignored:
        return (
            self.end_of_leader_ocs
            + self.measurement_orthogonal * (self.text_box.width * 0.5)
            + text_vertical_shifting_dir
            * self.measurement.text_vertical_distance()
        )

    def get_default_text_rotation(self) -> float:
        # user text rotation is not supported and ignored:
        return (90.0 if self.x_type else 0.0) + self.horizontal_dir

    def update_measurement(self) -> None:
        feature_location_vec: Vec2 = self.feature_location_ocs - self.origin_ocs
        # ordinate measurement is always absolute:
        self.measurement.update(
            self.local_x_axis.project(feature_location_vec).magnitude
            if self.x_type
            else self.local_y_axis.project(feature_location_vec).magnitude
        )

    def get_defpoints(self) -> list[Vec2]:
        return [
            self.origin_ocs,
            self.feature_location_ocs,
            self.end_of_leader_ocs,
        ]

    def transform_ucs_to_wcs(self) -> None:
        """Transforms dimension definition points into WCS or if required into
        OCS.
        """

        def from_ucs(attr, func):
            point = dxf.get(attr, NULLVEC)
            dxf.set(attr, func(point))

        dxf = self.dimension.dxf
        ucs = self.geometry.ucs
        from_ucs("defpoint", ucs.to_wcs)
        from_ucs("defpoint2", ucs.to_wcs)
        from_ucs("defpoint3", ucs.to_wcs)
        from_ucs("text_midpoint", ucs.to_ocs)

        # Horizontal direction in clockwise orientation, see DXF reference
        # for group code 51:
        dxf.horizontal_direction = -ucs.to_ocs_angle_deg(self.horizontal_dir)

    def render(self, block: GenericLayoutType) -> None:
        """Main method to create dimension geometry of basic DXF entities in the
        associated BLOCK layout.

        Args:
            block: target BLOCK for rendering

        """
        super().render(block)
        self.add_ordinate_leader()
        measurement = self.measurement
        if measurement.text:
            if self.geometry.supports_dxf_r2000:
                text = compile_mtext(measurement, self.tol)
            else:
                text = measurement.text
            self.add_measurement_text(
                text, measurement.text_location, measurement.text_rotation
            )
        self.geometry.add_defpoints(self.get_defpoints())

    def add_ordinate_leader(self) -> None:
        # DXF attributes from first extension line not from dimension line!
        attribs = self.extension_lines.dxfattribs(1)
        # The ordinate leader is normal to the measurement direction.
        # leader direction and text direction:
        direction = self.measurement_orthogonal
        leg_size = self.arrows.arrow_size * 2.0
        #            /---1---TEXT
        # x----0----/
        # d0 = distance from feature location (x) to 1st upward junction
        d0 = direction.project(self.leader_vec_ocs).magnitude - 2.0 * leg_size

        start0 = (
            self.feature_location_ocs + direction * self.extension_lines.offset
        )
        end0 = self.feature_location_ocs + direction * max(leg_size, d0)
        start1 = self.end_of_leader_ocs - direction * leg_size
        end1 = self.end_of_leader_ocs
        if self.measurement.vertical_placement != 0:
            end1 += direction * self.text_box.width

        self.add_line(start0, end0, dxfattribs=attribs)
        self.add_line(end0, start1, dxfattribs=attribs)
        self.add_line(start1, end1, dxfattribs=attribs)

    def add_measurement_text(
        self, dim_text: str, pos: Vec2, rotation: float
    ) -> None:
        """Add measurement text to dimension BLOCK.

        Args:
            dim_text: dimension text
            pos: text location
            rotation: text rotation in degrees

        """
        attribs = self.measurement.dxfattribs()
        self.add_text(dim_text, pos=pos, rotation=rotation, dxfattribs=attribs)