import random
import sys
import tkinter as tk
import time

### Partie A1 ###

def paquet():
    """Initialise et renvoie un paquet de 52 cartes."""
    couleurs = ['carreau','pique','trefle','coeur']
    rangs = ['as','2','3','4','5','6','7','8','9','10','valet','dame','roi']
    cartes = []
    for couleur in couleurs :
        for rang in rangs :
            cartes.append(rang+' de '+couleur) #Nomination de la carte en fonction de sa couleur et valeur
    return cartes

def valeurCarte(carte):
    """Pour une carte donnée, renvoie sa valeur en points."""
    if 'as' in carte :
        valeur = 11 #Inisialisation de la variable
    elif ('valet' in carte) or ('dame' in carte) or ('roi' in carte):
        valeur = 10 #Valeur des têtes
    else:
        valeur = int(str(carte.split(' ')[0])) #Valeur des autres cartes
    return valeur

def initPioche(n=8):
    """Prend un nombre de paquets egal au nombre de joueurs puis melange
    les cartes pour creer la pioche."""
    pioche_non_melangees = n*paquet()
    pioche = [] #Initialisation de la pioche melangee
    quantite = len(pioche_non_melangees) #Nb de cartes à trier
    for i in range(quantite):
        carte = random.choice(pioche_non_melangees)
        pioche.append(carte) #Ajoute une carte aléatoire dans la pioche mélangée
        pioche_non_melangees.remove(carte) #Et la retire de la pioche à mélanger
    return pioche

def piocheCarte(p, x=1):
    """Recoit en argument la pioche, et le nombre de cartes à piocher (par
    defaut 1), et retourne les x premieres cartes de la pioche (en les
    retirant)."""
    cartesPiochees = []
    for i in range(x):
        cartesPiochees.append(p.pop(0)) #Tire une carte de la pioche
    if x==1:
        return cartesPiochees[0]
    else :
        return cartesPiochees

### Partie A2 ###

def initJoueurs():
    liste_joueurs = []
    global nb_joueurs
    nb_joueurs = 0

    #Fenetre d'initialisation des joueurs
    ask_joueurs = tk.Tk()
    ask_joueurs.overrideredirect(1)
    ask_joueurs.geometry('200x300+600+200')
    ask_joueurs.title('Initialisation des joueurs')
    ask_joueurs.wm_attributes("-topmost", 1)

    #Etiquette nombre joueurs
    label_nb_joueurs = tk.Label(ask_joueurs, text='Nombre de joueurs :')
    label_nb_joueurs.pack()

    #Entree du nombre de joueurs
    entree_nb = tk.IntVar()
    entree_nb_joueurs = tk.Entry(ask_joueurs, textvariable=entree_nb)
    entree_nb_joueurs.pack()

    #Bouton valider le nombre de joueur
    bouton_valider_nb = tk.Button(ask_joueurs, text='Valider', command=lambda:valider_nb(ask_joueurs, entree_nb_joueurs))
    bouton_valider_nb.pack()

    #Etiquette joueur 1
    label_joueur1 = tk.Label(ask_joueurs, text='Joueur 1 :')
    label_joueur1.pack()

    #Entree joueur 1
    joueur1 = tk.StringVar()
    joueur1.set('Joueur 1')
    entree_joueur1 = tk.Entry(ask_joueurs, textvariable=joueur1, state='disabled')
    entree_joueur1.pack()

    #Etiquette joueur 2
    label_joueur2 = tk.Label(ask_joueurs, text='Joueur 2 :')
    label_joueur2.pack()

    #Entree joueur 2
    joueur2 = tk.StringVar()
    joueur2.set('Joueur 2')
    entree_joueur2 = tk.Entry(ask_joueurs, textvariable=joueur2, state='disabled')
    entree_joueur2.pack()

    #Etiquette joueur 3
    label_joueur3 = tk.Label(ask_joueurs, text='Joueur 3 :')
    label_joueur3.pack()

    #Entree joueur 3
    joueur3 = tk.StringVar()
    joueur3.set('Joueur 3')
    entree_joueur3 = tk.Entry(ask_joueurs, textvariable=joueur3, state='disabled')
    entree_joueur3.pack()

    #Etiquette joueur 4
    label_joueur4 = tk.Label(ask_joueurs, text='Joueur 4 :')
    label_joueur4.pack()

    #Entree joueur 4
    joueur4 = tk.StringVar()
    joueur4.set('Joueur 4')
    entree_joueur4 = tk.Entry(ask_joueurs, textvariable=joueur4, state='disabled')
    entree_joueur4.pack()

    #Etiquette joueur 5
    label_joueur5 = tk.Label(ask_joueurs, text='Joueur 5 :')
    label_joueur5.pack()

    #Entree joueur 5
    joueur5 = tk.StringVar()
    joueur5.set('Joueur 5')
    entree_joueur5 = tk.Entry(ask_joueurs, textvariable=joueur5, state='disabled')
    entree_joueur5.pack()

    #Bouton valider joueurs
    bouton_valider_joueurs = tk.Button(ask_joueurs, text='Valider', command=lambda:valider_joueurs(ask_joueurs,liste_joueurs,entree_joueur1,entree_joueur2
                                                                                ,entree_joueur3,entree_joueur4,entree_joueur5))
    bouton_valider_joueurs.pack()

    ask_joueurs.mainloop()

    return liste_joueurs

def initScores(joueurs,v=0):
    scores = {}
    for joueur in joueurs :
        scores[joueur] = v
    return scores

def premierTour(joueurs, pioche):
    scores = initScores(joueurs)
    for joueur in joueurs:
        cartes_piochees = piocheCarte(pioche,x=2)
        for carte in cartes_piochees :
            scores[joueur] += valeurCarte(carte)
    return scores

def gagnants(scores):
    maxi = 0
    gagnants = []
    for joueur in scores.keys() :
        if scores[joueur] <=21 and scores[joueur]>maxi:
            maxi = scores[joueur]
            gagnants = []
            gagnants.append(joueur)
        if scores[joueur] == maxi:
            gagnants.append(joueur)
    return gagnants

### Partie B1 ###

def continuer():
    global continuer
    continuer = -1
    while continuer!=0 and continuer!=1:
        pass
    if continuer == 0:
        return False
    else:
        return True

def tourJoueur(j, scores, pioche):
    while scores[j]<21 and continuer():
        scores[j] += valeurCarte(piocheCarte(pioche))
    return scores

### Partie B2 ###

def tourComplet(joueurs, scores, pioche):
    for j in joueurs:
        scores = tourJoueur(j, scores, pioche)
    return scores

def partieComplete():
    joueurs = initJoueurs()
    scores = initScores(joueurs)
    pioche = initPioche()
    scores = tourComplet(joueurs, scores, pioche)
    gagnants = gagnants(score)
    return gagnants

############################
### FONCTIONS GRAPHIQUES ###
############################

#----------Section Menu-------------#

   #----------------------------------#
def valider_nb(fenetre, entree):
    global nb_joueurs
    nb_joueurs = int(entree.get())
    i = 0
    for widget in fenetre.winfo_children() :
        if widget.winfo_class() == 'Entry' :
            if i > 0 and i <= nb_joueurs:
                widget.config(state='normal')
            i += 1

def valider_joueurs(fenetre,liste,entree1,entree2,entree3,entree4,entree5):
    liste.append(entree1.get())
    liste.append(entree2.get())
    liste.append(entree3.get())
    liste.append(entree4.get())
    liste.append(entree5.get())
    fenetre.destroy()
    can.delete(main, menu)

def nouvelle_partie(main, can, menu):
    """Lance une nouvelle partie de Blackjack"""
    for widget in main.winfo_children():
        if widget.winfo_class() == 'Button' :
            tk.Button.destroy(widget)

    gagnants = partieComplete()
    can.delete(main, menu)
    creerBoutons(main, can)

   #----------------------------------#

def reprendre_partie(main, can, menu):
    """Reprend la partie interrompue"""
    for widget in main.winfo_children():
        if widget.winfo_class() == 'Button' :
            tk.Button.destroy(widget)
    can.delete(main, menu)
    creerBoutons(main, can)

def menu(main, can, resume=True):
    """Affiche le menu au demarrage du jeu"""
    w = main.winfo_screenwidth() #Largeur de l'ecran
    h = main.winfo_screenheight() #Hauteur de l'ecran

    #Suppression des boutons de partie
    for widget in main.winfo_children():
        if widget.winfo_class() == 'Button' :
            tk.Button.destroy(widget)

    #Fond noirci du menu
    menu = can.create_rectangle(0,0,w,h,width=1,fill="black",stipple="gray75")

    #Bouton quitter
    bouton_quitter = tk.Button(main, text='Quitter', bg='black', fg='yellow', activebackground='yellow', activeforeground='black', command=main.destroy)
    bouton_quitter_win = can.create_window(w/2, 3*h/4, window=bouton_quitter)

    #Bouton nouvelle partie
    bouton_nouvelle_partie = tk.Button(main, text='Nouvelle Partie', bg='black', fg='yellow', activebackground='yellow', activeforeground='black',
                                       command=lambda:nouvelle_partie(main,can,menu))
    bouton_nouvelle_partie_win = can.create_window(w/2, h/4, window=bouton_nouvelle_partie)

    #Bouton reprendre partie
    bouton_reprendre = tk.Button(main, text='Reprendre', bg='black', fg='yellow', activebackground='yellow', activeforeground='black',
                                       command=lambda:nouvelle_partie(main,can,menu))
    bouton_reprendre_win = can.create_window(w/2, h/2, window=bouton_reprendre)

    if not resume :
        bouton_reprendre.config(state='disabled') #Desactive le bouton reprendre au demarrage du jeu

#----------Section Boutons----------#

def splitter():
    """Action servant à splitter deux cartes identiques."""
    pass

def rester():
    """Permet au joueur d'arreter son tour."""
    global continuer
    continuer = 0

def tirer():
    """Permet au joueur de tirer une carte."""
    global continuer
    continuer = 1

def doubler():
    """Permet au joueur de doubler sa mise et tirer une unique carte."""
    pass

def creerBoutons(main, can):
    """Creer les boutons permettant au joueur d'interagir."""
    k = main.winfo_screenwidth()/5 #Ecart des boutons
    y = main.winfo_screenheight()-30 #Hauteur des boutons

    #Bouton splitter
    bouton_splitter = tk.Button(main, text='Splitter', bg='blue', fg='white', activebackground='white', activeforeground='blue', command=splitter)
    bouton_splitter_win = can.create_window(k, y, window=bouton_splitter)

    #Bouton rester
    bouton_rester = tk.Button(main, text='Rester', bg='blue', fg='white', activebackground='white', activeforeground='blue', command=rester)
    bouton_rester_win = can.create_window(2*k, y, window=bouton_rester)

    #Bouton tirer
    bouton_tirer = tk.Button(main, text='Tirer', bg='blue', fg='white', activebackground='white', activeforeground='blue', command=tirer)
    bouton_tirer_win = can.create_window(3*k, y, window=bouton_tirer)

    #Bouton doubler
    bouton_doubler = tk.Button(main, text='Doubler', bg='blue', fg='white', activebackground='white', activeforeground='blue', command=doubler)
    bouton_doubler_win = can.create_window(4*k, y, window=bouton_doubler)

    #Bouton menu
    bouton_menu = tk.Button(main, text='Menu', bg='black', fg='yellow', activebackground='yellow', activeforeground='black',
                            command=lambda:menu(main,can))
    bouton_menu_win = can.create_window(40, 30, window=bouton_menu)

#----------Section Cartes-----------#

def associerCartes(cartes):
    """Associe chaque carte d'un paquet donné à son image sur l'application graphique."""
    association = {} #Initialisation du dictionnaire d'association
    for carte in cartes :
        couleur = carte.split(' ')[2] #Prends la couleur de la carte
        rang = carte.split(' ')[0][0] #Prends le rang de la carte (ou sa premiere lettre)
        if rang == '1' :
            rang = '10'
        association[carte] = rang+'-'+couleur+'.png' #Retrouve l'image correspondant à la carte
    return association

def trouverCarte(association, carte):
    """Trouve l'image d'une carte donnée dans une association carte/image."""
    return association[carte]

### Programme principal (brouillon et tests pour l'instant) ###

def main_prog():
    main = tk.Tk()
    w = main.winfo_screenwidth() #Largeur de l'ecran
    h = main.winfo_screenheight() #Hauteur de l'ecran
    main.title('Jeu de blackjack') #Creation de la fenetre
    main.attributes('-fullscreen', 1)
    main.resizable(height=False,width=False)

    table = tk.PhotoImage(file='Images/table_blackjack.gif') #Importation de l'arriere-plan
    fond = tk.Canvas(main, height=h, width=w, bg='black') #Creation du canvas allant accueillir l'interface graphique
    fond.pack()
    fond.create_image(0,0,anchor=tk.NW,image=table) #Image d'arriere-plan

    menu(main,fond,resume=False)

    main.mainloop()

main_prog()


from django.db import migrations, connections
from django.contrib.auth.models import Group
from ..models import User

from ..constants import Groups

def create_groups(apps, schema_editor):
    Group.objects.create(name=Groups.Passenger.name)
    Group.objects.create(name=Groups.Driver.name)

def insert_to_groups(apps, schema_editor):
    g = Group.objects.get(name=Groups.Driver.name)
    users = User.objects.all()
    for u in users:
        g.user_set.add(u)

class Migration(migrations.Migration):

    dependencies = [
        ('fleet_management', '0010_auto_20190731_1747'),
    ]

    operations = [
        migrations.RunPython(create_groups),
        migrations.RunPython(insert_to_groups),
    ]


#!/usr/local/bin/python3.6
##!/usr/bin/python3
import sys
import re

from collections import defaultdict, OrderedDict

def getAvailableStates(stateSet, char, states):
    availableStates = set()
    for state in stateSet:
        availableStates.update(states[(state, char)])
    return availableStates

pattern = re.compile(r'(^[0-9]+) ([0-9]+) (.){1}$')
pattern1 = re.compile(r'^[0-9]+$')

states = defaultdict(list)
charList = []
acceptingStates = set()

for line in sys.stdin:
    m = pattern.match(line)
    s = pattern1.match(line)
    if m:
        if m.group(3) not in charList:
            charList.append(m.group(3))
        if (m.group(1), m.group(3)) in states:
            states[(m.group(1), m.group(3))].append(m.group(2))
        else:
            states[(m.group(1), m.group(3))] = [m.group(2)]
    if s:
        acceptingStates.add(s.group(0))

statesNotInDict = [("0", )]
statesTable = OrderedDict()
removedStates = []

#generowanie tablicy
while len(statesNotInDict) != 0:
    for state in statesNotInDict:
        statesTable[state] = {}
        for char in charList:
            availableStates = tuple(getAvailableStates(state, char, states))
            if availableStates not in statesNotInDict and availableStates not in removedStates:
                statesNotInDict.append(tuple(availableStates))
            statesTable[state][char] = availableStates
        removedStates.append(state)
        statesNotInDict.remove(state)

detAcceptingStates = set()

#mapowanie zbiorów stanów do pojedynczych stanów
i = 0
mapToNumber = {}
finalStates = {}
for k, v in statesTable.items():
    mapToNumber[k] = i
    i += 1

#tworzenie hasha ze zmapowanymi stanami + wyznaczanie stanów akceptujących
for k, v in statesTable.items():
    if k in mapToNumber.keys():
        finalStates[mapToNumber[k]] = {}
        for i, j in v.items():
            if acceptingStates & set(j):
                detAcceptingStates.add(mapToNumber[j])
            if j in mapToNumber.keys():
                finalStates[mapToNumber[k]][i] = mapToNumber[j]

#wypisywanie automatu
for k, v in finalStates.items():
    for i, j in v.items():
        print(k, j, i)
for i in detAcceptingStates:
    print(i)


#  views.py
#
#  Copyright 2014 huangtao <huangtao.jh@gmail.com>
#
#  This program is free software; you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation; either version 2 of the License, or
#  (at your option) any later version.
#
#  This program 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 General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program; if not, write to the Free Software
#  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
#  MA 02110-1301, USA.
#
#

from documents.models import Document,Office,Tag
from django.forms import *
from mylib.djviews import SearchView
# Create your views here.
class SearchForm(ModelForm):
    class Meta:
        model=Document
        fields=['code','year','number','name','tags']

class HomeView(SearchView):
    model=Document
    context_object_name='object_list'
    template_name='documents/document_search.html'
    keywords={'code':None,
            'year':None,
            'number':None,
            'name':'contains',
            'tags':None,
            }
    search_form_class=SearchForm
    ordering=['-year','-efficetive_date','code','-number']


import time
import multiprocessing

try:
    from setproctitle import setproctitle
except ImportError:
    def setproctitle(title):
        pass

class StatsCollector(multiprocessing.Process):
    def __init__(self, queue):
        super(StatsCollector, self).__init__()
        self.queue = queue

    def close(self):
        pass

    def run(self):
        setproctitle("bucky: %s" % self.__class__.__name__)
        interval = self.interval
        while True:
            start_timestamp = time.time()
            interval = self.interval if self.collect() else interval + interval
            stop_timestamp = time.time()
            interval = min(interval, 300)
            interval = interval - (stop_timestamp - start_timestamp)
            if interval > 0.1:
                time.sleep(interval)

    def collect(self):
        raise NotImplementedError()

    def add_stat(self, metric_name, metric_value, timestamp, **metadata):
        if metadata:
            if self.metadata:
                metadata.update(self.metadata)
        else:
            metadata = self.metadata
        if metadata:
            metadata_tuple = tuple((k, metadata[k]) for k in sorted(metadata.keys()))
            self.queue.put((None, metric_name, metric_value, timestamp, metadata_tuple))
        else:
            self.queue.put((None, metric_name, metric_value, timestamp))

    def merge_dicts(self, *dicts):
        ret = {}
        for d in dicts:
            if d:
                ret.update(d)
        return ret


from keras.models import Sequential
#from imblearn.over_sampling import SMOTE
from sklearn.metrics import classification_report, confusion_matrix
from sklearn.linear_model import LogisticRegression
from sklearn.dummy import DummyClassifier
from keras.layers import Dense, Dropout, BatchNormalization, Activation
from keras.wrappers.scikit_learn import KerasClassifier
from preprocessing.model_ready import get_train_test_data

def get_model():
    estimator = Sequential([
        Dense(256, input_dim=28, kernel_initializer='uniform', kernel_regularizer='l2', use_bias=False),
        BatchNormalization(),
        Activation('relu'),
        Dense(128, kernel_initializer='uniform', kernel_regularizer='l2', use_bias=False),
        BatchNormalization(),
        Activation('relu'),
        Dense(64, kernel_initializer='uniform', kernel_regularizer='l2', use_bias=False),
        BatchNormalization(),
        Activation('relu'),
        Dense(32, kernel_initializer='uniform', kernel_regularizer='l2', use_bias=False),
        BatchNormalization(),
        Activation('relu'),
        Dense(1, activation='sigmoid')
    ])
    estimator.compile(loss='binary_crossentropy',
                      optimizer='adam',
                      metrics=['binary_accuracy'])
    return estimator

x_train, y_train, x_test, y_test = get_train_test_data('classification', user=10)

'''
#codigo para usar oversampling
columns = X.columns
sm = SMOTE(random_state=12, ratio='all')
X_train, y_train = sm.fit_sample(X_train, y_train)
X_train = pd.DataFrame(X_train, columns=columns)
y_train = pd.Series(y_train)

clf = LogisticRegression(random_state=0, solver='lbfgs', max_iter=350)
clf.fit(X_train, y_train)

print(clf.score(X_test, y_test))
print(classification_report(y_test, clf.predict(X_test)))
'''

model = LogisticRegression(solver='liblinear', max_iter=400, class_weight='balanced')
#model = create_classifier_model(clf)
print('LOGREG\n')
model.fit(x_train, y_train)
y_pred = model.predict(x_test)
print(confusion_matrix(y_test, y_pred))
print(classification_report(y_test, y_pred))

print('DNN\n')
modelnn = KerasClassifier(get_model, epochs=20, batch_size=32, verbose=2, validation_data=(x_test, y_test))
modelnn.fit(x_train, y_train)
y_pred = modelnn.predict(x_test)
print(classification_report(y_test, y_pred))

print(classification_report(y_test, DummyClassifier(strategy='most_frequent', random_state=7)
                            .fit(x_train, y_train).predict(x_test)))
get_model().summary()


# TO-DO: complete the helper function below to merge 2 sorted arrays
def merge(arrA, arrB):
    elements = len(arrA) + len(arrB)
    merged_arr = [0] * elements

    # Your code here
    i, j = 0,0
    k = 0

    # comparing and replacing elements in merged_arr till minimum of len(arrA) and len(arrB)
    while i < len(arrA) and j < len(arrB):
        if arrA[i] < arrB[j]:
            merged_arr[k] = arrA[i]
            i += 1
        else:
            merged_arr[k] = arrB[j]
            j += 1
        k += 1

    # copying remaining elements from A to merged_arr
    while i < len(arrA):
        merged_arr[k] = arrA[i]
        i += 1
        k += 1

    # copying remaining elements from B to merged_arr
    while j < len(arrB):
        merged_arr[k] = arrB[j]
        j += 1
        k += 1

    return merged_arr

# TO-DO: implement the Merge Sort function below recursively
def merge_sort(arr):
    # Your code here
    if len(arr) < 2:
        return arr
    else:
        mid = len(arr)// 2
        part1 = merge_sort(arr[0:mid])
        part2 = merge_sort(arr[mid:])
        return merge(part1, part2)

# STRETCH: implement the recursive logic for merge sort in a way that doesn't
# utilize any extra memory
# In other words, your implementation should not allocate any additional lists
# or data structures; it can only re-use the memory it was given as input
def merge_in_place(arr, start, mid, end):
    # Your code here
    start2 = mid
    while start <= mid and start2 <= end:
        if arr[start] <= arr[start2]:
            start += 1
        else:
            index = start2
            value = arr[start2]
            while index is not start:
                arr[index] = arr[index - 1]
                index -= 1
            arr[start] = value
            start += 1
            mid += 1
            start2 += 1
    return arr

print(merge_in_place([1,5,8,2,4], 0, 2, 4))
def merge_sort_in_place(arr, l, r):
    # Your code here
    if r - l < 1:
        return arr
    else:
        m = (l + r) // 2
        merge_sort_in_place(arr, l, m)
        merge_sort_in_place(arr, m + 1, r)
        return merge_in_place(arr, l, m+1, r)


import classdefs
import jsonpickle

def main():
    # Initialise other variables
    # Currently assuming 10 rounds per minute as an approximation for spells with durations
    rounds_per_minute = 10

    # Order of initialisation becomes important for charged ablities
    # Initialise any statuses infliced by charge delivering abilities
    status_weakness = classdefs.Status('Weakened', status_damage_mod=-1)

    # Initialise any abilities used to deliver charges
    ability_weakness_discharge = classdefs.AbilityGrantStatus('Weakness','hostile','discharge',None,None,status_weakness,5*rounds_per_minute)
    ability_harm_discharge = classdefs.AbilityDamageLocation('Harm','hostile','discharge',None,None,2)
    ability_shock_discharge = classdefs.AbilityDamageLocation('Shock','hostile','discharge',None,None,2)

    # Initialise combat statuses required for abilities
    status_distracted = classdefs.Status('Distracted', status_rating_multi=0)
    status_enhanced = classdefs.Status('Enhanced', status_damage_mod=1)
    status_charge_weakness = classdefs.StatusCharged('Charge (Weakness)', ability_weakness_discharge,status_damage_multi=0)
    status_charge_harm = classdefs.StatusCharged('Charge (Harm)', ability_harm_discharge,status_damage_multi=0)
    status_charge_shock = classdefs.StatusCharged('Charge (Shock)', ability_shock_discharge,status_damage_multi=0)

    # Initialise weapons
    weapon_sword = classdefs.Weapon('Sword',1,[1,1,1,1,1,1])
    weapon_shield = classdefs.Weapon('Shield',1.5,[1,0.5,0.5,1,1,1])
    weapon_off_hand = classdefs.Weapon('Off Hand Weapon',1.25,[1,3,1,0.5,2,0.5])
    weapon_off_hand_short = classdefs.Weapon('Off Hand Short Weapon',1.3,[1,3,1,0.5,2,0.5])
    weapon_two_handed = classdefs.Weapon('Two Handed',1.2,[1,3,1,0.5,1,1])
    weapon_polearm = classdefs.Weapon('Polearm',2,[1,1,1,1,1,1.5])
    weapon_select = weapon_sword,weapon_shield,weapon_off_hand,weapon_off_hand_short,weapon_two_handed,weapon_polearm

    # Initialise abilities
    # Note : "Fast" abilities usually have minimum duration of 0 if they affect the current round only, while others should start at 1
    ability_glimmer = classdefs.AbilityGrantStatus('Glimmer','hostile','fast','mana',1,status_distracted,0)
    ability_enhancement = classdefs.AbilityGrantStatus('Enhancement',['self','friendly'],'fast','mana',1,status_enhanced,0)
    ability_fireball = classdefs.AbilityDamageDirect('Fireball','hostile','interruptible','mana',4,3)
    ability_smite_ranged = classdefs.AbilityDamageDirect('Smite','hostile','uninterruptible','spirit',1,6)
    ability_heal_two = classdefs.AbilityHealCreature('Heal 2',['self','friendly'],'uninterruptible','spirit',1,2)
    ability_spirit_armour = classdefs.AbilityAffectCreature('Spirit Armour',['self','friendly'],'uninterruptible','spirit',1,'glob_spirit_arm',3,'set')
    ability_barrier_self = classdefs.AbilityAffectCreature('Barrier Self',['self','friendly'],'interruptible','mana',2,'glob_magic_arm',2,'set')
    ability_weakness_charge = classdefs.AbilityGrantStatus('Weakness (Charge)','self','uninterruptible','spirit',1,status_charge_weakness,3)
    ability_harm_charge = classdefs.AbilityGrantStatus('Harm (Charge)','self','uninterruptible','spirit',1,status_charge_harm,3)
    ability_shock_charge = classdefs.AbilityGrantStatus('Shock (Charge)','self','uninterruptible','mana',2,status_charge_shock,3)
    ability_select = ability_glimmer,ability_enhancement,ability_fireball,ability_smite_ranged,ability_heal_two,ability_spirit_armour,ability_barrier_self,ability_weakness_charge,ability_harm_charge,ability_shock_charge

    # Initialise variables
    hit_location_names = ['Head','Off Hand','Body','Favoured Hand','Off Leg','Favoured Leg']
    choice = None
    character_list = {}

    # Initialise Menus
    main_menu_string = """
    Treasure Trap Character Creator
    =================

    Please choose your option below:
    0 - Quit
    1 - Create New Character
    2 - Edit Existing Character
    3 - Delete Character
    4 - List All Characters
    5 - Save All Characters
    6 - Load All Characters
    """

    location_menu_string = """
    Choose location to edit
    =================
    0 - Done
    1 - Head
    2 - Off Hand
    3 - Body
    4 - Favoured Hand
    5 - Off Leg
    6 - Favoured Leg
    """

    edit_menu_string = """
    Choose statistic to edit
    =================
    0 - Done
    1 - Hits
    2 - Locational Armour
    3 - Global Armour
    4 - Resources
    5 - Weapons
    6 - Abilities
    """
    # Main Code
    # Autoload characters from file
    try:
        print("\nLoading...")
        with open('characters.txt','r') as infile:
            character_list = jsonpickle.decode(infile.read())
    except:
        print("\nNo character file found.")

    while choice != "0":

        print(main_menu_string)
        choice = input("Choice: ")
        print()

        # Exit
        if choice == "0":
            print("\nExiting...")

        # Create new character
        elif choice == "1":
            raw_name = input("Input character name: ")
            char_name = raw_name.capitalize()
            if char_name in character_list:
                print("\nA character with this name already exists. Please select a different name.")
            else:
                # Get hits from input
                try:
                    char_hits_crit = int(input('\nInput hits per critical (head/body) location as an integer:'))
                    char_hits_limb = int(input('\nInput hits per limb location as an integer:'))
                except ValueError:
                    print("\nInvalid values, hits defaulted to 3/loc.")
                    char_hits_crit = 3
                    char_hits_limb = 3
                # Character skill rating - set to 1 - may later include some options
                char_rating = 1
                # Actually set the characters hits
                char_hits_max = [char_hits_limb for i in range(6)]
                char_hits_max[0] = char_hits_crit
                char_hits_max[2] = char_hits_crit
                # Get damage from input
                try:
                    char_damage = int(input('\nInput damage call as an integer :'))
                except ValueError:
                    print("\nInvalid value, damage defaulted to 1.")
                    char_damage = 1
                # Get locational armour from input
                char_loc_armour = [0,0,0,0,0,0]
                char_loc_select = None
                while char_loc_select != -1:
                    print(location_menu_string)
                    char_loc_select = int(input("Choice: "))-1
                    if char_loc_select in range(0,6):
                        print('\nArmour value for ' + str(hit_location_names[char_loc_select]) + ' is currently set to ' + str(char_loc_armour[char_loc_select]))
                        try:
                            char_loc_armour[char_loc_select] = int(input('\nInput armour hits for location as an integer:'))
                        except ValueError:
                            print('\nInvalid choice, Armour value for ' + str(hit_location_names[char_loc_select]) + ' will remain as ' + str(char_loc_armour[char_loc_select]))
                    elif char_loc_select == -1:
                        continue
                    else:
                        print('\nInvalid choice.')
                # Get global armour from input
                try:
                    char_spirit_arm = int(input('\nInput points of Spirit Armour as an integer:'))
                except ValueError:
                    print("\nInvalid value, Spirit Armour defaulted to 0.")
                    char_spirit_arm = 0
                try:
                    char_magic_arm = int(input('\nInput points of Magic Armour as an integer:'))
                except ValueError:
                    print("\nInvalid value, Magic Armour defaulted to 0.")
                    char_magic_arm = 0
                try:
                    char_dac = int(input('\nInput points of DAC as an integer:'))
                except ValueError:
                    print("\nInvalid value, DAC defaulted to 0.")
                    char_dac = 0
                # Get Resources from input
                try:
                    char_spirit = int(input('\nInput points of Spirit as an integer:'))
                except ValueError:
                    print("\nInvalid value, Spirit points defaulted to 0.")
                    char_spirit = 0
                try:
                    char_mana = int(input('\nInput points of Mana as an integer:'))
                except ValueError:
                    print("\nInvalid value, Mana points defaulted to 0.")
                    char_mana = 0
                # Select a weapon
                print('\nWIP - Choose a single character weapon:')
                print('\nChoose a weapon:')
                for x in range(len(weapon_select)):
                    print(str(x+1) + ' - ' + weapon_select[x].name + ',')
                try:
                    char_weapon_select = int(input('\nChoice:'))
                    if char_weapon_select-1 not in range(len(weapon_select)):
                        raise
                except ValueError:
                    print("\nInvalid value, defaulted to single sword")
                    char_weapon_select = 1
                char_weapon = [weapon_select[char_weapon_select-1]]
                # Add ability/ies to character
                print('\nWIP - Choose a single character ability:')
                print('0 - No Abilities')
                for x in range(len(ability_select)):
                    print(str(x+1) + ' - ' + ability_select[x].name + ',')
                try:
                    char_ability_select = int(input('\nChoice:'))
                    if char_ability_select == 0:
                        char_ability = []
                    elif char_ability_select-1 not in range(len(ability_select)):
                        raise ValueError
                    else:
                        char_ability = [ability_select[char_ability_select-1]]
                except ValueError:
                    print("\nInvalid value, defaulted to no abilities")
                    char_ability = []
                # Create character and add to the character list
                character_list.update({char_name: classdefs.TreasureTrapPC(char_name,char_rating,char_hits_max,char_damage,char_weapon,char_ability,char_loc_armour,char_dac,char_spirit_arm,char_magic_arm,char_mana,char_spirit)})

        # Edit character
        elif choice == "2":
            print("\nAvailable characters:\n")
            for key in character_list:
                print(key)
                print(character_list.get(key), "\n")
            editchar_raw = input("Select a character to edit: ")
            editchar_name = editchar_raw.capitalize()
            if editchar_name not in character_list:
                print("\nCharacter does not exist.")
            else:
                editchar = character_list.get(editchar_name)
                edit_choice = None
                while edit_choice != "0":
                    print(edit_menu_string)
                    edit_choice = input("Choice: ")

                    # Edit Locational Hits
                    if edit_choice == "1":
                        loc_choice = None
                        while loc_choice != -1:
                            print("\nChoose location to edit hits :")
                            print("\n=================")
                            print("\n0 - Done")
                            for x in range(len(hit_location_names)):
                                print(str(x+1) + ' - ' + hit_location_names[x] + ' : '+ str(editchar.maxhits[x]))
                            loc_choice = int(input("\nChoice :"))-1
                            if loc_choice == -1:
                                continue
                            elif loc_choice in range(len(hit_location_names)):
                                try:
                                    editchar.maxhits[loc_choice] = int(input('\nInput hit points as an integer:'))
                                except ValueError:
                                    print("\nInvalid value, hits not changed")
                            else:
                                print("\nInvalid choice.")

                    #Edit Locational Armour
                    elif edit_choice == "2":
                        loc_choice = None
                        while loc_choice != -1:
                            print("\nChoose location to edit armour:")
                            print("\n=================")
                            print("\n0 - Done")
                            for x in range(len(hit_location_names)):
                                print(str(x+1) + ' - ' + hit_location_names[x] + ' : '+ str(editchar.loc_armour_max[x]))
                            loc_choice = int(input("\nChoice :"))-1
                            if loc_choice == -1:
                                continue
                            elif loc_choice in range(len(hit_location_names)):
                                try:
                                    editchar.loc_armour_max[loc_choice] = int(input('\nInput armour value as an integer:'))
                                except ValueError:
                                    print("\nInvalid value, armour not changed")
                            else:
                                print("\nInvalid choice.")

                    # Edit locational armour
                    elif edit_choice == "3":
                        print('Spirit armour : ' + str(editchar.glob_spirit_arm_max))
                        print('Magic armour : ' + str(editchar.glob_magic_arm_max))
                        print('DAC: ' + str(editchar.glob_dac_max))
                        try:
                            editchar.glob_spirit_arm_max = int(input('\nInput points of Spirit Armour as an integer:'))
                        except ValueError:
                            print("\nInvalid value, Spirit Armour not changed.")
                        try:
                            editchar.glob_magic_arm_max = int(input('\nInput points of Magic Armour as an integer:'))
                        except ValueError:
                            print("\nInvalid value, Magic Armour not changed.")
                        try:
                            editchar.glob_dac_max = int(input('\nInput points of DAC as an integer:'))
                        except ValueError:
                            print("\nInvalid value, DAC not changed.")

                    # Edit resources
                    elif edit_choice == "4":
                        print('Spirit points: ' + str(editchar.spirit_points_max))
                        print('Mana points : ' + str(editchar.mana_points_max))
                        try:
                            editchar.spirit_points_max = int(input('\nInput points of Spirit as an integer:'))
                        except ValueError:
                            print("\nInvalid value, Spirit points not changed.")
                        try:
                            editchar.mana_points_max = int(input('\nInput points of Mana as an integer:'))
                        except ValueError:
                            print("\nInvalid value, Mana points not changed.")

                    # Edit character weapon
                    elif edit_choice == "5":
                        print('Current Weapons : ' + str([o.name for o in editchar.weapons]))
                        print('\nWIP - Choose a single character weapon:')
                        print('\nChoose a weapon:')
                        for x in range(len(weapon_select)):
                            print(str(x+1) + ' - ' + weapon_select[x].name + ',')
                        try:
                            char_weapon_select = int(input('\nChoice:'))
                            if char_weapon_select-1 in range(len(weapon_select)):
                                editchar.weapons = [weapon_select[char_weapon_select-1]]
                            else:
                                raise ValueError
                        except ValueError:
                            print("\nInvalid value, weapon not changed")

                    #Edit character ability
                    elif edit_choice == "6":
                        print('Current Abilities :' + str([o.name for o in editchar.abilities]))
                        print('\nWIP - Choose a single character ability:')
                        print('0 - No Abilities')
                        for x in range(len(ability_select)):
                            print(str(x+1) + ' - ' + ability_select[x].name + ',')
                        try:
                            char_ability_select = int(input('\nChoice:'))
                            if char_ability_select == 0:
                                editchar.abilities = []
                            elif char_ability_select-1 not in range(len(ability_select)):
                                raise ValueError
                            else:
                                editchar.abilities = [ability_select[char_ability_select-1]]
                        except ValueError:
                            print("\nInvalid value, abilities not changed")

                    else:
                        print("\nInvalid choice.")

        # Delete character
        elif choice == "3":
            chardel = input("Which character would you like to delete?: ")
            chardelCap = chardel.capitalize()
            if chardelCap not in character_list:
                print("\nCharacter does not exist.")
            else:
                areusure = input("\nAre you sure you want to delete this character? 'Y' for YES, 'N' for NO: ")
                areusureCap = areusure.upper()
                if areusureCap == "Y":
                    del character_list[chardelCap]
                    print("\nCharacter WAS deleted.")
                else:
                    print("\nCharacter NOT deleted.")

        # List characters
        elif choice == "4":
            if character_list:
                for key in character_list:
                    print(key)
                    print(character_list.get(key))
            else:
                print("\nNo characters found")

        # Save characters
        elif choice == "5":
            # Save characters to file
            print("\nSaving...")
            with open('characters.txt','w') as outfile:
                outfile.write(jsonpickle.encode(character_list))
            print("\nSaving complete.")

        # Load characters
        # Issue - What we load back in just becomes a dictionary object...
        elif choice == "6":
            # Load characters from file
            print("\Loading...")
            with open('characters.txt','r') as infile:
                character_list = jsonpickle.decode(infile.read())
            print("\nLoading complete.")

        else:
            print("\nInvalid choice.")

    #Should probably prompt to save before quitting
    print("Exiting...")

if __name__ == "__main__":
    main()


from django.conf.urls import url, include
from django.shortcuts import render, redirect

import xadmin as admin

def index(request):
    return redirect('/course/showall/')

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^course/', include('content.urls')),
    url(r'^user/', include('user.urls')),
    url(r'^order/',include('order.urls')),
    url(r'', index)

]


#!/usr/bin/env python
import sys, json, pprint

inObj =  json.loads(open(sys.argv[1]).read())["Parameters"]

listobj = []
for parameter in inObj.iterkeys():
    data={}
    data["ParameterKey"]=parameter
    if 'Default' in inObj[parameter]:
        data["ParameterValue"]=inObj[parameter]["Default"]
    else:
        data["ParameterValue"]=""
    data["UsePreviousValue"]=False
    listobj.append(data)

print(json.dumps(listobj, sort_keys=True, indent=4))


from pprint import pformat
from typing import Tuple

import pytest

from enigma.constants import MENU as M
from enigma.menu import MenuMaker, convert_to_ZZ_code
from tests.menu_test_data import BASIC_3CH, BASIC_4CH, WELCHMAN_1L

CRIBS = {
    "basic": {
        "crib__guess": "ABCDDEF",
        "crib_cypher": "BCABEFB"
    },
    "welchman": {
        "crib__guess": "TOTHEPRESIDENTOFTHEUNITEDSTATES",
        "crib_cypher": "CQNZPVLILPEUIKTEDCGLOVWVGTUFLNZ"
    },
    "dermot_BB": {
        "crib__guess": "WETTERVORHERSAGE",
        "crib_cypher": "SNMKGGSTZZUGARLV"
    }
}
# sub_cribs define subsections of cribs by start:end indices
# which generate different loops and menus
SUB_CRIBS = {
    "welchman_1_loop": ("welchman", 0, 14),
    "welchman_4_loops": ("welchman", 2, 22),
    "welchman_no_loops": ("welchman", 14, 27),
    "dermot": ("dermot_BB", 0, 30),
    "basic_3ch_loop": ("basic", 0, 5),
    "basic_4ch_loop": ("basic", 1, 7)
}

def get_crib_cypher(crib_set_name: str) -> Tuple[str, str]:
    crib_key, start, end = SUB_CRIBS[crib_set_name]
    crib_guess = CRIBS[crib_key]["crib__guess"][start:end]
    crib_cypher = CRIBS[crib_key]["crib_cypher"][start:end]
    return crib_guess, crib_cypher

gw_all_loops = {frozenset(['E', 'I', 'P']), frozenset(['I', 'P', 'V']), frozenset(['N', 'O', 'T']),
                frozenset(['D', 'E', 'I', 'N', 'T'])}
loop_data = [
    ("welchman_1_loop", {frozenset(['E', 'I', 'P'])}),
    ("welchman_4_loops", gw_all_loops),  # note this has been failing since added, indicates true problems in code
    ("welchman_no_loops", set()),
    ("dermot", {frozenset(['G', 'E', 'V', 'S', 'A', 'R'])}),
    ("basic_3ch_loop", {frozenset(['A', 'B', 'C'])}),
    ("basic_4ch_loop", {frozenset(['B', 'D', 'E', 'F'])})
]

@pytest.mark.parametrize("crib_set_name, expected", loop_data)
def test_menumaker_loops(crib_set_name: str, expected: set) -> None:
    crib_guess, crib_cypher = get_crib_cypher(crib_set_name)
    menu_mkr = MenuMaker(crib=crib_guess, encoded_crib=crib_cypher)
    menu_mkr.search_menu_structure()
    found_loops = set(frozenset(loop) for loop in menu_mkr.found_loops)
    assert found_loops == expected

# I want deadends to be keys representing the individual character nodes that are truly
# the 'end' of a deadend chain. Values at the moment are just the shortest path from the most
# common letter to the deadend char, but this could change. Also not sure how to deal with
# shortest path when multiple 'most_common' letters e.g. dermot where both E & G have 4 connections
deadend_data = [
    ("basic_3ch_loop", {'E': 'BDE'}),
    ("basic_4ch_loop", {'A': 'BCA'}),
    ("welchman_1_loop", {'C': 'EINTC', 'D': 'ED', 'K': 'EINTK', 'U': 'EU', 'V': 'EPV'}),
    ("dermot", {'H': 'EGRZH', 'L': 'EGL', 'N': 'EN', 'U': 'EU', 'W': 'EVSW'}),
    ("welchman_4_loops", {'F': 'EF', 'G': 'EG', 'K': 'EDTK', 'R': 'EULR', 'S': 'EULS'})

]

@pytest.mark.parametrize("crib_set_name, expected", deadend_data)
def test_menumaker_deadends(crib_set_name: str, expected: dict) -> None:
    crib_guess, crib_cypher = get_crib_cypher(crib_set_name)
    menu_mkr = MenuMaker(crib=crib_guess, encoded_crib=crib_cypher)
    menu_mkr.search_menu_structure()
    assert menu_mkr.dead_ends.keys() == expected.keys()

# fmt: off
basic_link_idx = {'A': {0: 'B', 2: 'C'}, 'B': {0: 'A', 1: 'C', 3: 'D'}, 'C': {1: 'B', 2: 'A'}, 'D': {3: 'B', 4: 'E'}, 'E': {4: 'D'}}
w_14_link_idx = {'C': {0: 'T'}, 'D': {10: 'E'}, 'E': {4: 'P', 7: 'I', 10: 'D', 11: 'U'}, 'H': {3: 'Z'}, 'I': {7: 'E', 9: 'P', 12: 'N'}, 'K': {13: 'T'}, 'L': {6: 'R', 8: 'S'}, 'N': {2: 'T', 12: 'I'}, 'O': {1: 'Q'}, 'P': {4: 'E', 5: 'V', 9: 'I'}, 'Q': {1: 'O'}, 'R': {6: 'L'}, 'S': {8: 'L'}, 'T': {0: 'C', 2: 'N', 13: 'K'}, 'U': {11: 'E'}, 'V': {5: 'P'}, 'Z': {3: 'H'}}
dermot_link_idx = {'A': {12: 'S', 13: 'R'}, 'E': {1: 'N', 4: 'G', 10: 'U', 15: 'V'}, 'G': {4: 'E', 5: 'R', 11: 'R', 14: 'L'}, 'H': {9: 'Z'}, 'K': {3: 'T'}, 'L': {14: 'G'}, 'M': {2: 'T'}, 'N': {1: 'E'}, 'O': {7: 'T'}, 'R': {5: 'G', 8: 'Z', 11: 'G', 13: 'A'}, 'S': {0: 'W', 6: 'V', 12: 'A'}, 'T': {2: 'M', 3: 'K', 7: 'O'}, 'U': {10: 'E'}, 'V': {6: 'S', 15: 'E'}, 'W': {0: 'S'}, 'Z': {8: 'R', 9: 'H'}}
link_idx_data = [
    ("basic_3ch_loop", basic_link_idx),
    ("welchman_1_loop", w_14_link_idx),
    ("dermot", dermot_link_idx)
]

@pytest.mark.parametrize("crib_set_name, expected", link_idx_data)
def test_menumaker_create_link_index(crib_set_name: str, expected: set) -> None:
    crib_guess, crib_cypher = get_crib_cypher(crib_set_name)
    menu_mkr = MenuMaker(crib=crib_guess, encoded_crib=crib_cypher)
    menu_mkr.count_characters()
    menu_mkr.create_link_index()
    assert menu_mkr.link_index == expected

best_chars_data = [
    ("basic_3ch_loop", ('B',)),
    ("basic_4ch_loop", ('B',)),
    ("welchman_1_loop", ('E',)),
    ("dermot", ('E', 'G', 'R'))
]
exp_loops = [
    [{frozenset(['B', 'A', 'C']): 'BACB'}],
    [{frozenset(['B', 'D', 'E', 'F']): 'BFEDB'}],
    [{frozenset(['E', 'P', 'I']): 'EIPE'}],
    [{frozenset(['A', 'E', 'S', 'V', 'R', 'G']): 'GRASVEG'}]
]
loops_data = [tuple(list(data) + exp) for data, exp in zip(best_chars_data, exp_loops)]

@pytest.mark.parametrize("crib_set_name, expected", best_chars_data)
def test_find_best_characters(crib_set_name: str, expected: set) -> None:
    crib_guess, crib_cypher = get_crib_cypher(crib_set_name)
    menu_mkr = MenuMaker(crib=crib_guess, encoded_crib=crib_cypher)
    menu_mkr.count_characters()
    menu_mkr.create_link_index()
    menu_mkr.find_best_characters()
    assert menu_mkr.best_characters == expected

@pytest.mark.parametrize("crib_set_name, best_chars, expected", loops_data)
def test_find_loops(crib_set_name: str, best_chars: tuple, expected: dict) -> None:
    crib_guess, crib_cypher = get_crib_cypher(crib_set_name)
    menu_mkr = MenuMaker(crib=crib_guess, encoded_crib=crib_cypher)
    menu_mkr.count_characters()
    menu_mkr.create_link_index()
    menu_mkr.find_best_characters()
    for best_char in best_chars:
        menu_mkr.find_loops(best_char)
    assert menu_mkr.found_loops.keys() == expected.keys()

menu_data = [
    ("basic_3ch_loop", BASIC_3CH),
    ("basic_4ch_loop", BASIC_4CH),
    ("welchman_1_loop", WELCHMAN_1L)
]

def check_recursive(actual, expected):
    if isinstance(expected, dict):
        for k, v in expected.items():
            if k not in actual.keys():
                print(f"{k} missing from actual keys")
                continue
            if v == actual[k]:
                pass
            else:
                print(f"key={k}")
                check_recursive(actual[k], v)
    else:
        if actual != expected:
            print(actual, " != ", expected)

@pytest.mark.parametrize("crib_set_name, expected", menu_data)
def test_menu_prep(crib_set_name: str, expected: dict) -> None:
    crib_guess, crib_cypher = get_crib_cypher(crib_set_name)
    menu_mkr = MenuMaker(crib=crib_guess, encoded_crib=crib_cypher)
    menu_mkr.run()
    menu_mkr.network_graph(label=f"_{crib_set_name}")
    print("===start of menu test===")
    # easy check - not looking for identical ordering of in/out pairs, keys
    for key, exp_val in expected.items():
        if key == M.CONFIG:
            continue
        act_val = menu_mkr.menu[key]
        print(f"actual  ={pformat(act_val)}\nexpected={exp_val}\n-----")
        assert {act_val[M.IN], act_val[M.OUT]} == {exp_val[M.IN], exp_val[M.OUT]}, f"key={key} in/out not equal"
        assert act_val[M.LINK] == exp_val[M.LINK], f"key={key} menu_link not equal"
        act_conxns = set([i for k, v in act_val[M.CONXNS].items() for i in v.keys()])
        exp_conxns = set([i for k, v in exp_val[M.CONXNS].items() for i in v.keys()])
        assert act_conxns == exp_conxns, f"key={key} connections not equal"
    print("===easy/non-precise menu checks passed===")
    # hard check - looking for identical dicts, make sure in vs out is correct
    for key, exp_val in expected.items():
        act_val = menu_mkr.menu[key]
        print(f"k={key}\nact={pformat(act_val)}\nexp={pformat(exp_val)}")
        assert act_val == exp_val, f"k={key} menu not identical to expected"

zz_data = [
    (0, 'ZZZ'),
    (1, 'ZZA'),
    (17, 'ZZQ'),
    (25, 'ZZY'),
    (26, 'ZAZ'),
    (27, 'ZAA'),
    (28, 'ZAB')
]

@pytest.mark.parametrize("position, expected", zz_data)
def test_convert_to_ZZ_code(position: int, expected: str) -> None:
    assert expected == convert_to_ZZ_code(position)


def missing_number(numbers):
    n = len(numbers) + 1

    total = n * (n - 1) // 2

    for num in numbers:
        total = total - num

    return total

    # for i in range(1, n + 1):
    #     if i not in numbers:
    #         return i

values = [int(num) for num in input('Enter some numbers: ').split()]

print(missing_number(values))


import numpy as np

class Progress:
    def __init__(self, epochs):
        self.epochs = epochs
        self.epoch_train_losses = np.array([])
        self.epoch_val_loss = None

    def batch_train_loss(self, loss):
        self.epoch_train_losses = np.append(self.epoch_train_losses, loss)

    def val_loss(self, loss):
        self.epoch_val_loss = loss

    def print_epoch(self, epoch):
        epoch_avg_train_loss = np.mean(self.epoch_train_losses) if len(self.epoch_train_losses) > 0 else -1
        epoch_val_loss = self.epoch_val_loss if self.epoch_val_loss is not None else -1
        train_loss = "{:.5f}".format(epoch_avg_train_loss)
        val_loss = "{:.5f}".format(epoch_val_loss)
        print(
            f'Epoch {epoch}/{self.epochs}    |    Train loss: {train_loss}   -   Val loss: {val_loss}'
        )

        # clear values
        self.epoch_train_losses = np.array([])
        self.epoch_val_loss = None

    """
    def progress_bar(epochs, current_epoch, minibatches, current_minibatch):
        s = '['
        minibatches_chunk = ceil(minibatches / 6)
        freq = minibatches // minibatches_chunk

        if current_minibatch == 0 or freq % current_minibatch != 0:
            return

        bar_len = epochs * 6
        progress = (current_epoch * 6) + (current_minibatch // minibatches_chunk)
        s += '=' * progress
        s += ' ' * (bar_len - progress)
        s += ']'
        print(s, current_minibatch)
    """


#!/bin/python
import aubio
import subprocess
import pyaudio
from time import sleep

def write_to_input(path, switch):
    x = open(path,'w')
    x.write(switch)
    x.close()
def array_to_byte(numpy_array):
    # pyaudio cannot play sound from numpy arrays
    # The contents must all me converted into one byte object
    byte_samples = bytes()
    for i in numpy_array:
        byte_samples += bytes(i)
    return byte_samples
def main(path):
    src = aubio.source(path)
    hop_size = src.hop_size
    pitch_object = aubio.pitch(samplerate=src.samplerate)
    pyaudio_object = pyaudio.PyAudio()
    stream = pyaudio_object.open(format=pyaudio.paFloat32, channels=src.channels, rate=src.samplerate, output=True)

    while True:
        samples, read = src()
        stream.write(array_to_byte(samples))
        pitch = pitch_object(samples)
        if pitch[0] < 25:
            write_to_input('/sys/class/leds/input17::scrolllock/brightness', '0')
            write_to_input('/sys/class/leds/input17::capslock/brightness', '0')
            write_to_input('/sys/class/leds/input17::numlock/brightness', '0')
        elif pitch[0] < 440:
            write_to_input('/sys/class/leds/input17::scrolllock/brightness', '1')
            write_to_input('/sys/class/leds/input17::capslock/brightness', '0')
            write_to_input('/sys/class/leds/input17::numlock/brightness', '0')
        elif pitch[0] < 1100:
            write_to_input('/sys/class/leds/input17::scrolllock/brightness', '1')
            write_to_input('/sys/class/leds/input17::capslock/brightness', '1')
            write_to_input('/sys/class/leds/input17::numlock/brightness', '0')
        else:
            write_to_input('/sys/class/leds/input17::scrolllock/brightness', '1')
            write_to_input('/sys/class/leds/input17::capslock/brightness', '1')
            write_to_input('/sys/class/leds/input17::numlock/brightness', '1')

        if read < hop_size:
            break
    stream.stop_stream()
    stream.close()
    pyaudio_object.terminate()
    return True

if __name__ == '__main__':
    main('036-XenobladeChroniclesOST-GaurPlain.mp3')


import codecs
from argparse import ArgumentParser
from itertools import islice
import numpy as np
import spacy
import torch
from torch.autograd import Variable
from torch.utils.data import Dataset
from torch import LongTensor

from model import Ass4Net, emb_net
from utils import timeit
import pandas as pd
import json

@timeit
def readdata(fname, limit=None):
    premis, hypo, label = [], [], []
    with open(fname, 'r') as f:
        for line in islice(f, 1, limit, 1):
            line = json.loads(line)
            if line['gold_label'].strip() =='-':
                continue
            premis.append(line['sentence1'])
            hypo.append(line['sentence2'])
            label.append(line['gold_label'])
    return [premis, hypo, label]

@timeit
def read_emb(fname, limit=None):
    df = pd.read_csv(fname, sep=" ", quoting=3, header=None, index_col=0, nrows=limit)
    words, vec = df.index, df.values
    return [words, vec]
@timeit
def read_emb_fast(f_vocab_name, f_mat_name, limit=None):
    with codecs.open(f_vocab_name, 'r', 'utf-8') as f_in:
        index2word = [line.strip() for line in islice(f_in,0,limit,1)]

    word2index = {w: i for i, w in enumerate(index2word)}
    wv = np.load(f_mat_name)

    return wv, index2word, word2index

def get_word_repr(word, W2I):
    w = W2I.get(word, 0)
    if w == 0:
        w = int((np.exp(np.random.randint(1, 100)) * 7) % len(W2I))
    return w

class DataSet(Dataset):
    def __init__(self, data, W2I, L2I, limit=-1):
        premis_, hypo_, label_ = data
        premis, hypo, label = [], [], []
        self.tokenize = spacy.load('en_core_web_sm',disable=['ner','tagger','parser'])
        for (p, h, l) in zip(premis_, hypo_, label_):
            premis.append([get_word_repr(w.lemma_, W2I) for w in self.tokenize(p)])
            hypo.append([get_word_repr(w.lemma_, W2I) for w in self.tokenize(h)])
            label.append(L2I.get(l, 0))
        self.len = len(label) if limit == -1 or len(self.data) < limit else limit
        label = torch.tensor(label)

        # padding
        premis_seq_lengths = LongTensor(list(map(len, premis)))
        premis_t = Variable(torch.zeros((len(premis), premis_seq_lengths.max()))).long()
        for idx, (seq, seqlen) in enumerate(zip(premis, premis_seq_lengths)):
            premis_t[idx, :seqlen] = LongTensor(seq)
        hypo_seq_lengths = LongTensor(list(map(len, hypo)))
        hypo_t = Variable(torch.zeros((len(hypo), hypo_seq_lengths.max()))).long()
        for idx, (seq, seqlen) in enumerate(zip(hypo, hypo_seq_lengths)):
            hypo_t[idx, :seqlen] = LongTensor(seq)

        self.data = []
        for i in range(self.len):
            self.data.append([premis_t[i], hypo_t[i], label[i]])
        self.premis_seq_lengths = premis_seq_lengths
        self.hypo_seq_lengths = hypo_seq_lengths

    def __len__(self):
        return self.len

    def __getitem__(self, item):
        premis, hypo, label = self.data[item]
        premis_seq, hypo_seq = self.premis_seq_lengths[item], self.hypo_seq_lengths[item]
        return premis, hypo, label, premis_seq, hypo_seq

def read_snli_data_file(file_name):
    premis, hypo, label = [], [], []
    with open(file_name, 'r') as file:
        for line in file:
            js = json.loads(line[:-1])
            if js["gold_label"] == "-":
                continue
            premis.append(js["sentence1"])
            hypo.append(js["sentence2"])
            label.append(js["gold_label"])

    return [premis, hypo, label]

def torch_text_load_snli():
    import time
    import glob

    import torch
    import torch.optim as O
    import torch.nn as nn

    from torchtext import data
    from torchtext import datasets

    # from util import get_args, makedirs
    parser = ArgumentParser(description='')
    args = parser.parse_args()
    if torch.cuda.is_available():
        device = torch.device('cuda')
    else:
        device = torch.device('cpu')

    inputs = data.Field(lower=True, tokenize='spacy',tokenizer_language='en_core_web_sm')
    answers = data.Field(sequential=False)

    train, dev, test = datasets.SNLI.splits(inputs, answers)

    inputs.build_vocab(train, dev, test)
    # if args.word_vectors:
    #     if os.path.isfile(args.vector_cache):
    #         inputs.vocab.vectors = torch.load(args.vector_cache)
    #     else:
    #         inputs.vocab.load_vectors(args.word_vectors)
    #         makedirs(os.path.dirname(args.vector_cache))
    #         torch.save(inputs.vocab.vectors, args.vector_cache)
    answers.build_vocab(train)

    train_iter, dev_iter, test_iter = data.BucketIterator.splits(
        (train, dev, test), batch_size=128, device=device)

    config = args
    config.n_embed = len(inputs.vocab)
    config.d_out = len(answers.vocab)
    config.n_cells = config.n_layers

    # double the number of cells for bidirectional networks
    if config.birnn:
        config.n_cells *= 2

    # if args.resume_snapshot:
    #     model = torch.load(args.resume_snapshot, map_location=device)
    # else:
    # emb = emb_net(emb_size,emb_mat,device,200,1,0.2)
    model = Ass4Net(128,device,0.2,200,1)
    if args.word_vectors:
        model.embed.weight.data.copy_(inputs.vocab.vectors)
        model.to(device)

    criterion = nn.CrossEntropyLoss()
    opt = O.Adagrad(model.parameters(), lr=args.lr)

    iterations = 0
    start = time.time()
    best_dev_acc = -1
    header = '  Time Epoch Iteration Progress    (%Epoch)   Loss   Dev/Loss     Accuracy  Dev/Accuracy'
    dev_log_template = ' '.join('{:>6.0f},{:>5.0f},{:>9.0f},{:>5.0f}/{:<5.0f} {:>7.0f}%,{:>8.6f},{:8.6f},{:12.4f},{:12.4f}'.split(','))
    log_template = ' '.join('{:>6.0f},{:>5.0f},{:>9.0f},{:>5.0f}/{:<5.0f} {:>7.0f}%,{:>8.6f},{},{:12.4f},{}'.split(','))
    # makedirs(args.save_path)
    print(header)

    for epoch in range(args.epochs):
        train_iter.init_epoch()
        n_correct, n_total = 0, 0
        for batch_idx, batch in enumerate(train_iter):
            # switch model to training mode, clear gradient accumulators
            model.train()
            opt.zero_grad()

            iterations += 1

            # forward pass
            answer = model(batch)

            # calculate accuracy of predictions in the current batch
            n_correct += (torch.max(answer, 1)[1].view(batch.label.size()) == batch.label).sum().item()
            n_total += batch.batch_size
            train_acc = 100. * n_correct / n_total
if __name__ == '__main__':
    torch_text_load_snli()


from scipy import optimize
import configparser
import re

# encoding=utf8
import sys

reload(sys)
sys.setdefaultencoding('utf8')

def f(x):  # The rosenbrock function
    print
    .5 * (1 - x[0]) ** 2 + (x[1] - x[0] ** 2) ** 2
    return .5 * (1 - x[0]) ** 2 + (x[1] - x[0] ** 2) ** 2

# print optimize.minimize(f, [5,5], method="L-BFGS-B")
def add_section_header(properties_file, header_name):
    # configparser.ConfigParser requires at least one section header in a properties file.
    # Our properties file doesn't have one, so add a header to it on the fly.
    yield '[{}]\n'.format(header_name)
    for line in properties_file:
        yield line

infile = '/home/florian/lumpedflow/trunk/Models/LiverProject/ClosedLoop/PatientModel/RightLeftLiv/headers/ConfFile/Patient_CMAR.h'

file = open(infile)

with open(infile, 'rw') as f:
    read_data = f.read()

newstring = re.sub('(Ea_RA_val)', r'tutu', read_data)

with open(infile+'.test', 'w') as f:
    f.write(newstring)
# config = configparser.ConfigParser()
# config.optionxform = str
# config = configparser.RawConfigParser()
#
# config.read_file(file)

'''
config = configparser.ConfigParser(comment_prefixes=('#', ';' ,'/','*'), inline_comment_prefixes=('#', ';','/','*'))
config = configparser.RawConfigParser()
config.optionxform = str
config.read_file(infile)
# print config.sections()
# config.get(config.sections()[0], 'Ea_RA')
'''


def IsJolly(seq,n):
    new = [int(j) for j in range(1,n)]

    jolly = []
    for i in range(n-1):
        j = abs(seq[i] - seq[i+1])

        if 0 <= j <= n-1:
            jolly.append(j)

    jolly.sort()
    if new == jolly:
        return True
    else:
        return False

if __name__ == '__main__':

##    seq = [1,4,2,3]
##    seq = [1,4,2,-1,6]
##    seq = [11,7,4,2,1,6]
##    seq = [3,5,2,1]
    seq = [7,2,5,4,-2,1,3]
    print(IsJolly(seq,len(seq)))


# First import the library
import pyrealsense2 as rs
import cv2
import numpy as np
depth_image = None
color_image = None
frames = None

# Create a context object. This object owns the handles to all connected realsense devices
pipeline = rs.pipeline()
pipeline.start()

# First import the library
import pyrealsense2 as rs

# Create a context object. This object owns the handles to all connected realsense devices
pipeline = rs.pipeline()
pipeline.start()

img = np.zeros((512,512,3), np.uint8)
# mouse callback function
drawing = False # true if mouse is pressed
mode = True # if True, draw rectangle. Press 'm' to toggle to curve
ix,iy = -1,-1

# mouse callback function
previous_point = ()
initial_point = ()
contour_points = []

def draw_circle(event,x,y,flags,param):
    global ix,iy,drawing,mode, previous_point, initial_point, contour_points

    if event == cv2.EVENT_LBUTTONDOWN:
        drawing = True
        ix,iy = x,y
        previous_point = (x,y)
        initial_point = (x,y)
        contour_points.append([x,y])

    elif event == cv2.EVENT_MOUSEMOVE:
        if drawing == True:
            if mode == True:
                cv2.rectangle(img,(ix,iy),(x,y),(0,255,0),-1)
            else:
                # cv2.circle(img,(x,y),5,(0,0,255),-1)
                cv2.line(img, previous_point, (x,y), (0,0,255) )
                previous_point = (x,y)
                contour_points.append([x,y])

    elif event == cv2.EVENT_LBUTTONUP:
        drawing = False
        if mode == True:
            cv2.rectangle(img,(ix,iy),(x,y),(0,255,0),-1)
        else:
            # cv2.circle(img,(x,y),5,(0,0,255),-1)
            cv2.line(img, previous_point, (x,y), (255,0,0) )
            cv2.line(img, (x,y), initial_point, (255,0,0) )
            previous_point = []

            do_everything(depth_image, contour_points)
            contour_points = []

    cv2.imshow('image',img)

def  get_points_cloud(depth_image):
    nrows = depth_image.shape[0]
    ncols = depth_image.shape[1]

    xmin = np.array(contour_points)[:,0].min()
    xmax = np.array(contour_points)[:,0].max()
    ymin = np.array(contour_points)[:,1].min()
    ymax = np.array(contour_points)[:,1].max()

    # distance to middle pixel
    d = depth_image[int(nrows/2), int(ncols/2)]

    align = rs.align(rs.stream.color)
    aligned_frames = align.process(frames)
    aligned_depth_frame = aligned_frames.get_depth_frame()
    color_frame = aligned_frames.get_color_frame()

    depth_image = np.asanyarray(aligned_depth_frame.get_data())
    color_image = np.asanyarray(color_frame.get_data())

    pc = rs.pointcloud()
    pc.map_to(aligned_depth_frame)
    points = pc.calculate(color_frame)

    # pc = rs.pointcloud()
    # points = pc.calculate(frames[0])

    vertices = np.asanyarray(points.get_vertices())

    vertices = np.array([list(v) for v in vertices])[::3,:]

    import matplotlib.pyplot as plt
    plt.scatter(vertices[:,0], vertices[:,1], c=vertices[:,2],linewidth=0,cmap=plt.cm.jet)

    # from mpl_toolkits.mplot3d import Axes3D
    # fig = plt.figure(figsize=(4,4))
    # ax = fig.add_subplot(1, 1, 1, projection='3d')
    # ax.scatter3D(vertices[::10,0],vertices[::10,1],vertices[::10,2])
    # # https://github.com/IntelRealSense/librealsense/blob/5e73f7bb906a3cbec8ae43e888f182cc56c18692/include/librealsense2/rsutil.h#L15

    plt.show()

    # grey_color = 153
    # clipping_distance = 10000
    # depth_image_3d = np.dstack((depth_image,depth_image,depth_image)) #depth image is 1 channel, color is 3 channels
    # bg_removed = np.where((depth_image_3d > clipping_distance) | (depth_image_3d <= 0), grey_color, color_image)

    # Render images
    # depth_colormap = cv2.applyColorMap(cv2.convertScaleAbs(depth_image, alpha=0.03), cv2.COLORMAP_JET)
    # images = np.hstack((bg_removed, depth_colormap))
    # cv2.namedWindow('Align Example', cv2.WINDOW_AUTOSIZE)
    # cv2.imshow('Align Example', images)
    # cv2.waitKey(1)
    # points_image_coord = pc.calculate(frames[1])

def  get_mesh(points):
    pass

def  get_masked_triangles(contour_points, triangles, depth_image):
    pass

def  get_area_from_triangles(masked_triangles, points):
    pass

def do_everything(depth_image, contour_points):

    # obtener nube de puntos

    points = get_points_cloud(depth_image)

    # triangular la malla de pixeles

    triangles = get_mesh(points)

    # seleccionar triangulos dentro del contorno en coordenadas de pixeles

    masked_triangles = get_masked_triangles(contour_points, triangles, depth_image)

    # calcular area

    area = get_area_from_triangles(masked_triangles, points)

# Create a black image, a window and bind the function to window
cv2.namedWindow('image')
cv2.setMouseCallback('image',draw_circle)

for i in range(5):
    # This call waits until a new coherent set of frames is available on a device
    # Calls to get_frame_data(...) and get_frame_timestamp(...) on a device will return stable values until wait_for_frames(...) is called
    frames = pipeline.wait_for_frames()
    depth_data = frames[0].as_frame().get_data()
    color_data = frames[1].as_frame().get_data()
    depth_image = np.asanyarray(depth_data)/100 #cm?
    color_image = np.asanyarray(color_data)
    img = cv2.cvtColor(color_image, cv2.COLOR_BGR2RGB)

    # Display the resulting frame
    cv2.imshow('image',img)
    if cv2.waitKey(20) & 0xFF == ord('q'):
        break

cv2.imshow('image',img)
while(1):
    cv2.imshow('image',img)
    k = cv2.waitKey(1) & 0xFF
    if k == ord('m'):
        mode = not mode
    elif k == 27:
        break

cv2.destroyAllWindows()


from pathlib import Path
import os
import csv
import torch

from library import DS_PATH

def path_check_and_fix(pathfile):
    '''
    pathfile is assumed to be abs path
    '''
    try:
        path2check = os.path.abspath(os.path.join(pathfile, ".."))
        Path(path2check).mkdir(parents=True, exist_ok=True)
        return pathfile
    except Exception as e:
        print("Error when attempting to fix path!")
        print(e)
        raise

def save2csv(csv_data, filepath=None):
    if filepath:
        print("savings to csv...")
        filepath = path_check_and_fix(filepath)
        with open(filepath, "w", newline="") as f:
            writer = csv.writer(f)
            writer.writerows(csv_data)
    else:
        print("not saving, please insert filepath")

def save_torch_model(state, filepath=None):
    if filepath:
        filepath = path_check_and_fix(filepath)
        torch.save(state, filepath)
    else:
        print("not saving, please insert filepath")


import re

f = open("list_of.txt", 'w')

panel = {"BMX5" : {"costUSD" : "65.02", "costEUR" : "55.66", "costGBP": "48.11"},
	"Skoda": {"costUSD" : "14.496", "costEUR" : "12.91", "costGBP" : "12.91"},
	"kodiaq": {"costUSD" : "85",  "costEUR" : "75.68",  "costGBP" : "73.47"},
	"Renault": {"costUSD" : "45", "costEUR" : "40.03",  "costGBP" : "38.9"},
	"Chery":  {"costUSD" : "36", "costEUR" : "32.02",  "costGBP" : "31.12"},
	"Mutsubishi": {"costUSD" : "519", "costEUR" : "462.08", "costGBP" : "462.08 "}}

with open ("list_of.txt", 'w+') as op:
	op.write(str(panel))

def exer():
	empty_c = {}
	empty_c[car_nam] = ger
	panel.update(empty_c)
	another_string = empty_c
	reg = re.compile('[{}]')
	text = ("It USD = ")
	print (text,(reg.sub('', str(another_string))))
	with open('list_of.txt', 'a') as last:
		last.write(str(empty_c))

with open ("list_of.txt", 'r+') as oa:
	pane = eval(oa.read())
	car_nam = input("Type car name? ")
	if car_nam in pane:
		cost = ("costUSD")
		ge = panel.get(car_nam)[cost]
		print (car_nam, "cost in USD ", ge)
	else:
		print("Add price to car in  USD? ")
		ger = float(input())
		print ("What valuta EUR or GBP?")
		val = input("")
		if val == "EUR":
			EURO_to_dollar = float(0.89)
			suma = (ger*EURO_to_dollar)
			print ("In EURO", "%.2f"% suma)
			exer()
		elif val == "GBP":
			Dollar_to_GBP = float(0.76)
			sum1 = (ger * Dollar_to_GBP)
			print ("In GBP", "%.2f"% sum1)
			exer()
		else:
			exer()

f.close()


# -- coding: utf-8 --

# Copyright 2018 Olivier Scholder <o.scholder@gmail.com>

from pySPM import Block, utils
import numpy as np
import struct
import os.path
import zlib
import re

class InvalidRAWdataformat(Exception):
    def __init__(self, block, msg):
        self.block = block
        self.msg = msg

    def __str__(self):
        return "Invalid RAW dataformat seen in block "+self.block.parent+'/'+self.block.name+' : '+self.msg

class ITM:
    def __init__(self, filename, debug=False):
        """
        Create the ITM object out of the filename.
        Note that this works for all .ITA,.ITM, .ITS files as they have the same structure

        The ITM has the speciality to contain the "rawdata" block. Which contains a lot of sub-blocks all having a name which concists of spaces followed by numbers.
            Blocks: '  20': Contains parameters of the ToF-SIMS recorder during the measurement such as the Emission Current and the Suppressor Voltages.
                    All the parameters saves have the sames names that the ones found in propend and propstart.
                    '   2': Is the start block. Contains no info
                    '   3': It's the end block. Contains a byte (unknown meaning)
                    '   6': Uint32 indicating the scan number
                    '   7': uint64 telling the pixel id of the next '  14' block. The id is the scanNumber*(width*height)+height*row+col
                    '  14': binary block compressed with zlib. The raw data are encoded by a suite of uint32.
                            The sequence is as follow. The first 4-btyes should end with \xC0, the the second with \xD0, the third to \x40, the a suite of uint32 which don't end with \xc0
                            and the sequence starts again. Each sequence tell:
                                The first uint32 terminating by \xC0 tells the x coordinates of the pixel location (just replace the \xC0 byte by 0 and read it as a uint32)
                                The second uint32 terminating by\cD0 telld the y coord. of the pixel
                                The third terminating by \x40 tells the pixel number (increasing monotonically. I know iontof like to write 10 times the same information everywhere)
                                The rest are the detected peaks measured in channel unit for that specific pixel. In order to get the mass see the channel2mass function
        """
        self.filename = filename
        assert os.path.exists(filename)
        self.f = open(self.filename, 'rb')
        self.Type = self.f.read(8)
        assert self.Type == b'ITStrF01'
        self.root = Block.Block(self.f)
        d = self.root.goto('Meta/SI Image').dictList()
        self.size = {
            'pixels': {
                'x': d['res_x']['long'],
                'y': d['res_y']['long']},
            'real': {
                'x': d['fieldofview']['float'],
                'y': d['fieldofview']['float']*d['res_y']['long']/d['res_x']['long'],
                'unit': 'm'}}
        try:
            self.size['Scans'] = \
                self.root.goto(
                    'filterdata/TofCorrection/ImageStack/Reduced Data/ImageStackScans/Image.NumberOfScans').getULong()
        except:
            pass
        self.peaks = {}
        self.MeasData = {}
        try:
            self.Nscan = self.root.goto('propend/Measurement.ScanNumber').getKeyValue()['int']
        except:
            self.Nscan = None

        try:
            R = [z for z in self.root.goto('MassIntervalList').getList() if z[
                'name'] == 'mi']
            N = len(R)
            for x in R:
                try:
                    X = self.root.goto('MassIntervalList/mi['+str(x['id'])+']')
                    d = X.dictList()
                    self.peaks[d['id']['long']] = d
                except ValueError:
                    pass
        except Exception as e:
            if debug:
                raise e

    def getPeakList(self, name):
        """
        Retrieve extra MassIntervalList (MIL) by it's name. Those are saved and visible in iontof software in the spectrum window.
        """
        PeakList = []
        for x in self.root.goto('filterdata/TofCorrection/Spectrum/Reduced Data/ExtraMILs'):
            if x.goto('Name').getString() == name:
                for y in [z for z in x.getList() if z['name'].decode() == 'mi']:
                    d = x.goto('mi[{}]'.format(y['id'])).dictList()
                    PeakList.append({key.decode('utf8'):d[key] for key in d})
                return PeakList
        return None

    def showPeakList(self, name):
        for m in self.getPeakList(name):
            print("{id[long]}: ({desc[utf16]}) [{assign[utf16]}] {lmass[float]:.2f}u - {umass[float]:.2f}u (center: {cmass[float]:.2f}u)".format(**m))

    def get_summary(self):
        """
        Retrieve a summary of the important data concerning the measurement
        """
        values = self.getValues(start=False,names=["Instrument.SputterGun.Energy","Instrument.SputterGun.Species",
            "Instrument.LMIG.Extractor","Instrument.LMIG.Lens_Source","Instrument.Analyzer.ExtractionDelay",
            "Analysis.AcquisitionTime","Analysis.SputterTime","Analysis.TotalScans","Analysis.TotalTime"])
        def Get(v,k):
            return v.get(k,['Unknown'])[0]

        return {
            'pixels': self.size['pixels'],
            'fov': self.root.goto('Meta/SI Image[0]/fieldofview').getDouble(),
            'LMIG': {
                'Extractor': Get(values,"Instrument.LMIG.Extractor"),
                'Lens_Source': Get(values,"Instrument.LMIG.Lens_Source")},
            'ExtractionDelay': Get(values,"Instrument.Analyzer.ExtractionDelay"),
            'SputterSpecies': values.get('Instrument.SputterGun.Species',['Off'])[0],
            'SputterEnergy': values.get('Instrument.SputterGun.Energy',['Off'])[0],
            'AnalysisTime': Get(values,"Analysis.AcquisitionTime"),
            'SputterTime': Get(values,"Analysis.SputterTime"),
            'Scans': values.get("Analysis.TotalScans",[self.Nscan])[0],
            'TotalTime':  Get(values, "Analysis.TotalTime"),
            'peaks': self.get_masses(),
            }

    def getIntensity(self):
        """
        Retieve the total Ion image
        """
        X, Y = self.size['pixels']['x'], self.size['pixels']['y']
        return np.array(struct.unpack('<'+str(X*Y)+'I',
                                      zlib.decompress(self.root.goto('Meta/SI Image/intensdata').value))).reshape((Y, X))

    def get_LMIG_info(self):
        rs = self.getValues(start=True)
        re = self.getValues()
        Val = [["Parameter name", "Value at start", "Value at end"]]
        for i, x in enumerate(rs):
            Val.append([x, rs[x], re[x]])

    def getValue(self, name, end=True):
        return self.root.goto('prop{}/{name}'.format(['start','end'][end],name=name)).getKeyValue()

    def getValues(self, pb=False, start=True,end=True,names=[], startsWith="", nest=False, hidePrefix=True):
        """
        Beta function: Retieve a list of the values
        """
        Vals = {}
        startEnd = []
        if start:
            startEnd.append(True)
        if end:
            startEnd.append(False)
        for start in startEnd:
            List = self.root.goto(['propend', 'propstart'][start]).getList()
            if pb:
                import tqdm
                List = tqdm.tqdm(List)
            for l in List:
                Node = self.root.goto(['propend', 'propstart'][
                                      start]).gotoItem(l['name'], l['id'])
                r = Node.getKeyValue()
                del Node
                S = Vals
                if r['key'] in names or ( names==[] and r['key'].startswith(startsWith) ):
                    if hidePrefix:
                        key_name = r['key'][len(startsWith):]
                    else:
                        key_name = r['key']
                    if nest:
                        K = key_name.split('.')
                        for k in K:
                            if k not in S:
                                S[k] = {}
                            S = S[k]
                        S['value @'+['end', 'start'][start]] = r['string']
                    else:
                        if key_name in Vals:
                            Vals[key_name].append(r['string'])
                        else:
                            Vals[key_name] = [r['string']]

        return Vals

    def autoMassCal(self, t=None, S=None, pos=True, debug=False, Range=5000, FittingPeaks = ['C','CH','CH2','CH3','Na'], sf=None, k0=None):
        """
        perform an auto callibration for positive spectrum. (in test, might be unreliable)
        """
        from scipy.optimize import curve_fit
        TimeWidth = 1e10*self.root.goto('propend/Instrument.LMIG.Chopper.Width').getKeyValue()['float']
        if t is None or S is None:
            t, S = self.getSpectrum(time=True)
        N = np.prod(list(self.size['pixels'].values())) * self.Nscan
        mask = S > N*0.01/TimeWidth
        times_start = t[1:][np.nonzero(mask[1:]*(~mask[:-1]))]
        times_end = t[np.nonzero(mask[:-1]*(~mask[1:]))]
        times = (times_start + times_end)/2
        tH = times[0]
        mask = (t>=tH-TimeWidth)*(t<=tH+TimeWidth)
        tH = t[mask][np.argmax(S[mask])]
        if sf is None or k0 is None:
            sf=1e5
            for i in range(3):
                k0 = tH-sf*np.sqrt(utils.getMass('H+'))
                m = utils.time2mass(t, sf=sf, k0=k0)
                mP = utils.time2mass(times, sf=sf, k0=k0)
                t0 = times[np.argmin(np.abs(mP-12))]
                t1 = times[np.argmin(np.abs(mP-12))+1]
                sf = np.sqrt((t1-k0)**2 - (t0-k0)**2)
                k0 = tH-sf*np.sqrt(utils.getMass('H+'))
        ts = []
        for x in [utils.mass2time(utils.getMass(x+'+'), sf=sf, k0=k0) for x in FittingPeaks]:
            mask = (t>=(x-Range))*(t<=(x+Range))
            t_peak = t[mask][np.argmax(S[mask])]
            ts.append(t_peak)
        ms = [utils.getMass(x+'+') for x in FittingPeaks]
        if debug:
            return utils.fitSpectrum(ts, ms), ts, ms
        return utils.fitSpectrum(ts, ms)

    def showValues(self, pb=False, gui=False, **kargs):
        html = True
        if 'html' in kargs:
            html = kargs['html']
            del kargs['html']
        if gui:
            from pySPM import GUI
            Vals = self.getValues(pb, nest=True, **kargs)
            GUI.ShowValues(Vals)
        else:
            Vals = self.getValues(pb, **kargs)
            Table = [["Parameter Name", "Value @start", "Value @end"]]
            for x in Vals:
                Table.append(tuple([x]+Vals[x]))
            if not html:
                print(utils.aa_table(Table, header=True))
            else:
                from IPython.core.display import display, HTML
                res = utils.html_table(Table, header=True)
                display(HTML(res))

    def get_mass_cal(self):
        V = self.root.goto('filterdata/TofCorrection/Spectrum/Reduced Data/IMassScaleSFK0')
        sf = V.goto('sf',lazy=True).getDouble()
        k0 = V.goto('k0',lazy=True).getDouble()
        return sf, k0

    def channel2mass(self, channels, sf=None, k0=None, binning=1):
        """
        Calculate the mass from the time of flight
        The parameters sf and k0 will be read from the file (calibration used by iontof) in case they are None
        The binning just multiply the channels in order to get the correct answer (used for the ITA files for the moment)
        default values for uncalibrated spectrum are sf = 100'000 &  k0 = 0
        The time can be retrieved by knowing the channel width (typically 100ps). So time = channel * channelWidth
        The mass = (2*q*U/L**2)*(channel*channelWidth)**2
        L is the path length, thus twice the columns length and is about 2m I think
        For an extractor of 2keV and L=2m, 1u = (time[s]*310620.843175[u**.5/s])**2 = [channel/sf]**2 => sf is about 32000 for k0 = 0
        Caution. If data are binned, the channel number should be multiplied by the binning factor in order to use the same sf and k0 factor!

        For information the channel width is 50ps and is strangely not saved in the file.
        """
        if sf is None or k0 is None:
            sf0, k00 = self.get_mass_cal()
        if sf is None:
            sf = sf0
        if k0 is None:
            k0 = k00
        return ((binning*channels-k0)/(sf))**2

    def getSpectrum(self, sf=None, k0=None, time=False):
        """
        Retieve a mass,spectrum array
        This only works for .ita and .its files.
        For this reason it is implemented in the itm class.
        """
        RAW = zlib.decompress(self.root.goto(
            'filterdata/TofCorrection/Spectrum/Reduced Data/IITFSpecArray/CorrectedData').value)
        D = np.array(struct.unpack("<{0}f".format(len(RAW)//4), RAW))
        ch = 2*np.arange(len(D))
        if time:
            return ch, D
        return self.channel2mass(ch, sf=sf, k0=k0), D

    def getMeasData(self, name='Instrument.LMIG.Emission_Current', prog=False, debug=False):
        """
        Allows to recover the data saved during the measurements.
        This function is like getValues, but instead of giving the values at the beginning and at the end,
        it track the changes of them during the measurement.
        """
        if name in self.MeasData:
            return self.MeasData[name]
        rawdata = self.root.goto('rawdata')
        L = rawdata.getList()
        i = 1
        while L[-i]['name'] !=  '  20':
            i += 1
        max_index = L[-i]['id']
        if prog:
            try:
                from tqdm import tqdm_notebook as tqdm
            except:
                from tqdm import tqdm as tqdm
            T = tqdm(L)
        else:
            T=L
        for i,elt in enumerate(T):
            if elt['name'] != '  20':
                continue
            idx = elt['bidx']
            self.f.seek(idx)
            child = Block.Block(self.f)
            r = child.getKeyValue(0)
            if not r['key'] in self.MeasData:
                self.MeasData[r['key']] = []
            self.MeasData[r['key']].append((idx,r['float']))
        if name in self.MeasData:
            return self.MeasData[name]
        else:
            raise KeyError(name)

    def showMeasData(self, name='Instrument.LMIG.Emission_Current', prog=False, ax=None, mul=1, scans=2, **kargs):
        t = self.getMeasData('Measurement.AcquisitionTime')
        S = self.getMeasData("Measurement.ScanNumber")
        idx = [x[0] for x in t]
        time = [x[1] for x in t]
        ScanData = [x[1] for x in S]
        ScanIdx = [x[0] for x in S]
        s = np.interp(ScanIdx,idx,time)

        Meas = self.getMeasData(name,prog=prog)

        MeasData = [x[1] for x in Meas]
        MeasIdx = [x[0] for x in Meas]
        t = np.interp(MeasIdx,idx, time)
        if ax is None:
            import matplotlib.pyplot as plt
            ax = plt.gca()
        p = ax.plot(t, np.array(MeasData)*mul, **kargs)
        ax.set_xlabel("Time [s]");
        ax.set_ylabel(name)
        if scans:
            assert type(scans) is int
            lim = ax.get_ylim()
            axs = ax.twiny()
            axs.set_xticks(.5*s[:-1:scans]+.5*s[1::scans])
            axs.set_xticklabels([str(i+1) for i in range(0,self.Nscan,scans)])
            colors = [i%2 for i in range(0,self.Nscan,scans)]
            for i,tick in enumerate(axs.xaxis.get_ticklabels()):
                tick.set_color(["black","green"][colors[i]])
            axs.set_xlim(ax.get_xlim())
            for i in range(1,self.Nscan-1,2):
                ax.fill_between([s[i],s[i+1]],*lim,color='green',alpha=.1)
            axs.set_xlabel("Scan number")
            axs.set_xlim(ax.get_xlim())
            axs.set_ylim(*lim)
        return p

    def showSpectrum(self, low=0, high=None, sf=None, k0=None, ax=None, log=False, showPeaks=True):
        """
        Plot the (summed) spectrum
        low and high: mass boundary of the plotted data
        ax: matplotlib axis
        log: plot the log of the intensity if True
        """
        m, s = self.getSpectrum(sf=sf,k0=k0)
        if ax is None:
            import matplotlib.pyplot as plt
            ax = plt.gca()
        if high is None:
            high = m[-1]
        mask = np.logical_and(m >= low, m <= high)
        M = m[mask]
        S = s[mask]
        if log:
            S = np.log(S)
        ax.plot(M, S)
        self.get_masses()
        if showPeaks:
            for P in [x for x in self.peaks if self.peaks[x]['desc']['utf16'] not in ['total','sum of rest']]:
                p = self.peaks[P]
                c = p['cmass']['float']
                mask = (m >= p['lmass']['float'])*(m <= p['umass']['float'])
                if c >= low and c <= high:
                    i = np.argmin(abs(m-c))
                    ax.axvline(m[i], color='red')
                    ax.fill_between(m[mask], *ax.get_ylim(), color='red', alpha=.2)
                    ax.annotate(p['assign']['utf16'], (m[i], ax.get_ylim()[
                                1]), (2, -10), va='top', textcoords='offset points')

    def get_masses(self, mass_list=None):
        """
        retrieve the peak list as a dictionnary
        """
        if mass_list is None:
            masses = self.peaks
        else:
            masses = mass_list
        result = []
        for P in masses:
            if mass_list is None:
                p = self.peaks[P]
            else:
                p = P
            result.append({
                'id': p['id']['long'],
                'desc': p['desc']['utf16'],
                'assign': p['assign']['utf16'],
                'lmass': p['lmass']['float'],
                'cmass': p['cmass']['float'],
                'umass': p['umass']['float']})
        return result

    def getRawSpectrum(self, scans=None, ROI=None, FOVcorr=True, deadTimeCorr=True, **kargs):
        """
        Reconstruct the spectrum from RAW data.
        scans: List of scans to use. if None all scans are used (default)
        ROI: Region Of Interest. It can be:
            1) None: All pixels are used
            2) A list of images. The pixels will be added to the spectrum i if the value of the i-th image is True for that pixel
            3) An image with integer value. The current pixels will be added to the i-th spectrum if the value of ROI at that pixel is i.
        FOVcorr: Correction for the primary time of flight variation

        Δt = (√2/2)∙x∙√(mp/(2∙E)) where x is the x-corrdinate (in m), mp, the primary ion mass (in kg) and E the primary energy
        as E=½∙mp∙v² ⇒ v = √(2E/mp)

        Note: if E is given in eV, it should be multiplied by the electron charge.

        deadTimeCorr: Dead time correction (Poisson statistics)

        Icorr(c) = -N*log(1-I(c)/N'(c))
        where N = Nscan*size['x']*size['y']
        N'(c) = N - sum_{c'=c-ct}^{c-1}I(c')

        see Ref. T. Stephan, J. Zehnpfenning and A. Benninghoven, J. vac. Sci. A 12 (2), 1994

        """
        if ROI is None and 'roi' in kargs:
            ROI = kargs['roi']

        gun = self.root.goto('propend/Instrument.PrimaryGun.Species').getKeyValue()['string'] # Primary Gun Species (Bi1,Bi3,Bi3++)

        # if the + is missing in the name, add it
        if gun[-1]!='+':
            gun += '+'

        Q = gun.count('+') # number of charge

        nrj = self.root.goto('propend/Instrument.PrimaryGun.Energy').getKeyValue()['float'] # Primary ion energy (in eV)
        dx = self.size['real']['x']/self.size['pixels']['x'] # distance per pixel

        # Calculate the mass of the primary ion
        mp = utils.getMass(gun)

        # Perform the time of flight correction?
        if FOVcorr:
            DT = dx*(1/5e-11)*.5*np.sqrt(2)*np.sqrt((1e-3*mp/utils.NA)/(Q*2*nrj*utils.qe)) # delta time in channel per pixel. The 5e-11 is the channelwidth (50ps)
            # sqrt(2)/2 is from the sin(45°), nrj=E=.5*mp*v^2
        else:
            DT = 0

        if scans is None:
            scans = range(self.Nscan)

        assert hasattr(scans, '__iter__')

        # Allocate vector for the spectrum
        number_channels = int(round(self.root.goto('propend/Measurement.CycleTime').getKeyValue()['float']\
            / self.root.goto('propend/Registration.TimeResolution').getKeyValue()['float']))

        if kargs.get('prog',False):
            try:
                from tqdm import tqdm_notebook as tqdm
            except:
                from tqdm import tqdm as tqdm
            T = tqdm(scans)
        else:
            T = scans

        if ROI is None:
            Spectrum = np.zeros(number_channels, dtype=np.float32)
            for s in T:
                Data = self.getRawData(s)[2]
                for xy in Data:
                    dt = DT*(self.size['pixels']['x']/2-xy[0]) # time correction for the given x coordinate (in channel number)
                    ip = int(dt)
                    fp = dt%1
                    for x in Data[xy]:
                        Spectrum[x-ip] += (1-fp)
                        Spectrum[x-ip-1] += fp
        elif type(ROI) is np.ndarray:
            assert np.min(ROI)>=0
            Spectrum = np.zeros((number_channels,np.max(ROI)+1), dtype=np.float32)
            for s in T:
                Data = self.getRawData(s)[2]
                for xy in Data:
                    dt = DT*(self.size['pixels']['x']/2-xy[0]) # time correction for the given x coordinate (in channel number)
                    ip = int(dt)
                    fp = dt%1
                    id = ROI[xy[1],xy[0]]
                    for x in Data[xy]:
                        Spectrum[x-ip, id] += (1-fp)
                        Spectrum[x-ip-1, id] += fp
        elif type(ROI) in [list,tuple]:
            multi_roi = True
            Spectrum = np.zeros((number_channels,len(ROI)), dtype=np.float32)
            for s in T:
                Data = self.getRawData(s)[2]
                for xy in Data:
                    dt = DT*(self.size['pixels']['x']/2-xy[0]) # time correction for the given x coordinate (in channel number)
                    ip = int(dt)
                    fp = dt%1
                    li = []
                    for k,R in enumerate(ROI):
                        if R[xy[1],xy[0]]:
                            li.append(k)
                    for x in Data[xy]:
                        for k in li:
                            Spectrum[x-ip,k] += (1-fp)
                            Spectrum[x-ip-1,k] += fp
        sf = kargs.get('sf',self.root.goto('MassScale/sf').getDouble())
        k0 = kargs.get('k0',self.root.goto('MassScale/k0').getDouble())
        masses = self.channel2mass(np.arange(number_channels),sf=sf,k0=k0)
        if deadTimeCorr:
            dt = 2000 # 100ns*(1ch/50ps) = 2000 channels
            N = self.Nscan*self.size['pixels']['x']*self.size['pixels']['y'] # total of count events
            Np = np.zeros(Spectrum.shape)
            if Spectrum.ndim>1:
                for i in range(Spectrum.shape[1]):
                    Np[:,i] = N-np.convolve(Spectrum[:,i], np.ones(dt-1,dtype=int), 'full')[:-dt+2]
            else:
                Np = N-np.convolve(Spectrum, np.ones(dt-1,dtype=int), 'full')[:-dt+2]
            Np[Np==0] = 1
            Spectrum = -N*np.log(1-Spectrum/Np)
        if kargs.get('time',False):
            return np.arange(number_channels), Spectrum
        return masses, Spectrum

    def getRawData(self, scan=0):
        """
        Function which allows you to read and parse the raw data.
        With this you are able to reconstruct the data.
        Somehow the number of channel is double in the raw data compared
        to the compressed version saved in the ITA files.
        scan: The scan number. Start at 0
        """
        assert scan < self.Nscan
        found = False
        RAW = b''
        list_ = self.root.goto('rawdata').getList()
        startFound = False
        for x in list_:
            if x['name'] == '   6':
                if not startFound:
                    startFound = x['id'] == scan
                else:
                    break
            elif startFound and x['name'] == '  14':
                self.root.f.seek(x['bidx'])
                child = Block.Block(self.root.f)
                RAW += zlib.decompress(child.value)
        Blocks = {}
        _Block = []
        PixelList = []
        PixelOrder = np.zeros(
            (self.size['pixels']['y'], self.size['pixels']['x']))
        i = 0
        while i < len(RAW):
            b = RAW[i:i+4]
            if b[3:4] == b'\xc0':
                if len(_Block):
                    Blocks[(x, y)] = _Block
                b = b[:3] + b'\x00'
                x = struct.unpack('<I', b)[0]
                i += 4
                b = RAW[i:i+4]
                if b[3:4] != b'\xd0':
                    raise TypeError("Expecting a D0 block at {}".format(i+3))
                b = b[:3] + b'\x00'
                y = struct.unpack('<I', b)[0]
                i += 4
                b = RAW[i:i+4]
                if b[3] < 64:
                    raise TypeError("Expecting a 40 or higher block at {}, got {:02x}".format(i+3,b[3]))
                b = b[:3] + bytes([b[3]&16])
                _Block = []
                id = struct.unpack('<I', b)[0]
                PixelOrder[y, x] = id
                PixelList.append((x,y))
            else:
                _Block.append(struct.unpack('<I', b)[0])
            i += 4
        return PixelList, PixelOrder, Blocks

    def show_masses(self, mass_list=None):
        """
        Display the peak list (assignment name with lower, center and upper mass)
        """
        for m in self.get_masses():
            if mass_list is None or m['id'] in [z['id'] for z in mass_list]:
                print(
                    "{id}: ({desc}) [{assign}] {lmass:.2f}u - {umass:.2f}u (center: {cmass:.2f}u)".format(**m))

    def showStage(self, ax=None, markers=False):
        """
        Display an image of the stage used
        ax: maplotlib axis to be ploted in. If None the current one (or new) will be used
        markers: If True will display on the map the Position List items.
        """
        W = self.root.goto('SampleHolderInfo/bitmap/res_x').getLong()
        H = self.root.goto('SampleHolderInfo/bitmap/res_y').getLong()

        if ax is None:
            import matplotlib.pyplot as plt
            fig, ax = plt.subplots(1, 1, figsize=(W*10/H, 10))

        Dat = zlib.decompress(self.root.goto(
            'SampleHolderInfo/bitmap/imagedata').value)
        I = 255*np.array(struct.unpack("<"+str(W*H*3)+"B", Dat)
                         ).reshape((H, W, 3))
        ax.imshow(I)
        if markers:
            X = self.root.goto('Meta/SI Image[0]/stageposition_x').getDouble()
            Y = self.root.goto('Meta/SI Image[0]/stageposition_y').getDouble()

            def toXY(xy, W, H):
                sx = 23
                sy = 23
                return (913+sx*xy[0], 1145+sy*xy[1])

            for x in self.root.goto('SampleHolderInfo/positionlist'):
                if x.name == 'shpos':
                    y = pickle.loads(x.goto('pickle').value)
                    pos = toXY((y['stage_x'], y['stage_y']), W, H)
                    if pos[0] >= 0 and pos[0] < W and pos[1] >= 0 and pos[1] < H:
                        ax.annotate(y['name'], xy=pos, xytext=(-15, -25), textcoords='offset points',
                                    arrowprops=dict(arrowstyle='->', facecolor='black'))
                pos = toXY((X, Y), W, H)
                ax.plot(pos[0], pos[1], 'xr')
        ax.set_xlim((0, W))
        ax.set_ylim((0, H))

    def showPeaks(self):
        self.getMassInt()
        for p in self.peaks:
            P = {k.decode('utf8'): self.peaks[p][k] for k in self.peaks[p]}
            print("{0}) {peaklabel}".format(p, **P))

    def modify_block_and_export(self, path, new_data, output, **kargs):
        self.root.modify_block_and_export(path, new_data, output, **kargs)