# Binary Search Tree
#  James Cowgill
#

class BinaryTree:
    '''A dictionary implemented using an unbalanced binary search tree'''

    class _Node:
        '''A node in the tree'''

        def __init__(self, key, value, parent):
            '''Creates a new leaf node'''
            self.key = key
            self.value = value
            self.parent = parent
            self.left = None
            self.right = None

        def minimum(self):
            '''Returns the left most item in this subtree'''
            current = self
            while current.left is not None:
                current = current.left

            return current

        def successor(self):
            '''Returns the successor of this node or None'''
            if self.right is not None:
                # Find left most node of right subtree
                return self.right.minimum()

            else:
                # Go up the tree until we are not the right child
                current = self
                parent = self.parent

                while (parent is not None) and (current == parent.right):
                    current = parent
                    parent = parent.parent

                return parent

    # Public Viewing Methods
    # ============================
    def __init__(self):
        '''Creates a new dictionary'''
        self.clear()

    def clear(self):
        '''Removes all items from the dictionary'''
        self.__root = None
        self.__size = 0

    def __contains__(self, key):
        '''Returns true if the dictionary contains the given key'''
        return self.__find_node(key)[0]

    def __getitem__(self, key):
        '''Gets the item indexed by the given key'''
        result = self.__find_node(key)

        if result[0]:
            return result[1].value
        else:
            raise KeyError(key)

    def __iter__(self):
        '''In-order traversal'''
        if self.__root is not None:
            current = self.__root.minimum()

            while current is not None:
                yield (current.key, current.value)
                current = current.successor()

    def __len__(self):
        '''Returns the number of items in the dictionary'''
        return self.__size

    def __repr__(self):
        return "<AvlDictionary: " + ', '.join([repr(x) for x in self]) + ">"

    def get(self, key):
        '''Gets the item indexed by the given key
        or returns None if the key was not found'''
        result = self.__find_node(key)

        if result[0]:
            return result[1].value
        else:
            return None

    # Public Mutating Methods
    # ============================
    def __delitem__(self, key):
        '''Removes the given key from the dictionary'''

        # Find node to delete
        result = self.__find_node(key)

        if not result[0]:
            # Not found
            raise KeyError(key)

        # How many children?
        current = result[1]
        if (current.left is not None) and (current.right is not None):
            # Both - get successor
            successor = current.right.minimum()

            # Overwrite value
            current.key = successor.key
            current.value = successor.value

            # Delete successor
            self.__delete_update_parent(successor, successor.right)

        elif current.left is not None:
            # Left only
            self.__delete_update_parent(current, current.left)

        elif current.right is not None:
            # Right only
            self.__delete_update_parent(current, current.right)

        else:
            # Leaf node
            self.__delete_update_parent(current, None)

    def __setitem__(self, key, value):
        '''Sets an item in the dictionary'''

        # Find place to insert
        result = self.__find_node(key)

        if result[0]:
            # Replace existing value
            result[1].value = value

        else:
            # Insert new node as a child of result[1]
            parent = result[1]
            new_node = BinaryTree._Node(key, value, parent)
            self.__size += 1

            # Root insert?
            if parent is None:
                self.__root = new_node

            elif key < parent.key:
                parent.left = new_node

            else:
                parent.right = new_node

    # Private Methods
    # ============================
    def __find_node(self, key):
        '''Gets the node belonging to the given key

        returns a tuple (bool, node)
         if the node was found, the bool is true and the node is returned
         if not, the bool is false and its parent is returned'''

        parent = None
        current = self.__root

        while current is not None:
            parent = current

            if key == current.key:
                # Found the node
                return (True, current)

            elif key < current.key:
                # Move left
                current = current.left

            else:
                # Move right
                current = current.right

        # Not found
        return (False, parent)

    def __delete_update_parent(self, deleted, new_node):
        '''Updates the left / right pointer in deleted.parent to new_node'''
        parent = deleted.parent

        if parent is None:
            # Update root pointer
            self.__root = new_node

        elif deleted.key < parent.key:
            # Update left pointer
            parent.left = new_node

        else:
            # Update right pointer
            parent.right = new_node

        # Update new_node's parent
        if new_node is not None:
            new_node.parent = parent


"""
题目:
给定一个字符串数组，将字母异位词组合在一起。字母异位词指字母相同，但排列不同的字符串。
示例:
输入: ["eat", "tea", "tan", "ate", "nat", "bat"],
输出:
[
  ["ate","eat","tea"],
  ["nat","tan"],
  ["bat"]
]
说明：
所有输入均为小写字母。
不考虑答案输出的顺序。
"""
import collections

class Solution(object):
    def groupAnagrams0(self, strs):
        """
        :type strs: List[str]
        :rtype: List[List[str]]
        解题思路: 定义一个字典: key为字符串排序后的字符串; value为原始字符串
        """
        dict = {}

        for i in strs:
            sort_s = "".join((lambda x:(x.sort(),x)[1])(list(i)))

            if not dict:
                dict[sort_s] = [i]
            else:
                if sort_s in dict.keys():
                    dict[sort_s].append(i)
                else:
                    dict[sort_s] = [i]
        return dict.values()

    def groupAnagrams1(self, strs):
        """
        使用python的collections模块实现, 简化代码
        思路与groupAnagrams0 相同
        """
        # 初始化一个字典; 该字典的value为 list
        result_dict = collections.defaultdict(list)

        for s in strs:
            """
            注: 这里有一个小坑: 为什么dict的key类型为tuple?
                原因: dict/set 使用hash值进行索引,也即其要求欲存储的元素有可哈希的要求;
                     list 不使用 hash 值进行索引，故其对所存储元素没有可哈希的要求
                     所以,Python不支持dict的key为list或dict类型，因为list和dict类型是unhashable
            """
            result_dict[tuple(sorted(s))].append(s)

        return result_dict.values()

def main():
    list_s = ["eat", "tea", "tan", "ate", "nat", "bat"]

    s = Solution()

    all_anagrams0 = s.groupAnagrams0(list_s)

    print(all_anagrams0)

    all_anagrams1 = s.groupAnagrams1(list_s)

    print(all_anagrams1)

if __name__ == '__main__':
    main()


# %%
import matplotlib.pyplot as plt
import numpy as np
from torch import nn
import torch.nn.functional as F
import torch
from torch import optim
import random
import time
from utils import load_1d_data
from utils import load_2d_data
from utils import draw
from utils import table_draw

# %%
class Simple_Generator(nn.Module):
    def __init__(self):
        super(Simple_Generator, self).__init__()

        # define hidden linear layers
        self.fc1 = nn.Linear(100, 32)
        self.fc2 = nn.Linear(32, 64)
        self.fc3 = nn.Linear(64, 128)

        # final fully-connected layer
        self.fc4 = nn.Linear(128, 28 * 28)

        # dropout layer
        self.dropout = nn.Dropout(0.3)

        self.criterion = nn.BCEWithLogitsLoss()

        return

    def forward(self, x):
        # all hidden layers
        x = F.leaky_relu(self.fc1(x), 0.2)  # (input, negative_slope=0.2)
        x = self.dropout(x)
        x = F.leaky_relu(self.fc2(x), 0.2)
        x = self.dropout(x)
        x = F.leaky_relu(self.fc3(x), 0.2)
        x = self.dropout(x)
        # final layer with tanh applied
        out = F.tanh(self.fc4(x))

        return out

class Simple_Discriminator(nn.Module):
    def __init__(self):
        super(Simple_Discriminator, self).__init__()

        # define hidden linear layers
        self.fc1 = nn.Linear(784, 32 * 4)
        self.fc2 = nn.Linear(32 * 4, 32 * 2)
        self.fc3 = nn.Linear(32 * 2, 32)

        # final fully-connected layer
        self.fc4 = nn.Linear(32, 1)

        # dropout layer
        self.dropout = nn.Dropout(0.3)

        self.criterion = nn.BCEWithLogitsLoss()

        return

    def forward(self, x):
        # flatten image
        x = x.view(-1, 28 * 28)
        # all hidden layers
        x = F.leaky_relu(self.fc1(x), 0.2)  # (input, negative_slope=0.2)
        x = self.dropout(x)
        x = F.leaky_relu(self.fc2(x), 0.2)
        x = self.dropout(x)
        x = F.leaky_relu(self.fc3(x), 0.2)
        x = self.dropout(x)
        # final layer
        out = self.fc4(x)

        return out

class Simple_GAN(nn.Module):
    def __init__(self):
        super(Simple_GAN, self).__init__()
        self.generator = Simple_Generator()
        self.discriminator = Simple_Discriminator()

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

    def forward(self, x):
        x = self.generator.forward(x)

        return x

    def noise(self, num_samples):
        return torch.rand(num_samples, 100, device=(self.device)) * 2 - 1

    def train(self, train_set, batch_size, num_epoche, g_eta, g_momentum, d_eta, d_momentum, show=False):
        train_set = train_set.reshape(-1, 28 * 28).to(self.device) * 2 - 1
        self.to(self.device)
        print("trainning on " + str(self.device))

        labels = torch.cat((torch.zeros(batch_size, 1), torch.ones(batch_size, 1)), 0)
        labels = labels.to(self.device)
        fake_labels = torch.ones(batch_size, 1).to(self.device)

        g_optimizer = optim.Adam(self.generator.parameters(), lr=g_eta)
        d_optimizer = optim.Adam(self.discriminator.parameters(), lr=d_eta)
        num_set = train_set.size()[0]

        for epoch in range(num_epoche):
            tic = time.time()

            perm = perm = torch.randperm(num_set)
            for j in range(0, num_set, batch_size):
                indices = perm[j:j + batch_size]

                # optimize generator
                g_optimizer.zero_grad()

                noise = self.noise(batch_size)

                g_out = self.generator(noise)
                d_out = self.discriminator(g_out)

                g_loss = self.generator.criterion(d_out, fake_labels)
                g_loss.backward()
                g_optimizer.step()

                # optimize discriminator
                d_optimizer.zero_grad()

                fake = g_out.detach()
                real = train_set[indices].squeeze()
                batch = torch.cat((fake, real), 0)

                d_out = self.discriminator(batch)
                d_loss = self.discriminator.criterion(d_out, labels)
                d_loss.backward()
                d_optimizer.step()

            elapse = time.time() - tic
            print('epoch ' + str(epoch) + ' finished!')
            print('time usage: ' + str(elapse))

            if show is True:
                with torch.no_grad():
                    x = self.forward(self.noise(9))
                x = x.to(torch.device('cpu'))
                table_draw(x, 3, 3)

        self.to(torch.device('cpu'))

# %%
class CNN_Generator(nn.Module):
    def __init__(self):
        super(CNN_Generator, self).__init__()
        # The decoder
        self.t_conv1 = nn.ConvTranspose2d(1, 16, 2, stride=2, bias=False)
        # self.bn1 = nn.BatchNorm2d(16)
        self.t_conv2 = nn.ConvTranspose2d(16, 1, 2, stride=2, bias=False)
        # self.bn2 = nn.BatchNorm2d(1)

        return

    def forward(self, x):
        x = F.leaky_relu(self.t_conv1(x))
        x = F.sigmoid(self.t_conv2(x))

        return x

class CNN_Discriminator(nn.Module):
    def __init__(self):
        super(CNN_Discriminator, self).__init__()
        self.conv1 = nn.Conv2d(1, 64, 3, stride=(3, 3))
        # self.bn1 = nn.BatchNorm2d(64)
        self.conv2 = nn.Conv2d(64, 16, 3, stride=(3, 3))
        # self.bn2 = nn.BatchNorm2d(16)

        # self.pool = nn.MaxPool2d(2, 2)

        self.fc1 = nn.Linear(16 * 3 * 3, 120)
        self.fc2 = nn.Linear(120, 32)
        self.fc3 = nn.Linear(32, 1)

        # self.sm = nn.Softmax()

        # self.criterion = nn.NLLLoss()
        self.criterion = nn.BCELoss()

        return

    def forward(self, x):
        # Let the net to learn pool function
        # x = self.pool(F.leaky_relu(self.conv1(x)))

        # x = self.pool(F.leaky_relu(self.conv2(x)))

        x = x.reshape(-1, 1, 28, 28)

        x = F.leaky_relu(self.conv1(x))
        # x = F.leaky_relu(x)
        x = F.leaky_relu(self.conv2(x))
        # x = F.leaky_relu(x)

        x = x.view(-1, self.num_flat_features(x))   # -1 represents the batch dimension
        x = F.leaky_relu(self.fc1(x))
        x = F.leaky_relu(self.fc2(x))
        x = F.sigmoid(self.fc3(x))
        return x

    def num_flat_features(self, x):
        size = x.size()[1:]
        num_features = 1
        for s in size:
            num_features *= s
        return num_features

class CNN_GAN(nn.Module):
    def __init__(self):
        super(CNN_GAN, self).__init__()
        self.generator = CNN_Generator()
        self.discriminator = CNN_Discriminator()

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

    def forward(self, x):
        x = self.generator.forward(x)

        return x

    def noise(self, num_samples):
        return torch.rand(num_samples, 1, 7, 7, device=(self.device))

    def g_loss(self, d_out):
        loss = torch.mean(torch.log(1 - d_out))

        return loss

    def train(self, train_set, batch_size, num_epoche, g_eta, g_momentum, d_eta, d_momentum, show=False):
        train_set = train_set.to(self.device)
        self.to(self.device)
        print("trainning on " + str(self.device))

        labels = torch.cat((torch.zeros(batch_size, 1), torch.ones(batch_size, 1)), 0)
        labels = labels.to(self.device)
        fake_labels = torch.ones(batch_size, 1).to(self.device)

        g_optimizer = optim.Adam(self.generator.parameters(), lr=g_eta)
        d_optimizer = optim.Adam(self.discriminator.parameters(), lr=d_eta)
        num_set = train_set.size()[0]

        for epoch in range(num_epoche):
            tic = time.time()

            perm = perm = torch.randperm(num_set)
            for j in range(0, num_set, batch_size):
                indices = perm[j:j + batch_size]

                # optimize generator
                g_optimizer.zero_grad()

                noise = self.noise(batch_size)

                g_out = self.generator(noise)
                d_out = self.discriminator(g_out)

                g_loss = self.g_loss(d_out)
                g_loss.backward()
                g_optimizer.step()

                # optimize discriminator
                d_optimizer.zero_grad()

                fake = g_out.detach()
                real = train_set[indices]
                batch = torch.cat((fake, real), 0)

                d_out = self.discriminator(batch)
                d_loss = self.discriminator.criterion(d_out, labels)
                d_loss.backward()
                d_optimizer.step()

            elapse = time.time() - tic
            print('epoch ' + str(epoch) + ' finished!')
            print('time usage: ' + str(elapse))

            if show is True and epoch % 10 == 0:
                with torch.no_grad():
                    x = self.forward(self.noise(9))
                x = x.to(torch.device('cpu'))
                table_draw(x, 3, 3)

        self.to(torch.device('cpu'))

# %%
train_set, train_label, valid_set, valid_label, test_set, test_label = load_2d_data(50000, 0, 0)

# %%
net = Simple_GAN()

# %%
net.train(train_set, 100, 200, 0.002, 0.9, 0.002, 0.1, True)

# %%
net2 = CNN_GAN()

# %%
net2.train(train_set, 100, 20, 0.002, 0.9, 0.002, 0.1, True)

# %%
noise = net.noise(9).to(torch.device('cpu'))
with torch.no_grad():
    g_out = net.generator(noise)

# %%
print(g_out.size())

# %%
print(g_out)
# %%
table_draw(g_out, 3, 3)
# %%
net.discriminator(g_out)
# %%
net.discriminator(train_set[:10] * 2 - 1)
# %%
net.to(torch.device('cpu'))
# %%
net.discriminator.criterion(net.discriminator(g_out), torch.rand(20, 1))
# %%


import csv
import subprocess
import sys
from os import path
from os.path import split
from subprocess import check_output
import time

import gns3fy
import requests
from django.contrib.auth.decorators import login_required
from django.core.files.storage import FileSystemStorage
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import redirect, render
from django.views.generic import RedirectView
from tabulate import tabulate

from nwtopo.forms import CreateForm, DeploySearchForm, TemplateForm
from nwtopo.models import Clone, Deploy, Template

# Create your views here.
@login_required
def nwtopo(request):
    template_list = Template.objects.all()
    clone_list = Clone.objects.all()
    keep = []
    for i in clone_list:
        arg = i.name_clone
        keep.append(arg)
    print(keep)

    if request.method == 'POST':
        form = CreateForm(request.POST)
        if form.is_valid():
            print(request.POST)
            print(request.POST['temp_name'])

            temp_name = request.POST['temp_name']
            test = check_output([
                'python.exe',
                'static\\Scripts\\createfile.py',
                str(temp_name),
            ])

            Template.objects.create(
                temp_name=form.cleaned_data['temp_name']
            )
            return redirect('nwtopo')
    else:
        form = CreateForm()

    return render(request, 'nwtopo.html', {'form': form, 'template_list': template_list, 'keep': keep})

@login_required
def temp_del(request, temp_id, temp_name):
    temp_delete = check_output([
        'python.exe',
        'static\\Scripts\\delete_temp.py',
        str(temp_name),
    ])

    temp = Template.objects.get(pk=temp_id)
    temp.delete()

    name_clone = temp_name
    clone = Clone.objects.filter(name_clone=temp_name)
    clone.delete()

    return redirect('nwtopo')

@login_required
def temp_clone(request, temp_name):
    clone = check_output([
        'python.exe',
        'static\\Scripts\\clone_file.py',
        str(temp_name),
    ])

    clone_list = Clone.objects.all()
    all_clone = []
    count = 0
    for i in clone_list:
        arg = i.name_clone
        all_clone.append(arg)
        count += 1

    # count = 1
    if count == 0:
        Template.objects.create(
            temp_name=temp_name + "-" + str(1)
        )
        Clone.objects.create(
            name_clone=temp_name + "-" + str(1)
        )
    else:
        Template.objects.create(
            temp_name=temp_name + "-" + str(count+1)
        )
        Clone.objects.create(
            name_clone=temp_name + "-" + str(count+1)
        )

    return redirect('nwtopo')

@login_required
def topo(request):
    return render(request, 'topo_nw.html')

@login_required
def create_topo(request, temp_name):
    # scraping data to get id
    url = 'http://10.0.15.21/v2/projects'
    web_data = requests.get(url)
    text = web_data.json()

    dic = {}
    for i in text:
        key = i['name']
        if key not in dic.keys():
            dic[key] = i['project_id']

    # get id project!
    name = temp_name
    temp_id = dic[name]
    print(temp_id, name)

    return HttpResponseRedirect('http://10.0.15.21/static/web-ui/server/1/project/' + temp_id)

@login_required
def deploy(request):
    if request.method == 'POST':
        form = TemplateForm(request.POST)
        if form.is_valid():
            print(request.POST)
            print('******')

            Deploy.objects.create(
                temp_amount=form.cleaned_data['temp_amount']
            )
            return redirect('deploy_temp')
    else:
        form = TemplateForm()

    return render(request, 'deploy.html', {'form': form})

@login_required
def deploy_temp(request):
    template_list = Template.objects.all()
    clone_list = Clone.objects.all()
    keep = []
    for i in clone_list:
        arg = i.name_clone
        keep.append(arg)
    return render(request, 'deploy_temp.html', {'template_list': template_list, 'keep': keep})

@login_required
def deploy_temp_succ(request, temp_name):
    print('--------------------')
    deploy_list = Deploy.objects.all()
    lastest = Deploy.objects.latest('id')
    num = int(lastest.temp_amount)
    temp_name = temp_name
    print(type(lastest), lastest.temp_amount, temp_name)

    for i in range(num):
        test = check_output([
            'python.exe',
            'static\\Scripts\\clone_file.py',
            str(temp_name),
        ])

    clone = Deploy.objects.get(pk=lastest.id)
    clone.delete()
    time.sleep(60)

    return redirect('report')

@login_required
def report(request):
    # form = ItemSearchForm(request.GET)
    # if form.is_valid():
    #     item_name = form.cleaned_data['item_name']

    #     item_list = Item.objects.filter(item_name__icontains=item_name)

    template_list = Template.objects.all()

    url = 'http://10.0.15.21/v2/projects'
    web_data = requests.get(url)
    text = web_data.json()

    dic = {}
    for i in text:
        key = i['name']
        if key not in dic.keys():
            dic[key] = i['project_id']
    keep_deploy = []
    for i in dic.keys():
        keep_deploy.append(i)
    print(keep_deploy)
    temp_template = []
    for temp in template_list:
        temp_template.append(temp.temp_name)
    print(temp_template)

    temp_deploy = set(keep_deploy) - set(temp_template)
    print(temp_deploy)

    for i in temp_deploy:
        gns3_server = gns3fy.Gns3Connector("http://10.0.15.21")
        lab = gns3fy.Project(name=i, connector=gns3_server)
        lab.get()
        nodes_summary = lab.nodes_summary(is_print=False)
        node = str(nodes_summary).split(', ')

        project_id = str(lab).split(', ')
        project_id = project_id[1].replace('project_id=', '')
        project_id = project_id.replace("'", '')
        print("this is id project:", project_id)
        start = check_output([
            'python.exe',
            'static\\Scripts\\start_project.py',
            # str(all_id),
            str(project_id),
        ])
        # test = check_output([
        #     'python.exe',
        #     'static\\Scripts\\start_node.py',
        #     # str(all_id),
        #     str(project_id),
        # ])
        # time.sleep(5)

    return render(request, 'ip_report.html', {'temp_template': temp_template, 'temp_deploy': temp_deploy})

@login_required
def create_report(request, temp_name):
    template_list = Template.objects.all()

    url = 'http://10.0.15.21/v2/projects'
    web_data = requests.get(url)
    text = web_data.json()

    dic = {}
    for i in text:
        key = i['name']
        if key not in dic.keys():
            dic[key] = i['project_id']
    keep_deploy = []
    for i in dic.keys():
        keep_deploy.append(i)
    temp_template = []
    for temp in template_list:
        temp_template.append(temp.temp_name)

    temp_deploy = set(keep_deploy) - set(temp_template)

    for i in temp_deploy:
        gns3_server = gns3fy.Gns3Connector("http://10.0.15.21")
        lab = gns3fy.Project(name=i, connector=gns3_server)
        lab.get()
        nodes_summary = lab.nodes_summary(is_print=False)
        node = str(nodes_summary).split(', ')

        project_id = str(lab).split(', ')
        project_id = project_id[1].replace('project_id=', '')
        project_id = project_id.replace("'", '')
        print("this is id project:", project_id)
        test = check_output([
            'python.exe',
            'static\\Scripts\\start_node.py',
            # str(all_id),
            str(project_id),
        ])

    # url = 'http://10.0.15.21/v2/projects'
    # web_data = requests.get(url)
    # text = web_data.json()

    dic = {}
    for i in text:
        key = i['name']
        if key not in dic.keys():
            dic[key] = i['project_id']
    keep_deploy = []
    for i in dic.keys():
        keep_deploy.append(i)
    print(keep_deploy)
    temp_template = []
    for temp in template_list:
        temp_template.append(temp.temp_name)
    print(temp_template)

    temp_deploy = set(keep_deploy) - set(temp_template)
    print(temp_deploy)

    report = []
    for i in temp_deploy:
        # print('for:', i)
        if temp_name in i:
            # print('if', i)
            if len(i) <= len(temp_name)+3:
                report.append(i)
    print('test***************', report)

    # create report csv
    with open("media/report.csv", "w+") as csvfile:
        writer = csv.writer(csvfile)
        writer.writerow(["Node", "Status", "Console Port", "ID", "Project"])
        for i in report:
            gns3_server = gns3fy.Gns3Connector("http://10.0.15.21")
            lab = gns3fy.Project(name=i, connector=gns3_server)
            lab.get()
            nodes_summary = lab.nodes_summary(is_print=False)
            text = str(nodes_summary) + ", " + i
            use = text.split(", ")
            writer.writerow(use)

    return render(request, 'file_report.html')

@login_required
def file_report(request):
    # context = 'media/test.pdf'
    return render(request, 'file_report.html')

@login_required
def deploy_del(request, deploy_name):
    temp_delete = check_output([
        'python.exe',
        'static\\Scripts\\delete_temp.py',
        str(deploy_name),
    ])

    return redirect('report')


# 字符串索引，与子字符串
var1 = 'Hello World!'
var2 = "Runoob"

print ("var1[0]: ", var1[0])
print ("var2[1:5]: ", var2[1:5])

# 字符串连接
var1 = 'Hello World!'

print ("已更新字符串 : ", var1[:6] + 'Runoob!')

# 字符串格式化

print ("我叫 %s 今年 %d 岁!" % ('小明', 10))

# 字符串多行字面值

para_str = """这是一个多行字符串的实例
多行字符串可以使用制表符
TAB ( \t )。
也可以使用换行符 [ \n ]。
"""
print (para_str)


# Principal Component Analysis (PCA)

# Importing the libraries

import pandas as pd
from sklearn.decomposition import PCA
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import confusion_matrix, accuracy_score
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler

class PrincipalComponentAnalysis:

    def __init__(self, path):  # special method
        self.y = None
        self.X = None
        self.dataset = pd.read_csv(path)
        self.x_test = None
        self.x_train = None
        self.y_test = None
        self.y_train = None
        self.y_pred = None

    def data_preprocessing(self):
        self.X = self.dataset.iloc[:, :-1].values
        self.y = self.dataset.iloc[:, -1].values

        # train_test_split
        self.x_train, self.x_test, self.y_train, self.y_test = \
            train_test_split(self.X, self.y, test_size=0.2, random_state=0)

        # feature scaling
        sc = StandardScaler()
        self.x_train = sc.fit_transform(self.x_train)
        self.x_test = sc.transform(self.x_test)

    def apply_pca(self):
        pca = PCA(n_components=2)
        self.x_train = pca.fit_transform(self.x_train)
        self.x_test = pca.transform(self.x_test)
        print(self.x_test)

    def build_model(self):
        classifier = LogisticRegression(random_state=0)
        classifier.fit(self.x_train, self.y_train)
        return classifier

    def evaluate(self, model):
        self.y_pred = model.predict(self.x_test)
        cm = confusion_matrix(self.y_test, self.y_pred)
        print(cm)
        print(accuracy_score(self.y_test, self.y_pred))

path = 'datasets/Wine.csv'
p_object = PrincipalComponentAnalysis(path)
p_object.data_preprocessing()
p_object.apply_pca()
model = p_object.build_model()
p_object.evaluate(model)


import os
from appProject import app , db
from flask import (render_template , request , make_response , jsonify , session)
from werkzeug.utils import secure_filename
from appProject.analysisWithPandas import (getDropDowns , getMeData , getMeWordCloudData)
from appProject.models import DataSource , Feedback
import pandas as pd
import random

# function to check for valid file extension
def allowed_file(filename):
	return '.' in filename and filename.rsplit('.', 1)[1].lower() in app.config['ALLOWED_EXTENSIONS']

# Renders index.html
@app.route('/')
def index():
    filename = DataSource.query.order_by(DataSource.dateUploaded.desc()).first().fileName
    filePath = f'./data/files/{filename}'
    banks , periods = getDropDowns(filePath)
    session['fileSelected'] = filename
    return render_template('index.html',banks=banks,periods=periods)

# Responsible for charting
@app.route('/charting',methods=['POST'])
def data():
    response = request.get_json()
    percent  = response.get('selectedPercent') or 'All'
    bank     = response.get('selectedBank')  or 'All'
    period   = response.get('selectedPeriod') or 'All'
    filename = response.get('filename') or DataSource.query.order_by(
    	DataSource.dateUploaded.desc()).first().fileName
    data     = getMeData(percent,bank,period,filePath=f'./data/files/{filename}')
    data     = make_response(data)
    data.content_type = 'application/json'
    return data

#Responsible for uploading
@app.route('/uploadFile', methods=['POST'])
def upload_file():
    # check if the post request has the file part
    if 'files[]' not in request.files:
        resp = jsonify({'Error:': 'No file part in the request'})
        resp.status_code = 400
        return resp

    files = request.files.getlist('files[]')
    errors  = {}
    success = False

    for file in files:
        #checks if there is a file and belongs to a valid file extension
        if file and allowed_file(file.filename):
            filename = secure_filename(file.filename)
            session['fileSelected'] = filename
            #checks if file exsists in the DataSource model
            if not DataSource.query.filter_by(fileName = filename).first():
                datasrc = DataSource(fileName=filename, fileDescription = f"This is a file. Name is {filename}")
                db.session.add(datasrc)
                db.session.commit()
                file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
                feedback_list = []
                df = pd.read_csv(os.path.join(app.config['UPLOAD_FOLDER'], filename),encoding="ISO-8859-1")
                for i in range(len(df)):
                    row = df.iloc[i]
                    feedback_instace = Feedback(
                        customerName = row['Company'],
                        feedbackInformation = row['Consumer complaint narrative'],
                        feedbackType = None
                    )
                    feedback_list.append(feedback_instace)
                datasrc.feedbacks = feedback_list
                db.session.commit()
                success = True
            else:
                errors[file.filename] = 'File already exsists in DataBase'
        else:
            errors[file.filename] = 'File type is not allowed'
    #If file uploaded successfully & there are error as well
    if success and errors:
    	errors['message'] = 'File(s) successfully uploaded'
    	resp = jsonify(errors)
    	resp.status_code = 206
    	return resp
    #If all files have been uploaded successfully
    if success:
    	resp = jsonify({'message': 'All Files are successfully uploaded'})
    	resp.status_code = 201
    	return resp
    else:
    	resp = jsonify(errors)
    	resp.status_code = 400
    	return resp

#Responsible for returning back all the files that exists in the database
@app.route("/listFiles")
def list_files():
    """Endpoint to list files on the server."""
    files = DataSource.query.order_by(DataSource.dateUploaded.desc()).all()
    files = [f.fileName for f in files]
    return jsonify(files)

#Responsible for returning banks and periods for the selected file
@app.route('/getLatestDropDown',methods=['GET'])
def getLatestDropDown():
    filename = request.args.get('filename') or DataSource.query.order_by(DataSource.dateUploaded.desc()).first().fileName
    session['fileSelected'] = filename
    filePath = f'./data/files/{filename}'
    banks , periods = getDropDowns(filePath)
    response = {'banks':banks,'periods':periods}
    return jsonify(response)

# Responsible for charting Word Cloud
@app.route('/chartCloudData')
def chartCloudData():
    # get the filname which is then going to be used for charting
    # very crucial. This allows me to train the data of the selected
    # file in q2, making it very modular.

    filename  = session['fileSelected']
    try:
        feedbacks = DataSource.query.filter_by(fileName = filename)\
                            .first().feedbacks.all()
        if not feedbacks:
            raise Exception
    except:
        return jsonify('<ERROR>') , 500
    # we get the feedback information stored in the feedback instance
    # of the data source file
    data = []
    for f in feedbacks:
        data.append(f.feedbackInformation)
    try:
        array= getMeWordCloudData(data)
    except:
        return jsonify('<ERROR>') , 500
    return jsonify(array)

# Responsible for charting Sample Data Table
@app.route('/chartSampleDataTable')
def chartSampleDataTable():
    # get the filname which is then going to be used for charting
    # very crucial. This allows me to train the data of the selected
    # file in q2, making it very modular.

    filename  =  session['fileSelected']
    try:
        # get back top 100 feedbacks of the file from backend model
        feedbacks = DataSource.query.filter_by(fileName = filename)\
                                .first().feedbacks.all()[:100]
        if not feedbacks:
            raise Exception
    except:
        return jsonify('<ERROR>') , 500
    data = []
    # randomly assign a “Positive” or “Negative” value to each of the feedback.
    for f in feedbacks:
        data.append([f.feedbackInformation,random.choice(['Negative','Positive'])])
    return jsonify(data)

# Responsible to update the refresh the Sample Data Tab.
# This will refresh the Sample Data Tab on fly with the data of  trained file.
@app.route('/changeFileSelectedAfterTrain')
def changeFileSelectedAfterTrain():
    # This  ensure that when the Sample Data tab is
    # clicked the data used to process & chart the table
    # will be of the data source file that was clicked in the upload ui.
    session['fileSelected'] =  request.args.get('fileSelected')
    return jsonify('Success')


from rest_framework import viewsets, status
from .serializer import (
    WeaponSerializer,
    CategorySerializer,
    CustomWeaponSerializer,
    AverageRateCustomWeaponSerializer,
    AccesorySerializer,
    CustomWeaponAccessorySerializer
)
from .models import (Weapon, Category, CustomWeapon,
                     RateCustomWeapon, Accesory,  CustomWeaponAccessory)
from django.db.models import Avg
from rest_framework.views import APIView
from .utils.errorResponse import errorNotFound
from .utils.successResponse import successResponse
from math import ceil

class WeaponView(viewsets.ModelViewSet):
    serializer_class = WeaponSerializer
    queryset = Weapon.objects.all()

class CategoryView(viewsets.ModelViewSet):
    serializer_class = CategorySerializer
    queryset = Category.objects.all()

class CustomWeaponView(viewsets.ModelViewSet):
    serializer_class = CustomWeaponSerializer
    queryset = CustomWeapon.objects.all()

class AverageRateCustomWeaponView(APIView):
    def get(self, request):
        try:
            avg_custom_weapon = RateCustomWeapon.objects.values(
                'customWeapon').annotate(Avg('rate'))

            custom_weapons_avg = []
            for c_weapon_avg in avg_custom_weapon:

                customWeapon = CustomWeapon.objects.get(
                    id=c_weapon_avg['customWeapon'])

                serializer_custom_weapon = CustomWeaponSerializer(
                    customWeapon, many=False)

                custom_weapons_avg.append({
                    'customWeapon': serializer_custom_weapon.data,
                    'avg_rate': ceil(c_weapon_avg['rate__avg'])
                })

            serializer_avg = AverageRateCustomWeaponSerializer(
                custom_weapons_avg, many=False)

        except RateCustomWeapon.DoesNotExist as rateCustomDoesNotExists:
            print(rateCustomDoesNotExists)
            return errorNotFound("Rate for custom weapons does not exist")

        except CustomWeapon.DoesNotExist as customWeaponDoesNotExist:
            print(customWeaponDoesNotExist)
            return errorNotFound("Custom weapon does not exist")

        except Exception as e:
            print(e)
            return errorServer()

        return successResponse("Data Found", serializer_avg.instance)

class AccessoryView(viewsets.ModelViewSet):
    serializer_class = AccesorySerializer
    queryset = Accesory.objects.all()

class CustomWeaponAccessoryView(viewsets.ModelViewSet):
    serializer_class = CustomWeaponAccessorySerializer
    queryset = CustomWeaponAccessory.objects.all()


from django import template
from django.shortcuts import render, redirect, get_object_or_404
from urllib import request
from .models import DC, DA, QuizTemp, Result, Storico
from .forms import QuestionForm

# Create your views here.
def index(request):
    return render (request, "main/index.html")

def delete_all(request):
    entries = DC.objects.all()
    entries.delete()
    entries = DA.objects.all()
    entries.delete()
    entries = QuizTemp.objects.all()
    entries.delete()
    entries = Result.objects.all()
    entries.delete()
    entries = Storico.objects.all()
    entries.delete()

def add(request):
    inp = None
    index = 0
    file_location = "/home/v/Scrivania/SD_INIA10_0128a_02_p2.txt"
    with open(file_location, "r") as f:
        lines = f.readlines()
        while inp != "e":
            print(lines[index])
            print(lines[index+1])
            print(lines[index+2])
            print(lines[index+3])
            print(lines[index+4])

            inp = input("DOMANDA APERTA? Y or N: ").lower()
            if inp=="n":
                print("SCEGLIERE RISPOSTA CORRETTA. 1,2,3,4: ")
                inp = input()
                inp_ris = int(inp)
                d = DC()
                d.domanda = lines[index]
                d.r1 = lines[index+1]
                d.r2 = lines[index+2]
                d.r3 = lines[index+3]
                d.r4 = lines[index+4]
                d.rc = lines[index+inp_ris]
                if 'figura' in d.domanda:
                    n_figura = input('Inserire numero immagine: ')
                    d.image = 'static/images/image-' + n_figura + '.png'
                d.save()

                index+=5

                print("#"*20)
                print("#"*20)
            elif inp=="y" or inp=="s":
                d = DA()
                d.domanda = lines[index]
                d.risposta = "DA INSERIRE"
                if 'figura' in d.domanda:
                    n_figura = input('Inserire numero immagine: ')
                    d.image = 'static/images/image-' + n_figura + '.png'
                d.save()

                index+=1

                print("#"*20)
                print("#"*20)
            else:
                print("SCEGLIERE Y or N. RIPETO ULTIMA DOMANDA.")
    #return redirect('index')

def start(request):
    if request.method=="GET":
        if len(QuizTemp.objects.all()) > 0:
            questions = QuizTemp.objects.all()
        else:
            questions = DC.objects.order_by("?")[:30]
            for q in questions:
                qt = QuizTemp()
                qt.domanda = q.domanda
                qt.r1 = q.r1
                qt.r2 = q.r2
                qt.r3 = q.r3
                qt.r4 = q.r4
                qt.rc = q.rc
                qt.save()
        return render(request, "main/start.html", {"questions":questions})
    else:
        return redirect('quiz')

def quiz(request):
    if request.method=="GET":
        q = QuizTemp.objects.all()[0]
        num = 31 - len(QuizTemp.objects.all())
        return render(request, "main/quiz.html", {"q":q, "num":num})
    else:
        q = QuizTemp.objects.all()[0]
        r = Result()
        r.domanda = q.domanda
        r.r1 = q.r1
        r.r2 = q.r2
        r.r3 = q.r3
        r.r4 = q.r4
        r.rc = q.rc
        r.rispostaData = request.POST.get('answer').strip()
        r.save()

        QuizTemp.objects.filter(id=q.pk).delete()

        if len(QuizTemp.objects.all()) > 0:
            return redirect('quiz')
        else:
            return redirect('result')

def result(request):
    if request.method == "GET":
        if len(QuizTemp.objects.all()) > 0:
            return redirect(result_error)
        else:
            results = Result.objects.all()
            score = 0

            for r in results:
                r.r1 = r.r1.strip()
                r.r2 = r.r2.strip()
                r.r3 = r.r3.strip()
                r.r4 = r.r4.strip()
                r.rc = r.rc.strip()
                r.rispostaData = r.rispostaData.strip()
                if r.rc == r.rispostaData:
                    print("corretto")
                    r.correct = True
                    r.save()
                    score+=1
            if score >= 18:
                message = "PROMOSSO"
            else:
                message = "NON PASSATO"
            return render(request, "main/result.html",{"results":results, "score":score, "message":message})
    else:
        s = Storico()
        results = Result.objects.all()
        score = 0
        for r in results:
            if r.correct == True:
                score+=1
        s.score = score
        if score >= 18:
            s.passed = True
        s.save()
        entries = Result.objects.all()
        entries.delete()
        return redirect('storico')
def storico(request):
    return render(request, "main/storico.html")

def result_error(request):
    if request.method=="GET":
        message = "HAI ANCORA {} DOMANDE A CUI RISPONDERE.".format(len(QuizTemp.objects.all()))
        return render(request, "main/result_error.html",{"message":message})
    else:
        return redirect('quiz')

def prnt(request):
    dom = DA.objects.all()
    for d in dom:
        print(d.domanda)
        print(d.risposta)
        print("#################")

def view_all(request):
    d_ap = DA.objects.all()
    d_ch = DC.objects.all()
    return render(request, "main/view_all.html", {"d_ap":d_ap, "d_ch":d_ch})


"""
CS 3513, Homework 3
Problem Set 2.2
Example Solution
"""

# Doug Heisterkamp
# Last modified: 2/8/2014

import numpy as np
import numpy.linalg as la
import LUpivot

def problem16():
   "problem set 2.2, problem 16, page 81"
   def symTruss(theta):
      "input : theta in degree, returns forces P_1 to P_5 as an array"
      r = theta*np.pi/180
      c = np.cos(r)
      s = np.sin(r)
      A = np.array([[c,1,0,0,0],
                    [0,s,0,0,1],
                    [0,0,2*s,0,0],
                    [0,-c,c,1,0],
                    [0,s,s,0,0]],dtype=float)
      b = np.array([0,0,1,0,0],dtype=float)
      LU,seq = LUpivot.LUdecomp(A)
      x = LUpivot.LUsolve(LU,b,seq)
      return x

   x = symTruss(53)
   print("Problem 16: using theta = 53.")
   print("  P1={:5.4f}, P2={:5.4f}, P3={:5.4f}, P4={:5.4f}, P5={:5.4f}".format(
      x[0], x[1], x[2], x[3], x[4]))

def problem17():
   "problem set 2.2, problem 17, page 82"

   print("Problem 17, assuming typo in last equation.")
   for R in [5,10,20] :

      A = np.array([[50+R,-R,-30],
                    [-R,65+R,-15],
                    [-30,-15,45],  # typo in book? Using i1 for first i2
                   ],dtype=float)
      b = np.array([0,0,120],dtype=float)
      LU,seq = LUpivot.LUdecomp(A)
      i = LUpivot.LUsolve(LU,b,seq)
      print("   For R={:2d} ohms, Loop currents (amps): i1={:5.4f}, i2={:5.4f}, i3={:5.4f}".format(
             R,i[0],i[1],i[2]))

def problem20():
   "problem set 2.2, problem 20, page 83"
   import LUdecomp3

   print("Problem 20: solving with LUdecomp3")
   # matrix is tridiagonal, so using LUdecomp3 to
   # do something different.

   td_c = np.array([8,6,3,2],dtype=float)
   td_d = np.array([-8,-10,-11,-7,-4],dtype=float)
   td_e = np.array([4,2,5,4],dtype=float)
   b = np.array([-80,0,0,0,-30],dtype=float)
   td_c,td_d,td_e = LUdecomp3.LUdecomp3(td_c,td_d,td_e)
   c = LUdecomp3.LUsolve3(td_c,td_d,td_e,b)
   print("   Concentrations: c1={:5.3f}, c2={:5.3f}, c3={:5.3f}, c4={:5.3f}, c5={:5.3f}".format(
        c[0],c[1],c[2],c[3],c[4]))

if __name__ == "__main__" :
   print(__doc__)  # module doc from beginning of file
   problem16()
   print()
   problem17()
   print()
   problem20()


"""library URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/2.2/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  path('', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.urls import include, path
    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.db import router
from django.urls import path, include

from films.views import hello_world, error_page

from films.views import MoviesListAll, GenreListAll, PostCreateView, PostCreateGenreView, PostUpdateGenreView, \
    PostDeleteGenreView, PostUpdateMovieView, PostDeleteMovieView, UserViewSet, MovieViewSet, UserViewSet, GroupViewSet
#api
from rest_framework import routers

from rest_framework.authtoken import views

router = routers.DefaultRouter()
router.register('users', UserViewSet)
router.register('groups', GroupViewSet)
router.register('api-movies', MovieViewSet, base_name='s')

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', hello_world),
    path('error/', error_page),
    path('movies/', MoviesListAll.as_view(), ),
    path('movie/add/', PostCreateView.as_view(), ),
    path('genres/', GenreListAll.as_view(), name="genre_list"),
    path('genre/add', PostCreateGenreView.as_view(), ),
    path('genre/update/<int:pk>', PostUpdateGenreView.as_view(), name="genre_edit"),
    path('movie/update/<int:pk>', PostUpdateMovieView.as_view(), name="movie_edit"),
    path('genre/delete/<int:pk>', PostDeleteGenreView.as_view(), name="genre_delete"),
    path('movie/delete/<int:pk>', PostDeleteMovieView.as_view(), name="movie_delete"),
    path('api/', include(router.urls)),
    # path('api-auth/', include('rest_framework.urls', namespace='rest_framework')),
    path('api-movies/', views.obtain_auth_token),
]


from flask import Blueprint, request, render_template
from functions import load_post, uploads_posts

loader_blueprint = Blueprint('loader', __name__, url_prefix='/post', static_folder='static', template_folder='templates')

@loader_blueprint.route('/', )
def loader():
    return render_template('post_form.html')

@loader_blueprint.route('/upload/', methods=['POST'])
def upload():
    try:
        file = request.files['picture']
        filename = file.filename
        file.save(f"./uploads/{filename}")
        content = request.values['content']
        posts = load_post()
        posts.append({
            'pic': f'/uploads/{filename}',
            'content': content
        })
        uploads_posts(posts)
    except FileNotFoundError:
        return "
Файл не найден
"
    else:
        return render_template('post_uploaded.html', file=file, content=content)


from tkinter import Tk,Label,Button,Entry

vent = Tk()
vent.title("Ejemplo place")
vent.geometry("400x200")

def fSuma():
    n1=txtNum1.get()
    n2=txtNum2.get()
    r=float(n1)+float(n2)
    txtNum3.delete(0,'end')
    txtNum3.insert(0,r)

lblNum1 = Label(vent,text="Primer Número: ",bg="yellow")
lblNum1.place(x=10,y=10,width=100, height=30)
txtNum1=Entry(vent,bg="pink")
txtNum1.place(x=120,y=10,width=100, height=30)

lblNum2 = Label(vent,text="Segundo Número: ",bg="yellow")
lblNum2.place(x=10,y=50,width=100, height=30)
txtNum2=Entry(vent,bg="pink")
txtNum2.place(x=120,y=50,width=100, height=30)

btn1=Button(vent,text="Sumar", command=fSuma)
btn1.place(x=230,y=50,width=80, height=30)

lblNum3 = Label(vent,text="Resultado: ",bg="yellow")
lblNum3.place(x=10,y=120,width=100, height=30)
txtNum3=Entry(vent,bg="cyan")
txtNum3.place(x=120,y=120,width=100, height=30)

vent.mainloop()


#pylint:disable=E0602
import pygame
import pgzrun
from pgzhelper import *
from random import randint
from gamehelper import *

WIDTH = 400
HEIGHT = 400
score = 0

game_over = False

control_buttons = create_control_buttons()

fox = Actor("fox")
fox.scale = 1
fox.pos = 100, 100

coin = Actor("coin")
coin.scale = 3
coin.pos = randint(200, 1400), randint(200, 1000)

def time_up():
    global game_over
    game_over = True

def draw():
    screen.fill("green")
    fox.draw()
    coin.draw()
    draw_control_buttons(control_buttons)
    screen.draw.text("Score: " +str(score), topleft=(10, 10), fontsize=60)

    if game_over:
        screen.fill("pink")
        screen.draw.text("Final Score: " +str(score), topleft=(10, 10), fontsize=60)

def on_mouse_down(pos):
   (upbutton, downbutton, leftbutton, rightbutton) = control_buttons
   if upbutton.collidepoint(pos):
       fox.move_left(dist=40)
   if downbutton.collidepoint(pos):
       fox.move_right(dist=40)
   if leftbutton.collidepoint(pos):
       fox.move_back(dist=40)
   if rightbutton.collidepoint(pos):
       fox.move_forward(dist=40)

def move_coin():

          coin.pos = randint(200, 1400), randint(200, 1000)

def update():
          global score
          coin_collected = fox.colliderect(coin)

          if coin_collected:
                        score = score + 10
                        move_coin()

clock.schedule(time_up, 20.0)
move_coin

pgzrun.go()


from crawling import *

def naver_webtoon(url):
    ep_headers = {
        'referer': 'http://comic.naver.com/webtoon/'
    }
    html = req.get(url, headers=ep_headers).text
    soup = bfs(html, 'html.parser')

    webtoon_name = ''.join(soup.select('div.detail h2')[0].text.split())

    ep_name = soup.select('.tit_area h3')[0].text

    result = []
    n_result = []
    file_list = []
    max_width, max_height = 0, 0
    for tag in soup.select('#comic_view_area img'):
        try:
            print(tag['src'])
            result.append(tag['src'])
        except KeyError:
            print('필요한 자료 크롤링 완료')
            break

    for img_url in result:
        print(img_url)
        if re.match(r'^http.*$', img_url):
            n_result.append(img_url)

    for img_url in n_result:
        img = req.get(img_url, headers=ep_headers).content
        img_name = os.path.basename(img_url)
        img_path = os.path.join(webtoon_name, ep_name, img_name)

        dir_path = os.path.dirname(img_path)
        if not os.path.exists(dir_path):
            os.makedirs(dir_path)

        if os.path.exists(img_path):
            pass
        else:
            with open(img_path, 'wb') as f:
                f.write(img)
        file_list.append(img_path)
    for img_url in file_list:
        with Image.open(img_url) as im:
            if max_width < im.width:
                max_width = im.width

            max_height = max_height + im.height

    size = (max_width, max_height)
    white = (255, 255, 255)
    now =math.ceil(time.time())
    with Image.new('RGB', size, white) as canvas:
        height = 0
        for filename in file_list:
            with Image.open(filename) as im:
                canvas.paste(im, box=(0, height))
                height = height + im.height
        canvas.save('{}.png'.format(now))

if __name__ =='__main__':
    print('원하시는 웹툰의 url을 입력해 주세요!')
    req_url=input()
    print('으아아아 ~~요청하신 웹툰을 한 사진으로 만들어볼게요!!')
    naver_webtoon(req_url)


# 거스름돈의 개수 구하기
# 입력
change = int(input("거스름돈을 입력하세요: "))
# 거스름돈의 종류 리스트
coin = [500, 100, 50, 10]
# 거스름돈 개수 세서 출력
cnt = 0
for c in coin:
    while change >= c:
        change = change - c
        cnt += 1

print(cnt)


'''Problem Statement
Given a linked list, swap the two nodes present at position i and j, assuming 0 <= i <= j. The positions are based on 0-based indexing.

Note: You have to swap the nodes and not just the values.

Example:

linked_list = 3 4 5 2 6 1 9
positions = 2 5
output = 3 4 1 2 6 5 9
Explanation:

The node at position 3 has the value 2
The node at position 4 has the value 6
Swapping these nodes will result in a final order of nodes of 3 4 5 6 2 1 9
Let's take an example to understand a simple approach -
Given linked list = [3, 4, 5, 2, 6, 1, 9]
position_one = 2
position_two = 5
Note the original order of indexes - 0, 1, 2, 3, 4, 5, 6

Step 1 - Identify the two nodes to be swapped. Also, identify the previous of both the two nodes.
<PICTURE>
Check the order of the updated indexes as - 0, 1, 5, 3, 4, 2, 6, which implies that index 2 and index 5 have been swapped.'''

class Node:
    """LinkedListNode class to be used for this problem"""
    def __init__(self, data):
        self.data = data
        self.next = None
    def __str__(self):
        if self is None:
            return "None"
        else:
            return str(self.data)

"""
:param: head- head of input linked list
:param: `position_one` - indicates position (index) ONE
:param: `position_two` - indicates position (index) TWO
return: head of updated linked list with nodes swapped

TODO: complete this function and swap nodes present at position_one and position_two
Do not create a new linked list
"""
def swap_nodes(head, left_index, right_index):
    if left_index == right_index:
        return head
    if head is None:
        return head

    node = head.next
    last = head
    node_l_before = None
    node_l = head
    node_l_after = head.next
    node_r_after = None
    node_r_before = None
    node_r = None
    ctr = 1
    last
    while node is not None:
        print_linked_list(head)
        if ctr == left_index:
            print(f"caught left {ctr}")
            node_l_before = last
            node_l = node
            node_l_after = node.next
            print(f"last.data={str(last)}")
            print(f"node.data={str(node)}")
            print(f"node.next.data={str(node.next)}")
        if ctr == right_index:
            print(f"caught right {ctr}")
            node_r_before = last
            node_r = node
            node_r_after = node.next
            print(f"last.data={str(last)}")
            print(f"node.data={str(node)}")
            print(f"node.next.data={str(node.next)}")
            temp1 = node_l.next   # or node_l_after
            node_l.next = node.next
            temp2 = node_l
            if node_l_before is not None:
                node_l_before.next = node
            if right_index == left_index + 1:
                node.next = node_l
            else:
                last.next = node_l
                node.next = node_l_after
            if left_index == 0:
                head = node
            print(f"final results:")
            print(f"last.data={str(last)}")
            print(f"node.data={str(node)}")
            print(f"node.next.data={str(node.next)}")
            break
        ctr += 1
        last = node
        node = node.next
    return head

# Solution:
# Solution
"""
:param: head- head of input linked list
:param: `position_one` - indicates position (index) ONE
:param: `position_two` - indicates position (index) TWO
return: head of updated linked list with nodes swapped
"""
def swap_nodes_udacity_solution(head, position_one, position_two):

    # If both the indices are same
    if position_one == position_two:
        return head

    # Helper references
    one_previous = None
    one_current = None

    two_previous = None
    two_current = None

    current_index = 0
    current_node = head
    new_head = None

    # LOOP - find out previous and current node at both the positions (indices)
    while current_node is not None:

        # Position_one cannot be equal to position_two,
        # so either one of them might be equal to the current_index
        if current_index == position_one:
            one_current = current_node

        elif current_index == position_two:
            two_current = current_node
            break

        # If neither of the position_one or position_two are equal to the current_index
        if one_current is None:
            one_previous = current_node

        two_previous = current_node

        # increment both the current_index and current_node
        current_node = current_node.next
        current_index += 1

    # Loop ends

    '''SWAPPING LOGIC'''
    # We have identified the two nodes: one_current & two_current to be swapped,
    # Make use of a temporary reference to swap the references
    two_previous.next = one_current
    temp = one_current.next
    one_current.next = two_current.next
    two_current.next = temp

    # if the node at first index is head of the original linked list
    if one_previous is None:
        new_head = two_current
    else:
        one_previous.next = two_current
        new_head = head
    # Swapping logic ends

    return new_head

def test_function(test_case):
    head = test_case[0]
    left_index = test_case[1]
    right_index = test_case[2]

    left_node = None
    right_node = None

    temp = head
    index = 0
    try:
        while temp is not None:
            if index == left_index:
                left_node = temp
            if index == right_index:
                right_node = temp
                break
            index += 1
            temp = temp.next

        updated_head = swap_nodes(head, left_index, right_index)
        print("----------------------")
        print_linked_list(head)
        print_linked_list(updated_head)

        temp = updated_head
        index = 0
        pass_status = [False, False]

        while temp is not None:
            if index == left_index:
                pass_status[0] = temp is right_node
            if index == right_index:
                pass_status[1] = temp is left_node

            index += 1
            temp = temp.next

        if pass_status[0] and pass_status[1]:
            print("Pass")
        else:
            print("Fail")
        return updated_head
    except Exception as e:
        print("Exception Fail")

# helper functions for testing purpose
def create_linked_list(arr):
    if len(arr)==0:
        return None
    head = Node(arr[0])
    tail = head
    for data in arr[1:]:
        tail.next = Node(data)
        tail = tail.next
    return head

def print_linked_list(head):
    while head:
        print(head.data, end=" ")
        head = head.next
    print()

if __name__ == "__main__":
    print("TEST 1--------------------------------")
    arr = [3, 4, 5, 2, 6, 1, 9]
    head = create_linked_list(arr)
    left_index = 1
    right_index = 5
    test_case = [head, left_index, right_index]
    updated_head = test_function(test_case)
    print("TEST 2--------------------------------")
    arr = [3, 4, 5, 2, 6, 1, 9]
    head = create_linked_list(arr)
    left_index = 3
    right_index = 4
    test_case = [head, left_index, right_index]
    updated_head = test_function(test_case)
    print("TEST 3--------------------------------")
    arr = [3, 4, 5, 2, 6, 1, 9]
    left_index = 2
    right_index = 4
    head = create_linked_list(arr)
    test_case = [head, left_index, right_index]
    updated_head = test_function(test_case)
    print("TEST 4--------------------------------")
    arr = [3, 4, 5, 2, 6, 1, 9]
    left_index = 0
    right_index = 1
    head = create_linked_list(arr)
    test_case = [head, left_index, right_index]
    updated_head = test_function(test_case)
    print("TEST 5--------------------------------")
    arr = [3, 4, 5, 2, 6, 1, 9]
    left_index = 0
    right_index = 4
    head = create_linked_list(arr)
    test_case = [head, left_index, right_index]
    updated_head = test_function(test_case)
    print("TEST 6--------------------------------")
    arr = [3, 4, 5, 2, 6, 1, 9]
    left_index = 0
    right_index = 6
    head = create_linked_list(arr)
    test_case = [head, left_index, right_index]
    updated_head = test_function(test_case)
    print("TEST 7--------------------------------")
    arr = [3, 4, 5, 2, 6, 1, 9]
    left_index = 2
    right_index = 6
    head = create_linked_list(arr)
    test_case = [head, left_index, right_index]
    updated_head = test_function(test_case)
    print("TEST 8--------------------------------")
    arr = [3, 4, 5, 2, 6, 1, 9]
    left_index = 5
    right_index = 6
    head = create_linked_list(arr)
    test_case = [head, left_index, right_index]
    updated_head = test_function(test_case)

    print("TEST 9--------------------------------")
    arr = [3, 4, 5, 2, 6, 1, 9]
    left_index = 6
    right_index = 6
    head = create_linked_list(arr)
    test_case = [head, left_index, right_index]
    updated_head = test_function(test_case)
    a = 0


"""
    problem_2021_20.py
"""

import sys
import copy
from typing import List, Any, Generator, Iterator
from dataclasses import dataclass
from enum import IntEnum

from itertools import combinations

import logging
from flood_advent.utils import line_to_parts
from flood_advent.utils import SparseGrid
from flood_advent.utils import init_logging
from flood_advent.utils import LOGGER_NAME
from flood_advent.utils import binary_list_to_int
from flood_advent.utils import parse_args
from flood_advent.utils import Input

logger = logging.getLogger(LOGGER_NAME)

PART_1 = True

class MinMax():

    def __init__(self):
        self.min_x = None
        self.max_x = None
        self.min_y = None
        self.max_y = None

    def update(self, x, y):
        if self.min_x is not None:
            self.min_x = min(self.min_x, x)
            self.max_x = max(self.max_x, x)
            self.min_y = min(self.min_y, y)
            self.max_y = max(self.max_y, y)
        else:
            self.min_x = x
            self.max_x = x
            self.min_y = y
            self.max_y = y

    def extra_y_range(self, lextra, textra):
        for y in range(self.min_y - lextra, self.max_y + textra):
            yield y

    def extra_x_range(self, lextra, textra):
        for x in range(self.min_x - lextra, self.max_x + textra):
            yield x

    def y_range(self, add):
        for y in range(self.min_y, self.max_y + add):
            yield y

    def x_range(self, add):
        for x in range(self.min_x, self.max_x + add):
            yield x

class Image():

    def __init__(self):

        self.pixelmap = {}
        self.min_max = MinMax()
        self.enhance_cache = {}

    def load_image(self, data):
        for y_idx, row in enumerate(data):
            for x_idx, value in enumerate(row):
                self.add_pixels(x_idx, y_idx, value)

    def coord(self, x, y):
        return f"{x}:{y}"

    def add_pixels(self, x, y, value):
        assert value in ('.', '#')
        self.min_max.update(x, y)
        c = self.coord(x, y)
        self.pixelmap[c] = value

    def pixel_enhance_index(self, x, y, infinite_char):
        pixels = []
        for yi in [-1, 0, 1]:
            adj_y = y + yi
            for xi in [-1, 0, 1]:
                adj_x = x + xi
                c = self.coord(adj_x, adj_y)
                val = self.pixelmap.get(c, infinite_char)
                pixels.append(val)
        # logger.debug(pixels)
        to_b = {".": "0", "#": "1"}
        binary = [to_b[v] for v in pixels]
        # logger.debug(binary)
        as_int = int("".join(binary), 2)
        # logger.debug(as_int)
        return as_int

    def enhance(self, enhancer, infinite_char):
        logger.info("Enhancing image")
        new_image = Image()
        for y in self.min_max.extra_y_range(lextra=5, textra=5):
            for x in self.min_max.extra_x_range(lextra=5, textra=5):
                p_idx = self.pixel_enhance_index(x, y, infinite_char)
                new_value = enhancer.data[p_idx]
                # logger.debug("enhancer value at position %s: '%s'", p_idx, new_value)
                new_image.add_pixels(x, y, new_value)
        return new_image

    def light_pixel_count(self):
        """
        Count number of light ('#') pixels
        """
        total = 0
        for y in self.min_max.y_range(add=1):
            for x in self.min_max.x_range(add=1):
                c = self.coord(x, y)
                v = self.pixelmap.get(c)
                if v == '#':
                    total += 1
        return total

    def print(self):
        for y in self.min_max.extra_y_range(lextra=5, textra=5):
            for x in self.min_max.extra_y_range(lextra=5, textra=5):
                c = self.coord(x, y)
                v = self.pixelmap.get(c, '.')
                print(v, end="")
            print("")

class Enhancer():

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

    def __repr__(self):
        return self.data

def solve(lines):

    enhancer = Enhancer(data=lines[0])
    print(enhancer)
    image = Image()
    image.load_image(data=lines[2:])
    image.print()

    for x in range(50):
        logger.info("Enhancment #%d", x + 1)
        infinite_char = '.'
        if x % 2 and enhancer.data[0] == '#':
            infinite_char = '#'
        image = image.enhance(enhancer, infinite_char)

    image.print()
    return image.light_pixel_count()

if __name__ == "__main__":

    args = parse_args(sys.argv[1:])
    init_logging(is_verbose=args.verbose)
    logger = logging.getLogger(LOGGER_NAME)

    logger.debug("Logger init")
    year = 2021
    day = 20

    if args.year_day:
        year = int(args.year_day[:4])
        day = int(args.year_day[4:])

    problem_input = Input(year=year, day=day, use_test_data=args.use_test_data)
    lines = problem_input.get_lines()
    # lines  = problem_input.get_floats()
    # lines  = problem_input.get_ints()

    # convert from generator to list
    lines = list(lines)
    logger.info("Loaded %d values", len(lines))

    if args.print_data:
        for line in lines:
            print(line)

        sys.exit(0)

    ##################### Solution
    print("too high: 5959")
    print("too high: 5708")
    print("Solution:", solve(lines=lines))
    print("done.")

# end


def dist_vector(a, b):
    ret = []
    for i in xrange(len(a)):
        ret.append(float(a[i] - b[i]))
    return ret

def normalize(data):
    if not data:
        return
    for i in xrange(len(data[0])):
        lb = 1e50
        ub = -1e50
        for j in data:
            lb = min(lb, j[i])
            ub = max(ub, j[i])
        if ub != lb:
            for j in data:
                j[i] = (j[i] - lb + 0.0) / (ub - lb)


from datetime import timedelta

from django.contrib.auth import get_user_model
from django.utils.timezone import now
from notifications.models import Notification

from openwisp_users.tests.utils import TestOrganizationMixin

from .. import settings as app_settings
from ..models import Graph, Metric, Threshold
from ..utils import create_database, get_db, query

User = get_user_model()
notification_queryset = Notification.objects.order_by('timestamp')
start_time = now()
ten_minutes_ago = start_time - timedelta(minutes=10)

class TestMonitoringMixin(TestOrganizationMixin):
    ORIGINAL_DB = app_settings.INFLUXDB_DATABASE
    TEST_DB = '{0}_test'.format(ORIGINAL_DB)

    @classmethod
    def setUpClass(cls):
        setattr(app_settings, 'INFLUXDB_DATABASE', cls.TEST_DB)
        create_database()

    @classmethod
    def tearDownClass(cls):
        get_db().drop_database(cls.TEST_DB)
        setattr(app_settings, 'INFLUXDB_DATABASE', cls.ORIGINAL_DB)

    def tearDown(self):
        query('DROP SERIES FROM /.*/')

    def _create_general_metric(self, **kwargs):
        opts = {'name': 'test_metric'}
        opts.update(kwargs)
        m = Metric(**opts)
        m.full_clean()
        m.save()
        return m

    def _create_object_metric(self, **kwargs):
        opts = kwargs.copy()
        if 'content_object' not in opts:
            opts['content_object'] = self._create_user()
        return self._create_general_metric(**opts)

    def _create_threshold(self, **kwargs):
        t = Threshold(**kwargs)
        t.full_clean()
        t.save()
        return t

    def _create_graph(self, metric=None, test_data=True):
        m = metric or self._create_object_metric()
        if test_data:
            m.write(3, time=now() - timedelta(days=2))
            m.write(6, time=now() - timedelta(days=1))
            m.write(9, time=now())
        g = Graph(metric=m)
        g.full_clean()
        g.save()
        return g


from django.urls import path
from .views import (
    PostListView,
    PostDetailView,
    PostCreateView,
    PostUpdateView,
    PostDeleteView,
)
from . import views

urlpatterns = [
    path('', PostListView.as_view(), name='diary-home'),     # path('', views.home, name='diary-home'),
    path('post/<int:pk>/', PostDetailView.as_view(), name='post-detail'), #pk primary key, int integer
    path('post/new/', PostCreateView.as_view(), name='post-create'),
    path('post/<int:pk>/edit/', PostUpdateView.as_view(), name='post-edit'),
    path('post/<int:pk>/delete/', PostDeleteView.as_view(), name='post-delete'),
    path('about/', views.about, name='diary-about'),
]


class Solution:
    def invalidTransactions(self, transactions: List[str]) -> List[str]:
        trans = [x.split(',') for x in transactions]
        trans = [(a, int(b), int(c), d) for a, b, c, d in trans]
        invalid = []
        for i, t in enumerate(transactions):
            if trans[i][2] > 1000:
                invalid.append(t)
            else:
                for j in range(len(trans)):
                    if j != i:
                        if abs(trans[i][1] - trans[j][1]) <= 60 and trans[i][0] == trans[j][0] and trans[i][3] != trans[j][3]:
                            if t == 'bob,536,217,toronto':
                                print(trans[i], trans[j])
                            invalid.append(t)
                            break
        return invalid


import socket, threading, pickle, time

TYPE_PLAYER_GOTO = 1
TYPE_SEND_MESSAGE = 2
TYPE_CONNECT = 3
TYPE_DISCONNECT = 4
TYPE_ERROR = 5
TYPE_TEST = 6
TYPE_USERLIST = 7

ERR_NAME_TAKEN = 1

class User:
	def __init__(self, name, addr):
		self.name = name
		self.addr = addr
		self.x = 0
		self.y = 0
		self.z = 0

class Server:
	def __init__(self, host="0.0.0.0", port=11360):
		self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
		self.sock.setblocking(False)
		self.sock.bind((host, port))

		self.clients = {}

		self.__main()

	def broadcast(self, msg, exceptions=[]):
		for n, cli in self.clients.items():
			if n in exceptions:
				continue
			self.sock.sendto(pickle.dumps(msg), cli.addr)

	def __main(self):
		while True:
			try:
				raw, addr = self.sock.recvfrom(4096)
				if not raw:
					continue
				mtype, data = pickle.loads(raw)

				if mtype == TYPE_CONNECT:
					userData = pickle.loads(data)
					if userData["name"] not in self.clients.keys():
						msg = f"{userData['name']} has entered the game!"
						userData["msg"] = msg
						userData["users"] = list(self.clients.values())

						user = User(userData["name"], addr)
						user.x = userData["x"]
						user.y = userData["y"]
						user.z = userData["z"]
						self.clients[userData["name"]] = user
						print(msg)

						self.broadcast((
							TYPE_CONNECT,
							pickle.dumps(userData)
						), exceptions=[userData["name"]])

						self.broadcast((
							TYPE_SEND_MESSAGE,
							pickle.dumps({
								"user": "[SERVER]",
								"msg": msg,
								"color": (245, 120, 66)
							})
						), exceptions=[userData["name"]])
					else:
						msg = (
							TYPE_ERROR,
							pickle.dumps({
								"code": ERR_NAME_TAKEN,
								"msg": f"[ SERVER ] :: The name \"{userData['name']}\" is already taken."
							})
						)
						self.sock.sendto(pickle.dumps(msg), addr)
				elif mtype == TYPE_DISCONNECT:
					del self.clients[data]
					msg = f"{data} has left the game..."
					self.broadcast((
						TYPE_DISCONNECT,
						pickle.dumps({
							"msg": msg,
							"name": data
						})
					))
					self.broadcast((
						TYPE_SEND_MESSAGE,
						pickle.dumps({
							"user": "[SERVER]",
							"msg": msg,
							"color": (245, 120, 66)
						})
					))
					print(msg)
				elif mtype == TYPE_PLAYER_GOTO:
					posData = pickle.loads(data)
					who = posData["name"]
					self.clients[who].x = posData["x"]
					self.clients[who].y = posData["y"]
					self.clients[who].z = posData["z"]
					self.broadcast((
						TYPE_PLAYER_GOTO,
						data
					))
				elif mtype == TYPE_TEST:
					print("Testing Socket! Message: " + data)
					self.sock.sendto(pickle.dumps((TYPE_TEST, "MSG: " + data)), addr)
				elif mtype == TYPE_USERLIST:
					name = data
					users = [x for x in self.clients.values() if x.name != name]
					self.sock.sendto(pickle.dumps((TYPE_USERLIST, users)), addr)
				elif mtype == TYPE_SEND_MESSAGE:
					msgData = pickle.loads(data)
					_from = msgData["user"]
					msg = msgData["msg"]
					print(f"[ {_from} ] :: {msg}")
					self.broadcast((
						TYPE_SEND_MESSAGE,
						data
					), exceptions=[_from])

			except socket.error as e:
				if e.args[0] == socket.errno.EWOULDBLOCK:
					time.sleep(1)
				else:
					print(e)
					break

		self.sock.close()

def new_thread(proc, args=()):
	th = threading.Thread(target=proc, args=args)
	th.daemon = True
	th.start()

class Client:
	def init(self, host="191.252.103.220", port=11360):
		self.addr = (host, port)
		self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
		self.sock.setblocking(False)

		self.running = True

		new_thread(self.__main)

	def onGotoTarget(self, data):
		pass

	def onUserList(self, users):
		pass

	def onConnect(self, data):
		pass

	def onDisconnect(self, data):
		pass

	def onError(self, data):
		pass

	def onMessageReceived(self, _from, msg, color):
		pass

	def send(self, msg):
		self.sock.sendto(pickle.dumps(msg), self.addr)

	def __main(self):
		while self.running:
			try:
				raw, addr = self.sock.recvfrom(4096)
				if not raw: continue

				mtype, data = pickle.loads(raw)

				if mtype == TYPE_CONNECT:
					userData = pickle.loads(data)
					self.onConnect(userData)
					print(userData["msg"])
				elif  mtype == TYPE_DISCONNECT:
					userData = pickle.loads(data)
					self.onDisconnect(userData)
					print(userData["msg"])
				elif mtype == TYPE_PLAYER_GOTO:
					posData = pickle.loads(data)
					self.onGotoTarget(posData)
				elif mtype == TYPE_ERROR:
					dat = pickle.loads(data)
					self.onError(dat)
					print(dat["msg"])
				elif mtype == TYPE_USERLIST:
					self.onUserList(data)
				elif mtype == TYPE_SEND_MESSAGE:
					msgData = pickle.loads(data)
					self.onMessageReceived(msgData["user"], msgData["msg"], msgData["color"])

			except:
				pass

		self.sock.close()

if __name__ == "__main__":
	# serv = Server(host="localhost")
	serv = Server()


# https://garantexio.github.io/?python#overview
import requests
import jwt

class garantex_API():
    def __init__(self, garantex_private_key = 'garantex_private.key', garantex_UID = 'garantex_UID') -> None:

        self.host = 'garantex.io' # для тестового сервера используйте stage.garantex.biz
        self.gar_costs = {}
        self.gar_costs['верхний']= -1
        self.gar_costs['нижний']= -1
    def get_ticker_price(self, ticker_id = 'USDT_RUB'):
        '''
        Функция, которая показывает текущий прайс тикера

        ticker_id - айди тикера (напр., 'USDT_RUB', 'BTC_RUB')
        '''
        ret = requests.get('https://' + self.host + '/api/v2/coingecko/tickers')

        response = ret.json()
        self.gar_costs['верхний']= -1
        self.gar_costs['нижний']= -1
        for ticker in response:
            if ticker['ticker_id'] == ticker_id:
                self.gar_costs['верхний'] = round(float(ticker['ask']),2)
                self.gar_costs['нижний'] = round(float(ticker['bid']),2)


def my_func(arg_1, arg_2, arg_3):
    """ Возвращает сумму двух наибольших чисел.

        В случае ошибки возвращает None
        Позиционные параметры:
        arg_1 -- число 1
        arg_2 -- число 2
        arg_3 -- число 3

    """
    try:
        return arg_1 + arg_2 + arg_3 - min(arg_1, arg_2, arg_3)
    except TypeError:
        return None

print(str(my_func(-1, 32, -103)))


from urllib.request import urlopen
from bs4 import BeautifulSoup
import re
import pandas as pd

html = urlopen('https://slickdeals.net/')
soup = BeautifulSoup(html.read(), 'html.parser')

items = []
prices = []
shippings = []
for products in soup.findAll('li', {'class':'fpGridBox'}):
    try:
        item = products.find('a', {'class':'itemTitle'})
        items.append(item.text)
    except AttributeError as e:
        continue

    try:
        price = products.find('div', {'class':'itemPrice'})
        p = re.findall(r'\$[0-9]*', price.text)
        if p:
            prices.append(p[0].replace('$',''))
        else:
            prices.append('')
    except AttributeError as e:
        prices.append('')

    try:
        shipping = products.find('div', attrs={'class': 'priceInfo'})
        p = re.findall(r'\+ Free Shipping', shipping.text)
        if p:
            shippings.append(p[0])
        else:
            shippings.append('')
    except AttributeError as e:
        shippings.append('')

df = pd.DataFrame({'Item name': items, 'Price': prices, 'Free Shipping': shippings})
df.to_csv('items.csv', index=False, encoding='utf-8')


#!/usr/bin/env python3

import json
import io
import requests
from zipfile import *
from sentence_transformers import SentenceTransformer
from PIL import Image
from transformers import CLIPTokenizer
import torch
import clip
from tqdm import tqdm
import text_preprocessor

PATH_PRODUCTS_DATASET = "data_encoder/data"
# Name of the zip file (without .zip extension)
NAME_DATASET = "data-1.json"
PATH_PRODUCTS_MODEL = "all-MiniLM-L6-v2"

# Load the CLIP model
device = "cuda" if torch.cuda.is_available() else "cpu"
model, preprocess = clip.load('ViT-L/14', device)

def load_products_dataset():
    with ZipFile(PATH_PRODUCTS_DATASET+"/"+NAME_DATASET+".zip") as dataZip:
        with dataZip.open(NAME_DATASET, mode='r') as dataFile:
            products_dataset = json.load(dataFile)
    return products_dataset

def get_product_sentence(model, product):
    color = text_preprocessor.process_colors(
        product.get('colorShade'), product.get('colorList'))
    fields = [product.get('nameSearch'), product.get('merchantName'),
              product.get('brand'), product.get('city'), text_preprocessor.process_string(product.get('uniqueSellingPoint')), color]
    if fields[0] is None:
        fields[0] = product.get('name')
    non_empty_fields = [field for field in fields if field is not None]

    if non_empty_fields:
        return ' '.join(non_empty_fields)
    else:
        return ""

def get_products_sentences(model, products_dataset):
    return [get_product_sentence(model, product) for product in tqdm(products_dataset, desc="Calculating product vectors")]

def get_product_image(product):
    product_img = f"{(product['mediumImage'])}"
    return "http://www.static-src.com/wcsstore/Indraprastha/images/catalog/full" + product_img

def load_products_embedding_model():
    return SentenceTransformer(PATH_PRODUCTS_MODEL)

def calculate_product_vector(model, product):
    product_sentence = get_product_sentence(product)
    return model.encode(product_sentence)

def calculate_products_vectors(model, products_dataset):
    products_sentences = get_products_sentences(model, products_dataset)
    return model.encode(products_sentences)

def calculate_product_image_vectors(product):
    try:
        image = get_product_image(product)
        r = requests.get(image, stream=True)
        # Load and preprocess the image
        validated_image = Image.open(r.raw)
        preprocess_image = preprocess(validated_image).unsqueeze(0).to(device)
        # Encode the image
        with torch.no_grad():
            image_encoding = model.encode_image(preprocess_image)[0]
            # print(image_encoding)
            return image_encoding
    except Exception:
        return []

def calculate_products_image_vectors_clip(products_dataset):
    products_images = []
    for product in tqdm(products_dataset, desc="Calculating product image vectors"):
        product_image_vector = calculate_product_image_vectors(product)
        products_images.append(product_image_vector)
    return products_images

def export_products_json(products_dataset):
    # Serializing json
    json_object = json.dumps(products_dataset, indent=2)
    # Writing to dataset.json
    with open(PATH_PRODUCTS_DATASET+"/"+"products-vectors-"+NAME_DATASET, "w") as outfile:
        outfile.write(json_object)

def truncate_sentence(sentence, tokenizer):
    """
    Truncate a sentence to fit the CLIP max token limit (77 tokens including the
    starting and ending tokens).

    Args:
        sentence(string): The sentence to truncate.
        tokenizer(CLIPTokenizer): Retrained CLIP tokenizer.
    """

    cur_sentence = sentence
    # print("new doc",cur_sentence)
    tokens = tokenizer.encode(cur_sentence)

    if len(tokens) > 77:
        # Skip the starting token, only include 75 tokens
        truncated_tokens = tokens[1:76]
        cur_sentence = tokenizer.decode(truncated_tokens)
        # Recursive call here, because the encode(decode()) can have different result
        return truncate_sentence(cur_sentence, tokenizer)

    else:
        return cur_sentence


import pandas as pd

def compute_alpha(stock_prices: list, index_price: list) -> float:
    """
    Là cách tính do mình nghĩ ra để đo lường sự tương quan giữa phần trăm tăng giảm mỗi ngày của 2 cố phiếu

    :param stock_prices:
    :param index_price:
    :return:
    """
    if len(stock_prices) != len(index_price) or len(stock_prices) == 0:
        raise Exception("Date stock and index provided must be same length")

    pd_stock_prices = pd.DataFrame(
        stock_prices, index=[price['date'] for price in stock_prices], columns=['adClose'])
    pd_index_prices = pd.DataFrame(
        index_price, index=[price['date'] for price in stock_prices], columns=['adClose'])

    list_pct_stock_prices = (pd_stock_prices['adClose'].pct_change())
    list_pct_index_prices = (pd_index_prices['adClose'].pct_change())

    r = list_pct_stock_prices * list_pct_index_prices

    print(list_pct_stock_prices)
    print(list_pct_index_prices)
    print(r)
    print(round(r.sum(), 3))

    return round(r.sum(), 3)


LIGHTING = True # Enable Lighting

DYNAMIC_LIGHTING = LIGHTING  # Totally useless variable, but is used sometimes instead of LIGHTING bc I forgot to
# change it

LIGHTING_TYPE = "EXPONENTIAL"  # Exponential -> Alpha lighting, darker
                               # Linear -> Indev lighting, brighter

BRIGHTNESS = 1  # Brightness setting, 0 is Moody, 1 is Bright

MIPMAP = True  # Enable Mipmaps
MIPMAP_TYPE = "LINEAR"  # Nearest -> Rough Smoothing / Linear -> Linear Smoothing
SMOOTHING = True  # Enable Minification Filter
BLUR = False  # Linearizes magnified textures (cool for HD textures I guess ?)


# requirements
import tweepy as tw
# API keys
consumer_key = 'XXXXXXXXXXXXXXXX'
consumer_secret = 'XXXXXXXXXXXXXXXX'
access_token = 'XXXXXXXXXXXXXXXX'
access_token_secret = 'XXXXXXXXXXXXXXXX'

# authentication
auth = tw.OAuth1UserHandler(
    consumer_key, consumer_secret, access_token, access_token_secret)
api = tw.API(auth)
client = tw.Client(
    bearer_token='XXXXXXXXXXXXXX')
# opening a file
fo = open("TwitterAPI.txt", "r+")

# lookup tweets by id
fo.write('lookup a tweets by id:'+'\n')
ids = ['1546514661587271683', '1545468528538648576', '1545407365918474242']
tweets = client.get_tweets(ids=ids, tweet_fields=[
                           'context_annotations', 'created_at', 'geo'])
for tweet in tweets.data:
    print(tweet)
    fo.write(str((tweet.text).encode('utf8')))
    fo.write('\n')

# search tweets about cats (-is not including retweets)
fo.write('search tweets about cats(user,tweet):'+'\n')
query1 = 'cat -is:retweet'
tweets = client.search_recent_tweets(query=query1, tweet_fields=['context_annotations', 'created_at'],
                                     expansions='author_id', max_results=100)
# Get users list from the includes object
users = {u["id"]: u for u in tweets.includes['users']}
# print 100 usernames that tweeted about cats
for tweet in tweets.data:
    if users[tweet.author_id]:
        user = users[tweet.author_id]
        print(user)
        print(tweet)
        fo.write(str(user)+'\n')
        fo.write(str((tweet.text).encode('utf8')))
        fo.write('\n')

# search tweets about StarWars not including retweets that has madia
fo.write('search tweets about StarWars(tweet,image url):'+'\n')
query2 = 'StarWars -is:retweet has:media'
tweets = client.search_recent_tweets(query=query2, tweet_fields=['context_annotations', 'created_at'],
                                     media_fields=['preview_image_url'], expansions='attachments.media_keys',
                                     max_results=100)
media = {m["media_key"]: m for m in tweets.includes['media']}
for tweet in tweets.data:
    attachments = tweet.data['attachments']
    media_keys = attachments['media_keys']
    print(tweet.text)
    fo.write(str((tweet.text).encode('utf8')))
    fo.write('\n')
    if media[media_keys[0]].preview_image_url:
        print(media[media_keys[0]].preview_image_url)
        fo.write(str(media[media_keys[0]].preview_image_url)+'\n')

# geting the number of tweets made about python in the last week by day
fo.write('number tweets about python in the last week sorted by day:')
query3 = 'python -is:retweet'
counts = client.get_recent_tweets_count(query=query3, granularity='day')
for count in counts.data:
    print(count)
    fo.write(str(count)+'\n')

# getting a users liked tweets
fo.write('lookup a user\'s liked tweets:'+'\n')
tweets = client.get_liked_tweets("745911914")
for tweet in tweets:
    print(tweet)
    # fo.write(str((tweet.text).encode('utf8')))
    # fo.write('\n')

# lookup users by id
fo.write('lookup a users by id:'+'\n')
ids = ['706864165143511041', '95675862', '847378752', '995461522359894016']
users = client.get_users(ids=ids)
for user in users.data:
    print(user.username)
    fo.write(str(user.username)+'\n')

# lookup user by username
fo.write('lookup a users by id:'+'\n')
users = client.get_users(usernames='FIFAWorldCup')
for user in users.data:
    print(user.id)
    fo.write(str(user.id)+'\n')

# getting a users followers
fo.write('lookup a user\'s followers(id, username, profile picture URL):'+'\n')
users = client.get_users_followers(
    id='2381578122', user_fields=['profile_image_url'])
for user in users.data:
    print(user.id)
    print(user.username)
    print(user.profile_image_url)
    fo.write(str(user.id)+'\n')
    fo.write(str(user.username)+'\n')
    fo.write(str(user.profile_image_url)+'\n')

# getting a users followings
fo.write('lookup a user\'s followings(username):'+'\n')
users = client.get_users_following(id="963156842598682624",max_results=50)
for user in users.data:
    print(user.username)
    fo.write(str(user.username)+'\n')

# getting a users mention
fo.write('lookup a user\'s mentions:'+'\n')
tweets = client.get_users_mentions(id='3320478908', tweet_fields=[
                                   'context_annotations', 'created_at', 'geo'])
for tweet in tweets.data:
    print(tweet)
    fo.write(str((tweet.text).encode('utf8')))
    fo.write('\n')

# getting users that liked a tweet, return User id, Name, username
fo.write('lookup users that liked a tweet(user id, name, username):'+'\n')
users = client.get_liking_users(id="1545437932353380354")
for user in users:
    print(user)
    fo.write(str(user)+'\n')


# -*- coding: utf-8 -*-
"""
Created on Tue Mar 01 12:06:18 2022

@author: mjenks
"""

def parse(puzzle_input):
    data = puzzle_input.strip()

    return data

def decompress(string):
    i = 0
    decompressed = ''
    while i < len(string):
        char = string[i]
        if char == '(':
            i += 1
            marker = string[i:].split(')')[0]
            vals = marker.split('x')
            a = int(vals[0]) #num of chars
            b = int(vals[1]) #times repeated
            marker_len = len(marker) + 1
            i += marker_len
            for n in range(b):
                decompressed += string[i:i+a]
            i += a
        else:
            decompressed += char
            i += 1
    return decompressed

def solve(puzzle_data):
    first = decompress(puzzle_data)
    weight = [1 for x in puzzle_data]
    index = 0
    length = 0
    while index < len(puzzle_data):
        char = puzzle_data[index]
        if char == '(':
            index +=1
            marker = puzzle_data[index:].split(')')[0]
            vals = marker.split('x')
            a = int(vals[0]) #num of chars
            b = int(vals[1]) #multiplier
            marker_len = len(marker) + 1
            index += marker_len
            for n in range(a):
                if n+index < len(weight):
                    weight[n+index] = b*weight[n+index]
        else:
            length += weight[index]
            index += 1

    return len(first), length

puzzle_path = "input_day9.txt"
with open(puzzle_path) as f:
    puzzle_input = f.read()

puzzle_data = parse(puzzle_input)
solution1, solution2 = solve(puzzle_data)

print(solution1)
print(solution2)


from .Parser import Parser
from src.main.bitr4qs.namespace import BITR4QS
from rdflib.term import URIRef

class SnapshotParser(Parser):

    @staticmethod
    def _get_valid_revision(identifier):
        from src.main.bitr4qs.revision.Snapshot import Snapshot
        return Snapshot(URIRef(identifier))

    @staticmethod
    def _parse_valid_revision(revision, p, o):

        if str(p) == str(BITR4QS.transactedAt):
            revision.transaction_revision = o

        elif str(p) == str(BITR4QS.validAt):
            revision.effective_date = o

        elif str(p) == str(BITR4QS.nameDataset):
            revision.name_dataset = o

        elif str(p) == str(BITR4QS.urlDataset):
            revision.url_dataset = o

        elif str(p) == str(BITR4QS.precedingSnapshot):
            revision.preceding_revision = o

    @staticmethod
    def _get_transaction_revision(identifier):
        from src.main.bitr4qs.revision.Snapshot import SnapshotRevision
        return SnapshotRevision(URIRef(identifier))

    @staticmethod
    def _parse_transaction_revision(revision, p, o):

        if str(p) == str(BITR4QS.snapshot):
            revision.add_valid_revision(o)


#!/usr/bin/python3
# -*- coding: UTF-8 -*-

"""
Code for the ELV USB-I2C Dongle
"""

import sys, serial, time

#from I2Cpytools import glob
from i2cusbdongles import util
from i2cusbdongles.dongles.Dongle import Dongle

class ELVdongle(Dongle):
    """Code for the ELV USB-I2C Dongle"""

    name        = "ELVdongle"
    short       = "dongle"

    # Serial port
    ser         = None                  # serial port handle
    baudrates   = [1200, 2400, 4800, 9600, 14400, 19200, 28800, 38400, 57600, 115200]
    baudrate    = baudrates[9]          # 115200
    usbport     = '/dev/ttyUSB0'        #
    timeout     = 0.2                   # what is needed?

    #              ELV name    xX   time   reqB   wrt/rec   info     rec
    pTemplate   = "ELV {:7s} {:2s} {:10s} [{:3d}] [{:3d}]  {:20s} == {}"

    def __init__(self):
        """opening the serial port and testing for correct dongle"""

        # open serial port
        try:
            self.ser = serial.Serial(self.usbport, self.baudrate, timeout=self.timeout)
            print("ELV dongle  ", end="")
            util.ncprint("opened at serial port: {} (baudrate:{}, timeout: {} sec)".format(self.usbport, self.baudrate, self.timeout))
        except Exception as e:
            util.exceptPrint(e, sys.exc_info(), "ERROR Serial port for ELV dongle could not be opened")
            util.ecprint("Is ELV dongle connected? - Exiting")
            sys.exit(1)

        # stop macro '<') and set 'y30' (in order to NOT get ACK and NACK)
        # and get info by '?'
        self.ELVwriteAdmin(b'<y30?', name=self.short, info="Init Dongle")
        rec = self.ELVreadAdmin(140, name=self.short, info="").strip()
        if rec.startswith(b"ELV"):
            util.fncprint("ELV Dongle initialized")
        else:
            util.fecprint("ELV Dongle did not respond - is it connected?")
            sys.exit(1)

    def ELVreset(self):
        """Reset the ELV dongle (takes 2 sec!)"""

        print("\n---- Reset")
        self.ELVwriteAdmin(b'z4b', name=self.short, info="Reset Dongle")
        time.sleep(2) # 1 sec is NOT enough
        rec = self.ELVreadAdmin(name=self.short, info="")
        print(rec.decode("utf-8") )

    def ELVshowInfo(self):
        """Show the startup info"""

        print("\n---- Show Info")
        self.ELVwriteAdmin(b'?', name=self.short, info="Show Info")
        rec = self.ELVreadAdmin(140, name=self.short, info="").strip()
        print(rec.decode("utf-8") )

    def ELVshowMacro(self):
        """ Print the Macro in Memory """

        print("\n---- Show Macrocode")
        self.ELVwriteAdmin(b'U', name=self.short, info="Show Macrocode" )
        rec = self.ELVreadAdmin(255+26, name=self.short, info="")
        rd = (rec.decode("utf-8")).split("\r\n")
        print(rd[0])
        for i in range(0, len(rd[1]),64):
            print(rd[1][i:i+64], "|")
        print(rd[2])

    def ELVwriteAdmin (self, command, name= "-", info = "no info"):
        """write to the ELV USB-I2C - only for its interal admin functions"""

        command = command.upper()
        wrt     = self.ser.write(command)  # wrt = no of bytes written
        print( self.pTemplate.format(name, "TA", util.strtime()[11:], len(command), wrt, info, command))

    def ELVreadAdmin (self, length = 100, name = "-", info = "no info"):
        """read from the ELV USB-I2C - only for its internal admin functions"""

        rec = self.ser.read(length)
        cnt = self.ser.in_waiting
        if cnt > 0:
            util.bell()
            print("Bytes waiting:", cnt)
            while True:            # read single byte until nothing is returned
                x = self.ser.read(1)
                if len(x) == 0: break
                rec += x
        print("ELVreadAdmin: len(rec), rec:", len(rec), rec)
        rec = rec.strip()
        print( self.pTemplate.format(name, "RA", util.strtime()[11:], length, len(rec), info, rec))

        return rec

    def askDongle(self, addr, data, rbytes, wait_time=0, name="no name", info="no info", doPrint=True, end="\n"):
        """ Function doc """

        self.ELVwriteData(addr, data, name=name, info=info, doPrint=doPrint)
        if rbytes > 0:
            if wait_time>2: time.sleep(wait_time/1000)
            self.ELVinitializeRead(addr, rbytes, name=name, doPrint=doPrint)
            answ = self.ELVreadData(length=rbytes, name=name, doPrint=doPrint)
            if doPrint: print(end=end)
        else:
            answ = None

        return answ

    def ELVwriteData (self, addr, data, name="", info ="", doPrint=True):
        """write commands for the sensors via the ELV USB-I2C"""

        wA      = "{:02X}".format((addr << 1) + 0)
        wdata   = ""
        for a in data: wdata += " {:02X}".format(a) # puts a space at the beginning

        command = bytes('S {}{} P'.format(wA, wdata), 'ASCII').upper()
        wrt     = self.ser.write(command)  # wrt = no of bytes written
        if doPrint: print(self.pTemplate.format(name, "TX", util.strtime()[11:], len(command), wrt, info, command))

    def ELVinitializeRead(self, addr, rbytes, name="", info="", doPrint=True):
        """initialize reading from the sensor via the ELV USB-I2C"""

        rA      = "{:02X}".format((addr << 1) + 1)  # read address
        rb      = "{:02X}".format(rbytes)           # no of bytes
        command = bytes('S {} {} P'.format(rA, rb), 'ASCII').upper()
        wrt     = self.ser.write(command)  # wrt = no of bytes written
        if doPrint: print(self.pTemplate.format("", "iR", util.strtime()[11:], len(command), wrt, info, command))

    def ELVreadData (self, length=1, name="", info="", doPrint=True):
        """ read data from the ELV USB-I2C """

        rec = self.ser.read(length * 3 + 2) # 3 chars per byte('FF ') + CR, LF
        cnt = self.ser.in_waiting
        if cnt > 0:
            util.bell()
            print("Bytes waiting:", cnt)
            while True:                # read single byte until nothing is returned
                x = self.ser.read(1)
                if len(x) == 0: break
                rec += x

        rec = rec.rstrip(b"\r\n")       # remove carridge return, linefeed, keep last space

        if doPrint: print( self.pTemplate.format("", "RX", util.strtime()[11:], length, len(rec), info, rec), end="")

        if not rec.strip().startswith(b"Solve ") or \
           not rec.strip().startswith(b"Err: "):        # conversion unless an error msg from dongle
            rlist = self.__getListfromRec(rec)
            return rlist
        else:
            return rec

    def close(self):
        """ Close the serial port """

        self.ser.close()
        print("ELV is closed")

    def __getListfromRec(self, rec):
        """ convert ASCII string from terminal to list of integer """
        # rec    : b'BE 6E 9A 69 32 00 ...'
        # returns: [190, 110, 154, 105, 50, 0, ...]

        rlist = []
        if len(rec) >= 3:
            for i in range(0, len(rec), 3):
                rlist.append(int(rec[i:i+3], 16))
        else: # empty record
            pass

        return rlist