import argparse
import os
import random
import torch.nn as nn
import torch.backends.cudnn as cudnn
import torch.utils.data as Data
import torch.optim as optim
import torch.utils.data
import torchvision.transforms as transforms
import torchvision.utils as vutils
from PIL import Image
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import sys
import pickle
import time
import imageio
import numpy as np

parser = argparse.ArgumentParser()
parser.add_argument('--dataroot', default='./14st/', help='path to dataset')
parser.add_argument('--batchSize', type=int, default=16, help='input batch size')
parser.add_argument('--imageSize', type=int, default=64, help='the height / width of the input image to network')
parser.add_argument('--nz', type=int, default=100, help='size of the latent z vector')
parser.add_argument('--height', type=int, default=64)
parser.add_argument('--width', type=int, default=64)
parser.add_argument('--nc', type=int, default=3)
parser.add_argument('--gpu', default='0')
parser.add_argument('--ngf', type=int, default=64)
parser.add_argument('--ndf', type=int, default=64)
parser.add_argument('--niter', type=int, default=300, help='number of epochs to train for')
parser.add_argument('--glr', type=float, default=0.0001, help='learning rate, default=0.0002')
parser.add_argument('--dlr', type=float, default=0.0001, help='learning rate, default=0.0002')
parser.add_argument('--beta1', type=float, default=0.5, help='beta1 for adam. default=0.5')
parser.add_argument('--cuda', action='store_true', help='enables cuda')
parser.add_argument('--netG', default='', help="path to netG (to continue training)")
parser.add_argument('--netD', default='', help="path to netD (to continue training)")
parser.add_argument('--outf', default='./dc_output/', help='folder to output images and model checkpoints')
parser.add_argument('--manualSeed', type=int, help='manual seed')

opt = parser.parse_args()
print(opt)

try:
    os.makedirs(opt.outf)
except OSError:
    pass

HEIGHT, WIDTH = opt.height, opt.width

if opt.manualSeed is None:
    opt.manualSeed = random.randint(1, 10000)
print("Random Seed: ", opt.manualSeed)
random.seed(opt.manualSeed)
torch.manual_seed(opt.manualSeed)

cudnn.benchmark = True

if torch.cuda.is_available() and not opt.cuda:
    print("WARNING: You have a CUDA device, so you should probably run with --cuda")

#DataSet class
class img(Data.Dataset):

    def __init__(self, root_dir, transform, gpu):
        self.transform = transform
        with open(root_dir, 'rb')  as f:
            data = pickle.load(f)
        self.imgs = data['imgs']
        self.size = self.imgs.shape[0]
        self.gpu = gpu

    def __len__(self):
        return self.size #number of images

    def __getitem__(self, idx):
        imageio.imwrite('./temp'+ str(self.gpu)+'.jpg', np.transpose(self.imgs[idx]).astype(np.uint8))
        img = Image.open('./temp'+ str(self.gpu)+'.jpg')
        sample = self.transform(img)
        #print("debug22")
        #print(type(sample))
        #print(sample.size())

        return sample

transform = transforms.Compose([
        transforms.Resize((HEIGHT, WIDTH)),
        transforms.ToTensor(),
        transforms.Normalize([0.5, 0.5, 0.5], [0.5, 0.5, 0.5])
    ])

train_data = img(opt.dataroot, transform, opt.gpu)

#Create the data loaders
train_loader = Data.DataLoader(dataset=train_data, batch_size=opt.batchSize, shuffle=True)

device = torch.device("cuda:"+opt.gpu if opt.cuda else "cpu")
nz = int(opt.nz)
nc = int(opt.nc)
ngf = int(opt.ngf)
ndf = int(opt.ndf)

# custom weights initialization called on netG and netD
def weights_init(m):
    classname = m.__class__.__name__
    if classname.find('Conv') != -1:
        m.weight.data.normal_(0.0, 0.02)
    elif classname.find('BatchNorm') != -1:
        m.weight.data.normal_(1.0, 0.02)
        m.bias.data.fill_(0)

class Generator(nn.Module):
    def __init__(self):
        super(Generator, self).__init__()
        self.main = nn.Sequential(
            # input is Z, going into a convolution
            nn.ConvTranspose2d(nz, ngf * 8, 4, 1, 0, bias=False),
            nn.BatchNorm2d(ngf * 8),
            nn.ReLU(True),
            # state size. (ngf*8) x 4 x 4
            #nn.ConvTranspose2d(ngf * 16, ngf * 8, 4, 2, 1, bias=False),
            #nn.BatchNorm2d(ngf * 8),
            #nn.ReLU(True),
            # state size. (ngf*4) x 8 x 8
            nn.ConvTranspose2d(ngf * 8, ngf * 4, 4, 2, 1, bias=False),
            nn.BatchNorm2d(ngf * 4),
            nn.ReLU(True),
            # state size. (ngf*4) x 16 x 16
            nn.ConvTranspose2d(ngf * 4, ngf * 2, 4, 2, 1, bias=False),
            nn.BatchNorm2d(ngf * 2),
            nn.ReLU(True),
            # state size. (ngf*2) x 32 x 32
            nn.ConvTranspose2d(ngf * 2, ngf, 4, 2, 1, bias=False),
            nn.BatchNorm2d(ngf),
            nn.ReLU(True),
            # state size. (ngf) x 64 x 64
            nn.ConvTranspose2d(ngf, nc, 4, 2, 1, bias=False),
            nn.Tanh()
            # state size. (nc) x 128 x 128
        )

    def forward(self, input):
        output = self.main(input)
        return output

netG = Generator().to(device)
netG.apply(weights_init)
if opt.netG != '':
    netG.load_state_dict(torch.load(opt.netG))
print(netG)

class Discriminator(nn.Module):
    def __init__(self):
        super(Discriminator, self).__init__()
        self.main = nn.Sequential(
            # input is (nc) x 64 x 64
            nn.Conv2d(nc, ndf, 4, 2, 1, bias=False),
            nn.LeakyReLU(0.2, inplace=True),
            # state size. (ndf) x 32 x 32
            nn.Conv2d(ndf, ndf * 2, 4, 2, 1, bias=False),
            nn.BatchNorm2d(ndf * 2),
            nn.LeakyReLU(0.2, inplace=True),
            # state size. (ndf*2) x 16 x 16
            nn.Conv2d(ndf * 2, ndf * 4, 4, 2, 1, bias=False),
            nn.BatchNorm2d(ndf * 4),
            nn.LeakyReLU(0.2, inplace=True),
            # state size. (ndf*4) x 8 x 8
            nn.Conv2d(ndf * 4, ndf * 8, 4, 2, 1, bias=False),
            nn.BatchNorm2d(ndf * 8),
            nn.LeakyReLU(0.2, inplace=True),
            #nn.Conv2d(ndf * 8, ndf * 16, 4, 2, 1, bias=False),
            #nn.BatchNorm2d(ndf * 16),
            #nn.LeakyReLU(0.2, inplace=True),
            # state size. (ndf*8) x 4 x 4
            nn.Conv2d(ndf * 8, 1, 4, 1, 0, bias=False), #FIXME
            nn.Sigmoid()
        )

    def forward(self, input):
        output = self.main(input)
        return output.view(-1, 1).squeeze(1)

netD = Discriminator().to(device)
netD.apply(weights_init)
if opt.netD != '':
    netD.load_state_dict(torch.load(opt.netD))
print(netD)

criterion = nn.BCELoss()

fixed_noise = torch.randn(opt.batchSize, nz, 1, 1, device=device)
real_label = 0.95
fake_label = 0.05

# setup optimizer
optimizerD = optim.Adam(netD.parameters(), lr=opt.dlr, betas=(opt.beta1, 0.999))
optimizerG = optim.Adam(netG.parameters(), lr=opt.glr, betas=(opt.beta1, 0.999))

g_loss_for_plot = []
d_loss_for_plot = []

for epoch in range(opt.niter):
    start = time.time()
    avg_d = 0.0  # average d loss
    d_cnt = 0
    avg_g = 0.0  # average g loss
    g_cnt = 0

    for i, data in enumerate(train_loader, 0):
        if data.size(0) != opt.batchSize:
            break
        ############################
        # (1) Update D network: maximize log(D(x)) + log(1 - D(G(z)))
        ###########################
        # train with real
        netD.zero_grad()
        real_cpu = data.to(device)
        batch_size = real_cpu.size(0)
        label = torch.full((batch_size,), real_label, device=device)

        output = netD(real_cpu)
        #output = output.view(batch_size,)
        errD_real = criterion(output, label)

        avg_d += float(errD_real)

        errD_real.backward()
        D_x = output.mean().item()

        # train with fake
        noise = torch.randn(batch_size, nz, 1, 1, device=device)
        #print("debug33")
        #print(noise.size())
        fake = netG(noise)
        #print(fake.size())
        #print("~~~~---~~~~")
        label.fill_(fake_label)
        output = netD(fake.detach())
        errD_fake = criterion(output, label)

        avg_d += float(errD_fake)
        d_cnt += 1

        errD_fake.backward()
        D_G_z1 = output.mean().item()
        errD = errD_real + errD_fake
        optimizerD.step()

        ############################
        # (2) Update G network: maximize log(D(G(z)))
        ###########################
        netG.zero_grad()
        label.fill_(real_label)  # fake labels are real for generator cost
        output = netD(fake)
        errG = criterion(output, label)

        avg_g += float(errG)
        g_cnt += 1

        errG.backward()
        D_G_z2 = output.mean().item()
        optimizerG.step()

    print('[%d/%d][%d/%d] Loss_D: %.4f Loss_G: %.4f D(x): %.4f D(G(z)): %.4f / %.4f'
            % (epoch, opt.niter, i, len(train_loader),
                errD.item(), errG.item(), D_x, D_G_z1, D_G_z2))

    avg_d = avg_d / d_cnt
    avg_g = avg_g / g_cnt
    end = time.time()
    print("=============")

    print('epoch [{}/{}], avg_d:{:.4f}, avg_g:{:.4f}, time:{}'
          .format(epoch + 1, opt.niter, avg_d, avg_g, end - start))

    print("=============")
    sys.stdout.flush()

    d_loss_for_plot.append(avg_d)
    g_loss_for_plot.append(avg_g)

    if epoch % 2 == 0:
        if epoch == 0:
            vutils.save_image(real_cpu, '%s/real_samples.png' % opt.outf, normalize=True)
        fake = netG(fixed_noise)
        vutils.save_image(fake.detach(), '%s/fake_samples_epoch_%03d.png' % (opt.outf, epoch), normalize=True)
    if epoch % 9 == 0:
        d_loss_plt, = plt.plot(range(epoch + 1), d_loss_for_plot, label='d loss')
        g_loss_plt, = plt.plot(range(epoch + 1), g_loss_for_plot, label='g loss')
        plt.legend(handles=[g_loss_plt, d_loss_plt])
        plt.xlabel('iter')
        plt.title('D,G loss curve')
        try:
            plt.savefig(opt.outf + "plot_iter=" + str(epoch) + ".png")
        except:
            print("Plot failed!")

# do checkpointing
#torch.save(netG.state_dict(), '%s/netG_epoch_%d.pth' % (opt.outf, epoch))
#torch.save(netD.state_dict(), '%s/netD_epoch_%d.pth' % (opt.outf, epoch))


# attributes.py
# Copyright (c) 2007-2018 by Mark Bergsma <mark@nedworks.org>

# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

# System imports
import struct

# BGP imports
from exceptions import BGPException, AttributeException
from ip import IPv4IP, IPv6IP, IPPrefix
import bgp

# BGP attribute flags
ATTR_OPTIONAL = 1 << 7
ATTR_TRANSITIVE = 1 << 6
ATTR_PARTIAL = 1 << 5
ATTR_EXTENDED_LEN = 1 << 4

# BGP attribute types
ATTR_TYPE_ORIGIN = 1
ATTR_TYPE_AS_PATH = 2
ATTR_TYPE_NEXT_HOP = 3
ATTR_TYPE_MULTI_EXIT_DISC = 4
ATTR_TYPE_LOCAL_PREF = 5
ATTR_TYPE_ATOMIC_AGGREGATE = 6
ATTR_TYPE_AGGREGATOR = 7
ATTR_TYPE_COMMUNITY = 8

# RFC4760 attribute types
ATTR_TYPE_MP_REACH_NLRI = 14
ATTR_TYPE_MP_UNREACH_NLRI = 15

ATTR_TYPE_INT_LAST_UPDATE = 256 + 1

class Attribute(object):
    """
    Base class for all BGP attribute classes

    Attribute instances are (meant to be) immutable once initialized.
    """

    typeToClass = {}
    name = 'Attribute'
    typeCode = None

    def __init__(self, attrTuple=None):
        super(Attribute, self).__init__()

        if attrTuple is None:
            self.optional = False
            self.transitive = False
            self.partial = False
            self.extendedLength = False

            self.value = None
        else:
            flags, typeCode, value = attrTuple
            self.optional = (flags & ATTR_OPTIONAL != 0)
            self.transitive = (flags & ATTR_TRANSITIVE != 0)
            self.partial = (flags & ATTR_PARTIAL != 0)
            self.extendedLength = (flags & ATTR_EXTENDED_LEN != 0)

            self.value = value

            if typeCode not in self.typeToClass:
                if self.optional and self.transitive:
                    # Unrecognized optional, transitive attribute, set partial bit
                    self.typeCode = typeCode
                    self.partial = True
                elif not self.optional:
                    raise AttributeException(bgp.ERR_MSG_UPDATE_UNRECOGNIZED_WELLKNOWN_ATTR, attrTuple)

            self._initFromTuple(attrTuple)

        self.type = self.__class__

    def __eq__(self, other):
        return self is other or \
            (type(self) is type(other)
            and self.flags() == other.flags()
            and self.value == other.value)

    def __ne__(self, other):
        return not self.__eq__(other)

    def __hash__(self):
        return hash(self.tuple())

    def __repr__(self):
        return repr(self.tuple())

    def __str__(self):
        return self.__repr__()

    def flagsStr(self):
        """Returns a string with characters symbolizing the flags
        set to True"""

        s = ''
        for c, f in [('O', self.optional), ('T', self.transitive),
                     ('P', self.partial), ('E', self.extendedLength)]:
            if f: s += c
        return s

    def flags(self):
        return ((self.optional and ATTR_OPTIONAL or 0)
                | (self.transitive and ATTR_TRANSITIVE or 0)
                | (self.partial and ATTR_PARTIAL or 0)
                | (self.extendedLength and ATTR_EXTENDED_LEN or 0))

    def tuple(self):
        return (self.flags(), self.typeCode, self.value)

    def _initFromTuple(self, attrTuple):
        pass

    @classmethod
    def fromTuple(cls, attrTuple):
        """Instantiates an Attribute inheritor of the right type for a
        given attribute tuple.
        """

        return cls.typeToClass.get(attrTuple[1], cls)(attrTuple=attrTuple)

    def encode(self):
        return bgp.BGP.encodeAttribute(self.flags(), self.typeCode, self.value)

class BaseOriginAttribute(Attribute):
    name = 'Origin'
    typeCode = ATTR_TYPE_ORIGIN

    ORIGIN_IGP = 0
    ORIGIN_EGP = 1
    ORIGIN_INCOMPLETE = 2

    def __init__(self, value=None, attrTuple=None):
        super(BaseOriginAttribute, self).__init__(attrTuple=attrTuple)

        if not attrTuple:
            self.optional = False
            self.transitive = True
            self.value = value or self.ORIGIN_IGP

    def _initFromTuple(self, attrTuple):
        value = attrTuple[2]

        if self.optional or not self.transitive:
            raise AttributeException(bgp.ERR_MSG_UPDATE_ATTR_FLAGS, attrTuple)
        if len(value) != 1:
            raise AttributeException(bgp.ERR_MSG_UPDATE_ATTR_LEN, attrTuple)
        if ord(value) not in (self.ORIGIN_IGP, self.ORIGIN_EGP, self.ORIGIN_INCOMPLETE):
            raise AttributeException(bgp.ERR_MSG_UPDATE_INVALID_ORIGIN, attrTuple)

        self.value = ord(value)

    def encode(self):
        return struct.pack('!BBBB', self.flags(), self.typeCode, 1, self.value)

class OriginAttribute(BaseOriginAttribute): pass

class BaseASPathAttribute(Attribute):
    name = 'AS Path'
    typeCode = ATTR_TYPE_AS_PATH

    def __init__(self, value=None, attrTuple=None):
        super(BaseASPathAttribute, self).__init__(attrTuple=attrTuple)

        if not attrTuple:
            self.optional = False
            self.transitive = True

            if value and type(value) is list and reduce(lambda r,n: r and type(n) is int, value, True):
                # Flat sequential path of ASNs
                value = [(2, value)]
            self.value = value or [(2, [])] # One segment with one AS path sequence

    def _initFromTuple(self, attrTuple):
        value = attrTuple[2]

        if self.optional or not self.transitive:
            raise AttributeException(bgp.ERR_MSG_UPDATE_ATTR_FLAGS, attrTuple)
        if len(value) == 0:
            raise AttributeException(bgp.ERR_MSG_UPDATE_ATTR_LEN, attrTuple)

        self.value = []
        postfix = value
        try:
            # Loop over all path segments
            while len(postfix) > 0:
                segType, length = struct.unpack('!BB', postfix[:2])
                asPath = list(struct.unpack('!%dH' % length, postfix[2:2+length*2]))

                postfix = postfix[2+length*2:]
                self.value.append( (segType, asPath) )
        except Exception:
            raise AttributeException(bgp.ERR_MSG_UPDATE_MALFORMED_ASPATH)

    def encode(self):
        packedPath = "".join([struct.pack('!BB%dH' % len(asPath), segType, len(asPath), *asPath) for segType, asPath in self.value])
        return struct.pack('!BBB', self.flags(), self.typeCode, len(packedPath)) + packedPath

    def __str__(self):
        return " ".join([" ".join([str(asn) for asn in path]) for type, path in self.value])

    def __hash__(self):
        return hash(tuple([(segtype, tuple(path)) for segtype, path in self.value]))

class ASPathAttribute(BaseASPathAttribute): pass

class BaseNextHopAttribute(Attribute):
    name = 'Next Hop'
    typeCode = ATTR_TYPE_NEXT_HOP

    def __init__(self, value=None, attrTuple=None):
        super(BaseNextHopAttribute, self).__init__(attrTuple=attrTuple)

        if not attrTuple:
            self.optional = False
            self.transitive = True
            self._set(value)

    def _initFromTuple(self, attrTuple):
        value = attrTuple[2]

        if self.optional or not self.transitive:
            raise AttributeException(bgp.ERR_MSG_UPDATE_ATTR_FLAGS, attrTuple)
        if len(value) != 4:
            raise AttributeException(bgp.ERR_MSG_UPDATE_ATTR_LEN, attrTuple)

        self._set(value)

    def encode(self):
        return struct.pack('!BBB', self.flags(), self.typeCode, len(self.value.packed())) + self.value.packed()

    def _set(self, value):
        if value:
            if value in (0, 2**32-1):
                raise AttributeException(bgp.ERR_MSG_UPDATE_INVALID_NEXTHOP)
            self.value = IPv4IP(value)
        else:
            self.value = IPv4IP('0.0.0.0')

class NextHopAttribute(BaseNextHopAttribute):
    set = BaseNextHopAttribute._set

class BaseMEDAttribute(Attribute):
    name = 'MED'
    typeCode = ATTR_TYPE_MULTI_EXIT_DISC

    def __init__(self, value=None, attrTuple=None):
        super(BaseMEDAttribute, self).__init__(attrTuple=attrTuple)

        if not attrTuple:
            self.optional = True
            self.transitive = False
            self.value = value or 0

    def _initFromTuple(self, attrTuple):
        value = attrTuple[2]

        if not self.optional or self.transitive:
            raise AttributeException(bgp.ERR_MSG_UPDATE_ATTR_FLAGS, attrTuple)
        if len(value) != 4:
            raise AttributeException(bgp.ERR_MSG_UPDATE_ATTR_LEN, attrTuple)

        self.value = struct.unpack('!I', value)[0]

    def encode(self):
        return struct.pack('!BBBI', self.flags(), self.typeCode, 4, self.value)

class MEDAttribute(BaseMEDAttribute): pass

class BaseLocalPrefAttribute(Attribute):
    name = 'Local Pref'
    typeCode = ATTR_TYPE_LOCAL_PREF

    def __init__(self, value=None, attrTuple=None):
        super(BaseLocalPrefAttribute, self).__init__(attrTuple=attrTuple)

        if not attrTuple:
            self.optional = True
            self.transitive = False
            self.value = value or 0

    def _initFromTuple(self, attrTuple):
        value = attrTuple[2]

        if not self.optional or self.transitive:
            raise AttributeException(bgp.ERR_MSG_UPDATE_ATTR_FLAGS, attrTuple)
        if len(value) != 4:
            raise AttributeException(bgp.ERR_MSG_UPDATE_ATTR_LEN, attrTuple)

        self.value = struct.unpack('!I', value)[0]

    def encode(self):
        return struct.pack('!BBBI', self.flags(), self.typeCode, 4, self.value)

class LocalPrefAttribute(BaseLocalPrefAttribute): pass

class BaseAtomicAggregateAttribute(Attribute):
    name = 'Atomic Aggregate'
    typeCode = ATTR_TYPE_ATOMIC_AGGREGATE

    def __init__(self, value=None, attrTuple=None):
        super(BaseAtomicAggregateAttribute, self).__init__(attrTuple=attrTuple)

        if not attrTuple:
            self.optional = False
            self.value = None

    def _initFromTuple(self, attrTuple):
        if self.optional:
            raise AttributeException(bgp.ERR_MSG_UPDATE_ATTR_FLAGS, attrTuple)
        if len(attrTuple[2]) != 0:
            raise AttributeException(bgp.ERR_MSG_UPDATE_ATTR_LEN, attrTuple)

    def encode(self):
        return struct.pack('!BBB', self.flags(), self.typeCode, 0)

class AtomicAggregateAttribute(BaseAtomicAggregateAttribute): pass

class BaseAggregatorAttribute(Attribute):
    name = 'Aggregator'
    typeCode = ATTR_TYPE_AGGREGATOR

    def __init__(self, value=None, attrTuple=None):
        super(BaseAggregatorAttribute, self).__init__(attrTuple=attrTuple)

        if not attrTuple:
            self.optional = True
            self.transitive = True
            self.value = value or (0, IPv4IP('0.0.0.0')) # TODO: IPv6

    def _initFromTuple(self, attrTuple):
        value = attrTuple[2]

        if not self.optional or not self.transitive:
            raise AttributeException(bgp.ERR_MSG_UPDATE_ATTR_FLAGS, attrTuple)
        if len(value) != 6:
            raise AttributeException(bgp.ERR_MSG_UPDATE_ATTR_LEN, attrTuple)

        asn = struct.unpack('!H', value[:2])[0]
        aggregator = IPv4IP(value[2:]) # TODO: IPv6
        self.value = (asn, aggregator)

    def encode(self):
        return struct.pack('!BBBH', self.flags(), self.typeCode, 6, self.value[0]) + self.value[1].packed()

class AggregatorAttribute(BaseAggregatorAttribute): pass

class BaseCommunityAttribute(Attribute):
    name = 'Community'
    typeCode = ATTR_TYPE_COMMUNITY

    def __init__(self, value=None, attrTuple=None):
        super(BaseCommunityAttribute, self).__init__(attrTuple=attrTuple)

        if not attrTuple:
            self.optional = True
            self.transitive = True
            self.value = value or []

    def _initFromTuple(self, attrTuple):
        value = attrTuple[2]

        if not self.optional or not self.transitive:
            raise AttributeException(bgp.ERR_MSG_UPDATE_ATTR_FLAGS, attrTuple)
        if len(value) % 4 != 0:
            raise AttributeException(bgp.ERR_MSG_UPDATE_ATTR_LEN, attrTuple)

        length = len(value) / 4
        self.value = list(struct.unpack('!%dI' % length, value))

    def encode(self):
        return struct.pack('!BBB%dI' % len(self.value), self.flags(), self.typeCode, len(self.value) * 4, *self.value)

    def __str__(self):
        return str(["%d:%d" % (c / 2**16, c % 2**16) for c in self.value])

    def __hash__(self):
        return hash(tuple(self.value))

class CommunityAttribute(BaseCommunityAttribute): pass

# RFC4760 attributes

class BaseMPAttribute(Attribute):
    def __init__(self, value=(bgp.AFI_INET, bgp.SAFI_UNICAST), attrTuple=None):
        super(BaseMPAttribute, self).__init__(attrTuple=attrTuple)

        if not attrTuple:
            self.optional = True
            self.transitive = False
            self.extendedLength = True
            self.afi, self.safi = value[0:2]

    def _initFromTuple(self, attrTuple):
        if not self.optional or self.transitive:
            raise AttributeException(bgp.ERR_MSG_UPDATE_OPTIONAL_ATTR, attrTuple)

    def _unpackAFI(self, attrTuple):
        try:
            self.afi, self.safi = struct.unpack('!HB', attrTuple[2][:3])
        except struct.error:
            raise AttributeException(bgp.ERR_MSG_UPDATE_OPTIONAL_ATTR, attrTuple)
        else:
            if self.afi not in bgp.SUPPORTED_AFI or self.safi not in bgp.SUPPORTED_SAFI:
                raise AttributeException(bgp.ERR_MSG_UPDATE_OPTIONAL_ATTR, attrTuple)

    def _parseNLRI(self, attrTuple, value):
        try:
            return bgp.BGP.parseEncodedPrefixList(value, self.afi)
        except BGPException:
            raise AttributeException(bgp.ERR_MSG_UPDATE_OPTIONAL_ATTR, attrTuple)

    def addSomePrefixes(self, prefixSet, maxLen):
        """
        Add as many prefixes from prefixSet as will fit within maxLen,
        removing added prefixes from prefixSet.
        Returns the number of prefixes added.
        """
        # FIXME: Optimize to prevent double encoding

        bArray = bytearray()
        origPrefixSet = frozenset(prefixSet)
        count = bgp.BGP.encodeSomePrefixes(
            prefixSet=prefixSet,
            bArray=bArray,
            offset=0,
            maxLen=maxLen)
        self.value = self.value[0:-1] + (list(origPrefixSet - prefixSet), )
        return count

    @staticmethod
    def afiStr(afi, safi):
        return ({
                 bgp.AFI_INET:   "inet",
                 bgp.AFI_INET6:  "inet6"
            }[afi],
            {
                 bgp.SAFI_UNICAST:   "unicast",
                 bgp.SAFI_MULTICAST: "multicast"
            }[safi])

    def __str__(self):
        return "%s %s NLRI %s" % (BaseMPAttribute.afiStr(self.afi, self.safi) + (self.value[2], ))

class MPReachNLRIAttribute(BaseMPAttribute):
    name = 'MP Reach NLRI'
    typeCode = ATTR_TYPE_MP_REACH_NLRI

    # Tuple encoding of self.value:
    # (AFI, SAFI, NH, [NLRI])

    def __init__(self, value=None, attrTuple=None):
        super(MPReachNLRIAttribute, self).__init__(value=value, attrTuple=attrTuple)

        if not attrTuple:
            self.value = value or (bgp.AFI_INET6, bgp.SAFIUNICAST, IPv6IP(), [])

    def _initFromTuple(self, attrTuple):
        super(MPReachNLRIAttribute, self)._initFromTuple(attrTuple)

        self._unpackAFI(attrTuple)

        value = attrTuple[2]
        try:
            nhlen = struct.unpack('!B', value[3])[0]
            pnh = struct.unpack('!%ds' % nhlen, value[4:4+nhlen])[0]
        except struct.error:
            raise AttributeException(bgp.ERR_MSG_UPDATE_OPTIONAL_ATTR, attrTuple)

        if self.afi == bgp.AFI_INET:
            try:
                ip = struct.unpack('!I', pnh)[0]
            except struct.error:
                raise AttributeException(bgp.ERR_MSG_UPDATE_OPTIONAL_ATTR, attrTuple)
            else:
                nexthop = IPv4IP(ip)
        elif self.afi == bgp.AFI_INET6:
            nexthop = IPv6IP(packed=pnh)

        nlri = self._parseNLRI(attrTuple, value[5+nhlen:])

        self.value = (self.afi, self.safi, nexthop, nlri)

    def encode(self):
        afi, safi, nexthop, nlri = self.value
        pnh = nexthop.packed()
        encodedNLRI = bgp.BGP.encodePrefixes(nlri)
        length = 5 + len(pnh) + len(encodedNLRI)

        return struct.pack('!BBHHBB%dsB' % len(pnh), self.flags(), self.typeCode, length, afi, safi, len(pnh), pnh, 0) + encodedNLRI

    def __str__(self):
        return "%s %s NH %s NLRI %s" % (BaseMPAttribute.afiStr(self.afi, self.safi) + self.value[2:4])

    def __hash__(self):
        return hash((self.value[0:3] + (frozenset(self.value[3]), )))

    def addPrefixes(self, prefixes):
        """
        Adds a (copied) list of prefixes to this attribute's NLRI
        """
        self.value = self.value[0:3] + (list(prefixes), )

class MPUnreachNLRIAttribute(BaseMPAttribute):
    name = 'MP Unreach NLRI'
    typeCode = ATTR_TYPE_MP_UNREACH_NLRI

    # Tuple encoding of self.value:
    # (AFI, SAFI, [NLRI])

    def __init__(self, value=None, attrTuple=None):
        super(MPUnreachNLRIAttribute, self).__init__(value=value, attrTuple=attrTuple)

        if not attrTuple:
            self.value = value or (bgp.AFI_INET6, bgp.SAFIUNICAST, [])

    def _initFromTuple(self, attrTuple):
        super(MPUnreachNLRIAttribute, self)._initFromTuple(attrTuple)

        self._unpackAFI(attrTuple)

        nlri = self._parseNLRI(attrTuple, attrTuple[2][3:])

        self.value = (self.afi, self.safi, nlri)

    def encode(self):
        afi, safi, nlri = self.value
        encodedNLRI = bgp.BGP.encodePrefixes(nlri)
        length = 3 + len(encodedNLRI)

        return struct.pack('!BBHHB', self.flags(), self.typeCode, length, afi, safi) + encodedNLRI

    def addPrefixes(self, prefixes):
        """
        Adds a (copied) list of prefixes to this attribute's NLRI
        """
        self.value = self.value[0:2] + (list(prefixes), )

    def __hash__(self):
        return hash(self.value[0:2]) ^ hash(frozenset(self.value[2]))

class LastUpdateIntAttribute(Attribute):
    name = 'Last Update'
    typeCode = ATTR_TYPE_INT_LAST_UPDATE

    def _initFromTuple(self, attrTuple):
        self.value = attrTuple[2]

Attribute.typeToClass = {
    ATTR_TYPE_ORIGIN:            OriginAttribute,
    ATTR_TYPE_AS_PATH:           ASPathAttribute,
    ATTR_TYPE_NEXT_HOP:          NextHopAttribute,
    ATTR_TYPE_MULTI_EXIT_DISC:   MEDAttribute,
    ATTR_TYPE_LOCAL_PREF:        LocalPrefAttribute,
    ATTR_TYPE_ATOMIC_AGGREGATE:  AtomicAggregateAttribute,
    ATTR_TYPE_AGGREGATOR:        AggregatorAttribute,
    ATTR_TYPE_COMMUNITY:         CommunityAttribute,

    ATTR_TYPE_MP_REACH_NLRI:     MPReachNLRIAttribute,
    ATTR_TYPE_MP_UNREACH_NLRI:   MPUnreachNLRIAttribute,

    ATTR_TYPE_INT_LAST_UPDATE:   LastUpdateIntAttribute
}

class AttributeDict(dict):
    def __init__(self, attributes, checkMissing=False):
        """
        Expects another AttributeDict object, or a sequence of
        either unparsed attribute tuples, or parsed Attribute inheritors.
        """

        if isinstance(attributes, AttributeDict):
            return dict.__init__(self, attributes)

        dict.__init__(self)

        for attr in iter(attributes):
            if isinstance(attr, tuple):
                self._add(Attribute.fromTuple(attr))
            elif isinstance(attr, Attribute):
                self._add(attr)
            else:
                raise AttributeException(bgp.ERR_MSG_UPDATE_MALFORMED_ATTR_LIST)

        if checkMissing:
            # Check whether all mandatory well-known attributes are present
            for attr in [OriginAttribute, ASPathAttribute, NextHopAttribute]:
                if attr not in self:
                    raise AttributeException(bgp.ERR_MSG_UPDATE_MISSING_WELLKNOWN_ATTR,
                                             (0, attr.typeCode, None))

    def _add(self, attribute):
        """Adds attribute attr to the dict, raises AttributeException if already present"""

        if attribute.__class__ == Attribute:
            key = attribute.typeCode
        else:
            key = attribute.__class__

        if key in self:
            # Attribute was already present
            raise AttributeException(bgp.ERR_MSG_UPDATE_MALFORMED_ATTR_LIST)
        else:
            super(AttributeDict, self).__setitem__(key, attribute)

    add = _add

    def __str__(self):
        return "{%s}" % ", ".join(["%s: %s" % (attrType.__name__, str(attr)) for attrType, attr in self.iteritems()])

class FrozenAttributeDict(AttributeDict):
    __delitem__ = None
    __setitem__ = None
    clear = None
    fromkeys = None
    pop = None
    popitem = None
    setdefault = None
    update = None
    add = None

    def __eq__(self, other):
        return hash(self) == hash(other)

    def __hash__(self):
        import operator
        return reduce(operator.xor, map(hash, self.itervalues()), 0)


# import os,glob
# import cv2
# import copy

import sys,time,logging
if sys.version_info.major >= 3:
   import threading as threadmod
else:
   import thread as threadmod

import numpy as np
# import imgaug as ia
# from imgaug import augmenters as iaa
from keras.utils import Sequence
# import xml.etree.ElementTree as ET
from utils import BoundBox  # , bbox_iou
logger = logging.getLogger(__name__)
# Right now the truth are format as:
# bool objectFound   # if truth particle is in the hard scattering process
# bbox x                    # globe eta
# bbox y                    # globe phi
# bbox width             # Gaussian sigma (required to be 3*sigma<pi)
# bbox height            # Gaussian sigma (required to be 3*sigma<pi)
# bool class1             # truth u/d
# bool class2             # truth s
# bool class3             # truth c
# bool class4             # truth d
# bool class_other     # truth g

BBOX_CENTER_X = 1
BBOX_CENTER_Y = 2
BBOX_WIDTH = 3
BBOX_HEIGHT = 4

class BatchGenerator(Sequence):
    def __init__(self,filelist,
               config,
               evts_per_file,
               shuffle=True,
               jitter=True,
               norm=None):
      self.generator = None

      self.config          = config
      self.filelist        = filelist
      self.evts_per_file   = evts_per_file
      self.batch_size      = self.config['BATCH_SIZE']
      self.nevts           = len(filelist) * self.evts_per_file
      # self.nbatches        = int(self.nevts * (1. / self.batch_size))
      self.num_classes     = len(config['LABELS'])
      self.num_grid_x      = config['GRID_W']
      self.pix_per_grid_x  = float(self.config['IMAGE_W']) / self.config['GRID_W']
      self.num_grid_y      = config['GRID_H']
      self.pix_per_grid_y  = float(self.config['IMAGE_H']) / self.config['GRID_H']

      self.shuffle = shuffle
      self.jitter  = jitter
      self.norm    = norm

      self.anchors = [BoundBox(0, 0, config['ANCHORS'][2 * i], config['ANCHORS'][2 * i + 1]) for i in range(int(len(config['ANCHORS']) // 2))]

      '''
      ### augmentors by https://github.com/aleju/imgaug
      sometimes = lambda aug: iaa.Sometimes(0.5, aug)

      # Define our sequence of augmentation steps that will be applied to every image
      # All augmenters with per_channel=0.5 will sample one value _per image_
      # in 50% of all cases. In all other cases they will sample new values
      # _per channel_.
      self.aug_pipe = iaa.Sequential(
          [
              # apply the following augmenters to most images
              #iaa.Fliplr(0.5), # horizontally flip 50% of all images
              #iaa.Flipud(0.2), # vertically flip 20% of all images
              #sometimes(iaa.Crop(percent=(0, 0.1))), # crop images by 0-10% of their height/width
              sometimes(iaa.Affine(
                  #scale={"x": (0.8, 1.2), "y": (0.8, 1.2)}, # scale images to 80-120% of their size, individually per axis
                  #translate_percent={"x": (-0.2, 0.2), "y": (-0.2, 0.2)}, # translate by -20 to +20 percent (per axis)
                  #rotate=(-5, 5), # rotate by -45 to +45 degrees
                  #shear=(-5, 5), # shear by -16 to +16 degrees
                  #order=[0, 1], # use nearest neighbour or bilinear interpolation (fast)
                  #cval=(0, 255), # if mode is constant, use a cval between 0 and 255
                  #mode=ia.ALL # use any of scikit-image's warping modes (see 2nd image from the top for examples)
              )),
              # execute 0 to 5 of the following (less important) augmenters per image
              # don't execute all of them, as that would often be way too strong
              iaa.SomeOf((0, 5),
                  [
                      #sometimes(iaa.Superpixels(p_replace=(0, 1.0), n_segments=(20, 200))), # convert images into their superpixel representation
                      iaa.OneOf([
                          iaa.GaussianBlur((0, 3.0)), # blur images with a sigma between 0 and 3.0
                          iaa.AverageBlur(k=(2, 7)), # blur image using local means with kernel sizes between 2 and 7
                          iaa.MedianBlur(k=(3, 11)), # blur image using local medians with kernel sizes between 2 and 7
                      ]),
                      iaa.Sharpen(alpha=(0, 1.0), lightness=(0.75, 1.5)), # sharpen images
                      #iaa.Emboss(alpha=(0, 1.0), strength=(0, 2.0)), # emboss images
                      # search either for all edges or for directed edges
                      #sometimes(iaa.OneOf([
                      #    iaa.EdgeDetect(alpha=(0, 0.7)),
                      #    iaa.DirectedEdgeDetect(alpha=(0, 0.7), direction=(0.0, 1.0)),
                      #])),
                      iaa.AdditiveGaussianNoise(loc=0, scale=(0.0, 0.05*255), per_channel=0.5), # add gaussian noise to images
                      iaa.OneOf([
                          iaa.Dropout((0.01, 0.1), per_channel=0.5), # randomly remove up to 10% of the pixels
                          #iaa.CoarseDropout((0.03, 0.15), size_percent=(0.02, 0.05), per_channel=0.2),
                      ]),
                      #iaa.Invert(0.05, per_channel=True), # invert color channels
                      iaa.Add((-10, 10), per_channel=0.5), # change brightness of images (by -10 to 10 of original value)
                      iaa.Multiply((0.5, 1.5), per_channel=0.5), # change brightness of images (50-150% of original value)
                      iaa.ContrastNormalization((0.5, 2.0), per_channel=0.5), # improve or worsen the contrast
                      #iaa.Grayscale(alpha=(0.0, 1.0)),
                      #sometimes(iaa.ElasticTransformation(alpha=(0.5, 3.5), sigma=0.25)), # move pixels locally around (with random strengths)
                      #sometimes(iaa.PiecewiseAffine(scale=(0.01, 0.05))) # sometimes move parts of the image around
                  ],
                  random_order=True
              )
          ],
          random_order=True
      )
      '''

      if shuffle:
         np.random.shuffle(self.filelist)

    def __len__(self):
        return int(np.ceil(float(self.nevts) / self.config['BATCH_SIZE']))

    def get_num_classes(self):
        return self.num_classes

    def size(self):
        return self.nevts

    def load_annotation(self, i):
        file_index = int(i / self.evts_per_file)
        image_index = i % self.evts_per_file
        file_content = np.load(self.filelist[file_index])
        obj = file_content['truth'][image_index][0]
        logger.info(obj.shape)
        annot = [obj[BBOX_CENTER_X], obj[BBOX_CENTER_Y], obj[BBOX_WIDTH], obj[BBOX_HEIGHT], np.argmax(obj[5:10])]
        return np.array([annot])

    def load_image(self, i):
        file_index = int(i / self.evts_per_file)
        image_index = i % self.evts_per_file
        file_content = np.load(self.filelist[file_index])
        return file_content['raw'][image_index]

    # return a batch of images starting at the given index
    def __getitem__(self, idx):
        start = time.time()
        logger.debug('starting get batch of size %s',self.batch_size)

        instance_count = 0

        x_batch = np.zeros((self.batch_size, self.config['IMAGE_C'], self.config['IMAGE_H'], self.config['IMAGE_W']))                         # input images
        b_batch = np.zeros((self.batch_size, 1, 1, 1, self.config['TRUE_BOX_BUFFER'], 4))   # list of self.config['TRUE_self.config['BOX']_BUFFER'] GT boxes
        # turam - removed space for anchor boxes
        # y_batch = np.zeros((r_bound - l_bound, self.config['GRID_H'],  self.config['GRID_W'], self.config['BOX'], 4+1+len(self.config['LABELS'])))                # desired network output
        y_batch = np.zeros((self.batch_size, self.config['GRID_H'], self.config['GRID_W'], self.config['BOX'], 4 + 1 + len(self.config['LABELS'])))                # desired network output

        global_image_index = self.batch_size * idx
        image_index = global_image_index % self.evts_per_file
        file_index = global_image_index // self.evts_per_file

        logger.debug('[{0}] thread {1} opening file with idx {2} file_index {3} image_index {4}'.format(time.time() - start,threadmod.get_ident(), idx, file_index,image_index))

        if file_index < len(self.filelist):
            file_content = np.load(self.filelist[file_index])
        else:
            raise Exception('file_index {0} is outside range for filelist {1}'.format(file_index,len(self.filelist)))

        for i in range(self.config['BATCH_SIZE']):
            logger.debug('[{0}] loop {1} start'.format(time.time() - start,i))

            if image_index >= self.evts_per_file:
              file_index += 1
              file_content = np.load(self.filelist[file_index])
              image_index = 0

            x_batch[instance_count] = file_content['raw'][image_index]
            all_objs = file_content['truth'][image_index]

            logger.debug('[{0}] loop {1} file loaded'.format(time.time() - start,i))

            # augment input image and fix object's position and size
            # img, all_objs = self.aug_image(img, all_objs, jitter=self.jitter)

            # construct output from object's x, y, w, h
            true_box_index = 0

            for obj in all_objs:
                center_x = obj[BBOX_CENTER_X]
                center_x = center_x / self.pix_per_grid_x
                center_y = obj[BBOX_CENTER_Y]
                center_y = center_y / self.pix_per_grid_y

                grid_x = int(center_x)
                grid_y = int(center_y)

                center_w = (obj[BBOX_WIDTH]) / self.pix_per_grid_x  # unit: grid cell
                center_h = (obj[BBOX_HEIGHT]) / self.pix_per_grid_y  # unit: grid cell

                box = [center_x, center_y, center_w, center_h]

                # turam - note: removed anchor box handling

                # assign ground truth x, y, w, h, confidence and class probs to y_batch
                y_batch[instance_count, grid_y, grid_x, 0, 0:4] = box
                y_batch[instance_count, grid_y, grid_x, 0, 4] = 1.
                y_batch[instance_count, grid_y, grid_x, 0, 5:5 + self.num_classes] = obj[5:5 + self.num_classes]

                # assign the true box to b_batch
                b_batch[instance_count, 0, 0, 0, true_box_index] = box

                true_box_index += 1
                # true_box_index = true_box_index % self.config['TRUE_BOX_BUFFER']

            logger.debug('[{0}] loop {1} images converted'.format(time.time() - start,i))

            # assign input image to x_batch
            # if self.norm is not None:
            #    x_batch[instance_count] = self.norm(img)

            # turam - disable plotting

            """
            else:
                # plot image and bounding boxes for sanity check
                for obj in all_objs:
                    if obj['xmax'] > obj['xmin'] and obj['ymax'] > obj['ymin']:
                        cv2.rectangle(img[:,:,::-1], (obj['xmin'],obj['ymin']), (obj['xmax'],obj['ymax']), (255,0,0), 3)
                        cv2.putText(img[:,:,::-1], obj['name'],
                                    (obj['xmin']+2, obj['ymin']+12),
                                    0, 1.2e-3 * img.shape[0],
                                    (0,255,0), 2)

                x_batch[instance_count] = img
            """

            # increase instance counter in current batch
            instance_count += 1
            image_index += 1

        logger.debug('[{0}] exiting'.format(time.time() - start))

        # print(' new batch created', idx)

        return [x_batch, b_batch], y_batch

    def on_epoch_end(self):
        if self.shuffle:
            np.random.shuffle(self.filelist)

    """
    def aug_image(self, image, all_objs, jitter):
        h, w, c = image.shape

        if jitter:
            ### scale the image
            scale = np.random.uniform() / 10. + 1.
            image = cv2.resize(image, (0,0), fx = scale, fy = scale)

            ### translate the image
            max_offx = (scale-1.) * w
            max_offy = (scale-1.) * h
            offx = int(np.random.uniform() * max_offx)
            offy = int(np.random.uniform() * max_offy)

            image = image[offy : (offy + h), offx : (offx + w)]

            ### flip the image
            flip = np.random.binomial(1, .5)
            if flip > 0.5: image = cv2.flip(image, 1)

            image = self.aug_pipe.augment_image(image)

        # resize the image to standard size
        image = cv2.resize(image, (self.config['IMAGE_H'], self.config['IMAGE_W']))
        image = image[:,:,::-1]

        # fix object's position and size
        for obj in all_objs:
            for attr in ['xmin', 'xmax']:
                if jitter: obj[attr] = int(obj[attr] * scale - offx)

                obj[attr] = int(obj[attr] * float(self.config['IMAGE_W']) / w)
                obj[attr] = max(min(obj[attr], self.config['IMAGE_W']), 0)

            for attr in ['ymin', 'ymax']:
                if jitter: obj[attr] = int(obj[attr] * scale - offy)

                obj[attr] = int(obj[attr] * float(self.config['IMAGE_H']) / h)
                obj[attr] = max(min(obj[attr], self.config['IMAGE_H']), 0)

            if jitter and flip > 0.5:
                xmin = obj['xmin']
                obj['xmin'] = self.config['IMAGE_W'] - obj['xmax']
                obj['xmax'] = self.config['IMAGE_W'] - xmin

        return image, all_objs
        """

def global_to_grid(x,y,w,h,num_grid_x,num_grid_y):
   ''' convert global bounding box coords to
   grid coords. x,y = box center in relative coords
   going from 0 to 1. w,h are the box width and
   height in relative coords going from 0 to 1.
   num_grid_x,num_grid_y define the number of bins
   in x and y for the grid.
   '''
   global_coords  = [x,y]
   global_sizes   = [w,h]
   num_grid_bins  = [num_grid_x,num_grid_y]
   grid_coords    = [0.,0.]
   grid_sizes     = [0.,0.]
   for i in range(len(global_coords)):
      grid_bin_size = 1. / num_grid_bins[i]
      grid_bin = int(global_coords[i] / grid_bin_size)
      grid_coords[i] = (global_coords[i] - grid_bin_size * grid_bin) / grid_bin_size
      grid_sizes[i] = (global_sizes[i] / grid_bin_size)

   return grid_coords,grid_sizes

def grid_to_global(grid_bin_x, grid_bin_y,grid_x,grid_y,grid_w,grid_h,num_grid_x,num_grid_y):
   ''' inverse of global_to_grd '''
   grid_bins      = [grid_bin_x,grid_bin_y]
   grid_coords    = [grid_x,grid_y]
   grid_sizes     = [grid_w,grid_h]
   num_grid_bins  = [num_grid_x,num_grid_y]
   global_coords  = [0.,0.]
   global_sizes   = [0.,0.]
   for i in range(len(global_coords)):
      grid_bin_size     = 1. / num_grid_bins[i]
      global_coords[i]  = (grid_bins[i] + grid_coords[i]) * grid_bin_size
      global_sizes[i]   = grid_sizes[i] * grid_bin_size

   return global_coords,global_sizes


from z3 import *

x = Int('x')
y = Int('y')

s = Solver()

s.add(x <= 10, x >= 0)

s.add(Not(x == 11), True)

print(s.check())

m = s.model()
print(m)


from tkinter import Tk, BOTH
from tkinter.ttk import Frame , Label , Notebook , Style, Combobox
from tkinter.font import Font
import tkinter.font as fonts

families=[]
for font in dir(fonts):
	if font.isupper():
		families.append(font)

print(help(Font))

class Example(Frame):
	def __init__(self , parent):
		Frame.__init__(self , parent)
		self.parent = parent
		self.initUI()
	def initUI(self):
		self.parent.title("Fonts")
		self.pack(fill=BOTH , expand=True)
		txt = "Tkinter is a default Python GUI toolkit"
		myfont = Font(family="Ubuntu Mono", size=16)
		label1 = Label(self , text=txt , font=myfont)
		label1.grid(row=0, column=0)
		label2 = Label(self , text=txt , font="TkTextFont")
		label2.grid(row=1, column=0)
		label3 = Label(self , text=txt , font=('Times', '18', 'italic'))
		label3.grid(row=2, column=0)

		labelfamily=Label(self,text='Font Style',font='Calibri 12 bold')
		cbofamily=Combobox(self,width=30,values=families)

		labelfamily.grid(row=3,column=0,sticky='nw')
		cbofamily.grid(row=3,column=0,padx=100,sticky='nw')

def main():
	root = Tk()
	ex = Example(root)
	root.geometry("+300+300")
	root.mainloop()
if __name__ == '__main__':
	main()


"""
:copyright (c) 2014 - 2018, The Regents of the University of California, through Lawrence Berkeley National Laboratory (subject to receipt of any required approvals from the U.S. Department of Energy) and contributors. All rights reserved.  # NOQA
:author
"""

from __future__ import unicode_literals

import logging

from django.core.management.base import BaseCommand

from _localtools import logging_info
from seed.models import PropertyState
from seed.models import TaxLotState

logging.basicConfig(level=logging.DEBUG)

class Command(BaseCommand):
    def add_arguments(self, parser):
        parser.add_argument('--org', dest='organization', default=False)
        parser.add_argument('--stats', dest='stats', default=False, action="store_true")
        return

    def handle(self, *args, **options):
        logging_info("RUN  org_specific_commands with args={},kwds={}".format(args, options))
        if options['organization']:
            core_organization = list(map(int, options['organization'].split(",")))
        else:
            core_organization = [20, 69]

        logging_info("Processing organization list: {}".format(core_organization))

        for org in core_organization:
            process_org(org)

        logging_info("END org_specific_commands")
        return

def process_org(org):
    if org == 20:
        do_process_org_20()
    elif org == 69:
        do_process_org_69()

    return

def do_process_org_69():
    print("Single Commands for org=69")
    org_pk = 69

    tax_attrs_to_clear = ["address_line_1", "city", "state", "postal_code"]
    property_attrs_to_clear = ["address_line_1", "city", "state", "postal_code"]

    for ndx, property_state in enumerate(PropertyState.objects.filter(organization_id=org_pk).all()):
        for pa in property_attrs_to_clear:
            setattr(property_state, pa, None)
            property_state.save()

    for ndx, taxlot_state in enumerate(TaxLotState.objects.filter(organization_id=org_pk).all()):
        for ta in tax_attrs_to_clear:
            setattr(taxlot_state, ta, None)
            taxlot_state.save()
    return

def do_process_org_20():
    print("Single Commands for org=20")
    count = PropertyState.objects.filter(organization_id=20).count()
    for ndx, prop in enumerate(PropertyState.objects.filter(organization_id=20).all()):
        print("Processing {}/{}".format(ndx + 1, count))

        if prop.address_line_1:
            prop.extra_data["Address 1"] = prop.address_line_1
            prop.address_line_1 = None

        if prop.address_line_2:
            prop.extra_data["Address 2"] = prop.address_line_2
            prop.address_line_2 = None

        if prop.normalized_address:
            prop.extra_data["Normalized Address"] = prop.normalized_address
            prop.normalized_address = None

        prop.save()

    for ndx, tl in enumerate(TaxLotState.objects.filter(organization_id=20).all()):
        tl.address_line_1 = None
        tl.address_line_2 = None
        tl.normalized_address = None
        tl.save()


"""
Assignment 4: Neural Network
Part 2

@author: Divyam Jain
         17HS20047
"""
#Importing some essential libraries

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import string
import math

#Importing the dataset

dataset = pd.read_csv('Assignment_4_data.txt', header=None, delimiter='\t')

"""------Preprocessing------"""

#Removing punctuations

dataset2 = pd.DataFrame(index=range(len(dataset)),columns=[0,1])
dataset2[0]=dataset[0]
for i in range(len(dataset)):
    dataset2[1][i]=dataset[1][i].translate(str.maketrans('', '', string.punctuation))

#Convert into lowercase

dataset2[1] = dataset2[1].apply(lambda x: " ".join(x.lower() for x in x.split()))

#Removing stopwords

stop = np.loadtxt("NLTK's list of english stopwords", dtype='str')
dataset2[1] = dataset2[1].apply(lambda x: " ".join(x for x in x.split() if x not in stop))

#Removing stop words spelt in another way
freq = pd.Series(' '.join(dataset2[1]).split()).value_counts()[:500]
freq_common = ['u', '2', 'im', 'ur', '4', 'dont', 'ü', 'r', 'da', 'd', 'wat', 'n', 'cant', 'thats', 'didnt', 'ive','dun', 'youre', 'v' ]

dataset2[1] = dataset2[1].apply(lambda x: " ".join(x for x in x.split() if x not in freq_common))

#Applying Porter Stemming

from nltk.stem import PorterStemmer

st=PorterStemmer()
dataset2[1] = dataset2[1].apply(lambda x: " ".join([st.stem(word) for word in x.split()]))

#Removing extremely rare words (that only appear once)
freq_rare = pd.Series(' '.join(dataset2[1]).split()).value_counts()
freq_rare = freq_rare[freq_rare==1]
freq_rare = list(freq_rare.index)
dataset2[1] = dataset2[1].apply(lambda x: " ".join(x for x in x.split() if x not in freq_rare))

#Tokenization

dataset3=dataset2.copy()
for i in range(len(dataset)):
    dataset3[1][i]=dataset2[1][i].split()

#Splitting into training set and test set

from sklearn.model_selection import train_test_split

X_train, X_test, Y_train, Y_test = train_test_split(dataset3[1].values, dataset3[0].values, test_size=0.2)

#Making the vector V

V = np.unique(np.array(' '.join(dataset2[1]).split()))

#Create an input and output representation

   #For training
rep_in = pd.DataFrame(0,index=V, columns = range(len(X_train)))

for i in range(len(X_train)):
    for j in X_train[i]:
        rep_in[i][j]=1

rep_out = np.ndarray((len(Y_train),1))
for i in range(len(Y_train)):
    if Y_train[i]=='spam':
        rep_out[i][0]=1
    else:
        rep_out[i][0]=0

   #For testing
reptest_in = pd.DataFrame(0,index=V, columns = range(len(X_test)))

for i in range(len(X_test)):
    for j in X_test[i]:
        reptest_in[i][j]=1

reptest_out = np.ndarray((len(Y_test),1))
for i in range(len(Y_test)):
    if Y_test[i]=='spam':
        reptest_out[i][0]=1
    else:
        reptest_out[i][0]=0

#Building the neural network

n = 3   # n = number of layers

X = []
xx = np.ndarray(shape=(len(V)+1,1))
X.append(xx)
hl_1 = int(input('How many neurons do you want in the first hidden layer?'))
xx = np.ndarray(shape=(hl_1+1,1))
X.append(xx)
hl_2 = int(input('How many neurons do you want in the second hidden layer?'))
xx = np.ndarray(shape=(hl_2+1,1))
X.append(xx)
xx = np.ndarray(shape=(2,1))
X.append(xx)

#Weight initialiser

W = []
for i in range(1,n):
    W.append(np.random.randn(len(X[i-1]),len(X[i])-1)/100)
W.append(np.random.randn(len(X[n-1]),len(X[n]))/100)

#Forward Pass

def forward(zero_layer):

    for i in range(0,n):
        X[i][0][0]=1

    X[0][1:,0]=zero_layer

    for i in range(1,n):
        for j in range(1,len(X[i])):
            X[i][j][0]=1/(1+math.exp(-1*np.matmul(X[i-1].T,W[i-1][:,j-1])[0]))

    for j in range(0,len(X[n])):
        #print('cccccccccccc')
        #print(np.matmul(X[n-1].T,W[n-1][:,j])[0])
        X[n][j][0]=math.exp(np.matmul(X[n-1].T,W[n-1][:,j])[0])

    total = np.sum(X[n])

    for j in range(0,len(X[n])):
        X[n][j][0]=X[n][j][0]/total

#Back Propogation

def backward(actual):
    delta = [None]*n
    #print('Holoooooo')
    #print(X[n][0][0])
    if (X[n][0][0]==1 and actual==1) or (X[n][1][0]==1 and actual==0):
        error = 0
    else:
        error = -(actual*math.log(X[n][0][0])+(1-actual)*math.log(X[n][1][0]))

    delta[n-1]=np.ndarray(shape=(2,1))

    delta[n-1][0][0]=(X[n][0][0]-actual)
    delta[n-1][1][0]=(X[n][1][0]-(1-actual))

    for i in range(n-1,0,-1):
        delta[i-1]=np.ndarray(shape=(len(X[i])-1,1))
        for j in range(1,len(X[i])):
            delta[i-1][j-1][0]=0
            for k in range(0,len(delta[i])):
                delta[i-1][j-1][0]+=delta[i][k][0]*W[i][j][k]
            delta[i-1][j-1][0]=X[i][j][0]*(1-X[i][j][0])*delta[i-1][j-1][0]

    alpha = 0.1 #learning rate
    for i in range(0,len(W)):
        for j in range(0,len(W[i])):
            for k in range(0,len(delta[i])):
                W[i][j][k]=W[i][j][k]-alpha*X[i][j][0]*delta[i][k][0]

#Training

def training (epochs):

    for i in range(epochs):
        for j in range(len(X_train)):
            print("Epoch:",i,"Sample:",j)
            forward(rep_in[j])
            backward(rep_out[j][0])
        training_accuracy[i], test_accuracy[i] = accuracy(i)

training_accuracy = np.zeros(10)
test_accuracy = np.zeros(10)
predicted_train = [[],[],[],[],[],[],[],[],[],[]]
predicted_test = [[],[],[],[],[],[],[],[],[],[]]

def accuracy(index):

    #Training Accuracy
    for i in range(len(X_train)):
            forward(rep_in[i])
            if X[n][0][0]>X[n][1][0]:
                predicted_train[index].append(1)
            else:
                predicted_train[index].append(0)

    count = 0
    for i in range(len(predicted_train[index])):
        if predicted_train[index][i]==rep_out[i][0]:
            count+=1
    training_accuracy = count/len(predicted_train[index])*100

    #Test Accuracy

    for i in range(len(X_test)):
            forward(reptest_in[i])
            if X[n][0][0]>X[n][1][0]:
                predicted_test[index].append(1)
            else:
                predicted_test[index].append(0)

    count = 0
    for i in range(len(predicted_test[index])):
        if predicted_test[index][i]==reptest_out[i][0]:
            count+=1
    test_accuracy = count/len(predicted_test[index])*100

    return training_accuracy,test_accuracy

#Running the network

training(10)

#Plotting the graph

plt.plot([1,2,3,4,5,6,7,8,9,10], training_accuracy, color = 'red')
plt.plot([1,2,3,4,5,6,7,8,9,10], test_accuracy, color = 'blue')
plt.title('Training accuracy and Test accuracy for epoch 1 to 10')
plt.xlabel('Number of epochs')
plt.ylabel('Accuracy')
plt.legend(labels=('Training accuracy', 'Test accuracy'))
plt.show()

#To calculate training and test set errors
'''
pred_train = []
pred_test = []
def acc():

    #Training Accuracy
    for i in range(len(X_train)):
            forward(rep_in[i])
            pred_train.append(X[n][0][0])
    error=0
    for i in range(len(pred_train)):
        if (pred_train[i]==1 and rep_out[i][0]==1 ) or (pred_train[i]==0 and rep_out[i][0]==0):
            error+=0
        else:
            error += -(rep_out[i][0]*math.log(pred_train[i])+(1-rep_out[i][0])*math.log(1-pred_train[i]))

    train_error = error/len(X_train)

    #Test Accuracy

    for i in range(len(X_test)):
            forward(reptest_in[i])
            pred_test.append(X[n][0][0])

    error=0
    for i in range(len(pred_test)):
        if (pred_test[i]==1 and reptest_out[i][0]==1 ) or (pred_test[i]==0 and reptest_out[i][0]==0):
            error+=0
        else:
            error += -(reptest_out[i][0]*math.log(pred_test[i])+(1-reptest_out[i][0])*math.log(1-pred_test[i]))

    test_error = error/len(X_test)

    return train_error,test_error

train_error,test_error = acc()
'''

Assignment 4 - Neural Networks/Part2_A4.py


# distanza.py

# calcola la distanza tra due punti del piano

def distanza(p1, p2):
    # P1 e P2 sono tuple del tipo (x, y)
    dx = p1[0] - p2[0]
    dy = p1[1] - p2[1]

    return (dx**2 + dy**2)**0.5

def input_coordinate():
    x = input('Coordinata x: ')
    y = input('Coordinata y: ')

    return ( float(x), float(y) )

def stampa_coordinate(p):
    print('x:', p[0])
    print('y:', p[1])

# main
print("Distanza tra due punti")

print("\nPunto 1:")
p1 = input_coordinate()

print("\nPunto 2:")
p2 = input_coordinate()

print("\nPrimo punto:")
stampa_coordinate(p1)

print("\nSecondo punto:")
stampa_coordinate(p2)

print("\nDistanza tra i punti:", distanza(p1, p2))


word=input("Enter a string:")
vowlist=['a','e','i','o','u']
conscount=0
vowcount=0
space=0
for char in word:
	if char in vowlist:
		vowcount+=1
	elif char==' ':
		space+=1

	else:
		conscount+=1
print("no of vowels is",vowcount)
print("no of consonants is",conscount)


## Design Circular Queue

# Example 1:
# Input
# ["MyCircularQueue", "enQueue", "enQueue", "enQueue", "enQueue", "Rear", "isFull", "deQueue", "enQueue", "Rear"]
# [[3], [1], [2], [3], [4], [], [], [], [4], []]
# Output
# [null, true, true, true, false, 3, true, true, true, 4]

# Explanation
# MyCircularQueue myCircularQueue = new MyCircularQueue(3);
# myCircularQueue.enQueue(1); // return True
# myCircularQueue.enQueue(2); // return True
# myCircularQueue.enQueue(3); // return True
# myCircularQueue.enQueue(4); // return False
# myCircularQueue.Rear();     // return 3
# myCircularQueue.isFull();   // return True
# myCircularQueue.deQueue();  // return True
# myCircularQueue.enQueue(4); // return True
# myCircularQueue.Rear();     // return 4

## Rohan's Implementation
class MyCircularQueue:

    def __init__(self, k: int):
        self.arr = [None for _ in range(k)]
        self.len = k
        self.head = None
        self.tail = None
        self.debug = False
        if self.debug:
            print('-'*35)
            print(self.arr)

    def enQueue(self, value: int) -> bool:
        if self.debug:
            print("Current Capacity: ",self.currCapacity())
            print("Head: {}, Tail: {}".format(self.head, self.tail))
        if self.isEmpty():
            self.head = 0
            self.tail = 0
            self.arr[self.tail] = value

        elif self.isFull():
            if self.debug:  print("enQueue: FULL\n")
            return False

        else:
            self.tail+=1
            if not self.tail < self.len:
                self.tail=0
            self.arr[self.tail] = value

        if self.debug:
            print("Head: {}, Tail: {}".format(self.head, self.tail))
            print("enQueue: ",self.arr)
            print()
        return True

    def deQueue(self) -> bool:
        if self.debug:
            print("Current Capacity: ",self.currCapacity())
            print("Head: {}, Tail: {}".format(self.head, self.tail))
        if self.isEmpty():
            self.head = None
            self.tail = None
            if self.debug:  print("deQueue: EMPTY\n")
            return False
        elif self.head==self.tail:
            self.arr[self.head] = None
            self.head = self.tail = None
        else:
            self.arr[self.head] = None
            self.head +=1
            if not self.head < self.len:
                self.head = 0
        if self.debug:
            print("Head: {}, Tail: {}".format(self.head, self.tail))
            print("deQueue: ",self.arr)
            print()
        return True

    def Front(self) -> int:
        if not self.isEmpty() and self.head!=None:
            return self.arr[self.head]
        else:
            return -1

    def Rear(self) -> int:
        if not self.isEmpty() and self.tail!=None:
            return self.arr[self.tail]
        else:
            return -1

    def isEmpty(self) -> bool:
        return self.currCapacity()==0

    def isFull(self) -> bool:
        return self.currCapacity() == self.len

    def currCapacity(self) -> int:
        if self.tail==self.head==None:
            return 0
        elif self.tail>=self.head:
            return (self.tail - self.head + 1)
        else:
            return (self.len - self.head) + (self.tail + 1)

## Better Leetcode Implementation
class MyCircularQueue:

    def __init__(self, k: int):
        self.queue = [0]*k
        self.headIndex = 0
        self.count = 0
        self.capacity = k

    def enQueue(self, value: int) -> bool:
        if self.count == self.capacity:
            return False
        self.queue[(self.headIndex + self.count) % self.capacity] = value
        self.count += 1
        return True

    def deQueue(self) -> bool:
        if self.count == 0:
            return False
        self.headIndex = (self.headIndex + 1) % self.capacity
        self.count -= 1
        return True

    def Front(self) -> int:
        if self.count == 0:
            return -1
        return self.queue[self.headIndex]

    def Rear(self) -> int:
        if self.count == 0:
            return -1
        return self.queue[(self.headIndex + self.count - 1) % self.capacity]

    def isEmpty(self) -> bool:
        return self.count == 0

    def isFull(self) -> bool:
        return self.count == self.capacity

# Your MyCircularQueue object will be instantiated and called as such:
# obj = MyCircularQueue(k)
# param_1 = obj.enQueue(value)
# param_2 = obj.deQueue()
# param_3 = obj.Front()
# param_4 = obj.Rear()
# param_5 = obj.isEmpty()
# param_6 = obj.isFull()


from totalimpactwebapp.util import cached_property
from totalimpactwebapp.util import dict_from_dir
from urlparse import urlparse
from totalimpactwebapp import db
from totalimpactwebapp import json_sqlalchemy

class BiblioRow(db.Model):

    __tablename__ = 'biblio'
    tiid = db.Column(db.Integer, db.ForeignKey('item.tiid'), primary_key=True)
    provider = db.Column(db.Text, primary_key=True)
    biblio_name = db.Column(db.Text, primary_key=True)
    biblio_value = db.Column(json_sqlalchemy.JSONAlchemy(db.Text))
    collected_date = db.Column(db.DateTime())

    def __init__(self, **kwargs):
        super(BiblioRow, self).__init__(**kwargs)

        #if aliases.best_url is not None:
        #    self.url = aliases.best_url

class Biblio(object):

    def __init__(self, biblio_rows):

        # build out the properties of this object
        for row in biblio_rows:

            # if we don't have it already, write it.
            if not hasattr(self, row.biblio_name):
                setattr(self, row.biblio_name, row.biblio_value)

            # if it's from the user, write it; those always win.
            elif row.provider == "user_provided":
                setattr(self, row.biblio_name, row.biblio_value)

            else:
                pass

        #if aliases.best_url is not None:
        #    self.url = aliases.best_url

    @cached_property
    def display_year(self):
        try:
            return str(self.year)
        except AttributeError:
            return None

    @cached_property
    def calculated_genre(self):
        if hasattr(self, "genre") and self.genre:
            if self.genre not in ["undefined", "other"]:
                return self.genre

        if hasattr(self, "journal") and self.journal:
            return "article"

        return None

    @cached_property
    def calculated_host(self):
        try:
            return self.repository.split(" ")[0].lower()
        except AttributeError:
            return None

    @cached_property
    def display_authors(self):
        try:
            auths = ",".join(self.authors.split(",")[0:3])
            if len(auths) < len(self.authors):
                auths += " et al."
        except AttributeError:
            auths = None

        return auths

    @cached_property
    def display_title(self):
        try:
            return self.title
        except AttributeError:
            return "no title"

    @cached_property
    def free_fulltext_host(self):
        try:
            return self._get_url_host(self.free_fulltext_url)
        except AttributeError:
            return None

    def _get_url_host(self, url):
        # this should actually be done upstream, where we have a list of
        # free-fulltext DOI fragments. this quick hack gets a few for now.

        parsed = urlparse(url)
        if parsed.path.startswith("/10.1371"):
            host = "Public Library of Science"
        elif parsed.path.startswith("/10.6084"):
            host = "figshare"
        elif parsed.netloc == "www.ncbi.nlm.nih.gov/":
            host = "PubMed Central"
        else:
            host = parsed.netloc

        return host

    def to_dict(self):
        ret = dict_from_dir(self, "rows")
        return ret


#!/usr/bin/env python

import pickle

def grab_nocache(url):
    import urllib2
    req = urllib2.Request(url)
    response = urllib2.urlopen(req)
    #print(response.info())
    the_page = response.read()
    return the_page

def unpickle_d():
    try:
        return pickle.load( open( "save.p", "rb" ) )
    except:
        return dict()

def pickle_d(the_dict):
    pickle.dump(the_dict, open( "save.p", "wb" ) )

_pd = None

def grab(url, cache = True):
    print(url)
    global _pd
    if not _pd: _pd = unpickle_d()
    if cache and url in _pd:
        return _pd[url]
    s = grab_nocache(url)
    _pd[url] = s
    pickle_d(_pd)
    return s


"""
Problem:

Julius Caesar is credited with inventing one of the first ways

of encrypting messages for transmission. A Caesar cipher works

by replacing each of the characters in a piece of text with the

character a certain number of spaces along in the alphabet.

For example, if we moved 'APE' 3 along it would become 'DSH'.

Moving past 'Z' should take us back to 'A'.

The function 'encode' takes a piece of text and should move

it along the alphabet n spaces.

The function 'decode' should do the opposite.

All text will be given in uppercase. No punctuation will be

included, other than spaces - these should not be encoded.

Tests:

>>> encode("APE", 3)
DSH

>>> encode("HELLO WORLD", 12)
TQXXA IADXP

>>> encode("JULIUS CAESAR", 9)
SDURDB LJNBJA

>>> decode("DSH", 3)
APE

>>> decode("SDURB LJNBJA", 9)
JULIS CAESAR

>>> decode("TQXXA IADXP", 12)
HELLO WORLD

"""
import doctest
def run_tests():
    doctest.testmod(verbose=True)

def decode(word, shift):
    encode(word, -shift)

def encode(word, shift):
    ciphertext = ""
    for char in word:
        if char == " ":
            ciphertext += " "
        else:
            ascii_shifted = ord(char) - ord('A')
            ciphertext += chr(((ascii_shifted + shift) % 26) + ord('A'))

    print(ciphertext)

if __name__ == "__main__":
    run_tests()


import d2bot.visualizer as visualizer
import d2bot.core.game_env as game_env
import d2bot.simulator as simulator

from d2bot.torch.a3c.ActorCritic import ActorCritic

import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torch.autograd import Variable

import random
import time
import sys

from tensorboardX import SummaryWriter
writer = SummaryWriter()

'''
    model from https://github.com/ikostrikov/pytorch-a3c
'''

class Spliter(torch.nn.Module):

    def __init__(self, num_inputs, num_hidden):
        super(Spliter, self).__init__()

        self.num_hidden = num_hidden
        self.num_inputs = num_inputs
        self.num_outs = 2

        self.lstm_layer = nn.LSTM(num_inputs, self.num_hidden)

        self.linear = nn.Linear(self.num_hidden, self.num_outs)
        self.train()

    def forward(self, inputs):
        t = torch.FloatTensor(inputs)
        t = t.view(len(inputs),1,-1)

        lstm_outs,_ = self.lstm_layer(t)
        lstm_out = lstm_outs[-1]
        lstm_out = F.tanh(lstm_out)
        out = self.linear(lstm_out)
        return out

class SpliterWarpper:
    def __init__(self,num_inputs, num_hidden):
        self.nn_spliter = Spliter(num_inputs, num_hidden)
        self.optimizer = optim.SGD(self.nn_spliter.parameters(), lr=0.01)
        self.outs = []
        self.nll_loss_fn = nn.NLLLoss()

    def reset(self):
        self.outs.clear()

    def step(self, inputs):
        out = F.log_softmax(self.nn_spliter(inputs))
        self.outs.append(out)

    def train(self, labels):
        assert(len(labels) == len(self.outs))
        labels = labels.type(torch.LongTensor)
        loss = self.nll_loss_fn(torch.cat(self.outs),labels) / len(labels)
        pred = torch.cat(self.outs)
        score = torch.argmax(pred,1) == labels
        print(loss,
            float(sum(score).numpy()) / len(labels),
            float(sum(labels).numpy()) / len(labels))

        writer.add_scalar("train/spliter_loss",loss.item())
        writer.add_scalar("train/spliter_score",sum(score).item() / len(labels))
        writer.add_scalar("train/acc",sum(score).item() / len(labels))

        loss.backward()
        self.reset()

    def update(self):
        self.optimizer.step()
        self.optimizer.zero_grad()
        self.nn_spliter.zero_grad()

class A3CSpliterEnv(game_env.GameEnv):
    def __init__(self, *args, **kwargs):
        super(A3CSpliterEnv,self).__init__(*args, **kwargs)

        random.seed(time.time())

        self.game_no = 0

        self.out_classes = 9

        self.a3c_model = ActorCritic(5, self.out_classes, 128)
        self.a3c_model.load_state_dict(torch.load('F:\\Dota2BotStepByStep\\tmp\\model_3023_24392'))
        self.optimizer = optim.SGD(self.a3c_model.parameters(), lr=0.01)

        self.reset()

        self.gamma = 0.99
        self.tau = 1.0
        self.entropy_coef = 0.01

        self.batch_size = 256
        self.buffer_size = 1000
        self.i = 0

        self.nll_loss_fn = nn.NLLLoss()

        self.sw = SpliterWarpper(5, 128)

    def reset(self):
        self.entropies = []
        self.values = []
        self.rewards = []
        self.log_probs = []
        self.raw_log_probs = []
        self.raw_probs = []
        self.predefined_steps = []

    def update(self):
        print("Game %d updating"%self.game_no)
        self.optimizer.step()
        self.a3c_model.zero_grad()
        self.optimizer.zero_grad()
        self.sw.update()

    def train(self):
        #just make it simple

        R = torch.zeros(1, 1)
        gae = torch.zeros(1, 1)

        self.values.append(R)

        policy_loss = 0
        value_loss = 0
        teacher_loss = 0

        for i in reversed(range(len(self.rewards))):
            R = self.gamma * R + self.rewards[i]
            adv = R - self.values[i]
            value_loss = value_loss + 0.5 * adv.pow(2)

            #GAE
            delta_t = self.rewards[i] + self.gamma * self.values[i + 1].data - self.values[i].data
            gae = gae * self.gamma * self.tau + delta_t

            policy_loss = policy_loss - self.log_probs[i] * Variable(gae) - self.entropy_coef * self.entropies[i]

            #teacher_loss = teacher_loss + self.nll_loss_fn(self.raw_log_probs[i], self.predefined_steps[i])

        teacher_loss = torch.cat(self.raw_probs)
        teacher_loss = teacher_loss - torch.zeros(len(self.predefined_steps),self.out_classes).scatter_(1, torch.cat(self.predefined_steps).view(-1,1), 1)
        teacher_loss = torch.sum(teacher_loss ** 2)

        total_loss = (policy_loss + 0.5 * value_loss + teacher_loss)
        total_loss = total_loss / len(self.raw_probs)
        #print(total_loss)
        total_loss.backward()
        torch.nn.utils.clip_grad_norm(self.a3c_model.parameters(), 10)

        print("reward %f"%sum(self.rewards))

        writer.add_scalar("train/loss",total_loss.item())
        writer.add_scalar("train/policy_loss",policy_loss.item() / len(self.raw_probs))
        writer.add_scalar("train/policy_loss",value_loss.item() / len(self.raw_probs))
        writer.add_scalar("train/teacher_loss",teacher_loss.item() / len(self.raw_probs))
        writer.add_scalar("train/rewards",sum(self.rewards))
        writer.add_scalar("train/values",sum(self.values).item() / len(self.values))
        writer.add_scalar("train/entropy",sum(self.entropies).item() / len(self.entropies))

        acts = torch.cat(self.raw_log_probs)
        pd = torch.tensor(self.predefined_steps)
        self.sw.train(torch.argmax(acts,1) == pd)

    def _generator_run(self, input_):
        self.game_no = self.game_no + 1
        self.init_fn(input_)

        self.engine = simulator.Simulator(feature_name='unit_test1',
            actionspace_name='lattice1',
            canvas=self.canvas)

        self.reset()
        self.sw.reset()

        while self.engine.get_time() < 300:
            self.i = self.i + 1

            #print(dire_predefine_step)
            dire_state = self.engine.get_state_tup("Dire", 0)

            dire_predefine_step = self.engine.predefined_step("Dire",0)
            predefine_move = torch.LongTensor([dire_predefine_step[1]])

            is_end = dire_state[2]
            if is_end:
                break

            self.predefined_steps.append(predefine_move)
            action_out, value_out = self.a3c_model(dire_state[0])

            self.sw.step(dire_state[0])

            prob = F.softmax(action_out)
            self.raw_probs.append(prob)
            log_prob = F.log_softmax(action_out)
            self.raw_log_probs.append(log_prob)

            entropy = - (log_prob * prob).sum(1, keepdim=True)
            self.entropies.append(entropy)

            #action = prob.multinomial(num_samples=1).data
            action = torch.argmax(log_prob, 1).data.view(-1,1)
            log_prob = log_prob.gather(1,Variable(action))

            self.engine.set_order("Dire", 0, (1,action))

            self.engine.loop()

            reward = dire_state[1]
            self.rewards.append(reward)
            self.values.append(value_out)
            self.log_probs.append(log_prob)

            yield

        self.train()
        self.update()

def test():
    v = visualizer.Visualizer(A3CSpliterEnv)
    v.visualize()

def test_without_gui():
    env = A3CSpliterEnv()
    gen = env.run(True)
    gen.send(None)
    while True:
        try:
            gen.send((None,))
        except StopIteration:
            gen = env.run(True)
            gen.send(None)

if __name__ == '__main__':
    if len(sys.argv) == 2:
        if sys.argv[1] == "visible":
            test()
    test_without_gui()


from elastalert.alerts import Alerter, BasicMatchString

class TivoliAlerter(Alerter):
    file = open("testfile.txt","a")

    file.write("Hello World")
    file.write("This is our new text file")
    file.write("and this is another line.")
    file.write("Why? Because we can.\n")

    file.close()


import requests
from bs4 import BeautifulSoup as bs
import django
import os
import datetime
import string
import logging
import time
import sys

logging.basicConfig(filename='crawler.log',format='%(asctime)s %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p', level=logging.INFO)
logger = logging.getLogger(__name__)

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "vegetable.settings")
django.setup()

from django.db import transaction

from search.models import (
    Item,
    ItemType,
    Record
)
from spider.const import (
    BASE_URL,
    SLEEP_TIME,
    INDEX_TYPE_MAPPER
)

CREATE_DATETIME = datetime.datetime.now()

def veg_spider(item_type, oldest_date=None):
    if oldest_date is None:
        oldest_date = datetime.datetime.now().date()
    if not isinstance(oldest_date, datetime.date):
        try:
            oldest_date = datetime.datetime.strptime(oldest_date, '%Y-%m-%d').date()
        except ValueError:
            raise Exception("Oldest_date not invalid Error")

    stop = False
    page = 1

    records = []

    while not stop:
        logging.info('crawling page {} start'.format(page))
        url = BASE_URL.format(item_type=item_type, page=page)
        logging.info('url {}'.format(url))
        try:
            raw_html = requests.get(url).text
        except requests.RequestException as exc:
            logging.warning(repr(exc))
            continue

        rows = parse_page(raw_html, item_type)

        for index, row in enumerate(rows):
            if row['recorded_at'] < oldest_date:
                rows = rows[:index]
                stop = True
                break

        records.extend(rows)
        logging.info('crawling page {} success'.format(page))
        page += 1

        time.sleep(SLEEP_TIME)

    return records

@transaction.atomic
def store_date(rows):
    counter = 0
    for row in rows:
        item_type = \
            ItemType.objects.get_or_create(type_name=row['item_type'], defaults={'created_at': CREATE_DATETIME})[0]
        item = Item.objects.get_or_create(item_name=row['item_name'], item_unit=row['unit'], item_type=item_type,
                                          defaults={'created_at': CREATE_DATETIME})[0]

        row.pop('item', None)
        row.pop('item_type', None)
        recorded_at = row.pop('recorded_at')
        record, result = Record.objects.get_or_create(item=item, recorded_at=recorded_at, defaults=row)
        counter += 1 if result else 0

    logging.info('add {} records successfully'.format(counter))

def parse_page(raw_html, item_type):
    """
    parse raw html
    :param raw_html:
    :param item_type:
    :return: list<dict>
    """

    def clean_date(row_dict):
        del row_dict['useless']
        row_dict['item'] = row_dict['item_name']
        row_dict['lowest_price'] = int(float(row_dict['lowest_price']) * 100)
        row_dict['avg_price'] = int(float(row_dict['avg_price']) * 100)
        row_dict['highest_price'] = int(float(row_dict['highest_price']) * 100)
        row_dict['item_type'] = INDEX_TYPE_MAPPER.get(item_type)
        try:
            row_dict['recorded_at'] = datetime.datetime.strptime(row_dict['recorded_at'], '%Y-%m-%d').date()
        except ValueError:
            raise Exception('Date format error')

        return row_dict

    soup = bs(raw_html)

    table = soup.find('table', {'class': 'hq_table'})
    trs = table.findAll('tr')
    rows_td = [i.findAll('td') for i in trs][1:]  # 去掉表头

    rows = []
    for row in rows_td:
        labels = ['item_name', 'lowest_price', 'avg_price', 'highest_price', 'useless', 'unit', 'recorded_at']
        row = [td.get_text() for td in row][:-1]  # 去掉最后一个无用的
        row = dict(zip(labels, row))
        row = clean_date(row)
        rows.append(row)

    return rows

def main(oldest_date=None):
    for i in INDEX_TYPE_MAPPER:
        logging.info('crawling {}'.format(INDEX_TYPE_MAPPER[i]))
        records = veg_spider(i, oldest_date)
        store_date(records)

if __name__ == "__main__":
    if len(sys.argv) > 1:
        main(sys.argv[1])
    else:
        main()


from django.shortcuts import render, redirect
from user.models import User
from . import models
from . import forms

def recommend_school(request):
    if not request.session.get('is_login', None):
        # 没登录去登录
        return redirect("/login/")
    title = '推荐学校'
    if request.method == 'POST':
        request.session['school_name'] = request.POST.get('school_name')
        request.session['province'] = request.POST.get('province')
        # request.session['student_type'] = request.POST.get('student_type')
        request.session['epoch'] = request.POST.get('epoch')
    user = User.objects.get(username=request.session['username'])
    score = user.score - 10
    for i in range(30, 600, 10):
        schools = models.School_info.objects.filter(
            school_name__contains=request.session['school_name'],
            student_type__contains=request.session['student_type'],
            epoch__contains=request.session['epoch'],
            school_province__contains=request.session['province'],
            lowest_score__range=(score - i, score + i), student_type=user.subject)
        if len(schools) > 12:
            break
    schools = sorted(schools)[len(schools)//2-5: len(schools)//2+5]
    school_form = forms.school_form(initial={
        'school_name': request.session['school_name'], 'province': request.session['province'],
        'student_type': request.session['student_type'], 'epoch': request.session['epoch']
    })
    school_form.student_type = None
    return render(request, 'recommend_school.html', locals())


import multiprocessing as mp
import numpy as np
from ryserper import *
if __name__ == '__main__':

    jobs=[]
    #permanent=0
    permanent2=0
    #empty=[]
    pers=[]
    #qset=[[],[],[],[],[],[],[],[]]
    #for i in range(8):
        #qset[i]=mp.Queue()
    q2=mp.Queue()
    n=input('Size of Matrix: ')
    n=int(n)
    a=np.random.random_integers(0,1,size=(n,n))
    a=[[1,1,1,1,1],[1,1,1,1,1],[1,1,1,1,1],[1,1,1,1,1],[1,1,1,1,1]]
    #a=bigmat[:16][:16]
    a=np.array(a)
    #b=input('Place Matrix Here: ')
    #for i in range(n):
    #    b[i]=np.array(b[i])
    #b=np.array(b)
    #n=len(a)

   # for i in range(n):
    #    for j in range(n):
     #       print(a[i][j])
    #for i in range(n):
     #   for j in range(n):
      #      print(b[i][j])
    #ryserpers(a,n)
    start_time = time.time()
   # for i in range(8):
    #    empty.append(0)
    #parts=mp.Array('l',np.array(empty,dtype='int64'))
    for init in range(1,9):
        p=mp.Process(target=ryserperp,args=(a,n,init,q2,))
        jobs.append(p)
        p.start()

        #p.join()
    for m in range(8):
        jobs[m].join()
    for m in range(8):
        pers.append(q2.get())
    #p.join()
    #for k in parts:
     #   permanent=permanent+k
    for k in pers:
        permanent2=permanent2+k
    #print(parts[:])
   # print('Parts ',permanent)
   # print(q2)
    print('Permanent: ', permanent2)
    #print(pers[:])
    print (time.time() - start_time, "seconds")


from markdown.extensions import Extension
from markdown.preprocessors import Preprocessor
from markdown.treeprocessors import Treeprocessor
from markdown.postprocessors import Postprocessor
from markdown.inlinepatterns import Pattern
from markdown.util import etree

from pybtex.database.input import bibtex
from pybtex.style.template import FieldIsMissing

from collections import OrderedDict
import re

from .styles import APAStyle

BRACKET_RE = re.compile(r'\[([^\[]+)\]')
CITE_RE    = re.compile(r'@(\w+)')
DEF_RE     = re.compile(r'\A {0,3}\[@(\w+)\]:\s*(.*)')
INDENT_RE  = re.compile(r'\A\t| {4}(.*)')

CITATION_RE = r'\[([^@^\[]*)(@[a-zA-Z0-9;@\s]+)\]'
INNER_CITATION_RE = re.compile(r'@(\w+)')

class Bibliography(object):
    """ Keep track of document references and citations for exporting """

    def __init__(self, extension, bibtex_file, order):
        self.extension = extension
        self.order = order

        self.citations = OrderedDict()
        self.references = dict()
        self.style = APAStyle()

        if bibtex_file:
            try:
                parser = bibtex.Parser()
                self.bibsource = parser.parse_file(bibtex_file).entries
            except:
                print("Error loading bibtex file")
                self.bibsource = dict()
        else:
            self.bibsource = dict()

    def addCitation(self, citekey):
        self.citations[citekey] = self.citations.get(citekey, 0) + 1

    def setReference(self, citekey, reference):
        self.references[citekey] = reference

    def citationID(self, citekey):
        return "cite-" + citekey

    def referenceID(self, citekey):
        return "ref-" + citekey

    def formatAuthor(self, author):
        out = "%s %s."%(author.last()[0], author.first()[0][0])
        if author.middle():
            out += "%s."%(author.middle()[0][0])
        return out

    def formatReference(self, key, entry):
        try:
            return self.style.format_entry(key, entry, self.bibsource).text.render_as('html')
        except FieldIsMissing as error:
            return self.formatError(key, error)

    def formatError(self, key, error):
        return '%s: %s' % (key, error)

    def makeBibliography(self, root):
        if self.order == 'alphabetical':
            raise(NotImplementedError)

        div = etree.Element("div")
        div.set("class", "references")

        if not self.citations:
            return div

        for id in sorted(self.citations):

            ref_txt = etree.SubElement(div, "div")
            ref_txt.set("id", self.referenceID(id))
            ref_txt.set("class", "bibentry")
            if id in self.references:
                self.extension.parser.parseChunk(ref_txt, self.references[id])
            elif id in self.bibsource:
                par = etree.SubElement(ref_txt, "p")
                par.text = self.formatReference(id, self.bibsource[id])
            else:
                par = etree.SubElement(ref_txt, "p")
                par.text = self.formatError(id, 'Missing Citation')

        return div

class CitationsPreprocessor(Preprocessor):
    """ Gather reference definitions and citation keys """

    def __init__(self, bibliography):
        self.bib = bibliography

    def subsequentIndents(self, lines, i):
        """ Concatenate consecutive indented lines """
        linesOut = []
        while i < len(lines):
            m = INDENT_RE.match(lines[i])
            if m:
                linesOut.append(m.group(1))
                i += 1
            else:
                break
        return " ".join(linesOut), i

    def run(self, lines):
        linesOut = []
        i = 0

        while i < len(lines):
            # Check to see if the line starts a reference definition
            m = DEF_RE.match(lines[i])
            if m:
                key = m.group(1)
                reference = m.group(2)
                indents, i = self.subsequentIndents(lines, i+1)
                reference += ' ' + indents

                self.bib.setReference(key, reference)
                continue

            # Look for all @citekey patterns inside hard brackets
            for bracket in BRACKET_RE.findall(lines[i]):
                for c in CITE_RE.findall(bracket):
                    self.bib.addCitation(c)
            linesOut.append(lines[i])
            i += 1

        return linesOut

class CitationsPattern(Pattern):
    """ Handles converting citations keys into links """

    def __init__(self, pattern, bibliography):
        super(CitationsPattern, self).__init__(pattern)
        self.bib = bibliography

    def handleMatch(self, m):

        intro = m.group(2)
        citations = m.group(3)

        if intro:
            if len(intro) == 1:
                intro = ''
            template_et_al = '%s et al. (%s)'
            template = '%s (%s)'
            prefix = ''
            suffix = ''
        else:
            template_et_al = '%s et al., %s'
            template = '%s, %s'
            prefix = '('
            suffix = ')'

        container = etree.Element('span')
        container.text = intro
        citations = [m.group(1) for m in INNER_CITATION_RE.finditer(citations)]

        for i, citation in enumerate(citations):

            if citation in self.bib.citations:

                a = etree.SubElement(container, "a")
                a.set('id', self.bib.citationID(citation))
                a.set('href', '#' + self.bib.referenceID(citation))
                a.set('class', 'citation')

                if citation in self.bib.bibsource:

                    ref = self.bib.bibsource[citation]
                    authors = ref.persons['author']
                    year = ref.fields.get('year', '?')
                    if len(authors) > 1:
                        a.text = prefix + template_et_al % (authors[0].last()[0], year)
                    elif authors:
                        a.text = prefix + template % (authors[0].last()[0], year)
                    else:
                        a.text = prefix + citation
                else:

                    a.text = prefix + citation

                if i < len(citations)-1:
                    a.tail = '; '
                    prefix = ''
                else:
                    a.text += suffix

        return container

class CitationsTreeprocessor(Treeprocessor):
    """ Add a bibliography/reference section to the end of the document """

    def __init__(self, bibliography):
        self.bib = bibliography

    def run(self, root):
        citations = self.bib.makeBibliography(root)
        root.append(citations)

class CitationsExtension(Extension):

    def __init__(self, *args, **kwargs):

        self.config = {
            "bibtex_file": ["",
                            "Bibtex file path"],
            'order': [
                "unsorted",
                "Order of the references (unsorted, alphabetical)"]
        }
        super(CitationsExtension, self).__init__(*args, **kwargs)
        self.bib = Bibliography(
            self,
            self.getConfig('bibtex_file'),
            self.getConfig('order'),
        )

    def extendMarkdown(self, md, md_globals):
        md.registerExtension(self)
        self.parser = md.parser
        self.md = md

        md.preprocessors.add("mdx_bib",  CitationsPreprocessor(self.bib), "<reference")
        md.inlinePatterns.add("mdx_bib", CitationsPattern(CITATION_RE, self.bib), "<reference")
        md.treeprocessors.add("mdx_bib", CitationsTreeprocessor(self.bib), "_begin")

def makeExtension(*args, **kwargs):
    return CitationsExtension(*args, **kwargs)


from django.db import models

class TimestampFields(models.Model):

    created_at = models.DateTimeField(
        auto_now_add=True
    )
    updated_at = models.DateTimeField(
        auto_now=True
    )

    class Meta:
        abstract = True

class Project(TimestampFields):
    name = models.TextField()
    latitude = models.FloatField()
    longitude = models.FloatField()

class Measurement(TimestampFields):
    value = models.FloatField()
    project = models.ForeignKey(Project, on_delete=models.CASCADE)
    image = models.ImageField( upload_to='image', blank=True)


# iaalib/logic.py
# Part of "IAA IoT Alarm and Automation"
#
# Gianluigi Cosari - gianluigi@cosari.it
# logic Ver 1.0 July 2017
# Licensed under MIT

from transitions import Machine

#Define door status values (MQTT Wi-Fi module)
DOOR_CLOSED = 0
DOOR_OPEN = 1

#Define I/O output module values
IO_OFF = 1
IO_ON = 0

#Define I/O output relays duty
IO_SIREN = 9            # connected to siren (energized -> siren playing)
IO_SYSTEM_ARMED = 10    # notice for sistem armed (energized -> system armed)
IO_PEDESTRIAN_GATE = 11 # operated by RFID reader (energized for 1 second -> gate opens)
IO_CAR_GATE = 12        # operated by RFID reader (energized for 1 second -> gate opens)
IO_HOME_DOOR = 13       # operated by RFID reader (energized for 1 second -> door opens)
IO_SECURITY_LIGHTS = 14 # exterior perimeter lights (energized -> lights turn on)
IO_AUX1 = 15            # free
IO_AUX2 = 16            # free

# Finite state machine model implementing the IAA logic
class IAAmodel(object):

	#ricordarsi di gestire il tamper e la manutenzione

	states = ['idle', 'watching', 'armed', 'alert']

	transitions = [
		{ 'trigger': 'node_signal', 'source': 'idle', 'dest': 'idle', 'prepare': 'set_door_state', 'conditions': ['door_changed_state'], 'after': 'send_notification' },
		{ 'trigger': 'node_signal', 'source': 'watching', 'dest': 'watching', 'prepare': 'set_door_state', 'conditions': ['door_opened'], 'after': 'send_notification' },
		{ 'trigger': 'node_signal', 'source': 'armed', 'dest': 'alert', 'prepare': 'set_door_state', 'conditions': ['door_opened'], 'after': 'send_notification' },
		{ 'trigger': 'node_signal', 'source': 'alert', 'dest': 'alert', 'prepare': 'set_door_state', 'conditions': ['door_changed_state'], 'after': 'send_notification' },
		{ 'trigger': 'arm', 'source': ['idle', 'watching'], 'dest': 'armed', },
		{ 'trigger': 'disarm', 'source': ['watching', 'armed', 'alert'], 'dest': 'idle' },
		{ 'trigger': 'watch', 'source': 'idle', 'dest': 'watching', 'after': 'send_notification' }
	]

	def __init__(self, logger, messenger, i2c_q):

		#Initialize shared parameters
		self.logger = logger
		self.messenger = messenger
		self.i2c_q = i2c_q

		#Initialize node parameters
		self.node_id = None
		self.node_name = None
		self.door_state = None
		self.door_state_changed = False
		self.tamper_status = None

		#Initialize the state machine
		self.machine = Machine(model = self, states = IAAmodel.states, transitions = IAAmodel.transitions, initial='idle')

	#This method receives node data from main queue processor
	def set_door_state(self, node_data = None):
		self.node_id, self.node_name, self.door_state, self.door_state_changed, self.tamper_status = node_data
		self.logger.debug('FSM: node "%s" state set' % self.node_name)

	def door_changed_state(self, *args): #True when door status changed from closed to open OR from open to closed
		return self.door_state_changed

	def door_opened(self, *args): #True when door status changed from closed to open
		return self.door_state_changed and (self.door_state == DOOR_OPEN)

	def send_notification(self, *args):
		door_status_desc = 'stato non disponibile'
		if self.door_state == DOOR_OPEN: door_status_desc = 'aperta'
		if self.door_state == DOOR_CLOSED: door_status_desc = 'chiusa'
		self.logger.debug('FSM: sending door "%s" status to Telegram : ' % door_status_desc)
		self.messenger.put(self.node_name + ' ' + door_status_desc)

	def on_enter_idle(self, *args):
		self.logger.info('FSM: System entered status IDLE')

		#de-energize system armed notice relay
		item = (IO_SYSTEM_ARMED, IO_OFF)
		self.logger.debug("FSM: item {}".format(item))
		self.i2c_q.put(item)

		#de-energize siren relay
		item = (IO_SIREN, IO_OFF)
		self.logger.debug("FSM: item {}".format(item))
		self.i2c_q.put(item)

		self.messenger.put('Sistema DISARMATO')

	def on_enter_armed(self, *args):
		self.logger.info('FSM: System entered status ARMED')

		#energize system armed notice relay
		item = (IO_SYSTEM_ARMED, IO_ON)
		self.logger.debug("FSM: item {}".format(item))
		self.i2c_q.put(item)

		self.messenger.put('Sistema ARMATO')

	def on_enter_alert(self, *args):
		self.logger.info('FSM: System entered status ALERT')

		#energize siren relay
		item = (IO_SIREN, IO_ON)
		self.logger.debug("FSM: item {}".format(item))
		self.i2c_q.put(item)

		self.messenger.put('Sistema IN ALLARME!')