from pulp import *

import numpy as np, pandas as pd

import warnings

warnings.filterwarnings('always')

warnings.filterwarnings('ignore')
prob = LpProblem('Diet_Problem', LpMinimize)
df = pd.read_excel('diet.xls',nrows=17)
df.head() #Here we see the data
food = list(df.Foods)
#The list of items
count=pd.Series(range(1,len(food)+1))
print('List of different food items is here follows: -')
food_s = pd.Series(food)
#Convert to data frame
f_frame = pd.concat([count,food_s],axis=1,keys=['S.No','Food Items'])
f_frame
# Create a dictinary of costs for all food items
costs = dict(zip(food,df['Price/Serving']))
#Create a dictionary of calories for all items of food
calories = dict(zip(food,df['Calories']))
#Create a dictionary of cholesterol for all items of food
chol = dict(zip(food,df['Cholesterol (mg)']))
#Create a dictionary of total fat for all items of food
fat = dict(zip(food,df['Total_Fat (g)']))
#Create a dictionary of sodium for all items of food
sodium = dict(zip(food,df['Sodium (mg)']))
#Create a dictionary of carbohydrates for all items of food
carbs = dict(zip(food,df['Carbohydrates (g)']))
#Create a dictionary of dietary fiber for all items of food
fiber = dict(zip(food,df['Dietary_Fiber (g)']))
#Create a dictionary of protein for all food items
protein = dict(zip(food,df['Protein (g)']))
#Create a dictionary of vitamin A for all food items
vit_A = dict(zip(food,df['Vit_A (IU)']))
#Create a dictionary of vitamin C for all food items
vit_C = dict(zip(food,df['Vit_C (IU)']))
#Create a dictionary of calcium for all food items
calcium = dict(zip(food,df['Calcium (mg)']))
#Create a dictionary of iron for all food items
iron = dict(zip(food,df['Iron (mg)']))
# A dictionary called 'food_vars' is created to contain the referenced Variables
food_vars = LpVariable.dicts("Food",food,lowBound=0,cat='Continuous')
prob += lpSum([costs[i]*food_vars[i] for i in food])
prob
lpSum([food_vars[i]*calories[i] for i in food])
prob += lpSum([food_vars[x]*calories[x] for x in food]) >= 800, "CaloriesMinimum"
prob += lpSum([food_vars[x]*calories[x] for x in food]) <= 1300, "CaloriesMaximum"
prob
#Carbohydrates' constraint
prob += lpSum([food_vars[x]*carbs[x] for x in food]) >= 130, "CarbsMinimum"
prob += lpSum([food_vars[x]*carbs[x] for x in food]) <= 200, "CarbsMaximum"
#Fat's constraint
prob += lpSum([food_vars[x]*fat[x] for x in food]) >= 20, "FatsMinimum"
prob += lpSum([food_vars[x]*fat[x] for x in food]) <= 50, "FatsMaximum"
#Protein's constraint
prob += lpSum([food_vars[x]*protein[x] for x in food]) >= 100, "ProteinsMinimum"
prob += lpSum([food_vars[x]*protein[x] for x in food]) <= 150, "ProteinsMaximum"
#Vit_A constraint
prob += lpSum([food_vars[x]*vit_A[x] for x in food]) >= 1000, "Vit_A_Minimum"
prob += lpSum([food_vars[x]*vit_A[x] for x in food]) <= 10000, "Vit_A_Maximum"
prob.solve()
prob. solver
LpStatus[prob.status]
for var in prob.variables():
    print(f'Variable name: {var.name} , Variable value : {var.value()}n')
print('n')
print('*'*100)
print('n')
#We can also see the slack variables of the constraints
for name, con in prob.constraints.items():
    print(f'constraint name:{name}, constraint value:{con.value()}n')
print('*'*100)
print('n')
## OBJECTIVE VALUE
print(f'OBJECTIVE VALUE IS: {prob.objective.value()}')


from flask import Flask, redirect, url_for, render_template, request
import Task3
from Task3 import change_map, write_to_file
app = Flask(__name__)

@app.route("/")
def home():
    return render_template("index.html")

@app.route("/register", methods=["POST"])
def register():
    name = request.form.get("domain")
    token = request.form.get("tocken")
    return f"{name} {token}"

@app.route("/register/map", methods=["POST"])
def take_elements():
    elements = register().split()
    name = elements[0]
    tocker = elements[1]
    file_with_friends = write_to_file(name, tocker)
    your_map = change_map("friends.json")
    return your_map.get_root().render()

if __name__ == "__main__":
    app.run(debug=True)


"""
Implement a relational join as a MapReduce query:
SELECT *

FROM Orders, LineItem

WHERE Order.order_id = LineItem.order_id
"""

import MapReduce
import sys

mr = MapReduce.MapReduce()

counter = 0
def mapper(record):
    global counter
    # key: table identifier
    # value: document contents
    key = record[1]
    value = record
    mr.emit_intermediate(key, value)

def reducer(key, values):
    total=[]
    # key: word
    # values: list of occurrence counts
    order = [value for value in values if value[0] == "order"]
    line_items = [value for value in values if value[0] == "line_item"]
    for l in line_items:
        total.append(order[0] + l)
    for t in total:
        mr.emit(t)

if __name__ == '__main__':
    inputdata = open(sys.argv[1])
    mr.execute(inputdata, mapper, reducer)


# 처음에는 그냥 무작정 factorial 계산을 하고
# 뒤에서 부터 0의 개수를 셌다.

import sys
from math import factorial

n = int(sys.stdin.readline())

n = str(factorial(n))

count = 0

for i in range(len(n)-1, -1, -1):
    if n[i] == "0":
        count += 1
    else:
        break

print(count)

# 위의 코드보다 간결하게 작성하여 보자
# factorial 문제라고 마냥 다 계산해버리면 오래걸릴 수도 있다.
# 숫자 뒤에 0이 나온다는 것은?
# 10의 배수라는 것이다
# 그렇다면 10이 나오기 위해서는 ?
# 10의 약수인 2,5가 존재해야한다.
# 5의 배수가 존재한다면 2의 배수는 당연하게 존재할 것이다, ( 5 > 2 )
# 따라서 5가 몇 번 들어가는지 구하면 된다

# n = int(sys.stdin.readline())
#
# count = 1
# total = 0
#
# while n >= 5**count:
#     total += n//(5**count)
#     count += 1
#
# print(total)


# Matthieu Brucher
# Last Change : 2007-08-10 23:13

"""
A standard optimizer
"""

from . import optimizer

class StandardOptimizer(optimizer.Optimizer):
  """
  A standard optimizer, takes a step and finds the best candidate
  Must give in self.optimalPoint the optimal point after optimization
  """
  def __init__(self, **kwargs):
    """
    Needs to have :
      - an object function to optimize (function), alternatively a function ('fun'), gradient ('gradient'), ...
      - a way to get a new point, that is a step (step)
      - a criterion to stop the optimization (criterion)
      - a starting point (x0)
      - a way to find the best point on a line (lineSearch)
    Can have :
      - a step modifier, a factor to modulate the step (stepSize = 1.)
    """
    optimizer.Optimizer.__init__(self, **kwargs)
    self.stepKind = kwargs['step']
    self.optimalPoint = kwargs['x0']
    self.lineSearch = kwargs['line_search']

    self.state['new_parameters'] = self.optimalPoint
    self.state['new_value'] = self.function(self.optimalPoint)

    self.recordHistory(**self.state)

  def iterate(self, forceDir=None):
    """
    Implementation of the optimization. Does one iteration.
    (Optional) Provide known direction to overide step call in 'forceDir'.
    """
    self.state['old_parameters'] = self.optimalPoint
    self.state['old_value'] = self.state['new_value']

    if forceDir is None:
      step = self.stepKind(self.function, self.optimalPoint, state = self.state)
    else:
      self.state['direction'] = forceDir
      self.state['gradient'] = -forceDir
      step = forceDir

    self.optimalPoint = self.lineSearch(origin = self.optimalPoint,
                                        function = self.function,
                                        state = self.state)
    try:
      pest = self.function.pest
    except AttributeError:
      new_pars = self.optimalPoint
    else:
      # this would include self.optimalPoint if the lowest was found by the linesearch
      new_pars = pest.pars_dict_to_array(pest.log[pest._lowest_res_log_ix].pars)
      print("*** CHOSE pars with residual %.8f" % pest.log[pest._lowest_res_log_ix].residual_norm)
    self.state['new_parameters'] = new_pars

    self.state['new_value'] = self.function(new_pars)

    self.recordHistory(**self.state)


# Dependencies
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LogisticRegression, LinearRegression
from sklearn.ensemble import RandomForestClassifier
from sklearn.neighbors import KNeighborsClassifier
from sklearn.svm import SVC
from sklearn.model_selection import train_test_split
from sklearn.model_selection import GridSearchCV
from sklearn.metrics import accuracy_score

# Loading data
url = "https://raw.githubusercontent.com/callxpert/datasets/master/iris.data.txt"
names = ['sepal-length', 'sepal-width', 'petal-length', 'petal-width', 'class']
dataset = pd.read_csv(url, names=names)

# Data details
print('Data shape: ', dataset.shape)
print('------------------------------------------------------------------------------')
print('Data first 10:\n ', dataset.head(10))
print('------------------------------------------------------------------------------')
print('Data stats:\n ', dataset.describe())
print('------------------------------------------------------------------------------')

# Class distribution HOW MANY OBJECT HAVE DIFFERENT FLOWER
print('How many objects have different flower:\n', dataset.groupby('class').size())
print('------------------------------------------------------------------------------')

# Box and whisker plots
dataset.plot(kind='box', subplots=True, layout=(2,2), sharex=False, sharey=False)
#plt.show()

# Histogram
dataset.hist()
plt.show()

# Scatter plot matrix IMPORTANT FEATURES WITH RESPECT TO OTHER
pd.plotting.scatter_matrix(dataset, alpha=0.5, figsize=(8, 8), diagonal='kde')
plt.show()

# Splitting the data
array = dataset.values
X = array[:,0:4]
Y = array[:,4]
features_train, features_test, labels_train, labels_test = train_test_split(X, Y, test_size=0.2, random_state=7)

# Parameters for GridSearch for different algorithms
param_SVC = {'kernel':('linear','rbf','poly'), 'C':[1,10,100,1000], 'gamma':[0.0001,0.001,0.01,0.1,1], 'degree':[0,1,2,3]}
param_KN = {'n_neighbors':[1,2,3,4,5], 'algorithm':('auto', 'ball_tree', 'kd_tree'), 'leaf_size':[10,20,30]}
param_RF = {'n_estimators':[2,3,4,5,6,7,8,10,12,14], 'min_samples_split':[2,3,4,5,6], 'min_samples_leaf':[1,2,3,4]}
# param_LogisticR = {'penalty':('l1','12')}

# Making a models and fit the data
clf_SVC = GridSearchCV(SVC(),param_SVC)
clf_SVC.fit(features_train,labels_train)

clf_KN = GridSearchCV(KNeighborsClassifier(), param_KN)
clf_KN.fit(features_train,labels_train)

clf_RF = GridSearchCV(RandomForestClassifier(), param_RF)
clf_RF.fit(features_train,labels_train)

clf_LogisticR = LogisticRegression()
clf_LogisticR.fit(features_train,labels_train)

# Prediction with help of different models
pred_SVC = clf_SVC.predict(features_test)
pred_KN = clf_KN.predict(features_test)
pred_RF = clf_RF.predict(features_test)
pred_LogisticR = clf_LogisticR.predict(features_test)

# Printing the score
print('SVC score: ', accuracy_score(labels_test, pred_SVC))
print('KN score: ', accuracy_score(labels_test, pred_KN))
print('RF score: ', accuracy_score(labels_test, pred_RF))
print('Logistic score: ', accuracy_score(labels_test, pred_LogisticR))


import streamlit as st
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression

data=pd.read_csv("data//Salary_Data.csv")
lr=LinearRegression()
x = np.array(data['YearsExperience']).reshape(-1,1)
lr.fit(x,np.array(data['Salary']))
st.title("Salary Predictor")

nav= st.sidebar.radio("Navigation",['Home' , 'Prediction' , 'Contribute'])
if nav=='Home':
    st.image("data//salary.jpj")
    if st.checkbox("Show Table"):
        st.table(data)
    graph= st.selectbox("select graph",["Non-interactive","Interactive"])
    val= st.slider('Filter data ',0,20,value=5)
    data=data.loc[data['YearsExperience']>val]
    if graph =="Non-interactive" :
        fig,ax =plt.subplots()
        plt.figure(figsize=(10,5))
        ax.scatter(data['YearsExperience'],data['Salary'])
        plt.xlabel('years of experience')
        plt.ylabel('Salary')
        plt.title('Scatter plt')
        st.pyplot(fig)

    if graph =="Interactive" :
        fig, ax = plt.subplots()
        plt.figure(figsize=(10, 5))
        ax.scatter(data['YearsExperience'], data['Salary'])
        plt.xlabel('years of experience')
        plt.ylabel('Salary')
        plt.title('Scatter plt')
        st.pyplot_chart(fig)

if nav == "Prediction":
    st.image("data//salary.jpj")
    st.header("Know your Salary")
    val = st.number_input("Enter you exp",0.00,20.00,step=0.25)
    val = np.array(val).reshape(1,-1)
    pred =lr.predict(val)[0]

    if st.button("Predict"):
        st.success(f"Your predicted salary is {round(pred)}")
if nav == "Contribute":
    st.image("data//salary.jpj")
    st.header("Contribute to our dataset")
    ex = st.number_input("Enter your Experience",0.0,20.0)
    sal = st.number_input("Enter your Salary",0.00,1000000.00,step = 1000.0)
    if st.button("submit"):
        to_add = {"YearsExperience":[ex],"Salary":[sal]}
        to_add = pd.DataFrame(to_add)
        to_add.to_csv("data//Salary_Data.csv",mode='a',header = False,index= False)
        st.success("Submitted")


from flask import render_template, flash, redirect, url_for

from app.firestore_service import get_todos, put_todo, delete_todo, update_todo
from app.forms import TodoForm

from flask_login import login_required, current_user

from . import tasks

# Private Area Example
@tasks.route('/list', methods=['GET', 'POST'])
@login_required
def list():
  user_id = current_user.id

  task_form = TodoForm()

  if task_form.validate_on_submit():
    put_todo(user_id, task_form.description.data)
    flash('New Task created!', 'success')
    return redirect(url_for('tasks.list'))

  context = {
    'todos': get_todos(user_id),
    'task_form': task_form
  }
  return render_template('tasks.html', **context)

@tasks.route('/delete/<string:todo_id>', methods=['GET'])
@login_required
def delete(todo_id):
  user_id = current_user.id
  delete_todo(user_id=user_id, todo_id=todo_id)

  flash('Task removed', 'success')

  return redirect(url_for('tasks.list'))

@tasks.route('/status/<string:todo_id>/<int:done>', methods=['GET'])
@login_required
def status(todo_id, done):
  user_id = current_user.id

  update_todo(user_id=user_id, todo_id=todo_id, done=done)

  flash('Task updated', 'success')

  return redirect(url_for('tasks.list'))


# %%
import torch
import torch.nn as nn
import torchvision.transforms as transforms
from torch.utils.data import Dataset, DataLoader
import os
import numpy as np
from PIL import Image
import torchvision.utils
import matplotlib.pyplot as plt

# This is for the progress bar.
from tqdm.auto import tqdm

# %%
# parameters
batch_size = 4
n_epochs = 10
patience = 5  # If no improvement in 'patience' epochs, early stop

## blur
### b15
# train_set_dir = "blur/15/train"
# test_set_dir = "blur/15/test"
# model_path = "./model_b15.ckpt"

### b45
# train_set_dir = "blur/45/train/"
# test_set_dir = "blur/45/test/"
# model_path = "./model_b45.ckpt"

### b99
# train_set_dir = "blur/99/train/"
# test_set_dir = "blur/99/test/"
# model_path = "./model_b99.ckpt"

## pixel
### p4
# train_set_dir = "pixel/4/train/"
# test_set_dir = "pixel/4/test/"
# model_path = "./model_p4.ckpt"

### p8
# train_set_dir = "pixel/8/train/"
# test_set_dir = "pixel/8/test/"
# model_path = "./model_p8.ckpt"

### p16
# train_set_dir = "pixel/16/train/"
# test_set_dir = "pixel/16/test/"
# model_path = "./model_p16.ckpt"

### ori
train_set_dir = "att_img_flat/train/"
test_set_dir = "att_img_flat/test/"
model_path = "./model_ori.ckpt"

# %%
transform = transforms.Compose(
    [
        transforms.ToTensor(),
        transforms.Resize((128, 128), antialias=True),
        transforms.Normalize((0.5), (0.5)),
    ]
)

# %%
class mydataset(Dataset):
    def __init__(self, path, tfm=transform, files=None):
        super(mydataset).__init__()
        self.path = path
        self.files = sorted(
            [os.path.join(path, x) for x in os.listdir(path) if x.endswith(".png")]
        )
        if files:
            self.files = files
        print(f"One {path} sample", self.files[0])
        self.transform = tfm

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

    def __getitem__(self, idx):
        fname = self.files[idx]
        im = Image.open(fname)
        im = self.transform(im)
        try:
            label = int(fname.split("s")[-1].split("_")[0])
        except:
            label = -1  # test has no label
        return im, label

# %%
train_set = mydataset(train_set_dir, tfm=transform)
test_set = mydataset(test_set_dir, tfm=transform)

train_loader = DataLoader(
    train_set, batch_size=batch_size, shuffle=True, num_workers=0, pin_memory=True
)
test_loader = DataLoader(
    test_set, batch_size=batch_size, shuffle=True, num_workers=0, pin_memory=True
)

# %%
class Net(nn.Module):
    def __init__(self):
        super().__init__()
        self.cnn = nn.Sequential(
            nn.Conv2d(1, 64, 1, 1, 1),  # [64, 128, 128]
            nn.BatchNorm2d(64),
            nn.ReLU(),
            nn.MaxPool2d(2, 2, 0),  # [64, 64, 64]
            nn.Conv2d(64, 128, 3, 1, 1),  # [128, 64, 64]
            nn.BatchNorm2d(128),
            nn.ReLU(),
            nn.MaxPool2d(2, 2, 0),  # [128, 32, 32]
            nn.Conv2d(128, 256, 3, 1, 1),  # [256, 32, 32]
            nn.BatchNorm2d(256),
            nn.ReLU(),
            nn.MaxPool2d(2, 2, 0),  # [256, 16, 16]
            nn.Conv2d(256, 512, 3, 1, 1),  # [512, 16, 16]
            nn.BatchNorm2d(512),
            nn.ReLU(),
            nn.MaxPool2d(2, 2, 0),  # [512, 8, 8]
            nn.Conv2d(512, 512, 3, 1, 1),  # [512, 8, 8]
            nn.BatchNorm2d(512),
            nn.ReLU(),
            nn.MaxPool2d(2, 2, 0),  # [512, 4, 4]
        )
        self.fc = nn.Sequential(
            nn.Linear(512 * 4 * 4, 1024),
            nn.ReLU(),
            nn.Linear(1024, 512),
            nn.ReLU(),
            nn.Linear(512, 41),
        )

    def forward(self, x):
        out = self.cnn(x)
        out = out.view(out.size()[0], -1)
        return self.fc(out)

net = Net()

# %%
def fgsm_attack(model, loss, images, labels, eps) :
# adversarial attack

    images = images.to(device)
    labels = labels.to(device)
    images.requires_grad = True

    outputs = model(images)

    cost = loss(outputs, labels).to(device)
    model.zero_grad()
    cost.backward()

    attack_images = images + eps*images.grad.sign()
    attack_images = torch.clamp(attack_images, -1, 1)

    return attack_images

#%%
def imshow(img):
    npimg = img.numpy()
    fig = plt.figure(figsize = (5, 15))
    plt.imshow(np.transpose(npimg,(1,2,0)))
    plt.show()

# %%
torch.cuda.is_available = lambda: False
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

# Initialize a model, and put it on the device specified.
model = Net().to(device)
model.load_state_dict(torch.load(model_path))

# For the classification task, we use cross-entropy as the measurement of performance.
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.0003, weight_decay=1e-5)

# Initialize trackers, these are not parameters and should not be changed
stale = 0
best_acc = 0

for epoch in range(n_epochs):

    # ---------- Testing ----------
    # Make sure the model is in eval mode so that some modules like dropout are disabled and work normally.
    model.eval()

    # These are used to record information in testing.
    test_loss = []
    test_accs = []

    # Iterate the testing set by batches.
    for batch in tqdm(test_loader):

        images, labels = batch
        #imshow(torchvision.utils.make_grid(images, normalize=True))

        images = fgsm_attack(model, criterion, images, labels, 0).to(device)
        #imshow(torchvision.utils.make_grid(images, normalize=True))

        with torch.no_grad():
            logits = model(images.to(device))

        # We can still compute the loss (but not the gradient).
        loss = criterion(logits, labels.to(device))

        # Compute the accuracy for current batch.
        acc = (logits.argmax(dim=-1) == labels.to(device)).float().mean()

        # Record the loss and accuracy.
        test_loss.append(loss.item())
        test_accs.append(acc)
        # break

    # The average loss and accuracy for entire testing set is the average of the recorded values.
    test_loss = sum(test_loss) / len(test_loss)
    test_acc = sum(test_accs) / len(test_accs)

    # Print the information.
    print(
        f"[ Test | {epoch + 1:03d}/{n_epochs:03d} ] loss = {test_loss:.5f}, acc = {test_acc:.5f}"
    )

    # if not testing, save the last epoch
    if len(test_loader) == 0:
        torch.save(model.state_dict(), model_path)
        print("saving model at last epoch")

# %%
# get reports
from sklearn.metrics import classification_report, accuracy_score, hamming_loss

model_best = Net().to(device)
model_best.load_state_dict(torch.load(model_path))
model_best.eval()

label_pred = []
label_true = []

with torch.no_grad():
    for data, labels in tqdm(test_loader):
        test_pred = model_best(data.to(device))
        test_label = np.argmax(test_pred.cpu().data.numpy(), axis=1)
        if len(test_label) > 1 and len(labels) > 1:
            label_pred += test_label.squeeze().tolist()
            label_true += labels.squeeze().tolist()
        else:
            label_pred += test_label.tolist()
            label_true += labels.tolist()

    report = classification_report(
        label_true, label_pred, labels=[i for i in range(1, 41)], zero_division=0
    )
    print(report)

    test_acc = accuracy_score(label_true, label_pred)
    test_loss = hamming_loss(label_true, label_pred)

    # Print the information.
    print(f"loss = {test_loss:.5f}, acc = {test_acc:.5f}")

    with open("".join(model_path[2:].split(".")[:-1]) + "_report.txt", "w") as f:
        f.write(report)
        f.write(f"\nacc: {test_acc}\nloss: {test_loss}\n")


from fabric import Connection

host_list = ('root@demo.seafile.top', 'root@download.seafile.top')

for host in host_list:

    c = Connection(host)

    result = c.run('uname -s', hide=True)
    print("Ran {0.command!r} on {0.connection.host}, got stdout:\n{0.stdout}".format(result))

    result = c.put('lian-test', remote='/opt/')
    print("Uploaded {0.local} to {0.remote}".format(result))


#! /usr/bin/env python3

"""
jxl-strip

Strips the container off of a jxl file, reducing the size and removing any
potentially sensitive metadata. The original file is overwritten, so make sure
to have a copy if you are experimenting.

Currently it is possible for this program to produce invalid JXL files, if the
the image is a level 10 image, in which case the container is required. This
should be uncommon however, and really only effects CMYK, or gigapixel images.
"""

from pathlib import Path
import argparse
import sys

def has_container(bitstream: bytes) -> bool:
    """
    Determines the image type by sniffing the first few bytes.
    """
    # Test for raw JXL codestream.
    if bitstream[:2] == bytes.fromhex("FF0A"):
        return False
    # Test for JXL box structure. http://www-internal/2022/18181-2#box-types
    if bitstream[:12] == bytes.fromhex("0000 000C 4A58 4C20 0D0A 870A"):
        return True
    raise ValueError("Not a JPEG XL file.")

def decode_container(bitstream: bytes) -> bytes:
    """
    Parses the ISOBMFF container, extracts the codestream, and decodes it.
    JXL container specification: http://www-internal/2022/18181-2
    """

    def parse_box(bitstream: bytes, box_start: int) -> dict:
        LBox = int.from_bytes(bitstream[box_start : box_start + 4])
        XLBox = None
        if 1 < LBox <= 8:
            raise ValueError(f"Invalid LBox at byte {box_start}.")
        if LBox == 1:
            XLBox = int.from_bytes(bitstream[box_start + 8 : box_start + 16])
            if XLBox <= 16:
                raise ValueError(f"Invalid XLBox at byte {box_start}.")
        if XLBox:
            header_length = 16
            box_length = XLBox
        else:
            header_length = 8
            if LBox == 0:
                box_length = len(bitstream) - box_start
            else:
                box_length = LBox
        return {
            "length": box_length,
            "type": bitstream[box_start + 4 : box_start + 8],
            "data": bitstream[box_start + header_length : box_start + box_length],
        }

    # Reject files missing required boxes. These two boxes are required to be at
    # the start and contain no values, so we can manually check there presence.
    # Signature box. (Redundant as has already been checked.)
    if bitstream[:12] != bytes.fromhex("0000000C 4A584C20 0D0A870A"):
        raise ValueError("Invalid signature box.")
    # File Type box.
    if bitstream[12:32] != bytes.fromhex(
        "00000014 66747970 6A786C20 00000000 6A786C20"
    ):
        raise ValueError("Invalid file type box.")

    partial_codestream = []
    container_pointer = 32
    while container_pointer < len(bitstream):
        box = parse_box(bitstream, container_pointer)
        container_pointer += box["length"]
        if box["type"] == b"jxll":
            level = int.from_bytes(box["data"])
            if level != 5 or level != 10:
                raise ValueError("Unknown level")
        elif box["type"] == b"jxlc":
            codestream = box["data"]
        elif box["type"] == b"jxlp":
            index = int.from_bytes(box["data"][:4])
            partial_codestream.append([index, box["data"][4:]])

    if partial_codestream:
        partial_codestream.sort(key=lambda i: i[0])
        codestream = b"".join([i[1] for i in partial_codestream])

    return codestream

def main() -> int:
    """Read file from the command line, and strip its box."""

    parser = argparse.ArgumentParser(
        prog="jxl-strip",
        description="Strips the container from a JPEG XL image",
        epilog="jxl-strip will strip the container from any jxl images, reducing their size\nand removing any privacy compromising metadata.",
    )
    parser.add_argument(
        "-v",
        "--verbose",
        action="store_true",
        help="explain what is happening.",
    )
    parser.add_argument(
        "file", help="JXL file to strip, will be overwritten", type=Path
    )
    args = parser.parse_args()

    # Main program logic start.
    try:
        with open(args.file, "rb") as fp:
            # has_container will raise a ValueError if not a jxl file, and only
            # reading the first 12 bytes makes this check fast. If it is a jxl
            # file, reads the rest of it.
            bitstream = fp.read(12)
            container = has_container(bitstream)
            bitstream = bitstream + fp.read()
        if container:
            # There is technically a race condition here as we are reopening the
            # file, but doing it otherwise is annoying, and it is unlikely that
            # another tool is manipulating the files at the same time.
            if args.verbose:
                print(f"Striping {args.file}", file=sys.stderr)
            with open(args.file, "wb") as fp:
                fp.write(decode_container(bitstream))
        else:
            if args.verbose:
                print(
                    f"Skipping {args.file} as it is already stripped", file=sys.stderr
                )
    except FileNotFoundError:
        print(f"{args.file} not found", sys.stderr)
        return 1
    except ValueError:
        print(f"{args.file} is not a valid JXL file", sys.stderr)
        return 1

    return 0

if __name__ == "__main__":
    sys.exit(main())


"""
Run theano functions in parallel on multiple GPUs (data parallelism).

This file has everything unique to the workers.
"""

import os
import pickle
from threading import BrokenBarrierError

from .variables import Inputs, Shareds, SynkFunction
from .common import use_gpu
from .common import (PKL_FILE, FUNCTION, GPU_COMM, BROADCAST, REDUCE, ALL_REDUCE,
                  ALL_GATHER, GATHER, WORKER_OPS, AVG_ALIASES, CPU_COMM, SCATTER)

class Function(SynkFunction):

    rank = None
    master_rank = None

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self._build_output_subset_shmem(False)

    def __call__(self, sync, g_inputs, gpu_comm):
        """
        1. Gather the right inputs from mp shared values.
        2. Execute local theano function on those inputs.
        3. Send results back to master.
        """
        my_inputs = self.receive_inputs(g_inputs)
        output_subset, output_set = self._receive_output_subset()
        my_results = self._call_theano_function(my_inputs, output_subset)  # (always returns a tuple)
        self._collect_results(my_results, gpu_comm, output_set)

    def receive_inputs(self, g_inputs):
        assign_idx = g_inputs.sync.assign_idx[self._ID]
        my_idx = (assign_idx[self.rank], assign_idx[self.rank + 1])
        my_inputs = list()
        for input_ID, scatter in zip(self._input_IDs, self._inputs_scatter):
            if g_inputs.sync.tags[input_ID] != g_inputs.tags[input_ID]:
                # then a new shmem has been allocated, need to get it.
                shape = g_inputs.sync.shapes[input_ID][:]
                tag_ID = g_inputs.sync.tags[input_ID]
                g_inputs.alloc_shmem(input_ID, shape, tag_ID, False)
            shmem = g_inputs.shmems[input_ID]
            if scatter:
                my_inputs.append(shmem[my_idx[0]:my_idx[1]])
            else:
                my_inputs.append(shmem[:g_inputs.sync.max_idx[input_ID]])
        return tuple(my_inputs)

    def _receive_output_subset(self):
        output_set = [i for i, x in enumerate(self._output_subset_shmem) if x]
        output_subset = None if all(output_set) else output_set
        return output_subset, output_set

    def _collect_results(self, my_results, gpu_comm, output_set):
        for idx, r in zip(output_set, my_results):
            mode = self._collect_modes[idx]
            op = self._reduce_ops[idx]
            if mode == "reduce":
                gpu_comm.reduce(r, op=op, root=self.master_rank)
            elif mode == "gather":
                gpu_comm.all_gather(r)
            elif mode is not None:
                raise RuntimeError("Unrecognized collect mode in worker function.")

def unpack_functions(theano_functions, sync_dict, n_fcn):
    """
    Worker will recover variables in the same order as the master committed
    them, so they will have the same ID (index).
    """
    collect_modes_all = sync_dict["collect_modes"]
    reduce_ops_all = sync_dict["reduce_ops"]
    inputs_scatter_all = sync_dict["inputs_scatter"]
    synk_functions = list()
    g_inputs = Inputs()
    g_shareds = Shareds()
    for idx, fcn in enumerate(theano_functions[:n_fcn]):
        input_IDs = g_inputs.register_func(fcn)
        g_shareds.register_func(fcn, build_avg_func=False)
        synk_functions.append(Function(ID=idx,
                                       theano_function=fcn,
                                       input_IDs=input_IDs,
                                       inputs_scatter=inputs_scatter_all[idx],
                                       collect_modes=collect_modes_all[idx],
                                       reduce_ops=reduce_ops_all[idx],
                                       )
                              )
    g_shareds.avg_functions = theano_functions[n_fcn:]
    # g_shareds.unpack_avg_facs()  # (only needed for changing avg_fac later)
    return synk_functions, g_inputs, g_shareds

def receive_distribution(rank, n_gpu, sync):
    sync.barriers.distribute.wait()
    if not sync.distributed.value:
        return False
    sync_dict = sync.dict.copy()  # (retrieve it as a normal dict)
    with open(PKL_FILE, "rb") as f:
        theano_functions = pickle.load(f)  # should be all in one list
    if sync.barriers.delete_pkl.wait() == 0:
        os.remove(PKL_FILE)  # leave no trace
    synk_functions, g_inputs, g_shareds = \
        unpack_functions(theano_functions, sync_dict, sync.n_user_fcns.value)
    g_inputs.build_sync(len(synk_functions), n_gpu, False)
    g_shareds.build_sync(False)
    return synk_functions, g_inputs, g_shareds

def do_gpu_comms(sync, g_shareds, gpu_comm, master_rank):
    shared_IDs = g_shareds.sync.shared_IDs[:sync.n_shared.value]
    comm_ID = sync.comm_ID.value
    if comm_ID in [REDUCE, ALL_REDUCE]:
        op = WORKER_OPS.get(sync.comm_op.value, None)
        assert op is not None
        avg = op in AVG_ALIASES
        op = "sum" if avg else op
    if comm_ID == ALL_GATHER:
        src = g_shareds.gpuarrays[shared_IDs[0]]
        dest = g_shareds.gpuarrays[shared_IDs[1]]
        gpu_comm.all_gather(src, dest)
    else:
        for shared_ID in shared_IDs:
            src = g_shareds.gpuarrays[shared_ID]
            if comm_ID == BROADCAST:
                gpu_comm.broadcast(src, root=master_rank)
            elif comm_ID == REDUCE:
                gpu_comm.reduce(src, op=op, root=master_rank)
            elif comm_ID == ALL_REDUCE:
                gpu_comm.all_reduce(src, op=op, dest=src)
            elif comm_ID == GATHER:
                gpu_comm.all_gather(src)
            else:
                raise RuntimeError("Unrecognized GPU communication \
                    type in worker.")
        if comm_ID == ALL_REDUCE and avg:
            for shared_ID in shared_IDs:
                g_shareds.avg_functions[shared_ID]()

def do_cpu_comms(sync, g_shareds, rank):
    shared_ID = sync.shared_IDs[0]
    comm_ID = sync.comm_ID.value
    if comm_ID == SCATTER:
        if g_shareds.shmems[shared_ID] is None:
            g_shareds.alloc_shmem(shared_ID, rank, False)
        g_shareds.vars[shared_ID].set_value(g_shareds.shmems[shared_ID])
    else:
        raise RuntimeError("Unrecognized CPU comm type in worker.")

def error_close(sync):
    sync.workers_OK.value = False
    try:
        sync.barriers.exec_out.wait(1)
    except BrokenBarrierError:
        pass

def worker_exec(rank, n_gpu, master_rank, sync):
    gpu_comm = use_gpu(rank, n_gpu, sync, False)
    if not gpu_comm:
        return  # (exit quietly)

    distribution = receive_distribution(rank, n_gpu, sync)
    if not distribution:
        return  # (exit quietly)
    else:
        synk_functions, g_inputs, g_shareds = distribution

    Function.rank = rank  # endow all functions
    Function.master_rank = master_rank

    import atexit
    atexit.register(error_close, sync)

    while True:
        sync.barriers.exec_in.wait()
        if sync.quit.value:
            atexit.unregister(error_close)
            return  # (exit successfully)
        if sync.exec_type.value == FUNCTION:
            synk_functions[sync.func_ID.value](sync, g_inputs, gpu_comm)
        elif sync.exec_type.value == GPU_COMM:
            do_gpu_comms(sync, g_shareds, gpu_comm, master_rank)
        elif sync.exec_type.value == CPU_COMM:
            do_cpu_comms(sync, g_shareds, rank)
        else:
            raise RuntimeError("Unrecognized execution type in worker.")
        sync.barriers.exec_out.wait()  # Prevent premature shmem overwriting.


from plugin import Plugin

# import rpy if you use R
from rpy import *

# name your plugin according to the following notation :
# (end|iteration)_(optimum|all)_(type)
# for example : end_optimum_distribution
class end_optimum_value_successrate(Plugin):

    def __init__(self,data):
        # call the plugin basic initializations
        Plugin.__init__(self,data)

        # set the name of your plugin
        self.setName("end_optimum_value_successrate",
        "Plot the graph of success rates, considering a Test as a success when \
        the given precision of the problem is reached.")

    # necessary method, called when lauching the plugin
    def process(self):
        # uncomment this line if you use a R output
        self.outputInit()

        # put your plugin code here
        # the data are in self.data :
        #   self.data.color
        #   self.data.optimas
        #   self.data.pointsIter
        #   self.data.optimaIter
        #   ...

        slist = []
        slist = [t.succRate*100 for t in self.data.tests]
        r.plot(slist, type='n', main='Success rate for each test', xlab='Test index', ylab='Rate (%)')
        r.points(slist, pch = 21, type='h')
        r.points(slist, pch = 21)
        r.grid(nx=10, ny=40)

        # uncomment this line if you use a R output
        self.outputEnd()


import subprocess, sys

def pipInstall(package):
	subprocess.call([sys.executable, "-m", "pip", "install", package])

try:
	from freetype import *
except ImportError:
	pipInstall("freetype-py")
finally:
	from freetype import *

try:
	import numpy as np
except ImportError:
	pipInstall("numpy")
finally:
	import numpy as np

try:
	import OpenGL.GL as gl
	import OpenGL.GLU as glu
	import OpenGL.GLUT as glut
except ImportError:
	# pip by default fucks this up and installs 32 bit version.
	# However I have 64 bit python installed on my machine.
	# That is why we use pre-downloaded whl.
	# Make sure that the whl matches your python version.
	# For 32 bit python use 32 bit whl.
	pipInstall("PyOpenGL-3.1.6-cp39-cp39-win_amd64.whl")
	pipInstall("PyOpenGL_accelerate-3.1.6-cp39-cp39-win_amd64.whl")
finally:
	import OpenGL.GL as gl
	import OpenGL.GLU as glu
	import OpenGL.GLUT as glut

from serial_reader_thread import SerialReaderThread, Quat

import math

vertices= (
	(1, -1, -1),
	(1, 1, -1),
	(-1, 1, -1),
	(-1, -1, -1),
	(1, -1, 1),
	(1, 1, 1),
	(-1, -1, 1),
	(-1, 1, 1)
)

edges = (
	(0,1),
	(0,3),
	(0,4),
	(2,1),
	(2,3),
	(2,7),
	(6,3),
	(6,4),
	(6,7),
	(5,1),
	(5,4),
	(5,7)
)

surfaces = (
	(0,1,2,3),
	(3,2,7,6),
	(6,7,5,4),
	(4,5,1,0),
	(1,5,7,2),
	(4,0,3,6)
)

colors = (
	(255/255,0/255 ,0/255),  # red
	(255/255,99/255,71/255), # tomato
	(178/255,34/255,34/255), # firebrick
	(220/255,20/255,60/255), # crimson

	(0/255  ,128/255,0/255), # green
	(50/255 ,205/255,50/255), # lime green
	(0/255  ,255/255,127/255), # spring green
	(124/255,252/255,0/255), # lawn green

	(0/255  , 0/255 ,255/255), # blue
	(30/255 ,144/255,255/255), # dodger blue
	(100/255,149/255,237/255), # corn flower blue
	(65/255 ,105/255,225/255), # royal blue

	(255/255,165/255,0/255), # orange
	(255/255,215/255,0/255), # gold
	(240/255,230/255,140/255), # khaki
	(255/255,140/255,0/255), # dark orange

	(139/255,0/255,139/255), # magenta
	(128/255,0/255,128/255), # purple
	(148/255,0/255,211/255), # dark violet
	(255/255,20/255,147/255), # deep pink

	(0/255  ,255/255,255/255), # aqua
	(64/255 ,224/255,208/255), # turquoise
	(127/255,255/255,212/255), # aqua marine
	(0/255  ,206/255,209/255), # dark turquoise
)

class Window():
	def __init__(self, width, height, title):
		self.window = None
		self.base = 0
		self.texid = 0

		glut.glutInit(sys.argv)
		glut.glutInitDisplayMode(glut.GLUT_DOUBLE | glut.GLUT_RGB | glut.GLUT_DEPTH)
		self.window = glut.glutCreateWindow(title)
		glut.glutReshapeWindow(width, height)
		glut.glutDisplayFunc(self.on_display)
		glut.glutReshapeFunc(self.on_reshape)
		glut.glutKeyboardFunc(self.on_keyboard)

		gl.glTexEnvf(gl.GL_TEXTURE_ENV, gl.GL_TEXTURE_ENV_MODE, gl.GL_MODULATE)
		# gl.glEnable(gl.GL_DEPTH_TEST)
		# gl.glEnable(gl.GL_BLEND)
		gl.glEnable(gl.GL_COLOR_MATERIAL)
		gl.glColorMaterial(gl.GL_FRONT_AND_BACK, gl.GL_AMBIENT_AND_DIFFUSE)
		gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA)
		gl.glEnable(gl.GL_TEXTURE_2D)

		gl.glShadeModel(gl.GL_SMOOTH)
		gl.glClearColor(0, 0, 0, 0)
		gl.glClearDepth(1)
		gl.glEnable(gl.GL_DEPTH_TEST)
		gl.glDepthFunc(gl.GL_LEQUAL)
		gl.glHint(gl.GL_PERSPECTIVE_CORRECTION_HINT, gl.GL_NICEST)

		self.make_font("JetBrainsMono-Medium.ttf", 64)

		self.serial = SerialReaderThread()
		self.serial.start()

		glut.glutTimerFunc(25, self.timer_event, 1)

		glut.glutMainLoop()

	def __del__(self):
		if self.window is not None:
			glut.glutDestroyWindow(self.window)
			self.window = None
		self.serial.stopped = True
		self.serial.join()

	def timer_event(self, value):
		glut.glutPostRedisplay()
		glut.glutTimerFunc(25, self.timer_event, 1)

	def make_font(self, filename, size):
		# Load font  and check it is monotype
		face = Face(filename)
		face.set_char_size( size*64 )
		if not face.is_fixed_width:
			raise 'Font is not monotype'

		# Determine largest glyph size
		width, height, ascender, descender = 0, 0, 0, 0
		for c in range(32,128):
			face.load_char(chr(c), FT_LOAD_RENDER | FT_LOAD_FORCE_AUTOHINT)
			bitmap	= face.glyph.bitmap
			width	 = max( width, bitmap.width )
			ascender  = max( ascender, face.glyph.bitmap_top )
			descender = max( descender, bitmap.rows-face.glyph.bitmap_top )
		height = ascender+descender

		# Generate texture data
		Z = np.zeros((height*6, width*16), dtype=np.ubyte)
		for j in range(6):
			for i in range(16):
				face.load_char(chr(32+j*16+i), FT_LOAD_RENDER | FT_LOAD_FORCE_AUTOHINT)
				bitmap = face.glyph.bitmap
				x = i*width  + face.glyph.bitmap_left
				y = j*height + ascender - face.glyph.bitmap_top
				Z[y:y+bitmap.rows,x:x+bitmap.width].flat = bitmap.buffer

		# Bound texture
		self.texid = gl.glGenTextures(1)
		gl.glBindTexture(gl.GL_TEXTURE_2D, self.texid)
		gl.glTexParameterf(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_LINEAR)
		gl.glTexParameterf(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_LINEAR)
		gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_ALPHA, Z.shape[1], Z.shape[0], 0,
						gl.GL_ALPHA, gl.GL_UNSIGNED_BYTE, Z)

		# Generate display lists
		dx, dy = width/float(Z.shape[1]), height/float(Z.shape[0])
		self.base = gl.glGenLists(8*16)
		for i in range(8*16):
			c = chr(i)
			x = i%16
			y = i//16-2
			gl.glNewList(self.base+i, gl.GL_COMPILE)
			if (c == '\n'):
				gl.glPopMatrix()
				gl.glTranslatef( 0, -height, 0)
				gl.glPushMatrix()
			elif (c == '\t'):
				gl.glTranslatef(4*width, 0, 0)
			elif (i >= 32):
				gl.glBegin(gl.GL_QUADS)
				gl.glTexCoord2f((x  )*dx, (y+1)*dy), gl.glVertex(0,	 -height)
				gl.glTexCoord2f((x  )*dx, (y  )*dy), gl.glVertex(0,	 0 )
				gl.glTexCoord2f((x+1)*dx, (y  )*dy), gl.glVertex(width, 0 )
				gl.glTexCoord2f((x+1)*dx, (y+1)*dy), gl.glVertex(width, -height)
				gl.glEnd()
				gl.glTranslatef(width, 0, 0)
			gl.glEndList()

	def draw_text(self, text, x, y):
		gl.glEnable(gl.GL_BLEND)
		gl.glBindTexture(gl.GL_TEXTURE_2D, self.texid)
		gl.glColor(1,1,1,1) # white
		gl.glPushMatrix()
		gl.glTranslate(x, y, -5)
		gl.glPushMatrix()
		gl.glScalef(0.003, 0.003, 0.003)
		gl.glListBase(self.base)
		gl.glCallLists([ord(c) for c in text])
		gl.glPopMatrix()
		gl.glPopMatrix()
		gl.glBindTexture(gl.GL_TEXTURE_2D, 0)
		gl.glDisable(gl.GL_BLEND)

	def draw_cube_lines(self):
		gl.glBegin(gl.GL_LINES)
		gl.glColor3fv((0.1,0.1,0.1))
		for edge in edges:
			for vertex in edge:
				gl.glVertex3iv(vertices[vertex])
		gl.glEnd()

	def draw_cube_surfaces(self):
		gl.glBegin(gl.GL_QUADS)
		x = 0
		for surface in surfaces:
			for vertex in surface:
				gl.glColor3fv(colors[x])
				x+=1
				gl.glVertex3fv(vertices[vertex])
		gl.glEnd()

	def on_display(self):
		gl.glClearColor(0,0,0,0)
		gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT)

		gl.glLoadIdentity()
		gl.glTranslatef(0, 0, -7.0) # zoom out
		q = self.serial.quat
		degrees = 2 * math.acos(q.w) * 180.00/math.pi
		gl.glRotatef(degrees, -1 * q.nx, q.nz, q.ny)
		self.draw_cube_lines()
		self.draw_cube_surfaces()

		gl.glLoadIdentity()
		self.draw_text(f"Quat: {q.w:.3f}, {q.nx:.3f}, {q.ny:.3f}, {q.nz:.3f}", -2, -1.4)
		euler = self.serial.euler
		self.draw_text(f"Roll: {euler.roll:.1f}, Pitch: {euler.pitch:.1f}, Yaw: {euler.yaw:.1f}", -2, -1.65)

		glut.glutSwapBuffers()

	def on_reshape(self, width, height):
		if height == 0:
			height = 1

		aspect_ratio = width/height
		field_of_view = 45
		zNear = 0.1 #closer clipping plane
		zFar = 100.0 # further clipping plane

		gl.glViewport(0, 0, width, height)
		gl.glMatrixMode(gl.GL_PROJECTION)
		gl.glLoadIdentity()
		glu.gluPerspective(field_of_view, 1.0*aspect_ratio, zNear, zFar)
		gl.glMatrixMode(gl.GL_MODELVIEW)
		gl.glLoadIdentity()

	def on_keyboard(self, key, x, y):
		int_key = int.from_bytes(key, "little")
		if int_key == 27: # ESC key
			glut.glutDestroyWindow(self.window)
			self.window = None

if __name__ == '__main__':
	window = Window(800, 600, "Quat visualization")


import requests
import nlptest
import testing
from anytree import Node, RenderTree
from bs4 import BeautifulSoup

subdomain_limit = 3

def find_subdomains(url):
    source = requests.get(url).text
    soup = BeautifulSoup(source, 'lxml')

    texts = []

    for tag in soup.find_all('a'):
        link = tag.get('href',None)
        if link is not None and link.startswith('http') and not link.lower().endswith(('.pdf', '.gif')) and link not in texts:
            texts.append(link)
            if len(texts) == subdomain_limit:
                break
    return texts

def print_nodes(url):
    result = ""

    array = find_subdomains(url)
    root = Node(url)

    for i in range(len(array)):
        first_depth = Node(array[i], parent=root)
        array2 = find_subdomains(array[i])
        for j in range(len(array2)):
            second_depth = Node(array2[j], parent=first_depth)

    for pre, fill, node in RenderTree(root):
        result += pre + "" + node.name + "\n"

    return result

def find_all_keywords(url):

    result_dict = {}
    result_text = ""

    dict1 = nlptest.find_keywords_for_subdomains(result_dict, url)
    result_text += "#" + url + ":\n" + testing.format_text(dict1, 25) + "\n\n"

    urls = find_subdomains(url)

    for i in range(len(urls)):
        dict2 = nlptest.find_keywords_for_subdomains(result_dict, urls[i])
        result_text += "##" + urls[i] + ":\n" + testing.format_text(dict2, 25) + "\n\n"
        urls2 = find_subdomains(urls[i])
        for j in range(len(urls2)):
            dict3 = nlptest.find_keywords_for_subdomains(result_dict, urls2[j])
            result_text += "###" + urls2[j] + ":\n" + testing.format_text(dict3, 25) + "\n\n"

    return result_dict, result_text


h = input("input your height(m): ")
w = input("input your weight(kg): ")
height = float(h)
weight = float(w)
bmi = weight /(height*height)
print(bmi)
if bmi <18.5:
    print("too light")
elif bmi <25:
    print("normal")
elif bmi <28:
    print("too fat")
elif bmi <32:
    print("tooooooo fat")
else:
    print("suprise!!!you are the fatest ")


import os
from pytest_spark import spark_session

from ssp.spark.streaming.common.twitter_streamer_base import TwitterStreamerBase

def _get_test_spark_stream(spark_session):
    schema = TwitterStreamerBase._get_schema()
    test_files_path = "file:///" + os.path.abspath("data/streams/tweets/")
    sdf = spark_session.readStream.format("json").schema(schema).load(test_files_path)
    return sdf

def test_spark_stream(spark_session):
    sdf = _get_test_spark_stream(spark_session)
    count_acc = spark_session.sparkContext.accumulator(0)

    def foreach_batch_function(df, epoch_id, count_acc):
        # Transform and write batchDF
        count = df.count()

        count_acc += count

    sdf.writeStream.foreachBatch(lambda df, epoch_id :
                                 foreach_batch_function(df=df, epoch_id=epoch_id, count_acc=count_acc)).start().processAllAvailable()
    assert count_acc.value == 1000


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

"""
Andrés Fernández Burón
2023/10/04

Console game of 'Sink the fleet' with Python 3

File with Ship and Fleet classes for the game.
"""

# DEPENDENCIES

import numpy as np

# SUBMODULES
from .config import *
from .consts import *

############################################
#### GAME FLEET ############################
############################################

class Ship:
    ''' Ship class definition '''

    def __init__( self, large:int ):
        ''' Ship class constructor '''
        self.large = large

        empty_data = [ tuple([0,0]) for i in range( large ) ]
        self.location = np.array( empty_data ).astype( tuple )

    # METHODS:

    def ubicate( self, location ):
        ''' Update ship location in the class variable '''
        if type(location) == list:
            self.location = np.array( location )

        elif type(location) == np.array:
            self.location = location

class Fleet:
    ''' Fleet class definition '''

    def __init__( self ):
        ''' Fleet class constructor '''
        self.initialize()

    # METHODS:

    def initialize( self ):
        ''' Initialize the ship array '''
        ship_buffer = []
        for i in range( SHIPS_SIZES_COUNT ):
            large = SHIPS_SIZES_COUNT - i
            ship_count = i + 1

            for j in range( ship_count ):
                ship = Ship(large)
                ship_buffer.append( ship )

        self.ship_list = np.asarray( ship_buffer )
        self.count = len( self.ship_list )

    def get_ship_location( self, coordinates:tuple ):
        ''' Get a ship location of the fleet '''
        for i in range( self.ship_list.size ):
            for coord_arr in self.ship_list[i].location:

                mask = ( coord_arr == coordinates )

                if np.any( coord_arr[ mask ] ):
                    return self.ship_list[i].location


import pandas as pd
from sklearn.ensemble import RandomForestClassifier

# Load the training data
df = pd.read_csv('golf_ball_data.csv')

# Split the data into features and labels
X = df[['gender', 'handicap', 'driver_ball_speed', 'price_range']]
y = df['recommended_ball']

# Train a random forest classifier on the data
model = RandomForestClassifier()
model.fit(X, y)

# Ask the user for their information
gender = input('What is your gender (male/female)? ')
handicap = int(input('What is your golf handicap? '))
driver_ball_speed = int(input('What is your driver ball speed (in mph)? '))
price_range = int(input('What is your price range (1-5)? '))
current_ball = input('What golf ball do you currently use? ')
like_current_ball = input('Do you like your current golf ball (yes/no)? ')

# If the user likes their current golf ball, add it to the training data
if like_current_ball == 'yes':
    new_data = {'gender': [gender], 'handicap': [handicap], 'driver_ball_speed': [driver_ball_speed], 'price_range': [price_range], 'recommended_ball': [current_ball]}
    new_df = pd.DataFrame(data=new_data)
    df = df.append(new_df, ignore_index=True)
    X = df[['gender', 'handicap', 'driver_ball_speed', 'price_range']]
    y = df['recommended_ball']
    model.fit(X, y)

# Make a prediction based on the user's information
prediction = model.predict([[gender, handicap, driver_ball_speed, price_range]])

# Recommend a golf ball to the user
print(f'We recommend using the {prediction[0]} golf ball.')


import argparse
import json
import re

from app_config import config
from qcs import qcsapi

parser = argparse.ArgumentParser(description="Braspag qualys integration to evaluate images in CI pipeline")
parser.add_argument("--imageid", nargs="+", help="image Id to be evaluated")
parser.add_argument("--config", nargs=1, help="JSON file to be processed", type=argparse.FileType("r"))
arguments = parser.parse_args()

# Loading arguments
image_id = arguments.imageid[0]
config_arg = json.load(arguments.config[0])
qid_list = config_arg["qid"]
severity_toblock = config_arg["severity"]
vulncount = config_arg["vulncount"]

# Check Image Pattern
imagepattern = re.compile(r"([0-9a-z]{12})")
if imagepattern.match(image_id):
    pass
else:
    raise Exception("Provide a valid Image ID")

# check CVE Pattern
cve_list = []
cvepattern = re.compile(r"CVE-\d{4}-\d{4,7}")
for each in config_arg["cves"]:
    if cvepattern.match(each):
        cve_list.append(each)
    else:
        raise Exception("Invalid cve pattern")

# Creds for Api Access
creds = config.get_config()

# get url to build
url_builder = qcsapi.UrlBuilder()

# Api Call
con = qcsapi.QualysImages(creds, url_builder)
resp = con.GetByImageId(image_id)

# Valuation by severity
valuation = qcsapi.PolicyValuation.ValuationBySeverity(resp)

# Remove Sensor
# sensor_con = qcsapi.QualysSensor(creds, url_builder)
# Remove Sensor with Type CI/CD
# sensor_resp = sensor_con.RemoveSensorByType()

# sensor_uuid = ["fc9ff560-b3af-4f9d-8206-7cb5a6398a39"]
# sensor_resp = sensor_con.RemoveBySensoruuId(sensor_uuid)


from flask import Flask, request, jsonify, Markup
from pyslinger import pyslinger
import simplejson as json
from markdown import markdown

app = Flask(__name__)

@app.route('/', methods=['GET', 'POST'])
def load_item():
    if request.method == 'GET':
        # show usage docs
        return Markup(markdown(open('README.md').read()))
    if request.method == 'POST' and 'payload' in request.files:

        # Update any pyslinger constants passed
        # cq_server, username, password, static_root
        for field in request.form:
            setattr(pyslinger, field.upper(), request.form[field])

        payload = json.load(request.files['payload'])
        result = pyslinger.load_item(payload)
        return jsonify(result)

if __name__ == "__main__":
    app.run()


import numpy as np
from matplotlib import pyplot as plt
from .CurveBase import CurveBase
import abc
import pdb
import Curves.Bezier as Bezier
from dataclasses import dataclass
from typing import Callable

import minisam

@dataclass
class FlightSpec:
    vec2state: Callable = lambda x: x

class FlightOptParams:
    def __init__(self, dt = 0.01, Wcurv = 0, Wlen=0, Wagree = 0, Wspdev = 1, Wkdev = 0, rho = 0.001, init = None, final = None):

        self.dt = dt

        self.Wcurv  = Wcurv
        self.Wlen   = Wlen
        self.Wagree = Wagree
        self.Wspdev = Wspdev
        self.Wkdev  = Wkdev
        self.rho    = rho
        self.init = init
        self.final = final

class BezierCurveFactor(minisam.NumericalFactor):
    def __init__(self, key, start, end, order, duration, loss=None, optParams=FlightOptParams()):
        minisam.NumericalFactor.__init__(self, 1, [key], loss)
        self._start = start
        self._end = end
        self._order = order
        self.lossFunction = loss
        self.optParams = optParams
        self.dimension = len(self._start.getTranslation())
        self.duration = duration

    # make a deep copy
    def copy(self):
        return BezierCurveFactor(self.keys()[0], self._start, self._end, self._order, self.duration, self.lossFunction, self.optParams)

    # error = Bezier cost function
    def error(self, variables):
        my_params = variables.at(self.keys()[0])
        params = np.empty((self.dimension*(self._order-3) + 2, ))
        if(self.optParams.init != None and self.optParams.final == None):
            params[0] = self.duration*(self.optParams.init/self._order)
            params[1:] = my_params
        elif(self.optParams.init != None and self.optParams.final != None):
            params[0] = self.duration*(self.optParams.init/self._order)
            params[1] = self.duration*(self.optParams.final/self._order)
            params[2:] = my_params
        else:
            params = my_params
        b = Bezier.constructBezierPath(self._start, self._end, self._order, params)
        return np.array([Flight.BezierCostFunction(b, self.optParams)])

class TimePolyFactor(minisam.NumericalFactor):
    def __init__(self, key, curve, minSpd, maxSpd, maxGs, loss, ts, tf):
        minisam.NumericalFactor.__init__(self, 1, [key], loss)
        self._curve = curve
        self._minSpd = minSpd
        self._maxSpd = maxSpd
        self._maxGs = maxGs
        self._loss = loss
        self._ts = ts
        self._tf = tf

    # make a deep copy
    def copy(self):
        return TimePolyFactor(self.keys()[0], self._curve, self._minSpd, self._maxSpd, self._maxGs, self._loss, ts=self._ts, tf=self._tf)

    # error = Bezier cost function
    def error(self, variables):
        my_params = variables.at(self.keys()[0])
        coeffs = Flight.gen5thTimePoly(my_params, self._tf - self._ts)
        cost = Flight.TimeCostFunction(self._curve, coeffs, self._minSpd, self._maxSpd, self._maxGs, [self._ts, self._tf])
        return np.array([cost])

class Flight(CurveBase):
    def __init__(self, startPose, endPose, tspan = [0, 1], bezierOrder=3, optParams=FlightOptParams(), spec=FlightSpec()):
        super().__init__(tspan)
        self.startPose = startPose
        self.endPose = endPose
        self.bezier = Bezier(bezierOrder)
        self.tspan = tspan
        self.duration = tspan[1] - tspan[0]
        self.optParams = optParams
        self.timePolyCoeffs = np.array([0, 0, 0, 0, 1/(tspan[1]-tspan[0]), 0]) # By default, polynomial does not change s input
        self.spec = spec

        #self.dimension = len(startPose.getTranslation())

    def constructBezierPath(self, param):
        # Changes based on dimension
        #constructBezierPath uses parameterization to define bezier curve
        pts = np.empty((self.dimension,self.bezier.order+1))
        unit = np.zeros(self.dimension,)
        unit[0] = 1

        if(self.bezier.order == 3): # 3rd Order curve with 2 free points
            pos2 = self.startPose * ( param[0] * unit)
            pos3 = self.endPose   * (-param[1] * unit)
            pts = np.hstack((self.startPose.getTranslation(), pos2, pos3, self.endPose.getTranslation()))

        elif(self.bezier.order > 3):
            d1 = self.startPose * ( param[0] * unit)
            posmid = np.reshape(param[2:], (self.dimension, self.bezier.order-3))
            d2 = self.endPose   * (-param[1] * unit)
            pts = np.hstack((self.startPose.getTranslation(), d1, posmid, d2, self.endPose.getTranslation()))

        self.bezier.setControlPoints(pts)

    def optimizeBezierPath(self):
        if(self.bezier.order == 3 and self.optParams.init != None and self.optParams.final != None):
            self.bezier = Bezier.constructBezierPath(self.startPose, self.endPose,
                self.bezier.order, self.duration*np.array([self.optParams.init/self.bezier.order, self.optParams.final/self.bezier.order]))
        else:
            graph=minisam.FactorGraph()
            #loss = minisam.CauchyLoss.Cauchy(0.) # TODO: Options Struct
            loss= None
            graph.add(BezierCurveFactor(minisam.key('p', 0), self.startPose, self.endPose, self.bezier.order, self.duration, loss, optParams=self.optParams))

            init_values = minisam.Variables()

            opt_param = minisam.LevenbergMarquardtOptimizerParams()
            #opt_param.verbosity_level = minisam.NonlinearOptimizerVerbosityLevel.ITERATION
            opt = minisam.LevenbergMarquardtOptimizer(opt_param)
            values = minisam.Variables()

            linePts = self.startPose.getTranslation() + \
                np.arange(0,1+1/(self.bezier.order),1/(self.bezier.order))*(self.endPose.getTranslation()- self.startPose.getTranslation())
            #pdb.set_trace()

            if(self.optParams.init != None and self.optParams.final == None):
                # TODO: Initial Conditions
                initialGuess = np.hstack((linePts[3:-2].reshape((1,-1)), 1))
                #init_values.add(minisam.key('p', 0), np.ones((1+self.dimension*(self.bezier.order-3),)))
                init_values.add(minisam.key('p', 0), initialGuess)

                opt.optimize(graph, init_values, values)
                d = np.array([self.optParams.init/ self.bezier.order])
                self.bezier = Bezier.constructBezierPath(self.startPose, self.endPose,
                    self.bezier.order, np.hstack((d, values.at(minisam.key('p', 0)))))

            elif(self.optParams.init != None and self.optParams.final != None):
                print("Both Constrained")
                initialGuess = linePts[:,2:-2].reshape((1,-1))
                d =  self.duration*np.array([self.optParams.init/ self.bezier.order, self.optParams.final / self.bezier.order])
                unit = np.zeros((self.dimension))
                unit[0] = 1
                pos2 = self.startPose * (d[0] * unit)
                pos3 = self.endPose * (-d[1] * unit)
                v = (pos3 - pos2) / (self.bezier.order - 2)
                initialGuess = pos2 + np.multiply(np.arange(1,self.bezier.order-3+1), v)
                initialGuess = initialGuess.reshape((1,-1))
                init_values.add(minisam.key('p', 0), np.squeeze(initialGuess))
                #init_values.add(minisam.key('p', 0), np.ones((self.dimension*(self.bezier.order-3),)))

                opt.optimize(graph, init_values, values)
                #pdb.set_trace()
                self.bezier = Bezier.constructBezierPath(self.startPose, self.endPose,
                    self.bezier.order, np.hstack((d,values.at(minisam.key('p', 0)))))
            else:
                initialGuess = np.hstack((linePts[3:-2].reshape((1,-1))))
                #init_values.add(minisam.key('p', 0), np.ones((2+self.dimension*(self.bezier.order-3),)))
                init_values.add(minisam.key('p', 0), initialGuess)

                opt.optimize(graph, init_values, values)
                self.bezier = Bezier.constructBezierPath(self.startPose, self.endPose,
                    self.bezier.order, values.at(minisam.key('p', 0)))

    @staticmethod
    def gen5thTimePoly(cVec, td):
        if(td != 0):
            b = np.array([0, 1-cVec[0]*td**2 - cVec[1]*td**3, 1/td , 1/td -2*cVec[0]*td - 3*cVec[1]*td**2])
            b = np.reshape(b, (4,1))
            A = np.array([
            [1, 0, 0, 0],
            [1, td, td**4, td**5],
            [0, 1, 0, 0],
            [0, 1, 4*td**3, 5*td**4],
            ])
            beta = np.matmul(np.linalg.inv(A), b)

            beta = beta.T
            beta = np.squeeze(beta)
            coeffs = np.flip(np.hstack((beta[0:2], cVec, beta[2:4])))
            return coeffs
            #self.timePolyCoeffs = fliplr(obj.timePolyCoeffs);
        else:
            return np.zeros((6,))

    def setDynConstraints(self, minSpd, maxSpd, maxGs):
        self.minSpd = minSpd
        self.maxSpd = maxSpd
        self.maxGs = maxGs

    def optimizeTimePoly(self):
        graph=minisam.FactorGraph()
        #loss = minisam.CauchyLoss.Cauchy(0.) # TODO: Options Struct
        loss= None
        graph.add(TimePolyFactor(minisam.key('p', 0), self.bezier, self.minSpd, self.maxSpd, self.maxGs, loss, ts=self.tspan[0], tf= self.tspan[1]))

        init_values = minisam.Variables()

        opt_param = minisam.LevenbergMarquardtOptimizerParams()
        #opt_param.verbosity_level = minisam.NonlinearOptimizerVerbosityLevel.ITERATION
        opt = minisam.LevenbergMarquardtOptimizer(opt_param)
        values = minisam.Variables()
        init_values.add(minisam.key('p', 0), np.ones((2,)))

        opt.optimize(graph, init_values, values)
        self.timePolyCoeffs = Flight.gen5thTimePoly(values.at(minisam.key('p', 0)), self.duration)

    # In this function we use the time polynomial to "Stretch" s which is progress from 0-1
    def evalTimePoly(self, t):
        s = np.polyval(self.timePolyCoeffs, t)
        #pdb.set_trace()
        dsdt = np.polyval(np.polyder(self.timePolyCoeffs), t)
        d2sdt2 = np.polyval(np.polyder(self.timePolyCoeffs, 2), t)
        return s, dsdt, d2sdt2

    # t is real time here. The time polynomial gives progress (s) to input into bezier eval
    def evalPos(self, t):
        (s, dsdt, _) = self.evalTimePoly(t-self.tspan[0])
        return self.bezier.eval(s)

    # same as evalPos but for velocity
    def evalVel(self, t):
        (s, dsdt, _) = self.evalTimePoly(t-self.tspan[0])
        _, vs = self.bezier.evalJet(s)
        v = vs * dsdt
        return v

    # same as evalPos but for velocity
    def evalAcc(self, t):
        (s, dsdt, d2sdt2) = self.evalTimePoly(t-self.tspan[0])
        xs, vs, accs = self.bezier.evalJet2(s)
        a = accs * (dsdt**2) + vs*d2sdt2
        return a

    def x(self, t):
        return self.spec.vec2state(np.vstack((self.evalPos(t), self.evalVel(t), self.evalAcc(t))))

    def plotControlPoints(self, axes=None):
        self.bezier.plot(axes)

    @abc.abstractmethod
    def plotCurve(self, axes=None):
        return

    @staticmethod
    def BezierCostFunction(path:Bezier, optParams:FlightOptParams):
        # Cost function of 4 terms: total curvature, curvature variance, length, and speed variance
        t = np.arange(0, 1+optParams.dt, optParams.dt) # time step for evaulating cost

        cost = 0

        _, v = path.evalJet(t)
        speeds = np.linalg.norm(v, 2, 0)
        k = path.evalCurv(t)

        if(optParams.Wlen > 0):
            pathLength = optParams.dt*np.nansum(speeds)
            cost += optParams.Wlen * pathLength

        if(optParams.Wcurv > 0):
            totalCurv = np.nansum(np.power(k,2))
            cost += optParams.Wcurv * totalCurv

        if(optParams.Wkdev > 0):
            curvDev = np.nanvar(k, ddof=1)
            cost += optParams.Wkdev * curvDev

        if(optParams.Wspdev > 0):
            spddev = np.nanvar(speeds, ddof=1)
            cost += optParams.Wspdev * spddev

        if(optParams.Wagree > 0):
            startVec = path.Q[:,1] - path.Q[:,0]
            endVec = path.Q[:,3] - path.Q[:,2]

            startAngle = np.arctan2(startVec[1], startVec[0])
            endAngle = np.arctan2(endVec[1], endVec[0])
            angles = np.linspace(startAngle, endAngle, np.shape(t)[0])
            vecs = np.vstack((np.cos(angles),np.sin(angles)))
            ramp = np.linspace(1, 0, int(len(t)/10))
            weight = np.concatenate((ramp, np.zeros((np.shape(t)[0] - 2*np.shape(ramp)[0])), np.flip(ramp)))

            agree = np.sum(angles*weight*v/(speeds + optParams.rho))
            cost += optParams.Wkdev * agree

        #print(cost)
        #pdb.set_trace()
        return cost

    @staticmethod
    def TimeCostFunction(path:Bezier, timePolyCoeffs, minSpd, maxSpd, maxGs, tspan):
        # Cost function of 4 terms: total curvature, curvature variance, length, and speed variance
        dt = 0.01
        t = np.arange(0, tspan[1]-tspan[0], dt) # time step for evaulating cost
        tau = np.polyval(timePolyCoeffs, t)
        tauPrime = np.polyval(np.polyder(timePolyCoeffs), t)

        _, v = path.evalJet(tau)
        speeds = np.linalg.norm(v, 2, 0) * tauPrime # Speed in real units

        cost = 0

        k = path.evalCurv(tau) # Curvature
        ac = np.power(speeds,2)*k # Centripetal Acceleration

        Wvel = 100
        Wk = 5

        if(Wvel > 0):
            cost += Wvel*np.sum(np.power(speeds - 0.5*(minSpd + maxSpd), 2))

        if(Wk > 0):
            cost += Wk * np.sum(np.power(ac, 2))

        return cost


__version__ = '0.0.8'

import sys
from getpass import getpass
import re

# Fix python 2.x
try:
    input = raw_input
except NameError:
    pass

# https://www.siafoo.net/snippet/88
# or http://stackoverflow.com/questions/287871/print-in-terminal-with-colors-using-python
def highlight(string, status):
    if sys.stdout.isatty():
        mods = {
            'yellow': '33',
            'green': '32',
            'red': '31',
            'bold': '1',
        }
        attr = []
        if status == 'error':
            attr.append(mods['red'])
            attr.append(mods['bold'])

        elif status == 'msg':
            attr.append(mods['green'])

        elif status == 'notice':
            attr.append(mods['yellow'])

        return '\x1b[%sm%s\x1b[0m' % (';'.join(attr), string)
    else:
        return string

def print_error():
    error = 'Invalid input, please try again'
    print(highlight(error, 'error'))

def buildText(question, possibilities, default):
    text = ""
    if question:
        text += question + " "

    if possibilities:
        text += "("
        for p in possibilities:
            text += str(p) + "/"
        text = text[:-1]
        text += ") "

    if default or default == '':
        if default == '':
            text += "['']"

        else:
            text += "[" + default + "]"

    if text == "":
        return text

    else:
        return text.rstrip(" ") + "\n"

def checkInt(i):
    try:
        int(i)
    except ValueError:
        return False

    return True

def checkChar(ch):
    if len(ch) == 1 and ch.lower() in 'abcdefghijklmnopqrstuvwxyz':
        return True

def checkString(string):
    for c in string:
        if c.lower() not in 'abcdefghijklmnopqrstuvwxyz':
            return False

    return True

def checkEmail(email):
    if re.match(r".+\@.+\..+", email):
        return True

def checkNone(i):
    return True

def _ask(text, possibilities, default, check_method, masked=False):
    while True:
        if masked:
            i = getpass(buildText(text, possibilities, default))
        else:
            i = input(buildText(text, possibilities, default))

        if i == '':
            if default or default == '':
                return default
            else:
                print_error()
                continue

        elif possibilities:
            if i in possibilities:
                return i
            else:
                print_error()
                continue

        else:
            if check_method(i):
                return i
            else:
                print_error()
                continue

def askInt(text=None, possibilities=None, default=None):
    return _ask(text, possibilities, default, checkInt)

def askChar(text=None, possibilities=None, default=None):
    return _ask(text, possibilities, default, checkChar)

def askBool(text=None, possibilities=None, default=None):
    if not possibilities:
        possibilities = ['y', 'n']
    answers = {
        'True': ['y', 'yes', 'j', 'ja'],
        'False': ['n', 'no', 'nein']
    }

    a = _ask(text, possibilities, default, checkChar)
    if a in answers['True']:
        return True
    elif a in answers['False']:
        return False
    else:
        return a

def askString(text=None, possibilities=None, default=None):
    return _ask(text, possibilities, default, checkString)

def askEmail(text=None, possibilities=None, default=None):
    return _ask(text, possibilities, default, checkEmail)

def askPassword(text=None, possibilities=None, default=None):
    return _ask(text, possibilities, default, checkNone, masked=True)

def ask(text=None, possibilities=None, default=None):
    return _ask(text, possibilities, default, checkNone)

def explain(credit=False):
    instructions = "Attention: Input prompts follow this template:\n" \
                   "\"Question (answer1, answer2, answer3) [default_answer]\"\n" \
                   "(You can just hit enter to chose the default answer)"
    credits = "[Powered by ask (www.github.com/Chive/ask)]"

    print(highlight(instructions, 'msg'))
    if credit:
        print(highlight(credits, 'notice'))


import pickle
import socket
from server.server import Server
from logger.logger import Logger
from threading import Thread

from communicators.client_server_communicator import ClientServerCommunicator
from communicators.infectivity_tester_communicator import InfectivityTesterCommunicator
from packages.client_package import Package as ClientPackage
from packages.client_package import PackageType as ClientPackageType
from packages.infectivity_request import *
from packages.infectivity_response import *
from network.client import Client

class ClientTester(Server):
    __DEFAULT_PORT_CLIENTS = 5004

    def __init__(self,host:str,port:int,logger:Logger):
        super().__init__(host,port,logger)
        self.__workers = set()

    def __send_infectivity_response(self,response:InfectivityResponse):
        manager = InfectivityTesterCommunicator("127.0.0.1",5004,self._logger)
        manager.connect()
        manager.send_response(response)
        manager.close_connection()

    def __process_request(self,client_socket:socket):
        if client_socket is None:
            return
        host, _ = client_socket.getpeername()
        if host == "127.0.0.1" or host == "192.168.1.2":
            request = InfectivityTesterCommunicator.read_data(client_socket)
            self._logger.info("Request received")
            response = None
            if request.type == InfectivityRequestType.CHECK_CLIENT:
                host = request.payload[0]
                self._logger.info("Request of type CHECK_CLIENT for %s"%(host))
                client = Client(host, ClientTester.__DEFAULT_PORT_CLIENTS, self._logger)
                res = client.connect()
                if res == 0:
                    self._logger.info("Connection to %s established" %(host))
                    resp = client.send_test_package()
                    if resp is not None and client.check_for_valid_test_package(resp):
                        response = InfectivityResponse(InfectivityResponseType.STATUS_AVAILABLE,[host])
                        self._logger.info("Host %s check status valid" % (host))
                    else:
                        response = InfectivityResponse(InfectivityResponseType.STATUS_UNAVAILABLE, [host])
                        self._logger.info("Host %s check status invalid" % (host))
                else:
                    response = InfectivityResponse(InfectivityResponseType.STATUS_UNAVAILABLE, [host])
                    self._logger.info("Host %s is unreachable" % (host))
                InfectivityTesterCommunicator.send_data(client_socket,response)
                client.close_connection()

            if request.type == InfectivityRequestType.SCAN_CLIENT:
                host = request.payload[0]
                self._logger.info("Request of type SCAN_CLIENT for %s" % (host))
                client = Client(host, ClientTester.__DEFAULT_PORT_CLIENTS, self._logger)
                res = client.connect()
                if res == 0:
                    self._logger.info("Connection to %s established" % (host))
                    resp = client.send_scan_package()
                client.close_connection()
            if request.type == InfectivityRequestType.ARE_YOU_AWAKE:
                pack = InfectivityResponse(InfectivityResponseType.I_AM_AWAKE, [])
                InfectivityTesterCommunicator.send_data(client_socket, pack, self._logger)
                client_socket.close()
        else:
            request = ClientServerCommunicator.read_data(client_socket)
            self._logger.info("Request foreign received")
            response = None
            if request.type == ClientPackageType.RESULTS:
                results = request.payload
                response = InfectivityResponse(InfectivityResponseType.TEST_RESULTS, [host,results])
                self.__send_infectivity_response(response)
        client_socket.close()

        #case for SCAN_CLIENT
        #self.__send_infectivity_response(response)

    def __clear_finished_workers(self):
        to_clear=[]
        for worker in self.__workers:
            if not worker.is_alive():
                worker.join()
                to_clear.append(worker)
        for elim in to_clear:
            self.__workers.remove(elim)

    def handle_request(self, client_socket: socket):
        th = Thread(target = self.__process_request,args=(client_socket,))
        try:
            self.__clear_finished_workers()
        except Exception as e:
            self._logger.info("Error while cleaning thread: %s" %(e))
        self._logger.info("Finished workers cleared")
        self.__workers.add(th)
        self._logger.info("Thread created")
        th.start()
        self._logger.info("Thread %s started" % (th.native_id))


import dpath
max = 100000
disk = 70000000
needed = 30000000

with open('./input', 'r') as f:
    lines = [line[:-1] for line in f]

sizes = {}
counted = []
wd = ''
fs = {'root': {'_size': 0}}

def get(p):
    return dpath.get(fs, p)

def sets(p, v):
    dpath.new(fs, p, v)

def cd(p):
    global wd
    if p == '..':
        wd = '/'.join(wd.split('/')[:-1])
    elif p == '/':
        wd = 'root'
    else:
        wd = wd + '/' + p

def cont(p):
    a, b = p.split(' ')
    if a == 'dir':
        try:
            dpath.get(wd + '/' + b)
        except:
            sets(wd + '/' + b, {'_size': 0})
    else:
        if wd + '/' + b in counted:
            return
        counted.append(wd + '/' + b)
        recursiz(wd + '/' + p, int(a))

def recursiz(p, n):
    pth = 'root'
    for chnk in p.split('/')[1:]:
        sz = get(pth + '/_size') + n
        sets(pth + '/_size', sz)
        sizes[pth] = sz
        pth += '/' + chnk

for line in lines:
    if line == 'ls':
        continue
    if line.startswith('$ cd'):
        cd(line.split(' ')[2])
    elif line[0] == '$':
        continue
    else:
        cont(line)

total = 0
for k, v in sizes.items():
    if v <= max:
        total += v
print('part 1:', total)

for sois in sorted(sizes.values()):
    if sois >= needed - (disk - get('root/_size')):
        print('part 2:', sois)
        break


import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
import statsmodels.api as sm
from sklearn.linear_model import LinearRegression
from sklearn import datasets
diabetes=datasets.load_diabetes()
#print (diabetes.data.shape)
#print (diabetes.target.shape)
#print (diabetes.feature_names)
feature_cols=diabetes.feature_names
#diabetes=pd.DataFrame(diabetes)
#print (diabetes.iloc[0:100,:])
from sklearn.model_selection import train_test_split
X_train,X_test,y_train,y_test=train_test_split(diabetes.data,diabetes.target,test_size=0.2,random_state=0)
#print(X_train)
model=LinearRegression()
model.fit(X_train,y_train)
print ("Model_Score or R-Squared",model.score(X_test,y_test))
print ("Model_Quotients",model.coef_)
print ("Model Intercept",model.intercept_)
#To View featurewise model co-efficients
A=list(zip(feature_cols,model.coef_))
print("Feature wise co-efficients",A)
#print(model.predict(X_test))
y_pred=model.predict(X_test)
plt.plot(y_test,y_pred,".")
x = np.linspace(0, 330, 100)
y = x
plt.plot(x, y)
#plt.show()
from sklearn import metrics
#Absolute Mean Squared Error
print("Absolute_Mean_Squared_Error",metrics.mean_absolute_error(y_test,y_pred))
#Mean Squared Error
print("Mean_Squared_Error",metrics.mean_squared_error(y_test,y_pred))
#Root Mean squared error
print("RMSE",np.sqrt(metrics.mean_squared_error(y_test,y_pred)))

#To get r_squared and adjusted_r_squared
SS_Residual = sum((y_test-y_pred)**2)
SS_Total = sum((y_test-np.mean(y_test))**2)
r_squared = 1 - (float(SS_Residual))/SS_Total
print (r_squared,"r_squared")
adjusted_r_squared = 1 - (1-r_squared)*(len(y_test)-1)/(len(y_test)-X_train.shape[1]-1)
print(adjusted_r_squared,"adjusted_r_squared")

#shapes
print(X_train.shape[0])#rows
print(X_train.shape[1])#columns

#To check the significant variables
X2 = sm.add_constant(X_train)
est = sm.OLS(y_train, X2)
est2 = est.fit()
print(est2.summary())

#Calculate ViF
from statsmodels.stats.outliers_influence import variance_inflation_factor
X_train=pd.DataFrame(X_train)
vif=pd.DataFrame()
vif["Vif Factor"] = [variance_inflation_factor(X_train.values, i) for i in range(X_train.shape[1])]
vif["Features"]=X_train.columns
print (vif.round(1))


class BingoNumber:
    def __init__(self, num: int):
        self.number = num
        self.marked = False

    def mark_if(self, num: int):
        if self.number == num:
            self.marked = True

    def mark(self):
        self.marked = True

    def __repr__(self):
        if self.marked:
            return f'<{str(self.number).rjust(2, " ")}>'
        else:
            return f'[{str(self.number).rjust(2, " ")}]'

    def __bool__(self):
        return self.marked

class Board:
    def __init__(self):
        self.board = []

    def add_row(self, row: list):
        new_row = []
        for num in row:
            new_row.append(BingoNumber(num))
        self.board.append(new_row)

    def mark_number(self, num: int):
        for row in self.board:
            for number in row:
                number.mark_if(num)

    def won_row(self, row: int):
        return all([bool(num) for num in self.board[row]])

    def won_column(self, column: int):
        return all([bool(row[column]) for row in self.board])

    @property
    def unmarked(self):
        nums = []
        for row in self.board:
            for number in row:
                if not number:
                    nums.append(number.number)
        return nums

    @property
    def has_won(self):
        rows = any([self.won_row(i) for i in range(len(self.board))])
        columns = any([self.won_column(i) for i in range(len(self.board[0]))])
        return any([rows, columns])

    def __repr__(self):
        s = ''
        for row in self.board:
            for number in row:
                s += str(number)
            s += '\n'
        return s[:-1]

numbers = []
boards = []
current_board = Board()
for line in open('day4.txt'):
    line = line.strip()

    if not numbers:
        numbers = [int(n) for n in line.split(',')]
        continue

    if len(line) == 0 and len(current_board.board) > 0:
        boards.append(current_board)
        current_board = Board()
        continue

    if len(line) > 0:
        row = [int(n) for n in line.split()]
        current_board.add_row(row)
boards.append(current_board)

num_boards = len(boards)
part = 1
for num in numbers:
    for board in boards:
        board.mark_number(num)
        if board.has_won:
            if len(boards) in (num_boards, 1):
                print(board)
                print(f'Part {part}: {sum(board.unmarked)} * {num} = {sum(board.unmarked) * num}')
                print()
                part += 1
            boards = [b for b in boards if b is not board]


# podział zbioru
random.seed(42)

train_fraction   = 0.6
validation_fraction   = 0.9 - train_fraction
test_fraction   = 0.1

random_list = random.sample(range(1, len(df) + 1), len(df))
sample_list = np.divide(random_list, len(df))

train_data         = df[(sample_list <= 1) & (sample_list > 1 - train_fraction)]
validation_data    = df[(sample_list <= 1 - train_fraction) & (sample_list > test_fraction)]
test_data          = df[(sample_list <= test_fraction) & (sample_list >= 0)]

print(len(train_data), len(validation_data), len(test_data), len(train_data) + len(validation_data) + len(test_data) == len(df))

train_data_indices = np.random.choice(df.index, len(train_data), replace = False)
train_data = train_data.append(df.loc[train_data_indices]).sort_index()

df = pd.concat([df, df.loc[train_data_indices]]).drop_duplicates(keep=False)

validation_data_indices = np.random.choice(df.index, len(validation_data), replace = False)
validation_data = validation_data.append(df.loc[validation_data_indices]).sort_index()

df = pd.concat([df, df.loc[validation_data_indices]]).drop_duplicates(keep=False)

test_data_indices = np.random.choice(df.index, len(test_data), replace = False)
test_data = test_data.append(df.loc[test_data_indices]).sort_index()

df = pd.concat([train_data, validation_data, test_data]).sort_index()

print(len(set(test_data.index)) == len(test_data.index))
print(len(set(train_data.index)) == len(train_data.index))
print(len(set(validation_data.index)) == len(validation_data.index))

print(test_data['rain_tomorrow'].sum()*2 == len(test_data))
print(validation_data['rain_tomorrow'].sum()*2 == len(validation_data))
print(test_data['rain_tomorrow'].sum()*2 == len(test_data))

print(len(train_data), len(validation_data), len(test_data), len(train_data) + len(validation_data) + len(test_data) == len(df))
print(len(df))


"""
    Description: Data Preprocessing
    Author: Jimmy Lu
    Date: March 2022
"""
from nltk.tokenize import WordPunctTokenizer
from word_sequence import Word2Sequence
import config
from torch.utils.data import Dataset, DataLoader
import torch

def txt_to_wordlist(path):
    """
    Args:
        path (str): File storing text data
    Purpose:
        Preprocess words in the text file to list of words
    Returns:
        A list of all words in the file from path
    """
    text = open(path).readlines()
    seq_dict = {}
    temp_sequence = []
    count = 0
    for i in range(len(text)):
        if text[i] != "\n":
            temp_sequence += [text[i]]
        else:
            seq_dict[count] = temp_sequence
            count = count + 1
            temp_sequence = []

    word_list = []
    for idx, (key, value) in enumerate(seq_dict.items()):
        tknzed = [WordPunctTokenizer().tokenize(x) + ["\n"] for x in value]
        for sent in tknzed:
            for word in sent:
                word_list.append(word)

    return word_list

def to_sequence(wordlist, max_len):
    """
    Args:
        wordlist (list): List of words of the text file
        max_len (int): Maximum token limit for each returning word sequence
    Purpose:
        Preprocess word list to word sequences of length max_len
    Returns:
        input_sequences (2D list): A list of word list containing words from wordlist of limit max_len
    """
    input_sequences = []

    for i in range(0, len(wordlist)-max_len):
        input_sequences.append(wordlist[i:i+max_len])

    return input_sequences

class Dataset(Dataset):
    """
    Structure of Data:
        INPUT: ["<SOS>"] + word1 + word2 + word3 + word4 + word5 + word6 (Assume Max_Len was 7)
        TARGET: word1 + word2 + word3 + word4 + word5 + word6 + ["<EOS>"] (Assume Max_Len was 7)
    Purpose:
        PyTorch Dataset mechanism for future training
    """
    def __init__(self, sequences, tokenizer, max_len, limit=None):
        self.max_len = max_len

        self.sequences = sequences if limit == None else sequences[:limit]

        self.tokenizer = tokenizer

    def __getitem__(self, idx):
        x = ["<SOS>"] + self.sequences[idx][:-1]
        y = self.sequences[idx][0:-1] + ["<EOS>"]

        x = self.tokenizer.transform(x, max_len=self.max_len, pad_first=False)
        y = self.tokenizer.transform(y, max_len=self.max_len, pad_first=False)

        return x, y

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

def collate_fn(batch):
    '''
    Purpose:
        Convert word sequences from PyTorch Dataset to torch.LongTensor
    Param:
        batch: ([x, y]， [x, y], output of getitem...)
    '''
    x, y = list(zip(*batch))
    return torch.LongTensor(x), torch.LongTensor(y)

def get_dataloader(dataset, batch_size, shuffle=True, drop_last=False, collate_fn=collate_fn):
    """
    Args:
        dataset (torch.utils.data.Dataset): PyTorch Dataset containing ready word sequences
        batch_size (int): batch_size of dataset
        shuffle (bool, optional): Whether to shuffle returning dataloader. Defaults to True.
        drop_last (bool, optional): Whether to drop last batch of returning dataloader. Defaults to False.
        collate_fn (_type_, optional): Collate_fn for processing dataset. Defaults to collate_fn.
    Purpose:
        Return final processed PyTorch dataloader for training
    Returns:
        dataloader (torch.utils.data.DataLoader): PyTorch Dataloader containing sentence data
    """
    dataloader = DataLoader(dataset=dataset,
                            batch_size=batch_size,
                            shuffle=shuffle,
                            drop_last=drop_last,
                            collate_fn=collate_fn)
    return dataloader

word_list = txt_to_wordlist(config.path)
input_sequences = to_sequence(word_list, config.max_len)
dataset = Dataset(input_sequences, config.tokenizer, config.max_len, limit=None) # try with full dataset see what happens
dataloader = get_dataloader(dataset, config.batch_size)

# #NOTE: Test Run
# if __name__ == "__main__":
#     word_list = txt_to_wordlist(config.path)
#     input_sequences = to_sequence(word_list, config.max_len)
#     print(len(input_sequences[0]))

#     dataset = Dataset(input_sequences, config.max_len, limit=None)
#     for i, (x, y) in enumerate(dataset):
#         print(x)
#         print(len(x))
#         print(y)
#         print(len(y))
#         break

#     dataloader = get_dataloader(dataset, config.batch_size)
#     for i, (x, y) in enumerate(dataloader):
#         print(x)
#         print(x.shape)
#         print(y)
#         print(y.shape)
#         break


#Regular Method : it has first args is a self
#Class method: has first args as 'cls' with decorator as a '@classmethod'
# Static Method : dont pass automatically args or instance they just like function but it is in class

#decorator : it alter the functionallaty of method
class Employee:
    #class Variable
    raise_amount = 1.04
    emp_no = 0
    def __init__(self,first,last,pay):
        #instant variables
        self.first = first
        self.last = last
        self.pay = pay
        Employee.emp_no +=1

    def fullname(self):
        return '{} {}'.format(self.first,self.last)

    def apply_raise(self):
        self.pay = int(self.pay * self.raise_amount)

    #class Method
    @classmethod
    def apply_raise_amt(cls, amount):
        cls.raise_amount = amount
    #class methpd as alternative constructor
    @classmethod
    def from_string(cls, emp_str):
        first, last, pay = emp_str.split('-')
        #create new employee object
        return cls(first,last,pay)

    #static method
    @staticmethod
    def is_weekday(day):
        if day.weekday() == 5 or day.weekday():
            return False
        return True

emp1 = Employee('San','G',60000)
emp2 = Employee('Test','User',50000)

##it skip class varible automatically
#emp1.apply_raise_amt(4)
Employee.apply_raise_amt(10)
print(Employee.raise_amount)
print(emp1.raise_amount)

#
emp1_str ='S-G-100000'
new_emp1 = Employee.from_string(emp1_str)
print(new_emp1.first)
print(new_emp1.last)
print(new_emp1.pay)

from datetime import date
mydatetime= date(2019,9,28)
print(Employee.is_weekday(mydatetime))


import re
import math
import operator
from collections import defaultdict, deque
from pathlib import Path

def gen_recipe(lines):
    ingredient_regex = re.compile(r"(\d+ [A-Z]+),?\s*(.*)")
    result_regex = re.compile(r"=> (\d+ [A-Z]+)")

    for line in lines:
        ingredients = []
        while True:
            m = ingredient_regex.match(line)
            if m:
                ing, line = m.groups()
                quant, name = ing.split()
                ingredients.append((int(quant), name))
                continue
            m = result_regex.match(line)
            if m:
                (res,) = m.groups()
                quant, name = res.split()
                result = (int(quant), name)
                break
            raise RuntimeError(line)
        yield ingredients, result

def calculate_top_order(ratios, name):
    if name == "ORE":
        return 0
    return sum(calculate_top_order(ratios, n) for _, n in ratios[name]) + 1

def calculate_ore_for_fuel(ratios, amounts_produced, amount_fuel):
    requirements = defaultdict(int)
    requirements["FUEL"] = amount_fuel
    stockpile = defaultdict(int)

    while [x for x in requirements if x != "ORE"]:
        current_ing, _ = max(
            [(n, calculate_top_order(ratios, n)) for n in requirements],
            key=operator.itemgetter(1),
        )
        amount_required = requirements.pop(current_ing)
        amount_required -= stockpile[current_ing]
        stockpile[current_ing] = 0

        quant_multiplier = math.ceil(amount_required / amounts_produced[current_ing])
        excess = amounts_produced[current_ing] * quant_multiplier - amount_required
        stockpile[current_ing] += excess

        for quant, name in ratios[current_ing]:
            amount_ingredient_required = quant * quant_multiplier
            requirements[name] += amount_ingredient_required
    return requirements["ORE"]

def part1():
    lines = Path("input/14.txt").read_text().strip().split("\n")

    recipe = list(gen_recipe(lines))
    amounts_produced = {ing: c for _, (c, ing) in recipe}
    ratios = {ing: req for req, (_, ing) in recipe}

    required_ore = calculate_ore_for_fuel(ratios, amounts_produced, 1)
    print(required_ore)

def find_max_fuel(ratios, amounts_produced):
    total_ore = 1000000000000

    possible_fuel = 1
    prev_possible_fuel = 1
    while True:
        required_ore = calculate_ore_for_fuel(ratios, amounts_produced, possible_fuel)
        if required_ore > total_ore:
            break
        prev_possible_fuel = possible_fuel
        possible_fuel *= 2

    possible_fuels = list(range(prev_possible_fuel, possible_fuel))
    start = 0
    stop = len(possible_fuels) - 1

    while start <= stop:
        mid = start + (stop - start) // 2
        possible_fuel = possible_fuels[mid]
        required_ore = calculate_ore_for_fuel(ratios, amounts_produced, possible_fuel)

        if required_ore < total_ore:
            start = mid + 1
        elif required_ore > total_ore:
            stop = mid - 1
        else:
            break

    if required_ore > total_ore:
        possible_fuel = possible_fuels[mid - 1]
    return possible_fuel

def part2():
    lines = Path("input/14.txt").read_text().strip().split("\n")

    recipe = list(gen_recipe(lines))
    amounts_produced = {ing: c for _, (c, ing) in recipe}
    ratios = {ing: req for req, (_, ing) in recipe}
    max_fuel = find_max_fuel(ratios, amounts_produced)
    print(max_fuel)

if __name__ == "__main__":
    # part1()
    part2()


from __future__ import unicode_literals
__author__ = 'lexxodus'

from app import db
from app.api import api
from app.models import LevelSkill as LevelSkillModel
from datetime import datetime, timedelta
from dateutil import parser
from flask import abort, request
from flask.ext.restful import Resource

def get_level_skill_json(level_skill, public=False):
    data = {}
    data["id"] = level_skill.id
    data["pid"] = level_skill.pid
    data["lid"] = level_skill.lid
    data["calculated_on"] = level_skill.calculated_on.isoformat()
    data["considered_rows"] = level_skill.considered_rows
    data["skill_points"] = level_skill.skill_points
    data["high_score"] = level_skill.high_score
    data["attempt"] = level_skill.attempt
    if public:
        data['api_url'] = "%s%s" % (api.url_for(LevelSkill), level_skill.id)
    return data

class LevelSkill(Resource):

    def post(self):
        required_values = ["pid", "lid"]
        data = request.get_json()
        if not all(v in data for v in required_values):
            abort(404)
        pid = data["pid"]
        lid = data["lid"]
        until = data.get("until", None)
        if until:
            until = parser.parse(until)
        level_skill = LevelSkillModel(pid, lid, until)
        db.session.add(level_skill)
        db.session.commit()
        return get_level_skill_json(level_skill), 201

    def get(self, id=None):
        if id:
            level_skill = LevelSkillModel.query.get(id)
            if not level_skill:
                abort(404)
            return get_level_skill_json(level_skill)
        else:
            return self.get_all()

    def get_all(self):
        args = request.args
        level_skills = LevelSkillModel.query
        pids = args.getlist("pid")
        lids = args.getlist("lid")
        interval = args.get("interval", None)
        last = args.get("last", None)
        if pids:
            level_skills = level_skills.filter(LevelSkillModel.pid.in_(pids))
        if lids:
            level_skills = level_skills.filter(LevelSkillModel.lid.in_(lids))
        if interval:
            level_skills = level_skills.filter(LevelSkillModel.calculated_on >= datetime.now() - timedelta(seconds=interval))
        if last:
            level_skills = level_skills.order_by(LevelSkillModel.calculated_on.desc()).limit(last)
        else:
            level_skills = level_skills.order_by(LevelSkillModel.calculated_on).all()
        data = []
        for l in level_skills:
            data.append(get_level_skill_json(l))
        return data

    def delete(self, id):
        level_skill = LevelSkillModel.query.get(id)
        if not level_skill:
            abort(404)
        db.session.delete(level_skill)
        db.session.commit()
        return "", 204


"""
Create Models which will be mapped to tables in our database migrations.

Models include:
    Rooms: Has a title and description, can have attachments to other rooms and contain players
    Players: Has a corresponding user, a current room.

"""

from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save
from django.dispatch import receiver
from rest_framework.authtoken.models import Token
import uuid

class Room(models.Model):
    """Creates room model (table in database)
    Has a title, description, and n_to, s_to, e_to and w_to, which represent
    connections to other rooms.
    """
    title = models.CharField(max_length=50, default="DEFAULT TITLE")
    description = models.CharField(max_length=500, default="DEFAULT DESCRIPTION")
    n_to = models.IntegerField(default=0)
    s_to = models.IntegerField(default=0)
    e_to = models.IntegerField(default=0)
    w_to = models.IntegerField(default=0)
    def connectRooms(self, destinationRoom, direction):
        '''Connects rooms together, checking to see if input direction and destination room are valid'''
        destinationRoomID = destinationRoom.id
        try:
            destinationRoom = Room.objects.get(id=destinationRoomID)
        except Room.DoesNotExist:
            print("That room does not exist")
        else:
            if direction == "n":
                self.n_to = destinationRoomID
            elif direction == "s":
                self.s_to = destinationRoomID
            elif direction == "e":
                self.e_to = destinationRoomID
            elif direction == "w":
                self.w_to = destinationRoomID
            else:
                print("Invalid direction")
                return
            self.save()
    def playerNames(self, currentPlayerID):
        '''Returns all players in a given room'''
        return [p.user.username for p in Player.objects.filter(currentRoom=self.id) if p.id != int(currentPlayerID)]
    def playerUUIDs(self, currentPlayerID):
        '''Returns all player UUIDs in a given room'''
        return [p.uuid for p in Player.objects.filter(currentRoom=self.id) if p.id != int(currentPlayerID)]

class Player(models.Model):
    '''Creates a Player model (table in database) takes in a User, the current room, and a uuid'''
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    currentRoom = models.IntegerField(default=0)
    uuid = models.UUIDField(default=uuid.uuid4, unique=True)
    def initialize(self):
        '''Check to see if initial room is not yet set, and if so, sets it to the first room in the Room table (model)'''
        if self.currentRoom == 0:
            self.currentRoom = Room.objects.first().id
            self.save()
    def room(self):
        '''Returns the id of the current room the player is in. If invalid room id, calls initialize'''
        try:
            return Room.objects.get(id=self.currentRoom)
        except Room.DoesNotExist:
            self.initialize()
            return self.room()

@receiver(post_save, sender=User)
def create_user_player(sender, instance, created, **kwargs):
    '''Creates a user player'''
    if created:
        Player.objects.create(user=instance)
        Token.objects.create(user=instance)

@receiver(post_save, sender=User)
def save_user_player(sender, instance, **kwargs):
    '''Saves a player to the database'''
    instance.player.save()