import numpy as np
import itertools

# # define strength of cards
strength = {f'{i}': i for i in range(1, 11)}
strength['Walet'] = 11
strength['Dama'] = 12
strength['Król'] = 13
strength['As'] = 14

# create and mix cards based on given colors and numbers
def mix_cards(colors, numbers):
    # Create all pack
    allCards = []
    for col, num in itertools.product(colors, numbers):
        allCards.append(num + ' ' + col)
    # shuffled cards
    np.random.shuffle(allCards)
    return allCards

def deal_cards(allCards, n_players):
    game = []
    for i in range(n_players):
        cards = []
        for j in range(len(allCards)):
            if j % n_players == i:
                cards.append(allCards[j])
        game.append(cards)
    return game

# remove player from game
def remove_player(game, players):
    # if player has no more cards is removed from game
    players_to_remove = []
    for card, player in zip(game, players):
        if card == []:
            players_to_remove.append(player)
    for item in players_to_remove:
        players.remove(item)
        game.remove([])
    return game, players

# function which give back cards to owners (used after war ended with dead-heat)
def cards_come_back(game, players, cards_to_take):
    n = len(players)
    for i in range(n):
        for j in range(len(cards_to_take)):
            if j % n == i:
                game[i].append(cards_to_take[j])
    return game

# one round
def one_round(game, players, war):
    """
    :param game: list containing lists of cards for each player
    :param players: list of players - length must be the same as length of game
    :param war: bool - True if current round is the war
    :return: winner, cards which got winner, players, game
    """
    # cards to win
    cards_to_take = []
    round_ = []
    # print players and their cards
    for card, player in zip(game, players):
        print(player, card)

    if war:
        # if round is the war, first card doesn't matter so it goes strictly to cards to win
        for card, player in zip(game, players):
            cards_to_take.append(card[0])
            card.pop(0)
        # if one of players had only one card, remove him from game
        game2, players2 = remove_player(game.copy(), players.copy())

        # if all players were removed, then it is dead-heat
        if len(players2) == 0:
            game = cards_come_back(game, players, cards_to_take)
            return None, cards_to_take, players, game
        # update game and players to state after removing players
        game = game2
        players = players2

    # if only one player stayed, it's winner
    if len(players) == 1:
        return 0, cards_to_take, players, game

    else:
        # choose first card of each player and remove it from cards
        for card, player in zip(game, players):
            round_.append(card[0])
            card.pop(0)
        # scores for cards
        scores = list(map(lambda x: strength[x.split()[0]], round_))
        scores = np.array(scores)
        # maximum score
        max_val = np.max(scores)
        # add cards to cards for winner
        cards_to_take += round_

        # if there is only one max score, we have winner! Otherwise we have war
        if np.sum(scores == max_val) == 1:
            winner = np.argmax(scores)
        else:
            print('wojna')

            # choose players for war and their cards
            players_in_war = [i for i in range(len(scores)) if scores[i] == max_val]
            players_for_war = [players[i] for i in players_in_war]
            print('w wojnie biorą udział gracze', players_for_war)
            game_for_war = [game[i] for i in players_in_war]

            # if any players for war has no more cards, remove him from war
            if [] in game_for_war:
                game_for_war2, players_for_war2 = remove_player(game_for_war, players_for_war)
                # if there is no more players then it is dead-heat, otherwise update players for war and go into war
                if players_for_war2 == []:
                    print('remis - karty wracają do właścicieli')
                    game = cards_come_back(game, players, cards_to_take)
                    return None, [], players, game
                else:
                    game_for_war, players_for_war = game_for_war2, players_for_war2
            winner, cards_to_take_after_war, players_for_war, game_for_war = one_round(
                game_for_war,
                players_for_war,
                war=True)

            # if winer after war is None, it is dead-heat
            if winner is None:
                game = cards_come_back(game, players, cards_to_take)
                return None, [], players, game

            winner = players_in_war[winner]
            cards_to_take += cards_to_take_after_war

        # give cards to winner
        if not war:
            print('zwycięzca to', players[winner])
            print('wygrał', cards_to_take)
            game[winner] += cards_to_take

        # check if there is player with no more cards and remove him/her
        if [] in game:
            game, players = remove_player(game, players)
        return winner, cards_to_take, players, game

def main():
    # how many round with no winner to stop game
    n = 10000
    # how many times repeat that
    m = int(input('Ile razy chcesz powtórzyć rozgrywke? '))
    end = 0
    # min no. of players
    min_players = 2
    # max no. of players
    max_players = 17
    # number of players
    n_players = int(input('Podaj liczbę graczy: '))
    while (n_players < min_players) or (n_players > max_players):
        n_players = int(input(f'Podałeś złą liczbę. Liczba graczy musi być pomiędzy {min_players} a {max_players}: '))
    for j in range(m):
        # define colors and numbers in cards, create and mix them
        colors = ['Kier', 'Karo', 'Trefl', 'Pik']
        numbers = [str(i) for i in range(2, 11)] + ['Walet', 'Dama', 'Król', 'As']
        allCards = mix_cards(colors, numbers)

        # Names of players
        players = [f'Gracz {i + 1}' for i in range(n_players)]

        # dealing cards
        game = deal_cards(allCards, n_players)

        # one game go on till someone win or end if after n rounds there is no winner
        i = 0
        while len(players) > 1 and i < n:
            i += 1

            print('liczba graczy to', len(players))
            winner, cards_to_take, players, game = one_round(game, players, war=False)

        if i == n:
            print('nie skonczyli')
        else:
            print('skonczyli')
            end += 1

    print('Grę skończyli', end, 'razy na', m)

if __name__ == '__main__':
    main()


def dfs(node, visited, graph):
    visited[node] = True
    for neighbor in graph[node]:
        if not visited[neighbor]:
            dfs(neighbor, visited, graph)

# Reading input from user
n, m = map(int, input().split())

# Creating an empty graph
graph = [[] for _ in range(n+1)]

# Reading edges and populating the graph
for i in range(m):
    u, v = map(int, input().split())
    graph[u].append(v)
    graph[v].append(u)

# Reading the head node
head = int(input())

# Initializing the visited list with all elements set to False
visited = [False] * (n+1)

# Starting a Depth First Search (DFS) from the head node
dfs(head, visited, graph)

# Counting the number of unreachable nodes
unreachable = visited.count(False) - 1  # Subtracting 1 to exclude the head node

# Printing the result
print(unreachable)


#wk4ex2

def encipher(s, n):
    """encipher een functie die string s voorwaards roteert met n stappen. volgens ceasar schrift

    Args:
        s (string): een string, kan een zin zijn.
        n (int): een geheel getal tussen 0 en 25
    """
    if n > 25 or n < 0 or type(n) is not int:
        print('geen geldige input voor n')
        return
    elif s == '':
        return ''
    else:
        return rot(s[0],n) + encipher(s[1:], n)

def rot(s, n):
    """rot neemt 1 letter van encipher en roteert

    Args:
        s (string): de letter
        n (int): aantal stappen vooruit
    """
    if n == 0:
        return s
    elif 'a' <= s < 'z' or 'A' <= s < 'Z':
        return rot(chr(ord(s[0])+1),n-1)
    elif s == 'z' or s == 'Z':
        return rot(chr(ord(s[0]) - 25), n-1)
    else:
        return s

def decipher(s):
    """decipher functie die een gegeven string ontcijfert met een omgekeerd caesarschrift

    Args:
        s (string): de gegeven versleutelde string
    """
    L = [[encipher(b,n) for b in s] for n in range(26)]

    prob = [[letter_prob(b) for b in x] for x in L]
    lol = [sum(x) for x in prob]

    return encipher(s, lol.index(max(lol)))

def letter_prob(c):
    """If c is an alphabetic character,
       we return its monogram probability (for Dutch),
       otherwise we return 1.0.  We ignore capitalization.
       Adapted from
       https://www.sttmedia.com/characterfrequency-nederlands
    """
    if c == 'e' or c == 'E':
        return 0.1909
    if c == 'n' or c == 'N':
        return 0.0991
    if c == 'a' or c == 'A':
        return 0.0769
    if c == 't' or c == 'T':
        return 0.0642
    if c == 'i' or c == 'I':
        return 0.0630
    if c == 'o' or c == 'O':
        return 0.0581
    if c == 'r' or c == 'R':
        return 0.0562
    if c == 'd' or c == 'D':
        return 0.0541
    if c == 's' or c == 'S':
        return 0.0384
    if c == 'l' or c == 'L':
        return 0.0380
    if c == 'h' or c == 'H':
        return 0.0312
    if c == 'g' or c == 'G':
        return 0.0312
    if c == 'k' or c == 'K':
        return 0.0279
    if c == 'm' or c == 'M':
        return 0.0256
    if c == 'v' or c == 'V':
        return 0.0224
    if c == 'u' or c == 'U':
        return 0.0212
    if c == 'j' or c == 'J':
        return 0.0182
    if c == 'w' or c == 'W':
        return 0.0172
    if c == 'z' or c == 'Z':
        return 0.0160
    if c == 'p' or c == 'P':
        return 0.0149
    if c == 'b' or c == 'B':
        return 0.0136
    if c == 'c' or c == 'C':
        return 0.0130
    if c == 'f' or c == 'F':
        return 0.0073
    if c == 'y' or c == 'Y':
        return 0.0006
    if c == 'x' or c == 'X':
        return 0.0005
    if c == 'q' or c == 'Q':
        return 0.0001
    return 1.0

assert decipher('Bzdrzqbhiedq? Hj gda khdudq Bzdrzqrzkzcd.') == 'Caesarcijfer? Ik heb liever Caesarsalade.'
assert decipher('Aadxas ue exqotfe pq haadflqffuzs hmz baxufuqw yqf mzpqdq yuppqxqz.') == 'Oorlog is slechts de voortzetting van politiek met andere middelen.'

def blsort(L):
    """blsort neemt een lijst met binaire getallen, en set deze op volgorde

    Args:
        L (list): de lijst met binaire getallen
    """
    lc = [0 for x in L if x == 0] + [1 for x in L if x == 1]
    return lc

def rem_one(e, L):
    """Returns sequence L with one e rmoved
    """
    if len(L) == 0:
        return L
    elif L[0] != e:
        return L[0:1] + rem_one(e, L[1:])
    else:
        return L[1:]

def gensort(L):
    """gensort neemt lijst L en sorteerd.

    Args:
        L (list): lijst met integers
    """
    if L == []:
        return []
    else:
        lc = [min(L)]
        L = rem_one(min(L), L)
        return lc + gensort(L)

assert gensort([42, 1, 3.14]) == [1, 3.14, 42]
assert gensort([7, 9, 4, 3, 0, 5, 2, 6, 1, 8]) == [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

def lingo(s, t):
    """lingo neemt 2 strings en geeft terug hoeveel letters de beide woorden gemeen hebben.
    Dit hoeven niet letters zijn op dezelfde plek.

    s: string: het eerste woord
    t: string: het tweede woord

    """
    sameCounter = 0
    if s == '' or t == '':
        return 0
    if s[0] in t:
        rem_one(s[0], t)
        sameCounter += 1
    return sameCounter + lingo(s[1:], t)

def changeCalc(target, L):
    print(L)
    if target == 0:
        return True
    if target < 0:
        return False
    if L == []:
        return 0
    if L[0] > target:
        return changeCalc(target, L[1:])
    elif L[0] == target:
        return L[0]
    elif L[0] < target:
        use = L[0] + changeCalc(target - L[0], L[1:])
        lose = changeCalc(target, L[1:])
        return max(use, lose)

def exact_change(target, L):
    """exact_change neemt een target amount en een lijst en kijkt of target gehaald kan worden met de inhoud van de lijst

    Args:
        target (int): het te behalen nummer.
        L (list): de lijst met waarden

    Returns:
        boolean: T/F op basis van te behalen of niet
    """
    if changeCalc(target, L) == target or changeCalc(target, L) == True:
        return True
    else:
        return False

assert exact_change(42, [25, 1, 25, 10, 5, 1]) == True
assert exact_change(42, [25, 1, 25, 10, 5]) == False
assert exact_change(42, [23, 1, 23, 100]) == False
assert exact_change(42, [23, 17, 2, 100]) == True
assert exact_change(42, [25, 16, 2, 15]) == True  # de 16 moet "overgeslagen" kunnen worden...
assert exact_change(0, [4, 5, 6]) == True
assert exact_change(-47, [4, 5, 6]) == False
assert exact_change(0, []) == True
assert exact_change(42, []) == False

def lcs(s,t):
    """lcs neemt s en t en geeft een string terug met gemeenschappelijke letters

    Args:
        s (string): de eerste string
        t (string): de tweede string
    """
    newString = ''
    if len(s) == 0 or len(t) == 0:
        return ''
    elif s[0] == t[0]:
        newString += s[0]
        return s[0] + lcs(s[1:],t[1:])
    else:
        return max(lcs(s, t[1:]), lcs(s[1:], t), key=len)

assert lcs('mens', 'chimpansee') == 'mns'
assert lcs('gattaca', 'tacgaacta') == 'gaaca'
assert lcs('wow', 'wauw') == 'ww'
assert lcs('abcdefgh', 'efghabcd') == 'abcd'


# author: byduan
# function: The method of generator
import random

def getdetail(G):
    '''
    Get the detail information of the G
    :param filename:
    :return:
    '''

    commitname = list(set(G.vs()['value']))
    commit_count = len(commitname)
    edge_list_index = list()
    edge_list = list()
    eachCommunityNodeList = [[] for _ in range(commit_count)]
    in_edge = [[] for _ in range(commit_count)]
    between_edge = [[] for _ in range(commit_count)]
    detail_info = [[] for _ in range(commit_count)]

    node_list = list()
    for i in range(len(commitname)):
        eachCommunityNodeList[i] = G.vs.select(value=commitname[i])['id']
        for j in range(len(eachCommunityNodeList[i])):
            node_list.append(int(eachCommunityNodeList[i][j]))

    for e in G.es:
        edge_list_index.append(e.tuple)

    for i in range(len(edge_list_index)):
        edgeA = int(indexToId(G,edge_list_index[i][0]))
        edgeB = int(indexToId(G,edge_list_index[i][1]))
        edge_list.append((edgeA,edgeB))

    for i in edge_list:
        for commit in eachCommunityNodeList:
            if int(i[0]) in commit and int(i[1]) in commit:
                in_edge[eachCommunityNodeList.index(commit)].append((int(i[0]),int(i[1])))
                break
            if int(i[0]) in commit and int(i[1]) not in commit:
                between_edge[eachCommunityNodeList.index(commit)].append((int(i[0]),int(i[1])))
            if int(i[0]) not in commit and int(i[1]) in commit:
                between_edge[eachCommunityNodeList.index(commit)].append((int(i[0]),int(i[1])))

    for i in range(commit_count):
        detail_info[i].append(len(eachCommunityNodeList[i]))
        detail_info[i].append(len(in_edge[i]))
        detail_info[i].append(len(between_edge[i]))
        detail_info[i].append(eachCommunityNodeList[i])
        detail_info[i].append(in_edge[i])
        detail_info[i].append(between_edge[i])
    return node_list, edge_list, detail_info

def computQ(G):
    '''
    compute modularity
    :param detail_info:
    :return: Q
    '''
    q = list()
    detail_info = getdetail(G)

    m = len(detail_info[1])
    for i in range(len(detail_info[2])):
        q.append(detail_info[2][i][1]/m - ((2*detail_info[2][i][1] + detail_info[2][i][2])/(2*m))**2)
    Q = sum(q)
    return  Q

def judge(G):
    '''
    compute whether there is an edge between the selected nodes
    :param start_detail_info:
    :return:
    '''
    start_detail_info = getdetail(G)
    node_list = start_detail_info[0]
    edge_list = start_detail_info[1]
    temp1 = random.sample(node_list, 2)
    nodeA = temp1[0]
    nodeB = temp1[1]
    if (nodeA,nodeB) in edge_list or (nodeB,nodeA) in edge_list:
        return 1, temp1, start_detail_info
    else:
        return 0, temp1, start_detail_info

def lookCommunity(start_detail_info,random_node):
    '''
    compute the selected nddes belong to witch community
    :param start_detail_info:
    :param random_node:
    :return:
    '''
    communityOfnodeA, communityOfnodeB = 0,0
    for i in range(len(start_detail_info[2])):
        if random_node[0] in start_detail_info[2][i][3]:
            communityOfnodeA = i
        if random_node[1] in start_detail_info[2][i][3]:
            communityOfnodeB = i
    return communityOfnodeA, communityOfnodeB

def computQofDelete(detail_info,random_community):
    '''
    compute the change of modularity because the edges deletion
    :param detail_info:
    :param random_community:
    :return:
    '''

    m = len(detail_info[1])
    q2 = 0
    qqq = 0
    # compute the change of modularity because the intra-community edge deletion
    if random_community[0] == random_community[1]:
        for i in range(len(detail_info[2])):
            if i == random_community[0]:
                q2 = q2 + ((detail_info[2][i][1]-1)/(m-1)-((2*detail_info[2][i][1]-2+detail_info[2][i][2])/(2*m-2))**2)
            else:
                q2 = q2 + ((detail_info[2][i][1])/(m-1)-((2*detail_info[2][i][1]+detail_info[2][i][2])/(2*m-2))**2)
    # compute the change of modularity because the inter-community edge deletion
    else:
        for i in range(len(detail_info[2])):
            if i == random_community[0] or i == random_community[1]:
                qqq = qqq + ((detail_info[2][i][1]/(m-1)-((2*detail_info[2][i][1]+detail_info[2][i][2]-1)/(2*m-2))**2))
            else:
                qqq = qqq + ((detail_info[2][i][1])/(m-1)-((2*detail_info[2][i][1]+detail_info[2][i][2])/(2*m-2))**2)

    return q2,qqq

def computQofAdd(detail_info,random_community):
    '''
    compute the change of modularity because the change insertion
    :param detail_info:
    :param random_community:
    :return:
    '''
    m = len(detail_info[1])
    q1 = 0
    qq = 0
    # compute the change of modularity because the intra-community edge insertion
    if random_community[0] == random_community[1]:
        for i in range(len(detail_info[2])):
            if i == random_community[0]:
                q1 = q1+(detail_info[2][i][1]+1)/(m+1)-((2*detail_info[2][i][1]+2+detail_info[2][i][2])/(2*m+2))**2
            else:
                q1 = q1+(detail_info[2][i][1])/(m+1)-((2*detail_info[2][i][1]+detail_info[2][i][2])/(2*m+2))**2
    # compute the change of modularity because the inter-community edge insertion
    else:
        for i in range(len(detail_info[2])):
            if i == random_community[0] or i == random_community[1]:
                qq = qq+(detail_info[2][i][1])/(m+1)-((2*detail_info[2][i][1]+detail_info[2][i][2]+1)/(2*m+2))**2
            else:
                qq = qq+(detail_info[2][i][1])/(m+1)-((2*detail_info[2][i][1]+detail_info[2][i][2])/(2*m+2))**2
    return q1, qq

def idToIndex(G,id):
    '''
    map id to index
    :param G:
    :param id:
    :return:
    :function
    '''

    index = 0
    nodeIdLidt = list()
    commitname = list(set(G.vs()['value']))
    for commit in commitname:
        for i in range(len(G.vs.select(value=commit)['id'])):
            nodeIdLidt.append(G.vs.select(value=commit)['id'][i])

    nodeIdLidt = sorted(nodeIdLidt)
    if id in nodeIdLidt:
        for i in range(len(nodeIdLidt)):
            if nodeIdLidt[i]<id:
                index = index + 1
        return index
    else:
        return -1
    pass

def indexToId(G,index):
    '''
    map index to id
    :param G:
    :param index:
    :return:
    :function:
    '''
    nodeIdLidt = list()
    commitname = list(set(G.vs()['value']))
    for commit in commitname:
        for i in range(len(G.vs.select(value=commit)['id'])):
            nodeIdLidt.append(G.vs.select(value=commit)['id'][i])
    nodeIdLidt = sorted(nodeIdLidt)
    id = nodeIdLidt[index]
    return id
    pass

def writeQtoTXT(Q_LIST):
    '''
    Write to gml
    :param Q_LIST:
    :return:
    :function:
    '''
    line = ''
    for i in Q_LIST:
        line = line + str(i) + ' '
    with open('./result/Q_list.gml','w') as f:
        f.writelines(line)
    pass


from pathlib import Path
from typing import Any, Optional

import numpy as np
import torch
import torchvision.transforms.functional as TF
from PIL import Image
from torchvision import transforms
from yacs.config import CfgNode as CN

from .base_dataset import BaseDataset, Ingr, Metadata

class Nutrition5kDataset(BaseDataset):
    """
    Nutrition 5k Dataset Class

    Args:
        imgs_dir (Path): Path to images directory
        metadatas_path (Path): Path to metadatas (csv file)
        splits (list[str]): list of image names in current split
        transform (Optional[transforms.Compose]): RGB image transforms (default=None)
        transform_depth (Optional[transforms.Compose]): depth image transforms (default=None)
        normalize_depth (Optional[transforms.Compose]): dpeth normalization (default=None)
        rotate_flip (Optional[bool]): Whether to perform rotation and horizontal flip data augmentation (default=True)
        w_depth (Optional[bool]): Whether to load depth data (default=True)
        w_mask (Optional[bool]): Whether to load top-1 mask (default=True)
        w_mask_all (Optional[bool]): Whether to load all masks (default=True)
    """
    def __init__(self, *args, **kwargs) -> None:
        super(Nutrition5kDataset, self).__init__(*args, **kwargs)
        self.metadatas_dict: dict[str, Metadata] = {}
        self.init_metadatas()

    @staticmethod
    def transform_(imgs: dict[str, Any]) -> dict[str, torch.Tensor]:
        # rotate
        params = transforms.RandomRotation.get_params([-180, 180])
        imgs = {k: TF.rotate(img, params) for k, img in imgs.items()}

        if np.random.rand() < 0.5:
            imgs = {k: TF.hflip(img) for k, img in imgs.items()}
        return imgs

    def init_metadatas(self):
        """
        Extract metadatas for all dishes and normalize
        """
        mean_metadata = self.mean_metadata
        std_metadata = self.std_metadata
        for line in open(self.metadatas_path, "r").readlines():
            line = line.rstrip()
            data_list = line.split(",")
            data_dict = Metadata()
            dish_id = data_list[0]
            data_dict.dish_id = dish_id
            data_dict.cal = (float(data_list[1]) - mean_metadata.cal) / std_metadata.cal
            data_dict.mass = (
                float(data_list[2]) - mean_metadata.mass
            ) / std_metadata.mass
            data_dict.fat = (float(data_list[3]) - mean_metadata.fat) / std_metadata.fat
            data_dict.carb = (
                float(data_list[4]) - mean_metadata.carb
            ) / std_metadata.carb
            data_dict.protein = (
                float(data_list[5]) - mean_metadata.protein
            ) / std_metadata.protein
            data_dict.ingrs = []
            for id, name, grams, cal, fat, carb, protein in zip(*[data_list[x::7] for x in range(6, 13)]):  # type: ignore
                ingr = Ingr(
                    **{
                        "id": id,
                        "name": name,
                        "grams": grams,
                        "cal": cal,
                        "fat": fat,
                        "carb": carb,
                        "protein": protein,
                    }
                )
                data_dict.ingrs.append(ingr)
            assert len(data_list) == len(data_dict.ingrs) * 7 + 6
            self.metadatas_dict[dish_id] = data_dict

    def __getitem__(self, index: int) -> dict[str, Any]:
        metadata = self.metadatas_dict[self.splits[index]]
        img_dir = Path.joinpath(self.imgs_dir, self.splits[index])
        rgb_path = Path.joinpath(img_dir, "rgb.png")
        depth_path = Path.joinpath(img_dir, "depth_raw.png")
        mask_path = Path.joinpath(img_dir, "mask.pt")
        mask_all_path = Path.joinpath(img_dir, "mask_all.pt")
        sample = {
            "metadata": metadata,
            "rgb_path": str(rgb_path),
            "depth_path": str(depth_path),
        }
        imgs = {}
        rgb_img = Image.open(rgb_path)
        rgb_img = self.transform(rgb_img)
        imgs["rgb_img"] = rgb_img
        if self.w_depth:
            depth_img = Image.open(depth_path)
            depth_img = self.transform_depth(depth_img).float()  # type: ignore
            depth_img = self.normalize_depth(depth_img)
            imgs["depth_img"] = depth_img
        if self.w_mask:
            mask = torch.load(mask_path)
            mask = mask.unsqueeze(0)
            imgs["mask"] = mask
        if self.w_mask_all:
            imgs["mask_all"] = torch.load(mask_all_path)

        if self.rotate_flip:
            imgs = self.transform_(imgs)
        if self.w_mask:
            imgs["mask"] = imgs["mask"].squeeze(0)
        sample.update(imgs)
        return sample

def make_dataset(
    config: Optional[CN],
    imgs_dir: str = ".",
    metadatas_path: str = ".",
    splits_train_path: str = ".",
    splits_test_path: str = ".",
    unnormalized_int_tensor: bool = False,
    **kwargs,
) -> dict[str, BaseDataset]:
    if isinstance(config, CN):
        imgs_dir_p = Path(config.DATA.IMGS_DIR)
        metadatas_path_p = Path(config.DATA.METADATAS_PATH)
        splits_train_path_p = Path(config.DATA.SPLITS_TRAIN_PATH)
        splits_test_path_p = Path(config.DATA.SPLITS_TEST_PATH)
        if config.TRAIN.TRAINER != "multi_mask":
            kwargs.update(w_mask_all=False)
        if config.TRAIN.TRAINER == "normal" or config.TRAIN.TRAINER == "noisy":
            kwargs.update(w_mask=False)
    else:
        imgs_dir_p = Path(imgs_dir)
        metadatas_path_p = Path(metadatas_path)
        splits_train_path_p = Path(splits_train_path)
        splits_test_path_p = Path(splits_test_path)

    ### dishes with obvious mislabels
    removed = {
        "dish_1564159636",
        "dish_1551138237",
        "dish_1551232973",
        "dish_1551381990",
        "dish_1551389458",
        "dish_1551389551",
        "dish_1551389588",
        "dish_1551567508",
        "dish_1551567573",
        "dish_1551567604",
        "dish_1560974769",
    }
    splits_train = [
        line.rstrip() for line in open(splits_train_path_p, "r").readlines()
    ]
    splits_train = list(
        filter(
            lambda t: imgs_dir_p.joinpath(t, "rgb.png").is_file()
            and imgs_dir_p.joinpath(t, "depth_raw.png").is_file()
            and t not in removed,
            splits_train,
        )
    )
    splits_test = [line.rstrip() for line in open(splits_test_path_p, "r").readlines()]
    splits_test = list(
        filter(
            lambda t: imgs_dir_p.joinpath(t, "rgb.png").is_file()
            and imgs_dir_p.joinpath(t, "depth_raw.png").is_file()
            and t not in removed,
            splits_test,
        )
    )

    model_name = config.MODEL.NAME if config is not None else ""

    if unnormalized_int_tensor or model_name == "openseed":
        print("unnormalized")
        transform = transforms.Compose([transforms.PILToTensor()])
        normalize_depth = transforms.Normalize(3091, 5.361)
    else:
        transform = None
        normalize_depth = None
    train_dataset = Nutrition5kDataset(
        imgs_dir_p,
        metadatas_path_p,
        splits_train,
        transform=transform,
        normalize_depth=normalize_depth,
        **kwargs,
    )
    test_dataset = Nutrition5kDataset(
        imgs_dir_p,
        metadatas_path_p,
        splits_test,
        transform=transform,
        normalize_depth=normalize_depth,
        **kwargs,
    )
    return {"train": train_dataset, "test": test_dataset}


t = int(input())

for _ in range(t):
    m, n, x, y = map(int, input().split())
    x -= 1
    y -= 1

    for i in range(x, m * n + 1, m):
        if i % n == y:
            print(i + 1)
            break
    else:
        print(-1)


import pygame, sys, math, random
pygame.init()
screen = pygame.display.set_mode([1680,1000])
dirt = pygame.image.load("dirt.jpg")
mountian = pygame.image.load("mountian.jpg")
water = pygame.image.load("water.jpg")

terrains = [{"sprite": dirt}, {"sprite": mountian}, {"sprite": water}]

themap = [[-1 for x in range(150)] for y in range (150)]

for x in range (0,150):
    for y in range (0,150):
        themap[x][y] = terrains[random.randint(0,2)]

while True:
    pygame.time.delay(50)

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_SPACE:
                for x in range (0,150):
                    for y in range (0,150):
                        themap[x][y] = terrains[random.randint(0,2)]

    for x in range (0, 150):
        for y in range (0, 150):
            screen.blit(themap[x][y]["sprite"], [x * 16, y * 16])

    pygame.display.flip()


from dataclasses import dataclass

import pytest

from jinja2_component.environment import ComponentEnvironment

@pytest.fixture
def env():
    return ComponentEnvironment()

@pytest.fixture
def hello_component():
    @dataclass
    class Hello:
        template_string: str = '
Hello
'

    return Hello

@pytest.fixture
def helloworld_component():
    @dataclass
    class HelloWorld:
        name: str = 'World'
        template_string: str = '
Hello {{name}}
'

    return HelloWorld

def test_import():
    assert 'ComponentEnvironment' == ComponentEnvironment.__name__

def test_construction(env):
    k = 'jinja2_component.extension.ComponentExtension'
    ext = env.extensions
    assert 'ComponentEnvironment' == env.__class__.__name__
    assert {} == env.components
    assert k in ext.keys()
    assert 1 == len(ext.keys())

def test_register_components(env, hello_component):
    assert {} == env.components
    env.register_components([hello_component])
    tag_name = hello_component.__name__
    extensions = list(env.extensions.values())
    assert tag_name in extensions[0].tags

def test_load_template(env, hello_component):
    env.register_components([hello_component])
    hc = hello_component()
    env.load_template(hc)
    assert hello_component.__name__ in env.templates

def test_render_component(helloworld_component):
    env = ComponentEnvironment([helloworld_component])
    result = env.render_component(helloworld_component)
    assert '
Hello World
' == result

def test_render_component_extra(helloworld_component):
    env = ComponentEnvironment([helloworld_component])
    extra_context = dict(name='extra')
    result = env.render_component(helloworld_component,
                                  extra_context=extra_context)
    assert '
Hello extra
' == result

def test_render_string(env, helloworld_component):
    env.register_components([helloworld_component])
    ts = '{% HelloWorld %}'
    result = env.render_string(ts)
    assert '
Hello World
' == result

# This is the problematic one
# def test_render_string_context(env, helloworld_component):
#     env.register_components([helloworld_component])
#     ts = '{% HelloWorld name=context_name %}'
#     context = dict(context_name='CONTEXTBABY')
#     result = env.render_string(ts, context=context)
#     assert '
Hello CONTEXTBABY
' == result


import urllib.request
from bs4 import BeautifulSoup

base_url = 'http://www.domofond.ru/prodazha-kvartiry-magnitogorsk-c2293'

def get_html(url):
    response = urllib.request.urlopen(url)
    return response.read()

def pagination(html):
    soup = BeautifulSoup(html)
    number = soup.find_all('ul', {'class': 'pagination'})[-1].text
    number = re.sub("\D", "", number)
    return number

def parse(html):

    soup = BeautifulSoup(html)
    table = soup.find('div', {'id': 'listingResults'})
    rows = table.find_all('div', {'class': 'pull-left df_listingTileContent '})

    flats = []

    for row in rows:
        #Находим цену квартиры в теге <p> и преобразовываем в текст
        price = row.find('p').text
        #Преобразовываем весь найденный текст в число /отбрасывая все буквы, оставляя лишь числа/
        price = re.sub("\D", "", price)

        #Находим цену квадрата квартиры в теге <span>
        square_price = row.find('span').text
        square_price = re.sub("\D", "", square_price)

        square = row.find('li').text
        square = re.sub("\D", "", square)

        floor = (row.find('li')).find_next('li').text
        floor = re.findall('(\d+)', floor)

        address = row.find('span', {'itemprop': 'address'}).text

        #добавляем квартиры в словарь
        flats.append({
                'price': price,
                'square_price': square_price,
                'square': square,
                'floor': floor[0],
                'floor_all': floor[-1],
                'address': address
        })

    return flats

def main():
    page_count = int(pagination(get_html(base_url)))

    parse(get_html('http://www.domofond.ru/prodazha-kvartiry-magnitogorsk-c2293'))

    flats = []

    for page in range(1, page_count):
        #print('Parsim %d%%' %(page / page_count * 10))
        flats.extend(parse(get_html(base_url + '?Page=%d' % page)))

    for flat in flats:
        print(flat)

if __name__ == '__main__':
    main()


from collections import deque
from queue import Queue

class Graph:
    def __init__(self, v):
        self.V = v
        # 每个node的入度
        self.in_degree = [0 for _ in range(self.V)]
        # 入度为0的集合
        self.dq = deque([])
        # 邻接表
        self.adj = [[] for _ in range(self.V)]

    def add_edge(self, v1, v2):
        self.adj[v1].append(v2)
        self.in_degree[v2]+=1

    def topo_sort(self):
        for v in range(self.V):
            if self.in_degree[v]==0:
                self.dq.append(v)

        # print(self.dq)
        count = 0
        while len(self.dq) != 0:
            v = self.dq.popleft()
            print(v)
            count += 1
            for w in self.adj[v]:
                self.in_degree[w]-=1
                if self.in_degree[w]==0:
                    self.dq.append(w)
            # print(self.dq)

        if count<self.V:
            return False
        else:
            return True

if __name__ == "__main__":
    g = Graph(6)
    g.add_edge(5, 2)
    g.add_edge(5, 0)
    g.add_edge(4, 0)
    g.add_edge(4, 1)
    g.add_edge(2, 3)
    g.add_edge(3, 1)
    print(g.in_degree)
    print(g.adj)
    print(g.topo_sort())


# 'IS' AND 'IS NOT' LOGICAL OPERATORS

some = [1, 9, 21, 10, 16]
9 in some               # MORE LIKA ASKING A QUESTION THAT 'IS 9 IN SOME'

15 in some

20 not in some          # MORE LIKE SAYING '20 IS NOT IN SOME'

# RESULT WILL SHOW IN THE INTERACTIVE IDE

# FINDING AVERAGES
print('METHOD 1\n')
total = 0
count = 0
while True :
    inp = input('Enter a number: ') #CONVERTS INP TO STR
    if inp == 'done' :
        break                #IF 'INP' IS DONE, BREAK OUF OF THE LOOP
    value = float(inp)
    total = total + value
    count = count + 1

average = total / count
print('Average:', average,'\n')

print('METHOD 2\n')
numlist = list()                #Creates an empty set
while True :
    inp = input('Enter a number: ')
    if inp == 'done' : break    # Stops the while loop once done is triggered
    value = float(inp)          # converts str to float
    numlist.append(value)       # appends values into the list

average = sum(numlist) / len(numlist)   # avg
print('Average:', average)


from collections import defaultdict
import torch as th

import multiprocessing as mp
from vec_env import CloudpickleWrapper, clear_mpi_env_vars

class DummyVecEnv():

    def __init__(self, env_fn, batch_size):
        self.batch_size = batch_size
        self.envs = [env_fn.x() if isinstance(env_fn, CloudpickleWrapper) else env_fn() for _ in range(batch_size)]
        pass

    def step(self, actions, a=None):
        if a is None:
            obs_lst = []
            reward_lst = []
            done_lst = []
            info_lst = []
            for i in range(self.batch_size):
                obs, reward, done, info = self.envs[i].step(actions[i])
                obs_lst.append(obs)
                reward_lst.append(reward)
                done_lst.append(done)
                info_lst.append(info[0])

            return th.stack(obs_lst) if not isinstance(obs_lst[0], dict) else {k:th.stack([o[k] for o in obs_lst]) for k,v in obs_lst[0].items()}, \
                   th.FloatTensor(reward_lst), \
                   done_lst, \
                   info_lst
        else:
            obs, reward, done, info = self.envs[a].step(actions)
            return obs, th.FloatTensor([reward]), done, info

    def reset(self, idx=None):
        if idx is None:
            idx_lst = list(range(self.batch_size))
        else:
            idx_lst = [idx] if isinstance(idx, int) else idx
        obs_lst = []
        for i in idx_lst:
            obs = self.envs[i].reset()
            obs_lst.append(obs)
        if len(idx_lst) == 1:
            return obs_lst[0] if not isinstance(obs_lst[0], dict) else {k: v for  k, v in obs_lst[0].items()}
        else:
            return th.stack(obs_lst) if not isinstance(obs_lst[0], dict) else {k:th.stack([o[k] for o in obs_lst]) for k,v in obs_lst[0].items()}

    def render(self, **kwargs):
        img = self.envs[0].render('rgb_array')
        return img

    def close(self):
        for i in range(self.batch_size):
            self.envs[i].close()

    def get_obs_space(self):
        return self.envs[0].get_obs_space()

    def get_action_space(self):
        return self.envs[0].get_action_space()

    def get_available_actions(self, idx=None):
        if idx is None:
            idx_lst = list(range(self.batch_size))
        else:
            idx_lst = [idx] if isinstance(idx, int) else idx

        avail_actions_dct = defaultdict(lambda: [])
        for i in idx_lst:
            avail_actions = self.envs[i].get_available_actions()
            for k, v in avail_actions.items():
                avail_actions_dct[k].append(v)
        if len(idx_lst) == 1:
            return {k:v[0] for k, v in avail_actions_dct.items()}
        else:
            return {k:th.stack(v) for k, v in avail_actions_dct.items()}

    def get_trajectory(self, idx=None):
        if idx is None:
            idx_lst = list(range(self.batch_size))
        else:
            idx_lst = [idx] if isinstance(idx, int) else idx
        return [self.envs[_id].trajectory for _id in idx_lst]
    pass

def dummy_vec_env_worker(remote, parent_remote, env_fn_wrappers, batch_size=None):
    vec_env = DummyVecEnv(env_fn=env_fn_wrappers, batch_size=batch_size)
    parent_remote.close()
    try:
        while True:
            cmd, data = remote.recv()
            if cmd == 'step':
                remote.send(vec_env.step(data))
            elif cmd == 'reset':
                remote.send(vec_env.reset(data))
            elif cmd == 'render':
                remote.send(vec_env.render())
            elif cmd == 'close':
                remote.close()
                break
            elif cmd == 'get_spaces_spec':
                remote.send(CloudpickleWrapper((vec_env.envs[0].get_obs_space(),
                                                vec_env.envs[0].get_action_space())))
            elif cmd == 'get_available_actions':
                remote.send(vec_env.get_available_actions(data))
            elif cmd == 'get_trajectory':
                remote.send(vec_env.get_trajectory(data))
            else:
                raise NotImplementedError
    except KeyboardInterrupt:
        print('SubprocVecEnv worker: got KeyboardInterrupt')
    finally:
        vec_env.close()

def make_environment_func(env_tag, env_args):

    # Create environment
    env_registry = {"simple_4way_grid": Simple4WayGrid, "mini_grid": None}
    assert env_tag in env_registry, "Environment {} not in registry!".format(env_tag)

    make_env_fn = None
    if env_tag in ["simple_grid", "simple_4way_grid"]:
        def _make_env_fn():
            env = env_registry[env_tag](max_steps=env_args.env_arg_max_steps, grid_dim=env_args.env_arg_grid_dim)
            env.max_steps = env_args.env_arg_max_steps  # min(env.max_steps, max_steps)
            return env

    else:
        print("Unknown model")

    return _make_env_fn


import numpy as np

def find(track_id, songreader):
    for row in songreader:
        if row[0].strip() == track_id:
            return row

if __name__ == '__main__':
    songreader = np.genfromtxt('/Users/julio.barros/Downloads/msd_tagtraum_cd2.cls', delimiter='\t', usecols=range(2), dtype=str)
    songreader2 = np.genfromtxt('/Users/julio.barros/chamine-learning/musicas_nos_2_2.csv', delimiter='\t', usecols=range(1), dtype=str)

    dic = {}

    for row in songreader2:
        dic[row] = True

    for row in songreader:
        if (dic.get(row[0], False)):
            print(row[0], '\t', row[1])


"""
任意文件下载漏洞批量下载脚本
"""
import os
import threading

import requests
import threadpool

from config import *

total_urls = 0
complete_num = 0
dir_lock = threading.Lock()
progress_lock = threading.Lock()

def request_handler(urls):
    """
    urls 已经去重去参数，只保留相对路径，假设urls.txt中的链接为 http://xx.xx.com/xx/xx.php,
    执行到这一步就变成了 xx/xx.php。
    接下来可以用自定义函数处理它，比如利用文件包含漏洞下载源码的时候需要用php伪协议。
    @params:
        urls: 形如['xx/xx.php','xx/xxx/xxx.php']储存相对路径的列表
    """
    return urls

def response_handler(response):
    """
    用于处理下载后的页面，有些情况下服务器会返回多余的数据，这时候可以实现这个函数把多余数据删掉。
    @params:
        response: requests.Response 类，服务器响应包，详情参考requests文档。
    @rtype bytes
    """
    return response.content

def printProgress(iteration, total, prefix='', suffix='', decimals=1, barLength=100):
    """
    Call in a loop to create a terminal progress bar
    @params:
        iteration   - Required  : current iteration (Int)
        total       - Required  : total iterations (Int)
        prefix      - Optional  : prefix string (Str)
        suffix      - Optional  : suffix string (Str)
        decimals    - Optional  : positive number of decimals in percent complete (Int)
        barLength   - Optional  : character length of bar (Int)
    """
    import sys
    formatStr = "{0:." + str(decimals) + "f}"
    percent = formatStr.format(100 * (iteration / float(total)))
    filledLength = int(round(barLength * iteration / float(total)))
    bar = '#' * filledLength + '-' * (barLength - filledLength)
    sys.stdout.write('\r%s |%s| %s%s %s  ' %
                     (prefix, bar, percent, '%', suffix)),
    if iteration == total:
        sys.stdout.write('\n')
    sys.stdout.flush()

def data_clean(urls):
    slice_start = urls[0].index(SITE)+len(SITE)+1
    urls = set(map(lambda url: url.partition('?')[0].strip(), urls))
    urls = filter(lambda url: url.rpartition('.')[-1] in EXT_NAME, urls)
    urls = list(map(lambda url: url[slice_start:], urls))
    urls = request_handler(urls)
    return urls

def real_down(url):
    file_path = os.path.join('..', SITE, url)
    dir_path = file_path.rpartition('/')[0]
    dir_lock.acquire()
    if not os.path.exists(dir_path) and dir_path != '':
        os.makedirs(dir_path)
    dir_lock.release()
    # 参数 urls 经过去重，因此 file_path 具有唯一性，不存在多个线程同时操作同一 file_path 的情况，所以下面的操作无需上锁
    if not os.path.exists(file_path):
        response = requests.get(LINK.format(url))
        download_content = response_handler(response)
        with open(file_path, 'wb') as f:
            f.write(download_content)
    global complete_num
    progress_lock.acquire()
    complete_num += 1
    printProgress(complete_num, total_urls, 'Progress:', url, barLength=30)
    progress_lock.release()

if __name__ == '__main__':
    with open('urls.txt', 'r', encoding='utf8') as f:
        relative_urls = data_clean(f.readlines())
    total_urls = len(relative_urls)
    pool = threadpool.ThreadPool(THREADS)
    tasks = threadpool.makeRequests(real_down, relative_urls)
    [pool.putRequest(task) for task in tasks]
    pool.wait()


from uuid import uuid4
from hyperion.utils.logger import ProjectLogger
from hyperion.audio.io.source.in_device import InDevice

import os
import argparse
import numpy as np
import soundfile as sf

INPRINT_DURATION = 5
SAMPLING_RATE = 16000
CHUNK_DURATION_MS = 512
CHUNK_SIZE = int(SAMPLING_RATE * CHUNK_DURATION_MS / 1000)

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='Record voice inprint for a new speaker')
    parser.add_argument('name', type=str, help='Speaker name.')
    parser.add_argument('samples_dir', default='~/.hyperion/speakers_samples', type=str, help='Speaker samples directory.')
    args = parser.parse_args()

    args.samples_dir = os.path.expanduser(args.samples_dir)

    mic = InDevice(-2, 16000, db=60)
    mic.open()

    buffer = None
    recording_size = INPRINT_DURATION * SAMPLING_RATE
    stream = mic()
    for chunk in stream:
        ProjectLogger().info('Sound chunk received.')
        if buffer is not None and len(buffer) >= recording_size:
            break
        if chunk is None:
            continue
        buffer = chunk if buffer is None else np.concatenate([buffer, chunk], axis=0)

    mic.close()

    outdir = os.path.join(args.samples_dir, args.name)
    os.makedirs(outdir, exist_ok=True)
    sf.write(os.path.join(outdir, f'{uuid4()}.wav'), buffer[:recording_size, ...], SAMPLING_RATE)


import os
import json

import torch
import numpy as np
import random

from asd import BEST_PRETRAIN_MODEL_NAME, create_agent
from dataset import ASDPatientInteractionSimulator, SimPaDataset

EVAL_FILE = "Metrics.json"

def write_json(data, fp):
    with open(fp, "w") as outfile:
        json.dump(data, outfile, indent=4)

def initialize_seed(seed):
    """Method for seeding the random generators.

    Parameters
    ----------
    seed: int
        the seed to be used.

    Returns
    -------
    None

    """
    torch.manual_seed(seed)
    if torch.cuda.is_available():
        torch.cuda.manual_seed(seed)
    np.random.seed(seed)
    random.seed(seed)

def load_model(model, path):
    data = torch.load(path)
    model.load_state_dict(data["agent_state_dict"])
    model.eval()
    return model

def asd_classifier_test(agent, eval_dl, args):
    with torch.no_grad():
        agent.train(False)
        results = eval_dl.evaluate(
            agent,
            args.interaction_length,
            args.num_valid_trajs,
            None,
            args.seed,
            args.cuda_idx,
            args.thres,
            args.masked_inquired_actions,
            args.compute_metrics_flag,
            args.eval_batch_size,
        )
    out_path = f"{args.output}/{args.eval_prefix}{EVAL_FILE}"
    write_json(results, out_path)
    return results

def asd_test(args, params=None):
    """Method for pretraining an agent against a gym environment.

    Parameters
    ----------
    args: dict
        The arguments as provided in the command line.
    params: dict
        The parameters as provided in the configuration file.
        Default: None

    Return
    ------
    None

    """

    if params is None:
        params = {}

    assert args.batch_size > 0

    if not os.path.exists(args.output):
        os.makedirs(args.output)

    if args.seed is None:
        args.seed = 1234

    print(f"Asd testing: Using seed [{args.seed}] for this process.")

    args.metric = "accuracy"

    # initialize the random generator
    initialize_seed(args.seed)

    # create environment
    env = ASDPatientInteractionSimulator(args, patient_filepath=args.data, train=False)
    print(f"Test environment size: {env.sample_size}")

    args.inp_size = env.state_size + 5
    args.symptom_prediction_size = env.symptom_size
    args.action_state_size = 1
    args.patho_size = env.diag_size if args.patho_size is None else args.patho_size

    # import pdb;pdb.set_trace()
    # instantiate the agent
    saved_model_path = f"{args.output}/{BEST_PRETRAIN_MODEL_NAME}"
    agent = create_agent(args)

    args.device = torch.device(
        f"cuda:{args.cuda_idx}"
        if torch.cuda.is_available() and args.cuda_idx is not None
        else "cpu"
    )

    agent = load_model(agent, saved_model_path)
    agent.to(args.device)

    # create the datasets
    ds_valid = SimPaDataset(env, args.interaction_length)

    # infer
    asd_classifier_test(agent, ds_valid, args)


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Tue Nov 29 16:24:44 2016

@author: abauville
"""

# Input Test for Stokes FD
import sys
sys.path.insert(0, '../../src/UserInput')
#import json
#from InputDef import *
import InputDef as Input
import MaterialsDef as material
# Optional: uncomment the next line to activate the plotting methods to the Geometry objects, requires numpy and matplotlib
#from GeometryGraphical import *
from math import pi, sqrt, tan, sin, cos
print("\n"*5)

##             Units
## =====================================
m       = 1.0
s       = 1.0
K       = 1.0
kg      = 1.0

cm      = 0.01      * m
km      = 1000.0    * m

mn      = 60        * s
hour    = 60        * mn
day     = 24        * hour
yr      = 365       * day
Myr     = 1e6       * yr

Pa      = 1.0
MPa     = 1e6

deg     = pi/180

##      Declare singleton objects
## =====================================
Setup = Input.Setup(isDimensional=True)
Grid = Setup.Grid
Numerics = Setup.Numerics
Particles = Setup.Particles
Physics = Setup.Physics
Visu = Setup.Visu
Char = Setup.Char
BCStokes = Setup.BC.Stokes
BCThermal = Setup.BC.Thermal
ICThermal = Setup.IC.Thermal
ICDarcy = Setup.IC.Darcy
MatProps = Setup.MatProps
Geometry = Setup.Geometry
Output = Setup.Output

## Description
## =====================================
Setup.Description = "Angle of shear bands benchmark, based on Kaus, 2010 (doi:10.1016/j.tecto.2009.08.042)"

Numerics.phiMin = 1e-5
Numerics.phiMax = 0.9

Numerics.etaMin = 1e-6

##          Material properties
## =====================================
StickyAir   = Input.Material("StickyAir")
Matrix      = Input.Material("Sediments")
Inclusion   = Input.Material("Sediments")

Setup.MatProps = {"0":StickyAir,"1":Matrix,"2":Inclusion}

PhaseRef = Inclusion
PhaseRef.isRef = True

Matrix.name     = "Sediment"
Inclusion.name  = "Inclusion"

Matrix.vDiff    = material.DiffusionCreep       ("Off")
Inclusion.vDiff = material.DiffusionCreep       ("Off")
StickyAir.vDiff = material.DiffusionCreep       (eta0=1E16)

Matrix.vDisl    = material.DislocationCreep     (eta0=1E25, n=1)
Inclusion.vDisl = material.DislocationCreep     (eta0=1E20, n=1)

Matrix.rho0     = 2700  * kg/(m**3)
Inclusion.rho0  = 2700  * kg/(m**3)

Matrix.cohesion     = 10    * MPa
Inclusion.cohesion  = 1    * MPa

Matrix.cohesionWeakFac = 0.0
Matrix.frictionAngleWeakFac = 0.0
Matrix.staticPfFacWeakFac = 0.2
Matrix.strainWeakStart = 0.0
Matrix.strainWeakEnd = 0.3

Matrix.frictionAngle    = 30 * deg
Inclusion.frictionAngle = 0 * deg

Matrix.G                = 5e13 * Pa
Inclusion.G             = 5e13 * Pa
StickyAir.G             = Matrix.G
StickyAir.cohesion = Matrix.cohesion

#StickyAir.cohesion = Matrix.cohesion

##              Grid
## =====================================
#Grid.xmin = -1000.0e3
#Grid.xmax =  1000e3
#Grid.ymin = -380e3
#Grid.ymax =  20.0e3
RFac = 2; # Resolution Factor
HFac = 2.5

W = HFac * 60 * km
H = HFac * 10 * km
HStickyAir = HFac * 5 * km
d = HFac*800         # inclusion size

Grid.xmin = -W/2
Grid.xmax = +W/2
Grid.ymin =  0.0
Grid.ymax =  H + HStickyAir
Grid.nxC = RFac*128*2
Grid.nyC = RFac*32*2

Grid.fixedBox = False

dx = (Grid.xmax-Grid.xmin)/Grid.nxC
dy = (Grid.ymax-Grid.ymin)/Grid.nyC

##              Numerics
## =====================================
Numerics.nTimeSteps = 20
BCStokes.backStrainRate = -1.0e-15
Numerics.CFL_fac_Stokes = 0.25
Numerics.CFL_fac_Darcy = 0.8
Numerics.CFL_fac_Thermal = 10.0
Numerics.nLineSearch = 3
Numerics.maxCorrection  = 1.0
Numerics.minNonLinearIter = 50
Numerics.maxNonLinearIter = 50

Numerics.absoluteTolerance = 1e-4

Numerics.yieldComputationType = 1
Numerics.invariantComputationType = 1

Numerics.dtMaxwellFac_EP_ov_E  = 0.5;   # lowest,       ElastoPlasticVisc   /   G
Numerics.dtMaxwellFac_VP_ov_E  = 0.0;   # intermediate, ViscoPlasticVisc    /   G
Numerics.dtMaxwellFac_VP_ov_EP = 0.5;   # highest,      ViscoPlasticVisc    /   ElastoPlasticStress
Numerics.use_dtMaxwellLimit = False

Particles.nPCX = 4
Particles.nPCY = 4
Particles.noiseFactor = 0.0

##              Output
## =====================================
Output.folder = "/Users/abauville/GoogleDrive/StokesFD_Output/OutputTest"
#Output.khi = True
#Output.strainRate = True
#Output.frequency = Numerics.nTimeSteps-1

##                 BC
## =====================================
#BCStokes.SetupType = "Sandbox"

#BCStokes.refValue       = 1.0 * cm/yr / 1.0

#BCThermal.TB = 30.0 + 273.0
#BCThermal.TT = 0.0    + 273.0

#Mantle.vDisl.E = 0.0
#Mantle.vDiff.E = 0.0
#BCThermal.DeltaL = 1000e3+(Grid.ymin);

##                 IC
## =====================================
#Setup.IC.Thermal = Input.IC_HSC(age=100*Myr)
ICThermal.age = 100*Myr

ICDarcy.background = 0.0#Numerics.phiMin
ICDarcy.Amp = 0.0
ICDarcy.xc = Grid.xmin+(Grid.xmax-Grid.xmin)/2
ICDarcy.yc = Grid.ymin+(Grid.ymax-Grid.ymin)/2
ICDarcy.wx = (Grid.xmax-Grid.xmin)/16.0
ICDarcy.wy = (Grid.xmax-Grid.xmin)/16.0

##              Non Dim
## =====================================

#L = (Grid.xmax-Grid.xmin)/2.0
#L = (Grid.ymax-Grid.ymin)/2.0
#BCStokes.backStrainRate = - BCStokes.refValue / L

Char.set_based_on_lithostatic_pressure(PhaseRef,BCStokes,BCThermal,Physics,Grid,Length=H/2.0)
#Char.set_based_on_strainrate(PhaseRef,BCStokes,BCThermal,Grid)

Numerics.dtVep = .1*Char.time

f = 0.5
Numerics.dtIni = 15000*yr
Numerics.dtMin = 15000*yr
Numerics.dtMax = 15000*yr

##              Geometry
## =====================================

#W = Grid.xmax-Grid.xmin
#H = Grid.ymax-Grid.ymin

inclusion_w = 4.0*dx
inclusion_h = 4.0*dx

slope = tan(0*pi/180)

i = 0
MatrixPhase = 1
Geometry["%05d_line" % i] = Input.Geom_Line(MatrixPhase,slope,H,"y","<",Grid.xmin*2.0,Grid.xmax*2.0)
InclusionPhase = 2
i+=1
Geometry["%05d_line" % i] = Input.Geom_Line(InclusionPhase,0.0,inclusion_h,"y","<",Grid.xmin + W/2 - inclusion_w/2,Grid.xmin + W/2 + inclusion_w/2)

CharExtra = Input.CharExtra(Char)
RefVisc = PhaseRef.getRefVisc(0.0,Char.temperature,abs(BCStokes.backStrainRate))

##            Visualization
## =====================================
Particles.passiveDy = (Grid.ymax-Grid.ymin)*1/16
Particles.passiveDx = Particles.passiveDy

Visu.showParticles = False
Visu.filter = "Nearest"
Visu.particleMeshRes = 6
Visu.particleMeshSize = 1.5*(Grid.xmax-Grid.xmin)/Grid.nxC

Visu.type = "StrainRate"
Visu.writeImages = False
#Visu.outputFolder = "/Users/abauville/JAMSTEC/StokesFD_OutputTest/"
Visu.outputFolder = "/Users/abauville/GoogleDrive/Output_Sandbox/"
Visu.transparency = True

Visu.showGlyphs = False
Visu.glyphMeshType = "Triangle"
Visu.glyphScale = 0.1/(BCStokes.refValue/(Char.length/Char.time))
glyphSpacing = (Grid.ymax-Grid.ymin)/8 #50 * km
Visu.glyphSamplingRateX = round(Grid.nxC/((Grid.xmax-Grid.xmin)/glyphSpacing))
Visu.glyphSamplingRateY = round(Grid.nyC/((Grid.ymax-Grid.ymin)/glyphSpacing))

Visu.height = 0.5 * Visu.height
Visu.width = 1* Visu.width

#Visu.filter = "Linear"
Visu.filter = "Nearest"

Visu.shiftFacY = 0.0

print("\n"*5)
CharExtra = Input.CharExtra(Char)
RefVisc = PhaseRef.getRefVisc(0.0,Char.temperature,abs(BCStokes.backStrainRate))

print("dx = " + str(dx) + ", dy = " + str(dy) )

RefP = PhaseRef.rho0*abs(Physics.gy)*H/2.0

Visu.colorMap.Stress.scale  = 100.0e6/CharExtra.stress
Visu.colorMap.Stress.center = 0*200.0e6/CharExtra.stress
Visu.colorMap.Stress.max    = 1.0
Visu.colorMap.Viscosity.scale = RefVisc/CharExtra.visc
Visu.colorMap.Viscosity.max = 4.0
Visu.colorMap.StrainRate.scale = abs(BCStokes.backStrainRate/(1.0/Char.time))
Visu.colorMap.StrainRate.max = 1.0

Visu.colorMap.Stress.max    = 0.1

Visu.colorMap.Pressure.scale  = RefP/CharExtra.stress
Visu.colorMap.Pressure.center = 0.0
Visu.colorMap.Pressure.max    = 1.00

Visu.colorMap.VelocityDiv.scale = 1e-1

Visu.colorMap.Khi.max = 5.0
Visu.colorMap.Khib.max = 5.0

Visu.closeAtTheEndOfSimulation = False

###          Write the Input file
### =====================================
Input.writeInputFile(Setup)


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

import os
import subprocess
import sys

def get_deb_files(deb_path):
    deb_files = []
    for root, dirs, files in os.walk(deb_path, topdown=False):
        for name in files:
            # print(os.path.join(root, name))
            deb_files.append(os.path.join(root, name))
        # for name in dirs:
        #     print(os.path.join(root, name))
    return deb_files

def unpack_deb(deb_path):
    deb_files = get_deb_files(deb_path)
    for deb_file in deb_files:
        try:
            if deb_file == __file__:
                continue
            # if len(deb_file) < 4:
            #     continue
            # if deb_file[-4:] != ".deb" or deb_file[-5:0] != ".udeb":
            if deb_file[-4:] != ".deb":
                continue
            basename = os.path.basename(deb_file)
            subprocess.call(["dpkg-deb", "-R", deb_file, os.path.splitext(basename)[0]])
        except Exception as e:
            print("Unpack {} error, because {}".format(deb_file, e))

if __name__ == '__main__':
    if len(sys.argv) != 2:
        pkg_path = os.path.dirname(os.path.realpath(__file__))
    else:
        pkg_path = sys.argv[1]
    unpack_deb(pkg_path)


import math
import random
import sched
import threading
import time
from dataclasses import dataclass
from typing import Any, Dict, Optional, Tuple, cast

from absl.logging import logging

from snowflake.snowpark import Session
from snowflake.snowpark.types import (
    DateType,
    StructType,
    TimestampType,
    TimeType,
    _FractionalType,
    _IntegralType,
    _NumericType,
)

logger = logging.getLogger(__name__)

@dataclass(frozen=True)
class Stats:
    mean: float
    min_val: float
    max_val: float
    std: float

def replace_nan(val: Any, default_val: Any = 0) -> Any:
    return default_val if math.isnan(val) else val

class SyntheticDataGenerator:
    def __init__(self, session: Session, database: str, schema: str, source_table: str) -> None:
        self._session = session
        self._database = database
        self._schema = schema
        self._source_table = source_table
        self._table_schema, self._stats = self._collect_metadata()
        self._trigger_thread: Optional[threading.Thread] = None

    def trigger(self, batch_size: int, num_batches: int, freq: int = 10) -> None:
        def _run() -> None:
            s = sched.scheduler(time.monotonic, time.sleep)
            for i in range(num_batches):
                s.enter(freq * i, 1, self._generate_new_data, argument=(batch_size,))
            s.run()

        self._trigger_thread = threading.Thread(target=_run)
        self._trigger_thread.start()

    def __del__(self) -> None:
        if self._trigger_thread is not None:
            self._trigger_thread.join()

    def _collect_metadata(self) -> Tuple[StructType, Dict[str, Stats]]:
        df = self._session.table([self._database, self._schema, self._source_table])
        df_stats = df.to_pandas().describe()
        stats = {}
        for s in df.schema.fields:
            if not isinstance(s.datatype, (DateType, TimeType, TimestampType, _NumericType)):
                raise RuntimeError(f"Unsupported source column type {s.datatype} for {s.name}")

            cur_stats = df_stats[s.name]
            stats[s.name] = Stats(
                mean=replace_nan(cur_stats["mean"]),
                min_val=replace_nan(cur_stats["min"]),
                max_val=replace_nan(cur_stats["max"]),
                std=replace_nan(cur_stats["std"]),
            )

        return df.schema, stats

    def _generate_new_data(self, num_rows: int) -> None:
        batch = []
        for _ in range(num_rows):
            row = []
            for field in self._table_schema.fields:
                stats = self._stats[field.name]
                if isinstance(field.datatype, TimestampType):
                    row.append(time.time())
                elif isinstance(field.datatype, _IntegralType):
                    row.append(random.randint(cast(int, stats.min_val), cast(int, stats.max_val)))
                elif isinstance(field.datatype, _FractionalType):
                    row.append(random.uniform(stats.min_val, stats.max_val))
                else:
                    raise RuntimeError(f"Unsupported type: {field.datatype}")
            batch.append(row)

        df = self._session.create_dataframe(batch, self._table_schema)
        df.write.mode("append").save_as_table(  # type:ignore[call-overload]
            [self._database, self._schema, self._source_table], block=True
        )
        logger.info(f"Dumped {num_rows} rows to table {self._source_table}.")


file1 = "a_example.txt"
file2 = "b_read_on.txt"
file3 = "c_incunabula.txt"
file4 = "d_tough_choices.txt"
file5 = "e_so_many_books.txt"
file6 = "f_libraries_of_the_world.txt"

files = [file1, file2, file3, file4, file5, file6]

def read_input(file):
    with open(file, 'r') as f:
        B, L, D = [int(x) for x in f.readline().split()]
        scores = [int(x) for x in f.readline().split()]
        libraries = []
        for i in range(L):
            line = [int(x) for x in f.readline().split()]
            temp = [line[1], line[2]]
            temp.append(sorted([(scores[int(x)], int(x)) for x in f.readline().split()],key = lambda x: (-x[0], x[1])))
            libraries.append(temp)
        return (B,L,D,scores,libraries)

def outputFile(arr, filename):
    f = open(filename, "w")
    f.write(str(len(arr)) + "\n")
    for x in arr:
        f.write(str(x[0]) + " " + str(len(x[1])) + "\n")
        for y in x[1]:
            f.write(str(y) + " ")
        f.write("\n")
    print(arr)
    f.close()


####################################################################
                            ## imports ##
####################################################################

from tabnanny import verbose
import numpy as np
from numpy import pi
import matplotlib.pyplot as plt
import math
from typing import Iterable, Union, Optional

## qiskit imports ~
# from qiskit import *
from qiskit.algorithms import *
from qiskit import QuantumRegister, ClassicalRegister, QuantumCircuit, AncillaRegister
from qiskit import quantum_info, IBMQ, Aer
from qiskit import BasicAer, transpile
from qiskit.utils import QuantumInstance
from qiskit.quantum_info import Statevector, partial_trace , DensityMatrix
from qiskit.algorithms import optimizers, AmplitudeEstimation, EstimationProblem, AmplificationProblem, Grover, GroverResult, AmplitudeAmplifier
from qiskit.circuit.library import LinearAmplitudeFunction, LinearPauliRotations, PiecewiseLinearPauliRotations, WeightedAdder, GroverOperator
from qiskit_finance.circuit.library import LogNormalDistribution, NormalDistribution
from qiskit.visualization import plot_histogram, plot_state_qsphere, plot_bloch_multivector, plot_bloch_vector
from qiskit import execute

qsm = Aer.get_backend('qasm_simulator')
stv = Aer.get_backend('statevector_simulator')
aer = Aer.get_backend('aer_simulator')

#############################################################################
                    ## grover operator sub-routines ##
#############################################################################

def str_to_oracle(pattern: str, name= 'oracle', return_type = "QuantumCircuit" ) -> Union[QuantumCircuit,  Statevector] :
    """ Convert a given string to an oracle circuit
        ARGS:
             pattern: a numpy vector with binarry entries
        RETURNS:
                QuantumCircuit   """

    l = len(pattern)
    qr = QuantumRegister(l, name='reg')
    a = AncillaRegister(1, name='ancilla')
    oracle_circuit = QuantumCircuit(qr, a, name= name+str(pattern))
    for q in range(l):
        if(pattern[q]=='0'): oracle_circuit.x(qr[q])
    oracle_circuit.x(a)
    oracle_circuit.h(a)
    oracle_circuit.mcx(qr, a)
    oracle_circuit.h(a)
    oracle_circuit.x(a)
    for q in range(l):
        if(pattern[q]=='0'): oracle_circuit.x(qr[q])

    #oracle_circuit.barrier()
    if return_type == "QuantumCircuit":
        return oracle_circuit

def generate_oracles(good_states: list) -> QuantumCircuit :
    """ Return a QuantumCircuit that implements the oracles given the good_states
        ARGS:
            good_states: list of good staes, states must be binary strings, Eg. ['00', '11']
        RETURNS:
            QuantumCircuit """

    oracles = [ str_to_oracle(good_state) for good_state in good_states ]
    oracle_circuit = oracles[0]
    for oracle in oracles[1:] :
        oracle_circuit.compose(oracle,  inplace= True)

    return oracle_circuit

def to_oracle(pattern, name= 'oracle'):
    """ Convert a given pattern to an oracle
        input: pattern= a numpy vector with binarry entries
        output: oracle.Gate    """

    l = len(pattern)
    qr = QuantumRegister(l, name='reg')
    a = AncillaRegister(1, name='ancilla')
    qc = QuantumCircuit(qr, a, name= name+str(pattern))
    for q in range(l):
        if(pattern[q]==0): qc.x(qr[q])
    qc.x(a)
    qc.h(a)
    qc.mcx(qr, a)
    qc.h(a)
    qc.x(a)
    for q in range(l):
        if(pattern[q]==0): qc.x(qr[q])
    #qc.barrier()
    return qc.to_gate()

def diffuser(l:int)-> QuantumCircuit :
    """ Generate the Diffuser operator for the case where the initial state  is
        the equal superposition state of all basis vectors
        input: l= no. of qubits
        output: diffuser.Gate    """

    qr = QuantumRegister(l, name='reg')
    a = AncillaRegister(1, name='ancilla')
    circuit = QuantumCircuit(qr, a, name= 'Diff.')

    circuit.h(qr)
    circuit.x(qr)

    circuit.x(a)
    circuit.h(a)
    circuit.mcx(qr ,a)
    circuit.h(a)
    circuit.x(a)

    circuit.x(qr)
    circuit.h(qr)

    return circuit.to_gate()

def grover_iterate(qc, oracles, diffuser, qreg_u, ancilla, steps):
    """ Run full Grover iteration for given number of steps.
        input:
        qc: QuantumCiruit to append to
        oracles: a list of oracles generated from 'to_oracle()' function
        diffuser: a diffuser from 'diffuser()' function
        steps: no. of grover iterates"""
    for step in range(steps):
        for oracle in oracles:
            qc.append(oracle, list(range(qc.num_qubits)) )
        qc.append(diffuser, list([q for q in qreg_u])+ list(ancilla) )
        # qc.barrier()
    return qc

def grover(patterns, grover_steps): ## modified sub-routine for grover based on the 'grover_iterate()'

    dim = len(patterns[0])

    # create oracles ~\
    oracles = []
    for pattern in patterns : oracles.append( to_oracle(pattern))

    # create diffuser ~\
    diff = diffuser(dim)

    # create circuit ~\
    qreg = QuantumRegister(dim, name= 'init')
    ancilla = AncillaRegister(1, name='ancilla')
    qc = QuantumCircuit(qreg, ancilla, name='grover'+'^'+str(grover_steps))
    qc = grover_iterate(qc, oracles, diff, qreg, ancilla,grover_steps)

    return qc

####################################################################################
                        ## single qubit handler functions  ##
####################################################################################

def s_psi0(p:float)-> QuantumCircuit :  ## initial state preparation for a single qubit
    """ Prepare a QuantumCircuit that intiates a single qubit state
        input:
            p= amplitude of |1> in intial state
        output:
            s_psi0                                             """

    if verbose: print("inside-> 's_psi0'")

    qc = QuantumCircuit(1, name= " S_psi0 ")
    theta = 2*np.arcsin(np.sqrt(p))
    qc.ry(theta, 0)

    return qc

def Q(p: float, power:int= 1)-> QuantumCircuit:
    """ Prepare an 'QuantumCircuit' to implement grover operator 'Q'
        input:
            p= amplitude of |1> in intial state
            power= no.of times 'Q' is imposed
        output:
            Q^k                                                 """

    if verbose: print("inside-> 'Q'")

    theta = 2*np.arcsin(np.sqrt(p))
    qc = QuantumCircuit(1, name= ' Q'+ '^'+ str(power) )
    qc.ry(2*theta*power, 0)

    return qc

#####################################################################################
                            ## sub-routines for QPE ##
#####################################################################################

def crot(qc, l):
    """ Function to generate Controlled Rotation Ooeration  """

    if l == 0:
        return qc
    l = l-1
    qc.h(l)
    for q in range(l):
        qc.cp(pi/2**(l-q), q, l)
    #qc.barrier()
    # qc.draw()

def QFT(qc):
   """function to generate QFT circuit """

   dim = qc.num_qubits
   for q in range(dim):
      crot(qc, dim-q)
   for q in range(int(dim/2)):
      qc.swap(q, dim-q-1)

   #qc.draw()
   return qc

def qpe(): ## TODO
    pass

#####################################################################################
                ## Helper function for Quantum Phase Estimation ##
#####################################################################################

def qpe(p: float, trainable:bool= False, p_param:Union[float, None]= None , precision:int= 4, no_estimates:int= 5 ):

    ## define the grover operator ~
    # p = 0.25

    # precision= 4
    ## generate the Quantum Circuit ~
    preg = QuantumRegister(precision, name= 'precision_q')
    qreg = QuantumRegister(1, name='qreg')
    creg = ClassicalRegister(precision, name='precision_c')
    qc = QuantumCircuit(preg,qreg, creg)

    qc.h(preg)
    qc.append(s_psi0(p), [precision] )
    qc.barrier()

    if trainable== True:
        for q in range(precision):
            qc.append(Q( p_param  , 2**q).to_gate().control(1), [q]+list(range(precision,precision+1)) )

    else:
        for q in range(precision):
            qc.append(Q(p,2**q).to_gate().control(1), [q]+list(range(precision,precision+1)) )

    qftgate_inv = QFT(QuantumCircuit(precision, name='QFT')).to_gate().inverse()
    qc.barrier()
    qc.append(qftgate_inv, list(range(precision)))

    qc.measure(preg, creg)
    shots = 2000
    job = execute(qc, backend= aer, shots= shots)
    counts = job.result().get_counts()

    # no_estimates= 5
    estimate = sorted(zip(counts.values(), counts.keys()), reverse= True)
    p_est = 0
    for p in range(no_estimates):
        p_est += np.sin(int(estimate[p][1], 2)*pi/(2**precision))**2 * (estimate[p][0]/ shots)

    return p_est

def to_minimize(p_params, p= 0.2 , precision:int= 4, no_estimates:int= 5 ):
    print("inside-> to_minimize") ##
    p_est = qpe(p, trainable= True, p_param= p_params[0])
    print("ourside-> qpe, p_est", p_est)
    cost = (p_params - p_est)**2
    print("cost ", cost)
    return cost

#####################################################################################
                ## Helper functions for maximum likelihood estimation ##
#####################################################################################

def likelihood(n,m, shots, thetas= np.linspace(0, 2*pi, 100), log= False):
    """ Generate likelihood function over the given range of 'thetas'
        Input:
            n = count of 'good' state i.e '1'
            m = no. of grover steps
            shots = no. of shots
            thetas = range of angles
            log = (Bool) return the log value of likelihood
        Output:
            dictionary containing {theta: liklihood(theta)} pairs"""
    dic = {}
    for theta in thetas:
        dic[theta] = (((np.sin((2*m+1)*theta))**2)**n)*(((np.cos((2*m+1)*theta))**2)**(shots-n))
        if log== True: dic[theta] = np.log((((np.sin((2*m+1)*theta))**2)**n)*(((np.cos((2*m+1)*theta))**2)**(shots-n)) )
    return dic

def combine_likelihood(lkhs):
    """ Combine a list of liklehoods """
    dic = lkhs[0]
    for lkh in lkhs[1:]:
        for theta in lkh.keys():
            dic[theta] = dic[theta]*lkh[theta]

    return dic

def generate_le(p,q= 1, shots= 100, thetas= np.linspace(0, 2*pi, 50, endpoint= False)):
    """ Generate likelihood for various values of 'p' and 'q'
        Input:
            p= amplitude
            q= no. of grover steps
        Output:
            dictionary of likelihood
            """

    qreg = QuantumRegister(1, name= 'qreg')
    creg = ClassicalRegister(1, name= 'creg')
    qc = QuantumCircuit(qreg, creg )

    qc.append(s_psi0(p),[0])
    qc.barrier()
    qc.append(Q(p, q), [0])

    qc.measure(qreg, creg)
    counts =  execute(qc, backend= aer, shots = shots).result().get_counts()
    le = likelihood(counts['1'],q,shots,thetas= thetas)

    return le

#############################################################################################
                       ### State Preparation Ansatz ###
#############################################################################################

class state_preparation_ansatz(QuantumCircuit):
    """
        A class to initiate the state preparation ansatz for the Variational QAE algorithm

        ARGS
        ----
            num_ancillas:[int]
                        no. of ancillas to be used for the ansatz prepration
            name:[str]
                    name of the ansatz circuit

        RETURNS
        -------
                [QuantumCircuit] implementing the state preparation ansatz

    """

    def __init__(self,
        num_ancillas: int,
        name: str= "Q",
        # params: Optional[Union[Iterable, str, None]]= "random",
        insert_barrier:bool= False)-> None:

        super().__init__(name= name)

        ## set inputs ~
        self._num_ancillas= num_ancillas
        self._name= name
        self._insert_barrier= insert_barrier
        # self._params= params
        self._num_params = self._num_ancillas * 4 + 2

        ## build parameters ~
        qreg = QuantumRegister(1)
        ancillas = AncillaRegister(self._num_ancillas)
        qc = QuantumCircuit(qreg, ancillas)
        self.add_register(*qc.qregs)

    @property
    def num_ancillas(self):
        """ No, of ancillas used in the ansatz """
        return self._num_ancillas

    @property
    def num_params(self):
        """ No. of parmaters passed into the ansatz """
        return self._num_params

    def load_params(self, params_to_load: Iterable):
        """
            ARGS
            ----
                params_to_load:[Iterable]
                                new parametes to be reassigned into the ansatz

            RETURNS
            -------
                 [QuantumCircuit] with reassigned paramters

        """

        ## get list of tunable paramters ~
        param_data = [ data[0] for data in self.data if data[0].name== 'ry' ]

        ## reset the paramters with new 'params_to_load' ~
        for index, instrc in enumerate(param_data):
            instrc.params = [ params_to_load[index]]

        return self

    def show_params(self):
        """ Print the current paramter values in the ansatz """

        param_data = [ data[0] for data in self.data if data[0].name== 'ry' ]
        for index, intrc in enumerate(param_data):
            print( 'param' +str(index)+': ' ,intrc.params)

    def initialize(self, params):
        """ Function to build the state preparation circuit

            ARGS
            ----
                params:[Iterable, str]
                        paramters to initialize the circuit.
                        if params = 'random' the circuit paramters are initialised randomly
            RETURNS
            -------
                 [QuantumCircuit] with initialised paramters

        """

        if isinstance(params, str) and params== "random":

            print(" 'random' ")
            self._params_state = np.random.uniform(low=0, high= 2*pi, size= 2)
            self._params_ancilla_1= np.random.uniform(low=0, high= 2*pi, size= self._num_ancillas )
            self._params_ancilla_2= np.random.uniform(low=0, high= 2*pi, size= self._num_ancillas )
            self._params_ancilla_init= np.random.uniform(low=0, high= 2*pi, size= self._num_ancillas )
            self._params_ancilla_end= np.random.uniform(low=0, high= 2*pi, size= self._num_ancillas )

        elif isinstance(params, Iterable):

            if len(params) != self._num_params: raise ValueError(" no. of elements in 'params' must be ", self._num_params )
            self._params_state= np.append(params[0],params[-1])
            self._params_ancilla_init= params[1: 1 + self._num_ancillas]
            self._params_ancilla_1= params[1 + self._num_ancillas: 1 + 2 * self._num_ancillas]
            self._params_ancilla_2= params[1+ 2 * self._num_ancillas: 1 + 3 * self._num_ancillas]
            self._params_ancilla_end = params[1 + 3 * self._num_ancillas: -1]

        params_state = self._params_state
        params_ancilla_1= self._params_ancilla_1
        params_ancilla_2 = self._params_ancilla_2
        params_ancilla_init = self._params_ancilla_init
        params_ancilla_end = self._params_ancilla_end

        ancillas = self.ancillas
        qreg = self.qubits[0]

        ## set_ansatz ~
        self.h(ancillas)
        self.ry(params_state[0], qreg)

        for index, ancilla in list(enumerate(self.ancillas))  : self.ry(params_ancilla_init[index], ancilla)
        if self._insert_barrier == True: self.barrier()

        self.cx(qreg, ancillas[0])

        for index, ancilla in list(enumerate(ancillas))  :
            self.ry(params_ancilla_1[index], ancilla)
            self.cx(ancillas[index], ancillas[(index+1)%(self._num_ancillas)])

        if self._insert_barrier == True: self.barrier()

        for index, ancilla in list(reversed(list(enumerate(ancillas))))  :
            self.ry(params_ancilla_2[index], ancilla)
            self.cx(ancillas[index], ancillas[(index-1)%(self._num_ancillas)])

        self.cx( ancillas[0], qreg)

        if self._insert_barrier == True: self.barrier()
        for index, ancilla in list(enumerate(ancillas))  : self.ry(params_ancilla_end[index], ancilla)

        self.ry(params_state[1], qreg)
        self.h(ancillas)

        return self


from torch import nn
import torchvision

class NeuralNetwork(nn.Module):
    """
    Generic fully-connected network class
    The first argument of the constructor should be the number of input features, and the last should be the number of outputs
    """
    # layers = int layer sizes, starting with the input layer
    def __init__(self, *layers):
        super(NeuralNetwork, self).__init__()
        self.flatten = nn.Flatten()

        stack = []
        for i in range(len(layers) - 1):
            stack.extend([nn.Linear(layers[i], layers[i + 1]), nn.ReLU()])

        self.linear_relu_stack = nn.Sequential(*stack[:-1])

    def forward(self, x):
        x = self.flatten(x)
        logits = self.linear_relu_stack(x)
        return logits

class TransferModel18(nn.Module):
    """
    ResNet18 transfer learning model
    By default we set the fully-connected classifier layer to a single 512x2 layer
    """
    def __init__(self, pretrained=True, freeze=True, device='cpu'):
        super(TransferModel18, self).__init__()

        if pretrained:
            self.model = torchvision.models.resnet18(weights='DEFAULT').to(device)
        else:
            self.model = torchvision.models.resnet18().to(device)

        if freeze:
            for param in self.model.parameters():
                param.requires_grad = False

        # Fully-connected layer
        self.model.fc = nn.Sequential(
            nn.Linear(in_features=512, out_features=2, bias=True, device=device),
        )

        for layer in self.model.fc:
            if hasattr(layer, 'weight'):
                nn.init.xavier_uniform_(layer.weight)

    def forward(self, x):
        return self.model(x).squeeze()

class TransferModel50(nn.Module):
    """
    ResNet50 transfer learning model
    """
    def __init__(self, pretrained=True, freeze=True, device='cpu'):
        super(TransferModel50, self).__init__()

        if pretrained:
            self.model = torchvision.models.resnet50(weights=torchvision.models.ResNet50_Weights.default).to(device)
        else:
            self.model = torchvision.models.resnet50().to(device)

        if freeze:
            for param in self.model.parameters():
                param.requires_grad = False

        # Fully-connected layer
        self.model.fc = nn.Sequential(
            nn.Linear(in_features=2048, out_features=2, bias=True, device=device),
        )

        for layer in self.model.fc:
            if hasattr(layer, 'weight'):
                nn.init.xavier_uniform_(layer.weight)

    def forward(self, x):
        return self.model(x).squeeze()


import pygame, os
from weapon.weapon import *
from ship.shared import *
from ship.gameobject import *
from assets.art.spritesheet import *

class Hero(Ship):
    level_xp_start = 100
    level_xp_next = 0
    level_interval = 2
    kills_total = 0
    enemy_missed_total = 0
    time_since_kill = 0.0
    kill_streak = 0
    name = "Hero"
    color = None
    #Should be attributes available from the sprite system
    sprite_width = 100
    sprite_height = 50
    is_on_level = False
    target_x, target_y = None, None

    def __init__(self, on_status_effect_callback = None, x = 0, y = 0):
        super().__init__(on_status_effect_callback, x, y)
        self.spritesheet = Spritesheet(
            #filename, frames, row, width, height, colorkey = None
            os.path.join('assets', 'art', 'hero_sprite_sheet.png'),
            4,
            self.animation_row,
            self.sprite_width, self.sprite_height,
            (255, 255, 255))
        self.health = self.health_max
        self.level = 1
        self.level_xp_next = self.level_xp_start

    def enemy_missed_increase(self):
        #TODO: this is level's job
        self.enemy_missed_total += 1

    def on_level_up(self):
        self.level_xp_next *= self.level_interval
        self.level += 1
        self.health_max *= self.health_multiplier
        health_increase = (self.health_max - self.health) / 2
        self.health += health_increase
        self.health_change.append(("on_level_up", health_increase, self.health, self.health_max))
        print ("Level {}! Next level at {} xp. Max health: {};".format(self.level, self.level_xp_next, self.health_max))

    def on_killed(self, target):
        self.time_since_kill = 0
        self.experience_total += target.experience_total
        self.kills_total += 1
        self.kill_streak += 1
        print (">Hero xp: {} + {}; killed {}; kills: {}; streak: {}; time since: {}".format(
            self.experience_total - target.experience_total,
            target.experience_total,
            target.name,
            self.kills_total,
            self.kill_streak,
            self.time_since_kill))

    def target_update(self, target_x, target_y):
        self.target_x, self.target_y = target_x, target_y

    # slope = 0.0
    # b = 0
    # y_1280x = 0
    # v = (0,0)
    def bullet_velocity_update(self, bullet):
        '''Update bullet velocity to pass through target'''
        if self.target_x and self.target_y:
            self.bullet_target_velocity_update(bullet, (self.target_x, self.target_y))
            #self.slope = (self.target_y-self.y)/(self.target_x-self.x)
            #self.b = self.y - self.slope * self.x
            #self.y_1280x = self.slope*1280+self.b
            #self.v = (self.target_x, self.y)
            #theta = abs(math.atan(uv/tv) * (180/math.pi))
            #slope_reduced = bc/ac

            #print ("UV: {} = BC: {}, TV: {} = AC: {}, UT: {} = AB: {}".format(uv, bc, tv, ac, math.sqrt((uv*uv + tv*tv)), ab))
            #print ("Theta: {}; Theta R: {}, Slope: {}; reduced Slope: {}".format(theta, theta_r, self.slope, slope_reduced))
            #print ("dy: {}; dx: {}".format(bullet.velocity_y, bullet.velocity_x))

    def update(self, delta):
        x_before = self.x
        y_before = self.y
        super().update(delta)
        if self.is_on_level:
            #Keep the ship on screen
            if (self.x < 0 + self.sprite_width/2 or
                self.x > 1280 - self.sprite_width/2):
                self.x = x_before
            if (self.y < 0 + self.sprite_height/2 or
                self.y > 720 - self.sprite_height/2):
                self.y = y_before

            self.rect.center = (self.x, self.y)
            self.time_since_kill += delta
            if self.experience_total >= self.level_xp_next:
                self.on_level_up()
            if self.time_since_kill > 3000:
                self.kill_streak = 0

    def on_death(self):
        print("YOU DIED")
        print("--Health Report--")
        for update in self.health_change:
            #name, amount, health
            print ("{:03d} {} {:03d} => {:03d}/{:03d} : {}".format(
                int(update[1] + update[2]) if update[0] == "on_hit" else int(update[2] - update[1]),
                "-" if update[0] == "on_hit" else "+",
                int(update[1]),
                int(update[2]),
                int(update[3]),
                update[0]))

        self.kill()

class AverageShip(Hero):
    name = "T3ST"
    color = (240, 234, 214)
    velocity_max = 25
    health_max = 80
    health_multiplier = 1.05
    damage_multiplier = 1.05
    animation_row = 1

class Tank(Hero):
    name = "Tank"
    color = (0, 255, 0)
    velocity_max = 20
    health_max = 150
    health_multiplier = 1.08
    damage_multiplier = 1.08
    animation_row = 4

class GlassCannon(Hero):
    name = "GlassCannon"
    color = (255, 0, 0)
    velocity_max = 30
    health_max = 80
    health_multiplier = 1.02
    damage_multiplier = 1.12
    animation_row = 7


# -*- coding: utf-8 -*-
import scrapy
import json
import copy

class BilibilivideoinfoSpider(scrapy.Spider):
    name = 'bilibiliVideoInfo'
    allowed_domains = ['bilibili.com']

    def __init__(self, data_loc):
        super(BilibilivideoinfoSpider,self).__init__()
        self.data_loc = data_loc
        self.url_format1 = 'http://api.bilibili.com/archive_stat/stat?aid=%s&type=jsonp'
        self.url_format2 = 'http://www.bilibili.com/video/av%s/'
        self.url_format3 = 'http://interface.bilibili.com/player?id=cid:18208583&aid=%s'

    def start_requests(self):
        with open(self.data_loc,'r') as data:
            for aid in data.read().splitlines():
                yield scrapy.Request(self.url_format1%(aid), meta={'aid': aid}, callback=self.parse1)

    def parse1(self, response):
        json_response = json.loads(response.body_as_unicode())
        datas= {'aid': response.meta['aid'],
                'playNum': json_response['data']['view'],
                'comment':json_response['data']['reply'],
                'danmu':json_response['data']['danmaku'],
                'like':json_response['data']['favorite'],
        }
        yield scrapy.Request(self.url_format2%(response.meta['aid']),
                              meta={'aid':response.meta['aid'],'datas':datas},
                              callback=self.parse2)

    def parse2(self, response):
        datas =response.meta['datas']
        datas['title'] = response.css('title::text').extract_first()
        datas['issueTime'] =  response.css('time::attr(datetime)').extract_first()
        yield scrapy.Request(self.url_format3%(response.meta['aid']),
                             meta={'aid':response.meta['aid'],'datas':datas},
                             callback=self.parse3)

    def parse3(self, response):
        datas = response.meta['datas']
        datas['duration'] = response.css('duration::text').extract_first()

        yield datas


#!/usr/bin/python
# -*- encoding: utf-8 -*-

from logger import setup_logger
from model import BiSeNet

import torch

import os
import os.path as osp
import numpy as np
from PIL import Image
import torchvision.transforms as transforms
import cv2

def evaluate(input_path,result_path,file_name,count,cp='model_final_diss.pth'):

    n_classes = 19
    net = BiSeNet(n_classes=n_classes)
    net.cuda()
    save_pth = osp.join('res/cp', cp)
    net.load_state_dict(torch.load(save_pth))
    net.eval()

    to_tensor = transforms.Compose([
        transforms.ToTensor(),
        transforms.Normalize((0.485, 0.456, 0.406), (0.229, 0.224, 0.225)),
    ])
    with torch.no_grad():
        img = Image.open(input_path + file_name)
        if len(np.array(img)[0][0]) > 3:
            return
        image = img.resize((1024, 1024), Image.BILINEAR)
        img = to_tensor(image)
        img = torch.unsqueeze(img, 0)
        img = img.cuda()
        out = net(img)[0]
        parsing = out.squeeze(0).cpu().numpy().argmax(0)
        # print(parsing)

        image = np.array(image)
        dys, dxs = np.where(parsing==0)
        for dy, dx in zip(dys,dxs):
            image[dy,dx] = [222,222,222]

        result = Image.fromarray(image)
        tmp = str(count).zfill(6)
        result.save(result_path+tmp+'.png')
    print(f"{file_name} done!!!")

if __name__ == "__main__":
    GPU_NUM = 1 # 원하는 GPU 번호 입력
    device = torch.device(f'cuda:{GPU_NUM}' if torch.cuda.is_available() else 'cpu')
    torch.cuda.set_device(device)
    print(torch.cuda.get_device_name(GPU_NUM))

    input_PATH = 'makeup/'
    result_PATH = 'result/'
    count = 0
    for index in os.listdir('makeup/'):
        evaluate(input_PATH,result_PATH,index,count,cp='79999_iter.pth')
        count += 1

"""
        eye_map = np.zeros_like(parsing)

        image = np.array(image)
        for i in range(image.shape[0]):
          for j in range(image.shape[1]):
                if parsing[i,j] == 5 or parsing[i,j] == 4:
                    eye_map[i][j] = 1
                else:
                    continue
"""


UI_REPORT_PATH = "result/test_result/ui/"
INTERFACE_REPORT_PATH = 'result/test_result/interface/'
APP_REPORT_PATH = 'result/test_result/app/'

REPORT_PATH = "result/screen_shot/ui/"

PROJECT_ADD_CONTEXT = {'title': '增加项目', 'btn': '增加'}
PROJECT_NOT_FOUND = "项目不存在"
SUBSYSTEM_NOT_FOUND = "子系统不存在"
VERSION_NOT_FOUND = "版本不存在"
MODULE_NOT_FOUND = "模块不存在"
ENV_NOT_FOUND = "环境不存在"
PARENT_MODULE_NOT_FOUND = "父级模块不存在"
TASK_NOT_FOUND = "任务不存在"
TASK_IS_EMPTY = "任务用例为空"
# PARAM_TYPE_DICT = {"1": "提取变量", "2": "自定义变量", "3": "数据库变量"}

INTERFACE_NAME_EXIST = "接口名称已存在"
INTERFACE_PATH_EXIST = "请求路径已存在"
NAME_REPETITION = "名称已存在"
EXTRACT_NAME_REPRTITION = "引用名称已存在"
CASE_NAME_EXIST = "用例名称已存在"

INTERFACE_INFO_200 = "接口：%s,请求成功"
INTERFACE_INFO_500 = "接口:%s,请求失败，
 %s"

ADD_SUCCESS_200 = "添加成功"
ADD_FAIL_500 = "添加失败"
EDIT_SUCCESS_200 = "修改成功"
EDIT_FAIL_500 = "修改失败"
DEL_SUCCESSS_200 = "删除成功"
DEL_FAIL_500 = "删除失败"
MOVE_SUCCESS_200 = "移动成功"
MOVE_FAIL_500 = "移动失败"

PERMISSION_SUCCESSS_200 = "授权成功"
PERMISSION_FAIL_500 = "授权失败"
NOT_PERMISSION = "无权限"

CASE_INFO_200 = "用例执行成功"

ACTIVE_SUCCESS_200 = "激活成功"
ACTIVE_FAIL_500 = "激活失败"

SERVER_ERROR = "服务器错误"
USE_MSG = "%s关联了%s"
USING_MSG = "%s正在使用"

DATABASE_CONNECT_SUCCESSS = "数据库连接成功"
DATABASE_CONNECT_FAIL = "数据库连接失败"

DATA_NOT_FOUND = "找不到数据"

RUN_TASK_SUCCESS_200 = "开始执行任务"
RUN_TASK_FAIL_500 = "任务执行失败"
TASKING = "删除失败，请检查任务是否在运行中或者关联了用例"

STOP_TASK_SUCCESS_200 = "任务停止成功"
STOP_TASK_FAIL_500 = "任务停止失败"

SQL_OPERATE_SUCCESS_200 = "%s成功"
SQL_OPERATE_FAIL_500 = "%s失败, %s"

DATA_NO_FOUND = "%s未找到"
USERINFO_NOT_FIND = "用户信息不存在"

EXECUTE_CASE_SUCCESS = "用例执行成功！"
EXECUTE_CASE_FAIL = "用例执行失败,尽快查看日志看看错误信息！"
EXECUTE_CASE_EXCEPT = "请检测请求地址是否正确,执行发送请求出现异常了！异常信息是:%s"

NOT_METHMOD = "无该请求方式"
NOT_TYPE = "无该类型"
NOT_LIST = "参数类型不是list"
NOT_PARAM = "缺失参数"

NOT_ID = "ID不存在"
NOT_WRITE_NAME = "请填写名称"
NAME_INPUT_LONG = "名称输入超长"
DESC_INPUT_LONG = "说明输入超长"

NOT_CHOOSE_SELF = "不能选择自身模块作为上级模块"

NOT_PARAM_NAME = "该参数未保存"
PARAM_NAME_GENERATOR_SUCCESS = "参数生成成功"
PARAM_NAME_GENERATOR_FAIL = "参数生成失败"

SUBSYSTEM_NOT_CASE = "该系统下用例为空"
MODULE_NOT_CASE = "该模块下用例为空"
SUBSYSTEM_NOT_ENV = "系统下模块未绑定环境"
MODULE_NOT_ENV = "模块未绑定环境"
CASE_NOT_ENV = "用例未找到"

IMPORT_PARAMS_NOT_URL = "缺失Swagger URL"
IMPORT_PARAMS_NOT_JSON = "缺失Swagger JSON数据"
IMPORT_SWAGGER_DATA_ERR = "导入失败,请确认URL或文件是否正确"

INPUT_LONG = "输入超长"