import pygame
from shapely.geometry import LineString
#start of clipper_______________________________________________________________________________________________________
class Clipper:

    def __init__(self,surface,windowStartx,windowStarty,windowEndx,windowEndy):
        self.surface=surface
        self.wsx=windowStartx
        self.wsy=windowStarty
        self.wex=windowEndx
        self.wey=windowEndy
        pygame.draw.rect(self.surface, (200,200,200), (self.wsx,self.wsy,self.wex-self.wsx,self.wey-self.wsy), 1)

    def updateCodesOfTheLine(self,line):
        #updating codes of the line:
        #start points
        if(((line.getStartx()<self.wex) and (line.getStartx()>self.wsx)) and ( (line.getStarty()<self.wey) and (line.getStarty()>self.wsy))):
            line.setStartCode("0000")

        if ( (line.getStartx()<self.wsx) and (line.getStarty() < self.wey and line.getStarty() > self.wsy) ):
            line.setStartCode("1000")

        if( (line.getStartx()<self.wsx) and (line.getStarty()<self.wsy)):
            line.setStartCode("1001")

        if( (line.getStartx()<self.wsx) and (line.getStarty()>self.wey)):
            line.setStartCode("1010")

        if( (line.getStartx()<self.wex and line.getStartx() >self.wsx) and (line.getStarty()<self.wsy)):
            line.setStartCode("0001")

        if( (line.getStartx()<self.wex and line.getStartx() >self.wsx) and (line.getStarty()>self.wey)):
            line.setStartCode("0010")

        if( (line.getStartx()>self.wex) and line.getStarty()<self.wsy):
            line.setStartCode("0101")

        if( (line.getStartx()>self.wex) and (line.getStarty()>self.wsy and line.getStarty()<self.wey)):
            line.setStartCode("0100")

        if( (line.getStartx()>self.wex) and line.getStarty()>self.wey):
            line.setStartCode("0110")

        if ( (line.getStartx()<self.wsx) and (line.getStarty() < self.wey and line.getStarty() > self.wsy) ):
            line.setStartCode("1000")

        #setting end of line code
        if(((line.getEndx()<self.wex) and (line.getEndx()>self.wsx)) and ( (line.getEndy()<self.wey) and (line.getEndy()>self.wsy))):
            line.setEndCode("0000")

        if( (line.getEndx()<self.wsx) and (line.getEndy()<self.wsy)):
            line.setEndCode("1001")

        if( (line.getEndx()<self.wsx) and (line.getEndy()>self.wey)):
            line.setEndCode("1010")

        if( (line.getEndx()<self.wex and line.getEndx() >self.wsx) and ((line.getEndy()<self.wsy) )):
            line.setEndCode("0001")

        if( (line.getEndx()<self.wex and line.getEndx() >self.wsx) and ((line.getEndy()>self.wey))):
            line.setEndCode("0010")

        if( (line.getEndx()>self.wex) and line.getEndy()<self.wsy):
            line.setEndCode("0101")

        if( (line.getEndx()>self.wex) and (line.getEndy()>self.wsy and line.getEndy()<self.wey)):
            line.setEndCode("0100")

        if( (line.getEndx()>self.wex) and line.getEndy()>self.wey):
            line.setEndCode("0110")

        if ( (line.getEndx()<self.wsx) and (line.getEndy() < self.wey and line.getEndy() > self.wsy) ):
            line.setEndCode("1000")
        #end of updating codes of the line

    #finding intersection:
    def findIntersection(self,edge,startx,endx,starty,endy,isharizontalline):#if horizontal line is true we should use yedge to find intersection with harizontal edges of the rectangle and if it is false we are about to find it with vertical edges
        m=(endy-starty)/(endx-startx)
        print("the lines m is "+str(m))

        if(isharizontalline==True): #harizontal intersection
            newx=(1/m)*(edge-starty)+startx
            return (newx,edge)

        else: #vertical intersection
            newy=(m*edge - m*startx +starty )
        return(edge,newy)
    #end of finding intersection

    def clip(self,lineOne):#clipping Operation
        self.updateCodesOfTheLine(lineOne)
        #Case One completely inside!:
        if(((lineOne.getStartx()>=self.wsx and lineOne.getStartx() <=self.wex) and (lineOne.getStarty()>=self.wsy and lineOne.getStarty()<=self.wey)) and ((lineOne.getEndx()>=self.wsx and lineOne.getEndx()<=self.wex) and (lineOne.getEndy()>=self.wsy and lineOne.getEndy()<=self.wey)) ):
            print("Line is in so the whole line was printed")
            pygame.draw.line(screen,(255,255,255),(lineOne.getStartx(),lineOne.getStarty()),(lineOne.getEndx(),lineOne.getEndy()),1)

        #Case Two completely outside!:
        elif( (lineOne.getStartCode()[0] =="1" and  lineOne.getEndCode()[0]=="1") or (lineOne.getStartCode()[1]=="1" and lineOne.getEndCode()[1]=="1") or (lineOne.getStartCode()[2]=="1" and lineOne.getEndCode()[2]=="2") or (lineOne.getStartCode()[3]=="1" and lineOne.getEndCode()[3]=="1")):
            print("completely outside")

        #Case Three partially inside!:
        else:
            print("partially inside")

            #checking start codes to clip start of the line
            if (lineOne.getStartCode()=="0101" or lineOne.getStartCode()=="0100" or lineOne.getStartCode()=="0110"):
                print("line starts at right of window")
                (newStartx,newStarty)=self.findIntersection(self.wex,lineOne.getStartx(),lineOne.getEndx(),lineOne.getStarty(),lineOne.getEndy(),False)
                print("new startx="+str(newStartx)+"   newstarty="+str(newStarty))
                newStartx= newStartx-1
                lineOne.setStartx(newStartx)
                lineOne.setStarty(newStarty)
                self.clip(lineOne)

            elif(lineOne.getStartCode()=="0001"):
                print("line starts at top of window")
                (newStartx,newStarty)=self.findIntersection(self.wsy,lineOne.getStartx(),lineOne.getEndx(),lineOne.getStarty(),lineOne.getEndy(),True)
                print("new startx="+str(newStartx)+"   newstarty="+str(newStarty))
                newStarty=newStarty+1
                lineOne.setStartx(newStartx)
                lineOne.setStarty(newStarty)
                self.clip(lineOne)

            elif(lineOne.getStartCode()=="0010"):
                print("line starts at bottom of window")
                (newStartx,newStarty)=self.findIntersection(self.wey,lineOne.getStartx(),lineOne.getEndx(),lineOne.getStarty(),lineOne.getEndy(),True)
                print("new startx="+str(newStartx)+"   newstarty="+str(newStarty))
                newStarty=newStarty-1
                lineOne.setStartx(newStartx)
                lineOne.setStarty(newStarty)
                self.clip(lineOne)

            elif(lineOne.getStartCode()=="1001" or lineOne.getStartCode()=="1000" or lineOne.getStartCode()=="1010"):
                print("line one starts at left of window")
                (newStartx,newStarty)=self.findIntersection(self.wsx,lineOne.getStartx(),lineOne.getEndx(),lineOne.getStarty(),lineOne.getEndy(),False)
                print("new startx="+str(newStartx)+"   newstarty="+str(newStarty))
                newStartx=newStartx+1
                lineOne.setStartx(newStartx)
                lineOne.setStarty(newStarty)
                self.clip(lineOne)

            #checking end code to adjust end of the line
            if (lineOne.getEndCode()=="0101" or lineOne.getEndCode()=="0100" or lineOne.getEndCode()=="0110"):
                print("line ends at right of window")
                (newEndx,newEndy)=self.findIntersection(self.wex,lineOne.getStartx(),lineOne.getEndx(),lineOne.getStarty(),lineOne.getEndy(),False)
                print("new Endx="+str(newEndx)+"   newEndy="+str(newEndy))
                newEndx= newEndx-1
                lineOne.setEndx(newEndx)
                lineOne.setEndy(newEndy)
                self.clip(lineOne)

            elif(lineOne.getEndCode()=="0001"):
                print("line Ends at top of window")
                (newEndx,newEndy)=self.findIntersection(self.wsy,lineOne.getStartx(),lineOne.getEndx(),lineOne.getStarty(),lineOne.getEndy(),True)
                print("new Endx="+str(newEndx)+"   newEndy="+str(newEndy))
                newEndy=newEndy+1
                lineOne.setEndx(newEndx)
                lineOne.setEndy(newEndy)
                self.clip(lineOne)

            elif(lineOne.getEndCode()=="0010"):
                print("line Ends at bottom of window")
                (newEndx,newEndy)=self.findIntersection(self.wey,lineOne.getStartx(),lineOne.getEndx(),lineOne.getStarty(),lineOne.getEndy(),True)
                print("new Endx="+str(newEndx)+"   newEndy="+str(newEndy))
                newEndy=newEndy-1
                lineOne.setEndx(newEndx)
                lineOne.setEndy(newEndy)
                self.clip(lineOne)

            elif(lineOne.getEndCode()=="1001" or lineOne.getEndCode()=="1000" or lineOne.getEndCode()=="1010"):
                print("line one Ends at left of window")
                (newEndx,newEndy)=self.findIntersection(self.wsx,lineOne.getStartx(),lineOne.getEndx(),lineOne.getStarty(),lineOne.getEndy(),False)
                print("new Endx="+str(newEndx)+"   newEndy="+str(newEndy))
                newEndx=newEndx+1
                lineOne.setEndx(newEndx)
                lineOne.setEndy(newEndy)
                self.clip(lineOne)

#end of clipper_________________________________________________________________________________________________________

#start of Line__________________________________________________________________________________________________________
class Line:
    def __init__(self,startx,starty,endx,endy):
        self.startx=startx
        self.starty=starty
        self.endx=endx
        self.endy=endy
        self.startCode="FFFF"
        self.endCode="FFFF"

    def setStartCode(self,startCode):
        self.startCode=startCode
        print("start code is updated to "+self.startCode)

    def getStartCode(self):
        return self.startCode

    def setEndCode(self,endCode):
        self.endCode=endCode
        print("end code is updated to "+self.endCode)

    def getEndCode(self):
        return self.endCode

    def getStartx(self):
        return self.startx

    def getStarty(self):
        return self.starty

    def getEndx(self):
        return self.endx

    def getEndy(self):
        return self.endy

    def setStartx(self,newStartx):
        self.startx=newStartx

    def setEndx(self,newEndx):
        self.endx=newEndx

    def setStarty(self,newStarty):
        self.starty=newStarty

    def setEndy(self,newEndy):
        self.endy=newEndy
#end of Line____________________________________________________________________________________________________________

#start of screen________________________________________________________________________________________________________

background_colour = (0,0,0)

screen = pygame.display.set_mode((500, 500))

pygame.display.set_caption('Cohen-Sathurland Clipper')

screen.fill(background_colour)

#code of making Instantiation of clipper

Line1=Line(5,50,300,30)#startx starty endx endy of line
Clipper1= Clipper (screen,10,10,380,110)#startx starty endx endy of the Clipper Window
Clipper1.clip(Line1);

# end of making Instantiation

pygame.display.flip()

running = True

while running:

  for event in pygame.event.get():

    if event.type == pygame.QUIT:

      running = False


# -*- coding: utf-8 -*-
# Copyright 2017 GIG Technology NV
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# @@license_version:1.3@@
import logging

import webapp2
from google.appengine.api import taskqueue
from google.appengine.ext import deferred

from framework.plugin_loader import get_config
from plugins.rogerthat_api.api import friends
from plugins.tff_backend.bizz import get_rogerthat_api_key
from plugins.tff_backend.bizz.agenda import update_expired_events
from plugins.tff_backend.bizz.dashboard import rebuild_firebase_data
from plugins.tff_backend.bizz.global_stats import update_currencies
from plugins.tff_backend.bizz.nodes.stats import check_online_nodes, check_node_statuses
from plugins.tff_backend.bizz.payment import sync_transactions, sync_wallets
from plugins.tff_backend.configuration import TffConfiguration
from plugins.tff_backend.plugin_consts import NAMESPACE

class PaymentSyncHandler(webapp2.RequestHandler):

    def get(self):
        deferred.defer(sync_transactions)
        deferred.defer(sync_wallets)

class BackupHandler(webapp2.RequestHandler):

    def get(self):
        config = get_config(NAMESPACE)
        assert isinstance(config, TffConfiguration)
        if config.backup_disabled is True:
            logging.info('Backup is disabled, doing nothing')
            return

        models_to_backup = []

        # intercom_support
        models_to_backup.extend(['IntercomConversation',
                                 'RogerthatConversation'])

        # its_tyo_online_auth
        models_to_backup.extend(['Profile',
                                 'ProfileAppEmailMapping',
                                 'Session'])

        # tff_backend
        models_to_backup.extend(['Event',
                                 'EventParticipant',
                                 'GlobalStats',
                                 'InvestmentAgreement',
                                 'NodeOrder',
                                 'ProfilePointer',
                                 'PublicKeyMapping',
                                 'TffProfile',
                                 'ThreeFoldBlockHeight',
                                 'ThreeFoldPendingTransaction',
                                 'ThreeFoldTransaction',
                                 'ThreeFoldWallet',
                                 ])

        for model_to_backup in models_to_backup:
            taskqueue.add(
                url='/_ah/datastore_admin/backup.create',
                method='GET',
                queue_name="data-backup",
                params={
                    'filesystem': 'gs',
                    'gs_bucket_name': 'tff-backend-backups',
                    'name': model_to_backup,
                    'kind': [model_to_backup]
                }
            )

class RebuildSyncedRolesHandler(webapp2.RequestHandler):

    def get(self):
        api_key = get_rogerthat_api_key()
        friends.rebuild_synced_roles(api_key, members=[], service_identities=[])

class UpdateGlobalStatsHandler(webapp2.RequestHandler):

    def get(self):
        deferred.defer(update_currencies)

class CheckNodesOnlineHandler(webapp2.RequestHandler):

    def get(self):
        deferred.defer(check_online_nodes)

class CheckNodesStatusesHandler(webapp2.RequestHandler):

    def get(self):
        cfg = get_config(NAMESPACE)
        if cfg.orchestator and cfg.orchestator.jwt:
            deferred.defer(check_node_statuses)

class ExpiredEventsHandler(webapp2.RequestHandler):

    def get(self):
        deferred.defer(update_expired_events)

class RebuildFirebaseHandler(webapp2.RequestHandler):

    def get(self):
        deferred.defer(rebuild_firebase_data)


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

import numpy as np
import pandas as pd
#import seaborn as sns
import sklearn
from sklearn_extensions.fuzzy_kmeans import FuzzyKMeans
from sklearn.cluster import DBSCAN
from sklearn.decomposition import PCA
from polygone import performance_polygon_vs_player
import warnings
#sns.set()

# need to install kneebow and mlxtend

df = pd.read_csv('../csv/players_stats.csv')
player_names = df["Player"]

clustering_df = df.drop(columns=["Unnamed: 0","Player", "final_team","Pos"])

results = pd.DataFrame(data = None, columns = ['epsilon' , 'min_size', 'score'],dtype=np.float64)

for var_portion in np.arange(start = 0.6,stop=0.95,step=0.05,dtype=np.float64):
    pca = PCA(n_components=var_portion, svd_solver = 'full')
    pcabis = pca.fit(clustering_df)
    reducedDataSet = pcabis.transform(clustering_df)
    for eps in np.arange(start = 0.05,stop=0.95,step=0.01,dtype=np.float64):
        for size in np.arange(start = 2,stop=10,step=1,dtype=np.float64):
            m = DBSCAN(eps=eps, min_samples=size)
            m.fit(reducedDataSet)
            if(max(m.labels_)>1):
                score = sklearn.metrics.silhouette_score(clustering_df,m.labels_)
                results = results.append({'var_portion' : var_portion, 'epsilon' : eps , 'min_size' : size , 'score' : score, 'nb_clusters' : max(m.labels_)+1}, ignore_index=True)

results = results.sort_values(by=["score"], ascending = False)
results.to_csv("../csv/silhouette_search.csv", sep =';')

optimal_parameters = results.head(1)
optimal_parameters

pca_value = optimal_parameters.iloc[0]["var_portion"]
epsilon = optimal_parameters.iloc[0]["epsilon"]
min_size = optimal_parameters.iloc[0]["min_size"]

pca = PCA(n_components=pca_value, svd_solver = 'full')
pcabis = pca.fit(clustering_df)
dataSet = pcabis.transform(clustering_df)
model = DBSCAN(eps=epsilon, min_samples=min_size)
model.fit(dataSet)
result = pcabis.inverse_transform(dataSet)
res = np.zeros((0,3))
dbscan_cluster = pd.DataFrame(res)
number_of_players = df.shape[0]
for k in range(number_of_players):
    row = [[df['Player'].values[k], model.labels_[k], df["Pos"].values[k]]]
    dbscan_cluster = dbscan_cluster.append(row)
dbscan_cluster.columns = ["Player", "Cluster", "Pos"]

nb_players_per_cluster_dbscan = 4

pca = PCA(n_components=0.85, svd_solver = 'full')
pcabis = pca.fit(clustering_df)
dataSet = pcabis.transform(clustering_df)
model = DBSCAN(eps=0.22, min_samples=nb_players_per_cluster_dbscan)
model.fit(dataSet)
result = pcabis.inverse_transform(dataSet)
res = np.zeros((0,3))
dbscan_cluster = pd.DataFrame(res)
for k in range(df.shape[0]):
    row = [[df['Player'].values[k], model.labels_[k], df["Pos"].values[k]]]
    dbscan_cluster = dbscan_cluster.append(row)
    #cluster = cluster.sort_values(by=[1], ascending = False)
dbscan_cluster.columns = ["Player", "Cluster", "Pos"]

dbscan_cluster = dbscan_cluster.drop(columns="Pos")

# we remove the noise from the dbscan clusters
dbscan_cluster = dbscan_cluster[dbscan_cluster["Cluster"] != -1]

# we also considere that the maximum number of player of a consistent cluster is about 4
# we need to consider as noise the players in big cluster
nb_of_players_per_cluster = dbscan_cluster.groupby("Cluster").agg("count")
too_big_clusters = nb_of_players_per_cluster[nb_of_players_per_cluster["Player"] > nb_players_per_cluster_dbscan]["Player"]
dbscan_cluster = dbscan_cluster.loc[~dbscan_cluster['Cluster'].isin(too_big_clusters.index)]

nb_of_clusters_from_filtered_dbscan = len(dbscan_cluster.Cluster.unique())

# lets see who is clustered and who's not
clustered_players = dbscan_cluster["Player"]
unclustered_players = df.loc[~df["Player"].isin(clustered_players)]["Player"]

# highest cluster # found in dbscan
nb_clusters_from_dbscan = max(dbscan_cluster["Cluster"])

# we keep the interesting value
df_fcm = df[['Player', 'TRB', 'PTS', 'AST', 'DWS', 'TS%', "3PA", "OWS","USG%"]]

# we only keep the unclustered player
df_fcm = pd.merge(df_fcm, unclustered_players, on="Player")

# we keep the players name for later
players_name = df_fcm["Player"]
# we remove the player column for the computation
df_fcm = df_fcm.loc[:,(df_fcm.columns != "Player")]

# Computation
#nb_cluster_fuzzy = round(len(unclustered_players.index)/nb_max_players_per_cluster)
nb_cluster_fuzzy = 35
fuzzy_kmeans = FuzzyKMeans(k=nb_cluster_fuzzy, m=1.1)

# we can also directly compute fcm on the data (and not on the dbscan noise)

fuzzy_kmeans.fit(df_fcm)
fuzzy_clusters = pd.DataFrame(fuzzy_kmeans.fuzzy_labels_)

# we add the players name back
fuzzy_clusters = pd.concat([players_name, fuzzy_clusters], axis=1)

print("At first we clustered "+str(len(dbscan_cluster.index))+" players with DSBCAN.")

final_clusters = dbscan_cluster

nb_max_players_per_cluster_fcm = 4

for i in range(nb_cluster_fuzzy):
    # lets keep the coresponding col of membership degree
    sets = fuzzy_clusters[["Player", i]]

    # lets sort
    sets = sets.sort_values(by=i, ascending=False)

    #let's juste keep the top n% and be sure they are above a threeshold
    sets = sets.head(nb_max_players_per_cluster_fcm)
    sets = sets[["Player"]]
    print("we add "+str(nb_max_players_per_cluster_fcm)+" clustered players")

    # remove the hard clustered players from the fuzzy df to avoid having duplicates
    fuzzy_clusters = fuzzy_clusters[~fuzzy_clusters['Player'].isin(list(sets["Player"]))]

    #lets add the # of the cluster
    sets["Cluster"] = nb_clusters_from_dbscan+i+1
    #add those lines to the previous results
    final_clusters = pd.concat([final_clusters, sets], axis=0)

# ignore warnings for the polygone display
warnings.filterwarnings("ignore")

nb_of_cluster_printed = 0
nb_of_players_clustered = 0

#now let's print the overlapping polygones for each cluster
for i in final_clusters.Cluster.unique():
    players_to_draw = dbscan_cluster[dbscan_cluster["Cluster"] == i]["Player"].tolist()
    properties = ['OWS', 'DWS', 'AST','TS%', "TRB", "PTS", "3PA" ]
    if (len(players_to_draw) < 10):
        nb_of_cluster_printed+=1
        nb_of_players_clustered += len(players_to_draw)
        performance_polygon_vs_player(players_to_draw, properties)

print("We clustered "+str(nb_of_players_clustered)+" players with DBSCAN in "+str(nb_of_cluster_printed)+" clusters out of "+str(len(df.index))+" players.")
#print("Now we have "+str(len(final_clusters.index))+" players clustered out of "+str(len(clustering_df.index))+" players.")


# -*- coding:utf-8 -*-
# PROJECT_NAME : django-ueditor-plugin
# FILE_NAME    :
# AUTHOR       : younger shen
import json
from django.views.generic import View
from django.http import HttpResponse, Http404
from django.core.serializers.json import DjangoJSONEncoder
from django.views.decorators.csrf import csrf_exempt
from .utils import get_config
from .utils import upload_file
from .models import UeditorFile
# Create your views here.

class JsonResponse(HttpResponse):
    def __init__(self, context=None, encoder=DjangoJSONEncoder, safe=True, **kwargs):
        if safe and not isinstance(context, dict):
            raise TypeError('In order to allow non-dict objects to be '
                            'serialized set the safe parameter to False')

        data = json.dumps(context, cls=encoder)
        kwargs.setdefault('content_type', 'application/json')
        super(JsonResponse, self).__init__(content=data, **kwargs)

class JsonResponseMixin(object):
    content_type = 'application/json'
    response_class = JsonResponse

    def render_to_response(self, context, **response_kwargs):
        response_kwargs.setdefault('content_type', self.content_type)
        return self.response_class(context=context, **response_kwargs)

class JsonView(View, JsonResponseMixin):
    def get(self, request, *args, **kwargs):
        context = self.get_context_data(*args, **kwargs)
        return self.render_to_response(context)

class ControllerView(JsonView):

    def __init__(self, *args, **kwargs):
        self.config = get_config()
        super(ControllerView, self).__init__(*args, **kwargs)

    def get(self, request, *args, **kwarg):
        action_data = self.get_action(request)
        if action_data:
            return self.render_to_response(action_data)
        else:
            raise Http404

    def get_context_data(self):
        return self.config

    def post(self, request, *args, **kwargs):
        action_data = self.get_action(request, *args, **kwargs)
        if action_data:
            return self.render_to_response(action_data)
        else:
            raise Http404

    def config_action(self, request):
        return self.config

    def get_action(self, request):
        action = request.GET.get('action', '')
        action_method = getattr(self, action + '_action')
        if action_method:
            return action_method(request)
        return None

    def listfile_action(self, request):
        allow_file_types = self.config.get('fileManagerAllowFiles')
        default_size = self.config.get('fileManagerListSize')
        size = request.GET.get('size', '')
        start = request.GET.get('start', 0)
        try:
            size = int(size)
        except (ValueError, TypeError):
            size = default_size

        end = int(start) + size
        files = UeditorFile.objects.filter(type__in=allow_file_types, status=UeditorFile.UPLOAD_SUCCEED).values_list('url', flat=True)
        import random
        files_list = map(lambda x: {'url': x, 'mtime': random.random()}, files[start: end])

        if files.exists():
            return {'state': 'SUCCESS',
                    'list': files_list,
                    'start': start,
                    'total': files.count()
                    }
        else:
            return {'state': 'no match files',
                    'list': [],
                    'start': start,
                    'total': 0
                    }

    def listimage_action(self, request):
        allow_file_types = self.config.get('imageManagerAllowFiles')
        default_size = self.config.get('imageManagerListSize')
        size = request.GET.get('size', '')
        start = request.GET.get('start', 0)
        try:
            size = int(size)
        except (ValueError, TypeError):
            size = default_size

        end = int(start) + size
        files = UeditorFile.objects.filter(type__in=allow_file_types, status=UeditorFile.UPLOAD_SUCCEED).values_list('url', flat=True)
        import random
        files_list = map(lambda x: {'url': x, 'mtime': random.random()}, files[start: end])

        if files.exists():
            return {'state': 'SUCCESS',
                    'list': files_list,
                    'start': start,
                    'total': files.count()
                    }
        else:
            return {'state': 'no match files',
                    'list': [],
                    'start': start,
                    'total': 0
                    }

    def uploadimage_action(self, request):
        config = self.config

        uploadimage_config = {'pathFormat': config.get('imagePathFormat', ''),
                              'maxSize': config.get('imageMaxSize', ''),
                              'allowFiles': config.get('imageAllowFiles', ''),
                              'fieldName': config.get('imageFieldName', '')
                              }

        return upload_file(request, uploadimage_config)

    def uploadscrawl_action(self, request):
        config = self.config

        uploadscrawl_config = {'pathFormat': config.get('scrawlPathFormat', ''),
                               'maxSize': config.get('scrawlMaxSize', ''),
                               'allowFiles': config.get('scrawlAllowFiles', ''),
                               'oriName': config.get('scrawOriName', 'scrawl.png'),
                               'fieldName': config.get('scrawlFieldName', ''),
                               'base64': 'base64'
                               }

        return upload_file(request, uploadscrawl_config, base64='base64')

    def uploadvideo_action(self, request):
        config = self.config

        uploadvideo_config = {'pathFormat': config.get('videoPathFormat', ''),
                              'maxSize': config.get('videoMaxSize', ''),
                              'allowFiles': config.get('videoAllowFiles', ''),
                              'fieldName': config.get('videoFieldName', ''),
                              }

        return upload_file(request, uploadvideo_config)

    def uploadfile_action(self, request):
        config = self.config

        uploadfile_config = {'pathFormat': config.get('filePathFormat', ''),
                             'maxSize': config.get('fileMaxSize', ''),
                             'allowFiles': config.get('fileAllowFiles', ''),
                             'fieldName': config.get('fileFieldName', '')
                             }

        return upload_file(request, uploadfile_config)

controller_view = csrf_exempt(ControllerView.as_view())


from django.conf.urls import include, url

from django.contrib import admin
admin.autodiscover()

import root.views

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

urlpatterns = [
    url(r'^$', root.views.index, name='index'),
    url(r'^cost_of_sprint$', root.views.cost_detail, name='cost_detail'),
    url(r'^api/', include('root.urls')),
    url(r'^admin/', include(admin.site.urls)),
]


# -*- coding:utf-8 -*-
# @time:2017/8/12 0012 0:31
from collections import Counter
from math import log
import math
hmm_model = {i: Counter() for i in 'sbme'}

with open('dict_small.txt', encoding='utf-8') as f:
    for line in f:
        lines = line.split(' ')
        if len(lines[0]) == 1:
            #  single word
            hmm_model['s'][lines[0]] += int(lines[1])
        else:
            #  not single word
            hmm_model['b'][lines[0][0]] += int(lines[1])
            hmm_model['e'][lines[0][-1]] += int(lines[1])
            for m in lines[0][1:-1]:
                hmm_model['m'][m] += int(lines[1])
log_total = {i: log(sum(hmm_model[i].values())) for i in 'sbme'}
# for k, v in hmm_model.items():
#    print(k, v)
trans = {'ss': 0.3,
         'sb': 0.7,
         'bm': 0.3,
         'be': 0.7,
         'mm': 0.3,
         'me': 0.7,
         'es': 0.3,
         'eb': 0.7
         }
trans = {i: log(j) for i, j in trans.items()}

def viterbi(nodes):
    paths = nodes[0]
    for l in range(1, len(nodes)):
        paths_ = paths
        paths = {}
        for i in nodes[l]:
            nows = {}
            for j in paths_:
                if j[-1]+i in trans:
                    nows[j+i] = paths_[j]+nodes[l][i]+trans[j[-1]+i]
            k = list(nows.values()).index(max(list(nows.values())))
            paths[list(nows.keys())[k]] = list(nows.values())[k]
    return list(paths.keys())[list(paths.values()).index(max(list(paths.values())))]

def hmm_cut(s):
    nodes = [{i:log(j[t]+1)-log_total[i] for i, j in hmm_model.items()} for t in s]
    tags = viterbi(nodes)
    words = [s[0]]
    for i in range(1, len(s)):
        if tags[i] in ['b', 's']:
            words.append(s[i])
        else:
            words[-1] += s[i]
    return words

# print(' '.join(hmm_cut('今天天气不错')))
# print(' '.join(hmm_cut('李想是一个好孩子')))

print(' '.join(hmm_cut('你是直接用的他的模型还是用代码和训练数据集，还是说你这个只是从他论文上截图下来的')))
# print("小明 硕士 毕业 于 中 国科 学院 计算 所")
# print(' '.join(hmm_cut('已结婚的和尚未结婚的青年都要实行计划生育')))


import argparse
import os
import sys

from piprot.piprot import Piprot

def entrypoint():
    cli_parser = argparse.ArgumentParser(
        epilog="Here's hoping your requirements are nice and fresh!"
    )

    cli_parser.add_argument(
        "-d",
        "--delay",
        type=int,
        default=5,
        help="Delay before an outdated package triggers an error. (in days, defaults to 5).",
    )

    if os.path.isfile("requirements.txt"):
        nargs = "*"
        default = ["requirements.txt"]
    else:
        nargs = "+"
        default = None

    cli_parser.add_argument(
        "files", nargs=nargs, type=str, default=default, help="requirements file(s)"
    )

    cli_args = cli_parser.parse_args()
    piprot = Piprot(req_files=cli_args.files, delay_in_days=cli_args.delay)
    sys.exit(piprot.main())

if __name__ == "__main__":
    entrypoint()


import io, tempfile, os
from . import *
import nutils.log, nutils.core, nutils.parallel

log_stdout = '''\
iterator > iter 0 (0%) > a
iterator > iter 1 (33%) > b
iterator > iter 2 (67%) > c
levels > error
levels > warning
levels > user
levels > info
forked > [1] error
forked > [1] warning
forked > [1] user
forked > [1] info
exception > ValueError('test',)
  File "??", line ??, in ??
    raise ValueError( 'test' )
test.png
nonexistent.png
'''

log_stdout3 = '''\
levels > error
levels > warning
levels > user
forked > [1] error
forked > [1] warning
forked > [1] user
exception > ValueError('test',)
  File "??", line ??, in ??
    raise ValueError( 'test' )
'''

log_rich_output = '''\
\033[K\033[1;30miterator\033[0m\r\
\033[K\033[1;30miterator · iter 0 (0%)\033[0m\r\
\033[K\033[1;30miterator · iter 0 (0%) · \033[0ma
\033[K\033[1;30miterator · iter 1 (33%)\033[0m\r\
\033[K\033[1;30miterator · iter 1 (33%) · \033[0mb
\033[K\033[1;30miterator · iter 2 (67%)\033[0m\r\
\033[K\033[1;30miterator · iter 2 (67%) · \033[0mc
\033[K\033[1;30miterator · iter 3 (100%)\033[0m\r\
\033[K\033[1;30mempty\033[0m\r\
\033[K\033[1;30mempty · empty\033[0m\r\
\033[K\033[1;30mlevels\033[0m\r\
\033[K\033[1;30mlevels · \033[1;31merror\033[0m
\033[K\033[1;30mlevels · \033[0;31mwarning\033[0m
\033[K\033[1;30mlevels · \033[0;33muser\033[0m
\033[K\033[1;30mlevels · \033[0minfo
\033[K\033[1;30mforked · \033[1;31m[1] error\033[0m
\033[K\033[1;30mforked · \033[0;31m[1] warning\033[0m
\033[K\033[1;30mforked · \033[0;33m[1] user\033[0m
\033[K\033[1;30mforked · \033[0m[1] info
\033[K\033[1;30mexception\033[0m\r\
\033[K\033[1;30mexception · \033[1;31mValueError(\'test\',)
  File "??", line ??, in ??
    raise ValueError( \'test\' )\033[0m
\033[K\033[1;30m\033[0mtest.png
\033[K\033[1;30m\033[0mnonexistent.png
\033[K'''

log_html = '''\
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd">

<title>test</title>

<link rel="stylesheet" type="text/css" href="style.css">
<meta charset="UTF-8" />

iterator

iter 0 (0%)

a

iter 1 (33%)

b

iter 2 (67%)

c

levels

error

warning

user

info

exception

ValueError('test',)
  File "??", line ??, in ??
    raise ValueError( 'test' )

test.png

nonexistent.png

'''

log_indent = '''\
c iterator
 c iter 0 (0%)
  i a
 c iter 1 (33%)
  i b
 c iter 2 (67%)
  i c
c levels
 e error
 w warning
 u user
 i info
c exception
 e ValueError('test',)
 |   File "??", line ??, in ??
 |     raise ValueError( 'test' )
i test.png
i nonexistent.png
'''

def generate_log():
  with nutils.log.context( 'iterator' ):
    for i in nutils.log.iter( 'iter', 'abc' ):
      nutils.log.info( i )
  with nutils.log.context( 'empty' ):
    with nutils.log.context( 'empty' ):
      pass
  with nutils.log.context( 'levels' ):
    for level in ( 'error', 'warning', 'user', 'info' ):
      getattr( nutils.log, level )( level )
  nutils.parallel.procid = 1
  with nutils.log.context( 'forked' ):
    for level in ( 'error', 'warning', 'user', 'info' ):
      getattr( nutils.log, level )( level )
  nutils.parallel.procid = None
  with nutils.log.context( 'exception' ):
    nutils.log.error(
      "ValueError('test',)\n" \
      '  File "??", line ??, in ??\n' \
      "    raise ValueError( 'test' )")
  with nutils.core.open_in_outdir( 'test.png', 'w' ) as f:
    pass
  nutils.log.info( 'test.png' )
  nutils.log.info( 'nonexistent.png' )

@parametrize
class logoutput(ContextTestCase):

  def setUpContext(self, stack):
    super().setUpContext(stack)
    self.outdir = stack.enter_context(tempfile.TemporaryDirectory())
    if self.progressfile == 'seekable':
      self.progressfileobj = stack.enter_context(open(os.path.join(self.outdir, 'progress.json'), 'w' ))
    elif self.progressfile == 'stream':
      self.progressfileobj = progressfile=io.StringIO()
    else:
      self.progressfileobj = None

  def test(self):
    __outdir__ = self.outdir
    __verbose__ = self.verbose
    # Make sure all progress information is written, regardless the speed of
    # this computer.
    __progressinterval__ = -1
    stream = io.StringIO()
    kwargs = dict(title='test') if self.logcls == nutils.log.HtmlLog else {}
    if self.progressfileobj is not None:
      kwargs.update(progressfile=self.progressfileobj)
    with self.logcls(stream, **kwargs) as __log__:
      generate_log()
    self.assertEqual(stream.getvalue(), self.logout)

_logoutput = lambda name, logcls, logout, verbose=len(nutils.log.LEVELS), progressfile=False: logoutput(name, logcls=logcls, logout=logout, verbose=verbose, progressfile=progressfile)
_logoutput('stdout', nutils.log.StdoutLog, log_stdout)
_logoutput('stdout-verbose3', nutils.log.StdoutLog, log_stdout3, verbose=3)
_logoutput('rich_output', nutils.log.RichOutputLog, log_rich_output)
_logoutput('html', nutils.log.HtmlLog, log_html)
_logoutput('indent', nutils.log.IndentLog, log_indent)
_logoutput('indent-progress-seekable', nutils.log.IndentLog, log_indent, progressfile='seekable')
_logoutput('indent-progress-stream', nutils.log.IndentLog, log_indent, progressfile='stream')

class tee_stdout_html(ContextTestCase):

  def setUpContext(self, stack):
    super().setUpContext(stack)
    self.outdir = stack.enter_context(tempfile.TemporaryDirectory())

  def test(self):
    __outdir__ = self.outdir
    __verbose__ = len(nutils.log.LEVELS)
    stream_stdout = io.StringIO()
    stream_html = io.StringIO()
    __log__ = nutils.log.TeeLog(
      nutils.log.StdoutLog(stream_stdout),
      nutils.log.HtmlLog(stream_html, title='test'))
    with __log__:
      generate_log()
    self.assertEqual(stream_stdout.getvalue(), log_stdout)
    self.assertEqual(stream_html.getvalue(), log_html)

class html_post_mortem(ContextTestCase):

  def setUpContext(self, stack):
    super().setUpContext(stack)
    self.outdir = stack.enter_context(tempfile.TemporaryDirectory())

  def test(self):
    class TestException(Exception): pass

    virtual_module = dict(TestException=TestException)
    exec('''\
def generate_exception(level=0):
  if level == 1:
    raise TestException
  else:
    generate_exception(level+1)
''', virtual_module)
    __outdir__ = self.outdir
    stream = io.StringIO()
    with self.assertRaises(TestException):
      with nutils.log.HtmlLog(stream, title='test') as __log__:
        virtual_module['generate_exception']()
    self.assertIn('', stream.getvalue())

class move_outdir(ContextTestCase):

  def setUpContext(self, stack):
    super().setUpContext(stack)
    tmpdir = stack.enter_context(tempfile.TemporaryDirectory())
    self.outdira = os.path.join(tmpdir, 'a')
    self.outdirb = os.path.join(tmpdir, 'b')
    os.mkdir(self.outdira)
    self.outdirfd = os.open(self.outdira, flags=os.O_RDONLY)
    stack.callback(os.close, self.outdirfd)

  def test(self):
    __outdirfd__ = self.outdirfd
    os.rename(self.outdira, self.outdirb)
    __verbose__ = len(nutils.log.LEVELS)
    stream = io.StringIO()
    with nutils.log.HtmlLog(stream, title='test') as __log__:
      generate_log()
    self.assertEqual(stream.getvalue(), log_html)


import numpy as np
from scipy.sparse import lil_matrix

def get_bigramms(word):
    """
    Функция, составляющая по слову множество биграмм его букв.
    """
    n_gramms = set()
    n_gramms.add(" " + word[0])
    n_gramms.add(word[-1] + " ")
    for i in range(0, len(word) - 2):
        n_gramms.add(word[i:i + 2])
    return n_gramms

class CountVectorizer:
    """
    Класс, реализующий преобразование строк в векторы с помощью подхода Bag of Words.
    :param analyzer: 'word' - мешок слов, 'char_bigrams' - мешок буквенных биграмм
    """
    def __init__(self, analyzer='word'):
        """
        """
        self.columns = []
        self.n_dimensions = 0
        self.analyzer = analyzer

    def fit(self, texts):
        """
        Функция, находящая все уникальные слова или буквенные n-граммы в данных текстах.
        """
        col = set()
        for text in texts:
            for word in text.split():
                if self.analyzer == 'word':
                    if word not in col:
                        col.add(word)
                elif self.analyzer == 'char_bigrams':
                    bigramms = get_bigramms(word)
                    col = col | bigramms
        self.n_dimensions = len(col)
        self.columns = list(col)

    def fit_transform(self, texts):
        self.fit(texts)
        return self.transform(texts)

    def transform(self, texts):
        """
        Функция, преобразующая список строк в массив numpy.array
        """
        shape = (len(texts), self.n_dimensions)
        matrix = lil_matrix(shape)
        for row_index, text in enumerate(texts):
            enterings = {k: 0 for k in self.columns}

            for key in enterings:
                if self.analyzer == 'word':
                    enterings[key] = text.count(key)
                elif self.analyzer == 'char_bigrams':
                    bigramms = []
                    for word in text.split():
                        bigramms.extend(get_bigramms(word))
                    enterings[key] = bigramms.count(key)

            for column_index, col in enumerate(self.columns):
                matrix[row_index, column_index] = enterings[col]
        return matrix

    def __setstate__(self, d):
        self.columns = d['columns']
        self.n_dimensions = d['n_dim']
        self.analyzer = d['analyzer']

    def __getstate__(self):
        return {'columns': self.columns, 'n_dim': self.n_dimensions, 'analyzer': self.analyzer}


#BA model
import networkx as nx
import random
import matplotlib.pyplot as plt
import numpy as np
import scipy.stats as stats
import os
import logbin as lb
###############################################################################
# Will only print out information if N is below this number, use for testing
Nprint=20
# set seed to a number if you want to fix the random number seed for testing
# Otherwise set seed = None if you want true random numbers
#seed=0
seed = None
# Random numbers, not used here but in general of use
# see http://docs.python.org/2/library/random.html
# I often use random.randrange, random.sample, and random.random
if seed is None:
    random.seed()
    print(' Random number seed not fixed for proper run')
else:
    random.seed(seed)
    print (' Random number seed fixed for testing')
###############################################################################
#functions
# algin the eqautions in latex
def initG(N,edges,m_o,k,nodes):
    # initialise graph
    a=nx.Graph()
    # add nodes
    for i in range(N):
        a.add_node(i)
        nodes.append(i)
    # Now add edges
    # avoid self-edges
    for s in range(m_o+1):
        #print(s)
        for t in range(s,N):
                a.add_edge(s,t)
                #shw(a)
                edges.append([s,t])
                k[s] += 1
                edges.append([t,s])
                k[t] += 1
    return a
#plot fn
def shw(G):
    plt.figure()
    nx.draw_circular(G)
    plt.show()
#adding edge with preferential attatchment
def addedgerand(Graph, edges,nod,k,nodes):
    # want to add one end of edge to new vertex
    # then add other edge to an existing vertex preferentially
    #now insert edges
    ch = random.choice(nodes) # need to make this a list of current nodes at this time, not all total nodes
    k[ch] += 2
    edges.append([ch,ch])
    edges.append([ch,ch])
def addedgepref(Graph, edges,nod,k,nodes):
    # want to add one end of edge to new vertex
    # then add other edge to an existing vertex preferentially
    #now insert edges
    ch = random.choice(edges) # need to make this a list of current nodes at this time, not all total nodes
    v = random.choice(ch)
    #filter out self-loops
    #print(ch)
    # aviod self edges
    if v != nod:

        edges.append([nod,v])
        edges.append([v,nod])
        k[nod] += 1
        k[v] += 1
    elif v == nod:
        while v == nod:
            ch = random.choice(edges)
            v = random.choice(ch)
        k[nod] += 1
        k[v] += 1
        edges.append([nod,v])
        edges.append([v,nod])
# need parameters
#N total number of inital vertices
N = 3
#initialise graph with two connected nodes
#plt.figure()
#nx.draw_circular(G)
#plt.show()
#edge that has been added shouldnt be added again
n_add = 100000 #add this many nodes
#add nodes to initial graph
#degree of each nodes
nodestotal = [x for x in range(N+n_add+1)]
def addnewnodes(N,n_add,G,m,edges,k,nodes):
    for i in range(N,n_add+N+1):
        G.add_node(i)
        nodes.append(i)
        # Now add edges
        # avoid self-edges
        for h in range(int(m/2)):
            addedgepref(G,edges,i,k,nodes)
            #shw(G)
        for g in range(int(m/2)):
            addedgerand(G,edges,i,k,nodes)
def logbinn(k,scale,N,n_add,m):
    #need to do checks for this
    #need to log bin degrees
    #theory
    #plt.figure()
    #plt.rcParams.update({'font.size': 32})
    #plt.scatter(np.log(kt),np.log(pt), color = 'r', label = 'Theory, ' + str(m))
    #numerical
    #form a list of nodes - this is the number of nodes plus the number you add
    nodes = [x for x in range(N+n_add+1)]
    #subtract mink
    knew = np.array(k) - np.array(len(k)*[min(k)])
    #print(min(k),m)
    #print(edges)
    p = lb.logbin(knew,scale=scale)
    #p2 = lb.logbin(knew,scale=scale)
    #add back kmin to k values
    kf1 = np.array(p[0]) + np.array(len(p[0])*[min(k)])
    #kf2 = np.array(p2[0]) + np.array(len(p2[0])*[min(k)])
    return p,kf1 #return the k distribution
def theoryval(m,kk):
    ptt = []
    for i in kk:
        a = ((9*m) + 6)*((9*m) + 4)*((9*m) + 2)*(9*m)
        b = (i+(4*m)+4)*(i+(4*m)+3)*(i+(4*m)+2)*(i+(4*m)+1)*(i+(4*m))
        ptt.append(a/(4*b))
    pt = ptt
    return pt # returns theory prob for each k
def chisqttest(m,p2,kf): # mention why you did or didnt use the tests
    #for the statistical comparison
    # compare numerical data to theory
    # numerical only gives a fixed number of data points for certian k
    # plug this value of k into the theory and then use the kai squared test to compare answers.
    t = theoryval(m,kf)[:10]
    n = p2[1][:10]
    statistic, pval = stats.chisquare( n, t)
    print('stat = ',statistic,", for m = ",m)
    print('p-value = ',pval)
    critval = stats.chi2.ppf(q=0.95,df=len(kf)-1) # list of data set is df, check rwsidue qq plot- tell you if it as gaussian or not buuilt in func.
    print("crit val = ",critval)
    #plt.figure()
    #shift back logbin data
    #plt.scatter(np.log(kf),np.log(p2[1]), label = 'Numerical ' + str(m))
    #plt.scatter(np.log(kf[:15]),np.log(t), label = 'Theory ' + str(m))
    #plt.legend()
#list of m for same N
# need to do repeats and append before log binning!
repeats = 5
for x in [4,32]:#,8,16,32,64]:
    kreap = []
    for i in range(repeats):
        edges = []
        nodes = []
        k = len(nodestotal)*[0] # initial list of nodes with zero degree
        G = initG(N,edges,2,k,nodes) # create initial graph
        addnewnodes(N,n_add,G,x,edges,k,nodes) # add all nodes
        kreap.extend(k)
    pt = []
    plt.rcParams.update({'font.size': 32})
    #plt.scatter(np.log(kreap),np.log(pt),marker = '.', color = 'black')
    #p,p2,kf1,kf2 = logbinn(kreap,1.35,N,n_add,x) # outputs log binned data with scaling.
    #plt.scatter(np.log(kf1),np.log(p[1]),s = 10, label = 'No scaling logbin, m ='+str(x))
    #plt.scatter(np.log(kf2),np.log(p2[1]),s=150, label = 'Log binned, m = '+str(x) )
    p,kf = logbinn(kreap,1.35,N,n_add,x) # outputs log binned data with scaling.
    pt = theoryval(x,kf)
    #p = lb.logbin(k,scale=1.35)
    print(len(p[0]),len(p[1]))
    plt.scatter(np.log(kf),np.log(pt), color = 'r', label = 'Theory, ' + str(x))
    plt.scatter(np.log(kf),np.log(p[1]),s = 350,marker = '.', label = 'm ='+str(x))
    plt.legend()
    print('done ' + str(x))
    #plt.show()
    chisqttest(x,p,kf)
plt.rcParams.update({'font.size': 32})
plt.xlabel('ln($k$)')
plt.ylabel('ln($p_{\infty}(k)$)')
plt.show()
# do repeats for each m value and append each repeat then log bin.
# should help to get finite sized stuff


from collections import Counter

def choose(n, k):
  k = min(k, n-k)
  result = 1
  for i in xrange(k):
    result *= n - i
    result /= i + 1
  return result

def factorial(n):
  result = 1
  for i in xrange(2, n+1):
    result *= i
  return result

def isFactorial(n):
  runningFactorial = 1
  next             = 2
  while runningFactorial < n:
    runningFactorial *= next
    next             += 1
  return runningFactorial == n

def inverseFactorial(n):
  runningFactorial = 1
  next             = 1
  while runningFactorial < n:
    next             += 1
    runningFactorial *= next
  if runningFactorial != n:
    raise ValueError('The argument is not a valid factorial.')
  return next

def numPermutations(iterable):
  length      = len(iterable)
  frequencies = Counter(iterable)
  result      = factorial(length)
  for element in frequencies:
    result /= factorial(frequencies[element])
  return result

def numIntegerPermutations(iterable):
  # Catch empty iterable
  if len(iterable) == 0:
    return 0
  # In case a string is passed in, and not an int list
  intIterable = map(int, iterable)
  # If all permutations are integers, return that count
  if 0 not in intIterable:
    return numPermutations(intIterable)
  # Check for the singleton digit 0
  if len(intIterable) == 1:
    return 1
  # General case
  length          = len(intIterable)
  frequencies     = Counter(intIterable)
  frequencies[0] -= 1
  length         -= 1
  permutationsWithZeroFirst = factorial(length)
  for element in frequencies:
    permutationsWithZeroFirst /= factorial(frequencies[element])
  return numPermutations(iterable) - permutationsWithZeroFirst


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

from rest_framework import status
from rest_framework.parsers import MultiPartParser
from rest_framework.views import APIView
from rest_framework.response import Response
import backend.common.video_handler as handler
import datetime
import logging
import uuid
import os
from valley.settings import UPLOAD_ROOT

logger = logging.getLogger("valley")

class UploadFileView(APIView):
    parser_classes = (MultiPartParser,)

    def post(self, request, format=None):
        files = request.FILES.getlist("attachment", None)
        result = {}
        files_address = []
        try:
            fileDir = os.path.join(UPLOAD_ROOT, 'attachments', str(uuid.uuid4()))
            if (not os.path.exists(fileDir)) and len(files) != 0:  # 如果路径不存在
                os.makedirs(fileDir)
            try:
                for file in files:
                    file_absolute_path = os.path.join(fileDir, file.name).replace("\"", "")
                    file_handler = open(file_absolute_path, 'wb')  # 打开特定的文件进行二进制的写操作
                    try:
                        for chunk in file.chunks():  # 分块写入文件
                            file_handler.write(chunk)
                    finally:
                        file_handler.close()
                    files_address.append(file_absolute_path)
            except Exception as e:
                logger.error(e)
            result['msg'] = '查询成功'
            result['success'] = True
            result['data'] = files_address
            return Response(result, status.HTTP_200_OK)
        except Exception as e:
            logger.error(e)
            result['msg'] = '查询失败 %s' % e
            result['success'] = False
            return Response(result, status.HTTP_500_INTERNAL_SERVER_ERROR)

class UploadVideoView(APIView):
    parser_classes = (MultiPartParser,)

    def post(self, request, format=None):
        files = request.FILES.getlist("video", None)
        result = {}
        files_address = []
        try:
            subdir = os.path.join('videos', str(uuid.uuid4()))
            fileDir = os.path.join(UPLOAD_ROOT, subdir)
            if (not os.path.exists(fileDir)) and len(files) != 0:  # 如果路径不存在
                os.makedirs(fileDir)
            try:
                for file in files:
                    ext = os.path.splitext(file.name)[1]
                    name = datetime.datetime.now().strftime("%Y%m%d%H%M%S")
                    file_relative_path = os.path.join(subdir, name + ext)
                    file_absolute_path = os.path.join(fileDir, name + ext).replace("\"", "")
                    file_handler = open(file_absolute_path, 'wb')  # 打开特定的文件进行二进制的写操作
                    try:
                        for chunk in file.chunks():  # 分块写入文件
                            file_handler.write(chunk)
                    finally:
                        file_handler.close()
                    try:
                        out_path = os.path.join(fileDir, 'out.m3u8').replace("\"", "")
                        cover_path = os.path.join(fileDir, 'cover.jpeg').replace("\"", "")
                        thumb_path = os.path.join(fileDir, 'thumb.jpeg').replace("\"", "")
                        handler.create_m3u8(file_absolute_path, out_path, cover_path, thumb_path)
                        file_relative_path = os.path.join(subdir, 'out.m3u8')
                    except Exception as ex:
                        logger.error(ex)
                    files_address.append(file_relative_path)
            except Exception as e:
                logger.error(e)
            result['msg'] = '上传成功'
            result['success'] = True
            result['data'] = files_address
            return Response(result, status.HTTP_200_OK)
        except Exception as e:
            logger.error(e)
            result['msg'] = '上传失败 %s' % e
            result['success'] = False
            return Response(result, status.HTTP_500_INTERNAL_SERVER_ERROR)


import cube
from astropy.utils import data
from spectral_cube import SpectralCube, Projection
from radio_beam import Beam
from astropy import units as u
import time
import numpy as np
import matplotlib.pyplot as plt
import math
from astropy.io import fits
from astropy.wcs import WCS
from astropy.coordinates import SkyCoord
from astropy.nddata import Cutout2D
from regions import read_ds9

from matplotlib import rcParams
rcParams['mathtext.default']='regular'

############################################################
# basic information

position=SkyCoord(dec=50.4167*u.arcmin,ra=204.9706*u.degree,frame='icrs')

############################################################
# function

def fits_import(fitsimage, item=0):
    hdr = fits.open(fitsimage)[item].header
    wcs = WCS(hdr).celestial
    data=fits.open(fitsimage)[item].data
    data=np.squeeze(data)
    data_masked=np.ma.masked_invalid(data)

    return wcs, data_masked

def cut_2d(data,position,size,wcs):
    cut=Cutout2D(data=data,position=position,size=size,wcs=wcs)
    data_cut=cut.data
    wcs_cut=cut.wcs

    return wcs_cut, data_cut

############################################################
# main program

Dir='/1/home/heh15/workingspace/Arp240/NGC5257/12CO10/'
imageDir=Dir+'casa5.4/'
picDir=Dir+'picture/'
regionDir=Dir+'region/'

name=imageDir+'NGC5257_12CO10_combine_contsub_pbcor.fits'
imagecube=SpectralCube.read(name)
# imcube=imagecube.with_spectral_unit(u.km/u.s,velocity_convention='radio',rest_value=112.73*10**9*u.Hz)
common_beam = imagecube.beams.common_beam(tolerance=1e-5)
Imcube = imagecube.convolve_to(common_beam)

## create rms cube
rmscube=cube.calc_noise_in_cube(Imcube, spatial_average_nbeam=1.0, spectral_average_nchan=2)

# # mask the the low value of rmscube.
# mask=rmscube<3.0e-3*u.Jy/u.beam
# lowrms=rmscube.with_mask(~mask)
# newrms=lowrms.with_fill_value(3.0e-3)

## find the signal of the cube.
outcube=cube.find_signal_in_cube(Imcube,rmscube,snr_hi=4,nchan_hi=1,nchan_lo=2)
outcube.write(imageDir+'NGC5257_12CO10_pbcor_cube.fits',overwrite=True)
# kcube=outcube.to(u.K)
# kcube.write(imageDir+'NGC5257_12CO10_kcube.fits')

fitsfile=imageDir+'NGC5257_12CO10_pbcor_cube.fits'
outcube=SpectralCube.read(fitsfile)

### moment 0 map ###
imcube=outcube.with_spectral_unit(u.km/u.s,velocity_convention='radio',rest_value=112.73*10**9*u.Hz)
moment0=imcube.moment(order=0)
moment0.write(imageDir+'NGC5257_12CO10_pbcor_cube_mom0.fits',overwrite=True)
wcs=WCS(moment0.hdu.header)
mom0_data=moment0.hdu.data

size=u.Quantity((54,42),u.arcsec)
wcs_cut=cut_2d(mom0_data,position,size,wcs)[0]
mom0_cut=cut_2d(mom0_data,position,size,wcs)[1]

### moment 1 map ###
imcube=outcube.with_spectral_unit(u.km/u.s,velocity_convention='radio',rest_value=112.73*10**9*u.Hz)
moment1=imcube.moment(order=1)
moment1.write(imageDir+'NGC5257_12CO10_pbcor_cube_mom1.fits',overwrite=True)

wcs=WCS(moment1.hdu.header)
mom1_data=moment1.hdu.data

size=u.Quantity((54,42),u.arcsec)
wcs_cut=cut_2d(mom1_data,position,size,wcs)[0]
mom1_cut=cut_2d(mom1_data,position,size,wcs)[1]

fig=plt.figure()
ax=plt.subplot('111',projection=wcs_cut)
im=plt.imshow(mom0_cut,origin='lower',cmap='rainbow')
cbar=plt.colorbar(im)
cbar.set_label('km/s')

# region=read_ds9(regionDir+'anomaly.reg')[0]
# region_pix=region.to_pixel(wcs_cut)
# region_pix.plot(color='black')
# plt.savefig(picDir+'NGC5257_12CO10_mom1.png')

# name=imageDir+'NGC5257_12CO10_combine_contsub_pbcor.fits'
# imagecube=SpectralCube.read(name)
# test=np.array(outcube)
# np.nansum(test[:,160,160])*10

# imagecube[:,160,160].quicklook()
# outcube[:,160,160].quicklook()

# print(moment0[160,160])

# name=imageDir+'NGC5257_12CO10_combine_contsub_pbcor_mom0.fits'
# mom0=fits_import(name)[1]
# print(mom0[160,160])


from itertools import product

def prime_sieve(N):
  """
  Compute all prime to N
  initial condition: N > 1
  O(n log log n)
  """
  primes = [True]*(N+1)
  primes[0] = primes[1] = False

  for i in range(2, int(N**0.5)+1):
    if primes[i]:
      for j in range(i*i, N+1, i):
        primes[j] = False

  return primes

def divisor(num):
  """
  Return lowest divisor of number
  """
  for x in range(2,int(num**0.5)+1):
    if num%x == 0:
      return x
  return num

def jamcoin(digits):
  for binary in product(('0','1'),repeat=digits-2):
    coin = ''.join(('1',) + binary + ('1',))

    if not any(divisor(int(coin,base))==int(coin,base) for base in range(2,11)):
      print('Coin found: {}'.format(coin))
      yield coin

fh = open('output_large.txt','w')

T = int(input().strip())
for i in range(T):
  N, J = [int(x) for x in input().strip().split()]

  print('Case #{}:'.format(i+1),file=fh)

  coins = 0

  # Find Jam Coin
  for i in jamcoin(N):
    coins += 1

    # Find divisors
    div = []
    for base in range(2,11):
      div.append(divisor(int(i,base)))

    print('{} {}'.format(i,' '.join(map(str,div))),file=fh)
    if coins >= J: break


import logging
import os
import signal
import sys
import time
import atexit
import inspect
import gevent
import locust
from typing import Dict
from . import log
from .argument_parser import parse_locustfile_option, parse_options
from .env import Environment
from .log import setup_logging, greenlet_exception_logger
from . import stats
from .stats import (
    print_error_report,
    print_percentile_stats,
    print_stats,
    print_stats_json,
    stats_printer,
    stats_history,
)
from .stats import StatsCSV, StatsCSVFileWriter
from .user.inspectuser import print_task_ratio, print_task_ratio_json
from .util.timespan import parse_timespan
from .exception import AuthCredentialsError
from .input_events import input_listener
from .html import get_html_report
from .util.load_locustfile import load_locustfile

try:
    # import locust_plugins if it is installed, to allow it to register custom arguments etc
    import locust_plugins  # pyright: ignore[reportMissingImports]
except ModuleNotFoundError:
    pass

version = locust.__version__

def create_environment(
    user_classes,
    options,
    events=None,
    shape_class=None,
    locustfile=None,
    available_user_classes=None,
    available_shape_classes=None,
):
    """
    Create an Environment instance from options
    """
    return Environment(
        locustfile=locustfile,
        user_classes=user_classes,
        shape_class=shape_class,
        events=events,
        host=options.host,
        reset_stats=options.reset_stats,
        parsed_options=options,
        available_user_classes=available_user_classes,
        available_shape_classes=available_shape_classes,
    )

def main():
    # find specified locustfile(s) and make sure it exists, using a very simplified
    # command line parser that is only used to parse the -f option.
    locustfiles = parse_locustfile_option()
    locustfiles_length = len(locustfiles)

    # Grabbing the Locustfile if only one was provided. Otherwise, allowing users to select the locustfile in the UI
    # If --headless or --autostart and multiple locustfiles, all provided UserClasses will be ran
    locustfile = locustfiles[0] if locustfiles_length == 1 else None

    # Importing Locustfile(s) - setting available UserClasses and ShapeClasses to choose from in UI
    user_classes: Dict[str, locust.User] = {}
    available_user_classes = {}
    available_shape_classes = {}
    for _locustfile in locustfiles:
        docstring, _user_classes, shape_class = load_locustfile(_locustfile)

        # Setting Available Shape Classes
        if shape_class:
            shape_class_name = type(shape_class).__name__
            if shape_class_name in available_shape_classes.keys():
                sys.stderr.write(f"Duplicate shape classes: {shape_class_name}\n")
                sys.exit(1)

            available_shape_classes[shape_class_name] = shape_class

        # Setting Available User Classes
        for key, value in _user_classes.items():
            if key in available_user_classes.keys():
                previous_path = inspect.getfile(user_classes[key])
                new_path = inspect.getfile(value)
                if previous_path == new_path:
                    # The same User class was defined in two locustfiles but one probably imported the other, so we just ignore it
                    continue
                else:
                    sys.stderr.write(
                        f"Duplicate user class names: {key} is defined in both {previous_path} and {new_path}\n"
                    )
                    sys.exit(1)

            user_classes[key] = value
            available_user_classes[key] = value

    if len(stats.PERCENTILES_TO_CHART) != 2:
        logging.error("stats.PERCENTILES_TO_CHART parameter should be 2 parameters \n")
        sys.exit(1)

    def is_valid_percentile(parameter):
        try:
            if 0 < float(parameter) < 1:
                return True
            return False
        except ValueError:
            return False

    for percentile in stats.PERCENTILES_TO_CHART:
        if not is_valid_percentile(percentile):
            logging.error(
                "stats.PERCENTILES_TO_CHART parameter need to be float and value between. 0 < percentile < 1 Eg 0.95\n"
            )
            sys.exit(1)
    # parse all command line options
    options = parse_options()

    if options.headful:
        options.headless = False

    if options.slave or options.expect_slaves:
        sys.stderr.write("The --slave/--expect-slaves parameters have been renamed --worker/--expect-workers\n")
        sys.exit(1)

    if options.autoquit != -1 and not options.autostart:
        sys.stderr.write("--autoquit is only meaningful in combination with --autostart\n")
        sys.exit(1)

    if options.hatch_rate:
        sys.stderr.write("[DEPRECATED] The --hatch-rate parameter has been renamed --spawn-rate\n")
        options.spawn_rate = options.hatch_rate

    # setup logging
    if not options.skip_log_setup:
        if options.loglevel.upper() in ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"]:
            setup_logging(options.loglevel, options.logfile)
        else:
            sys.stderr.write("Invalid --loglevel. Valid values are: DEBUG/INFO/WARNING/ERROR/CRITICAL\n")
            sys.exit(1)

    logger = logging.getLogger(__name__)
    greenlet_exception_handler = greenlet_exception_logger(logger)

    if options.stop_timeout:
        try:
            options.stop_timeout = parse_timespan(options.stop_timeout)
        except ValueError:
            logger.error("Valid --stop-timeout formats are: 20, 20s, 3m, 2h, 1h20m, 3h30m10s, etc.")
            sys.exit(1)

    if options.list_commands:
        print("Available Users:")
        for name in user_classes:
            print("    " + name)
        sys.exit(0)

    if not user_classes:
        logger.error("No User class found!")
        sys.exit(1)

    # make sure specified User exists
    if options.user_classes:
        missing = set(options.user_classes) - set(user_classes.keys())
        if missing:
            logger.error(f"Unknown User(s): {', '.join(missing)}\n")
            sys.exit(1)
        else:
            names = set(options.user_classes) & set(user_classes.keys())
            user_classes = [user_classes[n] for n in names]
    else:
        # list() call is needed to consume the dict_view object in Python 3
        user_classes = list(user_classes.values())

    if os.name != "nt" and not options.master:
        try:
            import resource

            minimum_open_file_limit = 10000
            current_open_file_limit = resource.getrlimit(resource.RLIMIT_NOFILE)[0]

            if current_open_file_limit < minimum_open_file_limit:
                # Increasing the limit to 10000 within a running process should work on at least MacOS.
                # It does not work on all OS:es, but we should be no worse off for trying.
                resource.setrlimit(resource.RLIMIT_NOFILE, [minimum_open_file_limit, resource.RLIM_INFINITY])
        except BaseException:
            logger.warning(
                f"""System open file limit '{current_open_file_limit}' is below minimum setting '{minimum_open_file_limit}'.
It's not high enough for load testing, and the OS didn't allow locust to increase it by itself.
See https://github.com/locustio/locust/wiki/Installation#increasing-maximum-number-of-open-files-limit for more info."""
            )

    # create locust Environment
    locustfile_path = None if not locustfile else os.path.basename(locustfile)

    environment = create_environment(
        user_classes,
        options,
        events=locust.events,
        shape_class=shape_class,
        locustfile=locustfile_path,
        available_user_classes=available_user_classes,
        available_shape_classes=available_shape_classes,
    )

    if shape_class and (options.num_users or options.spawn_rate):
        logger.warning(
            "The specified locustfile contains a shape class but a conflicting argument was specified: users or spawn-rate. Ignoring arguments"
        )

    if options.show_task_ratio:
        print("\n Task ratio per User class")
        print("-" * 80)
        print_task_ratio(user_classes, options.num_users, False)
        print("\n Total task ratio")
        print("-" * 80)
        print_task_ratio(user_classes, options.num_users, True)
        sys.exit(0)
    if options.show_task_ratio_json:
        print_task_ratio_json(user_classes, options.num_users)
        sys.exit(0)

    if options.master:
        if options.worker:
            logger.error("The --master argument cannot be combined with --worker")
            sys.exit(-1)
        if options.expect_workers_max_wait and not options.expect_workers:
            logger.error("The --expect-workers-max-wait argument only makes sense when combined with --expect-workers")
            sys.exit(-1)
        runner = environment.create_master_runner(
            master_bind_host=options.master_bind_host,
            master_bind_port=options.master_bind_port,
        )
    elif options.worker:
        try:
            runner = environment.create_worker_runner(options.master_host, options.master_port)
            logger.debug("Connected to locust master: %s:%s", options.master_host, options.master_port)
        except OSError as e:
            logger.error("Failed to connect to the Locust master: %s", e)
            sys.exit(-1)
    else:
        runner = environment.create_local_runner()

    # main_greenlet is pointing to runners.greenlet by default, it will point the web greenlet later if in web mode
    main_greenlet = runner.greenlet

    if options.run_time:
        if options.worker:
            logger.error("--run-time should be specified on the master node, and not on worker nodes")
            sys.exit(1)
        try:
            options.run_time = parse_timespan(options.run_time)
        except ValueError:
            logger.error("Valid --run-time formats are: 20, 20s, 3m, 2h, 1h20m, 3h30m10s, etc.")
            sys.exit(1)

    if options.csv_prefix:
        stats_csv_writer = StatsCSVFileWriter(
            environment, stats.PERCENTILES_TO_REPORT, options.csv_prefix, options.stats_history_enabled
        )
    else:
        stats_csv_writer = StatsCSV(environment, stats.PERCENTILES_TO_REPORT)

    # start Web UI
    if not options.headless and not options.worker:
        # spawn web greenlet
        protocol = "https" if options.tls_cert and options.tls_key else "http"
        try:
            if options.web_host == "*":
                # special check for "*" so that we're consistent with --master-bind-host
                web_host = ""
            else:
                web_host = options.web_host
            if web_host:
                logger.info(f"Starting web interface at {protocol}://{web_host}:{options.web_port}")
            else:
                logger.info(
                    "Starting web interface at %s://0.0.0.0:%s (accepting connections from all network interfaces)"
                    % (protocol, options.web_port)
                )
            web_ui = environment.create_web_ui(
                host=web_host,
                port=options.web_port,
                auth_credentials=options.web_auth,
                tls_cert=options.tls_cert,
                tls_key=options.tls_key,
                stats_csv_writer=stats_csv_writer,
                delayed_start=True,
                userclass_picker_is_active=options.class_picker,
            )
        except AuthCredentialsError:
            logger.error("Credentials supplied with --web-auth should have the format: username:password")
            sys.exit(1)
    else:
        web_ui = None

    if options.autostart and options.headless:
        logger.warning("The --autostart argument is implied by --headless, no need to set both.")

    if options.autostart and options.worker:
        logger.warning("The --autostart argument has no meaning on a worker.")

    def assign_equal_weights(environment, **kwargs):
        environment.assign_equal_weights()

    if options.equal_weights:
        environment.events.init.add_listener(assign_equal_weights)

    # Fire locust init event which can be used by end-users' code to run setup code that
    # need access to the Environment, Runner or WebUI.
    environment.events.init.fire(environment=environment, runner=runner, web_ui=web_ui)

    if web_ui:
        web_ui.start()
        main_greenlet = web_ui.greenlet

    def stop_and_optionally_quit():
        if options.autostart and not options.headless:
            logger.info("--run-time limit reached, stopping test")
            runner.stop()
            if options.autoquit != -1:
                logger.debug("Autoquit time limit set to %s seconds" % options.autoquit)
                time.sleep(options.autoquit)
                logger.info("--autoquit time reached, shutting down")
                runner.quit()
                if web_ui:
                    web_ui.stop()
            else:
                logger.info("--autoquit not specified, leaving web ui running indefinitely")
        else:  # --headless run
            logger.info("--run-time limit reached, shutting down")
            runner.quit()

    def spawn_run_time_quit_greenlet():
        gevent.spawn_later(options.run_time, stop_and_optionally_quit).link_exception(greenlet_exception_handler)

    headless_master_greenlet = None
    stats_printer_greenlet = None
    if not options.only_summary and (options.print_stats or (options.headless and not options.worker)):
        # spawn stats printing greenlet
        stats_printer_greenlet = gevent.spawn(stats_printer(runner.stats))
        stats_printer_greenlet.link_exception(greenlet_exception_handler)

    gevent.spawn(stats_history, runner)

    def start_automatic_run():
        if options.master:
            # wait for worker nodes to connect
            start_time = time.monotonic()
            while len(runner.clients.ready) < options.expect_workers:
                if options.expect_workers_max_wait and options.expect_workers_max_wait < time.monotonic() - start_time:
                    logger.error("Gave up waiting for workers to connect")
                    runner.quit()
                    sys.exit(1)
                logging.info(
                    "Waiting for workers to be ready, %s of %s connected",
                    len(runner.clients.ready),
                    options.expect_workers,
                )
                # TODO: Handle KeyboardInterrupt and send quit signal to workers that are started.
                #       Right now, if the user sends a ctrl+c, the master will not gracefully
                #       shutdown resulting in all the already started workers to stay active.
                time.sleep(1)
        if not options.worker:
            # apply headless mode defaults
            if options.num_users is None:
                options.num_users = 1
            if options.spawn_rate is None:
                options.spawn_rate = 1

            # start the test
            if environment.shape_class:
                if options.run_time:
                    sys.stderr.write("It makes no sense to combine --run-time and LoadShapes. Bailing out.\n")
                    sys.exit(1)
                try:
                    environment.runner.start_shape()
                    environment.runner.shape_greenlet.join()
                except KeyboardInterrupt:
                    logging.info("Exiting due to CTRL+C interruption")
                finally:
                    stop_and_optionally_quit()
            else:
                headless_master_greenlet = gevent.spawn(runner.start, options.num_users, options.spawn_rate)
                headless_master_greenlet.link_exception(greenlet_exception_handler)

        if options.run_time:
            logger.info(f"Run time limit set to {options.run_time} seconds")
            spawn_run_time_quit_greenlet()
        elif not options.worker and not environment.shape_class:
            logger.info("No run time limit set, use CTRL+C to interrupt")

    if options.csv_prefix:
        gevent.spawn(stats_csv_writer.stats_writer).link_exception(greenlet_exception_handler)

    if options.headless:
        start_automatic_run()

    input_listener_greenlet = None
    if not options.worker:
        # spawn input listener greenlet
        input_listener_greenlet = gevent.spawn(
            input_listener(
                {
                    "w": lambda: runner.start(runner.user_count + 1, 100)
                    if runner.state != "spawning"
                    else logging.warning("Already spawning users, can't spawn more right now"),
                    "W": lambda: runner.start(runner.user_count + 10, 100)
                    if runner.state != "spawning"
                    else logging.warning("Already spawning users, can't spawn more right now"),
                    "s": lambda: runner.start(max(0, runner.user_count - 1), 100)
                    if runner.state != "spawning"
                    else logging.warning("Spawning users, can't stop right now"),
                    "S": lambda: runner.start(max(0, runner.user_count - 10), 100)
                    if runner.state != "spawning"
                    else logging.warning("Spawning users, can't stop right now"),
                },
            )
        )
        input_listener_greenlet.link_exception(greenlet_exception_handler)
        # ensure terminal is reset, even if there is an unhandled exception in locust or someone
        # does something wild, like calling sys.exit() in the locustfile
        atexit.register(input_listener_greenlet.kill, block=True)

    def shutdown():
        """
        Shut down locust by firing quitting event, printing/writing stats and exiting
        """
        logger.debug("Running teardowns...")

        if input_listener_greenlet is not None:
            input_listener_greenlet.kill(block=False)

        environment.events.quitting.fire(environment=environment, reverse=True)

        # determine the process exit code
        if environment.process_exit_code is not None:
            code = environment.process_exit_code
        elif len(runner.errors) or len(runner.exceptions):
            code = options.exit_code_on_error
        elif log.unhandled_greenlet_exception:
            code = 2
        else:
            code = 0

        logger.info(f"Shutting down (exit code {code})")

        if stats_printer_greenlet is not None:
            stats_printer_greenlet.kill(block=False)
        if headless_master_greenlet is not None:
            headless_master_greenlet.kill(block=False)
        logger.debug("Cleaning up runner...")
        if runner is not None:
            runner.quit()
        if options.json:
            print_stats_json(runner.stats)
        elif not isinstance(runner, locust.runners.WorkerRunner):
            print_stats(runner.stats, current=False)
            print_percentile_stats(runner.stats)
            print_error_report(runner.stats)

        environment.events.quit.fire(exit_code=code)
        sys.exit(code)

    # install SIGTERM handler
    def sig_term_handler():
        logger.info("Got SIGTERM signal")
        shutdown()

    def save_html_report():
        html_report = get_html_report(environment, show_download_link=False)
        logger.info("writing html report to file: %s", options.html_file)
        with open(options.html_file, "w", encoding="utf-8") as file:
            file.write(html_report)

    gevent.signal_handler(signal.SIGTERM, sig_term_handler)

    try:
        logger.info(f"Starting Locust {version}")
        if options.class_picker:
            logger.info("Locust is running with the UserClass Picker Enabled")
        if options.autostart and not options.headless:
            start_automatic_run()

        main_greenlet.join()
        if options.html_file:
            save_html_report()
    except KeyboardInterrupt:
        if options.html_file:
            save_html_report()
    except Exception:
        raise
    shutdown()


import doit
from doit import create_after
import glob
from numpy import int32
import os
import pandas as pd
import config
import subprocess
import shlex
from io import StringIO
import time
import json

# def task_scan_serialnumbers():
#     def get_serialnumbers(dependencies, targets):
#         mountpoints = pd.DataFrame(json.loads(subprocess.getoutput('lsblk -J -o  NAME,SIZE,FSTYPE,TYPE,MOUNTPOINT'))['blockdevices'])
#         mountpoints = mountpoints[~mountpoints.children.isna()]
#         mountpoints =pd.DataFrame(mountpoints.children.apply(lambda x: x[0]).to_list())[['name','mountpoint']]
#         paths = pd.DataFrame(subprocess.getoutput('udevadm info -q path -n $(ls /dev/s*1)').splitlines(),columns=['Path'])
#         paths[['host','dev']]=paths.Path.str.extract(r'(?P<host>host\d+).*block\/(?P<dev>([^\\]+$))')[['host','dev']]
#         paths['name'] =paths.dev.str.split('/',expand=True)[1]
#         mountpoints =mountpoints.merge(paths, on='name', how='inner')
#         mountpoints['CardUUID']=mountpoints.mountpoint.str.extract(r'(?P<CardUUID>[0-9A-F]{4}-[0-9A-F]{4})')
#         mountpoints = mountpoints[~mountpoints.CardUUID.isna()]
#         os.makedirs(os.path.dirname(targets[0]),exist_ok=True)
#         path = f'{os.path.dirname(targets[0])}/{os.path.splitext(os.path.basename(targets[0]))[0].split("_")[1]}'
#         mountpoints['Destination'] = path
#         mountpoints.to_csv(targets[0],index=False)

#     t = time.localtime()
#     target = f"{config.geturl('imagehead')}/backup_{time.strftime('%Y%m%dT%H%M%S', t)}_source.csv"
#     return {
#         'actions':[get_serialnumbers],
#         'targets':[target],
#         'uptodate':[False],
#         'clean':True,
#     }

# @create_after(executed='scan_serialnumbers', target_regex='*.csv')
def task_rsync_cards():
    def rsync_cards(dependencies, targets):
        cards = pd.read_csv(dependencies[0])
        cards = cards.groupby('mountpoint').first()
        hosts = cards.host.unique()
        cards['RsyncDone']= False
        processes = set()
        max_processes = 4
        workon = True
        hosts = cards.host.unique()
        for host in hosts:
            item =cards[cards['host']==host].iloc[0]
            if os.path.exists(item.name):
                os.makedirs(item.Destination,  exist_ok=True)
                command = shlex.split(f"rsync -a -W  --exclude '*.LRV' --exclude '*.THM' --progress  {item.name} {item.Destination}")
                processes.add(subprocess.Popen(command))#,startupinfo=
                if len(processes) >= max_processes:
                    os.wait()
                processes.difference_update([p for p in processes if p.poll() is not None])
        for host in hosts:
            if len(cards[cards['host']==host])==2: #check to see if there were two cards on the host
                item =cards[cards['host']==host].iloc[-1]
                if os.path.exists(item.name):
                    os.makedirs(item.Destination, exist_ok=True)
                    command = shlex.split(f"rsync -a -W  --exclude '*.LRV' --exclude '*.THM' --progress  {item.name} {item.Destination}")
                    processes.add(subprocess.Popen(command))
                    if len(processes) >= max_processes:
                        os.wait()
                    processes.difference_update([p for p in processes if p.poll() is not None])
        for p in processes:
            if p.poll() is None:
                p.wait()
        cards['RsyncDone']= cards.Destination.apply(os.path.exists)
        cards.to_csv(targets[0])
    file_dep = glob.glob(f"{config.geturl('imagehead')}/backup_*_source.csv")
    for file in file_dep:
        target = file.replace('.csv','_cardsread.csv')
        yield {
            'name':file,
            'file_dep':[file],
            'actions':[rsync_cards],
            'targets':[target],
            'uptodate':[False],
            'clean':True,
        }

@create_after(executed='rsync_cards', target_regex='*.csv')
def task_sync_backup():
    file_dep = glob.glob(f"{config.geturl('imagehead')}/*_cardsread.csv")
    t = time.localtime()
    target = f"{config.geturl('imagehead')}/log_{time.strftime('%Y%m%dT%H%M%S', t)}.log"
    return {
        'file_dep':file_dep,
        'actions':[f"rsync -av --progress {config.geturl('imagehead')}/  {config.geturl('backuphead')} > {target}"],
        'targets':[target],
        'uptodate':[True],
        'clean':True,
    }

@create_after(executed='sync_backup', target_regex='*.csv')
def task_clean_cards():
    def rsync_cards(dependencies, targets):
        cards = pd.read_csv(dependencies[0])
        cards['Backup'] =cards.Destination.str.replace(config.geturl('imagehead'),config.geturl('backuphead'))
        cards = cards.groupby('mountpoint').first()
        hosts = cards.host.unique()
        cards['CleanDone']= False
        processes = set()
        max_processes = 4
        workon = True
        hosts = cards.host.unique()
        for host in hosts:
            item =cards[cards['host']==host].iloc[0]
            if os.path.exists(item.name):
                os.makedirs(item.Destination,  exist_ok=True)
                command = shlex.split(f"rsync -a -W  --exclude '*.LRV' --exclude '*.THM' --progress --remove-source-files {item.name} {item.Backup}")
                processes.add(subprocess.Popen(command))#,startupinfo=
                if len(processes) >= max_processes:
                    os.wait()
                processes.difference_update([p for p in processes if p.poll() is not None])
        for host in hosts:
            if len(cards[cards['host']==host])==2: #check to see if there were two cards on the host
                item =cards[cards['host']==host].iloc[-1]
                if os.path.exists(item.name):
                    os.makedirs(item.Destination, exist_ok=True)
                    command = shlex.split(f"rsync -a -W  --exclude '*.LRV' --exclude '*.THM' --progress --remove-source-files {item.name} {item.Backup}")
                    processes.add(subprocess.Popen(command))
                    if len(processes) >= max_processes:
                        os.wait()
                    processes.difference_update([p for p in processes if p.poll() is not None])
        for p in processes:
            if p.poll() is None:
                p.wait()
        cards['CleanDone']= True
        cards.to_csv(targets[0])
    file_dep = glob.glob(f"{config.geturl('imagehead')}/*_cardsread.csv")
    for file in file_dep:
        target = file.replace('.csv','_z`cleaned.csv')
        yield {
            'name':file,
            'file_dep':[file],
            'actions':[rsync_cards],
            'targets':[target],
            'uptodate':[False],
            'clean':True,
        }

    # def sync_dbackup()
    #         os.makedirs(item.Destination,  exist_ok=True)
    #         command = shlex.split(f"rsync -a -W  --exclude '*.LRV' --exclude '*.THM' --progress  {item.name} {item.Destination}")
    #         processes.add(subprocess.Popen(command))#,startupinfo=
# def task_scan_devs():
#     result = subprocess.getoutput('lsblk -J -o  NAME,SIZE,FSTYPE,TYPE,MOUNTPOINT')

# def task_process_cameras():
#     def process_cameras(dependencies, targets):
#         backupsessions = pd.read_csv(config.geturl('backupsessions'),index_col='TimeStamp',parse_dates=['TimeStamp']).sort_values('TimeStamp')
#         barnumbers = pd.read_csv(config.geturl('barnumbers'))
#         cameras = []
#         for item in dependencies:
#             filter = os.path.join(item,config.cfg['paths']['videowild'])
#             files = glob.glob(filter)
#             if files:
#                 command = f"exiftool -api largefilesupport=1 -u  -json -ext MP4 -q -CameraSerialNumber -CreateDate -SourceFile -Duration -FileSize -FieldOfView {item}"
#                 result =subprocess.getoutput(command)
#                 try:
#                     df =pd.read_json(result)
#                     cameras.append(df)
#                 except:
#                     print('No json')
#         cameras = pd.concat(cameras)
#         cameras['CreateDate'] = pd.to_datetime(cameras['CreateDate'],format='%Y:%m:%d %H:%M:%S')
#         cameras =cameras.merge(barnumbers, on='CameraSerialNumber', how='inner')
#         path = f"{config.geturl('cardstore')}/{backupsessions.iloc[-1].name:%Y%m%dT%H%M%S}"
#         os.makedirs(path,exist_ok=True)
#         cameras['Destination']=cameras.apply(lambda x: f"{path}/{x.CameraNumber}_{x.CameraSerialNumber}_{x.CreateDate:%Y%m%dT%H%M}",axis=1)
#         cameras.to_csv(targets[0],index=False)

#     gopro = glob.glob('/media/*/*/DCIM/100GOPRO')
#     backupsessions = pd.read_csv(config.geturl('backupsessions'),index_col='TimeStamp',parse_dates=['TimeStamp']).sort_values('TimeStamp')
#     target = f"{config.geturl('cardstore')}/backup_{backupsessions.iloc[-1].name:%Y%m%dT%H%M%S}.csv"
#     return {
#         'file_dep':gopro,
#         'actions':[get_serialnumbers],
#         'targets':[target],
#         'uptodate':[True],
#         'clean':True,
#     }

if __name__ == '__main__':
    import doit
    DOIT_CONFIG = {'check_file_uptodate': 'timestamp'}
    #print(globals())
    doit.run(globals())


import requests
from bs4 import BeautifulSoup
from RankingView import *
#定义函数获取并检测页面信息
def Text(url):
     # 爬虫请求头信息
    headers = {
         'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36',
    }
    try:
        respone = requests.get(url,headers=headers,timeout=30)
        respone.raise_for_status()
        #解决中文字符编码问题
        respone.encoding = respone.apparent_encoding
        return respone.text
    except:
        return ""
def bang(url):
    html = Text(url)
    #使用BeautifulSoup解析页面信息
    soup = BeautifulSoup(html, "html.parser")
    name,zhishu,xingxi = [],[],[]
    #开始获取作品名称信息
    allname = soup.find_all('p',class_ = 'm-title')
    for x in allname:
        name.append(x.string) #使用列表方式 添加信息
    #获取作品昨日指数信息
    allzhishu = soup.find_all("li",class_='m-item-playcount')
    for y in allzhishu:
        zhishu.append(y.span.string)
    #使用中文字符的空格填充
#     print("{0}\t{1}\t{2:^40}".format("排名","作品名称","昨日指数",chr(12288)))
    #用range函数获取前50个数据
    for i in range(50):
#         print("{0}\t{1}\t{2:^40}".format(i+1, name[i], zhishu[i],chr(12288)))
#         xingxi.append([i+1, name[i], zhishu[i]])
        xingxi.append([name[i], zhishu[i]])
    return xingxi
def hot_search(mode='电视剧'):
    url=['https://www.360kan.com/rank/dianshi','https://www.360kan.com/rank/dianying']
    if mode=='电视剧':
        k=0
    elif mode=='电影':
        k=1
    else:
        return [['未找到!','','']]
    list = bang(url[k])
    if k==0:
        dainshi_bang(list)
        reli2(list)
    if k==1:
        dainying_bang(list)
        reli(list)
    return list
def cloudGen():
    lst=[]
    lst.append(hot_search('电视剧'))
    lst.append(hot_search('电影'))
    word_cloud(lst)
# cloudGen()
# t=hot_search('电影')
# print(t)


"""For an input measure generator and measurement_function algorithm
this script will:
1) compare the output from measure to truth
2) return performance metrics

Performance metrics computed separately for detection, segmentation, flux,
redshift

"""
import numpy as np
import btk.config
import btk.get_input_catalog
import btk.create_blend_generator
import btk.create_observing_generator
import btk.measure
import btk.draw_blends
from scipy import spatial

class Metrics_params(object):
    def make_meas_generator(self, catalog_name, max_number=2,
                            batch_size=1, seed=999):
        """
        Creates the default btk.meas_generator for input catalog
        Overwrite this function for user defined measurement generator
        """
        # Load parameters
        param = btk.config.Simulation_params(
            catalog_name, max_number=max_number, batch_size=batch_size,
            seed=seed)
        np.random.seed(param.seed)
        # Load input catalog
        catalog = btk.get_input_catalog.load_catlog(param)
        # Generate catalogs of blended objects
        blend_generator = btk.create_blend_generator.generate(
            param, catalog)
        # Generates observing conditions
        observing_generator = btk.create_observing_generator.generate(
            param)
        # Generate images of blends in all the observing bands
        draw_blend_generator = btk.draw_blends.generate(
            param, blend_generator, observing_generator)
        meas_params = btk.measure.Measurement_params()
        meas_generator = btk.measure.generate(
            meas_params, draw_blend_generator, param)
        self.meas_generator = meas_generator

    def get_detections(self, index):

        return [], []

    def get_segmentation(self, data=None, index=None):
        return None

    def get_flux(self, data=None, index=None):
        return None

    def get_redshift(self, data=None, index=None):
        return None

def evaluate_detection(detected_centers, true_centers,
                       distance_upper_bound=4):
    """
    Compares the true centers and detected centers to identify the
    number of true detections, number of sources that were undetected
    and number of spurious detections.
    Args:
        true_catalog: Catalog with true parameters of galaxies in blend.
        detected_centers: Centroids from detection algorithm ([N, (x, y)])
        distance_upper_bound: Match objects within this distance (in pixels)
                              (Default:10)
    Returns:
    """
    if len(detected_centers) == 0:
        # no detection
        return 0, len(true_centers), 0
    z_tree = spatial.KDTree(true_centers)
    detected_centers = np.array(detected_centers).reshape(-1, 2)
    match = z_tree.query(detected_centers,
                         distance_upper_bound=distance_upper_bound)
    fin, = np.where(match[0] != np.inf)  # match exists
    inf, = np.where(match[0] == np.inf)  # no match within distance_upper_bound
    detected = len(np.unique(match[1][fin]))
    undetected = len(np.setdiff1d(range(len(true_centers)), match[1][fin]))
    spurious = len(match[1][inf])
    return detected, undetected, spurious

def evaluate_segmentation(segmentation, data=None, index=None):
    if segmentation is None:
        return None
    return None

def evaluate_flux(flux, data=None, index=None):
    if flux is None:
        return None
    return None

def evaluate_redshift(redshift, data=None, index=None):
    if redshift is None:
        return None
    return None

def run(Metrics_params, test_size=1000):
    results = {'detection': [], 'segmentation': [],
               'flux': [], 'redshift': []}
    for i in range(test_size):
        # Evaluate detection algorithm
        detected_centers, true_centers = Metrics_params.get_detections(
            index=i)
        results['detection'].append(evaluate_detection(
            detected_centers, true_centers))
        # Evaluate segmentation algorithm
        segmentation = Metrics_params.get_segmentation(index=i)
        results['segmentation'].append(evaluate_segmentation(
            segmentation))
        # Evaluate flux measurement algorithm
        flux = Metrics_params.get_flux(
            index=i)
        results['flux'].append(evaluate_flux(
            flux))
        # Evaluate redshift estimation algorithm
        redshift = Metrics_params.get_redshift(
            index=i)
        results['redshift'].append(evaluate_redshift(
            redshift))
    return results


"""
Serializers from financialaid
"""
import datetime

from django.shortcuts import get_object_or_404
from rest_framework import serializers
from rest_framework.exceptions import ValidationError
from rest_framework.fields import IntegerField, FloatField, CharField

from courses.models import Program
from dashboard.models import ProgramEnrollment
from financialaid.api import determine_tier_program, determine_auto_approval
from financialaid.models import FinancialAid, FinancialAidStatus

class FinancialAidSerializer(serializers.Serializer):
    """
    Serializer for Financial Aid objects
    """
    original_income = FloatField(min_value=0)
    original_currency = CharField()
    program_id = IntegerField()

    def validate(self, data):
        """
        Validators for this serializer
        """
        data["program"] = get_object_or_404(Program, pk=data["program_id"])
        if not data["program"].financial_aid_availability:
            raise ValidationError("Financial aid not available for this program.")
        if not ProgramEnrollment.objects.filter(program=data["program"], user=self.context["request"].user).exists():
            raise ValidationError("User not in program.")
        return data

    def save(self):
        """
        Override save method
        """
        if self.validated_data["original_currency"] != "USD":
            raise ValidationError("Only USD supported currently")
        user = self.context["request"].user
        tier_program = determine_tier_program(self.validated_data["program"], self.validated_data["original_income"])

        financial_aid = FinancialAid.objects.create(
            original_income=self.validated_data["original_income"],
            original_currency=self.validated_data["original_currency"],
            tier_program=tier_program,
            user=user,
            income_usd=self.validated_data["original_income"],
            country_of_income=user.profile.country,
            date_exchange_rate=datetime.datetime.now()
        )

        if determine_auto_approval(financial_aid) is True:
            financial_aid.status = FinancialAidStatus.AUTO_APPROVED
        else:
            financial_aid.status = FinancialAidStatus.PENDING_DOCS
        financial_aid.save()

        # Add auditing here

        return financial_aid


import numpy as np
import cv2

img=cv2.imread("chess_board.png")

cv2.imshow("original", img)
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

gray=np.float32(gray)
dst=cv2.cornerHarris(gray, blockSize=2,ksize=3,k=0.04)

dst=cv2.dilate(dst, None)

img[dst>0.01 * dst.max()] = [0,0,255]

cv2.imshow("dst", img)
if cv2.waitKey(0) == 27:
    cv2.destroyAllWindows()