from __future__ import unicode_literals
from datetime import datetime, timedelta
import os

import pytz
from channels import Group
from django.contrib.gis.measure import D
from django.contrib.gis.db.models.functions import Distance

from django.core.files.base import ContentFile
from django.conf import settings
from django.contrib.gis.db import models
from django.urls import reverse
from django_extensions.db.fields import ShortUUIDField

from auction_rooms.common.models import DeletableTimeStampedModel
from auction_rooms.experiences.models import Experience
from auction_rooms.users.models import User
from auction_rooms.currencies.models import Currency

class AuctionQuerySet(models.QuerySet):
    def live(self):
        """
        Returns auctions that have not yet finished
        """
        return self.filter(
            deleted=False,
            end_date__gt=datetime.utcnow(),
            status=Auction.STATUS_LIVE
        )

    def finished(self):
        """
        Returns auctions that have finished
        """
        return self.filter(
            deleted=False,
            end_date__lte=datetime.utcnow()
        )

    def sold(self):
        return self.filter(
            deleted=False,
            status=Auction.STATUS_FINISHED_SOLD
        )

class AuctionManager(models.Manager):
    def get_queryset(self):
        return AuctionQuerySet(self.model, using=self._db)

    def create_auction(self, experience, check_in, check_out,
                       starting_price, reserve_price, end_date):
        """
        Create an auction from an experience
        """
        auction = self.create(
            experience=experience,
            title=experience.title,
            description=experience.description,
            location=experience.location,
            coords=experience.coords,
            terms=experience.terms,
            pax_adults=experience.pax_adults,
            pax_children=experience.pax_children,
            currency=experience.currency,
            check_in=check_in,
            check_out=check_out,
            starting_price=starting_price,
            reserve_price=reserve_price,
            end_date=end_date,
            url=experience.url,
        )

        # Copy the experience images over
        for experience_image in auction.experience.images.all():
            image_copy = ContentFile(experience_image.image.read())
            new_path = os.path.join(
                settings.MEDIA_ROOT,
                AuctionImage.image.field.upload_to,  # pylint: disable=no-member
                os.path.basename(experience_image.image.name)
            )
            auction_image = AuctionImage(auction=auction)
            auction_image.image.save(new_path, image_copy, True)
            auction_image.image.name = os.path.join(
                AuctionImage.image.field.upload_to,
                os.path.basename(experience_image.image.name)
            )
            auction_image.save()

        # Copy the inclusions over
        for experience_inclusion in auction.experience.inclusions.all():
            AuctionInclusion.objects.create(
                auction=auction,
                name=experience_inclusion.name
            )

        # Copy the exclusions over
        for experience_exclusion in auction.experience.exclusions.all():
            AuctionExclusion.objects.create(
                auction=auction,
                name=experience_exclusion.name
            )

        return auction

    def live(self):
        """
        Returns auctions that have not yet finished
        """
        return self.get_queryset().live()

    def finished(self):
        """
        Returns auctions that have finished
        """
        return self.get_queryset().finished()

    def sold(self):
        """
        Returns auctions that have finished
        """
        return self.get_queryset().sold()

class Auction(DeletableTimeStampedModel):
    STATUS_LIVE = 1
    STATUS_FINISHED_SOLD = 2
    STATUS_FINISHED_UNSOLD = 3
    _STATUS_CHOICES = (
        (STATUS_LIVE, 'Live'),
        (STATUS_FINISHED_SOLD, 'Finished Sold'),
        (STATUS_FINISHED_UNSOLD, 'Finished Unsold'),
    )
    status = models.IntegerField(
        choices=_STATUS_CHOICES,
        default=STATUS_LIVE
    )
    experience = models.ForeignKey(
        Experience,
        related_name='auctions',
        help_text='The experience this auction was created from',
        on_delete=models.DO_NOTHING
    )
    title = models.CharField(
        max_length=255,
        help_text='Title of the experience being auctioned'
    )
    description = models.TextField(
        help_text='Description of the experience being auctioned'
    )
    location = models.CharField(
        max_length=255,
        help_text='Location name of the experience'
    )
    coords = models.PointField(
        help_text='Location coordinates of the experience'
    )
    terms = models.TextField(
        null=True,
        blank=True,
        help_text='Terms and conditions for the auction/experience'
    )
    pax_adults = models.PositiveSmallIntegerField(
        default=2,
        help_text='Number of adults accepted as part of the experience'
    )
    pax_children = models.PositiveSmallIntegerField(
        default=0,
        help_text='Number of children accepted as part of the experience'
    )
    currency = models.ForeignKey(
        Currency,
        default=settings.DEFAULT_CURRENCY_ID,
        help_text='The date and time the experience starts',
        on_delete=models.DO_NOTHING
    )
    url = models.URLField(
        null=True,
        blank=True,
        help_text='View the experience on the providers website'
    )
    check_in = models.DateTimeField(
        help_text='The date and time the experience starts'
    )
    check_out = models.DateTimeField(
        help_text='The date and time the experience ends'
    )
    starting_price = models.DecimalField(
        max_digits=10,
        decimal_places=2,
        help_text='The initial price for the auction when it goes live'
    )
    reserve_price = models.DecimalField(
        max_digits=10,
        decimal_places=2,
        help_text='The minimum price that will be accpeted to win this auction'
    )
    end_date = models.DateTimeField(
        help_text='The date and time the auction finishes'
    )
    view_count = models.PositiveIntegerField(
        default=0,
        help_text='The number of times auction details have been viewed'
    )
    search_appearance_count = models.PositiveIntegerField(
        default=0,
        help_text='The number of times this auction has '
                  'appeared in search results or on the homepage'
    )
    featured = models.BooleanField(
        default=False,
        help_text='Set to true to show this auction in '
                  'the featured section on the homepage'
    )
    uuid = ShortUUIDField()

    objects = AuctionManager()

    def __unicode__(self):
        return '{}, {}, ending {}'.format(
            self.title,
            self.formatted_current_price(),
            self.end_date
        )

    def get_absolute_url(self):
        return self.get_guest_absolute_url()

    def get_provider_absolute_url(self):
        return reverse('auctions:provider-auction', args=(self.id,))

    def get_guest_absolute_url(self):
        return reverse('auctions:public-auction', args=(self.id,))

    def get_guest_confirmation_url(self):
        return '{}#confirm-{}'.format(
            reverse('auctions:won-auctions'),
            self.id
        )

    def is_live(self):
        """
        Return whether the auction is still biddable
        """
        return self.end_date > datetime.utcnow().replace(tzinfo=pytz.utc)

    def is_finished(self):
        """
        Return whether the auction is still biddable
        """
        return self.end_date <= datetime.utcnow().replace(tzinfo=pytz.utc)

    def was_won(self):
        return self.is_finished() and self.current_price() > self.reserve_price

    def highest_bid(self):
        if self.bids.count() > 0:
            return self.bids.order_by('-price').first()
        return None

    def current_price(self):
        bid = self.highest_bid()
        if bid is not None:
            return bid.price
        return self.starting_price

    def formatted_current_price(self):
        return '{}{}'.format(
            self.currency.symbol,
            self.current_price()
        )

    def formatted_reserve_price(self):
        return '{}{}'.format(
            self.currency.symbol,
            self.reserve_price
        )

    def formatted_starting_price(self):
        return '{}{}'.format(
            self.currency.symbol,
            self.starting_price
        )

    def get_default_image(self):
        if self.images.filter(default=True).exists():
            return self.images.filter(default=True).first()
        return self.images.first()

    def total_pax(self):
        return self.pax_adults + self.pax_children

    @property
    def provider_websocket_group(self):
        """
        Return the channel name that a provider should subscribe to
        when viewing a live auction.
        :return:
        """
        return Group('provider-auction-{}'.format(self.id))

    def send_provider_message(self, message):
        self.provider_websocket_group.send(message)

    @property
    def public_websocket_group(self):
        """
        Return the channel name that a provider should subscribe to
        when viewing a live public auction.
        :return:
        """
        return Group('public-auction-{}'.format(self.id))

    def send_public_message(self, message):
        self.public_websocket_group.send(message)

    def mark_complete(self):
        from auction_rooms.auctions.signals import auction_completed

        if self.bids.count() == 0 or self.current_price() < self.reserve_price:
            # Auction did not sell
            self.status = self.STATUS_FINISHED_UNSOLD
        else:
            # Auction sold
            self.status = self.STATUS_FINISHED_SOLD
        self.save()
        auction_completed.send(sender=self.__class__, auction=self)

    def is_ending(self):
        now = datetime.utcnow().replace(tzinfo=pytz.utc)
        return self.is_live() and self.end_date < now + timedelta(hours=24)

    def pretty_checkin_date(self):
        return self.check_in.strftime('%a, %-d %b %Y ')

    def pretty_checkin(self):
        return self.check_in.strftime('%H:%M %a, %-d %b %Y ')

    def pretty_checkout_date(self):
        return self.check_out.strftime('%a, %-d %b %Y ')

    def pretty_checkout(self, include_time=True):
        return self.check_out.strftime('%H:%M %a, %-d %b %Y ')

    def pretty_duration(self):
        days = (self.check_out.date() - self.check_in.date()).days
        return '{} Night{}'.format(days, 's' if days > 1 else '')

    def is_selling(self):
        """
        Return true if the auction has met the reserve price
        :return:
        """
        return self.current_price() >= self.reserve_price

    def related_auctions(self):
        """
        Returns any other live auctions for the same experience
        :return:
        """
        return Auction.objects.live().filter(
            experience=self.experience
        ).exclude(
            pk=self.id
        ).order_by('end_date')

    def local_auctions(self):
        """
        Returns any any local auctions in a 50 mile radius
        :return:
        """
        return Auction.objects.live().filter(
            coords__distance_lte=(self.coords, D(mi=50))
        ).exclude(
            experience=self.experience
        ).annotate(
            distance=Distance('coords', self.coords)
        ).order_by('distance', 'end_date')

class AuctionImage(models.Model):
    auction = models.ForeignKey(
        Auction,
        related_name='images',
        on_delete=models.DO_NOTHING
    )
    image = models.ImageField(upload_to='auctions/')
    default = models.BooleanField(default=False)

    def __unicode__(self):
        return '{} Image'.format(self.auction.title)

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

class AuctionInclusion(models.Model):
    auction = models.ForeignKey(
        Auction,
        related_name='inclusions',
        on_delete=models.DO_NOTHING
    )
    name = models.CharField(max_length=255)

    def __unicode__(self):
        return 'Includes {}'.format(self.name)

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

class AuctionExclusion(models.Model):
    auction = models.ForeignKey(
        Auction,
        related_name='exclusions',
        on_delete=models.DO_NOTHING
    )
    name = models.CharField(max_length=255)

    def __unicode__(self):
        return 'Excludes {}'.format(self.name)

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

class Bid(DeletableTimeStampedModel):
    auction = models.ForeignKey(
        Auction,
        related_name='bids',
        on_delete=models.DO_NOTHING
    )
    user = models.ForeignKey(
        User,
        related_name='bids',
        on_delete=models.DO_NOTHING
    )
    price = models.DecimalField(max_digits=10, decimal_places=2)

    class Meta:
        unique_together = ('auction', 'price')
        ordering = ('-price',)

    def __unicode__(self):
        return '{} bid on {} from {}'.format(
            self.formatted_price(),
            self.auction.title,
            self.user.get_full_name()
        )

    def formatted_price(self):
        return '{}{}'.format(
            self.auction.currency.symbol,
            self.price
        )

class Favourite(DeletableTimeStampedModel):
    auction = models.ForeignKey(
        Auction,
        related_name='favourites',
        on_delete=models.DO_NOTHING
    )
    user = models.ForeignKey(
        User,
        related_name='favourites',
        on_delete=models.DO_NOTHING
    )
    reminder_sent = models.BooleanField(default=False)
    new_listing_sent = models.BooleanField(default=False)

    class Meta:
        unique_together = ('auction', 'user')


#     [D]
# [N] [C]
# [Z] [M] [P]
#  1   2   3

# move 1 from 2 to 1
# move 3 from 1 to 3
# move 2 from 2 to 1
# move 1 from 1 to 2

mapping = {1:1, 5:2, 9:3, 13:4, 17:5, 21:6, 25:7, 29:8, 33:9}

import math
from collections import defaultdict
def get_starting_state(stack_string):
    lines = stack_string.split('\n')
    lines.reverse()
    # find the number of stacks by dividing by 4 and rounding up
    stack_count = math.ceil(len(lines[0])/4)
    stacks = defaultdict(list)
    for line in lines:
        # bucket size is 4
        for item in line:
            if item != '.' and item != '':
                try:
                    int(item)
                except ValueError:
                    stacks[mapping[line.index(item)]].append(item)
                    templist = list(line)
                    templist[line.index(item)] = '.'
                    line = ''.join(templist)

    return stacks

def parse_instruction(instruction):
    try:
        number_to_move = int(instruction[5:7])
        start_stack = int(instruction[13])
        dest_stack = int(instruction[18])
    except ValueError:
        number_to_move = int(instruction[5])
        start_stack = int(instruction[12])
        dest_stack = int(instruction[17])
    return number_to_move, start_stack, dest_stack

def run_crane(number_to_move, start_stack, dest_stack, stacks):
    crane = []
    for crates in range(number_to_move):
        crane.append(stacks[start_stack].pop())
    for crates in range(number_to_move):
        stacks[dest_stack].append(crane.pop())

with open('5.input', 'r') as input:
    data = input.read()

stack_string = data.split('move')[0].replace(" ", ".").replace("[", ".").replace("]", ".")
lines = data.split('\n')
instructions = []
for line in lines:
    if 'move' in line:
        instructions.append(line)

stacks = get_starting_state(stack_string)
for instruction in instructions:
    number_to_move, start_stack, dest_stack = parse_instruction(instruction)
    run_crane(number_to_move, start_stack, dest_stack, stacks)

print(stacks)


from __future__ import print_function
import ROOT
from array import array
from hist_utils import *

do_sg = False
do_sg = True
import tdrstyle
if do_sg:
    #import CMS_lumi_white as CMS_lumi # for PAS
    import CMS_lumi as CMS_lumi # for PRL
else:
    import CMS_lumi as CMS_lumi

#tdrstyle.setTDRStyle()
ROOT.gStyle.SetPadTickX(1)
ROOT.gStyle.SetPadTickY(1)
#change the CMS_lumi variables (see CMS_lumi.py)
CMS_lumi.lumi_7TeV = "4.8 fb^{-1}"
CMS_lumi.lumi_8TeV = "18.3 fb^{-1}"
CMS_lumi.writeExtraText = 1
CMS_lumi.cmsTextOffset = 0.
#CMS_lumi.extraText = "Preliminary"
#CMS_lumi.lumi_sqrtS = "41.5 fb^{-1} (13 TeV)" # used with iPeriod = 0, e.g. for simulation-only plots (default is an empty string)
CMS_lumi.lumi_sqrtS = "136 fb^{-1} (13 TeV)" # used with iPeriod = 0, e.g. for simulation-only plots (default is an empty string)
if do_sg:
    iPos = 11 # CMS in frame
else:
    iPos = 0 # CMS above frame
iPos = 0 # for PRL
if( iPos==0 ): CMS_lumi.relPosX = 0.19
iPeriod = 0

def rebin2d(kratio, kratio_rebin):

    for ix in range(0, h[kratio].GetNbinsX()+2):
        ma_x = h[kratio].GetXaxis().GetBinCenter(ix)
        #ma_x = h[kratio].GetXaxis().GetBinLowEdge(ix)
        ix_rebin = h[kratio].GetXaxis().FindBin(ma_x)
        for iy in range(0, h[kratio].GetNbinsY()+2):
            ma_y = h[kratio].GetYaxis().GetBinCenter(iy)
            #ma_y = h[kratio].GetYaxis().GetBinLowEdge(iy)
            iy_rebin = h[kratio].GetYaxis().FindBin(ma_y)
            binc = h[kratio].GetBinContent(ix, iy)

            ixy_rebin = h[kratio].GetBin(ix_rebin, iy_rebin)
            h[kratio].AddBinContent(ixy_rebin, binc)
            #if ix == 2: print(iy, ma_y, iy_rebin, binc)

    #return hrebin.Clone()
    #return hrebin

def draw_hist_2dma(k_, h, c, sample, blind, ymax_=None, ymin_=None, do_trunc=True, label=None):

    hc = {}
    wd, ht = int(800*1), int(680*1)
    txtFont = 42
    blindTextSize   = 0.75

    k = k_
    c[k] = ROOT.TCanvas("c%s"%k,"c%s"%k,wd,ht)
    h[k] = set_hist(h[k], "m_{ #Gamma,1} [GeV]", "m_{ #Gamma,2} [GeV]", "")
    ROOT.gPad.SetRightMargin(0.23)
    ROOT.gPad.SetLeftMargin(0.17)
    #ROOT.gPad.SetTopMargin(0.05) # no cms
    ROOT.gPad.SetTopMargin(0.085) # with cms
    ROOT.gPad.SetBottomMargin(0.17)
    ROOT.gStyle.SetPalette(55)#53
    #ROOT.TGaxis.fgMaxDigits = 1

    h[k].GetXaxis().SetTitleOffset(1.1)
    h[k].GetXaxis().SetLabelOffset(0.01)
    h[k].GetXaxis().SetTitleSize(0.07)
    h[k].GetXaxis().SetLabelSize(0.06)
    h[k].GetXaxis().SetLabelFont(txtFont)
    h[k].GetXaxis().SetTitleFont(txtFont)

    h[k].GetYaxis().SetTitleSize(0.07)
    h[k].GetYaxis().SetLabelSize(0.06)
    h[k].GetYaxis().SetTitleOffset(1.1)
    h[k].GetYaxis().SetLabelOffset(0.01)
    h[k].GetYaxis().SetLabelFont(txtFont)
    h[k].GetYaxis().SetTitleFont(txtFont)

    #h[k].GetZaxis().SetTitle("Events")
    #h[k].GetZaxis().SetTitle("Events / 25 MeV")
    #units = '(%d MeV)^{2}'%dMa
    units = '(%.2f GeV)^{2}'%(dMa/1.e3)
    if label is None:
        h[k].GetZaxis().SetTitle("Events / %s"%units)
    else:
        h[k].GetZaxis().SetTitle("%s / %s"%(label, units))
    h[k].GetZaxis().SetTitleOffset(1.22)
    h[k].GetZaxis().SetLabelOffset(0.01)
    h[k].GetZaxis().SetTitleSize(0.07)
    h[k].GetZaxis().SetTitleFont(txtFont)
    h[k].GetZaxis().SetLabelSize(0.06)
    h[k].GetZaxis().SetLabelFont(txtFont)
    h[k].GetZaxis().SetNdivisions(506)
    h[k].GetZaxis().SetMaxDigits(3) #doesnt seem to work on zaxis -> use newer version of ROOT (lcgdev4.sh)

    h[k].SetContour(100)

    if do_trunc:
        h[k].GetXaxis().SetRangeUser(0., 1.2)
        h[k].GetYaxis().SetRangeUser(0., 1.2)
    h[k].Draw("COL Z")
    #h[k].Draw("COL")

    #ymax_ = ...
    if ymax_ is not None:
        h[k].SetMaximum(ymax_)
    if ymin_ is not None:
        h[k].SetMinimum(ymin_)
    else:
        h[k].SetMinimum(0.)
    c[k].Draw()
    palette = h[k].GetListOfFunctions().FindObject("palette")
    palette.SetX1NDC(0.779)
    palette.SetX2NDC(0.779+0.05)
    palette.SetY2NDC(0.916)
    palette.SetY1NDC(0.17)

    print(sample)
    mass = sample.split('GeV')[0].split('mA')[-1].replace('p','.')
    print(mass)
    blindText = 'm_{#bf{#it{A}}} = %s GeV'%mass
    t_ = ROOT.gPad.GetTopMargin()
    ltx = ROOT.TLatex()
    ltx.SetNDC()
    ltx.SetTextFont(txtFont)#bold:62
    ltx.SetTextAlign(13)
    ltx.SetTextSize(blindTextSize*t_)
    ltx.SetTextColor(17)
    if mass == '1.0':
        ltx.DrawLatex(0.22, 0.27, blindText)
    else:
        ltx.DrawLatex(0.22, 0.868, blindText)

    CMS_lumi.relPosY = 0.8

    CMS_lumi.CMS_lumi(c[k], iPeriod, iPos)

    c[k].Update()
    c[k].Print('Plots/2dma/%s_blind_%s_%s%s_sel-%s.pdf'%(sample, blind, k, '_ext' if not do_trunc else '', sel))

#def plot_2dma(sample, blind):

hf, h = {}, {}
c = {}

keys = ['ma0vma1']

''' old (2017) version
#regions = ['sblo', 'sbhi', 'sr']
#regions = ['sblo2sr', 'sbhi2sr', 'sb2sr', 'sr']
regions = ['sblo2sr', 'sbhi2sr', 'sb2sr']
sample = 'Run2017B-F'
#blind = 'diag_lo_hi'
#blind = 'offdiag_lo_hi'
blind = None
#indir = 'Templates_tmp'
indir = 'Templates/prod_normblind_diaglohi/nom-nom/flo_None'

for r in regions:
    #hf[r] = ROOT.TFile("%s/%s_%s_blind_%s_templates.root"%(indir, sample, r, blind),"READ")
    inpath = '%s/%s/%s_sb2sr+hgg.root'%(indir, campaign, sample)
    hf[r] = ROOT.TFile.Open("%s/%s_%s_blind_%s_templates.root"%(indir, sample, r, blind),"READ")
    for k in keys:
        rk = '%s_%s'%(r, k)
        h[rk] = hf[r].Get(k)
        #draw_hist_2dma(k, h, c, sample, blind, r, do_trunc=False)
        #draw_hist_2dma(k, h, c, sample, blind, r, do_trunc=True)
'''

#'''
run = 'Run2'
r_sb2sr, r_sr = 'sb2sr+hgg', 'sr'
valid_blind = 'diag_lo_hi'
limit_blind = 'offdiag_lo_hi'
indir = 'root://cmseos.fnal.gov//store/user/lpchaa4g/mandrews/%s'%run
sub_campaign = 'bdtgtm0p96_relChgIsolt0p07_etalt1p44' # bdt > -0.96, relChgIso < 0.07 !! optimal
k = keys[0]
dMa = 25
dMa = 50

#'''
if do_sg:
    # Sg model
    sel = 'nom'
    CMS_lumi.extraText = "Simulation" # for PRL
    #CMS_lumi.extraText = "Simulation Preliminary" # for PAS
    ma_pts = ['0p1', '0p4', '1p0']#, '0p5']
    #ma_pts = ['1p0']
    regions = [r_sr]
    blinds = [limit_blind, valid_blind] # to get fully unblinded plots, run mk_sg_temp and combine_sg_temp with both blinding settings!
    #blinds = [limit_blind] # to get fully unblinded plots, run mk_sg_temp and combine_sg_temp with both blinding settings!
    #campaign = 'sg-Era04Dec2020v6/%s/nom-%s/Templates/systNom_nom'%(sub_campaign, sel) # 2016-18 phoid, 2016-18 ss. ss implemented only for shifted syst (as in v4)
    #campaign = 'sg-Era22Jun2021v2/%s/nom-%s/Templates/systNom_nom'%(sub_campaign, sel) # 2016-18 phoid, 2016-18 ss. ss implemented only for shifted syst (as in v4)
    #campaign = 'sg-Era22Jun2021v3/%s/nom-%s/Templates/systNom_nom'%(sub_campaign, sel) # v2 + interpolated mass pts
    campaign = 'sg-Era22Jun2021v6/%s/nom-%s/Templates/systNom_nom'%(sub_campaign, sel) #  bin50MeV
    do_blind = True
    do_blind = False
    for ma in ma_pts:

        sample = 'h4g-mA%sGeV'%ma if run == 'Run2' else 'h4g%s-mA%sGeV'%(run, ma)
        maxzs = []
        for r in regions:
            srk = '%s_%s_%s'%(sample, r, k)
            for b in blinds:

                inpath = "%s/%s/%s_%s_blind_%s_templates.root"%(indir, campaign, sample, r, b)
                print('>> Reading:', inpath)

                srkb = '%s-%s'%(srk, b)
                print('srkb:',srkb)

                hf[srkb] = ROOT.TFile.Open(inpath, "READ")

                h[srkb] = hf[srkb].Get(srkb)
                h[srkb].SetName(srkb)
                if b == limit_blind:
                    h[srk] = h[srkb].Clone()
                    h[srk].SetName(srk)
                else:
                    # to make fully unblinded 2dma, add offdiag + diag blinded plots
                    if not (do_blind and r == r_sr):
                        h[srk].Add(h[srkb])
            maxzs.append(h[srk].GetMaximum())
            print('h[%s], max: %f'%(srk, h[srk].GetMaximum()))

        for r in regions:
            srk = '%s_%s_%s'%(sample, r, k)

            # overwrite empty bins
            for ix in range(0, h[srk].GetNbinsX()+2):
                for iy in range(0, h[srk].GetNbinsY()+2):

                    binc = h[srk].GetBinContent(ix, iy)
                    if binc == 0:
                        h[srk].SetBinContent(ix, iy, 1.)

            draw_hist_2dma(srk, h, c, sample, limit_blind if do_blind and r == r_sr else None, ymax_=np.max(maxzs), do_trunc=True)
    #'''

else:
    # Bkg model
    sample = 'data'
    sel = 'nom'
    sel = 'inv'
    #campaign = 'bkgPtWgts-Era04Dec2020v2/%s/nom-%s/Templates_bkg'%(sub_campaign, sel) # combined full Run2, 2016H+2018 failed lumis, run = 'Run2'
    #campaign = 'bkgPtWgts-Era22Jun2021v1/%s/nom-%s/Templates_bkg'%(sub_campaign, sel) # combined full Run2, 2016H+2018 failed lumis, run = 'Run2'
    #campaign = 'bkgPtWgts-Era22Jun2021v4/%s/nom-%s/Templates_bkg'%(sub_campaign, sel) # combined full Run2, mgg95, hgg template with SFs, fhgg from br(hgg)
    campaign = 'bkgPtWgts-Era22Jun2021v2/%s/nom-%s/Templates_bkg'%(sub_campaign, sel) # bin 50MeV
    regions = [r_sb2sr, r_sr]
    blinds = [valid_blind, limit_blind]
    #regions = [r_sb2sr]
    do_blind = True if sel == 'nom' else False
    if sel == 'inv':
        do_blind = False
    CMS_lumi.extraText = "Preliminary"
    #do_blind = False

    inpath = '%s/%s/%s_sb2sr+hgg.root'%(indir, campaign, sample)
    print('>> Reading file:', inpath)
    hf['nom'] = ROOT.TFile.Open(inpath, "READ")
    maxzs = []
    for r in regions:
        srk = '%s_%s_%s'%(sample, r, k)
        for b in blinds:
            srkb = '%s-%s'%(srk, b)
            print('srkb:',srkb)
            h[srkb] = hf['nom'].Get(srkb)
            h[srkb].SetName(srkb)
            #if b == limit_blind: # for making illustrations only
            if b == valid_blind:
                h[srk] = h[srkb].Clone()
                h[srk].SetName(srk)
            else:
                if not (do_blind and r == r_sr):
                    h[srk].Add(h[srkb])
        maxzs.append(h[srk].GetMaximum())
        print('h[%s], max: %f'%(srk, h[srk].GetMaximum()))

    # Overwrite bkg plot with pol-optimized one from running `get_2dsyst+pol*.py`
    hf['bkgxpol'] = ROOT.TFile.Open('Fits/bkgxpol.root', "READ")
    # data_sb2sr_diag_lo_hi_ma0vma1_rebin
    kbkg = '%s_%s_%s'%(sample, r_sb2sr, k)
    srkb = 'data_sb2sr_%s_%s_rebin'%(valid_blind, k)
    h[kbkg].Reset()
    h[kbkg] = hf['bkgxpol'].Get(srkb)
    #if not do_blind:
    srkb = 'data_sb2sr_%s_%s_rebin'%(limit_blind, k)
    h[kbkg].Add(hf['bkgxpol'].Get(srkb))
    h[kbkg].SetName('data_sb2sr_%s'%k)

    for r in regions:
        srk = '%s_%s_%s'%(sample, r, k)
        draw_hist_2dma(srk, h, c, sample, limit_blind if do_blind and r == r_sr else None, ymax_=np.max(maxzs)*(1. if sel=='nom' else 1.02), do_trunc=True, label=('Obs. events' if r==r_sr else None))

    # Make ratio plot
    kobs = '%s_%s_%s'%(sample, r_sr, k)
    kbkg = '%s_%s_%s'%(sample, r_sb2sr, k)
    kratio = '%so%s'%(r_sb2sr, r_sr)
    h[kratio] = h[kobs].Clone()
    h[kratio].SetName(kratio)
    h[kratio].Divide(h[kbkg])
    #print('h[%s], min,max: %f, %f'%(kratio, h[kratio].GetMinimum(), h[kratio].GetMaximum()))
    #draw_hist_2dma(kratio, h, c, sample, limit_blind if do_blind else None, ymax_=2., ymin_=0., do_trunc=True, label='(Obs/Bkg)')
    draw_hist_2dma(kratio, h, c, sample, limit_blind if do_blind else None, ymax_=1.5, ymin_=0.5, do_trunc=True, label='(Obs/Bkg)')

'''
# rebinned ratios
# need to calculate ratio AFTER rebinning input hists
# otherwise values will be wrong as below
dMa = 25
dMa = 50
#dMa = 100
ma_bins = list(range(0,1200+dMa,dMa))
ma_bins = [-400]+ma_bins
ma_bins = [float(m)/1.e3 for m in ma_bins]
nbins = len(ma_bins)-1
ma_bins = array('d', ma_bins)

kratio_rebin = kratio+'_rebin'
h[kratio_rebin] = ROOT.TH2F(kratio_rebin, kratio_rebin, nbins, ma_bins, nbins, ma_bins)
#rebin2d(kratio, kratio_rebin)#, ma_bins, h[kratio_rebin])

for ix in range(0, h[kratio].GetNbinsX()+2):
    ma_x = h[kratio].GetXaxis().GetBinCenter(ix)
    #ma_x = h[kratio].GetXaxis().GetBinLowEdge(ix)
    ix_rebin = h[kratio_rebin].GetXaxis().FindBin(ma_x)
    for iy in range(0, h[kratio].GetNbinsY()+2):
        ma_y = h[kratio].GetYaxis().GetBinCenter(iy)
        #ma_y = h[kratio].GetYaxis().GetBinLowEdge(iy)
        iy_rebin = h[kratio_rebin].GetYaxis().FindBin(ma_y)
        binc = h[kratio].GetBinContent(ix, iy)

        ixy_rebin = h[kratio_rebin].GetBin(ix_rebin, iy_rebin)
        h[kratio_rebin].AddBinContent(ixy_rebin, binc)

# workaround: for some reason need to re-set bin contents for plotting to work
for ix in range(1, h[kratio_rebin].GetNbinsX()+1):
    for iy in range(1, h[kratio_rebin].GetNbinsY()+1):
        binc = h[kratio_rebin].GetBinContent(ix, iy)
        binerr = h[kratio_rebin].GetBinError(ix, iy)
        h[kratio_rebin].SetBinContent(ix, iy, binc)
        h[kratio_rebin].SetBinError(ix, iy, binerr)

draw_hist_2dma(kratio_rebin, h, c, sample, limit_blind if do_blind else None, ymax_=2., ymin_=0., do_trunc=True, label='(Obs/Bkg)')
'''

'''
# Make pull plot
kpull = 'pull'#%(r_sb2sr, r_sr)
h[kpull] = h[kobs].Clone()
h[kpull].SetName(kpull)
for ix in range(1, h[kpull].GetNbinsX()+1):
    for iy in range(1, h[kpull].GetNbinsY()+1):

        obs = h[kobs].GetBinContent(ix, iy)
        if obs == 0: continue

        bkg = h[kbkg].GetBinContent(ix, iy)
        diff = obs - bkg
        sg_bkg = h[kbkg].GetBinError(ix, iy)
        sg_obs = h[kobs].GetBinError(ix, iy)
        #sg = np.sqrt(sg_bkg*sg_bkg + sg_obs*sg_obs)
        sg = sg_bkg
        pull = diff/sg
        pull = (obs-bkg)/np.sqrt(bkg)

        h[kpull].SetBinContent(ix, iy, pull)

#h[kpull].Divide(h['%s_%s_%s'%(sample, r_sb2sr, k)])
print('h[%s], min,max: %f, %f'%(kpull, h[kpull].GetMinimum(), h[kpull].GetMaximum()))
draw_hist_2dma(kpull, h, c, sample, limit_blind if do_blind else None, ymax_=8., ymin_=-8., do_trunc=True, label='pull')
#draw_hist_2dma(kpull, h, c, sample, limit_blind if do_blind else None, ymax_=1.+2., ymin_=0., do_trunc=True, label='pull')
'''


import numpy as np

# Galactic conversion constants
RA_NGP = np.radians(192.859508333333)
DEC_NGP = np.radians(27.1283361111111)
L_CP = np.radians(122.932)
L_0 = L_CP - np.pi / 2.
RA_0 = RA_NGP + np.pi / 2.
DEC_0 = np.pi / 2. - DEC_NGP

def fk52gal(ra, dec):
    """ Convert from equatorial to galactic coordinates

    :param ra: scalar or array. Right Ascension
    :param dec: scalar or array. Declination

    :rtype: Tuple of L,B coordinates for each input
    """
    ra, dec = np.radians(ra), np.radians(dec)

    sinb = np.sin(dec) * np.cos(DEC_0) - np.cos(dec) * np.sin(ra - RA_0) \
        * np.sin(DEC_0)

    b = np.arcsin(sinb)

    cosl = np.cos(dec) * np.cos(ra - RA_0) / np.cos(b)
    sinl = (np.sin(dec) * np.sin(DEC_0) + np.cos(dec) * np.sin(ra - RA_0) *
            np.cos(DEC_0)) / np.cos(b)

    b = np.degrees(b)

    l = np.arccos(cosl)
    l[np.where(sinl < 0.)] = - l[np.where(sinl < 0.)]

    l = np.degrees(l + L_0)

    l = np.mod(l, 360.)
    b = np.mod(b + 90., 180.) - 90.

    return l, b

def gal2fk5(l, b):
    """ Convert from galactic to equatorial coordinates

    :param l: scalar or array. Galactic longitude
    :param b: scalar or array. Galactic latitude

    :rtype: Tuple of RA, dec coordinates for each input
    """

    l = np.radians(l)
    b = np.radians(b)

    sind = np.sin(b) * np.sin(DEC_NGP) + \
        np.cos(b) * np.cos(DEC_NGP) * np.sin(l - L_0)

    dec = np.arcsin(sind)

    cosa = np.cos(l - L_0) * np.cos(b) / np.cos(dec)
    sina = (np.cos(b) * np.sin(DEC_NGP) * np.sin(l - L_0) -
            np.sin(b) * np.cos(DEC_NGP)) / np.cos(dec)

    dec = np.degrees(dec)

    ra = np.arccos(cosa)
    ra[np.where(sina < 0.)] = -ra[np.where(sina < 0.)]

    ra = np.degrees(ra + RA_0)

    ra = np.mod(ra, 360.)
    dec = np.mod(dec + 90., 180.) - 90.

    return ra, dec


import paramiko
import os
from prox.libs import utils

CURR_DIR = os.getcwd()

ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())

def ssh_connect(host, username, key_filename=None):
    try:
        ssh.connect(host, username=username, key_filename=key_filename)
    except Exception as e:
        print(e)
        raise e
    else:
        return ssh

def sync_file(ftp_client,path_file, path_remote):
    ftp_client.put(path_file, path_remote)


class Humidity():
    def __init__(self, curHum, preHum, down_thresh=15, up_thresh=60, water_level=[0, 5, 20], v_thresh=3, penalty=100):
        self.curHum = curHum
        self.preHum = preHum
        self.up_thresh = up_thresh
        self.down_thresh = down_thresh
        self.action = [0, 1, 2]
        self.water_level = water_level
        self.v_thresh = v_thresh
        self.penalty = penalty

        self.alpha = (self.water_level[2] - self.water_level[1])/(self.v_thresh*(self.action[2]-self.action[1]))
        self.delta = self.preHum - self.curHum
        self.curState = None
        self.nextState = None

        self.maxReward = -2000
        self.tmpReward = 0

    def setCurState(self):
        if self.curHum < self.down_thresh:
            self.curState = -1
        elif self.curHum > self.up_thresh:
            self.curState = 1
        else:
            self.curState = 0

    def setNextState(self, nextHum):
        if nextHum < self.down_thresh:
            self.nextState = -1
        elif nextHum > self.up_thresh:
            self.nextState = 1
        else:
            self.nextState = 0

    def Reward(self, index):
        p = 0
        if self.nextState != int(0):
            p = 100
        r = - self.alpha * self.curState * self.delta * self.action[index] - self.water_level[index] - p
        return r

    def MakeDecision(self):
        self.setCurState()
        index = None
        nextHum = None
        index = None
        for i in self.action:
            nextHum = self.curHum - self.delta + self.water_level[i]
            self.setNextState(nextHum)
            self.tmpReward = self.Reward(i)
            if self.tmpReward > self.maxReward:
                self.maxReward = self.tmpReward
                index = i

        return index


from django.shortcuts import render
from django.db import connection
from django.http import HttpResponseNotFound
from django.http.response import HttpResponseNotAllowed, Http404

from myApp.query import Query

def index(request):
    result = dict()
    try:
        # cursor = connection.cursor()
        # connection.commit()
        # connection.close()
        cursor = connection.cursor()
        sqlQuery = "Select * from students;"
        cursor.execute(sqlQuery)
        row = cursor.fetchall()
        result["students"] = row
        cursor.close()
        # with connection.cursor() as cursor:

    except Exception as e:
        print(e)
    return render(request, "myApp/index.html", result)

def searchPage(request):
    result = dict()
    if request.method == 'GET':
        result["result"] = ""
        return render(request, "myApp/search.html")
    elif request.method == 'POST':
        queryType = int(request.POST['type'])

        if queryType == 1:
            result["result"] = "Result of Query #1"
            result["column"] = ('countryName','averageScore')
            result["datas"] = Query.queryType1()

        elif queryType == 2:
            result["result"] = "Result of Query #2"
            result["column"] = ('cityName','averageScore')
            result["datas"] = Query.queryType2()

        elif queryType == 3:
            result["result"] = "Result of Query #3"
            result["column"] = ('professorName','studentName')
            result["datas"] = Query.queryType3()

        elif queryType == 4:
            result["result"] = "Result of Query #4"
            result["column"] = ('professorName','studentName')
            result["datas"] = Query.queryType4()

        elif queryType == 5:
            result["result"] = "Result of Query #5"
            result["column"] = ('studentName','cityName')
            result["datas"] = Query.queryType5()
        return render(request, "myApp/search.html", result)
    else :
        return HttpResponseNotFound("")

def students(request, message = ""):
    result = dict()
    try:
        with connection.cursor() as cursor:
            sqlQuery = "Select * from students;"
            cursor.execute(sqlQuery)
            row = cursor.fetchall()

            result["type"] = "Students"
            result["column"] = ('studentID','name','score','country')
            result["datas"] = row
            result["result"] = message

    except Exception as e:
        print(e)

    return render(request, "myApp/import.html", result)

def professors(request, message = ""):
    result = dict()
    try:
        with connection.cursor() as cursor:
            sqlQuery = "Select * from professors;"
            cursor.execute(sqlQuery)
            row = cursor.fetchall()

            result["type"] = "Professors"
            result["column"] = ('facultyID','name','age','country')
            result["datas"] = row
            result["result"] = message

    except Exception as e:
        print(e)

    return render(request, "myApp/import.html", result)

def countries(request, message = ""):
    result = dict()
    try:
        with connection.cursor() as cursor:
            sqlQuery = "Select * from countries;"
            cursor.execute(sqlQuery)
            row = cursor.fetchall()

            result["type"] = "Countries"
            result["column"] = ('countryName','population','city')
            result["datas"] = row
            result["result"] = message

    except Exception as e:
        print(e)

    return render(request, "myApp/import.html", result)

def covid(request, message = ""):
    result = dict()
    try:
        with connection.cursor() as cursor:
            sqlQuery = "Select * from covid;"
            cursor.execute(sqlQuery)
            row = cursor.fetchall()

            result["type"] = "Covid"
            result["column"] = ('patientID','city')
            result["datas"] = row
            result["result"] = message

    except Exception as e:
        print(e)

    return render(request, "myApp/import.html", result)

def csvImport(request):
    if request.method != 'POST':
        return HttpResponseNotAllowed("Not Allowed")
    try:
        a = request.FILES['csv'].read()
        b = a.decode('utf-8')

        with open('.\\category\\myApp\\templates\\myApp\\'+request.FILES['csv'].name, "w") as csv:
            csv.write(b)

        datas = ""
        for row in b.splitlines():
            data = "("
            for r in row.split(','):
                data += "'{}',".format(r)
            data = data[:-1] + "),"
            datas += data
        with connection.cursor() as cursor:
            sqlQuery = "Insert INTO {} values {};".format(request.POST['type'], datas[:-1])
            cursor.execute(sqlQuery)
            row = cursor.fetchall()
            connection.commit()
        result = "Success!"
    except Exception as e:
        result = "Error : " + str(e)

    if request.POST['type'] == 'Students':
        return students(request,result)
    elif request.POST['type'] == 'Professors':
        return professors(request,result)
    elif request.POST['type'] == 'Countries':
        return countries(request,result)
    elif request.POST['type'] == 'Covid':
        return covid(request,result)

    return HttpResponseNotFound("")


members = ['Veronica Pittman', 'Heena Hooper', 'Uma Davidson', 'Amit Cook', 'Malik Clifford', 'Griffin Abbott', 'Aiysha Villa',
           'Stacie Kane', 'Arandeep Conway', 'Harrison Cameron', 'Shayna John', 'Gia Odonnell', 'Katarina Mcmanus', 'Toni Mellor',
           'Rogan Floyd', 'Anum Lake', 'Elora Mcbride', 'Aariz Shea', 'Gaia Wooten', 'Frederick Bonilla', 'Anastazja Bonner',
           'Ellie Obrien', "Carmel O'Brien", 'Elsie Blanchard', 'Rukhsar Houston', 'Aanya Akhtar', 'Vicky Livingston', 'Tarik Gentry',
           'Amber-Rose Lam', 'Ryan Dixon', 'Finnian Perkins', 'Eiliyah Bowes', 'Joyce Bright', 'Renzo Ewing', 'Yusra Mcpherson',
           'Sallie Maynard', 'Abdullah Ritter', 'Nabil Hook', 'Emer Beattie', 'Aiesha Mcdougall', 'Anya Black', 'Tony Mustafa',
           'Mitchell Hayward', 'Walid Butler', 'Samir Huber', 'Gordon Hassan', 'Leanna Olsen', 'Branden Whitley', 'Sasha Parry',
           'Una Allan', 'Lucie Southern', 'Nia Cabrera', 'Chante Sloan', 'Stewart Grey', 'Dillan Phan', 'Francesco Hollis',
           'April Neal', 'Kwabena House', 'Jadon Cordova', 'Brooke Robinson', 'Gary Davila', 'Uwais Naylor', 'Shirley Ahmad',
           'Om Carney', 'Nazim Owens', 'Elissa Hewitt', 'Mabel Croft', 'Hamza Knapp', 'Micheal Crosby', 'Karter Hines',
           'Ann Faulkner', 'Lochlan Wainwright', 'Olivia-Grace Robbins', 'Mahek Dominguez', 'Anja Spence', 'Bella Reese',
           'Samiha Dodd', 'Taryn Correa', 'Dylon Arellano', 'Conal Fischer', 'June Rowe', 'Arwen Mays', 'Adelle Vargas',
           'Annie Johnson', 'Jimi Leach', 'Zachary Harwood', 'Tiernan Ellwood', 'Coen Keenan', 'Jody Horner', 'Xena Howell',
           'Avni Quinn', 'Monica Tillman', 'Muskaan Reyes', 'Saara Goodman', 'Bob Hebert', 'Aras Cooper', 'Duane Adam',
           'Cecil Corona', 'Esha Felix', 'Mayur Steele']
unreturned_books = [4, 2, 3, 2, 4, 3, 3, 2, 3, 2, 4, 0, 4, 4, 3, 1, 0, 0, 0, 3, 4, 2,
       2, 3, 3, 0, 0, 2, 4, 4, 4, 2, 3, 3, 4, 0, 2, 3, 3, 0, 2, 1, 4, 1,
       2, 3, 1, 3, 0, 2, 1, 1, 0, 3, 1, 3, 1, 0, 1, 2, 1, 4, 2, 2, 0, 3,
       1, 1, 4, 3, 1, 3, 4, 0, 0, 3, 1, 3, 3, 0, 2, 1, 2, 1, 3, 3, 0, 4,
       0, 2, 4, 3, 1, 1, 4, 1, 2, 2, 2, 2]
# DO_NOT_EDIT_ANYTHING_ABOVE_THIS_LINE
finished = False # the user can at most have 5 unreturned books and can borrow at most 3 books at the same time, check if they are returning more books than they borrowed

while not finished:
    operation = input() # 'borrow' or 'return' or 'exit'
    while operation not in ['borrow', 'return', 'exit']:
        operation = input()

    if operation == 'exit':
        finished = True
        break

    user_id = input()
    while user_id not in members:
        user_id = input()

    amount = int(input())
    while amount <= 0:
        amount = int(input())

    i = members.index(user_id)
    user_account_info = unreturned_books[i]

    if operation == "borrow" and amount > 3:
        print("You cannot borrow more than 3 books at the same time")
        continue

    elif operation == "borrow" and (user_account_info == 5 or (user_account_info + amount > 5)):
        print("You must return the books you borrowed first")
        continue

    elif user_account_info < amount and operation == "borrow":
        old_amount = unreturned_books[i]
        unreturned_books[i] += amount
        print(old_amount, "=>", unreturned_books[i])
        continue

    elif operation == 'return' and amount > user_account_info:
        print("Whose books are they?")
        continue

    elif operation == 'return' and amount <= user_account_info:
        old_amount = unreturned_books[i]
        unreturned_books[i] -= amount
        print(old_amount, "=>", unreturned_books[i])
        continue
# DO_NOT_EDIT_ANYTHING_BELOW_THIS_LINE


# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models, migrations

class Migration(migrations.Migration):

    dependencies = [
        ('libraryapp', '0001_initial'),
    ]

    operations = [
        migrations.AddField(
            model_name='book',
            name='publishing_date',
            field=models.DateField(null=True, verbose_name='Publishing date', blank=True),
        ),
    ]


class Solution(object):
    def isPowerOfThree(self, n):
        """
        :type n: int
        :rtype: bool
        """
        if(n==0):
            return False
        else:
            while(n!=1):
                if(n%3!=0):
                    return False
                n=n/3
            return True

    x = isPowerOfThree(1,27)
    print(x)

    # https://leetcode.com/problems/power-of-three/


from bs4 import BeautifulSoup
from abc import ABC, abstractmethod
import requests

# 美食抽象類別
class Food(ABC):

    def __init__(self, area, category, price):
        self.area = area  # 地區
        self.category = category
        self.price = price
    @abstractmethod
    def scrape(self):
        pass

# 愛食記爬蟲
class IFoodie(Food):

    def scrape(self):
        response = requests.get(
            "https://ifoodie.tw/explore/" + self.area +
            "/list/" + self.category +
            "?priceLevel=" + self.price +
            "&sortby=popular&opening=true")

        soup = BeautifulSoup(response.content, "html.parser")

        cards = soup.find_all(
            'div', {'class': 'jsx-2740740998 restaurant-info'}, limit=6)

        content = ""
        for card in cards:

            title = card.find(  # 餐廳名稱
                "a", {"class": "jsx-2740740998 title-text"}).getText()

            stars = card.find(  # 餐廳評價
                "div", {"class": "jsx-1207467136 text"}).getText()
            address = card.find(  # 餐廳地址
                "div", {"class": "jsx-2740740998 address-row"}).getText()

            opening = card.find(
                "div",{"class": "jsx-2740740998 info"}).getText()

            url = card.find(
                "a",{"class":"jsx-2740740998 title-text"}).get("href")
            content += f"{title}  ⭐{stars}顆星\n\n🚗  {address}\n⏱  {opening}\n\n更多資訊：https://ifoodie.tw{url}\n\n"
        return content


import numpy as np
import pandas as pd
import tensorflow as tf

from datetime import date as d
from tensorflow import keras
from tensorflow.keras.models import load_model
from keras_preprocessing import image
from flask import Flask, jsonify, request

SERVER_INFO = {
    'AUTHOR': '\nRebecca Norwood',
    'NAME': '\nRock, Paper, Scissors image classification server.',
    'CURRENT_DATE_TIME': '\n' + d.today().strftime("%B %d, %Y")
}

"""initialize our Flask application"""
app = Flask(__name__)

"""load the model"""
# MODEL_PATH = 'Z:/School/CSUSM/Spring 2022/CS 478/Assignments/Norwood_Assignment6/model.h5'
# model = load_model(MODEL_PATH)
model = load_model('.\model.h5')

"""Default route that returns application info"""
@app.route('/', methods=['GET'])
def index():
    return (SERVER_INFO['NAME'] +
            SERVER_INFO['AUTHOR'] +
            SERVER_INFO['CURRENT_DATE_TIME'])

"""Test the model with test images"""
"""Images from: https://oreil.ly/dEUpx"""
@app.route('/predict', methods=['GET', 'POST'])
def predict():

    classifcation = ['paper', 'rock', 'scissors']

    if request.method == 'POST':
        posted_data = request.get_json()
        data = posted_data['data']

        image_path = 'client_images\\' + data
        img = image.load_img(image_path, target_size=(150,150))

        x = image.img_to_array(img)
        x = np.expand_dims(x, axis = 0)

        images = np.vstack([x])
        classes = model.predict(images, batch_size = 10)

        #Iterate through numpy array of images and set proper category dependent on array position
        for outerloop in classes:
            for idx, num in enumerate(outerloop):
                if num == 0:
                    continue
                else:
                    category = classifcation[idx]

    return jsonify(str("The image you've submitted is classified as a: " + str(category)))

#  main thread of execution to start the server
if __name__=='__main__':
    app.run(debug=True)


import io
import sys
import os
import sys
import time
import traceback

from PyQt5 import QtWidgets
from PyQt5.QtCore import Qt, QSharedMemory, pyqtSignal, QCoreApplication, QFile, QTextStream
from PyQt5.QtGui import QIcon, QFontDatabase

from app.core.common.logapi import log
from app.core.common.registry import Registry
from app.core.common.resourceslocation import ResourcesLocation
from app.core.common.settings import Settings

from app.core.lib.translator.translatormanager import LanguageManager

from app.ui.abstract import WelcomeNotification
from app.ui.exceptiondialog import CriticalExceptionDialog
from app.ui.globalframe import GlobalFrame
from app.ui.splashscreen import SplashScreen
from app.ui.wizard.firsttimewizard import Wizard

# Initialise the resources
from app import resources

class AppFTD(QtWidgets.QApplication):
    """
    The core application class. This class inherits from Qt's QApplication
    class in order to provide the core of the application.
    """

    welcome_message = 'This application is aimed to provide a local (without Internet connection) way to users to ' \
                      'work with Tabular data. \n\nIt has been developed from scratch and may contains ' \
                      'bugs. \nDon\'t hesitate to send any report if you find a bug while using the program.'

    welcome_title = 'Welcome to the Application'

    modify_style = pyqtSignal()

    def __init__(self, parent=None):
        super(AppFTD, self).__init__(parent)

        Registry.create()

        # self.style = 0
        self.modify_style.connect(self.change_style)

        # Initialize language manager
        LanguageManager(language='en_US')

        # Add predefined fonts
        #QFontDatabase.addApplicationFont(":/fonts/besmellah.ttf")
        QFontDatabase.addApplicationFont(":/fonts/capsuula.ttf")
        QFontDatabase.addApplicationFont(":/fonts/ubuntu.ttf")

        # Set stylesheet as Qt resource
        stylesheet = QFile(":/styles/default.css")
        stylesheet.open(QFile.ReadOnly | QFile.Text)

        self.stylesheet = QTextStream(stylesheet).readAll()
        self.setStyleSheet(self.stylesheet)

        self.setApplicationDisplayName("AppFTD")
        self.setApplicationName("AppFTD")

        self.setEffectEnabled(Qt.UI_AnimateCombo, False)
        self.setAttribute(Qt.AA_UseHighDpiPixmaps, True)

        Registry().register_signal("change_style", self.modify_style)

    def change_style(self):
        """
        Change stylesheet.

        :return:
        """
        pass
        # if self.style == 0:
        #     self.setStyleSheet(open("resources/styles/white.css").read())
        #     self.style = 1
        # else:
        #     self.setStyleSheet(open("resources/styles/default.css").read())
        #     self.style = 0

    def exec_(self):
        """
        Override exec method to allow the shared memory to be released on exit
        """
        result = QtWidgets.QApplication.exec_()
        # This function seems to cause problem in Ubuntu Linux because shared memory is not released.
        self.shared_memory.detach()
        return result

    def run(self):
        """
        Run the AppFTD application.x
        """
        activate_first_notification = False

        # First time checks in settings
        has_run_wizard = Settings().value('general_settings/wizard_runned')
        if not has_run_wizard:
            first_wizard = Wizard(parent=None)
            if first_wizard.exec_() == QtWidgets.QDialog.Accepted:
                Settings().setValue('general_settings/wizard_runned', 1)
                # Create the first notification only after wizard has been completed
                activate_first_notification = True
            elif first_wizard.was_cancelled:
                QCoreApplication.exit()
                sys.exit()

        # Show the SplashScreen
        show_splash = Settings().value('general_settings/splashscreen')
        if show_splash:
            splash = SplashScreen()
            splash.start_splashscreen.emit()

        # Start the main app window
        self.global_frame = GlobalFrame()

        # Make sure Qt really display the splash screen
        self.processEvents()
        self.global_frame.repaint()
        self.processEvents()

        Registry().execute('__application_init__')
        Registry().execute('__application_post_init__')

        self.processEvents()

        self.global_frame.show()

        # Show first notification program
        if activate_first_notification:
            WelcomeNotification(self.global_frame).notify(WelcomeNotification.OK, self.welcome_message,
                                                          self.welcome_title, button_text='OK')

        if show_splash:
            # now kill the splashscreen
            splash.finish(self.global_frame)
            log.debug('Splashscreen closed')

        # Need to implement update checker
        # update_check = Settings().value('general_settings/update_check')
        # if update_check:
        #     process

        return self.exec_()

    def is_already_running(self):
        """
        Look to see if AppFTD is already running and ask if a 2nd instance is to be started.
        """
        self.shared_memory = QSharedMemory('AppFTD')
        if self.shared_memory.attach():
            log.error("It's already running")
            return True
        else:
            self.shared_memory.create(1)
            return False

    def set_busy_cursor(self):
        """
        Sets the Busy Cursor for the Application
        """
        self.setOverrideCursor(Qt.BusyCursor)
        self.processEvents()

    def set_normal_cursor(self):
        """
        Sets the Normal Cursor for the Application
        """
        self.restoreOverrideCursor()
        self.processEvents()

def hook_exception(exc_type, exc_value, tracebackobj):
    """
    Global function to catch unhandled exceptions.
    Add an exception hook so that any uncaught exceptions are displayed in this window rather than somewhere where
    users cannot see it and cannot report when we encounter these problems.

    :param exc_type: The class of exception.
    :param exc_value: The actual exception object.
    :param tracebackobj: A traceback object with the details of where the exception occurred.
    """
    instance = AppFTD.instance()

    # KeyboardInterrupt is a special case.
    # We don't raise the error dialog when it occurs.
    if issubclass(exc_type, KeyboardInterrupt):
        if instance:
            instance.closeAllWindows()
        return

    separator = '-' * 80

    log_crash_file = ResourcesLocation().logs_dir + "/crash.log"
    log_dir = os.path.dirname(os.path.realpath(log_crash_file))

    # Create log dir to report crash and logging
    if not os.path.exists(log_dir):
        os.makedirs(log_dir)

    notice = \
        """An unhandled exception occurred. Please report the problem\n""" \
        """using the error reporting dialog or raise issue to {}.\n""" \
        """A log has been written to "{}".\n\nError information:\n""".format("github.com/ns3098",
                                                                             log_crash_file)
    time_string = time.strftime("%Y-%m-%d, %H:%M:%S")

    tbinfofile = io.StringIO()
    traceback.print_tb(tracebackobj, None, tbinfofile)
    tbinfofile.seek(0)
    tbinfo = tbinfofile.read()
    errmsg = '%s: \n%s' % (str(exc_type), str(exc_value))

    sections = [separator, time_string, separator, errmsg, separator, tbinfo]
    msg = '\n'.join(sections)

    with open(log_crash_file, 'w') as f:
        try:
            f.write(msg)
        except OSError:
            pass

    error_box = CriticalExceptionDialog()
    error_box.text_edit.setText(str(notice) + str(msg))
    if not error_box.exec_():
        Registry().execute("close_application")
        QtWidgets.QApplication.instance().quit()

def main():
    """
    The main function which parses command line options and then runs
    """
    # Add path to qt_plugins instead of having mediaservice, platforms and sqldrivers in main
    # directory, currently : plugins/mediaservice - plugins/platforms - plugins/sqldrivers

    # This is required for adding furthur functionality.
    QtWidgets.QApplication.addLibraryPath(os.path.join(ResourcesLocation().root_dir, 'plugins'))

    # Now create and actually run the application.
    app = AppFTD(sys.argv)

    log.info('Running program')
    log.info('INI file: %s', Settings.file_path)

    Registry().register('application', app)
    app.setApplicationVersion("v0.0.1")
    app.setWindowIcon(QIcon(":/icons/app_icon.png"))
    # Registry().execute("restore_default_settings")

    # Instance check
    if app.is_already_running():
        sys.exit()

    sys.excepthook = hook_exception
    sys.exit(app.run())


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

from __future__ import unicode_literals

import copy
import imp
import os
import tempfile

import jinja2
from flask import abort
from flask import current_app
from jinja2schema import infer
from jinja2schema import to_json_schema

from api.extensions import db
from api.lib.cmdb.attribute import AttributeManager
from api.lib.cmdb.cache import AttributeCache
from api.lib.cmdb.cache import CITypeAttributeCache
from api.lib.cmdb.const import OperateType
from api.lib.cmdb.const import ValueTypeEnum
from api.lib.cmdb.history import AttributeHistoryManger
from api.lib.cmdb.resp_format import ErrFormat
from api.lib.cmdb.utils import TableMap
from api.lib.cmdb.utils import ValueTypeMap
from api.lib.utils import handle_arg_list
from api.models.cmdb import CI

class AttributeValueManager(object):
    """
    manage CI attribute values
    """

    def __init__(self):
        pass

    @staticmethod
    def _get_attr(key):
        """
        :param key: id, name or alias
        :return: attribute instance
        """
        return AttributeCache.get(key)

    def get_attr_values(self, fields, ci_id, ret_key="name", unique_key=None, use_master=False):
        """

        :param fields:
        :param ci_id:
        :param ret_key: It can be name or alias
        :param unique_key: primary attribute
        :param use_master: Only for master-slave read-write separation
        :return:
        """
        res = dict()
        for field in fields:
            attr = self._get_attr(field)
            if not attr:
                continue

            value_table = TableMap(attr=attr).table
            rs = value_table.get_by(ci_id=ci_id,
                                    attr_id=attr.id,
                                    use_master=use_master,
                                    to_dict=False)
            field_name = getattr(attr, ret_key)
            if attr.is_list:
                res[field_name] = [ValueTypeMap.serialize[attr.value_type](i.value) for i in rs]
            elif attr.is_password and rs:
                res[field_name] = '******' if rs[0].value else ''
            else:
                res[field_name] = ValueTypeMap.serialize[attr.value_type](rs[0].value) if rs else None

            if unique_key is not None and attr.id == unique_key.id and rs:
                res['unique'] = unique_key.name
                res['unique_alias'] = unique_key.alias

        return res

    @staticmethod
    def _deserialize_value(value_type, value):
        if not value:
            return value

        deserialize = ValueTypeMap.deserialize[value_type]
        try:
            v = deserialize(value)
            return v
        except ValueError:
            return abort(400, ErrFormat.attribute_value_invalid.format(value))

    @staticmethod
    def _check_is_choice(attr, value_type, value):
        choice_values = AttributeManager.get_choice_values(attr.id, value_type, attr.choice_web_hook, attr.choice_other)
        if str(value) not in list(map(str, [i[0] for i in choice_values])):
            return abort(400, ErrFormat.not_in_choice_values.format(value))

    @staticmethod
    def _check_is_unique(value_table, attr, ci_id, type_id, value):
        existed = db.session.query(value_table.attr_id).join(CI, CI.id == value_table.ci_id).filter(
            CI.type_id == type_id).filter(
            value_table.attr_id == attr.id).filter(value_table.deleted.is_(False)).filter(
            value_table.value == value).filter(value_table.ci_id != ci_id).first()

        existed and abort(400, ErrFormat.attribute_value_unique_required.format(attr.alias, value))

    @staticmethod
    def _check_is_required(type_id, attr, value, type_attr=None):
        type_attr = type_attr or CITypeAttributeCache.get(type_id, attr.id)
        if type_attr and type_attr.is_required and not value and value != 0:
            return abort(400, ErrFormat.attribute_value_required.format(attr.alias))

    def _validate(self, attr, value, value_table, ci=None, type_id=None, ci_id=None, type_attr=None):
        ci = ci or {}
        v = self._deserialize_value(attr.value_type, value)

        attr.is_choice and value and self._check_is_choice(attr, attr.value_type, v)
        attr.is_unique and self._check_is_unique(
            value_table, attr, ci and ci.id or ci_id, ci and ci.type_id or type_id, v)

        self._check_is_required(ci and ci.type_id or type_id, attr, v, type_attr=type_attr)

        if v == "" and attr.value_type not in (ValueTypeEnum.TEXT,):
            v = None

        return v

    @staticmethod
    def _write_change(ci_id, attr_id, operate_type, old, new, record_id, type_id):
        return AttributeHistoryManger.add(record_id, ci_id, [(attr_id, operate_type, old, new)], type_id)

    @staticmethod
    def write_change2(changed, record_id=None):
        for ci_id, attr_id, operate_type, old, new, type_id in changed:
            record_id = AttributeHistoryManger.add(record_id, ci_id, [(attr_id, operate_type, old, new)], type_id,
                                                   commit=False, flush=False)
        try:
            db.session.commit()
        except Exception as e:
            db.session.rollback()
            current_app.logger.error("write change failed: {}".format(str(e)))

        return record_id

    @staticmethod
    def _compute_attr_value_from_expr(expr, ci_dict):
        t = jinja2.Template(expr).render(ci_dict)

        try:
            return eval(t)
        except Exception as e:
            current_app.logger.warning(str(e))
            return t

    @staticmethod
    def _compute_attr_value_from_script(script, ci_dict):
        script = jinja2.Template(script).render(ci_dict)

        script_f = tempfile.NamedTemporaryFile(delete=False, suffix=".py")
        script_f.write(script.encode('utf-8'))
        script_f.close()

        try:
            path = script_f.name
            dir_name, name = os.path.dirname(path), os.path.basename(path)[:-3]

            fp, path, desc = imp.find_module(name, [dir_name])

            mod = imp.load_module(name, fp, path, desc)

            if hasattr(mod, 'computed'):
                return mod.computed()
        except Exception as e:
            current_app.logger.error(str(e))

        finally:
            os.remove(script_f.name)

    @staticmethod
    def _jinja2_parse(content):
        schema = to_json_schema(infer(content))

        return [var for var in schema.get("properties")]

    def _compute_attr_value(self, attr, payload, ci_id):
        attrs = (self._jinja2_parse(attr['compute_expr']) if attr.get('compute_expr')
                 else self._jinja2_parse(attr['compute_script']))
        not_existed = [i for i in attrs if i not in payload]
        if ci_id is not None:
            payload.update(self.get_attr_values(not_existed, ci_id))

        if attr['compute_expr']:
            return self._compute_attr_value_from_expr(attr['compute_expr'], payload)
        elif attr['compute_script']:
            return self._compute_attr_value_from_script(attr['compute_script'], payload)

    def handle_ci_compute_attributes(self, ci_dict, computed_attrs, ci):
        payload = copy.deepcopy(ci_dict)
        for attr in computed_attrs:
            computed_value = self._compute_attr_value(attr, payload, ci and ci.id)
            if computed_value is not None:
                ci_dict[attr['name']] = computed_value

    def valid_attr_value(self, ci_dict, type_id, ci_id, name2attr, alias2attr=None, ci_attr2type_attr=None):
        key2attr = dict()
        alias2attr = alias2attr or {}
        ci_attr2type_attr = ci_attr2type_attr or {}

        for key, value in ci_dict.items():
            attr = name2attr.get(key) or alias2attr.get(key)
            key2attr[key] = attr

            value_table = TableMap(attr=attr).table

            try:
                if attr.is_list:
                    value_list = [self._validate(attr, i, value_table, ci=None, type_id=type_id, ci_id=ci_id,
                                                 type_attr=ci_attr2type_attr.get(attr.id))
                                  for i in handle_arg_list(value)]
                    ci_dict[key] = value_list
                    if not value_list:
                        self._check_is_required(type_id, attr, '')

                else:
                    value = self._validate(attr, value, value_table, ci=None, type_id=type_id, ci_id=ci_id,
                                           type_attr=ci_attr2type_attr.get(attr.id))
                    ci_dict[key] = value
            except Exception as e:
                current_app.logger.warning(str(e))

                return abort(400, ErrFormat.attribute_value_invalid2.format(
                    "{}({})".format(attr.alias, attr.name), value))

        return key2attr

    def create_or_update_attr_value(self, ci, ci_dict, key2attr):
        """
        add or update attribute value, then write history
        :param ci: instance object
        :param ci_dict: attribute dict
        :param key2attr: attr key to attr
        :return:
        """
        changed = []
        for key, value in ci_dict.items():
            attr = key2attr.get(key)
            if not attr:
                continue  # not be here
            value_table = TableMap(attr=attr).table

            if attr.is_list:
                existed_attrs = value_table.get_by(attr_id=attr.id, ci_id=ci.id, to_dict=False)
                existed_values = [i.value for i in existed_attrs]
                added = set(value) - set(existed_values)
                deleted = set(existed_values) - set(value)
                for v in added:
                    value_table.create(ci_id=ci.id, attr_id=attr.id, value=v, flush=False, commit=False)
                    changed.append((ci.id, attr.id, OperateType.ADD, None, v, ci.type_id))

                for v in deleted:
                    existed_attr = existed_attrs[existed_values.index(v)]
                    existed_attr.delete(flush=False, commit=False)
                    changed.append((ci.id, attr.id, OperateType.DELETE, v, None, ci.type_id))
            else:
                existed_attr = value_table.get_by(attr_id=attr.id, ci_id=ci.id, first=True, to_dict=False)
                existed_value = existed_attr and existed_attr.value
                if existed_value is None and value is not None:
                    value_table.create(ci_id=ci.id, attr_id=attr.id, value=value, flush=False, commit=False)

                    changed.append((ci.id, attr.id, OperateType.ADD, None, value, ci.type_id))
                else:
                    if existed_value != value:
                        if value is None:
                            existed_attr.delete(flush=False, commit=False)
                        else:
                            existed_attr.update(value=value, flush=False, commit=False)

                        changed.append((ci.id, attr.id, OperateType.UPDATE, existed_value, value, ci.type_id))

        try:
            db.session.commit()
        except Exception as e:
            db.session.rollback()
            current_app.logger.warning(str(e))
            return abort(400, ErrFormat.attribute_value_unknown_error.format(e.args[0]))

        return self.write_change2(changed)

    @staticmethod
    def delete_attr_value(attr_id, ci_id):
        attr = AttributeCache.get(attr_id)
        if attr is not None:
            value_table = TableMap(attr=attr).table
            for item in value_table.get_by(attr_id=attr.id, ci_id=ci_id, to_dict=False):
                item.delete()


import numpy as np
from matplotlib import pyplot as plt

def show_signal(audio_input, sample_rate=16_000, start=0, ):
    """
    This function takes in an audio signal, sample rate, and start time, and plots the signal in the time domain.

    :param audio_input: the audio signal you want to plot
    :param sample_rate: The sample rate of the audio file
    :param start: the start time of the signal in seconds
    """
    duration = audio_input.shape[0] / float(sample_rate)
    t = np.arange(0, duration, duration / audio_input.shape[0])
    t = np.add(t, start)
    fig, axs = plt.subplots()
    axs.set_title("Signal")
    axs.plot(t, audio_input)
    axs.set_xlabel("Time")
    axs.set_ylabel("Amplitude")
    plt.show()

def show_stats(list_input):
    """
    It shows the stats.

    :param list_input: a list of numbers
    """
    t = np.arange(0, len(list_input))
    fig, axs = plt.subplots()
    axs.set_title("Statistics")
    axs.plot(t, list_input)
    axs.set_xlabel("time")
    axs.set_ylabel("y")
    plt.show()


"""
Module defining the ToolTip widget
"""
from __future__ import annotations

import time
import tkinter as tk
from typing import Callable

# This code is based on Tucker Beck's implementation licensed under an MIT License
# Original code: http://code.activestate.com/recipes/576688-tooltip-for-tkinter/

class ToolTip(tk.Toplevel):
    """
    Creates a ToolTip (pop-up) widget for tkinter
    """

    def __init__(
        self,
        widget: tk.Widget,
        msg: str | Callable = None,
        delay: float = 0.0,
        follow: bool = True,
        refresh: float = 1.0,
        x_offset: int = +10,
        y_offset: int = +10,
        parent_kwargs: dict = {"bg": "black", "padx": 1, "pady": 1},
        **message_kwargs,
    ):
        """Create a ToolTip. Allows for `**kwargs` to be passed on both
            the parent frame and the ToolTip message

        Parameters
        ----------
        widget : tk.Widget
            The widget this ToolTip is assigned to
        msg : `Union[str, Callable]`, optional
            A string message (can be dynamic) assigned to the ToolTip.
            Alternatively, it can be set to a function thatreturns a string,
            by default None
        delay : `float`, optional
            Delay in seconds before the ToolTip appears, by default 0.0
        follow : `bool`, optional
            ToolTip follows motion, otherwise hides, by default True
        refresh : `float`, optional
            Refresh rate in seconds for strings and functions when mouse is
            stationary and inside the widget, by default 1.0
        x_offset : `int`, optional
            x-coordinate offset for the ToolTip, by default +10
        y_offset : `int`, optional
            y-coordinate offset for the ToolTip, by default +10
        parent_kwargs : `dict`, optional
            Optional kwargs to be passed into the parent frame,
            by default `{"bg": "black", "padx": 1, "pady": 1}`
        **message_kwargs : tkinter `**kwargs` passed directly into the ToolTip
        """
        self.widget = widget
        # ToolTip should have the same parent as the widget unless stated
        # otherwise in the `parent_kwargs`
        tk.Toplevel.__init__(self, **parent_kwargs)
        self.withdraw()  # Hide initially in case there is a delay
        # Disable ToolTip's title bar
        self.overrideredirect(True)

        # StringVar instance for msg string|function
        self.msgVar = tk.StringVar()
        # This can be a string or a function
        # Do not bother doing any sort of checks here since it sometimes results
        # into multiple spawn-hide calls being made when swapping between tooltips
        self.msg = msg
        self.delay = delay
        self.follow = follow
        self.refresh = refresh
        self.x_offset = x_offset
        self.y_offset = y_offset
        # visibility status of the ToolTip inside|outside|visible
        self.status = "outside"
        self.last_moved = 0
        # use Message widget to host ToolTip
        tk.Message(self, textvariable=self.msgVar, aspect=1000, **message_kwargs).grid()
        # Add bindings to the widget without overriding the existing ones
        self.widget.bind("<Enter>", self.on_enter, add="+")
        self.widget.bind("<Leave>", self.on_leave, add="+")
        self.widget.bind("<Motion>", self.on_enter, add="+")
        self.widget.bind("<ButtonPress>", self.on_leave, add="+")

    def on_enter(self, event) -> None:
        """
        Processes motion within the widget including entering and moving.
        """
        self.last_moved = time.time()

        # Set the status as inside for the very first time
        if self.status == "outside":
            self.status = "inside"

        # If the follow flag is not set, motion within the widget will
        # make the ToolTip dissapear
        if not self.follow:
            self.status = "inside"
            self.withdraw()

        # Offsets the ToolTip using the coordinates od an event as an origin
        self.geometry(f"+{event.x_root + self.x_offset}+{event.y_root + self.y_offset}")

        # Time is integer and in milliseconds
        self.after(int(self.delay * 1000), self._show)

    def on_leave(self, event=None) -> None:
        """
        Hides the ToolTip.
        """
        self.status = "outside"
        self.withdraw()

    def _show(self) -> None:
        """
        Displays the ToolTip.

        Recursively queues `_show` in the scheduler every `self.refresh` seconds
        """
        if self.status == "inside" and time.time() - self.last_moved > self.delay:
            self.status = "visible"

        if self.status == "visible":
            # Update the string with the latest function call
            # Try and call self.msg as a function, if msg is not callable try and
            # set it as a normal string if that fails throw an error
            try:
                self.msgVar.set(self.msg())
            except TypeError:
                # Intentionally do not check if msg is str, can be a list of str
                self.msgVar.set(self.msg)
            except:
                raise (
                    "Error: ToolTip `msg` must be a string or string returning "
                    + f"function instead `msg` of type {type(self.msg)} was input"
                )
            self.deiconify()

            # Recursively call _show to update ToolTip with the newest value of msg
            # This is a race condition which only exits when upon a binding change
            # that in turn changes the `status` to outside
            self.after(int(self.refresh * 1000), self._show)


import unittest
import parsers

class UptimeParserTest(unittest.TestCase):

    def setUp(self):
        self.example = '84983.36 434057.28'

    def test_process_stat_parsing(self):
        parser = parsers.get_parser('uptime')
        stats = parser.parse(self.example, dict())['stats']
        self.assertEqual(84983.36, stats.uptime)
        self.assertEqual(434057.28, stats.uptime_idle)

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


# dev-csv-to-html.py
#
#
# Issues: select all, select none, open selected
# deselect certain domains
import time
import csv
import os
import pandas as pd
import datetime
import validators

#########################################
# list of URL's that are not included in the final output
urlCheckList = ['googleapis','public-api.wordpress','stats.wp.com','gstatic','@gmail.com','doubleclick.net','ads-api.twitter.com','.js','.svg','.css','plus.google.com','.jpg','.png']

file_dir = '/Users/paulb.sizemore/OneDrive/_github/data_csv-to-html-links/'

files = [  f for f in os.listdir(file_dir)  if f.endswith(".csv")]
log_text = ''

for i in files:
    print('-----------------------------------------------')
    print(i)
    #print('-----------------------------------------------')
    file_name = file_dir + i.replace(".csv","") + ".html"
    urlList = []

    try:
        df = pd.read_csv(file_dir + i)
        df = df.drop_duplicates()

        for name, values in df.iteritems():
            #print(name)
            for index, row in df.iterrows():
                testText = str(values[index])
                #################################################
                # Testing to see if URL was returned
                if validators.url(testText):
                    # print('URL TO TEST:' + testText)
                    testCheckList = 0
                    ##############################################
                    # Testing to see if URL has a non-user string
                    for k in urlCheckList:
                        # print(k)
                        if k in testText:
                            testCheckList = 1
                            # print(testCheckList)
                        else:
                            testCheckList = testCheckList
                            # print(testCheckList)

                    if testCheckList == 0: urlList.append(testText)

        urlList = list(dict.fromkeys(urlList))
        #urlList = urlList.sort()

        if len(urlList) > 1:
            htmlOut = '<!DOCTYPE HTML>
Open All Links in

' + i + '
'
            urlCounter = 0
            for j in urlList:
                urlCounter = urlCounter + 1
                htmlOut = htmlOut + '(' + str(urlCounter) + ') ' + j + '
\n'
            htmlOut = htmlOut + '	'

            text_out = htmlOut
            with open(file_name, "w") as text_file:
                print(text_out, file=text_file)
        else: log_text = log_text + 'No rows returned: ' + file_name + '\n'
    except:
        log_text = log_text + 'Error: ' + file_name + '\n'

file_name = file_dir + '_error.log'
with open(file_name, "w") as text_file:
    print(log_text, file=text_file)


import json

from django.shortcuts import render
from django.db import connection
from django.http import HttpResponse

def main_page(request):
    return render(request, 'app/main_page.html', {})

def get_count_client(request):
    cursor = connection.cursor()
    cursor.execute('''SELECT count(distinct "Код клиента") from Клиент''')
    result = cursor.fetchone()
    response_data = {
        'data': result[0],
        'status': 200,
        'message': 'Ok.'
    }
    return HttpResponse(json.dumps(response_data), content_type="application/json")

def get_count_per_user(request):
    cursor = connection.cursor()
    cursor.execute('''SELECT users.*, orders.order_count
    from
    (
        SELECT "Код клиента", count(distinct "Код заказа") as order_count
        from "Заказ клиента" group by "Код клиента"
    ) as orders
    join Клиент as users on orders."Код клиента" == users."Код клиента"''')
    result = cursor.fetchall()

    response_data = [{"Код клиента": obj[0], "Фамилия":obj[1], "Имя":obj[2], "Город":obj[3], "Код заказа":obj[4], "Количество ордеров":obj[5]} for obj in result]

    return HttpResponse(json.dumps(response_data), content_type="application/json")


from random import *
#일반 유닛
class Unit:
    def __init__(self, name, hp, speed):
        self.name = name
        self.hp = hp
        self.speed = speed
        print("{0} 유닛이 생성되었습니다.".format(name)) #self.name해도 상관없음

    def move(self,location):
        print("[지상유닛 이동]")
        print("{0} : {1} 방향으로 이동합니다. [속도{2}]"\
            .format(self.name, location, self.speed))

    def damaged(self,damage): #메딕처럼 공격력이 없는 유닛도 데미지를 받을 수 있으니까
                              #어차피 하위클래스여서 상관없음
        print("{0} : {1} 데미지를 입었습니다".format(self.name, damage))
        self.hp -= damage
        print("{0} : 현재 체력은 {1}입니다".format(self.name, self.hp))
        if self.hp <= 0:
            print("{0} : 파괴되었습니다.".format(self.name))
#공격 유닛
class AttackUnit(Unit):
    def __init__(self, name, hp, speed, damage):
        Unit.__init__(self, name, hp, speed)
        self.damage = damage

    def attack(self, location):
        print("{0} : {1} 방향으로 적군을 공격합니다. [공격력{2}"\
            .format(self.name, location, self.damage))

#마린, 매번 AttackUnit에 매개변수에 마린의 정보를 던져주는 것은 불편하니까
#마린은 AttackUnit에 속하니까
class Marine(AttackUnit):
    def __init__(self):
        AttackUnit.__init__(self, "마린", 40, 1 ,5)

#만약 def__init__(self, name, 40, 1 ,5) 하면 의미가 없으니까
#고정 사용 목적이니까
#이전에는 def에서 매개변수에 할당된 값으로 정의를 했다면, 이번에는 직접 입력해서 정의한 것
#그리고 단순히 Marine클래스를 사용했을 때 attackunit이외에 다른 것은 필요가 없고 매개변수 필요한게 없으니
#self만 사용한것임

    #스팀팩 : 일정 시간 동안 이동 및 공격 속도를 증가, 체력 10 감소
    def stimpack(self):
        if self.hp > 10:
            self.hp -= 10
            print("{0} : 스팀팩을 사용합니다. (HP 10 감소)".format(self.name))
        else:
            print("{0} : 체력이 부족하여 스팀팩을 사용하지 않습니다.".format(self.name))

#탱크

class Tank(AttackUnit):

    #시즈모드 : 탱크를 지상에 고정시켜, 더 높은 파워로 공격 가능, 이동불가.
    seize_developed = False #시즈모드 개발여부
                            #tank1,2,3,4.. 개발함과 동시에 모두 적용이니까
                            #init에 안하고 그 위에 함
                            #init에 하면 새로 탱크를 만들때 마다 init이 실행되어 새로나온 unit은 false가 되니까
                            #근데 앞에다가 선언을 하면 tank클래스를 사용하는 모든 객체에 적용이 되는 거니까
                            #그리고 이렇게 밖에다 선언한 변수는 클래스이름.~ 으로 사용한다.

    def __init__(self): #init함수는 클래스를 호출할 때 사용되는 함수
                        #다른 함수들은 내가 따로 호출을 해야함.
        AttackUnit.__init__(self, "탱크", 150, 1 , 35)
        self.seize_mode = False

    #init을 제외한 함수의 매개변수가 self로 시작하기 때문에 함수를 호출할 때 self.함수 이런식인 거임
    #그리고 이때 self는 객체이름임
    #wraith1 = FlyableAttackUnit(...)
    #wraith2 = FlyableAttackUnit(...)
    #wraith1, 2여도 이들의 이름은 wraith여야함.
    #wraith1 = FlyableAttackUnit("wraith"..)
    #...
    #self.name = name = wraith
    #따라서 wraith1.name 해도 wraith가 나오는 거임
    #상위클래스를 호출하면 상위클래스의 init 하위클래스의 init 코드가 다 실행된다고 생각.
    #상위클래스에서 하위클래스의 함수를 부를 수 있는 것은 당연한것, 클래스를 떠나서 앞에 함수 주르륵 선언하고 함수내부에서 함수 호출 가능

    def set_seize_mode(self):
        if Tank.seize_developed == False: #def함수 밖에서 선언한 클래스 내에서 전역변수 느낌이니까 Tank
            return #객체 생성이후 self.set_seize_mode를 했는데 False면 return
                   #return을 만나면 이후 함수코드는 실행되지 않는다. 그리고 여기서는 리턴값이 없으니 아무것도 실행 안됨

        #현재 시즈모드가 아닐때 -> 시즈모드
        if self.seize_mode == False :
            print("{0} : 시즈모드로 전환합니다.".format(self.name))
            self.damage *= 2
            self.seize_mode = True
        #현재 시즈모드일 때 -> 시즈모드 해제
        else:
            print("{0} : 시즈모드를 해제합니다.".format(self.name))
            self.damage /= 2
            self.seize_mode = False

#날 수 있는 기능을 가진 클래스

class Flyable:
    def __init__(self, flying_speed):
        self.flying_speed = flying_speed

    def fly(self, name, location):
        print("{0} : {1} 방향으로 날라갑니다. [속도{2}]"\
            .format(name, location, self.flying_speed))

#공중 공격 유닛 클래스 : 공격 유닛 + 날 수 있는 유닛

class FlyableAttackUnit(AttackUnit, Flyable):
    def __init__(self, name, hp, damage, flying_speed):
        AttackUnit.__init__(self, name, hp, 0, damage)
        Flyable.__init__(self, flying_speed)

    def move1(self , location):
        print("[공중 유닛 이동]")
        self.fly(self.name, location)

#레이스

class Wraith(FlyableAttackUnit):
    def __init__(self):
        FlyableAttackUnit.__init__(self, "레이스", 80, 20, 5)
        self.clocked = False #클로킹 모드 (해제상태)

    def clocking(self):
        if self.clocked == True: #클로킹 모드 ->모드 해제
            print("{0} : 클로킹 모드 해제합니다.". format(self.name))
            self.clocked = False
        else:
            print("{0} : 클로킹 모드 설정합니다.". format(self.name))
            self.clocked = True

def game_start():
    print("[알림] 새로운 게임을 시작합니다.")

def game_over():
    print("Player : gg") #good gmae
    print("[Player] 님이 게임에서 퇴장하셨습니다.")

#실제 게임 진행
game_start()

#마린 3기 생성
m1 = Marine()
m2 = Marine()
m3 = Marine()

#탱크 2기 생성

t1 = Tank()
t2 = Tank()

#레이스 1기 생성
w1 = Wraith()

#유닛 일괄 관리 (생성된 모든 유닛 append처리)
attack_units = []
attack_units.append(m1)
attack_units.append(m2)
attack_units.append(m3)
attack_units.append(t1)
attack_units.append(t2)
attack_units.append(w1)

#전군 이동
for unit in attack_units:
    unit.move("1시")

#탱크 시즈모드 개발
Tank.seize_developed = True
print("[알림] 탱크 시즈 모드 개발이 완료되었습니다.")

#공격 모드 준비 (마린 : 스팀팩, 탱크 : 시즈모드, 레이스 : 클로킹)
for unit in attack_units:
    if isinstance(unit, Marine): #현재 객체가 클래스 Marine의 인스턴스냐(Marine클래스로 부터 나온 객체냐?)
        unit.stimpack()
    elif isinstance(unit, Tank):
        unit.set_seize_mode()
    elif isinstance(unit, Wraith):
        unit.clocking()

#전군 공격
for unit in attack_units:
    unit.attack("1시")

#전군 피해
for unit in attack_units:
    unit.damaged(randint(5,21)) # 공격은 랜덤으로 받음

#게임종료
game_over()

20스타크래프트(클래스).py

20스타크래프트(클래스).py


from string_manipulation.easy_problems.making_anagrams.test_resources.functionality_test_data import \
    functionality_test_data
from test_utilities.dynamic_test_creator import \
    dynamically_generate_tests, run_dynamic_tests

def making_anagrams(a: str, b: str) -> int:
    count_of_deletions_needed = 0
    unique_characters_in_both = set(a + b)
    counter_a = custom_counter(unique_characters_in_both, a)
    counter_b = custom_counter(unique_characters_in_both, b)
    for character in unique_characters_in_both:
        count_of_deletions_needed += abs(counter_a[character] - counter_b[character])
    return count_of_deletions_needed

def custom_counter(unique_characters: set, string: str) -> dict:
    """
    Given a set of all the unique instances of  different characters
    in a string and said string, returns an instance counter dictionary
    """
    counter = {}
    for character in unique_characters:
        if character in string:
            count = 0
            for char in string:
                if character == char:
                    count += 1
            counter[character] = count
        else:
            counter[character] = 0
    return counter

if __name__ == '__main__':
    dynamically_generate_tests(functionality_test_data, making_anagrams)
    run_dynamic_tests()


def concat(x,y):
    result = []
    i=0
    j = 0

    while i < len(x) and j < len(y):
        if x[i] < y[j]:
            result.append(x[i])
            i += 1
        else:
            result.append(y[j])
            j += 1

    result = result + x[i:] + y[j:]

    return result


"""
A full binary tree is a binary tree where each node has exactly 0 or 2 children.

Return a list of all possible full binary trees with N nodes.  Each element of the answer is the root node of one possible tree.

Each node of each tree in the answer must have node.val = 0.

You may return the final list of trees in any order.

Example 1:

Input: 7
Output: [[0,0,0,null,null,0,0,null,null,0,0],[0,0,0,null,null,0,0,0,0],[0,0,0,0,0,0,0],[0,0,0,0,0,null,null,null,null,0,0],[0,0,0,0,0,null,null,0,0]]
Explanation:

Note:

1 <= N <= 20
"""

# Definition for a binary tree node.
class TreeNode(object):
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None

class Solution(object):
    def __init__(self):
        self.result = {0: [], 1: [TreeNode(0)]}

    def allPossibleFBT(self, N):
        """
        :type N: int
        :rtype: List[TreeNode]
        """
        if N not in self.result:
            tree_list = []
            for x in range(N):
                y = N - 1 - x
                for left in self.allPossibleFBT(x):
                    for right in self.allPossibleFBT(y):
                        tree = TreeNode(0)
                        tree.left = left
                        tree.right = right
                        tree_list.append(tree)
            self.result[N] = tree_list
        return self.result[N]


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

import requests
import datetime
import os

from functions import slugify, getJSON

currentDate = datetime.datetime.now().strftime("%Y-%m-%d.txt")
apiKey = ""
errorOccurred = False

# Playlists Examples
Music = ["PLAYLIST_ID", "Music"]
Random = ["PLAYLIST_ID", "Random"]

# Add all Playlists variables to the allPlaylist Variable to download them properly
allPlaylists = [Music, Random]

part = "snippet"
directory = "playlists"
deletedVideos = 0

def checkForPrivacy(playlistid):
    url = (
            "https://www.googleapis.com/youtube/v3/playlistItems?key="
            + apiKey
            + "&playlistId="
            + playlistid[0]
            + "&part="
            + part
    )

    json = getJSON(url)
    global errorOccurred

    if "error" and 404 in json:
        print(f"The playlist {playlistid[1]} is set to private!")
        print("Please change the setting to at least unlisted!")
        errorOccurred = True
    elif "error" in json:
        print(f"The following problem has occured with this playlist:")
        print(f"{json['error']['code']}")
        print(f"{json['error']['errors'][0]['message']}")
        print(f"{json['error']['errors'][0]['reason']}")
        errorOccurred = True
    else:
        doRequest(playlistid[0])

def doRequest(elListo, pageToken=""):
    url = (
            "https://www.googleapis.com/youtube/v3/playlistItems?key="
            + apiKey
            + "&playlistId="
            + elListo
            + "&part="
            + part
            + "&maxResults=50"
            + "&pageToken="
            + pageToken
    )

    print(url)
    requestJSON = getJSON(url)

    for i in range(50):
        videoData = ""

        try:
            actualTitle = requestJSON["items"][i]["snippet"]["title"]
            actualVideoPostion = requestJSON["items"][i]["snippet"]["position"] + 1
            generalInformation = requestJSON["pageInfo"]["totalResults"]

            if actualTitle == "Deleted video" or actualTitle == "Private video":
                videoData = str(actualVideoPostion) + " - " + actualTitle
                print(videoData)
                file = open(videoData + ".jpg", "wb")
                # file.write(thumbnail.content)
                file.close()
                global deletedVideos
                deletedVideos += 1
                continue

            actualChannelName = requestJSON["items"][i]["snippet"]["videoOwnerChannelTitle"]

            try:
                actualThumbnail = requestJSON["items"][i]["snippet"]["thumbnails"]["maxres"]["url"]
            except:
                actualThumbnail = requestJSON["items"][i]["snippet"]["thumbnails"]["high"]["url"]

            if actualVideoPostion == generalInformation - 1:
                print("All Videos got captured by this script successfully! :)")
                break

            videoData = str(actualVideoPostion) + " - " + actualTitle + " by " + actualChannelName

            try:
                file = open(videoData + ".jpg", "wb")
            except OSError:
                file = open(str(actualVideoPostion) + " - " + slugify(actualTitle) + " by " + actualChannelName + ".jpg", "wb")

            # Create Image
            thumbnail = requests.get(actualThumbnail)
            file.write(thumbnail.content)
            file.close()

            print(videoData)

        except Exception as Error:
            print("A error has occurred! continue with next video ... " + videoData + " this video could have a problem")
            print(Error.with_traceback())
            continue

    try:
        pageToken = requestJSON["nextPageToken"]
        if pageToken != "":
            doRequest(elListo, pageToken)
    except:
        print("Everything is done now!")

def Work():
    os.chdir("playlists")

    for playlist in allPlaylists:
        global deletedVideos
        deletedVideos = 0
        if playlist[1] not in os.listdir(os.getcwd()):
            os.mkdir(playlist[1])
            os.chdir(playlist[1])
            if currentDate not in os.listdir(os.getcwd()):
                os.mkdir(currentDate)
                os.chdir(currentDate)
            else:
                os.chdir(currentDate)
            checkForPrivacy(playlist)
            string = f"0 - the're {deletedVideos} deletedVideos"
            file = open(string, "w")
            file.close()
            os.chdir("../../")
        else:
            os.chdir(playlist[1])
            if currentDate not in os.listdir(os.getcwd()):
                os.mkdir(currentDate)
                os.chdir(currentDate)
            else:
                os.chdir(currentDate)
            checkForPrivacy(playlist)
            string = f"0 - the're {deletedVideos} deletedVideos"
            file = open(string, "w")
            file.close()
            os.chdir("../../")

    finale()

def finale():
    if errorOccurred == False:
        print("Everything went down just fine! :) Congratulations")
    else:
        print("It looks like there was some sort of problem while running this script!")
        print("Please investigate furhter on your own or create your own issue on Github:")
        print("https://github.com/DanielOberlechner/YoutubePlaylistVideoTitle/issues")

Work()


import csv
import random
import math
import operator
from sklearn import preprocessing
from sklearn.model_selection import train_test_split
from sklearn import tree
from sklearn.metrics import confusion_matrix
from sklearn.metrics import accuracy_score
from matplotlib import pyplot as plt

def loadDataset(filename):
    with open(filename) as csvfile:
        lines = csv.reader(csvfile)
        dataset = list(lines)
        #for x in range(len(dataset)-1):
        #    for y in range(19):
        #        dataset[x+1][y+1] = float(dataset[x+1][y+1])
    return dataset

def getUniqueWords(dataset):
    unique_words = list()
    for x in range(len(dataset)):
        for y in range(len(dataset[1])):
            if dataset[x][y] not in unique_words:
                unique_words.append(dataset[x][y])
    return unique_words

dataset = loadDataset("./datasets/car.csv")
unique_words = getUniqueWords(dataset);

le = preprocessing.LabelEncoder()
le.fit(unique_words)
transformedDataset = [le.transform(dataset[i]) for i in range(len(dataset))]
#print(transformedDataset)
#print(unique_words)
#print(len(dataset[1]))
#print(le.transform(dataset[1]) )
#print([x[0:len(dataset[1])-1] for x in dataset])
#print([x[-1] for x in dataset])

X_train, X_test, y_train, y_test = train_test_split([x[0:len(transformedDataset[1])-1] for x in transformedDataset], [x[-1] for x in transformedDataset], test_size=0.2)

#print(len(X_train))
#print(len(X_train[1]))

max_depth = 2
clf = tree.DecisionTreeClassifier(max_depth=max_depth)
clf = clf.fit(X_train, y_train)
y_pred = clf.predict(X_test)

print(confusion_matrix(y_test, y_pred))
print(accuracy_score(y_test, y_pred))

fig = plt.figure(figsize=(25,20))
_ = tree.plot_tree(clf)
fig.savefig('imagename.png')


n=int(input())
def add(a):
    res=0
    for i in a:
        res+=i
    return res
for I in range(n):
    x=input().split()
    l=int(x[0])
    tag=int(x[1])
    a=input().split()
    #print(a)
    #print(tag)
    for i in range(l):
        a[i]=int(a[i])
    res=-1
    f=True
    roo=[]

    for i in range(l-1):
        for j in range(i+1,l):
            tmp=add(a[i:j+1])
            if tmp==tag:
                res=str(i+1)+' '+str(j+1)
                roo.append(res)
                #print(roo)
                f=False
    if len(roo)>0:
        print(roo[0])
    else:print(-1)


import tensorflow as tf

def preprocess_image(image):
    #image = tf.image.decode_image(image, channels=3)
    image = tf.image.decode_jpeg(image,
                                channels=3,
                                try_recover_truncated=True,
                                acceptable_fraction=0.5)
    image_size = tf.shape(image)
    #image = tf.image.resize_images(image, [331, 331])
    #image = tf.image.central_crop(image,0.9)

    def f1(): return tf.image.crop_to_bounding_box(
                        image,
                        0,
                        tf.cast((image_size[1]-image_size[0])/3,tf.int32),
                        image_size[0],
                        image_size[0]+tf.cast((image_size[1]-image_size[0])/4,tf.int32))
    def f2(): return tf.image.crop_to_bounding_box(
                        image,
                         tf.cast((image_size[0]-image_size[1])/3,tf.int32),
                        0,
                        image_size[1]+tf.cast((image_size[0]-image_size[1])/4,tf.int32),
                        image_size[1])

    image = tf.cond(
        image_size[0] > image_size[1],
        true_fn=f2,
        false_fn=f1)

    image = tf.image.resize_images(image, [299, 299],align_corners=True,method=1)

    return image

def augment_image(image):
    image = tf.image.random_flip_left_right(image)
    image = tf.image.random_brightness(
                image,0.125) #0.5247078
    image = tf.image.random_saturation(image,0.5,1.5) #0.3824261 and 1.4029386
    image = tf.image.random_hue(image,0.2) #-0.1267652 and 0.1267652
    image = tf.image.random_contrast(image,0.5,1.5) #0.3493415 and 1.3461331
    return image

def load_and_preprocess_image(path,is_training):
    image = tf.read_file(path)
    image = preprocess_image(image)
    if is_training:
        image = augment_image(image)
    #image /= 255.0  # normalize to [0,1] range
    image = 2*tf.cast(image,tf.float32)/255.0 -1

    return image

def tfdata_generator(all_image_path, labels=None, is_training=False,buffer_size=300,batch_size=32,n_epochs=None,include_filename=False):
    '''Construct a data generator using `tf.Dataset`. '''

    file_name = tf.data.Dataset.from_tensor_slices(all_image_path)
    dataset = file_name.map(lambda x: load_and_preprocess_image(x,is_training))

    if labels is not None:
        label_ds = tf.data.Dataset.from_tensor_slices(tf.cast(labels, tf.int32))
        dataset = tf.data.Dataset.zip((dataset, label_ds))
    if include_filename:
        dataset = tf.data.Dataset.zip((dataset, file_name))
    if is_training:
        dataset = dataset.shuffle(buffer_size)

    dataset = dataset.batch(batch_size)
    dataset = dataset.repeat(count=n_epochs)
    #dataset = dataset.prefetch(tf.contrib.data.AUTOTUNE)
    return dataset