import datetime
import io
import json
import traceback
import discord
import matplotlib.pyplot as plt
from statistics import mean, median
from discord.ext import commands
from views import dbView, confirmView, categoryView
from cogs import utils
import numpy as np
from matplotlib.collections import LineCollection
from matplotlib.colors import ListedColormap, BoundaryNorm
with open("./config.json") as f: configData = json.load(f)

class TrendsCog(commands.Cog, name='Trends Cog'):
    # Description of this cog (cog.__doc__)
    """OCR cog description"""

    def __init__(self, client):
        self.client = client

    @commands.command(aliases=['trend'])
    async def trends(self, ctx, *, server):
        """Test plotting of trends"""

        document = self.client.BMAH_coll.find_one({"name": "prices"})
        del document["name"]
        del document["_id"]

        # Create embed
        embed = discord.Embed(title=server.title(), color=self.client.color)
        embed.set_author(name="Trends", icon_url=ctx.guild.icon.url)

        # Create dict with all median prices -- {Mage : {Frostfire Circlet: 12555, Frostfire Shoulderpads: 17800, ...}, ...}
        median_prices = {}
        for category_name, items_obj in document.items():
            median_prices[category_name] = {}
            for item_name, price_list in items_obj.items():
                if price_list:
                    median_prices[category_name][item_name] = int(median(self.get_price(price_list)))

        # Get prices
        dict_of_under = {} # Format : {1: 100, 2: 50, 3: 66, 4: 75...} --> {counter (total) : ratio}
        total_items = 0
        qty_under = 0 #qty of items that were under the median
        for category_name, items_obj in document.items():
            for item_name, price_list in items_obj.items():
                for price_str in price_list:
                    if server.lower() in self.get_server(price_str).lower():
                        total_items += 1
                        price = self.get_price(price_str)
                        if price <= median_prices[category_name][item_name]:
                            qty_under += 1
                        dict_of_under[total_items] = round(qty_under / total_items * 100, 1)

        dataX = list(dict_of_under.keys())[3:]
        dataY = list(dict_of_under.values())[3:]

        file = self.create_plot(dataX, dataY)
        # image = discord.File('./images/graph.png', filename='graph.png')
        embed.set_image(url=f'attachment://graph.png')
        await ctx.send(file=file, embed=embed)

    def create_plot(self, dataX, dataY):
        # PLOTTING ----------------------------------------
        plt.style.use('dark_background')

        # Size/ratio of plot
        fig, ax = plt.subplots()#figsize=(1, 1), dpi=500)

        # Draw horizontal line
        plt.axhline(y=50, color='#4d5657', linewidth=0.4, linestyle='--', label='50%')  # [y, xmin, xmax]

        # Set limits
        #plt.xlim(min(data)-1000, max(data)+1000)
        plt.ylim(0, 100)

        # Set labels
        plt.xlabel("Records")
        plt.ylabel("% Under")

        # Colors
        # select how to color
        cmap = ListedColormap(['blue', 'lawngreen'])
        norm = BoundaryNorm([0, 50, 100], cmap.N)

        # get segments
        xy = np.array([dataX, dataY]).T.reshape(-1, 1, 2)
        segments = np.hstack([xy[:-1], xy[1:]])

        # make line collection
        lc = LineCollection(segments, cmap=cmap, norm=norm)
        lc.set_array(dataY)
        ax.add_collection(lc)

        # Create plot
        plt.plot(dataX, dataY)

        # Show legend
        plt.legend(frameon=False)

        # Save figure
        arr = io.BytesIO()
        plt.savefig(arr, transparent=True, bbox_inches='tight', pad_inches=None)
        plt.close(fig)

        # Create discord File
        arr.seek(0)
        file = discord.File(arr, filename='graph.png')

        return file

    @commands.command()
    async def listtest(self, ctx, without=None):
        """Shows the list of today's items that were scanned by the bot"""
        # content is a separate function because it is called with the selects
        try:
            document = self.client.BMAH_coll.find_one({"name": "todays_items"})
            if without is None:
                await self.list_fct(ctx.guild, ctx.channel, calledWithWithout=False, document=document, client=self.client)
            elif without.lower() == "without":
                view = categoryView.categoryView(document=document, client=self.client)
                view.message = await ctx.send("This will show today's list without a set of items you select.\nWhat categories are the items from?", view=view)
        except:
            await ctx.send(f'There was an error. Error log for Dev: ```{traceback.format_exc()}```')

    # Code changes
    async def list_fct(self, guild, channel, calledWithWithout, document, client, withServers=False, serverDocument=None):
        def date_suffix(myDate):
            date_suffix = ["th", "st", "nd", "rd"]

            if myDate % 10 in [1, 2, 3] and myDate not in [11, 12, 13]:
                return date_suffix[myDate % 10]
            else:
                return date_suffix[0]

        try:
            #document = self.client.BMAH_coll.find_one({"name": "todays_items"})
            emoji_dict = client.BMAH_coll.find_one({"name": "emojis"})

            # check if there are items in today's items
            if not calledWithWithout and len(document.keys()) == 3:
                embed = discord.Embed(description="There are no items in today's list", color=client.color)
                embed.set_author(name="Today's BMAH item list", icon_url=guild.icon.url)
                embed.timestamp = datetime.datetime.utcnow()
                await channel.send(embed=embed)
                return

            # if ;serverlist, fix serverDocument
            if withServers:
                del serverDocument["name"]
                del serverDocument["_id"]

            # Create embed
            now = datetime.datetime.now().strftime('%A, %B %d')
            date_suffix = date_suffix(int(datetime.datetime.now().strftime('%d')))
            embed = discord.Embed(description=f"The BMAH item list for **{now}{date_suffix}** is the following:", color=client.color) #title=f'{emoji} BMAH item list - {now}{date_suffix}')
            embed.set_author(name=f'BMAH item list', icon_url=guild.icon.url) #TODO: uncomment?
            embed.timestamp = datetime.datetime.now()
            embed.set_footer(text=guild.name)

            # get dict items
            item_list = [*document] # list of dict keys
            unwanted = {'Pets', 'Mounts', 'Misc', '_id', 'name', 'Toys'}
            item_list_sorted = sorted([item for item in item_list if item not in unwanted])
            wanted = {"Misc", "Pets", "Mounts", "Toys"}
            liste_a_part = [item for item in item_list if item in wanted]

            # order dict
            ordered_dict = {}
            for item_name in item_list_sorted:
                ordered_dict[f'{item_name}'] = document[f'{item_name}']

            # dict a part
            dict_a_part = {}
            for item_name in liste_a_part:
                dict_a_part[f'{item_name}'] = document[f'{item_name}']

            # create armor fields
            embed.add_field(name="\u200b", value="\u200b")
            embed.add_field(name="\u200b", value="\u200b")
            embed.add_field(name="\u200b", value="\u200b")
            if len(ordered_dict) == 0:
                embed.add_field(name="No armor items", value="\u200b", inline=True)
                embed.add_field(name="\u200b", value="\u200b")
                embed.add_field(name="\u200b", value="\u200b")

            # Create T3 (Armor) fields
            categories = ''
            items = ''
            servers = ''
            count = 0
            last_category = list(ordered_dict)[-1]
            for category, item_dict in ordered_dict.items():
                category_name = emoji_dict[f'{category}'] + " " + category
                categories += f'{category_name}\n'
                last_item = list(item_dict)[-1]
                for item, amount in item_dict.items():
                    # if ;listservers
                    if withServers:
                        for server, item_list in serverDocument.items():
                            for item_fromServerDoc in item_list:
                                if item.lower() in item_fromServerDoc.lower():
                                    items += f'ðŸ¡¢ {item} __*({server.capitalize()})*__\n'
                    else:
                        items += f'{item} {"("+ str(amount) +")" if amount > 1 else ""}\n'
                        categories += '\u200b\n'
                    if item == last_item:
                        items += "\u200b"

                if count % 3 == 0:
                    categories = ''
                    items = ''
                    servers = ''
                    print(categories)
                    print(items)
                    embed.add_field(name='Category', value=categories, inline=True)
                    embed.add_field(name='Items', value=items, inline=True)
                    embed.add_field(name="\u200b", value="\u200b")
                elif category == last_category:
                    embed.add_field(name='Category', value=categories, inline=True)
                    embed.add_field(name='Items', value=items, inline=True)
                    embed.add_field(name="\u200b", value="\u200b")
                count += 1

            # skip fields if fields not a multiple of 3
            if (len(ordered_dict)+1) % 3 == 0:
                # on finit avec 2 fields, donc en ajouter un vide
                embed.add_field(name="\u200b", value="\u200b")
            elif (len(ordered_dict)+2) % 3 == 0:
                # on finit avec 1 field, donc en ajouter 2 vides
                embed.add_field(name="\u200b", value="\u200b")
                embed.add_field(name="\u200b", value="\u200b")

            # Add Misc, Pets, Mounts
            if len(dict_a_part) == 0:
                embed.add_field(name="No Pets, Mounts or Misc items", value="\u200b", inline=True)
            else:
                categories = ''
                items = ''
                servers = ''
                count = 0
                last_category = list(ordered_dict)[-1]
                for category, item_dict in dict_a_part.items():
                    for item, amount in item_dict.items():
                        # if ;listservers
                        if withServers:
                            for server, item_list in serverDocument.items():
                                for item_fromServerDoc in item_list:
                                    if item.lower() in item_fromServerDoc.lower():
                                        items += f'ðŸ¡¢ {item} __*({server.capitalize()})*__\n'
                        else:
                            items += f'{item} {"(" + str(amount) + ")" if amount > 1 else ""}\n'
                            categories += '\u200b\n'

                    if count % 3 == 0:
                        categories = ''
                        items = ''
                        servers = ''
                        embed.add_field(name='Category', value=categories, inline=True)
                        embed.add_field(name='Items', value=items, inline=True)
                        embed.add_field(name="\u200b", value="\u200b")
                    elif category == last_category:
                        embed.add_field(name='Category', value=categories, inline=True)
                        embed.add_field(name='Items', value=items, inline=True)
                        embed.add_field(name="\u200b", value="\u200b")
                    count += 1

            # skip fields if fields not a multiple of 3
            #if (len(dict_a_part)+1) % 3 == 0:
            #    # on finit avec 2 fields, donc en ajouter un vide
            #    embed.add_field(name="\u200b", value="\u200b")
            #elif (len(dict_a_part)+2) % 3 == 0:
            #    # on finit avec 1 field, donc en ajouter 2 vides
            #    embed.add_field(name="\u200b", value="\u200b")
            #    embed.add_field(name="\u200b", value="\u200b")

            #await ctx.message.delete()
            await channel.send(embed=embed)
        except:
            await channel.send(f'There was an error. Error log for Dev: ```{traceback.format_exc()}```')

    def get_price(self, price_string):
        """Get price out of the prices database. Format is "442500-Yseras" or 442500. Shoots only the price in int format."""
        if type(price_string) is int:
            return price_string
        elif type(price_string) is str:
            # string format of type "442500-Yseras"
            price_int = int(price_string.split('-')[0])
            return price_int
        # if list of prices
        elif type(price_string) is list:
            return [self.get_price(x) for x in price_string]

    def get_server(self, price_string):
        """Get server out of the prices database. Format is "442500-Yseras" or 442500. Shoots only the server, or "x" if none set."""
        if type(price_string) is int:
            return "x"
        else:
            # string format of type "442500-Yseras"
            server_name = price_string.split('-')[1]
            return server_name

async def setup(client):
    await client.add_cog(TrendsCog(client))
    print('Trends cog is loaded')


from collections import defaultdict
for _ in range(int(input())):
    m = int(input())
    arr = list(map(int, input().split()))
    arr = list(set(arr))
    n = int(input())
    def_dict = defaultdict(list)
    count = 0
    for i in range(m):
        total = 0
        while total < n:
            total += arr[i]
            if len(def_dict[n-total]) != 0:
                k = def_dict[total]
                for x in k:
                    count += len(def_dict[x])
            def_dict[total].append(arr[i])
        if total == n:
            count += 1
        print('count: ' + str(count))
        print('total: ' + str(total))
    print(count)
    print(def_dict)


from typing import List, Optional, Final

class TextHandler:

    HEADER: Final = '<STR>'
    FOOTER: Final = '<END>'

    @staticmethod
    def remove_indicator(msg: str) -> Optional[str]:
        if not msg.startswith(TextHandler.HEADER) or not msg.endswith(TextHandler.FOOTER):
            return None
        else:
            return msg[len(TextHandler.HEADER):len(TextHandler.FOOTER) * -1]

    @staticmethod
    def insert_indicator(msg: str) -> str:
        return TextHandler.HEADER + msg + TextHandler.FOOTER

    @staticmethod
    def encode_msg(msg: str) -> List[List[int]]:
        encoded_msg = msg.encode('utf-8')
        return [[(byte >> i) & 1 for i in range(7, -1, -1)] for byte in encoded_msg]

    @staticmethod
    def decode_msg(byte_arr: List[List[int]]) -> str:
        byte_str = bytearray()
        for byte in byte_arr:
            tmp = 0
            for bit in byte:
                tmp = tmp * 2 + bit
            byte_str.append(tmp)
        return byte_str.decode('utf-8')


from django import forms
from django.utils.safestring import mark_safe
from django.conf import settings

class SliderWidget(forms.TextInput):

    def render(self, name, value, attrs=None):
        return mark_safe(u"""

                <input id="id_lecture_duration" name="lecture_duration" type="hidden"/>

            """)

    class Media:
        css = {
               'all': ('http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.13/themes/sunny/jquery-ui.css', settings.STATIC_URL + 'lectures/widgets/css/slider.css',)
        }
        js = ('http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.13/jquery-ui.min.js',
              settings.STATIC_URL + 'lectures/widgets/js/slider.js',)


import plotly.graph_objects as go
import numpy as np

"""
The following is based on Figure 3 from https://www.frontiersin.org/articles/10.3389/fnins.2012.00181/full
(Communication and control by listening: toward optimal design of a two-class auditory streaming brain-computer interface).

This is a visualization tool for observing how two Event Related Potentials interact with variable spacing.

Leonardo Ferrisi
"""

# Generate x values
x = np.linspace(0, 1000, 1000)

amplitude_modifier = 35 # Scale to reduce amplitude of sine waves

# Create array of zeroes with 4000 samples
zeroes = np.zeros(1000)

noise = np.random.normal(scale=0.009, size=zeroes.size)

SIGNAL_PERIOD = 322
FULL_PERIOD = 1000

P2_2_P3_SAMPLE = 240

SIGNAL_OFFSET = 155

# ERPs

erp_offset = - 0.4
erp_offset2 = -0.2

def generate_left_erp():

    offset = 30
    # Left Stimulus
    left_raw = np.sin((x-SIGNAL_OFFSET)/amplitude_modifier) + erp_offset
    left_raw_2 = np.sin(x / amplitude_modifier) + erp_offset2

    # Component 1 - The N1 and P2
    z_start = zeroes[0:offset]
    comp1 =  np.concatenate((z_start,left_raw[offset:P2_2_P3_SAMPLE]))
    # Component 2 - The P3
    comp2 = left_raw_2[P2_2_P3_SAMPLE:SIGNAL_PERIOD]

    left_erp =  np.concatenate((comp1, comp2, zeroes[0:FULL_PERIOD-SIGNAL_PERIOD]))
    #left_erp -= left_erp.flat[0]
    left_erp = left_erp + noise
    trace_left = go.Scatter(x=x, y=left_erp, name="Response to Left Stimuli (Attended)")

    return left_erp, trace_left

def generate_right_erp(offset=0):

    zerooffset = 39
    right_sig_inital_zeros = 44

    # Right Stimulus
    rightstim_modifer = 2
    right_raw = ( np.sin((x-((SIGNAL_OFFSET+zerooffset)-right_sig_inital_zeros))/amplitude_modifier) / rightstim_modifer ) # + erp_offset
    right_raw2 = ( np.sin(x / amplitude_modifier) / rightstim_modifer ) # + erp_offset2

    # Component1
    right_zero_comp = zeroes[0:zerooffset]
    r_comp1 = right_raw[zerooffset:P2_2_P3_SAMPLE]
    right_comp1 = np.concatenate((right_zero_comp, r_comp1))

    # Component2
    right_comp2 = right_raw2[P2_2_P3_SAMPLE:SIGNAL_PERIOD]

    z1 = zeroes[0:(FULL_PERIOD-SIGNAL_PERIOD)-offset]
    z2 = zeroes[0:offset]

    right_erp = np.concatenate((z2, right_comp1, right_comp2, z1)) # starts at 0
    #right_erp -= right_erp.flat[0]
    right_erp = right_erp + noise

    trace_right = go.Scatter(x=x, y=right_erp, name="Response to Right Stimuli")

    return right_erp, trace_right

left_erp, trace_left = generate_left_erp()

right_erp, trace_right = generate_right_erp(offset=0)

trace_combo = go.Scatter(x=x, y=(left_erp + right_erp), name="Combo")

# Create a series of steps in steps of in 1ms incriments
steps = [dict(label='0 ms', method='update', args=[{'visible': [True, True]}, {'title': 'Move slider to align right'}])]
for offset in np.arange(1, 601, 1):

    freq_per_stream = round(1000/(offset*2),4)
    freq_bt_streams = round(1000/offset, 4)

    next_left_start_idx = None
    next_right_start_idx = None

    # For the offset, append a copy of the erp after the offset and crop it to fit 1000ms / 1000 samples
    if (offset*2) > SIGNAL_PERIOD:
        # make another left
        next_left = left_erp

        next_left_start_idx = offset*2
        next_left_end_idx = (offset*2)+SIGNAL_PERIOD

        if next_left_start_idx < FULL_PERIOD:

            # if next_left_end_idx <= FULL_PERIOD:
            # print(f"Next left end: {next_left_end_idx}")
            z = zeroes[0: ( (FULL_PERIOD) - ( next_left_end_idx )) ]
            # print(f"Zero size = {z.size}")
            next_left_temp = np.concatenate(( next_left[0:SIGNAL_PERIOD], z ))

            l = np.concatenate(( left_erp[0: (offset*2)], next_left ))
            left_erp = l[0:FULL_PERIOD]

    right_erp, trace_right = generate_right_erp(offset=offset)

    # # For the right one
    # if (offset*3) > (offset+SIGNAL_PERIOD):
    #     next_right = right_erp
    #     next_right_start_idx = offset*3
    #     next_right_end_idx = (offset*3)+SIGNAL_PERIOD

    #     if next_right_start_idx < FULL_PERIOD:

    #         if next_right_end_idx <= FULL_PERIOD:
    #             # print(f"Next r end: {next_right_end_idx}")
    #             z = zeroes[0: ( (FULL_PERIOD) - ( next_right_end_idx )) ]
    #             # print(f"Zero size = {z.size}")
    #             next_right_temp = np.concatenate(( next_right[0:SIGNAL_PERIOD], z ))

    #             r = np.concatenate(( right_erp[0: next_right_start_idx], next_right_temp ))
    #             right_erp = r[0:FULL_PERIOD]

    print(f"Offset: {offset}, Next Left starts at: {next_left_start_idx}, Next Right starts at: {next_right_start_idx}")

    # print(f"For offset: {offset}, Next Left: {next_left_start_index}")

    # next_right_start_index = (offset)

    combo = left_erp - right_erp # using Subtraction as opposed to sum

    steps.append(dict(label=f'Between Stream Period: {offset} ms', method='update', args=[{'y': [combo, left_erp, right_erp]}, {'title': f'Between Stream Period of: {offset} ms | Within Stream Period of: {offset*2} ms | Frequency of: {freq_per_stream} Hz per stream | Frequency of: {freq_bt_streams} Hz between streams'}]))

# Create a Plotly figure
fig = go.Figure(data=[trace_combo, trace_left, trace_right])

sliders = [dict(
        active = 1,
        steps = steps
    )]

fig.update_layout(
    sliders=sliders,
    title = 'Move slider to align right response',
    xaxis = dict(
        range = [0, 1000],
        title = 'Time (ms)'
    ),
    yaxis = dict(
        range = [-1.5, 1.5],
        title = 'Amplitude (uV)'
    )
)

# Show the figure
fig.show()


#!/usr/bin/env python3

import numpy as np
import pandas as pd
import os
import matplotlib.pyplot as plt
import math
import streamlit as st
import sys
from PIL import Image
import logomaker
import gzip
import io

def ExtractAlignmentPosition(tax_id,sp_type,region):
	"""Extracts aligned sequences from gzipped file"""

	#Ensure correct case for input file
	region_lowercase = region.lower()
	region_uppercase = region.upper()
	sp_type = sp_type.upper()

	#Read gzipped content, save in object
	input_ = gzip.GzipFile('../generated_data/data_website/Aligned_sequences/'+tax_id+"/"+sp_type+"_align_"+region_lowercase+".txt.gz", 'rb')
	zipfile_content = input_.read()
	input_.close()

	#Write saved object to file to unzip it
	output = open('../generated_data/data_website/Aligned_sequences/'+tax_id+"/"+sp_type+"_align_"+region_lowercase+".txt", 'wb')
	output.write(zipfile_content)
	output.close()

	#Open alignment-file
	infile = open('../generated_data/data_website/Aligned_sequences/'+tax_id+"/"+sp_type+"_align_"+region_lowercase+".txt", "r")
	line = infile.readline()

	#Save the length of the aligned sequences
	len_seqs = len(line[:-1])

	infile.close()

	#Open file showing positions for alignments
	infile_positions = open('../generated_data/data_website/Aligned_sequences/'+tax_id+"/"+"align_positions.tab", "r")
	region_matched = False

	try:
		for line in infile_positions:
			splits = line.split("\t")

			#Find information about alignment positions for the chosen SP type
			if splits[0] == sp_type:

				#Select the border alignments should be based on (N, H, C)
				if splits[1] == region_uppercase:

					#Extract position 1 of logo (selected region border)
					alignment_position = splits[2]
					region_matched = True

		if not region_matched:
			raise ValueError
	except ValueError as err:
		print("Error! The signal peptide type {0} does not have an {1}-region.".format(sp_type,region))

	infile_positions.close()
	#Remove the unzipped file (only store gzipped version)
	os.remove('../generated_data/data_website/Aligned_sequences/'+tax_id+"/"+sp_type+"_align_"+region_lowercase+".txt")

	return alignment_position, len_seqs

def MakeLogo(tax_id,sp_type,region, low_limit, high_limit, scient_name, color_scheme, keep_zero, max_bits_plot):
	"""Create sequence logos to be display using Streamlit introducing dynamic elements"""

	#Define default color scheme
	color_1990 = {"K": "blue", "R": "blue", "H": "blue",
	"D": "red", "E": "red",
	"A": "black", "V": "black", "L": "black", "I": "black",
	"P": "black", "W": "black", "F": "black", "M": "black",
	"N": "green", "G": "green", "Q": "green", "S": "green",
	"C": "green", "Y": "green", "T": "green",
	"X": "magenta"}

	#Define colorscheme-codes
	if color_scheme == "Default":
		color_logo = color_1990
	elif color_scheme == "Hydrophobicity":
		color_logo = "hydrophobicity"
	elif color_scheme == "Charge":
		color_logo = "charge"
	elif color_scheme == "Chemistry":
		color_logo = "chemistry"

	#Ensure correct case for input file
	region_lowercase = region.lower()
	region_uppercase = region.upper()
	sp_type = sp_type.upper()

	#Read gzipped content, save in object
	input_ = gzip.GzipFile('../generated_data/data_website/Aligned_sequences/'+tax_id+"/"+sp_type+"_align_"+region_lowercase+".txt.gz", 'rb')
	zipfile_content = input_.read()
	input_.close()

	#Write saved object to file to unzip it
	output = open('../generated_data/data_website/Aligned_sequences/'+tax_id+"/"+sp_type+"_align_"+region_lowercase+".txt", 'wb')
	output.write(zipfile_content)
	output.close()

	#Open alignment-file
	infile = open('../generated_data/data_website/Aligned_sequences/'+tax_id+"/"+sp_type+"_align_"+region_lowercase+".txt", "r")

	seqs = []

	#Store all SP sequences as strings in a list
	for line in infile:
		seqs.append(line[:-1])

	infile.close()

	#Open file showing positions for alignments
	infile_positions = open('../generated_data/data_website/Aligned_sequences/'+tax_id+"/"+"align_positions.tab", "r")
	region_matched = False

	try:
		for line in infile_positions:
			splits = line.split("\t")

			#Find information about alignment positions for the chosen SP type
			if splits[0] == sp_type:

				#Select the border alignments should be based on (N, H, C)
				if splits[1] == region_uppercase:

					#Extract position 1 of logo (selected region border)
					alignment_position = splits[2]
					region_matched = True

		if not region_matched:
			raise ValueError
	except ValueError as err:
		print("Error! The signal peptide type {0} does not have an {1}-region.".format(sp_type,region))

	infile_positions.close()

	#Remove unzipped file
	os.remove('../generated_data/data_website/Aligned_sequences/'+tax_id+"/"+sp_type+"_align_"+region_lowercase+".txt")

	if int(alignment_position) == 0:
		st.info("No signal peptides of type " + sp_type + " were detected for this group.")

	else:
		def __SetPositions(low_limit, high_limit, keep_zero):
			"""Set lower limit and upper limit of position range for logo,"""
			"""Make sure input is correctly given"""
			try:
				if int(low_limit) > 0:
					raise ValueError
			except ValueError as err:
				print("The lower limit of the selected range must be a negative number. Your input lower input number {0} will be converted to -{0}.".format(low_limit))
				low_limit = -int(low_limit)
			try:
				if int(high_limit) < 0:
					raise ValueError
			except ValueError as err:
				print("The high limit of the selected range must be a positive number. Your input upper input number {0} will be converted to {1}.".format(str(high_limit), str(high_limit)[1:]))
				high_limit = str(high_limit)[1:]
				high_limit = int(high_limit)

			#Store positions in a list
			positions = list(range(low_limit,high_limit+1))

			#Determine if position "0" should be displayed
			if keep_zero == "Yes":
				positions.remove(int(low_limit))
			elif keep_zero == "No":
				positions.remove(0)

			#Save number of positions to be in logo
			number_of_pos = int(high_limit) - int(low_limit)

			#Plot-window settings
			set_boundary = -low_limit - 0.5

			return positions, low_limit, high_limit, number_of_pos, set_boundary

		#Extract output from inner function
		func_output = __SetPositions(low_limit, high_limit, keep_zero)
		pos_range = func_output[0]
		lower = func_output[1] + int(alignment_position)
		upper = func_output[2] + int(alignment_position) - 1
		number_of_pos = func_output[3]
		set_boundary = func_output[4]

		#Make a dataframe of amino acid counts in each position in each sequence
		count_df = logomaker.alignment_to_matrix(sequences = seqs, to_type = "counts", characters_to_ignore = "-")

		Rseq = []
		inf_df = count_df.copy()

		#Compute preparation of position heights
		for i in range(len(count_df)):
			n = sum(count_df.loc[i])
			if n != 0:
				e_n = (20-1)/(2*math.log(2)*n)
				Hl = 0
				for j in range(len(count_df.loc[i])):
					freq = (count_df.loc[i][j]/n)
					if freq > 0:
						logfreq = math.log2(freq)
					else:
						logfreq = 0
					Hl += freq*logfreq
			else:
				e_n = 0
				Hl = 0
				freq = 0
				logfreq = 0
			H = -Hl
			if math.log2(20)-(H+e_n) < 0:
				Rseq.append(0)
			else:
				Rseq.append(math.log2(20)-(H+e_n))

		#Calculate information matrix based on count matrix
		for i in range(len(count_df)):
			n = sum(count_df.loc[i])
			for j in range(len(count_df.loc[i])):
				if n != 0:
					freq = count_df.loc[i][j]/n
					inf_df.loc[i][j] = freq*Rseq[i]
				else:
					freq = 0
					inf_df.loc[i][j] = freq*Rseq[i]

		#Only keep positions to be visualized
		inf_df = inf_df.loc[lower:upper]
		inf_df_cleaned = inf_df.copy()

		inf_df_cleaned.index = list(range(0,number_of_pos))

		count_df = count_df.loc[lower:upper]
		count_df_cleaned = count_df.copy()
		count_df_cleaned.index = list(range(0,number_of_pos))

		E_n = []
		heights = []

		#Calculate small sample correction factor
		for i in range(len(count_df_cleaned)):
		    n = sum(count_df_cleaned.loc[i])
		    if n != 0:
		    	e_n = (20-1)/(2*math.log(2)*n)

		    else:
		    	e_n = 0

		    #Calculation of error bar magnitude
		    errorbar = 2*e_n
		    E_n.append(errorbar)

		    #Append position height information to list
		    heights.append(sum(inf_df_cleaned.loc[i]))

		##Preparation for logo styling depending on SP type and region border
		if sp_type == "SP":
			sp_type_desc = "Sec SPI"
			if region_lowercase == "n":
				region_border = "n-h region border"
			elif region_lowercase == "h":
				region_border = "h-c region border"
			elif region_lowercase == "c":
				region_border = "cleavage site"

		elif sp_type == "LIPO":
			sp_type_desc = "Sec SPII"
			if region_lowercase == "n":
				region_border = "n-h region border"
			elif region_lowercase == "h":
				region_border = "cleavage site"

		elif sp_type == "PILIN":
			sp_type_desc = "Sec SPIII"
			if region_lowercase == "n":
				region_border = "cleavage site"

		elif sp_type == "TAT":
			sp_type_desc = "Tat SPI"
			if region_lowercase == "n":
				region_border = "n-h region border"
			elif region_lowercase == "h":
				region_border = "h-c region border"
			elif region_lowercase == "c":
				region_border = "cleavage site"

		elif sp_type == "TATLIPO":
			sp_type_desc = "Tat SPII"
			if region_lowercase == "n":
				region_border = "n-h region border"
			elif region_lowercase == "h":
				region_border = "cleavage site"

		##Make the Logo
		fig, ax = plt.subplots(1,1,figsize=[4,2])

		seq_logo = logomaker.Logo(inf_df_cleaned,
			stack_order = "big_on_top",
			font_name='DejaVu Sans',
			color_scheme=color_logo,
			vpad=0)

		#Style using Logo methods
		seq_logo.style_xticks(anchor=0, spacing=30, rotation=0)

		seq_logo.ax.set_xticks(range(len(pos_range)))
		seq_logo.ax.set_xticklabels(x for x in pos_range)
		seq_logo.ax.axvline(set_boundary, color='k', linewidth=1, linestyle=':')
		seq_logo.ax.set_title(sp_type_desc + " " + region_border + " in " + scient_name)
		seq_logo.ax.set_ylabel('Information (bits)')
		seq_logo.ax.set_xlabel('Position')
		seq_logo.ax.set_xlim([-1, len(inf_df_cleaned)])
		seq_logo.ax.set_ylim([0, max_bits_plot])	##Customize here

		#Prepare errorbar visualization; make error bar for each position
		x = np.linspace(0,number_of_pos-1,number_of_pos)
		y = heights

		#Define error for each position
		xerr = 0
		yerr = E_n

		#Insert errorbars
		seq_logo.ax.errorbar(x, y,
		            xerr=xerr,
		            yerr=yerr,
		            fmt='.',
		           color='grey',
		           ecolor='grey')
		seq_logo.ax.grid(False)

		logo_bytes = io.BytesIO()
		plt.savefig(logo_bytes, format='png')
		logo_bytes.seek(0)
		im = Image.open(logo_bytes)

		#Display the logo to streamlit
		st.image(im)


# Actions:
# For 3x3: 0-L1, 1-L2, 2-U1, 3-U2, 4-R1, 5-R2, 6-D1, 7-D2
# For 4x4: 0-L1, 1-L2, 2-L3, 3-U1, 4-U2, 5-U3, 6-R1, 7-R2, 8-R3, 9-D1, 10-D2, 11-D3
actions_3x3 = ['L1', 'L2', 'U1', 'U2', 'R1', 'R2', 'D1', 'D2']
actions_4x4 = ['L1', 'L2', 'L3', 'U1', 'U2', 'U3', 'R1', 'R2', 'R3', 'D1', 'D2', 'D3']
STEP_COST = 2.5     # 2 & 1 are much for faster for 3x3 with a bit less optimality

from copy import deepcopy
import os
import time

# This function converts the 2D State list into a concise integer for effective storage
def state_to_int(mat):
    size = len(mat)
    flat = [x for y in mat for x in y]
    # print(flat)
    int_state = 0

    if size == 3:
        m_fac = 1
        for x in flat:
            int_state += x*m_fac
            m_fac *= 9
    elif size == 4:
        for x in flat[::-1]:
            int_state <<= 4
            int_state += x

    return int_state

# This function converts the integer state into the simpler 2D list
def int_to_state(int_st, size):
    flat, mat = [], []
    if size == 3:
        for i in range(9):
            flat.append(int_st % 9)
            int_st //= 9
        mat = [flat[0:3], flat[3:6], flat[6:9]]
    elif size == 4:
        for i in range(16):
            flat.append(int_st & 15)
            int_st >>= 4
        mat = [flat[0:4], flat[4:8], flat[8:12], flat[12:16]]
    return mat

# Read the starting state from file
def read_init_state(s):
    with open(s, 'r') as f:
        lines = f.read().splitlines()   # or f.readlines()
    # print(lines)
    size = int(lines[0])
    j = 1
    state = []
    for line in lines[1: size+1]:
        state.append([int(s) for s in line.split(' ')])
    return state, lines[-1]

# Returns all the possible actions for a given state
def valid_actions(state):
    valids = []
    size = len(state)
    flat = [x for y in state for x in y]
    ind = flat.index(0)
    pos = (ind // size, ind % size)
    if size == 3:
        if pos[1] == 0:
            valids += [0, 1]     # L1, L2 valid
        elif pos[1] == 1:
            valids.append(0)    # Only L1 valid

        if pos[0] == 0:
            valids += [2, 3]     # U1, U2 valid
        elif pos[0] == 1:
            valids.append(2)    # Only U1 valid

        if pos[1] == 2:
            valids += [4, 5]     # R1, R2 valid
        elif pos[1] == 1:
            valids.append(4)    # Only R1 valid

        if pos[0] == 2:
            valids += [6, 7]     # D1, D2 valid
        elif pos[0] == 1:
            valids.append(6)    # Only D1 valid
    elif size == 4:
        if pos[1] == 0:
            valids += [0, 1, 2]     # L1, L2, L3 valid
        elif pos[1] == 1:
            valids += [0, 1]        # L1, L2 valid
        elif pos[1] == 2:
            valids.append(0)        # Only L1 valid

        if pos[0] == 0:
            valids += [3, 4, 5]     # U1, U2, U3 valid
        elif pos[0] == 1:
            valids += [3, 4]        # U1, U2 valid
        elif pos[0] == 2:
            valids.append(3)        # Only U1 valid

        if pos[1] == 3:
            valids += [6, 7, 8]     # R1, R2, R3 valid
        elif pos[1] == 2:
            valids += [6, 7]        # R1, R2 valid
        elif pos[1] == 1:
            valids.append(6)        # Only R1 valid

        if pos[0] == 3:
            valids += [9, 10, 11]   # D1, D2, D3 valid
        elif pos[0] == 2:
            valids += [9, 10]       # D1, D2 valid
        elif pos[0] == 1:
            valids.append(9)        # Only D1 valid

    return valids

# Applies the given action, on the given state and returns the new state
def move(state, action):
    nstate = deepcopy(state)
    size = len(state)
    flat = [x for y in state for x in y]
    ind = flat.index(0)
    pos = (ind // size, ind % size)
    if size == 3:
        if 0 <= action <= 1:
            nstate[pos[0]][pos[1]: pos[1]+action+2] = state[pos[0]][pos[1] + 1: pos[1]+action+2] + [0]  # Move Left
        elif 2 <= action <= 3:
            action -= 2
            for i in range(pos[0], pos[0]+action+1):
                nstate[i][pos[1]] = state[i + 1][pos[1]]  # Move Up
            nstate[pos[0]+action+1][pos[1]] = 0
        elif 4 <= action <= 5:
            action -= 4
            nstate[pos[0]][pos[1]-action-1: pos[1]+1] = [0] + state[pos[0]][pos[1]-action-1: pos[1]]  # Move Right
        elif 6 <= action <= 7:
            action -= 6
            for i in range(pos[0]-action-1, pos[0]):
                nstate[i + 1][pos[1]] = state[i][pos[1]]  # Move down
            nstate[pos[0]-action-1][pos[1]] = 0
    elif size == 4:
        if 0 <= action <= 2:
            nstate[pos[0]][pos[1]: pos[1]+action+2] = state[pos[0]][pos[1] + 1: pos[1]+action+2] + [0]  # Move Left
        elif 3 <= action <= 5:
            action -= 3
            for i in range(pos[0], pos[0]+action+1):
                nstate[i][pos[1]] = state[i + 1][pos[1]]  # Move Up
            nstate[pos[0]+action+1][pos[1]] = 0
        elif 6 <= action <= 8:
            action -= 6
            nstate[pos[0]][pos[1]-action-1: pos[1]+1] = [0] + state[pos[0]][pos[1]-action-1: pos[1]]  # Move Right
        elif 9 <= action <= 11:
            action -= 9
            for i in range(pos[0]-action-1, pos[0]):
                nstate[i + 1][pos[1]] = state[i][pos[1]]  # Move down
            nstate[pos[0]-action-1][pos[1]] = 0
    return nstate

# Returns what action led to the new state from the previous state
def return_action(state, new_state, size):
    state = [x for y in state for x in y]
    new_state = [x for y in new_state for x in y]
    state = state.index(0)
    new_state = new_state.index(0)
    state = (state // size, state % size)
    new_state = (new_state // size, new_state % size)

    if size == 3:
        if new_state[1] > state[1]:
            return new_state[1] - state[1] - 1  # Left
        elif new_state[0] > state[0]:
            return new_state[0] - state[0] + 1  # Up
        elif new_state[1] < state[1]:
            return state[1] - new_state[1] + 3  # Right
        elif new_state[0] < state[0]:
            return state[0] - new_state[0] + 5  # Down
    elif size == 4:
        if new_state[1] > state[1]:
            return new_state[1] - state[1] - 1  # Left
        elif new_state[0] > state[0]:
            return new_state[0] - state[0] + 2  # Up
        elif new_state[1] < state[1]:
            return state[1] - new_state[1] + 5  # Right
        elif new_state[0] < state[0]:
            return state[0] - new_state[0] + 8  # Down

# Gets an action's ID and returns it's String format
def find_action(state, new_state, size):
    state = int_to_state(state, size)
    new_state = int_to_state(new_state, size)
    if size == 3:
        return actions_3x3[return_action(state, new_state, size)]
    elif size == 4:
        return actions_4x4[return_action(state, new_state, size)]

# Checks if the given state is the final goal state
def is_goal_reached(state):
    if len(state) == 3:
        if state == [[0, 1, 2], [3, 4, 5], [6, 7, 8]]:
            return True
        elif len(state) == 4:
            if state == [[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11], [12, 13, 14, 15]]:
                return True
        return False

# The heuristic function for the A-Star Search
def calc_heuristic(state):
    flat = [x for y in state for x in y]
    heuristic = 0
    if len(state) == 3:
        for pos, num in enumerate(flat):
            heuristic += abs(pos//3 - num//3) + abs(pos%3 - num%3)  # If size = 3
    else:
        for pos, num in enumerate(flat):
            heuristic += abs((pos >> 2) - (num >> 2)) + abs((pos & 3) - (num & 3))  # If size = 4 (Fast / and %)
    return heuristic

# The structure of a node in the Graph we build, containing the necessary elements for the A* Algorithm
class Node:
    def __init__(self, prev_node, state, cost, heuristic):
        self.prev_node = prev_node
        self.state = state
        self.cost = cost
        self.eval_fn = cost + heuristic
        self.next_priority_node = None

# This is a priority queue made with double linked list
# The queue needs to be sorted upon addition of every item
# The process of sorting can be avoided by adding an item in a correct spot ensuring the order
# An node can be added inbetween the list without changing the address of the other nodes
# The removal of the element with least value (cost) has a time complexity of O(1)
class Priority_queue:
    def __init__(self, top_node=None):
        self.top_node = top_node

    def insert(self, node):
        if self.top_node is None:
            self.top_node = node
        elif node.eval_fn < self.top_node.eval_fn:
            node.next_priority_node = self.top_node
            self.top_node = node
        else:
            curr_node = self.top_node
            while curr_node.next_priority_node is not None and node.eval_fn > curr_node.eval_fn:
                curr_node = curr_node.next_priority_node
            node.next_priority_node = curr_node.next_priority_node
            curr_node.next_priority_node = node

    def pop(self):
        top_node = self.top_node
        self.top_node = top_node.next_priority_node
        return top_node

# The A-Star Algorithm
# Input: Gets the initial/starting state of the Sliding Block puzzle
# Output: Prints the list of actions leading the blocks from the initial to final state
def astar(init_state):
    size = len(init_state)
    start_node = Node(None, state_to_int(init_state), 0, calc_heuristic(init_state))
    priority_queue = Priority_queue(start_node)
    visited_nodes = {}
    visited_nodes.update({start_node.state: start_node})

    while True:
        current_node = priority_queue.pop()
        state = int_to_state(current_node.state, size)
        if is_goal_reached(state):
            break
        for action in valid_actions(state):
            new_state = move(state, action)
            new_state_int = state_to_int(move(state, action))
            if not (new_state_int in visited_nodes):
                node = Node(current_node, new_state_int, current_node.cost + STEP_COST, calc_heuristic(new_state))
                priority_queue.insert(node)
                visited_nodes.update({new_state_int: node})
        if priority_queue.top_node is None:
            break

    # Backtracking solution
    actions = []
    curr_state = current_node.state
    while True:
        current_node = current_node.prev_node
        if current_node == None:
            break
        prev_state = current_node.state
        actions.append(find_action(prev_state, curr_state, size))
        curr_state = prev_state
    actions.reverse()

    print("Actions:", actions)
    print("Steps:", len(actions))
    print("Individual_Steps:", sum([int(s[1]) for s in actions]))

overall_start = time.time()
directories = ['examples/easy/', 'examples/moderate/', 'examples/difficult/']
# directories = ['examples/extreme/']

test = 1
print("*********************************************************")
for folder in directories:
    print(folder.split('/')[1].upper())
    print("*********************************************************")
    onlyfiles = [f for f in os.listdir(folder) if os.path.isfile(os.path.join(folder, f))]
    level_start = time.time()
    for file in onlyfiles:
        print(f"{test}) Executing:", file)
        test += 1
        start_time = time.time()
        state, tar = read_init_state(folder+file)
        astar(state)
        print("Time_taken:", time.time() - start_time)
        print(tar, end='\n\n')
    print("Overall Level Time:", time.time() - level_start, end='\n\n')
    print("*********************************************************")
print("All Tests Completed.\nOverall Time Taken:", time.time() - overall_start)


import sys
sys.stdin = open('input.txt', 'r')
input = sys.stdin.readline
from collections import deque

## 현재 거리에서 모든 노드까지의 거리 구하기
def bfs(s):

    q = deque()
    q.append(s)

    while q:

        s = q.popleft()

        for i in range(len(tree[s])):

            e, w = tree[s][i]

            if not visited[e]:
                visited[e] = visited[s] + w
                q.append(e)

n = int(input())

tree = [[] for _ in range(n+1)]

for _ in range(n - 1):

    s, e, w = map(int, input().split())

    tree[s].append((e, w))
    tree[e].append((s, w))

visited = [0] * (n + 1)

bfs(1)
# 가장 긴 거리
root_max = max(visited)

# 가장 긴 거리의 idx
idx = visited.index(root_max)

visited = [0] * (n + 1)

# 가장 긴 거이의 idx에서 실제 가장 긴 처리 찾기
bfs(idx)

print(max(visited))


from Readers.ReadEureka import *
import sqlite3

from Uploaders.UploadHanna import *
from Uploaders.UploadEureka import *
from Uploaders.UploadHobo import *
from Uploaders.UploadICP import *
from Uploaders.UploadICPNew import *
from Uploaders.UploadIC import *
from Uploaders.UploadScanFP import *
from Uploaders.UploadScanPAR import *
from Uploaders.UploadScanMaster import *
from Uploaders.UploadElementar import *
from Uploaders.UploadSampleId import *
from Uploaders.UploadAqualog import *
from Uploaders.UploadDOCIsotopes import *
from Uploaders.UploadLachat import *
from Uploaders.UploadNo3 import *
from Uploaders.UploadSrp import *
from Uploaders.UploadTss import *
from Uploaders.UploadWater import *
from Uploaders.UploadQ import *
from Uploaders.UploadSites import *
from Uploaders.UploadYSI import *
from Uploaders.UploadICNew import *
from Uploaders.UploadNewSrp import *
from Uploaders.upload_smartrock import *

from Readers.ReadICP import *
from Readers.ReadICPNew import *
from Readers.ReadIC import *
from Readers.ReadScanFP import *
from Readers.ReadScanPAR import *
from Readers.ReadScanMaster import *
from Readers.ReadElementar import *
from Readers.ReadSampleId import *
from Readers.ReadAqualog import *
from Readers.ReadDOCIsotopes import *
from Readers.ReadLachat import *
from Readers.ReadNo3 import *
from Readers.ReadSrp import *
from Readers.ReadTss import *
from Readers.ReadWater import *
from Readers.ReadQ import *
from Readers.ReadSites import *
from Readers.ReadYSI import *
from Readers.ReadICNew import *
from Readers.ReadNewSrp import *
from Readers.read_smartrock import *

class Uploader:
    def __init__(self, database):
        self.hannaReader = None
        self.database = database

    def getProjectId(self):
        return self.database.getProjectId()

    def uploadFile(self, cursor, filePath, fileOrigin, allowDuplicates):
            self.allowDuplicates = allowDuplicates
        # try:
            if fileOrigin == "field_hanna":

                self.hannaReader = ReadHanna(filePath)
                hannaUploader = UploaderHanna(cursor, self, self.hannaReader)

                # upload the data to the database
                hannaUploader.uploadHanna()
                hannaUploader.uploadBatch()
                hannaUploader.uploadLogs()

            if fileOrigin == "field_eureka": # *********************************************************

                self.eurekaReader = ReadEureka(filePath)
                self.eurekaUploader = UploaderEureka(cursor, self, self.eurekaReader)

                self.eurekaUploader.uploadEureka()
                self.eurekaUploader.uploadBatch()
                self.eurekaUploader.uploadLogs()

            if fileOrigin == "field_hobo.csv":
                self.hoboReader = ReadHobo(filePath)
                self.hoboUploader = UploadHobo(cursor, self, self.hoboReader, "absolute_pressure","hobo_pressure_logs_1", "hobo_pressure_batches_1")

                self.hoboUploader.uploadHobo()
                self.hoboUploader.uploadBatch()
                self.hoboUploader.uploadLogs()

            if fileOrigin == "light_hobo":
                self.hoboReader = ReadHobo(filePath)
                self.hoboUploader = UploadHobo(cursor, self, self.hoboReader, "intensity","hobo_light_logs_1", "hobo_light_batches_1")

                self.hoboUploader.uploadHobo()
                self.hoboUploader.uploadBatch()
                self.hoboUploader.uploadLogs()

            if fileOrigin == "dissolved_oxygen_hobo":
                self.hoboReader = ReadHobo(filePath)
                self.hoboUploader = UploadHobo(cursor, self, self.hoboReader, "dissolved_oxygen_mgl","hobo_oxygen_logs_1", "hobo_oxygen_batches_1")

                self.hoboUploader.uploadHobo()
                self.hoboUploader.uploadBatch()
                self.hoboUploader.uploadLogs()

            if fileOrigin == "conductivity_hobo":
                self.hoboReader = ReadHobo(filePath)
                self.hoboUploader = UploadHobo(cursor, self, self.hoboReader, "conductivity","hobo_conductivity_logs_1", "hobo_conductivity_batches_1")

                self.hoboUploader.uploadHobo()
                self.hoboUploader.uploadBatch()
                self.hoboUploader.uploadLogs()

            if fileOrigin == "field_hobo.hobo":
                raise RawHoboFileIngested(filePath)

            if fileOrigin == "icp":
                self.icpReader = ReadICP(filePath)
                self.icpUploader = UploadICP(cursor, self, self.icpReader)

                self.icpUploader.uploadBatch()
                self.icpUploader.uploadReads()

            if fileOrigin == "icp_new":
                self.icpReader = ReadICPNew(filePath)
                self.icpUploader = UploadICPNew(cursor, self, self.icpReader)

                self.icpUploader.uploadBatch()
                self.icpUploader.uploadReads()

            if fileOrigin == "ic":
                self.icReader = ReadIC(filePath)
                self.icUploader = UploadIC(cursor, self, self.icReader)

                self.icUploader.uploadBatch()
                self.icUploader.uploadReads()

            if fileOrigin == "ic_new":
                self.icReader = ReadICNew(filePath)
                self.icUploader = UploadICNew(cursor, self, self.icReader)

                self.icUploader.uploadBatch()
                self.icUploader.uploadReads()

            if fileOrigin == "scan.fp":
                self.scanFPReader = ReadScanFP(filePath)
                self.scanFPUploader = UploadScanFP(cursor, self, self.scanFPReader)

                self.scanFPUploader.uploadBatch()
                self.scanFPUploader.uploadReads()
            if fileOrigin == "scan.par":
                self.scanPARReader = ReadScanPAR(filePath)
                self.scanPARUploader = UploadScanPAR(cursor, self, self.scanPARReader)

                self.scanPARUploader.uploadBatch()
                self.scanPARUploader.uploadReads()

            if fileOrigin == "masterScan":
                self.scanMasterReader = ReadScanMaster(filePath)
                self.scanMasterUploader = UploadScanMaster(cursor, self, self.scanMasterReader)

                self.scanMasterUploader.uploadBatch()
                self.scanMasterUploader.uploadReads()

            if fileOrigin == "elementar":
                self.elementarReader = ReadElementar(filePath)
                self.elementarUploader = UploadElementar(cursor, self, self.elementarReader)

                self.elementarUploader.uploadBatch()
                self.elementarUploader.uploadReads()

            if fileOrigin == "sampleID":
                # FIXME automate filling blank tests
                # self.filePath = filePath
                self.sampleIdReader = ReadSampleId(filePath)
                self.sampleIdUploader = UploadSampleId(cursor, self, self.sampleIdReader)

                self.sampleIdUploader.uploadBatch()
                self.sampleIdUploader.uploadReads()

            if fileOrigin == "aqualog":
                self.aqualogReader = ReadAqualog(filePath)
                self.aqualogUploader = UploadAqualog(cursor, self, self.aqualogReader)

                self.aqualogUploader.uploadBatch()
                self.aqualogUploader.uploadReads()
            if fileOrigin == "docIsotopes":
                self.docReader = ReadDOCIsotopes(filePath)
                self.docUploader = UploadDOCIsotopes(cursor, self, self.docReader)

                self.docUploader.uploadBatch()
                self.docUploader.uploadReads()

            if fileOrigin == "lachat":
                self.lachatReader = ReadLachat(filePath)
                self.lachatUploader = UploadLachat(cursor, self, self.lachatReader)

                self.lachatUploader.uploadBatch()
                self.lachatUploader.uploadReads()

            if fileOrigin == "no3":
                self.no3Reader = ReadNo3(filePath)
                self.no3Uploader = UploadNo3(cursor, self, self.no3Reader)

                self.no3Uploader.uploadBatch()
                self.no3Uploader.uploadReads()

            if fileOrigin == "srp":
                self.srpReader = ReadSrp(filePath)
                self.srpUploader = UploadSrp(cursor, self, self.srpReader)

                self.srpUploader.uploadBatch()
                self.srpUploader.uploadReads()
            if fileOrigin == "tss":
                self.tssReader = ReadTss(filePath)
                self.tssUploader = UploadTss(cursor, self, self.tssReader)

                self.tssUploader.uploadBatch()
                self.tssUploader.uploadReads()
            if fileOrigin == "water":
                self.waterReader = ReadWater(filePath)
                self.waterUploader = UploadWater(cursor, self, self.waterReader)

                self.waterUploader.uploadBatch()
                self.waterUploader.uploadReads()
            if fileOrigin == "q":
                self.qReader = ReadQ(filePath)
                self.qUploader = UploadQ(cursor, self, self.qReader)

                self.qUploader.uploadBatch()
                self.qUploader.uploadReads()
            if fileOrigin == "YSI":
                self.ysiReader = ReadYSI(filePath)
                self.ysiUploader = UploadYSI(cursor, self, self.ysiReader)

                self.ysiUploader.uploadBatch()
                self.ysiUploader.uploadReads()
            if fileOrigin == "sites":
                self.sitesReader = ReadSites(filePath)
                self.sitesUploader = UploadSites(cursor, self, self.sitesReader)

                self.sitesUploader.uploadBatch()
                self.sitesUploader.uploadReads()
            if fileOrigin == "srp_new":
                self.newSrpReader = ReadNewSrp(filePath)
                self.newSrpUploader = UploadNewSrp(cursor, self, self.newSrpReader)

                self.newSrpUploader.uploadBatch()
                self.newSrpUploader.uploadReads()
            if fileOrigin == "smartrock":
                self.smartrock_reader = read_smartrock(filePath)
                self.smartrock_uploader = upload_smartrock(cursor, self, self.smartrock_reader)

                self.smartrock_uploader.uploadBatch()
                self.smartrock_uploader.uploadReads()

        # except sqlite3.OperationalError: # FIXME: PUT THIS BACK
        #     raise DatabaseLocked()
        #
        # except Error as e:
        #     print("ERROR in UPLOADER")
        #     print(type(e))
        #     raise e


# Implementing the review class
import dinner
import skiing
import travel

class Review:
    def __init__(self, aData=None, aReview=""):
        """constructor."""
        self._data = aData  # the data is a Dinner/Skiing/Travel object
        self._comment = aReview  # a string

    def display(self):
        """display the data."""
        if not self._data:
            print("NO DATA.")
            return
        self._data.display()
        print(f"Comment/Review: {self._comment}")

    def enterData(self):
        """prompt the user to enter a new object."""
        aData = None
        command = input(
            "Please indicate the type of the event: d for dinner, s for skking, t for travel").lower()
        if command == 'd':
            aDinner = dinner.Dinner()
            aDinner.inputData()
            aData = aDinner
        elif command == 's':
            aSkiing = skiing.Skiing()
            aSkiing.inputData()
            aData = aSkiing
        elif command == 't':
            aTravel = travel.Travel()
            aTravel.inputData()
            aData = aTravel
        else:
            print("Invalid input.")
            return
        self._comment = input("Please enter the review:")
        self._data = aData

    def updateData(self, aData):
        """update the data member."""
        self._data = aData

    def updateComment(self, aComment):
        """update the comment."""
        self._comment = aComment

    def __lt__(self, aReview):
        """overload the '<' operator."""
        return self._comment < aReview._comment

    def __eq__(self, aReview):
        """overload the '==' operator."""
        return self._comment == aReview._comment


from PIL import ImageDraw, ImageFont

def annotate_img(image, boxes):
    '''Annotate image with rectangles and text.

    Takes the original image and the boxes and draws a rectangle
    around the detected objects. For each rectangle a small text
    is drawn on the top with info about the label and the
    confidence (in percentage).

    Parameters
    ----------
    image: PIL.Image
        The original image.
    boxes: list
        The list with the labels, probability and bounding boxes.

    Returns
    ----------
    image: PIL.Image
        The annotated image.
    '''
    # get image size
    width = image.size[0]
    height = image.size[1]

    # list of labels
    labels = list(set([box[0] for box in boxes]))

    # colors for rectangles
    colors = ['red', 'blue', 'green', 'purple', 'orange', 'yellow', 'brown', 'pink', 'gray']

    # draw
    draw = ImageDraw.Draw(image)

    for i, box in enumerate(boxes):

        # get label and confidence
        label = box[0]
        confidence = box[1]

        # dimensions of box
        xmin, xmax, ymin, ymax = box[2:]

        # limit vertices to image
        xmin = max(xmin, 0)
        xmax = min(xmax, width - 1)
        ymin = max(ymin, 0)
        ymax = min(ymax, height - 1)

        # get color
        color = colors[labels.index(label) % len(colors)]

        # draw rectangle
        draw.rectangle([xmin, ymin, xmax, ymax], outline=color, width=5)

        # draw text
        txt_size = min(15, int(height / 40))
        font = ImageFont.truetype('Pillow/Tests/fonts/DejaVuSans.ttf', txt_size)
        ymin = max(ymin, txt_size)
        text = f'{label}-{confidence*100:.1f}%'
        draw.text((xmin, ymin), text, anchor='lb', font=font, fill=color)

    return image


import sublime
from sublime_plugin import WindowCommand

from ..git_command import GitCommand

class GsShowCommitInfoCommand(WindowCommand, GitCommand):
    def run(self, commit_hash):
        self._commit_hash = commit_hash
        sublime.set_timeout_async(self.run_async)

    def run_async(self):
        show_full = self.savvy_settings.get("show_full_commit_info")
        show_diffstat = self.savvy_settings.get("show_diffstat")
        text = self.git(
            "show",
            "--no-color",
            "--format=fuller",
            "--stat" if show_diffstat else None,
            "--patch" if show_full else None,
            self._commit_hash
        )
        output_view = self.window.create_output_panel("show_commit_info")
        output_view.set_read_only(False)
        output_view.run_command("gs_replace_view_text", {"text": text, "nuke_cursors": True})
        output_view.set_syntax_file("Packages/GitSavvy/syntax/show_commit.sublime-syntax")
        output_view.set_read_only(True)
        self.window.run_command("show_panel", {"panel": "output.show_commit_info"})


import numpy as np
from rover_state import RoverState
from geometry import rad_to_degree
from geometry import degree_to_rad

def predicate_stop(rover: RoverState):

  idx = rover.nav_angles < degree_to_rad(3)
  idx = np.logical_and(idx, rover.nav_angles > degree_to_rad(-3))

  if idx.sum() == 0:
    return True

  radius = rover.nav_dists[idx].max()

  if radius < 3:
    return True
  return False

def predicate_resume(rover: RoverState):

  idx = rover.nav_angles < degree_to_rad(3)
  idx = np.logical_and(idx, rover.nav_angles > degree_to_rad(-3))

  if (idx.sum()) == 0:
    return False

  radius = rover.nav_dists[idx].max()

  if radius > 7:
    return True
  return False

# This is where you can build a decision tree for determining throttle, brake and steer
# commands based on the output of the perception_step() function
def decision_step(rover: RoverState):

    # Implement conditionals to decide what to do given perception data
    # Here you're all set up with some basic functionality but you'll need to
    # improve on this decision tree to do a good job of navigating autonomously!

    # Example:
    # Check if we have vision data to make decisions with

    rover.step += 1
    if rover.nav_angles is not None:
        # Check for Rover.mode status
        if rover.mode == 'forward':
            # Check the extent of navigable terrain
            if not predicate_stop(rover):
                # If mode is forward, navigable terrain looks good
                # and velocity is below max, then throttle
                if rover.vel < rover.max_vel:
                    # Set throttle value to throttle setting
                    rover.throttle = rover.throttle_set
                else: # Else coast
                    rover.throttle = 0
                rover.brake = 0
                # Set steering to average angle clipped to the range +/- 15

                # randomized policy pick to get out of deterministic policy

                if rover.directions is None or len(rover.directions) == 0:
                    direction = np.mean(rover.nav_angles)
                    if rover.step - rover.last_roll > rover.memory_length:
                        rover.direction_pick = None
                else:
                    if rover.direction_pick is None \
                       or len(rover.directions) != rover.last_num_directions:
                        rover.direction_pick = -1 * np.random.randint(0, 2)
                        rover.last_roll = rover.step
                        rover.last_num_directions = len(rover.directions)

                    direction = rover.directions[rover.direction_pick]
                    print('picked direction:', direction, rover.step)

                rover.steer = np.clip(rad_to_degree(direction), -15, 15)

            # If there's a lack of navigable terrain pixels then go to 'stop' mode
            else:
                    # Set mode to "stop" and hit the brakes!
                    rover.throttle = 0
                    # Set brake to stored brake value
                    rover.brake = rover.brake_set
                    rover.steer = 0
                    rover.mode = 'stop'

        # If we're already in "stop" mode then make different decisions
        elif rover.mode == 'stop':
            print('in stop mode')
            # If we're in stop mode but still moving keep braking
            if rover.vel > 0.2:
                rover.throttle = 0
                rover.brake = rover.brake_set
                rover.steer = 0
            # If we're not moving (vel < 0.2) then do something else
            elif rover.vel <= 0.2:

                # Now we're stopped and we have vision data to see if there's a path forward
                if not predicate_resume(rover):
                    rover.throttle = 0
                    # Release the brake to allow turning
                    rover.brake = 0
                    # Turn range is +/- 15 degrees, when stopped the next line will induce 4-wheel turning
                    rover.steer = -15 # Could be more clever here about which way to turn
                # If we're stopped but see sufficient navigable terrain in front then go!
                else:
                    # Set throttle back to stored value
                    rover.throttle = rover.throttle_set
                    # Release the brake
                    rover.brake = 0
                    # Set steer to mean angle
                    direction = np.mean(rover.nav_angles)
                    rover.steer = np.clip(
                        rad_to_degree(direction), -15, 15)
                    rover.mode = 'forward'
    # Just to make the rover do something
    # even if no modifications have been made to the code
    else:
        rover.throttle = rover.throttle_set
        rover.steer = 0
        rover.brake = 0

    # If in a state where want to pickup a rock send pickup command
    if rover.near_sample and rover.vel == 0 and not rover.picking_up:
        rover.send_pickup = True

    return rover


''' 8. Общие идентификаторы
Обнаружилось, что несколько аналитиков продублировали работу друг друга. Теперь нужно понять, какие рейсы обработали несколько раз.
Вам дано несколько наборов идентификаторов рейсов (набор flight_id). Необходимо определить те идентификаторы, которые
присутствуют в каждом наборе.

Формат выходных данных:
На первой строчке записано натуральное число N. На последующих N строчках записаны идентификаторы тех рейсов, которые
обработал очередной аналитик. На одной строчке все идентификаторы записаны через запятую. В самих данных запятых нет.
Каждый идентификатор рейса (flight_id) - это натуральное число.

Формат выходных данных:
Одна строчка. Выведите все общие идентификаторы в порядке возрастания их значения (как числа).
В качестве разделителя используйте запятую.

Пример входных данных:
3
7,3,2
1,2,3,4,5
3,2

Пример выходных данных:
2,3
'''

N = int(input())
list_output = []
for _ in range(N):
    str_input = input().split(',')
    list_input = [int(str_input[i]) for i in range(len(str_input))]
    for i in range(len(list_input)):
        list_output.append(list_input[i])

import collections
id_cnt = collections.Counter(list_output)

key_list = list(id_cnt.keys())  # список ключей
val_list = list(id_cnt.values())  # список значений

id_in_every = []

# определяем индекс искомого значения и по нему находим искомый ключ
for i in range(len(key_list)):
    if val_list[i] == N:
        id_in_every.append(key_list[i])

id_in_every.sort()

print(*id_in_every, sep=',')


# This is a sample Python script.

# Press ⌃R to execute it or replace it with your code.
# Press Double ⇧ to search everywhere for classes, files, tool windows, actions, and settings.

import os
import sys
import json
import csv
import zipfile
from users import Users
from project_tasks import ProjectTasks
from project import Project
from yougile_api import Yougile
from task import Task
from comment import Comment

def parse_users(filename):
    with open(filename) as f:
        json_data = json.load(f)
        users = Users(json_data)
        return users

def parse_project_tasks(inzip_file):
    json_data = json.load(inzip_file)
    tasks = []
    for item in json_data:
        tasks.append(Task(item))
    return tasks

def parse_project_comments(inzip_file):
    json_data = json.load(inzip_file)
    comments = []
    for item in json_data:
        if item["parent_type"] == "Task":
            comments.append(Comment(item))
    return comments

def parse_project_obj(inzip_file):
    json_data = json.load(inzip_file)
    return Project(json_data)

def parse_project(filename):
    assert zipfile.is_zipfile(filename)

    with zipfile.ZipFile(filename, 'r') as file:
        project = None
        tasks = None
        subtasks = None
        comments = None

        for inzip_dir_filename in file.namelist():
            inzip_filename = os.path.split(inzip_dir_filename)[1]
            if inzip_filename == "tasks.json":
                with file.open(inzip_dir_filename, 'r') as inzip_file:
                    tasks = parse_project_tasks(inzip_file)
            elif inzip_filename == "project.json":
                with file.open(inzip_dir_filename, 'r') as inzip_file:
                    project = parse_project_obj(inzip_file)
            elif inzip_filename == "subtasks.json":
                with file.open(inzip_dir_filename, 'r') as inzip_file:
                    subtasks = parse_project_tasks(inzip_file)
            elif inzip_filename == "comments.json":
                with file.open(inzip_dir_filename, 'r') as inzip_file:
                    comments = parse_project_comments(inzip_file)
            else:
                print(inzip_filename)

        tasks_by_id = {}
        if tasks is not None and len(tasks) > 0:
            for task in tasks:
                tasks_by_id[task.json["id"]] = task

        if subtasks is not None and len(subtasks) > 0:
            for subtask in subtasks:
                task_id = subtask.json["task_id"]
                if task_id in tasks_by_id:
                    tasks_by_id[task_id].subtasks.append(subtask)
                    tasks_by_id[subtask.json["id"]] = subtask

        if comments is not None and len(comments) > 0:
            for comment in comments:
                parent_id = comment.json["parent_id"]
                if parent_id in tasks_by_id:
                    tasks_by_id[parent_id].comments.append(comment)

        if project is not None and tasks is not None:
            project.set_tasks(tasks)
        return project

def main():
    assert len(sys.argv) >= 2
    source_directory = sys.argv[1]
    bearer = sys.argv[2]

    sender = Yougile(bearer)

    users_filename = os.path.join(source_directory, "users.json")

    users = parse_users(users_filename)

    existing_users = sender.get_existing_users()
    for existing_user in existing_users:
        user = users.by_email(existing_user)
        if user:
            user.udid = existing_users[existing_user]

    for email in users.emails():
        user = users.by_email(email)
        if user.udid is None:
            result = sender.post("https://yougile.com/api-v2/users", {"email": user.email, "isAdmin": False})
            new_id = result["id"]
            user.udid = new_id

    projects_directory = os.path.join(source_directory, "projects")

    project_files = os.listdir(projects_directory)
    for file in project_files:
        project_file = os.path.join(projects_directory, file)
        project = parse_project(project_file)

        # собрать всех юзеров проекта
        all_user_ids = set()
        for task in project.tasks:
            all_user_ids.add(task.json["assignee_id"])
            all_user_ids.add(task.json["created_by_id"])
            all_user_ids.add(task.json["completed_by_id"])

        all_user_udids = {}
        for id in all_user_ids:
            user = users.by_id(id)
            if user is not None and user.udid is not None:
                all_user_udids[user.udid] = "worker"
            else:
                print("User " + str(id) + ": no user or udid")

        project_data = {"title": project.json["name"], "users": all_user_udids}
        result = sender.post("https://yougile.com/api-v2/projects", project_data)
        project_udid = result["id"]
        project.udid = project_udid

        board_data = {"title": "Доска", "projectId": project.udid}
        result = sender.post("https://yougile.com/api-v2/boards", board_data)
        board_id = result["id"]

        column_data = {"title": "Задачи", "color": 14, "boardId": board_id}
        result = sender.post("https://yougile.com/api-v2/columns", column_data)
        column_id = result["id"]

        for task in project.tasks:
            for subtask in task.subtasks:
                data = subtask.result_data()
                user_id = subtask.json["assignee_id"]
                user = users.by_id(user_id)
                if user is not None and user.udid is not None:
                    user_udid = user.udid
                    if user_udid == 0:
                        print("WAT")
                    data["assigned"] = [user_udid]
                data["columnId"] = column_id

                result = sender.post("https://yougile.com/api-v2/tasks", data)
                subtask.udid = result["id"]

            data = task.result_data()
            if "assignee_id" in task.json:
                user_id = task.json["assignee_id"]
                user = users.by_id(user_id)
                if user is not None and user.udid is not None:
                    user_udid = user.udid
                    if user_udid == 0:
                        print("WAT")
                    data["assigned"] = [user_udid]
                else:
                    print("User " + str(user_id) + ": no user or udid")

            data["columnId"] = column_id

            result = sender.post("https://yougile.com/api-v2/tasks", data)
            task.udid = result["id"]

if __name__ == '__main__':
    main()


from typing import List

class Solution:
    def climbStairs(self, n: int) -> int:
        # 状态转移方程为 dp[i] = dp[i-1] + dp[i-2]
        # 表示当前可选方案数等于前一步的方案加上前两步方案，之后走的一步或两步都是固定的
        # 流下了悔恨的泪水！
        f1, f2 = 1, 1
        for i in range(2, n+1):
            f1, f2 = f1 + f2, f1

        return f1

    def rob(self, nums: List[int]) -> int:
        # 状态转移方程为 dp[i] = max(dp[i-2]+cost[i], dp[i-1])
        # 表示选择方案只能出现在前一步的最大值或者前两步最大与当前的值的和之间
        if not len(nums):
            return 0
        # 在简化参数时稍微迷了点
        f1, f2 = nums[0], 0
        for i in range(1, len(nums)):
            f1, f2 = max(f2+nums[i], f1), f1

        return max(f1, f2)

    def isSubsequence(self, s: str, t: str) -> bool:
        for i in range(len(s)):
            try:
                cur_pos = t.index(s[i])
            # 找不到了必为False
            except ValueError as _:
                return False
            # 截取后半部分进行查找
            t = t[cur_pos+1:]

        return True

    def divisorGame(self, N: int) -> bool:
        # 纯数学思想
        return N % 2 == 0

class NumArray:
    # 状态转移方程为 dp[i] = nums[i-1] + dp[i-1]
    # 现将中间结果进行缓存，使用时再进行提取操作
    def __init__(self, nums: List[int]):
        lens = len(nums)
        self.dp = [0]*(lens + 1)
        self.dp[0] = 0

        for i in range(1, lens+1):
            self.dp[i] = nums[i-1] + self.dp[i-1]

    def sumRange(self, i: int, j: int) -> int:
        # 可以推导出来
        return self.dp[j+1] - self.dp[i]

if __name__ == '__main__':
    show = Solution()

    # 70 爬楼梯
    # print(show.climbStairs(4))

    # 198 打家劫舍
    # print(show.rob([2,7,9,3,1]))

    # 303 区域和检索-数组不可变
    # print(NumArray([-2, 0, 3, -5, 2, -1]).sumRange(2, 5))

    # 392 判断子序列
    # print(show.isSubsequence("acb","ahbgdc"))

    # 1025 除数博弈
    # print(show.divisorGame(100))


# Definition for a binary tree node.
import heapq
import unittest

# Read about enumerate in python
from typing import List

class MaxNumberOfEventsToAttend(unittest.TestCase):

    def maxEvents(self, events: List[List[int]]) -> int:
        events = sorted(events)
        minHeap = []
        lastDay = max(event[1] for event in events)
        eventId = 0
        result = 0

        for currentDay in range(1, lastDay + 1):

            while eventId < len(events) and currentDay >= events[eventId][0]:
                heapq.heappush(minHeap, events[eventId][1])
                eventId += 1

            while minHeap and currentDay > minHeap[0]:
                heapq.heappop(minHeap)

            if minHeap:
                heapq.heappop(minHeap)
                result += 1

        return result

    def test_Leetcode(self):
        self.assertEqual(3, self.maxEvents([[1, 2], [2, 3], [3, 4]]))
        self.assertEqual(4, self.maxEvents([[1, 2], [2, 3], [3, 4], [1, 2]]))
        self.assertEqual(4, self.maxEvents([[1, 4], [4, 4], [2, 2], [3, 4], [1, 1]]))
        self.assertEqual(1, self.maxEvents([[1, 100000]]))
        self.assertEqual(7, self.maxEvents([[1,1], [1,2], [1,3], [1,4], [1,5], [1,6], [1,7]]))

    def test_Leetcode(self):
        self.assertEqual(5, self.maxEvents([[1,2], [1,2], [3,3], [1,5], [1,5]]))

if __name__ == '__main__':
    unittest.main()


from model_layer.contract import Contract
import csv

class ContractData():
    def list_all_contracts(self):
        ''' Opens up the file contracts.csv as file_stream and returns a list of contracts and their info.'''
        contract_list = []
        with open("data_layer/data_files/contracts.csv",encoding="utf-8") as file_stream:
            dest_reader = csv.DictReader(file_stream)
            for row in dest_reader:
                info = Contract(row["contract_id"], row["customer_ssn"], row["employee_ssn"], row["vehicle_id"], row["loan_date"], row["end_date"], row["base_price"],row['contract_created'],row['pickup_date'],row["return_date"], row["extensions"],row['total'], row["status"])
                contract_list.append(info)
        return contract_list

    def new_contract(self, contr):
        ''' Takes in instance of contract class and puts the information to contracts.csv file'''
        contr_list = [contr.contract_id,contr.customer_ssn,contr.employee_ssn,contr.vehicle_id,contr.loan_date,contr.end_date,contr.base_price,contr.contract_created,contr.pickup_date,contr.return_date,contr.extensions,contr.total,contr.status]
        with open("data_layer/data_files/contracts.csv",'a+' , encoding="utf-8",newline="") as file_stream:
            writer = csv.writer(file_stream)
            writer.writerow(contr_list)

    def change_contract_attributes(self, attribute_list):
        ''' overwrite certain attributes in database '''
        values = attribute_list[1].split(",")
        file_list = []
        with open("data_layer/data_files/contracts.csv","r",encoding="utf-8") as file_stream:
            reader = csv.DictReader(file_stream)
            contract_id = attribute_list[0]
            for row in reader:
                if row["contract_id"] == contract_id:
                    for key, value in zip(row, values):
                        row[key] = value
                file_list.append(row)

        with open("data_layer/data_files/contracts.csv", "w", encoding="utf-8", newline="") as file_stream:
            keys = file_list[0].keys()
            the_writer = csv.DictWriter(file_stream, keys)
            the_writer.writeheader()
            the_writer.writerows(file_list)

    def terminate_contract(self, contract_id):
        ''' Terminates contract by removing the contract from db '''
        file_list = []
        with open("data_layer/data_files/contracts.csv", 'r', encoding='utf-8') as file_stream:
            csv_reader = csv.DictReader(file_stream)
            for row in csv_reader:
                if row["contract_id"] != contract_id:
                    file_list.append(row)
        with open("data_layer/data_files/contracts.csv", "w", encoding="utf-8", newline="") as file_stream:
            keys = file_list[0].keys()
            the_writer = csv.DictWriter(file_stream, keys)
            the_writer.writeheader()
            the_writer.writerows(file_list)

    def change_contract(self,cont):
        ''' overwrites the contracts with "new" contract '''
        cont_list = [cont.contract_id, cont.customer_ssn, cont.employee_ssn, cont.vehicle_id, cont.loan_date, cont.end_date,
        cont.base_price, cont.contract_created, cont.pickup_date, cont.return_date, cont.extensions, cont.total, cont.status]
        file_list = []
        with open("data_layer/data_files/contracts.csv", 'r', encoding='utf-8') as file_stream:
            csv_reader = csv.DictReader(file_stream)
            for row in csv_reader:
                if row["contract_id"] == cont.contract_id:
                    for key, value in zip(row.keys(), cont_list):
                        row[key] = value
                file_list.append(row)

        with open("data_layer/data_files/contracts.csv", 'w', encoding='utf-8', newline='') as file_stream:
            keys = file_list[0].keys()
            the_writer = csv.DictWriter(file_stream, keys)
            the_writer.writeheader()
            the_writer.writerows(file_list)


import re
import numpy as np
import pandas as pd
from typing import Tuple, List, Optional
import chardet
from unicodedata import normalize

def get_line_context(lines: pd.DataFrame, n: int = 1) -> pd.DataFrame:
        lines = lines.copy()
        lines.sort_values(by=['year', 'file', 'line'], inplace=True)
        lines.reset_index(inplace=True, drop=True)
        contexts = []
        for nm, gp in lines.groupby(['year', 'file']):
            for i, (_, line) in enumerate(gp.iterrows()):
                prev_text = '\n'.join(gp.iloc[i-n:i,]['text'].values)
                next_text = '\n'.join(gp.iloc[i+1:i+1+n,]['text'].values)
                # line['prev_context'] = prev_line_text
                # line['next_context'] = next_line_text
                contexts.append(nm + (line['line'], prev_text, next_text))
        contexts = pd.DataFrame(contexts, columns=['year', 'file', 'line', 'prev_context', 'next_context'])
        return contexts

def normalize_text(text):
    if isinstance(text, bytes):
        encoding = chardet.detect(text)['encoding']
        text = text.decode(encoding)
    # convert to ascii.
    text = normalize('NFKD', text).encode('ASCII', 'ignore').decode('ASCII')
    return text

def span2bio(s: str, start: int, end: int) -> str:
    """constructs a BIO label sequence from string s.

    Example::

        >>> span2bio("example 1", start=0, end=7)
        'BIIIIIIOO'
    """
    targets = ['O'] * len(s)
    if pd.notnull(start) and pd.notnull(end):
        targets[int(start)] = 'B'
        for i in range(int(start) + 1, int(end)):
            targets[i] = 'I'
    targets = ''.join(targets)
    assert len(targets) == len(s)
    return targets

def bio2span(s: str) -> Tuple[Optional[int], Optional[int]]:
    """constructs a span from a BIO label sequence.

    Example::

        >>> bio2span('BIIIIIIOO')
        (0, 7)
    """
    span = (None, None)
    result = re.search(r'[BI]+', s)
    if result:
        span = result.span()
    return span

def split_lines(lines: pd.DataFrame) -> pd.DataFrame:
    """randomly splits lines.

    Used for constructing more training data.
    """
    lines.sort_values(by=['year', 'file', 'line'], inplace=True)
    lines_split = []
    for nm, gp in lines.groupby(['year', 'file']):
        j = 0
        for _, row in gp.iterrows():
            text = row['text']
            bio = row['bio']
            split = np.random.choice([False, True])
            if split and len(text) > 1:
                split_idx = np.random.randint(low=1, high=len(text))
                new_line0 = {'text': text[:split_idx], 'bio': bio[:split_idx], 'line': j, 'year': nm[0], 'file': nm[1]}
                j += 1
                new_line1 = {'text': text[split_idx:], 'bio': bio[split_idx:], 'line': j, 'year': nm[0], 'file': nm[1]}
                j += 1
                lines_split.append(new_line0)
                lines_split.append(new_line1)
            else:
                new_line0 = {'text': text, 'bio': bio, 'line': j, 'year': nm[0], 'file': nm[1]}
                lines_split.append(new_line0)
                j += 1
    lines_split = pd.DataFrame(lines_split)
    lines_split['line'] += 1
    return lines_split


import allure
import logging
import pytest

from apis import UserAPI
from tests import TestBase
from utils import HttpConnection
from tools import meta, MetaData

logger = logging.getLogger(__name__)
suite_name = 'TestUserSuite'

class TestUser(TestBase):

    @classmethod
    def setup_class(cls):
        # cls._http = HttpConnection(access_token=auth.get_login_token())
        cls._http = HttpConnection(
            access_token=cls._cfg.env_config.access_token)
        cls._user_api = UserAPI(cls._http)
        cls._email = cls._cfg.env_config.email

    @classmethod
    def teardown_class(cls):
        cls._http.close()

    @allure.suite(suite_name)
    @allure.severity(allure.severity_level.NORMAL)
    @pytest.mark.smoke
    @meta(MetaData('zhengjin', '2020-12-5', ['smoke', 'user/list_users']))
    def test_user_list_all(self):
        data_dict = {'pageSize': 10, 'page': 1}
        resp_json = self._user_api.user_list(data_dict)
        self.assert_status_code_ok(resp_json)

        total = resp_json['data']['total']
        logger.debug(f"total users retrieved: {total}")
        assert total >= 0

        if total > 0:
            assert len(resp_json['data']['items']) > 0

    @allure.suite(suite_name)
    @allure.severity(allure.severity_level.NORMAL)
    @pytest.mark.smoke
    @meta(MetaData('zhengjin', '2020-12-5', ['smoke', 'user/list_user']))
    def test_user_list_by_email(self):
        data_dict = {'pageSize': 10, 'page': 1, 'email': self._email}
        resp_json = self._user_api.user_list(data_dict)
        self.assert_status_code_ok(resp_json)

        total = resp_json['data']['total']
        assert total == 1
        assert len(resp_json['data']['items']) == 1
        assert resp_json['data']['items'][0]['email'] == self._email

    @allure.suite(suite_name)
    @allure.severity(allure.severity_level.NORMAL)
    @pytest.mark.smoke
    @meta(MetaData('zhengjin', '2020-12-5', ['smoke', 'user/download_user']))
    def test_user_download_by_email(self):
        data_dict = {'pageSize': 10, 'page': 1, 'email': self._email}
        resp_content = self._user_api.user_download(data_dict)
        assert len(resp_content) > 0
        assert self._email in resp_content

    @allure.suite(suite_name)
    @allure.severity(allure.severity_level.NORMAL)
    @pytest.mark.smoke
    @meta(MetaData('zhengjin', '2020-12-5', ['smoke', 'user/unfrozen_user']))
    def test_user_unfrozen(self):
        user_id = self._user_api.get_user_id_by_email(self._email)
        data_dict = {'isFrozen': False, 'userIds': [user_id]}
        resp_json = self._user_api.user_frozen(data_dict)
        self.assert_status_code_ok(resp_json)
        assert len(resp_json['data']) == 1
        assert resp_json['data'][0]['id'] == user_id


from airflow import DAG
from airflow.operators.bash import BashOperator
from datetime import datetime, timedelta

# creating default arg

defdag={"start_date":datetime(2023,9,26),
        "email_on_failure":False,
        "email_on_retry":False,
        "retries":1,
        "retry_delay":timedelta(minutes=5),
        "project_id":1}

with DAG("dag1",schedule_interval=None, default_args=defdag) as dag:
    task0=BashOperator(task_id="bash_task", bash_command="echo 'hello word'")
    task1=BashOperator(task_id="copying_txt", bash_command="cp /opt/airflow/data/DATA_LAKE/dataset_row.txt /opt/airflow/data/DATA_CENTER")
    task2=BashOperator(task_id="removing_txt", bash_command="rm /opt/airflow/data/DATA_LAKE/dataset_row.txt")

        #creating dependencies
    task0>>task1>>task2


import requests as r, bs4, urllib.parse as u, telebot
from time import sleep

def HTMLParser(url):
    # print(url)
    url = r.get(url)
    UrlHTML = bs4.BeautifulSoup(url.text, 'lxml')
    videoSource = UrlHTML.findAll('a', href=True)
    videoTag = [i for i in videoSource if 'mp4' in str(i)][0]
    videoTag = str(videoTag).split(';')[0]
    videoUrl = videoTag.split('src=')[1]
    return u.unquote(str(videoUrl))

def VideoUrl(url):
    try:
        if 'www' in url:
            url = url.replace('www', 'm')
            # print(url)
        elif '//f' in url:
            url = url.replace('//f', '//m.f')
            # print(url)
        elif 'm.' in url:
            pass
        else:
            return 'Your link doesn\'t work'
        return HTMLParser(url)
    except:
        return 'An error has occured, please contact the bot creator.'

if __name__ == "__main__":

    bot_token = '<BOT_TOKEN>'
    bot = telebot.TeleBot(token=bot_token)

    @bot.message_handler(commands=['start'])
    def send_welcome(message):
        bot.reply_to(message, 'TEST MESSAGE')

    @bot.message_handler(func=lambda msg: msg.text is not None and '@BotName' in msg.text)
    def at_answer(message):
        fburl = message.text.split()[1]
        if 'http' not in fburl:
            fburl ='http://'+fburl
        bot.reply_to(message, VideoUrl(fburl)) #comment this line to send the video instead of link.
        #If you want to send the just the video without link use this:
        #bot.send_video(message.chat.id, VideoUrl(fburl), supports_streaming=True, reply_to_message_id=message.message_id)

    while True:
        try:
            bot.polling()
        except Exception:
            sleep(15)


import sys
from time import sleep

from colosseum import Colosseum
from constants import COLOSSEUM, LOGDIR, QUEUEDIR, PNG, IMG, PICK, FILES, PROBFILE
from io_sama import InputKun, OutputChan

# TODO v3 ideas:
# Kill by popular demand (events that wait for user interaction. needs from IO_Sama)
# Log and queue as pickle class instead of folders
# Rewrite access to the print name of Arpies
# Love affairs (possibility of magnetismn between player (makes them more likely to kill eachother))
# Support for mentions
# Defense teamups
# EasterEggs for certain combinations
### Neutral Manu
### Jeaggerbrothers
### Mon Amour
### Megazord

# random.seed(datetime.datetime.now().second)
# colosseum = Colosseum()
# i = 1
# while not colosseum.is_over():
#     print("Ronda " + str(i) + ": " + colosseum.let_the_games_begin())
#     i += 1

# def sensoo_wa_kawatta():
#     colosseum=None
#     try:
#         InputKun.load_pickle(COLOSSEUM)
#     except:
#         return

def stateful_call(tweet_for_real=True):
    colosseum = load_colosseum()

    ruta_img = IMG + PNG
    if not colosseum.is_over():
        tweet = colosseum.let_the_games_begin()
        colosseum.generateStatusImage(ruta_img)
        OutputChan.log_tweet(LOGDIR, tweet, ruta_img, colosseum)
        OutputChan.queue_tweet(QUEUEDIR, tweet, ruta_img, colosseum)
        OutputChan.process_queue(QUEUEDIR, tweet_for_real)
        OutputChan.save_pickle(FILES + COLOSSEUM + PICK, colosseum)

        # TODO Make this func so it sends all tweets in the queue directory (if successfully sent, deletes crom queue)
        if colosseum.is_over():
            # TODO Congratulations message (method in colosseum)
            tweet = colosseum.omedetoo()
            OutputChan.tweet_text(tweet, tweet_for_real)
            # colosseum.congratulations()
    else:
        print("Owarida")

def stateful_dequeue():
    colosseum = InputKun.load_pickle(COLOSSEUM)
    if colosseum is None:
        raise Exception("Wrong pickle")
    OutputChan.process_queue(QUEUEDIR)
    # TODO Make this func so it sends all tweets in the queue directory (if successfully sent, deletes crom queue)

def test_tweet_api():
    OutputChan.tweet_text(
        "Buenas noches a todos. En caso de emergencia, recuerden: Todas las salidas han sido selladas. Seguiremos informando [BIP BOOP]",
        True)

def test_tweet_api_img():
    OutputChan.tweet_image("Getting ready for you <3", "files/terminator.jpg", True)

def reload_files():
    colosseum = load_colosseum()
    colosseum.refresh_flavours()
    OutputChan.save_pickle(FILES + COLOSSEUM + PICK, colosseum)

def presentation(live=False):
    colosseum = load_colosseum()

    presentations = colosseum.get_presentations()

    OutputChan.tweet_text(
        "Hoy empieza la batalla por la supervivencia. Ya sabéis como funciona. Cada día a las 12:00 me encargaré de "
        "actualizaros. Pero antes de empezar, demos la bienvenida a los participantes!!", live)

    for present in presentations:
        OutputChan.tweet_text(present, live)
        sleep(1)

def load_colosseum():
    colosseum = InputKun.load_pickle(FILES + COLOSSEUM + PICK)
    if colosseum is None:
        colosseum = Colosseum()

    return colosseum

def update_probabilities():
    colosseum = load_colosseum()
    new_probabilities = InputKun.read_file(PROBFILE)
    for line in new_probabilities:
        tokens = line.split('=')
        colosseum.update_event_probability(tokens[0].strip(), float(tokens[1].strip()))

    OutputChan.save_pickle(FILES + COLOSSEUM + PICK, colosseum)

def print_status():
    colosseum=load_colosseum()
    colosseum.show_me_them_stats()

if __name__ == "__main__":
    print(sys.argv[1])

    mode = sys.argv[1]
    if mode == "test_tweet":
        test_tweet_api()
    elif mode == "test_image":
        test_tweet_api_img()
    elif mode == "test_intro":
        presentation()
    elif mode == "test_state":
        stateful_call(False)
    elif mode == "run_state":
        stateful_call(True)
    elif mode == "run_intro":
        presentation(True)
    elif mode == "reload_files":
        reload_files()
    elif mode == "update_probs":
        update_probabilities()
    elif mode== "print_status":
        print_status()
    else:
        print("I did nuthing")


from math import log, ceil

class Solution(object):
    def smallestGoodBase(self, n):

        number = int(n)

        power_ceil = 60 #ceil(log(number, 2))
        power_floor = power_ceil - 1

        # if number == ((2**power_ceil ) -1):
        #     return(str(2))
        base = 2
        while base <= number:

            while number <= (base ** power_floor):
                power_ceil = power_floor
                power_floor = power_floor - 1

            dig_sum = ((base**power_ceil ) -1) // (base-1)
            print(power_ceil, base, dig_sum)
            if dig_sum == number:
                return(str(base))

            base+=1

solobj = Solution().smallestGoodBase(470988884881403701)  #14919921443713777 #2251799813685247 #4681
print(solobj)


number=int(input("Enter the number of classes that are to be attended"))
tasks=[]
for i in range(0,number):
    subject=input("Specify the subjects")
    time=int(input("Specify the timings"))
    task=[subject,time]
    tasks.append(task)

ask=int(input("What is the time?"))
for i in range(0,number):
    if(tasks[i][1]==ask):
        print("your class for ",tasks[i][0],"has started")
        break
    elif(tasks[i][1]>ask):
        dif=tasks[i][1]-ask
        print("Your class for ",tasks[i][0],"starts in ",dif)

    elif(tasks[i][1]<ask):
        dif=ask-tasks[i][1]
        print("Your class for ",tasks[i][0],"started ",dif,"ago")


#!/usr/bin/env python
# -*- coding:utf-8 -*-
import codecs
from urllib import request
import urllib
import re
import time
import random
import socket
import threading

import settings

# 抓取代理IP

ip_totle = []
for page in range(2, 20):
    url='http://www.xicidaili.com/nn/'+str(page) #西刺代理
    headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64)"}
    request = urllib.request.Request(url=url, headers=headers)
    response = urllib.request.urlopen(request)
    content = response.read().decode('utf-8')
    print('get page', page)
    pattern = re.compile('(\d.*?)	')  # 截取与	之间第一个数为数字的内容
    ip_page = re.findall(pattern, str(content))
    ip_totle.extend(ip_page)
    time.sleep(random.choice(range(15, 20)))
# # 打印抓取内容
# print('代理IP地址     ', '\t', '端口', '\t', '速度', '\t', '验证时间')
# for i in range(0, len(ip_totle), 4):
#     print(ip_totle[i], '    ', '\t', ip_totle[i + 1], '\t', ip_totle[i + 2], '\t', ip_totle[i + 3])
# 整理代理IP格式
proxys = []
for i in range(0, len(ip_totle), 4):
    proxy_host = ip_totle[i] + ':' + ip_totle[i + 1]
    proxys.append(proxy_host)

proxy_ip = codecs.open('proxy_ip.txt', 'w', settings.FILE_ENCODE)  # 新建一个储存有效IP的文档
lock = threading.Lock()  # 建立一个锁

# 验证代理IP有效性的方法
def test(i):
    socket.setdefaulttimeout(5)  # 设置全局超时时间
    url = "http://stock.gtimg.cn/data/index.php?appn=detail&action=download&c=sh600030&d=20170808"  # 打算爬取的网址
    try:
        proxy_support = urllib.request.ProxyHandler({settings.PROXY_TYPE: proxys[i]})
        opener = urllib.request.build_opener(proxy_support)
        opener.addheaders = [("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64)")]
        urllib.request.install_opener(opener)
        urllib.request.urlopen(url).read()
        lock.acquire()  # 获得锁
        print(proxys[i], 'is OK')
        proxy_ip.write('%s\n' % str(proxys[i]))  # 写入该代理IP
        lock.release()  # 释放锁
    except Exception as e:
        lock.acquire()
        print(proxys[i], e)
        lock.release()

# 单线程验证
# for i in range(len(proxys)):
#     test(i)
# 多线程验证
threads = []
for i in range(len(proxys)):
    thread = threading.Thread(target=test, args=(i,))
    threads.append(thread)
    thread.start()# 阻塞主进程，等待所有子线程结束
for thread in threads:
    thread.join()

proxy_ip.close()  # 关闭文件