#!/usr/bin/env python3
"""
Copyright Seán Bruton, Trinity College Dublin, 2019.
Contact sbruton[á]tcd.ie.
"""
import argparse
import sys
import os
from typing import List
import h5py
import progressbar
import numpy as np

def downsample_dataset(h5_path: os.path, images_key: str):
    with h5py.File(h5_path, 'r+') as h5_file:
        low_res_images_key = images_key + '_lr'
        if low_res_images_key in list(h5_file.keys()):
            print("Low res dataset already exists, skipping.")
            return

        images_dataset = h5_file[images_key]
        num_images = images_dataset.shape[0]
        num_views = images_dataset.shape[1]
        num_channels = images_dataset.shape[2]
        full_height = images_dataset.shape[3]
        half_height = full_height // 2
        full_width = images_dataset.shape[4]
        half_width = full_width // 2

        low_res_dataset_shape = (
            num_images,
            num_views,
            num_channels,
            half_height,
            half_width
        )

        image_lr_chunk_shape = (1, 1, num_channels, half_height, half_width)

        low_res_dataset = h5_file.create_dataset(
            name=low_res_images_key,
            shape=low_res_dataset_shape,
            dtype=images_dataset.dtype,
            compression='lzf',
            chunks=image_lr_chunk_shape
        )

        print("Creating downsampled dataset.")
        bar = progressbar.ProgressBar()
        for idx in bar(np.arange(num_images)):
            low_res_dataset[idx] = images_dataset[idx, :, :, ::2, ::2]

def extract_indexed_dataset(h5_path: os.path,
                            input_images_key: str,
                            indices: List[int],
                            new_suffix: str):
    with h5py.File(h5_path, 'r+') as h5_file:
        new_images_key = input_images_key + new_suffix
        if new_images_key in list(h5_file.keys()):
            print("{} dataset already exists, skipping.".format(new_images_key))

        lr_images_dataset = h5_file[input_images_key]
        num_images = lr_images_dataset.shape[0]
        num_views = len(indices)
        num_channels = lr_images_dataset.shape[2]
        height = lr_images_dataset.shape[3]
        width = lr_images_dataset.shape[4]

        new_dataset_shape = (
            num_images,
            num_views,
            num_channels,
            height,
            width
        )

        new_chunk_shape = (1, num_views, num_channels, height, width)

        new_dataset = h5_file.create_dataset(
            name=new_images_key,
            shape=new_dataset_shape,
            dtype=lr_images_dataset.dtype,
            compression='lzf',
            chunks=new_chunk_shape
        )

        print("Creating new dataset: {}.".format(new_images_key))
        bar = progressbar.ProgressBar()
        for idx in bar(np.arange(num_images)):
            new_dataset[idx] = lr_images_dataset[idx, indices, :, :, :]

def get_y_indices(h5_path: os.path,
                  input_images_key: str,
                  x_indices: List[int]) -> List[int]:
    with h5py.File(h5_path) as h5_file:
        lr_images_dataset = h5_file[input_images_key]
        all_indices = np.arange(lr_images_dataset.shape[1], dtype=np.int32)
        return list(set(all_indices) - set(x_indices))

def clone_input_dataset(input_h5_path: os.path,
                        output_h5_path: os.path,
                        data_key: str):
    with h5py.File(input_h5_path, 'r') as input_h5_file:
        lr_images_dataset = input_h5_file[data_key]

        num_images = lr_images_dataset.shape[0]
        num_views = lr_images_dataset.shape[1]
        num_channels = lr_images_dataset.shape[2]
        height = lr_images_dataset.shape[3]
        width = lr_images_dataset.shape[4]

        new_dataset_shape = (
            num_images,
            num_views,
            num_channels,
            height,
            width
        )

        new_chunk_shape = (1, num_views, num_channels, height, width)

        with h5py.File(output_h5_path, 'w') as output_h5_file:
            new_dataset = output_h5_file.create_dataset(
                name=data_key,
                shape=new_dataset_shape,
                dtype=lr_images_dataset.dtype,
                compression='lzf',
                chunks=new_chunk_shape
            )

            print("Cloning light field dataset.")
            bar = progressbar.ProgressBar()
            for idx in bar(np.arange(num_images)):
                new_dataset[idx] = lr_images_dataset[idx]

def create_new_datasets(input_h5_path: os.path,
                        output_h5_path: os.path,
                        data_key: str):
    clone_input_dataset(input_h5_path, output_h5_path, data_key)

    downsample_dataset(output_h5_path, data_key)

    x_indices = [0, 5, 40, 45]
    y_indices = [1, 2, 3, 4,
                 8, 9, 10, 11, 12, 13,
                 16, 17, 18, 19, 20, 21,
                 24, 25, 26, 27, 28, 29,
                 32, 33, 34, 35, 36, 37,
                 41, 42, 43, 44]

    data_key_hr = data_key
    data_key_lr = data_key + '_lr'

    extract_indexed_dataset(output_h5_path, data_key_hr, x_indices, '_x')
    extract_indexed_dataset(output_h5_path, data_key_hr, y_indices, '_y')

    extract_indexed_dataset(output_h5_path, data_key_lr, x_indices, '_x')
    extract_indexed_dataset(output_h5_path, data_key_lr, y_indices, '_y')

if __name__ == '__main__':
    parser = argparse.ArgumentParser(
        description="Downsample the images and save to the h5 file."
    )
    parser.add_argument("input",
                        help="The input h5 file.",
                        type=str)
    parser.add_argument("output",
                        help="The input h5 file.",
                        type=str)
    parser.add_argument("key",
                        help="The images dataset key.",
                        type=str,
                        default='images')
    args = parser.parse_args()

    input_path = os.path.abspath(args.input)
    output_path = os.path.abspath(args.output)

    if not os.path.isfile(input_path):
        print("The specified input file {} does not exist.".format(input_path))
        sys.exit(1)

    try:
        create_new_datasets(input_path, output_path, args.key)
    except ValueError as e:
        print("Error occurred: {}".format(e))
        sys.exit(1)


"""
Finds cumulative scan volumes for masks from IWFS and DESS.
Finds cumulative BML volume of Manual BML segmentation.
Then, compares abs(vol(IWFS) - vol(DESS)) to vol(Manual BML).
"""

import pathlib
import matplotlib.pyplot as plt
import numpy as np
import scipy.stats

import common.dictutils
import common.files as files
import analysis.volume as vol

preds_iwfs = pathlib.Path('data/run_models/iwfs')
preds_dess = pathlib.Path('data/run_models/dess')
manual_bml_masks = pathlib.Path('data/run_models/bml')
cdi_files = pathlib.Path('data/cdi/OldMethod')

def main():

    print(f"Loading IWFS predictions from {preds_iwfs}")
    preds_iwfs_series = files.read_image_series(preds_iwfs, ends_with="pred.png")
    preds_iwfs_series = common.dictutils.slices_to_mask(preds_iwfs_series, threshold=0.5)
    preds_iwfs_volumes = common.dictutils.visit_to_volume(preds_iwfs_series)
    preds_iwfs_totals = {}  # Key: Patient, Val: List of Volumes

    print(f"Calculating IWFS volume metrics")
    for patient, visits in preds_iwfs_volumes.items():
        for visit, volume in visits.items():
            v = vol.mask(volume, voxel_size=0.357 * 0.511 * 3)
            if patient not in preds_iwfs_totals.keys():
                preds_iwfs_totals[patient] = [v, ]
            else:
                preds_iwfs_totals[patient].append(v)

    print(f"Loading DESS predictions from {preds_dess}")
    preds_dess_series = files.read_image_series(preds_dess, ends_with="pred.png")
    preds_dess_series = common.dictutils.slices_to_mask(preds_dess_series, threshold=0.5)
    preds_dess_volumes = common.dictutils.visit_to_volume(preds_dess_series)
    preds_dess_totals = {}  # Key: Patient, Val: List of Volumes

    print(f"Loading CDI markers from {cdi_files}")
    cdi = files.read_cdi_bone_volumes(cdi_files, ends_with="OldMethod_Femur.txt")
    print(f"Applying {len(cdi)} patient CDI markers.")
    print(f'CDI Markers for visits not Present in DESS:')
    for patient, visits in cdi.items():
        for visit, (start, end) in visits.items():
            try:
                preds_dess_volumes[patient][visit] = preds_dess_volumes[patient][visit][start:end, ...]

            except (KeyError,) as e:
                print(f"{patient}:{visit}, ", end='')
    print('')

    print(f"Calculating DESS volume metrics")
    for patient, visits in preds_dess_volumes.items():
        for visit, volume in visits.items():
            v = vol.mask(volume, voxel_size=0.365 * 0.456 * 0.7)
            if patient not in preds_dess_totals.keys():
                preds_dess_totals[patient] = [v, ]
            else:
                preds_dess_totals[patient].append(v)

    ################ Missing Data Check One ########################################################
    missing_iwfs = preds_dess_totals.keys() - preds_iwfs_totals.keys()
    missing_dess = preds_iwfs_totals.keys() - preds_dess_totals.keys()
    iwfs_dess_intersection = preds_dess_totals.keys() & preds_iwfs_totals.keys()
    print(f"> {len(missing_iwfs)} cases missing in IWFS, {len(missing_dess)} cases missing in DESS.")
    print(f"> {len(iwfs_dess_intersection)} usable cases, so far.")
    print("Missing IWFS Data: (Patients in DESS not in IWFS)")
    for p in sorted(missing_iwfs):
        print(f"{p} ", end='')
    print('')
    print("Missing DESS Data: (Patients in IWFS not in DESS)")
    for p in sorted(missing_dess):
        print(f"{p} ", end='')
    print('')
    #################################################################################################

    print(f"Calculating IWFS - DESS")
    # NOTE only uses vol[0], so ignores multiple visits!
    diff_iwfs_dess = {}  # Key: Patient, Val: Diff of Volumes
    for patient, iwfs_volumes in preds_iwfs_totals.items():
        assert len(iwfs_volumes) > 0
        if patient in preds_dess_totals.keys():
            assert len(preds_dess_totals[patient]) > 0
            diff_iwfs_dess[patient] = abs(iwfs_volumes[0] - preds_dess_totals[patient][0])

    print(f"Loading BML from {manual_bml_masks}")
    # Find Manual BML Mask Volumes
    manual_bml_series = files.read_image_series(manual_bml_masks, ends_with="mask.bmp")
    manual_bml_series = common.dictutils.slices_to_mask(manual_bml_series, threshold=0.5)
    manual_bml_volumes = common.dictutils.visit_to_volume(manual_bml_series)
    manual_bml_totals = {}  # Key: Patient, Val: List of Volumes

    print(f"Calculating BML volume metrics")
    for patient, visits in manual_bml_volumes.items():
        for visit, volume in visits.items():
            v = vol.mask(volume, voxel_size=0.357 * 0.511 * 3)
            if patient not in manual_bml_totals.keys():
                manual_bml_totals[patient] = [v, ]
            else:
                manual_bml_totals[patient].append(v)

    ################ Missing Data Check Two ########################################################
    missing_bml = diff_iwfs_dess.keys() - manual_bml_totals.keys()
    missing_preds = manual_bml_totals - diff_iwfs_dess.keys()
    bml_scans_intersection = diff_iwfs_dess.keys() & manual_bml_totals.keys()
    print(f"> {len(missing_bml)} patients in scans missing BML, {len(missing_preds)} cases in BML masks missing scan preds.")
    print(f"> {len(bml_scans_intersection) + len(missing_bml)} usable cases, total.")  # Note: Accounts for below
    print("Missing BML Data: (Patients in Preds Data without BML, Set to Zero)")
    for p in sorted(missing_bml):
        print(f"{p} ", end='')
        manual_bml_totals[p] = [0, ]  # Note: This sets patients without BML data to BML=0, assuming it's intentional.
    print('')
    print("Missing Bone Preds: (Patients in BML masks without Bone predictions present in both DESS *and* IWFS)")
    for p in sorted(missing_preds):
        print(f"{p} ", end='')
    print('')
    #################################################################################################

    print(f"Finding Pearson Correlation of IWFS and DESS")
    pearson_intersection = preds_iwfs_totals.keys() & preds_dess_totals.keys()
    pearson_x = []
    pearson_y = []
    for patient in pearson_intersection:
        pearson_x.append(next(iter(preds_iwfs_totals[patient])))
        pearson_y.append(next(iter(preds_dess_totals[patient])))

    pearson_x = np.array(pearson_x)
    pearson_y = np.array(pearson_y)
    r, p_val = scipy.stats.pearsonr(pearson_x, pearson_y)
    print(f"Pearson R: {r}\nP-Value: {p_val}")

    plt.scatter(pearson_x, pearson_y, alpha=0.7)
    plt.title("IWFS vs DESS Volume Measurements")
    plt.xlabel("IWFS Volume")
    plt.ylabel("DESS Volume")
    plt.figtext(0.99, 0.01, f"r = {r : .4f}", horizontalalignment='right')
    plt.show()

    print("Done.")

if __name__ == "__main__":
    main()


import pandas as pd
from mtcnn import MTCNN
import mtcnn
import numpy as np
import os
import glob
import cv2
import shutil
from pathlib import Path

def run(string_,id_):
  face_detector = MTCNN(min_face_size=25)

  face_count = 0
  #for path in glob.glob('test.mp4'):
    #print("Processing video ", path)
  video = cv2.VideoCapture(string_)
  break_temp = 0
  while True:

    ret, frame = video.read()
    # cv2.imshow('a',frame)
    if break_temp == 1 :
      break
    if ret == False:
      break
    faces = face_detector.detect_faces(frame)
    for face in faces:
      x,y,w,h = face['box']
      print(w,h)
      if w >= 77 and h >= 96:
        crop = frame[y:y+h,x:x+w,:]
        try:
          if not os.path.exists(str(id_)):
            os.mkdir(str(id_))
          else:
            pass
          # print('Writting to ',  + f'/{face_count}.jpg')
          cv2.imwrite(str(id_)+'/'+str(face_count)+'.jpg', crop)
          face_count += 1
          if face_count == 50 :
            break_temp = 1
            break
            print("done 100 image")

        except:
          print("Error on ", crop.shape)
    # cv2.waitKey(1)
  video.release()
# run("output1.mp4",122150051)
'''
for folder in FOLDER_LIST:
  if folder not in IGNORE_LIST:
    print(f"Extract faces from {folder}")
    face_count = 0
    for path in glob.glob(folder + '/*.mp4'):
      print("Processing video ", path)
      video = cv2.VideoCapture(path)
      while True:
        ret, frame = video.read()
        if ret == False:
          break
        faces = face_detector.detect_faces(frame)
        for face in faces:
          x,y,w,h = face['box']
          print(w,h)
          if w >= 77 and h >= 96:
            crop = frame[y:y+h,x:x+w,:]
            try:
              print('Writting to ', folder + f'/{face_count}.jpg')
              cv2.imwrite(folder + f'/{face_count}.jpg', crop)
              face_count += 1
            except:
              print("Error on ", crop.shape)

      video.release()
'''


from django.contrib import admin
from django.urls import path, include
from sis import views as sis_views

urlpatterns = [
    path('sis/', include('sis.urls')),
    path('student/', include('student.urls')),
    path("siteadmin/", admin.site.urls),
    path('accounts/', include('django.contrib.auth.urls')),
    path('schooladmin/', include('schooladmin.urls')),
    path('professor/', include('professor.urls')),
    path('', sis_views.index),
]


#Import all the libraries
import pandas as pd
import numpy as np
from sklearn import linear_model as model
import matplotlib.pyplot as plt

#read data from the dataset1.txt
dataframe = pd.read_csv('dataset1.txt')

x_values = dataframe[[0]]
y_values = dataframe[[1]]

#train model on data
regr = model.LinearRegression()
regr.fit(x_values, y_values)

# The coefficients and intercept:
print('Coefficients: ', regr.coef_)
print(regr.intercept_)

# The mean squared error
print('Mean squared error: %.2f ' % np.mean((regr.predict(x_values) - y_values) ** 2))
# Explained coefficient of determination score: 1 is perfect prediction
print('Coeff. determination score: %.2f' % regr.score(x_values, y_values))

dataframe['ypredicted'] = regr.predict(x_values)

#save result in file
filename = 'result.csv'
dataframe.to_csv(filename, index=False, encoding='utf-8')

#Visualize Results
plt.scatter(x_values, y_values)
plt.plot(x_values, regr.predict(x_values))
plt.xlabel('X')
plt.ylabel('Y')
plt.title('Simple Linear Regression')
plt.show()


# coding=utf-8
from global_test_case import GlobalTestCase as TestCase, popit_load_data
from subdomains.utils import reverse
from ..models import WriteItInstance, Message, Membership, Confirmation, Moderation
from ..views import MessageCreateForm, PerInstanceSearchForm
from contactos.models import Contact, ContactType
from popit.models import ApiInstance, Person
from django.utils.unittest import skipUnless
from datetime import datetime
from django.contrib.auth.models import User
from subdomains.tests import SubdomainTestMixin
from django.utils.translation import activate
from django.utils.translation import ugettext as _
from django.conf import settings

class InstanceTestCase(TestCase, SubdomainTestMixin):

    def setUp(self):
        super(InstanceTestCase,self).setUp()
        self.api_instance1 = ApiInstance.objects.all()[0]
        self.api_instance2 = ApiInstance.objects.all()[1]
        self.person1 = Person.objects.all()[0]

        self.owner = User.objects.all()[0]

    def test_create_instance(self):
        writeitinstance = WriteItInstance.objects.create(
            name='instance 1',
            slug='instance-1',
            owner=self.owner)
        self.assertTrue(writeitinstance.id)
        self.assertEquals(writeitinstance.name, 'instance 1')
        self.assertEquals(writeitinstance.slug, 'instance-1')
        self.assertEquals(writeitinstance.owner, self.owner)
        self.assertTrue(writeitinstance.allow_messages_using_form)
        self.assertFalse(writeitinstance.notify_owner_when_new_answer)
        self.assertTrue(writeitinstance.autoconfirm_api_messages)

    def test_owner_related_name(self):
        writeitinstance = WriteItInstance.objects.create(
            name='instance 1',
            slug='instance-1',

            owner=self.owner)

        self.assertIn(writeitinstance, self.owner.writeitinstances.all())

    def test_moderation_needed_in_all_messages(self):

        writeitinstance = WriteItInstance.objects.create(
            name='instance 1',
            slug='instance-1',
            moderation_needed_in_all_messages=False,
            owner=self.owner)

        self.assertTrue(writeitinstance)

    def test_instance_unicode(self):
        writeitinstance = WriteItInstance.objects.all()[0]
        self.assertEquals(writeitinstance.__unicode__() , writeitinstance.name)

    def test_instance_containning_several_messages(self):
        writeitinstance1 = WriteItInstance.objects.create(name='instance 1', slug='instance-1', owner=self.owner)
        writeitinstance2 = WriteItInstance.objects.create(name='instance 2', slug='instance-2', owner=self.owner)
        message1 = Message.objects.create(content='Content 1', subject='Subject 1', writeitinstance = writeitinstance1, persons=[self.person1])
        message2 = Message.objects.create(content='Content 2', subject='Subject 2', writeitinstance = writeitinstance1, persons=[self.person1])
        message3 = Message.objects.create(content='Content 3', subject='Subject 3', writeitinstance = writeitinstance2, persons=[self.person1])
        self.assertEquals(writeitinstance1.message_set.count(),2)
        self.assertEquals(message1.writeitinstance, writeitinstance1)
        self.assertEquals(message2.writeitinstance, writeitinstance1)
        self.assertEquals(writeitinstance2.message_set.count(),1)
        self.assertEquals(message3.writeitinstance, writeitinstance2)

    def test_get_absolute_url(self):
        writeitinstance1 = WriteItInstance.objects.all()[0]
        expected_url = reverse('instance_detail',
            subdomain=writeitinstance1.slug)

        self.assertEquals(expected_url, writeitinstance1.get_absolute_url())

    def test_get_absolute_url_i18n(self):
        activate("es")
        writeitinstance1 = WriteItInstance.objects.all()[0]
        self.assertTrue(writeitinstance1.get_absolute_url().endswith('/es/'))
        host = self.get_host_for_subdomain(writeitinstance1.slug)
        response = self.client.get(writeitinstance1.get_absolute_url(), HTTP_HOST=host)
        self.assertEquals(response.status_code, 200)
        self.assertTemplateUsed(response, 'nuntium/instance_detail.html')

    def test_get_non_existing_instance(self):
        url = reverse('instance_detail',
            subdomain="non-existing-slug")
        host = self.get_host_for_subdomain("non-existing-slug")
        response = self.client.get(url, HTTP_HOST=host)
        self.assertEquals(response.status_code, 404)

    def test_membership(self):
        writeitinstance = WriteItInstance.objects.create(name='instance 1', slug='instance-1', owner=self.owner)

        Membership.objects.create(writeitinstance=writeitinstance, person=self.person1)
        self.assertEquals(writeitinstance.persons.get(id=self.person1.id), self.person1)
        self.assertEquals(self.person1.writeit_instances.get(id=writeitinstance.id), writeitinstance)

    @skipUnless(settings.LOCAL_POPIT, "No local popit running")
    def test_create_an_instance_and_load_persons_from_an_api(self):
        # We have a popit running locally using the
        # start_local_popit_api.bash script
        popit_load_data()
        #loading data into the popit-api
        writeitinstance = WriteItInstance.objects.create(name='instance 1', slug='instance-1', owner=self.owner)

        writeitinstance.load_persons_from_a_popit_api(settings.TEST_POPIT_API_URL)

        self.assertEquals(writeitinstance.persons.all().count(), 2)

        raton = Person.objects.get(name='Ratón Inteligente')
        fiera = Person.objects.get(name="Fiera Feroz")

        self.assertIn(raton, [r for r in writeitinstance.persons.all()])
        self.assertIn(fiera, [r for r in writeitinstance.persons.all()])

class InstanceDetailView(TestCase, SubdomainTestMixin):
    def setUp(self):
        super(InstanceDetailView, self).setUp()
        self.api_instance1 = ApiInstance.objects.all()[0]
        self.api_instance2 = ApiInstance.objects.all()[1]
        self.person1 = Person.objects.all()[0]
        self.writeitinstance1 = WriteItInstance.objects.all()[0]
        self.url = self.writeitinstance1.get_absolute_url()
        self.host = self.get_host_for_subdomain(self.writeitinstance1.slug)

    def test_detail_instance_view(self):
        #I'm removing this because it has been already tested
        #self.assertTrue(url)
        response = self.client.get(self.url, HTTP_HOST=self.host)
        self.assertTemplateUsed(response, 'nuntium/instance_detail.html')
        self.assertEquals(response.context['writeitinstance'], self.writeitinstance1)
        self.assertTrue(response.context['form'])
        self.assertTrue(isinstance(response.context['form'],MessageCreateForm))
        self.assertEquals(response.status_code, 200)

    def test_instance_view_has_a_search_form(self):
        response = self.client.get(self.url, HTTP_HOST=self.host)

        self.assertIn('search_form', response.context)

        self.assertIsInstance(response.context['search_form'], PerInstanceSearchForm)

        self.assertEquals(response.context['search_form'].writeitinstance, self.writeitinstance1)

    def test_list_only_public_messages(self):
        private_message = Message.objects.create(content='Content 1', subject='a private message', writeitinstance = self.writeitinstance1, persons=[self.person1], public=False)
        response = self.client.get(self.url, HTTP_HOST=self.host)

        self.assertTrue('public_messages' in response.context)
        self.assertTrue(private_message not in response.context['public_messages'])

    def test_in_moderation_needed_instances_does_not_show_a_confirmated_but_not_moderated(self):
        self.writeitinstance1.moderation_needed_in_all_messages = True

        self.writeitinstance1.save()
        message = Message.objects.create(
            content='Content 3',
            subject='Subject 3',
            writeitinstance = self.writeitinstance1,
            confirmated = True,
            persons=[self.person1]
            )

        confirmation = Confirmation.objects.create(message=message)
        self.client.get(confirmation.get_absolute_url())

        #ok it is now confirmated but it is not moderated

        url = self.writeitinstance1.get_absolute_url()

        response = self.client.get(self.url, HTTP_HOST=self.host)

        self.assertNotIn(message, response.context['public_messages'])

    def test_list_only_confirmed_and_public_messages(self):
        message1 = self.writeitinstance1.message_set.all()[0]
        message2 = self.writeitinstance1.message_set.all()[1]
        message3 = Message.objects.create(
            content='Content 3',
            subject='Subject 3',
            writeitinstance = self.writeitinstance1,
            confirmated = True,
            persons=[self.person1]
            )
        private_message = Message.objects.create(content='Content 1',
            subject='a private message',
            writeitinstance = self.writeitinstance1,
            persons=[self.person1],
            confirmated = True,
            public=False)

        confirmation_for_message2 = Confirmation.objects.create(message=message2)
        self.client.get(confirmation_for_message2.get_absolute_url())

        #now i need to moderate this
        self.client.get(private_message.moderation.get_success_url())

        confirmation_for_private_message = Confirmation.objects.create(message=private_message)
        self.client.get(reverse('confirm', kwargs={'slug':confirmation_for_private_message.key}))

        url = self.writeitinstance1.get_absolute_url()

        response = self.client.get(self.url, HTTP_HOST=self.host)

        #message1 is not confirmed so it should not be in the list
        #private_message is not in the list either
        #only message 2 is in the list because is public and confirmed

        self.assertIn(message2, response.context['public_messages'])
        self.assertNotIn(message1, response.context['public_messages'])
        self.assertIn(message3, response.context['public_messages'])
        self.assertNotIn(private_message, response.context["public_messages"])

    def test_message_creation_on_post_form(self):

        #spanish
        data = {
        'author_email':u'falvarez@votainteligente.cl',
        'author_name':u'feli',
        'subject':u'Fiera no está',
        'content':u'¿Dónde está Fiera Feroz? en la playa?',
        'persons': [self.person1.id]
        }
        response = self.client.post(self.url, data, follow=True, HTTP_HOST=self.host)
        self.assertEquals(response.status_code, 200)
        new_messages = Message.objects.filter(subject='Fiera no está')
        self.assertTrue(new_messages.count()>0)
        self.assertEquals(len(response.context["form"].errors), 0)

    def test_I_get_an_acknoledgement_for_creating_a_message(self):
        #spanish
        data = {
        'subject':u'Fiera no está',
        'author_email':u'falvarez@votainteligente.cl',
        'author_name':u'feli',
        'public':True,
        'content':u'¿Dónde está Fiera Feroz? en la playa?',
        'persons': [self.person1.id]
        }

        response = self.client.post(self.url, data, follow=True, HTTP_HOST=self.host)
        self.assertEquals(response.status_code, 200)
        expected_acknoledgments = _("Thanks for submitting your message, please check your email and click on the confirmation link")

        self.assertContains(response, expected_acknoledgments)

        all_messages, all_retrieved = response.context["messages"]._get()

        self.assertEquals(len(all_messages), 1)
        self.assertEquals(all_messages[0].__str__(), expected_acknoledgments)

    def test_after_the_creation_of_a_message_it_redirects(self):
        data = {
        'subject':u'Fiera no está',
        'content':u'¿Dónde está Fiera Feroz? en la playa?',
        'author_name':u"Felipe",
        'author_email':u"falvarez@votainteligente.cl",
        'persons': [self.person1.id]
        }
        url = self.writeitinstance1.get_absolute_url()
        response = self.client.post(self.url, data, HTTP_HOST=self.host)

        self.assertRedirects(response, url)

    def test_flash_message_after_the_creation_of_a_private_message(self):
        data = {
            'subject':u'Fiera no está',
            'content':u'¿Dónde está Fiera Feroz? en la playa?',
            'author_name':u"Felipe",
            'public': False,
            'author_email':u"falvarez@votainteligente.cl",
            'persons': [self.person1.id]
        }

        url = self.writeitinstance1.get_absolute_url()
        response = self.client.post(self.url, data, follow=True, HTTP_HOST=self.host)

        expected_acknoledgments = _("Thanks for submitting your message, please check your email and click on the confirmation link, after that your message will be waiting form moderation")

        self.assertContains(response, expected_acknoledgments)

    def test_if_the_instance_needs_moderation_in_all_messages(self):
        self.writeitinstance1.moderation_needed_in_all_messages = True
        self.writeitinstance1.save()
        data = {
            'subject':u'Fiera no está',
            'content':u'¿Dónde está Fiera Feroz? en la playa?',
            'author_name':u"Felipe",
            'public': True,
            'author_email':u"falvarez@votainteligente.cl",
            'persons': [self.person1.id]
        }

        url = self.writeitinstance1.get_absolute_url()
        response = self.client.post(self.url, data, follow=True, HTTP_HOST=self.host)

        expected_acknoledgments = _("Thanks for submitting your message, please check your email and click on the confirmation link, after that your message will be waiting form moderation")

        self.assertContains(response, expected_acknoledgments)


"""
The solver file for Adam Smith's sliding puzzle.
This file uses A* to solve the 15 sliding puzzle and those with less elements.
@author Benjamin Scarbrough
@version 9/29/19
"""

"""
Imports.
"""
import sys
import heapq
import xxhash
import numpy as np
from itertools import chain

# def main():
    # """
    # A main method used for testing.
    # Uncomment to use.
    # """
    # solve([[6,5,2,3],[0,7,11,4],[9,1,10,8],[15,14,13,12]]) # Square Puzzle
    # solve([[1,2,3,4],[0,5,6,7],[9,10,11,8]]) # Easy Puzzle
    # solve([[5,4],[3,0],[1,2]])
    # solve([[0,3],[2,1]])
    # solve([[2,1,3,4],[5,6,7,8],[9,10,11,0]]) #Impossible
    # solve([[10,5,3,7],[2,9,8,4],[11,1,6,0]])
    # solve([[1,8,2],[0,4,3],[7,6,5]])
    # solve([[7,5,10],[11,2,3],[6,4,1],[9,8,0]])
    # solve([[2,6,5,4],[7,0,9,11],[1,10,3,15],[13,14,12,8]])

def solve(puzzle):
    """
    This is a function to solve the given puzzle. This takes a list as input.
    """
    print("Solving...")
    array_puzzle = np.asarray(puzzle)
    array_puzzle.flags.writeable = False # Turn off writable flags to prevent data being ovewritten accidentally.
    goal_state = __generate_goal(len(array_puzzle[0]), len(array_puzzle))

    flat_puzzle = list(chain.from_iterable(puzzle)) # Flatten the list

    # If the puzzle doesn't contain 0, exit.
    try:
        flat_puzzle.remove(0) # Remove 0 from the list
    except:
        print("All puzzles must include an open tile (0).")
        return None

    inversions = __count_inversions(flat_puzzle) # Count the inversions

    # width = len(array_puzzle[0]) # Get the width of the puzzle (columns)
    # length = len(array_puzzle) # Get the length of the puzzle (rows)

    oddEven = __odd_or_even(len(array_puzzle[0])) # Determine if the width is odd or even.
    start_position = __find_start(array_puzzle) # Find the start position's row
    solvable = __is_solvable(oddEven, inversions, len(array_puzzle), start_position) # Cleck if the puzzle is solvable.

    # If the puzzle is not solvable, return None.
    if(solvable == "None"):
        return None

    # If we cannot calculate a* (for example the given values are not all in sequential order (1-5) 4 is replaced by 6 (1,2,3,5,6))
    try:
        return __a_star(array_puzzle, goal_state)
    except:
        print("Please make sure there are no duplicate or skipped inputs.")
        return None

        # This code was used in testing to print out the string.
    # solved = __a_star(array_puzzle, goal_state)
    # Return the moves needed to complete the puzzle.
    # return print(str(__build_string(solved)) + " (" + str(len(solved)) + ")")

def __a_star(puzzle, goal):
    """
    This function takes a puzzle and its solved state as input, then finds the a best way to solve it.
    """
    # Make the goal state.
    goal_state = State(goal, 0, '', goal)
    # Make the first state.
    init_state = State(puzzle, 0, '', goal)

    # Make all the lists.
    open_list = list()
    temp_open_list = set()
    closed_list = set()

    # Push initial state to open list.
    heapq.heappush(open_list, init_state)
    temp_open_list.add(init_state)

    # While elements exist in the open list, loop.
    while open_list:
        # Pop the node and add it to the closed list.
        popped_node = heapq.heappop(open_list)
        list_states = popped_node._State__get_neighbors(goal) # Must add _State in front to call private method.
        temp_open_list.remove(popped_node)
        closed_list.add(popped_node)

        # If state is goal, return the path.
        if(popped_node == goal_state):
            return popped_node._State__get_path() # Must add _State in front to call private method.

        # Check all the child states (neighbors).
        for state in list_states:
            if state in temp_open_list:
                continue
            elif state in closed_list:
                continue
            else:
                # Combine the paths.
                state._State__combine_path(popped_node) # Must add _State in front to call private method.
                # Push the new state to the open list.
                heapq.heappush(open_list, state)
                temp_open_list.add(state)

    # Check for errors.
    if state != goal_state:
        sys.exit("The OPEN list is empty.")

def __count_inversions(puzzle):
    """
    This function counts the number of inversions.
    """
    puzzleLength = len(puzzle)
    count = 0
    for i in range(puzzleLength):
        for j in range(i + 1, puzzleLength):
            if(puzzle[i] > puzzle[j]):
                count += 1
    return count

def __odd_or_even(number):
    """
    This function returns 0 for even, and 1 for odd.
    """
    if(number % 2) == 0:
        return 0
    else:
        return 1

def __find_start(puzzle):
    """
    Find the row with the start point. The start point is defined as 0.
    [[1,2,3,4], [5,6,0,7]] would return 1.
    """
    for i in range(len(puzzle)):
        for j in range(len(puzzle[0])):
            if puzzle[i][j] == 0:
                return i
    return 0

def __is_solvable(evenOrOdd, inversions, rows, start):
    """
    Check if the puzzle is solvable.
    """
    if(evenOrOdd == 0):
        distance = (rows - 1) - start # calculate the distance of the start point from the bottom.
        solvable = inversions + distance
        if(__odd_or_even(solvable) != 0):
            return "None"
    if(evenOrOdd == 1 and __odd_or_even(inversions)!= 0):
        return "None"
    return "Ok"

def __generate_goal(width, length):
    """
    Generates the goal state.
    """
    goal = np.arange(1, ((width * length)+1)).reshape(length, width)
    goal[length - 1][width - 1] = 0
    return goal

    # This was the string builder method for the returned string.
# def __build_string(a_string):
#     """
#     A function to build the returned string.
#     """
#     string = ("[")
#     for i in range(len(a_string) -1):
#         string += ('\'')
#         string += (a_string[i])
#         string += ('\'')
#         string += (',')
#     string += ('\'')
#     string += (a_string[len(a_string) -1])
#     string += ('\'')
#     string += ("]")
#     return string

# The state class.
class State():
    """
    This is a class that determines the state of a board.
    """

    def __init__(self, puzzle, g, path, goal):
        """
        The constructor of the state class. Set everything up.
        """
        self.puzzle = puzzle
        self.puzzle.flags.writeable = False # Turn off writable flags to prevent data being ovewritten accidentally.
        self.g = g
        self.h = self.__cost_to_goal(goal)
        self.path = path

    def __cost_to_goal(self, goal_state):
        """
        A method that calculates the cost to go from the state to goal.
        The distance of every start node to its goal position, w/o the gap (0).
        """
        cost = 0
        for i in range(len(goal_state) * len(goal_state[0])):
            if(i != 0):
                pos_goal = self.__get_position(i, goal_state)
                pos_current = self.__get_position(i, self.puzzle)
                cost += self.__manhattan(pos_current[0], pos_current[1], pos_goal[0], pos_goal[1])
        return cost

    def __combine_path(self, other):
        """
        A method used to combine the paths of two states.
        """
        self.path = other.path + self.path

    def __get_path(self):
        """
        A method to get the path of a state.
        """
        return self.path

    def __manhattan(self, x_state, y_state, x_goal, y_goal):
        """
        Calculate the manhattan distance.
        """
        distance = (abs(x_state - x_goal) + abs(y_state - y_goal))
        return distance

    def __get_position(self, value, state):
        """
        Get the coordinates of value in the state.
        """
        coords = np.argwhere(state == value).flatten()
        return coords

    def __swap(self, x1, y1, x2, y2):
        """
        This is a method used to swap elements of the puzzle.
        """
        temp = self.puzzle.copy()
        temp[x1, y1] = temp[x2, y2]
        temp[x2, y2] = self.puzzle[x1, y1]
        return temp

    def __get_neighbors(self, goal):
        """
        This is a method to get the neighbors of the state.
        """
        neighbors = set()
        start = self.__get_position(0, self.puzzle)
            # start_x = start[0]
            # start_y = start[1]
        # Get the below neighbor.
        if(start[0] - 1 >= 0):
            temp = self.__swap(start[0], start[1], start[0] - 1, start[1])
            neighbors.add(State(temp, self.g + 1, 'D', goal))
        # Get the above neighbor
        if(start[0] + 1 <= len(self.puzzle) -1):
            temp = self.__swap(start[0], start[1], start[0] + 1, start[1])
            neighbors.add(State(temp, self.g + 1, 'U', goal))
        # Get the right neighbor
        if(start[1] - 1 >= 0):
            temp = self.__swap(start[0], start[1], start[0], start[1] - 1)
            neighbors.add(State(temp, self.g + 1, 'R', goal))
        # Get the left neighbor
        if(start[1] + 1 <= len(self.puzzle[0]) -1):
            temp = self.__swap(start[0], start[1], start[0], start[1] + 1)
            neighbors.add(State(temp, self.g + 1, 'L', goal))

        return neighbors

    def __lt__(self, other):
        """
        A magic less than method. Compare f(x) = g(x) + h(x) values.
        """
        f_self = self.g + self.h
        f_other = other.g + other.h
        if(f_self < f_other):
            return True
        return False

    def __hash__(self):
        """
        A magic hash method that uses xxhash to speed things up.
        """
        x = xxhash.xxh64()
        x.update(self.puzzle)
        return x.intdigest()

    def __eq__(self, other):
        """
        A magic equals method used for comparing states.
        """
        for i in range(len(self.puzzle)):
            for j in range(len(self.puzzle[0])):
                if(self.puzzle[i][j] != other.puzzle[i][j]):
                    return False
        return True

    def __str__(self):
        """
        A magic string function.
        """
        value = str(self.puzzle) + str(" ") + str(self.g) + str(" ") + str(self.h)
        return value


import datetime
import glob
import os
import subprocess

def run_silent(command):
    toto = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    result = toto.stdout.readlines()

batch = '''pyinstaller -n prism.exe --noconfirm --icon=logos.ico --log-level=INFO --clean --onefile -w main.py '''

run_silent(batch)

print('Deleting ver files')
path_to_build = 'z:\\source\\logos6\\dist\\'

fileList = glob.glob(path_to_build + '*.ver')
# Iterate over the list of filepaths & remove each file.
for filePath in fileList:
    try:
        os.remove(filePath)
    except:
        print("Error while deleting file : ", filePath)
file_name_version = datetime.datetime.now().strftime("%d_%m_%Y-%H_%M")
fo = open(path_to_build + file_name_version + '.ver', "w")
fo.write("version " + file_name_version)

# Close opend file
fo.close()


# Import CherryPy global namespace
import cherrypy
import copy
import urllib
import urllib2
import urlparse
import os.path
import json

import conf.data
import httpls_client
import shaper

import conf

class DriplsController(object):
    '''DripLS Controller'''

    def on_start(self):
        pass

    def on_stop(self):
        pass

    def on_server_start(self):
        pass

    @cherrypy.expose
    def ostatus(self, s=None):
        """ Throw with a specified status """

        raise cherrypy.HTTPError(int(s), message="Custom error raised : {0}".format(s))

    @cherrypy.expose
    def cache_info(self, cid=None, r=None, tag=None, **kwargs):
        """ Cache and rewrite a m3u8 """

        info = self.cache_stream(cid, r, tag, kwargs)

        return json.dumps(info, sort_keys=True, indent=4)

    @cherrypy.expose
    def updatesegment(self, url, new_action):
        """ Update a previously shaped segment on the fly """

        shaper.update_shaped_segment(url, new_action)

        return "OK"

    @cherrypy.expose
    def master_m3u8(self, cid=None, r=None, tag=None, **kwargs):
        """ Cache and stream back a shaped playlist """

        cached_cid = self.cache_stream(cid, r, tag, kwargs)["id"]

        with open("{0}/playlists/m_{1}.m3u8".format(shaper.shaper_store_path, cached_cid), "r") as pf:
            master_content = pf.read()

        # return the rewritten master
        cherrypy.response.headers['Content-Type'] = "application/vnd.apple.mpegurl"
        cherrypy.response.headers['Content-Disposition'] = "inline; filename={0}.m3u8".format(cid)

        return master_content

    @cherrypy.expose
    def playlist_m3u8(self, p=None, **kwargs):
        """ Stream back a cached playlist """

        with open("{0}/playlists/{1}.m3u8".format(shaper.shaper_store_path,p), "r") as pf:
            playlist_content = pf.read()

        cherrypy.response.headers['Content-Type'] = "application/vnd.apple.mpegurl"
        cherrypy.response.headers['Content-Disposition'] = "inline; filename={0}.m3u8".format(p)

        return playlist_content

    @cherrypy.expose
    def tag_m3u8(self, tag=None, **kwargs):
        """ Do the shaping off of a pre-made tag """

        with open("{0}/playlists/tag_{1}".format(shaper.shaper_store_path, tag) , "r") as pf:
            tag_qs = pf.read()

        #add old keys
        tag_args = urlparse.parse_qs(tag_qs)
        for key in tag_args:
            tag_args[key] = tag_args[key][0]

        #add any new kes that we might have gotten(some might override old keys)
        for key in kwargs:
            tag_args[key] = kwargs[key]

        #run master with the tag args
        return self.master_m3u8(**tag_args);

    def cache_stream(self, cid=None, r=None, tag=None, kwargs=None):
        """ Perform the actual caching and shaping  of the stream """

        rules = shaper.parse_rules(r)

        seeded_content_id = conf.common.get_seeded_cid(cid)
        master_playlist = conf.data.provider.pull_master_m3u8(cid, kwargs)

        info = shaper.cache_and_shape(master_playlist, seeded_content_id, rules)
        info["url"] = conf.common.get_final_url("playlist.m3u8","p=m_{0}".format(seeded_content_id))

        # if we have a tag, store
        if tag:
            self.store_tag(cid, r, tag, kwargs)

        return info

    def store_tag(self, cid, r, tag, kwargs):
        """ Store all arguments recieved on the url as the associated tag """
        tag_args = conf.data.provider.get_tag_kwargs(kwargs)
        tag_args["cid"] = cid

        if r:
            tag_args["r"] = r

        with open("{0}/playlists/tag_{1}".format(shaper.shaper_store_path, tag), "w") as pf:
            pf.write("{0}".format(urllib.urlencode(tag_args)))

conf.dripls_main_site_url = conf.app['root_url']
root = DriplsController()

current_path = os.path.dirname(os.path.abspath(__file__))

app_config = {
    '/playlists': {
         'tools.staticdir.on': True,
         'tools.staticdir.dir': os.path.join(shaper.shaper_store_path, 'playlists'),
         'tools.staticdir.content_types': {
             'ts': 'video/mp2t',
             'm3u8': 'application/vnd.apple.mpegurl'
         }
    }
}

cherrypy.config.update({
    'log.error_file': conf.error_log,
    'log.screen': True
})

app = cherrypy.tree.mount(root, '/', app_config)


# -*- coding: utf-8 -*-
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
"""
Example DAG using BigQueryToBigQueryOperator.
"""

import airflow
from airflow.gcp.operators.bigquery import BigQueryTableDeleteOperator
from airflow.models import DAG
from airflow.operators.bigquery_to_bigquery import BigQueryToBigQueryOperator

args = {
    'owner': 'Airflow',
    'start_date': airflow.utils.dates.days_ago(2)
}

with DAG(
    dag_id='example_bigquery_to_bigquery',
    default_args=args,
    schedule_interval=None,
) as dag:
    # [START howto_operator_bq_to_bq]
    copy_table = BigQueryToBigQueryOperator(
        task_id='copy_table',
        source_project_dataset_tables='bigquery-public-data.baseball.schedules',
        destination_project_dataset_table='bigquery-public-data.test.schedules',
        write_disposition='WRITE_EMPTY',
        create_disposition='CREATE_IF_NEEDED',
        bigquery_conn_id='bigquery_default')
    # [END howto_operator_bq_to_bq]

    delete_test_dataset = BigQueryTableDeleteOperator(
        task_id='delete_test_dataset',
        deletion_dataset_table='bigquery-public-data.test.schedules')


""" modules/api/__init__.py """

from __future__ import absolute_import

import os

from flask import Flask

from src import common
from src import config
from src import constants
from src import utils

APP = Flask(os.environ['CURRENT_MODULE_ID'])

# if os.getenv('FLASK_CONF') == 'TEST':
#     APP.config.from_object('wizy.settings.Testing')

# elif 'SERVER_SOFTWARE' in os.environ and os.environ['SERVER_SOFTWARE'].startswith('Dev'):
#     # Development settings
#     APP.config.from_object('wizy.settings.Development')

# else:
#     APP.config.from_object('wizy.settings.Production')

APP.jinja_env.add_extension('jinja2.ext.loopcontrols')
APP.secret_key = config.APP_SECRET_KEY

from . import routes

SOURCE_ID_PREFIX = 'API_MAIN_'

def catch_secured_route_more(path):
    """ Returns error json for invalid calls """

    source_id = SOURCE_ID_PREFIX + 'catch_secured_route_more'

    if path.startswith('api'):
        route_type = 'API'
    elif path.startswith('admin'):
        route_type = 'admin'
    else:
        route_type = 'generic'

    response_code = 404
    response_message = 'Invalid {} route'.format(route_type)
    exception_prefix = constants.EXCEPTION_CODE_TYPE_NOT_FOUND
    # if response_code == 401:
    #     exception_prefix = constants.EXCEPTION_CODE_TYPE_UNAUTHORIZED
    #     response_message = 'Unauthorized'
    # elif response_code == 403:
    #     exception_prefix = constants.EXCEPTION_CODE_TYPE_FORBIDDEN
    #     response_message = 'No permission to access this path'

    common.log([{
        '_parse': True,
        'pattern': '{},{} Exception: {}{}',
        'values': [
            source_id, SOURCE_ID_PREFIX,
            exception_prefix, common.EXCEPTION_CODE_SUFFIX
        ]
    }])
    return utils.format_error(
        response_code, response_message
    ), response_code


import os
import advertools as adv
import pandas as pd
from sklearn import svm
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics import classification_report
from sklearn.model_selection import train_test_split

from server.tweet_handling.tweet_filtering import FilteringMethod
from _pickle import load, dump

class DamageTweetFM(FilteringMethod):
    """
    used to check if a tweet talks about an earthquake happening now or not
    using sentiment analysis
    """

    def __init__(self, get_existing=True):
        """
        checks if a SVM and a corresponding vectorizer exists.
        if so it loads their states
        otherwise it initializes two new one
        """
        self.classifier_path = 'server/tweet_handling/DamageTweetFM' \
                               '/DamageTweetFM_state/classifier.pkl '
        self.vectorizer_path = 'server/tweet_handling/DamageTweetFM' \
                               '/DamageTweetFM_state/vectorizer.pkl '
        if get_existing and \
                os.path.isfile(self.classifier_path) and \
                os.path.isfile(self.vectorizer_path):

            with open(self.classifier_path, 'rb') as fid:
                self.classifier = load(fid)

            with open(self.vectorizer_path, 'rb') as fid:
                self.vectorizer = load(fid)
        else:
            stop_words = sorted(adv.stopwords['italian'])
            stop_words.append('terremoto')
            self.classifier = svm.SVC(kernel='rbf', C=5.0, gamma='scale')
            self.vectorizer = TfidfVectorizer(min_df=0.00001,
                                              max_df=0.9,
                                              stop_words=stop_words,
                                              sublinear_tf=True,
                                              use_idf=True)

    def train(self, train_data: pd.DataFrame, save_to_file=False):
        '''
        @param train_data: pandas csv with labels 'Content' (tweet), 'Label'
        @param save_to_file: bool
        @return:
        '''
        train_vectors = self.vectorizer.fit_transform(train_data['Content'])
        self.classifier.fit(train_vectors, train_data['Label'])
        if save_to_file:
            with open(self.classifier_path, 'wb') as fid:
                dump(self.classifier, fid)
            with open(self.vectorizer_path, 'wb') as fid:
                dump(self.vectorizer, fid)

    def predict(self, data: pd.DataFrame):
        '''

        @param data: pandas csv with labels 'Content' (tweet text), 'Label'
        @return: array of labels
        '''
        test_vectors = self.vectorizer.transform(data['Content'])
        labels = self.classifier.predict(test_vectors)
        return labels

if __name__ == "__main__":
    '''
    execute this to train a new classifier
    '''
    data = pd.read_csv("server/tweet_handling/DamageTweetFM/DamageTweetFM_dataset.csv")

    train_data, test_data = train_test_split(data, test_size=0.1)

    detector = DamageTweetFM(get_existing=False)
    detector.train(train_data=train_data, save_to_file=True)
    predictions = detector.predict(test_data)
    report = classification_report(test_data['Label'], predictions, output_dict=True)
    print('positive: ', report['pos'])
    print('negative: ', report['neg'])
    texts = ['ha fatto il terremoto', 'terremoto in politica',
             'Scossa: è crollato un ponte davanti ai miei occhi #terremoto']
    df = pd.DataFrame(texts, columns=['Content'])
    prediction = detector.predict(df)
    print()
    print(prediction)

    # print(detector.vectorizer.get_feature_names())


import flask
from ec import *
app = flask.Flask(__name__)

@app.route('/getCourse/<query>/<quarter>')
def hello_world(query, quarter):
    courses = getCourseInfo("2021-2022", query, quarter)

    course_schedule = None
    ret = None
    for course in courses:
        curr = f'{course.subject} {course.code}'

        if curr  == query:
            #found course, get correct section
            for section in course.sections:
                #check for lec component and correct quarter
                if section.component == "LEC" and section.term.split(" ")[1] == quarter:
                    course_schedule = section.schedules[0]

                    ret = {
                        "response": {
                            "courseCode": f'{course.subject} {course.code}',
                            "courseName": str(course.title),
                            "schedule": str(course_schedule),
                            "minUnits": str(course.units_min),
                            "maxUnits": str(course.units_max)
                        }
                    }
    if ret is None:
        status_code = app.make_response(rv=({"response": f"No offering for {query} in {quarter}"}, 404, {}))
        return status_code
    return app.make_response(rv=(ret, 200, {}))

if __name__ == '__main__':
    app.run(port=5000)


from scipy import misc
import numpy as np
import tensorflow as tf
import random
import matplotlib.pyplot as plt
import matplotlib as mp
import scipy.misc

# --------------------------------------------------
# setup

def weight_variable(shape):
    '''
    Initialize weights
    :param shape: shape of weights, e.g. [w, h ,Cin, Cout] where
    w: width of the filters
    h: height of the filters
    Cin: the number of the channels of the filters
    Cout: the number of filters
    :return: a tensor variable for weights with initial values
    '''

    # IMPLEMENT YOUR WEIGHT_VARIABLE HERE
    W = tf.Variable(tf.random_normal(shape))
    return W

def bias_variable(shape):
    '''
    Initialize biases
    :param shape: shape of biases, e.g. [Cout] where
    Cout: the number of filters
    :return: a tensor variable for biases with initial values
    '''

    # IMPLEMENT YOUR BIAS_VARIABLE HERE
    b = tf.Variable(tf.random_normal(shape))
    return b

def conv2d(x, W):
    '''
    Perform 2-D convolution
    :param x: input tensor of size [N, W, H, Cin] where
    N: the number of images
    W: width of images
    H: height of images
    Cin: the number of channels of images
    :param W: weight tensor [w, h, Cin, Cout]
    w: width of the filters
    h: height of the filters
    Cin: the number of the channels of the filters = the number of channels of images
    Cout: the number of filters
    :return: a tensor of features extracted by the filters, a.k.a. the results after convolution
    '''

    # IMPLEMENT YOUR CONV2D HERE
    h_conv = tf.nn.conv2d(x, W)

    return h_conv

def max_pool_2x2(x):
    '''
    Perform non-overlapping 2-D maxpooling on 2x2 regions in the input data
    :param x: input data
    :return: the results of maxpooling (max-marginalized + downsampling)
    '''

    # IMPLEMENT YOUR MAX_POOL_2X2 HERE
    h_max = tf.nn.max_pool2d(x)

    return h_max

ntrain =  1000# per class
ntest =  100# per class
nclass =  10# number of classes
imsize = 28 #each image is gray scale 28*28
nchannels = 1 #single color(gray)
batchsize = 10 #arbitrary number

Train = np.zeros((ntrain*nclass,imsize,imsize,nchannels))
Test = np.zeros((ntest*nclass,imsize,imsize,nchannels))
LTrain = np.zeros((ntrain*nclass,nclass))
LTest = np.zeros((ntest*nclass,nclass))

itrain = -1
itest = -1
for iclass in range(0, nclass):
    for isample in range(0, ntrain):
        path = './CIFAR10/Train/%d/Image%05d.png' % (iclass,isample)
        im = misc.imread(path); # 28 by 28
        im = im.astype(float)/255
        itrain += 1
        Train[itrain,:,:,0] = im
        LTrain[itrain,iclass] = 1 # 1-hot lable
    for isample in range(0, ntest):
        path = './CIFAR10/Test/%d/Image%05d.png' % (iclass,isample)
        im = misc.imread(path); # 28 by 28
        im = im.astype(float)/255
        itest += 1
        Test[itest,:,:,0] = im
        LTest[itest,iclass] = 1 # 1-hot lable

sess = tf.InteractiveSession()
#sess = tf.Session()

#tf variable for the data, remember shape is [None, width, height, numberOfChannels]
tf_data = tf.placeholder(tf.float32, [None, 28, 28, 1])

#tf variable for labels
tf_labels = tf.placeholder(tf.float32, [None, 10])

# --------------------------------------------------
# model
#create your model

"Convolutional layer with kernel 5*5 and 32 filters followed by ReLU"
W_conv1 = weight_variable([5, 5, 1, 32])
b_conv1 = bias_variable([32])
h_conv1 = tf.nn.relu(conv2d(tf_data, W_conv1) + b_conv1)

"Max Pooling Layer subsampling by 2"
h_pool1 = max_pool_2x2(h_conv1)

"Convolutional layer with kernel 5*5*32 and 64 filters followed by ReLU"
W_conv2 = weight_variable([5, 5, 32, 64])
b_conv2 = bias_variable([64])
h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2) + b_conv2)

"Max Pooling layer subsampling by 2"
h_pool2 = max_pool_2x2(h_conv2)

"Fully Connected layer with input 7*7*64 and output 1024"
W_fc1 = weight_variable([7 * 7 * 64, 1024])
b_fc1 = bias_variable([1024])
h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1)

"Fully Connected Layer with input 1024 and output 10"
W_fc2 = weight_variable([1024, 10])
b_fc2 = bias_variable([10])

"Softmax layer"
y = tf.nn.softmax(tf.matmul(h_fc1, W_fc2) + b_fc2, name='y')

# --------------------------------------------------
# loss
#set up the loss, optimization, evaluation, and accuracy
cross_entropy = tf.reduce_mean(-tf.reduce_sum(y_ * tf.log(y), reduction_indices=[1]))
train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)
correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32), name='accuracy')

# --------------------------------------------------
# optimization

sess.run(tf.initialize_all_variables())
#setup as [batchsize, width, height, numberOfChannels] and use np.zeros()
batch_xs = np.zeros((batchsize, 28, 28, 1))
#setup as [batchsize, the how many classes]
batch_ys = np.zeros((batchsize, 10))
for i in range(300): # try a small iteration size once it works then continue
    perm = np.arange(nsamples)
    np.random.shuffle(perm)
    for j in range(batchsize):
        batch_xs[j,:,:,:] = Train[perm[j],:,:,:]
        batch_ys[j,:] = LTrain[perm[j],:]
    if i%10 == 0:
        #calculate train accuracy and print it
        print('step %d, loss %g, training accuracy %g' % (i, loss, acc))
    # dropout only during training
    optimizer.run(feed_dict={tf_data: batch_xs, tf_labels: batch_ys, keep_prob: 1.0})

# --------------------------------------------------
# test

print("test accuracy %g"%accuracy.eval(feed_dict={tf_data: Test, tf_labels: LTest, keep_prob: 1.0}))

sess.close()


# coding:utf-8
from flask import Flask, request, jsonify, g, render_template, redirect, url_for, session, current_app
from model import Order, OrderDetailed, UserCart, db_session, desc, func
from .decorator import login_check

from mobile import api
from config import Conf

import hashlib
import time
import random
import datetime
import json

@api.route('/post_order', methods=['POST'])
@login_check
def post_order():
	userid	 = g.current_user.id
	userphone  = g.current_user.phone
	orderitems = request.get_json().get('orderitems')
	addressid = request.get_json().get('addressid')
	teamid	 = g.current_user.teamid

	# 设计订单编号
	nowTime = datetime.datetime.now().strftime("%Y%m%d%H%M")  #生成当前时间
	randomNum = random.randint(10000,100000)  #生成的随机5位整数n，其中1000<=n<=10000
	phnumber = str(userphone)[-4:]
	ordernumber = '%s%s%s%s' % (int(nowTime), int(phnumber), int(teamid), int(randomNum))

	# 订单类型
	order_type = orderitems[0]['order_type']

	# 计算订单总金额 和 图片真实地址 和 购物车id
	cartid = []
	all_total = 0
	if 'cartid' not in orderitems[0]:
		all_total = orderitems[0]['color_total']
	else:
		for i in range(len(orderitems)):
			# 计算订单总金额
			all_total += orderitems[i]['color_total']
			# 得到购物车id
			cartid.append(orderitems[i]['cartid'])

	if len(orderitems) > 0:

		addorder = Order(
			number = ordernumber,
			userid = userid,
			teamid = teamid,
			addressid = addressid,
			state = 0,
			order_total = all_total,
			order_type = order_type,
			addtime = datetime.datetime.now()
		)

		try:
			db_session.add(addorder)
			db_session.commit()
			# 获取刚加添加的id
			db_session.flush()
			order_id = addorder.id
			order_item = [OrderDetailed(
							proid = int(orderitems[i]['proid']),
							pronumber = orderitems[i]['pronumber'],
							size = orderitems[i]['size'],
							color = orderitems[i]['color'],
							unit = int(orderitems[i]['unit']),
							price = int(float(orderitems[i]['price'])),
							color_total = int(orderitems[i]['color_total']),
							order_id = int(order_id)
						)for i in range(len(orderitems))]

			try:
				db_session.add_all(order_item)
				db_session.commit()
			except Exception as e:
				print (e)
				db_session.rollback()
				return jsonify({'code': 3, 'message': '数据库错误'})

		except Exception as e:
			print (e)
			db_session.rollback()
			return jsonify({'code': 3, 'message': '数据库错误'})

		# 删除购物车
		delcart = db_session.query(UserCart).filter(UserCart.id.in_((cartid))).all()
		try:
			[db_session.delete(n) for n in delcart]
			db_session.commit()
			db_session.close()
		except Exception as e:
			print (e)
			db_session.rollback()
			return jsonify({'code': 3, 'message': '数据库错误'})

		return jsonify({'code': 1, 'message': '下单成功'})

@api.route('/get_order')
@login_check
def get_order():
	userid	 = g.current_user.id
	ordertype = int(request.args.get('ordertype',0))
	state = request.args.get('state',0)

	if state == '0':
		state = [0]
	if state == '1':
		state = [1,2,3,4,5,6,7,8,9,10,11,12,13,14]
	if state == '15':
		state = [15]
	# print state

	page = int(request.args.get('pageNo',1)) #get到页数

	lim = int(3) #get到每页显示数量

	newcont = db_session.query(func.count(Order.id)).\
				filter(Order.userid == userid).\
				filter(Order.order_type == ordertype).\
				filter(Order.state.in_((state))).\
				scalar() #计算数据总数
	if newcont == None:
		newcont = 0

	if page == 1:
		page_nb = 0 #如果第一页则从第0条数据开始调用
		page_show = int(lim + page_nb) #调用数量的结尾数
	else:
		page_nb = int((lim * (page - 1))) #否则用显示数量乘以当前页数减去1 得到开始数
		page_show = int(lim + page_nb) #调用数量的结尾数

	orderlist = Order.query.\
					filter_by(userid = userid, order_type = ordertype ).\
					filter(Order.state.in_((state))).\
					order_by(Order.addtime).limit(lim)[page_nb:page_show]

	return jsonify({'orderlist': [Orders.to_list() for Orders in orderlist]})

@api.route('/cancel_order', methods=['POST'])
@login_check
def cancel_order():
	orderid = request.get_json().get('id')

	cancel =  Order.query.filter_by(id=orderid).first()
	if cancel:
		cancel.state = 99
		try:
			db_session.add(cancel)
			db_session.commit()
		except Exception as e:
			print (e)
			db_session.rollback()
			return jsonify({'code': 3, 'message': '数据库错误'})

	return jsonify({'code': 1, 'message': '订单取消成功'})


# --- Imports

# Standard imports
import base64
import binascii
import hashlib

# Third party imports
from dateutil import parser

# Constants
STRING_FIELD_LIST = ['first_name', 'last_name', 'nickname']
INTEGER_FIELD_LIST = ['wins', 'losses', 'current_win_streak']
DATETIME_FIELD_LIST = ['created', 'last_seen']

def modify_value_type(attribute, new_value_raw):
    """Convert a value into an appropriate type

    Arguments
    ---------
    attribute : string
    new_value_raw : string

    Return value
    ------------
    new_value : string, int, or datetime
        logic is based on field
    """

    if attribute in STRING_FIELD_LIST:
        new_value = str(new_value_raw)

    elif attribute in INTEGER_FIELD_LIST:
        new_value = int(new_value_raw)

    elif attribute in DATETIME_FIELD_LIST:
        new_value = parser.parse(new_value_raw)

    else:
        new_value = new_value_raw

    return new_value

def username_hash(first_name, last_name, nickname):
    """Create 28-digit username from first name, last name, and nickname.

    Arguments
    ---------
    first_name : string
    last_name : string
    nickname : string

    Return value
    ------------
    username_28 : string

    Notes
    -----
    The SHA1 sum of the string concatenation is calculated.  This is converted
    to a 28-digit Base64 string.

    """
    salt = "The_Coding_Challenge_Salt"
    sha1_of_input = hashlib.sha1(salt + first_name + last_name + nickname)
    username_28 = \
        base64.b64encode(binascii.unhexlify(sha1_of_input.hexdigest()))

    return username_28


import random
import os
import json
import sys
import string
import unicodedata

#Numpy and Scipy
import numpy as np
from numpy import genfromtxt
import matplotlib.pyplot as plt
from scipy.spatial import distance

#KERAS
from keras.layers import Dense, Activation, Dropout
from keras.models import Sequential
from keras.regularizers import l1,l2
from keras.models import load_model

'''
Created on Oct 6, 2016

This class has two construction functions.
1. From data
2. From initial settings

Example of 2D maze setting

initial_setting = {
    "maze_bound"        : (0,0,10,10),             #Continous state bound
    "obstacles"         : [(1,1,3,3),(5,4,6,6.5)], #Some obstacles that never crosspassing
    "current_state"     : (0,0,0,1),               #Current State in X,Y and If in Jail
    "action_range"      : (-0.5,0.5),              #The effective action range
    "action_dim"        : 2,                       #Dimension of Actions
    "goal_state"        : (10,10,0,1),             #The goal state to finish running
    "jail_location"     : (-1,-1,1,0),             #Jain location
    "deadend_toleration": 2                        #How many step left after getting into jail
                   }
@author: wuga
'''

class DeterministicMaze(object):

    def __init__(self, setting):
        self.__dict__.update(setting)
        self.backup = setting
        self.X_AXIS = 0

    def Reset(self):
        backup=self.backup
        self.__dict__.update(backup)
        self.backup = backup
        self.X_AXIS = 0

    def UpdateState(self,new_state):
        self.current_state = new_state

    def Apply(self, action):
        if not self.current_state[2]:
            x_axis=self.current_state[0]
            y_axis=self.current_state[1]
            x_axis=self.current_state[0]+action[0]
            if x_axis>self.maze_bound[2]:
                x_axis=self.maze_bound[2]
            if x_axis<self.maze_bound[0]:
                x_axis=self.maze_bound[0]
            y_axis=self.current_state[1]+action[1]
            if y_axis>self.maze_bound[3]:
                y_axis=self.maze_bound[3]
            if y_axis<self.maze_bound[1]:
                y_axis=self.maze_bound[1]
            self.UpdateState((x_axis,y_axis,0,1))
            if self.Collision():
                self.UpdateState(self.jail_location)
        else:
            self.deadend_toleration=self.deadend_toleration-1
        return self.current_state

    def StateIn(self, area, position):
        if (position[0] >= area[0]) and (position[0] <= area[2]) and \
        (position[1] >= area[1]) and (position[1] <= area[3]):
            return True
        else:
            return False

    def Collision(self):
        for area in self.obstacles:
            if self.StateIn(area, self.current_state):
                return True
        return False

    def IfGameEnd(self):
        if (self.current_state[0] == self.goal_state[0]) and \
        (self.current_state[1] == self.goal_state[1]) and \
        (self.current_state[2] == self.goal_state[2]):
            #print 'Get goal state! system resetted'
            self.Reset()
        if (self.deadend_toleration == 0):
            self.Reset()

    def DeltaDistance(self,new_state,old_state):
        delta=[]
        delta.append(new_state[0]-old_state[0])
        delta.append(new_state[1]-old_state[1])
        if (new_state[2]==1):
            delta.append(1)
            delta.append(0)
        else:
            delta.append(0)
            delta.append(1)
        return delta

    def GetCurrentState(self):
        return self.current_state

initial_setting = {
    "maze_bound"        : (0,0,10,10),             #Continous state bound
    "obstacles"         : [(1,1,3,3),(5,4,6,6.5)], #Some obstacles that never crosspassing
    "current_state"     : (0,0,0,1),               #Current State in X,Y and If in Jail
    "action_range"      : (-0.5,0.5),              #The effective action range
    "goal_state"        : (10,10,0,1),             #The goal state to finish running
    "jail_location"     : (-1,-1,1,0),             #Jain location
    "deadend_toleration": 2,                       #How many step left after getting into jail
    "action_dim"        : 2                        #Dimension of Actions
    }

# Maze=DeterministicMaze(initial_setting)
# print Maze.current_state
# action1=(0,11)
# Maze.Apply(action1)
# action2=(1,10)
# Maze.Apply(action2)
# print Maze.current_state

#Given local path, find full path
def PathFinder(path):
    script_dir = os.path.dirname('__file__')
    fullpath = os.path.join(script_dir,path)
    return fullpath

#Read data_load_forecast for Deep Learning
def ReadData(path):
    fullpath=PathFinder(path)
    return genfromtxt(fullpath, delimiter=',')

class RandomWalk(object):
    def __init__(self, actiondim, ranges):
        self.ranges = ranges
        self.actiondim = actiondim

    def Go(self):
        stride = []
        for i in range(self.actiondim):
            stride.append(random.triangular(self.ranges[0], self.ranges[1], 0.2))
        print(stride)
        return stride

Maze=DeterministicMaze(initial_setting)
Planner=RandomWalk(Maze.action_dim,Maze.action_range)
for i in range(10):
    Planner.Go()

class DataGenerator(object):
    def __init__(self, model):
        self.maze = model
        self.planner = RandomWalk(self.maze.action_dim, self.maze.action_range)

    def WriteData(self, size, datapath, labelpath):
        fulldatapath = PathFinder(datapath)
        fulllabelpath = PathFinder(labelpath)
        datafile = open(fulldatapath, 'w')
        labelfile = open(fulllabelpath, 'w')
        for i in range(0, size):
            self.maze.IfGameEnd()
            action = self.planner.Go()
            old_state = Maze.GetCurrentState()
            self.maze.Apply(action)
            new_state = self.maze.GetCurrentState()
            Data = list(old_state) + action
            # Label=list(new_state)
            Label = self.maze.DeltaDistance(new_state, old_state)
            datafile.write(','.join(map(str, Data)) + '\n')
            labelfile.write(','.join(map(str, Label)) + '\n')
        datafile.close()
        labelfile.close()

Maze=DeterministicMaze(initial_setting)
Generator=DataGenerator(Maze)
Datapath="StateActionData.txt"
Labelpath="StateActionLabel.txt"
Generator.WriteData(100000,Datapath,Labelpath)

class FullyConnectedDeepNet(object):
    '''

    '''

    def __init__(self, observ, hidden, output, num_layers, drop_out):
        self.drop_out = drop_out
        self.DeepNet = Sequential()
        # self.Autoencoder.add(Dropout(0.5, input_shape=(observ,)))
        self.DeepNet.add(Sequential([Dense(hidden, input_dim=observ), Activation('relu')]))
        self.DeepNet.add(Dropout(drop_out))
        if num_layers > 1:
            for i in range(num_layers - 1):
                self.DeepNet.add(Sequential([Dense(hidden, input_dim=hidden), Activation('relu')]))
                self.DeepNet.add(Dropout(drop_out))
        self.DeepNet.add(Dense(output, input_dim=hidden))
        self.DeepNet.compile(optimizer='rmsprop', loss='mse')

    def Train(self, data, label, epoch):
        self.DeepNet.fit(data, label, nb_epoch=epoch)

    def Test(self, datapoint):
        return self.DeepNet.predict(datapoint, batch_size=128, verbose=0)

    def LoadModel(self, modelpath):
        self.DeepNet = load_model(modelpath)

    def Save(self, modelpath):
        self.DeepNet.save(modelpath)

    def GetModel(self):
        return self.DeepNet

Datapath="StateActionData.txt"
Labelpath="StateActionLabel.txt"
DNN_DELTA=FullyConnectedDeepNet(6,100,2,4,0.1)
DNN_INJAIL=FullyConnectedDeepNet(6,100,2,1,0.1)
Full_Data=ReadData(Datapath)
Full_Label=ReadData(Labelpath)
Train_Data = Full_Data[:90000]
Train_Label = Full_Label[:90000]
Test_Data = Full_Data[90000:]
Test_Label = Full_Label[90000:]
DNN_DELTA.Train(Train_Data,Train_Label[:,:2],30)
DNN_INJAIL.Train(Train_Data,Train_Label[:,2:],30)
DNN_DELTA.Save("TransitionModel_DELTA.h5")
DNN_INJAIL.Save("TransitionModel_INJAIL.h5")

Datapath="StateActionData.txt"
Labelpath="StateActionLabel.txt"
Full_Data=ReadData(Datapath)
Full_Label=ReadData(Labelpath)
Train_Data = Full_Data[:90000]
Train_Label = Full_Label[:90000]
Test_Data = Full_Data[90000:]
Test_Label = Full_Label[90000:]
DNN_DELTA=FullyConnectedDeepNet(6,100,2,4,0.1)
DNN_INJAIL=FullyConnectedDeepNet(6,100,2,1,0.1)
DNN_DELTA.LoadModel("TransitionModel_DELTA.h5")
DNN_INJAIL.LoadModel("TransitionModel_INJAIL.h5")

Test_Pred = np.concatenate((DNN_DELTA.Test(Test_Data), DNN_INJAIL.Test(Test_Data)), axis=1)
print(Test_Pred[:3])
print(Test_Label[:3])

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.patches as patches

def Virtualizing(Data, Label, Pred, Obstacles,SampleSize):
    sample_index=np.random.choice(len(Data), SampleSize)
    #print sample_index
    #print Train_Data[sample_index,:2],Train_Label[sample_index,:2]
    fig9 = plt.figure()
    ax9 = fig9.add_subplot(111)
    for i in sample_index:
        plt.plot([Data[i,0],Data[i,0]+Label[i,0]], [Data[i,1],Data[i,1]+Label[i,1]], 'r-',lw=1)
        plt.plot([Data[i,0],Data[i,0]+Pred[i,0]], [Data[i,1],Data[i,1]+Pred[i,1]], 'k-',lw=1)
    for j in range(len(Obstacles)):
        ax9.add_patch(patches.Rectangle((Obstacles[j][0], Obstacles[j][1]),
                                        Obstacles[j][2]-Obstacles[j][0], Obstacles[j][3]-Obstacles[j][1],
                                        hatch='\\', fill=False,linestyle='solid'))
    plt.show()

Virtualizing(Test_Data,Test_Label,Test_Pred,Maze.obstacles,500)

DNN_DELTA=FullyConnectedDeepNet(6,100,2,4,0.1)
# Train_Data=ReadData(Datapath)
# Train_Label=ReadData(Labelpath)
DNN_DELTA.LoadModel("TransitionModel_DELTA.h5")
for layer in DNN_DELTA.GetModel().layers:
    g=layer.get_config()
    h=layer.get_weights()
    print(g)
    print(h)

class NetTopology(object):
    def __init__(self, layers, drop_out):
        self.layers = layers
        self.input_dim = layers[0].get_config()[0].get('config').get('input_dim')
        self.num_upper_layers = len(layers)
        self.nodenames = []
        self.drop_out = drop_out
        layernodename = []
        for i in range(0, self.input_dim):
            layernodename.append('N0' + str(i))
        layernodename.append('B0')
        self.nodenames.append(layernodename)

    def LayerWiseTransform(self, layer, layer_id, lastlayer=False, hiddenstart='N', writefile=False, filehandler=None):
        if not lastlayer:
            input_dim = layer.get_config()[0].get('config').get('input_dim')
            output_dim = layer.get_config()[0].get('config').get('output_dim')
            activation = layer.get_config()[1].get('config').get('activation')
        else:
            input_dim = layer.get_config().get('input_dim')
            output_dim = layer.get_config().get('output_dim')
            activation = layer.get_config().get('activation')
        layernodename = []
        weights_bias = layer.get_weights()
        weights = weights_bias[0]
        bias = weights_bias[1]
        for i in range(0, output_dim):
            layernodename.append(hiddenstart + str(layer_id) + str(i))
        for i in range(0, output_dim):
            row = [layernodename[i], activation]
            for j in range(0, input_dim):
                row.append(self.nodenames[-1][j])
                row.append(weights[j][i] * self.drop_out)
            row.append(self.nodenames[-1][-1])
            row.append(bias[i])
            if writefile:
                filehandler.write(','.join(map(str, row)) + '\n')
            else:
                print(','.join(map(str, row)))
        layernodename.append('B' + str(layer_id))
        self.nodenames.append(layernodename)

    def NetTransform(self, hiddenstart='N', writefile=False, filepath=None, overwrite=False):
        filehandler = None
        if writefile:
            fullpath = PathFinder(filepath)
            if overwrite is True:
                filehandler = open(fullpath, 'w')
            else:
                filehandler = open(fullpath, 'a')
        counter = 0
        for i in range(0, self.num_upper_layers):
            if type(self.layers[i]) is not Dropout:
                if (i == self.num_upper_layers - 1):
                    self.LayerWiseTransform(self.layers[i], counter + 1, True, hiddenstart, writefile, filehandler)
                else:
                    self.LayerWiseTransform(self.layers[i], counter + 1, False, hiddenstart, writefile, filehandler)
                counter = counter + 1
        if writefile:
            filehandler.close()
        print('Done!')

Topo_DELTA = NetTopology(DNN_DELTA.GetModel().layers, DNN_DELTA.drop_out)
Topo_DELTA.NetTransform('D', True, "Network_MIX.txt", True)

Topo_INJAIL = NetTopology(DNN_INJAIL.GetModel().layers, DNN_INJAIL.drop_out)
Topo_INJAIL.NetTransform('I', True, "Network_MIX.txt", False)


from django.contrib.auth.models import Group
from rest_framework import serializers

class GroupSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Group
        exclude = ['permissions']

        extra_kwargs = {
            'url': {
                'view_name': 'api_v1:group-detail',
                'lookup_field': 'pk'
            },
        }


import os
import time
import urllib

import sikuli
from sikuli import wait, exists, FindFailed

# Local imports
from utils.sikuliUtils import click
from utils import pyUtils, sikuliUtils
from utils.pyUtils import log
import checkUtils

class EditToolsCheck:
    def __init__(self, editTools):
        self.editTools = editTools

    def createNewPanelsCheck(self, n):
        """Checker function to verify the n new panels were created

        n -- Number of panels created
        """
        log('## createNewPanelsCheck')

        if not exists('%sblankPanels.png' % n):
            self.editTools.testInfo.failed('createNewPanelsCheck: Could not find the %s new created panels on screen.' % n)
        else:
            log('- Found all %s new panels on screen.' % n)

        sikuliUtils.saveVersion(self.editTools.testInfo, 'Created %s new blank panels.' % n)

        """
        # Check there's n more panels in the beats directory
        allPanels = pythonHelper.findBeat(self.editTools.testInfo, 'p')
        if (allPanels - len(self.editTools.testInfo.allPanels['p'])) != n:
            self.editTools.testInfo.failed('createNewPanelsCheck: Expected %s new panels in the beats directory, found %s instead.' % (n, allPanels - len(self.editTools.testInfo.allPanels['p'])))
        else:
            log('- Found all %s new panels in the beats directory.' % n)
        """

        # Check there's n more panels in the current shotEdit
        newPanels = checkUtils.newPanelsInShotEdit(self.editTools.testInfo,
                                                   {'p': n},
                                                   beats=['p'],
                                                   methodName='createNewPanelsCheck')

        checkUtils.checkPanelDir(self.editTools.testInfo, newPanels, ['multitrack', 'jpg', 'xml'], 'createNewPanelsCheck')

        log('All checks performed for createNewPanels.')

    def copyPastePanelCheck(self, panel):
        log('## copyPastePanelCheck')

        # Make sure the copy/pasted panel is found twice on screen
        try:
            matches = list(sikuli.findAll(panel))
            n = len(matches)
            if n != 2:
                self.editTools.testInfo.failed('copyPastePanelCheck: Expected 2 instances of %s, found %s instead.' % (panel, n))
            else:
                log('- Found both instances of the copy/pasted panel on screen.')
        except FindFailed:
            self.editTools.testInfo.failed('copyPastePanelCheck: Could not find any instance of %s on screen.' % panel)

        sikuliUtils.saveVersion(self.editTools.testInfo, 'Copy/pasted one panel.')

        # Check there's 1 more panel in the new shotEdit
        checkUtils.newPanelsInShotEdit(self.editTools.testInfo,
                                       {'p': 1},
                                       beats=['p'],
                                       methodName='copyPastePanelCheck')

        log('All checks performed for copyPastePanelCheck.')

    def duplicatePanelCheck(self, panel):
        log('## duplicatePanelCheck')

        # Make sure the duplicated panel is found twice on screen
        try:
            matches = list(sikuli.findAll(panel))
            n = len(matches)
            if n != 2:
                self.editTools.testInfo.failed('duplicatePanelCheck: Expected 2 instances of %s, found %s instead.' % (panel, n))
            else:
                log('- Found both instances of the duplicated panel on screen.')
        except FindFailed:
            self.editTools.testInfo.failed('duplicatePanelCheck: Could not find any instance of %s on screen.' % panel)

        sikuliUtils.saveVersion(self.editTools.testInfo, 'Duplicated one panel.')

        # Check there's 1 more panel in the new shotEdit
        newPanels = checkUtils.newPanelsInShotEdit(self.editTools.testInfo,
                                                   {'p': 1},
                                                   beats=['p'],
                                                   methodName='copyPastePanelCheck')

        # Check the new panel has everything in its directory
        checkUtils.checkPanelDir(self.editTools.testInfo, newPanels, ['multitrack', 'jpg', 'xml'], 'duplicatePanelCheck')

        log('All checks performed for duplicatePanelCheck.')

    def addDialogueCheck(self, panels, dialogue):
        """Checks the dialogue has been saved in each panel's multitrack

        :param panels: Array of panel indices to check for dialogue
        :param dialogue: String added to each panel as dialogue
        :return: None
        """
        log('## addDialogueCheck')

        sikuliUtils.saveVersion(self.editTools.testInfo, 'Added dialogue to %s panels.' % len(panels))

        editPanels = self.editTools.testInfo.getPanelsFromShotEdit(perBeat=False)
        missing = []
        for panel in panels:
            multitrackDialogue = self.editTools.testInfo.getPanelDialogue(editPanels[panel-1])
            if dialogue.replace("[panelIndex]", str(panel)) == multitrackDialogue:
                log("addDialogueCheck: Found dialogue in %s's multitrack." % editPanels[panel-1], "debug")
            else:
                missing.append(editPanels[panel-1])
                log("addDialogueCheck: Couldn't find dialogue in %s's multitrack." % editPanels[panel-1], "error")
            self.editTools.testInfo.dialogue[editPanels[panel-1]] = multitrackDialogue
        if len(missing):
            self.editTools.testInfo.failed("addDialogue: Failed to find dialogue in the following panels' multitracks: "
                                           "%s" % missing)
        else:
            log("addDialogueCheck: Found dialogue in every panel's multitrack.")

        log('All checks performed for addDialogue.')


import database
import game
import init
import maps
import pygame
import random
import time
pygame.init()
chosen = ()
clicked = False
color = ''
dropping = True
matching = False
waiting = True
fruits = {"草莓", "汉堡", "苹果", "香蕉", "樱桃"}
last_x = 0
last_y = 0
map1 = maps.get("MapConnect")
screen = pygame.display.set_mode([init.H, init.V])
sx, sy = 0, 0
t1 = 0  # 消消乐定时器

class Items:  # 物品
    def __init__(self, i0: list, grid: int):
        self.x = len(i0[0])  # 行数
        self.y = len(i0)  # 列数
        self.grid = grid  # 物品格子尺寸
        self.i = i0  # 物品列表
        self.v = self.x * grid  # 地图高度
        self.h = self.y * grid  # 地图宽度

class Map:  # 地图
    def __init__(self, m0: list, grid: int):
        self.x = len(m0[0])  # 行数
        self.y = len(m0)  # 列数
        self.grid = grid  # 地图格子尺寸
        self.m = m0  # 地图列表
        self.v = self.x * grid  # 地图高度
        self.h = self.y * grid  # 地图宽度

class Player:  # 勇者
    def __init__(self):
        self.attack = 0
        self.calc = 0  # 是否拿取伤害计算手册
        self.defense = 0
        self.dir = '↓'
        self.exp = 0
        self.floor = 1
        self.gold = 0
        self.keys = [0, 0, 0, 0]
        self.life = 0
        self.pose = 0
        self.speed = 0
        self.t_walking = 0  # 行走定时器
        self.walking = False
        self.x = 0
        self.y = 0

def act(i: Items, m: Map, p: Player):  # 实时动作
    global dropping, fruits, map1, screen, waiting
    px, py = game.map2screen(m, p.x, p.y, init.V, 'corner')
    if p.floor == 5:  # 连连看
        connect(i, m, p)
    if p.walking:  # 勇者移动
        speed = p.speed * 3
        split = 8
        game.draw_tiles(i, m, p, screen)
        if time.time()-p.t_walking < 1/speed:  # 移动中
            p.pose = int((time.time() - p.t_walking) * speed * 4) % 4 + 1
            delta_grid = m.grid * int((time.time() - p.t_walking) * speed * split) / split
            if p.dir == '↑':
                game.draw_character(m, p, screen, True, (px, py - delta_grid))
            elif p.dir == '↓':
                game.draw_character(m, p, screen, True, (px, py + delta_grid))
            elif p.dir == '←':
                game.draw_character(m, p, screen, True, (px - delta_grid, py))
            elif p.dir == '→':
                game.draw_character(m, p, screen, True, (px + delta_grid, py))
        else:
            end_step(i, m, p)  # 移动完成
            game.draw_tiles(i, m, p, screen)
            pic = {'↑': "勇者后", '↓': "勇者前", '←': "勇者左", '→': "勇者右"}
            player_pic = pygame.image.load("Character/%s.png" % (pic[p.dir]+str(p.pose)))
            screen.blit(player_pic, game.map2screen(m, p.x, p.y, init.V, 'corner'))
    mx, my = game.map2screen(m, 0, 0, init.V, "corner")
    pygame.draw.lines(screen, 'white', True, [(mx, my), (mx + m.h, my), (mx + m.h, my + m.v), (mx, my + m.v)], 1)  # 边缘
    pygame.display.update()

def connect(i: Items, m: Map, p: Player):  # 三消
    global chosen, clicked, dropping, event, matching, t1, waiting
    if waiting:  # 等待中
        game.draw_character(m, p, screen, False)
        if time.time()-t1 > 0.2:
            waiting = False
    elif dropping:  # 下落中
        dropping = False
        if matching:
            for x in range(m.x):
                for y in range(m.y):
                    if map1[x][y] == "∅":
                        i.i[x][y] = ""
                        dropping = True
                        matching = False
                    map1[x][y] = ""
        else:
            for x in reversed(range(m.x)):
                for y in range(m.y):
                    drop_able = x < m.x-1 and set(m.m[x+1][y]) & passable and i.i[x+1][y] == ""
                    if (i.i[x][y] in fruits or "D" in i.i[x][y]) and drop_able:
                        dropping = True
                        i.i[x+1][y], i.i[x][y] = i.i[x][y], ""
                    elif m.m[x][y] == "石砖" and drop_able:
                        dropping = True
                        if random.randint(1, 20) == 1:
                            i.i[x+1][y] = random.choice(["防石D", "攻石D", "红血D", "蓝血D"])
                        else:
                            i.i[x+1][y] = random.choice(["草莓", "汉堡", "苹果", "香蕉", "樱桃"])
                    elif x != 0 and m.m[x][y] == "星空" and drop_able:
                        if "D" in i.i[x-1][y]:
                            i.i[x-1][y], i.i[x+1][y] = "", i.i[x-1][y].strip("D")
        matching = not dropping
        game.draw_tiles(i, m, p, screen)
        t1, waiting = time.time(), True
    elif matching:  # 消除中
        for x in range(m.x):
            for y in range(m.y):
                if x < m.x-2 and i.i[x][y] in fruits and i.i[x][y] == i.i[x+1][y] == i.i[x+2][y]:
                    dropping, map1[x][y], map1[x+1][y], map1[x+2][y] = True, "∅", "∅", "∅"
                if y < m.y-2 and i.i[x][y] in fruits and i.i[x][y] == i.i[x][y+1] == i.i[x][y+2]:
                    dropping, map1[x][y], map1[x][y+1], map1[x][y+2] = True, "∅", "∅", "∅"
        if dropping:
            t1, waiting = time.time(), True
        elif event.type == pygame.MOUSEBUTTONDOWN:
            clicked = True
        elif clicked and event.type == pygame.MOUSEBUTTONUP:
            if event.button == 1:
                x, y = game.screen2map(event, m, init.V)[1], game.screen2map(event, m, init.V)[0]
                if matching == 1:
                    if 0 <= x < m.x and 0 <= y < m.y and i.i[x][y] in fruits:
                        chosen = (x, y, i.i[x][y])
                        matching = 2
                        t1, waiting = time.time()-0.1, True
                elif matching == 2:
                    if 0 <= x < m.x and 0 <= y < m.y and i.i[x][y] in fruits:
                        if i.i[x][y] != chosen[2] and abs(x-chosen[0])+abs(y-chosen[1]) == 1:
                            i.i[x][y], i.i[chosen[0]][chosen[1]] = chosen[2], i.i[x][y]
                            tile = pygame.image.load(database.get(m.m[chosen[0]][chosen[1]]))
                            screen.blit(tile, game.map2screen(m, chosen[1], chosen[0], init.V, 'corner'))
                            tile = pygame.image.load(database.get(i.i[chosen[0]][chosen[1]]))
                            screen.blit(tile, game.map2screen(i, chosen[1], chosen[0], init.V, 'corner'))
                            tile = pygame.image.load(database.get(m.m[x][y]))
                            screen.blit(tile, game.map2screen(m, y, x, init.V, 'corner'))
                            tile = pygame.image.load(database.get(i.i[x][y]))
                            screen.blit(tile, game.map2screen(i, y, x, init.V, 'corner'))
                        t1, waiting = time.time()-0.1, True
                    matching = 1
            clicked = False

def end_step(i: Items, m: Map, p: Player):  # 移动完成后的动作
    global color, dropping, last_x, last_y, running, screen, t1, waiting
    front = 0
    p.x, p.y = {'↑': (p.x, p.y - 1), '↓': (p.x, p.y + 1), '←': (p.x - 1, p.y), '→': (p.x + 1, p.y)}[p.dir]
    block, item = m.m[p.y][p.x], i.i[p.y][p.x]
    p.walking = False
    p.pose = 1
    for x in range(m.x):  # 隔一步发生的事件
        for y in range(m.y):
            if m.m[x][y][-2:] == "余1":
                if set(m.m[x][y]) & set("╭╮╰╯═║"):
                    mapping = {'╭': '╮', '╮': '╯', '╯': '╰', '╰': '╭', '═': '║', '║': '═'}
                    m.m[last_y][last_x] = color + "障" + mapping[m.m[last_y][last_x][2]]
                elif m.m[x][y][:2] == "凹刺":
                    m.m[x][y] = "凸刺"
    if block == '':
        pass
    elif "钮" in block:  # 按钮事件
        color, attribute = block[0], block[1]
        if set(block) & set("凸撇捺"):
            for x in range(m.x):
                for y in range(m.y):
                    if attribute in m.m[x][y]:
                        if attribute == "柱" and m.m[x][y][0] == color:
                            mapping = {"凹": "凸", "凸": "凹", "撇": "捺", "捺": "撇"}
                            m.m[x][y] = m.m[x][y][:-1] + mapping[m.m[x][y][-1]]
                        elif attribute == "障":
                            mapping = {'╭': '╮', '╮': '╯', '╯': '╰', '╰': '╭', '═': '║', '║': '═'}
                            mapping.update({"凹": "凸", "凸": "凹"})
                            m.m[x][y] = m.m[x][y][:-1] + mapping[m.m[x][y][-1]]
    elif set(block) & set("╭╮╰╯═║"):
        color = block[0]
        last_x, last_y = p.x, p.y
        m.m[p.y][p.x] = block + "余1"
    elif block == "凹刺":
        m.m[p.y][p.x] = "凹刺余1"
    elif block == "凸刺":
        p.life -= 100
    elif block == "冰地":
        if (p.dir, p.x) in [('←', 0), ('→', m.y-1)] or (p.dir, p.y) in [('↑', 0), ('↓', m.x-1)]:
            return
        global passable
        if p.dir == '↑':
            front = set(m.m[p.y-1][p.x]) & (passable | set("╭╮║"))
        elif p.dir == '↓':
            front = set(m.m[p.y+1][p.x]) & (passable | set("╰╯║"))
        elif p.dir == '←':
            front = set(m.m[p.y][p.x-1]) & (passable | set("╭╰═"))
        elif p.dir == '→':
            front = set(m.m[p.y][p.x+1]) & (passable | set("╮╯═"))
        if not front:
            return
        p.walking = True
        p.t_walking = time.time()
    if item == '':
        pass
    elif item[-1] == "怪":  # 打怪
        life, attack, defense, gold = database.monster(item[:-1])
        if p.attack > defense:
            while True:
                life -= (p.attack - defense)  # 玩家攻击
                if life > 0:
                    p.life -= (attack - p.defense)  # 敌方攻击
                else:
                    break
                time.sleep(0.25)
                game.draw_tiles(i, m, p, screen)
                game.draw_character(m, p, screen, False)
                game.draw_status(p, screen)
                pygame.display.update()
            p.gold += gold
            p.exp += gold
            i.i[p.y][p.x] = ''
    elif set(item) & set("血石杖"):  # 可消耗品
        if item == "红血":
            p.life += 50
        elif item == "蓝血":
            p.life += 200
        elif item == "攻石":
            p.attack += 1
        elif item == "防石":
            p.defense += 1
        elif item == "权杖3":
            game.ice_power(i, m, p, screen)
        i.i[p.y][p.x] = ''
    elif item[-1] == "楼":  # 传送
        if item == "上楼":
            p.floor += 1
        elif item == "下楼":
            p.floor -= 1
        m.m, i.i = maps.get('Map'+str(p.floor)), maps.get('Items'+str(p.floor))
        t1 = time.time()
    elif item[-2:] == "钥匙":
        p.keys[{"黄": 0, "蓝": 1, "红": 2, "绿": 3}[item[0]]] += 1
        i.i[p.y][p.x] = ''
    elif item == "手册":
        p.calc, i.i[p.y][p.x] = 1, ''
    if p.life <= 0:
        running = False
        pygame.draw.rect(screen, "black", ((0, 0), (init.H, init.V)))
        font100 = pygame.freetype.Font("Fonts/思源黑体.otf", 100)
        font100.render_to(screen, [init.H/2-50, init.V/2-50], "死", fgcolor="red")
        init.font_a.render_to(screen, [init.H/2-40, init.V/2+50], "D E A D", fgcolor="red")
        pygame.display.update()
        time.sleep(1)
        pygame.quit()
    game.draw_status(p, screen)

def restart(i: Items, m: Map, p: Player):  # 重开
    m.m, i.m = maps.get("Map" + str(p.floor)), maps.get("Items" + str(p.floor))
    p.x, p.y = sx, sy
    p.life = 1000
    p.attack = 10
    p.defense = 10
    p.pose = 1
    p.speed = 1
    game.draw_status(p, screen)
    game.draw_tiles(i, m, p, screen)
    player_pic = pygame.image.load("Character/勇者前1.png")
    screen.blit(player_pic, game.map2screen(m, p.x, p.y, init.V, 'corner'))
    pygame.display.update()

P = Player()
M0, I0 = Map(maps.get("Map" + str(P.floor)), init.Grid), Items(maps.get("Items" + str(P.floor)), init.Grid)
for Y in range(M0.x):
    for X in range(M0.y):
        if M0.m[Y][X] == "始地":
            sx, sy = X, Y
P.x, P.y = sx, sy
passable = set("凹刺地楼钮")  # 可行走地形
non_pass_item = set("门")
restart(I0, M0, P)
pygame.display.set_caption('缝合怪')
pygame.display.flip()

running = True
while running:
    act(I0, M0, P)  # 动作
    for event in pygame.event.get():
        if event.type == pygame.QUIT:  # 按×退出
            running = False
            pygame.quit()
        elif event.type == pygame.KEYDOWN:  # 按下按键
            if event.key in {pygame.K_UP, pygame.K_DOWN, pygame.K_LEFT, pygame.K_RIGHT} and not P.walking:  # 按下方向键时
                game.begin_step(event, I0, M0, P, passable, non_pass_item, screen)
            elif event.key == pygame.K_r:
                if P.floor == 1:
                    restart(I0, M0, P)
                elif P.floor == 2:
                    game.ice_power(I0, M0, P, screen)
            elif event.key == pygame.K_SPACE:
                if P.calc != 0:
                    P.calc = 3-P.calc
        elif event.type == pygame.MOUSEMOTION:
            pygame.display.set_caption(str(game.screen2map(event, M0, init.V)))