import os
import re
import sys
import csv
import time
import getopt
import subprocess
import collections
import pandas as pd
import find_invariant as fi
import refine as refine
from shutil import copyfile
import association_rule_learning as assorule
import multiprocessing
import multiprocessing.dummy
import multiprocessing.managers
from sklearn.externals import joblib

class DataProcess(object):
    def __init__(self, name, replace_index):
        self.name = name
        self.replace_index = replace_index

    def execute(self, save=True, load=False):
        if load:
            try:
                return joblib.load("%s/data/dataset.pkl" % self.name), joblib.load("%s/itemMeaning.pkl" % self.name)
            except:
                raise FileExistsError
        dataList, stateDict = processor.collect_dataset()
        para_digit = self.para_form(stateDict.keys())
        dataset, itemMeaning = processor.encode(dataList, stateDict)

        if save:
            joblib.dump(dataset, "{}/data/dataset.pkl".format(self.name))
            joblib.dump(itemMeaning, "{}/data/itemMeaning.pkl".format(self.name))

        return dataset, itemMeaning, para_digit  # df, itemMeaning

    def para_form(self, name_list):
        """
        the parameter the protocol uses
        with symmetry reduction: NODE_1, NODE_2, ...
        without: 1, 2, ...
        '[]' is a symbol of local variables
        :param name_list:
        :return:
        """
        for name in name_list:
            if '[' in name:
                return False if re.search(r'\w+\_\d', name) else True
            continue
        return True

    def collect_dataset(self):
        """
        From reachable set collect dataset
        :return:
        dataList:
            [
                [v1, v2, ..., vn],
                [e11, e12, ..., e1n],
                ...,
                [en1,en2, ..., enn]]
        dataDict:
            {v1: {e11,e21,..., en1}, v2: {e12,e22, ..., en2},...}
        """
        print('Reading reachable set')
        if not os.path.exists('{0}/{0}.csv'.format(self.name)) and not os.path.exists('{0}/{0}.txt'.format(self.name)):
            raise FileExistsError
        if not os.path.exists('{0}/{0}.csv'.format(self.name)) or not self.is_rs_match_dataset():
            return self.txt2csv()
        else:
            return self.readcsv()

    def is_rs_match_dataset(self):
        """
        Counts the number of states in reachable set printed by Murphi and the number of lines in transferred csv.
        If these two equal, return True; else return False

        NOTE: actually csv file will add a title line with variable names, so # states in txt +1 = # lines in csv
        """
        print('call is_rs_match_dataset')

        csv_cnt = subprocess.check_output(['wc', '-l', '{0}/{0}.csv'.format(self.name)]).decode('utf-8')
        tail_rs = subprocess.check_output(['tail', '{0}/{0}.txt'.format(self.name)]).decode('utf-8')
        return int(re.findall(r'\d+', csv_cnt)[0]) == int(
            re.findall(r'State Space Explored:.*?(\d+)\sstates', tail_rs, re.S)[0]) + 1

    def readcsv(self):
        print('call read_csv')
        df = pd.read_csv('{0}/{0}.csv'.format(self.name))
        stateDict = {}
        booleandf = set(df.select_dtypes(include=[bool]).columns.values)

        for col in df.columns:
            if col in booleandf:
                df[col] = df[col].map({True: 'true', False: 'false'})
            stateDict[col] = set(df[col])
        return [df.columns.tolist()] + df.values.tolist(), stateDict

    def txt2csv(self):
        print('txt2csv...')
        csv_filename = '{0}/{0}.csv'.format(self.name)

        reachset = open('{0}/{0}.txt'.format(self.name)).read()

        if self.replace_index:
            for k, v in self.replace_index.items():
                reachset = reachset.replace(k, v)
        states = re.findall(r'State\s\d+:\n(.*?)\n\n', reachset, re.S)

        variables = [var.split(':')[0] for var in states[0].split('\n')]

        dataset = [variables]
        open(csv_filename, 'w').write("{}\n".format("".join(variables)))

        stateDict = collections.defaultdict(set)

        for state in states:
            for var in state.split('\n'):
                stateDict[var.split(":")[0]].add(var.split(":")[1])
            # dataset.append([var for var in state.split('\n')])
            dataset.append([var.split(':')[1] for var in state.split('\n')])

        with open(csv_filename, 'w') as f:
            for line in dataset:
                f.write(','.join(line) + '\n')
        return dataset, stateDict

    def describe(self, dataList):
        print('---------------------')
        print('Protocol {} has {} states.'.format(self.name, len(dataList) - 1))
        print('Each state has {} variables.'.format(len(dataList[0])))
        print('---------------------\n')

    def encode(self, dataList, stateDict):
        has_atom = os.path.exists('{0}/atom.txt'.format(self.name))
        dataset, itemMeaning = self.tonumber(dataList, stateDict, atom=has_atom, neg=True)
        # print(dataset, itemMeaning)
        #
        # # encoding
        # print('encoding...')
        # te = TransactionEncoder()
        # te_ary = te.fit(dataset).transform(dataset)
        # df = pd.DataFrame(te_ary, columns=te.columns_)
        # print('Total items in rs: %d' % len(itemMeaning))
        # print('finished')
        #
        # saving data
        # return df, itemMeaning
        return dataset, itemMeaning

    def tonumber(self, stateList, statesDict, atom=False, neg=False):
        stateList, statesDict = self.atom_feature(statesDict, stateList, self.get_atoms())
        mappingDict, itemMeaning = self.states2num_atom(statesDict)
        states_numberful = self.mapStates(mappingDict, stateList)
        return states_numberful, itemMeaning
        # elif neg:
        #     stateList, statesDict = self.negative(stateList, statesDict)
        #     mappingDict, itemMeaning = self.states2num(statesDict)
        # else:
        #     mappingDict, itemMeaning = self.states2num(statesDict)

    def enumerateStates(self, stateslist):
        statesDict = collections.defaultdict(set)
        col = len(stateslist[0])
        row = len(stateslist)
        for c in range(col):
            for r in range(1, row):
                if (stateslist[r][c] not in statesDict[stateslist[0][c]]) and (stateslist[r][c] != 'Undefined'):
                    statesDict[stateslist[0][c]].add(stateslist[r][c])
        return statesDict

    def atom_feature(self, stateDict, stateList, atom_feature):
        new_statelist, new_stateDict = [], {}
        index = {title: i for i, title in enumerate(stateList[0])}

        for i, af in enumerate(atom_feature):
            pre = af.split(' ')[0]
            post = af.split(' ')[-1]
            col = index[pre]
            cur = [af]

            for row in range(1, len(stateList)):
                if post in stateDict[pre]:
                    cur.append(str(post == stateList[row][col]))
                else:
                    if post in index:
                        col_post = index[post]
                        if stateList[row][col] != 'Undefined' and stateList[row][col_post] != 'Undefined':
                            cur.append(str(stateList[row][col_post] == stateList[row][col]))
                        else:
                            cur.append('Undefined')
                    else:
                        cur = []
                        break
            if cur:
                new_statelist.append(cur)
                new_stateDict[af] = {x for x in cur} - {af}

        t_statelist = list(list(i) for i in zip(*new_statelist))
        assert len(new_statelist) == len(t_statelist[0])
        assert len(new_statelist[0]) == len(t_statelist)

        print("Features / Atomic predicates: % d " % len(atom_feature))
        return t_statelist, new_stateDict

    def states2num_atom(self, statesDict):
        newDict = collections.defaultdict(lambda: collections.defaultdict(int))
        itemMeaning = {}
        cnt = 0

        for key, value in statesDict.items():
            for v in value:
                if v == 'Undefined':
                    continue
                low_key = key.lower()
                if 'true' in low_key or 'false' in low_key:
                    if 'true' in low_key:
                        itemMeaning[cnt] = key if v.lower() == 'true' else re.sub('true', 'false', key)
                    else:
                        itemMeaning[cnt] = key if v.lower() == 'true' else re.sub('false', 'true', key)
                else:
                    if v.lower() == 'false':
                        itemMeaning[cnt] = re.sub(r'=', '!=', key)
                    else:
                        itemMeaning[cnt] = key

                newDict[key][v] = cnt
                cnt += 1
        # print('ItemMeaning:', itemMeaning)
        # for key, value in itemMeaning.items():
        #     print(key, value)
        print('Total products in rs: %d ' % len(itemMeaning))
        return newDict, itemMeaning

    def mapStates(self, mappingDict, stateList):
        print('Mapping states into numbers using all variables...')
        states_numberful = []
        for r in range(1, len(stateList)):
            temp = set()
            for c in range(len(stateList[0])):
                if stateList[r][c] != 'Undefined':
                    temp.add(mappingDict[stateList[0][c]][stateList[r][c]])
            states_numberful.append(temp)

        print('successfully mapped!')
        return states_numberful

    def get_atoms(self):
        file_name = "{}/atom.txt".format(self.name)
        return set(filter(lambda x: x,
                          map(lambda x: re.sub(r'[()]', '', x.strip()), open(file_name, 'r').read().split("\n"))))

    def select_global(self, itemMeaning):
        global_vars = set()
        for k, v in itemMeaning.items():
            if not re.search('[\[\]]', v):
                global_vars.add(k)
        return global_vars

    def negative(self, stateList, statesDict):
        for i in range(1, len(stateList)):
            n = len(stateList[i])
            for j in range(n):
                vals = statesDict[stateList[0][j]]
                if len(vals) <= 2:
                    continue
                for v in vals:
                    if i == 1:
                        stateList[0].append(stateList[0][j])
                    stateList[i].append(v if v == stateList[i][j] else '!' + v)

        statesDict2 = self.enumerateStates(stateList)
        return stateList, statesDict2
        # def states2num(self, statesDict):
        #     newDict = collections.defaultdict(lambda: collections.defaultdict(int))
        #     itemMeaning = {}
        #     cnt = 0
        #
        #     for key, value in statesDict.items():
        #         for v in value:
        #             v = str(v)
        #             if v == 'Undefined': continue
        #             if '!' in v: itemMeaning[cnt] = key + ' != ' + v[1:]
        #             else:
        #                 itemMeaning[cnt] = key + ' = ' + v
        #             newDict[key][v] = cnt
        #             cnt += 1
        #     return newDict, itemMeaning

class RuleLearing(object):
    def __init__(self, df, params, itemMeaning, name, global_vars, freq_size=3, min_support=0.0, min_confidence=1.0,
                 is_minimize=False):
        self.df = df
        self.params = params
        self.name = name
        self.global_vars = global_vars
        self.itemMeaning = itemMeaning
        self.freq_size = freq_size
        self.min_support = min_support
        self.min_confidence = min_confidence
        self.is_minimize = is_minimize
        self.antecedants = []
        self.consequents = []

    def execute(self, para_digit, save=True, load=False):
        if load:
            try:
                self.antecedants = joblib.load('{0}/data/left.pkl'.format(self.name))
                self.consequents = joblib.load('{0}/data/right.pkl'.format(self.name))
            except:
                print('data for RuleLearning cannot be found!')
                # raise FileNotFoundError('data for RuleLearning cannot be found!')

        self.antecedants, self.consequents = assorule.FreqSet_AssoRule().generate(self.name, self.df, self.global_vars,
                                                                                self.itemMeaning,
                                                                                self.freq_size, self.min_support,
                                                                                self.min_confidence,
                                                                                self.is_minimize)

        # learner.learn_association_rule()
        para_rules = self.para_rules(para_digit, save)
        ins_rules = self.instantiate(para_rules)
        self.minimize_rule(ins_rules)

    def para_rules(self, para_digit, save=True):
        """
        parameterize association rules:
        1. parameterize: paralized line, subsitute parameters into P1,P2,... in original order
            i.e., n[NODE_1] = NODE_2 --> n[P1] = P2
                  n[NODE_2] = NODE_1 --> n[P1] = P2

        2. remove repeated: predicates that before and after '->' have the same variable name
            v1 = e1 -> v1 != e2
            or
            v1 = e1 & v2 = e3 -> v1 != e2
           will be removed
        """

        left, right = [], []
        para_rules, rules = set(), set()

        def paralize(line, par):
            """
            paralized line, subsitute parameters into P1,P2,... in original order
            i.e., n[NODE_1] = NODE_2 --> n[P1] = P2
                  n[NODE_2] = NODE_1 --> n[P1] = P2
            :param line:
            :param par:
            :return: paralized line, without changing the original parameters such as 'NODE_1', 'NODE_2'
            """

            search_para = re.search(r'\[\d\]', line) if para_digit else re.search(r'\[%s\_\d\]' % par, line)

            cnt = 1
            while search_para:
                line = line.replace(search_para.group(), '[P%d]' % cnt)
                search_para = re.search(r'\[\d\]', line) if para_digit else re.search(r'\[%s\_\d\]' % par, line)
                cnt += 1
            return line

        for ant, conse in zip(self.antecedants, self.consequents):
            # if len(conse) <= 1:
            line = "{} -> {}".format(' & '.join(sorted(ant)), conse)
            for par in self.params:
                paralized_line = paralize(line, par)
                # paralized_line = line
                if paralized_line in para_rules:
                    # para_rules.remove(paralized_line)
                    continue
                else:
                    para_rules.add(paralized_line)

                    # extract variable names and remove the rule which has same variable in both sides of '='
                    left_var, right_var = set([a.split(' ')[0] for a in ant]), set([conse.split(' ')[0]])

                    if left_var.issubset(right_var) or right_var.issubset(
                            left_var):  # or not re.search('[\[\]]', ''.join(left_var)):
                        para_rules.remove(paralized_line)
                        continue
                    else:
                        left.append(sorted([a for a in ant]))
                        right.append(conse)
                        rules.add("{} -> {}".format(' & '.join(sorted(ant)), conse))

        assert (len(left) == len(right))
        self.antecedants, self.consequents = left, right

        print('Parametrized rules: %d ' % len(left))

        # with open('%s/assoRule_min.txt' % name, 'w') as fw:
        #     for i, rule in enumerate(ins_rules, 1):
        #         fw.write('rule_%d: %s\n' % (i, rule))

        if save:
            f_left = '%s/data/left.pkl' % self.name
            f_right = '%s/data/right.pkl' % self.name

            joblib.dump(left, f_left)
            joblib.dump(right, f_right)

        return para_rules

    def instantiate(self, para_line, paras=['NODE_1', 'NODE_2']):
        """
        instantiate association rules.
        E.g. n[P1] -> P2  will be instantiated into :
             n[i] -> j
        and  n[j] -> i
        :param para_line:
        :return:
        """
        # paras = ['NODE_1', 'NODE_2']
        fname = '{0}/aux_invs.txt'.format(self.name)
        ins_lines = []
        for line in para_line:
            for index in range(len(paras)):
                temp = line
                search_para = re.search(r'P\d', temp)

                while search_para:
                    temp = re.sub(search_para.group(), paras[index], temp)
                    search_para = re.search(r'P\d', temp)
                    index ^= 1
                ins_lines.append(temp)

        with open(fname, 'w') as f:
            for cnt, line in enumerate(ins_lines, 1):
                f.write('rule_%d:   %s\n' % (cnt, line))

        print('instantiated rules: %d ' % len(ins_lines))
        return ins_lines

    def minimize_rule(self, ins_lines):
        fout = '%s/assoRule_min.txt' % self.name

        # with open(fn, 'r') as f:
        #     rules = list(line.strip('\n').split(': ')[1].strip(' ') for line in f.readlines() if line.strip())
        #
        rules = list(map(lambda line: line.split(' -> '), sorted(ins_lines, key=lambda x: len(x))))
        # joblib.dump(rules, 'mutualEx/data/rules.pkl')
        # rules = joblib.load('mutualEx/data/rules.pkl')

        left = [rule[0].split(' & ') for rule in rules]
        right = [rule[1] for rule in rules]

        same_right = collections.defaultdict(list)
        for l, r in zip(left, right):
            same_right[r].append(l)

        for r, left_list in same_right.items():
            index = [x for x in range(len(left_list))]
            for i in range(len(left_list)):
                for j in range(i + 1, len(left_list)):
                    if j not in index: continue
                    if not (set(left_list[i]) - set(left_list[j])):
                        index.remove(j)
            same_right[r] = [left_list[i] for i in index]

        min_rules = []
        new_l, new_r = [], []
        # with open(fout, 'w') as f:
        cnt = 1
        for r, left_list in same_right.items():
            for l in left_list:

                if not re.search('[\[\]]', ''.join(l)):
                    continue
                each = '{} -> {}\n'.format(' & '.join(l), r)
                new_l.append(l)
                new_r.append(r)
                min_rules.append(each)
                # f.write('rule_%d: %s' % (cnt, each))
                cnt += 1

        self.antecedants, self.consequents = new_l, new_r
        print('minimized: %d ' % (cnt - 1))
        assert len(self.antecedants) == cnt - 1
        return min_rules

    def built_map(self):
        """
        build a rule map using antecendents:

        e.g. n[NODE_1] = C -> n[NODE_2] != C
        build a rule map:
        {n[NODE]: n[NODE_1] = C -> n[NODE_2] != C}

        :return:
        """

        rules_map = collections.defaultdict(lambda: collections.defaultdict(set))
        par = self.params[0]

        for left, right in zip(self.antecedants, self.consequents):
            # key = ','.join(sorted(left))
            # for par in self.params:
            #     key = lambda x : re.sub(r'%s\_\d' % par, par, x)

            key = frozenset(map(lambda x: re.sub(r'%s\_\d' % par, par, x), left))
            # key = frozenset(map(lambda x: re.sub(r'\d', par, x), left))

            rules_map[key][frozenset(left)].add(right)
        return rules_map

    def slct_rules_by_guards(self, rules_map, guards, par, save=True, load=False):
        if load and os.path.exists("{}/data/norm_rule_dict.pkl".format(self.name)) and os.path.exists(
                "{}/data/rules.pkl".format(self.name)):
            return joblib.load("{}/data/norm_rule_dict.pkl".format(self.name)), joblib.load(
                "{}/data/rules.pkl".format(self.name))

        par = par[0]
        norm_rule_dict = {key: rules for key, rules in rules_map.items() if set(key).issubset(guards)}

        rules = set()

        for ant_dict in norm_rule_dict.values():
            for ant, conse_set in ant_dict.items():
                for conse in conse_set:
                    line = "{} -> {}".format(' & '.join(sorted(ant)), conse)
                    search_para = re.search(r'%s\_\d' % par, line)
                    # search_para = re.search(r'\d', line)

                    cnt = 1
                    while search_para:
                        line = re.sub(search_para.group(), 'P%d' % cnt, line)
                        search_para = re.search(r'%s\_\d' % par, line)
                        # search_para = re.search(r'%s\_\d' % par, line)

                        cnt += 1

                    rules.add(line)
        print('select %d association rules' % len(rules))

        # fout = '%s/selected_by_guard.txt' % self.name
        # with open(fout, 'w') as f:
        #     for i, r in enumerate(rules, 1):
        #         f.write('rule_%d: %s\n' % (i, r))

        # save data
        # self.write_to_file(rules)

        if save:
            joblib.dump(norm_rule_dict, "{}/data/norm_rule_dict.pkl".format(self.name))
            joblib.dump(rules, "{}/data/rules.pkl".format(self.name))

        return norm_rule_dict, rules

    def write_to_file(self, rules):
        with open("{}/rules.txt".format(self.name), 'w') as f:
            f.writelines("\n".join(rules))

class SlctInv(object):
    def __init__(self, name, par, test_rules, home=False):
        self.name = name
        self.home = home
        self.murphi_dir = self.loc_murphi_dir()
        self.par = par
        self.test_rules = {'rule_%d' % i: rule for i, rule in enumerate(test_rules, 1)}

    def select_invariant(self, pattern=re.compile(r'P\d'), num_core=multiprocessing.cpu_count(), original_file=None):
        translate_dic = self.translate_test_inv(pattern=pattern)
        original_file = "{0}/{0}.m".format(self.name) if original_file is None else original_file

        n = len(self.test_rules)
        jobs = [(i * n // num_core, (i + 1) * n // num_core) for i in range(num_core)]

        print('ranges', jobs)
        spurious = []
        with multiprocessing.Pool(num_core) as p:
            spurious.extend(p.starmap(self.parallel,
                                      [(index_range, pid, translate_dic, original_file) for
                                       pid, index_range
                                       in enumerate(jobs, 1)]))

        # print(spurious)
        spurious_cnt = 0
        for key in spurious:
            for k in key:
                self.test_rules.pop(k)
                spurious_cnt += 1

        print(n, spurious_cnt, len(self.test_rules))
        assert n == spurious_cnt + len(self.test_rules)
        return spurious_cnt

    def loc_murphi_dir(self):
        if not os.path.exists('murphi_url.txt'): raise FileExistsError
        return open('murphi_url.txt').read().strip()

    def run_murphi(self, file, aux_para=''):
        file = file.split('.')[0]
        process1 = subprocess.Popen("{0}/src/mu {1}.m".format(self.murphi_dir, file), shell=True,
                                    stdout=subprocess.PIPE,
                                    stderr=subprocess.PIPE)

        (stdout, stderr) = process1.communicate()
        if not re.search(r'Code generated', stdout.decode('utf-8')):
            print(stderr.decode('utf-8'))
            raise ValueError

        command2 = "g++ -ggdb -o {0}.o {0}.cpp -I {1}/include -lm".format(file, self.murphi_dir)

        process2 = subprocess.Popen(command2, shell=True,
                                    stdout=subprocess.PIPE,
                                    stderr=subprocess.PIPE)
        process2.communicate()

        process = subprocess.Popen("{0}.o -k10000000 {1}".format(file, aux_para), shell=True,
                                   stdout=subprocess.PIPE,
                                   stderr=subprocess.PIPE)

        (stdoutdata, stderrdata) = process.communicate()

        pattern_counter = re.compile(r'Invariant\s"(\w+).*"\sfailed')
        counter_ex = re.findall(pattern_counter, stdoutdata.decode('utf-8'))
        print(counter_ex)

        os.remove('%s.cpp' % file)
        os.remove('%s.o' % file)

        return counter_ex[0] if len(counter_ex) else 0

    def translate_test_inv(self, pattern):
        # test_invs is empty
        if not self.test_rules: return []
        # print('testing %d rules' % len(self.test_rules))

        translate_dic = {}
        for key, rule in self.test_rules.items():
            translate_dic.update(
                {key: '\n\nInvariant \"%s\"\n' % key + self.to_murphi(rule, self.par, pattern, self.home)})
        return translate_dic

    def parallel(self, index_range, id, translate_dic, original_file):
        start, end = index_range
        counters = []
        new_file = "{}_{}.m".format(original_file.split('.')[0], id)
        copyfile(original_file, new_file)
        with open(new_file, 'a') as f:
            for rule_num in range(start + 1, end + 1):
                f.writelines(translate_dic['rule_%d' % rule_num])
        print(new_file)
        counter_ex = self.run_murphi(new_file)

        while counter_ex:
            counters.append(counter_ex)
            pattern = re.compile(r'Invariant \"%s\".*?;' % counter_ex, re.S)
            new_content = re.sub(pattern, '', open(new_file).read())

            with open(new_file, 'w') as fw:
                fw.writelines(new_content)
            counter_ex = self.run_murphi(new_file)

        os.remove("{}.m".format(new_file.split('.')[0]))
        # os.remove("{}.cpp".format(new_file.split('.')[0]))
        # os.remove("{}.o".format(new_file.split('.')[0]))

        return counters

    def to_murphi(self, rule, par, pattern, home=False):
        """
        translate an association rule('Chan2[__P1__].Cmd = Inv -> Cache[__P2__].Data = AuxData') into murphi code
        invariant "rule_1"
            forall __P1__: NODE do forall __P2__: NODE do
            __P1__ != __P2__ -> (Chan2[__P1__].Cmd = Inv -> Cache[__P2__].Data = AuxData)
        end end;

        :param rule: an association rule
        :param par: NODE
        :return: murphi code
        """

        paras = list(set(pattern.findall(rule)))
        definition = " ".join("forall {} : {} do".format(x, par[0]) for x in paras)

        pre= ""

        home_def = " & ".join("{} != Home".format(x) for x in paras) if home else ""

        if len(paras) == 2:
            pre += "{} != {}".format(paras[0], paras[1])

        if home and pre: pre += " & " +home_def
        if pre: pre += ' -> '
        end = "end " * len(paras)

        murphi_code = "{}\n  {}({})\n{};".format(definition, pre, rule, end)

        return murphi_code

    def check_usedF(self, pattern, num_core, original_file):
        spurious_cnt = self.select_invariant(pattern=pattern, num_core=num_core, original_file=original_file)
        if not spurious_cnt:
            print('usedF all passed!')
        else:
            print('usedF failed.')
            print(spurious_cnt)

    def prnt_inv(self):
        invs = set(v for k, v in self.test_rules.items())
        with open("{}/invs.txt".format(self.name), 'w') as f:
            for i, inv in enumerate(invs, 1):
                f.writelines("rule_%d: %s\n" % (i, inv))
        return invs

def check_file(name):
    """
    check whether the folder, files (murphi, atoms) exist.
    If txt/csv doesn't exist, then call Murphi to generate reachable set
    Mkdir 'data' folder
    :param name:
    :return:
    """

    prefix = '{0}/{0}'.format(name)
    if os.path.exists('%s.m' % prefix):
        # and (os.path.exists('%s.csv' % prefix) or os.path.exists('%s.txt' % prefix)) \
        # and os.path.exists('%s/atom.txt' % name):

        # Need collect reachable set
        if not os.path.exists('%s.txt' % prefix) and not os.path.exists('%s.csv' % prefix):
            print('calling Murphi to generate reachable set...')
            inv_slcter = SlctInv(name, [], set(), home=False)
            inv_slcter.run_murphi('{0}/{0}.m'.format(name), '-ta >{0}/{0}.txt'.format(name))
        if not os.path.exists('%s/data' % name):
            os.mkdir('%s/data' % name)
    else:
        raise FileNotFoundError(
            'There must be murphi, reachable set, and atomic predicates in the corresponding folder')

prefix_msg = '''
==========================================================================
Welcome to L-CMP

1. Please make sure you have installed CMurphi properly, and
   write CMurphi's location into murphi_url.txt.
        E.g. /home/usr/cmurphi5.4.9.1/
2. We provide several testing protocols including:
        MutualExclusion, Mesi, Meosi, German, and Flash.
3. If you have any question, please contact us at:
        caojl[at]ios[dot]ac[dot]cn
==========================================================================
'''

help_msg = '''
==========================================================================
Usage:

Options:
1) General: (default: -n 2)
	-h            help.
	-p            protocol name
	-n <n>        number of node used for verification
	              (protocols with only homogenerous nodes -- 2
	               protocols with a heterogenerous node   -- 3)
2) Learning process: (default: -f 2, -s -0, -c 1)
	-l            load the existing auxiliary invariants.
	              (if file "aux_invs.txt" in the correspondent folder)
	-f <n>        the size of frequent set
	-s <n>        the minimun support in association rule learning algorithm
	-c <n>        the minimun confidence in association rule learning algorithm
2) Other options: (default: -k 2)
	-k <n>        number of processor

==========================================================================
'''

end_msg = '''
==========================================================================
Thank you for using L-CMP

All generated files can be found in the folder named after input protocol name.
If you have any question, please send to caojl[at]ios[dot]ac[dot]cn.
==========================================================================
'''

if __name__ == "__main__":
    try:
        if not os.path.exists('./murphi_url.txt'):
            print('murphi_url.txt does not exists! Please create!')
            sys.exit(1)

        with open('./murphi_url.txt', 'r') as f:
            murphi_url = f.read().strip()

        if murphi_url == '':
            print('Empty murphi_url.txt, please check again.')
            exit(1)
        if not os.path.exists(murphi_url):
            print('Wrong murphi url, please check url in murphi_url.txt again.')
            exit(1)

        sys.stderr.write(prefix_msg)

        opts, args = getopt.getopt(sys.argv[1:], 'p:n:f:s:c:k:h:l',
                                   ['protocol=', 'node=', 'frequentset=', 'support=', 'confid=', 'kernel=', 'help',
                                    'load'])

        # opts = [('-p', 'german'), ('-n', '2')]

        protocol_name = ''
        NODE_NUM, set_n, min_support, min_config, core_num, LOAD = 2, 3, 0.0, 1.0, multiprocessing.cpu_count(), False
        for opt, arg in opts:
            if opt in ('-h', '--help'):
                sys.stdout.write(help_msg)
                sys.exit(0)
            elif opt in ('-l', '--load'):
                LOAD = True
            elif opt in ('-p', '--protocol'):
                protocol_name = arg
            elif opt in ('-n', '--node'):
                NODE_NUM = int(arg)
            elif opt in ('-f', '--frequentset'):
                set_n = int(arg)
            elif opt in ('-s', '--support'):
                min_support = float(arg)
            elif opt in ('-c', '--confid'):
                min_config = float(arg)
            elif opt in ('-k', '--kernel'):
                core_num = int(arg)
            else:
                print('Wrong input!\n')
                sys.stderr.write(help_msg)
                sys.exit(1)

        if not protocol_name:
            print('Please input protocol name!')
            sys.exit(1)
    except getopt.GetoptError:
        sys.stderr.write(help_msg)
        sys.exit()
    else:
        # -------------------- Config --------------------
        name = protocol_name  # 'german'
        NUM = NODE_NUM  # 2
        # -------------------- End Config --------------------

        check_file(name)

        # -------------------- Start --------------------
        start = time.time()

        # ----------------------------------------
        # anaylze murphi description
        murphi_analyser = fi.Protocol(name)
        params, guards = murphi_analyser.execute()

        murphi_analyser.set_paras('NODE', NUM)
        print('PARA = %d' % (NUM))

        if LOAD:
            finv = "%s/aux_invs.txt" % name
            ins_invs = list(map(lambda x: x.split(':   ')[1],
                                filter(lambda x: x, [line.strip() for line in open(finv, 'r').readlines()])))
        else:
            # ----------------------------------------
            # preprocessor
            replace_index = None if NUM == 2 else {'NODE_1': 'Home'}
            processor = DataProcess(name, replace_index=replace_index)  # {'NODE_1': 'Home'})
            dataset, itemMeaning, para_digit = processor.execute(load=False)
            global_vars = processor.select_global(itemMeaning)
            print('local', global_vars)

            # ----------------------------------------
            # learner & minimize association rules
            learner = RuleLearing(dataset, params, itemMeaning, name, global_vars=global_vars, freq_size=3,
                                  min_support=0.0,
                                  min_confidence=1.0, is_minimize=False)
            learner.execute(para_digit, save=True, load=False)

            # build a rule map to easily find association rules
            rules_map = learner.built_map()
            new_dict, useful_rules = learner.slct_rules_by_guards(rules_map, guards, params, save=True, load=True)

            # ----------------------------------------
            # select auxiliary invariant
            murphi_analyser.set_paras('NODE', NUM + 1)
            print('PARA = %d' % (NUM + 1))

            former, add = 0x77777777, 2
            while True:
                inv_slcter = SlctInv(name, params, useful_rules, home=False if NUM == 2 else True)
                inv_slcter.select_invariant(num_core=core_num)
                invs = inv_slcter.prnt_inv()

                cur = len(invs)
                if former == cur:
                    break
                else:
                    print('PARA = %d' % (NUM + add))
                    former = min(former, cur)
                    murphi_analyser.set_paras('NODE', NUM + add)
                    add += 1

            ins_invs = learner.instantiate(invs, paras=['i', 'j'])
            # print(ins_invs)

        print('\n--------------------\nPhase 1 finished!\n--------------------\n')

        # strengthen and abstract
        refiner = refine.Refiner(name, ins_invs)
        abs_file, usedF = refiner.refine(node_num=NUM)

        print('\nchecking usedF...')
        murphi_analyser.set_paras('NODE', NUM)
        print('PARA = %d' % NUM)
        inv_slcter = SlctInv(name, params, usedF, home=False if NUM == 2 else True)
        inv_slcter.check_usedF(pattern=re.compile(r'\b[ij]\b'), num_core=core_num, original_file=abs_file)

        print('\n--------------------\nPhase 2 finished!\n--------------------\n')

        print('Total running time: %.3f s.' % (time.time() - start))
        sys.stderr.write(prefix_msg)


from django.conf.urls import patterns, include, url
from vehicles.views import VehiclesList, VehicleCreate, VehicleView, VehicleUpdate, delete_vehicle
from django.contrib.auth.decorators import login_required, permission_required

urlpatterns = patterns('',
    #List view
    url(r'^$', VehiclesList.as_view(), name='vehicle_list'),
    url('^create/$', VehicleCreate.as_view(), name='vehicle_create'),
    url('^(?P<pk>\d+)/$', VehicleView.as_view(), name='vehicle_details'),
    url(r'^(?P<pk>\d+)/update/$', VehicleUpdate.as_view(), name='vehicle_update'),
    url(r'^(?P<vehicle_id>\d+)/delete/$', delete_vehicle, name='vehicle_delete'),
)


# 1) smoothing to remove noise from the image
# 2) homogeneous filter is the most simple filter each output pixel is the mean of its kernel neighbours
# 3)  in image processing a kernel, convolution matrix or mask is a small matrix , it is used to blurring,sharpening
# ,embossing,edge detection and more.

# 4) in 1 D signals images can be filtered with various low pass filters (LPF) high pass filters (HPF)
# 5) LPF- helps in removing noise from the imaage
# 6) HPF - helps in finding edges in the images
# 7) guassian filter is nothing but using different-weight-kernel, in both x and y direction
# 8) median filter is something that replaces each pixel value with the median of its neighbouring pixel
# this method is great when dealing with salt and pepper noise
# 9) bilateral filter-A bilateral filter is a non-linear, edge-preserving, and noise-reducing smoothing
# filter for images. It replaces the intensity of each pixel with a weighted average of intensity values
# from nearby pixels. (used when u have to preserve edges)
import cv2        # bgr format
import matplotlib.pyplot as plt   # rgb format
import numpy as np

#img=cv2.imread("opencv-logo.png")
img=cv2.imread("class.png")
#img=cv2.imread("g_blur.jpg")
#cv2.imshow("image",img)
#img=cv2.imread("saltnpepper.jpg")
#img=cv2.imread("lena.jpg")
img=cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
kernel=np.ones((5,5),np.float32)/25
dst=cv2.filter2D(img,-1,kernel)
blur=cv2.blur(img,(5,5))  #averaging
gblur=cv2.GaussianBlur(img,(5,5),0) # inner values have more weight and outer values will be lesser in matrix
median=cv2.medianBlur(img,3) # 3/ kernel size must always be odd and 1 will give original image
bilat=cv2.bilateralFilter(img,9,75,75) #remove noise and keep edges sharp
title=["OG","2D","blur","gblur","median","bilateralfilter"]
images=[img,dst,blur,gblur,median,bilat]
for i in range(len(images)):
    plt.subplot(2,3,i+1)
    plt.imshow(images[i],"gray")
    plt.title(title[i])
    plt.xticks([])
    plt.yticks([])

plt.show()
cv2.waitKey(0)
cv2.destroyAllWindows()


from pathlib import Path
import yaml
#import ruamel.yaml
import src.common.processing_vars as var
import os.path
#import ruamel.yaml as yaml
def write_database_file(self,d:dict, ignore_existing:bool=False):
    yml_path = 'snowflake/data/' + d['DATABASE_NAME_SANS_ENV'] + '/database.yml'

    data = self.create_parent_load_data(yml_path)

    #data['version']="2.1"
    data['DATA_RETENTION_TIME_IN_DAYS']=self.choose_value_string(data, 'DATA_RETENTION_TIME_IN_DAYS', d,'DATA_RETENTION_TIME_IN_DAYS' , var.EMPTY_STRING)
    #data['COMMENT']=db['COMMENT'] if (db['COMMENT'] is not None and db['COMMENT'] != '') else var.EMPTY_STRING
    #print('ddidididididididididididid')
    #print(data['COMMENT'])
    #print('ddidididididididididididid')
    data['COMMENT'] = self.choose_value_string(data, 'COMMENT', d,'COMMENT', var.EMPTY_STRING)
    data['OWNER']=self.choose_value_string(data, 'OWNER', d,'OWNER' , var.EMPTY_STRING)

    if 'TAGS' in d and d['TAGS'] != []:
        if 'TAGS' in data:
            data['TAGS'] = self.choose_list_objects(d['TAGS'], data['TAGS'])
        else:
            data['TAGS'] = d['TAGS']
    else:
        data['TAGS']=var.EMPTY_STRING

    if 'GRANTS' in d and d['GRANTS'] != []:
        if 'GRANTS' in data:
            data['GRANTS'] = self.choose_list_objects(d['GRANTS'], data['GRANTS'])
        else:
            data['GRANTS'] = d['GRANTS']
    else:
        data['GRANTS']=var.EMPTY_STRING

    #ryaml = ruamel.yaml.YAML(typ=['rt', 'string'])
    #yaml_string = ryaml.dump_to_string(data)
    yaml_string = yaml.safe_dump(data, sort_keys=False)
    #yaml_string_converted = self.replace_jinja_ref_string(yaml_string)
    #yaml_string_converted = yaml_string_converted.replace("'"+var.EMPTY_STRING+"'",'')
    #yaml_str = yaml.dump(data, default_flow_style=False,indent=4).replace(r"''", '') #ruamel version
    yaml_string_converted = self.convert_special_characters_back_in_file(yaml_string)
    db_file_exists = os.path.isfile(yml_path)
    if not(db_file_exists and ignore_existing):
        with open(yml_path, "w+") as f:
            f.write(yaml_string_converted)

    #with Path(yml_path).open("w", encoding="utf-8") as f:
    #    yaml.dump(data,f,default_style=None,default_flow_style=False, sort_keys=False)
    #    #f.write('#RENAME: #uncomment with new name to rename')


from matplotlib import pyplot as plt
from Point import Point

# Constructing cutoff of a polygon by segments using the Cirus-Beck algorithm

def init_points_for_polygon():
    points = []
    xs = [2, 4, 9, 12, 14, 15, 12, 6, 1]
    ys = [3, 1, 1, 3, 7, 12, 14, 13, 7]
    for i in range(len(xs)):
        x = Point(xs[i], ys[i])
        points.append(x)
    return points

def init_segments():
    return [(Point(4, 0), Point(14, 6)), (Point(12, 0), Point(16, 2)), (Point(4, 12), Point(16, 13)),
            (Point(14, 6), Point(14, 14)), (Point(1, 7), Point(4, 1)), (Point(6, -2), Point(0, 12)),
            (Point(11, 16), Point(0, 8)), (Point(12, 15), Point(3, -2)), (Point(10, 0), Point(0, 12.5))]

def print_points(points: list):
    for i in range(len(points)):
        print("i: ", i, ": ", points[i].x, ":", points[i].y)

def get_cross_point(p1: Point, p2: Point, q1: Point, q2: Point):
    if (p1.x == p2.x and p2.y == p1.y) or (q1.x == q2.x and q1.y == q2.y):
        print("Not lines")
        return

    if p1.x > p2.x:
        p1.x, p2.x = p2.x, p1.x
        p1.y, p2.y = p2.y, p1.y
    if q1.x > q2.x:
        q1.x, q2.x = q2.x, p1.x
        q1.y, q2.y = q2.y, p1.y

    k1 = 0
    k2 = 0

    if p1.x != p2.x and p2.y != p1.y:
        k1 = (p2.y - p1.y) / (p2.x - p1.x)
    if q1.x != q2.x and q2.y != q1.y:
        k2 = (q2.y - q1.y) / (q2.x - q1.x)

    if k2 == k1:
        print("k1 == k2: Lines are parallel or collinear")
        return

    b1 = p1.y - k1 * p1.x
    b2 = q1.y - k2 * q1.x

    if p1.x == p2.x:
        x = p1.x
    elif q1.x == q2.x:
        x = q1.x
    else:
        x = (b2 - b1) / (k1 - k2)

    y = k1 * x + b1

    return Point(x, y)

def get_current_parameter(segment: tuple, vertex1: Point, vertex2: Point):
    normal_vector = Point(vertex2.y - vertex1.y, -(vertex2.x - vertex1.x))
    segment_vertex_vector = Point(vertex1.x - segment[0].x, vertex1.y - segment[0].y)
    segment_vector = Point(segment[1].x - segment[0].x, segment[1].y - segment[0].y)
    return (segment_vertex_vector * normal_vector) / (segment_vector * normal_vector)

def determine_intersection_type(p1: Point, p2: Point, segment: tuple):
    normal_vector = Point(p2.y - p1.y, -(p2.x - p1.x))
    segment_vector = Point(segment[1].x - segment[0].x, segment[1].y - segment[0].y)
    if segment_vector * normal_vector > 0:
        return 1
    elif segment_vector * normal_vector < 0:
        return -1
    else:
        return 0  # no intersection

def cirus_beck(polygon_points: list, segment: tuple):
    t0_values = [0]
    t1_values = [1]
    n = len(polygon_points)

    for i in range(len(polygon_points)):
        intersection_type = determine_intersection_type(polygon_points[i], polygon_points[(i + 1) % n], segment)
        t = get_current_parameter(segment, polygon_points[i], polygon_points[(i + 1) % n])
        if intersection_type == -1:
            t0_values.append(t)
        elif intersection_type == 1:
            t1_values.append(t)
        else:
            continue

    t0 = max(t0_values)
    t1 = min(t1_values)

    print(t0, t1)

    if t0 <= t1:
        x1 = segment[0].x + (segment[1].x - segment[0].x) * t0
        x2 = segment[0].x + (segment[1].x - segment[0].x) * t1
        y1 = segment[0].y + (segment[1].y - segment[0].y) * t0
        y2 = segment[0].y + (segment[1].y - segment[0].y) * t1
        plt.plot([x1, x2], [y1, y2], color="red")

def draw_polygon(points: list, color):
    for i in range(len(points)):
        plt.plot([points[i].x, points[(i + 1) % len(points)].x], [points[i].y, points[(i + 1) % len(points)].y], color=color)

def draw_segments(segments: list, color):
    for i in range(len(segments)):
        plt.plot([segments[i][0].x, segments[i][1].x], [segments[i][0].y, segments[i][1].y], color=color)

def draw_point(point: Point):
    plt.scatter(point.x, point.y)

def init():
    polygon_points = init_points_for_polygon()
    draw_polygon(polygon_points, "blue")
    segments = init_segments()
    draw_segments(segments, "green")

    for i in range(len(segments)):
        cirus_beck(polygon_points, segments[i])

    plt.grid(True)
    plt.show()

init()


import multiprocessing
import sys
import cv2
import random
import numpy as np
import os
import mmap
import torchvision.transforms as transforms
from PIL import Image
import torch
import time
def random_crop(image, crop_height, crop_width):
    max_x = image.shape[1] - crop_width + 1
    max_y = image.shape[0] - crop_height + 1
    x = np.random.randint(0, max_x)
    y = np.random.randint(0, max_y)
    crop = image[y: y + crop_height, x: x + crop_width]
    return crop

# def pil_loader(path):
#     # open path as file to avoid ResourceWarning (https://github.com/python-pillow/Pillow/issues/835)
#     with open(path, 'rb') as f:
#         img = Image.open(f)
#         return img.convert('RGB')

def readImageWithMmap(path):
    fd =  os.open(path, os.O_RDONLY | os.O_DIRECT)
    mm = mmap.mmap(fd, 0, access=mmap.ACCESS_READ)
    os.close(fd)
    img = np.fromstring(mm.read(), dtype="uint8")

    return img

def transform(image):
    image = cv2.imdecode(image, cv2.IMREAD_COLOR)
    image = cv2.resize(image, (224, 224))
    image = random_crop(image,224,224)

    if random.random()<0.5:
        image = cv2.flip(image, 1)

    image = image / 255.0
    image = image - (0.485, 0.456, 0.406)
    image = image / (0.229, 0.224, 0.225)
    image = image.transpose((2, 0, 1))
    return image

NUM_WORKER = 3
print(NUM_WORKER)

# normalize = transforms.Normalize(mean=[0.485, 0.456, 0.406],
#                                 std=[0.229, 0.224, 0.225])
# transform = transforms.Compose([
#         transforms.RandomResizedCrop(224),
#         transforms.RandomHorizontalFlip(),
#         transforms.ToTensor(),
#         normalize,
#     ])

def get_metadata(metadata_path='/home/Adama/metadata'):
    with open("metadata", "r") as f:
        lines = f.readlines()
    records = []
    for line in lines:
        line = line.split()
        records.append((line[0] , int(line[1])))
    return records

def work_process(q_in):
    t=0
    # mytransform = transform
    start = time.time()
    while True:
        deq = q_in.get()
        if deq is None:
            print(time.time()-start)
            break
        path, label = deq
        if t==0:
            image = readImageWithMmap(path)
            t = 1
        # image = readImageWithMmap(path)
        image2 = transform(image)
        #process.process(path)
        #insert your process function

def main(records):
    if NUM_WORKER > 0:
        q_in = [ multiprocessing.Queue(1024) for i in range(NUM_WORKER) ]
        multiprocess = [ multiprocessing.Process(target=work_process, args=(q_in[i],)) for i in range(NUM_WORKER) ]

        for p in multiprocess:
            p.start()

        for i, record in enumerate(records):
            q_in[i % NUM_WORKER].put(record)

        for q in q_in:
            q.put(None)

        for p in multiprocess:
            p.join()

if __name__ == "__main__":

    #you should prepare your metadata
    #and give your metadata path
    records = get_metadata('/home/Adama/dataloading/metadata')
    records = records[0:10000]
    print(len(records))
    begin = time.time()
    main(records)
    end = time.time()
    print("speed:", len(records) / (end - begin))


import numpy as np
import scipy

np.set_printoptions(threshold=np.inf)

def main():
    lines = []
    max_x, max_y, max_z = 0, 0, 0
    with open("input.txt", "r") as f:
        for line in f:
            lines.append(line.strip("\n"))
            x, y, z = (int(x) for x in line.strip("\n").split(","))
            max_x, max_y, max_z = max(max_x, x), max(max_y, y), max(max_z, z)

    result = []

    # Part 1
    grid = np.array(
        [
            [[0 for _ in range(max_z + 1)] for _ in range(max_y + 1)]
            for _ in range(max_x + 1)
        ]
    )
    for line in lines:
        x, y, z = (int(a) for a in line.strip("\n").split(","))
        grid[x, y, z] = 1

    bin = scipy.ndimage.generate_binary_structure(3, 1)
    conn_grid = grid * scipy.ndimage.convolve(grid, bin, mode="constant")

    number_of_blocks = np.count_nonzero(conn_grid > 0)
    conn_grid = conn_grid[conn_grid > 0] - 1
    result.append(number_of_blocks * 6 - conn_grid.sum())

    # Part 2

    with open("output.txt", "w") as f:
        for i in result:
            f.write(f"{i}\n")

if __name__ == "__main__":
    main()


from django.conf.urls import url

from . import views

# url namespace
app_name = 'post'  # reverse하는 모든 namespace URL에 앱네임을 지정해줘야 한다, 단 render 함수는 제외
urlpatterns = [
    url(r'^$', views.post_list, name='post_list'),
    # /post/3/$, /post/35/$
    # 정규표현식에서 매칭된 그룹을 위치인수로 변환하는 방법
    # url(r'(^\d+)/$', views.post_detail),

    # 정규표현식에서 매칭된 그룹을 키워드인수로 변환하는 방법
    # 그룹의 가장 앞부분에 ?P<패턴이름>을 지정
    url(r'^(?P<post_pk>\d+)/$', views.post_detail, name='post_detail'),
    # 위쪽의 결과들과 매칭되지 않을 경우
    url(r'^create/$', views.post_create, name='post_create'),
    url(r'^(?P<post_pk>\d+)/modify/$', views.post_modify, name='post_modify'),

    url(r'^(?P<post_pk>\d+)/delete/$', views.post_delete, name='post_delete'),
    url(r'^(?P<post_pk>\d+)/like-toggle/$', views.post_like_toggle, name='post_like_toggle'),
    url(r'^(?P<post_pk>\d+)/comment/create/$', views.comment_create, name='comment_create'),
    url(r'^comment/(?P<comment_pk>\d+)/modify/$', views.comment_modify, name='comment_modify'),

    url(r'^comment/(?P<comment_pk>\d+)/delete/$', views.comment_delete, name='comment_delete'),

    url(r'^tag/(?P<tag_name>\w+)/$', views.hashtag_post_list, name='hashtag_post_list'),

    url(r'^youtube/search/$', views.youtube_create, name='youtube_create'),
    # url(r'^youtube/create/$', views.youtube_create, name='youtube_create'),
]

# 위쪽의 결과들과 매칭되지 않을 경우
# url(r'^.*/$', views.post_anyway, name='post_anyway'),


import pandas as pd
import sqlalchemy
import requests
import sqlite3

DATABASE_LOCATION = "sqlite:///users.sqlite"

def get_user(url="https://randomuser.me/api/"):
    response = requests.get(url)
    if response.status_code == 200:
        payload = response.json()
        result = payload.get("results", [])
        for user in result:
            return {
                "firstname": user["name"]["first"],
                "lastname": user["name"]["last"],
                "gender": user["gender"],
                "age": user["dob"]["age"],
                "country": user["location"]["country"],
                "city": user["location"]["city"],
                "email": user["email"],
            }
    else:
        print("connection fail.")

def load_data():
    user_info = get_user()
    users = pd.DataFrame(
        user_info,
        columns=["firstname", "lastname", "gender", "age", "country", "city", "email"],
        index=[0],
    )

    engine = sqlalchemy.create_engine(DATABASE_LOCATION)
    conn = sqlite3.connect("users.sqlite")
    cursor = conn.cursor()

    sql_query = """
    CREATE TABLE IF NOT EXISTS users(
        id INTEGER,
        firstname VARCHAR(100),
        lastname VARCHAR(100),
        gender VARCHAR(50),
        age INTEGER,
        country VARCHAR(100),
        city VARCHAR(100),
        email VARCHAR(200),
        CONSTRAINT primary_key_constraint PRIMARY KEY (id)
    )
    """

    cursor.execute(sql_query)
    try:
        users.to_sql("users", engine, index=False, if_exists="append")
    except:
        print("Data already exists in the database")

    conn.close()
    print("Close database successfully")

if __name__ == "__main__":
    load_data()


import math

def find_distance(x1, y1, x2, y2):
    distance = (((x2 - x1) ** 2 + (y2 - y1) ** 2) ** 0.5)
    return distance

x_one = float(input())
y_one = float(input())
x_two = float(input())
y_two = float(input())

x1_y1_distance = find_distance(x_one, y_one, 0, 0)
x2_y2_distance = find_distance(x_two, y_two, 0, 0)
if x1_y1_distance <= x2_y2_distance:
    print(f"({math.floor(x_one)}, {math.floor(y_one)})")
else:
    print(f"({math.floor(x_two)}, {math.floor(y_two)})")


# Raspberry_Pi
import wave     #wavファイルを扱うためのライブラリ
import pyaudio
# import webapi

WAVE_OUTPUT_FILENAME = "sample.wav" #音声を保存するファイル名
iDeviceIndex = 0 #録音デバイスのインデックス番号

def MakeWavFile(FileName = "sample.wav", Record_Seconds = 60):

	#生音声取得時の設定
	CHUNK = 1024  #1024個のデータをfsというサンプル周波数で取ってきた。
	FORMAT = pyaudio.paInt16
	CHANNELS = 1 #モノラル
	RATE = 44100 #サンプルレート（録音の音質）

	p = pyaudio.PyAudio()
	print(p)
	stream = p.open(format = FORMAT, channels = CHANNELS, rate = RATE, input = True, input_device_index = iDeviceIndex, frames_per_buffer = CHUNK)

	#レコード開始
	print('Now Recording...')
	all = []
	for i in range(0, int(RATE / CHUNK * Record_Seconds)):
	    data = stream.read(CHUNK) #音声を読み取って、
	    all.append(data) #データを追加

	#レコード終了
	print('Now Recording...')

	stream.close()
	p.terminate()

	#保存
	wavFile = wave.open(FileName, 'wb')
	wavFile.setnchannels(CHANNELS)
	wavFile.setsampwidth(p.get_sample_size(FORMAT))
	wavFile.setframerate(RATE)
	wavFile.writeframes(b"".join(all)) #Python3用
	wavFile.close()

if __name__ == "__main__":
#WAVファイル作成, 引数は（ファイル名, 録音する秒数）
	MakeWavFile("sample.wav", Record_Seconds = 60)
#webapi.changedata(wavFile)


from typing import Text
import random
import pygame
from pygame import *
import cards
import the_AI
import cards
import wave_generatore
import os
import sound
import textures
import triggerKeyboard
import ClientLeaderBoards

pygame.font.init()
font = pygame.font.SysFont(None, 24)

tutorial = False

class UI:
    x=0
    y=0
    w=0
    h=0
    func= ""
    TAG = ""
    enabled=False
    Text = ""
    def __init__(self,x,y,w,h,func,TAG,Text):
        self.x=x
        self.y=y
        self.w=w
        self.h=h
        self.func=func
        self.TAG=TAG
        self.Text=Text
    def Run(self):
        globals()[self.func]()
    def CRun(self):
        pass
    def Draw(self,background):
        pygame.draw.rect(background,Color(100,100,100),((self.x,self.y),(self.w,self.h)))
        pygame.draw.rect(background,Color(255,212,66),((self.x+2,self.y+2),(self.w-4,self.h-4)))
        img = font.render(str(self.Text), True, pygame.Color(255,255,255));img_sqr = img.get_rect();img_sqr.center = (self.x+self.w/2, self.y+self.h/2)
        background.blit(img, img_sqr)
        return background

class UIT(UI):
    def __init__(self,x,y,w,h,func,TAG,Text):
        self.x=x
        self.y=y
        self.w=w
        self.h=h
        self.func=func
        self.TAG=TAG
        self.Text=Text
    def Run(self):
        #no ! ?
        if(globals()[self.func]):#what is this.
            globals()[self.func] = False
        else:
            globals()[self.func] = True
    def CRun(self):
        pass
    def Draw(self,background):
        pygame.draw.rect(background,Color(100,100,100),((self.x,self.y),(self.w,self.h)))
        if(globals()[self.func]):
            pygame.draw.rect(background,Color(0,255,0),((self.x+2,self.y+2),(self.w-4,self.h-4)))
        else:
            pygame.draw.rect(background,Color(255,0,0),((self.x+2,self.y+2),(self.w-4,self.h-4)))
        img = font.render(str(self.Text), True, pygame.Color(255,255,255));img_sqr = img.get_rect();img_sqr.center = (self.x+self.w/2, self.y+self.h/2)
        background.blit(img, img_sqr)
        return background

class UIS(UI):
    def __init__(self,x,y,w,h,func,TAG,Text):
        self.x=x
        self.y=y
        self.w=w
        self.h=h
        self.func=func
        self.TAG=TAG
        self.Text=Text
    def Run(self):
        pass
    def CRun(self):
        mousePos = pygame.mouse.get_pos()
        globals()[self.func]=(mousePos[0]-self.x)/self.w
    def Draw(self,background):
        pygame.draw.rect(background,Color(100,100,100),((self.x,self.y),(self.w,self.h)))
        pygame.draw.rect(background,Color(255,212,66),((self.x+2,self.y+2),(globals()[self.func]*(self.w-4),self.h-4)))
        img = font.render(str(self.Text), True, pygame.Color(255,255,255));img_sqr = img.get_rect();img_sqr.center = (self.x+self.w/2, self.y+self.h/2)
        background.blit(img, img_sqr)
        return background

def MENUINIT():
    TurnTagOn("Start_Menu")

WIN = pygame.display.set_mode((900,600))

menu = [
UI(500,400,100,50,"Menu_Go_TO_menu","Start_Menu","Start"),

UI(390,175,110,50,"Menu_Start_Game","Main_Menu","Game"),
UIT(390,225,110,50,"Overexdednd_enabled","Main_Menu","Overexdend"),#it just works!
UI(390,275,110,50,"Menu_Go_options","Main_Menu","Options"),
UI(390,325,110,50,"Menu_Go_Deck_Building","Main_Menu","Deck"),
UI(390,375,110,50,"Lead_Boarding","Main_Menu","Leaderboard"),
UI(390,425,110,50,"Leave","Main_Menu","Exit"),

UI(795,5,100,50,"Menu_Go_Back","Deck","Back"),

UI(10,10,100,50,"Menu_Go_Back","LeadBoarding","Back"),

UI(400,250,100,50,"Menu_Go_Back","Lose_Menu","Back"),
UI(400,300,100,50,"","Lose_Menu","you suck"),

UI(400,225,100,50,"Menu_Go_Back","Options_Menu","Back"),
UIT(400,275,100,50,"Sound_Play","Options_Menu","Sound"),#it just works!
UIS(350,325,200,50,"Sound_Effects","Options_Menu",""),

UI(400,225,100,50,"Menu_UnPause","Main_Pause","Back"),
UI(400,275,100,50,"Menu_Go_options","Main_Pause","Options"),
UI(400,325,100,50,"Menu_Go_TO_menu","Main_Pause","Main Menu"),

UI(325,200,250,50,'AdeusMaedoLory','Parabens Mãe do Lory', 'Parabens Mãe do Lory!')]

Sound_Effects = 0.5
Sound_Play = True

def restart():
    cards.cards=[]
    cards.new_card(3)
    the_AI.Enemy_Array=[]
    the_AI.Turret_Array=[]
    the_AI.PROJ_Array=[]
    the_AI.Base_Healt=300
    wave_generatore.EnabledEnemies.clear()
    wave_generatore.EnabledEnemies_Dificulty.clear()
    wave_generatore.Enemies_in_Wave.clear()
    cards.TurretSel=None
    global Restart_map
    Restart_map=True

def Menu_Start_Game():
    global gaming
    gaming=True
    restart()
    TurnOff()

loop=True
def Leave():
    global loop
    loop = False

def Menu_Go_Back():
    global DeckBuildTime
    DeckBuildTime=False
    global Leaderboarding
    Leaderboarding=False
    TurnOff()
    if(menuPause):
        TurnTagOn("Main_Pause")
    else:
        TurnTagOn("Main_Menu")

def Start_Menu():
    TurnTagOn("Start_Menu")

def Menu_Go_options():
    TurnOff()
    TurnTagOn("Options_Menu")

def Menu_Go_TO_menu():
    global gaming
    global menuPause
    gaming=False
    menuPause=False
    TurnOff()
    TurnTagOn("Main_Menu")

def Menu_Pause():
    TurnOff()
    TurnTagOn("Main_Pause")

def Menu_UnPause():
    global menuPause
    menuPause=False
    TurnOff()

do=False
def Menu_Go_Deck_Building():
    global DeckBuildTime
    global do
    DeckBuildTime=True
    do=True
    TurnOff()
    TurnTagOn("Deck")

Leaderboarding = False
Ldo = False
def Lead_Boarding():
    global Leaderboarding
    global Ldo
    ClientLeaderBoards.tryMore = True
    Leaderboarding=True
    Ldo=True
    TurnOff()
    TurnTagOn("LeadBoarding")

def ParabensMaedoLory():
    global menuPause
    menuPause = True
    TurnOff()
    TurnTagOn('Parabens Mãe do Lory')

def AdeusMaedoLory():
    global menuPause
    menuPause = False
    TurnOff()

def DIE():
    global gaming
    gaming=False
    sound.soundPlay = False
    TurnTagOn("Lose_Menu")

def TurnTagOn(TAG):
    for Curr in menu:
        if(Curr.TAG==TAG):
            Curr.enabled=True

def TurnTagOff(TAG):
    for Curr in menu:
        if(Curr.TAG==TAG):
            Curr.enabled=False

def TurnOff():
    for Curr in menu:
        Curr.enabled=False

PmouseACT = False
UNchank = False

Overexdednd_enabled=False
Restart_map=False
DeckBuildTime=False

fixthis = pygame.image.load(os.path.join("Miscs", "fixthis.png"))
fixthis = pygame.transform.scale(fixthis,(900,600))

name = ""

def MENUDRAW(background):
    global PmouseACT
    global DeckBuildTime

    mousePos = pygame.mouse.get_pos()
    mouseAct = pygame.mouse.get_pressed()

    global menuPause
    if(not menuPause):
        for Curr in menu:
            if(Curr.TAG=="Start_Menu" and Curr.enabled):
                background.blit(textures.Start_Menu_background,(0,0))
                break
            elif(Curr.TAG=="Deck" and Curr.enabled):
                background.blit(textures.Deck_Builder_background,(0,0))
                break
            elif (Curr.TAG=="Main_Menu" and Curr.enabled):
                pygame.mixer.stop()
                background.blit(textures.Main_Menu_background,(0,0))
                img = font.render(str(name), True, pygame.Color(255,255,255))
                background.blit(img, (5,5))
                break
            elif (Curr.TAG=="Options_Menu" and Curr.enabled):
                background.blit(textures.Main_Menu_background,(0,0))
                break
            elif (Curr.TAG=="Lose_Menu" and Curr.enabled):
                background.blit(textures.Main_Menu_background,(0,0))
                break
            elif (Curr.TAG=="LeadBoarding" and Curr.enabled):
                pygame.mixer.stop()
                background.blit(textures.Main_Menu_background,(0,0))
                break

    else:
        #no fuking idea of making TRASPARENCY ON THIS whiout imgages
        #background.fill((250, 250, 250,100))
        background.blit(fixthis,(0,0))

    global UNchank

    for Curr in menu:
        if(Curr.enabled):
            background=Curr.Draw(background)
            if(mouseAct[0]==True and not UNchank):
                if(mousePos[0]>=Curr.x and mousePos[0]<=Curr.x+Curr.w and mousePos[1]>=Curr.y and mousePos[1]<=Curr.y+Curr.h):
                    if(PmouseACT==False and Curr.func!=""):
                        Curr.Run()
                        UNchank=True
                    Curr.CRun()

    UNchank=False

    WIN.blit(background, (0, 0))
    PmouseACT=mouseAct[0]

    sound.soundMultiplier=Sound_Effects
    sound.soundPlay=Sound_Play

    if triggerKeyboard.input_enable:
        background.fill([0,0,0])
        triggerKeyboard.sqr(0,200,900,50,"Name:",background,(0,0,0))
        triggerKeyboard.sqr(0,250,900,100,triggerKeyboard.ult,background,(255,212,66))
        triggerKeyboard.sqr(0,350,900,50,"Press Enter to continue",background,(0,0,0))

    return background

#globals()["myfunction"]()
#YES!

gaming = False
menuPause = False


# -*- coding: utf-8 -*-

# C - Takahashi's Information

"""
行または列同士の引き算をすると同じ値が 3 つ並ぶはずである。
(1 行目) - (2 行目) で a_1 - a_2 が 3 つ並ぶ。
"""

class Answer:
    yes = 'Yes'
    no = 'No'

def main():
    c = [list(map(int, input().strip().split())) for _ in range(3)]

    answer = Answer.yes
    for i in range(2):
        row_diff = [c[i][j] - c[i + 1][j] for j in range(3)]
        if min(row_diff) != max(row_diff):
            answer = Answer.no
            break
    if answer == Answer.yes:
        for j in range(2):
            row_diff = [c[i][j] - c[i][j + 1] for i in range(3)]
            if min(row_diff) != max(row_diff):
                answer = Answer.no
                break

    print(answer)

if __name__ == '__main__':
    main()


import sys
import socket
import threading
import argparse

MAIN_PORTS = list(range(1, 1024))

def port_scan(host, port, protocol):
    s = socket.socket(socket.AF_INET, protocol)
    s.settimeout(10)
    if s.connect_ex((host, int(port))) == 0:
        print(f"Port {port}/{protocol} open")

def multi_process(host, port_scan, port, protocol):
    t = threading.Thread(target=port_scan, args=(host, str(port), protocol))
    t.start()

def write_results_to_file(results, filename):
    with open(filename, "w") as f:
        for result in results:
            f.write(result + "\n")

def main():
    parser = argparse.ArgumentParser()
    group = parser.add_mutually_exclusive_group()
    group.add_argument(
        "-m",
        "--mainports",
        help="Perform a Scan on the 1000 main TCP ports",
        action="store_true",
    )
    group.add_argument(
        "-p", "--ports", help="Specify ports for scan (separated by comma or hyphen)"
    )
    parser.add_argument(
        "-r", "--range", help="Specify a range of ports to scan (e.g. 1-1024)"
    )
    parser.add_argument(
        "-o", "--output", help="Specify a file to output the results to"
    )
    parser.add_argument("ip", help="IP or domain for scanning")
    args = parser.parse_args()

    try:
        host = socket.gethostbyname(args.ip)
    except socket.gaierror:
        print("Invalid host, try again")
        sys.exit(1)

    def parse_ports(args):
        if "-" in args:
            start, end = [int(i) for i in args.split("-")]
            ports = list(range(start, min(end + 1, 65536)))
        else:
            ports = [int(p) for p in args.split(",")]
            ports = [p if p <= 65535 else 65535 for p in ports]
        protocols = [socket.SOCK_STREAM] * len(ports)
        return ports, protocols

    def parse_range(args):
        start, end = args.split("-")
        ports = range(int(start), min(int(end) + 1, 65536))
        protocols = [socket.SOCK_STREAM] * len(ports)
        return ports, protocols

    def parse_mainports(args):
        ports = MAIN_PORTS
        protocols = [socket.SOCK_STREAM] * len(ports)
        return ports, protocols

    def parse_args(args):
        parse_functions = {
            "ports": parse_ports,
            "mainports": parse_mainports,
            "range": parse_range,
        }

        for arg, func in parse_functions.items():
            if getattr(args, arg):
                return func(getattr(args, arg))

        print("Args error")
        sys.exit(1)

    ports, protocols = parse_args(args)

    results = []
    for i, port in enumerate(ports):
        protocol = protocols[i]
        multi_process(host, port_scan, port, protocol)
        results.append(f"Port {port}/{protocol} closed")

    if args.output:
        write_results_to_file(results, args.output)

    sys.exit(0)

if __name__ == "__main__":
    main()


from django.db.models import fields
from rest_framework import serializers
from products.models import Products
from rest_framework_simplejwt.tokens import AccessToken, RefreshToken, TokenError

class ProductsSerializer(serializers.ModelSerializer):
    class Meta:
        model = Products
        fields = [
            "id",
            "name",
            "price",
            "description",
            "image",
        ]

# class RefreshTokenSerializer(serializers.Serializer):
#     refresh = serializers.CharField()
#     # access = serializers.CharField()

#     default_error_messages = {
#         'bad_token': _('Token is invalid or expired')
#     }

#     def validate(self, attrs):
#         print(attrs)
#         self.refresh_token = attrs['refresh']
#         # self.access_token = attrs['access']
#         return attrs

#     def save(self, **kwargs):
#         try:
#             # AccessToken(self.access_token).blacklist()
#             RefreshToken(self.refresh_token).blacklist()
#         except TokenError:
#             self.fail('bad_token')


class Solution:
    def minSubArrayLen(self, target: int, nums: List[int]) -> int:
        ans = float('inf')
        left = 0
        summation = 0

        for right in range(len(nums)):
            summation += nums[right]

            if summation >= target:
                while summation >= target:
                    summation -= nums[left]
                    ans = min(ans, right+1 - left)
                    left += 1

        if ans != float('inf'):
            return ans
        else:
            return 0


# Functions that helps in scrapping
# Remove Character from the text
def Remove_Character(Text, characters):
    if Text == None:
        return ''
    else:
        val = Text.get_text(separator=' ').rstrip().split()
        val = ' '.join(val)
        for c in characters:
            val = ''.join(val.split(c))
        return val
# Get the position value
def Get_Position_Value(Text_Value, value_address):
    if Text_Value == None:
        return ''
    else:
        val = Text_Value.get_text(separator=' ').rstrip().split()
        if len(val) == 0 :
            return "Null"
        elif len(val) <=  value_address:
            return "Null"
        else:
            return val[value_address]

# Join the array with given tag
def Join_Value_With(value, join_value):
    if value == None:
        return ''
    else:
        val = value.get_text(separator=' ').rstrip().split()
        val = join_value.join(val)
        return val

# To Reamove Unusal Spaces
def Remove_Unusal_Spaces(value):
    if value == None:
        return ''
    else:
        val = value.get_text(separator=' ').rstrip().split()
        val = ' '.join(val)
        return val

# Make the attributes naming
def Name_Attribute(attribute):
    if attribute == None:
        return ''
    else:
        # remove the unusual spaces and convert the sentence into array
        attr = attribute.get_text(separator=' ').rstrip().split()
        attr = [x.capitalize() for x in attr] # capitalize the first letter of the word
        attr = '_'.join(attr) # Join each word with "_"
        return(attr)

# Generate url
def generate_url(fixed_url, text , join_symbol):
    lower_text = text.lower().split()
    joined_text = join_symbol.join(lower_text)
    url = fixed_url + str(joined_text)
    return url


#  Given an array, rotate the array to the right by k steps, where k is non-negative.

class Solution(object):
    def rotate(self, nums, k):
        """
        :type nums: List[int]
        :type k: int
        :rtype: None Do not return anything, modify nums in-place instead.
        """
        length = len(nums)
        indexes_from_end = k % length
        if length > 1 and k > 0:
            nums[:] = nums[-indexes_from_end:] + nums[: -indexes_from_end]

if __name__ == '__main__':
    solution = Solution()
    print(solution.rotate([1, 2, 3, 4, 5, 6, 7], 3))  # should return [5,6,7,1,2,3,4]
    print(solution.rotate([-1, -100, 3, 99], 2))      # should return [3,99,-1,-100]


# Scrapy settings for tutorial project
#
# For simplicity, this file contains only the most important settings by
# default. All the other settings are documented here:
#
#     http://doc.scrapy.org/en/latest/topics/settings.html
#

BOT_NAME = 'tbcrawler'

SPIDER_MODULES = ['tbcrawler.spiders']
NEWSPIDER_MODULE = 'tbcrawler.spiders'

# Crawl responsibly by identifying yourself (and your website) on the user-agent
#USER_AGENT = 'tutorial (+http://www.yourdomain.com)'
ITEM_PIPELINES = [
    'tbcrawler.pipelines.TiebaPipeline',
]


# Definition for a point.
# class Point(object):
#     def __init__(self, a=0, b=0):
#         self.x = a
#         self.y = b

class Solution(object):
    def maxPoints(self, points):
        """
        :type points: List[Point]
        :rtype: int
        """
        if points is None or len(points) == 0:
            return 0
        dup = {}
        for point in points:
            dup[(point.x, point.y)] = dup.get((point.x, point.y), 0) + 1
        P = dup.keys()
        if len(P) == 1:
            return dup[P[0]]
        result = 0
        for i in xrange(len(P)-1):
            slopes = {}
            for j in xrange(i+1, len(P)):
                dx = P[i][0] - P[j][0]
                dy = P[i][1] - P[j][1]
                if dx == 0:
                    slope = '#'
                elif dy == 0:
                    slope = 0
                else:
                    slope = float(dy)/dx
                slopes[slope] = slopes.get(slope, 0) + dup[P[j]]
            result = max(result, dup[P[i]]+max(slopes.values()))
        return result


import logging
import sys

# BUG FIX: https://github.com/tensorflow/tensorflow/issues/26691
try:
    # Capirca uses Google's abseil-py library, which uses a Google-specific
    # wrapper for logging. That wrapper will write a warning to sys.stderr if
    # the Google command-line flags library has not been initialized.
    # https://github.com/abseil/abseil-py/blob/pypi-v0.7.1/absl/logging/__init__.py#L819-L825
    # This is not right behavior for Python code that is invoked outside of a
    # Google-authored main program. Use knowledge of abseil-py to disable that
    # warning; ignore and continue if something goes wrong.
    import absl.logging

    # https://github.com/abseil/abseil-py/issues/99
    logging.root.removeHandler(absl.logging._absl_handler)
    # https://github.com/abseil/abseil-py/issues/102
    absl.logging._warn_preinit_stderr = False
except Exception:
    pass

# handler for logging to StdOut
STDOUT_HANDLER = \
    logging.StreamHandler(sys.stdout)

STDOUT_HANDLER.setFormatter(
    logging.Formatter(
        fmt='%(asctime)s   %(levelname)s   %(name)s:   %(message)s\n',
        datefmt='%Y-%m-%d %H:%M'))

# utility class to flush logging stream upon each write
# http://stackoverflow.com/questions/29772158/make-ipython-notebook-print-in-real-time
class _FlushFile:
    def __init__(self, f):
        self.f = f

    def __getattr__(self, item):
        return self.f.__getattribute__(item)

    def flush(self):
        self.f.flush()

    def write(self, x):
        self.f.write(x)
        self.flush()

# enable live printing
def enable_live_print():
    sys.stdout = _FlushFile(sys.stdout)
    print('Live Printing Enabled')


from drf_spectacular.utils import extend_schema, extend_schema_view
from rest_framework import status, viewsets
from rest_framework.mixins import DestroyModelMixin
from rest_framework.permissions import BasePermission, IsAuthenticated
from rest_framework.response import Response
from rest_framework.views import APIView

from my_apps.shop.api_v1.permissions import AdminPermission
from my_apps.shop.api_v1.serializers import BannerSerializer
from my_apps.shop.models import Banner, Product

class MyDestroyModelMixin(DestroyModelMixin):
    """Add additional info in response when instance deleted"""

    def destroy(self, request, *args, **kwargs):
        instance = self.get_object()
        self.perform_destroy(instance)
        data = {"detail": "Deleted", "code": "deleted"}
        return Response(status=status.HTTP_204_NO_CONTENT, data=data)

@extend_schema(tags=["Admin user"])
class TestAdmin(APIView):
    """Just endpoint for test admin permissions"""

    permission_classes = [IsAuthenticated, AdminPermission]

    def get(self, request):
        return Response({"detail": "Test_OK", "code": "Test permission OK"})

@extend_schema(tags=["Admin user"])
@extend_schema_view(
    list=extend_schema(
        summary="Get list banners",
        request=BannerSerializer,
    ),
    update=extend_schema(summary="update banner", request=BannerSerializer),
    create=extend_schema(
        summary="Create new banner",
        request=BannerSerializer,
    ),
)
class BannerViewSet(viewsets.ModelViewSet, MyDestroyModelMixin):
    """API endpoint that allows made CRUD operations with Banner."""

    pagination_class = None
    queryset = Banner.objects.all()
    serializer_class = BannerSerializer
    permission_classes = [IsAuthenticated, AdminPermission]


#!/usr/bin/python3
""" rectangle """

from models.base import Base

class Rectangle(Base):
    """ rectangle """
    def __init__(self, width, height, x=0, y=0, id=None):
        if type(width) is not int:
            raise TypeError("width must be an integer")
        if type(height) is not int:
            raise TypeError("height must be an integer")
        if width <= 0:
            raise ValueError("width must be > 0")
        if height <= 0:
            raise ValueError("height must be > 0")
        if type(x) is not int:
            raise TypeError("x must be an integer")
        if type(y) is not int:
            raise TypeError("y must be an integer")
        if x < 0:
            raise ValueError("x must be >= 0")
        if y < 0:
            raise ValueError("y must be >= 0")

        self.__width = width
        self.__height = height
        self.__x = x
        self.__y = y
        super().__init__(id)

    @property
    def width(self):
        """ get width """
        return self.__width

    @width.setter
    def width(self, width):
        """ set width """
        if type(width) is not int:
            raise TypeError("width must be an integer")
        if width <= 0:
            raise ValueError("width must be > 0")
        self.__width = width

    @property
    def height(self):
        """ get height """
        return self.__height

    @height.setter
    def height(self, height):
        """ set height """
        if type(height) is not int:
            raise TypeError("height must be an integer")
        if height <= 0:
            raise ValueError("height must be > 0")
        self.__height = height

    @property
    def x(self):
        """ get x """
        return self.__x

    @x.setter
    def x(self, x):
        """ set x """
        if type(x) is not int:
            raise TypeError("x must be an integer")
        if x < 0:
            raise ValueError("x must be >= 0")
        self.__x = x

    @property
    def y(self):
        """ get y """
        return self.__y

    @y.setter
    def y(self, y):
        """ set y """
        if type(y) is not int:
            raise TypeError("y must be an integer")
        if y < 0:
            raise ValueError("y must be >= 0")
        self.__y = y

    def area(self):
        """ get area """
        return self.__height * self.__width

    def display(self):
        """ display """
        for x in range(self.__y):
            print()
        for i in range(self.__height):
            print(" " * self.__x + "#" * self.__width, end="\n")

    def __str__(self):
        """ str """
        return ("[Rectangle] ({}) {}/{} - {}/{}".format(self.id, self.__x,
                self.__y, self.__width, self.__height))

    def update(self, *args, **kwargs):
        """ update of the arguments """
        if args is None or len(args) == 0:
            if 'id' in kwargs:
                self.id = kwargs['id']
            if 'width' in kwargs:
                self.__width = kwargs['width']
            if 'height' in kwargs:
                self.__height = kwargs['height']
            if 'x' in kwargs:
                self.__x = kwargs['x']
            if 'y' in kwargs:
                self.__y = kwargs['y']
        else:
            if len(args) < 1:
                return
            self.id = args[0]
            if len(args) < 2:
                return
            self.__width = args[1]
            if len(args) < 3:
                return
            self.__height = args[2]
            if len(args) < 4:
                return
            self.__x = args[3]
            if len(args) < 5:
                return
            self.__y = args[4]

    def to_dictionary(self):
        dct = {}
        dct.setdefault('id', self.id)
        dct.setdefault('width', self.__width)
        dct.setdefault('height', self.__height)
        dct.setdefault('x', self.__x)
        dct.setdefault('y', self.__y)
        return dct


#! python3
# This program encrypts every .pdf file in a folder and
# tries to access all the pdfs in folder to make sure they
# were encrypted

import PyPDF2, os, sys
try:
    path, key = sys.argv[1:]
    os.chdir(path)

    # Searching for PDFs:
    for filename in os.listdir('.'):
        if filename.endswith('.pdf'):
            try:
                # Creating PDF reader and writer object:
                print('Encrypting %s...' % (filename))
                pdfFile = open(filename, 'rb')
                pdfReader = PyPDF2.PdfFileReader(pdfFile)
                encrypted = PyPDF2.PdfFileWriter()

                # Copying content:
                for pageNum in range(pdfReader.numPages):
                    page = pdfReader.getPage(pageNum)
                    encrypted.addPage(page)

                # Encrypting:
                encrypted.encrypt(key)

                # Creating new PDF:
                encryptedFile = open(filename[:-4] + '_encrypted.pdf', 'wb')
                encrypted.write(encryptedFile)
                encryptedFile.close()
                pdfFile.close()
                print('    Done.')

                # Deleting unencrypted pdf:
                os.unlink(filename)

            except PyPDF2.utils.PdfReadError:
                print('    %s is already encrypted.' % (filename))

    # Verifying encryption:
    print('Verifying encryption...')
    allEncrypted = True
    for filename in os.listdir('.'):
        if filename.endswith('.pdf'):
            pdfFile = open(filename, 'rb')
            pdfReader = PyPDF2.PdfFileReader(pdfFile)
            if not pdfReader.isEncrypted:
                print('WARNING: %s is not encrypted.' % filename)
                allEncrypted = False
    if allEncrypted:
        print('    All files are encrypted. Safe and sound.')

except (ValueError, IndexError, FileNotFoundError):
    print('Something went wrong. How to use:')
    print('    The first argument is the path to the folder containing the .pdf files;')
    print('    The second argument is the key which will encrypt all folders.')


from hexrdgui.constants import OverlayType

from . import compatibility
from .laue_overlay import LaueOverlay
from .overlay import Overlay
from .powder_overlay import PowderOverlay
from .rotation_series_overlay import RotationSeriesOverlay

type_dict = {
    OverlayType.laue: LaueOverlay,
    OverlayType.powder: PowderOverlay,
    OverlayType.rotation_series: RotationSeriesOverlay,
}

def create_overlay(material_name, type, **kwargs):
    if type not in type_dict:
        raise Exception(f'Unknown overlay type: {type}')

    return type_dict[type](material_name, **kwargs)

def to_dict(overlay):
    # Route the call through the compatibilty module to take care
    # of versioning.
    return compatibility.to_dict(overlay)

def from_dict(d):
    type = OverlayType(d.pop('type'))
    if type not in type_dict:
        raise Exception(f'Unknown overlay type: {type}')

    cls = type_dict[type]
    # Route the call through the compatibilty module to take care
    # of versioning.
    return compatibility.from_dict(cls, d)

def update_overlay_data(instr, display_mode):
    from hexrdgui.hexrd_config import HexrdConfig

    def flag_update(overlay):
        overlay.instrument = instr
        overlay.display_mode = display_mode
        overlay.update_needed = True

    # First, if there is a polar tth distortion overlay, make sure
    # that is flagged for updating.
    # Even if this isn't visible, we must update it if it is using to
    # compute the distortion.
    overlay = HexrdConfig().polar_tth_distortion_overlay
    if overlay:
        flag_update(overlay)

    if not HexrdConfig().show_overlays:
        # Nothing to do
        return

    for overlay in HexrdConfig().overlays:
        if not overlay.visible:
            # Skip over invisible overlays
            continue

        flag_update(overlay)

__all__ = [
    'LaueOverlay',
    'Overlay',
    'PowderOverlay',
    'RotationSeriesOverlay',
]


import math
import numpy
import json
import io

class Point:
    '''
    A point on the track with its distance to the center.
    '''

    def __init__(self, pos, dist):
        self.pos = pos
        self.dist = dist

def compute_distance(p0, p1):
    '''
    Computes the distance between `p0` and `p1`, projected onto the center of the track.
    '''
    delta_pos = p1.pos - p0.pos
    delta_dist = p1.dist - p0.dist

    delta_pos_norm = numpy.linalg.norm(delta_pos)
    sqr_dist = (delta_pos_norm * delta_pos_norm) - (delta_dist * delta_dist)
    if sqr_dist >= 0.00001:
        return math.sqrt(sqr_dist)
    else:
        return 0.

def projection_angle(p0, p1, proj_dist):
    '''
    Computes the angle of the projected vector relative to the center of the track.
    '''
    delta_pos = p1.pos - p0.pos
    delta_pos_len = numpy.linalg.norm(delta_pos)
    if delta_pos_len >= 0.00001:
        return math.acos(numpy.linalg.norm(proj_dist) / delta_pos_len)
    else:
        return 0.

def get_projected_vector(p0, p1):
    '''
    Computes the delta vector projected onto the center of the track.
    '''
    delta_pos = p1.pos - p0.pos
    proj_dist = compute_distance(p0, p1)
    delta_angle = projection_angle(p0, p1, proj_dist)

    if p1.dist < 0.:
        delta_angle = -delta_angle

    proj = numpy.array([
        delta_pos[0] * math.cos(delta_angle) - delta_pos[1] * math.sin(delta_angle),
        0.,
        delta_pos[0] * math.sin(delta_angle) + delta_pos[1] * math.cos(delta_angle),
    ])

    proj_len = numpy.linalg.norm(proj)
    if proj_len > 0.0001:
        proj /= proj_len
    proj *= proj_dist
    return proj

class DistanceTracker():
    def __init__(self, start_pos, start_cte):
        '''
        `start_pos` is the starting position of the car.
        `start_cte` is the starting Cross Track Error of the car.
        '''
        self.prev = Point(start_pos, start_cte)
        self.prev_proj = numpy.array([0., 0., 0.])
        self.total_distance = 0.

    def get_total_distance(self):
        '''
        Returns the total distance travelled since the beginning.
        This function can be used to compute the score.
        '''
        return self.total_distance

    def next(self, pos, cte):
        '''
        Updates the distance using the given new position and cte.
        This function must be called at each frames of the simulator to update the position and the travelled distance.

        `start_pos` is the starting position of the car.
        `start_cte` is the starting Cross Track Error of the car.
        '''
        pos = numpy.array(pos)
        curr = Point(pos, cte)
        proj = get_projected_vector(curr, self.prev)

        proj_len = numpy.linalg.norm(proj)
        direction = numpy.dot(self.prev_proj, proj)
        if direction >= -0.001:
            self.total_distance += proj_len
        elif direction:
            self.total_distance -= proj_len

        self.prev = curr
        self.prev_proj = proj

    def dictionnary_infos(self):
        infos_to_save = {"total_distance" : self.total_distance}
        return (infos_to_save)

    def upload(self, path, S3=None):
        path = f"{path}.json"
        infos_to_save = self.dictionnary_infos()
        if S3 != None:
            json_obj = json.dumps(infos_to_save).encode('UTF-8')
            bytes_obj = io.BytesIO(json_obj)
            bytes_obj.seek(0)
            S3.upload_bytes(bytes_obj, path)
        else:
            with open(path, "w") as f:
                json.dump(infos_to_save, f)

if __name__ == "__main__":
    d = DistanceTracker(numpy.array([0., 0.]), 0.)
    d.next(numpy.array([1., 1.]), 1.)
    d.next(numpy.array([-3., 2.]), 1.)

    # If uncommented, must partially cancel previous movements
    d.next(numpy.array([0., 0.]), 0.)

    print(d.get_total_distance())


#Oefening 2
#Ziehier de taxi-tarieven voor de stad Antwerpen:
#https://www.taxibedrijfantwerpen.be/prijs-taxi-antwerpen-kost-taxi-antwerpen/. Schrijf
#een functie die de afgelegde afstand (in kilometers) als parameter neemt, alsook ook
#andere nodige parameters (weekend, nacht, luchthaven) om de juiste prijs zoals je
#die op de site geafficheerd ziet te kunnen berekenen. Als resultaat geeft de functie
#de kostprijs van de rit terug. Schrijf binnen een main-functie een programma dat de
#functie demonstreert. Gebruik constanten om de tariefonderdelen weer te geven.
# Definieer constanten voor de tariefonderdelen

STARTTARIEF = 5.00 # euro
KILOMETERTARIEF = 2.50 # euro per km
WEEKENDTOESLAG = 0.00 # euro per km
NACHTTOESLAG = 2.50 # euro per rit
LUCHTHAVENTOESLAG = 85.00 # euro per rit

# Definieer een functie die de taxiprijs berekent op basis van de afstand en andere parameters
def bereken_taxiprijs(afstand, weekend=False, nacht=False, luchthaven=False):
    # Bereken het basistarief als het starttarief plus het kilometertarief maal de afstand
    basistarief = STARTTARIEF + KILOMETERTARIEF * afstand

    # Voeg eventuele toeslagen toe aan het basistarief
    if weekend: # Als het weekend is, voeg dan de weekendtoeslag toe per km
         basistarief  += 2.50
         basistarief  += WEEKENDTOESLAG * afstand

    if nacht: # Als het nacht is, voeg dan de nachttoeslag toe per rit
        basistarief += NACHTTOESLAG

    if luchthaven: # Als het een luchthavenrit is, voeg dan de luchthaventoeslag toe per rit
        basistarief += LUCHTHAVENTOESLAG

    # Rond het eindtarief af op twee decimalen en geef het terug als resultaat
    eindtarief = round(basistarief, 2)
    return eindtarief

# Definieer een main-functie om de bereken_taxiprijs functie te demonstreren met verschillende voorbeelden
def main():
    # Voorbeeld 1: Een rit van 5 km op een doordeweekse dag overdag (geen toeslagen)
    prijs1 = bereken_taxiprijs(5)
    print(f"Een rit van 5 km kost {prijs1} euro.")

    # Voorbeeld 2: Een rit van 10 km op een zaterdagavond (weekend- en nachttoeslag)
    prijs2 = bereken_taxiprijs(10, weekend=True, nacht=True)
    print(f"Een rit van 10 km kost {prijs2} euro.")

    # Voorbeeld 3: Een rit van 15 km naar de luchthaven op een zondagochtend (weekend- en luchthaventoeslag)
    prijs3 = bereken_taxiprijs(15, weekend=True, luchthaven=True)
    print(f"Een rit van 15 km kost {prijs3} euro.")

# Roep de main-functie aan om het programma te starten
main()