"""
Experimental implementation of Trained Ternary Quantization
"""

import os
# os.environ['CUDA_VISIBLE_DEVICES'] = '0'
import shutil
import pickle
import time
import numpy as np

import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim

from utils.dataset import get_dataloader, get_lmdb_imagenet
from models.ttq_resnet import resnet20_cifar, resnet20_stl
from utils.TTQ import test, measure_net_stats
from utils.train import accuracy
from utils.recorder import Recorder

# from tensorboardX import SummaryWriter

import argparse
def boolean_string(s):
    if s not in {'False', 'True'}:
        raise ValueError('Not a valid boolean string')
    return s == 'True'

parser = argparse.ArgumentParser(description='Approximation Training')
parser.add_argument('--model', '-m', type=str, default='ResNet20', help='Model Arch')
parser.add_argument('--dataset', '-d', type=str, default='CIFAR10', help='Dataset')
parser.add_argument('--optimizer', '-o', type=str, default='Adam', help='Optimizer Method')
parser.add_argument('--exp_spec', '-e', type=str, default='', help='Experiment Specification')
parser.add_argument('--init_lr', '-lr', type=float, default=1e-3, help='Initial Learning rate')
parser.add_argument('--n_epoch', '-n', type=int, default=100, help='Maximum training epochs')
parser.add_argument('--lr_adjust', '-ad', type=str, default='dorefa', help='LR adjusting method')
parser.add_argument('--batch_size', '-bs', type=int, default=128, help='Batch size')
parser.add_argument('--thresh_factor', '-tf', type=float, default=0.05, help='Batch size')
args = parser.parse_args()

# ------------------------------------------
use_cuda = torch.cuda.is_available()
model_name = args.model
dataset_name = args.dataset
MAX_EPOCH = args.n_epoch
optimizer_type = args.optimizer # ['SGD', 'SGD-M', 'adam']
dataset_type = 'large' if dataset_name in ['ImageNet'] else 'small'
lr_adjust = args.lr_adjust
batch_size = args.batch_size
thresh_factor = args.thresh_factor
# ------------------------------------------

print(args)
input('Take a look')

if dataset_name in ['CIFAR10', 'STL10']:
    num_classes = 10
    save_root = '../Results/%s-%s' % (model_name, dataset_name)
elif dataset_name == 'CIFAR100':
    num_classes = 100
    save_root = '../Results/%s-%s' % (model_name, dataset_name)
elif dataset_name == 'ImageNet':
    save_root = '../Results/%s' % model_name
else:
    raise NotImplementedError

###################
# Initial Network #
###################
if model_name == 'ResNet20':
    if dataset_name in ['CIFAR10', 'CIFAR100']:
        net = resnet20_cifar(num_classes=num_classes, thresh_factor=thresh_factor)
    else:
        net = resnet20_stl(num_classes=num_classes, thresh_factor=thresh_factor)
    pretrain_path = '%s/%s-%s-pretrain.pth' % (save_root, model_name, dataset_name)
else:
    raise NotImplementedError

net.load_state_dict(torch.load(pretrain_path), strict=False)

if use_cuda:
    net.cuda()

if optimizer_type == 'SGD-M':
    optimizer = optim.SGD(net.parameters(), lr=args.init_lr, momentum=0.9, weight_decay=5e-4)
elif optimizer_type == 'SGD':
    optimizer = optim.SGD(net.parameters(), lr=args.init_lr)
elif optimizer_type in ['adam', 'Adam']:
    optimizer = optim.Adam(net.parameters(), lr=args.init_lr)
else:
    raise NotImplementedError

################
# Load Dataset #
################
if dataset_name == 'ImageNet':
    try:
        train_loader = get_lmdb_imagenet('train', batch_size)
        test_loader = get_lmdb_imagenet('test', 100)
    except:
        train_loader = get_dataloader(dataset_name, 'train', batch_size)
        test_loader = get_dataloader(dataset_name, 'test', 100)
else:
    train_loader = get_dataloader(dataset_name, 'train', batch_size)
    test_loader = get_dataloader(dataset_name, 'test', 100)

####################
# Initial Recorder #
####################
SummaryPath = '%s/runs-TTQ/TheshFactor-%.3f-Optimizer-%s' \
               %(save_root, thresh_factor, optimizer_type)
if args.exp_spec is not '':
    SummaryPath += ('-' + args.exp_spec)

print('Save to %s' %SummaryPath)

if os.path.exists(SummaryPath):
    print('Record exist, remove')
    input()
    shutil.rmtree(SummaryPath)
    os.makedirs(SummaryPath)
else:
    os.makedirs(SummaryPath)

recorder = Recorder(SummaryPath=SummaryPath, dataset_name=dataset_name)
conv1_pos_file = open('%s/conv1_pos.txt' %SummaryPath, 'w+')
conv1_neg_file = open('%s/conv1_neg.txt' %SummaryPath, 'w+')
conv1_prune_file = open('%s/conv1_prune.txt' %SummaryPath, 'w+')

for epoch in range(MAX_EPOCH):

    if recorder.stop:
        break

    net.train()
    end = time.time()

    recorder.reset_performance()

    for batch_idx, (inputs, targets) in enumerate(train_loader):

        if use_cuda:
            inputs, targets = inputs.cuda(), targets.cuda()

        optimizer.zero_grad()

        outputs = net(inputs)
        losses = nn.CrossEntropyLoss()(outputs, targets)
        losses.backward()

        optimizer.step()

        ####################################
        # Measure the Variation of pos/neg #
        ####################################
        conv1_pos, conv1_neg, conv1_pos_rate, conv1_neg_rate, conv1_prune_rate = measure_net_stats(net.conv1)
        conv1_pos_file.write('%d, %.3f, %.3f\n' %(batch_idx + epoch * len(train_loader), conv1_pos, conv1_pos_rate))
        conv1_neg_file.write('%d, %.3f, %.3f\n' % (batch_idx + epoch * len(train_loader), conv1_neg, conv1_neg_rate))
        conv1_prune_file.write('%d, %.3f\n' %(batch_idx + epoch * len(train_loader), conv1_prune_rate))
        conv1_pos_file.flush()
        conv1_neg_file.flush()
        conv1_prune_file.flush()

        recorder.update(loss=losses.item(), acc=accuracy(outputs.data, targets.data, (1, 5)),
                        batch_size=outputs.shape[0], cur_lr=optimizer.param_groups[0]['lr'], end=end)

        recorder.print_training_result(batch_idx, len(train_loader),
                                       append='pos: %.3f, neg: %.3f, pos rate: %.3f, neg rate: %.3f, prune rate: %.3f'
                                              %(conv1_pos, conv1_neg, conv1_pos_rate, conv1_neg_rate, conv1_prune_rate))
        end = time.time()

    test_acc = test(net, test_loader=test_loader, dataset_name=dataset_name)

    recorder.update(loss=None, acc=test_acc, batch_size=0, end=None, is_train=False)
    # Adjust lr
    recorder.adjust_lr(optimizer=optimizer)

print('Best test acc: %s' %recorder.get_best_test_acc())
recorder.close()
conv1_pos_file.close()
conv1_neg_file.close()
conv1_prune_file.close()


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

import os
import logging
logging.getLogger().setLevel(logging.DEBUG)
from datetime import datetime

from vilya.libs.props import PropsMixin
from vilya.libs.model import BaseModel, ModelField
from vilya.libs.store import cache, store
from vilya.models.consts import PULL_REF_H, PULL_REF_M
from vilya.models.ticket import Ticket, TicketNode
from vilya.models.ngit.repo import PullRepo, ProjectRepo
from vilya.models.project import CodeDoubanProject
from vilya.config import DOMAIN

# mc keys, ('{self.id}', '{self.from_sha}', '{self.to_sha}')
MC_KEY_PULL_MERGE_BASE = 'PullRequest:%s:%s:%s:merge_base'
MC_KEY_PULL_IS_MERGABLE = 'PullRequest:%s:%s:%s:is_auto_mergable'
MC_KEY_PULL_ID_BY_PID_AND_TID = 'PullRequest:%s:%s:pull_id'
MC_KEY_PULL_COMMITS = 'PullRequest:%s:%s:%s:commits'

class PullMixin(object):

    def __init__(self, from_project_id, from_project_ref,
                 to_project_id, to_project_ref):
        self.from_project = from_project_id
        self.from_branch = from_project_ref
        self.to_project = to_project_id
        self.to_branch = to_project_ref
        self.merged = None
        self.ticket = None
        self.ticket_id = None
        self.mixin = True
        self.init_pull()
        self.sync()

    def init_pull(self):
        if self.merged:
            merged = self.merged.split('..')
            self._from_sha = merged[0]
            self._to_sha = merged[1]
        else:
            self._from_sha = None
            self._to_sha = None

    @property
    def repo(self):
        return PullRepo(self)

    @property
    def family_id(self):
        project = self.to_proj
        if project:
            return project.origin_project_id

    @property
    def from_ref(self):
        return self.from_branch

    @property
    def to_ref(self):
        return self.to_branch

    @property
    def same(self):
        return self.from_proj == self.to_proj

    @property
    def to_proj(self):
        return CodeDoubanProject.get(self.to_project)

    @property
    def from_proj(self):
        return CodeDoubanProject.get(self.from_project)

    @property
    def to_proj_str(self):
        return "%s:%s" % (self.to_proj, self.to_branch)

    @property
    def from_proj_str(self):
        return "%s:%s" % (self.from_proj, self.from_branch)

    @property
    def from_sha(self):
        if self._from_sha is None:
            self._from_sha = self.repo.from_sha
        return self._from_sha

    @property
    def to_sha(self):
        if self._to_sha is None:
            self._to_sha = self.repo.to_sha
        return self._to_sha

    @property
    def from_commit(self):
        return self.from_proj.repo.get_commit(self.from_sha)

    @property
    def to_commit(self):
        return self.to_proj.repo.get_commit(self.to_sha)

    @property
    def to_head_ref(self):
        return PULL_REF_H % self.ticket_id

    @property
    def to_merge_ref(self):
        return PULL_REF_M % self.ticket_id

    @property
    def from_head_ref(self):
        if self.from_project == self.to_project:
            return 'refs/heads/%s' % self.from_branch
        return 'refs/remotes/%s/%s' % (self.from_proj.remote_name,
                                       self.from_branch)

    @property
    def from_merge_ref(self):
        return 'refs/heads/%s' % self.to_branch

    @property
    def to_remote_ref(self):
        return "%s/%s" % (self.to_proj.remote_name,
                          self.to_branch)

    @property
    def from_remote_ref(self):
        return "%s/%s" % (self.from_proj.remote_name,
                          self.from_branch)

    def _get_merge_base(self):
        to_sha = self.to_sha
        from_sha = self.from_sha
        # for: from_sha is None
        if to_sha and from_sha:
            merge_base = self.repo.merge_base(to_sha, from_sha)
        else:
            merge_base = None
        merge_base = merge_base.hex if merge_base else to_sha
        return merge_base

    @property
    def merge_base(self):
        return self._get_merge_base()

    def _get_commits(self):
        commits = self.to_proj.repo.get_commits(self.from_sha, self.to_sha)
        return [c for c in commits if c]

    @property
    def commits(self):
        return self._get_commits()

    @property
    def merged_commits(self):
        if not self.merged:
            return []
        return self.commits

    @property
    def can_pull(self):
        from_commit = self.from_proj.repo.get_commit(self.from_ref)
        to_commit = self.to_proj.repo.get_commit(self.to_ref)
        if from_commit and to_commit:
            return True

    def get_diff(self, ref=None, from_ref=None, paths=None, context_lines=3,
                 ignore_space=False, rename_detection=False, linecomments=[],
                 **kw):
        ref = ref or self.from_sha
        from_ref = from_ref or self.merge_base
        return self.repo.get_diff(ref=ref, from_ref=from_ref,
                                  paths=paths,
                                  context_lines=context_lines,
                                  ignore_space=ignore_space,
                                  rename_detection=rename_detection,
                                  linecomments=linecomments,
                                  **kw)

    def update_ref(self):
        ticket = self.ticket
        if not ticket:
            return
        if ticket.closed:
            return
        project = self.to_proj
        project.repo.update_ref(self.to_head_ref,
                                self.from_head_ref)
        project.repo.update_ref(self.to_merge_ref,
                                self.from_merge_ref)

    def update_remote(self):
        if self.from_project == self.to_project:
            return
        from_proj = self.from_proj
        to_proj = self.to_proj
        remotes = to_proj.repo.remotes
        rs = [r['name'] for r in remotes]
        if from_proj.remote_name not in rs:
            to_proj.repo.add_remote(from_proj.remote_name,
                                    from_proj.repo_path)
        to_proj.repo.fetch(from_proj.remote_name)

    def sync(self):
        if self.merged:
            return
        if not self.from_proj:
            return
        assert self.from_proj.origin_project_id == self.family_id
        self.update_remote()
        self.update_ref()

    # TODO
    def insert(self, ticket_id):
        self.ticket_id = ticket_id
        return Pull2.create(from_project=self.from_proj.id,
                            from_branch=self.from_branch,
                            to_project=self.to_proj.id,
                            to_branch=self.to_branch,
                            ticket_id=ticket_id)

    def is_auto_mergable(self):
        return self.repo.can_merge()

    def is_up_to_date(self):
        if self.merged:
            return True
        try:
            commits = self.commits
            has_commits = True if commits else False
        except:
            has_commits = False
        return not has_commits

    def merge(self, operator, commit_message=''):
        message_header = "Merge pull request #%s from %s:%s" % (
            self.ticket_id, self.from_proj, self.from_ref)
        message_body = commit_message
        commit_sha = self.repo.merge(operator, message_header, message_body)
        return commit_sha

    def pull_clone(self, path):
        ref = self.to_ref
        proj = self.to_proj
        proj.repo.clone(path, bare=False, branch=ref, shared=True)
        repo = ProjectRepo.init(os.path.join(path, '.git'), path, bare=False)
        return repo

    def pull_fetch(self, repo):
        if self.from_project == self.to_project:
            ref = self.pull_fetch_local(repo)
        else:
            ref = self.pull_fetch_remote(repo)
        return ref

    def pull_fetch_remote(self, repo):
        # hotfix:
        from_proj = self.from_proj
        repo.add_remote(from_proj.remote_name,
                        from_proj.repo_path)
        repo.fetch_all()
        return self.from_remote_ref

    def pull_fetch_local(self, repo):
        repo.fetch_all()
        ref = 'origin/%s' % self.from_ref
        return ref

    def pull_merge(self, repo, ref, env, msg, commit_message):
        if not commit_message:
            repo.merge(ref, msg, no_ff=True, _env=env)
        else:
            repo.merge(ref, msg, commit_message, no_ff=True, _env=env)
        repo.push('origin', self.to_ref)

class Pull2(BaseModel, PropsMixin, PullMixin):
    __orz_table__ = "pullreq"
    from_project = ModelField(as_key=ModelField.KeyType.DESC)
    from_branch = ModelField(as_key=ModelField.KeyType.DESC)
    to_project = ModelField(as_key=ModelField.KeyType.DESC)
    to_branch = ModelField(as_key=ModelField.KeyType.DESC)
    merged = ModelField(as_key=ModelField.KeyType.DESC)
    ticket_id = ModelField(as_key=ModelField.KeyType.DESC)

    class OrzMeta:
        id2str = True
        cache_ver = "v1"

    def get_uuid(self):
        return '/pull/%s' % self.id

    def after_create(self):
        self.init_pull()
        self.sync()

    @classmethod
    def get(cls, **kwargs):
        r = super(Pull2, cls).get(**kwargs)
        if r:
            r.init_pull()
            r.sync()
        return r

    @property
    @cache(MC_KEY_PULL_MERGE_BASE % ('{self.id}',
                                     '{self.from_sha}',
                                     '{self.to_sha}'))
    def merge_base(self):
        return self._get_merge_base()

    @property
    @cache(MC_KEY_PULL_COMMITS % ('{self.id}',
                                  '{self.from_sha}',
                                  '{self.to_sha}'))
    def commits(self):
        return self._get_commits()

    @property
    def ticket(self):
        if not self.ticket_id:
            return None
        ticket = Ticket.get_by_projectid_and_ticketnumber(self.to_proj.id,
                                                          self.ticket_id)
        return ticket

    @property
    def full_url(self):
        return "%s/%s/pull/%s/" % (DOMAIN,
                                   self.to_proj.name,
                                   self.ticket_id)

    def get_commits_by_status(self, status):
        if status == 'closed':
            return self.merged_commits
        return self.commits

    def get_commits(self):
        return self.commits

    def get_commits_shas(self):
        return [c.sha for c in self.commits]

    def get_format_patch(self):
        text = self.to_proj.repo.get_patch_file(self.from_sha, self.merge_base)
        return text

    def get_diff_tree(self):
        text = self.to_proj.repo.get_diff_file(self.from_sha, self.merge_base)
        return text

    # TODO: cache
    def get_diff_length(self, ref=None, from_ref=None, paths=None):
        ref = ref or self.from_sha
        from_ref = from_ref or self.merge_base
        return self.repo.get_diff_length(ref=ref, from_ref=from_ref,
                                         paths=paths)

    def get_contexts(self, ref, path, line_start, line_end):
        return self.repo.get_contexts(ref, path, line_start, line_end)

    @classmethod
    def get_by_proj_and_ticket(cls, proj_id, tid):
        return cls.get(to_project=proj_id, ticket_id=tid)

    @classmethod
    def get_by_ticket(cls, ticket):
        proj_id = ticket.project_id
        tid = ticket.ticket_id
        return cls.get(to_project=proj_id, ticket_id=tid)

    @classmethod
    def get_by_from_and_to(cls, from_project, from_branch,
                           to_project, to_branch):
        rs = cls.gets(from_project=from_project,
                      from_branch=from_branch,
                      to_project=to_project,
                      to_branch=to_branch)
        return rs

    @classmethod
    # backward compatibility
    def get_max_ticket_id(cls, proj_id):
        rs = store.execute("select max(ticket_id) "
                           "from pullreq where to_project=%s",
                           (proj_id,))
        r = rs and rs[0]
        if r and r[0]:
            return int(r[0])

    @cache(MC_KEY_PULL_IS_MERGABLE % ('{self.id}',
                                      '{self.from_sha}',
                                      '{self.to_sha}'))
    def is_auto_mergable(self):
        return self.repo.can_merge()

    def can_fastforward(self):
        return self.repo.can_fastforward()

    # TODO: remove this
    def remove_branch_if_temp(self):
        if self.from_ref.startswith('patch_tmp'):
            try:
                self.to_proj.repo.delete_branch(self.from_ref)
            except AssertionError as err:
                logging.debug("Unable to remove_temp_branch(%s): %s" % (
                    self.from_ref, err))

    def is_temp_pull(self):
        if self.from_ref.startswith('patch_tmp'):
            return True

    def _save_merged(self, operator, from_sha, to_sha, merge_commit_sha):
        self.merged = "%s..%s" % (from_sha, to_sha)
        self.save()
        merged_time = datetime.now()
        self.merge_by = operator
        self.merge_time = merged_time.strftime('%Y-%m-%d %H:%M:%S')
        # FIXME: pullreq without ticket_id?
        if self.ticket_id:
            ticket = Ticket.get_by_projectid_and_ticketnumber(
                self.to_proj.id, self.ticket_id)
            if ticket:
                # add commits to ticket
                ticket.add_commits(merge_commit_sha, operator)
                TicketNode.add_merge(ticket.id, operator, merged_time)

    def _get_merge_by(self):
        return self.props.get('merge_by')

    def _set_merge_by(self, merge_by):
        self.set_props_item('merge_by', merge_by)

    merge_by = property(_get_merge_by, _set_merge_by)

    def _get_merge_time(self):
        return self.props.get('merge_time')

    def _set_merge_time(self, merge_time):
        self.set_props_item('merge_time', merge_time)

    def _base_repo_as_dict(self):
        # TODO: wrap to project repo
        d = self._repo_as_dict(self.to_proj)
        commit = self.to_commit
        ts = commit.author_timestamp if commit else 0
        d['repo']['pushed_at'] = datetime.fromtimestamp(
            float(ts)).strftime('%Y-%m-%dT%H:%M:%S')
        d['label'] = "%s:%s" % (self.to_proj.name, self.to_ref)
        d['sha'] = commit.sha if commit else None
        d['ref'] = self.to_ref

        return d

    def _head_repo_as_dict(self):
        d = self._repo_as_dict(self.from_proj)
        if not d['repo']:
            return d

        commit = self.from_commit
        if commit:
            ts = commit.author_timestamp if commit else 0
            d['repo']['pushed_at'] = datetime.fromtimestamp(
                float(ts)).strftime('%Y-%m-%dT%H:%M:%S')
            d['label'] = "%s:%s" % (self.from_proj.name, self.from_ref)
            d['sha'] = commit.sha if commit else None
            d['ref'] = self.from_ref

        return d

    def _repo_as_dict(self, proj):
        if not proj:
            return {'repo': {}}

        d = {}
        d['repo'] = {}
        d['repo']['id'] = proj.id
        d['repo']['name'] = proj.name
        d['repo']['clone_url'] = "%s/%s.git" % (DOMAIN, proj.name)
        d['repo']['html_url'] = "%s/%s" % (DOMAIN, proj.name)

        d['repo']['name'] = proj.name
        d['repo']['summary'] = proj.summary
        d['repo'][
            'fork'] = True if proj.fork_from and proj.fork_from > 0 else False
        d['repo']['created_at'] = proj.time.strftime('%Y-%m-%dT%H:%M:%S')
        d['repo']['author'] = {'login': proj.owner_id}

        return d

    def as_dict(self):
        if not (self.ticket_id and self.to_proj):
            return None

        ticket = Ticket.get_by_projectid_and_ticketnumber(
            self.to_proj.id, self.ticket_id)
        if not ticket:
            return None
        d = {}
        d['url'] = "%s/api/%s/pull/%s" % (
            DOMAIN, self.to_proj.name, self.ticket_id)
        d['html_url'] = "%s/%s/pull/%s/" % (
            DOMAIN, self.to_proj.name, self.ticket_id)
        d['number'] = self.ticket_id  # or ticket_id as name is better?
        d['title'] = ticket.title
        d['description'] = ticket.description
        d['merged'] = self.merged and True or False
        d['created_at'] = ticket.time.strftime('%Y-%m-%dT%H:%M:%S')
        if ticket.closed:
            d['closed_at'] = ticket.closed.strftime('%Y-%m-%dT%H:%M:%S')
            d['state'] = 'closed'
        else:
            d['closed_at'] = None
            d['state'] = 'open'

        if d['merged']:
            # No merged time recored, use closed_at instead
            d['merged_at'] = d['closed_at']
        else:
            d['merged_at'] = None

        d['author'] = {}
        d['author']['login'] = ticket.author
        d['ticket_id'] = self.ticket_id
        d['from_proj'] = self.from_proj and self.from_proj.name or ''
        d['to_proj'] = self.to_proj and self.to_proj.name or ''
        d['to_proj_id'] = self.to_proj and self.to_proj.id or -1
        d['creator'] = ticket.author
        d['base'] = self._base_repo_as_dict()
        d['head'] = self._head_repo_as_dict()
        commits = self.get_commits_by_status(d['state'])
        d['commit_id'] = [c.sha for c in commits]

        return d

    merge_time = property(_get_merge_time, _set_merge_time)

    def get_merged_commit_shas(self):
        commits_shas = []
        for ticket_commits in self.ticket.get_commits():
            commits_shas += [str(c) for c in ticket_commits.commits.split(',')]
        commits_shas = [c for c in commits_shas if c]
        return commits_shas

    def get_merged_commits(self):
        commits = []
        repo = self.to_proj.repo
        commits = filter(None, (repo.get_commit(str(c))
                                for c in self.get_merged_commit_shas()))
        commits = sorted(commits, key=lambda x: x.committer_time, reverse=True)
        if self.merged:
            # exclude last merge commit
            return commits[1:]
        else:
            return commits

    def get_delta_commits(self):
        """
        补充pull request创建之后再提交的commits
        """
        saved = self.get_merged_commit_shas()
        nowcommits = self.get_commits_shas()
        delta_commits = [c for c in nowcommits if c not in saved]
        if delta_commits:
            delta_commits = [self.to_proj.repo.get_commit(str(d))
                             for d in delta_commits]
            delta_commits = filter(None, delta_commits)
            return delta_commits
        return []

    @classmethod
    def open(cls, from_project, from_branch, to_project, to_branch):
        return PullMixin(from_project.id,
                         from_branch,
                         to_project.id,
                         to_branch)


import json
import re
from Library.book import Book

# dictionary to convert from written format to integer
RATING_NUMS = {
            "Zero": 0,
            "One": 1,
            "Two": 2,
            "Three": 3,
            "Four": 4,
            "Five": 5,
        }

def helper_filter(number, attr_to_filter_through):
    """
    This function helps to parse filters from the command line.
    :param number: the scraped numeric data to compare to the filter.
    :param attr_to_filter_through: The requested filter by the user.
    :return: False if there is an error, also if the requested filter does not match the scraped data.
    True if everything is all right.
    """
    pattern = r"[0-9.]+"
    num_after_pattern = float(re.findall(pattern, attr_to_filter_through)[0])
    if ">" in attr_to_filter_through:
        if num_after_pattern > number:
            return False
    elif "<" in attr_to_filter_through:
        if num_after_pattern < number:
            return False
    else:
        if num_after_pattern != number:
            return False

    return True

class Filter:

    def __init__(self, num_of_books=1000, genres=None, price_filter="",
                 upc_filter=None, availability_filter=None, rating_filter=str(" "),
                 words_in_title=None, words_in_description=None, num_of_reviews=None):
        """
                Constructs all the neccessary attributes for the scraper object
                :param num_of_books: Number of book that has to be scraped
                :param genres: Genres that has to be scraped
                :param filters: Filter we can use to scrape
                :param words_in_title: Filter to search by words in the title
                :param words_in_description: Search by passed words in description of the book
                """

        self.num_of_books = num_of_books
        self.genres = genres if genres is not None else []
        self.price_filter = price_filter.replace(" ", "")
        self.upc_filter = upc_filter
        self.availability_filter = availability_filter
        self.rating_filter = rating_filter.replace(" ", "")
        self.words_in_title = words_in_title.split() if words_in_title is not None else []  # gotovo
        self.words_in_description = words_in_description if words_in_description is not None else []
        self.num_of_reviews = num_of_reviews

    def __filter_by_upc(self, upc):
        """
        This method fulters by UPC.
        :param upc: the scraped UPC data.
        :return: True if it is a match to the requested UPC, false if not.
        """
        return False if upc not in self.upc_filter else True

    def __search_in_title(self, scraped_title):
        """
        This method searches for books by given titles.
        :param scraped_title: The title of the currently scraped book.
        :return: True if there is a match, False if not.
        """
        words_in_title = self.words_in_title if isinstance(self.words_in_title, unicode)\
            else self.words_in_title[0]
        with open(words_in_title, "r") as user_input:
            valid_titles = json.load(user_input)
            if scraped_title in valid_titles:
                valid_titles.remove(scraped_title)
                return True
            else:
                return False

    def __search_by_words_in_desc(self, scraped_desc):
        """
        This method search by words in given book description.
        :param scraped_desc: Passed book description
        :return: False if some of the words are not in the description, else returns True
        """
        for word in self.words_in_description.split(","):
            if word not in scraped_desc:
                return False

        return True

    def main_filter(self, bs4_book):
        """
        This method is the main filter method. It is dynamically scraping the webpage according to the requested
        filters from the command line.
        :param bs4_book: The parsed HTML data of a book's webpage.
        :return: Book object if the scraped book matches all the requested filters. False if there is a non-matching criteria.
        """
        book = Book()
        if self.price_filter:
            price = float(bs4_book.find("p", class_="price_color").text[2:])
            if not helper_filter(price, self.price_filter): return False
            else: book.price = price
        if self.rating_filter:
            rating = int(RATING_NUMS[bs4_book.find("p", class_="star-rating")["class"][1]])
            if not helper_filter(rating, self.rating_filter): return False
            else: book.rating = rating
        if self.upc_filter:
            upc = bs4_book.find_all("th")[0].find_next().text
            if not self.__filter_by_upc(upc): return False
            else: book.upc = upc
        if self.availability_filter:
            temp = bs4_book.find("p", class_="availability").text.strip()
            num_as_string = re.findall(r"[0-9]+", temp)
            availability = int(num_as_string[0])
            if not helper_filter(availability, self.availability_filter): return False
            else: book.availability = availability
        if self.num_of_reviews:
            num_of_reviews = int(bs4_book.find_all("th")[6].find_next().text)
            if not helper_filter(num_of_reviews, self.num_of_reviews): return False
            else: book.num_of_reviews = num_of_reviews
        if self.words_in_description:
            try:
                description = bs4_book.find("p", class_=None).text.strip().encode('ascii', 'ignore').decode()
            except:
                description = ""
            if not self.__search_by_words_in_desc(description): return False
            else: book.description = description
        if self.words_in_title:
            name = bs4_book.find("h1").text
            if not self.__search_in_title(name): return False
            else: book.name = name

        return book


import streamlit as st
from model_rf import predict_result
from model_svm import predict_result_svm
def predict():
	col1,col2=st.columns(2)
	with col1:
		CodedDay=st.text_input("Coded day")
		Zone=st.text_input("Zone")
	with col2:
		Weather =st.text_input("Weather")
		Temperature=st.text_input("Temp")
	if st.button("Predict from Random Forest"):
		p=predict_result(CodedDay,Zone,Weather,Temperature)
		st.success(str(p))
	if st.button("Predict from SVM"):
		p=predict_result_svm(CodedDay,Zone,Weather,Temperature)
		st.success(str(p))


import models
import ga_config as cfg
import pandas as pd
import matplotlib.pyplot as plt

model = models.Model('dynamic_double_pasternak', True)

params_list = cfg.DYNAMIC_DOUBLE_PASTERNAK_TEST

head = []
value = []
for param in params_list:
    head.append(param[0])
    value.append(param[1])

params = pd.Series(value, index =head)

analytical_data = model.calculate_model(params, 225000)

plt.plot(analytical_data['x_axis'], analytical_data['y_axis'])
plt.title(f"min value: {min(analytical_data['y_axis'])}")
plt.grid()
plt.show()


# -*- coding: utf-8 -*-
from __future__ import absolute_import
from datetime import datetime
import operator

from vilya.libs.store import store, mc, cache, mc_gets, bdb
from vilya.models.tag import Tag, TagName
from vilya.models.issue_vote import Upvote
from vilya.models.issue_participant import IssueParticipant
from vilya.models.issue_comment import IssueComment

MC_KEY_ISSUE = 'issue:v3:%s'
MC_KEY_ISSUES_DATA_BY_TARGET = 'issues_data:v3:type:%s:target_id:%s'
MC_KEY_ISSUES_IDS_BY_CREATOR_ID = 'issue_ids_by_creator_id:v3:%s'
MC_KEY_ISSUES_IDS_BY_ASSIGNEE_ID = 'issues_ids_by_assignee_id:v3:%s'
MC_KEY_USER_ISSUE_IDS_BY_CREATOR_ID = 'user_issue:v3:%s'
BDB_ISSUE_DESCRIPTION_KEY = 'issue_description:%s'
ISSUE_DATA_FIELDS = dict(issue_id=0, closer_id=1, updated_at=2, rank_score=3)

def filter_issue_ids_by_score(ids, order):
    if order == 'hot':
        index = ISSUE_DATA_FIELDS['rank_score']
        ids = [info for info
               in sorted(ids, key=operator.itemgetter(index), reverse=True)]
    else:
        index = ISSUE_DATA_FIELDS['updated_at']
        ids = [info for info
               in sorted(ids, key=operator.itemgetter(index), reverse=True)]
    return ids

def filter_issue_ids_by_state(ids, state):
    index = ISSUE_DATA_FIELDS['closer_id']
    if state:
        if state == 'open':
            ids = [info for info in ids if not info[index]]
        elif state == 'closed':
            ids = [info for info in ids if info[index]]
    return ids

class Issue(object):
    target_type = 'default'
    tag_type = 0  # not exists type
    provided_features = []  # Interface

    def __init__(self, id, title,
                 creator, assignee=None, closer=None,
                 created_at=None, updated_at=None, closed_at=None,
                 type='default', target_id=0):
        self.id = id
        self.issue_id = id
        self.title = title
        bdb_description = bdb.get(BDB_ISSUE_DESCRIPTION_KEY % id)
        self.description = bdb_description
        self.creator_id = creator
        self.assignee_id = assignee
        self.closer_id = closer
        self.created_at = created_at
        self.updated_at = updated_at
        self.closed_at = closed_at
        self.type = type
        self.number = 0
        self.target_id = target_id

    def __repr__(self):
        return '<%s(%s)>' % (self.__class__.__name__, self.id)

    @property
    def url(self):
        raise NotImplementedError('Subclasses should implement this!')

    @property
    def target(self):
        raise NotImplementedError('Subclasses should implement this!')

    def provide(self, name):
        '''检查是否提供某功能，即是否提供某接口'''
        return name in self.provided_features

    @property
    def state(self):
        if self.closer_id:
            return 'closed'

        return 'open'

    @property
    def is_closed(self):
        return self.state == 'closed'

    @property
    def creator(self):
        if self.creator_id:
            from vilya.models.user import User
            return User(self.creator_id)
        return None

    @property
    def closer(self):
        if self.closer_id:
            from vilya.models.user import User
            return User(self.closer_id)
        return None

    @property
    def assignee(self):
        if self.assignee_id:
            from vilya.models.user import User
            return User(self.assignee_id)
        return None

    def clear_cache(self):
        mc.delete(MC_KEY_ISSUE % self.issue_id)

    def update(self, title, description):
        store.execute("update issues "
                      "set title=%s, updated_at=null "
                      "where id=%s", (title, self.issue_id))
        store.commit()
        bdb.set(BDB_ISSUE_DESCRIPTION_KEY % self.issue_id, description)
        self.clear_cache()
        mc.delete(MC_KEY_ISSUES_DATA_BY_TARGET % (self.type, self.target_id))

    def close(self, user_id):
        store.execute("update issues "
                      "set closer_id=%s, closed_at=null "
                      "where id=%s", (user_id, self.issue_id))
        store.commit()
        self.clear_cache()
        mc.delete(MC_KEY_ISSUES_IDS_BY_CREATOR_ID % self.creator_id)
        mc.delete(MC_KEY_ISSUES_DATA_BY_TARGET % (self.type, self.target_id))
        self.closer_id = user_id

    def open(self):
        store.execute("update issues "
                      "set closer_id=null, closed_at=null "
                      "where id=%s", (self.issue_id,))
        store.commit()
        self.clear_cache()
        mc.delete(MC_KEY_ISSUES_IDS_BY_CREATOR_ID % self.creator_id)
        mc.delete(MC_KEY_ISSUES_DATA_BY_TARGET % (self.type, self.target_id))
        self.closer_id = None

    def add_tag(self, tag, type, target_id, author=None):
        author_id = author if author else self.creator_id
        # create tag if not exists
        tag_name = TagName.get_by_name_and_target_id(tag, type, target_id)
        if not tag_name:
            tag_name = TagName.add(tag, author_id, type, target_id)
        if not tag_name:
            return
        # add tag to issue if not already be added
        issue_tag = Tag.get_by_type_id_and_tag_id(
            type, self.issue_id, tag_name.id)
        if issue_tag:
            return
        Tag.add_to_issue(
            tag_name.id, type, self.issue_id, author_id, target_id)

    def add_tags(self, tags, target_id, author=None):
        for tag in tags:
            self.add_tag(tag, self.tag_type, target_id, author)

    def remove_tag(self, tag, type, target_id):
        # check if tag exists
        tag_name = TagName.get_by_name_and_target_id(tag, type, target_id)
        if not tag_name:
            return
        # delete tag relationship if exists
        issue_tag = Tag.get_by_type_id_and_tag_id(
            type, self.issue_id, tag_name.id)
        if issue_tag:
            issue_tag.delete()

    def remove_tags(self, tags, target_id):
        for tag in tags:
            self.remove_tag(tag, self.tag_type, target_id)

    def upvote_by_user(self, user_id):
        if user_id and (user_id != self.creator_id) and not self.is_closed:
            vote = Upvote.add(self.issue_id, user_id)
            if vote:
                self.update_rank_score()
        return self.vote_count

    def cancel_upvote_by_user(self, user_id):
        ok = Upvote.delete(self.issue_id, user_id)
        if ok:
            self.update_rank_score()
        return self.vote_count

    def has_user_voted(self, user_id):
        if user_id:
            vote = Upvote.get_by_issue_id_and_user_id(self.issue_id, user_id)
            return True if vote else False
        return False

    @property
    def vote_count(self):
        return Upvote.count_by_issue_id(self.issue_id)

    @property
    def comments(self):
        return IssueComment.gets_by_issue_id(self.issue_id)

    @property
    def comment_count(self):
        return IssueComment.count_by_issue_id(self.issue_id)

    def add_comment(self, content, user):
        res = IssueComment.add(self.issue_id, content, user)
        self.update_rank_score()
        return res

    def update_rank_score(self):
        vote_count = self.vote_count
        comment_count = self.comment_count
        time_delta = (datetime.now() - datetime(2011, 1, 1)).total_seconds()
        divider = (datetime(2013, 7, 8) - datetime(2011, 1, 1)).total_seconds()
        time_factor = time_delta / divider * 5
        score = (vote_count * 0.5 + comment_count) * time_factor
        store.execute(
            "update issues "
            "set rank_score=%s , updated_at=updated_at "  # 防止字段更新
            "where id=%s ",
            (score, self.issue_id))
        store.commit()
        mc.delete(MC_KEY_ISSUES_DATA_BY_TARGET % (self.type, self.target_id))
        return score

    def add_participants(self, user_ids):
        for user_id in user_ids:
            self.add_participant(user_id)

    def add_participant(self, user_id):
        p = IssueParticipant.get_by_issue_id_and_user_id(self.issue_id,
                                                         user_id)
        if not p:
            IssueParticipant.add(self.issue_id, user_id)

    def delete_participant(self, user_id):
        p = IssueParticipant.get_by_issue_id_and_user_id(self.issue_id,
                                                         user_id)
        if p:
            p.delete()

    def has_participated(self, user_id):
        return bool(IssueParticipant.get_by_issue_id_and_user_id(
            self.issue_id, user_id))

    @property
    def participants(self):
        return IssueParticipant.gets_by_issue_id(self.issue_id)

    def assign(self, user_id):
        old_id = self.assignee_id
        store.execute("update issues "
                      "set assignee_id=%s "
                      "where id=%s", (user_id, self.issue_id))
        store.commit()
        self.clear_cache()
        mc.delete(MC_KEY_ISSUES_IDS_BY_ASSIGNEE_ID % old_id)
        mc.delete(MC_KEY_ISSUES_IDS_BY_ASSIGNEE_ID % user_id)

    @classmethod
    def add(cls, title, description, creator, assignee=None, closer=None,
            created_at=None, updated_at=None, closed_at=None,
            type='default', target_id=0):
        time = datetime.now()
        issue_id = store.execute(
            'insert into issues (title, creator_id, '
            'assignee_id, closer_id, created_at, updated_at, type, target_id) '
            'values (%s, %s, %s, %s, NULL, NULL, %s, %s)',
            (title, creator, assignee, closer, type, target_id))
        store.commit()
        mc.delete(MC_KEY_ISSUE % issue_id)
        mc.delete(MC_KEY_ISSUES_IDS_BY_CREATOR_ID % creator)
        mc.delete(MC_KEY_ISSUES_IDS_BY_ASSIGNEE_ID % assignee)
        mc.delete(MC_KEY_ISSUES_DATA_BY_TARGET % (type, target_id))
        bdb.set(BDB_ISSUE_DESCRIPTION_KEY % issue_id, description)
        issue = cls(issue_id, title, creator, assignee, closer, time, time)
        issue.add_participant(creator)
        return issue

    def delete(self):
        store.execute('delete from issues where id=%s', (self.id,))
        store.commit()
        mc.delete(MC_KEY_ISSUE % self.id)
        mc.delete(MC_KEY_ISSUES_IDS_BY_CREATOR_ID % self.creator_id)
        mc.delete(MC_KEY_ISSUES_IDS_BY_ASSIGNEE_ID % self.assignee_id)
        mc.delete(MC_KEY_ISSUES_DATA_BY_TARGET % (type, self.target_id))
        bdb.set(BDB_ISSUE_DESCRIPTION_KEY % self.id, '')

    @classmethod
    def get(cls, id):
        rs = store.execute(
            "select id, title, creator_id, assignee_id, closer_id, "
            "created_at, updated_at, closed_at, type, target_id "
            "from issues where id=%s", (id,))
        return rs and cls(*rs[0]) or None

    @classmethod
    def get_by_issue_id(cls, id, state=None):
        issue = Issue.get(id)
        if not issue:
            return None

        if state and issue.state != state:
            return None

        return issue

    @classmethod
    @cache(MC_KEY_ISSUES_DATA_BY_TARGET % ('{cls.target_type}', '{target_id}'))
    def get_data_by_target(cls, target_id):
        rs = store.execute('select id, closer_id, updated_at, rank_score '
                           'from issues where type=%s and target_id=%s',
                           (cls.target_type, target_id))
        return rs

    @classmethod
    def gets_by_target(cls, target_id, state=None, order='',
                       limit=0, start=0):
        data = cls.get_data_by_target(target_id)
        data = filter_issue_ids_by_state(data, state)
        data = filter_issue_ids_by_score(data, order)
        ids = [issue_id for (issue_id, _, _, _) in data]
        if limit:
            ids = ids[start:start + limit]
        return Issue.get_cached_issues(ids)

    @classmethod
    def gets_by_creator_id(cls, id, state='open'):
        # FIXME 子类中的这个方法，参数非常不一致。需要尽快解决
        result = cls.get_ids_by_creator_id(id)
        if state == 'open':
            ids = [i for (i, closer_id) in result if not closer_id]
            return Issue.get_cached_issues(ids)
        else:
            ids = [i for (i, closer_id) in result if closer_id]
            return Issue.get_cached_issues(ids)

    @classmethod
    @cache(MC_KEY_ISSUES_IDS_BY_CREATOR_ID % '{id}')
    def get_ids_by_creator_id(cls, id):
        rs = store.execute("select id, closer_id "
                           "from issues "
                           "where creator_id = %s",
                           (id,))
        return rs

    @classmethod
    def gets_by_assignee_id(cls, id, state='open'):
        # FIXME 子类中的这个方法，参数非常不一致。需要尽快解决
        result = cls.get_ids_by_assignee_id(id)
        if state == 'open':
            ids = [i for (i, closer_id) in result if not closer_id]
            return Issue.get_cached_issues(ids)
        else:
            ids = [i for (i, closer_id) in result if closer_id]
            return Issue.get_cached_issues(ids)

    @classmethod
    def gets_by_participated_user(cls, user_id, state='open'):
        ps = IssueParticipant.gets_by_user_id(user_id)
        issue_ids = [p.issue_id for p in ps]
        issues = Issue.get_cached_issues(issue_ids)
        issues_with_state = [issue for issue in issues
                             if (state == 'open') is (not issue.closer_id)]
        return issues_with_state

    @classmethod
    @cache(MC_KEY_ISSUES_IDS_BY_ASSIGNEE_ID % '{id}')
    def get_ids_by_assignee_id(cls, id):
        rs = store.execute("select id, closer_id "
                           "from issues "
                           "where assignee_id = %s",
                           (id,))
        return rs

    @classmethod
    def gets_by_closer_id(cls, id):
        rs = store.execute("select id, title, "
                           "creator_id, assignee_id, closer_id, "
                           "created_at, updated_at, closed_at, type "
                           "from issues "
                           "where closer_id = %s ",
                           (id, ))
        return [cls(*r) for r in rs]

    @property
    def tags(self):
        return Tag.gets_by_issue_id(self.issue_id, self.tag_type)

    @staticmethod
    @cache(MC_KEY_ISSUE)
    def get_cached_issue(id):
        from vilya.models.issue_utils import ISSUE_TYPE_CLASS
        issue = Issue.get(id)
        if issue:
            subcls = ISSUE_TYPE_CLASS[issue.type]
            return subcls.get_by_issue_id(id)

    @staticmethod
    def get_cached_issues(ids):
        issues = mc_gets(MC_KEY_ISSUE, Issue.get_cached_issue, ids)
        return [i for i in issues if i]

def get_project_issues(issues):
    project_issues = []
    for issue in issues:
        project_issue = get_issue_by_id_and_state(issue.issue_id)
        if project_issue:
            project_issues.append(project_issue)
    return project_issues

# return project_issue or team_issue
def get_issue_by_id_and_state(id, state=None):
    issue = Issue.get_cached_issue(id)
    if not issue:
        return None

    if state and issue.state != state:
        return None

    return issue


import numpy as np
from ranker.tfidf_doc_ranker import TfidfDocRanker

class IR:
    def __init__(self, tfidf_path='data/wiki_first_paras-tfidf-ngram=2-hash=16777216-tokenizer=spacy.npz',
                 cased=False):
        self.ranker = TfidfDocRanker(tfidf_path=tfidf_path, cased=cased)
        self.all_titles = self.ranker.doc_dict[0]

    def closest_docs(self, s, k=10):
        '''Input: s: query text, k: num of titles to return in decreasing order or similarity.
           Output: (titles, scores)
        '''
        try:
            return self.ranker.closest_docs(s, k=k)
        except RuntimeError:
            # invalid query: pad and retry
            return self.ranker.closest_docs(s + ' pad', k=k)

    def rank_titles(self, query, titles):
        '''Input: query: text, titles: iterable containing titles to rank
           Output: dict of title:score
        '''
        ranker = self.ranker
        scores = {title: 0 for title in titles}
        try:
            res = ranker.text2spvec(query) * ranker.doc_mat
        except RuntimeError:
            return scores
        relevant_inds = set(res.indices)
        for title in titles:
            idx = ranker.get_doc_index(title)
            if idx in relevant_inds:
                scores[title] = res.data[np.where(res.indices == idx)][0]
        return scores


# This Python 3 environment comes with many helpful analytics libraries installed

# It is defined by the kaggle/python docker image: https://github.com/kaggle/docker-python

# For example, here's several helpful packages to load in

import numpy as np # linear algebra

import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)

# Input data files are available in the "../input/" directory.

# For example, running this (by clicking run or pressing Shift+Enter) will list the files in the input directory

import os

print(os.listdir("../input"))

# Any results you write to the current directory are saved as output.
import numpy as np

import pandas as pd

import matplotlib.pyplot as plt

import seaborn as sns

plt.style.use('seaborn')

sns.set(font_scale=2.5) # 이 두줄은 본 필자가 항상 쓰는 방법입니다. matplotlib 의 기본 scheme 말고 seaborn scheme 을 세팅하고, 일일이 graph 의 font size 를 지정할 필요 없이 seaborn 의 font_scale 을 사용하면 편합니다.

import missingno as msno

#ignore warnings

import warnings

warnings.filterwarnings('ignore')

train = pd.read_csv("../input/2019-1st-ml-month-with-kakr/train.csv")

test = pd.read_csv("../input/2019-1st-ml-month-with-kakr/test.csv")
from IPython.display import Image

Image(url= "https://static1.squarespace.com/static/5006453fe4b09ef2252ba068/t/5090b249e4b047ba54dfd258/1351660113175/TItanic-Survival-Infographic.jpg?format=1500w")
Image(url= "https://upload.wikimedia.org/wikipedia/commons/8/84/Titanic_cutaway_diagram.png")
train.head()
test.head()
train.describe()
test.describe()
train.info()
test.info()
print(train.isnull().sum())

train.isnull().sum() / train.shape[0]
print(test.isnull().sum())

test.isnull().sum() / test.shape[0]
f, ax = plt.subplots(1, 2, figsize=(18, 8))

train['Survived'].value_counts().plot.pie(explode=[0, 0.1], autopct='%1.1f%%', ax=ax[0], shadow=True)

ax[0].set_title('Pie plot - Survived')

ax[0].set_ylabel('')

sns.countplot('Survived', data=train, ax=ax[1])

ax[1].set_title('Count plot - Survived')

plt.show()
pd.crosstab(train['Pclass'], train['Survived'], margins=True).style.background_gradient(cmap='autumn_r')
# Explore Pclass vs Survived

g = sns.factorplot(x="Pclass",y="Survived",data=train,kind="bar", size = 6 ,

palette = "muted")

g.despine(left=True)

g = g.set_ylabels("survival probability")
y_position = 1.02

fig, ax = plt.subplots(1, 2, figsize = (18, 8))

train['Pclass'].value_counts().plot.bar(color = ['#CD7F32','#FFDF00','#D3D3D3'], ax=ax[0])

ax[0].set_title('Number of Passengers By Pclass', y = y_position)

ax[0].set_ylabel('Count')

sns.countplot('Pclass', hue = 'Survived', data = train, ax = ax[1])

ax[1].set_title('Pclass: Survived vs Dead', y = y_position)

plt.show()
pd.crosstab(train['Sex'], train['Survived'], margins=True).style.background_gradient(cmap='summer_r')
train[['Sex', 'Survived']].groupby(['Sex'], as_index=False).mean().sort_values(by='Survived', ascending=False)
fig, ax = plt.subplots(1, 2, figsize = (18, 8))

train[['Sex', 'Survived']].groupby(['Sex'], as_index = True).mean().plot.bar(ax = ax[0])

ax[0].set_title('Survived vs Sex')

sns.countplot('Sex', hue = 'Survived', data = train, ax = ax[1])

ax[1].set_title('Sex: Survived vs Dead')

plt.show()
fig, ax = plt.subplots(1, figsize = (18, 8))

sns.countplot('Pclass', hue = 'Sex', data = train)

ax.set_title('Pclass - Sex')

plt.show()
print('제일 나이 많은 탑승객 : {:.1f} Years'.format(train['Age'].max()))

print('제일 어린 탑승객 : {:.1f} Years'.format(train['Age'].min()))

print('탑승객 평균 나이 : {:.1f} Years'.format(train['Age'].mean()))
pd.crosstab(train['Age'], train['Survived'], margins=True).style.background_gradient(cmap='summer_r')
# Explore Age vs Survived

g = sns.FacetGrid(train, col='Survived')

g = g.map(sns.distplot, "Age")
fig, ax = plt.subplots(1, 1, figsize = (9, 5))

sns.kdeplot(train[train['Survived'] == 1]['Age'], ax = ax)

sns.kdeplot(train[train['Survived'] == 0]['Age'], ax = ax)

plt.legend(['Survived == 1', 'Survived == 0'])

plt.show()
plt.figure(figsize = (8, 6))

train['Age'][train['Pclass'] == 1].plot(kind = 'kde')

train['Age'][train['Pclass'] == 2].plot(kind = 'kde')

train['Age'][train['Pclass'] == 3].plot(kind = 'kde')

plt.xlabel('Age')

plt.title('Age Distribution within classes')

plt.legend(['1st Class', '2nd Class', '3rd Class'])
fig, ax = plt.subplots(1, 2, figsize = (18, 8))

sns.violinplot("Pclass", "Age", hue = "Survived", data = train, scale = 'count', split = True, ax = ax[0])

ax[0].set_title('Pclass and Age vs Survived')

ax[0].set_yticks(range(0, 110, 19))

sns.violinplot("Sex", "Age", hue = "Survived", data = train, scale = 'count', split = True, ax = ax[1])

ax[1].set_title('Sex and Age vs Survived')

ax[1].set_yticks(range(0, 110, 19))

plt.show()
pd.crosstab(train['Embarked'], train['Survived'], margins=True).style.background_gradient(cmap='summer_r')
fig, ax = plt.subplots(1, 1, figsize = (7, 7))

train[['Embarked', 'Survived']].groupby(['Embarked'], as_index = True).mean().sort_values(by = 'Survived', ascending = False).plot.bar(ax = ax)
fig, ax = plt.subplots(2, 2, figsize = (20, 15))

sns.countplot('Embarked', data = train, ax = ax[0, 0])

ax[0, 0].set_title('(1) No. Of passengers Boarded')

sns.countplot('Embarked', hue = 'Sex', data = train, ax = ax[0, 1])

ax[0, 1].set_title('(2) Male-Female Split for Embarked')

sns.countplot('Embarked', hue = 'Survived', data = train, ax = ax[1,0])

ax[1, 0].set_title('(3) Embarked vs Survived')

sns.countplot('Embarked', hue = 'Pclass', data = train, ax = ax[1, 1])

ax[1, 1].set_title('(4) Embarked vs Pclass')

plt.subplots_adjust(wspace = 0.2, hspace = 0.5)

plt.show()
fig, ax = plt.subplots(1, figsize = (18, 8))

sns.violinplot("Embarked", "Age", hue = "Survived", data = train, scale = 'count', split = True)

ax.set_title('Age vs Embarked')

ax.set_yticks(range(0, 110, 19))

plt.show()
pd.crosstab(train['SibSp'], train['Survived'], margins=True).style.background_gradient(cmap='summer_r')
fig, ax = plt.subplots(2, 3, figsize = (40, 20))

sns.countplot('SibSp', data = train, ax = ax[0, 0])

ax[0, 0].set_title('(1) No. Of passengers Boarded', y = 1.02)

sns.countplot('SibSp', hue = 'Survived', data = train, ax = ax[0, 1])

ax[0, 1].set_title('(2) Survived countplot depending on SibSp', y = 1.02)

train[['SibSp', 'Survived']].groupby(['SibSp'], as_index = True).mean().sort_values(by = 'Survived', ascending = False).plot.bar(ax = ax[0, 2])

ax[0, 2].set_title('(3) Survived rate depending on SibSp', y = 1.02)

sns.countplot('SibSp', hue = 'Pclass', data = train, ax = ax[1, 0])

ax[1, 0].set_title('(4) SibSp vs Pclass')

sns.countplot('SibSp', hue = 'Sex', data = train, ax = ax[1, 1])

ax[1, 1].set_title('(2) Male-Female Split for SibSp')

plt.subplots_adjust(wspace = 0.2, hspace = 0.5)

plt.show()
pd.crosstab(train['Parch'], train['Survived'], margins=True).style.background_gradient(cmap='summer_r')
fig, ax = plt.subplots(2, 3, figsize = (40, 20))

sns.countplot('Parch', data = train, ax = ax[0, 0])

ax[0, 0].set_title('(1) No. Of passengers Boarded', y = 1.02)

sns.countplot('Parch', hue = 'Survived', data = train, ax = ax[0, 1])

ax[0, 1].set_title('(2) Survived countplot depending on Parch', y = 1.02)

train[['Parch', 'Survived']].groupby(['Parch'], as_index = True).mean().sort_values(by = 'Survived', ascending = False).plot.bar(ax = ax[0, 2])

ax[0, 2].set_title('(3) Survived rate depending on Parch', y = 1.02)

sns.countplot('Parch', hue = 'Pclass', data = train, ax = ax[1, 0])

ax[1, 0].set_title('(4) Parch vs Pclass')

sns.countplot('Parch', hue = 'Sex', data = train, ax = ax[1, 1])

ax[1, 1].set_title('(2) Male-Female Split for Parch')

plt.subplots_adjust(wspace = 0.2, hspace = 0.5)

plt.show()
train['FamilySize'] = train['SibSp'] + train['Parch'] + 1

test['FamilySize'] = test['SibSp'] + test['Parch'] + 1
pd.crosstab(train['FamilySize'], train['Survived'], margins=True).style.background_gradient(cmap='summer_r')
fig, ax = plt.subplots(2, 3, figsize = (40, 20))

sns.countplot('FamilySize', data = train, ax = ax[0, 0])

ax[0, 0].set_title('(1) No. Of passengers Boarded', y = 1.02)

sns.countplot('FamilySize', hue = 'Survived', data = train, ax = ax[0, 1])

ax[0, 1].set_title('(2) Survived countplot depending on FamilySize', y = 1.02)

train[['FamilySize', 'Survived']].groupby(['FamilySize'], as_index = True).mean().sort_values(by = 'Survived', ascending = False).plot.bar(ax = ax[0, 2])

ax[0, 2].set_title('(3) Survived rate depending on FamilySize', y = 1.02)

sns.countplot('FamilySize', hue = 'Pclass', data = train, ax = ax[1, 0])

ax[1, 0].set_title('(4) FamilySize vs Pclass')

sns.countplot('FamilySize', hue = 'Sex', data = train, ax = ax[1, 1])

ax[1, 1].set_title('(2) Male-Female Split for FamilySize')

plt.subplots_adjust(wspace = 0.2, hspace = 0.5)

plt.show()
fig, ax = plt.subplots(1, 1, figsize=(8, 8))

g = sns.distplot(train['Fare'], color='b', label='Skewness : {:.2f}'.format(train['Fare'].skew()), ax=ax)

g = g.legend(loc='best')
train['Ticket'].value_counts()
train.head()
train['Title']= train.Name.str.extract('([A-Za-z]+)\.') #lets extract the Salutations

test['Title']= test.Name.str.extract('([A-Za-z]+)\.') #lets extract the Salutations
pd.crosstab(train['Title'], train['Sex']).T.style.background_gradient(cmap='summer_r')
train.groupby('Title').mean()
train['Title'].replace(['Mlle','Mme','Ms','Dr','Major','Lady','Countess','Jonkheer','Col','Rev','Capt','Sir','Don', 'Dona'],

                        ['Miss','Miss','Miss','Mr','Mr','Mrs','Mrs','Other','Other','Other','Mr','Mr','Mr', 'Mr'],inplace=True)

test['Title'].replace(['Mlle','Mme','Ms','Dr','Major','Lady','Countess','Jonkheer','Col','Rev','Capt','Sir','Don', 'Dona'],

                        ['Miss','Miss','Miss','Mr','Mr','Mrs','Mrs','Other','Other','Other','Mr','Mr','Mr', 'Mr'],inplace=True)
def Is_Alone(x):

    if x == 1:

        return 0

    else:

        return 1

train['IsAlone'] = train['FamilySize'].apply(Is_Alone)

test['IsAlone'] = test['FamilySize'].apply(Is_Alone)
train['FamilyName']= train.Name.str.extract('([A-Za-z]+)\,') #lets extract the Salutations

test['FamilyName']= test.Name.str.extract('([A-Za-z]+)\,') #lets extract the Salutations
train['FamilyName2']= train.Name.str.extract('([A-Za-z]+)\)') #lets extract the Salutations

test['FamilyName2']= test.Name.str.extract('([A-Za-z]+)\)') #lets extract the Salutations
if train.Ticket.str.extract('(\d+)').size > 1:

    train['Ticket2']= train.Ticket.str.extract(' (\d+)') #lets extract the Salutations

if test.Ticket.str.extract('(\d+)').size > 1:

    test['Ticket2']= test.Ticket.str.extract(' (\d+)') #lets extract the Salutations

train["Ticket2"] = train["Ticket2"].fillna(train["Ticket"])

test["Ticket2"] = test["Ticket2"].fillna(test["Ticket"])
train.head()
EDA_train = pd.read_csv("../input/titanic-eda-last/titanic_EDA_train.csv")

EDA_test = pd.read_csv("../input/titanic-eda-last/titanic_EDA_test.csv")

EDA_all = pd.read_csv("../input/titanic-eda-last/titanic_EDA_all - .csv")
EDA_train.head()
EDA_test.head()
EDA_all.head()
FE_all = pd.concat([train, test])

FE_all.head()

#다시 구분할 때 사용

#df_test = all_df.loc[all_df['price'].isnull()]

#df_train = all_df.loc[all_df['price'].notnull()]
#DataFrame(data, columns=['year', 'state', ‘pop'])

#pd(FE_all, columns=['PassengerId','Survived','Pclass','Name','Sex','Age','SibSp','Parch','Ticket','Fare','Cabin','Embarked','FamilySize','Title','IsAlone','FamilyName','FamilyName2'])

cols = FE_all.columns.tolist()

FE_all = FE_all[['PassengerId','Survived','Pclass','Name','Sex','Age','SibSp','Parch','Ticket','Ticket2','Fare','Cabin','Embarked','FamilySize','Title','IsAlone','FamilyName','FamilyName2']]

FE_all.head()
pd.set_option('display.max_rows', 7000)

#가족이 있는 사람들의 Title별

train[train['IsAlone'] == 1].sort_values(by=['Cabin', 'Ticket2', 'Fare', 'FamilySize']).groupby('Title').mean()
FE_all[(FE_all['Title'] == "Mrs") & (FE_all['SibSp'] == 1) & (FE_all['Parch'] > 1)]
FE_all[(FE_all['Title'] == "Mr") & (FE_all['SibSp'] == 1) & (FE_all['Parch'] > 1)]
FE_all[FE_all['FamilySize'] == 7].sort_values(by=['FamilySize', 'FamilyName','Ticket','Fare','Age'])
#아래 옵션을 통해 데이터 프레임의 전체를 출력하여 볼 수 있다.

#pd.set_option('display.max_rows', 7000)

train[train['FamilySize'] == 2].sort_values(by=['FamilySize', 'FamilyName','Ticket2','Fare','Age'])


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

#import dataset
data = pd.read_csv("auto-mpg.csv")
data['horsepower'] = data['horsepower'].replace('?','100')
data.horsepower.mean()
data.mpg.mean()
data.isnull().sum()

len(data['car name'].value_counts())
data['car name'] = data['car name'].str.split(' ').str.get(0)

data['car name'] = data['car name'].replace(['chevroelt','chevy'],'chevrolet')
data['car name'] = data['car name'].replace(['vokswagen','vw'],'volkswagen')
data['car name'] = data['car name'].replace('maxda','mazda')
data['car name'] = data['car name'].replace('toyouta','toyota')
data['car name'] = data['car name'].replace('mercedes','mercedes-benz')
data['car name'] = data['car name'].replace('nissan','datsun')
data['car name'] = data['car name'].replace('capri','ford')
data['car name'].value_counts()
data['car name'].isnull().sum()

x = data.iloc[:,[1,2,3,4,5,6,7]].values
y = data.iloc[:,0].values

#Categorical Variable

from sklearn.preprocessing import LabelEncoder
lb = LabelEncoder()
x[:,7] = lb.fit_transform(x[:,7])

from sklearn.preprocessing import OneHotEncoder
onehot = OneHotEncoder(categorical_features = [7])
x = onehot.fit_transform(x).toarray()

#Feature scaling
from sklearn.preprocessing import StandardScaler
sc = StandardScaler()
x = sc.fit_transform(x)

#Splitting data set
from sklearn.model_selection import train_test_split
xtrain,xtest,ytrain,ytest = train_test_split(x,y,test_size = 0.2,random_state = 0)

# multiple linear regression
from sklearn.linear_model import LinearRegression
lr = LinearRegression()
lr.fit(xtrain,ytrain)
ypred = lr.predict(xtest)

lr.score(xtrain,ytrain)

from sklearn.metrics import r2_score
print("Accuracy of the linear model is:",r2_score(ytest,ypred)*100)

#Polynomial regression

from sklearn.linear_model import LinearRegression
lr = LinearRegression()
lr.fit(xtrain,ytrain)

#add polynomial features to model
from sklearn.preprocessing import PolynomialFeatures
poly_reg = PolynomialFeatures(degree = 2)
xtrainpoly = poly_reg.fit_transform(xtrain)
xtestpoly = poly_reg.fit_transform(xtest)

poly_reg.fit(xtrainpoly,ytrain)
lr2 = LinearRegression()
lr2.fit(xtrainpoly,ytrain)
ypred_poly = lr2.predict(xtestpoly)

r2_score(ytest,ypred_poly)

#Decision tree Regression
from sklearn.tree import DecisionTreeRegressor
dtr = DecisionTreeRegressor(random_state = 13)
dtr.fit(xtrain,ytrain)

ypred_dtr = dtr.predict(xtest)
r2_score(ytest,ypred_dtr)

#Random forest
from sklearn.ensemble import RandomForestRegressor
rfr = RandomForestRegressor(n_estimators = 10,random_state = 0)
rfr.fit(xtrain,ytrain)

ypred_rfr = rfr.predict(xtest)
r2_score(ytest,ypred_rfr)

#Support Vector Regression
from sklearn.svm import SVR
svr = SVR(kernel = 'rbf')
svr.fit(xtrain,ytrain)

ypred_svr = svr.predict(xtest)
r2_score(ytest,ypred_svr)


from sklearn.preprocessing import StandardScaler
from sklearn.cluster import KMeans
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

data = pd.read_excel('data.xls')
data = (data - data.mean()) / data.std()
data.to_excel('tmp/standard_data.xls', index=False)

# data = StandardScaler().fit_transform(data)
# np.save('tmp/standard_data.np', data)
# np.savetxt('tmp/standard_data.csv', data)
# standard_data = np.load('standard_data.np.npy')

standard_data = pd.read_excel('tmp/standard_data.xls')

kmeans_model = KMeans(n_clusters=5, random_state=123).fit(standard_data)
kmeans_centers = kmeans_model.cluster_centers_
kmeans_labels = kmeans_model.labels_

centers = pd.DataFrame(kmeans_centers, columns=standard_data.columns)
labels = ['L', 'R', 'F', 'M', 'C']
legend = ['客户类别' + str(i + 1) for i in centers.index]
center = pd.concat([centers, centers['L']], axis=1).values

n = len(legend)
angle = np.linspace(0, 2 * np.pi, n, endpoint=False)
angles = np.concatenate((angle, [angle[0]]))

fig = plt.figure(figsize=(8, 6))
ax = fig.add_subplot(111, polar=True)
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

for i in range(n):
    ax.plot(angles, center[i])

ax.set_thetagrids(angle * 180 / np.pi, labels)
plt.title('聚类中心特征图')
plt.legend(legend)
plt.savefig('tmp/image.png')
plt.show()

data['labels'] = kmeans_labels
counts = data.labels.value_counts()
centers['counts'] = counts

writer = pd.ExcelWriter('tmp/cluster_result.xls')
data.to_excel(writer, sheet_name='类标号', index=False)
centers.to_excel(writer, sheet_name='聚类中心')
writer.save()
writer.close()

实验/1、航空公司客户价值分析/code.py


import datetime
import config

DATABASE = config.getDB()

class VirtualCo(Model):
    name = CharField()
    created_at = DateTimeField(default=datetime.datetime.now)

    class Meta:
        database = DATABASE

def initialize():
    DATABASE.connect(reuse_if_open=True)
    DATABASE.create_tables([VirtualCo], safe=True)
    DATABASE.close()


from game_data import data
from art import logo, vs
import random
import os

def clear():
    os.system('cls')

def format_data(account):
    """"Format the account data into printable format."""
    name = account["name"]
    description = account['description']
    country = account['country']
    return f"{name}, a {description}, from {country}"

def check_answer(user_chose, follower_a, follower_b):
    if follower_count > follower_count2 and user_chose == "a":
        return True
    elif follower_count2 > follower_count and user_chose == "b":
        return True
    else:
        return False

score = 0
should_continue = True
against_b = random.choice(data)

while should_continue:
    print(logo)

    compare_a = against_b
    against_b = random.choice(data)

    while compare_a == against_b:
        compare_a = random.choice(data)

    print(compare_a)
    print(f"Compare A: {format_data(compare_a)}")

    print(vs)
    print(against_b)
    print(f"Against B: {format_data(against_b)}")

    user_chose = input("Who has more followers? Type 'A' or 'B': ")

    follower_count = compare_a['follower_count']
    follower_count2 = against_b['follower_count']

    is_correct = check_answer(user_chose, follower_count, follower_count2)

    clear()

    if is_correct:
        score += 1
        print(f"You're right! Current score: {score} ")
    else:
        should_continue = False
        print(f"Wrong, Final score: {score} ")


import sys
import libvirt

conn = libvirt.open('qemu:///system')
if conn == None:
    print('Failed to open connection to qemu:///system')
    exit(1)

domainName = sys.argv[1]
dom = conn.lookupByName(domainName)
if dom == None:
    print('Failed to get the domain object')

ifaces = dom.interfaceAddresses(libvirt.VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_AGENT, 0)

print("The interface IP addresses:")
for (name, val) in ifaces.iteritems():
    if val['addrs']:
        for ipaddr in val['addrs']:
            if ipaddr['type'] == libvirt.VIR_IP_ADDR_TYPE_IPV4:
                print(ipaddr['addr'])
            elif ipaddr['type'] == libvirt.VIR_IP_ADDR_TYPE_IPV6:
                print(ipaddr['addr'])

conn.close()
exit(0)


class Solution:
    def permute(self, nums: List[int]) -> List[List[int]]:
        def gen_permutatons(nums, perm, perms):
            if not nums:
                perms.append(perm[:])
                return

            for i, n in enumerate(nums):
                perm.append(n)
                gen_permutatons(nums[:i] + nums[i+1:], perm, perms)
                perm.pop()
        perms = []
        gen_permutatons(nums, [], perms)
        return perms

### Alternate ###

class Solution:
    def permute(self, nums: List[int]) -> List[List[int]]:
            def backtrack(path):
                if len(path) == n:
                    res.append(path)
                else:
                    for i in range(n):
                        if i not in visited:
                            visited.add(i)
                            backtrack(path + [nums[i]])
                            visited.remove(i)
            res, visited, n = [], set(), len(nums)
            backtrack([])
            return res

### Alternate ###

class Solution:
    def __init__(self):
        self.res=[]

    def permute(self, nums):

        self.backtracking(nums, [])

        return self.res

    def backtracking(self,nums,path):

        if not nums:
            self.res.append(path)
        for n in range(len(nums)):
            self.backtracking(nums[:n]+nums[n+1:],path+[nums[n]])


import asyncio

class ChatServer(asyncio.Protocol):
    def connection_made(self, transport):
        self.peername = transport.get_extra_info('peername')
        print('connection from {}'.format(self.peername))
        self.transport = transport

    def data_received(self, data):
        msg = data.decode()
        #parsing the message
        if msg.startswith("usr:"): #receiving username on connection -> record the new user
            self.username = msg[4:]
            record_new_user(self)
        elif msg.startswith("msg:"): #receiving a message -> echo it to everyone except the author
            broadcast((self.username+': '+msg[4:]), self)
        elif msg == 'x': #receiving exit command -> close connection with the user
            remove_user(self)
            self.transport.close()

users = []

def record_new_user(user):
    users.append(user)
    broadcast(user.username+' has joined!', user, True)

def remove_user(user):
    users.remove(user)
    broadcast(user.username+' has left.', user)

def broadcast(msg, author, to_author=False):
    print(msg)
    for user in users:
        if user is not author:
            user.transport.write(msg.encode())

loop = asyncio.get_event_loop()
chat = loop.create_server(ChatServer, '127.0.0.1', 8888)
server = loop.run_until_complete(chat)
print('serving on {}'.format(server.sockets[0].getsockname()))

try:
    loop.run_forever()
except KeyboardInterrupt:
    print("exit")
finally:
    server.close()
    loop.close()


class Solution:
    def countSegments(self, s: str) -> int:
        myList=[]
        temp=""
        if not s:
            return 0
        listS= list(s)

        for index,char in enumerate(listS):
            if char == " " and temp:
                myList.append(temp[:])
                temp=""
            elif (index == len(listS)-1) and char != " ":
                myList.append(listS[index])

            elif char != " ":
                temp=temp+char
        return len(myList)


# Standard libraries
from typing import Optional

# Code
from sdk.fund.types import CallType, FundTxn, FundTxns
from sdk.chains.bsc.configs import BscConfig
from sdk.chains.bsc.configs.protocols.pancakeswap import PancakeswapPairConfig
from sdk.base.encoders import BaseProtocolEncoder

class PancakeswapLpFarmingUtilEncoder(BaseProtocolEncoder):
    """
    Encoder for the Pancakeswap LP Farming utility contract.
    """

    def __init__(self, config: BscConfig):
        super().__init__(config)

        # For convenience
        self.pancakeswap = config.protocols.pancakeswap
        self.address = config.fund_utils["pancakeswap_lp_farming_util"]

        # Util Contract
        self.contract = self._get_contract_encoder(__file__)

    def lp_farm(
        self,
        token_0: str,
        token_1: str,
        amount_token_0: str,
        amount_token_1: str,
        amount_token_0_min: str,
        amount_token_1_min: str,
        farm_all_balance: bool = False,
    ) -> FundTxns:
        """
        Adds liquidity and deposits the lp tokens received to farm.

        Args:
            token_0: The symbol of the first token of the lp pair.
            token_1: The symbol of the second token of the lp pair.
            amount_token_0: The amount of the first token to add.
            amount_token_1: The amount of the second token to add.
            amount_token_0_min: The minimum amount for the txn to succeed.
            amount_token_1_min: The minimum amount for the txn to succeed.
            farm_all_balance: Whether to farm all of the holding balance.

        Returns:
            The list of encoded fund transactions.
        """
        pair = self.__get_pair_if_exists(token_0, token_1)

        if not pair:
            raise ValueError("Liquidity pool for input pair does not exist")

        # Token 0 is ETH
        if self._is_eth(token_0):
            call_data = self.contract.encode_abi(
                "farmTokenAndETH",
                (
                    self._get_token_address(token_1),
                    amount_token_1,
                    amount_token_0,
                    amount_token_1_min,
                    amount_token_0_min,
                    pair.pid,
                    farm_all_balance,
                ),
            )

            return [FundTxn(CallType.UTIL, self.address, call_data)]

        # Token 1 is ETH
        if self._is_eth(token_1):
            call_data = self.contract.encode_abi(
                "farmTokenAndETH",
                (
                    self._get_token_address(token_0),
                    amount_token_0,
                    amount_token_1,
                    amount_token_0_min,
                    amount_token_1_min,
                    pair.pid,
                    farm_all_balance,
                ),
            )

            return [FundTxn(CallType.UTIL, self.address, call_data)]

        # Both are tokens
        call_data = self.contract.encode_abi(
            "farmTokens",
            (
                self._get_token_address(token_0),
                self._get_token_address(token_1),
                amount_token_0,
                amount_token_1,
                amount_token_0_min,
                amount_token_1_min,
                pair.pid,
                farm_all_balance,
            ),
        )

        return [FundTxn(CallType.UTIL, self.address, call_data)]

    def lp_unfarm(
        self,
        token_0: str,
        token_1: str,
        amount_lp_token: str,
        amount_token_0_min: str,
        amount_token_1_min: str,
    ) -> FundTxns:
        """
        Withdraws the lp tokens from farming and removes liquidity.

        Args:
            token_0: The symbol of the first token of the lp pair.
            token_1: The symbol of the second token of the lp pair.
            amount_lp_token: The amount of the lp tokens to unfarm.
            amount_token_0_min: The minimum amount for the txn to succeed.
            amount_token_1_min: The minimum amount for the txn to succeed.

        Returns:
            The list of encoded fund transactions.
        """
        pair = self.__get_pair_if_exists(token_0, token_1)

        if not pair:
            raise ValueError("Liquidity pool for input pair does not exist")

        # Token 0 is ETH
        if self._is_eth(token_0):
            call_data = self.contract.encode_abi(
                "unfarmTokenAndETH",
                (
                    self._get_token_address(token_1),
                    amount_lp_token,
                    amount_token_1_min,
                    amount_token_0_min,
                    pair.pid,
                ),
            )

            return [FundTxn(CallType.UTIL, self.address, call_data)]

        # Token 1 is ETH
        if self._is_eth(token_1):
            call_data = self.contract.encode_abi(
                "unfarmTokenAndETH",
                (
                    self._get_token_address(token_0),
                    amount_lp_token,
                    amount_token_0_min,
                    amount_token_1_min,
                    pair.pid,
                ),
            )

            return [FundTxn(CallType.UTIL, self.address, call_data)]

        # Both are tokens
        call_data = self.contract.encode_abi(
            "unfarmTokens",
            (
                self._get_token_address(token_0),
                self._get_token_address(token_1),
                amount_lp_token,
                amount_token_0_min,
                amount_token_1_min,
                pair.pid,
            ),
        )

        return [FundTxn(CallType.UTIL, self.address, call_data)]

    # -----------------
    # Private methods
    # -----------------
    def __get_pair_if_exists(
        self, symbol_0: str, symbol_1: str
    ) -> Optional[PancakeswapPairConfig]:
        """
        Returns the pair for two input tokens if they exist.

        Args:
            symbol_0: The symbol of the first token of the pair.
            symbol_1: The symbol of the second token of the pair.

        Returns:
            The address of the pair.
        """
        result: PancakeswapPairConfig
        if self.pancakeswap.pairs.get(f"{symbol_0}-{symbol_1}"):
            result = self.pancakeswap.pairs[f"{symbol_0}-{symbol_1}"]
            return result
        if self.pancakeswap.pairs.get(f"{symbol_1}-{symbol_0}"):
            result = self.pancakeswap.pairs[f"{symbol_1}-{symbol_0}"]
            return result

        return None


from django.urls import path
from projects import views

app_name = "projects"
urlpatterns = [
	path('', views.IndexView.as_view(), name='index'),
	path('resume/', views.ResumeView.as_view(), name='resume'),
	path('contact_me/', views.ContactMeView.as_view(), name='contact_me')
	# path('projects', views.overview, name='overview'),
	# path('projects/<int:pk>/', views.detail, name='detail')
]


import mysql.connector
from mysql.connector import cursor

class coffeedao:
    db=""
    def __init__(self):
        self.db = mysql.connector.connect(
        host="localhost",
        user="root",
        password="",
        database="coffeeexpress"
        )
        #print ("connection made")

    def create(self,coffeeconsumer):
        cursor = self.db.cursor()
        sql="insert into coffeeconsumers (firstname,lastname,postcode) values (%s,%s,%s)"
        values = [
            coffeeconsumer['firstname'],
            coffeeconsumer['lastname'],
            coffeeconsumer['postcode']
        ]
        cursor.execute(sql, values)
        self.db.commit()
        return cursor.lastrowid

        #make a new instance of the class to get the code to run
#coffeedao = coffeedao()

    def getAll(self):
        cursor = self.db.cursor()
        sql="select * from coffeeconsumers"
        cursor.execute(sql)
        results = cursor.fetchall()
        returnArray = []
        #print(results)
        #want results to be in JSON format
        for result in results:
            resultasDict=self.convertToDict(result)
            returnArray.append(resultasDict)

        return returnArray #return an array of dict objects

    def findById(self,id):
        cursor = self.db.cursor()
        sql="select * from coffeeconsumers where id = %s"
        values =[id]
        cursor.execute(sql,values)
        result = cursor.fetchone()
        return self.convertToDict(result)

    def update(self,coffeeconsumer):
        cursor = self.db.cursor()
        sql = " update coffeeconsumers set firstname = %s, lastname = %s,postcode = %s where id = %s"
        values =[
            coffeeconsumer['id'],
            coffeeconsumer['firstname'],
            coffeeconsumer['lastname'],
            coffeeconsumer['postcode']
        ]
        cursor.execute(sql, values)
        self.db.commit()
        return coffeeconsumer

    def delete (self,id):
        cursor = self.db.cursor()
        sql='delete  from coffeeconsumers where id = %s'
        values =[id]
        cursor.execute(sql,values)
        return{}

    #create a function to convert results to dict for later use in html file
    def convertToDict (self,result):
        colnames = ['id','firstname','lastname','postcode']
        coffeeconsumer={} # create a tuple

        if result:
            for i,colName in enumerate(colnames):
                value = result[i]
                coffeeconsumer[colName]=value
            return coffeeconsumer

coffeedao = coffeedao()


# Oytun Demirbilek
# 150150032

import pyautogui
import time
import os
import subprocess

import numpy as np
import cv2
import matplotlib.pyplot as plt
import scipy.stats as st

# You need to set the path to the game in order to open it in the program.
GAMEPATH = "./saturdaynightfilter_pc/SaturdayNightFilter.exe"

# Part1 function.
def sobel_filter():
    shapes = cv2.imread("shapes.png")

    # Define Sobel Operator Filters. Horizontal and vertical masks.
    mask_row = np.array([1, 2, 1])
    y_mask = np.array([-1 * mask_row, np.zeros(3), mask_row])
    x_mask = y_mask.transpose()

    # Image Smoothing before Edge Detection.
    shapes = cv2.blur(shapes, (5, 5))

    # Convolutions implemented with Sobel masks. Horizontal and vertical separately.
    x_edges = cv2.filter2D(shapes, -1, x_mask)
    y_edges = cv2.filter2D(shapes, -1, y_mask)

    # You can compare it with built-in Sobel results.
    # sobelx = cv2.Sobel(shapes,cv2.CV_64F,1,0,ksize=5)
    # sobely = cv2.Sobel(shapes,cv2.CV_64F,0,1,ksize=5)
    # plt.imshow(sobelx)
    # plt.show()
    # plt.close()
    # plt.imshow(sobely)
    # plt.show()
    # plt.close()

    # Save Results.
    plt.imshow(y_edges)
    plt.savefig("sobel_y.png")
    plt.close()

    plt.imshow(x_edges)
    plt.savefig("sobel_x.png")
    plt.close()

# Part3 function.
def generate_gaussian(ksize=7, sigma=5):
    # Utility to generate a gaussian window.
    x = np.linspace(-sigma, sigma, ksize + 1)
    dist = np.diff(st.norm.cdf(x))
    kernel = np.outer(dist, dist)
    return kernel / kernel.sum()

# Part3 function.
def hardcode_corners(image, kernel):
    import math

    # Size of the image and the kernel.
    (i_height, i_width) = image.shape[:2]
    (k_height, k_width) = kernel.shape[:2]

    # Half of the kernel size is the padding size.
    ksize = (k_width - 1) // 2
    # We need to pad the image in order to avoid indexes are not in image.
    image = cv2.copyMakeBorder(image, ksize, ksize, ksize, ksize, cv2.BORDER_REPLICATE)
    # Initialize output matrix. Will be the same size as image.
    output = np.zeros((i_height, i_width), dtype="float32")

    # Sliding window iteration.
    for y in np.arange(ksize, i_height + ksize):
        for x in np.arange(ksize, i_width + ksize):
            # Estimate mean difference between pixels.
            Ix = np.diff(image[y, x - ksize : x + ksize + 1]).mean()
            Iy = np.diff(image[y - ksize : y + ksize + 1, x]).mean()

            # Convolve image derivatives y-wise and x-wise separately.
            roi_x = Ix * kernel
            roi_y = Iy * kernel

            # Construct the image structure tensor.
            b = (roi_x * Iy).sum()
            a = (roi_x * roi_x).sum()
            d = (Iy * Iy).sum()
            # Calculate min eigenvalue and it is the kernel center.
            output[y - ksize, x - ksize] = (
                (a + d) - math.sqrt((a - d) ** 2 + 4 * (b**2))
            ) / 2

    return output

# Part3 function.
def corner_detector(image):

    # Sobel windows.
    mask_row = np.array([1, 2, 1])
    y_mask = np.array([-1 * mask_row, np.zeros(3), mask_row])
    x_mask = y_mask.transpose()

    # Gaussian window.
    gaussian_mask = generate_gaussian()

    # Method 1: Use separate kernels in the built-in convolution function.
    G12 = cv2.sepFilter2D(
        image, -1, kernelX=np.array([-1, 0, 1]), kernelY=np.array([-1, 0, 1])
    )  # Ix.Iy --> This can be problematic.
    G11 = cv2.sepFilter2D(
        image**2, -1, kernelX=np.array([-1, 0, 1]), kernelY=np.array([0, 0, 0])
    )  # Ix^2
    G22 = cv2.sepFilter2D(
        image**2, -1, kernelX=np.array([0, 0, 0]), kernelY=np.array([-1, 0, 1])
    )  # Iy^2

    # Calculate min eigenvalue matrices using filtered structures.
    first = G11 + G22
    second = np.sqrt(np.square(G11 - G22) + 4 * np.square(G12))
    min_eigens = (first - second) / 2
    # max_eigens = (first + second) / 2
    # corners = min_eigens*max_eigens - 0.04*np.square(min_eigens+max_eigens)

    # Method 2: Hardcoded convolution. Note that python iterations much slower and this method will take some time.
    # Everything is implemented with formulas.
    min_eigens = hardcode_corners(image, gaussian_mask)

    np.save("star_corners.npy", min_eigens)

    # In order to highlight corners in the image.
    # If the minimum eigenvalue takes very high values, the point is very much likely to be a corner.
    # image = image // 2
    # image[np.where(min_eigens>10000)] = 255
    return min_eigens

# Part4 function.
def detect(c):
    shape = "A"  # DEFAULT

    # Perimeter of the contour is needed for the approximation algorithm.
    peri = cv2.arcLength(c, True)

    # Contour approximation uses Ramer-Douglas-Peucker algorithm
    # to reduce the number of points in the curve.
    approx = cv2.approxPolyDP(c, 0.04 * peri, True)

    # Assign keyboard presses for each type of result of the approximation.
    if len(approx) < 4:
        shape = "A"  # TRIANGLE
    elif len(approx) == 4:
        shape = "S"  # SQUARE
    elif len(approx) == 6:
        shape = "F"  # HEXAGON
    elif len(approx) > 6:
        shape = "D"  # STAR
    return shape

# Part4 function.
def see_and_respond(ss):
    screensize = pyautogui.size()
    # To grayscale.
    ss = cv2.cvtColor(ss, cv2.COLOR_BGR2GRAY).astype(np.uint8)
    # Getting the frame from the image.
    # Shape fits between x = (1050, 1350)  y = (821, 1080) Tested on 1920 x 1080 resolution.
    # ** These parameters are really tricky, you need to catch the shape in a frame.
    # ** Game results may vary due to the resolution differences.
    slide_y = int(screensize[1] * 0.76) + 1
    slide_x_down = int(screensize[0] * 0.5468) + 1
    slide_x_up = int(screensize[0] * 0.7031) + 1
    frame = ss[slide_y:, slide_x_down:slide_x_up]

    # Get edges and contours.
    edges = cv2.Canny(frame, 400, 500)
    contours, hierarchy = cv2.findContours(
        edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE
    )

    # If no contours are found, there are no shapes in the frame yet.
    if len(contours) == 0:
        return "A"

    # cnts is a coordinate array defining the boundary curve.
    cnts = contours[0]
    if len(cnts.shape) == 3:
        # Since there should be only one shape at a time,
        # Get rid of the 1-sized dimension.
        cnts = cnts.squeeze(1)

    # Contours can be used to detect number of edges of a shape.
    polygon = detect(cnts)
    print("PRESS:", polygon)

    return polygon

# Part4 function.
def play_game():
    game = subprocess.Popen(GAMEPATH)
    screensize = pyautogui.size()
    time.sleep(6)

    # Play Vabank
    pyautogui.click(screensize[0] * 0.9, screensize[1] * 0.25)
    game_end = False
    prev_ss = pyautogui.screenshot()
    time.sleep(1)

    while not game_end:
        ss = pyautogui.screenshot()
        if ss == prev_ss:
            game_end = True
        prev_ss = ss
        key = see_and_respond(np.array(ss))
        pyautogui.press(key)

    pyautogui.press("Esc")

    # Play Shame
    pyautogui.click(screensize[0] * 0.9, screensize[1] * 0.36)
    game_end = False
    prev_ss = pyautogui.screenshot()
    time.sleep(1)

    while not game_end:
        ss = pyautogui.screenshot()
        if ss == prev_ss:
            game_end = True
        prev_ss = ss
        key = see_and_respond(np.array(ss))
        pyautogui.press(key)

    game.terminate()

# Part 1 & 2 function
def get_shapes():
    # Open the game as a subprocess in the program.
    game = subprocess.Popen(GAMEPATH)
    # Screen size will be used to find the button locations
    # Therefore the screen resolution itself will not change things.
    screensize = pyautogui.size()
    time.sleep(5)
    # Click All Shapes
    pyautogui.click(screensize[0] * 0.9, screensize[1] * 0.13)
    # Get screenshot of All Shapes
    ss = pyautogui.screenshot()

    ss.save("shapes.png")
    # Go to the main page from All Shapes.
    pyautogui.click(screensize[0] * 0.9, screensize[1] * 0.9)
    game.terminate()

def part1():
    # Get the All Shapes page screenshot from the game and save.
    get_shapes()
    # Apply sobel filter to saved image from All Shapes page and save the results.
    sobel_filter()

def part2():
    try:
        # If the All Shapes is already saved, read it.
        img = cv2.imread("shapes.png")
    except:
        # If the file does not exist, get the screenshot again.
        get_shapes()
        img = cv2.imread("shapes.png")

    # Canny edge detection.
    edges = cv2.Canny(img, 400, 500)
    plt.imshow(edges, cmap="gray")
    plt.savefig("canny_edges.png")
    plt.close()

def part3():
    try:
        # If the All Shapes is already saved, read it.
        img = cv2.imread("shapes.png")
    except:
        # If the file does not exist, get the screenshot again.
        get_shapes()
        img = cv2.imread("shapes.png")
    img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY).astype(np.float32)
    all_shapes = np.array_split(img, 4, axis=1)
    newimage = corner_detector(all_shapes[2])
    corners = np.load("star_corners.npy")
    # corners = cv2.cornerHarris(all_shapes[2],2,3,0.04)

    plt.imshow(newimage)
    plt.show()

def part4():

    # You can check the methods on all shapes page.
    # Works perfectly when the shape is not moving.

    # all_shapes = cv2.imread('shapes.png')

    ## Changes with resolution. **********************************************************
    # all_shapes = all_shapes[420:700,:]

    # all_shapes = cv2.cvtColor(all_shapes, cv2.COLOR_BGR2GRAY).astype(np.uint8)
    # all_shapes = np.array_split(all_shapes, 4,axis=1)

    # edgelist=[]
    # for shape in all_shapes:
    #    edges = cv2.Canny(shape,400,500)
    #    edgelist.append(edges)
    #    contours, hierarchy = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    #    print(contours[0].shape)
    #    detect(contours[0].squeeze())

    play_game()

part4()


import numpy as np
import scipy.stats
import matplotlib.pyplot as plt
import matplotlib.colors
from sar_data import *

class Gamma(object):
    """
    Test statistic on equality of two Gamma parameters
    Use for change detection between two single channel SAR images X and Y
    n, m are Equivalent Number of Looks (ENL)
    """

    def __init__(self, X, Y, n, m, shape):
        self.X = X
        self.Y = Y
        self.n = n
        self.m = m
        self.shape = shape
        self.Q = Y/X # Test statistic

    def histogram(self, percentile):
        f = plt.figure(figsize=(8, 4))
        ax = f.add_subplot(111)
        ax.hist(self.Q.flatten(), bins=100, normed=True, range=(0,5), color='#3F5D7D')

        ax.spines["top"].set_visible(False)
        ax.spines["right"].set_visible(False)
        ax.get_xaxis().tick_bottom()
        ax.get_yaxis().tick_left()

        ax.set_xlabel('Test statistic')
        ax.set_ylabel('Frequency')

        ax.set_ylim([0, 1.1])

        # Fisher's F overlay
        F = scipy.stats.f(2*self.m, 2*self.n)
        x = np.linspace(0, 5, 500)
        ax.plot(x, F.pdf(x), color='black', linewidth=2)

        # Select threshold from distrib quantile
        t_inf, t_sup = F.ppf(percentile/2), F.ppf(1 - percentile/2)

        return f, ax

    def image_binary(self, percentile):
        F = scipy.stats.f(2*self.m, 2*self.n)
        t_inf, t_sup = F.ppf(percentile/2), F.ppf(1 - percentile/2)

        im = np.zeros_like(self.Q)
        im[self.Q < t_inf] = 1
        im[self.Q > t_sup] = 1

        return im.reshape(self.shape)

    def image_color2(self, percentile):
        """
        Change detection image with two colors indicating the change direction
        Black - Gray - White
        """
        F = scipy.stats.f(2*self.m, 2*self.n)
        t_inf, t_sup = F.ppf(percentile/2), F.ppf(1 - percentile/2)

        im = np.empty_like(self.Q)
        im[:] = 0.5
        im[self.Q < t_inf] = 0
        im[self.Q > t_sup] = 1

        return im.reshape(self.shape)

    def image_color3(self, percentile):
        """
        Change detection image with blue/red indicating the change direction
        """
        F = scipy.stats.f(2*self.m, 2*self.n)
        t_inf, t_sup = F.ppf(percentile/2), F.ppf(1 - percentile/2)

        im = np.empty((self.shape[0], self.shape[1], 3))
        im[:,:] = np.array([0, 0, 0])
        im[self.Q.reshape(self.shape) < t_inf] = np.array([170, 63, 57])
        im[self.Q.reshape(self.shape) > t_sup] = np.array([35, 100, 103])

        return im

    def image_linear(self, percentile):
        pass

def multiENL_gamma(april, may):
    gamma = Gamma(april, may, 13, 13, (1024, 1024))

    f = plt.figure(figsize=(8, 4))
    ax = f.add_subplot(111)
    ax.hist(gamma.Q.flatten(), bins=100, normed=True, range=(0,3), color='#3F5D7D')

    ax.spines["top"].set_visible(False)
    ax.spines["right"].set_visible(False)
    ax.get_xaxis().tick_bottom()
    ax.get_yaxis().tick_left()

    ax.set_xlabel('Test statistic')
    ax.set_ylabel('Frequency')

    ax.set_ylim([0, 1.3])
    ax.set_xticks([0, 1, 2, 3])

    # Fisher's F overlay
    def overlay(ENL, side="right"):
        F = scipy.stats.f(2*ENL, 2*ENL)
        x = np.linspace(0, 3, 500)
        ax.plot(x, F.pdf(x), color='black', linewidth=1)
        mode = (ENL - 1)/(ENL+1)
        xtext = 0.4 if side == "left" else 1.3
        ax.annotate('{}'.format(ENL), xy=(mode, F.pdf(mode)), xytext=(xtext, F.pdf(mode)),
            arrowprops=dict(facecolor='black', shrink=0.05, width=.5, headwidth=2),
            fontsize=11,
            horizontalalignment='right',
            verticalalignment='center'
            )

    # overlay(8)
    overlay(9, "left")
    # overlay(10)
    overlay(11, "left")
    # overlay(12)
    overlay(13, "left")
    # overlay(14)
    overlay(15, "left")
    # overlay(16)
    overlay(17, "left")

    return f, ax

def critical_region():
    "Critical region figure"

    percent = 0.10

    f = plt.figure(figsize=(8, 3))
    ax = f.add_subplot(111)

    ax.spines["top"].set_visible(False)
    ax.spines["right"].set_visible(False)
    ax.get_xaxis().tick_bottom()
    ax.get_yaxis().tick_left()

    ax.set_xlabel('Test statistic')
    ax.set_ylabel('Frequency')

    ax.set_ylim([0, 1.1])

    # Fisher's F pdf
    ENL = 13
    F = scipy.stats.f(2*ENL, 2*ENL)
    x = np.linspace(0, 3, 500)
    y = F.pdf(x)
    ax.plot(x, y, color='black', linewidth=1)

    # Thresholds
    t_inf, t_sup = F.ppf(percent/2), F.ppf(1 - percent/2)
    ax.fill_between(x, y, where=(x < t_sup) == (x > t_inf), color='#3F5D7D')

    ax.set_xticks([t_inf, t_sup])
    ax.set_xticklabels([r"$c_1$", r"$c_2$"], size=16)

    anotx = (ENL - 1)/(ENL+1) + 0.2
    ax.annotate(r'$F(2m, 2n)$', xy=(anotx, F.pdf(anotx)), xytext=(anotx + 0.6, F.pdf(anotx)),
        arrowprops=dict(facecolor='black', shrink=0.05, width=.3, headwidth=5),
        fontsize=16,
        horizontalalignment='right',
        verticalalignment='center'
        )

    ax.text(0.68, 0.5, "No change", color="white", size=16)
    ax.text(0.07, 0.5, "Change", color="black", size=16)
    ax.text(2.0, 0.5, "Change", color="black", size=16)

    ax.axvline(t_inf, color="black", linestyle="--")
    ax.axvline(t_sup, color="black", linestyle="--")

    return f, ax

if __name__ == "__main__":
    print("Gamma test...")

    def gamma_test(april, may, channel, ENL, percent):
        # Data
        X = april.__dict__[channel]
        Y = may.__dict__[channel]
        Xno = april.region(region_nochange).__dict__[channel]
        Yno = may.region(region_nochange).__dict__[channel]

        # Name variables
        short_channel = channel[:2].upper()
        hist_filename = "fig/gamma/gamma.hist.ENL{0}.{1}.{2}.pdf".format(ENL, short_channel, percent)

        # No change region histogram
        gno = Gamma(Xno, Yno, ENL, ENL, april.shape)
        f, ax = gno.histogram(percent)
        f.savefig(hist_filename, bbox_inches='tight')

        ## Images
        g = Gamma(X, Y, ENL, ENL, april.shape)

        # Binary image
        im = g.image_binary(percent)
        im_filename = "fig/gamma/gamma.im.ENL{0}.{1}.{2}.jpg".format(ENL, short_channel, percent)
        plt.imsave(im_filename, im, cmap='gray')

        # Two level image, grayscale
        im = g.image_color2(percent)
        im_filename = "fig/gamma/gamma.color2.ENL{0}.{1}.{2}.jpg".format(ENL, short_channel, percent)
        plt.imsave(im_filename, im, cmap="gray", vmin=0, vmax=1)

        # Two level image, color
        im = g.image_color3(percent)
        im_filename = "fig/gamma/gamma.color3.ENL{0}.{1}.{2}.jpg".format(ENL, short_channel, percent)
        plt.imsave(im_filename, im)

    gamma_test(april, may, "hhhh", 13, 0.10)
    gamma_test(april, may, "hvhv", 13, 0.10)
    gamma_test(april, may, "vvvv", 13, 0.10)

    gamma_test(april, may, "hhhh", 13, 0.05)
    gamma_test(april, may, "hvhv", 13, 0.05)
    gamma_test(april, may, "vvvv", 13, 0.05)

    gamma_test(april, may, "hhhh", 13, 0.01)
    gamma_test(april, may, "hvhv", 13, 0.01)
    gamma_test(april, may, "vvvv", 13, 0.01)

    gamma_test(april, may, "hhhh", 13, 0.001)
    gamma_test(april, may, "hvhv", 13, 0.001)
    gamma_test(april, may, "vvvv", 13, 0.001)

    gamma_test(april, may, "hhhh", 13, 0.0001)
    gamma_test(april, may, "hvhv", 13, 0.0001)
    gamma_test(april, may, "vvvv", 13, 0.0001)

    gamma_test(april, may, "hhhh", 13, 0.00001)
    gamma_test(april, may, "hvhv", 13, 0.00001)
    gamma_test(april, may, "vvvv", 13, 0.00001)

    # At lower ENL than normal
    gamma_test(april, may, "hhhh", 12, 0.01)
    gamma_test(april, may, "hvhv", 12, 0.01)
    gamma_test(april, may, "vvvv", 12, 0.01)

    # MultiENL plots
    f, ax = multiENL_gamma(april.region(region_nochange).hhhh, may.region(region_nochange).hhhh)
    f.savefig("fig/gamma/gamma.multiENL.HH.pdf", bbox_inches='tight')

    f, ax = multiENL_gamma(april.region(region_nochange).hvhv, may.region(region_nochange).hvhv)
    f.savefig("fig/gamma/gamma.multiENL.HV.pdf", bbox_inches='tight')

    f, ax = multiENL_gamma(april.region(region_nochange).vvvv, may.region(region_nochange).vvvv)
    f.savefig("fig/gamma/gamma.multiENL.VV.pdf", bbox_inches='tight')

    f, ax = critical_region()
    f.savefig("fig/gamma/gamma.critical-region.pdf", bbox_inches='tight')