import os
os.chdir("D:\\trainings\\computer_vision")

#%matplotlib inline
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
# import the necessary packages specific to Computer vision
import cv2 # cv2.__version__

# fix random seed for reproducibility
seed_value = 123; np.random.seed(seed_value); #set_random_seed(seed_value) # Keras uses its source of randomness regardless Theano or TensorFlow.In addition, TensorFlow has its own random number generator that must also be seeded by calling the set_random_seed() function immediately after the NumPy random number generator:

exec(open(os.path.abspath('image_common_utils.py')).read())

#%% Basic image read/write using OpenCv

# cv2.IMREAD_COLOR -> 1, cv2.IMREAD_GRAYSCALE -> 0, cv2.IMREAD_UNCHANGED -> -1
color_image = cv2.imread('./image_data/balloon.jpg',1)
cv2.namedWindow('image', cv2.WINDOW_NORMAL) # Default: cv2.WINDOW_AUTOSIZE
cv2.imshow('image',color_image)

#Delay in milliseconds. 0 is the special value that means "forever".
k = cv2.waitKey(0) & 0xFF # 0xFF require for 64-bit machines
if k == 27:         # wait for ESC key to exit
    cv2.destroyAllWindows()
elif k == ord('s'): # wait for unicode of 's' key to save and exit
    cv2.imwrite('./image_output/balloon.jpg',color_image)
    cv2.destroyAllWindows()
else:
    cv2.destroyAllWindows()

print('%s%s' %("Existed with unicode: ", str(k)))

# Plot using matplotlib
plt.imshow(color_image) #, cmap = 'gray', interpolation = 'bicubic'
plt.xticks([]), plt.yticks([])  # to hide tick values on X and Y axis
plt.show()
# Did you see some blurryness in image?

# Color image loaded by OpenCV is in BGR mode. But Matplotlib displays in RGB mode
color_image_rgb = cv2.cvtColor(color_image, cv2.COLOR_BGR2RGB)

show_image([color_image, color_image_rgb], row_plot = 1)

# Note: You can use 'cv2.imwrite' to convert to different format. See the flags 'ImwriteFlags'
# at link https://docs.opencv.org/3.1.0/d4/da8/group__imgcodecs.html
#%% read/display/save video

#What is video: https://giphy.com/gifs/lol-super-bowl-shark-N7WBAaiHUgl6o/fullscreen

# Capture from device index or the name of a video file
capture_video = cv2.VideoCapture(0)

# Define the codec and create VideoWriter object. http://www.fourcc.org/codecs.php
fourcc = cv2.VideoWriter_fourcc(*'DIVX')
out = cv2.VideoWriter('./image_output/video.avi',fourcc,
                      20, # frame per sec
                      (640,480)) # size of video
#Example: frame width and height by capture_video.get(3) and capture_video.get(4). It gives me 640x480 by default.
#To modify it to 320x240. Just use ret = capture_video.set(3,320) and ret = capture_video.set(4,240)

while(capture_video.isOpened()):
    # ret indicates whether or not the frame was captured successfully. If
    # correct, then it's stored in the variable frame.
    ret, frame = capture_video.read()
    #frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    if ret==True:
        #frame = cv2.flip(frame,0) # To flip horizontally

        # write the frame
        out.write(frame)

        cv2.imshow('frame',frame)
        k = cv2.waitKey(1) & 0xFF
        if k == 113 or k == 27: # ord('q') -> 113, Esc -> 27
            break
    else:
        break

# Release everything if job is finished
capture_video.release()
out.release()
cv2.destroyAllWindows()

#Request: Come out of fear of video data :-)

#%% Draw different geometric shapes

#Few common arguments
#img : The image where you want to draw the shapes
#color : Color of the shape. for BGR, pass it as a tuple, eg: (255,0,0) for blue. For grayscale, just pass the scalar value.
#thickness : Thickness of the line or circle etc. If -1 is passed for closed figures like circles,
#it will fill the shape. default thickness = 1
#lineType : Type of line, whether 8-connected, anti-aliased line etc. By default, it is 8-connected.
#cv2.LINE_AA gives anti-aliased line which looks great for curves.

# Create a black image or load any image on which drawing need to be done
img_geo = np.zeros((512,512,3), np.uint8)

#Line: Draw a blue line with thickness of 6 px
img_geo = cv2.line(img_geo,(0,0),(511,511),(255,0,0),6)

#Rectangle (top-left corner and bottom-right corner)
img_geo = cv2.rectangle(img_geo,(384,0),(510,128),(0,255,0),3)

#Circle: center coordinates and radius
img_geo = cv2.circle(img_geo,(447,63), 63, (0,0,255), -1)

#Ellipse
#center location (x,y), axes lengths (major axis length, minor axis length). angle is the angle of
#rotation of ellipse in anti-clockwise direction. startAngle and endAngle denotes the starting and
#ending of ellipse arc measured in clockwise direction from major axis. i.e. giving values 0 and 360
#gives the full ellipse.
img_geo = cv2.ellipse(img_geo,(256,256),(100,50),0,0,360,255,-1)

#Polygon: coordinates of vertices in shape ROWSx1x2 where ROWS are number of vertices
pts = np.array([[10,5],[20,30],[70,20],[50,10]], np.int32)
pts = pts.reshape((-1,1,2))
img_geo = cv2.polylines(img_geo,[pts],
                        True, # If False - get a polylines joining all the points, not a closed shape.
                        (0,255,255))

#cv2.polylines() can be used to draw multiple lines

#Adding Text
#To put texts in images, you need specify following things.
#Position coordinates, Font type, Font Scale and regular things like color, thickness, lineType etc.
#For better look, lineType = cv2.LINE_AA is recommended.

font = cv2.FONT_HERSHEY_SIMPLEX
cv2.putText(img_geo,'Hi OpenCV',(10,500), font, 4,(255,255,255),2,cv2.LINE_AA)

cv2.imshow('image',img_geo)
k = cv2.waitKey(0) & 0xFF # 0xFF require for 64-bit machines
cv2.destroyAllWindows()

#%% Get the points where mouse is clicked

# First see the common attributes of cv2. In particular - various events
events = [i for i in dir(cv2) if 'EVENT' in i]
print(events)

# Create a black image, a window and bind the function to window
my_image = cv2.imread("./image_data/elephant.png", cv2.IMREAD_UNCHANGED)
#my_image = np.zeros((512,512,3), np.uint8)
cv2.namedWindow('my_image')
font = cv2.FONT_HERSHEY_SIMPLEX

# mouse callback function
def event_callback(event,x,y,flags,param):
    if event == cv2.EVENT_LBUTTONDOWN: # get list of events as explained above
        print('%s%s%s' %(str(x),', ', str(y)))
        cv2.putText(my_image,str(x) + ', ' + str(y),(x,y), font, 1,(255,255,255),2,cv2.LINE_AA)

    return

#Bind the function to window
cv2.setMouseCallback('my_image', event_callback)

while(True):
    cv2.imshow('my_image',my_image)
    if cv2.waitKey(10) & 0xFF == 27:
        break

cv2.destroyAllWindows()

# CW: Click at two different points and draw rectangle
#%% Write on each frame of Video
capture_video = cv2.VideoCapture('./image_data/horse.mp4')
sz = (int(capture_video.get(cv2.CAP_PROP_FRAME_WIDTH)), int(capture_video.get(cv2.CAP_PROP_FRAME_HEIGHT)))
print('WxH is: ',sz)

# Define the codec and create VideoWriter object. http://www.fourcc.org/codecs.php
fourcc = cv2.VideoWriter_fourcc(*'mp4v') # for avi - DIVX, mp4 - mp4v
out = cv2.VideoWriter('./image_output/horse_text.mp4',fourcc, int(capture_video.get(cv2.CAP_PROP_FPS)), sz, True)

count = 0
(label_width, label_height), baseline = cv2.getTextSize(str(count), cv2.FONT_HERSHEY_PLAIN, 3, 2)
print('lw, lh is ', label_width, label_height)

while(capture_video.isOpened()):
    ret, frame = capture_video.read()
    #frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    if ret==True:
        # write the frame
        cv2.putText(frame, str(count), (sz[0]-100, sz[1]-100), cv2.FONT_HERSHEY_PLAIN, 3, (0,0,0), 3, cv2.LINE_AA)
        out.write(frame)

    else:
        break
    count = count + 1

# Release everything if job is finished
capture_video.release()
out.release()
cv2.destroyAllWindows()

#%% Playing with color. It was also discusssed with skimage

# Let us read one image
my_image_color = cv2.imread('./image_data/elephant.png')
cv2.imshow('image',my_image_color); cv2.waitKey(0); cv2.destroyAllWindows()

#How to get any color, say green
cv2.imshow('image',my_image_color[:,:,1]); cv2.waitKey(0); cv2.destroyAllWindows()
#Nope

#How to get?? Discussion ppt

# Convert BGR to HSV
my_image_color_hsv = cv2.cvtColor(my_image_color,cv2.COLOR_BGR2HSV)

# define range of blue color in HSV
#green = np.uint8([[[0,255,0 ]]])
#hsv_green = cv2.cvtColor(green,cv2.COLOR_BGR2HSV)
#hsv_green # [[[ 60 255 255]]] Now use 60-30 & 60+30
# Also see the links
# http://answers.opencv.org/question/100647/how-to-remove-green-color-ie-to-set-it-to-0-in-an-image/
# https://stackoverflow.com/questions/10948589/choosing-the-correct-upper-and-lower-hsv-boundaries-for-color-detection-withcv

lower_range = np.array([30,0,0]); upper_range = np.array([90,255,255])

# Threshold the HSV image to get only blue colors
mask = cv2.inRange(my_image_color_hsv, lower_range, upper_range)
cv2.imshow('image',mask); cv2.waitKey(0); cv2.destroyAllWindows()

# Now get green color only
my_image_color_hsv_green = cv2.bitwise_and(my_image_color,my_image_color,mask = mask)
cv2.imshow('image',my_image_color_hsv_green); cv2.waitKey(0); cv2.destroyAllWindows()

# Now get NON green color only
my_image_color_hsv_NON_green = cv2.bitwise_not(my_image_color,my_image_color,mask = mask)
cv2.imshow('image',my_image_color_hsv_NON_green); cv2.waitKey(0); cv2.destroyAllWindows()

#CW: How to make improvement

#%% Various transformations
# Theory on ppt

#Euclidean transformations - preserve length and angle measures. All planes/square will
#remain planes/square

#Affine transformations(generalizations of Euclidean transformations) don't preserve lengths
#and angles. Use 'cv2.getAffineTransform' and 'cv2.warpAffine' to map source image to
#destination image(tilded/skewed/mirror)

# Let us read one image
my_image_color = cv2.imread('./image_data/elephant.png')
cv2.imshow('image',my_image_color); cv2.waitKey(0); cv2.destroyAllWindows()

# get w & h
h, w = my_image_color.shape[:2]

# Define source and destination points
trans_src_points = np.float32([[0,0], [w-1,0], [0,h-1]])
trans_dst_points = np.float32([[int(w/2),0], [w-1,0], [0,h-1]])

# Do the transformations
affine_matrix = cv2.getAffineTransform(trans_src_points, trans_dst_points)
my_image_affine = cv2.warpAffine(my_image_color, affine_matrix, (w,h))
cv2.imshow('image',my_image_affine); cv2.waitKey(0); cv2.destroyAllWindows()

# CW: Play with different set of coordinates


from scrapy.settings import CrawlerSettings
from scrapy.crawler import CrawlerProcess

spider_example_name = 'news_spider'

appname = 'openshift'

os.environ.setdefault('SCRAPER_SETTINGS_MODULE', '{0}.scraper.settings'.format(appname))
scrapy_settings_model = __import__(os.getenv('SCRAPER_SETTINGS_MODULE'), fromlist=[''])

settings = CrawlerSettings(scrapy_settings_model)
prs = CrawlerProcess(settings)
crawler = prs.create_crawler()
for name, spd in crawler.spiders._spiders.iteritems():
    if name == spider_example_name:
        spidercls = spd
crawler.crawl(spidercls(id=1))
prs.start()


#!/usr/bin/env python3
import sys
import time
import click
import pickle
import signal
from requests.compat import urljoin

from prometheus_client import start_http_server
from prometheus_client.core import REGISTRY

from ecs_container_exporter import utils
from ecs_container_exporter.utils import create_metric
from ecs_container_exporter.cpu_metrics import calculate_cpu_metrics
from ecs_container_exporter.memory_metrics import calculate_memory_metrics
from ecs_container_exporter.io_metrics import calculate_io_metrics
from ecs_container_exporter.network_metrics import calculate_network_metrics

import logging
log = logging.getLogger(__name__)

class ECSContainerExporter(object):

    include_containers = []
    exclude_containers = []
    # 1 - healthy, 0 - unhealthy
    exporter_status = 1
    # initial task metrics that do not change
    static_task_metrics = []
    # individual container tags
    task_container_tags = {}
    # task limits
    task_cpu_limit = 0
    task_mem_limit = 0
    # individual container limits
    task_container_limits = {}
    # the Task level metrics are included by default
    include_container_ids = [utils.TASK_CONTAINER_NAME_TAG]
    # stats are collected and aggregated across this interval
    # default to 55s for scrape_interval and scrape_timeout of 1m
    # should be set to 60 when using statsd, which doesn't have this issue
    interval = 55

    def __init__(self, metadata_url=None, include_containers=None, exclude_containers=None, interval=55, http_timeout=60):

        self.task_metadata_url = urljoin(metadata_url + '/', 'task')
        # For testing
        # self.task_stats_url = urljoin(metadata_url + '/', 'stats')
        self.task_stats_url = urljoin(metadata_url + '/', 'task/stats')

        if exclude_containers:
            self.exclude_containers = exclude_containers
        if include_containers:
            self.include_containers = include_containers

        self.interval = interval
        self.http_timeout = http_timeout

        self.log = logging.getLogger(__name__)
        # cacheing mainly for statsd metric type, since prometheus will run this
        # only once its lifetime
        self.cache_file_path = '/tmp/ecs-container-exporter.cache'
        self.collect_static_metrics()

    def start_prometheus_eporter(self, exporter_port):
        self.log.info(f'Exporter initialized with '
                      f'metadata_url: {self.task_metadata_url}, '
                      f'task_stats_url: {self.task_stats_url}, '
                      f'http_timeout: {self.http_timeout}, '
                      f'include_containers: {self.include_containers}, '
                      f'exclude_containers: {self.exclude_containers}')

        REGISTRY.register(self)
        # Start exporter http service
        start_http_server(int(exporter_port))
        while True:
            time.sleep(10)

    def send_statsd_metrics(self, statsd_host, statsd_port):
        utils.init_statsd_client(statsd_host, statsd_port)
        for metric in self.collect_all_metrics():
            utils.send_statsd(metric)

    def cache_load_task_metadata(self):
        try:
            with open(self.cache_file_path, 'rb') as cf:
                return pickle.load(cf)
        except FileNotFoundError:
            pass

        return None

    def cache_write_task_metadata(self, data):
        with open(self.cache_file_path, 'wb') as cf:
            pickle.dump(data, cf)

    def collect_static_metrics(self):
        metadata = self.cache_load_task_metadata()
        if metadata:
            self.log.debug(f'Using cached task metadata response from {self.cache_file_path}')
        else:
            retries = 24
            while True and retries > 0:
                # wait for the task to be in running state
                time.sleep(5)
                retries -= 1
                try:
                    metadata = utils.ecs_task_metdata(self.task_metadata_url, self.http_timeout)
                    self.cache_write_task_metadata(metadata)
                except Exception as e:
                    self.exporter_status = 0
                    self.log.exception(e)
                    continue

                if metadata.get('KnownStatus') != 'RUNNING':
                    self.log.warning(f'ECS Task not yet in RUNNING state, current status is: {metadata["KnownStatus"]}')
                    continue
                else:
                    break

            self.exporter_status = 1

        self.log.debug(f'Discovered Task metadata: {metadata}')
        self.parse_task_metadata(metadata)

    def parse_task_metadata(self, metadata):
        self.static_task_metrics = []
        self.task_container_tags = {}
        self.task_container_limits = {}

        # task cpu/mem limit
        task_tag = utils.task_metric_tags()
        self.task_cpu_limit, self.task_mem_limit = self.cpu_mem_limit(metadata, normalise_cpu=True)

        metric = create_metric('cpu_limit', self.task_cpu_limit, task_tag, 'gauge', 'Task CPU limit')
        self.static_task_metrics.append(metric)

        metric = create_metric('mem_limit', self.task_mem_limit, task_tag, 'gauge', 'Task Memory limit')
        self.static_task_metrics.append(metric)

        # container tags and limits
        for container in metadata['Containers']:
            container_id = container['DockerId']
            container_name = container['Name']

            if self.should_process_container(container_name,
                                             self.include_containers,
                                             self.exclude_containers):
                self.log.info(f'Processing stats for container: {container_name} - {container_id}')
                self.include_container_ids.append(container_id)
            else:
                self.log.info(f'Excluding container: {container_name} - {container_id} as per exclusion')

            self.task_container_tags[container_id] = {'container_name': container_name}

            # container cpu/mem limit
            cpu_value, mem_value = self.cpu_mem_limit(container)
            self.task_container_limits[container_id] = {'cpu': cpu_value, 'mem': mem_value}

            if container_id in self.include_container_ids:
                metric = create_metric('cpu_limit', cpu_value, self.task_container_tags[container_id],
                                       'gauge', 'Limit in percent of the CPU usage')
                self.static_task_metrics.append(metric)

                metric = create_metric('mem_limit', mem_value, self.task_container_tags[container_id],
                                       'gauge', 'Limit in memory usage in MBs')
                self.static_task_metrics.append(metric)

    def should_process_container(self, container_name, include_containers, exclude_containers):
        if container_name in exclude_containers:
            return False
        else:
            if include_containers:
                if container_name in include_containers:
                    return True
                else:
                    return False
            else:
                return True

    def cpu_mem_limit(self, metadata, normalise_cpu=False):
        # normalise to `cpu shares`
        cpu_limit = metadata.get('Limits', {}).get('CPU', 0) * (1024 if normalise_cpu else 1)
        mem_limit = metadata.get('Limits', {}).get('Memory', 0)

        return (
            cpu_limit, mem_limit
        )

    # All metrics are collected here
    def collect_all_metrics(self):
        container_metrics = self.collect_container_metrics()

        # exporter status metric
        metric = create_metric('exporter_status', self.exporter_status, {},
                               'gauge', 'Exporter Status')
        container_metrics.append(metric)

        return self.static_task_metrics + container_metrics

    # prometheus exporter collect function
    def collect(self):
        for metric in self.collect_all_metrics():
            yield utils.create_prometheus_metric(metric)

    def collect_container_metrics(self):
        metrics = []
        docker_stats = []
        # collect two stats samples as per the configured interval
        try:
            docker_stats.append(
                utils.ecs_task_metdata(self.task_stats_url, self.http_timeout)
            )
            # ECS stats API returns immediately, but docker stats waits for 1s adjust this accordingly
            time.sleep(self.interval)

            docker_stats.append(
                utils.ecs_task_metdata(self.task_stats_url, self.http_timeout)
            )
            if not all(docker_stats):
                raise Exception('Some stats are empty, try again')

            self.exporter_status = 1

        except Exception as e:
            self.exporter_status = 0
            self.log.exception(e)
            return metrics

        container_metrics_all = self.parse_container_metadata(docker_stats,
                                                              self.task_cpu_limit,
                                                              self.task_container_limits,
                                                              self.task_container_tags)

        # flatten and filter excluded containers
        filtered_container_metrics = []
        for metrics_by_container in container_metrics_all:
            for container_id, metrics in metrics_by_container.items():
                if container_id in self.include_container_ids:
                    filtered_container_metrics.extend(metrics)

        return filtered_container_metrics

    def parse_container_metadata(self, docker_stats, task_cpu_limit,
                                 task_container_limits, task_container_tags):
        """
        More details on the exposed docker metrics
        https://github.com/moby/moby/blob/c1d090fcc88fa3bc5b804aead91ec60e30207538/api/types/stats.go

        """
        container_metrics_all = []

        # ignore stats for containers in STOPPED state
        for container_id in list(docker_stats[1].keys()):
            if not docker_stats[1][container_id]:
                del(docker_stats[0][container_id])
                del(docker_stats[1][container_id])
                self.log.debug(f'Ignoring null stats for container_id {container_id}')

        try:
            # CPU metrics
            container_metrics_all.append(
                calculate_cpu_metrics(docker_stats,
                                      task_cpu_limit,
                                      task_container_limits,
                                      task_container_tags)
            )

            # Memory metrics
            container_metrics_all.append(
                calculate_memory_metrics(docker_stats[1], task_container_tags)
            )

            # I/O metrics
            container_metrics_all.append(
                calculate_io_metrics(docker_stats[1], task_container_tags)
            )

            # network metrics
            container_metrics_all.append(
                calculate_network_metrics(docker_stats[1], task_container_tags)
            )

        except Exception as e:
            self.log.warning("Could not retrieve metrics for {}: {}".format(task_container_tags, e), exc_info=True)
            self.exporter_status = 1

        return container_metrics_all

def shutdown(sig_number, frame):
    log.info("Recevied signal {}, Shuttting down".format(sig_number))
    sys.exit(0)

@click.command()
@click.option('--metadata-url', envvar='ECS_CONTAINER_METADATA_URI', type=str, default=None,
              help='Override ECS Metadata Url')
@click.option('--exporter-port', envvar='EXPORTER_PORT', type=int, default=9545,
              help='Change exporter listen port')
@click.option('--use-statsd', envvar='USE_STATSD', is_flag=True, type=bool, default=False,
              help='Emit metrics to statsd instead of starting Prometheus exporter')
@click.option('--statsd-host', envvar='STATSD_HOST', type=str, default='localhost',
              help='Override Stasd Host')
@click.option('--statsd-port', envvar='STATSD_PORT', type=int, default=8125,
              help='Override Stasd Port')
@click.option('--include', envvar='INCLUDE', type=str, default=None,
              help='Comma seperated list of container names to include, or use env var INCLUDE')
@click.option('--exclude', envvar='EXCLUDE', type=str, default=None,
              help='Comma seperated list of container names to exclude, or use env var EXCLUDE')
@click.option('--interval', envvar='INTERVAL', type=int, default=55,
              help='Stats collection and aggregation interval in seconds (specifically for CPU stats)')
@click.option('--log-level', envvar='LOG_LEVEL', type=str, default='INFO',
              help='Log level, default: INFO')
def main(
    metadata_url=None, exporter_port=9545, use_statsd=False, statsd_port=8125, statsd_host='localhost',
    include=None, exclude=None, interval=55, log_level='INFO'
):
    if not metadata_url:
        sys.exit('AWS environment variable ECS_CONTAINER_METADATA_URI not found '
                 'nor is --metadata-url set')

    signal.signal(signal.SIGTERM, shutdown)
    signal.signal(signal.SIGINT, shutdown)

    logging.basicConfig(
        format='%(asctime)s:%(levelname)s:%(message)s',
    )
    logging.getLogger().setLevel(
        getattr(logging, log_level.upper())
    )

    if exclude:
        exclude=exclude.strip().split(',')
    if include:
        include=include.strip().split(',')

    collector = ECSContainerExporter(metadata_url=metadata_url,
                                     include_containers=include,
                                     exclude_containers=exclude,
                                     interval=interval)

    if use_statsd:
        collector.send_statsd_metrics(statsd_host, statsd_port)
    else:
        collector.start_prometheus_eporter(exporter_port)

if __name__ == '__main__':
    main()


from django.db.migrations import serializer
from django_redis import get_redis_connection
from redis import RedisError
from requests import Response
from rest_framework import serializers
import logging
# import RedisError

logger = logging.getLogger("django")

class SmsCodeSerializer(serializers.Serializer):
    """定义序列化器"""

    # 手机号在路径的正则表达式校验过
    image_code_id = serializers.UUIDField()
    text = serializers.CharField(min_length=4,max_length=4)

    def validate(self, attrs):
        """进行验证码校验"""
        # 获取参数
        image_code_id = attrs["image_code_id"]
        text = attrs["text"]
        # 根据随机编码获取验证码
        rediscn= get_redis_connection("verify_codes")
        # try:
        real_text = rediscn.get("img_%s" % image_code_id)
        # except Exception as ret:
        #     raise serializers.ValidationError("数据库获取图片验证码错误")

        if not real_text:
            # 过期或者不存在
            raise serializers.ValidationError("无效的图片验证码")

        # 对比
        #　redis 储存的是二进制字节码，需要进行解码
        real_text = real_text.decode()
        if real_text.lower()!=text.lower():
            raise serializers.ValidationError("图片验证码错误")
        try:
            # 删除redis中的图片验证码，防止多次请求验证
            rediscn.delete("img_%s"% image_code_id)
        except RedisError as ret:
            logger.error(ret)

        # 是否发送过短信标志
        # mobile = self.context["view"].kwargs["mobile"]
        # 使用get 方法找参数加入找不到不会报错。
        mobile = self.context["view"].kwargs.get("mobile")

        if mobile:
            sms_flag = rediscn.get("send_flag_%s"%mobile)

            if sms_flag:
                raise serializers.ValidationError("请求手机验证码过于频繁")
        return attrs


from collections import deque
from collections.abc import Mapping
from itertools import product, chain, repeat

from added_value.items_table_directive import NonStringIterable
from added_value.multisort import tuplesorted
from added_value.sorted_frozen_set import SortedFrozenSet
from added_value.toposet import TopoSet
from added_value.util import unchain, empty_iterable

depth_marker = object()
ROOT = object()
LEAF = object()

_UNSET = object()

def breadth_first(obj, leaves=False):
    queue = deque()
    queue.append(obj)
    queue.append(None)
    level_keys = []
    current_level_keys = TopoSet()
    while len(queue) > 0:
        node = queue.popleft()
        if node is None:
            level_keys.append(current_level_keys)
            current_level_keys = TopoSet()
            queue.append(None)
            if queue[0] is None:
                break
            else:
                continue
        if isinstance(node, Mapping):
            current_level_keys.update(node.keys())
            for value in node.values():
                queue.append(value)
        elif isinstance(node, NonStringIterable):
            current_level_keys.update(range(len(node)))
            for value in node:
                queue.append(value)
        else:
            if leaves:
                current_level_keys.add(node)

    return [
        list(s) for s in level_keys[:-1]
    ]  # Why the slice? Remove leaves? Is the last always empty?

class Missing(object):
    def __str__(self):
        return ""

    def __repr__(self):
        return self.__class__.__name__

MISSING = Missing()

def tabulate_body(
    obj,
    level_keys,
    v_level_indexes,
    h_level_indexes,
    v_level_sort_keys=None,
    h_level_sort_keys=None,
):
    """
    Args:
        v_level_indexes: A sequence of level indexes.
        h_level_indexes: A sequence of level indexes.
    """
    v_key_sorted = make_sorter(v_level_sort_keys, v_level_indexes)
    h_key_sorted = make_sorter(h_level_sort_keys, h_level_indexes)

    h_level_keys = [level_keys[level] for level in h_level_indexes]
    v_level_keys = [level_keys[level] for level in v_level_indexes]

    h_key_tuples = h_key_sorted(product(*h_level_keys))
    v_key_tuples = v_key_sorted(product(*v_level_keys))

    h_size = len(h_key_tuples)
    v_size = len(v_key_tuples)

    table = [[MISSING for _ in range(h_size)] for _ in range(v_size)]

    for h_index, h_keys in enumerate(h_key_tuples):
        for v_index, v_keys in enumerate(v_key_tuples):
            key_path = [None] * len(level_keys)
            merge_into_by_index(key_path, h_level_indexes, h_keys)
            merge_into_by_index(key_path, v_level_indexes, v_keys)
            for v_level, v_key in zip(v_level_indexes, v_keys):
                key_path[v_level] = v_key

            item = obj
            for key in key_path:
                try:
                    item = item[key]
                except (IndexError, KeyError):
                    break
            else:  # no-break
                table[v_index][h_index] = item

    return table, v_key_tuples, h_key_tuples

def make_sorter(level_sort_keys, level_indexes):
    if level_sort_keys is not None:
        if len(level_sort_keys) != len(level_indexes):
            raise ValueError(
                "level_sort_keys with length {} does not correspond to level_indexes with length {}".format(
                    len(level_sort_keys), len(level_indexes)
                )
            )

        def key_sorted(level_keys):
            return tuplesorted(level_keys, *level_sort_keys)

    else:
        key_sorted = list
    return key_sorted

def strip_missing_rows(table, row_keys):
    stripped_table = []
    stripped_v_key_tuples = []
    for row, v_key_tuple in zip(table, row_keys):
        if any(cell is not MISSING for cell in row):
            stripped_table.append(list(row))
            stripped_v_key_tuples.append(v_key_tuple)
    return stripped_table, stripped_v_key_tuples

def strip_missing_columns(table, h_key_tuples):
    transposed_table = transpose(table)
    stripped_transposed_table, stripped_h_key_tuples = strip_missing_rows(
        transposed_table, h_key_tuples
    )
    stripped_table = transpose(stripped_transposed_table)
    return stripped_table, stripped_h_key_tuples

def merge_into_by_index(sequence, indexes, values):
    for index, value in zip(indexes, values):
        sequence[index] = value

def is_rectangular(seq_of_seqs):
    return len(set(map(len, seq_of_seqs))) <= 1

def size_h(rows_of_columns):
    try:
        first_row = rows_of_columns[0]
    except IndexError:
        return 0
    else:
        return len(first_row)

def size_v(rows_of_columns):
    return sum(1 for row in rows_of_columns if len(row) != 0)

def size(rows_of_columns):
    return size_v(rows_of_columns), size_h(rows_of_columns)

def transpose(rows_of_columns):
    return list(map(list, zip(*rows_of_columns)))

def assemble_table(
    table_body, v_key_tuples, h_key_tuples, v_level_titles=None, h_level_titles=None, empty=""
):
    if not is_rectangular(table_body):
        raise ValueError("table_body {} is not rectangular".format(table_body))
    if not is_rectangular(v_key_tuples):
        raise ValueError("v_key_tuples {} is not rectangular".format(v_key_tuples))
    if not is_rectangular(h_key_tuples):
        raise ValueError("h_key_tuples {} is not rectangular".format(h_key_tuples))
    if size_v(v_key_tuples) > 0 and (size_v(table_body) != size_v(v_key_tuples)):
        raise ValueError("table body and v_key_tuples have incompatible dimensions")
    h_key_tuples_transposed = transpose(h_key_tuples)
    if size_h(h_key_tuples_transposed) > 0 and (
        size_h(table_body) != size_h(h_key_tuples_transposed)
    ):
        raise ValueError("table body and h_key_tuples have incompatible dimensions")

    if (v_level_titles is not None) and (len(v_level_titles) != size_h(v_key_tuples)):
        raise ValueError("v_level_titles and v_key_tuples have incompatible dimensions")

    if (h_level_titles is not None) and (len(h_level_titles) != size_v(h_key_tuples_transposed)):
        raise ValueError("h_level_titles and h_key_tuples have incompatible dimensions")

    boxed_h_level_titles = (
        unchain(h_level_titles)
        if (h_level_titles is not None)
        else repeat(empty_iterable(), size_v(h_key_tuples_transposed))
    )

    num_h_level_title_columns = int(bool(h_level_titles))
    num_stub_columns = max(size_h(v_key_tuples), num_h_level_title_columns)
    table = []

    num_empty_columns = num_stub_columns - num_h_level_title_columns
    for boxed_h_level_title, h_key_row in zip(boxed_h_level_titles, h_key_tuples_transposed):
        row = list(chain(repeat(" ", num_empty_columns), boxed_h_level_title, h_key_row))
        table.append(row)

    if v_level_titles is not None:
        v_level_titles_row = v_level_titles + [empty] * size_h(table_body)
        table.append(v_level_titles_row)

    for v_key_row, table_row in zip(v_key_tuples, table_body):
        row = list(v_key_row)
        row.extend(table_row)
        table.append(row)

    assert is_rectangular(table)
    return table

def tabulate(
    obj,
    v_level_indexes=None,
    h_level_indexes=None,
    v_level_visibility=None,
    h_level_visibility=None,
    v_level_sort_keys=None,
    h_level_sort_keys=None,
    v_level_titles=None,
    h_level_titles=None,
    empty="",
):
    """Render a nested data structure into a two-dimensional table.

    Args:
        obj: The indexable data structure to be rendered, which can
            either be a non-string sequence or a mapping containing other
            sequences and mappings nested to arbitrarily many levels,
            with all the leaf items (which are neither sequences nor
            mappings, excluding strings).

        v_level_indexes: An iterable of the zero-based indexes of
            the levels for which the keys/indexes will be displayed
            along the vertical axis of the table. Taken together
            with the levels in h_levels these must represent the
            complete set of levels in the obj data structure. No
            level index should appear in both v_level_indexes and
            h_level_indexes, but all level indexes must appear in
            either v_level_indexes or h_level_indexes. If None,
            the levels not used in h_level_indexes will be used.
            If both v_level_indexes and h_level_indexes are not
            alternate indexes will be used as v_level and h_level
            indexes.

        h_level_indexes: An iterable of the zero-based indexes of
            the levels for which the keys/indexes will be displayed
            along the horizontal axis of the table. Taken together
            with the levels in v_levels these must represent the
            complete set of levels in the obj data structure. No
            level index should appear in both h_level_indexes and
            v_level_indexes, but all level indexes must appear in
            either h_level_indexes or v_level_indexes. If None,
            the levels not used in v_level_indexes will be used.
            If both v_level_indexes and h_level_indexes are not
            alternate indexes will be used as v_level and h_level
            indexes.

        v_level_visibility: An optional iterable of booleans, where each
            item corresponds to a level in v_level_indexes, and
            controls whether than level of index is included in
            the table stub columns. This iterable must contain
            the same number of items as v_level_indexes.

        h_level_visibility: An optional iterable of booleans, where each
            item corresponds to a level in h_level_indexes, and
            controls whether than level of index is included in
            the table header rows. This iterable must contain
            the same number of items as h_level_indexes.

        v_level_sort_keys: An optional iterable of Keys, where each
            key corresponds to a level in v_level_indexes, and
            controls how that key is sorted. If None, keys are sorted
            as-is.

        h_level_sort_keys: An optional iterable of Keys, where each
            key corresponds to a level in v_level_indexes, and
            controls how that key is sorted. If None, keys are sorted
            as-is.

        v_level_titles: An optional iterable of strings, where each
            string is a title which corresponds to a level in v_level_indexes,
            and which will be displayed against the row keys for that level.
            If None, no titles will be included.

        h_level_titles: An optional iterable of strings, where each
            string is a title which corresponds to a level in h_level_indexes,
            and which will be displayed against the column keys for that level.
            If None, no titles will be included.

        empty: An optional string value to use for empty cells.

    Returns:
        A list of lists representing the rows of cells.

    Example:

        tabulate(dict_of_dicts, [0, 1], [])

    """
    level_keys = breadth_first(obj)

    v_level_indexes, h_level_indexes = validate_level_indexes(
        len(level_keys), v_level_indexes, h_level_indexes
    )

    if v_level_visibility is None:
        v_level_visibility = [True] * len(v_level_indexes)
    if h_level_visibility is None:
        h_level_visibility = [True] * len(h_level_indexes)

    table, v_key_tuples, h_key_tuples = tabulate_body(
        obj, level_keys, v_level_indexes, h_level_indexes, v_level_sort_keys, h_level_sort_keys
    )

    table, v_key_tuples = strip_missing_rows(table, v_key_tuples)
    table, h_key_tuples = strip_missing_columns(table, h_key_tuples)
    v_key_tuples = strip_hidden(v_key_tuples, v_level_visibility)
    h_key_tuples = strip_hidden(h_key_tuples, h_level_visibility)
    return assemble_table(
        table, v_key_tuples, h_key_tuples, v_level_titles, h_level_titles, empty=empty
    )

def validate_level_indexes(num_levels, v_level_indexes, h_level_indexes):
    """Ensure that v_level_indexes and h_level_indexes are consistent.

    Args:
        num_levels: The number of levels of keys in the data structure being tabulated.
        v_level_indexes: A sequence of level indexes between zero and num_levels for
            the vertical axis, or None.
        h_level_indexes: A sequence of level indexes between zero and num_levels for for
            the horizontal axis, or None.

    Returns:
        A 2-tuple containing v_level_indexes and h_level_indexes sequences.

    Raises:
        ValueError: If v_level_indexes contains duplicate values.
        ValueError: If h_level_indexes contains duplicate values.
        ValueError: If v_level_indexes contains out of range values.
        ValueError: If h_level_indexes contains out of range values.
        ValueError: If taken together v_level_indexes and h_level_indexes
            do not include all levels from zero to up to, but not including
            num_levels.
        ValueError: If v_level_indexes and h_level_indexes have items in
            common.
    """
    if num_levels < 1:
        raise ValueError("num_levels {} is less than one".format(num_levels))

    all_levels = SortedFrozenSet(range(num_levels))

    if (h_level_indexes is None) and (v_level_indexes is None):
        v_level_indexes = range(0, num_levels, 2)
        h_level_indexes = range(1, num_levels, 2)

    h_level_set = SortedFrozenSet(h_level_indexes)
    v_level_set = SortedFrozenSet(v_level_indexes)

    if h_level_indexes is None:
        h_level_indexes = all_levels - v_level_set
    if v_level_indexes is None:
        v_level_indexes = all_levels - h_level_set

    if len(h_level_indexes) != len(h_level_set):
        raise ValueError("h_level_indexes contains duplicate values")
    if h_level_set and ((h_level_set[0] < 0) or (h_level_set[-1] >= num_levels)):
        raise ValueError("h_level_indexes contains out of range values")
    if len(v_level_indexes) != len(v_level_set):
        raise ValueError("v_level_indexes contains duplicate values")
    if v_level_set and ((v_level_set[0] < 0) or (v_level_set[-1] >= num_levels)):
        raise ValueError("v_level_indexes contains out of range values")

    unmentioned_levels = all_levels - v_level_set - h_level_set
    if len(unmentioned_levels) > 0:
        raise ValueError(
            "v_level_indexes and h_level_indexes do not together include levels {}".format(
                ", ".join(map(str, unmentioned_levels))
            )
        )
    if not h_level_set.isdisjoint(v_level_set):
        raise ValueError("h_level_indexes and v_level_indexes are not disjoint")
    v_level_indexes = list(v_level_indexes)
    h_level_indexes = list(h_level_indexes)
    return v_level_indexes, h_level_indexes

def strip_hidden(key_tuples, visibilities):
    """Filter each tuple according to visibility.

    Args:
        key_tuples: A sequence of tuples of equal length (i.e. rectangular)
        visibilities: A sequence of booleans equal in length to the tuples contained in key_tuples.

    Returns:
        A sequence equal in length to key_tuples where the items are tuples with a length corresponding
        to the number of items in visibility which are True.
    """
    result = []
    for key_tuple in key_tuples:
        if len(key_tuple) != len(visibilities):
            raise ValueError(
                "length of key tuple {} is not equal to length of visibilities {}".format(
                    key_tuple, visibilities
                )
            )
        filtered_tuple = tuple(item for item, visible in zip(key_tuple, visibilities) if visible)
        result.append(filtered_tuple)
    return result

# TODO: Multidimensional arrays. e.g. ndarray


# coding=utf-8
from django.shortcuts import render, get_object_or_404
from users.forms import UserRegisterForm, UserLoginForm
from django.utils import timezone
from users.models import CustomUser
from follow.models import Follower
from event.models import Event

# Create your views here.

def channel(request, channel_url):
	"""
	channel page
	that show all event for specific channel
	user_own : is user that has a this channel page
	"""
	now = timezone.now().date()
	user_own = get_object_or_404(CustomUser, channel_name=channel_url)  # wrap user from event

	try:  # this check if request.user follow user that own this channel page or not
		if user_own.followers.get(follower=request.user):
			follow_state = 'دنبال شده'
	except:
		follow_state = 'دنبال کردن'

	if Event.objects.filter(channel=user_own).exists():  # check user have event or n
		future_event = user_own.event_set.filter(pub_date__gte=now)  # event in future
		past_event = user_own.event_set.filter(pub_date__lt=now)  # event in past
	else:
		future_event = None
		past_event = None

	context = {
		'fea_event': future_event,  # future event
		'past_event': past_event,  # past event
		'usercreate': UserRegisterForm,  # register form
		'userlogin': UserLoginForm,  # login form
		'follower': Follower,  # follower model that has a following system
		'user_own': user_own,  # user_own is a user that have this channel page
		'follow_state': follow_state  # this is a variable to tell us request user is following with user_own or not
	}
	return render(request, 'channel/channel.html', context)


import tensorflow as tf
import json
import numpy as np

class TFReader:
    def __init__(self,
                 path_tfrecords_train: [],
                 path_tfrecords_test: [],
                 path_metadata: str,
                 num_labels: int,
                 batch_size: int=16,
                 buffer_size: int=10000,
                 scale_factor: int=10000,
                 seed: int=10,
                 num_epochs: int = 1
                 ):
        self._path_tfrecords_train = path_tfrecords_train
        self._path_tfrecords_test = path_tfrecords_test
        self._meta = path_metadata
        self._batch_size = batch_size
        self._buffer_size = buffer_size
        self._scale_factor = scale_factor
        self._num_labels = num_labels
        self._seed = seed
        self._num_epochs = num_epochs

        self.train_input_fn = self._input_fn(self, filenames=self._path_tfrecords_train, train=True, val=False)
        self.test_input_fn = self._input_fn(self, filenames=self._path_tfrecords_test, train=False, val=False)
        self.val_input_fn = self._input_fn(self, filenames=self._path_tfrecords_test, train=False, val=True)

        _read_meta = {
            'train': self._path_tfrecords_train,
            'test': self._path_tfrecords_test,
            'batch_size': self._batch_size,
            'buffer_size': self._buffer_size
        }

        json_path = "read_params.json"
        with open(json_path, "w") as op:
            json.dump(_read_meta, op)

    @staticmethod
    def make_labels(input_func, batch_size: int, num_labels: int):
        next_batch = input_func.make_one_shot_iterator().get_next()
        # test_labels = np.empty(shape=(batch_size, num_labels))
        config = tf.ConfigProto(
            device_count={'GPU': 0}
        )
        firsttime = True
        with tf.Session(config=config) as sess:
            while True:

                if firsttime:
                    firsttime=False
                    batch = sess.run(next_batch)
                    test_labels = batch[1]
                else:
                    try:
                        batch = sess.run(next_batch)
                        test_labels = np.concatenate((test_labels, batch[1]), axis=0)
                    except tf.errors.OutOfRangeError:
                        break
        return test_labels

    @staticmethod
    def _input_fn(self, filenames, train: bool, val: bool=False):
        # Args:
        # filenames:   Filenames for the TFRecords files.
        # train:       Boolean whether training (True) or testing (False).
        # batch_size:  Return batches of this size.
        # buffer_size: Read buffers of this size. The random shuffling
        #              is done on the buffer, so it must be big enough.

        # Create a TensorFlow Dataset-object which has functionality
        # for reading and shuffling data from TFRecords files.
        dataset = tf.data.TFRecordDataset(filenames=filenames)

        # Parse the serialized data in the TFRecords files.
        # This returns TensorFlow tensors for the image and labels.
        dataset = dataset.map(self._parse)

        if train:
            # If training then read a buffer of the given size and
            # randomly shuffle it.
            # dataset = dataset.shuffle(buffer_size=self._buffer_size)

            # this will only shuffle the buffer which is read in sequentially
            # set buffer size high to get a proper shuffle on as much of the data as you can handle
            # in ram
            dataset = dataset.apply(
                tf.contrib.data.shuffle_and_repeat(
                    buffer_size=self._buffer_size,
                    count=None,
                    seed=self._seed
                )
            )

            # Allow infinite reading of the data.
            # num_repeat = None
        else:
            # If testing then don't shuffle the data.
            # Using the data for validation, so needs to repeat num_epoch times
            if val:
                dataset = dataset.repeat(count=self._num_epochs)
            else:
                dataset = dataset.repeat(count=1)

        # Get a batch of data with the given size.
        dataset = dataset.batch(self._batch_size)

        return dataset

    @staticmethod
    def _parse(serialized):
        # Define a dict with the data-names and types we expect to
        # find in the TFRecords file.
        # It is a bit awkward that this needs to be specified again,
        # because it could have been written in the header of the
        # TFRecords file instead.
        features = \
            {
                'under1': tf.FixedLenFeature([5120], tf.float32),
                'under2': tf.FixedLenFeature([5120], tf.float32),
                'over1': tf.FixedLenFeature([5120], tf.float32),
                'a_open': tf.FixedLenFeature([1], tf.int64),
                'b_open': tf.FixedLenFeature([1], tf.int64),
                'c_open': tf.FixedLenFeature([1], tf.int64),
                'd_open': tf.FixedLenFeature([1], tf.int64),
                'e_open': tf.FixedLenFeature([1], tf.int64),
                'f_open': tf.FixedLenFeature([1], tf.int64),
                'pressure': tf.FixedLenFeature([1], tf.float32),
                'flow_rate': tf.FixedLenFeature([1], tf.float32),
                'density': tf.FixedLenFeature([1], tf.float32)
            }

        # Parse the serialized data so we get a dict with our data.
        parsed_example = tf.parse_single_example(serialized=serialized,
                                                 features=features)

        # Instructions for how features should be parsed and any transformations that still need
        # to be applied.... currently this is where we normalise

        # FOR SIGMOID
        a_open = tf.cast(parsed_example['a_open'][0], tf.float32)
        b_open = tf.cast(parsed_example['b_open'][0], tf.float32)
        c_open = tf.cast(parsed_example['c_open'][0], tf.float32)
        d_open = tf.cast(parsed_example['d_open'][0], tf.float32)
        e_open = tf.cast(parsed_example['e_open'][0], tf.float32)
        f_open = tf.cast(parsed_example['f_open'][0], tf.float32)
        # FOR LINEAR
        # a_open = tf.cast(2*parsed_example['a_open'][0]-1, tf.float32)
        # b_open = tf.cast(2*parsed_example['b_open'][0]-1, tf.float32)
        # c_open = tf.cast(2*parsed_example['c_open'][0]-1, tf.float32)
        # d_open = tf.cast(2*parsed_example['d_open'][0]-1, tf.float32)
        # e_open = tf.cast(2*parsed_example['e_open'][0]-1, tf.float32)
        # f_open = tf.cast(2*parsed_example['f_open'][0]-1, tf.float32)
        pressure = (parsed_example['pressure'][0]-53.190247)/20.778079
        pressure = tf.cast(pressure, tf.float32)
        density = (parsed_example['density'][0]-54.616127)/12.450806
        density = tf.cast(density, tf.float32)
        flow = (parsed_example['flow_rate'][0]-2545.418464)/647.744286
        flow = tf.cast(flow, tf.float32)
        label = [
            # a_open,
            # b_open,
            # c_open,
            # d_open,
            # e_open,
            # f_open,
            pressure,
            density,
            flow
        ]

        signal = tf.concat(
            [
            parsed_example['under1']/10000000,
            # parsed_example['under2']/10000000 +
            # parsed_example['over1']/10000000 +

                [a_open, b_open, c_open, d_open, e_open, f_open]
            ],
            0
        )

        return signal, label


import sys
import importlib
import datetime

bl_info = {
	"name":        "Photon-v2",
	"description": "A hobby renderer featuring PBR.",
	"author":      "Tzu-Chieh Chang (D01phiN)",
	"version":     (0, 0, 0),
	"blender":     (2, 78, 0),
	"location":    "Info Header >> Render Engine Menu",
	"warning":     "WIP...",  # showing warning icon and text in addons panel
	"category":    "Render"
}

print("PhotonBlend initializing...")
print(datetime.datetime.now())

bmodulePackageName = "bmodule"
bmoduleNames       = [
	"p2exporter",
	"material",
	"renderer",
	"light",
	"node",
	"world"
]

bmoduleFullNames = []
for bmoduleName in bmoduleNames:
	bmoduleFullNames.append("{}.{}.{}".format(__name__, bmodulePackageName, bmoduleName))

for bmoduleFullName in bmoduleFullNames:
	if bmoduleFullName in sys.modules:
		importlib.reload(sys.modules[bmoduleFullName])
	else:
		importlib.import_module(bmoduleFullName)

def register():
	for moduleName in bmoduleFullNames:
		if moduleName in sys.modules:
			if hasattr(sys.modules[moduleName], "register"):
				sys.modules[moduleName].register()
			else:
				print("bmodule %s should contain a register() function" % moduleName)
		else:
			print("bmodule %s is not correctly imported" % moduleName)

def unregister():
	for moduleName in bmoduleFullNames:
		if moduleName in sys.modules:
			if hasattr(sys.modules[moduleName], "unregister"):
				sys.modules[moduleName].unregister()
			else:
				print("bmodule %s should contain an unregister() function" % moduleName)
		else:
			print("bmodule %s is not correctly imported" % moduleName)


#!/usr/bin/env python

#######################################################################################
# The line at the very top tells the cpu that will be excuting this job
# which python to use and how to find it.
# Without that line this sould just be a simple text file and you would
# specifically need to type on the command line: python name_of_file.py
#######################################################################################
# The lines below set up important parameters for the slurm scheduling system
# slurm ->  Simple Linux Utility for Resource Management, a free and open-source job scheduler for Linux and Unix-like kernels
# The first line tells the slurm scheduler which partition to send the job to
# The next two lines tells which account to use.
# The last two lines with the -o and -e flags tell where to write out the error and output text files.
# These are useful when debugging code.
# They are simple text files that cat be viewed with the commands cat or less.
# The directory where these files are written must be created before
# Otherwise you won't have access to the output and error text files.
#######################################################################################

#SBATCH --partition centos7_default-partition
#SBATCH --account acc_psb6351
#SBATCH --qos pq_psb6351
#SBATCH -o /scratch/madlab/Mattfeld_PSB6351/crash/preproc_o
#SBATCH -e /scratch/madlab/Mattfeld_PSB6351/crash/preproc_e

#######################################################################################
# The following commands are specific to python programming.
# Tools that you'll need for your code must be imported.
# You can import modules directly without renaming them (e.g., import os)
# Or you can import and rename things (e.g., import pandas as pd)
# Or you can import specific features of a module (e.g., from nipype.interfaces.utility import Function)
# It is traditional in python programming to import everything
# you might need at the top of your script.  However, the only rule
# is modules must be imported before they are used.  Also, functions code that begins with def nameoffunc(inputtofunc):
# require importing their own modules
#######################################################################################

#######################################################################################
#많은 파일을 다뤄야 하는 파이썬 프로그램을 작성할 때, 특정 패턴이나 확장자를 가진 파일들의 경로나 이름이 필요할 때가 있다.
#glob 모듈의 glob 함수는 사용자가 제시한 조건에 맞는 파일명을 리스트이 형식으로 반환한다.
#단, 조건에 정규식을 사용할 수 없으며 엑셀 등에서도 사용할 수 있는 '*'와 '?' 같은 와일드카드만을 지원한다
#'*'는 임의 길이의 모든 문자열을 의미한다
#e.g. output = glob.glob('dir/*.txt') >>> print(output)['dir\\file1.txt', 'dir\\file102.txt', 'dir\\filea.txt']
#'?'는 한 자리의 문자를 의미한다
#e.g. output = glob.glob('dir/file?.*') >>> print(output)['dir\\file1.bmp', 'dir\\file1.txt', 'dir\\filea.txt']
#######################################################################################

import os
from glob import glob

# Import new things that we'll need
import pandas as pd
import numpy as np
import nipype.interfaces.afni as afni
import nipype.interfaces.fsl as fsl
import nipype.interfaces.freesurfer as fs
from nipype.interfaces.utility import Function
import nibabel as nb
import json
import nipype.interfaces.io as nio
import nipype.pipeline.engine as pe

#######################################################################################
# Below I am assigning a list with one string element to the variable named sid
# I do this because I want to iterate over subject ids (aka., sids) and I want
# to treat 021 as a whole and not as separate parts of the string which is
# also iterable. I know this is a list because of the [] brackets
#######################################################################################

sids = ['021']

#######################################################################################
# Below I set up some important directories for getting data and writing
# files that I won't need in the end. I use the os command path.join to
# combine different string elements into a path strcuture that will work
# across operating systems.  The below is only quasi correct because in the last
# string element of both the func_dir and fmap_dir variables I indicate
# directory structures with the '/' string.  This forward slash is only
# relevant for linux and osx operating systems....windows uses something different '\\'
# I am also using f string formatting to insert the first element of the
# sids list variable into the string.
#######################################################################################

# base_dir = '/home/data/madlab/Mattfeld_PSB6351/mattfeld_2020'
# work_dir = '/scratch/madlab/Mattfeld_PSB6351'
# func_dir = os.path.join(base_dir, f'dset/sub-{sids[0]}/func')
# fmap_dir = os.path.join(base_dir, f'dset/sub-{sids[0]}/fmap')
# fs_dir = os.path.join(base_dir, 'derivatives', 'freesurfer')

base_dir = '/home/hlee053/Documents/mattfeld_2020'
work_dir = '/scratch/hlee053'
func_dir = os.path.join(base_dir, f'dset/sub-{sids[0]}/func')
fmap_dir = os.path.join(base_dir, f'dset/sub-{sids[0]}/fmap')
fs_dir = os.path.join(base_dir, 'derivatives', 'freesurfer')

#######################################################################################
# Get a list of my study task json and nifti converted files
# I am using the glob function from glob that take a string as input
# That string can contain wildcards to grab multiple files that meet
# the string completion.  I also, use the function sorted to order them
# so that the func_files and fmap_files are in the same order based on
# alphanumeric numbering criteria.  This is important when I get
# specific elements from a .json file for a func file to preprocess.
# Be careful!!!!  glob will return an empty list if your wildcard
# string completion comes up empty rather than crash.  Make sure you
# have no typos.
# I plan to replace these lines with a nipype datagrabber soon.
#######################################################################################

func_json = sorted(glob(func_dir + '/*.json'))
func_files = sorted(glob(func_dir + '/*.nii.gz'))
fmap_files = sorted(glob(fmap_dir + '/*func*.nii.gz'))

#######################################################################################
# Here I am building a function that eliminates the
# mapnode directory structure and assists in saving
# all of the outputs into a single directory.
# This is a function because it starts with the word def
# and then has the functon name followed by paraentheses.
# The name inside the parentheses is a variable name that represents
# the input to the function.  In this case I'm providing a variable
# called func_files.  I will iterate over the length of the func_files
# variable to append tuples to a list variable called subs that have
# the ways I want to substitute names later in the datasink.  In this
# case I am getting ride of those names so that everything is saved
# in the same directory in the end.
#######################################################################################

def get_subs(func_files):
    '''Produces Name Substitutions for Each Contrast'''
    subs = []
    for curr_run in range(len(func_files)):
        subs.append(('_tshifter%d' %curr_run, ''))
        subs.append(('_volreg%d' %curr_run, ''))
    return subs

#######################################################################################
# Here I am building a function that takes in a
# text file that includes the number of outliers
# at each volume and then finds which volume (e.g., index)
# has the minimum number of outliers (e.g., min)
# searching over the first 201 volumes
# If the index function returns a list because there were
# multiple volumes with the same outlier count, pick the first one
#######################################################################################

def best_vol(outlier_count):
    best_vol_num = outlier_count.index(min(outlier_count[:200]))
    if isinstance(best_vol_num, list):
        best_vol_num = best_vol_num[0]
    return best_vol_num

#######################################################################################
# Here I am creating a list of lists containing the slice timing for each study run
#######################################################################################

slice_timing_list = [] # Here I define an empty list variable
for curr_json in func_json: # Here I am iterating over the variable func_json that was defined above through the sorted glob
    curr_json_data = open(curr_json) # I need to open the json file
    curr_func_metadata = json.load(curr_json_data) # THen I need to load the json file
    slice_timing_list.append(curr_func_metadata['SliceTiming'])

#######################################################################################
# Here I am establishing a nipype work flow that I will eventually execute
# Code here become less python specific and more nipype specific.  They share similarites
# but have some unique pecularities to take note.
#######################################################################################

psb6351_wf = pe.Workflow(name='psb6351_wf') # First I create a workflow...this will serve as the backbone of the pipeline
psb6351_wf.base_dir = work_dir + f'/psb6351workdir/sub-{sids[0]}' # I deinfe the working directory where I want preliminary files to be written
psb6351_wf.config['execution']['use_relative_paths'] = True # I assign a execution variable to use relative paths...TRYING TO USE THIS TO FIX A BUG?

#######################################################################################
# Create a Function node to substitute names of files created during pipeline
# In nipype you create nodes using the pipeline engine that was imported earlier.
# In this case I am sepcifically creating a function node with an input called func_files
# and expects an output (what the function returns) called subs.  The actual function
# which was created above is called get_subs.
# I can assign the input either through a workflow connect syntax or by simplying hardcoding it.
# in this case I hard coded it by saying that .inputs.func_files = func_files
#######################################################################################

getsubs = pe.Node(Function(input_names=['func_files'],
                           output_names=['subs'],
                           function=get_subs),
                  name='getsubs')
getsubs.inputs.func_files = func_files

#######################################################################################
# Here I am inputing just the first run functional data
# I want to use afni's 3dToutcount to find the number of
# outliers at each volume.  I will use this information to
# later select the earliest volume with the least number of outliers
# to serve as the base for the motion correction
#######################################################################################

id_outliers = pe.Node(afni.OutlierCount(),
                      name = 'id_outliers')
# Mandatory Inputs
id_outliers.inputs.in_file = func_files[0] # Input dataset #if the number is larger, it might reflect various body motions..The first study run is the closest to structure scan

# Optional Inputs
id_outliers.inputs.automask = True # Clip off small voxels
id_outliers.inputs.fraction = True # Write out the fraction of masked voxels which are outliers at each timepoint
id_outliers.inputs.legendre = True # Use Legendre polynomials
id_outliers.inputs.polort = 4 # Detrend each voxel timeseries with polynomials of order 'integer' prior to outlier estimation # 4 is recommended
id_outliers.inputs.out_file = 'outlier_file'

#ATM ONLY: Add an unwarping mapnode here using the field maps
calc_distor_corr = pe.Node(afni.Qwarp(),
                           name = 'calc_distor_corr')
calc_distor_corr.inputs.plusminus = True
calc_distor_corr.inputs.pblur = [0.05, 0.05]
calc_distor_corr.inputs.minpatch = 9
calc_distor_corr.inputs.noweight = True
calc_distor_corr.inputs.outputtype = 'NIFTI_GZ'
calc_distor_corr.inputs.out_file = 'foobar'
calc_distor_corr.inputs.in_file = fmap_files[0]
calc_distor_corr.inputs.base_file = fmap_files[1]

distor_corr = pe.MapNode(afni.NwarpApply(),
                         iterfield=['in_file'],
                         name = 'distor_corr')
distor_corr.inputs.ainterp = 'quintic'
calc_distor_corr.inputs.outputtype = 'NIFTI_GZ'
distor_corr.inputs.in_file = func_files

#######################################################################################
# The line below is the other way that inputs can be provided to a node
# Rather than hardcoding like above: distor_corr.inputs.ainterp = 'quintic'
# You pass the output from the previous node...in this case calc_distor_corr
# it's output is called 'source_warp' and you pass that to this node distor_corr
# and the relevant input here 'warp'
#######################################################################################

psb6351_wf.connect(calc_distor_corr, 'source_warp', distor_corr, 'warp')

#######################################################################################
# Create a Function node to identify the best volume based
# on the number of outliers at each volume. I'm searching
# for the index in the first 201 volumes that has the
# minimum number of outliers and will use the min() function
# I will use the index function to get the best vol.
#######################################################################################

getbestvol = pe.Node(Function(input_names=['outlier_count'],
                              output_names=['best_vol_num'],
                              function=best_vol),
                     name='getbestvol')
psb6351_wf.connect(id_outliers, 'out_file', getbestvol, 'outlier_count')

#######################################################################################
# Extract the earliest volume with the
# the fewest outliers of the first run as the reference
#######################################################################################

extractref = pe.Node(fsl.ExtractROI(t_size=1),
                     name = "extractref")
extractref.inputs.in_file = func_files[0]
#extractref.inputs.t_min = int(np.ceil(nb.load(study_func_files[0]).shape[3]/2)) #PICKING MIDDLE VOLUME of RUN 1
#PICKING MIDDLE
psb6351_wf.connect(getbestvol, 'best_vol_num', extractref, 't_min')

#######################################################################################
# Below is the command that runs AFNI's 3dvolreg command.
# this is the node that performs the motion correction
# I'm iterating over the functional files which I am passing
# functional data from the slice timing correction node before
# I'm using the earliest volume with the least number of outliers
# during the first run as the base file to register to.
#######################################################################################

volreg = pe.MapNode(afni.Volreg(),
                    iterfield=['in_file'],
                    name = 'volreg')
# Optional Input
volreg.inputs.outputtype = 'NIFTI_GZ' # AFNI outputtype
volreg.inputs.zpad = 4 # Zeropad around the adges by 'n' voxels during rotations
volreg.inputs.verbose = True # More detailed description of the process
volreg.inputs.interp = 'Fourier' # Spatial interpolation methods # default = haptic # cubic
volreg.inputs.in_file = func_files

psb6351_wf.connect(extractref, 'roi_file', volreg, 'basefile')

#######################################################################################
# Below is the command that runs AFNI's 3dTshift command
# this is the node that performs the slice timing correction
# I input the study func files as a list and the slice timing
# as a list of lists. I'm using a MapNode to iterate over the two.
# this should allow me to parallelize this on the HPC
#######################################################################################

tshifter = pe.MapNode(afni.TShift(),
                      iterfield=['in_file','slice_timing'],
                      name = 'tshifter')
# Mandatory Input
#tshifter.inputs.in_file = func_files # Input file to 3dT-shift

# Optional Inputs
tshifter.inputs.tr = '1.76' # Manually set the TR
tshifter.inputs.slice_timing = slice_timing_list # Time offests from the volume acquisition onset for each slice
tshifter.inputs.outputtype = 'NIFTI_GZ' # AFNI output filetype
tshifter.inputs.tzero = 0.0 # Align each slice to time offset of given slice
tshifter.inputs.interp = 'Fourier'# Different interpolation methods # default = Fourier # quintic

psb6351_wf.connect(volreg, 'out_file', tshifter, 'in_file')

#######################################################################################
# Calculate the transformation matrix from EPI space to FreeSurfer space
# using the BBRegister command
#######################################################################################

fs_register = pe.Node(fs.BBRegister(init='fsl'),
                      name ='fs_register')
fs_register.inputs.contrast_type = 't2'
fs_register.inputs.out_fsl_file = True
fs_register.inputs.subject_id = f'sub-{sids[0]}'
fs_register.inputs.subjects_dir = fs_dir

psb6351_wf.connect(extractref, 'roi_file', fs_register, 'source_file')

#######################################################################################
# Add a mapnode to spatially blur the data
# save the outputs to the datasink
#######################################################################################

#spatial smoothing
#3dblurtoFWHM -> Blurring will occur only within the mask. Voxels NOT in the mask will be set to zero in the output
#For each run, blur each volume by a $fwhm mm FWHM (Full Width at Half Max) Gaussian kernel
#Got some related information at https://andysbrainbook.readthedocs.io/en/latest/AFNI/AFNI_Short_Course/AFNI_Preprocessing/05_AFNI_Smoothing.html
blurring = pe.MapNode(afni.BlurToFWHM(),
                         iterfield=['in_file'],
                         name = 'blurring')
# Optional Inputs
blurring.inputs.fwhm = 6.0 #fwhm -> 4 is default, 6 is common #a float
blurring.inputs.automask = True #create an automaskk from the input dataset
blurring.inputs.outputtype = 'NIFTI_GZ' # AFNI outputtype

psb6351_wf.connect(tshifter, 'out_file', blurring, 'in_file')

#temporal smoothing
#3dTsmooth -> Smooth each voxel time series in a 3d+time dataset and produces as output a new 3d+time dataset(e.g., lowpass filter in time)
tsmooth = pe.MapNode(afni.TSmooth(),
                          iterfield=['in_file'],
                          name = 'tsmooth')
tsmooth.inputs.adaptive = 5 #use adaptive mean filtering of width N (N must be odd and bigger than 3)
tsmooth.inputs.num_threads = 1 #set number of threads #default = 1
tsmooth.outputtype = 'NIFTI_GZ'
psb6351_wf.connect(blurring, 'out_file', tsmooth, 'in_file')

#######################################################################################
# Below is the node that collects all the data and saves
# the outputs that I am interested in. Here in this node
# I use the substitutions input combined with the earlier
# function to get rid of nesting
#######################################################################################

datasink = pe.Node(nio.DataSink(), name="datasink")
datasink.inputs.base_directory = os.path.join(base_dir, 'derivatives/preproc')
datasink.inputs.container = f'sub-{sids[0]}'
psb6351_wf.connect(tsmooth, 'out_file', datasink, 'tsmooth')
psb6351_wf.connect(blurring, 'out_file', datasink, 'blurring')
psb6351_wf.connect(tshifter, 'out_file', datasink, 'sltime_corr')
psb6351_wf.connect(extractref, 'roi_file', datasink, 'study_ref')
psb6351_wf.connect(calc_distor_corr, 'source_warp', datasink, 'distortion')
psb6351_wf.connect(volreg, 'out_file', datasink, 'motion.@corrfile')
psb6351_wf.connect(volreg, 'oned_matrix_save', datasink, 'motion.@matrix')
psb6351_wf.connect(volreg, 'oned_file', datasink, 'motion.@par')
psb6351_wf.connect(fs_register, 'out_reg_file', datasink, 'register.@reg_file')
psb6351_wf.connect(fs_register, 'min_cost_file', datasink, 'register.@reg_cost')
psb6351_wf.connect(fs_register, 'out_fsl_file', datasink, 'register.@reg_fsl_file')
psb6351_wf.connect(getsubs, 'subs', datasink, 'substitutions')

#######################################################################################
# The following two lines set a work directory outside of my
# local git repo and runs the workflow
#######################################################################################

psb6351_wf.run(plugin='SLURM',
               plugin_args={'sbatch_args': ('--partition centos7_default-partition --qos pq_psb6351 --account acc_psb6351'),
                            'overwrite':True})


import random
import numpy as np
import scipy
import matplotlib
import matplotlib.pyplot as plt
import seaborn as sns
sns.set_context("talk")
import sknetwork
from IPython.display import SVG

def plot_policy(env, policy, title):
    policy = np.array([policy[s] for s in env.states])
    policy = policy.reshape((2, -1, env.len), order='F')
    labels = np.vectorize(lambda x: env.actions_dic[x])(policy)
    plot_states(policy, title=title, cbar=False, annot=labels, fmt='s')

def plot_states(state_array, title=None, figsize=(10, 10), annot=True,
                fmt="0.1f", linewidths=.5, square=True, cbar=False, cmap="Reds", ax=None):
    if ax is None:
        fig, axes = plt.subplots(2, 1, figsize=figsize)

    states_with_key = state_array[0]
    states_without_key = state_array[1]

    annot_with_key = annot[0]
    annot_without_key = annot[1]

    sns.heatmap(states_with_key, annot=annot_with_key, fmt=fmt, linewidths=linewidths,
                square=square, cbar=cbar, cmap=cmap, ax=axes[0],
                cbar_kws={"orientation": "horizontal"},
                annot_kws={"size": int(figsize[1] * 1.2)})
    axes[0].set_title('Policy without Key')

    sns.heatmap(states_without_key, annot=annot_without_key, fmt=fmt, linewidths=linewidths,
                square=square, cbar=cbar, cmap=cmap, ax=axes[1],
                cbar_kws={"orientation": "horizontal"},
                annot_kws={"size": int(figsize[1] * 1.2)})
    axes[1].set_title('Policy with Key')

    if title is not None:
        plt.suptitle(title)

    if ax is None:
        plt.show()
    else:
        return ax

def plot_qtables(q_array, title=None, figsize=(7, 7), annot=True,
                 fmt="0.1f", linewidths=.5, square=True, cbar=False, cmap="Reds"):
    num_actions = q_array.shape[-1]

    global_figsize = list(figsize)
    global_figsize[0] *= num_actions
    # Sample figsize in inches
    fig, ax_list = plt.subplots(nrows=num_actions, figsize=global_figsize)

    for action_index in range(num_actions):
        ax = ax_list[action_index]
        state_seq = q_array[:, :, action_index].T
        plot_states(state_seq, title=f'Action {action_index}', figsize=figsize, annot=True,
                    fmt="0.1f", linewidths=.5, square=True, cbar=False, cmap="Reds", ax=ax)

    plt.suptitle(title)
    plt.show()

def plot_state_freq(state_freq):
    x = np.arange(len(state_freq))
    y = state_freq.values()
    labels = [str(x) for x in state_freq.keys()]
    plt.figure(figsize=(10, 5))
    plt.bar(x, y, tick_label=labels)
    _ = plt.xticks(rotation='vertical')

def plot_scores(scores, window_size=100):
    ma = np.convolve(scores, np.ones(window_size, dtype=int), 'valid')
    ma /= window_size
    x = np.arange(len(scores))
    plt.figure(figsize=(10, 5))
    plt.figure(figsize=(15, 7))
    plt.xlabel("episodes")
    plt.ylabel("rewards")
    plt.scatter(x, scores, marker='+', c='b', s=30, linewidth=1,
                alpha=0.5, label="total rewards")
    plt.plot(x[window_size - 1:], ma, c='r',
             alpha=0.7, label="reward moving average")

def plot_scores_grid(data, label, num_runs, a):
    c = 3
    r = int(round(num_runs / c + 0.49, 0))

    fig, axes = plt.subplots(r, c, figsize=(r * 6, c * 5), sharey=True)
    for n in range(num_runs):
        ax = axes[n // c][n % c]
        scores = data[(label, str(n))]
        window_size = 100
        ma = np.convolve(scores, np.ones(window_size, dtype=int), 'valid')
        ma /= window_size
        x = np.arange(len(scores))
        ax.set_xlabel("episodes")
        ax.set_ylabel("rewards")
        ax.scatter(x, scores, marker='+', c='b', s=30, linewidth=1,
                   alpha=0.5, label="total rewards")
        ax.plot(x[window_size - 1:], ma, c='r',
                alpha=0.7, label="reward moving average")

    for i in range(n + 1, r * c):
        ax = axes[i // c][i % c]
        ax.axis('off')

    fig.suptitle(f'Total rewards over each run for {a}')

    plt.show()

def plot_scores(intrinsic_scores, ax=None, space_visitation=None):
    window_size = 50
    ma = np.convolve(intrinsic_scores, np.ones(window_size, dtype=int), 'valid')
    ma /= window_size

    if not ax:
        fig, ax = plt.subplots(1, 1)

    x = np.arange(len(intrinsic_scores))

    ax.set_xlabel("episodes")
    ax.set_ylabel("rewards")
    ax.scatter(x, intrinsic_scores, marker='+', c='b', s=30, linewidth=1,
                alpha=0.5, label="total rewards")
    ax.plot(x[window_size - 1:], ma, c='r',
             alpha=0.7, label="reward moving average")

    if space_visitation is not None:
        ax2 = ax.twinx()
        ax2.plot(x, space_visitation, c='black')
        ax2.set_ylabel("space visitation in %")
        ax2.set_ylim([0, 100])

def plot_trajectory(graph):
    graph.convert_labels('adjacency')
    adj = scipy.sparse.csr_matrix(graph.get_adjacency_matrix())
    pos = np.array([tuple(map(int, graph.index_node_labels[i].split('.')))
                    for i in range(len(graph.index_node_labels))])
    im = sknetwork.visualization.svg_graph(adj, pos, directed=True)
    return SVG(im)


import cv2
import numpy as np

# 画像読み込み
img = cv2.imread("")
h, w = img.shape[:2]
size = (w, h)

# 回転角の指定
angle = 180
angle_rad = angle/180.0*np.pi

# 回転後の画像サイズを計算
w_rot = int(np.round(h*np.absolute(np.sin(angle_rad))+w*np.absolute(np.cos(angle_rad))))
h_rot = int(np.round(h*np.absolute(np.cos(angle_rad))+w*np.absolute(np.sin(angle_rad))))
size_rot = (w_rot, h_rot)

# 元画像の中心を軸に回転する
center = ((w-1)/2, (h-1)/2)
print(center)
scale = 1.0
rotation_matrix = cv2.getRotationMatrix2D(center, angle, scale)

# 平行移動を加える (rotation + translation)
affine_matrix = rotation_matrix.copy()
affine_matrix[0][2] = affine_matrix[0][2] -w/2 + w_rot/2
affine_matrix[1][2] = affine_matrix[1][2] -h/2 + h_rot/2

img_rot = cv2.warpAffine(img, affine_matrix, size_rot, flags=cv2.INTER_CUBIC)

cv2.imshow("img_rot", img_rot)
cv2.waitKey(0)
cv2.destroyAllWindows()


import json
import argparse

from etherscan import Etherscan, sum_gas
from ethereum_emissions import EthereumEmissions
from nifty_gateway import list_nifty_gateway

parser = argparse.ArgumentParser(description='Estimate emissions for CryptoArt platforms.')
parser.add_argument('--ng', action='store_true', help='Estimate emissions for Nifty Gateway.')
parser.add_argument('--verbose', action='store_true', help='Verbose mode.')
args = parser.parse_args()

with open('env.json') as f:
    apikey = json.load(f)['etherscan-api-key']

with open('data/contracts.json') as f:
    contracts = json.load(f)

etherscan = Etherscan(apikey)
ethereum_emissions = EthereumEmissions()

print(f'Name\tKind\tAddress\tGas\tTransactions\tkgCO2')
for name_kind, address in contracts.items():
    if name_kind == 'Nifty Gateway/multiple':
        if args.ng:
            transactions = etherscan.load_transactions_multiple(list_nifty_gateway(args.verbose),
                verbose=args.verbose)
        else:
            continue
    else:
        transactions = etherscan.load_transactions(address, verbose=args.verbose)
    gas = sum_gas(transactions)
    kgco2 = int(ethereum_emissions.sum_kgco2(transactions))
    name, kind = name_kind.split('/')
    print(f'{name}\t{kind}\t{address}\t{gas}\t{len(transactions)}\t{kgco2}')


from django.conf.urls import url
from django.views.generic import TemplateView
from ecomapp.views import (
	base_view,
	category_view,
	product_view, cart_view,
	add_to_cart,
	remove_from_cart,
	change_item_qty,
	checkout_view,
	order_create_view,
	make_order_view
	)

urlpatterns = [
	url(r'^$', base_view, name='base'),
	url(r'^cart/$', cart_view, name='cart'),
	url(r'^remove_from_cart/$', remove_from_cart, name='remove_from_cart'),
	url(r'^add_to_cart/$', add_to_cart, name='add_to_cart'),
	url(r'^change_item_qty/$', change_item_qty, name='change_item_qty'),
	url(r'^category/(?P<category_slug>[-\w]+)/$', category_view, name='category_detail'),
	url(r'^product/(?P<product_slug>[-\w]+)/$', product_view, name='product_detail'),
	url(r'^checkout/$', checkout_view, name='checkout_view'),
	url(r'^order/$', order_create_view, name='create_order'),
	url(r'^make_order/$', make_order_view, name='make_order'),
	url(r'^thank_you/$', TemplateView.as_view(template_name='thank_you.html'), name='thank_you')
]


# -*- coding: utf-8 -*-
from pytest import fixture, raises

from storyscript.parser import Ebnf, Grammar

@fixture
def grammar(magic):
    grammar = Grammar()
    grammar.ebnf = magic()
    return grammar

@fixture
def ebnf(magic, grammar):
    ebnf = magic()
    grammar.ebnf = ebnf
    return ebnf

def test_grammar_init():
    grammar = Grammar()
    assert isinstance(grammar.ebnf, Ebnf)

def test_grammar_rules(grammar, ebnf):
    grammar.rules()
    defintions = (['values'], ['absolute_expression'], ['comment'],
                  ['assignment'], ['imports'], ['return_statement'], ['block'])
    ebnf.rules.assert_called_with('rules', *defintions)

def test_grammar_whitespaces(grammar, ebnf):
    grammar.whitespaces()
    tokens = (('ws', '(" ")+'), ('nl', r'/(\r?\n[\t ]*)+/'))
    ebnf.tokens.assert_called_with(*tokens, inline=True, regexp=True)

def test_grammar_indentation(grammar, ebnf):
    grammar.indentation()
    tokens = (('indent', '<INDENT>'), ('dedent', '<DEDENT>'))
    ebnf.tokens.assert_called_with(*tokens, inline=True)

def test_grammar_spaces(patch, call_count, grammar):
    patch.many(Grammar, ['whitespaces', 'indentation'])
    grammar.spaces()
    call_count(Grammar, ['whitespaces', 'indentation'])

def test_grammar_nested_block(grammar, ebnf):
    grammar.nested_block()
    definition = '_INDENT block+ _DEDENT'
    ebnf.rule.assert_called_with('nested_block', definition, raw=True)

def test_grammar_elseif_block(patch, call_count, grammar, ebnf):
    patch.many(Grammar, ['nested_block', 'elseif_statement'])
    grammar.elseif_block()
    call_count(Grammar, ['nested_block', 'elseif_statement'])
    definition = ('elseif_statement', 'nl', 'nested_block')
    ebnf.rule.assert_called_with('elseif_block', definition)

def test_grammar_else_block(patch, grammar, ebnf):
    patch.object(Grammar, 'else_statement')
    grammar.else_block()
    assert Grammar.else_statement.call_count == 1
    definition = ('else_statement', 'nl', 'nested_block')
    ebnf.rule.assert_called_with('else_block', definition)

def test_grammar_if_block(patch, call_count, grammar, ebnf):
    patch.many(Grammar, ['if_statement', 'elseif_block', 'else_block'])
    grammar.if_block()
    call_count(Grammar, ['if_statement', 'elseif_block', 'else_block'])
    definition = 'if_statement _NL nested_block elseif_block* else_block?'
    ebnf.rule.assert_called_with('if_block', definition, raw=True)

def test_grammar_foreach_block(patch, grammar, ebnf):
    patch.object(Grammar, 'foreach_statement')
    grammar.foreach_block()
    assert Grammar.foreach_statement.call_count == 1
    definition = 'foreach_statement _NL nested_block'
    ebnf.rule.assert_called_with('foreach_block', definition, raw=True)

def test_grammar_typed_argument(grammar, ebnf):
    grammar.typed_argument()
    definition = ('name', 'colon', 'types')
    ebnf.rule.assert_called_with('typed_argument', definition)

def test_grammar_function_argument(patch, grammar, ebnf):
    patch.object(Grammar, 'typed_argument')
    grammar.function_argument()
    assert Grammar.typed_argument.call_count == 1
    ebnf.rule.assert_called_with('function_argument', ('ws', 'typed_argument'))

def test_grammar_function_output(grammar, ebnf):
    grammar.function_output()
    ebnf.token.assert_called_with('returns', 'returns', inline=True)
    rule = ('ws', 'returns', 'ws', 'types')
    ebnf.rule.assert_called_with('function_output', rule)

def test_grammar_function_statement(patch, call_count, grammar, ebnf):
    patch.many(Grammar, ['function_argument', 'function_output'])
    grammar.function_statement()
    call_count(Grammar, ['function_argument', 'function_output'])
    rule = 'FUNCTION_TYPE _WS NAME function_argument* function_output?'
    ebnf.rule.assert_called_with('function_statement', rule, raw=True)

def test_grammar_function_block(patch, grammar, ebnf):
    patch.object(Grammar, 'function_statement')
    grammar.function_block()
    definition = ('function_statement', 'nl', 'nested_block')
    ebnf.rule.assert_called_with('function_block', definition)

def test_grammar_inline_expression(patch, grammar, ebnf):
    grammar.inline_expression()
    ebnf.tokens.assert_called_with(('op', '('), ('cp', ')'), inline=True)
    ebnf.rule.assert_called_with('inline_expression', ('op', 'service', 'cp'))

def test_grammar_arguments(patch, grammar, ebnf):
    grammar.arguments()
    rule = '_WS? NAME? _COLON _WS? (values|path)'
    ebnf.rule.assert_called_with('arguments', rule, raw=True)

def test_grammar_command(grammar, ebnf):
    grammar.command()
    ebnf.rule.assert_called_with('command', ('ws', 'name'))

def test_grammar_output(grammar, ebnf):
    grammar.output()
    rule = '(_WS _AS _WS NAME (_COMMA _WS? NAME)*)'
    ebnf.rule.assert_called_with('output', rule, raw=True)

def test_grammar_service_fragment(patch, call_count, grammar, ebnf):
    patch.many(Grammar, ['arguments', 'command', 'output'])
    grammar.service_fragment()
    call_count(Grammar, ['arguments', 'command', 'output'])
    rule = '(command arguments*|arguments+) output?'
    ebnf.rule.assert_called_with('service_fragment', rule, raw=True)

def test_grammar_service(patch, grammar, ebnf):
    patch.object(Grammar, 'service_fragment')
    grammar.service()
    assert Grammar.service_fragment.call_count == 1
    ebnf.rule.assert_called_with('service', ('path', 'service_fragment'))

def test_grammar_service_block(patch, grammar, ebnf):
    patch.object(Grammar, 'service')
    grammar.service_block()
    rule = 'service _NL (nested_block)?'
    ebnf.rule.assert_called_with('service_block', rule, raw=True)

def test_grammar_when_block(patch, grammar, ebnf):
    grammar.when_block()
    ebnf.token.assert_called_with('when', 'when', inline=True)
    rule = '_WHEN _WS (path output|service) _NL nested_block'
    ebnf.rule.assert_called_with('when_block', rule, raw=True)

def test_grammar_block(patch, call_count, grammar, ebnf):
    methods = ['if_block', 'foreach_block', 'function_block', 'service_block',
               'when_block']
    patch.many(Grammar, methods)
    grammar.block()
    call_count(Grammar, methods)
    definition = ('rules _NL|if_block|foreach_block|function_block'
                  '|arguments|service_block|when_block')
    ebnf.rule.assert_called_with('block', definition, raw=True)

def test_grammar_number(grammar, ebnf):
    grammar.number()
    tokens = (('int', '"0".."9"+'), ('float', """INT "." INT? | "." INT"""))
    ebnf.tokens.assert_called_with(*tokens, regexp=True, priority=2)
    ebnf.rules.assert_called_with('number', ['int'], ['float'])

def test_grammar_string(grammar, ebnf):
    grammar.string()
    tokens = (('single_quoted', "/'([^']*)'/"),
              ('double_quoted', '/"([^"]*)"/'))
    ebnf.tokens.assert_called_with(*tokens, regexp=True)
    definitions = (['single_quoted'], ['double_quoted'])
    ebnf.rules.assert_called_with('string', *definitions)

def test_grammar_boolean(grammar, ebnf):
    grammar.boolean()
    ebnf.tokens.assert_called_with(('true', 'true'), ('false', 'false'))
    ebnf.rules.assert_called_with('boolean', ['true'], ['false'])

def test_grammar_values(patch, call_count, grammar, ebnf):
    methods = ['number', 'string', 'list', 'objects', 'boolean',
               'inline_expression']
    patch.many(Grammar, methods)
    grammar.values()
    call_count(Grammar, methods)
    rules = (['number'], ['string'], ['boolean'], ['list'], ['objects'],
             ['inline_expression'])
    ebnf.rules.assert_called_with('values', *rules)

def test_grammar_operator(grammar, ebnf):
    grammar.operator()
    tokens = (('plus', '+'), ('dash', '-'), ('multiplier', '*'),
              ('bslash', '/'))
    ebnf.tokens.assert_called_with(*tokens)
    definitions = (['plus'], ['dash'], ['multiplier'], ['bslash'])
    ebnf.rules.assert_called_with('operator', *definitions)

def test_grammar_mutation(grammar, ebnf):
    grammar.mutation()
    rule = '_WS NAME arguments*'
    ebnf.rule.assert_called_with('mutation', rule, raw=True)

def test_grammar_expression(patch, grammar, ebnf):
    patch.many(Grammar, ['operator', 'mutation'])
    grammar.expression()
    assert Grammar.operator.call_count == 1
    assert Grammar.mutation.call_count == 1
    definitions = (('values', 'ws', 'operator', 'ws', 'values'),
                   ('values', 'operator', 'values'),
                   ('values', 'mutation'))
    ebnf.rules.assert_called_with('expression', *definitions)

def test_grammar_absolute_expression(patch, grammar, ebnf):
    patch.object(Grammar, 'expression')
    grammar.absolute_expression()
    assert Grammar.expression.call_count == 1
    ebnf.rule.assert_called_with('absolute_expression', ['expression'])

def test_grammar_list(grammar, ebnf):
    grammar.list()
    tokens = (('comma', ','), ('osb', '['), ('csb', ']'))
    ebnf.tokens.assert_called_with(*tokens, inline=True)
    definition = ('_OSB (_NL _INDENT)? (values (_COMMA (_WS|_NL)? '
                  'values)*)? (_NL _DEDENT)? _CSB')
    ebnf.rule.assert_called_with('!list', definition, raw=True)

def test_grammar_key_value(grammar, ebnf):
    grammar.key_value()
    ebnf.token.assert_called_with('colon', ':', inline=True)
    rule = '(string|path) _COLON _WS? (values|path)'
    ebnf.rule.assert_called_with('key_value', rule, raw=True)

def test_grammar_objects(patch, grammar, ebnf):
    patch.object(Grammar, 'key_value')
    grammar.objects()
    assert Grammar.key_value.call_count == 1
    ebnf.tokens.assert_called_with(('ocb', '{'), ('ccb', '}'), inline=True)
    rule = '_OCB (key_value (_COMMA _WS? key_value)*)? _CCB'
    ebnf.rule.assert_called_with('objects', rule, raw=True)

def test_grammar_path_fragment(grammar, ebnf):
    grammar.path_fragment()
    ebnf.token.assert_called_with('dot', '.', inline=True)
    definitions = (('dot', 'name'), ('osb', 'int', 'csb'),
                   ('osb', 'string', 'csb'), ('osb', 'path', 'csb'))
    ebnf.rules.assert_called_with('path_fragment', *definitions)

def test_grammar_path(patch, grammar, ebnf):
    patch.object(Grammar, 'path_fragment')
    grammar.path()
    token = '/[a-zA-Z-\/_0-9]+/'
    ebnf.token.assert_called_with('name', token, regexp=True, priority=1)
    Grammar.path_fragment.call_count == 1
    ebnf.rule.assert_called_with('path', 'NAME (path_fragment)*', raw=True)

def test_grammar_assignment_fragment(patch, grammar, ebnf):
    grammar.assignment_fragment()
    ebnf.token.assert_called_with('equals', '=')
    rule = 'EQUALS _WS? (values|expression|path|service)'
    ebnf.rule.assert_called_with('assignment_fragment', rule, raw=True)

def test_grammar_assignment(patch, grammar, ebnf):
    patch.many(Grammar, ['path', 'assignment_fragment'])
    grammar.assignment()
    assert Grammar.path.call_count == 1
    assert Grammar.assignment_fragment.call_count == 1
    definition = ('path', 'ws?', 'assignment_fragment')
    ebnf.rule.assert_called_with('assignment', definition)

def test_grammar_imports(patch, grammar, ebnf):
    grammar.imports()
    ebnf.token.assert_called_with('import', 'import', inline=True)
    rule = ('import', 'ws', 'string', 'ws', 'as', 'ws', 'name')
    ebnf.rule.assert_called_with('imports', rule)

def test_grammar_comparisons(grammar, ebnf):
    grammar.comparisons()
    tokens = (('greater', '>'), ('greater_equal', '>='), ('lesser', '<'),
              ('lesser_equal', '<='), ('not', '!='), ('equal', '=='))
    ebnf.tokens.assert_called_with(*tokens)
    definitions = (['greater'], ['greater_equal'], ['lesser'],
                   ['lesser_equal'], ['not'], ['equal'])
    ebnf.rules.assert_called_with('comparisons', *definitions)

def test_grammar_path_value(grammar, ebnf):
    grammar.path_value()
    ebnf.rules.assert_called_with('path_value', *(['path'], ['values']))

def test_grammar_if_statement(patch, grammar, ebnf):
    patch.object(Grammar, 'path_value')
    grammar.if_statement()
    assert Grammar.path_value.call_count == 1
    ebnf.token.assert_called_with('if', 'if', inline=True)
    rule = '_IF _WS path_value (_WS comparisons _WS path_value)?'
    ebnf.rule.assert_called_with('if_statement', rule, raw=True)

def test_grammar_else_statement(grammar, ebnf):
    grammar.else_statement()
    ebnf.token.assert_called_with('else', 'else', inline=True)
    ebnf.rule.assert_called_with('!else_statement', ['else'])

def test_grammar_elseif_statement(grammar, ebnf):
    grammar.elseif_statement()
    rule = '_ELSE _WS? _IF _WS path_value (_WS comparisons _WS path_value)?'
    ebnf.rule.assert_called_with('elseif_statement', rule, raw=True)

def test_grammar_foreach_statement(grammar, ebnf):
    grammar.foreach_statement()
    definition = ('foreach', 'ws', 'name', 'output')
    ebnf.rule.assert_called_with('foreach_statement', definition)
    tokens = (('foreach', 'foreach'), ('as', 'as'))
    ebnf.tokens.assert_called_with(*tokens, inline=True)

def test_grammar_return_statement(patch, ebnf, grammar):
    grammar.return_statement()
    ebnf.token.assert_called_with('return', 'return', inline=True)
    rule = '_RETURN _WS (path|values)'
    ebnf.rule.assert_called_with('return_statement', rule, raw=True)

def test_grammar_int_type(grammar, ebnf):
    grammar.int_type()
    ebnf.token.assert_called_with('int_type', 'int')

def test_grammar_float_type(grammar, ebnf):
    grammar.float_type()
    ebnf.token.assert_called_with('float_type', 'float')

def test_grammar_number_type(grammar, ebnf):
    grammar.number_type()
    ebnf.token.assert_called_with('number_type', 'number')

def test_grammar_string_type(grammar, ebnf):
    grammar.string_type()
    ebnf.token.assert_called_with('string_type', 'string')

def test_grammar_list_type(grammar, ebnf):
    grammar.list_type()
    ebnf.token.assert_called_with('list_type', 'list')

def test_grammar_object_type(grammar, ebnf):
    grammar.object_type()
    ebnf.token.assert_called_with('object_type', 'object')

def test_grammar_regexp_type(grammar, ebnf):
    grammar.regexp_type()
    ebnf.token.assert_called_with('regexp_type', 'regexp')

def test_grammar_types(patch, call_count, grammar, ebnf):
    methods = ['int_type', 'float_type', 'number_type', 'string_type',
               'list_type', 'object_type', 'regexp_type', 'function_type']
    patch.many(Grammar, methods)
    grammar.types()
    call_count(Grammar, methods)
    definitions = (['int_type'], ['float_type'], ['number_type'],
                   ['string_type'], ['list_type'], ['object_type'],
                   ['regexp_type'], ['function_type'])
    ebnf.rules.assert_called_with('types', *definitions)

def test_grammar_comment(grammar, ebnf):
    grammar.comment()
    token = token = '/(?<=###)\s(.*|\\n)+(?=\s###)|#(.*)/'
    ebnf.token.assert_called_with('comment', token, regexp=True)
    ebnf.rule.assert_called_with('comment', 'COMMENT+', raw=True)

def test_grammar_build(patch, call_count, grammar):
    methods = ['rules', 'spaces', 'values', 'absolute_expression', 'comment',
               'block', 'comparisons', 'assignment', 'imports', 'types',
               'return_statement']
    patch.many(Grammar, methods)
    result = grammar.build()
    grammar.ebnf.start.assert_called_with('_NL? block')
    call_count(Grammar, methods)
    assert result == grammar.ebnf.build()