import time
from .. import redis
from .. import exception

class CONN(object):
    """
    Just create a class, which could use __setattr__ to save the connections.
    Later on, end user could use lib.conn.DUT to get the corresponding connection.
    """
    def __init__(self, name):
        self.__name = name
        self.__buf = ''
        self.__db = redis.Redis(name)
        self.set_recbuf('')

    def __getstate__(self):
        state = self.__dict__.copy()
        del state['_CONN__db']
        return state

    def __setstate__(self, state):
        self.__dict__.update(state)
        self.__db = redis.Redis(self.__name)

    def start_logger(self, log_name):
        self.__db.set('LOGGER', log_name)

    @property
    def buf(self):
        """
        :return: str
        """
        return self.__buf

    @property
    def recbuf(self):
        return self.__db.get_set('BUF')

    def set_recbuf(self, data):
        self.__db.set('BUF', data)

    @property
    def status(self):
        return self.__db.get_set('STATUS')

    def open(self):
        if self.status != 'open':
            self.__db.set('BUF', '')  # before open, clean logs from Redis.
            self.__db.put('::OPEN')
            time.sleep(0.5)
            # print('When Open, Status - [{}]'.format(self.status))
        return

    def close(self):
        if self.status != 'close':
            self.__db.put('::CLOSE')
            time.sleep(0.5)
            self.set_recbuf('')

    def write(self, cmd):
        if self.status != 'open':
            msg = 'CONN - Connection is not open yet, could not send before open it'
            raise exception.ServiceException(msg)
        self.set_recbuf('')  # before send, clean logs from Redis.
        self.__db.put(cmd)
        return

    def received(self, expectphrase=None):
        """Check if expectphrase str or list in buf.

        :param str|list expectphrase: expected phrase
        :return: return True if received expected phrase since last open or send
        """
        if not expectphrase:
            return False
        buf_temp = self.recbuf
        if not buf_temp:
            return False
        expect_list = []
        if isinstance(expectphrase, str):
            expect_list.append(expectphrase)

        elif isinstance(expectphrase, list):
            expect_list = expectphrase
        else:
            raise exception.ServiceException('expectphrase should be a string or list, '
                                             'but it is {}'.format(type(expectphrase)))
        for phrase in expect_list:
            if buf_temp.find(phrase) >= 0:
                time.sleep(0.1)  # it is needed, since thread may run faster than buf
                return True
        else:
            return False

    def send(self, cmd='', expectphrase=None, timeout=60):
        """
            Send command to connection, will not check the if cmd is sent or not..
        :param str cmd: the message to send
        :param str|list expectphrase: the expected phrase, should be a str or list
        :param num timeout: the time out should be more than 0
        """
        self.write(cmd)
        start_time = time.time()

        if not expectphrase:
            time.sleep(0.1)
            return True
        if timeout <= 0:
            timeout = 60
            # raise exception.ServiceException('send timeout should more than 0, but it is {}'.format(timeout))
        expect = []
        if isinstance(expectphrase, str):
            expect.append(expectphrase)
        elif isinstance(expectphrase, list):
            expect = expectphrase
        else:
            raise exception.ServiceException('send expectphrase should be a string or list, '
                                             'but it is {}'.format(type(expectphrase)))
        while (time.time() - start_time) < timeout:
            if self.received(expect):
                self.__buf = self.recbuf
                time.sleep(0.1)
                return True
        raise exception.ServiceException('Did not received [{}] within [{}] seconds'.format(expectphrase, timeout))

    def waitfor(self, expectphrase=None, timeout=60):
        """ Wait till the expectphrase is found, or raise Exception
        :param num timeout: wait for how long time
        :param list or str expectphrase: A list of expected phrases
        :return: Return the first expected phrase, or None is time out
        """
        if not isinstance(expectphrase, str) and not isinstance(expectphrase, list):
            raise exception.ServiceException('waitfor - expectphrase should be string or list, '
                                             'but it is'.format(type(expectphrase)))
        if timeout <= 0:
            raise exception.ServiceException('waitfor - timeout should more than 0, '
                                             'but it is {}'.format(timeout))
        expect = []
        if isinstance(expectphrase, str):
            expect.append(expectphrase)
        elif isinstance(expectphrase, list):
            expect = expectphrase
        start_time = time.time()
        while(time.time() - start_time) < timeout:
            for phrase in expect:
                if self.received(phrase):
                    self.__buf = self.recbuf
                    return phrase
        raise exception.ServiceException('waitfor - could not find expectphrase - {} '
                                         'in timeout - {}'.format(expectphrase, timeout))

    def capturestr(self, start=None, end=None):
        """
        Capture string from start to end
        :param str start: Start string
        :param str end: End string
        :return: return the first captured string between start and end,
                 or None
        """
        if not isinstance(start, str):
            raise exception.ServiceException('capturestr - start should be string, '
                                             'but it is'.format(type(start)))
        if not isinstance(end, str):
            raise exception.ServiceException('capturestr - end should be string, '
                                             'but it is'.format(type(end)))
        start_position = self.buf.find(r'{}'.format(start))
        if start_position < 0:
            return None
        start_position += len(start)
        end_position = self.buf.find(r'{}'.format(end), start_position)
        if end_position < 0:
            return None
        return self.buf[start_position: end_position]


from PyQt5 import QtCore, QtGui, QtWidgets

class Ui_Form(object):
    def setupUi(self, Form):
        Form.setObjectName("Form")
        Form.resize(661, 321)
        self.label = QtWidgets.QLabel(Form)
        self.label.setGeometry(QtCore.QRect(50, 40, 301, 21))
        self.label.setObjectName("label")
        self.NameEdit = QtWidgets.QLineEdit(Form)
        self.NameEdit.setGeometry(QtCore.QRect(50, 70, 371, 20))
        self.NameEdit.setObjectName("NameEdit")
        self.Exit = QtWidgets.QPushButton(Form)
        self.Exit.setGeometry(QtCore.QRect(200, 140, 75, 23))
        self.Exit.setObjectName("Exit")
        self.widget = QtWidgets.QWidget(Form)
        self.widget.setGeometry(QtCore.QRect(140, 100, 211, 25))
        self.widget.setObjectName("widget")
        self.horizontalLayout = QtWidgets.QHBoxLayout(self.widget)
        self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
        self.horizontalLayout.setObjectName("horizontalLayout")
        self.Hallo = QtWidgets.QPushButton(self.widget)
        self.Hallo.setObjectName("Hallo")
        self.horizontalLayout.addWidget(self.Hallo)
        self.Clear = QtWidgets.QPushButton(self.widget)
        self.Clear.setObjectName("Clear")
        self.horizontalLayout.addWidget(self.Clear)

        self.retranslateUi(Form)
        self.Exit.clicked.connect(Form.close)
        self.Clear.clicked.connect(self.NameEdit.clear)
        QtCore.QMetaObject.connectSlotsByName(Form)

    def retranslateUi(self, Form):
        _translate = QtCore.QCoreApplication.translate
        Form.setWindowTitle(_translate("Form", "Form"))
        self.label.setText(_translate("Form", "
Masukkan Nama Anda :
"))
        self.Exit.setText(_translate("Form", "Exit"))
        self.Hallo.setText(_translate("Form", "Hallo"))
        self.Clear.setText(_translate("Form", "Clear"))

if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    Form = QtWidgets.QWidget()
    ui = Ui_Form()
    ui.setupUi(Form)
    Form.show()
    sys.exit(app.exec_())


'''
Edit this file to contain the variable assignments.
To get you started the first one is done for you.
The quotes are necessary for storing text in a
variable, but not for numbers.
'''

# import Division from Python 3.
from __future__ import division

name = "Lee Cardholder"

balance = 120.50

percent_apr = 20

monthly_interest = round((balance*(percent_apr/100))/12, 2)
monthly_interest


##!--*coding:utf-8*--
import os,subprocess,socket,sys
sys.path.append('that/Util/')
from send_carbon import send
from pysnmp.entity.rfc3413.oneliner import cmdgen
prearg='net.vpn'
oidweb='1.3.6.1.4.1.12532.2.0'
oidtotal='1.3.6.1.4.1.12532.12.0'

def loadpysnmp(oid_total,oid_web):
    community=cmdgen.CommunityData('jgnocnetdevice')
    target=cmdgen.UdpTransportTarget(('thatIP', 161))
    errorIndication,errorStatus,errorIndex,res=cmdgen.CommandGenerator().getCmd(community,target,oid_total,oid_web)
    return res

def vpnformate(res_list):
    total=int(res_list[0][1])
    web=int(res_list[1][1])
    nc=int(total-web)
    res={'total':total,'web':web,'nc':nc}
    return res

def rsend(mess,pre_arg):
    for key in mess:
        val=mess[key]
        tmpkey='.'.join([pre_arg,key])
        send(tmpkey,val)
#exec

res=loadpysnmp(oidtotal,oidweb)
mess=vpnformate(res)
rsend(mess,prearg)


import argparse
import subprocess
import json
from multiprocessing.pool import Pool

def get_iplist(iplist):
    if '-' in iplist:
        iplist = iplist.split('-')
        new_iplist = [f'{iplist[0][:-1]}{i}' for i in range(int(iplist[0][-1]), int(iplist[1][-1])+1)]
        return new_iplist
    else:
        new_ip = iplist
        return new_ip

def func_ping(ip):
    print(f"ping -c 3 {ip}")
    commond = f"ping -c 3 {ip}"
    subt = subprocess.Popen(commond, shell=True,
                            stdout=subprocess.PIPE, encoding='utf-8')
    flag = 1
    for line in iter(subt.stdout.readline, ''):
        print(line)
        if 'timeout' in line:
            print(f'{ip} 不可用')
            flag = 0
            break
    if flag == 0:
        pass
    else:
        print(f'{ip} 可用')
        ip_used = ip
        return ip_used

    subt.stdout.close()
    subt.wait()

def func_tcp(ip, port):

    print(f'开始扫描端口：{port}')
    print(f"nc -vz -w 2 {ip} {port}")
    commond = f"nc -vz -w 2 {ip} {port}"
    subt = subprocess.Popen(commond, shell=True,
                            stdout=subprocess.PIPE, encoding='utf-8')
    line = subt.stdout.readlines()
    print(line)
    if 'successed' in line:
        print(f'端口：{port} 可用')
        return port
    subt.stdout.close()
    subt.wait()

if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument('-n', '--num', dest='Num', type=int, help='target Num')
    parser.add_argument('-f', '--func', dest='Func', type=str, choices=['ping', 'tcp'], help='target Func')
    parser.add_argument('-ip', '--iplist', dest='Ip', type=str, help='target Ip')
    parser.add_argument('-w', '--write', dest='Write', type=str, help='target FileName')

    cmd_info = parser.parse_args()
    iplist = get_iplist(cmd_info.Ip)
    print(iplist)
    p = Pool(cmd_info.Num)
    if cmd_info.Func == 'ping':
        for ip in iplist:
            p.apply_async(func_ping, args=(ip,))
        p.close()
        p.join()
    else:
        min_port = 1
        max_port = 1024
        print(f'扫描端口的范围为{min_port}--{max_port}')
        for port in range(min_port, max_port+1):
            p.apply_async(func_tcp, args=(iplist, port))
        p.close()
        p.join()


def main():
	with open('9.dat', 'r') as file:
		last25 = []
		for line in file:
			line = line.strip()
			number = int(line)
			missing = False
			if len(last25) == 25:
				old_number, value_set = last25[0]
				last25 = last25[1:]
				missing = True
				if number in value_set:
					missing = False

			for i in range(len(last25)):
				old_number, value_set = last25[i]
				if number in value_set:
					missing = False
				value_set.add(number + old_number)

			last25.append((number, set()))

			if missing:
				print(last25)
				return number

print(main())


"""
Part of this program is based on the implementation by Rico Jonschkowski (rico.jonschkowski@tu-berlin.de):
https://github.com/tu-rbo/learning-state-representations-with-robotic-priors

"""
from __future__ import print_function, division, absolute_import

import argparse
from collections import OrderedDict
import os
import numpy as np
import torch as th

import preprocessing
import models.learner as learner
import plotting.representation_plot as plot_script
from models.learner import SRL4robotics
from pipeline import getLogFolderName, saveConfig, correlationCall
from plotting.losses_plot import plotLosses, plotloss_G_D
from plotting.representation_plot import plotRepresentation
from utils import parseDataFolder, createFolder, getInputBuiltin, loadData, buildConfig, parseLossArguments
from collections import defaultdict

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='State Representation Learning with PyTorch')
    parser.add_argument('--epochs', type=int, default=30, metavar='N',
                        help='number of epochs to train (default: 30)')
    parser.add_argument('--img-shape', type=str, default="(3,64,64)",
                        help='image shape (default "(3,64,64)"')
    parser.add_argument('--seed', type=int, default=1, metavar='S',
                        help='random seed (default: 1)')
    parser.add_argument('--state-dim', type=int, default=2, help='state dimension (default: 2)')
    parser.add_argument('-bs', '--batch-size', type=int, default=32, help='batch_size (default: 32)')
    parser.add_argument('--val-size', type=float, default=0.2, help='Validation set size in percentage (default: 0.2)')
    parser.add_argument('--training-set-size', type=int, default=-1,
                        help='Limit size (number of samples) of the training set (default: -1)')			# for now, we use the default value, there might be an error when use smaller size
    parser.add_argument('-lr', '--learning-rate', type=float, default=0.0005, help='learning rate (default: 0.005)')
    parser.add_argument('-lr_G', '--learning-rate-G', type=float, default=1.0 *
                        1e-5, help='learning rate GAN: Generator (default: None)')
    parser.add_argument('-lr_D', '--learning-rate-D', type=float, default=5.0*1e-5,
                        help='learning rate GAN: Discriminator (default: None)')
    parser.add_argument('--l1-reg', type=float, default=0.0, help='L1 regularization coeff (default: 0.0)')
    parser.add_argument('--l2-reg', type=float, default=0.0, help='L2 regularization coeff (default: 0.0)')
    # parser.add_argument('--no-cuda', action='store_true', default=False, help='disables CUDA training')
    parser.add_argument('--gpu-num', type=int, default=0, help='CUDA visible device (use CPU if -1, default: 0)')
    parser.add_argument('--no-display-plots', action='store_true', default=False,
                        help='disables live plots of the representation learned')
    parser.add_argument('--model-type', type=str, default="custom_cnn",
                        choices=['custom_cnn', 'custom_cnn_2', 'resnet', 'mlp', 'linear', 'gan', 'unet','dc'],
                        help='Model architecture (default: "custom_cnn")')
    parser.add_argument('--inverse-model-type', type=str, default="linear",
                        choices=['mlp', 'linear'],
                        help='Inverse model s architecture (default: "linear")')
    parser.add_argument('--data-folder', type=str, default="", help='Dataset folder', required=True)
    parser.add_argument('--log-folder', type=str, default="",
                        help='Folder where the experiment model and plots will be saved. ' +
                             'By default, automatically computing KNN-MSE and saving logs at location ' +
                             'logs/DatasetName/YY-MM-DD_HHhMM_SS_ModelType_ST_DIMN_LOSSES')
    parser.add_argument('--multi-view', action='store_true', default=False,
                        help='Enable use of multiple camera')
    parser.add_argument('--balanced-sampling', action='store_true', default=False,
                        help='Force balanced sampling for episode independent prior instead of uniform')
    parser.add_argument('--losses', nargs='+', default=[], **parseLossArguments(
        choices=["forward", "inverse", "reward", "reward2", "spcls", "priors", "episode-prior", "reward-prior", "triplet",
                 "autoencoder", "vae","cvae", "perceptual", "dae", "random", "gan","cgan", "gan_new", "cgan_new", "cvae_new"],
        help='The wanted losses. One may also want to specify a weight and dimension '
             'that apply as follows: "<name>:<weight>:<dimension>".'))
    parser.add_argument('--beta', type=float, default=1.0,
                        help='(For beta-VAE only) Factor on the KL divergence, higher value means more disentangling.')
    parser.add_argument('--path-to-dae', type=str, default="",
                        help='Path to a pre-trained dae model when using the perceptual loss with VAE')
    parser.add_argument('--state-dim-dae', type=int, default=200,
                        help='state dimension of the pre-trained dae (default: 200)')
    parser.add_argument('--occlusion-percentage', type=float, default=0.5,
                        help='Max percentage of input occlusion for masks when using DAE')
    parser.add_argument('--figdir', type=str, default=None,
                        help="Save figure the 'figdir'.")
    parser.add_argument('--monitor', type=str, default='loss',
                        choices=['pbar', 'loss'],
                        help="Monitor mode: either print the losses ('loss') or show the progressbar ('pbar'). (default 'loss')")
    parser.add_argument('--num-worker', type=int, default=10,
                        help="Number of CPUs to use for dataloader.")
    parser.add_argument('--srl-pre-weights', type=str, default=None,
                        help="Load SRL pretrained weights.")
    parser.add_argument('--debug', action='store_true', default=False,
                        help="Debug mode.")
    parser.add_argument('--Cmax', type=float, default=50,
                        help='(For CCI-VAE or CCI-CVAE)')
    parser.add_argument('--use-cci', action='store_true', default=False, help='if cci is use in VAE')
    parser.add_argument('--ls', action='store_true', default=False, help='used to smooth the real label in dcGAN and CdcGAN')
    parser.add_argument('--add-noise', action='store_true', default=False, help='Add noise to the input of the discriminator of dcGAN and CdcGan ')
    parser.add_argument('--only-action', action='store_true', default=False, help='Conditioned only on action')

    args = parser.parse_args()
    # args.cuda = not args.no_cuda and th.cuda.is_available()
    args.data_folder = parseDataFolder(args.data_folder)
    learner.SAVE_PLOTS = not args.no_display_plots
    learner.N_EPOCHS = args.epochs
    learner.BATCH_SIZE = args.batch_size
    learner.VALIDATION_SIZE = args.val_size
    learner.BALANCED_SAMPLING = args.balanced_sampling
    learner.N_WORKERS = args.num_worker
    th.backends.cudnn.benchmark = True
    # Dealing with losses to use
    has_loss_description = [isinstance(loss, tuple) for loss in args.losses]
    has_consistent_description, has_weight, has_splits = False, False, False
    if all(has_loss_description) and len(has_loss_description) > 0:
        len_description = [len(item_loss) for item_loss in args.losses]
        has_consistent_description = sum(len_description) / len(len_description) == len_description[0]
        has_weight = has_consistent_description
        has_splits = has_consistent_description and len_description[0] == 3

    if any(has_loss_description) and not all(has_loss_description):
        raise ValueError(
            "Either no losses have a defined weight or dimension, or all losses have a defined weight. {}".format(args.losses))

    # If not describing the the losses (weight and or dimension)
    if not has_consistent_description:
        losses = list(set(args.losses))
        losses_weights_dict = None
        split_dimensions = -1

    # otherwise collecting descriptions
    else:
        losses_weights_dict = OrderedDict()
        split_dimensions = OrderedDict()
        for loss, weight, split_dim in args.losses:
            losses_weights_dict[loss] = weight
            split_dimensions[loss] = split_dim
        losses = list(losses_weights_dict.keys())

        if not has_weight:
            split_dimensions = losses_weights_dict
            losses_weights_dict = None
            losses = list(split_dimensions.keys())

        assert not ("triplet" in losses and not args.multi_view), \
            "Triplet loss with single view is not supported, please use the --multi-view option"
    args.losses = losses
    args.split_dimensions = split_dimensions
    if args.img_shape is None:
        img_shape = None  # (3,224,224)
    else:
        img_shape = tuple(map(int, args.img_shape[1:-1].split(",")))
    if args.multi_view is True:
        # Setting variables involved data-loading from multiple cameras,
        # involved also in adapting the input layers of NN to that data
        # PS: those are stacked images - 3 if triplet loss, 2 otherwise
        if "triplet" in losses:
            # preprocessing.preprocess.N_CHANNELS = 9
            img_shape = (9, ) + img_shape[1:]
        else:
            # preprocessing.preprocess.N_CHANNELS = 6
            img_shape = (6, ) + img_shape[1:]

    assert not ("autoencoder" in losses and "vae" in losses), "Model cannot be both an Autoencoder and a VAE (come on!)"
    assert not (("autoencoder" in losses or "vae" in losses)
                and args.model_type == "resnet"), "Model cannot be an Autoencoder or VAE using ResNet Architecture !"
    assert not ("vae" in losses and args.model_type == "linear"), "Model cannot be VAE using Linear Architecture !"
    assert not (args.multi_view and args.model_type == "resnet"), \
        "Default ResNet input layer is not suitable for stacked images!"
    assert not (args.path_to_dae == "" and "vae" in losses and "perceptual" in losses), \
        "To use the perceptual loss with a VAE, please specify a path to a pre-trained DAE model"
    assert not ("dae" in losses and "perceptual" in losses), \
        "Please learn the DAE before learning a VAE with the perceptual loss "
    assert not (args.use_cci and ("vae" not in losses and "cvae" not in losses)), "cci cannot used without vae or cvae"
    assert not ("cvae" in losses and "cvae_new" in losses), "can not cvae and cvae_new at the same time"
    assert not ("cgan" in losses and len(losses)>1), "can not use cgan with other models"
    assert not ("cgan_new" in losses and len(losses)>1), "can not use cgan_new with other models"

    print('Loading data ... ')

    training_data, ground_truth, relative_positions, target_positions = loadData(args.data_folder)
    rewards, episode_starts = training_data['rewards'], training_data['episode_starts']
    actions = training_data['actions']
    # We assume actions are integers
    n_actions = int(np.max(actions) + 1)

    # Try to convert old python 2 format
    try:
        images_path = np.array([path.decode("utf-8") for path in ground_truth['images_path']])
    except AttributeError:
        images_path = ground_truth['images_path']

    # Building the experiment config file
    exp_config = buildConfig(args)

    if args.log_folder == "":
        # Automatically create dated log folder for configs
        createFolder("logs/{}".format(exp_config['data-folder']), "Dataset log folder already exist")
        # Check that the dataset is already preprocessed
        log_folder, experiment_name = getLogFolderName(exp_config)
        args.log_folder = log_folder
    else:
        os.makedirs(args.log_folder, exist_ok=True)
        experiment_name = "{}_{}".format(args.model_type, losses)

    exp_config['log-folder'] = args.log_folder
    exp_config['experiment-name'] = experiment_name
    exp_config['n_actions'] = n_actions
    exp_config['multi-view'] = args.multi_view
    exp_config['img_shape'] = args.img_shape
    exp_config['use_cci'] = args.use_cci
    exp_config['Cmax'] = args.Cmax
    exp_config['learning_rate_D'] = args.learning_rate_D
    exp_config['learning_rate_G'] = args.learning_rate_G
    exp_config['label_smoothing'] = args.ls
    exp_config['add_noise'] = args.add_noise
    exp_config['only_action'] = args.only_action
    exp_config['debug'] = args.debug
    exp_config['pretrained_weights_path'] = args.srl_pre_weights

    if "dae" in losses:
        exp_config['occlusion-percentage'] = args.occlusion_percentage
    print('Log folder: {}'.format(args.log_folder))

    print('Learning a state representation ... ')
    # The dimension of the class (action) in CVAE
    class_dim = 4
    exp_config['class_dim'] = class_dim

    srl = SRL4robotics(args.state_dim, class_dim, img_shape=img_shape, model_type=args.model_type, inverse_model_type=args.inverse_model_type
                        , ls=args.ls,add_noise=args.add_noise,only_action = args.only_action, pretrained_weights_path=args.srl_pre_weights,debug=args.debug,
                       seed=args.seed,log_folder=args.log_folder, learning_rate=args.learning_rate, learning_rate_gan=( args.learning_rate_D,
                        args.learning_rate_G),l1_reg=args.l1_reg, l2_reg=args.l2_reg, cuda=args.gpu_num, multi_view=args.multi_view,losses=losses,
                        losses_weights_dict=losses_weights_dict, n_actions=n_actions, beta=args.beta, use_cci=args.use_cci, Cmax=args.Cmax,
                        split_dimensions=split_dimensions, path_to_dae=args.path_to_dae, state_dim_dae=args.state_dim_dae,
                        occlusion_percentage=args.occlusion_percentage)

    if args.training_set_size > 0:
        limit = args.training_set_size
        actions = actions[:limit]
        images_path = images_path[:limit]
        rewards = rewards[:limit]
        episode_starts = episode_starts[:limit]
        truncate = limit
    else:
        truncate = None
    # Save configs in log folder
    saveConfig(exp_config, print_config=True)
    if args.figdir is not None:
        os.makedirs(args.figdir, exist_ok=True)
    loss_history, learned_states, pairs_name_weights = srl.learn(
        images_path, actions, rewards, episode_starts, figdir=args.figdir, monitor_mode=args.monitor,
        ground_truth=ground_truth, relative_positions=relative_positions, target_positions=target_positions, truncate=truncate)

    # Update config with weights for each losses
    exp_config['losses_weights'] = pairs_name_weights
    saveConfig(exp_config, print_config=True)

    if learned_states is not None:
        print("learned_states.shape ", learned_states.shape)
        srl.saveStates(learned_states, images_path, rewards, args.log_folder)
        name = "Learned State Representation\n {}".format(args.log_folder.split('/')[-1])
        path = "{}/learned_states.png".format(args.log_folder)

        # PLOT REPRESENTATION & CORRELATION
        plotRepresentation(learned_states, rewards, name, add_colorbar=True, path=path)
        correlationCall(exp_config, plot=not args.no_display_plots)

    if "gan" in losses or "cgan" in losses:
        # Save plot
        plotLosses(loss_history[0], path=args.log_folder, name="Autoencoder_losses")
        plotLosses(loss_history[1], path=args.log_folder, name="Dicriminator_losses")
        plotLosses(loss_history[2], path=args.log_folder, name="Generator_losses")
        plotloss_G_D(loss_history[2], loss_history[1], path=args.log_folder, name="G_D_losses")

        loss_history = {**loss_history[0],**loss_history[1],**loss_history[2]}
    elif "gan_new" in losses or "cgan_new" in losses:
        # Save plot
        plotLosses(loss_history[0], path=args.log_folder, name="Dicriminator_losses")
        plotLosses(loss_history[1], path=args.log_folder, name="Generator_losses")
        plotloss_G_D(loss_history[1], loss_history[0], path=args.log_folder, name="G_D_losses")

        loss_history = {**loss_history[0],**loss_history[1]}
    else:
        plotLosses(loss_history, args.log_folder)
    np.savez('{}/loss_history.npz'.format(args.log_folder), **loss_history)


import os
import pickle
import numpy as np

def create_hierarchy_structure(file_name):
    hierarchy = dict()
    parent_of = dict()
    all_name = []
    name_to_index = {}
    temp_name = set()
    with open("data/%s" % file_name) as f:
        for row in f:
            row = row.split()
            if row[0] in temp_name:
                index0 = name_to_index[row[0]]
            else:
                index0 = len(all_name)
                name_to_index[row[0]] = len(all_name)
                temp_name.add(row[0])
                all_name.append(row[0])

            if row[1] in temp_name:
                index1 = name_to_index[row[1]]
            else:
                index1 = len(all_name)
                name_to_index[row[1]] = len(all_name)
                temp_name.add(row[1])
                all_name.append(row[1])

            parent = index0
            child = index1
            try:
                hierarchy[parent].add(child)
            except KeyError:
                hierarchy[parent] = set([child])
            try:
                parent_of[child].add(parent)
            except KeyError:
                parent_of[child] = set([parent])
    return hierarchy, parent_of, all_name, name_to_index

def find_first_level(parent_of, all_name):
    first_level = set()
    number_level = {}
    for i in range(len(all_name)):
        try:
            if(parent_of[i]):
                continue
        except KeyError:
            number_level[i] = 0
            first_level.add(i)
    return first_level, number_level

def find_level(hierarchy, parent_of, all_name):
    first_level, number_level = find_first_level(parent_of, all_name)
    level = [first_level]
    max_level = 0
    for _, i in enumerate(level):
        old_level = {}
        for j in i:
            try:
                for k in hierarchy[j]:
                    prev_k = number_level[j]
                    try:
                        prev_k = number_level[k]
                    except KeyError:
                        pass
                    try:
                        if(prev_k < number_level[j] + 1):
                            old_level[prev_k].add(k)
                    except KeyError:
                        old_level[prev_k] = {k}
                    if(prev_k < number_level[j] + 1):
                        number_level[k] = number_level[j] + 1
                    if(max_level < number_level[k]):
                        max_level = number_level[k]
                        level.append({k})
                    else:
                        level[number_level[k]].add(k)
            except KeyError:
                continue
        for k, a in old_level.items():
            level[k] -= a
    if len(level[0]) == 1:
        level = level[1:]
    return level

def reindex_hierarchy(file_name):
    hierarchy, parent_of, all_name, name_to_index = create_hierarchy_structure(
        file_name)
    level = find_level(hierarchy, parent_of, all_name)
    remap = {}
    index = 0
    for l in level:
        for i in l:
            remap[i] = index
            index = index + 1

    new_hierarchy = {}
    for i in hierarchy:
        try:
            new_hierarchy[remap[i]] = set([remap[a] for a in hierarchy[i]])
        except KeyError:
            pass

    new_parent_of = {}
    for i in parent_of:
        try:
            new_parent_of[remap[i]] = set([remap[a] for a in parent_of[i]])
        except KeyError:
            pass

    new_level = np.concatenate([[0], np.cumsum([len(i) for i in level])])
    new_name_to_index = {}
    new_all_name = ['0'] * new_level[-1]
    for i in name_to_index:
        try:
            new_name_to_index[i] = remap[name_to_index[i]]
            new_all_name[remap[name_to_index[i]]] = i
        except KeyError:
            pass

    return new_hierarchy, new_parent_of, new_all_name, new_name_to_index, new_level

def load_hierarchy(file_name):
    with open('data/%s' % file_name, 'rb') as f:
        hierarchy, parent_of, all_name, name_to_index, level = pickle.load(
            f)
    return hierarchy, parent_of, all_name, name_to_index, level

def save_hierarchy(file_name, hierarchy, parent_of, all_name, name_to_index, level):
    directory = "data/%s" % "/".join(file_name.split("/")[:-1])
    if not os.path.exists(directory):
        os.makedirs(directory)
    with open('data/%s' % file_name, 'wb') as f:
        pickle.dump([hierarchy, parent_of, all_name,
                     name_to_index, level], f)

def cutoff_label(cutoff_label, hierarchy, parent_of, all_name, name_to_index, level):
    remap = {}
    j = 0
    l = 0
    delete_each_level = np.zeros(len(level))
    for i, _ in enumerate(all_name):
        if not i in cutoff_label:
            if i >= level[l]:
                l = l + 1
            remap[i] = j
            j = j + 1
        else:
            if i >= level[l]:
                l = l + 1
            delete_each_level[l] = delete_each_level[l] + 1

    # process new level
    level = remap_level(level, delete_each_level)
    hierarchy = remap_hie_and_parent(hierarchy, remap)
    parent_of = remap_hie_and_parent(parent_of, remap)
    all_name = remap_all_name(all_name, remap)
    name_to_index = remap_name_to_index(all_name)
    return hierarchy, parent_of, all_name, name_to_index, level, remap

def remap_level(level, delete_each_level):
    delete_each_level = np.cumsum(delete_each_level)
    new_level = np.array(level) - delete_each_level
    last_one = new_level[-1]
    c = 0
    for i in range(len(new_level) - 1):
        if new_level[-2 - i] != last_one:
            c = len(new_level) - i
            break
    new_level = new_level[:c]
    return new_level.astype(int).tolist()

def remap_hie_and_parent(hobject, remap):
    new_hobject = {}
    for key in hobject:
        value = hobject[key]
        try:
            new_key = remap[key]
            for v in value:
                try:
                    new_v = remap[v]
                except KeyError:
                    continue
                try:
                    new_hobject[new_key].add(new_v)
                except KeyError:
                    new_hobject[new_key] = set([new_v])
        except KeyError:
            continue
    return new_hobject

def remap_all_name(all_name, remap):
    all_in = list(remap.keys())
    all_name = np.array(all_name)[all_in]
    return all_name.tolist()

def remap_name_to_index(all_name):
    new_name_to_index = {}
    for i, n in enumerate(all_name):
        new_name_to_index[n] = i
    return new_name_to_index

def save_new_hierarchy(hierarchy_name, cutoff):
    hierarchy, parent_of, all_name, name_to_index, level = load_hierarchy(
        hierarchy_name)
    hierarchy, parent_of, all_name, name_to_index, level, remap = cutoff_label(
        cutoff, hierarchy, parent_of, all_name, name_to_index, level)
    save_hierarchy(hierarchy_name, hierarchy, parent_of,
                   all_name, name_to_index, level)
    return remap


# @Title: 组合 (Combinations)
# @Author: 18015528893
# @Date: 2021-02-28 12:21:11
# @Runtime: 416 ms
# @Memory: 16.2 MB

class Solution:
    def combine(self, n: int, k: int) -> List[List[int]]:
        result = []
        nums = list(range(1, n+1))

        def backtrack(path, start):
            if len(path) == k:
                result.append(list(path))
                return

            for i in range(start, len(nums)):
                path.append(nums[i])
                backtrack(path, i+1)
                path.pop()

        backtrack([], 0)
        return result


import matplotlib.pyplot as plt

def Serie_Leibniz_pi(n):
    return ((-1)**n) / (2*n+1)

n_termini = []
pi_termini = []

Somma_n = 0

for n in range(0, 30):
    a_n = Serie_Leibniz_pi(n)
    Somma_n += a_n
    pi_n = 4 * a_n

    n_termini.append(n)
    pi_termini.append(pi_n)

plt.plot(n_termini, pi_termini)
plt.grid()
plt.title("Serie di Leibniz per π")
plt.xlabel("n")
plt.ylabel("π(n)")
plt.show()


import re
import math
import random
import sys
import pprint
import cProfile
from utils import read_text
import time
import argparse

class FCM:

    def __init__(self, text, a=0, k=1):
        self.words = text
        self.fs_cache = {}
        self.a = a
        self.k = k
        self.contexts_seen = None
        self.prob_dic = None

    # Count all subsequences of k+1 words
    def count_subsequences(self, words, k):
        dic = {}

        for i in range(0, len(words)):
            seq = tuple(words[i:i + (k + 1)])
            if len(seq) < k + 1:
                continue
            if seq in dic:
                dic[seq] += 1
            else:
                dic[seq] = 1
        return dic

    # Get probability of a state c in the text
    def frequency_sequence(self, seq, total_len_seq):
        t_seq = tuple(seq)

        if t_seq in self.fs_cache:
            count = self.fs_cache[t_seq]
            result = count / total_len_seq
            return result
        return 0

    # Calculate all probabilities for each context
    def calculate_probabilities(self):
        words_len = len(self.words)
        unique_words = set(self.words)
        seq_count = self.count_subsequences(self.words, self.k)  # { context: num_occors}
        # Sequences Dictionary
        # for key in seq_count:
        #     print(f'{key} -> {seq_count[key]}')
        prob_dic = {}
        contexts_seen = {}
        for i in range(0, words_len):
            c = self.words[i:i + self.k]  # c - context
            if tuple(c) in contexts_seen:
                continue
            # Get the sum of all contexts where c exists
            sum_all_constexts_c = sum(
                [seq_count[tuple(c + [simbol])] for simbol in unique_words if tuple(c + [simbol]) in seq_count])
            all_probs = []
            # Get all possible sequences for c + appending with another simbol
            unique_words_len = len(unique_words)
            for simbol in unique_words:
                seq = tuple(c + [simbol])
                if seq not in seq_count:
                    if self.a:
                        n = 0

                    else:
                        continue
                else:
                    n = seq_count[seq]

                total = (sum_all_constexts_c + self.a * unique_words_len)
                # Prob of event e for context c
                prob_n = (n + self.a) / total

                # print(f'Seq:{seq} Nprob:{prob_n} the total from prob is {total}')
                context = ''.join(c)

                if context in prob_dic:
                    prob_dic[context].append((simbol, prob_n))
                else:
                    prob_dic[context] = [(simbol, prob_n)]
                all_probs.append(prob_n)
            contexts_seen[tuple(c)] = all_probs
        self.contexts_seen = contexts_seen
        self.prob_dic = prob_dic
        return prob_dic

    def calculate_frequencies(self, total_seq):
        for i in total_seq:
            seq_hash = tuple(i)
            if seq_hash in self.contexts_seen:
                if seq_hash in self.fs_cache:
                    self.fs_cache[seq_hash] += 1
                else:
                    self.fs_cache[seq_hash] = 0

    # Calculate entropy taking into account
    def calculate_entropy(self):
        words_len = len(self.words)
        context_entropy_list = []
        if self.contexts_seen == None: return 0

        # Total number of sequences
        total_seq = [self.words[i:i + self.k] for i in range(0, words_len)]
        total_seq_len = len(total_seq)

        # Calculate frequencies before hand
        # Done in order to prevent multiple transversals of the whole text
        self.calculate_frequencies(total_seq)

        for c in self.contexts_seen:
            all_probs = self.contexts_seen[c]
            # Get Hc entropy for each context/row
            # He gets 0 if prob is 0
            entropy_of_context = -1 * sum([prob * math.log(prob, 2) for prob in all_probs])
            # Probability of context/subsequence in total text
            prob_c = self.frequency_sequence(list(c), total_seq_len)
            # print(f'For c={c} entropy={entropy_of_context} Cprob={prob_c}')
            context_entropy_list.append(entropy_of_context * prob_c)
        return sum(context_entropy_list)

def main():
    pp = pprint.PrettyPrinter(indent=4)
    parser = argparse.ArgumentParser(description="Calculate Entropy",
                                     usage="python3 fcm.py -a <smoothing_parameter> -k <order_of_the_model> -path <path_of_the_text_file>")

    parser.add_argument("-a", help="Smoothing parameter", type=float, required=True)
    parser.add_argument("-k", help="Model context size", type=int, required=True)
    parser.add_argument("-path", help="Path to text file", required=True)

    args = parser.parse_args()

    text = read_text(args.path)
    fcm = FCM(text, args.a, args.k)
    prob_dic = fcm.calculate_probabilities()
    entropy = fcm.calculate_entropy()
    # for key in prob_dic:
    #     pp.pprint(f'{key} : {prob_dic[key]}')
    pp.pprint(f'Smoothing: {args.a} and Order: {args.k}')
    pp.pprint(f'Entropy:{entropy}')

if __name__ == "__main__":
    main()


#!/usr/bin/env python
# Copyright 2016 Red Hat, Inc.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.

import collections
import itertools
import netaddr
import os.path
import yaml

import six

from ansible.module_utils.basic import AnsibleModule
from os_net_config import validator

def open_network_environment_files(netenv_path, template_files):
    errors = []

    try:
        network_data = yaml.load(template_files[netenv_path])
    except Exception as e:
        return ({}, {}, ["Can't open network environment file '{}': {}"
                         .format(netenv_path, e)])
    nic_configs = []
    resource_registry = network_data.get('resource_registry', {})
    for nic_name, relative_path in six.iteritems(resource_registry):
        if nic_name.endswith("Net::SoftwareConfig"):
            nic_config_path = os.path.normpath(
                os.path.join(os.path.dirname(netenv_path), relative_path))
            try:
                nic_configs.append((
                    nic_name, nic_config_path,
                    yaml.load(template_files[nic_config_path])))
            except Exception as e:
                errors.append(
                    "Can't open the resource '{}' reference file '{}': {}"
                    .format(nic_name, nic_config_path, e))

    return (network_data, nic_configs, errors)

def validate(netenv_path, template_files):
    network_data, nic_configs, errors = open_network_environment_files(
        netenv_path, template_files)
    errors.extend(validate_network_environment(network_data, nic_configs))
    return errors

def validate_network_environment(network_data, nic_configs):
    errors = []

    cidrinfo = {}
    poolsinfo = {}
    vlaninfo = {}
    staticipinfo = {}

    for item, data in six.iteritems(network_data.get('parameter_defaults',
                                                     {})):
        if item.endswith('NetCidr'):
            cidrinfo[item] = data
        elif item.endswith('AllocationPools'):
            poolsinfo[item] = data
        elif item.endswith('NetworkVlanID'):
            vlaninfo[item] = data
        elif item.endswith('IPs'):
            staticipinfo[item] = data

    for nic_config_name, nic_config_path, nic_config in nic_configs:
        errors.extend(check_nic_configs(nic_config_path, nic_config))

    errors.extend(check_cidr_overlap(cidrinfo.values()))
    errors.extend(
        check_allocation_pools_pairing(
            network_data.get('parameter_defaults', {}), poolsinfo))
    errors.extend(check_static_ip_pool_collision(staticipinfo, poolsinfo))
    errors.extend(check_vlan_ids(vlaninfo))
    errors.extend(check_static_ip_in_cidr(cidrinfo, staticipinfo))
    errors.extend(duplicate_static_ips(staticipinfo))

    return errors

def get_network_config(resource, resource_name):
    # Finds and returns `properties > config > network_config` inside
    # a resources dictionary, with optional nesting levels in between.

    def deep_find_key(key_data, resource, resource_name):
        key, instance_type, instance_name = key_data
        if key in resource.keys():
            if not isinstance(resource[key], instance_type):
                raise ValueError("The '{}' property of '{}' must be a {}."
                                 "".format(key, resource_name, instance_name))
            return resource[key]
        for item in resource.values():
            if isinstance(item, collections.Mapping):
                return deep_find_key(key_data, item, resource_name)
        return None

    keys = [
        ('properties', collections.Mapping, 'dictionary'),
        ('config', collections.Mapping, 'dictionary'),
        ('network_config', collections.Iterable, 'list'),
    ]
    current_value = resource

    if not isinstance(resource, collections.Mapping):
        raise ValueError(
            "'{}' is not a valid resource.".format(resource_name))

    while len(keys) > 0:
        key_data = keys.pop(0)
        current_value = deep_find_key(key_data, current_value, resource_name)
        if current_value is None:
            break

    return current_value

def check_nic_configs(path, nic_data):
    errors = []

    if not isinstance(nic_data, collections.Mapping):
        return ["The nic_data parameter must be a dictionary."]

    # Look though every resources bridges and make sure there is only a single
    # bond per bridge and only 1 interface per bridge if there are no bonds.
    resources = nic_data.get('resources')
    if not isinstance(resources, collections.Mapping):
        return ["The nic_data must contain the 'resources' key and it must be "
                "a dictionary."]
    for name, resource in six.iteritems(resources):
        try:
            bridges = get_network_config(resource, name)
        except ValueError as e:
            errors.append('{}'.format(e))
            continue
        # Not all resources contain a network config:
        if not bridges:
            continue

        # Validate the os_net_config object against the schema
        v_errors = validator.validate_config(bridges, path)
        errors.extend(v_errors)
        if len(v_errors) > 0:
            continue

        # If we get here, the nic config file conforms to the schema and
        # there is no more need to check for existence and type of
        # properties.
        for bridge in bridges:
            if bridge['type'] == 'ovs_bridge':
                bond_count = 0
                interface_count = 0
                for bridge_member in bridge['members']:
                    if bridge_member['type'] in ('ovs_bond', 'ovs_dpdk_bond'):
                        bond_count += 1
                    elif bridge_member['type'] == 'interface':
                        interface_count += 1
                    else:
                        pass

                if bond_count >= 2:
                    errors.append(
                        'Invalid bonding: There are >= 2 bonds for'
                        ' bridge {} of resource {} in {}'.format(
                            bridge['name'], name, path))
                if bond_count == 0 and interface_count > 1:
                    errors.append(
                        'Invalid interface: When not using a bond, '
                        'there can only be 1 interface for bridge {} '
                        'of resource {} in {}'.format(
                            bridge['name'], name, path))
                if bond_count == 0 and interface_count == 0:
                    errors.append(
                        'Invalid config: There must be at least '
                        '1 interface or 1 bond for bridge {}'
                        'of resource {} in {}'.format(
                            bridge['name'], name, path))
    return errors

def check_cidr_overlap(networks):
    errors = []
    objs = []
    if not isinstance(networks, collections.Iterable):
        return ["The argument must be iterable."]
    for x in networks:
        try:
            objs.append(netaddr.IPNetwork(x))
        except (ValueError, TypeError):
            errors.append('Invalid network: {}'.format(x))

    for net1, net2 in itertools.combinations(objs, 2):
        if (net1 in net2 or net2 in net1):
            errors.append(
                'Networks {} and {} overlap.'
                .format(net1, net2))
    return errors

def check_allocation_pools_pairing(filedata, pools):
    if not isinstance(filedata, collections.Mapping):
        return ["The `filedata` argument must be a dictionary."]
    if not isinstance(pools, collections.Mapping):
        return ["The `pools` argument must be a dictionary."]
    errors = []
    for poolitem, pooldata in six.iteritems(pools):
        pool_objs = []
        if not isinstance(pooldata, collections.Iterable):
            errors.append('The IP ranges in {} must form a list.'
                          .format(poolitem))
            continue
        for dict_range in pooldata:
            try:
                pool_objs.append(netaddr.IPRange(
                    netaddr.IPAddress(dict_range['start']),
                    netaddr.IPAddress(dict_range['end'])))
            except Exception:
                errors.append("Invalid format of the IP range in {}: {}"
                              .format(poolitem, dict_range))
                continue

        subnet_item = poolitem.split('AllocationPools')[0] + 'NetCidr'
        try:
            network = filedata[subnet_item]
            subnet_obj = netaddr.IPNetwork(network)
        except KeyError:
            errors.append('The {} CIDR is not specified for {}.'
                          .format(subnet_item, poolitem))
            continue
        except Exception:
            errors.append('Invalid IP network: {}'.format(network))
            continue

        for ranges in pool_objs:
            for range in ranges:
                if range not in subnet_obj:
                    errors.append('Allocation pool {} {} outside of subnet'
                                  ' {}: {}'.format(poolitem,
                                                   pooldata,
                                                   subnet_item,
                                                   subnet_obj))
                    break
    return errors

def check_static_ip_pool_collision(static_ips, pools):
    """Statically defined IP address must not conflict with allocation pools.

    The allocation pools come as a dict of items in the following format:

    InternalApiAllocationPools: [
        {'start': '10.35.191.150', 'end': '10.35.191.240'}
    ]

    The static IP addresses are dicts of:

    ComputeIPs: {
        'internal_api': ['10.35.191.100', etc.],
        'storage': ['192.168.100.45', etc.]
    }
    """
    if not isinstance(static_ips, collections.Mapping):
        return ["The static IPs input must be a dictionary."]
    if not isinstance(pools, collections.Mapping):
        return ["The Pools input must be a dictionary."]
    errors = []
    pool_ranges = []
    for pool_name, ranges in six.iteritems(pools):
        if not isinstance(ranges, collections.Iterable):
            errors.append("The IP ranges in {} must form a list."
                          .format(pool_name))
            continue
        for allocation_range in ranges:
            try:
                ip_range = netaddr.IPRange(allocation_range['start'],
                                           allocation_range['end'])
            except Exception:
                errors.append("Invalid format of the IP range in {}: {}"
                              .format(pool_name, allocation_range))
                continue
            pool_ranges.append((pool_name, ip_range))

    for role, services in six.iteritems(static_ips):
        if not isinstance(services, collections.Mapping):
            errors.append("The {} must be a dictionary.".format(role))
            continue
        for service, ips in six.iteritems(services):
            if not isinstance(ips, collections.Iterable):
                errors.append("The {}->{} must be an array."
                              .format(role, service))
                continue
            for ip in ips:
                try:
                    ip = netaddr.IPAddress(ip)
                except netaddr.AddrFormatError as e:
                    errors.append("{} is not a valid IP address: {}"
                                  .format(ip, e))
                    continue
                ranges_with_conflict = ranges_conflicting_with_ip(
                    ip, pool_ranges)
                if ranges_with_conflict:
                    for pool_name, ip_range in ranges_with_conflict:
                        msg = "IP address {} from {}[{}] is in the {} pool."
                        errors.append(msg.format(
                            ip, role, service, pool_name))
    return errors

def ranges_conflicting_with_ip(ip_address, ip_ranges):
    """Check for all conflicts of the IP address conflicts.

    This takes a single IP address and a list of `(pool_name,
    netenv.IPRange)`s.

    We return all ranges that the IP address conflicts with. This is to
    improve the final error messages.
    """
    return [(pool_name, ip_range) for (pool_name, ip_range) in ip_ranges
            if ip_address in ip_range]

def check_vlan_ids(vlans):
    if not isinstance(vlans, collections.Mapping):
        return ["The vlans parameter must be a dictionary."]
    errors = []
    invertdict = {}
    for k, v in six.iteritems(vlans):
        if v not in invertdict:
            invertdict[v] = k
        else:
            errors.append('Vlan ID {} ({}) already exists in {}'.format(
                v, k, invertdict[v]))
    return errors

def check_static_ip_in_cidr(networks, static_ips):
    """Check all static IP addresses are from the corresponding network range.

    """
    if not isinstance(networks, collections.Mapping):
        return ["The networks argument must be a dictionary."]
    if not isinstance(static_ips, collections.Mapping):
        return ["The static_ips argument must be a dictionary."]
    errors = []
    network_ranges = {}
    # TODO(shadower): Refactor this so networks are always valid and already
    # converted to `netaddr.IPNetwork` here. Will be useful in the other
    # checks.
    for name, cidr in six.iteritems(networks):
        try:
            network_ranges[name] = netaddr.IPNetwork(cidr)
        except Exception:
            errors.append("Network '{}' has an invalid CIDR: '{}'"
                          .format(name, cidr))
    for role, services in six.iteritems(static_ips):
        if not isinstance(services, collections.Mapping):
            errors.append("The {} must be a dictionary.".format(role))
            continue
        for service, ips in six.iteritems(services):
            range_name = service.title().replace('_', '') + 'NetCidr'
            if range_name in network_ranges:
                if not isinstance(ips, collections.Iterable):
                    errors.append("The {}->{} must be a list."
                                  .format(role, service))
                    continue
                for ip in ips:
                    if ip not in network_ranges[range_name]:
                        errors.append(
                            "The IP address {} is outside of the {} range: {}"
                            .format(ip, range_name, networks[range_name]))
            else:
                errors.append(
                    "Service '{}' does not have a "
                    "corresponding range: '{}'.".format(service, range_name))
    return errors

def duplicate_static_ips(static_ips):
    errors = []
    if not isinstance(static_ips, collections.Mapping):
        return ["The static_ips argument must be a dictionary."]
    ipset = collections.defaultdict(list)
    # TODO(shadower): we're doing this netsted loop multiple times. Turn it
    # into a generator or something.
    for role, services in six.iteritems(static_ips):
        if not isinstance(services, collections.Mapping):
            errors.append("The {} must be a dictionary.".format(role))
            continue
        for service, ips in six.iteritems(services):
            if not isinstance(ips, collections.Iterable):
                errors.append("The {}->{} must be a list."
                              .format(role, service))
                continue
            for ip in ips:
                ipset[ip].append((role, service))
    for ip, sources in six.iteritems(ipset):
        if len(sources) > 1:
            msg = "The {} IP address was entered multiple times: {}."
            formatted_sources = ("{}[{}]"
                                 .format(*source) for source in sources)
            errors.append(msg.format(ip, ", ".join(formatted_sources)))
    return errors

def main():
    module = AnsibleModule(argument_spec=dict(
        path=dict(required=True, type='str'),
        template_files=dict(required=True, type='list')
    ))

    netenv_path = module.params.get('path')
    template_files = {name: content[1] for (name, content) in
                      module.params.get('template_files')}

    errors = validate(netenv_path, template_files)

    if errors:
        module.fail_json(msg="\n".join(errors))
    else:
        module.exit_json(msg="No errors found for the '{}' file.".format(
            netenv_path))

if __name__ == '__main__':
    main()


# -*- coding: utf-8 -*-
# @Author: Mujib
# @Date:   2017-07-15 15:30:59
# @Last Modified by:   Mujib
# @Last Modified time: 2017-07-15 15:55:44

# Implmenting sleep
import urllib.request
import time

normalCustomer = 'http://beans-r-us.appspot.com/prices.html'
loyalCustomer = 'http://www.beans-r-us.appspot.com/prices-loyalty.html'

price = 99.99;

while price > 4.74:

	# Sleep of 15 minute.
	time.sleep( 60 )
	page = urllib.request.urlopen( normalCustomer )

	text = page.read().decode( 'utf8' )

	# Here + 2 is added since we have to eliminate the character >$
	priceIndex = text.find( '>$' ) + 2;

	# Here + 4 is since the total 4 character
	price = float( text[ priceIndex:( priceIndex + 4 ) ] )

	print( "The price for the coffee is : " + str( price ) )

print( 'Price is low you can buy.' )


#-----------------------------------------------------------------------------------
# Terms and Conditions
#-----------------------------------------------------------------------------------
#
#Screencast Tutor 0.2.1 - A visual tutorial aid to display events in Blender's 3d view
#Copyright (C) 2011  Giles Bayliss
#
#This program is free software; you can redistribute it and/or
#modify it under the terms of the GNU General Public License
#as published by the Free Software Foundation; either version 2
#of the License, or (at your option) any later version.
#
#This program is distributed in the hope that it will be useful,
#but WITHOUT ANY WARRANTY; without even the implied warranty of
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#GNU General Public License for more details.
#
#You should have received a copy of the GNU General Public License
#along with this program; if not, write to the Free Software
#Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
#
#-----------------------------------------------------------------------------------
# Known issues and features
#-----------------------------------------------------------------------------------
#
# The fade out on the overlayed icons is driven by redundant events (i.e mousemove)
# I haven't had time to find a way of triggering a redraw without locking up the
# the interface but I suspect that with a little digging and some help with the guys
# on IRC this may be possible.  They're busy getting the next stable release out so
# I've avoided such frivolities thus far.
#
# Some events cannot be captured (must wait for blender event system to be updated)
#  i.e constraining axes during grab/rotate/translate/extrude so I have implemented a
# help bar during these modes.
#
# I realize that the first 50 lines is purely commentary so apologies but I would like
# to get it off my chest
#
# I never did get time to look at the splashscreen on starting the script. Sorry
#
# I only learned (barely) how to write python this last week or so.
# I know it's not perfect and a lot of it was done wiht very little sleep
# but I've tried to comment where I can and use classes and overrides where possible
# to maximise re-use.
#
#-----------------------------------------------------------------------------------
# Honors and mentions
#-----------------------------------------------------------------------------------
#
# This script was inspired by the Screencast_Keys script by Paulo Gomes.
# The aforementioned script was heroically maintained by Crouch. As such, I
# feel it only right to honor their efforts.
#
# This script was written from the ground up and does not borrow any of the code from
# the aforementioned authors. It does however borrow the use of the 'F7' key to halt
# execution of the operator
#
# The only common code is from the script templates and that necessitated by the
# blender python api.
#
# If you have any questions regarding this please do not hesitate to contant me.
#
# Finally thanks go to:
#
#   MikeyB and RobinP for allowing me the time off work to indulge in this project
#   Ton, Bart and the rest of the blender guys who made all this possible
#   Olson, for keeping me company on the irc graveyard shift and his testing this
#   Lumpycow for his awesome irc nick, always makes me smile ;)
#   Andrew Price for his great tuts
#   To everybody who has contributed code, scipts, docs, tuts and precious time in
#   the name of blender, I sympathize with your passion and pain.
#
#-----------------------------------------------------------------------------------
# Blender Addon information (required for 2.56+)
#-----------------------------------------------------------------------------------

bl_info = \
    {
        "name" : "Screencast Tutor",
        "author" : "jiggles100",
        "version" : (0,2,1),
        "blender" : (2, 5, 6),
        "api" : 32411,
        "location" : "View 3D > Screencast Tutor",
        "description" : "Tutorial Annotation System - tested with API 2.56.1 UNSTABLE",
        "warning" : "",
        "wiki_url" : "",
        "tracker_url" : "",
        "category" : "3D View",
    }

#-----------------------------------------------------------------------------------
# Imports
#-----------------------------------------------------------------------------------

import bpy
import bgl
import blf
import time

#-----------------------------------------------------------------------------------
# Overlay uAPI
#-----------------------------------------------------------------------------------
#
# This micro API (uAPI) provides an abstraction layer for displaying the controls
# overlayed on the 3D view. The drawing functions are performed using the bgl wrapper
# for opengl functions.  Please refer to the OpenGL documentation for help on any
# drawing functions
#
#
#-----------------------------------------------------------------------------------
# Base objects
#-----------------------------------------------------------------------------------

class OverlayRect():

    ox=10 # origin x
    oy=10 # origin y
    dx=10 # width
    dy=10 # height
    a=1.0 #alpha factor

    @classmethod
    def position(self,x,y):
        self.ox=x
        self.oy=y

    @classmethod
    def size(self,x,y):
        self.dx=x
        self.dy=y

    @classmethod
    def alpha(self,alpha):
        self.a=alpha

    @classmethod
    def draw(self):
        bgl.glEnable(bgl.GL_BLEND)

        #call subclass draw methods if overwritten
        self.draw_background()

        self.on_draw()

        # draw borders
        self.draw_border()

        # restore opengl defaults and cleanup
        bgl.glLineWidth(1)
        bgl.glColor4f(0.0, 0.0, 0.0, 1.0)
        bgl.glDisable(bgl.GL_BLEND)

        pass

    @classmethod
    def on_draw(self):
        pass

    @classmethod
    def draw_background(self):
        # background 50% alpha, black
        self.on_set_background()
        bgl.glRecti(self.ox, self.oy, self.ox + self.dx, self.oy + self.dy)

    @classmethod
    def draw_border(self):
        self.on_set_foreground()
        bgl.glLineWidth(2)
        bgl.glBegin(bgl.GL_LINE_LOOP)
        bgl.glVertex2i(self.ox, self.oy)
        bgl.glVertex2i(self.ox, self.oy + self.dy)
        bgl.glVertex2i(self.ox + self.dx, self.oy + self.dy)
        bgl.glVertex2i(self.ox + self.dx, self.oy)
        bgl.glEnd()

    @classmethod
    def on_set_background(self):
        bgl.glColor4f(0.0, 0.0, 0.0, 0.25*self.a)
        return

    @classmethod
    def on_set_foreground(self):
        bgl.glColor4f(1.0, 1.0, 1.0, 0.5*self.a)
        return

    @classmethod
    def width(self):
        return self.dx

    @classmethod
    def height(self):
        return self.dy

    @classmethod
    def left(self):
        return self.ox

    @classmethod
    def top(self):
        return self.oy + self.dy

    @classmethod
    def right(self):
        return self.ox + self.dx

    @classmethod
    def bottom(self):
        return self.oy

#-----------------------------------------------------------------------------------
# OverlayMouse
#-----------------------------------------------------------------------------------

class OverlayMouse(OverlayRect):

    #dx = 36 # overides base width
    #dy = 48 # overides base height

    bdx=12 # button width
    bdy=12 # button height

    lmb=False
    mmb=False
    rmb=False

    _scroll=''

    @classmethod
    def size(self,x,y):
        super().size(x,y)
        self.bdx=int(x/3.0)
        self.bdy=int(y/4.0)
        pass

    @classmethod
    def buttons(self,lmb,mmb,rmb):
        self.lmb=lmb
        self.mmb=mmb
        self.rmb=rmb

    @classmethod
    def scroll(self,scroll):
        if scroll!='':
            self.buttons(False,False,False)
        self._scroll=scroll

    @classmethod
    def on_draw(self):

        bgl.glColor4f(1.0, 1.0, 1.0, 0.5*self.a)

        #draw button backgrounds
        if self.lmb == True:
            #bgl.glColor4f(1.0, 0.5, 0.5, 0.5*self.a)
            bgl.glRecti(
                self.left(),
                self.top()-self.bdy,
                self.left() + self.bdx,
                self.top())

        if self.mmb == True:
            #bgl.glColor4f(0.5, 0.5, 1.0, 0.5*self.a)
            bgl.glRecti(
                self.ox + self.bdx,
                self.oy + self.dy - self.bdy,
                self.ox + self.dx - self.bdx,
                self.oy + self.dy)

        if self.rmb == True:
            #bgl.glColor4f(0.5, 1.0, 0.5, 0.5*self.a)
            bgl.glRecti(
                self.ox + self.dx-self.bdx,
                self.oy + self.dy - self.bdy,
                self.ox + self.dx,
                self.oy + self.dy)

        #draw button dividers
        bgl.glColor4f(1.0, 1.0, 1.0, 0.5*self.a)

        if self._scroll!='':
            mx=self.left() + int(self.bdx*1.5)
            my=self.top() - int(self.bdy*0.5)
            dx=4
            dy=0
            #flip
            if self._scroll=='WHEELUPMOUSE':
                dy+=4
            elif self._scroll=='WHEELDOWNMOUSE':
                dy-=4
            #line
            bgl.glLineWidth(3)
            bgl.glBegin(bgl.GL_LINES)
            bgl.glVertex2i(mx, my)
            bgl.glVertex2i(mx, my - dy)
            bgl.glEnd()
            # arrow
            bgl.glLineWidth(1)
            bgl.glBegin(bgl.GL_TRIANGLES)
            bgl.glVertex2i(mx - dx, my)
            bgl.glVertex2i(mx, my + dy)
            bgl.glVertex2i(mx + dx, my)
            bgl.glEnd()

        bgl.glLineWidth(1)
        bgl.glBegin(bgl.GL_LINES)
        #left-middle
        bgl.glVertex2i(self.ox+self.bdx, self.oy+self.dy)
        bgl.glVertex2i(self.ox+self.bdx, self.oy+self.dy-self.bdy)

        #middle-right
        bgl.glVertex2i(self.ox+self.dx-self.bdx, self.oy+self.dy)
        bgl.glVertex2i(self.ox+self.dx-self.bdx, self.oy+self.dy-self.bdy)

        #bottom
        bgl.glVertex2i(self.ox, self.oy+self.dy-self.bdy)
        bgl.glVertex2i(self.ox+self.dx, self.oy+self.dy-self.bdy)

        bgl.glEnd()
        pass

#-----------------------------------------------------------------------------------
# OverlayKey
#-----------------------------------------------------------------------------------

class OverlayKey(OverlayRect):

    tdx=8 # text offset x
    tdy=8 # text offset y
    font_id = 0 # default font
    font_size = 20
    _key='Global Key String'

    @classmethod
    def __init__(self,key):
        self.key(key) # key text

    @classmethod
    def key(self,key):
        self._key=key
        blf.size(self.font_id, self.font_size, 72)
        if key!='':
            dims=blf.dimensions(self.font_id, key)
            dx=int(dims[0])+2*self.tdx
            dy=int(dims[1])+2*self.tdy
            self.size(dx,dy)

    @classmethod
    def draw(self):
        super().draw()
        self.draw_text()

    @classmethod
    def draw_text(self):
        #write the text
        self.on_set_text_color()
        blf.position(self.font_id, self.left() + self.tdx, self.bottom() + self.tdy,0)
        blf.size(self.font_id, self.font_size, 72)
        blf.draw(self.font_id, self._key)

    @classmethod
    def on_set_text_color(self):
        bgl.glColor4f(1.0, 1.0, 1.0, 0.5*self.a)

#-----------------------------------------------------------------------------------
# Number Pad
#-----------------------------------------------------------------------------------

class NumpadKey(OverlayKey):
    tdx=3
    tdy=2
    font_size = 10
    borderwidth=1

    @classmethod
    def __init__(self,key):
        self._key=key
        self._selected=False

    @classmethod
    def selected(self, select):
        self._selected=select

    @classmethod
    def on_set_text_color(self):
        if self._selected==True:
            bgl.glColor4f(1.0, 1.0, 1.0, self.a)
        else:
            super().on_set_text_color()

    @classmethod
    def on_set_background(self):
        #need this to be transparent
        bgl.glColor4f(0.0, 0.0, 0.0, 0.0)
        return

    @classmethod
    def on_set_foreground(self):
        if self._selected==True:
            bgl.glColor4f(1.0, 1.0, 1.0, 1.1 * self.a)
        else:
            super().on_set_foreground()

    @classmethod
    def draw_border(self):
        if self._selected==False:
            pass
        else:
            super().draw_border()

class OverlayNumpad(OverlayRect):

    font_id = 0 #default font
    font_size = 12
    _key = ''

    @classmethod
    def key(self,key):
        self._key=key

    # this is a poor implementation of the draw routine, but having only learned python a week ago
    # this is all I can do to avoid debugging something I have no experience in so keeping it simple ;)

    @classmethod
    def draw(self):
        super().draw()
        dy=int(self.height()/5.0)
        dx=int(self.width()/4.0)
        y=self.bottom()
        x=self.left()
        m=-1 #sorry had to hack this as I refactored the code, hence negative int

        key0 = NumpadKey('0')
        key0.size(dx*2-m,dy-m)
        key0.position(x,y)
        if self._key=='0':
            key0.selected(True)
        key0.alpha(self.a)
        key0.draw()

        keyperiod = NumpadKey('.')
        keyperiod.size(dx-m,dy-m)
        keyperiod.position(x+dx*2,y)
        if self._key=='PERIOD':
            keyperiod.selected(True)
        keyperiod.alpha(self.a)
        keyperiod.draw()

        key1 = NumpadKey('1')
        key1.size(dx-m,dy-m)
        key1.position(x,y+dy)
        if self._key=='1':
            key1.selected(True)
        key1.alpha(self.a)
        key1.draw()

        key2 = NumpadKey('2')
        key2.size(dx-m,dy-m)
        key2.position(x+dx,y+dy)
        if self._key=='2':
            key2.selected(True)
        key2.alpha(self.a)
        key2.draw()

        key3 = NumpadKey('3')
        key3.size(dx-m,dy-m)
        key3.position(x+dx*2,y+dy)
        if self._key=='3':
            key3.selected(True)
        key3.draw()

        #next row
        r=2

        key4 = NumpadKey('4')
        key4.size(dx-m,dy-m)
        key4.position(x,y+dy*r)
        if self._key=='4':
            key4.selected(True)
        key4.draw()

        key5 = NumpadKey('5')
        key5.size(dx-m,dy-m)
        key5.position(x+dx,y+dy*r)
        if self._key=='5':
            key5.selected(True)
        key5.draw()

        key6 = NumpadKey('6')
        key6.size(dx-m,dy-m)
        key6.position(x+dx*2,y+dy*r)
        if self._key=='6':
            key6.selected(True)
        key6.draw()

        #next row
        r=3

        key7 = NumpadKey('7')
        key7.size(dx-m,dy-m)
        key7.position(x,y+dy*r)
        if self._key=='7':
            key7.selected(True)
        key7.draw()

        key8 = NumpadKey('8')
        key8.size(dx-m,dy-m)
        key8.position(x+dx,y+dy*r)
        if self._key=='8':
            key8.selected(True)
        key8.draw()

        key9 = NumpadKey('9')
        key9.size(dx-m,dy-m)
        key9.position(x+dx*2,y+dy*r)
        if self._key=='9':
            key9.selected(True)
        key9.draw()

        # top row
        r=4

        if self._key=='NUM LOCK': #doesn't exist as API event
            pass

        # DIVIDE key is named after guitarist from GnR

        keydivide = NumpadKey('/')
        keydivide.size(dx-m,dy-m)
        keydivide.position(x+dx,y+dy*r)
        if self._key=='SLASH':
            keydivide.selected(True)
        keydivide.draw()

        #quite amusingly the MULPIPLY key has been named after a french cartoon
        keymultiply = NumpadKey('*')
        keymultiply.size(dx-m,dy-m)
        keymultiply.position(x+dx*2,y+dy*r)
        if self._key=='ASTERIX':
            keymultiply.selected(True)
        keymultiply.draw()

        keyminus = NumpadKey('-')
        keyminus.size(dx-m,dy-m)
        keyminus.position(x+dx*3,y+dy*r)
        if self._key=='MINUS':
            keyminus.selected(True)
        keyminus.draw()

        keyplus = NumpadKey('+')
        keyplus.size(dx-m,dy*2-m)
        keyplus.position(x+dx*3,y+dy*2)
        if self._key=='PLUS':
            keyplus.selected(True)
        keyplus.draw()

        #key enter no symbol, so a bit of a hack but zzzzz
        keyenter = NumpadKey('</')
        keyenter.size(dx-m,dy*2-m)
        keyenter.position(x+dx*3,y)
        if self._key=='ENTER':
            keyenter.selected(True)
        keyenter.draw()

    @classmethod
    def draw_border(self):
        #call the default
        super().draw_border()

        #innerline
        dy=int(self.height()/5.0)
        dx=int(self.width()/4.0)
        y=self.bottom()
        x=self.left()

        bgl.glLineWidth(1)
        bgl.glColor4f(1.0, 1.0, 1.0, 0.25 * self.a)
        bgl.glBegin(bgl.GL_LINES)
        #horizontals
        bgl.glVertex2i(x,y+dy)
        bgl.glVertex2i(x+3*dx,y+dy)
        bgl.glVertex2i(x,y+2*dy)
        bgl.glVertex2i(x+4*dx,y + 2*dy)
        bgl.glVertex2i(x,y+3*dy)
        bgl.glVertex2i(x+3*dx,y + 3*dy)
        bgl.glVertex2i(x,y+4*dy)
        bgl.glVertex2i(x+4*dx,y + 4*dy)
        #verticals
        bgl.glVertex2i(x+dx,y+dy)
        bgl.glVertex2i(x+dx,y + 5*dy)
        bgl.glVertex2i(x+2*dx,y)
        bgl.glVertex2i(x+2*dx,y + 5*dy)
        bgl.glVertex2i(x+3*dx,y)
        bgl.glVertex2i(x+3*dx,y + 5*dy)
        bgl.glEnd()
        pass

#-----------------------------------------------------------------------------------
# Arrows
#-----------------------------------------------------------------------------------

class OverlayArrowKey(OverlayRect):

    _key = ''

    @classmethod
    def __init__(self,key):
        self.key(key)

    @classmethod
    def key(self,key):
        self._key=key

    @classmethod
    def on_draw(self):

        # This function was a lot more compact but a bug in which I thought had
        # been caused by a python scoping error forced me to right this monster
        # The more i use python the less I trust it, but I suppose I'd better
        # give it the benefit of the doubt for now.  I'll revisit this later
        # at least it's clear and functional :(

        mx=self.left()+int(0.5*self.width())
        my=self.bottom()+int(0.5*self.height())

        r = int(0.25*self.width()) #arrow radius

        bgl.glColor4f(1.0, 1.0, 1.0, 0.5*self.a)
        bgl.glLineWidth(3)

        if self._key == 'UP':
            bgl.glLineWidth(3)
            bgl.glBegin(bgl.GL_LINES)
            bgl.glVertex2i(mx, my)
            bgl.glVertex2i(mx, my - r)
            bgl.glEnd()
            bgl.glLineWidth(1)
            bgl.glBegin(bgl.GL_TRIANGLES)
            bgl.glVertex2i(mx - r, my)
            bgl.glVertex2i(mx, my + r)
            bgl.glVertex2i(mx + r, my)
            bgl.glEnd()
        elif self._key =='DOWN':
            bgl.glLineWidth(3)
            bgl.glBegin(bgl.GL_LINES)
            bgl.glVertex2i(mx, my)
            bgl.glVertex2i(mx, my + r)
            bgl.glEnd()
            bgl.glLineWidth(1)
            bgl.glBegin(bgl.GL_TRIANGLES)
            bgl.glVertex2i(mx - r, my)
            bgl.glVertex2i(mx, my - r)
            bgl.glVertex2i(mx + r, my)
            bgl.glEnd()
        elif self._key == 'LEFT':
            bgl.glLineWidth(3)
            bgl.glBegin(bgl.GL_LINES)
            bgl.glVertex2i(mx, my)
            bgl.glVertex2i(mx + r, my)
            bgl.glEnd()
            bgl.glLineWidth(1)
            bgl.glBegin(bgl.GL_TRIANGLES)
            bgl.glVertex2i(mx, my + r)
            bgl.glVertex2i(mx - r, my)
            bgl.glVertex2i(mx, my - r)
            bgl.glEnd()
        elif self._key == 'RIGHT':
            bgl.glLineWidth(3)
            bgl.glBegin(bgl.GL_LINES)
            bgl.glVertex2i(mx, my)
            bgl.glVertex2i(mx - r, my)
            bgl.glEnd()
            bgl.glLineWidth(1)
            bgl.glBegin(bgl.GL_TRIANGLES)
            bgl.glVertex2i(mx, my + r)
            bgl.glVertex2i(mx + r,my)
            bgl.glVertex2i(mx, my - r)
            bgl.glEnd()
        else:
           print('Screencast Tutor - Illegal key in OverlayArrow: ' + self._key)
           return

#-----------------------------------------------------------------------------------
# Info Box
#-----------------------------------------------------------------------------------

class OverlayInfo(OverlayRect):

    _padding=4 # text padding
    fsize_header=18
    fsize_body=12
    _header='Overlay Help Bar'
    _body='Use this space to display detailed info'
    _body2='Another space to display detailed info'

    @classmethod
    def header(self,value):
        self._header=value

    @classmethod
    def body(self,value):
        self._body=value

    @classmethod
    def body2(self,value):
        self._body2=value

    @classmethod
    def draw(self):
        super().draw()
        self.draw_text()

    @classmethod
    def draw_text(self):

        font_id = 0 #default font

        bgl.glColor4f(1.0, 1.0, 1.0, 0.5*self.a)

        #write the header text
        offset_x=self._padding
        offset_y=self.fsize_header
        blf.position(font_id, self.left() + offset_x, self.top()-offset_y,0)
        blf.size(font_id, self.fsize_header, 72)
        blf.draw(font_id,self._header)

        #write the body text
        offset_x=self._padding + 2
        offset_y=self.fsize_header + self.fsize_body + self._padding
        blf.position(font_id, self.left() + offset_x, self.top()-offset_y,0)
        blf.size(font_id, self.fsize_body, 72)
        blf.draw(font_id,self._body)

        #write the body2 text
        offset_y=self.fsize_header + self.fsize_body*2 + self._padding
        blf.position(font_id, self.left() + offset_x, self.top()-offset_y,0)
        blf.size(font_id, self.fsize_body, 72)
        blf.draw(font_id,self._body2)

#-----------------------------------------------------------------------------------
# 3D View Drawing Callback
#-----------------------------------------------------------------------------------

def draw_callback_px(self, context):

    if self.ignore==True:
        #print('ignore->' + self.key)
        #return
        pass

    #margins
    mx = 30
    my = 15
    dx = 20

    # cumulative origins
    ox=context.region.width-mx
    oy=context.region.height-my

    if self.type in ('MOUSE','SCROLL'):
        mouse = OverlayMouse()
        mouse.size(36,48)
        mouse.position(ox - mouse.width(), oy - mouse.height())

        if 'LEFTMOUSE' in self.buttons:
            mouse.buttons(True,False,False)
        if 'MIDDLEMOUSE' in self.buttons:
            mouse.buttons(False,True,False)
        if 'RIGHTMOUSE' in self.buttons:
            mouse.buttons(False,False,True)

        mouse.scroll(self.scroll)
        mouse.alpha(self.alpha)
        mouse.draw()

        ox -= mouse.width()

    elif self.type in ('KEY'):
        if self.key!='':
            key = OverlayKey(self.key)
            key.position(ox-key.width(), oy-key.height())
            ox-=key.width()
            key.alpha(self.alpha)
            key.draw()

            # XXX - TODO 'E' key shouldn't be shown in Object Mode
            modded = self.shift or self.ctrl or self.alt
            mode = bpy.context.mode
            help = False

            if self.key in ('G','R','S') and mode == 'OBJECT' and not modded:
                help=True
            if self.key in ('G','R','S','E') and mode == 'EDIT_MESH' and not modded:
                help=True

            if help==True:
                info=OverlayInfo()
                info.position(mx*2,my*3)
                info.size(context.region.width-mx*3,60)
                info.header('Translation constraints')
                info.body('Press X, Y or Z to constrain to global axis. Twice for local')
                info.body2(' Use shift to lock axis i.e Shift+X constrains to Y and Z axes')
                info.alpha(self.alpha)
                info.draw()

        else:
            pass
    elif self.type in ('NUMPAD'):
        if self.key!='':
            pad = OverlayNumpad()
            pad.key(self.key)
            pad.size(48,60)
            pad.position(ox-pad.width(), oy-pad.height())
            ox-=pad.width()
            pad.alpha(self.alpha)
            pad.draw()
        else:
            pass
    elif self.type in ('ARROW'):
        key = OverlayArrowKey(self.key)
        key.size(31,31)
        key.position(ox-key.width(), oy-key.height())
        ox-=key.width()
        key.alpha(self.alpha)
        key.draw()
    elif self.type in ('SPLASH'):
        splash = OverlayInfo()
        splash.position(mx*2,my*3)
        splash.size(context.region.width-mx*3,60)
        splash.header('ScreenCast Tutor by jiggles100 (NOT FOR COMMERCIAL USE)')
        splash.body('Press F7 to quit.  Thanks to Ton for blender. Olson for testing.')
        splash.alpha(self.alpha)
        splash.draw()

    else:
        print("Screencast Tutor ERROR:" + self.type + ":" + self.key)

    if self.shift == True:
        key = OverlayKey('shift')
        ox-= key.width() + dx
        key.position(ox, oy-key.height())
        key.alpha(self.alpha)
        key.draw()

    if self.alt == True:
        key = OverlayKey('alt')
        ox-= key.width()+dx
        key.position(ox, oy-key.height())
        key.alpha(self.alpha)
        key.draw()

    if self.ctrl == True:
        key = OverlayKey('ctrl')
        ox-= key.width()+dx
        key.position(ox, oy-key.height())
        key.alpha(self.alpha)
        key.draw()

    if self.os == True:
        key = OverlayKey('OS')
        ox -= key.width()+dx
        key.position(ox, oy-key.height())
        key.alpha(self.alpha)
        key.draw()

#-----------------------------------------------------------------------------------
# Blender Addon Operator Class Definition
#-----------------------------------------------------------------------------------

class ScreencastTutorOperator(bpy.types.Operator):

    '''F7 to quit'''
    bl_idname = "view3d.screencast_tutor"
    bl_label = "Screencast Tutor"

    def modal(self, context, event):

        try:
            context.area.tag_redraw()
        except Exception as ex:
            print(ex)
            return {'RUNNING_MODAL'}

        if event.type == 'F7': #always listen to quit first
            context.region.callback_remove(self._handle)
            return {'CANCELLED'}

        command=event.type
        action=event.value

        # fade alpha regardless of event type
        if self.alpha > 0.0:
            dt = self.timeout - time.clock() + 0.25
            if dt > 0.0:
                self.alpha=(dt/self.delay)**2

        # This is not the tidiest parse in the world but this is my first
        # foray into python

        # NOTE: event api is inconsistent in naming convention for input
        #       trigger names at this stage. Hopefully this will be
        #       resolved in future 2.6 release

        # ignore timer and inbetween and mousemoves and none

        if command[:5] in ('TIMER','NONE'):
            self.ignore=True
            return {'PASS_THROUGH'}

        elif command[:9] in ('INBETWEEN','MOUSEMOVE', 'WINDOW_DE'):
            self.ignore=True
            return {'PASS_THROUGH'}

        elif command[-5:] in ('SHIFT','_CTRL','T_ALT','OSKEY'):
            self.ignore=True
            return {'PASS_THROUGH'}
        else:
            self.ignore=False

        if action!='RELEASE':
            #reset flags
            self.shift=event.shift
            self.ctrl=event.ctrl
            self.alt=event.alt
            self.os=event.oskey

        #reset the alpha and timeout as it's a real event
        self.timeout = time.clock() + self.delay
        self.alpha = 1.0

        #scrollwheel
        if command[:5]=='WHEEL':
            self.type='SCROLL'
            self.scroll=command
            return {'PASS_THROUGH'}
        else:
            self.scroll=''

        #event tweaks
        if command[:-2]=='EVT_TWEAK':
            #self.type='IGNORE'
            self.tweak=True
            self.buttons=[]
            return {'PASS_THROUGH'}
        else:
            self.tweak=False

        #mouse buttons
        if command in ('LEFTMOUSE','MIDDLEMOUSE','RIGHTMOUSE'):
            self.type='MOUSE'
            if action == 'PRESS':
                self.buttons=[command] #.append(event.type)
            elif action == 'RELEASE':
                if command in self.buttons:
                    self.buttons.remove(command)
                else:
                    self.buttons.append(command) #hack for tweak
            elif action == 'CLICK':
                self.buttons.append(command)
            return {'PASS_THROUGH'}

        #arrows
        if command[-5:]=='ARROW':
            self.type='ARROW'
            self.key=command.replace('_ARROW','')
            return {'PASS_THROUGH'}

        #numpad
        elif command[:6]=='NUMPAD':
            self.type='NUMPAD'
            self.key=command.replace('NUMPAD_','')
            return {'PASS_THROUGH'}

        else: #the rest should be regular keys
            #need to find a way to convert specials
            self.type='KEY'
            self.key=command.replace('_',' ')
        return {'PASS_THROUGH'}

    def invoke(self, context, event):
        if context.area.type == 'VIEW_3D':

            self.alpha=0.0
            self.delay=1.0
            self.timeout=0.0
            self.ignore=True
            self.type='SPLASH'
            self.key=''
            self.scroll=''
            self.shift=False
            self.ctrl=False
            self.alt=False
            self.os=False

            context.window_manager.modal_handler_add(self)

            # Add the region OpenGL drawing callback
            # draw in view space with 'POST_VIEW' and 'PRE_VIEW'
            self._handle = context.region.callback_add(draw_callback_px, (self, context), 'POST_PIXEL')

            self.buttons=[]
            return {'RUNNING_MODAL'}

        else:
            self.report({'WARNING'}, "View3D not found, cannot run operator")
            return {'CANCELLED'}

#-----------------------------------------------------------------------------------
# Registration
#-----------------------------------------------------------------------------------

def register():
    bpy.utils.register_class(ScreencastTutorOperator)

def unregister():
    bpy.utils.unregister_class(ScreencastTutorOperator)

if __name__ == "__main__":
    register()

# whoa that was a tough ride ... a lot of hard work wrestling python, let's just say it's a unique language
# and dleave it at that . Well I'm bushed, I hope you enjoyed the addon
# GB ;)


import random
import threading
import time

semaforoAgente = threading.Semaphore(1)

def agentePapel():
    global papelEnMesa, fosforosEnMesa, tabacoEnMesa
    while True:
        semaforoAgente.acquire()
        papelEnMesa.append("blanco")
        tabacoEnMesa.append("Richtmon")

def agenteFosforo():
    global papelEnMesa,fosforosEnMesa,tabacoEnMesa
    while True:
        semaforoAgente.acquire()
        papelEnMesa.append("negro")
        fosforosEnMesa.append ("3 patitos")

def agenteTabaco():
    global papelEnMesa,fosforosEnMesa,tabacoEnMesa
    while True:
        semaforoAgente.acquire()
        fosforosEnMesa.append("fragata")
        tabacoEnMesa.append("Particulares")

def fumadorConPapel():
    global papelEnMesa, fosforosEnMesa, tabacoEnMesa
    while True:
        while len(fosforosEnMesa) != 0 and len(tabacoEnMesa) != 0: # si hay fósforos y tabaco en la mesa
            fosforosEnMesa.pop(0)
            tabacoEnMesa.pop(0) # tomarlos
            print("fumadorConPapel fumando 🚬")
            time.sleep(2) # armar cigarrillo y fumar: se puede simular con un sleep
            semaforoAgente.release() # llamar de nuevo a agente para que reponga en la mesa dos cosas al azar

def fumadorConFosforos():
    global papelEnMesa, fosforosEnMesa, tabacoEnMesa
    while True:
        while len(papelEnMesa) != 0 and len(tabacoEnMesa) != 0 : # si hay papel y tabaco en la mesa
            papelEnMesa.pop(0)
            tabacoEnMesa.pop(0) # tomarlos
            print("fumadorConFosforos fumando 🚬 ")
            time.sleep(2) # armar cigarrillo y fumar: se puede simular con un sleep
            semaforoAgente.release() # llamar de nuevo a agente para que reponga en la mesa dos cosas al azar

def fumadorConTabaco():
    global papelEnMesa, fosforosEnMesa, tabacoEnMesa
    while True:
        while len(fosforosEnMesa) !=0 and len(papelEnMesa) != 0: # si hay fósforos y papel en la mesa
            fosforosEnMesa.pop(0)
            papelEnMesa.pop(0) # tomarlos
            print("fumadorConTabaco fumando 🚬")
            time.sleep(2) # armar cigarrillo y fumar: se puede simular con un sleep
            semaforoAgente.release() # llamar de nuevo a agente para que reponga en la mesa dos cosas al azar

papelEnMesa = []
tabacoEnMesa = []
fosforosEnMesa = []

agenteFosforo = threading.Thread(target=agenteFosforo)
agentePapel = threading.Thread(target=agentePapel)
agenteTabaco = threading.Thread(target=agenteTabaco)
fumadorConPapelHilo = threading.Thread(target=fumadorConPapel)
fumadorConFosforosHilo = threading.Thread(target=fumadorConFosforos)
fumadorConTabacoHilo = threading.Thread(target=fumadorConTabaco)

agenteFosforo.start()
agentePapel.start()
agenteTabaco.start()
fumadorConPapelHilo.start()
fumadorConFosforosHilo.start()
fumadorConTabacoHilo.start()


#	Design Pattern Generator
#
#	Rafael Goncalves

CoreAnimation = "CoreAnimation"
CoreGraphics = "CoreGraphics"
Foundation = "Foundation"
CoreFoundation = "CoreFoundation"
QuartzCore = "QuartzCore"
ImageIO = "ImageIO"
CoreImage = "CoreImage"
CoreVideo = "CoreVideo"
CoreMedia = "CoreMedia"
Security = "Security"
SystemConfiguration = "SystemConfiguration"
Accounts = "Accounts"
MapKit = "MapKit"
CoreLocation = "CoreLocation"


#!/usr/bin/env python

# libraries
import warnings
import numpy as np

## reduction models
from sklearn.decomposition import PCA, FastICA, IncrementalPCA, KernelPCA, FactorAnalysis, TruncatedSVD, SparsePCA, MiniBatchSparsePCA, DictionaryLearning, MiniBatchDictionaryLearning
from sklearn.manifold import TSNE, MDS, SpectralEmbedding, LocallyLinearEmbedding, Isomap

# internal libraries
from ..tools.df2mat import df2mat
from .._shared.helpers import *
from .normalize import normalize as normalizer
from .align import align as aligner

# main function
@memoize
def reduce(x, reduce='IncrementalPCA', ndims=3, normalize=None, align=None,
           model=None, model_params=None, internal=False):
    """
    Reduces dimensionality of an array, or list of arrays

    Parameters
    ----------
    x : Numpy array or list of arrays
        Dimensionality reduction using PCA is performed on this array.

    reduce : str or dict
        Decomposition/manifold learning model to use.  Models supported: PCA,
        IncrementalPCA, SparsePCA, MiniBatchSparsePCA, KernelPCA, FastICA,
        FactorAnalysis, TruncatedSVD, DictionaryLearning, MiniBatchDictionaryLearning,
        TSNE, Isomap, SpectralEmbedding, LocallyLinearEmbedding, and MDS. Can be
        passed as a string, but for finer control of the model parameters, pass
        as a dictionary, e.g. reduce={'model' : 'PCA', 'params' : {'whiten' : True}}.
        See scikit-learn specific model docs for details on parameters supported
        for each model.

    ndims : int
        Number of dimensions to reduce

    model : None
        Deprecated argument.  Please use reduce.

    model_params : None
        Deprecated argument.  Please use reduce.

    align : None
        Deprecated argument.  Please use new analyze function to perform
        combinations of transformations

    normalize : None
        Deprecated argument.  Please use new analyze function to perform
        combinations of transformations

    Returns
    ----------
    x_reduced : Numpy array or list of arrays
        The reduced data with ndims dimensionality is returned.  If the input
        is a list, a list is returned.

    """

    # sub functions
    def reduce_list(x, model):
        split = np.cumsum([len(xi) for xi in x])[:-1]
        x_r = np.vsplit(model.fit_transform(np.vstack(x)), split)
        if len(x)>1:
            return [xi for xi in x_r]
        else:
            return [x_r[0]]

    # dictionary of models
    models = {
        'PCA' : PCA,
        'IncrementalPCA' : IncrementalPCA,
        'SparsePCA' : SparsePCA,
        'MiniBatchSparsePCA' : MiniBatchSparsePCA,
        'KernelPCA' : KernelPCA,
        'FastICA' : FastICA,
        'FactorAnalysis' : FactorAnalysis,
        'TruncatedSVD' : TruncatedSVD,
        'DictionaryLearning' : DictionaryLearning,
        'MiniBatchDictionaryLearning' : MiniBatchDictionaryLearning,
        'TSNE' : TSNE,
        'Isomap' : Isomap,
        'SpectralEmbedding' : SpectralEmbedding,
        'LocallyLinearEmbedding' : LocallyLinearEmbedding,
        'MDS' : MDS
    }

    # deprecated warning
    if (model is not None) or (model_params is not None):
        warnings.warn('Model and model params will be deprecated.  Please use the \
                      reduce keyword.  See API docs for more info: http://hypertools.readthedocs.io/en/latest/hypertools.tools.reduce.html#hypertools.tools.reduce')
        reduce = {}
        reduce['model'] = model
        reduce['params'] = model_params

    # if model is None, just return data
    if reduce is None:
        return x
    else:

        # common format
        x = format_data(x, ppca=True)

        # deprecation warnings
        if normalize is not None:
            warnings.warn('The normalize argument will be deprecated for this function.  Please use the \
                          analyze function to perform combinations of these transformations.  See API docs for more info: http://hypertools.readthedocs.io/en/latest/hypertools.analyze.html#hypertools.analyze')
            x = normalizer(x, normalize=normalize)

        if align is not None:
            warnings.warn('The align argument will be deprecated for this function.  Please use the \
                          analyze function to perform combinations of these transformations.  See API docs for more info: http://hypertools.readthedocs.io/en/latest/hypertools.analyze.html#hypertools.analyze')
            x = aligner(x, align=align)

        # if the shape of the data is already less than ndims, just return it
        if all([i.shape[1]<=ndims for i in x]):
            return x

        # if reduce is a string, find the corresponding model
        if type(reduce) in [str, np.string_]:
            model = models[reduce]
            model_params = {
                'n_components' : ndims
            }
        # if its a dict, use custom params
        elif type(reduce) is dict:
            if type(reduce['model']) is str:
                model = models[reduce['model']]
                if reduce['params'] is None:
                    model_params = {
                        'n_components' : ndims
                    }
                else:
                    model_params = reduce['params']
        if 'n_components' not in model_params:
            model_params['n_components'] = ndims

        # initialize model
        model = model(**model_params)

        # reduce data
        x_reduced = reduce_list(x, model)

        # return data
        if internal or len(x_reduced)>1:
            return x_reduced
        else:
            return x_reduced[0]