import time

import torch
from torch.autograd import Variable
import torch.optim as optim

from model import SkipGram, CBOW

#DEBUG = True #False
DEBUG = False

if DEBUG:
    from dataset import Dataset
else:
    from dataset_old import Dataset, Sampler

import random
import numpy as np

import matplotlib.pyplot as plt

class word2vec:
    def __init__(self, input_file, model_name, vocabulary_size=100000,
                 embedding_dim=200, epoch=10, batch_size=256, windows_size=2, neg_sample_size=10):
        self.model_name = model_name
        if DEBUG:
            self.data_loader = Dataset(batch_size=batch_size, window_size=windows_size)
        else:
            self.data = Dataset([input_file, input_file], vocabulary_size)
            self.data_loader = Sampler(self.data, window_size=windows_size, neg_sample_size=neg_sample_size, batch_size=batch_size)
        self.vocabulary_size = vocabulary_size
        self.embedding_dim = embedding_dim
        self.epoch = epoch
        self.batch_size = batch_size
        self.windows_size = windows_size
        self.neg_sample_size = neg_sample_size

    def showPlot(self, points, title):
        plt.figure()
        fig, ax = plt.subplots()
        plt.plot(points)
        plt.show()

    def train(self, report=True):
        model = SkipGram(self.vocabulary_size, self.embedding_dim)

        loss_list = list()

        if torch.cuda.is_available():
            model.cuda()

        optimizer = optim.SGD(model.parameters(), lr=0.2)

        for epoch in range(self.epoch):

            start = time.time()
            self.data.process =True
            batch_num = 0
            batch_new = 0

            for data_word, data_sentence in self.data_loader():

                optimizer.zero_grad()
                loss = model(data_word) / self.batch_size
                # loss = model(pos_u, pos_v, neg_v, self.batch_size, target, contex, labels)
                loss_list.append(loss)
                loss.backward()
                optimizer.step()

                if report and batch_num % 7 == 0: # 3000
                    end = time.time()
                    print('epoch,batch = %2d %5d:   batch_size = %5d  loss = %4.3f\r'
                          % (epoch, batch_num, self.batch_size, loss.item()), end="\n")
                    batch_new = batch_num
                    start = time.time()
                batch_num += 1

        self.showPlot(loss_list, 'Losses')
        model.save_embeddings(self.data.idx2word, 'word_embdding.txt')

if __name__ == '__main__':

    fixed_seed = 1
    if fixed_seed is not None:
        torch.manual_seed(fixed_seed)
        random.seed(fixed_seed)
        np.random.seed(fixed_seed)
        torch.cuda.manual_seed(fixed_seed)

    # w2v = word2vec('text8', 'SkipGram')
    w2v = word2vec('toy', 'SkipGram', batch_size=1, epoch=10)
    # w2v = word2vec('democratic_cleaned_min.txt', 'SkipGram')
    w2v.train()


from Sample_Tests.quoraAutomation.Page_Objects.BaseClass import BasePage
from appium.webdriver.common.mobileby import By
import time
class Homepage(BasePage):

    homeButton=(By.XPATH,'//android.widget.RelativeLayout//android.widget.ImageView[@content-desc="Me"]')
    moreOptions=(By.XPATH,"//android.widget.Button[@text='More options']")
    logout_Option=(By.XPATH,"//android.widget.TextView[@text='Logout']")
    confirm_Logout=(By.XPATH,"//android.widget.Button[@text='Logout']")

    def navigate_To_Logout(self, ):
        time.sleep(10)
        self.driver.find_element(*Homepage.homeButton).click()
        self.driver.find_element(*Homepage.moreOptions).click()
        self.driver.find_element(*Homepage.logout_Option).click()

        return self.driver.find_element(*Homepage.confirm_Logout)


# the observed state of car as seen by drivers
from pygame.math import Vector2

from src.car_command import car_command
from src.my_logger import my_logger
logger = my_logger(__name__)
from src.globals import SCREEN_WIDTH_PIXELS, SCREEN_HEIGHT_PIXELS, M_PER_PIXEL

VERSION='1.0'

class car_state:
    """
    Complete state of car. Updated by hidden model based on control input.

    """

    def __init__(self, x=M_PER_PIXEL * 490, y=M_PER_PIXEL * 615, body_angle_deg=0.0, length_m=4.5, width_m=2.0, max_steering=40, max_acceleration=100.0): # TODO car dimensions are not part of dynamic state, fix
        # todo constructor should put car at starting line, not middle of screen
        # intrinsic state
        # Screen coordinate system is computer vision standard, 0,0 is UL corner and y increases *downwards*.
        # It causes some confusion about angles.
        # (x, y) = tuple starting coordinates in m

        self.time=0
        self.position_m = Vector2(x, y) # x increases to right, y increases downwards
        self.velocity_m_per_sec = Vector2(0.0, 0.0) # vx and vy, with y increasing downwards, i.e. vy>0 means car is moving down the screen
        self.speed_m_per_sec=0.0 # length of velocity vector
        self.accel_m_per_sec_2 = Vector2(0.0, 0.0) # ax and ay *in frame of car*, *along* car body, i.e. ax>0 means car accelerating forwards. ay>0 means rightward acceleration on car body.
        self.steering_angle_deg = 0.0 # degrees of front wheel steering, increases CW/right with zero straight ahead
        self.body_angle_deg = body_angle_deg # degrees, increases CW (on screen!) with zero pointing to right/east
        self.yaw_rate_deg_per_sec = 0.0 # degrees/sec, increases CW on screen
        self.drift_angle_deg=0.0 # drift angle, (beta) relative to heading direction. Zero for no drift. +-90 for drifting entirely sideways. + is drift to left,- to right. TODO check description correct
        self.length_m = length_m # length in meters
        self.width_m = width_m # width in meters

        # current commanded control input
        self.command = car_command()

        self.time_results = []

        # other car(s) # todo add structure to send other car states to client for rendering

        self.other_cars: list = None  # list of other car_state for other cars

        self.server_msg=None # message from server to be displayed to driver

    def reset(self):
        pass

    def __str__(self):
        s='{}\npos=({:4.1f},{:4.1f})m vel=({:5.1f},{:5.1f})m/s, speed={:6.2f}m/s accel={:6.2f}m/s^2\nsteering_angle={:4.1f}deg body_angle={:4.1f}deg\nyaw_rate={:4.1f}deg/s drift_angle={:4.1f}\nmsg: {}'\
            .format(str(self.command),
                    self.position_m.x,
                    self.position_m.y,
                    self.velocity_m_per_sec.x,
                    self.velocity_m_per_sec.y,
                    self.speed_m_per_sec,
                    self.accel_m_per_sec_2.length(),
                    self.steering_angle_deg,
                    self.body_angle_deg,
                    self.yaw_rate_deg_per_sec,
                    self.drift_angle_deg,
                    self.server_msg)
        return s

    def get_record_headers(self, car):
        import datetime, time, getpass
        header ='# recorded output from l2race\n# format version: {}\n'.format(VERSION)
        header+=datetime.datetime.now().strftime('# Creation_time="%I:%M%p %B %d %Y"\n')  # Tue Jan 26 13:57:06 CET 2016
        header+='# Creation_time="{}" (epoch ms)\n'.format(int(time.time() * 1000.))
        header+='# Username="{}"\n'.format(getpass.getuser())
        header+='# Car_name="{}"\n'.format(car.name)
        header+='# Track_name="{}"\n'.format(car.track.name)
        h=[
            'time',
            'cmd.auto',
            'cmd.steering',
            'cmd.throttle',
            'cmd.brake',
            'cmd.reverse',
            'pos.x',
            'pos.y',
            'vel.x',
            'vel.y',
            'speed',
            'accel.x',
            'accel.y',
            'steering_angle',
            'body_angle',
            'yaw_rate',
            'drift_angle',
            'length',
            'width',
        ]
        for i in h[:-1]:
            header=header+i+','
        header+=h[-1]
        return header

    def get_record_csvrow(self):
        l=[
            self.time,
            1 if self.command.auto else 0,
            self.command.steering,
            self.command.throttle,
            self.command.brake,
            1 if self.command.reverse else 0,
            self.position_m.x,
            self.position_m.y,
            self.velocity_m_per_sec.x,
            self.velocity_m_per_sec.y,
            self.speed_m_per_sec,
            self.accel_m_per_sec_2.x,
            self.accel_m_per_sec_2.y,
            self.steering_angle_deg,
            self.body_angle_deg,
            self.yaw_rate_deg_per_sec,
            self.drift_angle_deg,
            self.length_m,
            self.width_m,
        ]
        s=''
        for v in l[:-1]:
            s=s+('{},'.format(v))
        s=s+('{:f}'.format(l[-1]))
        return s


# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models, migrations
import django.contrib.gis.db.models.fields

class Migration(migrations.Migration):

    dependencies = [
        ('spatial', '0005_incident_import_source'),
    ]

    operations = [
        migrations.CreateModel(
            name='Subdivision',
            fields=[
                ('id', models.AutoField(auto_created=True, verbose_name='ID', primary_key=True, serialize=False)),
                ('polygon', django.contrib.gis.db.models.fields.PolygonField(srid=4326)),
                ('display_name', models.CharField(max_length=255)),
            ],
        ),
    ]


from github import Github
from themes.level_1.level1 import genHTMLLevel1
from themes.level_2.level2 import genHTMLLevel2
from functions.RepoToHTML import repotohtml
from functions.addSocialLinks import strtoLinksHTML
from distutils.util import strtobool
import sys
import os

git = Github(sys.argv[1])
theme_selected = sys.argv[2]
blogs = strtobool(sys.argv[3])
include_hackathon = strtobool(sys.argv[4])
stats_choice = sys.argv[5]
social_links = sys.argv[6]
resume_link = sys.argv[7]
allow_footer = bool(sys.argv[8])

start = git.rate_limiting[0]
print(f'Request left at start of the script: {start}')

user_object = git.get_user()
git_username = user_object.login
user_data = {'username': git_username,
             'git_photo_url': user_object.avatar_url,
             'git_bio': user_object.bio,
             'git_email': user_object.email,
             'git_followers': user_object.followers,
             'git_following': user_object.following,
             'name': user_object.name,
             'latest_updated': str(user_object.updated_at)}

repo_list = [repo.name for repo in git.get_user().get_repos()]
project_data = {}
hackathon_data = {}

if include_hackathon:
    for repo in repo_list:
        print(f'Repo being checked: {repo}')
        try:
            repo_object = git.get_repo(git_username + '/' + repo)
            repo_topics = repo_object.get_topics()
            if len(repo_topics) != 0:
                if 'project' in repo_topics:
                    project_data[f'{repo}'] = {'repo_topics': repo_topics,
                                               'repo_description': repo_object.description,
                                               'repo_stars': int(repo_object.stargazers_count),
                                               'repo_forks': int(repo_object.forks_count)}

                if 'hackathon' in repo_topics:
                    hackathon_data[f'{repo}'] = {'repo_topics': repo_topics,
                                                 'repo_description': repo_object.description,
                                                 'repo_stars': int(repo_object.stargazers_count),
                                                 'repo_forks': int(repo_object.forks_count)}

                else:
                    continue
            else:
                continue
        except:
            continue
else:
    for repo in repo_list:
        print(f'Repo being checked: {repo}')
        try:
            repo_object = git.get_repo(git_username + '/' + repo)
            repo_topics = repo_object.get_topics()
            if len(repo_topics) != 0:
                if 'project' in repo_topics:
                    project_data[f'{repo}'] = {'repo_topics': repo_topics,
                                               'repo_description': repo_object.description,
                                               'repo_stars': int(repo_object.stargazers_count),
                                               'repo_forks': int(repo_object.forks_count)}
                else:
                    continue
            else:
                continue
        except:
            continue

end = git.rate_limiting[0]
print(f'Request left at end of the script: {end}')
print(f'Requests Consumed in this process: {start - end}')

project_repos = repotohtml(project_data, git_username)
if include_hackathon:
    hackathon_repos = repotohtml(hackathon_data, git_username)
else:
    hackathon_repos = None

social_data = strtoLinksHTML(social_links, user_data['username'])

if theme_selected == '1':
    indexFile = genHTMLLevel1(
        user_data, project_repos, hackathon_repos, blogs, stats_choice, social_data, resume_link, allow_footer)

elif theme_selected == '2':
    indexFile = genHTMLLevel2(user_data, project_repos,
                              hackathon_repos, blogs, stats_choice, social_data, resume_link, allow_footer)

with open('index.html', 'w', encoding='utf-8') as f:
    f.write(indexFile)


import mrcnn_wrapper as mrcnn # this can take some time the first time, since its loading 2gb of data into the model
import myhelpers as mh
import matplotlib.pyplot as plt
import glob
import skimage.io
from skimage.segmentation import mark_boundaries

# %%
filelist = sorted(glob.glob('/home/filip/space-time-volumes/databases/jogger_midfoot/frames/*.jpg'))[0:2]
#filelist = sorted(glob.glob('/home/fil/uni/space-time-volumes/databases/runner/*.jpg'))

all_images = []

for tmp in filelist:
    all_images.append(skimage.io.imread(tmp))

# %%
n_segments = [150, 400, 4000]
compactness = [40, 40, 10]
sigmas = [8, 4, 0]
# %% compute image pyramid and slic pyramid
slic_pyramid, image_pyramid = mh.slic_pyramid(all_images, n_segments, compactness, sigmas)
# %% compute mrcnn
mrcnn_data = mh.mrcnn_batch_detect(all_images)
# %% load
mrcnn_data = mh.read_from_file("mrcnn_data.pickle")
slic_pyramid = mh.read_from_file("slic_pyramid.pickle")
image_pyramid = mh.read_from_file("image_pyramid.pickle")

# %% save
mh.write_to_file(mrcnn_data, "mrcnn_data.pickle")
mh.write_to_file(slic_pyramid, "slic_pyramid.pickle")
mh.write_to_file(image_pyramid, "image_pyramid.pickle")

# %% Plot images and mrccn mask[0]
for idx, img in all_images:
    plt.subplot(2,len(all_images),idx+1)
    plt.axis('off')
    plt.imshow(img)

    plt.subplot(2,len(filelist),(idx+1)+len(filelist))
    #                slice   feature   detected_obj
    #                  v      v         v
    mask = mrcnn_data[idx]['masks'][:,:,0]
    plt.axis('off')
    plt.imshow(mask, cmap="gray")

plt.show()

# %%

num_images = len(slic_pyramid[0])
num_levels = len(slic_pyramid)

for i, imagePath in enumerate(filelist):
    image = skimage.io.imread(imagePath)
    mask = mrcnn_data[i]['masks'][:,:,0]
    for lvl in range(1, 2):
        plt.subplot(num_levels,num_images, (i+1) + (num_images*lvl))
        lvl_segs = slic_pyramid[lvl][i]
        improved_mask = mh.estimate_mask_with_superpixel_segmentation(mask, lvl_segs, 0.9)
        plt.axis('off')

        plt.imshow(improved_mask, cmap="gray")
plt.show()

# %% plot slic pyramid
for idx, file in enumerate(filelist):
    image = skimage.io.imread(file)

    for j in range(0,len(slic_pyramid)):

        plt.subplot(len(slic_pyramid), len(filelist), (idx+1) + (len(filelist)*j))
        plt.axis("off")

        plt.title(" n_segs: " + str(n_segments[j]) +
                  " cmpct: " + str(compactness[j]) +
                  " sigma: " + str(sigmas[j]))

        plt.imshow(mark_boundaries(image_pyramid[j][idx][:,:], slic_pyramid[j][idx][:,:]))

# %% merging
from skimage import data, io, segmentation, color
from skimage.future import graph
import numpy as np
import matplotlib.pyplot as plt

def _weight_mean_color(graph, src, dst, n):
    """Callback to handle merging nodes by recomputing mean color.

    The method expects that the mean color of `dst` is already computed.

    Parameters
    ----------
    graph : RAG
        The graph under consideration.
    src, dst : int
        The vertices in `graph` to be merged.
    n : int
        A neighbor of `src` or `dst` or both.

    Returns
    -------
    data : dict
        A dictionary with the `"weight"` attribute set as the absolute
        difference of the mean color between node `dst` and `n`.
    """

    diff = graph.node[dst]['mean color'] - graph.node[n]['mean color']
    diff = np.linalg.norm(diff)
    return {'weight': diff}

def merge_mean_color(graph, src, dst):
    """Callback called before merging two nodes of a mean color distance graph.

    This method computes the mean color of `dst`.

    Parameters
    ----------
    graph : RAG
        The graph under consideration.
    src, dst : int
        The vertices in `graph` to be merged.
    """
    graph.node[dst]['total color'] += graph.node[src]['total color']
    graph.node[dst]['pixel count'] += graph.node[src]['pixel count']
    graph.node[dst]['mean color'] = (graph.node[dst]['total color'] /
                                     graph.node[dst]['pixel count'])

merged = []
for idx, img in enumerate(image_pyramid[2]):
    labels = slic_pyramid[2][idx]
    g = graph.rag_mean_color(img, labels)

    labels2 = graph.merge_hierarchical(labels, g, thresh=70, rag_copy=False,
                                   in_place_merge=True,
                                   merge_func=merge_mean_color,
                                   weight_func=_weight_mean_color)

    out = color.label2rgb(labels2, img)
    out = segmentation.mark_boundaries(out, labels2)
    merged.append(out)

for idx, image in enumerate(merged):
    plt.subplot(1,len(merged), idx+1)
    plt.imshow(image)


# coding: utf-8

# In[43]:

import os
import csv
from sklearn.utils import shuffle
from sklearn.model_selection import train_test_split
import cv2
import matplotlib.pyplot as plt
from keras.models import Sequential,  Model
from keras.layers.core import Dense, Flatten, Activation, Dropout, Lambda
from keras.layers.convolutional import Convolution2D, Cropping2D
import numpy as np
import pandas as pd
from scipy.misc import imread
import matplotlib.pyplot as plt
from math import *
import cv2
from keras.callbacks import ModelCheckpoint

from sklearn.model_selection import train_test_split
get_ipython().magic('matplotlib inline')

print('All Packages Loaded')

# In[44]:

x = pd.read_csv('/home/carnd/test/data/driving_log.csv')
print("All Data Loaded")

# In[45]:

x.steering.plot(title='Steering data distribution', fontsize=17, figsize=(10,4), color= 'y')
plt.xlabel('frames')
plt.ylabel('Steering angle')
plt.show()

# In[46]:

x.throttle.plot(title='Throttle data distribution', fontsize=17, figsize=(10,4), color= 'b')
plt.xlabel('frames')
plt.ylabel('Throttle')
plt.show()

# In[47]:

x.brake.plot(title='Brake data distribution', fontsize=17, figsize=(10,4), color= 'k')
plt.xlabel('frames')
plt.ylabel('Brake')
plt.show()

# In[48]:

x.speed.plot(title='Speed data distribution', fontsize=17, figsize=(10,4), color= 'm')
plt.xlabel('frames')
plt.ylabel('Speed')
plt.show()

# In[49]:

samples = []

with open('/home/carnd/test/data/driving_log.csv') as csvfile:
    reader = csv.reader(csvfile)
    next(reader, None)
    for line in reader:
        samples.append(line)

# In[50]:

train_samples, validation_samples = train_test_split(samples,test_size=0.15) #simply splitting the dataset to train and validation set usking sklearn. .15 indicates 15% of the dataset is validation set

# In[51]:

def generator(samples, batch_size=32):
    num_samples = len(samples)

    while 1:
        shuffle(samples)
        for offset in range(0, num_samples, batch_size):

            batch_samples = samples[offset:offset+batch_size]

            images = []
            angles = []
            for batch_sample in batch_samples:
                    for i in range(0,3):

                        name = './data/IMG/'+batch_sample[i].split('/')[-1]
                        center_image = cv2.cvtColor(cv2.imread(name), cv2.COLOR_BGR2RGB)
                        center_angle = float(batch_sample[3])
                        images.append(center_image)

                        if(i==0):
                            angles.append(center_angle)
                        elif(i==1):
                            angles.append(center_angle+0.2)
                        elif(i==2):
                            angles.append(center_angle-0.2)

                        images.append(cv2.flip(center_image,1))
                        if(i==0):
                            angles.append(center_angle*-1)
                        elif(i==1):
                            angles.append((center_angle+0.2)*-1)
                        elif(i==2):
                            angles.append((center_angle-0.2)*-1)

            X_train = np.array(images)
            y_train = np.array(angles)

            yield sklearn.utils.shuffle(X_train, y_train)

# In[52]:

train_generator = generator(train_samples, batch_size=32)
validation_generator = generator(validation_samples, batch_size=32)

# ## Type of Problem : Regression
# ### Problem Statement: Find the Steering angle, given images from three cameras, i.e Left, Centre and Right.
#
# ##### Checklist for creating the pipeline of the NVIDIA model : https://tinyurl.com/y88xelpb
# 1. Preprocess incoming data, centered around zero with small standard deviation
# 2. Trim image the to train the network on the basis of the road and the steering angle only.
# 3. Layer 1 : Convolution Layer, Number of Filters : 24, Filter size= 5x5,  stride= 2x2.
# 4. Layer 2 : Convolution Layer, Number of Filters : 36, Filter Size = 5x5, stride = 2x2.
# 5. Layer 3 : Convolution Layer, Number of Filters : 48, Filter Size = 5x5, stride = 2x2.
# 6. Layer 4 : Convolution Layer, Number of Filters : 64, Filter Size = 3x3, stride = 1x1.
# 7. Layer 5 : Convolution Layer, Number of Filters : 64, Filter Size = 3x3, stride = 1x1.
# 8. Flatten the Image from a 2D format to a row based array.
# 9. Layer 6 : Fully Connected Layer
# 10. A dropout layer to avoid overfitting.
# 11. Layer 7 : Fully Connected Layer
# 12. Layer 8 : Fully Connected Layer

# In[53]:

model = Sequential()
model.add(Lambda(lambda x: x/127.5 - 1., input_shape=(160,320, 3), name='Normalization'))
model.add(Cropping2D(cropping=((60, 25),(0,0))))
model.add(Convolution2D(24, 5, 5, subsample=(2,2), activation='elu', name='Conv1'))
model.add(Convolution2D(36, 5, 5, subsample=(2,2), activation='elu', name='Conv2'))
model.add(Convolution2D(48, 5, 5, subsample=(2,2), activation='elu', name='Conv3'))
model.add(Convolution2D(64, 3, 3, activation='relu', name='Conv4'))
model.add(Convolution2D(64, 3, 3, activation='relu', name='Conv5'))
model.add(Flatten())
model.add(Dense(50, activation='elu', name='FC1'))
model.add(Dense(10, activation='elu', name='FC2'))
model.add(Dense(1, name='output'))
model.summary()

# In[54]:

class LossHistory(keras.callbacks.Callback):
    def on_train_begin(self, logs={}):
        print('BEGIN TRAINING')
        self.losses = []

    def on_batch_end(self, batch, logs={}):
        self.losses.append(logs.get('loss'))

# In[55]:

checkpoint = ModelCheckpoint('model-{epoch:03d}.h5',
                                 monitor='val_loss',
                                 verbose=0,
                                 save_best_only=True,
                                 mode='auto')

# In[56]:

batch_history = LossHistory()

# In[57]:

Early_Stopping=keras.callbacks.EarlyStopping(monitor='val_loss', min_delta=0, patience=0, verbose=0, mode='auto')

# In[58]:

Tensor_Board = keras.callbacks.TensorBoard(log_dir='./logs', histogram_freq=0, write_graph=True, write_images=False)

# In[59]:

model.compile(loss='mse',optimizer='adam')
plot_model = model.fit_generator(train_generator, samples_per_epoch= len(train_samples), validation_data=validation_generator,callbacks = [batch_history, Tensor_Board ],nb_val_samples=len(validation_samples), nb_epoch=5,verbose=1)
model.save('model_test_1.h5')
print('Hurray! The Model has been Saved!')

# In[60]:

def running_mean(x, N):
    cumsum = np.cumsum(np.insert(x, 0, 0))
    return (cumsum[N:] - cumsum[:-N]) / N

def plot_history(history):
    plt.plot(running_mean(history.losses, 50))
    plt.ylim(0, 0.06)
    plt.title('model loss')
    plt.ylabel('loss')
    plt.xlabel('batches')
    plt.show()

plot_history(batch_history)

# In[61]:

plt.plot(plot_model.history['loss'])
plt.plot(plot_model.history['val_loss'])
plt.title('model mean squared error loss')
plt.ylabel('mean squared error loss')
plt.xlabel('epoch')
plt.legend(['training set', 'validation set'], loc='upper right')
plt.show()

# In[ ]:


import unittest
from appium import webdriver
from Sample_Tests.quoraAutomation.Page_Objects.LoginPage import LoginPage
from Sample_Tests.quoraAutomation.Page_Objects.Homepage import Homepage
from Sample_Tests.quoraAutomation.Page_Objects.ShellStartRecord import ShellStartRecord
from Sample_Tests.quoraAutomation.Page_Objects.ShellStopRecord import ShellStopRecord

import time

class LoginLogout(unittest.TestCase):

    def setUp(self):
        self.driver = webdriver.Remote(command_executor='http://127.0.0.1:4723/wd/hub',
                                       desired_capabilities=
                                           {
                                               "platformName": "Android",
                                               "platformVersion": "6.0.1",
                                               "deviceName": "android",
                                               "appPackage": "com.quora.android",
                                               "appActivity": "com.quora.android.components.activities.LauncherActivity",
                                               "udid": "320849220ee571bd",
                                               "newCommandTimeout":"70"
                                           }
                                       )
        self.driver.implicitly_wait(50)
        ShellStartRecord(self.driver).record()

        #self.driver.start_recording_screen()

    def test_main(self):

        credentialsPage= LoginPage(self.driver).logging()

        credentialsPage.enterEmail().send_keys('lodestoneq@gmail.com')
        credentialsPage.enterPassword().send_keys('Asdf#123')
        credentialsPage.clicikngDone().click()

        logout_Btn= Homepage(self.driver).navigate_To_Logout()
        logout_Btn.click()
        time.sleep(3)

    def tearDown(self):
       #screenRecord(self.driver).record()
       ShellStopRecord(self.driver).stop()
       self.driver.quit()

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


from builtins import str
from builtins import object
import pytest
from chispa.dataframe_comparer import assert_df_equality
from pyspark.sql import types as sql_types
from pyspark.sql import functions as F
from pyspark.sql import Row
import datetime as dt

from spooq2.transformer import ThresholdCleaner

class TestBasicAttributes(object):
    """ Basic attributes of the transformer instance """

    def test_has_logger(self):
        assert hasattr(ThresholdCleaner(), "logger")

    def test_has_name(self):
        assert ThresholdCleaner().name == "ThresholdCleaner"

    def test_has_str_representation(self):
        assert str(ThresholdCleaner()) == "Transformer Object of Class ThresholdCleaner"

class TestCleaning(object):

    # fmt: off
    @pytest.fixture(scope="module")
    def input_df(self, spark_session):
        input_data = [
            #ids  #floats   #integers  #strings         #timestamps           #datetimes
            [0,       12.0,      12,      "12",  dt.datetime(1850,1,1, 12,0,0), dt.date(1850,1,1)],
            [1,       65.7,      65,      "65",  dt.datetime(2020,6,1, 12,0,0), dt.date(2020,6,1)],
            [2,      300.0,     300,     "300",  dt.datetime(2020,6,1, 15,0,0), dt.date(2020,6,15)],
            [4,     5000.0,    5000,    "5000",  dt.datetime(2020,6,1, 16,0,0), dt.date(2020,7,1)],
            [5,      -75.0,     -75,     "-75",  dt.datetime(9999,1,1, 12,0,0), dt.date(9999,1,1)],
        ]
        schema = sql_types.StructType(
            [
                sql_types.StructField("id",         sql_types.IntegerType(),   True),
                sql_types.StructField("floats",     sql_types.DoubleType(),    False),
                sql_types.StructField("integers",   sql_types.LongType(),      False),
                sql_types.StructField("strings",    sql_types.StringType(),    False),
                sql_types.StructField("timestamps", sql_types.TimestampType(), False),
                sql_types.StructField("datetimes",  sql_types.DateType(),      False),
            ]
        )
        return spark_session.createDataFrame(input_data, schema=schema)

    @pytest.fixture(scope="module")
    def thresholds(self):
        return {
            "integers":   {"min":  1,                           "max":  300},
            "floats":     {"min":  1.0,                         "max":  300.0},
            "strings":    {"min": "1",                          "max": "300"},
            "timestamps": {"min": dt.datetime(2020,6,1,12,0,0), "max": dt.datetime(2020,6,1,16,0,0)},
            "datetimes":  {"min": dt.date(2020,6,1),            "max": "2020-7-1"},
        }

    @pytest.fixture(scope="module")
    def expected_result(self):
        return {
            "integers":   [ 12,    65,    300,   None, None],
            "floats":     [ 12.0,  65.7,  300.0, None, None],
            "strings":    ["12",  "65",  "300",  None, None],
            "timestamps": [None, dt.datetime(2020,6,1, 12,0,0), dt.datetime(2020,6,1, 15,0,0),
                           dt.datetime(2020,6,1, 16,0,0), None],
            "datetimes":  [None, dt.date(2020,6,1), dt.date(2020,6,15), dt.date(2020,7,1), None],
        }
    # fmt: on

    @pytest.mark.parametrize("column_name", ["integers", "floats", "timestamps", "datetimes"])
    def test_clean_supported_format(self, column_name, input_df, thresholds, expected_result):
        thresholds_to_test = {column_name: thresholds[column_name]}
        transformer = ThresholdCleaner(thresholds=thresholds_to_test)
        df_cleaned = transformer.transform(input_df)
        result = [x[column_name] for x in df_cleaned.collect()]
        expected = expected_result[column_name]

        assert result == expected
        assert input_df.columns == df_cleaned.columns

    @pytest.mark.parametrize("column_name", ["strings"])
    def test_raise_exception_for_unsupported_format(self, column_name, input_df, thresholds):
        thresholds_to_test = dict([k_v1 for k_v1 in list(thresholds.items()) if k_v1[0] == column_name])
        transformer = ThresholdCleaner(thresholds_to_test)

        with pytest.raises(ValueError):
            transformer.transform(input_df).count()

    def test_dynamic_default_value(self, spark_session):
        input_df = spark_session.createDataFrame([
            Row(id=1, num=1),
            Row(id=2, num=2),
            Row(id=3, num=100),
            Row(id=4, num=4),
            Row(id=5, num=-1024),
        ])
        thresholds_to_test = dict(num=dict(min=0, max=99, default=F.col("id") * -1))
        output_df = ThresholdCleaner(thresholds_to_test).transform(input_df)
        expected_output_df = spark_session.createDataFrame([
            Row(id=1, num=1),
            Row(id=2, num=2),
            Row(id=3, num=-3),
            Row(id=4, num=4),
            Row(id=5, num=-5),
        ])
        assert_df_equality(expected_output_df, output_df)


#!/usr/bin/env python
"""
MCC 118 example program

Read channels 0 and 1 every 5 minutes and send an IFTTT event for logging to a
Google sheets spreadsheet. This uses the IFTTT Webhooks channel for inputs.
You create your own event and enter the name here for event_name (we used
voltage_data for the name), then choose an activity to occur when the event
happens. We used the Google Sheets activity and selected "add a row to a
spreadsheet", then set it up to log the time and voltages (Value0 and Value1).

1. Sign in to your account at [https://ifttt.com](https://ifttt.com), select
"My Applets", and click the "New Applet" button.
2. Click "this" then search for Webhooks. Click the Webhooks icon when found.
3. On the "Choose trigger" screen, click "Receive a web request".
4. On the "Complete trigger fields" screen, enter an event name ("voltage_data"
for this example) and click the "Create trigger" button.
5. Click "that", then search for "Google Sheets" on the "Choose action service"
screen and select the "Google Sheets" icon when found.
6. On the "Choose action" screen, select "Add row to spreadsheet".
7. On the "Complete action fields" screen, enter a spreadsheet name, modify the
"Formatted row" field so it contains "{{OccurredAt}} ||| {{Value1}} ||| {{Value2}}"
(without quotes). Change the Google Drive folder path if desired, then
click the "Create action" button.
8. Review the summary statement, then click the **Finish** button.

Enter your key from IFTTT Webhooks documentation for the variable "key". You
can find this key by:

1. At IFTTT.com go to My Applets, then click the Services heading.
2. Enter Webhooks in the Filter services field, then click on Webhooks.
3. Click on Documentation. Your key will be listed at the top; copy that key
and paste it inside the quotes below, replacing <my_key>.
"""
from __future__ import print_function
import time
import sys
import daqhats as hats
import requests

# IFTTT values
EVENT_NAME = "voltage_data"
KEY = "<my_key>"

def send_trigger(event, value1="", value2="", value3=""):
    """ Send the IFTTT trigger. """
    report = {}
    report['value1'] = str(value1)
    report['value2'] = str(value2)
    report['value3'] = str(value3)
    requests.post("https://maker.ifttt.com/trigger/" + event + "/with/key/" +
                  KEY, data=report)

def main():
    """ Main function """
    log_period = 5*60

    if KEY == "<my_key>":
        print("The default key must be changed to the user's personal IFTTT "
              "Webhooks key before using this example.")
        sys.exit()

    # Find the first MCC 118
    mylist = hats.hat_list(filter_by_id=hats.HatIDs.MCC_118)
    if not mylist:
        print("No MCC 118 boards found")
        sys.exit()

    board = hats.mcc118(mylist[0].address)

    while True:
        # read the voltages
        value_0 = board.a_in_read(0)
        value_1 = board.a_in_read(1)

        send_trigger(EVENT_NAME, "{:.3f}".format(value_0),
                     "{:.3f}".format(value_1))
        print("Sent data {0:.3f}, {1:.3f}.".format(value_0, value_1))
        time.sleep(log_period)

if __name__ == '__main__':
    main()


from collections import defaultdict
from pathlib import Path

import numpy as np
import torch.utils.data as torch_data

from ..utils import common_utils
from .augmentor.data_augmentor import DataAugmentor
from .processor.data_processor import DataProcessor
from .processor.point_feature_encoder import PointFeatureEncoder

class DatasetTemplate(torch_data.Dataset):
    def __init__(self, dataset_cfg=None, class_names=None, training=True, root_path=None, logger=None):
        super().__init__()
        self.dataset_cfg = dataset_cfg
        self.training = training
        self.class_names = class_names
        self.logger = logger
        self.root_path = root_path if root_path is not None else Path(self.dataset_cfg.DATA_PATH)
        self.logger = logger
        if self.dataset_cfg is None or class_names is None:
            return

        self.point_cloud_range = np.array(self.dataset_cfg.POINT_CLOUD_RANGE, dtype=np.float32)
        self.point_feature_encoder = PointFeatureEncoder(
            self.dataset_cfg.POINT_FEATURE_ENCODING,
            point_cloud_range=self.point_cloud_range
        )
        self.data_augmentor = DataAugmentor(
            self.root_path, self.dataset_cfg.DATA_AUGMENTOR, self.class_names, logger=self.logger
        ) if self.training else None
        self.data_processor = DataProcessor(
            self.dataset_cfg.DATA_PROCESSOR, point_cloud_range=self.point_cloud_range,
            training=self.training, num_point_features=self.point_feature_encoder.num_point_features
        )

        self.grid_size = self.data_processor.grid_size
        self.voxel_size = self.data_processor.voxel_size
        self.total_epochs = 0
        self._merge_all_iters_to_one_epoch = False

        if hasattr(self.data_processor, "depth_downsample_factor"):
            self.depth_downsample_factor = self.data_processor.depth_downsample_factor
        else:
            self.depth_downsample_factor = None

    @property
    def mode(self):
        return 'train' if self.training else 'test'

    def __getstate__(self):
        d = dict(self.__dict__)
        del d['logger']
        return d

    def __setstate__(self, d):
        self.__dict__.update(d)

    @staticmethod
    def generate_prediction_dicts(batch_dict, pred_dicts, class_names, output_path=None):
        """
        To support a custom dataset, implement this function to receive the predicted results from the model, and then
        transform the unified normative coordinate to your required coordinate, and optionally save them to disk.

        Args:
            batch_dict: dict of original data from the dataloader
            pred_dicts: dict of predicted results from the model
                pred_boxes: (N, 7), Tensor
                pred_scores: (N), Tensor
                pred_labels: (N), Tensor
            class_names:
            output_path: if it is not None, save the results to this path
        Returns:

        """

    def merge_all_iters_to_one_epoch(self, merge=True, epochs=None):
        if merge:
            self._merge_all_iters_to_one_epoch = True
            self.total_epochs = epochs
        else:
            self._merge_all_iters_to_one_epoch = False

    def __len__(self):
        raise NotImplementedError

    def __getitem__(self, index):
        """
        To support a custom dataset, implement this function to load the raw data (and labels), then transform them to
        the unified normative coordinate and call the function self.prepare_data() to process the data and send them
        to the model.

        Args:
            index:

        Returns:

        """
        raise NotImplementedError

    def prepare_data(self, data_dict):
        """
        Args:
            data_dict:
                points: optional, (N, 3 + C_in)
                gt_boxes: optional, (N, 7 + C) [x, y, z, dx, dy, dz, heading, ...]
                gt_names: optional, (N), string
                ...

        Returns:
            data_dict:
                frame_id: string
                points: (N, 3 + C_in)
                gt_boxes: optional, (N, 7 + C) [x, y, z, dx, dy, dz, heading, ...]
                gt_names: optional, (N), string
                use_lead_xyz: bool
                voxels: optional (num_voxels, max_points_per_voxel, 3 + C)
                voxel_coords: optional (num_voxels, 3)
                voxel_num_points: optional (num_voxels)
                ...
        """
        if self.training:
            assert 'gt_boxes' in data_dict, 'gt_boxes should be provided for training'
            gt_boxes_mask = np.array([n in self.class_names for n in data_dict['gt_names']], dtype=np.bool_)

            data_dict = self.data_augmentor.forward(
                data_dict={
                    **data_dict,
                    'gt_boxes_mask': gt_boxes_mask
                }
            )

        if data_dict.get('gt_boxes', None) is not None:
            selected = common_utils.keep_arrays_by_name(data_dict['gt_names'], self.class_names)
            data_dict['gt_boxes'] = data_dict['gt_boxes'][selected]
            data_dict['gt_names'] = data_dict['gt_names'][selected]
            gt_classes = np.array([self.class_names.index(n) + 1 for n in data_dict['gt_names']], dtype=np.int32)
            gt_boxes = np.concatenate((data_dict['gt_boxes'], gt_classes.reshape(-1, 1).astype(np.float32)), axis=1)
            data_dict['gt_boxes'] = gt_boxes

            if data_dict.get('gt_boxes2d', None) is not None:
                data_dict['gt_boxes2d'] = data_dict['gt_boxes2d'][selected]

        if data_dict.get('points', None) is not None:
            data_dict = self.point_feature_encoder.forward(data_dict)

        data_dict = self.data_processor.forward(
            data_dict=data_dict
        )

        if self.training and len(data_dict['gt_boxes']) == 0:
            new_index = np.random.randint(self.__len__())
            return self.__getitem__(new_index)

        data_dict.pop('gt_names', None)

        return data_dict

    @staticmethod
    def collate_batch(batch_list, _unused=False,
                      accumulated_step=1):
        data_dict = defaultdict(list)
        for cur_sample in batch_list:
            for key, val in cur_sample.items():
                data_dict[key].append(val)
        batch_size = len(batch_list)

        ret_list = []
        assert batch_size % accumulated_step == 0, 'batch size must be divisible by accumulated_step'
        accumulated_interval = batch_size // accumulated_step
        for step in range(accumulated_step):
            ret = dict()
            start_idx = step * accumulated_interval
            end_idx = (step + 1) * accumulated_interval
            for key, val in data_dict.items():
                val = val[start_idx:end_idx]
                try:
                    if key in ['voxels', 'voxel_num_points']:
                        ret[key] = np.concatenate(val, axis=0)
                    elif key in ['points', 'voxel_coords']:
                        coors = []
                        for i, coor in enumerate(val):
                            coor_pad = np.pad(coor, ((0, 0), (1, 0)), mode='constant', constant_values=i)
                            coors.append(coor_pad)
                        ret[key] = np.concatenate(coors, axis=0)
                    elif key in ['gt_boxes']:
                        max_gt = max([len(x) for x in val])
                        batch_gt_boxes3d = np.zeros((accumulated_interval, max_gt, val[0].shape[-1]), dtype=np.float32)
                        for k in range(accumulated_interval):
                            batch_gt_boxes3d[k, :val[k].__len__(), :] = val[k]
                        ret[key] = batch_gt_boxes3d
                    elif key in ['gt_boxes2d']:
                        max_boxes = max([len(x) for x in val])
                        batch_boxes2d = np.zeros((accumulated_interval, max_boxes, val[0].shape[-1]), dtype=np.float32)
                        for k in range(accumulated_interval):
                            if val[k].size > 0:
                                batch_boxes2d[k, :val[k].__len__(), :] = val[k]
                        ret[key] = batch_boxes2d
                    elif key in ["images", "depth_maps"]:
                        # Get largest image size (H, W)
                        max_h = 0
                        max_w = 0
                        for image in val:
                            max_h = max(max_h, image.shape[0])
                            max_w = max(max_w, image.shape[1])

                        # Change size of images
                        images = []
                        for image in val:
                            pad_h = common_utils.get_pad_params(desired_size=max_h, cur_size=image.shape[0])
                            pad_w = common_utils.get_pad_params(desired_size=max_w, cur_size=image.shape[1])
                            pad_width = (pad_h, pad_w)
                            # Pad with nan, to be replaced later in the pipeline.
                            pad_value = np.nan

                            if key == "images":
                                pad_width = (pad_h, pad_w, (0, 0))
                            elif key == "depth_maps":
                                pad_width = (pad_h, pad_w)

                            image_pad = np.pad(image,
                                               pad_width=pad_width,
                                               mode='constant',
                                               constant_values=pad_value)

                            images.append(image_pad)
                        ret[key] = np.stack(images, axis=0)
                    else:
                        ret[key] = np.stack(val, axis=0)
                except:
                    print('Error in collate_batch: key=%s' % key)
                    raise TypeError

            ret['batch_size'] = accumulated_interval
            ret_list.append(ret)
        return ret_list


import immlib
from collections import defaultdict

imm = immlib.Debugger()

'''
   initStatsKey()
           Value of the address that is added to the stats dictionary is a list.
           The list needs to be initialized so that it contains two int that is zero
'''
def initStatsKey(stats, oldValue):
    stats[oldValue].append(0)
    stats[oldValue].append(0)

'''
   initFuncCount()
           Value of the address that is added to the funcCount dictionary is a list.
           The list needs to be initialized so that it contains two int that is zero
'''
def initFuncCount(funcCount, funcAddr):
    funcCount[funcAddr].append(0)
    funcCount[funcAddr].append(0)

'''
   statsForAddr()
           Write to the file the statistic for a particular address
'''
def statsForAddr(statsFile, stats, key):
    #stats is a dictionary.
    #Key: address. Value: a list with two element.
    #First element contains amount of time it is true.
    #Second element contains amount of time it is false.
    statsFile.write(str(key)) #Address
    statsFile.write("\t\t")
    trueP = str((float(stats[key][0])/(stats[key][0]+stats[key][1]))*100)
    statsFile.write(trueP.split(".")[0]+"."+trueP.split(".")[1][0]) #Percentage of times it is true
    statsFile.write("\t\t")
    falseP = str((float(stats[key][1])/(stats[key][0]+stats[key][1]))*100)
    statsFile.write(falseP.split(".")[0]+"."+falseP.split(".")[1][0])#Percentage of times it is false
    statsFile.write("\n")

'''
   writeStatsHeader()
           The header for the file statsFile
'''
def writeStatsHeader(statsFile):
    statsFile.write("Branch Address")
    statsFile.write("\t")
    statsFile.write("Percent True")
    statsFile.write("\t")
    statsFile.write("Percent False")
    statsFile.write("\n")

'''
   statfForFunc()
           Write to the file the statistic for a particular address
'''
def statfForFunc(statfFile, funcCount, key):
    #stats is a dictionary.
    #Key: address. Value: a list with two element.
    #First element contains count of how many times user function is called.
    statfFile.write(str(key)) #Address
    statfFile.write("\t\t")
    statfFile.write(str(funcCount[key][0])) #Count
    statfFile.write("\n")

'''
   writeStatfHeader()
           The header for the file statfFile
'''
def writeStatfHeader(statfFile):
    statfFile.write("Function Address")
    statfFile.write("\t")
    statfFile.write("Count")
    statfFile.write("\n")

'''
   findEndAddr()
           Find the end address of program, 'cexit'
'''
def findEndAddr(imm, address):
    while(1) :
        opcode = imm.disasm(address)
        opcode_str = opcode.getDisasm().lower()

        if "cexit" in opcode_str:
            endAddr = address
            address -= 1
            break
        else :
            address += opcode.getOpSize()
    return address

'''
   findStartAddr()
           Find the start address of main function
'''
def findStartAddr(imm, base, address):
    while(address > base):
        opcode = imm.disasm(address)
        opcode_str = opcode.getDisasm().lower()

        if "call" in opcode_str:
            #callmain = address
            startAddr = int(opcode_str.split(".")[1], 16)
            break
        else:
            address -= 1
    address = imm.getCurrentAddress()
    imm.run()
    imm.run(startAddr)
    return startAddr

'''
   traceAddr()
           Trace the address line-by-line and search all of branch & CALL instruction
           1. Branch
               Compare current address and next address.
               Next, set the value whether it is true or false and write file
           2.  CALL
               Find the start address of function and write file
'''
def traceAddr(imm, address, endAddr, stats, oldValue, rawFile, funcFile, funcCount):
    prefixCall = 0
    CBIflag = 0
    stepAddr = 0
    nextAddr = 0
    while(address != endAddr):
        #Finish searching
        if(address == endAddr):
             imm.quitDebugger()

        opcode = imm.disasm(address)
        opcode_str = opcode.getDisasm().lower()
        #If PC points CALL instruction, get the start address of function
        if "call" in opcode_str:
            #Ignore superprefix section
            if(prefixCall == 0):
                name = opcode_str.split(".")[0].lower()
                prefixCall = 1
            elif name in opcode_str:
                calledAddr = opcode_str.split(".")[1].upper()
                funcFile.write(calledAddr)
                funcFile.write("\n")
                if calledAddr not in funcCount:
                    initFuncCount(funcCount, calledAddr)
                funcCount[calledAddr][0]+=1
                imm.stepIn(endAddr)
                address = imm.getCurrentAddress()

        #Ignore JMP instruction
        elif "jmp" in opcode_str:
             address = int(opcode_str.split(".")[1], 16)

        #Searching all control branch instruction
        elif ("cmp" in opcode_str) or ("test" in opcode_str):
             imm.stepOver(endAddr)
             address = imm.getCurrentAddress()
             opcode = imm.disasm(address)
             opcode_str = opcode.getDisasm()
             instruct = opcode_str.split(" ")[0]
            #If PC points to branch instruction, compare current address and next address
             if "J" in instruct:
                  stepAddr = int(opcode_str.split(".")[1], 16)
                  nextAddr = address + opcode.getOpSize()
                  CBIflag = 1
        prevAddr = address
        imm.stepOver(endAddr)
        address = imm.getCurrentAddress()

        #Determine the branch's value whether is true or false
        if(CBIflag):
             CBIflag = 0
             oldValue=hex(prevAddr).upper()
             initStatsKey(stats, oldValue)
             if(address == stepAddr):
                 rawFile.write(hex(prevAddr).upper()+":True \n")
                 stats[oldValue][0]+=1
             elif(address == nextAddr):
                 rawFile.write(hex(prevAddr).upper()+":False \n")
                 stats[oldValue][1]+=1

'''
    main()

        Step1. Using our function 'findEndAddr()' to search 'cexit' instruction.
        Step2. Using our function 'findStartAddr()' to search the begginning of the main function in executable file and run to start address.
        Step3. Using 'stepOver()' or 'stepIn()' function from start address to find conditional branch and function call instruction.
            - If we find the conditional branch instruction, check and write the value of branch instruction in file which name is 'rawFile'
              and go to next instruction by using the 'stepOver()' function.
            - If we find the function call instruction, count and write ,that how many times of function call, in file which name is 'funcFile'
              and go to next instruction by using the 'stepIn()' function.
            - Iterating this step from start address to end address.
        Step4. Creating the statistics file by using the function 'writeStatsHeader()' and 'writeStatfHeader()'.
        Step5. Closing all files and we create four files 'funcFile', 'rawFile', 'statsFile' and 'statfFile'.

        Note: The 'jmp' instruction is an unconditional jump, so we ignore that instruction in step3.

        Key Assumptions:

            Superfluous prefix appear just one time ,so all call instructions after that mean function calls.
            'Cmp' or 'test' instructions are always in front of conditional branch instructions.
            The command should be started before run state in immunity debugger.
'''
def main(args):

    #Initializing variables

    # rawFile =  controlbranch addr : boolean
    # funcFile = functionaddr
    # statsFile = percentage of true at each control branch
    # statfFile = count how many times local function is called
    rawFile = open('data.txt', 'a')
    funcFile = open('func.txt', 'a')
    statsFile = open('stats.txt', 'a')
    statfFile = open('statf.txt', 'a')
    files = [rawFile, funcFile, statsFile, statfFile]
    oldValue = ""
    funcAddr = ""
    stats = defaultdict(list)
    funcCount = defaultdict(list)
    name=imm.getDebuggedName()
    module=imm.getModule(name)
    address=module.getBaseAddress()
    base = address

    #Step 1 -- Find 'cexit' address
    address = findEndAddr(imm, address)
    endAddr = address - 1

    #Step 2 -- Find start address of main
    address = findStartAddr(imm, base, address)

    #Step 3 -- Get the branch execution and function call results
    traceAddr(imm, address, endAddr, stats, oldValue, rawFile, funcFile, funcCount)

    #Step 4 -- Create the statistics file
    writeStatsHeader(statsFile)
    writeStatfHeader(statfFile)
    for key in stats:
        statsForAddr(statsFile, stats, key)
    for key in funcCount:
        statfForFunc(statfFile, funcCount, key)
    #Close all files
    for f in files:
        f.close()

    return "Search completed!"


from tools.multireplace import MultiReplace
import logging

class Cleanup(object):
    def __new__(cls, data):
        """
        Strips given data.
        :param data: string
        :return: string
        """
        try:
            if data is not None:
                data = MultiReplace(str(data), {u'\xa0': u'', '\n': '', '  ': '', '\t': ''})
            else:
                data = ""
        except Exception as error:
            logging.warning("CLEANUP FOUT: data: " + str(data) + ". Error: {0}".format(error))

        return data


from pyswmm import Simulation, Nodes, Links
import numpy as np
from scipy.integrate import ode

class waterQuality:
    """Water quality module for SWMM

    This class provides all the necessary code to run StormReactor's
    water quality module with a SWMM simulation.

    Attributes
    __________
    config : dict
        dictionary with node/links where water quality methods are to
        be simulated, the pollutants to simulate, the pollutant water
        quality method to simulate, and the method's parameters.

        example:
        config = {
            '11': {'pollutant': 0, 'method': 'EventMeanConc', 'parameters': {"C": 10}}, \
            '5': {'pollutant': 0, 'method': 'EventMeanConc', 'parameters': {"C": 10}}, \
            'Link1': {'pollutant': 0, 'method': 'EventMeanConc', 'parameters': {"C": 10}},
            'Link2': {'pollutant': 0, 'method': 'EventMeanConc', 'parameters': {"C": 10}}
            }

    Methods
    _______
    updateWQState
        Updates the pollutant concentration during a SWMM simulation for
        all methods except CSTR.

    updateCSTRWQState
        Updates the pollutant concentration during a SWMM simulation for
        a CSTR.
    """

    # Initialize class
    def __init__(self, sim, config):
        self.sim = sim
        self.config = config
        self.flag = 0
        self.start_time = self.sim.start_time
        self.last_timestep = self.start_time
        self.solver = ode(self._CSTR_tank)

        # Water quality methods
        self.method = {
            "EventMeanConc": self._EventMeanConc,
            "ConstantRemoval": self._ConstantRemoval,
            "CoRemoval": self._CoRemoval,
            "ConcDependRemoval": self._ConcDependRemoval,
            "NthOrderReaction": self._NthOrderReaction,
            "kCModel": self._kCModel,
            "GravitySettling": self._GravitySettling,
            "Erosion": self._Erosion,
            "CSTR": self._CSTRSolver,
            "Phosphorus": self._Phosphorus,
            }

    def updateWQState(self):
        """
        Runs the selected water quality method (except CSTR) and updates
        the pollutant concentration during a SWMM simulation.
        """

        nodes = Nodes(self.sim)
        links = Links(self.sim)

        for asset_ID, asset_info in self.config.items():
            for node in nodes:
                attribute =self.config[asset_ID]['method']

                if node.nodeid == asset_ID:
                    self.flag = 0
                    self.method[attribute](asset_ID, \
                            self.config[asset_ID]['pollutant'], \
                            self.config[asset_ID]['parameters'], self.flag)

            for link in links:
                attribute =self.config[asset_ID]['method']

                if link.linkid == asset_ID:
                    self.flag = 1
                    self.method[attribute](asset_ID, \
                            self.config[asset_ID]['pollutant'], \
                            self.config[asset_ID]['parameters'], self.flag)

    def updateWQState_CSTR(self, index):
        """
        Runs the water quality method CSTR only and updates the pollutant
        concentration during a SWMM simulation.
        """

        nodes = Nodes(self.sim)

        for asset_ID, asset_info in self.config.items():
            for node in nodes:
                attribute =self.config[asset_ID]['method']

                if node.nodeid == asset_ID:
                    self.flag = 0
                    self.method[attribute](index, asset_ID, \
                            self.config[asset_ID]['pollutant'], \
                            self.config[asset_ID]['parameters'], self.flag)

    def _EventMeanConc(self, ID, pollutant_ID, parameters, flag):
        """
        Event Mean Concentration Treatment (SWMM Water Quality Manual, 2016)
        Treatment results in a constant concentration.

        Treatment method parameters required:
        C = constant treatment concentration for each pollutant (SI/US: mg/L)
        """

        # Set concentration
        if self.flag == 0:
            self.sim._model.setNodePollutant(ID, pollutant_ID, parameters["C"])
        else:
            self.sim._model.setLinkPollutant(ID, pollutant_ID, parameters["C"])

    def _ConstantRemoval(self, ID, pollutant_ID, parameters, flag):
        """
        CONSTANT REMOVAL TREATMENT (SWMM Water Quality Manual, 2016)
        Treatment results in a constant percent removal.

        R = pollutant removal fraction (unitless)
        """

        if self.flag == 0:
            # Get SWMM parameter
            Cin = self.sim._model.getNodeCin(ID, pollutant_ID)
            # Calculate new concentration
            Cnew = (1-parameters["R"])*Cin
            # Set new concentration
            self.sim._model.setNodePollutant(ID, pollutant_ID, Cnew)
        else:
            # Get SWMM parameter
            Cin = self.sim._model.getLinkC2(ID, pollutant_ID)
            # Calculate new concentration
            Cnew = (1-parameters["R"])*Cin
            # Set new concentration
            self.sim._model.setLinkPollutant(ID, pollutant_ID, Cnew)

    def _CoRemoval(self, ID, pollutant_ID, parameters, flag):
        """
        CO-REMOVAL TREATMENT (SWMM Water Quality Manual, 2016)
        Removal of some pollutant is proportional to the removal of
        some other pollutant.

        R1 = pollutant removal fraction (unitless)
        R2 = pollutant removal fraction for other pollutant (unitless)
        """

        if self.flag == 0:
            # Get SWMM parameter
            Cin = self.sim._model.getNodeCin(ID, pollutant_ID)
            # Calculate new concentration
            Cnew = (1-parameters["R1"]*parameters["R2"])*Cin
            # Set new concentration
            self.sim._model.setNodePollutant(ID, pollutant_ID, Cnew)
        else:
            #Get SWMM parameter
            Cin = self.sim._model.getLinkC2(ID, pollutant_ID)
            # Calculate new concentration
            Cnew = (1-parameters["R1"]*parameters["R2"])*Cin
            # Set new concentration
            self.sim._model.setLinkPollutant(ID, pollutant_ID, Cnew)

    def _ConcDependRemoval(self, ID, pollutant_ID, parameters, flag):
        """
        CONCENTRATION-DEPENDENT REMOVAL (SWMM Water Quality Manual, 2016)
        When higher pollutant removal efficiencies occur with higher
        influent concentrations.

        R_l = lower removal rate (unitless)
        BC  = boundary concentration that determines removal rate (SI/US: mg/L)
        R_u = upper removal rate (unitless)
        """

        parameters = parameters

        if self.flag == 0:
            # Get SWMM parameter
            Cin = self.sim._model.getNodeCin(ID, pollutant_ID)
            # Calculate removal
            R = (1-np.heaviside((Cin-parameters["BC"]), 0))\
            *parameters["R_l"]+np.heaviside((Cin\
            -parameters["BC"]),0)*parameters["R_u"]
            # Calculate new concentration
            Cnew = (1-R)*Cin
            # Set new concentration
            self.sim._model.setNodePollutant(ID, pollutant_ID, Cnew)
        else:
            # Get SWMM parameter
            Cin = self.sim._model.getLinkC2(ID, pollutant_ID)
            # Calculate removal
            R = (1-np.heaviside((Cin-parameters["BC"]), 0))\
            *parameters["R_l"]+np.heaviside((Cin\
            -parameters["BC"]),0)*parameters["R_u"]
            # Calculate new concentration
            Cnew = (1-R)*Cin
            # Set new concentration
            self.sim._model.setLinkPollutant(ID, pollutant_ID, Cnew)

    def _NthOrderReaction(self, ID, pollutant_ID, parameters, flag):
            """
            NTH ORDER REACTION KINETICS (SWMM Water Quality Manual, 2016)
            When treatment of pollutant X exhibits n-th order reaciton kinetics
            where the instantaneous reaction rate is kC^n.

            k   = reaction rate constant (SI: m/hr, US: ft/hr)
            n   = reaction order (first order, second order, etc.) (unitless)
            """

            parameters = parameters

            # Get current time
            current_step = self.sim.current_time
            # Calculate model dt in seconds
            dt = (current_step - self.last_timestep).total_seconds()
            # Update reference step
            self.last_timestep = current_step

            if self.flag == 0:
                # Get SWMM parameter
                C = self.sim._model.getNodeC2(ID, pollutant_ID)
                # Calculate treatment
                Cnew = C - (parameters["k"]*(C**parameters["n"])*dt)
                # Set new concentration
                self.sim._model.setNodePollutant(ID, pollutant_ID, Cnew)
            else:
                # Get SWMM parameter
                C = self.sim._model.getLinkC2(ID, pollutant_ID)
                # Calculate treatment
                Cnew = C - (parameters["k"]*(C**parameters["n"])*dt)
                # Set new concentration
                self.sim._model.setLinkPollutant(ID, pollutant_ID, Cnew)

    def _kCModel(self, ID, pollutant_ID, parameters, flag):
        """
        K-C_STAR MODEL (SWMM Water Quality Manual, 2016)
        The first-order model with bachground concnetration made popular by
        Kadlec and Knight (1996) for long-term treatment performance of wetlands.

        k   = reaction rate constant (SI: m/hr, US: ft/hr)
        C_s = constant residual concentration that always remains (SI/US: mg/L)
        """

        parameters = parameters

        if self.flag == 0:
            # Get SWMM parameters
            Cin = self.sim._model.getNodeCin(ID, pollutant_ID)
            d = self.sim._model.getNodeResult(ID, 5)
            hrt = self.sim._model.getNodeHRT(ID)
            # Calculate removal
            if d != 0.0 and Cin != 0.0:
                R = np.heaviside((Cin-parameters["C_s"]), 0)\
                *((1-np.exp(-parameters["k"]*hrt/d))*(1-parameters["C_s"]/Cin))
            else:
                R = 0
            # Calculate new concentration
            Cnew = (1-R)*Cin
            # Set new concentration
            self.sim._model.setNodePollutant(ID, pollutant_ID, Cnew)
        else:
            print("kCModel does not work for links.")

    def _GravitySettling(self, ID, pollutant_ID, parameters, flag):
        """
        GRAVITY SETTLING (SWMM Water Quality Manual, 2016)
        During a quiescent period of time within a storage volume, a fraction
        of suspended particles will settle out.

        k   = reaction rate constant (SI: m/hr, US: ft/hr)
        C_s = constant residual concentration that always remains (SI/US: mg/L)
        """

        parameters = parameters

        # Get current time
        current_step = self.sim.current_time
        # Calculate model dt in seconds
        dt = (current_step - self.last_timestep).total_seconds()
        # Update reference step
        self.last_timestep = current_step

        if self.flag == 0:
            # Get SWMM parameters
            Cin = self.sim._model.getNodeCin(ID, pollutant_ID)
            Qin = self.sim._model.getNodeResult(ID, 0)
            d = self.sim._model.getNodeResult(ID, 5)
            if d != 0.0:
                # Calculate new concentration
                Cnew = np.heaviside((0.1-Qin), 0)*(parameters["C_s"]\
                +(Cin-parameters["C_s"])*np.exp(-parameters["k"]/d*dt/3600))\
                +(1-np.heaviside((0.1-Qin), 0))*Cin
            else:
                Cnew = np.heaviside((0.1-Qin), 0)*parameters["C_s"]\
                +(Cin-parameters["C_s"])+(1-np.heaviside((0.1-Qin), 0))*Cin
            # Set new concentration
            self.sim._model.setNodePollutant(ID, pollutant_ID, Cnew)
        else:
            C = self.sim._model.getLinkC2(ID, pollutant_ID)
            Q = self.sim._model.getLinkResult(ID, 0)
            d = self.sim._model.getLinkResult(ID, 1)
            if d != 0.0:
                # Calculate new concentration
                Cnew = np.heaviside((0.1-Q), 0)*(parameters["C_s"]\
                +(C-parameters["C_s"])*np.exp(-parameters["k"]/d*dt/3600))\
                +(1-np.heaviside((0.1-Q), 0))*C
            else:
                Cnew = np.heaviside((0.1-Q), 0)*parameters["C_s"]\
                +(C-parameters["C_s"])+(1-np.heaviside((0.1-Q), 0))*C
            # Set new concentration
            self.sim._model.setLinkPollutant(ID, pollutant_ID, Cnew)

    def _Erosion(self, ID, pollutant_ID, parameters, flag):
        """
        ENGELUND-HANSEN EROSION (1967)
        Engelund and Hansen (1967) developed a procedure for predicting stage-
        discharge relationships and sediment transport in alluvial streams.

        w   = channel width (SI: m, US: ft)
        So  = bottom slope (SI: m/m, US: ft/ft)
        Ss  = specific gravity of sediment (for soil usually between 2.65-2.80)
        d50 = mean sediment particle diameter (SI/US: mm)
        d   = depth (SI: m, US: ft)
        qt  = sediment discharge per unit width (SI: kg/m-s, US: lb/ft-s)
        Qt  = sediment discharge (SI: kg/s, US: lb/s)
        """

        parameters = parameters

        # Get current time
        current_step = self.sim.current_time
        # Calculate model dt in seconds
        dt = (current_step - self.last_timestep).total_seconds()
        # Updating reference step
        self.last_timestep = current_step

        if self.flag == 0:
            print("Erosion does not work for nodes.")
        else:
            # Get SWMM parameters
            Cin = self.sim._model.getLinkC2(ID, pollutant_ID)
            Q = self.sim._model.getLinkResult(ID, 0)
            d = self.sim._model.getLinkResult(ID, 1)
            v = self.sim._model.getConduitVelocity(ID)

            # Erosion calculations for US units
            if self.sim._model.getSimUnit(0) == "US":
                g = 32.2            # ft/s^2
                ρw = 62.4           # lb/ft^3
                mm_ft = 0.00328     # ft/mm
                lb_mg = 453592      # mg/lb
                L_ft3 = 0.0353      # ft3/L
                if v != 0.0:
                    qt = 0.1*(1/((2*g*parameters["So"]*d)/v**2))*((d\
                    *parameters["So"]/((parameters["Ss"]-1)*parameters["d50"]))\
                    *(1/mm_ft))**(5/2)*parameters["Ss"]*ρw*((parameters["Ss"]-1)\
                    *g*(parameters["d50"]*mm_ft)**3)**(1/2) # lb/ft-s
                    Qt = parameters["w"]*qt       # lb/s
                else:
                    Qt = 0.0
                if Q !=0.0:
                    Cnew = (Qt/Q)*lb_mg*L_ft3   # mg/L
                    Cnew = max(Cin, Cin+Cnew)
                    # Set new concentration
                    self.sim._model.setLinkPollutant(ID, pollutant_ID, Cnew)

            # Erosion calculations for SI units
            else:
                g = 9.81            # m/s^2
                ρw = 1000           # kg/m^3
                mm_m = 0.001        # m/mm
                kg_mg = 1000000     # mg/kg
                L_m3 =  0.001       # m3/L
                if v != 0.0:
                    qt = 0.1*(1/((2*g*parameters["So"]*d)/v**2))*((d\
                    *parameters["So"]/((parameters["Ss"]-1)*parameters["d50"]))\
                    *(1/mm_m))**(5/2)*parameters["Ss"]*ρw*((parameters["Ss"]-1)\
                    *g*(parameters["d50"]*mm_m)**3)**(1/2) # kg/m-s
                    Qt = parameters["w"]*qt       # kg/s
                else:
                    Qt = 0.0
                if Q != 0.0:
                    Cnew = (Qt/Q)*L_m3*kg_mg    # mg/L
                    Cnew = max(Cin, Cin+Cnew)
                    # Set new concentration
                    self.sim._model.setLinkPollutant(ID, pollutant_ID, Cnew)

    def _CSTR_tank(self, t, C, Qin, Cin, Qout, V, k, n):
        """
        UNSTEADY CONTINUOUSLY STIRRED TANK REACTOR (CSTR)
        CSTR is a common model for a chemical reactor. The behavior of a CSTR
        is modeled assuming it is not in steady state. This is because
        outflow, inflow, volume, and concentration are constantly changing.

        NOTE: You do not need to call this method, only the CSTR_solver.
        CSTR_tank is intitalized in __init__ in Node_Treatment.
        """
        dCdt = (Qin*Cin - Qout*C)/V + k*C**n
        return dCdt

    def _CSTRSolver(self, index, ID, pollutant_ID, parameters, flag):
        """
        UNSTEADY CONTINUOUSLY STIRRED TANK REACTOR (CSTR) SOLVER
        CSTR is a common model for a chemical reactor. The behavior of a CSTR
        is modeled assuming it is not in steady state. This is because
        outflow, inflow, volume, and concentration are constantly changing.
        Therefore, Scipy.Integrate.ode solver is used to solve for concentration.

        NOTE: You only need to call this method, not CSTR_tank. CSTR_tank is
        intitalized in __init__ in Node_Treatment.

        k   = reaction rate constant (SI/US: 1/s)
        n   = reaction order (first order, second order, etc.) (unitless)
        c0  = intital concentration inside reactor (SI/US: mg/L)
        """

        # Get current time
        current_step = self.sim.current_time
        # Calculate model dt in seconds
        dt = (current_step - self.last_timestep).total_seconds()
        # Updating reference step
        self.last_timestep = current_step

        if self.flag == 0:
            # Get parameters
            Qin = self.sim._model.getNodeResult(ID, 0)
            Cin = self.sim._model.getNodeCin(ID, pollutant_ID)
            Qout = self.sim._model.getNodeResult(ID, 1)
            V = self.sim._model.getNodeResult(ID, 3)

            # Parameterize solver
            self.solver.set_f_params(Qin, Cin, Qout, V, parameters["k"], parameters["n"])
            # Solve ODE
            if index == 0:
                self.solver.set_initial_value(parameters["c0"], 0.0)
                self.solver.integrate(self.solver.t+dt)
            else:
                self.solver.set_initial_value(self.solver.y, self.solver.t)
                self.solver.integrate(self.solver.t+dt)
            # Set new concentration
            self.sim._model.setNodePollutant(ID, pollutant_ID, self.solver.y[0])
        else:
            print("CSTR does not work for links.")

    def _Phosphorus(self, ID, pollutant_ID, parameters, flag):
        """
        LI & DAVIS BIORETENTION CELL TOTAL PHOSPHOURS MODEL (2016)
        Li and Davis (2016) developed a dissolved and particulate phosphorus
        model for bioretention cells.

        B1    = coefficient related to the rate at which Ceq approaches Co (SI/US: 1/s)
        Ceq0  = initial DP or PP equilibrium concentration value for an event (SI/US: mg/L)
        k     = reaction rate constant (SI/US: 1/s)
        L     = depth of soil media (length of pathway) (SI: m, US: ft)
        A     = cross-sectional area (SI: m^2, US: ft^2)
        E     = filter bed porosity (unitless)
        """

        parameters = parameters
        t = 0

        if self.flag == 0:
            # Get SWMM parameters
            Cin = self.sim._model.getNodeCin(ID, pollutant_ID)
            Qin = self.sim._model.getNodeResult(ID, 0)
            # Time calculations for phosphorus model
            if Qin >= 0.01:
                # Get current time
                current_step = self.sim.current_time
                # Calculate model dt in seconds
                dt = (current_step - self.last_timestep).total_seconds()
                # Accumulate time elapsed since water entered node
                t = t + dt
                # Updating reference step
                self.last_timestep = current_step
                # Calculate new concentration
                Cnew = (Cin*np.exp((-parameters["k"]*parameters["L"]\
                    *parameters["A"]*parameters["E"])/Qin))+(parameters["Ceq0"]\
                    *np.exp(parameters["B1"]*t))*(1-(np.exp((-parameters["k"]\
                    *parameters["L"]*parameters["A"]*parameters["E"])/Qin)))
                # Set new concentration
                self.sim._model.setNodePollutant(ID, pollutant_ID, Cnew)
            else:
                t = 0
        else:
            C = self.sim._model.getLinkC2(ID, pollutant_ID)
            Q = self.sim._model.getLinkResult(ID, 0)
            # Time calculations for phosphorus model
            if Q >= 0.01:
                # Get current time
                current_step = self.sim.current_time
                # Calculate model dt in seconds
                dt = (current_step - self.last_timestep).total_seconds()
                # Accumulate time elapsed since water entered link
                t = t + dt
                # Updating reference step
                self.last_timestep = current_step
                # Calculate new concentration
                Cnew = (C*np.exp((-parameters["k"]*parameters["L"]\
                    *parameters["A"]*parameters["E"])/Q))+(parameters["Ceq0"]\
                    *np.exp(parameters["B1"]*t))*(1-(np.exp((-parameters["k"]\
                    *parameters["L"]*parameters["A"]*parameters["E"])/Q)))
                # Set new concentration
                self.sim._model.setLinkPollutant(ID, pollutant_ID, Cnew)
            else:
                t = 0


""" From "COMPUTATIONAL PHYSICS" & "COMPUTER PROBLEMS in PHYSICS"
    by RH Landau, MJ Paez, and CC Bordeianu (deceased)
    Copyright R Landau, Oregon State Unv, MJ Paez, Univ Antioquia,
    C Bordeianu, Univ Bucharest, 2017.
    Please respect copyright & acknowledge our work."""

# HOnumericReflex.py: Quantum HO wave functions via ODE solver

import numpy as np
import matplotlib.pylab as plt
from rk4Algor import rk4Algor

n = 5   #  Quantum number n = npr + L + 1 = integer > 0
xx = np.zeros((1000),float)            # x values for plot
yy = np.zeros((1000),float)            # wave function values
fvector = [0]*(2)                      # force function f
y = [0]*(2)     # array for 2 values

def f(x,y):                          # Force function for HO
    fvector[0] = y[1]
    fvector[1] = -(2*n+1-x**2)*y[0]
    return fvector

if (n%2 == 0):   y[0] = 1.;   y[1] = 0.   # Even parity
else:            y[0] = 0;    y[1] = -1.   # Odd parity

xRight = 5
f(0,y)     # force function at starting value
dx = 0.01
i = 0
# Compute WF from 0 to xRight in steps of dr
for x in np.arange(0,xRight,dx):
    xx[i+500] = x
    y = rk4Algor(x, dr, 2, y, f)
    yy[i+500] = y[0]   #
    i = i+1      # Advance i as well as x
          # Now reflect
i = 0
for x in np.arange(-dx,-xRight,-dx):
    xx[499-i] =  -xx[i+499]
    if (n%2 == 0): yy[499-i] =  yy[i+499]    # Even parity
    else:          yy[499-i] = -yy[i+499]    # Ddd parity
    i = i + 1
plt.figure()
plt.plot(xx,yy)
plt.grid()
plt.title('Harmonic Oscillator Wave Function n = 5')
plt.xlabel('x')
plt.ylabel('Wave Function u(x)')
plt.show()


import json
import jsonschema

from django.core.management import call_command
from django.test.client import Client
from jsonschema import validate
from io import StringIO

from apps.dot_ext.tests.test_models import TestDotExtModels
from apps.test import BaseApiTest

from .audit_logger_schemas import GLOBAL_STATE_METRICS_LOG_SCHEMA

loggers = [
    'audit.global_state_metrics'
]

class TestLoggersGlobalMetricsManagementCommand(BaseApiTest):

    def setUp(self):
        # Setup the RequestFactory
        self.client = Client()
        self._redirect_loggers(loggers)

    def tearDown(self):
        self._cleanup_logger()

    def _get_log_content(self, logger_name):
        return self._collect_logs(loggers).get(logger_name)

    def _validateJsonSchema(self, schema, content):
        try:
            validate(instance=content, schema=schema)
        except jsonschema.exceptions.ValidationError as e:
            # Show error info for debugging
            print("jsonschema.exceptions.ValidationError: ", e)
            return False
        return True

    def test_management_command_logging(self):
        # Run test method from apps/dot_ext/tests/test_models.py to populate DB with applicaiton entries.
        TestDotExtModels().test_application_count_funcs()

        # Create 5x Real (positive FHIR_ID) users
        for cnt in range(5):
            self._create_user('johnsmith' + str(cnt), 'password',
                              first_name='John1' + str(cnt),
                              last_name='Smith',
                              email='john' + str(cnt) + '@smith.net',
                              fhir_id='2000000000000' + str(cnt),
                              user_hicn_hash='239e178537ed3bc486e6a7195a47a82a2cd6f46e911660fe9775f6e00000000' + str(cnt),
                              user_mbi_hash='9876543217ed3bc486e6a7195a47a82a2cd6f46e911660fe9775f6e00000000' + str(cnt))

        # Create 7x Synthetic (negative FHIR_ID) users and access tokens for application2
        for cnt in range(7):
            self._create_user('johndoe' + str(cnt), 'password',
                              first_name='John' + str(cnt),
                              last_name='Doe',
                              email='john' + str(cnt) + '@doe.net',
                              fhir_id='-2000000000000' + str(cnt),
                              user_hicn_hash='255e178537ed3bc486e6a7195a47a82a2cd6f46e911660fe9775f6e00000000' + str(cnt),
                              user_mbi_hash='987654321aaaa11111aaaa195a47a82a2cd6f46e911660fe9775f6e00000000' + str(cnt))

        '''
        Call management command that produces the following entry to be validated with JsonSchema:

            {"type": "global_state_metrics", "group_timestamp": "2021-04-12T19:24:00+00:00",
             "real_bene_cnt": 5, "synth_bene_cnt": 7, "global_apps_active_cnt": 7,
             "global_apps_inactive_cnt": 3, "global_apps_require_demographic_scopes_cnt": 5}
        '''
        out = StringIO()
        call_command("log_global_state_metrics", stdout=out, stderr=StringIO())

        # Validate log entry
        log_content = self._get_log_content('audit.global_state_metrics')
        self.assertIsNotNone(log_content)
        log_content_dict = json.loads(log_content)
        self.assertTrue(self._validateJsonSchema(GLOBAL_STATE_METRICS_LOG_SCHEMA, log_content_dict))


# coding=utf-8
import logging
import pytz
from datetime import datetime

from odoo import api, fields, models, _
from odoo.exceptions import ValidationError, UserError

_logger = logging.getLogger(__name__)

class SaleOrder(models.Model):
    _inherit = 'sale.order'

    busqueda_ruc = fields.Char(
        string='Busqueda RUC',
    )
    @api.onchange('busqueda_ruc')
    def onchange_busqueda_ruc(self):
        if(self.busqueda_ruc is not False):
            cli = self.env['res.partner'].search([('nro_documento','=',self.busqueda_ruc)])
            if(len(cli)>0):
                self.partner_id = cli[0]
                self.busqueda_ruc=False
            else:
                raise ValidationError(u'No se encuentra el Cliente con RUC: ' + self.busqueda_ruc)

    def _get_tipo_documento(self):
        param = self.env['sale.parameters.it'].search([])
        if param.type_document_id:
            return param.type_document_id.id

    def _get_serie(self):
        param = self.env['sale.parameters.it'].search([])
        if param.invoice_serie_id:
            return param.invoice_serie_id

    def _get_account_journal(self):
        param = self.env['sale.parameters.it'].search([])
        if param.account_journal_id:
            return param.account_journal_id.id

    def _get_einvoice_means_payment(self):
        param = self.env['sale.parameters.it'].search([])
        if param.means_payment_id:
            return param.means_payment_id.id

    def _get_partner_id(self):
        param = self.env['main.parameter'].search([])
        if param.partner_venta_boleta:
            return param.partner_venta_boleta.id

    doc_search = fields.Char(u'Buscar x nro documento')
    partner_id = fields.Many2one('res.partner', string='Customer', readonly=True,
                                 states={'draft': [('readonly', False)], 'sent': [('readonly', False)]}, required=True,
                                 change_default=True, index=True, track_visibility='always', default=_get_partner_id)
    it_type_document = fields.Many2one('einvoice.catalog.01', u'Tipo de documento',
                                       states={'draft': [('readonly', False)], 'sent': [('readonly', False)]})
    it_invoice_serie = fields.Many2one('it.invoice.serie', u'Serie',
                                       states={'draft': [('readonly', False)], 'sent': [('readonly', False)]})
    sequence_id = fields.Many2one('ir.sequence', related='it_invoice_serie.sequence_id')
    invoice_number = fields.Char(u'Número', store=True, readonly=False, required=True)
    account_journal = fields.Many2one('account.journal', u'Diario de pago', default=_get_account_journal,
                                      states={'draft': [('readonly', False)], 'sent': [('readonly', False)]})
    einvoice_means_payment = fields.Many2one('einvoice.means.payment', u'Medio de pago',
                                             default=_get_einvoice_means_payment,
                                             states={'draft': [('readonly', False)], 'sent': [('readonly', False)]})

    @api.onchange('warehouse_id')
    def onchange_warehouse_id(self):
        for order in self:
            warehouse_id = order.warehouse_id
            tipo_doc_id = warehouse_id.tipo_doc_id
            serie_id = warehouse_id.invoice_serie_id
            if not serie_id:
                tipo_doc_id = order._get_tipo_documento()
                serie_id = order._get_serie()
            invoice_number = self.obtener_numero(serie_id)
            order.update({
                'it_type_document': tipo_doc_id,
                'it_invoice_serie': serie_id,
                'invoice_number': invoice_number
            })

            # order.it_type_document = tipo_doc_id
            # order.it_invoice_serie = serie_id
            # order.invoice_number = self.obtener_numero(serie_id)

    @api.onchange('it_invoice_serie')
    def onchange_invoice_id(self):
        for order in self:
            self.invoice_number = self.obtener_numero(self.it_invoice_serie)

    @api.model
    @api.returns('self', lambda value: value.id)
    def create(self, vals):
        if not vals.get('invoice_number', False):
            serie_id = self.env['it.invoice.serie'].browse(vals.get('it_invoice_serie'))
            vals.update({'invoice_number': self.obtener_numero(serie_id)})
        return super(SaleOrder, self).create(vals)

    def obtener_numero(self, serie_id):

        sequence_id = serie_id.sequence_id
        padding = sequence_id.padding
        prefix = sequence_id.prefix
        numero = sequence_id.number_next
        siguiente = '%s%0{}d'.format(padding) % (prefix, numero)
        return siguiente

    @api.onchange('doc_search')
    def onchange_doc_search(self):
        partner = self.env['res.partner'].search([('nro_documento', '=', self.doc_search)], limit=1)
        if partner.exists():
            return {
                'value': {'partner_id': partner.id}
            }
        else:
            raise UserError(_('Cliente no encontrado'))


import torch
import torch.nn as nn

#MODEL HELPERS

def int_func(X,Y,func):
    if func == 'exp':
        #interaction map
        I = torch.exp(torch.mm(X,Y.t()))
        #inverse of sum of columns for I and transpose I
        x_norm = torch.pow(torch.sum(I, dim=1),-1)
        y_norm = torch.pow(torch.sum(I.t(), dim=1),-1)
        #interaction maps with normalised columns
        I_x = I * x_norm[:,None]
        I_y = I.t() * y_norm[:,None]
        #contexts
        X_context = torch.mm(I_x,Y)
        Y_context = torch.mm(I_y,X)
    if func == 'tanh':
        #interaction map
        I = torch.tanh(torch.mm(X,Y.t()))
        #contexts
        X_context = torch.mm(I,Y)
        Y_context = torch.mm(I.t(),X)
    #concatenate
    catX = torch.cat((X,X_context))
    catY = torch.cat((Y,Y_context))
    return [catX, catY]

def int_func_map(X,Y,func):
    if func == 'exp':
        #interaction map
        I = torch.exp(torch.mm(X,Y.t()))
        #inverse of sum of columns for I and transpose I
        x_norm = torch.pow(torch.sum(I, dim=1),-1)
        y_norm = torch.pow(torch.sum(I.t(), dim=1),-1)
        #interaction maps with normalised columns
        I_x = I * x_norm[:,None]
        I_y = I.t() * y_norm[:,None]
        return [I_x, I_y]
    if func == 'tanh':
        #interaction map
        I = torch.tanh(torch.mm(X,Y.t()))
        return I

def get_activation_function(activation: str) -> nn.Module:
    """
    Gets an activation function module given the name of the activation.

    Supports:

    * :code:`ReLU`
    * :code:`LeakyReLU`
    * :code:`PReLU`
    * :code:`tanh`
    * :code:`SELU`
    * :code:`ELU`

    :param activation: The name of the activation function.
    :return: The activation function module.
    """
    if activation == 'ReLU':
        return nn.ReLU()
    elif activation == 'LeakyReLU':
        return nn.LeakyReLU(0.1)
    elif activation == 'PReLU':
        return nn.PReLU()
    elif activation == 'tanh':
        return nn.Tanh()
    elif activation == 'SELU':
        return nn.SELU()
    elif activation == 'ELU':
        return nn.ELU()
    else:
        raise ValueError(f'Activation "{activation}" not supported.')


from django.conf import settings
from django.conf.urls import url, include, patterns
from django.contrib import admin
from rest_framework.urlpatterns import format_suffix_patterns

from dashboard import api
from dashboard.views import download_database, home

urlpatterns = [
    url(r'^$', home),
    url(r'^admin/', include(admin.site.urls)),
    url(r'^jet/', include('jet.urls', 'jet')),
    url(r'^api/', include('rest_framework.urls', namespace='rest_framework')),
    url(r'^api/changelog/$', api.ChangeLog.as_view()),
    url(r'^api/changelog/(?P<pk>[0-9]+0)/$', api.ChangeLogDetail.as_view()),
    url(r'^api/db_changelog/$', api.DataBaseChangeLog.as_view()),
    url(r'^api/db_changelog/(?P<pk>[0-9]+0)/$', api.DataBaseChangeLogDetail.as_view()),
    url(r'^api/bus_search/$', api.BusDepartures.as_view()),
    url(r'^api/canceled_events/$', api.CanceledEvents.as_view()),
    url(r'^download_database/(?P<filename>[^/]+)/$', download_database, name='db-download'),
]

test = format_suffix_patterns(urlpatterns)

urlpatterns += patterns('',
    (r'^assets/(?P<path>.*)$', 'django.views.static.serve', {'document_root': settings.STATIC_ROOT}))


from easygraph.functions.path import *

__all__ = [
    'closeness_centrality',
]

def closeness_centrality(G, weight=None):
    '''Compute closeness centrality for nodes.

    .. math::

        C_{WF}(u) = \frac{n-1}{N-1} \frac{n - 1}{\sum_{v=1}^{n-1} d(v, u)},

    Notice that the closeness distance function computes the
    outcoming distance to `u` for directed graphs. To use
    incoming distance, act on `G.reverse()`.

    Parameters
    ----------
    G : graph
      A easygraph graph

    weight : None or string, optional (default=None)
      If None, all edge weights are considered equal.
      Otherwise holds the name of the edge attribute used as weight.

    Returns
    -------
    nodes : dictionary
      Dictionary of nodes with closeness centrality as the value.

    '''
    result_dict = dict()
    nodes = G.nodes
    length = len(nodes)
    import functools
    if weight is not None:
        path_length = functools.partial(single_source_dijkstra, weight=weight)
    else:
        path_length = functools.partial(single_source_bfs)
    for node in nodes:
        x = path_length(G, node)
        dist = sum(x.values())
        cnt = len(x)
        if dist  == 0:
            result_dict[node] = 0
        else:
            result_dict[node] = (cnt-1)*(cnt-1)/(dist*(length-1))
    return result_dict


## example bot ##

rooms = ["room", "roomhere"]

from irc import IRCBot, run_bot

owner = "theholder" # put your irc nick here

class bot(IRCBot):

	def say(self, nick, message, channel):
		if nick.lower() != owner:
			return
		else:
			ret = message[4:]
			return ret

	def command_patterns(self):
		return(
			self.command("say", self.say),
		)

host = "irc.domain.tld"
port = 6667
nick = "bot"

run_bot(bot,
	host,
	port,
	nick,
	rooms)


from flask import Flask, render_template, request
import os
import re
import random

from random import randint, choice
from nltk.util import ngrams
from functools import reduce
from flask import jsonify
import math

#Taken from su27's stackexchange post https://stackoverflow.com/questions/18967441/add-a-prefix-to-all-flask-routes/36033627#36033627
class PrefixMiddleware(object):

    def __init__(self, app, prefix=''):
        self.app = app
        self.prefix = prefix

    def __call__(self, environ, start_response):

        if environ['PATH_INFO'].startswith(self.prefix):
            environ['PATH_INFO'] = environ['PATH_INFO'][len(self.prefix):]
            environ['SCRIPT_NAME'] = self.prefix
            return self.app(environ, start_response)
        else:
            start_response('404', [('Content-Type', 'text/plain')])
            return ["This url does not belong to the app.".encode()]

app = Flask(__name__)
app.wsgi_app = PrefixMiddleware(app.wsgi_app, prefix='/thefaraway')

MAX_N = 5
SEED_MAX_SIZE = 20
MUTATION_CHANCE = 0.05
ADD_CHANCE = 0.03
LOSE_CHANCE = 0.03
POP_SIZE = 50
HINGE_P = .2
JOIN_P = .08
MIN_LENGTH = 10
MAX_LENGTH = 20

def read_text(txt_path=os.path.join(os.getcwd(), "texts", "WhateverItIsWhereverYouAre.txt")):
    with open(txt_path, 'r') as f:
        out = f.read()
    return out

def get_ngrams(txt, n=MAX_N):
    words = re.split(r"[ \t\n\r\f\v\.\!\?\",]+", txt.lower())
    return list_ngrams(words, n)

def list_ngrams(lst, n=MAX_N):
    the_ngrams = dict()
    the_ngrams[1] = lst
    for i in range(2, n + 1):
        the_ngrams[i] = set(ngrams(lst, i))

    return the_ngrams

txt = read_text()
ngs = get_ngrams(txt)

def n_sim(txta, n=MAX_N):
    a_ngrams = list_ngrams(txta)

    score = 0
    for i in range(2, n + 1):
        if len(a_ngrams[i]) >= 1:
            score += math.log1p(i) * len(a_ngrams[i].intersection(ngs[i])) / float(len(a_ngrams[i]))

    return score / (n - 1)

def weights(pop):
    return list(map(n_sim, pop))

def display_pop(pop):
    return "<br>".join(map(lambda l: " ".join(l), pop))

def mutate(t, mut_p = MUTATION_CHANCE, add_p = ADD_CHANCE, lose_p = LOSE_CHANCE, min_l = MIN_LENGTH, max_l = MAX_LENGTH):
    new = []
    words = ngs[1]
    for i, w in enumerate(t):
        r = random.random()
        if r <= mut_p:
            new.append(choice(words))
        elif r <= mut_p + add_p:
            new.append(w)
            new.append(choice(words))
        elif r <= mut_p + add_p + lose_p:
            pass
        else:
            new.append(w)
    if len(new) < min_l:
        for i in range(min_l - len(new)):
            new.append(choice(words))
    elif len(new) > max_l:
        new = new[:max_l]
    return new

def crossover(l, r):
    hingel = randint(0, len(l))
    hinger = randint(0, len(r))
    return l[:hingel] + r[hinger:]

def mutate_with_weight(x, mutp=MUTATION_CHANCE, addp=ADD_CHANCE, losep=LOSE_CHANCE):
    y = mutate(x, mut_p=mutp, add_p=addp, lose_p=losep)
    return [y, n_sim(y)]

def update(weighted_pop, mutp=MUTATION_CHANCE, addp=ADD_CHANCE, losep=LOSE_CHANCE):
    pop = [wp[0] for wp in weighted_pop]
    pop_weights = weights(pop)
    sample_l = random.choices(pop, pop_weights, k=POP_SIZE)
    sample_r = random.choices(pop, pop_weights, k=POP_SIZE)
    new_pop = []
    for i in range(POP_SIZE):
        new_pop.append(crossover(sample_l[i], sample_r[i]))
    return list(map(lambda x: mutate_with_weight(x, mutp, addp, losep), new_pop))

@app.route('/start/')
def genetictext():
    def sim_fit(t):
        return n_sim(t, ngs)

    def text_seed(max_len=SEED_MAX_SIZE):
        n = randint(MIN_LENGTH, SEED_MAX_SIZE)
        s = reduce(lambda a, b: a + [choice(ngs[1])], range(n + 1), [])
        return [s, n_sim(s)]

    pop = list(map(lambda x: text_seed(), range(POP_SIZE)))

    return jsonify(pop)

@app.route('/update/', methods=['POST'])
def a_generation():
    dat = request.get_json()
    new_pop = update(dat['population'], mutp=float(dat["mutp"]), addp=float(dat["addp"]), losep=float(dat["losep"]))
    return jsonify(new_pop)

@app.route('/')
def start_here():
    return render_template('environ.html')

if __name__ == '__main__':
    app.run(host='0.0.0.0')


import requests
import os
import pandas as pd
import json
import smtplib
from pathlib import Path
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email import encoders
from datetime import datetime as dt

# sources
# https://stackoverflow.com/questions/3362600/how-to-send-email-attachments
# https://www.tutorialspoint.com/send-mail-with-attachment-from-your-gmail-account-using-python

# read in data
credentials = pd.read_csv('backend/email_credentials.csv').squeeze()
recipients = json.load(open('backend/mailing_list.json', 'r'))
auth = pd.read_csv('backend/auth.csv').squeeze()

def post_slack_message(text, blocks = None):
    return requests.post('https://slack.com/api/chat.postMessage',
    {
        'token': auth['slack_token'],
        'channel': auth['slack_channel'],
        'text': text,
        'blocks': json.dumps(blocks) if blocks else None
    }).json()

def build_slack_message(email_details):

    return '\n'.join(str(detail[0]) + ' received data from ' + str(detail[1]) +
           ' file(s) regarding ' + str(detail[2]) + ' in the following regions: ' + ', '.join(detail[3])
           for detail in email_details)

def build_file_details(receiver, parsed_files):
    body = []
    for file in parsed_files:
        text_part = ('
' + str(file['Name']) + '' +
                     '
Regional Level: ' + receiver['region_level'] +
                     '
Regions: ' +', '.join(receiver['regions']) +
                     '
Date: ' + str(file['Date']) +
                     '
Value (95% CI): ' + str(file['Value']) + ' (' +
                                              str(file['Low_CI']) + ', ' +
                                              str(file['Upper_CI']) + ')')
        body.append(text_part)

    return ''.join(body)

def send_email(credentials, receiver, file_paths, parsed_files):
    message = MIMEMultipart()
    message['From'] = credentials['sender']
    message['To'] = receiver['address']

    # TODO: add handling for multiple dates/files
    message['Subject'] = (receiver['nickname'] + ' ' + receiver['data_type'] +
                          ' [' + parsed_files[0]['Date'] + ']')

    message['Cc'] = ','.join(receiver['cc'])
    # The subject line
    #The body and the attachments for the mail
    file_details = build_file_details(receiver, parsed_files)
    message_out = ('Hello,
Here is your requested data:
' + file_details +
                   '
Notes: ' + receiver['notes'] +
                   '

This is a bot. Please contact ' + credentials['real_email'] + ' if you have any questions.')
    message.attach(MIMEText(message_out, 'html'))

    if receiver['send_files']:
        for path in file_paths :
            part = MIMEBase('application', 'octate-stream')

            with open(path, 'rb') as file:
                part.set_payload(file.read())
            encoders.encode_base64(part)
            part.add_header('Content-Disposition',
                            'attachment; filename="{}"'.format(Path(path).name))
            message.attach(part)

#Create SMTP session for sending the mail
    session = smtplib.SMTP('smtp.gmail.com', 587) #use gmail with port
    session.starttls() #enable security
    session.login(credentials['sender'], credentials['sender_pass']) #login with mail_id and password
    text = message.as_string()

    all_receivers = [receiver['address']] + receiver['cc']

    session.sendmail(credentials['sender'], all_receivers, text)
    session.quit()

# extract most recent values from files to be used in email body text
def parse_file(file):
    file_name = file[0]
    file_path = file[1]

    # assumes format Date, value low CI, upper CI
    if file_path.endswith('csv'):
        df = pd.read_csv(file_path)
        max_date = max(df['Date'])
        df_new = df[(df.Date == max_date)]

        value = round(df_new.iloc[0, 1], 3)
        low_CI = round(df_new.iloc[0, 2], 3)
        upper_CI = round(df_new.iloc[0, 3], 3)

        file_values = {'Name':file_name, 'Date':max_date, 'Value':value,
                       'Low_CI':low_CI, 'Upper_CI': upper_CI}

    return file_values

# send emails
email_details = []
for receiver in recipients:
    parsed_files = [parse_file(file) for file in receiver['files']]
    file_paths = [file[1] for file in receiver['files']]

    send_email(credentials, receiver, file_paths, parsed_files)
    email_details.append([receiver['address'], len(receiver['files']), receiver['data_type'], receiver['regions']])

# build & send slack message
text = build_slack_message(email_details)
post_slack_message(text)