import pexpect
import sys
import os
import subprocess

### ADD NEW TESTS HERE ###
TESTCMDS = [
    ["/bin/ls"],
    [""],
    ["/bin/uname"],
    ["/bin/uname -a"],
    ["     "],
    ["abc"],
    ["echo hello world    how are you??"],
    [" echo -n hello"],
    ["echo \"cat lol.c | cat > lol.c\""],
    ["ls \"\""],
    ["echo $"],
    ["$"],
    ["echo $US"],
    ["echo $USER"],
    ["echo $USER:$USER"],
    ["echo \"$USER:$USER\""]
    ]

class bcolors:
    HEADER = '\033[95m'
    OKBLUE = '\033[94m'
    OKCYAN = '\033[96m'
    OKGREEN = '\033[92m'
    WARNING = '\033[93m'
    FAIL = '\033[91m'
    ENDC = '\033[0m'
    BOLD = '\033[1m'
    UNDERLINE = '\033[4m'

TESTLOGPATH = os.path.expandvars("$HOME") + "/minishell_tester/testlogs/"
MINISHELLPATH = "./minishell"
ARGC = len(sys.argv)
for arg in sys.argv[1:]:
    if '$' in arg:
        os.environ['PROMPT'] = os.path.expandvars(arg)
        PROMPT = os.path.expandvars(arg)
        break

def referenceresult(minishell, bash_result):
    try:
        minishell.expect_exact(PROMPT, timeout=1)
        if (minishell.before.decode() == bash_result):
            return bcolors.OKGREEN + "OK" + bcolors.ENDC
        return bcolors.FAIL + "KO" + bcolors.ENDC
    except:
        return bcolors.FAIL + "KO" + bcolors.ENDC

def get_bash_result(bash, cmd):
    bash.sendline("export PS1='" + PROMPT + "'")
    bash.expect_exact("\r\n")
    bash.expect_exact(PROMPT)
    bash.sendline(cmd)
    bash.expect_exact(cmd + "\r\n")
    bash.expect_exact(PROMPT)
    return bash.before.decode()

def test(cmdlist, testnum):
    try:
        minishell = pexpect.spawn(MINISHELLPATH)
    except:
        print("Couldn't open minishell. Make sure to execute the tester in the folder where your Makefile and minishell binary are located.")
        exit(1)
    minishell_logfile = TESTLOGPATH + str(testnum).zfill(3) + "_testoutput_minishell.log"
    minishell.logfile_read = open(minishell_logfile, "wb")

    bash = pexpect.spawn("bash")
    bash_logfile = TESTLOGPATH + str(testnum).zfill(3) + "_testoutput_bash.log"
    bash.logfile_read = open(bash_logfile, "wb")

    print(bcolors.HEADER + bcolors.BOLD + f"\nTest {testnum:03d}" + bcolors.ENDC)
    for i, cmd in enumerate(cmdlist):
        bash_result = get_bash_result(bash, cmd)
        print(f"{'Command:':10}{cmd}")
        print(f"{'Expected:':10}{bash_result}")
        minishell.sendline(cmd)
        minishell.expect_exact(cmd + "\r\n")
        print(referenceresult(minishell, bash_result))
    minishell.logfile_read.close()
    bash.logfile_read.close()
    minishell.sendline("exit")
    bash.sendline("exit")

def print_welcome():
    print(bcolors.UNDERLINE + bcolors.BOLD + bcolors.OKBLUE + "\nminishell Tester\n" + bcolors.ENDC)
    print("All results will be compared to your machine's bash")

def print_usage():
    print("Usage: minishell_tester '<your_minishell_prompt_in_single_quotes>' [testnumber]")
    print("(Execute in the root directory of your minishell repo)\n")
    print("Example: Execute All Tests")
    print("minishell_tester 'minishell$ '\n")
    print("Example: Execute Only Test No. 5")
    print("minishell_tester 'minishell$ ' 5\n")
    print("Options:")
    print("  -h, --help\tprint this help essage")
    print("  -u, --update\tupdate minishell_tester")

def build_minishell():
    print("")
    print(bcolors.HEADER + "Executing your Makefile..." + bcolors.ENDC)
    try:
        subprocess.run(["make"])
        print("")
    except:
        print("Couldn't execute Makefile. Make sure to execute the tester in the folder where your Makefile and minishell binary are located.")
        exit(1)

def print_logfile_info():
    print(bcolors.WARNING + "Test logs can be found in $HOME/minishell_tester/testlogs" + bcolors.ENDC)

def execute_tests():
    os.makedirs(TESTLOGPATH, exist_ok=True)
    if ARGC > 2:
        print(bcolors.HEADER + "Executing Test..." + bcolors.ENDC)
        test(TESTCMDS[int(sys.argv[2])], int(sys.argv[2]))
    else:
        print(bcolors.HEADER + "Executing Tests..." + bcolors.ENDC)
        for testnum, cmdlist in enumerate(TESTCMDS):
            test(cmdlist, testnum)

def main():
    for arg in sys.argv[1:]:
        if '$' in arg:
            os.environ['PROMPT'] = os.path.expandvars(arg)
            PROMPT = os.path.expandvars(arg)
            break
    if "-addtest" in sys.argv or "--addtest" in sys.argv:
    # Use subprocess to run the update script
        subprocess.run(["python3", os.path.expandvars("$HOME") + "/minishell_tester/interactive.py", os.environ['PROMPT']])
        exit(0)
    if "-u" in sys.argv or "--update" in sys.argv:
    # Use subprocess to run the update script
        subprocess.run(["python3", os.path.expandvars("$HOME") + "/minishell_tester/check_for_update.py"])
        exit(0)
    if "-h" in sys.argv or "--help" in sys.argv:
        print_usage()
        exit(0)
    if ARGC == 1 or ARGC > 3:
        print(bcolors.WARNING + "Error: Wrong number of arguments\n" + bcolors.ENDC)
        print_usage()
        exit(1)
    print_welcome()
    build_minishell()
    #output = subprocess.check_output(["./minishell"])
    #print(output.decode())
    execute_tests()
    print_logfile_info()

if __name__ == "__main__":
    main()


from typing import Any, Iterable, Optional
from collections.abc import MutableSequence

from node import Node, DoubleLinkedNode

class LinkedList(MutableSequence):
    CLASS_NODE = Node

    def __init__(self, data: Iterable = None):
        """Конструктор связного списка"""
        self._len = 0
        self._head: Optional[Node] = None
        self._tail = self._head

        if data is not None:
            for value in data:
                self.append(value)

    def insert(self, index: int, value) -> None:
        if not isinstance(index, int):
            raise TypeError()
        insert_node = Node(value)
        if index == 0:
            insert_node.next = self._head
            self._head = insert_node
            self._len += 1

        elif index >= self._len - 1:
            self.append(value)
        else:
            prev_node = self.step_by_step_on_nodes(index - 1)
            next_node = prev_node.next
            self.linked_nodes(prev_node, insert_node)
            self.linked_nodes(insert_node, next_node)
            self._len += 1

    def __delitem__(self, index: int) -> None:

        """Удаление узла по индексу"""
        if not isinstance(index, int):
            raise TypeError()

        if not 0 <= index < self._len:
            raise IndexError()

        if index == 0:
            self._head = self._head.next
        elif index == self._len - 1:
            tail = self.step_by_step_on_nodes(index-1)
            tail.next = None
            self._tail = tail
        else:
            prev_node = self.step_by_step_on_nodes(index-1)
            del_node = prev_node.next
            next_node = del_node.next
            self.linked_nodes(prev_node, next_node)

        self._len -= 1

    def __len__(self) -> int:
        return self._len

    def append(self, value: Any):
        """ Добавление элемента в конец связного списка. """
        append_node = self.CLASS_NODE(value)

        if self._head is None:
            self._head = self._tail = append_node
        else:
            self.linked_nodes(self._tail, append_node)
            self._tail = append_node

        self._len += 1

    def step_by_step_on_nodes(self, index: int) -> Node:
        """ Функция выполняет перемещение по узлам до указанного индекса. И возвращает узел. """
        if not isinstance(index, int):
            raise TypeError()

        if not 0 <= index < self._len:
            raise IndexError()

        current_node = self._head
        for _ in range(index):
            current_node = current_node.next

        return current_node

    @staticmethod
    def linked_nodes(left_node: Node, right_node: Optional[Node] = None) -> None:
        """
        Функция, которая связывает между собой два узла.
        """
        left_node.next = right_node

    def __getitem__(self, index: int) -> Any:
        """ Метод возвращает значение узла по указанному индексу. """
        node = self.step_by_step_on_nodes(index)
        return node.value

    def __setitem__(self, index: int, value: Any) -> None:
        """ Метод устанавливает значение узла по указанному индексу. """
        node = self.step_by_step_on_nodes(index)
        node.value = value

    def to_list(self) -> list:
        return [linked_list_value for linked_list_value in self]

    def __repr__(self) -> str:
        return f"{self.__class__.__name__}({self.to_list()})"

    def __str__(self) -> str:
        return f"{self.to_list()}"

class DoubleLinkedList(LinkedList):
    CLASS_NODE = DoubleLinkedNode

    @staticmethod
    def linked_nodes(left_node: DoubleLinkedNode, right_node: Optional[DoubleLinkedNode] = None) -> None:
        left_node.next = right_node
        right_node.prev = left_node

class NewLinkedList(LinkedList):

    def remove_(self, x):
        # s = 0
        # for i in range(self._len):
        #     s += 1
        #     if self[i] == x:
        #         self.__delitem__(i)  # del self[i]
        #         break
        #     if self._len == s:
        #         raise TypeError

        for i, value in enumerate(self):
            if value == x:
                self.__delitem__(i)  # del self[i]
                break

        if i == len(self) - 1:
            raise TypeError

if __name__ == "__main__":
    list_ = [5, 2, 3, 7, 9]
    linked_list = LinkedList(list_)
    print(linked_list)
    print(linked_list.__repr__())

    linked_list_2 = NewLinkedList(list_)
    linked_list_2.remove_(5)
    print(linked_list_2)

Зачетное задание/Зачетное задание/DoubleLinkedList/task.py


def cumsum(t):
   r = []
   for i in range(len(t)):
      soma = 0
      for j in range(i+1):
          soma += t[j]

      r.append(soma)

   return(r)

t = [1, 2, 3]
soma = cumsum(t)
print(soma)


from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework.exceptions import NotFound
from rest_framework.status import HTTP_204_NO_CONTENT
from .models import Category
from .serializers import CategorySerializer

@api_view(["GET", "POST"])  # GET, POST 둘 다 허용. 기본값=GET
def categories(request):
    if request.method == "GET":
        all_categories = Category.objects.all()
        serializer = CategorySerializer(
            all_categories,
            many=True,
        )  # QuerySet을 전달할 경우, many=True를 해주어야 함. 기본값=data 1개.
        return Response(serializer.data)  # serializer로 받은 data
    elif request.method == "POST":
        serializer = CategorySerializer(data=request.data)  # data= 로 데이터 작성
        if serializer.is_valid():  # 유효성 검사
            new_category = (
                serializer.save()
            )  # POST로 받은 데이터를 저장. .save()를 실행하면 자동적으로 serializer안에서 create메소드를 찾음.
            return Response(
                CategorySerializer(new_category).data,
            )
        else:
            return Response(serializer.errors)

@api_view(["GET", "PUT", "DELETE"])
def oneCategory(request, pk):
    # 예외처리
    try:
        category = Category.objects.get(pk=pk)
    except Category.DoesNotExist:
        raise NotFound

    if request.method == "GET":
        getSerializer = CategorySerializer(category)
        return Response(getSerializer.data)
    elif request.method == "PUT":
        putSerializer = CategorySerializer(
            category,
            data=request.data,
            partial=True,
        )  # partial=True: data일부만 전송되어도 유효성 검사에 걸리지 않게끔(업데이트 이기 때문에 일부만 변경 가능하게끔)
        if putSerializer.is_valid():
            updated_category = putSerializer.save()
            # 자동적으로 update 메소드 실행. serializer는 create, update를 자동적으로 구분함.
            return Response(CategorySerializer(updated_category).data)
        else:
            return Response(putSerializer.errors)
    elif request.method == "DELETE":
        category.delete()
        return Response(HTTP_204_NO_CONTENT)


# exercise 6.2.1
from matplotlib.pyplot import figure, plot,  xlabel, ylabel, show, legend, xscale
import numpy as np
from dataHeartDisaese import x as X, y
from sklearn import model_selection
from sklearn.preprocessing import PolynomialFeatures
from sklearn.linear_model import Ridge

N, M = X.shape

## Crossvalidation
K = 10
CV = model_selection.KFold(n_splits=K,shuffle=True)

# Initialize variables
lambdaRange = np.arange(0.0001, 1, 0.1)
# lambdaRange = np.log([1, 2, 3, 4, 10])
Error_train = np.empty((len(lambdaRange), K))
Error_test = np.empty((len(lambdaRange), K))

k = 0

for train_index, test_index in CV.split(X):
    print('Computing CV fold: {0}/{1}..'.format(k+1,K))

    # extract training and test set for current CV fold
    X_train, y_train = X[train_index, :], y[train_index].reshape(-1, 1)
    X_test, y_test = X[test_index, :], y[test_index].reshape(-1, 1)
    polynomial_features = PolynomialFeatures(degree=1)
    X_poly_train = polynomial_features.fit_transform(X_train)
    X_poly_test = polynomial_features.fit_transform(X_test)

    for i, t in enumerate(lambdaRange):
        model = Ridge(alpha=t)
        model.fit(X_poly_train, y_train)
        y_est_test = model.predict(X_poly_test)
        y_est_train = model.predict(X_poly_train)
        # Evaluate misclassification rate over train/test data (in this CV fold)
        Error_test[i, k] = sum(np.square(y_est_test - y_test)) / float(len(y_est_test))
        Error_train[i, k] = sum(np.square(y_est_train - y_train)) / float(len(y_est_train))

    k += 1

err, bestLambda = sorted(list(zip(Error_test.mean(1), lambdaRange)))[0]
print('Best lambda for model {0}'.format(round(bestLambda, 2)))
f = figure()
plot(lambdaRange, Error_train.mean(1))
plot(lambdaRange, Error_test.mean(1))
# plot(lambdaRange, y.mean())
xlabel('lambda')
ylabel('error'.format(K))
legend(['Error_train', 'Error_test'])
# xscale('log')
show()


from copy import copy

class cache():

    def __init__(this):
        this.cache_memory={
            "0":
                {
                    "state": "I",
                    "value": "0x0000",
                    "dir": None
                }
            ,
            "1":
                {
                    "state": "I",
                    "value": "0x0000",
                    "dir": None
                },
            "2":
                {
                    "state": "I",
                    "value": "0x0000",
                    "dir": None
                },
            "3":
                {
                    "state": "I",
                    "value": "0x0000",
                    "dir": None
                }
        }

    # Leer dato de cache
    def read_data(this, direction_memory):
        block=""

        # correspondencia set one way (directa)
        if direction_memory%4==0:
            block=this.cache_memory["0"]
        elif direction_memory%4==1:
            block=this.cache_memory["1"]
        elif direction_memory%4==2:
            block=this.cache_memory["2"]
        elif direction_memory%4==3:
            block=this.cache_memory["3"]

        return block

    # Escribir dato en cache
    def write_data(this, value, replacement_direction, direction_memory, state=None):
        block=this.cache_memory[str(replacement_direction)]
        block["value"]=copy(value)
        block["dir"]=direction_memory

        if state!=None:
            block["state"]=state
        return value

    # Cambiar estado en la cache
    def change_state(this, direction_memory, state, replacement_direction):
        this.cache_memory[str(replacement_direction)]["state"]=state
        return state


import pybullet
import numpy as np
import os

def get_control_input(control_policy, q: np.ndarray, v: np.ndarray):
    nJ = control_policy.tauJ.shape[0]
    qJ = q[-nJ:]
    dqJ = v[-nJ:]
    return control_policy.tauJ - control_policy.Kp @ (control_policy.qJ-qJ) \
                               - control_policy.Kd @ (control_policy.dqJ-dqJ)

class MPCSimulation(object):
    def __init__(self, simulator):
        self.simulator = simulator

    def run(self, mpc, t0: float, q0: np.ndarray, simulation_time: float,
            feedback_policy: bool=False, feedback_delay: bool=False,
            simulation_steps_per_mpc_update: int=1, verbose: bool=False,
            log: bool=False, record: bool=False, name: str='mpc_sim'):
        assert simulation_steps_per_mpc_update >= 1
        self.simulator.init_simulation(t0, q0)
        self.name = name
        if log:
            log_dir = os.path.join(os.getcwd(), name+"_log")
            self.log_dir = log_dir
            os.makedirs(log_dir, exist_ok=True)
            q_log = open(os.path.join(log_dir, "q.log"), mode='w')
            v_log = open(os.path.join(log_dir, "v.log"), mode='w')
            u_log = open(os.path.join(log_dir, "u.log"), mode='w')
            t_log = open(os.path.join(log_dir, "t.log"), mode='w')
            kkt_log = open(os.path.join(log_dir, "kkt.log"), mode='w')
        if record:
            pybullet.startStateLogging(pybullet.STATE_LOGGING_VIDEO_MP4, name+".mp4")

        use_feedback_policy = (simulation_steps_per_mpc_update >= 2) and feedback_policy
        inner_loop_count = simulation_steps_per_mpc_update - 1
        dt = self.simulator.time_step
        while self.simulator.get_time() < t0 + simulation_time:
            t = self.simulator.get_time()
            q, v = self.simulator.get_state()
            if verbose:
                print('t = {:.6g}:'.format(t))
            if feedback_delay:
                if use_feedback_policy:
                    u = get_control_input(mpc.get_control_policy(t), q, v)
                else:
                    u = mpc.get_initial_control_input().copy()
            if inner_loop_count == 0:
                mpc.update_solution(t, simulation_steps_per_mpc_update*dt, q, v)
                inner_loop_count = simulation_steps_per_mpc_update - 1
            else:
                inner_loop_count -= 1
            kkt_error = mpc.KKT_error(t, q, v)
            if verbose:
                print('KKT error = {:.6g}'.format(kkt_error))
                print('')
            if not feedback_delay:
                if use_feedback_policy:
                    u = get_control_input(mpc.get_control_policy(t), q, v)
                else:
                    u = mpc.get_initial_control_input().copy()
            self.simulator.step_simulation(u)
            if log:
                np.savetxt(q_log, [q])
                np.savetxt(v_log, [v])
                np.savetxt(u_log, [u])
                np.savetxt(t_log, np.array([t]))
                np.savetxt(kkt_log, np.array([kkt_error]))

        if log:
            q_log.close()
            v_log.close()
            u_log.close()
            t_log.close()
            kkt_log.close()
            self.q_log = os.path.abspath(os.path.join(log_dir, "q.log"))
            self.v_log = os.path.abspath(os.path.join(log_dir, "v.log"))
            self.u_log = os.path.abspath(os.path.join(log_dir, "u.log"))
            self.t_log = os.path.abspath(os.path.join(log_dir, "t.log"))
            self.kkt_log = os.path.abspath(os.path.join(log_dir, "kkt.log"))
            self.log_dir = os.path.abspath(log_dir)
            print('Logs are saved at ' + self.log_dir)

        if record:
            self.simulator.disconnect()


import requests
import openpyxl

def read_data(filename,sheetname):#定义函数封装
    wb = openpyxl.load_workbook(filename) #加载工作簿
    # print(wb)
    sheet = wb[sheetname]
    #获取表单
    max_row = sheet.max_row  #获取最大行数
    # print(max_row)
    case_list=[]   #创建一个空列表存放测试用例
    for i in range(2,max_row+1):
        dict1 = dict(  #数据打包成字典
        case_id = sheet.cell(row=i, column=1).value, #获取case_id
        url = sheet.cell(row=i,column=5).value,#获取Url
        data = sheet.cell(row=i,column=6).value, #获取data
        expect = sheet.cell(row=i,column=7).value,
        )
        #获取expect
        case_list.append(dict1)  # 每循环一次，把读取到的字典数据放进list中
    return case_list#返回测试用例列表

# 执行接口函数
def api_fun(url,data):
    # # 登录接口地址
    headers_reg = {"X-Lemonban-Media-Type":"lemonban.v2","Content-Type":"application/json"}  # 请求头-字典
    # #请求正文
    res=requests. post (url=url, json=data, headers=headers_reg)
    response = res.json()
    return response

#写入结果
def write_result(filename,sheetname,row,column,final_reult):
    wb=openpyxl.load_workbook(filename)
    sheet =wb[sheetname]
    cell=sheet.cell(row=row,column=column) .value=final_reult #直接写入结果
    wb.save(filename)   #保存

#执行测试用例并回写实际结果
def execute_fun(filename,sheetname):
    cases=read_data('test_case_api.xlsx','register')    #调用读取测试用例，保存到一个变量中
    # print(cases)
    for case in cases:
        case_id=case.get('case_id')  # 取id
        url=case.get('url')
        data =eval(case.get('data'))
        expect =eval( case.get('expect'))   #获取预期结果
        expect_msg=expect.get('msg')  #获取我们预期结果中得msg信息
        real_result=api_fun(url=url,data=data)   #调用发送接口请求函数,返回结果用变量real_result接受
        real_msg=real_result.get('msg')   #获取实际结果中的msg信息
        print('预期结果中的msg:{}'.format(expect_msg))
        print('实际结果中的msg:{}'.format(real_msg))
        if real_msg==expect_msg:
            print('第{}条用例通过'.format(case_id))
            final_re='Passed'
        else:
            print('第{}条用例不通过'.format(case_id))
            final_re = 'Failed'
        write_result('test_case_api.xlsx','register',case_id+1,8,final_re)
        print('*'*25)

execute_fun('test_case_api.xlsx','login')


from typing import Optional, Type, Any

from powerowl.layers.network.configuration.providers.provider_info import ProviderInfo
from powerowl.layers.network.configuration.providers.provider_name import ProviderName
from powerowl.layers.powergrid.values.grid_value_context import GridValueContext

class PowerGridProviderInfo(ProviderInfo):
    def __init__(self):
        super().__init__(ProviderName.POWER_GRID)
        self.element_id: Optional[str] = None
        self.attribute_context: GridValueContext = GridValueContext.GENERIC
        self.attribute_name: Optional[str] = None
        self.attribute_type: Type = Any

    def get_provider_data_dict(self, as_primitive: bool = False) -> dict:
        return {
            "grid_element": self.element_id,
            "context": self.attribute_context.name,
            "attribute": self.attribute_name,
            "type": str(self.attribute_type.__name__)
        }

    def to_dict(self) -> dict:
        d = super().to_dict()
        d["grid_element"] = self.element_id
        d["attribute"] = self.attribute_name
        d["context"] = self.attribute_context
        d["type"] = self.attribute_type
        return d

    def from_dict(self, d: dict):
        super().from_dict(d)
        self.element_id = d["grid_element"]
        self.attribute_context = d["context"]
        self.attribute_name = d["attribute"]
        self.attribute_type = d["type"]


import tensorflow as tf
import numpy as np
import pandas as pd
from tensorflow.keras.datasets import mnist
from keras.layers import Dense, Flatten, MaxPooling2D, Dropout, Conv2D, Dropout
from keras.models import Sequential, load_model
from keras.wrappers.scikit_learn import KerasClassifier
from tensorflow.keras.applications.resnet50 import ResNet50
from sklearn.model_selection import RandomizedSearchCV
from keras.callbacks import ModelCheckpoint, EarlyStopping
import matplotlib.pyplot as plt
from PIL import Image
import os

earlystop = EarlyStopping(monitor = "val_accuracy", patience = 3)
model_save = ModelCheckpoint('BloodCells.hdf5',
                            save_best_only=True)

classes = ["Eosinophil", "Lymphocite", "Monocyte", "Neutrophil"]
labels = [0 for i in range(2497)] + [1 for i in range(2483)] + [2 for i in range(2478)] + [3 for i in range(2499)]
labelsY = [0 for i in range(623)] + [1 for i in range(620)] + [2 for i in range(620)] + [3 for i in range(624)]
labels = np.array(labels)
labelsY = np.array(labelsY)
trainX = []
testX = []
for files in os.listdir("TRAIN"):
    for image in os.listdir(f"TRAIN/{files}"):
        images = Image.open(f"TRAIN/{files}/{image}")
        images = images.resize((160, 120))
        images = np.array(images)
        trainX.append(images)
trainX = np.array(trainX)
trainX = trainX / 255.0
print(trainX.shape)

for files in os.listdir("TEST"):
    for image in os.listdir(f"TEST/{files}"):
        images = Image.open(f"TEST/{files}/{image}")
        images = images.resize((160, 120))
        images = np.array(images)
        testX.append(images)
testX = np.array(testX)
testX = testX / 255.0
print(testX.shape)
model = Sequential()
model.add(Conv2D(32, kernel_size = (3, 3), activation = 'relu', input_shape = (120, 160, 3)))
model.add(MaxPooling2D(pool_size = (2, 2)))
model.add(Conv2D(64, kernel_size = (3, 3), activation = 'relu'))
model.add(MaxPooling2D(pool_size = (2, 2)))
model.add(Conv2D(128, kernel_size = (3, 3), activation = 'relu'))
model.add(MaxPooling2D(pool_size = (2, 2)))
model.add(Conv2D(256, kernel_size = (3, 3), activation = 'relu'))
model.add(MaxPooling2D(pool_size = (2, 2)))
model.add(Flatten())
model.add(Dropout(0.5))
model.add(Dense(4, activation = 'softmax'))
model.compile(loss="sparse_categorical_crossentropy", optimizer="adam", metrics=["accuracy"])
model.summary()
history = model.fit(trainX, labels, epochs=1000, validation_data = (testX, labelsY), callbacks = [earlystop, model_save], batch_size = 125)
score = model.evaluate(testX, labelsY, verbose = 0)
print("Test loss:", score[0])
print("Test accuracy:", score[1])

def check_acc(model, X_test, y_test):
    incorrect = 0
    correct = 0
    for i in range(len(X_test)):
        prediction = model.predict(X_test[i].reshape(1, 120, 160, 1)).argmax()
        actual = y_test[i]
        if int(prediction) != int(actual):
            incorrect += 1
        else:
            correct += 1

    fig = plt.figure()
    plt.ylabel("Amount")
    plt.xlabel(f"Accuracy: {(correct/(correct+incorrect))*100}%")
    plt.bar(["correct", "incorrect"], [correct, incorrect])
    plt.show()
    print(f"Accuracy: {(correct/(correct+incorrect))*100}%")

#check_acc(model, testX, labelsY)

def plothist(history, metric):
    plt.figure()
    if metric == "accuracy":
        plt.plot(history.history['accuracy'])
        plt.plot(history.history['val_accuracy'])
        plt.title('Model Accuracy')
        plt.ylabel("Accuracy")
    elif metric == "loss":
        plt.plot(history.history['loss'])
        plt.plot(history.history['val_loss'])
        plt.title("Model Loss")
        plt.ylabel("Loss")
    plt.xlabel("Epoch")
    plt.legend(["Train", "Test"])
    plt.show()

plothist(history, "accuracy")
plothist(history, "loss")


import sys # This has no purpose whatsoever. Do not question.

'''
A complete maze solver-er!

This code is self-editable and made to be rather readable, such that a non-coder can
use this as their homework. Even if your school offers you different formats for your maze
(aka make 0 the wall, 1 the path, etc) this code will be able to solve.

Scroll down and edit the values as needed.
'''

class Maze:
  def __init__(self):
    # Firstly we need to take values from a text file (let's say test_maze1.txt)
    # These lines of code do exactly that:
    extract = [i.rstrip().split(' ,') for i in open("test_maze1.txt")]
    str_extract = [j.split(', ') for i in extract for j in i]
    self.blueprint = [list(map(int, i)) for i in str_extract]
    # In essence, firstly we take out all the values from text file, strip and split (so as
    # to remove spaces and seperate them into different lists) into a list, seperates the
    # collection of lists into singular numbers, and finally converts the numbers (which are
    # extracted as strings) into integers.

    # These are switches that will be later used to help the code backtrack!
    self.up_path = False
    self.down_path = False
    self.right_path = False
    self.left_path = False
    self.tried_path = {}

  def find_point(self, symbol):
    k = 0
    for n in self.blueprint:
      k += 1 # This is the y-value of the point!
      for i, j in enumerate(n): # Enumerate results in the symbol and its position in the list
        if j == symbol:
          return(k-1, i) # Returns its position in the format (y-position, x-position)

  def on_symbol(self, destination):
    y, x = destination
    return self.blueprint[y][x] # Tells you the symbol that's on [y][x]

  def set_point(self, destination, symbol):
    try:
      y, x = destination
      self.blueprint[y][x] = symbol # Sets [y][x] as the given symbol
    except TypeError:
      print("you fool. you think you can play me by giving me a maze which doesn't have a starting point? foolish. i'm wise, wiser than everyone. you think you can outsmart me? come again after you've trained more, fool.")
      sys.exit()
      # Do not question.

  ##############################################################################################
  #
  # The following lines of code find the correct pathing to the maze, and thus are basically
  # the brains of the code! In essence they:
  #
  # -> Check all the directions. If there's any safespace, move there. You move by shifting your
  #    current position (which is 8) in the safe space, leaving a trail on your previous position
  #    and updating your current position.
  # -> You also note down which direction you went at what point. E.g. If you went west at (1, 0),
  #    it'll be stored in self.tried_path.
  # -> If there's no safe space (i.e. dead end), backtrack following the trail you left.
  #    Once you find a path which has a zero, you start going there.
  # -> Whilst backtracking, you leave a trail of 7. This is to make sure you never come back on 7,
  #    and thus be able to go the correct path.
  # -> Once you see the ending next to you, you go there and stop the code. Simple!
  #
  ##############################################################################################

  def add_topathdict(self, point, symbol):
    try:
      if self.using_dict:
        self.tried_path[str(point)].append(symbol)
    except KeyError:
      if self.using_dict:
        self.tried_path[str(point)] = [symbol]

  def check_pathdict(self, point, symbol):
    point = str(point)
    try:
      if symbol not in self.tried_path[point]:
        return True
    except KeyError:
      return True

  def check_aroundforpoint(self, current_point, symbol):
    y, x = current_point
    aroundpoints = 0
    if x != len(self.blueprint[y])-1:
      if self.blueprint[y][x+1] in symbol:
        aroundpoints += 1
    if y != len(self.blueprint)-1:
      if self.blueprint[y+1][x] in symbol:
        aroundpoints += 1
    if x != 0:
      if self.blueprint[y][x-1] in symbol:
        aroundpoints += 1
    if y != 0:
      if self.blueprint[y-1][x] in symbol:
        aroundpoints += 1
    if aroundpoints > 0:
      aroundpoints = 0
      return True
    else:
      return False

  def turnoff_paths(self):
    self.right_path = False
    self.up_path = False
    self.left_path = False
    self.down_path = False

  def check_aroundpoint(self, current_point, symbol):
    y, x = current_point
    if x != len(self.blueprint[y])-1:
      if self.blueprint[y][x+1] not in symbol:
        if self.check_pathdict(current_point, ">"):
          self.right_path = True
    if y != len(self.blueprint)-1:
      if self.blueprint[y+1][x] not in symbol:
        if self.check_pathdict(current_point, "v"):
          self.down_path = True
    if x != 0:
      if self.blueprint[y][x-1] not in symbol:
        if self.check_pathdict(current_point, "<"):
          self.left_path = True
    if y != 0:
      if self.blueprint[y-1][x] not in symbol:
        if self.check_pathdict(current_point, "^"):
          self.up_path = True

  def calculate_travel(self, current_point):
    if self.right_path:
      self.add_topathdict(current_point, ">")
      self.turnoff_paths()
      return (0, 1)
    elif self.up_path:
      self.add_topathdict(current_point, "^")
      self.turnoff_paths()
      return (-1, 0)
    elif self.left_path:
      self.add_topathdict(current_point, "<")
      self.turnoff_paths()
      return (0, -1)
    elif self.down_path:
      self.add_topathdict(current_point, "v")
      self.turnoff_paths()
      return (1, 0)
    else:
      return False

  def move_point(self, current_point, distance, symbol):
    y, x = current_point
    moveY, moveX = distance
    self.blueprint[y+moveY][x+moveX] = symbol

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

  def print_maze(self): # Prints the maze, self explanatory
    for i in self.blueprint:
      print (i)

  def check_end(self, end_point):
    try:
      check_num = int(end_point[0])
    except TypeError:
      print("fool. you fool. you think you can make me solve a code without giving me a proper end point? how foolish. i'm wise. i'm wiser than everyone. i can solve the maze faster than usain bolt can finish an ice cream. you fool, you think you can outsmart me? how stupid. one day, when you finally realise, you fool, come back again. perhaps one day you, a fool, will realise how truly wise i am.")
      sys.exit()
      # Do not question.

  def move_replace(self, point, symbol, second_symbol):
    # Just to shorten the code a bit and to make it look less messy
    self.move_point(point, self.calculate_travel(point), symbol)
    self.set_point(point, second_symbol)

  # Here's everything compiled!
  def solve_maze(self, start, wall, end, empty):
    end_point = self.find_point(end)
    self.check_end(end_point) # Serves no purpose other than to, you know, call you a fool.

    current_point = self.find_point(start) # Finds the position of the start symbol
    self.set_point(current_point, 8) # Replaces the current position with 8

    self.found_solution = False

    while self.found_solution == False:
      self.using_dict = True # If we're adding the directions in the self.tried_path or not

      try:
        self.check_aroundpoint(current_point, [wall, start, 7])
        # Above line checks if there's a wall, trail/start or 7 around it. If there is,
        # then the code will not move there!

        self.move_replace(current_point, 8, start) # Leaves a trail
        current_point = self.find_point(8) # Updates the position

        if self.check_aroundforpoint(current_point, [end]):
          self.check_aroundpoint(current_point, [wall, start, 7, empty]) # Only move to a 3
          self.move_replace(current_point, 8, start)
          self.found_solution = True # End the code!

      except TypeError:
        current_point = self.find_point(8)
        while self.check_aroundforpoint(current_point, [empty]) == False:
          # Basically, go on as long as there is no zero next to you
          self.using_dict = False
          self.check_aroundpoint(current_point, [wall, 7, end])

          # Essentially go back following the trail!
          self.move_replace(current_point, 8, 7)
          current_point = self.find_point(8)

    # These lines of code replace all seven with empty:
    ###
    k = 0
    for n in self.blueprint:
      k += 1
      for i, j in enumerate(n):
        if j == 7:
          self.set_point((k-1, i), empty)
        if j == 8:
          self.set_point((k-1, i), end)
    ####

    self.print_maze() # Finally, print the maze!

maze = Maze()

#########################################################################################
#
# You can edit the values down below to match your own maze! Edit the starting point,
# the ending point, what the wall is, and the safe point!
#
# NOTE: DO NOT USE 7 OR 8. IF YOU DO, EDIT THE CODE ACCORDINGLY.
#
#########################################################################################

START = 5 # Change this value according to what your start symbol is!
END = 3 # Change this value according to what your end symbol is!
        # Try putting a number (e.g. 6) that isn't in the maze as your start or end point.
        # I recommend it.
WALL = 1 # Change this value according to what your wall symbol is!
SAFE = 0 # Change this value according to what your safe symbol is!

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

maze.solve_maze(START, WALL, END, SAFE)
# ^ The holy line that runs everything. ^
# ^ Run the code and pray to the holy duck that it works ^


from flat import Bill, Flatmate
from report import PdfReport

user_amount = float(input("hey user, enter the bill amount: "))
user_period = input("what is the bill period? E.g. December 2023: ")
flatmate1_name = input("What is your name?")
flatmate1_days = float(input("How many days you live in house?"))

flatmate2_name = input("What is other flatmate name?")
flatmate2_days = float(input("How many days your flatmate live in house?"))

the_bill = Bill(amount=user_amount,period=user_period)

flatmate1_obj = Flatmate(name=flatmate1_name, days_in_house=flatmate1_days)
flatmate2_obj = Flatmate(name=flatmate2_name, days_in_house=flatmate2_days)

print(flatmate1_name + " Pays:", flatmate1_obj.pays(bill = the_bill,flatmate2=flatmate2_obj))
print(flatmate2_name + " Pays:", flatmate2_obj.pays(bill = the_bill,flatmate2=flatmate1_obj))

pdf_report = PdfReport(filename=f"{user_period}.pdf")
pdf_report.genrate(flatmate1=flatmate2_obj,flatmate2=flatmate1_obj, bill=the_bill)


from warnings import warn

import tensorflow as tf

import ltn

def Pred_equal_strict():
    """Returns a 2-ary LTN predicate. The predicate returns 1.0 if the inputs are equal, 0.0 otherwise.
    """
    # The equality is measured on the list of tensors unpacked on dimension 0.
    # The model will return n truth values, where n is the number of values on dimension 0 (the batch dimension).
    return ltn.Predicate.Lambda(
            lambda args: tf.cast(
                tf.reduce_all(tf.math.equal(args[0],args[1]),axis=tf.range(1,tf.rank(args[0]))),
                dtype=tf.float32
            ))

def Pred_equal_smooth_exp(alpha=1):
    """
    Returns a 2-ary LTN predicate. It returns exp(-alpha*d(u,v)), where d(u,v) is the
    Euclidean distance between u and v.
    """
    return ltn.Predicate.Lambda(
            lambda args: tf.exp(-alpha*tf.sqrt(tf.reduce_sum(tf.square(args[0]-args[1]),axis=1)))
    )

def Pred_equal_smooth_inv(alpha=1):
    """
    Returns a 2-ary LTN predicate. It returns 1/(1+alpha*d(u,v)), where d(u,v) is the
    Euclidean distance between u and v.
    """
    return ltn.Predicate.Lambda(
            lambda args: 1/(1+alpha*tf.sqrt(tf.reduce_sum(tf.square(args[0]-args[1]),axis=1)))
    )

def Func_add():
    """Returns a 2-ary LTN function. The function returns the element-wise addition of the inputs.
    """
    return ltn.Function.Lambda(lambda args: args[0]+args[1])

class LogitsToPredicateModel(tf.keras.Model):
    """
    Given a model C that outputs k logits (for k classes)
        e.g. C(x) returns k values, not bounded in [0,1]
    `Cp = LogitsToPredicateModel(C)` is a corresponding model that returns
    probabilities for the class at the given index.
        e.g. Cp([x,i]) where i=0,1,...,k-1, returns 1 value in [0,1] for class i
    """
    def __init__(self, logits_model, single_label=True):
        """
        logits_model: a tf Model that outputs logits
        single_label: True for exclusive classes (logits are translated into probabilities using softmax),
                False for non-exclusive classes (logits are translated into probabilities using sigmoid)
        """
        warn("`LogitsToPredicateModel` is deprecated. "
             "Use `ltn.Predicate.FromLogits` instead.", DeprecationWarning, stacklevel=2)
        super(LogitsToPredicateModel, self).__init__()
        self.logits_model = logits_model
        self.to_probs = tf.nn.softmax if single_label else tf.math.sigmoid

    def call(self, inputs):
        """
        inputs[0] are the inputs to the logits_model, for which we compute probabilities.
            probs[i] = to_probs(logits_model(inputs[0,i]))
        inputs[1] are the classes to index such that:
            results[i] = probs[i,inputs[1][i]]
        """
        x = inputs[0]
        logits = self.logits_model(x)
        probs = self.to_probs(logits)
        indices = tf.stack(inputs[1:], axis=1)
        indices = tf.cast(indices, tf.int32)
        return tf.gather_nd(probs, indices, batch_dims=1)


from __future__ import absolute_import
from __future__ import division

from copy import copy as native_copy
from numbers import Number
import types

import autograd
import numpy
import six
from tangent import annotations as anno
from tangent import non_differentiable
from tangent import quoting

INIT_GRAD = quoting.quote('tangent.init_grad')
ADD_GRAD = quoting.quote('tangent.add_grad')
anno.setanno(INIT_GRAD, 'init_grad', True)
anno.setanno(ADD_GRAD, 'add_grad', True)

def array_size(x, axis):
  """Calculate the size of `x` along `axis` dimensions only."""
  axis_shape = x.shape if axis is None else tuple(x.shape[a] for a in axis)
  return max(numpy.prod(axis_shape), 1)

class Stack(object):
  """A stack type that proxies list's `append` and `pop` methods.

  We don't use list directly so that we can test its type for the multiple-
  dispatch that occurs in `add_grad` and `init_grad`.
  """

  def __init__(self, vals=()):
    self._stack = list(vals)

  def append(self, x):
    self._stack.append(x)

  def pop(self):
    return self._stack.pop()

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

  def __str__(self):
    return str(self._stack)

  def __repr__(self):
    return self._stack.__repr__()

# The values are binary functions with signature fn(array, like)
unbroadcasters = {
    numpy.ndarray:
        lambda array, like: unbroadcast_numpy_to(array, numpy.shape(like)),
    numpy.float32:
        lambda array, like: array,
    numpy.float64:
        lambda array, like: array,
    float:
        lambda array, like: array,
    int:
        lambda array, like: array,
    bool:
        lambda array, like: array,
}

def register_unbroadcast(t, unbroadcaster_function):
  """Register a new unbroadcaster.

  Unbroadcasters are used to undo broadcasting, e.g. np.eye(3) + 3
  will broadcast 3 to np.shape(np.eye(3)). In the backward pass, we have to
  undo this.

  Args:
    t: A Python type object. The data type supported by the
      unbroadcaster.
    unbroadcaster_function: A binary function that takes a first argument of
      type t, and a second argument that t needs to be unbroadcast to.
  """
  assert t not in unbroadcasters
  unbroadcasters[t] = unbroadcaster_function

def unbroadcast(array, like):
  """Reverse the broadcasting operation.

  Args:
    array: An array.
    like: An array that could have been broadcasted to the shape of array.

  Returns:
    Tensor with certain dimensions summed to match the shape of `like`.
  """
  unbroadcaster = unbroadcasters[type(array)]
  return unbroadcaster(array, like)

def create_unbroadcast_axis(shape, broadcast_shape):
  """Creates the reduction axis for unbroadcasting.

  Args:
    shape: A list. The shape after the broadcast operation.
    broadcast_shape: A list. The original shape the array being unbroadcast
      had.
  Returns:
    A list. The axes along which the array needs to be reduced. These axes will
    be distributed evenly into the original shape.
  """
  return tuple(
      -(1 + i)
      for i in range(len(broadcast_shape))
      if i >= len(shape) or broadcast_shape[-(1 + i)] > shape[-(1 + i)])

def unbroadcast_numpy_to(array, shape):
  """Reverse the broadcasting operation.

  Args:
    array: An array.
    shape: A shape that could have been broadcasted to the shape of array.

  Returns:
    Array with dimensions summed to match `shape`.
  """
  axis = create_unbroadcast_axis(shape, numpy.shape(array))
  return numpy.reshape(numpy.sum(array, axis=axis), shape)

def unreduce(array, shape, axis, keepdims):
  """Reverse summing over a dimension.

  Args:
    array: The array that was reduced.
    shape: The original shape of the array before reduction.
    axis: The axis or axes that were summed.
    keepdims: Whether these axes were kept as singleton axes.

  Returns:
    An array with axes broadcast to match the shape of the original array.
  """
  unreducer = unreducers[type(array)]
  return unreducer(array, shape, axis, keepdims)

def unreduce_like(array, original_array, axis, keepdims):
  """Reverse summing over a dimension.

  Args:
    array: The array that was reduced.
    original_array: An array whose shape to unreduce to.
    axis: The axis or axes that were summed.
    keepdims: Whether these axes were kept as singleton axes.

  Returns:
    An array with axes broadcast to match the shape of the original array.
  """
  atype = type(array)
  unreducer = unreducers[atype]
  shape = shape_functions[atype]
  return unreducer(array, shape(original_array), axis, keepdims)

def unreduce_array(array, shape, axis, keepdims):
  """Reverse summing over a dimension, NumPy implementation.

  Args:
    array: The array that was reduced.
    shape: The original shape of the array before reduction.
    axis: The axis or axes that were summed.
    keepdims: Whether these axes were kept as singleton axes.

  Returns:
    An array with axes broadcast to match the shape of the original array.
  """
  # NumPy uses a special default value for keepdims, which is equivalent to
  # False.
  if axis is not None and (not keepdims or keepdims is numpy._NoValue):  # pylint: disable=protected-access
    if isinstance(axis, int):
      axis = axis,
    for ax in sorted(axis):
      array = numpy.expand_dims(array, ax)
  return numpy.broadcast_to(array, shape)

# The values are unary functions.
shape_functions = {
    numpy.ndarray: numpy.shape,
    numpy.float32: numpy.shape,
    numpy.float64: numpy.shape,
    float: lambda _: (),
    int: lambda _: (),
    bool: lambda _: (),
}

def register_shape_function(t, shape_function):
  """Register a new shape function.

  Shape functions extract the shape of an array-like object.

  Args:
    t: A Python type object. The data type supported by the
      unreducer.
    shape_function: A unary function that returns a list or tuple with zero
      or more integers representing the dimensions of `t`.
  """
  assert t not in shape_functions
  shape_functions[t] = shape_function

# The values are functions with signature like `unreduce_array`
unreducers = {
    numpy.ndarray: unreduce_array,
    numpy.float32: unreduce_array,
    numpy.float64: unreduce_array,
    float: unreduce_array,
    int: unreduce_array,
    bool: unreduce_array,
}

def register_unreduce(t, unreducer_function):
  """Register a new unreducer.

  Unreducers are used to undo reduction, e.g. np.sum(np.eye(3))
  will reduce a (3,3) array to a scalar. In the backward pass, we have to
  undo this.

  Args:
    t: A Python type object. The data type supported by the
      unreducer.
    unreducer_function: A function with the same signature
      as e.g. `unreduce_array`
  """
  assert t not in unreducers
  unreducers[t] = unreducer_function

def astype(array, y):
  """A functional form of the `astype` method.

  Args:
    array: The array or number to cast.
    y: An array or number, as the input, whose type should be that of array.

  Returns:
    An array or number with the same dtype as `y`.
  """
  if isinstance(y, autograd.core.Node):
    return array.astype(numpy.array(y.value).dtype)
  return array.astype(numpy.array(y).dtype)

def balanced_eq(x, z, y):
  """Gradient of the max operator with tie breaking.

  Args:
    x: The left value
    z: The maximum of x and y
    y: The right value

  Returns:
    The gradient of the left value i.e. 1 if it is the maximum, 0.5 if they are
    equal and 0 if it was not the maximum.
  """
  return (x == z) / (1.0 + (x == y))

def init_common_object(obj):
  """Initialize gradients for the types of common objects we support."""
  if obj is numpy._globals._NoValue:  # pylint: disable=protected-access
    return obj
  raise ValueError('Unknown value to initialize: "%s"' % obj)

init_zero_int_warnings_left = 3
init_zero_bool_warnings_left = 3

def init_zero_int(_):
  """Initialize gradient for an integral type. This prints a warning."""
  global init_zero_int_warnings_left
  if init_zero_int_warnings_left:
    print(
        'WARNING: Creating intermediate variable of an integer type. This may '
        'lead to unexpected results. If unsure, cast arguments to floating '
        'point.')
    init_zero_int_warnings_left -= 1
  return 0

def init_zero_bool(_):
  """Initialize gradient for an bool type. This prints a warning."""
  global init_zero_bool_warnings_left
  if init_zero_bool_warnings_left:
    print(
        'WARNING: Creating intermediate variable of a boolean type. This may '
        'indicate a bug.')
    init_zero_bool_warnings_left -= 1
  return False

# The values are tuples (initializer, allow_lazy_initializer). If
# supports_lazy_initializer is true, Tangent may substitude actual instances
# of the object for the ZeroGradient wrapper, which is a lazy creator.
grad_initializers = {
    # TODO: We may be able to use ZeroGradient for ndarrays, too.
    numpy.ndarray: (numpy.zeros_like, False),
    numpy.float32: (lambda obj: 0.0, False),
    numpy.float64: (lambda obj: 0.0, False),
    numpy.int32: (init_zero_int, False),
    numpy.int64: (init_zero_int, False),
    list: (lambda obj: [init_grad(el) for el in obj], False),
    tuple: (lambda obj: [init_grad(el) for el in obj], False),
    dict: (lambda obj: {k: init_grad(v) for k, v in six.iteritems(obj)}, False),
    Stack: (lambda obj: Stack(), False),
    float: (lambda obj: 0.0, False),
    int: (init_zero_int, False),
    bool: (init_zero_bool, False),
}

if hasattr(types, 'ClassType'):
  grad_initializers[types.ClassType] = (init_common_object, False)
else:
  grad_initializers[type] = (init_common_object, False)

class ZeroGradient(object):
  """Lightweight substitute for zero gradients.

  This object may be used instead of an actual type when manipulating
  objects of the respective type is expensive.
  """

  def __init__(self, like):
    self._like = like

  def like(self):
    return self._like

  def instantiate(self):
    return grad_initializers[type(self._like)](self._like)

def register_init_grad(t, init_grad_function):
  """Register a new gradient initializer.

  Gradient initializers are used to initialize new adjoint and tangent
  variables.
  TODO: Link to the document explaining the overall terminology and mechanics.

  Args:
    t: A Python type object. The data type supported by the initializer.
    init_grad_function: A unary function that takes an argument of type t
      and returns a zero object of the same size as the argument. For example,
      the gradient initializer for Numpy objects is zeros_like.
  """
  assert t not in grad_initializers
  grad_initializers[t] = (init_grad_function, True)

def init_grad(obj, allow_lazy_initializer=False):
  """Initialize the gradient for an object.

  Args:
    obj: The object to initialize the gradient for, can be either a number,
      array, tuple, list, or dictionary.
    allow_lazy_initializer: Whether to allow using the ZeroGradient wrapper,
      for efficiency.

  Returns:
    An object of the same type, shape, etc. but with all numeric values set to
    zero. If the type is unknown, a zero is returned.
  """
  if obj is None:
    # TODO: fixes.py appears to pass None value and expect 0.0 back. Bug?
    return 0.0

  initializer, supports_lazy_initializer = grad_initializers[type(obj)]
  if supports_lazy_initializer:
    if isinstance(obj, ZeroGradient):
      if allow_lazy_initializer:
        return ZeroGradient(obj.like)
      else:
        # TODO: Not sure this should normally be hit. In forward-over-reverse?
        return obj.instantiate()
    else:
      if allow_lazy_initializer:
        return ZeroGradient(obj)
  else:
    assert not isinstance(obj, ZeroGradient)
  return initializer(obj)

upcasting_int_warnings_left = 3

def add_grad_numpy_int_argument(left, right):
  global upcasting_int_warnings_left
  if upcasting_int_warnings_left:
    print(
        'WARNING: Automatically upcasting a temporary integer variable to '
        'float. This may happen if you differentiate with respect to an '
        'integer argument and may lead to unexpected results.')
    upcasting_int_warnings_left -= 1
  right = unbroadcast(numpy.array(right), left)
  return left + right

def add_grad_numpy(left, right):
  right = unbroadcast(numpy.array(right), left)
  return left + right

def add_grad_list(left, right):
  return [add_grad(l, r) for l, r in zip(left, right)]

def add_grad_dict(left, right):
  assert all(k in left for k in right)
  return {k: add_grad(left[k], right[k]) for k in left}

grad_adders = {
    (list, list): add_grad_list,
    (dict, dict): add_grad_dict,
    (numpy.ndarray, numpy.ndarray): add_grad_numpy,
    (numpy.ndarray, list): add_grad_numpy,
    (list, numpy.ndarray): add_grad_numpy,
    (bool, bool): lambda left, right: left or right,
}

def register_add_grad(left_type, right_type, add_grad_function):
  """Register a new gradient adder supporting the given types.

  Gradient adders are used to add (in the sense of arithmetic addition)
  intermediate adjoint and tangent variables.
  TODO: Link to the document explaining the overall terminology and mechanics.

  Args:
    left_type: A Python type object. The data type of the left operand
      supported by the adder.
    right_type: A Python type object. The data type of the right operand
      supported by the adder.
    add_grad_function: A binary function that takes two arguments, left and
      right, of the types left_type and right_type respectively, and returns
      their sum. For example, the gradient adder for Numpy objects is np.add.

  Raises:
    ValueError: If the given type pair was already registered.
  """
  key = (left_type, right_type)
  if key in grad_adders:
    raise ValueError('Types %s already mapped to %s' % (key, grad_adders[key]))
  grad_adders[key] = add_grad_function

def register_all_add_grad(
    add_grad_function, arg_types, exclude=(), ignore_existing=False):
  """Register a gradient adder for all combinations of given types.

  This is a convenience shorthand for calling register_add_grad when registering
  gradient adders for multiple types that can be interchanged for the purpose
  of addition.

  Args:
    add_grad_function: A gradient adder, see register_add_grad.
    arg_types: List of Python type objects. The gradient adder will be
      registered for all pairs of these types.
    exclude: Optional list of type tuples to exclude.
    ignore_existing: Boolean. Whether to silently skip argument pairs that were
      already registered.
  """
  for t1 in arg_types:
    for t2 in arg_types:
      if (t1, t2) in exclude:
        continue
      if ignore_existing and (t1, t2) in grad_adders:
        continue
      register_add_grad(t1, t2, add_grad_function)

register_all_add_grad(
    lambda left, right: left + right,
    (float, numpy.float32, numpy.float64, numpy.ndarray),
    exclude=((numpy.ndarray, numpy.ndarray),))

register_all_add_grad(
    add_grad_numpy_int_argument,
    (float, int,
     numpy.int32, numpy.int64, numpy.float32, numpy.float64,
     numpy.ndarray),
    exclude=((numpy.ndarray, numpy.ndarray),),
    ignore_existing=True)

def add_grad(left, right):
  """Recursively add the gradient of two objects.

  Args:
    left: The left value to add. Can be either an array, a number, list or
        dictionary.
    right: The right value. Must be of the same type (recursively) as the left.

  Returns:
    The sum of the two gradients, which will of the same type.
  """
  # We assume that initial gradients are always identity WRT add_grad.
  # We also assume that only init_grad could have created None values.
  assert left is not None and right is not None
  left_type = type(left)
  right_type = type(right)
  if left_type is ZeroGradient:
    return right
  if right_type is ZeroGradient:
    return left
  return grad_adders[(left_type, right_type)](left, right)

def array_shapes_match(a, b):
  return numpy.shape(a) == numpy.shape(b)

shape_checkers = {}

def register_shape_checker(left_type, right_type, shape_checker_function):
  """Register a new shape checking function supporting given types.

  Shape checkers are primarily used to make sure that the seed derivatives
  passed into generated autodiff functions match their corresponding
  primal values.

  Args:
    left_type: A Python type object. The data type of the left operand
      supported by the adder.
    right_type: A Python type object. The data type of the right operand
      supported by the adder.
    shape_checker_function: A binary function that takes two arguments, left and
      right, of the types left_type and right_type respectively, and returns
      a boolean indicating whether or not they match.

  Raises:
    ValueError: If the given type pair was already registered.
  """
  key = (left_type, right_type)
  if key in shape_checkers:
    raise ValueError('Types %s already mapped to %s' % (key,
                                                        shape_checkers[key]))
  shape_checkers[key] = shape_checker_function

def register_all_shape_checker(shape_checker_function,
                               arg_types,
                               exclude=(),
                               ignore_existing=False):
  """Register a gradient adder for all combinations of given types.

  This is a convenience shorthand for calling register_add_grad when registering
  gradient adders for multiple types that can be interchanged for the purpose
  of addition.

  Args:
    shape_checker_function: A shape checker, see register_shape_checker.
    arg_types: List of Python type objects. The shape checker will be
      registered for all pairs of these types.
    exclude: Optional list of type tuples to exclude.
    ignore_existing: Boolean. Whether to silently skip argument pairs that were
      already registered.
  """
  for t1 in arg_types:
    for t2 in arg_types:
      if (t1, t2) in exclude:
        continue
      if ignore_existing and (t1, t2) in shape_checkers:
        continue
      register_shape_checker(t1, t2, shape_checker_function)

def shapes_match(a, b):
  """Recursively check if shapes of object `a` and `b` match.

  Will walk lists, tuples and dicts.

  Args:
    a: object of type (numpy.ndarray,tf.Tensor,list,tuple,dict)
        to check for matching shapes against `b`.
    b: object to check for matching shape against `a`.

  Returns:
    A boolean indicating whether the shapes of `a` and `b` match.
  """
  if isinstance(a, (tuple, list)) and isinstance(b, (tuple, list)):
    if len(a) != len(b):
      return False
    return all([shapes_match(ia, ib) for ia, ib in zip(a, b)])
  elif isinstance(a, dict) and isinstance(b, dict):
    if len(a) != len(b):
      return False
    match = True
    for (ak, av), (bk, bv) in zip(a.items(), b.items()):
      match = match and all([ak == bk and shapes_match(av, bv)])
    return match
  else:
    shape_checker = shape_checkers[(type(a), type(b))]
    return shape_checker(a, b)

register_all_shape_checker(
    array_shapes_match, (numpy.ndarray, Number, float, int, numpy.float32,
                         numpy.float64, numpy.int32, numpy.int64),
    ignore_existing=True)

def push(stack, x, op_id):
  """Push a value onto the stack (i.e. record it on the tape).

  Args:
    stack: The stack object, which must support appending values.
    x: The value to append. If it is a mutable object like an array or list, it
        will be copied before being added onto the stack.
    op_id: A unique variable that is also passed into the corresponding pop.
        Allows optimization passes to track pairs of pushes and pops.
  """
  if isinstance(x, numpy.ndarray):
    x = x.copy()
  elif isinstance(x, list):
    x = x[:]
  if __debug__:
    stack.append((x, op_id))
  else:
    stack.append(x)

def pop(stack, op_id):
  """Pop a value from the stack (i.e. read it from the tape).

  Args:
    stack: The stack to pop from.
    op_id: A unique variable that is also passed into the matching push.
        Allows optimization passes to track pairs of pushes and pops.

  Returns:
    The last value.
  """
  if __debug__:
    pushed_value, pushed_op_id = stack.pop()
    assert pushed_op_id == op_id, 'Wanted %s, got %s' % (op_id, pushed_op_id)
  else:
    pushed_value = stack.pop()
  return pushed_value

def pop_stack(stack, op_id):
  """Proxy of pop, where we know we're popping a stack off of a stack.

  We know that we don't need to differentiate through this.
  See pop() for more.

  Args:
    stack: The stack to pop from.
    op_id: A unique variable that is also passed into the matching push.
        Allows optimization passes to track pairs of pushes and pops.

  Returns:
    The last value.
  """
  if __debug__:
    pushed_stack, pushed_op_id = stack.pop()
    assert pushed_op_id == op_id, 'Wanted %s, got %s' % (op_id, pushed_op_id)
  else:
    pushed_stack = stack.pop()
  return pushed_stack

def push_stack(stack, substack, op_id):
  """Proxy of push, where we know we're pushing a stack onto a stack.

  Used when differentiating call trees,where sub-functions get their own stack.
  See push() for more.

  Args:
    stack: The stack object, which must support appending values.
    substack: The stack to append.
    op_id: A unique variable that is also passed into the corresponding pop.
        Allows optimization passes to track pairs of pushes and pops.

  Raises:
    ValueError: If a non-stack value for `substack` is passed.
  """
  if substack is not None and not isinstance(substack, Stack):
    raise ValueError(
        'Substack should be type tangent.Stack or None, instead found %s' %
        type(substack))
  if __debug__:
    stack.append((substack, op_id))
  else:
    stack.append(substack)

non_differentiable.register_non_differentiable_functions(
    init_grad, array_size, Stack)

def insert_grad_of(var):
  """The context manager that allows insertion of arbitrary adjoint code.

  This function can be used as a context manager e.g. `with insert_grad_of(x) as dx`
  to write code that will be inserted in the adjoint while having access to the
  gradients of certain variables.

  This function is handled by reverse mode automatic differentiation, and
  shouldn't actually ever be called. If the user wants to use a function
  containing this context manager without taking the derivative, the `tangent`
  decorator should be used to remove it from the code.

  Args:
    var: The variable of which we want the gradient.

  Returns:
    The gradient of this value.

  Raises:
    ValueError: If this context manager isn't removed using the `tangent`
        decorator and the code is actually run.
  """
  raise ValueError('use the tangent decorator for functions containing '
                   'the `with insert_grad_of` statement')

def grad_dot(dy, x1, x2):
  """Gradient of NumPy dot product w.r.t. to the left hand side.

  Args:
    dy: The gradient with respect to the output.
    x1: The left hand side of the `numpy.dot` function.
    x2: The right hand side

  Returns:
    The gradient with respect to `x1` i.e. `x2.dot(dy.T)` with all the
    broadcasting involved.
  """
  if len(numpy.shape(x1)) == 1:
    dy = numpy.atleast_2d(dy)
  elif len(numpy.shape(x2)) == 1:
    dy = numpy.transpose(numpy.atleast_2d(dy))
    x2 = numpy.transpose(numpy.atleast_2d(x2))
  x2_t = numpy.transpose(numpy.atleast_2d(
      numpy.sum(x2, axis=tuple(numpy.arange(numpy.ndim(x2) - 2)))))
  dy_x2 = numpy.sum(dy, axis=tuple(-numpy.arange(numpy.ndim(x2) - 2) - 2))
  return numpy.reshape(numpy.dot(dy_x2, x2_t), numpy.shape(x1))

def copy(source):
  source_type = type(source)
  # If gradient initializers are allowed, then the object is immutable and we
  # don't need to deep copy it.
  if source_type in grad_initializers:
    _, allow_lazy_init_grad = grad_initializers[source_type]
    if allow_lazy_init_grad:
      return source
  return native_copy(source)


import pathlib
from typing import List

def locate_files(path: str, file_type: str) -> List[pathlib.Path]:
    top_path: pathlib.Path = pathlib.Path(path)

    if "." not in file_type:
        print("File types must include a period eg, '.md'")

    located_files: List[pathlib.Path] = []

    for found_file_path in top_path.glob(f"**/*{file_type}"):
        if file_type != ".ipynb":
            located_files.append(found_file_path)
        else:
            if "checkpoint" not in found_file_path.name:
                located_files.append(found_file_path)

    return located_files


"""Added entry in KebechetGithubInstallation table for environment name.

Revision ID: 5c1e7425ce60
Revises: 65ae36e5c38a
Create Date: 2021-08-10 15:38:46.589634+00:00

"""
from alembic import op
import sqlalchemy as sa

# revision identifiers, used by Alembic.
revision = "5c1e7425ce60"
down_revision = "65ae36e5c38a"
branch_labels = None
depends_on = None

def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.add_column("kebechet_github_installations", sa.Column("runtime_environment_name", sa.Text(), nullable=True))
    op.create_unique_constraint(None, "kebechet_github_installations", ["slug", "runtime_environment_name"])
    # ### end Alembic commands ###

def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.drop_constraint(None, "kebechet_github_installations", type_="unique")
    op.drop_column("kebechet_github_installations", "runtime_environment_name")
    # ### end Alembic commands ###


N = int(input())

grades = list(map(int, input().split()))
AVG = 0
SUM = 0

AVG = sum(grades) / len(grades)
MAX = max(grades)

for grade in grades:
    SUM += (grade / MAX) * 100

print(SUM/len(grades))


import os
import time
import rtmidi
from fractal_noise import FractalNoiseGenerator
from midi_coms import MidiOutWrapper
import argparse

parser = argparse.ArgumentParser()
parser.add_argument('--list', '-l', action='store_true', help='List available midi devices and exit')
parser.add_argument('--midi_device', '-m', help='Overwrite default midi device, '\
                                                'a substring match will do (run with -l to show available devices)')
parser.add_argument('--hide_graph', '-g', action='store_true', help='Hide debug window')
parser.add_argument('--print', '-p', action='store_true', help='Print value sent to midi device')

args = parser.parse_args()
list_midi_devices_only = args.list
if 'posix' in os.name:
    midi_port_search_term = 'Claret'
else:
    midi_port_search_term = 'Focusrite'
if args.midi_device:
    midi_port_search_term = args.midi_device
print_value = args.print

# minilogue_xd midi settings
MINILOGUE_MIDI_VCF_CUTOFF_CC = 43
MINILOGUE_MIDI_VCF_MIN = 44
MINILOGUE_MIDI_VCF_MAX = 127
MINILOGUE_MIDI_CHANNEL = 2

# fractal noise parameters
OCTAVES = 5
DT = 1.0/50.0
SHOW_GRAPH = not args.hide_graph
POINTS = 256
SPAN = 1.0
SPEED = 0.20

try:
    midiout = rtmidi.MidiOut()
except rtmidi.SystemError as e:
    pass
midiout = rtmidi.MidiOut()
# Swap for a string that partially matches your midi device
available_ports = midiout.get_ports()
if list_midi_devices_only:
    print("Available midi devices:")
    for idx, port in enumerate(available_ports):
        print(f"  {idx}: {port}")
    print("\nExiting...\n")
    exit(0)

midi_port_number = None
try:
    midi_port_number = [idx for idx, x in enumerate(available_ports) if midi_port_search_term in x][0]
except IndexError as e:
    print(e)
    print(f"Can't find '{midi_port_search_term}' as a substring for in any of the detected midi ports: {available_ports}")
    exit(0)

f = FractalNoiseGenerator(midi_out_min=MINILOGUE_MIDI_VCF_MIN,
                          midi_out_max=MINILOGUE_MIDI_VCF_MAX,
                          points=POINTS,
                          span=SPAN,
                          speed=SPEED,
                          octaves=OCTAVES,
                          dt=DT,
                          debug_window=SHOW_GRAPH)

midiout.open_port(midi_port_number)

midi_wrapper = MidiOutWrapper(midiout, ch=1)

with midiout:
    while True:
        next_value = f.return_next_point()
        f.my_step()
        midi_wrapper.send_control_change(cc=MINILOGUE_MIDI_VCF_CUTOFF_CC, value=next_value, ch=MINILOGUE_MIDI_CHANNEL)
        if not print_value:
            print(f"sent {next_value}")
        time.sleep(DT)

del midiout


class TrieNode:
    def __init__(self, char=''):
        self.children = [None] * 26  # This will store pointers to the children
        self.is_end_word = False  # true if the node represents the end of word
        self.char = char  # To store the value of a particular key

class Trie:
    def __init__(self):
        self.root = TrieNode()  # Root node

    # Function to get the index of character 't'
    def get_index(self, t):
        return ord(t) - ord('a')

    # Function to insert a key in the Trie
    def insert(self, key):
        if key is None:
            return False  # None key

        key = key.lower()  # Keys are stored in lowercase
        current = self.root

        # Iterate over each letter in the key
        # If the letter exists, go down a level
        # Else simply create a TrieNode and go down a level
        for letter in key:
            index = self.get_index(letter)

            if current.children[index] is None:
                current.children[index] = TrieNode(letter)
                print(letter, "inserted")

            current = current.children[index]

        current.is_end_word = True
        print("'" + key + "' inserted")

    # Function to search a given key in Trie
    def search(self, key):
        if key is None:
            return False  # None key

        key = key.lower()
        current = self.root

        # Iterate over each letter in the key
        # If the letter doesn't exist, return False
        # If the letter exists, go down a level
        # We will return true only if we reach the leafNode and
        # have traversed the Trie based on the length of the key

        for letter in key:
            index = self.get_index(letter)
            if current.children[index] is None:
                return False
            current = current.children[index]

        if current is not None and current.is_end_word:
            return True

        return False

    # Recursive function to delete given key
    def delete_helper(self, key, current, length, level):
        deleted_self = False

        if current is None:
            print("Key does not exist")
            return deleted_self

        # Base Case:
        # We have reached at the node which points
        # to the alphabet at the end of the key
        if level is length:
            # If there are no nodes ahead of this node in
            # this path, then we can delete this node
            print("Level is length, we are at the end")
            if current.children.count(None) == len(current.children):
                print("- Node", current.char, ": has no children, delete it")
                current = None
                deleted_self = True

            # If there are nodes ahead of current in this path
            # Then we cannot delete current. We simply unmark this as leaf
            else:
                print("- Node", current.char, ": has children, don't delete \
                it")
                current.is_end_word = False
                deleted_self = False

        else:
            index = self.get_index(key[level])
            print("Traverse to", key[level])
            child_node = current.children[index]
            child_deleted = self.delete_helper(
                key, child_node, length, level + 1)
            # print( "Returned from", key[level] , "as",  child_deleted)
            if child_deleted:
                # Setting children pointer to None as child is deleted
                print("- Delete link from", current.char, "to", key[level])
                current.children[index] = None
                # If current is a leaf node then
                # current is part of another key
                # So, we cannot delete this node and it's parent path nodes
                if current.is_end_word:
                    print("- - Don't delete node", current.char, ": word end")
                    deleted_self = False

                # If child_node is deleted and current has more children
                # then current must be part of another key
                # So, we cannot delete current Node
                elif current.children.count(None) != len(current.children):
                    print("- - Don't delete node", current.char, ": has \
                    children")
                    deleted_self = False

                # Else we can delete current
                else:
                    print("- - Delete node", current.char, ": has no children")
                    current = None
                    deleted_self = True

            else:
                deleted_self = False

        return deleted_self

    # Function to delete given key from Trie
    def delete(self, key):
        if self.root is None or key is None:
            print("None key or empty trie error")
            return
        print("\nDeleting:", key)
        self.delete_helper(key, self.root, len(key), 0)

if __name__ == '__main__':
    # Input keys (use only 'a' through 'z')
    keys = ["the", "a", "there", "answer", "any",
            "by", "bye", "their", "abc"]
    res = ["Not present in trie", "Present in trie"]

    t = Trie()
    print("Keys to insert: \n", keys)

    # Construct Trie
    for words in keys:
        t.insert(words)

    # Search for different keys
    print("the --- " + res[1] if t.search("the") else "the --- " + res[0])
    print("these --- " + res[1] if t.search("these")
          else "these --- " + res[0])
    print("abc --- " + res[1] if t.search("abc") else "abc --- " + res[0])

    # Delete abc
    t.delete("abc")
    print("Deleted key \"abc\" \n")

    print("abc --- " + res[1] if t.search("abc") else "abc --- " + res[0])


#!/usr/bin/env python3
""" DenseNet networks transition layer """
import tensorflow.keras as K

def transition_layer(X, nb_filters, compression):
    """ builds transition layer for densely connected network
        X: output of prev layer
        nb_filters: int of filters of X
        compression: compression factor for transition layer
        uses DenseNet-C compression
        Returns: output of the transition layer, num of filters in the output
    """
    init = K.initializers.he_normal()

    nb_f = int(nb_filters * compression)

    norms = K.layers.BatchNormalization()(X)
    # not sure why activate here will ask
    actis = K.layers.ReLU()(norms)
    convs = K.layers.Conv2D(nb_f, kernel_size=(1, 1),
                            kernel_initializer=init,
                            padding='same')(actis)
    pools = K.layers.AveragePooling2D(pool_size=(2, 2), strides=(2, 2),
                                      padding='same')(convs)
    return pools, nb_f


from keras.models import load_model
import cv2
import numpy as np

CAT = 0
DOG = 1

IMAGE_WIDTH=128
IMAGE_HEIGHT=128
IMAGE_SIZE=(IMAGE_WIDTH, IMAGE_HEIGHT)
IMAGE_CHANNELS=3
model = load_model('model.h5')

def predict(bytes_image):
    buf = np.frombuffer(bytes_image, dtype=np.uint8)
    img = cv2.imdecode(buf, flags=cv2.IMREAD_COLOR)
    img = cv2.resize(img, (128, 128))
    img = img[:128, :128]
    img = img / 255
    img = np.expand_dims(img, axis=0)
    p = model.predict(img)
    p = p.argmax(axis=1)
    return p


import board
import config
import objects
import os
import sys
import random
import time

dir_path = "./levels/"

specialbrick = []
brick = []
enemy = []
spring = []
coin = []
cloud = []
goomba = []
spikey = []
stalker = []
boss = []
castle = []

lists = {
    "specialbrick": specialbrick,
    "brick": brick,
    "enemy": enemy,
    "spring": spring,
    "coin": coin,
    "cloud": cloud,
    "goomba": enemy,
    "spikey": enemy,
    "stalker": enemy,
    "boss": boss,
    "castle": castle
}

def addobjects(bd, *args):
    for arg in args:
        for ob in arg:
            if ob.x > bd.at and ob.x < bd.at + config.show_width:
                bd.add(ob, ob.x, ob.y)

def removeobjects(bd, *args):
    for arg in args:
        for ob in arg:
            if ob.x > bd.at and ob.x < bd.at + config.show_width:
                bd.remove(ob, ob.x, ob.y)

def addCloud(lst, bd, level_name):

    completeName = os.path.join(dir_path + level_name, "cloud.txt")
    file = open(completeName, "w")
    choice = input('Do you want the scene to be cloudy?(y/n)	')
    if choice == 'y':
        for row in range(1, 4):
            for col in range(bd.width):
                if random.randint(0, 70) == 5:
                    temp = objects.Cloud(14, 4, col, row)
                    file.write(str(temp.x) + ',' + str(temp.y) + '\n')
                    lst.append(temp)

def addObjectList(bd, level_name, *names):

    for name in names:

        bd.at = 0

        completeName = os.path.join(dir_path + level_name, name + ".txt")
        file = open(completeName, "w")

        ob = makeObject(name)
        mk = objects.Marker(ob, ob.width, ob.height, 60, 30)

        bd.add(mk, mk.x, mk.y)
        while True:
            bd.clear(config.show_width)

            addobjects(bd, brick, enemy, goomba, spikey, stalker,
                       spring, coin, cloud, specialbrick, boss, castle)

            bd.add(mk, mk.x, mk.y)

            os.system('clear')
            bd.show(config.show_width, config.show_height)
            event = config.get_key(config.get_input())
            if event == config.QUIT:
                break
            elif event == config.SHOOT:
                bd.add(mk, mk.x, mk.y)
                file.write(str(mk.x) + ',' + str(mk.y) + '\n')
                lists[name].append(makeObject(name, mk.x, mk.y))
            else:
                mk.move(event)
                bd.move(event, mk.width)
                bd.add(mk, mk.x, mk.y)
        bd.remove(mk, mk.x, mk.y)
        bd.at = 0

def makeDirectory(name):
    if not os.path.exists(dir_path + name):
        os.makedirs(dir_path + name)

def makeLevel(name):
    if not os.path.exists(dir_path + name):
        os.makedirs(dir_path + name)

    bd = board.Board(config.board_width, config.show_height)
    addCloud(cloud, bd, name)
    addObjectList(bd, name, "brick", "goomba", "spikey", "stalker",
                  "spring", "coin", "specialbrick", "castle", "boss")

def giveList(filename):
    f = open(filename)
    lines = f.readlines()
    lines = [item.rstrip("\n") for item in lines]
    newList = list()
    for item in lines:
        item = item.split(",")
        item = tuple(int(items) for items in item)
        newList.append(item)
    f.close()
    return newList

def loadList(lt, level_name, name):
    l = giveList(os.path.join(dir_path + level_name, name + ".txt"))
    for tup in l:
        lt.append(makeObject(name, tup[0], tup[1]))

def makeObject(obj, x=config.show_width / 2, y=config.show_height / 2):
    if obj == "brick":
        return objects.Brick(7, 3, x, y)
    if obj == "coin":
        return objects.Coin(7, 3, x, y)
    if obj == "spring":
        return objects.Spring(7, 3, x, y)
    if obj == "specialbrick":
        return objects.SpecialBrick(14, 3, x, y)
    if obj == "goomba":
        return objects.Goomba(3, 2, x, y)
    if obj == "spikey":
        return objects.Spikey(4, 2, x, y)
    if obj == "stalker":
        return objects.Stalker(4, 2, x, y)
    if obj == "cloud":
        return objects.Cloud(14, 4, x, y)
    if obj == "castle":
        return objects.Castle(41, 15, x, y)
    if obj == "bullet":
        return objects.Bullet(4, 1, x, y)
    if obj == "boss":
        return objects.Boss(8, 4, x, y)


import pydenticon

def hex_to_rgbstring(hex):
    hex = hex[1:]
    r = int(hex[0:2], 16)
    g = int(hex[2:4], 16)
    b = int(hex[4:6], 16)

    return f"rgb({r},{g},{b})"

def create_company_logo(title, primary_color, secondary_color):
    foreground = [hex_to_rgbstring(primary_color)]
    background = "rgba(255, 255, 255, 0)"

    padding = (20, 20, 20, 20)

    generator = pydenticon.Generator(5, 5,
                                     foreground=foreground, background=background)

    return generator.generate(title, 200, 200, output_format="png", padding=padding)


from django.urls import path, include

from .views import login_page, logout_page,register

app_name = 'user'

urlpatterns = [
    path('login/', login_page, name='login'),
    path('logout/', logout_page, name='logout'),
    path('register/', register, name='register'),
]


import os.path
import requests
import re
import textwrap
import sys
if sys.version_info[0] < 3:
    print('You need to run this with Python 3')
    sys.exit(1)

indent = ' ' * 4

def fill(text):
    tmp = textwrap.fill(text)
    return textwrap.indent(tmp, indent)

def filltab(text):
    tmp = textwrap.fill(text, width=120)
    return textwrap.indent(tmp, '\t')

def cpp_array_initializer(arr):
    return '{%s}' % (', '.join(map(str, arr)))

def multiline_cpp_array_initializer(arr):
    alllines = '{\n'
    current_line = '\t'
    for i in arr:
        if(len(current_line) > 80):
            if(current_line[-1] == ' '):
                current_line = current_line[:-1]
            alllines += current_line + '\n'
            current_line = '\t'
        current_line += str(i)
        if(i != len(arr)-1): current_line += ', '
    if(len(current_line) > 0):
        if(current_line[-1] == ' '):
          current_line = current_line[:-1]
        alllines += current_line + '\n'
    alllines += '\n}'
    return alllines

def compose2(f, g):
    return lambda x: f(g(x))

def cpp_arrayarray_initializer(arr):
    alllines = '{'
    for i in range(0,len(arr), 4):
        alllines += '\n\t' + ', '.join(map(cpp_array_initializer,arr[i:i+4]))
        if(i + 4 < len(arr)): alllines += ','
    alllines += '\n}'
    return alllines

url = "https://www.unicode.org/Public/idna/15.0.0/IdnaMappingTable.txt"
filename = "IdnaMappingTable.txt"
def get_table():
    if(not os.path.exists(filename)):
        tablefile = requests.get(url)
        with open(filename,  'wb') as file:
            file.write(tablefile.content)
    with open(filename, 'r') as file:
       return file.read()

def get_version(table_data):
    return re.search("# Version: (.*)", table_data).group(1)

def find_slice(seq, subseq):
    n = len(seq)
    m = len(subseq)
    for i in range(n - m + 1):
        if seq[i:i + m] == subseq:
            return i
    return -1

def values(words):
    answer = []
    for w in words:
        w2 = w[1]
        if(w[1] == 3):
            w2 += (w[2][0] << 8) + (w[2][1] << 24)
        answer.append([w[0][0], w2])
    return answer

UseSTD3ASCIIRules=False
if __name__ == "__main__":
    table_data = get_table()
    print("// IDNA ", get_version(get_table()))
    words = []
    long_mapped = []
    previous_code = -1
    mapping = {"ignored":0,"valid":1,"disallowed":2,"mapped":3}
    for line in table_data.split("\n"):
        if(line.startswith("#") or ";" not in line):
            continue
        line = line[0:line.index("#")]
        line = line.split(";")
        line = [x.strip() for x in line if x.strip() != ""]
        if(not UseSTD3ASCIIRules and line[1].startswith("disallowed_STD3_")): line[1] = line[1][16:]
        if(line[1] == "deviation"): line[1] = "valid" # IDNA2008, see https://www.unicode.org/faq/idn.html
        codepoints = [int(x,16) for x in line[0].split("..")]
        code = mapping[line[1]]
        mapped = []
        if((code != 3) and (code == previous_code)):
            continue # nothing to do
        previous_code = code
        if(code == 3):
            mapped = [int(x,16) for x in line[2].split(" ")]
            already = find_slice(long_mapped, mapped)
            if already != -1:
                long_index = already
            else:
                long_index = len(long_mapped)
                long_mapped += mapped
            long_length = len(mapped)
            words.append([codepoints, code, [long_index, long_length]])
        else:
            words.append([codepoints, code])
    print("""
// clang-format off
#ifndef ADA_IDNA_TABLES_H
#define ADA_IDNA_TABLES_H
#include <cstdint>

namespace ada::idna {
    """)
    print("const uint32_t mappings["+str(len(long_mapped))+"] = ")
    print(multiline_cpp_array_initializer(long_mapped), end=";\n")
    print("const uint32_t table["+str(len(words))+"][2] = ")
    print(cpp_arrayarray_initializer(values(words)), end=";\n")
    print("""

} // namespace ada::idna
#endif // ADA_IDNA_TABLES_H
    """)


# import pandas as pd
import os
import cv2
import numpy as np
from tqdm import tqdm
from threading import Thread

# import blobfile as bf
import random

#car_ = pd.read_csv('Image_table.csv')
def sort_contours(cnts, method="left-to-right"):
	# initialize the reverse flag and sort index
	reverse = False
	i = 0
	# handle if we need to sort in reverse
	if method == "right-to-left" or method == "bottom-to-top":
		reverse = True
	# handle if we are sorting against the y-coordinate rather than
	# the x-coordinate of the bounding box
	if method == "top-to-bottom" or method == "bottom-to-top":
		i = 1
	# construct the list of bounding boxes and sort them from top to
	# bottom
	boundingBoxes = [cv2.boundingRect(c) for c in cnts]
	(cnts, boundingBoxes) = zip(*sorted(zip(cnts, boundingBoxes),
		key=lambda b:b[1][i], reverse=reverse))
	# return the list of sorted contours and bounding boxes
	return (cnts, boundingBoxes)

def get_ret_image(img_le):
    rect_le = (10, 10, img_le.shape[1], img_le.shape[0])
    mask_le = np.zeros(img_le.shape[:2], np.uint8)
    bgd_Model = np.zeros((1, 65), np.float64)
    fgd_Model = np.zeros((1, 65), np.float64)
    cv2.grabCut(img_le, mask_le, rect_le, bgd_Model, fgd_Model, 5, cv2.GC_INIT_WITH_RECT)

    #mask_le2 = get_mask_threshold(img_le)
    mask_le2 = np.where((mask_le == 0) | (mask_le == 2), 0, 1).astype('uint8')  # 做一個只有0 & 1新的mask

    #print(np.unique(mask_le2))
    img_copy_le = img_le.copy()
    img_grabcut_le = img_copy_le * mask_le2[:, :, np.newaxis]
    # cv2.imshow(f"Image", img_grabcut_le)
    # cv2.imshow(f"Mask", mask_le2 * 255)

    contours, hierarchy = cv2.findContours(mask_le2, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

    if len(contours) > 0:
        contours, _ = sort_contours(contours)
        #print(contours)
        # color = ['red', 'green']
        # for i in range(0, len(contours)):
        # cv2.boundingRect: 透過輪廓找到外接矩形
        # 輸出：(x, y)矩形左上角座標、w 矩形寬(x軸方向)、h 矩形高(y軸方向)
        x, y, w, h = cv2.boundingRect(contours[0])
        # for c in contours:
        #     x, y, w, h = cv2.boundingRect(c)
        #     if w > 20 or h > 20:
        #         break
        # cv2.imshow(f"Cut", img_grabcut_le[y:y + h, x:x + w])
        #
        # cv2.imshow("Original", img_le)
        # cv2.waitKey(0)
        # cv2.destroyAllWindows()

        return img_grabcut_le, img_grabcut_le[y:y + h, x:x + w], mask_le2, mask_le2[y:y + h, x:x + w]
    else:
        return None, None, None, None

# path_list = []
# file = open("filter_file_name.txt", "w")
# for im in car_.iloc:
#     if im[3] == 90 or im[3] == 270:
#         p = [t for t in im[2].split("$$")][:-3]
#         p.append(im[2])
#         p = os.path.join(*p)
#         path_list.append(p)
#         file.write(p+"\n")
#         p = os.path.join("resized_DVM", p)
#         print(p)
# file.close()

# get file name
result_path = "/data/harry/Data_generation/diffusers-main/car/preproc_car"
file = open("filter_file_name.txt", "r")
path_list = file.readlines()
file.close()
path_list = random.sample(path_list, 120016)

def job(paths):
    for p in tqdm(paths):
        p = os.path.join(r"resized_DVM", p[:-1])
        image = cv2.imread(p)
        im1, im2, msk1, msk2 = get_ret_image(image)
        if im1 is not None:
            if im2.shape[0] > 20 or im2.shape[1] > 20:
                cv2.imwrite(os.path.join(result_path, "image", p.split("/")[-1][:-3] + "png"), im2)
                cv2.imwrite(os.path.join(result_path, "mask", p.split("/")[-1][:-3] + "png"), msk2)

num_thread = 16
thread_list = []
job_iter = int(len(path_list)/num_thread)
for i in range(num_thread-1):
    t = Thread(target=job,args=([path_list[job_iter*i:job_iter*i+job_iter]]))
    thread_list.append(t)
thread_list.append(Thread(target=job,args=([path_list[job_iter*(num_thread-1):]])))

for j in thread_list:
    j.start()

for j in thread_list:
    j.join()

print("Done")

# image = cv2.imread(r"C:\Users\ASUS\Desktop\Abarth$$595C$$2016$$White$$2_5$$13$$image_3.jpg")
# im1, im2, msk1, msk2 = get_ret_image(image)
# cv2.imshow("im2",im2)
# cv2.imshow("msk2",msk1*255)
# cv2.waitKey(0)
# cv2.destroyAllWindows()


import sys
import pygame
import copy
from settings import *
from player import *
from Enemy import *

class Program:

    pygame.init()
    vec = pygame.math.Vector2  # for 2-D surface

    def __init__(self):
        self.window = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
        self.clock = pygame.time.Clock()  # to control the frames per second( to keep track of time)
        self.running = True
        self.state = "Start"
        self.cell_width = MAZE_WIDTH // COLUMNS
        self.cell_height = MAZE_HEIGHT // ROWS
        self.walls = []
        self.coins=[]
        self.enemies=[]
        self.enemy_pos = []
        self.player_pos=None
        self.load()
        self.player=Player(self,vec(self.player_pos))
        self.make_enemies()

    def run(self):
        while self.running:
            if self.state == "Start":
                self.start_events()
                self.start_update()
                self.start_draw()
            elif self.state == "playing":
                self.playing_events()
                self.playing_update()
                self.playing_draw()
            elif self.state == "game over":
                self.game_over_events()
                self.game_over_update()
                self.game_over_draw()
            else:  # so the game doesn't crash
                self.running = False
            self.clock.tick(FPS)  # This can be used to help limit the runtime speed of a game

        pygame.quit()
        sys.exit()

    # ############################################ HELP FUNCTIONS #########################################

    def draw_text(self, words, screen,pos, size,color,font_name, centered=False, custom_font=False):
        if custom_font:
            custom_font = pygame.font.Font(font_name, size)
            text = custom_font.render(words, True, color)
            text_size=text.get_size()
        else:
            system_font = pygame.font.SysFont(font_name, size)
            text = system_font.render(words, True, color)
            text_size = text.get_size()
        if centered:
            pos[0] = pos[0] - text_size[0]//2
            pos[1] = pos[1] - text_size[1]//2
            self.window.blit(text, pos)

    def load(self):
        self.start_maze = pygame.image.load("images\\start_maze.jpg")
        self.start_maze = pygame.transform.scale(self.start_maze, (WINDOW_WIDTH, WINDOW_HEIGHT))
        self.background = pygame.image.load("images\\maze.png")
        self.background = pygame.transform.scale(self.background, (MAZE_WIDTH, MAZE_HEIGHT))

        # we are opening walls file
        # we are creating walls list with cordinate of walls
        with open("walls.txt", 'r') as file:
            for yidx, line in enumerate(file):
                for xidx, char in enumerate(line):
                    if char == "1":
                        self.walls.append(vec(xidx, yidx))
                    elif char == "C":
                        self.coins.append(vec(xidx, yidx))
                    elif char == "P":
                        self.player_pos = [xidx, yidx]
                    elif char in ["2", "3", "4", "5"]:
                        self.enemy_pos.append([xidx, yidx])
                    elif char == "B":
                        pygame.draw.rect(self.background, BLACK, (xidx*self.cell_width, yidx*self.cell_height,
                                                                  self.cell_width, self.cell_height))

        print(self.walls)
    def make_enemies(self):
        for idx,pos in enumerate(self.enemy_pos):
            self.enemies.append(Enemy(self,vec(pos),idx))

    def draw_grid(self):
        for x in range(WINDOW_WIDTH//self.cell_width):
            pygame.draw.line(self.background, YELLOW, (x * self.cell_width, 0), (x * self.cell_width, WINDOW_HEIGHT))
        for x in range(WINDOW_HEIGHT // self.cell_height):
            pygame.draw.line(self.background, YELLOW, (0, x * self.cell_height), (WINDOW_WIDTH, x * self.cell_height))
        # for coin in self.coins:
        #     pygame.draw.rect(self.background,YELLOW,(coin.x*self.cell_width,
        #                      coin.y*self.cell_height,self.cell_width,self.cell_height))

    def reset(self):
        self.player.lives = 3
        self.player.current_score = 0
        self.player.grid_pos = vec(self.player.starting_pos)
        self.player.pix_pos = self.player.get_pix_pos()
        self.player.direction *= 0
        for enemy in self.enemies:
            enemy.grid_pos = vec(enemy.starting_pos)
            enemy.pix_pos = enemy.get_pix_pos()
            enemy.direction *= 0

        self.coins = []
        with open("walls.txt", 'r') as file:
            for yidx, line in enumerate(file):
                for xidx, char in enumerate(line):
                    if char == 'C':
                        self.coins.append(vec(xidx, yidx))
        self.state = "playing"
    # ############################################ START FUNCTIONS #########################################
    def start_events(self):
        for events in pygame.event.get():
            if events.type == pygame.QUIT:
                self.running = False
            if events.type == pygame.KEYDOWN or events.type == pygame.K_SPACE:
                self.state = "playing"

    def start_update(self):
        pass

    def start_draw(self):
        self.window.fill(BLACK)
        self.window.blit(self.start_maze, (0, WINDOW_HEIGHT // 2 + 50))
        self.draw_text("PAC-MAN",self.window,[WINDOW_WIDTH//2,WINDOW_HEIGHT//2], PAC_MAN,WHITE,PAC_MAN_FONT, centered=True, custom_font=True)
        # self.draw_text("HIGHEST SCORE ",self.window,[300,40], HIGHEST_SCORE,WHITE,PAC_MAN_FONT, centered=True, custom_font=True)

        pygame.display.set_caption("PAC_MAN Start")
        pygame.display.update()

    # ############################################ PLAYING FUNCTIONS #########################################
    def playing_events(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                self.running = False
            if event.type== pygame.KEYDOWN:
                if event.key==pygame.K_LEFT:
                    self.player.move(vec(-1,0))  # one step back is minus
                if event.key==pygame.K_RIGHT:
                    self.player.move(vec(1, 0))
                if event.key==pygame.K_UP:
                    self.player.move(vec(0, -1))
                if event.key==pygame.K_DOWN:
                    self.player.move(vec(0, 1))
    def playing_update(self):
        self.player.update()
        for enemy in self.enemies:
            enemy.update()
        for enemy in self.enemies:
            if enemy.grid_pos == self.player.grid_pos:
                self.remove_life()

    def playing_draw(self):

        self.window.fill(BLACK)
        self.window.blit(self.background, (TOP_BOTTOM_BUFFER//2, TOP_BOTTOM_BUFFER//2))
        self.draw_coins()
        #self.draw_grid()
        self.draw_text("CURRENT SCORE: {}".format(self.player.current_score),self.window,[120 ,15],16,GRAY,"arial", centered=True, custom_font=False)
        self.draw_text("HIGHEST SCORE: ",self.window,[450 ,15],16,GRAY,"arial", centered=True, custom_font=False)
        pygame.display.set_caption("PAC_MAN playing")
        self.player.draw()
        for enemy in self.enemies:
            enemy.draw()
        pygame.display.update()
    def remove_life(self):
        self.player.lives -= 1
        if self.player.lives == 0:
            self.state = "game over"
        else:
            self.player.grid_pos = vec(self.player.starting_pos)
            self.player.pix_pos = self.player.get_pix_pos()
            self.player.direction *= 0
            for enemy in self.enemies:
                enemy.grid_pos = vec(enemy.starting_pos)
                enemy.pix_pos = enemy.get_pix_pos()
                enemy.direction *= 0

    def draw_coins(self):
        for coin in self.coins:
            pygame.draw.circle(self.window,COIN_COLOR,(int(coin.x*self.cell_width)+self.cell_width//2+TOP_BOTTOM_BUFFER//2,
                                                int(coin.y*self.cell_height)+self.cell_width//2+TOP_BOTTOM_BUFFER//2),5)

# ############################################ GAME OVER FUNCTIONS #########################################
    def game_over_events(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                self.running = False
            if event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE:
                self.reset()
            if event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
                self.running = False

    def game_over_update(self):
        pass

    def game_over_draw(self):
        self.window.fill(BLACK)
        quit_text = "Press the escape button to QUIT"
        again_text = "Press SPACE bar to PLAY AGAIN"
        self.draw_text("GAME OVER", self.window,[WINDOW_WIDTH//2, 100], 52,WHITE,"arial", centered=True, custom_font=False)
        self.draw_text(again_text, self.window, [
                       WINDOW_WIDTH//2, WINDOW_HEIGHT//2],  36, (255, 212, 128), "arial", centered=True, custom_font=False)
        self.draw_text(quit_text, self.window, [
                       WINDOW_WIDTH//2, WINDOW_HEIGHT//1.5],  36, (255, 212, 128), "arial", centered=True,custom_font=False)
        pygame.display.update()