#Binary search is a fast search algorithm with run-time complexity of Ο(log n).
#This search algorithm works on the principle of divide and conquer.
#For this algorithm to work properly, the data collection should be in the sorted form.
#Binary search looks for a particular item by comparing the middle most item of the collection.
#If a match occurs, then the index of item is returned.
#If the middle item is greater than the item, then the item is searched in the sub-array to the left of the middle item.
#Otherwise, the item is searched for in the sub-array to the right of the middle item.
#This process continues on the sub-array as well until the size of the subarray reduces to zero.

n=int(input("Enter the length of array: "))
print("Enter values in array : ")
a=[int(input()) for i in range(n)]
print("Array: ",a)
key=int(input("Enter the element to be search:" ))
found=0;low=0;high=n-1
while low<=high:
    mid=(low+high)//2
    if key<a[mid]:
        high=mid-1
    elif key>a[mid]:
        low=mid+1
    elif key==a[mid]:
        print("Element found at location:", mid)
        found = 1
        break
if not found:
    print("Element not found")

#Time complexity : O(log2n)
#space complexity : O(1)


import asyncio
import datetime
import functools
import logging
import math
from collections import OrderedDict
from typing import Union
from contextlib import contextmanager

# Support for 3.6, for now add dependency manually
try:
    from contextlib import asynccontextmanager
except ImportError:
    from async_generator import asynccontextmanager

log = logging.getLogger(__name__.split('.')[0])
log.setLevel(logging.INFO)

class CloudWatchAsyncMetrics:

    dimensions = None
    client = None
    namespace = None
    reporter = None
    debug_level = 0

    @classmethod
    def with_namespace(cls, namespace):
        cls.namespace = namespace
        return cls

    @classmethod
    def with_client(cls, client):
        cls.client = client
        return cls

    @classmethod
    def setup_client(cls):
        if cls.client is None:
            import aioboto3
            cls.client = aioboto3.client('cloudwatch')
        return cls

    @classmethod
    def with_reporter(cls, reporter):
        cls.reporter = reporter
        return cls

    @classmethod
    def with_debug_level(cls, level):
        cls.debug_level = level
        if level > 0:
            log.setLevel(logging.DEBUG)
        return cls

    @classmethod
    async def put_metric(cls, **metric_data):
        try:
            return await cls.reporter.put_metric(**metric_data)
        except AttributeError:
            return False

    @classmethod
    async def put_statistic(cls, name, dimensions, value, unit=None):
        try:
            return await cls.reporter.put_statistic(name, dimensions, value, unit)
        except AttributeError:
            return False

    @classmethod
    async def send_metric(cls, **metric_data):

        try:
            if metric_data.get('Timestamp') is None:
                metric_data['Timestamp'] = datetime.datetime.now()
            cls.setup_client()
            return await cls.client.put_metric_data(
                Namespace=cls.namespace,
                MetricData=[{**metric_data}]
            )
        except AttributeError:
            return False

    @classmethod
    def with_monitored_dimension(cls, dimension, value):
        if cls.dimensions is None:
            cls.dimensions = {}
        cls.dimensions[dimension] = value
        return cls

    @classmethod
    def monitored_task(cls, func, name='transaction'):

        @contextmanager
        def monitor():
            previous_dimensions = cls.dimensions
            cls.dimensions = None
            start = datetime.datetime.now()
            yield
            elapsed = datetime.datetime.now() - start
            asyncio.run_coroutine_threadsafe(
                cls.put_statistic(
                    name=name, dimensions=cls.dimensions, value=elapsed.microseconds, unit='Microseconds'),
                asyncio.get_event_loop()
            )
            cls.dimensions = previous_dimensions

        @asynccontextmanager
        async def async_monitor():
            previous_dimensions = cls.dimensions
            cls.dimensions = None
            start = datetime.datetime.now()
            yield
            elapsed = datetime.datetime.now() - start
            await cls.put_statistic(
                name=name, dimensions=cls.dimensions, value=elapsed.microseconds, unit='Microseconds')
            cls.dimensions = previous_dimensions

        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            if not asyncio.iscoroutinefunction(func):
                with monitor():
                    return func(*args, **kwargs)
            else:
                async def tmp():
                    async with async_monitor():
                        return await func(*args, **kwargs)

                return tmp()

        return wrapper

class CloudWatchAsyncMetricReporter:

    MAX_METRICS_PER_REPORT = 20

    def __init__(self, report_interval=30):

        self.metrics = {}
        self.statistics = {}
        self.report_interval = report_interval
        self.sleep_task = None
        self.report_task = None

        self.lock = asyncio.Lock()

        self.stopped = False

    async def run(self):
        if self.report_interval:
            self.report_task = asyncio.create_task(self.report())
            log.debug('Reporting metrics to CloudWatch every {} sec'.format(self.report_interval))

    def stop(self):
        if self.sleep_task is not None:
            self.sleep_task.cancel()
        self.stopped = True

    async def put_metric(self, **metric_data):
        async with self.lock:
            name = metric_data['MetricName']
            dimensions = metric_data.get('Dimensions')
            metric_id = Metric.generate_id(name, dimensions)
            metric = self.metrics.get(metric_id)
            if metric is None:
                self.metrics[metric_id] = MetricSeries(name=name, dimensions=dimensions, unit=metric_data.get('Unit'))
                metric = self.metrics[metric_id]
            metric.add_value(metric_data['Value'])

        return True

    async def put_statistic(self, name, dimensions, value, unit=None):
        async with self.lock:
            metric_id = Metric.generate_id(name, dimensions)
            stat = self.statistics.get(metric_id)
            if stat is None:
                self.statistics[metric_id] = StatisticSeries(name=name, dimensions=dimensions, unit=unit)
                stat = self.statistics[metric_id]
            stat.add_value(value)

        return True

    async def report(self):

        while True:
            try:
                if self.stopped:
                    log.debug('reporter stopped')
                    return
                self.sleep_task = asyncio.create_task(asyncio.sleep(self.report_interval))
                try:
                    await self.sleep_task
                except asyncio.CancelledError:
                    log.debug('sleep cancelled; reporter stopped')
                    return
                if len(self.metrics) + len(self.statistics) == 0:
                    log.debug('nothing to report')
                    continue
                await self._report()
            except Exception as e:
                log.error(e)

    def _calculate_statistics(self) -> []:
        statistics = [stat.to_repr() for name, stat in self.statistics.items()]
        self.statistics = {}
        return list(filter(None.__ne__, statistics))

    def _calculate_metrics(self) -> []:
        metrics = [data.to_repr() for name, data in self.metrics.items()]
        self.metrics = {}
        return list(filter(None.__ne__, metrics))

    async def _report(self):
        CloudWatchAsyncMetrics.setup_client()
        async with self.lock:
            num_metrics = len(self.metrics) + len(self.statistics)
            metric_data = self._calculate_metrics() + self._calculate_statistics()
            for n in range(math.ceil(len(metric_data) / CloudWatchAsyncMetricReporter.MAX_METRICS_PER_REPORT)):
                if CloudWatchAsyncMetrics.debug_level > 1:
                    log.debug('Namespace: {})'.format(CloudWatchAsyncMetrics.namespace))
                    log.debug('Metric data: {}'.format(
                        metric_data[n * CloudWatchAsyncMetricReporter.MAX_METRICS_PER_REPORT:
                                           (n + 1) * CloudWatchAsyncMetricReporter.MAX_METRICS_PER_REPORT]))
                response = await CloudWatchAsyncMetrics.client.put_metric_data(
                    Namespace=CloudWatchAsyncMetrics.namespace,
                    MetricData=metric_data[n * CloudWatchAsyncMetricReporter.MAX_METRICS_PER_REPORT:
                                           (n + 1) * CloudWatchAsyncMetricReporter.MAX_METRICS_PER_REPORT]
                )
                if response.get('ResponseMetadata', {}).get('HTTPStatusCode') != 200:
                    log.warning('Failed reporting metrics to CloudWatch; response={}'.format(
                        response
                    ))
            log.debug('Reported {} metrics to CloudWatch'.format(num_metrics))

    async def flush(self):
        await self._report()

class MetricDimension:

    def __init__(self, dimensions):

        self.dimensions = OrderedDict(dimensions) if dimensions is not None else None
        self.dim_id = MetricDimension.generate_id(self.dimensions)

    def to_repr(self) -> Union[list, None]:
        if self.dimensions is None:
            return None
        return [{'Name': name, 'Value': value} for name, value in self.dimensions.items()]

    @staticmethod
    def generate_id(dimensions) -> str:
        if dimensions is not None:
            return '&'.join(['%s=%s' % (a, b) for a, b in dimensions.items()])
        else:
            return ''

class Metric:

    def __init__(self, name, dimensions, value, unit=None):

        self.name = name
        self.dimensions = MetricDimension(dimensions)
        self.value = value
        self.unit = unit

        self.metric_id = Metric.generate_id(self.name, self.dimensions)

    def to_repr(self) -> dict:
        data = {
            'MetricName': self.name,
            'Timestamp': datetime.datetime.now(),
            'Value': self.value
        }
        dimensions = self.dimensions.to_repr()
        if dimensions is not None:
            data['Dimensions'] = dimensions
        if self.unit is not None:
            data['Unit'] = self.unit
        return data

    @staticmethod
    def generate_id(name: str, dimensions) -> str:
        if isinstance(dimensions, MetricDimension):
            return '%s?%s' % (name, dimensions.dim_id)
        else:
            return '%s?%s' % (name, MetricDimension.generate_id(dimensions))

class MetricSeries:

    def __init__(self, name, dimensions=None, unit=None):

        self.metric = Metric(name=name, dimensions=dimensions, value={}, unit=unit)
        self.metric_id = self.metric.metric_id

    def add_value(self, value) -> None:
        values = self.metric.value
        count = values.get(value, 0) + 1
        values[value] = count

    def to_repr(self) -> Union[dict, None]:
        data = self.metric.to_repr()
        del data['Value']
        data['Values'] = []
        data['Counts'] = []
        for value, count in self.metric.value.items():
            data['Values'].append(value)
            data['Counts'].append(count)

        return data

class StatisticSeries(MetricSeries):

    def __init__(self, name, dimensions=None, unit=None):

        super().__init__(name=name, dimensions=dimensions, unit=unit)
        self.metric.value = []

    def to_repr(self) -> Union[dict, None]:
        if len(self.metric.value) == 0:
            return None
        data = self.metric.to_repr()
        del data['Value']
        data['StatisticValues'] = {
            'SampleCount': len(self.metric.value),
            'Sum': sum(self.metric.value),
            'Minimum': min(self.metric.value),
            'Maximum': max(self.metric.value)
        }

        return data

    def add_value(self, value) -> None:
        self.metric.value.append(value)


import json
import select
import socket
import time

from connectors import BaseConnector

class SocketsConnector(BaseConnector):

    class ReceivingChannel(BaseConnector.ReceivingChannel):

        def __init__(self, connector):
            super(SocketsConnector.ReceivingChannel, self).__init__(connector)
            self.socket = connector.socket

        @staticmethod
        def recv_timeout(sock, bytes_to_read, timeout_seconds):
            sock.setblocking(0)
            ready = select.select([sock], [], [], timeout_seconds)
            if ready[0]:
                return sock.recv(bytes_to_read)

            return False

        def run(self):
            while self.status:
                try:
                    data = self.recv_timeout(self.socket, 3024, 5)

                    if not data:
                        continue

                    self.connector.last_response_time = time.time()

                    udata = data.decode('utf-8')
                    json_data = json.loads(udata)

                    if 'event' in json_data and self.connector.values_accepted:
                        print('Receive: ', json_data)
                        self.connector.events.append(json_data)

                    if 'response' in json_data and json_data['id'] in self.connector.request_ids:
                        print('Receive: ', json_data)
                        self.connector.request_ids.remove(json_data['id'])
                        self.connector.responses.append(json_data)

                except json.decoder.JSONDecodeError:
                    pass
                except (ConnectionError, ConnectionResetError, ConnectionRefusedError):
                    self.connector.connected = False

    def __init__(self, controller):
        super(SocketsConnector, self).__init__(controller)
        self.name = 'Sockets'

        self.socket = None

    def init_connection(self):
        try:
            self.socket = socket.socket()
            self.socket.settimeout(1.5)
            self.socket.connect(tuple(BaseConnector.SOCKET_CONFIG))
            self.socket.settimeout(None)

            super().init_connection()

            self.start_io_threads()

            if self.get_response(self.send_request({'request': 'set_ready', 'args': {'status': True}})):
                self.connected = True
                self.start_alive_thread()
        except:
            self.connected = False

        return self.connected

    def process_task(self, task, args, kwargs):

        if not self.socket:
            return False

        try:
            self.socket.send(json.dumps(task).encode())
        except Exception:
            self.connected = False

        return self.connected


# Day 64 coding Statement: Amit and Feedback

tc=int(input('Enter number of testcases: '))

for i in range(tc):
    ss_arr=[]
    fb=input('Enter your geeky feedback: ')
    f,l=0,3
    for j in range(len(fb)):
        ss=fb[f:l]
        ss_arr.append(ss)
        f+=1;l+=1
    if ('010' or '101') in ss_arr:
        print('GOOD')
    else:
        print('BAD')


#problem link : https://leetcode.com/explore/featured/card/fun-with-arrays/526/deleting-items-from-an-array/3248/

class Solution:
    def removeDuplicates(self, nums: List[int]) -> int:
        if len(nums)==0: return 0
        i  = 0
        for j in range(1,len(nums)):
            if nums[j]!=nums[i]:
                i += 1
                nums[i]=nums[j]

        return i+1


# -*- coding: utf-8 -*-
"""
Created on Wed Nov 18 19:16:32 2020

@author: SUBHAM
"""

try:
    list = list(input("Enter elements separated by a space: ").split())
    list.sort()
    print("The sorted list is: ", list)

except:
    print("Enter homogeneous elements!!")


from flask import Flask, render_template, redirect, jsonify

#dependencies
import sqlalchemy
from sqlalchemy.ext.automap import automap_base
from sqlalchemy.orm import Session
from sqlalchemy import create_engine
from sqlalchemy import func

import pandas as pd
import numpy as np
import datetime

app = Flask(__name__)

engine = create_engine("sqlite:///Resources/hawaii.sqlite?check_same_thread=False")
Base = automap_base()
Base.prepare(engine, reflect=True)

Measurements = Base.classes.measurement
Stations = Base.classes.station
session = Session(engine)

@app.route("/")
#List all available routes
def home ():
	return (
		f"Welcome to the Surfs Up
"
		f"Available Routes:
"
		f"/api/v1.0/precipitation
"
		f"/api/v1.0/stations
"
		f"/api/v1.0/tobs
"
		f"/api/v1.0/(start)
"
		f"/api/v1.0(start)/(end)"
	)

@app.route("/api/v1.0/precipitation")
def precipitation():
	#Query for the dates and temperature observations from the last year.
	results = session.query(Measurements.date,Measurements.prcp).filter(Measurements.date >= "08-23-2017").all()

	year_prcp = list(np.ravel(results))
	#results.___dict___
	#Create a dictionary using 'date' as the key and 'prcp' as the value.
	"""year_prcp = []
	for result in results:
		row = {}
		row[Measurements.date] = row[Measurements.prcp]
		year_prcp.append(row)"""

	return jsonify(year_prcp)

@app.route("/api/v1.0/stations")
def stations():
	#return a json list of stations from the dataset.
	results = session.query(Stations.station).all()

	all_stations = list(np.ravel(results))

	return jsonify(all_stations)

@app.route("/api/v1.0/tobs")
def temperature():
	#Return a json list of Temperature Observations (tobs) for the previous year
	year_tobs = []
	results = session.query(Measurements.tobs).filter(Measurements.date >= "08-23-2017").all()

	year_tobs = list(np.ravel(results))

	return jsonify(year_tobs)

@app.route("/api/v1.0/<start>")
def start_trip_temp(start):

	start_trip = []

	results_min = session.query(func.min(Measurements.tobs)).filter(Measurements.date == start).all()

	results_max = session.query(func.max(Measurements.tobs)).filter(Measurements.date == start).all()
	results_avg = session.query(func.avg(Measurements.tobs)).filter(Measurements.date == start).all()

	return jsonify(results_min,results_max, results_avg)

@app.route("/api/v1.0/<start>/<end>")

def start_end_trip(start, end):

	start_end_trip_temps = []

	results_min = session.query(func.min(Measurements.tobs)).filter(Measurements.date == start, Measurements.date == end).all()
	results_max = session.query(func.max(Measurements.tobs)).filter(Measurements.date == start, Measurements.date == end).all()
	results_avg = session.query(func.avg(Measurements.tobs)).filter(Measurements.date == start, Measurements.date == end).all()

	return jsonify(results_min,results_max, results_avg)

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


import torch
from torch import nn
import torch.optim.lr_scheduler
from torch.utils.data import WeightedRandomSampler

from loaders.dr_dataset import DRDataset
from loaders.blindness_dataset import BlindnessDataset
from models.classifier import Classifier
# import models.modules

import numpy as np
from sklearn import metrics
from collections import OrderedDict
import os

def get_dataset_class(args):
	if args.pretraining: return DRDataset
	else: return BlindnessDataset

def get_model(args):
	model = Classifier(arch=args.arch, ckpt=args.checkpoint, pool_type=args.pool_type, norm_type=args.norm_type)

	if args.pretrained_model is not None:

		if len(args.pretrained_model) != 2: raise ValueError("Invalid pretraining info.")
		save_folder, save_id = args.pretrained_model
		save_path = os.path.join("./saves", save_folder, f"save_{save_id:03d}.pth")

		state_dict = torch.load(save_path)
		if "module." in list(state_dict.keys())[0]:
			temp_state = OrderedDict()
			for k, v in state_dict.items():
				temp_state[k.split("module.")[-1]] = v
			state_dict = temp_state
		model.load_state_dict(state_dict)

	return model

def check_memory_use(args, model, device):
	model.train()
	test_input = torch.randn((args.batch_size, 3, args.img_size, args.img_size), dtype=torch.float, device=device)
	try:
		model(test_input)
	except RuntimeError as e:
		torch.cuda.empty_cache()
		model.ckpt = True
		model.sequential = False
	model(test_input)

def get_loss(args):

	if args.loss == "crossentropy":
		loss_func = nn.CrossEntropyLoss()
	elif args.loss == "mse":
		loss_func = nn.MSELoss()
	elif args.loss == "l1":
		loss_func = nn.SmoothL1Loss()
	elif args.loss == "multimargin":
		loss_func = nn.MultiMarginLoss()
	# elif args.loss == "focal":
	# 	loss_func = models.modules.FocalLoss()
	else:
		raise ValueError(f"Invalid loss function specifier: {args.loss}")

	return loss_func

def get_train_sampler(args, dataset):
	if args.balancing_method == "sampling":
		return WeightedRandomSampler(weights=dataset.example_weights, num_samples=len(dataset))
	else:
		return None

def get_scheduler(args, optimizer):
	params = args.lr_schedule_params
	if args.lr_schedule == "poly":
		gamma = params["gamma"] if "gamma" in params else 0.9
		max_iter = args.epochs
		decay_iter = 1
		return PolynomialLR(optimizer, max_iter, decay_iter, gamma)
	elif args.lr_schedule == "exp":
		gamma = params["gamma"] if "gamma" in params else 0.95
		return torch.optim.lr_scheduler.ExponentialLR(optimizer, gamma)
	elif args.lr_schedule == "step":
		step_size = params["step_size"] if "step_size" in params else 5
		gamma = params["gamma"] if "gamma" in params else 0.5
		return torch.optim.lr_scheduler.StepLR(optimizer, step_size, gamma)
	elif args.lr_schedule == "multistep":
		milestones = params["milestones"] if "milestones" in params else list(range(10, args.epochs, 10))
		gamma = params["gamma"] if "gamma" in params else 0.2
		return torch.optim.lr_scheduler.MultiStepLR(optimizer, milestones, gamma)
	elif args.lr_schedule == "cosine":
		T_max = params["period"] // 2 if "period" in params else 10
		max_decay = params["max_decay"] if "max_decay" in params else 50
		eta_min = args.initial_lr / max_decay
		return torch.optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max, eta_min)
	else:
		return ConstantLR(optimizer)

class PolynomialLR(torch.optim.lr_scheduler._LRScheduler):
	def __init__(self, optimizer, max_iter, decay_iter=1, gamma=0.9, last_epoch=-1):
		self.decay_iter = decay_iter
		self.max_iter = max_iter
		self.gamma = gamma
		super(PolynomialLR, self).__init__(optimizer, last_epoch)

	def get_lr(self):
		if self.last_epoch % self.decay_iter or self.last_epoch % self.max_iter:
			return [base_lr for base_lr in self.base_lrs]
		else:
			factor = (1 - (self.last_epoch / self.max_iter)) ** self.gamma
			return [base_lr * factor for base_lr in self.base_lrs]

class ConstantLR(torch.optim.lr_scheduler._LRScheduler):
	def __init__(self, optimizer, last_epoch=-1):
		super(ConstantLR, self).__init__(optimizer, last_epoch)

	def get_lr(self):
		return [base_lr for base_lr in self.base_lrs]


import numpy as np

import json
import sys

# Opening JSON file
data = json.load(open('search_dataset.json', encoding='utf-8'))

argsCLA = str(sys.argv[1:])
target = {39 : None, 91 : None, 93 : None}
# The target function delete the ASCII character from the list
query = str(argsCLA).translate(target)

def levenshtein_distance(word, objData):

    word1 = len(word) + 1
    word2 = len(objData) + 1
    # Returns a new array of length
    matrix = np.zeros ((word1, word2))
    # Length for the search item
    for x in range (word1):
        matrix [x, 0] = x
    # Length for the item inside the JSON
    for y in range (word2):
        matrix [0, y] = y

    # Variables x and y are needed to compare letter by letter - row and column wise.
    for x in range (1, word1):
        for y in range (1, word2):
            # If the two letter are equal the position at matrix[x,y] is the minimun value
            if word[x-1] == objData[y-1]:
                matrix [x,y] = min(
                    matrix[x-1, y] + 1,
                    matrix[x-1, y-1],
                    matrix[x, y-1] + 1
                )
            else:
                matrix [x,y] = min(
                    matrix[x-1,y] + 1,
                    matrix[x-1,y-1] + 1,
                    matrix[x,y-1] + 1
                )

    # Rounding score to decimal number
    return round(matrix[word1 - 1, word2 - 1])

def main(data, query):
    # Loop thought the JSON file and each object, name and brand, are passed inside the levenshtein_distance function to return the score
    for obj in data:
        obj["score"] = levenshtein_distance(query, obj["name"]+" "+obj["brand"])

    # Sorting returned data by score
    data.sort(key= lambda x:x['score'])
    # Slice to first ten
    first_ten = data[:10]

    for obj in first_ten:
        print(f"Score: {obj['score']}, ID: '{obj['id']}', Name: '{obj['name']}', Brand: '{obj['brand']}'")

if __name__ == "__main__":
    main(data, query)


import os,sys,json

for section in ["Train","Dev","Test"]:
  Mask = {}
  for line in open("PartialSequences/%s/Mask.txt" % section,'r'):
    line = line.split()
    Mask[line[0]] = [int(v) for v in line[1:]]
  for name in Mask:
    input = open("SimpleActions/MTurk/%s/%s" % (section, name))
    out = open("PartialSequences/%s/%s" % (section,name), 'w')
    j = json.load(open("SimpleActions/MTurk/%s/%s" % (section,name)))
    A = []
    for i in range(len(Mask[name])):
      A.append(j["block_states"][Mask[name][i]])
    j["block_states"] = A
    j["type"] = "partial"
    out.write(json.dumps(j))


import numpy as np

import matplotlib.pyplot as plt
from matplotlib import cm
from matplotlib.colors import ListedColormap

from scipy.optimize import curve_fit, fsolve

""" All the numbers are in MeVs """

# Constants (masses of proton, neutron, electron and atomic constant)
Mp = 938.2720882
Mn = 939.5654205
Me = 0.510998950
u = 931.4941024

def read_data():
    """ Reads binding energies and masses from the data file """
    nuclides = []

    with open(r"code/mass_1.mas20.txt") as file:
        # We skip the header
        for _ in range(37):
            file.readline()

        for line in file:
            nuclide = {}

            nuclide["N"] = int(line[4:9])
            nuclide["Z"] = int(line[10:14])
            nuclide["A"] = int(line[15:19])

            # Check if A = N + Z
            if nuclide["N"] + nuclide["Z"] != nuclide["A"]:
                print(f"Inconsistency at N={nuclide['N']}, Z={nuclide['Z']}")

            nuclide["symbol"] = line[20:22].strip()

            b = line[54:66]

            # We skip nonexperimental values marked by the # sign
            if b.find('#') >= 0:
                continue

            # We convert keVs into MeVs
            nuclide["b"] = float(b) / 1000
            nuclide["error"] = float(line[68:77]) / 1000

            # We calculate the mass (can be also used the last column from the data file)
            nuclide["M"] = Mn * nuclide["N"] + Mp * nuclide["Z"] - nuclide["b"] * nuclide["A"]

            nuclides.append(nuclide)

    return nuclides

def max_nza(nuclides):
    """ Returns maximum values of the neutron number, proton number and mass number """
    max_n = 0
    max_z = 0
    max_a = 0

    for nuclide in nuclides:
        max_n = max(nuclide["N"], max_n)
        max_z = max(nuclide["Z"], max_z)
        max_a = max(nuclide["A"], max_a)

    return max_n, max_z, max_a

def colormap(elements=1024):
    """ An auxiliary function to change the colormap - zero values in white, large values in black """
    cmap = cm.get_cmap("jet", elements)
    cmap = cmap(np.linspace(0, 1, elements))
    cmap[:1, :] = [1, 1, 1, 1]        # Zero values (usually not measured values)
    cmap[-1:, :] = [0, 0, 0, 1]       # Large values
    cmap = ListedColormap(cmap)

    return cmap

def convert_2d(nuclides, name="b"):
    """ Returns the element with the given name as a 2D array """
    max_n, max_z, _ = max_nza(nuclides)

    result = np.empty((max_n + 1, max_z + 1), dtype=np.string_) if name == "symbol" else np.zeros((max_n + 1, max_z + 1))

    for nuclide in nuclides:
        result[nuclide["N"], nuclide["Z"]] = nuclide[name]

    return result

def valley_of_stability(p, max_n):
    """ Calculates the valley of stability """
    r = 0.5 * p[2] / p[3]

    def f(z, n):
        return n - z * (1 + r * (n + z)**(2/3))

    ns = np.linspace(1, max_n, max_n)
    zs = []

    for n in ns:
        zs.append(fsolve(f, n, [n])[0])

    return ns, np.array(zs)

def drip_line(p, max_n):
    """ Calculates the bottom drip line - the upper doesn't make much sense """
    ns, zs = valley_of_stability(p, max_n)

    rn = []
    rz = []

    for n, z in zip(ns, zs):
        n = int(n)
        z = int(z)

        if z % 2 == 1:
            z += 1

        while b_theory((n, z), *p) > 0:
            z -= 2

        rn.append(n)
        rz.append(z)

    return np.array(rn), np.array(rz)

def plot_b(nuclides, p=None):
    """ Plots the binding energy """
    b = convert_2d(nuclides, "b")

    plt.imshow(b.transpose(), cmap=colormap(), origin="lower", interpolation="none")

    # Line N = Z
    plt.plot([0, min(b.shape)], [0, min(b.shape)], "black")

    if p is not None:
        plt.plot(*valley_of_stability(p, b.shape[0]))
        plt.plot(*drip_line(p, b.shape[0]))

    plt.colorbar(label="MeV")
    plt.title("Binding energy per nucleon")
    plt.xlabel("N")
    plt.ylabel("Z")

    plt.show()

def sort_b(nuclides):
    """ Sorts the nuclides array according to the binding energy per nucleon """
    bs = [nuclide["b"] for nuclide in nuclides]
    return [nuclide for _, nuclide in sorted(zip(bs, nuclides))]

def deuteron_fusion(nuclides, mass):
    """ Calculates the energy obtained by fusion of mass kg of deuterium (excluding electrons) """
    m = convert_2d(nuclides, "M")
    mD = m[1, 1]
    mHe = m[2, 2]

    MeV_kg = 1E6 * 1.6021767E-19 / 2.99792E8**2
    MeV_J = 1E6 * 1.6021767E-19

    # Number of deuterons in mass
    nD = mass / (mD * MeV_kg)

    # Energy gain by the fusion of one reaction
    e1 = 2 * mD - mHe

    # Total energy
    energy_MeV = e1 * nD / 2

    # Conversion MeV to J
    energy_J = energy_MeV * MeV_J
    return energy_J

def water_fusion(nuclides, mass):
    """ Calculates the energy obtained by fusion of mass kg of deuterium (excluding electrons) """
    m = convert_2d(nuclides, "M")
    mD = m[1, 1]
    mHe = m[2, 2]

    MeV_kg = 1E6 * 1.6021767E-19 / 2.99792E8**2
    MeV_J = 1E6 * 1.6021767E-19

    # Molar weight [g / mol] of watter
    h2o_mol = 18.015
    NA = 6.0221E23

    # Number of molecules
    n_h2o = 1000 * mass / (h2o_mol / NA)

    # Number of D2O
    n_d2o = 160E-6 * n_h2o

    # Energy gain by the fusion of one reaction
    e1 = 2 * mD - mHe

    # Total energy
    energy_MeV = e1 * n_d2o

    # Conversion MeV to J
    energy_J = energy_MeV * MeV_J
    return energy_J

def alpha(nuclides):
    """ Finds all possible nuclides that can decay via alpha process """

    masses = convert_2d(nuclides, "M")

    # Hellium - alpha particle
    M_alpha = masses[2, 2]

    alpha = np.zeros_like(masses)

    for nuclide in nuclides:
        n = nuclide["N"]
        z = nuclide["Z"]

        # We don't have data
        if masses[n, z] == 0:
            continue
        if n <= 2 or z <= 2 or masses[n - 2, z - 2] == 0:
            continue

        if masses[n, z] - M_alpha > masses[n - 2, z - 2]:
            alpha[n, z] = 1
        else:
            alpha[n, z] = 2

    plt.imshow(alpha.transpose(), cmap=colormap(), origin="lower", interpolation="none")
    plt.title("Possible alpha decay (in green)")
    plt.xlabel("N")
    plt.ylabel("Z")

    plt.show()

def plot_magic(max_n, max_z):
    """ Plots the magic numbers """
    magic = [2, 8, 20, 28, 40, 50, 82, 126]

    for m in magic:
        if m < max_n:
            plt.plot([m, m], [0, max_z], "gray", lw=1)
        if m < max_z:
            plt.plot([0, max_n], [m, m], "gray", lw=1)

def beta(nuclides):
    """ Finds all possible nuclides that can decay via beta or beta+ process """
    max_n, max_z, _ = max_nza(nuclides)
    masses = convert_2d(nuclides, "M")
    beta = np.zeros_like(masses)

    for nuclide in nuclides:
        n = nuclide["N"]
        z = nuclide["Z"]

        # We don't have data
        if masses[n, z] == 0:
            continue
        if z >= max_z or masses[n - 1, z + 1] == 0:
            continue
        if n >= max_n or masses[n + 1, z - 1] == 0:
            continue

        if n > 1 and masses[n, z] - Mn + Mp > masses[n - 1, z + 1]:
            beta[n, z] = 1
        elif z > 1 and masses[n, z] - Mp + Mn > masses[n + 1, z - 1]:
            beta[n, z] = 2
        else:
            beta[n, z] = 3

    plt.imshow(beta.transpose(), cmap=colormap(), origin="lower", interpolation="none")
    plt.title("Possible beta (in blue) or beta+ (in yellow) decay.")
    plt.xlabel("N")
    plt.ylabel("Z")

    plt.show()

def beta_epsilon(nuclides):
    """ Finds all possible nuclides that can decay via beta or electron capture process """
    max_n, max_z, _ = max_nza(nuclides)
    masses = convert_2d(nuclides, "M")
    beta = np.zeros_like(masses)

    for nuclide in nuclides:
        n = nuclide["N"]
        z = nuclide["Z"]

        # We don't have data
        if masses[n, z] == 0:
            continue
        if z >= max_z or masses[n - 1, z + 1] == 0:
            continue
        if n >= max_n or masses[n + 1, z - 1] == 0:
            continue

        if n > 1 and masses[n, z] > masses[n - 1, z + 1] + Me:
            beta[n, z] = 1
        elif z > 1 and masses[n, z] + Me > masses[n + 1, z - 1]:
            beta[n, z] = 2
        else:
            beta[n, z] = 3

    plt.imshow(beta.transpose(), cmap=colormap(), origin="lower", interpolation="none")
    plt.title("Possible beta (in blue) or epsilon (in yellow) decay.")
    plt.xlabel("N")
    plt.ylabel("Z")

    plt.show()

def s2n(nuclides):
    """ Two-neutron separation energy """
    masses = convert_2d(nuclides, "M")
    s = np.zeros_like(masses)

    for nuclide in nuclides:
        n = nuclide["N"]
        z = nuclide["Z"]

        # We don't have data
        if masses[n, z] == 0:
            continue
        if n < 2 or masses[n - 2, z] == 0:
            continue

        s[n, z] = masses[n - 2, z] + 2 * Mn - masses[n, z]

    plt.imshow(s.transpose(), cmap=colormap(), origin="lower", interpolation="none", vmin=0, vmax=20)
    plt.colorbar(label="keV")
    plt.title("Two-neutron separation energy")
    plt.xlabel("N")
    plt.ylabel("Z")

    plt.show()

def s2p(nuclides):
    """ Two-proton separation energy """
    masses = convert_2d(nuclides, "M")
    s = np.zeros_like(masses)

    for nuclide in nuclides:
        n = nuclide["N"]
        z = nuclide["Z"]

        # We don't have data
        if masses[n, z] == 0:
            continue
        if z < 2 or masses[n, z - 2] == 0:
            continue

        s[n, z] = masses[n, z - 2] + 2 * Mp - masses[n, z]

    plt.imshow(s.transpose(), cmap=colormap(), origin="lower", interpolation="none", vmin=0, vmax=20)
    plt.colorbar(label="keV")
    plt.title("Two-proton separation energy")
    plt.xlabel("N")
    plt.ylabel("Z")

    plt.show()

def b_theory(x, a_v, a_s, a_c, a_a, a_p):
    """ Bethe-Weizsäcker formula for the binding energy per nucleon; x = (n, z) """
    z, n = x
    a = n + z

    b = a_v - a_s * a**(-1/3) - a_c * z * z * a**(-4/3) - a_a * ((n - z) / a)**2
    delta = a_p * a**(-3/2)

    if type(z) is int:
        if z % 2 == 1 and n % 2 == 1:
            delta = -delta
        if a % 2 == 1:
            delta = 0

    else:
        for i in range(len(z)):
            if z[i] % 2 == 1 and n[i] % 2 == 1:
                delta[i] = -delta[i]
            if a[i] % 2 == 1:
                delta[i] = 0

    b += delta

    return b

def bw_fit(nuclides):
    """ Fitting the Bethe-Weizsäcker formula """
    z = []
    n = []
    b = []

    for nuclide in nuclides:
        # We skip proton, neutron and deuteron
        if nuclide["A"] < 3:
            continue

        z.append(nuclide["Z"])
        n.append(nuclide["N"])
        b.append(nuclide["b"])

    z = np.array(z)
    n = np.array(n)
    b = np.array(b)

    cf = curve_fit(b_theory, (z,n), b)

    # Found parameters
    p = cf[0]
    print(f"aV = {p[0]}, aS = {p[1]}, aC = {p[2]}, aA = {p[3]}, aP = {p[4]}")

    d = b - b_theory((z, n), *p)
    print("chi^2 =", sum(d * d))

    max_n, max_z, _ = max_nza(nuclides)
    difference = np.zeros((max_n + 1, max_z + 1))
    for i in range(len(z)):
        difference[n[i], z[i]] = d[i]

    plt.imshow(difference.transpose(), cmap=cm.seismic, origin="lower", interpolation="none", vmin=-0.2, vmax=0.2)
    plt.colorbar(label="MeV")
    plt.title("Difference b_exp - b_theory")
    plt.xlabel("N")
    plt.ylabel("Z")

    plot_magic(max_n, max_z)

    plt.show()

    return p

if __name__ == "__main__":
    nuclides = read_data()
    plot_b(nuclides)

    sorted_nuclides = sort_b(nuclides)

    # Five elements with the highest binding energy
    for i in range(5):
        print(sorted_nuclides[-i - 1])

    print("Burning 1g of D gives", deuteron_fusion(nuclides, 0.001) / 3600000, "kWh")
    print("Burning 1g of water gives", water_fusion(nuclides, 0.001) / 3600000, "kWh")

    alpha(nuclides)
    beta(nuclides)
    beta_epsilon(nuclides)
    s2n(nuclides)
    s2p(nuclides)

    p = bw_fit(nuclides)
    plot_b(nuclides, p)


from flask import Flask, render_template, Response, jsonify, request
import settings
import time
import numpy as np
import datetime
import base64
import subprocess
from flask import send_file, send_from_directory
# from flask_analytics import Analytics
# from OpenSSL import SSL

app = Flask(__name__,
            static_url_path='',
            static_folder='static',
            template_folder='templates')

# Analytics(app)

log = settings.logging

# app.config['ANALYTICS']['GOOGLE_CLASSIC_ANALYTICS']['ACCOUNT'] = 'UA-115560866-1'

@app.route('/')
def index():
    return render_template('index.html')

@app.route('/about')
def about():
    return render_template('about.html')

@app.route('/products')
def products():
    return render_template('products.html')

@app.route('/store')
def store():
    return render_template('store.html')

# @app.route('/viewCV')
# def view_resume():
#     return render_template('pdfViewer.html')

# @app.route('/downloadCV')
# def download_resume():
#     return send_file('static/other/adam_jarzebak_cv.pdf', mimetype='pdf', as_attachment=True)

@app.route('/_apiQuery')
def api_query_task():
    query = request.args.get('apiQ0', "", type=str).strip()
    global color

    reply = ""

    if query == "color":
        color = True
        reply = "Changed to color"
    elif query == "gray":
        color = False
        reply = "Changed to gray"

    return jsonify(result=reply)

# context = SSL.Context(SSL.SSLv23_METHOD)
# context.use_privatekey_file('/etc/letsencrypt/live/adam.sobmonitor.org/privkey.pem')
# context.use_certificate_file('/etc/letsencrypt/live/adam.sobmonitor.org/fullchain.pem')

if __name__ == '__main__':
    # app.run(host='0.0.0.0', port=443, threaded=True, ssl_context=('/etc/letsencrypt/live/adam.sobmonitor.org/fullchain.pem','/etc/letsencrypt/live/adam.sobmonitor.org/privkey.pem'))
    app.run(host='0.0.0.0', port=3000, threaded=True, debug=False)
    log.debug("Started up analysis app")


import torch
import torch.nn as nn
import torch.nn.functional as F
# from torchsummary import summary

#We are tesing our model on MNIST dataset which is 1x28x28 insize so we have to change C5 layer in FC layer becasue at this stage
#pixel size would be 16x5x5 so we can not apply kernel of 5x5

class lenet(nn.Module):
    def __init__(self):
        super(lenet,self).__init__()
        #Here, we are plementing those layers which are having learnable parameters.
        #Start implementation of Layer 1 (C1) which has 6 kernels of size 5x5 with padding 0 and stride 1

        self.conv1 = nn.Conv2d(in_channels=1,out_channels=6,kernel_size=(5,5))

        #Start implementation of Layer 3 (C3) which has 16 kernels of size 5x5 with padding 0 and stride 1

        self.conv2 = nn.Conv2d(in_channels = 6, out_channels = 16,kernel_size = (5,5))

        #Start implementation of Layer 5 (C5) which is basically flattening the data

        self.L1 = nn.Linear(256, 120)

        #Start implementation of Layer 6 (F6) which has 85 Linear Neurons and input of 120

        self.L2 = nn.Linear(120,84)

        #Start implementation of Layer 7 (F7) which has 10 Linear Neurons and input of 84

        self.L3 = nn.Linear(84,10)

        #We have used pooling of size 2 and stride 2 in this architecture

        self.pool = nn.AvgPool2d(kernel_size = 2, stride = 2)

        #We have used tanh as an activation function in this architecture so we will use tanh at all layers excluding F7.
        self.act = nn.Tanh()

    #Now we will implement forward function to produce entire flow of the architecture.

    def forward(self,x):
        x = self.conv1(x)
        #We have used tanh as an activation function in this architecture so we will use tanh at all layers excluding F7.
        x = self.act(x)
        #Now this will be passed from pooling
        x = self.pool(x)
        #Next stage is convolution
        x = self.conv2(x)
        x = self.act(x)
        x = self.pool(x)
        #next we will pass from conv3, here we will not pass data from pooling as per Architecture

        #Now the data should be flaten and it would be passed from FC layers.
        x = x.view(x.size()[0], -1)
        x = self.L1(x)
        x = self.act(x)
        x = self.L2(x)
        x = self.act(x)
        x = self.L3(x)

        return x


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

import numpy as np
import sys
import os
from matplotlib import pyplot as plt
from matplotlib import cm

import pickle
import netCDF4 as nc

import climtools_lib as ctl
import climdiags as cd

from matplotlib.colors import LogNorm
from datetime import datetime

from scipy import stats
import pandas as pd

plt.rcParams['xtick.labelsize'] = 15
plt.rcParams['ytick.labelsize'] = 15
titlefont = 24
plt.rcParams['figure.titlesize'] = titlefont
plt.rcParams['axes.titlesize'] = 28
plt.rcParams['axes.labelsize'] = 18

#############################################################################
cart_in = '/data-hobbes/fabiano/WR_CMIP6/'

yr10 = 10 # length of running mean
#dtrtyp = 'light'
dtrtyp = 'histrebase'
cart_out_orig = '/home/fabiano/Research/lavori/CMIP6/cmip6_vs_cmip5_refEOF/'
ctl.mkdir(cart_out_orig)

ye1 = 1964
ye2 = 2005

cart_out_orig = cart_out_orig + 'ref_{}_{}/'.format(ye1, ye2)
ctl.mkdir(cart_out_orig)

file_hist_refEOF = cart_in + 'out_NEW_cmip6_hist_NDJFM_{}_4clus_4pcs_{}-{}_refEOF_dtr.p'
file_hist = cart_in + 'out_NEW_cmip6_hist_NDJFM_{}_4clus_4pcs_{}-{}_refCLUS_dtr.p'

file_hist_refEOF_cmip5 = '/home/fabiano/Research/lavori/CMIP6/cmip5_hist_reb/out_cmip5_hist_reb_NDJFM_{}_4clus_4pcs_{}-{}_refEOF_dtr.p'
file_hist_cmip5 = '/home/fabiano/Research/lavori/CMIP6/cmip5_hist_reb/out_cmip5_hist_reb_NDJFM_{}_4clus_4pcs_{}-{}_refCLUS_dtr.p'

numclus = 4
reg_names_area = dict()
reg_names_area['EAT'] = ['NAO+', 'SBL', 'AR', 'NAO-']
reg_names_area['PNA'] = ['PT', 'PNA+', 'PNA-', 'BR']

clatlo = dict()
clatlo['EAT'] = (70., -20.)
clatlo['PNA'] = (70., -120.)

colormip = dict()
colormip[('cmip5', 'EAT')] = ctl.color_set(7)[4]
colormip[('cmip6', 'EAT')] = ctl.color_set(7)[0]
colormip[('cmip5', 'PNA')] = ctl.color_set(7)[3]
colormip[('cmip6', 'PNA')] = ctl.color_set(7)[6]

area = 'EAT'
plocos = dict()
res_short = dict()
for area in ['EAT', 'PNA']:
    print(area)
    cart_out = cart_out_orig + '{}_NDJFM/'.format(area)
    ctl.mkdir(cart_out)

    results_hist, results_ref = ctl.load_wrtool(file_hist.format(area, ye1, ye2))
    results_hist_refEOF, _ = ctl.load_wrtool(file_hist_refEOF.format(area, ye1, ye2))
    results_hist_cmip5, _ = ctl.load_wrtool(file_hist_cmip5.format(area, ye1, ye2))
    results_hist_refEOF_cmip5, _ = ctl.load_wrtool(file_hist_refEOF_cmip5.format(area, ye1, ye2))

    resdict = dict()
    resdict['cmip6'] = results_hist
    resdict['cmip5'] = results_hist_cmip5
    resdict['cmip6_refEOF'] = results_hist_refEOF
    resdict['cmip5_refEOF'] = results_hist_refEOF_cmip5

    var_ratio = dict()
    freqbias = dict()
    for ke in resdict:
        var_ratio[ke] = np.array([resdict[ke][mod]['var_ratio'] for mod in resdict[ke].keys()])
        plocos[('var_ratio', ke, area)] = var_ratio[ke]
        freqbias[ke] = np.array([np.mean(np.abs(resdict[ke][mod]['freq_clus']-results_ref['freq_clus'])) for mod in resdict[ke].keys()])
        plocos[('freqbias', ke, area)] = freqbias[ke]
        # freqbias_all[ke] = np.stack([resdict[ke][mod]['freq_clus']-results_ref['freq_clus'] for mod in resdict[ke].keys()])

        for mod in resdict[ke]:
            res_short[(ke, mod, area, 'var_ratio')] = resdict[ke][mod]['var_ratio']
            res_short[(ke, mod, area, 'var_ratio_bias')] = np.abs(resdict[ke][mod]['var_ratio']-results_ref['var_ratio'])
            res_short[(ke, mod, area, 'freqbias')] = np.mean(np.abs(resdict[ke][mod]['freq_clus']-results_ref['freq_clus']))
            res_short[(ke, mod, area, 'patcor')] = resdict[ke][mod]['patcor']

    print(area)
    matmods = 'access bcc cnrm canesm fgoals gfdl hadgem ipsl miroc mpi noresm'.split()
    for tip in ['', '_refEOF']:
        for cose in ['var_ratio_bias', 'freqbias', 'patcor']:
            gigi = []
            for mo in matmods:
                okke5 = [ke for ke in resdict['cmip5'+tip].keys() if mo in ke.lower()]
                okke6 = [ke for ke in resdict['cmip6'+tip].keys() if mo in ke.lower()]

                zup = np.mean([res_short[('cmip6'+tip, ke, area, cose)] for ke in okke6]) - np.mean([res_short[('cmip5'+tip, ke, area, cose)] for ke in okke5])
                gigi.append(zup)

            gigi = np.array(gigi)
            if cose == 'patcor':
                print(tip, cose, np.sum(gigi > 0), len(gigi)) # se gigi > 0 la patcor migliora (è più alta) in cmip6
            else:
                print(tip, cose, np.sum(gigi < 0), len(gigi)) # se gigi < 0 il bias migliora in cmip6
            print(gigi)

    for tip in ['', '_refEOF']:
        fig = plt.figure(figsize = (16,12))
        ax = fig.add_subplot(111)
        for cos in ['cmip5', 'cmip6']:
            ax.scatter(var_ratio[cos+tip], freqbias[cos+tip], label = cos, color = colormip[(cos, area)], s = 50)

            varme = np.mean(var_ratio[cos+tip])
            varstd = np.std(var_ratio[cos+tip])
            frme = np.mean(freqbias[cos+tip])
            frstd = np.std(freqbias[cos+tip])
            ctl.ellipse_plot(varme, frme, varstd, frstd, colors = colormip[(cos, area)], ax = ax, alpha = 0.5)

        plocos[('var_ratio', 'ref', area)] = results_ref['var_ratio']
        ax.scatter(results_ref['var_ratio'], 0, s = 250, marker = '*', color = 'black', label = 'ERA')
        plt.legend(fontsize = 20)
        plt.xlabel('Variance ratio')
        plt.ylabel('Frequency bias')
        plt.title('cmip6 vs cmip6 var_fr '+tip)
        fig.savefig(cart_out + 'var_fr_plot_{}{}.pdf'.format(area, tip))

    # taylor with clouds
    patnames = reg_names_area[area]
    for tip in ['', '_refEOF']:
        fig = plt.figure(figsize=(16,12))
        for num, patt in enumerate(patnames):
            ax = plt.subplot(2, 2, num+1, polar = True)

            obs = results_ref['cluspattern_area'][num, ...]
            #obs = results_ref['centroids'][num, ...]
            plocos[('patterns', 'ref', area, num)] = obs
            meapats = dict()
            for cos in ['cmip5', 'cmip6']:
                models = list(resdict[cos+tip].keys())
                models.sort()
                print(cos, models)
                modpats = [resdict[cos+tip][mod]['cluspattern_area'][num, ...] for mod in models]
                #modpats = [resdict[cos+tip][mod]['eff_centroids'][num, ...] for mod in models]
                plocos[('patterns', cos+tip, area, num)] = modpats
                colors = [colormip[(cos, area)]]*len(modpats)
                ctl.Taylor_plot(modpats, obs, ax = ax, title = patt, colors = colors, only_first_quarter = True, plot_ellipse = True, ellipse_color = colors[0])#, mod_points_size = taylor_mark_dim, obs_points_size = int(1.1*taylor_mark_dim), max_val_sd = max_val_sd)

        fig.savefig(cart_out + 'taylor_{}{}.pdf'.format(area, tip))

with open(cart_out_orig + 'histbiases.p', 'wb') as filo:
    pickle.dump(res_short, filo)

cart_out = cart_out_orig + 'EAT_and_PNA/'
ctl.mkdir(cart_out)

for tip in ['', '_refEOF']:
    fig = plt.figure(figsize = (24,12))
    axes = []
    for i, area in enumerate(['EAT', 'PNA']):
        ax = plt.subplot(1, 2, i+1)
        for cos in ['cmip5', 'cmip6']:
            var_ratio = plocos[('var_ratio', cos+tip, area)]
            freqbias = plocos[('freqbias', cos+tip, area)]
            ax.scatter(var_ratio, freqbias, label = cos, color = colormip[(cos, area)], s = 50)

            varme = np.mean(var_ratio)
            varstd = np.std(var_ratio)
            frme = np.mean(freqbias)
            frstd = np.std(freqbias)
            ctl.ellipse_plot(varme, frme, varstd, frstd, colors = colormip[(cos, area)], ax = ax, alpha = 0.5)

        ax.scatter(plocos[('var_ratio', 'ref', area)], 0, s = 250, marker = '*', color = 'black', label = 'ERA')
        ax.legend(fontsize = 20)
        ax.set_xlabel('Variance ratio')
        ax.set_ylabel('Frequency bias')
        ax.set_title(area)
        axes.append(ax)
    ctl.adjust_ax_scale(axes)
    fig.savefig(cart_out + 'var_fr_plot_{}.pdf'.format(tip))

    positions = [0., 0.7, 1.8, 2.5]
    # Fig. 3 with boxes
    fig = plt.figure(figsize = (16,8))
    ax1 = fig.add_subplot(121)
    ax2 = fig.add_subplot(122)
    for ax, cose, tit in zip([ax1, ax2], ['var_ratio', 'freqbias'], ['Variance ratio', 'Frequency bias']):
        allpercs = dict()
        for nu in [10, 25, 50, 75, 90]:
            allpercs['p{}'.format(nu)] = [np.percentile(plocos[cose, cos + tip, area], nu) for area in ['EAT', 'PNA'] for cos in ['cmip5', 'cmip6']]
        colorzi = [colormip[(cos, area)] for area in ['EAT', 'PNA'] for cos in ['cmip5', 'cmip6']]
        nomi = [cos+' '+aa for aa in ['EAT', 'PAC'] for cos in ['cmip5', 'cmip6']]
        ctl.boxplot_on_ax(ax, allpercs, nomi, colorzi, plot_mean = False, plot_ensmeans = False, plot_minmax = False, positions = positions)
        # ax.axhline(0, color = 'gray', linewidth = 0.5)
        ax.set_xticks([])
        #ax.set_title(tit)
        #ax.axvline(np.mean([positions[-1], positions[-2]]), color = 'lightslategray', linewidth = 0.2, linestyle = '--')

        ax.axvline(1.25, color = 'lightslategray', linewidth = 0.2, linestyle = '--')
        ax.text(0.25, 1.05, 'EAT', horizontalalignment='center', verticalalignment='center', rotation='horizontal',transform=ax.transAxes, fontsize = 20)
        ax.text(0.75, 1.05, 'PAC', horizontalalignment='center', verticalalignment='center', rotation='horizontal',transform=ax.transAxes, fontsize = 20)

    ax1.scatter(0.35, plocos[('var_ratio', 'ref', 'EAT')], color = 'black', marker = '*', s = 100)
    ax1.scatter(2.15, plocos[('var_ratio', 'ref', 'PNA')], color = 'black', marker = '*', s = 100)

    ctl.custom_legend(fig, colorzi, nomi, ncol = 2, add_space_below = 0.1)
    ax1.set_ylabel('Variance ratio')
    ax2.set_ylabel('Frequency bias')
    #plt.title('cmip6 vs cmip6 var_fr '+tip)
    fig.savefig(cart_out + 'var_fr_boxes_{}.pdf'.format(tip))

# taylor with clouds
for tip in ['', '_refEOF']:
    fig = plt.figure(figsize=(24,12))
    for i, area in enumerate(['EAT', 'PNA']):
        patnames = reg_names_area[area]
        for num, patt in enumerate(patnames):
            ax = plt.subplot(2, 4, num+1+4*i, polar = True)

            obs = plocos[('patterns', 'ref', area, num)]
            meapats = dict()
            for cos in ['cmip5', 'cmip6']:
                modpats = plocos[('patterns', cos+tip, area, num)]

                colors = [colormip[(cos, area)]]*len(modpats)
                ctl.Taylor_plot(modpats, obs, ax = ax, title = patt, colors = colors, only_first_quarter = True, plot_ellipse = True, ellipse_color = colors[0], max_val_sd = 1.6)

    ax.text(0.05, 0.75, 'EAT', horizontalalignment='center', verticalalignment='center', rotation='vertical',transform=fig.transFigure, fontsize = 35)
    ax.text(0.05, 0.25, 'PAC', horizontalalignment='center', verticalalignment='center', rotation='vertical',transform=fig.transFigure, fontsize = 35)
    fig.savefig(cart_out + 'taylor_{}.pdf'.format(tip))

    for i, area in enumerate(['EAT', 'PNA']):
        fig = plt.figure(figsize=(16,12))
        patnames = reg_names_area[area]
        for num, patt in enumerate(patnames):
            ax = plt.subplot(2, 2, num+1, polar = True)

            obs = plocos[('patterns', 'ref', area, num)]
            meapats = dict()
            for cos in ['cmip5', 'cmip6']:
                modpats = plocos[('patterns', cos+tip, area, num)]

                colors = [colormip[(cos, area)]]*len(modpats)
                marknum = ['$_{}$'.format(nu) for nu in range(10)]
                marknum += ['${}$'.format(nu) for nu in range(10, len(colors))]
                ctl.Taylor_plot(modpats, obs, ax = ax, title = patt, colors = colors, only_first_quarter = True, plot_ellipse = False, ellipse_color = colors[0], max_val_sd = 1.6, markers = marknum, mod_points_size = 70, alpha_markers = 0.6)

    # ax.text(0.05, 0.75, 'EAT', horizontalalignment='center', verticalalignment='center', rotation='vertical',transform=fig.transFigure, fontsize = 35)
    # ax.text(0.05, 0.25, 'PAC', horizontalalignment='center', verticalalignment='center', rotation='vertical',transform=fig.transFigure, fontsize = 35)
        fig.savefig(cart_out + 'taylor_{}_wnumbers_{}.pdf'.format(tip, area))

    #### IMPROVEMENTS CHECK

    #corrs_pred = np.array([Rcorr(observation, var) for var in models])


import os
import pickle
import os.path
import re
import warnings
import sys
import glob

import pandas as pd
import numpy as np
import librosa
import librosa.display
import matplotlib.pyplot as plt
from tqdm import tqdm

def make_label_dic(path_to_metadata):
    '''
    This function takes in a directory of audio files in .wav format, computes the
    mel spectrogram for each audio file, reshapes them so that they are all the
    same size, flattens them, and stores them in a dataframe.

    Genre labels are also computed and added to the dataframe.

    Parameters:
    directory (int): a directory of audio files in .wav format

    Returns:
    df (DataFrame): a dataframe of flattened mel spectrograms and their
    corresponding genre labels
    '''

    num_to_label_dic = {}
    genres_tracks = pd.read_csv(path_to_metadata, index_col=0, header=[0, 1])

    keep_cols = [('track', 'genre_top')]

    df_all = genres_tracks[keep_cols]

    df_all['track_id'] = df_all.index

    for _, row in df_all.iterrows():
        track_id = int(row['track_id'])
        genre = str(row[('track', 'genre_top')])
        num_to_label_dic[track_id] = genre

    with open('label_dic.pkl', 'wb') as f:
        pickle.dump(num_to_label_dic, f)

def make_mel_spectrogram_df(directory):

    # Creating empty lists for mel spectrograms and labels
    labels = []
    mel_specs = []

    with open('label_dic.pkl', 'rb') as f:
        num_to_label_dic = pickle.load(f)

    # Looping through each file in the directory
    for f in tqdm(glob.glob('{}/*.mp3'.format(directory))):
        try:
            y, sr = librosa.load(f)

            # Extracting the label and adding it to the list
            curr_name = os.path.basename(f)
            label = num_to_label_dic.get(int(curr_name[:-4]))

            tqdm.write(label)
            labels.append(label)

            # Computing the mel spectrograms
            spect = librosa.feature.melspectrogram(y=y, sr=sr, n_fft=2048, hop_length=1024)
            spect = librosa.power_to_db(spect, ref=np.max)

            # Adjusting the size to be 128 x 640
            if spect.shape[1] != 640:
                spect.resize(128, 640, refcheck=False)

            # Flattening to fit into dataframe and adding to the list
            spect = spect.flatten()
            mel_specs.append(spect)
        except Exception as e:
            tqdm.write(str(e))
            continue

    # Converting the lists to arrays so we can stack them
    mel_specs = np.array(mel_specs)
    labels = np.array(labels).reshape(len(labels), 1)

    # Create dataframe
    df = pd.DataFrame(np.hstack((mel_specs, labels)))

    return df

warnings.simplefilter("ignore")
if not os.path.isfile('label_dic.pkl'):
    print('making label dict')
    make_label_dic('tracks.csv')

df = make_mel_spectrogram_df(sys.argv[1])
df.to_csv('{}.csv'.format(sys.argv[1]))


import numpy as np
import torch

class BoxCoder(object):
    """
    This class encodes and decodes a set of bounding boxes into
    the representation used for training the regressors.
    """
    def __init__(self, weights=(10., 10., 10., 5., 15.)):
        self.weights = weights

    def encode(self, ex_rois, gt_rois):
        ex_widths = ex_rois[:, 2] - ex_rois[:, 0]
        ex_heights = ex_rois[:, 3] - ex_rois[:, 1]
        ex_widths = torch.clamp(ex_widths, min=1)
        ex_heights = torch.clamp(ex_heights, min=1)
        ex_ctr_x = ex_rois[:, 0] + 0.5 * ex_widths
        ex_ctr_y = ex_rois[:, 1] + 0.5 * ex_heights
        ex_thetas = ex_rois[:, 4]

        gt_widths = gt_rois[:, 2] - gt_rois[:, 0]
        gt_heights = gt_rois[:, 3] - gt_rois[:, 1]
        gt_widths = torch.clamp(gt_widths, min=1)
        gt_heights = torch.clamp(gt_heights, min=1)
        gt_ctr_x = gt_rois[:, 0] + 0.5 * gt_widths
        gt_ctr_y = gt_rois[:, 1] + 0.5 * gt_heights
        gt_thetas = gt_rois[:, 4]

        wx, wy, ww, wh, wt = self.weights
        targets_dx = wx * (gt_ctr_x - ex_ctr_x) / ex_widths
        targets_dy = wy * (gt_ctr_y - ex_ctr_y) / ex_heights
        targets_dw = ww * torch.log(gt_widths / ex_widths)
        targets_dh = wh * torch.log(gt_heights / ex_heights)
        targets_dt = wt * (torch.tan(gt_thetas / 180.0 * np.pi) - torch.tan(ex_thetas / 180.0 * np.pi))

        targets = torch.stack(
            (targets_dx, targets_dy, targets_dw, targets_dh, targets_dt), dim=1
        )
        return targets

    def decode(self, boxes, deltas, mode='xywht'):

        widths = boxes[:, :, 2] - boxes[:, :, 0]
        heights = boxes[:, :, 3] - boxes[:, :, 1]
        widths = torch.clamp(widths, min=1)
        heights = torch.clamp(heights, min=1)
        ctr_x = boxes[:, :, 0] + 0.5 * widths
        ctr_y = boxes[:, :, 1] + 0.5 * heights
        thetas = boxes[:, :, 4]

        wx, wy, ww, wh, wt = self.weights
        dx = deltas[:, :, 0] / wx
        dy = deltas[:, :, 1] / wy
        dw = deltas[:, :, 2] / ww
        dh = deltas[:, :, 3] / wh
        dt = deltas[:, :, 4] / wt

        pred_ctr_x = ctr_x if 'x' not in mode else ctr_x + dx * widths
        pred_ctr_y = ctr_y if 'y' not in mode else ctr_y + dy * heights
        pred_w = widths if 'w' not in mode else torch.exp(dw) * widths
        pred_h = heights if 'h' not in mode else torch.exp(dh) * heights
        pred_t = thetas if 't' not in mode else torch.atan(torch.tan(thetas / 180.0 * np.pi) + dt) / np.pi * 180.0

        pred_boxes_x1 = pred_ctr_x - 0.5 * pred_w
        pred_boxes_y1 = pred_ctr_y - 0.5 * pred_h
        pred_boxes_x2 = pred_ctr_x + 0.5 * pred_w
        pred_boxes_y2 = pred_ctr_y + 0.5 * pred_h

        pred_boxes = torch.stack([
            pred_boxes_x1,
            pred_boxes_y1,
            pred_boxes_x2,
            pred_boxes_y2,
            pred_t], dim=2
        )
        return pred_boxes


"""comparehist.py"""

from scipy.spatial import distance as dist
import matplotlib.pyplot as plt
import numpy as np
import argparse
import glob
import cv2

parser = argparse.ArgumentParser()
parser.add_argument("-d", "--dataset", required = True,
	help = "Path to the directory of images")
args = vars(parser.parse_args())

# initialize the index dictionary to store the image name
# and corresponding histograms and the images dictionary
# to store the images themselves
index = {}
images = {}

target = input("Enter the image filename (including .jpg): ")

# loop over the image paths
for imagePath in glob.glob(args["dataset"] + "/*.jpg"):
	# extract the image filename (assumed to be unique) and
	# load the image, updating the images dictionary
	filename = imagePath[imagePath.rfind("/") + 1:]
	image = cv2.imread(imagePath)
    # convert to RGB format for matplotlib
	images[filename] = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
	# extract a 3D RGB color histogram from the image,
	# using 8 bins per channel, normalize, and update
	# the index
	hist = cv2.calcHist([image], [0, 1, 2], None, [8, 8, 8],
		[0, 256, 0, 256, 0, 256])
	hist = cv2.normalize(hist, hist).flatten()
	index[filename] = hist

# initialize the results dictionary and the sort
# direction
results = {}
reverse = False

# loop over the index
for (k, hist) in index.items():
	# compute the distance between the two histograms
	# using the method and update the results dictionary
	d = cv2.compareHist(index[target], hist, cv2.HISTCMP_BHATTACHARYYA)
	results[k] = d
# sort the results
results = sorted([(v, k) for (k, v) in results.items()], reverse = reverse)

# import pdb; pdb.set_trace()
# calculate similarity
results_dict = dict()

for score, img in results:
    results_dict.setdefault(score, []).append(img)

# get average similarity
total_similarity = 0
for val in results_dict.keys():
    total_similarity += val
avg_similarity = total_similarity / (len(results_dict) - 1)

print("\nAverage Similarity Score : ", avg_similarity)

if (avg_similarity < 0.6):
	print("\n\nThis image is too similar to the ones you've uploaded\n\n")
	print("Please try varying the lighting, angle of the object, background.\n\n")

elif (avg_similarity >= 0.6):
	print("You uploaded an image that is different enough. Good job!\n\n")
	print("You can continue to upload more images.\n\n")

# show the query image
fig = plt.figure("Most recently uploaded image")
ax = fig.add_subplot(1, 1, 1)
ax.imshow(images[target])
plt.axis("off")
# initialize the results figure
fig = plt.figure("Results: %s" % ("Hellinger"))
fig.suptitle("Your Training Images", fontsize = 20)
# loop over the results
for (i, (v, k)) in enumerate(results):
	# show the result
	ax = fig.add_subplot(1, len(images), i + 1)
	ax.set_title("%s: %.2f" % (k, v))
	plt.imshow(images[k])
	plt.axis("off")

print("Printing all training images and similarity score.\n\n")
plt.show()


from django.shortcuts import render_to_response, redirect
from django.views.decorators.csrf import ensure_csrf_cookie
from django.template import RequestContext
from django.contrib.auth.decorators import login_required
from django.utils.translation import ugettext_lazy as _
from django.core import serializers
from django.contrib.admin.views.decorators import staff_member_required
from django.db import IntegrityError

import apps.organizations.tz as tz
import apps.kanban.tasks as kanban_tasks
import apps.projects.tasks as projects_tasks
from apps.kanban.models import KanbanStat
from util import organizationOrNone, generateProjectSlug, generateProjectPrefix, duplicatePrefix
from apps.subscription.decorators import *
from apps.account.models import Account
import apps.github_integration.utils as github_utils

from apps.emailconfirmation.models import EmailAddress

import managers as managers
import apps.kanban.managers as kanban_managers

import signals as signals
from util import reduce_burndown_data
from util import getAllocationsForIteration

import portfolio_managers

import json
import requests
import mixpanel
import math
import logging
import time

from apps.projects.calculation import onDemandCalculateVelocity

logger = logging.getLogger(__name__)

from django.conf import settings

if "notification" in settings.INSTALLED_APPS:
    from notification import models as notification
else:
    notification = None

from apps.projects.access import *
from apps.projects.models import TimeEntry, FileJob, OfflineJob
from apps.projects.forms import *

from apps.organizations.models import Organization

from apps.classic import models as classic_models

import datetime

from django.contrib import messages
from story_views import handleAddStory

botNames=['googlebot',
            'slurp',
            'twiceler',
            'msnbot',
            'kaloogabot',
            'yodaobot',
            'baiduspider',
            'bingbot',
            'speedy spider',
            'dotbot']

@login_required
@ensure_csrf_cookie
def milestones(request, project_slug):
    project = get_object_or_404( Project, slug=project_slug )
    read_access_or_403(project, request.user)
    return render_to_response("projects/milestones.html", {
       "project": project,
       "organization": project.organization
    }, context_instance=RequestContext(request))

@login_required
def wait_job(request, job_id, template="projects/job_wait.html"):
    job = OfflineJob.objects.get(id=job_id)
    if job.owner != request.user:
        raise PermissionDenied()
    return render_to_response(template, {"job": job,
                                         "url": request.GET.get("redirect_url")},
                              context_instance=RequestContext(request))

@login_required
@ensure_csrf_cookie
def story_queue(request, project_slug):
    project = get_object_or_404( Project, slug=project_slug )
    write_access_or_403(project, request.user)
    return render_to_response("projects/story_queue.html", {
       "project": project,
       "organization": project.organization
    }, context_instance=RequestContext(request))

@login_required
def project_tips(request, organization_slug, project_slug=None):
    organization = get_object_or_404(Organization, slug=organization_slug)
    if not organization.hasReadAccess(request.user):
        raise PermissionDenied('You do not have access to that organization')

    if project_slug is None:
        project = None
    else:
        project = get_object_or_404( Project, slug=project_slug )

    return render_to_response("projects/tips.html", {
       "project": project,
       "organization": organization
    }, context_instance=RequestContext(request))

@login_required
@ensure_csrf_cookie
def classic_picker(request):
    return HttpResponseRedirect(reverse('home'))
    # # If a user.account.classic_mode == CLASSIC_FORCE_CLASSIC - go to www
    # # If a user.account.classic_mode == CLASSIC_FORCE_NEW - go to org picker
    # # If a user has no new projects and does have classic projects, redirect to classic WWW immiediately.
    # # If a user has no active classic projects and does have new projects, redirect to normal homepage
    # # If a user has both, display a page prompting which they would prefer to see
    # user = request.user
    # account = Account.objects.get(user=user)
    #
    # # if account.classic_mode == Account.CLASSIC_FORCE_CLASSIC:
    # #     return HttpResponseRedirect(settings.CLASSIC_SITE_URL)
    #
    # if account.classic_mode == Account.CLASSIC_FORCE_NEW:
    #     return HttpResponseRedirect(reverse('home'))
    #
    # newProjects = 0
    # classicProjects = 0
    # for team in Team.objects.filter(members=request.user, access_type='staff'):
    #     newProjects += Project.objects.filter(organization=team.organization, active=True).count()
    #     classicProjects += classic_models.Project.objects.filter(organization=team.organization, active=True).count()
    #
    # newProjects += Project.objects.filter(teams__members=request.user, active=True).count()
    # classicProjects += classic_models.Project.objects.filter(classic_teams__team__members=request.user, active=True).count()
    #
    # # if newProjects == 0 and classicProjects > 0:
    # #     return HttpResponseRedirect(settings.CLASSIC_SITE_URL)
    #
    # if newProjects > 0 and classicProjects == 0:
    #     return HttpResponseRedirect(reverse('home'))
    #
    # return render_to_response('classic_picker.html', context_instance=RequestContext(request) )

@login_required
@ensure_csrf_cookie
def test_page(request):
    organizations = Organization.getOrganizationsForUser(request.user)
    projects = getProjectsForUser(request.user, organizations[0])
    return render_to_response('test_page.html',{
       "my_organizations": organizations[0],
       "project": projects[1].slug
      }, context_instance=RequestContext(request) )

@login_required
@ensure_csrf_cookie
def home(request, template_name="unauthenticated_homepage_2014_09.html", force_org_view=False):
    fov = request.GET.get('force_org_view', False)

    organizations = Organization.getOrganizationsForUser(request.user)
    if not force_org_view and not fov and len(organizations) == 1:
        return HttpResponseRedirect(organizations[0].redirect_to_url())

    return render_to_response("homepage.html", {
       "my_organizations": organizations,
       "now": datetime.datetime.now()
      }, context_instance=RequestContext(request))

@staff_member_required
@ensure_csrf_cookie
def user_details_by_email(request, email):
    emails = EmailAddress.objects.filter(email__contains=email)

    users = [e.user for e in emails]
    return render_to_response("projects/user_list_details.html",
                              {
                                "users":users
                              },
                              context_instance=RequestContext(request))

@staff_member_required
@ensure_csrf_cookie
def user_details_staff(request, username):
    user = User.objects.get(username=username)
    teams = user.teams.all().order_by("organization__name")
    return render_to_response("projects/user_details.html",
                              {
                                "target_user":user,
                                "teams":teams
                              },
                              context_instance=RequestContext(request))

@login_required
@ensure_csrf_cookie
def planning(request, group_slug, sub_tool="iteration"):
    planningUrl = '{}#/planning/planningcolumn'.format(
                    reverse('project_app', kwargs={'project_slug':group_slug}))
    return HttpResponseRedirect(planningUrl)

@login_required
@ensure_csrf_cookie
def activate( request, group_slug, remove_from_portfolio = None):
    project = get_object_or_404( Project, slug=group_slug )
    admin_access_or_403(project, request.user, ignore_active=True)
    if project.portfolio_level is None and project.project_type != Project.PROJECT_TYPE_PORTFOLIO:
        # non-portfolio project
        project.active = True
        project.save()
    else:
        # protfolio project
        managers.activate_project(project, remove_from_portfolio)

    managers.rebuild_project_teams_cache(project)
    managers.rebuild_project_owner_cache(project.organization, project.creator)

    #clear newsitem cache
    managers.clearNewsItemsCache(project.organization, project.slug)

    return HttpResponseRedirect( reverse("project_detail", kwargs={"group_slug":project.slug} ) )

@login_required
@ensure_csrf_cookie
def activate_portfolio( request, group_slug ):
    project = get_object_or_404( Project, slug=group_slug )
    if project.project_type != 2:
        #got a portfolio mid level project
        project = project.portfolio_level.portfolio.root

    admin_access_or_403(project, request.user, ignore_active=True)
    managers.activate_project(project)
    managers.rebuild_project_teams_cache(project)
    managers.rebuild_project_owner_cache(project.organization, project.creator)

    #clear newsitem cache
    managers.clearNewsItemsCache(project.organization, project.slug)

    return HttpResponseRedirect( reverse("project_detail", kwargs={"group_slug":project.slug} ) )

# The project admin page, this is where you can change the title, description, etc. of a project.
@login_required
@ensure_csrf_cookie
def project_admin( request, group_slug ):
    project = get_object_or_404( Project, slug=group_slug )

    admin_access_or_403(project, request.user )

    form = ProjectOptionsForm(instance=project)
    logger.debug(request.POST)
    if request.method == 'POST': # If one of the three forms on the page has been submitted...
        if request.POST.get("action") == "rebuildReports":
            kanban_tasks.scheduleRebuildStepMovements(project, request.user)

        if request.POST.get("action") == "updateIndexes":
            projects_tasks.updateProjectIndexes.delay(project.slug)

        if request.POST.get("action") == "resetBurnup":
            points = project.points_log.all().order_by("-date")
            if len(points) > 0:
                project.burnup_reset = points[0].points_status10
                project.burnup_reset_date = tz.today(project.organization)
                project.save()
            #

        if request.POST.get("action") == "updateProject":
            form = ProjectOptionsForm( request.POST, instance=project)
            logger.debug("updateProject")
            if form.is_valid(): # All validation rules pass
                form.save()
                onDemandCalculateVelocity(project)
                # logger.debug("if form.is_valid() == True")
                #request.user.message_set.create(message="Project options Saved.")
                messages.add_message(request, messages.INFO, "Project options Saved.")
                return HttpResponseRedirect(reverse("project_detail",kwargs={'group_slug':project.slug}))
            else:
                logger.debug("if form.is_valid() == False"); logger.debug(form.errors);
        if request.POST.get("action") == "moveToOrganization":
            organization = get_object_or_404( Organization, id=request.POST.get("organization_id",""))
            user = project.creator
            org = project.organization
            if project.project_type == 2:
                portfolio_managers.move_portfolio_to_org(project, organization)
            else:
                if project.organization:
                    managers.remove_project_from_teams(project)
                project.organization = organization
                project.prefix = generateProjectPrefix(project)
                if duplicatePrefix(project, organization):
                    project.prefix = generateProjectPrefix(project)
                project.save()
                portfolio_managers.remove_project_from_portfolio(project)
                portfolio_managers.clear_story_releases(project)
            owners = organization.getOwnersGroup()
            if owners:
                owners.projects.add(project)
                # update owners project list cache
                managers.rebuild_project_teams_cache(project)
            #request.user.message_set.create(message="Project moved to organization")
            # update user project list cache
            managers.rebuild_staff_teams_cache(organization)
            managers.rebuild_project_owner_cache(org, user)

            #clear newsitem cache
            managers.clearNewsItemsCache(org, project.slug)
            managers.clearNewsItemsCache(organization, project.slug)

            messages.add_message(request, messages.INFO, "Project moved to organization")
            return HttpResponseRedirect(reverse("organization_detail",kwargs={'organization_slug':organization.slug}))

        if request.POST.get("action") == "archiveProject":
            managers.archive_project(project)
            # update user project teams cache
            managers.rebuild_project_teams_cache(project)
            # update user project list cache
            managers.rebuild_project_owner_cache(project.organization, project.creator)
            #clear newsitem cache
            managers.clearNewsItemsCache(project.organization, project.slug)
            return HttpResponseRedirect( reverse("project_detail", kwargs={"group_slug":project.slug} ) )

    return HttpResponseRedirect(reverse("project_detail",kwargs={'group_slug':project.slug}))

# Returns a JSON feed for a given project/iteration that can be transformed with some javascript
# into a burn up, burn down, or stacked chart.
@login_required
@ensure_csrf_cookie
def iteration_burndown(request, group_slug, iteration_id):
    project = get_object_or_404( Project, slug=group_slug )
    read_access_or_403(project, request.user )
    iteration = get_object_or_404( Iteration, id=iteration_id )
    try:
        if iteration.start_date:
            start_date_timestamp = int((time.mktime(iteration.start_date.timetuple()) - time.timezone)*1000)
        if iteration.end_date:
            end_date_timestamp = int((time.mktime(iteration.end_date.timetuple()) - time.timezone)*1000)
    except:
        # An invalid date, nothing more we can do.
        return HttpResponse("");

    has_startdate_data = False
    has_enddate_data = False
    highest_total_points = 0
    last_total_points = 0

    points = [[],[],[],[],[],[],[],[],[],[],[],[],[]]

    for log in iteration.points_log.all():

        if iteration.start_date:
            if log.timestamp() > start_date_timestamp and not has_startdate_data and start_date_timestamp != 0:
                # If the first day isn't filled out, give it 0's
                for i in range(13):
                    points[i].append( [start_date_timestamp, 0])

        has_startdate_data = True
        last_total_points = log.points_total
        if iteration.end_date:
            if log.timestamp() == end_date_timestamp :
                has_enddate_data = True
        if highest_total_points < log.points_total:
            highest_total_points = log.points_total
        points[0].append( [log.timestamp(), log.points_total] );
        points[1].append( [log.timestamp(), log.points_status1] );
        points[2].append( [log.timestamp(), log.points_status2] );
        points[3].append( [log.timestamp(), log.points_status3] );
        points[4].append( [log.timestamp(), log.points_status4] );
        points[5].append( [log.timestamp(), log.points_status5] );
        points[6].append( [log.timestamp(), log.points_status6] );
        points[7].append( [log.timestamp(), log.points_status7] );
        points[8].append( [log.timestamp(), log.points_status8] );
        points[9].append( [log.timestamp(), log.points_status9] );
        points[10].append( [log.timestamp(), log.points_status10] );
        points[11].append( [log.timestamp(), log.time_estimated] );
        points[12].append( [log.timestamp(), log.time_estimated_completed] );

    entries = TimeEntry.objects.filter(iteration=iteration).order_by("date")
    entries_series = []
    last_day = None
    last_count = 0
    for entry in entries:
        if entry.timestamp() != last_day:
            if last_day:
                entries_series.append([last_day, last_count]);
            last_day = entry.timestamp()
            # last_count = 0 don't reset so we get cumulative counts for the charts...
        last_count += entry.minutes_spent
    if last_day:
        entries_series.append([last_day, last_count]);

    allocations = getAllocationsForIteration(project, iteration)
    allocated_time = reduce(lambda total,allocation:total+allocation.minutes_allocated, allocations, 0)

    if allocated_time != 0:
        allocated_series = [[e[0],int((allocated_time-e[1])/60)] for e in entries_series]
    else:
        allocated_series = []

    entries_series = [[e[0], int(e[1]/60)] for e in entries_series]

    if not has_enddate_data and iteration.end_date:
        points[0].append( [end_date_timestamp, last_total_points])

    # TODO - filter out time entries not in date ranges.

    # Filter out stuff too early
    if iteration.start_date:
        for i in range(13):
            points[i] = filter(lambda x:x[0]>=start_date_timestamp, points[i])
            entries_series = filter(lambda x:x[0]>=start_date_timestamp, entries_series)

    # Filter out stuff too late
    if iteration.end_date:
        for i in range(13):
            points[i] = filter(lambda x:x[0]<=end_date_timestamp, points[i])
            entries_series = filter(lambda x:x[0]<=end_date_timestamp, entries_series)

    labels = project.statuses()
    labels = ["Total Points"] + list(labels) + ["Estimated Hours", "Completed"]

    # logger.debug( filter(lambda x:x[1]>0,points[11]))
    # logger.debug( filter(lambda x:x[1]>0,points[12]))

    # Convert minutes to hours
    points[11] = [ [d[0],d[1]/60] for d in points[11]]
    points[12] = [ [d[0],d[1]/60] for d in points[12]]

    data = [0] * 15
    for i in range(13):
        data[i] = {"label":labels[i], "data":reduce_burndown_data(points[i])}

    data[11]["hourseries"] = True
    data[12]["hourseries"] = True

    for i in range(1,11):
        data[i]["stack"] = True
        data[i]["statusType"] = i - 1

    # yaxis = 2 = the hourly axis
    data[11]["yaxis"] = 2;
    data[12]["yaxis"] = 2;
    data[13] = {"hourseries":True,"yaxis":2, "label":"Hours Spent", "data":entries_series, "lines":{ "show": True, "fill": False, "opacity":0.5 }, "points":{"radius":2}}
    data[14] = {"hourseries":True,"yaxis":2, "label":"Hours Left", "data":allocated_series, "lines":{ "show": True, "fill": False, "opacity":0.5 }, "points":{"radius":2}}

    json_serializer = serializers.get_serializer("json")()
    result = json.dumps(data)

    if highest_total_points == 0:
        return HttpResponse("[]")

    return HttpResponse(result) #, mimetype='application/json'

# Returns a JSON feed for a given project that can be transformed with some javascript
# into a burn up chart.
@login_required
@ensure_csrf_cookie
def project_burndown(request, group_slug):
    project = get_object_or_404( Project, slug=group_slug )
    read_access_or_403(project, request.user )
    total_points = [];
    claimed_points = [];
    if project.burnup_reset_date == None:
        points_log = project.points_log.all()
    else:
        points_log = project.points_log.filter(date__gte=project.burnup_reset_date)

    for log in points_log:
        total_points.append( [log.timestamp(), max(0,log.points_total - project.burnup_reset)] );
        claimed_points.append( [log.timestamp(), max(0,log.points_status10 - project.burnup_reset)] );

    total_stats = { "label":"Total Points", "data":reduce_burndown_data(total_points)}
    claimed_stats = { "label":"Claimed Points", "data":reduce_burndown_data(claimed_points)}

    json_serializer = serializers.get_serializer("json")()
    result = json.dumps([ total_stats , claimed_stats ])
    return HttpResponse(result) #, mimetype='application/json'

# Form and handler for creating a new project.
@login_required
@ensure_csrf_cookie
def create(request, group_slug, form_class=ProjectForm, template_name="projects/create.html", project_type="standard"):
    organization = get_object_or_404(Organization, slug=group_slug)

    personal = (project_type == "personal")

    if not (organization.hasStaffAccess(request.user) or personal):
        raise PermissionDenied()

    team_options = [(team.id, team.name) for team in organization.teams.all()]
    project_options = [(project.id, project.name) for project in organization.projects.all().filter(personal=False, project_type=1)]
    workflow_options = [('continuous', 'Continuous'), ('iterative', 'Iterative')]
    if project_options:
        project_options.insert(0,(0, 'None'))
    project_form = form_class(request.POST or None,
                                team_options=team_options,
                                project_options=project_options,
                                personal=personal,
                                workflow_options=workflow_options)

    admin_organizations = Organization.getOrganizationsForUser( request.user ) # The user can create projects in organizations the user is an admin in.
    if project_form.is_valid():
        project = managers.create_project(project_form.cleaned_data['name'],
                                   organization,
                                   request.user,
                                   personal,
                                   project_form.cleaned_data.get('Teams',None),
                                   Project.PROJECT_TYPE_KANBAN,
                                   project_form.cleaned_data.get('Workspace', None)
                                   )
        project_flow = project_form.cleaned_data.get('Workspace Flow', None)
        if project is not None and project_flow is not None and project_flow == 'continuous':
            kanban_managers.initContinousProject(project)

        if project is not None:
            mp = mixpanel.Mixpanel(settings.MIXPANEL_TOKEN)
            mp.track(organization.slug, 'Create Project')

            managers.clearNewsItemsCache(organization, project.slug)
            return HttpResponseRedirect(project.get_absolute_url())
        else:
            #request.user.message_set.create(message="This organization is over it's project limit.")
            messages.add_message(request, messages.INFO, "This organization is over it's project limit.")
            return HttpResponseRedirect( reverse("usage") )

    return render_to_response(template_name, {
        "project_form": project_form,
        "admin_organizations":admin_organizations,
        "organization":organization,
        "personal": personal
    }, context_instance=RequestContext(request))

@login_required
@ensure_csrf_cookie
def delete(request, group_slug=None, redirect_url=None):
    project = get_object_or_404(Project, slug=group_slug)
    project_slug = project.slug
    org = project.organization
    admin_access_or_403(project, request.user )
    if not redirect_url:
        redirect_url = reverse('home')

    managers.delete_project(project)

    #clear newsitem cache
    managers.clearNewsItemsCache(org, project_slug)
    #request.user.message_set.create(message=_("Project %(project_name)s deleted.") % {"project_name": project.name})
    messages.add_message(request, messages.INFO, _("Project %(project_name)s deleted.") % {"project_name": project.name})

    return HttpResponseRedirect(redirect_url)

@login_required
@expired_subscription_check
@ensure_csrf_cookie
def project_detail_picker(request, group_slug):
    """ The old project detail request, now just redirects to the board. """
    project = get_object_or_404(Project, slug=group_slug)
    read_access_or_403(project, request.user )
    return redirect("kanban_board",project_slug=group_slug)

@login_required
@expired_subscription_check
@ensure_csrf_cookie
def project(request, group_slug=None, form_class=ProjectUpdateForm,
        template_name="projects/project.html"):
    project = get_object_or_404(Project, slug=group_slug)
    read_access_or_403(project, request.user )
    if not request.user.is_authenticated():
        is_member = False
    else:
        is_member = project.user_is_member(request.user)

    action = request.POST.get("action")
    if action == "update":
        write_access_or_403(project, request.user )
        project_form = form_class(request.POST, instance=project)
        if project_form.is_valid():
            project = project_form.save()
    else:
        project_form = form_class(instance=project)

    add_story_form = handleAddStory(request, project)

    now = datetime.datetime.now()
    showIntro = (now - request.user.date_joined) < datetime.timedelta(days=3)
    kanban_stat = None

    if project.project_type == Project.PROJECT_TYPE_SCRUM:
        template_name = "projects/scrum_project.html"
    else:
        template_name = "projects/kanban_project.html"
        stats = KanbanStat.objects.filter(project=project).order_by("-created")[:1]
        logger.debug(stats)
        if len(stats) > 0:
            kanban_stat = stats[0]

    return render_to_response(template_name, {
        "project_form": project_form,
        "add_story_form": add_story_form,
        "project": project,
        "showIntro":showIntro,
        "organization": organizationOrNone(project),
        "group": project, # @@@ this should be the only context var for the project
        "is_member": is_member,
        "current_view":"project_page",
        "kanban_stat":kanban_stat
    }, context_instance=RequestContext(request))

# Drives the prediction page
# example: /projects/project/sch-r180-dashboards/project_prediction
@login_required
@ensure_csrf_cookie
def project_prediction(request, group_slug):
    project = get_object_or_404(Project, slug=group_slug)
    read_access_or_403(project, request.user )
    stories = project.get_default_iteration().stories.exclude(status=Story.STATUS_DONE).order_by("rank")

    # there is a form on the page with velocity, iteration length, and carry over.
    # IF they're filled out, we should override the default values.
    requested_velocity = request.GET.get("velocity","x");
    if requested_velocity.isdigit():
        velocity = int( requested_velocity )
    else:
        velocity = project.velocity
    if velocity == 0 or velocity == None:
        # A default velocity just in case this project doesn't have one yet.
        velocity = 25
    requested_length = request.GET.get("iteration_length","x")
    if requested_length.isdigit():
        iteration_length = int( requested_length )
    else:
        iteration_length = 14
    carry_over = (request.GET.get("carry_over","x") == "on")

    points_left = velocity
    temp_stories = []
    predictions = []
    iteration_number = project.iterations.count()
    start_date = datetime.date.today()
    current_iterations = project.get_current_iterations()
    unsized_stories = []
    total_points = 0

    # Find when the last scheduled iteration ends.
    for iteration in current_iterations:
        if iteration.end_date is not None and iteration.end_date > start_date:
            start_date = iteration.end_date

    total = 0
    for story in stories:
        total += story.points_value()

    if stories.count() > 0:
        average = int( request.GET.get('average',total / stories.count()) )
    else:
        average = 0

    # loop through the stories, and try to put them into a predicted iteration.
    for story in stories:
        if story.points == "?":
            points = average
        else:
            points = story.points_value()

        if points > points_left:
            record_prediction(predictions,temp_stories,iteration_number,start_date,iteration_length,points_left,average)
            iteration_number += 1
            if carry_over:
                points_left += velocity
            else:
                points_left = velocity
            temp_stories = []
            start_date += datetime.timedelta(days=iteration_length)
        if story.points == "?":
            unsized_stories.append(story)
        points_left -= int(points)
        total_points += points
        temp_stories.append(story)

    record_prediction(predictions,temp_stories,iteration_number,start_date,iteration_length,points_left,average)

    return render_to_response("projects/project_prediction.html", {
        "project": project,
        "predictions": predictions,
        "average": average,
        "velocity":velocity,
        "total_points":total_points,
        "ideal_iterations":int(math.ceil(total_points/velocity)),
        "predicted_iterations":len(predictions),
        "unsized_stories":unsized_stories,
        "carry_over": carry_over,
        "iteration_length":iteration_length,
        "iterations": project.iterations.all().order_by("-end_date")
    }, context_instance=RequestContext(request))

def record_prediction(predictions, stories,iteration_number,start_date,iteration_length,points_left, average):
    points = 0
    avgStories = 0
    for story in stories:
        if story.points == "?":
            p = average
            avgStories += 1
        else:
            p = story.points_value()
        points += p
    predictions.append( { "avgStories":avgStories, "carried":points_left, "stories":stories , "points":points, "num":iteration_number, "start":start_date, "end":(start_date +  datetime.timedelta(days=(iteration_length-1))) } )

@login_required
@ensure_csrf_cookie
def file_job_download(request, job_id, template="projects/job_download.html"):
    job = FileJob.objects.get(id=job_id)
    if job.owner != request.user:
        raise PermissionDenied()
    return render_to_response(template, { "job":job }, context_instance=RequestContext(request))

@login_required
def file_job_download_file(request, job_id):
    job = FileJob.objects.get(id=job_id)
    if job.owner != request.user:
        raise PermissionDenied()
    return HttpResponseRedirect( job.attachment_file.url )

@login_required
@ensure_csrf_cookie
def project_app(request, project_slug):
    project = get_object_or_404(Project, slug=project_slug)
    read_access_or_403(project, request.user)
    return render_to_response("projects/project.html",
                              {
                                  'project': project,
                                  'organization': project.organization,
                                  'can_write': has_write_access(project, request.user)
                              },
                              context_instance=RequestContext(request))


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

"""
ETAPE 2 :
On reprend la version précédente qui affiche la fenêtre graphique
On ajoute la gestion des évènements du clavier pour déclencher la fermeture de la fenêtre

@author : YF
Dernière mise à jour : juillet 2023

"""

import pygame

### constantes
# taille et titre de la fenêtre
TAILLE_FENETRE = LARGEUR, HAUTEUR = 800, 600  # (LARGEUR, HAUTEUR) de la fenêtre (en pixels)
TITRE = "Tutoriel Pygame"                     # Titre qui s'affiche dans la fenêtre
# couleurs
GRIS = 'darkgray'                             # constante définissant le GRIS
COULEUR_FOND = GRIS                           # couleur de fond

# initialisation de pygame
pygame.init()

# création de la fenêtre principale
window = pygame.display.set_mode((TAILLE_FENETRE))
pygame.display.set_caption(TITRE)

#  boucle principale
## variable qui détermine l'état de la boucle : True = la boucle est active, la fenêtre s'affiche
running = True

# tant que continuer est vraie
while running:

    # remplir la fenêtre avec une couleur
    window.fill(COULEUR_FOND)

    # événement fermeture de la fenêtre
    for event in pygame.event.get():
        if event.type == pygame.QUIT:  # pygame.QUIT : on clique sur la fermeture de la fenêtre
            running = False

    # rafraîchir la fenêtre
    pygame.display.update()

pygame.quit()


from src.file_helper import search_files, read_data
import unittest

class TestFileHelper(unittest.TestCase):

    def test_search_files_dummyextension_returns_non_empty_list(self):
        path = '../test_files'
        extension = 'json'
        files = search_files(path, extension)
        assert files is not None, 'expected non null list'

    def test_search_files_json_extension_returns_non_empty_list(self):
        path = '../test_files'
        extension = 'json'
        files = search_files(path, extension)
        assert files is not None, 'expected non null list'
        assert type(files) is list, 'expected a list'
        assert len(files) == 2 is not None, 'expected 2 elements'

    def test_read_data_known_filenames_returns_non_empty_list(self):
        files = [
            '../test_files/data_page_09012022000000.json',
            '../test_files/data_page_09302022000000.json']
        data = read_data(files)
        assert data is not None, 'expected non null list'
        assert type(data) is list, 'expected a list'
        assert len(data) > 0, 'expected non empty list'

    def test_read_data_dummy_filenames_returns_empty_list(self):
        files = [
            '../test_files/does_not_exists_09012022000000.json',
            '../test_files/does_not_exists_page_09302022000000.json']
        data = read_data(files)
        assert data is not None, 'expected non null list'
        assert type(data) is list, 'expected a list'
        assert len(data) == 0, 'expected empty list'