import User
import Order
import Market
import Currency
import datetime

class MainMenu:
    def __init__(self):
        self.user = User
        self.order = Order
        self.market = Market
        self.currency = Currency
        self.list_of_coins = [["DCC", "DCCapital Exchange"]]
        self.deleted_orders = []
        self.pre_orders_review = []
        self.list_of_trader = []
        self.list_of_matches = []
        self.running = bool
        self.show_options = {
                            "1": self.log_in,
                            "2": self.create_new_user,
                            "3": self.exit
                            }

    def display_menu(self):
        print('''
            Menu:
                1: Ingresar
                2: Crear cuenta
                3: Salir
            ''')

    def run_main_menu(self):
        self.running = True
        while self.running:
            self.display_menu()
            choice = input("Ingrese opción: ")
            action = self.show_options.get(choice)
            if action:
                action()
            else:
                print("{} no es una opción válida".format(choice))

    def log_in(self):
        username = input("Ingresar nombre de usuario: ")
        for user in self.user.User.list_of_users:
            if username == user.username:
                self.user.User.this_menu = True
                while self.user.User.this_menu:
                    if user.get_age() < 18:
                        self.user.Underaged.run_user(user)
                    elif user.has_priority:
                        self.user.Investor.run_user(user)
                    else:
                        self.user.Trader.run_user(user)
                    return
        print("Nombre de usuario inválido, pruebe nuevamente")
        return

    def create_new_user(self):
        username = input("Ingrese nombre de usuario: ")
        for user in self.user.User.list_of_users:
            if username in user.username:
                print("Nombre de usuario ya existe, pruebe nuevamente")
                return
        name = input("Ingrese su nombre: ")
        lastname = input("Ingrese su apellido: ")
        birthday = input("Ingrese su fecha de nacimiento de la siguiente forma -> YYYY-MM-DD: ")
        birth_list = birthday.split("-")
        try:
            if birthday != str(datetime.datetime.strptime(birthday, "%Y-%m-%d").date()):
                raise ValueError
            elif int(birth_list[0]) < 1900 or int(birth_list[0]) > 2017:
                raise ValueError
            else:
                self.user_assignment(username, name, lastname, birthday)
                for user in self.user.User.list_of_traders:
                    if user.username == username:
                        for coin in user.currency_balances:
                            if coin.symbol == "DCC":
                                coin.amount += 100000
                        user._save_users_csv()
                        user._save_money_csv()
                print("\n¡Usuario creado exitosamente! Por favor inicie sesión")
                return
        except ValueError:
            print("Fecha inválida, pruebe nuevamente")
            return

    def exit(self):
        self.running = False
        for user in self.user.User.list_of_users:
            user._save_all_csv()
            break
        print("Gracias por usar nuestra aplicación ¡Esperamos verte pronto!")

    def instantiate_users(self):  # Abre el archivo 'users.csv' y
        users = [line.split(';') for line in open('users.csv', 'r', encoding='UTF-8').read().split('\n')]
        list_of_kwargs = self._kwargs_master(users)
        for kwarg in list_of_kwargs:
            self.user_assignment(**kwarg)
        self._destroy_underaged_pair_orders()

    def instantiate_orders(self):  # creo las orders anteriores
        orders = [line.split(';') for line in open('orders.csv', 'r', encoding='UTF-8').read().split('\n')]
        list_of_kwargs = self._kwargs_master(orders)
        for kwarg in list_of_kwargs:
            self.order.Order(**kwarg)
        self.order.Order.list_of_orders.sort(key=lambda x: x.date_created)

    def instantiate_currencies(self):  # creo las currencies anteriores
        currencies = [line.split(';') for line in open('Currencies.csv', 'r', encoding='UTF-8').read().split('\n')]
        list_of_kwargs = self._kwargs_master(currencies)
        for kwarg in list_of_kwargs:
            values = kwarg.values()
            values_to_append = []
            short_value = ""
            long_value = ""
            for value in values:
                if len(value) == 3:
                    short_value = value
                else:
                    long_value = value
                if len(short_value) != 0 and short_value != "DCC" and len(long_value) != 0:
                    values_to_append.append(short_value)
                    values_to_append.append(long_value)
                    self.list_of_coins.append(values_to_append)
                    short_value = ""
                    long_value = ""

        for i in range(len(self.list_of_coins)):
            for j in range(len(self.list_of_coins)):
                if self.list_of_coins[i] != self.list_of_coins[j]:
                    self.market.Market(self.list_of_coins[i][0] + self.list_of_coins[j][0])

    def instantiate_money(self):
        try:
            money = [line.split(';') for line in open('money.csv', 'r', encoding='UTF-8').read().split('\n')]
            list_of_kwargs = self._kwargs_master(money)
            for kwarg in list_of_kwargs:
                for user in self.user.User.list_of_users:
                    if kwarg["username"] == user.username:
                        for coin in user.currency_balances:
                            if kwarg["symbol"] == coin.symbol:
                                coin.amount = float(kwarg["amount"])
        except:
            return

    def instantiate_historical_orders(self):
        try:
            orders = [line.split(';') for line in open('orderHistory.csv', 'r', encoding='UTF-8').read().split('\n')]
            list_of_kwargs = self._kwargs_master(orders)
            new_order = NotImplemented
            for kwarg in list_of_kwargs:
                new_order = self.order.Order(**kwarg)
                self.order.Order.list_of_orders.pop(self.order.Order.list_of_orders.index(new_order))
            orders_to_del = []
            self.order.Order.order_history.sort(key=lambda x: (x.order_id, x.date_created))
            for i in range(len(self.order.Order.order_history) - 1):
                o = self.order.Order.order_history[i]
                oo = self.order.Order.order_history[i + 1]
                if o.order_id == oo.order_id and o.ticker == oo.ticker and o.price == oo.price and \
                                o.date_created == oo.date_created and o.amount == o.amount and o.type == oo.type and \
                                o.date_match == oo.date_match and o not in orders_to_del:
                    orders_to_del.append(o)
            for order in orders_to_del:
                if order in self.order.Order.order_history:
                    self.order.Order.order_history.pop(self.order.Order.order_history.index(order))
            self.order.Order.order_history.sort(key=lambda x: x.date_created)
            self.order.Order._save_order_history(new_order)
            for user in self.user.User.list_of_users:
                list_of_orders = user.all_orders_id.split(":")
                if list_of_orders[0] == "":
                    return
                for i in range(len(list_of_orders)):
                    for order in self.order.Order.order_history:
                        if order.order_id == list_of_orders[i]:
                            user.list_of_my_historical_orders.append(order)
        except:
            return

    def instantiate_registered_markets(self):
        try:
            markets = [line.split(';') for line in open('registeredMarkets.csv', 'r', encoding="utf-8").read().split('\n')]
            list_of_kwargs = self._kwargs_master(markets)
            for user in self.user.User.list_of_users:
                user_markets = []
                user_markets_to_add = []
                for market in user.list_of_markets_registered:
                    user_markets.append(market.name)
                for kwarg in list_of_kwargs:
                    if kwarg["username"] == user.username:
                        if kwarg["name"] not in user_markets:
                            user_markets_to_add.append(kwarg["name"])
                for market in user.list_of_all_markets:
                    if market.name in user_markets_to_add:
                        user.list_of_markets_registered.append(market)
        except:
            return

    def user_assignment(self, username, name, lastname, birthday, orders=''):  # creo los users anteriores
        birth_date = birthday.split("-")
        year = int(datetime.datetime.now().strftime("%Y")) - int(birth_date[0])
        month = int(datetime.datetime.now().strftime("%m"))
        day = int(datetime.datetime.now().strftime("%d"))
        if month < int(birth_date[1]) or (month == int(birth_date[1]) and day > int(birth_date[2])):
            year -= 1
        if year < 18:
            new_user = self.user.Underaged(username, name, lastname, birthday, orders)
            self.destroy_underaged_orders(new_user)
        elif username[-8:] == "INVESTOR":
            investor_username = username[:-8]
            new_user = self.user.Investor(investor_username, name, lastname, birthday, orders)
            new_user.has_priority = True
        else:
            new_user = self.user.Trader(username, name, lastname, birthday, orders)
            self.go_to_order_preview(new_user)
        self.user.User.get_money(new_user, self.list_of_coins)
        return type(self.user)

    def destroy_underaged_orders(self, underaged):  # aca destruyo todas las orders de los usuarios underaged
        if len(underaged.orders_id) != 0:
            list_of_orders = underaged.orders_id.split(":")
            for i in range(len(list_of_orders)):
                for order in self.order.Order.list_of_orders:
                    if order.order_id == list_of_orders[i]:
                        self.deleted_orders.append(order)
                        self.order.Order.list_of_orders.pop(self.order.Order.list_of_orders.index(order))
            underaged.orders_id = ""

    def go_to_order_preview(self, trader):  # add orders from traders and investors for being checked
        list_of_orders = trader.orders_id.split(":")
        if list_of_orders[0] == "":
            return
        for i in range(len(list_of_orders)):
            for order in self.order.Order.list_of_orders:
                if order.order_id == list_of_orders[i] and order.order_id not in self.pre_orders_review:
                    self.pre_orders_review.append(order)

    def _destroy_underaged_pair_orders(self):  # checks the matches between wrong orders, taking them out
        for i in range(len(self.pre_orders_review)):
            order = self.pre_orders_review[i]
            for j in range(len(self.deleted_orders)):
                del_order = self.deleted_orders[j]
                if order.price == del_order.price and order.amount == del_order.amount and order != del_order:
                    self.order.Order.list_of_orders.pop(self.order.Order.list_of_orders.index(order))
        self._add_trader_orders_and_markets_to_user()

    def _add_trader_orders_and_markets_to_user(self):  # add orders and markets to user
        for market in self.market.Market.list_of_markets:
            self.user.User.list_of_all_markets.append(market)
        for user in self.user.User.list_of_users:
            if len(user.orders_id) > 0:
                list_of_orders = user.orders_id.split(":")
                for order in self.order.Order.list_of_orders:
                    if order.order_id in list_of_orders and order.order_id not in user.list_of_orders:
                        user.list_of_orders.append(order)
                        for market in self.market.Market.list_of_markets:
                            if market.name == order.ticker and market not in user.list_of_markets_registered:
                                user.list_of_markets_registered.append(market)
        self._get_matches()

    def _get_matches(self):  # Agarra las orders que ya se ejecutaron, las guarda y elimina
        for order in self.order.Order.list_of_orders:
            if order.date_match != "":
                for user in self.user.User.list_of_users:
                    if order in user.list_of_orders and order.type == "bid":
                        for user_coin in user.currency_balances:
                            if order.ticker[:3] == user_coin.symbol:
                                user_coin.amount -= float(order.amount)
                            elif order.ticker[3:] == user_coin.symbol:
                                user_coin.amount += float(order.price)
                        user.list_historical_matches.append(order)
                        user.list_historical_matches.sort(key=lambda x: x.date_match)
                        user.list_of_orders.pop(user.list_of_orders.index(order))
                        break
                    elif order in user.list_of_orders and order.type == "ask":
                        for user_coin in user.currency_balances:
                            if order.ticker[:3] == user_coin.symbol:
                                user_coin.amount += float(order.amount)
                            elif order.ticker[3:] == user_coin.symbol:
                                user_coin.amount -= float(order.price)
                        user.list_historical_matches.append(order)
                        user.list_historical_matches.sort(key=lambda x: x.date_match)
                        user.list_of_orders.pop(user.list_of_orders.index(order))
                        break
                self.list_of_matches.append(order)
        self._add_matches_to_respective_places()

    def _add_matches_to_respective_places(self):
        for order in self.list_of_matches:
            self.order.Order.list_of_orders.pop(self.order.Order.list_of_orders.index(order))
        if len(self.list_of_matches) > 0:  # en caso de que no haya ningun match en el csv
            self.list_of_matches.sort(key=lambda x: x.date_match)
            for user in self.user.User.list_of_users:
                for market in user.list_of_all_markets:
                    for i in range(len(user.list_of_markets_registered)):
                        if market.name == user.list_of_markets_registered[i].name:
                            user.list_of_markets_registered[i] = market
            for user in self.user.User.list_of_users:
                user._save_markets()
                break
        self._get_order_ids_right()

    def _get_order_ids_right(self):
        for user in self.user.User.list_of_users:
            actual_ids = []
            user.orders_id = ""
            for user_order in user.list_of_orders:
                actual_ids.append(user_order.order_id)
            for i in range(len(actual_ids)):
                user.orders_id += str(actual_ids[i]) + ":"
            user.orders_id = user.orders_id[:-1]
            user.all_orders_id = user.orders_id[:-1]
        for order in self.order.Order.order_history:
            order._save_orders_csv()
            break

    def _kwargs_master(self, list_to_turn):  # obtiene los kwargs para ser entregados
        list_of_headers = []
        list_of_kwargs = []
        for i in range(len(list_to_turn)):
            if i == 0:
                for j in range(len(list_to_turn[0])):
                    header = ""
                    for string in list_to_turn[0][j]:
                        if string != ":":
                            header += string
                        else:
                            list_of_headers.append(header)
                            break
            elif i < len(list_to_turn) - 1:
                kwargs = {}
                for j in range(len(list_to_turn[i])):
                    kwarg1 = {list_of_headers[j]: list_to_turn[i][j]}
                    kwargs.update(kwarg1)
                list_of_kwargs.append(kwargs)
        return list_of_kwargs

menu = MainMenu()
MainMenu.instantiate_orders(menu)
MainMenu.instantiate_currencies(menu)
MainMenu.instantiate_users(menu)
MainMenu.instantiate_money(menu)
MainMenu.instantiate_historical_orders(menu)
MainMenu.instantiate_registered_markets(menu)
menu.run_main_menu()


#%%
import requests
import dateparser
import pandas as pd
import time

from bs4 import BeautifulSoup as bs
from selenium import webdriver
from selenium.webdriver.firefox.options import Options
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

chrome_options = Options()
chrome_options.add_argument("--headless")

driver = webdriver.Firefox(options=chrome_options)
headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36'}

#%%

listo = []

for page in range(1,7):

    start_url = f'https://coronavirus.nt.gov.au/updates?page={page}'

    print(f"Starting page{page}")
    driver.get(start_url)

    time.sleep(3)

    soup = bs(driver.page_source, 'html.parser')

    links = soup.find_all(class_='py-4')
    links = [x.a['href'] for x in links]

    print(f"There are {len(links)} links.")

    for link in links:
        r = requests.get(link)
        soup2 = bs(r.text, 'html.parser')

        datter = soup2.find(class_='publishedDate').text

        datto = dateparser.parse(datter)

        datto = datto.strftime('%Y-%m-%d')

        print(datto)

        stringo = ''
        texto = soup2.find_all("p")
        texto = [x.text for x in texto]

        # print(texto)

        for par in texto:
            if "in hospital" in par:
                stringo += par
                stringo += " "

        if len(stringo) > 1:
            print(stringo)

            data = [{'Date': datto, 'Text': stringo}]
            inter = pd.DataFrame.from_records(data)

            listo.append(inter)

            fin = pd.concat(listo)

            with open('archive/nt_scraping/scraped.csv', 'w') as f:
                fin.to_csv(f, index=False, header=True)

    # print(r.status_code)
    # print(links)
    # print(r.text)

# %%


from plyer import notification
import time

def notifyMe(title, message):
    notification.notify(
        title = title,
        message = message,
        app_icon = "D:\\Resume projects\\Notifier\\clock-icon.png",
        timeout = 10,
    )

if __name__ == '__main__':
    while True:
        notifyMe("Hey Swasthik , take a break now !!")
        time.sleep(1200)


#!/usr/bin/env python
# coding: utf-8

# In[1]:

from __future__ import absolute_import, division, print_function, unicode_literals
import tensorflow as tf
from tensorflow import keras
import numpy as np
import matplotlib.pyplot as plt

# In[2]:

fashion_mnist = keras.datasets.fashion_mnist

# In[3]:

(train_images, train_labels), (test_images, test_labels) = fashion_mnist.load_data()

# In[4]:

class_names = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat',
               'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']

# In[5]:

len(train_labels)

# In[6]:

test_images.shape
len(test_labels)

# In[7]:

train_images = train_images / 255.0

# In[8]:

test_images = test_images / 255.0

# In[19]:

plt.figure(figsize=(50,50))
for i in range(100):
    plt.subplot(10,10,i+1)
    plt.xticks([])
    plt.yticks([])
    plt.grid(False)
    plt.imshow(train_images[i], cmap=plt.cm.binary)
    #plt.xlabel(class_names[train_labels[i]]) // view with class labels
plt.show()

# In[20]:

model = keras.Sequential([
    keras.layers.Flatten(input_shape=(28, 28)),
    keras.layers.Dense(128, activation='relu'),
    keras.layers.Dense(10, activation='softmax')
])

# In[21]:

model.compile(optimizer='adam',
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])

# In[22]:

model.fit(train_images, train_labels, epochs=10)

# In[23]:

test_loss, test_acc = model.evaluate(test_images,  test_labels, verbose=2)
print('\nTest accuracy:', test_acc)
print("Test loss is", test_loss)

# In[57]:

predictions = model.predict(test_images)
for i in range(9999):
    print(predictions[i])
for i in range(num_images):
    plot_value_array(i, predictions[i], test_labels)


from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import Select
import time

driver = webdriver.Chrome(executable_path = r"C:\Users\daniel.vasev\Desktop\Boohoo\Lichna\Automation\Drivers\chromedriver_win32\chromedriver.exe")
driver.get("https://www.amazon.co.uk/")
driver.maximize_window()

#CAPTURE ALL COOKIES created by the browser
cookies = driver.get_cookies()
# how many cookies are store in the browser
print(len(cookies))
#print cookies
print(cookies)

#ADD NEW COOKIES to the browser
cookies = {"name":"DanielCookie","value":"123456789"}
driver.add_cookie(cookies)

cookies = driver.get_cookies()
print(len(cookies))
print(cookies)

#Deleting the cookies
driver.delete_cookie("DanielCookie")
cookies = driver.get_cookies()
print(len(cookies))
print(cookies)

time.sleep(5)
driver.quit()


import httplib
from socket import error as SocketError
from luigi.s3 import ReadableS3File

def _patched_s3_close(self):
    try:
        self.s3_key.close()
    except Exception:
        self.s3_key.close(fast=True)
    self.closed = True

def _patched_s3_iterator(self):
    key_iter = self.s3_key.__iter__()
    has_next = True
    index = 0
    while has_next:
        try:
            # grad the next chunk
            chunk = ''
            while True:
                try:
                    chunk = next(key_iter)
                    break
                except (httplib.IncompleteRead, SocketError) as e:
                    self.s3_key.close(fast=True)
                    self.s3_key.open(mode='r', headers={
                        'Range': 'bytes=%d-' % index
                        })
                    key_iter = self.s3_key.__iter__()
            index += len(chunk)

            # split on newlines, preserving the newline
            for line in chunk.splitlines(True):

                if not line.endswith(os.linesep):
                    # no newline, so store in buffer
                    self._add_to_buffer(line)
                else:
                    # newline found, send it out
                    if self.buffer:
                        self._add_to_buffer(line)
                        yield self._flush_buffer()
                    else:
                        yield line
        except StopIteration:
            # send out anything we have left in the buffer
            output = self._flush_buffer()
            if output:
                yield output
            has_next = False
    self.close()

def patch():
    ReadableS3File.close = _patched_s3_close
    ReadableS3File.__iter__ = _patched_s3_iterator

patch()


from typing import Any, Dict

from perception_dataset.constants import EXTENSION_ENUM
from perception_dataset.t4_dataset.classes.abstract_class import AbstractRecord, AbstractTable

class InstanceRecord(AbstractRecord):
    def __init__(self, category_token: str, instance_name: str = ""):
        super().__init__()
        self._category_token: str = category_token
        self._instance_name: str = instance_name
        self._nbr_annotations: int = 0
        self._first_annotation_token: str = ""
        self._last_annotation_token: str = ""

    def to_dict(self) -> Dict[str, Any]:
        d = {
            "token": self.token,
            "category_token": self._category_token,
            "instance_name": self._instance_name,
            "nbr_annotations": self._nbr_annotations,
            "first_annotation_token": self._first_annotation_token,
            "last_annotation_token": self._last_annotation_token,
        }
        return d

    def set_annotation_info(
        self, nbr_annotations: int, first_annotation_token: str, last_annotation_token: str
    ):
        self._nbr_annotations = nbr_annotations
        self._first_annotation_token = first_annotation_token
        self._last_annotation_token = last_annotation_token

class InstanceTable(AbstractTable):
    """https://github.com/tier4/tier4_perception_dataset/blob/main/docs/t4_format_3d_detailed.md#instancejson"""

    FILENAME = "instance" + EXTENSION_ENUM.JSON.value

    def __init__(self):
        super().__init__()
        self._id_to_token: Dict[str, str] = {}

    def _to_record(self, category_token: str, instance_name: str = ""):
        return InstanceRecord(category_token=category_token, instance_name=instance_name)

    def get_token_from_id(self, instance_id: str, category_token: str, dataset_name: str) -> str:
        if instance_id in self._id_to_token:
            token = self._id_to_token[instance_id]
        else:
            token = self.insert_into_table(
                category_token=category_token, instance_name=dataset_name + "::" + str(instance_id)
            )
            self._id_to_token[instance_id] = token

        return token


from argparse import Namespace

import torch
import torch.nn as nn

from .base import BarlowTwins

class Model(BarlowTwins):
    def __init__(self, args):
        super().__init__(args)

        sizes = {'bn': torch.Size([self.projector_sizes[-1]])}

        # create embedding matrix
        self.register_buffer("embedding", nn.init.orthogonal_(torch.empty(7, *sizes['bn'])))

        self.pos_weight = args.pos_weight
        self.scale_weight = args.scale_weight
        self.color_weight = args.color_weight

    def forward(self, x):
        return self.bn(self.projector(self.backbone(x)))

    def loss_forward(self, y1, y2, **kwargs):
        # args and kwargs should be on gpu
        delta_pos = torch.cat([kwargs[f'{key}_1'] - kwargs[f'{key}_0'] for key in ['cam_pos_x', 'cam_pos_y']], dim=1)*self.pos_weight
        delta_scale = torch.cat([kwargs[f'{key}_1'] - kwargs[f'{key}_0'] for key in ['cam_scale']], dim=1)*self.scale_weight
        delta_color = torch.cat([kwargs[f'{key}_1'] - kwargs[f'{key}_0'] for key in ['brightness', 'contrast', 'saturation', 'hue']], dim=1)*self.color_weight
        is_not_bw = ((1.0-kwargs['applied_RandomGrayscale_0'])*(1.0-kwargs['applied_RandomGrayscale_1'])).squeeze()
        is_color_jittered = (kwargs['applied_ColorJitter_0']*kwargs['applied_ColorJitter_1']).squeeze()
        delta_color = torch.einsum('b,bm->bm',is_not_bw*is_color_jittered,delta_color)

        delta_vec = torch.cat([delta_pos, delta_scale, delta_color], dim=1).matmul(self.embedding)
        z1 = self.bn(self.projector(self.backbone(y1)))
        z1 = z1 + delta_vec
        z2 = self.bn(self.projector(self.backbone(y2)))

        # empirical cross-correlation matrix
        c = z1.T @ z2

        # sum the cross-correlation matrix between all gpus
        c.div_(self.args.batch_size)
        torch.distributed.all_reduce(c)

        # use --scale-loss to multiply the loss by a constant factor
        # see the Issues section of the readme
        on_diag = torch.diagonal(c).add_(-1).pow_(2).sum().mul(self.args.scale_loss)
        off_diag = off_diagonal(c).pow_(2).sum().mul(self.args.scale_loss)
        loss = on_diag + self.args.lambd * off_diag
        return loss

    def get_encoder(self):
        return self.backbone

### Utilities ###

def off_diagonal(x):
    # return a flattened view of the off-diagonal elements of a square matrix
    n, m = x.shape
    assert n == m
    return x.flatten()[:-1].view(n - 1, n + 1)[:, 1:].flatten()

def equivariant_all_bn(projector='8192-8192-8192', batch_size=1024, scale_loss=0.024, lambd=0.0051, pos_weight=0.3, scale_weight=200.0, color_weight=150.0, **kwargs):
    args = Namespace(projector=projector, batch_size=batch_size, scale_loss=scale_loss, lambd=lambd, pos_weight=pos_weight, scale_weight=scale_weight, color_weight=color_weight, **kwargs)
    return Model(args)


#!/usr/bin/python
#==========================================
#
# FILE: Contour2geo.py
# USAGE : python Contour2geo.py -r res [-h] [-i <inputfile>] [-o <outputfile>] [--spline] ')
# DESCRIPTION:  Create a geometry file (.geo) for Gmsh from a closed contour
#
# BUGS: ---
#
# AUTHOR:   F. Gillet-Chaulet
# ORGANIZATION: IGE(CNRS-France)
#
# VERSION: V1
# CREATED: 2020-05-02
# MODIFIED:
#  * 2020-05-19: prescribe mesh size using uniform background field
#
#==========================================
import sys, getopt

def main(argv):
   import numpy  as np

   inputfile = 'Contour.txt'
   outputfile = 'Contour.geo'
   spline = False

   found_r=False
   try:
      opts, args = getopt.getopt(argv,"hi:o:r:",["spline","gmsh3"])
   except getopt.GetoptError:
      usage()
      sys.exit(2)
   for opt, arg in opts:
      if opt == '-h':
         usage()
         sys.exit()
      elif opt in ("-r"):
         el_size= arg
         found_r=True
      elif opt in ("-i"):
         inputfile = arg
      elif opt in ("-o"):
         outputfile = arg
      elif opt in ("--spline"):
         spline = True

   if not found_r:
      print('missing mandatory argument -r')
      usage()
      sys.exit(2)

   print('Input file is : %s'%(inputfile))
   print('Output file is :  %s'%(outputfile))
   if (spline):
      print('make contour using splines')
   else :
      print('make contour using compound lines')

###############
###############
   if inputfile.lower().endswith('.shp'):
      import shapefile
      sf = shapefile.Reader(inputfile)

      #number of layers
      nlayers=len(sf)
      print('found {0} features in the shapefile'.format(nlayers))

      # index array for BC conditions
      index=np.arange(nlayers, dtype=np.uint8)

      # get shape records
      shapeRecs = sf.shapeRecords()
      c=0
      for r in shapeRecs:
          # BC given by attribute
          if hasattr(r.record, 'BC'):
              index[c]=r.record.BC
          else:
          # or shape order
              index[c]=c+1
          c=c+1

      print('BC ordering by feature: ')
      print(index)

      # sort shapes by BC
      sarray=np.argsort(index)

      # start with first shape
      lnum=0
      shape = shapeRecs[sarray[lnum]]

      # it works only is last point is first point of next shape
      # check this
      if ((lnum+1)>(nlayers-1)) :
          nextshape=shapeRecs[sarray[0]]
      else:
          nextshape=shapeRecs[sarray[lnum+1]]
      if (shape.shape.points[-1] != nextshape.shape.points[0]):
          print('sorry only works if last point is first of next feature')
          sys.exit(2)

      # take all points except last
      npp=len(shape.shape.points)-1
      pts=shape.shape.points[0:npp]
      # there will be npp lines for this BC
      lines=[npp]

      for i in range(1,len(sarray)):
        lnum=i
        shape = shapeRecs[sarray[lnum]]
        # it works only is last point is first point of next shape
        # check this
        if ((lnum+1)>(nlayers-1)) :
          nextshape=shapeRecs[sarray[0]]
        else:
          nextshape=shapeRecs[sarray[lnum+1]]
        if (shape.shape.points[-1] != nextshape.shape.points[0]):
          print('sorry only works if last point is first of next feature')
          sys.exit(2)

        npp=len(shape.shape.points)-1
        pts.extend(shape.shape.points[0:npp])
        lines.append(npp)

      Contour = np.array(pts)
      x = Contour[:,0]
      y = Contour[:,1]
      Npt = len(x)

   else:
      # ascii files
      Contour = np.loadtxt(inputfile)
      x = Contour[:,0]
      y = Contour[:,1]

      if x[0]==x[-1] and y[0]==y[-1]:
        #print('Same first and last points in contour file')
        Npt = len(x)-1
      else:
        Npt = len(x)
      # only one closed contour
      lines=[Npt]

   print('found %i points'%Npt)

   # Open the output file
   geo = open(outputfile, 'w')
   geo.write('// This a a geo file created using the python script Contour2geo.py // \n')
   geo.write('Mesh.Algorithm=5; \n')
   geo.write('// To control the element size, one can directly modify the lc value in the geo file // \n')
   geo.write('lc = {0} ; \n'.format(el_size))
   geo.write('// Mesh size near the boundary from prescribed value  //\n')
   geo.write('Mesh.CharacteristicLengthFromCurvature = 0; \n')
   geo.write('Mesh.CharacteristicLengthFromPoints = 1; \n')
   geo.write('// Give a background field with uniform value for the mesh size  // \n')
   geo.write('Mesh.CharacteristicLengthExtendFromBoundary = 0; \n')
   geo.write('Field[1] = MathEval; \n')
   geo.write('Field[1].F = Sprintf("%g",lc); \n')
   geo.write('Background Field = 1; \n')

   # write the points coordinates (x,y,0,lc)
   np=0
   for j in range(0,Npt):
     np=np+1
     geo.write('Point({0}) = '.format(np)+r'{'+' {0}, {1}, 0.0, lc'.format(x[j],y[j])+r'}'+'; \n')

   # if spline
   if spline:

      l0=1
      nl=1
      for j in range(0,(len(lines)-1)):
        geo.write('Spline({0}) = '.format(nl)+r'{')
        lastp=lines[j]
        for k in range(0,lastp):
          geo.write('{0},'.format(l0+k))
        geo.write('{0}'.format(l0+lastp) +r'}' + '; \n')
        l0=l0+lastp
        nl=nl+1

      geo.write('Spline({0}) = '.format(nl)+r'{')
      lastp=lines[-1]
      for k in range(0,lastp):
          geo.write('{0},'.format(l0+k))
      geo.write('1}; \n')

      if len(lines) == 1 :
          geo.write('Line Loop(1) = {1}; \n')
      else:
          geo.write('Line Loop(1) = '+r'{'+'{0}:{1}'.format(1,len(lines)) +r'}' +'; \n')

      geo.write('Plane Surface(1) = {1}; \n')
      geo.write('Physical Surface(1) = {1}; \n')

      for j in range(0,len(lines)):
        geo.write('Physical Line({0}) = '.format(j+1) +r'{' +'{0}'.format(j+1) +r'}'+'; \n')

# else it is lines, as a spline might not work in all cases
   else:

      nl=0
      for j in range(0,Npt-1):
        nl=nl+1
        geo.write('Line({0}) = '.format(nl)+r'{'+'{0},{1}'.format(j+1,j+2)+r'}'+'; \n')
      geo.write('Line({0}) = '.format(nl+1)+r'{'+'{0},{1}'.format(j+2,1)+r'}'+'; \n')

      geo.write('Curve Loop(1) = '+r'{'+'{0}:{1}'.format(1,nl+1)+r'};'+' \n')
      geo.write('Plane Surface(1) = {1}; \n')

      # create physical curves
      l0=1
      phy=0
      for j in range(0,(len(lines)-1)):
        phy=phy+1
        lf=l0+lines[j]-1
        geo.write('Physical Curve({0}) = '.format(phy)+r'{'+'{0}:{1}'.format(l0,lf)+r'};'+' \n')
        l0=lf+1

      phy=phy+1
      lf=l0+lines[-1]-1
      geo.write('Physical Curve({0}) = '.format(phy)+r'{'+'{0}:{1}'.format(l0,lf)+r'};'+' \n')

      geo.write('Physical Surface(1) = {1}; \n')

   geo.close()

def usage():
   print('usage: Contour2geo.py -r res [-h] [-i <inputfile>] [-o <outputfile>] [--spline] ')
   print('options:')
   print('   -h [print help]')
   print('   -r res [resolution]')
   print('   -i <inputfile> [default:Contour.txt]')
   print('   -o <outputfile> [default:Contour.geo]')
   print('   --spline [using splines instead of compound lines]')

if __name__ == "__main__":
   main(sys.argv[1:])


import numpy as np
import matplotlib.pyplot as plt
from distributions import NormalDistribution
from credits import Debt, Loan

class Agent:
    def __init__(self, name, money, income, expenses, income_changes,
                 expenses_changes, excess_spending, Loan, Debt, age=216):
        self.name = name
        self.age = age
        self.initial_age = age
        self.money = money
        self.income = income
        self.previncome = income
        self.expenses = expenses
        self.working = 0
        self.Debt = Debt
        self.Loan = Loan
        self.hire = 0.20
        self.fire = 0.01
        self.excess_spending = excess_spending
        self.excess_spending_per_month = 0
        self.income_changes = income_changes
        self.expenses_changes = expenses_changes
        # self.Loan.get_loan(NormalDistribution(2000,200), NormalDistribution(5*12,6),NormalDistribution(15,3))
        self.results = {"age": [], "money": [], "income": [], "expenses": [],
                        "working": [], "total_debt": [], "excess_spending": []}

    def update(self):
        self.age += 1

        self.working = self.working_possibility(
            self.working, self.hire, self.fire)
        if(self.working):
            if(self.income == 0):
                self.income = 0.9 * self.previncome
                # self.income = 1000 * (1.01**((self.age - self.initial_age)//12))
            self.income += self.income_changes.random()

        elif(not self.working):
            if(self.income):
                self.previncome = self.income
            self.income = 0
        self.expenses += self.expenses_changes.random()

        self.money = self.pay_credit(
            self.money, self.income, self.expenses, self.Debt.sum_debt(), self.Loan.sum_loan(self.age))
        self.excess_spending_per_month = abs(self.excess_spending.random())
        self.money *= self.excess_spending_per_month
        self.add_results(self.age, self.money, self.income, self.expenses,
                         self.working, self.excess_spending_per_month)

    def working_possibility(self, past_inf, hire, fire):
        if past_inf:
            return np.random.choice([0, 1], p=[fire, 1 - fire])
        else:
            return np.random.choice([1, 0], p=[hire, 1 - hire])

    def add_results(self, age, money, income, expenses, working, excess_spending):
        self.results["age"].append(age)
        self.results["money"].append(money)
        self.results["income"].append(income)
        self.results["expenses"].append(expenses)
        self.results["working"].append(working)
        self.results["total_debt"].append(
            self.Debt.sum_debt_amount() + self.Loan.sum_loan_amount(self.age))
        self.results["excess_spending"].append(excess_spending)

    def pay_credit(self, money, income, expenses, sum_debt, sum_loan):

        money += income - expenses - sum_debt - sum_loan
        if(money < 0):
            self.Debt.add_debt((money) * (-1), np.random.randint(1, 24))
            money = 0
        self.Debt.update()
        self.Loan.update(self.age)
        return money

    def plot(self, entry):
        plt.plot(range(self.initial_age, self.age),
                 self.results[entry], label=entry)
        plt.legend()

    def plot_histogram(self, entry):
        plt.hist(self.results[entry], bins=100)
        plt.show()

    def show(self):
        plt.show()


""" AVL Tree implemented on top of the standard BST. """

__author__ = 'Alexey Ignatiev'
__docformat__ = 'reStructuredText'

from bst import BinarySearchTree
from typing import TypeVar, Generic
from node import AVLTreeNode

K = TypeVar('K')
I = TypeVar('I')

class AVLTree(BinarySearchTree, Generic[K, I]):
    """ Self-balancing binary search tree using rebalancing by sub-tree
        rotations of Adelson-Velsky and Landis (AVL).
    """

    def __init__(self) -> None:
        """
            Initialises an empty Binary Search Tree
            :complexity: O(1)
        """

        BinarySearchTree.__init__(self)

    def get_height(self, current: AVLTreeNode) -> int:
        """
            Get the height of a node. Return current. Height if current is
            not None. Otherwise, return 0.
            :complexity: O(1)
        """
        if current is not None:
            return current.height
        return 0

    def get_weight(self, current: AVLTreeNode) -> int:
        """
            Get the weight of a node. Return current. Weight if current is
            not None. Otherwise, return 0.
            :complexity: O(1)
        """
        if current is not None:
            return current.weight
        return 0

    def get_balance(self, current: AVLTreeNode) -> int:
        """
            Compute the balance factor for the current sub-tree as the value
            (right.height - left.height). If current is None, return 0.
            :complexity: O(1)
        """

        if current is None:
            return 0
        return self.get_height(current.right) - self.get_height(current.left)

    def insert_aux(self, current: AVLTreeNode, key: K, item: I) -> AVLTreeNode:
        """
            Attempts to insert an item into the tree, it uses the Key to insert
            it. After insertion, performs sub-tree rotation whenever it becomes
            unbalanced.
            returns the new root of the subtree.
        """
        if current is None:
            current = AVLTreeNode(key, item)
            self.length += 1  # self.length added in insert_aux already
        elif key < current.key:
            current.left = self.insert_aux(current.left, key, item)
        elif key > current.key:
            current.right = self.insert_aux(current.right, key, item)
        else:
            # key == current.key:
            # it'll raise ValueError anyway
            current.right = self.insert_aux(current.right, key, item)

        current.height_update()  # always update height and weight before balancing
        current.weight_update()
        current = self.rebalance(current)
        return current

    def delete_aux(self, current: AVLTreeNode, key: K) -> AVLTreeNode:
        """
            Attempts to delete an item from the tree, it uses the Key to
            determine the node to delete. After deletion,
            performs sub-tree rotation whenever it becomes unbalanced.
            returns the new root of the subtree.
        """
        if current is None:
            raise ValueError("Empty tree, can't delete node")
        elif key < current.key:
            current.left = self.delete_aux(current.left, key)
        elif key > current.key:
            current.right = self.delete_aux(current.right, key)
        else:
            # actual key found to do deletion  (key == current.key)
            if self.is_leaf(current):  # if current is a leaf, no child to return (both left right is None)
                self.length -= 1
                return None
            elif current.left is None:  # there exist a right node
                self.length -= 1
                return current.right
            elif current.right is None: # there exist a left node
                self.length -= 1
                return current.left

            # Find the successor to replace
            successor = self.get_successor(current)
            current.key = successor.key
            current.item = successor.item
            current.right = self.delete_aux(current.right, successor.key)

        current.height_update()  # always update height and weight before balancing
        current.weight_update()
        current = self.rebalance(current)
        return current

    def left_rotate(self, current: AVLTreeNode) -> AVLTreeNode:
        """
            Perform left rotation of the sub-tree.
            Right child of the current node, i.e. of the root of the target
            sub-tree, should become the new root of the sub-tree.
            returns the new root of the subtree.
            Example:

                 current                                       child
                /       \                                      /   \
            l-tree     child           -------->        current     r-tree
                      /     \                           /     \
                 center     r-tree                 l-tree     center

            :complexity: O(1)
        """
        child = current.right
        center = current.right.left

        current.right = center
        current.height_update()
        current.weight_update()

        child.left = current
        child.height_update()
        child.weight_update()
        return child

    def right_rotate(self, current: AVLTreeNode) -> AVLTreeNode:
        """
            Perform right rotation of the sub-tree.
            Left child of the current node, i.e. of the root of the target
            sub-tree, should become the new root of the sub-tree.
            returns the new root of the subtree.
            Example:

                       current                                child
                      /       \                              /     \
                  child       r-tree     --------->     l-tree     current
                 /     \                                           /     \
            l-tree     center                                 center     r-tree

            :complexity: O(1)
        """
        child = current.left
        center = current.left.right

        current.left = center
        current.height_update()
        current.weight_update()

        child.right = current
        child.height_update()
        child.weight_update()
        return child

    def rebalance(self, current: AVLTreeNode) -> AVLTreeNode:
        """ Compute the balance of the current node.
            Do rebalancing of the sub-tree of this node if necessary.
            Rebalancing should be done either by:
            - one left rotate
            - one right rotate
            - a combination of left + right rotate
            - a combination of right + left rotate
            returns the new root of the subtree.
        """
        if self.get_balance(current) >= 2:
            child = current.right
            if self.get_height(child.left) > self.get_height(child.right):
                current.right = self.right_rotate(child)
            return self.left_rotate(current)

        if self.get_balance(current) <= -2:
            child = current.left
            if self.get_height(child.right) > self.get_height(child.left):
                current.left = self.left_rotate(child)
            return self.right_rotate(current)

        return current

    def kth_largest(self, k: int) -> AVLTreeNode:
        """
            Returns the kth largest element in the tree. k = 1 would return the largest.
            :pre: must be 1 < k < num of available potions
            :complexity: O(log(n)) , where n is length of tree
        """
        # Exception for k
        if k < 1:
            raise IndexError("Can't be less than 1")
        elif k > self.length:
            raise IndexError("Can't be more than the number of available potions")

        current = self.root
        iterator = self.get_weight(current.right) + 1

        if iterator == k:  # base case is when root is the only node in tree
            return current
        else:
            return self.kth_largest_aux(current, k, iterator)

    def kth_largest_aux(self,current: AVLTreeNode, k: int, iterator: int) -> AVLTreeNode:
        if current is None:
            raise IndexError('Empty tree')

        left = current.left
        right = current.right

        if iterator < k:  # if iterators node is smaller than k
            iterator += 1 + self.get_weight(left.right)
            return self.kth_largest_aux(left, k, iterator)  # iterate to left node
        elif iterator > k:  # if iterators node is larger than k
            iterator -= 1 + self.get_weight(right.left)
            return self.kth_largest_aux(right, k, iterator)  # iterate to right node
        else:  # iterators node == k
            return current


#!/usr/bin/env python
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
import os
import tempfile
from unittest import mock

import mozunit

from mozperftest.system.profile import Profile, ProfileNotFoundError
from mozperftest.tests.support import get_running_env

def test_profile():
    mach_cmd, metadata, env = get_running_env()

    with Profile(env, mach_cmd) as profile:
        profile(metadata)
        profile_dir = env.get_arg("profile-directory")
        assert os.path.exists(profile_dir)

    assert not os.path.exists(profile_dir)

CALLS = [0]

def _return_profile(*args, **kw):
    if CALLS[0] == 0:
        CALLS[0] = 1
        raise ProfileNotFoundError()

    tempdir = tempfile.mkdtemp()

    return tempdir

@mock.patch("mozperftest.system.profile.get_profile", new=_return_profile)
def test_conditionedprofile():
    mach_cmd, metadata, env = get_running_env(profile_conditioned=True)

    with Profile(env, mach_cmd) as profile:
        profile(metadata)
        profile_dir = env.get_arg("profile-directory")
        assert os.path.exists(profile_dir)

    assert not os.path.exists(profile_dir)

if __name__ == "__main__":
    mozunit.main()


# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.

from marionette_driver.errors import InvalidArgumentException
from marionette_harness import MarionetteTestCase

class TestWindowRect(MarionetteTestCase):
    def setUp(self):
        super(TestWindowRect, self).setUp()

        self.original_rect = self.marionette.window_rect

        self.max = self.marionette.execute_script(
            """
            return {
              width: window.screen.availWidth,
              height: window.screen.availHeight,
            }""",
            sandbox=None,
        )

        # WebDriver spec says a resize cannot result in window being
        # maximised, an error is returned if that is the case; therefore if
        # the window is maximised at the start of this test, returning to
        # the original size via set_window_rect size will result in error;
        # so reset to original size minus 1 pixel width
        start_size = {
            "height": self.original_rect["height"],
            "width": self.original_rect["width"],
        }
        if (
            start_size["width"] == self.max["width"]
            and start_size["height"] == self.max["height"]
        ):
            start_size["width"] -= 10
            start_size["height"] -= 10
        self.marionette.set_window_rect(
            height=start_size["height"], width=start_size["width"]
        )

    def tearDown(self):
        x, y = self.original_rect["x"], self.original_rect["y"]
        height, width = self.original_rect["height"], self.original_rect["width"]

        self.marionette.set_window_rect(x=x, y=y, height=height, width=width)

        is_fullscreen = self.marionette.execute_script(
            "return document.fullscreenElement;", sandbox=None
        )
        if is_fullscreen:
            self.marionette.fullscreen()

        super(TestWindowRect, self).tearDown()

    def test_get_types(self):
        rect = self.marionette.window_rect
        self.assertIn("x", rect)
        self.assertIn("y", rect)
        self.assertIn("height", rect)
        self.assertIn("width", rect)
        self.assertIsInstance(rect["x"], int)
        self.assertIsInstance(rect["y"], int)
        self.assertIsInstance(rect["height"], int)
        self.assertIsInstance(rect["width"], int)

    def test_set_types(self):
        invalid_rects = (
            ["a", "b", "h", "w"],
            [1.2, 3.4, 4.5, 5.6],
            [True, False, True, False],
            [[], [], [], []],
            [{}, {}, {}, {}],
        )
        for x, y, h, w in invalid_rects:
            print("testing invalid type position ({},{})".format(x, y))
            with self.assertRaises(InvalidArgumentException):
                self.marionette.set_window_rect(x=x, y=y, height=h, width=w)

    def test_setting_window_rect_with_nulls_errors(self):
        with self.assertRaises(InvalidArgumentException):
            self.marionette.set_window_rect(height=None, width=None, x=None, y=None)

    def test_set_position(self):
        old_position = self.marionette.window_rect
        wanted_position = {"x": old_position["x"] + 10, "y": old_position["y"] + 10}

        new_position = self.marionette.set_window_rect(
            x=wanted_position["x"], y=wanted_position["y"]
        )
        expected_position = self.marionette.window_rect

        self.assertEqual(new_position["x"], wanted_position["x"])
        self.assertEqual(new_position["y"], wanted_position["y"])
        self.assertEqual(new_position["x"], expected_position["x"])
        self.assertEqual(new_position["y"], expected_position["y"])

    def test_set_size(self):
        old_size = self.marionette.window_rect
        wanted_size = {
            "height": old_size["height"] - 50,
            "width": old_size["width"] - 50,
        }

        new_size = self.marionette.set_window_rect(
            height=wanted_size["height"], width=wanted_size["width"]
        )
        expected_size = self.marionette.window_rect

        self.assertEqual(
            new_size["width"],
            wanted_size["width"],
            "New width is {0} but should be {1}".format(
                new_size["width"], wanted_size["width"]
            ),
        )
        self.assertEqual(
            new_size["height"],
            wanted_size["height"],
            "New height is {0} but should be {1}".format(
                new_size["height"], wanted_size["height"]
            ),
        )
        self.assertEqual(
            new_size["width"],
            expected_size["width"],
            "New width is {0} but should be {1}".format(
                new_size["width"], expected_size["width"]
            ),
        )
        self.assertEqual(
            new_size["height"],
            expected_size["height"],
            "New height is {0} but should be {1}".format(
                new_size["height"], expected_size["height"]
            ),
        )

    def test_set_position_and_size(self):
        old_rect = self.marionette.window_rect
        wanted_rect = {
            "x": old_rect["x"] + 10,
            "y": old_rect["y"] + 10,
            "width": old_rect["width"] - 50,
            "height": old_rect["height"] - 50,
        }

        new_rect = self.marionette.set_window_rect(
            x=wanted_rect["x"],
            y=wanted_rect["y"],
            width=wanted_rect["width"],
            height=wanted_rect["height"],
        )
        expected_rect = self.marionette.window_rect

        self.assertEqual(new_rect["x"], wanted_rect["x"])
        self.assertEqual(new_rect["y"], wanted_rect["y"])
        self.assertEqual(
            new_rect["width"],
            wanted_rect["width"],
            "New width is {0} but should be {1}".format(
                new_rect["width"], wanted_rect["width"]
            ),
        )
        self.assertEqual(
            new_rect["height"],
            wanted_rect["height"],
            "New height is {0} but should be {1}".format(
                new_rect["height"], wanted_rect["height"]
            ),
        )
        self.assertEqual(new_rect["x"], expected_rect["x"])
        self.assertEqual(new_rect["y"], expected_rect["y"])
        self.assertEqual(
            new_rect["width"],
            expected_rect["width"],
            "New width is {0} but should be {1}".format(
                new_rect["width"], expected_rect["width"]
            ),
        )
        self.assertEqual(
            new_rect["height"],
            expected_rect["height"],
            "New height is {0} but should be {1}".format(
                new_rect["height"], expected_rect["height"]
            ),
        )

    def test_move_to_current_position(self):
        old_position = self.marionette.window_rect
        new_position = self.marionette.set_window_rect(
            x=old_position["x"], y=old_position["y"]
        )

        self.assertEqual(new_position["x"], old_position["x"])
        self.assertEqual(new_position["y"], old_position["y"])

    def test_move_to_current_size(self):
        old_size = self.marionette.window_rect
        new_size = self.marionette.set_window_rect(
            height=old_size["height"], width=old_size["width"]
        )

        self.assertEqual(new_size["height"], old_size["height"])
        self.assertEqual(new_size["width"], old_size["width"])

    def test_move_to_current_position_and_size(self):
        old_position_and_size = self.marionette.window_rect
        new_position_and_size = self.marionette.set_window_rect(
            x=old_position_and_size["x"],
            y=old_position_and_size["y"],
            height=old_position_and_size["height"],
            width=old_position_and_size["width"],
        )

        self.assertEqual(new_position_and_size["x"], old_position_and_size["x"])
        self.assertEqual(new_position_and_size["y"], old_position_and_size["y"])
        self.assertEqual(new_position_and_size["width"], old_position_and_size["width"])
        self.assertEqual(
            new_position_and_size["height"], old_position_and_size["height"]
        )

    def test_move_to_negative_coordinates(self):
        old_position = self.marionette.window_rect
        print("Current position: {}".format(old_position["x"], old_position["y"]))
        new_position = self.marionette.set_window_rect(x=-8, y=-8)
        print(
            "Position after requesting move to negative coordinates: {}, {}".format(
                new_position["x"], new_position["y"]
            )
        )

        # Different systems will report more or less than (-8,-8)
        # depending on the characteristics of the window manager, since
        # the screenX/screenY position measures the chrome boundaries,
        # including any WM decorations.
        #
        # This makes this hard to reliably test across different
        # environments.  Generally we are happy when calling
        # marionette.set_window_position with negative coordinates does
        # not throw.
        #
        # Because we have to cater to an unknown set of environments,
        # the following assertions are the most common denominator that
        # make this test pass, irregardless of system characteristics.

        os = self.marionette.session_capabilities["platformName"]

        # Regardless of platform, headless always supports being positioned
        # off-screen.
        if self.marionette.session_capabilities["moz:headless"]:
            self.assertEqual(-8, new_position["x"])
            self.assertEqual(-8, new_position["y"])

        # Certain WMs prohibit windows from being moved off-screen,
        # but we don't have this information.  It should be safe to
        # assume a window can be moved to (0,0) or less.
        elif os == "linux":
            # certain WMs prohibit windows from being moved off-screen
            self.assertLessEqual(new_position["x"], 0)
            self.assertLessEqual(new_position["y"], 0)

        # On macOS, windows can only be moved off the screen on the
        # horizontal axis.  The system menu bar also blocks windows from
        # being moved to (0,0).
        elif os == "mac":
            self.assertEqual(-8, new_position["x"])
            self.assertEqual(23, new_position["y"])

        # It turns out that Windows is the only platform on which the
        # window can be reliably positioned off-screen.
        elif os == "windows":
            self.assertEqual(-8, new_position["x"])
            self.assertEqual(-8, new_position["y"])

    def test_resize_larger_than_screen(self):
        new_size = self.marionette.set_window_rect(
            width=self.max["width"] * 2, height=self.max["height"] * 2
        )
        actual_size = self.marionette.window_rect

        # in X the window size may be greater than the bounds of the screen
        self.assertGreaterEqual(new_size["width"], self.max["width"])
        self.assertGreaterEqual(new_size["height"], self.max["height"])
        self.assertEqual(actual_size["width"], new_size["width"])
        self.assertEqual(actual_size["height"], new_size["height"])

    def test_resize_to_available_screen_size(self):
        expected_size = self.marionette.set_window_rect(
            width=self.max["width"], height=self.max["height"]
        )
        result_size = self.marionette.window_rect

        self.assertGreaterEqual(expected_size["width"], self.max["width"])
        self.assertGreaterEqual(expected_size["height"], self.max["height"])
        self.assertEqual(result_size["width"], expected_size["width"])
        self.assertEqual(result_size["height"], expected_size["height"])

    def test_resize_while_fullscreen(self):
        self.marionette.fullscreen()
        expected_size = self.marionette.set_window_rect(
            width=self.max["width"] - 100, height=self.max["height"] - 100
        )
        result_size = self.marionette.window_rect

        self.assertTrue(
            self.marionette.execute_script(
                "return window.fullscreenElement == null", sandbox=None
            )
        )
        self.assertEqual(self.max["width"] - 100, expected_size["width"])
        self.assertEqual(self.max["height"] - 100, expected_size["height"])
        self.assertEqual(result_size["width"], expected_size["width"])
        self.assertEqual(result_size["height"], expected_size["height"])


"""litreview2 URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/3.2/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  path('', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.urls import include, path
    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
"""
from django.conf import settings
from django.conf.urls.static import static
from django.contrib import admin
from django.urls import path
from litreview import views

import authentication.views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', authentication.views.login_page, name="login"),
    path('register', authentication.views.signup_page, name="signup"),
    path('logout/', authentication.views.logout_user, name='logout'),
    path('flux', views.flux_page, name="flux"),
    path('ticket_creation', views.ticket_creation, name="ticket-creation"),
    path("own_posts", views.own_posts, name='posts'),
    path('review_after_ticket/<int:ticket_id>/', views.review_after_ticket, name='review-after-ticket'),
    path('review_from_scratch', views.review_from_scratch, name='review-from-scratch'),
    path('ticket/<int:ticket_id>/edit', views.edit_ticket, name='edit-ticket'),
    path("own_posts/<int:ticket_id>/delete", views.delete_ticket, name="delete-ticket"),
    path('review/<int:review_id>/edit', views.edit_review, name='edit-review'),
    path('review/<int:review_id>/delete', views.delete_review, name='delete-review'),
    path('follow-users', views.follow_user, name='follow-user'),
    path('unfollow/<int:relation_id>', views.end_follow, name='end-follow'),
]

if settings.DEBUG:
    urlpatterns += static(
        settings.MEDIA_URL, document_root=settings.MEDIA_ROOT
    )


import tensorflow as tf
from tensorflow import keras
from keras.utils import to_categorical
from keras.models import Sequential
from keras.layers import Dense, Flatten, Conv2D, Dropout, MaxPool2D
import numpy as np
import logging
import os

os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'

tf.get_logger().setLevel(logging.ERROR)

EPOCHS = 128
BATCH_SIZE = 32

if __name__ == '__main__':
	# load dataset
	cifar_dataset = keras.datasets.cifar10
	(train_images, train_labels), (test_images, test_labels) = cifar_dataset.load_data()

	# standardize dataset
	mean = np.mean(train_images)
	stddev = np.std(train_images)
	train_images = (train_images - mean) / stddev
	test_images = (test_images - mean) / stddev

	# change labels to one-hot
	train_labels = to_categorical(train_labels, num_classes=10)
	test_labels = to_categorical(test_labels, num_classes=10)

	# model with 2 convolutional and one fully connected layer
	model = Sequential()
	model.add(Conv2D(64, (4, 4),
									 activation='relu',
									 padding='same',
									 input_shape=(32, 32, 3)))
	model.add(Dropout(0.2))
	model.add(Conv2D(64, (2, 2),
									 strides=(2, 2),
									 activation='relu',
									 padding='same'))
	model.add(Dropout(0.2))
	model.add(Conv2D(32, (3, 3),
									 activation='relu',
									 padding='same'))
	model.add(Dropout(0.2))
	model.add(Conv2D(32, (3, 3),
									 activation='relu',
									 padding='same'))
	model.add(MaxPool2D(pool_size=(2, 2), strides=2))
	model.add(Dropout(0.2))
	model.add(Flatten())
	model.add(Dense(64, activation='relu'))
	model.add(Dropout(0.2))
	model.add(Dense(64, activation='relu'))
	model.add(Dropout(0.2))
	model.add(Dense(10, activation='softmax'))
	model.compile(loss='categorical_crossentropy',
								optimizer='adam',
								metrics=['accuracy'])
	model.summary()
	history = model.fit(train_images, train_labels,
											validation_data=(test_images, test_labels),
											epochs=EPOCHS,
											batch_size=BATCH_SIZE,
											verbose=2,
											shuffle=True)


"""Add on update cascade to movie

Revision ID: ddabac37ae7a
Revises: 20b585387c32
Create Date: 2020-03-28 12:21:47.985895

"""
from alembic import op
import sqlalchemy as sa

# revision identifiers, used by Alembic.
revision = 'ddabac37ae7a'
down_revision = '20b585387c32'
branch_labels = None
depends_on = None

def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.drop_constraint('user', 'movie', type_='foreignkey')
    op.create_foreign_key('user', 'movie', 'user', ['user_key'], ['key'], onupdate='cascade', ondelete='cascade')
    # ### end Alembic commands ###

def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.drop_constraint('user', 'movie', type_='foreignkey')
    op.create_foreign_key('user', 'movie', 'user', ['user_key'], ['key'], ondelete='CASCADE')
    # ### end Alembic commands ###


import bpy
import blf
import gpu
import bmesh
import numpy
import math
import copy
from math import radians, degrees
from mathutils import Vector, Matrix, Euler
from math import sin, cos, pi
from bpy_extras import view3d_utils
from gpu_extras.batch import batch_for_shader
from bpy_extras.view3d_utils import region_2d_to_vector_3d, region_2d_to_origin_3d, location_3d_to_region_2d
from bpy.props import BoolProperty

# get circle vertices on pos 2D by segments
def generate_circle_verts(position, radius, segments):
    coords = []
    coords.append(position)
    mul = (1.0 / segments) * (pi * 2)
    for i in range(segments):
        coord = (sin(i * mul) * radius + position[0], cos(i * mul) * radius + position[1])
        coords.append(coord)
    return coords

# get circle triangles by segments
def generate_circle_tris(segments, startID):
    triangles = []
    tri = startID
    for i in range(segments - 1):
        tricomp = (startID, tri + 1, tri + 2)
        triangles.append(tricomp)
        tri += 1
    tricomp = (startID, tri, startID + 1)
    triangles.append(tricomp)
    return triangles

# draw a circle on scene
def draw_bbox_active_point(self, context):
    point = self.target
    # if point != (0, 0):
    if point is not None:
        position = point
        color = bpy.context.preferences.addons['InteractionOps'].preferences.vo_cage_ap_color
        radius = bpy.context.preferences.addons['InteractionOps'].preferences.vo_cage_ap_size
        segments = 12
        # create vertices
        coords = generate_circle_verts(position, radius, segments)
        # create triangles
        triangles = generate_circle_tris(segments, 0)
        # set shader and draw
        shader = gpu.shader.from_builtin('2D_UNIFORM_COLOR')
        batch = batch_for_shader(shader, 'TRIS', {"pos": coords}, indices=triangles)
        shader.bind()
        shader.uniform_float("color", color)
        batch.draw(shader)

# draw multiple circle in one batch on screen
def draw_bbox_cage_points(self, context):
    positions = (self.object_bbox(context))[0]
    if positions is not None:
        color = bpy.context.preferences.addons['InteractionOps'].preferences.vo_cage_points_color
        radius = bpy.context.preferences.addons['InteractionOps'].preferences.vo_cage_p_size
        segments = 12
        coords = []
        triangles = []
        # create vertices
        for center in positions:
            actCoords = generate_circle_verts(center, radius, segments)
            coords.extend(actCoords)
        # create triangles
        for tris in range(len(positions)):
            actTris = generate_circle_tris(segments, tris * (segments + 1))
            triangles.extend(actTris)
        # set shader and draw
        shader = gpu.shader.from_builtin('2D_UNIFORM_COLOR')
        batch = batch_for_shader(shader, 'TRIS', {"pos": coords}, indices=triangles)
        shader.bind()
        shader.uniform_float("color", color)
        batch.draw(shader)

def draw_bbox_lines(self, context):
    coords = (self.object_bbox(context))[1]
    if len(coords) != 0:
        if len(coords) == 8:
            indices = (
                (0, 1), (1, 2), (2, 3), (3, 0),
                (4, 5), (5, 6), (6, 7), (7, 4),
                (0, 4), (1, 5), (2, 6), (3, 7)
            )
        elif len(coords) > 8:
            indices = (
                # Bbox
                (0, 1), (1, 2), (2, 3), (0, 3),   # X-
                (4, 5), (5, 6), (6, 7), (4, 7),   # X+
                (0, 4),                           # Y- BTM
                (1, 5),                           # Y- UP
                (3, 7),                           # Y-BTM
                (2, 6),                           # Y+UP
                # SUBD
                (8, 10), (9, 11),                 # X-
                (12, 14), (13, 15),               # X+
                (16, 17), (8, 12),                # Y-
                (10, 14), (18, 19),               # Y+
                (11, 15), (16, 19),               # Z-
                (17, 18), (9, 13),                # Z+
                # Center
                (20, 23),                         # +X
                (20, 21),                         # -X
                (20, 27),                         # +Y
                (20, 25),                         # -Y
                (20, 31),                         # +Z
                (20, 29),                         # -Z
            )
        else:
            indices = ()
        color = bpy.context.preferences.addons['InteractionOps'].preferences.vo_cage_color
        shader = gpu.shader.from_builtin('3D_UNIFORM_COLOR')
        batch = batch_for_shader(shader, 'LINES', {"pos": coords}, indices=indices)
        shader.bind()
        shader.uniform_float("color", color)
        batch.draw(shader)

def draw_iops_text(self, context, _uidpi, _uifactor):
    prefs = bpy.context.preferences.addons['InteractionOps'].preferences
    tColor = prefs.text_color
    tKColor = prefs.text_color_key
    tCSize = prefs.text_size
    tCPosX = prefs.text_pos_x
    tCPosY = prefs.text_pos_y
    tShadow = prefs.text_shadow_toggle
    tSColor = prefs.text_shadow_color
    tSBlur = prefs.text_shadow_blur
    tSPosX = prefs.text_shadow_pos_x
    tSPosY = prefs.text_shadow_pos_y

    iops_text = (
        ("World space group", "F1"),
        ("Local space for active", "F2"),
        ("World space for active", "F3"),
        ("Origin to World center", "W"),
        ("Selected to World center", "M"),
        ("Pick up active object", "Shift + LMB Click"),
    )

    # FontID
    font = 0
    blf.color(font, tColor[0], tColor[1], tColor[2], tColor[3])
    blf.size(font, tCSize, _uidpi)
    if tShadow:
        blf.enable(font, blf.SHADOW)
        blf.shadow(font, int(tSBlur), tSColor[0], tSColor[1], tSColor[2], tSColor[3])
        blf.shadow_offset(font, tSPosX, tSPosY)
    else:
        blf.disable(0, blf.SHADOW)

    textsize = tCSize
    # get leftbottom corner
    offset = tCPosY
    columnoffs = (textsize * 21) * _uifactor
    for line in reversed(iops_text):
        blf.color(font, tColor[0], tColor[1], tColor[2], tColor[3])
        blf.position(font, tCPosX * _uifactor, offset, 0)
        blf.draw(font, line[0])

        blf.color(font, tKColor[0], tKColor[1], tKColor[2], tKColor[3])
        textdim = blf.dimensions(0, line[1])
        coloffset = columnoffs - textdim[0] + tCPosX
        blf.position(0, coloffset, offset, 0)
        blf.draw(font, line[1])
        offset += (tCSize + 5) * _uifactor

class IOPS_OT_VisualOrigin(bpy.types.Operator):
    """Visual origin placing helper tool"""
    bl_idname = "iops.visual_origin"
    bl_label = "Visual origin"
    bl_options = {"REGISTER", "UNDO"}

    mouse_pos = (0, 0)
    cursor = []
    # RayCastResults
    result = False
    result_obj = None
    vp_objs = []
    vp_group = None

    # BBoxResults
    pos_batch = []
    pos_batch_3d = []

    # DrawCalculations
    batch_idx = None
    target = (0, 0)

    # Handlers list
    vp_handlers = []

    hold_cursor: BoolProperty(
        name="Hold cursor",
        description="Hold cursor location and rotation",
        default=True
    )

    @classmethod
    def poll(self, context):
        return (context.area.type == "VIEW_3D" and
                context.mode == "OBJECT" and
                context.view_layer.objects.active.type == "MESH" and
                context.view_layer.objects.selected[:] != [])

    # Place origin for selected objects
    def place_origin(self, context):
        objs = context.view_layer.objects.selected
        pos = self.pos_batch_3d[self.batch_idx]
        context.scene.cursor.location = pos
        for ob in objs:
            context.view_layer.objects.active = ob
            bpy.ops.object.origin_set(type="ORIGIN_CURSOR")

    # Place origin for selected objects
    def move_selected_to_world(self, context):
        objs = context.view_layer.objects.selected
        for ob in objs:
            ob.location = (0, 0, 0)

    # Place origin to world center
    def origin_to_world(self, context):
        objs = context.view_layer.objects.selected
        context.scene.cursor.location = (0, 0, 0)
        context.scene.cursor.rotation_euler = (0, 0, 0)
        for ob in objs:
            context.view_layer.objects.active = ob
            bpy.ops.object.origin_set(type="ORIGIN_CURSOR")

    # Calculate distance between raycasts
    def calc_distance(self, context):
        mouse_pos = self.mouse_pos
        pos_batch = self.pos_batch
        if len(pos_batch) != 0:
            act_dist = numpy.linalg.norm(pos_batch[0] - Vector(mouse_pos))
            act_id = 0
            counter = 1
            itertargets = iter(self.pos_batch)
            next(itertargets)
            for pos in itertargets:
                dist = numpy.linalg.norm(pos - Vector(mouse_pos))
                if dist < act_dist:
                    act_id = counter
                    act_dist = dist
                counter += 1
            self.batch_idx = act_id
            self.target = pos_batch[act_id]

    def getActiveFromSelected(self, context):
        selected_objects = []
        active_object = None
        for ob in context.view_layer.objects.selected:
            if ob.type == 'MESH':
                selected_objects.append(ob)
        for ob in selected_objects:
            if ob == context.view_layer.objects.active:
                active_object = ob

        return active_object, selected_objects

    def orphan_data_purge(self, context):
        # Clean Up Start
        for block in bpy.data.meshes:
            if block.users == 0:
                bpy.data.meshes.remove(block)
        for block in bpy.data.materials:
            if block.users == 0:
                bpy.data.materials.remove(block)
        for block in bpy.data.textures:
            if block.users == 0:
                bpy.data.textures.remove(block)
        for block in bpy.data.images:
            if block.users == 0:
                bpy.data.images.remove(block)
        # Clean Up End

    def getBBOX_from_selected(self, context):
        scene = bpy.context.scene
        sel_objs = []
        # Collect selected
        for ob in context.view_layer.objects.selected:
            if ob.type == 'MESH':
                sel_objs.append(ob)
        # Make duplicates
        dups = []
        for ob in sel_objs:
            matrix = ob.matrix_world
            dup_mesh = ob.data.copy()
            dup_obj = bpy.data.objects.new("iops_dups", dup_mesh)
            dup_obj.matrix_world = matrix
            context.scene.collection.objects.link(dup_obj)
            dups.append(dup_obj)
        # Deselect originals
        for ob in sel_objs:
            ob.select_set(False)
        # Select duplicates
        for ob in dups:
            ob.select_set(True)
        context.view_layer.objects.active = dups[-1]
        # Local view check
        view = bpy.context.space_data
        if view.local_view:
            bpy.ops.view3d.localview(frame_selected=False)
        # Join duplicates and Apply transformation
        if len(dups) != 1:
            bpy.ops.object.join()
            bpy.ops.object.transform_apply(location=True, rotation=True, scale=True)
        else:
            bpy.ops.object.transform_apply(location=True, rotation=True, scale=True)
        # Get Bounding box from result
        dup = context.view_layer.objects.active
        dup_bounds = dup.bound_box
        bbox_verts = []
        for v in dup_bounds:
            v_co = Vector(v)
            bbox_verts.append(v_co)

        # Removing duplicates
        bpy.data.objects.remove(dup, do_unlink=True, do_id_user=True, do_ui_user=True)

        # Create a bounding box mesh from duplicated objects
        mesh = bpy.data.meshes.new('iops_bbox_mesh')
        mesh.from_pydata(bbox_verts, [], [])
        bbox = bpy.data.objects.new("iops_bbox", mesh)
        context.scene.collection.objects.link(bbox)

        # Restore selection
        for ob in sel_objs:
            ob.select_set(True)
        context.view_layer.objects.active = sel_objs[-1]

        # Assign vars
        if self.vp_group is None:
            self.result = True
            self.result_obj = bbox
            self.vp_group = bbox

    def active_to_world(self, context):
        # Collect selected
        sel_objs = []
        for ob in context.view_layer.objects.selected:
            if ob.type == 'MESH':
                sel_objs.append(ob)

        res = self.result
        obj = context.view_layer.objects.active
        # Duplicate active obj
        matrix = obj.matrix_world
        dup_mesh = obj.data.copy()
        dup_obj = bpy.data.objects.new("iops_dups", dup_mesh)
        dup_obj.matrix_world = matrix
        context.scene.collection.objects.link(dup_obj)
        # Deselect originals
        for ob in sel_objs:
            ob.select_set(False)
        # Select duplicates
        dup_obj.select_set(True)
        context.view_layer.objects.active = dup_obj
        # Local view check
        view = bpy.context.space_data
        if view.local_view:
            bpy.ops.view3d.localview(frame_selected=False)
        # Apply transformation
        bpy.ops.object.transform_apply(location=True, rotation=True, scale=True, properties=True)

        # Get Bounding box from result
        dup_bounds = dup_obj.bound_box
        bbox_verts = []
        for v in dup_bounds:
            v_co = Vector(v)
            bbox_verts.append(v_co)
        # Removing duplicates
        bpy.data.objects.remove(dup_obj, do_unlink=True, do_id_user=True, do_ui_user=True)

        # Create a bounding box mesh from duplicated objects
        mesh = bpy.data.meshes.new('iops_bbox_mesh')
        mesh.from_pydata(bbox_verts, [], [])
        bbox = bpy.data.objects.new("iops_bbox", mesh)
        context.scene.collection.objects.link(bbox)
        # Restore selection
        for ob in sel_objs:
            ob.select_set(True)
        # Restore active obj
        context.view_layer.objects.active = obj
        # Assign vars
        if self.vp_group is None:
            self.result = True
            self.result_obj = bbox
            self.vp_group = bbox

    def scene_ray_cast(self, context):
        # get the context arguments
        scene = context.scene
        region = context.region
        rv3d = context.region_data
        coord = self.mouse_pos
        view_layer = context.view_layer
        depsgraph = context.evaluated_depsgraph_get()
        # get the ray from the viewport and mouse
        view_vector = region_2d_to_vector_3d(region, rv3d, coord)
        ray_origin = region_2d_to_origin_3d(region, rv3d, coord)
        ray_target = ray_origin + view_vector

        if bpy.app.version[0] == 2 and bpy.app.version[1] > 90:
            result, location, normal, index, obj, matrix = scene.ray_cast(view_layer.depsgraph, ray_origin, view_vector, distance=1.70141e+38)
        elif bpy.app.version[0] == 2 and bpy.app.version[1] <= 90:
            result, location, normal, index, obj, matrix = scene.ray_cast(view_layer, ray_origin, view_vector, distance=1.70141e+38)
        elif bpy.app.version[0] == 3 and bpy.app.version[1] >= 0:
            result, location, normal, index, obj, matrix = scene.ray_cast(depsgraph, ray_origin, view_vector, distance=1.70141e+38)

        if result and obj in self.vp_objs:
            context.view_layer.objects.active = obj
            self.result_obj = obj
        return result, obj

    def object_bbox(self, context):
        scene = context.scene
        region = context.region
        rv3d = context.region_data
        coord = self.mouse_pos
        view_layer = context.view_layer

        res = self.result
        obj = self.result_obj

        verts_pos = []
        bbox_batch = []
        bbox_batch_3d = []
        face_batch = []
        face_batch_3d = []
        if obj is not None:
            matrix = obj.matrix_world
            matrix_trans = matrix.transposed()
            bbox = obj.bound_box
            bbox_verts_3d = []
            if len(bbox) != 0:
                subd_vert_pos = []
                bbox_edges = (
                    (0, 1), (1, 2), (2, 3), (0, 3),
                    (4, 5), (5, 6), (6, 7), (4, 7),
                    (0, 4), (1, 5), (2, 6), (3, 7), (0, 6))
                bbox_subd_edges = (
                    (8, 10), (9, 11), (12, 14), (13, 15),
                    (16, 17), (8, 12), (10, 14), (18, 19),
                    (11, 15), (16, 19), (17, 18), (9, 13))

                # BBox
                for v in bbox:
                    pos = Vector(v) @  matrix_trans
                    bbox_verts_3d.append(pos)

                # BBox Edge subD
                for e in bbox_edges:
                    v1 = Vector(bbox[e[0]])
                    v2 = Vector(bbox[e[1]])
                    vertmid = (v1 + v2) / 2
                    pos = Vector(vertmid) @  matrix_trans
                    bbox_verts_3d.append(pos)

                for e in bbox_subd_edges:
                    v1 = Vector(bbox_verts_3d[e[0]])
                    v2 = Vector(bbox_verts_3d[e[1]])
                    vertmid = (v1 + v2) / 2
                    pos = Vector(vertmid)
                    bbox_verts_3d.append(pos)

                # BBOX COLLECT
                for v in bbox_verts_3d:
                    pos3D = v
                    pos2D = location_3d_to_region_2d(region, rv3d, pos3D, default=None)
                    if pos2D is None:
                        pos2D = Vector((0, 0))
                    bbox_batch_3d.append(pos3D)
                    bbox_batch.append(pos2D)

            self.pos_batch = bbox_batch
            self.pos_batch_3d = bbox_batch_3d
            return [bbox_batch, bbox_batch_3d]
        else:
            return [bbox_batch, bbox_batch]

    def clear_draw_handlers(self):
        for handler in self.vp_handlers:
            bpy.types.SpaceView3D.draw_handler_remove(handler, "WINDOW")

    def execute(self, context):
        self.place_origin(context)
        if self.vp_group is not None:
            bpy.data.objects.remove(self.vp_group, do_unlink=True, do_id_user=True, do_ui_user=True)
            self.vp_group = None
        try:
            self.clear_draw_handlers()
        except ValueError:
            pass
        self.orphan_data_purge(context)
        return {"FINISHED"}

    def modal(self, context, event):
        context.area.tag_redraw()
        if event.type in {'MIDDLEMOUSE', 'WHEELUPMOUSE', 'WHEELDOWNMOUSE'}:
            # allow navigation
            return {'PASS_THROUGH'}
        # Pick up in Local space
        elif event.shift:
            if event.type == 'LEFTMOUSE' and event.value == "PRESS":
                self.mouse_pos = event.mouse_region_x, event.mouse_region_y
                self.scene_ray_cast(context)
                self.object_bbox(context)
                self.calc_distance(context)
                if self.vp_group is not None:
                    bpy.data.objects.remove(self.vp_group, do_unlink=True, do_id_user=True, do_ui_user=True)
                    self.vp_group = None
                    self.orphan_data_purge(context)
        # Pick up in world space
        elif event.type == 'F3' and event.value == "PRESS":
            if self.vp_group is not None:
                bpy.data.objects.remove(self.vp_group, do_unlink=True, do_id_user=True, do_ui_user=True)
                self.vp_group = None
                self.orphan_data_purge(context)
            if self.vp_group is None:
                self.active_to_world(context)
                self.object_bbox(context)
                self.calc_distance(context)

        elif event.type == "F1" and event.value == "PRESS":
            if self.vp_group is not None:
                bpy.data.objects.remove(self.vp_group, do_unlink=True, do_id_user=True, do_ui_user=True)
                self.vp_group = None
                self.orphan_data_purge(context)
            if self.vp_group is None:
                self.getBBOX_from_selected(context)
                self.object_bbox(context)
                self.calc_distance(context)
                self.orphan_data_purge(context)

        elif event.type == "F2" and event.value == "PRESS":
            self.result_obj, self.vp_objs = self.getActiveFromSelected(context)
            self.object_bbox(context)
            self.calc_distance(context)
            if self.vp_group is not None:
                bpy.data.objects.remove(self.vp_group, do_unlink=True, do_id_user=True, do_ui_user=True)
                self.vp_group = None
                self.orphan_data_purge(context)

        elif event.type == 'W' and event.value == "PRESS":
            self.origin_to_world(context)
            if self.vp_group is not None:
                bpy.data.objects.remove(self.vp_group, do_unlink=True, do_id_user=True, do_ui_user=True)
            self.vp_group = None
            self.clear_draw_handlers()
            self.orphan_data_purge(context)
            return {"FINISHED"}

        elif event.type == 'M' and event.value == "PRESS":
            self.move_selected_to_world(context)
            if self.vp_group is not None:
                bpy.data.objects.remove(self.vp_group, do_unlink=True, do_id_user=True, do_ui_user=True)
            self.vp_group = None
            self.clear_draw_handlers()
            self.orphan_data_purge(context)
            return {"FINISHED"}

        elif event.type == 'MOUSEMOVE':
            self.mouse_pos = event.mouse_region_x, event.mouse_region_y
            self.calc_distance(context)

        elif event.type in {"LEFTMOUSE", "SPACE"}:
            self.execute(context)
            if self.hold_cursor:
                context.scene.cursor.location = self.cursor[0]
                context.scene.cursor.rotation_euler = self.cursor[1]
            return {"FINISHED"}

        elif event.type in {'RIGHTMOUSE', 'ESC'}:
            self.mouse_pos = [0, 0]
            self.result = False
            self.result_obj = None
            if self.vp_group:
                    bpy.data.objects.remove(self.vp_group, do_unlink=True, do_id_user=True, do_ui_user=True)
            self.clear_draw_handlers()
            self.orphan_data_purge(context)
            return {'CANCELLED'}

        return {'RUNNING_MODAL'}

    def invoke(self, context, event):
        preferences = context.preferences
        if context.space_data.type == 'VIEW_3D':
            # store_cursor loc and rot
            self.cursor = [context.scene.cursor.location.copy(),context.scene.cursor.rotation_euler.copy()]
            args = (self, context)
            self.mouse_pos = event.mouse_region_x, event.mouse_region_y
            self.result_obj, self.vp_objs = self.getActiveFromSelected(context)
            self.object_bbox(context)
            self.calc_distance(context)
            uidpi = int((72 * preferences.system.ui_scale))
            args_text = (self, context, uidpi, preferences.system.ui_scale)
            # Add draw handlers
            self._handle_iops_text = bpy.types.SpaceView3D.draw_handler_add(draw_iops_text, args_text, 'WINDOW', 'POST_PIXEL')
            self._handle_bbox_lines = bpy.types.SpaceView3D.draw_handler_add(draw_bbox_lines, args, 'WINDOW', 'POST_VIEW')
            self._handle_bbox_points = bpy.types.SpaceView3D.draw_handler_add(draw_bbox_cage_points, args, 'WINDOW', 'POST_PIXEL')
            self._handle_bbox_act_point = bpy.types.SpaceView3D.draw_handler_add(draw_bbox_active_point, args, 'WINDOW', 'POST_PIXEL')
            self.vp_handlers = [self._handle_iops_text, self._handle_bbox_lines, self._handle_bbox_points, self._handle_bbox_act_point]
            # Add modal handler to enter modal mode
            context.window_manager.modal_handler_add(self)
            return {'RUNNING_MODAL'}
        else:
            self.report({'WARNING'}, "Active space must be a View3d")
            return {'CANCELLED'}


from django.urls import path, include
from final_exam_recheck.FruitApp.views import fruit_create, fruit_details, fruit_edit, fruit_delete

urlpatterns = [
    path('create/', fruit_create, name='fruit create page'),
    path('<int:fruitID>/', include([
        path('details/', fruit_details, name='fruit details page'),
        path('edit/', fruit_edit, name='fruit edit page'),
        path('delete/', fruit_delete, name='fruit delete page'),
    ])),
]

Python-Web-Basics/00 Previous Exams/Python Web Basics - 24 June 2023/final_exam_recheck/final_exam_recheck/FruitApp/urls.py


import sys

from PyQt5.QtWidgets import QApplication
from PyQt5 import QtWidgets

from gui4us.controller.controller import *
from gui4us.view.control import *
from gui4us.view.display import *
from gui4us.state_graph import *

APP = None

def start_view(*args):
    global APP
    APP = QApplication(sys.argv)
    APP.setStyle("Fusion")
    view = View(*args)
    view.show()
    return APP.exec_()

class View(QtWidgets.QMainWindow):

    def __init__(self, title, cfg, controller: Controller):
        super().__init__()
        self.controller = controller
        self.text_format = Qt.MarkdownText
        self.statusBar().showMessage('Configuring...')
        try:
            self.setWindowTitle(title)
            # Main layout
            self.main_widget = QWidget()
            self.setCentralWidget(self.main_widget)
            self.main_layout = QHBoxLayout(self.main_widget)
            self.control_panel = ControlPanel(controller)
            self.display_panel = DisplayPanel(cfg.displays, controller, self)

            self.main_layout.addWidget(self.control_panel.backend_widget)
            self.main_layout.addWidget(self.display_panel.backend_widget)

            # Main application state, enter the init state.
            self.state_graph = StateGraph(
                states={
                    State("init", on_enter=self.on_init),
                    State("started"),
                    State("stopped")
                },
                actions={
                    Action("start"),
                    Action("stop")
                },
                transitions={
                    Transition("init", "start", "started", self.on_init_start),
                    Transition("started", "stop", "stopped", self.on_stopped),
                    Transition("stopped", "start", "started", self.on_started)
                }
            )

            self.state = StateGraphIterator(
                self.state_graph, start_state="init")

            # Register callbacks to be called when some events occur.
            self.control_panel.actions_panel.add_on_start_stop_callback(
                self.on_start_stop_pressed)
            self.showMaximized()
            # self.adjustSize()
            # self.setFixedSize(self.size())

        except Exception as e:
            print(traceback.format_exc())
            print(e)
            self.controller.close()

    def on_start_stop_pressed(self):
        if self.state.is_current_state({"init", "stopped"}):
            self.state.do("start")
        else:
            self.state.do("stop")

    def on_init(self, event):
        self.control_panel.actions_panel.enable()
        self.control_panel.settings_panel.disable()
        self.control_panel.buffer_panel.disable()
        self.statusBar().showMessage(
            "Ready, press 'Start' button to start the hardware.")

    def on_init_start(self, event):
        self.statusBar().showMessage("Starting system.")
        self.on_started(event)

    def on_started(self, event):
        self.control_panel.settings_panel.enable()
        self.control_panel.buffer_panel.enable()
        self.display_panel.start()
        self.control_panel.buffer_panel.start()
        self.statusBar().showMessage("Running.")

    def on_stopped(self, event):
        self.control_panel.settings_panel.disable()
        self.control_panel.actions_panel.disable()
        self.statusBar().showMessage("Stopped.")

    def closeEvent(self, event):
        self.controller.close()
        event.accept()