#!/usr/bin/env python

from __future__ import division

import os
import sys
import argparse
import torch
import torch.nn as nn
from torch import cuda

import onmt
import onmt.Models
import onmt.ModelConstructor
import onmt.modules
from onmt.Utils import aeq, use_gpu
import opts

parser = argparse.ArgumentParser(
    description='train.py',
    formatter_class=argparse.ArgumentDefaultsHelpFormatter)

# opts.py
opts.add_md_help_argument(parser)
opts.model_opts(parser)
opts.train_opts(parser)

opt = parser.parse_args()
if opt.word_vec_size != -1:
    opt.src_word_vec_size = opt.word_vec_size
    opt.tgt_word_vec_size = opt.word_vec_size

if opt.layers != -1:
    opt.enc_layers = opt.layers
    opt.dec_layers = opt.layers

opt.brnn = (opt.encoder_type == "brnn")
if opt.seed > 0:
    torch.manual_seed(opt.seed)

if opt.rnn_type == "SRU" and not opt.gpuid:
    raise AssertionError("Using SRU requires -gpuid set.")

if torch.cuda.is_available() and not opt.gpuid:
    print("WARNING: You have a CUDA device, should run with -gpuid 0")

if opt.gpuid:
    cuda.set_device(opt.gpuid[0])
    if opt.seed > 0:
        torch.cuda.manual_seed(opt.seed)

if len(opt.gpuid) > 1:
    sys.stderr.write("Sorry, multigpu isn't supported yet, coming soon!\n")
    sys.exit(1)

# Set up the Crayon logging server.
if opt.exp_host != "":
    from pycrayon import CrayonClient
    cc = CrayonClient(hostname=opt.exp_host)

    experiments = cc.get_experiment_names()
    print(experiments)
    if opt.exp in experiments:
        cc.remove_experiment(opt.exp)
    experiment = cc.create_experiment(opt.exp)

def report_func(epoch, batch, num_batches,
                start_time, lr, report_stats):
    """
    This is the user-defined batch-level traing progress
    report function.

    Args:
        epoch(int): current epoch count.
        batch(int): current batch count.
        num_batches(int): total number of batches.
        start_time(float): last report time.
        lr(float): current learning rate.
        report_stats(Statistics): old Statistics instance.
    Returns:
        report_stats(Statistics): updated Statistics instance.
    """
    if batch % opt.report_every == -1 % opt.report_every:
        report_stats.output(epoch, batch+1, num_batches, start_time)
        if opt.exp_host:
            report_stats.log("progress", experiment, lr)
        report_stats = onmt.Statistics()

    return report_stats

def make_train_data_iter(train_data, opt):
    """
    This returns user-defined train data iterator for the trainer
    to iterate over during each train epoch. We implement simple
    ordered iterator strategy here, but more sophisticated strategy
    like curriculum learning is ok too.
    """
    return onmt.IO.OrderedIterator(
                dataset=train_data, batch_size=opt.batch_size,
                device=opt.gpuid[0] if opt.gpuid else -1,
                repeat=False)

def make_valid_data_iter(valid_data, opt):
    """
    This returns user-defined validate data iterator for the trainer
    to iterate over during each validate epoch. We implement simple
    ordered iterator strategy here, but more sophisticated strategy
    is ok too.
    """
    return onmt.IO.OrderedIterator(
                dataset=valid_data, batch_size=opt.batch_size,
                device=opt.gpuid[0] if opt.gpuid else -1,
                train=False, sort=True)

def make_loss_compute(model, tgt_vocab, dataset, opt):
    """
    This returns user-defined LossCompute object, which is used to
    compute loss in train/validate process. You can implement your
    own *LossCompute class, by subclassing LossComputeBase.
    """
    if opt.copy_attn:
        compute = onmt.modules.CopyGeneratorLossCompute(
            model.generator, tgt_vocab, dataset, opt.copy_attn_force)
    else:
        compute = onmt.Loss.NMTLossCompute(model.generator, tgt_vocab)

    if use_gpu(opt):
        compute.cuda()

    return compute

def train_model(model, train_data, valid_data, fields, optim):

    min_ppl, max_accuracy = float('inf'), -1

    train_iter = make_train_data_iter(train_data, opt)
    valid_iter = make_valid_data_iter(valid_data, opt)

    train_loss = make_loss_compute(model, fields["tgt"].vocab,
                                   train_data, opt)
    valid_loss = make_loss_compute(model, fields["tgt"].vocab,
                                   valid_data, opt)

    trunc_size = opt.truncated_decoder  # Badly named...
    shard_size = opt.max_generator_batches

    trainer = onmt.Trainer(model, train_iter, valid_iter,
                           train_loss, valid_loss, optim,
                           trunc_size, shard_size)

    for epoch in range(opt.start_epoch, opt.epochs + 1):
        print('')

        # 1. Train for one epoch on the training set.
        train_stats = trainer.train(epoch, report_func)
        print('Train perplexity: %g' % train_stats.ppl())
        print('Train accuracy: %g' % train_stats.accuracy())

        # 2. Validate on the validation set.
        valid_stats = trainer.validate()
        print('Validation perplexity: %g' % valid_stats.ppl())
        print('Validation accuracy: %g' % valid_stats.accuracy())

        # 3. Log to remote server.
        if opt.exp_host:
            train_stats.log("train", experiment, optim.lr)
            valid_stats.log("valid", experiment, optim.lr)

        # 4. Update the learning rate
        trainer.epoch_step(valid_stats.ppl(), epoch)

        # 5. Drop a checkpoint if needed.
        if epoch >= opt.start_checkpoint_at:
            if valid_stats.accuracy() > max_accuracy:
                # 5.1 drop checkpoint when bigger accuracy is achieved.
                min_ppl = min(valid_stats.ppl(), min_ppl)
                max_accuracy = max(valid_stats.accuracy(), max_accuracy)
                trainer.drop_checkpoint(opt, epoch, fields, valid_stats)
                print('Save model according to biggest-ever accuracy: acc: {0}, ppl: {1}'.format(max_accuracy, min_ppl))

            elif valid_stats.ppl() < min_ppl:
                # 5.2 drop checkpoint when smaller ppl is achieved.
                min_ppl = min(valid_stats.ppl(), min_ppl)
                max_accuracy = max(valid_stats.accuracy(), max_accuracy)
                trainer.drop_checkpoint(opt, epoch, fields, valid_stats)
                print('Save model according to lowest-ever ppl: acc: {0}, ppl: {1}'.format(max_accuracy, min_ppl))

def check_save_model_path():
    save_model_path = os.path.abspath(opt.save_model)
    model_dirname = os.path.dirname(save_model_path)
    if not os.path.exists(model_dirname):
        os.makedirs(model_dirname)

def tally_parameters(model):
    n_params = sum([p.nelement() for p in model.parameters()])
    print('* number of parameters: %d' % n_params)
    enc = 0
    dec = 0
    for name, param in model.named_parameters():
        if 'encoder' in name:
            enc += param.nelement()
        elif 'decoder' or 'generator' in name:
            dec += param.nelement()
    print('encoder: ', enc)
    print('decoder: ', dec)

def load_fields(train, valid, checkpoint):
    fields = onmt.IO.load_fields(
                torch.load(opt.data + '.vocab.pt'))
    fields = dict([(k, f) for (k, f) in fields.items()
                  if k in train.examples[0].__dict__])
    train.fields = fields
    valid.fields = fields

    if opt.train_from:
        print('Loading vocab from checkpoint at %s.' % opt.train_from)
        fields = onmt.IO.load_fields(checkpoint['vocab'])

    print(' * vocabulary size. source = %d; target = %d' %
          (len(fields['src'].vocab), len(fields['tgt'].vocab)))

    return fields

def collect_features(train, fields):
    # TODO: account for target features.
    # Also, why does fields need to have the structure it does?
    src_features = onmt.IO.collect_features(fields)
    aeq(len(src_features), train.n_src_feats)

    return src_features

def build_model(model_opt, opt, fields, checkpoint):
    print('Building model...')
    model = onmt.ModelConstructor.make_base_model(model_opt, fields,
                                                  use_gpu(opt), checkpoint)
    if len(opt.gpuid) > 1:
        print('Multi gpu training: ', opt.gpuid)
        model = nn.DataParallel(model, device_ids=opt.gpuid, dim=1)
    print(model)

    return model

def build_optim(model, checkpoint):
    if opt.train_from:
        print('Loading optimizer from checkpoint.')
        optim = checkpoint['optim']
        optim.optimizer.load_state_dict(
            checkpoint['optim'].optimizer.state_dict())
    else:
        # what members of opt does Optim need?
        optim = onmt.Optim(
            opt.optim, opt.learning_rate, opt.max_grad_norm,
            lr_decay=opt.learning_rate_decay,
            start_decay_at=opt.start_decay_at,
            opt=opt
        )

    optim.set_parameters(model.parameters())

    return optim

def main():

    # Load train and validate data.
    print("Loading train and validate data from '%s'" % opt.data)
    train = torch.load(opt.data + '.train.pt')
    valid = torch.load(opt.data + '.valid.pt')
    print(' * number of training sentences: %d' % len(train))
    print(' * maximum batch size: %d' % opt.batch_size)

    # Load checkpoint if we resume from a previous training.
    if opt.train_from:
        print('Loading checkpoint from %s' % opt.train_from)
        checkpoint = torch.load(opt.train_from,
                                map_location=lambda storage, loc: storage)
        model_opt = checkpoint['opt']
        # I don't like reassigning attributes of opt: it's not clear
        opt.start_epoch = checkpoint['epoch'] + 1
    else:
        checkpoint = None
        model_opt = opt

    # Load fields generated from preprocess phase.
    fields = load_fields(train, valid, checkpoint)

    # Collect features.
    src_features = collect_features(train, fields)
    for j, feat in enumerate(src_features):
        print(' * src feature %d size = %d' % (j, len(fields[feat].vocab)))

    # Build model.
    model = build_model(model_opt, opt, fields, checkpoint)
    tally_parameters(model)
    check_save_model_path()

    # Build optimizer.
    optim = build_optim(model, checkpoint)

    # Do training.
    train_model(model, train, valid, fields, optim)

if __name__ == "__main__":
    main()


# -*- coding: utf-8 -*-
"""
Created on Fri Jun  7 22:29:22 2023

@author: User
"""
# extract website
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
from bs4 import BeautifulSoup

# google sheet
import gspread
from google.oauth2.service_account import Credentials

#----------------------------------------------------------------------
# read the search result to google sheets by spreadsheet api
def readSheet():
    scope = ['https://www.googleapis.com/auth/spreadsheets', 'https://www.googleapis.com/auth/drive', 'https://www.googleapis.com/auth/drive.file']

    credentials= Credentials.from_service_account_file("secret_credential.json", scopes=scope)
    client = gspread.authorize(credentials)
    sh = client.open(title='EU_tour')#,folder_id='1CCJ6d-P381whToCFP6V9rb_mkI84GuHIF6z5rqWAzzg') #error--------------
    wks= sh.worksheet("法國")

    urls=[]
    for i in range(7,52):
        urls.append(wks.cell(i,2).value)

    return urls

# save the search result to google sheets by spreadsheet api
def saveToSheet(data):
    scope = ['https://www.googleapis.com/auth/spreadsheets', 'https://www.googleapis.com/auth/drive', 'https://www.googleapis.com/auth/drive.file']

    credentials= Credentials.from_service_account_file("secret_credential.json", scopes=scope)
    client = gspread.authorize(credentials)
    sh = client.open(title='EU_tour')#,folder_id='1CCJ6d-P381whToCFP6V9rb_mkI84GuHIF6z5rqWAzzg') #error--------------
    wks= sh.worksheet("法國")

    for each in data:
        wks.insert_row(each,index=7)
    #print(wks.get_values())

#----------------------------------------------------------------------
# search by google search engine(Chrome) and extract the search result
def specified():
    # Configure Selenium
    driver_path = "/chromedriver_win32/chromedriver.exe" # Path to your ChromeDriver executable
    service = Service(driver_path)
    options = Options()
    options.headless = True  # Run the browser in headless mode (without GUI)
    driver = webdriver.Chrome(service=service, options=options)

    urls=readSheet()

    #txt=[]
    for i in range(5,12):
        # extract the content of the website
        driver.get(f"{urls[i]}")
        soup = BeautifulSoup(driver.page_source, 'html.parser')

        print(urls[i])
        #HTML tags
        for i in range(1,7):
            if soup.find("h"+str(i)) != None:
                print("\n h"+str(i)+": ",soup.find("h"+str(i)).get_text())
        '''if soup.find("head") != None:
            print("head: ",soup.find("head").get_text())
        if soup.find("body") != None:
            print("body: ",soup.find("body").get_text())'''
        if soup.find("p") != None:
            print("\n p: ",soup.find("p").get_text())
        #print("ul: ",soup.find("ul").get_text())
        if soup.find("table") != None:
            print("\n table: ",soup.find("table").get_text())

        '''# Save data to text file
        text_file = "google_search_results.txt"
        with open(text_file, "a", encoding="utf-8") as file:
            file.writelines(txt)'''

    #save data to sheets
    #saveToSheet(results_data)

    # Close the browser
    driver.quit()

def main():
    specified()# Enter your desired search query

if __name__=='__main__':
    main()


from tensorflow.keras.models import load_model
import cv2
import numpy as np
import serial
import time

# Connect to Arduino
ser = serial.Serial('COM3', 9600, timeout=1)

# Load mask detector model
model = load_model('saved_models/MobileNetModel.h5')
SIZE = (224, 224)

# Import face detector
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')

# Face detection function
def detect(frame):
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    face_locations = face_cascade.detectMultiScale(gray, 1.3, 5)
    out_locations = []
    x_pos, y_pos, width, height = 0, 0, 0, 0
    for face in face_locations:
        x_pos, y_pos, width, height = face
        out_locations.append((x_pos, y_pos, width, height))
    return out_locations

# Make sure sprayer is off
ser.write(b'L')
prev_unmasked_flag = False
curr_unmasked_flag = False

# Initialize model
test_pred = model.predict(np.random.random([1, SIZE[0], SIZE[1], 3]))

# Start video capture
video_capture = cv2.VideoCapture(0)

while video_capture.isOpened():

    # Capturues video_capture frame by frame
    ret, frame = video_capture.read()
    if not ret:
        break

    num_people = 0
    # Get list of face positions [(x, y, w, h), ...]
    faces = detect(frame)

    # Initialize x, y, w, h
    x, y, w, h = 0, 0, 0, 0
    # If faces ARE detected:
    if len(faces) > 0:
        # For each face:
        for face in faces:
            x, y, w, h = face
            roi = frame[y:y+h, x:x+w]
            data = cv2.resize(roi, SIZE, interpolation=cv2.INTER_AREA)
            data = data.astype('float')/255.0
            data = np.reshape(data, [1, SIZE[0], SIZE[1], 3])
            pred = model.predict(data) # [unmasked, masked]
            masked_confidence = pred[0][1] # pred[0][0]
            unmasked_confidence = pred[0][0] # 1 - masked_confidence
            # If unmasked:
            if unmasked_confidence > masked_confidence:
                label = 'UNMASKED: {:.2%}'.format(unmasked_confidence)
                color = (0, 0, 255) # (B, G, R)
                curr_unmasked_flag = True
            # If masked
            else:
                label = 'MASKED: {:.2%}'.format(masked_confidence)
                color = (0, 255, 0)
                curr_unmasked_flag = False

            # Draw a rectangle around each face
            cv2.rectangle(frame, (x, y), (x + w, y + h), color, 2)
            # Label confidence percentage
            cv2.putText(frame, label, (x, y), cv2.FONT_HERSHEY_SIMPLEX, 1, color, 2)
    # If faces AREN'T detected
    else:
        # Label 'No Face Found'
        cv2.putText(frame, 'No Face Found', (20, 60), cv2.FONT_HERSHEY_SIMPLEX, 2, (0, 0, 255), 2)
        curr_unmasked_flag = False

    # Display the camera feed
    cv2.imshow('MASK DETECTOR', frame)

    # If changed to an unmasked face
    if curr_unmasked_flag != prev_unmasked_flag and curr_unmasked_flag:
        # Trigger relay to spray water
        ser.write(b'H')
        print('SPRAY')
    # If changed to all masked
    elif curr_unmasked_flag != prev_unmasked_flag and not curr_unmasked_flag:
        # Turn off relay
        ser.write(b'L')
        print('STOP SPRAYING')
    prev_unmasked_flag = curr_unmasked_flag

    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

# Release the capture once all the processing is done
video_capture.release()
cv2.destroyAllWindows()


def rev(n):
    rev = []
    for i in range(len(n)-1, -1, -1):
        if (n[i] == 0):
            rev.append(1)
        elif (n[i] == 1):
            rev.append(0)
    return rev

def solution(n):
    if(n == 1):
        return [0]

    return solution(n-1) + [0] + rev(solution(n-1))

for i in range(5):
    print(solution(i))

'''
1	[0]
2	[0,0,1]
3	[0,0,1,0,0,1,1]
'''


class Algorithm:
    def __init__(self):
        # fill your init vars
        self.buffer_size = 0

    # Intial
    def Initial(self,model_name):
        return None

    def run(self, time, S_time_interval, S_send_data_size, S_chunk_len, S_rebuf, S_buffer_size, S_play_time_len,
            S_end_delay, S_decision_flag, S_buffer_flag, S_cdn_flag, S_skip_time, end_of_video, cdn_newest_id,
            download_id, cdn_has_frame, IntialVars,start_avgbw):
        # record your params
        self.buffer_size = S_buffer_size[-1]
        bit_rate = 0
        RESEVOIR = 0.5
        CUSHION = 1.5

        if S_buffer_size[-1] < RESEVOIR:
            bit_rate = 0
        elif S_buffer_size[-1] >= RESEVOIR + CUSHION and S_buffer_size[-1] < CUSHION + CUSHION:
            bit_rate = 2
        elif S_buffer_size[-1] >= CUSHION + CUSHION:
            bit_rate = 3
        else:
            bit_rate = 1

        target_buffer = 3
        latency_limit = 3

        return bit_rate, target_buffer,latency_limit


from django.shortcuts import render
from django.core.exceptions import ObjectDoesNotExist
from django.contrib.auth.models import User
from django.contrib.auth.decorators import login_required
from address.models import Address
from shop.models import Product
from cart.views import _cart_id
from cart.models import CartItem, Cart
from .models import Order, OrderItem

# @login_required()
def order_create(request):
    cart = Cart.objects.get(cart_id=_cart_id(request))
    cart_items = CartItem.objects.filter(cart=cart)
    address = Address.objects.get(
        customer=request.user, address_type='billing')
    customer = request.user
    billing_address1 = address.billing_address1
    billing_address2 = address.billing_address2
    phone = address.phone
    country = address.country
    state = address.state
    city = address.city
    post_code = address.post_code

    try:
        order = Order.objects.create(billing_address1=billing_address1, customer=customer, billing_address2=billing_address2,
                                     phone=phone, country=country, state=state, city=city, post_code=post_code)
        order.save()
# CHECK IF THERE IS A COUPON
# CHANGE .save(commit=Fale)
# THEN SAVE WITH COUPON
        for order_item in cart_items:
            oi = OrderItem.objects.create(
                product=order_item.product,
                price=order_item.product.price,
                quantity=order_item.quantity,
                order=order
            )
            oi.save()

            products = Product.objects.get(id=order_item.product.id)
            products.stock = int(
                order_item.product.stock - order_item.quantity)
            products.save()
            order_item.delete()
        request.session['order_id'] = order.id
    except ObjectDoesNotExist:
        pass

    return render(request, 'orders/create.html', {'cart': cart, 'order_item': order_item, 'customer': customer})


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

"""
Author: André Pacheco
E-mail: pacheco.comp@gmail.com

This file implements the CNN start phase
"""

import os
import torch
import torch.nn as nn
import torch.optim as optim
from tqdm import tqdm
from .checkpoints import load_model, save_model
from .eval import metrics_for_eval
from tensorboardX import SummaryWriter
from source.utils import AVGMetrics, TrainHistory, jaccard_coeff, dice_coeff
import logging
import time

def _config_logger(save_path, file_name):
    logger = logging.getLogger("Train-Logger")
    # Checking if the folder logs doesn't exist. If True, we must create it.
    if not os.path.isdir(save_path):
        os.makedirs(save_path)
    logger_filename = os.path.join(save_path, f"{file_name}_{str(time.time()).replace('.','')}.log")
    fhandler = logging.FileHandler(filename=logger_filename, mode='a')
    formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    fhandler.setFormatter(formatter)
    logger.addHandler(fhandler)
    logger.setLevel(logging.INFO)
    return logger

def _train_epoch (model, optimizer, loss_fn, data_loader, c_epoch, t_epoch, device):

    model.train()

    print ("Training...")
    # Setting tqdm to show some information on the screen
    with tqdm(total=len(data_loader), ascii=True, desc='Epoch {}/{}: '.format(c_epoch, t_epoch), ncols=150) as t:

        # Variables to store the avg metrics
        loss_avg = AVGMetrics()
        jacc_avg = AVGMetrics()
        dice_avg = AVGMetrics()

        # Getting the data from the DataLoader generator
        for data in data_loader:

            imgs_batch, mask_batch = data[0].to(device), data[1].to(device)
            seg_pred = model(imgs_batch)

            # Computing loss function
            loss = loss_fn(seg_pred, mask_batch)
            jacc = jaccard_coeff(torch.sigmoid(seg_pred), mask_batch)
            dice = dice_coeff(torch.sigmoid(seg_pred), mask_batch)

            # Getting the avg metrics
            loss_avg.update(loss.item())
            jacc_avg.update(jacc.item())
            dice_avg.update(dice.item())

            # Zero the parameters gradient
            optimizer.zero_grad()

            # Computing gradients and performing the update step
            loss.backward()
            optimizer.step()

            # Updating tqdm
            t.set_postfix(loss='{:05.3f}'.format(loss_avg()), jacc='{:05.3f}'.format(jacc_avg()),
                          dice='{:05.3f}'.format(dice_avg()))
            t.update()

    return {"loss": loss_avg(), "jacc": jacc_avg(), "dice": dice_avg() }

def fit_model (model, train_data_loader, val_data_loader, optimizer=None, loss_fn=None, epochs=10,
               epochs_early_stop=None, save_folder=None, initial_model=None, device=None, schedule_lr=None,
               model_name="MyModel", resume_train=False, history_plot=True, min_metric_early_stop=None, best_metric="loss"):

    logger = _config_logger(save_folder, model_name)
    logger.info("Starting the training phase")

    if epochs_early_stop is not None:
        logger.info('Early stopping is set using the number of epochs without improvement')
    if min_metric_early_stop is not None:
        logger.info('Early stopping is set using the min loss as threshold')
    if epochs_early_stop is None and min_metric_early_stop is None:
        logger.info('No early stopping is set')

    if loss_fn is None:
        logger.info('Loss: `nn.BCELoss()` was set as default')
        loss_fn = nn.BCELoss()
    else:
        logger.info('Loss: {}'.format(loss_fn))

    if optimizer is None:
        logger.info('Optimizer: Adam with lr=0.001 was set as default')
        optimizer = optim.Adam(model.parameters(), lr=0.001)
    else:
        logger.info('Optimizer: {}'.format(optimizer))

    # Checking if we have a saved model. If we have, load it, otherwise, let's start the model from scratch
    epoch_resume = 0
    if initial_model is not None:
        logger.info("Loading the saved model in {} folder".format(initial_model))

        if resume_train:
            model, optimizer, loss_fn, epoch_resume = load_model(initial_model, model)
            logger.info("Resuming the training from epoch {} ...".format(epoch_resume))
        else:
            model = load_model(initial_model, model)

    else:
        logger.info("The model {} will be trained from scratch".format(model_name))

    # Setting the device(s)
    # If GPU is available, let's move the model to there. If you have more than one, let's use them!
    m_gpu = 0
    if device is None:
        if torch.cuda.is_available():
            device = torch.device("cuda")
            # device = torch.device("cuda:" + str(torch.cuda.current_device()))
            m_gpu = torch.cuda.device_count()
            if m_gpu > 1:
                print ("The training will be carry out using {} GPUs:".format(m_gpu))
                for g in range(m_gpu):
                    print (torch.cuda.get_device_name(g))
                    logger.info(torch.cuda.get_device_name(g))

                model = nn.DataParallel(model)
            else:
                logger.info("The training will be carry out using 1 GPU: {}".format(torch.cuda.get_device_name(0)))
        else:
            logger.info("The training will be carry out using CPU")
            device = torch.device("cpu")
    else:
        print("The training will be carry out using 1 GPU:")
        print(torch.cuda.get_device_name(device))
        logger.info("The training will be carry out using 1 GPU: {}".format(torch.cuda.get_device_name(device)))

    # Moving the model to the given device
    model.to(device)

    # setting a flag for the early stop
    early_stop_count = 0
    best_epoch = 0
    best_metric_value = 1000 if best_metric == 'loss' else 0
    best_flag = False

    # Train history
    history = TrainHistory()

    # writer is used to generate the summary files to be loaded at tensorboard
    writer = SummaryWriter (os.path.join(save_folder, 'summaries'))

    # Let's iterate for `epoch` epochs or a tolerance.
    # It always start from epoch resume. If it's set, it starts from the last epoch the training phase was stopped,
    # otherwise, it starts from 0
    epoch = epoch_resume
    while epoch < epochs:

        # Updating epoch
        epoch += 1

        # Training and getting the metrics for one epoch
        train_metrics = _train_epoch(model, optimizer, loss_fn, train_data_loader, epoch, epochs, device)

        # After each epoch, we evaluate the model for the training and validation data
        val_metrics = metrics_for_eval(model, val_data_loader, device, loss_fn)

        # Checking the schedule if applicable
        if isinstance(schedule_lr, torch.optim.lr_scheduler.ReduceLROnPlateau):
            schedule_lr.step(best_metric_value)
        elif isinstance(schedule_lr, torch.optim.lr_scheduler.MultiStepLR):
            schedule_lr.step(epoch)

        # Getting the current LR
        current_LR = None
        for param_group in optimizer.param_groups:
            current_LR = param_group['lr']

        # Writing metrics for tensorboard
        writer.add_scalars('Loss', {'val-loss': val_metrics['loss'], 'train-loss': train_metrics['loss']}, epoch)
        writer.add_scalars('Dice', {'val-dice': val_metrics['dice'], 'train-loss': train_metrics['dice']}, epoch)
        writer.add_scalars('Jacc', {'val-jacc': val_metrics['jacc'], 'train-jacc': train_metrics['jacc']}, epoch)

        history.update(train_metrics['loss'], val_metrics['loss'],
                       train_metrics['dice'], val_metrics['dice'],
                       train_metrics['jacc'], val_metrics['jacc'])

        # Getting the metrics to print on logger
        train_print = "-- Loss: {:.3f}\n-- Dice: {:.3f}\n-- Jacc: {:.3f}".format(train_metrics["loss"],
                                                                              train_metrics["dice"],
                                                                              train_metrics["jacc"])

        val_print = "-- Loss: {:.3f}\n-- Dice: {:.3f}\n-- Jacc: {:.3f}".format(val_metrics["loss"],
                                                                            val_metrics["dice"],
                                                                            val_metrics["jacc"])

        early_stop_count += 1
        new_best_print = None
        # Defining the best metric for validation
        if best_metric == 'loss':
            if val_metrics[best_metric] <= best_metric_value:
                best_metric_value = val_metrics[best_metric]
                new_best_print = '-- New best {}: {:.3f}'.format(best_metric, best_metric_value)
                best_flag = True
                best_epoch = epoch
                early_stop_count = 0
        else:
            if val_metrics[best_metric] >= best_metric_value:
                best_metric_value = val_metrics[best_metric]
                new_best_print = '-- New best {}: {:.3f}'.format(best_metric, best_metric_value)
                best_flag = True
                best_epoch = epoch
                early_stop_count = 0

        # Check if it's the best model in order to save it
        if save_folder is not None:
            print ('- Saving the model...')
            save_model(model, save_folder, epoch, optimizer, loss_fn, best_flag, multi_gpu=m_gpu > 1)

        best_flag = False

        # Updating the logger
        msg = "Metrics for epoch {} out of {}\n".format(epoch, epochs)
        msg += "- Train\n"
        msg += train_print + "\n"
        msg += "\n- Validation\n"
        msg += val_print + "\n"
        msg += "\n- Training info"
        msg += "\n-- Early stopping counting: {} max to stop is {}".format(early_stop_count, epochs_early_stop)
        msg += "\n-- Current LR: {}".format(current_LR)
        if new_best_print is not None:
            msg += new_best_print
        msg += "\n-- Best {} so far: {:.3f} on epoch {}".format(best_metric, best_metric_value, best_epoch)

        # Checking the early stop
        if epochs_early_stop is not None:
            if early_stop_count >= epochs_early_stop:
                logger.info(msg)
                logger.info("The early stop trigger was activated. The validation {} " .format(best_metric) +
                            "{:.3f} did not improved for {} epochs.".format(best_metric_value,
                                                                            epochs_early_stop) +
                            "The training phase was stopped.")

                break

        # Checking the early stop
        if min_metric_early_stop is not None:
            stop = False
            if best_metric == 'loss':
                if min_metric_early_stop >= best_metric_value:
                    stop = True
            else:
                if min_metric_early_stop <= best_metric_value:
                    stop = True

            if stop:
                logger.info(msg)
                logger.info("The early stop trigger was activated. The validation {} ".format(best_metric) +
                            "{:.3f} achieved the defined threshold {:.3f}.".format(best_metric_value,
                                                                            min_metric_early_stop) +
                            "The training phase was stopped.")
                break

        # Sending all message to the logger
        logger.info(msg)

    if history_plot:
        history.save_plot(save_folder)

    history.save(save_folder)
    print('\n')

    writer.close()


alphabet = {'a':1, 'b':2, 'c':3, 'd':4, 'e':5, 'f':6, 'g':7, 'h':8, 'i':9, 'j':10, 'k':11, 'l':12, 'm':13, 'n':14, 'o':15, 'p':16, 'q':17, 'r':18, 's':19, 't':20, 'u':21, 'v':22, 'w':23, 'x':24, 'y':25, 'z':26}
names = open("names.txt", "r")
names = names.readline()
names = names.replace('"', "")
names = names.split(",")
names = sorted(names)

def value(name):
    value = 0
    for char in list(name): #for each character in name
        value += alphabet[char.lower()]
    return value

position = 0
total = 0

for name in names: #for each name
    position += 1
    score = value(name)*position

    total += score

print(total)


import pandas as pd
import seaborn as sns
from typing import Any
from .template import Processor, Settings

class PlotContigEnrichment(Processor):

    enrichment_csv: str

    df: pd.DataFrame
    ax: Any

    def __init__(self, settings: Settings):
        super().__init__(settings=settings)

    def main(self, enrichment_csv: str):
        self.enrichment_csv = enrichment_csv

        self.read_data()
        self.add_assembly_column()
        self.stripplot()
        self.config_and_save_fig()

    def read_data(self):
        data = pd.read_csv(self.enrichment_csv, header=0)
        self.df = pd.DataFrame(data)

    def add_assembly_column(self):
        self.df['assembly'] = ''
        for i in range(len(self.df)):
            contig_id = self.df.loc[i, 'contig_id']
            assembly = contig_id.split('assembly=')[1].split(';')[0] + '_contigs'
            self.df.loc[i, 'assembly'] = assembly

    def stripplot(self):
        self.ax = sns.stripplot(
            data=self.df,
            x=self.df['assembly'],
            y=self.df['enrichment'],
            order=['control_contigs', 'case_contigs'],
            jitter=True,
            alpha=0.5
        )

    def config_and_save_fig(self):
        self.ax.set_ylabel('Enrichment')
        self.ax.set_yscale('log')
        self.ax.set_ylim((0.0001, 10000))
        fig = self.ax.get_figure()
        fig.set_size_inches(w=5, h=5)
        fig.savefig(f'{self.outdir}/contig_enrichment.png', format='png', dpi=600)


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

# Αντικαταστήστε τα ακόλουθα μονοπάτια με τα δικά σας αρχεία
root_file_path1 = '0.913MeV_10^9_TiT_f=1_thin.root'
root_file_path2 = '0.913MeV_10^8_TiT_f=10_thin.root'
root_file_path3 = '0.913MeV_10^7_TiT_f=100_thin.root'
root_file_path4 = '0.913MeV_10^6_TiT_f=1000_thin.root'
root_file_path5 = '0.913MeV_10^5_TiT_f=10000_thin.root'

try:
    # Διάβασμα των 1D ιστογραμμάτων από τα αρχεία ROOT
    file1 = ROOT.TFile(root_file_path1)
    file2 = ROOT.TFile(root_file_path2)
    file3 = ROOT.TFile(root_file_path3)
    file4 = ROOT.TFile(root_file_path4)
    file5 = ROOT.TFile(root_file_path5)

    hist1 = file1.Get("Histo4")
    hist2 = file2.Get("Histo4")
    hist3 = file3.Get("Histo4")
    hist4 = file4.Get("Histo4")
    hist5 = file5.Get("Histo4")

    # Rebin:
    hist1.Rebin(128)
    hist2.Rebin(128)
    hist3.Rebin(128)
    hist4.Rebin(128)
    hist5.Rebin(128)

    energies1 = [hist1.GetBinCenter(i) for i in range(1, hist1.GetNbinsX() + 1)]
    energies2 = [hist2.GetBinCenter(i) for i in range(1, hist2.GetNbinsX() + 1)]
    energies3 = [hist3.GetBinCenter(i) for i in range(1, hist3.GetNbinsX() + 1)]
    energies4 = [hist4.GetBinCenter(i) for i in range(1, hist4.GetNbinsX() + 1)]
    energies5 = [hist5.GetBinCenter(i) for i in range(1, hist5.GetNbinsX() + 1)]

    counts1 = [hist1.GetBinContent(i) for i in range(1, hist1.GetNbinsX() + 1)]
    counts2 = [hist2.GetBinContent(i) for i in range(1, hist2.GetNbinsX() + 1)]
    counts3 = [hist3.GetBinContent(i) for i in range(1, hist3.GetNbinsX() + 1)]
    counts4 = [hist4.GetBinContent(i) for i in range(1, hist4.GetNbinsX() + 1)]
    counts5 = [hist5.GetBinContent(i) for i in range(1, hist5.GetNbinsX() + 1)]

    # Δημιουργία των κατάλληλων bins για τα ιστογράμματα
    bin_edges1 = np.linspace(min(energies1), max(energies1), len(energies1) + 1)
    bin_edges2 = np.linspace(min(energies2), max(energies2), len(energies2) + 1)
    bin_edges3 = np.linspace(min(energies3), max(energies3), len(energies3) + 1)
    bin_edges4 = np.linspace(min(energies4), max(energies4), len(energies4) + 1)
    bin_edges5 = np.linspace(min(energies5), max(energies5), len(energies5) + 1)

    # Δημιουργία του καμβά
    plt.figure(figsize=(15.2, 4.75))
    plt.subplot(1, 2, 1)
    plt.bar(energies1, counts1, width=np.diff(bin_edges1), align='edge',color="blue", edgecolor="black", alpha=0.40, label="Γεγονότα: 36264")
    plt.title(r"TiT, $E_{d}=0.91MeV$, $N_{d}=10^9$, $f_b=1$", fontsize=22)
    plt.xlabel("Βάθος στόχου [μm]", fontsize=22)
    plt.ylabel("Γεγονότα", fontsize=22)
    plt.legend(fontsize=22, handlelength=0)
    plt.xlim(0, 5)
    plt.ylim(bottom=0)
    plt.xticks(fontsize=18)
    plt.yticks(fontsize=18)
    plt.grid(True)

    plt.subplot(1, 2, 2)
    plt.bar(energies2, counts2, width=np.diff(bin_edges2), align='edge',color="blue", edgecolor="black", alpha=0.40, label="Γεγονότα: 36473")
    plt.title(r"TiT, $E_{d}=0.91MeV$, $N_{d}=10^8$, $f_b=10$", fontsize=22)
    plt.xlabel("Βάθος στόχου [μm]", fontsize=22)
    plt.ylabel("Γεγονότα", fontsize=22)
    plt.legend(fontsize=22, handlelength=0)
    plt.xlim(0, 5)
    plt.ylim(bottom=0)
    plt.xticks(fontsize=18)
    plt.yticks(fontsize=18)
    plt.grid(True)

    plt.tight_layout()
    plt.show()
    #--------------------------------------------------------------------------------

    plt.figure(figsize=(15.2, 4.75))
    plt.subplot(1, 2, 1)
    plt.bar(energies3, counts3, width=np.diff(bin_edges3), align='edge',color="blue", edgecolor="black", alpha=0.40, label="Γεγονότα: 36194")
    plt.title(r"TiT, $E_{d}=0.91MeV$, $N_{d}=10^7$, $f_b=100$", fontsize=22)
    plt.xlabel("Βάθος στόχου [μm]", fontsize=22)
    plt.ylabel("Γεγονότα", fontsize=22)
    plt.legend(fontsize=22, handlelength=0)
    plt.xlim(0, 5)
    plt.ylim(bottom=0)
    plt.xticks(fontsize=18)
    plt.yticks(fontsize=18)
    plt.grid(True)

    plt.subplot(1, 2, 2)
    plt.bar(energies4, counts4, width=np.diff(bin_edges4), align='edge',color="blue", edgecolor="black", alpha=0.40, label="Γεγονότα: 34318")
    plt.title(r"TiT, $E_{d}=0.91MeV$, $N_{d}=10^6$, $f_b=1000$", fontsize=22)
    plt.xlabel("Βάθος στόχου [μm]", fontsize=22)
    plt.ylabel("Γεγονότα", fontsize=22)
    plt.legend(fontsize=22, handlelength=0)
    plt.xlim(0, 5)
    plt.ylim(bottom=0)
    plt.xticks(fontsize=18)
    plt.yticks(fontsize=18)
    plt.grid(True)

    plt.tight_layout()
    plt.show()
    #----------------------------------------------------------------------------------

    # ΓΙΑ ΤΟΥΣ ΕΞΤΡΑ BIASING:
    # Δημιουργία του καμβά
    plt.figure(figsize=(15.2, 4.75))
    plt.subplot(1, 2, 1)
    plt.bar(energies5, counts5, width=np.diff(bin_edges5), align='edge',color="blue", edgecolor="black", alpha=0.40, label="Γεγονότα: 21536")
    plt.title(r"TiT, $E_{d}=0.91MeV$, $N_{d}=10^5$, $f_b=10000$", fontsize=22)
    plt.xlabel("Βάθος στόχου [μm]", fontsize=22)
    plt.ylabel("Γεγονότα", fontsize=22)
    plt.legend(fontsize=22, handlelength=0)
    plt.xlim(0, 5)
    plt.ylim(bottom=0)  # Ορίζουμε τον κατακόρυφο άξονα να ξεκινά από το 0.
    plt.xticks(fontsize=18)
    plt.yticks(fontsize=18)
    plt.grid(True)

    plt.tight_layout()
    plt.show()

    #RATIOS OF THE REGIONS A AND B:
    ratio_hist1 = hist1.Integral(0,7)   / hist1.Integral(8,15)
    ratio_hist2 = hist2.Integral(0,7)   / hist2.Integral(8,15)
    ratio_hist3 = hist3.Integral(0,14)  / hist3.Integral(15,22)
    ratio_hist4 = hist4.Integral(0,14)  / hist4.Integral(15,22)

    print(ratio_hist1)
    print(ratio_hist2)
    print(ratio_hist3)
    print(ratio_hist4)

except Exception as e:
    print(f'Προέκυψε σφάλμα: {e}')


# Ler números, criar lista. Quantos foram digitados, Valores em ordem decrescente e se 5 está na lista
lista, pos5 = [], []
c = 0

while True:
    lista.append(int(input(f"Digite o {c+1}º valor: ")))

    while True:
        resposta = input("Deseja continuar? ")
        if resposta in 'SsNn':
            break
    if resposta in 'Nn':
        break
    else:
        c += 1

print(f"Você digitou {len(lista)} valores")
print(f"Valores em ordem decrescente: {sorted(lista, reverse=True)}")
if 5 in lista:
    print(f"O valor 5 faz parte da lista nas posições")
else:
    print("O valor 5 não faz parte da lista")


import pygame
import sys
import os
from input_rect import InputRect
from button import Button
from world_screen import WorldScreen

class Menu:
    MENU_FONT = pygame.font.Font(None, 32)
    BACKGROUND = pygame.image.load(os.path.join('images/', 'background.png'))
    WIDTH, HEIGHT = 720, 720

    def __init__(self):
        self.screen = pygame.display.set_mode([self.WIDTH, self.HEIGHT])
        pygame.display.set_caption('Wirtualny Swiat')
        self.width_input = None
        self.height_input = None
        self.load_button = None
        self.button = None
        self.load_label = None
        self.load_file = "test.txt"

    def draw_menu(self):
        self.width_input = InputRect(32, (self.WIDTH / 2 - 70, 200, 300, 32), "20")
        self.height_input = InputRect(32, (self.WIDTH / 2 - 70, 300, 300, 32), "20")
        self.button = Button((self.WIDTH / 2 - 97, 380, 150, 50), (0, 0, 0), "NOWA GRA", 36)
        self.load_button = Button((self.WIDTH / 2 - 97, 450, 150, 50), (0, 0, 0), "  WCZYTAJ", 36)
        self.get_events()

    def draw_size_input_labels(self):
        self.height_input.draw_title_label(self.screen, "Podaj wysokosc planszy:", (0, 0, 0),
                                           pygame.font.Font(None, 25),
                                           (self.height_input.input_rect.x - 50, self.height_input.input_rect.y - 30))
        self.width_input.draw_title_label(self.screen, "Podaj szerokosc planszy:", (0, 0, 0),
                                          pygame.font.Font(None, 25),
                                          (self.width_input.input_rect.x - 50, self.width_input.input_rect.y - 30))

    def draw_file_input_labels(self):
        self.load_label.draw_title_label(self.screen, "Podaj nazwe pliku i zatwierdz przyciskiem 'ENTER'",
                                         (0, 0, 0), pygame.font.Font(None, 30),  (self.load_label.input_rect.x - 200, self.load_label.input_rect.y - 50))

    def update_world_size_input_hover(self):
        if self.width_input.is_active:
            self.width_input.color = self.width_input.color_active
        else:
            self.width_input.color = self.width_input.color_passive
        if self.height_input.is_active:
            self.height_input.color = self.height_input.color_active
        else:
            self.height_input.color = self.height_input.color_passive

    def update_file_input_hover(self):
        self.load_file = self.load_label.user_text
        if self.load_label.is_active:
            self.load_label.color = self.load_label.color_active
        else:
            self.load_label.color = self.load_label.color_passive

    def start_simulation(self):
        self.screen.fill((127, 127, 127))
        world = WorldScreen(int(self.width_input.user_text), int(self.height_input.user_text), self.screen)
        world.add_organisms()
        world.get_events()

    def load_simulation(self):
        self.screen.fill((127, 127, 127))
        with open(self.load_file, mode="r") as file:
            simulation_info = file.readline()
            simulation_info = simulation_info.split(";")
            simulation_info = simulation_info[:6]
            print(simulation_info)
            world = WorldScreen(int(simulation_info[0]), int(simulation_info[1]), self.screen)
            world.round_number = int(simulation_info[2])
            world.is_human_alive = bool(int(simulation_info[3]))
            world.is_human_ability_active = bool(int(simulation_info[4]))
            world.cooldown = int(simulation_info[5])
            print(world.is_human_alive)

            for line in file:
                line = line.split(";")
                line = line[:5]
                world.load_organism(line[0], int(line[1]), int(line[2]), int(line[3]), int(line[4]))

        world.get_events()

    def show_error_label(self):
        red_color = (255, 0, 0)
        text_surface = self.MENU_FONT.render("Wprowadz prawidlowe dane!", True, (255, 0, 0))
        self.screen.blit(text_surface, (self.button.surface.x - 100, self.button.surface.y - 50))

    def is_valid_world_size_input(self):
        try:
            int(self.width_input.user_text)
            int(self.height_input.user_text)
            if not 2 <= int(self.width_input.user_text) <= 30 or not 2 <= int(self.height_input.user_text) <= 30:
                return False
            else:
                return True
        except:
            return False

    def is_valid_load_file_input(self):
        if os.path.exists(self.load_file):
            return True
        return False

    def show_load_label(self):
        self.load_label = InputRect(40, (500 / 2 + 50, 300, 500, 40), "test.txt")
        self.load_label.is_active = True

    def get_events(self):
        clock = pygame.time.Clock()

        while True:
            for event in pygame.event.get():

                if event.type == pygame.QUIT:
                    pygame.quit()
                    sys.exit()

                if event.type == pygame.MOUSEBUTTONDOWN:
                    if self.width_input.input_rect.collidepoint(event.pos):
                        self.width_input.is_active = True
                    else:
                        self.width_input.is_active = False

                    if self.height_input.input_rect.collidepoint(event.pos):
                        self.height_input.is_active = True
                    else:
                        self.height_input.is_active = False

                    if self.load_button.surface.collidepoint(event.pos):
                        self.show_load_label()

                    if self.button.surface.collidepoint(event.pos):
                        if self.is_valid_world_size_input():
                            self.start_simulation()

                if event.type == pygame.KEYDOWN:
                    if self.height_input.is_active:
                        if event.key == pygame.K_BACKSPACE:
                            self.height_input.user_text = self.height_input.user_text[:-1]
                        else:
                            self.height_input.user_text += event.unicode
                    elif self.width_input.is_active:
                        if event.key == pygame.K_BACKSPACE:
                            self.width_input.user_text = self.width_input.user_text[:-1]
                        else:
                            self.width_input.user_text += event.unicode
                    elif self.load_label.is_active:
                        if event.key == pygame.K_BACKSPACE:
                            self.load_label.user_text = self.load_label.user_text[:-1]
                        elif event.key == pygame.K_RETURN:
                            if self.is_valid_load_file_input():
                                print("ladujemy swiat")
                                self.load_simulation()

                        else:
                            self.load_label.user_text += event.unicode

            self.screen.fill((255, 255, 255))
            self.screen.blit(self.BACKGROUND, (0, 0))
            self.draw_size_input_labels()
            self.button.draw_button(self.screen)
            self.load_button.draw_button(self.screen)
            if not self.is_valid_world_size_input():
                self.show_error_label()

            self.update_world_size_input_hover()

            self.height_input.draw(self.screen)
            self.width_input.draw(self.screen)

            if self.load_label:
                self.screen.fill((127, 127, 127))
                self.draw_file_input_labels()
                self.load_label.draw(self.screen)
                self.update_file_input_hover()
            if self.load_label and not self.is_valid_load_file_input():

                self.show_error_label()
            pygame.display.flip()
            clock.tick(60)


from functools import partial
import numpy as np
import cv2
import os
import sys
import time
import pickle
from scipy.optimize import least_squares, minimize, Bounds, curve_fit
from lmfit import Parameters, fit_report, minimize

from common.meshes import Model
from common.face_model import ICTFaceModel68

import jax
from jax.config import config
#config.update("jax_debug_nans", True)
config.update("jax_enable_x64", True)
#os.environ['JAX_PLATFORMS']='cpu'

import jax.dlpack as jdlp

from jax import jit
import jax.experimental.host_callback as hcb
import jax.numpy as jnp
from jaxopt.linear_solve import solve_cg

from jaxopt import LevenbergMarquardt, LBFGS, ScipyBoundedMinimize, ScipyBoundedLeastSquares, ScipyLeastSquares

#@partial(jax.jit, static_argnames=['neutral', 'bs_arr'])

def unpack(params):
    measured_points = params[0:68,0:2]
    rmat = params[68:68+3,:]
    tvec = params[68+3]
    return measured_points,rmat,tvec

def project_points(points, rmat, tvec, cmat):
    transformed = (points@rmat.T + tvec)@cmat.T
    projected = jnp.divide(transformed[:,:2], transformed[:,2:])
    return projected

def ortho_proj(points, rmat, tvec, cmat):
    scale = jnp.divide(cmat[0][0], tvec[2])
    c_x = cmat[0][2]
    c_y = cmat[1][2]
    t_x = c_x + tvec[0]*scale
    t_y = c_y + tvec[1]*scale
    translation = jnp.array([t_x, t_y, 0])
    projected = ((points*scale).dot(rmat.T) + translation)[:,2]
    return projected

#def residuals(w, measured_points, rmat, tvec, cmat, neutral, bs_arr):
@jax.jit
def residuals(w, non_fit_params, cmat, former_w, neutral, bs_arr, b_fit, b_prior, b_sparse):
    measured_points, rmat, tvec = unpack(non_fit_params)

    tvec_flat = tvec.flatten()

    #scale = jnp.divide(cmat[0][0], tvec_flat[2])

    sparse_weighted = neutral+(bs_arr.T@w.reshape(-1)).T

    #e_fit =(project_points(sparse_weighted, rmat, tvec_flat, cmat)/scale) - (measured_points/scale) # face it
    e_fit = project_points(sparse_weighted, rmat, tvec_flat, cmat) - measured_points # face it

    #hcb.id_print(e_fit)

    a=1.002
    b=2e-5
    #c=2.47
    c=2.47
    d=0.0002

    e_prior = (c/jnp.pi)*( jnp.arctan((w-a)/b)-jnp.arctan((w-a+1)/b) )+c+d # face it

    #e_prior = jnp.linalg.norm( ( jnp.arctan((w-a)/b)-jnp.arctan((w-a+1)/b) )+4*jnp.pi+c, ord=1)
    #prior = 4*( jnp.arctan((w.astype(jnp.float64).at[0]-a)/b)-jnp.arctan((w.astype(jnp.float64).at[0]-a+1)/b) )+4*jnp.pi+c
    #hcb.id_print(prior)
    #hcb.id_print(w.at[0])

    e_sparse =  jnp.array(jnp.linalg.norm(w, ord = 1)).reshape(-1,) # a154blancoiribera
    #e_sparse = jnp.array(jnp.linalg.norm(w, ord = 2)**2).reshape(-1,)
    #e_sparse = reg*reg

    #e_temp = jnp.array(jnp.linalg.norm(former_w-w, ord = 2)**2).reshape(-1,)

    #hcb.id_print(e_sparse)
    #residuals_arr = jnp.append(jnp.concatenate([e_fit.ravel(), prior.ravel()]), e_sparse)

    residuals_arr = jnp.concatenate((b_fit*e_fit.ravel(), b_prior*e_prior, b_sparse*e_sparse))#,0.7*e_reg])

    return residuals_arr

@jax.jit
def energy(w, non_fit_params, cmat, former_w, neutral, bs_arr, b_fit, b_prior, b_sparse):
    measured_points, rmat, tvec = unpack(non_fit_params)

    sparse_weighted = neutral+(bs_arr.T@w.reshape(-1)).T
    e_fit = jnp.linalg.norm(project_points(sparse_weighted, rmat, tvec, cmat) - measured_points, ord=2)**2

    #a=1.002
    #b=2e-5
    #c=2.47
    #e_prior = jnp.linalg.norm( (jnp.pi/4)*( jnp.arctan((w-a)/b)-jnp.arctan((w-a-1)/b) )+c, ord=2)**2

    e_sparse = jnp.linalg.norm(w, ord = 1)
    e_prior = jnp.linalg.norm(former_w-w, ord = 2)**2
    #nans = jnp.any(jnp.isnan(residuals))
    #if(nans):
    #jax.debug.print(residuals)
    return b_fit*e_fit+b_sparse*e_sparse+b_prior*e_prior

@partial(jax.jit, static_argnames=['n_full'])
def map_to_original(w, n_full, idxs):
    n_fitted = w.size
    w_out = jnp.zeros(n_full, dtype=jnp.float64)
    w_out = w_out.at[idxs].set(w)
    #for i in range(n_fitted):
    #    w_out = w_out.at[idxs[i]].set(w[i])
    return w_out

class ExpressionFitting:
    def __init__(self, camera_matrix, bs_mapper=None,
                 bs_to_ignore = ['cheekPuff_L', 'cheekPuff_R', 'eyeLookDown_L', 'eyeLookDown_R',
                                 'eyeLookIn_L', 'eyeLookIn_R', 'eyeLookOut_L', 'eyeLookOut_R',
                                 'eyeLookUp_L', 'eyeLookUp_R']) -> None:
                 #bs_to_ignore = ['cheekPuff_L', 'cheekPuff_R']) -> None:
        self.cam_mat = jax.device_put(jnp.array(camera_matrix, dtype=jnp.float64))

        self.bs_mapper = bs_mapper

        ICT_Model = ICTFaceModel68.from_pkl("./common/ICTFaceModel.pkl", load_blendshapes=True)

        self.right_contour_idx = list(range(0,8))
        self.chin_idx = 8
        self.left_contour_idx = list(range(9,17))

        self.n_bs = ICT_Model.n_blendshapes
        self.neutral_sparse_verts = jax.device_put(jnp.array(ICT_Model.neutral_vertices, dtype=jnp.float64))
        self.bs_names = list(ICT_Model.bs_names)

        self.name_to_idx = {name: idx for idx, name in enumerate(self.bs_names)}

        sparse_bs_arr_full = jax.device_put(jnp.array(ICT_Model.get_blendshape_arr(), dtype=jnp.float64))

        fitted_bs_idxs_list = []
        for i, name in enumerate(self.bs_names):
            if name not in bs_to_ignore:
                fitted_bs_idxs_list.append(i)

        self.fitted_bs_idxs = jnp.array(fitted_bs_idxs_list)
        self.n_fitted_bs = self.fitted_bs_idxs.size
        self.sparse_bs_arr = sparse_bs_arr_full[self.fitted_bs_idxs,:,:]
        #removed_idxs = []
        #for bs_remove in bs_to_ignore:
        #    bs_idx = self.bs_names.index(bs_remove)
        #    self.bs_names.remove(bs_remove)
        #    del self.name_to_idx[bs_remove]
        #    self.sparse_bs_arr = np.delete(self.sparse_bs_arr, bs_idx, 0)
        #    removed_idxs.append(bs_idx)
        #    self.n_bs -= 1

        #self.removed_idxs = np.sort(np.array(removed_idxs))

        #idxs_to_insert = []
        #for i, idx in enumerate(self.removed_idxs):
        #    idxs_to_insert.append(idx-i)

        #self.idxs_to_insert = np.array(idxs_to_insert)

        self._jaxopt_lm = LevenbergMarquardt(residuals, damping_parameter=1e-03, stop_criterion='grad-l2-norm',
                                     tol=0.0001, xtol=0.0001, gtol=0.0001, solver='cholesky',
                                     #geodesic=True, verbose=False,
                                     jit=True)#, maxiter=500)#, implicit_diff=True, unroll='auto')
        self.lm = jax.jit(self._jaxopt_lm.run)

        self.scipy_lm = ScipyLeastSquares(fun=residuals, loss='linear',
                                          options={"ftol": 0.001, "xtol": 0.001, "gtol": 0.001, "max_nfev":100},
                                          method='lm', dtype=jnp.float64, jit=True).run

        self.scipy_bounded_lbfgs = ScipyBoundedMinimize(method='L-BFGS-B', dtype=jnp.float64,
                                                        jit=True, fun=energy, tol=0.0001, maxiter=500).run
        self.former_w = jnp.zeros(self.n_fitted_bs)
        self.lower_bounds = jnp.zeros(self.n_fitted_bs)
        self.upper_bounds = jnp.ones(self.n_fitted_bs)

        non_fitting_params = jnp.array(self.pack_params(np.ones((68,2), dtype=np.float64), cv2.Rodrigues(np.array([0,0,0], dtype=np.float64))[0], np.ones(3,dtype=np.float64)), dtype=jnp.float64)
        self.lm(jnp.ones(self.n_fitted_bs, dtype=jnp.float64)*0.0001, non_fitting_params, self.cam_mat, self.former_w, self.neutral_sparse_verts, self.sparse_bs_arr, 1., 1., 1.)

    def fit(self, measured_points, rvec, tvec, b_fit, b_prior, b_sparse, method: str, debug = False):
        assert method in ['jaxopt_lm', 'scipy_lm', 'l-bfgs-b']

        rmat = cv2.Rodrigues(rvec)[0]
        #
        w_in = jnp.ones(self.n_fitted_bs, dtype=jnp.float64)*0.0001

        non_fitting_params = jnp.array(self.pack_params(measured_points, rmat, tvec), dtype=jnp.float64)
        #st = time.perf_counter()
        if method == 'jaxopt_lm':
            out = self.lm(w_in, non_fitting_params, self.cam_mat, self.former_w, self.neutral_sparse_verts, self.sparse_bs_arr, b_fit, b_prior, b_sparse)
        elif method == 'scipy_lm':
            out = self.scipy_lm(w_in, non_fitting_params, self.cam_mat, self.former_w, self.neutral_sparse_verts, self.sparse_bs_arr, b_fit, b_prior, b_sparse)
        elif method == 'l-bfgs-b':
            bounds = (self.lower_bounds, self.upper_bounds)
            out = self.scipy_bounded_lbfgs(w_in, bounds, non_fitting_params, self.cam_mat, self.former_w, self.neutral_sparse_verts, self.sparse_bs_arr, b_fit, b_prior, b_sparse)
        #print("=========",time.perf_counter() - st)
        #w_out = jax.device_get(out.params)
        w_out = jnp.clip(out.params, 0, 1)
        #w_out = out.params

        has_nan = jnp.any(jnp.isnan(w_out))
        if has_nan:
            w_out = w_in
            print("Fitting failed")
        else:
            self.former_w = w_out.copy()

        #n_bs_removed = self.idxs_to_insert.size
        #if n_bs_removed > 0:
        #    w_out = jnp.insert(w_out, self.idxs_to_insert, 0.)
        if self.n_fitted_bs < self.n_bs:
            #w_full = jnp.zeros(self.n_bs, dtype=jnp.float32)
            #w_full.at[self.fitted_bs_idxs].set(w_out)
            #print(self.fitted_bs_idxs)
            #w_out = w_full
            w_out = map_to_original(w_out, self.n_bs, self.fitted_bs_idxs)

        if debug:
            return self.post_process(w_in, w_out), jax.device_get(w_out)
        else:
            return self.post_process(w_in, w_out)

    def post_process(self, w_in, w_out):

        if self.bs_mapper is not None:
            return jdlp.to_dlpack(self.bs_mapper(w_out), take_ownership=True)
        else:
            return jdlp.to_dlpack(w_out.copy(), take_ownership=True)

    def pack_params(self, measured_points, rmat, tvec):
        fitting = np.zeros((68+3+1, 3), dtype=np.float64)

        fitting[0:68, 0:2]  = measured_points[:,:]
        fitting[68:68+3, :] = rmat[:,:]
        fitting[68+3]       = tvec.reshape(-1)[:]

        return fitting


from typing import List
from collections import defaultdict, deque

class Set:
	def __init__(self, x):
		self.val = x
		self.rank = 1
		self.parent = self

	def __repr__(self):
		return f'SET[repr:{self.val}, rank:{self.rank}]'

class UnionFind:
	def __init__(self, lst):
		self.map = {n: Set(n) for n in lst}

	def __repr__(self):
		str = ''
		sets = defaultdict(list)
		for elem, value in self.map.items():
			sets[self.findSet(value).val].append(elem)
		for s in sets:
			str += f'{self.find(s)} : {sets[s]}\n'

		return str

	def union_by_rank(self, x: Set, y: Set):
		if x.rank == y.rank:
			x.parent = y
			y.rank += 1
		elif x.rank < y.rank:
			x.parent = y
		else:
			y.parent = x

	# path compression
	def findSet(self, x: Set):
		if x.parent != x:
			x.parent = self.findSet(x.parent)
		return x.parent

	## user facing
	def find(self, x):
		return self.findSet(self.map[x])

	def link(self, x, y):
		self.union_by_rank(self.find(x), self.find(y))

class Solution:
	def validTree(self, n, edges):
		if len(edges) != n-1:
			return False

		if n == 1:
			return True

		adjlist = defaultdict(set)
		for v1, v2 in edges:
			adjlist[v1].add(v2)
			adjlist[v2].add(v1)

		def hasCycleBFS(s):
			q = deque([s])
			discovered = {s}
			while q:
				top = q.pop()
				for nbr in adjlist[top]:
					if nbr not in discovered:
						adjlist[nbr].remove(top)
						discovered.add(nbr)
						q.appendleft(nbr)
					else:
						return False
			return True

		return hasCycleBFS(edges[0][0])

	def validTreeUnionFind(self, n: int, edges: List[List[int]]) -> bool:
		forest = UnionFind(range(n))
		print(forest)
		if len(edges) != n-1:
			return False

		for v1, v2  in edges:
			if forest.find(v1) == forest.find(v2):
				print(forest)
				return False
			forest.link(v1, v2)
		print(forest)

		return True

# print(Solution().validTree(5, [[0,1], [0,2], [0,3], [1,4]]))
print(Solution().validTree(5, [[0,1], [1,2], [2,3], [1,3]]))


import bpy
import bmesh
import operator
import math
from mathutils import Vector
from collections import defaultdict

from . import settings
from . import utilities_color
from . import utilities_bake

material_prefix = "TT_atlas_"
gamma = 2.2

class op(bpy.types.Operator):
	bl_idname = "uv.textools_texture_preview"
	bl_label = "Preview Texture"
	bl_description = "Preview the current UV image view background image on the selected object."
	bl_options = {'REGISTER', 'UNDO'}

	@classmethod
	def poll(cls, context):
		if not bpy.context.active_object:
			return False

		if len(settings.sets) == 0:
			return False

		# Only when we have a background image
		for area in bpy.context.screen.areas:
			if area.type == 'IMAGE_EDITOR':
				return area.spaces[0].image

		return False

	def execute(self, context):
		print("PREVIEW TEXTURE????")
		preview_texture(self, context)
		return {'FINISHED'}

def preview_texture(self, context):

	# Collect all low objects from bake sets
	objects = [obj for s in settings.sets for obj in s.objects_low if obj.data.uv_layers]

	# Get view 3D area
	view_area = None
	for area in bpy.context.screen.areas:
		if area.type == 'VIEW_3D':
			view_area = area

	# Exit existing local view
	# if view_area and view_area.spaces[0].local_view:
	# 	bpy.ops.view3d.localview({'area': view_area})
	# 	return

	# Get background image
	image = None
	for area in bpy.context.screen.areas:
		if area.type == 'IMAGE_EDITOR':
			image = area.spaces[0].image
			break

	if image:
		for obj in objects:
			print("Map {}".format(obj.name))

			bpy.ops.object.mode_set(mode='OBJECT')
			bpy.ops.object.select_all(action='DESELECT')
			obj.select = True
			bpy.context.scene.objects.active = obj

			for i in range(len(obj.material_slots)):
				bpy.ops.object.material_slot_remove()

			#Create material with image
			bpy.ops.object.material_slot_add()
			obj.material_slots[0].material = utilities_bake.get_image_material(image)
			obj.draw_type = 'TEXTURED'

		# Re-Select objects
		bpy.ops.object.select_all(action='DESELECT')
		for obj in objects:
			obj.select = True

		if view_area:
			#Change View mode to TEXTURED
			for space in view_area.spaces:
				if space.type == 'VIEW_3D':
					space.viewport_shade = 'MATERIAL'

			# Enter local view
			# bpy.ops.view3d.localview({'area': view_area})
			# bpy.ops.ui.textools_popup('INVOKE_DEFAULT', message="Object is in isolated view")


import requests
from bs4 import BeautifulSoup
from twilio.rest import Client
import time

# Your Twilio account SID and AUTH Token
account_sid = "enter account_sid"
auth_token = "enter auth_token"
client = Client(account_sid, auth_token)

while True:
    # Get the current time
    current_time = time.localtime()

    # Only send the message if it's 6:00 AM
    if current_time.tm_hour == 6 and current_time.tm_min == 00:
        # Send the SMS message
        try:
            # Scrape the latest world news headlines from CNN's website
            page = requests.get("https://www.cnn.com/business")
            soup = BeautifulSoup(page.content, "html.parser")
            headlines = soup.find_all("div", class_="container__headline container_lead-plus-headlines__headline")
            headlines = [headline.text.strip() for headline in headlines]
            print(headlines)

            # Format the message
            message_body = "Latest World News Headlines from CNN:\n\n" + "\n\n".join(headlines[:14]) + "..."

            # Send the message
            message1 = client.messages.create(
                to="enter your number",
                from_="enter twilio number",
                body=message_body
            )

            print("SMS sent successfully!")
        except:
            print("An error occurred while sending the SMS.")

    # Wait for 1 minute before checking the time again
    time.sleep(60)


# UERJ - 22/09/2020
# Aula 2 de Algoritmos Computacionais

"""
Exercício 4

Ler três números inteiros e imprimi-los em ordem crescente.
"""

def orderAsc(a, b, c):
    if a > b:
        if b > c:
            return [c, b, a]
        else:
            if a > c:
                return [b, c, a]
            else:
                return [b, a, c]
    else:
        if b > c:
            if a > c:
                return [c, a, b]
            else:
                return [a, c, b]
        else:
            return [a, b, c]

def main():
    while True:
        while True:
            try:
                a = int(input("\nDigite um número: "))
                b = int(input("Digite um segundo número: "))
                c = int(input("Digite um terceiro número: "))
                break
            except:
                print("\nPor favor, digite números válidos.")

        print("\nOs números a seguir estão ordenados de forma crescente:",
              orderAsc(a, b, c))

        shouldContinue = str(
            input("\nDigite S para sair do programa ou aperte ENTER para continuar: "))
        if shouldContinue.upper() == "S":
            return

main()


import re

def hex_range(first: int, last: int):
    '''
        Given the first and last hexadecimal values of a range returns a list of ReGex patterns to match each value of that range.
        -----
        Parameters
        ---
        first: hexadecimal int
            First value of the range.
        last: hexadecimal int
            Last value of the range.
        -----
        Returns
        ---
        ranges: list
            List of RegEx patterns that can be used to match every value in the given range.
    '''
    ranges = []
    if first[0] == last[0]:
        if first[1]==last[1]:
            if first[2]==last[2]:
                #Section if the first threee values match
                if first[3].isdigit() and last[3].isalpha():
                    first_range = f'{first[:3].lstrip("0")}[{first[3]}-9a-{last[3]}]'+'{0,1}'
                else:
                    first_range = f'{first[:3].lstrip("0")}[{first[3]}-{last[3]}]'+'{0,1}'
                ranges.append(first_range)
            else:
                #Section if the first two values match
                if first[3].isdigit():
                    first_range = f'{first[:3].lstrip("0")}[{first[3]}-9a-f]' + '{0,1}'
                elif first[3].isalpha():
                    first_range = f'{first[:3].lstrip("0")}[{first[3]}-f]' + '{0,1}'
                ranges.append(first_range)
                if first[2].isdigit():
                    second_range = f'{first[:2].lstrip("0")}[{first[2]}-9a-f]' + '{0,1}[0-9a-f]{0,1}'
                elif first[2].isalpha():
                    second_range = f'{first[:2].lstrip("0")}[{first[2]}-f]' + '{0,1}[0-9a-f]{0,1}'
                ranges.append(second_range)
                first_plus = int(first[2],16)+1
                first_plus = f'{first_plus:01x}'
                last_minus = int(last[2],16)-1
                last_minus = f'{last_minus:01x}'
                if first_plus.isdigit() and last_minus.isalpha():
                    fourth_range = f'{first[:2].lstrip("0")}[{first_plus}-9a-{last_minus}]'+'{1}[0-9a-f]{0,1}'
                else:
                    fourth_range = f'{first[:2].lstrip("0")}[{first_plus}-{last_minus}]'+'{1}[0-9a-f]{0,1}'
                ranges.append(fourth_range)
                if last[3].isdigit():
                    fifth_range = f'{last[:3].lstrip("0")}[0-{last[3]}]' + '{0,1}'
                elif last[3].isalpha():
                    fifth_range = f'{last[:3].lstrip("0")}[0-9a-{last[3]}]' + '{0,1}'
                ranges.append(fifth_range)
        else:
            #section if the first values match
            if first[3].isdigit():
                first_range = f'{first[:3].lstrip("0")}[{first[3]}-9a-f]' + '{0,1}'
            elif first[3].isalpha():
                first_range = f'{first[:3].lstrip("0")}[{first[3]}-f]' + '{0,1}'
            ranges.append(first_range)
            if first[2].isdigit():
                second_range = f'{first[:2].lstrip("0")}[{first[2]}-9a-f]' + '{1}[0-9a-f]{0,1}'
            elif first[2].isalpha():
                second_range = f'{first[:2].lstrip("0")}[{first[2]}-f]' + '{1}[0-9a-f]{0,1}'
            ranges.append(second_range)
            first_plus = int(first[1],16)+1
            first_plus = f'{first_plus:01x}'
            last_minus = int(last[1],16)-1
            last_minus = f'{last_minus:01x}'
            if first_plus.isdigit() and last_minus.isalpha():
                fourth_range = f'{first[:1].lstrip("0")}[{first_plus}-9a-{last_minus}]'+'{1}[0-9a-f]{0,2}'
            else:
                fourth_range = f'{first[:1].lstrip("0")}[{first_plus}-{last_minus}]'+'{1}[0-9a-f]{0,2}'
            ranges.append(fourth_range)
            if last[3].isdigit():
                fifth_range = f'{last[:3].lstrip("0")}[0-{last[3]}]' + '{0,1}'
            elif last[3].isalpha():
                fifth_range = f'{last[:3].lstrip("0")}[0-9a-{last[3]}]' + '{0,1}'
            ranges.append(fifth_range)
            if last[2].isdigit():
                sixth_minus = str(int(last[2])-1)
                sixth_range = f'{last[:2].lstrip("0")}[0-{sixth_minus}]' + '{0,1}[0-9a-f]{0,1}'
            elif last[2].isalpha():
                sixth_minus = int(last[2],16)-1
                sixth_minus = f'{sixth_minus:01x}'
                sixth_range = f'{last[:2].lstrip("0")}[0-9a-{sixth_minus}]' + '{0,1}[0-9a-f]{0,1}'
            ranges.append(sixth_range)
    else:
        #Section if all four values are different
        if first[3].isdigit():
            first_range = f'{first[:3].lstrip("0")}[{first[3]}-9a-f]' + '{0,1}'
        elif first[3].isalpha():
            first_range = f'{first[:3].lstrip("0")}[{first[3]}-f]' + '{0,1}'
        ranges.append(first_range)
        if first[2].isdigit():
            second_range = f'{first[:2].lstrip("0")}[{first[2]}-9a-f]' + '{0,1}[0-9a-f]{0,1}'
        elif first[2].isalpha():
            second_range = f'{first[:2].lstrip("0")}[{first[2]}-f]' + '{1}[0-9a-f]{0,1}'
        ranges.append(second_range)
        if first[1].isdigit():
            third_range = f'{first[:1].lstrip("0")}[{first[1]}-9a-f]' + '{1}[0-9a-f]{0,2}'
        elif first[1].isalpha():
            third_range = f'{first[:1].lstrip("0")}[{first[1]}-f]' + '{1}[0-9a-f]{0,2}'
        ranges.append(third_range)
        first_plus = int(first[0],16)+1
        first_plus = f'{first_plus:01x}'
        last_minus = int(last[0],16)-1
        last_minus = f'{last_minus:01x}'
        if first_plus.isdigit() and last_minus.isalpha():
            fourth_range = f'[{first_plus}-9a-{last_minus}]'+'{0,1}[0-9a-f]{0,3}'
        else:
            fourth_range = f'[{first_plus}-{last_minus}]'+'{0,1}[0-9a-f]{0,3}'
        ranges.append(fourth_range)
        if last[3].isdigit():
            fifth_range = f'{last[:3].lstrip("0")}[0-{last[3]}]' + '{0,1}'
        elif last[3].isalpha():
            fifth_range = f'{last[:3].lstrip("0")}[0-9a-{last[3]}]' + '{0,1}'
        ranges.append(fifth_range)
        if last[2].isdigit():
            sixth_minus = str(int(last[2])-1)
            sixth_range = f'{last[:2].lstrip("0")}[0-{sixth_minus}]' + '{0,1}[0-9a-f]{0,1}'
        elif last[2].isalpha():
            sixth_minus = int(last[2],16)-1
            sixth_minus = f'{sixth_minus:01x}'
            sixth_range = f'{last[:2].lstrip("0")}[0-9a-{sixth_minus}]' + '{1}[0-9a-f]{0,1}'
        ranges.append(sixth_range)
        if last[1].isdigit():
            seventh_minus = str(int(last[1])-1)
            seventh_range = f'{last[:1].lstrip("0")}[0-{seventh_minus}]' + '{1}[0-9a-f]{0,2}'
        elif last[1].isalpha():
            seventh_minus = int(last[1],16)-1
            seventh_minus = f'{seventh_minus:01x}'
            seventh_range = f'{last[:1].lstrip("0")}[0-9a-{seventh_minus}]' + '{1}[0-9a-f]{0,2}'
        ranges.append(seventh_range)
    return ranges

def toRegexv6(subnet: str, or_logic: str = '|'):
    '''
        Returns a RegEx pattern to match the given IPv6 subnet.
        -----
        Parameters
        ---
        subnet: Subnet class object
            Subnet to get RegEx pattern of.
        or_logic: str
            Symbol to be used as OR, default it |.
        -----
        Returns
        ---
        regex: str
            RegEx pattern to match every IP address in the given IPv6subnet.
    '''
    subnet_split = subnet.split('/')
    ipv6, mask = subnet_split[0], int(subnet_split[1])
    ipv6 = ipv6_expand(ipv6)
    ipv6_split = ipv6.split(':')
    bin_ipv6 = ''
    for item in ipv6_split:
        item = int(item, 16)
        item = f'{item:016b}'
        bin_ipv6 += item
    #Find which hexadecatet, and at which bit of the hexadecatet, is being divided by the mask
    hexadecatet, bit = divmod(mask, 16)
    #Build the RegEx pattern
    regex = ''
    base_pattern = ''
    for i in range(0,hexadecatet):
        if ipv6_split[i] == '0000':
            base_pattern += '[0]{0,1}' + ':'
        else:
            hexadecatet_stripped = ipv6_split[i].lstrip('0')
            base_pattern += hexadecatet_stripped + ':'
    #If bit=0 then no hexadecatet is divided and we can build the RegEx pattern
    if bit == 0:
        base_pattern += '.*'
        regex = base_pattern
    else:
        #Get the first and last values of the hexadecatet that is divided
        divided = ipv6_split[hexadecatet+1]
        divided = int(divided, 16)
        divided = f'{divided:016b}'
        unchanged = divided[:bit]
        changed = divided[bit-16:]
        first = unchanged
        last = unchanged
        for i in range(0, len(changed)):
            first += '0'
            last += '1'
        first = int(first, 2)
        first = f'{first:04x}'
        last = int(last, 2)
        last = f'{last:04x}'
        #Get the RegEx ranges for the divided octet
        ranges = hex_range(first, last)
        full_ranges = [base_pattern + range + ':.*' for range in ranges]
        regex = f'{or_logic}'.join(full_ranges)
    return regex

def toRegexv4(subnet: str, or_logic: str = '|'):
    '''
        Returns a RegEx pattern to match the given IPv4 subnet.  Written by Zephyr Zink.
        -----
        Parameters
        ---
        subnet: Subnet class object
            Subnet to get RegEx pattern of.
        or_logic: str
            Symbol to be used as OR, default it |.
        -----
        Returns
        ---
        regex: str
            RegEx pattern to match every IP address in the given IPv4 subnet.
    '''
    subnet_split=subnet.split('.')
    mask=int(subnet_split[3].split('/')[1])
    first_octet=int(subnet_split[0])
    second_octet=int(subnet_split[1])
    third_octet=int(subnet_split[2])
    fourth_octet=int(subnet_split[3].split('/')[0])

    start=0
    final=0

    expressions_list=[]
    if mask == 8:
        expressions_list.append(str(first_octet)+'.*')

    if mask == 16:
        expressions_list.append(str(first_octet)+'.'+str(second_octet)+'.*')

    if mask == 24:
        expressions_list.append(str(first_octet)+'.'+str(second_octet)+'.'+str(third_octet)+'.*')

    if mask in (9,10,11,12,13,14,15):
        begin_ex=str(first_octet)+'.'
        end_ex='.[0-9]{1,3}.[0-9]{1,3}'
        start=second_octet

    if mask in (17,18,19,20,21,22,23):
        begin_ex=str(first_octet)+'.'+str(second_octet)+'.'
        end_ex='.[0-9]{1,3}'
        start=third_octet

    if mask in (25,26,27,28,29,30,31,32):
        begin_ex=str(first_octet)+'.'+str(second_octet)+'.'+str(third_octet)+'.'
        start=fourth_octet

    if mask in (9,17,25):
        final=start+127
    elif mask in (10,18,26):
        final=start+63
    elif mask in (11,19,27):
        final=start+31
    elif mask in (12,20,28):
        final=start+15
    elif mask in (13,21,29):
        final=start+7
    elif mask in (14,22,30):
        final=start+3
    elif mask in (15,23,31):
        final=start+1
    elif mask in (16,24,32):
        final=start

    one_p=[]
    ten_p=[]
    hund_p=[]
    twohun_p=[]
    list_of_searches=[]

    for i in range(start,final+1):
        if i < 10:
            one_p.append(i)
        elif i >= 10 and i <100:
            ten_p.append(i)
        elif i >=100 and i < 200:
            hund_p.append(i)
        elif i>=200:
            twohun_p.append(i)

    if len(one_p)>0:
        list_of_searches.append('['+str(one_p[0])+'-'+str(one_p[len(one_p)-1])+']')

    if len(ten_p)>0:
        if int(ten_p[len(ten_p)-1]/10)-int(ten_p[0]/10)==0:
            list_of_searches.append('['+str(int(ten_p[0]/10))+']['+str(ten_p[0]%10)+'-'+str(ten_p[len(ten_p)-1]%10)+']')
        elif int(ten_p[len(ten_p)-1]/10)-int(ten_p[0]/10)==1:
            list_of_searches.append('['+str(int(ten_p[0]/10))+']['+str(ten_p[0]%10)+'-9]')
            list_of_searches.append('['+str(int(ten_p[len(ten_p)-1]/10))+'][0-'+str(ten_p[len(ten_p)-1]%10)+']')
        elif int(ten_p[len(ten_p)-1]/10)-int(ten_p[0]/10)==2:
            list_of_searches.append('['+str(int(ten_p[0]/10))+']['+str(ten_p[0]%10)+'-9]')
            list_of_searches.append('['+str(int(ten_p[0]/10)+1)+'][0-9]')
            list_of_searches.append('['+str(int(ten_p[len(ten_p)-1]/10))+'][0-'+str(ten_p[len(ten_p)-1]%10)+']')
        elif int(ten_p[len(ten_p)-1]/10)-int(ten_p[0]/10)>=3:
            list_of_searches.append('['+str(int(ten_p[0]/10))+']['+str(ten_p[0]%10)+'-9]')
            list_of_searches.append('['+str(int(ten_p[0]/10)+1)+'-'+str(int(ten_p[len(ten_p)-1]/10)-1)+'][0-9]')
            list_of_searches.append('['+str(int(ten_p[len(ten_p)-1]/10))+'][0-'+str(ten_p[len(ten_p)-1]%10)+']')

    if len(hund_p)>0:
        for i in range(0,len(hund_p)):
            hund_p[i]=hund_p[i]-100
        if int(hund_p[len(hund_p)-1]/10)-int(hund_p[0]/10)==0:
            list_of_searches.append('[1]['+str(int(hund_p[0]/10))+']['+str(hund_p[0]%10)+'-'+str(hund_p[len(hund_p)-1]%10)+']')
        elif int(hund_p[len(hund_p)-1]/10)-int(hund_p[0]/10)==1:
            list_of_searches.append('[1]['+str(int(hund_p[0]/10))+']['+str(hund_p[0]%10)+'-9]')
            list_of_searches.append('[1]['+str(int(hund_p[len(hund_p)-1]/10))+'][0-'+str(hund_p[len(hund_p)-1]%10)+']')
        elif int(hund_p[len(hund_p)-1]/10)-int(hund_p[0]/10)==2:
            list_of_searches.append('[1]['+str(int(hund_p[0]/10))+']['+str(hund_p[0]%10)+'-9]')
            list_of_searches.append('[1]['+str(int(hund_p[0]/10)+1)+'][0-9]')
            list_of_searches.append('[1]['+str(int(hund_p[len(hund_p)-1]/10))+'][0-'+str(hund_p[len(hund_p)-1]%10)+']')
        elif int(hund_p[len(hund_p)-1]/10)-int(hund_p[0]/10)>=3:
            list_of_searches.append('[1]['+str(int(hund_p[0]/10))+']['+str(hund_p[0]%10)+'-9]')
            list_of_searches.append('[1]['+str(int(hund_p[0]/10)+1)+'-'+str(int(hund_p[len(hund_p)-1]/10)-1)+'][0-9]')
            list_of_searches.append('[1]['+str(int(hund_p[len(hund_p)-1]/10))+'][0-'+str(hund_p[len(hund_p)-1]%10)+']')

    if len(twohun_p)>0:
        for i in range(0,len(twohun_p)):
            twohun_p[i]=twohun_p[i]-200
        if int(twohun_p[len(twohun_p)-1]/10)-int(twohun_p[0]/10)==0:
            list_of_searches.append('[2]['+str(int(twohun_p[0]/10))+']['+str(twohun_p[0]%10)+'-'+str(twohun_p[len(twohun_p)-1]%10)+']')
        elif int(twohun_p[len(twohun_p)-1]/10)-int(twohun_p[0]/10)==1:
            list_of_searches.append('[2]['+str(int(twohun_p[0]/10))+']['+str(twohun_p[0]%10)+'-9]')
            list_of_searches.append('[2]['+str(int(twohun_p[len(twohun_p)-1]/10))+'][0-'+str(twohun_p[len(twohun_p)-1]%10)+']')
        elif int(twohun_p[len(twohun_p)-1]/10)-int(twohun_p[0]/10)==2:
            list_of_searches.append('[2]['+str(int(twohun_p[0]/10))+']['+str(twohun_p[0]%10)+'-9]')
            list_of_searches.append('[2]['+str(int(twohun_p[0]/10)+1)+'][0-9]')
            list_of_searches.append('[2]['+str(int(twohun_p[len(twohun_p)-1]/10))+'][0-'+str(twohun_p[len(twohun_p)-1]%10)+']')
        elif int(twohun_p[len(twohun_p)-1]/10)-int(twohun_p[0]/10)>=3:
            list_of_searches.append('[2]['+str(int(twohun_p[0]/10))+']['+str(twohun_p[0]%10)+'-9]')
            list_of_searches.append('[2]['+str(int(twohun_p[0]/10)+1)+'-'+str(int(twohun_p[len(twohun_p)-1]/10)-1)+'][0-9]')
            list_of_searches.append('[2]['+str(int(twohun_p[len(twohun_p)-1]/10))+'][0-'+str(twohun_p[len(twohun_p)-1]%10)+']')

    for items in list_of_searches:
        if mask in (8,16,24):
            pass
        else:
            expressions_list.append(begin_ex+items+end_ex)
    expressions_list_full =f'{or_logic}'.join([ranget for ranget in expressions_list])
    return expressions_list_full

def toRegex(subnet: str, or_logic: str = '|'):
        '''
            Returns a RegEx pattern to match the given subnet.  Works for both IPv4 and IPv6.
            -----
            Parameters
            ---
            subnet: Subnet class object
                Subnet to get RegEx pattern of.
            or_logic: str
                Symbol to be used as OR, default it |.
            -----
            Returns
            ---
            regex_pattern: str
                RegEx pattern to match every IP address in the given subnet.
            -----
            Raises
            ---
            ValueError
                If given subnet address is not a valid format.
        '''
        subnet_split = subnet.split('/')
        iptype = ip_type(subnet_split[0])
        if iptype == 'v4':
            regex_pattern = toRegexv4(subnet, or_logic)
        elif iptype == 'v6':
            regex_pattern = toRegexv6(subnet, or_logic)
        else:
            raise ValueError(f'{subnet} is not a valid IPv4 or IPv6 subnet address')
        return regex_pattern

def ip_type(address: str):
    '''
        Given an IP or subnet will return 'v4' if IPv4 or 'v6' if IPv6.  Can also be used to validate IP and subnet addresses.
        -----
        Parameters
        ---
        ip: str
            IP address in decimal or hexadecimal notation.
        -----
        Returns
        ---
        iptype: str
            IP address type, either v4 or v6, or None if provided string isn't a valid IP address.
        -----
        Raises
        ---
        TyperError
            If input parameter is not of type string.
        ValueError
            If the network mask is invalid.  Expected values are between 0 and 32 for IPv4 and between 0 and 128 for IPv6.
            If the number of octets or hexadecatets is invalid.  Expected values are 4 and 8 for IPv4 and IPv6 respectively.
            If an invalid decimal or hexadecimal is provided. Expected decimal values are between 0 and 255 for IPv4 and expected hexadecial values are between 0 and ffff for IPv6.
            If an invalid IPv4 or IPv6 format is used.  Includes missing periods or colons as well as multiple zero contractions in IPv6.
    '''
    if type(address) == type(''):
        if '/' in address:
            address, mask = address.split('/')[0], int(address.split('/')[1])
        else:
            mask = 0
        if '.' in address:
            if mask not in range(0,33):
                raise ValueError(f'Invalid IPv4 network mask: mask should be integer between 0 and 32. {mask} does not fall in that range.')
            ip_split = address.split('.')
            if len(ip_split) == 4:
                for octet in ip_split:
                    if int(octet) not in range(0,256):
                        raise ValueError(f'Invalid decimal value: each octet should be a decimal value between 0 and 255. {octet} does not fall in that range.')
                iptype = 'v4'
                return iptype
            else:
                raise ValueError(f'Wrong number of octets: there should be 4 octets.  The IP provided contains {len(ip_split)} octets.')
        elif ':' in address:
            if mask not in range(0,129):
                raise ValueError(f'Invalid IPv6 network mask: mask should be integer between 0 and 128. {mask} does not fall in that range.')
            if address.count('::') > 1:
                count = address.count('::')
                raise ValueError(f'Too many zero contractions: IPv6 addresses can only have a single set of 0s contracted to "::". The IP provided contains {count} contractions.')
            else:
                ip_split = address.split(':')
                if len(ip_split) > 8:
                    raise ValueError(f'Wrong number of hexadecatets: there should be 8 hexadecatets.  The IP provided contains {len(ip_split)} hexadecatets.')
                elif '::' not in address and len(ip_split) != 8:
                    raise ValueError(f'Wrong number of hexadecatets: there should be 8 hexadecatets.  The IP provided contains {len(ip_split)} hexadecatets.')
                else:
                    for hexadecatet in ip_split:
                        if hexadecatet == '':
                            hexadecatet = '0'
                        if int(hexadecatet, 16) not in range(0,65536):
                            raise ValueError(f'Invalid hexadecimal value: each hexadecatet should be a hexadecimal value between 0 and ffff. {hexadecatet} does not fall in that range.')
                    iptype = 'v6'
                    return iptype
        else:
            raise ValueError(f'Invalid format: {address} is not a valid IPv4 or IPv6 address.')
    else:
        raise TypeError(f'IP should be a string not {type(address)}.')

def ipv6_expand(ipv6: str):
    '''
        Given a shortened IPv6 or subnet address will return the unshortened version.
        -----
        Parameters
        ---
        ipv6: str
            IPv6 or subnet address in hexadecimal notation.
        -----
        Returns
        ---
        expanded: str
            Expanded IPv6 or subnet address.  Adds leading zeros and expands contraced zeros.
    '''
    iptype = ip_type(ipv6)
    if iptype == 'v4':
        raise ValueError('Invalid IP type: IP must be v6.')
    if '/' in ipv6:
        ipv6, mask = ipv6.split('/')[0], ipv6.split('/')[1]
    else:
        mask = ''
    split = ipv6.split(':')
    zeros = ['0000' for i in range(0,9-len(split))]
    new_split = []
    for hexadecatet in split:
        if hexadecatet == '':
            new_split += zeros
        elif hexadecatet == '0':
            new_split.append('0000')
        elif len(hexadecatet) < 4:
            for i in range(0,4-len(hexadecatet)):
                hexadecatet = '0' + hexadecatet
            new_split.append(hexadecatet)
        else:
            new_split.append(hexadecatet)
    if mask == '':
        new_ipv6 = ':'.join(new_split)
    else:
        new_ipv6 = ':'.join(new_split) + '/' + mask
    return new_ipv6

def ipv6_contract(ipv6: str):
    '''
        Given an unshortened IPv6 or subnet address return contracted version.
        -----
        Parameters
        ---
        ipv6: str
            IPv6 or subnet address in hexadecimal notation.
        -----
        Returns
        ---
        contracted: str
            Shortened IPv6 or subnet address.  Removes leading zeros and contracts largest set of repeating zero hexadecatets.
    '''
    iptype = ip_type(ipv6)
    ipv6 = ipv6_expand(ipv6)
    if iptype == 'v4':
        raise ValueError('Invalid IP type: IP must be v6.')
    if '/' in ipv6:
        ipv6, mask = ipv6.split('/')[0], ipv6.split('/')[1]
    else:
        mask = ''
    ipv6_split = ipv6.split(':')
    ipv6_contracted = []
    #Remove leading zeros
    for hexadecatet in ipv6_split:
        while hexadecatet[0] == '0' and len(hexadecatet) > 1:
                hexadecatet = hexadecatet[1:]
        ipv6_contracted.append(hexadecatet)
    #Remove largest set of repeating zero hexadecatets
    #Find largest set of repeating zeros
    i=0
    replacing_zeros = []
    while i < 8:
        zeros = []
        if ipv6_contracted[i] == '0':
            zeros.append(i)
            j=1
            while ipv6_contracted[i+j] == '0':
                zeros.append(i+j)
                j+=1
            i+=j
            if len(zeros) >= len(replacing_zeros):
                replacing_zeros = zeros
        else:
            i+=1
    #Replace first zeros with empty string and remove the rest
    ipv6_contracted[replacing_zeros[0]] = ''
    i = 0
    for item in replacing_zeros[1:]:
        ipv6_contracted.pop(item-i)
        i += 1
    if mask == '':
        ipv6_contracted = ':'.join(ipv6_contracted)
    else:
        ipv6_contracted = ':'.join(ipv6_contracted) + '/' + mask
    return ipv6_contracted

def ip2bin(ip: str):
    '''
        Given an IP or subnet will return the IP in binary format.  Works for both IPv4 and IPv6.
        -----
        Parameters
        ---
        ip: str
            IP or subnet address in decimal or hexadecimal notation.
        -----
        Returns
        ---
        bin_ip: str
            Same IP address in binary format.
        bin_mask: str
            For subnet inputs, subnet mask in binary format.
    '''
    iptype = ip_type(ip)
    if '/' in ip:
        ip, mask = ip.split('/')[0], int(ip.split('/')[1])
    else:
        mask = None
    bin_ip = ''
    if iptype == 'v4':
        split_ip = ip.split('.')
        for octet in split_ip:
            octet = format(int(octet), '08b')
            bin_ip += octet
        if mask is not None:
            bin_mask = ''.join(['1' if i < mask else '0' for i in range(0,32)])
            return bin_ip, bin_mask
    elif iptype == 'v6':
        ip = ipv6_expand(ip)
        split_ip = ip.split(':')
        for octet in split_ip:
            octet = format(int(octet, 16), '016b')
            bin_ip += octet
        if mask is not None:
            bin_mask = ''.join(['1' if i < mask else '0' for i in range(0,128)])
            return bin_ip, bin_mask
    return bin_ip

def bin2ip(bin_ip: str, bin_mask: str = None):
    '''
        Given an IP, and optionally a network mask, in binary format will return the IP or subnet address in decimal, if IPv4, or hexadecimal, if IPv6, format.
        -----
        Parameters
        ---
        bin_ip: str
            IP address in binary format.
        bin_mask: str, optional
            Network mask in binary forat.
        -----
        Returns
        ---
        ip_address: str
            Same IP address in decimal or hexadecimal format.
        subnet_address: str
            Subnet address in decimal or hexadecimal format, assuming binary network ask was provided.
        -----
        Raises
        ---
        ValueError
            If any digits other than 0 or 1 are used in the binary format.
            If given binary string is not a valid IP address; it must be 32 digits for IPv4 and 128 digits for IPv6.
    '''
    if len(bin_ip) == 32:
        octets = [bin_ip[i:i+8] for i in range(0,32,8)]
        ip_address = '.'.join([str(int(octet,2)) for octet in octets])
    elif len(bin_ip) == 128:
        hexadecatets = [bin_ip[i:i+16] for i in range(0,128, 16)]
        ip_address = ':'.join([format(int(hexadecatet, 2), 'x') for hexadecatet in hexadecatets])
    else:
        raise ValueError(f'''{bin_ip} is not a valid binary IP address.  A binary IP address should either be 32 or 128 bits long for IPv4 and IPv6 address respectively.
                            The binary number you provided is {len(bin_ip)} bits long.''')
    if bin_mask is None:
        return ip_address
    else:
        mask = bin_mask.count('1')
        subnet_address = ip_address + '/' + str(mask)
        return subnet_address

def in_subnet(ip: str, subnet: str):
    '''
        Given an IP and a subnet will return True if the IP is in that subnet, will return False if otherwise.  Works for both IPv4 and IPv6.
        -----
        Parameter
        ---
        ip: str
            IP address.
        subnet: str
            Subnet address.
        -----
        Returns
        ---
        bool
            True if IP is in the given subnet, otherwise returns False.
    '''
    subnet_split = subnet.split('/')
    network = subnet_split[0]
    mask = int(subnet_split[1])
    #Convert the IP to binary
    bin_ip = ip2bin(ip)
    #Convert the subnet to binary
    bin_network = ip2bin(network)
    #Compare the network portion of the IP and the subnet to see if they match.
    if bin_ip[:mask] == bin_network[:mask]:
        return True
    else:
        return False


import sys
from PyQt5.QtWidgets import *

# from PyQt5.QtWidgets import QLabel
class Wİndow(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Label Widget")
        self.setGeometry(1000, 300, 300, 450)
        self.Label()

    def Label(self):
        label1 = QLabel("Hello PyQt5", self)  # self parametresini kullanmazsak pencerede gösteremeyiz
        label1.move(50,50) # x düzleminde 50 px gitsin, y düzleminde 100 px gitsin
        label2 = QLabel("PyQt5 is the very good",self)
        label2.move(50,80)
        self.show()

def main():
    App = QApplication(sys.argv)
    window = Wİndow()
    sys.exit(App.exec_())

if __name__ == "__main__":
    main()