from logging import warning, info

from overrides import overrides
import random
from typing import NamedTuple, List

from agents.utils.types import Transition

class AbstractReplayMemory:
    """
    Abstract class that describes basic API for Replay Memory
    """

    def __init__(self, capacity: int = 100_000):
        self.capacity = capacity

    def push(self, transition: NamedTuple):
        """
        Add transition to the replay memory.
        :param transition: transition performed by an agent, regularly: state, action, reward, next_state.
        """
        raise NotImplementedError("Push method should be implemented!")

    def sample(self, batch_size: int) -> List[NamedTuple]:
        """
        Sample batch of transitions from the replay memory.
        :param batch_size: size of batch
        :return: sampled batch of transitions
        """
        raise NotImplementedError("Sample method should be implemented!")

class ExperienceReplay(AbstractReplayMemory):
    """
    Simple Experience Replay memory.
    """

    def __init__(self, capacity: int = 100_000):
        super(ExperienceReplay, self).__init__(capacity=capacity)
        self.buffer = []
        self.position = 0

    @overrides
    def push(self, transition: NamedTuple):
        """
        Add transition to the replay memory.
        :param transition: transition performed by an agent, regularly: state, action, reward, next_state.
        """
        if len(self.buffer) < self.capacity:
            self.buffer.append(None)
        self.buffer[self.position] = transition
        self.position = (self.position + 1) % self.capacity

    @overrides
    def sample(self, batch_size: int) -> List[NamedTuple]:
        if len(self.buffer) < batch_size:
            raise ValueError(
                f"Can't sample batch of size {batch_size} from the buffer!\n"
                f"There are only {len(self.buffer)} elements in the buffer."
            )
        return random.sample(self.buffer, batch_size)

    def __len__(self):
        return len(self.buffer)

# TODO: create sum tree data structure
# TODO: continue creation of Prioritized Experience replay
class PrioritizedReplayMemory(AbstractReplayMemory):
    """
    Experience Replay memory that stores transitions with priorities and samples
    elements according to these priorities.
    """

    def __init__(
        self,
        capacity: int = 100_000,
        alpha: float = 0.6,
        beta_init: float = 0.4,
        beta_anneal_steps: int = 10000,
    ):
        super(PrioritizedReplayMemory, self).__init__(capacity=capacity)
        self.alpha_smoothing = alpha
        self.buffer = []
        self.beta_init = beta_init
        self.beta_anneal_steps = beta_anneal_steps
        self.beta_steps = 0

    @overrides
    def push(self, transition: NamedTuple):
        pass

    @overrides
    def sample(self, batch_size: int) -> List[NamedTuple]:
        pass

    def _beta_by_step(self, step: int):
        beta_ang = (1 - self.beta_init) / self.beta_anneal_steps
        beta = beta_ang * step + self.beta_init
        return min(beta, 1.0)

    def __len__(self):
        return len(self.buffer)

class BinaryPrioritizeReplayMemory(AbstractReplayMemory):
    def __init__(self, capacity: int = 100_000, priority_fraction: float = 0.0):
        super(BinaryPrioritizeReplayMemory, self).__init__(capacity=capacity)
        self.prior_buffer = []
        self.prior_position = 0
        self.prior_capacity = int(self.capacity * priority_fraction)
        self.secondary_buffer = []
        self.secondary_position = 0
        self.secondary_capacity = self.capacity - self.prior_capacity
        self.priority_fraction = priority_fraction

    def push(self, transition: NamedTuple, is_prior: bool = False):
        if self.priority_fraction == 0.0:
            is_prior = False
        if is_prior:
            self.prior_position = self._push(
                transition, self.prior_buffer, self.prior_position
            )
        else:
            self.secondary_position = self._push(
                transition, self.secondary_buffer, self.secondary_position
            )

    def _push(self, transition: Transition, buffer, position):
        if len(buffer) < self.prior_capacity:
            buffer.append(None)
        buffer[position] = transition
        position = (position + 1) % self.prior_capacity
        return position

    def sample(self, batch_size: int) -> List[NamedTuple]:
        if self.priority_fraction == 0.0:
            samples = random.sample(self.secondary_buffer, batch_size)
        else:
            prior_size = min(
                int(batch_size * self.priority_fraction), len(self.prior_buffer)
            )
            secondary_size = min(batch_size - prior_size, len(self.secondary_buffer))
            prior_samples = random.sample(self.prior_buffer, prior_size)
            secondary_samples = random.sample(self.secondary_buffer, secondary_size)
            samples = prior_samples + secondary_samples
            # random.shuffle(samples)
            if len(samples) != batch_size:
                warning(
                    f"Not enough elements in buffer: {len(prior_samples), len(secondary_samples)}"
                )

        # if len(self.secondary_buffer) < batch_size:
        #     raise ValueError(
        #         f"Can't sample batch of size {batch_size} from the buffer!\n"
        #         f"There are only {len(self.secondary_buffer)} elements in the buffer."
        #     )
        return samples

    def __len__(self) -> int:
        return len(self.prior_buffer) + len(self.secondary_buffer)

    def get_len_prior(self) -> int:
        return len(self.prior_buffer)

    def get_len_secondary(self) -> int:
        return len(self.secondary_buffer)

class SeqTernaryPrioritizeReplayMemory(AbstractReplayMemory):
    def __init__(
        self,
        capacity: int = 100_000,
        good_samples_fraction: float = 0.0,
        bad_samples_fraction: float = 0.0,
    ):
        super().__init__(capacity=capacity)
        self.good_samples_fraction = good_samples_fraction
        self.bad_samples_fraction = bad_samples_fraction
        self.good_seqs_buffer = []
        self.good_buffer_position = 0
        self.bad_seqs_buffer = []
        self.bad_buffer_position = 0
        self.neutral_seqs_buffer = []
        self.neutral_buffer_position = 0
        self.good_samples_capacity = int(self.capacity * self.good_samples_fraction)
        self.bad_samples_capacity = int(self.capacity * self.bad_samples_fraction)
        self.secondary_capacity = (
            self.capacity - self.good_samples_capacity - self.bad_samples_capacity
        )

    def push(self, transitions: List[Transition]):
        is_good = False
        is_bad = False
        for transition in transitions:
            if transition.reward > 0.5:
                is_good = True
            elif transition.reward < -0.5:
                is_bad = True
        if is_good:
            self.good_buffer_position = self._push(
                transitions=transitions,
                position=self.good_buffer_position,
                buffer=self.good_seqs_buffer,
                capacity=self.good_samples_capacity,
            )
        if is_bad:
            self.bad_buffer_position = self._push(
                transitions=transitions,
                position=self.bad_buffer_position,
                buffer=self.bad_seqs_buffer,
                capacity=self.bad_samples_capacity,
            )
        if not is_good and not is_bad:
            self.neutral_buffer_position = self._push(
                transitions=transitions,
                position=self.neutral_buffer_position,
                buffer=self.neutral_seqs_buffer,
                capacity=self.secondary_capacity,
            )

    def _push(self, transitions, buffer, position, capacity):
        if len(buffer) < capacity:
            buffer.append(None)
        buffer[position] = transitions
        return (position + 1) % capacity

    def sample(self, batch_size: int):
        if self.good_samples_fraction == 0.0:
            batch_size = min(batch_size, len(self.neutral_seqs_buffer))
            return random.sample(self.neutral_seqs_buffer, batch_size)
        else:
            good_size = min(
                int(self.good_samples_fraction * batch_size), len(self.good_seqs_buffer)
            )
            bad_size = min(
                int(self.bad_samples_fraction * batch_size), len(self.bad_seqs_buffer)
            )
            secondary_size = min(
                batch_size - bad_size - good_size, len(self.neutral_seqs_buffer)
            )
            pos_prior_samples = random.sample(self.good_seqs_buffer, good_size)
            neg_prior_samples = random.sample(self.bad_seqs_buffer, bad_size)
            secondary_samples = random.sample(self.neutral_seqs_buffer, secondary_size)
            samples = pos_prior_samples + neg_prior_samples + secondary_samples
            info(
                f"Good samples: {len(pos_prior_samples)}; bad samples: {len(neg_prior_samples)} rest samples: {len(secondary_samples)}"
            )
            return samples

class TernaryPrioritizeReplayMemory(AbstractReplayMemory):
    def __init__(self, capacity: int = 100_000, priority_fraction: float = 0.0):
        super(TernaryPrioritizeReplayMemory, self).__init__(capacity=capacity)
        self.priority_fraction = priority_fraction
        self.pos_prior_buffer = []
        self.pos_prior_position = 0
        self.neg_prior_buffer = []
        self.neg_prior_position = 0
        self.prior_capacity = int(self.capacity * self.priority_fraction) // 2
        self.secondary_buffer = []
        self.secondary_position = 0
        self.secondary_capacity = self.capacity - 2 * self.prior_capacity

    def push(self, transition: NamedTuple):
        if self.priority_fraction == 0.0:
            is_prior = False
        else:
            is_prior = transition.reward != 0.0
        if is_prior:
            self._push_prior(transition)
        else:
            self._push_secondary(transition)

    def sample(self, batch_size: int):
        if self.priority_fraction == 0.0:
            batch_size = min(batch_size, len(self.secondary_buffer))
            return random.sample(self.secondary_buffer, batch_size)
        else:
            prior_size = min(
                int(batch_size * self.priority_fraction) // 2,
                min(len(self.pos_prior_buffer), len(self.neg_prior_buffer)),
            )
            secondary_size = min(batch_size - prior_size, len(self.secondary_buffer))
            pos_prior_samples = random.sample(self.pos_prior_buffer, prior_size)
            neg_prior_samples = random.sample(self.neg_prior_buffer, prior_size)
            secondary_samples = random.sample(self.secondary_buffer, secondary_size)
            samples = pos_prior_samples + neg_prior_samples + secondary_samples
            return samples

    def _push_prior(self, transition: NamedTuple):
        if transition.reward > 0.0:
            if len(self.pos_prior_buffer) < self.prior_capacity:
                self.pos_prior_buffer.append(None)
            self.pos_prior_buffer[self.pos_prior_position] = transition
            self.pos_prior_position = (
                self.pos_prior_position + 1
            ) % self.prior_capacity
        else:
            if len(self.neg_prior_buffer) < self.prior_capacity:
                self.neg_prior_buffer.append(None)
            self.neg_prior_buffer[self.neg_prior_position] = transition
            self.neg_prior_position = (
                self.neg_prior_position + 1
            ) % self.prior_capacity

    def _push_secondary(self, transition: NamedTuple):
        if len(self.secondary_buffer) < self.secondary_capacity:
            self.secondary_buffer.append(None)
        self.secondary_buffer[self.secondary_position] = transition
        self.secondary_position = (
            self.secondary_position + 1
        ) % self.secondary_capacity

    def __len__(self) -> int:
        return (
            len(self.pos_prior_buffer)
            + len(self.neg_prior_buffer)
            + len(self.secondary_buffer)
        )

    def get_size(self) -> int:
        return len(self)

    def get_len_prior(self) -> int:
        return len(self.pos_prior_buffer) + len(self.neg_prior_buffer)

    def get_len_secondary(self) -> int:
        return len(self.secondary_buffer)


"""
    Код должен парсить элементы с сайта, который получает HTML шаблон с сервера, реализованный
с помощью JavaScript.

    Используется библиотека Selenium, предназначенная для автоматизации действий в веб-браузере,
а также для выполнения рутинных задач и тестирования Web-приложений
    (Установка Selenium: pip3 install selenium)

    Для работы с данной библиотекой используется WebDriver, необходимый для эмуляции обычного браузера,
который будет управляться через Selenium.
    (Мой браузер - Chrome, поэтому я устанавливаю ChromeDriver - https://chromedriver.chromium.org/downloads)
    Версия Chrome должна совпадать с версией ChromeDriver.
"""

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By

s = Service("D:\\Education\\Web\\untitled9\\chromedriver.exe")

def existence_check(num, path_elem):
    try:
        driver.find_element(By.XPATH, path_elem + "tr[%s]/td[2]" % (num + 1))
        return True
    except:
        return False

def collection_results():
    path_elem = "/html[@class='ru detect_flexbox']" \
                "/body[@class='inner-page ranged-list']" \
                "/div[@class='layout']/div[@class='wrapper']" \
                "/div[@id='js-content']/div[@class='wide']" \
                "/div[@class='data-table-container mCustomScrollbar _mCS_1']" \
                "/div[@id='mCSB_1']/div[@id='mCSB_1_container']" \
                "/div[@class='table-container']/table[@class='data with-hover sortable js-fixed js-table-data']" \
                "/tbody/"
    num = 0
    reg_numbers = list()
    sum_points = list()
    accept = list()
    orig = list()

    while existence_check(num, path_elem):
        reg_numbers.append(driver.find_element(By.XPATH, path_elem + "tr[%s]/td[2]" % (num + 1)).text)
        sum_points.append(driver.find_element(By.XPATH, path_elem + "tr[%s]/td[4]" % (num + 1)).text)
        accept.append(driver.find_element(By.XPATH, path_elem + "tr[%s]/td[7]" % (num + 1)).text)
        orig.append(driver.find_element(By.XPATH, path_elem + "tr[%s]/td[8]" % (num + 1)).text)
        num = num + 1

    dic = {}
    for i in range(len(reg_numbers)):
        if accept[i] == "+" and orig[i] == "+":
            dic[reg_numbers[i]] = sum_points[i]

    return dic

def print_result(dic):
    i = 0
    print("---Проходят на бюджет:---")
    for key,value in dic.items():
        i += 1
        if i > count_budget_places:
            break
        else:
            print(str(i) + ". " + key + " " + value)

    print("Количество непрошедших: " + str(len(dic) - count_budget_places))

def main():
    global count_budget_places, driver
    url = input("Ссылка на ранжированный список: ")

    try:
        driver = webdriver.Chrome(service=s)
        driver.get(url=url)
        print(driver.find_element(By.XPATH, "/html[@class='ru detect_flexbox']/body[@class='inner-page ranged-list']"
                                            "/div[@class='layout']/div[@class='wrapper']/div[@id='js-content']/div[@class='col-sm-4 col-md-2']/div[@class='data data-indent'][2]/div[@class='row'][3]/div[@class='col-md-2 col-sm-2 col-xs-4'][2]/direction").text)
        count_budget_places = int(driver.find_element(By.XPATH, "/html[@class='ru detect_flexbox']"
                                                        "/body[@class='inner-page ranged-list']"
                                                        "/div[@class='layout']/div[@class='wrapper']/div[@id='js-content']"
                                                        "/div[@class='col-sm-4 col-md-2']/div[@class='data data-indent'][2]"
                                                        "/div[@class='row'][1]/div[@class='col-md-2 col-sm-2 col-xs-4'][2]").text)
    finally:
        print_result(collection_results())
        driver.close()
        driver.quit()

main()


import numpy as np
from math import fabs
from vec3 import *

class Box:
    def __init__(self, p1, p2):
        self.p1 = p1
        self.p2 = p2

        self.rectangles = [
            Rectangle(
                vec3(p1.x, p2.y, p1.z),
                vec3(p2.x, p1.y, p1.z)
            ),

            Rectangle(
                vec3(p1.x, p2.y, p2.z),
                vec3(p1.x, p1.y, p1.z)
            ),

            Rectangle(
                vec3(p1.x, p1.y, p1.z),
                vec3(p2.x, p1.y, p2.z)
            ),

            Rectangle(
                vec3(p1.x, p2.y, p2.z),
                vec3(p2.x, p1.y, p2.z)
            ),

            Rectangle(
                vec3(p2.x, p2.y, p2.z),
                vec3(p2.x, p1.y, p1.z)
            ),

            Rectangle(
                vec3(p1.x, p2.y, p1.z),
                vec3(p2.x, p2.y, p2.z)
            )
        ]

    def get2DRectangles(self, n, p):
        return [rect.get2D(n, p) for rect in self.rectangles]

    def isInBox(self, p):
        if p.x < min(self.p1.x, self.p2.x) or p.x > max(self.p1.x, self.p2.x):
            return False
        if p.y < min(self.p1.y, self.p2.y) or p.y > max(self.p1.y, self.p2.y):
            return False
        if p.z < min(self.p1.z, self.p2.z) or p.z > max(self.p1.z, self.p2.z):
            return False
        return True

class Rectangle:
    def __init__(self, p1, p2):
        self.p1 = p1
        self.p2 = p2

    def get2D(self, n, p):
        p1 = project3D_on_2D(self.p1, n, p)
        p2 = project3D_on_2D(self.p2, n, p)
        return (p1.x, p1.y, fabs(p2.x-p1.x), fabs(p2.y-p1.y))

def project3D_on_2D(point3D, n, p):
    v = point3D-p
    perp_dist = v.dot(n)
    projected = point3D-perp_dist*n
    x = int(projected.x)
    y = int(projected.y)
    return vec3(x, y, 0)  # or just use projected if no integer casting

def almost_equal_pos(p1, p2, delta=5):
    # p1 = project3D_on_2D(p1, vec3(0, 0, 1), vec3(0, 0, 0))
    # p1 = vec3(p1.x, p1.y, 0)
    # p2 = project3D_on_2D(p2, vec3(0, 0, 1), vec3(0, 0, 0))
    # p2 = vec3(p2.x, p2.y, 0)
    if fabs(p1.x-p2.x) > delta:
        return False
    if fabs(p1.y-p2.y) > delta:
        return False
    if fabs(p1.z-p2.z) > delta:
        return False
    return True


# Make a paired circles and squares toy dataset for multimodal encoding
# In this example dataset : on of the modalities have a random color grey background dataset that is modality specific information :
# The circles all have the same size and the shared information is the shape

import os

import numpy as np
from PIL import Image
import torch
from sklearn.model_selection import train_test_split

dataset_size = 5000
size_image = 32
min_background, max_background = 5, 250
min_pertub, max_pertub = 0,0.3
rayon = r = 0.5
circle_thickness = 0.2
output_path = '../data/empty_full_bk'
if not os.path.exists(output_path):
    os.mkdir(output_path)

x = np.linspace(-1,1,size_image)

def circle(X,Y):
    c = np.random.uniform(-max_pertub, max_pertub, 2)
    shape = ((X-c[0])**2 + (Y-c[1])**2 <= (r + circle_thickness/2)**2)*((X-c[0])**2 + (Y-c[1])**2 >= (r - circle_thickness/2)**2)
    bk_color = np.random.randint(min_background, max_background)/255
    bk = (1-shape)*bk_color
    return shape + bk, bk_color

def square_line(X,Y):
    c = np.random.uniform(-max_pertub, max_pertub, 2)
    shape = (np.abs(X-c[0]) + np.abs(Y-c[1]) <= (r + circle_thickness/2))*(np.abs(X-c[0]) + np.abs(Y-c[1]) >= r - circle_thickness/2)
    bk_color = np.random.randint(min_background, max_background)/255
    bk = (1-shape)*bk_color
    return shape + bk, bk_color

empty, background , full = [], [], []

labels = []

for i in range(dataset_size):
    X, Y = np.meshgrid(x, x)
    # Add a circle pair to the dataset
    c, bkc = circle(X,Y)
    empty.append(c)
    background.append(bkc)
    full.append(X**2 + Y**2 <= r**2)
    # And then a square one
    c, bkc = square_line(X, Y)
    empty.append(c)
    background.append(bkc)
    full.append(np.abs(X) + np.abs(Y) <= r)
    labels.extend([0,1])

# Visualize some examples
output_examples = output_path + '/examples'
if not os.path.exists(output_examples):
    os.mkdir(output_examples)

for i in np.linspace(0,dataset_size-1, 100):
    i = int(i)
    img = Image.fromarray(np.uint8(np.concatenate([empty[i]*255, full[i]*255])))
    img.save(output_examples + f'/example_{i}.png')

# Save in pytorch format
empty = torch.unsqueeze(torch.FloatTensor(empty), 1)
full = torch.unsqueeze(torch.FloatTensor(full), 1)
labels, background = torch.tensor(labels),torch.tensor(background)
# Select some for training and testing
s_train, s_test, c_train, c_test, idx_train, idx_test = train_test_split(empty,full, np.arange(len(labels)), test_size=0.3)

torch.save(s_train, output_path + '/squares_train.pt')
torch.save(s_test, output_path + '/squares_test.pt')
torch.save(c_train, output_path + '/circles_train.pt')
torch.save(c_test, output_path + '/circles_test.pt')
torch.save(labels[idx_train], output_path+ '/labels_train.pt')
torch.save(labels[idx_test], output_path + '/labels_test.pt')
torch.save(background[idx_train], output_path + '/r_squares_train.pt')
torch.save(background[idx_test], output_path + '/r_squares_test.pt')
torch.save(background[idx_train], output_path +'/r_circles_train.pt')
torch.save(background[idx_test], output_path +'/r_circles_test.pt')

print(c_train.shape, c_test.shape)


from django.conf import settings
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path("admin/", admin.site.urls),
    path("accounts/", include("allauth.urls")),
    path("pages/", include("pages.urls")),
    path("", include("articles.urls")),
    path("character/", include("dnd_character.urls")),
    path("fediverse/", include("fediverse.urls")),
    path("calculator/", include("calculator.urls")),
    path("tasks/", include("htmx_tasks.urls")),
]

if settings.DEBUG:
    import debug_toolbar
    from django.conf.urls.static import static

    urlpatterns = [
        path("__debug__/", include(debug_toolbar.urls)),
    ] + urlpatterns

    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)


from __future__ import absolute_import, division, print_function

import os
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt

offline = not "DISPLAY" in os.environ

chart_count = 0
def show():
  global chart_count
  if offline:
    plt.savefig('charts/plot-{}.png'.format(chart_count))
    chart_count += 1
  else:
    plt.show()
  # Clear the current axes.
  plt.cla()
  # Clear the current figure.
  plt.clf()
  # Closes all the figure windows.
  plt.close('all')

if offline:
  mpl.use("Agg")

def plot_loss(subplot, epochs, history, test_loss = None):
  plot_metric('loss', 'Loss', subplot, epochs, history, test_loss)

def plot_acc(subplot, epochs, history, test_metric = None):
  plot_metric('acc', 'Accuracy', subplot, epochs, history, test_metric)

def plot_mae(subplot, epochs, history, test_metric = None):
  plot_metric('mean_absolute_error', 'Mean Abs Err', subplot, epochs, history, test_metric)

def plot_metric(metric, metric_name, subplot, epochs, history, test_metric = None):
  val_acc = subplot.plot(epochs, history['val_{}'.format(metric)], '--', label='Val {}'.format(metric_name))
  subplot.plot(epochs, history[metric], color=val_acc[0].get_color(), label='Train {}'.format(metric_name))
  if test_metric:
    subplot.plot(epochs, [test_acc] * len(epochs), label='Test {}'.format(metric_name))
  subplot.set_xlabel('Epochs')
  #subplot.set_yscale('log')
  subplot.set_ylabel(metric_name)
  subplot.set_xlim([0, max(epochs)])

def print_run(
    train_input, train_target, train_predict, test_input, test_target, test_predict, epoch, history):
  plt.figure(figsize=(12, 8))

  splt = plt.subplot(2, 4, 1)
  splt.imshow(train_input.astype("float32"))
  splt = plt.subplot(2, 4, 2)
  splt.imshow(train_target.astype("float32"))
  splt = plt.subplot(2, 4, 3)
  splt.imshow(train_predict.astype("float32"))

  plot_loss(plt.subplot(2, 4, 4), list(range(epoch + 1)), history)

  splt = plt.subplot(2, 4, 5)
  splt.imshow(test_input.astype("float32"))
  splt = plt.subplot(2, 4, 6)
  splt.imshow(test_target.astype("float32"))
  splt = plt.subplot(2, 4, 7)
  splt.imshow(test_predict.astype("float32"))

  if "acc" in history:
    plot_acc(plt.subplot(2, 4, 8), list(range(epoch + 1)), history)
  else:
    plot_mae(plt.subplot(2, 4, 8), list(range(epoch + 1)), history)
  plt.tight_layout()
  show()

def print_end(history, test_loss, test_acc):
  plt.figure(figsize=(12, 8))
  plot_loss(plt.subplot(1, 2, 1), history.epoch, history.history, test_loss)
  plot_acc(plt.subplot(1, 2, 2), history.epoch, history.history, test_acc)
  #plt.legend()
  show()


import torchvision
import torchvision.transforms as transforms
from torch.utils.data import DataLoader

import movie_poster

import pandas as pd
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as plt

data_dir = "datas"
img_dir = f"{data_dir}/images"

batch_size = 32
test_size = 0.15

all_dataset = pd.read_csv(f"{data_dir}/all_data.csv")
train_set, test_set = train_test_split(all_dataset, test_size=0.15)

pd.DataFrame(train_set).to_csv(f"{data_dir}/train_data.csv", header=True, index=False)
pd.DataFrame(test_set).to_csv(f"{data_dir}/test_data.csv", header=True, index=False)

test_set_fpath = f"{data_dir}/test_data.csv"

test_transform = transforms.Compose(
    [
        transforms.ToPILImage(),
        transforms.Resize((200, 200)),
        transforms.ToTensor(),
    ]
)

test_dataset = movie_poster.Dataset(test_set_fpath, img_dir, test_transform)
test_dataloader = DataLoader(test_dataset, batch_size=4, shuffle=True)

images, labels = next(iter(test_dataloader))
output = torchvision.utils.make_grid(images)
print("labels", labels)

def imshow(inp):
    inp = inp.transpose((1, 2, 0))
    plt.imshow(inp)

# imshow(output.numpy())
# plt.show()

print("Done")


from collections import defaultdict

class Solution:
    def minWindow(self, s: str, t: str) -> str:
        l, r = 0, 0
        min_window = [-1, len(s) + 1]

        t_freq = defaultdict(int)
        s_freq = defaultdict(int)

        for char in t: t_freq[char] += 1
        need = len(t_freq.keys())
        have = 0

        while r < len(s):
            char = s[r]
            s_freq[char] += 1

            if char in t_freq and s_freq[char] == t_freq[char]:
                have += 1

            while have == need:
                if (r - l + 1) < min_window[1]: min_window = [l, (r - l + 1)]

                s_freq[s[l]] -= 1
                if s[l] in t_freq and s_freq[s[l]] < t_freq[s[l]]:
                    have -= 1
                l += 1
            r += 1

        if min_window[0] == -1: return ""
        return s[min_window[0]:min_window[0] + min_window[1]]

s = Solution()
print(s.minWindow("aab", "aab"))


import random

quiz = {
    "Music":
        [
        {"Who sang the song 'Hit me baby'? ": ["Adele Kinobi", "Nick June", "Haley Smith"]},
        {"Who sang the song 'Love my baby'? ": ["Adele Kinobi", "Nick June", "Haley Smith", "Nikita"]},
        {"Who sang the song 'How are you'? ": ["Adele Kinobi", "Nick June", "Haley Smith", "Bob Sheeran"]}
        ]

      }

while (exit != "1"):
    level = 0
    genre = input(" Which quiz do you want to take? ")
    print(quiz.get("Music"))

    exit = input("Press 1 to exit or any other key to continue?  ")


import re
m = re.match('[a-z]+', 'Python')
print(m)
print(re.search('apple','I like apple!'))

p = re.compile('[a-z]+') # 알파벳 소문자
m = p.match('python')
print(m)
print(p.search('I like apple 123'))

print('---------------------정규 표현식--------------------')
from urllib.request import urlopen
from bs4 import BeautifulSoup
import re
html = urlopen('http://www.pythonscraping.com/pages/page3.html')
soup = BeautifulSoup(html, 'html.parser')
# 정규식: ('img.*\.jpg'): img 다음에 임의의 한 문자가 0회 이상: img.jpg, img1.jpg, imga.jpg 등
img_tag = re.compile('/img/gifts/img.*.jpg')
# find_all()에서 img의 src 속성값에 정규식 사용
images = soup.find_all('img', {'src': img_tag})

for image in images:
    print(image, end=" -> ['src'] 속성: ")
    print(image['src'])


from flask import Flask, jsonify, request

app = Flask(__name__)
accounts = [
    {"id": 1, "name": "John", "balance": 123.0},
    {"id": 2, "name": "Steve", "balance": 234.0},
]

@app.route("/")
def hello_word():
    return "Hello World"

@app.route("/accounts", methods=["GET"])
def get_accounts():
    return jsonify(accounts)

@app.route("/accounts/<account_id>", methods=["GET"])
def get_account(account_id):
    for acct in accounts:
        if acct.get("id", None) == int(account_id):
            return jsonify(acct)
    return {}

@app.route("/account", methods=["POST"])
def add_account():
    name = request.json["name"]
    balance = request.json["balance"]
    account_id = len(accounts) + 1
    data = {"id": account_id, "name": name, "balance": round(float(balance), 1)}
    accounts.append(data)

if __name__ == "__main__":
    app.run(port=8080)


from Rule import Setting
from Rule import Player
from Card import Card
import random

class Board:
    def __init__(self, number_of_players):
        self.number_of_players = number_of_players
        self.number_of_playingCards = 80

        self.deck = []
        self.players = []
        self.trashCan = []

        self.whoseTurn = 0
        self.phase = '2'

        # shuffle deck
        for idx, card in enumerate(Setting.PLAYING_CARD):
            self.deck.append(Card(card[0], card[1], card[2], card[3], idx))
        random.shuffle(self.deck)

        # init player, draw cards
        random.shuffle(Setting.NUMBER_OF_ROLE[self.number_of_players])
        for player_number in range(self.number_of_players):
            init_role = Setting.NUMBER_OF_ROLE[self.number_of_players][player_number]
            init_bullets = 4 + (init_role == 'Sheriff')  # 보안관은 bullets + 1

            self.players.append(Player.Player(player_number, init_bullets, init_role, None, self.deck[-init_bullets:]))
            del self.deck[-init_bullets:]


#!/usr/bin/env python
# coding: utf-8

# #  Simple tool to analyze data from www.data.gouv.fr
#
# **Note:** This is a Jupyter notebook which is also available as its executable export as a Python 3 script (therefore with automatically generated comments).

# # Libraries

# In[ ]:

import sys,os
addPath= [os.path.abspath("../source"),
          os.path.abspath("../venv/lib/python3.9/site-packages/")]
addPath.extend(sys.path)
sys.path = addPath

# In[ ]:

# Sys import
import sys, os, re
# Common imports
import math
import numpy             as NP
import numpy.random      as RAND
import scipy.stats       as STATS
from scipy import sparse
from scipy import linalg

# Better formatting functions
from IPython.display import display, HTML
from IPython import get_ipython

import matplotlib        as MPL
import matplotlib.pyplot as PLT
import seaborn as SNS
SNS.set(font_scale=1)

# Python programming
from itertools import cycle
from time import time
import datetime

# Using pandas
import pandas as PAN
import xlrd

# In[ ]:

import warnings
warnings.filterwarnings('ignore')
print("For now, reduce python warnings, I will look into this later")

# ### Import my own modules
# The next cell attempts to give user some information if things improperly setup.
# Intended to work both in Jupyter and when executing the Python file directly.

# In[ ]:

if not get_ipython() is None and os.path.abspath("../source/") not in sys.path:
    sys.path.append(os.path.abspath("../source/"))
try:
    from lib.utilities     import *
    from lib.figureHelpers import *
    from lib.DataMgrJSON   import *
    from lib.DataMgr       import *
    import lib.basicDataCTE as DCTE
except Exception as err:
    print("Could not find library 'lib' with contents 'DataGouvFr' ")
    if get_ipython() is None:
        print("Check the PYTHONPATH environment variable which should point to 'source' wich contains 'lib'")
    else:
        print("You are supposed to be running in JupySessions, and '../source/lib' should exist")
    raise err

# ## Check environment
#
# It is expected that:
# - your working directory is named `JupySessions`,
# - that it has subdirectories
#    - `images/*` where generated images may be stored to avoid overcrowding.
# - At the same level as your working dir there should be directories
#    - `../data` for storing input data and
#    - `../source` for python scripts.
#
# My package library is in `../source/lib`, and users running under Python (not in Jupyter) should
# set their PYTHONPATH to include "../source" ( *or whatever appropriate* ).

# In[ ]:

checkSetup(chap="Chap01")
ImgMgr = ImageMgr(chapdir="Chap01")

# # Load Data

# Vaccination data: https://www.data.gouv.fr/en/datasets/donnees-relatives-aux-personnes-vaccinees-contre-la-covid-19/
# https://www.data.gouv.fr/en/datasets/r/eb672d49-7cc7-4114-a5a1-fa6fd147406b
# https://www.data.gouv.fr/en/datasets/r/eb672d49-7cc7-4114-a5a1-fa6fd147406b
# https://www.data.gouv.fr/en/datasets/r/b234a041-b5ea-4954-889b-67e64a25ce0d
#
# Badges: vaccins covid19 (sans tiret???)

# ## Functions

# ## Load CSV and XLSX data from remote
# The `dataFileVMgr` will manage a cache of data files in `../data`, the data will be downloaded
# from www.data.gouv.fr using a request for datasets with badge '`covid-19`' if a more recent
# version is present on the remote site. The meta information is stored/cached  in `../data/.data`
# as the pickle of a json.
#
# We check what is in the cache/data directory; for each file, we identify the latest version,
# and list this below to make sure. The file name will usually contain a time stamp; this has to do with
# the version management/identification technique used when downloading from www.data.gouv.fr.
#
# For the files used in this notebook, the latest version is used/loaded irrespective of the
# timestamp used in the notebook.

# In[ ]:

tagset1 = ({"tag":"covid"}, {"tag":"covid19"})

# In[ ]:

specOpts={ 'cacheFname': '.cache.rqtTest2.json',
           "dumpMetaFile" : "rqtTest2.meta.dump",
           "dumpMetaInfoFile" : "rqtTest2.metainfo.dump",
           'ApiInq'       : 'datasets',
           'ApiInqQuery'  : tagset1,
           'InqParmsDir'  : {},
          }

# In[ ]:

rex = re.compile('(.*sursaud|^donnees-hospitalieres|^covid-hospit-incid|^sp-pos-).*')
def uselFn(urqt):
                return rex.match(urqt.fname) or rex.match(urqt.url)

# In[ ]:

dataFileVMgr = manageAndCacheDataFilesFRAPI("../data", maxDirSz= 170*(2**10)**2,
                                            **specOpts)

# In[ ]:

dataFileVMgr.getRemoteInfo()
dataFileVMgr.updatePrepare()
dataFileVMgr.updateSelect(displayCount=10 ,  URqtSelector = uselFn)
dataFileVMgr.cacheUpdate()

# In[ ]:

print("Most recent versions of files in data directory:")
for f in dataFileVMgr.listMostRecent() :
    print(f"\t{f}")

# In[ ]:

last = lambda x: dataFileVMgr.getRecentVersion(x,default=True)

# This ensures we load the most recent version, so that it is not required to update the list
# below. The timestamps shown in the following sequence will be update by the call to `getRecentVersion`.

# In[ ]:

dailyDepCsv    = last("sursaud-corona-quot-dep-2021-04-08-21h20.csv")
dailyRegionCsv = last("sursaud-corona-quot-reg-2021-04-03-19h33.csv")
dailyFranceCsv = last("sursaud-covid19-quotidien-2020-04-12-19h00-france.csv")
dailyXlsx      = last("sursaud-covid19-quotidien-2020-04-12-19h00.xlsx")
weeklyCsv      = last("sursaud-covid19-hebdomadaire-2020-04-08-19h00.csv")

hospAgeCsv     = last("donnees-hospitalieres-classe-age-covid19-2020-04-11-19h00.csv")
hospNouveauCsv = last("donnees-hospitalieres-nouveaux-covid19-2020-04-11-19h00.csv")
hospCsv        = last("donnees-hospitalieres-covid19-2020-04-11-19h00.csv")
hospEtablCsv   = last("donnees-hospitalieres-etablissements-covid19-2020-04-12-19h00.csv")
weeklyLabCsv   = last("sp-pos-heb-fra-2021-08-09-19h06.csv")
dailyLabCsv    = last("sp-pos-quot-fra-2021-08-09-19h06.csv")

S1 = set (dataFileVMgr.listMostRecent())
S2 =set((dailyDepCsv,dailyRegionCsv,dailyFranceCsv, dailyXlsx, weeklyCsv,
         hospAgeCsv, hospNouveauCsv, hospCsv,  hospEtablCsv, weeklyLabCsv, dailyLabCsv  ))
missing = S1. difference(S2)
if len(missing) > 0:
    print (f"Missing comparing with most recent files in ../data:")
for f in missing:
    print(f"\t{f}")

metaHebdoCsv = "../data/metadonnee-urgenceshos-sosmedecins-covid19-hebdo.csv"
metaQuotRegCsv = "../data/metadonnee-urgenceshos-sosmedecin-covid19-quot-reg.csv"
metaQuotFraCsv = "../data/metadonnee-urgenceshos-sosmedecin-covid19-quot-fra.csv"
metaQuotCsv = "../data/metadonnee-urgenceshos-sosmedecin-covid19-quot.csv"

metaHospservices = "../data/metadonnees-services-hospitaliers-covid19.csv"
metaHospAge = "../data/metadonnees-donnees-hospitalieres-covid19-classes-age.csv"
metaHospIncid = "../data/metadonnees-hospit-incid.csv"
metaHosp = "../data/metadonnees-donnees-hospitalieres-covid19.csv"
metaHospEtabl = "../data/donnees-hospitalieres-etablissements-covid19-2020-04-11-19h00.csv"

metaSexeCsv = "../data/metadonnees-sexe.csv"
metaRegionsCsv="../data/regions-france.csv"
metaTranchesAgeCsv="../data/code-tranches-dage.csv"

# In[ ]:

ad  = lambda x: "../data/"+x
S1 = set (map(ad, dataFileVMgr.listMostRecent(nonTS=True)))
S2 =set((metaHebdoCsv, metaQuotRegCsv,  metaQuotFraCsv, metaQuotCsv,
         metaHospservices, metaHospAge, metaHospIncid, metaHosp,  metaHospEtabl, metaRegionsCsv, metaTranchesAgeCsv ))
missing = S1. difference(S2)
if len(missing) > 0:
    print (f"Missing comparing with non timestamped files in ../data:")
    print ("These may eventually be exploited in other notebooks (e.g. COVID-MoreData-FromGouv)")
    for f in missing:
        print(f"\t{f}")

# Now load the stuff
#

# In[ ]:

ad  = lambda x: "../data/"+x
data_dailyRegion = read_csvPandas(ad(dailyRegionCsv), error_bad_lines=False,sep=";" )
data_dailyDep    = read_csvPandas(ad(dailyDepCsv), error_bad_lines=False,sep=";")
data_dailyFrance = read_csvPandas(ad(dailyFranceCsv), error_bad_lines=False,sep=",")
data_daily       = read_xlsxPandas(ad(dailyXlsx))
data_weekly      = read_csvPandas(ad(weeklyCsv), error_bad_lines=False,sep=";")

data_hospNouveau = read_csvPandas(ad(hospNouveauCsv), error_bad_lines=False,sep=";")
data_hosp        = read_csvPandas(ad(hospCsv), error_bad_lines=False,sep=";")
data_hospAge     = read_csvPandas(ad(hospAgeCsv), error_bad_lines=False,sep=";")
data_hospEtabl   = read_csvPandas(ad(hospEtablCsv), error_bad_lines=False,sep=";")

data_weeklyLab   = read_csvPandas(ad(weeklyLabCsv), error_bad_lines=False,sep=";")
data_dailyLab    = read_csvPandas(ad(dailyLabCsv), error_bad_lines=False,sep=";")

meta_Hebdo       = read_csvPandas(metaHebdoCsv,     clearNaN=True, error_bad_lines=False,sep=";", header=2)
meta_QuotReg     = read_csvPandas(metaQuotRegCsv, clearNaN=True, error_bad_lines=False,sep=";", header=1)
meta_QuotFra     = read_csvPandas(metaQuotFraCsv, clearNaN=True, error_bad_lines=False,sep=";", header=1)
meta_Quot        = read_csvPandas(metaQuotCsv, clearNaN=True, error_bad_lines=False,sep=";", header=1)
meta_HospServices = read_csvPandas(metaHospservices, clearNaN=True, error_bad_lines=False,sep=";")
meta_HospAge      = read_csvPandas(metaHospAge, clearNaN=True, error_bad_lines=False,sep=";")
meta_HospIncid    = read_csvPandas(metaHospIncid, clearNaN=True, error_bad_lines=False,sep=";")
meta_Hosp         = read_csvPandas(metaHosp, clearNaN=True, error_bad_lines=False,sep=";")

meta_Sexe = read_csvPandas(metaSexeCsv, clearNaN=True, error_bad_lines=False,sep=";",header=0)
meta_Regions = read_csvPandas(metaRegionsCsv, clearNaN=True, error_bad_lines=False,sep=",")
meta_Ages    =  read_csvPandas(metaTranchesAgeCsv, clearNaN=True, error_bad_lines=False,sep=";")

# ## Figure out data characteristics

# In[ ]:

def showBasics(data,dataName):
    print(f"{dataName:24}\thas shape {data.shape}")

dataListDescr = ((data_dailyRegion, "data_dailyRegion"),
                  (data_dailyDep,"data_dailyDep"),
                  (data_hospAge,"data_hospAge"),
                  (data_dailyFrance, "data_dailyFrance"),
                  (data_daily,"data_daily"),
                  (data_weekly , "data_weekly "),
                  (data_hospNouveau,"data_hospNouveau"),
                  (data_hosp,"data_hosp"),
                  (data_hospAge,"data_hospAge"),
                  (data_hospEtabl,"data_hospEtabl"),
                  (data_weeklyLab,"data_weeklyLab"),
                  (data_dailyLab ,"data_dailyLab"),
                  (meta_Hebdo,"meta_Hebdo"),
                  (meta_QuotReg,"meta_QuotReg"),
                  (meta_QuotFra,"meta_QuotFra"),
                  (meta_Quot,"meta_Quot"),
                  (meta_HospServices,"meta_HospServices"),
                  (meta_HospAge,"meta_HospAge"),
                  (meta_HospIncid,"meta_HospIncid"),
                  (meta_Hosp,"meta_Hosp"),
                  (meta_Sexe,"meta_Sexe"),
                  (meta_Regions,'meta_Regions'),
                  (meta_Ages,'meta_Ages'))

for (dat,name) in dataListDescr:
    showBasics(dat,name)

# ### Help with meta data
# Of course I encountered some surprises, see `checkRepresentedRegions` issue with unknown codes which
# did occur in some files!

# In[ ]:

def checkRepresentedRegions(df,col='reg',**kwOpts):
    "list regions represented in a dataframe, if kwd print=True, will print list of code->string"
    regs = set(df[col])
    if "print" in kwOpts:
        for r in regs:
            extract = meta_Regions[ meta_Regions['code_region'] == r]
            # print (f"r={r}\t{extract}\t{extract.shape}")
            if extract.shape[0] == 0:
                lib = f"**Unknown:{r}**"
            else:
                lib=extract.iloc[0]. at ['nom_region']
            print(f"Region: code={r}\t->{lib}")
    return regs

# In[ ]:

for (dat,name) in dataListDescr:
    if name[0:5]=="meta_": continue
    print(f"\nDescription of data in '{name}'\n")
    display(dat.describe().transpose())

# In[ ]:

for (dat,name) in dataListDescr:
    if name[0:5]!="meta_": continue
    print(f"\nMeta data in '{name}'\n")
    display(dat)

# ## Read the meta data characterising resources on the remote site
# This is a demo of the capabilities of  class `manageAndCacheDataFile`.

# In[ ]:

dataFileVMgr.pprintDataItem( item=".*org.*/^(name|class)$")
dataFileVMgr.pprintDataItem( item="resource.*/(f.*|title.*)")

# ## Get some demographics data from INSEE
# For the time being, these data are obtained / loaded from Insee web site using a manual process and are placed in a different directory, therefore a distinct FileManager is used, and loading this data is done here; for more details see the notebook `Pop-Data-FromGouv.ipy`
#
# Using the base version which does not try to update the "../dataPop" directory

# In[ ]:

dataFileVMgrInsee = manageDataFileVersions("../dataPop")
inseeDepXLS           ="../dataPop/InseeDep.xls"
inseeDep            = read_xlsxPandas(inseeDepXLS,  sheet_name=1, header=7)
inseeReg            = read_xlsxPandas(inseeDepXLS,  sheet_name=0, header=7)

# Now we can display our demographics data (summarized)

# In[ ]:

display(inseeDep.iloc[:,4:].sum())
display(inseeReg.iloc[:,4:].sum())

# ## Let's do some graphics!

# ### Données de  urgences hospitalières et de SOS médecins
# Df: dailyRegion ( file sursaud-covid19-quotidien)
# #### Structure the data

# Select age category '0', thus getting all ages

# In[ ]:

def select_Ages(df, ageGroup='0'):
    return df.loc[df['sursaud_cl_age_corona'] == ageGroup]
def select_AllAges(df):
    return select_Ages(df)

# In[ ]:

def groupByDate(df):
    return df.groupby('date_de_passage')

# First, I work with the dailyRegion data, summing up for all regions.

# In[ ]:

gr_all_age_regions = groupByDate(select_AllAges(data_dailyRegion)).sum()
checkRepresentedRegions(data_dailyRegion, print=True);

# In[ ]:

dfGr = PAN.DataFrame(gr_all_age_regions.copy(), columns=gr_all_age_regions.columns[1:])
painter = figureTSFromFrame(dfGr,figsize=(12,8))
painter.doPlot()
painter.setAttrs(label=f"Days since {painter.dt[0]}",
                 title="Whole France/Data ER + SOS-medecin\nAll age groups",
                 legend=True,
                 xlabel=f"Days since {painter.dt[0]}")

PAN.set_option('display.max_colwidth', None)
display(meta_QuotReg[[ "Colonne","Description_FR" ]])
ImgMgr.save_fig("FIG002")

# Then, I look at the national data, as represented in `data_dailyFrance` and `data_daily`

# In[ ]:

print(f"data_daily: {data_daily.shape}")
print(f"{','.join(data_daily.columns)}")
display(data_daily.describe())
display(data_daily[:5])

print("data_dailyFrance:  {data_dailyFrance.shape}")
print(f"{','.join(data_dailyFrance.columns)}")
display(data_dailyFrance.describe())
display(data_dailyFrance[:5])

# ### Hospital data
# DF: hospNouveau  File: donnees-hospitalieres-nouveaux-covid19

# In[ ]:

gr_all_data_hospNouveau=data_hospNouveau.groupby('jour').sum()
dfGrHN = PAN.DataFrame(gr_all_data_hospNouveau)
colOpts = {'incid_dc': {"c":"b","marker":"v"},
           'incid_rea': {"c":"r","marker":"o", "linestyle":"--"},
           'incid_rad': {"marker":"+"},
           'incid_hosp': {"marker":"*"}
          }

painter = figureTSFromFrame(dfGrHN)
painter.doPlot()
painter.setAttrs(colOpts=colOpts,
                 xlabel=f"Days since {painter.dt[0]}",
                 title="Whole France (Hospital)\nDaily variation in patient status",
                 legend=True  )

PAN.set_option('display.max_colwidth', None)
display(meta_HospIncid[[ "Colonne","Description_EN" ]])

# In[ ]:

gr_all_data_hosp=data_hosp.loc[data_hosp["sexe"] == 0 ].groupby('jour').sum()
cols = [ c for c in gr_all_data_hosp.columns if c != 'sexe']
dfGrH = PAN.DataFrame(gr_all_data_hosp[cols])
colOpts = { 'dc': {"c":"b","marker":"v"},
           'rea': {"c":"r","marker":"o", "linestyle":"--"},
           'rad': {"marker":"+"},
           'hosp': {"marker":"*"}
          }
painter = figureTSFromFrame(dfGrH)
painter.doPlot()
painter.setAttrs( colOpts=colOpts,
                  xlabel=f"Days since {painter.dt[0]}",
                  title="Whole France / Hospital\n:Daily patient status (ICU,Hosp) / Accumulated (discharged, dead)",
                 legend=True)
display(meta_Hosp[[ "Colonne","Description_EN" ]])
ImgMgr.save_fig("FIG003")

# ### Now analyze hospital data according to sex

# In[ ]:

data_hosp_DepSex=data_hosp.set_index(["dep","sexe"])
data_hosp_DepSex[data_hosp_DepSex.index.get_level_values(1)!=0]

d1 = data_hosp_DepSex[data_hosp_DepSex.index.get_level_values(1)==1]
d2 = data_hosp_DepSex[data_hosp_DepSex.index.get_level_values(1)==2]

d1s=d1.groupby("jour").sum()
d2s=d2.groupby("jour").sum()

dm= PAN.concat([d1s,d2s], axis=1)
cols1 = list(map (lambda x: x+"_M", d1s.columns))
cols2 = list(map (lambda x: x+"_F", d2s.columns))
dm.columns = (*cols1,*cols2)

# In[ ]:

painter = figureTSFromFrame(dm)

colOpts = {'dc_F': {"c":"r",  "marker":"v"},
           'dc_M': {"c":"b",  "marker":"v"},
           'rea_F': {"c":"r", "marker":"o", "linestyle":"--"},
           'rea_M': {"c":"b", "marker":"o", "linestyle":"--"},
           'rad_F': {"c":"k", "marker":"+"},
           'rad_M': {"c":"y", "marker":"+"},
           'hosp_M':{"c":"b"},
           'HospConv_M':{'c':'c'},
           'SSR_USLD_M' :{'c':'c',"marker":'p' },
           'hosp_F':{'c':'r'},
           'HospConv_F':{'c':'m'},
           'SSR_USLD_F' :{'c':'m',"marker":'p'},
           'autres_M':{'c':'c', "linestyle":":"},
           'autres_F':{'c':'m', "linestyle":":"}
          }
painter.doPlotBycol()
painter.setAttrs(colOpts = colOpts,
                    xlabel  = f"Days since {painter.dt[0]}",
               title="Whole France\ / Hospital\n Male / Female\n:Daily patient status (ICU,Hosp) / Accumulated (discharged, dead)",
               legend=True    )
display(meta_Hosp[[ "Colonne","Description_EN" ]])
ImgMgr.save_fig("FIG004")

# ### Now analyze hospital data according to age
# For now the data available in table `data_hospAge` covers a small number of days.... hopefully this may improve, either by more earlier data becoming available, or just by more data being collected day after day!

# In[ ]:

data_hosp_RegAge=data_hospAge.set_index(["reg","jour",'cl_age90'])
ddd= data_hosp_RegAge[ data_hosp_RegAge.index.get_level_values(2)!=0 ]

# We may have multiple entries for same day, this is an issue in the way
# this table is made up. For now, seems that best strategy is to sum!
# We keep track of previous strategy which was to arbitrarily select a value among duplicate indices,
# therefore the if True
if True:
  dhRA = ddd.groupby(by=list(ddd.index.names)).sum().copy()
  dhRAg = dhRA.unstack('cl_age90').groupby("jour").sum()
else:
    # older strategy, kept for referral, parameter keep has several possible values
    # remove duplicate entries, not performing selection between multiple values
  duplic = ~ddd.duplicated(keep=False)
  print( f"Number of duplicated lines: {duplic.sum()} {duplic.sum()/duplic.size*100:.2f}%")
  dhRA = ddd[ duplic ].unstack('cl_age90')
  dhRAg = dhRA.groupby("jour").sum()

# In[ ]:

ageClasses = sorted(set(dhRAg.columns.get_level_values(1)))
print(f"age classes = {ageClasses}")

levCat = sorted(set(dhRAg.columns.get_level_values(0)))
levAge = sorted(set(dhRAg.columns.get_level_values(1)))
subnodeSpec=(lambda i,j:{"nrows":i,"ncols":j})(*subPlotShape(len(levAge),maxCol=6))

print(f"nb age classes:{len(levAge)}\tsubnodeSpec:{subnodeSpec}")
if len(levAge) != len(ageClasses):
    raise RuntimeError("Inconsistent values for number of age classes")

# In[ ]:

colOpts = {'dc': {"c":"b","marker":"v"},
           'rea': {"c":"b","marker":"o", "linestyle":"--"},
           'rad': {"c":"r", "marker":"+"},
           'hosp':{"c":"k", "linestyle":"-"},
           'HospConv':{"c":"c", "linestyle":"-"},
           'SSR_USLD' :{"c":"g","linestyle":"-"},
           'autres':{'c':'m'}
          }

# In[ ]:

painter = figureTSFromFrame(None, subplots=subnodeSpec, figsize=(15,15))
for i in range(len(levAge)):
    cat = ageClasses[i]
    if cat < 90:
        title = f"Age {cat-9}-{cat}"
    else:
        title = "Age 90+"

    dfExtract = dhRAg.loc(axis=1)[:,cat]
    # remove the now redundant information labeled 'cl_age90'
    dfExtract.columns = dfExtract.columns.levels[0]
    painter.doPlotBycol(dfExtract);
    painter.setAttrs(colOpts = colOpts,
                     xlabel  = f"Days since {painter.dt[0]}",
                     title   = title,
                     legend  = True    )

    painter.advancePlotIndex()

display(meta_Hosp[[ "Colonne","Description_EN" ]])
ImgMgr.save_fig("FIG005")

# ## Testing : Laboratory data
#
# This concerns testing (I have not found the meta data yet, but column labels are clear enough).
# The `data_dailyLab` data is split between age classes and departements.

# In[ ]:

todayStr = datetime.date.today().isoformat()    # handle a data error that appeared on 5/5/2020

# Modif. August 2021:
# - we do not have the comfort of cat 0 summing all ages anymore
# - may be it would be better to divide per population.. this would give a different figure
# - should we rename columns with the old labels?

# In[ ]:

msk=d=data_dailyLab.loc[:,"jour"]<=todayStr      #there is an error in the version of the data distrib 05/05/2020
dl=data_dailyLab.loc[msk,:]
dlGrA = dl.groupby('jour').sum()
#dlGr["cl_age90"]=0     #
dlGr = dlGrA.drop(columns=["cl_age90", "pop"])

# In[ ]:

dlGr.columns

# In[ ]:

def LaboRelabCols(tble):
    corresp={
        'P_f' : 'Pos_f', 'P_h': 'Pos_h', 'P':'Positive',
        'T_f':'Tested_f', 'T_h':'Tested_h', 'T':'Tested'
    }
    rc = [corresp.get(x) for x in tble.columns]
    tble.columns=rc

# In[ ]:

LaboRelabCols(dlGr)

# In[ ]:

painter = figureTSFromFrame(dlGr)
colOpts = {'Tested': {"c":"b", "marker":"*"},
           'Positive':  {"c":"r", "marker":"+"},
           'Tested_h': {"c":"b","marker":"o", "linestyle":"--"},
           'Tested_f': {"c":"g","marker":"o", "linestyle":"--"},
           'Pos_h': {"c":"b", "marker":"+"},
           'Pos_f': {"c":"g", "marker":"+"}
          }
painter.doPlotBycol()
painter.setAttrs(colOpts = colOpts,
                    xlabel  = f"Days since {painter.dt[0]}",
               title="Whole France laboratory: tested, positive for male(h) and female(f)",
               legend=True    )

ImgMgr.save_fig("FIG006")

# Analyze laboratory data according to age

# In[ ]:

data_dailyLab.columns
dataDLab = data_dailyLab.loc[msk,:].copy()

# In[ ]:

dataDLab

# In[ ]:

dhRA

# In[ ]:

dataDLab=dataDLab.set_index(["jour",'cl_age90'])

# In[ ]:

dhRA = dataDLab.drop(columns=["pop"]).unstack('cl_age90')
dhRAg = dhRA.groupby("jour").sum()

# In[ ]:

ageClasses = sorted(set(dhRAg.columns.get_level_values(1)))
print(f"age classes = {ageClasses}")

levCat = sorted(set(dhRA.columns.get_level_values(0)))
levAge = sorted(set(dhRA.columns.get_level_values(1)))

subnodeSpec=(lambda i,j:{"nrows":i,"ncols":j})(*subPlotShape(len(levAge),maxCol=6))

print(f"nb age classes:{len(levAge)}\tsubnodeSpec:{subnodeSpec}")
if len(levAge) != len(ageClasses):
    raise RuntimeError("Inconsistent values for number of age classes")

ageLabs=['All']+[f"{x-9}-{x}" for x in ageClasses[1:-1]]+["90+"]

# In[ ]:

colOpts = {'Tested': {"c":"b", "marker":"*"},
           'Positive':  {"c":"r", "marker":"+"},
           'Tested_h': {"c":"b","marker":"o", "linestyle":"--"},
           'Tested_f': {"c":"g","marker":"o", "linestyle":"--"},
           'Pos_h': {"c":"b", "marker":"+"},
           'Pos_f': {"c":"g", "marker":"+"}
          }

# In[ ]:

painter = figureTSFromFrame(None, subplots=subnodeSpec, figsize=(15,15))
for i in range(len(ageClasses)):
    cat = ageLabs[i]
    ageSpec = ageClasses[i]
    title = f"Labo Tests\nAge: {cat}"

    dfExtract = dhRAg.loc(axis=1)[:,ageSpec]
    # remove the not needed information since we selected by ageSpec
    dfExtract.columns = [col[0] for col in dfExtract.columns]

    LaboRelabCols(dfExtract)

    painter.doPlotBycol(dfExtract);
    painter.setAttrs(colOpts = colOpts,
                     xlabel  = f"Days since {painter.dt[0]}",
                     title   = title,
                     legend  = True    )

    painter.advancePlotIndex()

ImgMgr.save_fig("FIG007")

# # Merge COVID and demographics data
# See the `Pop-Data-FromGouv.ipynb` notebook for more details on the demographics data obtained from
# INSEE (https://www.insee.fr/fr/accueil).

# Prepare the data for a database style join/merge, documented on https://pandas.pydata.org/pandas-docs/stable/user_guide/merging.html.
# First we need to establish "dep" as an index in hospital data:

# In[ ]:

hndDf = data_hospNouveau.copy()
hndDf.set_index("dep");

# Then we extract the demographic information and set index "dep"

# In[ ]:

depStats = inseeDep.iloc[:,[2,3,7,8]].copy()
cols = depStats.columns.values
cols[0]="dep"
depStats.columns = cols
depStats.set_index("dep");

# Now we perform the merge, and group by date and 'départements':

# In[ ]:

hndMerged = PAN.merge(hndDf,depStats, on="dep" )
hndGrMerged=hndMerged.groupby(["jour","dep"]).sum()

# For now, look at daily statistics normalized by concerned population (unit= event per million people)

# In[ ]:

hndGMJour = hndGrMerged.groupby("jour").sum()
colLabs = ("incid_hosp", "incid_rea", "incid_dc", "incid_rad")
for lab in colLabs:
    hndGMJour[lab+"_rate"] = hndGMJour[lab]/hndGMJour["Population totale"]*1.0e6

# And the graph can be readily generated:

# In[ ]:

ncolLabs = list ( x+"_rate" for x in colLabs)
df=hndGMJour.loc[:,ncolLabs]
colOpts = {'incid_dc_rate'  : {"c":"b","marker":"v"},
           'incid_rea_rate' : {"c":"r","marker":"o", "linestyle":"--"},
           'incid_rad_rate' : {"marker":"+"},
           'incid_hosp_rate': {"marker":"*"}
          }

painter = figureTSFromFrame(df)
painter.doPlot()
painter.setAttrs(colOpts=colOpts,
                 xlabel=f"Days since {painter.dt[0]}",
                 ylabel="Events per million people",
                 title="Whole France (Hospital)\nDaily variation in patient status",
                 legend=True  )

PAN.set_option('display.max_colwidth', None)
display(meta_HospIncid[[ "Colonne","Description_EN" ]])
ImgMgr.save_fig("FIG008")

# Now we can do the same exercise keeping the 'département' information around:

# In[ ]:

hndGMDepJour = hndGrMerged.iloc[:,[0,1,2,3,5]].copy()

# In[ ]:

colLabs = ("incid_hosp", "incid_rea", "incid_dc", "incid_rad")
for lab in colLabs:
    hndGMDepJour[lab+"_rate"] = hndGMDepJour[lab]/hndGMDepJour["Population totale"]*1.0e6

# In[ ]:

hGMDJExtract = hndGMDepJour.iloc[:,range(5,9)]

# ### Look at the distribution accross areas ('departements')
#

# This is simply an effort to get 'departement's by name rather than by number (you were supposed to learn the mapping in school... that was a long time ago... )

# In[ ]:

inseeDepLib=inseeDep.iloc[:,[2,3]]
cl=list(inseeDepLib.columns)
cl[0]="dep"
inseeDepLib.columns=cl

# In[ ]:

colLabs = ("incid_hosp", "incid_rea", "incid_dc", "incid_rad")
for lab in colLabs:
    hndMerged[lab+"_rate"] = hndMerged[lab]/hndMerged["Population totale"]*1.0e6

# Here we show the heat map for the most active days in the various 'départements', where activity is measured in events per million population.

# In[ ]:

cols=list(hndMerged.columns)
cols[6]="depL"
hndMerged.columns=cols
i=15
rowsSel={}
for icase in range(9,13):
  i+=1
  hhn=hndMerged.iloc[:,[6,1,icase]]

  lwhat = hndMerged.columns[icase]
  hh = hhn.pivot(index="depL", columns='jour',values=lwhat)

  largeRows=hh.max(axis=1).nlargest(10)
  smallRows=hh.max(axis=1).nsmallest(10)
  largeCols=hh.max(axis=0).nlargest(10)
  smallCols=hh.max(axis=0).nsmallest(10)

  rowsSel[lwhat] = (icase,largeRows.index,largeCols.index)
  hzz=hh.loc[largeRows.index,sorted(largeCols.index)]
  hmax  = hzz.max().max()
  hmin  = hzz.min().min()

  PLT.figure(figsize=(18,18))
  DCTE.simpleHeatMap(data=hzz,
                     title="Events per million population:"+lwhat+"\nMost active days",
                     SNSArgs={'vmax':hmax, 'vmin':hmin
                             })
  #
  ImgMgr.save_fig(f"FIG{i:03}")

# In[ ]:

i = 0
snsDtl={"SNSBox+":{"xtickLabels":{"rotation":90}},
        "SNSStrip+":{"xtickLabels":{"rotation":90}}}
for lwhat in rowsSel:
  i+=1
  icase = rowsSel[lwhat][0]
  hhn=hndMerged.iloc[:,[6,1,icase]]

  lwhat = hndMerged.columns[icase]
  hh = hhn.pivot(index="depL", columns='jour',values=lwhat)

  largeRows=rowsSel[lwhat][1]
  largeCols=rowsSel[lwhat][2]

  hzz=hh.loc[largeRows, : ]
  hmax  = hzz.max().max()
  hmin  = hzz.min().min()

  PLT.figure(figsize=(10,10))
  PLT.title("Event per million people:"+lwhat)
  title = "Events per million people:"+lwhat
  PLT.subplot(1,2,1)
  DCTE.boxStripPlot( data = hzz, x=None, y=None, title=title, **snsDtl)
  PLT.subplot(1,2,2)
  DCTE.boxStripPlot( data = hzz.transpose(), x=None, y=None, title=title, **snsDtl)

  ImgMgr.save_fig(f"FIG{(i+20):03}")

# ### Another look at departmental data

# In[ ]:

hndMerged.info()

# In[ ]:

hndMerged.iloc[:4,:]

# In[ ]:

hndMerged["date"] = PAN.to_datetime(hndMerged.loc[:,"jour"], format="%Y/%m/%d")
dateStart = hndMerged["date"].min()
dateEnd   = hndMerged["date"].max()
dateSpan  = dateEnd - dateStart
print(f"Our statistics span {dateSpan.days+1} days, start: {dateStart} and end {dateEnd}")

hndMerged["elapsedDays"] = (hndMerged["date"] - dateStart).dt.days

# In[ ]:

dtx = hndMerged[ hndMerged["Population totale"] > 1.0e6 ]
dtg = dtx.groupby("dep")
subnodeSpec=(lambda i,j:{"nrows":i,"ncols":j})(*subPlotShape(len(dtg),maxCol=4, colFirst=False))

# In[ ]:

painter = figureFromFrame(None, subplots=subnodeSpec, figsize=(15,20))
for (departement,dfExtractOrig) in dtg :
    pop = dfExtractOrig["Population totale"].iloc[0]
    depL = dfExtractOrig["depL"].iloc[0]
    print(f"Departement={depL}, pop:{pop/1.0E6}M")
    dfExtract = dfExtractOrig.set_index("elapsedDays").copy()
    dfExtract.loc[:,"cumhosp"] = dfExtract.loc[:,"incid_hosp"].sort_index().cumsum()/dfExtract.loc[:,"Population totale"]*1.0E6
    dfExtract.loc[:,"cumdeaths"] = dfExtract.loc[:,"incid_dc"].sort_index().cumsum()/dfExtract.loc[:,"Population totale"]*1.0E6
    dfExtract.loc[:,"hosp"] = dfExtract.loc[:,"incid_hosp"]/dfExtract.loc[:,"Population totale"]*1.0E6
    dfExtract.loc[:,"deaths"] = dfExtract.loc[:,"incid_dc"]/dfExtract.loc[:,"Population totale"]*1.0E6
    painter.doPlot(df = dfExtract.loc[:,["hosp","deaths","cumhosp","cumdeaths"]])
    painter.setAttrs(label=f"Days since {dateStart}",
                 title=f"Data from Data.Gouv.Fr: {depL}",
                 legend=True,
                 xlabel=f"Days since {dateStart}",
                 ylabel="Events per million population"   )

    painter.advancePlotIndex()
ImgMgr.save_fig("FIG050")

# In[ ]:

painter = figureFromFrame(None, subplots=subnodeSpec, figsize=(15,20))
for (departement,dfExtractOrig) in dtg :
    pop = dfExtractOrig["Population totale"].iloc[0]
    depL = dfExtractOrig["depL"].iloc[0]
    print(f"Departement={depL}, pop:{pop/1.0E6}M")
    dfExtract = dfExtractOrig.set_index("elapsedDays").copy()
    dfExtract.loc[:,"cumhosp"] = dfExtract.loc[:,"incid_hosp"].sort_index().cumsum()/dfExtract.loc[:,"Population totale"]*1.0E6
    dfExtract.loc[:,"cumdeaths"] = dfExtract.loc[:,"incid_dc"].sort_index().cumsum()/dfExtract.loc[:,"Population totale"]*1.0E6
    dfExtract.loc[:,"hosp"] = dfExtract.loc[:,"incid_hosp"]/dfExtract.loc[:,"Population totale"]*1.0E6
    dfExtract.loc[:,"deaths"] = dfExtract.loc[:,"incid_dc"]/dfExtract.loc[:,"Population totale"]*1.0E6
    painter.doPlot(df = dfExtract.loc[:,["hosp","deaths","cumhosp","cumdeaths"]],
                   colOpts={"hosp": {"yscale":'log'},
                          "deaths": {"yscale":'log'},
                          "cumhosp": {"yscale":'log'},
                          "cumdeaths": {"yscale":'log'},})
    painter.setAttrs(label=f"Days since {dateStart}",
                 title=f"Data from Data.Gouv.Fr: {depL}",
                 legend=True,
                 xlabel=f"Days since {dateStart}",
                 ylabel="Events per million population"
                 )

    painter.advancePlotIndex()
ImgMgr.save_fig("FIG051")


#coding:utf-8

def fibonanci():
    yield 1
    yield 2
    yield 3
    yield 4
    yield 7
    yield 11
    yield 18

data = fibonanci()
print(data)
print(next(data))
for i in fibonanci():
    print(i)
import sys
print(sys.maxsize)
print("===>", sys.maxsize ** 66)
data = str(sys.maxsize + 1)
# print("size ", len(data))

import abc
class AbstractDict(metaclass=abc.ABCMeta):
    def foo(self):
        return None

AbstractDict.register(dict)

print(isinstance({}, AbstractDict))


from flask import Flask, render_template, request
from pytube import YouTube
from youtubesearchpython import VideosSearch
import ssl
ssl._create_default_https_context = ssl._create_stdlib_context

app = Flask(__name__)

@app.route("/", methods=['POST', 'GET'])
def anime_home():
    if request.method == "POST":

        searchstring = ""

        anime_name = request.form.get("name")
        searchstring += str(anime_name.lower())

        op_or_ed = request.form.get("op_or_ed")
        number = request.form.get("number")
        if op_or_ed == "opening":
            searchstring += f" op{str(number)}"
        else:
            searchstring += f" ed{str(number)}"

        # path = request.form.get("path")
        path = "/Users/jerrickban/Desktop/Test"

        print(searchstring)
        link = get_yt_url_from_keywords(searchstring)
        download_link(link, path)
        print(anime_name)
        print(op_or_ed)
        print(number)
        print(path)

    return render_template("index.html")

def get_new_op_num():
    file = open("op_number.txt", "r")
    num = int(file.read())
    new_num = num + 1
    file.write(str(new_num))
    return new_num

def get_yt_url_from_keywords(keywords):
    video = VideosSearch(keywords, limit=1)
    link = video.result()["result"][0]["link"]
    print(link)
    return link

def download_link(link, path):
    yt = YouTube(link,
                    use_oauth=False,
                    allow_oauth_cache=True)

    yd = yt.streams.get_highest_resolution()

    yd.download(path)


def is_spam(message):
    import re

    # Check if the message contains special characters, numbers, and uppercase letters
    special_chars = re.findall(r'[\W]', message)
    numbers = re.findall(r'\d', message)
    uppercase_letters = re.findall(r'[A-Z]', message)
    urls = re.findall(r'(https?://[^\s]+)', message)

    # Calculate the ratio of special characters, numbers, and uppercase letters to the total length of the message
    special_char_ratio = len(special_chars) / len(message)
    number_ratio = len(numbers) / len(message)
    uppercase_ratio = len(uppercase_letters) / len(message)
    url_ratio = len(urls) / len(message)

    # Set thresholds to determine if a message is spam or not
    special_char_threshold = 0.3
    number_threshold = 0.2
    uppercase_threshold = 0.4
    url_threshold = 0.1

    if (special_char_ratio > special_char_threshold or
        number_ratio > number_threshold or
        uppercase_ratio > uppercase_threshold or
        url_ratio > url_threshold):
        return True
    else:
        return False


def sorted_courses(courses):
    return sorted([course['name'] for course in courses])

def sorted_courses_2(courses):
    names = []
    for course in courses:
        names.append(course['name'])
    names.sort()
    return names

def get_lecturers(courses):
#     set(course['lecturer'] for course in courses)
    lecturers = []
    for course in courses:
        lecturer = course['lecturer']
        if lecturer not in lecturers:
            lecturers.append(lecturer)

    return lecturers

def courses_without_grades(courses):
    return [course['name'] for course in courses if 'grade' not in course]

def courses_with_good_grades(courses):
    return [course['name'] for course in courses if course.get('grade') in [1,2,3] ]

def add_course(courses, new_course):
    courses.append(new_course)

def add_course_2(courses, new_course):
    return courses + [new_course]

def add_grade_for_course(courses, name, grade):
    for course in courses:
        if course['name'] == name:
            course['grade'] = grade

def main():
    courses = [
        {
            "name": "Mathe",
            "lecturer": "X",
            "grade": 2,
        },
        {
            "name": "Mathe 2",
            "lecturer": "X",
        },
        {
            "name": "Holzkunde",
            "lecturer": "Y",
            "grade": 4,
        },
    ]
    courses_collegue = [
        {
            "name": "Mathe",
            "lecturer": "X",
            "grade": 1,
        },
        {
            "name": "Holzkunde",
            "lecturer": "Y",
            "grade": 4,
        },
    ]
    add_grade_for_course(courses, name="Mathe 2", grade=1)
    # to add grade:
    # courses[1]['grade'] = 2
    #   OR
    # mathe2 = courses[1]
    # mathe2['grade'] = 3
    print(courses_with_good_grades(courses))
    return courses
#     print("meine:")
#     print(sorted_courses_2(courses))
#     print("kollege:")
#     print(sorted_courses_2(courses_collegue))

# courses = main()

prices = {
    'apple': 1,
    'pear': 4,
}

mathe = {"name": "Mathe"}

def add_participant(course, name):
    course.setdefault('participants', []).append(name)

print(mathe)
add_participant(mathe, name="Bernhard")
print(mathe)
add_participant(mathe, name="Alex")
print(mathe)


from cosmosis.datablock import names, option_section
from linear_alignments import kirk_rassat_host_bridle_power
from linear_alignments import bridle_king
from linear_alignments import bridle_king_corrected
import numpy as np

def setup(options):
	method = options[option_section, "method"].lower()
	if method not in ["krhb", "bk", "bk_corrected"]:
		raise ValueError('The method in the linear alignment module must'
			'be either "KRHB" (for Kirk, Rassat, Host, Bridle) or BK for '
			'Bridle & King or "BK_corrected" for the corrected version of that')
	return method

def execute(block, config):
	# load z_lin, k_lin, P_lin, z_nl, k_nl, P_nl, C1, omega_m, H0
	lin = names.matter_power_lin
	nl = names.matter_power_nl
	ia = names.intrinsic_alignment_parameters
	cosmo = names.cosmological_parameters

	method = config

	z_lin,k_lin,p_lin=block.get_grid(lin,"z","k_h","p_k")
	z_nl,k_nl,p_nl=block.get_grid(nl,"z","k_h","p_k")

	omega_m = block[cosmo, "omega_m"]
	A = block[ia, "A"]

	# We initialise the galaxy bias terms to be 1 for all scales and redshifts in our fiducial model
	# This  probably isn't the right module for this, but it's convenient to do this here for the moment
	r_g= np.ones_like(p_nl) ; b_g= np.ones_like(p_nl) ;
	block.put_grid(names.bias_field, "z", z_nl, "k_h", k_nl, "r_g", r_g)
	block.put_grid(names.bias_field, "z", z_nl, "k_h", k_nl, "b_g", b_g)

	#run computation and write to datablock
	if method=='krhb':
		P_II, P_GI, b_I, r_I = kirk_rassat_host_bridle_power(z_lin, k_lin, p_lin, z_nl, k_nl, p_nl, A, omega_m)
		block.put_grid(ia, "z", z_nl, "k_h", k_nl,  "b_I", b_I)
		block.put_grid(ia, "z", z_nl, "k_h", k_nl, "r_I", r_I)
	elif method=='bk':
		P_II, P_GI, b_I, r_I = bridle_king(z_nl, k_nl, p_nl, A, omega_m)
		block.put_grid(ia,  "z", z_nl, "k_h", k_nl, "b_I", b_I)
		block.put_grid(ia,  "z", z_nl, "k_h", k_nl, "r_I", r_I)
	elif method=='bk_corrected':
		P_II, P_GI, b_I, r_I = bridle_king_corrected(z_nl, k_nl, p_nl, A, omega_m)
		block.put_grid(ia, "z", z_nl, "k_h", k_nl, "b_I", b_I)
		block.put_grid(ia, "z", z_nl, "k_h", k_nl,  "r_I", r_I)

	return 0

def cleanup(config):
	pass


from my_libs.argb import ARGB
#  3x 4x  01234567
names = 'krgybmcw'    # rgb cmykw
nums = range(30, 38)  # 30, 31...37
color_dict = dict(zip(names, nums))

fend = '\033[0m'  # reset to defalut

def style_str(nums):
    """get style code \033[a;b;cm"""
    ret = '\033['
    for i in nums:
        ret += '{};'.format(i)
    ret = ret[:-1] + 'm'
    return ret

def strARGB2nums(x, fore_back: bool):
    if isinstance(x, str):
        return [color_dict[x] + fore_back*10]
    elif isinstance(x, ARGB):
        rgb = x.RGB()
        return [38 + fore_back*10, 2] + list(rgb)

def style_code(fore, back):
    nums = []
    if fore is not None:
        nums += strARGB2nums(fore, False)
    if back is not None:
        nums += strARGB2nums(back, True)
    return style_str(nums)


import random
import pdb

class LotteryRecord:
    def __init__(self):
        self.date = None
        self.numbers = []

finalRecord = []
finished = False
while not finished:
    tempRecord = LotteryRecord()
    date = input("Please enter the date of the lottery draw (type stop if finished): ")
    if date == "stop":
        finished = True
    else:
        tempRecord.date = date
        amount = int(input("Please enter who many lottery tickets you want for this date: "))
        numbers = []
        for count in range(amount):
            for count in range(6):
                randomNum = random.randint(1,49)
                numbers.append(randomNum)
            tempRecord.numbers.append(numbers)
            numbers = []
    finalRecord.append(tempRecord)

for tempRecord in finalRecord:
        print(tempRecord.date)
        print(tempRecord.numbers)


adjacency_list = {
    1: [2, 8],
    2: [1, 3, 8],
    3: [2, 4, 8],
    4: [3, 7, 9],
    5: [6, 7],
    6: [5],
    7: [4, 5, 8],
    8: [1, 2, 3, 7],
    9: [4, 6],
}

n = len(adjacency_list)
visited = [False] * n
start = 1
path = []

def hamilton(v):
    path.append(v)
    if len(path) == n:
        if path[0] in adjacency_list[path[-1]]:
            return True
        else:
            path.pop()
            return False
    visited[v - 1] = True
    for next_v in adjacency_list[v]:
        if not visited[next_v - 1]:
            if hamilton(next_v):
                return True
    visited[v - 1] = False
    path.pop()
    return False

if hamilton(start):
    print("Цикл найден: ", end="")
    print(*path)
else:
    print("Гамильтонов цикл не найден")

Лабораторная работа №5/task2/dfs.py


#
# @lc app=leetcode id=747 lang=python3
#
# [747] Largest Number At Least Twice of Others
#

# @lc code=start
class Solution:
    def dominantIndex(self, nums: List[int]) -> int:
        if len(nums)==1:
            return 0
        maxNumKey=nums.index(max(nums))
        maxNum=nums.pop(maxNumKey)
        nums2x = [n*2 for n in nums]
        if maxNum>=max(nums2x):
            return maxNumKey
        else:
            return -1
# @lc code=end


from Raton import Raton
from Teclado import Teclado
from Monitor import Monitor
from Computadora import Computadora
from Orden import Orden

raton1 = Raton('USB', 'Hp')
teclado1 = Teclado('Bluethoot', 'Genius')
monitor1 = Monitor('Samnsung', '25"')
computadora1 = Computadora('Lenovo', raton1, teclado1, monitor1)

raton2 = Raton('USB Tipo C', 'Logitech')
teclado2 = Teclado('USB', 'HP')
monitor2 = Monitor('Xiaomi', '30"')
computadora2 = Computadora('Acer', raton2, teclado2, monitor2)

raton3 = Raton('Bluethoot', 'Genius')
teclado3 = Teclado('USB/Bluethoot', 'Anne Pro 2')
monitor3 = Monitor('LG', '28"')
computadora3 = Computadora('Asus', raton2, teclado2, monitor2)

computadoras = [computadora1, computadora2]
orden1 = Orden(computadoras)
print(orden1)
orden1.agregar_computadora(computadora3)
print(orden1)


def FixHex(file_path):
  data = ""
  with open(file_path, "r") as input_file:
    data = input_file.read()

  data = data.lower()

  hex_list = []
  start = 0
  while start < len(data):
    end = start
    while end < len(data) and data[end] != ' ':
      end += 1
    hex_list.append(data[start:end])
    start = end + 1

  hex_list = ["0x" + item for item in hex_list]
  data = ", ".join(hex_list)

  pos = file_path.find(".txt")
  if pos == -1:
    pos = len(file_path)
  new_file_path = file_path[ : pos] + "_fix.txt"

  with open(new_file_path, "w+") as output_file:
    output_file.write(data)

FixHex("hex.txt")


import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BCM)
GPIO.setup(17,GPIO.IN)
GPIO.setup(25,GPIO.OUT)
GPIO.setup(22,GPIO.OUT)

GPIO.output(25,GPIO.LOW)
GPIO.output(22,GPIO.HIGH)
light = 0

try:
	while True:
		input = GPIO.input(17)

		if (input):
			print("Who let the dogs out?!?")
			if (not light):
				GPIO.output(25,GPIO.HIGH)
				GPIO.output(22,GPIO.LOW)
				light = 1

			else:
				GPIO.output(25,GPIO.LOW)
				GPIO.output(22,GPIO.HIGH)
				light = 0
			time.sleep(0.1) # stop pushing!

		time.sleep(0.1)

finally:
	GPIO.cleanup()


#!/usr/bin/python3
"""Modulo add_integer

This module defines a basic function for add 2 numbers

Example:
    add_integer = __import__('0-add_integer').add_integer
    print(add_integer(1, 2))
"""

def add_integer(a, b=98):
    """Adds 2 numbers, return the add of the numbers a and b

    Args:
        a (int, float): first number to be add
        b (int, float): second number to be add

    Returns:
        int: the add of the two args

    Raises:
        TypeError: when a or b aren't integer or float
    """
    if not (type(a) == int or type(a) == float):
        raise TypeError("a must be an integer")

    if not (type(b) == int or type(b) == float):
        raise TypeError("b must be an integer")

    a = int(a)
    b = int(b)

    return a + b


#목돈 예치 후 만기시 받는 금액 계산
#Input: 예치액, 예치기간, 이자구분(단/복리), 이자율
#Output: 소득에 대한 과세와 주민세 제외 금액 산출.

import pickle
import os

result=open("result.txt", "w", encoding='UTF8')

capital=int(input("원금 입력: "))
duration=int(input("예치기간 입력(월): "))
interchoice=input("단리는 1, 복리는 2 입력: ")
inter_minmax=input("기본 금리는 1, 최고 금리는 2 입력: ")

with open("name_list.pkl","rb") as n:
    name_list = pickle.load(n)
with open("bank_list.pkl","rb") as b:
    bank_list = pickle.load(b)

for i in range(len(name_list)):
    try:
        if int(inter_minmax)==1:
            with open("basic_list.pkl","rb") as bi: #pkl형태의 list 파일 불러오기
                basic_list = pickle.load(bi)

            basic_inter=float(basic_list[i].replace("기본 금리: ","").replace("%","")) #list에서 계산 하기 위해 기본 금리의 실수만 추출

            inter_calc=basic_inter #결과값 출력시 사용하기 위해 다른 변수에 금리 입력
            inter=inter_calc/100/12 #월 이자율 계산을 위해 12로 나누고 백분율료 되어 있기에 100으로 나눔

            if int(interchoice)==1: #단리 계산
                total=float(capital+(capital*inter*duration))

            elif int(interchoice)==2: #복리 계산
                total=float(capital*(1+inter)**duration)

        elif int(inter_minmax)==2:
            with open("max_list.pkl","rb") as mi: #pkl형태의 list 파일 불러오기
                max_list = pickle.load(mi)

            max_inter=float(max_list[i].replace("최대 금리: ","").replace("%","")) #list에서 계산 하기 위해 기본 금리의 실수만 추출

            inter_calc=max_inter #결과값 출력시 사용하기 위해 다른 변수에 금리 입력
            inter=inter_calc/100/12 #월 이자율 계산을 위해 12로 나누고 백분율료 되어 있기에 100으로 나눔

            if int(interchoice)==1: #단리 계산
                total=float(capital+(capital*inter*duration))

            elif int(interchoice)==2: #복리 계산
                total=float(capital*(1+inter)**duration)

        inter_out = total - capital; #총 금액에서 원금을 제해 이자만 추출
        tax_out = inter_out * 15.4 / 100; #이자에 적용되는 세금을 계산
        total=total-tax_out #총 금액에서 세금을 제함

        result.write(str()+str(i+1)+"번째 상품"+"\n")
        result.write(str()+bank_list[i]+"\n")
        result.write(str()+name_list[i]+"\n")
        result.write(str()+"예치 기간: "+str(duration)+"개월"+"\n")
        result.write(str()+"예치 원금: "+str(capital)+"원"+"\n")
        result.write(str()+"환급금: "+str(total)+"원"+"\n")
        result.write(str()+"이율: "+str(inter_calc)+"%"+"\n")
        result.write(str()+"예치 이자: "+str(inter_out)+"원"+"\n")
        result.write(str()+"이자 과세: "+str(tax_out)+"원"+"\n")
        result.write(str()+"----------------------"+"\n")

        #--------------temp for test-----------------
        # name=name_list[i].replace("상품명:  ","")
        # bank_name=bank_list[i].replace("은행명: ","")
        # print(f"상품명: {name}, 은행명: {bank_name}, 예치기간: {duration}개월, 환급금: {total}원, 예치원금: {capital}원, 예치이자: {inter_out}원, 이자 과세: {tax_out}원")
        #--------------temp for test-----------------
    except:
        pass

print("계산 완료")
print("계산 결과는 result.txt에 저장되었습니다.")

result.close()
os.system("pause")


#!/usr/bin/python
#Sangram Grewal

#FOR THE CLIENT

#import relevant modules
import socket
import os
import sys

#confirm args are valid for this script
if len(sys.argv) < 4:
	exit(1)

#get name of file to be transferred from args
filename = sys.argv[3]

#confirm file exists, open it if it does
if len(filename) <= 1:
	sys.exit("File doesn't exist")
infile = open(filename, 'rb')

#create the socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

#get destination ip address from args
ip = sys.argv[1]

#get destination port number from args
port = int(sys.argv[2])

#bring the socket online
s.connect((ip, port))

#transfer the file size first- packet will always be 4 bytes long
size = os.path.getsize(filename)
size_s = str(size)
#making sure the file size packet is always 4 bytes
#if size > 4 bytes, it is concatenated
if len(size_s) > 4:
	size_s = size_s[:5]
#if size < 4 bites, the packet is filled with whitespace until it's 4 bytes
while len(size_s) < 4:
	size_s = ' ' + size_s
size_b = str(size_s).encode()
s.send(size_b)

#next transfer file name- packet will always be 20 bytes
name_s = filename
#make sure the name packet size is alwasy 20 bytes
if len(name_s) > 20:
	name_s = name_s[:21]
while len(name_s) < 20:
	name_s = ' ' + name_s
name_b = name_s.encode('utf-8')
s.send(name_b)

#read and send first 1000 bytes from file
data = infile.read(1000)

#loop and read/send data in 1000 byte chunks
while data:
	s.send(data)
	data = infile.read(1000)

#cleanup
infile.close()
s.close()


import darknet
import cv2
import time

class Detector:

    def __init__(self, config_file, data_file, weights, batch_size, threshold=0.10):
        self.network, self.class_names, self.class_colors = darknet.load_network(
            config_file,
            data_file,
            weights,
            batch_size=batch_size
        )
        self.threshold = threshold
        self.width = darknet.network_width(self.network)
        self.height = darknet.network_height(self.network)

    def detect_frame(self, frame):
        start_time = time.time()

        image_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
        image_resized = cv2.resize(image_rgb, (self.width, self.height))
        darknet_image = darknet.make_image(self.width, self.height, 3)
        darknet.copy_image_from_bytes(darknet_image, image_resized.tobytes())
        detections = darknet.detect_image(self.network, self.class_names, darknet_image,
                                          thresh=self.threshold)
        darknet.free_image(darknet_image)

        result = self._process_detection(detections)
        fps = (1/(time.time()-start_time))

        return result, fps

    def detect_frame_set(self, frame_set):
        stat, frame = frame_set.next()

        while stat:
            result, fps = self.detect_frame(frame)
            print("%2.4f completed. Current FPS: %.4f" %
                  (frame_set.file_idx*100/frame_set.file_cnt, fps))
            # code to proccess result
            stat, frame = frame_set.next()

    def _process_detection(self, detections):
        class_names, height, width = self.class_names, self.height, self.width
        label_map = {k[1]: int(k[0]) for k in enumerate(class_names)}
        result = []

        for label, confidence, bbox in detections:
            x, y, w, h = bbox
            x /= width
            w /= width
            y /= height
            h /= height

            result.append({
                "label": label_map[label],
                "confidence": float(confidence),
                "bbox": (x, y, w, h)
            })
            # print("%d %.4f %.4f %.4f %.4f" % (label_map[label], x, y, w, h))

        return result


from nltk.tokenize import word_tokenize
from nltk.corpus import stopwords
from nltk.stem import WordNetLemmatizer
import nltk
import matplotlib.pyplot as plt

lemmatizer = WordNetLemmatizer()

stop_words = set(stopwords.words('english'))

with open('text.txt', 'r') as f:
	text = f.read()

fig, ax = plt.subplots()
fig.subplots_adjust(bottom=0.3)

filtered_text = [word for word in word_tokenize(text) if word not in stop_words]
lemmatized_text = list(map(lemmatizer.lemmatize, filtered_text))
lemmatized_text = [w for w in lemmatized_text if w.isalpha()]
fdist = nltk.FreqDist(lemmatized_text)

fdist.plot(20,cumulative=False)
plt.show()


# -*-coding: utf-8 -*-
#@Author: 'ljd'
#@Time：2016/9/10 11:13

import logging
logger = logging.getLogger('simple_logging.log')
logger.setLevel(logging.DEBUG)

ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)

formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
ch.setFormatter(formatter)
logger.addHandler(ch)
logger.debug('debug message')


#
# MICA (Multiple and Inhomogeneous Component Analysis)
# A Non-parametric Approach to Constrain the Transfer Function in Reverberation Mapping
#
# Yan-Rong Li, liyanrong@mail.ihep.ac.cn
#
# Reference: Li, Y.-R. et al. 2016, arXiv:1608.03741
#
#
# analysis.py
#

import numpy as np
from scipy.optimize import curve_fit
from lmfit import minimize, Parameters, fit_report
import matplotlib.pyplot as plt
from matplotlib.backends.backend_pdf import PdfPages

pdf = PdfPages('hist.pdf')

nbin = 50
ntau = 100
tau1 = 0.0
tau2 = 50.0
nc = 4
nb = 30000

data = np.loadtxt("../data/mcmc_04.txt", skiprows=nb)   # change into the file name you want to diagnose
nt=data.shape[0]
npar = data.shape[1]

print(nt, npar)

par=np.zeros((npar-1, 3))

def gaussian(x, amp, cen, wid):
    return (amp) * np.exp(-(x-cen)**2 /(2*wid**2))

def residual(params, x, data, eps_data):
    amp = params['amp'].value
    cen = params['cen'].value
    wid = params['wid'].value

    model = amp * np.exp(-(x-cen)**2 /(2*wid**2))

    return (data-model)/eps_data

for i in range(1,npar):
  print(i)
  sort=np.sort(data[:, i])
  mean = np.mean(data[:,i])
  std = np.std(data[:,i])
  low = np.percentile(data[:,i], 15.85, interpolation='linear')
  up = np.percentile(data[:,i], 100.0-15.85, interpolation='linear')
  hrange=[data[:,i].min(), data[:,i].max()]

  hist_data = data[:,i]
  hist_range = (hist_data.min(), hist_data.max())
  print(i, hist_range)

  hist, bin_edges = np.histogram(hist_data, density=False, bins=nbin, range=hist_range)

  bin_centres = (bin_edges[:-1] + bin_edges[1:])/2
  eps_data = np.zeros(len(hist)) + 1.0

  params = Parameters()
  idx = np.argmax(hist);
  print(i, idx, hist[idx], )
  params.add('amp', value=np.max(hist), min=0.0)
  params.add('cen', value=bin_centres[idx], min=bin_centres[0], max=bin_centres[-1])
  params.add('wid', value=std, min=0.0)
  idx = np.where( hist > np.max(hist)*0.0)

  out = minimize(residual, params, args=(bin_centres[idx[0]], hist[idx[0]], eps_data[idx[0]]), method='leastsq')

# Get the fitted curve
  bin_fit = np.linspace(bin_centres[0], bin_centres[-1], nbin)
  hist_fit = gaussian(bin_fit, out.params['amp'].value, out.params['cen'].value,out.params['wid'].value)

  fig=plt.figure()

  #plt.plot(bin_centres, hist, label='Test data')
  plt.hist(hist_data, normed=False, bins=nbin, range=hist_range)
  plt.plot(bin_fit, hist_fit, label='Fitted data')

  print(np.min(data[:, i]), np.max(data[:, i]))
  plt.xlim(hist_range)
# Finally, lets get the fitting parameters, i.e. the mean and standard deviation:
  mean = out.params['cen'].value
  par[i-1, 0] = mean
  par[i-1, 1] = mean - low
  par[i-1, 2] = up - mean
  pdf.savefig(fig)
  plt.close()

pdf.close()

print(par)

np.savetxt("../data/par.txt", par, fmt="%f\t%f\t%f")

fig = plt.figure()
ax = fig.add_subplot(111)

tau = np.linspace(tau1, tau2, ntau)
tf = np.zeros(ntau)
tau_grid = np.linspace(tau1, tau2, nc)

width = par[2, 0]
for i in range(nc):
  fk = np.exp(par[3+i, 0])/np.sqrt(2.0*np.pi)/width * np.exp( -0.5*(tau - tau_grid[i])**2/width/width)
  tf += fk
  ax.plot(tau, fk, "r:")

ax.plot(tau, tf, linewidth=2)

plt.show()


# -*- coding: utf-8 -*-
"""
@author: Infaraway
@time: 2017/4/15 19:33
@Function:
"""

import sys
import time
type = sys.getfilesystemencoding()

def eclat(prefix, items, min_support, freq_items):
    while items:
        # 初始遍历单个的元素是否是频繁
        key, item = items.pop()
        key_support = len(item)
        if key_support >= min_support:
            # print frozenset(sorted(prefix+[key]))
            freq_items[frozenset(sorted(prefix+[key]))] = key_support
            suffix = []  # 存储当前长度的项集
            for other_key, other_item in items:
                new_item = item & other_item  # 求和其他集合求交集
                if len(new_item) >= min_support:
                    suffix.append((other_key, new_item))
            eclat(prefix+[key], sorted(suffix, key=lambda item: len(item[1]), reverse=True), min_support, freq_items)
    return freq_items

def eclat_zc(data_set, min_support=1):
    """
    Eclat方法
    :param data_set:
    :param min_support:
    :return:
    """
    # 将数据倒排
    data = {}
    trans_num = 0
    for trans in data_set:
        trans_num += 1
        for item in trans:
            if item not in data:
                data[item] = set()
            data[item].add(trans_num)
    freq_items = {}
    freq_items = eclat([], sorted(data.items(), key=lambda item: len(item[1]), reverse=True), min_support, freq_items)
    return freq_items


import w3af.core.controllers.output_manager as om
import w3af.core.data.constants.severity as severity

from w3af.core.controllers.plugins.audit_plugin import AuditPlugin
from w3af.core.data.fuzzer.fuzzer import create_mutants
from w3af.core.data.kb.vuln import Vuln
from w3af.core.data.fuzzer.mutants.querystring_mutant import QSMutant

PATH_PARAM = '%3B/w3af.cmd%3B/w3af.cmd'
EXEC_TOKEN = 'w3afExecToken'
ESCAPE_CHARS = ('"', '&', '|', '\n')
SHELL_CHARS = ('&', '|')
NOT_VULNERABLE_TYPES = ('application/xml', 'text/xml', 'text/html')

class rfd(AuditPlugin):
    """
    Identify reflected file download vulnerabilities.
    :author: Dmitry (nixwzard@gmail.com)
    """
    def audit(self, freq, orig_response, debugging_id):
        """
        Tests an URL for RFD vulnerabilities.

        :param freq: A FuzzableRequest
        :param orig_response: The HTTP response associated with the fuzzable request
        :param debugging_id: A unique identifier for this call to audit()
        """
        orig_headers = orig_response.headers

        ct, _ = orig_headers.iget('content-type', None)
        cd, _ = orig_headers.iget('content-disposition', None)

        if ct is not None:
            ct = ct.split(';')[0]

        if cd is not None:
            cd = orig_headers['content-disposition']
            # we have the header, but is it was set correctly?

            if 'filename' in cd.lower():
                # yes filename exists
                om.out.debug(u'URL "%s" is not vulnerable to RFD because of'
                             u' explicit filename in content-disposition header'
                             u', response id %s' %
                             (freq.get_url(), orig_response.id))
                return
            else:
                self._test(freq)

        elif ct in NOT_VULNERABLE_TYPES:
            om.out.debug(u'URL "%s" is not vulnerable to RFD because'
                         u' response content-type is "%s" and'
                         u' content-disposition header is missing,'
                         u' response id %s' %
                         (freq.get_url(), ct, orig_response.id))
            return
        else:
            self._test(freq)

    def _report_vuln(self, debug_msg, freq, rid):
        debug_msg = debug_msg % (freq.get_uri(), rid)
        om.out.debug(debug_msg)
        desc = u'Reflected File Download has been ' \
               u'found at: %s'
        desc = desc % freq.get_url()
        v = Vuln.from_fr(u'Reflected File Download vulnerability',
                         desc, severity.HIGH,
                         rid, self.get_name(), freq)
        self.kb_append_uniq(self, 'rfd', v)

    def _test(self, freq):
        uri = freq.get_uri()
        new_path = uri.get_path()+PATH_PARAM
        uri.set_path(new_path)
        freq.set_uri(uri)
        freq.set_querystring(uri.get_querystring())

        payload1 = EXEC_TOKEN
        payload2 = EXEC_TOKEN+''.join(ESCAPE_CHARS)
        payloads = payload1, payload2

        mutants = create_mutants(freq, payloads, mutant_tuple=(QSMutant,))

        for mutant in mutants:
            response = self._uri_opener.send_mutant(mutant)
            body = response.body.decode('unicode-escape')
            if not response.get_code() == 200:
                # no need to seek reflection if it is not OK
                continue

            rpos = body.find(payloads[0])
            if rpos == -1:
                # the input is not reflected
                continue

            # is it JSONP?
            if body[rpos+len(EXEC_TOKEN)] == '(' and not '\"' in body[:rpos]:
                # we've reflected as JSONP callback
                self._report_vuln(u'%s is vulnerable, to RFD because even if'
                                  u' escape chars are filtered, JSONP callback'
                                  u' comes first, response id %s',
                                  freq, response.id)
                break

            # now we need to figure out what escape chars were filtered
            if body[rpos:rpos+len(payloads[1])] == payloads[1]:
                # nothing was filtered or escaped
                self._report_vuln(u'%s is vulnerable to RFD because nothing is'
                                  u' filtered or escaped, response id %s',
                                  freq, response.id)
                return

            filtered, escaped = self._find_escaped_or_filtered(body,
                                                               rpos+len(EXEC_TOKEN),
                                                               ESCAPE_CHARS)

            if '\n' not in filtered:
                self._report_vuln(u'%s is vulnerable to RFD because with'
                                  u' newline we don\'t need any escaping,'
                                  u' response id %s ',
                                  freq, response.id)
                return

            fne = filtered + escaped

            if not '\"' in filtered:
                if not all(char in fne for char in SHELL_CHARS):
                        self._report_vuln(u'%s is vulnerable to RFD because'
                                          u' double quotes are not filtered,'
                                          u' response id %s',
                                          freq, response.id)
                        return

            else:
                #should find out if we have preceding double quotes
                if '\"' in body[:rpos]:
                    continue

                if not all(char in fne for char in SHELL_CHARS):
                        self._report_vuln(u'uri %s is vulnerable to RFD because'
                                          u' we don\'t need to escape double'
                                          u' quotes ,response id %s',
                                          freq, response.id)
                        return

    def _find_escaped_or_filtered(self, body, pos, chars):
        filtered = []
        escaped = []
        for c in chars:
            try:
                if body[pos] == c:
                    pos += 1
                    continue

                elif body[pos] == '\\' and body[pos+1] == c:
                    escaped += [c]
                    pos += 2

                else:
                    filtered += [c]
                    pos += 1

            except IndexError:
                filtered += [c]
                continue

        return filtered, escaped

    def get_long_desc(self):
        """
        :return: A DETAILED description of the plugin functions and features.
        """
        return """
        This plugin detects Reflected File Download vulnerabilities and is based
        on Oren Hafif's research.
        """


#
# @lc app=leetcode id=409 lang=python3
#
# [409] Longest Palindrome
#
# https://leetcode.com/problems/longest-palindrome/description/
#
# algorithms
# Easy (49.57%)
# Likes:    776
# Dislikes: 74
# Total Accepted:    126.6K
# Total Submissions: 255.4K
# Testcase Example:  '"abccccdd"'
#
# Given a string which consists of lowercase or uppercase letters, find the
# length of the longest palindromes that can be built with those letters.
#
# This is case sensitive, for example "Aa" is not considered a palindrome
# here.
#
# Note:
# Assume the length of given string will not exceed 1,010.
# palindrome: a word, phrase, or sequence that reads the same backwards as forwards
#
#
# Example:
#
# Input:
# "abccccdd"
#
# Output:
# 7
#
# Explanation:
# One longest palindrome that can be built is "dccaccd", whose length is 7.
#
#
#

# @lc code=start
class Solution:
    def longestPalindrome(self, s: str) -> int:
        letters = dict()
        for i in range(len(s)):
            if s[i] in letters:
                letters[s[i]] += 1
            else:
                letters[s[i]] = 1
        ANY_ODD = False
        longest_palindrome = 0
        for l in letters.keys():
            if letters[l] % 2 == 1:
                ANY_ODD = True
                longest_palindrome += letters[l] - 1
            else:
                longest_palindrome += letters[l]
        if ANY_ODD:
            return longest_palindrome + 1
        else:
            return longest_palindrome
# @lc code=end

s = Solution()
s.longestPalindrome("abccccdd")
print(s.longestPalindrome("bb"))

'''
>>> 17 // 3.0  # explicit floor division discards the fractional part
5.0
>>> 17 % 3  # the % operator returns the remainder of the division
2

dict.keys()

'''


# Definition for singly-linked list.
# class ListNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.next = None

#链表的基本操作
class Solution(object):
    def addTwoNumbers(self, l1, l2):
        """
        :type l1: ListNode
        :type l2: ListNode
        :rtype: ListNode
        """
        carry = 0
        res0 = res = ListNode(0)
        while l1 or l2 or carry:
            if l1:
                carry += l1.val
                l1 = l1.next
            if l2:
                carry += l2.val
                l2 = l2.next
            v = carry % 10
            carry /= 10
            res.next = ListNode(v)
            res = res.next
        return res0.next