import torch
import torch.nn as nn
from torch.nn import init
import torch.nn.functional as F
import functools

# Normal U-Net

# https://github.com/Mayamayb/MultiClass_UNet/blob/master/UNet.py
def double_conv(in_channels, out_channels):
    return nn.Sequential(
        nn.Conv2d(in_channels, out_channels, 3, padding=1),
        nn.ReLU(inplace=True),
        nn.Conv2d(out_channels, out_channels, 3, padding=1),
        nn.ReLU(inplace=True)
    )

class UNet(nn.Module):

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

        self.dconv_down1 = double_conv(1, 64)
        self.dconv_down2 = double_conv(64, 128)
        self.dconv_down3 = double_conv(128, 256)
        self.dconv_down4 = double_conv(256, 512)

        self.maxpool = nn.MaxPool2d(2)
        self.upsample = nn.Upsample(scale_factor=2, mode='bilinear', align_corners=True)

        self.dconv_up3 = double_conv(256 + 512, 256)
        self.dconv_up2 = double_conv(128 + 256, 128)
        self.dconv_up1 = double_conv(128 + 64, 64)

        self.conv_last = nn.Conv2d(64, n_class, 1)

        # self.softmax = F.softmax

    def forward(self, x):
        conv1 = self.dconv_down1(x)
        x = self.maxpool(conv1)

        conv2 = self.dconv_down2(x)
        x = self.maxpool(conv2)

        conv3 = self.dconv_down3(x)
        x = self.maxpool(conv3)

        x = self.dconv_down4(x)

        x = self.upsample(x)
        x = torch.cat([x, conv3], dim=1)

        x = self.dconv_up3(x)
        x = self.upsample(x)
        x = torch.cat([x, conv2], dim=1)

        x = self.dconv_up2(x)
        x = self.upsample(x)
        x = torch.cat([x, conv1], dim=1)

        x = self.dconv_up1(x)

        out = self.conv_last(x)

        # out = self.softmax(out, dim=1)

        return out

# https://github.com/junyanz/pytorch-CycleGAN-and-pix2pix/blob/master/models/networks.py
"""
    elif netG == 'unet_128':
        net = UnetGenerator(input_nc, output_nc, 7, ngf, norm_layer=norm_layer, use_dropout=use_dropout)
    elif netG == 'unet_256':
        net = UnetGenerator(input_nc, output_nc, 8, ngf, norm_layer=norm_layer, use_dropout=use_dropout)
"""
class UnetGenerator(nn.Module):
    """Create a Unet-based generator"""

    def __init__(self, input_nc, output_nc, num_downs, ngf=64, norm_layer=nn.BatchNorm2d, use_dropout=False):
        """Construct a Unet generator
        Parameters:
            input_nc (int)  -- the number of channels in input images
            output_nc (int) -- the number of channels in output images
            num_downs (int) -- the number of downsamplings in UNet. For example, # if |num_downs| == 7,
                                image of size 128x128 will become of size 1x1 # at the bottleneck
            ngf (int)       -- the number of filters in the last conv layer
            norm_layer      -- normalization layer
        We construct the U-Net from the innermost layer to the outermost layer.
        It is a recursive process.
        """
        super(UnetGenerator, self).__init__()
        # construct unet structure
        unet_block = UnetSkipConnectionBlock(ngf * 8, ngf * 8, input_nc=None, submodule=None, norm_layer=norm_layer, innermost=True)  # add the innermost layer
        for i in range(num_downs - 5):          # add intermediate layers with ngf * 8 filters
            unet_block = UnetSkipConnectionBlock(ngf * 8, ngf * 8, input_nc=None, submodule=unet_block, norm_layer=norm_layer, use_dropout=use_dropout)
        # gradually reduce the number of filters from ngf * 8 to ngf
        unet_block = UnetSkipConnectionBlock(ngf * 4, ngf * 8, input_nc=None, submodule=unet_block, norm_layer=norm_layer)
        unet_block = UnetSkipConnectionBlock(ngf * 2, ngf * 4, input_nc=None, submodule=unet_block, norm_layer=norm_layer)
        unet_block = UnetSkipConnectionBlock(ngf, ngf * 2, input_nc=None, submodule=unet_block, norm_layer=norm_layer)
        self.model = UnetSkipConnectionBlock(output_nc, ngf, input_nc=input_nc, submodule=unet_block, outermost=True, norm_layer=norm_layer)  # add the outermost layer

    def forward(self, input):
        """Standard forward"""
        return self.model(input)

class UnetSkipConnectionBlock(nn.Module):
    """Defines the Unet submodule with skip connection.
        X -------------------identity----------------------
        |-- downsampling -- |submodule| -- upsampling --|
    """

    def __init__(self, outer_nc, inner_nc, input_nc=None,
                 submodule=None, outermost=False, innermost=False, norm_layer=nn.BatchNorm2d, use_dropout=False):
        """Construct a Unet submodule with skip connections.
        Parameters:
            outer_nc (int) -- the number of filters in the outer conv layer
            inner_nc (int) -- the number of filters in the inner conv layer
            input_nc (int) -- the number of channels in input images/features
            submodule (UnetSkipConnectionBlock) -- previously defined submodules
            outermost (bool)    -- if this module is the outermost module
            innermost (bool)    -- if this module is the innermost module
            norm_layer          -- normalization layer
            user_dropout (bool) -- if use dropout layers.
        """
        super(UnetSkipConnectionBlock, self).__init__()
        self.outermost = outermost
        if type(norm_layer) == functools.partial:
            use_bias = norm_layer.func == nn.InstanceNorm2d
        else:
            use_bias = norm_layer == nn.InstanceNorm2d
        if input_nc is None:
            input_nc = outer_nc
        downconv = nn.Conv2d(input_nc, inner_nc, kernel_size=4,
                             stride=2, padding=1, bias=use_bias)
        downrelu = nn.LeakyReLU(0.2, True)
        downnorm = norm_layer(inner_nc)
        uprelu = nn.ReLU(True)
        upnorm = norm_layer(outer_nc)

        if outermost:
            upconv = nn.ConvTranspose2d(inner_nc * 2, outer_nc,
                                        kernel_size=4, stride=2,
                                        padding=1)
            down = [downconv]
            up = [uprelu, upconv, nn.Tanh()]
            model = down + [submodule] + up
        elif innermost:
            upconv = nn.ConvTranspose2d(inner_nc, outer_nc,
                                        kernel_size=4, stride=2,
                                        padding=1, bias=use_bias)
            down = [downrelu, downconv]
            up = [uprelu, upconv, upnorm]
            model = down + up
        else:
            upconv = nn.ConvTranspose2d(inner_nc * 2, outer_nc,
                                        kernel_size=4, stride=2,
                                        padding=1, bias=use_bias)
            down = [downrelu, downconv, downnorm]
            up = [uprelu, upconv, upnorm]

            if use_dropout:
                model = down + [submodule] + up + [nn.Dropout(0.5)]
            else:
                model = down + [submodule] + up

        self.model = nn.Sequential(*model)

    def forward(self, x):
        if self.outermost:
            return self.model(x)
        else:   # add skip connections
            return torch.cat([x, self.model(x)], 1)

#https://github.com/Rainyfish/FASRGAN-and-Fs-SRGAN
class double_conv(nn.Module):
    '''(conv => BN => ReLU) * 2'''

    def __init__(self, in_ch, out_ch):
        super(double_conv, self).__init__()
        self.conv = nn.Sequential(
            nn.Conv2d(in_ch, out_ch, 3, padding=1),
            nn.BatchNorm2d(out_ch,out_ch),
            # nn.GroupNorm(int(out_ch/4),out_ch),
            nn.ReLU(inplace=True),
            nn.Conv2d(out_ch, out_ch, 3, padding=1),
            nn.BatchNorm2d(out_ch),
            # nn.GroupNorm(int(out_ch / 4), out_ch),
            nn.ReLU(inplace=True)
        )

    def forward(self, x):
        x = self.conv(x)
        return x

class inconv(nn.Module):
    def __init__(self, in_ch, out_ch):
        super(inconv, self).__init__()
        self.conv = double_conv(in_ch, out_ch)

    def forward(self, x):
        x = self.conv(x)
        return x

class down(nn.Module):
    def __init__(self, in_ch, out_ch):
        super(down, self).__init__()
        self.mpconv = nn.Sequential(
            nn.MaxPool2d(2),
            double_conv(in_ch, out_ch)
        )

    def forward(self, x):
        x = self.mpconv(x)
        return x

class up(nn.Module):
    def __init__(self, in_ch, out_ch, bilinear=True):
        super(up, self).__init__()

        #  would be a nice idea if the upsampling could be learned too,
        #  but my machine do not have enough memory to handle all those weights
        if bilinear:
            self.up = nn.Upsample(scale_factor=2, mode='bilinear', align_corners=True)
        else:
            self.up = nn.ConvTranspose2d(in_ch // 2, in_ch // 2, 2, stride=2)

        self.conv = double_conv(in_ch, out_ch)

    def forward(self, x1, x2):
        x1 = self.up(x1)

        # input is CHW
        diffY = x2.size()[2] - x1.size()[2]
        diffX = x2.size()[3] - x1.size()[3]

        x1 = F.pad(x1, (diffX // 2, diffX - diffX // 2,
                        diffY // 2, diffY - diffY // 2))

        # for padding issues, see
        # https://github.com/HaiyongJiang/U-Net-Pytorch-Unstructured-Buggy/commit/0e854509c2cea854e247a9c615f175f76fbb2e3a
        # https://github.com/xiaopeng-liao/Pytorch-UNet/commit/8ebac70e633bac59fc22bb5195e513d5832fb3bd

        x = torch.cat([x2, x1], dim=1)
        x = self.conv(x)
        return x

class outconv(nn.Module):
    def __init__(self, in_ch, out_ch):
        super(outconv, self).__init__()
        self.conv = nn.Conv2d(in_ch, out_ch, 1)

    def forward(self, x):
        x = self.conv(x)
        return x

class UNet(nn.Module):
    def __init__(self):
        super(UNet, self).__init__()
        n_channels=64
        n_classes=3
        self.inc = inconv(n_channels, 64)
        self.down1 = down(64, 128)
        self.down2 = down(128, 256)
        self.down3 = down(256, 256)
        # self.down4 = down(512, 512)
        # self.up1 = up(1024, 256)
        self.up2 = up(512, 128)
        self.up3 = up(256, 64)
        self.up4 = up(128, 64)
        self.outc = outconv(64, 3)

        # patch_size = 192 // 8
        patch_size = 128 // 8

        m_classifier = [
            nn.Linear(256 * patch_size ** 2, 1024),
            nn.LeakyReLU(negative_slope=0.2, inplace=True),
            nn.Linear(1024, 1)
        ]

        # self.features = nn.Sequential(*m_features)
        self.classifier = nn.Sequential(*m_classifier)

    def forward(self, x):
        x1 = self.inc(x)
        x2 = self.down1(x1) #128
        x3 = self.down2(x2) #256
        x4 = self.down3(x3) #512
        # features = self.features(x)
        output = self.classifier(x4.view(x4.size(0), -1))
        # x5 = self.down4(x4)
        # x = self.up1(x5, x4)
        x = self.up2(x4, x3)
        x = self.up3(x, x2)
        x = self.up4(x, x1)
        x = self.outc(x)
        return output, x

# PartialConv U-Net


# -*- coding: utf-8 -*-
import json

import scrapy

from ..items import DouyuItem

class DouyuSpider(scrapy.Spider):
    name = 'douyu'
    allowed_domains = ['douyucdn.cn']
    baseurl = 'http://capi.douyucdn.cn/api/v1/getVerticalRoom?limit=20&offset='
    offset = 0

    start_urls = [baseurl + str(offset)]

    def parse(self, response):
        # r_list存放所有主播信息,每个主播为一个字典
        r_list = json.loads(response.text)['data']
        if len(r_list) == 0:
            return

        for r in r_list:
            item = DouyuItem()
            item['link'] = r['vertical_src']
            item['name'] = r['nickname']
            item['house'] = r['room_id']
            item['city'] = r['anchor_city']

            yield item

        self.offset += 20
        yield scrapy.Request(self.baseurl + str(self.offset), callback=self.parse, dont_filter=True)


#! /usr/bin/env python
# -*- coding: utf-8 -*-
"""
SeisHub database client for ObsPy.

The obspy.seishub package contains a client for the seismological database
SeisHub (http://www.seishub.org).

ObsPy is an open-source project dedicated to provide a Python framework for
processing seismological data. It provides parsers for common file formats and
seismological signal processing routines which allow the manipulation of
seismological time series (see Beyreuther et al. 2010, Megies et al. 2011).
The goal of the ObsPy project is to facilitate rapid application development
for seismology.

For more information visit http://www.obspy.org.

:copyright:
    The ObsPy Development Team (devs@obspy.org)
:license:
    GNU Lesser General Public License, Version 3
    (http://www.gnu.org/copyleft/lesser.html)
"""

from setuptools import find_packages, setup
import os
import shutil
import sys

LOCAL_PATH = os.path.abspath(os.path.dirname(__file__))
DOCSTRING = __doc__.split("\n")

# package specific settings
NAME = 'obspy.seishub'
AUTHOR = 'The ObsPy Development Team'
AUTHOR_EMAIL = 'devs@obspy.org'
LICENSE = 'GNU Lesser General Public License, Version 3 (LGPLv3)'
KEYWORDS = ['ObsPy', 'seismology', 'SeisHub']
INSTALL_REQUIRES = ['obspy.core', 'obspy.mseed', 'lxml', 'obspy.xseed']
ENTRY_POINTS = {}

def convert2to3():
    """
    Convert source to Python 3.x syntax using lib2to3.
    """
    # create a new 2to3 directory for converted source files
    dst_path = os.path.join(LOCAL_PATH, '2to3')
    shutil.rmtree(dst_path, ignore_errors=True)

    # copy original tree into 2to3 folder ignoring some unneeded files
    def ignored_files(_adir, filenames):
        return ['.svn', '2to3', 'debian', 'build', 'dist'] + \
               [fn for fn in filenames if fn.startswith('distribute')] + \
               [fn for fn in filenames if fn.endswith('.egg-info')]
    shutil.copytree(LOCAL_PATH, dst_path, ignore=ignored_files)
    os.chdir(dst_path)
    sys.path.insert(0, dst_path)
    # run lib2to3 script on duplicated source
    from lib2to3.main import main
    print("Converting to Python3 via lib2to3...")
    main("lib2to3.fixes", ["-w", "-n", "--no-diffs", "obspy"])

def getVersion():
    # fetch version
    file = os.path.join(LOCAL_PATH, 'obspy', NAME.split('.')[1], 'VERSION.txt')
    return open(file).read()

def setupPackage():
    # use lib2to3 for Python 3.x
    if sys.version_info[0] == 3:
        convert2to3()
    # setup package
    setup(
        name=NAME,
        version=getVersion(),
        description=DOCSTRING[1],
        long_description="\n".join(DOCSTRING[3:]),
        url="http://www.obspy.org",
        author=AUTHOR,
        author_email=AUTHOR_EMAIL,
        license=LICENSE,
        platforms='OS Independent',
        classifiers=[
            'Development Status :: 4 - Beta',
            'Environment :: Console',
            'Intended Audience :: Science/Research',
            'Intended Audience :: Developers',
            'License :: OSI Approved :: GNU Library or ' + \
                'Lesser General Public License (LGPL)',
            'Operating System :: OS Independent',
            'Programming Language :: Python',
            'Topic :: Scientific/Engineering',
            'Topic :: Scientific/Engineering :: Physics'],
        keywords=KEYWORDS,
        packages=find_packages(exclude=['distribute_setup']),
        namespace_packages=['obspy'],
        zip_safe=False,
        install_requires=INSTALL_REQUIRES,
        download_url="https://svn.obspy.org/trunk/%s#egg=%s-dev" % (NAME,
                                                                    NAME),
        include_package_data=True,
        test_suite="%s.tests.suite" % (NAME),
        entry_points=ENTRY_POINTS,
    )
    # cleanup after using lib2to3 for Python 3.x
    if sys.version_info[0] == 3:
        os.chdir(LOCAL_PATH)

if __name__ == '__main__':
    setupPackage()


# import required libraries
from vidgear.gears import VideoGear
import cv2
import socket

options = {"hflip": True, "exposure_mode": "auto", "iso": 800, "exposure_compensation": 15, "awb_mode": "horizon", "sensor_mode": 0}

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(("192.168.1.5", 55556))
stream = VideoGear(resolution=(128, 128), framerate=60, logging = True, **options).start()

while True:

    frame = stream.read()
    if frame is None:
        break

    byte_image = bytearray(frame)
    print(len(byte_image))
    with open('opencv.jpg','rb') as image:
        f = image.read()
        byte_image = bytearray(f)
    sock.send(byte_image)
    # {do something with the frame here}

    cv2.imshow("Output Frame", frame)

    # check for 'q' key if pressed
    key = cv2.waitKey(1) & 0xFF
    if key == ord("q"):
        sock.close()
        break

# close output window
cv2.destroyAllWindows()

# safely close video stream
stream.stop()


# Copyright 2021 Hang-Chi Shen. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ==============================================================================

import numpy as np
import tensorflow as tf
from scipy import fft
from .block2channel import Block2Channel2d
from .block2channel import Block2Channel3d
from .block2channel import block2channel_2d
from .block2channel import block2channel_3d

def channel2fft(np_array, block_shape, check_shape=True):
    """
    Convert 2d or 3d numpy array to 3d, then do fft op at last dimension.
    :param np_array: 2d or 3d array
    :param block_shape: (block_h, block_w) example (2, 2),
    block shape should <= input tensor shape
    :param check_shape: check shape while run block2channel_2d(...) or block2channel_3d(...)
    :return: 3d numpy array, the same like output of block2channel_2d(...) or block2channel_3d(...)
    """
    if len(np_array.shape) == 2:
        out = block2channel_2d(np_array, block_shape, False, check_shape)

    elif len(np_array.shape) == 3:
        out = block2channel_3d(np_array, block_shape, False, check_shape)

    else:
        print("shape {} not support, recommend [h, w] or [h, w, channel]".format(np_array.shape))
        raise NotImplementedError
    # todo: fix bugs here
    return fft.rfft(out.astype(np.float32))

class RFFTLayer2d(tf.keras.layers.Layer):
    """
    Convert tf tensor with batch(like [batch, h, w]) to [h//block_H, w//block_w, block_h*block_w]
    then do DCT op at last dimension.
    :param block_shape: (block_h, block_w) example (2, 2),
    block shape should <= input tensor shape
    :param check_shape: check shape while run block2channel_2d(...)
    :return: [batch, h//block_H, w//block_w, block_h*block_w]
    """

    def __init__(self, block_shape, groups=None, dct_type=2, check_shape=True, **kwargs):
        super(RFFTLayer2d, self).__init__(**kwargs)
        self.block_shape = block_shape
        self.groups = groups
        self.dct_type = dct_type
        self.check_shape = check_shape
        self.block2Channel2d = None

    def build(self, input_shape):
        self.block2Channel2d = Block2Channel2d(self.block_shape, False, self.check_shape)

    def call(self, inputs, **kwargs):
        # [batch, h, w] ==>> [batch, h//block_H, w//block_w, block_h*block_w]
        out = self.block2Channel2d(inputs)
        if self.groups:
            print("NotImplemented!")
            raise NotImplemented
        else:
            return tf.cast(tf.signal.rfft(tf.cast(out, dtype=tf.float32)), dtype=tf.float32)

class RFFTLayer3d(tf.keras.layers.Layer):
    """
    Convert tf tensor with batch [batch, h, w, channel] to [batch, h//block_H, w//block_w, channel*block_h*block_w],
    then do rfft op at last dimension.
    :param block_shape: (block_h, block_w) example (2, 2),
    block shape should <= input tensor shape
    :param dct_type: default 2, example tf.signal.dct(tensor, type=dct_type)
    :param check_shape: check shape while run block2channel_3d(...)
    :return: [batch, h//block_H, w//block_w, channel*block_h*block_w]
    """

    def __init__(self, block_shape, groups=None, data_type=tf.float32, check_shape=True, **kwargs):
        super(RFFTLayer3d, self).__init__(**kwargs)
        self.block_shape = block_shape
        self.groups = groups
        self.data_type = data_type
        self.check_shape = check_shape
        self.block2Channel3d = None

    def build(self, input_shape):
        self.block2Channel3d = Block2Channel3d(self.block_shape, False, self.check_shape)

    def call(self, inputs, **kwargs):
        # [batch, h, w, channel] ==>> [batch, h//block_H, w//block_w, channel*block_h*block_w]
        out = self.block2Channel3d(inputs)
        if self.groups:
            print("NotImplemented!")
            raise NotImplemented

        else:
            return tf.cast(tf.signal.rfft(tf.cast(out, dtype=tf.float32)), dtype=self.data_type)


def isvalid(text):
    pairsopen = {'(':')', '[':']','{':'}'}
    pairsclose = {')':'(', ']':'[','}':'{'}
    match = {'(':0, '[':0,'{':0}
    for i in text:
        if i in pairsopen.keys():
            match[i] += 1
        elif i in pairsclose.keys():
            if match[pairsclose[i]] > 0:
                match[pairsclose[i]] -= 1
            else:
                return False #parantez açılmadan kapanmış
        else:
            return False #geçersiz karakter
    return True if sum(match.values()) == 0 else False

def checkform(text):
    pairs = {')':'(', ']':'[','}':'{'}
    que = []
    for i in text:
        if i in pairs.values():
            que.append(i)
        elif i in pairs.keys():
            if que[-1] == pairs[i]:
                que.pop(-1)
            else:
                return False #parantez açılmadan kapanmış
        else:
            return False #geçersiz karakter
    return False if que else True #que de eleman varsa False

def is_wellformed(data):
    lst = [i for i in ["()","{}","[]"] if i in data]
    while lst:
        for i in lst:
            data = data.replace(i,"")
        lst = [i for i in ["()","{}","[]"] if i in data]
    return not bool(data)

def checkform1(text):
    pairs = {')':'(', ']':'[','}':'{'}
    que = []
    for i in text:
        if i in pairs.values():
            que.append(i)
        elif (i in pairs.keys()) and que and (que[-1] == pairs[i]):
            que.pop(-1)
        else:
            return False
    return False if que else True

def checkform3(text):
    lst = [i for i in ["()","{}","[]"] if i in text]
    while lst:
        for i in lst:
            text = text.replace(i,"")
        lst = [i for i in ["()","{}","[]"] if i in text]
    return not bool(text)

from collections import deque
def checkform4(s):
    pairs = {')':'(', ']':'[','}':'{'}
    que = deque()
    for i in s:
        if (i in pairs.keys()) and que and (que[-1] == pairs[i]):
            que.pop()
        else:
            que.append(i)
    return len(que) == 0

s = ["([)]", "([])", "((()[]{()})())"]

for i in s:
    print(i, is_wellformed(i))
    print(i, checkform4(i))


import cv2
import numpy as np
def ContrastEnhancement(image):
    #### it work very well

    image=np.array(image,np.uint8)
    lab = cv2.cvtColor(image, cv2.COLOR_BGR2LAB)
    # cv2.imshow("lab", lab)
    # cv2.waitKey(0)

    # -----Splitting the LAB image to different channels-------------------------
    l, a, b = cv2.split(lab)

    # -----Applying CLAHE to L-channel-------------------------------------------
    clahe = cv2.createCLAHE(clipLimit=3.0, tileGridSize=(6, 6))
    cl = clahe.apply(l)

    # -----Merge the CLAHE enhanced L-channel with the a and b channel-----------
    limg = cv2.merge((cl, a, b))

    # -----Converting image from LAB Color model to RGB model--------------------
    final = cv2.cvtColor(limg, cv2.COLOR_LAB2BGR)
#    final=np.array(final/255.0,np.float32)
#     cv2.imshow("lab", final)
#     cv2.waitKey(0)
    return final


import numpy as np
import pandas as pd
from sklearn.preprocessing import LabelEncoder
from sklearn.preprocessing import MinMaxScaler
from sklearn.model_selection import train_test_split
import collections
import time

def preprocess():

    path = 'D:/'
    file_name = 'data.csv'

    start = time.time()

    # load data
    data = pd.read_csv(path + file_name)

    # drop rows with negative 'Order_Qty' value
    data = data[data.Order_Qty >= 0]

    # extract 'Order_Qty' column to be used as labels
    y = data['Order_Qty'].values
    # replace all non-zero values with one
    y[y > 0] = 1
    # drop 'Order_Qty' column
    data.drop('Order_Qty', axis=1, inplace=True)
    # total number of valid data sets
    data_size = len(y)
    dict_order_qty = dict(collections.Counter(y))
    keys_order_qty = list(dict_order_qty.keys())

    # extract 'Country' column
    countries = data['Country'].values
    # compute frequency of each country
    dict_country = dict(collections.Counter(countries))
    keys_country = list(dict_country.keys())
    top_3_countries = collections.Counter(countries).most_common(3)
    # print(top_3_countries)
    for i in range(0, len(countries)):
        country = countries[i]
        if country != 'US' and country != 'SA' and country != 'QA':
            countries[i] = 'other'
    # one-hot encode 'Country'
    le_country = LabelEncoder()
    labels_country = le_country.fit_transform(countries)
    country_b = np.zeros((len(countries), 4), dtype=int)
    country_b[np.arange(len(countries), dtype=int), labels_country] = 1
    # print(country_b)

    # extract 'Coverage' column
    coverage = data['Coverage'].values
    dict_coverage = dict(collections.Counter(coverage))
    keys_coverage = list(dict_coverage.keys())
    # one-hot encode 'Coverage'
    le_coverage = LabelEncoder()
    labels_coverage = le_coverage.fit_transform(coverage)
    coverage_b = np.zeros((len(coverage), 2), dtype=int)
    coverage_b[np.arange(len(coverage), dtype=int), labels_coverage] = 1
    # print(coverage_b)

    # extract 'SKU' column
    skus = [str(i) for i in data['SKU'].values]
    # compute frequency of each SKU
    dict_sku = dict(collections.Counter(skus))
    keys_sku = list(dict_sku.keys())
    top_5_skus = collections.Counter(skus).most_common(5)
    # print(top_5_skus)
    for i in range(0, len(skus)):
        sku = skus[i]
        if sku != '10070735' and sku != '10019577' and sku != '10108817' and sku != '10106342' and sku != '10064539':
            skus[i] = 'other'
    # one-hot encode 'SKU'
    le_sku = LabelEncoder()
    labels_sku = le_sku.fit_transform(skus)
    sku_b = np.zeros((len(skus), 6), dtype=int)
    sku_b[np.arange(len(skus), dtype=int), labels_sku] = 1
    # print(sku_b)

    # extract 'SKU_Category' column
    sku_categories = [str(i) for i in data['SKU_Category'].values]
    # compute frequency of each SKU category
    dict_sku_category = dict(collections.Counter(sku_categories))
    keys_sku_category = list(dict_sku_category.keys())
    top_5_sku_categories = collections.Counter(sku_categories).most_common(5)
    # print(top_5_sku_categories)
    for i in range(0, len(sku_categories)):
        sku_category = sku_categories[i]
        if sku_category != '33346' and sku_category != '10322' and sku_category != '14345' and sku_category != '10321' and sku_category != '14382':
            sku_categories[i] = 'other'
    # one-hot encode 'SKU_Category'
    le_sku_category = LabelEncoder()
    labels_sku_category = le_sku_category.fit_transform(sku_categories)
    sku_category_b = np.zeros((len(sku_categories), 6), dtype=int)
    sku_category_b[np.arange(len(sku_categories), dtype=int), labels_sku_category] = 1
    # print(sku_category_b)

    # extract 'EB_Flag' column
    eb_flag = data['EB_Flag'].values
    # compute frequency of each EB_Flag
    dict_eb_flag = dict(collections.Counter(eb_flag))
    keys_eb_flag = list(dict_eb_flag.keys())
    # one-hot encode 'EB_Flag'
    le_eb_flag = LabelEncoder()
    labels_eb_flag = le_eb_flag.fit_transform(eb_flag)
    eb_flag_b = np.zeros((len(eb_flag), 2), dtype=int)
    eb_flag_b[np.arange(len(eb_flag), dtype=int), labels_eb_flag] = 1
    # print(eb_flag_b)

    # extract 'RFQ_TYPE' column
    rfq_type = [str(i) for i in data['RFQ_TYPE'].values]
    # compute frequency of each RFQ_TYPE
    dict_rfq_type = dict(collections.Counter(rfq_type))
    keys_rfq_type = list(dict_rfq_type.keys())
    # One-hot encode RFQ_Type
    le_rfq_type = LabelEncoder()
    labels_rfq_type = le_rfq_type.fit_transform(rfq_type)
    rfq_type_b = np.zeros((len(rfq_type), 9), dtype=int)
    rfq_type_b[np.arange(len(rfq_type), dtype=int), labels_rfq_type] = 1

    # extract 'List_Price' column
    list_price = data['List_Price'].values
    # scale data to the [0, 1] range
    min_max_scaler = MinMaxScaler()
    list_price_n = np.array(min_max_scaler.fit_transform(np.array(list_price).reshape(-1, 1)))

    # extract 'RFQ_Price' column
    rfq_price = data['RFQ_Price'].values
    # scale data to the [0, 1] range
    min_max_scaler = MinMaxScaler()
    rfq_price_n = np.array(min_max_scaler.fit_transform(np.array(rfq_price).reshape(-1, 1)))
    # print(rfq_price_n)

    # extract 'List_Price*RFQ_Qty' column
    list_price_x_rfq_qty = data['List_Price*RFQ_Qty'].values
    # scale data to the [0, 1] range
    min_max_scaler = MinMaxScaler()
    list_price_x_rfq_qty_n = np.array(min_max_scaler.fit_transform(np.array(list_price_x_rfq_qty).reshape(-1, 1)))
    # print(list_price_x_rfq_qty_n)

    # extract 'RFQ_Price*Order_Qty' column
    rfq_price_x_order_qty = data['RFQ_Price*Order_Qty'].values
    # scale data to the [0, 1] range
    min_max_scaler = MinMaxScaler()
    rfq_price_x_order_qty_n = np.array(min_max_scaler.fit_transform(np.array(rfq_price_x_order_qty).reshape(-1, 1)))
    # print(rfq_price_x_order_qty_n)

    country_b = np.array(country_b)
    coverage_b = np.array(coverage_b)
    sku_b = np.array(sku_b)
    sku_category_b = np.array(sku_category_b)
    eb_flag_b = np.array(eb_flag_b)
    rfq_type_b = np.array(rfq_type_b)
    list_price_n = list_price_n
    rfq_price_n = rfq_price_n
    list_price_x_rfq_qty_n = list_price_x_rfq_qty_n
    rfq_price_x_order_qty_n = rfq_price_x_order_qty_n

    # concatenate all encoded and normalized arrays
    X = np.concatenate((country_b, coverage_b), axis=1)
    X = np.concatenate((X, sku_b), axis=1)
    X = np.concatenate((X, sku_category_b), axis=1)
    X = np.concatenate((X, eb_flag_b), axis=1)
    X = np.concatenate((X, rfq_type_b), axis=1)
    X = np.concatenate((X, list_price_n), axis=1)
    X = np.concatenate((X, rfq_price_n), axis=1)
    X = np.concatenate((X, list_price_x_rfq_qty_n), axis=1)
    X = np.concatenate((X, rfq_price_x_order_qty_n), axis=1)

    # split into train&cv and test sets
    test_size = 0.3
    X_train_and_cv, X_test, y_train_and_cv, y_test = train_test_split(X, y, test_size=test_size)

    # split into train and cv sets
    cv_size = 0.2
    X_train, X_cv, y_train, y_cv = train_test_split(X_train_and_cv,
                                                    y_train_and_cv,
                                                    test_size=cv_size)

    # # compute percentage of each key
    # for i in range(0, len(keys_order_qty)):
    #     key = keys_order_qty[i]
    #     dict_order_qty[key] = dict_order_qty.get(key) / data_size
    # for i in range(0, len(keys_country)):
    #     key = keys_country[i]
    #     dict_country[key] = dict_country.get(key) / data_size
    # for i in range(0, len(keys_sku)):
    #     key = keys_sku[i]
    #     dict_sku[key] = dict_sku.get(key) / data_size
    # for i in range(0, len(keys_sku_category)):
    #     key = keys_sku_category[i]
    #     dict_sku_category[key] = dict_sku_category.get(key) / data_size
    # for i in range(0, len(keys_eb_flag)):
    #     key = keys_eb_flag[i]
    #     dict_eb_flag[key] = dict_eb_flag.get(key) / data_size
    # for i in range(0, len(keys_rfq_type)):
    #     key = keys_rfq_type[i]
    #     dict_rfq_type[key] = dict_rfq_type.get(key) / data_size

    # # write result into a text file
    # file = open('result.txt', 'w')
    # file.write('Number of valid data sets: {}'.format(data_size))
    # file.write("\n\nCountry:")
    # file.write('\nKeys: {}'.format(keys_country))
    # file.write('\nNo. of keys: {}'.format(len(keys_country)))
    # file.write('\nFrequency of each category: {}'.format(dict_country))
    # file.write("\n\nCoverage:")
    # file.write('\nKeys: {}'.format(keys_coverage))
    # file.write('\nNo. of keys: {}'.format(len(keys_coverage)))
    # file.write('\nFrequency of each category: {}'.format(dict_coverage))
    # file.write("\n\nSKU:")
    # file.write('\nKeys: {}'.format(keys_sku))
    # file.write('\nNo. of keys: {}'.format(len(keys_sku)))
    # file.write('\nFrequency of each category: {}'.format(dict_sku))
    # file.write("\n\nSKU_Category:")
    # file.write('\nKeys: {}'.format(keys_sku_category))
    # file.write('\nNo. of keys: {}'.format(len(keys_sku_category)))
    # file.write('\nFrequency of each category: {}'.format(dict_sku_category))
    # file.write("\n\nEB_Flag:")
    # file.write('\nKeys: {}'.format(keys_eb_flag))
    # file.write('\nNo. of keys: {}'.format(len(keys_eb_flag)))
    # file.write('\nFrequency of each category: {}'.format(dict_eb_flag))
    # file.write("\n\nRFQ_Type:")
    # file.write('\nKeys: {}'.format(keys_rfq_type))
    # file.write('\nNo. of keys: {}'.format(len(keys_rfq_type)))
    # file.write('\nFrequency of each category: {}'.format(dict_rfq_type))
    # file.write("\n\nOrder_Qty:")
    # file.write('\nKeys: {}'.format(keys_order_qty))
    # file.write('\nNo. of keys: {}'.format(len(keys_order_qty)))
    # file.write('\nFrequency of each category: {}'.format(dict_order_qty))
    # file.close()

    end = time.time()

    print('\nPREPROCESSING COMPLETE\nTime elapsed: {:.2f} {}'.format((end - start), 'seconds'))

    return X_train, X_cv, X_test, y_train, y_cv, y_test


import click
import os
import json

@click.group()
def main():
    pass

@main.command()
@click.option('clang_path', '--clang',
              help = 'The clang bin path',
              type = click.STRING,
              default= '/nix/store/p5w6pzixrxzikq4vjvkzg7xccwwbvanv-clang-wrapper-11.1.0/bin/clang')
def cpp_json(clang_path: str):
    include_path_env = os.getenv('CMAKE_INCLUDE_PATH')
    if include_path_env == None:
      print("CMAKE_INCLUDE_PATH has no content.")
      return
    include_paths = list(set(include_path_env.split(':')))
    print(include_paths)

    js = {
      "configurations": [
          {
            "name": "Linux",
            "includePath": [
              "${workspaceFolder}/**"
            ],
            "defines": [
              "SPDLOG_FMT_EXTERNAL"
            ],
            "compilerPath": clang_path,
            "cStandard": "c17",
            "cppStandard": "c++20",
            "intelliSenseMode": "linux-clang-x64"
          }
      ],
      "version": 4
    }
    print(js)
    for e in include_paths:
      js['configurations'][0]['includePath'].append(e)

    if not os.path.exists('.vscode'):
      os.makedirs('.vscode')

    with open('.vscode/c_cpp_properties.json', 'w') as fp:
      json.dump(js, fp, indent=4)

if __name__ == '__main__':
    main()


import time

from nbformat import read
from runipy.notebook_runner import NotebookRunner
from steemdata.helpers import timeit

def run_notebook(filename='Charts'):
    """ Run Specific Notebook. """
    # convert to v3 of notebook format, as v4 is not supported yet
    notebook = read(open('%s.ipynb' % filename), 3)
    r = NotebookRunner(notebook)
    r.run_notebook()

def run():
    """ Run a chart updating notebook twice a day. """
    while True:
        print('Running Charts notebook...')
        with timeit():
            run_notebook()
        print('Done.')
        time.sleep(3600 * 12)

if __name__ == '__main__':
    run()


import sys
from keras.models import load_model
import numpy as np
import jieba
from gensim.models.word2vec import Word2Vec
from keras.preprocessing.sequence import pad_sequences
from keras.models import model_from_json
from keras import backend as K

#p test_model.py ./data/test_x.csv ./dict.txt.big final_result.csv
X_test_address = sys.argv[1]
dictionary_address = sys.argv[2]
output_adress = sys.argv[3]
w2v_model = Word2Vec.load("word2vec_250.model")

def predict_model(X_test, model_name):
    json_file = open(model_name+'.json', 'r')
    loaded_model_json = json_file.read()
    json_file.close()
    model = model_from_json(loaded_model_json)
    model.load_weights(model_name+'.weight')
    Y_preds = model.predict(X_test)
    print(Y_preds)
    K.clear_session()
    del model
    return Y_preds

def predict_model_hdf5(X_test, model_name):
    model = load_model(model_name+'.h5')
    Y_preds = model.predict(X_test)
    print(Y_preds)
    K.clear_session()
    del model
    return Y_preds

def process_text(text):
    cutWords = []
    for w in text :
        if( not_Bnumber(w) ):
            cutWords.append(w)
    return cutWords

def not_Bnumber(text):
    if len(text)>1 and (text[0]=='B' or 'b') and text[1].isdigit():
        return False
    else:
        return True
# Load dict from TA
jieba.load_userdict(dictionary_address)

test_x = []
with open(X_test_address,'r',encoding = 'utf-8') as f :
    lines = f.readlines()
    for i,line in enumerate(lines) :
        if i != 0 :        # ignore first line "id,comment"
            test_x.append(line.split(',',1)[1])

cutWords = []
# cut test x
for x in test_x :
    # Using accurate mode
    setList = jieba.cut(x,cut_all=False)
    cutWords.append(process_text(setList))

embedding_matrix = np.zeros(  (len(w2v_model.wv.vocab.items())+1, w2v_model.vector_size) )
word2idx = {}

vocab_list = [(word, w2v_model.wv[word]) for word, _ in w2v_model.wv.vocab.items()]
for i, vocab in enumerate(vocab_list):
    word, vec = vocab
    embedding_matrix[i + 1] = vec
    word2idx[word] = i + 1

def text_to_index(corpus):
    new_corpus = []
    for doc in corpus:
        new_doc = []
        for word in doc:
            try:
                new_doc.append(word2idx[word])
            except:
                new_doc.append(0)
        new_corpus.append(new_doc)
    return np.array(new_corpus)

PADDING_LENGTH = 100
X_test = text_to_index(cutWords)
X_test = pad_sequences(X_test, maxlen=PADDING_LENGTH, padding='post', truncating='post')

Y_preds0 = predict_model(X_test, 'rnn250_00')
Y_preds1 = predict_model(X_test, 'rnn250_01')
Y_preds2 = predict_model(X_test, 'rnn250_02')
Y_preds7 = predict_model(X_test, 'rnn250_07')
Y_preds_label = (Y_preds0 + Y_preds1 + Y_preds2 + Y_preds7)/4

for i in range(Y_preds_label.shape[0]):
    if(Y_preds_label[i]>=0.5):
        Y_preds_label[i] = 1
    else:
        Y_preds_label[i] = 0

save = open(output_adress,'w')
save.write("id,label\n")
for i in range(len(Y_preds_label)):
    save.write(str(i) + "," + str(int(Y_preds_label[i])) + "\n")
save.close()

'''
START_TIME = time.time()
Y_preds0 = predict_model(X_test, 'rnn250_00')
runTime = time.time() - START_TIME
print(runTime)
np.save('rnn250_00.npy', Y_preds0)
'''


from advent.intcode import compute, run, run_io
import asyncio
import pytest

pytestmark = pytest.mark.asyncio

async def test_input():
    assert await run_io([42], [3, 0, 4, 0, 99]) == 42

async def test_large_number():
    output = await run_io([], [1102, 34915192, 34915192, 7, 4, 7, 99, 0])
    assert len(str(output)) == 16

async def test_relative_mode():
    program = [109, 1, 204, -1, 1001, 100, 1, 100, 1008, 100, 16, 101, 1006, 101, 0, 99]
    iq = asyncio.Queue()
    oq = asyncio.Queue()
    task = asyncio.create_task(compute(program, iq, oq))
    await task

    output = []
    while True:
        try:
            output.append(oq.get_nowait())
        except asyncio.QueueEmpty:
            break

    assert output == program

async def test_relative_mode_simple():
    program = [109, 36, 204, -34, 99]
    output = await run_io([], program)
    assert output == 204

async def test_relative_mode_input():
    program = [109, 36, 203, 0, 204, 0, 99]
    output = await run_io([42], program)
    assert output == 42

async def test_relative_mode_output():
    program = [109, -1, 204, 1, 99]
    output = await run_io([], program)
    assert output == 109

async def test_long_instruction():
    program = [109, 36, 21102, 3, 4, 0, 204, 0, 99]
    output = await run_io([], program)
    assert output == 12

async def test_relative_base_adjust():
    program = [109, 36, 203, -2, 209, -2, 204, -41, 99]
    output = await run_io([5], program)
    assert output == 109

async def test_output():
    output = await run_io([], [104, 1125899906842624, 99])
    assert output == 1125899906842624

async def test_equals():
    assert await run_io([8], [3, 9, 8, 9, 10, 9, 4, 9, 99, -1, 8]) == 1
    assert await run_io([9], [3, 9, 8, 9, 10, 9, 4, 9, 99, -1, 8]) == 0

async def test_less_than():
    assert await run_io([7], [3, 9, 7, 9, 10, 9, 4, 9, 99, -1, 8]) == 1
    assert await run_io([8], [3, 9, 7, 9, 10, 9, 4, 9, 99, -1, 8]) == 0
    assert await run_io([9], [3, 9, 7, 9, 10, 9, 4, 9, 99, -1, 8]) == 0

async def test_less_than_immediate():
    program = [3, 3, 1107, -1, 8, 3, 4, 3, 99]
    assert await run_io([7], program) == 1
    assert await run_io([8], program) == 0
    assert await run_io([9], program) == 0

async def test_equals_immediate():
    program = [3, 3, 1108, -1, 8, 3, 4, 3, 99]
    assert await run_io([7], program) == 0
    assert await run_io([8], program) == 1
    assert await run_io([9], program) == 0

async def test_jump():
    program = [3, 12, 6, 12, 15, 1, 13, 14, 13, 4, 13, 99, -1, 0, 1, 9]
    assert await run_io([0], program) == 0
    assert await run_io([8], program) == 1
    assert await run_io([9], program) == 1

async def test_jump_immediate():
    program = [3, 3, 1105, -1, 9, 1101, 0, 0, 12, 4, 12, 99, 1]
    assert await run_io([0], program) == 0
    assert await run_io([8], program) == 1
    assert await run_io([9], program) == 1

async def test_big_program_jump():
    program = [
        3,
        21,
        1008,
        21,
        8,
        20,
        1005,
        20,
        22,
        107,
        8,
        21,
        20,
        1006,
        20,
        31,
        1106,
        0,
        36,
        98,
        0,
        0,
        1002,
        21,
        125,
        20,
        4,
        20,
        1105,
        1,
        46,
        104,
        999,
        1105,
        1,
        46,
        1101,
        1000,
        1,
        20,
        4,
        20,
        1105,
        1,
        46,
        98,
        99,
    ]

    assert await run_io([0], program) == 999
    assert await run_io([8], program) == 1000
    assert await run_io([9], program) == 1001

async def test_whole_program():
    with open("input/02.txt") as file_input:
        symbols = file_input.read().strip("\n").split(",")
        code = [int(symbol) for symbol in symbols]
        output = await run(code, 12, 2)
        assert output == 5534943

async def test_program_doesnt_mutate_input():
    with open("input/02.txt") as file_input:
        symbols = file_input.read().strip("\n").split(",")
        code = [int(symbol) for symbol in symbols]
        orig = code.copy()
        await run(code, 12, 2)
        assert code == orig


#!/usr/bin/env python3
#
# Copyright (c) 2017-2020 The Bitcoin ABC developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.

import mock
import unittest

from test.abcbot_fixture import ABCBotFixture
import test.mocks.phabricator

class EndpointBackportcheckTestCase(ABCBotFixture):
    def test_backportCheck_happyPath(self):
        self.phab.differential.revision.search.return_value = test.mocks.phabricator.Result([{
            'id': '1234',
            'fields': {
                'summary': 'This is a test summary'
            },
        }])

        response = self.post_json_with_hmac(
            '/backportCheck', self.headers, {'object': {'phid': '1234'}})
        assert response.status_code == 200
        self.phab.differential.revision.search.assert_called_with(
            constraints={"phids": ['1234']})
        self.phab.differential.revision.edit.assert_not_called()

    def test_backportCheck_invalid_json(self):
        response = self.post_data_with_hmac(
            '/backportCheck', self.headers, "not: a valid json")
        self.assertEqual(response.status_code, 415)

    def test_backportCheck_hasNoPRs(self):
        # Despite potential matches for linking PRs, the phab API should not be
        # called to update the summary, even if the result would be the same.
        self.phab.differential.revision.search.return_value = test.mocks.phabricator.Result([{
            'id': '1234',
            'fields': {
                'summary': "This is a test summary `Ignore this backport PR2345` some text.\n"
                "Some text ```Ignore this PR3456``` Some more text.\n"
                "```\nPR4567 in a multi-line code block\nPR5678 in the same code block\n```\n"
                "  Ignore this indented PR4567"
                # Note that short numbered PRs are much more common when referencing non-bitcoin PRs,
                # so we'll ignore them for now.
                "Ignore short numbered PRs: PR123"
                # But we do support secp256k1 PRs with 2-3 digits, so make
                # sure they're also ignored properly
                "This is a test summary `Ignore this secp256k1 backport PR234` some text.\n"
                "Some text ```Ignore this secp256k1 PR345``` Some more text.\n"
                "```\nsecp256k1 PR456 in a multi-line code block\nsecp256k1 PR567 in the same code block\n```\n"
                "  Ignore this indented secp256k1 PR456"
                "Ignore long numbered PRs for secp256k1: PR1234"
                "Ignore short numbered PRs for secp256k1: PR1",
            },
        }])

        response = self.post_json_with_hmac(
            '/backportCheck', self.headers, {'object': {'phid': '1234'}})
        assert response.status_code == 200
        self.phab.differential.revision.search.assert_called_with(
            constraints={'phids': ['1234']})
        self.phab.differential.revision.edit.assert_not_called()

    def test_backportCheck_hasPRs(self):
        self.phab.differential.revision.search.return_value = test.mocks.phabricator.Result([{
            'id': '1234',
            'fields': {
                'summary': "This is a test summary\n"
                # Bitcoin Core links
                "Backport of Core PR2345 and PR34567\n"
                "PR6789 outside of a code block `PR4567 inside a code block`\n"
                "```PR4567 in a single-line code block```\n"
                "```\nPR4567 in a multi-line code block\n```\n"
                "  PR4567 in a code block using indentation\n"
                "Another backport PR567890\n"
                # secp256k1 links
                "Backport of Secp256k1 PR23 and PR345\n"
                "SECP256K1 PR678 outside of a code block `secp256k1 PR456 inside a code block`\n"
                "```secp256k1 PR456 in a single-line code block```\n"
                "```\nsecp256k1 PR456 in a multi-line code block\n```\n"
                "  secp256k1 PR456 in a code block using indentation\n"
                "Another secp backport PR567",
            },
        }])

        response = self.post_json_with_hmac(
            '/backportCheck', self.headers, {'object': {'phid': '1234'}})
        assert response.status_code == 200
        self.phab.differential.revision.search.assert_called_with(
            constraints={'phids': ['1234']})
        calls = [mock.call(transactions=[{
            "type": "summary",
            "value": "This is a test summary\n"
            # Bitcoin Core links
            "Backport of Core [[https://github.com/bitcoin/bitcoin/pull/2345 | PR2345]] and "
            "[[https://github.com/bitcoin/bitcoin/pull/34567 | PR34567]]\n"
            "[[https://github.com/bitcoin/bitcoin/pull/6789 | PR6789]] outside of a code block `PR4567 inside a code block`\n"
            "```PR4567 in a single-line code block```\n"
            "```\nPR4567 in a multi-line code block\n```\n"
            "  PR4567 in a code block using indentation\n"
            "Another backport [[https://github.com/bitcoin/bitcoin/pull/567890 | PR567890]]\n"
            # secp256k1 links
            "Backport of Secp256k1 [[https://github.com/bitcoin-core/secp256k1/pull/23 | PR23]] and "
            "[[https://github.com/bitcoin-core/secp256k1/pull/345 | PR345]]\n"
            "SECP256K1 [[https://github.com/bitcoin-core/secp256k1/pull/678 | PR678]] outside of a code block `secp256k1 PR456 inside a code block`\n"
            "```secp256k1 PR456 in a single-line code block```\n"
            "```\nsecp256k1 PR456 in a multi-line code block\n```\n"
            "  secp256k1 PR456 in a code block using indentation\n"
            "Another secp backport [[https://github.com/bitcoin-core/secp256k1/pull/567 | PR567]]",
        }], objectIdentifier='1234'), mock.call(transactions=[{
            "type": "comment",
            "value": "[Bot Message]\n"
            "One or more PR numbers were detected in the summary.\n"
            "Links to those PRs have been inserted into the summary for reference.",
        }], objectIdentifier='1234')]
        self.phab.differential.revision.edit.assert_has_calls(
            calls, any_order=True)

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


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

from django import forms
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.models import User
from django.core.exceptions import MultipleObjectsReturned
from django.core.urlresolvers import reverse
from django.shortcuts import redirect
from django.utils.html import format_html
from django.utils.translation import ugettext_lazy as _

from import_export.admin import ExportActionModelAdmin, ImportExportMixin
import impersonate

from . import resources
from .forms import GradeAdminForm, EventAdminForm, CupAdminForm, ParticipationAdminForm, AscentInlineFormSet, UserCreateForm
from .mixins import AutoSelectGymMixin, LimitOptionsMixin
from .models import Cup, Position, AgeGroup, Event, Route, Gym, Sector, Grade, Points, Participation, Ascent, UserProfile

# INLINES

class UserProfileInline(admin.StackedInline):
    model = UserProfile

class UserParticipationInlineReadOnly(LimitOptionsMixin, admin.TabularInline):
    """
    This InlineAdmin displays all event participations that the current user
    has no privileges to edit for. Nothing can be added, changed or deleted
    here.
    """
    model = Participation
    extra = 0
    can_delete = False
    verbose_name_plural = "Wettkampfteilnahmen anderer Hallen"

    # TODO: make start and end times editable to the editors when the event in
    # question needs this info
    exclude = ['start', 'end']

    def has_add_permission(self, request):
        return False

    readonly_fields = [
        'event',
        'category',
        'gender',
        'age',
        'city',
        'confirmed'
    ]

    def get_queryset(self, request):
        qs = super(UserParticipationInlineReadOnly, self).get_queryset(request)
        # Only display those participation objects that belong to a gym that
        # the current user is *not* a manager of.
        return qs.exclude(event__gym__managers=request.user)

class UserParticipationInline(LimitOptionsMixin, admin.TabularInline):
    """
    This InlineAdmin displays all event participations that the current user
    (or superuser) can edit and delete.
    """
    model = Participation
    extra = 0

    def get_queryset(self, request):
        qs = super(UserParticipationInline, self).get_queryset(request)
        # Display all participations for this person if the current user has
        # admin privileges
        if request.user.is_superuser:
            return qs
        # But only display those participation objects that belong to a gym that
        # the current user is a manager of if they're not an admin.
        return qs.filter(event__gym__managers=request.user)

class PositionInlineAdmin(admin.TabularInline):
    """
    Inline model admin for selecting who scored how during the finals of an
    event.
    """
    model = Position
    extra = 0
    ordering = ["participation__category", "position"]

    class ParticipationChoiceField(forms.ModelChoiceField):
        """
        I once tried to use a AutoSelect2Field but due to the way the Django
        clones the DOM when inserting new inline forms, the widget breaks.

        Right now it works, but only slowly because the query is not cached and
        needs to be retrieved several times once a few finalists are entered.
        But generally the event is done by then so long loading times are not
        a big deal.

        Don't use Participation.__unicode__() as a label because that would
        generate a lot of database queries for events and, also, the user
        should think that participants are selected and not participation
        objects.
        """
        def label_from_instance(self, obj):
            return obj.participant.__unicode__()

    def formfield_for_foreignkey(self, db_field, request, **kwargs):
        """ Limit choices to users who participated in that event. """
        if db_field.name == "participation":
            kwargs["queryset"] = Participation.objects.\
                select_related("participant").filter(
                    event=request._obj_
                ).order_by('participant__first_name', 'participant__last_name')
            return self.ParticipationChoiceField(**kwargs)

class AscentInlineAdmin(admin.TabularInline):
    model = Ascent
    raw_id_fields = ['route']
    readonly_fields = ('grade', '_route__event')
    formset = AscentInlineFormSet
    extra = 0

    def get_fields(self, request, obj=None):
        """
        Display Ascent fields depending on whether this event is a bouldering
        or setter's competition.
        """
        fields = ['route', 'grade']
        if obj and obj.event:
            if obj.event.is_bouldering_contest:
                fields.append('style')
            else:
                fields.append(('comment', 'rating', 'grade_correct'))
        fields.append('_route__event')
        return fields

# FILTERS

class EventGymListFilter(admin.SimpleListFilter):
    """ Filter through event's gym relation. """
    title = "Halle"
    parameter_name = "event__gym"

    def lookups(self, request, model_admin):
        gyms = Gym.objects.all()
        if not request.user.is_superuser:
            gyms = gyms.filter(managers=request.user)
        return [(g.id, g.name) for g in gyms]

    def queryset(self, request, queryset):
        if self.value():
            return queryset.filter(event__gym_id=self.value())

class ParticipationYearFilter(admin.SimpleListFilter):
    title = "Jahr"
    parameter_name = "year"

    def lookups(self, request, model_admin):
        qs = model_admin.get_queryset(request)
        dates = qs.distinct("event").values_list("event__begin", flat=True).order_by()
        return sorted(set((d.year, d.year) for d in dates), reverse=True)

    def queryset(self, request, queryset):
        if self.value():
            return queryset.filter(event__begin__year=self.value())

# MODELADMINS

class SectorAdmin(AutoSelectGymMixin, LimitOptionsMixin, admin.ModelAdmin):
    search_fields = ('name',)
    list_display = ('name', 'gym', 'sort')
    list_editable = ('sort',)
    list_filter = (
        ('gym', admin.RelatedOnlyFieldListFilter),
    )

    def get_queryset(self, request):
        """
        Limit Sectors to those that belong to the current user unless they're
        an admin.
        """
        qs = super(SectorAdmin, self).get_queryset(request)
        if request.user.is_superuser:
            return qs
        return qs.filter(gym__managers=request.user)

class AgeGroupAdmin(admin.ModelAdmin):
    list_display = ('name', 'min_age', 'max_age')

class GymAdmin(admin.ModelAdmin):
    filter_horizontal = ["managers"]
    list_display = ('name', 'manager_list', 'city', 'event_num',)

    def manager_list(self, obj):
        """
        Displays a list of names of all those people who are in charge of
        this gym and the related objects.
        """
        return ", ".join([u.get_full_name() for u in obj.managers.all()])
    manager_list.short_description = "verantwortlich"

    def event_num(self, obj):
        """ Returns the number of events that are related to this gym. """
        return obj.event_set.count()
    event_num.short_description = "Wettkämpfe"

    def get_queryset(self, request):
        """
        Limit gyms to those that belong to the current user unless they're
        an admin.
        """
        qs = super(GymAdmin, self).get_queryset(request)
        if request.user.is_superuser:
            return qs
        return qs.filter(managers=request.user)

    def has_add_permission(self, request):
        # Only administrators are able to add new gyms.
        return request.user.is_superuser

    def has_change_permission(self, request, obj=None):
        if obj is not None:
            # The change form of a particular object is requested and only
            # displayed to superusers or managers of that particular gym.
            return request.user.is_superuser or \
                    obj.managers.filter(pk=request.user.pk).exists()
        else:
            # The changelist is requested and only shown to superusers or
            # people who are managers of at least one gym. Returning `False`
            # will make the changelist not even viewable.
            return request.user.is_superuser or \
                    self.model.objects.filter(managers=request.user).exists()

    def has_delete_permission(self, *args, **kwargs):
        # This works exactly the same as `has_change_permission` except that
        # obj=None equals the "delete selected" admin action on the
        # changelist.

        # There's a bug in Django in the way that no object level permissions
        # are checked when running an admin action.
        # https://code.djangoproject.com/ticket/11383
        return self.has_change_permission(*args, **kwargs)

    def changelist_view(self, request, extra_context=None):
        # Skip the changelist if there's only one object to edit and go
        # directly to the changeform.
        # This is inspired by django-single-model-admin.
        info = '{0}_{1}'.format(self.model._meta.app_label, getattr(self.model._meta, 'model_name'))

        try:
            instance = self.get_queryset(request).get()

        except self.model.DoesNotExist:
            return redirect(reverse('admin:{0}_add'.format(info)))

        except MultipleObjectsReturned:
            return super(GymAdmin, self).changelist_view(request, extra_context=extra_context)

        else:
            return redirect(reverse('admin:{0}_change'.format(info), args=[instance.pk]))

class CupAdmin(admin.ModelAdmin):
    form = CupAdminForm
    list_display = ["name", "events"]

    def events(self, obj):
        event_names = [e.name for e in obj.event_set.all()]
        return format_html("" + "
".join(event_names) + "")
    events.short_description = "Zugeordnete Wettkämpfe"

    def has_delete_permission(self, request, obj=None):
        # Regular users should not be able to delete Cup objects in general.
        # Right now, there's no ownership implemented in the Cup model because
        # no one (besides myself) needed to create a cup. If a user needs to
        # have a Cup deleted, they have to contact an admin.
        if request.user.is_superuser:
            return True
        return False

class RouteAdmin(LimitOptionsMixin, ImportExportMixin, ExportActionModelAdmin):
    list_display = ['number', 'colored_grade', 'sector', 'points', 'event', 'name', 'creator', ]
    list_display_links = ('number',)
    list_select_related = ('event', 'sector', 'grade',)
    search_fields = ['number', 'name']
    date_hierarchy = 'created'
    ordering = ('event', 'number')
    readonly_fields = ('created',)

    list_filter = [
        EventGymListFilter,
        ('event', admin.RelatedOnlyFieldListFilter),
        ('grade', admin.RelatedOnlyFieldListFilter),
        ('sector', admin.RelatedOnlyFieldListFilter),
    ]

    fields = (
        ('number', 'name'),
        'event',
        'grade',
        'sector',
        'points',
        ('created', 'creator'),
    )
    inlines = [AscentInlineAdmin]
    # What gets im- and exported through django-import-export is defined in
    # this class
    resource_class = resources.RouteResource
    import_template_name = "admin/import_export/route_import.html"

    def get_formsets_with_inlines(self, request, obj=None):
        # Don't display AscentInlineAdmin on blank forms
        for inline in self.get_inline_instances(request, obj):
            if isinstance(inline, AscentInlineAdmin) and obj is None:
                continue
            yield inline.get_formset(request, obj), inline

    def get_form(self, request, obj=None, **kwargs):
        # Attach object to request in order to change field options
        # accordingly later on.
        if obj:
            request._route_ = obj
        return super(RouteAdmin, self).get_form(request, obj, **kwargs)

    def get_queryset(self, request):
        # Limit Routes to those that belong to the current user unless they're
        # an admin.
        qs = super(RouteAdmin, self).get_queryset(request).prefetch_related('ascent_set')
        if request.user.is_superuser:
            return qs
        return qs.filter(event__gym__managers=request.user)

class GradeAdmin(LimitOptionsMixin, admin.ModelAdmin):
    list_display = ['name', 'color', 'gym', 'relaxed', 'power', 'sort']
    list_editable = ['sort', 'color']
    list_filter = ['gym', 'relaxed', 'power']
    ordering = ['gym', 'sort']
    search_fields = ['name', 'gym__name']
    form = GradeAdminForm

    def get_queryset(self, request):
        """
        Limit Grades to those that belong to the current user unless they're an
        admin.
        """
        qs = super(GradeAdmin, self).get_queryset(request)
        if request.user.is_superuser:
            return qs
        return qs.filter(gym__managers=request.user)

class ParticipationAdmin(LimitOptionsMixin, ImportExportMixin, ExportActionModelAdmin):
    list_display = ('participant', 'confirmed', 'category', 'event')
    list_editable = ('confirmed',)
    list_filter = [
        EventGymListFilter,
        ParticipationYearFilter,
        'confirmed',
        'category',
        ('event', admin.RelatedOnlyFieldListFilter)
    ]
    search_fields = [
        'participant__first_name',
        'participant__last_name',
        'participant__email'
    ]

    inlines = [AscentInlineAdmin]
    readonly_fields = ("datetime",)
    form = ParticipationAdminForm
    resource_class = resources.ParticipationResource

    def get_fields(self, request, obj=None):
        # Don't do anything irregular when a new object is created
        if not obj:
            return super(ParticipationAdmin, self).get_fields(request)

        fields = ['participant',]

        # When event does not rely on confirming participations, don't display
        # the respective checkbox
        if obj.event.needs_confirmation:
            fields.append(('event', 'confirmed'))
        else:
            fields.append('event')

        # When event does not use a separation of levels, don't display the
        # level select widget
        if obj.event.uses_levels:
            fields.append('category')

        # Only display start/end times when the corresponding mode is in use
        if obj.event.mode == Event.ALL_YOU_CAN_TOP:
            fields.append(('start', 'end'))

        fields.extend(('age', 'gender', 'city', 'datetime'))

        return fields

    def get_form(self, request, obj=None, **kwargs):
        """ Hide `category` field if there's no separation in levels. """
        self.exclude = []
        if obj and not obj.event.uses_levels:
            self.exclude.append('category')
        return super(ParticipationAdmin, self).get_form(request, obj, **kwargs)

    def get_changelist_form(self, request, **kwargs):
        return ParticipationAdminForm

    def formfield_for_foreignkey(self, db_field, request, **kwargs):
        if db_field.name == "participant":
            kwargs["queryset"] = User.objects.order_by("first_name", "last_name") # NOQA
        return super(ParticipationAdmin, self).\
            formfield_for_foreignkey(db_field, request, **kwargs)

    def get_queryset(self, request):
        """
        Limit participations to those that belong to the current user's event
        unless they're an admin.
        """
        qs = super(ParticipationAdmin, self).get_queryset(request).prefetch_related('ascent_set', 'event')
        if not request.user.is_superuser:
            return qs.filter(event__gym__managers=request.user)
        return qs

class EventAdmin(LimitOptionsMixin, admin.ModelAdmin):
    form = EventAdminForm
    list_display = [
        'name', 'begin', 'participant_count', 'public',
        'needs_confirmation', 'uses_levels',
        'boulder_count'
    ]
    date_hierarchy = 'begin'
    ordering = ["-begin"]
    inlines = [PositionInlineAdmin]
    filter_horizontal = ['age_groups']
    list_filter = (
        ('gym', admin.RelatedOnlyFieldListFilter),
        'cup'
    )
    fieldsets = [
        [None, {
            'fields': ['name',
                      ('begin', 'end'),
                      'begin_checkin',
                      'poster',
                      'description',
                      ('gym', 'cup'),
          ]
        }],
        ('Erweiterte Einstellungen', {
            'fields': (
                'is_bouldering_contest',
                'hide_boulder_ranking',
                'uses_levels',
                'needs_confirmation',
                'max_participants',
                'age_groups',
                'mode',
            ), 'classes': ('collapse',),
        }),
        ('Sichtbarkeit', {
            'fields': (
                'public',
                'sandboxed',
            ), 'classes': ('collapse',),
        }),
    ]

    class Media:
        # Include jQuery script that handles hiding and displaying fields
        # according to which mode the event runs (i.e. setter's competition,
        # bouldering competition)
        js = ("js/boulderdb.admin.js",)

    def get_queryset(self, request):
        """
        Limits events to those that belong to the current user's gym unless
        they're an admin.
        """
        qs = super(EventAdmin, self).get_queryset(request)
        if not request.user.is_superuser:
            qs = qs.filter(gym__managers=request.user)
        return qs.prefetch_related(
            'boulders', 'boulders__grade', 'boulders__sector')

    def get_form(self, request, obj=None, **kwargs):
        form = super(EventAdmin, self).get_form(request, obj, **kwargs)

        # Automatically select the first gym that the user is a manager of
        try:
            form.base_fields["gym"].initial = Gym.objects.filter(managers=request.user).first()
        except IndexError:
            pass

        # add instance to request for processing through inline formsets,
        # because at least PositionInline needs to filter the queryset of
        # users down to only those that partook in the event
        request._obj_ = obj

        return form

    def participant_count(self, obj):
        p = obj.participants.count()
        s = "%s" % p

        if obj.needs_confirmation:
            confirmed_p = obj.participants.filter(
                participation__confirmed=True).count()
            s = s + u" (%s bestätigt)" % confirmed_p

        if obj.max_participants:
            s = s + " von max. %s" % obj.max_participants

        return s
    participant_count.short_description = "Teilnehmende"

    def boulder_count(self, obj):
        return obj.boulders.count()
    boulder_count.short_description = "Boulder"

class UserProfileAdmin(UserAdmin):
    """
    Custom user admin that not only displays information about the user object
    but also on the related profile and all of the user's event
    participations.
    """
    list_display = ('full_name', 'email', 'birthday', 'is_staff', 'impersonate',)
    list_display_links = ('full_name', 'email')
    list_select_related = ('profile',)
    add_form = UserCreateForm

    add_fieldsets = (
        (None, {
            'classes': ('wide',),
            'fields': ('first_name', 'last_name', 'password1', 'password2'),
        }),
    )

    def full_name(self, obj):
        return obj.get_full_name()
    full_name.short_description = 'Name'

    def birthday(self, obj):
        return obj.profile.birthday
    birthday.short_description = 'Geburtsdatum'
    birthday.oder_field = 'profile__birthday'

    def impersonate(self, obj):
        if obj in self.users_impersonable:
            url = reverse('impersonate-start', kwargs={'uid': obj.pk})
            return format_html(u"{} verkörpern", url, obj.first_name)
        else:
            return "(nicht erlaubt)"
    impersonate.short_description = 'als … ausgeben'

    def get_list_display(self, request):
        # Store a list of all users that can be impersonated
        self.users_impersonable = impersonate.helpers.users_impersonable(request)
        return self.list_display

    def get_fieldsets(self, request, obj=None):
        # Prevent permission escalation
        if request.user.is_superuser:
            return super(UserProfileAdmin, self).get_fieldsets(request, obj)

        safe_fieldset = (
            (
                None, {'fields': ('username', 'password')}
            ),
            (
                _('Personal info'), {'fields': ('first_name', 'last_name', 'email')}
            )
        )
        return safe_fieldset

    def get_inline_instances(self, request, obj=None):
        # No need to seperate between events that the user is manager of and
        # other events when the user is a superuser; just let them edit all.
        all_inlines = [
            UserProfileInline,
            UserParticipationInline,
            UserParticipationInlineReadOnly
        ]
        superuser_inlines = [
            UserProfileInline,
            UserParticipationInline
        ]

        if request.user.is_superuser:
            self.inlines = superuser_inlines
        else:
            self.inlines = all_inlines
        return super(UserProfileAdmin, self).get_inline_instances(request)

class PointsAdmin(admin.ModelAdmin):
    # TODO: Add PointsResource to export the previous year's points and import
    # them for the next year easily. Creating them one by one is too much
    # work.
    list_filter = ["cup"]
    list_display = ["cup", "position", "points"]
    model = Points
    list_editable = ("points",)

admin.site.register(AgeGroup, AgeGroupAdmin)
admin.site.register(Cup, CupAdmin)
admin.site.register(Event, EventAdmin)
admin.site.register(Grade, GradeAdmin)
admin.site.register(Gym, GymAdmin)
admin.site.register(Participation, ParticipationAdmin)
admin.site.register(Route, RouteAdmin)
admin.site.register(Points, PointsAdmin)
admin.site.register(Sector, SectorAdmin)

# Unregister Django's own UserAdmin because we need a modified version to
# display the full name etc.
admin.site.unregister(User)
admin.site.register(User, UserProfileAdmin)

admin.site.site_header = "Willkommen auf blocsport.de/admin"
admin.site.site_title = "Blocsport-Verwaltung"
admin.site.index_title = "Blocsport-Verwaltung"


from django.conf.urls import url, include
from django.urls import path, include
from . import views

# Wire up our API using automatic URL routing.
# Additionally, we include login URLs for the browsable API.
urlpatterns = [
    path('admin/add-playlist/', views.PlaylistCreateView.as_view(), name='playlist-create'),
    path('admin/add-cartoon/', views.CartoonCreateView.as_view(), name='cartoon-create'),
    path('admin/playlists/', views.PlaylistListView.as_view(), name='playlistlisting'),
    path('', views.CartoonListView.as_view(), name='cartoonlisting'),
    path('cartoons/<int:pk>/', views.CartoonDetailsView.as_view(), name='cartoondetails'),
    path('cartoons/<int:pk>/edit/', views.CartoonEditView.as_view(), name='cartoon-edit'),
    path('playlists/<int:pk>/', views.PlaylistDetailsView.as_view(), name='playlistdetails'),
    path('playlists/<int:pk>/edit/', views.PlaylistEditView.as_view(), name='playlist-edit'),

]


from tabulate import tabulate
from collections import OrderedDict

def isterminal(char):
    if(char.isupper() or char == "#"):
        return False
    else:
        return True
def insert(grammar, lhs, rhs):
    if(lhs in grammar and rhs not in grammar[lhs] and grammar[lhs] != "null"):
        grammar[lhs].append(rhs)
    elif(lhs not in grammar or grammar[lhs] == "null"):
        grammar[lhs] = [rhs]
    return grammar
def first(lhs, grammar, grammar_first):
    rhs = grammar[lhs]
    for i in rhs:
        k = 0
        flag = 0
        current = []
        confirm = 0
        flog = 0
        if(lhs in grammar and "#" in grammar_first[lhs]):
            flog = 1
        while(1):
            check = []
            if(k>=len(i)):
                if(len(current)==0 or flag == 1 or confirm == k or flog == 1):
                    grammar_first = insert(grammar_first, lhs, "#")
                break
            if(i[k].isupper()):
                if(grammar_first[i[k]] == "null"):
                    grammar_first = first(i[k], grammar, grammar_first)
                for j in grammar_first[i[k]]:
                    grammar_first = insert(grammar_first, lhs, j)
                    check.append(j)
            else:
                grammar_first = insert(grammar_first, lhs, i[k])
                check.append(i[k])
            if(i[k]=="#"):
                flag = 1
            current.extend(check)
            if("#" not in check):
                if(flog == 1):
                    grammar_first = insert(grammar_first, lhs, "#")
                break
            else:
                confirm += 1
                k+=1
                grammar_first[lhs].remove("#")
    return(grammar_first)
def rec_follow(k, next_i, grammar_follow, i, grammar, start, grammar_first, lhs):
    if(len(k)==next_i):
        if(grammar_follow[i] == "null"):
            grammar_follow = follow(i, grammar, grammar_follow, start)
        for q in grammar_follow[i]:
            grammar_follow = insert(grammar_follow, lhs, q)
    else:
        if(k[next_i].isupper()):
            for q in grammar_first[k[next_i]]:
                if(q=="#"):
                    grammar_follow = rec_follow(k, next_i+1, grammar_follow, i, grammar, start, grammar_first, lhs)
                else:
                    grammar_follow = insert(grammar_follow, lhs, q)
        else:
            grammar_follow = insert(grammar_follow, lhs, k[next_i])

    return(grammar_follow)

def follow(lhs, grammar, grammar_follow, start):
    for i in grammar:
        j = grammar[i]
        for k in j:
            if(lhs in k):
                next_i = k.index(lhs)+1
                grammar_follow = rec_follow(k, next_i, grammar_follow, i, grammar, start, grammar_first, lhs)
    if(lhs==start):
        grammar_follow = insert(grammar_follow, lhs, "$")
    return(grammar_follow)
def show_dict(dictionary):
    for key in dictionary.keys():
        print(key+"  :  ", end = "")
        for item in dictionary[key]:
            if(item == "#"):
                print("Epsilon, ", end = "")
            else:
                print(item+", ", end = "")
        print("")
def get_rule(non_terminal, terminal, grammar, grammar_first):
    for rhs in grammar[non_terminal]:
        for rule in rhs:
            if(rule == terminal):
                string = non_terminal+"="+rhs
                return string

            elif(rule.isupper() and terminal in grammar_first[rule]):
                string = non_terminal+"="+rhs
                return string

grammar = OrderedDict()
grammar_first = OrderedDict()
grammar_follow = OrderedDict()

f = open('first_follow_grammar.txt')
for i in f:
    i = i.replace("\n", "")
    lhs = ""
    rhs = ""
    flag = 1
    for j in i:
        if(j=="="):
            flag = (flag+1)%2
            continue
        if(flag==1):
            lhs += j
        else:
            rhs += j
    grammar = insert(grammar, lhs, rhs)
    grammar_first[lhs] = "null"
    grammar_follow[lhs] = "null"

print("Grammar")
show_dict(grammar)

for lhs in grammar:
    if(grammar_first[lhs] == "null"):
        grammar_first = first(lhs, grammar, grammar_first)

start = list(grammar.keys())[0]
for lhs in grammar:
    if(grammar_follow[lhs] == "null"):
        grammar_follow = follow(lhs, grammar, grammar_follow, start)

print("\nFollow")
show_dict(grammar_follow)

f.close()


# encoding: utf-8
from __future__ import unicode_literals

import sys

from tornado import ioloop
from tornado.httpclient import AsyncHTTPClient

from autopkg.poll_sms import get_sms
from daemonizer import Daemon
from .settings import KYLIN_HOST

def check_celery():
    client = AsyncHTTPClient()
    client.fetch("http://{}/celery/qsize/".format(KYLIN_HOST))

class MyDaemon(Daemon):
    def run(self):
        # p1 = ioloop.PeriodicCallback(get_sms, 1000)
        # p1.start()
        ioloop.PeriodicCallback(check_celery, 3600*1000).start()
        ioloop.IOLoop.instance().start()

if __name__ == "__main__":
    d = MyDaemon("/tmp/kylin-daemon.pid", stdout="/tmp/my-daemon.log", stderr="/tmp/my-damon.error.log")
    if len(sys.argv) == 2:
        if sys.argv[1] == "start":
            d.start()
        elif sys.argv[1] == "stop":
            d.stop()
        elif sys.argv[1] == "restart":
            d.restart()
        else:
            print("Unknown command")
            sys.exit(2)
        sys.exit(0)
    else:
        print("Usage: %s start|stop|restart" % sys.argv[0])
        sys.exit(2)


import datetime

from django.contrib.auth import _get_user_session_key, BACKEND_SESSION_KEY, load_backend, HASH_SESSION_KEY
from django.contrib.auth.models import AnonymousUser
from jwt.compat import constant_time_compare
from rest_framework import serializers

from streamifye import settings

def days_since(date):
    """
    Evaluates the difference between two dates
    :param date: date to compare
    :type date: DateTime
    :return: Number of days since input date
    :rtype: int
    """
    now = datetime.datetime.now(tz=datetime.timezone.utc)
    return int((now - date).days)

def get_user(request):
    """
    Returns the user model instance associated with the given request session.
    If no user is retrieved an instance of `AnonymousUser` is returned.
    """
    user = None
    try:
        user_id = _get_user_session_key(request)
        backend_path = request.session[BACKEND_SESSION_KEY]
    except KeyError:
        pass
    else:
        if backend_path in settings.AUTHENTICATION_BACKENDS:
            backend = load_backend(backend_path)
            user = backend.get_user(user_id)
            # Verify the session
            if ('django.contrib.auth.middleware.SessionAuthenticationMiddleware'
                    in settings.MIDDLEWARE_CLASSES and hasattr(user, 'get_session_auth_hash')):
                session_hash = request.session.get(HASH_SESSION_KEY)
                session_hash_verified = session_hash and constant_time_compare(
                    session_hash,
                    user.get_session_auth_hash()
                )
                if not session_hash_verified:
                    request.session.flush()
                    user = None

    return user or AnonymousUser()

class Base64ImageField(serializers.ImageField):
    """
    A Django REST framework field for handling image-uploads through raw post data.
    It uses base64 for encoding and decoding the contents of the file.

    Heavily based on
    https://github.com/tomchristie/django-rest-framework/pull/1268

    Updated for Django REST framework 3.
    """

    def to_internal_value(self, data):
        from django.core.files.base import ContentFile
        import base64
        import six
        import uuid

        # Check if this is a base64 string
        if isinstance(data, six.string_types):
            # Check if the base64 string is in the "data:" format
            if 'data:' in data and ';base64,' in data:
                # Break out the header from the base64 content
                header, data = data.split(';base64,')

            # Try to decode the file. Return validation error if it fails.
            try:
                decoded_file = base64.b64decode(data)
            except TypeError:
                self.fail('invalid_image')

            # Generate file name:
            file_name = str(uuid.uuid4())[:12]  # 12 characters are more than enough.
            # Get the file name extension:
            file_extension = self.get_file_extension(file_name, decoded_file)

            complete_file_name = "%s.%s" % (file_name, file_extension,)

            data = ContentFile(decoded_file, name=complete_file_name)

        return super(Base64ImageField, self).to_internal_value(data)

    def get_file_extension(self, file_name, decoded_file):
        import imghdr

        extension = imghdr.what(file_name, decoded_file)
        extension = "jpg" if extension == "jpeg" else extension

        return extension


import unittest2 as unittest
import lxml
from lxml.etree import ParserError

from zope.interface import alsoProvides
from zope.viewlet.interfaces import IViewletManager
from zope.component import queryMultiAdapter

from Products.Five.browser import BrowserView as View
from Products.CMFCore.utils import getToolByName

from emas.theme.interfaces import IEmasThemeLayer
from emas.theme import MessageFactory as _

from emas.theme.tests.base import FUNCTIONAL_TESTING

def find_viewlet(context, request, manager_name, viewlet_name, layer=None):
    if layer:
        alsoProvides(request, layer)

    view = View(context, request)
    manager = queryMultiAdapter(
        (context, request, view),
        IViewletManager,
        manager_name,
        default=None
    )
    manager.update()
    viewlets = manager.viewlets
    viewlets = [v for v in viewlets if v.__name__ == viewlet_name]
    return viewlets and viewlets[0] or None

class TestPracticeServiceMessagesViewlet(unittest.TestCase):
    """ Test the intelligent practice messages service viewlets  """

    layer = FUNCTIONAL_TESTING

    def setUp(self):
        super(TestPracticeServiceMessagesViewlet, self).setUp()
        self.setRoles(['Reader',])
        self.context = self.portal.maths
        self.request = self.portal.REQUEST
        self.manager_name = 'plone.abovecontent'
        self.themelayer = IEmasThemeLayer
        self.viewlet_name = 'emas.practice_service_messages'

    def test_viewlet_exists(self):
        viewlet = self.get_viewlet()
        self.failUnless(viewlet)
        self.failUnless(viewlet.__name__ == self.viewlet_name)

    def test_no_messages(self):
        viewlet = self.get_viewlet()
        result = viewlet.index()
        self.assertRaises(ParserError, lxml.html.fromstring, result)

    def test_noaccess_message(self):
        plone_utils = getToolByName(self.portal, 'plone_utils')
        message = _(u'You do not currently have access to this service.')
        plone_utils.addPortalMessage(message, 'services-warning')

        viewlet = self.get_viewlet()
        result = viewlet.index()

        expected_result = \
u"""\n\n
\n
You do not currently have access to this service.
\n
\n\n\n"""
        self.assertEqual(result, expected_result, 'Incorrect message returned.')

        doc = lxml.html.fromstring(result)
        self.assertEqual(len(doc.xpath('//dl')), 1, 'No content found.')

    def get_viewlet(self):
        viewlet = find_viewlet(self.context,
                               self.request,
                               self.manager_name,
                               self.viewlet_name,
                               self.themelayer)
        return viewlet


from django.contrib import admin
from django.urls import path,include
from django.conf import settings
from django.conf.urls.static import static

from mysite.core import views #6 | go to app/views.py file for  step 7

urlpatterns = [
    path('admin/', admin.site.urls),
    path('',views.home,name='home'), #5 here views.home in 'home' is connect from views.py file def 'home'(req)
    path('signup/',views.signup,name='signup'), # name ='' is refernce for url in base.html file like
    path('secret/',views.secret_page,name='secret'),
    path('secret2/',views.SecratePage.as_view(),name='secret2'),
    path('accounts/', include('django.contrib.auth.urls')),
    path('upload/',views.upload,name='upload'), # Here views.upload means defupload connect from view.py
    path('books/',views.book_list,name='book_list'),
    path('books/upload/',views.upload_book,name='upload_book'),
    path('books/<int:pk>/',views.delete_book,name='delete_book'),
    path('class/books/',views.BookListView.as_view(),name ='class_book_list'),
    path('class/books/upload/',views.UploadBookView.as_view(),name ='class_upload_book'),
]

if settings.DEBUG: # Only during development pupose
	urlpatterns += static(settings.MEDIA_URL,document_root = settings.MEDIA_ROOT)