# -*- coding: utf-8 -*-
from __future__ import division, print_function, absolute_import

import os
import sys
import subprocess
from datetime import datetime
from pprint import pprint, pformat
import logging
from glob import glob
from collections import namedtuple

import numpy as np
import tensorflow as tf

_DEFAULT_SESSIONS_PATH = './_sessions/'
_PRINT_SUMMARY_FREQ = 50

logger = logging.getLogger(__name__)

###############################################################################
# Some helper functions
###############################################################################
def compute_accuracy(oneshot_labels, predictions, k):
    """Computes Top-k accuracy. Note that the behaviour of in_top_k differs from
    the top_k op in its handling of ties; if multiple classes have the same
    prediction value and straddle the top-k boundary, all of those classes are
    considered to be in the top k."""
    correct_mask = tf.nn.in_top_k(predictions, tf.argmax(oneshot_labels, 1),
                                  k, name="top_{}_correct_mask".format(k))
    return tf.reduce_mean(tf.cast(correct_mask, tf.float32)) * 100.00

def get_num_trainable_params():
    return sum(np.prod(p.get_shape().as_list())
               for p in tf.trainable_variables())

def get_timedelta(start_time):
    delta = datetime.now() - start_time

    # timedelta objects don't have hours and seconds!
    hours, remainder = divmod(delta.seconds, 3600)
    minutes, seconds = divmod(remainder, 60)

    return('[{:01d} day(s), {:02d} hr(s), {:02d} min(s)]'.
           format(delta.days, hours, minutes))

def time_per_step(start_time, num_steps):
    delta = datetime.now() - start_time

    return (delta / num_steps).total_seconds() * 1000

def get_resettable_mean_metric(values, scope):
    """Used for validation and test datasets where we're interested in computing
    accuracy over the entire dataset but due to their size still have to loop
    through them via batches. Since we do this multiple times during training
    we'd like the metric to be resettable."""

    with tf.variable_scope(scope) as s:
        mean_op, update_mean_op = tf.metrics.mean(values)

    # The .* regex makes filtering work in nested scopes
    variables = tf.get_collection(tf.GraphKeys.LOCAL_VARIABLES, '.*'+scope)

    if (len(variables) == 0):
        logger.error("Couldn't collect resettable mean \"{}\"".format(scope))
        sys.exit()

    reset_mean_op = tf.variables_initializer(variables)

    return {'value_op': mean_op,
            'update_op': update_mean_op,
            'reset_op': reset_mean_op}

def find_latest_chkpt(search_dir):
    try:

        sessions = glob(os.path.join(search_dir, '*/'))
        sessions.sort(key=os.path.getmtime, reverse=True)

        # We pick up index 2 from the sorted list instead of 0 or 1 because
        # we've already created the session directory for this run plus the
        # 'latest' symlink
        latest_session = sessions[2]

        latest_checkpoint = tf.train.latest_checkpoint(
                    os.path.join(latest_session, 'train_checkpoints'))

        logger.info('Latest session found: {}'.format(latest_session))
        logger.info('Resuming from checkpoint: {}'.format(latest_checkpoint))

        return latest_checkpoint
    except IndexError:
        logger.error("Couldn't find the checkpoint.")
        sys.exit()

def make_symbolic_link(sessions_dir, session_name):
    latest_symlink = os.path.join(sessions_dir, 'latest')

    try:
        os.symlink(session_name, latest_symlink)
    except FileExistsError:
        logger.debug("Replaced old symbolic link.")
        os.unlink(latest_symlink)
        os.symlink(session_name, latest_symlink)

def save_frozen_model(sess, output_node_names, output_path,
                      placeholder_values=None):
    """Args:
        placeholder_values: dictionary for injecting values into placeholders
    """
    vars_removed_graph_def = tf.graph_util.convert_variables_to_constants(
        sess, tf.get_default_graph().as_graph_def(), output_node_names)

    # We'd like to convert unrelated placeholders to consts at this stage.
    # Examples of such placeholders are "keep_prob" for Dropout layers or
    # "is_training" for BatchNorm layers. Unfortunately there is not an easy way
    # to do this when freezing the model. The only official API I'm aware of is
    # the "map_dict" argument in "tf.import_graph_def" method which means
    # placeholders values can be provided when loading the frozen models. That's
    # why we're doing a dummy load here to use that API and will store the
    # result. The downside is that calling import_graph_def() adds an extra
    # prefix which cannot be removed.

    with tf.Graph().as_default() as output_graph:
        tf.import_graph_def(
            vars_removed_graph_def,
            input_map=placeholder_values,
            name="frozen")

    tf.train.write_graph(
        output_graph,
        output_path,
        'frozen_model.pb',
        as_text=False)

def load_frozen_graph(frozen_graph):

    with open(frozen_graph, "rb") as f:
        restored_graph_def = tf.GraphDef()
        restored_graph_def.ParseFromString(f.read())

    # temporarily override the current default graph
    with tf.Graph().as_default() as graph:
        tf.import_graph_def(restored_graph_def, name="")

    return graph

def configure_logger(log_file):

    # Make sure we're not adding duplicate handlers if train() is called
    # multiple times.
    if not logger.handlers:

        logger.setLevel(logging.DEBUG)

        file_log_format = logging.Formatter(
                        fmt='%(asctime)s [%(levelname)s] %(message)s',
                        datefmt="%Y-%m-%d %H:%M:%S")

        console_log_format = file_log_format

        console_log_handler = logging.StreamHandler()
        console_log_handler.setFormatter(console_log_format)
        console_log_handler.setLevel(logging.INFO)

        logger.addHandler(console_log_handler)

        # Also store logs to a file
        file_log_handler = logging.FileHandler(log_file, 'w')
        file_log_handler.setFormatter(file_log_format)
        file_log_handler.setLevel(logging.DEBUG)
        logger.addHandler(file_log_handler)

def train(num_epochs, batch_size, dataset, model_fn, optimiser_fn,
          resume_from_latest_checkpoint=False, tag=None, freeze_model=False):

    # Hopefully the caller has already set the the graph-level random seed for
    # reproducibility.

    # Generate a unique name for this run. Used to name directories for
    # TensorBoard and stored checkpoints.
    this_session_name = datetime.now().strftime("%a-%d-%b-%I%M%p")
    if tag is not None:
        this_session_name = tag

    this_session_path = os.path.join(_DEFAULT_SESSIONS_PATH, this_session_name)
    os.makedirs(this_session_path)

    # Create a 'latest' symlink when necessary
    if len(os.listdir(_DEFAULT_SESSIONS_PATH)) > 1:
        make_symbolic_link(_DEFAULT_SESSIONS_PATH, this_session_name)

    SUMMARIES_PATH = os.path.join(this_session_path, 'summaries')
    TRAIN_CHECKPOINTS_PATH = os.path.join(
                this_session_path, 'train_checkpoints/train_checkpoint')
    BEST_VAL_CHECKPOINT_PATH = os.path.join(
                this_session_path, 'val_checkpoints/best_val_checkpoint')

    configure_logger(os.path.join(this_session_path, 'log.txt'))

    ###########################################################################
    # Placeholders
    ###########################################################################
    batch_images = tf.placeholder(
            tf.float32,
            [None, dataset.image_size, dataset.image_size, dataset.channels],
            'model_input')
    batch_labels = tf.placeholder(tf.float32, [None, dataset.num_classes])

    tf.summary.image('images', batch_images, max_outputs=6)

    is_training = tf.placeholder(tf.bool, name='is_training')
    keep_prob = tf.placeholder(tf.float32, name='keep_prob')

    ###########################################################################
    # The Model
    ###########################################################################
    model = model_fn(batch_images, dataset.num_classes, is_training, keep_prob)

    ###########################################################################
    # Accuracy
    ###########################################################################
    batch_top1_accuracy_op = compute_accuracy(batch_labels, model.output, 1)
    batch_top5_accuracy_op = compute_accuracy(batch_labels, model.output, 5)

    top1_mean_acc_ops = get_resettable_mean_metric(batch_top1_accuracy_op,
                                                   'val_top1_mean')
    top5_mean_acc_ops = get_resettable_mean_metric(batch_top5_accuracy_op,
                                                   'val_top5_mean')

    tf.summary.scalar('Top-1 Training Accuracy', batch_top1_accuracy_op)
    tf.summary.scalar('Top-5 Training Accuracy', batch_top5_accuracy_op)

    # Validation-related summaries are added to a separate collection so that
    # they can be evaluated at separate time from training summaries.
    tf.summary.scalar('Validation Top-1 Accuracy',
                      top1_mean_acc_ops['value_op'],
                      collections=['VALIDATION_SUMMARIES'])

    ###########################################################################
    # Optimiser
    ###########################################################################
    global_step_op = tf.train.create_global_step()
    steps_per_epoch = dataset.num_train_samples // batch_size

    train_op, total_loss_op = optimiser_fn(batch_labels, model.output)

    ###########################################################################
    # TensorBoard Summaries/Checkpoints
    ###########################################################################
    train_summary_op = tf.summary.merge_all()
    val_summary_op = tf.summary.merge_all('VALIDATION_SUMMARIES')

    train_chkpt_op = tf.train.Saver(max_to_keep=5, keep_checkpoint_every_n_hours=2)
    best_val_chkpt_op = tf.train.Saver(max_to_keep=1)

    ###########################################################################
    # Session
    ###########################################################################

    def evaluate(dataset_init_fn, dataset_select_fn):
        """A helper function used to compute accuracy on validation and
        training dataset. Ideally we'd like to do this in one go but often the
        entire validation set is too big to fit in memory and therefore we
        still need to use batches for validation as well.

        Args:

        Returns:
            Top 1% and Top 5% accuracies
        """
        dataset_init_fn(sess)
        sess.run([top1_mean_acc_ops['reset_op'],
                  top5_mean_acc_ops['reset_op']])

        while True:
            try:
                _, images, labels = sess.run(dataset.next_element,
                                             feed_dict=dataset_select_fn())

                sess.run([top1_mean_acc_ops['update_op'],
                          top5_mean_acc_ops['update_op']],
                         feed_dict={batch_images: images,
                                    batch_labels: labels,
                                    is_training: False,
                                    keep_prob: 1.0})

            except tf.errors.OutOfRangeError:
                top1, top5 = sess.run([top1_mean_acc_ops['value_op'],
                                       top5_mean_acc_ops['value_op']])
                break

        return top1, top5

    def main_training_loop(sess, starting_epoch, num_epochs):

        #################################
        #    The Actual Training Loop
        #################################
        summary_writer = tf.summary.FileWriter(SUMMARIES_PATH, sess.graph)

        dataset.evaluate_handles(sess)

        train_start_time = summary_start_time = datetime.now()
        logger.info('Training start time: {}'.format(train_start_time))

        current_step = starting_epoch * steps_per_epoch
        best_epoch = 0
        best_validation_acc = 0.0
        testing_acc = 0.0

        # TODO: Put these in the right place
        # --------8<----------
        epoch_loss = tf.Variable(0, trainable=False, dtype=tf.float32)
        update_epoch_loss = tf.assign_add(epoch_loss, total_loss_op)
        reset_epoch_loss = tf.variables_initializer([epoch_loss])
        tf.summary.scalar('Epoch Training Loss', epoch_loss, collections=['EPOCH_SUMMARIES'])
        epoch_summary_op = tf.summary.merge_all('EPOCH_SUMMARIES')
        # --------8<----------

        for epoch_num in range(starting_epoch, num_epochs):

            sess.run(reset_epoch_loss)

            for batch_num in range(steps_per_epoch):

                _, images, labels = sess.run(
                                dataset.next_element,
                                feed_dict=dataset.from_training_set())

                sess.run([train_op, update_epoch_loss], feed_dict={batch_images: images,
                                              batch_labels: labels,
                                              is_training: True,
                                              keep_prob: 0.5})

                if batch_num % _PRINT_SUMMARY_FREQ == 0:

                    top1, top5, batch_summary = sess.run(
                            [batch_top1_accuracy_op, batch_top5_accuracy_op,
                             train_summary_op],
                            feed_dict={batch_images: images,
                                       batch_labels: labels,
                                       is_training: False,
                                       keep_prob: 1.0})

                    logger.debug('time/step: {:.2f} ms'.
                                 format(time_per_step(summary_start_time,
                                                      _PRINT_SUMMARY_FREQ)))

                    logger.info(
                        '{} Epoch {:>3} - Batch {:>4} - '
                        'Batch accuracy: top-1 {:5.2f}% - top-5: {:5.2f}%'
                        .format(get_timedelta(train_start_time), epoch_num,
                                batch_num, top1, top5))

                    summary_writer.add_summary(batch_summary, current_step)
                    summary_start_time = datetime.now()

                current_step += 1

            ########################
            #     End of Epoch
            ########################
            train_chkpt_op.save(sess, TRAIN_CHECKPOINTS_PATH, global_step_op)

            # Evaluate accuracy on the validation dataset (and testing dataset
            # if observed validation is the best seen)
            val_acc, _ = evaluate(dataset.initialize_validation,
                                  dataset.from_validation_set)

            summary_writer.add_summary(sess.run(val_summary_op), current_step)
            summary_writer.add_summary(sess.run(epoch_summary_op), current_step)

            logger.info('Epoch training loss {} - Validation accuracy: top-1 {:5.2f}%'.format(
                    epoch_loss.eval(), val_acc))

            if val_acc > best_validation_acc:
                logger.info('New Best Validation!')

                best_validation_acc = val_acc
                best_epoch = epoch_num

                testing_acc, _ = evaluate(dataset.initialize_testing,
                                          dataset.from_testing_set)

                best_val_chkpt_op.save(sess, BEST_VAL_CHECKPOINT_PATH, global_step_op)

            logger.info(
                'Testing accuracy to report: {:5.2f}% (error: {:5.2f}%) - '
                'Seen in epoch {}'
                .format(testing_acc, 100.0 - testing_acc, best_epoch))

        ########################
        #   End of training!
        ########################
        total_train_time = datetime.now() - train_start_time

        logger.info('End of training! Overall training time: {}'
                    .format(total_train_time))

        logger.info('Best observed validation accuracy: {:5.2f}%'
                    .format(best_validation_acc))
        logger.info('Testing accuracy to report: {:5.2f}% (error: {:5.2f}%) - '
                    'Seen in epoch {}'
                    .format(testing_acc, 100-testing_acc, best_epoch))

        summary_writer.close()

        return testing_acc, best_epoch

    def _print_env_details():
        logger.info("=====================================")
        """ A helper function to print env details. """
        logger.info("Timestamp: {}".format(datetime.now()))
        logger.info("TensorFlow Version: {}".format(tf.VERSION))
        logger.info('Session Name: "{}"'.format(this_session_name))
        logger.info("Total number of trainable parameters: {:,}"
                    .format(get_num_trainable_params()))
        logger.info("{} Epochs - Batch Size {}".format(num_epochs, batch_size))
        logger.debug(pformat(globals()))
        logger.debug(pformat(locals()))
        logger.debug("All Trainable Parameters:")
        for var in tf.trainable_variables():
            logger.debug('{} {}'.format(var.name, var.shape))
        logger.info("=====================================")

    _print_env_details()

    with tf.Session() as sess:

        sess.run(tf.global_variables_initializer())

        if resume_from_latest_checkpoint:
            train_chkpt_op.restore(sess, find_latest_chkpt(_DEFAULT_SESSIONS_PATH))
            starting_epoch = global_step_op.eval() // steps_per_epoch
            # TODO: Restore best validation details
        else:
            starting_epoch = 0

        #######################################################################
        # Let's train!
        #######################################################################
        acc, best_epoch = main_training_loop(sess, starting_epoch, num_epochs)

        if freeze_model:
            logger.info("Feezing the model ...")
            save_frozen_model(sess, ['model_output'], this_session_path,
                              {'is_training': False})
            logger.info("Frozen model saved.")

        sess.close()

    TestResults = namedtuple('TestResults', ['session_name', 'accuracy',
                                             'best_epoch', 'trained_model'])

    return TestResults(this_session_name, acc, best_epoch, model)


import requests
from googletrans import Translator
import random

translator = Translator()

# Random API calls for now

def get_corona_stats(country):
    url = 'https://api.covid19api.com/total/country/' + country
    r = requests.get(url=url)

    data = r.json()

    cases = data[len(data)-1]

    confirmed = cases['Confirmed']
    recovered = cases['Recovered']
    deaths = cases['Deaths']

    return confirmed, recovered, deaths

def get_random_cat():
    url = 'https://api.thecatapi.com/v1/images/search'
    r = requests.get(url=url)

    cat_img =  r.json()[0]['url']
    return cat_img

def translate(text):
    return translator.translate(text, dest='en').text

def get_meme():
    url = 'https://api.imgflip.com/get_memes'
    r = requests.get(url=url)

    img_id = random.randint(0, len(r.json()['data']['memes']))
    return r.json()['data']['memes'][img_id]['url']

print(get_meme())


import os
import openai
import tiktoken

openai.api_key = os.getenv("OPENAI_API_KEY")

def get_sentiment(msg):
    """
    Get the sentiment from a text message

    parameters:
    msg (string): The text message

    returns:
    sentiment (string): The sentiment detected in the message
    """
    response = openai.Completion.create(
    model="text-davinci-003",
    prompt="Classify the sentiment in this messge: {}".format(msg),
    temperature=0,
    max_tokens=60,
    top_p=1.0,
    frequency_penalty=0.0,
    presence_penalty=0.0
    )

    # Transform response in dict
    r_dict = response.to_dict()

    # Get only the 'text' value
    sentiment = r_dict.get('choices')[0].get('text').replace('\n','')

    return sentiment

def write_feedback(msg):
    """
    Write a message to answer a given site feedback

    parameters:
    msg (string): The text message

    returns:
    feedback (string): The feedback message to post
    """
    response = openai.Completion.create(
    model="text-davinci-003",
    prompt="Evaluate the sentiment and the message idiom and reply with a kindly message with a follow-up question if the sentiment is negative. If positive, just reply  only with a kindly message: {}".format(msg),
    temperature=0,
    max_tokens=180,
    top_p=1.0,
    frequency_penalty=0.0,
    presence_penalty=0.0
    )

    # Transform response in dict
    r_dict = response.to_dict()

    # Get only the 'text' value
    feedback = r_dict.get('choices')[0].get('text').replace('\n','')

    return feedback

def summarize(text):
    """
    Summarizes the provided text using the text-davinci-003 language model from OpenAI.

    Args:
    text (str): The text to be summarized.

    Returns:
    response (object): The response object containing the summary generated by the model.
    """
    tokens = get_tokens(text)
    print("Tokens: {}".format(tokens.nb_tokens))
    response = openai.Completion.create(
    model="text-davinci-003",
    prompt=f"Sumariza a reclamação a seguir para um responsável da qualidade do atendimento. Se houver menção da qualidade do atendimento customer care, também referir : {text} ",
    temperature=1,
    max_tokens=tokens.nb_tokens,
      top_p=1.0,
    frequency_penalty=0.0,
    presence_penalty=0.0
    )
    return response

def get_tokens(text,enc_name="p50k_base"):
    """
    Returns a class object containing information about the tokens generated from the provided text.

    Args:
    text (str): The text for which tokens will be generated.
    enc_name (str, optional): The name of the encoding scheme to be used. Defaults to "p50k_base".

    Returns:
    token_class (object): A class object containing information about the generated tokens.
    """
    encoding = tiktoken.get_encoding(enc_name)
    token_integers = encoding.encode(text)
    nb_tokens = len(token_integers)
    token_bytes = [encoding.decode_single_token_bytes(token) for token in token_integers]
    tokens = {"nb_tokens": nb_tokens, "token_bytes": token_bytes, "token_integers": token_integers}
    token_class = type("tokens", (), tokens)

    return token_class


import json
import logging
from typing import Any, Dict, List, Optional

import click

from aws_orbit import utils
from aws_orbit.messages import print_list, stylize
from aws_orbit.models.context import Context, ContextSerDe

_logger: logging.Logger = logging.getLogger(__name__)

def list_images(env: str, region: Optional[str]) -> None:
    context: "Context" = ContextSerDe.load_context_from_ssm(env_name=env, type=Context)
    names = utils.extract_images_names(env_name=env)
    if names:
        print_list(
            tittle=f"Available docker images into the {stylize(context.name)} env:",
            items=[k for k in names],
        )
    else:
        click.echo(f"There is no docker image(s) into the {stylize(context.name)} env.")

def list_env(env: str, variable: str) -> None:
    ssm = utils.boto3_client("ssm")
    res = ssm.get_parameters_by_path(Path="/orbit", Recursive=True)
    env_info: Dict[str, Any] = {}
    if env and len(env) > 0:
        _logger.debug(f"looking for {env}")
    while True:
        params = res["Parameters"]
        for p in params:
            if not p["Name"].endswith("context") or "teams" in p["Name"]:
                continue
            env_name = p["Name"].split("/")[2]
            if len(env) > 0 and not env_name == env:
                continue
            env_name = p["Name"].split("/")[2]
            context: "Context" = ContextSerDe.load_context_from_ssm(env_name=env_name, type=Context)
            _logger.debug(f"found env: {env_name}")
            if len(context.teams) > 0:
                teams_list: List[str] = [x.name for x in context.teams]
            else:
                teams_list = []

            if variable == "landing-page":
                print(context.landing_page_url)
            elif variable == "toolkitbucket":
                print(context.toolkit.s3_bucket)
            elif variable == "all":
                env_info[env_name] = {
                    "LandingPage": f"{context.landing_page_url}/orbit/login",
                    "Teams": teams_list,
                    "ToolkitBucket": context.toolkit.s3_bucket,
                }
            else:
                raise Exception(f"Unknown --variable option {variable}")

        if "NextToken" in res:
            res = ssm.get_parameters_by_path(Path="/orbit", Recursive=True, NextToken=res["NextToken"])
        else:
            break

    if variable == "all":
        if len(env_info) == 0:
            click.echo("There are no Orbit environments available")
            return
        else:
            print("Available Orbit environments:")
            print(json.dumps(env_info, indent=4, sort_keys=True))


from django.urls import path

from . import views

app_name = "login"

urlpatterns = [
    path("", views.login, name="login"),
    path("auth/", views.authenticate_user, name="auth"),
    path("signup/", views.signup, name="signup"),
    path("register/", views.register_user, name="register"),
]


"""
      ***Logging***:
Logging is a means of tracking events that happen when some software runs.
Logging is important for software developing, debugging and running.
If you don’t have any logging record and your program crashes,
there are very little chances that you detect the cause of the problem.
And if you detect the cause, it will consume a lot of time

"""

"""
In its simplest term, the `logging` module is used to print things out
(to the console or to a file).

The `logging` module should be used to communicate with the developer
(e.g. information about what’s happening; when an error happens; a critical problem; etc…).

To communicate with the user, continue using `print()` and `input()`.

To use logging, we just have to import the `logging` module and get a new logger:

"""

"""

There are various logging levels (below in ascending order of criticality),
for you to use depending on the circumstance:

DEBUG
INFO
WARNING
ERROR
CRITICAL

So if you’re logging for help while developing or debugging,
use the `DEBUG` level (`logger.debug('message')`).

If your program’s about to crash because a critical exception happened;
use `logger.critical()`.
"""

"""
import logging
logger = logging.getLogger('test_logger')
logger.info("Everything is Fine")
logging.basicConfig(level=logging.DEBUG)
logging.basicConfig(level=logging.INFO)

logger.debug('Serious Issue')
logger.info("Everything is Fine")

logger.setLevel(logging.CRITICAL)
logger.critical('Internet Is Down')

"""

import logging
logging.basicConfig(
    format='%(asctime)s %(levelname)-8s [%(filename)s:%(lineno)d] %(message)s',
    datefmt='%d-%m-%Y %H:%M:%S',
    level=logging.DEBUG
)

logger = logging.getLogger()

logger.info('This Is Info Log')
logger.debug('This is Debug Log')
logger.critical('This is Critical Log')
logger.error('An Error Occurred')
logger.warning('This Is Warning Log')

Advance Python Developement/logging in python.py


from pytube import YouTube

vid = YouTube("https://www.youtube.com/watch?v=v3UBlEJDXR0")

title = vid.title

print("You will now be downloading: " + title)
#vid.streams.filter(progressive=True)

#vid.download(output_path = r"c:\Users\kev1n\Downloads", filename = title)


import os
import json

from scripts.artifact_report import ArtifactHtmlReport
from scripts.lleapfuncs import logfunc, tsv, get_next_unused_name

def get_mdadm(files_found, report_folder, seeker, wrap_text):

    data_list = []
    data_headers = ['array', 'device_name', 'sourcefile']
    for file_found in files_found:
        file_found = str(file_found)
        with open(file_found, 'r', encoding='utf-8') as f:
            lines = f.readlines()
            for line in lines:
                temp_data_list = []
                if 'ARRAY ' in line:
                    array_list = line.split()
                    # Pop the first 2 entries off as they should alwasy be the same
                    temp_data_list.append(array_list.pop(0))
                    temp_data_list.append(array_list.pop(0))
                    for item in array_list:
                        item_list = item.split("=")
                        if item_list[0] in data_headers:
                            col_num = data_headers.index(item_list[0])
                            temp_data_list.insert(col_num, item_list[1])
                        else:
                            data_headers.append(item_list[0])
                            col_num = data_headers.index(item_list[0])
                            temp_data_list.insert(col_num, item_list[1])
                temp_data_list.append(file_found)
                data_list.append(temp_data_list)

    usageentries = len(data_list)
    if usageentries > 0:
        report = ArtifactHtmlReport(f'mdadm arrays')
        #check for existing and get next name for report file, so report from another file does not get overwritten
        report_path = os.path.join(report_folder, f'mdadm_arrays.temphtml')
        report_path = get_next_unused_name(report_path)[:-9] # remove .temphtml
        report.start_artifact_report(report_folder, os.path.basename(report_path))
        report.add_script()

        report.write_artifact_data_table(data_headers, data_list, file_found)
        report.end_artifact_report()

        tsvname = f'mdadm_arrays'
        tsv(report_folder, data_headers, data_list, tsvname)

    else:
        logfunc(f'No mdadm arrays data available')

__artifacts__ = {
        "mdadm": (
                "Raids",
                ('**/etc/mdadm/mdadm.conf'),
                get_mdadm)
}


#!/usr/bin/env python

# Space Invaders
# Created by Lee Robinson

from pygame import *
import sys
from os.path import abspath, dirname
from random import choice
import numpy as np
from enum import Enum

from model.circuit_grid_model import CircuitGridModel
from controls.circuit_grid import CircuitGrid, CircuitGridNode
from copy import deepcopy

from utils.navigation import MOVE_UP, MOVE_DOWN, MOVE_LEFT, MOVE_RIGHT
from utils.parameters import WIDTH_UNIT, WINDOW_HEIGHT, WINDOW_WIDTH, \
    LEFT, RIGHT, NOTHING, NO, YES, MEASURE_LEFT, MEASURE_RIGHT, WINDOW_SIZE
from qiskit import BasicAer, execute, ClassicalRegister

BASE_PATH = abspath(dirname(__file__))
FONT_PATH = BASE_PATH + '/fonts/'
IMAGE_PATH = BASE_PATH + '/images/'
SOUND_PATH = BASE_PATH + '/sounds/'

# Colors (R, G, B)
WHITE = (255, 255, 255)
GREEN = (78, 255, 87)
YELLOW = (241, 255, 0)
BLUE = (80, 255, 239)
PURPLE = (203, 0, 255)
RED = (237, 28, 36)

#SCREEN_HEIGHT = 640
SCREEN_HEIGHT = 300
SCREEN = display.set_mode((800, 640))
#screen = display.set_mode(WINDOW_SIZE)
FONT = FONT_PATH + 'space_invaders.ttf'
IMG_NAMES = ['ship', 'mystery',
             'enemy1_1', 'enemy1_2',
             'enemy2_1', 'enemy2_2',
             'enemy3_1', 'enemy3_2',
             'explosionblue', 'explosiongreen', 'explosionpurple',
             'laser', 'enemylaser']
IMAGES = {name: image.load(IMAGE_PATH + '{}.png'.format(name)).convert_alpha()
          for name in IMG_NAMES}
POSITIONS = [20, 120, 220, 320, 420, 520, 620, 720]
# OFFSETS = [-100, 0, -200, 100, -300, 200, -400, 300]
OFFSETS = [-400, -300, -200, -100, 0, 100, 200, 300]
DISTRIBUTIONS = [25.0, 25.0, 15.0, 15.0, 7.0, 7.0, 3.0, 3.0]
LABEL_TEXT = ["|000>", "|001>", "|010>", "|011>", "|100>", "|101>", "|110>", "|111>"]

NUMBER_OF_SHIPS = 8

BLOCKERS_POSITION = 450
ENEMY_DEFAULT_POSITION = 65  # Initial value for a new game
ENEMY_MOVE_DOWN = 35
ENEMY_HEALTH = 96

BULLET_MAX_DAMAGE = 96

class ShipState(Enum):
    SUPERPOSITION = 0
    MEASURED = 1

class Ship(sprite.Sprite):
    def __init__(self, id):
        sprite.Sprite.__init__(self)
        self.id = id
        self.probability = DISTRIBUTIONS[id] / 100.0
        self.image = IMAGES['ship'].copy()
        self.image.fill((255, 255, 255, self.probability * 500), None, BLEND_RGBA_MULT)
        self.speed = 5
        self.rect = self.image.get_rect(topleft=(POSITIONS[self.id], 540))
        self.classical = False

    def update(self, *args):
        self.update_opacity(self.probability)
        game.screen.blit(self.image, self.rect)

    def fire(self, measuring, measured_ship):
        if measuring:
            if self is measured_ship:
                bullet = Bullet(self.rect.x + 23,
                                self.rect.y + 5, -1,
                                15, 'laser', 'center', 1.0)
                game.bullets.add(bullet)
                game.allSprites.add(game.bullets)
                game.sounds['shoot'].play()

        else:
            bullet = Bullet(self.rect.x + 23,
                            self.rect.y + 5, -1,
                            15, 'laser', 'center', self.probability)
            game.bullets.add(bullet)
            game.allSprites.add(game.bullets)
            game.sounds['shoot'].play()

    def update_opacity(self, prob):
        self.image = IMAGES['ship'].copy()
        opacity = 0
        if self.classical:
            opacity = 1
        else:
            if prob > 0.75:
                opacity = 1
            elif prob > 0.5:
                opacity = 0.8
            elif prob > 0.25:
                opacity = 0.6
            elif prob > 0.1:
                opacity = 0.35
        self.image.fill((255, 255, 255, opacity * 255), None, BLEND_RGBA_MULT)

class ShipGroup(sprite.Group):
    def __init__(self, number_of_ships, position):
        sprite.Group.__init__(self)
        self.ships = [None] * number_of_ships
        self.number_of_ships = number_of_ships
        self.position = position
        self.measured_ship = None
        self.measuring = False
        self.timer = 0.0
        self.state = ShipState.SUPERPOSITION

    def update(self, keys, *args):
        passed = time.get_ticks() - self.timer
        if self.measuring and passed > 600:
            self.measuring = False

        for ship in self:
            if self.state == ShipState.SUPERPOSITION:
                ship.classical = False
                ship.rect.x = (OFFSETS[ship.id] + POSITIONS[self.position]) % 800
            elif self.state == ShipState.MEASURED:
                if ship == self.measured_ship:
                    ship.classical = True
                    ship.rect.x = (OFFSETS[ship.id] + POSITIONS[self.position]) % 800
                else:
                    ship.rect.x = 999999999
            ship.update_opacity(ship.probability)
            ship.update()

    def add_internal(self, *sprites):
        super(ShipGroup, self).add_internal(*sprites)
        for s in sprites:
            self.ships[s.id] = s

    def remove_internal(self, *sprites):
        super(ShipGroup, self).remove_internal(*sprites)
        for s in sprites:
            self.kill(s)

    def fire(self):
        for ship in self:
            ship.fire(self.state == ShipState.MEASURED, self.measured_ship)

    def kill(self, ship):
        self.ships[ship.id] = None

    def explode_ships(self, explosionsGroup, measured_ship_id):
        for ship in self.ships:
            if ship is not None:
                if ship.id == measured_ship_id:
                    ship.update_opacity(1.0)
                    ship.update()
                    self.measured_ship = ship
                else:
                    ship.kill()

                # ShipExplosion(ship, sprite.Group())

    def update_probabilities(self, probabilities):
        for ship in self:
            p_amp = probabilities[ship.id]
            ship.probability = p_amp.real*p_amp.real + p_amp.imag*p_amp.imag
            ship.update_opacity(ship.probability)

    def measure(self, measured_ship_id):
        for ship in self.ships:
            if ship is not None:
                if ship.id == measured_ship_id:
                    self.measured_ship = ship
        self.measuring = True
        self.timer = time.get_ticks()
        self.state = ShipState.MEASURED
        self.update([])

    def draw(self, screen):
        for ship in self.ships:
            if ship is not None and ship is Ship:
                text = Text(FONT, 50, '000', WHITE, 50, 50)
                text.draw(screen)

class Bullet(sprite.Sprite):
    def __init__(self, xpos, ypos, direction, speed, filename, side, multiplier=1.0):
        sprite.Sprite.__init__(self)
        self.image = IMAGES[filename]
        self.rect = self.image.get_rect(topleft=(xpos, ypos))
        self.speed = speed
        self.direction = direction
        self.side = side
        self.filename = filename
        self.multiplier = multiplier
        self.damage = BULLET_MAX_DAMAGE * multiplier + 1  # accounting for floating point issue

    def update(self, keys, *args):
        self.image = IMAGES[self.filename].copy()
        alpha = 0
        if self.multiplier > 0.01: # if alpha is above 0 basically
            alpha = max(self.multiplier * 255, 128)
        self.image.fill((255, 255, 255, alpha), None, BLEND_RGBA_MULT)
        game.screen.blit(self.image, self.rect)
        self.rect.y += self.speed * self.direction
        if self.rect.y < 15 or self.rect.y > 650:
            self.kill()

class Enemy(sprite.Sprite):
    def __init__(self, row, column):
        sprite.Sprite.__init__(self)
        self.row = row
        self.column = column
        self.images = []
        self.load_images()
        self.index = 0
        self.image = self.images[self.index]
        self.rect = self.image.get_rect()
        self.health = ENEMY_HEALTH

    def toggle_image(self):
        self.index = (self.index + 1) % len(self.images)
        self.image = self.images[self.index]

    def update(self, *args):
        self.image = self.images[self.index].copy()
        alpha = max(255 * self.health / ENEMY_HEALTH, 50)
        self.image.fill((255, 255, 255, alpha), None, BLEND_RGBA_MULT)
        game.screen.blit(self.image, self.rect)

    def load_images(self):
        images = {0: ['1_2', '1_1'],
                  1: ['2_2', '2_1'],
                  2: ['2_2', '2_1'],
                  3: ['3_1', '3_2'],
                  4: ['3_1', '3_2'],
                  }
        img1, img2 = (IMAGES['enemy{}'.format(img_num)] for img_num in
                      images[self.row])
        self.images.append(transform.scale(img1, (40, 35)))
        self.images.append(transform.scale(img2, (40, 35)))

class EnemiesGroup(sprite.Group):
    def __init__(self, columns, rows):
        sprite.Group.__init__(self)
        self.enemies = [[None] * columns for _ in range(rows)]
        self.columns = columns
        self.rows = rows
        self.leftAddMove = 0
        self.rightAddMove = 0
        self.moveTime = 600
        self.direction = 1
        self.rightMoves = 30
        self.leftMoves = 30
        self.moveNumber = 15
        self.timer = time.get_ticks()
        self.bottom = game.enemyPosition + ((rows - 1) * 45) + 35
        self._aliveColumns = list(range(columns))
        self._leftAliveColumn = 0
        self._rightAliveColumn = columns - 1

    def update(self, current_time):
        if current_time - self.timer > self.moveTime:
            if self.direction == 1:
                max_move = self.rightMoves + self.rightAddMove
            else:
                max_move = self.leftMoves + self.leftAddMove

            if self.moveNumber >= max_move:
                self.leftMoves = 30 + self.rightAddMove
                self.rightMoves = 30 + self.leftAddMove
                self.direction *= -1
                self.moveNumber = 0
                self.bottom = 0
                for enemy in self:
                    enemy.rect.y += ENEMY_MOVE_DOWN
                    enemy.toggle_image()
                    if self.bottom < enemy.rect.y + 35:
                        self.bottom = enemy.rect.y + 35
            else:
                velocity = 10 if self.direction == 1 else -10
                for enemy in self:
                    enemy.rect.x += velocity
                    enemy.toggle_image()
                self.moveNumber += 1

            self.timer = current_time + self.moveTime

    def add_internal(self, *sprites):
        super(EnemiesGroup, self).add_internal(*sprites)
        for s in sprites:
            self.enemies[s.row][s.column] = s

    def remove_internal(self, *sprites):
        super(EnemiesGroup, self).remove_internal(*sprites)
        for s in sprites:
            self.kill(s)
        self.update_speed()

    def is_column_dead(self, column):
        return not any(self.enemies[row][column]
                       for row in range(self.rows))

    def random_bottom(self):
        col = choice(self._aliveColumns)
        col_enemies = (self.enemies[row - 1][col]
                       for row in range(self.rows, 0, -1))
        return next((en for en in col_enemies if en is not None), None)

    def update_speed(self):
        if len(self) == 1:
            self.moveTime = 200
        elif len(self) <= 10:
            self.moveTime = 400

    def kill(self, enemy):
        self.enemies[enemy.row][enemy.column] = None
        is_column_dead = self.is_column_dead(enemy.column)
        if is_column_dead:
            self._aliveColumns.remove(enemy.column)

        if enemy.column == self._rightAliveColumn:
            while self._rightAliveColumn > 0 and is_column_dead:
                self._rightAliveColumn -= 1
                self.rightAddMove += 5
                is_column_dead = self.is_column_dead(self._rightAliveColumn)

        elif enemy.column == self._leftAliveColumn:
            while self._leftAliveColumn < self.columns and is_column_dead:
                self._leftAliveColumn += 1
                self.leftAddMove += 5
                is_column_dead = self.is_column_dead(self._leftAliveColumn)

class Blocker(sprite.Sprite):
    def __init__(self, size, color, row, column):
        sprite.Sprite.__init__(self)
        self.height = size
        self.width = size
        self.color = color
        self.image = Surface((self.width, self.height))
        self.image.fill(self.color)
        self.rect = self.image.get_rect()
        self.row = row
        self.column = column

    def update(self, keys, *args):
        game.screen.blit(self.image, self.rect)

class Mystery(sprite.Sprite):
    def __init__(self):
        sprite.Sprite.__init__(self)
        self.image = IMAGES['mystery']
        self.image = transform.scale(self.image, (75, 35))
        self.rect = self.image.get_rect(topleft=(-80, 45))
        self.row = 5
        self.moveTime = 25000
        self.direction = 1
        self.timer = time.get_ticks()
        self.mysteryEntered = mixer.Sound(SOUND_PATH + 'mysteryentered.wav')
        self.mysteryEntered.set_volume(0.3)
        self.playSound = True

    def update(self, keys, currentTime, *args):
        resetTimer = False
        passed = currentTime - self.timer
        if passed > self.moveTime:
            if (self.rect.x < 0 or self.rect.x > 800) and self.playSound:
                self.mysteryEntered.play()
                self.playSound = False
            if self.rect.x < 840 and self.direction == 1:
                self.mysteryEntered.fadeout(4000)
                self.rect.x += 2
                game.screen.blit(self.image, self.rect)
            if self.rect.x > -100 and self.direction == -1:
                self.mysteryEntered.fadeout(4000)
                self.rect.x -= 2
                game.screen.blit(self.image, self.rect)

        if self.rect.x > 830:
            self.playSound = True
            self.direction = -1
            resetTimer = True
        if self.rect.x < -90:
            self.playSound = True
            self.direction = 1
            resetTimer = True
        if passed > self.moveTime and resetTimer:
            self.timer = currentTime

class EnemyExplosion(sprite.Sprite):
    def __init__(self, enemy, *groups):
        super(EnemyExplosion, self).__init__(*groups)
        self.image = transform.scale(self.get_image(enemy.row), (40, 35))
        self.image2 = transform.scale(self.get_image(enemy.row), (50, 45))
        self.rect = self.image.get_rect(topleft=(enemy.rect.x, enemy.rect.y))
        self.timer = time.get_ticks()

    @staticmethod
    def get_image(row):
        img_colors = ['purple', 'blue', 'blue', 'green', 'green']
        return IMAGES['explosion{}'.format(img_colors[row])]

    def update(self, current_time, *args):
        passed = current_time - self.timer
        if passed <= 100:
            game.screen.blit(self.image, self.rect)
        elif passed <= 200:
            game.screen.blit(self.image2, (self.rect.x - 6, self.rect.y - 6))
        elif 400 < passed:
            self.kill()

class MysteryExplosion(sprite.Sprite):
    def __init__(self, mystery, score, *groups):
        super(MysteryExplosion, self).__init__(*groups)
        self.text = Text(FONT, 20, str(score), WHITE,
                         mystery.rect.x + 20, mystery.rect.y + 6)
        self.timer = time.get_ticks()

    def update(self, current_time, *args):
        passed = current_time - self.timer
        if passed <= 200 or 400 < passed <= 600:
            self.text.draw(game.screen)
        elif 600 < passed:
            self.kill()

class ShipExplosion(sprite.Sprite):
    def __init__(self, ship, *groups):
        super(ShipExplosion, self).__init__(*groups)
        self.image = IMAGES['ship']
        self.rect = self.image.get_rect(topleft=(ship.rect.x, ship.rect.y))
        self.timer = time.get_ticks()

    def update(self, current_time, *args):
        passed = current_time - self.timer
        if 300 < passed <= 600:
            game.screen.blit(self.image, self.rect)
        elif 900 < passed:
            self.kill()

class Life(sprite.Sprite):
    def __init__(self, xpos, ypos):
        sprite.Sprite.__init__(self)
        self.image = IMAGES['ship']
        self.image = transform.scale(self.image, (23, 23))
        self.rect = self.image.get_rect(topleft=(xpos, ypos))

    def update(self, *args):
        game.screen.blit(self.image, self.rect)

class Text(object):
    def __init__(self, textFont, size, message, color, xpos, ypos):
        self.font = font.Font(textFont, size)
        self.surface = self.font.render(message, True, color)
        self.rect = self.surface.get_rect(topleft=(xpos, ypos))

    def draw(self, surface):
        surface.blit(self.surface, self.rect)

class Labels(object):
    def __init__(self):
        self.labels = []

    def initialize(self, position):
        self.labels = []
        for i in range(8):
            self.labels.append(Text(FONT, 20, LABEL_TEXT[i], WHITE, POSITIONS[position] + OFFSETS[i], 600))

    def update(self, screen, position):
        for i in range(len(self.labels)):
            self.labels[i].rect = self.labels[i].surface.get_rect(topleft=((POSITIONS[position] + OFFSETS[i]) % 800, 600))
        for label in self.labels:
            label.draw(screen)
"""
class PauseBar(sprite.Sprite):
    def __init__(self, mystery, score, *groups):
        self.readytext = Text(FONT, 20, "QUANTUM READY", WHITE,
                         400, 0)
        self.text = Text(FONT, 20, "QUANTUM NOT READY", RED,
                         400, 0)
        self.timer = time.get_ticks()
        self.ready = False

    def update(self, current_time, *args):
        passed = current_time - self.timer
        if passed <= 600:
            self.text.draw(game.screen)
        elif 600 > passed:
            self.readytext.draw(game.screen)
            self.ready = True
            self.timer = currentTime

    def reset():
        self.ready = False
"""

class SpaceInvaders(object):
    def __init__(self):
        # It seems, in Linux buffersize=512 is not enough, use 4096 to prevent:
        #   ALSA lib pcm.c:7963:(snd_pcm_recover) underrun occurred
        mixer.pre_init(44100, -16, 1, 4096)
        init()
        self.clock = time.Clock()
        self.caption = display.set_caption('Space Invaders')
        self.screen = SCREEN
        self.background = image.load(IMAGE_PATH + 'qiskit.png').convert()
        self.startGame = False
        self.mainScreen = True
        self.gameOver = False
        # Counter for enemy starting position (increased each new round)
        self.enemyPosition = ENEMY_DEFAULT_POSITION
        self.titleText = Text(FONT, 50, 'Space Invaders', WHITE, 164, 155)
        self.titleText2 = Text(FONT, 25, 'Press any key to continue', WHITE,
                               201, 225)
        self.pauseText = Text(FONT, 42, 'Quantum Circuit Composer', WHITE, 50, 155)
        self.pauseText2 = Text(FONT, 25, 'Press ENTER key to continue', WHITE,
                               164, 225)
        self.gameOverText = Text(FONT, 50, 'Game Over', WHITE, 250, 270)
        self.nextRoundText = Text(FONT, 50, 'Next Round', WHITE, 240, 270)
        self.enemy1Text = Text(FONT, 25, '   =   10 pts', GREEN, 368, 270)
        self.enemy2Text = Text(FONT, 25, '   =  20 pts', BLUE, 368, 320)
        self.enemy3Text = Text(FONT, 25, '   =  30 pts', PURPLE, 368, 370)
        self.enemy4Text = Text(FONT, 25, '   =  ?????', RED, 368, 420)
        self.scoreText = Text(FONT, 20, 'Score', WHITE, 5, 5)
        self.livesText = Text(FONT, 20, 'Lives ', WHITE, 640, 5)

        self.life1 = Life(715, 3)
        self.life2 = Life(742, 3)
        self.life3 = Life(769, 3)
        self.livesGroup = sprite.Group(self.life1, self.life2, self.life3)

        self.shipPosition = 4

        self.circuit_grid_model = CircuitGridModel(3, 10)
        self.circuit_grid = CircuitGrid(0, SCREEN_HEIGHT , self.circuit_grid_model)
        self.paused = False
        #self.pause_bar = 0
        #self.pause_ready = False
        #self.pause_increment_time = 50

        self.labels = Labels()
        #self.pause_bar = PauseBar()

    def reset(self, score):
        self.player = ShipGroup(NUMBER_OF_SHIPS, self.shipPosition)
        self.make_ships()
        self.labels.initialize(self.player.position)
        self.playerGroup = sprite.Group(self.player)
        self.explosionsGroup = sprite.Group()
        self.bullets = sprite.Group()
        self.mysteryShip = Mystery()
        self.mysteryGroup = sprite.Group(self.mysteryShip)
        self.enemyBullets = sprite.Group()
        self.make_enemies()
        self.allSprites = sprite.Group(self.player, self.enemies,
                                       self.livesGroup, self.mysteryShip)
        self.keys = key.get_pressed()

        self.timer = time.get_ticks()
        self.noteTimer = time.get_ticks()
        self.shipTimer = time.get_ticks()
        self.score = score
        self.create_audio()
        self.makeNewShip = False
        self.shipAlive = True

    def make_blockers(self, number):
        blockerGroup = sprite.Group()
        for row in range(4):
            for column in range(9):
                blocker = Blocker(10, GREEN, row, column)
                blocker.rect.x = 50 + (200 * number) + (column * blocker.width)
                blocker.rect.y = BLOCKERS_POSITION + (row * blocker.height)
                blockerGroup.add(blocker)
        return blockerGroup

    def create_audio(self):
        mixer.init(48000, -16, 1, 1024)
        mixer.music.load('sounds/SG.mp3')
        mixer.music.play()
        mixer.music.set_volume(0.35)
        self.sounds = {}
        for sound_name in ['shoot', 'shoot2', 'invaderkilled', 'mysterykilled',
                           'shipexplosion']:
            self.sounds[sound_name] = mixer.Sound(
                SOUND_PATH + '{}.wav'.format(sound_name))
            self.sounds[sound_name].set_volume(0.2)

        self.musicNotes = [mixer.Sound(SOUND_PATH + '{}.wav'.format(i)) for i
                           in range(4)]
        for sound in self.musicNotes:
            sound.set_volume(0.5)

        self.noteIndex = 0

    def play_main_music(self, currentTime):
        if currentTime - self.noteTimer > self.enemies.moveTime:
            self.note = self.musicNotes[self.noteIndex]
            if self.noteIndex < 3:
                self.noteIndex += 1
            else:
                self.noteIndex = 0

            self.note.play()
            self.noteTimer += self.enemies.moveTime

    @staticmethod
    def should_exit(evt):
        # type: (pygame.event.EventType) -> bool
        return evt.type == QUIT or (evt.type == KEYUP and evt.key == K_ESCAPE)

    def get_probability_amplitudes(self, circuit, qubit_num, shot_num):
        backend_sv_sim = BasicAer.get_backend('statevector_simulator')
        job_sim = execute(circuit, backend_sv_sim, shots=shot_num)
        result_sim = job_sim.result()
        quantum_state = result_sim.get_statevector(circuit, decimals=3)
        return quantum_state

    def get_measurement(self, circuit, qubit_num, shot_num):
        backend_sv_sim = BasicAer.get_backend('qasm_simulator')
        cr = ClassicalRegister(qubit_num)
        measure_circuit = deepcopy(circuit)  # make a copy of circuit
        measure_circuit.add_register(cr)    # add classical registers for measurement readout
        measure_circuit.measure(measure_circuit.qregs[0], measure_circuit.cregs[0])
        job_sim = execute(measure_circuit, backend_sv_sim, shots=shot_num)
        result_sim = job_sim.result()
        counts = result_sim.get_counts(circuit)
        return int(list(counts.keys())[0], 2)

    def check_input(self):
        self.keys = key.get_pressed()
        for e in event.get():
            if self.should_exit(e):
                sys.exit()
            """
            if e.type == KEYDOWN:
                if e.key == K_SPACE:
                    if len(self.bullets) == 0 and self.shipAlive:
                        if self.score < 1000:
                            self.player.fire()
                            # bullet = Bullet(self.player.rect.x + 23,
                            #                 self.player.rect.y + 5, -1,
                            #                 15, 'laser', 'center')
                            # self.bullets.add(bullet)
                            # self.allSprites.add(self.bullets)
                            # self.sounds['shoot'].play()
                        # else:
                        #     leftbullet = Bullet(self.player.rect.x + 8,
                        #                         self.player.rect.y + 5, -1,
                        #                         15, 'laser', 'left')
                        #     rightbullet = Bullet(self.player.rect.x + 38,
                        #                          self.player.rect.y + 5, -1,
                        #                          15, 'laser', 'right')
                        #     self.bullets.add(leftbullet)
                        #     self.bullets.add(rightbullet)
                        #     self.allSprites.add(self.bullets)
                        #     self.sounds['shoot2'].play()

            """
            if e.type == KEYDOWN:
                if e.key == K_ESCAPE:
                    self.running = False
                elif e.key == K_RETURN:
                    self.paused = not(self.paused)
                elif not self.paused:
                    if e.key == K_SPACE:
                        if len(self.bullets) == 0 and self.shipAlive:
                            self.player.fire()
                    elif e.key == K_o:
                        self.player.state = ShipState.SUPERPOSITION
                        if self.player.position >= 0:
                            self.player.position = (self.player.position - 1) % 8
                            self.player.update(self.keys)
                    elif e.key == K_p:
                        self.player.state = ShipState.SUPERPOSITION
                        if self.player.position <= 7:
                            self.player.position = (self.player.position + 1) % 8
                            self.player.update(self.keys)
                else:
                    if e.key == K_a:
                        self.circuit_grid.move_to_adjacent_node(MOVE_LEFT)
                    elif e.key == K_d:
                        self.circuit_grid.move_to_adjacent_node(MOVE_RIGHT)
                    elif e.key == K_w:
                        self.circuit_grid.move_to_adjacent_node(MOVE_UP)
                    elif e.key == K_s:
                        self.circuit_grid.move_to_adjacent_node(MOVE_DOWN)
                    elif e.key == K_x:
                        self.circuit_grid.handle_input_x()
                    elif e.key == K_y:
                        self.circuit_grid.handle_input_y()
                    elif e.key == K_z:
                        self.circuit_grid.handle_input_z()
                    elif e.key == K_h:
                        self.circuit_grid.handle_input_h()
                    elif e.key == K_BACKSPACE:
                        self.circuit_grid.handle_input_delete()
                    elif e.key == K_c:
                        # Add or remove a control
                        self.circuit_grid.handle_input_ctrl()
                    elif e.key == K_UP:
                        # Move a control qubit up
                        self.circuit_grid.handle_input_move_ctrl(MOVE_UP)
                    elif e.key == K_DOWN:
                        # Move a control qubit down
                        self.circuit_grid.handle_input_move_ctrl(MOVE_DOWN)
                    elif e.key == K_LEFT:
                        # Rotate a gate
                        self.circuit_grid.handle_input_rotate(-np.pi / 8)
                    elif e.key == K_RIGHT:
                        # Rotate a gate
                        self.circuit_grid.handle_input_rotate(np.pi / 8)
                    circuit = self.circuit_grid.circuit_grid_model.compute_circuit()
                    state = self.get_probability_amplitudes(circuit, 3, 100)
                    self.player.update_probabilities(state)
                    self.circuit_grid.draw(self.screen)
                    self.player.update(self.keys)
                    display.flip()

    def make_enemies(self):
        enemies = EnemiesGroup(10, 5)
        for row in range(5):
            for column in range(10):
                enemy = Enemy(row, column)
                enemy.rect.x = 157 + (column * 50)
                enemy.rect.y = self.enemyPosition + (row * 45)
                enemies.add(enemy)

        self.enemies = enemies

    def make_ships(self):
        ships = ShipGroup(NUMBER_OF_SHIPS, self.shipPosition)
        for i in range(NUMBER_OF_SHIPS):
            ship = Ship(i)
            ships.add(ship)
        ships.update([])
        self.player = ships
        circuit = self.circuit_grid.circuit_grid_model.compute_circuit()
        state = self.get_probability_amplitudes(circuit, 3, 100)
        self.player.update_probabilities(state)

    def make_enemies_shoot(self):
        if (time.get_ticks() - self.timer) > 700 and self.enemies:
            enemy = self.enemies.random_bottom()
            self.enemyBullets.add(
                Bullet(enemy.rect.x + 14, enemy.rect.y + 20, 1, 5,
                       'enemylaser', 'center'))
            self.allSprites.add(self.enemyBullets)
            self.timer = time.get_ticks()

    def calculate_score(self, row):
        scores = {0: 30,
                  1: 20,
                  2: 20,
                  3: 10,
                  4: 10,
                  5: choice([50, 100, 150, 300])
                  }

        score = scores[row]
        self.score += score
        return score

    def create_main_menu(self):
        self.enemy1 = IMAGES['enemy3_1']
        self.enemy1 = transform.scale(self.enemy1, (40, 40))
        self.enemy2 = IMAGES['enemy2_2']
        self.enemy2 = transform.scale(self.enemy2, (40, 40))
        self.enemy3 = IMAGES['enemy1_2']
        self.enemy3 = transform.scale(self.enemy3, (40, 40))
        self.enemy4 = IMAGES['mystery']
        self.enemy4 = transform.scale(self.enemy4, (80, 40))
        self.screen.blit(self.enemy1, (318, 270))
        self.screen.blit(self.enemy2, (318, 320))
        self.screen.blit(self.enemy3, (318, 370))
        self.screen.blit(self.enemy4, (299, 420))

    def check_collisions(self):
        sprite.groupcollide(self.bullets, self.enemyBullets, True, True)

        col = sprite.groupcollide(self.enemies, self.bullets, False, True)
        for enemy in col.keys():
            self.sounds['invaderkilled'].play()
            enemy.health -= col[enemy][0].damage
            if enemy.health <= 0:
                enemy.kill()
                self.calculate_score(enemy.row)
                EnemyExplosion(enemy, self.explosionsGroup)
                self.gameTimer = time.get_ticks()

        for mystery in sprite.groupcollide(self.mysteryGroup, self.bullets,
                                           True, True).keys():
            mystery.mysteryEntered.stop()
            self.sounds['mysterykilled'].play()
            score = self.calculate_score(mystery.row)
            MysteryExplosion(mystery, score, self.explosionsGroup)
            newShip = Mystery()
            self.allSprites.add(newShip)
            self.mysteryGroup.add(newShip)

        collision_handled = False

        circuit = self.circuit_grid.circuit_grid_model.compute_circuit()
        state = self.get_measurement(circuit, 3, 1)

        hits = sprite.groupcollide(self.playerGroup, self.enemyBullets,
                                          False, True)
        self.player.measuring = False

        if self.player.state == ShipState.SUPERPOSITION:
            for ship in hits:
                if ship.probability > 0.0:
                    self.player.measure(state)
                if state == ship.id:  # quantum case
                    if not collision_handled:
                        if self.life3.alive():
                            self.life3.kill()
                        elif self.life2.alive():
                            self.life2.kill()
                        elif self.life1.alive():
                            self.life1.kill()
                        else:
                            self.gameOver = True
                            self.startGame = False
                        self.sounds['shipexplosion'].play()
                        self.player.explode_ships(self.explosionsGroup, ship.id)
                        self.makeNewShip = True
                        self.shipPosition = self.player.position
                        self.shipTimer = time.get_ticks()
                        self.shipAlive = False

                        collision_handled = True
        elif self.player.state == ShipState.MEASURED:
            for ship in hits:
                print("collision detected, state is MEASURED")
                if not collision_handled:
                    if self.life3.alive():
                        self.life3.kill()
                    elif self.life2.alive():
                        self.life2.kill()
                    elif self.life1.alive():
                        self.life1.kill()
                    else:
                        self.gameOver = True
                        self.startGame = False
                    self.sounds['shipexplosion'].play()
                    self.player.explode_ships(self.explosionsGroup, -1)
                    self.makeNewShip = True
                    self.shipPosition = self.player.position
                    self.shipTimer = time.get_ticks()
                    self.shipAlive = False

                    collision_handled = True

        # for ship in hits:
        #     if not self.player.measuring and ship.probability > 0.0:
        #         self.player.measure(state)
        #         self.player.measuring = True

        if self.enemies.bottom >= 540:
            sprite.groupcollide(self.enemies, self.playerGroup, True, True)
            if not self.player.alive() or self.enemies.bottom >= 600:
                self.gameOver = True
                self.startGame = False

        sprite.groupcollide(self.bullets, self.allBlockers, True, True)
        sprite.groupcollide(self.enemyBullets, self.allBlockers, True, True)
        if self.enemies.bottom >= BLOCKERS_POSITION:
            sprite.groupcollide(self.enemies, self.allBlockers, False, True)

    def create_new_ship(self, createShip, currentTime):

        if createShip and (currentTime - self.shipTimer > 900):
            self.player = ShipGroup(NUMBER_OF_SHIPS, self.shipPosition)
            self.make_ships()
            self.labels.initialize(self.player.position)
            self.allSprites.add(self.player)
            self.playerGroup.add(self.player)
            self.makeNewShip = False
            self.shipAlive = True
        elif createShip and (currentTime - self.shipTimer > 300):
            if self.player.measured_ship:
                self.player.measured_ship.kill()

    def create_game_over(self, currentTime):
        self.screen.blit(self.background, (0, 0))
        passed = currentTime - self.timer
        if passed < 750:
            self.gameOverText.draw(self.screen)
        elif 750 < passed < 1500:
            self.screen.blit(self.background, (0, 0))
        elif 1500 < passed < 2250:
            self.gameOverText.draw(self.screen)
        elif 2250 < passed < 2750:
            self.screen.blit(self.background, (0, 0))
        elif passed > 3000:
            self.mainScreen = True

        for e in event.get():
            if self.should_exit(e):
                sys.exit()

    def main(self):
        while True:
            if self.mainScreen:
                self.screen.blit(self.background, (0, 0))
                self.titleText.draw(self.screen)
                self.titleText2.draw(self.screen)
                self.enemy1Text.draw(self.screen)
                self.enemy2Text.draw(self.screen)
                self.enemy3Text.draw(self.screen)
                self.enemy4Text.draw(self.screen)
                self.create_main_menu()
                for e in event.get():
                    if self.should_exit(e):
                        sys.exit()
                    if e.type == KEYUP:
                        # Only create blockers on a new game, not a new round
                        self.allBlockers = sprite.Group(self.make_blockers(0),
                                                        self.make_blockers(1),
                                                        self.make_blockers(2),
                                                        self.make_blockers(3))
                        self.livesGroup.add(self.life1, self.life2, self.life3)
                        self.reset(0)
                        self.startGame = True
                        self.mainScreen = False

            elif self.startGame:
                if not self.enemies and not self.explosionsGroup and not self.paused:
                    currentTime = time.get_ticks()
                    if currentTime - self.gameTimer < 3000:
                        self.screen.blit(self.background, (0, 0))
                        self.scoreText2 = Text(FONT, 20, str(self.score),
                                               GREEN, 85, 5)
                        self.scoreText.draw(self.screen)
                        self.scoreText2.draw(self.screen)
                        self.nextRoundText.draw(self.screen)
                        self.livesText.draw(self.screen)
                        #self.circuit_grid.draw(self.screen)
                        # self.player.draw(self.screen)
                        self.livesGroup.update()
                        self.check_input()
                        self.labels.update(self.screen, self.player.position)
                    if currentTime - self.gameTimer > 3000:
                        # Move enemies closer to bottom
                        self.enemyPosition += ENEMY_MOVE_DOWN
                        self.reset(self.score)
                        self.gameTimer += 3000
                else:

                    self.screen.blit(self.background, (0, 0))
                    self.allBlockers.update(self.screen)
                    self.scoreText2 = Text(FONT, 20, str(self.score), GREEN,
                                           85, 5)
                    self.scoreText.draw(self.screen)
                    self.scoreText2.draw(self.screen)
                    self.livesText.draw(self.screen)
                    #self.circuit_grid.draw(self.screen)
                    self.labels.update(self.screen, self.player.position)
                    # self.player.draw(self.screen)
                    self.check_input()
                    if not self.paused:
                        currentTime = time.get_ticks()
                        self.play_main_music(currentTime)
                        self.enemies.update(currentTime)
                        self.make_enemies_shoot()
                        self.allSprites.update(self.keys, currentTime)
                        self.explosionsGroup.update(currentTime)
                        self.check_collisions()
                        self.create_new_ship(self.makeNewShip, currentTime)
                    else:
                        self.pauseText.draw(self.screen)
                        self.pauseText2.draw(self.screen)
                        self.circuit_grid.draw(self.screen)
                        self.player.update(self.keys)
                    # self.ships.update(self.keys)

            elif self.gameOver:
                currentTime = time.get_ticks()
                # Reset enemy starting position
                self.enemyPosition = ENEMY_DEFAULT_POSITION
                self.create_game_over(currentTime)

            display.update()
            self.clock.tick(60)

if __name__ == '__main__':
    game = SpaceInvaders()
    game.main()


import collections
import uuid
import wrapt

from iopipe.compat import string_types, urlparse
from .util import ensure_utf8

INCLUDE_HEADERS = [
    "content-length",
    "content-type",
    "host",
    "server",
    "user-agent",
    "x-amz-target",
]

Request = collections.namedtuple(
    "Request",
    [
        "hash",
        "headers",
        "hostname",
        "method",
        "path",
        "pathname",
        "port",
        "protocol",
        "query",
        "url",
    ],
)

Response = collections.namedtuple(
    "Response", ["headers", "statusCode", "statusMessage"]
)

def patch_requests_session_send(context, http_filter, http_headers):
    """
    Monkey patches requests' session class, if available. Overloads the
    send method to add tracing and metrics collection.
    """

    def wrapper(wrapped, instance, args, kwargs):
        if not hasattr(context, "iopipe") or not hasattr(context.iopipe, "mark"):
            return wrapped(*args, **kwargs)
        id = ensure_utf8(str(uuid.uuid4()))
        with context.iopipe.mark(id):
            response = wrapped(*args, **kwargs)
        trace = context.iopipe.mark.measure(id)
        context.iopipe.mark.delete(id)
        collect_metrics_for_response(
            response.request, response, context, trace, http_filter, http_headers
        )
        return response

    try:
        wrapt.wrap_function_wrapper("requests.sessions", "Session.send", wrapper)
    except Exception:  # pragma: no cover
        pass

def patch_botocore_session_send(context, http_filter, http_headers):
    """
    Monkey patches botocore's session, if available. Overloads the
    session class' send method to add tracing and metric collection.
    """

    def wrapper(wrapped, instance, args, kwargs):
        if not hasattr(context, "iopipe") or not hasattr(context.iopipe, "mark"):
            return wrapped(*args, **kwargs)
        id = str(uuid.uuid4())
        with context.iopipe.mark(id):
            response = wrapped(*args, **kwargs)
        trace = context.iopipe.mark.measure(id)
        context.iopipe.mark.delete(id)
        collect_metrics_for_response(
            args[0], response, context, trace, http_filter, http_headers
        )
        return response

    try:
        wrapt.wrap_function_wrapper(
            "botocore.httpsession", "URLLib3Session.send", wrapper
        )
    except Exception:  # pragma: no cover
        pass

def patch_botocore_vendored_session_send(context, http_filter, http_headers):
    """
    Monkey patches botocore's vendored requests, if available. Overloads the
    session class' send method to add tracing and metric collection.
    """

    def wrapper(wrapped, instance, args, kwargs):
        if not hasattr(context, "iopipe") or not hasattr(context.iopipe, "mark"):
            return wrapped(*args, **kwargs)
        id = str(uuid.uuid4())
        with context.iopipe.mark(id):
            response = wrapped(*args, **kwargs)
        trace = context.iopipe.mark.measure(id)
        context.iopipe.mark.delete(id)
        collect_metrics_for_response(
            response.request, response, context, trace, http_filter, http_headers
        )
        return response

    try:
        wrapt.wrap_function_wrapper(
            "botocore.vendored.requests.sessions", "Session.send", wrapper
        )
    except Exception:  # pragma: no cover
        pass

def restore_requests_session_send():
    """Restores the original requests session send method"""
    try:
        from requests.sessions import Session as RequestsSession
    except ImportError:  # pragma: no cover
        pass
    else:
        if hasattr(RequestsSession.send, "__wrapped__"):
            setattr(RequestsSession, "send", RequestsSession.send.__wrapped__)

def restore_botocore_session_send():
    """Restores the original botocore session send method"""
    try:
        from botocore.httpsession import URLLib3Session as BotocoreSession
    except ImportError:  # pragma: no cover
        pass
    else:
        if hasattr(BotocoreSession.send, "__wrapped__"):
            setattr(BotocoreSession, "send", BotocoreSession.send.__wrapped__)

def restore_botocore_vendored_session_send():
    """Restores the original botocore vendored session send method"""
    try:
        from botocore.vendored.requests.sessions import (
            Session as BotocoreVendoredSession,
        )
    except ImportError:  # pragma: no cover
        pass
    else:
        if hasattr(BotocoreVendoredSession.send, "__wrapped__"):
            setattr(
                BotocoreVendoredSession,
                "send",
                BotocoreVendoredSession.send.__wrapped__,
            )

def patch_http_requests(context, http_filter, http_headers):
    if not hasattr(context, "iopipe"):
        return

    patch_requests_session_send(context, http_filter, http_headers)
    patch_botocore_session_send(context, http_filter, http_headers)
    patch_botocore_vendored_session_send(context, http_filter, http_headers)

def restore_http_requests():
    restore_requests_session_send()
    restore_botocore_session_send()
    restore_botocore_vendored_session_send()

def collect_metrics_for_response(
    http_request, http_response, context, trace, http_filter, http_headers
):
    """
    Collects relevant metrics from a requests Response object and adds them to
    the IOpipe context.
    """
    include_headers = INCLUDE_HEADERS
    if isinstance(http_headers, (list, tuple)):
        include_headers = include_headers + [
            key.lower()
            for key in http_headers
            if isinstance(http_headers, string_types)
        ]

    request = None
    if http_request:
        parsed_url = None
        if hasattr(http_request, "url"):
            parsed_url = urlparse(http_request.url)

        request_headers = []
        if hasattr(http_request, "headers"):
            request_headers = [
                {"key": ensure_utf8(k), "string": ensure_utf8(v)}
                for k, v in http_request.headers.items()
                if k.lower() in include_headers
            ]

        request = Request(
            hash=ensure_utf8(getattr(parsed_url, "fragment", None)),
            headers=request_headers,
            hostname=ensure_utf8(getattr(parsed_url, "hostname", None)),
            method=ensure_utf8(getattr(http_request, "method", None)),
            path=ensure_utf8(getattr(parsed_url, "path", None)),
            # TODO: Determine if this is redundant
            pathname=ensure_utf8(getattr(parsed_url, "path", None)),
            port=ensure_utf8(getattr(parsed_url, "port", None)),
            protocol=ensure_utf8(getattr(parsed_url, "scheme", None)),
            query=ensure_utf8(getattr(parsed_url, "query", None)),
            url=ensure_utf8(getattr(http_request, "url", None)),
        )

        # TODO: Possibly remove the namedtuple in favor of just a dict
        request = request._asdict()

    response_headers = []
    if hasattr(http_response, "headers"):
        response_headers = [
            {"key": ensure_utf8(k), "string": ensure_utf8(v)}
            for k, v in http_response.headers.items()
            if k.lower() in include_headers
        ]

    response = Response(
        headers=response_headers,
        statusCode=ensure_utf8(getattr(http_response, "status_code", None)),
        statusMessage=None,
    )

    # TODO: Possibly remove the namedtuple in favor of just a dict
    response = response._asdict()

    if http_filter is not None and callable(http_filter):
        try:
            request, response = http_filter(request, response)
        except Exception:
            return

    context.iopipe.mark.http_trace(trace, request, response)


# Напишите программу, удаляющую из текста все слова, содержащие "абв".

from colorama import init, Fore

init(autoreset=True)

text = 'абв зеленый абвход три хр тр трабвбр пр учитьабв'

print(Fore.BLUE + f'Исходный текст:\n--> {text}')

final_text = ' '.join(
    list(filter(lambda x: not 'абв' in x, list(text.split()))))

print(Fore.GREEN +
      f'Текст после удаления слов, содержащих "абв":\n--> {final_text}')


import os

import geopandas as gpd
import pandas as pd

def main(regions_file_path: str, municipalities_file_path: str) -> None:
    os.makedirs('./output/kommuner', exist_ok=True)

    data_reg = gpd.read_file(regions_file_path)
    print(data_reg.head())
    print(len(data_reg.index))
    data_reg.to_file('./output/kommuner/lan.geojson', driver="GeoJSON", encoding='utf-8')

    data_mun = gpd.read_file(municipalities_file_path)
    data_mun["LnKod"] = data_mun["KnKod"].apply(lambda kn_kod: kn_kod[:2])
    data_mun["LnNamn"] = data_mun["LnKod"].apply(lambda ln_kod: data_reg.loc[data_reg['LnKod'] == ln_kod, 'LnNamn'].iloc[0])
    print(data_mun.head())
    print(len(data_mun.index))
    for index, lan_namn in data_reg['LnNamn'].items():
        data_mun_reg = data_mun[data_mun['LnNamn'] == lan_namn]
        data_mun_reg.to_file('./output/kommuner/{}.geojson'.format(lan_namn), driver="GeoJSON", encoding='utf-8')

if __name__ == '__main__':
    pd.set_option('display.max_columns', None)
    main(
        "../data-collected/sverige-geodata/LanSweref99TM/Lan_Sweref99TM_region.shp",
        "../data-collected/sverige-geodata/KommunSweref99TM/Kommun_Sweref99TM_region.shp"
    )


# https://leetcode.com/problems/kth-missing-positive-number/
import pytest

class Solution:
    def findKthPositive(self, arr: list[int], k: int) -> int:
        first = arr[0]
        result = []
        i = 1
        l = 0
        while l < len(arr):
            first = arr[l]
            while i < first:
                result.append(i)
                i += 1
            i = first + 1
            l += 1

        if len(result) < k:
            i = arr[len(arr) - 1] + 1
            p = k
            while p >= 0:
                result.append(i)
                i += 1
                p -= 1

        return result[k - 1]

@pytest.mark.parametrize(
    ("arr", "k", "result"), [([2, 3, 4, 7, 11], 5, 9), ([1, 2, 3, 4], 2, 6)]
)
def test_missingpositive(arr: list[int], k: int, result: int) -> None:
    assert result == Solution().findKthPositive(arr, k)


import torch.nn as nn
import torch.nn.functional as F

# 构建网络
class MyModel(nn.Module):
    def __init__(self):
        super(MyModel, self).__init__()
        self.model1 = nn.Sequential(
            nn.Conv2d(in_channels=3, out_channels=32, kernel_size=5, stride=1, padding=2),
            nn.MaxPool2d(2),
            nn.Conv2d(in_channels=32, out_channels=32, kernel_size=5, stride=1, padding=2),
            nn.MaxPool2d(2),
            nn.Conv2d(in_channels=32, out_channels=64, kernel_size=5, stride=1, padding=2),
            nn.MaxPool2d(2),
            nn.Flatten(),
            nn.Linear(1024, 64),
            nn.Linear(64, 10)
        )

    def forward(self, x):
        x = self.model1(x)
        return x


#!/usr/bin/env python
# -*- coding: utf-8 -*-
from django.contrib.auth.models import User, Group

from rest_framework import serializers, fields

from perfectday.api import models
from perfectday.api import utils

class UserSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = User
        fields = ('url', 'username', 'email', 'groups')

class PersonSerializer(serializers.HyperlinkedModelSerializer):
    user = UserSerializer()
    habits = serializers.HyperlinkedRelatedField(view_name='habit-detail',
                                                 many=True,
                                                 read_only=True)

    class Meta:
        model = models.Person
        fields = ('id', 'url', 'user', 'worth', 'habits')

class GroupSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Group
        fields = ('url', 'name')

class PeriodSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = models.Period
        fields = ('start', 'period')

class ScheduleSerializer(serializers.HyperlinkedModelSerializer):
    periods = PeriodSerializer(many=True)

    class Meta:
        model = models.Schedule
        fields = ('weight', 'start', 'stop', 'periods')

    def run_validation(self, data=fields.empty):
        if data['start'] == '':
            data['start'] = utils.int_now()
        return super(ScheduleSerializer, self).run_validation(data)

class HabitSerializer(serializers.HyperlinkedModelSerializer):
    schedule = ScheduleSerializer()
    happened_today = serializers.BooleanField(read_only=True)
    today_action_id = serializers.IntegerField(read_only=True)

    class Meta:
        model = models.Habit
        fields = ('id', 'url', 'person', 'short_description', 'long_description', 'schedule',
                  'happened_today', 'today_action_id')

    def create(self, validated_data):
        schedule_data = validated_data.pop('schedule')
        periods_data = schedule_data.pop('periods')
        if periods_data == []:
            periods_data = [{'start': 0, 'period': 1}]  # default to daily

        habit = models.Habit.objects.create(**validated_data)

        if schedule_data['start'] == 0:
            schedule_data['start'] = utils.int_now()

        schedule = models.Schedule.objects.create(habit=habit, **schedule_data)

        for period_data in periods_data:
            models.Period.objects.create(schedule=schedule, **period_data)
        return habit

    def update(self, habit, validated_data):
        schedule_data = validated_data.pop('schedule')
        periods_data = schedule_data.pop('periods')

        old_schedule = habit.schedule
        if old_schedule is not None:
            old_schedule.stop = utils.int_now()
            old_schedule.save()

        if schedule_data['start'] == 0:
            schedule_data['start'] = utils.int_now()

        schedule = models.Schedule.objects.create(habit=habit, **schedule_data)

        for period_data in periods_data:
            models.Period.objects.create(schedule=schedule, **period_data).save()

        schedule.save()

        habit.short_description = validated_data.get('short_description', habit.short_description)
        habit.long_description = validated_data.get('long_description', habit.long_description)
        habit.save()

        return habit

class ActionSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = models.Action
        fields = ('url', 'habit', 'when')

    def validate_when(self, value):
        if value <= 0:  # you can't do shit on day zero now, soz
            value += utils.int_now()
        return value

class EpochSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = models.RewardEpoch
        fields = ('cost',)

class RewardSerializer(serializers.HyperlinkedModelSerializer):
    current_epoch = EpochSerializer()

    class Meta:
        model = models.Reward
        fields = ('url', 'person', 'short_description', 'long_description', 'current_epoch')

    def create(self, validated_data):
        epoch_data = validated_data.pop('current_epoch')
        reward = models.Reward.objects.create(**validated_data)
        models.RewardEpoch.objects.create(reward=reward, **epoch_data)
        return reward

    # TODO: make this and habit.update not create new epochs unnecessarily
    def update(self, reward, validated_data):
        epoch_data = validated_data.pop('current_epoch')
        models.RewardEpoch.objects.create(reward=reward, **epoch_data)

        reward.short_description = validated_data.get('short_description', reward.short_description)
        reward.long_description = validated_data.get('long_description', reward.long_description)
        return reward

class PurchaseSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = models.Purchase
        fields = ('url', 'reward', 'when')


"""
217. Contains Duplicate
Difficulty:Easy

Given an integer array nums, return true if any value appears at least twice in the array, and return false if every element is distinct.

Example 1:

Input: nums = [1,2,3,1]
Output: true
Example 2:

Input: nums = [1,2,3,4]
Output: false
Example 3:

Input: nums = [1,1,1,3,3,4,3,2,4,2]
Output: true

Constraints:

1 <= nums.length <= 105
-109 <= nums[i] <= 109
"""

from typing import List

class Solution:
    def containsDuplicate(self, nums: List[int]) -> bool:
        hash_table = {}
        for n in nums:
            if n not in hash_table:
                hash_table[n] = True
            else:
                return True
        return False

if __name__ == "__main__":
    solution = Solution()
    # print(solution.containsDuplicate(nums=[1, 2, 3, 1]))  # true
    print(solution.containsDuplicate(nums=[1, 2, 3, 4]))  # false
    # print(solution.containsDuplicate(nums=[1, 1, 1, 3, 3, 4, 3, 2, 4, 2]))  # true


from odoo.tests import common, tagged
from odoo import fields
from dateutil.relativedelta import relativedelta

@tagged("post_install", "-at_install")
class TestEventPriceShared(common.SavepointCase):
    @classmethod
    def setUpClass(cls):
        super(TestEventPriceShared, cls).setUpClass()
        cls.registration_obj = cls.env['event.registration']
        cls.track_obj = cls.env['event.track']
        cls.customer = cls.env.ref('base.res_partner_12')
        cls.student1 = cls.env.ref('base.res_partner_18')
        cls.student2 = cls.env.ref('base.res_partner_10')
        cls.resource_calendar = cls.env.ref('resource.resource_calendar_std')
        cls.amounced_stage = cls.env.ref('event.event_stage_announced')
        cls.uom_unit = cls.env.ref('uom.product_uom_unit')
        vals = {'name': 'User event price shared',
                'login': 'ueps@avanzosc.es'}
        cls.user = cls.env['res.users'].create(vals)
        vals = {'name': 'employee event price shared',
                'user_id': cls.user.id}
        cls.env['hr.employee'].create(vals)
        cls.product = cls.env['product.product'].create({
            'name': 'product event price sahred',
            'default_code': 'PEPS',
            'uom_id': cls.uom_unit.id,
            'uom_po_id': cls.uom_unit.id,
            'type': 'service',
            'service_tracking': 'task_in_project',
            'invoice_policy': 'order',
            'service_policy': 'delivered_timesheet',
            'event_ok': True})
        cls.event = cls.env['event.event'].create({
            'name': 'Event event_price_shared',
            'date_begin': fields.Date.today(),
            'date_end': fields.Date.today() + relativedelta(days=+7),
            'shared_price_event': True,
            'organizer_id': cls.customer.id,
            'customer_id': cls.customer.id,
            'resource_calendar_id': cls.resource_calendar.id,
            'main_responsible_id': cls.user.id,
            'event_ticket_ids': [(0, 0, {'product_id': cls.product.id,
                                         'name': cls.product.name,
                                         'price': 50})]
            })

    def test_event_price_shared(self):
        self.event.stage_id = self.amounced_stage.id
        self.assertIsNot(self.event.project_id, False)
        track_vals = {'event_id': self.event.id,
                      'name': 'Session 1',
                      'date': fields.Date.today(),
                      'partner_id': self.user.partner_id.id}
        track = self.track_obj.create(track_vals)
        registration_vals = {
            'event_id': self.event.id,
            'partner_id': self.student1.id,
            'student_id': self.student1.id,
            'event_ticket_id': self.event.event_ticket_ids[0].id,
            'real_date_start': fields.Date.today()}
        registration1 = self.registration_obj.create(registration_vals)
        registration1.action_confirm()
        registration_vals = {
            'event_id': self.event.id,
            'partner_id': self.student2.id,
            'student_id': self.student2.id,
            'event_ticket_id': self.event.event_ticket_ids[0].id,
            'real_date_start': fields.Date.today()}
        registration2 = self.registration_obj.create(registration_vals)
        registration2.action_confirm()
        self.assertEqual(self.event.count_sale_orders, 2)
        sales = self.event.sale_order_lines_ids.mapped('order_id')
        for sale in sales:
            sale.action_confirm()
        self.assertIsNot(registration1.task_id, False)
        self.assertIsNot(registration2.task_id, False)
        self.assertNotEqual(registration1.task_id, registration2.task_id)
        track.button_session_done()
        self.assertEqual(len(track.account_analytic_line_ids), 2)