import os,glob
from Bio import SeqIO
import statistics
import numpy as np
from Bio.Seq import Seq
import re

vcf_folder = '/scratch/users/anniz44/genomes/donor_species/vcf_round2/merge/details/'
output_folder = '/scratch/users/anniz44/genomes/donor_species/vcf_round2/BS/'
target_TF = '%s/target.TF.faa'%(output_folder)
ref_BS = '%s/ccpA_BS.fa'%(output_folder)
input_bs_file = '%s/binding_results_ccpA.txt'%(output_folder)
BS_folder = ''
distance = 5000 # extract 5kb neighbourhood
distance_TF = 5000 # TF with BS nearby

def find_strains(vcf_file,genomewithSNP):
    mut_strains = []
    for linesvcf in open(vcf_file, 'r'):
        if linesvcf.startswith('CHR'):
            linesvcf_set = linesvcf.split('\n')[0].split('\t')
            allgenome = linesvcf_set[9:]
            i = 1
            # find mutated strains
            for genome in allgenome:
                if str(i) in genomewithSNP:
                    mut_strains.append(genome)
                i += 1
            break
    return [mut_strains,allgenome]

def load_genes(input_faa):
    Mapping_loci_all = dict()
    for record in SeqIO.parse(input_faa, 'fasta'):
        record_id = str(record.id)
        contig = '_'.join(record_id.split('_')[0:-1])
        description = str(record.description).replace(' ', '').split('#')
        Mapping_loci_all.setdefault(contig, [])
        Mapping_loci_all[contig].append([int(description[1]) - 1,
                                         int(description[2]) - 1, record_id])
    return Mapping_loci_all

def contig_length(CHR):
    try:
        total_length = CHR.split('size')[1]
    except IndexError:
        try:
            total_length = CHR.split('length_')[1].split('_cov')[0]
        except IndexError:
            total_length = 10000
    return int(total_length)

def load_BS_old(BS_file,Mapping_loci_all):
    allBS = []
    allBS.append('BS\tpvalue\tlocus\tcontig\tstrand\ttargetgane\tlocusgene\n')
    target_gene_list = dict()
    BS_loci = dict()
    i = 0
    for lines in open(BS_file, 'r'):
        if not lines.startswith('#') and not lines.startswith('motif_id') and lines != '\n':
            lines_set = lines.split('\n')[0].split('\t')
            pvalue = lines_set[7]
            contig, locus1, locus2, strand = lines_set[2:6]
            if contig_length(contig) >= 5000:
                i += 1
                BS_loci.setdefault(contig, [])
                locus1 = int(locus1)
                locus2 = int(locus2)
                targetgene = ''
                locus_target = 0
                if contig in Mapping_loci_all:
                    for locus in Mapping_loci_all[contig]:
                        locusre1, locusref2, genename = locus
                        if locus2 <= locusref2 and targetgene == '':
                            targetgene = genename
                            locus_target = locusre1
                    seq = lines_set[9]
                    if targetgene != '':
                        if strand == '-':
                            # the gene before
                            gene_locus = int(targetgene.split('_')[-1])
                            if gene_locus > 1:
                                targetgene = '_'.join(targetgene.split('_')[0:-1]) + '_%s' % (
                                        int(targetgene.split('_')[-1]) - 1)
                    else:
                        targetgene = '%s_1' % (contig)
                    allBS.append('%s\t%s\t%s\t%s\t%s\t%s\t%s\n' % (
                        seq, pvalue, locus1, contig, strand, targetgene, locus_target))
                    target_gene_list.setdefault(targetgene, set())
                    target_gene_list[targetgene].add(seq)
                    BS_loci[contig].append([locus1, locus2, seq, targetgene,pvalue])
    f1 = open('%s.BS.txt' % (output_file), 'w')
    f1.write(''.join(allBS))
    f1.close()
    aa_output = []
    for record in SeqIO.parse(input_faa, 'fasta'):
        record_id = str(record.id)
        if record_id in target_gene_list:
            for seq in target_gene_list[record_id]:
                aa_output.append('>%s_%s_C_%s_G_%s\n%s\n' % (
                    seq, lineage, record_id.split('_')[1], record_id.split('_')[-1], str(record.seq)))
                select_seq_faa.setdefault(seq,'>%s_%s_C_%s_G_%s\n%s\n' % (
                        seq, lineage, record_id.split('_')[1], record_id.split('_')[-1], str(record.seq)))
    f1 = open('%s.BS.faa' % (output_file), 'w')
    f1.write(''.join(aa_output))
    f1.close()
    return BS_loci

def load_BS(BS_file,Mapping_loci_all,BS_loci,TF_locus):
    allBS = []
    allBS.append('BS\tpvalue\tlocus\tcontig\tstrand\ttargetgane\tlocusgene\n')
    target_gene_list = dict()
    i = 0
    genomename = os.path.split(BS_file)[-1].split('.fimo.tsv')[0]
    check_TF_BS = False
    TF_locus_genome = TF_locus.get(genomename,[])
    TF_contig = [i[0] for i in TF_locus_genome]
    if TF_locus_genome != []:
        # check TF
        for lines in open(BS_file, 'r'):
            if not check_TF_BS and not lines.startswith('#') and not lines.startswith('motif_id') and lines != '\n':
                lines_set = lines.split('\n')[0].split('\t')
                contig, locus1, locus2, strand = lines_set[2:6]
                if contig in TF_contig:
                    locus1 = int(locus1)
                    locus2 = int(locus2)
                    for contig_TF,locus1_TF,locus2_TF,gene in TF_locus_genome:
                        if contig_TF == contig and locus1_TF - distance_TF <= locus2 and locus2_TF + distance_TF >= locus1:
                            #print(locus1_TF - distance_TF,locus2_TF + distance_TF,locus1,locus2,gene)
                            check_TF_BS = True
                            break
        if not check_TF_BS:
            print('not BS near TF for genome %s'%(genomename))
        else:
            # BS near TF
            print('found BS near TF for genome %s' % (genomename))
            pass_genome.append(genomename)
            # load BS
            for lines in open(BS_file, 'r'):
                if not lines.startswith('#') and not lines.startswith('motif_id') and lines != '\n':
                    lines_set = lines.split('\n')[0].split('\t')
                    pvalue = lines_set[7]
                    contig, locus1, locus2, strand = lines_set[2:6]
                    i += 1
                    locus1 = int(locus1)
                    locus2 = int(locus2)
                    targetgene = ''
                    locus_target = 0
                    if contig in Mapping_loci_all:
                        for locus in Mapping_loci_all[contig]:
                            locusre1, locusref2, genename = locus
                            if locus2 <= locusref2 and targetgene == '':
                                targetgene = genename
                                locus_target = locusre1
                        seq = lines_set[9]
                        if targetgene != '':
                            if strand == '-':
                                # the gene before
                                gene_locus = int(targetgene.split('_')[-1])
                                if gene_locus > 1:
                                    targetgene = '_'.join(targetgene.split('_')[0:-1]) + '_%s' % (
                                            int(targetgene.split('_')[-1]) - 1)
                        else:
                            targetgene = '%s_1' % (contig)
                        allBS.append('%s\t%s\t%s\t%s\t%s\t%s\t%s\n' % (
                            seq, pvalue, locus1, contig, strand, targetgene, locus_target))
                        target_gene_list.setdefault(targetgene, set())
                        target_gene_list[targetgene].add(seq)
                        BS_loci.setdefault(seq, [])
                        BS_loci[seq].append([genomename, locus1, locus2, '%s_C_%s_G_%s' % (genomename,
                                                                                targetgene.split('_')[1],
                                                                                targetgene.split('_')[-1])])
                # output BS and gene target
            # output BS and gene target
            f1 = open('%s.BS.txt' % (output_file), 'w')
            f1.write(''.join(allBS))
            f1.close()
            aa_output = []
            for record in SeqIO.parse(input_faa, 'fasta'):
                record_id = str(record.id)
                if record_id in target_gene_list:
                    for seq in target_gene_list[record_id]:
                        record_seq = str(record.seq)
                        aa_output.append('>%s_%s_C_%s_G_%s\n%s\n' % (
                            seq, genomename, record_id.split('_')[1], record_id.split('_')[-1], record_seq))
                        select_seq_faa.setdefault(seq,['',set()])
                        if record_seq not in select_seq_faa[seq][-1]:
                            select_seq_faa[seq][-1].add(record_seq)
                            select_seq_faa[seq][0]+=('>%s_%s_C_%s_G_%s\n%s\n' % (
                                    seq, genomename, record_id.split('_')[1], record_id.split('_')[-1], record_seq))
            f1 = open('%s.BS.faa' % (output_file), 'w')
            f1.write(''.join(aa_output))
            f1.close()
    return BS_loci

def annotate(fasta_output):
    cutoff = 0.7
    cmd_cluster = ('%s -sort length -cluster_fast %s -id %s -centroids %s.cluster.aa -uc %s.uc -threads %s\n'
                           % ('usearch', fasta_output, cutoff, fasta_output,
                              fasta_output, 40))
    os.system(cmd_cluster)
    fasta_output = fasta_output + '.cluster.aa'
    cutoff = 0.01
    database = '/scratch/users/mit_alm/database/eggnog/xaa.hmm'
    cmds = ('hmmsearch --tblout %s.eggnog.1.txt --cpu 40 -E %s %s %s\n') % (
    fasta_output, cutoff, database, fasta_output)
    database = '/scratch/users/mit_alm/database/eggnog/xab.hmm'
    cmds += ('hmmsearch --tblout %s.eggnog.2.txt --cpu 40 -E %s %s %s\n') % (
        fasta_output, cutoff, database, fasta_output)
    database = '/scratch/users/mit_alm/database/eggnog/xac.hmm'
    cmds += ('hmmsearch --tblout %s.eggnog.3.txt --cpu 40 -E %s %s %s\n') % (
        fasta_output, cutoff, database, fasta_output)
    f1 = open(output_file_BS + '.eggnog.sh', 'w')
    f1.write(
        '#!/bin/bash\nsource ~/.bashrc\nexport LD_LIBRARY_PATH=/scratch/users/anniz44/bin/pro/lib/gsl-2.6:/scratch/users/anniz44/bin/pro/lib/glibc-2.14-build:/scratch/users/anniz44/bin/pro/lib/:/scratch/users/anniz44/bin/miniconda3/lib:$LD_LIBRARY_PATH\n%s' % (
            cmds))
    f1.close()

def allele_freq_to_allele(genotype, ALT_set):
    genotype = [int(i) for i in genotype.split(':')[-1].split(',')]
    Major_ALT = '-'
    if sum(genotype) > 0:
        ALT_set_sample = dict()
        ALT_frq_set = set()
        for i in range(0,len(ALT_set)):
            ALT_frq = int(genotype[i])
            ALT_set_sample.setdefault(ALT_frq, set())
            ALT_set_sample[ALT_frq].add(ALT_set[i])
            ALT_frq_set.add(ALT_frq)
        ALT_frq_set = sorted(ALT_frq_set, reverse=True)
        for ALT_frq in ALT_frq_set:
            for alleles in ALT_set_sample[ALT_frq]:
                if Major_ALT == '-':
                    Major_ALT = alleles
    return Major_ALT

def find_mutations_on_BS_old(vcf_file2,mut_strains,BS_loci):
    BS_SNP_output = []
    mut_strains_set = []
    wild_type_set = []
    allseqout = set()
    genomewithSNPvcf = []
    genomewithnoSNPvcf = []
    samplefile = vcf_file2.replace('.all.raw.vcf.all','.all.raw.vcf.filtered.samplename.txt')
    for lines in open(samplefile, 'r'):
        # set sample name
        sample_set = lines.split('\n')[0].split('\t')
        i = 9
        for samples in sample_set:
            genome = samples
            if genome in mut_strains:
                genomewithSNPvcf.append(i)
                mut_strains_set.append('M.%s' % (genome))
            elif genome in allgenome:
                genomewithnoSNPvcf.append(i)
                wild_type_set.append('W.%s' % (genome))
            i += 1
    BS_SNP_output.append('BS\tBS_in_ref\tCHR\tPOS\tPOS_on_BS\tTarget\tpvalue\tMutated_alleles\tWildtype_alleles\t%s\t%s\n' % (
        '\t'.join(mut_strains_set),
        '\t'.join(
            wild_type_set)
    ))
    #print(mut_strains,mut_strains_set,wild_type_set)
    for linesvcf in open(vcf_file2, 'r'):
        linesvcf_set = linesvcf.split('\n')[0].split('\t')
        if not linesvcf.startswith('#'):
            contig, POS = linesvcf_set[0:2]
            if contig in BS_loci:
                POS = int(POS)
                for BSpos in BS_loci[contig]:
                    BSpos1, BSpos2, seq, targetgene,pvalue = BSpos
                    if POS >= BSpos1 - distance and POS <= BSpos2 + distance :
                        REF = linesvcf_set[3]
                        ALT_set = [REF]
                        ALT = linesvcf_set[4]
                        for a_ALT in ALT.split(','):
                            if a_ALT != '.':
                                ALT_set.append(a_ALT)
                        # BS site
                        Mut_allele = []
                        Wild_allele = []
                        # Major_ALT in mutated strains
                        for i in genomewithSNPvcf:
                            genotype = linesvcf_set[i]
                            Major_ALT = allele_freq_to_allele(genotype, ALT_set)
                            Mut_allele.append(Major_ALT)
                        # Major_ALT in wild type strains
                        for i in genomewithnoSNPvcf:
                            genotype = linesvcf_set[i]
                            Major_ALT = allele_freq_to_allele(genotype, ALT_set)
                            Wild_allele.append(Major_ALT)
                        Mut_allele_set = sorted(set(Mut_allele))
                        Wild_allele_set = sorted(set(Wild_allele))
                        if any(i not in Wild_allele_set for i in Mut_allele_set):
                            # different alleles
                            inref = False
                            if seq in Ref:
                                inref = True
                            BS_SNP_output.append('%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n' % (
                                seq, inref, contig, POS, POS - BSpos1 + 1, targetgene,pvalue,
                                ';'.join(list(Mut_allele_set)),
                                ';'.join(list(Wild_allele_set)),
                                '\t'.join(Mut_allele),
                                '\t'.join(Wild_allele)
                            ))
                            allseqout.add(select_seq_faa.get(seq, ''))
    f1 = open('%s.BSsum.txt' % (output_file_BS),'w')
    f1.write(''.join(BS_SNP_output))
    f1.close()
    if len(allseqout)>0:
        f1 = open('%s.BS.faa' % (output_file_BS), 'w')
        f1.write(''.join(list(allseqout)))
        f1.close()
        annotate('%s.BS.faa' % (output_file_BS))

def find_mutations_on_BS(vcf_file2,mut_strains,BS_loci_co_assembly):
    BS_SNP_output = []
    mut_strains_set = []
    wild_type_set = []
    allseqout = set()
    genomewithSNPvcf = []
    genomewithnoSNPvcf = []
    samplefile = vcf_file2.replace('.all.raw.vcf.all','.all.raw.vcf.filtered.samplename.txt')
    for lines in open(samplefile, 'r'):
        # set sample name
        sample_set = lines.split('\n')[0].split('\t')
        i = 9
        for samples in sample_set:
            genome = samples
            if genome in mut_strains:
                genomewithSNPvcf.append(i)
                mut_strains_set.append('M.%s' % (genome))
            elif genome in allgenome:
                genomewithnoSNPvcf.append(i)
                wild_type_set.append('W.%s' % (genome))
            i += 1
    BS_SNP_output.append('BS\tBS_in_ref\tCHR\tPOS\tPOS_on_BS\tMutated_alleles\tWildtype_alleles\t%s\t%s\n' % (
        '\t'.join(mut_strains_set),
        '\t'.join(
            wild_type_set)
    ))
    #print(mut_strains,mut_strains_set,wild_type_set)
    finished_set = []
    for linesvcf in open(vcf_file2, 'r'):
        linesvcf_set = linesvcf.split('\n')[0].split('\t')
        if not linesvcf.startswith('#'):
            contig, POS = linesvcf_set[0:2]
            if contig in BS_loci_co_assembly:
                POS = int(POS)
                for seq_loci_sub,seq in BS_loci_co_assembly[contig]:
                    if [seq_loci_sub,seq] not in finished_set:
                        finished_set.append([seq_loci_sub,seq])
                        BSpos1, BSpos2 = seq_loci_sub
                        if POS >= BSpos1 - distance and POS <= BSpos2 + distance:
                            REF = linesvcf_set[3]
                            ALT_set = [REF]
                            ALT = linesvcf_set[4]
                            for a_ALT in ALT.split(','):
                                if a_ALT != '.':
                                    ALT_set.append(a_ALT)
                            # BS site
                            Mut_allele = []
                            Wild_allele = []
                            # Major_ALT in mutated strains
                            for i in genomewithSNPvcf:
                                genotype = linesvcf_set[i]
                                Major_ALT = allele_freq_to_allele(genotype, ALT_set)
                                Mut_allele.append(Major_ALT)
                            # Major_ALT in wild type strains
                            for i in genomewithnoSNPvcf:
                                genotype = linesvcf_set[i]
                                Major_ALT = allele_freq_to_allele(genotype, ALT_set)
                                Wild_allele.append(Major_ALT)
                            Mut_allele_set = sorted(set(Mut_allele))
                            Wild_allele_set = sorted(set(Wild_allele))
                            if any(i not in Wild_allele_set for i in Mut_allele_set):
                                # different alleles
                                inref = False
                                if seq in Ref:
                                    inref = True
                                #targetgene = [i[-1] for i in BS_loci[seq]]
                                BS_SNP_output.append('%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n' % (
                                    seq, inref, contig, POS, POS - BSpos1 + 1,
                                    ';'.join(list(Mut_allele_set)),
                                    ';'.join(list(Wild_allele_set)),
                                    '\t'.join(Mut_allele),
                                    '\t'.join(Wild_allele)
                                ))
                                allseqout.add(select_seq_faa.get(seq, '')[0])
    f1 = open('%s.BSsum.txt' % (output_file_BS), 'w')
    f1.write(''.join(BS_SNP_output))
    f1.close()
    if len(allseqout)>0:
        f1 = open('%s.BS.faa' % (output_file_BS), 'w')
        f1.write(''.join(list(allseqout)))
        f1.close()
        annotate('%s.BS.faa' % (output_file_BS))

def find_TF(input_faa,blast_out,alloutput):
    withTF = False
    genomename = os.path.split(input_faa)[-1].split('.faa')[0]
    #donor = genomename.split('_')[0]
    TF_set = dict()
    for lines in open(blast_out):
        lines_set = lines.split('\t')
        query,reference = lines_set[0:2]
        TF_set.setdefault(query,[])
        TF_set[query].append(reference)
    for record in SeqIO.parse(input_faa, 'fasta'):
        record_id = str(record.id)
        if record_id in TF_set:
            for reference in TF_set[record_id]:
                #if donor in reference:
                    description = str(record.description).replace(' ', '').split('#')
                    alloutput.append('%s\t%s\t%s\t%s\t%s\n'%(genomename,record_id,description[1],description[2],reference))
                    withTF = True
    if not withTF:
        print('TF not found for %s'%(input_faa))
    return alloutput

def load_TF(TF_locus_file):
    TF_locus = dict()
    for lines in open(TF_locus_file,'r'):
        lines_set = lines.split('\t')
        genome, gene,locus1,locus2 = lines_set[0:4]
        genome = genome.split('.all')[0]
        contig = '_'.join(gene.split('_')[0:-1])
        TF_locus.setdefault(genome,[])
        TF_locus[genome].append([contig,int(locus1),int(locus2),gene])
    return TF_locus

def find_target_BS(mut_strains, BS_loci,allgenome):
    BS_select = set()
    wild_strains = [i for i in allgenome if i not in mut_strains]
    if any(genome in mut_strains for genome in pass_genome) and any(genome in wild_strains for genome in pass_genome):
        # mutated genome and wild strains all passed
        print('found enough genomes passing the criterion of BS near TF')
        for seq in BS_loci:
            allgenomewithBS = [i[0] for i in BS_loci[seq]]
            # only in mutated
            if (any(genome in mut_strains for genome in allgenomewithBS) and not any(
                    genome in wild_strains for genome in allgenomewithBS)):
                BS_select.add(seq)
    else:
        print('not enough genomes passing the criterion of BS near TF')
        BS_select = set()
    return BS_select

def find_BS_coassembly(co_assembly,BS_select):
    BS_loci_co_assembly = dict()
    for record in SeqIO.parse(co_assembly, 'fasta'):
        record_id = str(record.id)
        record_seq = str(record.seq)
        for seq in BS_select:
            seq_loci = [[m.start()+1, m.end()+1] for m in re.finditer(seq, record_seq)]
            if seq_loci!=[]:
                BS_loci_co_assembly.setdefault(record_id,[])
                for seq_loci_sub in seq_loci:
                    BS_loci_co_assembly[record_id].append([seq_loci_sub,seq])
            seq_rev = str(Seq(seq).reverse_complement())
            seq_loci = [[m.start()+1, m.end()+1] for m in re.finditer(seq_rev, record_seq)]
            if seq_loci!=[]:
                if seq_rev in select_seq_faa:
                    seq = seq_rev
                BS_loci_co_assembly.setdefault(record_id, [])
                for seq_loci_sub in seq_loci:
                    BS_loci_co_assembly[record_id].append([seq_loci_sub, seq])
    return BS_loci_co_assembly

def TF_near_BS(TF_locus,BS_file_all):
    BS_TF = []
    for BS_file in BS_file_all:
        check_TF_BS = False
        genome = os.path.split(BS_file)[-1].split('.BS.txt')[0]
        TF_locus_genome = TF_locus.get(genome, [])
        TF_contig = [i[0] for i in TF_locus_genome]
        for lines in open(BS_file,'r'):
            if not lines.startswith('BS'):
                lines_set = lines.split('\n')[0].split('\t')
                seq,contig,locus = lines_set[0:3]
                if contig in TF_contig:
                    locus = int(locus)
                    for contig_TF, locus1_TF, locus2_TF,gene in TF_locus_genome:
                        if contig_TF == contig and locus1_TF - distance_TF <= locus and locus2_TF + distance_TF >= locus:
                            check_TF_BS = True
                            BS_TF.append('%s\t%s\t%s\t%s\t%s\n'%(genome,contig,seq,locus,gene))
        if not check_TF_BS:
            print('BS not found near TF %s'%(genome))
    f1 = open('%s/allBSnearTF.txt' % (output_folder), 'w')
    f1.write(''.join(BS_TF))
    f1.close()

# find all TF
try:
    f1 = open('%s/allTFloci.txt' % (output_folder), 'r')
except FileNotFoundError:
    cmds = 'export LD_LIBRARY_PATH=/scratch/users/anniz44/bin/pro/lib/gsl-2.6:/scratch/users/anniz44/bin/pro/lib/glibc-2.14-build:/scratch/users/anniz44/bin/pro/lib/:/scratch/users/anniz44/bin/miniconda3/lib:$LD_LIBRARY_PATH\n'
    os.system(cmds)
    alloutput = []
    allinput_faa = glob.glob('%s/*/*.faa'%(output_folder))
    for input_faa in allinput_faa:
        cmds = (
            "diamond blastp --query %s --db %s.dmnd --out %s.TF.txt --id 80 --outfmt 6 --max-target-seqs 10 --evalue 1e-1 --threads 40\n"%
            (
                input_faa,target_TF,input_faa,
            ))
        os.system(cmds)
        alloutput = find_TF(input_faa, input_faa + '.TF.txt', alloutput)
    f1 = open('%s/allTFloci.txt' % (output_folder), 'w')
    f1.write(''.join(alloutput))
    f1.close()

# load TF loci
TF_locus = load_TF('%s/allTFloci.txt' % (output_folder))

# find BS predicted in genomes near TF
try:
    f1 = open('%s/allBSnearTF.txt' % (output_folder), 'r')
except FileNotFoundError:
    BS_file_all = glob.glob('%s/*/*.BS.txt'%(output_folder))
    #BS_file_all = glob.glob('%s/*.BS.txt' % (output_folder))
    TF_near_BS(TF_locus, BS_file_all)
    print('finished processing TF near BS')

# load ref
Ref = []
if ref_BS != 'None':
    for record in SeqIO.parse(ref_BS, 'fasta'):
        Ref.append(str(record.seq))

# process each SNP
for lines in open(input_bs_file,'r'):
    if not lines.startswith('AA_POS_ref'):
        try:
            lines_set = lines.split('\t')
            lineage = lines_set[4].split('__')[0].replace('CL', 'clustercluster')
            species = lines_set[4].split('_')[0]
            donor = lines_set[5]
            SNP = lines_set[3]
            output_file_BS = '%s/%s/%s_%s_%s' % (output_folder, BS_folder,species, donor, SNP)
            print(output_file_BS)
            try:
                f1 = open('%s.BSsum.txt' % (output_file_BS), 'r')
            except FileNotFoundError:
                select_seq_faa = dict()
                # find genome names
                vcf_file = '%s/%s%s' % (
                    vcf_folder, lineage, '.all.parsi.fasta.linktrunc.sum.txt')
                genomewithSNP = lines_set[-9].split(';')
                mut_strains, allgenome = find_strains(vcf_file, genomewithSNP)
                print('process %s mutated strains %s'%(lineage,mut_strains))
                lineage = lineage.split('.donor')[0]
                # process fino results
                donor_species = '%s_%s'%(species,donor)
                BS_file_all = glob.glob('%s/%s/%s/*.fimo.tsv'%(output_folder,BS_folder,donor_species))
                BS_loci = dict()
                pass_genome = []
                for BS_file in BS_file_all:
                    output_file = BS_file.split('.fimo.tsv')[0]
                    input_faa = '%s/%s/%s.faa'%(output_folder,donor_species,os.path.split(output_file)[-1])
                    # load all gene position
                    Mapping_loci_all = load_genes(input_faa)
                    # load BS
                    BS_loci = load_BS(BS_file, Mapping_loci_all,BS_loci,TF_locus)
                # find targeted BS only in mutated or only in WT
                BS_select = find_target_BS(mut_strains, BS_loci,allgenome)
                if BS_select!= set():
                    # find genome locus for BS_select
                    co_assembly = '%s/co-assembly/%s.all.spades2.fasta'%(output_folder,lineage)
                    BS_loci_co_assembly = find_BS_coassembly(co_assembly,BS_select)
                    print(BS_loci_co_assembly)
                    # find mutations on BS in mutated strains
                    vcf_file2 = '%s/moredetails/%s.all.raw.vcf.all' % (
                        vcf_folder, lineage)
                    print(vcf_file2)
                    find_mutations_on_BS(vcf_file2, mut_strains, BS_loci_co_assembly)
            # filter BS
            BS_file = '%s.BSsum.txt' % (output_file_BS)
            # filter BS
            BS_set = set()
            for lines in open(BS_file, 'r'):
                if not lines.startswith('BS'):
                    lines_set = lines.split('\t')
                    BS = lines_set[0]
                    POS_on_BS = int(lines_set[4])
                    Mut = lines_set[5]
                    if POS_on_BS >= -20 and POS_on_BS <= 20:
                        # BS with changes on BS itself and not just loss
                        BS_set.add(BS)
            BS_file_out = []
            for lines in open(BS_file, 'r'):
                if lines.startswith('BS'):
                    BS_file_out.append(lines)
                elif lines != '':
                    seq = lines.split('\t')[0]
                    if seq in BS_set:
                        # BS with changes on BS itself and not just loss
                        BS_file_out.append(lines)
            f1 = open('%s.BSsum.filtered.txt' % (output_file_BS), 'w')
            f1.write(''.join(BS_file_out))
            f1.close()
        except FileNotFoundError:
            pass

alleggnog = glob.glob(os.path.join(output_folder, '%s/*eggnog.sh'%(BS_folder)))
if alleggnog!= []:
    f1 = open(os.path.join(output_folder, '%s/allanno.sh'%(BS_folder)), 'w')
    f1.write('#!/bin/bash\nsource ~/.bashrc\n')
    for sub_scripts in alleggnog:
        f1.write('jobmit %s %s small1\n' % (sub_scripts, os.path.split(sub_scripts)[-1]))
    f1.close()
    print('please run %s/%s/allanno.sh'%(output_folder,BS_folder))


import sys
import asyncio
from aioconsole import ainput

async def input_loop(loop):
    while True:
        input_ = await ainput(loop=loop)
        if input_ == "@end":
            sys.exit(0)
        print(f"Echo: {input_}")

if __name__ == "__main__":
    loop = asyncio.get_event_loop()
    loop.run_until_complete(input_loop(loop))


import unittest

from libs.model import MonthClosings

class MyTestCase(unittest.TestCase):

    def test_closing_performance(self):

        #given:
        closings = MonthClosings()
        closings.closings = [100, 100, 105]

        #when:
        performance = closings.calculate_performance()

        #then:
        self.assertEqual(2, len(performance))
        self.assertEqual(0, performance[0])
        self.assertEqual(0.05, performance[1])

if __name__ == '__main__':
    unittest.main()


# -*- coding: utf-8 -*-
import scrapy
from scrapy import Request
from lxml import etree
from WaiBaoSpider.utils.csvWriter import CSVDumper
from WaiBaoSpider.utils.base import unicode_body, deal_ntr
import os

class LuAnSpider(scrapy.Spider):
    name = "luan"
    # base_url = "http://www.luan.gov.cn/nocache/supervision/?product_id=3&page={}"
    base_url = "http://www.luan.gov.cn/zxly/?type=product&page={}"
    data_path = os.getcwd() + "/WaiBaoSpider/data/"
    if os.path.exists(data_path):
        pass
    else:
        os.mkdir(data_path)
    dump_list = CSVDumper(data_path + "%s_list.csv" % name)
    dump_detail = CSVDumper(data_path + "%s_detail.csv" % name)
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36",
    }

    # custom_settings = {
    # }

    def start_requests(self):
        for i in range(1, 915):
            # for i in range(2, 4):
            url = self.base_url.format(i)
            print(url)
            yield Request(url, headers=self.headers, callback=self.parse_list)

    # def parse_list(self, response):
    #     body = unicode_body(response)
    #     html = etree.HTML(body)
    #     lines = html.xpath("//table[@class='is-xjnr']/tr")
    #     print(len(lines))
    #     for info in lines:
    #         item = {}
    #         item[u"类别"] = info.xpath("./td[1]/text()")[0].strip() if info.xpath("./td[1]/text()") else ""
    #         title = info.xpath("./td[3]/a//text()") if info.xpath("./td[3]/a//text()") else []
    #         item[u"来信标题"] = deal_ntr("".join(title).strip())
    #         item[u"来信时间"] = info.xpath("./td[5]/text()")[0].strip() if info.xpath("./td[5]/text()") else ""
    #         item[u"处理状态"] = info.xpath("./td[7]/span/text()")[0].strip() if info.xpath("./td[7]/span/text()") else ""
    #         item[u"浏览次数"] = info.xpath("./td[9]/text()")[0].strip() if info.xpath("./td[9]/text()") else ""
    #         item[u"回复评价"] = info.xpath("./td[11]/a/text()")[0].strip() if info.xpath("./td[11]/a/text()") else ""
    #         item[u"链接"] = "http://www.luan.gov.cn{}".format(
    #             info.xpath("./td[3]/a/@href")[0].strip() if info.xpath("./td[3]/a/@href") else "")
    #         if info.xpath("./td[3]/a/span/text()"):
    #             item[u"是否公开"] = u"不公开"
    #             item_detail = {
    #                 u"链接": item[u"链接"],
    #                 u"标题": item[u"来信标题"],
    #                 u"来信人": u"",
    #                 u"来信时间": item[u"来信时间"],
    #                 u"处理情况": item[u"处理状态"],
    #                 u"督办部门": u"",
    #                 u"问题类别": u"",
    #                 u"浏览": item[u"浏览次数"],
    #                 u"来信内容": u"",
    #                 u"回复内容": u"",
    #                 u"回复单位": u"",
    #                 u"回复时间": u"",
    #                 u"是否公开": u"否",
    #             }
    #             self.dump_detail.process_item(item_detail)
    #         else:
    #             item[u"是否公开"] = u"公开"
    #             yield Request(item[u"链接"], headers=self.headers, callback=self.parse_detail,
    #                           meta={"url": item[u"链接"], "llcs": item[u"浏览次数"], "clzt": item[u"处理状态"]})
    #         self.dump_list.process_item(item)

    def parse_list(self, response):
        body = unicode_body(response)
        html = etree.HTML(body)
        lines = html.xpath("//ul[@class='is-listnews']/li")
        print(len(lines))
        for info in lines:
            item = {}
            item[u"来信标题"] = info.xpath("./a/text()")[0].strip() if info.xpath("./a/text()") else ""
            item[u"来信时间"] = info.xpath("./span/text()")[0].strip() if info.xpath("./span/text()") else ""
            item[u"链接"] = "http://www.luan.gov.cn{}".format(
                info.xpath("./a/@href")[0].strip() if info.xpath("./a/@href") else "")
            self.dump_list.process_item(item)
            yield Request(item[u"链接"], headers=self.headers, callback=self.parse_detail,
                          meta={"url": item[u"链接"]})

    def parse_detail(self, response):
        body = unicode_body(response)
        data = response.meta
        html = etree.HTML(body)
        item = {}
        item[u"链接"] = data["url"]
        item[u"标题"] = html.xpath("//div[@class='is-newstitle']/text()")[0].strip() if html.xpath(
            "//div[@class='is-newstitle']/text()") else ""
        item[u"来信人"] = html.xpath("//div[@class='is-mailinfo']/text()[1]")[0].strip().replace(u"来信人：",
                                                                                u"") if html.xpath(
            "//div[@class='is-mailinfo']/text()[1]") else ""
        item[u"来信时间"] = html.xpath("//div[@class='is-mailinfo']/text()[2]")[0].strip().replace(u"来信时间：",
                                                                                u"") if html.xpath(
            "//div[@class='is-mailinfo']/text()[2]") else ""
        item[u"处理情况"] = html.xpath("//span[@class='orange state']/text()")[0].strip() if html.xpath(
            "//span[@class='orange state']/text()") else ""
        dbbm = html.xpath("//div[@class='is-mailinfo']/span[4]/text()[1]")[0].strip().replace(u"|",
                                                                                u"").replace(
            u"督办部门：", u"") if html.xpath("//div[@class='is-mailinfo']/span[4]/text()[1]") else ""
        item[u"督办部门"] = deal_ntr(dbbm)
        item[u"问题类别"] = html.xpath("//div[@class='is-mailinfo']/span[4]/span[@class='red'][1]/text()")[
            0].strip() if html.xpath("//div[@class='is-mailinfo']/span[4]/span[@class='red'][1]/text()") else ""
        item[u"浏览"] = html.xpath("//div[@class='is-mailinfo']/span[4]/span[@class='red'][2]/text()")[
            0].strip() if html.xpath("//div[@class='is-mailinfo']/span[4]/span[@class='red'][2]/text()") else ""
        lxnr = html.xpath("//div[@class='is-mailwen']/p//text()") if html.xpath(
            "//div[@class='is-mailwen']/p//text()") else []
        item[u"来信内容"] = deal_ntr("".join(lxnr))
        hf_content = html.xpath("//div[@class='is-hfcontent']//text()") if html.xpath(
            "//div[@class='is-hfcontent']//text()") else []
        item[u"回复内容"] = deal_ntr("".join(hf_content))
        item[u"回复单位"] = html.xpath("//div[@class='is-mialhf']/h1/span[2]/text()")[0].strip().replace(u"回复单位：",
                                                                                u"") if html.xpath(
            "//div[@class='is-mialhf']/h1/span[2]/text()") else ""
        item[u"回复时间"] = html.xpath("//div[@class='is-mialhf']/h1/span[1]/text()")[0].strip().replace(u"回复时间：",
                                                                                u"") if html.xpath(
            "//div[@class='is-mialhf']/h1/span[1]/text()") else ""
        self.dump_detail.process_item(item)


import cv2
import numpy as np

img = cv2.imread('/home/kanish/Documents/ICR advanced forms/Advanced handwritting samples/athul_scanned/525/525_2.png', 0)

kernel = np.ones((5, 1), np.uint8)
erosion = cv2.erode(img, kernel, iterations=1)

cv2.imwrite('morphex.png', erosion)

cv2.imshow('gray', erosion)
cv2.waitKey(0)


#!/usr/bin/python3

from typing import List
import json
from bplib.butil import TreeNode, arr2TreeNode, btreeconnect

class Solution:
    def intersect(self, nums1: List[int], nums2: List[int]) -> List[int]:
        st = {}
        for n in nums1:
            if n not in st:
                st[n] = 0
            st[n] += 1
        ans = []
        for n in nums2:
            if n in st and st[n] > 0:
                st[n] -= 1
                ans.append(n)
        return ans

arr1 = json.loads(input())
arr2 = json.loads(input())

sol = Solution()
print(sol.intersect(arr1, arr2))


import pygame
import field_and_pointer as fp
import argparser as ap

# Stack, field, pointer and the 2-input operators
stackstack = [[]]
the_field = fp.Field(fp.load_code())
pointer = fp.Pointer((0, 0), (1, 0))
operators = {
    "+": lambda x1, x2: stackstack[-1].append(x1 + x2),
    "-": lambda x1, x2: stackstack[-1].append(x2 - x1),
    "*": lambda x1, x2: stackstack[-1].append(x1 * x2),
    "/": lambda x1, x2:
    stackstack[-1].append(int(float(x2) // float(x1)))
    if x1 else stackstack[-1].append(0),
    "%": lambda x1, x2: stackstack[-1].append(x2 % x1),
    "`": lambda x1, x2:
    stackstack[-1].append(1) if x2 > x1 else stackstack[-1].append(0),
    "\\": lambda x1, x2: stackstack[-1].extend([x1, x2]),
    "g": lambda x1, x2: stackstack[-1].append(ord(the_field.get_char(x2, x1)))}

# Global constants related to pygame
CHAR_WIDTH = 12
CHAR_HEIGHT = 28
SCREEN_HEIGHT_MODIFIER = 300
SCREEN_HEIGHT = the_field.Y * CHAR_HEIGHT + SCREEN_HEIGHT_MODIFIER
SCREEN_WIDTH = the_field.X * CHAR_WIDTH + 500
BG_COLOR = (52, 52, 52)
STACK_BG_COLOR = (0, 0, 0, 100)
STACK_OUTPUT_COLOR = (230, 200, 70)
SOSS_OUTPUT_COLOR = (70, 230, 200)
POINTER_COLOR = (255, 255, 255, 130)
STACK_CHAR_HEIGHT = 16
STACK_CHAR_WIDTH = 10
ARGS = ap.parse_arguments()
_paused = False
_step_once = False
_reset = False

# Pygame surface inits
if not ARGS.OUTPUT_MODE:
    screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
    background = pygame.Surface(screen.get_size()).convert()
    pointer_rect = pygame.Surface((CHAR_WIDTH, CHAR_HEIGHT), pygame.SRCALPHA)
    pointer_rect.fill(POINTER_COLOR)
    stacksurf = pygame.Surface((SCREEN_WIDTH, SCREEN_HEIGHT_MODIFIER),
                               pygame.SRCALPHA)
    outsurf = pygame.Surface((int(float(SCREEN_WIDTH) / 2.0),
                             SCREEN_HEIGHT_MODIFIER),
                             pygame.SRCALPHA)
    pygame.display.set_caption("Befunge-98 Interpreter")
    # Pygame font inits
    pygame.font.init()
    stackfont = pygame.font.Font("../font/Inconsolata.otf", 18)
    codefont = pygame.font.Font("../font/Inconsolata.otf", 24)

# Global constants related to bf98.py
_outcount = 0
_outline = 0
_instring = ""


import requests
from bs4 import BeautifulSoup as soup

def requesting_ip():
    HEADERS = {
        'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
        #'Accept-Encoding':'gzip, deflate, br',
        'Accept-Language':'en-US,en;q=0.5',
        'Connection':'keep-alive',
        'Upgrade-Insecure-Requests':'1',
        'User-Agent':'Mozilla/5.0 (Windows NT 6.1; rv:60.0) Gecko/20100101 Firefox/60.0',
    }

    url = 'https://www.duckduckgo.com/html?q=my+ip'

    if url:
        r = requests.get(url, headers=HEADERS)
        page = soup(r.text, 'html5lib')
        page = str(page).splitlines()
        return page
    elif url_check == False:
        print('< check url >')

def parsing_ip(page):
    for line in page:
        if 'Your IP address is ' in line and ' in <a href="http' in line:
            line = line.replace('Your','\nYour').splitlines()[1]
            line = line.split(' ')
            print(f'{line[0]} {line[1]} {line[2]} {line[3]} {line[4]} ')

def main():
    page = requesting_ip()
    if page:
        parsing_ip(page)

if __name__ == '__main__':
    main()


import hashlib
import zlib
from PyQt5 import QtCore, QtGui, QtWidgets
from file_browse import *

data=[
        {'Check':'','More':'','Details':'','@timestamp':'2023/03/12 12:00:00','Rule':'Enumeration of users or Groups','Severity':'low','Risk Score':'21','Reason':'process event with process dsmemberutil, parent process bash, by root'},
        {'Check':'','More':'','Details':'','@timestamp':'2023/03/12 12:00:01','Rule':'Potential persitance via login hook','Severity':'medium','Risk Score':'50','Reason':'modify key-value pairs in plist files to influence system behaviors, such as hiding the execution of an application (i.e. Hidden Window) or running additional commands for persistence '},
        {'Check':'','More':'','Details':'','@timestamp':'2023/03/12 12:00:02','Rule':'Malware prevention alert','Severity':'high','Risk Score':'73','Reason':'malware, intrusion_detection file event with process AYHelperService'},
        {'Check':'','More':'','Details':'','@timestamp':'2023/03/12 12:00:00','Rule':'Enumeration of users or Groups','Severity':'low','Risk Score':'21','Reason':'process event with process dsmemberutil, parent process bash, by root'}
]
class Ui_FileScan(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()
        self.vLayout1 = QtWidgets.QVBoxLayout()
        self.vLayout2=QtWidgets.QVBoxLayout()
        self.layout = QtWidgets.QHBoxLayout()
        self.bigLayout=QtWidgets.QVBoxLayout()

        self.add_label("Sandbox",1.5,Qt.AlignCenter,20)

        self.add_file_browser_layer1()
        self.add_submit_url_layer2()

        self.buttonClose = QtWidgets.QPushButton('Back')
        self.buttonClose.clicked.connect(self.close)

        self.vLayout1.addStretch()
        self.vLayout2.addStretch()

        self.bigLayout.addLayout(self.layout)
        self.add_label("Drag your file into left field or click to select a file",0.5,Qt.AlignVCenter,10)

        self.bigLayout.addStretch()

        self.setLayout(self.bigLayout)

    def add_label(self,title,width,alignment,fontsize):
        label_princ = QtWidgets.QLabel(title, self)
        label_princ.setStyleSheet("border: "+str(width)+"px solid black;")
        label_princ.setAlignment(alignment)
        label_princ.setFont(QtGui.QFont('Times',fontsize))
        self.bigLayout.addWidget(label_princ)
    def add_file_browser_layer1(self):
        self.fileBrowser=FileBrowser('Open File')
        self.vLayout1.addWidget(self.fileBrowser)
        self.buttonAnayze = QtWidgets.QPushButton('Analyze')
        self.buttonAnayze.clicked.connect(self.analize_file)
        self.buttonAnayze.setMaximumWidth(200)
        self.vLayout1.addWidget(self.buttonAnayze)
        self.layout.addLayout(self.vLayout1)
    def add_submit_url_layer2(self):
        self.url_label= QtWidgets.QLineEdit( self)
        self.url_label.setPlaceholderText("Submit url or hash")

        self.url_label.setAlignment(Qt.AlignLeft | Qt.AlignHCenter)
        self.url_label.setStyleSheet("border: 1px solid black; background-color: rgb(229, 228, 226);")
        self.url_label.setFixedSize(400,400)

        buttonClose = QtWidgets.QPushButton('Submit')
        buttonClose.clicked.connect(self.action_submit)

        self.vLayout2.addWidget(self.url_label)
        self.vLayout2.addWidget(buttonClose)

        self.layout.addLayout(self.vLayout2)
    def action_submit(self):
        #https://www.travelandleisure.com/thmb/n4LZNPWDaJnGGl4jz988ms4u-Pk=/1500x0/filters:no_upscale():max_bytes(150000):strip_icc()/header-PARISPANDA1221-87f0c4cc46bf423ebcaf669c50912c3c.jpg

        print(self.url_label.text())
    def analize_file(self):
        try:
            file=self.fileBrowser.getPaths()[0]
        except:
            file='./table.py'

        # icon_1=QtWidgets.QLabel()
        # pixmap=QtGui.QPixmap('./icons/done.svg')
        # pixmap= pixmap.scaled(30, 30,Qt.KeepAspectRatio)
        # icon_1.setPixmap(pixmap)
        # icon_1.setAlignment(Qt.AlignLeft)
        # self.vLayout1.addWidget(icon_1)

        label_2 = QtWidgets.QLabel("Summary", self)
        label_2.setStyleSheet("border: 1px solid black;")
        label_2.setAlignment(Qt.AlignLeft | Qt.AlignHCenter)
        self.vLayout1.addWidget(label_2)

        tableWidget=QtWidgets.QTableWidget()
        cols=2
        rows=8
        tableWidget.setColumnCount(cols)
        tableWidget.setRowCount(rows)

        tableWidget.setAlternatingRowColors(True)
        tableWidget.setWindowTitle("File analysis")
        tableWidget.setHorizontalHeaderLabels(data[0].keys())
        [tableWidget.horizontalHeader().setSectionResizeMode(i,QtWidgets.QHeaderView.ResizeToContents) for i in range(cols-1)]
        tableWidget.horizontalHeader().setSectionResizeMode(cols-1,QtWidgets.QHeaderView.Stretch)
        self.vLayout1.addWidget(tableWidget)

        with open(file,'rb') as f:
            content=f.read()
        file_data={"Filename":file,"File type":"binary data","MD5":hashlib.md5(content).hexdigest(),"Sha256":hashlib.sha256(content).hexdigest(),"Sha512":hashlib.sha512(content).hexdigest(),"CRC32":hex(zlib.crc32(content) & 0xffffffff),"Yara":"None Matched","Score":"32"}
        for i, (k, v) in enumerate(file_data.items()):
            tableWidget.setItem(i,0,QtWidgets.QTableWidgetItem(k))
            tableWidget.setItem(i,1,QtWidgets.QTableWidgetItem(v))

        self.buttonAnayze.hide()
        self.fileBrowser.hide()

        self.bigLayout.addWidget(self.buttonClose)


import nibabel as nib
import matplotlib.pyplot as plt
#import cv2
import os
# https://www.kaggle.com/kmader/show-3d-nifti-images
import numpy as np
import tqdm as tqdm

data_path = '../dataset/wonjun_processing/imagesTr'
label_path = '../dataset/wonjun_processing/labelsTr'
data_file_list = sorted(os.listdir(data_path))
label_file_list = sorted(os.listdir(label_path))

ivh = 0
ich = 0

for d in range(len(data_file_list)):

    ct_path = os.path.join(data_path, data_file_list[d])
    ct = nib.load(ct_path)
    affine = ct.affine
    ct = ct.get_fdata()

    mask_path = os.path.join(label_path,label_file_list[d])
    mask = nib.load(mask_path)
    mask = mask.get_fdata()

    # ct data slice
    ct = ct[:512, :512, :32]
    mask = mask[:512, :512, :32]

    h, w, c = ct.shape

    if c < 32:
        z_padding = 32-c
        ct = np.pad(ct, ((0, 0), (0, 0), (0, z_padding)), 'constant')
        mask = np.pad(mask, ((0, 0), (0, 0), (0, z_padding)), 'constant')

    print(d)
    print(ct.shape)

    c_path = '../dataset/wonjun_processing/img/' + data_file_list[d][:3]
    m_path = '../dataset/wonjun_processing/label/' + label_file_list[d][:4]

    ct_t = nib.Nifti1Image(ct, affine)
    mask_t = nib.Nifti1Image(mask, affine)

    nib.save(ct_t, c_path)
    nib.save(mask_t, m_path)


from django.conf.urls.defaults import *
from django.conf import settings
from django.contrib import admin
from seishinkan.website.feeds import NewsFeed, TerminFeed

admin.autodiscover()

feeds = {
  'termine': TerminFeed,
  'news': NewsFeed,
}

urlpatterns = patterns('',
    (r'^i18n/', include('django.conf.urls.i18n')),
    (r'^verwaltung/doc/', include('django.contrib.admindocs.urls')),
    (r'^verwaltung/', include(admin.site.urls)),
    (r'^feed/termine/$', TerminFeed()),
    (r'^feed/news/$', NewsFeed()),
)

if 'rosetta' in settings.INSTALLED_APPS:
    urlpatterns += patterns('',
        url(r'^rosetta/', include('rosetta.urls')),
  )

# Simple Generic Views
urlpatterns += patterns('django.views.generic.simple',
    (r'^accounts/$', 'redirect_to', {'url': '/'}),
)

# Seishinkan Website Views
urlpatterns += patterns('seishinkan.website.views',
    (r'^$', 'index'),
    (r'^login/$', 'seishinkan_login'),
    (r'^lang/(.*)/$', 'set_lang'),
    (r'^logout/$', 'seishinkan_logout'),
    (r'^seite/(\d+)/$', 'index'),
    (r'^links/$', 'links'),
    (r'^kontakt/$', 'kontakt'),
    (r'^news/$', 'news'),
    (r'^news/(\d+)/$', 'news'),
    (r'^news/archiv/$', 'news'),
    (r'^termin/$', 'termin'),
    (r'^termin/(\d+)/$', 'termin'),
    (r'^termin/archiv/$', 'termin'),
    (r'^termine/$', 'termin'),
    (r'^termine/archiv/$', 'termin'),
    (r'^impressum/$', 'impressum'),
    (r'^info/$', 'info'),
    (r'^sysinfo/$', 'sysinfo'),
    (r'^videos/$', 'video'),
    (r'^bilder/$', 'picasa_albums'),
    (r'^bilder/(.+)/$', 'picasa_photos'),
    (r'^downloads/$', 'downloads'),
    # (r'^videos/(.+)/$', 'video'),
    (r'^email/$', 'mailinglist'),
    (r'^log/$', 'admin_log'),
    (r'^permissions/$', 'permissions'),
    (r'^graduierungen/$', 'graduierungen'),
    (r'^mitglieder/$', 'mitgliederlisten'),
    (r'^mitglieder/csv/$', 'mitglieder_csv'),
    (r'^mitglieder/csv/(\d+)/$', 'mitglieder_csv'),
    (r'^mitglieder/xls/$', 'mitglieder_xls'),
    (r'^mitglieder/xls/(\d+)/$', 'mitglieder_xls'),
    (r'^trainerliste/(\d+)/(\d+)/$', 'trainerliste_xls'),
    (r'^teilnehmerliste/(\d+)/(\d+)/$', 'teilnehmerliste_xls'),

    # dynamic_url muss am Ende stehen
    (r'^(.+)/$', 'dynamic_url'),
)

if settings.DEBUG:
    urlpatterns += patterns('',
        (r'^static/(?P<path>.*)$', 'django.views.static.serve', {'document_root': settings.MEDIA_ROOT}),
    )

handler404 = 'seishinkan.website.views.my_404'


# importing Numpy package
import numpy as np

# To declare symbol variables x and y
from sympy import symbols

 #  You can't use numpy arrays for symbolical calculations with sympy. Instead, use a sympy Matrix
#    (https://stackoverflow.com/questions/68589864/matrix-determinant-symbolic-in-python)
import sympy as sp

# creating a 3X3 Numpy matrix
n_array = np.array([[55, 25, 15],
                    [30, 44, 2],
                    [11, 45, 77]])

# Displaying the Matrix
print("Numpy Matrix is:")
print(n_array)

# calculating the determinant of matrix
det = np.linalg.det(n_array)

print("\nDeterminant of given 3X3 square matrix:")
print(int(det))

# FOR DETERMINANTS WITH SYMBOLS VARIABLES

# Problemas de clase 1 ejercicio 2

# Declaring symbol variables x and y
x = sp.symbols('x')
y = sp.symbols('y')
z = sp.symbols('z')

# creating a 3X3 sp matrix
matrix = sp.Matrix(([1, x, x**2],
                    [1, y, y**2],
                    [1, z, z**2]))

# Displaying the Matrix
print("Matrix is:")
print(matrix)

# calculating the determinant of sp nmatrix
det3 = sp.det(matrix)

print("\nDeterminant of given 3X3 square matrix:")
print((det3))


import numpy

from chainer import cuda
from chainer import optimizer

class RMSpropGraves(optimizer.Optimizer):
    """Alex Graves's RMSprop.

    See http://arxiv.org/abs/1308.0850

    """

    def __init__(self, lr=1e-4, alpha=0.95, momentum=0.9, eps=1e-4):
        # Default parameter values are the ones in the original paper.
        self.lr = lr
        self.alpha = alpha
        self.eps = eps
        self.momentum = momentum

    def init_state_cpu(self, param, grad):
        n = numpy.zeros_like(param)
        g = numpy.zeros_like(param)
        delta = numpy.zeros_like(param)
        return n, g, delta

    def init_state_gpu(self, param, grad):
        n = cuda.zeros_like(param)
        g = cuda.zeros_like(param)
        delta = cuda.zeros_like(param)
        return n, g, delta

    def update_one_cpu(self, param, grad, state):
        n, g, delta = state
        n *= self.alpha
        n += (1 - self.alpha) * grad * grad
        g *= self.alpha
        g += (1 - self.alpha) * grad
        delta *= self.momentum
        delta -= self.lr * grad / numpy.sqrt(n - g * g + self.eps)
        param += delta

    def update_one_gpu(self, param, grad, state):
        n, g, delta = state
        cuda.elementwise(
            'T grad, T lr, T alpha, T momentum, T eps',
            'T param, T avg_n, T avg_g, T delta',
            '''avg_n = alpha * avg_n + (1 - alpha) * grad * grad;
               avg_g = alpha * avg_g + (1 - alpha) * grad;
               delta = delta * momentum -
                   lr * grad * rsqrt(avg_n - avg_g * avg_g + eps);
               param += delta;''',
            'rmsprop_graves')(grad,
                              self.lr, self.alpha, self.momentum, self.eps,
                              param, n, g, delta)


import os
import traceback
from prefect import flow
from conf.config import DATA_DIR, DATASET_EXCEL_LINKS
from src.utils import write_local_to_parquet
from src.flows.pipeline_components import ingest_data_from_list_files, load_csv_dataset, save_dataset_to_csv, upload_to_gcs_bucket, write_data_google_bq

@flow(name="end_to_end_pipeline_from_http_to_bq",
      description="Flow that download the dataset in excel format given a list of links (excel), "
                  "Combine the data, save it to csv, convert to parquet and then upload to google cloud bucket",
      log_prints=True)
def end_to_end_pipeline_from_http_to_bq(filename_arr_path: list = DATASET_EXCEL_LINKS,
                                        name_output_dataset="global_terrorism_db"):
    """
    End to end pipeline
    Download files given an array of links > convert to csv > save to parquet format > upload to google cloud bucket
    > upload to google big query
    :param filename_arr_path:
    :param name_output_dataset:
    :return:
    """
    try:
        # 0. Check beforehand if there is CSV dataset so that we don't download again
        filename_csv = name_output_dataset + '.csv'
        path_filename_csv = DATA_DIR.joinpath(filename_csv)
        if not os.path.isfile(path_filename_csv):
            # 1. Download excel data from links (github)
            combined_data_df = ingest_data_from_list_files(filename_arr_path)
            # 2. Convert data to csv
            path_filename_csv = save_dataset_to_csv(combined_data_df, name_output_dataset)
        else:
            print("CSV file already exists")
        # 3. Load the csv dataset freshly created
        data_df = load_csv_dataset(path_filename_csv)
        # 4. save to parquet format
        dataset_parquet_path = os.path.splitext(path_filename_csv)[0] + ".parquet"
        write_local_to_parquet(data_df, dataset_parquet_path)
        # 5. Upload to GCS
        upload_to_gcs_bucket(dataset_parquet_path)
        # 6. Upload to Google Big query
        write_data_google_bq(data_df)

    except Exception as ex:
        print("Exception raised: ", ex)
        print(traceback.format_exc())
        exit(-1)

if __name__ == '__main__':
    name_output_data = "global_terrorism_db"
    filename_arr_path = DATASET_EXCEL_LINKS
    end_to_end_pipeline_from_http_to_bq(filename_arr_path=DATASET_EXCEL_LINKS, name_output_dataset=name_output_data)


# importint the necessary lirbraries

# import tensorflow.keras as kerasfrom __future__ import print_function
from __future__ import print_function

import keras
from keras.layers import Convolution2D
from keras.layers import Flatten
from keras.layers import Dense
from keras.layers import Dropout
from keras.layers import *
from keras.layers.normalization import BatchNormalization
from keras import optimizers
from keras.preprocessing.image import ImageDataGenerator
from keras.callbacks import ModelCheckpoint
from keras import initializers
from keras.preprocessing import image
from keras.preprocessing.image import img_to_array
from keras import layers
from keras.models import load_model
import matplotlib.image as mpimg

import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

import tensorflow as tf
from keras import backend as K
from keras.layers import Layer
from keras import activations
from keras import utils
from keras import models
from keras.models import Model
from keras.callbacks import ModelCheckpoint
from keras.optimizers import Adam, SGD

from sklearn.model_selection import train_test_split
from sklearn.preprocessing import LabelBinarizer
from os import listdir
import os
from imutils import paths
import numpy as np
import pickle
import matplotlib.pyplot as plt
import cv2
import random
import os

class Length(layers.Layer):
    """
    Compute the length of vectors. This is used to compute a Tensor that has the same shape with y_true in margin_loss.
    Using this layer as model's output can directly predict labels by using `y_pred = np.argmax(model.predict(x), 1)`
    inputs: shape=[None, num_vectors, dim_vector]
    output: shape=[None, num_vectors]
    """

    def call(self, inputs, **kwargs):
        return K.sqrt(K.sum(K.square(inputs), -1) + K.epsilon())

    def compute_output_shape(self, input_shape):
        return input_shape[:-1]

    def get_config(self):
        config = super(Length, self).get_config()
        return config

class Mask(layers.Layer):
    """
    Mask a Tensor with shape=[None, num_capsule, dim_vector] either by the capsule with max length or by an additional
    input mask. Except the max-length capsule (or specified capsule), all vectors are masked to zeros. Then flatten the
    masked Tensor.
    For example:
        ```
        x = keras.layers.Input(shape=[8, 3, 2])  # batch_size=8, each sample contains 3 capsules with dim_vector=2
        y = keras.layers.Input(shape=[8, 3])  # True labels. 8 samples, 3 classes, one-hot coding.
        out = Mask()(x)  # out.shape=[8, 6]
        # or
        out2 = Mask()([x, y])  # out2.shape=[8,6]. Masked with true labels y. Of course y can also be manipulated.
        ```
    """

    def call(self, inputs, **kwargs):
        if type(inputs) is list:  # true label is provided with shape = [None, n_classes], i.e. one-hot code.
            assert len(inputs) == 2
            inputs, mask = inputs
        else:  # if no true label, mask by the max length of capsules. Mainly used for prediction
            # compute lengths of capsules
            x = K.sqrt(K.sum(K.square(inputs), -1))
            # generate the mask which is a one-hot code.
            # mask.shape=[None, n_classes]=[None, num_capsule]
            mask = K.one_hot(indices=K.argmax(x, 1), num_classes=x.get_shape().as_list()[1])

        # inputs.shape=[None, num_capsule, dim_capsule]
        # mask.shape=[None, num_capsule]
        # masked.shape=[None, num_capsule * dim_capsule]
        masked = K.batch_flatten(inputs * K.expand_dims(mask, -1))
        return masked

    def compute_output_shape(self, input_shape):
        if type(input_shape[0]) is tuple:  # true label provided
            return tuple([None, input_shape[0][1] * input_shape[0][2]])
        else:  # no true label provided
            return tuple([None, input_shape[1] * input_shape[2]])

    def get_config(self):
        config = super(Mask, self).get_config()
        return config

def squash(vectors, axis=-1):
    """
    The non-linear activation used in Capsule. It drives the length of a large vector to near 1 and small vector to 0
    :param vectors: some vectors to be squashed, N-dim tensor
    :param axis: the axis to squash
    :return: a Tensor with same shape as input vectors
    """
    s_squared_norm = K.sum(K.square(vectors), axis, keepdims=True)
    scale = s_squared_norm / (1 + s_squared_norm) / K.sqrt(s_squared_norm + K.epsilon())
    return scale * vectors

class CapsuleLayer(layers.Layer):
    """
    The capsule layer. It is similar to Dense layer. Dense layer has `in_num` inputs, each is a scalar, the output of the
    neuron from the former layer, and it has `out_num` output neurons. CapsuleLayer just expand the output of the neuron
    from scalar to vector. So its input shape = [None, input_num_capsule, input_dim_capsule] and output shape = \
    [None, num_capsule, dim_capsule]. For Dense Layer, input_dim_capsule = dim_capsule = 1.

    :param num_capsule: number of capsules in this layer
    :param dim_capsule: dimension of the output vectors of the capsules in this layer
    :param routings: number of iterations for the routing algorithm
    """

    def __init__(self, num_capsule, dim_capsule, routings=3,
                 kernel_initializer='glorot_uniform',
                 **kwargs):
        super(CapsuleLayer, self).__init__(**kwargs)
        self.num_capsule = num_capsule
        self.dim_capsule = dim_capsule
        self.routings = routings
        self.kernel_initializer = initializers.get(kernel_initializer)

    def build(self, input_shape):
        assert len(input_shape) >= 3, "The input Tensor should have shape=[None, input_num_capsule, input_dim_capsule]"
        self.input_num_capsule = input_shape[1]
        self.input_dim_capsule = input_shape[2]

        # Transform matrix
        self.W = self.add_weight(shape=[self.num_capsule, self.input_num_capsule,
                                        self.dim_capsule, self.input_dim_capsule],
                                 initializer=self.kernel_initializer,
                                 name='W')

        self.built = True

    def call(self, inputs, training=None):
        # inputs.shape=[None, input_num_capsule, input_dim_capsule]
        # inputs_expand.shape=[None, 1, input_num_capsule, input_dim_capsule]
        inputs_expand = K.expand_dims(inputs, 1)

        # Replicate num_capsule dimension to prepare being multiplied by W
        # inputs_tiled.shape=[None, num_capsule, input_num_capsule, input_dim_capsule]
        inputs_tiled = K.tile(inputs_expand, [1, self.num_capsule, 1, 1])

        # Compute `inputs * W` by scanning inputs_tiled on dimension 0.
        # x.shape=[num_capsule, input_num_capsule, input_dim_capsule]
        # W.shape=[num_capsule, input_num_capsule, dim_capsule, input_dim_capsule]
        # Regard the first two dimensions as `batch` dimension,
        # then matmul: [input_dim_capsule] x [dim_capsule, input_dim_capsule]^T -> [dim_capsule].
        # inputs_hat.shape = [None, num_capsule, input_num_capsule, dim_capsule]
        inputs_hat = K.map_fn(lambda x: K.batch_dot(x, self.W, [2, 3]), elems=inputs_tiled)

        # Begin: Routing algorithm ---------------------------------------------------------------------#
        # The prior for coupling coefficient, initialized as zeros.
        # b.shape = [None, self.num_capsule, self.input_num_capsule].
        b = tf.zeros(shape=[K.shape(inputs_hat)[0], self.num_capsule, self.input_num_capsule])

        assert self.routings > 0, 'The routings should be > 0.'
        for i in range(self.routings):
            # c.shape=[batch_size, num_capsule, input_num_capsule]
            c = tf.nn.softmax(b, dim=1)

            # c.shape =  [batch_size, num_capsule, input_num_capsule]
            # inputs_hat.shape=[None, num_capsule, input_num_capsule, dim_capsule]
            # The first two dimensions as `batch` dimension,
            # then matmal: [input_num_capsule] x [input_num_capsule, dim_capsule] -> [dim_capsule].
            # outputs.shape=[None, num_capsule, dim_capsule]
            outputs = squash(K.batch_dot(c, inputs_hat, [2, 2]))  # [None, 10, 16]

            if i < self.routings - 1:
                # outputs.shape =  [None, num_capsule, dim_capsule]
                # inputs_hat.shape=[None, num_capsule, input_num_capsule, dim_capsule]
                # The first two dimensions as `batch` dimension,
                # then matmal: [dim_capsule] x [input_num_capsule, dim_capsule]^T -> [input_num_capsule].
                # b.shape=[batch_size, num_capsule, input_num_capsule]
                b += K.batch_dot(outputs, inputs_hat, [2, 3])
        # End: Routing algorithm -----------------------------------------------------------------------#

        return outputs

    def compute_output_shape(self, input_shape):
        return tuple([None, self.num_capsule, self.dim_capsule])

    def get_config(self):
        config = {
            'num_capsule': self.num_capsule,
            'dim_capsule': self.dim_capsule,
            'routings': self.routings
        }
        base_config = super(CapsuleLayer, self).get_config()
        return dict(list(base_config.items()) + list(config.items()))

def PrimaryCap(inputs, dim_capsule, n_channels, kernel_size, strides, padding):
    """
    Apply Conv2D `n_channels` times and concatenate all capsules
    :param inputs: 4D tensor, shape=[None, width, height, channels]
    :param dim_capsule: the dim of the output vector of capsule
    :param n_channels: the number of types of capsules
    :return: output tensor, shape=[None, num_capsule, dim_capsule]
    """
    output = layers.Conv2D(filters=dim_capsule * n_channels, kernel_size=kernel_size, strides=strides, padding=padding,
                           name='primarycap_conv2d')(inputs)
    outputs = layers.Reshape(target_shape=[-1, dim_capsule], name='primarycap_reshape')(output)
    return layers.Lambda(squash, name='primarycap_squash')(outputs)

"""
# The following is another way to implement primary capsule layer. This is much slower.
# Apply Conv2D `n_channels` times and concatenate all capsules
def PrimaryCap(inputs, dim_capsule, n_channels, kernel_size, strides, padding):
    outputs = []
    for _ in range(n_channels):
        output = layers.Conv2D(filters=dim_capsule, kernel_size=kernel_size, strides=strides, padding=padding)(inputs)
        outputs.append(layers.Reshape([output.get_shape().as_list()[1] ** 2, dim_capsule])(output))
    outputs = layers.Concatenate(axis=1)(outputs)
    return layers.Lambda(squash)(outputs)
"""

def CapsNet(input_shape, n_class, routings):
    """
    A Capsule Network on MNIST.
    :param input_shape: data shape, 3d, [width, height, channels]
    :param n_class: number of classes
    :param routings: number of routing iterations
    :return: Two Keras Models, the first one used for training, and the second one for evaluation.
            `eval_model` can also be used for training.
    """
    x = layers.Input(shape=input_shape)

    # Layer 1: Just a conventional Conv2D layer
    conv1 = layers.Conv2D(filters=128, kernel_size=9, strides=1, padding='valid', activation='relu', name='conv1')(x)

    # Layer 2: Conv2D layer with `squash` activation, then reshape to [None, num_capsule, dim_capsule]
    primarycaps = PrimaryCap(conv1, dim_capsule=8, n_channels=32, kernel_size=9, strides=2, padding='valid')

    # Layer 3: Capsule layer. Routing algorithm works here.
    digitcaps = CapsuleLayer(num_capsule=n_class, dim_capsule=16, routings=routings,
                             name='digitcaps')(primarycaps)

    # Layer 4: This is an auxiliary layer to replace each capsule with its length. Just to match the true label's shape.
    # If using tensorflow, this will not be necessary. :)
    out_caps = Length(name='capsnet')(digitcaps)

    # Decoder network.
    y = layers.Input(shape=(n_class,))
    masked_by_y = Mask()([digitcaps, y])  # The true label is used to mask the output of capsule layer. For training
    masked = Mask()(digitcaps)  # Mask using the capsule with maximal length. For prediction

    # Shared Decoder model in training and prediction
    decoder = models.Sequential(name='decoder')
    decoder.add(layers.Dense(512, activation='relu', input_dim=16 * n_class))
    decoder.add(layers.Dense(1024, activation='relu'))
    decoder.add(layers.Dense(np.prod(input_shape), activation='sigmoid'))
    decoder.add(layers.Reshape(target_shape=input_shape, name='out_recon'))

    # Models for training and evaluation (prediction)
    train_model = models.Model([x, y], [out_caps, decoder(masked_by_y)])
    eval_model = models.Model(x, [out_caps, decoder(masked)])

    # manipulate model
    noise = layers.Input(shape=(n_class, 16))
    noised_digitcaps = layers.Add()([digitcaps, noise])
    masked_noised_y = Mask()([noised_digitcaps, y])
    manipulate_model = models.Model([x, y, noise], decoder(masked_noised_y))
    return train_model, eval_model, manipulate_model

def margin_loss(y_true, y_pred):
    """
    Margin loss for Eq.(4). When y_true[i, :] contains not just one `1`, this loss should work too. Not test it.
    :param y_true: [None, n_classes]
    :param y_pred: [None, num_capsule]
    :return: a scalar loss value.
    """
    L = y_true * K.square(K.maximum(0., 0.9 - y_pred)) + \
        0.5 * (1 - y_true) * K.square(K.maximum(0., y_pred - 0.1))

    return K.mean(K.sum(L, 1))

def capsule_prediction(image_path):
    # define the model
    model, eval_model, manipulate_model = CapsNet(input_shape=(28, 28, 3),
                                                  n_class=10,
                                                  routings=3)
    eval_model.summary()
    dir_name = os.path.dirname(os.path.abspath(__file__))
    eval_model.load_weights(dir_name + "/best_weights_capsule_train.h5")

    # setting up predictions
    new_img = None
    try:
        new_img = image.load_img(image_path, target_size=(28, 28))
    except OSError:
        return {'error': 'could not identify image'}

    the_image = image.load_img(image_path)
    img = image.img_to_array(new_img)
    img = np.expand_dims(img, axis=0)
    img = img / 255

    prediction, y_recon = eval_model.predict(img)
    li = ["Bacterial_spot", "Early_blight", "healthy", "Late_blight", "Leaf_Mold", "mosaic_virus", "Septoria_leaf_spot",
          "spider_mite", "Target_Spot", "Yellow_Leaf_Curl"]
    # decode the results into a list of tuples (class, description, probability)
    # (one such list for each sample in the batch)
    class_name = li[prediction.argmax()]

    '''
    d = prediction.flatten()
    j = d.max()
    for index,item in enumerate(d):
        if item == j:
            class_name = li[index]
    '''

    # ploting image with predicted class name
    '''plt.figure(figsize=(4, 4))
    plt.imshow(the_image)
    plt.axis('off')
    plt.title(class_name)'''
    K.clear_session()
    return {'disease': class_name}


from extract_words import extract_words
import gi
gi.require_version('Gtk', '3.0')
gi.require_version('WebKit', '3.0')
from gi.repository import Gtk, Gdk, WebKit

class MainWindow(Gtk.Window):
    def __init__(self):

        Gtk.Window.__init__(self, title='My Window Title')
        self.AUTHEN_CODE = None  # authentication code for API of Shanbay.com
        self.set_title('English Reading Companion')
        self.set_default_size(800, 600)
        self.set_border_width(10)
        self.connect('delete-event', self.quit)
        self.connect('key-press-event', self.on_key_click)

        # Left List
        self.wl_store = Gtk.ListStore(str)
        self.wl_treeview = Gtk.TreeView(model=self.wl_store)
        self.wl_column = Gtk.TreeViewColumn('New [%d]' % len(self.wl_store), Gtk.CellRendererText(), text=0)
        self.wl_treeview.append_column(self.wl_column)
        self.wl_treeview.get_selection().set_mode(Gtk.SelectionMode.MULTIPLE)
        self.wl_treeview.override_background_color(Gtk.StateType.NORMAL,
                                                   Gdk.RGBA.from_color(Gdk.color_parse('CadetBlue3')))

        wl_scrolled_window = Gtk.ScrolledWindow()
        wl_scrolled_window.set_policy(
            Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)
        wl_scrolled_window.add(self.wl_treeview)

        # Middle List
        self.wm_store = Gtk.ListStore(str)
        try:
            with open('undetermined_words.dat', 'r') as f:
                for line in f:
                    self.wm_store.append([line.strip()])
        except FileNotFoundError:
            pass
        self.wm_treeview = Gtk.TreeView(model=self.wm_store)
        self.wm_column = Gtk.TreeViewColumn('Undertermined [%d]' % len(self.wm_store), Gtk.CellRendererText(), text=0)
        self.wm_treeview.append_column(self.wm_column)
        self.wm_treeview.get_selection().set_mode(Gtk.SelectionMode.MULTIPLE)
        self.wm_treeview.override_background_color(Gtk.StateType.NORMAL,
                                                   Gdk.RGBA.from_color(Gdk.color_parse('CadetBlue3')))

        wm_scrolled_window = Gtk.ScrolledWindow()
        wm_scrolled_window.set_policy(
            Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)
        wm_scrolled_window.add(self.wm_treeview)

        # Right List
        self.wr_store = Gtk.ListStore(str)
        self.wr_treeview = Gtk.TreeView(model=self.wr_store)
        self.wr_column = Gtk.TreeViewColumn('Mastered [%d]' % len(self.wr_store), Gtk.CellRendererText(), text=0)
        self.wr_treeview.append_column(self.wr_column)
        self.wr_treeview.get_selection().set_mode(Gtk.SelectionMode.MULTIPLE)
        self.wr_treeview.override_background_color(Gtk.StateType.NORMAL,
                                                   Gdk.RGBA.from_color(Gdk.color_parse('CadetBlue3')))

        wr_scrolled_window = Gtk.ScrolledWindow()
        wr_scrolled_window.set_policy(
            Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)
        wr_scrolled_window.add(self.wr_treeview)

        box_outer = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=10)
        # Left Part
        l_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=0)

        push_btn = Gtk.Button(label='Push To Shanbay.com')
        push_btn.connect('clicked', self.push_to_shanbay)
        l_box.pack_start(wl_scrolled_window, True, True, 0)
        l_box.pack_start(push_btn, False, False, 0)

        box_outer.pack_start(l_box, True, True, 0)

        # Middle Part
        m_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=0)

        m_btn_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=0)

        left_btn = Gtk.Button()
        left_btn.add(Gtk.Arrow(Gtk.ArrowType.LEFT, Gtk.ShadowType.NONE))
        left_btn.connect('clicked', self.word_move_left)

        right_btn = Gtk.Button()
        right_btn.add(Gtk.Arrow(Gtk.ArrowType.RIGHT, Gtk.ShadowType.NONE))
        right_btn.connect('clicked', self.word_move_right)

        m_btn_box.pack_start(left_btn, True, True, 0)
        m_btn_box.pack_start(right_btn, True, True, 0)

        import_btn = Gtk.Button(label='Import Words')
        import_btn.connect('clicked', self.import_words)
        m_box.pack_start(wm_scrolled_window, True, True, 0)
        m_box.pack_start(m_btn_box, False, False, 0)
        m_box.pack_start(import_btn, False, False, 0)

        box_outer.pack_start(m_box, True, True, 0)

        # Right Part
        r_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=0)
        save_btn = Gtk.Button(label='Save To File & Clear')
        save_btn.connect('clicked', self.save_to_file)
        r_box.pack_start(wr_scrolled_window, True, True, 0)
        r_box.pack_start(save_btn, False, False, 0)
        box_outer.pack_start(r_box, True, True, 0)

        self.add(box_outer)
        self.show_all()

    def word_move_left(self, *args):
        selection = self.wm_treeview.get_selection()
        model, paths = selection.get_selected_rows()

        for path in paths:
            self.wl_store.insert(0, model[path][:])
        for path in paths[::-1]:
            model.remove(model.get_iter(path))
        self.wl_treeview.set_cursor(Gtk.TreePath(0))
        self.wl_column.set_title('New [%d]' % len(self.wl_store))
        self.wm_column.set_title('Undetermined [%d]' % len(self.wm_store))

    def word_move_right(self, *args):
        selection = self.wm_treeview.get_selection()
        model, paths = selection.get_selected_rows()
        for path in paths:
            self.wr_store.insert(0, model[path][:])
        for path in paths[::-1]:
            model.remove(model.get_iter(path))
        self.wr_treeview.set_cursor(Gtk.TreePath(0))
        self.wr_column.set_title('Mastered [%d]' % len(self.wr_store))
        self.wm_column.set_title('Undetermined [%d]' % len(self.wm_store))

    def move_right_back(self, widget):
        model, paths = self.wr_treeview.get_selection().get_selected_rows()
        for path in paths:
            self.wm_store.insert(0, model[path][:])
        for path in paths[::-1]:
            model.remove(model.get_iter(path))
        self.wm_treeview.set_cursor(Gtk.TreePath(0))
        self.wr_column.set_title('Mastered [%d]' % len(self.wr_store))
        self.wm_column.set_title('Undetermined [%d]' % len(self.wm_store))

    def move_left_back(self, widget):
        model, paths = self.wl_treeview.get_selection().get_selected_rows()
        for path in paths:
            self.wm_store.insert(0, model[path][:])
        for path in paths[::-1]:
            model.remove(model.get_iter(path))
        self.wm_treeview.set_cursor(Gtk.TreePath(0))
        self.wl_column.set_title('New [%d]' % len(self.wl_store))
        self.wm_column.set_title('Undetermined [%d]' % len(self.wm_store))

    def save_to_file(self, widget):
        words_to_save = [row[:][0] for row in self.wr_store]
        if len(words_to_save) > 0:
            with open('known_words.dat', 'a') as f:
                f.write('\n'.join(words_to_save) + '\n')
        self.wr_store.clear()
        self.wr_column.set_title('Mastered [%d]' % len(self.wr_store))
        self.wm_column.set_title('Undetermined [%d]' % len(self.wm_store))

    def push_to_shanbay(self, widget):
        if self.AUTHEN_CODE is None:
            self.AUTHEN_CODE = self.authenticate(self)
        if self.AUTHEN_CODE is None:
            return
        words_to_push = [row[:][0] for row in self.wl_store]
        if len(words_to_push) > 0:
            with open('learning_words.dat', 'a') as f:
                f.write('\n'.join(words_to_push) + '\n')
        self.wl_store.clear()
        self.wl_column.set_title('New [%d]' % len(self.wl_store))
        self.wm_column.set_title('Undetermined [%d]' % len(self.wm_store))

    def import_words(self, widget):
        words_in_window = set([row[:][0] for row in self.wl_store] +
                              [row[:][0] for row in self.wm_store] +
                              [row[:][0] for row in self.wr_store])
        dialog = Gtk.FileChooserDialog("Select file to be opened", self,
                                       Gtk.FileChooserAction.OPEN,
                                       (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
                                        Gtk.STOCK_OK, Gtk.ResponseType.OK))
        dialog.show()

        response = dialog.run()
        if response == Gtk.ResponseType.OK:
            words = extract_words(dialog.get_filename(), words_in_window)
        elif response == Gtk.ResponseType.CANCEL:
            words = []
        dialog.destroy()
        for word in words:
            self.wm_store.append([word])
        self.wm_column.set_title('Undetermined [%d]' % len(self.wm_store))

    def on_key_click(self, widget, ev):
        ctrl = ev.state & Gdk.ModifierType.CONTROL_MASK

        if ctrl:
            if ev.keyval == Gdk.KEY_Left:
                self.move_right_back(widget)
            elif ev.keyval == Gdk.KEY_Right:
                self.move_left_back(widget)
            else:
                pass
        else:
            if ev.keyval == Gdk.KEY_Left:
                self.word_move_left(widget)
            elif ev.keyval == Gdk.KEY_Right:
                self.word_move_right(widget)
            else:
                pass

    def _javascript_console_message(self, view, message, line, sourceid):
        return True  # True prevents calling original handler

    def authenticate(self, *args, **kwargs):
        dialog = Gtk.Dialog("Authenticate", self, 0,
                            (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
                             Gtk.STOCK_OK, Gtk.ResponseType.OK))
        dialog.set_default_size(800, 600)
        box = dialog.get_content_area()
        box.set_homogeneous(False)

        webview = WebKit.WebView()
        webview.connect("console-message", self._javascript_console_message)
        webview.load_uri("https://api.shanbay.com/oauth2/authorize/?cliend_id=05623ce286a180e4e8c1&response_type=code&state=123")

        scrolled_window = Gtk.ScrolledWindow()
        scrolled_window.add(webview)
        scrolled_window.set_size_request(750, 650)
        box.add(scrolled_window)
        dialog.show_all()

        response = dialog.run()
        if response == Gtk.ResponseType.OK:
            uri = webview.get_uri()
        elif response == Gtk.ResponseType.CANCEL:
            uri = None
        dialog.destroy()
        self.AUTHEN_CODE = uri

    def quit(self, *args, **kwargs):
        with open('undetermined_words.dat', 'w') as f:
            f.write('\n'.join([row[:][0] for row in self.wm_store]))
        Gtk.main_quit(self, *args, **kwargs)

win = MainWindow()
Gtk.main()


import re

data = input()

pattern = r"^>{2}(?P<product>\w+)<<(?P<price>\d+(\.\d+)?)\!(?P<quantity>\d+)($|\s)"

product = []
total_price = 0

while not data == "Purchase":
    match = re.match(pattern, data)
    if match:
        obj = match.groupdict()
        product.append(obj["product"])
        total_price += float(obj["price"]) * int(obj["quantity"])

    data = input()

print("Bought furniture:")

for el in product:
    print(el)

print(f"Total money spend: {total_price:.2f}")


from pyspark.sql import SparkSession
from pyspark.sql import S
Logger.getLogger("org").setLevel(Level.ERROR)

sparkConf = newSparkConf()
sparkConf.set("spark.app.name", "My Application 1")
sparkConf.set("spark.master", "local[2]")

spark = SparkSession.builder()\
    .config(sparkConf)\
    .getOrCreate()

DDLString = "country String, weeknum Int, numinvoices Int, totalquantity Int, invoicevalue Double"

input = spark.read\
    .format("csv")\
    .schema(DDLString)\
    .option("path", "C:/Users/chnis/Downloads/Big Data/week11/windowdata.csv")\
    .load

input.write\
    .format("avro")\
    .partitionBy("country")\
    .mode("Overwrite")\
    .option("path", "C:/Users/chnis/Downloads/Big Data/week11/windowdata_output_avro")\
    .save()


from django import http
from django.http.response import Http404, HttpResponseForbidden
from rest_framework import viewsets, mixins, status
from rest_framework.response import Response
from rest_framework.decorators import action, api_view, permission_classes

from django.shortcuts import get_object_or_404

from .models import Answer, Enrollment, Offering, User, Exercise, UserAnswerSummary
from .serializers import AnswerSerializer, OfferingSerializer, UserAnswerSummarySerializer, UserSerializer, ExerciseSerializer
from .permissions import IsAdminOrSelf, IsAdminUser, IsEnrolledInOfferingOrIsStaff

class UserViewSet(viewsets.ModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer
    permission_classes = [IsAdminOrSelf]

class OfferingViewSet(viewsets.ReadOnlyModelViewSet):
    queryset = Offering.objects.all()
    serializer_class = OfferingSerializer
    permission_classes = [IsAdminUser]

@api_view(['GET'])
@permission_classes([IsAdminUser])
def get_enrolled_students(request, off_pk):
    students = User.objects.filter(enrollment__offering_id=off_pk)
    return Response(UserSerializer(students, many=True).data)

class ExerciseViewSet(mixins.CreateModelMixin, mixins.ListModelMixin, viewsets.GenericViewSet):
    serializer_class = ExerciseSerializer

    def get_permissions(self):
        permissions = [IsAdminUser]
        if self.action == 'list':
            permissions = [IsEnrolledInOfferingOrIsStaff]

        return [permission() for permission in permissions]

    def create(self, request, off_pk=None):
        offering = get_object_or_404(Offering, pk=off_pk)

        exercise, new = offering.exercise_set.update_or_create(slug=request.data['slug'],
            defaults={
                'url': request.data['url'],
                'type': request.data['type'],
                'topic': request.data['topic'],
                'group': request.data['group'],
            })

        s = ExerciseSerializer(exercise)
        return Response(s.data, status=status.HTTP_201_CREATED)

    def list(self, request, off_pk=None):
        offering = get_object_or_404(Offering, pk=off_pk)
        exercises_json = ExerciseSerializer(offering.exercise_set.all(), many=True)
        return Response(exercises_json.data)

class AnswerViewSet(viewsets.ModelViewSet):
    serializer_class = AnswerSerializer
    permission_classes = [IsEnrolledInOfferingOrIsStaff]

    def get_queryset(self):
        offering_pk = self.kwargs.get('off_pk')
        get_object_or_404(Offering, pk=offering_pk)
        exercise = get_object_or_404(Exercise, offering=offering_pk, slug=self.kwargs.get('ex_slug'))

        f = user_filter(self.request)

        return Answer.objects.filter(exercise=exercise, **f)

    def create(self, request, off_pk=None, ex_slug=None):
        get_object_or_404(Offering, pk=off_pk)
        exercise = get_object_or_404(Exercise, slug=ex_slug, offering=off_pk)
        if not exercise.allow_submissions:
            return HttpResponseForbidden()

        answer_data = {
            'user': request.user.pk,
            'exercise': exercise.pk,
            'test_results': request.data['test_results'],
            'student_input': request.data['student_input'],
            'points': request.data['points']
        }

        answer = AnswerSerializer(data=answer_data)
        if answer.is_valid():
            answer.save()
            return Response(answer.data, status=status.HTTP_201_CREATED)

        return Response(answer.errors, status=status.HTTP_400_BAD_REQUEST)

    def list_answers_by_student(self, request, off_pk, ex_slug, student_pk):
        get_object_or_404(Offering, pk=off_pk)
        exercise = get_object_or_404(Exercise, offering=off_pk, slug=ex_slug)

        filters = {
            'exercise': exercise
        }

        if self.request.user.is_staff:
            filters['user'] = self.kwargs.get('student_pk')
        elif self.request.user.pk != int(student_pk):
            return HttpResponseForbidden()

        answers = Answer.objects.filter(**filters)
        answers_json = AnswerSerializer(answers, many=True)

        return Response(answers_json.data, status=status.HTTP_200_OK)

def user_filter(request):
    user_pk = request.user.pk
    request_user_pk = request.GET.get('user')
    if request_user_pk and request_user_pk != user_pk and request.user.is_staff:
        user_pk = request_user_pk
    filters = {}
    if not request.user.is_staff or request_user_pk:
        # Can only see own summaries if not admin
        filters['user__pk'] = user_pk
    return filters

@api_view(['GET'])
@permission_classes([IsEnrolledInOfferingOrIsStaff])
def get_latest_answer_by_student(request, off_pk, ex_slug, student_pk):
    offering = get_object_or_404(Offering, pk=off_pk)
    try:
        answer = Answer.objects.filter(
            user__pk=student_pk,
            exercise__slug=ex_slug,
            exercise__offering=offering,
        ).latest('pk')
    except Answer.DoesNotExist:
        raise Http404
    return Response(AnswerSerializer(answer).data)

@api_view(['GET'])
@permission_classes([IsEnrolledInOfferingOrIsStaff])
def get_answer(request, off_pk, ex_slug, ans_pk):
    get_object_or_404(Offering, pk=off_pk)
    answer = get_object_or_404(Answer, pk=ans_pk, **user_filter(request))
    return Response(AnswerSerializer(answer).data)

@api_view(['GET'])
@permission_classes([IsEnrolledInOfferingOrIsStaff])
def get_previous_answer(request, off_pk, ex_slug, ans_pk):
    get_object_or_404(Offering, pk=off_pk)

    filters = user_filter(request)
    try:
        answer = Answer.objects.filter(
            exercise__slug=ex_slug,
            pk__lt=ans_pk,
            **filters).latest('pk')
    except Answer.DoesNotExist:
        raise Http404()
    return Response(AnswerSerializer(answer).data)

@api_view(['GET'])
@permission_classes([IsEnrolledInOfferingOrIsStaff])
def get_next_answer(request, off_pk, ex_slug, ans_pk):
    get_object_or_404(Offering, pk=off_pk)

    filters = user_filter(request)
    try:
        answer = Answer.objects.filter(
            exercise__slug=ex_slug,
            pk__gt=ans_pk,
            **filters).earliest('pk')
    except Answer.DoesNotExist:
        raise Http404()
    return Response(AnswerSerializer(answer).data)

@api_view(['GET'])
@permission_classes([IsEnrolledInOfferingOrIsStaff])
def list_summaries(request, off_pk):
    offering = get_object_or_404(Offering, pk=off_pk)

    filters = user_filter(request)
    all_summaries = UserAnswerSummary.objects.filter(**filters).filter(exercise__offering=offering).prefetch_related('exercise')
    all_summaries_json = UserAnswerSummarySerializer(all_summaries, many=True)

    return Response(all_summaries_json.data, status=status.HTTP_200_OK)

@api_view(['GET'])
@permission_classes([IsEnrolledInOfferingOrIsStaff])
def list_summaries_for_exercise(request, off_pk, ex_slug):
    get_object_or_404(Offering, pk=off_pk)
    exercise = get_object_or_404(Exercise, offering=off_pk, slug=ex_slug)

    filters = user_filter(request)
    filters['exercise'] = exercise
    all_summaries = UserAnswerSummary.objects.filter(**filters).prefetch_related('exercise')
    all_summaries_json = UserAnswerSummarySerializer(all_summaries, many=True)

    return Response(all_summaries_json.data, status=status.HTTP_200_OK)

@api_view(['GET'])
@permission_classes([IsAdminUser])
def list_students_that_tried_exercise(request, off_pk, ex_slug):
    get_object_or_404(Offering, pk=off_pk)
    exercise = get_object_or_404(Exercise, offering=off_pk, slug=ex_slug)

    all_students = User.objects.filter(answer__exercise__slug=ex_slug).distinct()
    all_students_json = UserSerializer(all_students, many=True)

    return Response(all_students_json.data, status=status.HTTP_200_OK)

@api_view(['GET'])
@permission_classes([IsAdminUser])
def activate_exercise(request, off_pk, ex_slug):
    get_object_or_404(Offering, pk=off_pk)
    exercise = get_object_or_404(Exercise, offering=off_pk, slug=ex_slug)
    exercise.allow_submissions = True
    exercise.save()
    return Response('OK', status=status.HTTP_200_OK)

@api_view(['GET'])
@permission_classes([IsAdminUser])
def deactivate_exercise(request, off_pk, ex_slug):
    get_object_or_404(Offering, pk=off_pk)
    exercise = get_object_or_404(Exercise, offering=off_pk, slug=ex_slug)
    exercise.allow_submissions = False
    exercise.save()
    return Response('OK', status=status.HTTP_200_OK)


import tkinter
import time
from AlgorithmSimulator.config import general_setting
from AlgorithmSimulator.model import sort

class View():

    def __init__(self, master):
        'UI関連のオブジェクト生成'

        # 各種設定
        self.drawn_obj = []

        # キャンバスのサイズを決定
        self.canvas_width = general_setting.CANVAS_WIDTH
        self.canvas_height = general_setting.CANVAS_HEIGHT

        #エラー処理用メッセージ
        self.message = ''

        # 情報表示用のフレームを作成
        self.canvas_frame = tkinter.Frame(
            master,
        )
        self.canvas_frame.grid(column=1, row=1)

        # 操作用ウィジェットのフレームを作成
        self.operation_frame = tkinter.Frame(
            master,
        )
        self.operation_frame.grid(column=2, row=1, padx=10)

        # キャンバスの生成と配置
        self.canvas = tkinter.Canvas(
            self.canvas_frame,
            width=self.canvas_width,
            height=self.canvas_height,
        )
        self.canvas.pack()

        # ラベルの生成と配置
        self.text = tkinter.StringVar()
        self.text.set("Please press Start button")

        self.label = tkinter.Label(
            self.canvas_frame,
            textvariable=self.text,
        )
        self.label.pack()

        # テキストボックス配置用のフレームの生成と配置
        max_w = self.canvas_width // 2
        max_h = self.canvas_height // 2

        # データ数が画面サイズに収まるようにコントロール
        # キャンバスの幅 / 2 or キャンバスの高さ / 2の小さいほうを選択
        if max_w < max_h:
            max = max_w
        else:
            max = max_h

        self.text_frame = tkinter.LabelFrame(
            self.operation_frame,
            text="Number of data（Max" + str(max) + "）"
        )
        self.text_frame.pack(ipadx=10, pady=10)

        self.entry = tkinter.Entry(
            self.text_frame,
            width=4
        )
        self.entry.pack()

        # ラジオボタン配置用のフレームの生成と配置
        self.radio_frame = tkinter.LabelFrame(
            self.operation_frame,
            text="Algorithm"
        )
        self.radio_frame.pack(ipadx=10, pady=10)

        # チェックされているボタン取得用のオブジェクト生成
        self.sort = tkinter.IntVar()
        self.sort.set(sort.Sort.QUICK_SORT)

        # アルゴリズム選択用のラジオボタンを作成し配置
        self.selection_button = tkinter.Radiobutton(
            self.radio_frame,
            variable=self.sort,
            text="Selection Sort",
            value=sort.Sort.SELECTION_SORT
        )
        self.selection_button.pack()

        self.quick_button = tkinter.Radiobutton(
            self.radio_frame,
            variable=self.sort,
            text="Quick Sort",
            value=sort.Sort.QUICK_SORT
        )
        self.quick_button.pack()

        self.merge_button = tkinter.Radiobutton(
            self.radio_frame,
            variable=self.sort,
            text="Merge Sort",
            value=sort.Sort.MERGE_SORT
        )
        self.merge_button.pack()

        self.insertion_button = tkinter.Radiobutton(
            self.radio_frame,
            variable=self.sort,
            text="Insertion Sort",
            value=sort.Sort.INSERTION_SORT
        )
        self.insertion_button.pack()

        self.heap_button = tkinter.Radiobutton(
            self.radio_frame,
            variable=self.sort,
            text="Heap Sort",
            value=sort.Sort.HEAP_SORT
        )
        self.heap_button.pack()

       # 開始ボタンの生成と配置
        self.button = tkinter.Button(
            self.operation_frame,
            text="Start",
        )
        self.button.pack()

    def start(self, n):
        '背景を描画'

        # データ数をセット
        self.num = n

        # １つのデータを表す線の幅を決定
        self.line_width =  self.canvas_width / self.num

        # データの値１の線の高さを決定
        # データの値が N の時、線の高さは self.line_height * N となる
        self.line_height =  self.canvas_height / self.num

        # データ数が多すぎて描画できない場合
        if self.line_width < 2 or self.line_height < 2:
            return False

        # 背景位置調整用（中央寄せ）
        self.offset_x = int(
            (self.canvas.winfo_width() - self.line_width * self.num) / 2
        )
        self.offset_y = int(
            (self.canvas.winfo_height() - self.line_height * self.num + 1) / 2
        )

        # 一旦描画しているデータを削除
        for obj in self.drawn_obj:
            self.canvas.delete(obj)

        # 削除したので描画済みデータリストは空にする
        self.drawn_obj = []

        # 事前に背景オブジェクトを削除
        self.canvas.delete("background")

        # 背景を描画
        self.canvas.create_rectangle(
            self.offset_x,
            self.offset_y,
            int(self.offset_x + self.line_width * self.num),
            int(self.offset_y + self.line_height * self.num),
            width=0,
            fill="#000000",
            tag="background"
        )

        # 即座に描画を反映
        self.canvas.update()

        return True

    def get_algorithm(self):
        'ソートアルゴリズム取得'

        return self.sort.get()

    def get_data_num(self):
        'データ数取得'

        return int(self.entry.get())

    def draw_data(self, data):
        'データの並びを線としてを描画'

        # 一旦描画しているデータを削除
        for obj in self.drawn_obj:
            self.canvas.delete(obj)

        # 削除したので描画済みデータリストは空にする
        self.drawn_obj = []

        # リストの数字を矩形で描画
        i = 0
        for value in data:
            # 矩形の始点と終点を決定

            # データ位置から矩形の横方向座標を決定
            x1 = int(self.offset_x + i * self.line_width)
            x2 = int(self.offset_x + (i + 1) * self.line_width)

            # データの値から矩形の縦方向座標を決定
            y1 = int(self.offset_y + self.line_height * (self.num - value))
            y2 = int(self.offset_y + self.line_height * self.num)

            # 後から消せるようにtagをつけておく
            tag = "line" + str(i)
            self.drawn_obj.append(tag)

            # 長方形を描画
            self.canvas.create_rectangle(
                x1, y1,
                x2, y2,
                tag=tag,
                fill="#CC0000",
                width=1
            )

            i += 1

        # 描画を即座に反映
        self.canvas.update()

        # WAIT秒分だけスリープ
        time.sleep(general_setting.WAIT)

    def update_message(self, text):
        'メッセージを更新してラベルに表示'

        # ラベルに描画する文字列をセット
        self.text.set(text)

        # 描画を即座に反映
        self.label.update()


# Line requirements:
# Apply Google CLI Syntax for required and optional args
# https://developers.google.com/style/code-syntax

import os
import re

current_dir = os.path.dirname(os.path.realpath(__file__))
# os.chdir(current_dir)

IGNORE_VARIABLES = ["flags"] # [flags]

def _replace_array(line: str):
    '''
    Convert [value][,[value]] -> VALUE...
    '''
    matches = re.findall(r'\[,\[(.*?)\]\]', line) # ['name', 'receiver']
    if matches:
        for variable_name in matches:
            if variable_name in IGNORE_VARIABLES: continue
            line = line.replace(f'[{variable_name}][,[{variable_name}]]', f"{variable_name.upper().replace('-', '_')}...")
    return line

def _replace_standard(line: str):
    '''
    Convert [value] -> VALUE
    '''
    matches = re.findall(r'\[(.*?)\]', line) # ['name', 'receiver']
    if matches:
        for variable_name in matches:
            if variable_name in IGNORE_VARIABLES: continue
            line = line.replace(f'[{variable_name}]', f'{variable_name.upper().replace("-", "_")}')
    return line

def convert_commands_to_google_format(chain: str, debug: bool = False):

    for root, dirs, files in os.walk(chain):

        if 'cmd' in root or '/cli' in root:
            if debug: print(root, files)

            for file in files:
                if not file.endswith(".go"):
                    continue

                file_path = os.path.join(root, file)
                with open(file_path, 'r') as f:
                    lines = f.readlines()

                with open(file_path, 'w') as f:
                    for line in lines:
                        if re.search(r'Use:.*\"', line):
                            line = _replace_array(line)
                            line = _replace_standard(line)
                        f.write(line)


#Faça um programa para a leitura de duas notas parciais de um aluno. O programa deve calcular a média alcançada por aluno e apresentar:
#A mensagem "Aprovado", se a média alcançada for maior ou igual a sete;
#A mensagem "Reprovado", se a média for menor do que sete;
#A mensagem "Aprovado com Distinção", se a média for igual a dez.
n1 = float(input("Informe primeira nota: "))
n2 = float(input("Informe segunda nota: "))
m = (n1 + n2) / 2
if (m < 7):
	print("A média do aluno é: {:.2f} e ele está REPROVADO!".format(m))
elif((m >= 7) and (m < 10)):
	print("A média do aluno é: {:.2f} e ele está APROVADO!".format(m))
else:
	print("A média do aluno é: {:.2f} e ele está APROVADO COM DISTINÇÃO!".format(m))