# Importing Modules

import os
import csv

# Path to ur CSV file

csvPyPoll = os.path.join("..", "PyPoll", "election_data.csv")

# Open file to read and get information out of it

with open(csvPyPoll, "r", newline = "") as csvfile:
    csvreader = csv.reader(csvfile, delimiter = ",")

    # Skipping first line in our file

    header = next(csvreader)

    # Create empty lists to iterate through specific rows

    voter_id = []
    county = []
    candidate = []

    # Looping though every single row (without header) to append each element in DATA to lists we made before

    for row in csvreader:
        voter_id.append(row[0])
        county.append(row[1])
        candidate.append(row[2])

    # The total number of votes cast

    total_votes = len(voter_id)

    # A complete list of candidates who received votes and the total number of votes each candidate won

    candidate_list = []     # creating empty list to store all candidate names
    candidate_votes = {}    # creating empty dictionary to store all votes for each candidate

    for name in candidate:
        if name not in candidate_list:
            candidate_list.append(name)
            candidate_votes[name] = 0
        candidate_votes[name] = candidate_votes[name] + 1

    # The percentage of votes each candidate won

    candidate_vote_percentage = {}    # creating empty dictionary to store all percentage for every candidate

    for element in candidate_list:
        candidate_vote_percentage[element] = (candidate_votes[element]/total_votes)*100

    # The winner of the election based on popular vote

    winner_votes =  0

    for candidate in candidate_votes:

        if candidate_votes[candidate] > winner_votes:
            winner_votes = candidate_votes[candidate]
            winner = candidate

with open("Election_Results.txt", "w") as file:

    file.write("Election Results")
    file.write("\n")
    file.write("---------------------------")
    file.write("\n")
    file.write(f"Total Votes: {total_votes}")
    file.write("\n")
    file.write(f"---------------------------")
    file.write("\n")

    print(f"""
Election Results
---------------------------
Total Votes: {total_votes}
---------------------------""")

    for person in candidate_votes:
        votes = candidate_votes[person]
        percentage = candidate_vote_percentage[person]

        print(f"{person}: {percentage:.3f}% ({votes})")

        file.write(f"{person}: {percentage:.3f}% ({votes})")
        file.write("\n")

    print(f"""
---------------------------
Winner:{winner}
---------------------------
        """)

    file.write("---------------------------")
    file.write("\n")
    file.write(f"Winner: {winner}")
    file.write("\n")
    file.write("---------------------------")


from selenium import webdriver
from selenium.webdriver.firefox.options import Options as FirefoxOptions
from selenium.webdriver.common.action_chains import ActionChains
from datetime import datetime
from PIL import Image
from io import BytesIO
import re
import shutil
import requests
import time
import os
import base64

directory = "src"
query = input("What would you like to search? ")
query.replace(" ", "+")
url = 'https://www.google.com/search?q='+str(query)
url = url + '&source=lnms&tbm=isch&sa=X&ved=2ahUKEwie44_AnqLpAhUhBWMBHUFGD90Q_'
url = url + 'AUoAXoECBUQAw&biw=1920&bih=947'
qty = int(input("How many pictures? "))
# Timestring so queries can be run more than once without conflict
runtime = datetime.now().strftime("%Y%m%d%H%M%S")
# run headless
options = FirefoxOptions()
options.add_argument("--headless")
driver = webdriver.Firefox(options=options)

def save_img(inp, img, i):
    try:
        filename = runtime + "_" + inp + "_" + str(i)+".jpg"
        image_path = os.path.join(os.getcwd(), directory, filename)
        if (img.startswith("http")):
            image = requests.get(img, stream=True)

            with open(image_path, "wb") as file:
                shutil.copyfileobj(image.raw, file)
        else:
            # Google sometimes stores images in base64 strings, this deals with
            # that
            print("Base64 image (lower res, Sorry!)")
            img = re.sub('^data:image/.+;base64,', '', img)
            byte_data = base64.b64decode(img)
            img_data = BytesIO(byte_data)
            imgfile = Image.open(img_data)
            imgfile.save(image_path, "jpeg")
    except Exception:
        print("Image failed to save!")
        pass

def scrape_images(input, url, driver, quantity):
    try:
        driver.get(url)
        time.sleep(3)
        for j in range(1, quantity+1):
            print("Downloading image: %d" % (j))
            imgurl = driver.find_element_by_xpath('//div//div//div//div//div//div//div//div//div//div['+str(j)+']//a[1]//div[1]//img[1]')
            imgurl.click()
            time.sleep(5)
            # n3VNCb
            # //body/div[2]/c-wiz/div[3]/div[2]/div[3]/div/div/div[3]/div[2]/c-wiz/div[1]/div[1]/div/div[2]/a/img
            try:
                img = driver.find_element_by_xpath("//body/div[2]/c-wiz/.//div[contains(@class, 'tvh9oe BIB1wf')]/.//img[contains(@class, 'n3VNCb')]").get_attribute("src")
            except Exception as b:
                print("Could not find HQ image Error: " % (str(b)))
                img = driver.find_element_by_xpath("//body/div[2]/c-wiz/.//img[contains(@class, 'n3VNCb')]").get_attribute("src")
            save_img(input, img, j)
    except Exception as e:
        print("Could not scrape")
        print(str(e))

scrape_images(query, url, driver, qty)
driver.close()


# from curses.ascii import isblank
from ast import dump
from enum import unique
from flask import Flask, make_response, abort
# importation de flask
from flask_sqlalchemy import SQLAlchemy
from urllib.parse import quote_plus
from flask import jsonify, request, json
from sqlalchemy import ForeignKey

app = Flask(__name__)  # lancement application Flask

app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://postgres:{}@localhost:5432/nom_base_de_donnees'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

db = SQLAlchemy(app)

class Categories(db.Model):
    __tablename__ = 'categories'
    id = db.Column(db.Integer, primary_key=True)
    nom = db.Column(db.String(20), nullable=False)
    libelle_categorie = db.Column(db.String(20), nullable=False)
    livres = db.relationship('Livres', backref='categories', lazy=True)

    def __init__(self, nom, libelle_categorie):
        self.nom = nom
        self.libelle_categorie = libelle_categorie

    def format(self):
        return{
            "id": self.id,
            "nom": self.nom,
            "libelle_categorie": self.libelle_categorie
        }

    def insert(self):
        db.session.add(self)
        db.session.commit()

    def delete(self):
        db.session.delete(self)
        db.session.commit()

    def update(self):
        db.session.commit()

class Livres(db.Model):
    __tablename__ = 'livres'
    id = db.Column(db.Integer, primary_key=True)
    isbn = db.Column(db.String(13), nullable=False)
    titre = db.Column(db.String(30), nullable=False)
    date_publication = db.Column(db.Date(), nullable=False)
    auteur = db.Column(db.String(30), nullable=False)
    editeur = db.Column(db.String(30), nullable=False)
    categorie_id = db.Column(db.Integer, db.ForeignKey(
        'categories.id'), nullable=False)

    def __init__(self, isbn, titre, date_publication, auteur, editeur, categorie_id):

        self.isbn = isbn
        self.titre = titre
        self.date_publication = date_publication
        self.auteur = auteur
        self.editeur = editeur
        self.categorie_id = categorie_id

    def format(self):
        return{
            "id":self.id,
            "isbn": self.isbn,
            "titre": self.titre,
            "date publication": self.date_publication,
            "auteur": self.auteur,
            "editeur": self.editeur,
            "id categorie": self.categorie_id
        }

    def insert(self):
        db.session.add(self)
        db.session.commit()

    def delete(self):
        db.session.delete(self)
        db.session.commit()

    def update(self):
        db.session.commit()

db.create_all()

#############################################################
#                                                           #
#                                                           #
#      TEST DE L'API                                        #
#                                                           #
#                                                           #
#############################################################

@app.route('/', methods=['GET'])
def test():
    return jsonify({"message": "bonjour"})

#############################################################
#                                                           #
#                                                           #
#      AFFICHAGE DE TOUS LES LIVRES                         #
#                                                           #
#                                                           #
#############################################################

# affiche tous les livres
@app.route('/livres', methods=['GET'])
def glivres():
    tlivres = Livres.query.order_by(Livres.id).all()
    Livres_format = [livre.format() for livre in tlivres]

    return jsonify({
        'success': True,
        'Livres': Livres_format,
        'nombre de livres': len(tlivres)
    })

#############################################################
#                                                           #
#                                                           #
#      SUPPRESSION D'UN LIVRE                               #
#                                                           #
#                                                           #
#############################################################
# suppression d'un livre
@app.route('/livres/<int:id>', methods=['DELETE'])
def supLivre(id):
    try:
        livre = Livres.query.get(id)
        if livre is None:
            abort(404)
        livre.delete()
        return jsonify({
            'success': True,
            'Livre supprimé': livre.id,
            'Nombre livre': len(Livres.query.all())
        })
    except:
        return abort(422)

#############################################################
#                                                           #
#                                                           #
#      MODIFICATION D'UN LIVRE                              #
#                                                           #
#                                                           #
#############################################################

# modifier un livre

@app.route('/livres/<int:id>', methods=['PATCH'])
def modifier_Livre(id):
    try:
        # recuperation de l'info passer en body
        body = request.get_json()
        livre = Livres.query.get(id)
        if livre is None:
            abort(404)
        else:

            livre.isbn = body.get('isbn')
            livre.titre = body.get('titre')
            livre.date_publication = body.get('date_publication')
            livre.auteur = body.get('auteur')
            livre.editeur = body.get('editeur')
            livre.categorie_id = body.get('categorie_id')

            categorie = Categories.query.get(body.get('categorie_id'))
            if categorie is None:
                abort(404)
            livre.update()
            livres = Livres.query.all()
            return ({
                "success": True,
                #"id livre": livres.id,
                "Nombre de livre": len(livres),
                #"Liste de livres": [livree.format() for livree in livres]

            })
    except:
        return abort(400)

#############################################################
#                                                           #
#                                                           #
#      SELECTION D'UN LIVRE                                 #
#                                                           #
#                                                           #
#############################################################

# afficher un Livre par rapport a son id
@app.route('/livres/<int:id>')
def selectionner_Livre(id):
    try:
        livre = Livres.query.get(id)
        if livre is None:
            abort(404)
        else:
            return jsonify({
                'success': True,
                'livre': livre.format()
            })
    except:
        return jsonify({
                'success': False,
                'msg': 'Not Found'
        })

#############################################################
#                                                           #
#                                                           #
#      ENREGISTREMENT DES LIVRES                            #
#                                                           #
#                                                           #
#############################################################

@app.route('/enrgLivre', methods=['POST'])
def enregistrer_livres():
    try:
        # recuperation des donnees envoye par json dans une variable body
        body = request.get_json()
        new_isbn = body.get('isbn')
        new_titre = body.get('titre')
        new_date = body.get("date_publication")
        new_auteur = body.get('auteur')
        new_editeur = body.get('editeur')
        new_categorie = body.get('categorie_id')

        categoriees = Categories.query.get(new_categorie)
        if categoriees is None:
            abort(404)
        else:

            livre = Livres(isbn=new_isbn, titre=new_titre, auteur=new_auteur, date_publication=new_date,
                        editeur=new_editeur, categorie_id=new_categorie)
            livre.insert()
            return jsonify({
                "success": True,
                "id_livre": livre.id,
                "Nombre_livres": len(Livres.query.all()),
                "Liste_livres": [livres.format() for livres in Livres.query.all()]
            })
    except:
        return abort(400)

#############################################################
#                                                           #
#                                                           #
#      SUPPRESSION D'UNE CATEGORIE                          #
#                                                           #
#                                                           #
#############################################################
@app.route('/supCat/<int:id>', methods=['DELETE'])
def suppCat(id):
    try:
        categ = Categories.query.get(id)
        catego = Categories.query.all()
        if categ is None:
            abort(404)
        categ.delete()
        return ({
            "success": True,
            "deleted": categ.id,
            "Nombre categorie": len(catego),
            # "Liste categorie": [catg.format() for catg in catego]
        })
    except:
        return abort(422)

#############################################################
#                                                           #
#                                                           #
#      MODIFICATION D'UNE CATEGORIE                         #
#                                                           #
#                                                           #
#############################################################
@app.route('/upCat/<int:id>', methods=['PATCH'])
def modifier_Cat(id):
    try:
        body = request.get_json()
        categ = Categories.query.get(id)
        if categ is None:
            abort(404)
        else:
            categ.libelle_categorie = body.get('libelle_categorie', None)
            categ.nom=body.get('nom')
            categ.update()
            return jsonify({
                'success': True,
                'id categorie': categ.id
            })
    except:
        return abort(400)

#############################################################
#                                                           #
#                                                           #
#      ENREGISTREMENT DES CATEGORIES                        #
#                                                           #
#                                                           #
#############################################################
@app.route('/enrgCat', methods=['POST'])
def pCat():
    try:
        body = request.get_json()
        new_nom = body.get('nom')
        new_libelle = body.get('libelle_categorie')

        #   vCat = Categories.query.filter_by(new_nom)
        #   if vCat is not None:
        #          return jsonify({
        #                 "msg":"cette categorie existe deja!"
        #          })
        #   else:
        categorie = Categories(nom=new_nom, libelle_categorie=new_libelle)
        categorie.insert()
        categs = Categories.query.order_by(Categories.id).all()

        return jsonify({
            "msg": "La categorie est enregistre avec success",
            "id categorie": categorie.id,
            "Nombre de categorie": len(Categories.query.all()),
            "Liste Categorie": [categories.format() for categories in categs]

        })
    except:
        return abort(400)

#############################################################
#                                                           #
#                                                           #
#      AFFICHAGE DE TOUTES LES CATEGORIES                   #
#                                                           #
#                                                           #
#############################################################
@app.route('/categorie', methods=['GET'])
def Liste_Cat():
    try:
        ListeCategorie = Categories.query.order_by(Categories.id).all()
        categs = [categoriees.format() for categoriees in ListeCategorie]
        if ListeCategorie is None:
            abort(404)
        else:
            return jsonify({
                "success": True,
                "Liste categories": categs,
                "nombre categories": len(ListeCategorie)
            })
    except:
        return abort(400)

#############################################################
#                                                           #
#                                                           #
#      SELECTION D'UNE CATEGORIE                            #
#                                                           #
#                                                           #
#############################################################
@app.route('/categorie/<int:id>')
def selectionner_categorie(id):
    try:
        categorie = Categories.query.get(id)
        if categorie is None:
            abort(404)
        else:
            return jsonify({
                'success': True,
                'Categorie': categorie.format()
            })
    except:
        return abort(404)

#############################################################
#                                                           #
#                                                           #
#      GESTION DES ERREURS                                  #
#                                                           #
#                                                           #
#############################################################

@app.errorhandler(404)
def handle_404_error(_error):
    return make_response(jsonify({
        "success":False,
        "error_type":"404",
        "error": "Non retrouvé parmis ceux existant!!"
        }),404)

@app.errorhandler(500)
def handle_500_error(_error):
    return make_response(jsonify({
        "success":False,
        "error_type":"500",
        "error": "Erreur en interne(base ou code) !!"
        }),500)

@app.errorhandler(405)
def handle_405_error(_error):
    return make_response(jsonify({
        "success":False,
        "error_type":"405",
        "error": "Méthode non autorisé!!"
                                  }),405)

@app.errorhandler(401)
def handle_401_error(_error):
    return make_response(jsonify({
        "success":False,
        "error_type":"401",
        "error": "Cette action ne peut être autorisé!!"
        }),401)

@app.errorhandler(400)
def handle_400_error(_error):
    return make_response(jsonify({
        "success":False,
        "error_type":"400",
        "error": "Mauvaise requête!!"
        }),400)

@app.errorhandler(422)
def handle_422_error(_error):
    return make_response(jsonify({
        "success":False,
        "error_type":"422",
        "error": "Unprocessable ou Syntaxe requete incorrecte!!"
        }),422)


# -*- coding: utf-8 -*-
"""
Usage:
    THEANO_FLAGS="device=gpu0" python exptBikeNYC.py
"""

import os
import  pickle
import numpy as np
import math

from keras.optimizers import Adam
from keras.callbacks import EarlyStopping, ModelCheckpoint
from deepst.models.Model import stresnet
from deepst.config import Config
import deepst.metrics as metrics
from deepst.datasets import SubwayBJ
np.random.seed(1337)  # for reproducibility
import h5py
from keras.utils import np_utils
from keras.utils.vis_utils import plot_model

CACHEDATA = True
DATAPATH = Config().DATAPATH
nb_epoch = 200
nb_epoch_cont = 200
batch_size = 32
T = 24  # number of time intervals in one day

lr = 0.0008
len_closeness = 4
len_period = 2
len_trend = 2
nb_residual_unit = 4

nb_flow = 2
days_test = 9
len_test = T * days_test
map_height, map_width = 268, 11
nb_area = 268
m_factor =  math.sqrt(1. * map_height * map_width / nb_area)
print('factor: ', m_factor)
path_result = 'RET'
path_model = 'MODEL'

if os.path.isdir(path_result) is False:
    os.mkdir(path_result)
if os.path.isdir(path_model) is False:
    os.mkdir(path_model)

def build_model(external_dim):
    c_conf = (len_closeness, nb_flow, map_height,
              map_width) if len_closeness > 0 else None
    p_conf = (len_period, nb_flow, map_height,
              map_width) if len_period > 0 else None
    t_conf = (len_trend, nb_flow, map_height,
              map_width) if len_trend > 0 else None

    model = stresnet(c_conf=c_conf, p_conf=p_conf, t_conf=t_conf,
                     external_dim=external_dim, nb_residual_unit=nb_residual_unit)
    adam = Adam(lr=lr)
    model.compile(loss='mse', optimizer=adam, metrics=[metrics.rmse,metrics.rmseIn,metrics.rmseOut])
    model.summary()
    plot_model(model, to_file='modelgridcnn.png', show_shapes=True)
    return model

def read_cache(fname):
    mmn = pickle.load(open('preprocessing.pkl', 'rb'))

    f = h5py.File(fname, 'r')
    num = int(f['num'].value)
    X_train, Y_train, X_test, Y_test = [], [], [], []
    #for i in xrange(num):
    for i in range(num):
        X_train.append(f['X_train_%i' % i].value)
        X_test.append(f['X_test_%i' % i].value)
    Y_train = f['Y_train'].value
    Y_test = f['Y_test'].value
    external_dim = f['external_dim'].value
    timestamp_train = f['T_train'].value
    timestamp_test = f['T_test'].value
    f.close()
    return X_train, Y_train, X_test, Y_test, mmn, external_dim, timestamp_train, timestamp_test

def cache(fname, X_train, Y_train, X_test, Y_test, external_dim, timestamp_train, timestamp_test):
    h5 = h5py.File(fname, 'w')
    h5.create_dataset('num', data=len(X_train))

    for i, data in enumerate(X_train):
        h5.create_dataset('X_train_%i' % i, data=data)
    for i, data in enumerate(X_test):
        h5.create_dataset('X_test_%i' % i, data=data)
    h5.create_dataset('Y_train', data=Y_train)
    h5.create_dataset('Y_test', data=Y_test)
    external_dim = -1 if external_dim is None else int(external_dim)
    h5.create_dataset('external_dim', data=external_dim)
    h5.create_dataset('T_train', data=timestamp_train)
    h5.create_dataset('T_test', data=timestamp_test)
    h5.close()

def main():
    # load data
    print("loading data...")
#     X_train, Y_train, X_test, Y_test, mmn, external_dim, timestamp_train, timestamp_test = BikeNYC.load_data(
#         T=T, nb_flow=nb_flow, len_closeness=len_closeness, len_period=len_period, len_trend=len_trend, len_test=len_test,
#         preprocess_name='preprocessing.pkl', meta_data=True)
    fname = os.path.join(DATAPATH, 'CACHE', 'BJSubway_C{}_P{}_T{}.h5'.format(
        len_closeness, len_period, len_trend))
    if os.path.exists(fname) and CACHEDATA:
        X_train, Y_train, X_test, Y_test, mmn, external_dim, timestamp_train, timestamp_test = read_cache(
            fname)
        print("load %s successfully" % fname)
    else:
        X_train, Y_train, X_test, Y_test, mmn, external_dim, timestamp_train, timestamp_test = SubwayBJ.load_data(
            T=T, nb_flow=nb_flow, len_closeness=len_closeness, len_period=len_period, len_trend=len_trend, len_test=len_test,
            preprocess_name='preprocessing.pkl', meta_data=True)
        if CACHEDATA:
            cache(fname, X_train, Y_train, X_test, Y_test, external_dim, timestamp_train, timestamp_test)

    print("\n days (test): ", [v[:8] for v in timestamp_test[0::T]])
    print('=' * 10)
    print("compiling model...")
    model = build_model(external_dim)
    print(model.metrics_names)
    #保存超参数名字
    hyperparams_name = 'c{}.p{}.t{}.resunit{}.lr{}'.format(len_closeness, len_period, len_trend, nb_residual_unit, lr)
    fname_param = os.path.join('MODEL', '{}.best.h5'.format(hyperparams_name))
    early_stopping = EarlyStopping(monitor='val_rmse', patience=5, mode='min')
    model_checkpoint = ModelCheckpoint(fname_param, monitor='val_rmse', verbose=0, save_best_only=True, mode='min')
    print('=' * 10)
    print("training model...")
    history = model.fit(X_train, Y_train,
                        nb_epoch=nb_epoch,
                        batch_size=batch_size,
                        validation_split=0.1,
                        callbacks=[early_stopping, model_checkpoint],
                        verbose=1)
    model.save_weights(os.path.join('MODEL', '{}.h5'.format(hyperparams_name)), overwrite=True)
    pickle.dump((history.history), open(os.path.join(path_result, '{}.history.pkl'.format(hyperparams_name)), 'wb'))
    print('=' * 10)
    print('evaluating using the model that has the best loss on the valid set')

    model.load_weights(fname_param)
    score = model.evaluate(X_train, Y_train, batch_size=Y_train.shape[0] // 48, verbose=0)
    print('Train score: %.6f rmse (norm): %.6f rmse (real): %.6f' %(score[0], score[1], score[1] * (mmn._max - mmn._min) / 2. * m_factor))

    score = model.evaluate(X_test, Y_test, batch_size=Y_test.shape[0], verbose=0)
    print('Test score: %.6f rmse (norm): %.6f rmse (real): %.6f' %(score[0], score[1], score[1] * (mmn._max - mmn._min) / 2. * m_factor))

    print('=' * 10)
    print("training model (cont)...")
    fname_param = os.path.join('MODEL', '{}.cont.best.h5'.format(hyperparams_name))
    model_checkpoint = ModelCheckpoint(fname_param, monitor='rmse', verbose=0, save_best_only=True, mode='min')
    history = model.fit(X_train, Y_train, nb_epoch=nb_epoch_cont, verbose=1, batch_size=batch_size, callbacks=[model_checkpoint], validation_data=(X_test, Y_test))
    pickle.dump((history.history), open(os.path.join(path_result, '{}.cont.history.pkl'.format(hyperparams_name)), 'wb'))
    model.save_weights(os.path.join('MODEL', '{}_cont.h5'.format(hyperparams_name)), overwrite=True)

    print('=' * 10)
    print('evaluating using the final model')
    score = model.evaluate(X_train, Y_train, batch_size=Y_train.shape[0] // 48, verbose=0)
    print('Train score: %.6f rmse (norm): %.6f rmse (real): %.6f' %(score[0], score[1], score[1] * (mmn._max - mmn._min) ))#/ 2. * m_factor))

    score = model.evaluate(X_test, Y_test, batch_size=Y_test.shape[0], verbose=0)
    print('Test score: %.6f rmse (norm): %.6f rmse (real): %.6f' %(score[0], score[1], score[1] * (mmn._max - mmn._min) ))#/ 2. * m_factor))

if __name__ == '__main__':
    main()


import numpy as np
import pandas as pd
from scipy import io, stats
import seaborn as sns
from matplotlib import pyplot as plt

# Convenience functions to handle data import
def import_expression_data(mtx_gene_exp_fil, barcodes_fil, features_fil):

    gene_expression = io.mmread(mtx_gene_exp_fil)
    barcodes = pd.read_csv(barcodes_fil, header=None)[0]
    features = pd.read_csv(features_fil, header=None)[0]

    gene_expression = pd.DataFrame(gene_expression.toarray(), index=barcodes, columns=features)

    return gene_expression

# Insert your code into the function shells below
def task_1_a(relative_path_to_data = '../exercise_1_data/'):

    gene_expression = import_expression_data(relative_path_to_data+'expression_data_1.mtx',
                                             relative_path_to_data+'expression_data_1_barcodes.tsv',
                                             relative_path_to_data+'expression_data_1_genes.tsv')
    cell_annotations = pd.read_csv(relative_path_to_data+'expression_data_1_metadata.tsv', sep='\t', index_col=0)

    organ_identity = {'A': '', 'B': '', 'C': '', 'D': '', 'E': '', 'F': ''}
    cell_type_identity = {'T1': '', 'T2': '', 'T3': '', 'T4': '', 'T5': ''}

    '''Insert your code here and update the dictionaries with your identification.
    Take care to use the same annotations are used in the paper.'''

    organ_identity = pd.Series(organ_identity).to_frame()
    cell_type_identity = pd.Series(cell_type_identity).to_frame()

    return organ_identity, cell_type_identity

def task_1_b(relative_path_to_data = '../exercise_1_data/'):

    gene_expression = import_expression_data(relative_path_to_data+'expression_data_2.mtx',
                                             relative_path_to_data+'expression_data_2_barcodes.tsv',
                                             relative_path_to_data+'expression_data_2_genes.tsv')

    cell_annotations = pd.DataFrame(index=gene_expression.index.values, columns=['phenotype'])

    '''Insert code here and update the cell_annotations dataframe with the phenotypes.
       Take care to use the same annotations are used in the paper.'''

    return cell_annotations

def task_2_a(relative_path_to_data = '../exercise_1_data/'):

    cell_sequences = np.load(relative_path_to_data+'tex_sampling.npy')
    cell_annotations = pd.read_csv(relative_path_to_data+'expression_data_3_metadata.txt', sep='\t', index_col=0)

    upper_trajectory_louvain_ordering = []
    lower_trajectory_louvain_ordering = []

    '''Insert code here and append each list with the sequence of louvain clusters.'''

    return upper_trajectory_louvain_ordering, lower_trajectory_louvain_ordering

def task_2_b(relative_path_to_data = '../exercise_1_data/'):

    gene_expression = import_expression_data(relative_path_to_data+'expression_data_3.mtx',
                                             relative_path_to_data+'expression_data_3_barcodes.tsv',
                                             relative_path_to_data+'expression_data_3_genes.tsv')

    cell_annotations = pd.read_csv(relative_path_to_data+'expression_data_3_metadata.txt', sep='\t', index_col=0)

    gene_correlations = pd.DataFrame(index=gene_expression.columns.values, columns=['correlation', 'p-values'])

    '''Insert your code here.'''

    return gene_correlations

# Run the code after updating all the functions
def main(relative_path_to_data = '../exercise_1_data/', output_path=''):

    #Task 1A output
    t1_organ_identity, t1_cell_type_identity = task_1_a(relative_path_to_data)
    t1_organ_identity.to_csv(output_path+'t1_organ_identity.txt', header=False)
    t1_cell_type_identity.to_csv(output_path+'t1_celltype_identity.txt', header=False)

    t1b_cell_annotations = task_1_b(relative_path_to_data)
    t1b_cell_annotations.to_csv(output_path+'t1b_cell_annotations.txt', sep='\t')

    t2a_upper_trajectory_louvain_ordering, t2a_lower_trajectory_louvain_ordering = task_2_a(relative_path_to_data)
    pd.DataFrame(t2a_upper_trajectory_louvain_ordering).to_csv(output_path+'t2a_upper_louvain_sequence.txt', header=False)
    pd.DataFrame(t2a_lower_trajectory_louvain_ordering).to_csv(output_path+'t2a_lower_louvain_sequence.txt', header=False)

    t2b_gene_correlations = task_2_b(relative_path_to_data)
    t2b_gene_correlations.sort_values('correlation').iloc[:10].to_csv(output_path+'t2b_gene_correlations.txt', sep='\t')

    sns.scatterplot(t2b_gene_correlations.correlation, -np.log(t2b_gene_correlations['p-values']))
    plt.savefig('t2b_volcano_plot.png')

    return t1_cell_type_identity, t1_cell_type_identity, t1b_cell_annotations, t2a_upper_trajectory_louvain_ordering, t2a_lower_trajectory_louvain_ordering, t2b_gene_correlations

if __name__ == "__main__":

    # Update paths if required
    t1_cell_type_identity, t1_cell_type_identity, t1b_cell_annotations, t2a_upper_trajectory_louvain_ordering,
    t2a_lower_trajectory_louvain_ordering, t2b_gene_correlations = main('../exercise_1_data/', './')


import json
import functools

from django import http

def autocomplete_result(func):
    @functools.wraps(func)
    def inner(request, *args, **kwargs):
        name = request.GET.get('q', None)
        if not name:
            raise http.Http404()
        limit = int(request.GET.get('limit', 10))
        limit = min(limit, 40)
        args = (request, ) + args + (name, limit)
        items = func(*args, **kwargs)
        result = []
        for item in items:
            result.append((item.id, str(item)))
        return http.HttpResponse(json.dumps(result))
    return inner


import tkinter
import tkinter.messagebox

from solentware_grid.gui.dataedit import RecordEdit
from solentware_grid.gui.datadelete import RecordDelete
from solentware_grid.core.dataclient import DataNotify

from solentware_bind.gui.bindings import Bindings

from .cql import CQL
from .cqledit import CQLEdit
from ..core.chessrecord import ChessDBrecordPartial
from ..core.cqlstatement import CQLStatement
from .eventspec import EventSpec
from .display import Display
from .displaytext import (
    ShowText,
    InsertText,
    EditText,
    DisplayText,
    ListGamesText,
)

class CQLDisplayListGamesError(Exception):
    """Exception class for display of lists of games."""

class _CQLDisplay(ShowText, DisplayText, CQL, Display, Bindings, DataNotify):
    """Extend and link ChessQL statement to database.

    sourceobject - link to database.

    Attribute binding_labels specifies the order navigation bindings appear
    in popup menus.

    Method _insert_item_database allows records to be inserted into a database
    from any CQL widget.

    """

    binding_labels = (
        EventSpec.navigate_to_position_grid,
        EventSpec.navigate_to_active_game,
        EventSpec.navigate_to_game_grid,
        EventSpec.navigate_to_repertoire_grid,
        EventSpec.navigate_to_active_repertoire,
        EventSpec.navigate_to_repertoire_game_grid,
        EventSpec.navigate_to_partial_grid,
        EventSpec.partialdisplay_to_previous_partial,
        EventSpec.partialdisplay_to_next_partial,
        EventSpec.navigate_to_partial_game_grid,
        EventSpec.navigate_to_selection_rule_grid,
        EventSpec.navigate_to_active_selection_rule,
        EventSpec.tab_traverse_backward,
        EventSpec.tab_traverse_forward,
    )

    def __init__(self, sourceobject=None, **ka):
        """Extend and link ChessQL statement to database."""
        super().__init__(**ka)
        self.blockchange = False
        if self.ui.base_partials.datasource:
            self.set_data_source(self.ui.base_partials.get_data_source())
        self.sourceobject = sourceobject
        self.insertonly = sourceobject is None
        self.recalculate_after_edit = sourceobject

    @property
    def ui_displayed_items(self):
        """Return manager of widgets displaying a partial position record."""
        return self.ui.partial_items

    @property
    def ui_configure_item_list_grid(self):
        """Return function to configure partial position grid to fit text."""
        return self.ui.configure_partial_grid

    @property
    def ui_set_item_name(self):
        """Return function to set status bar text to name of active query."""
        return self.ui.set_partial_name

    @property
    def ui_set_find_item_games(self):
        """Return function to set status bar text."""
        return self.ui.set_find_partial_name_games

    def _get_navigation_events(self):
        """Return event description tuple for navigation from query."""
        return (
            (EventSpec.navigate_to_partial_grid, self.set_focus_partial_grid),
            (EventSpec.partialdisplay_to_previous_partial, self._prior_item),
            (EventSpec.partialdisplay_to_next_partial, self._next_item),
            (
                EventSpec.navigate_to_partial_game_grid,
                self.set_focus_partial_game_grid,
            ),
            (
                EventSpec.navigate_to_repertoire_grid,
                self.set_focus_repertoire_grid,
            ),
            (
                EventSpec.navigate_to_active_repertoire,
                self.set_focus_repertoirepanel_item,
            ),
            (
                EventSpec.navigate_to_repertoire_game_grid,
                self.set_focus_repertoire_game_grid,
            ),
            (
                EventSpec.navigate_to_position_grid,
                self.set_focus_position_grid,
            ),
            (EventSpec.navigate_to_active_game, self.set_focus_gamepanel_item),
            (
                EventSpec.navigate_to_selection_rule_grid,
                self.set_focus_selection_rule_grid,
            ),
            (
                EventSpec.navigate_to_active_selection_rule,
                self.set_focus_selectionpanel_item,
            ),
            (EventSpec.navigate_to_game_grid, self.set_focus_game_grid),
            (EventSpec.export_from_partialdisplay, self._export_partial),
            (EventSpec.tab_traverse_forward, self.traverse_forward),
            (EventSpec.tab_traverse_backward, self.traverse_backward),
            (EventSpec.tab_traverse_round, self.traverse_round),
        )

    def delete_item_view(self, event=None):
        """Remove ChessQL statement item from screen."""
        del event
        self.ui.delete_position_view(self)

    def _insert_item_database(self, event=None):
        """Add ChessQL statement to database."""
        del event
        if self.ui.partial_items.active_item is None:
            tkinter.messagebox.showinfo(
                parent=self.ui.get_toplevel(),
                title="Insert ChessQL Statement",
                message="No active ChessQL statement to insert into database.",
            )
            return

        # This should see if ChessQL statement with same name already exists,
        # after checking for database open, and offer option to insert anyway.
        if self.ui.database is None:
            tkinter.messagebox.showinfo(
                parent=self.ui.get_toplevel(),
                title="Insert ChessQL Statement",
                message="Cannot add ChessQL statement:\n\nNo database open.",
            )
            return

        datasource = self.ui.base_partials.get_data_source()
        if datasource is None:
            tkinter.messagebox.showinfo(
                parent=self.ui.get_toplevel(),
                title="Insert ChessQL Statement",
                message="".join(
                    (
                        "Cannot add ChessQL statement:\n\n",
                        "Partial position list hidden.",
                    )
                ),
            )
            return
        updater = ChessDBrecordPartial()
        updater.value.process_statement(self.get_name_cql_statement_text())
        title = "Insert ChessQL Statement"
        tname = title.replace("Insert ", "").replace("S", "s")
        if not updater.value.get_name_text():
            tkinter.messagebox.showerror(
                parent=self.ui.get_toplevel(),
                title=title,
                message="".join(
                    (
                        "The '",
                        tname,
                        " has no name.\n\nPlease enter it's ",
                        "name as the first line of text.'",
                    )
                ),
            )
            return
        message = [
            "".join(
                (
                    "Confirm request to add ",
                    tname,
                    " named:\n\n",
                    updater.value.get_name_text(),
                    "\n\nto database.\n\n",
                )
            )
        ]
        if not updater.value.cql_error:
            if tkinter.messagebox.YES != tkinter.messagebox.askquestion(
                parent=self.ui.get_toplevel(),
                title=title,
                message="".join(message),
            ):
                tkinter.messagebox.showinfo(
                    parent=self.ui.get_toplevel(),
                    title=title,
                    message=tname.join(("Add ", " to database abandonned.")),
                )
                return
        else:
            message.append(updater.value.cql_error.get_error_report())
            if tkinter.messagebox.YES != tkinter.messagebox.askquestion(
                parent=self.ui.get_toplevel(),
                title=title,
                message="".join(message),
            ):
                tkinter.messagebox.showinfo(
                    parent=self.ui.get_toplevel(),
                    title=title,
                    message=tname.join(("Add ", " to database abandonned.")),
                )
                return
        editor = RecordEdit(updater, None)
        editor.set_data_source(datasource, editor.on_data_change)
        updater.set_database(editor.get_data_source().dbhome)
        updater.key.recno = None  # 0
        editor.put()
        tkinter.messagebox.showinfo(
            parent=self.ui.get_toplevel(),
            title=title,
            message="".join(
                (
                    tname,
                    ' "',
                    updater.value.get_name_text(),
                    '" added to database.',
                )
            ),
        )

    def on_game_change(self, instance):
        """Recalculate list of games for ChessQL statement after game update.

        instance is ignored: it is assumed a recalculation is needed.

        """
        del instance
        if self.sourceobject is not None:
            self._get_cql_statement_games_to_grid(
                self.cql_statement
            )  # .match)

    def generate_popup_navigation_maps(self):
        """Return genenal and current widget navigation binding maps."""
        navigation_map = dict(self._get_navigation_events())
        local_map = {}
        return navigation_map, local_map

    def _create_primary_activity_popup(self):
        """Delegate then add close command to popup and return popup menu."""
        popup = super()._create_primary_activity_popup()
        self._add_close_item_entry_to_popup(popup)
        return popup

    def on_partial_change(self, instance):
        """Prevent update from self if instance refers to same record."""
        if instance.newrecord:

            # Editing an existing record.
            value = instance.newrecord.value
            key = instance.newrecord.key

        else:

            # Inserting a new record or deleting an existing record.
            value = instance.value
            key = instance.key

        if self.sourceobject is not None:
            if (
                key == self.sourceobject.key
                and self.datasource.dbname == self.sourceobject.dbname
                and self.datasource.dbset == self.sourceobject.dbset
            ):
                self.blockchange = True

        pds = self.ui.partial_games.datasource
        if self.sourceobject is not None and key != self.sourceobject.key:
            pass
        elif self is not self.ui.partial_items.active_item:
            pass
        elif instance.newrecord is None:
            pds.forget_cql_statement_games(instance)
        elif instance.newrecord is False:
            try:
                pds.update_cql_statement_games(instance)
            except AttributeError as exc:
                if str(exc) == "'NoneType' object has no attribute 'answer'":
                    msg = "".join(
                        (
                            "Unable to add ChessQL statement to database, ",
                            "probably because an 'empty square' is in the ",
                            "query (eg '.a2-3'):\n\nThe reported  error ",
                            "is:\n\n",
                            str(exc),
                        )
                    )
                else:
                    msg = "".join(
                        (
                            "Unable to add ChessQL statement to database:\n\n",
                            "The reported error is:\n\n",
                            str(exc),
                        )
                    )
                tkinter.messagebox.showinfo(
                    parent=self.ui.get_toplevel(),
                    title="Insert ChessQL Statement",
                    message=msg,
                )
                return
        else:

            # Unfortunatly the existing list will have to be recalculated if
            # one of the caught exceptions occurs.
            pds.forget_cql_statement_games(instance)
            try:
                pds.update_cql_statement_games(instance.newrecord)
            except AttributeError as exc:
                if str(exc) == "'NoneType' object has no attribute 'answer'":
                    msg = "".join(
                        (
                            "Unable to edit ChessQL statement on database, ",
                            "probably because an 'empty square' is in the ",
                            "query (eg '.a2-3'):\n\nThe reported  error ",
                            "is:\n\n",
                            str(exc),
                        )
                    )
                else:
                    msg = "".join(
                        (
                            "Unable to edit ChessQL statement on database:",
                            "\n\nThe reported error is:\n\n",
                            str(exc),
                        )
                    )
                tkinter.messagebox.showinfo(
                    parent=self.ui.get_toplevel(),
                    title="Insert ChessQL Statement",
                    message=msg,
                )
                return

        if self is self.ui.partial_items.active_item:
            if self.sourceobject is not None and key == self.sourceobject.key:

                # Maybe should create a new CQLStatement instance.
                # self.cql_statement is a CQLStatement instance.
                # value is a ChessDBvaluePartial instance.
                self.cql_statement = value
                self.set_and_tag_item_text()
                self._get_cql_statement_games_to_grid(value)

    def get_text_for_statusbar(self):
        """Return 'Please wait ..' message for status bar."""
        return "".join(
            (
                "Please wait while finding games for ChessQL statement ",
                self.cql_statement.get_name_text(),
            )
        )

    def get_selection_text_for_statusbar(self):
        """Return CQL query name text for display in status bar."""
        return self.cql_statement.get_name_text()

    def set_game_list(self):
        """Delegate to refresh_game_list via 'after(...) call."""
        self.panel.after(
            0, func=self.try_command(self.ui.set_partial_name, self.panel)
        )
        self.panel.after(
            0, func=self.try_command(self.refresh_game_list, self.panel)
        )

    def _get_cql_statement_games_to_grid(self, statement):  # match):
        """Populate Partial Position games grid with games selected by match.

        "match" is named for the CQL version-1.0 keyword which started a CQL
        statement.  Usage is "(match ..." which become "cql(" no later than
        version 5.0 of CQL.  Thus "cql" is now a better name for the argument.

        """
        pgd = self.ui.partial_games
        if len(pgd.keys):
            key = pgd.keys[0]
        else:
            key = None
        pgd.close_client_cursor()
        try:
            pgd.datasource.get_cql_statement_games(
                statement, self.sourceobject
            )
        except AttributeError as exc:
            if str(exc) == "'NoneType' object has no attribute 'answer'":
                msg = "".join(
                    (
                        "Unable to list games for ChessQL statement, ",
                        "probably because an 'empty square' is in the query ",
                        "(eg '.a2-3'):\n\nThe reported  error is:\n\n",
                        str(exc),
                    )
                )
            else:
                msg = "".join(
                    (
                        "Unable to list games for ChessQL statement:\n\n",
                        "The reported error is:\n\n",
                        str(exc),
                    )
                )
            tkinter.messagebox.showinfo(
                parent=self.ui.get_toplevel(),
                title="Delete ChessQL Statement",
                message=msg,
            )
            return
        pgd.fill_view(currentkey=key, exclude=False)
        if pgd.datasource.not_implemented:
            tkinter.messagebox.showinfo(
                parent=self.ui.get_toplevel(),
                title="ChessQL Statement Not Implemented",
                message="".join(
                    (
                        "These filters are not implemented and ",
                        "are ignored:\n\n",
                        "\n".join(sorted(pgd.datasource.not_implemented)),
                    )
                ),
            )

class CQLDisplay(_CQLDisplay, CQL, DataNotify):
    """Display ChessQL statement from database and allow delete and insert.

    Method _delete_item_database allows records to be deleted from a database.

    """

    def _delete_item_database(self, event=None):
        """Remove ChessQL statement from database."""
        del event
        if self.ui.database is None:
            tkinter.messagebox.showinfo(
                parent=self.ui.get_toplevel(),
                title="Delete ChessQL Statement",
                message="".join(
                    (
                        "Cannot delete ChessQL statement:\n\n",
                        "No database open.",
                    )
                ),
            )
            return
        datasource = self.ui.base_partials.get_data_source()
        if datasource is None:
            tkinter.messagebox.showerror(
                parent=self.ui.get_toplevel(),
                title="Delete ChessQL Statement",
                message="".join(
                    (
                        "Cannot delete ChessQL statement:\n\n",
                        "ChessQL statement list hidden.",
                    )
                ),
            )
            return
        if self.sourceobject is None:
            tkinter.messagebox.showinfo(
                parent=self.ui.get_toplevel(),
                title="Delete ChessQL Statement",
                message="".join(
                    (
                        "The ChessQL statement to delete has not ",
                        "been given.\n\nProbably because database ",
                        "has been closed and opened since this copy ",
                        "was displayed.",
                    )
                ),
            )
            return
        if self.blockchange:
            tkinter.messagebox.showinfo(
                parent=self.ui.get_toplevel(),
                title="Delete ChessQL Statement",
                message="\n".join(
                    (
                        "Cannot delete ChessQL statement.",
                        "Record has been amended since this copy displayed.",
                    )
                ),
            )
            return
        if tkinter.messagebox.YES != tkinter.messagebox.askquestion(
            parent=self.ui.get_toplevel(),
            title="Delete ChessQL Statement",
            message="Confirm request to delete ChessQL statement.",
        ):
            return
        statement = self.cql_statement

        # Consider changing this since the call no longer ever returns None.
        if statement.is_statement() is not None:

            value = self.sourceobject.value
            if (
                statement.get_name_text() != value.get_name_text()
                or statement.is_statement() != value.is_statement()
                or statement.get_statement_text() != value.get_statement_text()
            ):
                tkinter.messagebox.showinfo(
                    parent=self.ui.get_toplevel(),
                    title="Delete ChessQL Statement",
                    message="\n".join(
                        (
                            "Cannot delete ChessQL statement.",
                            " ".join(
                                (
                                    "ChessQL statement on display is not",
                                    "same as rule from record.",
                                )
                            ),
                        )
                    ),
                )
                return
        editor = RecordDelete(self.sourceobject)
        editor.set_data_source(datasource, editor.on_data_change)
        editor.delete()
        tkinter.messagebox.showinfo(
            parent=self.ui.get_toplevel(),
            title="Delete ChessQL Statement",
            message="".join(
                (
                    'ChessQL statement "',
                    self.sourceobject.value.get_name_text(),
                    '" deleted from database.',
                )
            ),
        )

class CQLDisplayInsert(
    ListGamesText, InsertText, _CQLDisplay, CQLEdit, DataNotify
):
    """Display ChessQL statement from database allowing insert.

    CQLEdit provides the widget and _CQLDisplay the database interface.

    Listing games for ChessQL statements is different to selection rule
    statements because selection rules share the listing area with the Game
    and Index options to the Select menu.  Index opens up the 'Move to' and
    Filter options too.  A definite user action is always required to generate
    game lists for selection rules, in addition to navigating to (giving focus
    to) the selection rule.  The area where ChessQL game lists are shown is
    dedicated to ChessQL statements.

    """

    def _get_list_games_events(self):
        """Return tuple of event bindings to list games for ChessQL rule."""
        return (
            (EventSpec.display_list, self._process_and_set_cql_statement_list),
        )

    def _add_list_games_entry_to_popup(self, popup):
        """Add option to list games for selection rule to popup."""
        # index argument added when change in method resolution order caused
        # this entry to be added after 'Close Item' rather than before.
        self._set_popup_bindings(
            popup, bindings=self._get_list_games_events(), index="Close Item"
        )

    def _set_database_navigation_close_item_bindings(self, switch=True):
        """Delegate then set list games event bindings."""
        super()._set_database_navigation_close_item_bindings(switch=switch)
        self.set_event_bindings_score(
            self._get_list_games_events(), switch=switch
        )

    def _process_and_set_cql_statement_list(self, event=None):
        """Display games with position matching edited ChessQL statement."""
        del event
        statement = CQLStatement()
        # Not sure this is needed or wanted.
        # statement.dbset = self.ui.base_games.datasource.dbset
        statement.process_statement(self.get_name_cql_statement_text())
        self.cql_statement = statement
        try:
            self.refresh_game_list()
        except AttributeError as exc:
            if str(exc) == "'NoneType' object has no attribute 'answer'":
                msg = "".join(
                    (
                        "Unable to list games for ChessQL statement, ",
                        "probably because an 'empty square' is in the query ",
                        "(eg '.a2-3'):\n\nThe reported  error is:\n\n",
                        str(exc),
                    )
                )
            else:
                msg = "".join(
                    (
                        "Unable to list games for ChessQL statement:\n\n",
                        "The reported error is:\n\n",
                        str(exc),
                    )
                )
            tkinter.messagebox.showinfo(
                parent=self.ui.get_toplevel(),
                title="ChessQL Statement",
                message=msg,
            )
        return "break"

class CQLDisplayEdit(EditText, CQLDisplayInsert):
    """Display ChessQL statement from database allowing edit and insert.

    Method _update_item_database allows records on the database to be amended.

    """

    def _update_item_database(self, event=None):
        """Modify existing ChessQL statement record."""
        del event
        if self.ui.database is None:
            tkinter.messagebox.showinfo(
                parent=self.ui.get_toplevel(),
                title="Edit ChessQL Statement",
                message="Cannot edit ChessQL statement:\n\nNo database open.",
            )
            return
        datasource = self.ui.base_partials.get_data_source()
        if datasource is None:
            tkinter.messagebox.showinfo(
                parent=self.ui.get_toplevel(),
                title="Edit ChessQL Statement",
                message="".join(
                    (
                        "Cannot edit ChessQL statement:\n\n",
                        "Partial position list hidden.",
                    )
                ),
            )
            return
        if self.sourceobject is None:
            tkinter.messagebox.showinfo(
                parent=self.ui.get_toplevel(),
                title="Edit ChessQL Statement",
                message="".join(
                    (
                        "The ChessQL statement to edit has not ",
                        "been given.\n\nProbably because database ",
                        "has been closed and opened since this copy ",
                        "was displayed.",
                    )
                ),
            )
            return
        if self.blockchange:
            tkinter.messagebox.showinfo(
                parent=self.ui.get_toplevel(),
                title="Edit ChessQL Statement",
                message="\n".join(
                    (
                        "Cannot edit ChessQL statement.",
                        "It has been amended since this copy was displayed.",
                    )
                ),
            )
            return
        original = ChessDBrecordPartial()
        original.load_record(
            (self.sourceobject.key.recno, self.sourceobject.srvalue)
        )

        # is it better to use DataClient directly?
        # Then original would not be used. Instead DataSource.new_row
        # gets record keyed by sourceobject and update is used to edit this.
        updater = ChessDBrecordPartial()
        updater.value.process_statement(self.get_name_cql_statement_text())
        title = "Edit ChessQL Statement"
        tname = title.replace("Edit ", "").replace("S", "s")
        if not updater.value.get_name_text():
            tkinter.messagebox.showerror(
                parent=self.ui.get_toplevel(),
                title=title,
                message="".join(
                    (
                        "The '",
                        tname,
                        " has no name.\n\nPlease enter it's ",
                        "name as the first line of text.'",
                    )
                ),
            )
            return
        message = [
            "".join(
                (
                    "Confirm request to edit ",
                    tname,
                    " named:\n\n",
                    updater.value.get_name_text(),
                    "\n\non database.\n\n",
                )
            )
        ]
        if not updater.value.cql_error:
            if tkinter.messagebox.YES != tkinter.messagebox.askquestion(
                parent=self.ui.get_toplevel(),
                title=title,
                message="".join(message),
            ):
                tkinter.messagebox.showinfo(
                    parent=self.ui.get_toplevel(),
                    title=title,
                    message=tname.join(("Edit ", " on database abandonned.")),
                )
                return
        else:
            message.append(updater.value.cql_error.get_error_report())
            if tkinter.messagebox.YES != tkinter.messagebox.askquestion(
                parent=self.ui.get_toplevel(),
                title=title,
                message="".join(message),
            ):
                tkinter.messagebox.showinfo(
                    parent=self.ui.get_toplevel(),
                    title=title,
                    message=tname.join(("Edit ", " on database abandonned.")),
                )
                return
        editor = RecordEdit(updater, original)
        editor.set_data_source(datasource, editor.on_data_change)
        updater.set_database(editor.get_data_source().dbhome)
        original.set_database(editor.get_data_source().dbhome)
        updater.key.recno = original.key.recno
        editor.edit()
        tkinter.messagebox.showinfo(
            parent=self.ui.get_toplevel(),
            title=title,
            message="".join(
                (
                    tname,
                    ' "',
                    updater.value.get_name_text(),
                    '" amended on database.',
                )
            ),
        )


#%%

import re
from operator import add, mul

with open('input11') as file:
    lines = file.read().splitlines()

class Monkey:
    def __init__(self, challenge, starting_items, operand, operand_number, test_div_by_n, target_true, target_false, least_common_multiple):
        self.challenge = challenge
        self.starting_items = starting_items
        self.operand = operand
        self.operand_number = operand_number
        self.test_number = test_div_by_n
        self.target_true = target_true
        self.target_false = target_false
        self.count_inspections = 0
        self.least_common_multiple = least_common_multiple

    def execute_turn(self):
        items_out = []
        while len(self.starting_items) > 0:
            self.count_inspections += 1

            # operation
            item = self.starting_items.pop(0)
            op_2 = self.operand_number if isinstance(self.operand_number, int) else item
            item_new = self.operand(item, op_2)

            if self.challenge == 1:
                item_new = int(item_new/3)
            else:
                item_new = item_new % self.least_common_multiple

            # test
            target_monkey = self.target_true if (item_new % self.test_number == 0) else self.target_false
            items_out.append((item_new, target_monkey))
        return items_out

    def receive(self, item):
        self.starting_items.append(item)

def parse_input(challenge):
    least_common_multiple = 1
    for line in lines:
        if 'Test' in line:
            least_common_multiple *= int(re.search('\d+', line)[0])

    monkeys = []
    for line in lines:
        if 'Monkey' in line:
            starting_items = []
        elif 'Starting' in line:
            numbers = re.findall('\d+', line)
            for number in numbers:
                starting_items.append(int(number))
        elif 'Operation' in line:
            string_end = line.split('= old ')[1]
            opperand = add if string_end[0] == "+" else mul
            operand_num = string_end[1:].strip()
            if operand_num.isdigit():
                opperand_arg = int(operand_num)
            else:
                opperand_arg = operand_num
        elif 'Test' in line:
            test_div_by_n = int(re.search('\d+', line)[0])
        elif 'true' in line:
            target_true = int(re.search('\d+', line)[0])
        elif 'false' in line:
            target_false = int(re.search('\d+', line)[0])
            monkeys.append(Monkey(challenge, starting_items, opperand, opperand_arg, test_div_by_n, target_true, target_false, least_common_multiple))
    return monkeys

# ─── Challenge 1 ──────────────────────────────────────────────────────────────

monkeys = parse_input(challenge=1)
for _ in range(20):
    for monkey in monkeys:
        out_list = monkey.execute_turn()
        for item, target_monkey in out_list:
            monkeys[target_monkey].receive(item)
inspec_times = [monkey.count_inspections for monkey in monkeys]
inspec_times.sort()
print('result 1: ', mul(*inspec_times[-2:]))

# ─── Challenge 2 ──────────────────────────────────────────────────────────────

monkeys = parse_input(challenge=2)
for _ in range(10000):
    for monkey in monkeys:
        out_list = monkey.execute_turn()
        for item, target_monkey in out_list:
            monkeys[target_monkey].receive(item)
inspec_times = [monkey.count_inspections for monkey in monkeys]
inspec_times.sort()
print('result 2: ', mul(*inspec_times[-2:]))


# File_name: stop_elasticache.py
# Purpose: delete elasticache clusters
# Problem:
# Author: Søren	Wandrup-Bendixen
# Email: soren.wandrup-Bendixen@cybercom.com
# Created: 2019-07-01
# Called from lambda_function.py

import boto3

# instance_type	= 'elasticache'
def	delete_clusters(instance_type,region_name_,RunningInstances) :
	client	= boto3.client(instance_type, region_name=region_name_)
	clusters = client.describe_cache_clusters(  )['CacheClusters']
	for cluster in clusters:
		RunningInstances.append(instance_type	+ '	'	+ region_name_ + '	CacheCluster	   ' + cluster['CacheClusterId'])
		# auto remove previos snapshot
		snapshot_identifier = 'auto-stop-all-' + instance_id
		try:
			old_snapshots = client.describe_snapshots( SnapshotName= snapshot_identifier)
			if len(old_snapshots) > 0:
				response = client.delete_snapshot( SnapshotName= snapshot_identifier)
		except client.exceptions.SnapshotNotFoundFault:
			print('No snapshot found with this id ' + snapshot_identifier )

		response = client.create_snapshot(    CacheClusterId=cluster['CacheClusterId'],    SnapshotName= snapshot_identifier)
		response = client.delete_cache_cluster( CacheClusterId=cluster['CacheClusterId']	)

	return


from aiogram import types
from aiogram.types import InlineKeyboardMarkup, InlineKeyboardButton, CallbackQuery
from aiogram.utils.callback_data import CallbackData

from loader import dp
from utils.db_api.dataset import getUser, updateSubs

edit_call = CallbackData("shows_item", "items")

@dp.message_handler(text="Инфо")
async def get_regs(message: types.Message):
    user = getUser(message.from_user.id)
    await message.answer(f"Ваш ник : {message.from_user.username}\n"
                         f"Знак зодиака : {user['zodiak']}\n"
                         f"Подписка на утренний гороскоп :  {user['subs']}")

@dp.message_handler(text="Подписка")
async def get_pod(message: types.Message):
    markup = InlineKeyboardMarkup()
    user = getUser(message.from_user.id)
    sbs = int(user["subs"])
    if sbs == 0:
        tae = "не активна"
        markup.insert(
            InlineKeyboardButton(
                text="Активировать",
                callback_data=edit_call.new(items=0)
            )
        )
    else:
        tae = "активна"
        markup.insert(
            InlineKeyboardButton(
                text="Деактивирвть",
                callback_data=edit_call.new(items=1)
            )
        )

    await message.answer(f"Ваша утренняя подписка на гороскоп  {tae}",
                         reply_markup=markup)

@dp.callback_query_handler(edit_call.filter())
async def show_edit(call: CallbackQuery, callback_data: dict):
    # print(callback_data)
    dto = int(callback_data['items'])
    if dto == 1:
        updateSubs(0, call.from_user.id)
        await call.message.answer("Подписка отключена")
    else:
        updateSubs(1, call.from_user.id)
        await call.message.answer("Подписка включена")


person_1 = {
        'first': 'javier',
        'last': 'ramon',
        'age': '41',
        'city': 'teruel',
        }

person_2 = {
        'first': 'laura',
        'last': 'jambrina',
        'age': '42',
        'city': 'teruel',
        }

person_3 = {
        'first': 'alejandra',
        'last': 'julian',
        'age': '41',
        'city': 'teruel',
        }

# Se crea una LISTA de DICCIONARIOS:
people_list = [person_1, person_2, person_3]

# Se RECORRE la LISTA:
for person in people_list:
    # Se RECORRE el DICCIONARIO:
    for tag, value in person.items():
        print('- {}:'.format(tag.capitalize()), end=' ')

        if value.isdigit():
            print('{}'.format(value))
        else:
            print('{}'.format(value.capitalize()))

    print('')


"""
Output the eventalign values given the following input:
Raw Fast5 folder, match_fasta_ref file, outdir

Usage:

python get_eventalign.py fast5_dir match_fasta_ref.txt outdir hpc/local
"""

import sys
import os
import subprocess
import pathlib

fast5_dir = sys.argv[1]
match_fasta_ref_file = sys.argv[2]
outdir    = sys.argv[3]
executor  = sys.argv[4]

if not executor == "hpc":
    executor = "local"

with open(match_fasta_ref_file) as f:
    for line in f:
        _5mer, fasta, ref = line.split()

nanopolish_index = "nanopolish index -d " + fast5_dir + " " + fasta
minimap2         = "minimap2 -ax map-ont " + ref + " " + fasta + " | samtools sort -o " + outdir + "/" + _5mer + ".sorted.bam -T " + _5mer + ".tmp"
samtools_index   = "samtools index " + outdir + "/" + _5mer + ".sorted.bam"
nanopolish_align = "nanopolish eventalign --reads " + fasta + " --bam " + outdir + "/" + _5mer + ".sorted.bam --genome " + ref + " --scale-events > " + outdir + "/" +_5mer + ".eventalign.txt"

commands = ["module load minimap2/2.17", "module load samtools/1.4.1", "module load nanopolish/v0.13.2", nanopolish_index, minimap2, samtools_index, nanopolish_align]
pathlib.Path(outdir).mkdir(parents=True, exist_ok=True)
command  = " && ".join(commands)
if executor == "hpc":
    command = 'bsub -q short -n 1 -W 4:00 -R select[rh=6] -R rusage[mem=4000] -o ' + outdir + "/" + _5mer + ".log " + '"' + command  + '"'

print(_5mer, " running ...")
subprocess.call(command, shell = True)
if (executor == "hpc"):
    print(_5mer, " submitted to hpc!")
else:
    print(_5mer, " done!")


# Chris homework_2.3
import math
x_origin = input("Enter x coordinate of origin: ")
x_origin = eval(x_origin)
y_origin = input("Enter y coordinate of origin: ")
y_origin = eval(y_origin)
radius = input("Enter radius: ")
radius = eval(radius)
x_point = input("Enter x coordinate of the point: ")
x_point = eval(x_point)
y_point = input("Enter y coordinate of the point: ")
y_point = eval(y_point)
distance = math.sqrt((x_point - x_origin)**2 + (y_point - y_origin)**2)
if distance > radius:
    print("The point is outside the circle.")
elif distance == radius:
    print("The point is on the circle.")
else:
    print("The point is inside the circle.")


import math
import os
import random
import re
import sys

# Complete the repeatedString function below.
def repeated_strings(s, n):
    found_a_times = 0
    additional_finds = 0

    for char in s:
        if char == 'a':
            found_a_times += 1

    repititions_of_str = n // len(s)
    print('repetitions of str: ', repititions_of_str)
    no_remainder_total = repititions_of_str * found_a_times
    remainder = n % len(s)
    print('surplus', remainder)
    if remainder > 0:
        for letter in list(s)[:remainder]:
            if letter == 'a':
                print('theres extra of remainder:', remainder)
                additional_finds += 1

    return no_remainder_total + additional_finds

if __name__ == '__main__':
    fptr = open(os.environ['OUTPUT_PATH'], 'w')

    s = input()

    n = int(input())

    result = repeated_strings(s, n)

    fptr.write(str(result) + '\n')

    fptr.close()


# baekjoon 1003

t = int(input())
dp = [0 for i in range(41)]
dp[0] = [1, 0]
dp[1] = [0, 1]

def fib(n):
    if n == 0:
        return dp[0]
    elif n == 1:
        return dp[1]
    if dp[n] == 0:
        minus_one, minus_two = fib(n-1), fib(n-2)
        dp[n] = [minus_one[0]+minus_two[0], minus_one[1]+minus_two[1]]
    return dp[n]

for i in range(t):
    n = int(input())
    res = fib(n)
    print(res[0], res[1])


import neucore

authToken = "Your_AuthToken_Here" # visit console.ailiverse.com to obtained your auth token if you have not already

model = neucore.Model(authToken, model="Image Segmentation")

model.uploadFile("train.zip", "labelme")

model.train(epochs=10)

results = model.infer("hen.jpg")

print(results)


import json

from django.contrib.auth.decorators import login_required
from django.contrib.auth.forms import UserCreationForm
from django.shortcuts import render, redirect, get_object_or_404
from django.template.defaulttags import url

from chat.forms import ContactForm
from chat.models import Message

def home(req):
    return render(req, "basemain.html")

def about(req):
    return render(req, "about.html")

def contact(req):
    if req.method == "POST":
        form = ContactForm(req.POST)
        if form.is_valid():
            form.save()
            return redirect("thanks")
    else:
        form = ContactForm()
    return render(req, "contact.html", context={'form': form})

def register(req):
    if req.method == "POST":
        form = UserCreationForm(req.POST)
        if form.is_valid():
            form.save()
            return redirect(req.GET.get("next") or url("home"))
    else:
        form = UserCreationForm()
    return render(req, "registration/register.html", context={"form": form})

# def profile(req, id):
#     prof = get_object_or_404(Profile, id=id)
#     return render(req, "profile.html", context={"form": prof})

def thanks(req):
    return render(req, "thanks.html")

# @login_required
# def profile_edit(req):
#     if req.method == "POST":
#         form = ProfileForm(req.POST)
#         if form.is_valid():
#             form.save()
#             return redirect("contact thanks")
#     else:
#         form = ProfileForm()
#     return render(req, "profile_edit.html", context={"form": form})

@login_required
def chat(req):
    return render(req, "chatindex.html")

@login_required
def api_log(req):
    log = Message.objects.filter(index=0, deleted=False)[:100]
    for item_no in range(log):
        if log[item_no].edited:
            log[item_no] = Message.objects.filter(msg_id=log[item_no].msg_id).order_by("-index")[0]
    return render(req, "api_log.html", context={"messages": log})

@login_required
def api_new(req):
    validation_errors = []

    if not req.POST.get("query"):
        validation_errors += ["No json processed"]

    jso = json.loads(req.POST.get("query"))

    if not type(jso["body"]) == "String":
        validation_errors += ["Incorrect message type"]

    if not type(jso["profile_id"]) == "Integer":
        validation_errors += ["Incorrect profile id format"]

    if validation_errors:
        return render(req, "errors.html", context={"validation_errors": validation_errors})

    msg_id = Message.objects.all().order_by("-msg_id")[0].msg_id + 1

    msg = Message(msg_id=msg_id, body=jso["body"], profile_id=jso["profile_id"])
    msg.save()

    return render(req, "jsonsuccess.html")

@login_required
def api_edit(req):
    validation_errors = []

    if not req.POST.get("query"):
        validation_errors += ["No json processed"]
        return render(req, "errors.html", context={"validation_errors": validation_errors})

    jso = json.loads(req.POST.get("query"))
    old_msg = Message.objects.filter(msg_id=req.POST.get("query")).order_by("-index")[0]

    if not old_msg.exists():
        validation_errors += ["No message to update with that id"]
        return render(req, "errors.html", context={"validation_errors": validation_errors})

    if jso["delete"] == True:
        old_msg.deleted = True
        old_msg.save()
        return render(req, "jsonsuccess.html")

    if not jso["body"]:
        validation_errors += ["No new message body"]
        return render(req, "errors.html", context={"validation_errors": validation_errors})

    msg = Message(index=old_msg.index+1, msg_id=old_msg.msg_id, body=jso["body"])
    msg.save()

    return render(req, "jsonsuccess.html")


import logging
import sys
sys.path.append('.')

import tests.test_nodeEndpoints.add_work_items as awi

#logging utility
logging.getLogger("Nodes").setLevel(logging.WARNING)
logging.getLogger("endpoints").setLevel(logging.WARNING)
logging.basicConfig(format='%(name)-12s:%(lineno)-3s | %(levelname)-8s | %(message)s'
                , stream=sys.stdout, level=logging.DEBUG)
logger = logging.getLogger(__name__)

if __name__ == '__main__':
    logger.debug('--- sendingTasks.py ---')
    logger.debug('- connecting 1 executor (user) and sending 12 tasks')
    awi.SAMPLES = 1_000_000
    ip = sys.argv[1]
    port = int(sys.argv[2])
    awi.submit_helper(1, 30, ip=ip, port=port)
    logger.debug('- tasks sent to the head node')