#!/usr/bin/env python

# Any copyright is dedicated to the Public Domain.
# https://creativecommons.org/publicdomain/zero/1.0/

# Written by Francois Fleuret <francois@fleuret.org>

import torch

from torch import nn
from torch.nn import functional as F
from torch import optim
from torchvision import datasets

######################################################################

cifar_train_set = datasets.CIFAR10('./data/cifar10/', train = True, download = True)
train_input = torch.from_numpy(cifar_train_set.data).permute(0, 3, 1, 2).float()
train_targets = torch.tensor(cifar_train_set.targets, dtype = torch.int64)

mu, std = train_input.mean(), train_input.std()
train_input.sub_(mu).div_(std)

######################################################################

class ResNetBlock(nn.Module):
    def __init__(self, nb_channels, kernel_size,
                 skip_connections = True, batch_normalization = True):
        super().__init__()

        self.conv1 = nn.Conv2d(nb_channels, nb_channels,
                               kernel_size = kernel_size,
                               padding = (kernel_size - 1) // 2)

        self.bn1 = nn.BatchNorm2d(nb_channels)

        self.conv2 = nn.Conv2d(nb_channels, nb_channels,
                               kernel_size = kernel_size,
                               padding = (kernel_size - 1) // 2)

        self.bn2 = nn.BatchNorm2d(nb_channels)

        self.skip_connections = skip_connections
        self.batch_normalization = batch_normalization

    def forward(self, x):
        y = self.conv1(x)
        if self.batch_normalization: y = self.bn1(y)
        y = F.relu(y)
        y = self.conv2(y)
        if self.batch_normalization: y = self.bn2(y)
        if self.skip_connections: y = y + x
        y = F.relu(y)

        return y

######################################################################

class ResNet(nn.Module):

    def __init__(self, nb_residual_blocks, nb_channels,
                 kernel_size = 3, nb_classes = 10,
                 skip_connections = True, batch_normalization = True):
        super().__init__()

        self.conv = nn.Conv2d(3, nb_channels,
                              kernel_size = kernel_size,
                              padding = (kernel_size - 1) // 2)
        self.bn = nn.BatchNorm2d(nb_channels)

        self.resnet_blocks = nn.Sequential(
            *(ResNetBlock(nb_channels, kernel_size, skip_connections, batch_normalization)
              for _ in range(nb_residual_blocks))
        )

        self.fc = nn.Linear(nb_channels, nb_classes)

    def forward(self, x):
        x = F.relu(self.bn(self.conv(x)))
        x = self.resnet_blocks(x)
        x = F.avg_pool2d(x, 32).view(x.size(0), -1)
        x = self.fc(x)
        return x

######################################################################

def get_stats(skip_connections, batch_normalization, nb_samples = 100):

    model = ResNet(nb_residual_blocks = 30, nb_channels = 10,
                   kernel_size = 3, nb_classes = 10,
                   skip_connections = skip_connections, batch_normalization = batch_normalization)

    criterion = nn.CrossEntropyLoss()

    monitored_parameters = [ b.conv1.weight for b in model.resnet_blocks ]

    result = torch.empty(len(monitored_parameters), nb_samples)

    for n in range(nb_samples):
        output = model(train_input[n:n+1])
        loss = criterion(output, train_targets[n:n+1])
        model.zero_grad()
        loss.backward()
        for d, p in enumerate(monitored_parameters):
            result[d, n] = p.grad.norm()

    return result

######################################################################

import matplotlib.pyplot as plt
import numpy as np

fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)

ax.set_xlabel('Depth', labelpad = 10)
ax.set_yscale('log')
ax.set_ylabel('Gradient norm', labelpad = 10)

graph_param = [
    ( True,   True, 'tab:red', 'SC+BN' ),
    ( True,  False, 'tab:green', 'SC' ),
    ( False,  True, 'tab:blue', 'BN' ),
    ( False, False, 'tab:orange', 'None' ),
]

for sc, bn, color, label in graph_param:
    print('Computing ' + label)
    x = get_stats(skip_connections = sc, batch_normalization = bn)
    ax.plot(x.mean(1).numpy(), color = color, label = label)

ax.legend(frameon = False)

plt.show()

######################################################################


# uncompyle6 version 3.7.4
# Python bytecode 3.4 (3310)
# Decompiled from: Python 3.6.9 (default, Apr 18 2020, 01:56:04)
# [GCC 8.4.0]
# Embedded file name: /home/sbo/lib/python3.4/site-packages/vai/models/Configuration.py
# Compiled at: 2015-05-02 14:07:56
# Size of source mod 2**32: 2141 bytes
import copy, os, json, locale
from .. import paths

class Configuration:
    DEFAULTS = {'colors.syntax_schema': 'default',
     'colors.status_bar.fg': 'yellow',
     'colors.status_bar.bg': 'blue',
     'colors.side_ruler.fg': 'cyan',
     'colors.side_ruler.bg': 'transparent',
     'icons.collection': 'unicode1'}
    _instance = None
    _filename = None
    flags = {'has_wide_ncurses': True}

    @classmethod
    def instance(cls):
        if cls._instance is None:
            cls._instance = cls()
        return cls._instance

    @classmethod
    def setFilename(cls, filename):
        if cls._instance is not None:
            if self._filename is not None:
                raise Exception('Configuration already initialized')
        cls._filename = filename

    @classmethod
    def filename(cls):
        if cls._filename is None:
            cls._filename = paths.configFile()
        return cls._filename

    @classmethod
    def save(cls):
        config = cls.instance()
        with open(cls._filename, 'w') as (f):
            f.write(json.dumps(config._config_dict, indent=4, sort_keys=True))

    def __init__(self):
        cls = self.__class__
        filename = cls.filename()
        try:
            with open(filename, 'r') as (f):
                merge_data = json.loads(f.read())
        except:
            merge_data = {}

        self._config_dict = copy.deepcopy(Configuration.DEFAULTS)
        self._config_dict.update(merge_data)

    def __getitem__(self, key):
        return self._config_dict[key]

    @classmethod
    def get(cls, key):
        if key == 'icons.collection' and locale.getpreferredencoding(False) != 'UTF-8' or not cls.flags.get('has_wide_ncurses'):
            return 'ascii'
        return cls.instance()[key]


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

import numpy

import matplotlib.pyplot as plt

from ..core.frequency import FrequencyAxis
from ..core.dfunction import DFunction
from ..core.managers import EnergyUnitsManaged
from ..core.units import cm2int

class AbsSpectrumBase(DFunction, EnergyUnitsManaged):
    """Provides basic container for absorption spectrum

    """

    def __init__(self, axis=None, data=None):
        super().__init__()
        self.axis = axis
        self.data = data

    def set_axis(self, axis):
        """Sets axis atribute

        Parameters
        ----------

        axis : FrequencyAxis object
            Frequency axis object. This object has managed energy units

        """
        self.axis = axis

    def set_data(self, data):
        """Sets data atribute

        Parameters
        ----------

        data : array like object (numpy array)
            Sets the data of the absorption spectrum

        """
        self.data = data

    def set_by_interpolation(self, x, y, xaxis="frequency"):

        from scipy import interpolate

        if xaxis == "frequency":

            om = self.convert_2_internal_u(x)

        elif xaxis == "wavelength":
            # convert to internal (nano meters) units of wavelength

            # convert to energy (internal units)
            # to cm
            om = 1.0e-7*x
            # to 1/cm
            om = 1.0/om
            # to 1/fs
            om = om*cm2int

        if om[1] > om[2]:
            # reverse order
            om = numpy.flip(om,0)
            y = numpy.flip(y,0)

        # equidistant points on the x-axis
        omin = numpy.amin(om)
        omax = numpy.amax(om)
        length = om.shape[0]
        step = (omax-omin)/length

        # new frequency axis
        waxis = FrequencyAxis(omin, length, step)

        # spline interpolation
        tck = interpolate.splrep(om, y, s=0)
        ynew = interpolate.splev(waxis.data, tck, der=0)

        # setting the axis and data
        self.axis = waxis
        self.data = ynew

    def clear_data(self):
        """Sets spectrum data to zero

        """
        shp = self.data.shape
        self.data = numpy.zeros(shp, dtype=numpy.float64)

    def normalize2(self,norm=1.0):
        """Normalizes spectrum to a given value

        """
        mx = numpy.max(self.data)
        self.data = norm*self.data/mx

    def normalize(self):
        """Normalization to one

        """
        self.normalize2(norm=1.0)

    def subtract(self, val):
        """Subtracts a value from the spectrum to shift its base line

        """
        self.data -= val

    def add_to_data(self, spect):
        """Performs addition on the data.

        Expects a compatible object holding absorption spectrum
        and adds its data to the present absorption spectrum.

        Parameters
        ----------

        spect : spectrum containing object
            This object should have a compatible axis and some data

        """

        if self.axis is None:
            self.axis = spect.axis.copy()

        if not numpy.allclose(spect.axis.data, self.axis.data):
            numpy.savetxt("spect_data_wrong.dat", spect.axis.data)
            numpy.savetxt("self_data_wrong.dat", self.axis.data)
            raise Exception("Incompatible axis")

        if self.data is None:
            self.data = numpy.zeros(len(spect.data),
                                    dtype=spect.axis.data.dtype)

        self.data += spect.data

    def load_data(self, filename, ext=None, replace=False):
        """Load the spectrum from a file

        Uses the load method of the DFunction class to load the absorption
        spectrum from a file. It sets the axis type to 'frequency', otherwise
        no changes to the inherited method are applied.

        Parameters
        ----------

        """
        super().load_data(filename, ext=ext, axis='frequency', replace=replace)

    #save method is inherited from DFunction

    def plot(self, **kwargs):
        """ Plotting absorption spectrum using the DFunction plot method

        """
        if "ylabel" not in kwargs:
            ylabel = r'$\alpha(\omega)$ [a.u.]'
            kwargs["ylabel"] = ylabel

        fig = super().plot(**kwargs)
        if fig is not None:
            return fig

    def gaussian_fit(self, N=1, guess=None, plot=False, Nsvf=251):
        from scipy.signal import savgol_filter
        from scipy.interpolate import UnivariateSpline
        """Performs a Gaussian fit of the spectrum based on an initial guess

        Parameters
        ----------

        Nsvf : int
            Length of the Savitzky-Golay filter window (odd integer)

        """
        x = self.axis.data
        y = self.data

        if guess is None:

            raise Exception("Guess is required at this time")
            # FIXME: create a reasonable guess
            guess = [1.0, 11000.0, 300.0, 0.2,
                     11800, 400, 0.2, 12500, 300]

            #
            # Find local maxima and guess their parameters
            #

            # Fit with a given number of Gaussian functions

            if not self._splines_initialized:
                self._set_splines()

            # get first derivative and smooth it
            der = self._spline_r.derivative()
            y1 = der(x)
            y1sm = savgol_filter(y1,Nsvf,polyorder=3)

            # get second derivative and smooth it
            y1sm_spl_der = UnivariateSpline(x,y1sm,s=0).derivative()(x)
            y2sm = savgol_filter(y1sm_spl_der,Nsvf,polyorder=3)

            # find positions of optima by looking for zeros of y1sm

            # isolate maxima by looking at the value of y2sm

            #plt.plot(x, der(x))
            #plt.plot(x, y1sm)
            plt.plot(x, y2sm)
            plt.show()

        def funcf(x, *p):
            return _n_gaussians(x, N, *p)

        # minimize, leastsq,
        from scipy.optimize import curve_fit
        popt, pcov = curve_fit(funcf, x, y, p0=guess)

        if plot:

            plt.plot(x,y)
            plt.plot(x,_n_gaussians(x, N, *popt))
            for i in range(N):
                a = popt[3*i]
                print(i, a)
                b = popt[3*i+1]
                c = popt[3*i+2]
                y = _gaussian(x, a, b, c)
                plt.plot(x, y,'-r')
            plt.show()

        # FIXME: Create a readable report

        return popt, pcov

#    def convert_to_energy(self, eaxis, units):
#        """
#
#        """
#
#        if units == "nm":
#            x = self.axis.data
#            y = self.data
#
#            # to cm
#            x = 1.0e-7*x
#            # to 1/cm
#            x = 1.0/x
#            # to rad/fs
#            x = x*cm2int
#
#            xn = numpy.zeros(x.shape, dtype=x.dtype)
#            yn = numpy.zeros(y.shape, dtype=y.dtype)
#
#            for i in range(len(x)):
#                xn[i] = x[len(x)-i-1]
#                yn[i] = y[len(x)-i-1]
#
#            # spline it
#
#            # evaluate at points if eaxis
#

def _gaussian(x, height, center, fwhm, offset=0.0):
    """Gaussian function with a possible offset

    Parameters
    ----------

    x : float array
        values to calculate Gaussian function at

    height : float
        height of the Gaussian at maximum

    center : float
        position of maximum

    fwhm : float
        full width at half maximum of the Gaussian function

    offset : float
        the value at infinity; effectively an offset on the y-axis

    """

    return height*numpy.exp(-(((x - center)**2)*4.0*numpy.log(2.0))/
                            (fwhm**2)) + offset

def _n_gaussians(x, N, *params):
    """Sum of N Gaussian functions plus an offset from zero

    Parameters
    ----------

    x : float
        values to calculate Gaussians function at

    N : int
        number of Gaussians

    params : floats
        3*N + 1 parameters corresponding to height, center, fwhm  for each
        Gaussian and one value of offset

    """
    n = len(params)
    k = n//3

    if (k*3 == n) and (k == N):

        res = 0.0
        pp = numpy.zeros(3)
        for i in range(k):
            pp[0:3] = params[3*i:3*i+3]
            #pp[3] = 0.0
            arg = tuple(pp)
            res += _gaussian(x, *arg)
        res += params[n-1] # last parameter is an offset
        return res

    else:
        raise Exception("Inconsistend number of parameters")


#! /usr/bin/env python3
# -*- coding: utf-8 -*-
###
###   Goal:
###      Produce AGP files summarizing scaffolding results of DeCoSTAR
###
###   INPUT:
###      1- New adjacencies file
###         (27avian_dataset/results/decostar/ADseq+scaff_Boltz_kT0.1/DeCoSTAR_27avian_ADseq+scaff_Boltz_kT0.1_Linear_0.1_M_new_adjacencies_with_scaff)
###      2- Genome assemblies directory
###         (27avian_dataset/data/INPUT_DATA/FASTA/SCAFF)
###      3- prefix file
###         (DeCoSTAR_27avian_ADseq+scaff_Boltz_kT0.1_Lin0.1_M2_)
###      4- AGP files path/prefix
###         (27avian_dataset/results/AGP/SCAFF/)
###
###   OUTPUT:
###      - AGP files summarizing scaffolding results of DeCoSTAR
###
###   Name: create_AGP_from_new_adjacencies.py    Author: Yoann Anselmetti
###   Creation date: 2018/06/11                   Last modification: 2020/11/04
###

from sys import argv
from re import search
from os import close, path, listdir, makedirs
from datetime import datetime
import errno
from collections import namedtuple   #New in version 2.6
from Bio import SeqIO

def mkdir_p(dir_path):
   try:
      makedirs(dir_path)
   except OSError as exc: # Python >2.5
      if exc.errno == errno.EEXIST and path.isdir(dir_path):
         pass
      else:
         raise

def get_SCAFF_ID(i):
   SCAFF_ID=""
   i+=1
   if i>=1000000 and i<=9999999:
      SCAFF_ID="SCAFF"+str(i)
   elif i>=100000:
      SCAFF_ID="SCAFF0"+str(i)
   elif i>=10000:
      SCAFF_ID="SCAFF00"+str(i)
   elif i>=1000:
      SCAFF_ID="SCAFF000"+str(i)
   elif i>=100:
      SCAFF_ID="SCAFF0000"+str(i)
   elif i>=10:
      SCAFF_ID="SCAFF00000"+str(i)
   elif i>=1:
      SCAFF_ID="SCAFF000000"+str(i)
   else:
      exit("ERROR too much scaffolds!!! -> (>9999999)")
   return i,SCAFF_ID

def rev_ori(ori):
   if ori=="-":
      return "+"
   elif ori=="+":
      return "-"
   elif ori=="?":
      return "?"
   else:
      exit("ERROR, orientation: \""+ori+"\" is incorrect, it should be \"+\" or \"-\"!!!")

def rev_ctg_order(listCTG):
   new_listCTG=list()
   for i in range(1,len(listCTG)+1):
      rev_ctg=CTG(listCTG[-i].id,rev_ori(listCTG[-i].ori))
      new_listCTG.append(rev_ctg)
   return new_listCTG

def mergeCTG(species,ctg1,ctg2,ori_ctg1,ori_ctg2,dict_newSCAFF_ID,dict_newSCAFF,scaffold_ID_with_ctg_order,scaff_id):
   # Get new ID of ctg1 and ctg2 if they have been previously changed
   new_ctg1,new_ctg2="",""
   if species in dict_newSCAFF_ID:
      if ctg1 in dict_newSCAFF_ID[species]:
         new_ctg1=dict_newSCAFF_ID[species][ctg1]
      if ctg2 in dict_newSCAFF_ID[species]:
         new_ctg2=dict_newSCAFF_ID[species][ctg2]

   # If ctg1 has been previously changed
   new_ctg1_order=list()
   new_ctg2_order=list()
   if new_ctg1:
      first_ctg1=dict_newSCAFF[species][new_ctg1][0]
      last_ctg1=dict_newSCAFF[species][new_ctg1][-1]
      # Get the correct order of contigs in new_ctg1
      if ctg1==first_ctg1.id:
         new_ctg1_order=rev_ctg_order(dict_newSCAFF[species][new_ctg1])
      elif ctg1==last_ctg1.id:
         new_ctg1_order=dict_newSCAFF[species][new_ctg1]
      else:
         exit("ERROR, contig \""+ctg1+"\" should be to the start or the end of the new contig \""+new_ctg1+"\" !!!")
      # Remove the previous version of "new_ctg1"
      dict_newSCAFF[species].pop(new_ctg1,None)

   # If ctg2 has been previously changed
   if new_ctg2:
      first_ctg2=dict_newSCAFF[species][new_ctg2][0]
      last_ctg2=dict_newSCAFF[species][new_ctg2][-1]
      # Get the correct order of contigs in new_27avian_dataset/data/INPUT_DATA/27avian_species.t2
      if ctg2==last_ctg2.id:
         new_ctg2_order=rev_ctg_order(dict_newSCAFF[species][new_ctg2])
      elif ctg2==first_ctg2.id:
         new_ctg2_order=dict_newSCAFF[species][new_ctg2]
      else:
         exit("ERROR, contig \""+ctg2+"\" should be to the start or the end of the new contig \""+new_ctg2+"\" !!!")
      # Remove the previous version of "new_ctg2"
      dict_newSCAFF[species].pop(new_ctg2,None)

   # If ctg1 has NOT been previously changed
   if not new_ctg1_order:
      new_ctg1_order.append(CTG(ctg1,ori_ctg1))
   # If ctg2 has NOT been previously changed
   if not new_ctg2_order:
      new_ctg2_order.append(CTG(ctg2,ori_ctg2))

   # Concatenate the two CTG order to define the new SCAFF
   new_ctg_order=new_ctg1_order+new_ctg2_order

   # Set the ID of the new scaffold
   new_CTG_ID=""
   ### If we set the scaffold ID with the ctg order list
   if scaffold_ID_with_ctg_order:
      for elem in new_ctg_order:
         ctg=elem.id
         ori=elem.ori
         short_ctg=ctg.split(sep)[0]
         if not new_CTG_ID:
            new_CTG_ID+=short_ctg+"("+ori+")"
         else:
            new_CTG_ID+=":"+short_ctg+"("+ori+")"
   ### If we set the scaffold ID with the format "SCAFFXXXXXX"
   else:
      if new_ctg1:
         new_CTG_ID=new_ctg1
      elif new_ctg2:
         new_CTG_ID=new_ctg2
      else:
         scaff_id,new_CTG_ID=get_SCAFF_ID(scaff_id)

   #
   if not species in dict_newSCAFF:
      dict_newSCAFF[species]=dict()
   dict_newSCAFF[species][new_CTG_ID]=new_ctg_order

   if not species in dict_newSCAFF_ID:
      dict_newSCAFF_ID[species]=dict()
   for elem in new_ctg_order:
      ctg=elem.id
      dict_newSCAFF_ID[species][ctg]=new_CTG_ID

   return scaff_id

################
###   MAIN   ###
################
if __name__ == '__main__':

   start_time = datetime.now()

   CTG=namedtuple("CTG",["id","ori"])

   # Recovery of input parameters
   newAdj_file=argv[1]
   FASTA_dir=argv[2]
   file_prefix=argv[3]
   OUTPUT_AGP=argv[4]

   scaffold_ID_with_ctg_order=False
   write_unscaffolded_ctg=True
   default_gap_size=100
   verbose=1
   sep="_size"

   # Create OUTPUT_DIR if not existing
   mkdir_p(OUTPUT_AGP)

   print("1/ Merge scaffolds linked by linearized new adjacencies")
   dict_newSCAFF,dict_newSCAFF_ID,dict_distCTG=dict(),dict(),dict()
   input_file=open(newAdj_file,"r")
   scaff_id=0
   stored_species=""
   for new_adj in input_file:
      r=search("^([^\t]*)\t([^\t]*)\t([^\t]*)\t([^\t]*)\t([^\t]*)\t([^\t]*)\t([^\t]*)\t([^\t]*)\t([^\t]*)\t([^\t]*)\t([^\t]*)\t([^\t]*)\t([^\t]*)\t([^\t]*)\t([^\t]*)\t([^\t]*)\t([^\t\n]*)\n$",new_adj)
      if r:
         species=r.group(1)
         ctg1=r.group(2)
         ctg2=r.group(3)
         ori_ctg1=r.group(4)
         ori_ctg2=r.group(5)
         dist_ctg=r.group(6)
         gf1=r.group(7)
         gf2=r.group(8)
         g1=r.group(9)
         g2=r.group(10)
         ori_g1=r.group(11)
         ori_g2=r.group(12)
         dist_gene=r.group(13)
         vscore=r.group(14)
         dscore=r.group(15)
         links=r.group(16)
         support=r.group(17)

         if species!="#species":
            if stored_species!=species:
               scaff_id=0
               stored_species=species
            dict_distCTG[(ctg1,ctg2)]=dist_ctg
            scaff_id=mergeCTG(species,ctg1,ctg2,ori_ctg1,ori_ctg2,dict_newSCAFF_ID,dict_newSCAFF,scaffold_ID_with_ctg_order,scaff_id)
   input_file.close()
   dict_newSCAFF_ID.clear()

   # Print the new CTG ID after merging initial contigs/scaffoldsin new scaffolds
   if verbose>1:
      if verbose>2:
         print("\n1bis/ Print association between new scaffolds ID and old scaffolds/contigs ID / species:")
      else:
         print("\n1bis/ Print new scaffolds ID / species:")
      # Print new linked scaffolds / species
      for species in sorted(dict_newSCAFF):
         print("\n"+species+":")
         for ctg in dict_newSCAFF[species]:
            print("\t"+ctg)
            if verbose>2:
               for elem in dict_newSCAFF[species][ctg]:
                  print("\t\t", end=' ')
                  print(elem)

   # Print distance between CTG pairs linked by DeCoSTAR
   if verbose>2:
      print("\n\t1ter/ Print distance between CTG pairs linked by DeCoSTAR:")
      for distCTG in sorted(dict_distCTG):
         print(distCTG,"\t",dict_distCTG[distCTG])

   print("\n2/ Write AGP files after scaffolding with linearized new adjacencies predicted by DeCoSTAR")
   for species in sorted(dict_newSCAFF):
      if verbose>0:
         print("\t"+species)
      output_agp=open(OUTPUT_AGP+"/"+file_prefix+species+".agp","w")

      dict_CTG=dict()
      FASTA_FILE=""
      for FASTA in sorted(listdir(FASTA_dir)):
         i=0
         spe=""
         r=search("^([^\.]*)\..*$",FASTA)
         if r:
            spe=r.group(1)
         else:
            exit("!!! ERROR, FASTA file name: "+FASTA+" is incorrectly written (Must be: ${species_name}.fa) !!!")
         if spe==species:
            FASTA_FILE=FASTA_dir+"/"+FASTA
            # Browse FASTA file of current species to get list of scaffolds
            fasta_file=open(FASTA_dir+"/"+FASTA)
            for sequence in SeqIO.parse(fasta_file,"fasta"):
               ctg=sequence.id
               size=len(sequence.seq)
               dict_CTG[ctg]=size
            fasta_file.close()
            break

      for scaff in sorted(dict_newSCAFF[species]):
         listCTG=dict_newSCAFF[species][scaff]
         ID=""
         gap_size=0
         posSTART=1
         posEND=0
         bool_default=False
         stored_CTG=""
         for ctg in listCTG:
            ### Allow to discard duplicate CTG (corresponding to a circularizing adjacency predicted by DeCoSTAR)
            if ctg.id!=stored_CTG:
               stored_CTG=ctg.id
               ctg_size=dict_CTG[ctg.id]
               del dict_CTG[ctg.id]
               # Get size of the gap between the 2 scaffolded contigs (ID and ctg.id)
               if ID:
                  if (ID,ctg.id) in dict_distCTG:
                     if dict_distCTG[(ID,ctg.id)]=="?":
                        bool_default=True
                        gap_size=default_gap_size
                     else:
                        gap_size=int(float(dict_distCTG[(ID,ctg.id)]))
                        # print gap_size
                        if gap_size<0:
                           if verbose>1:
                              print("\t!!!WARNING!!! => NEGATIVE distance between contigs "+ID+" and "+ctg.id)
                  elif (ctg.id,ID) in dict_distCTG:
                     if dict_distCTG[(ctg.id,ID)]=="?":
                        bool_default=True
                        gap_size=default_gap_size
                     else:
                        gap_size=int(float(dict_distCTG[(ctg.id,ID)]))
                        # print gap_size
                        if gap_size<0:
                           if verbose>1:
                              print("\t!!!WARNING!!! => NEGATIVE distance between contigs "+ctg.id+" and "+ID)
                  else:
                     exit("ERROR: CTG adjacency ("+ID+"-"+ctg.id+") is not present in DeCoSTAR predicted adjacencies file: "+newAdj_file)

                  # Write gap in AGP file
                  posEND+=gap_size
                  if bool_default:
                     output_agp.write(scaff+"\t"+str(posSTART)+"\t"+str(posEND)+"\t.\tU\t"+str(gap_size)+"\tscaffold\tno\tna\n")
                  else:
                     output_agp.write(scaff+"\t"+str(posSTART)+"\t"+str(posEND)+"\t.\tN\t"+str(gap_size)+"\tscaffold\tyes\tpaired-ends\n")
                  bool_default=False
                  posSTART=posEND+1
               posEND+=ctg_size

               # Write current contig in the AGP file
               ID=ctg.id
               ori=ctg.ori
               output_agp.write(scaff+"\t"+str(posSTART)+"\t"+str(posEND)+"\t.\tW\t"+ID+"\t1\t"+str(ctg_size)+"\t"+ori+"\n")
               posSTART=posEND+1

      # Write remaining contigs (not scaffolded) in the AGP file
      if write_unscaffolded_ctg:
         for ctg in sorted(dict_CTG):
            ctg_size=dict_CTG[ctg]
            output_agp.write(ctg+"\t1\t"+str(ctg_size)+"\t.\tW\t"+ctg+"\t1\t"+str(ctg_size)+"\t+\n")
      output_agp.close()

   end_time = datetime.now()
   print('\nDuration: {}'.format(end_time-start_time))


from datetime import datetime
from collections import defaultdict
from math import exp

from extreme_amount_question import HighestAmountQuestion
from utils import get_paged_data

def weight(photo):
    taken = datetime.strptime(photo['created_time'][:10], '%Y-%m-%d')
    days_elapsed = (datetime.now() - taken).days + 1
    if days_elapsed < 0:
        raise Exception('Picture is dated ahead of today')
    return int(10 * exp((-0.002) * days_elapsed))

class MostTaggedWithQuestion(HighestAmountQuestion):
    QUESTION_TEXT = \
            'Out of the following, who has %s been tagged most with recently?'

    @classmethod
    def gen(cls, self_data, friend_data):
        tags = defaultdict(int)
        for photo in get_paged_data(friend_data, 'photos'):
            for tag in get_paged_data(photo, 'tags'):
                if 'id' not in tag:
                    continue        # Ignore tags of non-fb objects
                tags[tag['name']] += weight(photo)
        del tags[friend_data['name']]
        return cls(tags)


from fatpages.models import Fatpage as mFatpage
from django.template import loader, RequestContext
from django.shortcuts import get_object_or_404
from django.http import HttpResponse, HttpResponseRedirect
from django.conf import settings
from django.core.xheaders import populate_xheaders
from django.utils.safestring import mark_safe

DEFAULT_TEMPLATE = 'Fatpages/default.html'

def Fatpage(request, url):
    """
    Flat page view.

    Models: `Fatpages.Fatpages`
    Templates: Uses the template defined by the ``template_name`` field,
        or `Fatpages/default.html` if template_name is not defined.
    Context:
        Fatpage
            `Fatpages.Fatpages` object
    """
    if not url.endswith('/') and settings.APPEND_SLASH:
        return HttpResponseRedirect("%s/" % request.path)
    if not url.startswith('/'):
        url = "/" + url
    f = get_object_or_404(mFatpage, url__exact=url)
    # If registration is required for accessing this page, and the user isn't
    # logged in, redirect to the login page.
    if f.registration_required and not request.user.is_authenticated():
        from django.contrib.auth.views import redirect_to_login
        return redirect_to_login(request.path)
    if f.template_name:
        t = loader.select_template((f.template_name, DEFAULT_TEMPLATE))
    else:
        t = loader.get_template(DEFAULT_TEMPLATE)

    # To avoid having to always use the "|safe" filter in Fatpage templates,
    # mark the title and content as already safe (since they are raw HTML
    # content in the first place).
    f.title = mark_safe(f.title)
    f.content = mark_safe(f.content)
    f.headmatter = mark_safe(f.headmatter)

    c = RequestContext(request, {
        'fatpage': f,
    })
    response = HttpResponse(t.render(c))
    populate_xheaders(request, response, mFatpage, f.id)
    return response


import numpy as np
import matplotlib.pyplot as plt

class Blasius :
    def __init__(self, end, stepsize) :
        self.init = 0
        self.end = end
        self.h = stepsize
        self.x = np.arange(self.init, self.end + self.h, self.h)

    def solve(self):
        #f'' = z로 두면 dz/dx = -2 * z * y (f''' = -2 f'' f)
        self.y = np.zeros(self.x.shape)
        self.y1 = np.zeros(self.x.shape)
        self.y2 = np.zeros(self.x.shape)
        self.y3 = np.zeros(self.x.shape)
        self.y[0] = 0
        self.y1[0] = 0
        randominit = np.arange(0, 2, 0.001)
        print('''Searching the value of f''(0)''')
        for init in randominit :
            self.y2[0] = init
            for i in range(len(self.x) - 1) :
                k1 = -2 * self.y[i] * self.y2[i]
                k2 = -2 * (self.y[i] + self.y1[i] * self.h / 2) * (self.y2[i] + k1 * self.h / 2)
                k3 = -2 * (self.y[i] + self.y1[i] * self.h / 2) * (self.y2[i] + k2 * self.h / 2)
                k4 = -2 * (self.y[i] + self.y1[i] * self.h) * (self.y2[i] + k3 * self.h)
                self.y2[i+1] = self.y2[i] + self.h * (k1 + 2*k2 + 2*k3 + k4) / 6
                self.y1[i+1] = self.y1[i] + self.h * self.y2[i]
                self.y[i+1] = self.y[i] + self.h * self.y1[i]
            if 0.999 < abs(self.y1[-1]) < 1.001 :
                print("""Proper initial Value for f''(0) = {} (f'(inf) = {})"""
                      .format(init, self.y1[-1]))
                break
        print('''       x     /      f(x)     /      f'(x)     ''')
        for i in range(len(self.x)) :
            print('''    {}    /     {}     /    {}    '''.
                  format(round(self.x[i], 5), round(self.y[i], 5), round(self.y1[i], 5)))
        # x = 0 부터 x = 2.5까지 f'(x) ** 2의 적분값을 구하기 위한 수치적분
        int = 0
        for i in range(len(self.x)) :
            if self.x[i] > 2.5 :
                break
            int += self.h * self.y1[i]**2
        print('int value = {}'.format(int))

        plt.title('Blasius Equation using Shooting Method and RK4')
        plt.plot(self.x, self.y, 'blue', label = 'f(x)')
        plt.plot(self.x, self.y1, 'red', label = '''f'(x)''')
        plt.plot(self.x, self.y2, 'green', label = '''f''(x)''')
        plt.legend()
        plt.show()

Blasius(6, 0.01).solve()

Blasius Equation/1. Blasius Equation(RK4).py


#!/usr/bin/python3
import sqlite3
import os

class database:

    # Initialise the database
    def __init__(self):
        self.conn = sqlite3.connect("events.db")
        self.c = self.conn.cursor()

    # Connect to the database. If the file doesn't exist, it creates it.
    def db_connect(self):

        # Thanks to stackoverflow for help with this one.
        # https://stackoverflow.com/a/1604121
        database_exists = self.c.execute("SELECT name FROM sqlite_master WHERE name='downloads'").fetchone()

        if not database_exists:
            # id = DiceVideoId
            # name = the name of event/episode
            # quality = bitrate
            # date = timestamp
            self.c.execute("CREATE TABLE downloads (id integer unique, name text, quality text, date integer)")
            self.conn.commit()

    # Insert download into the database
    def db_ins(self, video_id, video_name, video_qual, timestamp):
        try:
            self.c.execute("INSERT INTO downloads VALUES ('{}', '{}', '{}', '{}')".format(video_id, video_name, video_qual, timestamp))
            self.conn.commit()
        except sqlite3.IntegrityError:
            print("Error: Couldn't add {} to the database. ID already exists.".format(video_id))

    # Update download information in the database
    def db_upd(self, video_id, video_name, video_qual, timestamp):
        self.c.execute("UPDATE downloads SET name = '{}', quality = '{}', date = '{}' WHERE id = {}".format(video_name, video_qual, timestamp, video_id))
        print("UPDATE downloads SET name = '{}', quality = '{}', date = '{}' WHERE id = {}".format(video_name, video_qual, timestamp, video_id))
        self.conn.commit()

    # Query the database for previously downloaded episode
    def db_query(self, video_id):
        #self.c.execute("INSERT INTO downloads VALUES ('{}', '{}', '{}', '{}')".format(video_id, video_name, video_qual, timestamp))
        result = self.c.execute("SELECT date FROM downloads WHERE id = '{}'".format(video_id))
        if result.fetchone():
            return True
        else:
            return False

    # Close the database, and commit any final changes
    def db_close(self):
        self.conn.commit()
        self.conn.close()

if __name__ == "__main__":
    print("Please run python main.py instead.")
    pass


from bs4 import BeautifulSoup
import requests

url = 'http://www.tripadvisor.cn/Attractions-g60763-Activities-New_York_City_New_York.html'
wb_data = requests.get(url)
soup = BeautifulSoup(wb_data.text,'lxml')
titles = soup.select(' div.property_title > a[target="_blank"]')
imgs = soup.select('img[width="160"]')
tags = soup.select(' div.p13n_reasoning_v2' )

for title,img,tag in zip(titles,imgs,tags):
    data = {
            'title' :title.get_text(),
            'img' :img.get('src'),
            'tag' :list(tag.stripped_strings),
     }
    print(data)


# -*- coding: utf-8 -*-
"""
Created on Thu Dec 26 20:05:23 2019

@author: 王新华
"""

import numpy as np
from astropy.io import fits
import scipy.fftpack as fft
import cupy as cp
from xyy_lib import xyy_lib as xyy
import os
from skimage import filters
import json
import re
import matplotlib.pyplot as plt

def align():
    f = open(r"/home/wangxinhua/level1/Level1/json.txt",'r')
    para = json.load(f)
    f.close()
    rcxsize = int(para['rcxsize'])
    rcysize = int(para['rcysize'])
    corstart = re.findall('\d+',para['corstart'])
    corstart = [int(i) for i in corstart]
    corsize = re.findall('\d+',para['corsize'])
    corsize = [int(i) for i in corsize]
    flated_path = para['flated_path']
    sobel = int(para['sobel'])
    path = para['path']
    only_align_no_luckyimage = int(para['only_align_no_luckyimage'])
    redrive = para['redrive']
    only_align_no_luckyimage_path = para['only_align_no_luckyimage_path']
    pfstart = re.findall('\d+',para['pfstart'])
    pfstart = [int(i) for i in pfstart]
    pfsize = re.findall('\d+',para['pfsize'])
    pfsize = [int(i) for i in pfsize]
    lucky_align_path = para['lucky_align_path']
    win=xyy.win(int(pfsize[0]),int(pfsize[1]),0.5,winsty='hann')     #----窗函数
    diameter = float(para['diameter'])
    wavelen = float(para['wavelen'])
    pixsca = float(para['pixsca'])
    fsp = float(para['fsp'])
    srstx = int(para['srstx'])
    srsty = int(para['srsty'])
    srxsize = int(para['srxsize'])
    srysize = int(para['srysize'])
    postprocess_flag = int(para['postprocess_flag'])
    srsize = int(para['srsize'])
    winsr=xyy.win(srsize,srsize, 0.5, winsty='hann')
    diaratio = float(para['diaratio'])
    start_r0 = float(para['start_r0'])
    step_r0 = float(para['step_r0'])
    maxfre=wavelen*10.0**(-10.0)/(2.0*diameter*pixsca)*(180.0*3600.0/np.pi)
    filename = para['filename']
    sitfdata=fits.getdata(filename)
    gussf=xyy.gaussf2d(rcxsize,rcysize,1.5)
    infrq=(pfsize[0]//2)*0.05/maxfre
    otfrq=(pfsize[0]//2)*0.10/maxfre
    datapath=[]
    flatpath=[]
    darkpath=[]
    subpaths = os.listdir(path)
    for i in range(len(subpaths)):
        subpath=os.path.join(path,subpaths[i])

        if ('F' in subpaths[i]) or ('f' in subpaths[i]) :
            flatpath.append(subpath)
        elif ('D' in subpaths[i]) or ('d' in subpaths[i]):
            darkpath.append(subpath)
        else:
            datapath.append(subpath)

    #做对齐
    #读预处理后的数据做对齐
    proceed_path = r'F:/2019-12-29chengjiang/20190518/HA'
    dirs = xyy.nvst_dirsandfiles_path(proceed_path)
    roots = dirs[0]
    fitsfile = dirs[1]
    t = 0
    for i in roots:
        i = i.split(':')[1]
        if 'f' not in i and 'd' not in i and 'F' not in i and 'D' not in i:
            data_root = i
            data_fits = dirs[1][t]
        t+=1
    for i in data_fits:
        data_path_fits = os.listdir(i)
        numb = len(data_path_fits)
        assert numb == 100
        cube = np.empty([numb,rcxsize,rcysize], dtype = np.float32)
        try:
            data_dir_fitstmp = os.path.join(i,data_path_fits[0])
        except Exception as e:
            print('warning:目录'+i+'下没有fits文件')
            continue
        ini = xyy.readfits(data_dir_fitstmp)[0]
        initmp = ini[corstart[0]:corstart[0]+corsize[0],corstart[1]:corstart[1]+corsize[1]]
        initmp_gpu = cp.asarray(initmp)
        print('基准文件：'+ data_dir_fitstmp)
        if sobel == 1:
            initmp = filters.sobel(filters.gaussian(initmp,5.0))
        t = 0
        for j in data_path_fits:
            head=fits.getheader(os.path.join(i,j))
            if t !=0:
                data = xyy.readfits(i+"\\"+j)[0]
                datatmp = data[corstart[0]:corstart[0]+corsize[0],corstart[1]:corstart[1]+corsize[1]]
                if sobel == 1:
                    datatmp = filters.sobel(filters.gaussian(datatmp,5.0))
                datatmp_gpu = cp.asarray(datatmp)
                cc,corr = xyy.corrmaxloc_gpu(initmp_gpu,datatmp_gpu)
                tmp = xyy.imgshift(data,[-cc[0],-cc[1]])#对齐后的图
                if only_align_no_luckyimage == 1:
                    #不选帧，直接叠加
                    print('不选帧对齐模式')
                    ini += tmp
                else:
                    #print('选帧后对齐模式')
                    cube[t,:,:] = tmp[0:rcxsize,0:rcysize]
                    cubepf=cube[:,pfstart[0]:pfstart[0]+pfsize[0],pfstart[1]:pfstart[1]+pfsize[1]]
                    cubemean=np.mean(cubepf, axis=0)
                    psdcube = np.empty([numb,pfsize[0],pfsize[1]], dtype=np.float32)

                    for nn in range(numb):
                        tmp=cubepf[nn,:,:].copy()
                        meantmp=np.mean(tmp)
                        tmp=(tmp-meantmp)*win+meantmp
                        psd=np.abs(fft.fftshift(fft.fft2(tmp)))**2
                        psd=(psd/psd[pfsize[0]//2,pfsize[1]//2]).astype(np.float32)
                        psdcube[nn,:,:]=psd
                    psdmean=np.mean(psdcube, axis=0)
                    psdcube=psdcube/psdmean
                    [Y,X]=np.meshgrid(np.arange(pfsize[1]),np.arange(pfsize[0]))
                    dist=((X-pfsize[0]//2)**2.0+(Y-pfsize[1]//2)**2.0)**0.5
                    ring=np.where((dist>=infrq)&(dist<=otfrq), 1.0, 0.0).astype(np.float32)
                    psdcube=psdcube*ring
                    ringcube=np.mean(np.mean(psdcube, axis=1),axis=1)
                    index0=np.argsort(ringcube)[::-1]
                    #---------------------------------------------------------------------------------------
                    #--------------------------------  取排序前**帧, 再次相关对齐，叠加
                    cubesort0=cube.copy()[index0][0:int(fsp*numb),:,:]
                    ini=np.mean(cubesort0, axis=0).astype(np.float32)
                    initmp=ini[corstart[0]:corstart[0]+corsize[0],corstart[1]:corstart[1]+corsize[1]]
                    if sobel==1:
                        initmp=filters.sobel(filters.gaussian(initmp,5.0))
                    initmp_gpu=cp.asarray(initmp)
                    # ----------------------   对齐
                    for nn in range(cubesort0.shape[0]):
                        data=cubesort0[nn,:,:].copy()
                        datatmp=data[corstart[0]:corstart[0]+corsize[0],corstart[1]:corstart[1]+corsize[1]]
                        if sobel==1:
                            datatmp=filters.sobel(filters.gaussian(datatmp,5.0))

                        datatmp_gpu=cp.asarray(datatmp)
                        cc,corr=xyy.corrmaxloc_gpu(initmp_gpu, datatmp_gpu)

                        ####cc,corr=xyy.corrmaxloc(initmp, datatmp)

                        tmp=xyy.imgshift(data,[-cc[0],-cc[1]])
                        cubesort0[nn,:,:]=tmp

                    averg=np.mean(cubesort0, axis=0).astype(np.float32)#叠加

            t +=1
        #----------------------------    选帧（1计算功率谱，2环带积分，3排序）

        #.................................................
        aligned_path = i+'/aligned'
        print('对齐后文件存储位置：'+path+os.path.splitdrive(aligned_path)[1])
        if only_align_no_luckyimage == 1:
            try:
                os.mkdir(path+os.path.splitdrive(aligned_path)[1])
            except Exception as e:
                print('警告：'+aligned_path+'文件夹已经存在')
            xyy.writefits(path+os.path.splitdrive(aligned_path)[1]+'\\'+'aligned.fits',initmp/len(data_path_fits))
        else:
            try:
                os.mkdir(path+os.path.splitdrive(aligned_path)[1])
            except Exception as e:
                print(path+aligned_path+'文件夹已经存在')

            xyy.writefits(path+os.path.splitdrive(aligned_path)[1]+'\\'+'aligned.fits',averg)
        #退卷积
        if postprocess_flag == 1:
            cubesr=cube[:,srstx:srstx+srxsize,srsty:srsty+srysize]
            r0,index=xyy.cubesrdevr0(cubesr,srsize,winsr,sitfdata,diameter,diaratio,maxfre,0.00,0.06,start_r0,step_r0)
            sitf=xyy.GetSitf(sitfdata,maxfre,rcxsize,index)
            img=xyy.ImgPSDdeconv(averg,sitf)

            head['CODE2'] = r0

            result=xyy.ImgFilted(img,gussf)

            result=result/np.median(result)*np.median(averg)
            fitsname = path+os.path.splitdrive(aligned_path)[1]+'\\'+'post_aligned.fits'
            xyy.writefits(fitsname,result.astype(np.float32),head)
            #plt.imshow(result)

if __name__ == "__main__":
    align()


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

import socket
import datetime
import threading
import subprocess
import BaseHTTPServer

def _lsof(port):
    try:  # try to find which process uses the socket
        process = subprocess.Popen(["sudo", "lsof", "-ti:{}".format(port)], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        stdout, stderr = process.communicate()

        if stderr and not stdout:
            return -1, stderr

        if stdout and not stderr:
            return 0, stdout

        return -1, ""

    except subprocess.CalledProcessError as error:
        return -1, error

class HttpServer:
    def __init__(self, host, port, request_handler):
        try:
            self.http_server = BaseHTTPServer.HTTPServer((host, port), request_handler)

        except socket.error as error:
            if 98 == error.errno: # address already in use error
                # try to find PID of the process that uses the socket
                return_code, pids = _lsof(port)
                if 0 == return_code:  # managed to find PID(s)
                    raise RuntimeError("Address is already used by process(es) with PID(s): {}".format(pids))
                else:  # failed to find PID(s)
                    raise RuntimeError(error.strerror)

            else:  # process other socket errors
                raise RuntimeError(error.strerror)

        except Exception as error:  # process other exceptions
            raise RuntimeError(error)

        self.serve_thread = threading.Thread(target=self.http_server.serve_forever)  # servE because the server.servE_forever
        self.serve_thread.daemon = True

        self.shutdown_thread = threading.Thread(target=self.http_server.shutdown)
        self.shutdown_thread.daemon = True

    def __del__(self):
        self.shutdown()

    def listen(self):
        if False in [hasattr(self, "serve_thread"), hasattr(self, "http_server")]:
            return

        if self.serve_thread.is_alive():
            return

        self.serve_thread.start()
        self.tic = datetime.datetime.now()
        host, port = self.http_server.server_address
        print("  HTTP-server started listening to {}:{}".format(host, port))

    def shutdown(self):
        if False in [hasattr(self, "serve_thread"), hasattr(self, "shutdown_thread")]:
            return

        if self.serve_thread.is_alive():

            if self.shutdown_thread.is_alive():
                return

            self.http_server.shutdown()
            self.shutdown_thread.start()
            self.shutdown_thread.join()
            self.toc = datetime.datetime.now()
            print("  Shutting down HTTP-server. Uptime: {}".format(self.toc-self.tic))


from django.shortcuts import render
from django.db.models import Q,Count
from django.http import HttpResponse
from django.views.decorators.csrf import csrf_exempt

from relatedLaw.models import RelatedLaw,LawText
from exam.models import ExamHistory

import simplejson as json

# Create your views here.
def index(request):
    examTypes = ExamHistory.examType
    return render(request,'theory/index.html',{'examTypes':examTypes})

@csrf_exempt
def step2(request):
    datas = request.POST.getlist('data[]')
    q_objects = Q()
    for data in datas:
        q_objects |= Q(**{'examTypeCode': data})

    exam = ExamHistory.objects.filter(q_objects) \
        .values('idexam').annotate(count=Count('idexam'))

    q_objects = Q()
    for data in exam:
        q_objects |= Q(**{'idexam': data['idexam']})

    law = RelatedLaw.objects.filter(q_objects).values('lawNameCode').annotate(Count('lawNameCode'))
    list = []
    for query in law:
        tt = {}
        tt['code'] = query['lawNameCode']
        tt['codeName'] = law.model(lawNameCode=query['lawNameCode']).get_lawNameCode_display()
        list.append(tt)
    context = {
        'data':list
    }
    return HttpResponse(json.dumps(context),content_type="application/json")

@csrf_exempt
def step3(request):
    step2 = request.POST.get('step2')
    step3 = request.POST.get('step3')
    theory = LawText.objects.filter(lawNameCode=step2, lawCategory=step3).extra(
        select={'lawContent_jo0': 'CAST(lawContent_jo AS SIGNED)' \
            , 'lawContent_hang0': 'CAST(lawContent_hang AS SIGNED)' \
            , 'lawContent_ho0': 'CAST(lawContent_ho AS SIGNED)' \
            , 'lawContent_mok0': 'CAST(lawContent_mok AS SIGNED)'}) \
        .order_by('lawContent_jo0', 'lawContent_hang0', 'lawContent_ho0', 'lawContent_mok0').values('idlaw_text','lawText')
    list = []
    print(theory.query)
    for query in theory:
        list.append(query['lawText'])

    context = {
        'data':list
    }
    return HttpResponse(json.dumps(context),content_type="application/json")


import pytest

@pytest.allure.CRITICAL
@pytest.allure.feature('SELENIUM.Smoke - nomenclature - Navigate')
@pytest.mark.navigate
@pytest.mark.selenium
@pytest.mark.smoke
class TestSeleniumSmokeNomenclatureNavigate:
    # Background #######################################################################################################
    @pytest.fixture()
    @pytest.allure.step('Background')
    def background(self, frontend):
        frontend.general.button_click('Свернуть меню', None, type_web_element='min_menu')

    # Scenario 0 #######################################################################################################
    @pytest.allure.story("""Section Nomenclature""")
    @pytest.mark.navigate_0
    @pytest.mark.case_0
    @pytest.mark.parametrize(
        ('section', 'subsection', 'name'),
        [
            ('Номенклатура', 'Блюда', 'warehouse.nomenclature.dish'),
            ('Номенклатура', 'Модификаторы', 'warehouse.nomenclature.mods'),
            ('Номенклатура', 'Ингредиенты', 'warehouse.nomenclature.singleproduct'),
            ('Номенклатура', 'Полуфабрикаты', 'warehouse.nomenclature.semiproduct')
        ]
    )
    def test_case_selenium_smoke_navigate_0(self, frontend, section, subsection, name):
        frontend.navigate.go_to_module(section, subsection, checking_time=True)
        frontend.navigate.opened_module_with_url(name)

    # Scenario 1 #######################################################################################################
    @pytest.allure.story("""Section Orders""")
    @pytest.mark.navigate_1
    @pytest.mark.case_1
    @pytest.mark.parametrize(
        ('section', 'subsection', 'name'),
        [
            ('Продажи', 'Чеки', 'front.orders'),
            ('Продажи', 'Пречеки', 'front.preorders'),
            ('Продажи', 'Отмены', 'front.cancellations'),
            ('Продажи', 'Внесения/инкассации', 'front.encashment'),
            ('Продажи', 'Кассовые смены', 'front.zreport')

        ]
    )
    def test_case_selenium_smoke_navigate_1(self, frontend, section, subsection, name):
        frontend.navigate.go_to_module(section, subsection, checking_time=True)
        frontend.navigate.opened_module_with_url(name)

    # Scenario 2 #######################################################################################################
    @pytest.allure.story("""Section Documents""")
    @pytest.mark.navigate_2
    @pytest.mark.case_2
    @pytest.mark.parametrize(
        ('section', 'subsection', 'name'),
        [
            ('Склад', 'Приходные накладные', 'warehouse.documents.incoming'),
            ('Склад', 'Расходные накладные', 'warehouse.documents.outgoing'),
            ('Склад', 'Внутренние перемещения', 'warehouse.documents.exchange'),
            ('Склад', 'Акты списания', 'warehouse.documents.discard'),
            ('Склад', 'Акты приготовления', 'warehouse.documents.cooking'),
            ('Склад', 'Акты разбора', 'warehouse.documents.decomposition'),
            ('Склад', 'Акты переработки', 'warehouse.documents.processing'),
            ('Склад', 'Акты инвентаризации', 'warehouse.inventory.document')
        ]
    )
    def test_case_selenium_smoke_navigate_2(self, frontend, section, subsection, name):
        frontend.navigate.go_to_module(section, subsection, checking_time=True)
        frontend.navigate.opened_module_with_url(name)

    # Scenario 3 #######################################################################################################
    @pytest.allure.story("""Section Core Dictionaries""")
    @pytest.mark.navigate_3
    @pytest.mark.case_3
    @pytest.mark.parametrize(
        ('section', 'subsection', 'name', 'tmp'),
        [
            ('Справочники', 'Единицы измерения', 'core.dictionaries.measureunits', 'Единицы измерения'),
            ('Справочники', 'Тэги', 'core.dictionaries.storeitemtag', 'Тэги'),
            ('Справочники', 'Контрагенты', 'warehouse.providers', 'Контрагенты'),
            ('Справочники', 'Причины списания', 'core.dictionaries.orderdiscardreasons', 'Причины отмены заказа'),
            ('Справочники', 'Типы оплат', 'core.dictionaries.paymenttypes', 'Типы оплат'),
            ('Справочники', 'Фасовки', 'core.dictionaries.packingunits', 'Фасовки товаров')
        ]
    )
    def test_case_selenium_smoke_navigate_3(self, frontend, section, subsection, name, tmp):
        frontend.navigate.go_to_module(section, subsection, checking_time=True)
        frontend.navigate.opened_module_with_url(name)

    # Scenario 4 #######################################################################################################
    @pytest.allure.story("""Section Personnel""")
    @pytest.mark.navigate_4
    @pytest.mark.case_4
    @pytest.mark.parametrize(
        ('section', 'subsection', 'name'),
        [
            ('Персонал', 'Сотрудники', 'personnel.employee'),
            ('Персонал', 'Должности', 'users.role')
        ]
    )
    def test_case_selenium_smoke_navigate_4(self, frontend, section, subsection, name):
        frontend.navigate.go_to_module(section, subsection, checking_time=True)
        frontend.navigate.opened_module_with_url(name)

    # Scenario 5 #######################################################################################################
    @pytest.allure.story("""Section CRM""")
    @pytest.mark.navigate_5
    @pytest.mark.case_5
    @pytest.mark.parametrize(
        ('section', 'subsection', 'name', 'tmp'),
        [
            ('CRM', 'Клиенты', 'crm.customer', 'Клиенты CRM'),
            ('CRM', 'Группы клиентов', 'crm.customer.group', 'Группы клиентов CRM'),
            ('CRM', 'Фиксированные скидки', 'crm.settings.fixed', 'Фиксированные скидки'),
            ('CRM', 'Скидки по расписанию', 'crm.settings.scheduled', 'Скидки по расписанию'),
            ('CRM', 'Типы бонусных счетов', 'crm.accounting.account.type', 'Типы бонусных счетов'),
            ('CRM', 'Бонусные программы', 'crm.settings.bonus', 'Бонусные программы'),
            ('CRM', 'Надбавки', 'crm.settings.markup', 'Надбавки')
        ]
    )
    def test_case_selenium_smoke_navigate_5(self, frontend, section, subsection, name, tmp):
        frontend.navigate.go_to_module(section, subsection, checking_time=True)
        frontend.navigate.opened_module_with_url(name)

    # Scenario 6 #######################################################################################################
    @pytest.allure.story("""Section Company""")
    @pytest.mark.navigate_6
    @pytest.mark.case_6
    @pytest.mark.parametrize(
        ('section', 'subsection', 'name'),
        [
            ('Предприятие', 'Настройки', 'core.company'),
            ('Предприятие', 'Организации', 'core.company.businesses'),
            ('Предприятие', 'Склады', 'warehouse.store'),
            ('Предприятие', 'Места приготовления', 'warehouse.nomenclature.cooking_place'),
            ('Предприятие', 'Места реализации', 'warehouse.nomenclature.sale_place'),
            ('Предприятие', 'Заведения', 'front.tablemanagement')
        ]
    )
    def test_case_selenium_smoke_navigate_6(self, frontend, section, subsection, name):
        frontend.navigate.go_to_module(section, subsection, checking_time=True)
        frontend.navigate.opened_module_with_url(name)

    # Scenario 7 #######################################################################################################
    @pytest.allure.story("""Section Devices""")
    @pytest.mark.navigate_7
    @pytest.mark.case_7
    @pytest.mark.parametrize(
        ('section', 'subsection', 'name'),
        [
            ('Устройства', 'Фискальные регистраторы', 'front.terminals.kkm'),
            ('Устройства', 'Банковские терминалы', 'front.terminals.pos'),
            ('Устройства', 'Принтеры', 'front.terminals.ticketdevices'),
            ('Устройства', 'QR Box', 'front.terminals.raspberry')

        ]
    )
    def test_case_selenium_smoke_navigate_7(self, frontend, section, subsection, name):
        frontend.navigate.go_to_module(section, subsection, checking_time=True)
        frontend.navigate.opened_module_with_url(name)

# # Scenario 11 ######################################################################################################
# @pytest.allure.story("""Проверка даты и названия""")
# @pytest.mark.navigate_11
# @pytest.mark.case_11
# def test_case_selenium_smoke_navigate_11(self, frontend, rest_api, psql, couchdb, background):
#     pass


from yolotr.models import Darknet
from yolotr.utils.datasets import *
from yolotr.utils.utils import *
import torch
import os

current_path = os.path.dirname(__file__)

class  TrafficDetector:
    def __init__(self,
                 img_size=640,
                 cfg_file="yolov4-tiny.cfg",
                 weights_file="yolov4-tiny.pt",
                 names_file="coco.names"):
        self.img_size = img_size
        self.cfg = os.path.join(current_path, F"cfg/{cfg_file}")
        self.weights = os.path.join(current_path, F"cfg/{weights_file}")
        self.names = os.path.join(current_path, F"cfg/{names_file}")
        # 构建模型
        self.model = Darknet(self.cfg, self.img_size)
        # 加载预训练模型
        self.model.load_state_dict(torch.load(self.weights)['model'])
        self.CUDA = torch.cuda.is_available()
        if self.CUDA:
            self.model.cuda()
        # 因为模型中使用了BatchNorm，Dropout等操作，预测的时候需要调用eval屏蔽
        self.model.eval()
        # ------------ 识别类型名
        # 加载类别
        self.names = load_classes(self.names)

    def detect(self, img0):
        img = self.format_img(img0)
        if self.CUDA:
            img = img.cuda()
        # 计算侦测结果
        pred = self.model(img, augment=False)[0]
        pred = pred.cpu()
        # 进行最大化抑制
        pred = non_max_suppression(pred, 0.3, 0.2, merge=False, classes=None, agnostic=False)
        # 解析识别结果
        for det in pred:
            if det is not None and len(det):
                det[:, :4] = scale_coords(img.shape[2:], det[:, :4], img0.shape).round()
        if pred[0] is not None:
            return pred[0].cpu().detach().numpy()  # 总长6：目标位置与大小（0:3），目标概率(4)，目标类别[5]
        else:
            return None

    def detect_mark(self, img0):
        # 侦测
        pred = self.detect(img0)
        # 标注
        if pred is not None:
            # 循环标注
            for result in pred:
                x1, y1, x2, y2 = result[0:4]
                prob = result[4]
                clss = int( result[5])
                cls_name = self.get_name(clss)
                # print([x1, y1, x2, y2], prob, clss, cls_name)
                # 备注：这里可以做一个概率阈值过滤（登录成功，可以考虑使用计数规则）
                # 标注
                img0 = cv2.rectangle(img0, (x1,y1),(x2,y2), color=(0, 0, 255), thickness=2)

        return img0, pred

    def get_name(self, idx):
        return self.names[idx]

    def format_img(self, img0):
        img = letterbox(img0, new_shape=self.img_size)[0]
        img = img[:, :, ::-1].transpose(2, 0, 1)  # BGR to RGB
        img = np.ascontiguousarray(img)
        img = torch.from_numpy(img)
        img = img.float()
        img /= 255.0  # 0 - 255 to 0.0 - 1.0
        if img.ndimension() == 3:
            img = img.unsqueeze(0)
        return img

    def load_image(self, img_file):
        img0 = cv2.imread(img_file)  # BGR
        return img0


import pickle

from moviepy.editor import *
from moviepy.video.tools.tracking import manual_tracking, Trajectory

clip = VideoFileClip("input/Gorod_2.mp4")

if __name__ == "__main__":
    start_frame = 3
    end_frame = 14
    trjectories_count = 1
    trajectories = manual_tracking(
        clip,
        t1=start_frame,
        t2=end_frame,
        nobjects=trjectories_count,
        fps=3,
        savefile="gorod_track"
    )


# Copyright 2021 CDPedistas (see AUTHORS.txt)
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 3, as published
# by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranties of
# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
# PURPOSE.  See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program.  If not, see <http://www.gnu.org/licenses/>.
#
# For further info, check  https://github.com/PyAr/CDPedia/

import shutil
from unittest.mock import patch

import pytest
from PIL import Image

from src.images.download import optimize_png, download, FetchingError, optimize_image

@pytest.fixture
def image_config(tmp_path):
    def f(name):
        img_test_name = 'tests/fixtures/image_to_optimize.png'
        test_path = tmp_path / name
        shutil.copy(img_test_name, str(test_path))
        init_size = test_path.stat().st_size
        return test_path, init_size
    yield f

@pytest.mark.parametrize('filename', [
    'image.png',  # simple
    'Image.PNG',  # uppercase
    'moño.png',  # unicode
    'the image.png',  # spaces
])
def test_pngquant_optimize_ok(image_config, filename):
    img_path, init_size = image_config(filename)
    optimize_png(str(img_path), init_size, init_size)
    final_size = img_path.stat().st_size
    assert init_size > final_size

def test_pngquant_optimize_problem(tmp_path, logs):
    # create something that pngquant will not understand
    img_path = tmp_path / 'weird.png'
    weird_content = "this is not really a png"
    img_path.write_text(weird_content)

    # it should not crash, and leave the original content untouched
    optimize_png(str(img_path), 23, 23)
    assert img_path.read_text() == weird_content
    assert "pngquant failed with 25 on '{}'".format(img_path) in logs.debug

def test_download_ok(tmp_path):
    test_path = tmp_path / 'foo' / 'bar' / 'baz.png'

    with patch('src.images.download.optimize_image') as _optimize_mock:
        with patch('src.images.download._download') as _download_mock:
            # real download will be ok, no need to patch RETRIES
            _download_mock.return_value = None

            download(('test-url', str(test_path)))

    # check directory were prepared ok
    assert test_path.parent.exists()

    # download and optimization was called ok
    _download_mock.assert_called_once_with('test-url', str(test_path))
    _optimize_mock.assert_called_once_with(str(test_path))

@pytest.mark.parametrize('extension', [
    '.svg',
    '.gif',
    '.Svg',
    '.Gif',
    '.SVG',
    '.GIF',
])
def test_download_no_optimization(extension, tmp_path):
    test_path = tmp_path / 'foo' / 'bar' / ('baz.' + extension)

    with patch('src.images.download.optimize_image') as _optimize_mock:
        with patch('src.images.download._download') as _download_mock:
            # real download will be ok, no need to patch RETRIES
            _download_mock.return_value = None

            download(('test-url', str(test_path)))

    # optimization was NOT called
    _optimize_mock.assert_not_called()

def test_download_retry_ok(tmp_path):
    test_path = tmp_path / 'foo' / 'bar' / 'baz.png'

    with patch('src.images.download.optimize_image'):
        with patch('src.images.download._download') as _download_mock:
            with patch('src.images.download.RETRIES', [0]):
                # first time ends with error, second ok
                _download_mock.side_effect = [
                    ValueError('pumba'),
                    None,
                ]
                download(('test-url', str(test_path)))

    # check directory were prepared ok
    assert test_path.parent.exists()

    # download was called twice
    assert _download_mock.call_count == 2

def test_download_problems(tmp_path):
    test_path = tmp_path / 'foo' / 'bar' / 'baz.png'

    with patch('src.images.download.optimize_image'):
        with patch('src.images.download._download') as _download_mock:
            with patch('src.images.download.RETRIES', [0]):
                # always in error
                _download_mock.side_effect = [
                    ValueError('pumba'),
                    ValueError('pumba'),
                ]
                with pytest.raises(FetchingError):
                    download(('test-url', str(test_path)))

    # check directory were prepared ok
    assert test_path.parent.exists()

    # download was called twice
    assert _download_mock.call_count == 2

def test_optimize_pil_error_unidentified(tmp_path, logs):
    tmp_image = tmp_path / "foo.png"
    tmp_image.write_text("not really a PNG, this will cause PIL to crash on open")

    optimize_image(str(tmp_image))
    msg = "PIL UnidentifiedImageError: cannot identify image file '.*/foo.png'"
    assert msg in logs.debug

def test_optimize_pil_error_generic(tmp_path, logs):
    tmp_image = tmp_path / "foo.png"
    tmp_image.write_text("stuff")
    with patch.object(Image, 'open') as mock:
        mock.side_effect = ValueError("pumba")
        optimize_image(str(tmp_image))
    msg = r"PIL optimization failed: ValueError\('pumba'.*\) when processing '.*foo.png'"
    assert msg in logs.debug


from django.contrib import messages
from django.shortcuts import redirect, render
import bcrypt
from .decorators import login_required
from .models import *
from datetime import datetime, time, timedelta
from django.utils import timezone
import re

@login_required
def index(request):
    context = {
        'mensajes': Mensaje.objects.all(),
        'comentarios': Comentario.objects.all(),
    }
    return render(request, 'index.html', context)

@login_required
def mensaje_crear(request):
    print(request.POST)

    errors= Mensaje.objects.validador_basico_mensaje(request.POST)
    print(errors)
    if len(errors) > 0:
        for key, value in errors.items():
            messages.error(request, value)
        return redirect("/")
    else:
        mensaje_creado = request.POST['mensaje']
        user_id_creador = request.session['usuario']['id']

        mensaje = Mensaje.objects.create(
            mensaje = mensaje_creado,
            user = User.objects.get(id = user_id_creador),
        )
        messages.success(request, "Mensaje agregado correctamente")
        return redirect(f"/")

def calculate_minutos(fecha):
    today = timezone.now()
    print(today, "today")
    print(fecha, "fecha")
    print("años", (today.year - fecha.year), (today.year - fecha.year)*365*24*60)
    print("meses", (today.month - fecha.month), (today.month - fecha.month)*30*24*60)
    print("dias", (today.day - fecha.day), (today.day - fecha.day)*24*60)
    print("horas", (today.hour-fecha.hour), (today.hour-fecha.hour)*60)
    print("minutos", (today.minute-fecha.minute))
    resultado = (today.year - fecha.year)*365*24*60 + (today.month - fecha.month)*30*24*60 + (today.day - fecha.day)*24*60 + (today.hour-fecha.hour)*60 + (today.minute-fecha.minute)
    print(resultado)
    return resultado

@login_required
def mensaje_borrar(request, val):
    errors = {}
    print(request.GET, 'Entró a borrar mensaje')
    borr = Mensaje.objects.get(id = val)
    print("Aqui se va a borrar el mensaje ID=", val)
    calc = calculate_minutos(borr.created_at)
    if calc > 30:
        messages.warning(request, "No se borró el mensaje. Tiempo expirado máximo 30 min")
    else:
        print("Autorizado para borrar el mensaje")
        messages.success(request, "Mensaje borrado exitosamente")
        borr.delete()
    return redirect("/")

@login_required
def comentario_crear(request):
    print(request.POST)

    errors= Comentario.objects.validador_basico_comentario(request.POST)
    print(errors)
    if len(errors) > 0:
        for key, value in errors.items():
            messages.error(request, value)
        return redirect("/")
    else:
        comentario_creado = request.POST['comentario']
        id_mensaje = request.POST['id_mensaje_comentario']
        comentario_user_id = request.session['usuario']['id']

        comentario = Comentario.objects.create(
            comentario = comentario_creado,
            user = User.objects.get(id=comentario_user_id),
            mensaje = Mensaje.objects.get(id=id_mensaje),
        )
        messages.success(request, "Comentario agregado correctamente")
        return redirect(f"/")

@login_required
def comentario_borrar(request, val):
    print(request.GET)
    borr = Comentario.objects.get(id = val)
    print("Aqui se va a borrar el comentario ID=", val)
    calc = calculate_minutos(borr.created_at)
    if calc > 30:
        messages.warning(request, "No se borró el comentario. Tiempo expirado máximo 30 min")
    else:
        print("Autorizado para borrar el comentario")
        messages.success(request, "Comentario borrado exitosamente")
        borr.delete()
    return redirect("/")


#!/usr/bin/env python

# WS server example

import asyncio
import os
import websockets

async def echo(websocket, path):
    while True:
        msg = await websocket.recv()
        print(f'Received {len(msg)} bytes')
        await websocket.send(msg)

host = os.getenv('BIND_HOST', 'localhost')
print(f'Serving on {host}:8766')

start_server = websockets.serve(echo, host, 8766, max_size=2 ** 30)

asyncio.get_event_loop().run_until_complete(start_server)
asyncio.get_event_loop().run_forever()


import ipaddress
import string
import random
import os
import shutil
import glob

import natlaslogging

SCAN_ID_LENGTH = 16

utillogger = natlaslogging.getLogger("Utilities")

def validate_target(target, config):
	try:
		iptarget = ipaddress.ip_address(target)
		if iptarget.is_private and not config.scan_local:
			utillogger.error("We're not configured to scan local addresses!")
			return False
	except ipaddress.AddressValueError:
		utillogger.error("%s is not a valid IP Address" % target)
		return False
	return True

def generate_scan_id():
	return ''.join(random.choice(string.ascii_lowercase + string.digits) for _ in range(SCAN_ID_LENGTH))

def cleanup_files(scan_id):
	utillogger.info("Cleaning up files for %s" % scan_id)
	if os.path.isdir("data/aquatone.%s" % scan_id):
		shutil.rmtree("data/aquatone.%s" % scan_id)
	for file in glob.glob("data/natlas."+scan_id+".*"):
		try:
			os.remove(file)
		except Exception:
			utillogger.error("Could not remove file %s" % file)


# Copyright (c) 2015 SUSE Linux GmbH.  All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
from azure.storage.blob.baseblobservice import BaseBlobService
from azure.storage.sharedaccesssignature import SharedAccessSignature

# project
from azurectl.azurectl_exceptions import (
    AzureCannotInit,
    AzureContainerListError,
    AzureContainerListContentError,
    AzureContainerCreateError,
    AzureContainerDeleteError
)

ISO8061_FORMAT = '%Y-%m-%dT%H:%M:%SZ'

class Container(object):
    """
        Information from Azure storage containers
    """
    def __init__(
        self,
        account=None,
        account_name=None,
        key=None,
        blob_service_host_base=None
    ):
        if account:
            self.account_name = account.storage_name()
            self.account_key = account.storage_key()
            self.blob_service_host_base = account.get_blob_service_host_base()
        elif (account_name and key and blob_service_host_base):
            self.account_name = account_name
            self.account_key = key
            self.blob_service_host_base = blob_service_host_base
        else:
            raise AzureCannotInit('''
                Either an account, or account_name, key, and service host base
                are required.
            ''')

    def list(self):
        result = []
        blob_service = BaseBlobService(
            self.account_name,
            self.account_key,
            endpoint_suffix=self.blob_service_host_base
        )
        try:
            for container in blob_service.list_containers():
                result.append(format(container.name))
        except Exception as e:
            raise AzureContainerListError(
                '%s: %s' % (type(e).__name__, format(e))
            )
        return result

    def exists(self, container):
        blob_service = BaseBlobService(
            self.account_name,
            self.account_key,
            endpoint_suffix=self.blob_service_host_base
        )
        try:
            blob_service.get_container_properties(container)
            return True
        except Exception:
            return False

    def create(self, container):
        blob_service = BaseBlobService(
            self.account_name,
            self.account_key,
            endpoint_suffix=self.blob_service_host_base
        )
        try:
            blob_service.create_container(
                container_name=container,
                fail_on_exist=True
            )
        except Exception as e:
            raise AzureContainerCreateError(
                '%s: %s' % (type(e).__name__, format(e))
            )
        return True

    def delete(self, container):
        blob_service = BaseBlobService(
            self.account_name,
            self.account_key,
            endpoint_suffix=self.blob_service_host_base
        )
        try:
            blob_service.delete_container(
                container_name=container,
                fail_not_exist=True
            )
        except Exception as e:
            raise AzureContainerDeleteError(
                '%s: %s' % (type(e).__name__, format(e))
            )
        return True

    def content(self, container):
        result = {container: []}
        blob_service = BaseBlobService(
            self.account_name,
            self.account_key,
            endpoint_suffix=self.blob_service_host_base
        )
        try:
            for blob in blob_service.list_blobs(container):
                result[container].append(format(blob.name))
            return result
        except Exception as e:
            raise AzureContainerListContentError(
                '%s: %s' % (type(e).__name__, format(e))
            )

    def sas(self, container, start, expiry, permissions):
        sas = SharedAccessSignature(
            self.account_name, self.account_key
        )
        signed_query = sas.generate_container(
            container_name=container,
            permission=permissions,
            expiry=expiry.strftime(ISO8061_FORMAT),
            start=start.strftime(ISO8061_FORMAT)
        )
        return 'https://{0}.blob.core.windows.net/{1}?{2}'.format(
            self.account_name, container, signed_query
        )


#Senior Design ECE 1896 Posture Watcher
#Gerald Kiliany

#Read input from Force Sensitive Resistors through ADC (MCP3008)

#import necessary libraries
import spidev
import time
import sys
import RPi.GPIO as GPIO
import csv

#variables
samplePeriod = 1
FSR_channel0 = 0
FSR_channel1 = 1
FSR_channel2 = 2
FSR_channel3 = 3
FSR_channel4 = 4
seatedThresh = 10 #threshold for pressure to consider a user to be seated (1024 range)
timeElapsed = 0
vibMode = False
vibrating = False
vibPinIn = 17 #GPIO pin to read vibration mode input
vibPinOut = 26 #GPIO pin for vibration motor
seatCount = 0
oversittingThresh = 5
notSittingThresh = 2
standCount = 0

#GPIO setup
GPIO.setmode(GPIO.BCM)
GPIO.setup(vibPinIn, GPIO.IN)
GPIO.setup(vibPinOut, GPIO.OUT)

#SPI Comm setup
mcp0 = spidev.SpiDev()
mcp0.open(0,0) #open communication between spi bus 0 and mcp device on channel 0
mcp0.max_speed_hz = 1000000

def readADC(adcnum):
    #Read SPI data from ADC, 8 channels
    if adcnum > 7 or adcnum < 0:
        return -1
   # mcp0.open(0,0)
   # mcp0.max_speed_hz = 1000000

    r = mcp0.xfer2([1, (8 + adcnum) << 4, 0])
    data = ((r[1] & 3) << 8) + r[2]

    #spi.close()
    return data

while timeElapsed < 5069: #for debugging don't run forever
        timeElapsed+=1

        vibMode = GPIO.input(17) #read pin 17 for if vibration switch on or off

        FSR_value0 = readADC(FSR_channel0) #0-1023 for 10 bit ADC, sensor 0
        FSR_value1 = readADC(FSR_channel1) #sensor 1
        FSR_value2 = readADC(FSR_channel2) #sensor 2
        FSR_value3 = readADC(FSR_channel3) #sensor 3
        FSR_value4 = readADC(FSR_channel4) #sensor 4
        #adc = MCP3008()
        #FSR_value0 = adc.read(channel = 0)
        #FSR_value1 = adc.read(channel = 1)

        #perform ops on data
        if FSR_value0 > seatedThresh:
            isSeated = True;
        else:
            isSeated = False;
        #for testing

        if isSeated:
            seatCount +=1 #increment time spent seated
            standCount = 0 #reset counter for standing
        else :
            standCount+=1
            if standCount >= notSittingThresh: #sense standing, reset seated count
                seatCount = 0

        print("Time elapsed: ", timeElapsed)
        print("FSR0 value: ", FSR_value0)
        print("FSR1 value: ", FSR_value1)
        print("FSR2 value: ", FSR_value2)
        print("FSR3 value: ", FSR_value3)
        print("FSR4 value: ", FSR_value4)
        print("Seated or not: ", isSeated)

        if (seatCount >= oversittingThresh) & ((seatCount % oversittingThresh) == 0) & (standCount < 1): #compare time sitting to the threshold considered to be too long
            if(vibMode) :
                print("Vibration Mode: Vibrating")
                GPIO.output(vibPinOut, GPIO.HIGH)
            else:
                print("Seated too long")
               # print("Pressure Pad Value: ", FSR_value0)
               # print("Seated or not: ", isSeated)
        #Write to file
        currValues = [FSR_value0, FSR_value1, FSR_value2, FSR_value3, FSR_value4]
        with open('mlData.csv', 'a', newline = '') as csvfile:
            outWriter = csv.writer(csvfile, delimiter = ' ')
            outWriter.writerow(currValues)

        time.sleep(samplePeriod)
        GPIO.output(vibPinOut, GPIO.LOW)
        #end
mcp0.close() #end comms with mcp device


#############################
# 현재 1개의 레시피 추천까지 진행
##############################
"""Example using TF Lite to classify objects with the Raspberry Pi camera."""

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import argparse
import io
import time
import threading
import numpy as np
import picamera

from tkinter import *
from tkinter import messagebox

from PIL import Image, ImageTk ###import 추가->mj
from tflite_runtime.interpreter import Interpreter
#import tflite ###import 추가->mj
import pandas as pd

class Camera(threading.Thread):
  m_bPressed = False
  m_rFood ={} ######################카메라 고장으로 잠시 주석하고 테스트했음
  #m_rFood={'onion':1,'tomato':1} ##대신 테스트했던 코드
  m_bExit = False

  def __init__(self):
    super().__init__()

  def Pressed(self, bEnable) :
      self.m_bPressed = bEnable

  def load_labels(self, path):
    with open(path, 'r') as f:
      return {i: line.strip() for i, line in enumerate(f.readlines())}

  def set_input_tensor(self, interpreter, image):
    tensor_index = interpreter.get_input_details()[0]['index']
    input_tensor = interpreter.tensor(tensor_index)()[0]
    input_tensor[:, :] = image

  def result(self):
    s = self.m_rFood.keys()

    return s

  def classify_image(self, interpreter, image, top_k=1):
    """Returns a sorted array of classification results."""
    self.set_input_tensor(interpreter, image)
    interpreter.invoke()
    output_details = interpreter.get_output_details()[0]
    output = np.squeeze(interpreter.get_tensor(output_details['index']))

    # If the model is quantized (uint8 data), then dequantize the results
    if output_details['dtype'] == np.uint8:
      scale, zero_point = output_details['quantization']
      output = scale * (output - zero_point)

    ordered = np.argpartition(-output, top_k)
    return [(i, output[i]) for i in ordered[:top_k]]

  def exit(self):
    self.m_bExit = True

  def run(self):

    parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)
    parser.add_argument('--model', help='File path of .tflite file.', required=True)
    parser.add_argument('--labels', help='File path of labels file.', required=True)
    args = parser.parse_args()

    #labels = self.load_labels('labels.txt')
    #interpreter = Interpreter('model_unquant.tflite')
    labels = self.load_labels(args.labels)
    interpreter = Interpreter(args.model)

    interpreter.allocate_tensors()
    _, height, width, _ = interpreter.get_input_details()[0]['shape']

    with picamera.PiCamera(resolution=(640, 480), framerate=3) as camera:
      camera.start_preview(fullscreen=False, window=(0,0,320,240) )
      try:
        stream = io.BytesIO()
        for _ in camera.capture_continuous(
          stream, format='jpeg', use_video_port=True):

          stream.seek(0)
          image = Image.open(stream).convert('RGB').resize((width, height),Image.ANTIALIAS)
          start_time = time.time()
          results = self.classify_image(interpreter, image)

          elapsed_ms = (time.time() - start_time) * 1000
          label_id, prob = results[0]

          stream.seek(0)
          stream.truncate()
          camera.annotate_text = '%s %.2f\n%.1fms' % (labels[label_id], prob,
                                                        elapsed_ms)

          if self.m_bPressed :
            self.m_rFood[labels[label_id]]=label_id
            #self.m_rFood.append(labels[label_id])
            print ( labels[label_id] )
            self.m_bPressed = False
            camera.annotate_text = '%s added.' % (labels[label_id] )

          if self.m_bExit:
            camera.stop_preview()
            break

      finally:
        camera.stop_preview()

cam = Camera()

def pressed_button() :
    cam.Pressed(True)
    print('button pressed')

def show_result():
    msg = messagebox.showinfo('result',cam.result())
    print('show')
def pressed_recipe(text):
    print(text)

def show_recipe():
    try:
      source = cam.result()
      data= pd.read_csv('food_Ingredients.csv')
      #print(data)

      recipe_ingredient=data['food ingredients']
      ingredients=[]
      count=[0 for _ in range(len(data))]
      #print("data 갯수 %d" %len(data))
      recommend=[]
      for num,i in enumerate(recipe_ingredient):
          ingredients.append(i.split(','))
      for num,a in enumerate(ingredients):
          print(a)
          for s in source:
              if s in a:
                  count[num]+=1 # 나중에 딕셔너리형으로 바꾸는거 고려
      if any(count):
          for num in range(len(count)):
              if count[num]!=0:
                  count[num] = count[num]/len(ingredients[num])
          result=count.index(max(count))
          recommend.append(data['cook'][result])
      else:
          print("해당재료로 만들 수 있는 레시피 없음.")
          msg2 = messagebox.showinfo('no recommend','No recipe for the ingredients')
          raise ValueError('No recipe for the ingredients!')

    #print(max(count))
    # for num,cnt in enumerate(count):
    #     if max(count)==0:
    #         print("해당재료로 만들 수 있는 레시피 없음.")
    #         msg2 = messagebox.showinfo('no recommend','No recipe for the ingredients')
    #         break
    #     if cnt==max(count) :
    #         recommend.append(data['cook'][num])
    # #print(recommend)

      recipe = Tk()
      recipe.configure(bg='white')
      recipe.geometry('750x600+500+500')
      recipe.title('레시피 추천')
      l = Label(recipe, bg="white", text=recommend[0], font=13) #요리제목
      l.place(x=30, y=10)

      image1 = Image.open("image/%s_2.jpg"%recommend[0])
      image2 = Image.open("image/%s_3.jpg"%recommend[0])

      image1 = image1.resize((350,500),Image.ANTIALIAS)
      image2 = image2.resize((350,500),Image.ANTIALIAS)

      img1 = ImageTk.PhotoImage(image1,master=recipe)
      img2 = ImageTk.PhotoImage(image2,master=recipe)

      label1 = Label(recipe, image= img1)
      label2 = Label(recipe, image= img2)

      # # Position image
      label1.place(x=20, y=60)
      label2.place(x=370,y=60)

    # btn={}
    # for num,a in enumerate(recommend):
    #       btn[a] = Button(recipe, width=20, height=1, text=a, bg="yellow", command=lambda: pressed_recipe(a))
    #       btn[a].place(x=130+150*num, y=10)
    #print(btn)
      recommend.clear()
      cam.m_rFood.clear()
      ingredients.clear()
      count.clear()
      recipe.mainloop()
    finally:
      recommend.clear()
      cam.m_rFood.clear()
      ingredients.clear()
      count.clear()
      print("end")

    return recommend

def main():
    try:
        cam.start()
        window = Tk()
        window.geometry('250x250+650+300')
        window.title('AI CHEF')

        l = Label(window, bg="white", text='Capturing the Image', font=13)
        l.place(x=30, y=10)

        b1 = Button(window, width=10, height=2, text='CAPTURE', bg="magenta", command=pressed_button)
        b1.place(x=65, y=60)

        b2 = Button(window, width=10, height=2, text='RESULT', bg="pink", command=show_result)
        b2.place(x=65, y=120)

        b3 = Button(window, width=10, height=2, text='RECIPE', bg="blue", command=show_recipe)
        b3.place(x=65, y=180)

        window.mainloop()

    finally:
        cam.exit()
        cam.join()
        quit()
    return

if __name__ == '__main__':
    main()


# -*- coding: utf-8 -*-
"""
Created on Tue May  7 18:07:06 2019

@author: kaany
"""
from sklearn.decomposition import PCA
from matplotlib import pyplot as plt
import numpy as np

from DataGenerator import generateData
from Preprocessing import deleteFeaturesRandomly

NUMBER_OF_CLASSES = 4
NUMBER_OF_FEATURES = NUMBER_OF_CLASSES*2
NUMBER_OF_FEATURES_PER_CLASS = 200
TOTAL_NUMBER_OF_RECORDS = NUMBER_OF_CLASSES * NUMBER_OF_FEATURES_PER_CLASS

FEATURE_MEAN_RANGE = [0, 50]

RANDOM_NUMBER_SEED = 0
NUMBER_OF_FEATURES_TO_PRUNE = 4

data, labels = generateData(NUMBER_OF_CLASSES, NUMBER_OF_FEATURES,
                            NUMBER_OF_FEATURES_PER_CLASS, FEATURE_MEAN_RANGE,
                            RANDOM_NUMBER_SEED)
prunedData = deleteFeaturesRandomly(data, labels, NUMBER_OF_FEATURES_TO_PRUNE,
                                    randomNumberSeed=RANDOM_NUMBER_SEED)

distinctLabels = np.unique(labels)

pca = PCA()
pcaData = pca.fit_transform(prunedData)

plt.figure()
plt.title("Feature Selection With PCA")
plt.xlabel("PC1")
plt.ylabel("PC2")
for label in distinctLabels:
    plt.scatter(pcaData[labels==label,0], pcaData[labels==label,1],
                c=np.random.rand(3,))