"""
Upsampling + Conv + Conv
"""
from torch.autograd import Variable
import torch
import torch.nn as nn
import numpy as np

def get_activation(activation):
    if activation == 'leakyrelu':
        return nn.LeakyReLU(0.2, inplace=True)
    elif activation == 'relu':
        return nn.ReLU(True)
    elif activation == 'elu':
        return nn.ELU(inplace=True)
    elif activation == 'selu':
        return nn.SELU(inplace=True)
    elif activation == 'sigmoid':
        return nn.Sigmoid()
    elif activation == 'tanh':
        return nn.Tanh()
    else:
        raise ValueError(f'activation `{activation}` not supported')

def get_pooling(pooling):
    if pooling == 'max':
        return nn.MaxPool2d(2, 2)
    elif pooling == 'avg':
        return nn.AvgPool2d(2, 2)
    else:
        raise ValueError(f'pooling `{pooling}` not supported')

def get_normalize(normalize, nf):
    if normalize == 'batch':
        return nn.BatchNorm2d(nf)
    elif normalize == 'instance':
        return nn.InstanceNorm2d(nf)
    else:
        raise ValueError('normalize layer not supported')

class DOWNSAMPLE_D(nn.Module):
    """
    downsample: mean | max
    activation: leakyrelu | relu | elu | selu | sigmoid | tanh
    normalize = 'none | batch | instance'
    outactivation: none | tanh | sigmoid | elu
    """

    def __init__(self,
                 imsize,
                 imchannel,
                 netwidth,
                 extraconv=1,
                 pooling='avg',
                 activation='leakyrelu',
                 normalize='none',
                 outactivation='none',
                 outdim=1,
                 ngpu=1):
        super().__init__()
        #region yapf: disable
        self.imsize         = imsize
        self.imchannel      = imchannel
        self.netwidth       = netwidth
        self.extraconv      = extraconv
        self.activation     = activation
        self.normalize      = normalize
        self.outactivation  = outactivation
        self.outdim         = outdim
        self.bias           = True if normalize == 'none' else False
        self.ngpu           = ngpu
        #region yapf: enable
        assert imsize % 4 == 0, "imsize has to be a multiple of 4"

        main = nn.Sequential()

        insize, inchannel, outchannel = imsize, imchannel, netwidth

        while insize > 4:
            main.add_module(f'pyramid.{inchannel}-{outchannel}.conv',
                            nn.Conv2d(
                                inchannel, outchannel, 3, 1, 1,
                                bias=self.bias))

            if normalize != 'none':
                main.add_module(
                    f'pyramid.{inchannel}-{outchannel}.{normalize}norm',
                    get_normalize(normalize, outchannel))

            main.add_module(f'pyramid.{inchannel}-{outchannel}.{activation}',
                            get_activation(activation))

            # extra convs
            for t in range(extraconv):
                main.add_module(f'pyramid.{outchannel}.conv{t}.conv',
                                nn.Conv2d(
                                    outchannel,
                                    outchannel,
                                    3,
                                    1,
                                    1,
                                    bias=self.bias))

                if normalize != 'none':
                    main.add_module(
                        f'pyramid.{outchannel}.conv{t}.{normalize}norm',
                        get_normalize(normalize, outchannel))

                main.add_module(f'pyramid.{outchannel}.conv{t}.{activation}',
                                get_activation(activation))

            main.add_module(f'pyramid.{outchannel}.pool', get_pooling(pooling))

            insize //= 2
            inchannel = outchannel
            outchannel *= 2

        assert insize == 4

        # state size. bs x outchannel x 4 x 4
        main.add_module(f'final.{inchannel}-{outdim}.conv',
                        nn.Conv2d(inchannel, outdim, 4, 1, 0, bias=True))

        if outactivation != 'none':
            main.add_module(f'final.{outchannel}-{outdim}.{outactivation}',
                            get_activation(outactivation))
        self.main = main

    def forward(self, input):
        if self.ngpu > 1:
            output = nn.parallel.data_parallel(self.main, input,
                                               range(self.ngpu))
        else:
            output = self.main(input)

        output = output.view(output.size(0), self.outdim)

        return output

class UPSAMPLE_G(nn.Module):
    """
    upsample: nearest | bilinear
    activation: leakyrelu | relu | elu | selu | sigmoid | tanh
    normalize = 'none | batch | instance'
    """

    def __init__(self,
                 imsize,
                 imchannel,
                 nz,
                 width,
                 extraconv=0,
                 upsampling='nearest',
                 activation='leakyrelu',
                 normalize='batch',
                 ngpu=1):
        super().__init__()
        #region yapf: disable
        self.imsize         = imsize
        self.imchannel      = imchannel
        self.nz             = nz
        self.width          = width
        self.extraconv      = extraconv
        self.activation     = activation
        self.normalize      = normalize
        self.bias           = True if normalize == 'none' else False
        self.ngpu           = ngpu
        #region yapf: enable
        assert imsize % 4 == 0, "imsize has to be a multiple of 4"

        inchannel, insize = width, 8
        while insize < imsize:
            inchannel = inchannel * 2
            insize = insize * 2

        main = nn.Sequential()
        # input is Z (bs x nz x 1 x 1), going into a convolution
        main.add_module(f'initial.{nz}-{inchannel}.convt',
                        nn.ConvTranspose2d(
                            nz, inchannel, 4, 1, 0, bias=self.bias))

        if normalize != 'none':
            main.add_module(f'initial.{inchannel}.{normalize}norm',
                            get_normalize(normalize, inchannel))

        main.add_module(f'initial.{inchannel}.{activation}',
                        get_activation(activation))

        insize, outchannel = 4, inchannel // 2
        while insize < imsize:
            main.add_module(f'pyramid.{inchannel}.upsample',
                            nn.Upsample(scale_factor=2, mode=upsampling))

            # extra conv
            for t in range(extraconv):
                main.add_module(f'pyramid.{inchannel}.conv{t}.conv',
                                nn.Conv2d(
                                    inchannel,
                                    inchannel,
                                    3,
                                    1,
                                    1,
                                    bias=self.bias))

                if normalize != 'none':
                    main.add_module(
                        f'pyramid.{inchannel}.conv{t}.{normalize}norm',
                        get_normalize(normalize, inchannel))

                main.add_module(f'pyramid.{inchannel}.conv{t}.{activation}',
                                get_activation(activation))

            main.add_module(f'pyramid.{inchannel}-{outchannel}.conv',
                            nn.Conv2d(
                                inchannel, outchannel, 3, 1, 1,
                                bias=self.bias))
            if normalize != 'none':
                main.add_module(
                    f'pyramid.{inchannel}-{outchannel}.{normalize}norm',
                    get_normalize(normalize, outchannel))

            main.add_module(f'pyramid.{inchannel}-{outchannel}.{activation}',
                            get_activation(activation))

            insize = insize * 2
            inchannel //= 2
            outchannel = inchannel // 2

        assert insize == imsize

        main.add_module(f'pyramid.{inchannel}-{imchannel}.conv',
                        nn.Conv2d(inchannel, imchannel, 3, 1, 1, bias=True))

        main.add_module(f'final.{imchannel}.tanh'.format(), nn.Tanh())
        self.main = main

    def forward(self, input):
        if input.ndimension() == 2:
            input = input.view(input.size(0), input.size(1), 1, 1)
        assert input.size() == (input.size(0), self.nz, 1, 1)

        if self.ngpu > 1:
            output = nn.parallel.data_parallel(self.main, input,
                                               range(self.ngpu))
        else:
            output = self.main(input)
        return output


from flask import render_template,redirect,url_for,request,abort,flash
from . import main
from .forms import UpdateProfile,BlogForm,CommentForm,SubscribeForm
from .. import db,photos
from ..models import User,Blog,Comment,Subscriber
from flask_login import login_required,current_user
from .. import db,photos
import json
from .requests import get_quotes

@main.route('/')
def index():
    sports = Blog.get_blogs('')
    travel = Blog.get_blogs('Travel-Blog')
    fitness = Blog.get_blogs('Fitness-Blog')
    fashion = Blog.get_blogs('Fashion-Blog')
    food = Blog.get_blogs('Food-Blog')
    politics = Blog.get_blogs('Political-Blog')
    quote = get_quotes()
    return render_template('index.html', sports = sports, travel = travel, fitness = fitness, fashion = fashion, food = food, quote=quote )

@main.route('/user/<uname>')
def profile(uname):
    user = User.query.filter_by(username = uname).first()

    if user is None:
        abort(404)

    return render_template("profile/profile.html", user = user)

@main.route('/user/<uname>/update',methods = ['GET','POST'])
@login_required
def update_profile(uname):
    user = User.query.filter_by(username = uname).first()
    if user is None:
        abort(404)

    form = UpdateProfile()

    if form.validate_on_submit():
        user.bio = form.bio.data

        db.session.add(user)
        db.session.commit()

        return redirect(url_for('.profile',uname=user.username))

    return render_template('profile/update.html',form =form)

@main.route('/user/<uname>/update/pic',methods= ['POST'])
@login_required
def update_pic(uname):
    user = User.query.filter_by(username = uname).first()
    if 'photo' in request.files:
        filename = photos.save(request.files['photo'])
        path = f'photos/{filename}'
        user.profile_pic_path = path
        db.session.commit()
    return redirect(url_for('main.profile',uname=uname))

@main.route('/new-blog', methods = ['GET','POST'])
@login_required
def new_blog():
    blog_form = BlogForm()
    if blog_form.validate_on_submit():
        title = blog_form.title.data
        blog = blog_form.blog_body.data
        category = blog_form.blog_category.data

        new_blog = Blog(title = title, content = blog, category = category,user = current_user)
        new_blog.save_blog()

        return redirect(url_for('main.index'))

    title = 'New Blog'
    return render_template('new_blog.html', title = title, blog_form = blog_form)

@main.route('/blogs/sports')
def sports():
    blogs = Blog.get_blogs('Sports-Blog')

    return render_template('sports.html',blogs = blogs)

@main.route('/blogs/travel')
def travel():
    blogs = Blog.get_blogs('Travel-Blog')

    return render_template('travel.html',blogs = blogs)

@main.route('/blogs/fitness')
def fitness():
    blogs = Blog.get_blogs('Fitness-Blog')

    return render_template('fitness.html',blogs = blogs)

@main.route('/blogs/fashion')
def fashion():
    blogs = Blog.get_blogs('Fashion-Blog')

    return render_template('fashion.html',blogs = blogs)

@main.route('/blogs/food')
def food():
    blogs = Blog.get_blogs('Food-Blog')

    return render_template('food.html',blogs = blogs)

@main.route('/blogs/politics')
def politics():
    blogs = Blog.get_blogs('Political-Blog')

    return render_template('politics.html',blogs = blogs)

@main.route('/blog/<int:id>', methods = ["GET","POST"])
def blog(id):
    blog = Blog.get_blog(id=id)
    posted_date = blog.posted.strftime('%b %d, %Y')

    comment_form = CommentForm()
    if comment_form.validate_on_submit():

        name = comment_form.name.data
        comment = comment_form.comment.data

        new_comment = Comment(name = name, comment = comment, blog = blog)
        new_comment.save_comment()

        return redirect(url_for('main.blog',id=id))

    comments = Comment.get_comments(blog)
    return render_template('get_blog.html', blog = blog, comment_form = comment_form, comments = comments, date = posted_date)

@main.route('/blog/<int:id>/update', methods = ['GET','POST'])
@login_required
def update_blog(id):
    blog = Blog.get_blog(id)
    form = BlogForm()
    if form.validate_on_submit():
        blog.title = form.title.data
        blog.content = form.blog_body.data
        blog.category = form.blog_category.data
        db.session.commit()
        return redirect(url_for('main.blog', id = id))
    elif request.method == 'GET':
        form.title.data = blog.title
        form.blog_body.data = blog.content
        form.blog_category.data = blog.category
    return render_template('new_blog.html', blog_form = form, id=id)

@main.route('/blog/delete/<int:id>', methods = ['GET', 'POST'])
@login_required
def delete_blog(id):
    blog = Blog.get_blog(id)
    db.session.delete(blog)
    db.session.commit()

    flash('Blog has been deleted')
    return redirect(url_for('main.index'))

    return render_template('get_blog.html', id=id, blog = blog)

@main.route('/blog/comment/delete/<int:id>', methods = ['GET', 'POST'])
@login_required
def delete_comment(id):
    comment = Comment.query.filter_by(id=id).first()
    blog_id = comment.blog
    Comment.delete_comment(id)

    flash('Comment has been deleted')
    return redirect(url_for('main.blog',id=blog_id))

@main.route('/blogs/latest', methods = ['GET','POST'])
def latest_blogs():
    blogs = Blog.query.order_by(Blog.posted.desc()).all()

    return render_template('latest.html',blogs = blogs)

@main.route('/subscription',methods=['GET','POST'])
def subscription():
    subscription_form = SubscribeForm()

    if subscription_form.validate_on_submit():
        new_subscriber = Subscriber(subscriber_name=subscription_form.subscriber_name.data,subscriber_email=subscription_form.subscriber_email.data)

        db.session.add(new_subscriber)
        db.session.commit()

        return redirect(url_for('main.index'))

    return render_template('subscription.html',subscription_form = subscription_form)


import requests
import json
from collections import abc
from dateutil.tz import tzoffset
from datetime import datetime

def get_botanical_garden_events(start_date, end_date):
    '''
    Get events data from the National Park Aquatic Gardens EventCalendarService API

    Parameters:
        start_date (str): a date string of the form YYYY-MM-DD. Events will be inclusive of this start date.
        end_data (str): a date string of the form YYYY-MM-DD. Events will be inclusive of this end date.

    Returns:
        data (list): a list of dicts representing each event. Could convert dicts to json.
    '''
    url = f'https://www.nps.gov/common/components/nps/eventcalendar/EventCalendarService.cfc'+\
          f'?method=getEvents&parkCode=keaq&dateStart={start_date}&dateEnd={end_date}'+\
          f'&expandRecurring=true'
    r = requests.get(url)
    r_json = r.json()
    data = r_json['data']

    return data

def recursive_items(dictionary):
    '''
    Recursive function to get all key:value pairs in a nested dictionary of unknown depth
    '''

    for key, value in dictionary.items():
        if type(value) is dict:
            yield from recursive_items(value)
        else:
            yield (key, value)

def filter_data(data):
    '''
    Iterate through all key:value pairs in the data array, returning those that match our schema
    '''

    keys = ['longitude', 'latitude', 'dateStart', 'description', 'images',
            'id', 'dateEnd', 'isRegResRequired', 'infoURL',
            'title','regResInfo']
    key_map = {'title':'name',
               'dateStart':'startDate',
               'dateEnd':'endDate',
               'latitude':'geo.lat',
               'longitude':'geo.lon',
               'infoURL':'url',
               'images':'image',
               'description':'description',
               'isRegResRequired':'registrationRequired',
               'regResInfo':'regResInfo',
               'id':'id'
                }
    filtered_data = []
    for d in data:
        filtered = {k:None for k in key_map.values()}
        for key, _ in recursive_items(d):
            if key in keys:
                mapped_key = key_map[key]
                filtered[mapped_key] = d[key] if mapped_key != 'registrationRequired' else int(d[key])
        filtered_data.append(filtered)

    return filtered_data

if __name__ == '__main__':
    data = get_botanical_garden_events('2018-01-01','2018-12-31')
    filtered_data = filter_data(data)
    print(len(filtered_data))


import random
import numpy as np

class DefaultRandomGenerator:

    def rand(self, size=None):
        if size is None:
            return random.random()
        else:
            n = size[0]
            m = size[1]
            val = np.zeros((n, m))
            for i in range(n):
                for j in range(m):
                    val[i, j] = random.random()

            return val

    def perm(self, length, n=1):
        perms = []
        for _ in range(n):
            perm = list(range(length))
            random.shuffle(perm)
            perms.append(perm)
        return perms

    def seed(self, x):
        random.seed(x)

    def randint(self, low, high, size=None):
        if low >= high:
            return low
        else:
            res = low + (self.rand(size) * (high - low))
            if res > high:
                res = high
        return int(res)


from __future__ import print_function, division
from skimage import morphology
from skimage import measure
from sklearn.cluster import KMeans
from skimage.transform import resize
import SimpleITK as sitk
import numpy as np
import os
from glob import glob
from tqdm import tqdm
import pandas as pd
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from mpl_toolkits.mplot3d.art3d import Poly3DCollection
import scipy.misc
from Heatmap import create_heatmap
from CropSamples import crop_samples
from Respace import respace
import pickle

def show_3d_img(img):
    for z in range(img.shape[0]):
        plt.imshow(img[z], cmap='gray')
        plt.show()
        #scipy.misc.imsave('images/{}.jpg'.format(z), img[z])

def plot_3d(image, threshold=0.5):

    # Position the scan upright,
    # so the head of the patient would be at the top facing the camera
    p = image.transpose(2,1,0)

    verts, faces = measure.marching_cubes(p, threshold)

    fig = plt.figure(figsize=(10, 10))
    ax = Axes3D(fig)
    #ax = fig.add_subplot(111, projection='3d')

    # Fancy indexing: `verts[faces]` to generate a collection of triangles
    mesh = Poly3DCollection(verts[faces], alpha=0.70)
    face_color = [0.45, 0.45, 0.75]
    mesh.set_facecolor(face_color)
    ax.add_collection3d(mesh)

    ax.set_xlim(0, p.shape[0])
    ax.set_ylim(0, p.shape[1])
    ax.set_zlim(0, p.shape[2])

    plt.show()

# Get rows in data frame associated with each file
def get_filename(fileList, case):
    for f in fileList:
        if case in f:
            return(f)

# Takes a pandas data frame read from the annotations csv file append
# reeturns a list of dictionary containing the nodules and converted coordinates
def change_nodule_coordinate_spacing(nodulesDF, origin, sourceSpacing, targetSpacing):
    nodules=[]
    targetSpacing = [targetSpacing[1], targetSpacing[2], targetSpacing[0]]
    for noduleIndex, row in nodulesDF.iterrows():
        worldCoord = np.array([row["coordX"], row["coordY"], row["coordZ"]])
        voxelCoord = np.rint(np.absolute(worldCoord - origin) / targetSpacing)
        voxelCoord = np.array([int(voxelCoord[2]), int(voxelCoord[0]), int(voxelCoord[1])])

        nodule= {
        'seriesuid' : row['seriesuid'],
        'coords' : voxelCoord,
        }
        #print(row['seriesuid'])
        if 'diameter_mm' in row.index:
            nodule['diameter_mm'] = row['diameter_mm']
        nodules.append(nodule)
    return nodules
def read_image(imageFile):
    # Read the scan
    itkImage = sitk.ReadImage(imageFile)
    npImage = sitk.GetArrayFromImage(itkImage).transpose(0,2,1)
    npZ, height, width = npImage.shape
    npOrigin = np.array(itkImage.GetOrigin())
    npSpacing = itkImage.GetSpacing()
    npSpacing = np.array([npSpacing[2], npSpacing[0], npSpacing[1]])
    return npImage, npSpacing, npOrigin

def normalize_values(npImage):
    maxHU = 400.0
    minHU = -1000.0
    npImage = (npImage-minHU) / (maxHU - minHU)
    npImage[npImage>1] = 1
    npImage[npImage<0] = 0
    npImage = npImage*2 -1
    return npImage

# Get list of image files
inputPath = "/media/amos/My Passport/Data/luna/"
outputPath = "/media/amos/My Passport/Data/luna/nodules_dataset"
annotationPath = "datasets/nodules/annotations/"
targetSpacing = np.array([1.25, 1, 1])

# For each subset
for i in range(0,9):
    print("subset" + str(i))
    subsetPath = inputPath + "subset" + str(i) + "/"
    fileList = glob(subsetPath + "*.mhd")

    # Get locations of the nodules
    nodulesDF = pd.read_csv(annotationPath + "annotations.csv")
    nodulesDF["file"] = nodulesDF["seriesuid"].map(lambda fileName: get_filename(fileList, fileName))
    nodulesDF = nodulesDF.dropna()

    # Get locations of candidates
    candidatesDF = pd.read_csv(annotationPath + "candidates.csv")
    candidatesDF["file"] = candidatesDF["seriesuid"].map(lambda fileName: get_filename(fileList, fileName))
    candidatesDF = candidatesDF.dropna()

    samples = []
    # For each image file
    for fileCount, imageFile in enumerate(tqdm(fileList)):
        #if fileCount < 52 : continue
        suid = imageFile.split("/")[-1][:-4]

        print("reading image")
        npImage, npSpacing, npOrigin = read_image(imageFile)

        # Get all nodules and candidates present
        # z x y
        print("resizing nodule coords")
        nodules = change_nodule_coordinate_spacing(nodulesDF[nodulesDF["file"] == imageFile], npOrigin, npSpacing, targetSpacing)
        #print("{} nodules in {}".format(len(nodules), suid))
        #candidates = change_nodule_coordinate_spacing(candidatesDF[candidatesDF["file"] == imageFile], npOrigin, npSpacing, targetSpacing)

        # Rescale the scan
        print("respacing image")
        scan = respace(npImage, npSpacing, targetSpacing)
        print("renormalizing")
        scan = normalize_values(scan)

        # Generate heatmap
        print("generating heatmap")
        heatmap_real = create_heatmap(nodules, scan.shape, candidates=False)
        #heatmap_candidates = create_heatmap(candidates, scan.shape, candidates=True)
        #plot_3d(heatmap_candidates)

        # Generate sample boxes to be cropped at test time
        print("generating crops")
        samples.append(crop_samples(nodules, scan.shape, np.array([64, 96, 96]), 20, 0.8))
        #coords = nodules[0]["coords"]
        #show_3d_img(scan[coords[0]-10:coords[0]+10, coords[1]-50:coords[1]+50,coords[2]-50:coords[2]+50])
        #for sample in samples[suid]:
        #    coords = sample['bounds']
        #    show_3d_img(heatmap_real[coords[0]+50:coords[0]+51, coords[1]:coords[4], coords[2]:coords[5]])
        #    show_3d_img(scan[coords[0]+50:coords[0]+51, coords[1]:coords[4], coords[2]:coords[5]])
        #samples = samples + crop_samples(candidates, scan.shape, np.array([100, 100, 125]), 10, 0.8, candidates="candidates")

        print("saving")
        #save the mask and scan as compressed npz files
        if not os.path.exists(os.path.join(outputPath, "heatmaps", "real")):
            os.makedirs(os.path.join(outputPath, "heatmaps", "real"))
        if not os.path.exists(os.path.join(outputPath, "heatmaps", "candidates")):
            os.makedirs(os.path.join(outputPath, "heatmaps", "candidates"))
        if not os.path.exists(os.path.join(outputPath, "scans_processed")):
            os.makedirs(os.path.join(outputPath, "scans_processed"))
        np.savez_compressed(os.path.join(outputPath, "heatmaps", "real", "%s" % (suid)), a = heatmap_real)
        #np.savez_compressed(os.path.join(outputPath, "heatmaps", "candidates", "%s" % (nodules[0]['seriesuid'])), a = heatmap_candidates)
        np.savez_compressed(os.path.join(outputPath, "scans_processed", "%s" % (suid)), a = scan)

        #save crop boxes
        f = open(os.path.join(outputPath, "crops.pkl"), 'wb')
        print(samples)
        pickle.dump(samples, f)
        f.close()


import pygame
from sprites import *
from config import *
import sys

class Game:
    def __init__(self):
        pygame.init()
        self.screen = pygame.display.set_mode((WIN_WIDTH, WIN_HEIGHT), pygame.RESIZABLE)
        self.clock = pygame.time.Clock()
        self.running = True
        self.font = pygame.font.Font(None, 50)

        self.intro_background = pygame.image.load('menu.jpg')
        self.go_background = pygame.image.load('Gameover.jpg')

    def createTilemap(self):
        for i, row in enumerate(tilemap):
            for j, column in enumerate(row):
                if column == 'A':
                    Ground(self, j, i)
                if column == 'B':
                    Block(self, j, i)
                if column == 'E':
                    Enemy(self, j, i)
                if column == "P":
                    Player(self, j, i)

    def new(self):
        # a new game starts
        self.playing = True

        self.all_sprites = pygame.sprite.LayeredUpdates()
        self.blocks = pygame.sprite.LayeredUpdates()
        self.enemies = pygame.sprite.LayeredUpdates()
        self.attacks = pygame.sprite.LayeredUpdates()

        self.createTilemap()

    def events(self):
        # game loop events
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                self.playing = False
                self.running = False

    def update(self):
        # game loop updates
        self.all_sprites.update()

    def draw(self):
        # game loop draw
        self.screen.fill(BLACK)
        self.all_sprites.draw(self.screen)
        self.clock.tick(FPS)
        pygame.display.update()

    def main(self):
        #game loop
        while self.playing:
            self.events()
            self.update()
            self.draw()

    def game_over(self):
        restart_button = Button(606.5, 480, 338, 95, WHITE, BLACK, 'TRY AGAIN', 70)

        for sprite in self.all_sprites:
            sprite.kill()

        while self.running:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    self.running = False

            mouse_pos = pygame.mouse.get_pos()
            mouse_pressed = pygame.mouse.get_pressed()

            if restart_button.is_pressed(mouse_pos, mouse_pressed):
                self.new()
                self.main()

            self.screen.blit(self.go_background, (0, 0))
            self.screen.blit(restart_button.image, restart_button.rect)
            self.clock.tick(FPS)
            pygame.display.update()

    def intro_screen(self):
        intro = True

        title = self.font.render('', True, BLACK)
        title_rect = title.get_rect(x=10, y=10)

        play_button = Button(455, 400, 338, 95, WHITE, BLACK, 'PLAY', 80)
        exit_button = Button(455, 550, 338, 95, WHITE, BLACK, 'EXIT', 80)

        while intro:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    intro = False
                    self.running = False

            mouse_pos = pygame.mouse.get_pos()
            mouse_pressed = pygame.mouse.get_pressed()

            if play_button.is_pressed(mouse_pos, mouse_pressed):
                intro = False
            if exit_button.is_pressed(mouse_pos, mouse_pressed):
                intro = False
                self.running = False

            self.screen.blit(self.intro_background, (0, 0))
            self.screen.blit(title, title_rect)
            self.screen.blit(play_button.image, play_button.rect)
            self.screen.blit(exit_button.image, exit_button.rect)
            self.clock.tick(FPS)
            pygame.display.update()

g = Game()
g.intro_screen()
g.new()
while g.running:
    g.main()
    g.game_over()

pygame.quit()
sys.exit()


import pandas as pd
import numpy as np
import os
from lumpyrem import run

class Simulation():
	"""
	A class used to represent a lumprep.in file. It facilitates the generating coherent LUMPREM models and using a silofile as input for climate data.

	Attributes
	----------
	model_list : list
		list of lumprem Model objects
	silofile : tuple
		tuple with (silo file name, column name). This is the silofile to read, and the column to be used for evapotranspiration data.For example: ('silofile.txt','evap')
	start_date : str
		start date of the simulation. Must be in format dd/mm/yyyy.
	end_date : str
		end date of the simulation. Must be in format dd/mm/yyyy.
	steps_per_day : int, optional
		LUMPREP variable steps_per_day and nstep control variable in LUMPREM (default 1)
	nday_out : int, str, optional
		must be either a positive int or the str 'monthly'. Defines the time interval in days at which LUMPREM records results.
	batch_file: str, optional
		name of the batch file to be generated.(default 'run.bat')
	pest_control_file: str, optional
		name of the pest control file to be generated.(default 'temp.pst')

	"""

	def __init__(self, model_list, silofile, start_date, end_date, steps_per_day = 1,nday_out ='monthly',batch_file = 'run.bat',pest_control_file = 'temp.pst', workspace=False):
		self.start_date = start_date
		self.end_date = end_date
		self.nday_out = nday_out
		self.steps_per_day = steps_per_day
		self.model_list = model_list

		self.model_names = []
		for m in model_list:
			self.model_names.append(m.lumprem_model_name)

		self.batch_file = batch_file
		self.pest_control_file = pest_control_file
		self.silofile = silofile

		if workspace==False:
			self.workspace = os.getcwd()
		else:
			self.workspace = workspace

	def write_simulation(self, infile='lumprep.in'):
		"""Writes the LUMPREP input file from the Simulation object.
		Parameters
		----------
		infile : str
			filename for the LUMPREP input file (default 'lumprep.in')
		"""

		infile = os.path.join(self.workspace, infile)

		if not os.path.exists(self.workspace):
			os.makedirs(self.workspace)

		unique_keys = ['start_date','end_date','nday_out','steps_per_day']
		selfdict = self.__dict__

		with open(infile, 'w') as f:
			f.write('# File created using lumpyrem. \n\n')
			for key in unique_keys:
				f.write("{0:} {1:}\n".format(key.upper(), selfdict[key]))
			f.write('\n')

		f.close()

		#write models to lumprep input file
		count=0
		for model in self.model_list:
			model_dict = model.__dict__
			count = count+1

			with open(infile, 'a') as f:
				f.write('# Lumprem dataset number '+str(count)+'\n')
				f.write("{0: <32} {1:}{2:}".format('SILOFILE', self.silofile[0],'\t'+str(self.silofile[1])+'\n'))
				#f.write("{0: <32} {1:}{2:}".format('RAINFILE', os.path.join(self.workspace,'rain.dat'),'\n'))
				#f.write("{0: <32} {1:}{2:}".format('EPOTFILE', os.path.join(self.workspace,'epot.dat'),'\n'))
				for key in model_dict:
					if type(model_dict[key]) == tuple:
						input1 = model_dict[key][0]
						input2 = model_dict[key][1]
					else:
						input1 = model_dict[key]
						input2 = ''
						if input1 == None:
							continue
					if key in ['workspace', 'elevmin', 'elevmax']:#, 'rainfile','epotfile']:
						continue
					f.write("{0: <32}{1:}{2:}".format(key.upper(), str(input1),'\t'+str(input2)+'\n'))
				f.write('\n')
		with open(infile, 'a') as f:
			f.write("{0: <32} {1:}{2:}".format('BATCH_FILE_NAME',self.batch_file,'\n'))
			f.write("{0: <32} {1:}{2:}".format('PEST_CONTROL_FILE',self.pest_control_file,'\n'))
			f.write('\n')
		f.close()

		lumprepin = os.path.basename(infile)
		run.run_process('lumprep', commands=[lumprepin], path=self.workspace)

	def run_simulation(self):
		"""Runs LUMPREM on models created using LUMPREP in the Simulation object.
		"""
		for model in self.model_list:
			model_name = model.lumprem_model_name
			run.run_process('lumprem', commands=['lr_'+model_name+'.in','lr_'+model_name+'.out'], path=self.workspace)

	def get_results(self):
		""" Reads the results from all LUMPREM models in the Simulation object and returns a Dataframe with parameters and results.

		Returns
		-------
		final : DataFrame
			Pandas dataframe of all model results and parameters from the Simulation object.
		"""

		results = pd.DataFrame()
		for m in self.model_names:
			abc = []
			filename = os.path.join(self.workspace,'lr_'+str(m)+'.out')
			textlist = []

			with open(filename) as f:
				for line in f:
					textlist.append([i for i in line.split()])

			floatlist=[]
			for i in textlist[1:-2]:
				floatlist.append([float(x) for x in i])
			df = pd.DataFrame(floatlist, columns=textlist[0])
			df['model_name'] = str(m)
			results = pd.concat([results,df])

		param2 = pd.DataFrame()
		for model in self.model_list:
			columns = model.__dict__.keys()
			param = pd.DataFrame(columns=columns)
			for k in columns:
				param.at[0,k] = model.__dict__[k]
				param[k] = pd.to_numeric(param[k],errors='ignore')
			param2 = pd.concat([param2,param])

		final = results.merge(param2,how='outer', left_on='model_name', right_on='lumprem_model_name')
		return final


# A strobogrammatic number is a number that looks the same when rotated 180 degrees (looked at upside down).

# Write a function to determine if a number is strobogrammatic. The number is represented as a string.

# example:
# "69" -> True
# "88" -> True
# "962" -> False

class Solution:
    def isStrobogrammatic(self, num: str) -> bool:
        cache = {"0":"0", "1":"1","6":"9","8":"8","9":"6"}
        result = ""

        for i in num:
            if i not in cache:
                return False
            result = cache[i] + result
        return result == num


"""
1324. Print Words Vertically

Given a string s. Return all the words vertically in the same order in which they appear in s.
Words are returned as a list of strings, complete with spaces when is necessary. (Trailing spaces are not allowed).
Each word would be put on only one column and that in one column there will be only one word.

Example 1:

Input: s = "HOW ARE YOU"
Output: ["HAY","ORO","WEU"]
Explanation: Each word is printed vertically.
 "HAY"
 "ORO"
 "WEU"
Example 2:

Input: s = "TO BE OR NOT TO BE"
Output: ["TBONTB","OEROOE","   T"]
Explanation: Trailing spaces is not allowed.
"TBONTB"
"OEROOE"
"   T"
Example 3:

Input: s = "CONTEST IS COMING"
Output: ["CIC","OSO","N M","T I","E N","S G","T"]

Constraints:

1 <= s.length <= 200
s contains only upper case English letters.
It's guaranteed that there is only one space between 2 words.

"""
import itertools

class PrintWordVertically:

    """
        With matrices or so, we'd use zip to transpose (= flip so that rows become columns and columns become rows).
        But zip stops at the shortest, and here the columns aren't all the same length. So we use zip_longest instead and tell it to fill with spaces.

        Nice version in three steps:
    """
    def printVertically(self, s):
        columns = s.split()
        rows = itertools.zip_longest(*columns, fillvalue=' ')
        return [''.join(row).rstrip() for row in rows]

    # Oneliner (which is what I wrote during the contest):
    def printVertically(self, s):
        return [''.join(r).rstrip() for r in itertools.zip_longest(*s.split(), fillvalue=' ')]

    def doit_(self, s: str) -> list:

        lst = s.split(' ')
        max_len = max([len(x) for x in lst])
        n = len(lst)

        ans = []
        for i in range(max_len):
            ans.append([lst[j][i] if i < len(lst[j]) else ' ' for j in range(n)])

        ans = [''.join(lst).rstrip() for lst in ans]

        return ans


from django.template import Context, loader
from django.http import HttpResponse
from django.template import RequestContext
from django.shortcuts import get_object_or_404, render
from urllib import urlopen
import json
import locale
import re

def index(request):
  # Function-wide local variable
  url_prefix = "http://data.benzinga.com/stock/"

  # Convert balance to a currency string
  locale.setlocale(locale.LC_ALL, '')
  balanceFloat = request.session.get("balance", 100000.00)
  balance = locale.currency(balanceFloat, grouping=True)

  # Get the portfolio
  portfolio = request.session.get('portfolio', {})

  if request.method == 'POST':
    # If an order to buy or sell has been placed
    if request.POST.get("order", None) is not None and request.POST.get("quant", None) is not None and request.POST.get("symbol", None) is not None:

      symbol = request.POST["symbol"]
      jsonurl = urlopen(url_prefix + symbol)
      jdata = json.loads(jsonurl.read())
      if re.match('^[\w-]+$', symbol) is None:
        params = {'balance': balance, 'portfolio': portfolio, 'error': "Error: Invalid symbol"}
        return render(request, 'index.html', params)
      if jdata.get("status", None) is not None and jdata["status"] == "error":
        params = {'balance': balance, 'portfolio': portfolio, 'error': "Error: Symbol not found"}
        return render(request, 'index.html', params)

      # If an invalid quantity has been provided
      if request.POST["quant"].isdigit() is False or int(request.POST["quant"]) <= 0:
        params = {'symbol': symbol, 'balance': balance, 'portfolio': portfolio,
        'error': "Quantity must be a positive value", 'jdata': jdata}
        return render(request, 'index.html', params)

      # If an order to buy shares has been placed
      elif request.POST["order"] == "Buy" and request.POST.get("ask", None) is not None:
        quantity = int(request.POST["quant"])
        price = float(request.POST["ask"])
        if quantity*price > balanceFloat:
          # This order cannot be placed
          params = {'symbol': symbol, 'balance': balance, 'portfolio': portfolio,
          'error': "Error: Order exceeds balance", 'jdata': jdata}
          return render(request, 'index.html', params)
        if symbol in portfolio:
          # Increase the count of shares
          portfolio[symbol]["quantity"] += quantity
        else:
          # Add this symbol to the portfolio
          portfolio[symbol] = {}
          portfolio[symbol]["name"] = jdata["name"]
          portfolio[symbol]["quantity"] = quantity
          portfolio[symbol]["price"] = price
        balanceFloat -= quantity*price

        # Update the session variables and load the page
        request.session["balance"] = balanceFloat
        request.session["portfolio"] = portfolio
        balance = locale.currency(balanceFloat, grouping=True)
        params = {'symbol': symbol, 'balance': balance, 'portfolio': portfolio, 'jdata': jdata}
        return render(request, 'index.html', params)

      # If an order to sell shares has been placed
      elif request.POST["order"] == "Sell" and request.POST.get("bid", None) is not None:
        quantity = int(request.POST["quant"])
        price = float(request.POST["bid"])
        if symbol not in portfolio:
          # This order cannot be placed
          params = {'symbol': symbol, 'balance': balance, 'portfolio': portfolio,
          'error': "Error: There are no shares for this stock in the portfolio", 'jdata': jdata}
          return render(request, 'index.html', params)
        elif quantity > int(portfolio[symbol]["quantity"]):
          # This order cannot be placed
          params = {'symbol': symbol, 'balance': balance, 'portfolio': portfolio,
          'error': "Error: Selling more shares for this stock than in the portfolio", 'jdata': jdata}
          return render(request, 'index.html', params)
        portfolio[symbol]["quantity"] -= quantity
        if portfolio[symbol]["quantity"] == 0:
          # Remove this stock from the portfolio
          del portfolio[symbol]
        balanceFloat += quantity*price

        # Update the session variables and load the page
        request.session["balance"] = balanceFloat
        request.session["portfolio"] = portfolio
        balance = locale.currency(balanceFloat, grouping=True)
        params = {'symbol': symbol, 'balance': balance, 'portfolio': portfolio, 'jdata': jdata}
        return render(request, 'index.html', params)

      # A bad order request has been made; return the default page
      else:
        params = {'symbol': symbol, 'balance': balance, 'portfolio': portfolio}
        return render(request, 'index.html', params)

    # If a symbol is being retrieved
    elif request.POST.get("symbol", None) is not None:
      symbol = request.POST["symbol"]
      jsonurl = urlopen(url_prefix + symbol)
      jdata = json.loads(jsonurl.read())

      if re.match('^[\w-]+$', symbol) is None:
        params = {'balance': balance, 'portfolio': portfolio, 'error': "Error: Invalid symbol"}
        return render(request, 'index.html', params)
      if jdata.get("status", None) is not None and jdata["status"] == "error":
        params = {'balance': balance, 'portfolio': portfolio, 'error': "Error: Symbol not found"}
        return render(request, 'index.html', params)

      params = {'symbol': symbol, 'balance': balance, 'portfolio': portfolio, 'jdata': jdata}
      return render(request, 'index.html', params)

    # Invalid POST parameters; return the default page
    else:
      params = {'balance': balance, 'portfolio': portfolio}
      return render(request, 'index.html', params)

  else:
    # Default page
    params = {'balance': balance, 'portfolio': portfolio}
    return render(request, 'index.html', params)


from django.conf.urls.defaults import patterns, include, url
from django.conf import settings

# Uncomment the next two lines to enable the admin:
from django.contrib import admin
admin.autodiscover()

urlpatterns = patterns('',
    url(r'^$', 'shop.views.site', {'site': 'START'}),
    url(r'^home/$', 'shop.views.index'),
    url(r'^hockley/$', 'shop.views.index'),
    url(r'^menu/$', 'shop.views.site', {'site': 'MENU'}),
#    url(r'^shop/$', 'shop.views.shop'),
    url(r'^blog/$', 'shop.views.blog'),
    url(r'^jobs/$', 'shop.views.site', {'site': 'JOBS'}),
    url(r'^friends/$', 'shop.views.site', {'site': 'FRIENDS'}),
    url(r'^find_us/$', 'shop.views.site', {'site': 'FIND_US'}),
    url(r'^contact/$', 'shop.views.contact'),
    url(r'^suppliers/$', 'shop.views.site', {'site': 'SUPPLIERS'}),
    url(r'^cakes/$', 'shop.views.gallery', {'site': 'CAKES'}),
     url(r'^gallery/$', 'shop.views.gallery', {'site': 'GALLERY'}),
    url(r'^cakes/item/(?P<item_id>\d+)/$', 'shop.views.cake_detail'),
    url(r'^gallery/item/(?P<item_id>\d+)/$', 'shop.views.image_detail'),
#    url(r'^shop/item/(?P<item_id>\d+)/$', 'shop.views.detail'),
#    url(r'^shop/basket/(?P<basket_id>\d+)/$', 'shop.views.basket'),
    url(r'^media/(?P<path>.*)$', 'django.views.static.serve', {
            'document_root': settings.MEDIA_ROOT,
        }),

    url(r'^sherwood/$', 'shop.views.site', {'site': 'SHERWOOD_HOME'}),
    url(r'^sherwood_menu/$', 'shop.views.site', {'site': 'SHERWOOD_MENU'}),

    url(r'^catering/$', 'shop.views.site', {'site': 'CATERING_HOME'}),
    url(r'^weddings/$', 'shop.views.site', {'site': 'WEDDINGS'}),
    url(r'^parties/$', 'shop.views.site', {'site': 'PARTIES'}),
    url(r'^events/$', 'shop.views.site', {'site': 'EVENTS'}),
    url(r'^pavilion/$', 'shop.views.site', {'site': 'PAVILION_HOME'}),

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

    # Uncomment the admin/doc line below to enable admin documentation:
    # url(r'^admin/doc/', include('django.contrib.admindocs.urls')),

    # Uncomment the next line to enable the admin:
    url(r'^admin/', include(admin.site.urls)),
#    url(r'^shop/admin/', include(admin.site.urls)),
#    url(r'^', include('cms.urls')),
)

#if settings.DEBUG:
#    urlpatterns = patterns('',
#    url(r'^media/(?P<path>.*)$', 'django.views.static.serve',
#        {'document_root': settings.MEDIA_ROOT, 'show_indexes': True}),
#    url(r'', include('django.contrib.staticfiles.urls')),
#) + urlpatterns


import os
import math
from yacs.config import CfgNode as CN

_C = CN()
cfg = _C
_C.MODEL_NAME = 'efficientnetb3'
_C.CKPT_DIR = './checkpoint/' + _C.MODEL_NAME
_C.LOG_DIR = _C.CKPT_DIR + '/logs'

_C.TRAIN = CN()
_C.TRAIN.BATCH_SIZE = 16
_C.TRAIN.EPOCHS = 1000
_C.TRAIN.ACTIVATION = 'softmax'
_C.TRAIN.WEIGHTS = 'imagenet'
_C.TRAIN.FREEZE_ENCODER = False
_C.TRAIN.OPTIMIZER = 'sgd'
_C.TRAIN.RHO = 0.9
_C.TRAIN.MOMENTUM = 0.9
_C.TRAIN.SNAP_SHOT = 3

_C.DATASET = CN()
_C.DATASET.TRAIN_DATA = './dataset/record/train*'
_C.DATASET.VAL_DATA = './dataset/record/val*'
_C.DATASET.RAW_SIZE = (600, 800)     # H, W
_C.DATASET.SIZE = (300, 400)
_C.DATASET.CHANNELS = 3
_C.DATASET.N_CLASSES = 5
_C.DATASET.LABELS = ['0', '1', '2', '3', '4']
_C.DATASET.NUM_TRAIN = 4000

_C.SCHEDULER = CN()
_C.SCHEDULER.LR_TYPE = 'exponential'    # piecewise, cosine_decay_restart
_C.SCHEDULER.LR_INIT = 1e-1
_C.SCHEDULER.LR_DECAY_RATE = 0.96
_C.SCHEDULER.LR_LOWER_BOUND = 1e-5
_C.SCHEDULER.LR_DECAY_STEPS = math.ceil(_C.DATASET.NUM_TRAIN / _C.TRAIN.BATCH_SIZE) * 3
_C.SCHEDULER.WARMUP_STEPS = math.ceil(_C.DATASET.NUM_TRAIN / _C.TRAIN.BATCH_SIZE) * 10
_C.SCHEDULER.CDR_T_MUL = 1.5
_C.SCHEDULER.CDR_M_MUL = 0.5
_C.SCHEDULER.NUM_PERIODS = 0.5
_C.SCHEDULER.LCD_ALPHA = 0.0
_C.SCHEDULER.LCD_BETA = 0.0001
_C.SCHEDULER.INITIAL_VARIANCE = 1.0
_C.SCHEDULER.VARIANCE_DECAY = 0.55
_C.SCHEDULER.BOUNDARIES = [5000, 8000, 10000, 12000, 14000, 16000, 18000, 19000, 20000]
_C.SCHEDULER.BOUNDARIES = [1e-4, 9e-5, 8e-5, 7e-5, 6e-5, 5e-5, 4e-5, 3e-5, 2e-5, 1e-5]

_C.LOSS = CN()
_C.LOSS.TYPE = 'ce_loss'
_C.LOSS.WEIGHT_DECAY = 5e-5
_C.LOSS.TOPK = _C.DATASET.SIZE[0] * _C.DATASET.SIZE[0] * 0.25
_C.LOSS.IGNORE = True
_C.LOSS.ALPHA = 0.25
_C.LOSS.GAMMA = 2
_C.LOSS.LABEL_SMOOTHING = 0.05
_C.LOSS.WEIGHTS = [1, 1, 1, 1, 1, 1, 1, 1]

_C.AUGMENTATION = CN()


import pytest
from selenium import webdriver
import time
import math

@pytest.fixture(scope="function")
def browser():
    print("\nstart browser for test..")
    # инициализируем драйвер браузера. После этой команды вы должны увидеть новое открытое окно браузера
    chrome_opt = webdriver.ChromeOptions()
    # удаляем gpu ошибку из терминала
    chrome_opt.add_argument('--disable-gpu')
    # path to driver
    path = r"C:/chromedriver/chromedriver.exe"
    # declare and initialize driver variable
    browser = webdriver.Chrome(executable_path=path, options=chrome_opt)
    yield browser
    print("\nquit browser..")
    browser.quit()

@pytest.mark.parametrize('number', ["236895", "236896", "236897",
    "236898", "236899", "236903", "236904", "236905"])
def test_use_parameters(browser, number):
    link = f"https://stepik.org/lesson/{number}/step/1"
    browser.get(link)

    answer = math.log(int(time.time()))
    print(answer)

    time.sleep(7)

    text_input = browser.find_element_by_css_selector('textarea.textarea')
    text_input.clear()
    text_input.send_keys(str(answer))

    button = browser.find_element_by_css_selector(".submit-submission")
    button.click()
    time.sleep(2)

    actual_result = browser.find_element_by_css_selector(".smart-hints__hint").text
    expected_result = "Correct!"

    assert actual_result == expected_result

# pytest -s -v test_parameters.py


"""
Read file into texts and calls.
It's ok if you don't understand how to read files
"""
import csv
with open('texts.csv', 'r') as f:
    reader = csv.reader(f)
    texts = list(reader)

with open('calls.csv', 'r') as f:
    reader = csv.reader(f)
    calls = list(reader)

"""
TASK 2: Which telephone number spent the longest time on the phone
during the period? Don't forget that time spent answering a call is
also time spent on the phone.
Print a message:
"<telephone number> spent the longest time, <total time> seconds, on the phone during
September 2016.".
"""

# * All the phone calls are during September
# * Need to keep track of the caller and the callee time for each number
# * Lookup the longest time at the end since the overall runtime won't be
#   impacted and it is much simpler

number_map = {}
def update_durations(number_map, number, duration):
    last_duration = number_map.get(number, 0)
    number_map[number] = last_duration + duration

for source, dest, time, duration in calls:
    update_durations(number_map, source, int(duration))
    update_durations(number_map, dest, int(duration))

longest_number = max(number_map.keys(), key=(lambda k: number_map[k]))
longest = number_map[longest_number]

print(longest_number, "spent the longest time,", longest, "seconds, on the phone during September 2016.")


import json
import argparse
from flask import Flask, jsonify, redirect, render_template
import subprocess
import requests
app = Flask(__name__)

json_path = "./config/val/val.json"

@app.route('/')
def hello():
    names = get_names()
    # return 'on
off
on'
    return render_template('index.html', names=names)

@app.route('/on')
def on():
    res = send_ir('light:on')
    if res:
        return jsonify({'status': False})
    else:
        return jsonify({'status': True})

@app.route('/off')
def off():
    res = send_ir('light:off')
    if res:
        return jsonify({'status': False})
    else:
        return jsonify({'status': True})

@app.route("/send/<name>")
def archive(name=""):
    if name == "":
        return jsonify({'status': False})
    else:
        res = send_ir(name)

        if res:
            return jsonify({'status': False})
        else:
            return jsonify({'status': True})

@app.route("/names")
def names():
    names = get_names()
    ret = []
    for name in names:
        ret.append({'name': name})
    return jsonify(ret)

def send_ir(name):
    command = ['python', 'irrp.py', '-p', '-g27',
               '-f', json_path, name]
    res = subprocess.call(command)
    return res

def get_names():
    with open(json_path, "r") as f:
        records = json.load(f)
    keys = list(records.keys())
    keys.reverse()
    return keys

if __name__ == "__main__":
    app.run(debug=True, host='0.0.0.0')


# hook 参数处理 且 处理污点池
import dongtai_agent_python.global_var as dt_global_var
from dongtai_agent_python.common import origin
from dongtai_agent_python.global_var import _global_dt_dict
from dongtai_agent_python.common.content_tracert import method_pool_data, dt_tracker_get, dt_tracker_set, come_in, \
    deal_args

def wrapData(result, origin_cls, _fcn, signature=None, source=False, comeData=None):
    dt_data_args = dt_tracker_get("dt_data_args")
    if dt_data_args is None:
        return result

    if comeData is None:
        comeData = []

    dt_open_pool = _global_dt_dict.get("dt_open_pool")
    if not dt_open_pool:
        return result

    # 污点池
    dt_global_var.dt_set_value("dt_open_pool", False)

    # 获取source点
    taint_in = []
    if source:
        can_upload = 1
        # 入参入池 id
        end_args = deal_args(comeData)
        for one in end_args:
            dt_data_args = come_in(one, dt_data_args)
            origin.list_append(taint_in, one)
    else:
        can_upload = 0

        if len(dt_data_args) != 0:
            # 入参入池 id
            end_args = deal_args(comeData)
            for two in end_args:
                if two in dt_data_args:
                    # hook 当前方法 且 将结果值存入污点池
                    can_upload = 1
                    if two not in taint_in:
                        origin.list_append(taint_in, two)

    if can_upload == 1:
        # 当前方法type为2、3， callerMethod not in 2、3类其他方法中

        dt_data_args = come_in(result, dt_data_args)
        dt_tracker_set("dt_data_args", dt_data_args)
        method_pool_data(origin_cls, _fcn, comeData, taint_in, result, source=source, signature=signature)

    dt_global_var.dt_set_value("dt_open_pool", True)

    return result


from Music import Music
from ml_utils import *
import os
import tensorflow as tf
import tensorflow_hub as hub
import time

np.set_printoptions(threshold=np.inf)
model_url = "https://tfhub.dev/google/universal-sentence-encoder/2"
embed = hub.Module(model_url)

os.environ['JAVA_HOME'] = "/Library/Java/JavaVirtualMachines/jdk1.8.0_211.jdk/Contents/Home"

memory = '6g'
pyspark_submit_args = ' --driver-memory ' + memory + ' pyspark-shell'
os.environ["PYSPARK_SUBMIT_ARGS"] = pyspark_submit_args

if __name__ == "__main__":
    start = time.time()
    music = Music()
    select_PID = music.Products.sortBy(lambda x: x[1], ascending=False).take(10)[9][0]
    print(select_PID)

    Positive_Reviews = music.og \
        .filter(lambda x: x.split("\t")[3] == select_PID) \
        .filter(lambda x: int(x.split("\t")[7]) >= 4) \
        .map(lambda x: (x.split("\t")[2], splitSentence(x.split("\t")[13]))) \
        .flatMap(Split) \
        .zipWithIndex() \
        .map(lambda x: (x[1], x[0]))

    Positive_Reviews_body = Positive_Reviews.map(lambda x: x[1][0])
    print(Positive_Reviews.count())

    Positive_Reviews_collect = Positive_Reviews_body.collect()

    Positive_Sentence_Matrix = np.array([])
    with tf.Session() as session:
        session.run([tf.global_variables_initializer(), tf.tables_initializer()])
        message_embeddings = np.array(session.run(embed(Positive_Reviews_collect)))
        print(message_embeddings.shape)
        Positive_Sentence_Matrix = message_embeddings.copy()

    print(Positive_Sentence_Matrix.shape)
    norm_vector = np.sqrt(np.sum(Positive_Sentence_Matrix ** 2, axis=1))[:, np.newaxis]
    norm_matrix = norm_vector.dot(norm_vector.T)
    dot_product_matrix = Positive_Sentence_Matrix.dot(Positive_Sentence_Matrix.T)
    cosinedistance_matrix = 1 - dot_product_matrix / norm_matrix

    distance_for_each = (np.sum(cosinedistance_matrix, axis=1) / (cosinedistance_matrix.shape[1] - 1))
    center_index = np.argmin(distance_for_each)
    Closet10_Index = np.argsort(cosinedistance_matrix[center_index, :])[:11]
    distance_overall = np.mean(distance_for_each)
    end = time.time()
    time_spent = end - start
    f = open("Stage3_Positive.txt", 'w')
    # f.write(str(Positive_Reviews.collect()))
    f.write("total time spent: " + str(time_spent) + "s" + "\n")
    # f.write("the distance matrix:" + str(cosinedistance_matrix) + "\n")
    f.write("the index of central sentence: " + str(center_index) + "\n")
    f.write("the center sentence for positive reviews: " + str(Positive_Reviews.lookup(center_index)) + "\n")
    f.write("the 10 closest sentences for positive central sentence: " + "\n")
    for i in Closet10_Index:
        f.write(str(Positive_Reviews.lookup(i)) + "\n")
    f.write("Average distance between one sentence with others" + "\n" + str(distance_for_each) + "\n")
    f.write("Overall Average distance: " + str(distance_overall))
    f.close()


from .forms import UploadFileForm
from job_app.models import Job, IsOpen, JobTitle, Status, City, State, ZipCode, County
from nurse_manage.models import AvailableTime, Skill
from uploader.models import Document
from nurse_manage.models import Nurse, Discipline, AvailableTime
from django.shortcuts import render
import csv, openpyxl
from  nurse_manage.helper.available_time_generator import AvailableTimeGenerator

# Create your views here.
def upload_job(request):
    # handle file upload
    if request.method == 'POST':
        form = UploadFileForm(request.POST, request.FILES)
        if form.is_valid():
            file = Document(file=request.FILES['file'])
            file.save()
            ifile = open(file.file.path, "r", encoding='utf-8', errors='ignore')
            readers = csv.reader(ifile)
            readers.__next__()  # skip the first line (headers)

            error = []
            success = []

            for row in readers:
                title = JobTitle.objects.get_or_create(name=row[0])
                status = Status.objects.get_or_create(name=row[1])
                city = City.objects.get_or_create(name=row[2])
                state = State.objects.get_or_create(name=row[3])
                zip_code = ZipCode.objects.get_or_create(code=row[4])
                is_open = IsOpen.objects.get_or_create(open=str2bool(row[5]))

                try:
                    job = Job(title=title[0], status=status[0], city=city[0], state=state[0],
                              zip_code=zip_code[0], is_open=is_open[0], description=row[6])
                    job.save()
                    success.append(title[0])
                except Exception as e:
                    error.append(title[0])

            context = {'errors': error, 'success': success}
            return render(request, 'django_excel/result.html', context)

    form = UploadFileForm()  # an empty unbound form
    return render(request, 'django_excel/upload.html', {'form': form})

def str2bool(v):
    return v.lower() in ("yes", "true", "t", "1")

def upload_city(request):
    if request.method == 'POST':
        form = UploadFileForm(request.POST, request.FILES)
        if form.is_valid():
            file = Document(file=request.FILES['file'])
            file.save()
            ifile = open(file.file.path, "r", encoding='utf-8')
            readers = csv.reader(ifile)

            county = request.POST.getlist('county')[0]
            error = []
            success = []
            counties = []
            county_level = False

            for row in readers:
                city_name = row[0]
                try:
                    city_name = city_name.strip()
                    county, created = County.objects.get_or_create(name=county)
                    city = City.objects.create(name=city_name, county=county)
                    city.save()
                    success.append(city_name)

                except Exception as e:
                    print(e)
                    error.append(city_name)

            context = {'errors': error, 'success': success}
            return render(request, 'django_excel/result.html', context)

    form = UploadFileForm()  # an empty unbound form
    return render(request, 'django_excel/upload_city.html', {'form': form})

def upload_time(request):
    if request.method == 'POST':
        form = UploadFileForm(request.POST, request.FILES)
        if form.is_valid():
            file = Document(file=request.FILES['file'])
            file.save()
            ifile = open(file.file.path, "r", encoding='utf-8')
            readers = csv.reader(ifile)

            readers.__next__()  # skip the first line (headers)

            error = []
            success = []

            for row in readers:
                code = row[2]

                try:
                    available_time = AvailableTime(code=code)
                    available_time.save()
                    success.append(str(code))

                except Exception as e:
                    print(e)
                    error.append(str(code))

            context = {'errors': error, 'success': success}
            return render(request, 'django_excel/result.html', context)

    form = UploadFileForm()  # an empty unbound form
    return render(request, 'django_excel/upload_time.html', {'form': form})

def upload_nurse(request):
    values = ['name', 'title', 'dateOfHire', 'status', 'skill', 'area', 'cellphone', 'work_phone', 'email', 'comment']

    if request.method == 'POST':
        form = UploadFileForm(request.POST, request.FILES)
        if form.is_valid():
            file = Document(file=request.FILES['file'])
            file.save()

            wb = openpyxl.load_workbook(file.file.path)
            sheet = wb.get_sheet_by_name("Staff List")

            error = []
            success = []
            a_time_gen = AvailableTimeGenerator()
            try:
                for r in range(1, 60):

                    for c, v in zip(range(1, 9), range(0, len(values))):
                        values[v] = sheet.cell(row=r, column=c).value

                    name = values[0]

                    while name != None and name != "Employee Name":
                        name = values[0]
                        discipline = values[1]

                        status = values[3]

                        skill = values[4]

                        covered_areas = values[5]

                        cell_phone = values[6]
                        email = values[8]
                        comment = values[9]
                        available_time = a_time_gen.generate_time_list()
                        try:
                            # create and populate nurse instance:
                            nurse, created = Nurse.objects.get_or_create(name=name, cell_phone=cell_phone)
                            print(nurse, created)
                            if discipline != None:
                                list = discipline.split(",")
                                for e in list:
                                    if e != None:
                                        e = e.strip()
                                        discipline, created = Discipline.objects.get_or_create(name=e)
                                        print(discipline)
                                        nurse.disciplines.add(discipline)

                            if skill != None:
                                list = skill.split(",")

                                for e in list:
                                    if e != None:
                                        e = e.strip()
                                        skill, created = Skill.objects.get_or_create(name=e)
                                        nurse.skills.add(skill)

                            # populate fake available time

                            print("=========================")
                            print(available_time)
                            for e in available_time:
                                a_time = AvailableTime.objects.get(code=e)
                                print(a_time)
                                nurse.availableTime.add(a_time)
                                print("Success")

                            if covered_areas != None:
                                list = covered_areas.split(',')

                                for e in list:
                                    if e != None:
                                        e = e.strip()
                                        area, created = City.objects.get_or_create(name=e)
                                        print(area)
                                        nurse.covered_areas.add(area)

                        except Exception as e:
                            error.append(nurse.name)

                        success.append(nurse.name)
                        break
            except Exception as e:
                print(e)

            context = {'errors': error, 'success': success}
            return render(request, 'django_excel/result.html', context)

    form = UploadFileForm()  # an empty unbound form
    return render(request, 'django_excel/upload_nurse.html', {'form': form})


# =============================================================================
# Results_bar_chart.py
# =============================================================================
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

results = pd.read_csv('Results.csv', parse_dates=True,
                      index_col=0, error_bad_lines=False)

#results = results.drop(['DTR'])

mae = results.iloc[:, 0]
rmse = results.iloc[:, 1]

labels = results.index

x = np.arange(len(labels))  # the label locations
width = 0.45  # the width of the bars

# Plots
plt.rc('xtick', labelsize=18)
plt.rc('ytick', labelsize=18)

fig, ax = plt.subplots()
ax2 = ax.twinx()
rects1 = ax.bar(x - width/2, mae, width,
                label='MAE', color='#e62929', zorder=10)
rects2 = ax2.bar(x + width/2, rmse, width, label='RMSE', color='#3d4de0')

# Add some text for labels, title and custom x-axis tick labels, etc.
ax.set_ylabel('MAE', fontsize=18)
ax2.set_ylabel('RMSE', fontsize=18)
ax.set_xlabel('Model', fontsize=18)
ax.set_title('Performance of all models', fontsize=20)
ax.set_xticks(x)
ax.set_xticklabels(labels, fontsize=16)
#ax.legend(loc='upper right', fontsize=13)
leg2 = fig.legend([rects1, rects2],
                  ['MAE', 'RMSE'],
                  bbox_to_anchor=(0.125, 1.01),
                  bbox_transform=ax.transAxes, fontsize=18)
ax.grid(True)
ax.autoscale()

def autolabel(rects, axi):
    """Attach a text label above each bar in *rects*, displaying its height."""
    if axi == 1:
        for rect in rects:
            height = rect.get_height()
            ax.annotate('{}'.format(height),
                        xy=(rect.get_x() + rect.get_width() / 2 - 0.02, height),
                        xytext=(0, 3),  # 3 points vertical offset
                        textcoords="offset points",
                        ha='center', va='bottom',
                        fontsize=14, color='#e62929')
    else:
        for rect in rects:
            height = rect.get_height()
            ax2.annotate('{}'.format(height),
                         xy=(rect.get_x() + rect.get_width() / 2 + 0.02, height),
                         xytext=(0, 3),  # 3 points vertical offset
                         textcoords="offset points",
                         ha='center', va='bottom',
                         fontsize=14, color='#3d4de0')

autolabel(rects1, 1)
autolabel(rects2, 2)

fig.tight_layout()

plt.show()


#!/bin/python
import pandas as pd
import glob, os

os.chdir("/home/marco/workspace/git/StatLearnTeam/DataCovidNEW/")
all_files = glob.glob("new*.csv")

li = []

for filename in all_files:
    df = pd.read_csv(filename, index_col=None, header=0)
    li.append(df)

frame = pd.concat(li, axis=0, ignore_index=True)

frame.to_csv('/home/marco/workspace/git/StatLearnTeam/articles_analysis/new_prociv_data.csv', sep = ';', na_rep = 'NULL')


# Copyright 2015 The TensorFlow Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ==============================================================================

"""A very simple MNIST classifier.
See extensive documentation at
https://www.tensorflow.org/get_started/mnist/beginners
"""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import argparse
import sys

from tensorflow.examples.tutorials.mnist import input_data

import tensorflow as tf
from ffnn import mlp
import pdb

FLAGS = None

def main(_):

# Import data
    mnist = input_data.read_data_sets(FLAGS.data_dir, one_hot=True)
    mlp_name = 'TEST_MLP'
    dtype = tf.float32
    input_size = 784
    output_size = 10
    hidden_size = 100000
    act_func = None

    weight_params = {'dtype': dtype,
                    # 'weight_init': 'uniform',
                     'weight_init': 'normal',
                     'weight_init_mean': -0.000005,
                     'weight_init_stddev': 0.000005,
                    # 'weight_init_max': 0.05,
                    # 'weight_init_min': -5,
                     'weight_decay': None,
                     'variable_share': False}

    mlp_params = {'name': mlp_name,
                  'IO_dtype': dtype,
                  'input_size': input_size,
                  'output_size': output_size,
                  'hidden_size': hidden_size,
                  'hidden_act': act_func,
                  'output_act': None,
                  'weight_params': weight_params}

    mlp_net = mlp(mlp_params)
    with tf.Graph().as_default():
        input_pl = tf.placeholder(dtype=dtype,
                                  shape=(None, input_size),
                                  name='input_pl')
        output_pl = tf.placeholder(dtype=dtype,
                                   shape=(None, output_size),
                                   name='input_pl')
        mnist_logits = mlp_net.build(input_pl)
        sess = tf.Session()
        cross_entropy = tf.reduce_mean(
            tf.nn.softmax_cross_entropy_with_logits(labels=output_pl,
                                                    logits=mnist_logits))
        # train_step = tf.train.AdamOptimizer(learning_rate=0.000001,
        #                                     epsilon=0.1).minimize(cross_entropy)
        train_step = tf.train.GradientDescentOptimizer(0.5).minimize(cross_entropy)
        correct_prediction = tf.equal(tf.argmax(mnist_logits, 1),
                                      tf.argmax(output_pl, 1))
        accuracy = tf.reduce_mean(tf.cast(correct_prediction,
                                          tf.float32))
        sess.run(tf.global_variables_initializer())
        for _ in range(1000):
            batch_xs, batch_ys = mnist.train.next_batch(1000)
            sess.run(train_step, feed_dict={input_pl: batch_xs,
                                            output_pl: batch_ys})

            # Test trained model
            print(sess.run(accuracy, feed_dict={input_pl: mnist.test.images,
                                                output_pl: mnist.test.labels}))

if __name__ == '__main__':
  parser = argparse.ArgumentParser()
  parser.add_argument('--data_dir', type=str, default='/tmp/tensorflow/mnist/input_data',
                      help='Directory for storing input data')
  FLAGS, unparsed = parser.parse_known_args()
  tf.app.run(main=main, argv=[sys.argv[0]] + unparsed)


import tweepy

def get_api(cfg):
  auth = tweepy.OAuthHandler(cfg['consumer_key'], cfg['consumer_secret'])
  auth.set_access_token(cfg['access_token'], cfg['access_token_secret'])
  return tweepy.API(auth)

def tweet(contents : str):
  cfg = {
    "consumer_key"        : "",
    "consumer_secret"     : "",
    "access_token"        : "",
    "access_token_secret" : ""
    }

  api = get_api(cfg)
  if(contents.count(contents) <= 140):
    status = api.update_status(status=contents)
    return "Tweet sent"
  else:
      print("Too many characters to tweet!")
      return "Tweet error: Too many characters to tweet"


import os
import sys
import yaml
import timeit
import shutil
from datetime import datetime

from crotal import utils
from crotal import logger
from crotal import settings
from crotal.utils import remove_dir
from crotal.controller import Controller
from crotal.plugins.pinyin.pinyin import PinYin

LOGO = \
"""  ____ ____   ___ _____  _    _
 / ___|  _ \\ / _ \\_   _|/ \\  | |
| |   | |_) | | | || | / _ \\ | |
| |___|  _ <| |_| || |/ ___ \\| |___
 \____|_| \_\\\\___/ |_/_/   \\_\\_____|
"""

POST_SAMPLE =\
"""---
title: "{0}"
date: {1}
categories:
slug: {2}
---

"""

PAGE_SAMPLE = \
"""---
layout: page.html
title: "{0}"
date: {1}
url: {2}
description: {3}
---

## A demo page!

This is a demo page.
"""

class Command(object):

    @staticmethod
    def generate(full=False, silent=False, is_preview=True):
        if full and os.path.exists(settings.PUBLISH_DIR):
            shutil.rmtree(settings.PUBLISH_DIR)
        utils.load_config_file()
        setattr(settings, 'THEME_DIR', os.path.join('themes', settings.theme))
        setattr(settings, 'TEMPLATES_DIR', os.path.join(settings.THEME_DIR, 'public'))
        setattr(settings, 'THEME_STATIC_DIR', os.path.join(settings.THEME_DIR, 'static'))
        start = timeit.default_timer()

        controller = Controller(full=full)
        copydir_time = timeit.default_timer()
        if not silent:
            logger.info('Static files copied.')

        controller.load(is_preview)
        if not silent:
            logger.info('Source loaded.')

        get_posts_time = timeit.default_timer()

        controller.save()
        save_other_files_time = timeit.default_timer()

        controller.save_posts()
        if not silent:
            logger.info('Posts saved.')
        controller.save_pages()
        if not silent:
            logger.info('Pages saved.')
        controller.save_categories()
        controller.save_tags()

        save_posts_time = timeit.default_timer()
        controller.save_db()
        remove_dir(settings.PUBLISH_DIR)

        if not silent:
            logger.info('%d posts generated.' % len(controller.post_collector.posts))
            logger.info('%d pages generated.' % len(controller.page_collector.pages))
            logger.info('Site generated, master %s!' % settings.author)

    @staticmethod
    def init():
        if len(sys.argv) != 3:
            site_name = 'crotal'
        else:
            site_name = sys.argv[2]
        curr = os.path.dirname(os.path.abspath(__file__))
        dir = os.path.join(curr, "init")
        utils.copy_dir(dir, site_name)
        logger.blue_text(message=LOGO)
        utils.init_git_repo(site_name)
        logger.success('Site created.')

    @staticmethod
    def create_post():
        if not os.path.exists(settings.CONFIG_PATH):
            logger.error('No "_config.yml" file found for the current directory.')
            sys.exit()
        if len(sys.argv) != 3:
            logger.error('Please specify the post title.')
        else:
            title = sys.argv[2]
            now = datetime.now()
            pub_time = now.strftime('%Y-%m-%d %H:%M')
            pinyin = PinYin()
            pinyin.load_word()
            slug = pinyin.hanzi2pinyin_split(string=title, split='-')
            new_post = POST_SAMPLE.format(title, pub_time, slug)
            file_title = now.strftime("%Y-%m-%d") + '-' + slug + '.markdown'
            file_path = os.path.join(settings.POSTS_DIR, file_title)
            open(os.path.join(settings.BASE_DIR, file_path), 'w+').write(new_post)
            logger.success(' '.join([file_path, 'created.']))

    @staticmethod
    def create_page():
        if not os.path.exists(settings.CONFIG_PATH):
            logger.error('No "_config.yml" file found for the current directory.')
            sys.exit()
        title = logger.info_input('Page Title')
        url = logger.info_input('Page URL (.e.g, /foo/bar/):')
        description = logger.info_input('Page Description:')
        pinyin = PinYin()
        slug = pinyin.hanzi2pinyin_split(string=title, split="-")
        now = datetime.now()
        pub_date = now.strftime("%Y-%m-%d %H:%M")
        page = PAGE_SAMPLE.format(title, pub_date, url, description)
        file_path = os.path.join(settings.PAGES_DIR, slug + '.markdown')
        open(os.path.join(settings.BASE_DIR, file_path), 'w+').write(page)
        logger.success('You can browse the page by {0} After generating the site.'.format(url))


import sys

with open(sys.argv[1], 'r') as test_cases:
    for line in test_cases.readlines():
        X, Y, N = map(int, line.strip().split(' '))
        for number in range(1, N+1):
            output = ''
            if number % X == 0:
                output += 'F'
            if number % Y == 0:
                output += 'B'
            if not output:
                output = number

            print(output, end=' ')
        print()


import typing

from octobot.database import Database
import telegram
import json

from settings import Settings

def create_db_entry_name(chat: typing.Union[telegram.Chat, int]):
    if isinstance(chat, telegram.Chat):
        chat = chat.id
    return f"admcache:{chat}"

def reset_cache(chat: typing.Union[telegram.Chat, int]):
    return Database.redis.delete(create_db_entry_name(chat))

def check_perms(chat: typing.Union[telegram.Chat, int], user: typing.Union[telegram.User, int],
                permissions_to_check: set, bot=None):
    db_entry = create_db_entry_name(chat)

    if isinstance(user, telegram.User):
        user_id = user.id
    else:
        user_id = user
    if isinstance(chat, telegram.Chat):
        chat_id = chat.id
    else:
        chat_id = chat
    if "is_bot_owner" in permissions_to_check:
        if Settings.owner == user_id: permissions_to_check.remove("is_bot_owner")
        return Settings.owner == user_id, permissions_to_check
    if not str(chat_id).startswith("-100"):
        return True, []
    if Database.redis is not None and Database.redis.exists(db_entry) == 1:
        adm_list = json.loads(Database.redis.get(db_entry).decode())
    else:
        if bot is None:
            adm_list_t = chat.get_administrators()
        else:
            adm_list_t = bot.get_chat_administrators(chat_id=chat_id)
        adm_list = []
        for admin in adm_list_t:
            adm_list.append(admin.to_dict())
        if Database.redis is not None:
            Database.redis.set(db_entry, json.dumps(adm_list))
            Database.redis.expire(db_entry, 240)
    for member in adm_list:
        if int(member["user"]["id"]) == int(user_id):
            if member["status"] == "creator":
                return True, []
            if "is_admin" in permissions_to_check:
                permissions_to_check.remove("is_admin")
            for user_permission in permissions_to_check.copy():
                if member[user_permission]:
                    permissions_to_check.remove(user_permission)
            break
    return len(permissions_to_check) == 0, permissions_to_check

def permissions(*perms_args, **perms_kwargs):
    """
    Decorator to check permissions.

    :param perms: Valid permissions that can be found on :class:`telegram.ChatMember` + is_admin. Example: `@permissions(can_delete_messages=True)`. The value does not matter.
    """
    perms = set(perms_kwargs.keys())
    perms.update(perms_args)

    def decorator(function):
        def wrapper(bot, context):
            if context.chat is not None:
                res, missing_perms = check_perms(context.chat, context.user, perms.copy())
                if res:
                    function(bot, context)
                else:
                    context.reply(context.localize(
                        "Sorry, you can't execute this command cause you lack following permissions: {}").format(
                        ', '.join(missing_perms)))

        return wrapper

    return decorator

def not_admin(function):
    """
    Decorator to check if sender is not an admin.
    """
    perms = {"is_admin"}

    def wrapper(bot, context):
        if context.chat is not None:
            res, missing_perms = check_perms(context.chat, context.user, perms.copy())
            if not res:
                function(bot, context)

    return wrapper

def my_permissions(*perms_args, **perms_kwargs):
    """
    Decorator to check bots own permissions.

    :param perms: Valid permissions that can be found on :class:`telegram.ChatMember` + is_admin. Example: `@my_permissions(can_delete_messages=True)`. The value does not matter.
    """
    perms = set(perms_kwargs.keys())
    perms.update(perms_args)
    if "is_admin" not in perms:
        perms.add("is_admin")

    def decorator(function):
        def wrapper(bot, context):
            if context.chat is not None:
                res, missing_perms = check_perms(context.chat, bot.me, perms.copy())
                if res:
                    function(bot, context)
                elif "is_admin" not in missing_perms:
                    context.reply(context.localize(
                        "Sorry, you can't execute this command cause I lack following permissions: {}").format(
                        ', '.join(missing_perms)))

        return wrapper

    return decorator


"""
BP ENTIRE time to compute: 112.161 seconds
BP SOLVE  time to compute: 110.533 seconds
FS SOLVE  time to compute: 508.476 seconds
"""

from fenics_viz      import *
from time            import time
import issm              as im
import numpy             as np
import matplotlib.pyplot as plt
import matplotlib.tri    as tri
import os

# directories for saving data :
mdl_odr = 'HO'

if mdl_odr == 'HO': mdl_pfx = 'BP'
else:               mdl_pfx = mdl_odr
plt_dir = './images/issm/' + mdl_pfx + '/'
out_dir = './results/issm/' + mdl_pfx + '/'

# create the output directory if it does not exist :
d       = os.path.dirname(out_dir)
if not os.path.exists(d):
  os.makedirs(d)

# ISMIP HOM A experiment :
md = im.model()
md.miscellaneous.name = 'ISMIP_HOM_A'

# Geometry :
print_text('::: issm -- constructing geometry :::', 'red')

# Define the geometry of the simulation :
#md = triangle(md, './exp/square.exp', 80000)
L  = 80000.0
n  = 50
md = im.squaremesh(md, L, L, n, n)
md = im.setmask(md, 'all', '')

#surface
md.geometry.surface = - md.mesh.x * np.tan(0.5*np.pi/180.0)

# base of ice sheet with 'L' the size of the side of the square :
md.geometry.base = + md.geometry.surface - 1000.0 \
                   + 500.0 * np.sin(md.mesh.x*2*np.pi/L) \
                           * np.sin(md.mesh.y*2*np.pi/L)

#thickness is the difference between surface and base :
md.geometry.thickness = md.geometry.surface - md.geometry.base

# ISMIP_HOM experiment :
md.materials.rho_ice = 910.0
md.constants.g       = 9.80665
md.constants.yts     = 31556926.0

# one friciton coefficient per node :
print_text('::: issm -- defining friction parameters :::', 'red')

md.friction.coefficient = 10 * np.ones(md.mesh.numberofvertices)
#floating_v = numpy.where(md.mask.groundedice_levelset < 0)[0]
#md.friction.coefficient[floating_v] = 0

# one friciton exponent (p,q) per element :
md.friction.p = np.ones(md.mesh.numberofelements)
md.friction.q = np.zeros(md.mesh.numberofelements)

print_text('::: issm -- construct ice rheological properties :::', 'red')

# The rheology parameters sit in the material section :

# B has one value per vertex :
n   = 3.0
spy = md.constants.yts   # s a^{-1}
A   = 1e-16              # Pa^{-n} s^{-1}
B   = (A / spy)**(-1/n)
md.materials.rheology_B = B * np.ones(md.mesh.numberofvertices)

# n has one value per element :
md.materials.rheology_n = n * np.ones(md.mesh.numberofelements)

print_text('::: issm -- set boundary conditions :::', 'red')

# Set the default boundary conditions for an ice-sheet :
md = im.SetIceSheetBC(md)  # create placeholder arrays for indicies
md.extrude(6, 1.0)
md = im.setflowequation(md, mdl_odr, 'all')

md.stressbalance.spcvx = np.nan * np.ones(md.mesh.numberofvertices)
md.stressbalance.spcvy = np.nan * np.ones(md.mesh.numberofvertices)
md.stressbalance.spcvz = np.nan * np.ones(md.mesh.numberofvertices)

# set no-slip basal velocity BC :
basal_v                         = md.mesh.vertexonbase
md.stressbalance.spcvx[basal_v] = 0.0
md.stressbalance.spcvy[basal_v] = 0.0
md.stressbalance.spcvz[basal_v] = 0.0

# set periodic lateral boundary conditions :
minX = np.where(md.mesh.x == 0)[0] + 1
maxX = np.where(md.mesh.x == L)[0] + 1

# for y, maxX and minX should be excluded :
minY = np.where(np.logical_and(md.mesh.y == 0,
                               md.mesh.x != L,
                               md.mesh.x != 0))[0] + 1
maxY = np.where(np.logical_and(md.mesh.y == L,
                               md.mesh.x != L,
                               md.mesh.x != 0))[0] + 1

# set the nodes that should be paired together :
md.stressbalance.vertex_pairing = np.array([np.append(minX, minY),
                                            np.append(maxX, maxY)]).T

# solve :
print_text('::: issm -- solving :::', 'red')

md.cluster = im.generic('name', im.gethostname(), 'np', 1)
md.verbose = im.verbose('convergence', True)

t0         = time()             # start the timer
md         = im.solve(md, 'Stressbalance')
print_text("total time to compute: %g seconds" % (time() - t0), 'red', 1)

# plot the results :
print_text('::: issm -- plotting :::', 'red')

p   = md.results.StressbalanceSolution.Pressure[md.mesh.vertexonbase]
u_x = md.results.StressbalanceSolution.Vx[md.mesh.vertexonsurface]
u_y = md.results.StressbalanceSolution.Vy[md.mesh.vertexonsurface]
u_z = md.results.StressbalanceSolution.Vz[md.mesh.vertexonsurface]
u   = np.array([u_x.flatten(), u_y.flatten(), u_z.flatten()])

# save the mesh coordinates and data for interpolation with CSLVR :
np.savetxt(out_dir + 'x.txt',   md.mesh.x2d)
np.savetxt(out_dir + 'y.txt',   md.mesh.y2d)
np.savetxt(out_dir + 'u_x.txt', u[0])
np.savetxt(out_dir + 'u_y.txt', u[1])
np.savetxt(out_dir + 'u_z.txt', u[2])
np.savetxt(out_dir + 'p.txt',   p)

U_mag  = np.sqrt(u[0]**2 + u[1]**2 + u[2]**2 + 1e-16)
U_lvls = np.array([U_mag.min(), 10, 20, 30, 40, 50, 60, 70, 80, U_mag.max()])

tp_kwargs     = {'linestyle'      : '-',
                 'lw'             : 1.0,
                 'color'          : 'k',
                 'alpha'          : 0.5}

quiver_kwargs = {'pivot'          : 'middle',
                 'color'          : 'k',
                 'scale'          : None,
                 'alpha'          : 0.8,
                 'width'          : 0.005,
                 'headwidth'      : 3.0,
                 'headlength'     : 3.0,
                 'headaxislength' : 3.0}

plot_variable(u                   = u,
              name                = 'U',
              direc               = plt_dir,
              coords              = (md.mesh.x2d, md.mesh.y2d),
              cells               = md.mesh.elements2d - 1,
              figsize             = (8,8),
              cmap                = 'viridis',
              scale               = 'lin',
              numLvls             = 10,
              levels              = U_lvls,
              levels_2            = None,
              umin                = None,
              umax                = None,
              plot_tp             = True,
              tp_kwargs           = tp_kwargs,
              show                = False,
              hide_x_tick_labels  = False,
              hide_y_tick_labels  = False,
              xlabel              = r'$x$',
              ylabel              = r'$y$',
              equal_axes          = True,
              title               = r'$\underline{u} |_S^{\mathrm{ISSM}}$',
              hide_axis           = False,
              colorbar_loc        = 'right',
              contour_type        = 'filled',
              extend              = 'neither',
              ext                 = '.pdf',
              normalize_vec       = True,
              plot_quiver         = False,
              quiver_kwargs       = quiver_kwargs,
              res                 = 150,
              cb                  = True,
              cb_format           = '%g')

u_z_tit  = r'$u_z |_S^{\mathrm{ISSM}}$'
u_z_lvls = np.array([u_z.min(), -4, -3, -2, -1,
                                 1,  2,  3,  4, u_z.max()])

plot_variable(u                   = u_z.flatten(),
              name                = 'u_z',
              direc               = plt_dir,
              coords              = (md.mesh.x2d, md.mesh.y2d),
              cells               = md.mesh.elements2d - 1,
              figsize             = (8,8),
              cmap                = 'RdGy',
              scale               = 'lin',
              numLvls             = 10,
              levels              = u_z_lvls,
              levels_2            = None,
              umin                = None,
              umax                = None,
              plot_tp             = False,
              tp_kwargs           = tp_kwargs,
              show                = False,
              hide_x_tick_labels  = False,
              hide_y_tick_labels  = False,
              xlabel              = r'$x$',
              ylabel              = r'$y$',
              equal_axes          = True,
              title               = u_z_tit,
              hide_axis           = False,
              colorbar_loc        = 'right',
              contour_type        = 'filled',#'lines',
              extend              = 'neither',
              ext                 = '.pdf',
              normalize_vec       = False,
              plot_quiver         = True,
              quiver_kwargs       = quiver_kwargs,
              res                 = 150,
              cb                  = True,
              cb_format           = '%g')