###
# 03-01-2021
# Hi, here's your problem today. This problem was recently asked by Twitter:
#
# You are given the root of a binary tree.
# Find and return the largest subtree of that tree, which is a valid binary search tree.
###
class TreeNode:
    def __init__(self, key):
        self.left = None
        self.right = None
        self.key = key

    def __str__(self):
        # preorder traversal
        answer = str(self.key)
        if self.left:
            answer += str(self.left)
        if self.right:
            answer += str(self.right)
        return answer

def is_bst(root):
    def is_bst_helper(root, min_key, max_key):
        if root is None:
            return True
        if root.key <= min_key or root.key >= max_key:
            return False
        return is_bst_helper(root.left, min_key, root.key) and \
               is_bst_helper(root.right, root.key, max_key)

    return is_bst_helper(root, float('-inf'), float('inf'))

def size(root):
    if root is None:
        return 0
    return size(root.left) + size(root.right) + 1

def largest_bst_subtree(root):
    def helper(root):
        # Returns a tuple of (size, root) of the largest subtree.
        if is_bst(root):
            return (size(root), root)
        return max(helper(root.left), helper(root.right), key=lambda x: x[0])

    return helper(root)[1]

#     5
#    / \
#   6   7
#  /   / \
# 2   4   9
node = TreeNode(5)
node.left = TreeNode(6)
node.right = TreeNode(7)
node.left.left = TreeNode(2)
node.right.left = TreeNode(4)
node.right.right = TreeNode(9)
print(largest_bst_subtree(node))


from enums.quadOperators import QuadOperator
from src.paramsVm import ParamsVm
from src.executionMemory import ExecutionMemory

class VirtualMachine:
    def __init__(self):
        self.quadruples = []
        self.instructionPointer = 0
        self.instructionPointerStack = []
        self.executionMemory = None
        self.paramsVM = None

    def init(self, quadruples, paramsVm: ParamsVm):
        self.quadruples = quadruples
        self.instructionPointer = 1
        self.executionMemory = ExecutionMemory(paramsVm)
        self.paramsVM = paramsVm

    def run(self):
        endOfProgram = False
        print('running')
        while not endOfProgram:
            quadruple = self.quadruples[self.instructionPointer]
            operator = quadruple[0]
            leftOperand = quadruple[1]
            rightOperand = quadruple[2]
            result = quadruple[3]

            self.instructionPointer += 1
            if operator == QuadOperator.GOTO:
                self.instructionPointer = result

            if operator == QuadOperator.GOTOF:
                value = self.executionMemory.getValueOfAddress(leftOperand)
                if value == False or value == 'False':
                    self.instructionPointer = result

            if operator == QuadOperator.GOTOT:
                if leftOperand == True or value == 'True':
                    self.instructionPointer = result

            if operator == QuadOperator.PRINT:
                value = self.executionMemory.getValueOfAddress(result)
                print(value)

            if operator == QuadOperator.GOSUB:
                self.instructionPointerStack.append(self.instructionPointer)
                self.executionMemory.incrementCurrentLocalMemoryPointer()
                self.instructionPointer = result

            if operator == QuadOperator.ERA:
                self.executionMemory.addLocalMemory(self.paramsVM.FunctionsSize[result])

            if operator == QuadOperator.PARAMETER:
                value = self.executionMemory.getValueOfAddress(rightOperand)
                self.executionMemory.setFunctionParameter(value, result)

            if operator == QuadOperator.ENDFUNC:
                self.executionMemory.freeCurrentLocalMemory()
                self.instructionPointer = self.instructionPointerStack.pop()

            if operator == '+':
                leftValue, rightValue = self.getValuesOfAddresses(leftOperand, rightOperand)
                tempResult = leftValue + rightValue
                self.executionMemory.setValueToAddress(tempResult, result)

            if operator == '-':
                leftValue, rightValue = self.getValuesOfAddresses(leftOperand, rightOperand)
                tempResult = leftValue - rightValue
                self.executionMemory.setValueToAddress(tempResult, result)

            if operator == '*':
                leftValue, rightValue = self.getValuesOfAddresses(leftOperand, rightOperand)
                tempResult = leftValue * rightValue
                self.executionMemory.setValueToAddress(tempResult, result)

            if operator == '/':
                leftValue, rightValue = self.getValuesOfAddresses(leftOperand, rightOperand)
                tempResult = leftValue / rightValue
                self.executionMemory.setValueToAddress(tempResult, result)

            if operator == '>':
                leftValue, rightValue = self.getValuesOfAddresses(leftOperand, rightOperand)
                tempResult = leftValue > rightValue
                self.executionMemory.setValueToAddress(tempResult, result)

            if operator == '<':
                leftValue, rightValue = self.getValuesOfAddresses(leftOperand, rightOperand)
                tempResult = leftValue < rightValue
                self.executionMemory.setValueToAddress(tempResult, result)

            if operator == '<=':
                leftValue, rightValue = self.getValuesOfAddresses(leftOperand, rightOperand)
                tempResult = leftValue <= rightValue
                self.executionMemory.setValueToAddress(tempResult, result)

            if operator == '>=':
                leftValue, rightValue = self.getValuesOfAddresses(leftOperand, rightOperand)
                tempResult = leftValue >= rightValue
                self.executionMemory.setValueToAddress(tempResult, result)

            if operator == '==':
                leftValue, rightValue = self.getValuesOfAddresses(leftOperand, rightOperand)
                tempResult = leftValue == rightValue
                self.executionMemory.setValueToAddress(tempResult, result)

            if operator == '=':
                value = self.executionMemory.getValueOfAddress(leftOperand)
                self.executionMemory.setValueToAddress(value, result)

            if operator == QuadOperator.READ:
                value = input()
                if value.isnumeric():
                    value = int(value)
                self.executionMemory.setValueToAddress(value, result)

            if operator == QuadOperator.PRINTMATRIX:
                self.executionMemory.printMatrix(leftOperand, rightOperand)

            if operator == QuadOperator.SQUAREVECTOR:
                self.executionMemory.squareVector(leftOperand, rightOperand)

            if operator == QuadOperator.END:
                endOfProgram = True

    def getValuesOfAddresses(self, address1, address2):
        leftValue = self.executionMemory.getValueOfAddress(address1)
        rightValue = self.executionMemory.getValueOfAddress(address2)
        return [leftValue, rightValue]


""" This app allows the user to process several mathematical
functions on a csv file """

import csv
import os
import sys

import matplotlib.pyplot as plt
from pandas import read_csv

print('***************** Welcome to the Python Data Analysis App ********** ')
print('What type of data would you like to analyze')
while True:
    try:
        data_type = int(input('1. Population Data \n'
                              '2. Housing Data \n'
                              '3. Exit the Program \n'))

        def line_count(read):
            """This method counts the lines read in the csv file and displays the count"""
            count = str(read.line_num - 1)
            return 'Count equals: ' + count

        if data_type == 1:
            with open(os.path.join(sys.path[0] + '\\' + 'popchange.csv'), 'r') as pop_data:
                reader = csv.DictReader(pop_data)
                st = read_csv('popchange.csv')

                result_a = []
                result_b = []
                result_c = []

                for row in reader:
                    a = int(row['Pop Apr 1'])
                    b = int(row['Pop Jul 1'])
                    c = int(row['Change Pop'])

                    result_a.append(a)
                    result_b.append(b)
                    result_c.append(c)

            def process_pop(pop, title, bins, mean_std, min_max):
                """This method processes the population data and returns the
                count of items, mean, standard deviations, min, max and a histogram"""
                print(line_count(reader))
                print('Mean equals: ' + str(st.mean(axis=0)[mean_std]))
                print('Standard Deviation equals: ' + str(st.std(axis=0)[mean_std]))
                print('Min equals: ' + str(st.min(axis=0)[min_max]))
                print('Max equals: ' + str(st.max(axis=0)[min_max]))
                print('Here is a histogram of the data you selected')
                plt.hist(pop, bins=bins, edgecolor='black')
                plt.title(title)
                plt.xlabel('Population')
                plt.ylabel('Total number of properties April 1')
                return plt.show()

            print('You have entered Population Data.')
            column_select = input('Select which column you would like to analyze: \n'
                                  'A. Pop Apr 1 \n'
                                  'B. Pop Jul 1 \n'
                                  'C. Change Pop \n'
                                  'D. Exit Column \n')

            if not column_select:
                print('You entered an invalid entry, reenter your selection.')

            while column_select:
                if column_select.upper() == 'A':
                    a_pop = process_pop([result_a], 'April 1 Population',
                                        [10000, 30000, 50000, 70000, 90000,
                                         110000, 130000, 150000], 1, 4)
                    break

                if column_select.upper() == 'B':
                    b_pop = process_pop(result_b, 'July 1 Population',
                                        [10000, 30000, 50000, 70000, 90000,
                                         110000, 130000, 150000], 2, 5)
                    break

                if column_select.upper() == 'C':
                    c_pop = process_pop(result_c, 'Change in Population (April - July)',
                                        [-10500, -9000, -7500, -6000, -4500, -3000, -1500,
                                         0, 1500, 3000, 4500, 6000, 7500, 9000, 10500], 3, 6)
                    break

                if column_select.upper() == 'D':
                    input('Press any key to return to the main menu')
                    break

                print('You entered an invalid entry, reenter your selection.')
                break

        if data_type == 2:
            with open(os.path.join(sys.path[0] + '\\' + 'housing.csv'), 'r') as house_data:
                reader2 = csv.DictReader(house_data)
                sd = read_csv('housing.csv')

                result_f = []
                result_g = []
                result_h = []
                result_i = []
                result_j = []
                result_m = []
                result_n = []

                for row in reader2:
                    f = int(row['AGE'])
                    g = int(row['BEDRMS'])
                    h = int(row['BUILT'])
                    i = int(row['ROOMS'])
                    j = float(row['UTILITY'])
                    m = (row['NUNITS'])
                    n = (row['WEIGHT'])

                    result_f.append(f)
                    result_g.append(g)
                    result_h.append(h)
                    result_i.append(i)
                    result_j.append(j)
                    result_m.append(m)
                    result_n.append(n)

                    def process_house(house, ticks, xlabel, mean_std, min_max):
                        """This method processes the house data and returns the
                        count of items, mean, standard deviations, min, max and a histogram"""
                        print(line_count(reader2))
                        print('Mean equals: ' + str(sd.mean(axis=0)[mean_std]))
                        print('Standard Deviation equals: ' + str(sd.std(axis=0)[mean_std]))
                        print('Min equals: ' + str(sd.min(axis=0)[min_max]))
                        print('Max equals: ' + str(sd.max(axis=0)[min_max]))
                        print('Here is a histogram of the data you selected')
                        plt.hist(house, bins=ticks, edgecolor='black')
                        plt.ylabel('Number of Homes')
                        plt.xlabel(xlabel)
                        return plt.show()

            print('Here is the housing data')
            param_select = input('Select which housing parameter you would like to analyze: \n'
                                 'A. Age \n'
                                 'B. Bedrooms \n'
                                 'C. Built \n'
                                 'D. Rooms \n'
                                 'E. Utility \n'
                                 'F. Exit Column \n')

            if not param_select:
                print('You entered an invalid entry, reenter your selection.')

            while param_select:
                if param_select.upper() == 'A':
                    process_house(result_f,
                                  [-10, 0, 10, 20, 30, 40, 50, 60, 70], 'Age', 0, 0)
                    break

                if param_select.upper() == 'B':
                    process_house(result_g,
                                  [0, 1, 2, 3, 4, 5, 6, 7, 8], 'Bedrooms', 1, 1)
                    break

                if param_select.upper() == 'C':
                    process_house(result_h,
                                  [1919, 1929, 1939, 1949, 1959, 1969, 1979,
                                   1989, 1999, 2009, 2019], 'Year Built', 2, 2)
                    break

                if param_select.upper() == 'D':
                    process_house(result_i, [0, 3, 6, 9, 12, 15], 'Rooms', 4, 4)
                    break

                if param_select.upper() == 'E':
                    process_house(result_j, [0, 300, 600, 900, 1200, 1500], 'Utility', 6, 6)
                    break

                if param_select.upper() == 'F':
                    input('Press any key to return to the main menu')
                    break

                print('Invalid input, please reenter your selection')
                break

        if data_type == 3:
            print('Thank you for using the Python Data Analysis App')
            sys.exit()

    except ValueError:
        print('You entered an invalid entry, please select one of the listed options')


import torch
from bench.core.executer import Executer

def __split_heads_qkv(queries, keys, values, n_head, d_key, d_value):
    """
    Reshape input tensors at the last dimension to split multi-heads
    and then transpose. Specifically, transform the input tensor with shape
    [bs, max_sequence_length, n_head * hidden_dim] to the output tensor
    with shape [bs, n_head, max_sequence_length, hidden_dim].
    """
    # The value 0 in shape attr means copying the corresponding dimension
    # size of the input as the output dimension size.
    reshaped_q = torch.reshape(queries, shape=[1, 1, n_head, d_key])
    # permuate the dimensions into:
    # [batch_size, n_head, max_sequence_len, hidden_size_per_head]
    q = torch.transpose(reshaped_q, 1, 2)
    # For encoder-decoder attention in inference, insert the ops and vars
    # into global block to use as cache among beam search.
    reshaped_k = torch.reshape(keys, [1, 1, n_head, d_key])
    k = torch.transpose(reshaped_k, 1, 2)
    reshaped_v = torch.reshape(values, shape=[1, 1, n_head, d_value])
    v = torch.transpose(reshaped_v, 1, 2)
    return q, k, v

def args_adaptor(np_args):
    queries = torch.from_numpy(np_args[0]).cuda()
    keys = torch.from_numpy(np_args[1]).cuda()
    values = torch.from_numpy(np_args[2]).cuda()
    n_head = 12
    d_key = -1
    d_value = -1
    return [queries, keys, values, n_head, d_key, d_value]

def executer_creator():
    return Executer(__split_heads_qkv, args_adaptor)


# 문자열 word가 주어질 때, 해당 문자열에서 a 가 처음으로 등장하는 위치(index)를 출력해주세요.
# a 가 없는 경우에는 -1을 출력해주세요.
# find() index() 메서드 사용 금지
# 일단 a인지 아닌지 확인하고 만약 a라면
# 레인지로 수열 만들고 그 숫자를 인덱싱해서 만약 a리면 그 숫자 출력

word = input()
for i in range(len(word)):
    if word[i] == 'a':
        print(i)
        break
    else:
        print(-1)
        break

# 추가 문제
# 문자열 word가 주어질 때, 해당 문자열에서 a 의 모든 위치(index)를 출력해주세요.
# find() index() 메서드 사용 금지
word = input()
for i in range(len(word)):
    if word[i] == 'a':
        print(i, end=' ')


import boto3

def upload_to_bucket(bucket_name, file_name, dest_name):
    # Create an S3 client
    s3 = boto3.client('s3')

    # Upload the file to S3
    s3.upload_file(file_name,
                   bucket_name, dest_name)


# individual network settings for each actor + critic pair
# see model for details

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

from torch.optim import Adam
import numpy as np

# add OU noise for exploration
from OUNoise import OUNoise
from model import Actor, Critic

#device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
device = 'cpu'

td3_config = {
    'td3_noise': 0.2,
    'td3_noise_clip': 0.5,
    'td3_delay': 2
}

class TD3Agent:
    # Shared critic
    critic1 = None
    target_critic1 = None
    critic_optimizer1 = None

    critic2 = None
    target_critic2 = None
    critic_optimizer2 = None

    def __init__(self, agent_number, state_size, action_size, config):
        self.agent_number = agent_number
        self.state_size = state_size
        self.action_size = action_size

        self.batch_size = config['BATCH_SIZE']
        self.gamma = config['GAMMA']
        self.tau = config['TAU']

        # initialize Actor Network
        self.actor = Actor(state_size, action_size).to(device)
        self.target_actor = Actor(state_size, action_size).to(device)
        self.actor_optimizer = Adam(self.actor.parameters(), lr=config['LR_ACTOR'])

        # initialize Critic Networks
        if TD3Agent.critic1 is None:
            TD3Agent.critic1 = Critic(state_size, action_size).to(device)
        if TD3Agent.target_critic1 is None:
            TD3Agent.target_critic1 = Critic(state_size, action_size).to(device)
            TD3Agent.target_critic1.load_state_dict(TD3Agent.critic1.state_dict())
        if TD3Agent.critic_optimizer1 is None:
            TD3Agent.critic_optimizer1 = Adam(TD3Agent.critic1.parameters(), lr=config['LR_CRITIC'])
        self.critic1 = TD3Agent.critic1
        self.target_critic1 = TD3Agent.target_critic1
        self.critic_optimizer1 = TD3Agent.critic_optimizer1

        if TD3Agent.critic2 is None:
            TD3Agent.critic2 = Critic(state_size, action_size).to(device)
        if TD3Agent.target_critic2 is None:
            TD3Agent.target_critic2 = Critic(state_size, action_size).to(device)
            TD3Agent.target_critic2.load_state_dict(TD3Agent.critic2.state_dict())
        if TD3Agent.critic_optimizer2 is None:
            TD3Agent.critic_optimizer2 = Adam(TD3Agent.critic2.parameters(), lr=config['LR_CRITIC'])
        self.critic2 = TD3Agent.critic2
        self.target_critic2 = TD3Agent.target_critic2
        self.critic_optimizer2 = TD3Agent.critic_optimizer2

        self.noise = OUNoise(action_size)

        self.total_steps = 0

    def act(self, obs, add_noise=True):
        obs = torch.from_numpy(obs).float().to(device)
        self.actor.eval() # Set the local policy in evaluation mode
        with torch.no_grad():
            action = self.actor(obs).cpu().data.numpy()
        self.actor.train() # Set the local policy in training mode
        if add_noise:
            action += self.noise.sample()
        return np.clip(action, -1, 1)

    def reset(self):
        self.noise.reset()

    def step(self, memory):
        self.total_steps += 1
        if len(memory) > self.batch_size:
            experiences = memory.sample()
            self.learn(experiences, self.gamma)

    def learn(self, experiences, gamma):
        x, actions, rewards, next_x, dones = experiences

        states = torch.chunk(x, 2, dim=1)
        next_states = torch.chunk(next_x, 2, dim=1)
        rewards = rewards[:, self.agent_number].reshape(rewards.shape[0], 1)
        dones = dones[:, self.agent_number].reshape(dones.shape[0], 1)

        # --- update critic ---
        actions_next = [self.target_actor(x) for x in next_states]
        actions_next_ = torch.cat(actions_next, dim=1).to(device)
        # Generate random noise
        noise = torch.randn_like(actions_next_).mul(td3_config['td3_noise'])
        noise = noise.clamp(-td3_config['td3_noise_clip'], td3_config['td3_noise_clip'])

        actions_next_ = (actions_next_ + noise).clamp(-1, 1)

        Q1_targets_next = self.target_critic1(next_x, actions_next_)
        Q2_targets_next = self.target_critic2(next_x, actions_next_)

        Q_targets_next = torch.min(Q1_targets_next, Q2_targets_next)
        # Compute Q targets for current states (y_i)
        Q_targets = rewards + (gamma * Q_targets_next * (1 - dones))
        Q_targets = Q_targets.detach()
        # Compute critic loss
        Q1_expected = self.critic1(x, actions)
        Q2_expected = self.critic2(x, actions)

        critic_loss1 = F.mse_loss(Q1_expected, Q_targets)
        critic_loss2 = F.mse_loss(Q2_expected, Q_targets)

        # Minimize the loss
        self.critic_optimizer1.zero_grad()
        critic_loss1.backward()
        self.critic_optimizer1.step()

        self.critic_optimizer2.zero_grad()
        critic_loss2.backward()
        self.critic_optimizer2.step()

        if (self.total_steps) % td3_config['td3_delay']:
            # --- update actor ---
            actions_pred = [self.actor(s) for s in states]
            actions_pred_ = torch.cat(actions_pred, dim=1).to(device)
            # actor_loss = -self.critic1(x, actions_pred_)[self.agent_number].mean()
            actor_loss = -self.critic1(x, actions_pred_).mean()
            # Minimize the loss
            self.actor_optimizer.zero_grad()
            actor_loss.backward()
            self.actor_optimizer.step()

            # update target newtorks
            self.soft_update(self.critic1, self.target_critic1, self.tau)
            self.soft_update(self.critic2, self.target_critic2, self.tau)
            self.soft_update(self.actor, self.target_actor, self.tau)

    def soft_update(self, local_model, target_model, tau):
        for target_param, local_param in zip(target_model.parameters(), local_model.parameters()):
            target_param.data.copy_(tau * local_param.data + (1.0 - tau) * target_param.data)


""" This file defines the sample class. """
import numpy as np

from gps.proto.gps_pb2 import ACTION

class Sample(object):
    """
    Class that handles the representation of a trajectory and stores a
    single trajectory.
    Note: must be serializable for easy saving, no C++ references!
    """
    def __init__(self, agent):
        self.agent = agent

        self.T = agent.T
        self.dX = agent.dX
        self.dU = agent.dU
        self.dO = agent.dO
        self.dM = agent.dM

        # Dictionary containing the sample data from various sensors.
        self._data = {}

        self._X = np.empty((self.T, self.dX))
        self._X.fill(np.nan)
        self._obs = np.empty((self.T, self.dO))
        self._obs.fill(np.nan)
        self._meta = np.empty(self.dM)
        self._meta.fill(np.nan)

    def set(self, sensor_name, sensor_data, t=None):
        """ Set trajectory data for a particular sensor. """
        if t is None:
            self._data[sensor_name] = sensor_data
            self._X.fill(np.nan)  # Invalidate existing X.
            self._obs.fill(np.nan)  # Invalidate existing obs.
            self._meta.fill(np.nan)  # Invalidate existing meta data.
        else:
            if sensor_name not in self._data:
                self._data[sensor_name] = \
                        np.empty((self.T,) + sensor_data.shape)
                self._data[sensor_name].fill(np.nan)
            self._data[sensor_name][t, :] = sensor_data
            self._X[t, :].fill(np.nan)
            self._obs[t, :].fill(np.nan)

    def get(self, sensor_name, t=None):
        """ Get trajectory data for a particular sensor. """
        return (self._data[sensor_name] if t is None
                else self._data[sensor_name][t, :])

    def get_X(self, t=None):
        """ Get the state. Put it together if not precomputed. """
        X = self._X if t is None else self._X[t, :]
        if np.any(np.isnan(X)):
            for data_type in self._data:
                if data_type not in self.agent.x_data_types:
                    continue
                data = (self._data[data_type] if t is None
                        else self._data[data_type][t, :])
                self.agent.pack_data_x(X, data, data_types=[data_type])
        return X

    def get_U(self, t=None):
        """ Get the action. """
        return self._data[ACTION] if t is None else self._data[ACTION][t, :]

    def get_obs(self, t=None):
        """ Get the observation. Put it together if not precomputed. """
        obs = self._obs if t is None else self._obs[t, :]
        if np.any(np.isnan(obs)):
            for data_type in self._data:
                if data_type not in self.agent.obs_data_types:
                    continue
                if data_type in self.agent.meta_data_types:
                    continue
                data = (self._data[data_type] if t is None
                        else self._data[data_type][t, :])
                self.agent.pack_data_obs(obs, data, data_types=[data_type])
        return obs

    def get_meta(self):
        """ Get the meta data. Put it together if not precomputed. """
        meta = self._meta
        if np.any(np.isnan(meta)):
            for data_type in self._data:
                if data_type not in self.agent.meta_data_types:
                    continue
                data = self._data[data_type]
                self.agent.pack_data_meta(meta, data, data_types=[data_type])
        return meta

    # For pickling.
    def __getstate__(self):
        state = self.__dict__.copy()
        state.pop('agent')
        return state

    # For unpickling.
    def __setstate__(self, state):
        self.__dict__ = state
        self.__dict__['agent'] = None


# -*- coding: utf-8 -*-

"""
Given a linked list, rotate the list to the right by k places, where k is non-negative.

Example 1:

Input: 1->2->3->4->5->NULL, k = 2
Output: 4->5->1->2->3->NULL
Explanation:
rotate 1 steps to the right: 5->1->2->3->4->NULL
rotate 2 steps to the right: 4->5->1->2->3->NULL
Example 2:

Input: 0->1->2->NULL, k = 4
Output: 2->0->1->NULL
Explanation:
rotate 1 steps to the right: 2->0->1->NULL
rotate 2 steps to the right: 1->2->0->NULL
rotate 3 steps to the right: 0->1->2->NULL
rotate 4 steps to the right: 2->0->1->NULL
"""

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def rotateRight(self, head: ListNode, k: int) -> ListNode:
        if not head or k == 0:
            return head

        rotated = [None]
        list_size = 1
        ptr = head
        while ptr.next:
            list_size += 1
            ptr = ptr.next
            rotated.append(None)

        # If we are asked to move list to the number k which % on list_size = 0 - list placement will be the same
        if k % list_size == 0:
            return head

        ptr = head
        cur_index = 0
        while ptr:
            new_index = (cur_index + k) % list_size
            rotated[new_index] = ListNode(ptr.val)
            ptr = ptr.next
            cur_index += 1

        for i in range(list_size - 1):
            rotated[i].next = rotated[i + 1]

        head = rotated[0]
        return head


import requests

class GitHubUser(object):
    url = 'https://api.github.com/users/{0}'

    def __init__(self, username):
        self.username = username
        self.url = self.url.format(username)

    def fetch(self):
        r = requests.get(self.url)
        return r.json()

    def short_info(self):
        user = self.fetch()
        return """------------------
Username: {0}
Name:     {1}
Link:     {2}
""".format(user['login'], user['name'],
           user['html_url'])


import asyncio
import logging
from configparser import ConfigParser

from pyrogram import Client, filters
from pyrogram.errors import ChatAdminRequired, RPCError
from pyrogram.types import (Message)

from dbhelper import DBHelper

botconfig = ConfigParser()
botconfig.read('bot.ini', encoding='utf-8')
default_config = {}
logging.basicConfig(level=logging.INFO)
db = DBHelper()

def init_default_config():
    global default_config
    default_config = dict(botconfig.items('config'))

def get_group_config(chat_id):
    try:
        int(chat_id)
    except ValueError:
        return None
    db_config = db.get_group_config(chat_id, 'all')
    if db_config is None:
        return default_config
    else:
        final_config = {**default_config, **db_config}
        return final_config

def bot(app):
    @app.on_message(filters.command("acset") & filters.group)
    async def set_config(client: Client, message: Message):
        if message.from_user is None:
            reply_message = await message.reply("请从个人账号发送指令。")
            await asyncio.sleep(10)
            await reply_message.delete()
            return
        chat_id = message.chat.id
        user_id = message.from_user.id
        admins = await client.get_chat_members(chat_id, filter="administrators")
        help_message = "使用方法:\n" \
                       "/acset [配置项] [值]\n\n" \
                       "配置项:\n" \
                       "`operate`: 发现频道发言执行的动作，值为 `ban`, `del`(删除消息), `all`(ban + 删除消息)。" \
                       "注意：因为 Telegram 限制，这个 ban 并不能实际 ban 掉使用频道发言的用户，但可以禁用他使用频道发言的能力\n" \
                       "`message`: 发现频道发言后发送的消息\n" \
                       "`silent_mode`: 是否启用静默模式（不发送消息）1(开启) 或者 0(关闭)\n\n" \
                       "例如: \n" \
                       "`/acset operate ban`"
        if not any([
            admin.user.id == user_id and
            (admin.status == "creator" or admin.can_restrict_members)
            for admin in admins
        ]):
            reply_message = await message.reply("您没有权限使用此命令。")
            await asyncio.sleep(10)
            await reply_message.delete()
            return

        args = message.text.split(" ", maxsplit=2)
        if len(args) < 3:
            await message.reply(help_message)
            return
        key = args[1]
        value = args[2]
        if db.set_group_config(chat_id, key, value):
            await message.reply("配置项设置成功")
        else:
            await message.reply("配置项设置失败, 请输入 /acset 查看帮助")

    @app.on_message(filters.group)
    async def group_message(client, message):
        # 过滤用户消息
        if bool(message.from_user) and not bool(message.sender_chat):
            return
        # 过滤频道匿名消息
        if message.chat.id == message.sender_chat.id:
            return
        # 过滤频道附属群组消息
        if bool(message.forward_from_chat):
            if message.forward_from_chat.id == message.sender_chat.id:
                return

        chat_id = message.chat.id
        channel_id = message.sender_chat.id
        group_config = get_group_config(chat_id)
        if group_config is None:
            return

        try:
            if group_config['operate'] == 'del':
                await message.delete()
            elif group_config['operate'] == 'ban':
                await client.ban_chat_member(chat_id=chat_id, user_id=channel_id)
            elif group_config['operate'] == 'all':
                await message.delete()
                await client.ban_chat_member(chat_id=chat_id, user_id=channel_id)

            if int(group_config['silent_mode']) == '1':
                return
            else:
                reply_message = await message.reply(group_config['message'])
                await asyncio.sleep(10)
                await reply_message.delete()
                return
        except ChatAdminRequired:
            logging.error('机器人权限不足，无法操作, 群组 ID:' + str(chat_id))
            return
        except RPCError as e:
            logging.error('rpc error: ' + str(e))
            return
        except KeyError:
            logging.error('配置项缺失')
            return
        except Exception as e:
            logging.error('未知错误：' + str(e))
            return

def main():
    db.setup()
    init_default_config()
    app = Client("Anti channel bot",
                 api_id=botconfig.get('auth', 'api_id'),
                 api_hash=botconfig.get('auth', 'api_hash'),
                 bot_token=botconfig.get('auth', 'bot_token'))
    bot(app)
    app.run()

if __name__ == "__main__":
    main()


import torch
import torch.nn as nn
import torch.optim as optim
import torch.nn.functional as F
import tqdm
import os
import numpy as np
import time

from storage_utils import save_statistics

class ExperimentBuilder(nn.Module):
    def __init__(self, network_model, experiment_name, num_epochs, train_data, val_data,
                 test_data, weight_decay_coefficient, use_gpu, gpu_id, continue_from_epoch=-1):
        """
        Initializes an ExperimentBuilder object. Such an object takes care of running training and evaluation of a deep net
        on a given dataset. It also takes care of saving per epoch models and automatically inferring the best val model
        to be used for evaluating the test set metrics.
        :param network_model: A pytorch nn.Module which implements a network architecture.
        :param experiment_name: The name of the experiment. This is used mainly for keeping track of the experiment and creating and directory structure that will be used to save logs, model parameters and other.
        :param num_epochs: Total number of epochs to run the experiment
        :param train_data: An object of the DataProvider type. Contains the training set.
        :param val_data: An object of the DataProvider type. Contains the val set.
        :param test_data: An object of the DataProvider type. Contains the test set.
        :param weight_decay_coefficient: A float indicating the weight decay to use with the adam optimizer.
        :param use_gpu: A boolean indicating whether to use a GPU or not.
        :param continue_from_epoch: An int indicating whether we'll start from scrach (-1) or whether we'll reload a previously saved model of epoch 'continue_from_epoch' and continue training from there.
        """
        super(ExperimentBuilder, self).__init__()
        if torch.cuda.is_available() and use_gpu:  # checks whether a cuda gpu is available and whether the gpu flag is True
            self.device = torch.device('cuda:{}'.format(gpu_id))  # sets device to be cuda
            os.environ["CUDA_VISIBLE_DEVICES"] = gpu_id  # sets the main GPU to be the one at index 0 (on multi gpu machines you can choose which one you want to use by using the relevant GPU ID)
            print("use GPU")
            print("GPU ID {}".format(gpu_id))
        else:
            print("use CPU")
            self.device = torch.device('cpu')  # sets the device to be CPU

        self.experiment_name = experiment_name
        self.model = network_model
        self.model.to(self.device)  # sends the model from the cpu to the gpu
        self.model.reset_parameters()  # re-initialize network parameters
        self.train_data = train_data
        self.val_data = val_data
        self.test_data = test_data
        self.optimizer = optim.Adam(self.parameters(), amsgrad=False,
                                    weight_decay=weight_decay_coefficient)
        # Generate the directory names
        self.experiment_folder = os.path.abspath(experiment_name)
        self.experiment_logs = os.path.abspath(os.path.join(self.experiment_folder, "result_outputs"))
        self.experiment_saved_models = os.path.abspath(os.path.join(self.experiment_folder, "saved_models"))
        print(self.experiment_folder, self.experiment_logs)
        # Set best models to be at 0 since we are just starting
        self.best_val_model_idx = 0
        self.best_val_model_acc = 0.

        if not os.path.exists(self.experiment_folder):  # If experiment directory does not exist
            os.mkdir(self.experiment_folder)  # create the experiment directory
            os.mkdir(self.experiment_logs)  # create the experiment log directory
            os.mkdir(self.experiment_saved_models)  # create the experiment saved models directory

        self.num_epochs = num_epochs
        self.criterion = nn.CrossEntropyLoss().to(self.device)  # send the loss computation to the GPU
        if continue_from_epoch == -2:
            try:
                self.best_val_model_idx, self.best_val_model_acc, self.state = self.load_model(
                    model_save_dir=self.experiment_saved_models, model_save_name="train_model",
                    model_idx='latest')  # reload existing model from epoch and return best val model index
                # and the best val acc of that model
                self.starting_epoch = continue_from_epoch
            except:
                print("Model objects cannot be found, initializing a new model and starting from scratch")
                self.starting_epoch = 0
                self.state = dict()

        elif continue_from_epoch != -1:  # if continue from epoch is not -1 then
            self.best_val_model_idx, self.best_val_model_acc, self.state = self.load_model(
                model_save_dir=self.experiment_saved_models, model_save_name="train_model",
                model_idx=continue_from_epoch)  # reload existing model from epoch and return best val model index
            # and the best val acc of that model
            self.starting_epoch = self.state['current_epoch_idx']
        else:
            self.starting_epoch = 0
            self.state = dict()

    def get_num_parameters(self):
        total_num_params = 0
        for param in self.parameters():
            total_num_params += np.prod(param.shape)

        return total_num_params

    def run_train_iter(self, x, y):
        """
        Receives the inputs and targets for the model and runs a training iteration. Returns loss and accuracy metrics.
        :param x: The inputs to the model. A numpy array of shape batch_size, channels, height, width
        :param y: The targets for the model. A numpy array of shape batch_size, num_classes
        :return: the loss and accuracy for this batch
        """
        self.train()  # sets model to training mode (in case batch normalization or other methods have different procedures for training and evaluation)
        y = np.argmax(y, axis=1)  # convert one hot encoded labels to single integer labels
        x, y = torch.Tensor(x).float().to(device=self.device), torch.Tensor(y).long().to(
            device=self.device)  # send data to device as torch tensors
        out = self.model.forward(x)  # forward the data in the model
        loss = F.cross_entropy(input=out, target=y)  # compute loss

        self.optimizer.zero_grad()  # set all weight grads from previous training iters to 0
        loss.backward()  # backpropagate to compute gradients for current iter loss

        self.optimizer.step()  # update network parameters
        _, predicted = torch.max(out.data, 1)  # get argmax of predictions
        accuracy = np.mean(list(predicted.eq(y.data).cpu()))  # compute accuracy
        return loss.data, accuracy

    def run_evaluation_iter(self, x, y):
        """
        Receives the inputs and targets for the model and runs an evaluation iterations. Returns loss and accuracy metrics.
        :param x: The inputs to the model. A numpy array of shape batch_size, channels, height, width
        :param y: The targets for the model. A numpy array of shape batch_size, num_classes
        :return: the loss and accuracy for this batch
        """
        self.eval()  # sets the system to validation mode
        y = np.argmax(y, axis=1)  # convert one hot encoded labels to single integer labels
        x, y = torch.Tensor(x).float().to(device=self.device), torch.Tensor(y).long().to(
            device=self.device)  # convert data to pytorch tensors and send to the computation device
        out = self.model.forward(x)  # forward the data in the model
        loss = F.cross_entropy(out, y)  # compute loss
        _, predicted = torch.max(out.data, 1)  # get argmax of predictions
        accuracy = np.mean(list(predicted.eq(y.data).cpu()))  # compute accuracy
        return loss.data, accuracy

    def save_model(self, model_save_dir, model_save_name, model_idx, state):
        """
        Save the network parameter state and current best val epoch idx and best val accuracy.
        :param model_save_name: Name to use to save model without the epoch index
        :param model_idx: The index to save the model with.
        :param best_validation_model_idx: The index of the best validation model to be stored for future use.
        :param best_validation_model_acc: The best validation accuracy to be stored for use at test time.
        :param model_save_dir: The directory to store the state at.
        :param state: The dictionary containing the system state.

        """
        state['network'] = self.state_dict()  # save network parameter and other variables.
        torch.save(state, f=os.path.join(model_save_dir, "{}_{}".format(model_save_name, str(
            model_idx))))  # save state at prespecified filepath

    def load_model(self, model_save_dir, model_save_name, model_idx):
        """
        Load the network parameter state and the best val model idx and best val acc to be compared with the future val accuracies, in order to choose the best val model
        :param model_save_dir: The directory to store the state at.
        :param model_save_name: Name to use to save model without the epoch index
        :param model_idx: The index to save the model with.
        :return: best val idx and best val model acc, also it loads the network state into the system state without returning it
        """
        state = torch.load(f=os.path.join(model_save_dir, "{}_{}".format(model_save_name, str(model_idx))))
        self.load_state_dict(state_dict=state['network'])
        return state['best_val_model_idx'], state['best_val_model_acc'], state

    def run_experiment(self):
        """
        Runs experiment train and evaluation iterations, saving the model and best val model and val model accuracy after each epoch
        :return: The summary current_epoch_losses from starting epoch to total_epochs.
        """
        total_losses = {"train_acc": [], "train_loss": [], "val_acc": [],
                        "val_loss": [], "curr_epoch": []}  # initialize a dict to keep the per-epoch metrics
        for i, epoch_idx in enumerate(range(self.starting_epoch, self.num_epochs)):
            epoch_start_time = time.time()
            current_epoch_losses = {"train_acc": [], "train_loss": [], "val_acc": [], "val_loss": []}

            with tqdm.tqdm(total=self.train_data.num_batches) as pbar_train:  # create a progress bar for training
                for idx, (x, y) in enumerate(self.train_data):  # get data batches
                    loss, accuracy = self.run_train_iter(x=x, y=y)  # take a training iter step
                    current_epoch_losses["train_loss"].append(loss)  # add current iter loss to the train loss list
                    current_epoch_losses["train_acc"].append(accuracy)  # add current iter acc to the train acc list
                    pbar_train.update(1)
                    pbar_train.set_description("loss: {:.4f}, accuracy: {:.4f}".format(loss, accuracy))

            with tqdm.tqdm(total=self.val_data.num_batches) as pbar_val:  # create a progress bar for validation
                for x, y in self.val_data:  # get data batches
                    loss, accuracy = self.run_evaluation_iter(x=x, y=y)  # run a validation iter
                    current_epoch_losses["val_loss"].append(loss)  # add current iter loss to val loss list.
                    current_epoch_losses["val_acc"].append(accuracy)  # add current iter acc to val acc lst.
                    pbar_val.update(1)  # add 1 step to the progress bar
                    pbar_val.set_description("loss: {:.4f}, accuracy: {:.4f}".format(loss, accuracy))
            val_mean_accuracy = np.mean(current_epoch_losses['val_acc'])
            if val_mean_accuracy > self.best_val_model_acc:  # if current epoch's mean val acc is greater than the saved best val acc then
                self.best_val_model_acc = val_mean_accuracy  # set the best val model acc to be current epoch's val accuracy
                self.best_val_model_idx = epoch_idx  # set the experiment-wise best val idx to be the current epoch's idx

            for key, value in current_epoch_losses.items():
                total_losses[key].append(np.mean(
                    value))  # get mean of all metrics of current epoch metrics dict, to get them ready for storage and output on the terminal.

            total_losses['curr_epoch'].append(epoch_idx)
            save_statistics(experiment_log_dir=self.experiment_logs, filename='summary.csv',
                            stats_dict=total_losses, current_epoch=i,
                            continue_from_mode=True if (self.starting_epoch != 0 or i > 0) else False) # save statistics to stats file.

            # load_statistics(experiment_log_dir=self.experiment_logs, filename='summary.csv') # How to load a csv file if you need to

            out_string = "_".join(
                ["{}_{:.4f}".format(key, np.mean(value)) for key, value in current_epoch_losses.items()])
            # create a string to use to report our epoch metrics
            epoch_elapsed_time = time.time() - epoch_start_time  # calculate time taken for epoch
            epoch_elapsed_time = "{:.4f}".format(epoch_elapsed_time)
            print("Epoch {}:".format(epoch_idx), out_string, "epoch time", epoch_elapsed_time, "seconds")
            self.state['current_epoch_idx'] = epoch_idx
            self.state['best_val_model_acc'] = self.best_val_model_acc
            self.state['best_val_model_idx'] = self.best_val_model_idx
            self.save_model(model_save_dir=self.experiment_saved_models,
                            # save model and best val idx and best val acc, using the model dir, model name and model idx
                            model_save_name="train_model", model_idx=epoch_idx, state=self.state)
            self.save_model(model_save_dir=self.experiment_saved_models,
                            # save model and best val idx and best val acc, using the model dir, model name and model idx
                            model_save_name="train_model", model_idx='latest', state=self.state)

        print("Generating test set evaluation metrics")
        self.load_model(model_save_dir=self.experiment_saved_models, model_idx=self.best_val_model_idx,
                        # load best validation model
                        model_save_name="train_model")
        current_epoch_losses = {"test_acc": [], "test_loss": []}  # initialize a statistics dict
        with tqdm.tqdm(total=self.test_data.num_batches) as pbar_test:  # ini a progress bar
            for x, y in self.test_data:  # sample batch
                loss, accuracy = self.run_evaluation_iter(x=x,
                                                          y=y)  # compute loss and accuracy by running an evaluation step
                current_epoch_losses["test_loss"].append(loss)  # save test loss
                current_epoch_losses["test_acc"].append(accuracy)  # save test accuracy
                pbar_test.update(1)  # update progress bar status
                pbar_test.set_description(
                    "loss: {:.4f}, accuracy: {:.4f}".format(loss, accuracy))  # update progress bar string output

        test_losses = {key: [np.mean(value)] for key, value in
                       current_epoch_losses.items()}  # save test set metrics in dict format
        save_statistics(experiment_log_dir=self.experiment_logs, filename='test_summary.csv',
                        # save test set metrics on disk in .csv format
                        stats_dict=test_losses, current_epoch=0, continue_from_mode=False)

        return total_losses, test_losses


# https://practice.geeksforgeeks.org/problems/sort-an-array-of-0s-1s-and-2s/0

#code
def quickSort(a, l, r):
    if l < r:
        q = partition(a, l, r)
        quickSort(a, l, q-1)
        quickSort(a, q+1, r)

def partition(a, l, r):
    pivot = a[r]
    i = l - 1
    for x in range(l, r):
        if a[x]<=pivot:
            i+=1
            a[i],a[x] = a[x], a[i]
    a[i+1], a[r] = a[r], a[i+1]
    return i+1

# def partition(arr,low,high):
#     i = ( low-1 )         # index of smaller element
#     pivot = arr[high]     # pivot

#     for j in range(low , high):
#         if   arr[j] <= pivot:
#             i = i+1
#             arr[i],arr[j] = arr[j],arr[i]

#     arr[i+1],arr[high] = arr[high],arr[i+1]
#     return ( i+1 )

# def quickSort(arr,low,high):
#     if low < high:
#         pi = partition(arr,low,high)
#         quickSort(arr, low, pi-1)
#         quickSort(arr, pi+1, high)

if __name__=="__main__":
    tc = int(input())
    for x in range(tc):
        n = int(input())
        a = list(map(int, input().split()))
        quickSort(a, 0, len(a)-1)
        print(*a)


import io
import sys

_INPUT = """\
30
"""
sys.stdin = io.StringIO(_INPUT)

def is_prime(n):
    if n == 1:
        return True
    for i in range(2, int(n**0.5) + 1):
        if n % i == 0:
            return False
    return True

def make_divisors(n):
    divisors = []
    for i in range(1, int(n**0.5)+1):
        if n % i == 0:
            divisors.append(i)
            if i != n // i:
                divisors.append(n//i)

    divisors.sort()
    return divisors

k = int(input())
li = make_divisors(k)
ans = 1

for i in range(len(li)):
    ans *= li[i]
    print(ans)
    # if ans % k == 0:
    #     print(ans)
    #     exit()
    # print(ans)


from random import randint

from faker import Faker
from faker.providers import internet, phone_number, credit_card

fake = Faker()
fake.add_provider(internet)
fake.add_provider(phone_number)
fake.add_provider(credit_card)

fake_emails = [fake.email() for _ in range(0, 1500)]

def make_fake_pii():
    name = fake.name().split()
    return {
        "firstname": name[0],
        "lastname": name[1],
        "phone": fake.phone_number(),
        "email": fake_emails[randint(0, 1499)]
    }

def make_identification_data():
    name = fake.name().split()
    tn = fake.phone_number()
    return {
        "firstname": name[0],
        "lastname": name[1],
        "name": name,
        "slack": f"@{name[1]}",
        "telegram": f"@{name[0]}",
        "phone": tn,
        "whatsapp": tn,
        "email": fake_emails[randint(0, 1499)],
        "birthday": fake.date_time_between(start_date='-75y', end_date='-18y').strftime("%Y-%m-%dT%H:%M:%S")
    }

fake_persons = [make_fake_pii() for _ in range(0, 500)]
fake_identity = [make_identification_data() for _ in range(0, 500)]

def make_fake_login():
    name = fake.name().split()
    return {
        "email": fake_emails[randint(0, 1499)]
    }

def make_fake_loc():
    lng, lat, town, country, tz = fake.local_latlng()
    return {
        "login": fake_emails[randint(0, 1499)],
        "lng": lng,
        "lat": lat,
        "town": town,
        "country": country,
        "tz": tz
    }


import sys
input = sys.stdin.readline

n = int(input())
a = list(map(int, input().split()))

ans = 0
for l in range(n):
    x = a[l]
    for r in range(l, n):
        if x >= a[r]:
            x = a[r]
        if ans <= x * (r - l + 1):
            ans = x * (r - l + 1)
print(ans)


import math
n=int(input("Enter the number: "))
f=1
for i in range(2,int(math.sqrt(n))+1):
    if n%i==0:
        f=0
        break
if f:
    print(n," is a prime number")
else:
    print(n," is not a prime number")


from PyQt5.QtCore import QObject
from lib.port import PortFactory
from lib.device import DeviceFactory

class Server(QObject):
    def __init__(self, config, parent=None):
        super().__init__(parent=parent)

        self.port = {}
        for key, value in config['port'].items():
            self.port[key] = PortFactory.create_port(value)

        self.device = {}
        for key, value in config['device'].items():
            port = self.port.get(value['port'], 'None')
            self.device[key] = DeviceFactory(port=port, config=value)


import numpy as np
import torch
from torch.utils.data.dataset import Dataset, Subset

class MaximumLabelDataset(Subset):
    def __init__(self, ds: Dataset, n, seed=None):
        print("data seed:", seed)

        rng = np.random.default_rng(seed)

        labels = ds.targets

        dataset_idx = []

        max_label = torch.max(labels) if torch.is_tensor(labels) else np.max(labels)

        labels = np.array(labels)

        for i in range(max_label + 1):
            idxs = np.where(labels == i)[0]
            # np.random.shuffle(idxs)
            rng.shuffle(idxs)
            dataset_idx.extend(idxs[:n])
        # print(dataset_idx)
        # np.random.shuffle(dataset_idx)
        rng.shuffle(dataset_idx)
        print("ids", dataset_idx)

        super().__init__(ds, dataset_idx)
        self.targets = labels[dataset_idx]


from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time
from collections import Counter
import termtables as tt
import sqlite3
import datetime

def create_database():
    print('Categories:\n', categories, '\n')

    # creating tables if not exists

    cur.execute('''
        CREATE TABLE IF NOT EXISTS language(
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            name VARCHAR(128) UNIQUE,
            last_update varchar(128)
        )
    '''
    )

    cur.execute('''
        CREATE TABLE IF NOT EXISTS skill(
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            name VARCHAR(128) UNIQUE
        )
    '''
    )

    cur.execute('''
        CREATE TABLE IF NOT EXISTS count(
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            language_id INTEGER,
            skill_id INTEGER,
            counter INTEGER
        )
    '''
    )

    # inserting categories to language table in the database (only for the first time)
    try:
        for category_name in categories:
            cur.execute('INSERT INTO language (name, last_update) VALUES (?, ?)', (category_name,'NULL'))
        conn.commit()
    except:
        print('')

def live_retrieve():

    print('\n---------------------------------------------')
    print('LOADING...')
    print('---------------------------------------------\n')

    browser = webdriver.Firefox()
    url = 'https://justjoin.it/all/' + category
    browser.get(url)
    scroll_element = browser.find_element_by_class_name('css-ic7v2w')
    last_offers = None
    list_of_skills_scraped_from_website = []
    names_list = []
    companies_list = []
    cities_list = []

    # reading divs with offers, to compare with last offers, so if divs_with_offers == last_offers, it means that, we have reached the bottom of the page
    while True:
        time.sleep(1)
        divs_with_offers = browser.find_elements_by_xpath("/html/body/div[1]/div[3]/div[1]/div/div[2]/div[1]/div/div/div")
        divs_with_skills = browser.find_elements_by_class_name('css-1ij7669')
        divs_with_company_names = browser.find_elements_by_class_name('css-ajz12e')
        divs_with_job_names = browser.find_elements_by_class_name('css-1x9zltl')
        divs_with_city_names = browser.find_elements_by_class_name('css-1ihx907')

        if divs_with_offers == last_offers:
            break
        else:
            last_offers = divs_with_offers

            # creating lists with company, job and city names
            for div in divs_with_company_names:
                    companies_list.append(div.text)
            for div in divs_with_job_names:
                    names_list.append(div.text)
            for div in divs_with_city_names:
                    cities_list.append(div.text)

            # adding text of anchor tags (as tuple) to a list
            for element in divs_with_skills:
                list_of_skills_scraped_from_website.append(element.text)

            # scrolling down, so new divs will be created
            scroll_element.send_keys(Keys.PAGE_DOWN)

    # closing browser
    browser.quit()

    # compounding new list fof touples (job_title, company_name, city_name, (skill1, skill2, skill3))
    # (Python Developer, ChokityPooh, New York, (python, django, sql))
    list_with_company_job_skill_names = []
    for x in range(len(names_list)):
        list_with_company_job_skill_names.append((names_list[x],companies_list[x], cities_list[x], list_of_skills_scraped_from_website[x]))

    # deleting duplicated offers, we are deleting duplicated tuples
    list_with_company_job_skill_names = list(dict.fromkeys(list_with_company_job_skill_names))

    # this is the list of all skills, but without replacing  / \
    list_of_skills_without_duplicates = []

    # this is the list of all skills ['python', 'django', 'sql', 'python', 'flask', 'django']
    # there are duplicates due to the fact, that job offers can have the same required skill set
    list_of_required_skills = []

    for x in list_with_company_job_skill_names:
        (_, _, _, skill) = x
        list_of_skills_without_duplicates.append(skill)

    for x in list_of_skills_without_duplicates:
        x = x.replace(' /','\n').replace('/ ','\n').replace(' / ','\n').replace('/','\n').split('\n')
        x = [sub.strip() for sub in x]
        list_of_required_skills += x

    # we are counting how many duplicates of a single element are in required_skill[] list, and we are getting top number_of_skills entered by user
    most_common_skills = Counter(list_of_required_skills).most_common(1000)

    # adding skills and counter to proper category
    for element in most_common_skills:
        skill_name = element[0]
        skill_counter = element[1]

        # checking if skill name is in the skill table, if not it will insert one
        cur.execute('SELECT id from skill WHERE name like ?', (skill_name, ) )
        row = cur.fetchone()
        if row is None:
            cur.execute('INSERT INTO skill (name) VALUES (?)', (skill_name, ) )

        # if skill name in skill table, we are retrieving its id
        cur.execute('SELECT id from skill WHERE name like ?', (skill_name, ) )
        row = cur.fetchone()
        skill_id = row[0]

        # getting id of the row from count table, so we can later update its columns
        cur.execute('SELECT id FROM count WHERE skill_id like ? AND language_id like ?',(skill_id, categories.index(category)+1) )

        row = cur.fetchone()
        if row is None:
            cur.execute('INSERT INTO count (language_id, skill_id, counter) VALUES (?, ?, ?)', (categories.index(category)+1, skill_id, skill_counter))
        else:
            cur.execute('UPDATE count SET counter = ? WHERE id = ? AND skill_id = ?', (skill_counter, row[0], skill_id))

        conn.commit()

    # setting last_update to now(), so program knows that there is an exisitng data for this category in the database, so user can decide if he wants to
    # scrape website on live, or just retrieve data for this category from database
    now_time = datetime.datetime.now()
    cur.execute('UPDATE language SET last_update = ? WHERE name like ?', (now_time, category) )
    conn.commit()

#displaying data function - retrieving data from db, and printing it as table
def display_data():
    cur.execute('''
        SELECT skill.name, counter
        FROM count
        INNER JOIN language ON language.id = count.language_id
        INNER JOIN skill on skill.id = count.skill_id
        WHERE language.id = ?
        ORDER BY counter DESC
        LIMIT ?
    ''', (categories.index(category)+1, number_of_skills))

    rows = cur.fetchall()

    print('\nDisplaying data for: ', category.upper())
    # formating data into tables
    formatted_table_with_data = tt.to_string(
        rows,
        header = ['SKILL', 'COUNTER'],
        style = tt.styles.ascii_thin_double
    )
    print(formatted_table_with_data)

if __name__ == '__main__':
    categories = ['all', 'javascript', 'html', 'php', 'ruby', 'python', 'java', 'net', 'scala', 'c', 'mobile', 'testing', 'devops', 'ux', 'pm', 'game', 'analytics', 'security', 'data', 'go', 'sap', 'support', 'other']

    conn = sqlite3.connect('skill_counter_single.sqlite')
    cur = conn.cursor()

    create_database()

    # choosing category to scrape data for
    while True:
        category = input('Type the category name or press enter to display data for all available jobs: ').lower()

        if category in categories:
            break
        print('Wrong input, type again!\n')

    # choosing the number of skills to display in the table, it must be an integer
    while True:
        try:
            number_of_skills = int(input('\nType number of skills to display: '))
        except ValueError:
            print('Not an integer! Try again!')
            continue
        else:
            break

    # getting information if data for chosen category is in our database if not it will immediately go to scrape a web
    # otherwise it will ask user whether to display data from database or scrape web to display live data
    # at the begining every category has last_update set to NULL
    cur.execute('SELECT last_update FROM language WHERE id like ?',(categories.index(category)+1, ))
    row = cur.fetchone()

    if(row[0] != 'NULL'):
        print('Last update:',row[0])
        while True:
            from_db = input('Do you want to retrieve data from db? (yes/no) ').strip().lower()

            if from_db == 'yes':
                print('Displaying from db')
                display_data()
                break
            elif from_db == 'no':
                print('Displaying live data')
                live_retrieve()
                display_data()
                break
            else:
                print('Wrong input, type again!\n')
    else:
        live_retrieve()
        display_data()

    conn.close()


"""
An integer N is given, representing the area of some rectangle.

The area of a rectangle whose sides are of length A and B is A * B, and the perimeter is 2 * (A + B).

The goal is to find the minimal perimeter of any rectangle whose area equals N.
The sides of this rectangle should be only integers.

For example, given integer N = 30, rectangles of area 30 are:

(1, 30), with a perimeter of 62,
(2, 15), with a perimeter of 34,
(3, 10), with a perimeter of 26,
(5, 6), with a perimeter of 22.
Write a function:

def solution(N)

that, given an integer N, returns the minimal perimeter of any rectangle whose area is exactly equal to N.

For example, given an integer N = 30, the function should return 22, as explained above.

Write an efficient algorithm for the following assumptions:

N is an integer within the range [1..1,000,000,000].
"""
def solution(N):
    i = 1
    # We define an absurd perimeter cause "N is an integer within the range [1..1,000,000,000]."
    perimeter = 300000000000000
    # We use the O(sqrt(N)) approach to only take on consideration the first divisors
    while i * i < N:
        if N % i == 0 and 2 * (( N / i) + i) < perimeter:
            perimeter = 2 * (( N / i) + i)
        i += 1
    # And then check for the cases that N is a perfect square root number (36)
    if i * i == N:
        perimeter = 2 * (( N / i) + i)
    return int(perimeter)


def read_matrix():
    row_count, column_count = map(int, input().split())
    matrix = []
    for row_index in range(row_count):
        row = input().split()
        matrix.append(row)
    return matrix, row_count, column_count

def check_if_valid_index(index_row, index_col, rows, cols):
    if 0 <= index_row < rows and 0 <= index_col < cols:
        return True
    return False

def check_if_valid_command(command, coords, rows, cols):
    if len(coords) == 4 and command == "swap":
        for index in range(0, len(coords), 2):
            if check_if_valid_index(coords[index], coords[index + 1], rows, cols):
                return True
    return False

def print_matrix(matrix):
    for row_index in range(len(matrix)):
        for col_index in range(len(matrix[row_index])):
            print(f"{matrix[row_index][col_index]}", end=' ')
        print()

matrix, rows, cols = read_matrix()

data = input()

while not data == "END":
    split_data = data.split()
    command = split_data[0]
    coordinates = [int(el) for el in split_data[1:]]

    if check_if_valid_command(command, coordinates, rows, cols):
        current_row, current_col = coordinates[0], coordinates[1]
        row_swap, col_swap = coordinates[2], coordinates[3]
        temp = matrix[current_row][current_col]
        matrix[current_row][current_col] = matrix[row_swap][col_swap]
        matrix[row_swap][col_swap] = temp
        print_matrix(matrix)
    else:
        print("Invalid input!")
    data = input()


import contextlib
import os
from tempfile import TemporaryDirectory
from typing import Callable, Optional, TypeVar

from framework import utils

# Locally, this will always compare against main, even if we try to merge into, say, a feature branch.
# We might want to do a more sophisticated way to determine a "parent" branch here.
DEFAULT_A_REVISION = os.environ.get("BUILDKITE_PULL_REQUEST_BASE_BRANCH", "main")

T = TypeVar("T")
U = TypeVar("U")

def default_comparator(ah: T, be: T) -> bool:
    """Returns `true` iff that the two arguments are equal.

    The default assertion for A/B-tests using `ab_test`.

    Ridiculous variable names sponsored by pylint."""
    return ah == be

def git_ab_test(
    test_runner: Callable[[bool], T],
    comparator: Callable[[T, T], U] = default_comparator,
    *,
    a_revision: str = DEFAULT_A_REVISION,
    b_revision: Optional[str] = None,
) -> (T, T, U):
    """
    Performs an A/B-test using the given test runner between the specified revision, and the currently checked out revision.
    The specified revisions will be checked out in temporary directories, with `test_runner` getting executed in the
    repository root. If the test depends on firecracker binaries built from the requested revision, care has to be taken
    that they are built from the sources in the temporary directory (which can be ensured via the `workspace` parameter
    to `cargo_build.get_binary`).

    Note that there are no guarantees on the order in which the two tests are run.

    :param test_runner: A callable which when executed runs the test in the context of the current working directory. Its
                        parameter is `true` if and only if it is currently running the "A" test.
    :param comparator: A callable taking two outputs from `test_runner` and comparing them. Should return some value
                       indicating whether the test should pass or no, which will be returned by the `ab_test` functions,
                       and on which the caller can then do an assertion.
    :param a_revision: The revision to checkout for the "A" part of the test. Defaults to the pull request target branch
                       if run in CI, and "main" otherwise.
    :param b_revision: The git revision to check out for "B" part of the test. Defaults to whatever is currently checked
                       out (in which case no temporary directory will be created).
    :return: The output of both "A" test, the "B" test and the comparator, which can then be used for assertions
             (alternatively, your comparator can perform any required assertions and not return anything).
    """

    # We can't just checkout random branches in the current working directory. Locally, this might not work because of
    # uncommitted changes. In the CI this will not work because multiple tests will run in parallel, and thus switching
    # branches will cause random failures in other tests.
    with temporary_checkout(a_revision) as a_tmp:
        with chdir(a_tmp):
            result_a = test_runner(True)

        if b_revision:
            with temporary_checkout(b_revision) as b_tmp:
                with chdir(b_tmp):
                    result_b = test_runner(False)
                # Have to call comparator here to make sure both temporary directories exist (as the comparator
                # might rely on some files that were created during test running, see the benchmark test)
                comparison = comparator(result_a, result_b)
        else:
            # By default, pytest execution happens inside the `tests` subdirectory. Change to the repository root, as
            # documented.
            with chdir(".."):
                result_b = test_runner(False)
            comparison = comparator(result_a, result_b)

        return result_a, result_b, comparison

@contextlib.contextmanager
def temporary_checkout(revision: str):
    """
    Context manager that checks out firecracker in a temporary directory and `chdir`s into it

    Will change back to whatever was the current directory when the context manager was entered, even if exceptions
    happen along the way.
    """
    with TemporaryDirectory() as tmp_dir:
        utils.run_cmd(
            f"git clone https://github.com/firecracker-microvm/firecracker {tmp_dir}"
        )

        with chdir(tmp_dir):
            utils.run_cmd(f"git checkout {revision}")

        yield tmp_dir

# Once we upgrade to python 3.11, this will be in contextlib:
# https://docs.python.org/3/library/contextlib.html#contextlib.chdir
@contextlib.contextmanager
def chdir(to):
    """Context manager that temporarily `chdir`s to the specified path"""
    cur = os.getcwd()

    try:
        os.chdir(to)
        yield
    finally:
        os.chdir(cur)


# continue : for some action, stop executing remaining lines of block and go to next iteration

# Print first 7 numbers  between 1 to 100. Which are divisible by 5.
# If number ends with 0(divisible by 10) don't consider it.

'''
1   2  3  4  5  6  7  8  9 10
11 12 13 14 15 16 17 18 19 20
21 22 23 24 25 26 27 28 29 30
........

required output : 5
count = 1
'''

n1 = 1
n2 = 100
count = 0
while n1 <= n2:
    if n1 % 5 == 0:
        if n1 % 10 == 0:
            n1 += 1
            continue
        print(n1)
        count += 1
        if count == 7:
            break
    n1 += 1
print("End of program")

# Every mobile postpaid bill every 24 hours
import time
while True:
    time.sleep(2)
    print("Python programming")


from threading import RLock

from common.api import BkLoginApi
from common.local import get_local_param, set_local_param
from django.conf import settings
from django.utils import translation
from django.utils.translation.trans_real import get_supported_language_variant

class BkLanguage:
    """
    当前请求需要的语言环境
    在中间件BkLocaleMiddleware中根据http header初始化
    """

    default_language_code = settings.LANGUAGE_CODE

    EN = settings.BK_LANGUAGE_EN
    CN = settings.BK_LANGUAGE_CN
    ALL = settings.BK_LANGUAGE_ALL

    @staticmethod
    def current_language():
        """
        获取当前请求的语言环境
        :return:
        """
        return get_local_param("language", BkLanguage.default_language_code)

    @staticmethod
    def set_language(language_code, request=False):
        """
        设置当前请求的语言环境
        :param language_code: 取值只能在setting中定义的语言列表中选择
        :return:
        """
        input_language_code = language_code
        if input_language_code == "zh-hans":
            # 统一
            input_language_code = BkLanguage.CN

        from pizza.settings_default import BK_SUPPORTED_LANGUAGES

        if input_language_code not in BK_SUPPORTED_LANGUAGES:
            return False

        set_local_param("language", input_language_code)

        # 如果是双语， 则默认语言为英文
        if language_code == BkLanguage.ALL:
            language_key = BkLanguage.EN
        else:
            language_key = language_code

        # 设置Django国际化语言
        if language_key == "zh-cn":
            # zh-cn在Django中不建议用， 统一使用zh-hans
            language_key = "zh-hans"

        language = get_supported_language_variant(language_key)
        translation.activate(language)
        if request:
            request.LANGUAGE_CODE = translation.get_language()
        return True

    @staticmethod
    def get_user_language(bk_username, default=None):
        language = BkLanguage.current_language()

        try:
            res = BkLoginApi.get_user_info(
                {
                    "bk_username": bk_username,
                }
            )
            user_info = res.data if res.is_success() else {}
            if "language" in user_info:
                language = user_info["language"]
        except Exception:
            if default:
                language = default

        return language

    @staticmethod
    def translate(origin_string, language_code):
        """
        把当前origin_string翻译为指定语言
        :param origin_string:
        :param language_code:
        :return:
        """
        from pizza.settings_default import BK_SUPPORTED_LANGUAGES

        if language_code not in BK_SUPPORTED_LANGUAGES:
            return False

        language_key = language_code
        if language_key == "zh-cn":
            # zh-cn在Django中不建议用， 统一使用zh-hans
            language_key = "zh-hans"

        # 获取国际化翻译对象
        translator = translation._trans.translation(language_key)
        # 翻译
        target_message = translator.ugettext(origin_string)
        return target_message

    @staticmethod
    def to_en(origin_string):
        """
        把当前origin_string翻译为英文
        :param origin_string:
        :return:
        """
        language_key = BkLanguage.EN

        if language_key == "zh-cn":
            # zh-cn在Django中不建议用， 统一使用zh-hans
            language_key = "zh-hans"

        # 获取国际化翻译对象
        translator = translation._trans.translation(language_key)
        # 翻译
        target_message = translator.ugettext(origin_string)
        return target_message

    @staticmethod
    def to_cn(origin_string):
        """
        把当前origin_string翻译为中文
        :param origin_string:
        :return:
        """
        language_key = BkLanguage.CN
        if language_key == "zh-cn":
            # zh-cn在Django中不建议用， 统一使用zh-hans
            language_key = "zh-hans"

        # 获取国际化翻译对象
        translator = translation._trans.translation(language_key)
        # 翻译
        target_message = translator.ugettext(origin_string)
        return target_message

    translates_cache = None
    cache_lock = RLock()

    @classmethod
    def translate_multiply_by_config_db(cls, content_key):
        """
        根据配置库语言对照配置表进行翻译
        """
        from common.api.modules.meta import MetaApi

        target_language = BkLanguage.current_language()
        translates = cls.translates_cache
        if translates is None:
            with cls.cache_lock:
                if translates is None:
                    response = MetaApi.content_language_configs.list()
                    content_language_configs = response.data if response.is_success() else []
                    translates = {}
                    for config in content_language_configs:
                        if config["content_key"] not in translates:
                            translates[config["content_key"]] = {}
                        translates[config["content_key"]][config["language"]] = config["content_value"]
                    cls.translates_cache = translates
        return translates.get(content_key, {}).get(target_language, content_key)

    @staticmethod
    def translate_singly_by_config_db(content_key):
        """
        根据配置库语言对照配置表进行翻译
        """
        from common.api.modules.meta import MetaApi

        target_language = BkLanguage.current_language()
        translates = get_local_param("translates", {})
        if content_key not in translates or target_language not in translates[content_key]:
            response = MetaApi.content_language_configs.translate(
                {
                    "content_key": content_key,
                    "language": target_language,
                }
            )
            if response.is_success():
                translates.update({content_key: {target_language: response.data}})
        set_local_param("translates", translates)
        return translates.get(content_key, {}).get(target_language, content_key)

bktranslate = BkLanguage.translate_singly_by_config_db
bktranslates = BkLanguage.translate_multiply_by_config_db


from django.urls import path
from .views import BookDetail, BookList,MovieDetail, MovieList

urlpatterns = [
    path('books/',BookList.as_view(),name = 'book'),
    path('books/<int:pk>/', BookDetail.as_view() ,name ='singlebook'),
    path('movies/', MovieList.as_view(),name= 'movies'),
    path('movies/<int:pk>/', MovieDetail.as_view(), name = 'singlemovie')

]


from django.conf.urls import url
from . import views

app_name = 'inventory'

urlpatterns = [
    url(r'^$', views.start, name='start'),
    url(r'^about_us/$', views.about_us, name='about_us'),
    url(r'^contact/$', views.contact, name='contact'),
    url(r'^register/$', views.register, name='register'),
    url(r'^login_user/$', views.login_user, name='login_user'),
    url(r'^logout_user/$', views.logout_user, name='logout_user'),
    url(r'^dashboard/$', views.dashboard, name='dashboard'),
    url(r'^supplier/add_supplier/$', views.add_supplier, name='add_supplier'),
    url(r'^(?P<supplier_id>[0-9]+)/update_supplier/$', views.update_supplier, name='update_supplier'),
    url(r'^supplier/manage_supplier/$',views.manage_supplier, name='manage_supplier'),
    url(r'^delete_supplier/(?P<supplier_id>[0-9]+)/$', views.delete_supplier, name='delete_supplier'),
    url(r'^product/category/$', views.category, name='category'),
    url(r'^product/category1/$', views.category1, name='category1'),
    url(r'^delete_category/(?P<category_id>[0-9]+)/$', views.delete_category, name='delete_category'),
    url(r'^product/subcategory/$', views.subcategory, name='subcategory'),
    url(r'^product/subcategory1/$', views.subcategory1, name='subcategory1'),
    url(r'^delete_subcategory/(?P<subcategory_id>[0-9]+)/$', views.delete_subcategory, name='delete_subcategory'),
    url(r'^update_product/(?P<product_id>[0-9]+)/$', views.update_product, name='update_product'),
    url(r'^product/add_product/$', views.add_product, name='add_product'),
    url(r'^product/add_product1/$', views.add_product1, name='add_product1'),
    url(r'^get_product/$', views.get_product, name='get_product'),
    url(r'^product/manage_product/$', views.manage_product, name = 'manage_product'),
    url(r'^product/manage_product/view_product/(?P<product_id>[0-9]+)/$', views.view_product, name = 'view_product'),
    url(r'^delete_product/(?P<product_id>[0-9]+)/$', views.delete_product, name='delete_product'),
    url(r'^customer/add_customer1/$', views.add_customer1, name='add_customer1'),
    url(r'^customer/add_customer/$', views.add_customer, name='add_customer'),
    url(r'^customer/manage_customer/$', views.manage_customer, name = 'manage_customer'),
    url(r'^customer/delete_customer/(?P<customer_id>[0-9]+)/$', views.delete_customer, name='delete_customer'),
    url(r'^customer/update_customer/(?P<customer_id>[0-9]+)/$', views.update_customer, name='update_customer'),
    #url(r'^add_employee/$', views.add_employee, name='add_employee'),
    url(r'^business_profile/$',views.business_profile, name='business_profile'),
    url(r'^settings/localization/$',views.localization, name='localization'),

    url(r'^get_purchase/$', views.get_purchase, name='get_purchase'),
    url(r'^purchase/new_purchase/$', views.new_purchase, name='new_purchase'),
    url(r'^purchase/new_purchase/purchase/(?P<purchase_id>[0-9]+)/$', views.new_purchase_purchase, name='new_purchase_purchase'),

    url(r'^purchase/new_purchase/invoice/(?P<purchase_id>[0-9]+)/$', views.purchase_invoice, name='purchase_invoice'),

    url(r'^purchase/manage_purchase/invoice/(?P<purchase_id>[0-9]+)/$', views.invoice, name='invoice'),
    url(r'^purchase/manage_purchase/$', views.manage_purchase, name='manage_purchase'),
    url(r'^report/stock_report/$',views.stock_report, name='stock_report'),

    url(r'^order/new_order/$',views.new_order, name='new_order'),
    url(r'^order/new_order/order/(?P<order_id>[0-9]+)/$',views.new_order_order, name='new_order_order'),
    url(r'^order/new_order/checkout/(?P<order_id>[0-9]+)/$',views.checkout, name='checkout'),

    url(r'^get_discount/$', views.get_discount, name='get_discount'),
    url(r'^order/new_order/invoice/(?P<order_id>[0-9]+)/$', views.order_invoice, name='order_invoice'),
    url(r'^order/manage_order/$',views.manage_order, name='manage_order'),
    url(r'^order/manage_order/invoice/(?P<order_id>[0-9]+)/$',views.ordinvoice, name='ordinvoice'),
    url(r'^report/sales_report/$',views.sales_report, name='sales_report'),
    url(r'^report/sales_report1/$',views.sales_report1, name='sales_report1'),
    url(r'^report/sales_summary_report/$',views.sales_summary_report, name='sales_summary_report'),
    url(r'^report/sales_summary_report1/$',views.sales_summary_report1, name='sales_summary_report1'),
    url(r'^report/purchase_report/$',views.purchase_report, name='purchase_report'),
    url(r'^report/purchase_report1/$',views.purchase_report1, name='purchase_report1'),
    url(r'^notification/$',views.notification, name='notification'),
    url(r'^cancelled_order/$',views.cancelled_order, name='cancelled_order'),
    url(r'^forgot_pasword/$',views.forgot_password, name='forgot_password'),
    url(r'^submit/$',views.submit, name='submit'),

]


from django.urls import path
from . import views

urlpatterns = [

    path('',views.home,name='home'),
    path('blog_details/<int:pk>/',views.blog_details,name='blog_details'),
    # path('blog/',views.blog,name='blog'),
    path('contact/',views.contact,name ='contact'),

    # path('accounts/login',views.login_user,name='login_user'),
    # path('accounts/register',views.register_user,name='register_user')

]


import threading
import time

# funcion target del hilo
def thread_function(name):
    print(f"Starting thread: {name}")
    time.sleep(3)
    print(f"Ending thread: {name}")

# creo el hilo
x = threading.Thread(target=thread_function, args=(1,))

# lo inicio
x.start()

# espera a que termine
x.join()

print("We're done here.")


#Name:      Shazam Zafar
#Class:     Python (M5L5)
#Date:      November 29, 2018

#list for all the data given
#First letter of the flavor needs to be capital

flavors = ['Vanilla','Chocolate','Strawberry','Mint','Pistachio','Spumoni']
scoops = [1,2,3]
Itype = ['cone','bowl']

#Exceptions Class
class FlavorError(ValueError):
    def __init__(self, arg):
        self.strerror = arg
        self.args = {arg}

#Exceptions Class
class ScoopsError(ValueError):
    def __init__(self, arg):
        self.strerror = arg
        self.args = {arg}

#Creating menu class for IceCream store
class IceCreamStore:
        def __init__(self, flavor, scoop, Itype):
            self.__flavor = flavor
            self.__scoops = scoop
            self.__Itype = Itype

        #creating class for flavor, scoop and type
        def set_falvour(self, flavor):
            self.__flavor = flavor

        def set_scoop(self, scoop):
            self.__scoops = scoop

        def set_type(self, Itype):
            self.__Itype = Itype

        #calling the flavor, scops and type
        def get_falvour(self):
            return self.__flavor

        def get_scoop(self):
            return self.__scoops

        def get_type(self):
            return self.__Itype

# loop asking user again and again

while True:
    #Asking user for input
    flavor =input("Enter a flavor of ice cream: ")
    Scoops = (input("Enter the number of scoops "))
    Type = (input("Would you like a cone or bowl? "))
    myIceCream = IceCreamStore(flavor,Scoops,Type)
    excount = 0
    #Exceptions for flavor
    try:
        if myIceCream.get_falvour() not in flavors.__str__():
            raise FlavorError('{0} is not on the menu.'.format(myIceCream.get_falvour()))
    except FlavorError as e:
        print(e.strerror)
        excount+=1
    #Exception for scoops
    try:
        if myIceCream.get_scoop() not in scoops.__str__():
            raise ScoopsError('we do not offer that many scoops')
    except ScoopsError as e:
        print(e.strerror)
        excount+=1
    # printing the final output
    if excount <=0:
        print(Scoops,"Scoops of", flavor, "in a",Type)
    print()


import os
import sys
import subprocess
import logging

default_logger = logging.getLogger(name='aligner')

def _find_bash():
    """Originally from https://github.com/chapmanb/bcbio-nextgen/blob/master/bcbio/provenance/do.py"""

    try:
        which_bash = subprocess.check_output(["which", "bash"]).strip()
    except subprocess.CalledProcessError:
        which_bash = None
    for test_bash in [which_bash, "/bin/bash", "/usr/bin/bash", "/usr/local/bin/bash"]:
        if test_bash and os.path.exists(test_bash):
            return test_bash
    raise IOError("Could not find bash in any standard location. Needed for unix pipes")

def _normalize_cmd_args(cmd):
    """Normalize subprocess arguments to handle list commands, string and pipes.
Piped commands set pipefail and require use of bash to help with debugging
intermediate errors.
Originally from https://github.com/chapmanb/bcbio-nextgen/blob/master/bcbio/provenance/do.py
"""
    if isinstance(cmd, basestring):
        # check for standard or anonymous named pipes
        if cmd.find(" | ") > 0 or cmd.find(">(") or cmd.find("<("):
            return "set -o pipefail; " + cmd, True, _find_bash()
        else:
            return cmd, True, None
    else:
        return cmd, False, None

def _do_run(cmd, output_file=None, input_file=None, logger=default_logger):
    """Perform running and check results, raising errors for issues.
Originally from https://github.com/chapmanb/bcbio-nextgen/blob/master/bcbio/provenance/do.py
"""
    cmd, shell_arg, executable_arg = _normalize_cmd_args(cmd)

    if output_file is None:
        stdout_value = subprocess.PIPE
    else:
        stdout_value = output_file

    logger.info('Starting: %s' % cmd)
    s= subprocess.Popen(cmd, shell=shell_arg, executable=executable_arg,
                         stdout=stdout_value,
                         stderr=subprocess.STDOUT,
                         stdin=input_file)
    stdoutdata, stderrdata = s.communicate()
    exitcode = s.poll()
    if exitcode is not None and exitcode != 0:
        error_msg += " ".join(cmd)
        error_msg += " ".join(stdoutdata)
        error_msg += " ".join(stderrdata)
        s.communicate()
        s.stdout.close()
        raise subprocess.CalledProcessError(exitcode, error_msg)

    stdoutdata = stdoutdata.split("\n")
    for line in stdoutdata:
        logger.info(line)
    if(stderrdata != None):
        stderrdata = stderrdata.split("\n")
        for line in stderrdata:
            logger.info(line)

    """
    while True:
        stdout_line = stdoutdata.readline()
        if stdout_line:
            debug_stdout.append(stdout_line)

            logger.debug(stdout_line.rstrip())

        exitcode = s.poll()
                break
        sys.stdout.flush()

    s.communicate()
    s.stdout.close()
    """

    logger.info('Completed: %s' % cmd)
    return exitcode


import matplotlib.pyplot as plt
import numpy as np
import random
from itertools import repeat
import pylab
import copy

def gen_signal():

    signal = []
    for x in range(10):
        signal += list(repeat(random.randint(-1,1), 100))

    return np.array(signal)

def cross_correlate(xs, ys, minval=False):
    """Takes two arrays and finds the x-value of the second at which both correlate highest.
        xs and ys are the first and second signals, respectively, with minval being a boolean
        declaring whether or not the x-value of minimum correlation should be found as well."""

    maxcorr = 0
    mincorr = 5
    xmax = 0
    xmin = 0
    for X in range(len(ys) - len(xs)):
        corr = 0
        for x in range(len(xs)):
            corr +=  (xs[x] * ys[x + X])
        if corr > maxcorr:
            maxcorr = corr
            xmax = X
        if minval and corr < mincorr:
            mincorr = corr
            xmin = X

    plt.subplot(211)
    plt.plot(xs, color="y")
    plt.ylabel("One-Dimensional Signal Pre-image")
    plt.subplot(212)
    plt.axvline(x=xmax, linewidth=1, color='r')
    if minval:
        plt.axvline(x=xmin, linewidth=1, color='blue')
        plt.text(s=("Min: " + str(xmin)), x=xmin-100, y=1)
    plt.plot(ys, color="y")
    pylab.ylim(-1.5, 1.5)
    plt.ylabel("Image Translated With Noise Added")
    plt.text(s=("Max: " + str(xmax)), x=xmax-100, y=1)

    plt.show()

def addNoise(xs):

    xs = list(map(lambda x: x + np.random.normal(0, 0.5), xs))
    return xs

def main():

    signal = gen_signal()

    frontzeros = random.randint(1000, 2000)
    backzeros = random.randint(1000, 2000)
    image = np.append(np.zeros(frontzeros), signal)
    image = np.append(image, np.zeros(backzeros))
    image = addNoise(image)

    # If you want to disable the display of minimum value, just change the below boolean to 'False'."
    cross_correlate(signal, image, True)

main()