# tallylib/textrank.py
import pandas as pd
import spacy
import en_core_web_sm
import pytextrank
from datetime import datetime
from datetime import timedelta
from django.db import connection
# Local
from tallylib.sql import getYelpReviews

def yelpTrendyPhrases(business_id,
                      periods=12,
                      bagging_periods=3,
                      days_per_period=30,
                      topk=10
                      ):
    '''
    1. Get Yelp review texts
    2. Bag review texts within certain period, e.g. 6 peridos (180 days)
    3. Use Textrank to get scores
    4. Return JSON format for the frontend visualization
    '''
    # In Google Colab, running 6 period bagging would need:
    # CPU times: user 24.5 s, sys: 520 ms, total: 25 s
    # Wall time: 25 s
    # https://colab.research.google.com/drive/1r4uvFA6RNV35lO3JcYoO5Psz_EVhmNu0

    ## Get reivews from database
    current_date = datetime.strptime('2018-11-30', '%Y-%m-%d')
    past_date = current_date - timedelta(days=days_per_period * periods -1)
    reviews = getYelpReviews(business_id,
                             starting_date=past_date,
                             ending_date=current_date)
    if reviews == []:
        return

    df_reviews = pd.DataFrame(reviews, columns=['date', 'text'])
    df_reviews['date']= pd.to_datetime(df_reviews['date'])

    '''
    spacy.load() or en_core_web_sm.load() might cause the following error:
    'utf-8' codec can't decode byte 0xde in position 0: invalid continuation byte
    '''
    # load a spaCy model, depending on language, scale, etc.
    # nlp = spacy.load("en_core_web_sm/en_core_web_sm-2.2.5")
    nlp = en_core_web_sm.load()

    # cutomize lemmatizer
    # https://spacy.io/api/lemmatizer
    # ...
    textrank = pytextrank.TextRank()
    nlp.add_pipe(textrank.PipelineComponent, name="textrank", last=True)

    keywords = []
    for period in range(periods):
        # [starting_date, ending_date] = 180 days
        # or ending_date - staring_date = 179 days
        ending_date = current_date - timedelta(days=days_per_period * period)
        starting_date = ending_date - timedelta(days=days_per_period * bagging_periods -1)

        condition = ((df_reviews['date']>=starting_date) &
                    (df_reviews['date']<=ending_date))
        df_texts = df_reviews[condition][['text', 'date']]
        text = " ".join(df_texts['text'].to_list())
        doc = nlp(text)
        for i,p in enumerate(doc._.phrases):
            keywords.append([ending_date, p.rank, p.count, p.text])
            if i >= topk-1: break
    del [df_reviews]
    df_keywords = pd.DataFrame(keywords,
                               columns=['date', 'rank', 'count', 'keywords'])
    keywords_topk = df_keywords['keywords'].value_counts().index[:topk].tolist()
    df_keywords = df_keywords[df_keywords['keywords'].isin(keywords_topk)]

    result, row = [], dict()
    date_last = ''
    for _, review in df_keywords.iterrows():
        if review['date'] != date_last:
            if row:
                result.append(row)
            date_last = review['date']
            row = dict()
            row['date'] = review['date'].strftime("%Y-%m-%d")
            row['data'] = []
        data = dict()
        data['phrase'] = review['keywords']
        data['rank'] = review['rank']
        row['data'].append(data)

    return result


from flask import Flask, session, render_template, request, redirect

from mysqlconnection import connectToMySQL

app = Flask(__name__)
app.secret_key = "ThisKeyIsSecret"

mysql = connectToMySQL('friendsdb')
all_friends = mysql.query_db("SELECT * FROM friends")
print("Fetched all friends", all_friends)

# @app.route('/')
# def index():
#     mysql = connectToMySQL('friendsdb')
#     all_friends = mysql.query_db("SELECT * FROM friends")
#     print("Fetched all friends", all_friends)
#     return render_template('index.html', friends = all_friends)

if __name__ == "__main__":
    app.run(debug=True)


import progressbar
import nltk
import os
from itertools import combinations

class BioCreative(object):

    def __init__(self, root_directory, tokenizer, relation_type):
        """
        object that represents BioCreative dataset.
        :param root_directory: directory where biocreative dataset exitst
        :param tokenizer: tokenizer to be used: NLTK
        :param relation_type: relation type: binary or multiclass
        """

        self.root_directory = root_directory
        self.tokenizer = tokenizer
        self.relation_type = relation_type

        # dataset represents -> [train_instance, train_labels, dev_instance, dev_labels, test_instance, test_label]
        self.dataset = [None] * 6

        # prepare dataset
        print('Start to prepare dataset')
        self.dataset[0], self.dataset[1] = self.prepare_dataset(dataset_type='training')
        self.dataset[2], self.dataset[3] = self.prepare_dataset(dataset_type='development')
        self.dataset[4], self.dataset[5] = self.prepare_dataset(dataset_type='test')

    def prepare_dataset(self, dataset_type):

        abstracts_location = ''
        entities_location = ''
        relations_location = ''
        if dataset_type == 'training':
            training_directory = os.path.join(self.root_directory, 'chemprot_training', 'chemprot_training')
            abstracts_location = os.path.join(training_directory, "chemprot_training_abstracts.tsv")
            entities_location = os.path.join(training_directory, "chemprot_training_entities.tsv")
            relations_location = os.path.join(training_directory, "chemprot_training_relations.tsv")
        elif dataset_type == 'development':
            development_directory = os.path.join(self.root_directory, 'chemprot_development', 'chemprot_development')
            abstracts_location = os.path.join(development_directory, "chemprot_development_abstracts.tsv")
            entities_location = os.path.join(development_directory, "chemprot_development_entities.tsv")
            relations_location = os.path.join(development_directory, "chemprot_development_relations.tsv")
        elif dataset_type == 'test':
            test_directory = os.path.join(self.root_directory, 'chemprot_test_gs', 'chemprot_test_gs')
            abstracts_location = os.path.join(test_directory, "chemprot_test_abstracts_gs.tsv")
            entities_location = os.path.join(test_directory, "chemprot_test_entities_gs.tsv")
            relations_location = os.path.join(test_directory, "chemprot_test_relations_gs.tsv")

        abstracts = self.parse_abstract_file(abstracts_location)
        entities = self.parse_entity_file(entities_location)
        relations = self.parse_relation_file(relations_location)

        data = []
        labels = []

        progress_bar = progressbar.ProgressBar(maxval=len(abstracts),
                                               widgets=["Preparing {} dataset: ".format(dataset_type),
                                                        progressbar.Bar('=', '[', ']'),
                                                        ' ',
                                                        progressbar.Percentage()])
        progress_bar_counter = 0
        progress_bar.start()

        # for each abstract
        for abstract_id, abstract_text in abstracts.items():
            # get sentences
            sentences = nltk.sent_tokenize(abstract_text)

            # get sentence boundaries
            sentences_offsets = []
            for sentence in sentences:
                sentences_offsets.append(abstract_text.find(sentence))
            sentences_offsets.append(len(abstract_text))

            # find entities in the sentences
            sentence_entity_mapping = {}
            entities_in_abstract = entities[abstract_id]
            for entity in entities_in_abstract:
                entity_start_idx = entity['start_idx']
                entity_end_idx = entity['end_idx']
                for sentence_id in range(len(sentences)):
                    sentence_start = sentences_offsets[sentence_id]
                    sentence_end = sentences_offsets[sentence_id + 1]
                    if sentence_start <= int(entity_start_idx) and int(entity_end_idx) <= sentence_end:
                        if sentence_id not in sentence_entity_mapping:
                            sentence_entity_mapping[sentence_id] = []
                        sentence_entity_mapping[sentence_id].append(entity)
                        break

            # create training data
            for sentence_id, entities_in_sentence in sentence_entity_mapping.items():
                sentence_text = sentences[sentence_id]
                comb = combinations(entities_in_sentence, 2)
                for pair in comb:
                    arg1_entity_type = pair[0]['entityType']
                    arg2_entity_type = pair[1]['entityType']

                    if (arg1_entity_type == 'CHEMICAL' and arg2_entity_type != 'CHEMICAL') or \
                            (arg1_entity_type != 'CHEMICAL' and arg2_entity_type == 'CHEMICAL'):
                        sentence_start = sentences_offsets[sentence_id]

                        arg1_start = int(pair[0]['start_idx']) - sentence_start
                        arg2_start = int(pair[1]['start_idx']) - sentence_start

                        instance = [abstract_id, sentence_text,
                                    pair[0]['entityID'], pair[0]['name'], pair[0]['entityType'], str(arg1_start),
                                    pair[1]['entityID'], pair[1]['name'], pair[1]['entityType'], str(arg2_start)]
                        data.append(instance)

                        relations_in_abstracts = []
                        if abstract_id in relations:
                            relations_in_abstracts = relations[abstract_id]

                        label = self.check_instance_relation(relations_in_abstracts,
                                                             instance[2],
                                                             instance[6])
                        label = int(label)
                        if self.relation_type == 'binary':
                            if label != 0:
                                label = 1
                        labels.append(label)

            progress_bar_counter = progress_bar_counter + 1
            progress_bar.update(progress_bar_counter)
        progress_bar.finish()

        return data, labels

    def get_dataset(self):
        return self.dataset

    @staticmethod
    def check_instance_relation(relation_list, arg1, arg2):
        """
        takes the candidate relation and assign label to it.
        :param relation_list: relations list in abstract
        :param arg1: entity id of argument 1 in candidate relation
        :param arg2: entity id of argument 2 in candidate relation
        :return: (string) candidate relation label
        """

        for relation in relation_list:
            relation_arg1 = relation['arg_1']
            relation_arg2 = relation['arg_2']
            if relation_arg1 == arg1 and relation_arg2 == arg2:
                return relation['CPR']
            elif relation_arg2 == arg1 and relation_arg1 == arg2:
                return relation['CPR']
        return '0'

    @staticmethod
    def parse_abstract_file(file_location):
        """
        takes BioCreative abstract file and returns a dictionary.
        :return result: dictionary stores abstract ids and corresponding abstract
        '16357751' = full text of the abstract
        """

        result = {}
        with open(file_location, 'r', encoding="utf8") as file:
            lines = file.readlines()
        for line in lines:
            line = line.split('\t')
            abstract_id = line[0]
            abstract_title = line[1]
            abstract_text = line[2]
            full_abstract_text = abstract_title + ' ' + abstract_text
            result[abstract_id] = full_abstract_text
        return result

    @staticmethod
    def parse_entity_file(file_location):
        """
        takes biocreative entity file and return a dictionary
        :return result: entities dictionary. Each abstract key contains a entity dict
        '11319232' = [{'abstractID': '11319232', 'entityID': 'T1', 'entityType': 'CHEMICAL', 'start_idx': '242', 'end_idx': '251', 'name': 'acyl-CoAs'},
                      {'abstractID': '11319232', 'entityID': 'T2', 'entityType': 'CHEMICAL', 'start_idx': '1193', 'end_idx': '1201', 'name': 'triacsin'},
                      ... , ]
        """

        result = {}
        with open(file_location, 'r', encoding="utf-8") as file:
            lines = file.readlines()
        for line in lines:
            line = line.split('\t')
            entity = {'abstractID': line[0],
                      'entityID': line[1],
                      'entityType': line[2],
                      'start_idx': line[3],
                      'end_idx': line[4],
                      'name': line[5][:-1]}
            if line[0] not in result:
                result[line[0]] = []
            result[line[0]].append(entity)
        return result

    @staticmethod
    def parse_relation_file(file_location):
        """
        takes the biocreative relation files and returns content dictionary
        :return result: (dictionary) abstract_id -> (list)relations
        '10047461' = [{'abstractID': '10047461', 'CPR': '3', 'eval_status': 'Y ', 'relation_type': 'ACTIVATOR', 'arg_1': 'T13', 'arg_2': 'T57'},
                      {'abstractID': '10047461', 'CPR': '3', 'eval_status': 'Y ', 'relation_type': 'ACTIVATOR', 'arg_1': 'T7', 'arg_2': 'T39'},
                      ... ]
        """
        result = {}
        with open(file_location, 'r', encoding="utf-8") as file:
            lines = file.readlines()
        for line in lines:
            line = line.split('\t')
            cpr_value = line[1].split(':')[-1]
            arg1_value = line[4].split(':')[-1]
            arg2_value = line[5][:-1].split(':')[-1]
            relation = {'abstractID': line[0],
                        'CPR': cpr_value,
                        'eval_status': line[2],
                        'relation_type': line[3],
                        'arg_1': arg1_value,
                        'arg_2': arg2_value}

            if line[0] not in result:
                result[line[0]] = []
            result[line[0]].append(relation)
        return result


import FWCore.ParameterSet.Config as cms

# link to card:
# https://github.com/cms-sw/genproductions/tree/master/bin/Powheg/production/V2/13TeV/Higgs/VBF_H_NNPDF30_13TeV/VBF_H_NNPDF30_13TeV_M-125.input

externalLHEProducer = cms.EDProducer("ExternalLHEProducer",
    args = cms.vstring('/cvmfs/cms.cern.ch/phys_generator/gridpacks/slc6_amd64_gcc630/13TeV/Powheg/V2/RelValidation/VBFH/VBF_H_slc6_amd64_gcc630_CMSSW_9_3_9_patch1_VBF_new.tgz'),
    nEvents = cms.untracked.uint32(5000),
    numberOfParameters = cms.uint32(1),
    outputFile = cms.string('cmsgrid_final.lhe'),
    scriptName = cms.FileInPath('GeneratorInterface/LHEInterface/data/run_generic_tarball_cvmfs.sh'),
    generateConcurrently = cms.untracked.bool(True)
)


#!/usr/bin/python

"""
    Compatibility of different python versions.
    Goal for now is to run on 2.6, 2.7 and 3.3 onwards.
    We skip versions prior to 2.6 and 3.1, 3.2, see Armin Ronachers blog
    post at http://lucumr.pocoo.org/2013/5/21/porting-to-python-3-redux/
"""

import sys
PY2 = sys.version_info[0] == 2

# Queue in python3 has moved:
try:
    from Queue import Queue
except ImportError:
    from queue import Queue

# String types, stolen from Armin Ronacher above
if not PY2:
    text_type = str
    string_types = (str,)
    unichr = chr
else:
    text_type = unicode
    string_types = (str, unicode)
    unichr = unichr


#!/usr/bin/python2
# coding: utf-8

import re
import sys

# Ouverture du fichier resultat
fichierFinal=open(sys.argv[2], "w")

# Pour chaque ligne du fichier
with open(sys.argv[1]) as f:
	for ligne in f:
		seqid=(ligne.split(" ")[0]).split(";")[0]
		liste_seq=ligne.split(" ")
		for sequence in liste_seq:
			fichierFinal.write (seqid + "\t" + sequence.split(";")[0] + "\n")
		# ---- Done ----
	# ---- Done ----
# ---- Fin with ----

fichierFinal.close()


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

import math
import scrapy
from pymongo import MongoClient
from scrapy.spidermiddlewares.httperror import HttpError
from twisted.internet.error import DNSLookupError, TimeoutError, TCPTimedOutError

class WuSong1991To2017Spider(scrapy.spiders.Spider):
    name = "wusong_1991_2017_spider"
    handle_httpstatus_list = [302]
    years = ["1950"]
    start_url_template="http://www.itslaw.com/search/lawsAndRegulations?searchMode=lawsAndRegulations&sortType=1&conditions=searchWord%2B%E7%9A%84%2B1%2B%E7%9A%84&conditions=publishDate%2B{0}%2B4%2B{1}"
    page_url_template="http://www.itslaw.com/api/v1/lawRegulations?startIndex={0}&countPerPage=20&sortType=1&conditions=searchWord%2B%E7%9A%84%2B1%2B%E7%9A%84&conditions=publishDate%2B{1}%2B4%2B{2}"

    def start_requests(self):
        for year in self.years:
            start_url=self.start_url_template.format(year,year)
            yield scrapy.Request(url=start_url,
                                 method="GET",
                                 callback=self.parse,
                                 meta={"start_url":start_url,"year":year})

    def parse(self, response):
        year=response.meta["year"]
        start_url=response.meta["start_url"]
        return scrapy.Request(url=self.page_url_template.format(str(0), year,year),
                              method="GET",
                              dont_filter=True,
                              meta={"start_url": start_url, "year": year},
                              callback=self.parse_page_count,
                              errback=self.handle_error)

    def parse_page_count(self, response):
         year = response.meta["year"]
         start_url = response.meta["start_url"]
         result=json.loads(response.body_as_unicode())
         count= result["data"]['lawRegulationArticleSearchResult']["publishDateResults"][0]["count"]
         next=[]
         next.extend(self.parse_page_list(response))
         if count>20:
             page_count = math.floor(count / 20)
             for page_index in range(1, int(page_count) + 1):
                 next.append(scrapy.Request(url=self.page_url_template.format(str(page_index*20), year, year),
                                       method="GET",
                                       headers={"Referer":start_url},
                                       dont_filter=True,
                                       callback=self.parse_page_list,
                                       errback=self.handle_error))
         return next

    def parse_page_list(self,response):
         result=json.loads(response.body_as_unicode())
         articles= result["data"]['lawRegulationArticleSearchResult']['lawRegulationArticles']
         next=[]
         for article in articles:
             if self.__existed_doc(article["lawRegulationId"]):
                 continue

             url = "http://www.itslaw.com/api/v1/lawRegulations/lawRegulation?lawAndRegulationId=%s" % article["lawRegulationId"]
             referer="http://www.itslaw.com/search/lawsAndRegulations/lawAndRegulation?lawAndRegulationId=%s"%article["lawRegulationId"]
             next.append(scrapy.Request(url=url,
                            method="GET",
                            headers={"Referer": referer},
                            dont_filter=True,
                            meta={"article":article},
                            callback=self.parse_detail,
                            errback=self.handle_error))
         return next

    def parse_detail(self,response):
        result = json.loads(response.body_as_unicode())
        article= response.meta["article"]
        article["content"]=result["data"]["lawRegulationDetail"]
        article["collection"]="wusong_law"
        return article

    def handle_error(self, failure):
        # log all failures
        self.logger.error(repr(failure))

        # in case you want to do something special for some errors,
        # you may need the failure's type:
        if failure.check(HttpError):
            # these exceptions come from HttpError spider middleware
            # you can get the non-200 response
            response = failure.value.response
            self.logger.error('HttpError on %s', response.url)
        elif failure.check(DNSLookupError):
            # this is the original request
            request = failure.request
            self.logger.error('DNSLookupError on %s', request.url)
        elif failure.check(TimeoutError, TCPTimedOutError):
            request = failure.request
            self.logger.error('TimeoutError on %s', request.url)

    def __existed_doc(self, lawAndRegulationId):
        """获取法院地域,获取所有没有子菜单的法院"""
        client = MongoClient(self.settings["MONGO_URI"], replicaSet=self.settings["MONGO_REPLICAT_SET"])
        db = client[self.settings["MONGO_DATABASE"]]
        db.authenticate(self.settings["MONGO_USERNAME"], self.settings["MONGO_PASSWORD"])
        result = db["wusong_law"].count({"lawAndRegulationId": lawAndRegulationId})
        return result > 0


import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

def plot_scores(df, start_index, filepath_output):
    fig, ax = plt.subplots()
    plt.plot(np.flip(df['Public Score'].values)[start_index:], color='blue', label='Public Score')
    plt.plot(np.flip(df['Private Score'].values)[start_index:], color='red', label='Private Score')
    numbers = np.flip(df['Num'].values)[start_index:]
    explanations = np.flip(df['Source'].values)[start_index:]
    xtick_labels = [str(numbers[i]) + ' (' + explanations[i]  + ')' for i in range(len(numbers))]
    plt.xticks(range(len(xtick_labels)), xtick_labels, rotation=90)
    plt.subplots_adjust(bottom=0.5)
    plt.legend()
    #plt.show()
    fig.set_figheight(10)
    fig.set_figwidth(15)
    plt.savefig(filepath_output)

df = pd.read_csv('data/scores.csv', sep='\s*,\s*')
plot_scores(df, 0, 'scores_all.png')
plot_scores(df, 11, 'scores_latest.png')


# Needed project interpreters:
# sklearn
import pickle
from api import read_data
import numpy as np

if __name__ == "__main__":
        # Read features and labels of csv file
        # text_mail is an array with all email bodies
        # label_mail is empty, because train_mode == False
        text_mail, label_mail, id_mail = read_data('pre_processing\email_test.csv', False)
        # Read the saved files created by trainer.py
        # Load SVM
        filename = 'svm_email.sav'
        loaded_model = pickle.load(open(filename, 'rb'))
        # Load vectorizer
        filename = 'tfidf_vectorizer.sav'  # Load the tfidf word matrix which the model trained
        tfidf_vectorizer = pickle.load(open(filename, 'rb'))
        # Vectorize features
        # tfidf_train_features is a word matrix, with all the words of the mails
        tfidf_test_features = tfidf_vectorizer.transform(text_mail)
        # Run predictor
        predictions = loaded_model.predict(tfidf_test_features)
        # Calculate the probabilities of the prediction
        output_proba = loaded_model.predict_proba(tfidf_test_features)

        for id, pred, proba in zip(id_mail, predictions, output_proba):
                ind = np.argpartition(proba, -1)[-1:]  # Take the better probability
                print("Row "+ str(id) + ": The exception \'"+ pred + "\' has been predicted with an accuracy of " + str(proba[ind]))


from django.urls import path, re_path, include
from manhana.authentication.views import *

app_name = 'authentication'
urlpatterns = [
    path('', VerificaUsuarioView.as_view(), name="verifica_user"),
    path('usuario/informacao_adicional/form/', InfoAdicionaisUserView.as_view(), name="info_adicional_user"),
    path('usuario/informacao_adicional/detalhe/', SelecionarVinculoView.as_view(), name="selecao_vinculo"),
    path('usuario/selecao/perfil/', SelecionarPerfilView.as_view(), name="selecao_perfil"),

    path('usuario/buscar/', BuscaPessoaView.as_view(), name='buscar_pessoa'),
    path('usuario/buscar/pessoa/detalhe/<int:id>/', DetalhaPessoaView.as_view(), name='detalha_pessoa'),
    path('usuario/buscar/pessoa/detalhe/<int:id>/confirma/username/', ConfirmaUsernameView.as_view(), name='confirma_username'),
    path('usuario/pessoa/<int:id_pessoa_sig>/existe/', UserExisteView.as_view(), name='conta_existe'),
    path('usuario/novo/confirmacao/', ConfirmacaoNovoUserView.as_view(), name='confirmacao_novo_user'),
    path('usuario/novo/pessoa/<int:id_pessoa_sig>/', UsuarioNovoView.as_view(), name="user_novo"),
]


#!/usr/bin/python
# coding: ISO-8859-1

"""
    ftp info
    ~~~~~~~~

    List information about the biggest files on a FTP server.

    :copyleft: 2012 by Jens Diemer
    :license: GNU GPL v3 or above
"""

__version__ = (0,0,1)
VERSION_STRING = '.'.join(str(part) for part in __version__)


"""
Defines classes for cage molecules.

The difference between :class:`CageStructUnit` and :class:`Cage`
is that :class:`CageStructUnit` is for cages loaded directly into
``stk``, while :class:`Cage` is for cages constructed by ``stk``.

"""

import numpy as np
import itertools as it
import warnings
import rdkit.Chem.AllChem as rdkit
import pywindow
from scipy.optimize import minimize
from sklearn.metrics.pairwise import euclidean_distances

from .macro_molecule import MacroMolecule
from .struct_unit import StructUnit
from ...utilities import atom_vdw_radii

class CageBase:
    """
    A base class for cage molecules.

    """

    def _cavity_size(self, origin, conformer):
        """
        Calculates diameter of the molecule from `origin`.

        The cavity is measured by finding the atom nearest to
        `origin`, correcting for van der Waals diameter and multiplying
        by -2.

        This function should not be used directly. Use
        :meth:`cavity_size` instead, which finds the optimal value of
        `origin` to use.

        Parameters
        ----------
        origin : :class:`numpy.ndarray`
            Holds the x, y and z coordinate of the position from which
            the cavity is measured.

        conformer : :class:`int`
            The id of the conformer to be used.

        Returns
        -------
        :class:`float`
            The (negative) diameter of the molecules cavity.

        """

        atom_vdw = np.array([atom_vdw_radii[x.GetSymbol()] for x
                            in self.mol.GetAtoms()])
        pos_mat = self.mol.GetConformer(conformer).GetPositions()
        distances = euclidean_distances(pos_mat, np.array([origin]))
        distances = distances.flatten() - atom_vdw
        return -2*min(distances)

    def cavity_size(self, conformer=-1):
        """
        Calculates the diameter of the molecule's cavity.

        Parameters
        ----------
        conformer : :class:`int`, optional
            The id of the conformer to be used.

        Returns
        -------
        :class:`float`
            The diameter of the molecule's cavity in Angstroms.

        """

        # This function uses _cavity_size() to calculate the cavity
        # size. _cavity_size() finds the closest atom to `origin` to
        # get its value of the cavity.

        # What this function does is finds the value of `origin` which
        # causes _cavity_size() to calculate the largest possible
        # cavity.
        ref = self.center_of_mass(conformer)
        icavity = 0.5*self._cavity_size(ref, conformer)
        bounds = [(coord+icavity, coord-icavity) for coord in ref]
        cavity_origin = minimize(
                            lambda x: self._cavity_size(x, conformer),
                            x0=ref,
                            bounds=bounds).x
        cavity = -self._cavity_size(cavity_origin, conformer)
        return 0 if cavity < 0 else cavity

class CageStructUnit(CageBase, StructUnit):
    """
    Represents molecular cages loaded into ``stk``.

    """

class Cage(CageBase, MacroMolecule):
    """
    Represents molecular cages constructed by ``stk``.

    """

    def window_difference(self, conformer=-1):
        """
        The average difference across window sizes.

        First take the average window difference between all windows
        of the same type. Then take the average of window differences
        across window types.

        Consider a triangular-based prism cage topology. Such a
        cage will have triangular windows and square windows. You
        only want to compare the triangulars with other
        triangular windows and squares only with other squares.

        Parameters
        ---------
        conformer : :class:`int`, optional
            The id of the conformer to use.

        Returns
        -------
        :class:`float`
            The total difference of window size when considering
            every combination of windows of the same type.

        None : :class:`NoneType`
            If not all windows were found.

        """

        windows = self.windows(conformer)

        if windows is None or len(windows) < self.topology.n_windows:
            return None

        windows = np.array(windows)

        # Cluster the windows into groups so that only size
        # differences between windows of the same type are taken
        # into account. To do this, first sort the windows by
        # size. If two windows types are present split the
        # windows at the two groups at the point where the window
        # sizes have the biggest difference. If there are three
        # types split it at the two biggest differences and so
        # on.

        diffs = list(abs(np.ediff1d(windows)))
        sorted_diffs = sorted(diffs, reverse=True)

        # Get indices of where the list should be split.
        split = []
        for x in range(self.topology.n_window_types-1):
            i = diffs.index(sorted_diffs[x]) + 1
            split.append(i)

        # Get the sub-lists.
        og = list(windows)
        clusters = []
        for i in sorted(split, reverse=True):
            clusters.append(og[i:])
            og = og[:i]

        if self.topology.n_window_types == 1:
            clusters.append(og)

        # After this sum the differences in each group and then
        # sum the group totals.
        diff_sums = []
        for cluster in clusters:
            diff_sum = sum(abs(w1 - w2) for w1, w2 in
                           it.combinations(cluster, 2))

            diff_num = sum(1 for _ in it.combinations(cluster, 2))

            diff_sums.append(diff_sum / diff_num)

        return np.mean(diff_sums)

    def window_variance(self, conformer=-1):
        """
        The variance in window sizes.

        For cages where multiple window types are present, the
        window variance within each window type is calculated first and
        the returned value is the mean of these variances.

        Parameters
        ---------
        conformer : :class:`int`, optional
            The id of the conformer to use.

        Returns
        -------
        :class:`float`
            The variance in window sizes.

        """

        windows = self.windows(conformer)

        if windows is None or len(windows) < self.topology.n_windows:
            return None

        windows = np.array(windows)

        # Cluster the windows into groups so that only size
        # differences between windows of the same type are taken
        # into account. To do this, first sort the windows by
        # size. If two windows types are present split the
        # windows at the two groups at the point where the window
        # sizes have the biggest difference. If there are three
        # types split it at the two biggest differences and so
        # on.

        diffs = list(abs(np.ediff1d(windows)))
        sorted_diffs = sorted(diffs, reverse=True)

        # Get indices of where the list should be split.
        split = []
        for x in range(self.topology.n_window_types-1):
            i = diffs.index(sorted_diffs[x]) + 1
            split.append(i)

        # Get the sub-lists.
        og = list(windows)
        clusters = []
        for i in sorted(split, reverse=True):
            clusters.append(og[i:])
            og = og[:i]

        if self.topology.n_window_types == 1:
            clusters.append(og)

        variances = [np.var(c) for c in clusters]
        return np.mean(variances)

    def windows(self, conformer=-1):
        """
        Returns window sizes found by ``pywindow``.

        Parameters
        ----------
        conformer : :class:`int`, optional
            The id of the conformer to use.

        Returns
        -------
        None : :class:`NoneType`
            If the function for finding windows and their sizes
            found fewer than the required number of windows or
            if it failed for some other reason.

        :class:`list` of :class:`float`
            Each :class:`float` represents the size of a
            window in the cage. If the window finding function
            found more than the expected number of windows, only
            the largest ``n`` windows are returned. Where ``n`` is the
            number of expected windows for that cage topology.

        """

        with warnings.catch_warnings():
            warnings.simplefilter("ignore")
            # Load an RDKit molecule object to pywindow.

            # As pywindow doesnt support multiple conformers, first
            # make an rdkit molecule holding only the desired
            # conformer.
            new_mol = rdkit.Mol(self.mol)
            new_mol.RemoveAllConformers()
            new_mol.AddConformer(self.mol.GetConformer(conformer))

            loader = pywindow.molecular.Molecule.load_rdkit_mol
            pw_molecule = loader(new_mol)
            # Find windows and get a single array with windows' sizes.
            all_windows = pw_molecule.calculate_windows()

        # If pywindow failed, return ``None``.
        if all_windows is None:
            return None

        # pywindow sometimes detects super large windows by accident,
        # filter them out first.
        valid_windows = sorted((w for w in all_windows if w < 1e6),
                               reverse=True)
        return valid_windows[:self.topology.n_windows]

class CageComplex(MacroMolecule):
    """
    Represents a cage-guest system.

    """

    pass


def partial_sums(l):
		sum_even = 0
		sum_odd = 0
		for i in range(len(l)):
				if i % 2 == 0:
						sum_even += l[i]
				else:
						sum_odd += l[i]
		print("Sum of the elements at even indices:", sum_even)
		print("Sum of the elements at odd indices:", sum_odd)

# test case
partial_sums([1,-2,7.89,3.4,2])


import json
from ldclient.client import Config
from ldclient.user_filter import UserFilter

base_config = Config("fake_sdk_key")
config_with_all_attrs_private = Config("fake_sdk_key", all_attributes_private = True)
config_with_some_attrs_private = Config("fake_sdk_key", private_attribute_names=set([u'firstName', u'bizzle']))

# users to serialize

user = {
    u'key': u'abc',
    u'firstName': u'Sue',
    u'custom': {
        u'bizzle': u'def',
        u'dizzle': u'ghi'
    }
}

user_specifying_own_private_attr = {
    u'key': u'abc',
    u'firstName': u'Sue',
    u'custom': {
        u'bizzle': u'def',
        u'dizzle': u'ghi'
    },
    u'privateAttributeNames': [ u'dizzle', u'unused' ]
}

user_with_unknown_top_level_attrs = {
    u'key': u'abc',
    u'firstName': u'Sue',
    u'species': u'human',
    u'hatSize': 6,
    u'custom': {
        u'bizzle': u'def',
        u'dizzle': u'ghi'
    }
}

anon_user = {
    u'key': u'abc',
    u'anonymous': True,
    u'custom': {
        u'bizzle': u'def',
        u'dizzle': u'ghi'
    }
}

# expected results from serializing user

user_with_all_attrs_hidden = {
    u'key': u'abc',
    u'custom': { },
    u'privateAttrs': [ u'bizzle', u'dizzle',  u'firstName' ]
}

user_with_some_attrs_hidden = {
    u'key': u'abc',
    u'custom': {
        u'dizzle': u'ghi'
    },
    u'privateAttrs': [ u'bizzle',  u'firstName' ]
}

user_with_own_specified_attr_hidden = {
    u'key': u'abc',
    u'firstName': u'Sue',
    u'custom': {
        u'bizzle': u'def'
    },
    u'privateAttrs': [ u'dizzle' ]
}

anon_user_with_all_attrs_hidden = {
    u'key': u'abc',
    u'anonymous': True,
    u'custom': { },
    u'privateAttrs': [ u'bizzle', u'dizzle' ]
}

def test_all_user_attrs_serialized():
    uf = UserFilter(base_config)
    j = uf.filter_user_props(user)
    assert j == user

def test_all_user_attrs_private():
    uf = UserFilter(config_with_all_attrs_private)
    j = uf.filter_user_props(user)
    assert j == user_with_all_attrs_hidden

def test_some_user_attrs_private():
    uf = UserFilter(config_with_some_attrs_private)
    j = uf.filter_user_props(user)
    assert j == user_with_some_attrs_hidden

def test_per_user_private_attr():
    uf = UserFilter(base_config)
    j = uf.filter_user_props(user_specifying_own_private_attr)
    assert j == user_with_own_specified_attr_hidden

def test_per_user_private_attr_plus_global_private_attrs():
    uf = UserFilter(config_with_some_attrs_private)
    j = uf.filter_user_props(user_specifying_own_private_attr)
    assert j == user_with_all_attrs_hidden

def test_unknown_top_level_attrs_stripped():
    uf = UserFilter(base_config)
    j = uf.filter_user_props(user_with_unknown_top_level_attrs)
    assert j == user

def test_leave_anonymous_attr_as_is():
    uf = UserFilter(config_with_all_attrs_private)
    j = uf.filter_user_props(anon_user)
    assert j == anon_user_with_all_attrs_hidden


class Solution:
    def subarraysWithKDistinct(self, A: List[int], K: int) -> int:
        return self.atMostK(nums, k) - self.atMostK(nums, k-1)

    def atMostK(self, A: str, K: int) -> int:  # subarray with at most K different numbers
        # (0) edge case
        if not A:
            return 0

        # (1) initialize
        d = {}
        l, res = 0, 0

        # (2) traverse array
        for r in range(len(A)):
            d[A[r]] = d.get(A[r], 0) + 1   # (2.1) add characters of s into dictionary

            while len(d) > K:              # (2.2) deal with len(d) > 2
                d[A[l]] -= 1
                if d[A[l]] == 0:
                    del d[A[l]]
                l += 1

            res += r-l+1                   # (2.3) update the maxwindow

        # (3) return result
        return res

# Time: O(N)
# Space: O(N)

14 Sliding Window/992. Subarrays with K Different Integers.py


# based on: https://github.com/ericwoolard/CS-GO-Update-Notifier

import io
import json
import os
import sys

def save(path, data_str, mode='w'):
    path = ensureAbsPath(path)
    try:
        with io.open(path, mode, encoding='utf-8') as f:
            f.write(str(data_str))
    except IOError:
        directory = os.path.dirname(path)
        if not os.path.isdir(directory):
            try:
                os.makedirs(directory)
            except OSError as oserr:
                pass
        if os.path.isdir(directory):
            return save(path, data_str, mode)
        else:
            print(f'Could not write to {path}')
            return False
    else:
        return True

def read(path):
    path = ensureAbsPath(path)
    try:
        fileContents = ''
        with open(path) as f:
            fileContents = f.read()
        return fileContents
    except IOError:
        print(f'Could not find or open file: {path}')
        return False

def ensureAbsPath(path):
    botRootDir = os.path.dirname(os.path.abspath(sys.argv[0])) + '/'
    return path if os.path.isabs(path) else botRootDir + path

def saveJson(path, data):
    return save(
        path,
        json.dumps(
            data,
            ensure_ascii=False,
            indent=4,
            separators=(',', ': ')
        )
    )

def readJson(path):
    f = read(path)
    if f:
        try:
            return json.loads(f)
        except ValueError:
            print(f'Could not parse JSON file: {path}')
            return False
    else:
        return False

def updateJson(path, v, k):
    jsonFile = open(path, 'r')
    data = json.load(jsonFile)
    jsonFile.close()

    tmp = data[k]
    data[k] = v

    jsonFile = open(path, "w+")
    jsonFile.write(json.dumps(data, indent=4))
    jsonFile.close()


#coding=utf-8
__author__ = 'Li Baoshan'
__date__ = "2019/5/18 16:40"
from django import forms
from django.forms import ModelForm
from operation.models import UserAsk

import re

#利用ModelFrom将Model转化为form,不再继承form.Form
class UserAskForm(ModelForm):
    class Meta:
        model=UserAsk
        fields=['name','mobile','course_name']

    def clean_mobile(self):
        """
        验证手机号码是否合法
        """
        mobile=self.cleaned_data['mobile']
        REGEX_MOBILE="^1[358]\d{9}$|^147\d{8}$|^176\d{8}$"
        p=re.compile(REGEX_MOBILE)
        if p.match(mobile):
            return mobile
        else:
            raise forms.ValidationError(u'手机号码非法',code="mobile_invalid")


# -*- coding: utf-8 -*-
#
# Nitrate is copyright 2010 Red Hat, Inc.
#
# Nitrate is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version. This program is distributed in
# the hope that it will be useful, but WITHOUT ANY WARRANTY; without
# even the implied warranties of TITLE, NON-INFRINGEMENT,
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
#
# The GPL text is available in the file COPYING that accompanies this
# distribution and at <http://www.gnu.org/licenses>.
#
# Authors:
#   Xuqing Kuang <xkuang@redhat.com>

import qpid.messaging
from datetime import datetime
from base import QPIDBase

class QPIDSender(QPIDBase):
    def __init__(self, url, **kwargs):
        super(QPIDSender, self).__init__(url, **kwargs)
        self.sender = None

    def init_sender(self):
        """Initial the sender"""
        if not self.session:
            self.init_session()
        self.sender = self.session.sender(self.queue_name)

    def send(self, content, properties = {}):
        """Sending the content"""
        if not self.sender:
            self.init_sender()
        message = qpid.messaging.Message(properties=properties, content = content)
        self.sender.send(message)

    def typing(self):
        """Sending the contents real time with typing"""
        content = ''
        while content != 'EOF':
            content = raw_input('Start typing:')
            self.send(content)

if __name__ == '__main__':
    s = QPIDSender()
    s.send('Testing at %s' % datetime.now())
    s.close()


from predict import predict_from_text
import argparse

parser = argparse.ArgumentParser()

parser.add_argument("text",
                   help="Please enter the sentence you want to predict",
                   type=str)
parser.add_argument("-f",
                   "--filepath",
                   help="The path of the file that stores the learned weights",
                   type=str,
                   default="./model/model_weights.pth")

args = parser.parse_args()

predict_from_text(args.text, args.filepath)


"""
"""
import sys
import argparse
import peewee

import database.db_queries as queries

from main_functions import fetch_image_urls, get_image, get_image_bulk, process_tags, save, save_file
from database.database import connect_db
from downloaders import DownloaderManager

__author__ = 'Chronoes'

def init_parser():
    parser = argparse.ArgumentParser(
        description='''
        Retrieve image from URL and save tags to local DB.
        Currently supported Gelbooru, Konachan and Yande.re.''')
    parser.add_argument('-o', '--out',
        help='Custom filename for destination. Only works for single URL source')
    # parser.add_argument('-s', '--series',
    #     action='store_true',
    #     help='Read source file of URLs as an image series. Multiple series must be separated by newline.')
    parser.add_argument('--redownload',
        help='Redownload options: =images that do not exist in filesystem (--force for all). =metadata to redownload metadata.',
        choices=('images', 'metadata'))
    parser.add_argument('-f', '--force',
        action='store_true',
        help='Apply some force.')
    parser.add_argument('-g', '--group',
        help='Group to be used for image')
    parser.add_argument('source', nargs='?', default='-',
        help='Source must be a valid URL or file of URLs')
    return parser

def main():
    parser = init_parser()
    args = parser.parse_args()
    connect_db()

    try:
        img_group = queries.find_group(args.group) if args.group else None
    except peewee.DoesNotExist as e:
        raise Exception(f'No such image group {args.group}') from e

    if args.redownload == 'images':
        urls = fetch_image_urls(img_group, args.force)
        def redownload_images_cb(result, error=False):
            if error:
                print(result)
            else:
                save_file(result)
                print(f'Image {result["original_link"]} redownloaded.')

        get_image_bulk(urls, redownload_images_cb, redownload=True)
    elif args.redownload == 'metadata':
        urls = fetch_image_urls(img_group, True)
        def redownload_metadata_cb(result, error=False):
            if error:
                print(result)
            else:
                img = queries.find_by_filename(result['filename'])
                process_tags(img, result['tags'])
                print(f'Image {result["filename"]} ({result["original_link"]}) metadata redownloaded.')

        get_image_bulk(urls, redownload_metadata_cb, redownload=True, skip_data=True)
    elif args.source.startswith('http'):
        if img_group is None:
            raise Exception('--group option must be specified for HTTP link as source')
        manager = DownloaderManager()
        downloader = manager.determine_downloader(args.source)
        if 'out' in args:
            img_info = get_image(downloader, custom_name=args.out)
        else:
            img_info = get_image(downloader)
        if type(img_info) == str:
            print(img_info)
        else:
            img_info['group'] = img_group.name
            save(img_info)
    else:
        file = sys.stdin if args.source == '-' else open(args.source, 'r')
        with file as f:
            urls = []
            for line in f:
                line = line.strip()
                if line == 'series' or line == 'end series':
                    urls.append((None, line))
                else:
                    parts = line.split(' ', maxsplit=1)
                    if len(parts) == 1:
                        if img_group is None:
                            raise Exception('Lines in file must have format if --group is not set: <group> <url>')
                        else:
                            urls.append((img_group.name, parts[0]))
                    else:
                        urls.append(tuple(parts))

        def save_image_cb(result, error=False):
            if error:
                print(result)
            else:
                save(result)

        get_image_bulk(urls, save_image_cb, redownload=bool(args.redownload))

if __name__ == '__main__':
    main()


import re
import requests
import pandas as pd
from bs4 import BeautifulSoup
import vaxutils

def read(source: str) -> pd.Series:
    soup = BeautifulSoup(requests.get(source).content, "html.parser")
    date = parse_date(soup)
    return parse_data(soup).pipe(vaxutils.enrich_data, 'date', date)

def parse_data(soup: BeautifulSoup) -> pd.Series:
    table = soup.find(class_="govstyleTable-default")
    data = pd.read_html(str(table))[0]
    return data.set_index(data.columns[0]).T.squeeze()

def parse_date(soup: BeautifulSoup) -> str:
    date = re.search(r"Data applies to: Week ending (\d[\w\s]+\d{4})", soup.text).group(1)
    date = str(date)
    return vaxutils.clean_date(date, "%d %B %Y")

def translate_index(input: pd.Series) -> pd.Series:
    return input.rename({
        'Total number of first dose vaccinations': 'people_vaccinated',
        'Total number of second dose vaccinations': 'people_fully_vaccinated',
        'Total number of doses': 'total_vaccinations',
    })

def enrich_location(input: pd.Series) -> pd.Series:
    return vaxutils.enrich_data(input, 'location', "Jersey")

def enrich_vaccine(input: pd.Series) -> pd.Series:
    return vaxutils.enrich_data(input, 'vaccine', "Oxford/AstraZeneca, Pfizer/BioNTech")

def enrich_source(input: pd.Series) -> pd.Series:
    return vaxutils.enrich_data(input, 'source_url',
                                "https://www.gov.je/Health/Coronavirus/Vaccine/Pages/VaccinationStatistics.aspx")

def pipeline(input: pd.Series) -> pd.Series:
    return (
        input.pipe(translate_index)
            .pipe(enrich_location)
            .pipe(enrich_vaccine)
            .pipe(enrich_source)
    )

def main():
    source = "https://www.gov.je/Health/Coronavirus/Vaccine/Pages/VaccinationStatistics.aspx"
    data = read(source).pipe(pipeline)

    vaxutils.increment(
        location=str(data['location']),
        total_vaccinations=int(data['total_vaccinations']),
        people_vaccinated=int(data['people_vaccinated']),
        people_fully_vaccinated=int(data['people_fully_vaccinated']),
        date=str(data['date']),
        source_url=str(data['source_url']),
        vaccine=str(data['vaccine'])
    )

if __name__ == "__main__":
    main()


# stdlib
from functools import wraps
import re
import sys

from jnpr.junos.exception import RpcError
from jnpr.junos import jxml as JXML

def timeoutDecorator(function):
    @wraps(function)
    def wrapper(*args, **kwargs):
        if 'dev_timeout' in kwargs:
            try:
                dev = args[0].dev
            except:
                dev = args[0]
            restore_timeout = dev.timeout
            dev.timeout = kwargs.pop('dev_timeout', None)
            try:
                result = function(*args, **kwargs)
                dev.timeout = restore_timeout
                return result
            except Exception:
                dev.timeout = restore_timeout
                raise
        else:
            try:
                return function(*args, **kwargs)
            except Exception:
                raise

    return wrapper

def normalizeDecorator(function):
    @wraps(function)
    def wrapper(*args, **kwargs):
        if 'normalize' in kwargs:
            normalize = kwargs.pop('normalize', None)
            try:
                dev = args[0].dev
            except:
                dev = args[0]

            if dev._normalize != normalize:
                restore_transform = dev.transform

                if normalize is False:
                    try:
                        dev.transform = dev._nc_transform
                        result = function(*args, **kwargs)
                        dev.transform = restore_transform
                        return result
                    except Exception:
                        dev.transform = restore_transform
                        raise
                else:
                    try:
                        dev.transform = dev._norm_transform
                        result = function(*args, **kwargs)
                        dev.transform = restore_transform
                        return result
                    except Exception:
                        dev.transform = restore_transform
                        raise
            else:
                try:
                    return function(*args, **kwargs)
                except Exception:
                    raise
        else:
            try:
                return function(*args, **kwargs)
            except Exception:
                raise

    return wrapper

def ignoreWarnDecorator(function):
    """
    Ignore warnings if all <rpc-error> elements are at severity 'warning' and
    match one of the values of the ignore_warning argument.

    For example::
        dev.rpc.get(ignore_warning=True)
        dev.rpc.get(ignore_warning='vrrp subsystem not running')
        dev.rpc.get(ignore_warning=['vrrp subsystem not running',
                                    'statement not found'])
        cu.load(cnf, ignore_warning='statement not found')

    :ignore_warning: A boolean, string or list of string.
        If the value is True, it will ignore all warnings regarldess of the
        warning message. If the value is a string, it will ignore warning(s) if
        the message of each warning matches the string. If the value is a list
        of strings, ignore warning(s) if the message of each warning matches at
        least one of the strings in the list.

    .. note::
            When the value of ignore_warning is a string, or list of strings,
            the string is actually used as a case-insensitive regular
            expression pattern. If the string contains only alpha-numeric
            characters, as shown in the above examples, this results in a
            case-insensitive substring match. However, any regular expression
            pattern supported by the re library may be used for more
            complicated match conditions.
    """
    @wraps(function)
    def wrapper(*args, **kwargs):
        ignore_warn = kwargs.pop('ignore_warning', False)
        if ignore_warn:
            try:
                result = function(*args, **kwargs)
                return result
            except RpcError as ex:
                if hasattr(ex, 'errs'):
                    for err in ex.errs:
                        if err['severity'] == 'warning':
                            if ((sys.version < '3' and
                                 isinstance(ignore_warn, (str, unicode))) or
                                (sys.version >= '3' and
                                 isinstance(ignore_warn, str))):
                                if not re.search(ignore_warn, err['message'],
                                                 re.I):
                                    # Message did not match.
                                    raise ex
                            elif isinstance(ignore_warn, list):
                                for warn_msg in ignore_warn:
                                    if re.search(warn_msg, err['message'],
                                                 re.I):
                                        # Warning matches. Break skips else.
                                        break
                                else:
                                    # Message didn't match any of the
                                    # ignore_warn pattern values.
                                    raise ex
                        else:
                            # Not a warning (probably an error).
                            raise ex
                    # Every err was a warning that matched ignore_warn
                    return ex.xml
                else:
                    # Safety net.
                    # I can't think of a situation where this would occur.
                    raise ex
        else:
            return function(*args, **kwargs)

    return wrapper


# -*- coding: utf-8 -*-
# This plugins is licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php
# Authors: Yusuke Kishita <yuusuuke.kishiita@gmail.com>, Kenji Hosoda <hosoda@s-cubism.jp>
from gluon import *

# For referencing static and views from other application
import os
APP = os.path.basename(os.path.dirname(os.path.dirname(__file__)))

def setup(managed_html):
    managed_html.settings.smarteditor_plugins.append(URL(APP, 'static', 'plugin_managed_gallery/smarteditor_plugin.coffee'))
    managed_html.settings.content_types['gallery'] = content_block

def content_block(managed_html, kwdargs):
    name = kwdargs.get('name')
    content_type = kwdargs.get('type')
    @managed_html.content_block(name,
                       Field('gallery', label='gallery', default=''),
                       Field('width', label='width', default='500'),
                       Field('height', label='height', default='300'),
                       Field('effect', label='effect', default='wave'),
                       Field('delay', label='delay', default='5'),
                       parent=None, content_type=content_type)
    def _(content):
        from gluon.utils import web2py_uuid
        uuid = web2py_uuid()
        if not content.gallery:
            current.response.write(XML('Gallery'), escape=False)
            return
        files = managed_html.db(managed_html.db.managed_html_file.id.belongs(content.gallery.split(','))).select()
        current.response.write(XML("""<div id='%s'>"""%uuid).xml(),escape=False)
        for file in files:
            current.response.write(XML("""<img file_id='%s' src='%s'/>"""%(file.id, URL('static', 'uploads/contents/%s'%file.name))).xml(),escape=False)
        current.response.write(XML("""
</div>
<script type="text/javascript" src="%s"></script>
<script type="text/javascript">
jQuery(function($) {
$('#%s').jqFancyTransitions({ width: %s, height: %s , effect: '%s', delay: %s});
});
</script>
"""%(URL(APP, 'static', 'plugin_managed_gallery/jqFancyTransitions.1.8.min.js'),
    uuid,
    content.width,
    content.height,
    content.effect,
    int(content.delay or 5) * 1000,
    )).xml(),
    escape=False)
    return _


# Fernando Valadez-Nunez
# 02/27/2020

# Problem 5
# Use the following chunk of code to produce the image shown below.

import turtle
def drawSquare (t, size):
    for i in range (4):
        t.forward(size)
        t.left(90)

def main():
    wn = turtle.Screen()
    wn.bgcolor('white')
    pat = turtle.Turtle()
    pat.pensize(2)
    pat.speed(10)
    pat.color('blue')
    space = -10

    for i in range(20, 105, 20):
        drawSquare(pat,i)
        pat.up()
        pat.goto(space, space)
        pat.down()
        space = space - 10
    wn.exitonclick()
main()


import utils
import json

import newspaper
from newspaper import Article
import sqlite3

from  pyvi import ViTokenizer as tach_tu
from Stopword import *
def match_data(keyword_format): # hàm trả về kết quả các bài báo liên quan tới key word
    conn = sqlite3.connect("data/crawlingDB.db")
    query = """SELECT * FROM news where description like ? or subject like ?"""
    data = conn.execute(query, (keyword_format,keyword_format)).fetchall()
    conn.commit()
    return data

def get_news_id(news_id):
    news = []
    conn = sqlite3.connect("DATA/crawlingDB.db")
    query = """
    SELECT N.id, N.subject, N.description, N.image, N.original_url, C.name, C.url
    FROM news N INNER JOIN category C on N.category_id = C.id
    WHERE N.id=?
    """
    row = conn.execute(query,(news_id, )).fetchone()
    print(row)
    conn.close()
    new = [{'id': int(row[0])}, {'subject': row[1]}, {'description': row[2]}, {'image': row[3]},
               {'original_url': row[4]}, {'category_id': row[5]}]
    return new

def creat_word_count_dict(data):
    # tạo thư viện chứa các từ
    words = ""
    for item in data:
        for i in item:
            words += i

    words = tach_tu.tokenize(words)
    #print("Nội dung sau khi word segmentation: ",str(words))
    words = words.split()
    words_dict = set(words)
    #print("Các từ trong nội dung: ",words_dict)
    words_count_dict = dict.fromkeys(words_dict, 0)

    # đếm số lượng từ xuất hiện trong thư viện
    for word in words:
        words_count_dict[word] += 1
    return dict(words_count_dict)

def compute_TF(word_count_dict, bow):
    tf_dict = {}
    bow_count = len(bow)
    for word, count in word_count_dict.items():
        tf_dict[word] = round(count/float(bow_count),2)
    #print("compute_TF", tf_dict) ###
    return tf_dict

def compute_IDF(doc_list):
    import math
    idf_dict = {}
    N = len(doc_list)

    idf_dict = dict.fromkeys(doc_list.keys(), 0)

    for word, count in doc_list.items():
        if count > 0:
            idf_dict[word] += 1

    for word, count in idf_dict.items():
        idf_dict[word] = round(math.log(N / float(count)),2)
    #print("compute_IDF", idf_dict)  ###
    return idf_dict

def compute_TFIDF(tf_bow, idfs):
    tfidf = {}
    for word, val in tf_bow.items():
        tfidf[word] = round((val*idfs[word]),2)
    #print("compute_TFIDF", tfidf)  ###
    return tfidf

#read category
def read_category():
    rows = utils.get_all("SELECT  * FROM category")
    data = []
    for r in rows:
        data.append(
            {"id": r[0],
             "subject": r[1],
             "url": r[2]
             }
        )
    with open("json_file/category.json", "w") as cat:
        json.dump(data, cat)
    #return render_template("category.html", data=data)

# read news
def get_news():
    rows = utils.get_all("SELECT * FROM news")
    data = []
    for r in rows:
        data.append(
        {
            "id": r[0],
            "subject": r[1],
            "description": r[2],
            "image": r[3],
            "original_url": r[4],
            "category_id": r[5]
        })
    with open("json_file/news.json", "w", encoding= "utf8") as f:
        json.dump(data, f)

def read_news(keywords = None):
    with open("json_file/news.json", encoding= "utf8") as f:
        news = json.load(f)
        print(news)
    if keywords:
        news = [n for n in news if n["subject"].lower().find(keywords.lower()) >= 0]
    return news

def read_news_cua_tuyen(keywords = None):

    conn = sqlite3.connect("DATA/crawlingDB.db")
    data = []
    if keywords is not None:
        # news = get_all("SELECT * FROM news")
        keyword_format = "%{}%".format(keywords)
        keyword_tokennize = tach_tu.tokenize(keywords)
        print("Từ khoá: ", keyword_tokennize)

        # output
        bow = str(keyword_tokennize).split(' ')
        print("bow tìm kiếm :", bow)
        print("------------------------------------------------------------")

        # xử lí
        list_news_match = []  # list chứa if_idf và link bài viết
        sort_new_by_tf_idf = []  # list chứa tf_idf của các bài viết match với keyword -> dùng để sắp xếp theo thứ tự
        for row in match_data(keyword_format):  # với mỗi bài báo liên quan tới keyword, tiến hành tính tf-idf
            data_match = loai_bo_stopword(str(row[2]))  # loại bỏ stopword
            word_dict = creat_word_count_dict(data_match)  # tạo bag of word đếm số lần xuất hiện
            # print("Số lần xuất hiện :",word_dict)
            # tính TF
            tf = compute_TF(word_dict, bow)
            # print("Kết quả tf:", tf)
            # Tính IDF
            idf = compute_IDF(word_dict)
            # print("Kết quả idf:", idf)
            # Cuối cùng: Tính TF-IDF Từ kết quả TF và IDF phía trên chỉ cần nhân lại là xong
            tf_idf = compute_TFIDF(tf, idf)
            # print(tf_idf)
            for key, value in tf_idf.items():  # tạo vòng lặp tìm ra keyword và tf_idf của nó,  -> tf_idf = value
                if (key == keyword_tokennize):
                    data.append(get_news_id(row[0]))

    conn.close()
    return data

if __name__ == "__main__":
    #read_category()
    #get_news()
   print(read_news_cua_tuyen("Thuỷ Tiên"))


import math

# Type hinting imports
from typing import List

"""
    Confirms that an array is valid (all rows and columns have the same number of items),
    and returns the number of items in each row and column
"""

def sizeArray(arr: List[List[int]]):
    colLen = len(arr)

    rowLen = len(arr[0])
    for sub in arr:
        if len(sub) != rowLen:
            raise ValueError("Your array is jagged. Please confirm that all rows have the same number of elements")
    return (colLen, rowLen)

"""
    Finds the 1 dimensional peak in an array
    1 2 2 1 -- In this case, either of the 2s would be a peak
"""

def find1DPeak(arr: List[List[int]], colLen: int, middleCol: int):
    maxVal = 0
    maxRow = 0
    for i in range(0, colLen, 1):
        if (arr[middleCol][i] > maxVal):
            maxVal = arr[middleCol][i]
            maxRow = i
    return (maxRow, maxVal)

"""
    Calls the function to find a 1D peak, checks to see if the 1D peak is also a 2D peak
    If not, keeps looking for different 1D peaks

    1 2 2 1
    3 2 1 1   -- In this case, the 2s in the rop row and the 3 on the bottom row would be peaks
"""

def find2DPeak(arr: List[List[int]], colLen: int, rowLen: int, middleCol: int):
    maxRow, maxVal = find1DPeak(arr, colLen, middleCol)

    # If we're on the left or rightmost column, we've found a peak
    if (middleCol == 0) or (middleCol == colLen - 1):
        return maxVal

    # Make sure the numbers to the left and right are below peak
    if (maxVal >= arr[middleCol - 1][maxRow]) and (maxVal >= arr[middleCol + 1][maxRow]):
        return maxVal
    # Check two columns to the left
    elif (maxVal < arr[middleCol - 1][maxRow]):
        return find2DPeak(arr, colLen, rowLen, middleCol - math.ceil(middleCol / 2))
    # Check two columns to the right
    else:
        return find2DPeak(arr, colLen, rowLen, middleCol + math.ceil(middleCol / 2))

def findPeak(arr: List[List[int]]):
    colLen, rowLen = sizeArray(arr)
    middleCol = math.ceil(colLen / 2)
    return find2DPeak(arr, colLen, rowLen, middleCol)

"""
    Peak Finding Algorithm
    https://courses.csail.mit.edu/6.006/spring11/lectures/lec02.pdf
"""

def main():
    arr = [
        [10, 8, 10, 10],
        [14, 15, 12, 11],
        [15, 9, 11, 19],
        [16, 17, 19, 20],
    ]

    print(findPeak(arr))

if __name__ == "__main__":
    main()


def matrix_converter(matrix):
    matrix = matrix[1:len(matrix)]
    level = 0
    start = 0
    end = 0
    res = []
    number = ""
    i = 0
    while i<len(matrix):
        if matrix[i] == "[":
            if level == 0:
                start = i
            level += 1
        elif matrix[i] == "]":
            level -= 1
            if level == 0:
                end = i
                res.append(matrix_converter(matrix[start:end+1]))
        elif matrix[i].isdigit() and level == 0:
            number = matrix[i] + number
            while matrix[i+1].isdigit():
                i += 1
                number += matrix[i]
            res.append(int(number))
            number = ""
        i += 1
    return res

# test :
matrix = "[[1, [[13, 19]]], [112, [3, [4]]]]"
print("input type =", type(matrix))
print("input =", matrix)
matrix = matrix_converter(matrix)
print("output type =", type(matrix))
print("output =", matrix)


import stripe
import paypalrestsdk as paypal
from django.conf import settings

default_app_config = 'milove.shop.apps.ShopConfig'

# setup payment methods

stripe.api_key = settings.STRIPE_API_KEY

paypal.configure({
    'mode': settings.PAYPAL_MODE,
    'client_id': settings.PAYPAL_CLIENT_ID,
    'client_secret': settings.PAYPAL_CLIENT_SECRET,
})


import sys
import argparse
import os
import json

parser = argparse.ArgumentParser(description='Process a beatsaber song.')
parser.add_argument('basedir', metavar='FileDir', type=str,
                    help='a folder to convert to beatswiper format')

args = parser.parse_args()
basedir = args.basedir

difftrans = {
    "Easy":         0,
    "Normal":       1,
    "Hard":         2,
    "Expert":       3,
    "ExpertPlus":   4,
}
directiontrans = [
    2,
    6,
    4,
    0,
    3,
    1,
    5,
    7,
    8
]

def convToBeatSwiperJson(info, song, diff):

    print(f"\n[+] Making song data: {diff}")

    metaout = {"UniqeNumber": 37,
               "Song_Title": "", # This
               "Song_Description": "Amanotes;test",
               "Song_AuthorName": "", # This
               "Song_FolderName": "", # This
               "Pack_FolderIndex": 0,
               "PackFolderName": "Modified",
               "BPM": 0,                         # This
               "status_Availability": 1,
               "available_Difficulties": [ # This
                   1,
                   3,
                   4
               ],
               "coinUnlockValue": [
                   800,
                   900,
                   1200
               ],
               "levelUnlockValue": [
                   0,
                   0,
                   0
               ],
               "isUnlocked": True,                  # This
               "priority": 549,
               "version": 1,
               "downloadedVersion": 0,
               "leaderboardID": "CgkIpPv3hdYLEAIQJQ",
               "totalTime_Seconds": 0}                # This

    # =================================
    # straight read json & transfer

    metaout["Song_Title"] = info["_songName"]
    metaout["Song_AuthorName"] = info["_songAuthorName"]
    metaout["BPM"] = float(info["_beatsPerMinute"])

    # =================================
    # calc and trasfer

    foldername = info["_songName"].replace(" ", "_").replace("'", "".replace('"', ""))
    time = round(song["_notes"][-1]["_time"] + 1)

    songdiff = [difftrans[x] for x in [info["_difficultyBeatmapSets"][0]["_difficultyBeatmaps"][y]["_difficulty"] for y in range(len(info["_difficultyBeatmapSets"][0]["_difficultyBeatmaps"]))]]
    # whoo wee, what a chonker

    metaout["Song_FolderName"] = foldername
    metaout["totalTime_Seconds"] = time
    metaout["available_Difficulties"] = songdiff

    # =================================
    # Song stuff!
    # wierd because beatswiper uses a json list but without the brackets

    songout = []

    for i, x in enumerate(song["_notes"]):
        songout.append({
                "Amanotes_NoteNumber": i,
                "name": "",
                "row_number": x["_lineLayer"] + 1,
                "line_number": x["_lineIndex"] + 1,
                "direction_number": directiontrans[x["_cutDirection"]],
                "time": x["_time"],
                "number": 0,
                "colorKind": x["_type"],
                "pool_Index": 0
        })
    try:
        os.mkdir(f"{basedir}/../{foldername}")
        print(f"[+] Making directory: {foldername}")
    except:
        pass

    print(f"[+] Writing song data: {foldername}/{diff}")
    songfile = open(f"{basedir}/../{foldername}/{diff}.txt", "w").write("")
    songfile = open(f"{basedir}/../{foldername}/{diff}.txt", "a")
    for i, x in enumerate(songout):
        songfile.write(json.dumps(x) + "\n")
    songfile.close()

    print(f"[+] Writing song info: {foldername}/info.txt")
    infofile = open(f"{basedir}/../{foldername}/info.txt", "w")
    json.dump(metaout, infofile)

def main():

    if not os.path.isdir(basedir):
        print("not a dir")
        exit()

    files = []
    for (dirpath, dirnames, filenames) in os.walk(basedir):
        files.extend(filenames)
        break

    infostr = "Info.dat"

    if not "Info.dat" in files:
        if not "info.dat" in files:
            print("Directory structure is wrong")
            exit()
        infostr = "info.dat"

    with open(f"{basedir}/{infostr}") as info:
        infojson = json.load(info)

    for x in infojson["_difficultyBeatmapSets"][0]["_difficultyBeatmaps"]:

        with open(f'{basedir}/{x["_beatmapFilename"]}') as song:
            songjson = json.load(song)

        convToBeatSwiperJson(infojson, songjson, x["_difficulty"])

if __name__ == "__main__":
    main()


'''
Created on Dec 20, 2017

@author: Oribow
'''
from PyQt5.QtWidgets import QGraphicsView, QGraphicsItemGroup, QGraphicsRectItem, \
    QGraphicsItem, QGraphicsScene, QGraphicsLineItem, QLabel, QVBoxLayout, QWidget, QHBoxLayout, \
    QSlider, QGraphicsEllipseItem, \
    QSpinBox, QAbstractItemView, \
    QPushButton, QTableView
from PyQt5.QtCore import Qt, pyqtSignal, QItemSelectionModel
from PyQt5.Qt import QBrush, QPixmap

from data.AssetUtil import resPathToAbs
from data.ItemTemplates import ComposeableItem
from data.Refila import ConstFilter
from morestrategy_too.AmountList import AmountList, AmountItem, copyInPlace
from morestrategy_too.GameData import Actor
from morestrategy_too.QItemCollectionSelector import QItemCollectionSelector
from morestrategy_too.QUIFactory import ComposerItemUIFactory
import math

ITEM_SIZE = 100
ITEM_SIZE_HALF = ITEM_SIZE / 2
ITEM_SPACE = 10
INDICATOR_SIZE = math.sqrt(2 * ITEM_SIZE ** 2)
INDICATOR_OFFSET = ITEM_SIZE - (INDICATOR_SIZE - ITEM_SIZE) / 2

class QComposer(object):

    def __init__(self, tab, tabWd, collectionSelector, actor, proxyActor):
        self.proxyActor = proxyActor
        self.actorsItemsChanged = False

        self.scene = QGraphicsScene()
        self.scene.selectionChanged.connect(self.gItemSelectionChanged)
        self.selectionIndicator = QGraphicsEllipseItem(-100, -100, INDICATOR_SIZE, INDICATOR_SIZE)
        self.scene.addItem(self.selectionIndicator)
        TreeItem.scene = self.scene
        TreeItem.changeAmountCallback = self.changeAmount
        TreeItem.uiFactory = ComposerItemUIFactory(self.scene)

        self.collectionSelector = collectionSelector
        collectionSelector.selectedChanged.connect(self.aItemSelectionChanged)

        self.targetActor = actor
        actor.ownedItems.aItemChanged.connect(self.targetActorsItemChanged)

        self.graphicsViewWd = tabWd.findChild(QGraphicsView, 'composer_view')
        self.graphicsViewWd.setScene(self.scene)

        self.tab = tab
        tab.tabBecameVisible.connect(self.tabBecameVisible)

        tabWd.findChild(QPushButton, "make_bt").clicked.connect(self.makeClicked)
        tabWd.findChild(QPushButton, "autofill_bt").clicked.connect(self.autofillClicked)
        tabWd.findChild(QPushButton, "clear_bt").clicked.connect(self.clearClicked)

        self.gItemSelectionChanged()
        self.rootGItem = TreeItem()
        self.rootGItem.drawCached()

    def tabBecameVisible(self):
        if self.actorsItemsChanged:
            self.updateProxyActorsItems()

    def targetActorsItemChanged(self, batch):
        if not self.tab.isActiveTab:
            self.actorsItemsChanged = True
        else:
            self.updateProxyActorsItems()

    def updateProxyActorsItems(self):
        # copy inplace
        copyInPlace(self.targetActor.ownedItems, self.proxyActor.ownedItems)
        self.proxyActor.ownedItems.startBatch()
        self.applyItemUpdate(self.rootGItem)
        self.rootGItem.drawCached()
        self.proxyActor.ownedItems.clearBatch()

    def applyItemUpdate(self, gItem):
        if gItem.aItem == None:
            return
        i = self.proxyActor.ownedItems.getAItemById(gItem.aItem.item.id)
        if i == None:
            gItem.clear(None, TreeItem.CLEAR_IGNORE)
            return
        gItem.takePreferredAmountOfItem(self.proxyActor, i)
        for c in gItem.children:
            self.applyItemUpdate(c)

    def gItemSelectionChanged(self):
        gItems = self.scene.selectedItems()
        if len(gItems) == 0:
            self.collectionSelector.setConstantPreFilter(ConstFilter(False))
            self.selectionIndicator.hide()
        else:
            gItem = gItems[0]
            self.selectionIndicator.show()
            self.selectionIndicator.setPos(gItem.x + INDICATOR_OFFSET, gItem.y + INDICATOR_OFFSET)
            if gItem.aItem != None:
                m = self.collectionSelector.tableModel
                for i in range(len(m.filteredAItemList)):
                    if gItem.aItem == m.filteredAItemList[i]:
                        # self.collectionSelector.tableView.setCurrentIndex(self.collectionSelector.proxyModel.mapFromSource(m.index(i, 0)))
                        self.collectionSelector.tableView.selectionModel().select(
                            self.collectionSelector.proxyModel.mapFromSource(m.index(i, 0)),
                            QItemSelectionModel.SelectCurrent)
                        break

            self.collectionSelector.setConstantPreFilter(self.getFilterForGItem(gItem))

    def aItemSelectionChanged(self, aItem):
        if aItem == None or not aItem.isValid():
            return
        gItems = self.scene.selectedItems()
        if len(gItems) == 0:
            return
        else:
            gItem = gItems[0]
            gItem.setAItem(aItem, self.proxyActor)

    def getFilterForGItem(self, gItem):
        if gItem.parent == None:
            return RootFilter(gItem.aItem)
        else:
            return ItemFuncFilter(gItem)

    def changeAmount(self, gItem, amount):
        if amount < 1:
            return

        amount -= gItem.aItem.amount
        if amount == 0:
            return

        if amount < 0:
            if gItem.aItem.item.amount + amount < 0:
                amount = -(gItem.aItem.item.amount - 1)
            self.proxyActor.ownedItems.append(AmountItem(gItem.aItem.item, amount * -1))
            gItem.aItem.amount += amount
        else:
            i = self.proxyActor.ownedItems.getAItemById(gItem.aItem.item.id)
            if amount > i.amount:
                amount = i.amount

            self.proxyActor.ownedItems.remove(AmountItem(gItem.aItem.item, amount))
            gItem.aItem.amount += amount

    def makeClicked(self):
        if not self.rootGItem.isValidComposition():
            return
        self.targetActor.ownedItems.startBatch()
        result = AmountList()
        self.rootGItem.createComposition(result)
        self.targetActor.ownedItems.addAmountList(result)
        aItem = self.rootGItem.aItem
        self.rootGItem.clear(self.targetActor, TreeItem.CLEAR_REMOVE)
        self.targetActor.ownedItems.endBatch()
        i = self.proxyActor.ownedItems.getAItemById(aItem.item.id)
        self.rootGItem.setAItem(i, self.proxyActor)
        self.rootGItem.drawCached()

    def clearClicked(self):
        self.targetActor.ownedItems.startBatch()
        self.rootGItem.clear(self.proxyActor, TreeItem.CLEAR_RECYCLE)
        self.targetActor.ownedItems.endBatch()
        self.rootGItem.drawCached()

    def autofillClicked(self):
        if self.rootGItem.aItem is None:
            return
        self.autofill(self.rootGItem)
        self.rootGItem.drawCached()

    def autofill(self, gItem):
        if gItem.aItem == None and (gItem.parent == None or gItem.parent.aItem.item.allowAutoFill):
            filter = self.getFilterForGItem(gItem)
            vI = next((x for x in self.proxyActor.ownedItems if filter.isValidItem(x)), None)
            if vI == None:
                return
            gItem.setAItem(vI, self.proxyActor)

        for c in gItem.children:
            self.autofill(c)

class TreeItem(QGraphicsItemGroup):
    CLEAR_RECYCLE, CLEAR_REMOVE, CLEAR_IGNORE = range(3)

    scene = None
    changeAmountCallback = None
    uiFactory = None

    def __init__(self, parent=None):
        QGraphicsItemGroup.__init__(self)
        self.setFlags(QGraphicsItem.ItemIsSelectable)
        self.parent = parent
        TreeItem.scene.addItem(self)
        self.aItem = None
        self.lineCache = []
        self.children = []
        # cached draw params
        self.x = 0
        self.y = 0
        self.nextDown = False

    def setAItem(self, aItem, proxyActor):
        if aItem == self.aItem:
            return
        proxyActor.ownedItems.startBatch()
        if self.aItem != None:
            self.clear(proxyActor, self.CLEAR_RECYCLE)

        if aItem != None:
            self.takePreferredAmountOfItem(proxyActor, aItem)
            # handle children
            if issubclass(type(self.aItem.item), ComposeableItem):
                reqChildCount = self.aItem.item.getChildCount(self.getChildAItems())
            else:
                reqChildCount = 0
            self.updateChildCount(reqChildCount)
        self.drawCached()
        if self.parent != None:
            self.parent.childItemChanged()
        proxyActor.ownedItems.endBatch()

    def childItemChanged(self):
        cc = self.aItem.item.getChildCount(self.getChildAItems())
        if len(self.children) != cc:
            self.updateChildCount(cc)
            self.drawCached()

    def updateChildCount(self, newChildCount):
        orgChildCount = len(self.children)
        while len(self.children) < newChildCount:
            self.children.append(TreeItem(self))
        for i in range(orgChildCount):
            self.children[i].show()
        for i in range(newChildCount, len(self.children)):
            self.children[i].hide()

    def drawCached(self):
        self.draw(self.nextDown, self.x, self.y)

    def draw(self, nextDown, x, y):
        self.nextDown = nextDown
        self.x = x
        self.y = y

        # remove old stuff
        for c in self.childItems():
            c.setParentItem(None)
        # just draw me at x, y
        self.setPos(x, y)
        # if self.isDrawingDirty:

        self.drawBase()
        if self.aItem != None:
            self.uiFactory.beginRootLayout(x, y, ITEM_SIZE, self)
            self.aItem.item.onComposerDraw(self.uiFactory, self.aItem.amount, self.getMinAmount(), self.getMaxAmount())
            self.uiFactory.endRootLayout()

        orgX = x
        orgY = y
        lastX = x
        lastY = y

        for child in self.children:
            if nextDown:
                nextX = orgX
                nextY = y + ITEM_SIZE + ITEM_SPACE
            else:
                nextX = x + ITEM_SIZE + ITEM_SPACE
                nextY = orgY

            # draw connection between children
            if nextDown:
                QGraphicsLineItem(lastX + ITEM_SIZE_HALF - orgX, lastY + ITEM_SIZE - orgY,
                                  nextX + ITEM_SIZE_HALF - orgX, nextY + ITEM_SIZE - orgY, self)
            else:
                QGraphicsLineItem(lastX + ITEM_SIZE - orgX, lastY + ITEM_SIZE_HALF - orgY, nextX - orgX,
                                  nextY + ITEM_SIZE_HALF - orgY, self)

            tmpX, tmpY = child.draw(not nextDown, nextX, nextY)
            if tmpX > x:
                x = tmpX
            if tmpY > y:
                y = tmpY
            lastX = nextX
            lastY = nextY

        return x, y

    def drawBase(self):
        rect = QGraphicsRectItem(0, 0, ITEM_SIZE, ITEM_SIZE, self)
        rect.setBrush(QBrush(Qt.green))

    def amountChanged(self, amount):
        self.changeAmountCallback(self.aItem, amount)

    def handleItemChange(self, aList):
        pass

    def getMinAmount(self):
        if self.parent == None:
            return 1
        otherChildren = self.parent.getOtherChildren(self)
        return self.parent.aItem.item.minAmountOfItem(otherChildren, self.aItem)

    def getMaxAmount(self):
        if self.parent == None:
            return 1
        otherChildren = self.parent.getOtherChildren(self)
        return self.parent.aItem.item.maxAmountOfItem(otherChildren, self.aItem)

    def getOtherChildren(self, child):
        otherChildren = []
        for c in self.children:
            if c.aItem != None and c != child:
                otherChildren.append(c)
        return otherChildren

    def getChildAItems(self):
        aItems = []
        for c in self.children:
            aItems.append(c.aItem)
        return aItems

    def isValidComposition(self):
        if self.aItem == None and self.parent != None:
            return True

        for c in self.children:
            if not c.isValidComposition():
                return False

        if issubclass(type(self.aItem.item), ComposeableItem):
            return self.aItem.item.isCompositionAcceptable(self.getChildAItems())
        else:
            return True

    def createComposition(self, aList):
        if self.aItem == None:
            return

        for c in self.children:
            c.createComposition(aList)

        if issubclass(type(self.aItem.item), ComposeableItem):
            self.aItem.item.createComposition(self.getChildAItems(), aList)

    def clear(self, actor, clearMode):
        for c in self.children:
            c.clear(actor, clearMode)
        if clearMode == self.CLEAR_RECYCLE:
            if self.aItem != None:
                actor.ownedItems.append(self.aItem)
        elif clearMode == self.CLEAR_REMOVE:
            if self.aItem != None:
                actor.ownedItems.remove(self.aItem)

        self.aItem = None
        while (len(self.children) > 0):
            self.scene.removeItem(self.children[0])
            del self.children[0]

    def takePreferredAmountOfItem(self, actor, aItem):
        myAItem = aItem.copy()

        if self.parent == None:
            myAItem.amount = 1
        else:
            otherChildren = self.parent.getOtherChildren(self)
            max = self.parent.aItem.item.maxAmountOfItem(otherChildren, aItem)
            if max > aItem.amount:
                max = aItem.amount

            myAItem.amount = max

        actor.ownedItems.remove(myAItem)
        self.aItem = myAItem

class RootFilter(object):

    def __init__(self, aItem):
        self.aItem = aItem

    def isValidItem(self, aItem):
        if not issubclass(type(aItem.item), ComposeableItem):
            return False

        if aItem.amount == 0 and aItem.item.id == self.aItem.item.id:
            return True
        return aItem.item.canBeRoot

class ItemFuncFilter(object):

    def __init__(self, treeItem):

        self.children = []
        for c in treeItem.parent.children:
            if c.aItem != None:
                self.children.append(c.aItem)
        self.aItem = treeItem.parent.aItem

    def isValidItem(self, aItem):
        if aItem.amount == 0 and aItem.item.id == self.aItem.item.id:
            return True
        return self.aItem.item.isItemAcceptableChild(self.children, aItem)