from sqlalchemy import BigInteger,Column,Integer,SmallInteger,Unicode

from .PublicModel import ModelPublic

class ModelUser(ModelPublic):
    __tablename__ = "t_cyuser"
    Deptid = Column(BigInteger, index=True, comment="用户所在部门的ID", doc="用户所在部门的ID")
    NoCard = Column(Unicode(32), index=True, comment="卡号", doc="卡号，不能超过15字符")
    NoUser = Column(
        Unicode(32), index=True, comment="账号（学工号）", doc="这是账号（学工号），不能超过15字符"
    )
    NoSfz = Column(BigInteger, index=True, comment="身份证号", doc="身份证号")
    Name = Column(Unicode(32), index=True, comment="用户名", doc="这是用户名，不能超过15字符")
    Psw = Column(Unicode(32), index=True, comment="密码", doc="密码，不能超过15字符")
    Sex = Column(SmallInteger, index=True, comment="用户性别", doc="这是用户性别，0 女，1 男")
    Attr = Column(
        SmallInteger,
        index=True,
        comment="用户管理权限",
        doc="这是用户属性，表示用户的管理权限，0 普通用户，1 管理员，2 超级管理员（可对管理员进行控制）",
    )
    AttrJf = Column(
        SmallInteger,
        index=True,
        comment="机房管理权限",
        doc="这是用户属性，表示机房管理权限，0 普通用户，1 管理员，2 超级管理员（可对管理员进行控制）",
    )
    Power = Column(
        SmallInteger,
        index=True,
        comment="未知",
        doc="未知，可选值为0，2，85，127",
    )
    PowerJf = Column(
        SmallInteger,
        index=True,
        comment="未知",
        doc="未知，可选值为0，8，10",
    )
    Email = Column(Unicode(254), index=True)
    Phone = Column(Integer, index=True)
    Yue = Column(Integer, comment="用户余额1", doc="这是用户余额1，单位为分（默认）")
    Yue2 = Column(Integer, comment="用户余额2", doc="这是用户余额2，单位为分（扩展于特殊需求）")
    LocalID = Column(Unicode(1024), comment="管理房间的ID列表", doc="管理房间的ID列表")


# 도시: 그래프의 노드, A -> B로 가는 버스를 사용할 때 필요한 비용이 c라고 하면
# : A -> B로의 가중치 c의 간선
# 모든 노드 -> 모든 노드로 가는 최단 거리를 구해준다.
# 플로이드워셜 알고리즘 사용
INF = int(1e9)
n = int(input())
k = int(input())
distance = [[INF] * n for _ in range(int(n))]
for i in range(n):
    distance[i][i] = 0

for _ in range(k):
    a, b, w = map(int, input().split())
    if distance[a - 1][b - 1] > w:
        distance[a - 1][b - 1] = w
for k in range(n):
    for a in range(n):
        for b in range(n):
            distance[a][b] = min(distance[a][b], distance[a][k] + distance[k][b])

for i in range(n):
    print(" ".join(map(str, distance[i])).replace(str(INF), "0"))


import random
from enum import IntEnum
from pathlib import Path
import json
from pprint import pprint
from collections import namedtuple

from flask import (
    Flask,
    request,
    jsonify,
    send_from_directory,
    abort,
)
from flask_cors import CORS

APP = Flask(__name__)
CORS(APP)

FILE_DIR = Path(__file__).parent.absolute()
CARDS = open(FILE_DIR / 'cards').read().splitlines()
TABLES = {
    # table_key: table_state
}

@APP.route('/')
def index_html():
    print("yeah", FILE_DIR)
    return send_from_directory(FILE_DIR / 'static', "index.html")

class GameState(IntEnum):
    T1_explains = 0
    T1_guess = 1
    T2_explains = 2
    T2_guess = 3
    Game_END = 4

def team_no_and_guess_from_game_state(gs):
    team_no, guess = gs//2 + 1, bool(1 - gs%2)
    return team_no, guess

def advance_game_state(gs):
    return (gs + 1) % 4

@APP.route('/new_tipp/<table_key>/<team>', methods=['POST'])
def new_tipp(table_key, team):
    table_state = TABLES.get(table_key, new_table(table_key))
    TABLES[table_key] = table_state

    print(f'new_tipp {table_key} {team}')

    new_tipp = request.json["new_tipp"]
    table_state["tipps"].append(new_tipp)

    table_state["game_state"] = advance_game_state(table_state["game_state"])

    pprint(table_state)
    return jsonify(table_state)

@APP.route('/reset/<table_key>')
def reset(table_key):
    print(f'RESET {table_key}')
    del TABLES[table_key]
    table_state = TABLES.get(table_key, new_table(table_key))

    pprint(table_state)
    return jsonify(table_state)

@APP.route('/stop_guessing/<table_key>')
def stop_guessing(table_key):
    print(f'stop guessing {table_key}')
    table_state = TABLES.get(table_key, new_table(table_key))
    TABLES[table_key] = table_state

    table_state["game_state"] = advance_game_state(table_state["game_state"])

    pprint(table_state)
    return jsonify(table_state)

@APP.route('/guess/<table_key>/<int:row>/<int:col>', methods=['GET'])
def guess(table_key, row, col):
    table_state = TABLES.get(table_key, new_table(table_key))
    TABLES[table_key] = table_state

    print(f'guess {table_key} {row} {col}')

    card_id = row * 5 + col

    card = table_state['cards'][card_id]
    gs = table_state["game_state"]
    team_no, guess = team_no_and_guess_from_game_state(gs)
    if card["solution"] == team_no:
        # revealed card was correct, no change of game_state
        pass
    elif card["solution"] == 3:
        # bomb was revealed -> game ends
        gs = 4
    else:
        # revealed card was incorred
        gs = advance_game_state(gs)

    card["revealed"] = True
    table_state["game_state"] = gs

    pprint(table_state)
    return jsonify(table_state)

@APP.route('/table/<table_key>', methods=['GET'])
def table(table_key=None):
    table_state = TABLES.get(table_key, new_table(table_key))
    TABLES[table_key] = table_state

    pprint(table_state)
    return jsonify(table_state)

def new_table(table_key):
    random.seed(table_key)
    table_cards = random.sample(CARDS, 25)

    start_team = random.randint(1, 2)  # 1 or 2
    other_team = 3 - start_team        # 2 or 1

    # Team 1: 1, Team 2: 2, Neutral: 0 , Bomb: 3
    table_solution = [3] + [0]*7 + [start_team]*9 + [other_team]*8
    random.shuffle(table_solution)

    revealed = [False]*25

    game_state = GameState.T1_explains if start_team == 1 else GameState.T2_explains

    cards = []
    for i, card_text in enumerate(table_cards):
        cards.append({
            "text": card_text,
            "revealed": revealed[i],
            "solution": table_solution[i],
        })

    table_state = {
        'key': table_key,
        'start_team': start_team,
        'game_state': game_state.value,
        "cards": cards,
        "tipps": []
    }
    return table_state

if __name__ == '__main__':

    APP.run(
        host='0.0.0.0',
        # host='127.0.0.1',
        port=8080,
        debug=True,
    )


import os
import warnings
import requests
from time import sleep
from pathlib import Path
from typing import List, Dict, Any, Optional
from pandas import DataFrame, read_json
from tqdm import tqdm
from bs4 import BeautifulSoup
from bs4.element import Tag
from dotenv import load_dotenv
from recsys.utils import send_request, create_logger

warnings.filterwarnings('ignore')

BAR_FORMAT = '{percentage:3.0f}%|{bar:20}{r_bar}'
COLUMNS = [
    'title_id',
    'text',
    'rating',
    'date',
    'title',
    'author',
    'helpfulness'
]
USER_AGENT = (
    'Mozilla/5.0 (Windows NT 6.1)'
    'AppleWebKit/537.36 (KHTML, like Gecko)'
    'Chrome/88.0.4324.150 Safari/537.36'
)
START_URL_TEMPLATE = (
    'https://www.imdb.com{}reviews?sort=helpfulnessScore'
    '&dir=desc&ratingFilter=0'
)
LINK_URL_TEMPLATE = (
    'https://www.imdb.com{}reviews/_ajax/?sort=helpfulnessScore'
    '&dir=desc&ratingFilter=0'
)

class ReviewCollector:
    """
    Contains methods for parsing IMDB movie reviews.

    Public methods:
        * collect_review: parses reviews of a given movie.
        * find_reviews_num: finds number of reviews for a given movie.
        * is_all_reviews_collected: check if there any title we can scrape
        details about.
        * collect: parses pages and saves IDs on a disk or cloud.
    """
    def __init__(self, config: Dict[str, Any]):
        """
        Initializes Review Collector class. All parameters related to web
        scraping of movie reviews must be specified in config.

        The config must contains the following fields:
        * mode: specifies where the results should be saved. When set up to
        'local' all movie related data will be saved on local machine, where
        application is running. When set up to 'cloud' related data saves on
        AWS. Using 'cloud' mode you also need to set up the following
        environment variables: AWS_SECRET_ACCESS_KEY, AWS_ACCESS_KEY and
        AWS_S3_BUCKET.

        * metadata_file: name of file (possibly with folder) movies metadata
        will be saved to.

        * n_reviews: maximum number of reviews to scrape for a given movie.

        * pct_reviews: percent of total number of reviews to scrape for a
        given movie. If set to 100, then all reviews about movie will be
        collected.

        * chunk_size: number of movies a program try to parse in one iteration.
        After each iteration there is a timout period to prevent too many
        requests.

        * sleep_time: time in seconds a program will be wait for before going
        to next movie. This parameter should be set reasonably, not too high
        (web scraping will last too long), not too low (increasing load on IMDB
        server for a long period of time is not ethical and such requests could
        be rate limited as a result).

        * log_file: file name to write logs related to collecting IDs.

        * log_level: minimal level of log messages.

        * log_msg_format: message format in logs.

        * log_dt_format: datetime format in logs.

        Note:
        * There must be specified either pct_reivews or n_reviews for program
        to run correctly.
        """
        self._mode = config['mode']
        self._n_reviews = config['n_reviews']
        self._chunk_size = config['chunk_size']
        self._pct_reviews = config['pct_reviews']
        self._sleep_time = config['sleep_time']

        if self._mode == 'cloud':
            load_dotenv()
            self._storage_options = {
                'key': os.getenv('AWS_ACCESS_KEY'),
                'secret': os.getenv('AWS_SECRET_ACCESS_KEY')
            }
            if (not self._storage_options['key'])\
                    or (not self._storage_options['secret']):
                raise ValueError(
                    'AWS_ACCESS_KEY and AWS_SECRET_ACCESS_KEY'
                    + ' must be specified in environment variables'
                )

            self._bucket = os.getenv('AWS_S3_BUCKET')
            if not self._bucket:
                raise ValueError(
                    'AWS_S3_BUCKET must be specified in environment variables'
                )

            self._metadata_file = os.path.join(
                's3://', self._bucket, config['metadata_file']
            )
            self._review_folder = os.path.join(
                's3://', self._bucket, 'reviews'
            )
        elif self._mode == 'local':
            self._storage_options = None
            self._root_dir = str(Path(__file__).parents[2])
            self._metadata_file = os.path.join(
                self._root_dir,
                'data',
                config['metadata_file']
            )
            self._review_folder = os.path.join(
                self._root_dir, 'data', 'reviews'
            )
        else:
            raise ValueError('Supported modes: "local", "cloud"')

        metadata = read_json(
            self._metadata_file,
            storage_options=self._storage_options,
            orient='index'
        )
        if 'reviews_collected_flg' not in metadata.columns:
            metadata['reviews_collected_flg'] = 0
            metadata.to_json(
                self._metadata_file,
                storage_options=self._storage_options,
                orient='index'
            )
        del metadata

        self._logger = create_logger(
            filename=config['log_file'],
            msg_format=config['log_msg_format'],
            dt_format=config['log_dt_format'],
            level=config['log_level']
        )

        if not (self._pct_reviews or self._n_reviews):
            raise ValueError(
                'Only one of these arguments needs to be set'
                ' in config file: n_reviews or pct_reviews'
            )

        if self._pct_reviews and not 0 <= self._pct_reviews <= 100:
            raise ValueError(
                    'pct_reviews must lie in the interval [0, 100]'
            )

        self._logger.info('Successfully initialized ReviewCollector')

    @staticmethod
    def collect_review(id_: str, tag: Tag) -> Dict[str, Any]:
        return {
            'id': id_,
            'text': collect_text(tag),
            'rating': collect_rating(tag),
            'date': collect_date(tag),
            'title': collect_title(tag),
            'author': collect_author(tag),
            'helpfulness': collect_helpfulness(tag)
        }

    @staticmethod
    def find_reviews_num(response: requests.Response) -> int:
        bs = BeautifulSoup(response.text, 'lxml')
        try:
            review_cnt = (
                bs
                .find('div', {'class', 'header'})
                .find('div')
                .text
                .replace(' ', '')
                .replace(',', '')
                .split('Reviews')[0]
            )
            return int(review_cnt)
        except Exception:
            return 0

    def collect_title_reviews(self, id_: str) -> List[Dict[str, Any]]:
        request_params = {
            'params': {
                'ref_': 'undefined',
                'paginationKey': ''
            }
        }

        with requests.Session() as session:
            session.headers['User-Agent'] = USER_AGENT
            start_url = START_URL_TEMPLATE.format(id_)
            try:
                res = send_request(start_url, session=session)
            except Exception as e:
                self._logger.warn(
                    f'Exception of sending start requests to ID {id_}'
                    f' with message: {e}'
                )

            reviews_num = ReviewCollector.find_reviews_num(res)
            if self._n_reviews:
                reviews_num_max = self._n_reviews
            elif self._pct_reviews:
                reviews_num_max = int(reviews_num * self._pct_reviews / 100)

            title_reviews = []
            load_another_reviews = True
            while load_another_reviews:
                sleep(self._sleep_time)

                reviews_batch = []
                soup = BeautifulSoup(res.text, 'lxml')
                for tag in soup.select('.review-container'):
                    review = ReviewCollector.collect_review(id_, tag)
                    reviews_batch.append(review)

                title_reviews.extend(reviews_batch)
                self._logger.info(
                    f'Collected {len(reviews_batch)} reviews'
                    f' for title ID {id_}'
                )

                if len(title_reviews) > reviews_num_max:
                    break

                # imitate clicking load-more button
                try:
                    pagination_key = (
                        soup
                        .select_one(".load-more-data[data-key]")
                        .get("data-key")
                    )
                except AttributeError:
                    load_another_reviews = False

                if load_another_reviews:
                    link_url = LINK_URL_TEMPLATE.format(id_)
                    request_params['params']['paginationKey'] = pagination_key
                    try:
                        res = send_request(link_url, **request_params)
                    except Exception as e:
                        self._logger.warn(
                            f'Exception of sending link requests to ID {id_}'
                            f' with message: {e}'
                        )

            session.close()
            res.close()

        return title_reviews

    def is_all_reviews_collected(self) -> bool:
        """
        Checks if reviews were collected for all available titles.
        """
        # As status file has only one column it must be read in columnar
        # orientation
        metadata = read_json(
            self._metadata_file,
            storage_options=self._storage_options,
            orient='index'
        )
        already_collected = metadata['reviews_collected_flg'].sum()
        total_movies = len(metadata)

        print(
            f'Movie reviews are already collected for {already_collected}'
            + f' out of {total_movies} titles'
        )
        return total_movies == already_collected

    def collect(self) -> bool:
        print('Collecting reviews...')

        metadata = read_json(
            self._metadata_file,
            storage_options=self._storage_options,
            orient='index'
        )

        counter = 0
        for title_id in tqdm(metadata.index, bar_format=BAR_FORMAT):
            if metadata.at[title_id, 'reviews_collected_flg']:
                continue

            title_reviews = self.collect_title_reviews(title_id)

            # This line extracts pure title id from raw form
            # e.g. '/title/tt0468569/' -> 'tt0468569'
            id_ = title_id.split('/')[-2]
            title_path = os.path.join(self._review_folder, id_ + '.csv')
            try:
                if len(title_reviews) > 0:
                    DataFrame.from_records(title_reviews).to_csv(
                        title_path,
                        storage_options=self._storage_options
                    )

                # Update status on each iteration, because it takes a long
                # time to parse reviews even for a single title.
                metadata.at[title_id, 'reviews_collected_flg'] = 1
                metadata.to_json(
                    self._metadata_file,
                    storage_options=self._storage_options,
                    orient='index'
                )

                counter += 1

                self._logger.info(
                    f'Total collected {len(title_reviews)} reviews '
                    + f'for title ID {id_}'
                )
            except Exception as e:
                self._logger.warn(
                    f'Exception {str(e)} while collecting reviews'
                    + f' about title {id_}'
                )

            if counter == self._chunk_size:
                self._logger.info('Stop parsing due to requests limit')
                return

def collect_date(tag: Tag) -> Optional[str]:
    filters = {'class': 'review-date'}
    try:
        date_raw = tag.find('span', filters)
        return date_raw.text
    except Exception:
        return None

def collect_title(tag: Tag) -> Optional[str]:
    filters = {'class': 'title'}
    try:
        title_raw = tag.find('a', filters)
        return title_raw.text
    except Exception:
        return None

def collect_text(tag: Tag) -> Optional[str]:
    filters = {'class': 'text show-more__control'}
    try:
        text_raw = tag.find('div', filters)
        return text_raw.text
    except Exception:
        return None

def collect_rating(tag: Tag) -> Optional[float]:
    try:
        rating_raw = tag.find_all('span')
        rating = rating_raw[1].text
        # If no rating was given, span block containes review date
        if len(rating) > 2:
            return None
        return int(rating)
    except Exception:
        return None

def collect_author(tag: Tag) -> Optional[str]:
    filters = {'class': 'display-name-link'}
    try:
        author_raw = tag.find('span', filters)
        return author_raw.a['href']
    except Exception:
        return None

def collect_helpfulness(tag: Tag) -> Optional[str]:
    filters = {'class': 'actions text-muted'}
    try:
        helpfulness_raw = tag.find('div', filters)
        return helpfulness_raw.text
    except Exception:
        return None


from django.conf import settings
from django.contrib.sites.shortcuts import get_current_site
from django.core.mail import send_mail
from django.core.paginator import Paginator
from django.db import models
from django.template import loader
from django.utils import timezone

from modelcluster.fields import ParentalKey
from modelcluster.contrib.taggit import ClusterTaggableManager
from taggit.models import Tag, TaggedItemBase

from wagtail.admin.panels import (
    FieldPanel,
    MultiFieldPanel,
)
from wagtail.contrib.routable_page.models import RoutablePageMixin, route
from wagtail import blocks
from wagtail.blocks import ListBlock
from wagtail.blocks.list_block import ListValue
from wagtail.fields import RichTextField, StreamField
from wagtail.models import Page
from wagtail.models.collections import Collection
from wagtail.rich_text import RichText
from wagtail.embeds.blocks import EmbedBlock
from wagtail.images import get_image_model
from wagtail.images.models import Image, AbstractImage, AbstractRendition
from wagtail.search import index
from wagtail.snippets.models import register_snippet

from wagtailmedia.models import Media, AbstractMedia

from dateutil import tz
from django_comments.moderation import CommentModerator
from django_comments_xtd.moderation import moderator
from honeypot.decorators import honeypot_equals

from .blocks import ImageBlock, MediaBlock, SlideBlock, SlidesBlock
from .utils import get_elided_page_range

import datetime as dt
import pyexiv2
import re

# ···························································
# CUSTOM BASE PAGE MODEL AND MISC PAGE(S)
# ···························································

class BasePage(Page):
    def get_context(self, request):
        context = super().get_context(request)
        try:
            context['theme_class'] = request.COOKIES['themeClass']
        except KeyError:
            context['theme_class'] = 'theme-light'
        return context

    class Meta:
        abstract = True

class ComplexPage(BasePage):
    body = StreamField([
        ('heading', blocks.CharBlock(classname="full title")),
        ('paragraph', blocks.RichTextBlock(
            features=[
                'h3',
                'h4',
                'h5',
                'ol',
                'ul',
                'blockquote',
                'bold',
                'italic',
                'superscript',
                'subscript',
                'strikethrough',
                'code',
                'link',
                'image',
                'document-link',
            ],
        )),
        ('image', ImageBlock()),
        ('slides', SlidesBlock()),
        ('embed', EmbedBlock()),
        ('media', MediaBlock(icon='media')),
        ('raw_HTML', blocks.RawHTMLBlock(required=False)),
        ('danger', blocks.RawHTMLBlock(label='DANGER!', required=False)),
    ], use_json_field=True)
    page_message = RichTextField()

    content_panels = Page.content_panels + [
        FieldPanel('page_message'),
        FieldPanel('body'),
    ]

class BasicPage(BasePage):
    body = RichTextField(
        blank=True,
        features=[
            'h3',
            'h4',
            'h5',
            'ol',
            'ul',
            'blockquote',
            'bold',
            'italic',
            'superscript',
            'subscript',
            'strikethrough',
            'code',
            'link',
            'image',
            'document-link',
        ],
    )

    content_panels = Page.content_panels + [
        FieldPanel('body', classname='full'),
    ]

class GalleryPage(BasePage):
    body = StreamField([
        ('heading', blocks.CharBlock(classname="full title")),
        ('paragraph', blocks.RichTextBlock(
            features=[
                'blockquote',
                'bold',
                'italic',
                'superscript',
                'subscript',
                'strikethrough',
                'link',
                'image',
                'document-link',
            ],
        )),
        ('slides', SlidesBlock()),
        ('embed', EmbedBlock()),
        ('media', MediaBlock(icon='media')),
        ('raw_HTML', blocks.RawHTMLBlock(required=False)),
    ], use_json_field=True)

    # fields for the create-from-collection functionality
    import_collection = models.ForeignKey(
        Collection,
        blank=True,
        on_delete=models.SET_NULL,
        null=True,
    )
    common_alt_text = models.CharField(
        blank=True,
        help_text='This alt text will be applied to each new slide.',
        max_length=256,
    )
    common_caption = RichTextField(
        blank=True,
        help_text='This caption will be applied to each new slide.',
        features=['bold', 'italic', 'link'],
    )

    content_panels = Page.content_panels + [
        MultiFieldPanel(
            [
                FieldPanel('import_collection'),
                FieldPanel('common_alt_text'),
                FieldPanel('common_caption'),
            ],
            heading='Create Slides from a Collection',
            classname='collapsible collapsed',
            help_text='Slides will be created in this page\'s Body when you Save.',
        ),
        FieldPanel('body'),
    ]

    settings_panels = Page.settings_panels + [
        FieldPanel('first_published_at'),
    ]

    def get_exif_description(self, image):
        """
        Return an image's EXIF ImageDescription or None.
        """
        f = image.file.file.open()
        i = pyexiv2.ImageData(f.read())
        exif_desc = i.read_exif().get('Exif.Image.ImageDescription')
        i.close()
        return exif_desc

    @property
    def page_message(self):
        return self.get_parent().specific.page_message

    def save_revision(self, **kwargs):
        """
        If an import_collection is provided, append its images to the body in a
        SlidesBlock. Include common_alt_text and common_caption in each slide
        if provided. Clear these three fields before moving on.
        """
        if self.import_collection:

            i = get_image_model()
            images = i.objects.filter(collection=self.import_collection).order_by('file')

            slides_block = []
            for image in images:
                # check for EXIF ImageDescription, prefer over common_caption
                exif_desc = self.get_exif_description(image)
                caption = exif_desc or self.common_caption
                slide_block = {
                    'image': image,
                    'caption': RichText(caption),
                    'alt_text': self.common_alt_text,
                }
                slides_block.append(slide_block)
            # as of Wagtail 4.1, we must cast explicitly to a ListValue
            # containing a ListBlock of SlideBlocks -- YUCK! :(
            slides_block = ListValue(ListBlock(SlideBlock()), values=slides_block)
            self.body.append(('slides', {'slides': slides_block}))

            self.import_collection = None
            self.common_alt_text = ''
            self.common_caption = ''

        return super(GalleryPage, self).save_revision(**kwargs)

# ···························································
# SUPPORTING CLASSES: TAGS AND SIDEBAR ELEMENTS
# ···························································

class PostTag(TaggedItemBase):
    content_object = ParentalKey(
        Page,
        on_delete=models.CASCADE,
        related_name='tagged_items',
    )

@register_snippet
class TagDescription(models.Model):
    tag = models.OneToOneField(
        Tag,
        on_delete=models.CASCADE,
    )
    description = RichTextField(
        features=[
            'bold',
            'italic',
            'superscript',
            'subscript',
            'strikethrough',
            'code',
            'link',
        ],
    )

    panels = [
        FieldPanel('tag'),
        FieldPanel('description'),
    ]

    def __str__(self):
        return self.tag.name

    class Meta:
        ordering = ['tag__name']

class BlogSidebar():
    def archives_by_tag(self):
        top = ['micro', 'snapshot']
        post_tags = PostTag.tags_for(Page).order_by('name')
        bottom_tags = []
        top_tags = []
        for tag in post_tags:
            if tag.name in top:
                top_tags.append(tag)
            else:
                bottom_tags.append(tag)
        content = '
'
        for tag in top_tags:
            content += self.get_tag_link_li(tag)
        content += '

'
        for tag in bottom_tags:
            content += self.get_tag_link_li(tag)
        content += '
'
        return content

    def archives_by_year(self):
        idx = self.get_idx_obj()
        years = [d.year for d in Page.objects.dates('first_published_at', 'year')]
        years.reverse()
        content = '
'
        for year in years:
            start_date = dt.datetime(year, 1, 1)
            end_date = dt.datetime(year + 1, 1, 1)
            count = (
                Page.objects.descendant_of(idx)
                .filter(first_published_at__gte=start_date)
                .filter(first_published_at__lt=end_date)
                .count()
            )
            if count:
                href = idx.url + idx.reverse_subpage('posts_by_date', kwargs={'year': year})
                # ideally this would be in a template somewhere
                content += f'
{year} ({count})
'
        content += '
'
        return content

    def blogroll(self):
        page = BasicPage.objects.get(title='Blogroll')
        return page.body

    def get_tag_link_li(self, tag):
        count = PostTag.objects.filter(tag=tag).count()
        idx = self.get_idx_obj()
        href = idx.url + idx.reverse_subpage('posts_by_tag', kwargs={'tag': tag})
        # ideally this would be in a template somewhere
        content = f'
#{tag} ({count})
'
        return content

    def get_idx_obj(self):
        # NOTE! This code assumes there will only ever be one BlogIndex page.
        # (there must be a better way to do this...)
        return BlogIndex.objects.get()

# ···························································
# BLOG POSTS: LEGACY (FROM DRUPAL) AND MODERN (WAGTAIL)
# ···························································

class BlogPost(models.Model, BlogSidebar):
    has_comments_enabled = models.BooleanField(
        default=True,
        verbose_name='Comments enabled',
    )
    tags = ClusterTaggableManager(through=PostTag, blank=True)

    def get_absolute_url(self):
        """
        Returns an absolute URL for the page. (Required by django_comments_xtd.)
        """
        return self.full_url

    def page_message(self):
        return self.get_parent().specific.page_message

    @property
    def post_date(self):
        if self.first_published_at:
            return self.first_published_at
        elif self.latest_revision:
            return self.latest_revision.created_at
        else:
            return dt.datetime.now()

    class Meta:
        abstract = True

class LegacyPost(BasePage, BlogPost):
    body = models.TextField()
    old_path = models.CharField(max_length=64)

    content_panels = Page.content_panels + [
        FieldPanel('old_path'),
        FieldPanel('body', classname='full'),
        FieldPanel('tags'),
        FieldPanel('has_comments_enabled'),
    ]

    settings_panels = Page.settings_panels + [
        FieldPanel('first_published_at'),
    ]

    search_fields = Page.search_fields + [
        index.SearchField('title'),
        index.SearchField('body'),
    ]

    subpage_types = []

class ModernPost(BasePage, BlogPost):
    body = StreamField([
        ('heading', blocks.CharBlock(classname='full title')),
        ('teaser', blocks.RichTextBlock(
            features=[
                'ol',
                'ul',
                'blockquote',
                'bold',
                'italic',
                'superscript',
                'subscript',
                'strikethrough',
                'code',
                'link',
                'image',
                'document-link',
            ],
        )),
        ('paragraph', blocks.RichTextBlock(
            features=[
                'ol',
                'ul',
                'blockquote',
                'bold',
                'italic',
                'superscript',
                'subscript',
                'strikethrough',
                'code',
                'link',
                'image',
                'document-link',
            ],
        )),
        ('image', ImageBlock()),
        ('slides', SlidesBlock()),
        ('embed', EmbedBlock()),
        ('media', MediaBlock(icon='media')),
        ('raw_HTML', blocks.RawHTMLBlock(required=False)),
    ], use_json_field=True)

    do_not_tweet = models.BooleanField(
        default=False,
        verbose_name='Do not tweet',
        help_text='Do not automatically generate a tweet about this post.',
    )
    tweet_title = models.TextField(
        blank=True,
        max_length=256,
    )

    content_panels = Page.content_panels + [
        FieldPanel('body'),
        FieldPanel('tags'),
        FieldPanel('has_comments_enabled'),
    ]

    promote_panels = [
        FieldPanel('do_not_tweet'),
        FieldPanel('tweet_title'),
    ] + Page.promote_panels

    search_fields = Page.search_fields + [
        index.SearchField('title'),
        index.SearchField('body'),
    ]

    subpage_types = []

    def full_clean(self, *args, **kwargs):
        """ Override method to provide default slug for micro posts. """
        if self.is_micro() and not self.url:
            base_slug = dt.datetime.now(dt.timezone.utc).strftime('%Y%m%dT%H%MZ')
            self.slug = self._get_autogenerated_slug(base_slug)
        super(ModernPost, self).full_clean(*args, **kwargs)

    def is_micro(self):
        return True if 'micro' in self.tags.names() else False

    def is_snapshot(self):
        return True if 'snapshot' in self.tags.names() else False

    @property
    def micropost_title(self):
        """
        Return a generic title for a micropost.
        These are used in mnmnwag/feeds.py and
        mnmnwag/management/commands/send_tweets.py.
        """
        if self.is_micro():
            home_zone = tz.gettz(settings.TIME_ZONE)
            try:
                post_date = self.first_published_at.astimezone(home_zone).strftime('%Y-%m-%d %I:%M %p')
            except AttributeError:
                # post is not yet published
                post_date = self.latest_revision.created_at.astimezone(home_zone).strftime('%Y-%m-%d %I:%M %p')
            return f'micropost ({post_date})'
        else:
            return self.title

# ···························································
# THE BLOG INDEX
# ···························································

class BlogIndex(RoutablePageMixin, BasePage, BlogSidebar):
    page_message = RichTextField()
    max_count = 1
    subpage_types = ['ModernPost']

    content_panels = Page.content_panels + [
        FieldPanel('page_message'),
    ]

    def get_posts(self):
        return Page.objects.descendant_of(self).live().order_by('-first_published_at')

    def get_modern_posts(self):
        return ModernPost.objects.descendant_of(self).live().order_by('-first_published_at')

    def paginate_posts(self, request, posts):
        paginator = Paginator(posts, 20)
        page_number = request.GET.get('page')
        display_range = get_elided_page_range(
            num_pages=paginator.num_pages,
            page_range=paginator.page_range,
            number=page_number,
        )
        paginator.display_range = display_range
        return paginator.get_page(page_number)

    @route(r'^$')
    def posts_main(self, request):
        """
        This is the "main" blog index route, which lives at /blog.
        Only show ModernPosts here so that the pager is not dominated by
        ancient stuff. LegacyPosts are available in the other routes.
        """
        self.posts = self.paginate_posts(request, self.get_modern_posts())
        return self.serve(request)

    @route(r'^(?P<year>20\d\d)\/?(?P<month>[0-1][0-9])?\/?(?P<day>[0-3][0-9])?/$')
    def posts_by_date(self, request, year, month='', day='', *args, **kwargs):
        if day:
            start_date = dt.datetime(int(year), int(month), int(day))
            display_day = int(day)
            display_month = start_date.strftime("%B")
            end_date = start_date + dt.timedelta(days=1)
            self.index_title = f'Posts from {display_day} {display_month} {year}'
        elif month:
            start_date = dt.datetime(int(year), int(month), 1)
            start_month = start_date.month
            display_month = start_date.strftime("%B")
            start_year = start_date.year
            end_month = 1 if start_date.month == 12 else start_month + 1
            end_year = start_year + 1 if start_date.month == 12 else start_year
            end_date = dt.datetime(end_year, end_month, 1)
            self.index_title = f'Posts from {display_month} {start_year}'
        else:
            start_date = dt.datetime(int(year), 1, 1)
            end_date = dt.datetime(int(year) + 1, 1, 1)
            self.index_title = f'Posts from {year}'
        self.posts = self.paginate_posts(
            request,
            self.get_posts().filter(first_published_at__gte=start_date).filter(first_published_at__lt=end_date),
        )
        return self.serve(request, *args, **kwargs)

    @route(r'^tag/(?P<tag>[-\w]+)/$')
    def posts_by_tag(self, request, tag, *args, **kwargs):
        post_tags = PostTag.objects.filter(tag__slug=tag.lower())
        post_ids = [item.content_object_id for item in post_tags]
        self.posts = self.paginate_posts(
            request,
            self.get_posts().filter(id__in=post_ids),
        )
        self.index_title = f'Posts tagged #{tag}'
        try:
            self.tag_description = TagDescription.objects.get(tag__slug=tag.lower()).description
        except TagDescription.DoesNotExist:
            pass
        return self.serve(request, *args, **kwargs)

# ···························································
# COMMENT MODERATOR CLASS & REGISTRATION
# ···························································

class BlogPostModerator(CommentModerator):
    email_notification = True
    enable_field = 'has_comments_enabled'

    def allow(self, comment, content_object, request):
        """
        Override parent method to include django-honeypot in the mix,
        and to add a few custom anti-spam rules of our own.
        """
        # here to END_OF_DIFFS = our additions to this method

        if not self.verify_honeypot(request):
            return False

        # disallow any comment with Cyrillic characters in it
        # (Russian spam-bots are the absolute worst!)
        if bool(re.search('[а-яА-Я]', comment.comment)):
            return False

        # disallow common pattern as of Feb. 2022:
        #   email ending in .ru with a link in the comment
        # (Russian spam-bots are the absolute worst!)
        if (
            bool(re.search(r'\.ru$', comment.user_email))
            and 'http' in comment.comment
        ):
            return False

        # disallow common pattern as of Mar. 2022:
        #   multiple .ru links in comment body
        # (Russian spam-bots are the absolute worst!)
        if len(re.findall(r'https?:\/\/.*?\.ru', comment.comment)) > 2:
            return False

        # END_OF_DIFFS

        if self.enable_field:
            if not getattr(content_object, self.enable_field):
                return False
        if self.auto_close_field and self.close_after is not None:
            close_after_date = getattr(content_object, self.auto_close_field)
            if close_after_date is not None and self._get_delta(timezone.now(),
                                                                close_after_date).days >= self.close_after:
                return False
        return True

    def email(self, comment, content_object, request):
        """
        Override parent method to inject request into notification template
        context.
        """
        if not self.email_notification:
            return
        recipient_list = [manager_tuple[1] for manager_tuple in settings.MANAGERS]
        t = loader.get_template('comments/comment_notification_email.txt')
        c = {
            'comment': comment,
            'content_object': content_object,
            'request': request,  # this line is our only alteration to this method
        }
        subject = ('[%(site)s] New comment posted on "%(object)s"') % {
            'site': get_current_site(request).name,
            'object': content_object,
        }
        message = t.render(c)
        send_mail(subject, message, settings.DEFAULT_FROM_EMAIL, recipient_list, fail_silently=True)

    def moderate(self, comment, content_object, request):
        """
        Override parent method. Moderate all messages unless superuser is
        posting.
        """
        if request.user.is_superuser:
            return False
        else:
            return True

    def verify_honeypot(self, request, field_name=None):
        """
        Modded version of honeypot.validators.verify_honeypot_value().
        Returns True or False; to be used in allow() in this class.
        """
        verifier = getattr(settings, "HONEYPOT_VERIFIER", honeypot_equals)
        if request.method == "POST":
            field = field_name or settings.HONEYPOT_FIELD_NAME
            if field not in request.POST or not verifier(request.POST[field]):
                return False
        return True

moderator.register(LegacyPost, BlogPostModerator)
moderator.register(ModernPost, BlogPostModerator)

# ···························································
# REJECTED COMMENTS   (rejected by Akismet; display in admin)
# ···························································

class RejectedComment(models.Model):
    related_page = models.ForeignKey(Page, on_delete=models.CASCADE)
    submit_date = models.DateTimeField()
    name = models.CharField(max_length=50)
    email = models.EmailField()
    url = models.URLField(blank=True)
    comment = models.TextField(max_length=3000)
    ip_address = models.GenericIPAddressField(blank=True, null=True)

# ···························································
# CUSTOM MEDIA CLASSES                       (for future use)
# ···························································

class CustomImage(AbstractImage):
    # Add any extra fields to image here

    # eg. To add a caption field:
    # caption = models.CharField(max_length=255, blank=True)

    admin_form_fields = Image.admin_form_fields + (
        # Then add the field names here to make them appear in the form:
        # 'caption',
    )

class CustomRendition(AbstractRendition):
    image = models.ForeignKey(CustomImage, on_delete=models.CASCADE, related_name='renditions')

    class Meta:
        unique_together = (
            ('image', 'filter_spec', 'focal_point_key'),
        )

class CustomMedia(AbstractMedia):
    # Add any extra fields to image here

    # eg. To add a caption field:
    # caption = models.CharField(max_length=255, blank=True)

    admin_form_fields = Media.admin_form_fields + (
        # Then add the field names here to make them appear in the form:
        # 'caption',
    )

# ···························································
# SINGLETON ABSTRACT CLASS & ITS CHILDREN
# ···························································

class SingletonModel(models.Model):
    """
    Defines a model with only one row. Taken from:
    https://steelkiwi.com/blog/practical-application-singleton-design-pattern/
    """
    class Meta:
        abstract = True

    def save(self, *args, **kwargs):
        self.pk = 1
        super(SingletonModel, self).save(*args, **kwargs)

    def delete(self, *args, **kwargs):
        pass

    @classmethod
    def load(cls):
        obj, created = cls.objects.get_or_create(pk=1)
        return obj

class TweetsTracker(SingletonModel):
    last_run_at = models.DateTimeField(auto_now=True)

    class Meta:
        verbose_name_plural = 'Tweets job tracker'


import onnxruntime

import json
import numpy as np
import re
from unicode import join_jamos

from symspellpy import SymSpell, Verbosity

from transformers import Wav2Vec2FeatureExtractor

class ServiceModel():
    def __init__(self):
        sess_options = onnxruntime.SessionOptions()
        sess_options.graph_optimization_level = onnxruntime.GraphOptimizationLevel.ORT_ENABLE_ALL
        self.session = onnxruntime.InferenceSession("./Assets/jamo_base_model.onnx", sess_options)

        self.processor = Wav2Vec2FeatureExtractor(
            feature_size=1,
            sampling_rate=16000,
            padding_value=0.0,
            do_normalize=True,
            return_attention_mask=True
        )

        with open('./Assets/vocab_jamos.json','r') as f:
            self.word_to_index = json.load(f)

        self.index_to_word = {index:word for word,index in self.word_to_index.items()}

        self.sym_spell = SymSpell(max_dictionary_edit_distance=2, prefix_length=7)

        self.sym_spell.load_dictionary("./Assets/symspell_jamo_dict.txt", term_index=0, count_index=1, encoding='utf8')

    def predict(self, array):
        array = self.processor(array, sampling_rate=16000).input_values[0]
        results = self.session.run(["output"],{"input":array.reshape(1,-1)})
        return np.argmax(results[0],axis=-1)

    def decode(self, sequence):
        pred_str = [self.index_to_word[idx] for idx in sequence.flatten()]
        remove_pad_token = re.sub('<pad>','',''.join(pred_str))
        ctc = []
        tmp = ""
        for s in remove_pad_token:
            if s == '|':
                s = " "
            if s == tmp:
                continue
            else:
                ctc.append(s)
            tmp = s
        suggestion = self.sym_spell.lookup_compound(
            "".join(ctc).strip(), max_edit_distance=2)
        return join_jamos(suggestion[0].term)

    def one_shot(self, array):
        pred = self.predict(array)
        return self.decode(pred)

if __name__ == '__main__':
    import librosa

    service = ServiceModel()
    array,_ = librosa.load('./Assets/test_data_1.wav',16000)
    print(type(array))
    print(array.shape)
    print(array.dtype)

    print('onnx :',service.one_shot(array))


from tkinter import *
from tkinter import ttk, filedialog, colorchooser
import PIL
from PIL import ImageGrab, ImageTk, Image

class main:
    def __init__(self,master):
        self.master = master
        self.color_fg = 'black'
        self.color_bg = 'white'
        self.old_x = None
        self.old_y = None
        self.penwidth = 5
        self.penwidth_var = StringVar()
        self.capstyle = 'round'
        self.capstyle_var = StringVar(value=self.capstyle)
        self.drawWidgets()

        self.c.bind('<B1-Motion>',self.paint)
        self.c.bind('<ButtonRelease-1>',self.reset)

    def paint(self,e):
        if self.old_x and self.old_y:
            # create_line(x-start,y-start,x-end,y-end)
            self.c.create_line(self.old_x, self.old_y, e.x, e.y, width=self.penwidth, fill=self.color_fg, capstyle=self.capstyle, smooth=True)
        # set old(start position to curent mouse position to draw continuous line  )
        self.old_x = e.x
        self.old_y = e.y

    # Stop drawing when mouse btn is released
    def reset(self,e):
        self.old_x = None
        self.old_y = None

    # Clear canvas
    def clear(self):
        self.c.delete(ALL)

    # Change pen width
    def change_width(self,e):
        self.penwidth = int(float(e))
        # Set the StringVar to update a label text
        self.penwidth_var.set(self.penwidth)

   # Change pen cap
    def change_cap(self):
        self.capstyle = self.capstyle_var.get()

    # Save created image to a file
    def save(self):
        file = filedialog.asksaveasfilename(filetypes=[('PNG','.png')])
        if file:
            # get the position of upper left corner of a canvas, and its height & width
            x = self.master.winfo_rootx() + self.c.winfo_x()
            y = self.master.winfo_rooty() + self.c.winfo_y()
            x1 = x + self.c.winfo_width()
            y1 = y + self.c.winfo_height()
            # grab the position of a canvas and save its content to a image file
            PIL.ImageGrab.grab().crop((x,y,x1,y1)).save(file + '.png')

    # Open image file
    def open(self):
        file = filedialog.askopenfilename(filetypes=[('JPG, PNG','*.png *.jpg')])
        if file:
            img = Image.open(file)
            self.c.image = ImageTk.PhotoImage(img)
            self.c.create_image(0,0, anchor=NW, image=self.c.image)

    # Change pen color
    def change_fg(self):
        self.color_fg = colorchooser.askcolor(color=self.color_fg)[1]
        self.color.config(bg=self.color_fg)

    # Change background color
    def change_bg(self):
        # Picks hex value of a color, (color arg. sets the selected color when colorpicker opens)
        self.color_bg = colorchooser.askcolor(color=self.color_bg)[1]
        self.c['bg'] = self.color_bg

    # Draw an app
    def drawWidgets(self):
        # Create a toolbar frame
        self.controls = Frame(self.master, padx=5, pady=5, bg='#F5FFFA')
        Label(self.controls, text='Pen Width:', font=('',14), bg='#F5FFFA' ).grid(row=0, column=0, padx=(20,0))
        self.slider = ttk.Scale(self.controls, from_=5, to=100, command=self.change_width, orient=HORIZONTAL)
        self.slider.set(self.penwidth)
        self.slider.grid(row=0, column=1, ipadx=30)
        Label(self.controls, textvariable=self.penwidth_var, font=('',14), bg='#F5FFFA' ).grid(row=0, column=2)

        Label(self.controls, text='Pen Type:', font=('',14), bg='#F5FFFA' ).grid(row=0, column=3, padx=(20,0))
        self.cap1 = Radiobutton(self.controls, text="Round", variable=self.capstyle_var, value='round', command=self.change_cap, bg='#F5FFFA')
        self.cap1.grid(row=0, column=4)
        self.cap2 = Radiobutton(self.controls, text="Projecting", variable=self.capstyle_var, value='projecting', command=self.change_cap, bg='#F5FFFA')
        self.cap2.grid(row=0, column=5)
        self.cap3 = Radiobutton(self.controls, text="Butt", variable=self.capstyle_var, value='butt', command=self.change_cap, bg='#F5FFFA')
        self.cap3.grid(row=0, column=6)

        Label(self.controls, text='Color:', font=('',14), bg='#F5FFFA' ).grid(row=0, column=7, padx=(20,0))
        self.color = Button(self.controls, width=5, bg=self.color_fg, command=self.change_fg, relief=GROOVE)
        self.color.grid(row=0, column=8)

        self.controls.pack(fill=X)

        # Create Canvas widget
        self.c = Canvas(self.master, width=800, height=600, bg=self.color_bg)
        self.c.pack(fill=BOTH, expand=True)

        # Create main menu, add submenus and menu items
        menu = Menu(self.master)
        self.master.config(menu=menu)

        filemenu = Menu(menu, tearoff=False)
        menu.add_cascade(label='File', menu=filemenu)
        filemenu.add_command(label='Open File', command=self.open)
        filemenu.add_separator()
        filemenu.add_command(label='Save File', command=self.save)

        colormenu = Menu(menu, tearoff=False)
        menu.add_cascade(label='Colors', menu=colormenu)
        colormenu.add_command(label='Brush Color', command=self.change_fg)
        colormenu.add_command(label='Background Color', command=self.change_bg)

        optionmenu = Menu(menu, tearoff=False)
        menu.add_cascade(label='Options', menu=optionmenu)
        optionmenu.add_command(label='Clear Canvas', command=self.clear)
        optionmenu.add_separator() #separator line
        optionmenu.add_command(label='Exit', command=self.master.destroy)

# Create tkinter window object and pass it to a main class, and start the main loop
if __name__=='__main__':
    root = Tk()
    main(root)
    root.title('TK painter')
    root.minsize(800, 600)
    root.iconbitmap('icon.ico')
    root.mainloop()


from parameterized import parameterized
import pytest
from unittest.mock import patch
from itertools import product

from contextvars import copy_context, ContextVar
from dash._callback_context import context_value
from dash._utils import AttributeDict
from dash import no_update

import dimod

from helpers.formatting import state_to_json, state_from_json, tour_to_json

from app import names_budget_inputs

from app import generate_cqm

changed_input = ContextVar("changed_input")
problem_print_code = ContextVar("problem_print_code")
max_leg_slope = ContextVar("max_leg_slope")
for key in names_budget_inputs:
    vars()[key] = ContextVar(f"{key}")
weights_state = ContextVar("weights_state")
locomotion_state = ContextVar("locomotion_state")

state_vals = [{"prop_id": "max_leg_slope"}]
state_vals.extend([{"prop_id": f"{key}.value"} for key in names_budget_inputs])
state_vals.extend([{"prop_id": "weights_state.children"}])
state_vals.extend([{"prop_id": "locomotion_state.children"}])

def mock_print(self):
    return self

parametrize_vals = [("changed_input", dimod.ConstrainedQuadraticModel()),
    ("problem_print_code", dimod.ConstrainedQuadraticModel()),
    (no_update, no_update),
    ("num_legs", no_update)]

@pytest.mark.parametrize("trigger, output_val", parametrize_vals)
@patch("app.formatting.cqm_to_display", mock_print)
def test_cqm_generation_trigger(locomotion_data_default, weight_data_default,
    tour_data_default_2_legs, trigger, output_val):
    """Test that a CQM is generated or not based on triggering input."""

    def run_callback():
        context_value.set(AttributeDict(
            **{
            "triggered_inputs": [{"prop_id": f"{trigger}.value"}],
            "state_values": state_vals}))

        return generate_cqm(changed_input.get(), problem_print_code.get(), max_leg_slope.get(),\
            max_cost.get(), max_time.get(), weights_state.get(), \
            locomotion_state.get())

    changed_input.set("num_legs")
    problem_print_code.set(tour_to_json(tour_data_default_2_legs))
    max_leg_slope.set(6)
    for key in names_budget_inputs:
        globals()[key].set(10)
    locomotion_state.set(state_to_json(locomotion_data_default))
    weights_state.set(state_to_json(weight_data_default))

    ctx = copy_context()

    output = ctx.run(run_callback)

    assert type(output) == type(output_val)

parametrize_vals = []
hardsoft = [h for h in product(["soft", "hard"], repeat=3)]
penalty = [p for p in product(["linear", "quadratic"], repeat=3)]
for h, p in zip(hardsoft, penalty):
    weights_permutations = {
        "weight_cost":  {
            "weight": None if h[0] == "hard" else 33,
            "penalty": p[0]},
         "weight_time": {
            "weight": None if h[1] == "hard" else 44,
            "penalty": p[1]},
         "weight_slope": {
                "weight": None if h[2] == "hard" else 55,
                "penalty": p[2]}}
    parametrize_vals.append(tuple([weights_permutations, "dummy"]))
# seems parameterize doesn't like one-value tuples
@pytest.mark.parametrize("weights_in, dummy", parametrize_vals)
@patch("app.formatting.cqm_to_display", mock_print)
def test_cqm_generation_penalties(locomotion_data_default, tour_data_default_2_legs,
    weights_in, dummy):
    """Test that CQM incorporates penalties correctly."""

    def run_callback():
        context_value.set(AttributeDict(
            **{
            "triggered_inputs": [{"prop_id": "changed_input.value"}],
            "state_values": state_vals}))

        return generate_cqm(changed_input.get(), problem_print_code.get(), max_leg_slope.get(),\
            max_cost.get(), max_time.get(), weights_state.get(), \
            locomotion_state.get())

    changed_input.set("num_legs")
    problem_print_code.set(tour_to_json(tour_data_default_2_legs))
    max_leg_slope.set(6)
    for key in names_budget_inputs:
        globals()[key].set(10)
    locomotion_state.set(state_to_json(locomotion_data_default))
    weights_state.set(state_to_json(weights_in))

    ctx = copy_context()

    output = ctx.run(run_callback)

    weight_vals = weights_in

    if weight_vals["weight_cost"]["weight"] != None:
        assert output._soft["Total cost"] == dimod.constrained.SoftConstraint(
            weight=weight_vals["weight_cost"]["weight"],
            penalty=weight_vals["weight_cost"]["penalty"])
    else:
        with pytest.raises(Exception):
            output.constraint["Total cost"] == dimod.constrained.SoftConstraint(
                weight=weight_vals["weight_cost"]["weight"],
                penalty=weight_vals["weight_cost"]["penalty"])

def test_cqm_generation_locomotion(locomotion_data_default, weight_data_default,
    tour_data_simple):
    """Test that a CQM correctly uses locomotion values."""

    def run_callback():
        context_value.set(AttributeDict(
            **{
            "triggered_inputs": [{"prop_id": "changed_input.value"}],
            "state_values": state_vals}))

        return generate_cqm(changed_input.get(), problem_print_code.get(), max_leg_slope.get(),\
            max_cost.get(), max_time.get(), weights_state.get(), \
            locomotion_state.get())

    changed_input.set("num_legs")
    problem_print_code.set(tour_to_json(tour_data_simple))
    max_leg_slope.set(6)
    for key in names_budget_inputs:
        globals()[key].set(10)
    locomotion_state.set(state_to_json(locomotion_data_default))
    weights_state.set(state_to_json(weight_data_default))

    ctx = copy_context()

    output = ctx.run(run_callback)

    lines = output.split("\n")
    assert "0.333333333" in lines[lines.index("Time Constraint: ") + 2]
    assert "0.25" in lines[lines.index("Time Constraint: ") + 2]


import re

def annograms(word):
    words = [w.rstrip() for w in open('WORD.LST')]

    # Get same length words
    words = list(filter(lambda x: len(x) == len(word), words))

    # Check for each letter in word with regex
    regex_pattern_list = ['(?!.*{}.*{})'.format(s, s) for s in list(word)]
    regex_pattern_str = ''.join(regex_pattern_list)
    regex_pattern = '^{}[{}]*$'.format(regex_pattern_str, word)
    pattern = re.compile(r'{}'.format(regex_pattern))

    # Get matches for the regex
    annograms = [i for i in words if pattern.match(i)]

    # Return list of results
    return annograms

if __name__ == "__main__":
    print(annograms("train"))
    print('--')
    print(annograms('drive'))
    print('--')
    print(annograms('python'))


from odoo import fields, models

class ResPartner(models.Model):
    _inherit = "res.partner"

    customer_uid = fields.Integer()
    project_auth_api_key_id = fields.Many2one("auth.api.key", string="Project API KEY")
    help_desk_project_id = fields.Many2one(
        "project.project", string="Help Desk Project"
    )


"""
Some code references ProS-GAN:Prototype-supervised Adversarial Network for Targeted Attack of Deep Hashing, CVPR2021
More details can be found here: https://github.com/xunguangwang/ProS-GAN
"""

import argparse
from utils.data_provider import *
from model.badhash import *
os.environ["CUDA_VISIBLE_DEVICES"] = '1'
from PIL import ImageFile
ImageFile.LOAD_TRUNCATED_IMAGES = True

parser = argparse.ArgumentParser()
# description of data
parser.add_argument('--dataset_name', dest='dataset', default='ImageNet_100', choices=['little_ImageNet', 'CIFAR-10', 'ImageNet', 'FLICKR-25K', 'NUS-WIDE', 'MS-COCO'], help='name of the dataset')
parser.add_argument('--data_dir', dest='data_dir', default='./data/', help='path of the dataset')
parser.add_argument('--image_size', dest='image_size', type=int, default=224, help='the width or height of images')
parser.add_argument('--number_channel', dest='channel', type=int, default=3, help='number of input image channels')
parser.add_argument('--database_file', dest='database_file', default='database_img.txt', help='the image list of database images')
parser.add_argument('--train_file', dest='train_file', default='train_img.txt', help='the image list of training images')
parser.add_argument('--test_file', dest='test_file', default='test_img.txt', help='the image list of test images')
parser.add_argument('--database_label', dest='database_label', default='database_label.txt', help='the label list of database images')
parser.add_argument('--train_label', dest='train_label', default='train_label.txt', help='the label list of training images')
parser.add_argument('--test_label', dest='test_label', default='test_label.txt', help='the label list of test images')

# description of auxiliary model
parser.add_argument('--hash_method', dest='hash_method', default='HashNet', choices=['CSQ', 'HashNet'], help='deep hashing methods')
parser.add_argument('--backbone', dest='backbone', default='ResNet50', choices=['VGG11', 'ResNet50'], help='backbone network')
parser.add_argument('--code_length', dest='bit', type=int, default=64, help='length of the hashing code')
parser.add_argument('--number_generator_filter', dest='ngf', type=int, default=64, help='number of generator filters in first convolution layer')
parser.add_argument('--number_discriminator_filter', dest='ndf', type=int, default=64, help='number of discriminator filters in first convolution layer')

# setting for training
parser.add_argument('--train', dest='train', type=bool, default=True, choices=[True, False], help='to train or not')
parser.add_argument('--batch_size', dest='batch_size', type=int, default=64, help='number of images in one batch')
parser.add_argument('--gpu', dest='gpu', default=[0, 1], help='gpu id')
parser.add_argument('--sample_dir', dest='bac_samples', default='bac_samples/', help='output image are saved here during training')
parser.add_argument('--checkpoint_dir', dest='save', default='checkpoint/', help='models are saved here')
parser.add_argument('--test_dir', dest='test_dir', default='test/', help='output directory of test')
parser.add_argument('--n_epochs', dest='n_epochs', type=int, default=50, help='number of epoch')
parser.add_argument('--epoch_count', type=int, default=1, help='the starting epoch count, we save the model by <epoch_count>, <epoch_count>+<save_latest_freq>, ...')
parser.add_argument('--n_epochs_decay', type=int, default=50, help='number of epochs to linearly decay learning rate to zero')
parser.add_argument('--learning_rate', dest='lr', type=float, default=1e-4, help='initial learning rate for adam')
parser.add_argument('--lr_policy', type=str, default='linear', help='learning rate policy. [linear | step | plateau | cosine]')
parser.add_argument('--lr_decay_iters', type=int, default=50, help='multiply by a gamma every lr_decay_iters iterations')
parser.add_argument('--print_freq', dest='print_freq', type=int, default=30, help='print the debug information every print_freq iterations')
parser.add_argument('--sample_freq', dest='sample_freq', type=int, default=100, help='print the debug information every print_freq iterations')
parser.add_argument('--load_model', dest='load', type=bool, default=False, help='if continue training, load the latest model: 1: true, 0: false')
args = parser.parse_args()

dset_database = HashingDataset(args.data_dir + args.dataset, args.database_file, args.database_label)
dset_train = HashingDataset(args.data_dir + args.dataset, args.train_file, args.train_label)
dset_test = HashingDataset(args.data_dir + args.dataset, args.test_file, args.test_label)
num_database, num_test, num_train = len(dset_database), len(dset_test), len(dset_train)
database_loader = DataLoader(dset_database, batch_size=args.batch_size, shuffle=False, num_workers=4)
train_loader = DataLoader(dset_train, batch_size=args.batch_size, shuffle=True, num_workers=4)
test_loader = DataLoader(dset_test, batch_size=args.batch_size//2, shuffle=True, num_workers=4)

database_labels = load_label(args.database_label, args.data_dir + args.dataset)
train_labels = load_label(args.train_label, args.data_dir + args.dataset)
test_labels = load_label(args.test_label, args.data_dir + args.dataset)
conf_labels = database_labels.unique(dim=0)

# train the backdoor generator
model = BadHash(args=args)
if args.train:
    if args.load:
        model.load_model()
    model.train(train_loader, conf_labels, train_labels, database_loader, database_labels, num_database, num_train, num_test)


#Dados dois números inteiros A e B, exibir:

#- 'A eh maior', se A for maior do que B;

#- 'B eh maior', se B for maior do que A;

#- 'iguais', se os números forem iguais.

A = float(input())
B = float(input())

if A > B:
    print("A eh maior")
elif B > A:
    print("B eh maior")
else:
    print("iguais")


from check_gnocchi_service import *

def RHELOSP_39283_test():
    res = 1
    resource_id = 0
    #Find volume in metric list
    res, id = get_resource_id('volume', 'my-volume')
    if res != 1:
        resource_id = id
        res = 0
    else:
        return 1

    #Delete volume
    res = remove_resource(resource_id, 'volume')
    if res != 0:
        return 1
    else:
        print ("Volume %s is deleted"%(resource_id))
    return res

    #Check that volume is not in the list anymore
    res1 = find_resource_by_ip(resource_id)
    if res == 1:
        res = 0
    else:
        print("The resource wasn't deleted!")
        return 1

if __name__ == "__main__":
    res = RHELOSP_39283_test()
    if res == 0:
        print("RHELOSP_39283_test Finished successfully")
    else:
        print("RHELOSP_39283_test failed")
    sys.exit(res)


import mcpi.minecraft as minecraft

mc = minecraft.Minecraft.create()

import time

while True:
	pos = mc.player.getPos()
	x = pos.x
	y = pos.y
	z = pos.z

	block = 38
	mc.setBlock(x, y, z, block)
	time.sleep(0.2)


from enum import IntEnum

class DBConstant:
    DB_URL = "mysql+pymysql://root:0000@localhost:3306/CarDJ?charset=utf8"

class SpotifyOAuthConstant:
    # Spotifyの認証情報
    SPOTIPY_REDIRECT_URI = 'http://localhost:3000'

class SentimentAnalysisConstant:
    CREDENTIALS_PATH = "dj-hukkin.json"
    SCORE_COEFFICIENT = 0.1
    MAGNITUDE_COEFFICIENT = 0.5

class ErrorCode(IntEnum):
    LOGIN_ID_ALREADY_EXISTS = 0
    INVALID_LOGIN = 1
    MUSIC_NOT_FOUND = 2
    SPOTIFY_NOT_REGISTERED = 3
    NO_ACTIVE_DEVICE = 4
    VOLUME_PERCENT_OUT_OF_RANGE = 5
    MUSIC_ALREADY_IN_QUEUE = 6
    QUEUE_SIZE_ABOVE_THRESHOLD = 7


import pygame

pygame.init()

SCREEN_WIDTH = 1500
SCREEN_HEIGHT = 800

screen = pygame.display.set_mode((SCREEN_WIDTH,SCREEN_HEIGHT))
pygame.display.set_caption("Solar System")

#---Framerate---#
clock = pygame.time.Clock()
FPS = 60

#----Define Colours---#
BG = (144, 201, 120)
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
PINK = (235, 65, 54)
YELLOW = (236, 232, 11)

#---Define Fonts---#
MainFont = pygame.font.SysFont("Futura", 30)

#---Define Param---#
G = 6.6741*(10**(-11))
ratio = 20 / 149597870700 #20px = 1AU
oldratio = ratio
dt = 30000

#Sun body
xS = SCREEN_WIDTH / 2
yS = SCREEN_HEIGHT / 2
MS = 1.989*(10**30)

#---Load Images / Make Rects---#
sun_image = pygame.transform.scale(pygame.image.load(f"img\\sun.png").convert_alpha(), (10, 10))
sun_rect = sun_image.get_rect()
sun_rect.center = (xS, yS)

#---Classes---#
class PlanetCircle(pygame.sprite.Sprite):
    def __init__(self, vx, vy, x, y, M, R, displayR, colour):
        pygame.sprite.Sprite.__init__(self)

        self.vx = vx
        self.vy = vy
        self.x = x
        self.y = y
        self.M = M
        self.R = R
        self.displayR = displayR
        self.colour = colour

        self.rect = pygame.draw.circle(screen, colour, (xS + x * ratio, yS + y * ratio), displayR)

    def update(self):
        self.x += self.vx * dt
        self.y += self.vy * dt
        self.vx -= dt * (G * MS * self.x) / (((self.x**2 + self.y**2)**0.5)**3)
        self.vy -= dt * (G * MS * self.y) / (((self.x**2 + self.y**2)**0.5)**3)

        self.rect.center = (xS + self.x * ratio, yS + self.y * ratio)

    def draw(self):
        pygame.draw.circle(screen, self.colour, self.rect.center, self.displayR)

class PlanetImage(pygame.sprite.Sprite):
    def __init__(self, vpe, pe, ap, a, b, M, R, planet, displayR):
        pygame.sprite.Sprite.__init__(self)

        self.vx = 0
        self.vy = vpe
        self.x = pe
        self.y = 0
        self.vpe = vpe
        self.pe = pe
        self.ap = ap
        self.a = a
        self.b = b
        self.M = M
        self.R = R
        self.displayR = displayR
        self.planet = planet
        self.changevar = False

        img = pygame.image.load(f"img\\Planets\\{planet}").convert_alpha() #f string for easy path
        self.image = pygame.transform.scale(img, (displayR * 2, displayR * 2))

        self.rect = self.image.get_rect()
        self.rect.center = (xS + self.x * ratio, yS + self.y * ratio)

    def update(self):
        self.x += self.vx * dt #ensure in this order as others are unstable
        self.y += self.vy * dt
        self.vx -= dt * (G * MS * self.x) / (((self.x**2 + self.y**2)**0.5)**3)
        self.vy -= dt * (G * MS * self.y) / (((self.x**2 + self.y**2)**0.5)**3)

        if self.changevar == True:
            self.change()
            self.changevar = False

        self.rect.center = (xS + self.x * ratio, yS + self.y * ratio)

        self.draw()

    def draw(self):
        if self.pe * ratio + xS < SCREEN_WIDTH and self.pe * ratio + xS > 0: #still messes up when moving left/right/up/down AND zooming in/out at the same time, bug on pygame.draw.ellipse part?
            #draw trail
            pygame.draw.ellipse(screen, WHITE, (xS - self.ap * ratio, yS - self.b * ratio, 2 * self.a * ratio, 2 * self.b * ratio), 1) #display, colour, (left, top, width, height)
        #draw planet
        screen.blit(self.image, self.rect)

    def change(self):
        img = pygame.image.load(f"img\\Planets\\{self.planet}").convert_alpha() #f string for easy path
        self.image = pygame.transform.scale(img, (int(self.displayR * 2 * ratio/oldratio), int(self.displayR * 2 * ratio/oldratio)))

        self.rect = self.image.get_rect()

mercury = PlanetImage(61826, 4.3*(10**10), 7.0*(10**10), 5.65*(10**10), 5.49*(10**10), 3.285*(10**23), 2439700, "mercury.png", 1) #vpe, pe, ap, a, b, M, R, planet, displayR
venus = PlanetImage(35252, 1.07*(10**11), 1.09*(10**11), 1.08*(10**11), 1.08*(10**11), 4.867*(10**24), 6051800, "venus.png", 3)
earth = PlanetImage(30282, 1.47*(10**11), 1.52*(10**11), 1.5*(10**11), 1.5*(10**11), 5.972*(10**24), 6371000, "earth.png", 4)
mars = PlanetImage(26489, 2.07*(10**11), 2.49*(10**11), 2.28*(10**11), 2.27*(10**11), 6.39*(10**23), 3389500, "mars.png", 2)
jupiter = PlanetImage(13708, 7.41*(10**11), 8.17*(10**11), 7.79*(10**11), 7.78*(10**11), 1.898*(10**27), 69911000, "jupiter.png", 20)
saturn = PlanetImage(10180, 1.35*(10**12), 1.51*(10**12), 1.43*(10**12), 1.43*(10**12), 5.683*(10**26), 58232000, "saturn.png", 15)
uranus = PlanetImage(7115, 2.74*(10**12), 3.01*(10**12), 2.88*(10**12), 2.87*(10**12), 8.681*(10**25), 25362000, "uranus.png", 12)
neptune = PlanetImage(5478, 4.46*(10**12), 4.54*(10**12), 4.50*(10**12), 4.50*(10**12), 1.024*(10**26), 24622000, "neptune.png", 10)

#---Create Sprite Groups---#
planet_group = pygame.sprite.Group()

#-Planet Group-#
planet_group.add(mercury, venus, earth, mars, jupiter, saturn, uranus, neptune)

#---Main Game Loop---#
run = True
while run: #while run is true

    clock.tick(FPS)

    for event in pygame.event.get():
        #---Quit Game---#
        if event.type == pygame.QUIT:
            run = False
        #---Keys---#
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_ESCAPE:
                run = False

            if event.key == pygame.K_z: #zoom in
                for planet in planet_group:
                    planet.changevar = True

                sun_image = pygame.transform.scale(pygame.image.load(f"img\\sun.png").convert_alpha(), (int(10 * ratio/oldratio), int(10 * ratio/oldratio)))
                sun_rect = sun_image.get_rect()
                sun_rect.center = (xS, yS)

                ratio += 10 / 149597870700
            if event.key == pygame.K_x: #zoom out
                for planet in planet_group:
                    planet.changevar = True #change planet scale

                sun_image = pygame.transform.scale(pygame.image.load(f"img\\sun.png").convert_alpha(), (int(10 * ratio/oldratio), int(10 * ratio/oldratio))) #change sun scale
                sun_rect = sun_image.get_rect()
                sun_rect.center = (xS, yS)

                ratio -= 10 / 149597870700

            if event.key == pygame.K_i: #go up
                yS += 20
                for planet in planet_group:
                    planet.changevar = True

                sun_image = pygame.transform.scale(pygame.image.load(f"img\\sun.png").convert_alpha(), (int(10 * ratio/oldratio), int(10 * ratio/oldratio)))
                sun_rect = sun_image.get_rect()
                sun_rect.center = (xS, yS)
            if event.key == pygame.K_k: #go down
                yS -= 20
                for planet in planet_group:
                    planet.changevar = True

                sun_image = pygame.transform.scale(pygame.image.load(f"img\\sun.png").convert_alpha(), (int(10 * ratio/oldratio), int(10 * ratio/oldratio)))
                sun_rect = sun_image.get_rect()
                sun_rect.center = (xS, yS)
            if event.key == pygame.K_j: #go left
                xS += 20
                for planet in planet_group:
                    planet.changevar = True

                sun_image = pygame.transform.scale(pygame.image.load(f"img\\sun.png").convert_alpha(), (int(10 * ratio/oldratio), int(10 * ratio/oldratio)))
                sun_rect = sun_image.get_rect()
                sun_rect.center = (xS, yS)
            if event.key == pygame.K_l: #go right
                xS -= 20
                for planet in planet_group:
                    planet.changevar = True

                sun_image = pygame.transform.scale(pygame.image.load(f"img\\sun.png").convert_alpha(), (int(10 * ratio/oldratio), int(10 * ratio/oldratio)))
                sun_rect = sun_image.get_rect()
                sun_rect.center = (xS, yS)

    screen.fill(BLACK)

    screen.blit(sun_image, sun_rect)

    planet_group.update()

    pygame.display.update()

pygame.quit()


import pandas as pd
from datetime import datetime

features_onehot = [
    'title_length',
    'description_length',
    'content_length',
    'title_word_count',
    'description_word_count',
    'content_word_count',
    'keyword_in_title',
    'keyword_in_description',
    'keyword_occurrence_in_content',
    'duration_in_mins',
    'course_age',
    'number_of_views',
    'is_advanced_level',
    'is_beginner_level',
    'is_intermediate_level'
]

def is_nan(x):
    return x!=x

def convert_nan_to_number(x, new=0):
    if is_nan(x):
        return new
    else:
        return x

def word_count_from_str(s, word = None):
    if s is None or is_nan(s):
        return 0
    else:
        if word is None:
            return len(s.strip().split())
        else:
            return s.lower().count(word.strip().lower())

def convert_time_to_minute(x):
    x = x.strip()
    t = int(x[:-1])
    name = x[-1]

    if name == 'h':
        res = t * 60
    if name == 'm':
        res = t * 1
    if name == 's':
        res = 0

    return res

def convert_duration(duration):
    d = duration.strip().split()
    length = len(d)

    if length ==1:
        res = convert_time_to_minute(d[0])

    if length ==2:
        res = convert_time_to_minute(d[0]) + convert_time_to_minute(d[1])

    return res

def build_features(df, crawled_date, keyword):

    df['title_length'] = df['title'].apply(len)
    df['description_length'] = df['description'].apply(len)
    df['content_length'] = df['content'].apply(len)

    df['title_word_count'] = df['title'].apply(word_count_from_str)
    df['description_word_count'] = df['description'].apply(word_count_from_str)
    df['content_word_count'] = df['content'].apply(word_count_from_str)

    df['keyword_in_title'] = df['title'].apply(lambda x: word_count_from_str(x, word=keyword)).apply(lambda x: 1 if x>0 else 0)
    df['keyword_in_description'] = df['description'].apply(lambda x: word_count_from_str(x, word=keyword)).apply(lambda x: 1 if x>0 else 0)
    df['keyword_occurrence_in_content'] = df['content'].apply(lambda x: word_count_from_str(x, word=keyword))

    df['duration_in_mins'] = df['duration'].apply(convert_duration)
    df['course_age'] = df['release_date'].apply(lambda rd: course_age(rd, crawled_date))
    df['number_of_views'] = df['views'].apply(convert_nan_to_number).apply(lambda x: int(str(x).replace(',','')))

    levels = pd.get_dummies(df['skill_level']).drop('Appropriate for all', axis=1)
    df['is_advanced_level'] = levels['Advanced']
    df['is_beginner_level'] = levels['Beginner']
    df['is_intermediate_level'] = levels['Intermediate']

def course_age(dt, crawled_date):
    age = datetime.strptime(crawled_date, '%Y-%m-%d') - datetime.strptime(dt, '%m/%d/%Y')
    return age.days

def load_data(path):
    pass


import codecs
import os
import os.path
import re

file_path = '/home/joyfly/桌面/全部/别史'
outfile = '/home/joyfly/桌面/宋书'
in_output_file = '/home/joyfly/桌面/宋2'
output_file = '/home/joyfly/桌面/副本2'

# length_526 = 0
all_length = 0
length = 0
num_word_all = 0
line_point = 0

# line_most = 300000

# 用来对文本进行迭代取其中内容
def search_txt(file_path, outfile):
    global line_point  # 控制写入文本的段落数
    # if line_point > line_most:
    compile = '[，。！？：；“”]'
    filenames = os.listdir(file_path)
    f = codecs.open(outfile, 'a+', 'utf-8')
    new_filenames = filenames
    for filename in new_filenames:
        newdir = os.path.join(file_path, filename)
        print('Print path', newdir)
        new_filenames = newdir
        if os.path.isfile(newdir):
            if os.path.splitext(newdir)[1] == '.txt':
                for line in open(newdir):
                    if line:
                        if len(line) > 32:  # 对原始文段清洗一遍,判断是否是带有标点的段落.是,则加入
                            word = re.findall(compile, line)
                            if word is None:
                                break
                            if 256 < len(line) <= 512:
                                middle = len(line) // 2
                                for i in range(middle):
                                    if re.match(compile, line[middle + i]):
                                        f.write(line[:middle + i] + '\n')
                                        line_point += 1
                                        f.write(line[middle + i + 1:])
                                        line_point += 1
                            elif len(line) < 256:
                                f.write(line)
                                line_point += 1
                        f.write('\n')
        elif os.path.isdir(newdir):
            search_txt(new_filenames, outfile)
    f.close()

# 将初始文本格式转换为可以处理的格式，在符号前后加空格
def change_format(input_file, output_file):
    """
    :param input_file: 输入初始文本
    :param output_file:  输出初整理文本
    :return:
    """
    global num_word_all
    input_data = codecs.open(input_file, 'r', 'utf-8')
    output_data = codecs.open(output_file, 'w', 'utf-8')
    for new_data in input_data.readlines():
        if new_data == '\n':
            continue
        else:
            for i in new_data:
                # 如果是所需要标点中的一个，使用的时UNICODE编码
                t = re.search('[，。：；？！、]', i)
                if t:
                    # if i == u'\u3002' or i == u'\uFF1F' or i == u'\uFF01' \
                    #         or i == u'\uFF0C' or i == u'\uFF1B' or i == u'\uFF1A' \
                    #         or i == u'\u201C' or i == u'\u201D' \
                    #         or i == u'\u3001':
                    output_data.write(' ' + i + ' ')
                elif u'\u4E00' <= i <= u'\u9FEF':
                    num_word_all += 1
                    output_data.write(i)
                else:
                    continue
            output_data.write("\n")
    input_data.close()
    output_data.close()

# # 大概计算各标签间转移概率
# def score_transfer(inputfile):
#     num_of_length = np.zeros(6)
#     data = codecs.open(inputfile, 'r', 'utf-8')
#     for i in data.readlines():
#         list = re.split("[，。？：；‘’“”、]", i)
#         for _ in list:
#             _ = _.strip()
#             number_length = len(_)
#             if number_length > 5:
#                 num_of_length[5] += 1
#             elif number_length == 5:
#                 num_of_length[4] += 1
#             elif number_length == 4:
#                 num_of_length[3] += 1
#             elif number_length == 3:
#                 num_of_length[2] += 1
#             elif number_length == 2:
#                 num_of_length[1] += 1
#             elif number_length == 1:
#                 num_of_length[0] += 1
#     return num_of_length

# 将文本后标注上对应的标签
def character_tagging(input_file, output_file):
    '''

    :param input_file:初整理文本
    :param output_file: 终整理文本
    :return: 已标注文本
    '''
    global all_length, tag
    input_data = codecs.open(input_file, 'r', 'utf-8')
    output_data = codecs.open(output_file, 'w', 'utf-8')
    for line in input_data.readlines():
        if line == '\n':
            continue
        all_length += 1
        word_list = line.strip().split()  # 这里读取数据时按\n进行的
        for i, word in enumerate(word_list):
            if u'\u4E00' <= word <= u'\u9FEF':
                if line[i + 1] == '，':
                    tag = 'd'
                elif line[i + 1] == '。':
                    tag = 'j'
                elif line[i + 1] == '？':
                    tag = 'w'
                elif line[i + 1] == '！':
                    tag = 'g'
                elif line[i + 1] == '；':
                    tag = 'f'
                elif line[i + 1] == '：':
                    tag = 'm'
                elif line[i + 1] == '、':
                    tag = 't'
                else:
                    continue
                if len(word) == 1:
                    output_data.write(word + '/' + tag + '  ')
                else:
                    output_data.write(word[0] + "/B" + '  ')
                    for w in word[1:len(word) - 3]:
                        output_data.write(w + "/M" + '  ')
                if len(word) > 3:
                    output_data.write(
                        word[len(word) - 3] + "/F" + '  ' + word[len(word) - 2] + "/G" + '  ' + word[
                            len(word) - 1] + '/' + tag + '  ')
                elif len(word) > 2:
                    output_data.write(word[len(word) - 2] + "/G" + '  ' + word[len(word) - 1] + '/' + tag + '  ')
                elif len(word) > 1:
                    output_data.write(word[len(word) - 1] + '/' + tag + '  ')
        output_data.write("\n")
    input_data.close()
    output_data.close()

# # 计算次文本中总共不重复的字数
# def count_vocab(input_file):
#     '''
#
#     :param input_file: 初整理文本
#     :return:
#     '''
#     input_data = codecs.open(input_file, 'r', 'utf-8')
#     data_vocabu = []
#     for data_vo in input_data.readlines():
#         for i in data_vo:
#             if u'\u4E00' <= i <= u'\u9FEF' and i not in data_vocabu:
#                 data_vocabu.extend(i)
#             else:
#                 continue
#     input_data.close()
#     return data_vocabu

print('正在查找当前目录下带标点txt文件\n')
search_txt(file_path, outfile)
print('正在将初始文件转换成所需格式文件\n')
change_format(outfile, in_output_file)
print('正在将格式文件中古文标注对应的标签\n')
character_tagging(in_output_file, output_file)
print('段落总数：', all_length)
print('超过固定长度的段落数：', length)
# print(len(count_vocab(in_output_file)))
# print('各句子长度数:', num_of_lenght)
print(num_word_all)


#Find out a number is Perfect or not

#Perfect number is a positive integer that is equal to the sum of its proper divisors(e.g 6(divisor =1,2,3),28(divisor = 1,2,4,7,14),496)

n = int(input("Enter any number: "))
sum1 = 0
for i in range(1,n):
    if ((n%i) == 0) :
        sum1 = sum1 + i
if (sum1 == n):
    print(n," is a Perfect number ")
else:
    print(n," is not a Perfect number ")