from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import os
import modeling
import optimization
import tokenization
import tensorflow as tf
from utils import load_wrapper, write_wrapper
from utils import lm_bucket, data_bucket

flags = tf.flags

FLAGS = flags.FLAGS
checkpoint_suffixes = ['meta', 'index', 'data-00000-of-00001']
SAVE_PER_EPOCH = 3

## Required parameters
flags.DEFINE_string(
    "data_dir", None,
    "The directory that contains the data, should contain data.json, train.tf_record, predict.tf_record")

flags.DEFINE_integer(
    "initialization_seed", 0,
    "The random seed used for initializing the MLP layer")

flags.DEFINE_integer(
    "dataorder_seed", 0,
    "The random seed used for shuffling the data")

flags.DEFINE_string(
    "pretrain_dir", None,
    "directory that contains all information about a pretrained model.")

flags.DEFINE_string(
    'model_size', None,
    'pretraining model size, mini, small, medium, base, large'
)

flags.DEFINE_integer(
    'pretrain_seed', None,
    'pretraining seed'
)

flags.DEFINE_integer(
    'pretrain_steps', 2000000,
    'number of steps the model has pretrained'
)

flags.DEFINE_bool(
    'original', False,
    'whether to use the original pre-trained model for initialization'
)

## Other parameters

flags.DEFINE_bool(
    "do_lower_case", True,
    "Whether to lower case the input text. Should be True for uncased "
    "models and False for cased models.")

flags.DEFINE_integer(
    "max_seq_length", 128,
    "The maximum total input sequence length after WordPiece tokenization. "
    "Sequences longer than this will be truncated, and sequences shorter "
    "than this will be padded.")

flags.DEFINE_bool("do_train", True, "Whether to run training.")

flags.DEFINE_bool(
    "do_predict", True,
    "Whether to run the model in inference mode on the test set.")

flags.DEFINE_integer("train_batch_size", None, "Total batch size for training.")

flags.DEFINE_integer("eval_batch_size", 64, "Total batch size for eval.")

flags.DEFINE_integer("predict_batch_size", 64, "Total batch size for predict.")

flags.DEFINE_float("learning_rate", None, "The initial learning rate for Adam.")

flags.DEFINE_float("num_train_epochs", 4.0,
                   "Total number of training epochs to perform.")

flags.DEFINE_float(
    "warmup_proportion", 0.1,
    "Proportion of training to perform linear learning rate warmup for. "
    "E.g., 0.1 = 10% of training.")

flags.DEFINE_bool("use_tpu", True, "Whether to use TPU or GPU/CPU.")

DEFAULT_TPU_NAME = os.popen('curl http://metadata.google.internal/computeMetadata/v1/instance/hostname -H Metadata-Flavor:Google').read().split('.')[0]

print('using TPU: ', DEFAULT_TPU_NAME)
tf.flags.DEFINE_string(
    "tpu_name", DEFAULT_TPU_NAME,
    "The Cloud TPU to use for training. This should be either the name "
    "used when creating the Cloud TPU, or a grpc://ip.address.of.tpu:8470 "
    "url.")

tf.flags.DEFINE_string(
    "tpu_zone", None,
    "[Optional] GCE zone where the Cloud TPU is located in. If not "
    "specified, we will attempt to automatically detect the GCE project from "
    "metadata.")

tf.flags.DEFINE_string(
    "gcp_project", None,
    "[Optional] Project name for the Cloud TPU-enabled project. If not "
    "specified, we will attempt to automatically detect the GCE project from "
    "metadata.")

tf.flags.DEFINE_string("master", None, "[Optional] TensorFlow master URL.")

flags.DEFINE_integer(
    "num_tpu_cores", 8,
    "Only used if `use_tpu` is True. Total number of TPU cores to use.")

def rewrite_checkpoint_info(output_dir, model_name):
    tmp_f_name = 'tmp.txt'
    with open(tmp_f_name, 'w') as tmp_out_file:
        tmp_out_file.write('model_checkpoint_path: "%s"\n' % model_name)
        tmp_out_file.write('all_model_checkpoint_paths: "%s"\n' % model_name)
    os.system('gsutil mv %s %s' % (tmp_f_name, os.path.join(output_dir, 'checkpoint')))

def file_based_input_fn_builder(input_file, seq_length, is_training,
                                drop_remainder):
  """Creates an `input_fn` closure to be passed to TPUEstimator."""

  name_to_features = {
      "input_ids": tf.FixedLenFeature([seq_length], tf.int64),
      "input_mask": tf.FixedLenFeature([seq_length], tf.int64),
      "segment_ids": tf.FixedLenFeature([seq_length], tf.int64),
      "label_ids": tf.FixedLenFeature([], tf.int64),
      "is_real_example": tf.FixedLenFeature([], tf.int64),
  }

  def _decode_record(record, name_to_features):
    """Decodes a record to a TensorFlow example."""
    example = tf.parse_single_example(record, name_to_features)

    # tf.Example only supports tf.int64, but the TPU only supports tf.int32.
    # So cast all int64 to int32.
    for name in list(example.keys()):
      t = example[name]
      if t.dtype == tf.int64:
        t = tf.to_int32(t)
      example[name] = t

    return example

  def input_fn(params):
    """The actual input function."""
    batch_size = params["batch_size"]

    # For training, we want a lot of parallel reading and shuffling.
    # For eval, we want no shuffling and parallel reading doesn't matter.
    d = tf.data.TFRecordDataset(input_file)
    if is_training:
      d = d.repeat()
      d = d.shuffle(buffer_size=100, seed=FLAGS.dataorder_seed)

    d = d.apply(
        tf.contrib.data.map_and_batch(
            lambda record: _decode_record(record, name_to_features),
            batch_size=batch_size,
            drop_remainder=drop_remainder))

    return d

  return input_fn

def create_model(bert_config, is_training, input_ids, input_mask, segment_ids,
                 labels, num_labels, use_one_hot_embeddings):
  """Creates a classification model."""
  model = modeling.BertModel(
      config=bert_config,
      is_training=is_training,
      input_ids=input_ids,
      input_mask=input_mask,
      token_type_ids=segment_ids,
      use_one_hot_embeddings=use_one_hot_embeddings)

  # In the demo, we are doing a simple classification task on the entire
  # segment.
  #
  # If you want to use the token-level output, use model.get_sequence_output()
  # instead.
  output_layer = model.get_pooled_output()

  hidden_size = output_layer.shape[-1].value

  output_weights = tf.get_variable(
      "output_weights", [num_labels, hidden_size],
      initializer=tf.truncated_normal_initializer(stddev=0.02, seed=FLAGS.initialization_seed))

  output_bias = tf.get_variable(
      "output_bias", [num_labels], initializer=tf.zeros_initializer())

  with tf.variable_scope("loss"):
    if is_training:
      # I.e., 0.1 dropout
      output_layer = tf.nn.dropout(output_layer, keep_prob=0.9)

    logits = tf.matmul(output_layer, output_weights, transpose_b=True)
    logits = tf.nn.bias_add(logits, output_bias)
    probabilities = tf.nn.softmax(logits, axis=-1)
    log_probs = tf.nn.log_softmax(logits, axis=-1)

    one_hot_labels = tf.one_hot(labels, depth=num_labels, dtype=tf.float32)

    per_example_loss = -tf.reduce_sum(one_hot_labels * log_probs, axis=-1)
    loss = tf.reduce_mean(per_example_loss)

    return (loss, per_example_loss, logits, probabilities)

def model_fn_builder(bert_config, num_labels, init_checkpoint, learning_rate,
                     num_train_steps, num_warmup_steps, use_tpu,
                     use_one_hot_embeddings):
  """Returns `model_fn` closure for TPUEstimator."""

  def model_fn(features, labels, mode, params):  # pylint: disable=unused-argument
    """The `model_fn` for TPUEstimator."""

    tf.logging.info("*** Features ***")
    for name in sorted(features.keys()):
      tf.logging.info("  name = %s, shape = %s" % (name, features[name].shape))

    input_ids = features["input_ids"]
    input_mask = features["input_mask"]
    segment_ids = features["segment_ids"]
    label_ids = features["label_ids"]
    is_real_example = None
    if "is_real_example" in features:
      is_real_example = tf.cast(features["is_real_example"], dtype=tf.float32)
    else:
      is_real_example = tf.ones(tf.shape(label_ids), dtype=tf.float32)

    is_training = (mode == tf.estimator.ModeKeys.TRAIN)

    (total_loss, per_example_loss, logits, probabilities) = create_model(
        bert_config, is_training, input_ids, input_mask, segment_ids, label_ids,
        num_labels, use_one_hot_embeddings)

    tvars = tf.trainable_variables()
    initialized_variable_names = {}
    scaffold_fn = None
    if init_checkpoint:
      (assignment_map, initialized_variable_names
      ) = modeling.get_assignment_map_from_checkpoint(tvars, init_checkpoint)
      if use_tpu:

        def tpu_scaffold():
          tf.train.init_from_checkpoint(init_checkpoint, assignment_map)
          return tf.train.Scaffold()

        scaffold_fn = tpu_scaffold
      else:
        tf.train.init_from_checkpoint(init_checkpoint, assignment_map)

    tf.logging.info("**** Trainable Variables ****")
    for var in tvars:
      init_string = ""
      if var.name in initialized_variable_names:
        init_string = ", *INIT_FROM_CKPT*"
      tf.logging.info("  name = %s, shape = %s%s", var.name, var.shape,
                      init_string)

    output_spec = None
    if mode == tf.estimator.ModeKeys.TRAIN:

      train_op = optimization.create_optimizer(
          total_loss, learning_rate, num_train_steps, num_warmup_steps, use_tpu)

      output_spec = tf.contrib.tpu.TPUEstimatorSpec(
          mode=mode,
          loss=total_loss,
          train_op=train_op,
          scaffold_fn=scaffold_fn)
    elif mode == tf.estimator.ModeKeys.EVAL:

      def metric_fn(per_example_loss, label_ids, logits, is_real_example):
        predictions = tf.argmax(logits, axis=-1, output_type=tf.int32)
        accuracy = tf.metrics.accuracy(
            labels=label_ids, predictions=predictions, weights=is_real_example)
        loss = tf.metrics.mean(values=per_example_loss, weights=is_real_example)
        return {
            "eval_accuracy": accuracy,
            "eval_loss": loss,
        }

      eval_metrics = (metric_fn,
                      [per_example_loss, label_ids, logits, is_real_example])
      output_spec = tf.contrib.tpu.TPUEstimatorSpec(
          mode=mode,
          loss=total_loss,
          eval_metrics=eval_metrics,
          scaffold_fn=scaffold_fn)
    else:
      output_spec = tf.contrib.tpu.TPUEstimatorSpec(
          mode=mode,
          predictions={"probabilities": probabilities},
          scaffold_fn=scaffold_fn)
    return output_spec

  return model_fn

# This function is not used by this file but is still used by the Colab and
# people who depend on it.
def input_fn_builder(features, seq_length, is_training, drop_remainder):
  """Creates an `input_fn` closure to be passed to TPUEstimator."""

  all_input_ids = []
  all_input_mask = []
  all_segment_ids = []
  all_label_ids = []

  for feature in features:
    all_input_ids.append(feature.input_ids)
    all_input_mask.append(feature.input_mask)
    all_segment_ids.append(feature.segment_ids)
    all_label_ids.append(feature.label_id)

  def input_fn(params):
    """The actual input function."""
    batch_size = params["batch_size"]

    num_examples = len(features)

    # This is for demo purposes and does NOT scale to large data sets. We do
    # not use Dataset.from_generator() because that uses tf.py_func which is
    # not TPU compatible. The right way to load data is with TFRecordReader.
    d = tf.data.Dataset.from_tensor_slices({
        "input_ids":
            tf.constant(
                all_input_ids, shape=[num_examples, seq_length],
                dtype=tf.int32),
        "input_mask":
            tf.constant(
                all_input_mask,
                shape=[num_examples, seq_length],
                dtype=tf.int32),
        "segment_ids":
            tf.constant(
                all_segment_ids,
                shape=[num_examples, seq_length],
                dtype=tf.int32),
        "label_ids":
            tf.constant(all_label_ids, shape=[num_examples], dtype=tf.int32),
    })

    if is_training:
      d = d.repeat()
      d = d.shuffle(buffer_size=100, seed=FLAGS.dataorder_seed)

    d = d.batch(batch_size=batch_size, drop_remainder=drop_remainder)
    return d

  return input_fn

def main(_):
  data_dir = os.path.join(data_bucket, FLAGS.data_dir)
  if FLAGS.train_batch_size is None and FLAGS.learning_rate is None:
    hyperparams = load_wrapper(os.path.join(data_dir, 'size2hyperparam.json'))
    FLAGS.train_batch_size, FLAGS.learning_rate = hyperparams[FLAGS.model_size]['bsize'], hyperparams[FLAGS.model_size]['lr']
    hyper_config = 'besthyper'
  else:
    hyper_config = 'lr%fbsize%d' % (FLAGS.learning_rate, FLAGS.train_batch_size)

  if not FLAGS.original:
    pretrain_dir = '{size}/pretrain_seed{pretrain_seed}step{pretrain_steps}'.format(size=FLAGS.model_size, pretrain_seed=FLAGS.pretrain_seed, pretrain_steps=FLAGS.pretrain_steps)
  else:
    pretrain_dir = '{size}/original'.format(size=FLAGS.model_size)
  output_dir = os.path.join(data_dir, 'results', pretrain_dir,
                            'init%ddataorder%d%s' % (FLAGS.initialization_seed, FLAGS.dataorder_seed, hyper_config)) + '/'
  print('output_dir', output_dir)
  lock_path = os.path.join(output_dir, 'lock.json')
  if tf.gfile.Exists(lock_path):
    print('lock ', lock_path, ' already exists. exitting')
    exit(0)
  else:
    write_wrapper('lock', lock_path)

  init_checkpoint_flag = os.path.join(lm_bucket, pretrain_dir, "bert_model.ckpt")
  bert_config_flag = os.path.join(lm_bucket, pretrain_dir, "bert_config.json")

  tf.logging.set_verbosity(tf.logging.INFO)

  data = load_wrapper(os.path.join(data_dir, 'data.json'))
  print('Successfully loaded data')
  print('task', data['task_name'])
  print('number of train examples', len(data['train']))
  print('number of predict examples', len(data['predict']))

  task_name = data['task_name'].lower()
  print('task', task_name)

  tokenization.validate_case_matches_checkpoint(FLAGS.do_lower_case, init_checkpoint_flag)

  bert_config = modeling.BertConfig.from_json_file(bert_config_flag)

  if FLAGS.max_seq_length > bert_config.max_position_embeddings:
    raise ValueError(
        "Cannot use sequence length %d because the BERT model "
        "was only trained up to sequence length %d" %
        (FLAGS.max_seq_length, bert_config.max_position_embeddings))

  tf.gfile.MakeDirs(output_dir)

  label_list = data['label_list']

  tpu_cluster_resolver = None
  if FLAGS.use_tpu and FLAGS.tpu_name:
    tpu_cluster_resolver = tf.contrib.cluster_resolver.TPUClusterResolver(
        FLAGS.tpu_name, zone=FLAGS.tpu_zone, project=FLAGS.gcp_project)

  train_examples = data['train']
  iteration_per_loop = int(len(train_examples) / SAVE_PER_EPOCH / FLAGS.train_batch_size) + 1
  save_checkpoints_steps = iteration_per_loop
  num_train_steps = save_checkpoints_steps * int(FLAGS.num_train_epochs) * SAVE_PER_EPOCH
  num_warmup_steps = int(num_train_steps * FLAGS.warmup_proportion)
  print('iteration per loop: %d' % iteration_per_loop)

  is_per_host = tf.contrib.tpu.InputPipelineConfig.PER_HOST_V2
  run_config = tf.contrib.tpu.RunConfig(
      cluster=tpu_cluster_resolver,
      master=FLAGS.master,
      model_dir=output_dir,
      save_checkpoints_steps=save_checkpoints_steps,
      keep_checkpoint_max=4,
      tpu_config=tf.contrib.tpu.TPUConfig(
          iterations_per_loop=iteration_per_loop,
          num_shards=FLAGS.num_tpu_cores,
          per_host_input_for_training=is_per_host))

  def get_estimator(init_checkpoint_arg):
    model_fn = model_fn_builder(
      bert_config=bert_config,
      num_labels=len(label_list),
      init_checkpoint=init_checkpoint_arg,
      learning_rate=FLAGS.learning_rate,
      num_train_steps=num_train_steps,
      num_warmup_steps=num_warmup_steps,
      use_tpu=FLAGS.use_tpu,
      use_one_hot_embeddings=FLAGS.use_tpu)

    # If TPU is not available, this will fall back to normal Estimator on CPU
    # or GPU.
    estimator = tf.contrib.tpu.TPUEstimator(
      use_tpu=FLAGS.use_tpu,
      model_fn=model_fn,
      config=run_config,
      train_batch_size=FLAGS.train_batch_size,
      eval_batch_size=FLAGS.eval_batch_size,
      predict_batch_size=FLAGS.predict_batch_size)
    return estimator

  estimator = get_estimator(init_checkpoint_arg=init_checkpoint_flag)

  if FLAGS.do_train:
    train_file = os.path.join(data_dir, "train.tf_record")
    tf.logging.info("***** Running training *****")
    tf.logging.info("  Num examples = %d", len(train_examples))
    tf.logging.info("  Batch size = %d", FLAGS.train_batch_size)
    tf.logging.info("  Num steps = %d", num_train_steps)
    train_input_fn = file_based_input_fn_builder(
        input_file=train_file,
        seq_length=FLAGS.max_seq_length,
        is_training=True,
        drop_remainder=True)
    estimator.train(input_fn=train_input_fn, max_steps=num_train_steps)

  if FLAGS.do_predict:
    predict_drop_remainder = True if FLAGS.use_tpu else False
    num_actual_predict_examples = len(data['predict'])
    predict_file = os.path.join(data_dir, "predict.tf_record")

    steps_of_interest = [i * save_checkpoints_steps for i in range(num_train_steps // save_checkpoints_steps + 1)]
    steps_of_interest.append(num_train_steps)
    for cur_step in steps_of_interest:
      model_name = "model.ckpt-%d" % cur_step
      init_checkpoint_arg = os.path.join(output_dir, model_name)
      all_files_found = True
      for suffix in checkpoint_suffixes:
        if not tf.gfile.Exists('%s.%s' % (init_checkpoint_arg, suffix)):
          all_files_found = False
      if not all_files_found:
        continue
      rewrite_checkpoint_info(output_dir, model_name)
      predict_input_fn = file_based_input_fn_builder(
          input_file=predict_file,
          seq_length=FLAGS.max_seq_length,
          is_training=False,
          drop_remainder=predict_drop_remainder)

      estimator = get_estimator(init_checkpoint_arg=init_checkpoint_arg)

      result = estimator.predict(input_fn=predict_input_fn)
      output_predict_file = os.path.join(output_dir, "test_results%d.tsv" % cur_step)
      with tf.gfile.GFile(output_predict_file, "w") as writer:
        num_written_lines = 0
        tf.logging.info("***** Predict results *****")
        for (i, prediction) in enumerate(result):
          probabilities = prediction["probabilities"]
          if i >= num_actual_predict_examples:
            break
          output_line = "\t".join(
              str(class_probability)
              for class_probability in probabilities) + "\n"
          writer.write(output_line)
          num_written_lines += 1
      assert num_written_lines == num_actual_predict_examples
      for suffix in checkpoint_suffixes:
        os.system('gsutil rm %s.%s' % (init_checkpoint_arg, suffix))

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


from z3 import *
import time
from timeit import default_timer as timer

class graph:

    def __init__(self, gdict = None):
        if gdict is None:
            gdict = {}
        self.gdict = gdict

    def getVertices(self):
        return list(self.gdict.keys())

# Finds a path between start and end in graph
# Returns None if there is no path
def find_path(graph, start, end, path=[]):
    path = path + [start]
    if start == end:
        return path
    if start not in graph.keys():
        return None
    for node in graph[start]:
        if node not in path:
            newpath = find_path(graph, node, end, path)
            if newpath: return newpath
    return None

# Returns a list of all edges in graph (edges are stored as sets of vertices)
def findedges(graph):
    edges = []
    for v in graph.keys():
        for w in graph[v]:
            if {v, w} not in edges:
                edges.append({v, w})
    return edges

# Adds an edge between v and w in graph
def addedge(graph, v, w):
    if v in graph.keys():
        graph[v].append(w)
    else:
        graph[v] = [w]
    if w in graph.keys():
        graph[w].append(v)
    else:
        graph[w] = [v]

# Returns a contradictory cycle (edges in g1 are taken to be dashed and edges in g2 are solid)
# Returns None if there is no contradictory cycle
def contradictory_cycle(g1, g2):
    for e in findedges(g2):
        if len(list(e)) == 1:
            return list(e)
        v, w = list(e)
        if (find_path(g1, v, w) != None):
            return find_path(g1, v, w)
    return None

# Merges the two conjunctions f1 and f2 into a single conjunction and returns it
def and_merge(f1, f2):
    result = set([])
    if (str(f1.decl()) != 'And'):
        result.add(f1)
    else:
        result = result.union(set(f1.children()))
    if (str(f2.decl()) != 'And'):
        result.add(f2)
    else:
        result = result.union(set(f2.children()))
    return And(result)

# Eliminates all 'Implies' predicates from the formula in favour of 'Not' and 'Or'
def implies_elim(formula):
    root = str(formula.decl())
    if (root == '=='):
        return formula
    elif (root == 'Implies'):
        [f1, f2] = formula.children()
        f1 = implies_elim(f1)
        f2 = implies_elim(f2)
        return Or(Not(f1), f2)
    elif (root == 'Not'):
        return Not(implies_elim(formula.children()[0]))
    else:
        res = []
        for i in range(len(formula.children())):
            res.append(implies_elim(formula.children()[i]))
        if (root == 'And'):
            return And(res)
        if (root == 'Or'):
            return Or(res)

# Converts formula into negation normal form
def negation_normal_form(formula):
    formula = implies_elim(formula)
    root = str(formula.decl())
    if (root == '=='):
        return formula
    elif (root == 'And' or root == 'Or'):
        res = []
        for i in range(len(formula.children())):
            res.append(negation_normal_form(formula.children()[i]))
        if (root == 'And'):
            return And(res)
        elif (root == 'Or'):
            return Or(res)
    elif (root == 'Not'):
        f = formula.children()[0]
        r = str(f.decl())
        if (r == 'Not'):
            return negation_normal_form(f.children()[0])
        elif (r == '=='):
            return formula
        else:
            list = []
            for i in range(len(f.children())):
                child = (negation_normal_form(Not(f.children()[i])))
                list.append(child)
            if (r == 'And'):
                return Or(list)
            elif (r == 'Or'):
                return And(list)
    return formula

# Converts formula into DNF
def convert_to_dnf(formula):
    formula = negation_normal_form(formula)
    root = str(formula.decl())
    result = set([])
    if (root == '==' or root == 'Not'):
        return {formula}
    elif (root == 'Or'):
        for f in formula.children():
            result = result.union(convert_to_dnf(f))
    elif (root == 'And'):
        f1 = formula.children()[0]
        f2 = formula.children()[1:]
        l1 = convert_to_dnf(f1)
        if (len(f2) > 1):
            l2 = convert_to_dnf(And(f2))
        else:
            l2 = convert_to_dnf(f2[0])
        for i in l1:
            for j in l2:
                result.add(and_merge(i, j))
    return result

pl_to_lit = []
pl_letters = []

# If literal has already been converted to a propositional letter, that propositional letter is returned
# Otherwise, a new propositional letter is created and is returned
def lit_to_pl(literal):
    root = literal.decl()
    if str(root) == '==':
        if set(literal.children()) not in pl_to_lit:
            pl_letters.append(Bool("p" + str(len(pl_letters) + 1)))
            pl_to_lit.append(set(literal.children()))
            return pl_letters[-1]
        else:
            i = pl_to_lit.index(set(literal.children()))
            return pl_letters[i]

#def pl_to_index(pl):
#    i = str(pl)[1:]
#    return eval(i)

# Converts an E formula into a PL formula
def convert_to_pl(formula):
    root = formula.decl()
    if str(root) == '==':
        [v, w] = formula.children()
        if str(v) == str(w):
            return True
        return lit_to_pl(formula)
    elif str(root) == 'Not':
        f = formula.children()[0]
        return Not(convert_to_pl(f))
    elif str(root) == 'Implies':
        f1 = formula.children()[0]
        f2 = formula.children()[1]
        return Implies(convert_to_pl(f1), convert_to_pl(f2))
    else:
        res = []
        for f in formula.children():
            res.append(convert_to_pl(f))
        if str(root) == 'And':
            return And(res)
        elif str(root) == 'Or':
            return Or(res)
        elif str(root) == 'Implies':
            return Implies(res)

def approach1(formula):
    formula = negation_normal_form(formula)
    dnf = convert_to_dnf(formula)
    for conjunction in dnf:
        g1 = {}
        g2 = {}
        root = conjunction.decl()
        if str(root) == "And":
            for literal in conjunction.children():
                if str(literal.decl()) == '==':
                    addedge(g1, literal.children()[0], literal.children()[1])
                elif str(literal.decl()) == 'Not':
                    l = literal.children()[0]
                    addedge(g2, l.children()[0], l.children()[1])
            if contradictory_cycle(g1, g2) == None:
                return "SAT"
        else:
            return "SAT"
    return "UNSAT"

def approach2(formula):
    global pl_letters
    global pl_to_lit
    pl_letters = []
    pl_to_lit = []
    pl_formula = convert_to_pl(formula)
    s = Solver()
    s.add(pl_formula)
    result = s.check()
    while result == sat:
        m = s.model()
        g1 = {}
        g2 = {}
        for i in range(len(pl_letters)):
            [v, w] = list(pl_to_lit[i])
            if m[pl_letters[i]] == True:
                addedge(g1, v, w)
            else:
                addedge(g2, v, w)
        cont_cycle = contradictory_cycle(g1, g2)
        if cont_cycle != None:
            new_clause = []
            for i in range(len(cont_cycle) - 1):
                j = pl_to_lit.index({cont_cycle[i], cont_cycle[i+1]})
                new_clause.append(Not(pl_letters[j]))
            new_clause.append(pl_letters[pl_to_lit.index({cont_cycle[0], cont_cycle[-1]})])
            s.add(Or(new_clause))
            result = s.check()
        else:
            pl_to_lit = []
            pl_letters = []
            return "SAT"
    pl_to_lit = []
    pl_letters = []
    return "UNSAT"

def approach3(formula):
    global pl_letters
    global pl_to_lit
    pl_letters = []
    pl_to_lit = []
    pl_formula = convert_to_pl(formula)
    s = Solver()
    s.add(pl_formula)
    vertices = []
    for i in range(len(pl_letters)):
        [v, w] = list(pl_to_lit[i])
        if v not in vertices:
            vertices.append(v)
        if w not in vertices:
            vertices.append(w)
    for i in vertices:
        for j in vertices:
            for k in vertices:
                if (i == j or j == k or k == i):
                    continue
                if({i, j} not in pl_to_lit):
                    pl_to_lit.append({i, j})
                    pl_letters.append(Bool("p" + str(len(pl_letters) + 1)))
                    a = len(pl_letters) - 1
                else:
                    a = pl_to_lit.index({i, j})
                if({j, k} not in pl_to_lit):
                    pl_to_lit.append({j, k})
                    pl_letters.append(Bool("p" + str(len(pl_letters) + 1)))
                    b = len(pl_letters) - 1
                else:
                    b = pl_to_lit.index({j, k})
                if({i, k} not in pl_to_lit):
                    pl_to_lit.append({i, k})
                    pl_letters.append(Bool("p" + str(len(pl_letters) + 1)))
                    c = len(pl_letters) - 1
                else:
                    c = pl_to_lit.index({i, k})
                s.add(Or(Not(pl_letters[a]), Not(pl_letters[b]), pl_letters[c]))
    result = s.check()
    if result == sat:
        return "SAT"
    else:
        return "UNSAT"

# Declare uninterpreted constants and input the formula here
x1, x2, x3, x4, x5, x6, x7, f1, f2, f3, g1, g2, h1, h2 = Ints('x1 x2 x3 x4 x5 x6 x7 f1 f2 f3 g1 g2 h1 h2')
formula = And(x1 == x2, Implies(x1 == x2, x2 == x3), Not(x1 == x3))

g1 = {}
g2 = {}

start = timer()
res = approach1(formula)
end = timer()
print("Approach 1: ", res, ",", end - start)

start = timer()
res = approach2(formula)
end = timer()
print("Approach 2: ", res, ",", end - start)

start = timer()
res = approach3(formula)
end = timer()
print("Approach 3: ", res, ",", end - start)


from snowflake.connector import DictCursor

def deploy_db_object_state_get(self,deploy_db_name:str, env:str)->dict:
    cur = self._conn.cursor(DictCursor)
    object_full_name = deploy_db_name + '.DEPLOY.OBJECT_STATE'
    query = '''
        SELECT OBJECT_TYPE, OBJECT_NAME, DEPLOY_HASH, DB_HASH, DEPLOY_HASH_CODE FROM identifier(%s) WHERE ENV = %s;
    '''

    data={}
    try:
        cur.execute(query,(object_full_name,env))
        for rec in cur:
            nw = {}
            nw['OBJECT_TYPE'] = rec['OBJECT_TYPE']
            nw['DEPLOY_HASH'] = rec['DEPLOY_HASH']
            nw['DB_HASH'] = rec['DB_HASH']
            nw['DEPLOY_HASH_CODE'] = rec['DEPLOY_HASH_CODE']
            data[rec['OBJECT_NAME']] = nw

    except Exception as ex:
        msg = 'SQL Error:\n\nQuery: ' + query + '\n\nError Message:\n' + str(ex) + '\n\n'
        raise Exception(msg)
    finally:
        cur.close()
    return data


import os

from celery import Celery

from util.setting import conf

def task_files():
    file_paths = []
    bash_path = os.path.dirname(os.path.abspath(__file__))
    for root, dirs, files in os.walk(bash_path):
        if len(set(root.split('/')).intersection({'.git', 'venv', '__pycache__'})) > 0:
            continue
        for filename in files:
            filepath = os.path.join(root, filename)
            file_paths.append(filepath)
    py_files = [file[:-3] for file in file_paths if file[-3:] == '.py']
    py_files = [
        file.replace(bash_path + '/', '').replace('/', '.') for file in py_files
    ]
    py_files.remove('celery_server')
    return py_files

py_files = task_files()
celery_app = Celery('celery_server', broker=conf.get('BROKER_URL'), include=py_files)
celery_app.config_from_object(conf)

if __name__ == '__main__':
    # cmd celery -A celery_server worker -l INFO -c 4 -D -f ./celery.log --pidfile celery.pid
    celery_app.start()
    # task_files()


from django.urls import re_path

from dojo.home import views

urlpatterns = [
    #  dojo home pages
    re_path(r'^$', views.home, name='home'),
    re_path(r'^dashboard$', views.dashboard, name='dashboard'),
    re_path(r'^support$', views.support, name='support'),
]


import random
print("Welcome to the Hangman GAME!")
random_words=["marvel","harrypotter","thor","groot","captainamerica"]
word=random.choice(random_words)
n=len(word)
list=["_"]*n
print(list)
i=0
n=len(list)
count=n
chances=0
stages = ['''
  +---+
  |   |
  O   |
 /|\  |
 / \  |
      |
=========
''', '''
  +---+
  |   |
  O   |
 /|\  |
 /    |
      |
=========
''', '''
  +---+
  |   |
  O   |
 /|\  |
      |
      |
=========
''', '''
  +---+
  |   |
  O   |
 /|   |
      |
      |
=========''', '''
  +---+
  |   |
  O   |
  |   |
      |
      |
=========
''', '''
  +---+
  |   |
  O   |
      |
      |
      |
=========
''', '''
  +---+
  |   |
      |
      |
      |
      |
=========
''']
k=6
while True:
    if count==0:
        print("Game Over , You Won ! ")
        print(f"You took {chances} to finish this game")
        break
    g=input("letter:").lower()
    chances=chances+1
    if g in word:
        for i in range(len(word)):
            if(g.lower()==word[i].lower()):
                list[i]=g.lower()
                count=count-1
        print(list)
    else:
        if k==0:
            print("Hangman Died, You Lost the GAME!")
        print("try again")
        print(stages[k])
        k=k-1

    n=n-1


from ZTUtils import make_query

import time
from zope.interface import implements
from Products.ATContentTypes.interface import IATTopic

from zope import schema
from zope.formlib import form
from zope.component import getMultiAdapter

from plone.portlets.interfaces import IPortletDataProvider
from plone.app.portlets.portlets import base
from plone.app.portlets.cache import render_cachekey
from plone.memoize import ram
from plone.memoize.compress import xhtml_compress
from plone.memoize.instance import memoize
from zope.schema.vocabulary import SimpleVocabulary

from Acquisition import aq_inner

from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile

from collective.portlet.relateditems import RelatedItemsMessageFactory as _

try:
    from collective.contentleadimage.config import IMAGE_FIELD_NAME
    from collective.contentleadimage.leadimageprefs import ILeadImagePrefsForm
    from zope.component import getUtility
    from Products.CMFPlone.interfaces import IPloneSiteRoot
    LEADIMAGE_EXISTS = True
except ImportError:
    LEADIMAGE_EXISTS = False

_N_CHAR = 100

DEFAULT_ALLOWED_TYPES = (
    'News Item',
    'Document',
    'Event',
    'File',
    'Image',
)

SORTING_CRITERIA = SimpleVocabulary.fromItems((
    (_(u"Modification date"), "modified"),
    (_(u"Effective date"), "effective"),
    (_(u"Creation date"), "created"),
))

# used to sanitize search
def quotestring(s):
    return '"%s"' % s

def quote_bad_chars(s):
    bad_chars = ["(", ")"]
    for char in bad_chars:
        s = s.replace(char, quotestring(char))
    return s

class IRelatedItems(IPortletDataProvider):
    """A portlet

    It inherits from IPortletDataProvider because for this portlet, the
    data that is being rendered and the portlet assignment itself are the
    same.
    """

    portlet_title = schema.TextLine(
        title=_(u'Portlet title'),
        description=_(u'Title in portlet.'),
        required=True,
        default=_(u'Related Items')
    )

    count = schema.Int(
        title=_(u'Number of related items to display'),
        description=_(u'How many related items to list.'),
        required=True,
        default=10
    )

    states = schema.Tuple(
        title=_(u"Workflow state"),
        description=_(u"Items in which workflow state to show."),
        default=('published', ),
        required=True,
        value_type=schema.Choice(
            vocabulary="plone.app.vocabularies.WorkflowStates"
        )
    )

    allowed_types = schema.Tuple(
        title=_(u"Allowed Types"),
        description=_(u"Select the content types that should be shown."),
        default=DEFAULT_ALLOWED_TYPES,
        required=True,
        value_type=schema.Choice(
            vocabulary="plone.app.vocabularies.ReallyUserFriendlyTypes"
        )
    )

    sorting = schema.Choice(
        title=_(u"Sorting criteria"),
        description=_(u"Select the sorting criteria for the collected contents."),
        default='modified',
        required=True,
        vocabulary=SORTING_CRITERIA,
    )

    show_all_types = schema.Bool(
        title=_(u"Show all types in 'more' link"),
        description=_(u"If selected, the 'more' link will display "
                       "results from all content types instead of "
                       "restricting to the 'Allowed Types'."),
        default=False,
    )

    only_subject = schema.Bool(
        title=_(u"Search only on subject"),
        description=_(u"If selected, we will search only on content subject."),
        default=False,
    )

    display_all_fallback = schema.Bool(
        title=_(u"Display recent items on no results fallback"),
        description=_(u"If selected, we will display all "
                      "allowed items where there are no results for "
                      "our current related items query"),
        default=True,
    )

    display_description = schema.Bool(
        title=_(u"Display description"),
        description=_(
            u"If selected, we will show the content short description"),
        default=True,
    )
    """"
    show_recent_items = schema.Bool(
        title=_(u"Show recent items"),
        description=_(u"If selected, recent items are shown "
                       #"results from all content types instead of "
                       "when related items are not found'."),
        default=False,
    )
    """

class Assignment(base.Assignment):
    """Portlet assignment.

    This is what is actually managed through the portlets UI and associated
    with columns.
    """

    implements(IRelatedItems)

    def __init__(self,
                 portlet_title=u'Related Items',
                 count=5,
                 states=('published',),
                 allowed_types=DEFAULT_ALLOWED_TYPES,
                 sorting='modified',
                 #show_recent_items=False,
                 only_subject=False,
                 show_all_types=False,
                 display_description=True,
                 display_all_fallback=True,
                ):
        self.portlet_title = portlet_title
        self.count = count
        self.states = states
        self.allowed_types = allowed_types
        self.sorting = sorting
        self.only_subject = only_subject
        #self.show_recent_items = show_recent_items
        self.show_all_types = show_all_types
        self.display_description = display_description
        self.display_all_fallback = display_all_fallback

    @property
    def title(self):
        """This property is used to give the title of the portlet in the
        "manage portlets" screen.
        """
        return self.portlet_title or _(u"Related Items")

class Renderer(base.Renderer):
    """Portlet renderer.

    This is registered in configure.zcml. The referenced page template is
    rendered, and the implicit variable 'view' will refer to an instance
    of this class. Other methods can be added and referenced in the template.
    """
    _template = ViewPageTemplateFile('relateditems.pt')

    @ram.cache(render_cachekey)
    def render(self):
        return xhtml_compress(self._template())

    @property
    def available(self):
        return len(self._data())

    def getRelatedItems(self):
        return self._data()

    @property
    def showRelatedItemsLink(self):
        """Determine if the 'more...' link needs to be displayed
        """
        # if the more link is for all types then always show it
        if self.data.show_all_types:
            return True
        # if we have more results than are shown, show the more link
        elif len(self.all_results) > self.data.count:
            return True
        return False

    def hasLeadImage(self):
        return LEADIMAGE_EXISTS

    def itemHasLeadImage(self, item):
        if self.hasLeadImage():
            return item.hasContentLeadImage

    def currenttime(self):
        return time.time()

    def showTime(self, item):
        return item.start.TimeMinutes() != '00:00' and item.end.TimeMinutes()

    @property
    def prefs(self):
        res = ''
        if LEADIMAGE_EXISTS:
            portal = getUtility(IPloneSiteRoot)
            res = ILeadImagePrefsForm(portal)
        return res

    #used for the view (relateditems.pt)
    def tag(self, obj, css_class='tileImage'):
        if LEADIMAGE_EXISTS:
            context = aq_inner(obj)
            field = context.getField(IMAGE_FIELD_NAME)
            if field is not None:
                if field.get_size(context) != 0:
                    scale = 'thumb'  # self.prefs.desc_scale_name
                    return field.tag(context, scale=scale, css_class=css_class)
        return ''

    def getAllRelatedItemsLink(self):
        portal_state = getMultiAdapter((self.context, self.request),
                                       name=u'plone_portal_state')
        portal_url = portal_state.portal_url()
        context = aq_inner(self.context)
        req_items = {}
        # make_query renders tuples literally, so let's make it a list
        req_items['Subject'] = list(context.Subject())
        if not self.data.show_all_types:
            req_items['portal_type'] = list(self.data.allowed_types)
        return '%s/search?%s' % (portal_url, make_query(req_items))

    def trimDescription(self, desc):
        if len(desc) > _N_CHAR:
                res = desc[0:_N_CHAR]
                lastspace = res.rfind(" ")
                res = res[0:lastspace] + " ..."
                return res
        else:
                return desc

    def _contents(self):
        contents = []
        # Collection
        if IATTopic.providedBy(self.context):
            try:
                contents = self.context.queryCatalog(
                contentFilter={'sort_limit': 6})
            except:
                pass
        # probably a folder
        else:
            contents = self.context.getFolderContents()

        # Make sure the content is not too big
        contents = contents[:6]

        return contents

    def _itemQuery(self, value):
        search_query = []

        # Include categories in the search query
        #keywords = map(lambda x: x.lower(), value.Subject())
        keywords = list(value.Subject())

        # Include words from title in the search query
        title = value.Title().split()

        search_query = title + keywords

        # Filter out boolean searches and keywords with only one letter
        search_query = [res
                        for res in search_query
            if not res.lower() in ['not', 'and', 'or'] and len(res) != 1]

        return search_query

    def _itemsQuery(self, values):
        query = ''
        items = []
        for item in values:
            items += self._itemQuery(item)

        # remove duplicated search keywords
        items = self.uniq(items)

        #if len(items):
        #    query = items.pop(0)

        query = " OR ".join(items)

        return query

    def uniq(self, alist):    # Fastest order preserving
        set = {}
        return [set.setdefault(e, e) for e in alist if e not in set]

    def _query(self):
        context = aq_inner(self.context)

        contents = [self.context]
        # TODO: test if a collection limited to 3 items show anything...
        # get items in folder or collection
        folder_contents = []
        if self.context.isPrincipiaFolderish:
            folder_contents = self._contents()
            folder_contents = map(lambda x: x.getObject(), folder_contents)
        else:
            # Add references and back-references (related items)
            try:
                contents += context.getReferences()
            except Exception:
                pass
            try:
                contents += context.getBackReferences()
            except Exception:
                pass

        contents += folder_contents

        search_query = self._itemsQuery(contents)
        return search_query

    def getPortletTitle(self):
        return self.data.portlet_title

    def displayDescription(self):
        return self.data.display_description

    @memoize
    def _data(self):
        plone_tools = getMultiAdapter((self.context, self.request),
                                      name=u'plone_tools')
        context = aq_inner(self.context)
        here_path = ('/').join(context.getPhysicalPath())

        # Exclude items from related if contained in folderish
        content = []
        if self.context.isPrincipiaFolderish:
            content = self._contents()

        exclude_items = map(lambda x: x.getPath(), content)
        exclude_items += [here_path]

        search_query = self._query()
        search_query = quote_bad_chars(search_query)
        #print 'search_query = '+search_query

        catalog = plone_tools.catalog()
        limit = self.data.count
        # increase by one since we'll get the current item
        extra_limit = limit + len(exclude_items)

        query = dict(portal_type=self.data.allowed_types,
                     SearchableText=search_query,
                     sort_on=getattr(self.data, "sorting", "modified"),
                     sort_order='reverse',
                     sort_limit=extra_limit)
        if self.data.only_subject:
            query['Subject'] = self.context.Subject()
            if 'SearchableText' in query:
                del query['SearchableText']
        results = catalog(**query)

        # filter out the current item
        self.all_results = [res
                            for res in results
                            if not res.getPath() in exclude_items]

        # No related items were found
        # Get the latest modified articles

        #if self.data.show_recent_items and self.all_results == []:
        if self.data.display_all_fallback and (self.all_results == []):
            results = catalog(portal_type=self.data.allowed_types,
                sort_on=getattr(self.data, "sorting", "modified"),
                sort_order='reverse',
                sort_limit=extra_limit)
            self.all_results = [res
                                for res in results
                                if not res.getPath() in exclude_items]

        return self.all_results[:limit]

class AddForm(base.AddForm):
    """Portlet add form.

    This is registered in configure.zcml. The form_fields variable tells
    zope.formlib which fields to display. The create() method actually
    constructs the assignment that is being added.
    """
    form_fields = form.Fields(IRelatedItems)
    label = _(u"Add Related Items Portlet")
    description = _(u"This portlet displays recent Related Items.")

    def create(self, data):
        return Assignment(
            portlet_title=data.get('portlet_title', u'Related Items'),
            count=data.get('count', 5),
            states=data.get('states', ('published',)),
            allowed_types=data.get('allowed_types',
                                   DEFAULT_ALLOWED_TYPES),
            #show_recent_items=data.get('show_recent_items', False),
            only_subject=data.get('only_subject', False),
            show_all_types=data.get('show_all_types', False),
            display_all_fallback=data.get('display_all_fallback', True),
            display_description=data.get('display_description', True),
        )

class EditForm(base.EditForm):
    """Portlet edit form.

    This is registered with configure.zcml. The form_fields variable tells
    zope.formlib which fields to display.
    """
    form_fields = form.Fields(IRelatedItems)
    label = _(u"Edit Related Items Portlet")
    description = _(u"This portlet displays related items based on "
                     "keywords matches, title and related items.")


class Solution(object):
    def trap(self, height):
        """
        :type height: List[int]
        :rtype: int
        """
        maxL=[]
        e=0
        leftH=[]
        for ele in height:
            if(ele>e):
                leftH.append(ele)
                e=ele
            else:
                leftH.append(e)
        e=0
        rightH=[]
        for ele in range(len(height)-1,-1,-1):
            if(height[ele]>e):
                rightH.append(height[ele])
                e=height[ele]
            else:
                rightH.append(e)
        rightH=rightH[::-1]
        res=[]
        for ele in range(len(leftH)):
            res.append(min(leftH[ele],rightH[ele]))
        count=0
        for ele in range(len(res)):
            if(res[ele]-height[ele]>0):
                count+=res[ele]-height[ele]
        return count


import pandas as pd
import numpy as np
from sklearn.metrics import mean_absolute_error, mean_absolute_percentage_error, accuracy_score
import altair as alt
import streamlit as st

def setup():
  PAGE_CONFIG = {"page_title":"FantAnalytics",
                  "page_icon":":bar_chart:",
                  "layout":"wide",
                  "theme":"dark"}
  st.set_page_config(**PAGE_CONFIG)

  setup()

df = pd.read_csv("Dashboard/Predizioni/2022-23.csv", index_col=0)

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

def accuracy_sign(y_val, preds, previous_period, given_threshold:float=None, absolute_error:bool=False):
    '''
    Compute accuracy of predicted trend w.r.t. previous_period

    given_threshold: meant to avoid distortions in the absence of any trend. If provided, predictions with error < given_threshold are considered correct, regardless of the actual sign
    absolute_error: ignored when given_threshold is None. If False, given_threshold is evaluated as % error, else as an abolute_error
    '''

    # Make sure we are dealing with three Series with the same index
    y_val = pd.Series(y_val).reset_index(drop=True)
    preds = pd.Series(preds).reset_index(drop=True)
    previous_period = pd.Series(previous_period).reset_index(drop=True)
    index = [i for i in y_val.index]

    # For each sample, compute the real and the predicted trends
    real = [1 if (y_val[i] - previous_period[i]) >= 0 else 0 for i in index]
    predicted = [1 if (preds[i] - previous_period[i]) >= 0 else 0 for i in index]

    # Modify predicted to match real when the error is neglectable
    if given_threshold is not None:
        # Compute errors
        if not absolute_error:
            # Add very small value when zero to make division possible
            # Error is below threshold if the predicted value is exactly zero as well
            y_val = [x if x != 0 else .0001 for x in y_val]
            preds = [x if x != 0 else .0001 for x in preds]
            ratios = [preds[i] / y_val[i] for i in range(size)]
            error_below_threshold = [(x > 1 - given_threshold) and (x < 1 + given_threshold) for x in ratios]
        else:
            error_below_threshold = [abs(preds[i] - y_val[i]) < given_threshold for i in index]

        real = [real[i] for i in range(len(predicted)) if error_below_threshold[i] == False]
        predicted = [predicted[i] for i in range(len(predicted)) if error_below_threshold[i] == False]

    return accuracy_score(real, predicted)

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

def scatter(df, x:str, y:str, tooltip:list=["Nome"], x_min=None, x_max=None, y_min=None, y_max=None, allinea_assi:bool=False, diagonali:bool=False):

    df = df.reset_index().round(2)

    x_min = df[x].min() if x_min is None else x_min
    x_max = df[x].max() if x_max is None else x_max
    y_min = df[y].min() if y_min is None else y_min
    y_max = df[y].max() if y_max is None else y_max
    axis_min = min([x_min, y_min])
    axis_max = max([x_max, y_max])

    x_domain = [x_min-.5, x_max+.5] if not allinea_assi else [axis_min-.5, axis_max+.5]
    y_domain = [y_min-.5, y_max+.5] if not allinea_assi else [axis_min-.5, axis_max+.5]

    graph = (alt.Chart(df)
        .mark_circle(size=40)
        .encode(
            x=alt.X(x, scale=alt.Scale(domain=x_domain), title=x),
            y=alt.Y(y, scale=alt.Scale(domain=y_domain), title=y),
            color=alt.Color("Ruolo Anno Successivo", scale=alt.Scale(domain=["P", "D", "C", "A"], range=["#F8AB12", "#65C723", "#136AF6", "#F21C3C"]), title="Ruolo"),
            tooltip=alt.Tooltip(tooltip))
        .interactive())

    if diagonali:

        central_line = (alt.Chart(pd.DataFrame({'var1': [-100, 100], 'var2': [-100, 100]}))
            .mark_line()
            .encode(
                x=alt.X('var1', title=""),
                y=alt.Y('var2', title=""))
            .interactive())

        steps = [i for i in list(np.arange(-1, 1.1, .125)) if i != 0]
        counter = 0
        for step in steps:
            globals()["line"+str(counter)] = (alt.Chart(pd.DataFrame(pd.DataFrame({'var1': [-100-step, 100-step], 'var2': [-100+step, 100+step]})))
            .mark_line(color="grey", opacity=(1-abs(step))/2)
            .encode(
                x=alt.X('var1', title=""),
                y=alt.Y('var2', title=""))
                )
            counter +=1

        return graph + central_line + alt.layer(*(globals()["line"+str(i)] for i in range(counter)))

    return graph

def bars_multiple_features(df, x:list, y:str, x_name:str=" ", y_name:str=" ", x_min=None, x_max=None):

    x_min = min([df[i].min() for i in x]) if x_min is None else x_min
    x_max = max([df[i].max() for i in x]) if x_max is None else x_max
    x_domain = [x_min-.5, x_max+.5]

    # Create a series of values indexed by (y1 + each value of x)
    df = df.reset_index()[x+[y]].set_index(y).stack().reset_index().rename(columns={"level_1": y_name, 0: x_name})

    graph = (alt.Chart(df)
        .mark_bar()
        .encode(
            x=alt.X(x_name, scale=alt.Scale(domain=x_domain)),
            y=y_name,
            color=alt.Color(y_name, legend=None),
        ))

    return graph

def grafico_esplora_predizioni(df, x_min:int=None, x_max:int=None):

    df = df.rename(columns={"Fantavoto Media Reale Anno Successivo": "Media Reale",
                                "Fantavoto Media Predetta Anno Successivo": "Media Predetta",
                                "Differenza Reale Fantavoto Media Anno Successivo": "Reale",
                                "Differenza Predetta Fantavoto Media Anno Successivo": "Predetta"})

    selector_player = alt.selection_point(fields=['Nome'], on="mouseover", empty="none")

    graph1 = (scatter(df,
        x="Media Reale",
        y="Media Predetta",
        tooltip=["Nome", "Media Reale", "Errore Predizione"],
        allinea_assi=True,
        diagonali=True)
        .add_params(selector_player)
        )

    graph2 = (bars_multiple_features(df,
        x=["Reale", "Predetta"],
        y="Nome",
        x_name="Differenza Anno Precedente (se disponibile)",
        y_name=" ",
        x_min=x_min,
        x_max=x_max)
        .transform_filter(selector_player)
        )
    graph2 = graph2.properties(height=100)

    return alt.vconcat(graph1, graph2).resolve_scale(color='independent')

def density_chart(x:str, group:str=None, df=None, graph_type:str="area", x_title:str=None, group_title:str=None, y_title:str="Density", legend:bool=True, color_domain:list=None, color_range:list=None, opacity:float=.3, filled:bool=True, strokeDash:list=[0]):

    chart = alt.Chart(df) if df is not None else alt.Chart()

    if graph_type == "area":
        chart = chart.mark_area(opacity=opacity, filled=filled, strokeDash=strokeDash)
    elif graph_type == "line":
        chart = chart.mark_line(opacity=opacity, filled=filled, strokeDash=strokeDash)
    else:
        raise Exception("graph_type should be either area or line")

    x_title = x if x_title is None else x_title
    if group is None:
        chart = chart.transform_density(x, as_=[x, y_title])
        chart = chart.encode(x=alt.X(x, title=x_title), y=y_title+":Q")
    else:
        chart = chart.transform_density(x, as_=[x, y_title], groupby=[group])
        group_title = group if group_title is None else group_title
        if legend:
            color = alt.Color(group, title=group_title) if color_domain is None or color_range is None else alt.Color(group, scale=alt.Scale(domain=color_domain, range=color_range), title=group_title)
        else:
            color = alt.Color(group, title=group_title, legend=None) if color_domain is None or color_range is None else alt.Color(group, scale=alt.Scale(domain=color_domain, range=color_range), title=group_title, legend=None)
        chart = chart.encode(x=alt.X(x, title=x_title), y=y_title+":Q", color=color)

    return chart

def grafico_densita_predizioni(df, by_group:bool=True, facet:bool=False):

    color_domain=["P", "D", "C", "A"]
    color_range=["#F8AB12", "#65C723", "#136AF6", "#F21C3C"]

    if by_group:

        df = df.rename(columns={"Ruolo":"Ruolo_", "Ruolo Anno Successivo":"Ruolo"})

        predicted = density_chart(
            x="Fantavoto Media Predetta Anno Successivo",
            group="Ruolo",
            x_title="Media Fantavoto",
            y_title="Densità",
            group_title="Predetta",
            color_domain=color_domain,
            color_range=color_range,
            graph_type="line",
            filled=False,
            opacity=1,
            legend=not facet
            )

        real = density_chart(
            x="Fantavoto Media Reale Anno Successivo",
            group="Ruolo",
            x_title="Media Fantavoto",
            y_title="Densità",
            group_title="Reale",
            color_domain=color_domain,
            color_range=color_range,
            opacity=.2,
            legend=not facet
            )

    else:

        predicted = density_chart(
            x="Fantavoto Media Predetta Anno Successivo",
            x_title="Media Fantavoto",
            y_title="Densità",
            graph_type="line",
            filled=False,
            opacity=1
            )

        real = density_chart(
            x="Fantavoto Media Reale Anno Successivo",
            x_title="Media Fantavoto",
            y_title="Densità",
            color_domain=color_domain,
            color_range=color_range,
            opacity=.2
            )

    chart = alt.layer(real, predicted, data=df.reset_index())

    if facet and by_group:
        return chart.properties(height=300).facet(facet=alt.Column("Ruolo", title=None), columns=2)
    else:
        return chart.resolve_scale(color='independent')

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

def main():
    st.set_page_config(layout="wide")
    st.sidebar.title("FantAnalytics")
    st.sidebar.image("https://cdn3.iconfinder.com/data/icons/education-science-vol-2-1/512/soccer_football_sports_game-512.png", width=150) #"https://cdn-icons-png.flaticon.com/512/3588/3588441.png"

    sx, dx = st.columns(2)
    with dx:
        stagione = st.selectbox("", ["2022-23", "2023-24"])
    with sx:
        st.title(f"Stagione {stagione}")

    if stagione == "2022-23":

        # Sidebar
        st.sidebar.header(":gear: Filtri")
        eta_min = int(df["Età"].min())
        eta_max = int(df["Età"].max())
        slider_eta = st.sidebar.slider("Età", min_value=eta_min, max_value=eta_max, value=[eta_min, eta_max])
        slider_presenze = st.sidebar.slider("Presenze Anno Precedente", min_value=0, max_value=38, value=[5,38])
        ruoli = ["P", "D", "C", "A"]
        checkbox_ruoli = st.sidebar.multiselect("Ruoli", options=ruoli, default=ruoli)
        name_search = (st.sidebar.text_input("Nome Giocatore")).title()

        # Filtra Dati
        subset = df[df["Ruolo Anno Successivo"].isin(checkbox_ruoli)]
        subset = subset[(subset["Età"] >= slider_eta[0]) & (subset["Età"] < slider_eta[1] + 1)]
        subset = subset[(subset["Presenze"] >= slider_presenze[0]) & (subset["Presenze"] < slider_presenze[1] + 1)]
        if name_search != "":
            subset = subset[subset["Nome"].str.startswith(name_search)]

        # Check in caso di subset vuoto
        if subset.shape[0] > 0:

            st.header("Esplora Predizioni Fantavoto")
            sx, dx = st.columns(2)
            with sx:
                st.altair_chart(grafico_esplora_predizioni(subset, x_min=-3, x_max=3), use_container_width=True)
            with dx:
                with st.expander("Dettagli", expanded=True):
                    st.info('''
                        ✅ Una previsione perfetta poggia sulla diagonale azzurra\n
                        - Un punto ↖ rappresenta una previsione sovrastimata, uno ↘ una previsione sottostimata\n
                        - Un punto ↗ rappresenta una media Fantavoto alta, uno ↙ una media bassa\n
                        🔍 Passa il mouse su un punto per scoprire il nome di quel giocatore e popolare il secondo grafico
                        ''')

            st.divider()
            sx, dx = st.columns(2)
            with sx:
                st.header("Densità Predizioni Fantavoto")
            with dx:
                with st.expander("Dettagli"):
                    st.info('''
                        📚 Compara la distribuzione Predetta (➖) a quella Reale (🟣)
                        ''')
                    dx1, dx2 = st.columns(2)
                    with dx1:
                        toggle_by_role = st.toggle("Densità per Ruolo", value=False)
                    with dx2:
                        if toggle_by_role:
                            toggle_facet = st.toggle("Separa Grafici per Ruolo", value=True)
                        else:
                            toggle_facet = False
            if subset.shape[0] > 0:
                st.altair_chart(grafico_densita_predizioni(subset, by_group=toggle_by_role, facet=toggle_facet), use_container_width=True)

            st.divider()
            with st.container():
                st.header("Performance Modello")
                sx, dx = st.columns(2)
                with sx:
                    st.subheader(":dart: Errore Assoluto")
                    sx1, sx2, sx3 = st.columns(3)
                    with sx1:
                        st.markdown("### Medio:")
                        mae = mean_absolute_error(subset["Fantavoto Media Reale Anno Successivo"], subset["Fantavoto Media Predetta Anno Successivo"])
                        st.markdown(f"# :red[{round(mae, 2)}]")
                    with sx2:
                        st.markdown("### Medio %:")
                        mape = mean_absolute_percentage_error(subset["Fantavoto Media Reale Anno Successivo"], subset["Fantavoto Media Predetta Anno Successivo"])
                        st.markdown(f"# :red[{round(mape*100, 2)}%]")
                    with sx3:
                        st.markdown("### Massimo:")
                        max_error = subset["Errore Predizione"].max()
                        st.markdown(f"# :red[{round(max_error, 2)}]")
                with dx:
                    st.subheader(":chart_with_upwards_trend: Accuratezza del Trend Previsto")
                    with st.expander("Dettagli"):
                        st.info('''
                                📉 Classificazione binaria: il modello riesce a predire in che direzione si muoverà la media Fantavoto rispetto all'anno precedente?\n
                                ❌ La seconda variante esclude le predizioni con errore trascurabile, per testare l'affidabilità del modello su quelle più problematiche\n
                                ⚙ Usa lo slider per regolare la soglia di tolleranza\n
                                ⚠ Questo KPI è ovviamente calcolato solo per i giocatori con Presenze Anno Precedente > 0
                                ''')
                        slider_soglia_errore = st.slider("Soglia Errore Trascurabile", min_value=0.0, max_value=1.0, value=0.5)
                    if slider_presenze[1] > 0:
                        dx1, dx2 = st.columns(2)
                        with dx1:
                            st.markdown(f"### Assoluta:")
                            acc_sign = accuracy_sign(subset["Fantavoto Media Reale Anno Successivo"], subset["Fantavoto Media Predetta Anno Successivo"], subset["Fantavoto Media"])
                            st.markdown(f"# :blue[{round(acc_sign*100, 2)}%]")
                        with dx2:
                            if slider_soglia_errore > 0:
                                st.markdown(f"### Solo Errori >= {slider_soglia_errore}:")
                                acc_sign_given_error = accuracy_sign(subset["Fantavoto Media Reale Anno Successivo"], subset["Fantavoto Media Predetta Anno Successivo"], subset["Fantavoto Media"], given_threshold=slider_soglia_errore, absolute_error=True)
                                st.markdown(f"# :blue[{round(acc_sign_given_error*100, 2)}%]")
                            else:
                                pass
                    else:
                        st.markdown("Non applicabile per giocatori senza Presenze Anno Precedente")

        else:
            st.divider()
            st.subheader("Nessun Giocatore :face_with_monocle:")
            st.markdown("Imposta dei filtri meno restrittivi")
            st.divider()

    elif stagione == "2023-24":
        st.markdown("## Coming soon...\n#### ...dopo le mie aste :sunglasses:\n######  \n###### (ma se non giocate contro di me scrivetemi pure)")

if __name__ == '__main__':
    main()


import os

from .ansible_runner import AnsibleRunner
from keywords.exceptions import ProvisioningError

from keywords.utils import log_info

import argparse

# Install aws credentials onto machine in /root/.aws/credentials file.
# Currently used by awslogs, which is a cloudwatch logs forwarder.
#
# Don't use full aws credentials, create a keypair on the existing mobiletestkit user
# which has full cloudwatch permissions, but nothing else

def install_aws_credentials(cluster_config, aws_access_key_id, aws_secret_access_key):

    log_info("Installing aws credentials for cluster_config: {}".format(cluster_config))

    ansible_runner = AnsibleRunner(config=cluster_config)

    status = ansible_runner.run_ansible_playbook(
        "install-aws-credentials.yml",
        extra_vars={
            "aws_access_key_id": aws_access_key_id,
            "aws_secret_access_key": aws_secret_access_key,
        },
    )
    if status != 0:
        raise ProvisioningError("Failed to aws credentials")

if __name__ == "__main__":

    usage = "usage: python install_aws_credentials.py --aws-access-key-id AKIAIYOURKEY --aws-secret-access-key uaLqkyoursecret"

    parser = argparse.ArgumentParser()
    parser.add_argument("--aws-access-key-id", help="aws access key id (use limited key, see comments in code)", required=True)
    parser.add_argument("--aws-secret-access-key", help="aws secret access key", required=True)
    args = parser.parse_args()

    try:
        cluster_conf = os.environ["CLUSTER_CONFIG"]
    except KeyError as ke:
        print("Make sure CLUSTER_CONFIG is defined and pointing to the configuration you would like to provision", ke)
        raise KeyError("CLUSTER_CONFIG not defined. Unable to provision cluster.")

    install_aws_credentials(cluster_conf, args.aws_access_key_id, args.aws_secret_access_key)


# -*- coding: utf-8 -*-
import time
import math

class Cup(object):
    def __init__(self, drink, price):
        self.content = drink
        self.price = price
        self._init_temp = 80
        self.full = 1.0
        self._timestamp = time.time()    # initiate time for cool-down

    def heat_up(self, degrees):
        if degrees < 0:
            raise Exception('heat_up accepts only positive numbers')
        new_temp = self.temp + degrees
        if new_temp <= 100:
            self._init_temp = new_temp
        else:
            self._init_temp = 100
        self._timestamp = time.time()    # refresh time for cool-down

    def drink(self, sip):
        if sip < 0:
            raise Exception('drink only accepts positive numbers')
        self.full -= sip
        if self.full <= 0:
            self.full = 0

    @property
    def temp(self):
        exponent = time.time() - self._timestamp
        return int(self._init_temp * math.exp(-0.0002 * exponent))

class CoffeeMachine(object):

    @staticmethod
    def brew(drink):
        price_list = {
            'tea': 1.80,
            'coffee': 2.10,
            'latte': 2.60,
            'chocolate': 2.10,
            'chai': 2.40
        }
        if drink in price_list:
            return Cup(drink, price_list[drink])
        else:
            return 'Drink not available.'


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Fri Nov  3 12:51:33 2017

@author: emilykukura

A permutation is an ordered arrangement of objects. For example,
3124 is one possible permutation of the digits 1, 2, 3 and 4. If all
of the permutations are listed numerically or alphabetically, we call
it lexicographic order. The lexicographic permutations of 0, 1 and 2 are:

012   021   102   120   201   210

What is the millionth lexicographic permutation of the
digits 0, 1, 2, 3, 4, 5, 6, 7, 8 and 9?
"""

import math, time

#returns the ind-th lex. perm of the numbers in number_set
def get_lex_perm(number_set, ind):
    #print("\n\nget_lex_perm called with arguments:\nnumber_set = {}\nind =  {}\n".format(number_set, ind))
    num_classes = len(number_set)
    number_list = sorted(number_set)
    total_perms = math.factorial(num_classes)
    # we will split all of the permutations into num_classes = len(number_set)
    # so that each class contains the permutations starting with a single number in number_set
    class_size = int(total_perms / num_classes)
    ind_class = math.floor(ind / class_size) #e.g. if index is 54 and the class size is 10, will be in the class with index 5
    the_class = number_list[ind_class]
    remaining_ind = ind - (class_size * ind_class)
    remaining_nums = set(number_set)
    remaining_nums.remove(the_class)

    #print("num_classes = {}\ntotal_perms = {}\nclass_size = {}\n".format(num_classes, total_perms, class_size))
    #print("ind_class = {}\nthe_class = {}\nremaining_ind = {}\n".format(ind_class, the_class, remaining_ind))

    res = [the_class]
    #print("len(remaining_nums) = ", len(remaining_nums))

    if len(remaining_nums) > 0:
        res.extend(get_lex_perm(remaining_nums, remaining_ind))

    #print("\nres when number_set = {} is {}\n".format(number_set, res))

    return res

def solution_1(numbers, ind):
    return get_lex_perm(numbers, ind-1)

if __name__ == '__main__':

    numbers = {i for i in range(10)}
    num = 1000000

    #numbers = {i for i in range(4)}
    #num = 8
    #0123, 0132, 0213, 0231, 0312, 0321
    #1023, 1032, 1203, 1230, 1302, 1320
    #2013, 2031, 2103, 2130, 2301, 2310
    #3012, 3021, 3102, 3120, 3201, 3210

    start = time.time()
    res_1 = solution_1(numbers, num)
    end = time.time()
    print("res_1 = {}\nTook {} seconds".format(res_1, end-start))
    # time ~ 0.000128 s

    # Answer: 2783915460

#a = [1,2]
#a.extend([3,4])
#print(a)


from typing import Dict, Optional, Tuple

import torch
import torch.nn.functional as F
from transformers.models.gpt2.modeling_gpt2 import GPT2LMHeadModel

from archai.nlp.models.hf_gpt2.config_hf_gpt2 import HfGPT2Config, HfGPT2FlexConfig
from archai.nlp.models.hf_gpt2.hf_gpt2_utils.gpt2_lm_head_model_flex import GPT2LMHeadModelFlex
from archai.nlp.models.model_base import ArchaiModel

class HfGPT2(ArchaiModel):
    """Huggingface's Open AI GPT-2 standard architecture.

    """

    def __init__(self, **kwargs) -> None:
        """Initializes the class by creating compatible configuration and model objects.

        """

        super().__init__()

        self.config = HfGPT2Config(**kwargs)
        self.model = GPT2LMHeadModel(self.config)

        if self.config.tie_weight:
            self.model.tie_weights()

    def forward(self,
                input_ids: torch.Tensor,
                labels: Optional[torch.Tensor] = None,
                mems: Optional[torch.Tensor] = None,
                past_key_values: Optional[torch.Tensor] = None,
                output_loss: Optional[bool] = True,
                output_prediction_scores: Optional[bool] = False
                ) -> Tuple[torch.Tensor, ...]:
        assert mems is None, 'HfGPT2 does not support memory (mems).'

        # Labels are the same as input_ids because they will be shifted inside the model
        # Causal attention mask is also created inside the model
        outputs = self.model(input_ids=input_ids,
                             labels=input_ids,
                             attention_mask=torch.ones_like(input_ids),
                             past_key_values=past_key_values)

        if output_loss:
            return (outputs.loss, None, None, outputs.past_key_values)

        if output_prediction_scores:
            # GPT-2 only outputs the logits, so they need to be converted with log_softmax
            return (None, F.log_softmax(outputs.logits, dim=-1), None, outputs.past_key_values)

    def get_params(self) -> Dict[str, int]:
        params = {}

        params['embedding'] = self.get_params_from_layer(['Embedding'])
        params['attention'] = self.get_params_from_layer(['GPT2Attention'])
        params['ff'] = self.get_params_from_layer(['GPT2MLP'])
        params['layer_norm'] = self.get_params_from_layer(['LayerNorm'])

        params['non_embedding'] = params['attention'] + params['ff'] + params['layer_norm']
        params['total'] = params['non_embedding'] + params['embedding']

        return params

class HfGPT2Flex(ArchaiModel):
    """Huggingface's Open AI GPT-2 flex-based architecture.

    Flex-based architectures allow different hyperparameters settings for each layer.

    """

    def __init__(self, **kwargs) -> None:
        """Initializes the class by creating compatible configuration and model objects.

        """

        super().__init__()

        self.config = HfGPT2FlexConfig(**kwargs)
        # assert all(self.config.n_head[0] == n_h for n_h in self.config.n_head), 'HfGPT2Flex does not support different `n_head`.'

        self.model = GPT2LMHeadModelFlex(self.config)

        if self.config.tie_weight:
            self.model.tie_weights()

    def forward(self,
                input_ids: torch.Tensor,
                labels: Optional[torch.Tensor] = None,
                mems: Optional[torch.Tensor] = None,
                past_key_values: Optional[torch.Tensor] = None,
                output_loss: Optional[bool] = True,
                output_prediction_scores: Optional[bool] = False
                ) -> Tuple[torch.Tensor, ...]:
        assert mems is None, 'HfGPT2Flex does not support memory (mems).'

        # Causal attention mask is created inside the model
        outputs = self.model(input_ids=input_ids,
                             labels=labels,
                             attention_mask=torch.ones_like(input_ids),
                             past_key_values=past_key_values,
                             output_loss=output_loss,
                             output_prediction_scores=output_prediction_scores)

        if output_loss:
            return (outputs.loss, None, None, outputs.past_key_values)

        if output_prediction_scores:
            return (None, outputs.logits, None, outputs.past_key_values)

    def get_params(self) -> Dict[str, int]:
        params = {}

        if self.config.div_val >= 1:
            # Positional embeddings are nn.Embedding layers, which overlap
            # when calculated together with AdaptiveEmbedding (have inner nn.Embedding layers)
            params['embedding'] = self.get_params_from_layer(['AdaptiveEmbedding']) + self.config.max_position_embeddings * self.config.hidden_size
        else:
            params['embedding'] = self.get_params_from_layer(['Embedding'])

        params['attention'] = self.get_params_from_layer(['GPT2AttentionFlex'])
        params['ff'] = self.get_params_from_layer(['GPT2MLPFlex'])
        params['layer_norm'] = self.get_params_from_layer(['LayerNorm'])

        params['non_embedding'] = params['attention'] + params['ff'] + params['layer_norm']
        params['total'] = params['non_embedding'] + params['embedding']

        return params


# -*- coding: utf-8 -*-
import logging,os,subprocess,re
from flask.logging import default_handler

from common.models.job.JobKillQueue import JobKillQueue
from common.models.job.JobList import JobList
from common.services.CommonConstant import CommonConstant
from jobs.tasks.BaseJob import BaseJob
from application import app,db

'''
强制停止Job
python /data/www/python3/python3_jobs/manage_job.py runjob -m kill
'''
class JobTask( BaseJob ):
    def __init__(self):
        ## 设置Job使用debug模式
        app.config['DEBUG'] = True
        logging_format = logging.Formatter(
            '%(levelname)s %(asctime)s %(filename)s:%(funcName)s L%(lineno)s %(message)s')
        default_handler.setFormatter(logging_format)

    def run(self, params):
        pid_path = self.getPidPath('kill.pid')
        if self.checkPidExist(pid_path):
            app.logger.info("[core] dispatch is running")
            return False

        pid = str(os.getpid())
        if not self.setPidFile(pid_path, pid):
            err_msg = self.getErrMsg()
            app.logger.info("Cann't get a lock file，err msg : " + err_msg)
            return False

        params = self.getEnvFile()
        server_id = params['id']
        host = params['name']

        kill_list = JobKillQueue.query.filter_by( server_id = server_id ,status =  CommonConstant.default_status_neg_2)\
            .order_by( JobKillQueue.id.asc() ).limit(10).all()

        if not kill_list:
            app.logger.info("没有Job需要kill~~")
            return True

        ##找到Job 杀死job
        for t in kill_list :
            tmp_ret = self.kill_process_with_children( t.job_id )
            t.status = CommonConstant.default_status_true if tmp_ret else CommonConstant.default_status_false
            db.session.add( t )
            db.session.commit()

        return True
    '''
    杀死job的父进程 和子进程，我们只杀死子进程，父进程就会死掉
    '''
    def kill_process_with_children(self,job_id):
        info = JobList.query.filter_by(id=job_id).first()
        if not info:
            app.logger.info("job_id:%s 没有查询到新" %(job_id) )
            return True

        ##如果填写了杀死命令，那么就用杀死命令执行
        if info.command_kill:
            app.logger.info( "job_id:%s 配置了杀死命令：%s" %( job_id, info.command_kill) )
            try:
                status = subprocess.check_call( info.command_kill, shell=True)
                if status != 0:
                    app.logger.info("job_id:%s 命令：%s 未能通过job平台正常退出，异常退出，退出状态为%d" % (job_id, info.command_kill, status))
            except Exception as e:
                app.logger.info("job_id:%s kill 命令：%s  失败，可能已经退出" % (job_id, info.command_kill ) )
            return True
        ##根据关键词找到的父id
        ppid = self.findPidByKw( job_id )

        if not os.path.isdir("/proc/%s/" % ppid ):
            app.logger.info("job_id:%s 父进程/proc/%s/不存在，进程已经退出,不再查询其子进程" % (job_id,ppid) )
            return True

        cmd = "ps -A -o ppid,pid,cmd | grep -v grep  |grep %s" % ppid
        app.logger.info( cmd )
        status, output = subprocess.getstatusoutput( cmd )
        if len( output ) < 1:
            return True

        output_arr = output.split('\n')
        child_pid = 0
        for tmp_p in output_arr:
            app.logger.info(tmp_p)
            if info.command not in tmp_p:
                app.logger.info("job_id:%s 没找到运行命令" % job_id)
                continue

            tmp_process_arr = re.split("\s+",tmp_p.strip() )
            app.logger.info( tmp_process_arr )
            if str(tmp_process_arr[0]) != str(ppid):
                continue

            child_pid = int( tmp_process_arr[1])

        app.logger.info( "job_id:%s 子进程id：%s"% (job_id,child_pid ) )
        if child_pid < 1:
            app.logger.info("job_id:%s 未找到运行的子进程" % job_id )
            return False

        if not os.path.isdir("/proc/%s/" % child_pid ):
            app.logger.info("job_id:%s 子进程/proc/%s/不存在，进程已经退出,不再查询其子进程" % (job_id, child_pid) )
            return False
        try:
            status = subprocess.check_call("kill -9 %s" % child_pid, shell=True)
            if status != 0:
                app.logger.info("job_id:%s 进程%s未能通过job平台正常退出，异常退出，退出状态为%d" % (job_id, child_pid,status ))
        except Exception as e:
            app.logger.info("job_id:%s kill 进程%s失败，可能已经退出" % (job_id, child_pid) )
        return True


"""
ID: colinya1
LANG: PYTHON3
TASK: beads
"""

fin = open("beads.in", "r")
fout = open("beads.out", "a")

n = int(fin.readline().strip())
necklace = fin.readline().strip()

print(n)
print(necklace[0:])

def evaluate(stringIn):
    """stringIn represents a necklace that has already been broken.
    We read from the beginning to the right, and then from the end to the left.
    Returns int, which is number of beads which can be legally taken."""

    numBeads = 0
    startColor = "w"
    endColor = "w"

    sameColor = True

    while sameColor:
        for char in stringIn:
            if startColor == "w":
                startColor = char

            if char == "w":
                numBeads += 1
            elif startColor == char:
                numBeads += 1
            else:
                sameColor = False
                break
        break

    sameColor = True

    stringBack = stringIn[numBeads:][::-1]
    while sameColor:
        for char in stringBack:
            if endColor == "w":
                endColor = char

            if char == "w":
                numBeads += 1
            elif endColor == char:
                numBeads += 1
            else:
                sameColor = False
                break
        break
    return numBeads

maxNum = 0
for i in range(n):
    newNeck = necklace[i:] + necklace[:i]
    print(newNeck)
    newMax = evaluate(newNeck)
    if newMax > maxNum:
        maxNum = newMax

print(maxNum)
fout.write(str(maxNum) + "\n")


import tkinter as tk

LARGE_FONT = ("Verdana",12)
# https://pythonprogramming.net/change-show-new-frame-tkinter/
class SeaofBTCapp(tk.Tk):

	def __init__(self, *args, **kwargs):
		tk.Tk.__init__(self, *args, **kwargs)
		container = tk.Frame(self)

		container.pack(side="top",fill="both", expand=True)

		container.grid_rowconfigure(0,weight=1)
		container.grid_columnconfigure(0, weight=1)

		self.frames = {}

		for F in (StartPage, PageOne, PageTwo):
			frame = F(container, self)

			self.frames[F] = frame
			frame.grid(row=0, column=0, sticky="nsew")

		self.show_frame(StartPage)

	def show_frame(self, cont):

		frame = self.frames[cont]
		frame.tkraise()

def qf(quickPrint):
	print(quickPrint)

class StartPage(tk.Frame):
	def __init__(self, parent, controller):
		tk.Frame.__init__(self, parent)
		label = tk.Label(self, text="Start Page", font=LARGE_FONT)
		label.pack(pady=15,padx=15)

		button = tk.Button(self, text="Visit Page 1",
                            command=lambda: controller.show_frame(PageOne))
		button.pack()
		button2 = tk.Button(self, text="Visit Page 2",
                            command=lambda: controller.show_frame(PageTwo))
		button2.pack()

class PageOne(tk.Frame):
	def __init__(self, parent, controller):
		tk.Frame.__init__(self, parent)
		label = tk.Label(self, text="Page One!!!", font=LARGE_FONT)
		label.pack(pady=10,padx=10)

		button1 = tk.Button(self, text="Back to Home",
                            command=lambda: controller.show_frame(StartPage))
		button1.pack()

		button2 = tk.Button(self, text="Page Two",
                            command=lambda: controller.show_frame(PageTwo))
		button2.pack()

class PageTwo(tk.Frame):
	def __init__(self, parent, controller):
		tk.Frame.__init__(self, parent)
		label = tk.Label(self, text="Page Two!!!", font=LARGE_FONT)
		label.pack(pady=10,padx=10)

		button1 = tk.Button(self, text="Back to Home",command=lambda: controller.show_frame(StartPage))
		button1.pack()

		button2 = tk.Button(self, text="Page One",
                            command=lambda: controller.show_frame(PageOne))
		button2.pack()

if __name__ == '__main__':
	app = SeaofBTCapp()
	app.mainloop()

3. Python/08. GUI Programming/4. Changing View.py


from django.views.decorators.csrf import csrf_exempt
from django.http import JsonResponse,HttpResponse
import youtube_dl
from youtube_dl import DownloadError
import re
import uuid
import os
from youtube_search import YoutubeSearch
import json
@csrf_exempt
def search(request):
    query=request.POST.get("query")
    result=str(uuid.uuid1()).split('-')[0]+".mp3"
    ydl_opts = {
    'format': 'bestaudio/bestaudio',
    'postprocessors': [{'key': 'FFmpegExtractAudio',
               'preferredcodec': 'mp3',
               'preferredquality': '192'}],
    'outtmpl': 'media/'+result,
    'quiet': False,
    'noplaylist':True,
    'ignoreerrors':True,
    'max-downloads':1,
    }
    ydl = youtube_dl.YoutubeDL(ydl_opts)
    try:
        title=(ydl.extract_info(query,download=False))['title']
    except youtbe_dl.utils.ExtractorError:
        return JsonResponse({"INVALID":"This mp3 is not available for download by you tube"},safe=False)
    title=re.sub('[\W_]+', '', str(title))+".mp3"
    try:
        ydl.download([query])
    except  youtube_dl.utils.DownloadError:
        print('Something went wrong!')
    except  youtube_dl.utils.UnavailableVideoError:
        return JsonResponse({"INVALID":"Mp3 format is not available for this song."},safe=False)
    except  youtube_dl.utils.GeoRestrictedError:
        return JsonResponse({"INVALID":"Song is not available in your country."},safe=False)
    except  youtube_dl.utils.YoutubeDLError:
        return JsonResponse({"INVALID":"Some error occured. Try again please."},safe=False)
    return JsonResponse({"fn":result,"sn":title},safe=False)
def autosuggest(request):
    data = request.GET.get("term")
    results = YoutubeSearch(''+data, max_results=5).to_json()
    mimetype = 'application/json'
    return HttpResponse(json.dumps(results), mimetype)


#!/usr/bin/env python
import rospy
from rospy_tutorials.srv import AddTwoInts, AddTwoIntsResponse, AddTwoIntsRequest  # Messages used in the node must be imported.

'''
"my_server" is the callback method of the service. Argument "req" contains request message sent by the client.
'''
def my_server(req):
	res = AddTwoIntsResponse() # declaring a response varible of the service.
	rospy.loginfo("Request received to add: %d & %d", req.a, req.b)
	res.sum=req.a+req.b
	return res

rospy.init_node('service_server_node_py') #initialzing the node with name "service_server_node_py"

'''
A service server is created in the below line.
First argument is the name of the Service. Service with name "add_py" is registered.
Second argument is the message type. The message type of this service is "AddTwoInts".
Third argument is the name of the callback method. This callback method is called whenever the client request for service.
'''
rospy.Service('add_py', AddTwoInts, my_server)

rospy.loginfo("Python Service server ready to add two numbers")

'''
rospy.spin() simply keeps your node from exiting until the node has been shutdown. Unlike roscpp::spin(), rospy.spin() does not affect the subscriber callback functions, as those have their own threads.
'''
rospy.spin()


#! /usr/bin/env python
import json
import warnings
from glob import glob
from os import path

import datreant

def convert(folder):
    treants = glob(path.join(folder, 'Treant*'))
    if len(treants) == 0:
        warnings.warn("No treant found in folder: {}".format(folder))
        return
    elif len(treants) > 1:
        warnings.warn("Multiple treants found in folder: {}\n"
                      "    Skipping conversion".format(folder))
        return

    json_file = treants[0]
    with open(json_file) as fh:
        old = json.load(fh)
    datreant.Treant(folder, categories=old['categories'], tags=old['tags'])

def main():
    import argparse
    parser = argparse.ArgumentParser(
        description="Convert pre 1.0 Treant to new Treant",
        formatter_class=argparse.ArgumentDefaultsHelpFormatter)
    parser.add_argument(
        "directories",
        metavar="DIRECTORY",
        nargs="+",
        help="one or more directories that are being processed")
    args = parser.parse_args()

    for dir in args.directories:
        convert(dir)

if __name__ == '__main__':
    main()


from django import forms
from django.contrib.auth.models import User
from django.utils.translation import ugettext_lazy as _
from django.utils import timezone

from redactor.fields import RedactorEditor

from insite_messages.models import Message

class MessageComposeForm(forms.Form):

  recipient = forms.ModelChoiceField(widget=forms.Select(attrs={
                        'class': 'ui fluid search dropdown',
                        'placeholder': _('recipient')}),
                      label=_('Recipient'),
                      queryset= User.objects.all())

  subject = forms.CharField(widget=forms.TextInput(attrs={
                        'placeholder': _('subject')}),
                      label=_('Subject'),
                      max_length=120)

  body = forms.CharField(widget=forms.Textarea(attrs={
                         'placeholder': _('message body'),
                         'cols': "20",
                         'rows': "5"}),
                        label=_('Message'),
                        max_length=500)

  def save(self, sender, parent=None):

    recipient = self.cleaned_data['recipient']
    try:
      recipient = User.objects.get(username=recipient.username)
    except User.DoesNotExist:
      raise forms.ValidationError(_('The following username is incorrect: %(username)s') % {
        'username': recipient_username
      })

    subject = self.cleaned_data['subject']
    body = self.cleaned_data['body']

    message = Message.objects.create_message(sender, recipient, subject, body)

    if parent is not None:
      message.parent = parent
      parent.replied_at = timezone.now()
      parent.save()

    message.save()

    return message

  class Meta:
    model = Message
    exclude = ['parent', 'sent_at', 'read_at', 'replied_at', 'sender_deleted_at', 'recipient_deleted_at']
    widgets = {
      'body': RedactorEditor()
    }


import os

def create_project_structure():
    project_name = "hr_process_optimization"
    directories = [
        "app",
        "app/models",
        "app/routes",
        "app/utils",
    ]

    files = [
        "app/__init__.py",
        "app/main.py",
        "app/models/__init__.py",
        "app/models/job.py",
        "app/models/candidate.py",
        "app/models/user.py",
        "app/routes/__init__.py",
        "app/routes/job.py",
        "app/routes/candidate.py",
        "app/routes/auth.py",
        "app/utils/__init__.py",
        "app/utils/nlp.py",
        "app/utils/ranking.py",
        "app/utils/email.py",
        "app/utils/auth.py",
        "requirements.txt",
        ".env",
        ".gitignore",
        "README.md",
        "main.py",
        "database.db",  # SQLite database file
    ]

    # Create the project directory
    os.makedirs(project_name, exist_ok=True)

    # Create directories
    for directory in directories:
        path = os.path.join(project_name, directory)
        os.makedirs(path, exist_ok=True)

    # Create files
    for file in files:
        path = os.path.join(project_name, file)
        with open(path, 'w') as f:
            pass

if __name__ == "__main__":
    create_project_structure()
    print("Project structure created successfully.")


from django.shortcuts import render,HttpResponse
from django.contrib.auth.decorators import login_required
from django.views.decorators.csrf import csrf_exempt
from utils.pages import page
from jasset import models
from django.db.models import Q
from jasset.api.asset import DealResponseAsset
# Create your views here.

@login_required
def asset_list(request):
    asset_objs = models.Asset.objects.select_related()
    page_objs = page(request, asset_objs)
    return render(request, "jasset/asset_list.html", {"page_objs": page_objs})

@login_required
def host_list(request):
    host_objs = models.Host.objects.select_related()
    page_objs = page(request, host_objs)
    return render(request, "jasset/host_list.html", {"page_objs": page_objs})

@csrf_exempt
def asset_api(request):
    """处理客户端反馈回的数据"""
    deal_asset_obj=DealResponseAsset(request)
    deal_asset_obj.execute()

    return HttpResponse("OK")

@login_required
def asset_info(request,asset_id):

    host_obj=models.Host.objects.filter(asset_id=asset_id).first()
    try:
        record_objs=host_obj.asset.assetrecord.all().order_by("-create_time")
    except:
        record_objs=None

    return render(request,"jasset/asset_info.html",locals())

@login_required
def assetrecord_list(request):
    if request.method=="GET":
        assetrecord_objs=models.AssetRecord.objects.select_related().order_by("create_time")
        page_objs=page(request,assetrecord_objs,page_number=20)
    if request.method=="POST":
        host_ip=request.POST.get("host_ip")
        assetrecord_objs=models.AssetRecord.objects.filter(asset__host__host_ip=host_ip).select_related().order_by("create_time")
        page_objs=page(request,assetrecord_objs,page_number=20)
    return render(request,"jasset/asset_record_list.html",locals())

@login_required
def asseterrorlog_list(request):
    if request.method=="GET":
        asset_error_log_objs=models.ErrorLog.objects.select_related().order_by("create_time")
        page_objs=page(request,asset_error_log_objs,page_number=20)
    if request.method=="POST":
        host_ip=request.POST.get("host_ip")
        asset_error_log_objs=models.ErrorLog.objects.filter(asset__host__host_ip=host_ip).select_related().order_by("create_time")
        page_objs=page(request,asset_error_log_objs,page_number=20)
    return render(request,"jasset/asset_error_log_list.html",locals())


import streamlit as st
import pandas as pd
import pickle
import numpy as np
from PIL import Image

model_landrace = pickle.load(open('model_landrace.sav', 'rb'))
model_yorkshire = pickle.load(open('model_yorkshire.sav', 'rb'))

st.title('Prediksi Angka Kelahiran Hewan Ternak Babi')
image = Image.open('img/pic.png')
st.image(image, width=300)

def predict_landrace(usia, bobot, penyakit, induk):
    result = model_landrace.predict([[0, bobot, usia, penyakit, induk]])

    return result

def predict_yorkshire(usia, bobot, penyakit, induk):
    result = model_yorkshire.predict([[0, bobot, usia, penyakit, induk]])

    return result

def main():
    jenis_option = st.selectbox("Pilih jenis babi", ["Landrace", "Yorkshire"])

    usia = st.slider('Usia (Bulan)', 8, 71, 8)
    bobot = st.slider('Bobot (Kg)', 80, 250, 80)
    chk_penyakit = st.selectbox('Penyakit', ('Ya', 'Tidak'))
    if chk_penyakit == 'Ya':
        penyakit = 1
    else:
        penyakit = 0
    induk = st.slider('Jumlah Indukan Yang Akan Melahirkan', 2, 4, 2)

    if st.button("Prediksi"):
        if jenis_option == "Landrace":
            result = predict_landrace(usia, bobot, penyakit, induk)
        elif jenis_option == "Yorkshire":
            result = predict_yorkshire(usia, bobot, penyakit, induk)

        prediksi = str(result).replace('[', '').replace(']', '')
        hasil = np.round(float(prediksi))
        hasil = int(hasil)
        st.write("Hasil prediksi:", hasil)
        st.write("Jadi untuk 2 minggu kedepan induk babi akan melahirkan sebanyak ", hasil, "ekor anak babi")
        st.write("Dan untuk per ekor indukan babi akan melahirkan sebanyak ", int(hasil/induk), "ekor anak babi")

if __name__ == "__main__":
    main()


from sortedcontainers import SortedList

class Solution:
    def countFairPairs(self, nums: List[int], lower: int, upper: int) -> int:
        n = len(nums)
        bst = SortedList()
        res = 0
        for i in range(n):
            res += bst.bisect_right(upper - nums[i]) - bst.bisect_left(lower - nums[i])
            bst.add(nums[i])
        return res


import pygame
import sys
import random

# Initialisation de Pygame
pygame.init()

# Dimensions de l'écran
largeur, hauteur = 640, 480
taille_case = 20

# Couleurs
noir = (0, 0, 0)
blanc = (255, 255, 255)
vert = (0, 255, 0)

# Création de l'écran
ecran = pygame.display.set_mode((largeur, hauteur))
pygame.display.set_caption("Snake")

# Fonction pour afficher le message de fin de jeu
def message_fin(texte):
    police = pygame.font.Font(None, 36)
    texte_surface = police.render(texte, True, blanc)
    texte_rect = texte_surface.get_rect()
    texte_rect.center = (largeur // 2, hauteur // 2)
    ecran.blit(texte_surface, texte_rect)
    pygame.display.flip()
    pygame.time.wait(2000)

# Fonction principale du jeu
def jouer():
    # Initialisation du serpent
    serpent = [(3, 1), (3, 2), (3, 3)]
    direction = (1, 0)

    # Position initiale de la pomme
    pomme = (random.randint(0, (largeur // taille_case) - 1), random.randint(0, (hauteur // taille_case) - 1))

    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_UP:
                    direction = (0, -1)
                elif event.key == pygame.K_DOWN:
                    direction = (0, 1)
                elif event.key == pygame.K_LEFT:
                    direction = (-1, 0)
                elif event.key == pygame.K_RIGHT:
                    direction = (1, 0)

        # Déplacer le serpent
        tête = (serpent[0][0] + direction[0], serpent[0][1] + direction[1])
        serpent.insert(0, tête)

        # Vérifier si le serpent mange la pomme
        if serpent[0] == pomme:
            pomme = (random.randint(0, (largeur // taille_case) - 1), random.randint(0, (hauteur // taille_case) - 1))
        else:
            serpent.pop()

        # Vérifier si le serpent a perdu
        if (serpent[0][0] < 0 or serpent[0][0] >= largeur // taille_case or
                serpent[0][1] < 0 or serpent[0][1] >= hauteur // taille_case or
                serpent[0] in serpent[1:]):
            message_fin("Game Over")
            jouer()

        # Effacer l'écran
        ecran.fill(noir)

        # Dessiner le serpent
        for segment in serpent:
            pygame.draw.rect(ecran, vert, (segment[0] * taille_case, segment[1] * taille_case, taille_case, taille_case))

        # Dessiner la pomme
        pygame.draw.rect(ecran, blanc, (pomme[0] * taille_case, pomme[1] * taille_case, taille_case, taille_case))

        # Mettre à jour l'écran
        pygame.display.flip()

        # Contrôler la vitesse du jeu
        pygame.time.Clock().tick(10)

# Lancer le jeu
jouer()


import argparse

def parse_args():
    """
    Parses command line arguments for jobs.
    Available arguments: --recreate, --norefresh, --dryrun, --refreshonly
    Passing no arguments: default behavior
        Truncsert and Tableau Refresh
    --recreate: necessary if table structure changes
        Drop Create and Tableau Refresh
    --recreate --norefresh:
        Drop Create and don't perform Tableau Refresh
    --dryrun: View the full DDL, do not execute statement or refresh tableau
        Print full statement and return
    --refreshonly: Kick the tableau refresh
        Tableau Refresh only
    Examples:
    python3 jobs/debug__command_line_args.py --norefresh --recreate
    Namespace(dryrun=False, norefresh=True, recreate=True, refreshonly=False)
    python3 jobs/debug__command_line_args.py --norefresh
    Namespace(dryrun=False, norefresh=True, recreate=False, refreshonly=False)
    python3 jobs/debug__command_line_args.py
    Namespace(dryrun=False, norefresh=False, recreate=False, refreshonly=False)
    """

    parser = argparse.ArgumentParser()
    parser.add_argument("--recreate", help="recreate", action="store_true")
    parser.add_argument("--norefresh", help="no refresh", action="store_true")
    parser.add_argument("--dryrun", help="dryrun", action="store_true")
    parser.add_argument("--refreshonly", help="refreshonly", action="store_true")
    args = parser.parse_args()

    return args

if __name__ == '__main__':
    print(parse_args())