import pandas as pd
import sklearn.cluster as cluster
from sklearn.preprocessing import scale
import sklearn.decomposition as decomp
import matplotlib.pyplot as plt
import csv

# Data Cleaning and Organization
data = pd.read_csv("data_by_genres.csv")
genres = data[['genres']]
data = data.drop('genres', 1)
data = data.drop("duration_ms", 1)
data = data.drop("popularity", 1)
data = data.drop("key", 1)
data = data.drop("mode", 1)

# Normalization (Scaling)
X = data.to_numpy()
X = scale(X)

# Dimensionality Reduction (PCA)
#pca = decomp.KernelPCA(n_components=2, kernel='rbf')
#X = pca.fit_transform(X)
#print(X.shape)

#2900 genres,
# Agglomerative Clustering
agglomerative = cluster.AgglomerativeClustering(n_clusters=297, linkage='ward')
print(agglomerative.fit_predict(X))

# plt.scatter(X[:,0], X[:,1], c = agglomerative.labels_, cmap= 'rainbow')
# plt.show()

with open("genres_classified_without_mode.csv", "w") as fout:
    csv_writer = csv.writer(fout)
    temp = list(zip(genres.values.flatten(), agglomerative.labels_))
    temp.sort(key = lambda x: x[1])
    for genre, label in temp:
        csv_writer.writerow([genre, label])


import builtins
import socket
from typing import List, Union
from unittest import mock
from unittest.mock import DEFAULT, Mock, call, patch

from autoreduce_db.reduction_viewer.models import (Experiment, Instrument, ReductionArguments, ReductionScript, Status,
                                                   DataLocation, RunNumber, ReductionRun)
from django.db import IntegrityError
from django.test import TestCase
from django.utils import timezone

from autoreduce_scripts.manual_operations.manual_remove import (ManualRemove, main, remove, user_input_check)

# pylint:disable=no-member,invalid-name

class FakeMessage:
    started_by = 0
    run_number = 1234567
    message = "I am a message"
    description = "This is a fake description"
    data = "/some/location"

def create_experiment_and_instrument():
    "Creates a test experiment and instrument"

    experiment, _ = Experiment.objects.get_or_create(reference_number=1231231)
    instrument, _ = Instrument.objects.get_or_create(name="ARMI", is_active=1, is_paused=0)
    return experiment, instrument

def _make_data_locations(reduction_run, message_data_loc: Union[str, List[str]]):
    """
    Create a new data location entry which has a foreign key linking it to the current
    reduction run. The file path itself will point to a datafile
    (e.g. "/isis/inst$/NDXWISH/Instrument/data/cycle_17_1/WISH00038774.nxs")
    """
    if isinstance(message_data_loc, str):
        DataLocation.objects.create(file_path=message_data_loc, reduction_run=reduction_run)
    else:
        DataLocation.objects.bulk_create(
            [DataLocation(file_path=data_loc, reduction_run=reduction_run) for data_loc in message_data_loc])

def _make_run_numbers(reduction_run, message_run_number: Union[int, List[int]]):
    """
    Creates the related RunNumber objects
    """
    if isinstance(message_run_number, int):
        RunNumber.objects.create(reduction_run=reduction_run, run_number=message_run_number)
    else:
        RunNumber.objects.bulk_create(
            [RunNumber(reduction_run=reduction_run, run_number=run_number) for run_number in message_run_number])

def create_reduction_run_record(experiment, instrument, message, run_version, script_text, status):
    """
    Creates an ORM record for the given reduction run and returns
    this record without saving it to the DB
    """

    time_now = timezone.now()
    script = ReductionScript.objects.create(text=script_text)
    arguments = ReductionArguments.objects.create(
        raw="""{"standard_vars":{"variable_str":"value1","variable_int":123,"variable_float":123.321,
        "variable_listint":[1,2,3],"variable_liststr":["a","b","c"],"variable_none":null,
        "variable_empty":"","variable_bool":true}}""",
        instrument=instrument)
    reduction_run = ReductionRun.objects.create(run_version=run_version,
                                                run_description=message.description,
                                                hidden_in_failviewer=0,
                                                admin_log='',
                                                reduction_log='',
                                                created=time_now,
                                                last_updated=time_now,
                                                experiment=experiment,
                                                instrument=instrument,
                                                status_id=status.id,
                                                started_by=message.started_by,
                                                reduction_host=socket.getfqdn(),
                                                batch_run=isinstance(message.run_number, list),
                                                script=script,
                                                arguments=arguments,
                                                run_title="Test title")
    _make_run_numbers(reduction_run, message.run_number)
    _make_data_locations(reduction_run, message.data)

    return reduction_run

def make_test_run(experiment, instrument, run_version: str):
    "Creates a test run and saves it to the database"
    status = Status.get_queued()
    fake_script_text = "scripttext"
    msg1 = FakeMessage()
    msg1.run_number = 101
    run = create_reduction_run_record(experiment, instrument, msg1, run_version, fake_script_text, status)
    run.save()
    run.data_location.create(file_path='test/file/path/2.raw')
    return run

def make_test_batch_run(experiment, instrument, run_version: str):
    "Creates a test run and saves it to the database"
    status = Status.get_queued()
    fake_script_text = "scripttext"
    msg1 = FakeMessage()
    msg1.run_number = [101, 102, 103]
    run = create_reduction_run_record(experiment, instrument, msg1, run_version, fake_script_text, status)
    run.save()
    run.data_location.create(file_path='test/file/path/2.raw')
    return run

class TestManualRemove(TestCase):
    """
    Test manual_remove.py
    """
    fixtures = ["status_fixture"]

    def setUp(self):
        self.manual_remove = ManualRemove(instrument="ARMI")
        # Setup database connection so it is possible to use
        # ReductionRun objects with valid meta data
        self.experiment, self.instrument = create_experiment_and_instrument()

        self.run1 = make_test_run(self.experiment, self.instrument, "1")
        self.run2 = make_test_run(self.experiment, self.instrument, "2")
        self.run3 = make_test_run(self.experiment, self.instrument, "3")

    def test_find_run(self):
        """
        Test: That the correct number of run versions are discovered
        When: find_run_versions_in_database is called
        """
        actual = self.manual_remove.find_run_versions_in_database(run_number=101)
        self.assertEqual(3, len(actual))

    def test_find_run_invalid(self):
        """
        Test: That no run versions are found for a run number that doesn't exist in the database
        When: find_run_versions_in_database is called
        """
        actual = self.manual_remove.find_run_versions_in_database(run_number="000")
        self.assertEqual(0, len(actual))

    @patch("autoreduce_scripts.manual_operations.manual_remove.ManualRemove.run_not_found")
    def test_process_results_not_found(self, mock_not_found):
        """
        Test: run_not_found is called
        When: No matching records are found in the database
        """
        self.manual_remove.to_delete["101"] = []
        self.manual_remove.process_results(delete_all_versions=True)
        mock_not_found.assert_called_once()
        mock_not_found.reset_mock()
        self.manual_remove.process_results(delete_all_versions=True)
        mock_not_found.assert_called_once()

    @patch("autoreduce_scripts.manual_operations.manual_remove.ManualRemove.run_not_found")
    @patch("autoreduce_scripts.manual_operations.manual_remove.ManualRemove.multiple_versions_found")
    def test_process_results_single(self, mock_multi, mock_not_found):
        """
        Test: That the code does not call multiple_versions_found
        When: The results only contain single runs (not multiple versions)
        """
        self.manual_remove.to_delete["101"] = ["test"]
        self.manual_remove.process_results(delete_all_versions=False)
        mock_multi.assert_not_called()
        mock_not_found.assert_not_called()

    @patch("autoreduce_scripts.manual_operations.manual_remove.ManualRemove.multiple_versions_found")
    def test_process_results_multi(self, mock_multi_version):
        """
        Test: process_results function routes to correct function if the run has multiple versions
        When: Multiple runs / versions are found in the database

        Note: For this test the content of results[key] list does not have to be Run objects
        """
        self.manual_remove.to_delete["101"] = ["test", "test2"]
        self.manual_remove.process_results(delete_all_versions=False)
        mock_multi_version.assert_called_once()

    @patch("autoreduce_scripts.manual_operations.manual_remove.ManualRemove.multiple_versions_found")
    def test_process_results_multi_with_delete_all(self, mock_multi_version):
        """
        Test: process_results function doesn't ask for user input with delete_all_versions=True
        When: Multiple runs / versions are found in the database

        Note: For this test the content of results[key] list does not have to be Run objects
        """
        self.manual_remove.to_delete["101"] = ["test", "test2"]
        self.manual_remove.process_results(delete_all_versions=True)
        mock_multi_version.assert_not_called()

    def test_run_not_found(self):
        """
        Test: That the correct corresponding run is deleted
        When: The value of a to_delete key is empty
        """
        self.manual_remove.to_delete["101"] = []
        self.manual_remove.run_not_found("101")
        self.assertEqual(0, len(self.manual_remove.to_delete))

    @patch("autoreduce_scripts.manual_operations.manual_remove.ManualRemove.validate_csv_input")
    @patch.object(builtins, "input")
    def test_multiple_versions_found_single_input(self, mock_input, mock_validate_csv):
        """
        Test: That the user is not asked more than once for input
        When: The input is valid
        """
        self.manual_remove.to_delete["101"] = [self.run1, self.run2, self.run3]
        mock_input.return_value = "2"
        mock_validate_csv.return_value = (True, ["2"])
        self.manual_remove.multiple_versions_found("101")

        self.assertEqual(1, mock_validate_csv.call_count)
        mock_validate_csv.assert_has_calls([call("2")])

    @patch("autoreduce_scripts.manual_operations.manual_remove.ManualRemove.validate_csv_input")
    @patch.object(builtins, "input")
    def test_multiple_versions_retry_user_input(self, mock_input, mock_validate_csv):
        """
        Test: Input is re-validated
        When: The user initially gives incorrect input
        """
        self.manual_remove.to_delete["101"] = [self.run1, self.run2, self.run3]
        mock_input.side_effect = ["invalid", "2"]
        mock_validate_csv.side_effect = [(False, []), (True, ["2"])]
        self.manual_remove.multiple_versions_found("101")

        self.assertEqual(2, mock_validate_csv.call_count)
        mock_validate_csv.assert_has_calls([call("invalid"), call("2")])

    @patch("autoreduce_scripts.manual_operations.manual_remove.ManualRemove.validate_csv_input")
    @patch.object(builtins, "input")
    def test_multiple_versions_remove_one(self, mock_input, mock_validate_csv):
        """
        Test: That manual_remove will remove one run version
        When: Multiple versions are found for a run and one version is inputted
        """
        self.manual_remove.to_delete["101"] = [self.run1, self.run2, self.run3]
        mock_input.return_value = "2"
        mock_validate_csv.return_value = (True, ["2"])
        self.manual_remove.multiple_versions_found("101")

        # We said to delete version 2 so it should be the only entry for that run number
        self.assertEqual(1, len(self.manual_remove.to_delete["101"]))
        self.assertEqual("2", self.manual_remove.to_delete["101"][0].run_version)

    @patch("autoreduce_scripts.manual_operations.manual_remove.ManualRemove.validate_csv_input")
    @patch.object(builtins, "input")
    def test_multiple_versions_found_list_input(self, mock_input, mock_validate_csv):
        """
        Test: The correct versions are deleted
        When: The user asks to delete two run versions as an inputted list
        """
        self.manual_remove.to_delete["101"] = [self.run1, self.run2, self.run3]
        mock_input.return_value = "1,3"
        mock_validate_csv.return_value = (True, ["1", "3"])
        self.manual_remove.multiple_versions_found("101")

        # We said to delete versions 1 and 3 so there should be those entries to delete for that run
        self.assertEqual(2, len(self.manual_remove.to_delete["101"]))
        self.assertEqual("1", self.manual_remove.to_delete["101"][0].run_version)
        self.assertEqual("3", self.manual_remove.to_delete["101"][1].run_version)

    @patch("autoreduce_scripts.manual_operations.manual_remove.ManualRemove.validate_csv_input")
    @patch.object(builtins, "input")
    def test_multiple_versions_found_range_input(self, mock_input, mock_validate_csv):
        """
        Test: That the correct versions are deleted
        When: The user asks to delete a range of versions
        """
        self.manual_remove.to_delete["101"] = [self.run1, self.run2, self.run3]
        mock_input.return_value = "1-3"
        mock_validate_csv.return_value = (True, ["1", "2", "3"])
        self.manual_remove.multiple_versions_found("101")

        # We said to delete versions 1, 2 and 3 so there should 3 entries to delete for that run
        self.assertEqual(3, len(self.manual_remove.to_delete["101"]))
        self.assertEqual("1", self.manual_remove.to_delete["101"][0].run_version)
        self.assertEqual("2", self.manual_remove.to_delete["101"][1].run_version)
        self.assertEqual("3", self.manual_remove.to_delete["101"][2].run_version)

    @patch("autoreduce_scripts.manual_operations.manual_remove.ManualRemove.validate_csv_input")
    @patch.object(builtins, "input")
    def test_multiple_versions_found_range_input_reversed(self, mock_input, mock_validate_csv):
        """
        Test: That the correct versions are deleted
        When: The user asks to delete a range of versions in reverse
        """
        self.manual_remove.to_delete["101"] = [self.run1, self.run2, self.run3]
        mock_input.return_value = "3-1"
        mock_validate_csv.return_value = (True, ["1", "2", "3"])
        self.manual_remove.multiple_versions_found("101")
        # We said to delete version 2 so it should be the only entry for that run number
        self.assertEqual(3, len(self.manual_remove.to_delete["101"]))
        self.assertEqual("1", self.manual_remove.to_delete["101"][0].run_version)
        self.assertEqual("2", self.manual_remove.to_delete["101"][1].run_version)
        self.assertEqual("3", self.manual_remove.to_delete["101"][2].run_version)

    def test_validate_csv_single_val(self):
        """
        Test: For expected validation result
        When: User input contains a single run
        """
        actual = self.manual_remove.validate_csv_input("1")
        self.assertEqual((True, [1]), actual)

    def test_validate_csv_single_val_invalid(self):
        """
        Test: For expected validation result (False, [])
        When: User input validation with single value that is invalid
        """
        actual = self.manual_remove.validate_csv_input("a")
        self.assertEqual((False, []), actual)

    def test_validate_csv_list(self):
        """
        Test: For expected validation result
        When: user input contains multiple runs
        """
        actual = self.manual_remove.validate_csv_input("1,2,3")
        self.assertEqual((True, [1, 2, 3]), actual)
        actual = self.manual_remove.validate_csv_input("1-3")
        self.assertEqual((True, [1, 2, 3]), actual)

        # bad input
        actual = self.manual_remove.validate_csv_input("1-2-1")
        self.assertEqual((False, []), actual)

    def test_validate_csv_invalid(self):
        """
        Test: For expected validation result (False, [])
        When: User input is invalid type and multiple
        """
        actual = self.manual_remove.validate_csv_input("t,e,s,t")
        self.assertEqual((False, []), actual)

    @patch("autoreduce_scripts.manual_operations.manual_remove.ManualRemove.find_run_versions_in_database")
    @patch("autoreduce_scripts.manual_operations.manual_remove.ManualRemove.process_results")
    @patch("autoreduce_scripts.manual_operations.manual_remove.ManualRemove.delete_records")
    @patch("autoreduce_scripts.manual_operations.manual_remove.get_run_range", return_value=range(1, 2))
    def test_main(self, mock_get_run_range, mock_delete, mock_process, mock_find):
        """
        Test: The correct control functions are called
        When: The main() function is called
        """
        main(instrument="GEM", first_run=1)
        mock_get_run_range.assert_called_once_with(1, last_run=None)
        mock_find.assert_called_once_with(1)
        mock_process.assert_called_once()
        mock_delete.assert_called_once()

    @patch("autoreduce_scripts.manual_operations.manual_remove.ManualRemove.find_run_versions_in_database")
    @patch("autoreduce_scripts.manual_operations.manual_remove.ManualRemove.process_results")
    @patch("autoreduce_scripts.manual_operations.manual_remove.ManualRemove.delete_records")
    @patch("autoreduce_scripts.manual_operations.manual_remove.get_run_range")
    def test_main_with_list(self, mock_get_run_range: Mock, mock_delete: Mock, mock_process: Mock, mock_find: Mock):
        """
        Test: The correct control functions are called
        When: The main() function is called
        """
        main(instrument="GEM", first_run=[1, 2, 3])
        mock_get_run_range.assert_not_called()
        mock_find.assert_has_calls([mock.call(1), mock.call(2), mock.call(3)])
        assert mock_process.call_count == 3
        assert mock_delete.call_count == 3

    @patch("autoreduce_scripts.manual_operations.manual_remove.ManualRemove.find_run_versions_in_database")
    @patch("autoreduce_scripts.manual_operations.manual_remove.ManualRemove.process_results")
    @patch("autoreduce_scripts.manual_operations.manual_remove.ManualRemove.delete_records")
    @patch("autoreduce_scripts.manual_operations.manual_remove.user_input_check")
    @patch("autoreduce_scripts.manual_operations.manual_remove.get_run_range", return_value=range(1, 12))
    def test_main_range_greater_than_ten(self, mock_get_run_range, mock_uic, mock_delete, mock_process, mock_find):
        """
        Test: The correct control functions are called including handle_input for many runs
        When: The main() function is called
        """
        main(instrument="GEM", first_run=1, last_run=11)
        mock_get_run_range.assert_called_with(1, last_run=11)
        mock_uic.assert_called_with("GEM", range(1, 12))
        mock_find.assert_called()
        mock_process.assert_called()
        mock_delete.assert_called()

    @patch("autoreduce_scripts.manual_operations.manual_remove.ManualRemove.find_run_versions_in_database")
    @patch("autoreduce_scripts.manual_operations.manual_remove.ManualRemove.process_results")
    @patch("autoreduce_scripts.manual_operations.manual_remove.ManualRemove.delete_records")
    @patch("autoreduce_scripts.manual_operations.manual_remove.get_run_range", return_value=range(1, 10))
    def test_main_range_less_than_ten(self, mock_get_run_range, mock_delete, mock_process, mock_find):
        """
        Test: The correct control functions are called including handle_input for many runs
        When: The main() function is called
        """
        return_value = main(instrument="GEM", first_run=1, last_run=9)

        assert len(return_value) == 9
        mock_get_run_range.assert_called_with(1, last_run=9)
        mock_find.assert_called()
        mock_process.assert_called()
        mock_delete.assert_called()

    @patch("autoreduce_scripts.manual_operations.manual_remove.ManualRemove.find_run_versions_in_database")
    @patch("autoreduce_scripts.manual_operations.manual_remove.ManualRemove.process_results")
    @patch("autoreduce_scripts.manual_operations.manual_remove.ManualRemove.delete_records")
    def test_run(self, mock_delete, mock_process, mock_find):
        """
        Test: The correct control functions are called
        When: The run() function is called
        """
        remove("GEM", 1, False, False)
        mock_find.assert_called_once_with(1)
        mock_process.assert_called_once()
        mock_delete.assert_called_once()

    def test_delete_data_location(self):
        """
        Test: The correct query is run and associated records are removed
        When: Calling delete_data_location
        """
        with patch("autoreduce_scripts.manual_operations.manual_remove.DataLocation") as data_location:
            self.manual_remove.delete_data_location(123)
            data_location.objects.filter.assert_called_once_with(reduction_run_id=123)

    def test_delete_reduction_location(self):
        """
        Test: The correct query is run and associated records are removed
        When: Calling delete_reduction_location
        """
        with patch("autoreduce_scripts.manual_operations.manual_remove.ReductionLocation") as red_location:
            self.manual_remove.delete_reduction_location(123)
            red_location.objects.filter.assert_called_once_with(reduction_run_id=123)

    def test_delete_reduction_run_location(self):
        """
        Test: The correct query is run and associated records are removed
        When: Calling delete_reduction_run_location
        """
        with patch("autoreduce_scripts.manual_operations.manual_remove.ReductionRun") as red_run:
            self.manual_remove.delete_reduction_run(123)
            red_run.objects.filter.assert_called_once_with(id=123)

    def test_delete_records(self):
        """
        Test: Record deletion is attempted directly via the ReducedRun.delete method
        When: delete_records is called while self.to_delete is populated
        """
        mock_record = Mock()
        mock_record.id = 12
        self.manual_remove.to_delete = {"1234": [mock_record]}
        self.manual_remove.delete_records()
        mock_record.delete.assert_called_once()

    @patch.multiple("autoreduce_scripts.manual_operations.manual_remove.ManualRemove",
                    delete_reduction_location=DEFAULT,
                    delete_data_location=DEFAULT,
                    delete_reduction_run=DEFAULT)
    def test_delete_records_integrity_err_reverts_to_manual(self, delete_reduction_location, delete_data_location,
                                                            delete_reduction_run):
        """
        Test: If the ReducedRun.delete fails with Integrity Error
              the code reverts back to the manual deletion of each table entry
        When: delete_records is called while self.to_delete is populated
        """
        mock_record = Mock()
        mock_record.id = 12
        mock_record.delete.side_effect = IntegrityError
        self.manual_remove.to_delete = {"1234": [mock_record]}

        self.manual_remove.delete_records()

        delete_reduction_location.assert_called_once_with(12)
        delete_data_location.assert_called_once_with(12)
        delete_reduction_run.assert_called_once_with(12)

    def test_user_input_check(self):
        """
        Test: user_input_check() returns True of false
        When: Based on user input if range of runs to remove is larger than 10
        """
        with patch.object(builtins, "input", lambda _: "Y"):
            user_input_check(range(1, 11), "GEM")

        inputs = ["N", "Y"]
        with patch.object(builtins, "input", lambda _: inputs.pop()):
            user_input_check(range(1, 11), "GEM")

class TestManualRemoveBatchRuns(TestCase):
    """
    Test manual_remove.py
    """
    fixtures = ["status_fixture"]

    def setUp(self):
        self.manual_remove = ManualRemove(instrument="ARMI")
        # Setup database connection so it is possible to use
        # ReductionRun objects with valid meta data
        self.experiment, self.instrument = create_experiment_and_instrument()

        self.batch_run1 = make_test_batch_run(self.experiment, self.instrument, "1")
        self.batch_run2 = make_test_batch_run(self.experiment, self.instrument, "2")
        self.batch_run3 = make_test_batch_run(self.experiment, self.instrument, "3")

    @patch("autoreduce_scripts.manual_operations.manual_remove.ManualRemove.find_run_versions_in_database")
    @patch("autoreduce_scripts.manual_operations.manual_remove.ManualRemove.process_results")
    @patch("autoreduce_scripts.manual_operations.manual_remove.ManualRemove.delete_records")
    def test_remove_with_mocks(self, mock_delete, mock_process, mock_find):
        """
        Test: The correct control functions are called
        When: The remove() function is called
        """
        remove("GEM", self.batch_run1.pk, False, batch_run=True)
        mock_find.assert_not_called()
        mock_process.assert_called_once()
        mock_delete.assert_called_once()

    @patch("autoreduce_scripts.manual_operations.manual_remove.ManualRemove.find_run_versions_in_database")
    def test_remove_without_mocks(self, mock_find):
        """
        Test: The ReductionRun object is removed from the database
        When: The remove() function is called
        """
        pks = [self.batch_run1.pk, self.batch_run2.pk, self.batch_run3.pk]
        for pk in pks:
            remove("GEM", pk, False, batch_run=True)
            mock_find.assert_not_called()
            with self.assertRaises(ReductionRun.DoesNotExist):
                ReductionRun.objects.get(pk=pk)

    def test_find_batch_run(self):
        """
        Test: find_batch_run finds the correct run object, which should equal the one from setUp
        When: find_batch_run is called
        """
        assert self.manual_remove.find_batch_run(self.batch_run1.pk)[0] == self.batch_run1


import logging
from datetime import datetime
from datetime import timedelta
import pdb
from . import enumerations
from multiprocessing import Pool
from multiprocessing.dummy import Pool as ThreadPool

"""Module:

Class: station

    Methods:
        __init__
        get_obs
        add_record
        get_region
        get_epoch_time
        get_season
        add_empty_record
        parse_datetime_to_hour
        check_duplicate_time
        is_closer_time
        is_auto
        is_AO2_or_MANU
        is_canadian
        is_russian
        __str__
        __repr__
"""

MISSING_VALUE = 9999

class station:

    def __init__(self, name):

        self.name = name
        self.long_name = None
        # Where the keys are the METAR names of the observations,
        # and the values are an array representing the hourly data
        self.observations = {}
        # Hours are represented YYYYMMDDHH
        self.hours = []
        self.empty_obs = True

    def get_obs(self, obs_str):
        """Returns and array of the given observation string. e.g. 'TMP' would
        return the temperature array of the station.
        """

        obs_str = obs_str.upper()
        obs_arr = self.observations.get(obs_str, None)
        if obs_arr is not None:
            return obs_arr
        # TODO check for alternate names

        return obs_arr

    def add_record(self, observation_keys, values, hour):
        """Appends to the data for a given time period
        to the predictor dictionary for this station.
        'observation_keys' is an array of
        all observations keys e.g. 'TMP', in METAR file.
        'values' is a string list
        'hour' is the hour of this observation
        'new' is boolean indicating it's the first record
        """

        if self.empty_obs:
            for ob in observation_keys:
                self.observations[ob] = []
            self.empty_obs = False

        remove_dupe = False
        if values[0] != 'UNKN':
            if self.check_duplicate_time(hour):
                if self.is_closer_time(values, observation_keys):
                    # Exit this function, because existing record was closer
                    return
                remove_dupe = True
            else:
                self.hours.append(hour)

        for ob, datum in zip(observation_keys, values):
            datum = datum.strip()
            # Assigns the function that will handle special-case string observations.
            # Returns None if enumeration is not necessary.
            datum = enumerations.get_enumeration_function(ob)(datum)
            if datum == '':
                datum = MISSING_VALUE
            if remove_dupe:
                self.observations[ob][-1] = datum
            else:
                self.observations[ob].append(datum)

    def get_region(self):
        """Returns this station's region based on its lat/lon.
        Return values will be one of the following:
        'southeast'
        'southwest'
        'northeast'
        'northwest'
        'farnorth'
        """

        if "LAT" in self.observations and "LON" in self.observations:
            # Choose the first lat and lon
            lat = self.observations["LAT"][0]
            lon = self.observations["LON"][0]
            if lat > 50:
                return "farnorth"
            if lat > 35:
                prefix = "north"
            else:
                prefix = "south"
            if lon > 100:
                suffix = "west"
            else:
                suffix = "east"
            return prefix + suffix

        return None

    def get_epoch_time(self):
        """Return hours array as seconds since the epoch."""

        epoch = datetime.utcfromtimestamp(0)

        def unix_time(dt): return (dt - epoch).total_seconds()
        return [unix_time(self.parse_hour_to_datetime(i)) for i in self.hours]

    def get_season(self, string_return=True):
        """Returns the season as a string, or
        if specified by 'string_return=False' a number, where,
        'spring' : 0
        'summer' : 1
        'fall'   : 2
        'winter' : 3
        Assume that the duration of a station record will
        never be more than about a month .
        """

        # Get a middle date in the record.
        date = self.hours[int(len(self.hours)/2)]
        month = int(date[4:6])

        if month >= 3 and month <= 5:
            if string_return:
                return "spring"
            return 0

        if month >= 6 and month <= 8:
            if string_return:
                return "summer"
            return 1

        if month >= 9 and month <= 11:
            if string_return:
                return "fall"
            return 2

        if month == 12 or month <= 2:
            if string_return:
                return "winter"
            return 3

    def add_empty_record(self, observation_keys, index, hour):
        """Takes in index for the hours object data field and the hour that
        should be inserted. This routine should be used when a station is not
        represented in a METAR file.
        This will give MISSING values to observations for the given hour.
        """

        if self.empty_obs:
            for ob in observation_keys:
                self.observations[ob] = []
            self.empty_obs = False

        if index == -1:
            for obs_name, obs_list in self.observations.items():
                obs_list.append(MISSING_VALUE)
            self.hours.append(hour)

        elif index >= 0:
            for obs_name, obs_list in self.observations.items():
                obs_list.insert(index, MISSING_VALUE)
            self.hours.insert(index, hour)

    def parse_datetime_to_hour(self, time):
        """Assumed that time is a datetime object.
        hours are represented YYYYMMDDHH
        """

        return str(time.year).zfill(4) + str(time.month).zfill(2) \
            + str(time.day).zfill(2) + str(time.hour).zfill(2)

    def parse_hour_to_datetime(self, time):
        """Assumed that time is in form YYYYMMDDHH, which is the format of the
        self.hours array.
        """

        year = int(time[:4])
        month = int(time[4:6])
        day = int(time[6:8])
        hour = int(time[8:10])

        return datetime(year, month, day, hour)

    def check_duplicate_time(self, cur_hour):
        """Given cur_hour, returns if it is a duplicate to the last entered time."""

        if self.hours:
            most_recent_hour = self.hours[-1]
            return cur_hour == most_recent_hour  # We've got dupes

        return False

    def is_closer_time(self, station_obs, predictors):
        """Returns a boolean based on whether the old station_obs is
        closer to 50 of the hour. MANU observations are selected over
        Automated observations. This function expects that the argument,
        station_obs, is from the same hourly record as the current last time.
        """

        # First check station type
        new_station_type = station_obs[predictors.index('TYPE')]
        old_station_type = self.observations['TYPE']
        old_station_type = old_station_type[len(old_station_type) - 1]

        if new_station_type == 'MANU' and old_station_type != 1:
            return False

        if new_station_type != 'MANU' and old_station_type == 1:
            return True

        new_time = station_obs[predictors.index('TIME')]
        old_time = self.observations['TIME']
        old_time = old_time[len(old_time) - 1]
        # extract the hour
        if isinstance(new_time,str): new_time = new_time.strip()[-2:]
        if isinstance(old_time,str): old_time = old_time.strip()[-2:]
        # cast to int
        new_time = int(new_time)
        old_time = int(old_time)
        if new_time < 30:
            new_time += 60
        if old_time < 30:
            old_time += 60

        return abs(old_time - 50) < abs(new_time - 50)

    def is_auto(self, i):
        """Return true if station is an automatic station."""

        type_arr = self.get_obs("TYPE")
        return type_arr[i] >= 2 and type_arr[i] <= 8

    def is_AO2_or_MANU(self, i):
        """return true if station is a manual station (MANU)
        or if AO2 or AO2A.
        """

        type_arr = self.get_obs("TYPE")
        return type_arr[i] >= 1 and type_arr[i] <= 3

    def is_canadian(self):

        return self.name[:1] == 'C'

    def is_russian(self):

        return self.name[:2] == 'UH' or self.name[:2] == 'UE'

    def __str__(self):

        return self.name

    __repr__ = __str__


from .utils import *

from .processor import Processor

class DarkflowSegmentProcessor(Processor):
    def __init__(self, camera, stride=1, threshold=0.1):
        self.tfnet = load_darkflow('dot-tracking', gpu=1.0, threshold=threshold)
        super().__init__(camera, ['segment'], stride)

    def segments(self, frame):
        return self._process_frame(frame)

    def _process_frame(self, frame):
        result = self.tfnet.return_predict(frame) #get a dict of detected items with labels and confidences.
        sorted_result = sorted(result, key=lambda x: x['confidence'], reverse=True)
        segments = [darkflow_to_rect(x) for x in sorted_result]
        return segments

    async def process_frame(self, frame, frame_id):
        return

    async def decorate_frame(self, frame, name):
        if name == 'segment':
            for s in self.segments(frame):
                draw_rectangle(frame, s, (255, 255, 0), 1)


from kivy.core.text import Label
from kivy.graphics import Rectangle
from kivy.graphics import Color

BORDER_SIZE = 0.25

def build_label(text):
        label = Label(font_size=12)
        label.text = text
        label.refresh()
        return (
            label,
            (float(label._size[0]),
            float(label._size[1])))

class Style(object):
    def __init__(self, text):
        self.outer_color = Color(0.0, 0.0, 0.0, 1.0)
        self.inner_color = Color(0.2, 0.2, 0.2, 1.0)
        self.text_color = Color(0.0, 0.0, 0.0, 1.0)
        self.outer_rect = Rectangle()
        self.inner_rect = Rectangle()
        label, size = build_label(text)
        self.label_size = size
        self.text_rect = Rectangle(texture=label.texture)

    def init(self, x, y, w, h, depth):
        self.inner_color.rgb = (depth, depth, depth)
        self.update(x, y, w, h)

    def update(self, x, y, w, h, depth=None):
        self.outer_rect.pos = (x, y)
        self.outer_rect.size = (w, h)
        self.inner_rect.pos = (x + BORDER_SIZE, y + BORDER_SIZE)
        self.inner_rect.size = (w - (BORDER_SIZE * 2.0), h - (BORDER_SIZE * 2.0))

        label_width, label_height = self.label_size
        if self.label_size[0] < w:
            self.text_rect.size = self.label_size
            width = label_width
            height = label_height
        else:
            scale_factor = w / label_width
            width = scale_factor * label_width
            height = scale_factor * label_height
            self.text_rect.size = (width, height)
        self.text_rect.pos = (
            x - ((width - w) / 2.0),
            y - ((height - h) / 2.0))

class NodeStyle(Style):
    pass

class LeafStyle(Style):
    pass

class Node(object):
    def __init__(self, name, path, parent):
        self.name = name
        self.path = path
        self.parent = parent
        self.children = {}

    def setdefault(self, name, path, parent):
        if name in self.children:
            return self.children[name]
        n = Node(name, path, parent)
        self.children[name] = n
        return n

    def add_instructions(self, canvas):
        canvas.add(self.style.outer_color)
        canvas.add(self.style.outer_rect)
        canvas.add(self.style.inner_color)
        canvas.add(self.style.inner_rect)
        canvas.add(self.style.text_color)
        canvas.add(self.style.text_rect)

    def is_leaf(self):
        return bool(self.children)

    def build_style(self):
        self.style = LeafStyle(self.name)\
            if self.is_leaf()\
            else NodeStyle(self.name)

    def collide_point(self, x, y):
        rx, ry = self.style.outer_rect.pos
        rw, rh = self.style.outer_rect.size
        return (rx < x <= (rx + rw)) and (ry < y <= (ry + rh))

    def check_highlight(self, mouse_x, mouse_y):
        g, b = self.style.depth_color[1:3]
        self.style.inner_color.rgba = (
            (1.0, g, b, 1.0)
            if self.collide_point(mouse_x, mouse_y)
            else self.style.depth_color)
        return True

    def center(self):
        x, y = self.style.outer_rect.pos
        w, h = self.style.outer_rect.size
        return (x + w / 2.0, y + h / 2.0)


a= [['happy','BirtHday','to','yoU'],['this','Is','MY','BdaY','Month'],['wish','me','HappY','BirtHday']]

def upper(a):
    b=[]
    c=[]
    d=[]
    e=[]
    for l in a:
        if l==a[0]:
            for l1 in l:
                b.append(l1.upper())
            e.append(b)
        elif l==a[1]:
            for l1 in l:
                c.append(l1.upper())
            e.append(c)
        elif l==a[2]:
            for l1 in l:
                d.append(l1.upper())
            e.append(d)
        else:
            pass
    print(e)

upper(a)


from typing import List

class Solution:
    def wiggleSort(self, nums: List[int]) -> None:
        """
        Do not return anything, modify nums in-place instead.

        Directly sort the nums and swap them

        https://leetcode.com/problems/wiggle-sort-ii/discuss/77678/3-lines-Python-with-Explanation-Proof
        https://leetcode.com/problems/wiggle-sort-ii/discuss/155764/Python-3-lines-simplest-solution-for-everyone-to-understand
        """
        nums.sort()
        half = len(nums[::2]) - 1
        nums[::2], nums[1::2] = nums[half::-1], nums[:half:-1]

        # tmp = sorted(nums)
        # nums[0::2] = tmp[:(len(tmp)+1)//2][::-1]
        # nums[1::2] = tmp[(len(tmp)+1)//2:][::-1]

        # arr = sorted(nums)
        # for i in range(1, len(nums), 2):
        #     nums[i] = arr.pop()
        # for i in range(0, len(nums), 2):
        #     nums[i] = arr.pop()

# Runtime: 164 ms, faster than 78.30% of Python3 online submissions for Wiggle Sort II.
# Memory Usage: 17.2 MB, less than 47.34% of Python3 online submissions for Wiggle Sort II.


import json
import os

import requests
from django.http import HttpResponseRedirect
from django.shortcuts import render, redirect
from django.views.generic import TemplateView

from .connectors import fyle

CLIENT_ID = os.environ.get("CLIENT_ID")
CLIENT_SECRET = os.environ.get("CLIENT_SECRET")
BASE_URL = os.environ.get("BASE_URL")

class HomeView(TemplateView):
    def get(self, request):
        return render(request, 'welcome.html')

    def post(self, request):
        return redirect('profile/')

class ProfileView(TemplateView):
    def get(self, request):
        code = request.GET.get('code')
        error = request.GET.get('error')
        if code:
            return self.get_profile_details(self.request)
        elif error == "access_denied":
            return redirect('/login')
        return self.authorize(self.request)

    def authorize(self, request):
        global BASE_URL
        global CLIENT_ID
        redirect_uri = "{0}{1}/profile".format("http://", request.get_host())
        authorize_url = "{0}/app/main/#/oauth/authorize?client_id={1}&redirect_uri={2}" \
                        "&response_type=code&state=ajsfbjak".format(
            BASE_URL, CLIENT_ID, redirect_uri)
        return HttpResponseRedirect(authorize_url)

    def get_profile_details(self, request):
        global CLIENT_SECRET
        global CLIENT_ID
        global BASE_URL
        code = request.GET.get('code')
        error = request.GET.get('error')
        token_url = '{0}/api/oauth/token'.format(BASE_URL)
        if code and error is None:
            json_response = requests.post(token_url, data={"grant_type": "authorization_code",
                                                           "client_id": CLIENT_ID,
                                                           "client_secret": CLIENT_SECRET,
                                                           "code": code})
            data = json.loads(json_response.text)
            refresh_token = data.get("refresh_token")
            fyle_connection = fyle.FyleConnector(refresh_token)
            emp_details = fyle_connection.extract_employee_details()
            return render(self.request, 'profile.html', context={'emp_data': emp_details})
        return redirect('/login')


import argparse
import code
import curses
import itertools
import logging
import logging.handlers
import os
import socket
import subprocess
import sys
import unittest
import unittest.signals

import qubes.tests
import qubes.api.admin

class CursesColor(dict):
    colors = (
        'black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white')
    attrs = {
        'bold': 'bold', 'normal': 'sgr0'}
    def __init__(self):
        super(CursesColor, self).__init__()
        self.has_colors = False
        try:
            curses.setupterm()
            self.has_colors = True
        except curses.error:
            return

    def __missing__(self, key):
        # pylint: disable=unused-argument
        if not self.has_colors:
            return ''

        try:
            value = curses.tigetstr(self.attrs[key])
        except KeyError:
            try:
                value = curses.tparm(
                    curses.tigetstr('setaf'), self.colors.index(key))
            except ValueError:
                return ''

        value = value.decode()
        self[key] = value
        return value

class QubesTestResult(unittest.TestResult):
    '''A test result class that can print colourful text results to a stream.

    Used by TextTestRunner. This is a lightly rewritten unittest.TextTestResult.
    '''

    separator1 = unittest.TextTestResult.separator1
    separator2 = unittest.TextTestResult.separator2

    def __init__(self, stream, descriptions, verbosity):
        super(QubesTestResult, self).__init__(stream, descriptions, verbosity)
        self.stream = stream
        self.showAll = verbosity > 1 # pylint: disable=invalid-name
        self.dots = verbosity == 1
        self.descriptions = descriptions

        self.color = CursesColor()
        self.hostname = socket.gethostname()

        self.log = logging.getLogger('qubes.tests')

    def _fmtexc(self, err):
        if str(err[1]):
            return '{color[bold]}{}:{color[normal]} {!s}'.format(
                err[0].__name__, err[1], color=self.color)
        else:
            return '{color[bold]}{}{color[normal]}'.format(
                err[0].__name__, color=self.color)

    def get_log(self, test):
        try:
            return test.log
        except AttributeError:
            return self.log

    def getDescription(self, test): # pylint: disable=invalid-name
        teststr = str(test).split('/')
        for i in range(-2, 0):
            try:
                fullname = teststr[i].split('_', 2)
            except IndexError:
                continue
            fullname[-1] = '{color[bold]}{}{color[normal]}'.format(
                fullname[-1], color=self.color)
            teststr[i] = '_'.join(fullname)
        teststr = '/'.join(teststr)

        doc_first_line = test.shortDescription()
        if self.descriptions and doc_first_line:
            return '\n'.join((teststr, '  {}'.format(
                doc_first_line, color=self.color)))
        else:
            return teststr

    def startTest(self, test): # pylint: disable=invalid-name
        super(QubesTestResult, self).startTest(test)
        self.get_log(test).critical('started')
        if self.showAll:
            if not qubes.tests.in_git:
                self.stream.write('{}: '.format(self.hostname))
            self.stream.write(self.getDescription(test))
            self.stream.write(' ... ')
            self.stream.flush()

    def addSuccess(self, test): # pylint: disable=invalid-name
        super(QubesTestResult, self).addSuccess(test)
        self.get_log(test).warning('ok')
        if self.showAll:
            self.stream.writeln('{color[green]}ok{color[normal]}'.format(
                color=self.color))
        elif self.dots:
            self.stream.write('.')
            self.stream.flush()

    def addError(self, test, err): # pylint: disable=invalid-name
        super(QubesTestResult, self).addError(test, err)
        self.get_log(test).critical(
            'ERROR ({err[0].__name__}: {err[1]!r})'.format(err=err))
        if self.showAll:
            self.stream.writeln(
                '{color[red]}{color[bold]}ERROR{color[normal]} ({})'.format(
                    self._fmtexc(err), color=self.color))
        elif self.dots:
            self.stream.write(
                '{color[red]}{color[bold]}E{color[normal]}'.format(
                    color=self.color))
            self.stream.flush()

    def addFailure(self, test, err): # pylint: disable=invalid-name
        super(QubesTestResult, self).addFailure(test, err)
        self.get_log(test).error(
            'FAIL ({err[0].__name__}: {err[1]!r})'.format(err=err))
        if self.showAll:
            self.stream.writeln('{color[red]}FAIL{color[normal]}'.format(
                color=self.color))
        elif self.dots:
            self.stream.write('{color[red]}F{color[normal]}'.format(
                color=self.color))
            self.stream.flush()

    def addSkip(self, test, reason): # pylint: disable=invalid-name
        super(QubesTestResult, self).addSkip(test, reason)
        self.get_log(test).warning('skipped ({})'.format(reason))
        if self.showAll:
            self.stream.writeln(
                '{color[cyan]}skipped{color[normal]} ({})'.format(
                    reason, color=self.color))
        elif self.dots:
            self.stream.write('{color[cyan]}s{color[normal]}'.format(
                color=self.color))
            self.stream.flush()

    def addExpectedFailure(self, test, err): # pylint: disable=invalid-name
        super(QubesTestResult, self).addExpectedFailure(test, err)
        self.get_log(test).warning('expected failure')
        if self.showAll:
            self.stream.writeln(
                '{color[yellow]}expected failure{color[normal]}'.format(
                    color=self.color))
        elif self.dots:
            self.stream.write('{color[yellow]}x{color[normal]}'.format(
                color=self.color))
            self.stream.flush()

    def addUnexpectedSuccess(self, test): # pylint: disable=invalid-name
        super(QubesTestResult, self).addUnexpectedSuccess(test)
        self.get_log(test).error('unexpected success')
        if self.showAll:
            self.stream.writeln(
                '{color[yellow]}{color[bold]}unexpected success'
                    '{color[normal]}'.format(color=self.color))
        elif self.dots:
            self.stream.write(
                '{color[yellow]}{color[bold]}u{color[normal]}'.format(
                    color=self.color))
            self.stream.flush()

    def printErrors(self): # pylint: disable=invalid-name
        if self.dots or self.showAll:
            self.stream.writeln()
        self.printErrorList(
            '{color[red]}{color[bold]}ERROR{color[normal]}'.format(
                color=self.color),
            self.errors)
        self.printErrorList(
            '{color[red]}FAIL{color[normal]}'.format(
                color=self.color),
            self.failures)
        self.printErrorList(
            '{color[yellow]}EXPECTED{color[normal]}'.format(
                color=self.color),
            self.expectedFailures)

    def printErrorList(self, flavour, errors): # pylint: disable=invalid-name
        for test, err in errors:
            self.stream.writeln(self.separator1)
            self.stream.writeln('%s: %s' % (flavour, self.getDescription(test)))
            self.stream.writeln(self.separator2)
            self.stream.writeln('%s' % err)

def demo(verbosity=2):
    class TC_00_Demo(qubes.tests.QubesTestCase):
        '''Demo class'''
        def test_0_success(self):
            '''Demo test (success)'''
            pass
        def test_1_error(self):
            '''Demo test (error)'''
            raise Exception()
        def test_2_failure(self):
            '''Demo test (failure)'''
            self.fail('boo')
        def test_3_skip(self):
            '''Demo test (skipped by call to self.skipTest())'''
            self.skipTest('skip')
        @unittest.skip(None)
        def test_4_skip_decorator(self):
            '''Demo test (skipped by decorator)'''
            pass
        @unittest.expectedFailure
        def test_5_expected_failure(self):
            '''Demo test (expected failure)'''
            self.fail()
        @unittest.expectedFailure
        def test_6_unexpected_success(self):
            '''Demo test (unexpected success)'''
            pass

    suite = unittest.TestLoader().loadTestsFromTestCase(TC_00_Demo)
    runner = unittest.TextTestRunner(stream=sys.stdout, verbosity=verbosity)
    runner.resultclass = QubesTestResult
    return runner.run(suite).wasSuccessful()

parser = argparse.ArgumentParser(
    epilog='''When running only specific tests, write their names like in log,
        in format: MODULE+"/"+CLASS+"/"+FUNCTION. MODULE should omit initial
        "qubes.tests.". Example: basic/TC_00_Basic/test_000_create''')

parser.add_argument('--verbose', '-v',
    action='count',
    help='increase console verbosity level')
parser.add_argument('--quiet', '-q',
    action='count',
    help='decrease console verbosity level')

parser.add_argument('--list', '-l',
    action='store_true', dest='list',
    help='list all available tests and exit')

parser.add_argument('--failfast', '-f',
    action='store_true', dest='failfast',
    help='stop on the first fail, error or unexpected success')
parser.add_argument('--no-failfast',
    action='store_false', dest='failfast',
    help='disable --failfast')

# pylint: disable=protected-access
try:
    name_to_level = logging._nameToLevel
except AttributeError:
    name_to_level = logging._levelNames
parser.add_argument('--loglevel', '-L', metavar='LEVEL',
    action='store', choices=tuple(k
        for k in sorted(name_to_level.keys(),
            key=lambda x: name_to_level[x])
        if isinstance(k, str)),
    help='logging level for file and syslog forwarding '
        '(one of: %(choices)s; default: %(default)s)')
del name_to_level
# pylint: enable=protected-access

parser.add_argument('--logfile', '-o', metavar='FILE',
    action='store',
    help='if set, test run will be also logged to file')

parser.add_argument('--kmsg', '--very-brave-or-very-stupid',
    action='store_true', dest='kmsg',
    help='log most important things to kernel ring-buffer')
parser.add_argument('--no-kmsg', '--i-am-smarter-than-kay-sievers',
    action='store_false', dest='kmsg',
    help='do not abuse kernel ring-buffer')

parser.add_argument('--allow-running-along-qubesd',
    action='store_true', default=False,
    help='allow running in parallel with qubesd;'
        ' this is DANGEROUS and WILL RESULT IN INCONSISTENT SYSTEM STATE')

parser.add_argument('--break-to-repl',
    action='store_true', default=False,
    help='break to REPL after tests')

parser.add_argument('names', metavar='TESTNAME',
    action='store', nargs='*',
    help='list of tests to run named like in description '
        '(default: run all tests)')

parser.set_defaults(
    failfast=False,
    loglevel='DEBUG',
    logfile=None,
    kmsg=False,
    verbose=2,
    quiet=0)

def list_test_cases(suite):
    for test in suite:
        if isinstance(test, unittest.TestSuite):
            #yield from
            for i in list_test_cases(test):
                yield i
        else:
            yield test

def main(args=None):
    args = parser.parse_args(args)

    suite = unittest.TestSuite()
    loader = unittest.TestLoader()

    if args.names:
        alltests = loader.loadTestsFromName('qubes.tests')
        for name in args.names:
            suite.addTests(
                [test for test in list_test_cases(alltests)
                 if str(test).startswith(name)])
    else:
        suite.addTests(loader.loadTestsFromName('qubes.tests'))

    if args.list:
        for test in list_test_cases(suite):
            print(str(test)) # pylint: disable=superfluous-parens
        return True

    logging.root.setLevel(args.loglevel)

    if args.logfile is not None:
        ha_file = logging.FileHandler(
            os.path.join(os.environ['HOME'], args.logfile))
        ha_file.setFormatter(
            logging.Formatter('%(asctime)s %(name)s[%(process)d]: %(message)s'))
        logging.root.addHandler(ha_file)

    if args.kmsg:
        try:
            subprocess.check_call(('sudo', 'chmod', '666', '/dev/kmsg'))
        except subprocess.CalledProcessError:
            parser.error('could not chmod /dev/kmsg')
        else:
            ha_kmsg = logging.FileHandler('/dev/kmsg', 'w')
            ha_kmsg.setFormatter(
                logging.Formatter('%(name)s[%(process)d]: %(message)s'))
            ha_kmsg.setLevel(logging.CRITICAL)
            logging.root.addHandler(ha_kmsg)

    if not args.allow_running_along_qubesd \
    and os.path.exists(qubes.api.admin.QubesAdminAPI.SOCKNAME):
        parser.error('refusing to run until qubesd is disabled')

    runner = unittest.TextTestRunner(stream=sys.stdout,
        verbosity=(args.verbose-args.quiet),
        failfast=args.failfast)
    unittest.signals.installHandler()
    runner.resultclass = QubesTestResult
    result = runner.run(suite)

    if args.break_to_repl:
        code.interact(local=locals())

    return result.wasSuccessful()

if __name__ == '__main__':
    sys.exit(not main())


_errorScoreMap = {')': 3, ']': 57, '}': 1197, '>': 25137}
_completionScoreMap = {'(': 1, '[': 2, '{': 3, '<': 4}

def getErrorScore(line):
    stack = []
    for ch in line:
        if ch in ['(', '[', '{', '<']:
            stack.append(ch)
        elif (len(stack) == 0 and ch in [')', ']', '}', '>'])\
                or (ch == ')' and len(stack) > 0 and stack[-1] != '(')\
                or (ch == ']' and len(stack) > 0 and stack[-1] != '[')\
                or (ch == '}' and len(stack) > 0 and stack[-1] != '{')\
                or (ch == '>' and len(stack) > 0 and stack[-1] != '<'):
            return _errorScoreMap[ch]
        else:
            stack.pop()
    return 0

def getCompletionScore(line):
    stack = []
    for ch in line:
        if ch in ['(', '[', '{', '<']:
            stack.append(ch)
        else:
            stack.pop()
    score = 0
    while len(stack) > 0:
        score = score * 5 + _completionScoreMap[stack[-1]]
        stack.pop()
    return score

def getInput():
    lines = []
    with open('./Day10_Input.txt') as inputFile:
        for line in inputFile:
            line = line.rstrip()
            lines.append(line)
    return lines

lines = getInput()
incompleteLines = []

# Part 1
errorScore = 0
for line in lines:
    score = getErrorScore(line)
    if score == 0:
        incompleteLines.append(line)
    errorScore += score
print("Corruption Score: " + str(errorScore))

# part 2
completionScores = []
for line in incompleteLines:
    completionScores.append(getCompletionScore(line))
completionScores.sort()
midIndex = (len(completionScores) - 1) / 2
print("Middle Completion Score: " + str(completionScores[int(midIndex)]))


# basic.show_number(decin2) #M
# basic.show_number(decinx)  #L
def conv(num: number):
    x = 0
    while x < 8:
        if num / 2 - int(num / 2) != 0:
            list2[x] = 1
        else:
            list2[x] = 0
        num = int(num / 2)
        x += 1
    # set up screen
    basic.clear_screen()
    x = 1
    while x < 5:
        led.plot_brightness(x, 4, 5)
        x += 1
    x = 1
    while x < 5:
        led.plot_brightness(x, 2, 5)
        x += 1
    n = 0
    while n < 4:
        if list2[n] == 1:
            led.plot(4 - n, 4)
        n += 1
    n = 4
    while n < 8:
        if list2[n] == 1:
            led.plot(8 - n, 2)
        n += 1

def on_button_pressed_a():
    global hh, tt, uu, mm, ll, decin
    if decip == True and allset == False:
        if hhs == False:
            hh = hh + 1
            if hh == 3:
                hh = 0
            basic.show_number(hh)
        if hhs == True and tts == False:
            tt = tt + 1
            if hh == 2:
                troll = 6
            else:
                troll = 10
            if tt == troll:
                tt = 0
            basic.show_number(tt)
        if hhs == True and tts == True:
            uu = uu + 1
            if hh == 2:
                uroll = 6
            else:
                uroll = 10
            if uu == uroll:
                uu = 0
            basic.show_number(uu)
    if decip == False:
        # if mms:
        # basic.show_string("true")
        if mms == False:
            mm = mm + 1
            if mm == 16:
                mm = 0
            basic.show_string("" + (hexa[mm]))
        if mms and lls == False:
            # asic.show_string("z")
            ll = ll + 1
            if ll == 16:
                ll = 0
            basic.show_string("" + (hexa[ll]))
    if allset:
        decin = decin + 1
        if decin > 255:
            decin = 255
        # basic.show_number(decin)
        convx(decin)
        conv(decin)
input.on_button_pressed(Button.A, on_button_pressed_a)

def convx(dex: number):
    global decin2, decinx
    decin2 = int(dex / 16)
    decinx = dex - decin2 * 16

def on_button_pressed_ab():
    basic.clear_screen()
    basic.show_number(decin)
    # show Dec
    basic.show_string("=")
    convx(decin)
    basic.show_string("" + (hexa[decin2]))
    # show Hex most sig
    basic.show_string(":")
    basic.show_string("" + (hexa[decinx]))
    # show Hex least sig
    conv(decin)
input.on_button_pressed(Button.AB, on_button_pressed_ab)

def on_button_pressed_b():
    global decin, uus, tts, hhs, allset, lls, mms
    if allset == True:
        # basic.show_string("allset =t")
        decin = decin - 1
        if decin < 0:
            decin = 0
        # basic.show_number(decin)
        convx(decin)
        conv(decin)
    if decip == True and allset == False:
        if hhs == True and tts == True:
            uus = True
        if hhs == True and tts == False:
            tts = True
            basic.show_string("U")
        if hhs == False:
            hhs = True
            basic.show_string("T")
        if hhs == True and tts == True and uus == True and decip == True:
            allset = True
            decin = hh * 100 + tt * 10 + uu
            # +1  #1 added b pressed takes 1 away
            conv(decin)
    if decip == False and allset == False:
        # Hex in
        if mms == True:
            lls = True
        if mms == False and lls == False:
            mms = True
            basic.show_string("L")
        if mms and lls:
            # basic.show_number(mm)
            # basic.show_string(":")
            # basic.show_number(ll)
            decin = mm * 16 + ll
            # basic.show_number(decin)
            convx(decin)
            conv(decin)
            allset = True
input.on_button_pressed(Button.B, on_button_pressed_b)

uus = False
decinx = 0
decin2 = 0
lls = False
mms = False
tts = False
hhs = False
allset = False
hexa: List[str] = []
uu = 0
tt = 0
hh = 0
decin = 0
ll = 0
mm = 0
selected = False
h = 0
hexip = False
if selected == False:
    if input.button_is_pressed(Button.B):
        basic.show_string("M")
        decip = False
    else:
        basic.show_string("H")
        decip = True
    selected = True
mm = -1
ll = -1
selected = False
decip
current = decin
hh = -1
tt = -1
uu = -1
list2 = [0, 0, 0, 0, 0, 0, 0, 0, 0]
hexa = ["0",
    "1",
    "2",
    "3",
    "4",
    "5",
    "6",
    "7",
    "8",
    "9",
    "A",
    "B",
    "C",
    "D",
    "E",
    "F"]
hexnum = [128, 64, 32, 16, 8, 4, 2, 1]


import os
from django.contrib.gis.utils import LayerMapping
from .models import LowerGroundFloor
from .floordata import geojson

for feat in geojson['features']:
    geom = feat['properties']['geometry']
    lg = LowerGroundFloor(geom=geom, floor=-1)
    lg.save()

room_mapping = {
     'floor' : 'Floor',
     'geom' : 'LINESTRING',
}
przyziemie_room_shp = os.path.abspath(
    os.path.join(os.path.dirname(__file__), 'data', 'baselayer.shp'))

def run(verbose=True):
    try:
        verbose = bool(int(verbose))
    except Exception as err:
        info = 'ERROR: ENV.Verbose={!r:} invalid value. Using default False instead'
        print(info.format(verbose))
        verbose = False

    lm = LayerMapping(LowerGroundFloor, przyziemie_room_shp, room_mapping,
                      transform=False, encoding='iso-8859-1')

    lm.save(strict=True, verbose=verbose)


import functions
import pandas as pd
import os
import shutil

# Se obtiene la ruta de la tabla y del esquema
tableRout,schemaRout,columns,registerAmount,partitions,user = functions.getVariables()
#Se intenta borrar el archivo
if os.path.exists(tableRout):
    shutil.rmtree(tableRout)
# Se obtienen las columnas del esquema
columnsFromSchema = functions.getColumnsFromSchema(schemaRout)
# Se obtienen las columnas que tendrán valor por default
defaultColumns = functions.getDefaultColumns(columns,columnsFromSchema)
# Se obtienen los diccionarios con las tuplas columna / valores
columnsWithNotNullValues = functions.getValuesForColumns(columns,user)
columnsWithNullValues = functions.getValuesForNullColumns(defaultColumns,registerAmount)
# Se combinan ambos diccinarios
columnsWithValues = functions.mergeColumns(columnsWithNotNullValues,columnsWithNullValues)
df = pd.DataFrame(columnsWithValues)
df.to_parquet(path = tableRout, partition_cols=partitions)


import numpy as np
import random
import os
import os.path
import pickle
from pathlib import Path
from datetime import datetime

# Configuration file
from conf import read_conf

# Features
from file_loader import collate_fn
from file_loader import Dataset
from file_loader import fit_normalizer
from file_loader import read_feat_file
from file_loader import TorchStandardScaler
from sklearn import preprocessing

# Labels
from phone_mapping import get_label_encoder
from phone_mapping import phone_to_moa

# Training and testing data
from file_loader import read_feat_list

# PyTorch
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim

# Models
from net import LSTMLM
from net import initialize_weights
from net import initialize_network
from net import get_model_type

from tqdm import tqdm
import logging
import re
from shutil import copyfile

def get_device():
    """

    Returns:

    """
    if torch.cuda.is_available():
        device = torch.device("cuda:0")
    else:
        device = torch.device("cpu")

    return device

def train(model, optimizer, conf_dict, train_generator):
    """ Train a phoneme classification model

    Args:
        model (torch.nn.Module): neural network model
        optimizer (optim.SGD): pytorch optimizer
        conf_dict (dict): configuration parameters
        train_generator

    Returns:
        none

    """
    # Training mode
    model.train()

    # Get device
    device = get_device()

    # Initial states
    h0, c0 = model.init_state(conf_dict["batch_size"], conf_dict["num_hidden"])
    h0 = h0.to(device)
    c0 = c0.to(device)

    for _, y_batch, loss_mask in train_generator:
        optimizer.zero_grad()

        # Convert to tensor
        y_batch = torch.from_numpy(y_batch)

        # Get one-hot encoded vectors
        X_batch = (F.one_hot(y_batch, num_classes=conf_dict["num_classes"])).float()

        # Initial time step will be zeros
        X_batch = torch.cat((torch.zeros(conf_dict["batch_size"], 1, conf_dict["num_classes"]), X_batch), 1)

        # Move to GPU
        X_batch = X_batch.to(device)
        y_batch = y_batch.to(device)
        loss_mask = (torch.from_numpy(loss_mask)).to(device)

        # Get outputs
        train_outputs, (_, _) = model(X_batch[:, 0:-1, :], (h0, c0))
        train_outputs = train_outputs.permute(0, 2, 1)

        # Calculate loss
        # Note: Loss is set up so model tries to predict next phoneme in the sequence
        loss = torch.sum(loss_mask * F.nll_loss(train_outputs, y_batch, reduction='none'))/conf_dict["batch_size"]

        # Backpropagate
        loss.backward()

        # Update weights
        optimizer.step()

def validate(model, conf_dict, valid_generator):
    """ Validate phoneme classification model

    Args:
        model (torch.nn.Module): neural network model
        conf_dict (dict): configuration parameters
        valid_generator

    Returns:
        metrics (dict): loss and accuracy averaged across batches

    """

    metrics = {}

    # Running values
    num_frames = 0
    running_loss = 0

    # Get device
    device = get_device()

    # Evaluation mode
    model.eval()

    # Initial states
    h0, c0 = model.init_state(conf_dict["batch_size"], conf_dict["num_hidden"])
    h0 = h0.to(device)
    c0 = c0.to(device)

    with torch.no_grad():
        for _, y_val, loss_mask in valid_generator:
            # Convert to tensor
            y_val = torch.from_numpy(y_val)

            # Get one hot encoded vectors
            X_val = (F.one_hot(y_val, num_classes=conf_dict["num_classes"])).float()

            # Initial time step will be all zeros
            X_val = torch.cat((torch.zeros(conf_dict["batch_size"], 1, conf_dict["num_classes"]), X_val), 1)

            # Move to GPU
            X_val = X_val.to(device)
            y_val = y_val.to(device)
            loss_mask = (torch.from_numpy(loss_mask)).to(device)

            # Get outputs
            outputs, (_, _) = model(X_val[:, 0:-1, :], (h0, c0))
            outputs = outputs.permute(0, 2, 1)

            # Initial states
            #h_prev, c_prev = model.init_state(conf_dict["batch_size"], conf_dict["num_hidden"])
            #y_prev = torch.zeros(conf_dict["batch_size"], 1, conf_dict["num_classes"])
            #h_prev = h_prev.to(device)
            #c_prev = c_prev.to(device)
            #y_prev = y_prev.to(device)

            # Get outputs and predictions for each time step
            #outputs = torch.zeros(conf_dict["batch_size"], loss_mask.size()[1], conf_dict["num_classes"], dtype=torch.float32)
            #for t in range(0, loss_mask.size()[1]):
            #    y_prev, (h_prev, c_prev) = model(y_prev, (h_prev, c_prev))
            #    y_prev = (F.one_hot(torch.argmax(y_prev, dim=2), num_classes=conf_dict["num_classes"])).float()
            #    outputs[:, t, :] = y_prev
            #outputs = outputs.permute(0, 2, 1)

            # Calculate running loss and running number of frames
            running_loss += (torch.sum(loss_mask * F.nll_loss(outputs, y_val, reduction='none'))).item()
            num_frames += (torch.sum(loss_mask)).item()

    # Average loss over all batches
    metrics['loss'] = running_loss / num_frames

    return metrics

def train_and_validate(conf_file, num_models):
    """ Train and evaluate a phoneme classification model

    Args:
        conf_file (str): txt file containing model info
        num_models (int): number of instances to of model to train

    Returns
        none

    """
    # Read in conf file
    conf_dict = read_conf(conf_file)

    # Read in feature files
    train_list = read_feat_list(conf_dict["training"])
    valid_list = read_feat_list(conf_dict["development"])

    # Label encoder
    le = get_label_encoder(conf_dict["label_type"])

    for i in range(num_models):
        # Model directory - create new folder for each new instance of a model
        model_dir = os.path.join("lm", conf_dict["label_type"], (conf_file.split("/")[2]).replace(".txt", ""), "model" + str(i))
        while os.path.exists(model_dir):
            i += 1
            model_dir = os.path.join("lm", conf_dict["label_type"], (conf_file.split("/")[2]).replace(".txt", ""),
                                     "model" + str(i))
        Path(model_dir).mkdir(parents=True)

        # Copy config file
        copyfile(conf_file, (conf_file.replace("conf/"+conf_dict["label_type"]+"/", model_dir + "/")).replace(conf_file.split("/")[2], "conf.txt"))

        # Configure log file
        logging.basicConfig(filename=model_dir+"/log", filemode="w", level=logging.INFO)

        ########## CREATE MODEL ##########
        # Instantiate the network
        logging.info("Initializing model")
        model = LSTMLM(conf_dict)
        model.apply(initialize_weights)
        model.to(get_device())

        # Configure optimizer
        if conf_dict["optimizer"] == "sgd":
            optimizer = optim.SGD(model.parameters(), lr=conf_dict["learning_rate"], momentum=conf_dict["momentum"])
        elif conf_dict["optimizer"] == "adam":
            optimizer = optim.Adam(model.parameters(), lr=conf_dict["learning_rate"])

        ########## TRAINING ##########
        # Training curves
        training_curves = model_dir + "/training_curves"
        with open(training_curves, "w") as file_obj:
            file_obj.write("Epoch,Validation Loss\n")

        logging.info("Training")

        # Generators
        train_set = Dataset(train_list, conf_dict, le)
        train_generator = torch.utils.data.DataLoader(train_set, batch_size=conf_dict["batch_size"],
                                                      num_workers=4, collate_fn=collate_fn, shuffle=True)
        valid_set = Dataset(valid_list, conf_dict, le)
        valid_generator = torch.utils.data.DataLoader(valid_set, batch_size=conf_dict["batch_size"],
                                                      num_workers=4, collate_fn=collate_fn, shuffle=True)

        # Used to track minimum loss
        min_loss = float("inf")
        loss = []

        iterator = tqdm(range(conf_dict["num_epochs"]))

        for epoch in iterator:
            with open(training_curves, "a") as file_obj:
                current_time = datetime.now().strftime("%m/%d/%y %H:%M:%S")
                logging.info("Time: {}, Epoch: {}".format(current_time, epoch+1))

                # Train
                train(model, optimizer, conf_dict, train_generator)

                # Validate
                valid_metrics = validate(model, conf_dict, valid_generator)
                loss.append(valid_metrics["loss"])

                file_obj.write("{},{}\n".format(epoch+1, round(valid_metrics["loss"], 3)))

                # Track the best model and create checkpoint
                if valid_metrics['loss'] < min_loss:
                    min_loss = valid_metrics["loss"]
                    torch.save({'model': model.state_dict(), 'optimizer': optimizer.state_dict()},
                               model_dir + "/checkpoint.pt")

                # Stop early if accuracy does not improve over last 10 epochs
                if epoch >= 10:
                    if loss[-1] - loss[-11] >= 0:
                        logging.info("Detected minimum validation loss. Stopping early.")
                        iterator.close()
                        break

if __name__ == '__main__':
    # User inputs
    conf_file = "conf_lm/phoneme/LSTM_sim_rev_fftspec_ci.txt"
    num_models = 1

    # Train and validate model
    train_and_validate(conf_file, num_models)


hollydays = int(input())
workdays = 365 - hollydays

hollydays_playtime = hollydays * 127
workdays_playtime = workdays * 63
total_playtime_min = hollydays_playtime + workdays_playtime
difference_min = abs(total_playtime_min - 30000)
h = difference_min // 60
m = abs(difference_min % 60)

if total_playtime_min > 30000:
    print('Tom will run away')
    print(f'{h} hours and {m} minutes more for play')
else:
    print('Tom sleeps well')
    print(f'{h} hours and {m} minutes less for play')


from hoshino import Service
from hoshino.typing import CQEvent

import json, time, requests

sv = Service('clanrank', bundle='pcr公会战', help_='''
clanrank <公会名> [all] | 查看该公会最新或者全部的会战名次记录
'''.strip())

def second2time(second):
    return time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(second))

def get_default_data():
    request_url = 'https://service-kjcbcnmw-1254119946.gz.apigw.tencentcs.com//default'
    request_headers = {
            'Accept': 'application/json, text/javascript, */*; q=0.01',
            'Accept-Language': 'zh-CN,zh;q=0.9',
            'Connection': 'keep-alive',
            'Host': 'service-kjcbcnmw-1254119946.gz.apigw.tencentcs.com',
            'Origin': 'https://kengxxiao.github.io',
            'Referer': 'https://kengxxiao.github.io/Kyouka/',
            'Sec-Fetch-Dest': 'empty',
            'Sec-Fetch-Mode': 'cors',
            'Sec-Fetch-Site': 'cross-site',
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36',
            }
    response = requests.get(url=request_url, headers=request_headers)
    return response.text

def get_clan_data(history, clanName):
    request_url = 'https://service-kjcbcnmw-1254119946.gz.apigw.tencentcs.com//name/0'
    payload_data = json.dumps({'history': history, 'clanName': clanName,})
    request_headers = {
            'Accept': 'application/json, text/javascript, */*; q=0.01',
            #'Accept-Encoding': 'gzip, deflate, br',         加上这行会导致响应文本乱码
            'Accept-Language': 'zh-CN,zh;q=0.9',
            'Connection': 'keep-alive',
            'Content-Length': '48',
            'Content-Type': 'application/json',
            'Host': 'service-kjcbcnmw-1254119946.gz.apigw.tencentcs.com',
            'Origin': 'https://kengxxiao.github.io',
            'Referer': 'https://kengxxiao.github.io/Kyouka/',
            'Sec-Fetch-Dest': 'empty',
            'Sec-Fetch-Mode': 'cors',
            'Sec-Fetch-Site': 'cross-site',
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36',
            }
    response = requests.session().post(url=request_url, data=payload_data, headers=request_headers)
    return response.text

@sv.on_prefix('clanrank')
async def search_clanrank(bot, ev: CQEvent):
    try:
        s = ev.message.extract_plain_text().split(' ')
        if not ((len(s)==1 and s[0]!='') or (len(s)==2 and s[1]=='all')):
            await bot.send(ev, '参数错误，请重试')
            return
        clan_name = s[0]
        if len(s) == 1:
            clan_data_dict = json.loads(get_clan_data(0, clan_name))
            clan_data = clan_data_dict['data']
            if len(clan_data)!=0 and clan_data[0]['clan_name']==clan_name:
                rank = clan_data[0]['rank']
                ts = clan_data_dict['ts']
                msg_head = f'{clan_name}公会最新的会战名次为:\n'
                msg_part = f'{rank}名, 记录时间: {second2time(ts)}'
            else:
                await bot.send(ev, f'未找到{clan_name}公会的最新名次')
                return
        else:
            default_data_dict = json.loads(get_default_data())
            history_list = default_data_dict['history']
            history_list.sort(reverse = True)
            result_list = []
            for history in history_list:
                clan_data_dict = json.loads(get_clan_data(history, clan_name))
                data = clan_data_dict['data']
                if len(data) != 0:
                    name = data[0]['clan_name']
                    rank = data[0]['rank']
                    if name == clan_name:
                        result_list.append(f'{rank}名, 记录时间: {second2time(history)}')
            if len(result_list) != 0:
                msg_head = f'{clan_name}公会记录在档的会战名次为:\n'
                msg_part = '\n'.join(result_list)
            else:
                await bot.send(ev, f'未找到{clan_name}公会的相关数据')
                return
        await bot.send(ev, msg_head + msg_part)
    except:
        await bot.send(ev, '指令发生错误，请重试')


import numpy as np
import os
import sys
import librosa
import soundfile as sf
from tqdm import tqdm

class ErrorCovarianceMatrix:

    def __init__(self,p,q):

        self.p = p

        self.q = q

        # initialize matrices

        self.mqq = np.zeros((q,q), dtype=np.float32)
        self.mqp = np.zeros((q,p), dtype=np.float32)
        self.mpq = np.zeros((p,q), dtype=np.float32)
        self.mpp = np.zeros((p,p), dtype=np.float32)

        self.oqq = np.asarray([0,0], dtype=np.int32)
        self.oqp = np.asarray([0,0], dtype=np.int32)
        self.opq = np.asarray([0,0], dtype=np.int32)
        self.opp = np.asarray([0,0], dtype=np.int32)

    def getqq(self,i,j):

        return self.mqq[(self.oqq[0]+i) % self.q,(self.oqq[1]+j) % self.q]

    def getqp(self, i, j):

        return self.mqp[(self.oqp[0] + i) % self.q, (self.oqp[1] + j) % self.p]

    def getpq(self, i, j):

        return self.mpq[(self.opq[0]+i) % self.p, (self.opq[1] + j) % self.q]

    def getpp(self, i, j):

        return self.mpp[(self.opp[0]+i) % self.p, (self.opp[1]+j) % self.p]

    def setqq(self,i,j,v):

        self.mqq[(self.oqq[0] + i) % self.q, (self.oqq[1] + j) % self.q] = v

    def setqp(self, i, j, v):

        self.mqp[(self.oqp[0] + i) % self.q, (self.oqp[1] + j) % self.p] = v

    def setpq(self, i, j, v):

        self.mpq[(self.opq[0] + i) % self.p, (self.opq[1] + j) % self.q] = v

    def setpp(self, i, j, v):

        self.mpp[(self.opp[0] + i) % self.p, (self.opp[1] + j) % self.p] = v

    def setC(self,C):

        self.mqq = np.float32(C[:self.q,:self.q])
        self.mqp = np.float32(C[:self.q,self.q:])
        self.mpq = np.float32(C[self.q:,:self.q])
        self.mpp = np.float32(C[self.q:,self.q:])

    def get(self):

        C = np.zeros((self.q+self.p,self.q+self.p), dtype=np.float32)

        for i in range(self.q):
            for j in range(self.q):
                C[i,j] = self.getqq(i,j)

        for i in range(self.q):
            for j in range(self.p):
                C[i,self.q+j] = self.getqp(i,j)

        for i in range(self.p):
            for j in range(self.q):
                C[self.q+i,j] = self.getpq(i,j)

        for i in range(self.p):
            for j in range(self.p):
                C[self.q+i,self.q+j] = self.getpp(i,j)

        return C

    def FCT(self, asp, ans):

        # qq

        for i in range(self.q):

            accu = 0

            for j in range(self.q):

                accu -= ans[j]*self.getqq(i,j)

            self.setqq(i, self.q, accu)

        self.oqq[1] = (self.oqq[1] + 1) % self.q

        # qp

        for i in range(self.p):

            accu = 0

            for j in range(self.q):

                accu -= ans[j] * self.getpq(i, j)

            self.setpq(i, self.q, accu)

        self.opq[1] = (self.opq[1] + 1) % self.q

        # pq

        for i in range(self.q):

            accu = 0

            for j in range(self.p):

                accu -= asp[j] * self.getqp(i, j)

            self.setqp(i, self.p, accu)

        self.oqp[1] = (self.oqp[1] + 1) % self.p

        # pp

        for i in range(self.p):

            accu = 0

            for j in range(self.p):

                accu -= asp[j] * self.getpp(i, j)

            self.setpp(i, self.p, accu)

        self.opp[1] = (self.opp[1] + 1) % self.p

    def FC(self, asp, ans):

        # qq

        for i in range(self.q):

            accu = 0

            for j in range(self.q):

                accu -= ans[j]*self.getqq(j,i)

            self.setqq(self.q,i,accu)

        self.oqq[0] = (self.oqq[0]+1)%self.q

        # qp

        for i in range(self.p):

            accu = 0

            for j in range(self.q):

                accu -= ans[j] * self.getqp(j, i)

            self.setqp(self.q, i, accu)

        self.oqp[0] = (self.oqp[0] + 1) % self.q

        # pq

        for i in range(self.q):

            accu = 0

            for j in range(self.p):

                accu -= asp[j] * self.getpq(j, i)

            self.setpq(self.p, i, accu)

        self.opq[0] = (self.opq[0] + 1) % self.p

        # pp

        for i in range(self.p):

            accu = 0

            for j in range(self.p):

                accu -= asp[j] * self.getpp(j, i)

            self.setpp(self.p, i, accu)

        self.opp[0] = (self.opp[0] + 1) % self.p

    def predictor(self,asp, ans, sig_s, sig_n):

        self.FC(asp,ans)
        self.FCT(asp,ans)
        qq = self.getqq(self.q-1,self.q-1) + sig_n*sig_n
        pp = self.getpp(self.p-1,self.p-1) + sig_s*sig_s
        self.setqq(self.q-1,self.q-1,qq)
        self.setpp(self.p-1,self.p-1,pp)

    def gain(self):

        g = np.zeros((self.p+self.q,), np.float32)

        for i in range(self.q):

            g[i] = self.getqq(i,self.q-1) + self.getqp(i,self.p-1)

        for i in range(self.p):

            g[self.q+i] = self.getpq(i, self.q-1) + self.getpp(i, self.p-1)

        g /= (self.getqq(self.q-1,self.q-1)+self.getqp(self.q-1,self.p-1)+self.getpp(self.p-1,self.p-1) + self.getpq(self.p-1,self.q-1))

        return g

    def update(self,gain):

        auxqq = np.zeros((self.q,self.q), dtype=np.float32)
        auxqp = np.zeros((self.q,self.p), dtype=np.float32)
        auxpq = np.zeros((self.p,self.q), dtype=np.float32)
        auxpp = np.zeros((self.p,self.p), dtype=np.float32)

        for i in range(self.q):

            for j in range(self.q):

                v = self.getqq(i,j) - gain[i]*(self.getqq(self.q-1,j)+self.getpq(self.p-1,j))

                auxqq[i,j] = v

        for i in range(self.q):

            for j in range(self.p):

                v = self.getqp(i,j) - gain[i]*(self.getqp(self.q-1,j) + self.getpp(self.p-1,j))

                auxqp[i,j] = v

        for i in range(self.p):

            for j in range(self.q):

                v = self.getpq(i,j) - gain[self.q+i]*(self.getpq(self.p-1,j)+self.getqq(self.q-1,j))

                auxpq[i,j] = v

        for i in range(self.p):

            for j in range(self.p):

                v = self.getpp(i,j) - gain[self.q+i]*(self.getpp(self.p-1,j) + self.getqp(self.q-1,j))

                auxpp[i,j] = v

        """================"""

        for i in range(self.q):

            for j in range(self.q):

                self.setqq(i,j,auxqq[i,j])

        for i in range(self.q):

            for j in range(self.p):

                self.setqp(i,j,auxqp[i,j])

        for i in range(self.p):

            for j in range(self.q):

                self.setpq(i,j,auxpq[i,j])

        for i in range(self.p):

            for j in range(self.p):

                self.setpp(i,j,auxpp[i,j])

class StateVector:

    def __init__(self,p,q):

        self.xq = np.zeros((q,), dtype=np.float32)
        self.xp = np.zeros((p,), dtype=np.float32)

        self.q = q
        self.p = p

        self.oq = 0
        self.op = 0

    def getq(self,i):

        return self.xq[(self.oq+i)%self.q]

    def getp(self,i):

        return self.xp[(self.op+i)%self.p]

    def setq(self,i,v):

        self.xq[(self.oq+i)%self.q] = v

    def setp(self,i,v):

        self.xp[(self.op+i)%self.p] = v

    def setX(self,x):

        self.xq = x[:self.q]

        self.xp = x[self.q:]

    def predictor(self,asp,ans):

        accu = 0

        for i in range(self.q):

            accu -= self.getq(i)*ans[i]

        self.setq(self.q, accu)

        self.oq = (self.oq+1)%self.q

        accu = 0

        for i in range(self.p):

            accu -= self.getp(i)*asp[i]

        self.setp(self.p,accu)

        self.op = (self.op+1)%self.p

    def update(self,gain,rt):

        aux = self.getq(self.q-1)+self.getp(self.p-1)

        aux = rt-aux

        ga = gain*aux

        for i in range(self.q):

            v = self.getq(i)+ga[i]

            self.setq(i,v)

        for i in range(self.p):

            v = self.getp(i) + ga[self.q+i]

            self.setp(i,v)

    def get(self):

        x = np.zeros((self.p+self.q,), dtype=np.float32)

        for i in range(self.q):

            x[i] = self.getq(i)

        for i in range(self.p):

            x[self.q+i] = self.getp(i)

        return x

class STPKalman:

    def __init__(self, p=10, q=1):

        self.p = p
        self.q = q

        self.ecm = ErrorCovarianceMatrix(p,q)
        self.sv = StateVector(p,q)

    def step(self,rt,asp,ans,sig_s,sig_n):
        """
        :param asp: Параметры речи в STP, анализирующий полином имеет вид: \(1 + \text{asp}[p-1] \cdot z^{-1} + \ldots + \text{asp}[0] \cdot z^{-p}\)
        :param ans: Параметры шума в STP, анализирующий полином аналогичен
        :return: Фильтрованный вектор состояний; первые \(q\) элементов для шума, следующие \(p\) элементов для речи
        """

        asp = asp.astype(np.float32)
        ans = ans.astype(np.float32)
        sig_s = np.float32(sig_s)
        sig_n = np.float32(sig_n)

        self.sv.predictor(asp,ans)
        self.ecm.predictor(asp,ans,sig_s,sig_n)
        G = self.ecm.gain()
        self.sv.update(G,rt)
        self.ecm.update(G)

        return self.sv.getp(0)

SAMPLING_RATE = 16000

if __name__ == "__main__":

    signal, sr = librosa.load("orig.wav", sr=None)
    noise, sr = librosa.load("noise.wav", sr=None)
    signal = signal[16000:64000]
    noise = noise[:len(signal)]

    SNR = 10.

    noise *= (np.linalg.norm(signal)**2/np.linalg.norm(noise)**2/10**(SNR/10.))**.5

    mixed = signal + noise

    start = 0
    frame = 320 # размер кадра
    n_mfcc = 80
    p = n_mfcc
    q = 32

    kl = STPKalman(p, q)

    e = np.zeros_like(mixed)

    num_frames = len(mixed) // frame
    pbar = tqdm(total=num_frames)

    while start+frame <= len(mixed):
        fs = signal[start:start+frame]
        fn = noise[start:start+frame]
        fr = mixed[start:start+frame]

        asp = librosa.feature.mfcc(y=fs, sr=sr, n_mfcc=n_mfcc, n_fft=256, hop_length=64)
        asp = np.mean(asp, axis=1)
        asp_mean = np.mean(asp)
        asp_std = np.std(asp)
        asp = (asp - asp_mean) / asp_std
        sig_s = np.var(asp)

        ans = librosa.feature.mfcc(y=fn, sr=sr, n_mfcc=q, n_fft=256, hop_length=64)
        ans = np.mean(ans, axis=1)
        ans_mean = np.mean(ans)
        ans_std = np.std(ans)
        ans = (ans - ans_mean) / ans_std
        sig_n = np.var(ans)

        for i in range(frame):

            e[start + i] = kl.step(fr[i], asp[::-1], ans[::-1], sig_s, sig_n)

        start += frame
        pbar.update(1)

    pbar.close()
    sf.write('output.wav', e, sr)
    sf.write('output_mixed.wav', mixed, sr)


from django.core.validators import MaxValueValidator, MinValueValidator
from django.db import models

class Coupon(models.Model):
    """
    Model representing a coupon which can be applied to an order to give a discount.
    """

    code: models.CharField = models.CharField(max_length=20, unique=True)
    valid_from: models.DateTimeField = models.DateTimeField()
    valid_to: models.DateTimeField = models.DateTimeField()
    discount: models.IntegerField = models.IntegerField(
        validators=[MinValueValidator(0), MaxValueValidator(100)]
    )
    active: models.BooleanField = models.BooleanField()

    class Meta:
        ordering: tuple = ("-valid_from",)

    def __str__(self) -> str:
        return self.code


from collections import defaultdict

class Solution:
    def longestDupSubstring(self, S: str) -> str:
        """
        https://leetcode.com/problems/longest-duplicate-substring/discuss/695029/Python-Binary-search-O(n-log-n)-average-with-Rabin-Karp-explained
        """
        begin, end = 0, len(S)
        q = (1 << 31) - 1

        answer = ''

        while begin + 1 < end:
            mid = (begin + end) // 2
            found, candidate = self.RabinKarp(S, mid, q)
            if found:
                # update answer and try to find longer answer
                begin, answer = mid, candidate
            else:
                end = mid

        return answer

    def RabinKarp(self, S: str, M: int, q: int) -> bool:
        """
        Using rolling hash to hash the substring
        """
        if M == 0:
            # '' is substring of any string
            return True

        # auxiliary value for fast update of rolling hash
        h = (1 << (8 * M - 8)) % q
        # because it is more than ord('z') = 122
        d = 256
        t = 0

        # for each hash we keep start indexes of windows
        dic = defaultdict(list)

        # Evaluate hash for first window
        for i in range(M):
            t = (d * t + ord(S[i])) % q
        dic[t].append(i-M+1)

        # Evaluate hashes for all other windows in O(n), using evaluated h
        for i in range(len(S) - M):
            t = (d * (t - ord(S[i]) * h) + ord(S[i + M])) % q
            for j in dic[t]:
                # check all possible combinations and compare not hashes but original windows
                # to make sure that is was not a collision
                if S[i+1:i+M+1] == S[j:j+M]:
                    return (True, S[j:j+M])
            dic[t].append(i+1)

        return (False, '')

# Runtime: 2308 ms, faster than 29.48% of Python3 online submissions for Longest Duplicate Substring.
# Memory Usage: 40.1 MB, less than 25.11% of Python3 online submissions for Longest Duplicate Substring.


from django.test import TestCase

class SimpleTest(TestCase):
    def test_basic_addition(self):
        """
        Tests that 1 + 1 always equals 2.
        """
        self.assertEqual(1 + 1, 2)
        #

    #    def test_save_course(self):
    #        p = Course(courseName='test',courseTime=2,startTime=datetime.now(),maxTraineeAmount=2,courseSpeaker='evan')
    #        p.save()

    def test_page(self):
        pageNo = 8
        pageSize = 10
        pageCount = 30
        pre_page_count = 9
        if pageCount < pre_page_count:
            startPageIndex = 1
            endPageIndex = pageCount
        elif pageNo <= (pre_page_count / 2) + 1:
            startPageIndex = 1
            endPageIndex = pre_page_count
        else:
            startPageIndex = pageNo - (pre_page_count / 2)
            endPageIndex = pageNo + ((pre_page_count / 2))
            if endPageIndex >= pageCount:
                endPageIndex = pageCount
                startPageIndex = pageCount - pre_page_count + 1
        self.assertEqual(startPageIndex, 4)
        self.assertEqual(endPageIndex, 12)


from collections.abc import Collection
from typing import Any
import logging

import pytest

from nlmaps_tools.process import (
    ProcessingRequest,
    ProcessingResult,
    ProcessingTool,
)
from nlmaps_tools.process.models import SingleProcessorResult
from nlmaps_tools.process.processors import BuiltinProcessor

class DummyProcessor(BuiltinProcessor):
    def __init__(self, sources: Collection[str], target: str) -> None:
        name = f"{'/'.join(sources)}-{target}"
        super().__init__(sources=sources, target=target, name=name)

    def __call__(self, given: dict[str, Any]) -> str:
        formatted_args = ",".join(given[source] for source in self.sources)
        result = f"{self.name}({formatted_args})"
        logging.info(f"{self.name}: {formatted_args} -> {result}")
        return result

    def __eq__(self, other: Any) -> str:
        return (
                type(self) == type(other)
                and self.name == other.name
                and self.sources == other.sources
                and self.target == other.target
        )

    def __hash__(self) -> int:
        return hash((self.sources, self.target, self.name))

    def __repr__(self) -> str:
        return self.name

@pytest.fixture
def processors() -> set[DummyProcessor]:
    return {
        DummyProcessor(["A"], "B"),
        DummyProcessor(["B"], "A"),
        DummyProcessor(["B"], "E"),
        DummyProcessor(["B"], "C"),
        DummyProcessor(["B"], "D"),
        DummyProcessor(["B", "C", "D"], "E"),
        DummyProcessor(["E"], "G"),
        DummyProcessor(["A", "F"], "B"),
        DummyProcessor(["0"], "A"),
    }

@pytest.fixture
def process_tool(processors) -> ProcessingTool:
    return ProcessingTool(processors)

def _get_processors_by_name(
        processors: set[DummyProcessor], names: set[str]
) -> set[DummyProcessor]:
    return {proc for proc in processors if proc.name in names}

@pytest.mark.parametrize(
    ["process_request", "expected_solutions_by_names"],
    [
        (
                ProcessingRequest(given={"A": "1"}, wanted={"E"}, processors=set()),
                [{"A-B", "B-E"}, {"A-B", "B-C", "B-D", "B/C/D-E"}],
        ),
        (
                ProcessingRequest(given={"A": "1", "F": "2"}, wanted={"E"}, processors=set()),
                [
                    {"A-B", "B-E"},
                    {"A-B", "B-C", "B-D", "B/C/D-E"},
                    {"A/F-B", "B-E"},
                    {"A/F-B", "B-C", "B-D", "B/C/D-E"},
                ],
        ),
        (
                ProcessingRequest(given={"A": "1"}, wanted={"E", "B", "G"}, processors=set()),
                [{"A-B", "B-E", "E-G"}, {"A-B", "B-C", "B-D", "B/C/D-E", "E-G"}],
        ),
        (
                ProcessingRequest(given={"A": "1"}, wanted={"E", "C"}, processors=set()),
                [{"A-B", "B-C", "B-E"}, {"A-B", "B-C", "B-D", "B/C/D-E"}],
        ),
        (
                ProcessingRequest(given={"0": "1"}, wanted={"B"}, processors=set()),
                [{"0-A", "A-B"}],
        ),
    ],
)
def test_find_solutions(process_tool, process_request, expected_solutions_by_names):
    expected_frozen_solutions = frozenset(
        frozenset(_get_processors_by_name(process_tool.processors, names))
        for names in expected_solutions_by_names
    )
    solutions = process_tool._find_solutions(process_request)
    frozen_solutions = frozenset(frozenset(s) for s in solutions)
    assert frozen_solutions == expected_frozen_solutions

def test_process_request(process_tool):
    request = ProcessingRequest(given={"A": "1"}, wanted={"B"}, processors=set())
    expected_result_key = "B"
    expected_result_value = "A-B(1)"
    expected_result_processor_name = "A-B"
    max_result_time = 0.01  # Pretty randomly chosen.
    result = process_tool.process_request(request)
    assert list(result.results.keys()) == [expected_result_key]
    assert result.results[expected_result_key].result == expected_result_value
    assert result.results[expected_result_key].processor_name == expected_result_processor_name
    assert result.results[expected_result_key].wallclock_seconds < max_result_time
    assert result.wallclock_seconds > result.results[expected_result_key].wallclock_seconds

def test_select_wanted_from_result(process_tool):
    request = ProcessingRequest(given={"A": "1"}, wanted={"C"}, processors=set())
    given_result = ProcessingResult(
        results={
            "B": SingleProcessorResult(result="A-B(1)", processor_name="A-B", wallclock_seconds=0.05),
            "C": SingleProcessorResult(result="B-C(A-B(1))", processor_name="B-C", wallclock_seconds=0.05),
        },
        wallclock_seconds=0.11
    )
    expected_result = ProcessingResult(
        results={
            "C": SingleProcessorResult(result="B-C(A-B(1))", processor_name="B-C", wallclock_seconds=0.05),
        },
        wallclock_seconds=0.11
    )
    selected_result = process_tool.select_wanted_from_result(given_result, request)
    assert selected_result == expected_result


import os

from src.constant import resource_path, platform

def show_notification(message, title, subtitle=None, sound_name=None):
    if platform == "darwin":
        show_notification_mac(message, title, subtitle, sound_name)
    elif platform in ("win32", "cygwin"):
        show_notification_win(message, title)

def show_notification_mac(message, title, subtitle=None, sound_name=None):
    """
        Display an OSX notification with message title an subtitle
        sounds are located in /System/Library/Sounds or ~/Library/Sounds
    """
    title_part = ''
    if title:
        title_part = 'with title "{0}"'.format(title)
    subtitle_part = ''
    if subtitle:
        subtitle_part = 'subtitle "{0}"'.format(subtitle)
    soundname_part = ''
    if sound_name:
        soundname_part = 'sound name "{0}"'.format(sound_name)

    apple_script_notification = 'display notification "{0}" {1} {2} {3}'.format(message, title_part, subtitle_part,
                                                                                soundname_part)
    os.system("osascript -e '{0}'".format(apple_script_notification))

def show_notification_win(message, title):
    from win10toast import ToastNotifier

    toaster = ToastNotifier()

    toaster.show_toast(title,
                       message,
                       icon_path=os.path.join(resource_path, "icon.png"),
                       duration=10)

if __name__ == '__main__':
    show_notification("message", "title", "123")