""" Views for  default and custom restrictions for the coupon app. """

import logging

from django.conf import settings
from django.core.urlresolvers import reverse
from django.http import HttpResponseRedirect
from django.shortcuts import render_to_response
from django.template import RequestContext

from advertiser.business.tasks import take_web_snap
from common.session import delete_key_from_session, parse_curr_session_keys
from coupon.forms import (RestrictionsForm, get_restrictions_initial_data,
    ValidDaysForm, get_valid_days_initial_data)
from coupon.models import Coupon
from coupon.service.single_coupon_service import SINGLE_COUPON
from coupon.service.restrictions_service import COUPON_RESTRICTIONS
from coupon.service.valid_days_service import VALID_DAYS
from ecommerce.service.locking_service import (get_locked_data,
    get_incremented_pricing)
from ecommerce.service.product_list import set_selected_product
from ecommerce.service.calculate_current_price import get_product_price

from market.service import get_current_site

LOG = logging.getLogger('ten.%s' % __name__)
LOG.setLevel(logging.DEBUG)

def show_create_restrictions(request):
    """ Allows advertiser to specify coupon restrictions. """
    try:
        session_dict = parse_curr_session_keys(request.session,
            ['this_business', 'this_offer'])
        business = session_dict['this_business']
        offer = session_dict['this_offer']
        site = get_current_site(request)
        slot_price, locked_flyer_price, locked_consumer_count = \
            get_locked_data(request, site)
    except KeyError:
        return HttpResponseRedirect(reverse('advertiser-registration'))
    annual_slot_price = get_product_price(3, site)
    context_dict = {}
    context_instance_dict = {'js_create_restrictions':1,
                'business_name':business['business_name'],
                'slogan':business['slogan'],
                'headline':offer['headline'],
                'qualifier':offer['qualifier'],
                'slot_price':slot_price,
                'locked_flyer_price':locked_flyer_price,
                'locked_consumer_count':locked_consumer_count,
                'annual_slot_price':annual_slot_price}
    context_instance_dict.update(get_incremented_pricing(locked_consumer_count))
    if request.method == 'POST':
        return process_create_restrictions(request,
            created_redirect=reverse('checkout-coupon-purchase'),
            required_fields_not_filled_out='coupon/display_create_restrictions.html',
            context_instance=RequestContext(request, context_instance_dict))
    else:
        try:
            session_dict = parse_curr_session_keys(request.session,
                ['coupon_id', 'this_coupon'])
            coupon = Coupon.objects.get(id=session_dict['coupon_id'])
            # Remove 'add_locations' key from session. No longer needed.
            delete_key_from_session(request, 'add_location')
            context_dict.update(SINGLE_COUPON.set_single_coupon_dict(
                request, coupon))
            # Display the Offer Creation restrictions_form.
            restrictions_intial_dict = \
                get_restrictions_initial_data(session_dict['this_coupon'])
            restrictions_form = \
                RestrictionsForm(initial=restrictions_intial_dict)
            valid_days_initial_dict = \
                get_valid_days_initial_data(session_dict['this_coupon'])
            valid_days_form = ValidDaysForm(initial=valid_days_initial_dict)
            context_dict.update({'restrictions_form':restrictions_form,
                        'valid_days_form':valid_days_form})
            return render_to_response('coupon/display_create_restrictions.html',
                context_dict,
                context_instance=RequestContext(request, context_instance_dict))
        except KeyError:
            return HttpResponseRedirect(reverse('advertiser-registration'))

def process_create_restrictions(request, created_redirect,
        required_fields_not_filled_out, context_instance):
    """ Save configured coupon restrictions. """
    # Populate the RestrictionsForm.
    restrictions_form = RestrictionsForm(request.POST)
    valid_days_form = ValidDaysForm(request.POST)
    # Check all required fields are filled out.
    if restrictions_form.is_valid() and valid_days_form.is_valid():
        try:
            session_dict = parse_curr_session_keys(request.session,
            ['this_business', 'this_offer', 'this_coupon', 'coupon_id'])
            # Use cleaned_data
            restrictions_cleaned_data = restrictions_form.cleaned_data
            valid_days_cleaned_data = valid_days_form.cleaned_data
            # Get coupon_id from session.
            # Check coupon exists.
            coupon = Coupon.objects.get(
                id=session_dict['this_coupon']['coupon_id'])
            COUPON_RESTRICTIONS.check_redeemed_by_sms_changes(
                restrictions_cleaned_data, coupon, session_dict['this_coupon'])
            COUPON_RESTRICTIONS.check_for_restriction_changes(
                restrictions_cleaned_data, coupon, session_dict['this_coupon'])
            VALID_DAYS.check_for_valid_days_changes(valid_days_cleaned_data, coupon,
                session_dict['this_coupon'])
            # Web Snap.
            if coupon.offer.business.web_url:
                if settings.CELERY_ALWAYS_EAGER is False:
                    take_web_snap.delay(coupon.offer.business)
            #add_slot_choice of 0 will only add a slot to the products list
            #calculations and create list of products in session.
            if request.session.get('ad_rep_id', False):
                # Set default product selection for ad rep in session.
                set_selected_product(request, 2)
            else:
                set_selected_product(request, 2)
            # Session has been modified, save the session.
            request.session.modified = True
            coupon.save()
        except Coupon.DoesNotExist:
            return HttpResponseRedirect(reverse('all-coupons'))
        return HttpResponseRedirect(created_redirect)
    else:
        context_dict = {'restrictions_form':restrictions_form,
                        'valid_days_form':valid_days_form}
        # All required fields are not filled out. Return to page with form data.
        return render_to_response(required_fields_not_filled_out,
            context_dict,
            context_instance=context_instance)


from django.urls import path, re_path
from . import views
from django.contrib.auth import views as auth_views

app_name = 'manager'
urlpatterns=[
    path('', views.manager_index, name='index'),
    path('login/', auth_views.LoginView.as_view(template_name='manager/login.html'), name='login'),
    path('logout/', auth_views.LogoutView.as_view(), name='logout'),
    re_path(r'^calendar/$', views.AdminCalendarView.as_view(), name='calendarAdmin'),
    re_path(f'^calendar/adminsave/$', views.admin_save, name='adminsave'),
    re_path(r'^reservation/group/(?P<reservation_id>\d+)$', views.group_form, name='group_form'),
    re_path(r'^reservation/group/(?P<reservation_id>\d+)/confirm$', views.group_confirm, name='confirm'),
    path('regular/', views.admin_regular_list, name='admin_regular_list'),
    re_path(r'^regular/(?P<reservation_id>\d+)/$', views.admin_regular_form, name='admin_regular_form'),
    re_path(r'^regular/(?P<reservation_id>\d+)/status/$', views.regular_status_change, name='regular_status_change'),
    path('regulardate/', views.regulardate_cud, name='regulardate_cud'),
    re_path(r'regulardate/(?P<date_id>\d+)/$', views.regulardate_cud, name='regulardate_cud'),
    ]


from PIL import Image
import numpy as np
from os.path import join
from os import listdir

tdir='.'

# Google maps traffic levels
whitecol   = 0xffffff
greencol   = 0x63d668
orangecol  = 0xff974d
redcol     = 0xf23c32
darkredcol = 0x811f1f

levels={}
cachefn=join(tdir,'trafficlevels')
try:
  with open(cachefn,'r') as fp:
    for x in fp:
      if x[:1]!='#':
        y=x.strip().split()
        levels[(y[0],y[1])]=[int(z) for z in y[2:]]
except FileNotFoundError:
  pass

for fn in sorted(listdir(tdir)):
  if fn[:6]=='London' and fn[-4:]=='.png':
    f=fn[:-4].find('.')
    key=(fn[:f],fn[f+1:-4])
    if key not in levels:
      im_frame = Image.open(join(tdir,fn))
      np_frame = np.array(im_frame)
      im_frame.close()
      rgb = np_frame[:,:,0]*65536+np_frame[:,:,1]*256+np_frame[:,:,2]
      numcols = [np.sum(rgb==v) for v in [whitecol,greencol,orangecol,redcol,darkredcol]]
      if numcols[0]<1000000:
        levels[key]=numcols
        print("Read",fn)
      else:
        print("Discarding",fn)

# Work out overall congestion as weighted sum of orange, red and dark red
ll=sorted(levels);n=len(ll)
l0=[]
for x in sorted(ll):
  m=levels[x]
  c=m[2]+3*m[3]+10*m[4]
  l0.append(c)

# Work out cumulative version of l0 with padded ends
l0pad=l0[:168]+l0+l0[-168:]
cum=[]
t=0
for c in l0pad:
  cum.append(t)
  t+=c
cum.append(t)

# Create 24-hour and 168-hour moving averages
l1=[];l2=[]
for (a,l) in [(24,l1),(168,l2)]:
  assert a%2==0;a2=a//2
  for i in range(168,n+168):
    l.append(int((cum[i+a2]-cum[i-a2+1]+(l0pad[i-a2]+l0pad[i+a2])/2+a2)/a))

with open(cachefn,'w') as fp:
  print("# Location      LocalDateTime    White    Green   Orange      Red  Darkred     Cong   Cong24  Cong168",file=fp)
  for i in range(n):
    (loc,date)=ll[i]
    print(loc,date,' '.join("%8d"%x for x in levels[(loc,date)][:5]),"%8d %8d %8d"%(l0[i],l1[i],l2[i]),file=fp)


from hdmf.utils import docval, call_docval_func, get_docval
from pynwb import register_class, NWBContainer
from pynwb.core import NWBDataInterface, MultiContainerInterface
from pynwb.device import Device

@register_class('ShanksElectrode', 'ndx-franklab-novela')
class ShanksElectrode(NWBContainer):
    ''' Representation of ShanksElectrode object in NWB '''

    @docval(
        {'name': 'name', 'type': str, 'doc': 'name of the shank'},
        {'name': 'rel_x', 'type': float, 'doc': 'the rel_x value of this electrode'},
        {'name': 'rel_y', 'type': float, 'doc': 'the rel_y value of this electrode'},
        {'name': 'rel_z', 'type': float, 'doc': 'the rel_z value of this electrode'},
    )
    def __init__(self, **kwargs):
        super(ShanksElectrode, self).__init__(name=kwargs['name'])
        self.rel_x = kwargs['rel_x']
        self.rel_y = kwargs['rel_y']
        self.rel_z = kwargs['rel_z']

@register_class('Shank', 'ndx-franklab-novela')
class Shank(MultiContainerInterface):
    ''' Representation of Shank object in NWB '''

    @docval(
        {'name': 'name', 'type': str, 'doc': 'name of the shank'},
        {'name': 'shanks_electrodes', 'type': (list, tuple), 'doc': 'electrodes in shank', 'default': list()}
    )
    def __init__(self, **kwargs):
        super(Shank, self).__init__(name=kwargs['name'])
        self.shanks_electrodes = kwargs['shanks_electrodes']

    __clsconf__ = [
        {
            'attr': 'shanks_electrodes',
            'type': ShanksElectrode,
            'add': 'add_shanks_electrode',
            'get': 'get_shanks_electrode'
        }
    ]

@register_class('Probe', 'ndx-franklab-novela')
class Probe(Device, MultiContainerInterface):
    ''' Representation of Probe object in NWB '''

    @docval(*get_docval(Device.__init__) + (
            {'name': 'id', 'type': 'int', 'doc': 'unique id of the probe'},
            {'name': 'probe_type', 'type': 'str', 'doc': 'type of probe'},
            {'name': 'units', 'type': 'str', 'doc': 'units in device'},
            {'name': 'probe_description', 'type': 'str', 'doc': 'description of the probe'},
            {'name': 'contact_side_numbering', 'type': 'bool', 'doc': 'is contact_side_numbering enabled'},
            {'name': 'contact_size', 'type': 'float', 'doc': 'value of contact size as float'},
            {'name': 'shanks', 'type': (list, tuple), 'doc': 'shanks in probe', 'default': list()}
    ))
    def __init__(self, **kwargs):
        super().__init__(**{kwargs_item: kwargs[kwargs_item]
                            for kwargs_item in kwargs.copy()
                            if kwargs_item != 'id'
                            if kwargs_item != 'probe_type'
                            if kwargs_item != 'units'
                            if kwargs_item != 'probe_description'
                            if kwargs_item != 'contact_side_numbering'
                            if kwargs_item != 'contact_size'
                            if kwargs_item != 'shanks'
                            })
        call_docval_func(super(Probe, self).__init__, kwargs)
        self.id = kwargs['id']
        self.probe_type = kwargs['probe_type']
        self.units = kwargs['units']
        self.probe_description = kwargs['probe_description']
        self.contact_side_numbering = kwargs['contact_side_numbering']
        self.contact_size = kwargs['contact_size']
        self.shanks = kwargs['shanks']

    __nwbfields__ = ('id', 'probe_type', 'units', 'probe_description', 'contact_side_numbering',
                     'contact_size')

    __clsconf__ = [
        {
            'attr': 'shanks',
            'type': Shank,
            'add': 'add_shank',
            'get': 'get_shank'
        }
    ]


import os
import json
from json import JSONDecoder
import numpy as np
import tensorflow as tf
import torch
from keras_preprocessing import sequence
from torch.utils.data import Dataset
from torch.utils.data import DataLoader
from tqdm import tqdm

##meta
task='B'
if task=='A':
    n_classes=2
else:
    n_classes=4
learning_rate = 1e-5
max_epoch=50
log_path = './log/task{}/'.format(task)
exp_path = './exp/task{}/'.format(task)
result_path = './results/task{}/'.format(task)
restore_path = './exp/task{}/epoch_{}'.format(task, 24)#A:48 B:34
max_len =50
emb_size=728
inference= True
if inference:
    batch_size=784
else:
    batch_size = 16
##rnn
rnn_size=100
layer_size=2
dropout_keep_prob=0.5

##attention
attn_size = 200
use_final_state = False
print('task',task)

def load_dict(fname):
    with open(fname, 'r') as file:
        dictionary = json.load(file)
    return dictionary

def load_data(filename):
    with open(filename, 'r') as file:
        data = json.load(file)
        dataList=data['data']
    return dataList

def load_feature(filename):
    with open(filename,'r')as f:
        feature=f.read()
    feature=JSONDecoder().decode(feature)
    return feature

##global
data_folder = "data"
trainA_file = os.path.join(data_folder, 'trainA.json')
trainB_file = os.path.join(data_folder, 'trainB.json')
test_file = os.path.join(data_folder, 'test.json')

train_feature_f = os.path.join(data_folder, 'task3_train_feature.txt')
test_feature_f = os.path.join(data_folder, 'task3_test_feature.txt')

train_feature = load_feature(train_feature_f)
test_feature = load_feature(test_feature_f)

word2idx_f = os.path.join(data_folder, 'word2idx.json')
pos2idx_f = os.path.join(data_folder, 'pos2idx.json')
word_embeds_f = os.path.join(data_folder, 'word_embedding.npy')
pos_embeds_f = os.path.join(data_folder, 'pos_embedding.npy')

##prepare data
train_totalA = load_data(trainA_file)
train_totalB = load_data(trainB_file)

trainA = train_totalA[:3450]
validA = train_totalA[3450:]
trainB = train_totalB[:3450]
validB = train_totalB[3450:]
train_fea = train_feature[:3450]
valid_fea = train_feature[3450:]
test = load_data(test_file)

word2idx = load_dict(word2idx_f)
pos2idx = load_dict(pos2idx_f)
vocab_size = len(word2idx)

word_embedding = np.load(word_embeds_f)
pos_embedding = np.load(pos_embeds_f)

class IronyDataset(Dataset):
    def __init__(self, raw_data, feature_data):
        self.data = raw_data
        self.feature = feature_data

    def __len__(self):
        return len(self.data)

    def __getitem__(self, index):
        raw_samples = self.data[index]
        length= len(raw_samples['word'])
        sentence = []
        for i in range(length):
            word_emb = word_embedding[word2idx[raw_samples['word'][i]]]
            pos_emb = pos_embedding[pos2idx[raw_samples['pos'][i]]]
            sample = np.concatenate([word_emb, pos_emb])
            sentence.append(sample)
        label = self.data[index]["label"]
        feature = self.feature[index]
        return sentence, label, feature

def collate_fn(batch):
    # sorted_batch = sorted(batch, key=lambda x: x[0].size(0), reverse=True)
    sequences = [x[0] for x in batch]
    sequences_padded = []
    for sequence in sequences:
        # sequence_padded =np.pad(np.array(sequence),
        #                             [(0, max_len - len(sequence))], 'constant', constant_values=(0, 0))
        sequence=np.array(sequence)
        sequence_padded = np.concatenate([sequence,np.zeros(shape=[max_len-sequence.shape[0],sequence.shape[1]])], axis=0)
        sequences_padded.append(sequence_padded)
    sequences_padded = np.array(sequences_padded)
    lengths = np.array([len(x) for x in sequences])
    labels = np.array(list(map(lambda x: x[1], batch)))
    features = np.array(list(map(lambda x: x[2], batch)))
    return sequences_padded, labels, lengths, features
if task=='A':
    train_data = IronyDataset(trainA, train_fea)
    valid_data = IronyDataset(validA, valid_fea)
else:
    train_data = IronyDataset(trainB, train_fea)
    valid_data = IronyDataset(validB, valid_fea)
test_data = IronyDataset(test, test_feature)
train_loader = DataLoader(train_data, batch_size=batch_size, shuffle=True, collate_fn=collate_fn, drop_last=True)
valid_loader = DataLoader(valid_data, batch_size=batch_size, shuffle=False, collate_fn=collate_fn)
test_loader = DataLoader(test_data, batch_size=len(test_data), shuffle=False, collate_fn=collate_fn)

#########build graph######################################
# placeholder
output_keep_prob = tf.placeholder(tf.float32, name='output_keep_prob')
input_data = tf.placeholder(tf.float32, shape=[batch_size, max_len, emb_size], name='input_data')
targets = tf.placeholder(tf.int64, shape=[batch_size], name='targets')
input_data_len = tf.placeholder(tf.int32, shape=[batch_size], name='input_data_len')
mask = tf.sequence_mask(input_data_len, maxlen=max_len)
fc_feature = tf.placeholder(tf.float32, shape=[batch_size, 149], name='fc_feature')
# imbalance_weight = tf.convert_to_tensor([1.9907674552798615,2.7555910543130993,12.23404255319149, 18.852459016393443], dtype=tf.float32)
imbalance_weight = tf.convert_to_tensor([1,1,2,3], dtype=tf.float32)
# forward
with tf.name_scope('fw_rnn'), tf.variable_scope('fw_rnn'):
    lstm_fw_cell_list = [tf.contrib.rnn.LSTMCell(rnn_size) for _ in range(layer_size)]
    lstm_fw_cell_m = tf.contrib.rnn.DropoutWrapper(tf.contrib.rnn.MultiRNNCell(lstm_fw_cell_list), output_keep_prob=output_keep_prob)

#backward
with tf.name_scope('bw_rnn'), tf.variable_scope('bw_rnn'):
    lstm_bw_cell_list = [tf.contrib.rnn.LSTMCell(rnn_size) for _ in range(layer_size)]
    lstm_bw_cell_m = tf.contrib.rnn.DropoutWrapper(tf.contrib.rnn.MultiRNNCell(lstm_bw_cell_list), output_keep_prob=output_keep_prob)

with tf.name_scope('bi_rnn'), tf.variable_scope('bi_rnn'):
    outputs, final_state  = tf.nn.bidirectional_dynamic_rnn(lstm_fw_cell_m, lstm_bw_cell_m, input_data, dtype=tf.float32)
    outputs = tf.concat(outputs, axis= 2)
    final_state = tf.concat(final_state, axis = 2)

with tf.name_scope('attention'),tf.variable_scope('attention'):
    attention_w = tf.Variable(tf.truncated_normal([2*rnn_size, attn_size], stddev=0.1), name='attention_w')
    attention_b = tf.Variable(tf.constant(0.1, shape=[attn_size]), name='attention_b')
    if use_final_state:
        u_w = final_state
    else:
        u_w = tf.Variable(tf.truncated_normal([attn_size, 1], stddev=0.1), name='attention_uw')
    attn_z = tf.tanh(tf.matmul(outputs, tf.tile(tf.expand_dims(attention_w,axis=0), multiples=[batch_size ,1,1]))+attention_b)
    attn_z = tf.reduce_mean(tf.matmul(attn_z, tf.tile(tf.expand_dims(u_w,axis=0), multiples=[batch_size ,1,1])), axis=-1)
    print(attn_z)
    attn_z_mask = attn_z - 1e20*tf.cast(mask, tf.float32)
    print(mask, attn_z_mask)
    alpha = tf.nn.softmax(attn_z_mask)
    print(alpha)
    final_outputs = tf.reduce_sum(outputs*tf.expand_dims(alpha,axis=-1),axis=1)
    print(outputs)

with tf.name_scope('fc'),tf.variable_scope('fc'):
    fc_w = tf.Variable(tf.truncated_normal([2 * rnn_size+149, n_classes], stddev=0.1), name='fc_w')
    fc_b = tf.Variable(tf.zeros([n_classes]), name='fc_b')

logits  =tf.matmul(tf.concat([final_outputs, fc_feature], axis=1), fc_w)+fc_b
prob = tf.nn.softmax(logits)
if task=='B':
    total_loss = tf.reduce_mean(tf.nn.sparse_softmax_cross_entropy_with_logits(logits=logits, labels=targets)*tf.nn.embedding_lookup(imbalance_weight, targets))
else:
    total_loss = tf.reduce_mean(tf.nn.sparse_softmax_cross_entropy_with_logits(logits = logits, labels=targets))
optimizer = tf.train.AdamOptimizer(learning_rate)
train_op = optimizer.minimize(total_loss)
accuracy = tf.reduce_mean(tf.cast( tf.equal(targets, tf.argmax(prob, axis=1)),tf.float32))
predictions = tf.argmax(prob, axis=1)
# tf.summary.scalar('train_loss', total_loss)
# tf.summary.scalar('accuracy', accuracy)
# merged = tf.summary.merge_all()

saver = tf.train.Saver(max_to_keep=100)

####################################################

tf_config = tf.ConfigProto()
tf_config.gpu_options.allow_growth = True
train_writer = tf.summary.FileWriter(log_path+'train')
valid_writer = tf.summary.FileWriter(log_path+'valid')

with tf.Session(config=tf_config) as sess:
    if os.path.exists(os.path.join(exp_path, 'checkpoint')):
        saver.restore(sess, restore_path)
    else:
        sess.run(tf.global_variables_initializer())
    graph_writer = tf.summary.FileWriter(log_path + 'graph')
    graph_writer.add_graph(sess.graph)

    if inference:
        for sequences, labels, lengths, features in tqdm(test_loader, desc='test'):
            # print('input data',sequences,labels, lengths)
            results = sess.run([predictions], feed_dict={
                input_data: sequences,
                input_data_len: lengths.reshape(-1),
                output_keep_prob: 1.0,
                fc_feature: features
            })
            np.savetxt(X=results, fname=result_path+'result')

    else:
        for epoch in range(max_epoch):
            step = epoch * len(train_data)
            test_loss, test_acc = [] , []
            for sequences, labels, lengths, features in tqdm(valid_loader, desc='test'):
                # print('input data',sequences,labels, lengths)
                loss, acc = sess.run([total_loss, accuracy], feed_dict={
                    input_data:sequences,
                    input_data_len:lengths.reshape(-1),
                    targets:labels,
                    output_keep_prob: 1.0,
                    fc_feature:features
                })
                test_loss.append(loss)
                test_acc.append(acc)
            print('epoch_{}'.format(epoch+1),'test loss:', np.mean(test_loss), 'test acc', np.mean(test_acc))
            valid_writer.add_summary(tf.Summary(value=[tf.Summary.Value(tag='loss', simple_value=np.mean(test_loss))]),
                                     epoch)
            valid_writer.add_summary(tf.Summary(value=[tf.Summary.Value(tag='acc', simple_value=np.mean(test_acc))]), epoch)

            train_loss, train_acc = [], []
            for sequences, labels, lengths, features in tqdm(train_loader, desc='train'):
                # print('input data', sequences.shape, labels.shape, lengths.shape, features.shape)
                _, loss, acc = sess.run([train_op, total_loss, accuracy], feed_dict={
                    input_data: sequences,
                    input_data_len: lengths.reshape(-1),
                    targets: labels,
                    output_keep_prob: dropout_keep_prob,
                    fc_feature:features
                })
                train_loss.append(loss)
                train_acc.append(acc)

            print('epoch_{}'.format(epoch+1),'train loss:', np.mean(train_loss), 'train acc', np.mean(train_acc))
            train_writer.add_summary(tf.Summary(value=[tf.Summary.Value(tag='loss', simple_value=np.mean(train_loss))]),epoch)
            train_writer.add_summary(tf.Summary(value=[tf.Summary.Value(tag='acc', simple_value=np.mean(train_acc))]), epoch)

            if (epoch+1)%2==0:
                print(epoch+1, 'saved')
                saver.save(sess, exp_path+'epoch_{}'.format(epoch+1))


from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

class FilterPage:
    SEARCHBAR = (By.XPATH, "/html/body/app-root/app-clients/header/form")
    LOYALTYFILTER = (
        By.XPATH,
        "/html/body/app-root/app-clients/header/aside/div[1]/app-client-loyality-level-filter/div/div[1]",
    )
    OPTION = (
        By.XPATH,
        "/html/body/app-root/app-clients/header/aside/div[1]/app-client-loyality-level-filter/div/div[2]/mat-checkbox[1]/label/div",
    )
    SEARCH_BTN = (
        By.XPATH,
        "/html/body/app-root/app-clients/header/aside/div[2]/button[1]",
    )

    def __init__(self, driver):
        self.driver = driver

    def check_filters(self):
        wait = WebDriverWait(self.driver, 20)
        searchbar = wait.until(EC.visibility_of_element_located(self.SEARCHBAR))
        searchbar.click()
        loyaltyfilter = wait.until(EC.visibility_of_element_located(self.LOYALTYFILTER))
        loyaltyfilter.click()
        option = wait.until(EC.visibility_of_element_located(self.OPTION))
        option.click()
        loyaltyfilter.click()
        search_btn = wait.until(EC.visibility_of_element_located(self.SEARCH_BTN))
        search_btn.click()


#!/usr/bin/env python
#
# Megan Rich, HRL, 8/25/14
# This node checks if the tf frame '/head_frame' obtained from
# head registration is currently within reach of the PR2. If the
# head frame is not within reach of the PR2, it will move the PR2 base
# to within range of the subject's head.

import roslib
roslib.load_manifest('tf')
roslib.load_manifest('actionlib')
roslib.load_manifest('move_base')
import actionlib
#from actionlib_msgs.msg import MoveBaseAction
from move_base_msgs.msg import MoveBaseAction, MoveBaseActionGoal
import rospy
import math
import tf
from geometry_msgs.msg import Twist, PointStamped, Pose, Quaternion, PoseStamped
from std_msgs.msg import String
import os

class check_head():

    def __init__(self):
        rospy.init_node('check_head')
        self.listener = tf.TransformListener()
        self.pub=rospy.Publisher('head_check', String)
        self.head=rospy.Publisher('head_check_confirm', String)
        self.move=rospy.Publisher('base_controller/command', Twist)
        rospy.Subscriber('head_check', String, self.head_check)
        rospy.sleep(1)
        self.cmd=Twist()
        self.l=0
        self.r=0
        self.t=0
        self.trans14=(0.13928415716177617, 0.6565833449408256, -1.357303916796)
        self.rot14=(0.2789777273842869, -0.05907426262263365, 0.8767308579569227, -0.3873301715916394)
        self.transh=(0.13895118715509372, 0.6563869581415823, -1.3570648116919164)
        self.roth=(0.2675468812908289, -0.052590910844725884, 0.8789907250153403, -0.39118814877892155)
        #precalculated values of the maximum length of both arms (form /(l or r)_shoulder_pan_link
        #to the the appropriate tool frame
        #assumes spoon tool is in left gripper
        self.l_arm_length=1.36
        self.r_arm_length=0.94
        #check if left and right arms are within reach of the registered head
        self.calc_left()
        self.calc_right()

    #check if head check is complete
    def head_check(self, data):
        self.mess=data.data
        if self.mess == 'Ready':
            self.t=self.t+1
            if self.t==2:
                self.head.publish('Ready')
                print('Head check complete')
                os._exit(0)

    def calc_left (self):

        try:
            #look up transforms of /l_shoulder_pan_link and /head_frame
            #with respect to same coordinate frame (/odom_combined)
            (trans1, rot1)=self.listener.lookupTransform('/l_shoulder_pan_link', '/odom_combined', rospy.Time(0))
            #(trans14, rot14)=self.listener.lookupTransform('/head_frame', '/odom_combined', rospy.Time(0))
            #calculate the distance between them (distance to head)
            self.l_dist2head=math.sqrt((self.trans14[0]-trans1[0])**2+(self.trans14[1]-trans1[1])**2+(self.trans14[2]-trans1[2])**2)
            print('Left distance: %s'%self.l_dist2head)

        except (tf.LookupException, tf.ConnectivityException, tf.ExtrapolationException): #check for tf exceptions
            print ('Error! Most likely cause: tf lookup Exception')
            self.l_dist2head=1.

        #check if the head is within reach
        if self.l_dist2head >(self.l_arm_length):
            print('Head not reachable!')
            print('Left arm too short')
            #send message to master control, so it will not start yet
            self.pub.publish('Too far')
            #move base to be within reach of left arm
            self.base_mover('l')
        elif self.l_dist2head==1.:
            #if there was a tf exception try again 3 times before quitting
            print('calculation failed')
            self.l=self.l+1
            if self.l<=3:
                print('trying again')
                self.calc_left()
            else:
                print('exiting')
                os._exit(0)
        else:
            #if head within reach of left arm, publish a message to the master control node
            #this message allows it to begin
            print('Head within reach')
            self.pub.publish('Ready')
    def calc_right(self):
        try:
            #look up transforms of /r_shoulder_pan_link and /head_frame
            #with respect to same coordinate frame (/odom_combined)
            (trans1, rot1)=self.listener.lookupTransform('/r_shoulder_pan_link', '/odom_combined', rospy.Time(0))
            #(trans14, rot14)=self.listener.lookupTransform('/head_frame', '/odom_combined', rospy.Time(0))
            #calculate the distance between them (distance to head)
            self.r_dist2head=math.sqrt((self.trans14[0]-trans1[0])**2+(self.trans14[1]-trans1[1])**2+(self.trans14[2]-trans1[2])**2)
            print('Right distance: %s'%self.r_dist2head)
        except (tf.LookupException, tf.ConnectivityException, tf.ExtrapolationException): #check for tf exceptions
            print ('Error! Most Likely a tf lookup exception')
            self.r_dist2head=1.

        #check if head is within reach of the right arm
        if self.r_dist2head >(self.r_arm_length):
            print('Head not reachable')
            print('Right arm too short')
             #send message to master control, so it will not start yet
            self.pub.publish('Too far')
            #move base to be within reach of right arm
            self.base_mover('r')
        elif self.r_dist2head==1.:
            #if there was a tf exception try again 3 times before quitting
            print('calculation failed')
            self.r=self.r+1
            if self.r<=3:
                print('trying again')
                self.calc_right()
            else:
                print('exiting')
                os._exit(0)
        else:
            print ('Head within reach')
            self.pub.publish('Ready')

    def base_mover(self, side):
        if side == 'l':
            #make sure it won't run over someone's foot
            #move base so left arm is within range of head
            print('moving better location for the left arm')
            while  not rospy.is_shutdown() and self.l_dist2head>self.l_arm_length:
                (trans1, rot1)=self.listener.lookupTransform('/l_shoulder_pan_link', '/odom_combined', rospy.Time(0))
                (trans2, rot2)=self.listener.lookupTransform('/base_footprint', '/odom_combined', rospy.Time(0))
                #(trans14, rot14)=self.listener.lookupTransform('/head_frame', '/odom_combined', rospy.Time(0))

                self.l_dist2head=math.sqrt((trans1[0]-self.trans14[0])**2+(trans1[1]-self.trans14[1])**2+(trans1[2]-self.trans14[2])**2)
                self.cmd.linear.x=trans2[0]-self.trans14[0]
                self.cmd.linear.y=trans2[1]-self.trans14[1]
                self.cmd.linear.z=0.
                self.cmd.angular.x=0.
                self.cmd.angular.y=0.
                self.cmd.angular.z=0.
                self.move.publish(self.cmd)
                rospy.sleep(1)
            #when done moving
            print('done moving')
            print('performing final head check')
            #check to make sure it worked and moving the base didn't mess up the other arm
            self.t=0
            self.calc_left()
            self.calc_right()
        if side == 'r':
            #make sure it won't run over someone's foot
            #move base so right arm is within range of head
            print('moving to better location for right arm')
            while not rospy.is_shutdown() and self.r_dist2head>self.r_arm_length:
                (trans1, rot1)=self.listener.lookupTransform('/r_shoulder_pan_link', '/odom_combined', rospy.Time(0))
                (trans2, rot2)=self.listener.lookupTransform('/base_footprint', '/odom_combined', rospy.Time(0))
                #(trans14, rot14)=self.listener.lookupTransform('/head_frame', '/odom_combined', rospy.Time(0))
                self.r_dist2head=math.sqrt((trans1[0]-self.trans14[0])**2+(trans1[1]-self.trans14[1])**2+(trans1[2]-self.trans14[2])**2)
                self.cmd.linear.x=trans2[0]-self.trans14[0]
                self.cmd.linear.y=trans2[1]-self.trans14[1]
                self.cmd.linear.z=0.
                self.cmd.angular.x=0.
                self.cmd.angular.y=0.
                self.cmd.angular.z=0.
                self.move.publish(self.cmd)
                rospy.sleep(1)
            #when done moving
            print('done moving')
            print('performing final head check')
            #check to make sure it worked and that moving the base didn't mess up the other arm
            self.t=0
            self.calc_left()
            self.calc_right()

if __name__=='__main__':
    a = check_head()
    while not rospy.is_shutdown():
        rospy.spin()


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

from collections import namedtuple
from functools import partial
from uuid import uuid4

import falcon
from django.apps import apps
from elasticsearch_dsl import Q

from mcod.applications.depricated.schemas import ApplicationsList, ApplicationSuggestion
from mcod.applications.depricated.serializers import ApplicationsSerializer, ApplicationsMeta
from mcod.applications.deserializers import ApplicationApiRequest, ApplicationApiSearchRequest, CreateSubmissionRequest
from mcod.applications.documents import ApplicationsDoc
from mcod.applications.serializers import ApplicationApiResponse, SubmissionApiResponse
from mcod.applications.tasks import send_application_proposal
from mcod.core.api.handlers import CreateOneHdlr
from mcod.core.api.handlers import SearchHdlr, RetrieveOneHdlr
from mcod.core.api.hooks import login_optional
from mcod.core.api.views import BaseView
from mcod.core.versioning import versioned
from mcod.datasets.depricated.schemas import DatasetsList
from mcod.datasets.depricated.serializers import DatasetSerializer, DatasetsMeta
from mcod.datasets.deserializers import DatasetApiSearchRequest
from mcod.datasets.documents import DatasetsDoc
from mcod.datasets.serializers import DatasetApiResponse
from mcod.following.handlers import FollowingSearchHandler
from mcod.following.handlers import RetrieveOneFollowHandler
from mcod.lib.handlers import (
    CreateHandler)
from mcod.lib.handlers import SearchHandler

class ApplicationSearchApiView(BaseView):
    @falcon.before(login_optional)
    @versioned
    def on_get(self, request, response, *args, **kwargs):
        self.handle(request, response, self.GET, *args, **kwargs)

    @falcon.before(login_optional)
    @on_get.version('1.0')
    def on_get(self, request, response, *args, **kwargs):
        self.handle(request, response, self.GET_1_0, *args, **kwargs)

    class GET(SearchHdlr):
        deserializer_schema = partial(ApplicationApiSearchRequest, many=False)
        serializer_schema = partial(ApplicationApiResponse, many=True)
        search_document = ApplicationsDoc()

        def _queryset_extra(self, queryset, **kwargs):
            return queryset.filter('term', status='published')

    class GET_1_0(FollowingSearchHandler):
        meta_serializer = ApplicationsMeta()
        deserializer_schema = ApplicationsList()
        serializer_schema = ApplicationsSerializer(many=True)
        search_document = ApplicationsDoc()

class ApplicationApiView(BaseView):
    @falcon.before(login_optional)
    @versioned
    def on_get(self, request, response, *args, **kwargs):
        self.handle(request, response, self.GET, *args, **kwargs)

    @falcon.before(login_optional)
    @on_get.version('1.0')
    def on_get(self, request, response, *args, **kwargs):
        self.handle(request, response, self.GET_1_0, *args, **kwargs)

    class GET_1_0(RetrieveOneFollowHandler):
        database_model = apps.get_model('applications', 'Application')
        serializer_schema = ApplicationsSerializer(many=False)

    class GET(RetrieveOneHdlr):
        deserializer_schema = partial(ApplicationApiRequest, many=False)
        database_model = apps.get_model('applications', 'Application')
        serializer_schema = partial(ApplicationApiResponse, many=False)

        def _get_instance(self, id, *args, **kwargs):
            instance = getattr(self, '_cached_instance', None)
            if not instance:
                model = self.database_model
                try:
                    self._cached_instance = model.objects.get(pk=id, status='published')
                except model.DoesNotExist:
                    raise falcon.HTTPNotFound
            return self._cached_instance

class ApplicationDatasetsView(BaseView):
    @falcon.before(login_optional)
    @versioned
    def on_get(self, request, response, *args, **kwargs):
        self.handle(request, response, self.GET, *args, **kwargs)

    @falcon.before(login_optional)
    @on_get.version('1.0')
    def on_get(self, request, response, *args, **kwargs):
        self.handle(request, response, self.GET_1_0, *args, **kwargs)

    class GET_1_0(SearchHandler):
        meta_serializer = DatasetsMeta()
        deserializer_schema = DatasetsList()
        serializer_schema = DatasetSerializer(many=True, include_data=('institution',))
        search_document = DatasetsDoc()

        def _queryset(self, cleaned, *args, **kwargs):
            qs = super()._queryset(cleaned, *args, **kwargs)
            if 'id' in kwargs:
                qs = qs.query("nested", path="applications",
                              query=Q("term", **{'applications.id': kwargs['id']}))
            return qs

    class GET(SearchHdlr):
        deserializer_schema = partial(DatasetApiSearchRequest, many=False)
        serializer_schema = partial(DatasetApiResponse, many=True)
        search_document = DatasetsDoc()

        def _queryset_extra(self, queryset, id=None, **kwargs):
            if id:
                queryset = queryset.query("nested", path="applications",
                                          query=Q("term", **{'applications.id': id}))
            return queryset.filter('term', status='published')

class ApplicationSubmitView(BaseView):
    @versioned
    def on_post(self, request, response, *args, **kwargs):
        self.handle_post(request, response, self.POST, *args, **kwargs)

    @on_post.version('1.0')
    def on_post(self, request, response, *args, **kwargs):
        self.handle(request, response, self.POST_1_0, *args, **kwargs)

    class POST_1_0(CreateHandler):
        databse_model = apps.get_model('applications', 'Application')
        deserializer_schema = ApplicationSuggestion()

        def _data(self, request, cleaned, *args, **kwargs):
            send_application_proposal.delay(cleaned)
            return cleaned

        def _serialize(self, data, meta, links=None, *args, **kwargs):
            return {}

    class POST(CreateOneHdlr):
        databse_model = apps.get_model('applications', 'Application')
        deserializer_schema = partial(CreateSubmissionRequest)
        serializer_schema = partial(SubmissionApiResponse, many=False)

        def clean(self, *args, **kwargs):
            cleaned = super().clean(*args, **kwargs)
            return cleaned

        def _get_data(self, cleaned, *args, **kwargs):
            _data = cleaned['data']['attributes']
            send_application_proposal.s(dict(_data)).apply_async(countdown=1)
            fields, values = [], []
            for field, val in _data.items():
                fields.append(field)
                values.append(val)
            fields.append('id')
            values.append(str(uuid4()))
            result = namedtuple('Submission', fields)(*values)
            return result


#!/usr/bin/python

import argparse
import os
import sys

REASON_PHRASES = {
    400: "Bad Request",
    403: "Forbidden",
    451: "Unavailable",
    502: "Bad Gateway",
    503: "Service Unavailable",
    504: "Gateway Timeout",
}

def status_from_file(f):
    filepath = f.name
    filename = os.path.basename(filepath)
    status_code_str = filename.split(".", 1)[0]
    return int(status_code_str)

def compress_markup(content):
    return content.replace("\n", "")

def write_http_response(stream, status_code, content):
    reason_phrase = REASON_PHRASES[status_code]
    stream.write("HTTP/1.1 %d %s\r\n" % (status_code, reason_phrase))
    stream.write("Content-Type: text/html; charset=UTF-8\r\n")
    stream.write("Content-Length: %d\r\n" % len(content))
    stream.write("\r\n")
    stream.write(content)

def main():
    parser = argparse.ArgumentParser(description="generate an http response")
    parser.add_argument("--no-compress",
                        action="store_false",
                        dest="compress",
                        default=True)
    parser.add_argument("file", type=open)
    args = parser.parse_args()

    status_code = status_from_file(args.file)
    content = args.file.read()
    if args.compress:
        content = compress_markup(content)
    write_http_response(sys.stdout, status_code, content)

if __name__ == "__main__":
    sys.exit(main())


from slips_files.common.imports import *
import ipaddress

class HorizontalPortscan():
    def __init__(self, db):
        self.db = db
        self.cache_det_thresholds = {}
        self.fieldseparator = self.db.get_field_separator()
        self.port_scan_minimum_dips = 5
        self.pending_horizontal_ps_evidence = {}
        self.alerted_once_horizontal_ps = {}

    def calculate_confidence(self, pkts_sent):
        if pkts_sent > 10:
            confidence = 1
        elif pkts_sent == 0:
            return 0.3
        else:
            confidence = pkts_sent / 10.0
        return confidence

    def combine_evidence(self):
        """
        Combines all the evidence in pending_horizontal_ps_evidence into 1 evidence and calls set_evidence
        this function is called every 3 pending ev
        """
        for key, evidence_list in self.pending_horizontal_ps_evidence.items():
            profileid, twid, state, protocol, dport = key.split('-')
            final_evidence_uids = []
            final_pkts_sent = 0
            for evidence in evidence_list:
                timestamp, pkts_sent, evidence_uids, amount_of_dips = evidence
                final_evidence_uids += evidence_uids
                final_pkts_sent += pkts_sent
            self.set_evidence_horizontal_portscan(
                timestamp,
                final_pkts_sent,
                protocol,
                profileid,
                twid,
                final_evidence_uids,
                dport,
                amount_of_dips
            )

        self.pending_horizontal_ps_evidence = {}

    def get_resolved_ips(self, dstips: dict) -> list:
        """
        returns the list of dstips that have dns resolution, we will discard them when checking for
        horizontal portscans
        """
        dstips_to_discard = []

        for dip in dstips:
            dns_resolution = self.db.get_dns_resolution(dip)
            dns_resolution = dns_resolution.get('domains', [])
            if dns_resolution:
                dstips_to_discard.append(dip)
        return dstips_to_discard

    def check(self, profileid, twid):
        def get_uids():
            """
            returns all the uids of flows to this port
            """
            uids = []
            for dip in dstips:
                for uid in dstips[dip]['uid']:
                     uids.append(uid)
            return uids

        saddr = profileid.split(self.fieldseparator)[1]
        try:
            saddr_obj = ipaddress.ip_address(saddr)
            if saddr == '255.255.255.255' or saddr_obj.is_multicast:
                return False
        except ValueError:
            pass

        direction = 'Dst'
        role = 'Client'
        type_data = 'Ports'
        for state in ('Established', 'Not Established'):
            for protocol in ('TCP', 'UDP'):
                dports = self.db.getDataFromProfileTW(
                    profileid, twid, direction, state, protocol, role, type_data
                )

                for dport in dports.keys():
                    dstips: dict = dports[dport]['dstips']
                    for ip in self.get_resolved_ips(dstips):
                        dstips.pop(ip)
                    amount_of_dips = len(dstips)
                    cache_key = f'{profileid}:{twid}:dport:{dport}:HorizontalPortscan'
                    prev_amount_dips = self.cache_det_thresholds.get(cache_key, 0)

                    if (
                        amount_of_dips >= self.port_scan_minimum_dips
                        and prev_amount_dips + 5 <= amount_of_dips
                    ):

                        pkts_sent = 0
                        for dip in dstips:
                            if 'spkts' not in dstips[dip]:
                                pkts_sent += int(dstips[dip]["pkts"])
                            else:
                                pkts_sent += int(dstips[dip]["spkts"])

                        uids: list = get_uids()
                        timestamp = next(iter(dstips.values()))['stime']

                        self.cache_det_thresholds[cache_key] = amount_of_dips

                        if not self.alerted_once_horizontal_ps.get(cache_key, False):
                            self.alerted_once_horizontal_ps[cache_key] = True
                            self.set_evidence_horizontal_portscan(
                                timestamp,
                                pkts_sent,
                                protocol,
                                profileid,
                                twid,
                                uids,
                                dport,
                                amount_of_dips
                            )
                        else:
                            evidence_details = (timestamp, pkts_sent, uids, amount_of_dips)
                            key = f'{profileid}-{twid}-{state}-{protocol}-{dport}'
                            try:
                                self.pending_horizontal_ps_evidence[key].append(evidence_details)
                            except KeyError:
                                self.pending_horizontal_ps_evidence[key] = [evidence_details]
                            if len(self.pending_horizontal_ps_evidence[key]) == 3:
                                self.combine_evidence()

    def set_evidence_horizontal_portscan(
            self,
            timestamp,
            pkts_sent,
            protocol,
            profileid,
            twid,
            uid,
            dport,
            amount_of_dips
    ):
        evidence_type = 'HorizontalPortscan'
        attacker_direction = 'srcip'
        source_target_tag = 'Recon'
        srcip = profileid.split('_')[-1]
        attacker = srcip
        threat_level = 'medium'
        category = 'Recon.Scanning'
        portproto = f'{dport}/{protocol}'
        port_info = self.db.get_port_info(portproto)
        port_info = port_info or ""
        confidence = self.calculate_confidence(pkts_sent)
        description = (
            f'horizontal port scan to port {port_info} {portproto}. '
            f'From {srcip} to {amount_of_dips} unique dst IPs. '
            f'Total packets sent: {pkts_sent}. '
            f'Threat Level: {threat_level}. '
            f'Confidence: {confidence}. by Slips'
        )

        self.db.setEvidence(evidence_type, attacker_direction, attacker, threat_level, confidence, description,
                                 timestamp, category, source_target_tag=source_target_tag, conn_count=pkts_sent,
                                 port=dport, proto=protocol, profileid=profileid, twid=twid, uid=uid)


#
# copy_marlin_variant_to_framework.py
#
Import("env")

# Detect that 'vscode init' is running
from SCons.Script import COMMAND_LINE_TARGETS
if "idedata" in COMMAND_LINE_TARGETS:
    env.Exit(0)

import os,shutil
from SCons.Script import DefaultEnvironment
from platformio import util
from platformio.package.meta import PackageSpec

def copytree(src, dst, symlinks=False, ignore=None):
    for item in os.listdir(src):
        s = os.path.join(src, item)
        d = os.path.join(dst, item)
        if os.path.isdir(s):
            shutil.copytree(s, d, symlinks, ignore)
        else:
            shutil.copy2(s, d)

env = DefaultEnvironment()
platform = env.PioPlatform()
board = env.BoardConfig()
variant = board.get("build.variant")

platform_packages = env.GetProjectOption('platform_packages')
# if there's no framework defined, take it from the class name of platform
framewords = {
    "Ststm32Platform": "framework-arduinoststm32",
    "AtmelavrPlatform": "framework-arduino-avr"
}
if len(platform_packages) == 0:
    platform_name = framewords[platform.__class__.__name__]
else:
    platform_name = PackageSpec(platform_packages[0]).name

FRAMEWORK_DIR = platform.get_package_dir(platform_name)
assert os.path.isdir(FRAMEWORK_DIR)
assert os.path.isdir("buildroot/share/PlatformIO/variants")

variant_dir = os.path.join(FRAMEWORK_DIR, "variants", variant)

source_dir = os.path.join("buildroot/share/PlatformIO/variants", variant)
assert os.path.isdir(source_dir)

if os.path.isdir(variant_dir):
    shutil.rmtree(variant_dir)

if not os.path.isdir(variant_dir):
    os.mkdir(variant_dir)

copytree(source_dir, variant_dir)


from flask import Blueprint, render_template, request, jsonify, redirect, url_for, flash, abort
from studyup.models import Question, Choice, Answer, Comment, User
from studyup import db
from studyup.discussion.forms import CommentForm
from flask_login import login_required, current_user
from datetime import datetime

discussion = Blueprint('discussion', __name__)
comment = Blueprint('comment', __name__)

#returns topic name of given topicNo
@discussion.route("/api/topic/<int:topic_no>")
def topic(topic_no):
    TOPICS = [
        (1, 1, 1, 'Standards and units, Unit consistency, Uncertainty and significant figures'),
        (1, 1, 2, 'Vectors and vector addition, Components of vectors, Unit vectors'),
        (1, 2, 3, 'Displacement, time, and average velocity, Instantaneous velocity'),
        (1, 2, 4, 'Average and instantaneous acceleration'),
        (1, 2, 5, 'Motion with constant acceleration, Freely falling bodies'),
        (1, 3, 6, 'Position and velocity vectors, Acceleration vector'),
        (1, 3, 7, 'Projectile motion'),
        (1, 3, 8, 'Motion in a circle'),
        (1, 3, 9, 'Relative velocity'),
        (1, 4, 10, 'Force and interactions, Mass and weight, Newton\'s first law, Inertial frames of reference'),
        (1, 4, 11, 'Free-body diagrams, Newton\'s second law, Newton\'s third law'),
        (1, 5, 12, 'Newton\'s 1st law: particles in equilibrium'),
        (1, 5, 13, 'Newton\'s 2nd law: dynamics of particles'),
        (1, 5, 14, 'Frictional forces'),
        (1, 5, 15, 'Dynamics of circular motion'),
        (2, 6, 16, 'Scalar product, Work'),
        (2, 6, 17, 'Work and kinetic energy'),
        (2, 6, 18, 'Work and energy with varying forces, Power'),
        (2, 7, 19, 'Gravitational potential energy, Conservation of mechanical energy (gravitational force), Conservative and nonconservative forces'),
        (2, 7, 20, 'Elastic potential energy, Conservation of mechanical energy'),
        (2, 7, 21, 'Force and potential energy, Energy diagrams'),
        (2, 8, 22, 'Momentum and Impulse'),
        (2, 8, 23, 'Conservation of momentum, Momentum conservation and collisions'),
        (2, 8, 24, 'Elastic collisions'),
        (2, 8, 25, 'Center of mass'),
        (2, 9, 26, 'Angular velocity and acceleration, Rotation with constant angular acceleration'),
        (2, 9, 27, 'Relating linear and angular kinematics'),
        (2, 9, 28, 'Energy in rotational motion, Parallel-axis theorem'),
        (2, 10, 29, 'Vector product, Torque'),
        (2, 10, 30, 'Torque and Angular acceleration for a rigid body'),
        (2, 10, 31, 'Rigid-body rotation about a moving axis'),
        (2, 10, 32, 'Angular momentum, Conservation of angular momentum'),
        (3, 11, 33, 'Conditions for equilibrium, Center of gravity'),
        (3, 11, 34, 'Solving rigid-body equilibrium problems'),
        (3, 11, 35, 'Stress, strain, elastic moduli, Elasticity and plasticity'),
        (3, 12, 36, 'Density, Pressure in a fluid'),
        (3, 12, 37, 'Buoyancy'),
        (3, 12, 38, 'Fluid flow, Bernoulli\'s equation'),
        (3, 13, 39, 'Newton\'s law of gravitation, Weight'),
        (3, 13, 40, 'Gravitational potential energy, Motion of satellites'),
        (3, 13, 41, 'Kepler\'s laws and the motion of the planets'),
        (3, 14, 42, 'Describing oscillation, Simple harmonic motion'),
        (3, 14, 43, 'Energy in simple harmonic motion'),
        (3, 14, 44, 'Applications of simple harmonic motion, The simple pendulum, The physical pendulum'),
        (3, 14, 45, 'Damped Oscillations, Forced Oscillations'),
        (3, 15, 46, 'Types of mechanical waves, Periodic waves, Mathematical description of wave, Speed of a transverse wave'),
        (3, 15, 47, 'Energy in wave motion, Wave interference, boundary conditions, and superposition'),
        (3, 15, 48, 'Standing waves on a string, Normal modes of a string'),
        (3, 16, 49, 'Doppler Effect')
            ]

    return jsonify({'name': TOPICS[topic_no - 1][3]})

@discussion.route("/api/topic/<int:topic_num>/questions")
def questionPerTopic(topic_num):
    q = Question.query.filter_by(topic_no=int(topic_num)).all()

    qList = []
    for question in q:
        questionObj = {}
        questionObj['id'] = question.id
        questionObj['body'] = question.body
        qList.append(questionObj)
    return jsonify({'questions': qList})

@discussion.route('/discussion')
def select():
    return render_template('discussion.html')

@discussion.route('/discussion/<int:question_id>', methods=['GET','POST'])
@login_required
def add_comment(question_id):
    form = CommentForm()
    question = Question.query.filter_by(id=question_id).first()
    if form.validate_on_submit():
        comment = Comment()
        comment.time_posted = datetime.utcnow()
        comment.comment = form.body.data
        user = User.query.filter_by(username=current_user.username).first()
        comment.user_id = user.id
        comment.question_id = question_id
        db.session.add(comment)
        db.session.commit()
        flash('Comment added!', 'success')
        comments = Comment.query.filter_by(question_id=question_id).all()
        return redirect(url_for('discussion.add_comment', question_id=question_id, comments=comments, tempRemove=0))

    comments = Comment.query.filter_by(question_id=question_id).all()
    return render_template('view-question.html', form=form, question=question, comments=comments, tempRemove=0)

@discussion.route('/discussion/<int:question_id>/edit/<int:comment_id>', methods=['GET','POST'])
@login_required
def edit_comment(question_id, comment_id):
    question = Question.query.filter_by(id=question_id).first()
    comments = Comment.query.filter_by(question_id=question_id).all()
    comment = Comment.query.filter_by(id=comment_id).first()
    form = CommentForm()
    if comment.user != current_user:
        abort(403)
    if form.validate_on_submit():
        comment.comment = form.body.data
        comment.edited = True
        db.session.commit()
        flash('Comment edited', 'success')
        return redirect(url_for('discussion.add_comment', question_id=question_id, comments=comments, tempRemove=0))
    return render_template('view-question.html', question=question, form=form, comments=comments, tempRemove=comment_id, editComment=comment)

@discussion.route('/discussion/<int:question_id>/delete/<int:comment_id>', methods=['POST'])
@login_required
def delete_comment(question_id,comment_id):
    # question = Question.query.filter_by(id=question_id).first()
    comments = Comment.query.filter_by(question_id=question_id).all()
    comment = Comment.query.filter_by(id=comment_id).first()
    if current_user.user_type != 2: # not a moderator
        abort(403)
    db.session.delete(comment)
    db.session.commit()
    flash('Comment has been deleted!', 'success')
    return redirect(url_for('discussion.add_comment',question_id=question_id, comments=comments))


from collections import defaultdict
from collections.abc import Iterable
from typing import Optional, Generator, Union, Hashable, List, Dict
import sys

import dataset

from pymemdb import Column, ColumnDoesNotExist

version = sys.version_info
if version.major < 3:  # pragma: no cover
    raise Exception("Python version must be 3.6 or higher")
if version.major >= 3 and version.minor < 8:  # pragma: no cover
    ORDER_TYPE = Union[str, bool]
else:  # pragma: no cover
    from typing import Literal  # type: ignore
    ORDER_TYPE = Literal["ascending", "descending", False]  # type:ignore

ROW_GEN = Generator[dict, None, None]

class Table:
    """Object that represents a Table in the Database.
       Can also used standalone"""

    def __init__(self, name: Optional[str] = None,
                 primary_id: str = "id") -> None:
        self.name = name
        self.idx_name = primary_id
        self._columns: defaultdict = defaultdict(Column)
        self.idx = 1
        self.keys: set = set()
        self.create_column(name=self.idx_name, unique=True)

    @classmethod
    def from_dataset(cls, table: dataset.table.Table, name=None) -> None:
        if name is None:
            name = table.name

        pk = None
        for col in table.table.columns:
            if col.primary_key is True:
                pk = col.name
                break

        pymemdb_table = cls(name, primary_id=pk)
        for row in table:
            pymemdb_table.insert(row)

        return pymemdb_table

    def to_dataset(self, db: dataset.Database, drop=False):
        if self.name in db.tables and drop:
            db[self.name].drop()
        if self.name not in db.tables:
            db.create_table(self.name, primary_id=self.idx_name)

        with db as tx:
            for row in self.all():
                tx[self.name].insert(row)

    def all(self, ordered: ORDER_TYPE = False) -> ROW_GEN:
        """returns a generator of all rows of the table.

        Keyword Arguments:
            ordered {["ascending", "descending", False]} -- Can be set to
                ascending or descending to sort by the primary id column
                (default: {False})
        Raises:
            ValueError: [if 'ordered' is not in {"ascending', 'descending',
                                                 False}]

        Returns:
            Generator -- [A Generator over all the rows in the table]

        Yields:
            dict -- [Dictionary that contains all elements of a row in the
                     table]
        """
        if ordered is False:
            for i in self.keys:
                yield self._get_row(i)
        elif ordered == "ascending":
            for i in sorted(self.keys):
                yield self._get_row(i)
        elif ordered == "descending":
            for i in sorted(self.keys, reverse=True):
                yield self._get_row(i)
        else:
            raise ValueError("Value for kwarg 'ordered' not in [False, "
                             "ascending, descending] !")

    def create_column(self, name: str, default: Hashable = None,
                      unique: bool = False) -> None:
        """Create a Column in the table.

        Arguments:
            name {str} -- Name of the column

        Keyword Arguments:
            default {Hashable} -- Default value for the column
                                    (default: {None})
            unique {bool} -- If values are enforced to be unique for this
                             column. If True, trying to insert a value more
                             than once will raise UniqueConstraintError
                             (default: {False})
        """
        self._columns[name] = Column(default=default, unique=unique)

    @property
    def columns(self) -> List[str]:
        """Returns a list of all column names of the table.

        Returns:
            List[str] -- [List of column names]

        """
        return list(self._columns)

    def drop(self) -> None:
        """Delete table."""
        del self

    def insert(self, row: Dict) -> int:
        """Inserts a row in the table. If a column is not present,
           it will be created with default value None

        Arguments:
            row {Dict} -- dictionary that represents a row in the table.

        Raises:
            UniqueConstraintError: [if constraint of a column is violated]

        Returns:
            int -- [primary key for the row inserted]
        """
        if self.idx_name in row:
            idx = row[self.idx_name]
        else:
            while self.idx in self.keys:
                self.idx += 1
            idx = self.idx
        self.keys.add(idx)
        for key, val in row.items():
            self._columns[key].insert(idx, val)
        if self.idx_name not in row:
            self._columns[self.idx_name].insert(idx, idx)
        return idx

    def insert_ignore(self, row: Dict, keys: List[str], ignore_errors: bool = True) -> Optional[int]:
        """Inserts rows into the table. If another row is already present
           where all the values are identical for the fields in 'keys', the
           insert will be skipped

        Arguments:
            row {Dict} -- [row to be inserted]
            keys {List[str]} -- [List of columns to check for ignore]

        Raises:
            UniqueConstraintError: [if constraint of a column is violated]

        Returns:
            Optional[int] -- [primary key for the row inserted or None if
                              the insert was skipped]

        """
        results = self.find(**{key: row[key] for key in keys}, ignore_errors=ignore_errors)
        try:
            next(results)
        except StopIteration:
            return self.insert(row)
        return None

    def find(self, ignore_errors: bool = True,
             **kwargs) -> Generator[dict, None, None]:
        """finds rows in the table.

        Keyword Arguments:
            **kwargs -- keyword is the column name and value represents the
                        value to search.
                        if value is in iterable, it matches a
                        SELECT * WHERE keyword IN val
                        search.
            ignore_errors {bool} -- if True, it raises an error if a column
                                    does not exist in the table
                                    (default: {False})

        Returns:
            Generator[dict] -- [Generator over all rows that match the search]
        """
        results = self._find_rows(ignore_errors=ignore_errors, **kwargs)

        for idx in results:
            yield {self.idx_name: idx, **self._get_row(idx)}

    def find_one(self, ignore_errors: bool = False, **kwargs) -> Optional[dict]:
        """finds a single row from the table, if there is one.
        Keyword Arguments:
            ignore_errors {bool} -- if True, it raises an error if a column
                                    does not exist in the table
                                    (default: {False})

        Returns:
            Optional[dict] -- single row from the table or None if there is
                              none that matches the query.
        """

        try:
            row = next(self.find(ignore_errors=ignore_errors, **kwargs))
        except StopIteration:
            return None
        return row

    def delete(self, ignore_errors: bool = False, **kwargs) -> int:
        pks = {row[self.idx_name] for row in self.find(**kwargs)}
        if len(pks) == 0 and not ignore_errors:
            raise KeyError(f"No matching rows found for {kwargs}")
        for pk in pks:
            self.keys.remove(pk)
        for col in self._columns.values():
            for pk in pks:
                col.drop(pk)
        return len(pks)

    def update(self, where: dict, **kwargs) -> int:
        pks = self._find_rows(**where)
        if not pks:
            return 0

        for col, val in kwargs.items():
            cell_dict = self._columns[col].cells
            val_dict = self._columns[col].values
            for pk in pks:
                cell_dict[pk] = val
                val_dict[val].add(pk)
        return len(pks)

    def update_replace(self, where: dict, **kwargs):
        n_rows = self.update(where=where, **kwargs)
        if n_rows == 0:
            return 0

        new_where = {**where, **kwargs}
        rows = self.find(**new_where)
        result_counter = defaultdict(frozenset)
        for row in rows:
            pk = row[self.idx_name]
            del row[self.idx_name]
            r = result_counter[tuple(row.items())]
            result_counter[tuple(row.items())] = r.union({pk})

        rowcount = 0
        for pks in result_counter.values():
            if len(pks) < 2:
                continue
            keep = min(pks)
            pks = pks.difference({keep})
            n = self.delete(**{self.idx_name: pks})
            rowcount += n

        return rowcount

    def _get_row(self, idx: int) -> dict:
        row = {col: self._columns[col].find_value(idx) for col in self.columns}
        row = {self.idx_name: idx, **row}
        return row

    def _find(self, col: str, val: Hashable) -> set:
        if isinstance(val, Iterable) and not isinstance(val, str):
            results: set = set()
            for v in val:
                results.update(self._columns[col].find(v))
            return results
        return self._columns[col].find(val)

    def _find_rows(self, ignore_errors: bool = True, **kwargs) -> set:
        results: set = set()
        for col, val in kwargs.items():
            if col not in self._columns:
                if ignore_errors:
                    continue
                else:
                    raise KeyError(f"Column {col} not in Table!")
            if len(results) == 0:
                results = self._find(col, val)
            else:
                pk = self._find(col, val)
                results = results.intersection(pk)
            if val == self._columns[col].default:
                column_cells = set(self._columns[col].cells)
                mis_def_keys = self.keys.symmetric_difference(column_cells)
                results.update(mis_def_keys)
            if not results:
                return set()
        return results

    def __eq__(self, other):
        return self.name == other.name

    def __getitem__(self, col):
        if col not in self._columns:
            raise ColumnDoesNotExist("Column {col} does not exist!")
        return self._columns[col]

    def __delitem__(self, col):
        if col not in self._columns:
            raise ColumnDoesNotExist(f"Column {col} does not exist!")
        del self._columns[col]

    def __len__(self):
        return len(self.keys)


import pygame
from game_objects.puck import Puck
from game_objects.paddle import Paddle
import utils.Color as Color

pygame.init()
clock = pygame.time.Clock()

FPS = 60
DISPLAY_X = 600
DISPLAY_Y = 400
PADDLE_WIDTH = 10
PADDLE_HEIGHT = 50
PADDLE_DISTANCE_FROM_GOAL = 30
PUCK_RADIUS = 10
PUCK_SPEED = 5
PADDLE_SPEED = 10
gameDisplay = pygame.display.set_mode((DISPLAY_X, DISPLAY_Y))

puck = Puck(gameDisplay, board_width=DISPLAY_X, board_height=DISPLAY_Y,
            speed=PUCK_SPEED, radius=PUCK_RADIUS)
paddle_left = Paddle(gameDisplay, x=PADDLE_DISTANCE_FROM_GOAL,
                     board_height=DISPLAY_Y, height=PADDLE_HEIGHT,
                     width=PADDLE_WIDTH, speed = PADDLE_SPEED)
paddle_right = Paddle(gameDisplay, x=DISPLAY_X-PADDLE_DISTANCE_FROM_GOAL,
                      board_height=DISPLAY_Y, height=PADDLE_HEIGHT,
                      width=PADDLE_WIDTH, speed = PADDLE_SPEED)

def game_loop():
    game_exit = False
    while not game_exit:

        # EVENT HANDLER
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                game_exit = True
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_q:
                    game_exit = True
                if event.key == pygame.K_UP:
                    paddle_right.set_speed(-1)
                elif event.key == pygame.K_DOWN:
                    paddle_right.set_speed(1)
                if event.key == pygame.K_w:
                    paddle_left.set_speed(-1)
                elif event.key == pygame.K_s:
                    paddle_left.set_speed(1)
            elif event.type == pygame.KEYUP:
                if event.key == pygame.K_UP:
                    paddle_right.set_speed(0)
                if event.key == pygame.K_DOWN:
                    paddle_right.set_speed(0)
                if event.key == pygame.K_w:
                    paddle_left.set_speed(0)
                elif event.key == pygame.K_s:
                    paddle_left.set_speed(0)

        puck.checkPaddle(paddle_left)
        puck.checkPaddle(paddle_right)
        puck.update()
        paddle_left.update()
        paddle_right.update()

        gameDisplay.fill(Color.BLACK)
        puck.show()
        paddle_left.show()
        paddle_right.show()
        pygame.display.update()

        clock.tick(FPS)

game_loop()

pygame.quit()
quit()


# -*- coding: utf-8 -*-
import numpy as np
from scipy.stats import norm as scipy_norm

from ._patcher import Patcher

class GaussianPatcher(Patcher):
    def __init__(self,
                 area_mean=10.0,
                 area_cov=5.0,
                 eccentricity=0.5,
                 neighbors_structure='rook',
                 avoid_aggregation=True,
                 nb_of_missing_to_fill=1,
                 proceed_even_if_no_probability=True,
                 n_tries_target_sample=1000,
                 equi_neighbors_proba=False):
        super().__init__(neighbors_structure = neighbors_structure,
                         avoid_aggregation = avoid_aggregation,
                         nb_of_missing_to_fill = nb_of_missing_to_fill,
                         proceed_even_if_no_probability = proceed_even_if_no_probability,
                         n_tries_target_sample=n_tries_target_sample,
                         equi_neighbors_proba=equi_neighbors_proba)

        self.area_mean = area_mean
        self.area_cov = area_cov
        self.eccentricity = eccentricity

    def _sample(self, n):
        eccentricities = np.ones(n) * self.eccentricity
        areas = scipy_norm.rvs(loc=self.area_mean,
                               scale=self.area_cov,
                               size=n)
        areas[areas < 1] = 1

        return (areas, eccentricities)


from tests.BaseTestWithDB import BaseTestWithDB
from django.urls import reverse

class ProgrammingChallengesListURLTest(BaseTestWithDB):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.language = "en"

    def test_valid_programming_challenges_list(self):
        kwargs = {
            "topic_slug": "binary-numbers",
            "lesson_slug": "lesson-1",
        }
        url = reverse("topics:programming_challenges_list", kwargs=kwargs)
        self.assertEqual(url, "/en/topics/binary-numbers/lesson-1/programming/")


import numpy as np
import utils
import datetime
import cpuinfo
import os
import sys
import uuid
import tensorcircuit as tc

def tensorcircuit_benchmark(
    uuid,
    tcbackend,
    n,
    nlayer,
    nitrs,
    timeLimit,
    isgpu,
    mpsd,
    dt="32",
    minus=1,
    contractor="auto",
):
    meta = {}

    if isgpu == 0:
        os.environ["CUDA_VISIBLE_DEVICES"] = "-1"
        meta["isgpu"] = "off"

    else:
        # gpu = tf.config.list_physical_devices("GPU")
        # tf.config.experimental.set_memory_growth(device=gpu[0], enable=True)
        meta["isgpu"] = "on"
        meta["Gpuinfo"] = utils.gpuinfo()
    tc.set_backend(tcbackend)
    if dt == "32":
        tc.set_dtype("complex64")
        dtype = "complex64"
        vtype = "float32"
    else:  # dt == "64":
        tc.set_dtype("complex128")
        dtype = "complex128"
        vtype = "float64"
    if contractor not in ["auto", "cotengra"]:
        tc.set_contractor(contractor)
    elif contractor == "cotengra":
        import cotengra as ctg

        opt0 = ctg.ReusableHyperOptimizer(
            minimize="combo",
            max_repeats=512,
            max_time=90,
            progbar=True,
        )

        # def opt_reconf(inputs, output, size, **kws):
        #     tree = opt0.search(inputs, output, size)
        #     tree_r = tree.subtree_reconfigure_forest(
        #         progbar=True,
        #         num_trees=20,
        #         num_restarts=10,
        #         subtree_weight_what=("flops",),
        #     )
        #     return tree_r.get_path()

        tc.set_contractor(
            "custom",
            optimizer=opt0,
            contraction_info=True,
            preprocessing=True,
        )

    meta["contractor"] = contractor

    def tfi_energy(c, n, j=1.0, h=-1.0):
        e = 0.0
        for i in range(n):
            e += h * c.expectation((tc.gates.x(), [i]))
        for i in range(n - 1):
            e += j * c.expectation((tc.gates.z(), [i]), (tc.gates.z(), [(i + 1) % n]))
        return e

    meta["Software"] = "tensorcircuit[%s %s]" % (tcbackend, dt)
    meta["minus"] = minus
    meta["Cpuinfo"] = cpuinfo.get_cpu_info()["brand_raw"]
    meta["Version"] = {
        "sys": sys.version,
        "tensorcircuit": tc.__version__,
        "numpy": np.__version__,
    }
    meta["VQE test parameters"] = {
        "mpsd": mpsd,
        "nQubits": n,
        "nlayer": nlayer,
        "nitrs": nitrs,
        "timeLimit": timeLimit,
    }
    meta["UUID"] = uuid
    meta["Benchmark Time"] = (
        datetime.datetime.now().astimezone().strftime("%Y-%m-%d %H:%M %Z")
    )
    meta["Results"] = {}

    paramx = tc.backend.ones(nlayer * n, dtype=vtype)
    paramzz = tc.backend.ones(nlayer * n, dtype=vtype)

    def energy_raw(paramx, paramzz):
        if mpsd is None:
            c = tc.Circuit(n)
        else:
            c = tc.MPSCircuit(n)
            c.set_split_rules({"max_singular_values": mpsd})
        paramx = tc.backend.cast(paramx, dtype)
        paramzz = tc.backend.cast(paramzz, dtype)

        for i in range(n):
            c.H(i)
        for j in range(nlayer):
            for i in range(n - minus):
                c.exp1(
                    i,
                    (i + 1) % n,
                    theta=paramzz[j * n + i],
                    unitary=tc.gates._zz_matrix,
                )
            for i in range(n):
                c.rx(i, theta=paramx[j * n + i])
        if mpsd is None:
            e = tfi_energy(c, n)
            fd = 1.0
        else:
            e = tfi_energy(c, n)
            fd = c._fidelity
        # tensorflow only works for complex case, while jax only works for real case, don't know how to solve it
        # if tcbackend != "tensorflow":
        e = tc.backend.real(e)

        return e, fd

    energy_raw = tc.backend.value_and_grad(energy_raw, argnums=(0, 1), has_aux=True)
    energy_raw = tc.backend.jit(energy_raw)

    def energy(paramx, paramzz):
        # paramx = tc.backend.convert_to_tensor(paramx)
        # paramzz = tc.backend.convert_to_tensor(paramzz)
        (value, f), grads = energy_raw(paramx, paramzz)
        print("fidelity: ", f, value)
        # print(tc.backend.numpy(f), tc.backend.numpy(value))
        # value = tc.backend.numpy(tc.backend.real(value))
        # grads = [tc.backend.numpy(tc.backend.real(g)) for g in grads]
        return value, grads

    opt = utils.Opt(energy, [paramx, paramzz], tuning=True, backend=tcbackend)
    ct, it, Nitrs = utils.timing(opt.step, nitrs, timeLimit)
    meta["Results"]["with jit"] = {
        "Construction time": ct,
        "Iteration time": it,
        "# of actual iterations": Nitrs,
    }
    print(meta)
    return meta

if __name__ == "__main__":
    _uuid = str(uuid.uuid4())
    (
        n,
        nlayer,
        nitrs,
        timeLimit,
        isgpu,
        minus,
        path,
        dtype,
        contractor,
        mpsd,
        tcbackend,
    ) = utils.arg(dtype=True, contractor=True, mps=True, tc=True)
    if dtype == 1:
        dtypestr = "32"
    else:
        dtypestr = "64"

    r = tensorcircuit_benchmark(
        _uuid,
        tcbackend,
        n,
        nlayer,
        nitrs,
        timeLimit,
        isgpu,
        mpsd,
        dtypestr,
        minus=minus,
        contractor=contractor,
    )
    utils.save(r, _uuid, path)