import tflite_runtime.interpreter as tflite
import numpy as np
import sys

def state_to_tensor(state, move):
    vec = np.zeros((1,7), dtype=np.float32)
    if move != -1:
        vec[0, move] = 1
        tensor = np.append(vec, state, axis=0)
        tensor = tensor.reshape((1,7,7,1))
        return tensor

def available_moves(state):
    avaiable_move_list = []
    for i in range(7):
        if state[0][i] == 0:
            avaiable_move_list.append(i)
    return avaiable_move_list

m_path = ""
difficulty = sys.argv[2]
if 'dummy' in difficulty:
    m_path = 'AI/model_values_connect_four__second_0_dummy.tflite'
elif 'easy' in difficulty:
    m_path = 'AI/model_values_connect_four__second_49_easy.tflite'
elif 'medium' in difficulty:
    m_path = 'AI/model_values_connect_four__second_99_medium.tflite'
elif 'hard' in difficulty:
    m_path = 'AI/model_values_connect_four__second_149_hard.tflite'
elif 'expert' in difficulty:
    m_path = 'AI/model_values_connect_four__first_hard.tflite'
else:
     m_path = 'AI/model_values_connect_four__first_hard.tflite'

interpreter = tflite.Interpreter(model_path=m_path)
interpreter.allocate_tensors()

input_details = interpreter.get_input_details()
output_details = interpreter.get_output_details()

floating_model = input_details[0]['dtype'] == np.float32

state = np.zeros((6,7), dtype=np.float32)
#state[0][0] = float(1)

data = sys.argv[1]
data_split = data.split('.')
data_split = [i.split(',') for i in data_split]
for r_ctr, row in enumerate(data_split):
    for c_ctr, value in enumerate(row):
        state[r_ctr][c_ctr] = float(value)

# Loop through each possible move and decide what's best
best_move = -1
best_value = -99999
# Loop only through legal moves
for move in available_moves(state):
    input_data = state_to_tensor(state, move)
    interpreter.set_tensor(input_details[0]['index'], input_data)

    #Invoke model
    interpreter.invoke()

    # Get result
    output_data = interpreter.get_tensor(output_details[0]['index'])
    result = np.squeeze(output_data)

    # Obtain the best move possible
    if result > best_value:
        best_value = result
        best_move = move

print(best_move)


# coding:utf-8
import socket

HOST = '192.168.3.51'
PORT = 21567
ADDR = (HOST, PORT)
BUF = 1024

client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(ADDR)

while True:
    data = input('data to send:')
    if not data:
        break

    client.send(data.encode('utf-8'))
    print('data sent')
    data = client.recv(BUF)
    print('recv data: ', data)

client.close()


import peachy
import peachy.geo

class HidingSpot(peachy.Entity):

    def __init__(self, x, y, width, height):
        peachy.Entity.__init__(self)
        peachy.geo.Rect.__init__(x, y, width, height)
        self.group = 'hiding-spot interact'
        self.visible = False

    def render(self):
        peachy.graphics.set_color(0, 0, 0)
        peachy.graphics.draw_rect(self.x, self.y, self.width, self.height)


import streamlit as st
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.svm import SVC
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import RandomForestClassifier
from sklearn.preprocessing import LabelEncoder
from sklearn.model_selection import train_test_split
from sklearn.metrics import plot_confusion_matrix, plot_roc_curve, plot_precision_recall_curve
from sklearn.metrics import precision_score, recall_score

def main():
    st.title('Binary Classification Web Application')
    st.sidebar.title('Binary Classification Web Application')
    st.markdown('Are your mushrooms edible?  馃崉')
    st.sidebar.markdown('Are your mushrooms edible?  馃崉')

    @st.cache_data(persist=True)
    def load_data():
        df = pd.read_csv('mushrooms.csv')
        label_encoder = LabelEncoder()
        for col in df.columns:
            df[col] = label_encoder.fit_transform(df[col])
        return df

    @st.cache_data(persist=True)
    def split_data(dataset):
        X = np.array(dataset.drop('type', axis=1))
        y = np.array(dataset['type'])

        x_train, x_test, y_train, y_test = train_test_split(
            X, y, test_size=0.3, random_state=0)
        return x_train, x_test, y_train, y_test

    def plot_metrics(model, metrics_list):
        if 'Confusion Matrix' in metrics_list:
            st.subheader('Confusion Matrix')
            fig, ax = plt.subplots()
            plot_confusion_matrix(model, x_test, y_test,
                                  display_labels=class_names, ax=ax)
            st.pyplot(fig)

        if 'ROC Curve' in metrics_list:
            st.subheader('Receiver Operating Characteristic Curve')
            fig, ax = plt.subplots()
            plot_roc_curve(model, x_test, y_test, ax=ax)
            st.pyplot(fig)

        if 'Precision-Recall Curve' in metrics_list:
            st.subheader('Precision-Recall Curve')
            fig, ax = plt.subplots()
            plot_precision_recall_curve(model, x_test, y_test, ax=ax)
            st.pyplot(fig)

    df = load_data()
    x_train, x_test, y_train, y_test = split_data(df)
    class_names = ['Edible', 'Poisonous']
    metrics_list = ['Confusion Matrix', 'ROC Curve', 'Precision-Recall Curve']

    if st.sidebar.checkbox('Show raw data', False):
        st.subheader('Mushroom dataset for classification')
        st.write(df)

    st.sidebar.subheader('Select a Classifier')
    classifier = st.sidebar.selectbox(
        'Classifier: ', ('Support Vector Machine', 'Logistic Regression', 'Random Forest'))

    if classifier == 'Support Vector Machine':
        st.sidebar.subheader('Model Hyperparameters')
        位 = st.sidebar.number_input(
            '位 (Regularization Parameter): ', 0.01, 10.0, step=0.01, key='位_svm')
        kernel = st.sidebar.radio('Kernel: ', ('rbf', 'linear'), key='kernel')
        纬 = st.sidebar.radio('纬 (Kernel Coefficient): ',
                             ('scale', 'auto'), key='纬')

        metrics = st.sidebar.multiselect(
            'Select which metrics to plot: ', metrics_list)

        if st.sidebar.button('Classify', key='classify'):
            st.subheader('Support Vector Machine Classification Results: ')
            model = SVC(C=位, kernel=kernel, gamma=纬)
            model.fit(x_train, y_train)
            predictions = model.predict(x_test)
            accuracy = model.score(x_test, y_test)
            precision = precision_score(
                y_test, predictions, labels=class_names)
            recall = recall_score(y_test, predictions, labels=class_names)
            st.write(f'Accuracy: {accuracy: .2f}')
            st.write(f'Precision: {precision: .2f}')
            st.write(f'Recall: {recall: .2f}')
            plot_metrics(model, metrics)

    if classifier == 'Logistic Regression':
        st.sidebar.subheader('Model Hyperparameters')
        位 = st.sidebar.number_input(
            '位 (Regularization Parameter): ', 0.01, 10.0, step=0.01, key='位_lr')
        max_iter = st.sidebar.slider(
            'Maximum Number of Iterations:', 1, 500, key='max_iter')

        metrics = st.sidebar.multiselect(
            'Select which metrics to plot: ', metrics_list)

        if st.sidebar.button('Classify', key='classify'):
            st.subheader('Logistic Regression Classification Results: ')
            model = LogisticRegression(C=位, max_iter=max_iter)
            model.fit(x_train, y_train)
            predictions = model.predict(x_test)
            accuracy = model.score(x_test, y_test)
            precision = precision_score(
                y_test, predictions, labels=class_names)
            recall = recall_score(y_test, predictions, labels=class_names)
            st.write(f'Accuracy: {accuracy: .2f}')
            st.write(f'Precision: {precision: .2f}')
            st.write(f'Recall: {recall: .2f}')
            plot_metrics(model, metrics)

    if classifier == 'Random Forest':
        st.sidebar.subheader('Model Hyperparameters')
        n_estimators = st.sidebar.number_input(
            'Number of trees in the forest: ', 100, 500, step=10, key='n_estimators')
        max_depth = st.sidebar.number_input(
            'Maximum depth of the forest: ', 1, 20, step=1, key='max_depth')
        metrics = st.sidebar.multiselect(
            'Select which metrics to plot: ', metrics_list)

        if st.sidebar.button('Classify', key='classify'):
            st.subheader('Random Forest Classification Results: ')
            model = RandomForestClassifier(
                n_estimators=n_estimators, max_depth=max_depth)
            model.fit(x_train, y_train)
            predictions = model.predict(x_test)
            accuracy = model.score(x_test, y_test)
            precision = precision_score(
                y_test, predictions, labels=class_names)
            recall = recall_score(y_test, predictions, labels=class_names)
            st.write(f'Accuracy: {accuracy: .2f}')
            st.write(f'Precision: {precision: .2f}')
            st.write(f'Recall: {recall: .2f}')
            plot_metrics(model, metrics)

if __name__ == '__main__':
    main()


import logging
import torch
import torch.nn as nn

class ClassificationNetwork(nn.Module):
    def __init__(self, num_inputs, hidden_size, num_outputs):
        super(ClassificationNetwork, self).__init__()
        # Fully connected and ReLU layers
        self.fc1 = nn.Linear(num_inputs, hidden_size)
        self.fc2 = nn.Linear(hidden_size, num_outputs)
        self.relu = nn.ReLU(inplace=True)
        self.dropout = nn.Dropout(p=0.5)

        self._init_weights() # Initialize weights
        self._get_trainable_params() # Print number of trainable parameters

    def forward(self, x1, x2):
        x = x1 * x2
        x = self.fc1(x)
        x = self.relu(x)
        x = self.dropout(x)
        x = self.fc2(x)
        return x

    def _init_weights(self):
        for m in self.modules():
            if isinstance(m, nn.Linear):
                nn.init.xavier_normal_(m.weight)
                nn.init.uniform_(m.bias)

    def _get_trainable_params(self):
        num_params = sum(p.numel() for p in self.parameters() if p.requires_grad)
        logging.info('Number of trainable parameters in ClassificationNetwork: {}'.format(num_params))
        return num_params


from plugins import *

class Greetings(Frame):
    def __init__(self, parent, *args, **kwargs):
        Frame.__init__(self, parent, bg='black')
        # Initialize main greetings
        self.main_greeting = ''
        self.mainLbl = Label(self, font=('Helvetica', large_text_size), fg="white", bg="black")
        self.mainLbl.pack(fill="none", expand=True)
        # self.timeLbl.place(relx=.5, rely=.5, anchor="center")
        # Initialize Dobby's replies
        self.dobby_greeting = ''
        self.dobbyLbl = Label(self, text=self.dobby_greeting, font=('Helvetica', small_text_size), fg="white", bg="black")
        self.dobbyLbl.pack(fill="none", expand=True)

        self.greet()

    def greet(self):
        self.main_greeting = 'Hello Buddy!!'
        self.dobby_greeting = 'Hello, Dobby here ..'
        self.mainLbl.config(text=self.main_greeting)
        self.dobbyLbl.config(text=self.dobby_greeting)


from typing import Dict

from .. import Provider as LoremProvider

class Provider(LoremProvider):
    """Implement lorem provider for ``fil_PH`` locale.

    Word list is based on the source(s) below with some filtering,
    de-conjugating, and additional common words.

    Sources:

    - https://1000mostcommonwords.com/1000-most-common-filipino-words/
    """

    word_list = (
        "abo",
        "abot",
        "aga",
        "agham",
        "akin",
        "aklat",
        "ako",
        "akyat",
        "alam",
        "alang-alang",
        "alikabok",
        "alin",
        "alok",
        "alon",
        "ama",
        "amin",
        "amoy",
        "anak",
        "ang",
        "angkop",
        "anim",
        "ano",
        "antas",
        "apat",
        "aral",
        "araw",
        "ari-arian",
        "asa",
        "asawa",
        "asin",
        "aso",
        "asukal",
        "asul",
        "at",
        "atin",
        "away",
        "ay",
        "ayos",
        "baba",
        "babae",
        "babaw",
        "bagal",
        "bagaman",
        "bagay",
        "bago",
        "bagyo",
        "bahagi",
        "bahay",
        "baka",
        "bakal",
        "bakasyon",
        "bakit",
        "bakuran",
        "balat",
        "balde",
        "balikat",
        "banat",
        "banda",
        "bangka",
        "bangko",
        "bansa",
        "barko",
        "basa",
        "basehan",
        "baso",
        "bata",
        "batas",
        "batay",
        "bato",
        "bawas",
        "bawat",
        "bayad",
        "bayan",
        "baybayin",
        "benta",
        "bente",
        "berde",
        "bibig",
        "bigas",
        "bigat",
        "bigay",
        "bigkas",
        "bihira",
        "bilang",
        "bili",
        "bilis",
        "binata",
        "binibini",
        "binti",
        "biyahe",
        "biyaya",
        "boses",
        "braso",
        "buhangin",
        "buhay",
        "buhok",
        "bukas",
        "bulaklak",
        "bundok",
        "buntot",
        "buo",
        "burol",
        "butas",
        "buti",
        "buto",
        "buwan",
        "daan",
        "dagat",
        "dagdag",
        "dahil",
        "dahilan",
        "dala",
        "dalaga",
        "dalas",
        "dalawampu",
        "daliri",
        "daloy",
        "damit",
        "damo",
        "dapat",
        "dati",
        "dating",
        "digmaan",
        "dilaw",
        "disenyo",
        "dito",
        "doon",
        "dugo",
        "dyip",
        "edad",
        "eksakto",
        "eksperimento",
        "elemento",
        "enerhiya",
        "epekto",
        "eroplano",
        "espesyal",
        "estado",
        "gabi",
        "gala",
        "galaw",
        "galit",
        "gamit",
        "gamot",
        "gana",
        "ganap",
        "ganda",
        "gas",
        "gastos",
        "gatas",
        "gawa",
        "gawin",
        "gilid",
        "giliw",
        "ginang",
        "ginoo",
        "ginto",
        "gising",
        "gitna",
        "gubat",
        "guhit",
        "gulo",
        "gulong",
        "gusto",
        "haba",
        "habang",
        "hakbang",
        "halaga",
        "halalan",
        "halaman",
        "haligi",
        "halimbawa",
        "hambing",
        "hanap",
        "hanapbuhay",
        "hanay",
        "handa",
        "hanggan",
        "hanggang",
        "hangin",
        "hardin",
        "hati",
        "hatid",
        "hatol",
        "hayop",
        "higit",
        "hila",
        "hilaga",
        "hilera",
        "himpapawid",
        "hindi",
        "hintay",
        "hirap",
        "hiwa",
        "hiwalay",
        "hugis",
        "hula",
        "huli",
        "hulog",
        "humantong",
        "husay",
        "iba",
        "ibabaw",
        "ibig",
        "ibon",
        "ilalim",
        "ilan",
        "ilang",
        "ilog",
        "ilong",
        "industriya",
        "ingay",
        "inggit",
        "init",
        "inom",
        "insekto",
        "instrumento",
        "inumin",
        "ipon",
        "isa",
        "isda",
        "isip",
        "iskor",
        "isla",
        "itim",
        "itlog",
        "ito",
        "iwan",
        "iyon",
        "kaaway",
        "kababaihan",
        "kabayo",
        "kabuuan",
        "kaganapan",
        "kahit",
        "kahon",
        "kaibigan",
        "kailangan",
        "kailanman",
        "kain",
        "kaisa-isa",
        "kakaiba",
        "kalabit",
        "kalagayan",
        "kalahati",
        "kalakal",
        "kalakalan",
        "kalsada",
        "kalye",
        "kama",
        "kamay",
        "kampanilya",
        "kampo",
        "kanin",
        "kanluran",
        "kanta",
        "kanya",
        "kapag",
        "kapal",
        "kapangyarihan",
        "kapantay",
        "kapatid",
        "kapit-bahay",
        "kapital",
        "kapitan",
        "kapwa",
        "karagatan",
        "karamihan",
        "karanasan",
        "karaniwan",
        "karapatan",
        "karne",
        "kasalukuyan",
        "kasama",
        "kasanayan",
        "kasangkapan",
        "kasaysayan",
        "kaso",
        "katangian",
        "katarungan",
        "katawan",
        "katinig",
        "katulad",
        "katunayan",
        "kawal",
        "kaya",
        "kaysa",
        "kayumanggi",
        "kilos",
        "kinang",
        "kinig",
        "klase",
        "ko",
        "kompanya",
        "koponan",
        "kopya",
        "kotse",
        "kuha",
        "kulay",
        "kumpleto",
        "kung",
        "kuskos",
        "kuwento",
        "laban",
        "lagay",
        "lagda",
        "lago",
        "lahat",
        "lahi",
        "lakad",
        "lakas",
        "laki",
        "lalim",
        "lalo",
        "laman",
        "lamang",
        "lambak",
        "lambot",
        "lamig",
        "landas",
        "langis",
        "langit",
        "langoy",
        "lapit",
        "larawan",
        "laro",
        "lason",
        "lawa",
        "lawak",
        "layag",
        "layo",
        "leeg",
        "libo",
        "libre",
        "ligaw",
        "ligtas",
        "liit",
        "likas",
        "likha",
        "likido",
        "likod",
        "lima",
        "linaw",
        "linggo",
        "linis",
        "linya",
        "lipad",
        "listahan",
        "litaw",
        "liwanag",
        "lubid",
        "lugar",
        "luma",
        "lungsod",
        "lupa",
        "lupon",
        "lutas",
        "luwag",
        "maaari",
        "maaga",
        "madali",
        "maging",
        "maginoo",
        "magkano",
        "magulang",
        "mahal",
        "mahalaga",
        "mahirap",
        "maikli",
        "mainam",
        "mainit",
        "mais",
        "makina",
        "mali",
        "maliban",
        "manatili",
        "manggagawa",
        "mangyari",
        "mangyaring",
        "manipis",
        "maniwala",
        "mansanas",
        "mapa",
        "marahil",
        "marami",
        "mas",
        "masa",
        "masyado",
        "mata",
        "may",
        "mayroon",
        "medyo",
        "merkado",
        "mga",
        "milyon",
        "minahan",
        "minuto",
        "mukha",
        "mula",
        "muli",
        "mundo",
        "musika",
        "na",
        "naging",
        "nais",
        "nakita",
        "namin",
        "nanay",
        "nawala",
        "nayon",
        "ng",
        "ngayon",
        "ngipin",
        "ngiti",
        "ngunit",
        "noon",
        "numero",
        "oo",
        "opisina",
        "opo",
        "oras",
        "orihinal",
        "pa",
        "paa",
        "paaralan",
        "pabor",
        "pabuya",
        "pader",
        "pagitan",
        "pakiramdam",
        "paksa",
        "palagi",
        "palapag",
        "pamamagitan",
        "pamilya",
        "panahon",
        "panalo",
        "pandiwa",
        "pangalan",
        "panganib",
        "pangarap",
        "pangkat",
        "pangmaramihang",
        "pangngalan",
        "pangunahin",
        "pantig",
        "panuntunan",
        "papel",
        "para",
        "paraan",
        "pareho",
        "pares",
        "parirala",
        "parisukat",
        "partido",
        "pasa",
        "pasiya",
        "pasok",
        "patakaran",
        "patlang",
        "patnubay",
        "pato",
        "payag",
        "pera",
        "pigil",
        "pilak",
        "pili",
        "pindot",
        "pinto",
        "piraso",
        "pito",
        "plano",
        "port",
        "posible",
        "posisyon",
        "problema",
        "produkto",
        "proseso",
        "prutas",
        "pula",
        "puno",
        "punta",
        "punto",
        "pusa",
        "puso",
        "puti",
        "puwang",
        "puwersa",
        "radyo",
        "rehiyon",
        "resulta",
        "sa",
        "saan",
        "sabay",
        "sabi",
        "sagot",
        "sakahan",
        "salamat",
        "salamin",
        "sali",
        "salita",
        "sama",
        "sampu",
        "sandali",
        "sang-ayon",
        "sangay",
        "sanggol",
        "sapat",
        "sapatos",
        "sarili",
        "sariwa",
        "saya",
        "sayaw",
        "sigaw",
        "siglo",
        "sigurado",
        "sikat",
        "sila",
        "silangan",
        "silya",
        "simbolo",
        "simula",
        "singil",
        "singsing",
        "sining",
        "sira",
        "sistema",
        "siya",
        "siyam",
        "siyempre",
        "solusyon",
        "subok",
        "sukat",
        "sulat",
        "sulok",
        "sulong",
        "sumbrero",
        "sundin",
        "sundo",
        "sunod",
        "sunog",
        "suot",
        "suporta",
        "suri",
        "taas",
        "taba",
        "tagal",
        "tagumpay",
        "tahanan",
        "tahimik",
        "tainga",
        "takbo",
        "takot",
        "tala",
        "talakay",
        "talim",
        "talo",
        "talon",
        "tama",
        "tandaan",
        "tanggap",
        "tanghali",
        "tangi",
        "tangkad",
        "tanong",
        "tao",
        "taon",
        "tapang",
        "tapat",
        "tapon",
        "tapos",
        "tatlon",
        "tatsulok",
        "tawag",
        "tawid",
        "tayo",
        "temperatura",
        "timbang",
        "timog",
        "tinapay",
        "tinda",
        "tindahan",
        "tingin",
        "tipon",
        "tiyak",
        "tono",
        "totoo",
        "trabaho",
        "trak",
        "tren",
        "tubig",
        "tugon",
        "tukoy",
        "tuktok",
        "tula",
        "tulad",
        "tulog",
        "tulong",
        "tuloy",
        "tumba",
        "tunay",
        "tungkol",
        "tungo",
        "tunog",
        "turo",
        "tuwa",
        "tuwid",
        "ugat",
        "ulan",
        "ulo",
        "una",
        "upo",
        "upuan",
        "uri",
        "wala",
        "walo",
        "wika",
        "yaman",
        "yelo",
    )

    parts_of_speech: Dict[str, tuple] = {}


from __future__ import print_function

from fife import fife
from fife.extensions.pychan.pychanbasicapplication import PychanApplicationBase
from fife.extensions.cegui.ceguibasicapplication import CEGUIApplicationBase, CEGUIEventListener
#import pickle
#from traceback import print_exc
#import cProfile
#from multiprocessing import Process, Pipe
#from random import randrange

from input import MouseListener, KeyListener
from view import View
from timeline import RealTimeline, Timer
from character import Character
from world import World
from worldvisual import WorldVisual
#from obstacle import Obstacle
from gui import GUI
from combat import Combat
import serializer
import memtest
from exploration import Exploration
from campaign.campaign import Campaign
from config import importobjects
from config import music
from dialogue import DialogueState, loadDialogue

class Listener(CEGUIEventListener):
	def __init__(self, application):
		super(Listener, self).__init__(application)

	def keyPressed(self, evt):
		pass

class Application(CEGUIApplicationBase, PychanApplicationBase):
	def __init__(self, settings):
		#self.ar = []
		#for i in xrange(512):
		#	self.ar.append(' ' * memtest.MEGA)
		#self.a = ' ' * memtest.MEGA * 1024
		#memtest.alloc_max_str()
		#memtest.alloc_max_array()

		print("* Initializing application...")
		super(Application, self).__init__(settings)
		self.settings = settings
		self.model = self.engine.getModel()
		self.mapLoader = fife.MapLoader(self.model,
									self.engine.getVFS(),
									self.engine.getImageManager(),
									self.engine.getRenderBackend())
		self.objectLoader = fife.ObjectLoader(self.model,
									self.engine.getVFS(),
									self.engine.getImageManager(),
									self.engine.getAnimationManager())
#		self.atlasLoader = fife.AtlasLoader(self.model,
#									self.engine.getVFS(),
#									self.engine.getImageManager())

		self.map = None
		self.world = None
		self.view = None
		self.change_res = False

		self.eventmanager = self.engine.getEventManager()
		self.mouselistener = MouseListener(self)
		self.keylistener = KeyListener(self)
		self.eventmanager.addMouseListenerFront(self.mouselistener)
		self.eventmanager.addKeyListenerFront(self.keylistener)
		self.soundmanager = self.engine.getSoundManager()
		self.soundmanager.init()
		self.imagemanager = self.engine.getImageManager()
		print("* Application initialized!")

		self.gui = GUI(self)
		self.real_timeline = RealTimeline()
		self.engine.getTimeManager().registerEvent(self.real_timeline)
		self.game_speed = 1

		#print self.engine.getRenderBackend().isDepthBufferEnabled()

#		self.loadAtlas("objects/nature.xml")
		print("* Loading objects...")
		for import_object in importobjects.import_list:
			self.loadObject(import_object)
		if self.settings.get("gameplay", "PreloadSprites", True):
			self.imagemanager.reloadAll()
		print("* Objects loaded!")

		self.sounds = {}
		self.music = None
		self.music_name = ""
		#self.music = self.soundmanager.createSoundEmitter("music/SFT-Two Mapple Inn.ogg")
#		self.sound_attack = self.soundmanager.createSoundEmitter("sfx/attack-1.ogg")
		#self.music.looping = True
		if not self.settings.get("FIFE", "PlaySounds"):
			self.soundmanager.setVolume(0.0)
		#self.music.play()

		self.cursor = self.imagemanager.load("gui/cursors/Mousecursor01.png")
		self.cursor.setXShift(-4)
		#self.imagemanager.free("gui/cursors/Mousecursor01.png")
		#self.imagemanager.reload("gui/cursors/Mousecursor01.png")
		self.map_cursor = self.imagemanager.load("gui/cursors/Mousecursor02.png")
		self.map_cursor.setXShift(-29)
		self.map_cursor.setYShift(-29)
		#self.null_image = self.imagemanager.loadBlank(1, 1)
		#self.engine.getCursor().set(self.null_image)
		#self.engine.getCursor().setDrag(self.cursor, -4, 0)
		self.engine.getCursor().set(self.cursor)

		self.unloadMap()

		self.lastmem = 0

	def createListener(self):
		self._listener = Listener(self)
		return self._listener

	def playSound(self, sound):
		if sound not in self.sounds:
			self.sounds[sound] = self.soundmanager.createEmitter(
					"sfx/" + sound + ".ogg")
		self.sounds[sound].play()

	def loadObject(self, filename, pingpong = False, object_name = ""):
		if self.objectLoader.isLoadable(filename):
			self.objectLoader.load(filename)
		else:
			print("WARNING: Can't load", filename)

	def loadAtlas(self, filename):
		if self.atlasLoader.isLoadable(filename):
			self.atlasLoader.load(filename)
		else:
			print("WARNING: Can't load", filename)

	def loadMap(self, map_name):
		print("* Loading objects for map", map_name)
		for import_object in importobjects.import_by_map.get(map_name, ()):
			self.loadObject(import_object)
		if self.settings.get("gameplay", "PreloadSprites", True):
			self.imagemanager.reloadAll()
		print("* Objects loaded!")
		filename = str("maps/" + map_name + ".xml")
		if self.mapLoader.isLoadable(filename):
			print("* Loading map", map_name)
			self.map = self.mapLoader.load(filename)
			self.camera = self.map.getCamera("main_camera")
			self.maplayer = self.map.getLayer("buildings_layer")
			#print "imagemanager.reloadAll()"
			#self.imagemanager.reloadAll()
			print("* Map loaded!")
		else:
			print("WARNING: Can't load map")
		if music.music_by_map.get(map_name, self.music_name) != self.music_name:
			self.music_name = music.music_by_map[map_name]
			if self.music:
				self.music.stop()
			self.music = self.soundmanager.createEmitter(
					"music/" + self.music_name + ".ogg")
			self.music.setLooping(True)
			self.music.play()

	def unloadMap(self):
		self.real_timeline.clear()
		if self.world:
			self.world.visual.cleanUp()
		if self.map:
			self.model.deleteMap(self.map)
		if self.imagemanager.getMemoryUsed() > 700000000:
			self.imagemanager.freeUnreferenced()
		print("Memory used by the image manager:", "{:,}".format(self.imagemanager.getMemoryUsed()))
		self.map = None
		self.world = None
		self.view = None
		self.change_map_name = None
		self.combat = None
		self.cutscene = None
		self.exploration = None

	def gameOver(self):
		self.unloadMap()
		self.gui.showMainMenu()

	def newGame(self):
		self.loadMap(self.world.current_map_name)
		self.world.visual = WorldVisual(self, self.maplayer, self.world)
		self.view = View(self)
		camera_loc = self.view.camera.getLocation()
		camera_loc.setLayerCoordinates(self.world.camera_coords)
		self.view.camera.setLocation(camera_loc)
		self.gui.showHUD()
		self.unpause(True)
		self.change_map_name = None
		self.exploration = Exploration(self)
		print("* Game started!")

	def loadMapTest(self, map_name, pc_coords, pc_sprite):
		print("* Loading map test...")
		self.unloadMap()
		self.world = World(self)
		#self.world = World(self, "Ashgrove")
		#campaign.init(self.world)
		self.world.current_map_name = map_name
		if not pc_sprite.endswith(".xml"):
			print("Incorrect sprite file name", pc_sprite)
			return
		pc_sprite_name = pc_sprite.split("\\")[-1][:-4]
		print(pc_sprite, pc_sprite_name)
		pc = self.world.addCharacterAt(pc_coords,
								map_name, "test_character", "test character", str(pc_sprite_name))
		self.world.enablePlayerCharacter(pc)
		self.loadObject("objects\\Sprites - Characters\\" + str(pc_sprite))
		self.loadMap(self.world.current_map_name)
		self.world.visual = WorldVisual(self, self.maplayer, self.world)
		self.view = View(self)
		#self.view.camera.getLocationRef().setLayerCoordinates(
		#			fife.ModelCoordinate(40, 0, 0))
		self.gui.showHUD()
		self.unpause(True)
		self.change_map_name = None
		self.exploration = Exploration(self)
		print("* Map loaded!")

	def saveGame(self, save_name):
		self.world.refresh()
		serializer.save(self.world, "saves/" + save_name + ".sav")
		print("* Game saved!")

	def loadGame(self, save_name):
		self.loadMap(self.world.current_map_name)
		self.world.application = self
		self.world.visual = WorldVisual(self, self.maplayer, self.world)
		self.view = View(self)
		self.gui.showHUD()
		self.unpause(True)
		self.change_map_name = None
		self.exploration = Exploration(self)
		print("* Game loaded!")

	def changeMap(self, map_name):
		self.real_timeline.clear()
		self.world.visual.cleanUp()
		self.world.visual = None
		self.world.current_map_name = map_name
		if self.map:
			self.model.deleteMap(self.map)
		if self.imagemanager.getMemoryUsed() > 700000000:
			self.imagemanager.freeUnreferenced()
		print("Memory used by the image manager:", "{:,}".format(self.imagemanager.getMemoryUsed()))
		self.loadMap(self.world.current_map_name)
		self.world.visual = WorldVisual(self, self.maplayer, self.world)
		self.view = View(self)
		self.gui.showHUD()
		self.unpause(True)
		self.exploration = Exploration(self)

	def prepareChangeMap(self, map_name):
		if map_name == self.world.current_map_name:
			return
		print("* Changing map...")
		self.pause(True)
		self.gui.loading.showFade(lambda: self.prepareChangeMap2(map_name), map=map_name)

	def prepareChangeMap2(self, map_name):
		self.change_map_name = map_name

	def prepareNewGame(self):
		print("* Starting new game...")
		self.unloadMap()
		self.world = World(self)
		#self.world = World(self, "Ashgrove")
		Campaign.init(self.world)
		#self.real_timeline.addTimer(Timer("new game", 50, 1, self.newGame))
		self.gui.loading.showFade(self.newGame, map=self.world.current_map_name)

	def prepareLoadGame(self, save_name):
		self.unloadMap()
		self.world = serializer.load("saves/" + save_name + ".sav")
		#self.real_timeline.addTimer(Timer("load game", 50, 1, self.loadGame, args=save_name))
		self.gui.loading.showFade(lambda: self.loadGame(save_name),
									map=self.world.current_map_name)

	def prepareLoadMapTest(self, map_name, pc_coords, pc_sprite):
		self.gui.loading.showFade(lambda: self.loadMapTest(map_name, pc_coords, pc_sprite),
									map=map_name)

	def setTimeMultiplier(self, multiplier):
		self.real_timeline.multiplier = multiplier
		self.model.setTimeMultiplier(multiplier)

	def unpause(self, init=False):
		if init:
			self._paused = False
			self.force_paused = False
		self.world.visual.game_timeline.paused = False
		self.setTimeMultiplier(self.game_speed)

	def pause(self, override=False):
		if override:
			self._paused = True
		self.world.visual.game_timeline.paused = True
		self.setTimeMultiplier(0)

	def togglePause(self):
		if self.force_paused:
			return
		if self._paused:
			self._paused = False
			self.unpause()
		else:
			self._paused = True
			self.pause()

	@property
	def paused(self):
		return self._paused or self.force_paused

	def forcePause(self):
		gui_pause = (self.gui.dialogue.window.isVisible() or self.gui.game_menu.window.isVisible()
				or self.gui.preferences.window.isVisible() or self.gui.help.window.isVisible()
				or self.gui.save_load.window.isVisible() or self.gui.book.window.isVisible()
				or self.gui.journal.window.isVisible()
				or self.gui.character_sheet.window.isVisible()
				or self.gui.inventory.window.isVisible() or self.gui.looting.window.isVisible()
				or self.gui.weapon_info.window.isVisible() or self.gui.loading.window.isVisible())
		#if gui_pause and not self.force_paused:
		if gui_pause or self._paused:
			self.pause()
		#if not gui_pause and self.force_paused and not self._paused:
		else:
			self.unpause()
		self.force_paused = gui_pause	# obsolete?

	@property
	def current_character(self):
		return self.world.player_character

	def startCombat(self, combatants, surprised=[]):
		for character in self.world.characters:
			if character.visual:
				character.visual.idle()
		self.combat = Combat(self, combatants, surprised=surprised)
		self.combat.beginTurn()

	def startCutscene(self, Cutscene):
		self.cutscene = Cutscene(self)
		self.gui.hideAll()

	def startDialogue(self, dialogue, npc=None, pc=None):
		if isinstance(dialogue, str):
			dialogue = loadDialogue(dialogue)
		self.gui.dialogue.start(DialogueState(dialogue, self.world, npc=npc, pc=pc))

	def changeRes(self):
		self.change_res = True
		self.engine.getCursor().setNativeImageCursorEnabled(
			self.settings.get("FIFE", "NativeImageCursor", False))

	def changeRes2(self):
		#PyCEGUIOpenGLRenderer.OpenGLRenderer.grabTextures(
		#	PyCEGUI.System.getSingleton().getRenderer())
		self.change_res = False
		old_mode = self.engine.getRenderBackend().getCurrentScreenMode()
		new_mode = self.engine.getDeviceCaps().getNearestScreenMode(
				int(self.settings.get("FIFE", "ScreenResolution", "1024x768").split("x")[0]),
				int(self.settings.get("FIFE", "ScreenResolution", "1024x768").split("x")[1]),
				self.settings.get("FIFE", "BitsPerPixel", "0"),
				self.settings.get("FIFE", "RenderBackend", "OpenGL"),
				self.settings.get("FIFE", "FullScreen", False))
		if (old_mode.getWidth() == new_mode.getWidth()
				and old_mode.getHeight() == new_mode.getHeight()
				and old_mode.isFullScreen() == new_mode.isFullScreen()
				and self.engine.getRenderBackend().isVSyncEnabled()
					== self.settings.get("FIFE", "VSync", True)):
			return
		self.engine.getRenderBackend().setVSyncEnabled(
			self.settings.get("FIFE", "VSync", True))
		self.engine.changeScreenMode(new_mode)
		if not self.view:
			return
		self.camera.setViewPort(fife.Rect(0, 0,
			self.engine.getRenderBackend().getScreenWidth(),
			self.engine.getRenderBackend().getScreenHeight()))
		self.camera.refresh()
		#PyCEGUIOpenGLRenderer.OpenGLRenderer.restoreTextures(
		#	PyCEGUI.System.getSingleton().getRenderer())
		#PyCEGUI.System.getSingleton().notifyDisplaySizeChanged(PyCEGUI.Sizef(
		#	int(self.settings.get("FIFE", "ScreenResolution", "1024x768").split("x")[0]),
		#	int(self.settings.get("FIFE", "ScreenResolution", "1024x768").split("x")[1])))

	def _pump(self):
		if self.change_res:
			self.changeRes2()
			return
		if self.imagemanager.getMemoryUsed() != self.lastmem:
			print("Memory used by the image manager:", "{:,}".format(
															self.imagemanager.getMemoryUsed()))
			#memtest.alloc_max_str()
			#memtest.alloc_max_array()
			self.lastmem = self.imagemanager.getMemoryUsed()
		#if self.imagemanager.getMemoryUsed() > 800000000:
		#	self.imagemanager.freeUnreferenced()
		self.gui.pump()
		#if self.world:
		if self.view:
			self.forcePause()
			if self.change_map_name and (self.world.current_map_name != self.change_map_name):
				self.changeMap(self.change_map_name)
				#memtest.alloc_max_str()
				#memtest.alloc_max_array()
			elif self.cutscene:
				if not self.cutscene.pump():
					self.cutscene = None
					self.gui.hud.show()
				#try:
				#	self.cutscene.pump()
				#except StopIteration:
				#	self.cutscene = None
				#	self.gui.hud.show()
			elif self.combat:
				self.combat.pump()
			elif self.exploration and not self.paused:
				self.exploration.pump(self.real_timeline.last_frame_time)
		#if self.world:
		#	if self.world.visual:
		if self.view:
			self.view.pump()
		self.gui.pump2()
		if self._listener.quitrequested:
			self.quit()


from pathlib import Path

import librosa
import numpy as np
import soundfile
from audio_utils import AudioUtils
from scipy import signal

def scale_to_ref(tar_data, ref_data, eps=1e-7):
    ref_rms = np.sqrt(np.mean(ref_data**2))
    cur_rms = np.sqrt(np.mean(tar_data**2)) + eps
    return tar_data / cur_rms * ref_rms

def get_truncated_rir(rir, fs, *, direct_range=(-0.006, 0.08)):
    rir /= np.sum(rir)
    rir_early = np.zeros_like(rir)

    peak_idx = np.argmax(np.abs(rir))
    start_idx = max(0, peak_idx + int(fs * direct_range[0]))
    end_idx = peak_idx + int(fs * direct_range[1])

    rir[:start_idx] = 0

    rir_early[start_idx:end_idx] = rir[start_idx:end_idx]

    # scale = 0.9 / np.max(np.abs([rir, rir_early]))
    # rir *= scale
    # rir_early *= scale
    return rir, rir_early

def get_rts_rir(
    rir,
    original_T60: float,
    direct_range=(-0.002, 0.08),
    target_T60=0.05,
    sr: int = 32000,
):
    assert rir.ndim == 1, "rir must be a 1D array."

    q = 3 / (target_T60 * sr) - 3 / (original_T60 * sr)

    peak_idx = np.argmax(np.abs(rir))
    start_idx = max(0, peak_idx + int(sr * direct_range[0]))
    end_idx = peak_idx + int(sr * direct_range[1])

    rir[:start_idx] = 0

    win = np.zeros_like(rir)
    win[start_idx:end_idx] = 1
    win[end_idx:] = 10 ** (-q * np.arange(rir.shape[0] - end_idx))
    rts_rir = rir * win

    # scale = 0.9 / np.max(np.abs([rir, rts_rir]))
    # rir *= scale
    # rts_rir *= scale
    rts_rir = scale_to_ref(rts_rir, rir)
    return rir, rts_rir

out_dir = Path(r"D:\Temp\out1")
# in_clean_path = r"F:\Test\1.audio_test\1.in_data\anechoic_room_speech.wav"
in_clean_path = r"F:\BaiduNetdiskDownload\BZNSYP\Wave\007537.wav"
# in_rir_path = r"F:\Test\3.dataset\3.rir\wedo_rk_out_speedup_rir\large_meeting_room_rk_out_3_speed_1.0.wav"
in_rir_path = r"D:\Temp\gpu_rir\gpu_rir_10244_rt60_1.10s.wav"

sr = 32000

clean_data, _ = librosa.load(
    in_clean_path,
    sr=sr,
)

rir_data, _ = librosa.load(
    in_rir_path,
    sr=sr,
)

if bool(1):
    tam, tar_rt60, ori_rt60 = 0.07, 0.05, 1.0
    prefix = f"{Path(in_clean_path).stem};{Path(in_rir_path).stem};tam={tam};tar_rt60={tar_rt60};ori_rt60={ori_rt60};"
    rir, rts_rir = get_rts_rir(
        rir_data,
        ori_rt60,
        direct_range=(-0.002, tam),
        target_T60=tar_rt60,
    )
else:
    direct_range = (-0.001, 0.001)
    prefix = (
        f"{Path(in_clean_path).stem};{Path(in_rir_path).stem};early={direct_range};"
    )
    rir, rts_rir = get_truncated_rir(rir_data, sr, direct_range=direct_range)

reverb_data = signal.convolve(clean_data, rir)
label_data = signal.convolve(clean_data, rts_rir)
# label_data = scale_to_ref(label_data, reverb_data) * 0.944

scale = 0.95 / np.max(np.abs([reverb_data, label_data]))
reverb_data *= scale
label_data *= scale

out_dir.mkdir(exist_ok=True)

soundfile.write(
    out_dir / f"{prefix}[speech]reverb_label.wav",
    AudioUtils.merge_channels(reverb_data, label_data),
    sr,
)
soundfile.write(
    out_dir / f"{prefix}[speech]reverb.wav",
    reverb_data,
    sr,
)
soundfile.write(
    out_dir / f"{prefix}[speech]label.wav",
    label_data,
    sr,
)
soundfile.write(
    out_dir / f"{prefix}[rir]original_target.wav",
    AudioUtils.merge_channels(rir, rts_rir),
    sr,
)
...


from django.contrib.auth import views
from django.conf.urls import url
from django.urls import path
from .views import (
    ArticleList,
    ArticleCreate,
    ArticleUpdate,
    ArticleDelete,
    ProfileView,
    UserList
)

app_name = 'account'
urlpatterns = [
    path('', ArticleList.as_view(), name='home'),
    path('article/create', ArticleCreate.as_view(), name='article_create'),
    path('article/update/<int:pk>', ArticleUpdate.as_view(), name='article_update'),
    path('article/delete/<int:pk>', ArticleDelete.as_view(), name='article_delete'),
    path('profile', ProfileView.as_view(), name='profile'),
    path('users', UserList.as_view(), name='user_list')
]


#!/usr/local/bin/python3
"""
------------------------------------------------------------------------
_CSV APPENDER.PY

AUTHOR(S):     Peter Walker    pwalker@csumb.edu

PURPOSE-  This script will either ask the user for a directory containing
            network test output files (Field Test or Crowd Source), or will
            use the directory provided in the sys.argv array. It will also use
            a CSV file, specified by the user or in sys.argv. It will parse all
            of the files, then add the requested information to the given CSV.

FUNCTIONS:
    appendToCSV
    __main__
------------------------------------------------------------------------
"""

from _csvCommonFuncs_ import parseAllTests

def appendToCSV(folderPath, csvPath, outputFilename="./_result.csv", options="", *args, **kwargs):
    """
    Given the folder that contains the raw data, the CSV to be
    appending to, and a few other options, this function will pass
    every file to the FieldTest_File constructor, store the object,
    and then iterate through every File object, creating a line in
    the CSV from it's values. The user can chose which values should
    be calculated from each File object
    ARGS:
        folderPath      String, the absolute path the folder containing the raw data
        csvPath         String, the absolute path to the original CSV file
        outputFilename  String, the path where the resulting CSV will be saved.
                        Default: ./_result.csv, a CSV in the current directory
        options         String, the option numbers that correspond to which values each
                        line in the CSV should contain.
        NewHeaders      KWARG. Anything. If this is set, then the new CSV headers will be
                        used when finding header/attribute pairs that match
    RETURNS:
        Creates a CSV file at the location in outputFilename
    RAISES:
        ValueError - if folderPath is not a directory, if csvPath is not a CSV file,
                     if PyObject could not be imported
    """
    import os
    import datetime
    import traceback
    #Doing some error checking of the values passed
    #Checking that the folderPath arg contains a value
    if not folderPath or not csvPath:
        raise ValueError("You need to pass in a legitimate folder path through the argument"+
                         "\"folderPath\" or \"csvPath\"")
    #Checking that folderPath is a legitimate directory
    from os.path import (abspath, isdir, isfile)
    folderPath = abspath(folderPath)
    if not isdir(folderPath):
        raise RuntimeError("The argument \"folderPath\" must contain a legitimate directory")
    csvPath = abspath(csvPath)
    if not isfile(csvPath) and (csvPath[-4:].lower() != ".csv"):
        raise RuntimeError("The argument \"csvPath\" must contain a legitimate CSV file")
    #If the file given in outputFilename already exits, warning the user that it will be overwritten.
    # But before that, we need to make sure that the path is the absolute path
    outputFilename = abspath(outputFilename)
    if isfile(outputFilename):
        print("This script will overwrite the contents in \""+
              os.path.basename(outputFilename)+"\".\n"+
              "Do you wish to continue? (y/n)")
        ans = str(input(">>> ")).lower()
        if ans != "y":
            print("Now exiting...")
            raise SystemExit
    #Checking that the arg options is a string
    if not isinstance(options, str):
        raise ValueError("The argument \"options\" must be a string.")
    #Trying to import the fileType object. If unsuccessful, then we exit
    try:
        from FileParser.FieldTest_File import FieldTest_File as outputFile
    except:
        raise RuntimeError("Was unable to import the necessary files for parsing")
    #END TRY/EXCEPT

    #Importing a function from Parser.utils that will let us export the 2 dimensional array
    # that will be created as a CSV file. Also, importing some other statistical functions
    from Parser.utils.basic_utils import csvImport, csvExport
    #Importing our headers based on the type of raw files being used
    from _csvHeaders_ import FieldTestHeaders as headers
    from _csvHeaders_ import FTcsvHeadersOrder as headersOrder

    #Asking the user which kind of values they want in their csv if the script is being
    # run as main, and only the default options are currently chosen.
    if (options == ""):
        print("Please input on one line which values you would like included in the CSV:\n" +
              " example: >>> 13\n\n" +
              " a - All Headers, specified below\n")

        for hdr in headersOrder[5:]:
            print(" "+str(headersOrder.index(hdr)-4)+" - "+hdr[4:])
            if len(headers[hdr])>10:
                half = int(len(headers[hdr])/2)
                print("       "+" ".join(headers[hdr][:half])+"\n"+
                      "       "+" ".join(headers[hdr][half:]))
            else:
                print("       "+" ".join(headers[hdr]))
            #END FOR
        #END FOR
        #Asking for options
        options = str(input(">>> "))
        print()
    #END IF

    #Creating the array that will hold all of the column headers for this CSV
    csvHeaders = []
    #If the user chose all options, then we redeclare options to include all of the option numbers
    if "a" in options:
        options = "".join([str((headersOrder.index(elem)-4)) for elem in headersOrder[5:]])
    #Depending on what numbers the user inputed at the terminal, we will append
    # the headers values to our csvHeader array
    possibleOpts = [(headersOrder.index(elem)-4) for elem in headersOrder[5:]]
    for ind in possibleOpts:
        if str(ind) in options:
            csvHeaders.extend(headers[headersOrder[ind+4]])

    #Now we will parse all of the files in the folder specified in folderPath, and then
    # create the CSV at the location specified in outputFilename
    startTime = datetime.datetime.now()
    parsedFiles = parseAllTests('fieldtest', folderPath, outputFilename, startTime)

    #Importing our csv as an array, which we will be searching through to find
    # the correct row to append values to
    print("Importing CSV from "+csvPath)
    csvAsArray = csvImport(csvPath)
    oldRowLength = len(csvAsArray[0])

    #Now that we've found a path that has not been used, we can print out all of the test
    # into it for error checking
    print("CSV File being created...")
    for file in parsedFiles:
        fileAsArray = []
        #We first split the options chosen into individual elements
        for option in list(options):
            #If the option is a number and is less than 4, then we can use it
            if option.isnumeric() and int(option)<(len(headersOrder)-4):
                #We first get the header of the option chosen
                # eg. 1 => 1+4 => headersOrder[5] => "csv Stat Headers"
                # We then grab just the middle word from the string for use
                hdr = headersOrder[int(option)+4]
                hdrType = hdr.split(" ")[1]

                ## !!!! HACK for old Column Order
                #We are going to get the function that need to be called, call the
                # function, and then re-order the array as necessary
                array = getattr(file, "get_csv"+hdrType+"Values")()
                if hdrType == "Stat" or hdrType == "Qual":
                    array = array[:4] + array[8:12] + array[4:8] + array[12:]
                elif hdrType == "RvMos":
                    array = array[2:] + array[:2]
                #END IF/ELIFs
                fileAsArray.extend(array)
                ## !!!! END HACK

                #getValues = getattr(file, "get_csv"+hdrType+"Values")
                #fileAsArray.extend(getValues())
            #END IF
        #END FOR

        #The CSV headers have recently changed, but if the CSV is using
        # the new headers, set 'NewHeaders' to anything
        try:
            if kwargs["NewHeaders"] is not None:
                pairs=[("Date","Date"), ("Time","Time"),
                       ("LocationID", "LocationID"),
                       ("DeviceID", "DeviceID")]
            else:
                pairs=[("Date","Date"), ("Time","Time"),
                       ("Location_ID", "LocationID"),
                       ("Device ID", "DeviceID")]
            #END IF/ELSE
        except:
            pairs=[("Date","Date"), ("Time","Time"),
                   ("Location_ID", "LocationID"),
                   ("Device ID", "DeviceID")]
        #END TRY/EXCEPT
        #Now we will want to search for the array that matches our file. What we
        # do is get all of the rows that have the right Date and Time. From those,
        # we search for the one with the correct Location ID. If there are still
        # multiple, then we search for the right Device ID.
        matchingRows = findCSVRows(csvAsArray, file, headerAttrbPairs=pairs[:2])
        added = False
        if matchingRows:
            numFields = 3
            while True:
                toSearch = [csvAsArray[0][:]]
                toSearch.extend(matchingRows)
                if len(toSearch)<2 or numFields>len(pairs):
                    break
                elif len(toSearch) == 2:
                    added = True
                    toSearch[1].extend(fileAsArray)
                    break
                else:
                    matchingRows = findCSVRows(csvAsArray, file,
                                               headerAttrbPairs=pairs[:numFields])
                    numFields += 1
                #END IF/ELIF/ELSE
        #If the file was not added, then create a file containing all of the
        # file names that were not added.
        if not added:
            with open(os.path.join(os.path.expanduser("~"), "Desktop", "missingFiles.txt"), "a") as fs:
                fs.write(folderPath.split("/")[-1]+"   "+file.Filename+"\n")
        #END IF

        #Printing out how long the script has been running
        timeDiff = datetime.datetime.now() - startTime
        timeDiff_str = str(timeDiff).split(".")[0]
        print("  Current Run Time: "+timeDiff_str, end='\r')
    #END FOR

    #Now we need to put in placeholders for the rows that did not have a file
    filler = ["File Missing"]*len(csvHeaders)
    for row in csvAsArray[1:]:
        if len(row) == oldRowLength:
            row.extend(filler)
    #END FOR
    #Just before we create our CSV from our massive array, we need to append the new
    # headers (in csvHeaders) to the first element
    csvAsArray[0].extend(csvHeaders)
    #Creating the csv with the csvExport function from Parser.utils.basic_utils
    csvExport(csvAsArray, outputFilename)
    #Printing an empty line after the CSV has been created,
    # so to clear the "Current Run Time:" text
    print(" "*50, end='\r')
    print("CSV File has been created.")
#END DEF

def findCSVRows(csvAsArray, parsedFile, headerAttrbPairs=[], *args, **kwargs):
    """
    This function will take a given CSV, and find the row that
    corresponds to the given parsed file object. The function takes pairs
    of CSV headers and file attributes, and will find all of the rows where
    the CSV columns match all of the file's attributes.
    ARGS:
        csvAsArray      A 2-dimensional array, representing the CSV
        parsedFile      _File object, representing the file whose line we are
                        looking for in the CSV
        headerAttrbPairs
                        KWARGS. Each key represents the column that we will be
                        looking in, while the value associated with that key is
                        the value we are looking for in the column. The row
                        must contain all header/value pairs in order to be
                        returned
    RETURNS:
        List of Arrays, where each array is a row in the CSV where the information
        matched what was given
    """
    if not isinstance(csvAsArray, list) or not isinstance(headerAttrbPairs, list):
        raise ValueError("You need to pass in a list through the arguments"+
                         "\"csvAsArray\" and \"headerAttrbPairs\"")
    #This will loop through all of the pairs in headerAttrbPairs, checking that
    # all of the headers and attributes exist in the CSV and parsed file object
    for header, attr in headerAttrbPairs:
        #This is raising an error if 'header' is not only of the column
        # headers in the CSV
        if header not in csvAsArray[0]:
            raise ValueError(header+" is not a header in the CSV file")
        #This will raise an AttributeError if 'attr' is not an attribute of parsedFile
        __ = getattr(parsedFile, attr)
    #END FOR
    #Making a reference to the CSV headers, and then creating an empty arry (for where
    # the matching rows will go). I am renaming tempHeaders to csvHeaders because I want to
    csvHeaders = csvAsArray[0]
    matchingRows = []
    for row in csvAsArray[1:]:
        matching = True
        #For each row, we want to make sure that all of the headers/attribute pairs
        # match the. Then we will add that row to the array 'matchingRows'
        for header, attr in headerAttrbPairs:
            #We need to use 'in' because, sometimes, there is whitespace in the CSV, and this will
            # get us around that, while still finding the row where the information matches
            if ( str(getattr(parsedFile, attr)) not in str(row[csvHeaders.index(header)])
                 and str(getattr(parsedFile, attr)) != str(row[csvHeaders.index(header)]) ):
                matching = False
        #END FOR
        if matching:
            matchingRows.append(row)
    #END FOR
    return matchingRows
#END DEF

## -----------------------------------------------------------------------------

#MAIN
if __name__ == "__main__":
    """
    This script can be run as __main__ by a user. If they do not give the necessary
    inputs from the comamnd line, then tkinter will ask for the locations of
    files and folder.
    __main__ then calls appendToCSV() with the necessary arguments
    """
    #IMPORTS
    import sys
    import os
    import datetime
    from tkinter.filedialog import (askdirectory, askopenfilename)
    #END IMPORTS
    #Timestamp of the current time
    startingTheScript = datetime.datetime.now()
    #This takes care of the problem of having to run the script from within the
    # folder the contains it. This will dynamically add the project path to Python's
    # sys.path array.
    #We combine the current directory with the path in __file__, get the absolute path
    # of that join, and then remove the script name from the end. That end string is
    # then appended to sys.path
    sys.path.append( os.path.abspath(os.path.join(os.getcwd(), __file__)).rsplit("/",1)[0] )
    #If the number of arguments was less than 2, then we will ask the user where the
    # raw data is, and where they want the file saved.
    if ("-h" in sys.argv) or ("--help" in sys.argv):
        print("This script requires at least one flag, and has a few optional inputs:\n"+
              "  -h/--help    Help menu\n"+
              "  -i [path]    The path to the raw data that will be parsed\n"+
              "  -v [path]    The path to the original CSV file we are appending to\n"+
              "  -o [path]    The path where the file will be saved\n"+
              "  --all        Create the csv with all possible columns\n"+
              "Here some possible ways to run this script:\n" +
              "$ py "+(__file__.split("/")[-1])+"\n" +
              "$ py "+(__file__.split("/")[-1])+" -i /path/to/raw_date -v /path/to/csv\n" +
              "$ py "+(__file__.split("/")[-1])+" -i /path/to/raw_data -o /path/to/result.csv\n")
        raise SystemExit
    #END IF

    #These is where we will determine what information has been provided by the user, and
    # what is missing
    RawDataPath = ""
    OriginalCSVPath = ""
    ResultDataPath = ""
    #If the input path was not specified, then we need to ask the user for it's location
    if "-i" not in sys.argv:
        print("Please select the folder containing the raw data you wish to convert into a CSV...")
        RawDataPath = askdirectory( initialdir=os.path.expanduser("~"),
                                    title="Select the FOLDER containing the raw data",
                                    mustexist=True)
    else:
        path = sys.argv[sys.argv.index("-i")+1]
        RawDataPath = os.path.abspath(path)
    #END IF/ELSE
    #If the CSV path was not specified, then we need to ask the user for it's location
    if "-v" not in sys.argv:
        print("Please select the CSV file that will be appended to...")
        OriginalCSVPath = askopenfilename( initialdir=os.path.expanduser("~"),
                                           title="Select the base CSV to append to",
                                           filetypes=[("CSV files", "*.csv")],
                                           multiple=False)
    else:
        path = sys.argv[sys.argv.index("-v")+1]
        OriginalCSVPath = os.path.abspath(path)
    #END IF/ELSE

    #If the user did not specify where to save the output file, then we will
    # ask them which folder they would like the file saved in.
    if "-o" not in sys.argv:
        print("Please select where you would like to save the output...")
        ResultDir = askdirectory( initialdir=os.path.expanduser("~"),
                                  title="Select the FOLDER to hold the new CSV",
                                  mustexist=True)
        ResultDataPath = ResultDir+"/" + RawDataPath.split("/")[-1]+"_results.csv"
    else:
        path = sys.argv[sys.argv.index("-o")+1]
        if ".csv" not in path[-4:]:
            path += ".csv"
        ResultDataPath = os.path.abspath(path)
    #END IF/ELSE

    #If the user used the "--all" flag, then we will run the CSV creator with the
    # 'a' options, which creates the CSV with all of the possible columns included.
    options = ""
    if "--all" in sys.argv:
        options = "a"

    #Now we actually call the function that creates the CSV
    appendToCSV(folderPath=RawDataPath,
                csvPath=OriginalCSVPath,
                outputFilename=ResultDataPath,
                options=options
                )

    #Doing some calculation of how long the script had to run
    timeToRun = datetime.datetime.now() - startingTheScript
    print("The script has completed with a time of: " + str(timeToRun).split(".")[0])
    print("Now exiting...")
    raise SystemExit
#END IF MAIN


"""Top-level package for LRL Toolbox."""

__author__ = """Luis Rodriguez"""
__email__ = 'luisrodluj@gmail.com'
__version__ = '0.0.1'

import logging
import sys

logger = logging.getLogger("lrl_toolbox")

handler = logging.StreamHandler(sys.stdout)
handler.setLevel(logging.DEBUG)

formatter = logging.Formatter('[%(asctime)s] {%(filename)s:%(lineno)d} %(levelname)s - %(message)s')

handler.setFormatter(formatter)
logger.addHandler(handler)


#!/usr/bin/python3
""" Matrix rotation algorithm """

def rotate_2d_matrix(matrix):
    """This algorithm rotates a 2d matrix in place

    Args:
        matrix (_type_): A list of intergers

    Returns:
        list: a rotated matrix
    """

    if not isinstance(matrix, list):
        return

    len_matr = len(matrix)

    # Rotate the matrix in-place
    for i in range(len_matr // 2):
        for j in range(i, len_matr - i - 1):

            # queue stores the temp variable as we swap
            queue = matrix[i][j]

            # swap element with the one that would occupy after the rotation
            matrix[i][j] = matrix[len_matr - j - 1][i]
            matrix[len_matr - j - 1][i] = matrix[len_matr -
                                                 i - 1][len_matr - j - 1]

            matrix[len_matr - i - 1][len_matr -
                                     j - 1] = matrix[j][len_matr - i - 1]
            matrix[j][len_matr - i - 1] = queue

    for row in matrix:
        return row


# -*- coding:utf-8 -*-
import cv2 as cv

logo_path = r"F:\CSDN\Image\logo.png"
lena_path = r"F:\CSDN\Image\lena.bmp"

logo = cv.imread(logo_path)
lena = cv.imread(lena_path)
# print(lena.shape)
# print(logo.shape)
# I want to put logo on top-left corner,SO I create a ROI
rows,cols,channels = logo.shape
roi = lena[0:rows, 0:cols]

# cv.imshow('roi',roi)
cv.waitKey()
cv.destroyAllWindows()


import hashlib
import secrets
from typing import Optional

from Crypto.Cipher import AES

from ..config import CONFIG
from ..helper.crypto import c3_aid, cuid_galaxy2

class Account(object):
    """
    贴吧的用户信息容器

    Args:
        BDUSS_key (str, optional): 用于快捷调用BDUSS. Defaults to None.
    """

    __slots__ = [
        '_BDUSS_key',
        '_BDUSS',
        '_STOKEN',
        '_tbs',
        '_android_id',
        '_uuid',
        '_client_id',
        '_sample_id',
        '_cuid',
        '_cuid_galaxy2',
        '_c3_aid',
        '_z_id',
        '_aes_ecb_sec_key',
        '_aes_ecb_chiper',
        '_aes_cbc_sec_key',
        '_aes_cbc_chiper',
    ]

    def __init__(
        self,
        BDUSS_key: Optional[str] = None,
    ) -> None:
        self._BDUSS_key = BDUSS_key
        users_cfg = CONFIG.setdefault('User', {})
        user_cfg = users_cfg.get(BDUSS_key, {})
        self.BDUSS = user_cfg.get('BDUSS', '')
        self.STOKEN = user_cfg.get('STOKEN', '')

        self._tbs: str = None
        self._android_id: str = None
        self._uuid: str = None
        self._client_id: str = None
        self._sample_id: str = None
        self._cuid: str = None
        self._cuid_galaxy2: str = None
        self._c3_aid: str = None
        self._z_id: str = None
        self._aes_ecb_sec_key: bytes = None
        self._aes_ecb_chiper = None
        self._aes_cbc_sec_key: bytes = None
        self._aes_cbc_chiper = None

    @property
    def BDUSS_key(self) -> str:
        """
        当前账号的BDUSS_key
        """

        return self._BDUSS_key

    @property
    def BDUSS(self) -> str:
        """
        当前账号的BDUSS
        """

        return self._BDUSS

    @BDUSS.setter
    def BDUSS(self, new_BDUSS: str) -> None:
        if new_BDUSS and len(new_BDUSS) != 192:
            raise ValueError(f"BDUSS的长度应为192个字符 而输入的{new_BDUSS}有{len(new_BDUSS)}个字符")
        self._BDUSS = new_BDUSS

    @property
    def STOKEN(self) -> str:
        """
        当前账号的STOKEN
        """

        return self._STOKEN

    @STOKEN.setter
    def STOKEN(self, new_STOKEN: str) -> None:
        if new_STOKEN and len(new_STOKEN) != 64:
            raise ValueError(f"STOKEN的长度应为64个字符 而输入的{new_STOKEN}有{len(new_STOKEN)}个字符")
        self._STOKEN = new_STOKEN

    @property
    def android_id(self) -> str:
        """
        返回一个随机的android_id

        Returns:
            str: 长度为16的16进制字符串 包含8字节信息 字母为小写

        Examples:
            91be894d01799c49

        Note:
            在初始化后该属性便不会再发生变化
        """

        if self._android_id is None:
            self._android_id = secrets.token_hex(8)
        return self._android_id

    @property
    def uuid(self) -> str:
        """
        使用uuid.uuid4生成并返回一个随机的uuid

        Returns:
            str: 包含16字节信息

        Examples:
            e4200716-58a8-4170-af15-ea7edeb8e513

        Note:
            在初始化后该属性便不会再发生变化
        """

        if self._uuid is None:
            import uuid

            self._uuid = str(uuid.uuid4())

        return self._uuid

    @property
    def tbs(self) -> str:
        """
        返回一个可作为请求参数的反csrf校验码tbs

        Returns:
            str: 长度为26的16进制字符串 字母为小写

        Examples:
            17634e03cbe25e6e1674526199

        Note:
            在初始化后该属性便不会再发生变化
        """

        return self._tbs

    @property
    def client_id(self) -> str:
        """
        返回一个可作为请求参数的client_id

        Returns:
            str

        Examples:
            wappc_1653660000000_123

        Note:
            在初始化后该属性便不会再发生变化
        """

        return self._client_id

    @property
    def sample_id(self) -> str:
        """
        返回一个可作为请求参数的sample_id

        Returns:
            str

        Examples:
            104505_3-105324_2-...-107269_1

        Note:
            在初始化后该属性便不会再发生变化
        """

        return self._sample_id

    @property
    def cuid(self) -> str:
        """
        返回一个可作为请求参数的cuid

        Returns:
            str

        Examples:
            baidutiebaappe4200716-58a8-4170-af15-ea7edeb8e513

        Note:
            在初始化后该属性便不会再发生变化\n
            此实现仅用于9.x等旧版本 11.x后请使用cuid_galaxy2填充对应字段
        """

        if self._cuid is None:
            self._cuid = f"baidutiebaapp{self.uuid}"
        return self._cuid

    @property
    def cuid_galaxy2(self) -> str:
        """
        返回一个可作为请求参数的cuid_galaxy2

        Returns:
            str

        Examples:
            A3ED2D7B9CFC28E8934A3FBD3A9579C7|VZ5FKB5XS

        Note:
            在初始化后该属性便不会再发生变化\n
            此实现与12.x版本及以前的官方实现一致
        """

        if self._cuid_galaxy2 is None:
            self._cuid_galaxy2 = cuid_galaxy2(self.android_id)
        return self._cuid_galaxy2

    @property
    def c3_aid(self) -> str:
        """
        返回一个可作为请求参数的c3_aid

        Returns:
            str

        Examples:
            A00-ZNU3O3EP74D727LMQY745CZSGZQJQZGP-3JXCKC7X

        Note:
            在初始化后该属性便不会再发生变化\n
            此实现与12.x版本及以前的官方实现一致
        """

        if self._c3_aid is None:
            self._c3_aid = c3_aid(self.android_id, self.uuid)
        return self._c3_aid

    @property
    def z_id(self) -> str:
        """
        返回一个可作为请求参数的z_id

        Returns:
            str

        Note:
            在初始化后该属性便不会再发生变化\n
            此实现与12.x版本及以前的官方实现一致
        """

        return self._z_id

    @property
    def aes_ecb_sec_key(self) -> bytes:
        """
        返回一个供贴吧AES-ECB加密使用的随机密码

        Returns:
            bytes: 长度为31字节的随机密码

        Note:
            在初始化后该属性便不会再发生变化
        """

        if self._aes_ecb_sec_key is None:
            self._aes_ecb_sec_key = secrets.token_bytes(31)
        return self._aes_ecb_sec_key

    @property
    def aes_ecb_chiper(self):
        """
        获取供贴吧websocket使用的AES-ECB加密器

        Returns:
            Any: AES chiper
        """

        if self._aes_ecb_chiper is None:
            salt = b'\xa4\x0b\xc8\x34\xd6\x95\xf3\x13'
            ws_secret_key = hashlib.pbkdf2_hmac('sha1', self.aes_ecb_sec_key, salt, 5, 32)
            self._aes_ecb_chiper = AES.new(ws_secret_key, AES.MODE_ECB)

        return self._aes_ecb_chiper

    @property
    def aes_cbc_sec_key(self) -> bytes:
        """
        返回一个供贴吧AES-CBC加密使用的随机密码

        Returns:
            bytes: 长度为16字节的随机密码

        Note:
            在初始化后该属性便不会再发生变化
        """

        if self._aes_cbc_sec_key is None:
            self._aes_cbc_sec_key = secrets.token_bytes(16)
        return self._aes_cbc_sec_key

    @property
    def aes_cbc_chiper(self):
        """
        获取供贴吧客户端使用的AES-CBC加密器

        Returns:
            Any: AES chiper
        """

        if self._aes_cbc_chiper is None:
            self._aes_cbc_chiper = AES.new(self.aes_cbc_sec_key, AES.MODE_CBC, iv=b'\x00' * 16)
        return self._aes_cbc_chiper


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

import socket
import threading
import socketserver
import json

def client(ip, port, message):
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.connect((ip, port))

    try:
        print("Send: {}".format(message))
        sock.sendall(message.encode("utf-8"))

        response = sock.recv(1024)
        jresp = json.loads(response.decode('utf-8'))
        print("Recv: ", jresp)

    finally:
        sock.close()

if __name__ == "__main__":
    # Port 0 means to select an arbitrary unused port
    HOST, PORT = "127.0.0.1", 9000
    msg = [{"request": 1}]
    jmsg = json.dumps(msg)
    client(HOST, PORT, jmsg)


# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
from collections import deque
class Solution:
    def zigzagLevelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:
      if root is None:
        return []
      res = []
      s1 = [root]
      s2 = []
      level = []
      while s1 or s2:
        while s1:
          node = s1.pop()
          level.append(node.val)
          if node.left:
            s2.append(node.left)
          if node.right:
            s2.append(node.right)
        if level:
          res.append(level)
        level = []
        while s2:
          node = s2.pop()
          level.append(node.val)
          if node.right:
            s1.append(node.right)
          if node.left:
            s1.append(node.left)
        if level != []:
          res.append(level)
        level = []
      return res


# Code for ManimGL

from manimlib import *
from intro import Intro
from logo import Logo

class Thumbnail(Scene):
    n: int = 1
    def construct(self):
        title = Text("¿Qué es una función?").scale(2)
        subtitle = Text(f"Parte {self.n}").scale(1.5)
        VGroup(title, subtitle).arrange(DOWN)
        logo = Logo().scale(0.75).to_corner(DR)
        func = Tex("y=f(x)", isolate=["f", "x", "y"]) \
            .set_color_by_tex_to_color_map({"f": GREY, "x": BLUE, "y": YELLOW}) \
            .scale(2) \
            .to_corner(UL)
        self.add(title, subtitle, logo, func)

class IntroVideo(Intro):
    n: int = 1
    def construct(self):
        titulo = Text("Funciones", font_size=72).to_edge(UP)
        self.play(DrawBorderThenFill(titulo))
        subtitulo = Text("¿Qué son y para qué sirven?") \
            .next_to(titulo, DOWN)
        parte = Text(f"Parte {self.n}").to_edge(DOWN)
        self.play(GrowFromEdge(subtitulo, UP))
        self.play(Write(parte))
        super().construct()
        self.play(*[FadeOut(mob) for mob in self.mobjects[1:]])

class BouncingBall(Dot):
    def __init__(self, y0=3.5, vy0 = 0, gry = 0, c=0.9, g=10, **kwargs):
        super().__init__(y0 * UP, **kwargs)
        self.v = vy0 * UP
        self.gry = gry
        self.c = c
        self.g = g

    def start_bouncing(self):
        self.add_updater(self.bounce_updater)
        return self

    def stop_bouncing(self):
        self.remove_updater(self.bounce_updater)
        self.v = 0 * UP
        return self

    def bounce_updater(self, m: Mobject, dt):
        dv = -self.g * dt * UP
        self.v += dv
        m.shift(self.v * dt)
        if self.get_y() <= self.gry + self.radius:
            self.v -= dv # Get back to the original velocity
            self.v *= -self.c
            m.set_y(self.gry + self.radius)

class BouncingBallScene(Scene):
    def construct(self):
        title = Text("Motivación").scale(0.75).to_corner(UL)
        self.ax = Axes(x_range=[-1, 5], y_range=[0, 5])
        labels = self.ax.get_axis_labels(r"t\text{ [s]}", r"y\text{ [m]}")
        self.play(Write(title))
        self.play(Write(VGroup(self.ax, labels)))
        self.wait()
        ball = BouncingBall(
            y0=self.ax.get_y_axis().get_top(),
            gry=self.ax.get_x_axis().get_y(),
            color=RED
        )
        ball.align_to(self.ax.get_x_axis(), LEFT)
        ball.save_state()
        self.play(ShowCreation(ball))
        ball.start_bouncing()
        self.wait(5)
        ball.stop_bouncing()
        self.wait()
        self.play(Restore(ball))
        self.wait()

        ball_copy = ball.deepcopy().set_opacity(0)
        t_tracker = ValueTracker(0)

        ball_copy.add_updater(lambda m: m.set_x(self.ax.c2p(t_tracker.get_value())[0]).set_y(ball.get_y()))
        ball.start_bouncing()
        self.path = TracedPath(ball_copy.get_center, stroke_color=YELLOW, stroke_width=4)
        self.bring_to_back(self.path, ball_copy)
        self.play(t_tracker.animate.set_value(5), run_time=5, rate_func=linear)
        ball_copy.clear_updaters()
        ball.stop_bouncing()
        self.wait()

        dot = Dot(self.ax.get_origin()).set_opacity(0)
        self.play(dot.animate.move_to(self.ax.c2p(2, 0)).set_opacity(1))
        self.wait()
        self.play(dot.animate.move_to(self.ax.i2gp(2, self.path)))
        self.wait()

        h_line = self.ax.get_h_line(dot.get_center())
        tip = ArrowTip().next_to(h_line, LEFT, buff=0)
        h_line.add(tip)
        y_coord = np.round(self.ax.p2c(dot.get_center())[1], decimals=2)
        y_coord_tex = Tex(f"{y_coord}").next_to(h_line, LEFT)
        self.bring_to_back(h_line)
        self.play(ShowCreation(h_line), Write(y_coord_tex))
        self.wait()
        self.t = ValueTracker(2)

        def dot_updater(m):
            m.move_to(self.ax.i2gp(self.t.get_value(), self.path))

        def h_line_updater(m):
            m.become(self.ax.get_h_line(dot.get_center()))
            tip = ArrowTip().next_to(h_line, LEFT, buff=0)
            m.add(tip)

        def y_coord_tex_updater(m):
            y_coord = np.round(self.ax.p2c(dot.get_center())[1], decimals=2)
            m.become(Tex(f"{y_coord}")).next_to(h_line, LEFT)

        dot.add_updater(dot_updater)
        h_line.add_updater(h_line_updater)
        y_coord_tex.add_updater(y_coord_tex_updater)
        self.play(self.t.animate.set_value(5), run_time=3)
        dot.remove_updater(dot_updater)
        h_line.remove_updater(h_line_updater)
        y_coord_tex.remove_updater(y_coord_tex_updater)
        self.wait()

        all_group = VGroup(title, ball, self.ax, labels, tip, h_line, y_coord_tex, dot, self.path)
        self.play(FadeOut(all_group))

class WhatIsFunction(Scene):
    def construct(self):
        title = Text("Concepto de función").scale(0.75).to_corner(UL)
        self.play(Write(title))
        tex_to_color_map = {
            "y": YELLOW,
            "f": GREY,
            "x": BLUE
        }
        func_tex = Tex("y", "=", "f", "(", "x", ")") \
            .set_color_by_tex_to_color_map(tex_to_color_map) \
            .scale(2)
        self.play(Write(func_tex))
        self.wait()
        f_x = func_tex[2:]
        self.play(Indicate(f_x))
        self.wait()
        self.play(Indicate(f_x[0]))
        self.play(Indicate(f_x[1:]))
        self.wait()
        self.play(Indicate(f_x))
        self.wait()
        self.play(Indicate(f_x))
        texto = TexText("$f$", " de ", "$x$") \
            .set_color_by_tex_to_color_map(tex_to_color_map) \
            .next_to(f_x, DOWN)
        self.play(GrowFromCenter(texto))
        self.wait()
        self.play(FadeOut(texto))

        g = VGroup(
            Tex("x", "=", "4"),
            Tex("y", "=", "5")
        ).arrange(RIGHT, buff=2).scale(2).next_to(func_tex, DOWN)
        for mob in g:
            mob.set_color_by_tex_to_color_map(tex_to_color_map)
            self.play(FadeIn(mob))

        self.wait()
        g_now = VGroup(
            Tex("x", "=", "3.1"),
            Tex("y", "=", "7.4")
        ).arrange(RIGHT, buff=2).scale(2).next_to(func_tex, DOWN)
        for mob in g_now: mob.set_color_by_tex_to_color_map(tex_to_color_map)
        self.play(Transform(g, g_now))
        self.wait()

        sc_rec = ScreenRectangle(height=3).to_corner(UR)
        self.play(ShowCreation(sc_rec))
        self.wait()
        self.play(Uncreate(sc_rec))
        self.wait()

        gr = VGroup(func_tex, g)
        self.play(FadeOut(gr))

        new_func = Tex("f", "(", "x", ")", "=", "2", "x", "+", "1") \
            .set_color_by_tex_to_color_map(tex_to_color_map) \
            .scale(2)
        self.play(Write(new_func))
        self.wait()

        tex_to_color_map_copy = tex_to_color_map.copy()
        tex_to_color_map_copy[r"2\relax"] = BLUE
        f_2 = Tex("f", "(", r"2\relax", ")", "=", "2", "(", r"2\relax", ")", "+", "1") \
            .set_color_by_tex_to_color_map(tex_to_color_map_copy) \
            .scale(1.5) \
            .next_to(new_func, DOWN)
        self.play(Write(f_2))
        self.wait()
        f_2_new = Tex("f", "(", r"2\relax", ")", "=", "5") \
            .set_color_by_tex_to_color_map(tex_to_color_map_copy) \
            .scale(1.5) \
            .next_to(new_func, DOWN)
        self.play(Transform(f_2, f_2_new))
        self.wait()

        self.play(FadeOut(VGroup(title, new_func, f_2)))


from enum import Enum, IntEnum

from pydantic import BaseModel, conint, confloat

class SexEnum(Enum):
    M = 'M'
    F = 'F'

class ChesPainTypeEnum(Enum):
    TypicalAngina = 'TA'
    AtypicalAngina = 'ATA'
    NonAnginalPain = 'NAP'
    Asymptomatic = 'ASY'

class FastingBsEnum(IntEnum):
    T = 1
    F = 0

class RestingECGEnum(Enum):
    Normal = 'Normal'
    ST = 'ST'
    LVH = 'LVH'

class ExerciseAnginaEnum(Enum):
    Yes = 'Y'
    No = 'N'

class STSlopeEnum(Enum):
    Up = 'Up'
    Flat = 'Flat'
    Down = 'Down'

class Patient(BaseModel):
    age: conint(ge=1)
    sex: SexEnum
    chestPainType: ChesPainTypeEnum
    restingBP: confloat(ge=0.0)
    cholesterol: confloat(ge=0.0)
    fastingBS: FastingBsEnum
    restingECG: RestingECGEnum
    maxHR: conint(ge=60, le=202)
    exerciseAngina: ExerciseAnginaEnum
    oldpeak: float
    sTSlope: STSlopeEnum

    class Config:
        use_enum_values = True

class PredictResponse(BaseModel):
    prob: confloat(ge=0.0, le=1.0)


# coding=utf-8
# __author:"NGLS Chuang"
# date: 2019/11/12
"""
  多行注释
"""
"""
 字典
  a=10
  b=a
  b=15
  这里需要讲一个点，a=10,a=5 是在内存空间内创建一个a=10的空间而a的指针指向10 ，后又创建一个a=5的空间，这时a的指针又指向5.而那个10的空间还是存在的

  不可变类型：整形，字符串，元组
  可变类型：列表，字典
  总结：就是看开辟的内存是否可被修改。
  字典定义
  dic={''}
  dic2=dict((()))
  dic6=dict.fromkeys(['host1',host2,'host3'],'test') 这个创建字典时会把列表中每一个作为一个key ,而所有都是一个value
  字典存储的键值对是无序的，
  在取值时，通过dic['key'] 则可对应这个的值
  字典两大特点：无序，键唯一

    字典的相关操作方法
    1.增加
    dic1={'name':'alex'}
    dic1{'age'}=18       则会吧这个键值对进行了添加。
    setdefault
    dic1.setdefault{'age',34}
    该方法是 对dic1中的键值对进行检查，如果有age这个键，那么就不做任何变动，如果没有则会添加一个这样的键值对。
    如果用一个值去接收它，那么就会接收到原来age的
    2.查的话 基本都是通过key 查找对应的value
    查找对应的key 可以通过 dic1.keys()  如果想用的话可以通过 list(dic1.keys())编程列表进行操作
    同理查找所有的value list(dic1.values()),会打印所有的值。
    3.改
    dic1{'age'}=26...
    dic1.update(dic4) 该方法是把dic4字典的键值对加入，如果有重复则会覆盖。
    4.删除
    del dic1{'name'} 删除该索引下的键值对
    dic1.clear() 对字典进项清空。
    dic1.pop('age')  删除索引对应的值，并把值返回
    5.嵌套字典的操作
      修改 dic1[key1][key2][1]='要改的内容'
    6.字典的排序
      sorted(dic1)  根据键的数字由小到大的排序，字符串英文也是 dic1.value()  可以根据值来排序
    7.字典的遍历
      for i in dic1
        print(i,dic1[i])
      for i in dic1.items():
        print(i)
"""
"""
字符串
    1.字符串可以用切片输出
    比如：print('helloworld'[2:])
    2.关键字 in 可以判断字符串是否存在某个字符串， 存在True 反之
    3.字符串格式化，print('%s is a good'%'alasl')
    4.字符串的正确拼接 c=''.join([a,b])
字符串的常用内置方法
    1.st='hello world'
    print(st.count('l'))查看个数
    2.print(st.capitalize())将字符串首字母大写
    3.print(st.center(50,'-'))一共打印50个- 把字符串放中间
    4.print（st.encode()）
    5.print(st.endswith('y'))是否是以这个字符串结尾
    6.print(st.startswith('y'))是否是以这个字符串开头
    7.print(st.find('o'))查找某一个字符的位置并且返还给我们
    8.print(st.index('w')) 返回值6
    7.print('sad'.isalnum())查看是否是字母
    8.print()
"""

menu = {
    '北京': {
        '朝阳': {
            '国贸': {
                'CICC': {},
                'HP': {},
                'CCTV': {},
            },
            '望京': {
                '陌陌': {},
                '奔驰': {},
                '360': {},
            },
            '三里屯': {
                '优衣库': {},
                '苹果': {},
                '艾比': {},
            },
        },
        '昌平': {
            '沙河': {
                '沙河居委会': {},
                'oldboy': {},
                '阿泰包子': {},
            },
            '天通苑': {
                '链家': {},
                '我爱我家': {},
                '社区': {},
            },
            '回笼馆': {
                '优衣库': {},
                '苹果': {},
                '艾比': {},
            },
        },
        '海淀': {
            '五道口': {
                '谷歌': {},
                '网易': {},
                '快手': {},
            },
            '中观村': {
                '优酷': {},
                '爱奇艺': {},
                '腾讯': {},
            },
            '五棵松': {
                '华西': {},
                '二院': {},
                '医院': {},
            },
        },
    },
    '上海': {
        '浦东': {
            '陆家嘴': {
                'CCIC': {},
                '高盛': {},
                '摩根': {},
            },
            '外滩': {},
            '郊区': {},
        },
        '文行': {
        },
        '静安': {
        },
    },
    '山东': {
        '济南': {},
        '德州': {
            '乐陵': {
                '定乌镇': {},
                '城区': {},
                '艾比下乡': {},
            },
            '平原': {},
            '庞德': {},
        },
        '青岛': {},
    }
}
"""
  要求可以 一层一层进入到所有层
  可以在每层返回到上一层
  可以在任一层推出
"""
# flag = True
# while flag:
#     print('选择那您的省份/或直辖市')
#     # 第一层循环出北京等市单位
#     for city in menu:
#         print(city)
#     choice = input('>>:').strip()
#     if choice in menu:
#         while True:
#             # 循环出区和市的单位
#             for city2 in menu[choice]:
#                 print(city2)
#             choice2 = input("输入市,返回上一层请输入exit>>:").strip()
#             if choice2 in menu[choice]:
#                 while True:
#                     # 循环出三里屯
#                     for city3 in menu[choice][choice2]:
#                         print(city3)
#                     choice3 = input("输入乡及场所,返回上一层请输入exit:").strip()
#                     if choice3 in menu[choice][choice2]:
#                         while True:
#                             for city4 in menu[choice][choice2][choice3]:
#                                 print(city4)
#                             choice4 = input('返回上一层请输入exit')
#                             if choice4 == 'exit':
#                                 break
#                     elif choice3 == 'exit':
#                         break
#             elif choice2 == 'exit':
#                 break
#             else:
#                 print('输入正确省份')
#
#     else:
#         print('请输入正确省份')
"""
下面是简化版的代码。
"""
# 定义一个当前层 ,思路是 每次循环的小字典 都赋值给这个current_layer
current_layer = menu
parent_layer = []
# 回退思路 就是把没进入一层的父层添加到列表里，这样我们只需要，在回退时把这个值pop并删掉取出来进行操作即可
while True:
    for city in current_layer:
        print(city)
    choice = input('>>>:').strip()
    if len(choice) == 0: continue
    if choice in current_layer:
        parent_layer.append(current_layer)
        current_layer = current_layer[choice]
    elif choice =="exit":
        # 这句话就代表 parent_layer不为空就是true 反之
        if parent_layer:
            current_layer = parent_layer.pop()
        else:
            print('到头了，别按了')

    else:
        print("无此项")


from torch import nn
import torch
import numpy as np
import torch.nn.functional as fn
import os

feat_depth, roi_dim, fc_neuron = 256, 3, 1024

def get_device(gpu):
    if gpu >= 0 and torch.cuda.is_available():
        return torch.device("cuda:" + str(gpu))
    return torch.device("cpu")

def bbox_iou(box_a, box_b):
    xa, ya, wa, ha = box_a[..., 0], box_a[..., 1], box_a[..., 2], box_a[..., 3]
    xb, yb, wb, hb = box_b[..., 0], box_b[..., 1], box_b[..., 2], box_b[..., 3]
    x1, y1, x2, y2 = xa - wa / 2, ya - ha / 2, xa + wa / 2, ya + ha / 2
    x3, y3, x4, y4 = xb - wb / 2, yb - hb / 2, xb + wb / 2, yb + hb / 2
    x5 = torch.max(x1, x3)
    y5 = torch.max(y1, y3)
    x6 = torch.min(x2, x4)
    y6 = torch.min(y2, y4)
    w = torch.clamp(x6 - x5, min=0)
    h = torch.clamp(y6 - y5, min=0)
    inter_area = w * h
    b1_area = (x2 - x1) * (y2 - y1)
    b2_area = (x4 - x3) * (y4 - y3)
    iou = inter_area / (b1_area + b2_area - inter_area + 1e-16)
    return iou

def anchor_bbox(anchor, n_grid):
    # anchor_tensor: [na, ng, ng, 4(x/y/w/h)]

    na, ng = len(anchor), n_grid
    grids = np.linspace(0.5 / ng, (ng - 0.5) / ng, ng)
    gy, gx = np.meshgrid(grids, grids)
    x = torch.tensor(gx).view(1, ng, ng).repeat(na, 1, 1).float()
    y = torch.tensor(gy).view(1, ng, ng).repeat(na, 1, 1).float()
    a = torch.tensor(anchor).view(na, 1, 1, 2).repeat(1, ng, ng, 1)
    w = a[:, :, :, 0]
    h = a[:, :, :, 1]
    anchor_tensor = torch.stack((x, y, w, h), dim=-1)
    return anchor_tensor

def valid_bbox(bbox):
    x, y, w, h = bbox[..., 0], bbox[..., 1], bbox[..., 2], bbox[..., 3]
    x1, x2, y1, y2 = x - w / 2, x + w / 2, y - h / 2, y + h / 2
    valid_x = torch.bitwise_and(torch.bitwise_and(0 <= x1, x1 <= x2), x2 <= 1)
    valid_y = torch.bitwise_and(torch.bitwise_and(0 <= y1, y1 <= y2), y2 <= 1)
    valid = torch.bitwise_and(valid_x, valid_y)
    return valid

def roi_pooling(feature, proposals):
    # feature: [nb, fd, ng, ng]
    # proposals: [nb, nr, 5(x/y/w/h/obj)]
    # rois: [nb, nr, fd * rd * rd]

    nb, nr, ng = proposals.size(0), proposals.size(1), feature.size(2)
    fd, rd = feat_depth, roi_dim
    p = proposals[..., 0:4]
    valid = valid_bbox(p)
    x, y, w, h = p[..., 0], p[..., 1], p[..., 2], p[..., 3]
    p = (torch.stack((x - w / 2, x + w / 2, y - h / 2, y + h / 2), dim=-1) * ng).long()
    rois = torch.zeros((nb, nr, fd, rd, rd)).float()
    for i in range(nb):
        for j in range(nr):
            if valid[i, j]:
                _x1, _x2, _y1, _y2 = p[i, j, 0], p[i, j, 1], p[i, j, 2], p[i, j, 3]
                im = feature[i, :, _x1:(_x2 + 1), _y1:(_y2 + 1)]
                rois[i, j, :, :, :] = fn.adaptive_max_pool2d(im, (rd, rd))
    rois = rois.view(nb, nr, -1)
    return rois

def output_to_real(outputs, proposals):
    p = proposals
    t = outputs
    xp, yp, wp, hp = p[..., 0], p[..., 1], p[..., 2], p[..., 3]
    tx, ty, tw, th = t[..., 0], t[..., 1], t[..., 2], t[..., 3]
    x = tx * wp + xp
    y = ty * hp + yp
    w = torch.exp(tw) * wp
    h = torch.exp(th) * hp
    obj = t[..., 4] + 0 * x
    real = torch.stack((x, y, w, h, obj), dim=-1)
    return real

def real_to_output(real, proposals):
    p = proposals
    r = real
    xp, yp, wp, hp = p[..., 0], p[..., 1], p[..., 2], p[..., 3]
    x, y, w, h = r[..., 0], r[..., 1], r[..., 2], r[..., 3]
    tx = (x - xp) / (wp + 1e-30)
    ty = (y - yp) / (hp + 1e-30)
    tw = torch.log((w + 1e-30) / (wp + 1e-30))
    th = torch.log((h + 1e-30) / (hp + 1e-30))
    obj = r[..., 4] + 0 * tx
    outputs = torch.stack((tx, ty, tw, th, obj), dim=-1)
    return outputs

class Net(nn.Module):

    def __init__(self, gpu):
        super().__init__()
        self.device = get_device(gpu)

    def save_to_file(self, file):
        state = self.state_dict()
        torch.save(state, file)

    def load_from_file(self, file):
        if os.path.exists(file):
            state = torch.load(file, map_location=self.device)
            self.load_state_dict(state)
        else:
            print("cannot load net file: " + file)

class BackBoneNet(Net):

    def __init__(self, gpu=-1):
        super().__init__(gpu)
        layers = list()
        layers.append(nn.Conv2d(3, 96, kernel_size=7, stride=2, padding=1))
        layers.append(nn.ReLU(inplace=True))
        layers.append(nn.MaxPool2d(kernel_size=3, stride=2, padding=1))
        layers.append(nn.LocalResponseNorm(5))
        layers.append(nn.Conv2d(96, 256, kernel_size=5, stride=2))
        layers.append(nn.ReLU(inplace=True))
        layers.append(nn.MaxPool2d(kernel_size=3, stride=2, padding=1))
        layers.append(nn.LocalResponseNorm(5))
        layers.append(nn.Conv2d(256, 384, kernel_size=3, stride=1, padding=1))
        layers.append(nn.ReLU(inplace=True))
        layers.append(nn.Conv2d(384, 384, kernel_size=3, stride=1, padding=1))
        layers.append(nn.ReLU(inplace=True))
        layers.append(nn.Conv2d(384, feat_depth, kernel_size=3, stride=1, padding=1))
        layers.append(nn.ReLU(inplace=True))
        layers.append(nn.MaxPool2d(kernel_size=3, stride=2))
        self.cnn = nn.Sequential(*layers)
        self.to(self.device)

    def forward(self, images):
        images = images.to(self.device)
        feature = self.cnn(images)
        return feature

class RegionProposeNet(Net):
    anchor = [[0.1, 0.1], [0.3, 0.3], [0.5, 0.5], [0.8, 0.8]]

    def __init__(self, gpu=-1):
        super().__init__(gpu)
        layers = list()
        layers.append(nn.Conv2d(feat_depth, feat_depth, 3, 1, 1))
        layers.append(nn.LeakyReLU(0.1, inplace=True))
        layers.append(nn.Conv2d(feat_depth, 5 * len(self.anchor), 1, 1, 0))
        self.cnn = nn.Sequential(*layers)
        self.to(self.device)

    def forward(self, feature):
        # feature: [nb, feat_depth, ng, ng]
        # proposals: [nb, na, ng, ng, 5(x/y/w/h/obj)]

        nb, ng, na = feature.size(0), feature.size(2), len(self.anchor)
        p = self.cnn(feature).view(nb, 5, na, ng, ng).permute((0, 2, 3, 4, 1))
        a = anchor_bbox(self.anchor, ng).to(self.device)
        ax, ay, aw, ah = a[None, ..., 0], a[None, ..., 1], a[None, ..., 2], a[None, ..., 3]
        x = p[..., 0] * aw + ax
        y = p[..., 1] * ah + ay
        w = torch.exp(p[..., 2]) * aw
        h = torch.exp(p[..., 3]) * ah
        obj = torch.sigmoid(p[..., 4])
        proposals = torch.stack((x, y, w, h, obj), dim=-1)
        return proposals

    def predict(self, feature, n_best=None):
        # feature: [nb, feat_depth, ng, ng]
        # proposals: [nb, nr, 5(x/y/w/h/obj)]

        nb, ng, na = feature.size(0), feature.size(2), len(self.anchor)
        nr = na * ng * ng
        feature = feature.to(self.device)
        proposals = self(feature).view(nb, nr, 5)
        idx = torch.argsort(- proposals[:, :, 4], dim=1)
        proposals = torch.gather(proposals, 1, idx[:, :, None].repeat(1, 1, 5))
        if n_best is not None:
            proposals = proposals[:, :n_best, :].contiguous()
        return proposals

    def loss_fn(self, feature, targets):
        # feature: [nb, feat_depth, ng, ng]
        # targets: [nb, no, 4(x/y/w/h)]

        proposals = self(feature)
        gt = targets.to(self.device)
        p = proposals.to(self.device)
        nb, na, ng, no = p.size(0), p.size(1), p.size(2), gt.size(1)
        anchors = anchor_bbox(self.anchor, ng)[None, :, :, :, :].repeat(nb, 1, 1, 1, 1).to(self.device)
        anchors_obj = anchors.view(nb, na, ng, ng, 1, 4).repeat(1, 1, 1, 1, no, 1)
        gt_roi = gt.view(nb, 1, 1, 1, no, 4).repeat(1, na, ng, ng, 1, 1)
        iou_obj = bbox_iou(anchors_obj, gt_roi)
        iou_idx = torch.argmax(iou_obj, dim=-1, keepdim=True)
        iou_idx_t = iou_idx.view(nb, na, ng, ng, 1, 1).repeat(1, 1, 1, 1, 1, 4)
        gt_active = torch.gather(gt_roi, -2, iou_idx_t).view(nb, na, ng, ng, 4)
        iou_active = torch.gather(iou_obj, -1, iou_idx).view(nb, na, ng, ng)
        valid = valid_bbox(anchors)
        mask_obj = torch.bitwise_and(iou_active > 0.5, valid)
        mask_no_obj = torch.bitwise_and(torch.bitwise_and(iou_active > 0, iou_active < 0.1), valid)
        loss_reg = torch.sum((p[..., 0:4] - gt_active) ** 2, dim=-1)
        loss_obj = (p[..., 4] - 1) ** 2
        loss_no_obj = (p[..., 4] - 0) ** 2
        loss_1 = torch.sum(loss_reg * mask_obj)
        loss_2 = torch.sum(loss_obj * mask_obj)
        loss_3 = torch.sum(loss_no_obj * mask_no_obj)
        loss = loss_1 + loss_2 + loss_3
        return loss

class FastHead(Net):

    def __init__(self, n_cls, gpu=-1):
        super().__init__(gpu)
        layers = list()
        layers.append(nn.Linear(feat_depth * roi_dim * roi_dim, fc_neuron))
        layers.append(nn.ReLU())
        layers.append(nn.Linear(fc_neuron, fc_neuron))
        layers.append(nn.ReLU())
        layers.append(nn.Linear(fc_neuron, n_cls * 5))
        self.fc = nn.Sequential(*layers)
        self.n_cls = n_cls
        self.to(self.device)

    def forward(self, rois):
        # rois: [nb, nr, fd*rd*rd]
        # outputs: [nb, nr, nc, 5(tx/ty/tw/th/obj)]

        nb, nr, nc = rois.size(0), rois.size(1), self.n_cls
        rois = rois.to(self.device)
        outputs = self.fc(rois)
        outputs = outputs.view(nb, nr, nc, 5)
        outputs[..., 4] = torch.sigmoid(outputs[..., 4])
        return outputs

    def predict(self, feature, proposals):
        # feature: [nb, fd, ng, ng]
        # proposals: [nb, nr, 5(x/y/w/h/obj)]
        # preds: [nb, nr, nc, 5(x/y/w/h/obj)]

        nb, nr, nc = proposals.size(0), proposals.size(1), self.n_cls
        rois = roi_pooling(feature, proposals)
        outputs = self(rois).view(nb, nr, nc, 5)
        preds = output_to_real(outputs, proposals[:, :, None, :])
        return preds

    def loss_fn(self, feature, proposals, targets):
        # feature: [nb, fd, ng, ng]
        # proposals: [nb, nr, 5(x/y/w/h/obj)]
        # targets: [nb, nc, 5(x/y/w/h/obj)]

        nb, nr, nc = proposals.size(0), proposals.size(1), self.n_cls

        feature = feature.to(self.device)
        props = proposals.to(self.device)
        rois = roi_pooling(feature, proposals)
        targets = targets.to(self.device)
        outpus = self(rois).view(nb, nr, nc, 5)

        tgets = real_to_output(targets[:, None, :, :], props[:, :, None, :])  # [nb, nr, nc, 5]

        valid = valid_bbox(props)  # [nb, nr]
        ious = bbox_iou(props[:, :, None, :], targets[:, None, :, :])  # [nb, nr, nc]

        loss = torch.sum(valid[:, :, None] * (targets[:, None, :, 4] == 1) *
                ((ious > 0.7) * torch.sum((outpus - tgets) ** 2, dim=-1) +
                (ious < 0.3) * (outpus[..., 4] - 0)**2))

        return loss

def main():
    nb, n_cls, img_dim, n_obj = 10, 3, 500, 2

    images = torch.zeros((nb, 3, img_dim, img_dim)).float()
    targets_obj = torch.zeros((nb, n_obj, 4)).float()
    targets_cls = torch.zeros((nb, n_cls, 5)).float()

    bbn: BackBoneNet = BackBoneNet()
    rpn: RegionProposeNet = RegionProposeNet()
    fhd: FastHead = FastHead(n_cls)

    feature = bbn(images)
    loss_rpn = rpn.loss_fn(feature, targets_obj)
    print(images.shape, feature.shape, loss_rpn)

    proposals = rpn.predict(feature, n_best=64)
    loss_fhd = fhd.loss_fn(feature, proposals, targets_cls)
    print(proposals.shape, loss_fhd)

    print("done")

if __name__ == "__main__":
    main()


from sample_server import SampleServer
from simulation import Simulation

# Inherit from SampleServer, as we did with the unit tests.
class SimulationServer(SampleServer):

    # This is a method I know exists from the parent class, that will
    # be called every time a post request is made.
    def do_POST(self):
        # Call the parent method (which is part of our class now, so self works),
        # in order to extract post data.
        postData = self.get_post_data();
        # Extract the keys. This almost forms a contract with the caller, dictating
        # the information that needs to be passed.
        location = postData["location"];
        days = postData["days"];
        # Call our original simulation class, and the weather method, to invoke our model.
        # Note we're creating an object of simulation here on the fly. Really this should
        # be done in a constructor.
        weather = Simulation().weather(location, days);
        # Once again invoke the parent method to send the data back.
        # Should really be encapsulated in a JSON string also for consistency, but
        # we're just doing things simply for now.
        self.send_post_response(weather);


from typing import Union
import os
from pathlib import Path

from pasquim.parser import Lexer, Parser
from pasquim.primitives import compile_expr, wordsize

# A Scheme expression, which can be an Atom or List
Exp = Union[str, int, float, list]

class Compiler:
    """A Scheme compiler.

    Translates a Scheme program into Assembly, then generates an executable
    binary.

    Args:
        path (str): Path where compiled program will be saved.
        program (str): Scheme program to be compiled.
    """
    def __init__(self, path: str, program: str) -> None:
        self.path = self._prep_output(path)
        parser = Parser(Lexer(program).tokenize())
        self.program = parser.parse()

        self.asm_program = ""

    @staticmethod
    def _prep_output(path: str) -> Path:
        """Prepares output path for the compiled program."""
        output_path = Path(path)
        output_path.mkdir(parents=True, exist_ok=True)

        return output_path

    def _emit(self, line: str) -> None:
        """Adds a line to the assembly program."""
        self.asm_program += line + "\n"

    def _emit_expr(self, expr: Exp) -> None:
        """Compiles a single passed expression."""

        for i in compile_expr(expr, -wordsize):
            self._emit(i)

    def compile_program(self) -> None:
        """Compiles Scheme program to Assembly."""
        self.asm_program = ""  # reset

        self._emit(".text")
        self._emit(".p2align 4,,15")
        self._emit(".globl scheme_entry")
        self._emit("scheme_entry:")

        # handle incoming call from C
        self._emit("push %esi")
        self._emit("push %edi")
        self._emit("push %edx")

        # program's code
        self._emit_expr(self.program)

        # restore state for return to C
        self._emit("pop %edx")
        self._emit("pop %edi")
        self._emit("pop %esi")
        self._emit("ret")

    def compile_to_binary(self) -> None:
        self.compile_program()

        compiled_path = self.path.joinpath("compiled.s")
        with open(compiled_path, 'w') as f:
            f.write(self.asm_program)

        os.system(f"gcc -fomit-frame-pointer -m32 "
                  f"{str(compiled_path)} pasquim/src/rts.c "
                  f"-o {str(self.path.joinpath('a.out'))}")