#   Copyright (C) 2016 Canonical Ltd.
#
#   Author: Scott Moser <scott.moser@canonical.com>
#           Christian Ehrhardt <christian.ehrhardt@canonical.com>
#
#   Curtin is free software: you can redistribute it and/or modify it under
#   the terms of the GNU Affero General Public License as published by the
#   Free Software Foundation, either version 3 of the License, or (at your
#   option) any later version.
#
#   Curtin is distributed in the hope that it will be useful, but WITHOUT ANY
#   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
#   FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License for
#   more details.
#
#   You should have received a copy of the GNU Affero General Public License
#   along with Curtin.  If not, see <http://www.gnu.org/licenses/>.
""" gpg.py
gpg related utilities to get raw keys data by their id
"""

from curtin import util

from .log import LOG

def export_armour(key):
    """Export gpg key, armoured key gets returned"""
    try:
        (armour, _) = util.subp(["gpg", "--export", "--armour", key],
                                capture=True)
    except util.ProcessExecutionError as error:
        # debug, since it happens for any key not on the system initially
        LOG.debug('Failed to export armoured key "%s": %s', key, error)
        armour = None
    return armour

def recv_key(key, keyserver, retries=None):
    """Receive gpg key from the specified keyserver"""
    LOG.debug('Receive gpg key "%s"', key)
    try:
        util.subp(["gpg", "--keyserver", keyserver, "--recv", key],
                  capture=True, retries=retries)
    except util.ProcessExecutionError as error:
        raise ValueError(('Failed to import key "%s" '
                          'from server "%s" - error %s') %
                         (key, keyserver, error))

def delete_key(key):
    """Delete the specified key from the local gpg ring"""
    try:
        util.subp(["gpg", "--batch", "--yes", "--delete-keys", key],
                  capture=True)
    except util.ProcessExecutionError as error:
        LOG.warn('Failed delete key "%s": %s', key, error)

def getkeybyid(keyid, keyserver='keyserver.ubuntu.com', retries=None):
    """get gpg keyid from keyserver"""
    armour = export_armour(keyid)
    if not armour:
        try:
            recv_key(keyid, keyserver=keyserver, retries=retries)
            armour = export_armour(keyid)
        except ValueError:
            LOG.exception('Failed to obtain gpg key %s', keyid)
            raise
        finally:
            # delete just imported key to leave environment as it was before
            delete_key(keyid)

    return armour


import random
from argparse import ArgumentParser
from datetime import datetime
from pathlib import Path

import h5py
import matplotlib.pyplot as plt
import numpy as np
import tensorflow as tf
from sklearn.metrics import classification_report, confusion_matrix

from commands import Command
from model import train_model, test_model
from math import floor

parser = ArgumentParser()

parser.add_argument("data_files", nargs="+", help="Data files to train on", default=[])
parser.add_argument("--output_file", "-o", type=str, help="Output file",
                    default=str(Path(f"./models/{datetime.now().strftime('%Y-%m-%d--%H_%M_%S')}--model")))
parser.add_argument("--epochs", "-e", type=int, help="Epochs to train for")
parser.add_argument("--steps_per_epoch", "-s", type=int, help="Steps/batches per epoch")
parser.add_argument("--sequence_length", "-sl", type=int, help="Size of the RNN sequence to train on", default=100)
parser.add_argument("--batch_size", "-b", type=int, help="Batch Size", default=32)
parser.add_argument("--validation_steps", "-vs", type=int, default=10, help="Validation steps per epoch (batches of "
                                                                            "batch_size sequence_size sequences to "
                                                                            "validate on)")
parser.add_argument("--test_split", "-t", type=float, default=0.1, help="Test split")

NOTHING_WEIGHT = 0.075

def random_segments(data, batch_size, segment_length: int, noise: bool):
    use_data = [d for d in data if d[0].shape[0] >= segment_length]
    while True:
        batch_features = []
        batch_labels = []
        weight = []
        for i in range(batch_size):
            features, labels = random.choice(use_data)
            start = random.randint(0, len(features) - (segment_length + 1))

            feature = features[start:start + segment_length]

            if noise:
                feature += np.random.normal(0, 0.2, feature.shape)

            batch_features.append(feature)
            l = labels[start:start + segment_length]
            batch_labels.append(l)
            # 0.1 if Nothing, else 1
            weight.append(l[:, 0] * -(1 - NOTHING_WEIGHT) + 1)

        yield np.stack(batch_features, axis=0), np.stack(batch_labels, axis=0), np.stack(weight, axis=0)

def all_segments(files, index: int, batch_size: int, segment_length: int):
    for f in files:
        data = f[index]
        i = 0
        while i < len(data) - segment_length:
            batch = []
            for j in range(batch_size):
                if i >= len(data) - segment_length:
                    break

                batch.append(data[i:i + segment_length])
                i += 20

            if len(batch) > 0:
                yield np.stack(batch, axis=0)

def plot_confusion_matrix(cm, target_names, title="Confusion Matrix"):
    cm = cm.astype('float') / cm.sum(axis=1)[:, np.newaxis]

    fig, ax = plt.subplots()
    fig.set_size_inches(6, 6)
    fig.set_dpi(100)
    im = ax.imshow(cm, interpolation='nearest', cmap=plt.cm.Blues)
    ax.figure.colorbar(im, ax=ax)
    # We want to show all ticks...
    ax.set(xticks=np.arange(cm.shape[1]),
           yticks=np.arange(cm.shape[0]),
           # ... and label them with the respective list entries
           xticklabels=target_names, yticklabels=target_names,
           title=title,
           ylabel='True label',
           xlabel='Predicted label')

    # Rotate the tick labels and set their alignment.
    plt.setp(ax.get_xticklabels(), rotation=45, ha="right",
             rotation_mode="anchor")

    # Loop over data dimensions and create text annotations.
    fmt = '.2f'
    thresh = cm.max() / 2.
    for i in range(cm.shape[0]):
        for j in range(cm.shape[1]):
            ax.text(j, i, format(cm[i, j], fmt),
                    ha="center", va="center",
                    color="white" if cm[i, j] > thresh else "black")
    fig.tight_layout()

    plt.plot()
    plt.show()

def display_report(model, test_data, test_labels, name, args):
    target_names = [c.name for c in list(Command)]
    y_true = test_labels
    y_true = np.argmax(y_true, axis=-1).flatten()

    Y_pred = model.predict(test_data)
    y_pred = np.argmax(Y_pred, axis=-1).flatten()
    # y_pred = y_pred.flatten()
    print(f'{name} Classification Report')
    print(classification_report(y_true, y_pred, target_names=target_names))

    cm = confusion_matrix(y_true, y_pred)

    plot_confusion_matrix(cm, target_names, f"{name} Confusion Matrix")

def segment_data(all_data):
    last = 0
    new_data = []
    new_labels = []
    nothing_count = 0
    for d in all_data:
        data = d[0]
        labels = d[1]
        last = 0
        nothing_count = 0
        for i in range(0, len(data)):
            current = labels[i].argmax()
            # print("{}: {}".format(i, labels[i].argmax()))
            if(current != last):
                if(current != 0):
                    new_data.append(data[i:i+29])
                    new_labels.append(labels[i+5].tolist())
                    if(nothing_count == 0):
                        new_data.append(data[i-29:i])
                        new_labels.append(labels[i-5].tolist())
                    nothing_count = (nothing_count + 1) % 4
            last = current
    new_labels = np.array(new_labels)
    new_data = np.array(new_data)
    # print(new_labels)
    return new_data, new_labels

if __name__ == '__main__':

    if len(tf.config.list_physical_devices('GPU')) < 1:
        print("Warning: Not using GPU, this will be slow")

    args = parser.parse_args()

    data_files = [Path(d) for d in args.data_files]

    for d in data_files:
        if not d.exists():
            raise FileNotFoundError(f"Data file {d} does not exist")

    all_data = []

    for d in data_files:
        with h5py.File(str(d), 'r') as f:
            all_data.append((np.log10(f["features"][:]), f["labels"][:]))

    #print(all_data)
    #exit()
    new_data, new_labels = segment_data(all_data)
    total_count = new_data.shape[0]
    print(total_count)
    test_count = floor(total_count * 0.2)
    end_train = total_count - test_count
    indices = np.arange(new_data.shape[0])
    np.random.shuffle(indices)
    new_data = new_data[indices]
    new_labels = new_labels[indices]
    train_data = new_data[0:end_train]
    test_data = new_data[end_train:]
    train_labels = new_labels[0:end_train]
    test_labels = new_labels[end_train:]
    #print(train_data)
    #print(train_labels)

    # all_features = np.concatenate([d[0] for d in all_data], axis=0)
    #
    # f_mean = np.mean(all_features, axis=0)
    # f_std = np.std(all_features, axis=0)
    #
    # shift = 2
    # all_data = [((d[0] - f_mean) / f_std, np.concatenate([np.zeros((shift, 5)), d[1][:-shift, :]], axis=0)) for d in
    #             all_data]
    #
    # num_test = int(sum(d[0].shape[0] for d in all_data) * args.test_split)
    #
    # file_idx = 0
    # data_idx = 0
    # remaining = num_test
    #
    # train = []
    # test = []

    model = test_model()

    #print(train_data)
    #X_train_log = np.log10(train_data, out=np.zeros_like(train_data), where=(train_data!=0))
    #X_test_log = np.log10(test_data, out=np.zeros_like(test_data), where=(test_data!=0))
    #exit()
    X_train_log = train_data
    X_test_log = test_data

    hist = model.fit(X_train_log,train_labels,validation_data=(X_test_log,test_labels),epochs=12,batch_size=20)

    # Plot training & validation loss values
    plt.plot(hist.history['loss'])
    plt.plot(hist.history['val_loss'])
    plt.title('Model loss')
    plt.ylabel('Loss')
    plt.xlabel('Epoch')
    plt.legend(['Train', 'Test'], loc='upper left')
    plt.show()

    # Plot training & validation accuracy values
    plt.plot(hist.history['acc'])
    plt.plot(hist.history['acc_1'])
    plt.plot(hist.history['val_acc'])
    plt.plot(hist.history['val_acc_1'])
    plt.title('Model accuracy')
    plt.ylabel('Accuracy')
    plt.xlabel('Epoch')
    plt.legend(['Train', "Weighted Train", 'Test', "Weighted Test"], loc='upper left')
    plt.show()

    out_path = Path(args.output_file)

    model.save(args.output_file)

    #np.save(out_path / "mean.npy", f_mean)
    #np.save(out_path / "std.npy", f_std)

    # just train
    display_report(model, X_train_log, train_labels, "Just Train", args)

    # just test
    display_report(model, X_test_log, test_labels, "Just Test", args)


# This is to find a relation between cluster mass and the average redshift at a given angular radii
# (c) mattchelldavis

from astropy.io import fits
import numpy as np

import matplotlib as mpl
mpl.use('Agg') # When I don't want to display graphs

import matplotlib.pyplot as plt
import kmeans_radec as kmrd
import sys
from scipy import integrate
import treecorr
import time
import scipy

from colossus.cosmology import cosmology as csmg
#csmg.setCosmology('WMAP9', {'flat':True,'Om0':0.2}) # setting cosmology in colossus

from colossus.halo import concentration as concen
# my other files
import error as err
import cosmology as cosmo
import ploting
import fitting_NFW

# <<--Important overarching variable Definitions-->>
# coorilation function
min_sep = 0.2
max_sep = 7
nbins = 10
n = 4
# data limits
clust_z_min = 0.1
clust_z_max = 0.33
gal_z_min = 0.4
# <<--End of line-->>

program_start = time.time()

# getting cluster and bacground galaxy data
clusters = fits.getdata('/calvin1/mattchell200/redmapper_catalogs/sdss/v5.10/dr8_run_redmapper_v5.10_lgt20_catalog.fit');

back_gal = fits.getdata('/calvin1/mattchell200/fits/sdss_galaxies_dr12_cut.fit')
# print clusters.dtype.names
# imposing limits on cluster data
print('n = {0}\nR_min = {1}\nR_max = {2}'.format(n, min_sep, max_sep))
print('cutting clusters...')
c = np.array([clusters['RA'].copy(),clusters['DEC'].copy(),clusters['Z_LAMBDA'].copy(),clusters['LAMBDA_CHISQ'].copy()]).T
c_rel = np.array([[clust[0],clust[1],clust[2],cosmo.easy_D_A(clust[2]),clust[3]] for clust in c if clust_z_min < clust[2] < clust_z_max and clust[3] > 20.]).T
n_clusters = c_rel[0].size
print("{0} clusters.".format(n_clusters))

# imposing limits on galaxy data
print('cutting galaxies...')
b_g = np.array([back_gal['RA'].copy(),back_gal['DEC'].copy(),back_gal['Z_NOQSO'].copy(),back_gal['i'].copy(),back_gal['g'].copy(),back_gal['r'].copy(),back_gal['i_color'].copy(),back_gal['g_color'].copy(),back_gal['r_color'].copy(),back_gal['i_psf'].copy(),back_gal['i_mod'].copy(),back_gal['i_fib2'].copy(),back_gal['z_mod'].copy(),back_gal['z_psf'].copy()]).T
b_g_rel = np.array([gal for gal in b_g if gal_z_min < gal[2]]).T
n_galaxies = b_g_rel[0].size
print("{0} galaxies.".format(n_galaxies))

'''
plt.plot(b_g_rel[3], b_g_rel[11], ',b')
plt.xlabel(r'$ i $-band Magnitudes')
plt.ylabel(r'$ i_{psf} $ Magnitudes')
plt.subplots_adjust(bottom=0.15, left=0.15)
plt.show()

b_g_rel_north = np.asarray([gal for gal in b_g_rel.T if 100 < gal[0] < 300]).T
b_g_rel_south = np.asarray([gal for gal in b_g_rel.T if 100 > gal[0] or gal[0] > 300]).T

plt.plot(b_g_rel_north[0],b_g_rel_north[1],"b,")
plt.plot(b_g_rel_south[0],b_g_rel_south[1],"r,")
plt.title("Galaxies in the North (blue) and South (red)")
plt.xlabel("RA")
plt.ylabel("Dec")
plt.xlim(0.,360.)
plt.ylim(-90.,90.)
plt.show()

plt.hist(c_rel[4],50,range=(15.,205.),normed=True,color="blue",alpha=0.3)
#plt.hist(b_g_rel_south[2],50,range=(0.2,1.2),normed=True,color="red",alpha=0.3)
plt.title("Galaxy Redshift Distribution in the North (blue) and South (red)")
plt.xlabel(r"$z$",fontsize=16)
plt.ylabel(r"Probability")
plt.yscale("log")
plt.show()
'''
# set probability distributions for calcualtion of expected mu value
fitting_NFW.set_p_of_zr(c_rel.copy(),20.,210.)
fitting_NFW.set_p_of_g(b_g_rel[2].copy(),gal_z_min)

# using treecorr corrilation function for average z at pysical seperation
print('finding correlation function...')

cat_c = treecorr.Catalog(ra=c_rel[0].copy(), dec=c_rel[1].copy(), r=c_rel[3].copy(), ra_units='deg', dec_units='deg')
nn = treecorr.NNCorrelation(min_sep=min_sep, max_sep=max_sep, nbins=nbins, metric='Rlens')

del_z_bar = np.zeros(nbins)
N = np.zeros(nbins)
cat_g = treecorr.Catalog(ra=b_g_rel[0].copy(), dec=b_g_rel[1].copy(), w=np.power(b_g_rel[2].copy(),n), ra_units='deg', dec_units='deg')
nn.process(cat_c,cat_g)

z_bar = nn.weight.copy()/nn.npairs.copy()
mean_z = np.average(np.power(b_g_rel[2],n))
print(mean_z, z_bar, n)
del_z_bar = z_bar-mean_z
N = nn.npairs.copy()
sep = nn.meanr.copy()
print(N)

# Calcualtion of error on the signal
Cov_mat = err.jack_knife(nn,b_g_rel[0:3].copy(),c_rel.copy(),mean_z,sep,nbins,n,ncen=70,read_from_file=False)
#Cov_mat = err.randoms_cluster_errors(n_clusters,clust_z_min,clust_z_max,nn,cat_g,mean_z,sep,nbins,read_from_file=False)
#Cov_mat = err.anylitical_error(b_g_rel[2],N)

# quick significance checker
'''
mean_2_z = np.average(np.power(b_g_rel[2],2.))
chi_2 = np.sum(np.power(del_z_bar,2.)*N/(mean_2_z-np.power(mean_z,2.)))
print("chi_2: {0}".format(chi_2))
chi_2_dist = lambda x: np.power(x,nbins/2.-1)*np.exp(-x/2.)/(np.power(2.,nbins/2.)*scipy.special.gamma(nbins/2.))
tot_prob = scipy.integrate.quad(chi_2_dist,0,chi_2)
print("total probability: {0}".format(tot_prob))
print("Significance: {0}".format(scipy.special.erfinv(tot_prob[0])*np.power(2,0.5)))
'''
print("fitting signal...")
M_0, var_M_0 = fitting_NFW.multiple_profiles(sep.copy(),del_z_bar.copy(),N.copy(),b_g_rel.copy(),c_rel.copy(),n,Cov_mat.copy())

r = np.logspace(np.log10(min_sep),np.log10(max_sep),30,endpoint=True)
model = []
model_p = []
model_m = []
M_p = M_0+np.power(var_M_0,0.5)
M_m = M_0-np.power(var_M_0,0.5)
quad_coeff = fitting_NFW.get_quad_coeff_for_d_del_z_d_Sig(b_g_rel.copy(),n)
for r_i in r:
    model.append(fitting_NFW.expect_delta_z_bar_of_Sig(M_0,r_i,quad_coeff))
    model_p.append(fitting_NFW.expect_delta_z_bar_of_Sig(M_p,r_i,quad_coeff))
    model_m.append(fitting_NFW.expect_delta_z_bar_of_Sig(M_m,r_i,quad_coeff))
model = np.asarray(model)
model_p = np.asarray(model_p)
model_m = np.asarray(model_m)

'''
# ploting signal to noise as a function of mode number
n = np.linspace(.5,5.,16,endpoint=True)
print(n)
sig_noise = []
signal = []
noise = []
for k in n:
    del_z_n_bar, sig = fitting.other_modes(b_g_rel,cat_c,nn,k)
    A_n, sig_A = fitting.fit_powr_law(sep,del_z_n_bar,sig)
    sig_noise.append(A_n/sig_A)
    signal.append(A_n)
    noise.append(sig_A)
s_n = np.asarray(sig_noise)
signal = np.asarray(signal)
noise = np.asarray(noise)

plt.plot(n,s_n)
plt.xlabel('n')
plt.ylabel('Signal/Noise')
plt.title('Checking Signal to Noise')
plt.show()

plt.plot(n,signal,'r')
plt.plot(n,noise,'b')
plt.xlabel('n')
plt.ylabel('Signal (red) and Noise (blue)')
plt.title('Signal And Noise')
plt.show()
'''

# ploting avg redshift as a function of r
old_sig = np.power((np.average(np.power(b_g_rel[2],2.))-np.power(np.average(b_g_rel[2]),2.))/N,0.5)
sig = np.power(np.array([Cov_mat[i,i] for i in range(sep.size)]),0.5)
print(sig/old_sig)
plt.figure(1,figsize=(7.5,7),dpi=80)
plt.axhline(y=0.0, xmin=0.0, xmax=1.0, linewidth=1, color='k')
data_graph = plt.errorbar(sep, del_z_bar, yerr=sig, fmt='o', color='b', capsize=3)
plt.fill_between(r, model_m, model_p, color='r', alpha=0.25)
model_graph, = plt.plot(r, model, 'r')
sig_label, = plt.fill(np.NaN, np.NaN, 'r', alpha=0.25)

#model_p_graph = plt.plot(r,model_p,'r',alpha=0.5)
#model_m_graph = plt.plot(r,model_m,'r',alpha=0.5)
if n == 1:
    plt.ylabel(r'$\Delta \bar{z}$', fontsize=14)
else:
    plt.ylabel(r'$\Delta \bar{z^{'+str(n)+'}}$', fontsize=14)

plt.xscale('log')
plt.xlim([min_sep, max_sep])
plt.xlabel(r'$R \ (Mpc)$')

plt.subplots_adjust(hspace=0.26,wspace=0.56,right=0.95,left=0.16,top=0.93,bottom=0.15)
plt.legend([data_graph, (model_graph, sig_label)], [r'$\Delta \bar{z}$ Signal', 'NSF model'])
#plt.suptitle('Redshift Signal vs. Physical Radius')
plt.savefig("auto/delta_z_bar_fit_NFW_{0}.png".format(n))
plt.close()

# ploting r*avg redshift as a function of r
plt.figure(1,figsize=(7.5,7),dpi=80)
plt.axhline(y=0.0, xmin=0.0, xmax=1.0, linewidth=1, color='k')
data_graph = plt.errorbar(sep, sep*del_z_bar, yerr=sep*sig, fmt='o', color='b', capsize=3)
plt.fill_between(r, r*model_m, r*model_p, color='r', alpha=0.25)
model_graph, = plt.plot(r, r*model, 'r')
sig_label, = plt.fill(np.NaN, np.NaN, 'r', alpha=0.25)

if n == 1:
    plt.ylabel(r'$R \Delta \bar{z} \ (Mpc)$', fontsize=14)
else:
    plt.ylabel(r'$R \Delta \bar{z^{'+str(n)+'}} \ (Mpc)$', fontsize=14)

plt.xscale('log')
plt.xlim([min_sep, max_sep])
plt.xlabel(r'$R \ (Mpc)$')

plt.subplots_adjust(hspace=0.26,wspace=0.56,right=0.95,left=0.16,top=0.93,bottom=0.15)
plt.legend([data_graph, (model_graph, sig_label)], [r'$\Delta \bar{z}$ Signal', 'NSF model'])
#plt.suptitle('Redshift Signal Times Radius vs. Physical Radius')
plt.savefig("auto/delta_z_bar_r_fit_NFW_{0}.png".format(n))
plt.close()

'''
ploting.histogram(b_g_rel[2],100,range=(0.,3.),color='r',xlabel='Redshift',ylabel='counts',title='Log of Background Galaxies Histogram',yscale='log')

ploting.plot_posit(b_g_rel[0],b_g_rel[1],color='r')
'''
program_end = time.time()
run_time = program_end-program_start

print("done")
print("total run time: "+str(run_time)+" sec")
print("             or "+str(run_time/60.)+" min")
print("             or "+str(run_time/3600.)+" hr\n")


from django.conf.urls.defaults import patterns, url, include
from django.contrib import admin
from django.shortcuts import redirect

from amo.urlresolvers import reverse
from . import views

urlpatterns = patterns('',
    # AMO stuff.
    url('^$', lambda r: redirect('admin:index'), name='zadmin.home'),
    url('^env$', views.env, name='amo.env'),
    url('^flagged', views.flagged, name='zadmin.flagged'),
    url('^hera', views.hera, name='zadmin.hera'),
    url('^settings', views.settings, name='zadmin.settings'),

    # The Django admin.
    url('^models/', include(admin.site.urls)),
)

# Hijack the admin's login to use our pages.
def login(request):
    url = '%s?to=%s' % (reverse('users.login'), request.path)
    return redirect(url)

admin.site.login = login


#
# @lc app=leetcode id=3 lang=python
#
# [3] Longest Substring Without Repeating Characters
#
# https://leetcode.com/problems/longest-substring-without-repeating-characters/description/
#
# algorithms
# Medium (28.41%)
# Likes:    5595
# Dislikes: 313
# Total Accepted:    941.9K
# Total Submissions: 3.3M
# Testcase Example:  '"abcabcbb"'
#
# Given a string, find the length of the longest substring without repeating
# characters.
#
#
# Example 1:
#
#
# Input: "abcabcbb"
# Output: 3
# Explanation: The answer is "abc", with the length of 3.
#
#
#
# Example 2:
#
#
# Input: "bbbbb"
# Output: 1
# Explanation: The answer is "b", with the length of 1.
#
#
#
# Example 3:
#
#
# Input: "pwwkew"
# Output: 3
# Explanation: The answer is "wke", with the length of 3.
#             Note that the answer must be a substring, "pwke" is a
# subsequence and not a substring.
#
#
#
#
#
#
import collections
class Solution(object):
    # two points: Your runtime beats 86.8 % of python submissions
    def lengthOfLongestSubstring01(self, s):
        """
        :type s: str
        :rtype: int
        """
        start, ans = 0, 0
        count = {}
        for end in range(len(s)):
            c = s[end]
            if c in count:
                start = max(start, count[c] + 1)
            count[c] = end
            ans = max(ans, end - start + 1)
        return ans

    # solution 5: slid window
    def lengthOfLongestSubstring(self, s):
        counter = collections.defaultdict(int)
        left, ans = 0, 0
        for right in range(len(s)):
            # duplicate
            while counter.get(s[right], 0) != 0:
                counter[s[left]] = counter.get(s[left], 0) - 1
                left += 1

            counter[s[right]] += 1
            # update result
            ans = max(ans, right - left + 1)

        return ans

    # solution 4: two points - Your runtime beats 93.13 % of python submissions
    def lengthOfLongestSubstring04(self, s):
        """
        :type s: str
        :rtype: int
        """
        window_start, max_length = 0, 0
        char_index_map = {}
        # try to extend the range [windowStart, windowEnd]
        for window_end in range(len(s)):
            right_char = s[window_end]
            # if the map already contains the 'right_char', shrink the window from the beginning so that
            # we have only one occurrence of 'right_char'
            if right_char in char_index_map:
                # this is tricky; in the current window, we will not have any 'right_char' after its previous index
                # and if 'window_start' is already ahead of the last index of 'right_char', we'll keep 'window_start'
                window_start = max(window_start, char_index_map[right_char] + 1)

            # insert the 'right_char' into the map
            char_index_map[right_char] = window_end
            # remember the maximum length so far
            max_length = max(max_length, window_end - window_start + 1)

        return max_length

    '''
    # solution 3: two points - Your runtime beats 43.25 % of python submissions
    def lengthOfLongestSubstring(self, s):
        """
        :type s: str
        :rtype: int
        """
        d = {}
        start = 0
        ans = 0
        for end in range(len(s)):
            c = s[end]
            d[c] = d.get(c,0)+1

            while d[c]>1:
                d[s[start]] -=1
                if d[s[start]] == 0:
                    del d[s[start]]
                start += 1

            ans = max(ans, end - start +1)

        return ans
    '''

    '''
    # solution 2: Your runtime beats 98.97 % of python submissions
    def lengthOfLongestSubstring(self, s):
        """
        :type s: str
        :rtype: int
        """
        if not s:
            return 0

        start = ans = 0
        usedChar = {}
        for i,c in enumerate(s):
            if c in usedChar and start <=usedChar[c]:
                start = usedChar[c] + 1
            else:
                ans = max(ans, i - start + 1)
            usedChar[c] = i

        return ans
    '''

    '''
    # solution 1: Your runtime beats 8 % of python submissions
    def lengthOfLongestSubstring(self, s):
        """
        :type s: str
        :rtype: int
        """
        if not s:
            return 0
        ans = 0

        #i,j=0,0
        for i in range(len(s)):
            d = set(s[i])
            j = i+1
            while j<len(s) and s[j] not in d:
                d.add(s[j])
                j +=1
            ans = max(ans, len(d))
        return ans
    '''


import random
def drowBoard(board):
    print('   |   |')
    print(' ' + board[7] + ' | ' + board[8] + ' | ' + board[9])
    print('   |   |')
    print('------------')
    print('   |   |')
    print(' ' + board[4] + ' | ' + board[5] + ' | ' + board[6])
    print('   |   |')
    print('------------')
    print('   |   |')
    print(' ' + board[1] + ' | ' + board[2] + ' | ' + board[3])
    print('   |   |')
#drowBoard([' ', ' ', ' ', ' ', 'X', 'O', ' ', 'X', ' ', 'O'])
# select the player letter be 'X' or "O"
def inputPlayerLetter():
    letter=''
    while not(letter=='X' or letter=='O'):
        print("which letter u want to sellect")
        letter=input().upper()
# the first letter is player and sec is for computer
    if letter=='X':
        return['X','O']
    else:
        return['O','X']
def whoGoesFirst():
    if random.randint(0, 1) == 0:
        return 'computer'
    else:
        return 'player'
def playAgain():
    print("Do u want to play again? (yes or no")
    return input().lower().startswith(y)

def makeMove(board,letter,move):
    board[move]=letter

def isWinner(bo,le):
    return((bo[7]==le and bo[8]==le and bo[9]==le) or # across the top
    (bo[4]==le and bo[5]==le and bo[6]==le) or        # across the middel
    (bo[1]==le and bo[2]==le and bo[3]==le) or         # accroess the bot
    (bo[7]==le and bo[4]==le and bo[1]==le) or         # down the left side
    (bo[8]==le and bo[5]==le and bo[2]==le) or          # down the middle side
    (bo[9]==le and bo[6]==le and bo[3]==le) or          # down the bot side
    (bo[7]==le and bo[5]==le and bo[3]==le) or           #diagnalleft to right
    (bo[9]==le and bo[5]==le and bo[1]==le))              # diag rt to lft

def getBoardCopy(board):
    dupeBoard=[]
    for i in board:
        dupeBoard.append(i)
    return dupeBoard

def isSpaceFree(board,move):
    return board[move]==' '

def getPlayerMove(board):
    move=' '
    while move not in ' 1 2 3 4 5 6 7 8 9'.split() or not isSpaceFree(board,int(move)):
        print("what is ur next move? (1-9)")
        move=input()
        return int(move)
def chooseRandomMoveFromList(board,movesList):
 # Returns a valid move from the passed list on the passed board.
 # Returns None if there is no valid move
    possibleMoves=[]
    for i in movesList:
        if isSpaceFree(board, i):
            possibleMoves.append(i)

    if len(possibleMoves)!=0:
        return random.choice(possibleMoves)
    else:
        return None

def getComputerMove(board, computerLetter):
    # Given a board and the computer's letter, determine where to move and return that move.
    if computerLetter=='X':
        playerLetter='O'
    else:
        playerLetter='X'

        # Here is our algorithm for our Tic Tac Toe
        #  # First, check if we can win in the next move
    for i in range(1, 10):
        copy = getBoardCopy(board)
        if isSpaceFree(copy, i):
            makeMove(copy, computerLetter, i)
            if isWinner(copy, computerLetter):
                return i

# Check if the player could win on their next move, and block them.
    for i in range(1, 10):
        copy = getBoardCopy(board)
        if isSpaceFree(copy, i):
            makeMove(copy, playerLetter, i)
            if isWinner(copy, playerLetter):
                return i

    # Try to take one of the corners, if they are free.
    move = chooseRandomMoveFromList(board, [1, 3, 7, 9])
    if move != None:
        return move
# Try to take the center, if it is free.
    if isSpaceFree(board,5):
        return 5
    # Move on one of the sides
    return chooseRandomMoveFromList(board, [2, 4, 6, 8])

def isBoardFull(board):
    # Return True if every space on the board has been taken. Otherwise return False.
    for i in range(1, 10):
        if isSpaceFree(board, i):
            return False

    return True

print('Welcome to tic tac toe')

while True:
    #reset the board
    theBoard=[' '] * 10
    playerLetter , computerLetter = inputPlayerLetter()
    turn=whoGoesFirst()
    print('the' + turn + 'will go first')
    gameIsPlaying =True

    while gameIsPlaying:
        if turn== "player":
            drowBoard(theBoard)
            move= getPlayerMove(theBoard)
            makeMove(theBoard, playerLetter, move)

            if isWinner(theBoard, playerLetter):
                drowBoard(theBoard)
                print('u have won the game!')
                gameIsPlaying=False
            else:
                if isBoardFull(theBoard):
                    drowBoard(theBoard)
                    print("the game is tie")
                    break
                else:
                    turn ="computer"

        else:
            move = getComputerMove(theBoard, computerLetter)

            makeMove(theBoard, computerLetter, move)

            if isWinner(theBoard, computerLetter):

                drawBoard(theBoard)

                print('The computer has beaten you! You lose.')

                gameIsPlaying = False

            else:
                if isBoardFull(theBoard):
                    drowBoard(theBoard)
                    print("game is tie")
                    break
                else:
                    turn = 'player'

    if not playAgain():
        break


import os
import json
import PySide.QtGui as QtGui
from PySide.QtCore import Signal

class JobWidget(QtGui.QWidget):

    rendererChanged = Signal(int)

    def __init__(self, renderer):
        super(JobWidget, self).__init__()
        self.setLayout(QtGui.QVBoxLayout())
        jobBox = QtGui.QGroupBox('Job Set')
        jobBoxLayout = QtGui.QGridLayout()
        jobBox.setLayout(jobBoxLayout)
        self.layout().addWidget(jobBox)
        self.layout().setContentsMargins(0, 0, 0, 0)
        jobBoxLayout.addWidget(QtGui.QLabel('Renderer:'), 0, 0)
        self.rendererBox = QtGui.QComboBox()
        self.setRendererDrop(renderer)
        self.rendererBox.currentIndexChanged.connect(self.emitRendererChangedSignal)
        jobBoxLayout.addWidget(self.rendererBox, 0, 1)
        jobBoxLayout.addWidget(QtGui.QLabel('Priority:'), 1, 0)
        self.priorityBox = QtGui.QSpinBox()
        self.priorityBox.setMinimum(1)
        self.priorityBox.setMaximum(10)
        self.priorityBox.setValue(5)
        self.priorityBox.setMaximumWidth(50)
        jobBoxLayout.addWidget(self.priorityBox, 1, 1)
        jobBoxLayout.addWidget(QtGui.QLabel('Dependent Job:'), 1, 2)
        self.dependJobLineEdit = QtGui.QLineEdit()
        jobBoxLayout.addWidget(self.dependJobLineEdit, 1, 3)
        self.dependJobLineEdit.setText('')
        jobBoxLayout.addWidget(QtGui.QLabel('Frame Split Mode:'), 2, 0)
        self.splitmodeDrop = QtGui.QComboBox()
        self.setSplitModeDrop()
        self.splitmodeDrop.activated[int].connect(self.splitModeSelected)
        jobBoxLayout.addWidget(self.splitmodeDrop, 2, 1)
        hlayout = QtGui.QHBoxLayout()
        hlayout.addItem(QtGui.QSpacerItem(10, 10, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum))
        hlayout.addWidget(QtGui.QLabel('Count:'))
        jobBoxLayout.addLayout(hlayout, 2, 2)
        self.countBox = QtGui.QSpinBox()
        self.countBox.setValue(5)
        jobBoxLayout.addWidget(self.countBox, 2, 3)
        self.countLabel = QtGui.QLabel('frames/chunk')
        jobBoxLayout.addWidget(self.countLabel, 2, 4)
        jobBoxLayout.addWidget(QtGui.QLabel('Client Pool:'), 3, 0)
        self.poolDrop = QtGui.QComboBox()
        self.setPoolsDrop()
        jobBoxLayout.addWidget(self.poolDrop, 3, 1)

    def emitRendererChangedSignal(self):
        self.rendererChanged.emit(int(self.rendererBox.currentIndex()))

    def setRendererDrop(self, renderer):
        if os.path.exists(os.environ['SHOT_SUBMIT_CONFIG']):
            jd = open(os.environ['SHOT_SUBMIT_CONFIG']).read()
            data = json.loads(jd)
            options = data['Renderers'][renderer]
            for option in options:
                self.rendererBox.addItem(option)

    def setPoolsDrop(self):
        if os.path.exists(os.environ['SHOT_SUBMIT_CONFIG']):
            jd = open(os.environ['SHOT_SUBMIT_CONFIG']).read()
            data = json.loads(jd)
            options = data['Pools']
            for option in options:
                self.poolDrop.addItem(option)

    def setSplitModeDrop(self):
        self.splitmodeDrop.addItem('No Splitting')
        self.splitmodeDrop.addItem('Split into X total pieces')
        self.splitmodeDrop.addItem('Split into X frames per chunk')
        self.splitmodeDrop.setCurrentIndex(2)

    def splitModeSelected(self, index):
        if index == 0:
            self.countLabel.setText('')
            self.countBox.setValue(0)
            self.countBox.setEnabled(False)
        elif index == 1:
            self.countBox.setEnabled(True)
            self.countBox.setValue(2)
            self.countLabel.setText('total pieces')
        else:
            self.countBox.setEnabled(True)
            self.countBox.setValue(5)
            self.countLabel.setText('frames/chunk')

    def getRenderer(self):
        return str(self.rendererBox.currentText())

    def getClientPools(self):
        return str(self.poolDrop.currentText())

    def getSplitMode(self):
        splitMode = str(self.splitmodeDrop.currentIndex())
        count = str(self.countBox.text())
        return '%s,%s' % (splitMode, count)

    def getDependentJob(self):
        return str(self.dependJobLineEdit.text())


import sys
#sys.stdin=open("input.txt", "r")

n = int(input())
nList = [list()]*n

for i in range(n):
    nList[i] = list(map(int, input().split()))

sum = 0

s=e=n//2

for i in range(n):
    for j in range(s, e+1):
        sum += nList[i][j]
    if i<n//2:
        s-=1
        e+=1
    else:
        s+=1
        e-=1

print(sum)


from django.utils import six

from django.contrib.auth.models import User
from django.core import serializers
from django.http import JsonResponse
from django.shortcuts import render

from authsys.models import UserProfile
from orders.forms import CheckoutForm
from orders.models import ProductInBascket, ProductInOrder, Order

def bascket_adding(request):
    if not request.session.exists(request.session.session_key):
        request.session.create()
    session_key = request.session.session_key

    data = request.POST
    product_id = data.get('product_id')
    num = data.get('quantity')
    product_name = data.get('product_name')
    print(product_name, product_id , num , data.get('is_delete')== 'false')
    if data.get('is_delete') == 'true':

        ProductInBascket.objects.filter(id=product_id).update(is_active=False)
    else:

        new_product, created = ProductInBascket.objects.get_or_create(session_key=session_key, product_id=product_id, defaults={'number_of_products' : num});
        if not created:
            new_product.number_of_products += int(num)
            new_product.is_active = True
            new_product.save(force_update=True)
    return_dict = dict()
    total_prod_items = ProductInBascket.objects.filter(session_key=session_key, is_active=True)
    total_prod_num = total_prod_items.count()
    list_products = [{'price' : item.product.price, 'name' : item.product.name , 'quant' : item.number_of_products,'id' : item.id}
                     for item in total_prod_items]
    return_dict['total_prod_num'] = total_prod_num
    return_dict['total_prod_items'] = list_products
    return JsonResponse(return_dict)

def checkout(request):
    if not request.session.exists(request.session.session_key):
        request.session.create()
    session_key = request.session.session_key
    if request.method == "POST":
        form = CheckoutForm(request.POST or None)
        print(request.POST)
        if form.is_valid():

            product_queryset = dict(request.POST)
            name =product_queryset['name'][0]
            phone = product_queryset['phone'][0]
            adress = product_queryset['adress'][0]
            product_dict = {}
            for k, v in product_queryset.items():
                if k.isdigit():

                   product_dict[k] = v[0]

            user, created = User.objects.get_or_create(username=phone, defaults={ 'first_name': name })
            if created:
                user_profile = UserProfile.objects.create(user_id=user.id, adress=adress)

            order = Order.objects.create(user=user , customer_name=name , customer_phone=phone, status_order_id=3)
            for k , v in product_dict.items():

                product_in_bascket = ProductInBascket.objects.get(id=k)
                product_in_bascket.number_of_products = v
                product_in_bascket.order = order
                product_in_bascket.save(force_update=True)
                ProductInOrder.objects.create(product=product_in_bascket.product,  number_of_products=int(v),
                                              total_price=product_in_bascket.total_price, order=order)

        return JsonResponse({'bar' : 'foo'})
    products_in_bascket = ProductInBascket.objects.filter(session_key=session_key, is_active=True, order__isnull=True)
    total_price = 0
    for item in products_in_bascket:
        total_price+=item.total_price

    return render(request, 'orders/checkout.html', locals())


#!/usr/bin/env python

import os
import re
import sys
import json
import unicodecsv

from wikidata_suggest import suggest

in_csv = unicodecsv.reader(open(sys.argv[1], 'rb'))
out_fh = open(sys.argv[2], "wb")
out_csv = unicodecsv.writer(out_fh)
authors_file = sys.argv[3]

seen_header = False

if os.path.isfile(authors_file):
    authors = json.load(open(authors_file))
else:
    authors = {}

for row in in_csv:

    # copy over the headers
    if not seen_header:
        out_csv.writerow(row)
        seen_header = True
        continue

    # can be multiple names separated by semicolons
    names = [n.strip() for n in row[16].split(";")]

    # no names, no work to do :)
    if len(names) == 1 and names[0] == "":
        continue

    # use wikidata to normalize the names
    new_names = []
    for name in names:

        if name in authors:
            new_names.append(name)
            continue

        parts = [n.strip() for n in name.split(',', 1)]
        if len(parts) == 2:
            name = ' '.join([parts[1], parts[0]])

        wikidata = suggest(name)

        if wikidata:
            new_names.append(wikidata['label'])
            authors[wikidata['label']] = wikidata['id']
        else:
            new_names.append(name)
            authors[name] = None

        json.dump(authors, open(authors_file, 'w'), indent=2)

    # write out the normalized names
    row[16] = " ; ".join(new_names)
    out_csv.writerow(row)
    out_fh.flush()


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
#==============================================================================
# SCRIPT TO VERIFY DATE FOR TIME SERIES
#==============================================================================

This script will verify date for time series and will filter when same date
are wrong (e.g. when a 2017 year is between 2016).

@author: fncsobral
@date  : 05/dec/2016
@mod1  : 16/jan/2017 - Arranging UTC time, and improving date filter.
@mod2  : 17/jan/2017 - Arranging index problem with variables DataFrame
#==============================================================================
"""

from datetime import datetime as dtm
import numpy as np
import time
import calendar

#==============================================================================
#
#==============================================================================
def ver_continuity(var_dtfr):
    '''
    Use the DataFrame of a specific data
    to get all the time information, generate a
    EPOCH date and then will organize the time
    sorted ascending, to verify if date is in
    the correct place.

    RETURN:
        - epc_smpl: dictionary that contains all the period of sampling. This
        group will be used to verify the amount of samples captured in that
        hour in GETTING_DATA.PY script.

    '''

    # Getting all the fields information to build epoch date.
    # 150000 is the visual limit that I think sensors were took off the water.
    nms   = ['YEAR', 'MONTH', 'DAY', 'HOUR', 'MIN', 'SEC']
    YEAR  = var_dtfr[nms[0]][:150000]
    MONTH = var_dtfr[nms[1]][:150000]
    DAY   = var_dtfr[nms[2]][:150000]
    HOUR  = var_dtfr[nms[3]][:150000]
    MIN   = var_dtfr[nms[4]][:150000]
    SEC   = var_dtfr[nms[5]][:150000]

    # Cutting all VAR_DTFR
    var_dtfr = var_dtfr[:150000]

    # Building epoch date vector.
    epc = list()
    for yy, mm, dd, HH, MM, SS in zip(YEAR, MONTH, DAY, HOUR, MIN, SEC):
        epc.append(calendar.timegm(dtm(yy, mm, dd, HH, MM, SS).timetuple()))

    # First evaluation, verifying if data is in the right position. If not,
    # data will be discarted. Better evaluation about data veracity just can be
    # made using some kind of metadata, what I don't have now and I expected
    # spreadsheet to be corrected offered to the users...
    idx = np.argsort(epc)

    # This part verifies if the time is placed at the right position. If not, it
    # is removed and another index verification will happen.
    TT = True
    while TT == True:
#        print('Idx length is:', len(idx))

        for ii, kk in enumerate(idx):
            if kk != ii:
#                print('Index ii is at wrong place at the original series.',
#                      'Indice ii = ', ii, ' Indice kk = ', kk)
                # Removing the element that is the wrong place.
                epc = np.delete(epc, ii)
                idx = np.argsort(epc)

                # Removing from VAR_DTFR
                var_dtfr = var_dtfr.drop(var_dtfr.index[ii])
                break

            elif ii == len(idx) - 1:
                print('LAST verification...')
                TT = False

            else:
                pass

    # Getting epoch sorted and with repeated numbers cut off. Sometimes at
    # time sampling, there are more than one data for the same time, and
    # those are removed here.   [NÃO SEI SE MANTENHO ISSO....17/JAN/2017]
    new_epc      = np.unique(epc)
    new_var_dtfr = var_dtfr.drop_duplicates(['YEAR', 'MONTH', 'DAY', 'HOUR', 'MIN', 'SEC'])

    # Current time: to cut date not realistic with the actual date (2017 date in
    # 2016 year). In epoch date.
    cur_time = time.mktime(time.localtime())

    # ----------------- List to stores index to be removed ------------------ #
    # Epoch date that represent future date (still not achieved in real life calendar)
    epc_future = list()

    # Epoch date that sampling does not started in HH:01:30
    epc_start  = list()

    # Dictionary that will contain the samples for each hour.
    epc_smpl   = dict()

    # List that stores the samples for each hour.
    tmsmpl     = list()

    # Loop over epc ascending sorted.
    for ii, ee in enumerate(new_epc):

        # Getting information of "ee", which is the iteration for all epoch
        # dates of sampling (already sorted as ascend and without repeated numbers)
        yy = dtm.utcfromtimestamp(ee).year
        mm = dtm.utcfromtimestamp(ee).month
        dd = dtm.utcfromtimestamp(ee).day
        HH = dtm.utcfromtimestamp(ee).hour

        # EPC_REF is the mark for the first moment of sampling, that is, HH:01:30
        # for each HH; the reference.
        epc_ref = calendar.timegm(dtm(yy, mm, dd, HH, 1, 30).timetuple())

        # If time is greater than localtime, will be removed.
        if ee > cur_time:
            # Storing index remove value later.
            epc_future.append(ii)

            # Removing index ii from DATAFRAME VAR_DTFR
            new_var_dtfr = new_var_dtfr.drop(new_var_dtfr.index[ii])

            print('Date out of range, need to be removed ', ii, dtm.fromtimestamp(ee))

        # Data between expected time sample 01m30s and 1m49s
        elif ee - epc_ref >= 0 and ee - epc_ref <= 19:
            tmsmpl.append(ii)
#            print('Time sample within the range of 30s and 49s.')

            # Verifying the next time. If it changed of HH (difference will be
            # greater than 19s), the appended values will be stored in dictionary
            # EPC_SMPL
            # Verifying if ii index will not exceed the NEW_EPC length.
            if ii+1 <= len(new_epc)-1:
                # GG is epoch date
                gg = new_epc[ii + 1]

                # If difference greater than 19 sec, store the epoch appended and
                # initiate another TMSMPL storing for the next hours.
                if gg - epc_ref > 19:
                    epc_smpl[str(epc_ref)] = tmsmpl
                    tmsmpl = list()
            else:
                pass

        # This part will get times that are within the time period of sampling
        # but started in other moment instead 1m30s.
        # The values are the indexes refered to NEW_EPC.
        else:
            epc_start.append(ii)

            # Removing index ii from DATAFRAME VAR_DTFR
            new_var_dtfr = new_var_dtfr.drop(new_var_dtfr.index[ii])

            print('Started in other time than 1m30s: ', dtm.utcfromtimestamp(ee))

    # Storing EPC_FUTURE and EPC_START inside EPC_SMPL
    epc_smpl['epc_start' ] = epc_start
    epc_smpl['epc_future'] = epc_future

    ###
    # Return dictionary with time samples.
    return epc_smpl, new_var_dtfr

#==============================================================================
# END
#==============================================================================


from __future__ import (absolute_import, division, print_function,
                        unicode_literals)

import argparse
import os
import sys
from uuid import uuid4

from PH5WebService.PH5MetaQuery.station_args_container \
                                import StationArgsContainer
from PH5WebService.common import inventory_utils
from PH5WebService.common.custom_exceptions import ArgumentValidationError
from PH5WebService.common.log import sta_logger
from PH5WebService.PH5MetaQuery.write_ph5geocsv import inventory_to_ph5_geocsv
from PH5WebService.PH5MetaQuery.write_stationtxt import inventory_to_station_text
from PH5WebService.PH5MetaQuery.configuration import CONFIG
from ph5.core import ph5api
from ph5.clients.ph5tostationxml import run_ph5_to_stationxml

def parse_arguments():

    sentinel_dict = {}

    def _preprocess_sysargv(argv):
        inputs = []
        for arg in argv[1:]:
            # handles case where values contain --, otherwise they will
            # be interpreted as arguments.
            if '--,' in arg or ',--' in arg or arg == '--':
                sentinel = uuid4().hex
                key = '%s' % sentinel
                sentinel_dict[key] = arg
                inputs.append(sentinel)
            else:
                inputs.append(arg)
        return inputs

    def _postprocess_sysargv(v):
        if v in sentinel_dict:
            return sentinel_dict.get(v)
        else:
            return v

    # define command line arguments
    parser = argparse.ArgumentParser(description='Command line parser for '
                                                 'pic-ph5 station xml query.')
    # Parameter for handling POST request
    parser.add_argument('--STDIN',
                        help="For POST request, POST body "
                             "is passed in as stdin",
                        action="store_true")
    # channel options
    parser.add_argument('--network', '--net',
                        help="Select one or more network codes. Can be SEED "
                             "codes or data center defined codes. Accepts "
                             "wildcards and lists.")
    parser.add_argument('--reportnum', '--report',
                        help="Select one or more network codes. Can be SEED "
                             "codes or data center defined codes. Accepts "
                             "wildcards and lists.")
    parser.add_argument('--station', '--sta',
                        help="Select one or more SEED station codes. Accepts "
                             "wildcards and lists.")
    parser.add_argument('--location', '--loc',
                        help="Select one or more SEED location identifier. "
                        "Use -- for 'Blank' location IDs (ID's containing 2 "
                        "spaces). Accepts wildcards and lists.",
                        type=_postprocess_sysargv)
    parser.add_argument('--channel', '--cha',
                        help="Select one or more SEED channel codes. "
                             "Accepts wildcards and lists.")
    parser.add_argument('--arrayid', '--array',
                        help="Select one or more SEED channel codes. "
                             "Accepts wildcards and lists.")
    parser.add_argument('--receiver',
                        help="Select one or more receiver ids. "
                             "Accepts lists.")
    parser.add_argument('--component',
                        help="Select one or more component ids. Accepts "
                             "wildcards and lists.")

    # time constraints
    parser.add_argument('--starttime', '--start',
                        help="Limit to metadata describing channels operating "
                        "on or after the specified start time.")
    parser.add_argument('--endtime', '--end',
                        help="Limit to metadata describing channels operating "
                             "on or before the specified end time.")

    # rectangular geographic constraints
    parser.add_argument('--minlatitude', '--minlat', help='Southern boundary.')
    parser.add_argument('--maxlatitude', '--maxlat', help='Northern boundary.')
    parser.add_argument('--minlongitude', '--minlon', help='Western boundary.')
    parser.add_argument('--maxlongitude', '--maxlon', help='Eastern boundary.')

    # radial geographic constraints
    parser.add_argument("--latitude", "--lat", action="store",
                        help="Specify the central latitude point for a radial "
                             "geographic constraint.")
    parser.add_argument("--longitude", "--lon", action="store",
                        help="Specify the central longitude point for a "
                             "radial geographic constraint.")
    parser.add_argument("--minradius", action="store",
                        help="Specify minimum distance from the geographic "
                             "point defined by latitude and longitude.")
    parser.add_argument("--maxradius", action="store",
                        help="Specify maximum distance from the geographic "
                             "point defined by latitude and longitude.")

    # miscellaneous
    parser.add_argument('--level', default='station',
                        help="Specify level of detail using network, station, "
                        "channel,or response.")
    parser.add_argument('--format', default='xml',
                        help="Specify output format. Valid formats "
                             "include xml.")

    args = parser.parse_args(_preprocess_sysargv(sys.argv))
    return args

def parse_level(level, out_format):
    """
    Method for parsing PH5 Station Service request level
    :param level: The Station service request level (Network, Station,
        Channel, or Response) :type: str
    :returns: A validated request level string :type: str
    """
    level = level.upper()
    out_format = out_format.upper()
    if (level == 'RESPONSE' and out_format == 'TEXT') or \
            level not in ['NETWORK', 'STATION', 'CHANNEL', 'RESPONSE']:
        raise ArgumentValidationError("Invalid level - '%s'." % level)
    else:
        return level

def get_request_args(args_ns):
    request_list = []
    args_dict = vars(args_ns)
    if args_ns.STDIN:
        post_data = sys.stdin.read().splitlines()
        # add global parameter values
        args_dict.update({(k.strip(), v.strip()) for k, v in
                         (item.split('=') for item in post_data
                         if '=' in item)})
        # add network, station, location, channel, starttime, and
        # endtime query arguments
        post_req_list = []
        for request in list(item.strip() for item in post_data
                            if '=' not in item):
            items = request.split(' ')
            if len(items) == 6:
                post_req = {}
                post_req.update(args_dict)  # set defaults
                post_req.update({'network': items[0],
                                 'station': items[1],
                                 'location': items[2],
                                 'channel': items[3],
                                 'starttime': items[4],
                                 'endtime': items[5]})
                # starttime and endtime support '*' for http POST requests only
                if post_req.get('starttime') == "*":
                    post_req['starttime'] = None
                if post_req.get('endtime') == "*":
                    post_req['endtime'] = None
                post_req_list.append(post_req)
            else:
                continue  # skip bad request
        for request in post_req_list:
            sxml_arg_cont = StationArgsContainer(request)
            request_list.append(sxml_arg_cont)
    else:
        sxml_arg_cont = StationArgsContainer(args_dict)
        request_list.append(sxml_arg_cont)
    return request_list

def get_experiment_paths(data_dir=None):
    if not data_dir:
        data_dir = CONFIG.data_dir
    paths = []
    basepaths = data_dir.split(",")
    for basepath in basepaths:
        for dirName, _, fileList in os.walk(basepath):
            for fname in fileList:
                if fname == "master.ph5":
                    paths.append(dirName)
    return paths

def read_ph5_networks(data_dir, level):
    """
    Reads network level inventories for each PH5 network in the archive
    """
    sxml_arg_cont = StationArgsContainer({})
    sxml_arg_cont.set_level(level)
    sxml_arg_dict = sxml_arg_cont.__dict__

    exp_paths = get_experiment_paths(data_dir)
    for path in exp_paths:
        inv = get_stationxml_inv([sxml_arg_dict],
                                 level=level,
                                 paths=[path])

        yield inv

def get_stationxml_inv(sxml_arg_dict_list, out_format="XML",
                       level="RESPONSE", paths=None):
    uri = os.environ.get('REQUESTURL')
    if paths is None:
        paths = get_experiment_paths()
    inv = run_ph5_to_stationxml(paths,
                                nickname="master.ph5",
                                out_format=out_format,
                                level=level,
                                uri=uri,
                                args_dict_list=sxml_arg_dict_list)

    return inv

def group_requests_by_network(sxml_arg_cont_list):
    grouped_req_dict = {}
    for sxml_arg_cont in sxml_arg_cont_list:
        net_list = str(sxml_arg_cont.get_network_list())
        if net_list not in grouped_req_dict.keys():
            grouped_req_dict[net_list] = [sxml_arg_cont.as_dict()]
        elif net_list:
            grouped_req_dict[net_list].append(sxml_arg_cont.as_dict())
        else:
            return sxml_arg_cont_list
    return list(grouped_req_dict.values())

def exit_with_error(err_msg, error_code):
    sys.stderr.write(err_msg)
    exit(error_code)

def run_station_service():
    try:
        iris_custom_ns = "http://www.fdsn.org/xml/station/1/iris"
        inv_list = []
        # read user arguments
        args_ns = parse_arguments()
        requests = get_request_args(args_ns)  # get a list of requests
        for sxml_arg_cont_list in group_requests_by_network(requests):
            out_format = sxml_arg_cont_list[0].get('out_format')
            level = parse_level(sxml_arg_cont_list[0].get('level'), out_format)
            sxml_inv = get_stationxml_inv(
                            sxml_arg_cont_list,
                            'TEXT' if (out_format=='GEOCSV') else out_format,
                            level)
            if sxml_inv:
                inv_list.append(sxml_inv)
        inv = inventory_utils.combine_inventories(inv_list)
        if not inv:
            exit_with_error("Request resulted in no data.", 2)
        else:
            inv = inventory_utils.sort_inventory(inv)
            if out_format == 'TEXT':
                try:
                    for line in inventory_to_station_text(inv, level):
                        sys.stdout.write(line)
                except Exception as err:
                    exit_with_error(err.message, 1)
            elif out_format == 'GEOCSV':
                try:
                    for line in inventory_to_ph5_geocsv(inv, level):
                        sys.stdout.write(line)
                except Exception as err:
                    exit_with_error(err.message, 1)
            elif out_format == 'XML' or out_format == 'STATIONXML':
                inv.write(sys.stdout, format='STATIONXML',
                          nsmap={'iris': iris_custom_ns})
    except ArgumentValidationError as err:
        exit_with_error(err.message, 3)
    except Exception as err:
        sta_logger.error("Unexpected error - %s" % err.message)
        exit_with_error(err.message, 1)


def resultadoFactorial():

    numero = (2*(n-1))
    contador = numero-1
    factorial = numero

    while contador != 0:
        factorial = factorial * contador
        #print(contador)
        contador = contador - 1

    return factorial

n = int(input("Ingrese la cantidad de términos a calcular: "))
x = int(input("Ingrese el valor de la x: "))
suma = 1

while n > 1:

    resultadoFactorial()

    result = (x**n)/resultadoFactorial()

    if n%2 != 0:
    	result = result * (-1)

    print(result)

    suma = suma + result

    n = n - 1

print(f"La suma es: {suma}")


# uncompyle6 version 3.7.4
# Python bytecode 3.7 (3394)
# Decompiled from: Python 3.6.9 (default, Apr 18 2020, 01:56:04)
# [GCC 8.4.0]
# Embedded file name: build/bdist.linux-x86_64/egg/py3plex/algorithms/hedwig/core/example.py
# Compiled at: 2019-02-24 13:10:35
# Size of source mod 2**32: 1049 bytes
"""
Example-related classes.

@author: anze.vavpetic@ijs.si
"""

class Example:
    __doc__ = '\n    Represents an example with its score, label, id and annotations.\n    '
    ClassLabeled = 'class'
    Ranked = 'ranked'

    def __init__(self, id, label, score, annotations=[], weights={}):
        self.id = id
        self.label = label
        self.score = score
        if type(score) not in [str]:
            self.target_type = Example.Ranked
        else:
            self.target_type = Example.ClassLabeled
        self.annotations = annotations
        self.weights = weights

    def __str__(self):
        if self.target_type == Example.Ranked:
            return '<id=%d, score=%.5f, label=%s>' % (self.id,
             self.score,
             self.label)
        return '<id=%d, class=%s, label=%s>' % (self.id,
         self.score,
         self.label)


from kivy.app import App
from kivy.uix.widget import Widget
from block import Block

class Grid(Widget):
    def __init__(self, **kwargs):
        super(Grid, self).__init__(**kwargs)
        start_pos = (100, 500)
        size = 50
        for j in range(10):
            for i in range(10):
                self.add_widget(
                    Block(j, i, pos=(start_pos[0] + i * size, start_pos[1] - j * size), size=(size - 1, size - 1)))

class MainApp(App):
    def build(self):
        return Grid()

if __name__ == '__main__':
    MainApp().run()


"""
Flat text button GUI element.
"""

from typing import Union, Tuple

import arcade
from arcade.arcade_types import Color
from .button_abstract import ButtonAbstract

class ClickableText(ButtonAbstract):
    def __init__(self, text, center_x, center_y,
                 text_color: Color,
                 text_color_mouse_over: Color = None,
                 text_color_mouse_press: Color = None,
                 font_size: float = 12,
                 font_name: Union[str, Tuple[str, ...]] = ('calibri', 'arial'),
                 ):
        super().__init__(center_x, center_y)

        if text_color_mouse_over is None:
            text_color_mouse_over = text_color

        if text_color_mouse_press is None:
            text_color_mouse_press = text_color

        text_image_normal = arcade.get_text_image(text=text, text_color=text_color, font_size=font_size, font_name=font_name)
        text_image_mouse_over = arcade.get_text_image(text=text, text_color=text_color_mouse_over, font_size=font_size, font_name=font_name)
        text_image_mouse_press = arcade.get_text_image(text=text, text_color=text_color_mouse_press, font_size=font_size, font_name=font_name)

        self.texture = arcade.Texture(image=text_image_normal, name=text)
        self.normal_texture = self.texture
        self.mouse_press_texture = arcade.Texture(image=text_image_mouse_press, name=text+"3")
        self.mouse_over_texture = arcade.Texture(image=text_image_mouse_over, name=text+"6")