from utils import kernel_rbf
from layer import Layer_rbf
# import tensorflow as tf
import tensorflow.compat.v1 as tf
tf.disable_v2_behavior()
import numpy as np
from dsdgp import DSDGP

class LOWDGP():
#     def __init__(self, x_tr, y_tr, layers, num_samples=20):
#         self.x_tr, self.y_tr, self.layers = x_tr.astype(np.float32), y_tr.astype(np.float32), layers
#         self.f_tr = np.concatenate((np.ones((self.x_tr.shape[0], 1)), self.x_tr), axis=1).astype(np.float32)
#         self.num_samples = num_samples
#         self.input_dim, self.output_dim = x_tr.shape[1], y_tr.shape[1]
#         self.num_data = x_tr.shape[0]
#         self.prior_m_beta = np.zeros((self.input_dim + 1, 1), dtype=np.float32)
#         self.prior_s_beta = np.ones((self.input_dim + 1), dtype=np.float32)
#         self.m_beta = tf.Variable(np.zeros([self.input_dim + 1, 1]), dtype=tf.float32)
#         self.s_beta = tf.exp(tf.Variable(np.zeros([self.input_dim + 1, ]), dtype=tf.float32))
#         self.variance = tf.exp(tf.Variable(tf.log(1e-4), dtype=tf.float32))

#         self.dsdgp = DSDGP(X=self.x_tr, Y=None, layers=self.layers, Z=None, num_samples=self.num_samples)
#         self.dsdgp.initialize_param()

    def __init__(self, num_data, input_dim, output_dim, layers, num_samples=20):
        self.num_data, self.num_samples = num_data, num_samples
        self.input_dim, self.output_dim = input_dim, output_dim
        self.prior_m_beta = np.zeros((self.input_dim + 1, 1), dtype=np.float32)
        self.prior_s_beta = np.ones((self.input_dim + 1), dtype=np.float32)
        self.m_beta = tf.Variable(np.zeros([self.input_dim + 1, 1]), dtype=tf.float32)
        self.s_beta = tf.exp(tf.Variable(np.zeros([self.input_dim + 1,]), dtype=tf.float32))
        self.variance = tf.exp(tf.Variable(tf.log(1e-4), dtype=tf.float32))

        self.dsdgp = DSDGP(num_data=num_data, input_dim=input_dim, output_dim=output_dim, \
                           layers=layers, num_samples=num_samples)
        self.dsdgp.initialize_param()

#     def _build_likelihood(self):
#         KL_gamma = tf.reduce_sum([layer.KL() for layer in self.dsdgp.layers])
#         KL_beta = self._build_beta_kl()
#         _, gamma_mean, gamma_var = self.dsdgp._build_predict(self.x_tr, full_cov=False, S=self.num_samples)
#         inner_exp = self.y_tr - tf.matmul(self.f_tr, self.m_beta) - gamma_mean
#         E_log_p_Y = -0.5 * self.num_data * tf.log(2 * np.pi * self.variance)
#         E_log_p_Y -= 0.5 / self.variance * tf.matmul(inner_exp, inner_exp, transpose_a=True)
#         lik = tf.reduce_mean(E_log_p_Y, axis=0)
#         lik -= 0.5 / self.variance * (tf.reduce_sum(tf.reduce_mean(gamma_var, axis=0)) + \
#                                       tf.trace(tf.matmul(tf.matmul(self.f_tr, tf.matrix_diag(self.s_beta)), \
#                                                          self.f_tr, transpose_b=True)))
#         lik -= KL_gamma + KL_beta
#         return tf.reduce_sum(lik)

    def _build_likelihood(self, X, Y):

        # PRIOR
        F = tf.cast(tf.concat((tf.ones((self.num_data, 1)), X), axis=1), dtype=tf.float32)
        KL_gamma = tf.reduce_sum([layer.KL() for layer in self.dsdgp.layers])
        KL_beta = self._build_beta_kl()

        # LOG-LIKELIHOOD
        _, gamma_mean, gamma_var = self.dsdgp._build_predict(X, full_cov=False, S=self.num_samples)
        inner_exp = Y - tf.matmul(F, self.m_beta) - gamma_mean
        E_log_p_Y = -0.5 * self.num_data * tf.log(2 * np.pi * self.variance)
        E_log_p_Y -= 0.5 / self.variance * tf.matmul(inner_exp, inner_exp, transpose_a=True)
        lik = tf.reduce_mean(E_log_p_Y, axis=0)

        # ELBO = LOG-LIKELIHOOD + PRIOR
        elbo = lik
        elbo -= 0.5 / self.variance * (tf.reduce_sum(tf.reduce_mean(gamma_var, axis=0)) + \
                                      tf.trace(tf.matmul(tf.matmul(F, tf.matrix_diag(self.s_beta)), \
                                                         F, transpose_b=True)))
        elbo -= KL_gamma + KL_beta
        return tf.reduce_sum(elbo), tf.reduce_sum(lik)

    def _build_beta_kl(self):
        kl = 0.5 * tf.reduce_sum(self.s_beta)
        kl += 0.5 * tf.matmul(self.m_beta, self.m_beta, transpose_a=True)
        kl -= 0.5 * self.input_dim
        kl -= 0.5 * tf.log(tf.reduce_prod(self.s_beta))
        return tf.reduce_sum(kl)

    def _build_predict(self, xnew, num_samples):
        xnew = xnew.astype(np.float32)
        tilde_xnew = np.concatenate((np.ones((xnew.shape[0], 1)), xnew), axis=1).astype(np.float32)
        fmean = self.dsdgp.predict_y(xnew, num_samples)

        S, D = tf.cast(fmean.shape[0], tf.int32), tf.cast(self.m_beta.shape[0], tf.int32)
        z = tf.random_normal([S, D, 1], dtype=tf.float32)
        beta = self.m_beta + z * tf.expand_dims(self.s_beta, -1) ** 0.5
        tilde_xnew = tf.tile(tf.expand_dims(tilde_xnew, 0), [S, 1, 1])
        noise = tf.sqrt(self.variance) * tf.random_normal(fmean.shape, dtype=tf.float32)

        return fmean + tf.matmul(tilde_xnew, beta) + noise


# Problems Completed [ ]

# Your test/solution code here
def intersect(list1, list2):
    inter = []
    for ele1 in list1:
        for ele2 in list2:
            if ele1 == ele2:
                inter.append(ele1)
    return inter
print(intersect(['a', 'b', 'c'], ['x', 'y', 'z']))

# Problem 0
# Write a function `min_max_product(list)` that return the product between the
# Use min() and max() to find the largest and smallest number of the list.
# largest value and the smallest value in the list.
# sum() both the product of min() and max().
# def min_max_product(list):
# Problem 1
# def find_highest_priced():
# use max() to find highest
# key=priced.get returns highest value
# Problem 2
def bracket_matcher(input):
  stack = []

  open_brackets = ('(', '{', '[')
  close_brackets = (')', '}', ']')

  bracket_pairs = {
    '[' : ']',
    '{' : '}',
    '(' : ')'
  }
  # loop over all the characters in the input string
  for char in input:
  # ignore anything that isn't a bracket
    if char in open_brackets:
  # encounter open bracket: keep track of it in your stack
      stack.append(char)
    elif char in close_brackets:
  # encounter closing bracket: pop() off the stack and compare
      open_pair = stack.pop()

      if len(stack) == 0:
        return False
  return True if len(stack) == 0 else False

# Problem 3
# def count_the_bits():


# def temp_conv(c):
#     return 9/5 * c + 32
#
# def km_m(km):
#     return km * 1000
#
# def m_km(m):
#     return m / 1000

# f = temp_conv(34.4)
# print(f)
temp = [34.4,23.5,28.7,30.6,29.6,22.11]
# f = []
# for t in temp:
#     f.append(round(temp_conv(t),2))
#
# print(f)
#
kms = [300,230,221,4.5,56.7,55]
# ms = []
# for k in kms:
#     ms.append(km_m(k))
#
# print(ms)

def myMap(func, iter):
    data = []
    for i in range(len(iter)):
        data.append(func(iter[i]))
    return data

f = myMap(lambda c : 9/5 * c + 32, temp)
print(f)
ms = myMap(lambda km : km * 1000, kms)
print(ms)

# f = list(map(temp_conv, temp))
# print(f)
# ms = list(map(km_m, kms))
# print(ms)

f = list(map(lambda c : 9/5 * c + 32, temp))
print(f)

ms = list(map(lambda km : km * 1000, kms))
print(ms)


def parseInput():
    with open("input", 'r') as input_file:
        return [int(char) for char in input_file.readlines()[0]]

def createLayers(data):
    layers = []
    for i in range(0, len(data), 25*6):
        layers.append(data[i:i+25*6])
    return layers

def findLayerWithLeastZeroes(layers):
    least_zeroes = 1000000
    best_layer = None
    for i in range(0, len(layers)):
        count = layers[i].count(0)
        if count < least_zeroes:
            least_zeroes = count
            best_layer = i
    return best_layer

def getFinalImage(layers):
    image = ''
    for i in range(0, 25*6):
        for j in range(0, len(layers)):
            if layers[j][i] == 2:
                if j == len(layers)-1:
                    image += str(layers[j][i])
                    break
                continue
            image += str(layers[j][i])
            break
    return image

def getSolution1Value(best_layer):
    one_count = best_layer.count(1)
    two_count = best_layer.count(2)
    return one_count * two_count

def printFinalImage(final_image):
    for i in range(0, 25*6, 25):
        row = ''
        for pixel in final_image[i:i+25]:
            if pixel == '1':
                row += ':'
            else:
                row += ' '
        print(row)

def solution():
    data = parseInput()
    layers = createLayers(data)
    best_layer = findLayerWithLeastZeroes(layers)
    final_image = getFinalImage(layers)
    print(1, getSolution1Value(layers[best_layer]))
    print(2)
    printFinalImage(final_image)

if __name__ == "__main__":
    solution()


#code to automate the acquisition of "just the two of us" images from youtube and crop them

import math
import os
from time import perf_counter

import cv2
import googleapiclient.discovery  # google's youtube API
import numpy as np
from vidgear.gears import CamGear

from api_key import key  # requires a api_key.py file containing the variable 'key' with a google api key as the value

cache_file = "video_list_cache.txt" # file where retrieved playlist content will be stored

youtube = googleapiclient.discovery.build("youtube", "v3", developerKey = key)

def create_dir(path): # create directory with given name (relative to current file)
    try:
        if not os.path.exists(path):
            os.makedirs(path)
    except OSError:
        print(f"ERROR: creating directory with name {path}")

# removes black border that exists around most images for some reason
def trim_border(image): # solution by https://stackoverflow.com/a/30540322/
    threshold = 4 # 0 = pure black
    if len(image.shape) == 3:
        flatImage = np.max(image, 2)
    else:
        flatImage = image
    assert len(flatImage.shape) == 2

    rows = np.where(np.max(flatImage, 0) > threshold)[0]
    if rows.size:
        cols = np.where(np.max(flatImage, 1) > threshold)[0]
        image = image[cols[0]: cols[-1] + 1, rows[0]: rows[-1] + 1]
    else:
        image = image[:1, :1]

    return image

def save_frame(stream, save_dir, name): #get frame from video and save to specified directory
    create_dir(save_dir) # check if directory exits, else creates one

    metadata = stream.ytv_metadata
    total_frames = metadata['fps'] * metadata['duration']
    target_frame = math.ceil(total_frames/5) # the frame of the video that will be captured (5% through the video)

    frame_pos = 0 # currently iterated frame
    while frame_pos < target_frame: # go to specified frame
        frame = stream.read()

        if (frame is None):
            break

        frame_pos+=1

    frame = trim_border(frame) # remove black border
    cv2.imwrite(f"{save_dir}\\{name}.png", frame) # save frame to image file

    stream.stop() # release stream
    print("Completed Capturing A Frame Of " + str(name))

if __name__ == "__main__": # you know the drill

    # Code to get list of videos in playlist
    print("Aquiring Playlist...")

    tik = perf_counter()
    playlist_id = "PL-vSysBoeI98daMpbj5V5vtRf-qxI0qAJ" # https://www.youtube.com/playlist?list=PL-vSysBoeI98daMpbj5V5vtRf-qxI0qAJ

    if (not os.path.isfile(cache_file)): # check if cache file exists
        print("Requesting Playlist from Youtube...")
        request = youtube.playlistItems().list( # request playlist from youtube
            part = "snippet",
            playlistId = playlist_id,
            maxResults = 50
        )
        response = request.execute()

        playlist_items = []
        while request is not None: # put response in list
            response = request.execute()
            playlist_items += response["items"]
            request = youtube.playlistItems().list_next(request, response)

        video_list = [f'https://www.youtube.com/watch?v={t["snippet"]["resourceId"]["videoId"]}' for t in playlist_items] # construct list of video urls

        with open(cache_file, "w") as f: # save urls to file
            for vid_url in video_list:
                f.write(vid_url+"\n")
    else:
        # get links from file
        print("Getting Playlist from Cache...")
        video_list = []
        with open(cache_file) as f:
            video_list = [line.rstrip("\n") for line in f]

    tok = perf_counter()

    print(f"Got playlist in {tok - tik:0.4} seconds")
    print(f"total: {len(video_list)}")

    vid_count = 1

    skip_to_vid = 0 # used for debugging (0 or less to disable)

    options = {"STREAM_RESOLUTION": "720p"}
    for vid in video_list:
        try:
            if (skip_to_vid <= 0 or vid_count >= skip_to_vid): # check for debug flag and act on it
                print(f"Starting on {vid_count}")
                stream = CamGear(source=vid, # get yt video
                                stream_mode=True,
                                logging=False,
                                time_delay=0.5,
                                **options).start()

                print("Completed Downloading of Video")

                print(vid)

                save_frame(stream, "saves", vid_count)
        except ValueError as e:
            print("Private Video Detected! Skipping...")

        vid_count += 1

print("Done!")
print(f"Completed: {len(video_list)} videos")


from django.db import models
from base.models import BaseModel
from django.conf import settings

class Customer(BaseModel):
    """Customer Model"""

    first_name = models.CharField(max_length=200)
    last_name = models.CharField(max_length=200)
    email = models.EmailField(unique=True)
    phone = models.CharField(max_length=200)
    address = models.TextField(max_length=200)
    picture = models.ImageField(upload_to="profile/images")
    user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)

    class Meta:
        """Meta"""

        ordering = ["first_name", 'last_name']
        indexes = [models.Index(fields=["user", 'email', 'phone'])]

    def __str__(self):
        """Module name"""
        return f'{self.first_name} {self.last_name}'


class Solution:
    def searchInsert1(self, nums: List[int], target: int) -> int:
        ans=len(nums)-1
        if max(nums) < target:
            return len(nums)
        if min(nums) > target:
            return 0
        for i in range(0, len(nums)):
            if nums[i] == target:
                return i
            if(nums[i]>target and nums[i]<nums[ans]):
                ans = i
        return ans

    def searchInsert2(self, nums: List[int], target: int) -> int:
        if target in nums:
            return nums.index(target)
        else:
            nums.insert(0,target)
            nums.sort()
            return nums.index(target)


from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait

APP_URL = "https://rahulshettyacademy.com/angularpractice/"
options = webdriver.ChromeOptions()
options.add_argument("--start-maximized")
driver = webdriver.Chrome("../drivers/chromedriver.exe", options=options)

driver.get(APP_URL)
driver.find_element_by_link_text("Shop").click()
mobile_products = driver.find_elements_by_xpath("//div[@class='card-body']")
for mobile in mobile_products:
    if mobile.find_element_by_xpath("h4/a").text == "Blackberry":
        mobile.find_element_by_xpath("following-sibling::div/button").click()
        break

driver.find_element_by_xpath("//a[contains(text(),'Checkout')]").click()
driver.find_element_by_xpath("//button[contains(text(),'Checkout')]").click()
driver.find_element_by_id("country").send_keys("ind")

wait = WebDriverWait(driver, 10)
wait.until(EC.visibility_of_element_located((By.XPATH, "//a[text()='India']")))

driver.find_element_by_link_text("India").click()

driver.find_element_by_xpath("//div[@class='checkbox checkbox-primary']").click()

driver.find_element_by_css_selector("input[value='Purchase']").click()

assert "Success" in driver.find_element_by_xpath("//strong[contains(text(),'Success')]").text
driver.get_screenshot_as_file("test.png")

driver.close()


from rest_framework.generics import GenericAPIView
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated

# Serializers imports
from ..serializers import *

class ShowMyUserProfileView(GenericAPIView):
    permission_classes = (
        IsAuthenticated,
    )

    def get(self, request, userName, **kwargs):

        requested_user: Usuario = Usuario.objects.get(username=userName)

        albums = [Album.objects.filter(usuario=requested_user),]

        data = {
            "result": {
                "user": UsuarioProfileSerializer(requested_user).data,
                "albums": [AlbumSerializer(a, many=True).data for a in albums]
            },
            "errors": None,
        }

        return Response(data, status=200)


from parser import *

Calculated = namedtuple('fields', 'costs_singleUse costs_multiUse_deposts costs_multiUse_rents')

def make_codesRates_dict(codes_singleUse:list, rates_singleUse:list):
	"""{codes_codes_singleUse: rates_singleUse, ...etc.}"""
	return dict(zip(codes_singleUse, rates_singleUse))

def filter_repeated_codes(codes_multiUse):
	"""[1, 1, 2, 2] -> [1, 2]"""
	filtred_codes = []
	for code in codes_multiUse:
		if not code in filtred_codes:
			filtred_codes.append(code)
	return filtred_codes

def make_codesPayments_dict(codes_multiUse, deposits_multiUse, rents_multiUse):
	"""codes_multiUse; deposits_multiUse; rents_multiUse ->
	-> {codes_multiUse: (deposits_multiUse, rents_multiUse)}"""
	codes_multiUse = filter_repeated_codes(codes_multiUse)
	depRen_tuples = zip(deposits_multiUse, rents_multiUse)
	codes_and_DepRenTuples = zip(codes_multiUse, depRen_tuples)  #(code_multiUse, (deposits_multiUse, rents_multiUse), ...etc.)
	return dict(codes_and_DepRenTuples)

def calc_packings(data):
	codesRates_dict = make_codesRates_dict(data.codes_singleUse, data.rates_singleUse)
	codesPayments_dict = make_codesPayments_dict(data.codes_multiUse, data.deposits_multiUse,
									  data.rents_multiUse)
	costs_singleUse = []
	costs_multiUse_deposts = []
	costs_multiUse_rents =[]

	index = 0
	for code in data.codes:
		if code in codesRates_dict:
			rate = codesRates_dict[code]
			number = data.numbers[index]

			cost = round(rate * number, 2)

			costs_singleUse.append(cost)
			costs_multiUse_deposts.append(None)
			costs_multiUse_rents.append(None)
			index +=1
		elif code in codesPayments_dict:
			payment = codesPayments_dict[code]
			number = data.numbers[index]

			deposit = payment[0]
			dep_cost = round(deposit * number, 2)

			rent = payment[1]
			rent_cost = round(rent * number, 2)

			costs_multiUse_deposts.append(dep_cost)
			costs_multiUse_rents.append(rent_cost)
			costs_singleUse.append(None)
			index +=1
		else:
			costs_singleUse.append(None)
			costs_multiUse_deposts.append(None)
			costs_multiUse_rents.append(None)
			index +=1

	return Calculated(costs_singleUse, costs_multiUse_deposts, costs_multiUse_rents)

def write_column(sheet, data:list, starting_row, column):
		for i in data:
			sheet.cell(starting_row, column).value = i
			starting_row += 1

def write_results(sample_file, outp_filename, parsed, calculated):
	wb = load_workbook(sample_file)
	sheet = wb.active

	write_column(sheet, parsed.custumers, 5, 4)   		          # Поставщик
	write_column(sheet, parsed.varieties, 5, 5)   		          # Сорт
	write_column(sheet, parsed.prices, 5, 6)      		          # Цена за стебель
	write_column(sheet, parsed.pieces, 5, 7)   		          # Кол-во в коробке
	write_column(sheet, parsed.numbers, 5, 8)  		          # Коробок шт.
	write_column(sheet, parsed.totals, 5, 9)  		          # Всего стеблей
	write_column(sheet, parsed.amounts, 5, 10)  		          # Purchases of products (NE)
	write_column(sheet, calculated.costs_singleUse, 5, 14)  	  # Single use packaging Connect (NE)
	write_column(sheet, calculated.costs_multiUse_deposts, 5, 15)     # Packaging deposit by Connect (AG)
	write_column(sheet, calculated.costs_multiUse_rents, 5, 16)       # Packaging rent by Connect (NE)

	wb.save(outp_filename)

	return outp_filename

if __name__ == '__main__':
	pass


from enum import Enum
from collections import deque
import math
import networkx as nx
import numpy as np
import itertools as it
from .mobility import mobility
from .division import Division

'''
    init_df should have columns 'infective', 'inhabitant' and 'susceptible'.
    Setting iterative to False will reduce the running time but may result in
    a suboptimal clustering.
'''
def adaptive_mobility_regions(init_df,res=16000,mobility=None,iterative=True,**kwargs):
    if not mobility:
        from .mobility import mobility as mobmob
        mobility = mobmob
    if not 'infective' in init_df.columns:
        init_df['infective'] = init_df['infected_tested']+init_df['infected_nottested']
    G = mobility.G.copy()
    nx.set_node_attributes(G, init_df['infective'].to_dict(), 'infective')
    nx.set_node_attributes(G, init_df['susceptible'].to_dict(), 'susceptible')

    scorer = AdaptiveMobilityRegionsScorer(G=G,res=res,**kwargs)
    opt = Louvain(scorer,iterative=iterative)
    opt.optimize()
    print("Obtained score",opt.scorer.value())
    return opt.scorer.candidate()

'''
    Returns a division with two regions: One being division[isolated_area] and
    one obtained from merging all other regions.
'''
def isolation_division(division,isolated_area):
    return Division({
        i: 0 if division[i]==division[isolated_area] else 1
        for i in division.keys()
    })

'''
    Returns the mobility regions coresponding to a given resolution parameter res.
        mobility_regions(res=res)
    Set iterative=False to accelerate.
'''
def mobility_regions(res=2,mobility=None,iterative=True,**kwargs):
    if not mobility:
        from .mobility import mobility as mobmob
        mobility = mobmob
    scorer=ModularityScorer(mobility.G,res=res,**kwargs)
    opt = Louvain(scorer,iterative=iterative)
    opt.optimize()
    return opt.scorer.candidate()
class LouvainScorer:
    @staticmethod
    def aggregate_graph(G,C,agg_attrs=[],agg_edge_attrs=[]):
        newG = nx.DiGraph()
        newG.add_nodes_from(C.regions.keys())
        attrs_dict = {
            node: {
                **{
                    attr: sum([
                        G.nodes[subnode][attr]
                        for subnode in subnodes
                    ])
                    for attr in agg_attrs
                }, **{
                    attr: sum([
                        G[i][j][attr]
                        for i,j in G.subgraph(subnodes).edges
                    ]) + sum([
                        G.nodes[subnode][attr]
                        for subnode in subnodes
                        if attr in G.nodes[subnode]
                    ])
                    for attr in agg_edge_attrs
                }
            }
            for node,subnodes in C.regions.items()
        }
        nx.set_node_attributes(newG,attrs_dict)
        newEdges={}
        for i,j in G.edges:
            if not (C[i],C[j]) in newEdges:
                newEdges[C[i],C[j]] = 0
            newEdges[C[i],C[j]] += G[i][j]['weight']
        newG.add_weighted_edges_from([
            e+(w,)
            for e,w in newEdges.items()
        ])
        return newG

    def __init__(self, G, C0=None,agg_attrs=[],agg_edge_attrs=[]):
        self.G = G
        self.G_start = self.G.copy()
        if C0 is None:
            C0 = Division(dict(zip(G.nodes,G.nodes)))
        self.HC0 = C0
        self.HC = self.HC0.copy()
        self.performed_actions = []
        self.agg_attrs=agg_attrs
        self.agg_edge_attrs = agg_edge_attrs

        # Total weight of the graph
        self.in_degree = lambda x: (sum(d for _,d in self.G.in_degree(x, weight='weight')) if hasattr(x, '__iter__') else self.G.in_degree(x,weight='weight'))
        self.out_degree = lambda x: (sum(d for _,d in self.G.out_degree(x, weight='weight')) if hasattr(x, '__iter__') else self.G.out_degree(x,weight='weight'))
        self.total = self.in_degree(self.G.nodes)

        self.current_value = self.recalculate_value()

    # Returns the (current) candidate as a flat clustering
    def candidate(self):
        return self.HC.flatClustering()

    # Only called at initialization. Leaving this at 0 should not influence the
    # optimization while it will result in wrong values of current_value and value()
    def recalculate_value(self):
        return 0

    def value(self):
        return self.current_value

    def relabel_value(self,newlabel,node):
        pass
    def action_value(self,action):
        # Only do something for RelabelNode
        if type(action)==RelabelNode:
            return self.relabel_value(action.newlabel, action.node)
        return self.current_value

    # This is called right before the Aggregate action is performed. Can be
    # implemented to keep track of variables
    def will_aggregate(self):
        pass
    def will_recluster(self):
        pass
    def will_relabel(self,newlabel,node):
        pass
    def will_flatten(self):
        pass

    # The nodes who need to be revisited by MoveNodes after node has been moved to newlabel
    def revisit_nodes_after_relabel(self,relabel_action):
        node = relabel_action.node
        label = relabel_action.newlabel
        return set(self.G.predecessors(node)).union(self.G.successors(node))-self.HC.regions[label]

    # Updates clustering by performing the action
    def perform_action(self,action):
        if type(action) == Aggregate:
            # Aggregate the graph
            self.G = self.aggregate_graph(self.G,self.HC,agg_attrs=self.agg_attrs,agg_edge_attrs=self.agg_edge_attrs)
            self.will_aggregate()
        elif type(action) == Flatten:
            # Use the flat version of G
            self.G = self.G_start
            self.will_flatten()
        elif type(action) == RelabelNode:
            # Use the flat version of G
            self.current_value = self.relabel_value(action.newlabel,action.node)
            self.will_relabel(action.newlabel,action.node)
        elif type(action) != RelabelNode:
            print(action,"of type",type(action),"is not allowed for a",type(self))
        self.HC = action.perform(self.HC)
        self.performed_actions.append(action)

class ProductFormScorer(LouvainScorer):
    def __init__(self, G, node_in_weights, node_out_weights, C0=None):
        newG = G.copy()
        nx.set_node_attributes(newG,node_in_weights,'in_weight')
        nx.set_node_attributes(newG,node_out_weights,'out_weight')
        agg_attrs = ['in_weight','out_weight']
        super().__init__(newG,C0=C0,agg_attrs=agg_attrs)

    def initialize_aggregates(self):
        self.community_aggregates = {
            l: {
                'weight': self.weight(c,c,symmetric=False),
                **{
                    attr: sum(
                        self.G.nodes[i][attr]
                        for i in c
                    )
                    for attr in ['in_weight','out_weight']
                }
            }
            for l,c in self.HC.regions.items()
        }
    def community_contribution(self,weight,in_weight,out_weight):
        return weight - in_weight * out_weight
    def recalculate_value(self):
        # Recompute the aggregates
        self.initialize_aggregates()

        return sum(
            self.community_contribution(**aggs)
            for aggs in self.community_aggregates.values()
        )

    def relabel_value(self,newlabel,node,verbose=False):
        oldlabel = self.HC[node]
        newlabel_contribution_before = self.community_contribution(
            **self.community_aggregates[newlabel]
        ) if newlabel in self.community_aggregates else 0

        # Subtract previous contributions of newlabel and oldlabel and add updated ones
        return self.current_value - newlabel_contribution_before - self.community_contribution(
            **self.community_aggregates[oldlabel]
        ) + self.community_contribution(
            **self.update_aggregates_before_leave(oldlabel,node)
        ) + self.community_contribution(
            **self.update_aggregates_before_enter(newlabel,node)
        )

    # If withoutself and HC[i]==label, then we compute the penalty between {i} and label-{i}
    def node_community_penalty(self,i,label,withoutself=False):
        selfpenalty = 0
        if withoutself and self.HC[i]==label:
            selfpenalty = -2*self.G.nodes[i]['in_weight']*self.G.nodes[i]['out_weight']
        return selfpenalty + (
            self.community_aggregates[label]['in_weight'] * self.G.nodes[i]['out_weight']
            + self.community_aggregates[label]['out_weight'] * self.G.nodes[i]['in_weight']
        )

    def node_community_contribution(self,i,label):
        weight = sum([
            self.G[i][j]['weight'] for j in self.G.successors(i)
        ]) + sum([
            self.G[j][i]['weight'] for j in self.G.predecessors(i)
        ])
        return weight - self.node_community_penalty(i,label)

    def pair_contribution(self,i,j):
        return (
            self.G[i][j]['weight'] if j in self.G[i] else 0
        ) + (
            self.G[j][i]['weight'] if i in self.G[j] else 0
        ) - (
            self.G.nodes[i]['in_weight'] * self.G.nodes[j]['out_weight']
            + self.G.nodes[i]['out_weight'] * self.G.nodes[j]['in_weight']
        )

    def will_relabel(self,newlabel,node):
        self.community_aggregates[newlabel] = self.update_aggregates_before_enter(newlabel,node)
        oldlabel = self.HC[node]
        if len(self.HC.regions[oldlabel])==1:
            del self.community_aggregates[oldlabel]
        else:
            self.community_aggregates[oldlabel] = self.update_aggregates_before_leave(oldlabel,node)

    # Assuming node is not yet in HC[newlabel]
    def update_aggregates_before_enter(self,newlabel,node):
        if not newlabel in self.HC.regions.keys():
            #print(node,'wants to move to the new label',newlabel)
            # Then it's a move to a new label
            return {
                'weight': self.weight({node},{node},symmetric=False),
                **{
                    attr: self.G.nodes[node][attr]
                    for attr in self.agg_attrs
                }
            }
        if node in self.HC.regions[newlabel]:
            print("AggregationScorer.update_aggregates_before_enter error: node",node,"is in community",newlabel)
        aggs_before = self.community_aggregates[newlabel]
        newc = self.HC.regions[newlabel]
        return {
            'weight': aggs_before['weight'] + self.weight({node},newc,symmetric=True) + self.weight({node},{node},symmetric=False),
            **{
                attr: aggs_before[attr] + self.G.nodes[node][attr]
                for attr in self.agg_attrs
            }
        }

    # Assuming node in HC.regions[oldlabel]
    def update_aggregates_before_leave(self,oldlabel,node):
        if not node in self.HC.regions[oldlabel]:
            print("AggregationScorer.update_aggregates_before_leave error: node",node,"is not in community",oldlabel)
        aggs_before = self.community_aggregates[oldlabel]
        oldc = self.HC.regions[oldlabel]-{node}

        return {
            'weight': aggs_before['weight'] - self.weight({node},oldc,symmetric=True) - self.weight({node},{node},symmetric=False),
            **{
                attr: aggs_before[attr] - self.G.nodes[node][attr]
                for attr in self.agg_attrs
            }
        }

    def weight(self,c_start,c_end,symmetric=False,weight_attr='weight'):
        # Note that even if weight_attr!='weight', then still the constructor
        # of LouvainScorer gives self.G edge-weights with label 'weight'
        weight = sum(
            self.G[i][j][weight_attr]
            for i in c_start
            for j in set(c_end).intersection(self.G[i])
        )
        if symmetric:
            weight += sum(
                self.G[i][j][weight_attr]
                for i in c_end
                for j in set(c_start).intersection(self.G[i])
            )
        return weight

class ModularityScorer(ProductFormScorer):
    def __init__(self, G, C0=None, res=1):
        in_weight,out_weight = ModularityScorer.in_out_weights(G,res=res)
        super().__init__(G, in_weight, out_weight, C0=C0)

    def in_out_weights(G,res=1):
        in_degree = G.degree
        out_degree = G.degree
        if G.is_directed():
            in_degree = G.in_degree
            out_degree = G.out_degree
        total = sum([d for _,d in in_degree(G.nodes, weight='weight')])
        scaling = math.sqrt(res / total)
        in_weight = {
            i: scaling * in_degree(i, weight='weight')
            for i in G.nodes
        }
        out_weight = {
            i: scaling * out_degree(i, weight='weight')
            for i in G.nodes
        }
        return (in_weight,out_weight)

    def value(self,normalized=False):
        if normalized:
            return self.current_value/self.total
        return self.current_value

class AdaptiveMobilityRegionsScorer(ProductFormScorer):
    def __init__(self, G,
                 C0=None, res=1):
        self.total_inhabitants = sum(
            G.nodes[i]['inhabitant']
            for i in G.nodes
        )
        self.res=res
        in_weight,out_weight = AdaptiveMobilityRegionsScorer.in_out_weights(G,self.total_inhabitants,res=res)
        super().__init__(G, in_weight, out_weight, C0=C0)

    @staticmethod
    def in_out_weights(G,total_inhabitants,res=1):
        scaling = math.sqrt(res / total_inhabitants)
        in_weight = {
            i: scaling * G.nodes[i]['infective']
            for i in G.nodes
        }
        out_weight = {
            i: scaling * G.nodes[i]['susceptible']
            for i in G.nodes
        }
        return (in_weight,out_weight)

    def value(self):
        return self.current_value

class ObjectiveScorer(LouvainScorer):
    def __init__(self,init_df,horizon=30,tradeoff=1500,init_hc=None,mobility=mobility):
        from .mobility_seir import MobilitySEIR
        if init_hc is None:
            init_hc = Division(dict(zip(init_df.index,init_df.index)))
        if not isinstance(init_hc,Division):
            init_hc = Division(init_hc)
        self.tradeoff=tradeoff
        self.horizon=horizon
        self.seir = MobilitySEIR(init_df, horizon, division=init_hc.flatClustering())
        self.block2areas = {
            l: init_hc.flatitems({l})
            for l in init_hc.keys()
        }
        G = self.aggregate_graph(mobility.G,Division.FromRegions(self.block2areas))
        super().__init__(G,C0=Division(init_hc))

    def flattenblocks(self,blocks):
        return set().union(*(self.block2areas[block] for block in blocks))

    def relabel_value(self,newlabel,node):
        oldlabel = self.HC[node]
        oldlabel_oldscore = self.region2score[oldlabel]
        flatnodes = self.flattenblocks(self.HC.flatitems({node}))
        # find the areas corresponding to the new destination region
        r_dest = flatnodes
        if newlabel in self.seir.division.regions:
            r_dest |= self.seir.division.regions[newlabel]
        newlabel_oldscore = self.region2score[newlabel] if newlabel in self.region2score else 0
        newlabel_newscore = self.seir.objective(self.tradeoff,region=r_dest)
        # Lazy-load oldlabel_newscore
        if not oldlabel in self.region2block2leave_score:
            self.region2block2leave_score[oldlabel] = {}
        if not node in self.region2block2leave_score[oldlabel]:
            r_orig = self.seir.division.regions[oldlabel] - flatnodes
            self.region2block2leave_score[oldlabel][node] = self.seir.objective(self.tradeoff,region=r_orig)
        oldlabel_newscore = self.region2block2leave_score[oldlabel][node]
        return self.current_value + (
            newlabel_newscore - newlabel_oldscore
        ) + (
            oldlabel_newscore - oldlabel_oldscore
        )

    def recalculate_value(self):
        # Clean lazy-loader
        self.region2block2leave_score = {}
        # Simulate and store results
        self.seir.simulate_all()
        self.region2score = {
            r: self.seir.objective(self.tradeoff,region=r)
            for r in self.seir.division.labels()
        }
        self.current_value = sum(self.region2score.values())
        return self.current_value

    def revisit_nodes_after_relabel(self,relabel_action):
        return self.HC.nodes()

    def will_flatten(self):
        # Clean lazyloader
        self.region2block2leave_score = {}

    def will_relabel(self,newlabel,node):
        # update region2score. Note that we do this super inefficiently by repeating the simulation.
        oldlabel = self.HC[node]

        # Clean lazyloader
        if newlabel in self.region2block2leave_score:
            del self.region2block2leave_score[newlabel]
        if oldlabel in self.region2block2leave_score:
            del self.region2block2leave_score[oldlabel]

        # Move all nodes
        nodes = self.flattenblocks(self.HC.flatitems({node}))
        for i in nodes:
            self.seir.division[i] = newlabel
        self.seir.region2states[newlabel] = self.seir.simulate_region(newlabel)
        self.region2score[newlabel] = self.seir.objective(self.tradeoff,region=newlabel)
        # Check whether the old region still exists
        if oldlabel in self.seir.division.regions:
            self.seir.region2states[oldlabel] = self.seir.simulate_region(oldlabel)
            self.region2score[oldlabel] = self.seir.objective(self.tradeoff,region=oldlabel)
        else:
            del self.seir.region2states[oldlabel], self.region2score[oldlabel]
'''
    Definition of all the different actions/moves that the optimization algorithm makes.
'''
class Action:
    # Performs the action on the (hierarchical) clustering HC and return the resulting clustering
    def perform(self,C):
        pass
    # For reproducability purposes
    def __hash__(self):
        return str(self).__hash__()
    # For reproducability purposes
    def __eq__(self,obj):
        return type(self)==type(obj) and hash(self)==hash(obj)

# A non-action (doesn't change the clustering)
class SkipAction(Action):
    def __init__(self,description=""):
        self.description = str(description)
    def __str__(self):
        if len(self.description)>0:
            return "skip {}".format(self.description)
        return "skip"
    # For reproducability purposes
    def __hash__(self):
        return (type(self),self.description).__hash__()

# A non-action (doesn't change the clustering)
class Done(Action):
    def __str__(self):
       return "optimization finished"

# A non-action (doesn't change the clustering)
class Restart(Action):
    def __str__(self):
       return "Start a new iteration"

class RelabelNode(Action):
    def __init__(self, node, newlabel):
        self.node = node
        self.newlabel = newlabel
    def perform(self,HC):
        HC[self.node] = self.newlabel
        return HC
    def __str__(self):
        return "relabeling node {} to label {}".format(self.node,self.newlabel)
    def __hash__(self):
        return (type(self),self.node,self.newlabel).__hash__()

# Aggregate the clusters into new nodes by going up a level in the hierarchy
class Aggregate(Action):
    print_str = "aggregating clusters"
    def perform(self,HC):
        self.print_str = "aggregating {} clusters".format(len(HC.regions))
        return HC.nextlevel()
    def __str__(self):
        return self.print_str
# Flatten the Hierarchical clustering into a regular clustering
class Flatten(Action):
    def perform(self,HC):
        return HC.flatClustering()
    def __str__(self):
        return "flattening clusters"

'''
    Definition of the optimization algorithm.
'''
class Louvain:
    '''
    I like to view Louvain as a state diagram with the states represented by
    the enum LouvainState. The actions cause the following transitions:
        RelabelNode: MOVENODES_UNIMPROVED/MOVENODES_IMPROVED -> MOVENODES_IMPROVED
        Aggregate:   PASS_HAS_IMPROVED -> MOVENODES_UNIMPROVED
        Flatten: PASS_WAS_STABLE -> ITERATION_ENDED
        SkipAction:
            if the queue is empty:
                MOVENODES_UNIMPROVED -> PASS_WAS_STABLE
                MOVENODES_IMPROVED -> PASS_HAS_IMPROVED
            else we remain in state MOVENODES_UNIMPROVED/MOVENODES_IMPROVED
    Louvain can be applied iteratively by transitioning from ITERATION_ENDED to
    MOVENODES_UNIMPROVED (whenever the iteration performed RelabelNode at least once).
    After each occurrence of RelabelNode or SkipAction, current_node is taken from
    the queue.
    '''
    class LouvainState(Enum):
        MOVENODES_UNIMPROVED=0
        MOVENODES_IMPROVED=1
        PASS_WAS_STABLE=2
        PASS_HAS_IMPROVED=3
        ITERATION_ENDED=4

    def __init__(self,scorer,iterative=False,random=False,seed=None):
        self.scorer = scorer
        # Keep track of the action_index at the start of the iteration so that
        # At the end of the iteration, we can see whether we can terminate.
        self.action_index_start = len(scorer.performed_actions)

        self.iterative = iterative
        if random:
            self.random = np.random.RandomState(seed=seed)
        else:
            self.random = False

        self.state = Louvain.LouvainState.MOVENODES_UNIMPROVED
        self.start_pass()

    # Iterator that returns the next action at each point.
    # NOTE THAT IT DOES NOT PERFORM THE ACTION so that iterating over this
    # without performing results in an infinite loop
    def action_sequence(self):
        while True:
            action = self.select_action(self.candidate_actions())
            yield (action)
            if isinstance(action, Done):
                break  # Optimization finished

    def optimize(self,verbose=False):
        for action in self.action_sequence():
            if verbose:
                print(action)
            if not type(action) in (Done,SkipAction,Restart):
                self.scorer.perform_action(action)
            self.update_state(action)

    def next(self):
        if not hasattr(self,'action_iterator'):
            self.action_iterator = self.action_sequence()

        action = next(self.action_iterator)
        if not type(action) in (Done,SkipAction):
            self.scorer.perform_action(action)
        self.update_state(action)
        print(action)

    def start_pass(self):
        nodes = self.scorer.HC.keys()
        # Randomize order
        if self.random:
            nodes = list(nodes)
            self.random.shuffle(nodes)
        self.queue = deque(nodes)
        self.stable_nodes = []
        self.current_node = self.queue.popleft()

    def iteration_ended(self):
        if not self.iterative:
            return # We are done, the algorithm has terminated
        # Check if RelabelNode was performed since the first aggregation of this iteration
        new_actions = self.scorer.performed_actions[self.action_index_start:]
        aggregated = False
        for action in new_actions:
            if type(action)==Aggregate:
                aggregated = True
            if aggregated and type(action)==RelabelNode:
                self.action_index_start = len(self.scorer.performed_actions)
                self.state = Louvain.LouvainState.MOVENODES_UNIMPROVED
                self.start_pass()
                return
        # Else, The algorithm has terminated

    def candidate_actions(self):
        if self.state == Louvain.LouvainState.ITERATION_ENDED:
            # Terminate
            return set()
        if self.state == Louvain.LouvainState.PASS_WAS_STABLE:
            return {Flatten()}
        if self.state == Louvain.LouvainState.PASS_HAS_IMPROVED:
            return {Aggregate()}

        # Else we return the RelabelNode candidates
        labels = {self.scorer.HC.newlabel()}
        # Don't allow to move to new community if it is in a singleton
        if len(self.scorer.HC.regions[self.scorer.HC[self.current_node]])==1:
            labels=set()
        # Check if the graph is aggregated
        if self.current_node in self.scorer.G.nodes:
            # If so, return the labels of the neighbors of i
            labels = labels.union({
                self.scorer.HC[j]
                for j in it.chain(
                        self.scorer.G.neighbors(self.current_node),
                        self.scorer.G.predecessors(self.current_node))
            } - {self.scorer.HC[self.current_node]})
        else:
            # If not, we simply return all other labels
            labels = labels.union(self.scorer.HC.labels() - {self.scorer.HC[self.current_node]})
        # We add the SkipAction, so that there is always at least one action returned.
        # If only one action is returned (a forced action), it will be the SkipAction.
        return {
            RelabelNode(self.current_node, label)
            for label in labels
        }.union({SkipAction(self.current_node)})

    def select_action(self,candidates):
        candidates = {
            c: self.scorer.action_value(c)
            for c in candidates
        }
        if len(candidates) == 0:
            # Iteration ends if there are no candidates left
            return Done()
        # If candidate is a dict, we assume its values are the scores.
        if isinstance(candidates,dict):
            best_action = max(candidates,key=candidates.get)
        # If there is only one candidate, then we consider it a 'forced move'
        # Otherwise, only perform an action if it increases the score
        best_action = max(candidates, key=self.scorer.action_value)
        if len(candidates) == 1 or self.scorer.action_value(best_action) > self.scorer.value():
            return best_action
        else:
            return SkipAction("tie")

    def update_state(self,action):
        if type(action)==RelabelNode:
            self.state = Louvain.LouvainState.MOVENODES_IMPROVED
            # We add all nodes that were previously stable, since this change
            # may make them unstable again.
            # The speed could be significantly improved by efficiently identifying
            # which nodes definitely remained stable so that they do not need to
            # requeued.
            self.queue.extend(self.stable_nodes)
            self.stable_nodes = [self.current_node]
            # len(queue)==len(HC.keys())-len(stable_nodes)==len(HC.keys())-1
            # while an occurrance of RelabelNode implies len(HC.keys())>1.
            # Therefore the queue must be nonempty at this point
            self.current_node = self.queue.popleft()
        if type(action)==SkipAction:
            self.stable_nodes.append(self.current_node)
            if len(self.queue)>0:
                self.current_node = self.queue.popleft()
            elif self.state==Louvain.LouvainState.MOVENODES_IMPROVED:
                self.state = Louvain.LouvainState.PASS_HAS_IMPROVED
            else: # self.state==Louvain.LouvainState.MOVENODES_UNIMPROVED
                self.state = Louvain.LouvainState.PASS_WAS_STABLE

        if type(action)==Aggregate:
            self.state = Louvain.LouvainState.MOVENODES_UNIMPROVED
            self.start_pass()
        if type(action)==Flatten:
            self.state = Louvain.LouvainState.ITERATION_ENDED
            self.iteration_ended()


def main(input_filename,output_filename):
    with open(input_filename,'r') as input_file,\
         open(output_filename,'w')as output_file:
        for line in input_file:
            if len(line)>0:
                line=line.split()
                output_file.write('(0)\n'.format(operate(line(0))))

#hola soy isabel esto es
#una prueba

def operate(x,y):
    return int(x)+int(y)

if __name__=='__main__':
    main('number.in','numbers.out')


from django.shortcuts import render
from django.views.decorators.csrf import csrf_exempt
from rest_framework.parsers import JSONParser
from django.http import JsonResponse

from InventoryApp.models import Factories, Products
from InventoryApp.serializers import FactoriesSerializer, ProductsSerializer

from django.core.files.storage import default_storage

from rest_framework.views import APIView

from rest_framework.response import Response

from django.http import HttpResponse
# Create your views here.

@csrf_exempt
def factoryApi(request,id=0):
    if request.method=='GET':
        if id!=0:
            factory=Factories.objects.get(FactoryId=id)
            factory_serializer=FactoriesSerializer(factory)
            return JsonResponse(factory_serializer.data,safe=False)
        factories = Factories.objects.all()
        factories_serializer=FactoriesSerializer(factories,many=True)
        return JsonResponse(factories_serializer.data,safe=False)

    elif request.method=='POST':
        factory_data = JSONParser().parse(request)
        print(factory_data)
        factories_serializer=FactoriesSerializer(data=factory_data)
        if factories_serializer.is_valid():
            factories_serializer.save()
            factories = Factories.objects.all()
            factories_serializer=FactoriesSerializer(factories,many=True)
            return JsonResponse(factories_serializer.data,safe=False)
            # return JsonResponse(factories_serializer,safe=False)
        return JsonResponse("Failed to add",safe=False)

    elif request.method=='PUT':
        factory_data = JSONParser().parse(request)
        factory=Factories.objects.get(FactoryId=factory_data['FactoryId'])
        factories_serializer=FactoriesSerializer(factory,data=factory_data)
        if factories_serializer.is_valid():
            factories_serializer.save()
            factories = Factories.objects.all()
            factories_serializer=FactoriesSerializer(factories,many=True)
            return JsonResponse(factories_serializer.data,safe=False)
            # return JsonResponse("Added successfully",safe=False)
        return JsonResponse("Failed to add",safe=False)

    elif request.method=='DELETE':
        factory=Factories.objects.get(FactoryId=id)
        factory.delete()
        factories = Factories.objects.all()
        factories_serializer=FactoriesSerializer(factories,many=True)
        return JsonResponse(factories_serializer.data,safe=False)
        # return JsonResponse("Deleted successfully",safe=False)

@csrf_exempt
def productApi(request,id=0):
    if request.method=='GET':

        products = Products.objects.select_related().filter(Factory=id)
        print(products)
        products_serializer=ProductsSerializer(products,many=True)
        # print(products_serializer)
        return JsonResponse(products_serializer.data,safe=False)

    elif request.method=='POST':
        form = Products(request.POST,request.FILES)
        # product_data=dir(request)
        product_data=request.POST
        # product_data = JSONParser().parse(request)
        print("pdata:",form)
        # products_serializer=ProductsSerializer(data=product_data)
        # print(products_serializer)
        # if products_serializer.is_valid():
        #     products_serializer.save()
        #     products = Products.objects.select_related().filter(Factory=id)
        #     products_serializer=ProductsSerializer(products,many=True)
        #     print(products_serializer)
        #     return JsonResponse(products_serializer.data,safe=False)
        return JsonResponse("Failed to add",safe=False)

    elif request.method=='PUT':
        product_data = JSONParser().parse(request)
        product=Products.objects.get(productId=product_data['productId'])
        products_serializer=ProductsSerializer(product,data=product_data)
        if products_serializer.is_valid():
            products_serializer.save()
            return JsonResponse("Added successfully",safe=False)
        return JsonResponse("Failed to add",safe=False)

    elif request.method=='DELETE':
        product=Products.objects.get(ProductId=id)
        product.delete()
        products = Products.objects.select_related().filter(Factory=id)
        products_serializer=ProductsSerializer(products,many=True)
        return JsonResponse(products_serializer.data,safe=False)

@csrf_exempt
def SaveFile(request):
    print("req:",request.FILES)
    file_=request.FILES['file']
    file_name=default_storage.save(file_.name,file_)
    return JsonResponse(file_name,safe=False)

class productClass(APIView):
    def get(self,request,id=0):
        products = Products.objects.select_related().filter(Factory=id)
        # products = Products.objects.all()
        products_serializer=ProductsSerializer(products,many=True)
        # form=FormData()
        return JsonResponse(products_serializer.data,safe=False)

    def post(self,request):
        products_serializer=ProductsSerializer(data=request.data)
        print(request.data)
        if products_serializer.is_valid():
            products_serializer.save()
            # products = Products.objects.select_related().filter(Factory=id)
            # products_serializer=ProductsSerializer(products,many=True)
            # print(products_serializer)
            return JsonResponse(products_serializer.data)
        return Response({"status":500})
    def delete(self,request,id=0):
        product=Products.objects.get(ProductId=id)
        product.delete()
        return Response({"status":200})
class productDetail(APIView):
    def get(self,request,id=0):
        product=Products.objects.get(ProductId=id)
        # products = Products.objects.all()
        products_serializer=ProductsSerializer(product)
        print(products_serializer.data)
        return Response(products_serializer.data)
    def put(self,request,id=0):
        product=Products.objects.get(ProductId=request.data['ProductId'])
        print("put",product)
        # products = Products.objects.all()
        products_serializer=ProductsSerializer(product,data=request.data)
        if products_serializer.is_valid():
            products_serializer.save()
            return Response(products_serializer.data)
        return Response({"status":500,"message":"error:("})


from bmp180 import BMP180
from machine import I2C, Pin                        # create an I2C bus object accordingly to the port you are using

# bus =  I2C(scl=Pin(4), sda=Pin(5), freq=100000)   # on esp8266
bus = I2C(scl=machine.Pin(5), sda=machine.Pin(4))

bmp180 = BMP180(bus)
bmp180.oversample_sett = 2
bmp180.baseline = 101325

temp = bmp180.temperature
p = bmp180.pressure
mbar = p/100
altitude = bmp180.altitude
print(temp, mbar, altitude)


if __name__ == '__main__':
    marks = []
    both = []
    for _ in range(int(input())):
        name = input()
        score = float(input())
        marks += [score]
        both += [[name, score]]
    second_lowest = sorted(list(dict.fromkeys(marks)))[1]
    for x, y in sorted(both):
        if second_lowest == y:
            print(x)

# stdin = 5
#         Harry
#         37.21
#         Berry
#         37.21
#         Tina
#         37.2
#         Akriti
#         41
#         Harsh
#         39

# https://www.hackerrank.com/challenges/nested-list/problem


from .core import encode, decode, alabel, ulabel, IDNAError
import codecs
import re
from typing import Tuple, Optional

_unicode_dots_re = re.compile('[\u002e\u3002\uff0e\uff61]')

class Codec(codecs.Codec):

    def encode(self, data: str, errors: str = 'strict') -> Tuple[bytes, int]:
        if errors != 'strict':
            raise IDNAError('Unsupported error handling \"{}\"'.format(errors))

        if not data:
            return b"", 0

        return encode(data), len(data)

    def decode(self, data: bytes, errors: str = 'strict') -> Tuple[str, int]:
        if errors != 'strict':
            raise IDNAError('Unsupported error handling \"{}\"'.format(errors))

        if not data:
            return '', 0

        return decode(data), len(data)

class IncrementalEncoder(codecs.BufferedIncrementalEncoder):
    def _buffer_encode(self, data: str, errors: str, final: bool) -> Tuple[str, int]:  # type: ignore
        if errors != 'strict':
            raise IDNAError('Unsupported error handling \"{}\"'.format(errors))

        if not data:
            return "", 0

        labels = _unicode_dots_re.split(data)
        trailing_dot = ''
        if labels:
            if not labels[-1]:
                trailing_dot = '.'
                del labels[-1]
            elif not final:
                # Keep potentially unfinished label until the next call
                del labels[-1]
                if labels:
                    trailing_dot = '.'

        result = []
        size = 0
        for label in labels:
            result.append(alabel(label))
            if size:
                size += 1
            size += len(label)

        # Join with U+002E
        result_str = '.'.join(result) + trailing_dot  # type: ignore
        size += len(trailing_dot)
        return result_str, size

class IncrementalDecoder(codecs.BufferedIncrementalDecoder):
    def _buffer_decode(self, data: str, errors: str, final: bool) -> Tuple[str, int]:  # type: ignore
        if errors != 'strict':
            raise IDNAError('Unsupported error handling \"{}\"'.format(errors))

        if not data:
            return ('', 0)

        labels = _unicode_dots_re.split(data)
        trailing_dot = ''
        if labels:
            if not labels[-1]:
                trailing_dot = '.'
                del labels[-1]
            elif not final:
                # Keep potentially unfinished label until the next call
                del labels[-1]
                if labels:
                    trailing_dot = '.'

        result = []
        size = 0
        for label in labels:
            result.append(ulabel(label))
            if size:
                size += 1
            size += len(label)

        result_str = '.'.join(result) + trailing_dot
        size += len(trailing_dot)
        return (result_str, size)

class StreamWriter(Codec, codecs.StreamWriter):
    pass

class StreamReader(Codec, codecs.StreamReader):
    pass

def getregentry() -> codecs.CodecInfo:
    # Compatibility as a search_function for codecs.register()
    return codecs.CodecInfo(
        name='idna',
        encode=Codec().encode,  # type: ignore
        decode=Codec().decode,  # type: ignore
        incrementalencoder=IncrementalEncoder,
        incrementaldecoder=IncrementalDecoder,
        streamwriter=StreamWriter,
        streamreader=StreamReader,
    )


import requests
import copy
import json
import pdb
from typing import Dict, List, Tuple, Union
from ttt_web.ttt_app import create_app
import yaml

INTRO_TEXT = """
Welcome to Tick Tack Toe

What you can do:
* create a new game with a name, player user names and selected board size (3x3 or 4x4)
* Continue a saved game
* Make moves on your turn using coordinates eg. A2
* Type "userstats" on your turn to access user statistics - view the leader board or view the stats for a particular player
* Type 'exit' to quit the game - your game will automatically be saved

ENJOY!
"""
## NICO: is this the right way to config the root url?
def root_url(config_purpose:str='play_game',config_file:str='ttt_web/config/config.yaml') -> dict:
    with open(f'{config_file}', 'r') as f:
        config_dict = yaml.safe_load(f)
    host = config_dict[config_purpose]['host']
    # port = config_dict[config_purpose]['port']
    return f"http://{host}:5001"
    # NICO: Question: when I put the port number in the config file it breaks the program at the connect_db stage. It starts that step and seems to get stuck. No error message or anything, just continual nothing ? What's the problem?

def create_new_game()-> dict:
    game_name = input("Game Name: ")
    board_size = input("Select board size: A. 3x3 B. 4x4 \n>")
    if board_size.upper() == 'B' or board_size[0] == '4':
        board_size = 4
    else:
        board_size = 3
    player1 = input("Player1 Username: ")
    player2 = input("Player2 Username: ")
    data = {"game_name":game_name, "board_size":board_size,"player1":player1, "player2":player2}
    url = root_url()+"/new" #http://localhost:5001/new
    flask_game_created = requests.post(url, json=data).json() # {"status_code": #, "message":"...","game_id":#}
    # success
    if flask_game_created['status_code'] == 200:
        game_id = flask_game_created["game_id"]
        return {"status_code": flask_game_created['status_code'],"game_id":game_id, "player1":player1, "player2":player2}
    else:
        print(flask_game_created['status_code'], flask_game_created['message'])
        return {"status_code": flask_game_created['status_code']} #TODO: I don't think this return is doing anything, need to deal with 500 error in run() function perhaps? Or return EXIT?

# VISUAL | Adds row and colum labels - asethetic only
def add_axis_title(gb:List[List]) -> List[List]:
    gb_copy = copy.deepcopy(gb)
    board_size = len(gb)
    col_head = [" "]
    for i in range(board_size):
        col_head.append(str(i+1))
    gb_copy.insert(0,col_head)

    alphabet = ["A","B","C","D"]
    row_head = [""]
    for i in range(board_size):
        row_head.append(alphabet[i])
    for i in range(1,(board_size+1)):
        gb_copy[i].insert(0,f'{row_head[i]}')
    return gb_copy

# VISUAL | prints out board nicely
def print_beautiful_board(gb_copy:List[List]) -> str:
    print('\n')
    size = len(gb_copy)
    board_string = str()
    for r in range(size):
        for c in range(size):
            board_string += f"{gb_copy[r][c]}  "
        board_string += "\n"
    print(board_string)
    return board_string

def display_board(game_id:int):
    url = root_url()+'/viewgame'
    flask_viewgame = requests.post(url, json={'game_id':game_id})
    gb = flask_viewgame.json()['message']
    print_beautiful_board(add_axis_title(gb))

def load_game()->dict:
    # capture user serach
    name_search = input("search for a game or press enter to list all games: ")
    game_id_valid = False
    if name_search == "": # search all
        # pdb.set_trace()
        url = root_url()+'/games'
        flask_games:dict = requests.get(url).json()
        # Print out games
        print("Game_Name | Game_ID")
        all_games:List[dict] = flask_games['message']
        for game in all_games:
            print(game['game_name']+' : '+ str(game['game_id']))
        # select game by id, ensure choice is valid game_id
        while not game_id_valid:
            try:
                game_id = int(input("Select the game_id for the game you want to continue: "))
                for game in flask_games['message']:
                    if game_id in game.values():
                        game_id_valid = True
            except ValueError:
                print("must be an integer matching a valid game_id")
    else: # search subset of games
        url = root_url()+'/games'
        flask_games = requests.post(url, json={'name':name_search}).json()
        # if perfect match skip second selection step
        if flask_games['count'] == 1 and 'name_search' in flask_games['message'].keys(): # unique + full game_name
            game_id = flask_games['message']['name_search']
        else: # selection needed
            # Print out games
            print("Game_Name | Game_ID")
            all_games:List[dict] = flask_games['message']
            for game in all_games:
                for key in game:
                    print(game[key])
            try:
                game_id = int(input("Select the game_id for the game you want to continue: "))
                for game in flask_games:
                    if game_id in game.values():
                        game_id_valid = True
            except ValueError:
                print("must be an integer matching a valid game_id")
    # display game info
    url = root_url()+'/game'
    flask_game = requests.post(url, json={"game_id":game_id}).json()
    print("\nGAME INFO")
    print("Game Name: "+flask_game['game_name'])
    print("Game ID: "+str(flask_game["game_id"]))
    print("Player1: "+flask_game['player1'])
    print("Player2: "+flask_game['player2'])
    # determin current player
    url = root_url()+'/currentplayer'
    flask_current_player = requests.post(url, json={"game_id":game_id}).json()
    player = flask_current_player['current_player']
    return {"game_id":game_id, "player": player, "player1": flask_game['player1'],"player2": flask_game['player2']}

def make_move(game_id:int, player:str)->dict:
    move = input(f"{player} Move: ")
    # special cases
    if move == "exit":
        return {'message':'Game Exited', "game_over":True}
    if move == "userstats":
        return {'message': 'userstats', "success":False, 'game_over':False}
    # TODO add more: undo
    move_dict = {'move': move, "game_id":game_id}
    url = root_url()+'/move'
    flask_move = requests.post(url, json=move_dict).json()
    return flask_move # dict with keys: message:str, success:boolean, game_over:boolean

def display_userstats():
    select_user = input("Type a username to view their stats or press enter to view the full leader board: ")
    url = root_url()+'/userstats'
    flask_leaderboard = requests.get(url).json()
    if select_user == "":
        for key in flask_leaderboard:
            print(key, flask_leaderboard[key])
    else:
        print("\n")
        print(flask_leaderboard['Player'])
        print(flask_leaderboard[f'{select_user}'])

def run():
    # Intro and Instructions
    print(INTRO_TEXT)
    # Get game type
    resp_new = input("\nWhat kind of game do you want? \nA. New Game \nB. Saved Game\n> ")
    # new
    if resp_new[0].capitalize() == 'A' or resp_new[0].capitalize() == 'N':
        game_info = create_new_game()
        game_id = game_info["game_id"]
        player1 = game_info["player1"]
        player2 = game_info["player2"]
        player = player1
        # game creation succeeded, get empty_board
        display_board(game_id)
    # old
    else:
        game_info = load_game()
        game_id = game_info['game_id']
        player1 = game_info['player1']
        player2 = game_info['player2'] ###not working!!
        player = game_info['player']
        display_board(game_id)
    # Make move
    move_outcome = make_move(game_id, player)
    while not move_outcome['game_over']: # game not over
            if not move_outcome['success']:
                if move_outcome['message'] == 'userstats': #special input
                    display_userstats()
                else: # move failed
                    print(move_outcome['message'])
                    print('try again')
            else:
                if player == player1: #update current player
                    player = player2
                else:
                    player = player1
            display_board(game_id) # display updated board
            move_outcome = make_move(game_id, player) # next move
    display_board(game_id)
    print(move_outcome['message'])
    return

if __name__ == "__main__":
    run()


import logging
from time import sleep
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import unittest

class ChromeWow:
    def __init__(self):
        self.driver = webdriver.Chrome()
        self.url = "https://eu.gear.blizzard.com/"
        self.logger = self._set_logger()

    def _set_logger(self):
        logger = logging.getLogger('Selenium')
        logger.setLevel(logging.INFO)
        handler = logging.StreamHandler()
        formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
        handler.setFormatter(formatter)
        logger.addHandler(handler)
        return logger

    def run_add_product_to_cart_and_ship_test(self):
        self.logger.info("Open WoW Gear URL")
        self.driver.get(self.url)
        sleep(4)

        self.logger.info("Search for a product")
        self.driver.find_element(By.NAME, 'q').send_keys('horde beanie')
        self.driver.find_element(By.CSS_SELECTOR, "button[type='submit']").submit()

        self.logger.info("Check if search was successfull")
        search_successfull = self.driver.find_element(By.CSS_SELECTOR, ".search-page>.container>.page-header>h1>span:nth-child(3)").text
        tc = unittest.TestCase()
        tc.assertEqual("REVEALED THE FOLLOWING:", search_successfull)

        self.logger.info("Click on first returned product")
        self.driver.find_element(By.CSS_SELECTOR, ".product-collection>div>div:nth-child(1)").click()

        self.logger.info("Get rid of a promo popup")
        popup_close = WebDriverWait(self.driver,10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, ".klaviyo-close-form")))
        popup_close.click()
        sleep(2)

        self.logger.info("Add product to cart")
        self.driver.find_element(By.CSS_SELECTOR, "#product-add-to-cart").click()
        sleep(2)

        self.logger.info("Checkout")
        self.driver.find_element(By.CSS_SELECTOR, ".btn-checkout").click()
        sleep(2)

        self.logger.info("Add shipping details")
        self.driver.find_element(By.CSS_SELECTOR, "#checkout_email").send_keys("john.doe@example.com")
        sleep(1)
        self.driver.find_element(By.CSS_SELECTOR, "#checkout_shipping_address_first_name").send_keys("John")
        sleep(1)
        self.driver.find_element(By.CSS_SELECTOR, "#checkout_shipping_address_last_name").send_keys("Doe")
        sleep(1)
        self.driver.find_element(By.CSS_SELECTOR, "#checkout_shipping_address_address1").send_keys("Targ Drzewny")
        sleep(2)
        self.driver.find_element(By.CSS_SELECTOR, "#checkout_shipping_address_address2").send_keys("9/11")
        sleep(2)
        self.driver.find_elements(By.CSS_SELECTOR, ".ui-button-text")[0].click()
        self.driver.find_element(By.CSS_SELECTOR, "#checkout_shipping_address_city").send_keys("Gdansk")
        sleep(1)
        self.driver.find_element(By.CSS_SELECTOR, "#checkout_shipping_address_zip").send_keys("80-001")
        sleep(1)
        self.driver.find_element(By.CSS_SELECTOR, "#checkout_shipping_address_phone").send_keys("+48606606606")
        sleep(1)
        self.driver.find_element(By.CSS_SELECTOR, "#continue_button").submit()
        sleep(2)

        self.logger.info("Continue to payment")
        self.driver.find_element(By.CSS_SELECTOR, "#continue_button").submit()
        sleep(2)

        self.driver.quit()


# -*- coding: utf-8 -*-
"""
Created on Sun Nov  6 23:20:31 2022

@author: Jim Achterberg
"""
import numpy as np
import pandas as pd
from numpy import random as rd
from sklearn.datasets import make_spd_matrix
from scipy.stats import ortho_group as og
from scipy.stats import rv_discrete

def VAR_gaussian(shape):
    N,T,F = shape
    sigma = make_spd_matrix(n_dim=F)
    err_mean = np.zeros(shape=F)
    errors = rd.multivariate_normal(err_mean,sigma,size=(N,T))
    V = rd.uniform(low=0,high=1,size=(F)) * np.identity(n=F)
    Q = og.rvs(dim=F)
    A = np.matmul(np.matmul(Q,V),np.linalg.inv(Q))
    data = np.empty((N,T,F))
    for t in range(T):
        if t==0:
            data[:,t,:] = errors[:,t,:]
        else:
            data[:,t,:] = np.matmul(errors[:,t-1,:],A)+errors[:,t,:]
    return data

def attributes(shape,n_cat,probs):
    N,A = shape
    vals = list(range(n_cat))
    distr = rv_discrete(a=0,b=n_cat-1,values=(vals,probs))
    attr = distr.rvs(size=(N,A))
    return attr

data = attributes((100,5),5,[.2]*5)


### N^2 Solution

class Solution:
    def maxScoreSightseeingPair(self, A: List[int]) -> int:

        hash_table = []
        value = 0
        max_value = 0

        for item in range(1,len(A)):
            hash_table.append(item)

        for item in range(len(A)-1):
            for j in range(len(hash_table)):
                if max_value > A[item]+A[hash_table[j]]:
                    continue
                else:
                    value = A[item] + A[hash_table[j]] + item - hash_table[j]
                    max_value = max(max_value,value)
            hash_table.remove(item+1)

        return max_value

### 2N Solution

class Solution:
    def maxScoreSightseeingPair(self, A: List[int]) -> int:
        max_value = []
        max_value.append(0)
        max_pair = []
        max_pair.append(0)

        for i in range(1,len(A)):
            max_value.append(max(max_value[i-1],A[i-1] + (i-1)))

        score = 0

        for i in range(1,len(A)):
            score = max_value[i] + A[i] - i
            max_pair.append(max(score,max_pair[i-1]))

        return max(max_pair)


"""Module provider for Linode V4"""
import json
import logging
from argparse import ArgumentParser
from typing import List

import requests

from lexicon.exceptions import AuthenticationError
from lexicon.interfaces import Provider as BaseProvider

LOGGER = logging.getLogger(__name__)

class Provider(BaseProvider):
    """Provider class for Linode V4"""

    @staticmethod
    def get_nameservers() -> List[str]:
        return ["linode.com"]

    @staticmethod
    def configure_parser(parser: ArgumentParser) -> None:
        parser.add_argument("--auth-token", help="specify api key for authentication")

    def __init__(self, config):
        super(Provider, self).__init__(config)
        self.domain_id = None
        self.api_endpoint = "https://api.linode.com/v4/"

    def authenticate(self):
        self.domain_id = None
        payload = self._get(
            "domains", query_params={"filter": {"domain": self.domain.lower()}}
        )
        if payload["data"]:
            self.domain_id = payload["data"][0]["id"]
        else:
            raise AuthenticationError("Domain not found")

    def cleanup(self) -> None:
        pass

    def create_record(self, rtype, name, content):
        if not self.list_records(rtype, name, content):
            if name:
                name = self._relative_name(name).lower()

            self._post(
                f"domains/{self.domain_id}/records",
                data={"name": name, "type": rtype, "target": content, "ttl_sec": 0},
            )

        return True

    # List all records. Return an empty list if no records found
    # type, name and content are used to filter records.
    # If possible filter during the query, otherwise filter after response is received.
    def list_records(self, rtype=None, name=None, content=None):
        resources_url = f"domains/{self.domain_id}/records"

        if name:
            name = self._relative_name(name).lower()

        processed_records = []

        payload = self._get(resources_url)
        for page in range(1, payload["pages"] + 1, 1):
            if page > 1:
                payload = self._get(resources_url, query_params={"page": page})

            resource_list = payload["data"]
            if rtype:
                resource_list = [
                    resource for resource in resource_list if resource["type"] == rtype
                ]
            if name:
                resource_list = [
                    resource
                    for resource in resource_list
                    if self._relative_name(resource["name"]).lower() == name
                ]
            if content:
                resource_list = [
                    resource
                    for resource in resource_list
                    if resource["target"] == content
                ]

            for resource in resource_list:
                processed_records.append(
                    {
                        "id": resource["id"],
                        "type": resource["type"],
                        "name": self._full_name(resource["name"]).lower(),
                        "ttl": resource["ttl_sec"],
                        "content": resource["target"],
                    }
                )

        LOGGER.debug("list_records: %s", processed_records)
        return processed_records

    # Create or update a record.
    def update_record(self, identifier, rtype=None, name=None, content=None):
        if not identifier:
            resources = self.list_records(rtype, name, None)
            identifier = resources[0]["id"] if resources else None

        LOGGER.debug("update_record: %s", identifier)

        if name:
            name = self._relative_name(name).lower()

        url = f"domains/{self.domain_id}/records/{identifier}"
        self._put(
            url,
            data={
                "name": name.lower() if name else None,
                "type": rtype if rtype else None,
                "target": content if content else None,
            },
        )

        return True

    # Delete an existing record.
    # If record does not exist, do nothing.
    def delete_record(self, identifier=None, rtype=None, name=None, content=None):
        delete_resource_id = []
        if not identifier:
            resources = self.list_records(rtype, name, content)
            delete_resource_id = [resource["id"] for resource in resources]
        else:
            delete_resource_id.append(identifier)

        LOGGER.debug("delete_records: %s", delete_resource_id)

        for resource_id in delete_resource_id:
            self._delete(f"domains/{self.domain_id}/records/{resource_id}")

        return True

    # Helpers
    def _request(self, action="GET", url="", data=None, query_params=None):
        if data is None:
            data = {}
        if query_params is None:
            query_params = {}
        default_headers = {
            "Accept": "application/json",
            "Content-Type": "application/json",
            "Authorization": f"Bearer {self._get_provider_option('auth_token')}",
        }

        request_filter = query_params["filter"] if "filter" in query_params else None
        if request_filter is not None:
            default_headers["X-Filter"] = json.dumps(request_filter)
            del query_params["filter"]

        request_url = f"{self.api_endpoint}{url}"

        response = requests.request(
            action,
            request_url,
            params=query_params,
            data=json.dumps(data),
            headers=default_headers,
        )
        # if the request fails for any reason, throw an error.
        response.raise_for_status()
        if action == "DELETE":
            return ""
        result = response.json()
        return result


# project: p4
# submitter: kgschears@wisc.edu
# partner: none
# hours: 5
# Data: https://www.kaggle.com/datasets/equinxx/spotify-top-50-songs-in-2021
import pandas as pd
from flask import Flask, request, jsonify, Response
import re
import time
import matplotlib
# !!!!!!!
matplotlib.use('Agg') #very important for using matplotlib in the backend
#!!!!!!!

import matplotlib.pyplot as plt
from io import StringIO
# !!!!!!!
matplotlib.use('Agg') #very important for using matplotlib in the backend
#!!!!!!!

users={}
User_Count=0
Version_A=True
clicked_A=0
clicked_B=0
Version_B=None
data= pd.read_csv("main.csv")
app = Flask(__name__)
# df = pd.read_csv("main.csv")

@app.route('/')
def home():
    global User_Count
    global Version_A
    global clicked_A
    global clicked_B
    global Version_B
    User_Count+=1
    if Version_A and User_Count < 10 or User_Count > 10 and clicked_A > clicked_B:
        with open("index.html") as f:
            html = f.read()
    else:
        if not Version_B:
            new_html=""
            with open("index.html","r") as f:
                f.seek(0)
                old_html=f.readlines()
                new_html+="".join(old_html[:2])
                new_html+="\n \n"
                new_html+="".join(old_html[2:])
                Version_B = new_html
        html=Version_B
    Version_A= not Version_A #toggle boolean to switch to Version_B
    return Response(html,status=200)

# @app.route('/')
# def home():
#     global User_Count
#     global Version_A
#     global clicked_A
#     global clicked_B
#     User_Count+=1
#     if Version_A and User_Count < 10 or User_Count > 10 and clicked_A > clicked_B:
#         with open("index_Version_A.html") as f:
#             html = f.read()
#     else:
#         with open("index_Version_B.html") as f:
#             html = f.read()
#     Version_A= not Version_A #toggle boolean to switch to Version_B
#     return html

@app.route('/browse.html')
def browse():
    global data
    html="
Spotify Top 50 2021 Dataset
"
    html+=data.to_html()
    return Response(html,status=200)

@app.route('/browse.json')
def browse_json():
    global users
    global data
    # request.remote_addr a flask client variable that holds the clients IP address
    found= False
    if users.get(request.remote_addr):
        found=True
    if  not found or found and time.time()-users[request.remote_addr] > 60 :

        data_dict=data.to_dict("index")
        users[request.remote_addr]=time.time()
        return jsonify(data_dict)
    else:
        return Response(f"
Retry-After: {60-(time.time()-users[request.remote_addr])} seconds
",status=429, headers={"Retry-After": 60-(time.time()-users[request.remote_addr])})

@app.route('/donate.html')
def donate():
    global User_Count
    if User_Count < 10:
        global Version_A
        global clicked_A
        global clicked_B
        if not Version_A: # not Version_A means it is Version_A because boolean toggle at end of home() function!
            clicked_A+=1
        else:
            clicked_B+=1
    with open("donate.html") as f:
        html=f.read()
    return Response(html,status=200)

@app.route('/email', methods=["POST"])
def email():
    email = str(request.data, "utf-8")
    if re.match(r"^[a-zA-Z0-9]?[a-zA-Z0-9]*@{1}[a-zA-Z0-9]*\.com$", email): # 1
        with open("emails.txt", "a+") as f: # open file in append mode
            f.write(email + "\n") # 2
            f.seek(0)
            num_subscribed= len(f.readlines())
        return jsonify(f"thanks, you're subscriber number {num_subscribed}!")
    return jsonify("Enter vaild email or Will Smith will slap you in your sleep!") # 3

@app.route('/dashboard_1.svg', methods=["GET"])
def scatter_plot():
    fig, ax = plt.subplots(figsize=(5,5))
    global data
    args = request.args
    x_axis = args.get("x_axis")
    y_axis = args.get("y_axis")
    if x_axis and y_axis:
        x_ax=x_axis
        y_ax=y_axis
    else:
        # dancability vs acousticness  scatter plot
        x_ax="tempo"
        y_ax="acousticness"

    ax.scatter(x=data[x_ax], y=data[y_ax]) # same as data.plot.scatter(ax=ax, x=x_ax,y=y_ax)
    ax.set_xlabel(x_ax)
    ax.set_ylabel(y_ax)
    ax.spines['top'].set_visible(False)
    ax.spines['right'].set_visible(False)
    ax.set_title(f"{x_ax} vs {y_ax} Top 50 song 2021")
    f = StringIO()
    fig.savefig(f, format="svg")
    plt.close() # closes the most recent fig

    svg = f.getvalue()

    hdr = {"Content-Type": "image/svg+xml"}
    return Response(svg, headers=hdr)

@app.route('/dashboard_2.svg')
def hist_plot():
    global data
    # histogram of artists and the number of count in the top 50 song list
    fig, ax = plt.subplots(figsize=(7,7))
    data["artist_name"].hist(ax=ax, bins=35)
    plt.xticks(rotation = 90)
    ax.margins(x=0)
    ax.spines['top'].set_visible(False)
    ax.spines['right'].set_visible(False)
    ax.grid(False)
    ax.set_xlabel("Artist name")
    #----Need this block for every svg graph------
    f = StringIO()
    fig.savefig(f, format="svg", bbox_inches='tight',pad_inches = 0)
    plt.close() # closes the most recent fig
    svg = f.getvalue()
    hdr = {"Content-Type": "image/svg+xml"}
    #--------------------------------------------
    return Response(svg, headers=hdr)

if __name__ == '__main__':
    app.run(host="0.0.0.0", debug=True, threaded=False) # don't change this line!


import sys
from collections import deque

N = int(sys.stdin.readline())
tree = list([] for _ in range(N+1))
for i in range(N-1):
    x, y = map(int, sys.stdin.readline().split())
    tree[x].append(y)
    tree[y].append(x)
# print(tree)

def BFS(start):
    q = deque()
    q.append(start)
    visited = [0] * (N+1)
    visited[start] = 1
    while q:
        temp = int(q.popleft())
        for node in tree[temp]:
            if visited[node] == 0:
                visited[node] = 1
                result.append((node, temp))
                q.append(node)

result = list()
BFS(1)
# print(result)
result.sort()
for ans in result:
    print(ans[1])


"""

  Write a function that takes in a Binary Tree and returns a list of its branch
  sums ordered from leftmost branch sum to rightmost branch sum.

  A branch sum is the sum of all values in a Binary Tree branch. A Binary Tree
  branch is a path of nodes in a tree that starts at the root node and ends at
  any leaf node.

"""

import unittest

# This is the class of the input root. Do not edit it.
class BinaryTree:
    def __init__(self, value):
        self.value = value
        self.left = None
        self.right = None

def branchSums(root):
    branchSumList = []
    branchSumsHelper(root, branchSumList, 0)
    return branchSumList

def branchSumsHelper(root, branchSumList, runningSum):
    if root is None:
        return

    newRunningSum = runningSum + root.value

    if root.left == None and root.right == None:
        branchSumList.append(newRunningSum)
        return

    branchSumsHelper(root.left, branchSumList, newRunningSum)
    branchSumsHelper(root.right, branchSumList, newRunningSum)

# This file is initialized with a code version of this
# question's sample test case. Feel free to add, edit,
# or remove test cases in this file as you see fit!

class TestProgram(unittest.TestCase):
    def test_case_1(self):
        tree = BinaryTree(1).insert([2, 3, 4, 5, 6, 7, 8, 9, 10])
        self.assertEqual(branchSums(tree), [15, 16, 18, 10, 11])

class BinaryTree(BinaryTree):
    def insert(self, values, i=0):
        if i >= len(values):
            return
        queue = [self]
        while len(queue) > 0:
            current = queue.pop(0)
            if current.left is None:
                current.left = BinaryTree(values[i])
                break
            queue.append(current.left)
            if current.right is None:
                current.right = BinaryTree(values[i])
                break
            queue.append(current.right)
        self.insert(values, i + 1)
        return self

"""
Test Case 1
{
  "tree": {
    "nodes": [
      {"id": "1", "left": "2", "right": "3", "value": 1},
      {"id": "2", "left": "4", "right": "5", "value": 2},
      {"id": "3", "left": "6", "right": "7", "value": 3},
      {"id": "4", "left": "8", "right": "9", "value": 4},
      {"id": "5", "left": "10", "right": null, "value": 5},
      {"id": "6", "left": null, "right": null, "value": 6},
      {"id": "7", "left": null, "right": null, "value": 7},
      {"id": "8", "left": null, "right": null, "value": 8},
      {"id": "9", "left": null, "right": null, "value": 9},
      {"id": "10", "left": null, "right": null, "value": 10}
    ],
    "root": "1"
  }
}
Test Case 2
{
  "tree": {
    "nodes": [
      {"id": "1", "left": null, "right": null, "value": 1}
    ],
    "root": "1"
  }
}
Test Case 3
{
  "tree": {
    "nodes": [
      {"id": "1", "left": "2", "right": null, "value": 1},
      {"id": "2", "left": null, "right": null, "value": 2}
    ],
    "root": "1"
  }
}
Test Case 4
{
  "tree": {
    "nodes": [
      {"id": "1", "left": "2", "right": "3", "value": 1},
      {"id": "2", "left": null, "right": null, "value": 2},
      {"id": "3", "left": null, "right": null, "value": 3}
    ],
    "root": "1"
  }
}
Test Case 5
{
  "tree": {
    "nodes": [
      {"id": "1", "left": "2", "right": "3", "value": 1},
      {"id": "2", "left": "4", "right": "5", "value": 2},
      {"id": "3", "left": null, "right": null, "value": 3},
      {"id": "4", "left": null, "right": null, "value": 4},
      {"id": "5", "left": null, "right": null, "value": 5}
    ],
    "root": "1"
  }
}
Test Case 6
{
  "tree": {
    "nodes": [
      {"id": "1", "left": "2", "right": "3", "value": 1},
      {"id": "2", "left": "4", "right": "5", "value": 2},
      {"id": "3", "left": "6", "right": "7", "value": 3},
      {"id": "4", "left": "8", "right": "9", "value": 4},
      {"id": "5", "left": "10", "right": "1-2", "value": 5},
      {"id": "6", "left": "1-3", "right": "1-4", "value": 6},
      {"id": "7", "left": null, "right": null, "value": 7},
      {"id": "8", "left": null, "right": null, "value": 8},
      {"id": "9", "left": null, "right": null, "value": 9},
      {"id": "10", "left": null, "right": null, "value": 10},
      {"id": "1-2", "left": null, "right": null, "value": 1},
      {"id": "1-3", "left": null, "right": null, "value": 1},
      {"id": "1-4", "left": null, "right": null, "value": 1}
    ],
    "root": "1"
  }
}
Test Case 7
{
  "tree": {
    "nodes": [
      {"id": "0", "left": "1", "right": null, "value": 0},
      {"id": "1", "left": "10", "right": null, "value": 1},
      {"id": "10", "left": "100", "right": null, "value": 10},
      {"id": "100", "left": null, "right": null, "value": 100}
    ],
    "root": "0"
  }
}
Test Case 8
{
  "tree": {
    "nodes": [
      {"id": "0", "left": null, "right": "1", "value": 0},
      {"id": "1", "left": null, "right": "10", "value": 1},
      {"id": "10", "left": null, "right": "100", "value": 10},
      {"id": "100", "left": null, "right": null, "value": 100}
    ],
    "root": "0"
  }
}
Test Case 9
{
  "tree": {
    "nodes": [
      {"id": "0", "left": "9", "right": "1", "value": 0},
      {"id": "9", "left": null, "right": null, "value": 9},
      {"id": "1", "left": "15", "right": "10", "value": 1},
      {"id": "15", "left": null, "right": null, "value": 15},
      {"id": "10", "left": "100", "right": "200", "value": 10},
      {"id": "100", "left": null, "right": null, "value": 100},
      {"id": "200", "left": null, "right": null, "value": 200}
    ],
    "root": "0"
  }
}

Your Solutions

Run Code
Solution 1
Solution 2
Solution 3
# This is the class of the input root. Do not edit it.
class BinaryTree:
    def __init__(self, value):
        self.value = value
        self.left = None
        self.right = None

def branchSums(root):
    branchSumList = []
	branchSumsHelper(root, branchSumList, 0)
	return branchSumList

def branchSumsHelper(root, branchSumList, runningSum):
	if root is None:
		return

	newRunningSum = runningSum + root.value

	if root.left == None and root.right == None:
		branchSumList.append(newRunningSum)
		return

	branchSumsHelper(root.left, branchSumList, newRunningSum)
	branchSumsHelper(root.right, branchSumList, newRunningSum)

1
# This is the class of the input root. Do not edit it.
2
class BinaryTree:
3
    def __init__(self, value):
4
        self.value = value
5
        self.left = None
6
        self.right = None
7

8

9
def branchSums(root):
10
    branchSumList = []
11
    branchSumsHelper(root, branchSumList, 0)
12
    return branchSumList
13

14
def branchSumsHelper(root, branchSumList, runningSum):
15
    if root is None:
16
        return
17

18
    newRunningSum = runningSum + root.value
19

20
    if root.left == None and root.right == None:
21
        branchSumList.append(newRunningSum)
22
        return
23

24
    branchSumsHelper(root.left, branchSumList, newRunningSum)
25
    branchSumsHelper(root.right, branchSumList, newRunningSum)
26

27

28

Custom Output

Raw Output

Submit Code
Run or submit code when you're ready.

"""


import os
from time import ctime
import optparse

from pvg_common import pvg_config, acquireThread, acquireObject

if __name__ == '__main__':

    parser = optparse.OptionParser(usage='%prog [options] [argument]', version='%prog version 1.0')
    parser.add_option('-c', '--config', dest='config_file', metavar="CONFIG_FILE", help="The full path to the config file to open")

    (options, args) = parser.parse_args()

    configfile = options.config_file

    if configfile is None:
        print ('You need to specify the path to a config file')
        parser.print_help()
        exit(-1)

    try:
        option_file = pvg_config(configfile)
    except:
        print ('Problem with configuration file %s.' % configfile)
        exit(-1)

    monitorsData = option_file.getMonitorsData()
    print ( "Found %s monitors." % len(monitorsData) )

    for mn in monitorsData:
        m = monitorsData[mn]
        at = acquireObject(mn, m['source'], m['resolution'], m['mask_file'], m['track'], m['track_type'], m['dataFolder'])
        at.start()
        print ( "%s: Acquisition for monitor %s started." % ( ctime(), mn ))


import scrapy
from scrapy.http import FormRequest
from scrapy.http import Request
from datetime import datetime
from scrapy.selector import Selector
from dgut_spider.handlePic import handle

class GetClassCourseSpider(scrapy.Spider):
    name = 'ClassCourse'

    def __init__(self):
        self.getUrl = 'http://jwxt.dgut.edu.cn/jwweb/ZNPK/KBFB_ClassSel.aspx' # first
        self.vcodeUrl = 'http://jwxt.dgut.edu.cn/jwweb/sys/ValidateCode.aspx' # second
        self.postUrl = 'http://jwxt.dgut.edu.cn/jwweb/ZNPK/KBFB_ClassSel_rpt.aspx' # third
        self.CourseUrl = 'http://jwxt.dgut.edu.cn/jwweb/ZNPK/drawkbimg.aspx'
        self.findSessionId = None # to save the cookies

    def start_requests(self):
        request = scrapy.Request(self.getUrl,
                callback = self.downloadPic)
        yield request

    def downloadPic(self, response):
        # download the picture
        # find the session id
        self.findSessionId = response.headers.getlist('Set-Cookie')[0].decode().split(';')[0].split('=')
        request = scrapy.Request(self.vcodeUrl,
                cookies = {self.findSessionId[0]: self.findSessionId[1]},
                callback = self.getAndHandleYzm)
        yield request

    def getAndHandleYzm(self, response):
        yzm = handle(response.body)

        yield FormRequest(self.postUrl,
                formdata = {'Sel_XNXQ': '20151',
                            'Sel_XZBJ': '1101201201',
                            'txt_yzm': yzm,
                            'txtzxbj': '',
                            'type': '2'},
                headers = {
                    'Referer': self.getUrl,
                    'Cookies': self.findSessionId[0] + '=' + self.findSessionId[1]
                    },
                callback = self.parse
                )

    def parse(self, response):
        body = response.body.decode('gbk')
        num = body.find('alert')
        if num != -1:
            yield scrapy.Request(self.vcodeUrl+'?t='+'%.f' % (datetime.now().microsecond / 1000),
                    headers = {
                        'Referer': self.getUrl,
                        'Cookies': self.findSessionId[0] + '=' + self.findSessionId[1]
                        },
                    callback = self.getAndHandleYzm
                    )

        else:
            sel = Selector(text = body)
            # to find the src tag, find the url
            self.CourseUrl = sel.xpath('//img/@src').extract()[0]
            self.CourseUrl = 'http://jwxt.dgut.edu.cn/jwweb/ZNPK/' + self.CourseUrl

            headers = {#'Cookie': self.findSessionId[0] + '=' + self.findSessionId[1],
                'Referer': 'http://jwxt.dgut.edu.cn/jwweb/ZNPK/KBFB_ClassSel_rpt.aspx',
                   'User-Agert': 'Mozilla/5.0 (X11; Linux x86_64; rv:47.0) Gecko/20100101 Firefox/47.0'
                }
            request = Request(self.CourseUrl, headers = headers, callback = self.parseData
                    )
            yield request

    def parseData(self, response):
        with open('three.jpg', 'wb') as f:
            f.write(response.body)


class Archivo:
    def __init__(self,nombreArchivo,separador='-'):
        self.__archivo = nombreArchivo
        self.__separador = separador

    def leer(self):
        try:
            with open(self.__archivo, 'r', encoding="utf-8") as file:
                lista = []
                for line in file.readlines():
                    line = line[:-1].split(self.__separador)
                    lista.append(line)
                if len(lista) != 0:
                    return lista
                else:
                    print('No hay datos compadre')
                    return lista
        except IOError as io:
            print(f'Error: Operacion Incorrecta {io}  ')

    def buscar(self,buscado):
        resultado = []
        with open(self.__archivo, mode = 'r', encoding='utf-8') as file:
            for linea in file.readlines():
                if linea[:-1].split(self.__separador)[0].find(buscado) is not -1 :
                    resultado = linea[:-1].split(self.__separador)
        return resultado

   #  def buscarRol(self,buscado1,buscado2):
   #      resultado = []
   #      with open(self.__archivo,mode='r',encoding='utf-8') as file:
   #          for linea in file:
   #              registro = linea[:-1].split(self.__separador)
   #              if registro[1] == buscado1 and registro[2] == buscado2:
   #                  resultado = registro
   #      return resultado

    def escribir(self,datos):
        with open(self.__archivo, mode='a', encoding='UTF-8') as file:
            file.write(f'\n{datos}')

# class Archivo:
#    def __init__(self,ah,sg):
#       self.__ah = ah
#       self.__ah = sg

# with open(r'./DATOS/departamento.txt',mode='r',encoding='utf-8') as file:
#    print(file.readlines())
#f  = open(r'./DATOS/departamento.txt','r')
#print(f.readlines())
a = Archivo(r'./DATOS/administrativo.txt','|')
# #a.escribir('4|deparatamento de los pijudos')
b = a.buscar('1')
print(b)


from utils.testcase import TestCase
from player.serializers import RoomSerializer, RoomsSerializer

import sure

class SerializersTestCase(TestCase):
    def test_room_serializer(self):
        expected_result = {
            'name': 'a',
            'current_music': None,
            'shuffle': False,
            'can_adjust_volume': False,
            'count_left': 0,
            'time_left': 0,
            'current_time_left': 0,
            'playlist': [],
            'volume': 10,
            'token': self.r.token,
            'current_time_past': 0,
            'current_time_past_percent': 0,
            'listeners': 0,
        }

        dict(RoomSerializer(self.r).data).should.eql(expected_result)

    def test_rooms_serializer(self):
        expected_result = {
            'name': 'a',
            'current_music': None,
            'shuffle': False,
            'can_adjust_volume': False,
            'count_left': 0,
            'time_left': 0,
            'current_time_left': 0,
            'playlist': [],
            'volume': 10,
            'listeners': 0,
        }

        dict(RoomsSerializer(self.r).data).should.eql(expected_result)