#! /usr/bin/python3

from collections import Counter
import random
import logging
from concurrent.futures.process import ProcessPoolExecutor
import subprocess
import requests
import time
import argparse
import sys
import re
import json
import os, shutil
sys.path.append( f"{os.path.dirname(__file__)}/.." )

import helper
from config import *

"""
    Ability:
        - Get list of domains

    # Resources:
        + https://tls.bufferover.run/dns/?q=
        + https://crt.sh/?output=json&q=
        + https://chaos-data.projectdiscovery.io/{TARGET}.zip'
        - https://api.certspotter.com/v1/issuances?domain={TARGET}&include_subdomains=true&expand=dns_names&expand=cert
        - https://api.threatminer.org/v2/index.php
        - https://sonar.omnisint.io/subdomains/zarebin.ir

        tools:
            + gobuster
            + subfinder
            + amass
"""

SUBDOMAINS = []
IP = {}

class Subdomain:

    def __init__(self, target, **kwargs):
        logging.basicConfig(format="%(message)s", level=logging.INFO)

        # self.check_constructor_params(kwargs)
        self._opts = kwargs
        self.subdomains = {}

        # self.target = target
        self._sources = {
                    "urls": [
                        # self.bufferoverrun,
                        self.crt_sh,
                        # self.ominisint,
                        # self.projectdiscovery,
                        # self.rapiddns
                    ],
                    "tools": [
                        {
                            "name": "subfinder",
                            "cmd": "./subfinder -all -silent -nc -d {target}",
                            "subfinder_subs": [],
                            "tmp_output": "",
                        },
                        {
                            "name": "amass",
                            "cmd": "./amass enum -silent -d {target} -o {tmp_output} && cat {tmp_output} && rm {tmp_output}",
                            "amass_subs": [],
                            "tmp_output": f"{TOOLS_DIR}/amass.{target}",
                        },
                        # {
                        #     "name": "gobuster",     # brute-force subdomain
                        #     "cmd": "./gobuster dns -d {target} -w {wordlist} -z -q --no-error",
                        #     "gobuster_subs": [],
                        #     "tmp_output": "",
                        #     "wordlist": f"{PROJ_DIR}/wordlists/subs.meduim.txt",
                        # },
                    ]
                }

        self.runner(target)
        # print(self.subdomains)

    def check_constructor_params(self, kwargs):
        for k,v in kwargs.items():
            if k == "bruteforce" and v:
                for d in self._sources["tools"]:
                    if d["name"] == "gobuster":
                        pass

    def runner(self, target):
        results = {}

        workers = 8
        # with ProcessPoolExecutor(max_workers=workers) as executor:
        with ProcessPoolExecutor(max_workers=workers) as executor:
            for k,v in self._sources.items():
                if k == "urls":
                    for method in v:
                        e = executor.submit(method, target=target)
                        res = e.result() if not e.result() == None else []
                        # The method name is used for json key
                        name = method.__qualname__.split('.')[1]
                        results.update({ name: res })

                elif k == "tools":
                    for data in v:
                        if data["name"] == "gobuster" and not self._opts.get("bruteforce"): continue

                        e = executor.submit(helper.execute_tool, target=target, **data)
                        res = e.result() if not e.result() == None else []
                        results.update({data['name']: res})

        # self.ip_domain_relation(bufferoverrun_res)
        # self.recursive_and_refiner(target, results, refine=True)    # refiner
        # self.recursive_and_refiner(target)               # recursive check

        # print(json.dumps(results, indent=4))
        self.subdomains =  results

    def bufferoverrun(self, target):

        api_keys = [
            'BmxmnugMjy4uT9EaMVVoM1hGlFMQZVyj5GgkBznb', # fehej45650@seinfaq.com
            'vdhECNcdhW41TDPo6qmRvcOrgvxdovt8KXqQH5sf', # ponay57265@otodir.com
            '8ectV0KDUJa7D0JJiCREiT5DFY8Hp3y2ncVTPLAg', # jofihit265@lurenwu.com
            '6TaXNAK8CP207AIjRXTrf4q1r8WMizRa1XueufM4', # panav14359@rxcay.com
            'gm2StOWPLz4YZjrKudqIk8PQ2Ecl4FEa9bwoP7RN', # sohawep941@xitudy.com
        ]

        url = f"http://tls.bufferover.run/dns?q=.{target}"
        x_api_key = random.choise(api_keys)
        headers = {'x-api-key': x_api_key}
        res = requests.get(url, headers=headers).text
        logging.info(f"{ helper.get_colored('[+]', 'g') } Request to {url} (x-api-key: {x_api_key}) (status: {res.status_code})")

        res = json.loads(res)
        return  res['FDNS_A'] + \
                res['RDNS'] if res['RDNS'] else []

    def ip_domain_relation(self, bufferoverrun_res):
        for pair in bufferoverrun_res:
            ip, sub = pair.split(',')
            if re.match('^[0-9]+', ip):
                if ip not in IP:
                    IP.update( {ip: [sub]} )
                IP.get(ip).append(sub) if sub not in IP.get(ip) else []
            else:
                continue
            self.bufferoverrun_subs.append(sub)

    def rapiddns(self, target):
        cmd = """
            curl -s "https://rapiddns.io/s/__TARGET__?full=1" | \
            grep "<td>" | \
            sed -E "s/<(\/)?td>/\n/g" | \
            tr '<>' '\n' | \
            sed -E '/^$/d' | \
            grep -v "href=" | \
            grep -E "[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}" -B1 | \
            grep -iE "__TARGET__" | \
            sed -E "s/(,|\.)$//g" | \
            sort -u
        """.replace("__TARGET__", target)

        data = {
            "name": "rapiddns",
            "cmd": cmd,
            }

        urls = helper.execute_tool(target=target, **data)
        return list(Counter(urls).keys())

    def crt_sh(self, target):
        url = f"https://crt.sh/?q={target}&output=json"
        res = requests.get(url)
        status = str(res.status_code)

        count = 5
        while status != "200" and count > 0:
            try:
                res = requests.get(url)
                status = res.status_code
                count -= 1
                time.sleep(1)
            except Exception as e:
                print(e)

        logging.info(f"{ helper.get_colored('[+]', 'g') } Request to {url} (status: {res.status_code})")
        logging.info(f"{ helper.get_colored('[.]', 'c') } Parsing and appending 'crt.sh' output to the results")

        res = re.sub("(-|\"|\\\\n)", '\n', res.text.lower())
        subs = re.findall(f'.*\.{target}', res)
        subs = list(Counter(subs).keys())     # Uniq list

        return subs

    def recursive_and_refiner(self, target, subdomains, refine=False):
        tested = []
        subs = subdomains.copy()
        tested.append(target)

        for sub in subs:
            if sub.startswith('*.'):
                subs.remove(sub)
                sub = sub.replace('*.', '')
                subs.append(sub)

                if not tested.count(sub) and not refine: # sould be re-implemented (crt, bufferover, crobat)
                    tested.append(sub)
                    # subs = self.crt_sh(sub, recheck=True)
                    subs = self.crt_sh(sub)
                    if len(subs): subs.insert(-1, (s for s in subs) )

        return subs

    def projectdiscovery(self, target):
        target = target.rsplit('.', maxsplit=1)[0]
        url = f'https://chaos-data.projectdiscovery.io/{target}.zip'
        res = requests.get(url)

        logging.info(f"{ helper.get_colored('[+]', 'g') } Request to {url} (status: {res.status_code})")

        if res.status_code == '200':
            dir = f'/tmp/gath/{target}'
            path = f'{dir}/{target}.zip'
            logging.debug(f"{ helper.get_colored('[.]', 'y') } Creating {dir} directory")
            os.mkdir(dir)

            helper.write_zip_file(res.content, path)
            helper.unzip_file(path)

            logging.info(f"{ helper.get_colored('[.]', 'c') } Parsing and appending 'projectdiscovery' output to the results")

            subs = subprocess.check_output(f'cat {dir}/*{target}*', stderr=subprocess.STDOUT, shell=True).split()

            logging.debug(f"{ helper.get_colored('[.]', 'y') } Removing {dir} directory")
            os.rmdir(dir)

            return subs

    def ominisint(self, target):
        try:
            url = f'https://sonar.omnisint.io/subdomains/{target}'
            res = requests.get(url)
            logging.info(f"{ helper.get_colored('[+]', 'g') } Request to {url} (status: {res.status_code})")

            if res.status_code == 200:
                subs = json.loads(res.text)
                logging.info(f"{ helper.get_colored('[.]', 'c') } Appending the 'Omnisint' output to the results")
                return subs
        except Exception as e:
            logging.warning(f"{ helper.get_colored('[!]', 'r') } Exception: {e}")

    @property
    def get_subdomains(self): return self.subdomains

if __name__ == "__main__":
    try:
        target = sys.argv[1]
        SUBDOMAINS = Subdomain(target, bruteforce=False)
        # SUBDOMAINS = Subdomain(target).get_subdomains
        # SUBDOMAINS = list(Counter(SUBDOMAINS).keys())   # Uniqe list
        # print( json.dumps(SUBDOMAINS, indent=4) )
    except Exception as e:
        logging.error(f"{ helper.get_colored('[!]', 'r') } Exception: {e}")


from __future__ import annotations
from subsystems import *
from facade import WashingMachine

def client_code(facade: WashingMachine) -> None:
    """
    The client code works with complex subsystems through a simple interface
    provided by the Facade. When a facade manages the lifecycle of the
    subsystem, the client might not even know about the existence of the
    subsystem. This approach lets you keep the complexity under control.
    """

    print(facade.operation(), end="")

if __name__ == "__main__":
    # The client code may have some of the subsystem's objects already created.
    # In this case, it might be worthwhile to initialize the Facade with these
    # objects instead of letting the Facade create new instances.
    washing = washing.Washing()
    spinning = spinning.Spinning()
    rinsing = rinsing.Rinsing()

    facade = WashingMachine(washing, spinning, rinsing)
    client_code(facade)


from imageio import imread

for name in ['arrow', 'car1', 'car2', 'car3', 'car4', 'car5', 'wall']:
  image = imread('sprites/' + name + '.png')
  result = 'static color_t %s[] = {' % name
  for y in range(image.shape[0]):
    for x in range(image.shape[1]):
      r = image[y][x][0] >> 3
      g = image[y][x][1] >> 2
      b = image[y][x][2] >> 3
      rgb = (r << 11) | (g << 5) | b
      result += '0x%04x, ' % rgb
  print(result[:-2] + '};')


# Merge sort
# Uses Divide and Conquer
# Time complexity: O(nlogn)
# Space Complexity:O(n)

def merge(left, right):  # Function to merge sorted lists
    i, j = 0, 0
    result = []
    while i < len(left) and j < len(right):
        if left[i] <= right[j]:
            result.append(left[i])
            i += 1
        else:
            result.append(right[j])
            j += 1
    result += left[i:]
    result += right[j:]
    return result

def merge_sort(lst):  # Function to sort a list
    if len(lst) <= 1:  # If list has only 1 element or is empty
        return lst
    mid = len(lst) // 2
    left = merge_sort(lst[:mid])
    right = merge_sort(lst[mid:])
    return merge(left, right)

print(merge_sort([1, 9, 1, 22, 10, 0, -1, -222222]))


import torch, torch.nn as nn, torch.nn.functional as F
from . import BaseMetric
import numpy as np
from sklearn.metrics import roc_auc_score as sk_roc_auc_score

class Accuracy(BaseMetric):
    def __init__(self, key_output='seq_relationship_logits', key_input='next_sentence_label'):
        super().__init__()
        self.key_input = key_input
        self.key_output = key_output

    def forward(self, bert_output, bert_input, **kwargs):
        preds_labels = bert_output[self.key_output]
        preds_labels = preds_labels.argmax(-1)
        labels = bert_input[self.key_input]

        acc = (preds_labels == labels).sum() / labels.shape[0] * 100.
        return {'hate_acc' : acc}

class AreaUnderCurve(BaseMetric):
    def __init__(self, use_log=False, key_output='seq_relationship_logits', key_input='next_sentence_label'):
        super().__init__()
        self.key_input = key_input
        self.key_output = key_output
        self.use_log = use_log

    def forward(self, bert_output, bert_input, **kwargs):
        preds = bert_output[self.key_output].exp() if self.use_log else bert_output[self.key_output]
        preds = preds[:,1].cpu().numpy()
        labels = bert_input[self.key_input]
        labels = labels.cpu().numpy()
        try:
            auc = sk_roc_auc_score(labels, preds)
        except:
            auc = (np.round(preds) == labels).sum() / labels.shape[0] * 100.
        return {'hate_auc' : auc}


from apiclient.discovery import build
from googleapiclient.errors import HttpError
from pytube import PyTubeNotFoundException, PyTubeException
from pytube.parser import PyTubeParser
import re

YOUTUBE_API_SERVICE_NAME = "youtube"
YOUTUBE_API_VERSION = "v3"
YOUTUBE_CHANNEL_ID_PATTERN = r'^UC.{22}$'

class PyTubeClient(object):

    def __init__(self, api_key, http_mock=None):
        self.youtube_client = build(YOUTUBE_API_SERVICE_NAME, YOUTUBE_API_VERSION, developerKey=api_key)
        self.http_mock = http_mock
        self.parser = PyTubeParser()

    def is_channel_id(self, identifier):
        """
        Checks whether the supplied identifier conforms to the pattern of a Youtube channelId
        :param identifier: username or channel id
        :return: True if identifier matches pattern, False if not
        """

        if not identifier:
            raise PyTubeException(u'Identifier must be specified')

        return re.match(YOUTUBE_CHANNEL_ID_PATTERN, identifier) is not None

    def is_valid_identifier(self, identifier):
        """
        Checks to see whether the identifier supplied is a valid Youtube username.
        Returns true if it is, raises PyTubeNotFound if not.
        """
        if not identifier:
            raise PyTubeNotFoundException(u'You must specify an identifier')

        channels = self._get_channels_for(identifier)

        if channels:
            return True
        else:
            raise PyTubeNotFoundException(u'User/Channel {} not found'.format(identifier))

    def get_video(self, video_id):
        """
        Retrieves a single video record
        :param video_id: youtube id of the video to retrieve
        """
        try:
            video_response = self.youtube_client.videos().list(
                part='snippet,statistics,recordingDetails',
                id=video_id
            ).execute(http=self.http_mock)
        except HttpError:
            raise PyTubeNotFoundException('Video cannot be found')

        videos = video_response.get('items', [])
        if videos:
            video_record = videos[0]

            video = self.parser.parse_single_video(video_record)
            video.update(self.parser.parse_video_meta(video_record))

            return video

        raise PyTubeNotFoundException('Video cannot be found')

    def get_videos_for(self, identifier, **kwargs):
        """
        Retrieves a list of videos belonging to the specified user or channel, which is constructed via a number of
        Youtube Data API calls.
        If username is not valid, it raises PyTubeNotFound
        """

        mock_requests = kwargs.get('mocks', {})

        if not identifier:
            raise PyTubeNotFoundException(u'You must specify a username')

        channels = self._get_channels_for(identifier)

        if channels:
            playlist_id = channels[0].get('contentDetails', {}).get('relatedPlaylists', {}).get('uploads')
            if not playlist_id:
                raise PyTubeNotFoundException(u'Could not find the "uploads" playlist for {}'.format(identifier))

            playlist_items = self._get_playlist_items_for_playlist(playlist_id,
                                                                   http_mock=mock_requests.get('playlistItems'))

            if playlist_items:
                video_meta = self._get_video_meta_for_videos(playlist_items, http_mock=mock_requests.get('videos'))
                return self.parser.parse_videos(identifier, playlist_items, video_meta)
            return None

        else:
            raise PyTubeNotFoundException(u'User {} not found'.format(identifier))

    def _get_channels_for(self, identifier):
        """
        Retrieves the channel information for a given identifier. It will return some basic user information
        such as title and description (amongst others), but also returns the playlist ids belonging to that user
        """
        try:
            criteria = {
                'part': 'contentDetails'
            }

            if self.is_channel_id(identifier):
                criteria['id'] = identifier
            else:
                criteria['forUsername'] = identifier

            channels_response = self.youtube_client.channels().list(**criteria).execute(http=self.http_mock)
        except HttpError:
            raise PyTubeNotFoundException(u'Channel for {} cannot be found'.format(identifier))

        return channels_response.get('items', [])

    def _get_playlist_items_for_playlist(self, playlist_id, results_per_page=50, page_token=None, http_mock=None):
        """
        Retrieves a list of videos which belong to a playlist. The data returned in this response includes video title,
        description, thumbnails and video id
        :param playlist_id: id of the playlist to retrieve videos for
        :param results_per_page: number of results to return per request
        :param page_token: the token to retrieve subsequent pages of data
        :param http_mock: HttpMock object used within unit testing to mock the API response
        :return: list of dict items relating to videos belonging to the playlist
        """
        try:
            playlist_response = self.youtube_client.playlistItems().list(
                part='snippet',
                playlistId=playlist_id,
                maxResults=results_per_page,
                pageToken=page_token
            ).execute(http=http_mock)
        except HttpError:
            raise PyTubeNotFoundException('Playlist with id {} cannot be found'.format(playlist_id))

        playlist_items = playlist_response.get('items', [])
        videos = []

        if playlist_items:
            for item in playlist_items:
                item_snippet = item.get('snippet')
                if item_snippet:
                    videos.append(item_snippet)

        return videos

    def _get_video_meta_for_videos(self, playlist_items, http_mock=None):
        """
        Retrieves a list of meta data against a collections of playlistItems
        :param playlist_items: list of playlistItems
        :param http_mock: HttpMock object used within unittesting to mock the API response
        :return: list of dict items relating to video meta data belonging to the playlist items
        """
        try:
            video_response = self.youtube_client.videos().list(
                part='statistics,recordingDetails',
                id=map(lambda v: v['resourceId']['videoId'], playlist_items),
                maxResults=len(playlist_items)
            ).execute(http=http_mock)
        except HttpError:
            raise PyTubeNotFoundException('Videos cannot be found {}'.format(playlist_items))

        data = {}

        for video in video_response.get('items', []):
            data[video['id']] = video

        return data


from dataclasses import dataclass
from typing import Any

from pyramid.config import Configurator
from pyramid.request import Request
from sqlalchemy import text

from ..db_schemata import Account, ApiKey
from ..interfaces import IActor, IDBSession

@dataclass
class Actor:
    account_id: int | None
    account_id_raw: int | None
    api_key_id: str | None
    api_key_id_raw: str | None
    remote_addr: str | None
    user_agent: str | None

def factory(context: Any, request: Request) -> Actor:
    account_id = None
    account_id_raw = None
    api_key_id = None
    api_key_id_raw = None
    remote_addr = request.remote_addr
    user_agent = request.user_agent
    api_key_secret = request.headers.get("X-Api-Key")
    if api_key_secret:
        db = request.find_service(IDBSession, name="readonly")
        q = (
            db.query(
                # SQLAlchemyのキャッシュを回避するため、必ず属性単位で検索する。
                ApiKey.id.label("api_key_id"),
                ApiKey.deleted_at.label("api_key_deleted_at"),
                Account.id.label("account_id"),
                Account.deleted_at.label("account_deleted_at"),
            )
            .select_from(ApiKey)
            .join(Account)
            .filter(
                ApiKey.secret == api_key_secret,
                ApiKey.sys_deleted_at.is_(text("NULL")),
                Account.sys_deleted_at.is_(text("NULL")),
            )
        )
        row = q.one_or_none()
        if row:
            account_id_raw = row.account_id
            api_key_id_raw = row.api_key_id
            if row.api_key_deleted_at is None:
                api_key_id = api_key_id_raw
                if row.account_deleted_at is None:
                    account_id = account_id_raw
    return Actor(
        account_id=account_id,
        account_id_raw=account_id_raw,
        api_key_id=api_key_id,
        api_key_id_raw=api_key_id_raw,
        remote_addr=remote_addr,
        user_agent=user_agent,
    )

def includeme(config: Configurator) -> None:
    config.register_service_factory(factory, IActor)


"""Search all tiles in given radius from given point."""
from typing import Tuple

import numpy as np
import pandas as pd

from src import np_tiles_converter

def _xy_combinations(x_arr: np.ndarray, y_arr: np.ndarray) -> np.ndarray:
    """Fast cartesian product of two arrays.

    Given two arrays returns all combinations of their members.
    any x <-> any y
    """
    return np.dstack(np.meshgrid(x_arr, y_arr)).reshape(-1, 2)

def get_nearby_tiles(
    df_coords: pd.DataFrame, zoom: int, radius: float = 500
) -> pd.DataFrame:
    """Output all tiles in given distance from provided coordinates.

    For example if you have 100 locations and for each point you want to list
    all tiles which have centers in aprx 500 meters.

    Arguments:
        df_coords - have two columns "lon" and "lat" which store coordinates in degrees
        radius - radius in meters

    """
    # pylint: disable=too-many-locals
    assert "lon" in df_coords.columns
    assert "lat" in df_coords.columns
    assert radius > 0
    assert 1 <= zoom <= 23

    # we will need to add ids to all coordinates:
    n_coords = df_coords.shape[0]

    if n_coords > 30000:
        print("Too many points in dataset, calculations may take a while")

    coord_lat = df_coords["lat"].values
    coord_lon = df_coords["lon"].values
    coord_id = np.arange(0, n_coords)  ## simply indexing [0,1,2,3,4,...]

    # for each input coordinate
    # 1. get it's tile X,Y indexes
    # 2. tile center lat/lot coordinates
    idx_x_cent, idx_y_cent = np_tiles_converter.np_deg2idx(
        coord_lat, coord_lon, zoom=zoom
    )
    center_lat, center_lon = np_tiles_converter.np_idx2deg(
        idx_x_cent, idx_y_cent, zoom=zoom
    )

    # distance in meters to the closest adjacent tile
    lat_adj, lon_adj = np_tiles_converter.np_idx2deg(
        idx_x_cent + 1, idx_y_cent, zoom=zoom
    )
    x_tile_dist = np_tiles_converter.np_haversin(
        center_lat, center_lon, lat_adj, lon_adj
    )

    lat_adj, lon_adj = np_tiles_converter.np_idx2deg(
        idx_x_cent, idx_y_cent + 1, zoom=zoom
    )
    y_tile_dist = np_tiles_converter.np_haversin(
        center_lat, center_lon, lat_adj, lon_adj
    )

    # let's calculate how far we should searh for good tiles
    # left, right, down and up from given points
    # we will include all tiles in 'lim' from current tile
    # adding small number to prevent division on zero
    x_tiles_lim = np.ceil(radius / x_tile_dist + 0.0001) + 1
    y_tiles_lim = np.ceil(radius / (y_tile_dist + 0.0001)) + 1

    max_x_lim = x_tiles_lim.max()
    max_y_lim = y_tiles_lim.max()

    # To get full circle in given radius we need to check all nearby tiles:
    # by applying negative shifts (moving left/up) and positive shifts (moving right/down)
    # Because search is symmetric, let's only search one quarter of the circle
    # by checking only positive shifts

    shifts_xy = _xy_combinations(
        np.arange(0, max_x_lim + 1),
        np.arange(0, max_y_lim + 1),
    )
    shifts_xy = shifts_xy.astype(np.int32)
    n_shifts = shifts_xy.shape[0]

    # five columns: id, lat, lon, idx_x, idx_y
    center_coords = np.concatenate(
        [
            coord_id.reshape([-1, 1]),
            center_lat.reshape([-1, 1]),
            center_lon.reshape([-1, 1]),
            idx_x_cent.reshape([-1, 1]),
            idx_y_cent.reshape([-1, 1]),
        ],
        axis=1,
    )

    coords = np.repeat(center_coords, n_shifts, axis=0)

    # print (coords.shape)

    # same as np.repeat, but work a bit different
    shifts_x = np.tile(shifts_xy[:, 0], n_coords)
    shifts_y = np.tile(shifts_xy[:, 1], n_coords)

    # rough filter by delta tiles, given diagonal in the triangle
    #
    filter_rough = shifts_x + shifts_y <= max(max_x_lim, max_y_lim) * np.sqrt(2)
    coords = coords[filter_rough]
    shifts_x = shifts_x[filter_rough]
    shifts_y = shifts_y[filter_rough]

    # print (coords.shape)

    # all tiles candidates in required distance from given tile
    #
    inner_lat, inner_lon = np_tiles_converter.np_idx2deg(
        coords[:, 3] + shifts_x, coords[:, 4] + shifts_y, zoom=zoom
    )

    # calculate haversine distance and filter based on distance
    dist = np_tiles_converter.np_haversin(
        coords[:, 1], coords[:, 2], inner_lat, inner_lon
    )

    filt_dist = dist <= radius
    coords = coords[filt_dist]
    shifts_x = shifts_x[filt_dist]
    shifts_y = shifts_y[filt_dist]

    # print (coords.shape)

    nbr_id, nbr_x, nbr_y = _cover_full_circle(coords, shifts_x, shifts_y)

    nearby_tiles = pd.DataFrame(
        {
            "coord_id": nbr_id,
            "tile_idx_x": nbr_x,
            "tile_idx_y": nbr_y,
        }
    )

    return nearby_tiles

def _cover_full_circle(
    coords: np.ndarray, shifts_x: np.ndarray, shifts_y: np.ndarray
) -> Tuple[np.ndarray, np.ndarray, np.ndarray]:
    """Extrapolating shifts from circle Q1 to other quarters.

    Returns:
        point_id - id of initial point,
        nbr_x - x tile coord of a neigbour
        nbr_y - y tile coord of a neigbour
    """
    # neighbours in given distance
    point_id = np.array([])
    nbr_x = np.array([])
    nbr_y = np.array([])

    near_x = coords[:, 3] + 1 * shifts_x
    near_y = coords[:, 4] + 1 * shifts_y
    point_id = np.concatenate([point_id, coords[:, 0]])
    nbr_x = np.concatenate([nbr_x, near_x])
    nbr_y = np.concatenate([nbr_y, near_y])

    # to prevent duplication remove [0,0]
    filt = (shifts_x == 0) & (shifts_y == 0)
    shifts_x = shifts_x[~filt]
    shifts_y = shifts_y[~filt]
    coords = coords[~filt]

    near_x = coords[:, 3] + -1 * shifts_x
    near_y = coords[:, 4] + -1 * shifts_y
    point_id = np.concatenate([point_id, coords[:, 0]])
    nbr_x = np.concatenate([nbr_x, near_x])
    nbr_y = np.concatenate([nbr_y, near_y])

    # to prevent duplication remove [0,*] and [*,0]
    filt = (shifts_x == 0) | (shifts_y == 0)
    shifts_x = shifts_x[~filt]
    shifts_y = shifts_y[~filt]
    coords = coords[~filt]

    near_x = coords[:, 3] + -1 * shifts_x
    near_y = coords[:, 4] + 1 * shifts_y
    point_id = np.concatenate([point_id, coords[:, 0]])
    nbr_x = np.concatenate([nbr_x, near_x])
    nbr_y = np.concatenate([nbr_y, near_y])

    near_x = coords[:, 3] + 1 * shifts_x
    near_y = coords[:, 4] + -1 * shifts_y
    point_id = np.concatenate([point_id, coords[:, 0]])
    nbr_x = np.concatenate([nbr_x, near_x])
    nbr_y = np.concatenate([nbr_y, near_y])

    return point_id, nbr_x, nbr_y


# SIMPLE FUNCTION TESTS
# testing daysToIdx
print("dayToIdx test\n")
print(f"{dayToIdx('M')} \n")
print(f"{dayToIdx('T')} \n")
print(f"{dayToIdx('W')} \n")
print(f"{dayToIdx('R')} \n")
print(f"{dayToIdx('F')} \n")

for i in days_arr:
    print(f"{i} is at index {dayToIdx(i)}")

# testing idxToDay
print("\nidxToDay test\n")
for j in range(0, 5):
    print(f"The {j}-th day is " + days_arr[j])

# testing timeToIdx:
print("\ntimeToIdx test\n")
for i in range(14, 44):
    i = i/2.0
    print(f"time {i} is at index {timeToIdx(i)}")

# testing idxToTime:
print("\nidxToTime test\n")
for i in range(0, 30):
    print(f"idx {i} stores time {idxToTime(i)}")

# SCHEDULE TEST

urmom = Schedule()

for i in range(14, 18):
    i = i/2.0
    urmom.setUnavailable("MTWRF", i)

urmom.setUnavailable("MWF", 11)
urmom.setUnavailable("MWF", 11.5)
for i in range(24, 30):
    i = i/2.0
    urmom.setUnavailable("W", i)

for i in range(18, 24):
    i = i/2.0
    urmom.setUnavailable("TR", i)

urmom.setUnavailable("TR", 7.5)
urmom.setUnavailable("M", 10)

print(urmom)

print(str(urmom.checkAvailable((7.0, 9.0), "TR")))
print(str(urmom.checkAvailable((7.0, 9.0), "MWF")))

aas = readFile('.github/bigboi.csv', "CS")

print(aas)

print(nearestTimes([3.50, 5.5]))

for i in aas.courses[0].sections:
    for j in i:
        print(urmom.checkAvailable(nearestTimes(j.time), j.days))

x = classWorks(aas.courses[0], urmom)

'''for a in x:
    for b in a:
        print(str(b))'''

y = subjectOptions(aas, urmom)

for a in y:
    #print(key)
    for b in a:
        for c in b:
            print(str(c))

print(y)

toCSV(y)

#print(makeDictForJSON(y))

#with open("sample.json", "w") as outfile:
urmom2 = json.dumps(makeDictForJSON(y), indent = 4)
#print(urmom2)

with open("sample.json", "w") as outfile:
    json.dump(makeDictForJSON(y), outfile)

atlasSched = Schedule()

for i in range(22, 26):
    i = i/2
    atlasSched.setUnavailable("MWF", i)

for i in range(28, 32):
    i = i/2
    atlasSched.setUnavailable("MWF", i)

for i in range(22, 24):
    i = i/2
    atlasSched.setUnavailable("TR", i)

print(json.dumps(makeDictForJSON(subjectOptions(readFile(".github/bigboi.csv", "CS"), atlasSched)), indent = 4))

input = "CS+09:10AM - 10:30AM,02:00PM - 03:30PM+08:00AM - 12:00PM,04:30PM - 06:15PM+08:15AM - 11:00AM,02:15PM - 04:00PM+09:00AM - 04:00PM+08:00AM - 09:00AM"
doEverything(input)


"""
Module for interaction with remote servers.

@author: Raoul Schram
"""

import os
import re
import copy
import shlex
try:
    import subprocess32 as subprocess
except ImportError as e:
    import subprocess

from string import Template

from batchgen.util import batch_dir
from batchgen.backend.hpc import make_check_clean_directory

def _ssh_template():
    """ SSH command to log into remote server. """
    ssh = Template("""
    ssh -q -o ConnectTimeout=10 -o ServerAliveInterval=10 ${user}${server} \
    'cd ${remote_dir}; batchgen ${command_file} ${config_file} || \
    echo "Error: while executing batchgen."'
""")
    return ssh

def _remote_submit_template():
    sub_templ = Template("""#!/bin/bash

    ssh -q -o ConnectTimeout=10 -o ServerAliveInterval=10 ${user}${server} \
    'cd ${remote_dir}; ${exec_line}'
""")
    return sub_templ

def parse_remote_msg(msg):
    """ Figure out the different components of the output of the remote script.

    Arguments
    ---------
    msg: str
        Unicode string that encodes the output.

    Returns
    -------
    error_msg: str
        List of error messages, empty list means no errors.
    exec_line: str
        Line to execute on remote (anything not starting with #/*/Error
    info_msg: str
        Anything starting with asterixes (*)
    """
    msg = msg.split("\n")
    exec_line = ""
    info_msg = ""
    error_msg = []
    for line in msg:
        sw_hash = re.match(r'^#', line) is not None
        sw_asterix = re.match(r'^\*', line) is not None
        sw_error = re.match(r'^Error', line) is not None
        if sw_asterix:
            info_msg += line+"\n"
        elif line == "" or sw_hash:
            pass
        elif sw_error:
            error_msg.append(line)
        else:
            exec_line += line

    return error_msg, exec_line, info_msg

def send_batch_ssh(command_string, config, force_clear=False):
    """ Prepare a batch on a remote server.

    Arguments
    ---------
    command_file: str
        File with commands to execute.
    config: str
        ConfigParser configuration, read from file.
    """

    if "user" in config.options("CONNECTION"):
        user = config.get("CONNECTION", "user")+"@"
    else:
        user = ""
    server = config.get("CONNECTION", "server")
    remote_dir = config.get("CONNECTION", "remote_dir")
    backend = config.get("BACKEND", "backend")
    job_name = config.get("BATCH_OPTIONS", "job_name")
    pre_post_file = config.get("BATCH_OPTIONS", "pre_post_file")

    # Write new configuration file with remote_dir as base_dir.
    # WARNING: this is not a deep copy, so the var config is also changed.
    remote_pp_file = "remote_pp_{job_name}.sh".format(job_name=job_name)
    # Absolute path (from $HOME) to copy pre_post_file.
    long_remote_pp_file = os.path.join(remote_dir, remote_pp_file)
    new_config = copy.copy(config)
    new_config.remove_section("CONNECTION")
    new_config.set("BATCH_OPTIONS", "base_dir", remote_dir)
    new_config.set("BATCH_OPTIONS", "pre_post_file", remote_pp_file)
    new_config_file = "remote_cfg.ini"
    with open(new_config_file, "w") as f:
        new_config.write(f)

    new_command_file = "remote_command_script.sh"
    with open(new_command_file, "w") as f:
        f.write(command_string)

    # Copy the command file and the configuration file to remote server.
    copy_command = "scp -q {command_file} {new_config_file} " \
                   "{user}{server}:{remote_cf}"
    copy_command = copy_command.format(command_file=new_command_file,
                                       user=user, server=server,
                                       remote_cf=remote_dir,
                                       new_config_file=new_config_file)
    # Copy pre_post_file to remote server.
    subprocess.run(shlex.split(copy_command))

    copy_command = "scp -q {pp_file} {user}{server}:{remote_pp_file}"
    copy_command = copy_command.format(pp_file=pre_post_file, user=user,
                                       server=server,
                                       remote_pp_file=long_remote_pp_file)
    subprocess.run(shlex.split(copy_command))

    # SSH into the remote server and run batchgen with new config file.
    ssht = _ssh_template()
    ssh_command = ssht.safe_substitute(user=user, server=server,
                                       remote_dir=remote_dir,
                                       command_file=new_command_file,
                                       config_file=new_config_file)
    res = subprocess.run(shlex.split(ssh_command), stdout=subprocess.PIPE,
                         stderr=subprocess.PIPE)
    msg = res.stdout.decode('utf-8')

    # Check for error at remote server.
    error_msg, exec_line, info_msg = parse_remote_msg(msg)
    if len(error_msg) != 0:
        print("----- Remote error at {server} -----".format(server=server))
        print(msg)
        print("----- stderr -----")
        print(res.stderr.decode('utf-8'))
        return

    # Output directory for script that remotely submits the script.
    output_dir = batch_dir(backend, job_name, remote=True)
    if not make_check_clean_directory(output_dir, force_clear=force_clear):
        return

    sub_templ = _remote_submit_template()
    sub_script = sub_templ.safe_substitute(user=user, server=server,
                                           remote_dir=remote_dir,
                                           exec_line=exec_line)
    sub_file = os.path.join(output_dir, "submit_remote.sh")
    with open(sub_file, "w") as f:
        f.write(sub_script)
    os.chmod(sub_file, 0o755)

    # Print instructions and info
    print(info_msg)
    print(sub_file)


import time
import os
from Sensors import *
from Publishers import SensorPublisher
import json

if __name__ == "__main__":
    currDir = os.path.dirname(os.path.abspath(__file__))
    settings_file_path = os.path.join(currDir,'..','settings.json')

    settingsFile = open(settings_file_path)
    settingsDict = json.load(settingsFile)
    settingsFile.close()
    baseTopic = settingsDict["baseTopic"]
    deviceID = "111"
    userAssociationID = "1"
    baseTopic += userAssociationID + "/sensor"
    deviceName = "BatteryChargeSimulator1"
    catalogURL = settingsDict["Catalog_url_Carlo"]
    sensor = BatteryChargeSensor(deviceID, deviceName, userAssociationID, baseTopic, True)
    topic = sensor.getMQTTtopic()

    broker = "mqtt.eclipseprojects.io" # to be updated with the relative reference
    port = 1883 # same
    publisher = SensorPublisher("csim48rPisensor" + deviceID, deviceID, deviceName, userAssociationID, sensor.getMeasureType(), broker, port, topic, catalogURL)
    publisher.startOperation()

    while True:
        publisher.rPi_publish(topic, sensor.sensor_update(), 2)
        publisher.sendLastUpdateToCatalog(sensor.getValue())
        time.sleep(5)


from time import time

n = int(input())
A=input().split()
A_ = A.copy()

start = time()
while True:
    for i in range(len(A)//2):
        if int(A[i * 2 - i]) > int(A[i * 2 + 1 - i]):
            A.pop(i * 2 + 1 - i)
        else:
            A.pop(i * 2 - i)
    if len(A) == 2:
        break

if int(A[0]) > int(A[1]):
    A.pop(0)
else:
    A.pop(1)

print(A_.index(A[0]) + 1)

elapsed_time = time() - start

print(elapsed_time)


import importlib
import inspect
from typing import List, Optional

from IPython.display import display
from lamin_utils import colors, logger
from lamindb_setup import settings
from lamindb_setup._init_instance import get_schema_module_name
from lnschema_core import Registry

def view(
    n: int = 7, schema: Optional[str] = None, registries: Optional[List[str]] = None
):
    """View data.

    Args:
        n: Display the last `n` rows of a table.
        schema: Schema module to view. Default's to
            `None` and displays all schema modules.
        registries: List of Registry names. Defaults to
            `None` and lists all ORMs.

    Examples:
        >>> ln.view()
    """
    if schema is not None:
        schema_names = [schema]
    else:
        schema_names = ["core"] + list(settings.instance.schema)

    for schema_name in schema_names:
        schema_module = importlib.import_module(get_schema_module_name(schema_name))

        all_registries = {
            orm
            for orm in schema_module.__dict__.values()
            if inspect.isclass(orm)
            and issubclass(orm, Registry)
            and orm.__name__ != "Registry"
        }
        if registries is not None:
            filtered_registries = {
                orm for orm in all_registries if orm.__name__ in registries
            }
        else:
            filtered_registries = all_registries
        if len(schema_names) > 1:
            section = f"* module: {colors.green(colors.bold(schema_name))} *"
            section_no_color = f"* module: {schema_name} *"
            logger.print("*" * len(section_no_color))
            logger.print(section)
            logger.print("*" * len(section_no_color))
        for orm in sorted(filtered_registries, key=lambda x: x.__name__):
            if hasattr(orm, "updated_at"):
                df = orm.filter().order_by("-updated_at")[:n].df()
            else:
                # need to adjust in the future
                df = orm.filter().df().iloc[-n:]
            if df.shape[0] > 0:
                logger.print(colors.blue(colors.bold(orm.__name__)))
                display(df)


#
# 1. UnderStanding Unsupervised Learning
# 선존재하는 라벨이 없는 데이터 셋에서 이전에는 감지되지 않았던 패턴을 인간의 개입을 최소화하며 찾아내는 것.
# 사람이 라벨링한 데이터를 사용하는 supervised learning과 달리 unsupervised learning (self-organization)은
# input에 대해 확률 밀도 함수를 허용

# unsupervised learning의 주된 methodsms cluster analysis, principal component analysis가 있다.

# i) Cluster analysis
# 데이터 포인트를 비슷한 것들끼리 여러 그룹으로 나누는 작업

# ii) Principal Component Analysis (PCA)
# PCA는 통계적인 처리 방식으로 dataset의 n개의 축을
# 주성분으로 알려진 새로운 직교하는 n개의 축으로 변환하는 것을 의미한다.
# 관측값이 상호 연관된 여러 정량적 종속 변수에 의해 설명되는 데이터를 분석할 때 사용된다.
# 데이터에서 중요 정보를 추출후, 이 정보를 pa라고 하는 새로운 직교 변수 집합으로 표현

# K-means, DBSCAN, t-SNE 등의 알고리즘을 이용해 이를 구현한다.

from sklearn.cluster import KMeans
from sklearn import datasets
import matplotlib.pyplot as plt

iris = datasets.load_iris()
X = iris.data

# KMeans
km = KMeans(n_clusters=3)
km.fit(X)
y_km = km.predict(X)

# plot 3 clusters
plt.scatter(
    X[y_km == 0, 0], X[y_km == 0, 1],
    s=50, c='lightgreen',
    marker='s', edgecolor='black',
    label='cluster 1'
)

plt.scatter(
    X[y_km == 1, 0], X[y_km == 1, 1],
    s=50, c='orange',
    marker='o', edgecolor='black',
    label='cluster 2'
)

plt.scatter(
    X[y_km == 2, 0], X[y_km == 2, 1],
    s=50, c='lightblue',
    marker='v', edgecolor='black',
    label='cluster 3'
)

# plot the centroids
plt.scatter(
    km.cluster_centers_[:, 0], km.cluster_centers_[:, 1],
    s=250, marker='*',
    c='red', edgecolor='black',
    label='centroids'
)
plt.legend(scatterpoints=1)
plt.grid()

plt.savefig('cluster.png')


import cv2, sys

# Print the HSV value of the pixel just clicked
def mouse_event(event, x, y, _, __):
    if event == cv2.EVENT_LBUTTONUP:
        pixel_value = frameGray[y,x]
        print(f"({x:3},{y:3}) -> {pixel_value}")

# Camera number can be given as a command line argument
# Note that camera number may change by rebooting or re-connection!
cap = cv2.VideoCapture(cv2.CAP_DSHOW+2 if len(sys.argv) == 1 else int(sys.argv[1]))

# Set frame size; for Logicool C270n, allowed values include
# 640x480, 320x240 and 160x120.
# High-resolution images require more processing cost.
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 320);
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 240);

# Prepare a window for the original image
cv2.namedWindow('src', cv2.WINDOW_NORMAL)
cv2.setMouseCallback('src', mouse_event)
cv2.moveWindow('src', 120,0)
cv2.resizeWindow('src',320,240)

# Another window for the transformed image
cv2.namedWindow('circles', cv2.WINDOW_NORMAL)
cv2.moveWindow('circles', 460,0)
cv2.resizeWindow('circles', 320,240)

while True:
    # (1) カメラからの入力画像1フレームをframeに格納
    _, frame = cap.read()
    frameGray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    # (2)ハフ変換のための前処理（画像を平滑化しないと誤検出が出やすい）
    frameGray = cv2.GaussianBlur(frameGray, (11,11), 0)

    # (3)ハフ変換による円の検出と検出した円の描画
    h, w = frameGray.shape
    circles = cv2.HoughCircles(frameGray, cv2.HOUGH_GRADIENT,
              dp=1, minDist=3, param1=20, param2=70, minRadius=10, maxRadius=max(h,w))
    if circles is not None:
        circles = circles.squeeze(axis=0)
        for i in range(0, min(3, len(circles))):
            p = circles[i]
            cv2.circle(frame, (int(p[0]),int(p[1])), 4, (0,255,0), -1, 8, 0)
            cv2.circle(frame, (int(p[0]),int(p[1])), int(p[2]), (0,0,255), 6-2*i, 8, 0)

    # (4) 検出結果表示用のウィンドウを確保し表示する
    cv2.imshow('circles', frame)
    cv2.imshow('src', frameGray)

    # Press 'q' in the frame window to exit loop
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

# cap.release()
# cv2.destroyAllWindows()


def getPercentageAmount(creditAmount, creditPercentage):
    return (creditAmount * creditPercentage)/100

isAmountIncorrect = True
while(isAmountIncorrect):
    print("Enter credit amount:")
    try:
        creditAmount = int(input())
        isAmountIncorrect = False
    except:
        print("Credit amount has to be a figure!")

isPercentageIncorrect = True
while(isPercentageIncorrect):
    print("Enter credit percentage:")
    try:
        creditPercentage = int(input())
        isPercentageIncorrect = False
    except:
        print("Credit percentage has to be a figure!")

overpayment = getPercentageAmount(creditAmount, creditPercentage)
payment = creditAmount + overpayment

print("Total payment amount: " + str(payment))
print("Overpayment amount: " + str(overpayment))


# -*- coding: utf-8 -*-
"""
Created on Thu Jul 21 17:44:39 2016

by Matthäus Deutsch
Computer Science HU Berlin
Project: "Kaggle Bimbo Challenge"
"""

import numpy as np
import data

#%% Simple Mean-based Modell

# define the logmean
def logmean(x):
    return np.exp(np.mean(np.log(x+1)))-1

# load the training data
print('load training data')
df_train = data.get_train(nrows = 10000)

# compute the means for different configurations
print('compute means')
mean_tab = df_train.groupby('ProductId').agg({'AdjDemand': logmean})
mean_tab2 = df_train.groupby(['ProductId', 'ClientId']).agg({'AdjDemand': logmean})
global_mean = logmean(df_train['AdjDemand'])

# generate estimation for each ProductID-ClientID-pair
def estimate(key):
    key = tuple(key) # key needs to be a tuple
    try:
        est = mean_tab2.at[key,'AdjDemand']
    except KeyError:
        try :
            est = mean_tab.at[key[0],'AdjDemand']
        except KeyError:
            est = global_mean
    return est

# load the test data
print('load test data')
df_test = data.get_test(nrows=10000)
print('compute predictions')
df_test['Demanda_uni_equil'] = df_test[['ProductId', 'ClientId']].\
                apply(lambda x:estimate(x), axis=1)
df_submit = df_test[['id', 'Demanda_uni_equil']]
print(df_submit.shape)
df_submit = df_submit.set_index('id')
df_submit.to_csv('naive_product_client_logmean.csv')


import torch
from torch import optim
from torch.utils.data import DataLoader
from torchvision.datasets import MNIST
from torchvision.transforms import transforms
from capsnet import CapsNet, CapsuleLoss
import capsnet
import config
from torch.utils.data import ConcatDataset
import manager_datasets as datasets_control

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

def get_data_loader_A_APTOS(datasets, size):

    test_transform = transforms.Compose([
                                         transforms.Grayscale(num_output_channels=1),
                                         transforms.Resize([size, size], transforms.InterpolationMode("bicubic")),
                                         transforms.ToTensor(),
                                         #transforms.Normalize((0.485, 0.456, 0.406), (0.229, 0.224, 0.225))
                                         transforms.Normalize((0.5), (0.5))
                                         ])

    dataset_list = []

    for key in datasets.keys():
        datasets[key][0]["level"].replace({2: 1, 3: 1, 4: 1}, inplace=True)
        datasets[key][0].reset_index(inplace=True)
        dataset_list.append(datasets_control.dataset(datasets[key][0], f'{datasets[key][1]}', image_transform=test_transform))

    dataset_full = ConcatDataset(dataset_list)
    train = DataLoader(dataset_full, batch_size=config.BATCH, shuffle=True, generator=torch.Generator().manual_seed(1))

    return train

def main(train_loader, test_loader):
    # Load model
    model = CapsNet().to(device)
    criterion = CapsuleLoss()
    optimizer = optim.Adam(model.parameters(), lr=1e-3)
    scheduler = optim.lr_scheduler.ExponentialLR(optimizer, gamma=0.96)

    # Train
    model.train()
    for ep in range(config.EPOCHS):
        batch_id = 1
        correct, total, total_loss = 0, 0, 0.
        for images, labels in train_loader:
            optimizer.zero_grad()
            images = images.to(device)
            labels = torch.eye(10).index_select(dim=0, index=labels).to(device)
            logits, reconstruction = model(images)

            # Compute loss & accuracy
            loss = criterion(images, labels, logits, reconstruction)
            correct += torch.sum(
                torch.argmax(logits, dim=1) == torch.argmax(labels, dim=1)).item()
            total += len(labels)
            accuracy = correct / total
            total_loss += loss
            loss.backward()
            optimizer.step()
            print('Epoch {}, batch {}, loss: {}, accuracy: {}'.format(ep + 1,
                                                                      batch_id,
                                                                      total_loss / batch_id,
                                                                      accuracy))
            batch_id += 1
        scheduler.step(ep)
        print('Total loss for epoch {}: {}'.format(ep + 1, total_loss))

    # Eval
    model.eval()
    correct, total = 0, 0
    for images, labels in test_loader:
        # Add channels = 1
        images = images.to(device)
        # Categogrical encoding
        labels = torch.eye(10).index_select(dim=0, index=labels).to(device)
        logits, reconstructions = model(images)
        pred_labels = torch.argmax(logits, dim=1)
        correct += torch.sum(pred_labels == torch.argmax(labels, dim=1)).item()
        total += len(labels)
    print('Accuracy: {}'.format(correct / total))

    # Save model
    torch.save(model.state_dict(), './model/capsnet_ep{}_acc{}.pt'.format(config.EPOCHS, correct / total))

if __name__ == '__main__':
    # params = capsnet.get_capsule_params(config.IMG_SIZE)
    # print("Conv params: ", params)

    train, val, test = datasets_control.get_datasets()
    train = get_data_loader_A_APTOS(train, config.IMG_SIZE)
    valid = get_data_loader_A_APTOS(val, config.IMG_SIZE)
    main(train, valid)


import json
import unittest

from pymongo.errors import BulkWriteError, DuplicateKeyError

from tests.implementations import TweetMongoRepository, WeiboMongoRepository

class TestMongoRepository(unittest.TestCase):

    def test_add(self):
        repo = TweetMongoRepository('test_add')
        tweet = {'id': 1, 'text': 'tweet1'}
        repo.add(tweet)
        tweet = repo.get(1)
        expected = {'_id': 1, 'id': 1, 'text': 'tweet1'}
        self.assertEqual(expected, tweet)

    def test_add_errors_when_duplicate_disallowed(self):
        repo = TweetMongoRepository('test_add_errors_when_duplicate_disallowed')
        tweet = {'id': 1, 'text': 'tweet1'}
        repo.add(tweet)
        error = False
        try:
            repo.add(tweet, error_duplicates=True)
        except DuplicateKeyError:
            error = True
        self.assertTrue(error)

    def test_add_does_not_error_when_duplicate_ignored(self):
        repo = TweetMongoRepository(
            'test_add_does_not_error_when_duplicate_ignored')
        tweet = {'id': 1, 'text': 'tweet1'}
        repo.add(tweet)
        error = False
        try:
            repo.add(tweet, error_duplicates=False)
        except DuplicateKeyError:
            error = True
        self.assertFalse(error)

    def test_add_many(self):
        repo = TweetMongoRepository('test_add_many')
        tweets = [
            {'id': 1, 'text': 'tweet1'},
            {'id': 2, 'text': 'tweet2'},
        ]
        repo.add_many(tweets, error_duplicates=False)
        tweets = list(repo.all())
        expected = [
            {'_id': 1, 'id': 1, 'text': 'tweet1'},
            {'_id': 2, 'id': 2, 'text': 'tweet2'},
        ]
        self.assertEqual(expected, tweets)

    def test_add_many_sets_id(self):
        repo = WeiboMongoRepository('test_add_many')
        with open('tests/data/Result_6.json') as f:
            data = json.loads(f.read())
        self.assertEqual(5, len(data))
        repo.add_many(data)
        posts = list(repo.all())
        self.assertEqual(5, len(posts))
        for x in posts:
            self.assertEqual(x['_id'], x['mid'])

    def test_add_many_errors_duplicate_when_requested(self):
        repo = TweetMongoRepository(
            'test_add_many_errors_duplicate_when_requested')
        tweets = [
            {'id': 1, 'text': 'tweet1'},
            {'id': 2, 'text': 'tweet2'},
            {'id': 2, 'text': 'tweet2'},
        ]
        error = False
        try:
            repo.add_many(tweets, error_duplicates=True)
        except ValueError:
            error = True
        self.assertTrue(error)

    def test_add_many_inserts_non_duplicates_when_errors_ignored(self):
        repo = TweetMongoRepository(
            'test_add_many_inserts_non_duplicates_when_errors_ignored')
        repo.add({'id': 1, 'text': 'tweet1'})
        tweets = [
            {'id': 1, 'text': 'tweet1'},
            {'id': 2, 'text': 'tweet2'},
            {'id': 3, 'text': 'tweet3'},
        ]
        error = False
        try:
            repo.add_many(tweets, error_duplicates=False)
        except BulkWriteError:
            error = True
        self.assertFalse(error)
        self.assertTrue(repo.exists(_id=1))
        self.assertTrue(repo.exists(_id=2))
        self.assertTrue(repo.exists(_id=3))

    def test_all(self):
        repo = TweetMongoRepository('test_all')
        repo.add({'id': 1, 'text': 'tweet1'})
        repo.add({'id': 2, 'text': 'tweet2'})
        tweets = list(repo.all())
        self.assertEqual(2, len(tweets))
        ids = set([x['_id'] for x in tweets])
        expected = {1, 2}
        self.assertSetEqual(expected, ids)

    def test_count(self):
        repo = TweetMongoRepository('test_count')
        repo.add({'id': 1, 'text': 'tweet1'})
        repo.add({'id': 2, 'text': 'tweet2'})
        repo.add({'id': 3, 'text': 'tweet3'})
        count = repo.count()
        self.assertEqual(3, count)

    def test_delete(self):
        repo = TweetMongoRepository('test_delete')
        tweet = {'id': 1, 'text': 'tweet1'}
        repo.add(tweet)
        tweet = repo.get(1)
        expected = {'_id': 1, 'id': 1, 'text': 'tweet1'}
        self.assertEqual(expected, tweet)
        repo.delete(1)
        tweet = repo.get(1)
        self.assertIsNone(tweet)

    def test_exists_returns_false_when_not_exists(self):
        repo = TweetMongoRepository('test_exists_returns_false_when_not_exists')
        exists = repo.exists(_id=1)
        self.assertFalse(exists)

    def test_exists_returns_true_when_exists(self):
        repo = TweetMongoRepository('test_exists_returns_true_when_exists')
        tweet = {'id': 1, 'text': 'tweet1'}
        repo.add(tweet)
        exists = repo.exists(_id=1)
        self.assertTrue(exists)

    def test_get_returns_tweet_when_exists(self):
        repo = TweetMongoRepository('test_get_returns_tweet_when_exists')
        tweet = {'id': 1, 'text': 'tweet1'}
        repo.add(tweet)
        tweet = repo.get(1)
        self.assertIsNotNone(tweet)
        expected = {'_id': 1, 'id': 1, 'text': 'tweet1'}
        self.assertEqual(expected, tweet)

    def test_get_returns_none_when_not_exists(self):
        repo = TweetMongoRepository('test_get_returns_none_when_not_exists')
        tweet = repo.get(1)
        self.assertIsNone(tweet)

    def test_update(self):
        repo = TweetMongoRepository('test_update')
        repo.add({'id': 1, 'text': 'tweet1', 'label': 'a'})
        tweet = repo.get(1)
        self.assertEqual('a', tweet['label'])
        tweet['label'] = 'b'
        repo.update(tweet)
        tweet = repo.get(1)
        self.assertEqual('b', tweet['label'])

    def test_update_attributes(self):
        repo = TweetMongoRepository('test_update_attributes')
        repo.add({'id': 1, 'text': 'tweet1', 'label': 'a', 'lang': 'en'})
        repo.update_attributes(1, label='b', lang='zh')
        tweet = repo.get(1)
        self.assertEqual('b', tweet['label'])
        self.assertEqual('zh', tweet['lang'])

    def test_search(self):
        repo = TweetMongoRepository('test_search')
        repo.add({'id': 1, 'text': 'tweet1', 'label': 'a'})
        repo.add({'id': 2, 'text': 'tweet2', 'label': 'a'})
        repo.add({'id': 3, 'text': 'tweet3', 'label': 'b'})
        tweets = list(repo.search(label='a'))
        self.assertEqual(2, len(tweets))
        ids = set([x['id'] for x in tweets])
        expected = {1, 2}
        self.assertSetEqual(expected, ids)

    def test_upsert(self):
        repo = TweetMongoRepository('test_search')
        tweet = {'id': 1, 'text': 'tweet1', 'label': 'a'}
        repo.upsert(tweet)
        result = repo.get(1)
        self.assertEqual('a', result['label'])
        tweet['label'] = 'b'
        repo.upsert(tweet)
        result = repo.get(1)
        self.assertEqual('b', result['label'])


import os,re,sys

import pandas as pd
import matplotlib.pyplot as plt

companies = ['Amazon', 'Apple', 'Delta', 'Google', 'IBM', 'Microsoft', 'Pfizer', 'Spotify']

root = './Data/TrainingAndTestSets/'
path_to_output_files = './Data/Figures/'

DICT  = {
    1: 'i', 2: 'ii', 3: 'iii',
    4: 'iv',  5:'v', 6: 'vi',
    7: 'vii', 8: 'viii', 9 : 'xi'
}

if __name__=='__main__':

    i = 0
    for compnay in companies:
        print(compnay)
        i +=1
        rroot = root + compnay

        path_to_training_set = rroot + '/training_set.csv'
        path_to_test_set = rroot + '/test_set.csv'

        training_set = pd.read_csv(path_to_training_set)
        test_set = pd.read_csv(path_to_test_set)

        output_dir = path_to_output_files + compnay + '/'

        emotions = test_set[['Date', 'emotion_score']]
        print(emotions['Date'])
        emotions1 = emotions.groupby('Date')

        subjectivity = test_set[['Date', 'subjectivity_score']]
        subjectivity1 = subjectivity.groupby('Date')

        print(test_set.columns)

        #groupedEmotions = emotions.groupby('Date')
        #groupedSubjectivity = subjectivity.groupby('Date')

        title = DICT[i] + '. ' + compnay

        plt.figure(1)
        plt.plot(emotions1['emotion_score'].sum(), color = 'r')
        plt.title(title)
        plt.ylabel('Emotion Score')
        plt.xlabel('Date')
        plt.xticks(fontsize = 8)
        plt.savefig(output_dir + 'Emotions.png')

        plt.close()

        plt.figure(2)
        plt.plot(subjectivity1['subjectivity_score'].sum(), color='r')
        plt.title(title)
        plt.ylabel('Subjectivity Score')
        plt.xlabel('Date')
        plt.xticks(fontsize=8)
        plt.savefig(output_dir + 'Subjectivity.png')

        plt.close()


# coding: utf-8

# In[25]:

import speech_recognition as sr
import numpy as np
import os
import speech_recognition as sr
from tqdm import tqdm

# In[31]:

# Load all audio files (divided in previous step)
files = sorted(os.listdir('\\parts\\'))

with open("\\api.json") as f:
    GOOGLE_CLOUD_SPEECH_CREDENTIALS = f.read()

# In[39]:

all_text = []
i = 0

for f in tqdm(files):
    # Load audio files part by part
    name = '\\parts\\' + f

    with sr.AudioFile(name) as source:
        audio = r.record(source)

    # Transcribe audio file (I used Polish language)
    text = r.recognize_google_cloud(audio, credentials_json=GOOGLE_CLOUD_SPEECH_CREDENTIALS, language='pl-PL')
    # Add text to a list
    all_text.append(text)

    # This is important, because I save results every 5 steps in order API will cut me
    # (Google Speech API has requests limitation)
    i = i + 1
    if i%5 == 0:
        print(name,"- current saved")
        with open("\\txt.txt", "w") as f:
                f.write(str(all_text))


import json
import pickle

from flask import Flask,request,app,jsonify, url_for, render_template
import numpy as np
import pandas as pd

app = Flask(__name__)

# Load the model
regmodel=pickle.load(open('regmodel.pkl','rb'))
scalar=pickle.load(open('scaling.pkl','rb'))

@app.route('/')
def home():
    return render_template('home.html')

'''The above code is the app.py file. This is the main file that will run the application. The first thing we do is import the necessary libraries. We then load the model that we saved in the previous step. We then create a route for the home page. The home page is the page that will be displayed when the application is run. We then create a route for the prediction page. This is the page that will be displayed when the user clicks the predict button. We then get the values from the form and store them in a variable. We then pass the values to the model and get the prediction. We then display the prediction on the home page. We then run the application.

'''

@app.route('/predict_api', methods=['POST'])
def predict_api():
    data=request.json['data']
    print(data)
    print(np.array(list(data.values())).reshape(1,-1))
    new_data=scalar.transform(np.array(list(data.values())).reshape(1,-1))
    output=regmodel.predict(new_data)
    print(output[0])
    return jsonify(output[0])

@app.route('/predict',methods=['POST'])
def predict():
    data=[float(x) for x in request.form.values()]
    final_input=scalar.transform(np.array(data).reshape(1,-1))
    print(final_input)
    output=regmodel.predict(final_input)[0]
    return render_template("home.html",prediction_text="The House price prediction is {}".format(output))

if __name__ == "__main__":
    app.run(debug=True)


import sys

from socket import (socket, AF_INET, SOCK_DGRAM, SOL_SOCKET, SO_REUSEADDR,
                    SO_BROADCAST)
from struct import pack, unpack

UDP_IP = "127.0.0.1"
UDP_PORT = 6454

BROADCAST_PORT = 7788

class ArtnetPacket:

    ARTNET_HEADER = b'Art-Net\x00'

    def __init__(self):
        self.op_code = None
        self.ver = None
        self.sequence = None
        self.physical = None
        self.universe = None
        self.length = None
        self.data = None

    def __str__(self):
        return ("ArtNet package:\n - op_code: {0}\n - version: {1}\n - "
                "sequence: {2}\n - physical: {3}\n - universe: {4}\n - "
                "length: {5}\n - data : {6}").format(
            self.op_code, self.ver, self.sequence, self.physical,
            self.universe, self.length, self.data)

    def unpack_raw_artnet_packet(raw_data):

        if unpack('!8s', raw_data[:8])[0] != ArtnetPacket.ARTNET_HEADER:
            print("Received a non Art-Net packet")
            return None

        packet = ArtnetPacket()
        (packet.op_code, packet.ver, packet.sequence, packet.physical,
            packet.universe, packet.length) = unpack('!HHBBHH', raw_data[8:18])

        packet.data = unpack(
            '{0}s'.format(int(packet.length)),
            raw_data[18:18+int(packet.length)])[0]

        return packet

def listen_and_redirect_artnet_packets(workQueue, queueLock):

    print(("Listening in {0}:{1} and redirecting with "
           "destination port {2}...").format(
        UDP_IP, UDP_PORT, BROADCAST_PORT))

    sock = socket(AF_INET, SOCK_DGRAM)  # UDP
    sock.bind((UDP_IP, UDP_PORT))

    sock_broadcast = socket(AF_INET, SOCK_DGRAM)
    sock_broadcast.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
    sock_broadcast.setsockopt(SOL_SOCKET, SO_BROADCAST, 1)

    while True:
        try:
            data, addr = sock.recvfrom(1024)
            packet = ArtnetPacket.unpack_raw_artnet_packet(data)
            # sock_broadcast.sendto(
            #     packet.data, ('255.255.255.255', BROADCAST_PORT))
            print(packet)

            # Fill the queue
            print("artnet - try lock")
            queueLock.acquire()
            print("artnet - GOT lock")

            if (workQueue.full()):
                workQueue.get()
            else:
                workQueue.put(packet)

            queueLock.release()

        except KeyboardInterrupt:
            sock.close()
            sock_broadcast.close()
            sys.exit()


from app.caches.base import RedisHashCache
from app.caches.keys import USER_FLAG_CACHE_KEY_PREFIX
from app.enums.account import AccountFlagEnum

class UserFlagCache(RedisHashCache):
    """
    用户标签缓存
    """
    KEY_PREFIX = USER_FLAG_CACHE_KEY_PREFIX

    def __init__(self, uid):
        self.uid = uid
        super(UserFlagCache, self).__init__()

    def set_flag(self, flag: AccountFlagEnum):
        return self.hset(self.uid, flag.value)

    def get_flag(self):
        value = self.hget(self.uid)
        if not value:
            return None
        return AccountFlagEnum(int(value))

if __name__ == '__main__':
    from app.main import flask_app

    with flask_app.app_context():
        uid = 1
        UserFlagCache(uid).set_flag(AccountFlagEnum.VIP)
        flag = UserFlagCache(uid).get_flag()
        print(flag)


import math
import itertools
import matplotlib.image as mpimg

from server.routes.way import Way
from server.routes.surface_type import SurfaceType
from server.routes.helper_debug.calculation_time import calculation_time
from server.routes.helper_debug.path_logs import PathLogs
from server.routes.image_compression import ImageCompression
from server.routes.surface import Surface

class SearcherCoordinate:
    def __init__(self, point, pixels):
        self.__row, self.__col = ImageCompression.convert_real_to_compress_coordinate(point)
        self.__pixels = pixels
        self.__children = {(self.__row, self.__col)}
        self.__checked = {()}

    def get_coordinate(self):
        for i in self.__children:
            row, col = i
            if i not in self.__checked:
                if self.__pixels[row][col].surface.surface_type == SurfaceType.FREE_SPACE:
                    k = ImageCompression.convert_compress_to_real_coordinate((row, col))
                    return ImageCompression.convert_compress_to_real_coordinate((row, col))
                else:
                    new_children = self.__children
                    if (row + 1, col) not in self.__checked:
                        new_children.add((row + 1, col))
                    if (row - 1, col) not in self.__checked:
                        new_children.add((row - 1, col))
                    if (row, col + 1) not in self.__checked:
                        new_children.add((row, col + 1))
                    if (row, col - 1) not in self.__checked:
                        new_children.add((row, col - 1))
                    self.__checked.add((row, col))
                    self.__children = new_children
                    return self.get_coordinate()


def main():
    file = open("input.txt")

    lines = file.readlines()

    result = 0

    data = lines[0].strip().split(',')

    for i in range(80):
        for j in range(len(data)):
            if int(data[j]) == 0:
                data.append(8)
                data[j] = int(6)
            else:
                data[j] = int(data[j]) - 1

    result = len(data)

    out = open("output-part1.txt", "w")
    out.write(str(result))
    file.close()
    out.close()

if (__name__ == "__main__"):
    main()


from pathlib import Path
from subprocess import check_call
from tempfile import TemporaryDirectory

import pytest
from invoke import Context

import sscutils.tests as testmod
from sscutils.config_loading import RunConfig
from sscutils.invoke_commands import build_meta, cleanup
from sscutils.naming import DEFAULT_ENV_NAME, MAIN_MODULE_NAME, template_repo
from sscutils.utils import cd_into, reset_meta_module
from sscutils.get_runtime import get_runtime

CORE_PY = Path(testmod.__file__).parent / "core_of_test_artifact.py"

def pytest_addoption(parser):
    # test / explore / live
    parser.addoption("--mode", action="store", default="test")

@pytest.fixture(scope="session")
def empty_template():
    ctx = Context()
    with TemporaryDirectory() as tmpdir:
        check_call(["git", "clone", template_repo, tmpdir])
        with cd_into(tmpdir):
            check_call(["dvc", "remote", "add", f"testrem", "/nothing"])
            check_call(["dvc", "remote", "default", "testrem"])
            Path(MAIN_MODULE_NAME, "core.py").write_text(CORE_PY.read_text())
            build_meta(ctx)
        yield tmpdir
        with cd_into(tmpdir):
            cleanup(ctx)

@pytest.fixture
def in_template(empty_template):
    with cd_into(empty_template):
        yield

@pytest.fixture
def running_template(in_template):
    with RunConfig(write_env=DEFAULT_ENV_NAME, read_env=DEFAULT_ENV_NAME):
        reset_meta_module()
        get_runtime(reset=True)
        yield


# Задайте список из вещественных чисел.
# Напишите программу, которая найдёт разницу между максимальным и минимальным значением дробной части элементов.

# Пример:
# - [1.1, 1.2, 3.1, 5, 10.01] => 0.19

import random
b = int(input('Задайте размер списка вещественных чисел = '))
list = [round(random.uniform(1.99, 10), 2) for list in range(b)]
max_list = max(list)
min_list = min(list)
N = max_list - min_list
print(f'{list} Pазница между максимальным и минимальным значением: {round(N, 2)}')

# рабочее решение:
# lst = list(map(float, input("Введите числа через пробел:\n").split()))
# new_lst = [round(i%1,2) for i in lst if i%1 != 0]
# print(max(new_lst) - min(new_lst))

# Решение преподователя (в мах 1 а в мин 0 потому что..)
# list = [1.1, 1.2, 3.1, 5, 10.01]
# min = 1
# max = 0
# for i in list:
#     if (i % 1) <= min:
#         min = i % 1
#     if ( i % 1) >= max:
#         max = i % 1
# print (f' Разница между максимальным и минимальным значением дробной части элементов {(max-min)}')


## medium
## backtracking, array
## 36ms, beats 100%

class Solution:
    def subsets(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        res = []

        def dfs(res,tmp,index):
            res.append(tmp[:])# deep copy of tmp
            for i in range(index,len(nums)):
                tmp.append(nums[i])
                dfs(res,tmp,i+1)
                tmp.pop()

        dfs(res,[],0)
        return res

## Another structure
## 44ms, 56.16%

class Solution:
    def subsets(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        res = []

        def dfs(res, tmp, index):
            res.append(tmp)
            for i in range(index, len(nums)):
                dfs(res,tmp+[nums[i]],i+1)

        dfs(res,[],0)
        return res


import numpy as np

class EarlyStopping:

    """
    Early Stopping Class
    """

    def __init__(self,
                 patience: int = 5,
                 min_delta: float = 0.0,
                 best_score: float = None,
                 counter: int = 0):

        """ Early Stopping Class Initialiser

        Parameters:
        -----------
        patience : int
            Patience for early stopping
        min_delta : float
            Minimum delta for early stopping
        best_score : float
            Best score for early stopping
        counter : int
            Counter for early stopping

        Returns:
        --------
        None

        """

        self.patience = patience
        self.counter = counter
        self.best_score = best_score
        self.early_stop = False
        self.min_delta = min_delta

    def __call__(self,
                 validation_loss: float,
                 counter_overwrite: bool = False) -> tuple:

        """ Early Stopping Class Call Function

        Parameters:
        -----------
        validation_loss : float
            Validation loss
        counter_overwrite : bool
            Counter overwrite

        Returns:
        --------
        early_stop : bool
            Early stopping boolean
        best_score : float
            Best score
        counter : int
            Counter

        """

        score = validation_loss

        if counter_overwrite == True:
            self.counter = 0
            self.best_score = None

        if self.best_score is None:
            self.best_score = score

        elif np.greater_equal(self.min_delta, self.best_score - score):
            self.counter += 1
            print("Early Stopping Counter: {}/{}".format(self.counter, self.patience))
            if self.counter >= self.patience:
                self.early_stop = True

        else:
            self.best_score = score
            self.counter = 0

        return self.early_stop, self.best_score, self.counter


from PIL import Image
import qrcode

sl = 100
def QR_area(image, pos):                       # tìm các pixel ở đó chứa mã QR
    size = image.size[0]
    QR_area = []
    for i in range(size):
        QR_area.append([])
        for j in range(size):
            QR_area[i].append(0)
    for i in range(size):
        for j in range(size):
            if (i < 120) or (i >= (size - 120)) or (j < 120) or (j >= (size - 120)):
                QR_area[i][j] = 1
                continue
            if (i >= 120 and j >= 120 and i < 360 and j < 360):
                QR_area[i][j] = 1
                continue
            if (i >= (size - 360) and j >= 120 and i < (size - 120) and j < 360):
                QR_area[i][j] = 1
                continue
            if (i >= 120 and j >= (size - 360) and i < 360 and j < (size - 120)):
                QR_area[i][j] = 1
                continue
            if (i % 30 == 10 and j % 30 == 10):
                for a in range(10):
                    for b in range(10):
                        QR_area[i + a][j + b] = 1

    for i in pos:
        for j in pos:
            if (i == 6 and j == pos[-1]) or (j == 6 and i == pos[-1])\
                or (i == 6 and j == 6):
                continue
            else:
                for a in range(150):
                    for b in range(150):
                        QR_area[10*(3*(i-2)+12)+a][10*(3*(j-2)+12)+b] = 1
    return QR_area

def QR_fromtext(txt,ver=5,err_crt = qrcode.constants.ERROR_CORRECT_H):         # Sinh ảnh QR nhị phân từ text
    qr = qrcode.QRCode(version = ver,error_correction = err_crt,box_size=3)
    qr.add_data(txt)
    qr.make(fit=True)
    img_qr = qr.make_image()
    img_size = img_qr.size[0] - 24

    img_frame = img_qr
    for x in range(0,img_size):
        for y in range(0,img_size):
            if x < 24 and (y < 24 or y > img_size-25):
                continue
            if x > img_size-25 and (y < 24 ):
                continue
            if (x%3 ==1 and  y%3 == 1):
                if (img_frame.getpixel((x+12,y+12)) == 0):
                    continue
            img_frame.putpixel((x+12,y+12),(255))
    pos = qrcode.util.pattern_position(qr.version)
    img_qr2 = qr.make_image()
    for i in pos:
        for j in pos:
            if (i == 6 and j == pos[-1]) or (j == 6 and i == pos[-1])\
                or (i == 6 and j == 6):
                continue
            else:
                rect = (3*(i-2)+12,3*(j-2)+12,3*(i+3)+12,3*(j+3)+12)
                img_tmp = img_qr2.crop(rect)
                img_frame.paste(img_tmp,rect)

    img_res = Image.new("RGBA",(img_frame.size[0]*10,img_frame.size[1]*10),(0,0,0,0))
    img_res = img_res.convert('1')
    img_frame = img_frame.resize((img_frame.size[0]*10,img_frame.size[1]*10), Image.NEAREST)
    img_res.paste(img_frame,(0,0),img_frame)
    return img_res, pos


# -*- encoding: utf-8 -*-
'''
@项目名称：   txsp.py
@更新时间：   2022/07/29 21:42:49
@版本号  ：   1.0
@环境变量：   txspCookie 福利中心抓取Cookie
@更新内容：   福利中心任务
'''

import json
import os
from time import sleep
import requests

COOKIE_NAME = "txspCookie"

class User:

    def __init__(self, cookie, index=1) -> None:
        self.cookie = cookie
        self.valid = True
        self.index = index

    def get(self, url, header=None):
        headers = {
            "Content-Type": "application/json",
            "User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/537.51.1 (KHTML, like Gecko) Mobile/11A465 QQLiveBrowser/8.5.95 AppType/UN WebKitCore/WKWebView iOS GDTTangramMobSDK/4.370.6 GDTMobSDK/4.370.6 cellPhone/iPhone 12",
            "referer": "https://fuli.v.qq.com/",
            "origin": "https://fuli.v.qq.com/",
            "cookie": self.cookie
        }
        if(header):
            headers.update(header)
        try:
            res = requests.get(url, headers=headers)
            return res.json()
        except Exception as e:
            print("GET异常：{0}".format(str(e)))
            return None

    def post(self, url, body='', header=None):
        headers = {
            "Content-Type": "application/json",
            "User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/537.51.1 (KHTML, like Gecko) Mobile/11A465 QQLiveBrowser/8.5.95 AppType/UN WebKitCore/WKWebView iOS GDTTangramMobSDK/4.370.6 GDTMobSDK/4.370.6 cellPhone/iPhone 12",
            "referer": "https://fuli.v.qq.com/",
            "origin": "https://fuli.v.qq.com/",
            "accept-encoding":"gzip, deflate, br",
            "connection":"keep-alive",
            "cookie": self.cookie
        }
        if(header):
            headers.update(header)
        # 捕获异常
        try:
            res = requests.post(url, data=body, headers=headers)
            return res.json()
        except Exception as e:
            print("POST异常：{0}".format(str(e)))
            return None

    def vipInfo(self):
        url = "https://vip.video.qq.com/fcgi-bin/comm_cgi?name=spp_SVipInfo&cmd=1&source_scene=4&otype=xjson"
        rjson = self.get(url=url)
        if(not rjson):
            self.valid = False
            return
        if("msg" not in rjson):
            self.valid = True
            self.nickname = rjson['nick']
            self.vipInfo = rjson["hlw"]
            print("用户昵称：",self.nickname)
            if(self.vipInfo['vip']):
                print("VIP状态：有效")
            else:
                print("VIP状态：过期")
            print("VIP等级：",self.vipInfo['level'])
            print("VIP经验：",self.vipInfo['score'])
        else:
            self.valid = False
            print("获取账号信息失败：",rjson["msg"])

    def welfareCenter(self,onlyCoin = False):
        url = "https://pbaccess.video.qq.com/activity/welfare_center/v2/queryUserActivityNew"
        body = {"activity_id":1001}
        rjson = self.post(url=url,body=json.dumps(body))
        if(not rjson):
            return
        if("msg" not in rjson):
            self.coin = rjson['data']['asset_info']['coin']
            if(onlyCoin):
                print(f"账号[{self.nickname}]：{self.coin}")
                return
            print("福利金币：",self.coin)

            tasks = rjson['data']['task_info']
            print("")
            if(len(tasks['watch_video_info']['watch_video_record'])>=2):
                print("任务[播放视频]已完成")
            else:
                print("任务[播放视频]未完成")
                self.taskWatch()
            if(len(tasks['browse_info']['browse_record'])>=2):
                print("任务[浏览商店]已完成")
            else:
                print("任务[浏览商店]未完成")
                self.taskBrowse()
            print(f"任务[好友助力]进度：{tasks['help_share_info']['help_share_count']}/{tasks['help_share_info']['help_share_limit']}")
            if(tasks['help_share_info']['help_share_count'] != tasks['help_share_info']['help_share_limit']):
                self.needHelp = True
                self.shareCode = rjson['data']['vuid_encoded']
            else:
                self.needHelp = False
        else:
            print("获取福利中心信息失败：",rjson['msg'])

    def taskBrowse(self):
        url = "https://pbaccess.video.qq.com/activity/platform/gateway/v2/browse"
        body = {"activity_id":"1001","browse_page":"caochangdi","task_group_id":"4"}
        rjson = self.post(url,body=json.dumps(body))

        if(rjson['err_msg'] == "success"):
            print("任务[浏览商店]执行成功")
        else:
            print("任务[浏览商店]执行失败：",rjson['err_msg'])

    def taskWatch(self):
        url = "https://pbaccess.video.qq.com/activity/platform/gateway/v2/WatchVideo"
        body = {"activity_id":"1001","vid":"mzc00200p51jpn7","task_group_id":"1"}
        rjson = self.post(url,body=json.dumps(body))

        if(rjson['err_msg'] == "success"):
            print("任务[播放视频]执行成功")
        else:
            print("任务[播放视频]执行失败：",rjson['err_msg'])

    def signInfo(self):
        url = "https://pbaccess.video.qq.com/activity/platform/gateway/v2/querySignInfo"
        body = {"activity_id":"1001","task_group_id":5}
        rjson = self.post(url=url,body=json.dumps(body))
        if(not rjson):
            return
        if(not rjson['err_msg']):
            if(rjson['data']['is_sign']):
                print("今日已签到")
            else:
                print("今日未签到")
                self.signIn()
        else:
            print("获取签到信息失败：",rjson['err_msg'])

    def signIn(self):
        url = "https://pbaccess.video.qq.com/activity/platform/gateway/v2/signPlay"
        body = {"activity_id":"1001","task_group_id":5}
        rjson = self.post(url=url,body=json.dumps(body))
        if(not rjson):
            return
        if(rjson['err_msg'] == "success"):
            print(f"签到成功：+{rjson['data']['reward_count']}金币")
        else:
            print("签到失败：",rjson['err_msg'])

    def shareHelp(self, users):
        if(not self.valid):
            return
        for user in users:
            if(user.cookie == self.cookie):
                continue
            if(not user.valid or not user.needHelp):
                continue
            url = "https://pbaccess.video.qq.com/activity/platform/gateway/v2/helpShare"
            body = {"activity_id":"1001","task_group_id":2,"sponsor_id":user.shareCode}
            rjson = self.post(url=url,body=json.dumps(body))
            if(not rjson):
                continue
            if(rjson['err_msg'] == "success"):
                print(f"[{self.nickname}]->[{user.nickname}]助力成功")
            else:
                print(f"[{self.nickname}]->[{user.nickname}]助力失败：{rjson['err_msg']}")
            sleep(2)

    def run(self):
        print(f"======账号[{self.index}]======")
        self.vipInfo()
        if(self.valid):
            print("\n>>>福利中心")
            self.welfareCenter()
            print("")
            self.signInfo()
        print("\n")

def initEnv():
    env = os.environ
    if(COOKIE_NAME in env):
        cookies = env[COOKIE_NAME]
        if(cookies.find("&")):
            return cookies.split("&")
    return []

if __name__ == "__main__":
    cookies = initEnv()
    users = []
    index = 1
    for cookie in cookies:
        users.append(User(cookie, index))
        index +=1
    for user in users:
        try:
            user.run()
        except Exception as e:
            print("运行异常：", str(e))

    print("\n======福利助力======")
    for user in users:
        user.shareHelp(users)

    print("\n======账号总览======")
    for user in users:
        if(user.valid):
            user.welfareCenter(True)


import matplotlib.pyplot as plt
from nnv import NNV

plt.rcParams["figure.figsize"] = (10,10)

TwoLayers = [
    {"title":"input\n(relu)", "units": 3,  "color": "orange", "edges_color":"red", "edges_width":2},
    {"title":"output\n(sigmoid)", "units": 1,"color": "blue"},
]

NNV(TwoLayers, node_radius=10, spacing_layer=60, font_size=22).render(save_to_file="TwoLayers.png")

plt.rcParams["figure.figsize"] = (100,10)

ThreeLayers = [
    {"title":"input\n(relu)", "units": 3, "color": "yellow"},
    {"title":"hidden\n(relu)", "units": 4, "color": "orange", "edges_color":"red", "edges_width":2},
    {"title":"output\n(sigmoid)", "units": 1,"color": "blue"},

]

NNV(ThreeLayers, node_radius=10, spacing_layer=60, font_size=24).render(save_to_file="ThreeLayers.pdf")


import numpy as np
import math

def entropy(y_values: np.ndarray) -> float:
    """
    Calculate the entropy of the random variable y.
    :param y_values: The y-values to calculate the entropy of.
    :return: The entropy value, H(y).
    """
    total = len(y_values)
    _, counts = np.unique(y_values, return_counts=True)
    counts = [c / total for c in counts]
    ps = [p * math.log(p) for p in counts]
    return sum(ps)

def conditional_entropy(attr_values: np.ndarray, y_values: np.ndarray) -> float:
    """
    Calculate the conditional entropy (i.e. P(y_values|attr_values)) of the variable attr and y.
    :param attr_values: The attribute values of a single variable, corresponding to the y values.
    :param y_values: The y values.
    :return: The conditional entropy value.
    """
    total = 0
    uniq_attrs, uniq_count = np.unique(attr_values, return_counts=True)
    for idx, attr in enumerate(uniq_attrs):
        p = uniq_count[idx] / len(attr_values)
        mask = attr_values == attr
        cur_ys = y_values[mask]
        total += p * entropy(cur_ys)
    return -total * (1 / len(uniq_attrs))

def info_gain(attr_values: np.ndarray, y_values: np.ndarray) -> float:
    """
    Calculate the information gain of an attribute.
    :param attr_values: The values for the attribute that correspond to each row in the y_values variable.
    :param y_values: The y values.
    :return: The information gain, as calculated.
    """
    e = entropy(y_values)
    ce = conditional_entropy(attr_values, y_values)
    return e - ce

if __name__ == '__main__':
    data = np.array([
        [1, 1, '+'],
        [1, 0, '+'],
        [1, 1, '+'],
        [1, 0, '+'],
        [0, 1, '+'],
        [0, 0, '-'],
        [0, 1, '-'],
        [0, 0, '-']
    ])
    print(conditional_entropy(data[:, 0], data[:, 2]))
    # for i in range(2):
    #     ig = info_gain(data[:, i], data[:, 2])
    #     print(f'Information gain for feature number {i}:', ig)
    # # print(entropy(np.array(['+', '+', '+', '+', '+', '-', '-', '-'])))


print(__name__)

__all__ = ['money','read1','read2']

print('from the spam.py')

money = 0

def read1():
    print('spam模块.read1:', money)

def read2():
    print("spam模块.read2")
    read1()

def change():
    global money
    money = 1    # 在模块中修改

if __name__ == '__main__':
    print('文件被当做脚本执行了')
    read1()
else:
    print('文件被导入了')