import tensorflow as tf
import tensorflow.contrib.slim as slim
import os
tf.logging.set_verbosity('INFO')

BATCH_NORM_MOMENTUM = 0.997
BATCH_NORM_EPSILON = 1e-3

def shufflenet(images, is_training, num_classes=1000, depth_multiplier='1.0'):
    """
    This is an implementation of ShuffleNet v2:
    https://arxiv.org/abs/1807.11164
    Arguments:
        images: a float tensor with shape [batch_size, image_height, image_width, 3],
            a batch of RGB images with pixel values in the range [0, 1].
        is_training: a boolean.
        num_classes: an integer.
        depth_multiplier: a string, possible values are '0.5', '1.0', '1.5', and '2.0'.
    Returns:
        a float tensor with shape [batch_size, num_classes].
    """
    possibilities = {'0.5': 48, '1.0': 116, '1.5': 176, '2.0': 224}
    initial_depth = possibilities[depth_multiplier]

    def batch_norm(x):
        x = tf.layers.batch_normalization(
            x, axis=3, center=True, scale=True,
            training=is_training,
            momentum=BATCH_NORM_MOMENTUM,
            epsilon=BATCH_NORM_EPSILON,
            fused=True, name='batch_norm'
        )
        return x

    with tf.name_scope('standardize_input'):
        x = (2.0 * images) - 1.0

    with tf.variable_scope('ShuffleNetV2'):
        params = {
            'padding': 'SAME', 'activation_fn': tf.nn.relu,
            'normalizer_fn': batch_norm, 'data_format': 'NHWC',
            'weights_initializer': tf.contrib.layers.xavier_initializer()
        }
        with slim.arg_scope([slim.conv2d, depthwise_conv], **params):

            x = slim.conv2d(x, 24, (3, 3), stride=2, scope='Conv1')
            x = slim.max_pool2d(x, (3, 3), stride=2, padding='SAME', scope='MaxPool')

            x = block(x, num_units=4, out_channels=initial_depth, scope='Stage2')
            x = block(x, num_units=8, scope='Stage3')
            x = block(x, num_units=4, scope='Stage4')

            final_channels = 1024 if depth_multiplier != '2.0' else 2048
            x = slim.conv2d(x, final_channels, (1, 1), stride=1, scope='Conv5')

    # global average pooling
    x = tf.reduce_mean(x, axis=[1, 2])

    logits = slim.fully_connected(
        x, num_classes, activation_fn=None, scope='classifier',
        weights_initializer=tf.contrib.layers.xavier_initializer()
    )
    return logits

def block(x, num_units, out_channels=None, scope='stage'):
    with tf.variable_scope(scope):

        with tf.variable_scope('unit_1'):
            x, y = basic_unit_with_downsampling(x, out_channels)

        for j in range(2, num_units + 1):
            with tf.variable_scope('unit_%d' % j):
                x, y = concat_shuffle_split(x, y)
                x = basic_unit(x)
        x = tf.concat([x, y], axis=3)

    return x

def concat_shuffle_split(x, y):
    with tf.name_scope('concat_shuffle_split'):
        shape = tf.shape(x)
        batch_size = shape[0]
        height, width = shape[1], shape[2]
        depth = x.shape[3].value

        z = tf.stack([x, y], axis=3)  # shape [batch_size, height, width, 2, depth]
        z = tf.transpose(z, [0, 1, 2, 4, 3])
        z = tf.reshape(z, [batch_size, height, width, 2*depth])
        x, y = tf.split(z, num_or_size_splits=2, axis=3)
        return x, y

def basic_unit(x):
    in_channels = x.shape[3].value
    x = slim.conv2d(x, in_channels, (1, 1), stride=1, scope='conv1x1_before')
    x = depthwise_conv(x, kernel=3, stride=1, activation_fn=None, scope='depthwise')
    x = slim.conv2d(x, in_channels, (1, 1), stride=1, scope='conv1x1_after')
    return x

def basic_unit_with_downsampling(x, out_channels=None):
    in_channels = x.shape[3].value
    out_channels = 2 * in_channels if out_channels is None else out_channels

    y = slim.conv2d(x, in_channels, (1, 1), stride=1, scope='conv1x1_before')
    y = depthwise_conv(y, kernel=3, stride=2, activation_fn=None, scope='depthwise')
    y = slim.conv2d(y, out_channels // 2, (1, 1), stride=1, scope='conv1x1_after')

    with tf.variable_scope('second_branch'):
        x = depthwise_conv(x, kernel=3, stride=2, activation_fn=None, scope='depthwise')
        x = slim.conv2d(x, out_channels // 2, (1, 1), stride=1, scope='conv1x1_after')
        return x, y

@tf.contrib.framework.add_arg_scope
def depthwise_conv(
        x, kernel=3, stride=1, padding='SAME',
        activation_fn=None, normalizer_fn=None,
        weights_initializer=tf.contrib.layers.xavier_initializer(),
        data_format='NHWC', scope='depthwise_conv'):

    with tf.variable_scope(scope):
        assert data_format == 'NHWC'
        in_channels = x.shape[3].value
        W = tf.get_variable(
            'depthwise_weights',
            [kernel, kernel, in_channels, 1], dtype=tf.float32,
            initializer=weights_initializer
        )
        x = tf.nn.depthwise_conv2d(x, W, [1, stride, stride, 1], padding, data_format='NHWC')
        x = normalizer_fn(x) if normalizer_fn is not None else x  # batch normalization
        x = activation_fn(x) if activation_fn is not None else x  # nonlinearity
        return x

SHUFFLE_BUFFER_SIZE = 10000
NUM_FILES_READ_IN_PARALLEL = 10
NUM_PARALLEL_CALLS = 8
RESIZE_METHOD = tf.image.ResizeMethod.BILINEAR
IMAGE_SIZE = 224  # this will be used for training and evaluation
MIN_DIMENSION = 256  # when evaluating, resize to this size before doing central crop

class Pipeline:
    def __init__(self, filenames, is_training, batch_size, num_epochs):
        """
        Arguments:
            filenames: a list of strings, paths to tfrecords files.
            is_training: a boolean.
            batch_size, num_epochs: integers.
        """
        self.is_training = is_training

        # read the files in parallel
        dataset = tf.data.Dataset.from_tensor_slices(filenames)
        num_shards = len(filenames)
        if is_training:
            dataset = dataset.shuffle(buffer_size=num_shards)
        dataset = dataset.apply(tf.contrib.data.parallel_interleave(
            tf.data.TFRecordDataset, cycle_length=NUM_FILES_READ_IN_PARALLEL
        ))
        dataset = dataset.prefetch(buffer_size=batch_size)

        # mix the training examples
        if is_training:
            dataset = dataset.shuffle(buffer_size=SHUFFLE_BUFFER_SIZE)
        dataset = dataset.repeat(num_epochs)

        # decode and augment data
        dataset = dataset.apply(tf.contrib.data.map_and_batch(
            self.parse_and_preprocess, batch_size=batch_size,
            num_parallel_batches=1, drop_remainder=False
        ))
        dataset = dataset.prefetch(buffer_size=1)

        self.dataset = dataset

    def parse_and_preprocess(self, example_proto):
        """What this function does:
        1. Parses one record from a tfrecords file and decodes it.
        2. Possibly augments it.
        Returns:
            image: a float tensor with shape [height, width, 3],
                a RGB image with pixel values in the range [0, 1].
            label: an int tensor with shape [].
        """
        features = {
            'image': tf.FixedLenFeature([], tf.string),
            'label': tf.FixedLenFeature([], tf.int64),
            'ymin': tf.FixedLenSequenceFeature([], tf.float32, allow_missing=True),
            'xmin': tf.FixedLenSequenceFeature([], tf.float32, allow_missing=True),
            'ymax': tf.FixedLenSequenceFeature([], tf.float32, allow_missing=True),
            'xmax': tf.FixedLenSequenceFeature([], tf.float32, allow_missing=True)
        }
        parsed_features = tf.parse_single_example(example_proto, features)

        # get an image as a string, it will be decoded later
        image_as_string = parsed_features['image']

        # get a label
        label = tf.to_int32(parsed_features['label'])

        if self.is_training:

            # get groundtruth boxes, they must be in from-zero-to-one format,
            # also, it assumed that ymin < ymax and xmin < xmax
            boxes = tf.stack([
                parsed_features['ymin'], parsed_features['xmin'],
                parsed_features['ymax'], parsed_features['xmax']
            ], axis=1)
            boxes = tf.to_float(boxes)  # shape [num_boxes, 4]
            # they are only used for data augmentation

            image = self.augmentation(image_as_string, boxes)
        else:
            image = tf.image.decode_jpeg(image_as_string, channels=3)
            image = (1.0 / 255.0) * tf.to_float(image)  # to [0, 1] range
            image = resize_keeping_aspect_ratio(image, MIN_DIMENSION)
            image = central_crop(image, crop_height=IMAGE_SIZE, crop_width=IMAGE_SIZE)

        image.set_shape([IMAGE_SIZE, IMAGE_SIZE, 3])

        # in the format required by tf.estimator,
        # they will be batched later
        features = {'images': image}
        labels = {'labels': label}
        return features, labels

    def augmentation(self, image_as_string, boxes):

        image = get_random_crop(image_as_string, boxes)
        image = tf.image.random_flip_left_right(image)
        image = tf.image.resize_images(
            image, [IMAGE_SIZE, IMAGE_SIZE],
            method=RESIZE_METHOD
        )

        image = (1.0 / 255.0) * tf.to_float(image)  # to [0, 1] range
        image = random_color_manipulations(image, probability=0.25, grayscale_probability=0.05)
        return image

def resize_keeping_aspect_ratio(image, min_dimension):
    """
    Arguments:
        image: a float tensor with shape [height, width, 3].
        min_dimension: an int tensor with shape [].
    Returns:
        a float tensor with shape [new_height, new_width, 3],
            where min_dimension = min(new_height, new_width).
    """
    image_shape = tf.shape(image)
    height = tf.to_float(image_shape[0])
    width = tf.to_float(image_shape[1])

    original_min_dim = tf.minimum(height, width)
    scale_factor = tf.to_float(min_dimension) / original_min_dim
    new_height = tf.round(height * scale_factor)
    new_width = tf.round(width * scale_factor)

    new_size = [tf.to_int32(new_height), tf.to_int32(new_width)]
    image = tf.image.resize_images(image, new_size, method=RESIZE_METHOD)
    return image

def get_random_crop(image_as_string, boxes):

    distorted_bounding_box = tf.image.sample_distorted_bounding_box(
        tf.image.extract_jpeg_shape(image_as_string),
        bounding_boxes=tf.expand_dims(boxes, axis=0),
        min_object_covered=0.25,
        aspect_ratio_range=[0.75, 1.33],
        area_range=[0.08, 1.0],
        max_attempts=100,
        use_image_if_no_bounding_boxes=True
    )
    begin, size, _ = distorted_bounding_box
    offset_y, offset_x, _ = tf.unstack(begin)
    target_height, target_width, _ = tf.unstack(size)
    crop_window = tf.stack([offset_y, offset_x, target_height, target_width])

    crop = tf.image.decode_and_crop_jpeg(
        image_as_string, crop_window, channels=3
    )
    return crop

def central_crop(image, crop_height, crop_width):
    shape = tf.shape(image)
    height, width = shape[0], shape[1]

    amount_to_be_cropped_h = (height - crop_height)
    crop_top = amount_to_be_cropped_h // 2
    amount_to_be_cropped_w = (width - crop_width)
    crop_left = amount_to_be_cropped_w // 2

    return tf.slice(image, [crop_top, crop_left, 0], [crop_height, crop_width, -1])

def random_color_manipulations(image, probability=0.1, grayscale_probability=0.1, fast=True):

    def manipulate(image):
        if not fast:
            # intensity and order of this operations are kinda random,
            # so you will need to tune this for you problem
            image = tf.image.random_brightness(image, 0.15)
            image = tf.image.random_contrast(image, 0.8, 1.2)
            image = tf.image.random_hue(image, 0.15)
            image = tf.image.random_saturation(image, 0.8, 1.2)
            image = tf.clip_by_value(image, 0.0, 1.0)
        else:
            image = distort_color_fast(image)
        return image

    def to_grayscale(image):
        image = tf.image.rgb_to_grayscale(image)
        image = tf.image.grayscale_to_rgb(image)
        return image

    with tf.name_scope('random_color_manipulations'):
        do_it = tf.less(tf.random_uniform([]), probability)
        image = tf.cond(do_it, lambda: manipulate(image), lambda: image)

    with tf.name_scope('to_grayscale'):
        make_gray = tf.less(tf.random_uniform([]), grayscale_probability)
        image = tf.cond(make_gray, lambda: to_grayscale(image), lambda: image)

    return image

def distort_color_fast(image):
    with tf.name_scope('distort_color'):
        br_delta = tf.random_uniform([], -32.0/255.0, 32.0/255.0)
        cb_factor = tf.random_uniform([], -0.1, 0.1)
        cr_factor = tf.random_uniform([], -0.1, 0.1)
        channels = tf.split(axis=2, num_or_size_splits=3, value=image)
        red_offset = 1.402 * cr_factor + br_delta
        green_offset = -0.344136 * cb_factor - 0.714136 * cr_factor + br_delta
        blue_offset = 1.772 * cb_factor + br_delta
        channels[0] += red_offset
        channels[1] += green_offset
        channels[2] += blue_offset
        image = tf.concat(axis=2, values=channels)
        image = tf.clip_by_value(image, 0.0, 1.0)
        return image

MOMENTUM = 0.9
USE_NESTEROV = True
MOVING_AVERAGE_DECAY = 0.995

def model_fn(features, labels, mode, params):
    """
    This is a function for creating a computational tensorflow graph.
    The function is in format required by tf.estimator.
    """

    is_training = mode == tf.estimator.ModeKeys.TRAIN
    logits = shufflenet(
        features['images'], is_training,
        num_classes=params['num_classes'],
        depth_multiplier=params['depth_multiplier']
    )
    predictions = {
        'probabilities': tf.nn.softmax(logits, axis=1),
        'classes': tf.argmax(logits, axis=1, output_type=tf.int32)
    }

    if mode == tf.estimator.ModeKeys.PREDICT:
        export_outputs = tf.estimator.export.PredictOutput({
            name: tf.identity(tensor, name)
            for name, tensor in predictions.items()
        })
        return tf.estimator.EstimatorSpec(
            mode, predictions=predictions,
            export_outputs={'outputs': export_outputs}
        )

    with tf.name_scope('weight_decay'):
        add_weight_decay(params['weight_decay'])
        regularization_loss = tf.losses.get_regularization_loss()

    with tf.name_scope('cross_entropy'):
        losses = tf.nn.sparse_softmax_cross_entropy_with_logits(labels=labels['labels'], logits=logits)
        loss = tf.reduce_mean(losses, axis=0)
        tf.losses.add_loss(loss)

    total_loss = tf.losses.get_total_loss(add_regularization_losses=True)
    tf.summary.scalar('cross_entropy_loss', loss)
    tf.summary.scalar('regularization_loss', regularization_loss)

    if mode == tf.estimator.ModeKeys.EVAL:
        eval_metric_ops = {
            'accuracy': tf.metrics.accuracy(labels['labels'], predictions['classes']),
            'top5_accuracy': tf.metrics.mean(tf.to_float(tf.nn.in_top_k(
                predictions=predictions['probabilities'], targets=labels['labels'], k=5
            )))
        }
        return tf.estimator.EstimatorSpec(mode, loss=total_loss, eval_metric_ops=eval_metric_ops)

    assert mode == tf.estimator.ModeKeys.TRAIN
    with tf.variable_scope('learning_rate'):
        global_step = tf.train.get_global_step()
        learning_rate = tf.train.polynomial_decay(
            params['initial_learning_rate'], global_step,
            params['decay_steps'], params['end_learning_rate'],
            power=1.0
        )  # linear decay
        tf.summary.scalar('learning_rate', learning_rate)

    update_ops = tf.get_collection(tf.GraphKeys.UPDATE_OPS)
    with tf.control_dependencies(update_ops), tf.variable_scope('optimizer'):
        optimizer = tf.train.MomentumOptimizer(learning_rate, momentum=MOMENTUM, use_nesterov=USE_NESTEROV)
        grads_and_vars = optimizer.compute_gradients(total_loss)
        train_op = optimizer.apply_gradients(grads_and_vars, global_step)

    for g, v in grads_and_vars:
        tf.summary.histogram(v.name[:-2] + '_hist', v)
        tf.summary.histogram(v.name[:-2] + '_grad_hist', g)

    with tf.name_scope('evaluation_ops'):
        train_accuracy = tf.reduce_mean(tf.to_float(tf.equal(
            labels['labels'], predictions['classes']
        )), axis=0)
        train_top5_accuracy = tf.reduce_mean(tf.to_float(tf.nn.in_top_k(
            predictions=predictions['probabilities'], targets=labels['labels'], k=5
        )), axis=0)
    tf.summary.scalar('train_accuracy', train_accuracy)
    tf.summary.scalar('train_top5_accuracy', train_top5_accuracy)

    with tf.control_dependencies([train_op]), tf.name_scope('ema'):
        ema = tf.train.ExponentialMovingAverage(decay=MOVING_AVERAGE_DECAY, num_updates=global_step)
        train_op = ema.apply(tf.trainable_variables())

    return tf.estimator.EstimatorSpec(mode, loss=total_loss, train_op=train_op)

def add_weight_decay(weight_decay):
    weights = [
        v for v in tf.trainable_variables()
        if 'weights' in v.name and 'depthwise_weights' not in v.name
    ]
    for w in weights:
        value = tf.multiply(weight_decay, tf.nn.l2_loss(w))
        tf.add_to_collection(tf.GraphKeys.REGULARIZATION_LOSSES, value)

class RestoreMovingAverageHook(tf.train.SessionRunHook):
    def __init__(self, model_dir):
        super(RestoreMovingAverageHook, self).__init__()
        self.model_dir = model_dir

    def begin(self):
        ema = tf.train.ExponentialMovingAverage(decay=MOVING_AVERAGE_DECAY)
        variables_to_restore = ema.variables_to_restore()
        self.load_ema = tf.contrib.framework.assign_from_checkpoint_fn(
            tf.train.latest_checkpoint(self.model_dir), variables_to_restore
        )

    def after_create_session(self, sess, coord):
        tf.logging.info('Loading EMA weights...')
        self.load_ema(sess)

"""
The purpose of this script is to train a network.
Evaluation will happen periodically.
To use it just run:
python train.py
Parameters below is for training 0.5x version.
"""

# 1281144/128 = 10008.9375
# so 1 epoch ~ 10000 steps

GPU_TO_USE = '0'
BATCH_SIZE = 128
VALIDATION_BATCH_SIZE = 512
NUM_EPOCHS = 133  # set 166 for 1.0x version
TRAIN_DATASET_SIZE = 1281144
NUM_STEPS = NUM_EPOCHS * (TRAIN_DATASET_SIZE // BATCH_SIZE)
PARAMS = {
    'train_dataset_path': '/mnt/datasets/imagenet/train_shards/',
    'val_dataset_path': '/mnt/datasets/imagenet/val_shards/',
    'weight_decay': 4e-5,
    'initial_learning_rate': 0.0625,  # 0.5/8
    'decay_steps': NUM_STEPS,
    'end_learning_rate': 1e-6,
    'model_dir': 'models/run00/',
    'num_classes': 1000,
    'depth_multiplier': '0.5'  # set '1.0' for 1.0x version
}

def get_input_fn(is_training):

    dataset_path = PARAMS['train_dataset_path'] if is_training else PARAMS['val_dataset_path']
    filenames = os.listdir(dataset_path)
    filenames = [n for n in filenames if n.endswith('.tfrecords')]
    filenames = [os.path.join(dataset_path, n) for n in sorted(filenames)]

    batch_size = BATCH_SIZE if is_training else VALIDATION_BATCH_SIZE
    num_epochs = None if is_training else 1

    def input_fn():
        pipeline = Pipeline(
            filenames, is_training,
            batch_size=batch_size,
            num_epochs=num_epochs
        )
        return pipeline.dataset

    return input_fn

session_config = tf.ConfigProto(allow_soft_placement=True)
session_config.gpu_options.visible_device_list = GPU_TO_USE
run_config = tf.estimator.RunConfig()
run_config = run_config.replace(
    model_dir=PARAMS['model_dir'], session_config=session_config,
    save_summary_steps=500, save_checkpoints_secs=1200,
    log_step_count_steps=500
)

train_input_fn = get_input_fn(is_training=True)
val_input_fn = get_input_fn(is_training=False)
estimator = tf.estimator.Estimator(model_fn, params=PARAMS, config=run_config)

train_spec = tf.estimator.TrainSpec(train_input_fn, max_steps=NUM_STEPS)
eval_spec = tf.estimator.EvalSpec(
    val_input_fn, steps=None, start_delay_secs=3600 * 2, throttle_secs=3600 * 2,
    hooks=[RestoreMovingAverageHook(PARAMS['model_dir'])]
)
tf.estimator.train_and_evaluate(estimator, train_spec, eval_spec)


#csv = comma seperated values
import csv
fruit = [
    ['rice','soup'],
    ['noodles','milk'],
    ['eggs','onion'],
    ]

#write
print("write to csv...")
with open('fruit','wt') as fout:
    csvout = csv.writer(fout)
    csvout.writerows(fruit)

#read
with open('fruit','rt') as fin:
    cin = csv.reader(fin)
    fruit = [row for row in cin]

print("read from csv...")
print(fruit)


import json

from src.api.api import API, TagAPI, QueryAPI
from src.db.workout import models
from src.utils.db_utils import DBConnection
from src.utils import log

WORKOUT_DB = None

LOGGER = log.new_logger()

STORED_APIS = {"API": None, "TagAPI": None, "QueryAPI": None}

def get_db():
    global WORKOUT_DB
    if not WORKOUT_DB:
        LOGGER.info("Instantiating new db connection", db_connection="new")
        WORKOUT_DB = DBConnection(LOGGER).workout_db
    else:
        LOGGER.info("Reusing DB connection", db_connection="reuse")
    LOGGER.info("Connection established")
    return WORKOUT_DB

def get_api(api_type=API):
    global STORED_APIS
    name = api_type.__name__
    if name in STORED_APIS and STORED_APIS[name] is not None:
        return STORED_APIS[name]
    STORED_APIS[name] = api_type(get_db(), LOGGER)
    return STORED_APIS[name]

def equipment_http(request):
    """
    /equipment
    """
    return get_api().parse(request, models.Equipment)

def tags_http(request, is_dev=False):
    """
    /tags

    """
    return TagAPI(
        get_db(),
        [
            models.TagType.TAG,
            models.TagType.SPORT,
            models.TagType.CREATOR,
            models.TagType.EQUIPMENT,
        ],
        LOGGER,
    ).parse(request, models.Tags)

def exercises_http(request, is_dev=False):
    """
    /exercises

    """
    return TagAPI(get_db(), [models.TagType.EXERCISE], LOGGER).parse(
        request, models.Tags
    )

def everything_http(request, is_dev=False):
    """
    /everything

    """
    if request.method != "GET":
        return API.error("Must send as a GET request")
    request.args = {}
    data = {
        "tags": json.loads(tags_http(request))["body"],
        "equipment": json.loads(equipment_http(request))["body"],
        "exercises": json.loads(exercises_http(request))["body"],
        "workouts": json.loads(workouts_http(request))["body"],
        "sources": json.loads(sources_http(request))["body"],
    }

    return API.success(data)

def sources_http(request, is_dev=False):
    return get_api(QueryAPI).parse(
        request, models.SourcesMaterialized, {"id": int, "url": str,}
    )

def workouts_http(request, is_dev=False):
    return get_api(QueryAPI).parse(
        request, models.WorkoutsMaterialized, {"id": int, "url": str,}
    )

if __name__ == "__main__":
    pass


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

# order is important
acceptedWayColors = ['red', 'blue', 'green', 'yellow', 'mtb']
acceptedBgColors = ['white']
acceptedFgColors = acceptedWayColors
acceptedSymbols = ['bar', 'dot', 'backslash', 'bowl', 'L', 'turned_T', 'triangle', 'corner', 'mtb']
# other symbols are now rendered as 'bar' for simplicity
otherSymbols = ['diamond', 'cross', 'circle', 'fork', 'rectangle', 'lower', 'yes']

class OsmcSymbol:
    def __init__(self, osmc_string):
        self.parts = osmc_string.replace('\\', 'backslash').split(':')
        self.wayColor = None
        self.bgColor = None
        self.fgColor = None
        self.symbol = None
        self.text = None
        if len(self.parts):
            self._parse_parts()

    def _parse_parts(self):
        if len(self.parts) >= 1:
            self.wayColor = self.parts[0]
        if len(self.parts) >= 2:
            self.bgColor = self.parts[1]
        if len(self.parts) >= 3:
            fg_parts = self.parts[2].split('_', 1)
            if len(fg_parts) == 2:
                if fg_parts[1] in otherSymbols:
                    fg_parts[1] = 'bar'
                    self.parts[2] = '_'.join(fg_parts)
                self.fgColor = fg_parts[0]
                self.symbol = fg_parts[1]
                if self.fgColor != self.wayColor and self.bgColor == self.wayColor:
                    # treat symbols like red:red:white_bar the same way as red:white:red_bar
                    self.bgColor = self.fgColor
                    self.fgColor = self.wayColor
            else:
                if len(fg_parts) == 1:
                    self.symbol = fg_parts[0]

                    # treat symbols like red:white:dot like red:white:red_dot
                    self.fgColor = self.wayColor
        if len(self.parts) >= 4:
            self.text = ':'.join(self.parts[3:])

    def is_accepted(self):
        return ((self.wayColor in acceptedWayColors)
                and (self.bgColor in acceptedBgColors)
                and (self.fgColor == self.wayColor)
                and (self.symbol in acceptedSymbols))

    def get_string_value(self):
        if len(self.parts) < 3:
            return ':'.join(self.parts)

        return ':'.join([self.wayColor, self.bgColor, self.fgColor + '_' + self.symbol])

    def __lt__(self, other):
        if self.is_accepted() and other.is_accepted():
            if self.symbol == other.symbol:
                return acceptedWayColors.index(self.wayColor) > acceptedWayColors.index(other.wayColor)
            else:
                return acceptedSymbols.index(self.symbol) > acceptedSymbols.index(other.symbol)


from fastapi import FastAPI, status
# from starlette import status #上面的status继承自这

app = FastAPI()

#post
@app.post("/items/", status_code=201)
async def create_item(name: str):
    return {"name": name}

#get
@app.get("/items2/", status_code=201)
async def create_item2(name: str):
    return {"name": name}

#
@app.post("/items3/", status_code=status.HTTP_404_NOT_FOUND)#不一定写数字,也定义了意思常量
async def create_item3(name: str):
    print('HTTP_404:', status.HTTP_404_NOT_FOUND)
    return {"name": name}

#
@app.get("/i/", status_code=status.HTTP_404_NOT_FOUND)
async def i(name: str):
    print('HTTP_404:', status.HTTP_404_NOT_FOUND)
    return {"name": name}

if __name__ == '__main__':
    import uvicorn
    uvicorn.run(app, host="127.0.0.1", port=8000)

D_响应状态码与错误处理/d016_响应状态码.py


import importlib
import torch.utils.data
from torch.utils.data._utils.collate import default_collate
import numpy as np

from data.base_dataset import BaseDataset
from tools.utils import get_vprint

def find_dataset_using_name(dataset_name):
    # Given the option --dataset [datasetname],
    # the file "datasets/datasetname_dataset.py"
    # will be imported.
    dataset_filename = "data." + dataset_name + "_dataset"
    datasetlib = importlib.import_module(dataset_filename)

    # In the file, the class called DatasetNameDataset() will
    # be instantiated. It has to be a subclass of BaseDataset,
    # and it is case-insensitive.
    dataset = None
    target_dataset_name = dataset_name.replace('_', '') + 'dataset'
    for name, cls in datasetlib.__dict__.items():
        if name.lower() == target_dataset_name.lower() \
           and issubclass(cls, BaseDataset):
            dataset = cls

    if dataset is None:
        raise ValueError(f"In {dataset_filename}.py, there should be a subclass of BaseDataset "
                         f"with class name that matches {target_dataset_name} in lowercase.")

    return dataset

def create_dataset(opt, phase='train', fold=None, from_vid=False, load_vid=False, verbose=True):
    dataset = find_dataset_using_name(opt.dataset)
    instance = dataset(opt, phase=phase, fold=fold, from_vid=from_vid, load_vid=load_vid, verbose=verbose)
    file_type = "video" if from_vid else "img"
    load_type = "video" if load_vid else "img"
    vprint = get_vprint(verbose)
    fold_str = f"-{fold}" if fold is not None else ""
    vprint(f"Creation of dataset [{type(instance).__name__}-{phase}{fold_str}] of size {len(instance)} "
           f"loading {load_type} data from {file_type} data")
    return instance

def create_dataloader(dataset, batch_size, num_workers, is_train):
    dataloader = torch.utils.data.DataLoader(
        dataset,
        batch_size=batch_size,
        shuffle=is_train,
        num_workers=num_workers,
        drop_last=is_train,
        worker_init_fn=lambda _: np.random.seed(),
        collate_fn=custom_collate_fn
    )
    return dataloader

def custom_collate_fn(batch):
    input_dict = {}
    elem = batch[0]
    for key in elem:
        if key in ["img", "mask_img", "flow_img", "layout"] and elem[key].ndim == 4:
            input_dict[key] = torch.cat([d[key] for d in batch], dim=0)
        else:
            input_dict[key] = default_collate([d[key] for d in batch])
    return input_dict


# We'll start by creating a Node class,
# which represents a single node in the
# linked list. Each node contains two main
# components: the data it holds and a
# reference to the next node.

class Node:
    def __init__(self, data, next=None):
        self.data = data
        self.next = next

# Next, we'll create the LinkedList class,
# which will handle the operations related
# to the linked list, such as insertion,
# deletion, searching, etc.

class LinkedList:
    def __init__(self):
        self.head = None

    def display(self):
        # To print the contents of the linked list,
        # we need to traverse through each node and
        # print its data.
        current = self.head
        while current:
            print(current.data, end=" ")
            current = current.next

    def insert_at_beginning(self, data):
        # Method to insert a new node at the
        # beginning of the linked list.
        new_node = Node(data)
        new_node.next = self.head
        self.head = new_node

    def insert_at_end(self, data):
        # insert a node at the end of the
        # linked list, we need to traverse
        # to the last node and then add the new node.
        new_node = Node(data)
        if not self.head:
            self.head = new_node
        else:
            current = self.head
            while current.next:
                current = current.next
            current.next = new_node

    def delete(self, data):
        # To delete a node from the linked list,
        # we need to find the node and update
        # the references to bypass it.
        if not self.head:
            return
        if self.head.data == data:
            self.head = self.head.next
            return
        current = self.head
        while current.next:
            if current.next.data == data:
                current.next = current.next.next
                return
            current = current.next

    def search(self, data):
        # search for a value in the linked list, we
        # can traverse the list and compare each
        # node's data with the target value.
        current = self.head
        while current:
            if current.data == data:
                return True
            current = current.next
        return False

def main():
    # Create an instance of the LinkedList class
    my_list = LinkedList()
    # Insert nodes
    my_list.insert_at_beginning(3)
    my_list.insert_at_beginning(2)
    my_list.insert_at_beginning(1)
    my_list.insert_at_end(4)
    # Display the linked list
    my_list.display()  # Output: 1 2 3 4
    # Delete a node
    my_list.delete(2)
    # Display the linked list after deletion
    my_list.display()  # Output: 1 3 4
    # Search for a value
    print(my_list.search(3))  # Output: True
    print(my_list.search(5))  # Output: False

main()


from django import forms

class diagnosisform2(forms.Form):
    presence = forms.ChoiceField(
                widget=forms.RadioSelect(
                    attrs={"class": "form-check-input", "id": "hi"}
                ),
                choices=[("no", "no"), ("yes", "yes")],
            )

class diagnosisform(forms.Form):
    def __init__(self, *args, **kwargs):
        n_diagnoses = kwargs.pop("n_diagnoses")
        super(diagnosisform, self).__init__(*args, **kwargs)
        for i in range(n_diagnoses):
            # self.fields['i' + str(i)] =  forms.CharField(label=i)
            self.fields["i" + str(i)] = forms.ChoiceField(
                widget=forms.RadioSelect(
                    attrs={"class": "form-check-input", "id": "hi" + str(i)}
                ),
                choices=[("no", "no"), ("yes", "yes")],
            )
    # answer = forms.ChoiceField(widget=forms.RadioSelect(attrs={'class': 'form-check-input', 'id': 'hi'}), choices=CHOICES)
    # https://stackoverflow.com/questions/17159567/how-to-create-a-list-of-fields-in-django-forms

class SignupForm(forms.Form):
	#django gives a number of predefined fields
	#CharField and EmailField are only two of them
	#go through the official docs for more field details
	name = forms.CharField(label='Enter your name', max_length=100)

# https://techincent.com/render-django-form-individual-fields-manually/


from flask import g, flash

from bluecat.api_exception import PortalException
import config.default_config as config
from bluecat.util import safe_str

def get_acls(**kwargs):
    """
    Retrieve all ACLs from default configuration
    :return: All ACLs in default configuration
    """
    # Use the default result template to store results
    result = []

    # Retrieve the configuration object
    try:
        configuration = g.user.get_api().get_configuration(config.default_configuration)
    except PortalException as e:
        g.user.logger.error('%s' % e, msg_type=g.user.logger.EXCEPTION)
        flash('Configuration %s could not be retrieved from the Gateway configuration' % config.default_configuration)
        return result

    # Retrieve list of ACLs from configuration
    acls = configuration.get_children_of_type('ACL')

    # Loop through ACLs appending to result dictionary
    for acl in acls:
        result.append((acl.get_id(), safe_str(acl.get_name())))

    return result


def process_inputs(file_path):
    with open(file_path, 'r') as f:
        return f.read().split('\n')

def part_1(input):
    result = 0

    for racksack in input:
        length = len(racksack)
        first = racksack[:length // 2]
        second = racksack[length // 2:]

        common = set(first).intersection(second).pop()

        result += get_value(common)

    return result

def get_value(common):
    if common >= 'A' and common <= 'Z':
        return ord(common) % 64 + 26
    else:
        return ord(common) % 96

def part_2(input):
    result = 0

    for first, second, third in zip(*[iter(input)] * 3):
        common = set(first).intersection(second).intersection(third).pop()
        result += get_value(common)

    return result

if __name__ == '__main__':
    file_path = './3-Rucksack_Reorganization/input.txt'
    input = process_inputs(file_path)

    print("--Part 1--")
    print(part_1(input))

    print("--Part 2--")
    print(part_2(input))


import sys
input = sys.stdin.readline
n = int(input())
A = list(map(int,input().split()))
A.sort()
i = 0
j = 1
k = 2

cnt = 0
if n < 3:
    print(0)
else:
    while k != n:
        if A[i]+A[j] == A[k]:
            cnt += 1
            k += 1
        elif i-1 == j:
            j += 1
        elif A[i]+A[j] < A[k]:
            if i-1 == j:
                j += 1
                i += 1
            else:
                i+=1
        elif A[i]+A[j] > A[k]:
            k += 1

    print(cnt)


"""
Implement atoi which converts a string to an integer.

The function first discards as many whitespace characters as necessary until the first non-whitespace character is found. Then, starting from this character takes an optional initial plus or minus sign followed by as many numerical digits as possible, and interprets them as a numerical value.

The string can contain additional characters after those that form the integral number, which are ignored and have no effect on the behavior of this function.

If the first sequence of non-whitespace characters in str is not a valid integral number, or if no such sequence exists because either str is empty or it contains only whitespace characters, no conversion is performed.

If no valid conversion could be performed, a zero value is returned.

Note:

Only the space character ' ' is considered a whitespace character.
Assume we are dealing with an environment that could only store integers within the 32-bit signed integer range: [−231,  231 − 1]. If the numerical value is out of the range of representable values, 231 − 1 or −231 is returned.
"""

class Solution(object):
    def myAtoi(self, s):
        """
        :type s: str
        :rtype: int
        """
        num_start = False
        ret_num = ""
        is_positive = True
        for i in range(len(s)):
            cur_char = s[i]
            if num_start == False:
                if cur_char == ' ':
                    continue
                elif cur_char == '-':
                    num_start = True
                    is_positive = False
                elif cur_char == '+':
                    num_start = True
                elif cur_char.isdigit():
                    num_start = True
                    ret_num += cur_char
                elif not cur_char.isdigit():
                    return 0
            else:
                if cur_char.isdigit():
                    ret_num += cur_char
                else:
                    break

        if ret_num == "":
            return 0

        if is_positive:
            ret_num = int(ret_num)
        else:
            ret_num = -1 * int(ret_num)

        if ret_num >= 2**31 - 1:
            return 2**31 - 1
        elif ret_num <= -2**31:
            return -2**31
        else:
            return ret_num

"""
Example 1:

Input: str = "42"
Output: 42

Example 2:

Input: str = "   -42"
Output: -42

Example 3:

Input: str = "4193 with words"
Output: 4193

Example 4:

Input: str = "words and 987"
Output: 0

Example 5:

Input: str = "-91283472332"
Output: -2147483648

Time: O(n) (n is the length of the string)
"""


from enum import Enum
from math import radians, sin, cos, sqrt, atan2

from enums.DistanceType import DistanceType

def calculate_distance(lat1, lon1, lat2, lon2, distance_type=DistanceType.MILES):
    # Convert coordinates to radians
    lat1_rad, lon1_rad, lat2_rad, lon2_rad = map(radians, [lat1, lon1, lat2, lon2])

    # Earth's radius in miles or kilometers
    radius = 3959 if distance_type == DistanceType.MILES else 6371

    # Haversine formula to calculate distance
    dlat = lat2_rad - lat1_rad
    dlon = lon2_rad - lon1_rad
    a = sin(dlat / 2) ** 2 + cos(lat1_rad) * cos(lat2_rad) * sin(dlon / 2) ** 2
    c = 2 * atan2(sqrt(a), sqrt(1 - a))
    distance = radius * c

    print(distance)

    return distance


"""This file includes the memory structure for the bot. The core memory structure is simply a dictionary with
embeddings as the keys and summaries as the values. When searching for a memory, a string is input, for which
an embedding is generated. The system then returns the n most similar summaries that are within a range and
have not been used in the current conversation."""

from transformers import AutoTokenizer, AutoModel
import torch
import numpy as np

'''LT memory is essentially a dictionary that uses embeddings as keys and summaries as values.'''
class LTMemory_System():
    def __init__(self):
        self.tokenizer = AutoTokenizer.from_pretrained("bert-base-uncased")
        self.model = AutoModel.from_pretrained("bert-base-uncased")
        self.lt_memory = dict() #hash -> summary
        self.keys = dict() #hash -> embedding

    def generate_embedding(self, doc_string): #input: document string, output: numerical embeddings
        inputs = self.tokenizer(doc_string, padding=True, truncation=True, return_tensors="pt")
        with torch.no_grad():
            outputs = self.model(**inputs)
        embeddings = outputs.last_hidden_state.mean(dim=1)
        return np.array(embeddings)

    def add_memory(self, summary): #input: summary string
        embedding = self.generate_embedding(summary)
        hashed = hash(embedding.tostring())
        self.lt_memory[hashed] = summary
        self.keys[hashed] = embedding

    def access_memory(self, embedding): #input: numerical embedding; output: summary
        return self.lt_memory[hash(embedding.tostring())]

    def get_closest_memories(self, embedding, k=3): #input: embedding; output: k closest summaries, k closest embeddings
        distances = []
        for i, embedding_2 in enumerate(self.keys.keys()):
            dist = self.euclidean_distance(embedding, embedding_2)
            distances.append((embedding_2, dist))

        distances.sort(key=lambda x: x[1])

        k_closest_indices = [x[0] for x in distances[:k]]

        return [self.lt_memory[embedding] for embedding in k_closest_indices], [embedding for embedding in k_closest_indices]

    def euclidean_distance(self, arr1, arr2):
        return np.linalg.norm(arr1 - arr2)

    def to_string(self):
        output = ""
        for key, value in self.lt_memory.items():
            output += f"{key}: {value}\n"
        return output


from sqlalchemy import create_engine, Column, Integer, String
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
Base = declarative_base()

__all__ = ['CoreInstance', 'get_division', 'get_release']

class Meta(Base):
    __tablename__ = 'meta'

    meta_id = Column(Integer, primary_key=True)
    meta_key = Column(String)
    meta_value = Column(String)

    def __repr__(self):
        return "<Meta(meta_id='%s',meta_key='%s', meta_value='%s')>" % (
            self.meta_id, self.meta_key, self.meta_value)

Session = sessionmaker()

class CoreInstance:

    __division = None
    __release = None

    def __init__(self, url, timeout=3600):
        self.engine = create_engine(url, pool_recycle=timeout, echo=False)
        Session.configure(bind=self.engine)

    def __get_meta_value(self, meta_key):
        s = Session()
        try:
            meta = s.query(Meta).filter(Meta.meta_key == meta_key).first()
            return meta.meta_value
        finally:
            s.close()

    @property
    def division(self):
        if self.__division is None:
            self.__division = self.__get_meta_value('species.division')
        return self.__division

    @property
    def release(self):
        if self.__release is None:
            self.__release = self.__get_meta_value('schema_version')
        return self.__release

def get_division(src_uri, tgt_uri, db_type):
    uri = src_uri
    if db_type == "variation" or db_type == "funcgen":
        uri = tgt_uri.replace("_variation_", "_core_").replace("_funcgen_","_core_")
    inst = CoreInstance(uri)
    division_meta = inst.division
    division = str(division_meta).replace('Ensembl','')
    return division.lower()

def get_release(src_uri):
    inst = CoreInstance(src_uri)
    return int(inst.release)


import torch
import torch.nn as nn
from torch.autograd import Variable

import mlflow
import mlflow.pytorch

class RNN(nn.Module):
    def __init__(self, i_size, h_size, n_layers, o_size):
        super(RNN, self).__init__()

        self.rnn = nn.LSTM(
            input_size=i_size,
            hidden_size=h_size,
            num_layers=n_layers
        )
        self.out = nn.Linear(h_size, o_size)

    def forward(self, x, h_state):
        r_out, hidden_state = self.rnn(x, h_state)

        hidden_size = hidden_state[-1].size(-1)
        r_out = r_out.view(-1, hidden_size)
        outs = self.out(r_out)

        return outs, hidden_state

def train_mlmodel(x_train, y_train, parameters):
    rnn = RNN(parameters['INPUT_SIZE'], parameters["HIDDEN_SIZE"], parameters['NUM_LAYERS'], parameters['OUTPUT_SIZE'])
    optimizer = torch.optim.Adam(rnn.parameters(), lr=parameters['learning_rate'])
    criterion = nn.MSELoss()
    hidden_state = None

    mlflow.set_experiment(parameters['EXP_NAME'])
    with mlflow.start_run(run_name=parameters['RUN_NAME']) as run:
        for epoch in range(parameters['num_epochs']):
            inputs = Variable(torch.from_numpy(x_train).float())
            labels = Variable(torch.from_numpy(y_train).float())
            output, hidden_state = rnn(inputs, hidden_state)
            loss = criterion(output.view(-1), labels)
            optimizer.zero_grad()
            # torch.autograd.set_detect_anomaly(True)
            loss.backward(retain_graph=True)
            optimizer.step()

            print('epoch{}, loss{}'.format(epoch, loss.item()))
            mlflow.log_metric("epoch "+ str(epoch), loss.item())
        mlflow.log_param('loss_type', 'MSELoss')
        mlflow.log_param('test_data_ratio', parameters['test_data_ratio'])
        mlflow.log_param('num_train_iter', parameters['num_train_iter'])
        mlflow.log_param('learning_rate', parameters['learning_rate'])
        mlflow.log_param('INPUT_SIZE', parameters['INPUT_SIZE'])
        mlflow.log_param('HIDDEN_SIZE', parameters['HIDDEN_SIZE'])
        mlflow.log_param('NUM_LAYERS', parameters['NUM_LAYERS'])
        mlflow.log_param('OUTPUT_SIZE', parameters['OUTPUT_SIZE'])
        mlflow.log_param('num_epochs', parameters['num_epochs'])
        mlflow.pytorch.log_model(rnn, 'model')
    mlflow.end_run()
    return rnn


import requests
from django.views.generic import ListView, DetailView, UpdateView, CreateView, DeleteView, TemplateView, FormView, View
from .models import *
from django.shortcuts import render
from django.core.paginator import Paginator  # импортируем класс, позволяющий удобно осуществлять постраничный вывод
from .filters import PostFilter  # импортируем недавно написанный фильтр
from .forms import PostForm, CatForm
from django.shortcuts import redirect
from django.contrib.auth.models import Group
from django.contrib.auth.decorators import login_required
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.auth.mixins import PermissionRequiredMixin
from django.core.mail import send_mail
from django.core.mail import EmailMultiAlternatives
from django.template.loader import render_to_string
from django.db.models.signals import ModelSignal
from datetime import datetime, date, time
from django.core.cache import cache
import logging
from django.utils.translation import gettext as _  # импортируем функцию для перевода
from django.http import HttpResponse
# class NewsListN(ListView):
#     model = Post
#     template_name = 'news.html'
#     context_object_name = 'post'
#     queryset = Post.objects.filter(noa='N')
#
#     # class NewsListPost(ListView):
#     #     model = Post
#     #     template_name = 'news.html'
#     #     context_object_name = 'post'
#     #     queryset = News.objects.order_by('-id').filter(noa='A')
#
#
# class DetailNew(DetailView):
#     model = Post
#     template_name = 'new.html'
#     context_object_name = 'new'
#     queryset = Post.objects.filter(noa='N')

# logger = logging.getLogger(__name__)

custom_create_signal = ModelSignal(use_caching=True)
custom_update_signal = ModelSignal(use_caching=True)

class NewsListN(ListView):
    model = Post
    template_name = 'news_list.html'
    context_object_name = 'post'
    queryset = Post.objects.filter(noa='N')
    ordering = ['-id']
    paginate_by = 15  # поставим постраничный вывод в один элемент
    # form_class = PostForm

    def get_filter(self):
        return PostFilter(self.request.GET, queryset=super().get_queryset())

    def get_queryset(self):
        return self.get_filter().qs

    def get_context_data(self, *args, **kwargs):
        context = super().get_context_data(*args, **kwargs)
        context['filter'] = self.get_filter()
        return context

class NewsDetailView(DetailView):
    template_name = 'news_detail.html'
    queryset = Post.objects.all()

    # def get_object(self, *args, **kwargs):
    #     # obj = cache.get(f'post-{self.kwargs["pk"]}', None)
    #
    #     # if not obj:
    #     obj = super().get_object(queryset=kwargs['queryset'])
    #         # cache.set(f'post-{self.kwargs["pk"]}', obj)
    #     return obj

class NewsCreateView(LoginRequiredMixin, PermissionRequiredMixin,  CreateView):
    template_name = 'news_create.html'
    form_class = PostForm
    permission_required = ('news.add_post',)

    def form_valid(self, form):
        self.object = form.save(commit=False)
        self.object.author = Author.objects.get_or_create(name=self.request.user)[0]
        # user = self.request.user
        all_post_author = self.object.author.post_set.all() # Добавили все посты автора
        count_today_post = 0
        for post in all_post_author:
            if post.author == self.object.author:
                time_delta = datetime.now().date() - post.time_in.date()
                if time_delta.total_seconds() < 86400:
                    count_today_post += 1
        if count_today_post < 3:

            self.object.save()
        else:
            return self.handle_no_permission()
        category = Category.objects.get(pk=self.request.POST['category'])
        self.object.category.add(category)
        custom_create_signal.send(sender=Post, instance=self.object, created=True)

        return super().form_valid(form)
        # text = self.object.text
        # heading = self.object.heading
        # if user.subscribe_category == category:
        #     html_content = render_to_string(
        #         'sub_new_post.html',
        #         {
        #             'user': user,
        #             'category': category,
        #             'heading': heading,
        #             'text': text
        #         }
        #     )
        #
        #     msg = EmailMultiAlternatives(
        #         subject=f'Новая статья в категории: {heading}!',
        #         from_email='murik0525@yandex.ru',
        #         to=['murik0525@yandex.ru'],
        #     )
        #     msg.attach_alternative(html_content, 'text/html')
        #     msg.send()

# дженерик для редактирования объекта
class NewsUpdateView(LoginRequiredMixin, PermissionRequiredMixin, UpdateView):
    template_name = 'news_create.html'
    form_class = PostForm
    permission_required = ('news.change_post',)

    def dispatch(self, request, *args, **kwargs):
        user = request.user
        author = Author.objects.get(name=user)
        if not author.post_set.filter(pk=kwargs.get('pk')).exists():
            return self.handle_no_permission()
        return super().dispatch(request, *args, **kwargs)

    # метод get_object мы используем вместо queryset, чтобы получить информацию об объекте, который мы собираемся редактировать
    def get_object(self, **kwargs):
        id = self.kwargs.get('pk')
        return Post.objects.get(pk=id)

    def form_valid(self, form):
        self.object = form.save(commit=False)
        self.object.author = Author.objects.get_or_create(name=self.request.user)[0]
        # user = self.request.user
        self.object.save()
        category = Category.objects.get(pk=self.request.POST['category'])
        self.object.category.add(category)
        custom_update_signal.send(sender=Post, instance=self.object, created=False)
        return super().form_valid(form)

# дженерик для удаления товара
class NewsDeleteView(LoginRequiredMixin, DeleteView):
    template_name = 'news_delete.html'
    queryset = Post.objects.all()
    success_url = '/news/'

    def dispatch(self, request, *args, **kwargs):
        user = request.user
        author = Author.objects.get(name=user)
        if not author.post_set.filter(pk=kwargs.get('pk')).exists():
            return self.handle_no_permission()
        return super().dispatch(request, *args, **kwargs)

class ProfileView(LoginRequiredMixin, TemplateView):
    template_name = 'profile.html'

    def dispatch(self, request, *args, **kwargs):
        user = request.user
        gr = Group.objects.get(name='common')
        if user.is_authenticated:
            gr.user_set.add(user)
            return super().dispatch(request, *args, **kwargs)
        return self.handle_no_permission()

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['is_not_authors'] = not self.request.user.groups.filter(name='authors').exists()
        return context

@login_required
def upgrade_me(request):
    user = request.user
    premium_group = Group.objects.get(name='authors')
    if not request.user.groups.filter(name='authors').exists():
        premium_group.user_set.add(user)
        Author.objects.create(name=user)
    return redirect('/')

class SubscribeCategory(FormView):
    form_class = CatForm
    template_name = 'category.html'
    success_url = '/news/'

    def form_valid(self, form):
        user = self.request.user
        print(user.subscribe_category)
        user.subscribe_category = Category.objects.get(pk=self.request.POST['category'])
        user.save()
        html_content = render_to_string(
            'subscribe_created.html',
            {
                'user': user,
            }
        )

        msg = EmailMultiAlternatives(
            subject='Подписка оформлена!',
            from_email='murik0525@yandex.ru',
            to=[user.email],
        )
        msg.attach_alternative(html_content, 'text/html')
        msg.send()
        return super().form_valid(form)

# Create your views here.

class Index(View):
    def get(self, request):
        string = _('Hello world')

        return HttpResponse(string)


import unittest
from dice_roller import DiceRoller as dr

class TestDiceRoller(unittest.TestCase):

    def setUp(self):
        self.number = 0
        self.two_sided_result = dr.two_sided_roll()
        self.four_sided_result = dr.four_sided_roll()
        self.six_sided_result = dr.six_sided_roll()
        self.ten_sided_result = dr.ten_sided_roll()
        self.twelve_sided_result = dr.twelve_sided_roll()
        self.twenty_sided_reult = dr.twenty_sided_roll()

    def test_two_sided(self):
        for number in range(1, 3):
            if(number == self.two_sided_result):
                self.number = number
        self.assertEquals(self.number, self.two_sided_result)

    def test_four_sided(self):
        for number in range(1, 5):
            if(number == self.four_sided_result):
                self.number = number
        self.assertEquals(self.number, self.four_sided_result)

    def test_six_sided(self):
        for number in range(1, 7):
            if(number == self.six_sided_result):
                self.number = number
        self.assertEquals(self.number, self.six_sided_result)

    def test_ten_sided(self):
        for number in range(1, 11):
            if(number == self.ten_sided_result):
                self.number = number
        self.assertEquals(self.number, self.ten_sided_result)

    def test_twelve_sided(self):
        for number in range(1, 12):
            if(number == self.twelve_sided_result):
                self.number = number
        self.assertEquals(self.number, self.twelve_sided_result)

    def test_twenty_sided(self):
        for number in range(1, 20):
            if(number == self.twenty_sided_reult):
                self.number = number
        self.assertEquals(self.number, self.twenty_sided_reult)

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


from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage
from django.shortcuts import render
from .models import Ordenes
from .forms import OrdenesForm, UpdateOrdenesForm
from django.views.generic.edit import UpdateView
from django.contrib import messages
from django.views.generic.detail import DetailView
from django.views.generic import DeleteView
from django.views.generic.edit import CreateView
from django.urls import reverse_lazy
from django.contrib.messages.views import SuccessMessageMixin
from datetime import date
from .filters import OrdenesFilter, HistoryFilter
from django.db.models import Sum, Max
from operator import sub
from Stock.models import StockMovimientos,Stock

def ListarEntregadosView(request):
    Model_one = Ordenes.objects.all().filter(estado='Completato')

    myFilter = OrdenesFilter(request.GET, queryset=Model_one)
    paginator = Paginator(myFilter.qs, 10)
    page = request.GET.get('page1')
    try:
        pub = paginator.page(page)
    except PageNotAnInteger:
        pub = paginator.page(1)
    except EmptyPage:
        pub = paginator.page(paginator.num_pages)

    myFilter = OrdenesFilter(request.GET, queryset=Model_one)

    context = {'Model_one': Model_one, 'pub': pub, "myFilter": myFilter}
    return render(request, 'ordenes/listarEntregados.html', context)

def dashboard(request):

    # todo crear entregados por mes

    # variables globales para pasar a dashboard
    totalUsado = StockMovimientos.objects.values("nombre__nombre").filter(tipo_de_movimiento=False).annotate(Sum("cantidad"))
    totalprod = Ordenes.objects.values_list("producto__nombre").exclude(cantidadEntregada=None).annotate(cantidad=Sum('cantidad_recibida')).order_by('producto')
    totalprodentregados = Ordenes.objects.values_list("producto__nombre").exclude(cantidadEntregada=None).annotate(cantidad=Sum('cantidadEntregada')).order_by('producto')
    totalprodentregados2 = Ordenes.objects.all().exclude(cantidadEntregada=None).annotate(cantidad=Sum("cantidadEntregada"))
    #funciones para recuperar datos a mostrar

    totalUsadoetiq = []
    totalUsadocant = []
    for i in totalUsado:
        totalUsadoetiq.append(i["nombre__nombre"])
        totalUsadocant.append(i["cantidad__sum"])

    productos1 = []
    for i in totalprod:
        if totalprod[0] != None:
            productos1.append(i[1])
        else:
            productos1.append(0)

    productos2 = []
    listatitulos = []
    for i in totalprodentregados:
        if i[1] != None:
            listatitulos.append(i[0])

            productos2.append(i[1])
        else:
            listatitulos.append(i[0])
            productos2.append(0)

    total = list(map(int.__sub__,productos2,productos1))

    context = {"total": total,"etiquetas":listatitulos,"totalProdEntr":totalprodentregados2,"totalUsadoEtiq":totalUsadoetiq,"totalUsadoCant":totalUsadocant}
    return render(request, 'ordenes/dashboard.html', context)

class CreateOrdenView(SuccessMessageMixin, CreateView):
    form_class = OrdenesForm
    template_name = 'ordenes/crearOrden.html'

    def get_success_url(self):
        return reverse_lazy('listarOrden')

    def form_valid(self, form):
        formulario = form.save(commit=False)

        if formulario.estado == 'Entregado':
            formulario.fecha_entrega_real = date.today()
        else:
            formulario.fecha_entrega_real = None
        formulario.usuarios = self.request.user
        messages.success(self.request, '¡¡¡ Orden %s creada correctamente !!!' % (formulario.producto))
        return super().form_valid(form)

def ListViewOrden(request):
    ordenes = Ordenes.objects.filter(estado='Entregado')
    historial = Ordenes.history.all()
    # ----------------------------------------------- graficas----------------------------------
    totalprod = Ordenes.objects.values_list("producto__nombre").annotate(cantidad=Sum('cantidad_recibida')).order_by('producto')
    totalprodentregados = Ordenes.objects.values_list("producto__nombre").annotate(cantidad=Sum('cantidadEntregada')).order_by('producto')
    totalfechasentregadas = Ordenes.objects.values_list("fecha_entrega_real", 'producto__nombre', 'cantidadEntregada').order_by('producto')
    listaTodos = []
    listaproductos = []
    listaEtiquetas = []

    for i in totalfechasentregadas:
        if i[0] != None:
            listaTodos.append(i)

    print(listaTodos)

    for i in totalprodentregados:
        if i[1] != None:
            listaproductos.append(i[1])
        else:
            listaproductos.append(0)

        listaEtiquetas.append(i[0])
    productos1 = []
    etiquetas = []

    for i in totalprod:
        if totalprod[0] != None:
            productos1.append(i[1])
        else:
            productos1.append(0)
        etiquetas.append(i[0])
    fuera = ("Completato", "Entregado")

    Model_one = Ordenes.objects.exclude(estado__in=fuera).order_by('fecha_entrega_estimada')
    total = Model_one.count
    myFilter = OrdenesFilter(request.GET, queryset=Model_one)
    paginator = Paginator(myFilter.qs, 10)
    page = request.GET.get('page1')
    try:
        pub = paginator.page(page)
    except PageNotAnInteger:
        pub = paginator.page(1)
    except EmptyPage:
        pub = paginator.page(paginator.num_pages)

    myFilter = OrdenesFilter(request.GET, queryset=Model_one)
    comparar = date.today()
    fechasAcomparar = []
    for i in Model_one:
        fechasAcomparar.append(str(abs(comparar - i.fecha_entrega_estimada).days) + " dias" + " " + str(i.orden))

    print(fechasAcomparar)
    context = {'pub': pub, 'myFilter': myFilter, 'listatodos': listaTodos, 'listaproductos': listaproductos, 'listaetiquetas': listaEtiquetas, 'productos1': productos1, 'etiquetas': etiquetas, 'Total': total, 'Model_one': Model_one, 'Ordenes': ordenes,
               'History': historial}
    return render(request, 'ordenes/ListarOrden.html', context)

def ListHistorialView(request):
    porOrden = Ordenes.history.values_list("orden").annotate(cantidad=Sum('history_id'))

    orden = []
    historial = []
    for i in porOrden:
        historial.append(i[1])
        orden.append(i[0])

    Model_one = Ordenes.history.all().order_by('history_id')
    total = Model_one.count
    paginator = Paginator(Model_one, 10)
    page = request.GET.get('page1')
    try:
        Model_one = paginator.page(page)
    except PageNotAnInteger:
        Model_one = paginator.page(1)
    except EmptyPage:
        Model_one = paginator.page(paginator.num_pages)

    context = {'Model_one': Model_one, 'total': total, 'orden': orden, 'historial': historial}
    return render(request, 'ordenes/history.html', context)

class DetailOrdenView(DetailView):
    form_class = OrdenesForm
    model = Ordenes
    template_name = 'ordenes/detailOrden.html'

class DeleteOrdenView(DeleteView):
    model = Ordenes

    def get_success_url(self):
        success_message = '¡¡¡ Producto eliminado correctamente !!!'
        messages.success(self.request, (success_message))
        return reverse_lazy('listarOrden')

class UpdateOrdenView(UpdateView):
    form_class = UpdateOrdenesForm
    model = Ordenes
    template_name = 'ordenes/updateOrden.html'

    def get_success_url(self):
        return reverse_lazy('listarOrden')

    def form_invalid(self, form):
        print("errrrrorororororo")
        print(form)
        return super().form_invalid(form)

    def form_valid(self, form):
        formulario = form.save(commit=False)
        from Productos.models import Productos

        print(formulario)  # 3
        print(form)

        hola = Productos.objects.get(id=formulario.producto.id)

        print(hola)

        if (hola.telaio == None):
            print("Aca estoy pero no tengo que hacer nada")
            Productos.objects.filter(id=formulario.producto.id).update(telaio=formulario.telaio)
            formulario.telaio = formulario.cantidad_recibida / formulario.telaio

        else:
            pass

        if formulario.estado == 'Completato':
            formulario.fecha_entrega_real = date.today()
            messages.success(self.request, "¡¡¡ L'ordine %s è stato consegnato !!!" % (formulario.orden))

        else:
            formulario.fecha_entrega_real = None
            messages.success(self.request, "¡¡¡ L'ordine %s è stato aggiornato correttamente !!!" % (formulario.orden))

        formulario.usuarios = self.request.user

        return super().form_valid(form)


import sys
import cgitb

from qtpy.QtCore import QLockFile
from qtpy.QtWidgets import QMessageBox

from mainapplication import appctxt
from application import MainWindow

if __name__ == '__main__':

    sys.excepthook = cgitb.Hook(1, None, 5, sys.stderr, 'text')
    try:
        main_appctxt = appctxt
        lock_file = QLockFile("dundi.lock")
        if lock_file.tryLock():
            mainWin = MainWindow()
            mainWin.show()
            exit_code = main_appctxt.app.exec_()
            sys.exit(exit_code)

        else:
            error_message = QMessageBox()
            error_message.setIcon(QMessageBox.Warning)
            error_message.setWindowTitle("Error")
            error_message.setText("The application is already running!")
            error_message.setStandardButtons(QMessageBox.Ok)
            error_message.exec()
    finally:
        lock_file.unlock()


from __future__ import division

import argparse
import chainer
import importlib

import numpy as np
import pytest
import torch

from espnet.asr.pytorch_backend.asrtts import Reporter
from espnet.nets.pytorch_backend.e2e_asrtts import TacotronRewardLoss
from espnet.nets.pytorch_backend.nets_utils import pad_list

def make_arg(**kwargs):
    defaults = dict(
        elayers=4,
        subsample="1_2_2_1_1",
        etype="vggblstm",
        eunits=100,
        eprojs=100,
        dtype="lstm",
        dlayers=1,
        dunits=300,
        atype="location",
        aheads=4,
        awin=5,
        aconv_chans=10,
        aconv_filts=100,
        mtlalpha=0.5,
        lsm_type="",
        lsm_weight=0.0,
        sampling_probability=0.0,
        adim=320,
        dropout_rate=0.0,
        dropout_rate_decoder=0.0,
        nbest=5,
        beam_size=3,
        penalty=0.5,
        maxlenratio=1.0,
        minlenratio=0.0,
        ctc_weight=0.2,
        streaming_min_blank_dur=10,
        streaming_onset_margin=2,
        streaming_offset_margin=2,
        verbose=2,
        char_list=[u"あ", u"い", u"う", u"え", u"お"],
        outdir=None,
        ctc_type="warpctc",
        sym_space="<space>",
        sym_blank="<blank>",
        sortagrad=0,
        grad_noise=False,
        context_residual=False,
        use_speaker_embedding=True,
        expected_loss="tts",
        alpha=0.5,
        n_samples_per_input=5,
        policy_gradient=True,
        sample_scaling=0.1,
        generator="tts",
        rnnloss=None,
        update_asr_only=True
    )
    defaults.update(kwargs)
    return argparse.Namespace(**defaults)

def make_tts_args(**kwargs):
    defaults = dict(
        use_speaker_embedding=False,
        spk_embed_dim=None,
        embed_dim=512,
        elayers=1,
        eunits=512,
        econv_layers=3,
        econv_filts=5,
        econv_chans=512,
        dlayers=2,
        dunits=1024,
        prenet_layers=2,
        prenet_units=256,
        postnet_layers=5,
        postnet_filts=5,
        postnet_chans=512,
        output_activation=None,
        atype="location",
        adim=512,
        aconv_chans=32,
        aconv_filts=15,
        cumulate_att_w=True,
        use_batch_norm=True,
        use_concate=True,
        dropout=0.5,
        zoneout=0.1,
        reduction_factor=1,
        threshold=0.5,
        maxlenratio=5.0,
        minlenratio=0.0,
        use_cbhg=False,
        spc_dim=None,
        cbhg_conv_bank_layers=8,
        cbhg_conv_bank_chans=128,
        cbhg_conv_proj_filts=3,
        cbhg_conv_proj_chans=256,
        cbhg_highway_layers=4,
        cbhg_highway_units=128,
        cbhg_gru_units=256,
        use_masking=True,
        bce_pos_weight=1.0,
        use_guided_attn_loss=False,
        guided_attn_loss_sigma=0.4,
    )
    defaults.update(kwargs)
    return argparse.Namespace(**defaults)

def prepare_inputs(mode, ilens=[150, 100], olens=[4, 3], is_cuda=False):
    np.random.seed(1)
    assert len(ilens) == len(olens)
    xs = [np.random.randn(ilen, 40).astype(np.float32) for ilen in ilens]
    ys = [np.random.randint(1, 5, olen).astype(np.int32) for olen in olens]
    ilens = np.array([x.shape[0] for x in xs], dtype=np.int32)
    embs = torch.from_numpy(np.random.randn(2, 128)).float().to(torch.device('cpu'))

    if mode == "chainer":
        if is_cuda:
            xp = importlib.import_module('cupy')
            xs = [chainer.Variable(xp.array(x)) for x in xs]
            ys = [chainer.Variable(xp.array(y)) for y in ys]
            ilens = xp.array(ilens)
            embs = [chainer.Variable(xp.array(e)) for e in embs]
        else:
            xs = [chainer.Variable(x) for x in xs]
            ys = [chainer.Variable(y) for y in ys]
        return xs, ilens, ys, embs

    elif mode == "pytorch":
        ilens = torch.from_numpy(ilens).long()
        xs_pad = pad_list([torch.from_numpy(x).float() for x in xs], 0)
        ys_pad = pad_list([torch.from_numpy(y).long() for y in ys], -1)
        embs = torch.from_numpy(np.random.randn(2, 128)).float().to(torch.device('cpu'))
        if is_cuda:
            xs_pad = xs_pad.cuda()
            ilens = ilens.cuda()
            ys_pad = ys_pad.cuda()
            embs = embs.cuda()
        return xs_pad, ilens, ys_pad, embs
    else:
        raise ValueError("Invalid mode")

@pytest.mark.parametrize(
    "module, etype, atype, dtype", [
        ('espnet.nets.pytorch_backend.e2e_asrtts', 'blstmp', 'location', 'lstm'),
    ]
)
def test_model_trainable_and_decodable(module, etype, atype, dtype):
    args = make_arg(etype=etype, atype=atype, dtype=dtype)
    if "pytorch" in module:
        batch = prepare_inputs("pytorch", is_cuda=False)
    else:
        batch = prepare_inputs("chainer", is_cuda=False)

    m = importlib.import_module(module)
    tts_args = make_tts_args(spk_embed_dim=128, use_speaker_embedding=True)
    loss_fn = TacotronRewardLoss(None, idim=5, odim=40, train_args=tts_args, reporter=Reporter())
    asr_model = m.E2E(40, 5, args)
    model = m.E2E(40, 5, args, predictor=asr_model, asr2tts=True, loss_fn=loss_fn, rnnlm=None)
    attn_loss = model(*batch)[0]
    attn_loss.backward()  # trainable

    with torch.no_grad(), chainer.no_backprop_mode():
        in_data = np.random.randn(100, 40)
        model.recognize(in_data, args, args.char_list)  # decodable
        if "pytorch" in module:
            batch_in_data = [np.random.randn(100, 40), np.random.randn(50, 40)]
            model.recognize_batch(batch_in_data, args, args.char_list)  # batch decodable

# @pytest.mark.skipif(torch.cuda.device_count() < 2, reason="multi gpu required")
# @pytest.mark.parametrize("module", ["espnet.nets.pytorch_backend.e2e_asrtts"])
# def test_model_trainable_gpu(module):
#    ngpu = 1
#    args = make_arg()
#    m = importlib.import_module(module)
#    device_ids = list(range(ngpu))
#    tts_args = make_tts_args(spk_embed_dim=128, use_speaker_embedding=True)
#    loss_fn = TacotronRewardLoss(None, idim=5, odim=40, train_args=tts_args, reporter=Reporter())
#    asr_model = m.E2E(40, 5, args)
#    model = m.E2E(40, 5, args, predictor=asr_model, asr2tts=True, loss_fn=loss_fn, rnnlm=None)
#    if "pytorch" in module:
#        model = torch.nn.DataParallel(model, device_ids)
#        batch = prepare_inputs("pytorch", is_cuda=True)
#        model.cuda()
#        loss = 1. / ngpu * model(*batch)[0]
#        loss.backward(loss.new_ones(ngpu))  # trainable


def check(nums,target):
  subset = []
  def backtrack(start,sum):
    if sum==target:
      return True
    if sum>target or start==len(nums):
      return False
    if backtrack(start+1,sum+nums[start]):
      subset.append(nums[start])
      return True
    return backtrack(start+1,sum)
  if backtrack(0,0):
    return True, subset
  else:
    return False, [ ]
nums=list(map(int,input().split(" ")))
target_sum=int(input())

bool, subset = check(nums, target_sum)

if bool:
  print("subset with sum", target_sum, "exists:", subset)
else:
  print("No subset with sum", target_sum, "exists:", subset)


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

import os
import configparser
# from scrapy import log
from scrapy.http import Request, Response
from scrapy import signals

import tweepy

class Twitter:
    def __init__(self, *args, **kwargs):
        super(Twitter, self).__init__(*args, **kwargs)
        self.config_file = str(os.path.dirname(os.path.abspath(__file__)) + "/config.ini")
        if os.path.exists(self.config_file):
            self.config = configparser.ConfigParser()
            self.config.read(self.config_file, "utf-8")

class TwitterUserTimelineRequest(Request):
    def __init__(self, *args, **kwargs):
        auth = kwargs.pop("auth", None)
        spider = kwargs.pop("spider", None)
        self.oauth = tweepy.OAuthHandler(auth["CONSUMER_KEY"], auth["CONSUMER_SECRET"])
        self.oauth.set_access_token(auth["ACCESS_TOKEN"], auth["ACCESS_TOKEN_SECRET"])
        super(TwitterUserTimelineRequest, self).__init__('https://twitter.com', dont_filter=True, **kwargs)

class TwitterUserTimelineResponse(Response):
    def __init__(self, *args, **kwargs):
        auth = kwargs.pop("auth", None)
        self.api = tweepy.API(auth,wait_on_rate_limit=True)
        super(TwitterUserTimelineResponse, self).__init__('https://twitter.com', *args, **kwargs)


from kubot.core.handlers import cmd

@cmd("adduser", access="admin", help_text="Add a user to the system")
def adduser(args, message, say):
    if len(args) < 1:
        say("""```Syntax: adduser @username [access level]
        Where access level is either user or admin
        ```""")
        return
    access_level = "user"
    if len(args) > 1:
        access_level = args[1].lower()
    print(message)
    say(f"Added user {args[0]} with access level `{args[1]}`")


import time
import os
import subprocess
import sys
import re
import argparse
import collections
import gzip
import math
import shutil
import pandas as pd
import tensorflow_hub as hub
import numpy as np
import time
from datetime import datetime
import random

import logging
from silence_tensorflow import silence_tensorflow

os.environ['TPU_LOAD_LIBRARY']='0'
os.environ['TF_ENABLE_EAGER_CLIENT_STREAMING_ENQUEUE']='False'
import tensorflow as tf

import tensorflow_addons as tfa
from tensorflow import strings as tfs
from tensorflow.keras import mixed_precision

import enformer_vanilla as enformer

resolver = tf.distribute.cluster_resolver.TPUClusterResolver(tpu=sys.argv[1])
tf.config.experimental_connect_to_cluster(resolver)
tf.tpu.experimental.initialize_tpu_system(resolver)
strategy = tf.distribute.TPUStrategy(resolver)

dnase_indices = [120,177,248]
cage_indices=[4831,5082,5210]

dnase_dict = {120: 'jurkat',177: 'cd8', 248: 'cd4'}
cage_dict = {4831: 'jurkat', 5082: 'cd8', 5210: 'cd4'}

if sys.argv[2] == 'IL2RA':
    path="gs://picard-testing-176520/IL2RA_IL15RA/ISM_sequences/IL2RA.tfr"
    start=5964061
    steps = 4548
elif sys.argv[2] == 'IL15RA':
    path="gs://picard-testing-176520/IL2RA_IL15RA/ISM_sequences/IL15RA.tfr"
    start=5879133
    steps = 3294
with strategy.scope():
    options = tf.data.Options()
    options.experimental_distribute.auto_shard_policy=\
        tf.data.experimental.AutoShardPolicy.DATA
    options.deterministic=False
    options.experimental_threading.max_intra_op_parallelism=1
    mixed_precision.set_global_policy('mixed_bfloat16')
    #options.num_devices = 64

    BATCH_SIZE_PER_REPLICA = 1 # batch size 24, use LR ~ 2.5 e -04
    NUM_REPLICAS = strategy.num_replicas_in_sync
    GLOBAL_BATCH_SIZE = BATCH_SIZE_PER_REPLICA * NUM_REPLICAS

    model = enformer.Enformer()
    checkpoint_options = tf.train.CheckpointOptions(experimental_io_device="/job:localhost")
    checkpoint = tf.train.Checkpoint(module=model)#,options=options)
    tf.saved_model.LoadOptions(experimental_io_device='/job:localhost')
    latest = tf.train.latest_checkpoint("/home/javed/ism_compute/sonnet_weights")
    checkpoint.restore(latest,options=checkpoint_options).assert_existing_objects_matched()

    def deserialize(serialized_example,input_length=196607):
        """Deserialize bytes stored in TFRecordFile."""
        feature_map = {
          'sequence': tf.io.FixedLenFeature([],tf.string),
          'base_pos': tf.io.FixedLenFeature([], tf.string),
          'base_id': tf.io.FixedLenFeature([], tf.string),
          'wt_seq': tf.io.FixedLenFeature([], tf.string),
        }

        data = tf.io.parse_example(serialized_example, feature_map)

        ### rev_comp
        #rev_comp = random.randrange(0,2)

        example = tf.io.parse_example(serialized_example, feature_map)

        sequence=tf.io.decode_raw(example['sequence'],tf.bool)
        sequence=tf.reshape(sequence,(input_length,4))
        sequence=tf.cast(sequence,tf.float32)

        wt = tf.io.decode_raw(example['wt_seq'],tf.bool)
        wt = tf.reshape(wt,(input_length,4))
        wt = tf.cast(wt,tf.float32)

        base_pos = tf.io.parse_tensor(example['base_pos'],
                                      out_type=tf.int32)
        base_id = tf.io.parse_tensor(example['base_id'],
                                      out_type=tf.int32)

        rev_sequence = tf.gather(sequence, [3, 2, 1, 0], axis=-1)
        rev_sequence = tf.reverse(rev_sequence, axis=[0])

        rev_wt = tf.gather(wt, [3, 2, 1, 0], axis=-1)
        rev_wt = tf.reverse(rev_wt, axis=[0])

        return {
                'sequence':tf.cast(tf.ensure_shape(sequence,[input_length,4]),dtype=tf.float32),
                'rev_sequence': tf.cast(tf.ensure_shape(rev_sequence,[input_length,4]),dtype=tf.float32),
                'wt': tf.cast(tf.ensure_shape(wt,[input_length,4]),dtype=tf.float32),
                'rev_wt':tf.cast(tf.ensure_shape(rev_wt,[input_length,4]),dtype=tf.float32),
                'base_pos': tf.cast(base_pos,dtype=tf.int32),
                'base_id': tf.cast(base_id,dtype=tf.int32)}

    files = tf.data.Dataset.list_files(path,shuffle=True, seed=42)

    dataset = tf.data.TFRecordDataset(files,
                                      compression_type='ZLIB',
                                      num_parallel_reads=4)
    dataset = dataset.with_options(options)

    dataset = dataset.map(lambda record: deserialize(record,
                                                     196608),
                                  deterministic=False,
                                  num_parallel_calls=4)

    dataset=dataset.repeat(2).batch(8).prefetch(1)
    dataset_dist= strategy.experimental_distribute_dataset(dataset)
    dataset_dist_it = iter(dataset_dist)

    @tf.function
    def val_step(inputs):
        output_seq = model(inputs['sequence'], is_training=False)['human']
        output_rev_seq = tf.reverse(model(inputs['rev_sequence'], is_training=False)['human'],axis=[1])
        output_wt = model(inputs['wt'], is_training=False)['human']
        output_rev_wt = tf.reverse(model(inputs['rev_wt'], is_training=False)['human'],axis=[1])

        output_seq_ave = (output_seq+output_rev_seq)/2.0
        output_wt_ave = (output_wt+output_rev_wt)/2.0

        base_pos = inputs['base_pos']
        dnase_pos = ((base_pos) - start)//128
        # Create the offsets tensor
        offsets = tf.constant([-3,-2, -1, 0, 1, 2,3], dtype=tf.int32)
        dnase_sub_inds = dnase_pos + offsets

        dnase_seq = tf.gather(output_seq_ave,dnase_indices,axis=2)
        dnase_seq = tf.gather(dnase_seq,dnase_sub_inds,axis=1)
        dnase_seq = tf.reduce_sum(dnase_seq,axis=1)
        dnase_wt = tf.gather(output_wt_ave,dnase_indices,axis=2)
        dnase_wt = tf.gather(dnase_wt,dnase_sub_inds,axis=1)
        dnase_wt = tf.reduce_sum(dnase_wt,axis=1)

        cage_sub_indices = tf.constant([446,447,448,449,450],dtype=tf.int32)
        cage_seq = tf.gather(output_seq_ave,cage_indices,axis=2)
        cage_seq = tf.gather(cage_seq,cage_sub_indices,axis=1)
        cage_seq = tf.reduce_sum(cage_seq,axis=1)

        cage_wt = tf.gather(output_wt_ave,cage_indices,axis=2)
        cage_wt = tf.gather(cage_wt,cage_sub_indices,axis=1)
        cage_wt = tf.reduce_sum(cage_wt,axis=1)

        base_id = inputs['base_id']

        repeat = tf.constant([0,0,0])
        base_id = base_id + repeat
        base_pos = base_pos + repeat

        dnase_tensor = tf.constant(dnase_indices,dtype=tf.int32)
        cage_tensor = tf.constant(cage_indices,dtype=tf.int32)

        return tf.squeeze(dnase_seq),tf.squeeze(dnase_wt),tf.squeeze(cage_seq),tf.squeeze(cage_wt),base_id,base_pos,dnase_tensor,cage_tensor

    dnase_mut_list = []
    dnase_wt_list = []
    cage_mut_list = []
    cage_wt_list = []
    base_pos_list = []
    base_id_list = []
    dnase_data_list = []
    cage_data_list = []

    for _ in tf.range(steps): ## for loop within @tf.fuction for improved TPU performance
        start_time = time.time()
        dnase_mut,dnase_wt,cage_mut,cage_wt,base,base_pos,dnase_tensor,cage_tensor=strategy.run(val_step,
                     args=(next(dataset_dist_it),))
        for x in strategy.experimental_local_results(dnase_mut):
            dnase_mut_list.append(tf.reshape(x, [-1]))

        for x in strategy.experimental_local_results(dnase_wt):
            dnase_wt_list.append(tf.reshape(x, [-1]))

        for x in strategy.experimental_local_results(cage_mut):
            cage_mut_list.append(tf.reshape(x, [-1]))

        for x in strategy.experimental_local_results(cage_wt):
            cage_wt_list.append(tf.reshape(x, [-1]))

        for x in strategy.experimental_local_results(base):
            base_id_list.append(tf.reshape(x, [-1]))
        for x in strategy.experimental_local_results(base_pos):
            base_pos_list.append(tf.reshape(x, [-1]))

        for x in strategy.experimental_local_results(dnase_tensor):
            dnase_data_list.append(tf.reshape(x, [-1]))

        for x in strategy.experimental_local_results(cage_tensor):
            cage_data_list.append(tf.reshape(x, [-1]))

    dnase_mut_np=tf.concat(dnase_mut_list,axis=0).numpy()
    dnase_wt_np=tf.concat(dnase_wt_list,axis=0).numpy()
    cage_mut_np=tf.concat(cage_mut_list,axis=0).numpy()
    cage_wt_np=tf.concat(cage_wt_list,axis=0).numpy()
    base_pos_np=tf.concat(base_pos_list,axis=0).numpy()
    base_id_np=tf.concat(base_id_list,axis=0).numpy()

    dnase_np=tf.concat(dnase_data_list,axis=0).numpy()
    cage_np=tf.concat(cage_data_list,axis=0).numpy()

    df = pd.DataFrame(list(zip(base_pos_np, base_id_np, dnase_np,cage_np,dnase_mut_np,dnase_wt_np,cage_mut_np,cage_wt_np)),
                        columns=['base_pos', 'base_id', 'dnase_idx','cage_idx','dnase_mut','dnase_wt','cage_mut','cage_wt'])
    df['base_pos'] = df['base_pos'] - 1
    df['start'] = df['base_pos']
    df['stop'] =df['start'] + 1
    df['chrom'] = 'chr10'

    df['cage_percent_diff'] = 100.0*(df['cage_mut'] - df['cage_wt']) / df['cage_wt']
    df['dnase_percent_diff'] = 100.0*(df['dnase_mut'] - df['dnase_wt']) / df['dnase_wt']

    # Filter and rename for dnase_idx
    for val in dnase_indices:
        temp_df = df[df['dnase_idx'] == val][['chrom', 'start', 'stop', 'dnase_percent_diff']]
        name = dnase_dict[val]
        full_name = sys.argv[2] + '-DNASE-' + name + ".bedGraph"
        temp_df.to_csv(full_name, index=False,sep='\t',header=False)

    for val in cage_indices:
        temp_df = df[df['cage_idx'] == val][['chrom', 'start', 'stop', 'cage_percent_diff']]
        name = cage_dict[val]
        full_name = sys.argv[2] + '-CAGE-' + name + ".bedGraph"
        temp_df.to_csv(full_name, index=False,sep='\t',header=False)


import io
import os
import pyaudio
import google.cloud.speech
import sys
import RPi.GPIO as GPIO
import time
import threading
import asyncio
import websockets
import json

# 초음파 센서 세팅
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
TRIG = 17
ECHO = 18
GPIO.setup(TRIG, GPIO.OUT)
GPIO.setup(ECHO, GPIO.IN)

# Audio recording parameters
RATE = 16000
CHUNK = int(RATE / 10)  # 100ms

uw = 0
#exit_flag = False  # 종료 여부를 확인하기 위한 플래그
exit_flag=threading.Event()
send_msg=""
serial_num=1111

class Stack:
    def __init__(self):
        self.items = []

    def is_empty(self):
        return len(self.items) == 0

    def push(self, item):
        self.items.append(item)

    def pop(self):
        if not self.is_empty():
            return self.items.pop()
        else:
            print("Stack is empty. Cannot pop.")

    def peek(self):
        if not self.is_empty():
            return self.items[-1]
        else:
            print("Stack is empty. Nothing to peek.")

    def size(self):
        return len(self.items)

    def clear(self):
        self.items = []

stack=Stack()

def stream_generator(stream):
    while True:
        data = stream.read(CHUNK)
        yield data

def send_and_receive_message(send_msg):
    uri = "ws://i9c103.p.ssafy.io:30002/"
    websocket=websockets.connect(uri)

    print("msg sending")
    websocket.send(json.dumps({"role":"handshake", "number":1111}))
    data = {"role": "gpt","message": send_msg, "number": 1111}
    websocket.send(json.dumps(data))

    # Receive and immediately print the response
    response = websocket.recv()
    print(f"Received: {response}")

def listen_print_loop(responses):
    send_msg=""
    stack.push("test string")
    num_chars_printed = 0
    for response in responses:
        #print(stack.pop())

        if not response.results:
            continue

        result = response.results[0]
        if not result.alternatives:
            continue

        transcript = result.alternatives[0].transcript

        overwrite_chars = ' ' * (num_chars_printed - len(transcript))

        if not result.is_final:
            stack.push(transcript + overwrite_chars)
            # stt와 sense모두 돌아가야함
            # sense가 가까워 지는경우 전역에 저장해 준뒤 보내줌
            # sense와의 연동
            # exit_flag true인 경우
            # string으로 보내주기
            # stack clear
            if exit_flag.is_set():
                send_msg=stack.peek()
                print(send_msg)
        else:
            print("send message is ",send_msg,end=" ")
            print()
            send_msg=""
            stack.clear()

def stt():
    global uw, exit_flag
    client = google.cloud.speech.SpeechClient()

    config = google.cloud.speech.RecognitionConfig(
        encoding=google.cloud.speech.RecognitionConfig.AudioEncoding.LINEAR16,
        sample_rate_hertz=RATE,
        language_code='ko-KR',
        enable_automatic_punctuation=True,
        enable_spoken_punctuation=True,
        model='latest_long',
    )

    streaming_config = google.cloud.speech.StreamingRecognitionConfig(
        config=config,
        interim_results=True,
    )

    p = pyaudio.PyAudio()

    # 어떻게 넣을지
    Speaker_diarization_config=google.cloud.speech.SpeakerDiarizationConfig(
        min_speaker_count=1,
        max_speaker_count=1,
    )

    stream = p.open(
        format=pyaudio.paInt16,
        channels=1,
        rate=RATE,
        input=True,
        frames_per_buffer=CHUNK,
    )

    audio_generator = stream_generator(stream)
    requests = (
        google.cloud.speech.StreamingRecognizeRequest(audio_content=content)
        for content in audio_generator
    )

    responses = client.streaming_recognize(streaming_config, requests)

    listen_print_loop(responses)

def sense():
    global uw, exit_flag
    while True:
        GPIO.output(17, False)
        time.sleep(0.5)

        GPIO.output(17, True)
        time.sleep(0.00001)
        GPIO.output(17, False)

        while GPIO.input(18) == 0:
            start = time.time()

        while GPIO.input(18) == 1:
            stop = time.time()

        time_interval = stop - start
        uw = time_interval * 17000
        uw = round(uw, 2)
        print(uw,end=" ")

        # 먼 경우
        if uw > 100:
            # thread가 존재 할때 종료 3. 멀어졌을때 종료하고 초기화
            print("remote")
            exit_flag.set()
        # 가까운 경우
        else:
            # thread가 미존재시 생성 2.스레드 생성해 입력 받기
            print("close")
            exit_flag.clear()

def main():

        global send_msg
        thread_stt = threading.Thread(target=stt)
        thread_sense = threading.Thread(target=sense)

        thread_stt.start()
        thread_sense.start()

        try:
            while True:
                '''
                if exit_flag.is_set():
                    thread_msg=threading.Thread(target=send_and_receive_message,args=(send_msg,))
                    thread_msg.start()
                    send_msg=""
                    thread_msg.join()'''
                time.sleep(1)

        except KeyboardInterrupt:
            GPIO.cleanup()
            thread_sense.join()
            thread_stt.join()

if __name__ == '__main__':
    main()


from myapp import app, db
from myapp.models import *

def send_coupon_email(customer, coupon):
    subject = f"Discount Coupon from {coupon.store.name}"
    sender = app.config["MAIL_USERNAME"]
    recipients = [customer.email]
    msg = Message(subject, sender=sender, recipients=recipients)
    msg.body = f"You received a discount coupon from {coupon.store.name}. Your coupon code is {coupon.code}. It will expire at {coupon.expire_date.strftime('%a %d %b %Y, %I:%M%p')} UTC"
    try:
        mail.send(msg)
        coupon.email_sent = True
        db.session.commit()
    except Exception as e:
        print(f"ERROR sending email to {customer.email}: {e}")
    # print(f'Sending email to {customer.email} for {coupon.code}')
    # print(f'ERROR: NOT IMPLEMENTED')

def send_coupon_sms(customer, coupon):
    print(f"Sending sms to {customer.email} for {coupon.code}")
    print(f"ERROR: NOT IMPLEMENTED")

@app.cli.command("send-coupons")
def send_coupons():
    customers = db.session.scalars(db.select(Customer)).all()
    for customer in customers:
        for coupon in customer.coupons:
            if not coupon.email_sent:
                send_coupon_email(customer, coupon)
            if not coupon.sms_sent:
                send_coupon_sms(customer, coupon)

@app.cli.command("fetch-reviews")
def fetch_reviews():
    from myapp.utils import generate_random_code, get_review_list

    stores = db.session.scalars(db.select(Store)).all()
    timestamp_now = datetime.utcnow()
    for store in stores:
        account_id_list = [customer.account_id for customer in store.customers]
        review_list = get_review_list(
            store.hex_id, datetime.timestamp(store.upto_timestamp)
        )
        for review in review_list:
            account_id, timestamp, rating, text, photos = review
            print(account_id, end="")
            if account_id in account_id_list:
                customer = db.session.scalar(
                    db.select(Customer).filter_by(account_id=review[0])
                )
                review = Review()
                update = Update(rating=rating, text=text, timestamp=timestamp)
                for item in photos:
                    photo = Photo(url=f"https://lh5.googleusercontent.com/p/{item}")
                    update.photos.append(photo)
                review.updates.append(update)

                if review.updates.count() == 1:
                    if customer.coupons.count() > 0:
                        days_after_last_coupon = (
                            timestamp_now - customer.got_coupon_date
                        ).days
                        if days_after_last_coupon < 15:
                            # generate coupon
                            coupon = Coupon(
                                code=generate_random_code(),
                                expire_date=timestamp_now + timedelta(days=30),
                            )
                            customer.coupons.append(coupon)
                            customer.got_coupon_date = timestamp_now
                            store.coupons.append(coupon)
                    else:
                        # generate coupon
                        coupon = Coupon(
                            code=generate_random_code(),
                            expire_date=timestamp_now + timedelta(days=30),
                        )
                        customer.coupons.append(coupon)
                        customer.got_coupon_date = timestamp_now
                        store.coupons.append(coupon)
                customer.reviews.append(review)
                store.reviews.append(review)
                print(" - registered")
            else:
                print(" - not registered")
            store.upto_timestamp = timestamp_now
            db.session.commit()


import copy
from pyaudio import PyAudio, paInt16
from threading import Thread
import numpy as np
import sys

class AudioAnalyzer(Thread):
    SAMPLING_RATE = 48000
    CHUNK_SIZE = 1024
    BUFFER_TIMES = 50
    ZERO_PADDING = 3
    NUM_HPS = 3

    NOTE_NAMES = ['Do', 'Do#', 'Re', 'Re#', 'Mi', 'Fa', 'Fa#', 'Sol', 'Sol#', 'La', 'La#', 'Si']

    def __init__(self, queue, *args, **kwargs):
        Thread.__init__(self, *args, **kwargs)

        self.queue = queue
        self.buffer = np.zeros(self.CHUNK_SIZE * self.BUFFER_TIMES)
        self.hanning_window = np.hanning(len(self.buffer))
        self.running = False

        try:
            self.audio_object = PyAudio()
            self.stream = self.audio_object.open(format=paInt16,
                                                 channels=1,
                                                 rate=self.SAMPLING_RATE,
                                                 input=True,
                                                 output=False,
                                                 frames_per_buffer=self.CHUNK_SIZE)
        except Exception as e:
            sys.stderr.write('Error: Line {} {} {}\n'.format(sys.exc_info()[-1].tb_lineno, type(e).__name__, e))
            return

    @staticmethod
    def frequency_to_number(freq, a4_freq):
        if freq == 0:
            sys.stderr.write("Error: No hay frecuencia, el sistema no reconoce la entrada de audio\n")
            return 0
        return 12 * np.log2(freq / a4_freq) + 69

    @staticmethod
    def number_to_frequency(number, a4_freq):
        return a4_freq * 2.0**((number - 69) / 12.0)

    @staticmethod
    def number_to_note_name(number):
        return AudioAnalyzer.NOTE_NAMES[int(round(number) % 12)]

    @staticmethod
    def frequency_to_note_name(frequency, a4_freq):
        number = AudioAnalyzer.frequency_to_number(frequency, a4_freq)
        note_name = AudioAnalyzer.number_to_note_name(number)
        return note_name

    def run(self):
        self.running = True

        while self.running:
            try:
                data = self.stream.read(self.CHUNK_SIZE, exception_on_overflow=False)
                data = np.frombuffer(data, dtype=np.int16)

                self.buffer[:-self.CHUNK_SIZE] = self.buffer[self.CHUNK_SIZE:]
                self.buffer[-self.CHUNK_SIZE:] = data

                magnitude_data = abs(np.fft.fft(np.pad(self.buffer * self.hanning_window,
                                                       (0, len(self.buffer) * self.ZERO_PADDING),
                                                       "constant")))
                magnitude_data = magnitude_data[:int(len(magnitude_data) / 2)]
                magnitude_data_orig = copy.deepcopy(magnitude_data)
                for i in range(2, self.NUM_HPS+1, 1):
                    hps_len = int(np.ceil(len(magnitude_data) / i))
                    magnitude_data[:hps_len] *= magnitude_data_orig[::i]

                frequencies = np.fft.fftfreq(int((len(magnitude_data) * 2) / 1),
                                             1. / self.SAMPLING_RATE)

                for i, freq in enumerate(frequencies):
                    if freq > 60:
                        magnitude_data[:i - 1] = 0
                        break

                self.queue.put(round(frequencies[np.argmax(magnitude_data)], 2))

            except Exception as e:
                sys.stderr.write('Error: Line {} {} {}\n'.format(sys.exc_info()[-1].tb_lineno, type(e).__name__, e))

        self.stream.stop_stream()
        self.stream.close()
        self.audio_object.terminate()

if __name__ == "__main__":
    from analizer.threading_helper import ProtectedList
    import time

    q = ProtectedList()
    a = AudioAnalyzer(q)
    a.start()

    while True:
        q_data = q.get()
        if q_data is not None:
            print("loudest frequency:", q_data, "nearest note:", a.frequency_to_note_name(q_data, 440))
            time.sleep(0.02)