import os, sys
import re
import fnmatch

try:
  from teststatus import RESULTS_KEYWORDS
except ImportError:
  from .teststatus import RESULTS_KEYWORDS

class WordExpression:
    """
    Takes a string consisting of words, parentheses, and the operators "and",
    "or", and "not".  A word is any sequence of characters not containing
    a space or a parenthesis except the special words "and", "or", and "not".
    The initial string is parsed during construction then later evaluated
    with the evaluate() method.  Each word is evaluated to true or false
    based on an evaluator function given to the evaluate() method.

    Without an expression (a None), the evaluate method will always return
    True, while an empty string for an expression will always evaluate to
    False.
    """

    def __init__(self, expr=None):
        ""
        self.expr = None

        self.words = set()   # the words in the expression

        self.evalexpr = None
        self.nr_evalexpr = None

        if expr != None:
            self.append( expr )

    def append(self, expr, operator='or'):
        """
        Appends the given expression string using an 'and' or 'or' operator.
        """
        assert operator in ['or','and']

        if expr != None:

            expr = expr.strip()

            if self.expr != None:
                expr = combine_two_expressions( self.expr, expr, operator )

            self.expr = expr

            self.evalexpr = parse_word_expression( self.expr, self.words )
            self.nr_evalexpr = parse_non_results_expression( self.expr )

    def getWordList(self):
        """
        Returns a list containing the words in the current expression.
        """
        return list( self.words )

    def containsResultsKeywords(self):
        ""
        return len( set( RESULTS_KEYWORDS ).intersection( self.words ) ) > 0

    def keywordEvaluate(self, keyword_list):
        """
        Returns the evaluation of the expression against a simple keyword list.
        """
        return self.evaluate( lambda k: k in keyword_list )

    def evaluate(self, evaluator_func, include_results=True):
        """
        Evaluates the expression from left to right using the given
        'evaluator_func' to evaluate True/False of each word.  If the original
        expression string is empty, false is returned.  If no expression was
        set in this object, true is returned.

        If 'include_results' is False, the original expression is stripped
        of results keywords and the resulting expression is evaluated.
        """
        if include_results:
            evex = self.evalexpr
        else:
            evex = self.nr_evalexpr

        if evex == None:
            return True

        def evalfunc(tok):
            if evaluator_func(tok): return True
            return False

        r = eval( evex )

        return r

    def __repr__(self):
        if self.expr == None:return 'WordExpression=None'
        return 'WordExpression="' + self.expr + '"'

    def __str__(self): return self.__repr__()

def combine_two_expressions( expr1, expr2, operator ):
    ""
    if operator == 'or':

        if expr1 and expr2:
            expr = expr1 + ' or ' + conditional_paren_wrap( expr2 )
        elif expr1:
            expr = expr1
        else:
            expr = expr2

    else:
        if expr1 and expr2:
            expr = expr1 + ' and ' + conditional_paren_wrap( expr2 )
        else:
            # one expression is empty, which is always false,
            # so replace the whole thing with an empty expr
            expr = ''

    return expr

def conditional_paren_wrap( expr ):
    ""
    if ' ' in expr:
        return '( '+expr+' )'
    return expr

def parse_word_expression( expr, wordset=None ):
    """
    Throws a ValueError if the string is an invalid expression.
    Returns the final expression string (which may be modified from the
    original).
    """
    if wordset != None:
        wordset.clear()

    toklist = separate_expression_into_tokens( expr )
    evalexpr = convert_token_list_into_eval_string( toklist )

    if wordset != None:
        add_words_to_set( toklist, wordset )

    def evalfunc(tok):
        return True
    try:
        # evaluate the expression to test validity
        v = eval( evalexpr )
        assert type(v) == type(False)
    except Exception:
        raise ValueError( 'invalid option expression: "' + expr + '"' )

    return evalexpr

def parse_non_results_expression( expr ):
    ""
    nrmod = NonResultsExpressionModifier( expr )
    toklist = nrmod.getNonResultsTokenList()

    if len( toklist ) == 0:
        return None

    else:
        evalexpr = convert_token_list_into_eval_string( toklist )
        return evalexpr

class NonResultsExpressionModifier:

    def __init__(self, expr):
        ""
        self.toklist = separate_expression_into_tokens( expr )
        self.toki = 0

        self.nonresults_toklist = self.parse_subexpr()

        trim_leading_binary_operator( self.nonresults_toklist )

    def getNonResultsTokenList(self):
        ""
        return self.nonresults_toklist

    def parse_subexpr(self):
        ""
        toklist = []
        oplist = []

        while self.toki < len( self.toklist ):

            tok = self.toklist[ self.toki ]
            self.toki += 1

            if tok in _OPERATOR_LIST:
                if tok == ')':
                    break
                elif tok == '(':
                    sublist = self.parse_subexpr()
                    if sublist:
                        append_sublist( toklist, oplist, sublist )
                    oplist = []
                else:
                    oplist.append( tok )

            elif tok in RESULTS_KEYWORDS:
                oplist = []

            else:
                append_token( toklist, oplist, tok )
                oplist = []

        return toklist

def trim_leading_binary_operator( toklist ):
    ""
    if toklist:
        if toklist[0] == 'and' or toklist[0] == 'or':
            toklist.pop( 0 )

def append_sublist( toklist, oplist, sublist ):
    ""
    append_operator( toklist, oplist )

    if oplist and len( sublist ) > 1:
        sublist = ['(']+sublist+[')']

    toklist.extend( sublist )

def append_token( toklist, oplist, tok ):
    ""
    append_operator( toklist, oplist )
    toklist.append( tok )

def append_operator( toklist, oplist ):
    ""
    if oplist:
        toklist.extend( oplist )

_OPERATOR_LIST = ['(',')','not','and','or']

def convert_token_list_into_eval_string( toklist ):
    ""
    modified_toklist = []

    for tok in toklist:
        if tok in _OPERATOR_LIST:
            modified_toklist.append( tok )
        elif tok:
            modified_toklist.append( '(evalfunc("'+tok+'")==True)' )
        else:
            modified_toklist.append( 'False' )

    return ' '.join( modified_toklist )

def add_words_to_set( toklist, wordset ):
    ""
    for tok in toklist:
        if tok and tok not in _OPERATOR_LIST:
            wordset.add( tok )

def separate_expression_into_tokens( expr ):
    ""
    toklist = []

    if expr.strip():

        for whitetok in expr.strip().split():
            for lptok in split_but_retain_separator( whitetok, '(' ):
                for rptok in split_but_retain_separator( lptok, ')' ):
                    rptok = rptok.strip()
                    if rptok:
                        toklist.append( rptok )

    else:
        toklist.append( '' )

    return toklist

def split_but_retain_separator( expr, separator ):
    ""
    seplist = []

    splitlist = list( expr.split( separator ) )
    last_token = len(splitlist) - 1

    for i,tok in enumerate( splitlist ):
        seplist.append( tok )
        if i < last_token:
            seplist.append( separator )

    return seplist

##############################################################################

class ParamFilter:

    def __init__(self, expr=None):
        """
        If 'expr' is not None, load() is called.
        """
        self.wexpr = None
        self.wordD = {}
        if expr != None:
          self.load(expr)

    def load(self, expr):
        """
        Loads the parameter specifications.  The 'expr' argument can be either
        a string word expression or a list of strings.

        If a list, each string is composed of parameter specifications
        separated by a '/' character.  A parameter specification is of the
        form:

          np        parameter np is defined
          np=       same as "np"
          !np       parameter np is not defined
          np!=      same as "!np"
          np<=4     parameter is less than or equal to four
          np>=4     parameter is greater than or equal to four
          np<4      parameter is less than four
          np>4      parameter is greater than four
          !np=4     not parameter is equal to four

        The parameter specifications separated by '/' are OR'ed together and
        the list entries are AND'ed together.

        Raises a ValueError if the expression contains a syntax error.
        """
        if type(expr) == type([]):
          # 'expr' is a list of strings that are AND'ed together
          self.wexpr = WordExpression()
          for ors in expr:
            # the divide character is used as an OR operator
            L = []
            for s in ors.split('/'):
              if s.strip():
                L.append(s)
            x = ' or '.join( L )
            self.wexpr.append(x, 'and')
        else:
          self.wexpr = WordExpression(expr)

        # map each word that appears to an evaluation function object instance
        self.wordD = {}
        for w in self.wexpr.getWordList():
          self.wordD[w] = self._make_func(w)

    def evaluate(self, paramD):
        """
        Evaluate the expression previously loaded against the given parameter
        values.  Returns true or false.
        """
        if self.wexpr == None:
          return 1
        evalobj = ParamFilter.Evaluator(self.wordD, paramD)
        return self.wexpr.evaluate( evalobj.evaluate )

    class Evaluator:
        def __init__(self, wordD, paramD):
            self.wordD = wordD
            self.paramD = paramD
        def evaluate(self, word):
            return self.wordD[word].evaluate(self.paramD)

    def _make_func(self, word):
        """
        Returns an instance of an evaluation class based on the word.
        """
        if not word: raise ValueError( 'empty word (expected a word)' )
        if word[0] == '!':
          f = self._make_func( word[1:] )
          if isinstance(f, ParamFilter.EvalLE):
            return ParamFilter.EvalGT(f.p, f.v)
          if isinstance(f, ParamFilter.EvalGE):
            return ParamFilter.EvalLT(f.p, f.v)
          if isinstance(f, ParamFilter.EvalNE):
            return ParamFilter.EvalEQ(f.p, f.v)
          if isinstance(f, ParamFilter.EvalLT):
            return ParamFilter.EvalGE(f.p, f.v)
          if isinstance(f, ParamFilter.EvalGT):
            return ParamFilter.EvalLE(f.p, f.v)
          if isinstance(f, ParamFilter.EvalEQ):
            return ParamFilter.EvalNE(f.p, f.v)
        L = word.split( '<=', 1 )
        if len(L) > 1:
          return ParamFilter.EvalLE( L[0], L[1] )
        L = word.split( '>=', 1 )
        if len(L) > 1:
          return ParamFilter.EvalGE( L[0], L[1] )
        L = word.split( '!=', 1 )
        if len(L) > 1:
          return ParamFilter.EvalNE( L[0], L[1] )
        L = word.split( '<', 1 )
        if len(L) > 1:
          return ParamFilter.EvalLT( L[0], L[1] )
        L = word.split( '>', 1 )
        if len(L) > 1:
          return ParamFilter.EvalGT( L[0], L[1] )
        L = word.split( '=', 1 )
        if len(L) > 1:
          return ParamFilter.EvalEQ( L[0], L[1] )
        return ParamFilter.EvalEQ( word, '' )

    class EvalEQ:
        def __init__(self, param, value):
            if not param: raise ValueError( 'parameter name is empty' )
            self.p = param ; self.v = value
        def evaluate(self, paramD):
            v = paramD.get(self.p,None)
            if self.v:
              if v == None: return 0  # paramD does not have the parameter
              if type(v) == type(2): return v == int(self.v)
              elif type(v) == type(2.2): return v == float(self.v)
              if v == self.v: return 1
              try:
                if int(v) == int(self.v): return 1
              except: pass
              try:
                if float(v) == float(self.v): return 1
              except: pass
              return 0
            return v != None  # true if paramD has the parameter name

    class EvalNE:
        def __init__(self, param, value):
            if not param: raise ValueError( 'parameter name is empty' )
            self.p = param ; self.v = value
        def evaluate(self, paramD):
            v = paramD.get(self.p,None)
            if self.v:
              if v == None: return 0  # paramD does not have the parameter
              if type(v) == type(2): return v != int(self.v)
              elif type(v) == type(2.2): return v != float(self.v)
              if v == self.v: return 0
              try:
                if int(v) == int(self.v): return 0
              except: pass
              try:
                if float(v) == float(self.v): return 0
              except: pass
              return 1
            return v == None  # true if paramD does not have the parameter name

    class EvalLE:
        def __init__(self, param, value):
            if not param: raise ValueError( 'parameter name is empty' )
            if not value: raise ValueError( "empty less-equal value" )
            self.p = param ; self.v = value
        def evaluate(self, paramD):
            v = paramD.get(self.p,None)
            if v == None: return 0
            if type(v) == type(2): return v <= int(self.v)
            elif type(v) == type(2.2): return v <= float(self.v)
            if v == self.v: return 1
            try:
              if int(v) > int(self.v): return 0
              return 1
            except: pass
            try:
              if float(v) > float(self.v): return 0
              return 1
            except: pass
            return v <= self.v

    class EvalGE:
        def __init__(self, param, value):
            if not param: raise ValueError( 'parameter name is empty' )
            if not value: raise ValueError( "empty greater-equal value" )
            self.p = param ; self.v = value
        def evaluate(self, paramD):
            v = paramD.get(self.p,None)
            if v == None: return 0
            if type(v) == type(2): return v >= int(self.v)
            elif type(v) == type(2.2): return v >= float(self.v)
            if v == self.v: return 1
            try:
              if int(v) < int(self.v): return 0
              return 1
            except: pass
            try:
              if float(v) < float(self.v): return 0
              return 1
            except: pass
            return v >= self.v

    class EvalLT:
        def __init__(self, param, value):
            if not param: raise ValueError( 'parameter name is empty' )
            if not value: raise ValueError( "empty less-than value" )
            self.p = param ; self.v = value
        def evaluate(self, paramD):
            v = paramD.get(self.p,None)
            if v == None: return 0
            if type(v) == type(2): return v < int(self.v)
            elif type(v) == type(2.2): return v < float(self.v)
            if v == self.v: return 0
            try:
              if int(v) >= int(self.v): return 0
              return 1
            except: pass
            try:
              if not float(v) < float(self.v): return 0
              return 1
            except: pass
            return v < self.v

    class EvalGT:
        def __init__(self, param, value):
            if not param: raise ValueError( 'parameter name is empty' )
            if not value: raise ValueError( "empty greater-than value" )
            self.p = param ; self.v = value
        def evaluate(self, paramD):
            v = paramD.get(self.p,None)
            if v == None: return 0
            if type(v) == type(2): return v > int(self.v)
            elif type(v) == type(2.2): return v > float(self.v)
            if v == self.v: return 0
            try:
              if int(v) <= int(self.v): return 0
              return 1
            except: pass
            try:
              if not float(v) > float(self.v): return 0
              return 1
            except: pass
            return v > self.v

######################################################################

if __name__ == "__main__":

    # this component is called as a

    import getopt
    optL,argL = getopt.getopt( sys.argv[1:], "p:o:f:" )
    for n,v in optL:
        if n == '-p':
            pD = {}
            for param,value in [ s.split('/') for s in argL[0].split() ]:
                pD[param] = value
            pf = ParamFilter( v )
            if pf.evaluate( pD ):
                sys.stdout.write( 'true' )
            else:
                sys.stdout.write( 'false' )
            break

        elif n == '-f':
            wx = WordExpression( v )
            if wx.evaluate( lambda wrd: wrd == argL[0] ):
                sys.stdout.write( 'true' )
            else:
                sys.stdout.write( 'false' )
            break

        elif n == '-o':
            opts = argL[0].split()
            wx = WordExpression( v )
            if wx.evaluate( opts.count ):
                sys.stdout.write( 'true' )
            else:
                sys.stdout.write( 'false' )
            break


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

veriler = pd.read_csv('Ads_CTR_Optimisation.csv')

import random

N = 10000
d = 10
toplam = 0
secilenler = []
for n in range(0,N):
    ad = random.randrange(d)
    secilenler.append(ad)
    odul = veriler.values[n,ad] # verilerdeki n. satır = 1 ise odul 1
    toplam = toplam + odul

plt.hist(secilenler)
plt.show()

7- Takviyeli Öğrenme (Reinforced Learning)/1- UCB (Üst Güven Sınırı)/Rasgele Örnekleme Yaklaşımı/random.py


def  even_or_average():
    list_new = []
    list_two = []
    print("Please enter 5 numbers - \n")
    count = 0
    while len(list_new) < 5:
        user_input = input(f'Please input number {count + 1} - ')
        list_new.append(int(user_input))
        count += 1
        continue
    print(list_new)
    for i in list_new:
        if i % 2 == 0:
            list_two.append(i)
            print(max(list_two))
        else:
            print(sum(list_new) / len(list_new))

even_or_average()


from menu import MENU, resources

def prompt_user():
    """Prompts user for input and returns user's choice"""
    choice = input("What would you like? (espresso/latte/cappuccino): ")
    return choice

def print_report(resources):
    """Takes resources dictionary as parameter and prints a report detailing the amount of resources
    left in the coffee machine."""
    print(f"Water: {resources['water']}ml")
    print(f"Milk: {resources['milk']}ml")
    print(f"Coffee: {resources['coffee']}")
    print(f"Money: ${resources['money']}")

def check_resources(drink, resources):
    """Takes user's drink choice and resources dictionary as input.
    Checks to see if there are enough resoures in the machine to make the user's drink choice.
    If even one resources is lower than what the user needs to make their drink, returns False."""
    enough = True
    # Check water
    if MENU[drink]["ingredients"]["milk"] > resources["milk"]:
        print("Sorry there is not enough milk.")
        enough = False
    # Check milk
    if MENU[drink]["ingredients"]["water"] > resources["water"]:
        print("Sorry there is not enough water.")
        enough = False
    #Check coffee
    if MENU[drink]["ingredients"]["coffee"] > resources["coffee"]:
        print("Sorry there is not enough coffee.")
        enough = False
    return enough

def process_coins():
    quarters = int(input("How many quarters?: "))
    dimes = int(input("How many dimes?: "))
    nickles = int(input("How many nickles?: "))
    pennies = int(input("How many pennies?: "))
    total = (quarters * 0.25) + (dimes * 0.1) + (nickles * 0.05) + (pennies * 0.01)
    return total


import requests
import time

with open('NEWURL.txt','r') as f:
	url = f.readlines()
for i in range(len(url)):
	url[i] = url[i].strip()

	try:
		t1 = time.time()
		r = requests.get(url[i])
		t2 = time.time()
		Time = t2 - t1
		print(Time)
		print(len(r.content))
		Throughput = (len(r.content)/ (Time))
		print(Throughput)
		print(type(Throughput))
		#f = open('F:\\UCL\\python\\throughput.txt', 'a+')
	except Exception as e:
		print(e)


from django.conf.urls import url
from . import views
urlpatterns = [
    url(r'^$', views.index),
    url(r'^register', views.register),
    url(r'^login', views.login),
    url(r'^show', views.show),
    url(r'^add', views.add),
    url(r'^createtrip', views.createtrip),
    url(r'^logout', views.logout),
    url(r'^(?P<tid>\d+)/destroy', views.destroy),
    url(r'^(?P<tid>\d+)/granttrip', views.granttrip),
    url(r'^(?P<tid>\d+)/view', views.view),

    # url(r'^stats', views.stats)

]


from flask import Flask, request, jsonify
import sys
from elasticsearch_dsl import Search, A, Q
from elasticsearch import Elasticsearch
app = Flask(__name__)
from flask import render_template
import logging

logger = logging.getLogger()
logger.setLevel(logging.DEBUG)

ch = logging.StreamHandler(sys.stdout)
ch.setLevel(logging.DEBUG)
logger.addHandler(ch)

es = Elasticsearch(['http://elastic:changeme@localhost:9200/'], use_ssl=False)

PAGESIZE = 8

@app.route('/')
@app.route('/movies')
def index():
    page = 1
    sort = request.args.get('sort')
    search = request.args.get('search')
    logger.debug(request.args)
    s = Search(using=es)
    s = s.index('imdb')
    s = s.source(includes=['title', 'poster', '_id'])
    s = s[(page-1)*PAGESIZE:page*PAGESIZE]
    if search:
        s = s.query(Q('multi_match', query=search, fields=['title', 'summary', 'casts'])).extra(size=8)
    if sort:
        s = s.sort(sort)
    ret = s.execute()
    logger.debug(ret.hits)
    movies = get_movies(ret.hits)
    genres = get_genre_agg()
    return render_template('review.html', movies=movies, genres=genres)

@app.route('/movie/<string:mid>')
def movie_page(mid):
    s = Search(using=es)
    s = s.index('imdb')
    s = s.filter('term', _id=mid)
    ret = s.execute()
    return render_template('single.html', movie=get_movie_detail(ret.hits[0].to_dict()))

def get_genre_agg():
    s = Search(using=es)
    s = s.index('imdb')
    s.aggs.bucket('genres', A('terms', field='genres'))
    ret = s.execute()
    return [x['key'] for x in ret.to_dict()['aggregations']['genres']['buckets']]

def get_movie_detail(movie):
    movie['genres'] = '/'.join(movie['genres'])
    movie['creators'] = ', '.join(movie['creators'])
    movie['casts'] = ', '.join(movie['casts'])
    return movie

def get_movies(hits):
    for r in hits:
        r._d_['id'] = r.meta.id
    return [x.to_dict() for x in hits]

@app.route('/suggest/<string:input>')
def get_suggest(input):
    if not input:
        return None
    s = Search(using=es)
    s = s.index('imdb')
    s = s.suggest('suggestion', input, completion={'field': 'suggest'})
    s = s.source(False)
    ret = s.execute()
    results = [x['text'] for x in ret.suggest.suggestion[0]['options']]
    return jsonify(result=results)


# -*- coding: utf-8 -*-
from __future__ import print_function
import sys, os, warnings

gpu = sys.argv[ sys.argv.index('-gpu') + 1 ] if '-gpu' in sys.argv else '0'
os.environ['PYTHONHASHSEED'] = '0'
#os.environ['CUDA_VISIBLE_DEVICES']=gpu
#os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3' # Disable Tensorflow CUDA load statements
#warnings.filterwarnings('ignore')

from keras import backend as K
import tensorflow as tf

import copy
import argparse
import numpy as np

gpus = tf.config.list_physical_devices('GPU')
print("Num GPUs Available: ", gpus)

if gpus:
  try:
    # Currently, memory growth needs to be the same across GPUs
    tf.config.experimental.set_memory_growth(gpus[int(gpu)], True)
    logical_gpus = tf.config.list_logical_devices('GPU')
    print(len(gpus), "Physical GPUs,", len(logical_gpus), "Logical GPUs")
  except RuntimeError as e:
    # Memory growth must be set before GPUs have been initialized
    print(e)

import utilArgparse
import utilConst
import utilIO
import util
import CNNmodel

#util.init()

K.set_image_data_format('channels_last')

# ----------------------------------------------------------------------------
def menu():
    parser = argparse.ArgumentParser(description='Data augmentation on test')

    parser.add_argument('-m', required=False, help='Pathfile for the model')

    parser.add_argument('-db_train_src', required=True, help='Dataset path for training (src imags)')
    parser.add_argument('-db_train_gt', required=True, help='Dataset path for training (gt images)')

    parser.add_argument('-db_test_src', required=False, help='Dataset path to test (src imags)')
    parser.add_argument('-db_test_gt', required=False, help='Dataset path to test (gt images)')

    parser.add_argument('-aug',   nargs='*',
                        choices=utilConst.AUGMENTATION_CHOICES,
                        default=[utilConst.AUGMENTATION_NONE],
                        help='Data augmentation modes')

    parser.add_argument('-npatches', default=-1, dest='n_pa', type=int,   help='Number of patches to be extracted from training data')

    parser.add_argument('-n_annotated_patches', default=-1, dest='n_an', type=int,   help='Number of patches to be extracted from training data')

    parser.add_argument('-window_w', default=256, dest='win_w', type=int,   help='width of window')
    parser.add_argument('-window_h', default=256, dest='win_h', type=int,   help='height of window')

    parser.add_argument('-l',          default=4,        dest='n_la',     type=int,   help='Number of layers')
    parser.add_argument('-f',          default=64,      dest='nb_fil',   type=int,   help='Number of filters')
    parser.add_argument('-k',          default=5,        dest='ker',            type=int,   help='kernel size')
    parser.add_argument('-drop',   default=0.2,        dest='drop',          type=float, help='dropout value')

    parser.add_argument('-pages_train',   default=-1,      type=int,   help='Number of pages to be used for training. -1 to load all the training set.')

    parser.add_argument('-e',           default=200,    dest='ep',            type=int,   help='nb_epoch')
    parser.add_argument('-b',           default=16,     dest='ba',               type=int,   help='batch size')
    parser.add_argument('-verbose',     default=1,                                  type=int,   help='1=show batch increment, other=mute')

    parser.add_argument('--test',   action='store_true', help='Only run test')

    parser.add_argument('-res', required=False, help='File where append the results.')
    parser.add_argument('-gpu',    default='0',    type=str,   help='GPU')
    parser.add_argument('-no_mask', required=False, action='store_true', help='File where append the results.')

    args = parser.parse_args()

    print('CONFIG:\n -', str(args).replace('Namespace(','').replace(')','').replace(', ', '\n - '))

    return args

def tpc_result(result):
    return round(result*100,1)

def number_to_string(number):
    return str(tpc_result(number)).replace(".",",")

if __name__ == "__main__":
    config = menu()
    print (config)

    if config.m is None:
      path_model = utilIO.getPathModel(config)
    else:
      path_model = config.m
    utilIO.createParentDirectory(path_model)

    input_shape = util.getInputShape(config)

    list_src_train = utilIO.listFilesRecursive(config.db_train_src)
    list_gt_train = utilIO.listFilesRecursive(config.db_train_gt)
    assert(len(list_src_train) == len(list_gt_train))

    train_data, val_data = util.create_Validation_and_Training_partitions(
                                        list_src_train=list_src_train,
                                        list_gt_train=list_gt_train,
                                        pages_train=config.pages_train)

    if config.test == False: # TRAINING MODE

      print("Training and validation partitioned...")
      print("\tTraining: %d" %(len(train_data)))
      print("\tValidation: %d" %(len(val_data)))

      augmentation_val = ["none"]
      if utilConst.AUGMENTATION_RANDOM in config.aug:
        augmentation_val = ["random"]

      model = CNNmodel.get_model(input_shape, config.no_mask, config.n_la, config.nb_fil, config.ker, dropout=config.drop, stride=2)

      train_generator = util.create_generator(train_data, config.no_mask, config.ba, input_shape, config.n_pa, config.n_an, config.aug)
      val_generator = util.create_generator(val_data, config.no_mask, config.ba, input_shape, config.n_pa, config.n_an, augmentation_val)

      nb_train_pages = len(train_data)
      nb_val_pages = len(val_data)

      epochs = config.ep
      patience = 20

      print("Number of effective epochs: " + str(epochs))
      print("Effective patience: " + str(patience))

      if utilConst.AUGMENTATION_RANDOM in config.aug:
        assert(config.n_pa!=-1)
        steps_per_epoch = int(np.ceil((config.n_pa*nb_train_pages)/ config.ba))
      else:
        number_annotated_patches = util.get_number_annotated_patches(train_data, input_shape[0], input_shape[1], config.n_pa)
        print ("Number of annotated patches: " + str(number_annotated_patches))
        steps_per_epoch = np.ceil(number_annotated_patches/config.ba)

      steps_per_epoch = max(1, steps_per_epoch)
      CNNmodel.train(model, path_model, train_generator, val_generator, steps_per_epoch, nb_val_pages, config.ba, epochs, patience=patience)

    else: #TEST MODE

      list_src_test = utilIO.listFilesRecursive(config.db_test_src)
      list_gt_test = utilIO.listFilesRecursive(config.db_test_gt)
      assert(len(list_src_test) == len(list_gt_test))

      test_data = utilIO.match_SRC_GT_Images(list_src_test, list_gt_test)

      print("Obtaining best threshold...(Validation partition)")

      threshold=None
      best_fm_val, best_th_val, prec_val, recall_val, dict_predictions = util.compute_best_threshold(path_model, val_data, config.ba, input_shape, nb_annotated_patches=config.n_an, threshold=threshold, with_masked_input=False)

      print("Results of the test...")
      with_mask = not config.no_mask
      dict_results = util.test_model(config, path_model, test_data, input_shape, best_th_val, with_mask)

      separator = ";"
      print ("SUMMARY:")
      str_result = "VAL"+separator+str(best_th_val) + separator + number_to_string(best_fm_val) + separator + number_to_string(prec_val) + separator + number_to_string(recall_val) + "\n"  #number_to_string(best_fm_val) + separator + number_to_string(prec_val) + separator + number_to_string(recall_val) + separator + str(best_th_val).replace(".", ",") + separator

      best_fm_test = dict_results[utilConst.KEY_RESULT][0][0]
      prec_test = dict_results[utilConst.KEY_RESULT][0][1]
      recall_test = dict_results[utilConst.KEY_RESULT][0][2]

      print("Results: " + number_to_string(best_fm_test) + separator + number_to_string(prec_test) + separator + number_to_string(recall_test))

      str_result += key + separator + separator + number_to_string(best_fm_test) + separator + number_to_string(prec_test) + separator + number_to_string(recall_test) + separator + "\n"
      print(str_result)

      if config.res is not None:
        utilIO.appendString(str_result, config.res, True)


from flask import render_template,redirect
from flask_appbuilder.models.sqla.interface import SQLAInterface
from flask import Blueprint, current_app, jsonify, make_response, request
# 将model添加成视图，并控制在前端的显示
from myapp.models.model_serving import Service,KfService
from myapp.models.model_team import Project,Project_User
from myapp.utils import core
from flask_babel import gettext as __
from flask_babel import lazy_gettext as _
from flask_appbuilder.actions import action
from myapp import app, appbuilder,db,event_logger
import logging
import re
import uuid
import requests
from myapp.exceptions import MyappException
from flask_appbuilder.security.decorators import has_access
from myapp.models.model_job import Repository
from flask_wtf.file import FileAllowed, FileField, FileRequired
from werkzeug.datastructures import FileStorage
from wtforms.ext.sqlalchemy.fields import QuerySelectField
from myapp import security_manager
import os,sys
from wtforms.validators import DataRequired, Length, NumberRange, Optional,Regexp
from wtforms import BooleanField, IntegerField, SelectField, StringField,FloatField,DateField,DateTimeField,SelectMultipleField,FormField,FieldList
from flask_appbuilder.fieldwidgets import BS3TextFieldWidget,BS3PasswordFieldWidget,DatePickerWidget,DateTimePickerWidget,Select2ManyWidget,Select2Widget
from myapp.forms import MyBS3TextAreaFieldWidget,MySelect2Widget,MyCodeArea,MyLineSeparatedListField,MyJSONField,MyBS3TextFieldWidget,MySelectMultipleField
from myapp.utils.py import py_k8s
import os, zipfile
import shutil
from flask import (
    current_app,
    abort,
    flash,
    g,
    Markup,
    make_response,
    redirect,
    render_template,
    request,
    send_from_directory,
    Response,
    url_for,
)
from .base import (
    DeleteMixin,
    api,
    BaseMyappView,
    check_ownership,
    CsvResponse,
    data_payload_response,
    DeleteMixin,
    generate_download_headers,
    get_error_msg,
    get_user_roles,
    handle_api_exception,
    json_error_response,
    json_success,
    MyappFilter,
    MyappModelView,

)
from sqlalchemy import and_, or_, select
from .baseApi import (
    MyappModelRestApi
)

import kubernetes
from kfserving import KFServingClient
from kfserving import V1alpha2EndpointSpec
from kfserving import V1alpha2CustomSpec
from kfserving import V1alpha2PredictorSpec
from kfserving import V1alpha2TensorflowSpec
from kfserving import V1alpha2InferenceServiceSpec
from kfserving import V1alpha2InferenceService

from flask_appbuilder import CompactCRUDMixin, expose
import pysnooper,datetime,time,json
conf = app.config

class KfService_ModelView(MyappModelView):
    datamodel = SQLAInterface(KfService)
    crd_name = 'inferenceservice'
    help_url = conf.get('HELP_URL', {}).get(datamodel.obj.__tablename__, '') if datamodel else ''
    show_columns = ['name', 'label','service_type','default_service','canary_service','canary_traffic_percent','k8s_yaml']
    add_columns = ['name', 'label', 'service_type','default_service','canary_service','canary_traffic_percent']
    list_columns = ['label_url','host','service','deploy','status','roll']
    edit_columns = add_columns
    base_order = ('id','desc')
    order_columns = ['id']

    @expose('/deploy1/<kfservice_id>',methods=['POST',"GET"])
    def deploy1(self,kfservice_id):
        mykfservice = db.session.query(KfService).filter_by(id=kfservice_id).first()
        from myapp.utils.py.py_k8s import K8s
        k8s = K8s(mykfservice.project.cluster.get('KUBECONFIG',''))
        namespace = conf.get('KFSERVING_NAMESPACE')
        crd_info = conf.get('CRD_INFO')['inferenceservice']
        crd_list = k8s.get_crd(group=crd_info['group'], version=crd_info['version'], plural=crd_info['plural'],
                                    namespace=namespace)
        for crd_obj in crd_list:
            if crd_obj['name'] == mykfservice.name:
                k8s.delete_crd(group=crd_info['group'], version=crd_info['version'], plural=crd_info['plural'],
                               namespace=namespace, name=mykfservice.name)
        def get_env(env_str):
            if not env_str:
                return []
            envs = re.split('\r|\n', env_str)
            envs = [env.split('=') for env in envs if env and len(env.split('=')) == 2]
            return envs

        def get_kfjson(service,mykfservice):
            if not service:
                return None

            image_secrets = conf.get('HUBSECRET', [])
            user_hubsecrets = db.session.query(Repository.hubsecret).filter(Repository.created_by_fk == g.user.id).all()
            if user_hubsecrets:
                for hubsecret in user_hubsecrets:
                    if hubsecret[0] not in image_secrets:
                        image_secrets.append(hubsecret[0])

            kfjson={
                "minReplicas": service.min_replicas,
                "maxReplicas": service.max_replicas,
                "custom": {
                    "affinity": {
                        "nodeAffinity": {
                            "requiredDuringSchedulingIgnoredDuringExecution": {
                                "nodeSelectorTerms": [
                                    {
                                        "matchExpressions": [
                                            {
                                                "key": "gpu" if core.get_gpu(service.resource_gpu)[0] else "cpu",
                                                "operator": "In",
                                                "values": [
                                                    "true"
                                                ]
                                            },
                                        ]
                                    }
                                ]
                            }
                        },
                    },
                    "imagePullSecrets": [{"name":hubsecret} for hubsecret in image_secrets],
                    "container": {
                        "image": service.images,
                        "imagePullPolicy": conf.get('IMAGE_PULL_POLICY','Always'),
                        "name": mykfservice.name+"-"+service.name,
                        "workingDir": service.working_dir if service.working_dir else None,
                        "command": ["sh", "-c",service.command] if service.command else None,
                        "resources": {
                            "requests": {
                                "cpu": service.resource_cpu,
                                "memory": service.resource_memory
                            }
                        },
                        "env":[{"name":env[0],"value":env[1]} for env in get_env(service.env)],
                        # "volumeMounts": [
                        #     {
                        #         "mountPath": "/mnt/%s" % service.created_by.username,
                        #         "name": "workspace",
                        #         "subPath": service.created_by.username
                        #     }
                        # ],
                        # "volumeDevices":[
                        #     {
                        #         "devicePath": "/data/home/",
                        #         "name": "workspace"
                        #     }
                        # ]
                    }
                    # "volumes": [
                    #     {
                    #         "name": "workspace",
                    #         "persistentVolumeClaim": {
                    #             "claimName": "kubeflow-user-workspace"
                    #         }
                    #     }
                    # ]
                }
            }
            return kfjson

        crd_json={
            "apiVersion": "serving.kubeflow.org/v1alpha2",
            "kind": "InferenceService",
            "metadata": {
                "labels": {
                    "app": mykfservice.name
                },
                "name": mykfservice.name,
                "namespace": namespace
            },
            "spec": {
                "canaryTrafficPercent": mykfservice.canary_traffic_percent,
                "default": {
                    mykfservice.service_type: get_kfjson(mykfservice.default_service,mykfservice)
                },
                "canary": {
                    mykfservice.service_type: get_kfjson(mykfservice.canary_service,mykfservice),
                } if mykfservice.canary_service else None,

            }
        }

        import yaml
        ya = yaml.load(json.dumps(crd_json))
        ya_str = yaml.safe_dump(ya, default_flow_style=False)
        logging.info(ya_str)
        crd_objects = k8s.create_crd(group=crd_info['group'],version=crd_info['version'],plural=crd_info['plural'],namespace=namespace,body=crd_json)
        flash(category='warning',message='部署启动，一分钟后部署完成')
        return redirect('/kfservice_modelview/list/')

    # 创建kfserving
    @expose('/deploy/<kfservice_id>', methods=['POST', "GET"])
    def deploy(self, kfservice_id):
        mykfservice = db.session.query(KfService).filter_by(id=kfservice_id).first()

        namespace = conf.get('KFSERVING_NAMESPACE')
        crd_info = conf.get('CRD_INFO')['inferenceservice']

        # 根据service生成container
        def make_container(service,mykfservice):
            from myapp.utils.py.py_k8s import K8s
            k8s = K8s()    # 不部署，不需要配置集群信息
            container = k8s.make_container(name=mykfservice.name + "-" + service.name,
                                           command=["sh", "-c",service.command] if service.command else None,
                                           args=None,
                                           volume_mount=None,
                                           image_pull_policy=conf.get('IMAGE_PULL_POLICY','Always'),
                                           image=service.images,
                                           working_dir=service.working_dir if service.working_dir else None,
                                           env=service.env,
                                           resource_memory=service.resource_memory,
                                           resource_cpu = service.resource_cpu,
                                           resource_gpu= service.resource_gpu,
                                           username = service.created_by.username
                                           )
            return container

        api_version = crd_info['group'] + '/' + crd_info['version']
        default_endpoint_spec = V1alpha2EndpointSpec(
            predictor=V1alpha2PredictorSpec(
                min_replicas= mykfservice.default_service.min_replicas,
                max_replicas=mykfservice.default_service.max_replicas,
                custom=V1alpha2CustomSpec(
                    container=make_container(mykfservice.default_service,mykfservice)
                )
            )
        ) if mykfservice.default_service else None

        canary_endpoint_spec = V1alpha2EndpointSpec(
            predictor= V1alpha2PredictorSpec(
                min_replicas=mykfservice.canary_service.min_replicas,
                max_replicas=mykfservice.canary_service.max_replicas,
                custom=V1alpha2CustomSpec(
                    container=make_container(mykfservice.canary_service,mykfservice)
                )
            )
        ) if mykfservice.canary_service else None

        metadata = kubernetes.client.V1ObjectMeta(
            name=mykfservice.name,
            labels={
                "app":mykfservice.name,
                "rtx-user":mykfservice.created_by.username
            },
            namespace=namespace
        )

        isvc = V1alpha2InferenceService(
            api_version=api_version,
            kind=crd_info['kind'],
            metadata=metadata,
            spec=V1alpha2InferenceServiceSpec(
                default=default_endpoint_spec,
                canary=canary_endpoint_spec,
                canary_traffic_percent=mykfservice.canary_traffic_percent
            )
          )

        KFServing = KFServingClient()
        try:
            KFServing.delete(mykfservice.name, namespace=namespace,version=crd_info['version'])
        except Exception as e:
            print(e)

        KFServing.create(isvc,namespace=namespace,version=crd_info['version'])

        flash(category='warning', message='部署启动，一分钟后部署完成')
        return redirect('/kfservice_modelview/list/')

    # 灰度
    @expose('/roll/<kfservice_id>', methods=['POST', "GET"])
    def roll(self, kfservice_id):
        mykfservice = db.session.query(KfService).filter_by(id=kfservice_id).first()
        namespace = conf.get('KFSERVING_NAMESPACE')
        crd_info = conf.get('CRD_INFO')['inferenceservice']

        # 根据service生成container
        def make_container(service, mykfservice):
            from myapp.utils.py.py_k8s import K8s
            k8s = K8s()   # 不部署，不需要配置集群信息
            container = k8s.make_container(name=mykfservice.name + "-" + service.name,
                                           command=["sh", "-c", service.command] if service.command else None,
                                           args=None,
                                           volume_mount=None,
                                           image_pull_policy=conf.get('IMAGE_PULL_POLICY','Always'),
                                           image=service.images,
                                           working_dir=service.working_dir if service.working_dir else None,
                                           env=service.env,
                                           resource_memory=service.resource_memory,
                                           resource_cpu=service.resource_cpu,
                                           resource_gpu=service.resource_gpu,
                                           username=service.created_by.username,
                                           ports = service.ports
                                           )
            return container

        canary_endpoint_spec = V1alpha2EndpointSpec(
            predictor=V1alpha2PredictorSpec(
                min_replicas=mykfservice.canary_service.min_replicas,
                max_replicas=mykfservice.canary_service.max_replicas,
                custom=V1alpha2CustomSpec(
                    container=make_container(mykfservice.canary_service, mykfservice)
                )
            )
        ) if mykfservice.canary_service else None

        KFServing = KFServingClient()
        KFServing.rollout_canary(mykfservice.name, canary=canary_endpoint_spec, percent=mykfservice.canary_traffic_percent,
                                 namespace=namespace, timeout_seconds=120,version=crd_info['version'])

        flash(category='warning', message='滚动升级已配置，刷新查看当前流量比例')
        return redirect('/kfservice_modelview/list/')

    # 基础批量删除
    # @pysnooper.snoop()
    def base_muldelete(self,items):
        if not items:
            abort(404)
        for item in items:
            try:
                k8s_client = py_k8s.K8s(item.project.cluster.get('KUBECONFIG',''))
                crd_info = conf.get("CRD_INFO", {}).get(self.crd_name, {})
                if crd_info:
                    k8s_client.delete_crd(group=crd_info['group'],version=crd_info['version'],plural=crd_info['plural'],namespace=conf.get('KFSERVING_NAMESPACE'),name=item.name)
            except Exception as e:
                flash(str(e), "danger")

    def pre_delete(self,item):
        self.base_muldelete([item])

    # @event_logger.log_this
    # @expose("/delete/<pk>")
    # @has_access
    # def delete(self, pk):
    #     pk = self._deserialize_pk_if_composite(pk)
    #     self.base_delete(pk)
    #     url = url_for(f"{self.endpoint}.list")
    #     return redirect(url)

appbuilder.add_view(KfService_ModelView,"kfserving",icon = 'fa-tasks',category = '服务化')


import typing

from sqlalchemy import Integer
from sqlalchemy import Text
from sqlalchemy.orm import DeclarativeBase
from sqlalchemy.orm import declared_attr
from sqlalchemy.orm import Mapped
from sqlalchemy.orm import mapped_column

class Base(DeclarativeBase):
    pass

class HasRelatedDataMixin:
    @declared_attr
    def related_data(cls) -> Mapped[str]:
        return mapped_column(Text(), deferred=True)

class User(HasRelatedDataMixin, Base):
    @declared_attr.directive
    def __tablename__(cls) -> str:
        return "user"

    @declared_attr.directive
    def __mapper_args__(cls) -> typing.Dict[str, typing.Any]:
        return {}

    id = mapped_column(Integer, primary_key=True)

class Foo(Base):
    __tablename__ = "foo"

    id = mapped_column(Integer, primary_key=True)

u1 = User()

if typing.TYPE_CHECKING:
    # EXPECTED_TYPE: str
    reveal_type(User.__tablename__)

    # EXPECTED_TYPE: str
    reveal_type(Foo.__tablename__)

    # EXPECTED_TYPE: str
    reveal_type(u1.related_data)

    # EXPECTED_TYPE: InstrumentedAttribute[str]
    reveal_type(User.related_data)


# 2차원 배열 채우기 3(달팽이 배열)
# filling 2D array(snail pattern array)
# n이 입력되면 크기가 n인 다음과 같은 2차원 배열을 출력하시오.
n = int(input())
a = [[0] * n for i in range(n)]
k, c = 0, 1
f = n
i = 0
j = -1
while True:
    # 행 고정, 열 증가 또는 감소
    for b in range(1, f+1):
        if k >= n*n:
            break
        k += 1
        j += c
        a[i][j] = k
    f -= 1
    if f < 1:
        break
    # 열 고정, 행 증가 또는 감소
    for b in range(1, f+1):
        if k >= n*n:
            break
        k += 1
        i += c
        a[i][j] = k
    c *= -1
for x in range(n):
    for y in range(n):
        print(a[x][y], end=' ')
    print()


"Command line driver for changing from files chunking by baseline to files chunking by time."

from hera_cal import vis_clean
from hera_cal._cli_tools import parse_args, run_with_profiling

parser = vis_clean.time_chunk_from_baseline_chunks_argparser()
a = parse_args(parser)

run_with_profiling(
    vis_clean.time_chunk_from_baseline_chunks, a,
    time_chunk_template=a.time_chunk_template,
    baseline_chunk_files=a.baseline_chunk_files, clobber=a.clobber,
    outfilename=a.outfilename, time_bounds=a.time_bounds
)


def factorial(a,n):
    flag=0
    global fac
    global i
    if a==n:
        flag=1
        if flag ==1:
            print(fac)
    else:
        fac *= i
        i=i+1
        factorial(a+1,n)
        if flag==1:
            return

t=int(input())
fac=1
i=1
factorial(0,t)


# coding: utf-8

"""Download and file clips."""

import logging
import hashlib
import os
import datetime
import ffmpy
import requests

from tinydb import Query
from config import db, SUPPORTED_TYPES, DATA_DIR

logger = logging.getLogger('oxo')

def download_clip(url, bot, update, content_type, fname=None):
    """Download clips."""
    if not fname:
        fname = hashlib.sha1(url.encode(encoding='UTF-8')).hexdigest()

    author = update.message.from_user.first_name
    if content_type not in SUPPORTED_TYPES:
        logger.info("Link not supported: \n{}\nType{}".format(
            url, content_type))
        bot.sendMessage(chat_id=update.message.chat_id, text="ðŸ‘¾ Link not supported. Only mp4, webm and gif links.")
    elif duplicate(url):
        logger.info("Detected duplicate {}".format(url))
        update.message.reply_text("ðŸ‘¾ Reposter!")
    else:
        fpath = os.path.join(DATA_DIR, "clips", fname)
        logger.debug("Downloading clip to {}...".format(fpath))

        with open(fpath, "wb+") as f:
            r = requests.get(url, stream=True)

            if r.ok:
                for block in r.iter_content(1024):
                    f.write(block)
            else:
                logger.error("Download failed {}".format(r))

        # Convert gif files using ffmpeg
        if url[-3:] == "gif":
            fpath = convert_gif(fpath)
            fname = os.path.basename(fpath)

        clip = {
            "type": "clip",
            "url": url,
            "author": author,
            "filename": fname,
            "created": datetime.datetime.now().isoformat(),
            "incoming": True
        }

        db.insert(clip)
        bot.sendMessage(chat_id=update.message.chat_id, text="ðŸ‘¾ Added video to database.")
        logger.info("Saved new clip {} from {}".format(fname, author))

def duplicate(url):
    """Boolean, true if given filenam exists in clips."""
    Duplicate = Query()
    return len(db.search(Duplicate.url == url)) > 0

#
# Converting gifs
#

def convert_gif(fpath):
    """Convert gif at fpath using ffmpeg."""
    logger.info("Converting gif to mp4...")

    new_fpath = fpath + ".mp4"

    ff = ffmpy.FFmpeg(
        inputs={
            fpath: None
        },
        outputs={
            new_fpath: '-pix_fmt yuv420p -vf "scale=trunc(iw/2)*2:trunc(ih/2)*2"'
        }
    )
    ff.run()
    return new_fpath


import flanders

# as a first step we build the search tree
# we can later reuse the search tree many times

points = [
    (60.4, 51.3),
    (173.9, 143.8),
    (132.9, 124.9),
    (19.5, 108.9),
    (196.5, 9.9),
    (143.3, 53.3),
]

tree = flanders.build_search_tree(points)

# now we will search the indices of nearest neighbor points
# for two observer points

observer_coordinates = [(119.2, 59.7), (155.2, 30.2)]
view_vectors = [(0.0, 1.0), (-1.0, -1.0)]
view_angles_deg = [90.0, 90.0]

indices = flanders.nearest_indices_from_coordinates(
    tree, observer_coordinates, view_vectors, view_angles_deg
)

assert indices == [2, -1]

# instead of using observer coordinates, also the original
# points themselves can be observers and we can select them
# by their index

observer_indices = [0, 1, 2, 3, 4, 5]
view_vectors = [(1.0, 1.0) for _ in observer_indices]
view_angles_deg = [90.0 for _ in observer_indices]

indices = flanders.nearest_indices_from_indices(
    tree, observer_indices, view_vectors, view_angles_deg
)

assert indices == [5, -1, 1, 2, -1, 1]


import ast
import asyncio
import threading
import time
from datetime import datetime, timedelta
from collector.main_collector import MainCollector
from data_base import DataBase
from keys import VIME_TEST_TOKEN
from keys import VIME_TOKEN, VIME_TEST_TOKEN
from utils import cls
from vime_api.vime import Vime

TEST_MODE = False

if TEST_MODE:
	VIME_TOKEN = VIME_TEST_TOKEN

CONFIG_FILE = 'config.cfg'

class VimeArchive:
    def __init__(self) -> None:
        self.vime = Vime(VIME_TOKEN)
        self.load_config()
        self.make_db()
        self.load_locale()
        self.log_list = []
        self.threads = []

        self.main_collector = MainCollector(self, self.db, self.db_p)
        self.run_async_thread(self.log_cycle())

    async def log_cycle(self):
        while True:
            print_text = f'Threads'
            print_text += f'\n    Count: {len(self.threads)}'
            print_text += f'\nCollectors'
            print_text += f'\n    Main Collector:          {self.main_collector.get_status()}'
            print_text += f'\n    Matches Collector:       {self.main_collector.matches_collector.get_status()}'
            print_text += f'\n    Leaderboards Collector:  {self.main_collector.lb_collector.get_status()}'
            print_text += f'\n    Players Collector:       {self.main_collector.players_collector.get_status()}'
            print_text += f'\n    Rank Collector:          {self.main_collector.rank_collector.get_status()}'
            print_text += f'\nVime'
            print_text += f'\n    Limit Remaining: {self.vime.limit_remaining}'
            print_text += f'\nDataBase users.db'
            print_text += f'\n    Update:  {len(self.users_db.update_list)}'
            print_text += f'\n    Insert:  {len(self.users_db.insert_list)}'
            print_text += f'\n    Delete:  {len(self.users_db.delete_list)}'
            print_text += f'\n    Get:     {len(self.users_db.get_dict)}'
            print_text += '\nLogs'
            for m in self.log_list:
                print_text += f'\n    {m}'
            print_text += '\nExceptions'
            for e in self.main_collector.exceptions:
                print_text += f'\n{e}'
            cls()
            print(print_text)
            time.sleep(1)

    def load_config(self):
        self.activeUsers = []
        self.last_match_id = 0
        try:
            f = open(CONFIG_FILE, 'r', encoding='utf-8')
            data = f.read()
            config = {}
            if data != '':
                config = ast.literal_eval(data)
            try:
                self.last_match_id = config['last_match_id']
            except:
                self.last_match_id = None
            try:
                self.activeUsers = config['active_users']
            except:
                self.activeUsers = []
            f.close()
        except FileNotFoundError:
            open(CONFIG_FILE, 'a', encoding='utf-8')

    def save_config(self):
        open(CONFIG_FILE, 'a', encoding='utf-8')
        f = open(CONFIG_FILE, 'w', encoding='utf-8')
        f.write(str({'last_match_id': self.main_collector.matches_collector.last_match_id, 'active_users': self.main_collector.players_collector.activeUsers}))
        f.close()

    def make_db(self):
        date = datetime.now()
        self.db = DataBase(f'{date.day}.{date.month}.{date.year}')
        date_p = datetime.now() - timedelta(days=1)
        self.db_p = DataBase(f'{date_p.day}.{date_p.month}.{date_p.year}')
        self.users_db = DataBase(date='', file_name='users.db')

    def load_locale(self):
        f = open('locale.txt', 'r', encoding='utf-8')
        self.locale = ast.literal_eval(f.read())
        f.close()

    def log(self, message: str):
        self.log_list.append(message)

    def run_async_thread(self, target):
        thread = threading.Thread(target=self.run_async, args=[target])
        self.threads.append(thread)
        thread.start()

    def run_async(self, target):
        asyncio.run(target)

vime_archive = VimeArchive()


# -*- coding: utf-8 -*-
"""
Created on Fri Sep 15 12:19:30 2023

@author: sharrm

"""

import fiona
import geopandas as gpd
import matplotlib.pyplot as plt
import numpy as np
import os
import pandas as pd
import pickle
import rasterio
from rasterio.mask import mask
from scipy import spatial
from scipy import ndimage
from skimage import feature, filters
from skimage.morphology import binary_dilation, binary_erosion
from sklearn import svm
from sklearn.ensemble import RandomForestClassifier, HistGradientBoostingClassifier
from sklearn.metrics import accuracy_score#, confusion_matrix, ConfusionMatrixDisplay
from sklearn.metrics import classification_report, f1_score, recall_score, precision_score
from sklearn.model_selection import train_test_split, learning_curve, StratifiedKFold
from sklearn.neural_network import MLPClassifier
from sklearn.preprocessing import MinMaxScaler, StandardScaler

# %% - morphology

def normalize(band):
    band_min, band_max = (np.nanmin(band), np.nanmax(band))
    return ((band-band_min)/((band_max - band_min)))

def near_land(input_blue, input_green, input_red, input_704, input_nir, shapefile, out_dir, write):

    # Open the geotiff file
    with rasterio.open(input_green) as green:
        # Read the green band metadata
        out_meta = green.meta

        # Open the shapefile
        gdf = gpd.read_file(shapefile)

        # Crop the raster to the shapefile extent
        cropped_green, transform = mask(green, gdf.geometry, crop=True)

    # Open the geotiff file
    with rasterio.open(input_nir) as nir:
        # Open the shapefile
        gdf = gpd.read_file(shapefile)

        # Crop the raster to the shapefile extent
        cropped_nir, transform = mask(nir, gdf.geometry, crop=True)

    # Open the geotiff file
    with rasterio.open(input_704) as b704:
        # Open the shapefile
        gdf = gpd.read_file(shapefile)

        # Crop the raster to the shapefile extent
        cropped_704, transform = mask(b704, gdf.geometry, crop=True)

    # Open the geotiff file
    with rasterio.open(input_blue) as blue:
        # Open the shapefile
        gdf = gpd.read_file(shapefile)

        # Crop the raster to the shapefile extent
        cropped_blue, transform = mask(blue, gdf.geometry, crop=True)

    # Open the geotiff file
    with rasterio.open(input_red) as red:
        # Open the shapefile
        gdf = gpd.read_file(shapefile)

        # Crop the raster to the shapefile extent
        cropped_red, transform = mask(red, gdf.geometry, crop=True)

    # compute ndwi
    ndwi = (cropped_green - cropped_nir) / (cropped_green + cropped_nir)
    cropped = np.moveaxis(ndwi, 0, -1)[:,:,0]

    # compute pSDBr
    pSDBr = np.log(cropped_blue * 1000) / np.log(cropped_red * 1000)
    pSDBg = np.log(cropped_blue * 1000) / np.log(cropped_green * 1000)

    # create binary array for land and water pixels
    nan_vals = np.where(np.isnan(cropped))
    cropped_land_water = np.where(cropped < 0.1, 1, 0)

    # morphological operation to grow land pixels
    morphed_land = binary_dilation(cropped_land_water) #.astype(cropped_land_water.dtype))
    erode_land = binary_erosion(morphed_land) #.astype(cropped_land_water.dtype))

    # pixels adjacent to land
    zero_mask = np.logical_and(morphed_land, ~erode_land)
    land_adjacent_ndwi = np.where(zero_mask, cropped, 0)
    # land_adjacent_ndwi = np.where(land_adjacent_ndwi < 0.15, 0, land_adjacent_ndwi)
    # land_adjacent_percentile = np.where(np.percentile(land_adjacent_ndwi, 90), land_adjacent_ndwi, 0)
    percentile10 = np.nanpercentile(cropped[zero_mask == 1], 10)
    print(f'Precentile 10: {percentile10:.3f}')
    percentile10 = np.where(land_adjacent_ndwi < percentile10, land_adjacent_ndwi, 0)

    percentile90 = np.nanpercentile(cropped[zero_mask == 1], 90)
    print(f'Precentile 90: {percentile90:.3f}')
    percentile90 = np.where(land_adjacent_ndwi > percentile90, land_adjacent_ndwi, 0)

    # ndwi values for pixels adjacent to land for histogram
    ndwi_adjacent = cropped[zero_mask == 1]
    print(f'Average land adjacent NDWI value: {np.nanmean(ndwi_adjacent):.3f} ± {np.nanstd(ndwi_adjacent):.3f}')
    print(f'Median land adjacent NDWI value: {np.nanmedian(ndwi_adjacent):.3f}')
    land_adjacent_ndwi[nan_vals] = np.nan
    percentile10[nan_vals] = np.nan
    percentile90[nan_vals] = np.nan

    red_n = normalize(cropped_red[0,:,:])
    green_n = normalize(cropped_green[0,:,:])
    blue_n = normalize(cropped_blue[0,:,:])

    rgb_composite_n = np.dstack((red_n, green_n, blue_n))

    # Stack the bands to create an RGB image
    rgb_image = np.dstack((cropped_red[0,:,:], cropped_green[0,:,:], cropped_blue[0,:,:]))
    brightened_image = np.clip(rgb_composite_n * 3, 0, 255)#.astype(np.uint8)
    brightened_image[nan_vals] = 255
    m = np.ma.masked_where(np.isnan(brightened_image),brightened_image)

    # plt.figure(figsize=(10, 10))
    f, ax = plt.subplots(2,2, figsize=(10, 6), dpi=200)
    ax[0,0].imshow(brightened_image)
    ax[0,0].set_title('RGB', fontsize=10)
    ax[0,1].imshow(land_adjacent_ndwi, vmax=0.1, cmap='cividis')
    ax[0,1].set_title('Land Adjacent Pixels', fontsize=10)
    ax[1,0].imshow(percentile10, vmax=0.01, cmap='cividis')
    ax[1,0].set_title('10th Percentile', fontsize=10)
    ax[1,1].imshow(percentile90, vmax=0.05, cmap='cividis')
    ax[1,1].set_title('90th Percentile', fontsize=10)
    # plt.tight_layout()
    plt.setp(plt.gcf().get_axes(), xticks=[], yticks=[]);
    plt.show()

    # ndwi values for pixels adjacent to land for histogram
    ndwi_adjacent = cropped[zero_mask == 1]
    print(f'Average land adjacent NDWI value: {np.nanmean(ndwi_adjacent):.3f} ± {np.nanstd(ndwi_adjacent):.3f}')
    print(f'Median land adjacent NDWI value: {np.nanmedian(ndwi_adjacent):.3f}')
    land_adjacent_ndwi[nan_vals] = np.nan

    training_data = np.vstack((cropped_blue.flatten(),
                               cropped_green.flatten(),
                               cropped_red.flatten(),
                               cropped_704.flatten(),
                               cropped_nir.flatten(),
                               ndwi.flatten(),
                               # pSDBg.flatten(),
                               pSDBr.flatten())).transpose()
    training_data[np.isnan(training_data)] = 2

    # Plot the masked image
    plt.figure(figsize=(12, 6))
    plt.subplot(2, 2, 1)
    plt.imshow(cropped, cmap='gray', vmin=0.2)
    plt.title('Land Adjacent Pixels')
    plt.imshow(zero_mask, cmap='Reds', alpha=0.3, vmax=0.2)
    plt.colorbar()

    # Plot histogram of values
    plt.subplot(2, 2, 2)
    plt.hist(ndwi_adjacent, bins=50, edgecolor='k')
    plt.xlabel('NDWI Value')
    plt.ylabel('Frequency')
    plt.title('Distribution of NDWI Values at Land Adjacent Pixels')
    plt.tight_layout()
    plt.show()

    land_adjacent_ndwi[nan_vals] = 2

    # raster meta
    out_meta.update({"driver": "GTiff",
                      "height": cropped_nir.shape[1],
                      "width": cropped_nir.shape[2],
                      "count": cropped_nir.shape[0],
                      "nodata": 2,
                      "transform": transform})

    # save rasters
    if write:
        morph_name = os.path.join(out_dir, 'morphed.tif')
        with rasterio.open(morph_name, "w", **out_meta) as dest:
            dest.write(morphed_land, 1)

        dest = None

        ndwi_name = os.path.join(out_dir, 'ndwi.tif')
        with rasterio.open(ndwi_name, "w", **out_meta) as dest:
            dest.write(cropped, 1)

        dest = None

        print(f'Wrote: {ndwi_name}')

        water_name = os.path.join(out_dir, 'land_adjacent.tif')
        with rasterio.open(water_name, "w", **out_meta) as dest:
            dest.write(land_adjacent_ndwi, 1)

        dest = None

        percentile10_name = os.path.join(out_dir, 'percentile10.tif')
        with rasterio.open(percentile10_name, "w", **out_meta) as dest:
            dest.write(percentile10, 1)

        dest = None

        print(f'Wrote: {percentile10_name}')

        percentile90_name = os.path.join(out_dir, 'percentile90.tif')
        with rasterio.open(percentile90_name, "w", **out_meta) as dest:
            dest.write(percentile90, 1)

        dest = None

        print(f'Wrote: {percentile90_name}')

    return land_adjacent_ndwi, training_data

# %% - training

# plots the learning curve -- relationship between prediction accuracy and data size
def plotLearningCurve(train_size_abs, train_mean, train_std, test_mean, test_std, curve_title):
    plt.plot(train_size_abs, train_mean, color='forestgreen', marker='o', markersize=5, label='Training Accuracy')
    plt.fill_between(train_size_abs, train_mean + train_std, train_mean - train_std, alpha=0.3, color='forestgreen')
    plt.plot(train_size_abs, test_mean, color='royalblue', marker='+', markersize=5, linestyle='--', label='Validation Accuracy')
    plt.fill_between(train_size_abs, test_mean + test_std, test_mean - test_std, alpha=0.3, color='royalblue')
    plt.title(curve_title)
    plt.xlabel('Training Data Size')
    plt.ylabel('Model accuracy (f1-score)')
    plt.grid()
    plt.legend(loc='lower right')
    plt.show()

    return None

# computes and plots learning curve
def compute_learning_curve(clf, x_train, y_train):

    # start_time = time.time() # start time for process timing
    cv = StratifiedKFold(n_splits=5)
    print(f'\nComputing learning curve for {clf}.')

    train_size_abs, train_scores, test_scores = learning_curve(
    clf, x_train, y_train, cv=cv, scoring='f1_macro',
    train_sizes=np.linspace(0.1, 1., 10), random_state=42)

    # Calculate training and test mean and std
    train_mean = np.mean(train_scores, axis=1)
    train_std = np.std(train_scores, axis=1)
    test_mean = np.mean(test_scores, axis=1)
    test_std = np.std(test_scores, axis=1)

    # Plot the learning curve
    print(f'--Plotting learning curve for {clf}.')
    plotLearningCurve(train_size_abs, train_mean, train_std, test_mean, test_std, curve_title=clf)
    print(f'Test accuracy:\n{test_mean}')
    print(f'Test standard deviation:\n{test_std}')

    return None

def subsample(array1, array2, adjustment):
    # get indices of rows containing 0 and 1
    indices_with_zeros = np.where(array1 == 0)[0]
    indices_with_ones = np.where(array1 == 1)[0]

    # randomly select a subset of rows containing 0
    num_rows_to_select = np.count_nonzero(array1 == 1) * adjustment # Adjust as needed
    rng = np.random.default_rng(0)
    selected_indices_zeros = rng.choice(indices_with_zeros, size=num_rows_to_select, replace=False)

    # include the randomly selected rows
    selected_rows_array1 = np.concatenate((array1[indices_with_ones], array1[selected_indices_zeros]))
    selected_rows_array2 = np.vstack((array2[indices_with_ones], array2[selected_indices_zeros]))

    return selected_rows_array1, selected_rows_array2

def train_model(water_vals, training_data):
    labels = np.where((water_vals != 0) & (water_vals != 2), 1, water_vals)

    water_vals_1d = training_data
    labels_1d = labels.flatten()

    print(f'\nTraining else values: {np.count_nonzero(labels_1d == 0)}')
    print(f'Water labels: {np.count_nonzero(labels_1d == 1)}')
    print(f'Nan labels: {np.count_nonzero(labels_1d == 2)}')

    # water_vals_1d = np.delete(water_vals_1d, np.where(training_data == 2), axis = 0)
    # labels_1d = np.delete(labels_1d, np.where(training_data == 2), axis=0)

    # subsample()

    print(f'\nTrainData Shape: {water_vals_1d.shape}\nLabels Shape: {labels_1d.shape}')

    X_train, X_test, Y_train, Y_test = train_test_split(water_vals_1d, labels_1d,
                                                        test_size=0.3, random_state=40, stratify=labels_1d)

    scaler = MinMaxScaler().fit(water_vals_1d)
    X_train_scaled = scaler.transform(X_train)
    X_test_scaled = scaler.transform(X_test)

    print(f'\nX Train Shape: {X_train_scaled.shape}\nY_train Shape: {Y_train.shape}')
    print(f'Water labels: {np.count_nonzero(Y_train == 1)}\n')

    clf = RandomForestClassifier(random_state=42, n_jobs=4, n_estimators=50)
    # clf = HistGradientBoostingClassifier(random_state=42, max_iter=500, learning_rate=0.1, max_depth=5)
    # clf = MLPClassifier(random_state=42, max_iter=300, hidden_layer_sizes=(30,30,30))
    # clf = svm.SVC(C=1.0, class_weight='balanced', random_state=42)

    # X_learn_scaled = scaler.transform(water_vals_1d)
    # compute_learning_curve(clf, X_learn_scaled, labels_1d)

    print(f'Training {clf}')
    model = clf.fit(X_train_scaled, Y_train)

    # feature_list = ['blue', 'green', 'red', '704', 'nir', 'ndwi', 'pSDBr']

    # feature_importance = pd.Series(model.feature_importances_,index=feature_list).sort_values(ascending=False).round(3)
    # print(f'\nFeature Importance:\n{feature_importance}\n')

    print('--Computing Precision, Recall, F1-Score...')
    classification = classification_report(Y_test, model.predict(X_test_scaled), labels=model.classes_)
    print(f'--Classification Report:\n{classification}')

    return water_vals_1d, labels_1d, model

def save_model(model_dir, model_name, model):
    model_name = os.path.join(model_dir, model_name)
    pickle.dump(model, open(model_name, 'wb')) # save the trained Random Forest model

    print(f'Saved model: {model_name}')

    return None

# %% - prediction

def predict(test_blue, test_green, test_red, test_704, test_nir, shapefile, model):
    # Open the geotiff file
    with rasterio.open(test_green) as green:
        # Read the green band metadata
        prediction_meta = green.meta

        # Open the shapefile
        gdf = gpd.read_file(shapefile)

        # Crop the raster to the shapefile extent
        cropped_green, transform = mask(green, gdf.geometry, crop=True)

    # Open the geotiff file
    with rasterio.open(test_nir) as nir:
        # Open the shapefile
        gdf = gpd.read_file(shapefile)

        # Crop the raster to the shapefile extent
        cropped_nir, transform = mask(nir, gdf.geometry, crop=True)

    # Open the geotiff file
    with rasterio.open(test_704) as b704:
        # Open the shapefile
        gdf = gpd.read_file(shapefile)

        # Crop the raster to the shapefile extent
        cropped_704, transform = mask(b704, gdf.geometry, crop=True)

    # Open the geotiff file
    with rasterio.open(test_blue) as blue:
        # Open the shapefile
        gdf = gpd.read_file(shapefile)

        # Crop the raster to the shapefile extent
        cropped_blue, transform = mask(blue, gdf.geometry, crop=True)

    # Open the geotiff file
    with rasterio.open(test_red) as red:
        # Open the shapefile
        gdf = gpd.read_file(shapefile)

        # Crop the raster to the shapefile extent
        cropped_red, out_transform = mask(red, gdf.geometry, crop=True)

    # compute ndwi
    ndwi = (cropped_green - cropped_nir) / (cropped_green + cropped_nir)

    # compute pSDBr
    pSDBr = np.log(cropped_blue * 1000) / np.log(cropped_red * 1000)
    pSDBg = np.log(cropped_blue * 1000) / np.log(cropped_green * 1000)

    # shape prediction data
    test_data = np.vstack((cropped_blue.flatten(),
                               cropped_green.flatten(),
                               cropped_red.flatten(),
                               cropped_704.flatten(),
                               cropped_nir.flatten(),
                               ndwi.flatten(),
                               # pSDBg.flatten(),
                               pSDBr.flatten())).transpose()

    scaler = MinMaxScaler().fit(test_data)
    # scaler = StandardScaler().fit(test_data)
    scaled = scaler.transform(test_data)
    scaled[np.isnan(scaled)] = 2

    prediction = model.predict(scaled)
    prediction_shape = cropped_red.shape

    print(f'\nPrediction (0) values: {np.count_nonzero(prediction == 0)}')
    print(f'Prediction (1) values: {np.count_nonzero(prediction == 1)}')

    return prediction_shape, prediction, prediction_meta, pSDBr, out_transform

def plot_prediction(prediction, prediction_shape, pSDBr):
    # reshape
    img = np.reshape(prediction, prediction_shape)
    img = np.moveaxis(img, 0, -1)[:,:,0]

    # pSDBr = np.moveaxis(pSDBr, 0, -1)[:,:,0]
    # mask = np.ma.masked_where(img != 1, img)
    img = np.where(img == 2, np.nan, img)

    fig = plt.figure()
    # plt.imshow(pSDBr, cmap='gray')
    # plt.imshow(mask, cmap='hot', alpha=0.7)
    plt.imshow(img, cmap='viridis')
    plt.title('Prediction')
    plt.colorbar()
    plt.show()

    return img.shape

def save_prediction(prediction, pSDBr, prediction_shape, prediction_meta, out_dir, out_transform):

    prediction_name = os.path.join(out_dir, '_prediction.tif')
    pSDBr_name = os.path.join(out_dir, '_pSDBr.tif')
    img = np.reshape(prediction, prediction_shape)
    # img = np.ma.masked_where(img == 1, img)

    # raster meta
    prediction_meta.update({"driver": "GTiff",
                            "height": prediction_shape[1],
                            "width": prediction_shape[2],
                            "count": prediction_shape[0],
                            "nodata": 2,
                            "transform": out_transform})

    # save rasters
    with rasterio.open(prediction_name, "w", **prediction_meta) as dest:
        dest.write(img) # had to specify '1' here for some reason
        dest = None

    print(f'\nSaved prediction to: {prediction_name}')

    # save rasters
    with rasterio.open(pSDBr_name, "w", **prediction_meta) as dest:
        dest.write(pSDBr) # had to specify '1' here for some reason
        dest = None

    print(f'Saved pSDBr to: {pSDBr_name}')

    return None

# %% - main

if __name__ == '__main__':
    out_dir = r"C:\_ZeroShoreline\Out\Testing"
    model_dir = r'C:\_ZeroShoreline\Model'
    model_name = 'RF_BGR7NWpR_StCroix.pkl'

    # in492 = r"C:\_ZeroShoreline\Imagery\Hatteras_20230102\S2A_MSI_2023_01_02_15_53_20_T18SVE_L2R_rhos_492.tif"
    # in560 = r"C:\_ZeroShoreline\Imagery\Hatteras_20230102\NDWI\S2A_MSI_2023_01_02_15_53_20_T18SVE_L2R_rhos_560.tif"
    # in665 = r"C:\_ZeroShoreline\Imagery\Hatteras_20230102\S2A_MSI_2023_01_02_15_53_20_T18SVE_L2R_rhos_665.tif"
    # in704 = r"C:\_ZeroShoreline\Imagery\Hatteras_20230102\S2A_MSI_2023_01_02_15_53_20_T18SVE_L2R_rhos_704.tif"
    # in833 = r"C:\_ZeroShoreline\Imagery\Hatteras_20230102\NDWI\S2A_MSI_2023_01_02_15_53_20_T18SVE_L2R_rhos_833.tif"
    # land = r"C:\_ZeroShoreline\Extent\Hatteras_Inlet_FocusedExtent.shp"

    in492 = r"C:\_ZeroShoreline\Imagery\StCroix_20220129\S2A_MSI_2022_01_29_14_58_03_T20QKE_L2R_rhos_492.tif"
    in560 = r"C:\_ZeroShoreline\Imagery\StCroix_20220129\S2A_MSI_2022_01_29_14_58_03_T20QKE_L2R_rhos_560.tif"
    in665 = r"C:\_ZeroShoreline\Imagery\StCroix_20220129\S2A_MSI_2022_01_29_14_58_03_T20QKE_L2R_rhos_665.tif"
    in704 = r"C:\_ZeroShoreline\Imagery\StCroix_20220129\S2A_MSI_2022_01_29_14_58_03_T20QKE_L2R_rhos_704.tif"
    in833 = r"C:\_ZeroShoreline\Imagery\StCroix_20220129\S2A_MSI_2022_01_29_14_58_03_T20QKE_L2R_rhos_833.tif"
    land = r"C:\_ZeroShoreline\Extent\StCroix_Zero.shp"

    # in492 = r"C:\_ZeroShoreline\Imagery\HalfMoonShoal_20221209\S2A_MSI_2022_12_09_16_16_30_T17RLH_L2R_rhos_492.tif"
    # in560 = r"C:\_ZeroShoreline\Imagery\HalfMoonShoal_20221209\S2A_MSI_2022_12_09_16_16_30_T17RLH_L2R_rhos_560.tif"
    # in665 = r"C:\_ZeroShoreline\Imagery\HalfMoonShoal_20221209\S2A_MSI_2022_12_09_16_16_30_T17RLH_L2R_rhos_665.tif"
    # in704 = r"C:\_ZeroShoreline\Imagery\HalfMoonShoal_20221209\S2A_MSI_2022_12_09_16_16_30_T17RLH_L2R_rhos_704.tif"
    # in833 = r"C:\_ZeroShoreline\Imagery\HalfMoonShoal_20221209\S2A_MSI_2022_12_09_16_16_30_T17RLH_L2R_rhos_833.tif"
    # land = r"C:\_ZeroShoreline\Extent\Halfmoon_Zero.shp"

    # in492 = r"C:\_ZeroShoreline\Imagery\FL_Keys_20230115\S2A_MSI_2023_01_15_16_06_24_T17RNH_L2R_rhos_492.tif"
    # in560 = r"C:\_ZeroShoreline\Imagery\FL_Keys_20230115\S2A_MSI_2023_01_15_16_06_24_T17RNH_L2R_rhos_560.tif"
    # in665 = r"C:\_ZeroShoreline\Imagery\FL_Keys_20230115\S2A_MSI_2023_01_15_16_06_24_T17RNH_L2R_rhos_665.tif"
    # in704 = r"C:\_ZeroShoreline\Imagery\FL_Keys_20230115\S2A_MSI_2023_01_15_16_06_24_T17RNH_L2R_rhos_704.tif"
    # in833 = r"C:\_ZeroShoreline\Imagery\FL_Keys_20230115\S2A_MSI_2023_01_15_16_06_24_T17RNH_L2R_rhos_833.tif"
    # land = r"C:\_ZeroShoreline\Extent\FL_Zero.shp"

    water_vals, training_data = near_land(in492, in560, in665,
                                          in704, in833, land, out_dir, write=False)
    water_vals_1d, labels_1d, model = train_model(water_vals, training_data)
    # save_model(model_dir, model_name, model)

    # in492 = r"C:\_ZeroShoreline\Imagery\Hatteras_20230102\S2A_MSI_2023_01_02_15_53_20_T18SVE_L2R_rhos_492.tif"
    # in560 = r"C:\_ZeroShoreline\Imagery\Hatteras_20230102\NDWI\S2A_MSI_2023_01_02_15_53_20_T18SVE_L2R_rhos_560.tif"
    # in665 = r"C:\_ZeroShoreline\Imagery\Hatteras_20230102\S2A_MSI_2023_01_02_15_53_20_T18SVE_L2R_rhos_665.tif"
    # in704 = r"C:\_ZeroShoreline\Imagery\Hatteras_20230102\S2A_MSI_2023_01_02_15_53_20_T18SVE_L2R_rhos_704.tif"
    # in833 = r"C:\_ZeroShoreline\Imagery\Hatteras_20230102\NDWI\S2A_MSI_2023_01_02_15_53_20_T18SVE_L2R_rhos_833.tif"
    # land = r"C:\_ZeroShoreline\Extent\Hatteras_Inlet_FocusedExtent.shp"

    # in492 = r"C:\_ZeroShoreline\Imagery\StCroix_20220129\S2A_MSI_2022_01_29_14_58_03_T20QKE_L2R_rhos_492.tif"
    # in560 = r"C:\_ZeroShoreline\Imagery\StCroix_20220129\S2A_MSI_2022_01_29_14_58_03_T20QKE_L2R_rhos_560.tif"
    # in665 = r"C:\_ZeroShoreline\Imagery\StCroix_20220129\S2A_MSI_2022_01_29_14_58_03_T20QKE_L2R_rhos_665.tif"
    # in704 = r"C:\_ZeroShoreline\Imagery\StCroix_20220129\S2A_MSI_2022_01_29_14_58_03_T20QKE_L2R_rhos_704.tif"
    # in833 = r"C:\_ZeroShoreline\Imagery\StCroix_20220129\S2A_MSI_2022_01_29_14_58_03_T20QKE_L2R_rhos_833.tif"
    # land = r"C:\_ZeroShoreline\Extent\StCroix_Zero.shp"

    # in492 = r"C:\_ZeroShoreline\Imagery\HalfMoonShoal_20221209\S2A_MSI_2022_12_09_16_16_30_T17RLH_L2R_rhos_492.tif"
    # in560 = r"C:\_ZeroShoreline\Imagery\HalfMoonShoal_20221209\S2A_MSI_2022_12_09_16_16_30_T17RLH_L2R_rhos_560.tif"
    # in665 = r"C:\_ZeroShoreline\Imagery\HalfMoonShoal_20221209\S2A_MSI_2022_12_09_16_16_30_T17RLH_L2R_rhos_665.tif"
    # in704 = r"C:\_ZeroShoreline\Imagery\HalfMoonShoal_20221209\S2A_MSI_2022_12_09_16_16_30_T17RLH_L2R_rhos_704.tif"
    # in833 = r"C:\_ZeroShoreline\Imagery\HalfMoonShoal_20221209\S2A_MSI_2022_12_09_16_16_30_T17RLH_L2R_rhos_833.tif"
    # land = r"C:\_ZeroShoreline\Extent\Halfmoon_Zero.shp"

    # in492 = r"C:\_ZeroShoreline\Imagery\FL_Keys_20230115\S2A_MSI_2023_01_15_16_06_24_T17RNH_L2R_rhos_492.tif"
    # in560 = r"C:\_ZeroShoreline\Imagery\FL_Keys_20230115\S2A_MSI_2023_01_15_16_06_24_T17RNH_L2R_rhos_560.tif"
    # in665 = r"C:\_ZeroShoreline\Imagery\FL_Keys_20230115\S2A_MSI_2023_01_15_16_06_24_T17RNH_L2R_rhos_665.tif"
    # in704 = r"C:\_ZeroShoreline\Imagery\FL_Keys_20230115\S2A_MSI_2023_01_15_16_06_24_T17RNH_L2R_rhos_704.tif"
    # in833 = r"C:\_ZeroShoreline\Imagery\FL_Keys_20230115\S2A_MSI_2023_01_15_16_06_24_T17RNH_L2R_rhos_833.tif"
    # land = r"C:\_ZeroShoreline\Extent\FL_Zero.shp"

    prediction_shape, prediction, prediction_meta, pSDBr, out_transform = predict(in492, in560, in665,
                                          in704, in833, land, model)
    img_shape = plot_prediction(prediction, prediction_shape, pSDBr)
    # save_prediction(prediction, pSDBr, prediction_shape, prediction_meta, out_dir, out_transform)


from __future__ import print_function
import datetime
from tzlocal import get_localzone
import pickle
import os.path
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request

# If modifying these scopes, delete the file token.pickle.
SCOPES = ['https://www.googleapis.com/auth/calendar.readonly']

def get_creds():

    creds = None
    # The file token.pickle stores the user's access and refresh tokens, and is
    # created automatically when the authorization flow completes for the first
    # time.
    if os.path.exists('token.pickle'):
        with open('token.pickle', 'rb') as token:
            creds = pickle.load(token)
    # If there are no (valid) credentials available, let the user log in.
    if not creds or not creds.valid:
        if creds and creds.expired and creds.refresh_token:
            creds.refresh(Request())
        else:
            flow = InstalledAppFlow.from_client_secrets_file(
                'credentials.json', SCOPES)
            creds = flow.run_local_server(port=0)
        # Save the credentials for the next run
        with open('token.pickle', 'wb') as token:
            pickle.dump(creds, token)

    return creds

def get_events(creds):

    service = build('calendar', 'v3', credentials=creds)

    #get today's date
    today = datetime.date.today()
    #tmrw = (today + datetime.timedelta(1))

    #hack to get local timezone
    '''
    local_t = datetime.datetime.fromtimestamp(0)
    utc_t = datetime.datetime.utcfromtimestamp(0)
    local_tz = datetime.timezone(local_t - utc_t)
    '''

    local_tz = get_localzone()

    #turn today's date into a datetime set at midnight in local timezone
    today_dt = datetime.datetime.combine(today, datetime.time(0, tzinfo=local_tz))
    #tmrw_dt = today_dt + datetime.timedelta(1)
    day_after_tmrw_dt = today_dt + datetime.timedelta(2)

    events_result = service.events().list(calendarId='primary', timeMin=today_dt.isoformat(), timeMax=day_after_tmrw_dt.isoformat(), maxResults=5, singleEvents=True, orderBy='startTime').execute()
    events = events_result.get('items', [])

    events_list = []
    if not events:
        pass
    for event in events:
        #if(event['summary'] == 'Work'):
        start = event['start']['dateTime']
        end = event['end']['dateTime']
        events_list.append((event['summary'], start, end))
            #print(event['summary'], start, end)

    return events_list

'''
    print('Getting Tomorrow\'s Work Schedule')
    events_result = service.events().list(calendarId='primary', timeMin=tmrw_dt.isoformat(), timeMax=day_after_tmrw_dt.isoformat(), maxResults=5, singleEvents=True, orderBy='startTime').execute()
    events = events_result.get('items', [])

    if not events:
        print('No Work Tomorrow!')
    for event in events:
        if(event['summary'] == 'Work'):
            start = event['start']['dateTime']
            end = event['end']['dateTime']
            events_list.append((event['summary'], start, end))
            print(event['summary'], start, end)
'''

if __name__ == '__main__':
    creds = get_creds()
    print(get_events(creds))


from pico2d import *
import time

image = None
end_result = False
closing = False
change_state = None
final_score = None
strings = []
index = 0
last_time = 0
last_blink = 0
score_font = None
blink = False

def init():
    global image, end_result, closing, change_state, score_font, final_score, strings, index, last_time, blink, last_blink
    score_font = load_font("../res/score.ttf", 30)
    end_result = False
    closing = False
    change_state = None
    index = 0
    last_time = 0
    last_blink = 0
    final_score = 0
    strings = []
    image = load_image('../res/back.png')
    blink = False

def update():
    global index, last_time, blink, last_blink

    if index < 5:
        now = time.time()
        if last_time+0.5 <= now:
            index += 1
            last_time = time.time()
    elif index == 5:
        now2 = time.time()
        if last_blink+0.1 <= now2:
            if blink is True:
                blink = False
            else:
                blink = True
            last_blink = time.time()

def draw():
    global index, image, score_font, strings
    image.draw(300, 400)
    for i in range(index):
        score_font.draw(50, 700 - i * 100, strings[i], (255, 255, 255))
    if index == 5 and blink is True:
        score_font.draw(50, 200, "Press Space Key to Return Title", (255, 255, 255))

def handle_event():
    global end_result, closing, change_state, index
    evt = get_events()
    for e in evt:
        if e.type == SDL_QUIT:
            end_result = True
            closing = True
        elif (e.type, e.key) == (SDL_KEYDOWN, SDLK_ESCAPE):
            if index < 5:
                index = 5
            else:
                change_state = 0
                end_result = True
        elif (e.type, e.key) == (SDL_KEYDOWN, SDLK_SPACE):
            if index < 5:
                index = 5
            else:
                change_state = 0
                end_result = True


"""Delete disabled column

Revision ID: de3bdf5a9ff8
Revises: 2b7fcebfede1
Create Date: 2021-06-20 09:35:40.600021

"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import mysql

# revision identifiers, used by Alembic.
revision = 'de3bdf5a9ff8'
down_revision = '2b7fcebfede1'
branch_labels = None
depends_on = None

def upgrade() -> None:
    # ### commands auto generated by Alembic - please adjust! ###
    op.drop_index('ix_users_disabled', table_name='users')
    op.drop_index('ix_users_email', table_name='users')
    op.create_index(op.f('ix_users_email'), 'users', ['email'], unique=True)
    op.drop_column('users', 'disabled')
    # ### end Alembic commands ###

def downgrade() -> None:
    # ### commands auto generated by Alembic - please adjust! ###
    op.add_column('users', sa.Column('disabled', mysql.TINYINT(
        display_width=1), autoincrement=False, nullable=False))
    op.drop_index(op.f('ix_users_email'), table_name='users')
    op.create_index('ix_users_email', 'users', ['email'], unique=False)
    op.create_index('ix_users_disabled', 'users', ['disabled'], unique=False)
    # ### end Alembic commands ###


from django.shortcuts import render
from django.http import HttpResponse
from django.shortcuts import get_object_or_404
from .models import UserInfo
from .models import battledata
from .forms import UserForm,dataForm
# ユーザ情報を辞書に格納して、users.htmlに返す
def showUsers(request):
    usefinfo = UserInfo.objects.all()
    context = {
        'msg': '現在の利用状況',
        'userinfo': usefinfo,
        'count':usefinfo.count,
    }

    return render(request, 'form/users.html',context)

def showDetail(request,user):
    #URLのidをもとに、ユーザ情報を抽出
    userinfoDetail = get_object_or_404(UserInfo,userName=user)

    context = {
        'userinfoDetail':userinfoDetail,
    }
    #detail.htmlへデータを渡す
    return render(request, 'form/detail.html',context)

def showCreateUserForm(request):
    #フォームを変数にセット
    form = UserForm()

    context = {
        'userForm':form,
    }

    #detail.htmlへデータを渡す
    return render(request, 'form/create.html',context)

def addUsers(request):
    if request.method=='POST':
        userForm = UserForm(request.POST)
        if(userForm.is_valid()):
            userForm.save()
    userinfo = UserInfo.objects.all()
    context = {
        'msg': '現在の利用状況',
        'userinfo': userinfo,
        'count':userinfo.count,
    }
    #user.htmlへデータを渡す
    return render(request, 'form/users.html',context)

def showEditUserForm(request,user):

    #idをもとにユーザ情報を取得
    userinfo = get_object_or_404(UserInfo,userName=user)
    #フォームをオブジェクトを作成
    userForm = UserForm(instance=userinfo)
    #ユーザ情報をフォームに格納
    context = {
        'userinfo':userinfo,
        'userForm':userForm,
    }

    #user.htmlへデータを渡す
    return render(request, 'form/edit.html',context)

def updateUser(request,user):
    if request.method=='POST':
        userInfo = get_object_or_404(UserInfo,userName=user)
        userForm = UserForm(request.POST,instance=userInfo)
        if userForm.is_valid():
            userForm.save()

    usefinfo = UserInfo.objects.all()
    context = {
        'msg': '現在の利用状況',
        'userinfo': usefinfo,
        'count':usefinfo.count,
    }
    #detail.htmlへデータを渡す
    return render(request, 'form/users.html',context)

def syouhaiForm(request):
    battleData = battledata.objects.all()
    context = {
        'battledata' : battleData,
    }
    return render(request, 'form/syouhaikai.html',context)

def syouriData(request,Id):
    if request.method == 'POST':
        Battledata = get_object_or_404(battledata,battleID=Id)
        if Battledata.winner != "none":
            context = {
                'battledata' : Battledata,
                }
            return render(request,'form/error.html',context)
        elif 'button1' in request.POST:
            Battledata.winner = Battledata.userID1
            Battledata.save()
            index="勝利"
        elif 'button2' in request.POST:
            Battledata.winner = Battledata.userID2
            Battledata.save()
            index="敗北"

    context = {
        'battledata' : Battledata,
        'index' : index,
    }
    return render(request, 'form/syouhaikekka.html',context)


"""djangodemo03 URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/1.11/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  url(r'^$', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  url(r'^$', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.conf.urls import url, include
    2. Add a URL to urlpatterns:  url(r'^blog/', include('blog.urls'))
"""
from django.conf.urls import url

from index import views

urlpatterns = [
    # url(r'^index/', views.index),
    url(r'^01-add-author/$', views.add_author),
    url(r'^02-add-book/$', views.add_book),
    url(r'^03-add-publisher/$', views.add_publisher),
    url(r'^02-query/$', views.query),
    url(r'^03-queryall/$', views.queryall),
    url(r'^04-filter/$', views.filter_views),
    url(r'^05-lookup/$', views.filed_lookup),
    url(r'^06-exclude/$', views.exclud),
    url(r'^05-update/(\d+)/$', views.update, name='upgrade'),
    url(r'^06-aggregate/$', views.aggregate),
    url(r'^07-annotate/$', views.annotate),
    url(r'^07-annotate_book/$', views.annotate_book),
    url(r'^08-update/$', views.update08),
    url(r'^09-delete/(\d+)/$', views.delete),
    url(r'^10-oto/$', views.oto_views),
    url(r'^10-find_oto/$', views.oto_find),
    url(r'^10-one_to_many/$', views.onetomany),
    url(r'^11-find_otm/$', views.find_otm),
    url(r'^12-mtm/$', views.add_mtm),
    url(r'^13-find_mtm/$', views.find_mtm),
    url(r'^13-objects/$', views.object_views),
    url(r'^13-name_like/$', views.name_like_views),
    url(r'^13-book_date/$', views.book_date_views),
]


'''
实现从一个文件夹下随机抽取一定数量的图片并移动到另一个文件夹
'''

import os
import random
import shutil

def moveFile(fileDir):
    pathDir = os.listdir(fileDir)  # 取图片的原始路径
    filenumber = len(pathDir)
    rate = 0.2  # 自定义抽取图片的比例，比方说100张抽10张，那就是0.1
    picknumber = int(filenumber * rate)  # 按照rate比例从文件夹中取一定数量图片
    sample = random.sample(pathDir, picknumber)  # 随机选取picknumber数量的样本图片
    # print(sample)
    for name in sample:
        shutil.move(fileDir + name, tarDir + name)
    return

if __name__ == '__main__':
    # 源图片文件夹路径
    fileDir = "C:\\Users\\huili\\Desktop\\a1\\"
    # 移动到新的文件夹路径
    tarDir = "C:\\Users\\huili\\Desktop\\a2\\"
    moveFile(fileDir)


#!/usr/bin/env python3

from time import sleep
from datetime import datetime
from tasks import primeira_task, segunda_task

q1 = 'filarq30_1'
q2 = 'filarq30_2'

s = 'INFORMACAO '

if __name__ == '__main__':
    while True:
        try:
            print(f'*** {datetime.now()}')
            _1 = primeira_task.apply_async(args=[s], queue=q1)
            _1 = _1.get()
            _2 = segunda_task.apply_async(args=[_1], queue=q2)
            sleep(3)
        except KeyboardInterrupt:
            break