import fractions
from Crypto.Util.number import GCD
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP

def continued_fraction_expansion(e, n):
    cf_expansion = []
    while n:
        cf_expansion.append(e // n)
        e, n = n, e % n
    return cf_expansion

def convergents(cf_expansion):
    convergents_list = []
    numerator, denominator = 0, 1
    for x in cf_expansion:
        numerator, denominator = denominator, x * denominator + numerator
        convergents_list.append((numerator, denominator))
    return convergents_list

def wiener_attack(public_key):
    n, e = public_key

    cf_expansion = continued_fraction_expansion(e, n)
    convergent_list = convergents(cf_expansion)

    for k, d in convergent_list:
        if k == 0:
            continue

        # Calculate phi and ensure it's a positive integer
        phi = (e * d - 1) // k
        if phi <= 0 or (e * d - 1) % k != 0:
            continue

        # Calculate possible factors of n using phi
        x = pow(phi - n - 1, 2) - 4 * n
        if x < 0:
            continue

        root_x = int(x**0.5)
        if root_x * root_x != x:
            continue

        p, q = (phi - n - 1 + root_x) // 2, (phi - n - 1 - root_x) // 2
        if p * q == n and GCD(e, phi) == 1:
            return d

    return None

def rsa_differential_attack_wiener(public_key, ciphertexts):
    n, e = public_key

    # Attempt to recover the private key (d) using Wiener's attack
    d = wiener_attack(public_key)
    if d is None:
        # Unable to recover the private key using Wiener's attack
        return []

    # Decrypt the ciphertexts using the private key (d)
    possible_plaintexts = []
    for ct in ciphertexts:
        pt = pow(ct, d, n)
        possible_plaintexts.append(pt)

    return possible_plaintexts

# Generate RSA key pair with small d
key = RSA.generate(1024)
n, e = key.n, key.e
d = key.d

print("Public key (n, e):", (n, e))
print("Private key (d):", d)

# Encrypt messages using the public key
plaintexts = [b'Hello, world!', b'Secure communication']
cipher = PKCS1_OAEP.new(key.publickey())
ciphertexts = [cipher.encrypt(pt) for pt in plaintexts]
print("Ciphertexts:", ciphertexts)

# Perform the Wiener attack
possible_plaintexts = rsa_differential_attack_wiener((n, e), ciphertexts)
print("Possible plaintexts (as integers):", possible_plaintexts)

# Convert the integers back to bytes
possible_plaintexts_bytes = [pt.to_bytes((pt.bit_length() + 7) // 8, byteorder='big') for pt in possible_plaintexts]
print("Possible plaintexts (as bytes):", possible_plaintexts_bytes)


import networkx as nx
import time
import numpy as np
import heapq
import network_process as ns
import TARank as AUC
import matplotlib.pyplot as plt
import math

'''
选择候选节点集
'''
'''
创新：1.初始化节点排序是整个图的节点排序 而不是社区内的节点排序 这使得在社区内部也考虑了网络全局信息
    2.在进行候选节点选择时，由于初始化BGN是反向地加入节点，首先加入的是网络中最不重要的节点，所以在遍历一部分最不重要的节点后，
    剩余节点满足候选节点的数量要求后，直接将剩余节点加入候选节点集，不用再计算其加入网络的最大连通分量的大小，减小其时间复杂度的同时提高准确率。
'''

def sortNode(G):
    '''
    按度从大到小排序
    '''
    matG = []
    nodeG = nx.nodes(G)
    # print(nodeG)
    matG.append(nodeG)  # 加入节点列表
    degreeG = list(dict(nx.degree(G)).values())
    # print(degreeG)
    matG.append(degreeG)  # 加入度列表
    # print(matG) #1127, 1128, 1129, 1130, 1131, 1132, 1133, 0)), dict_values([38, 30, 22, 10, 21, 26, 8,
    matG = np.array(matG)
    result = matG.T[np.lexsort(-matG)].T  # 按最后一行的顺序逆序  # 按度从大到小排序
    # x.T 将x 转置   a.T[np.lexsort(a)].T按最后一行顺序排序
    # np.lexsort((b,a)) # Sort by a, then by b
    li = result[0]  # 返回与度从大到小的节点序号
    return li

def greedHeap(G, vrank, c_size):  # vrank节点排序序列  #
    '''

    :param G:
    :param vrank:
    :param c_size: 想要选取的候选节点数量  则进行Heap_BGN的节点有 len(G)-c_size
    :return:
    '''
    heap = []
    len_G = len(G)
    S = []  # 集合S存放每次选择的节点
    # !!!!!!!! 不是顺序递增 就用字典来存储
    # cost = [1]*len_G  # 加入节点之后的R值（鲁棒性值）
    cost = {node: 1 for node in G.nodes()}  # 节点的R值（鲁棒性值）
    # is_update = np.zeros(len_G)  #已更新为1

    is_update = {node: 0 for node in G.nodes()}  # 记录是否被更新

    # print('社区内节点：', G.nodes())

    # Cluster = [set()] * len_G  # 用以记录每一个集团的成员节点
    # Cluster = {node: set() for node in G.nodes()}
    Cluster = {i: set() for i in range(len_G)}

    # NodeCluster = [0]*len_G #记录每一个节点所属集团的ID
    NodeCluster = {node: 0 for node in G.nodes()}  # 记录每一个节点所属集团的ID

    newClusterId = 1
    maxcluster = 1  # 最大连通分量的大小
    sumcluster = 0
    '''
    for i in range(len_G):
        heapq.heappush(heap,(cost[i],i,vrank[i]))#建堆
    '''
    i = 0
    for node in G.nodes():
        heapq.heappush(heap, (cost[node], i, vrank[i]))  # 根据初始化排序 去构建堆
        i += 1
    # print '建堆完成'
    print(heap)
    while len(heap) > c_size:
        v = heapq.heappop(heap)  # 从堆中删除元素，返回值是堆中最小的元素
        nodev = v[2]  # 弹出被选择的节点
        # print('被弹出节点：',nodev)
        if is_update[nodev] == 1:
            NodeCluster, Cluster, newClusterId, maxcluster = chooseV(nodev, G, NodeCluster, Cluster, newClusterId,
                                                                     maxcluster)
            sumcluster = sumcluster + maxcluster
            S.append(nodev)
            is_update = {node: 0 for node in G.nodes()}  # 选完一个节点后更新状态为未更新
        else:  # 如果没有更新则更新
            cost[nodev] = updateCost(nodev, G, NodeCluster, cost, Cluster, maxcluster)  # 更新节点的cost
            is_update[nodev] = 1  # 标记为已更新
            heapq.heappush(heap, (cost[nodev], v[1], nodev))  # 放入堆
    rnum = (sumcluster - len_G) / len_G / len_G
    # print (rnum)
    # print(S)
    S = set(G.nodes) - set(S)  # 求剩下的相对重要的节点
    return S

def updateCost(nodev, G, NodeCluster, cost, Cluster, maxcluster):  # 更新节点的cost       计算最大连通分量的大小
    ci = set()  # 记录nodev可能连接的集团的ID集合
    for vj in nx.all_neighbors(G, nodev):
        if NodeCluster[vj] != 0:  # vj已属于某个集团
            ci.add(NodeCluster[vj])
    sumc = 1
    for name in ci:
        sumc = sumc + len(Cluster[name])
    if sumc < maxcluster:
        sumc = maxcluster
    cost[nodev] = sumc
    return cost[nodev]

def chooseV(nodev, G, NodeCluster, Cluster, newClusterId, maxcluster):  # 选择该节点:创建新集团 or 合并集团    维持派系
    ci = set()  # 记录vi可能连接的集团的ID集合
    for vj in nx.all_neighbors(G, nodev):
        if NodeCluster[vj] != 0:  # vj已属于某个集团
            ci.add(NodeCluster[vj])
    if len(ci) == 0:  # 即新加入的节点为孤立节点
        NodeCluster[nodev] = newClusterId  # 分配给新的集团
        Cluster[newClusterId] = set()  # 新集团
        Cluster[newClusterId].add(nodev)  # 将vi加入
        newClusterId = newClusterId + 1
    else:  # 加入的节点不是孤立节点
        minci = min(ci)  # 记录Ci中编号最小的集团ID，记为minci
        NodeCluster[nodev] = minci  # 节点vi所属集团的ID minci
        Cluster[minci].add(nodev)  # 将节点vi加入到编号为minci的集团中
        # 将Ci中所有集团的成员节点都合并，均放入minci中
        for name in ci:
            if name != minci:
                for nod in Cluster[name]:
                    NodeCluster[nod] = minci  # 修改集团索引
                    Cluster[minci].add(nod)
        if len(Cluster[minci]) > maxcluster:
            maxcluster = len(Cluster[minci])  # 最大连通分量的大小
    return NodeCluster, Cluster, newClusterId, maxcluster

'''  选择一部分节点 一部分不重要的节点'''
def imp_BGN(G,rank_dg,rank_ks,seed_size): # seed_size选择的种子节点数量
    eplision=0.1  # 控制参数
    len_G = len(G)
    S = []  # 集合S存放每次选择的节点
    G_R=G.copy()
    # !!!!!!!! 不是顺序递增 就用字典来存储
    cost = {node: 1 for node in G.nodes()}  # 节点的R值（鲁棒性值）thtea
    deg_ks={node:eplision*(rank_dg[node]+rank_ks[node]) for node in G.nodes()}  # 辅助判断  保证辅助判断小于1
    # is_affected={node:0 for node in G.nodes()}  # 初始化所有节点未被影响

    # is_update = {node: 0 for node in G.nodes()}  # 记录是否被更新

    # print('社区内节点：', G.nodes())

    # Cluster = [set()] * len_G  # 用以记录每一个集团的成员节点  # 错误用法,因为用*的话，赋予统一空间，修改时会修改所有!!!!  应该用列表生成器
    # Cluster={node:set() for node in G.nodes()}

    Cluster = {i: set() for i in range(len_G)}

    NodeCluster = {node: 0 for node in G.nodes()}  # 记录每一个节点所属集团的ID

    newClusterId = 1
    maxcluster = 1  # 最大连通分量的大小
    while len(G_R)>seed_size:
        for node in G_R.nodes():  # 对于即将要加入图的节点计算其鲁棒性值，选其鲁棒性值最小的  # ！！！！！修改不是所有节点都进行更新操作 受影响的节点才进行更新
            cost[node] = updateCost(node, G, NodeCluster, cost, Cluster, maxcluster)+deg_ks[node]  # 更新节点的cost
        # thtea=sorted(cost.items(),key=lambda x:x[1],reverse=True) #从大到小排列
        # node_min=thtea[0][0]
        node_min=min(cost.items(),key=lambda x:x[1])[0] # 取节点
        NodeCluster, Cluster, newClusterId, maxcluster = chooseV(node_min, G, NodeCluster, Cluster, newClusterId,maxcluster)  # 即添加节点
        # 添加节点需要计算哪些节点受到影响
        S.append(node_min)
        G_R.remove_node(node_min)
        cost.pop(node_min)
    S = list(set(G.nodes) - set(S))  # 剩余的节点就是相对重要的节点   大量节省了时间
    return S

def imp_BGN_BFS(G,auc,eplision,seed_size): # auc 分数进行辅助判断  seed_size 选择的种子节点数量  eplision 区分参数 对于不同的网络有不同的值
    # eplision=0.01  # 控制参数  根据网络变化
    # eplision=0.0001   # for email
    len_G = len(G)
    S = []  # 集合S存放每次选择的节点
    G_R=G.copy()
    # !!!!!!!! 不是顺序递增 就用字典来存储
    cost = {node: 1 for node in G.nodes()}  # 节点的R值（鲁棒性值）thtea

    Cluster = {i: set() for i in range(len_G)}
    NodeCluster = {node: 0 for node in G.nodes()}  # 记录每一个节点所属集团的ID

    newClusterId = 1
    maxcluster = 1  # 最大连通分量的大小
    # sumcluster = 0
    while len(G_R)>seed_size:
        for node in G_R.nodes():  # 对于即将要加入图的节点计算其鲁棒性值，选其鲁棒性值最小的  # ！！！！！修改不是所有节点都进行更新操作 受影响的节点才进行更新
            cost[node] = updateCost(node, G, NodeCluster, cost, Cluster, maxcluster)*(1+eplision*auc[node])  # 更新节点的cost
        # thtea=sorted(cost.items(),key=lambda x:x[1],reverse=True) #从大到小排列
        # node_min=thtea[0][0]
        node_min=min(cost.items(),key=lambda x:x[1])[0] # 取节点
        NodeCluster, Cluster, newClusterId, maxcluster = chooseV(node_min, G, NodeCluster, Cluster, newClusterId,maxcluster)  # 即添加节点
        # 添加节点需要计算哪些节点受到影响
        S.append(node_min)
        G_R.remove_node(node_min)
        cost.pop(node_min)
    S = list(set(G.nodes) - set(S))  # 剩余的节点就是相对重要的节点   大量节省了时间
    return S

def calcNode_E1(G,v): # 邻居节点的度的熵
    result = 0
    degree1 = 0
    for u in list(G.neighbors(v)):  # 求节点v的邻居节点的度之和
        degree1 += G.degree(u)

    for u in list(G.neighbors(v)):
        result += G.degree(u) / degree1 * math.log(G.degree(u) / degree1)
    return -1 * result

def calcNode_E2(G): # 用度计算
    all_degree = nx.number_of_edges(G) * 2  # 网络中所有节点度之和 边2的数量*2
    # node's information pi
    node_information={}
    for node in G.nodes():
        node_information[node]=0
        for u in nx.neighbors(G,node):
            node_information[node]+=-(G.degree(u)/all_degree)*math.log(G.degree(u)/all_degree)
    return node_information

def get_seeds_by_HeapBGN(g, com_nodes,init_rank,seed_candidate):
    '''
    根据传入的参数选择备选节点加入备选节点库  在每个社区中选择
    :param g: 整体的社交网络
    :param com_nodes: 当前社区
    inin_rank：初始化排序
    :return:
    注意：测试初始化排序是社区内部的还是整个图的 是整个图的还是只是社区内部的？？？
    '''

    seed = []  # 返回选取的高影响力种子节点
    initrank_c=[] # 社区内部的初始化排序
    # 根据节点获取图的子图 社区
    community_graph = nx.subgraph(g, com_nodes)
    # nx.draw(community_graph, with_labels=True)
    # plt.show()

    node_c=community_graph.nodes()
    # 找到社区内部对应的初始化排序
    for i in range(len(init_rank)):
        if init_rank[i] in node_c:
            initrank_c.append(init_rank[i])

    # size_g = len(community_graph)  # 计算社区大小
    # ！！！！计算需要多少节点传入候选节点=======公式==== 0.5*size_g  相对于每个社区大小选取
    # initial-BGN  在每个社区中进行 然后截取部分节点
    # !!!!! 因为最先选择的节点是最不重要的节点 节点需要反转  所以只对部分节点进行HeapBGN操作 剩下的直接传入候选节点集 不用再对剩下的重要节点排序
    # seed_len = 0.6 * size_g
    # initrank = list(sortNode(community_graph))  # 初始化排序   社区内部
    # initrank.reverse()  # 度从小到大的编号

    print('初始化排序：', initrank_c)
    seed = greedHeap(community_graph, initrank_c, seed_candidate)  # 在每个社区中
    return list(seed)

def get_seeds_by_impBGN(g, com_nodes,rank1,rank2,seed_candidate):  # 在社区内部执行改进的BGN
    '''

    :param g:
    :param com_nodes: 社区内的节点集
    :param rank1:
    :param rank2:
    :param seed_candidate: 候选种子节点
    :return:
    '''
    # 根据节点获取图的子图 社区
    community_graph = nx.subgraph(g, com_nodes)
    # size_g = len(community_graph)  # 计算社区大小
    # ！！！！计算需要多少节点传入候选节点=======公式==== 0.5*size_g  相对于每个社区大小选取
    # initial-BGN  在每个社区中进行 然后截取部分节点
    # !!!!! 因为最先选择的节点是最不重要的节点 节点需要反转  所以只对部分节点进行HeapBGN操作 剩下的直接传入候选节点集 不用再对剩下的重要节点排序
    # seed_candicate = 0.6 * size_g
    seed=imp_BGN(community_graph,rank1,rank2,seed_candidate)
    return seed

'''  选择一部分节点 一部分不重要的节点'''

def get_seeds_by_impBGNBFS(g, com_nodes,auc,eplision,seed_candidate): # auc 分数进行辅助判断  eplision 区分参数
    # 根据节点获取图的子图 社区
    community_graph = nx.subgraph(g, com_nodes)
    # size_g = len(community_graph)  # 计算社区大小
    # ！！！！计算需要多少节点传入候选节点=======公式==== 0.5*size_g  相对于每个社区大小选取
    # initial-BGN  在每个社区中进行 然后截取部分节点
    # !!!!! 因为最先选择的节点是最不重要的节点 节点需要反转  所以只对部分节点进行HeapBGN操作 剩下的直接传入候选节点集 不用再对剩下的重要节点排序
    # seed_candicate = 0.6 * size_g
    seed = imp_BGN_BFS(community_graph,auc,eplision,seed_candidate)
    return seed

if __name__ == '__main__':
    # 输入图
    # G = nx.karate_club_graph()
    eplision=0.1
    G=nx.read_edgelist('data/karate_edges.txt',nodetype=int)
    com_lists = ns.get_community(G)  # 获得社区列表
    print(com_lists)
    print(com_lists[0])
    start_time = time.process_time()
    # 传入整个图的初始化排序
    init_rank_G=list(sortNode(G))
    init_rank_G.reverse()
    com_seed = get_seeds_by_HeapBGN(G, com_lists[0],init_rank_G,3)
    end_time = time.process_time()
    print('-----------------------')
    print('HeapBGN候选节点degree:',com_seed)  # 选出的候选节点集
    print('运行时间：', end_time - start_time)

    print('------------------------')

    node_ks = nx.core_number(G)
    node_ks_min = min(node_ks.items(), key=lambda x: x[1])[1]
    node_ks_max = max(node_ks.items(), key=lambda x: x[1])[1]
    # node_ks=sorted(node_ks.items(),key=lambda x:x[1],reverse=True)

    print('--------求节点的熵1-邻居节点------------')
    node_information1 = {node: calcNode_E1(G, node) for node in G.nodes()}
    node_inf_min = min(node_information1.items(), key=lambda x: x[1])[1]
    node_inf_max = max(node_information1.items(), key=lambda x: x[1])[1]
    print('节点熵：', node_information1)
    # 归一化

    # 对k-shell 值归一化  不用排序
    print('节点k-shell:',node_ks)
    for node in node_ks:  # 遍历字典键
        node_ks[node] = float(node_ks[node] - node_ks_min) / (node_ks_max - node_ks_min)
    print('归一化节点k-shell:',node_ks)

    print('--------对节点熵1进行归一化------------')
    for node in node_information1:  # 遍历字典键
        node_information1[node] = float(node_information1[node] - node_inf_min) / (node_inf_max - node_inf_min)
    print(node_information1)

    print('初始化排序：')

    init_rank={node: eplision*(node_information1[node]+node_ks[node]) for node in G.nodes()}
    init_rank=sorted(init_rank.items(),key=lambda x:x[1])   # 从小到大排序
    print(init_rank)
    # print(init_rank[0])
    initrank=[]
    for node,score in init_rank: # 初始化排序 从小到大的节点列表
        initrank.append(node)
    print('初始化排序结果',initrank)

    seed_imp= get_seeds_by_impBGN(G,com_lists[0],node_information1,node_ks,3)
    seed_imp_heap=get_seeds_by_HeapBGN(G,com_lists[0],initrank,3)
    print('改进熵度BGN候选节点：',seed_imp)
    print('改进熵度Heap-BGN候选节点：',seed_imp_heap)

    auc_score = AUC.process(G)
    print('AUC分数：', auc_score)
    auc_min = min(auc_score.items(), key=lambda x: x[1])[1]
    auc_max = max(auc_score.items(), key=lambda x: x[1])[1]
    # 进行归一化
    print('---------------归一化AUC分数-----------')
    for node in auc_score:  # 遍历字典键
        auc_score[node] = float(auc_score[node] - auc_min) / (auc_max - auc_min)
    print(auc_score)

    seed_impBGNAUC=get_seeds_by_impBGNBFS(G,com_lists[0],auc_score,0.01,3)
    print('改进BGNAUC候选节点：',seed_impBGNAUC)


class Node:
    '''Created by krishna kant sharma B.tech 3rd year '''

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

class SinglyLinkedList:

    def __init__(self):
        self.head = None

    def printList(self):
        temp = self.head
        while temp:
            print(temp.data, '-->', end=" ")
            temp = temp.next

    def insertAtBeggning(self, data):
        new_node = Node(data)
        new_node.next = self.head
        self.head = new_node

    def insertInBetween(self, data, node_after):
        if node_after is None:
            print("Please provide valid node_after value")
            return
        new_node = Node(data)
        temp = self.head
        new_node.next = node_after.next
        node_after.next = new_node

    def insertAtEnd(self, data):
        new_node = Node(data)
        if self.head is None:
            self.head = new_node
            return
        temp = self.head
        while temp.next:
            temp = temp.next
        temp.next = new_node

    def deleteAtBegging(self):
        self.head = self.head.next

    def deleteAtEnd(self):
        if self.head is None:
            print('No element to delete')
            return
        temp = self.head
        while temp.next.next:
            temp = temp.next
        temp.next = None

    def deleteAnyNode(self, val):
        if self.head is None:
            print('No value to delete')
            return
        if self.head.data == val:
            self.head = self.head.next
        temp = self.head
        while temp:
            if temp.data == val:
                pre.next = temp.next
                return
            pre = temp
            temp = temp.next
        print("element not found")

    def deleteAtPosition(self, position):
        if position < 0 or position > self.listLength():
            print('Enter valid position')
            return
        if position == 0:
            self.head = self.head.next
            return
        temp = self.head
        count = 0
        pre = self.head
        while count <= position:
            if count == position:
                pre.next = temp.next
                return
            count = count + 1
            pre = temp
            temp = temp.next

    def listLength(self):
        c = 0
        temp = self.head
        while temp:
            temp = temp.next
            c = c + 1
        return c

ll = SinglyLinkedList()
ll.deleteAtEnd()  # No element to delete
ll.insertAtEnd(20)  # 20
ll.insertAtEnd(30)  # 30
ll.insertInBetween(40, ll.head.next)  # 20 30 40
ll.insertAtEnd(50)  # 20 30 40 50
ll.insertAtBeggning(10)  # 10 20 30 40 50
ll.deleteAtEnd()  # 10 20 30 40
ll.deleteAnyNode(30)  # 10 20 40
ll.deleteAtPosition(2)  # 10 20
ll.printList()  # will print
print(ll.listLength())  # 2

'''
                           output
-----------------------------------------------------------
No element to delete
10
20
2
'''


class Solution:
    def slowestKey(self, releaseTimes: List[int], keysPressed: str) -> str:

        duration = [releaseTimes[0]]
        mx = releaseTimes[0]
        for i in range(1, len(releaseTimes)):
            diff = releaseTimes[i]-releaseTimes[i-1]
            if diff > mx: mx = diff
            duration.append(diff)

        mx_char = float('-inf')
        for c in range(len(keysPressed)):
            if duration[c] == mx and ord(keysPressed[c]) > mx_char:
                mx_char = ord(keysPressed[c])

        return chr(mx_char)


from set3.ctr_mode import encrypt_ctr, decrypt_ctr
from random import randrange

key = bytes([randrange(255) for _ in range(16)])

def encrypt(input):
    if b';' in input or b'=' in input:
        raise Exception("invalid characters")
    prefix = b"comment1=cooking%20MCs;userdata="
    postfix = b";comment2=%20like%20a%20pound%20of%20bacon"
    return encrypt_ctr(prefix + input + postfix, key, 0)

def is_admin(ct):
    pt = decrypt_ctr(ct, key, 0)
    print(pt)
    return b"admin=true" in pt

if __name__ == "__main__":
    # Goal is same as before - craft an input
    # yields is_admin true
    # 1 + 5 + 1 + 4 = 11 bytes, i.e.
    # prefix is exactly 2 blocks
    ct = encrypt(b"A:admin<true")
    modified_ct = bytearray(ct)
    modified_ct[16*2+1] ^= 1 # flip the bit to add 1 and turn ':' into ;
    modified_ct[16*2+7] ^= 1 # flip the bit to add 1 ant turn '<' into =
    print(is_admin(bytes(modified_ct)))


# coding=utf-8
import os
import time
import urllib.request as urllib

class AppInfo:
    def __init__(self, app_name, app_id, download_count):
        self.app_name = app_name
        self.download_count = download_count
        self.app_link = "http://www.anzhi.com/dl_app.php?s={0:1s}&n=5".format(app_id)

class Anzhi:
    def __init__(self):
        self.urlList = []
        self.baseurl = 'http://www.anzhi.com/list_1_{0:1d}_hot.html'

    def geturl(self, pageIndex):
        # 从1开始的
        for page in range(1, pageIndex + 1):
            self.urlList.append(self.baseurl.format(page))

    def spider(self):
        for i in range(len(self.urlList)):
            response = urllib.urlopen(self.urlList[i])
            html = response.readlines()

            app_info_list = []
            download_count = ''
            app_name = ''
            app_id = ''
            for i in range(len(html)):
                line = str(html[i].decode('utf-8'))
                if 'app_name' in line:
                    startIndex = line.index(".html") + 7
                    endIndex = line.index("")
                    app_name = line[startIndex:endIndex]
                    # print(app_name)
                elif 'app_downnum l' in line and len(app_name) > 0:
                    startIndex = line.index("下载") + 3
                    endIndex = line.index("")
                    download_count = line[startIndex:endIndex]

                    # 过滤掉下载量低于1000w的
                    indexOfWan = download_count.find("万")
                    indexOfYi = download_count.find("亿")
                    if indexOfYi == -1 and indexOfWan == -1 or indexOfWan != -1 and len(
                            download_count[0:indexOfWan]) <= 3:
                        app_name = ''
                        app_id = ''
                        download_count = ''

                elif 'opendown' in line and len(download_count) > 0:
                    startIndex = line.index("opendown(") + 9
                    endIndex = line.rindex(")")
                    app_id = line[startIndex:endIndex]
                if len(app_name) > 0 and len(download_count) > 0 and len(app_id) > 0:
                    app_info_list.append(AppInfo(app_name, app_id, download_count))
                    app_name = ''
                    app_id = ''
                    download_count = ''

            print('total download file size=' + str(len(app_info_list)))
            for index in range(len(app_info_list)):
                appInfo = app_info_list[index]
                # 创建下载目录
                file_dir = os.getcwd() + '/download'
                if not os.path.exists(file_dir):
                    os.mkdir(file_dir)

                # 过滤已下载完成的
                file_path = file_dir + '/' + appInfo.app_name + '.apk'
                if os.path.exists(file_path):
                    print('skip ,file already exit')
                    continue

                print('DOWNLOAD START....')
                print(
                    'appInfo：{ ' + 'index=' + str(index)
                    + "--app_name=" + appInfo.app_name
                    + "--app_link=" + appInfo.app_link
                    + "--downloadCount=" + appInfo.download_count + " }")

                start = time.time()
                urllib.urlretrieve(appInfo.app_link, file_path)
                end = time.time()
                print('DOWNLOAD COMPLETED '
                      + 'app_name=' + appInfo.app_name
                      + ',cost time=' + str(int(end - start)))

                # 一条优秀的分割线
                print('--------------------------------------')

    def start(self):
        self.geturl(10)
        self.spider()

if __name__ == '__main__':
    # 安智市场
    anzhi = Anzhi()
    anzhi.start()


menor_vinte = 0
idade_grupo = 0
maior_idade_homem = 0
nome_velho = ''
for p in range(1, 4):
    print(f"------- PESSOA {p} -------")
    nome = str(input('Digite o nome: ')).strip()
    idade = int(input('Digite a idade: '))
    sexo = str(input('Digite o sexo [M/F]: ')).strip()
    if p == 1 and sexo in 'Mm':
        maior_idade_homem = idade
        nome_velho = nome
    if sexo in 'Mm' and idade > maior_idade_homem:
        maior_idade_homem = idade
        nome_velho = nome
    if sexo in 'Ff':
        if idade <= 20:
            menor_vinte += 1
    idade_grupo += idade
media_idade = idade_grupo / 4
print(f'A média de idade das pessoas do grupo é {media_idade}')
print(f'O número de mulheres com idade menor que 20 anos é {menor_vinte}')
print(f'O homem mais velho se chama: {nome_velho}')


import torch

class TextClassificationDataset:
    def __init__(self, data, tokenizer, config):
        self.data = data
        self.tokenizer = tokenizer
        self.config = config
        self.text_column = self.config.text_column
        self.target_column = self.config.target_column

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

    def __getitem__(self, item):
        text = str(self.data[item][self.text_column])
        target = self.data[item][self.target_column]
        target = int(target)
        inputs = self.tokenizer(
            text,
            max_length=self.config.max_seq_length,
            padding="max_length",
            truncation=True,
        )

        ids = inputs["input_ids"]
        mask = inputs["attention_mask"]

        if "token_type_ids" in inputs:
            token_type_ids = inputs["token_type_ids"]
        else:
            token_type_ids = None

        if token_type_ids is not None:
            return {
                "input_ids": torch.tensor(ids, dtype=torch.long),
                "attention_mask": torch.tensor(mask, dtype=torch.long),
                "token_type_ids": torch.tensor(token_type_ids, dtype=torch.long),
                "labels": torch.tensor(target, dtype=torch.long),
            }
        return {
            "input_ids": torch.tensor(ids, dtype=torch.long),
            "attention_mask": torch.tensor(mask, dtype=torch.long),
            "labels": torch.tensor(target, dtype=torch.long),
        }


"""
Nick/user tracking

Author:
    - linuxdaemon <linuxdaemon@snoonet.org>
"""

import asyncio
import datetime
import re
import string
from collections import defaultdict
from contextlib import suppress

import sqlalchemy.exc
from sqlalchemy import Table, Text, Column, DateTime, PrimaryKeyConstraint, Boolean, and_

from cloudbot import hook
from cloudbot.event import EventType
from cloudbot.util import database
from cloudbot.util.async_util import wrap_future, create_future
from cloudbot.util.backoff import Delayer

address_table = Table(
    'addrs',
    database.metadata,
    Column('nick', Text),
    Column('addr', Text),
    Column('created', DateTime),
    Column('seen', DateTime),
    Column('reg', Boolean, default=False),
    Column('nick_case', Text),
    PrimaryKeyConstraint('nick', 'addr')
)

hosts_table = Table(
    'hosts',
    database.metadata,
    Column('nick', Text),
    Column('host', Text),
    Column('created', DateTime),
    Column('seen', DateTime),
    Column('reg', Boolean, default=False),
    Column('nick_case', Text),
    PrimaryKeyConstraint('nick', 'host')
)

masks_table = Table(
    'masks',
    database.metadata,
    Column('nick', Text),
    Column('mask', Text),
    Column('created', DateTime),
    Column('seen', DateTime),
    Column('reg', Boolean, default=False),
    Column('nick_case', Text),
    PrimaryKeyConstraint('nick', 'mask')
)

RFC_CASEMAP = str.maketrans(dict(zip(
    string.ascii_uppercase + "[]\\",
    string.ascii_lowercase + "{}|"
)))

def update_user_data(db, table, column_name, now, nick, value):
    """
    :type db: sqlalchemy.orm.Session
    :type table: Table
    :type column_name: str
    :type now: datetime.datetime
    :type nick: str
    :type value: str
    """

    def _insert_or_update():
        try:
            db.execute(table.insert().values(**args))
        except sqlalchemy.exc.IntegrityError:
            db.rollback()
            db.execute(table.update().values(seen=now, nick_case=nick).where(clause))
        finally:
            db.commit()

    nick_cf = rfc_casefold(nick)
    clause = and_(table.c.nick == nick_cf, getattr(table.c, column_name) == value)

    args = {
        'nick': nick_cf,
        column_name: value,
        'created': now,
        'seen': now,
        'reg': False,
        'nick_case': nick
    }

    delayer = Delayer(2)
    while True:
        with delayer:
            try:
                _insert_or_update()
            except sqlalchemy.exc.TimeoutError:
                pass
            else:
                break

def _set_result(fut, result):
    if not fut.done():
        fut.set_result(result)

def get_regex_cache(conn):
    try:
        cache = conn.memory["sherlock"]["re_cache"]
    except LookupError:
        conn.memory.setdefault("sherlock", {})["re_cache"] = cache = {}

    return cache

def get_regex(conn, name):
    cache = get_regex_cache(conn)
    try:
        regex = cache[name.lower()]
    except LookupError:
        conf = conn.config["plugins"]["sherlock"]["regex"][name.lower()]
        cache[name.lower()] = regex = re.compile(conf)

    return regex

def rfc_casefold(text):
    return text.translate(RFC_CASEMAP)

def _handle_who_response(irc_paramlist):
    return irc_paramlist[5], irc_paramlist[3]

def _handle_userhost_response(irc_paramlist):
    response = irc_paramlist[1].lstrip(':')
    nick, _, ident_host = response.partition('=')
    ident_host = ident_host[1:]  # strip the +/-
    nick = nick.rstrip('*')  # strip the * which indicates oper status
    ident, _, host = ident_host.partition('@')
    return nick, host

def _handle_whowas(irc_paramlist):
    return irc_paramlist[1], irc_paramlist[3]

def _handle_whowas_host(irc_paramlist):
    nick = irc_paramlist[1]
    hostmask = irc_paramlist[-1].strip().rsplit(None, 1)[1]
    host = hostmask.split('@', 1)[1]
    return nick, host

response_map = {
    '352': ("user_mask", _handle_who_response),
    '302': ("user_host", _handle_userhost_response),
    '340': ("user_ip", _handle_userhost_response),  # USERIP responds with the same format as USERHOST
    '314': ("user_whowas_mask", _handle_whowas),
    '379': ("user_whowas_host", _handle_whowas_host),
}

@asyncio.coroutine
def await_response(fut):
    return (yield from asyncio.wait_for(fut, 60))

@asyncio.coroutine
def await_command_response(conn, name, cmd, nick):
    futs = conn.memory["sherlock"]["futures"][name]
    nick_cf = rfc_casefold(nick)
    try:
        fut = futs[nick_cf]
    except LookupError:
        futs[nick_cf] = fut = create_future(conn.loop)
        conn.cmd(cmd, nick)

    try:
        res = yield from await_response(fut)
    finally:
        with suppress(KeyError):
            del futs[nick_cf]

    return res

@asyncio.coroutine
def get_user_host(conn, nick):
    return (yield from await_command_response(conn, "user_host", "USERHOST", nick))

@asyncio.coroutine
def get_user_ip(conn, nick):
    return (yield from await_command_response(conn, "user_ip", "USERIP", nick))

@asyncio.coroutine
def get_user_mask(conn, nick):
    return (yield from await_command_response(conn, "user_mask", "WHO", nick))

@asyncio.coroutine
def get_user_whowas(conn, nick):
    nick_cf = rfc_casefold(nick)
    futs = conn.memory["sherlock"]["futures"]
    send_command = False
    try:
        mask_fut = futs["user_whowas_mask"][nick_cf]
    except LookupError:
        send_command = True
        futs["user_whowas_mask"][nick_cf] = mask_fut = create_future(conn.loop)

    try:
        host_fut = futs["user_whowas_host"][nick_cf]
    except LookupError:
        send_command = True
        futs["user_whowas_host"][nick_cf] = host_fut = create_future(conn.loop)

    if send_command:
        conn.cmd("WHOWAS", nick)

    try:
        return (yield from await_response(asyncio.gather(mask_fut, host_fut)))
    except asyncio.TimeoutError:
        return None, None

@hook.on_start
def clear_regex_cache(bot):
    for conn in bot.connections.values():
        get_regex_cache(conn).clear()

@hook.on_start
def init_futures(bot):
    for conn in bot.connections.values():
        conn.memory["sherlock"] = {
            "futures": defaultdict(dict),
        }

@hook.event(EventType.notice)
@asyncio.coroutine
def on_notice(db, nick, chan, conn, event):
    try:
        server_info = conn.memory["server_info"]
    except LookupError:
        return

    if chan.casefold() != nick.casefold():
        # This isn't a PM / Private notice, ignore it
        return

    if nick.casefold() != server_info["server_name"]:
        # This message isn't from the server, ignore it
        return

    yield from handle_snotice(db, event)

@hook.irc_raw(response_map.keys())
@asyncio.coroutine
def handle_response_numerics(conn, irc_command, irc_paramlist):
    try:
        name, handler = response_map[irc_command]
    except LookupError:
        return

    nick, value = handler(irc_paramlist)

    futs = conn.memory["sherlock"]["futures"][name]
    try:
        fut = futs.pop(rfc_casefold(nick))
    except LookupError:
        return

    _set_result(fut, value.strip())

@asyncio.coroutine
def handle_snotice(db, event):
    conn = event.conn
    content = event.content
    for name, handler in HANDLERS.items():
        regex = get_regex(conn, name)
        match = regex.match(content)
        if match:
            yield from handler(db, event, match)

            break

@asyncio.coroutine
def set_user_data(event, db, table, column_name, now, nick, value_func, conn=None):
    value = yield from value_func(event.conn if conn is None else conn, nick)
    yield from event.async_call(update_user_data, db, table, column_name, now, nick, value)

@asyncio.coroutine
def delay_call(coro, timeout):
    yield from asyncio.sleep(timeout)
    return (yield from coro)

@asyncio.coroutine
def on_nickchange(db, event, match):
    conn = event.conn
    old_nick = match.group('oldnick')
    new_nick = match.group('newnick')
    now = datetime.datetime.now()

    old_nick_cf = rfc_casefold(old_nick)
    new_nick_cf = rfc_casefold(new_nick)

    futures = conn.memory["sherlock"]["futures"]

    data_futs = futures["data"]
    nick_change_futs = futures["nick_changes"]

    futs = {
        'addr': create_future(conn.loop),
        'host': create_future(conn.loop),
        'mask': create_future(conn.loop),
    }

    data_futs[new_nick_cf] = futs

    try:
        old_futs = data_futs.pop(old_nick_cf)
    except LookupError:
        nick_change_futs[old_nick_cf] = fut = create_future(conn.loop)
        try:
            old_futs = yield from asyncio.wait_for(fut, 30)
        except asyncio.TimeoutError:
            old_futs = {}
        finally:
            with suppress(LookupError):
                del nick_change_futs[old_nick_cf]

    try:
        nick_fut = nick_change_futs.pop(new_nick_cf)
    except LookupError:
        pass
    else:
        _set_result(nick_fut, futs)

    @asyncio.coroutine
    def _handle_set(table, name, value_func):
        try:
            value = yield from value_func(event.conn, new_nick)
        except (asyncio.TimeoutError, asyncio.CancelledError):
            value = yield from asyncio.wait_for(futs[name], 300)

        del futs[name]

        with suppress(LookupError):
            _set_result(old_futs[name], value)

        yield from asyncio.gather(
            event.async_call(update_user_data, db, table, name, now, old_nick, value),
            event.async_call(update_user_data, db, table, name, now, new_nick, value)
        )

    @asyncio.coroutine
    def _do_mask():
        yield from _handle_set(masks_table, 'mask', get_user_mask)

    @asyncio.coroutine
    def _timeout_whowas():
        try:
            yield from asyncio.gather(
                _handle_set(hosts_table, 'host', get_user_host),
                _do_mask(),
            )
        except (asyncio.TimeoutError, asyncio.CancelledError):
            mask, host = yield from get_user_whowas(event.conn, new_nick)
            if mask and host:
                with suppress(KeyError):
                    _set_result(old_futs['host'], host)

                with suppress(KeyError):
                    _set_result(old_futs['mask'], mask)

                yield from asyncio.gather(
                    event.async_call(update_user_data, db, hosts_table, 'host', now, old_nick, host),
                    event.async_call(update_user_data, db, hosts_table, 'host', now, new_nick, host),

                    event.async_call(update_user_data, db, masks_table, 'mask', now, old_nick, mask),
                    event.async_call(update_user_data, db, masks_table, 'mask', now, new_nick, mask),
                )

    yield from asyncio.gather(
        _handle_set(address_table, 'addr', get_user_ip),
        _timeout_whowas(),
    )

    with suppress(KeyError):
        del data_futs[new_nick_cf]

@asyncio.coroutine
def on_user_connect(db, event, match):
    nick = match.group('nick')
    ident = match.group('ident')
    host = match.group('host')
    addr = match.group('addr')

    now = datetime.datetime.now()

    nick_cf = rfc_casefold(nick)
    conn = event.conn

    mask_fut = create_future(conn.loop)

    futs = {
        'mask': mask_fut,
    }

    data_futs = conn.memory["sherlock"]["futures"]["data"]

    data_futs[nick_cf] = futs

    @asyncio.coroutine
    def _handle_set(table, name, value_func):
        try:
            value = yield from value_func(event.conn, nick)
        except (asyncio.TimeoutError, asyncio.CancelledError):
            value = yield from futs[name]

        del futs[name]

        yield from event.async_call(update_user_data, db, table, name, now, nick, value)

    @asyncio.coroutine
    def _do_mask():
        yield from _handle_set(masks_table, 'mask', get_user_mask)

    yield from asyncio.gather(
        event.async_call(update_user_data, db, hosts_table, 'host', now, nick, host),
        event.async_call(update_user_data, db, address_table, 'addr', now, nick, addr),
        _do_mask(),
    )

    with suppress(LookupError):
        del data_futs[nick_cf]

@asyncio.coroutine
def on_user_quit(db, event, match):
    nick = match.group('nick')
    ident = match.group('ident')
    host = match.group('host')
    addr = match.group('addr')

    now = datetime.datetime.now()

    nick_cf = rfc_casefold(nick)
    conn = event.conn

    futures = conn.memory["sherlock"]["futures"]

    data_futs = futures["data"]
    nick_change_futs = futures["nick_changes"]

    try:
        old_futs = data_futs.pop(nick_cf)
    except LookupError:
        nick_change_futs[nick_cf] = fut = create_future(conn.loop)
        try:
            old_futs = yield from asyncio.wait_for(fut, 30)
        except asyncio.TimeoutError:
            old_futs = {}
        finally:
            with suppress(LookupError):
                del nick_change_futs[nick_cf]

    with suppress(KeyError):
        _set_result(old_futs['host'], host)

    with suppress(KeyError):
        _set_result(old_futs['addr'], addr)

    @asyncio.coroutine
    def _do_whowas():
        mask, _ = yield from get_user_whowas(event.conn, nick)
        if mask:
            with suppress(KeyError):
                _set_result(old_futs['mask'], mask)

            yield from event.async_call(update_user_data, db, masks_table, 'mask', now, nick, mask)

    yield from asyncio.gather(
        event.async_call(update_user_data, db, hosts_table, 'host', now, nick, host),
        event.async_call(update_user_data, db, address_table, 'addr', now, nick, addr),
        _do_whowas(),
    )

HANDLERS = {
    'nick': on_nickchange,
    'connect': on_user_connect,
    'quit': on_user_quit,
}

@asyncio.coroutine
def ignore_timeout(coro):
    try:
        return (yield from coro)
    except (asyncio.TimeoutError, asyncio.CancelledError):
        pass

@hook.irc_raw('352')
@asyncio.coroutine
def on_who(conn, irc_paramlist):
    try:
        lines, fut = conn.memory["sherlock"]["futures"]["who_0"][0]
    except LookupError:
        return

    if not fut.done():
        lines.append(irc_paramlist[1:])

@hook.irc_raw('315')
@asyncio.coroutine
def on_who_end(conn, irc_paramlist):
    name = irc_paramlist[1]
    if name != "0":
        return

    try:
        lines, fut = conn.memory["sherlock"]["futures"]["who_0"][0]
    except LookupError:
        return

    _set_result(fut, lines)

@hook.on_start
@asyncio.coroutine
def get_initial_data(bot, loop, db, event):
    wrap_future(asyncio.gather(
        *[get_initial_connection_data(conn, loop, db, event) for conn in bot.connections.values() if conn.connected]
    ))

@hook.irc_raw('376')
@hook.command("getdata", permissions=["botcontrol"], autohelp=False)
@asyncio.coroutine
def get_initial_connection_data(conn, loop, db, event):
    """
    - Update all user data

    :type conn: cloudbot.client.Client
    :type loop: asyncio.AbstractEventLoop
    :type db: sqlalchemy.orm.Session
    :type event: cloudbot.event.Event
    """
    if conn.nick.endswith('-dev') and not hasattr(event, 'triggered_command'):
        # Ignore initial data update on development instances
        return

    fut = create_future(loop)
    try:
        lines, fut = conn.memory["sherlock"]["futures"]["who_0"][0]
    except LookupError:
        pass
    else:
        if not fut.done():
            return "getdata command already running"

    conn.memory["sherlock"]["futures"]["who_0"][0] = ([], fut)

    yield from asyncio.sleep(10)

    now = datetime.datetime.now()
    conn.send("WHO 0")
    try:
        lines = yield from asyncio.wait_for(fut, 30 * 60)
    except asyncio.TimeoutError:
        return "Timeout reached"
    finally:
        with suppress(LookupError):
            del conn.memory["sherlock"]["futures"]["who_0"][0]

    users = []
    for line in lines:
        chan, ident, host, server, nick, status, realname = line
        num_hops, _, realname = realname.partition(' ')
        users.append((nick, host))

    futs = [
        wrap_future(event.async_call(update_user_data, db, masks_table, 'mask', now, nick, mask))
        for nick, mask in users
    ]

    for nick, mask in users:
        yield from asyncio.gather(
            ignore_timeout(set_user_data(event, db, hosts_table, 'host', now, nick, get_user_host, conn)),
            ignore_timeout(set_user_data(event, db, address_table, 'addr', now, nick, get_user_ip, conn))
        )

    yield from asyncio.gather(*futs)

    return "Done."


import numpy as np

class PolynomialFeatures:

    def __init__(self):
        pass

    # Source: https://stackoverflow.com/questions/58867481/polynomial-expansion-from-scratch-with-numpy-python
    def transform(self, lst, degree):
        if degree==1:
            if 1 not in lst:
                result = lst.insert(0,1)
            result = lst
            return result
        elif degree > 1:
            new_result=[]
            result = self.transform(lst, degree-1)
            new_result.extend(result)
            for item in lst:
                for p_item in result:
                    tmp = item*p_item
                    if (tmp not in result) and (tmp not in new_result):
                        new_result.append(tmp)
            return new_result
        return 0


from django.contrib import admin
from django.urls import path
from .views import (
    home,
    content_view ,
    login_view,
    logout_view,
    register_view
    )

from django.conf import settings

urlpatterns = [
    path("", home , name='home' ),
    path("content/<int:id>/", content_view , name='content' ),
    path('login/', login_view, name='login'),
    path('logout/', logout_view, name='logout'),
    path('register/', register_view, name='register'),

]

if settings.DEBUG:
    from django.conf.urls.static import static
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)


"""
CS 1 22fa

Final Exam Part C.2: OH Client Program (oh_client.py)

Tests for Part C.2 Grading.
- Test coverage for exercises C.2.1-C.2.4

NOTE: this client program relies on the oh_manager.py classes
working.

Students can ask on Discord if they have questions about test
results, but also double-check against spec examples and refer
to comments in respective test functions.
"""

from student_classes import Student, TA
from oh_manager import Entry, QueueManager
from oh_client import *
import oh_client

# It's generally poor practice to use global variables like this,
# but this is ok for testing to avoid re-implementing a local
# mock_input function. Some test functions will reset this
# global to test different input value cases shown in the spec/
# edge cases.
input_values = []

# Helper functions for tests
def mock_input(s):
    """
    Overrides the built-in input function to keep track of
    input values for functions that take user input.
    """
    print(s, end='')
    next_input = input_values[0]
    del input_values[0]
    return next_input

# mock the input
oh_client.input = mock_input

def test_c21_add_ta():
    """
    C.2.1. add_ta function in oh_client.py, which is used in prompt_add_ta,
    factoring out the add_ta functionality from user input for testing
    """
    # There shouldn't be any output after this test function
    output = []
    # Override output for testing print statements
    oh_client.print = lambda s='': output.append(s)

    manager = QueueManager()
    # From spec examples
    unknown_ta = manager.get_ta('2177843')
    assert unknown_ta is None
    # >>> prompt_add_ta(manager) # examples
    # Enter the TA's name: Foo Bar
    ta_name = 'Foo Bar'
    # Enter the TA's UID: 2177843
    ta_uid = '2177843'
    # Enter the TA's Grade/Year: Sophomore
    ta_year = 'Sophomore'
    # Enter the TA's email: foobar@caltech.edu
    ta_email = 'foobar@caltech.edu'
    # Enter the start time for your OH in HH:MM format (hours 0-23): 18:00
    ta_oh_start = '18:00'
    # Enter the end time for your OH in HH:MM format (hours 0-23): 22:00
    ta_oh_end = '22:00'
    add_ta(manager, ta_uid, ta_name, ta_year, ta_email, ta_oh_start, ta_oh_end)
    assert len(manager.tas) == 1
    ta1 = manager.get_ta('2177843')
    assert isinstance(ta1, TA)
    # same examples as C.1 tests
    assert str(ta1) == 'Name: Foo Bar\nUID: 2177843\nEmail: foobar@caltech.edu\nYear: Sophomore'
    add_ta(manager, '1234567', 'Maddie Ramos', 'Sophomore', 'maddie@caltech.edu', '11:00', '13:00')
    assert len(manager.tas) == 2
    ta2 = manager.get_ta('1234567')
    assert str(ta2) == 'Name: Maddie Ramos\nUID: 1234567\nEmail: maddie@caltech.edu\nYear: Sophomore'

    add_ta(manager, '0101', 'Claude Shannon', 'Senior', 'cs@caltech.edu', '01:01', '10:10')
    assert len(manager.tas) == 3
    ta3 = manager.get_ta('0101')
    assert str(ta3) == 'Name: Claude Shannon\nUID: 0101\nEmail: cs@caltech.edu\nYear: Senior'
    assert output == []

def test_c2_answer_next_question():
    """
    An Entry __str__ representation should simply be its associated Student's
    str followed by '\n' and the question information as specified in the spec.
    """
    output = []
    # Override output for testing print statements
    oh_client.print = lambda s='': output.append(str(s))
    global input_values

    manager = QueueManager()
    ta = TA('2177843', 'Foo Bar', 'Sophomore', 'foobar@caltech.edu', '18:00', '22:00')
    student = Student('2187112', 'Lorem Hovik', 'Freshman', 'lhovik@caltech.edu')
    q1 = Entry('What is a list?', student, 'MP1', '18:20')
    q2 = Entry('Is it true there are peacocks on campus?', student, 'General', '18:25')
    manager.enter_ta(ta)
    manager.add_entry(q1)
    manager.add_entry(q2)
    unknown_uid = '2345328'
    input_values = [unknown_uid]
    answer_next_question(manager)  # Ex. Giving UID for TA not in QueueManager
    # From spec examples:
    # Enter the answering TA's UID: 2345328
    # There should be exactly one print statement
    assert len(output) == 1
    assert output[0] == 'TA not found.'
    output = []

    # Foo Bar TA's uid
    ta_uid = '2177843'
    # Reset input values for next example
    input_values = [ta_uid, 'n']
    answer_next_question(manager)  # Ex. Question not resolved (re-enters queue)
    # From spec examples:
    # Enter the answering TA's UID: 2177843
    # Entry's string representation is output after giving known uid
    # assert ''.join(output) == 'Name: Lorem Hovik\nUID: 2187112\nEmail: lhovik@caltech.edu\nYear: Freshman\n' + \
    #                           'Question for MP1: What is a list?'
    assert ''.join(output) == 'Name: Lorem Hovik\nUID: 2187112\nEmail: lhovik@caltech.edu\nYear: Freshman\n' + \
                              'Question for MP1: What is a list?'
    # Enter "y" if the question has been resolved. n
    # In this example, the TA uid was known, but they did not resolve the question,
    # so the manager is unchanged (still 2 entries in the unresolved queue)
    # Remember to put the question _back_ at the end of the queue!
    assert len(manager.unresolved_entries) == 2
    assert len(manager.resolved_entries) == 0

    output = []
    # Reset input values for next example
    input_values = [ta_uid, 'y']
    answer_next_question(manager)  # Ex. Question resolved (removed from queue)
    assert ''.join(output) == 'Name: Lorem Hovik\nUID: 2187112\nEmail: lhovik@caltech.edu\nYear: Freshman\n' + \
                              'Question for General: Is it true there are peacocks on campus?'
    # Enter "y" if the question has been resolved. y
    # Double-check state of unresolved entries vs. resolved entries
    # In this example, the TA uid was known, and they confirmed to resolve the next entry
    # Moved q1 from unresolved to resolved
    assert len(manager.unresolved_entries) == 1
    assert len(manager.resolved_entries) == 1

    output = []
    # Reset input values for next example
    input_values = [ta_uid, 'y']
    answer_next_question(manager)  # Ex. Question resolved (removed from queue)
    assert ''.join(output).rstrip() == 'Name: Lorem Hovik\nUID: 2187112\nEmail: lhovik@caltech.edu\nYear: Freshman\n' + \
                              'Question for MP1: What is a list?'
    # Enter "y" if the question has been resolved. y
    # Double-check state of unresolved entries vs. resolved entries
    # Both questions were resolved at this point
    assert len(manager.unresolved_entries) == 0
    assert len(manager.resolved_entries) == 2

    output = []
    # Reset input values for empty-queue example
    input_values = [ta_uid]
    answer_next_question(manager)  # Ex. Queue is now empty
    # Enter the answering TA's UID: 2177843
    # No currently unresolved questions found.
    assert ''.join(output) == 'No currently unresolved questions found.'
    # Double-check that unresolved_entries is actually empty
    assert len(manager.unresolved_entries) == 0
    assert len(manager.resolved_entries) == 2

def test_c23_log_resolved_entries():
    """
    """
    # There shouldn't be any output after this test function
    output = []
    # Override output for testing print statements
    oh_client.print = lambda s='': output.append(str(s))
    manager = QueueManager()

    student1 = Student('2187112', 'Lorem Hovik', 'Freshman', 'lhovik@caltech.edu')
    student2 = Student('012345', 'Oppa', 'Sophomore', 'oppa@caltech.edu')
    ta1 = TA('2177843', 'Foo Bar', 'Sophomore', 'foobar@caltech.edu', '18:00', '22:00')
    ta3 = TA('0101', 'Claude Shannon', 'Senior', 'cs@caltech.edu', '01:01', '10:10')
    # Add resolved entries
    # (from spec examples)
    q1 = Entry('What is a list?', student1, 'MP1', '01:20')
    q2 = Entry('Is it true there are peacocks on campus?', student2, 'General', '18:25')
    q3 = Entry('How do I write a good docstring?', student1, 'Final', '18:26')
    manager.add_resolved_entry(q1, ta3) # Timestamp: 01:20
    manager.add_resolved_entry(q2, ta1) # Timestamp: 18:25
    manager.add_resolved_entry(q3, ta3) # Timestamp: 18:26
    # Log resolved (i.e., q1, q2, and q3)
    # They should be logging to the given filename, not hard-coding resolved.csv
    log_resolved_questions(manager, 'resolved_test.csv')

    row1 = ['MP1', 'What is a list?', '6', 'Claude Shannon', '(01:01-10:10)']
    row2 = ['General', 'Is it true there are peacocks on campus?', '12', 'Foo Bar', '(18:00-22:00)']
    row3 = ['Final', 'How do I write a good docstring?', '13', 'Claude Shannon', '(01:01-10:10)']
    expected_rows = [row1, row2, row3]
    with open('resolved_test.csv', 'r') as f:
        # Leniency if there's an extra \n at the end
        reader = csv.reader(f)
        # just check that response_time is an int, since its computed based on real-time
        # Column fieldnames should be first row in CSV reader
        fieldnames = next(reader)
        # From oh_client.py RESOLVED_QUESTION_LOG_COLUMNS
        assert fieldnames == ['assignment', 'question', 'response_time', 'response_ta', 'ta_timeframe']
        for i in range(len(expected_rows)):  # 3 rows expected after column header
            expected_row = expected_rows[i]
            actual_row = next(reader)
            for col_index in range(len(expected_row)):
                # Leniency check on col 2 (resolved_time, which depends on local time)
                if col_index == 2:
                    try:
                        response_time = int(actual_row[col_index])
                    except ValueError as err:
                        assert False == f'Expected integer value for response_time, but found: {actual_row[col_index]}'
                else:
                    # Otherwise, check for equality
                    assert expected_row[col_index] == actual_row[col_index]
        try:
            # Leniency if there's an extra \n at the end
            line = next(reader)
            assert not line or False == 'Extra rows found in CSV file'
        except StopIteration as err:
            assert True # No more rows found

#        assert f.read().rstrip() == '''assignment,question,response_time,response_ta,ta_timeframe
#MP1,What is a list?,6,Claude Shannon,(18:00-22:00)
#MP1,What is a dictionary?,2,Foo Bar,(18:00-22:00)
#MP1,How do I write a good docstring?,4,Claude Shannon,(18:00-22:00)'''

    # There shouldn't be any other output printed from C.2.3
    assert output == []

def test_c24_log_unresolved_questions():
    """
    Tests the QueueManager's __len__ method, which is simply the length
    of its unresolved_entires list.
    """
    # There shouldn't be any output after this test function
    output = []
    # Override output for testing print statements
    oh_client.print = lambda s='': output.append(str(s))
    manager = QueueManager()

    student1 = Student('2187112', 'Lorem Hovik', 'Freshman', 'lhovik@caltech.edu')
    student2 = Student('012345', 'Oppa', 'Sophomore', 'oppa@caltech.edu')
    # Add resolved entries
    # (from spec examples)
    q1 = Entry('What is a list?', student1, 'MP1', '01:20')
    q2 = Entry('Is it true there are peacocks on campus?', student2, 'General', '18:25')
    q3 = Entry('How do I write a good docstring?', student1, 'Final', '18:26')
    manager.add_entry(q1)
    manager.add_entry(q2)
    manager.add_entry(q3)
    # Log unresolved (i.e., q1, q2, and q3)
    # They should be logging to the given filename, not hard-coding unresolved.csv
    log_unresolved_questions(manager, 'unresolved_test.csv')

    row1 = ['2187112', 'Lorem Hovik', 'lhovik@caltech.edu', 'MP1', 'What is a list?']
    row2 = ['012345', 'Oppa', 'oppa@caltech.edu', 'General', 'Is it true there are peacocks on campus?']
    row3 = ['2187112', 'Lorem Hovik', 'lhovik@caltech.edu', 'Final', 'How do I write a good docstring?']
    expected_rows = [row1, row2, row3]
    with open('unresolved_test.csv', 'r') as f:
        # Leniency if there's an extra \n at the end
        reader = csv.reader(f)
        # just check that response_time is an int, since its computed based on real-time
        # Column fieldnames should be first row in CSV reader
        fieldnames = next(reader)
        # From oh_client.py UNRESOLVED_QUESTION_LOG_COLUMNS
        assert fieldnames == ['student_uid', 'student_name', 'student_email',
                              'assignment', 'question']
        for i in range(len(expected_rows)):  # 3 rows expected after column header
            expected_row = expected_rows[i]
            actual_row = next(reader)
            for col_index in range(len(expected_row)):
                # check for equality
                assert expected_row[col_index] == actual_row[col_index]
        # Finally, double-check that there weren't any unspecified rows added
        try:
            line = next(reader)
            # Leniency if there's an extra \n at the end
            assert not line or False == 'Extra rows found in CSV file'
        except StopIteration as err:
            assert True # No more rows found

    # There shouldn't be any other output printed from C.2.4
    assert output == []

def test_c23_c24_log_empty_cases():
    """
    Tests for edge-cases overlooked by students (e.g. loop bound errors)
    """
    # There shouldn't be any output after this test function
    output = []
    # Override output for testing print statements
    oh_client.print = lambda s='': output.append(str(s))
    manager = QueueManager()
    ta = TA('2177843', 'Foo Bar', 'Sophomore', 'foobar@caltech.edu', '18:00', '22:00')
    manager.enter_ta(ta)
    try:
        log_resolved_questions(manager, 'resolved_empty.csv')
        # It doesn't matter how students handle this case, as long as an error isn't thrown
        # (they can ignore the file-writing, write an empty file, or write just the single
        # column header)
    except Exception as err:
        assert False == 'Empty resolved_entries.csv should not throw an error'
    try:
        log_unresolved_questions(manager, 'unresolved_empty.csv')
    except Exception as err:
        assert False == 'Empty unresolved_entries.csv should not throw an error'

def test_additional_requirements(mocker):
    # There should not be any explicit calls to dunder
    # methods like __str__, __len__, __init__
    # the only occurrences should come from the method definitions.
    counts = {'TODO' : 0, ' pass': 0, 'import ': 0,
              '__str__': 0, '__init__': 0, '__len__': 0}
    with open('oh_manager.py') as f:
        for line in f:
            for key in counts:
                if key == ' pass':
                    if ' pass ' in line or line.rstrip()[-4:] == 'pass':
                        counts[' pass'] += 1
                elif key in line:
                    counts[key] += 1
    assert counts['TODO'] == 0
    assert counts[' pass'] == 0
    assert counts['import '] == 2
    # Both classes have __init__
    assert counts['__init__'] == 2
    # Only Entry has __str__
    assert counts['__str__'] == 1
    # Only QueueManager has __len__
    assert counts['__len__'] == 1


#1. Create a list with 5 items (names of people) and write a python program to output the 2nd
#item.

names = ["rashid" , "trevor", "musa", "naser", "gum"]

#2. Write a python program to change the value of the first item to a new value

names[0] = "kisejjere"

#3. Write a python program to add a sixth item to the list

names.append("john")

#4. Write a python program to add “Bathel” as the 3rd item in your list

names.insert(2, "Bathel")
print(names)

#5. Write a python program to remove the 4th item from the list

names.pop(4)

print(names)

#6. Use negative indexing to print the last item in your list

print(names[-1])

#7. Create a new list with 7 items and use a range of indexes to print the 3rd, 4th and 5th items
new_list = [21,23,3,4,5,3,2]

print("3rd", new_list[2])
print("4th", new_list[3])
print("5th", new_list[4])

#8. Write a list of countries and make a copy of it
countries = ["uganda", "kenya", "sudan", "tanzania"]

counries_copy = list(countries)

print(countries is counries_copy)

#9. Write a python program to loop through the list of countries

for country in countries:
    print(country)

#10. Write a list of animal names and sort them in both descending and ascending order
animals = ["cat", "dog", "hen", "cow", "anttelope"]
animals.sort()
print("ascending - ", animals)

animals.sort(reverse=True)
print("descending", animals)

#11. Using the list above, write a python program to output only animal names with the letter
#‘a’ in them

for animal in animals:
    index = animal.find("a")
    if(index != -1):
        print(animal)

#12. Write two lists, one containing your first names and the other your second names. Join
#the two lists

fname = ["kisejjere"]
sname = ["rashid"]

name = fname + sname
print(name)

####################################        Exercise2 (Tuples)

"""
1. Consider the tuple below;
x = (“samsung”, “iphone”, “tecno”, “redmi”)
Write a python program to output your favorite phone brand.
"""

x = ("samsung", "iphone", "tecno", "redmi")
print(x[0])

#2. Use negative indexing to print the 2nd last item in your tuple.

print(x[-2])

#3. Using the phones list above, write a python program to update “iphone” to “itel”
x = list(x)
x[1] = "itel"
print(x)

#4. Write a python program to add “Huawei” to your tuple.
x = tuple(x)

x = tuple(list(x) + ["Huawei"])
print(x)

#5. Write a python program to loop through the tuple above.
for phone in x:
    print(phone)

#6. Write a python program to remove/delete the first item in your tuple.
x = x[1:]

print(x)

#Using the tuple() constructor, create a tuple of the cities in Uganda.
cities = ("kampala", "masaka", "jinja","mukono")

#8. Write a python program to unpack your tuple.
for city in cities:
    print(city)

#9. Use a range of indexes to print the 2nd, 3rd and 4th cities in your tuple above.
for i in range(1, len(cities)):
    print(cities[i])

"""
10. Write two tuples, one containing your first names and the other your second names. Join
the two tuples
"""

fname = ("kisejjere")
sname = ("rashid")

name = fname + sname
print(name)

#11. Create a tuple of colors and multiply it by 3
colors = ("red", "blue", "green")

print(colors * 3)

"""
12. Return the number of times 8 appears in this tuple
thistuple = (1, 3, 7, 8, 7, 5, 4, 6, 8, 5)
"""

thistuple = (1, 3, 7, 8, 7, 5, 4, 6, 8, 5)

print(thistuple.count(8))

###########################    Exercise3 (Sets)

#1. Use the set() constructor to create a set of 3 of your favorite beverages

beverages = set(["passion fruit", "munanasi", "water"])

print(beverages)

#2. Use the correct method to add 2 more items to the beverages set.

beverages.add("soda")

beverages.add("minute maid")

"""
3. Given the set below;
mySet = {“oven”, “kettle”, “microwave”, “refrigerator”}
Check if microwave is present in the set.
"""
mySet = {"oven", "kettle", "microwave", "refrigerator"}

print(mySet.intersection({"microwave"}))

#4. Write a python program to remove “kettle” from the set above

mySet.remove("kettle")

print(mySet)

#5. Write a python program to loop through the set above
for s in mySet:
    print(s)

#6. Write a set of 4 items and a list of two items. Write a python program to add elements in
#the list to elements in the set.

mySet = {"hey", "hello", "ok" , "good"}
myList = ["hi", "tsup"]

mySet = mySet.union(myList)

print(mySet)

#Write two sets, one containing your ages and the other your first names. Join the two
#sets

ages = {21,10,23,20}
names = {"rashid", "kisejjere"}

joint = ages.union(names)

print(joint)

###################### Exercise4 (Strings)

#1. Declare two variables, an integer and a string and use the correct method to concatenate
#the two variable

a = 20
b = "the number is "

c = b + str(a)

print(c)

"""
2. Consider the example below;
txt = “ Hello, Uganda! ”
Output the string without spaces at the beginning, in the middle and at the end.
"""

txt = " Hello, Uganda! "

output = "".join(txt.strip().split(" "))

print(output)

#3. Write a python program to convert the value of ‘txt’ to uppercase.

print("txt".upper())

#4. Write a python program to replace character ‘U’ with ‘V’ in the string above
t = txt.replace("U", "V")

print(t)

"""
5. Using the code below, write a python program to return a range of characters in the 2nd
, 3rd and 4th position.
y = “I am proudly Ugandan”
"""

y = "I am proudly Ugandan"
print("2nd", y[1])
print("3rd", y[2])
print("4th", y[2])

"""
6. The piece of code below will give an error when output;
x = “All “Data Scientists” are cool!”
Write a python program to correct it
"""

x = "All \"Data Scientists\" are cool!"
print(x)

###################    Exercise5 (Dictionaries)

"""
1. With reference to the dictionary below, write a python program to print the value of the
shoe size.
Add this dictionary to your .py file
Shoes = {
“brand” : “Nick”,
“color” : “black”,
“size” : 40
}
"""

Shoes = {
"brand" : "Nick",
"color" : "black",
"size" : 40
}

print(Shoes["size"])

#2. Write a python program to change the value “Nick” to “Adidas"
Shoes["brand"] = "Adidas"
print(Shoes)

#3. Write a python program to add a key/value pair "type”: "sneakers" to the dictionary

Shoes["type"] = "sneakers"
print(Shoes)

#4. Write a python program to return a list of all the keys in the dictionary above.

print(Shoes.keys())

#5. Write a python program to return a list of all the values in the dictionary above.

print(Shoes.values())

#6. Check if the key “size” exists in the dictionary above

if "size" in Shoes:
    print(True)
else:
    print(False)

#. Write a python program to loop through the dictionary above.
for item in Shoes.items():
    print(item)

#8. Write a python program to remove “color” from the dictionary

Shoes.pop("color")

print(Shoes)

#9. Write a python program to empty the dictionary above

Shoes.clear()

print(Shoes)

#10. Write a dictionary of your choice and make a copy of it

sample = {
    2 : "two",
    3 : "three",
    4 : "four"
}

dict_copy = sample.copy()

print(sample is dict_copy)

#11. Write a python program to show nested dictionaries

newsted_dict = {
    "dict" : {
        1 : "one",
        2 : "two"
    },

    "inn" : {
        "in" : {
            "val" : 43
        }
    }
}

print(newsted_dict)


# -*- coding: utf-8 -*-
import scrapy
from yun_shang_wang.items import YunShangWangItem
import re

class YswSpider(scrapy.Spider):
    name = 'ysw'
    allowed_domains = ['www.ynshangji.com',
                       'ynshangji.com'
                       ]
    start_urls = ['http://www.ynshangji.com/']
    # start_urls = ['http://13281188246.ynshangji.com/liuyan/']

    '''
    http://shunda03.ynshangji.com/liuyan/
    http://zhisheng123.ynshangji.com/liuyan/
    ttp://13281188246.ynshangji.com/liuyan/

    '''

    def parse(self, response):
        # 大分类
        class_list = response.xpath('//ul[@class="m_zl"]//li//a')
        print('----- len(class_list)', len(class_list))
        if class_list != []:
            for min_class in class_list:
                p_d_url = min_class.xpath('./@href')
                if p_d_url != []:
                    page_data_url = p_d_url.extract()[0]
                    yield scrapy.Request(url=page_data_url, callback=self.parse_page_data)

    def parse_page_data(self, response):
        # 页面上列表  翻页
        print('***** ',response.url)
        data_list = response.xpath('//div[@class="s-list s-pro-list"]/ul//li')
        n_url = response.xpath('//div[@class="paging mb30"]/a[last()]/@href')
        print('**** len(data_list) = ', len(data_list))
        if data_list != []:
            for data_info in data_list:
                d_url = data_info.xpath('.//div[@class="company"]/a[2]/@href')
                if d_url != []:
                    data_url = d_url.extract()[0] + '/liuyan/'
                    yield scrapy.Request(url=data_url, callback=self.parse_data, meta={'info_url':data_url})

        # 翻页
        if n_url != []:
            next_url = 'http://www.ynshangji.com' + n_url.extract()[0]
            print('next_url = ', next_url)
            yield scrapy.Request(url=next_url, callback=self.parse_page_data)

    def parse_data(self, response):
        # 详细信息
        print('+++++ ', response.url)
        data_info = response.xpath('//table[@class="bgcolor3"]//tr')
        print('++++++++ ', len(data_info))
        # print('+++ ', response.body.decode('gbk'), '+++')

        item = YunShangWangItem()
        # 爬取对应官网名称(siteName) 例： 阿里巴巴商友圈
        item['siteName'] = '云商网'
        # 爬取对应官网链接(webLinks) 例： https://club.1688.com/
        item['webLinks'] = 'http://www.ynshangji.com/'
        # 对应详情页链接(detailLink)：  	https://qiye.gongchang.com/hongyipu/contact/
        item['detailLink'] = response.meta['info_url']
        data_list = response.xpath('//table[@id="viewAttribute"]//tr')
        # 企业名称:(companyName)			中国科学器材有限公司
        item['companyName'] = ''
        companyName = response.xpath('//table[@class="bgcolor3"]//tr[1]/td[2]/text()').extract()
        print('companyName = ', companyName)
        if companyName == []:
            companyName = response.xpath('//div[@id="bodyleft"]//li[1]/text()').extract()
            if companyName != []:
                item['companyName'] = companyName[0].replace('\xa0', '').replace('\n', '').replace('\t', '').replace('\r', '')
        else:
            item['companyName'] = companyName[0].replace('\xa0', '').replace('\n', '').replace('\t', '').replace('\r', '')

        # print('************ ', item['companyName'])
        # 企业英文名：(companyEnglishName)			China National Scientific Instruments and Materials Co., Ltd
        item['companyEnglishName'] = ''
        # 注册类型：(registrationType)		供应商
        item['registrationType'] = ''
        # 企业性质：(companyType)			国有绝对控股企业
        item['companyType'] = ''
        # 成立时间:(establishedTime)   		2015-07-22
        item['establishedTime'] = ''
        # 营业执照号:(businessLicenseNo)			91331102350072370U
        item['businessLicenseNo'] = ''
        # 经营模式：(businessModel)			贸易型
        item['businessModel'] = ''
        # 注册资本：(registeredCapital)			400000.000000 万元
        item['registeredCapital'] = ''
        # 雇员人数：(employee)			301-500 人
        item['employee'] = ''
        # 联 系 人：(contact)			雷靖行
        item['contact'] = ''
        contact = response.xpath('//table[@class="bgcolor3"]//tr[1]/td[4]/text()').extract()
        if contact == []:
            contact = response.xpath('//div[@id="bodyleft"]//li[3]/text()').extract()
            if contact != []:
                item['contact'] = contact[0].replace(' ', '').replace(':', '').replace('：', '').replace('\n', '').replace('\t', '').replace('\r', '').replace('联系人', '')
        else:
            item['contact'] = contact[0].replace('\xa0', '').replace('\n', '').replace('\t', '').replace('\r', '')
        # 手机号码：(phoneNumber)			18117451540
        item['phoneNumber'] = ''
        phoneNumber = response.xpath('//table[@class="bgcolor3"]//tr[2]/td[4]/text()').extract()
        if phoneNumber == []:
            phoneNumber = response.xpath('//div[@id="bodyleft"]//li[5]/text()').extract()
            if phoneNumber != []:
                item['phoneNumber'] = phoneNumber[0].replace(' ', '').replace(':', '').replace('：', '').replace('\n', '').replace('\t', '').replace('\r', '').replace('手机', '')
        else:
            item['phoneNumber'] = phoneNumber[0].replace(' ', '').replace('\n', '').replace('\t', '').replace('\r', '')
        # 联系电话：(telephone)			0755-00000000
        item['telephone'] = ''
        telephone = response.xpath('//table[@class="bgcolor3"]//tr[2]/td[2]/text()').extract()
        if telephone == []:
            telephone = response.xpath('//div[@id="bodyleft"]//li[4]/text()').extract()
            if telephone != []:
                item['telephone'] = telephone[0].replace(' ', '').replace(':', '').replace('：', '').replace('\n', '').replace('\t', '').replace('\r','').replace('电话', '')
        else:
            item['telephone'] = telephone[0].replace('\xa0', '').replace('\n', '').replace('\t', '').replace('\r','')
        # 公司传真：(companyFax)			0755-00000000
        item['companyFax'] = ''
        # E-MAIL  : (Email)  		18641572818@163.com
        item['Email'] = ''
        Email = response.xpath('//table[@class="bgcolor3"]//tr[3]/td[4]/text()').extract()
        if Email != []:
            if '系统已隐藏' not in Email[0]:
                item['Email'] = Email[0].replace('\n', '').replace('\t', '').replace('\r','')

        # Q Q号 码：(qq)   		282278944
        item['qq'] = ''
        qq = response.xpath('//table[@class="bgcolor3"]//tr[4]/td[4]/a/@href').extract()
        if qq == []:
            qq = response.xpath('//table[@class="bgcolor3"]//tr[4]/td[4]/a/img/@src').extract()
            if qq != []:
                item['qq'] = qq[0].replace('\n', '').replace('\t', '').replace('\r', '').replace(':', ':').replace('：', ':').split(':')[2]
        else:
            item['qq'] = re.findall(r'uin=(.*?)&Site', qq[0].replace('\xa0', '').replace('\n', '').replace('\t', '').replace('\r', ''), re.DOTALL)[0]
        # 微信： (wechat)  		mdjx6673
        item['wechat'] = ''
        # 邮政编码：	(postcode)		210000
        item['postcode'] = ''
        # 客服旺旺：	(angelBeauty)		**********
        item['angelBeauty'] = ''
        # 主营产品：(mainProducts)			理化分析仪器、光学仪器、电子仪器及配件、生物技术及生物工程设备、计算机及附属设备
        item['mainProducts'] = ''
        # 企业地址：(businessAddress)			北京市朝阳区太阳宫中路19号院1号楼4层
        item['businessAddress'] = ''
        businessAddress = response.xpath('//table[@class="bgcolor3"]//tr[3]/td[2]/text()').extract()
        if businessAddress == []:
            businessAddress = response.xpath('//div[@id="bodyleft"]//li[6]/text()').extract()
            if businessAddress != []:
                item['businessAddress'] = businessAddress[0].replace(' ', '').replace(':', '').replace('：', '').replace('\xa0', '').replace('\n', '').replace('\t','').replace('\r', '').replace('地址', '')
        else:
            item['businessAddress'] = businessAddress[0].replace('\xa0', '').replace('\n', '').replace('\t','').replace('\r', '')
        # 企业网址：(Website)			www.csimc.com.cn
        item['Website'] = ''
        Website = response.xpath('//table[@class="bgcolor3"]//tr[5]/td[2]/a/@href').extract()
        if Website == []:
            pass
        else:
            item['Website'] = Website[0].replace('\xa0', '').replace('\n', '').replace('\t', '').replace('\r', '')
        print('item = ', item)
        # if item['phoneNumber'] != '':
        yield item


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Tue Oct 18 15:20:23 2022

@author: yuchenzhou
"""

import os
a=os.getcwd()
print(a)

protein_name=input('Enter Protein Name:')

file = open(a+'/MOL_GMX.top')
lines = file.readlines()
file.close()

find_defaults=lines.index('[ defaults ]\n')
print(find_defaults)
find_system=lines.index('[ system ]\n')
print(find_system)

del lines[find_system:find_system+6]
del lines[find_defaults:find_defaults+3]
file_itp=open('/Users/yuchenzhou/Desktop/GROMACS/tmp/MOL_GMX.itp','w')
file_itp.writelines(lines)
if '_ZN' in protein_name:
    file_itp.write('; Ligand position restraints \n#ifdef POSRES_LIG \n#include "posre_MOL.itp" \n#endif')

file_itp.close()

file_pro = open('/Users/yuchenzhou/Desktop/GROMACS/Protein_Input_Files/'+protein_name+'/'+protein_name+'_processed.gro')
pro_lines = file_pro.readlines()
file_pro.close()

file_lig = open(a+'/MOL_GMX.gro')
lig_lines = file_lig.readlines()

pro_lines[1]='  '+str(int(pro_lines[1])+int(lig_lines[1]))+'\n'

file_com = open('/Users/yuchenzhou/Desktop/GROMACS/tmp/complex.gro','w')
file_com.writelines(pro_lines[:-1])
file_com.writelines(lig_lines[2:-1])
file_com.writelines(pro_lines[-1])
file_com.close()


import turtle
import random

def draw_polygon(turt, n, l):
    """'turt' is turtle object, 'n' is number of sides, 'l' is length of each side"""
    for i in range(n):
        turt.forward(l)
        turt.left(360 / n)

def radial_pattern(turt, n, l, numshapes):
    """draws an n-polygon with sides l long numshapes times in a circular pattern"""
    for i in range(numshapes):
        draw_polygon(turt, n, l)
        turt.left(360 / numshapes)

def radial_pattern_filled_random(turt, n, l, numshapes):
    turt.fillcolor(random.randint(0, 255),
                   random.randint(0, 255),
                   random.randint(0, 255))
    turt.begin_fill()
    radial_pattern(turt, n, l, numshapes)
    turt.end_fill()

def main():
    t = turtle.Turtle()
    t.screen.colormode(255)
    t.speed(1)
    t.up()

    x = -t.screen.window_width()+200
    y = -t.screen.window_height()+200
    print(x, y)
    t.goto(x, y)
    t.setheading(180)
    t.down()
    t.backward(77)

    turtle.done()

if __name__ == '__main__':
    main()


from setuptools import find_packages
from setuptools import setup

package_name = 'jetbot_move'

setup(
    name=package_name,
    version='0.14.0',
    packages=find_packages(exclude=['test']),
    data_files=[
        ('share/ament_index/resource_index/packages',
            ['resource/' + package_name]),
        ('share/' + package_name, ['package.xml']),
        ('share/' + package_name + '/demo_routines', ['demo_routines/autumn.json']),
        ('share/' + package_name + '/launch',
         ['launch/circle.launch.py', 'launch/dance.launch.py']),
    ],
    install_requires=['setuptools'],
    zip_safe=True,
    author='Jeremy Wallace',
    author_email='jeremygw@amazon.com',
    maintainer='Jeremy Wallace',
    maintainer_email='jeremygw@amazon.com',
    keywords=['ROS'],
    classifiers=[
        'Intended Audience :: Developers',
        'License :: OSI Approved :: Apache Software License',
        'Programming Language :: Python',
        'Topic :: Software Development',
    ],
    description=(
        'Move operations for the Jetbot'
    ),
    license='Apache License, Version 2.0',
    tests_require=['pytest'],
    entry_points={
        'console_scripts': [
            'circle = jetbot_move.circle:main',
            'dance = jetbot_move.dance:main'
        ],
    },
)


import sys

def main(lines):
    # このコードは標準入力と標準出力を用いたサンプルコードです。
    # このコードは好きなように編集・削除してもらって構いません。
    # ---
    # This is a sample code to use stdin and stdout.
    # Edit and remove this code as you like.
    A, B, C, X = map(int, lines[0].split())      # lines[0].split() のように、インデックスを指定していつもの文字列にしてsplitするやつにもち込めればいいね。

    if X <= A:
        print(1)
    elif X <= B:
        print(C / (B - (A+1) + 1))
    else:
        print(0)

if __name__ == '__main__':
    lines = []
    for l in sys.stdin:
        lines.append(l.rstrip('\r\n'))
    main(lines)

# ちゃんとACとれたよ！！！
# 手入力だと ctrl D 幼いといけないけど、提出すると行けた。


import os
import numpy as np
import matplotlib

import matplotlib.pyplot as plt

from .tools import *

def show(block=True):
    plt.show(block)

def save(fig, legend, fileName, fileFormat='pdf', overwrite=False):
    fullFileName = fileName + '.' + fileFormat if not fileName.endswith(fileFormat) else fileName
    if not overwrite and os.path.exists(fullFileName):
        warn("Output file %s exists already! Not overwriting!" % fullFileName)
        return

    print("Writing plot to " + fullFileName)
    extra = ()
    if legend:
        extra = (legend,)

    fig.savefig(fullFileName, bbox_inches='tight', format=fileFormat)

def plotMultiDelays(x, delays, xLabel, labels=None, title=None, markersize=1.5, fileName=None, overwrite=None, colors=None, block=False, show=False):
    if not colors:
        defaultColors = ['r', 'g', 'b']
        colors = list(reversed(defaultColors[:len(delays)]))

    yLabel = "offset [msec]"

    import matplotlib.gridspec as gridspec

    figsize = (5, 2.5)

    breakX = False

    def plotMyDelays(ax):
        xA = np.array(x, dtype=float)
        xA = xA - min(xA[~np.isnan(xA)])
        if labels:
            for i, (d, l) in enumerate(zip(delays, labels)):
                assert(len(xA) == len(d))
                ax.plot(xA, np.asarray(d) * 1000, linestyle='-', marker='.', markersize=markersize, label=l, color=colors[i])
        else:
            for i, d in enumerate(delays):
                assert(len(xA) == len(d))
                ax.plot(xA, np.asarray(d) * 1000, linestyle='-', marker='.', markersize=markersize, color=colors[i])

    fig, ax = plt.subplots(1, 1, figsize=figsize)
    plotMyDelays(ax)
    ax.set_xlabel(xLabel)
    ax.set_ylabel(yLabel)

    if title:
        ax.set_title(title)

    legend = None
    if labels:
        legend = ax.legend(loc='upper right', shadow=False)

    if fileName:
        save(fig, legend, fileName, overwrite=overwrite)

    if show:
      show(block)
    return fig


import random
import pygame

from settings import *
from tile import Tile
from player import Player
from debug import debug
from support import *
from weapon import Weapon

class Level:
    def __init__(self):

        # Get the display surface.
        self.player = None
        self.display_surface = pygame.display.get_surface()

        # Sprite group setup.
        self.visible_sprites = YSortCameraGroup()
        self.obstacle_sprites = pygame.sprite.Group()

        # Attack sprites.
        # Stores the current weapon used for attacking.
        self.current_attack = None

        # Sprite setup
        self.create_map()

    def create_map(self):
        # dict of the different layouts of the map.
        layouts = {
            "boundary": import_csv_layout("map/map_FloorBlocks.csv"),
            "grass": import_csv_layout("map/map_Grass.csv"),
            "object": import_csv_layout("map/map_Objects.csv")
        }

        # Importing all the graphics for objects.
        graphics = {
            "grass": import_folder("graphics/grass"),
            "objects": import_folder("graphics/objects")
        }

        # Loop over dictionary containing the layouts of image.
        for style, layout in layouts.items():
            # Loop over layout for columns & rows.
            for row_index, row in enumerate(layout):
                for col_index, col in enumerate(row):
                    # Avoid boundaries being placed in incorrect areas.
                    if col != "-1":
                        # Set spacing between each index according to the tile size.
                        x = col_index * TILE_SIZE
                        y = row_index * TILE_SIZE
                        if style == "boundary":
                            Tile((x, y), [self.obstacle_sprites], "invisible")

                        if style == "grass":
                            # Get random grass image.
                            random_grass_image = random.choice(graphics["grass"])
                            # Create a grass tile.
                            Tile((x, y), [self.visible_sprites, self.obstacle_sprites], "grass", random_grass_image)

                        if style == "object":
                            # Create an object tile.
                            surf = graphics["objects"][int(col)]
                            Tile((x, y), [self.visible_sprites, self.obstacle_sprites], "object", surf)

        # Place the player in towards the middle of the screen on the path.
        self.player = Player((2000, 1430), [self.visible_sprites], self.obstacle_sprites, self.create_attack,
                             self.destroy_attack)

    # Bring weapon to the level class to interact with objects.
    def create_attack(self):
        self.current_attack = Weapon(self.player, [self.visible_sprites])

    # Destroys the attack image on screen & sets current_attack back to none.
    def destroy_attack(self):
        if self.current_attack:
            self.current_attack.kill()
        self.current_attack = None

    # Runs the level class.
    def run(self):
        # update & draw the game.
        self.visible_sprites.custom_draw(self.player)
        self.visible_sprites.update()
        debug(self.player.status)

class YSortCameraGroup(pygame.sprite.Group):
    def __init__(self):
        super().__init__()
        self.display_surface = pygame.display.get_surface()

        # Get half the width & height of the display surface.
        self.half_width = self.display_surface.get_size()[0] // 2
        self.half_height = self.display_surface.get_size()[1] // 2

        # Vector to help offset the camera according to player position.
        self.offset = pygame.math.Vector2()

        # Creating the floor surface & rectangle to be below everything.
        self.floor_surf = pygame.image.load("graphics/tilemap/ground.png").convert()
        self.floor_rect = self.floor_surf.get_rect(topleft=(0, 0))

    def custom_draw(self, player):
        # Getting the offset.
        self.offset.x = player.rect.centerx - self.half_width
        self.offset.y = player.rect.centery - self.half_height

        # Draw the floor.
        floor_offset_position = self.floor_rect.topleft - self.offset
        self.display_surface.blit(self.floor_surf, floor_offset_position)

        """
        Sort the sprites so the player appears behind it with a greater y position
        & in front of obstacles with a lesser y position.
        """
        for sprite in sorted(self.sprites(), key=lambda sprite: sprite.rect.centery):
            # Setting the offset position to the top left according to values in offset vector.
            offset_position = sprite.rect.topleft - self.offset
            self.display_surface.blit(sprite.image, offset_position)


import os
import time
from prometheus_client import start_http_server, Gauge, Histogram, Counter
import requests
import logging

logger=logging.getLogger()
logging.basicConfig(level=logging.DEBUG)

_INF = float("inf")

class AppMetrics:
    def __init__(self, app_port=8000, polling_interval_seconds=5):
        self.app_port = app_port
        self.polling_interval_seconds = polling_interval_seconds

        # Prometheus metrics to collect
        self.total_requests = Counter("total_request","Total request")
        self.total_succ_requests = Counter("total_succ_request", "Total successful request")
        self.total_fail_requests = Counter("app_total_fail_request","Total failed request")
        self.time_dur = Histogram('python_request_duration_seconds', 'Histogram for the duration in seconds.', buckets=(1, 2, 5, 6, 10, _INF))

        self.total_number_per_label =  {
            'airplane': Counter("total_airplane_requests", "Total airplane requests"),
            'automobile': Counter("total_automobile_request", "Total automobile requests"),
            'bird': Counter("total_bird_requests", "Total bird requests"),
            'cat':Counter("total_cat_requests", "Total cat requests"),
            'deer':Counter("total_deer_requests", "Total deer requests"),
            'dog':Counter("total_dog_requests", "Total dog requests"),
            'frog':Counter("total_frog_requests", "Total frog requests"),
            'horse':Counter("total_horse_requests", "Total horse requests"),
            'ship':Counter("total_ship_requests", "Total ship requests"),
            'truck':Counter("total_truck_requests", "Total truck requests")
            }

        self.total_acc_per_label =  {
            'airplane': Gauge("total_airplane_acc", "total airplane accuracy"),
            'automobile': Gauge("total_automobile_acc", "total automobile accuracy"),
            'bird': Gauge("total_bird_acc", "total bird accuracy"),
            'cat':Gauge("total_cat_acc", "total cat accuracy"),
            'deer':Gauge("total_deer_acc", "total deer accuracy"),
            'dog':Gauge("total_dog_acc", "total dog accuracy"),
            'frog':Gauge("total_frog_acc", "total frog accuracy"),
            'horse':Gauge("total_horse_acc", "total horse accuracy"),
            'ship':Gauge("total_ship_acc", "total ship accuracy"),
            'truck':Gauge("total_truck_acc", "total truck accuracy")
            }

        self.average_acc = Gauge("average_acc", "Average accuracy for all labels")

    def run_metrics_loop(self):
        while True:
            self.fetch()
            time.sleep(self.polling_interval_seconds)

    def fetch(self):
        # Fetch raw status data from the application
        status_data = None
        try:
            headers = {'Accept': 'application/json'}
            resp = requests.get(url=f"http://localhost:{self.app_port}/metric", headers=headers)
            status_data = resp.json()
        except Exception as e:
            print(e)
        if status_data is not None:
            # logger.info(status_data)
            # Update Prometheus metrics with application metrics
            self.total_requests.inc(status_data['suc_requests'] + status_data['failed_requests'])
            self.total_succ_requests.inc(status_data['suc_requests'])
            self.total_fail_requests.inc(status_data['failed_requests'])

            for item, accuracy in status_data['acc_per_label'].items():
                for acc in accuracy:
                    self.total_acc_per_label[item].set(acc)

            for item, num in status_data['num_labels'].items():
                self.total_number_per_label[item].inc(num)

            for dur in status_data['time_dur']:
                self.time_dur.observe(dur)

def main():

    polling_interval_seconds = int(os.getenv("POLLING_INTERVAL_SECONDS", "5"))
    app_port = int(os.getenv("APP_PORT", "8000"))
    exporter_port = int(os.getenv("EXPORTER_PORT", "9877"))
    logger.info(f"exporter started on port 9877")

    app_metrics = AppMetrics(
        app_port=app_port,
        polling_interval_seconds=polling_interval_seconds
    )
    start_http_server(exporter_port)
    app_metrics.run_metrics_loop()

if __name__ == "__main__":
    main()


"""
CH14. 49_Minimum_Height_Trees.py
"""
import collections
from gc import collect
import heapq
import functools
import itertools
import re
import sys
import math
import bisect

class TreeNode:
    def __init__(self, val, left = None, right = None):
        self.val = val
        self.left = left
        self.right = right

def toTree(list):
    size = len(list)
    idx = 1

    if size == 0:
        return None

    def recursive(i):
        if i > size or list[i-1] is None:
            return None
        node = TreeNode(list[i-1])
        node.left = recursive(i*2)
        node.right = recursive(i*2+1)
        return node
    return recursive(idx)

def printTree(root):
    if root is None:
        print('Tree is Empty')

    q = collections.deque([root])

    while q:
        for _ in range(len(q)):
            cur = q.popleft()
            if cur.left:
                q.append(cur.left)
            if cur.right:
                q.append(cur.right)
            print(cur.val, end = ' ')
        print()

# 입력 1
n1 = 4
edges1 = [[1, 0], [1, 2], [1, 3]]
# 출력 1
output1 = [1]

# 입력 2
n2 = 6
edges2 = [[0, 3], [1, 3], [2, 3], [4, 3], [5, 4]]
# 출력 2
output2 = [3, 4]

# 입력 3
n3 = 9
edges3 = [[1, 3], [2, 3], [3, 4], [3, 5], [4, 6], [6, 10], [5, 7], [5, 8], [8, 9]]
# 출력 3
output3 = [3]

# --------------------------------------------------
def findMinHeightTrees(n, edges):
    if n <= 1:
        return [0]

    graph = collections.defaultdict(list)
    for i, j in edges:
        graph[i].append(j)
        graph[j].append(i)

    leaves = []
    for i in range(n + 1):
        if len(graph[i]) == 1:
            leaves.append(i)

    while n > 2:
        n -= len(leaves)
        new_leaves = []
        for leaf in leaves:
            neighbor = graph[leaf].pop()
            graph[neighbor].remove(leaf)

            if len(graph[neighbor]) == 1:
                new_leaves.append(neighbor)

        leaves = new_leaves

    return leaves

print(findMinHeightTrees(n1, edges1))
print(findMinHeightTrees(n1, edges1) == output1)
print(findMinHeightTrees(n2, edges2))
print(findMinHeightTrees(n2, edges2) == output2)
print(findMinHeightTrees(n3, edges3))
print(findMinHeightTrees(n3, edges3) == output3)

# --------------------------------------------------


# -*- coding: utf-8 -*-
"""
@Time ： 2023/3/5 16:41
@Auth ： Yin yanquan
@File ：criterion.py
@IDE ：PyCharm
@Motto：ABC(Always Be Coding)
"""

import numpy as np
import cv2
from PIL import Image
from PIL import ImageChops

def cal_IOU(image1, image2):
    """
    计算重叠度
    :param image1: 图片1
    :param image2: 图片2
    :return: None（TP）
    """
    gt_mask = cv2.imread(image1, cv2.IMREAD_GRAYSCALE)
    out_mask = cv2.imread(image2, cv2.IMREAD_GRAYSCALE)
    size = gt_mask.shape
    w = size[1]  # 宽度
    h = size[0]  # 高度
    IOU_mask = np.zeros((h, w), dtype=int)
    # print(size,w,h)
    for i in range(h):
        for j in range(w):
            if int(gt_mask[i][j]) > 240 and int(out_mask[i][j]) > 240:
                IOU_mask[i][j] = 255
    cv2.imwrite('./IOU.jpg', IOU_mask)
    return IOU_mask

def compare_images(image1, image2, save_path):
    """
    比较图片，如果有不同则生成展示不同的图片
    :param image1: 第一张图片的路径
    :param image2: 第二张图片的路径
    :param save_path: 不同图的保存路径
    :return: None （FP+FN）
    """
    image_one = Image.open(image1)
    image_two = Image.open(image2)
    try:
        diff = ImageChops.difference(image_one, image_two)

        if diff.getbbox() is None:
            print("No difference between the two pictures")
        else:
            diff.save(save_path)
    except ValueError as e:
        text = ("表示图片大小和box对应的宽度不一致，参考API说明：Pastes another image into this image."
                "The box argument is either a 2-tuple giving the upper left corner, a 4-tuple defining the left, upper, "
                "right, and lower pixel coordinate, or None (same as (0, 0)). If a 4-tuple is given, the size of the pasted "
                "image must match the size of the region.使用2纬的box避免上述问题")
        print("【{0}】{1}".format(e, text))

def cal_criterion(ground_truth_mask, output_mask):
    """
    计算对抗样本输入模型后的mask与ground truth的比值
    :param ground_truth_mask: 原图片对应的gt_mask
    :param output_mask: 对抗样本输入模型后的mask与gt_mask的差值
    :return: 两者的比率， output_mask的非黑像素数量，gt_mask的非黑像素数量，攻击是否成功
    """

    gt_mask = cv2.imread(ground_truth_mask, cv2.IMREAD_GRAYSCALE)
    gt_pixels = cv2.countNonZero(gt_mask)

    out_mask = cv2.imread(output_mask, cv2.IMREAD_GRAYSCALE)
    out_pixels = cv2.countNonZero(out_mask)

    attack_rate = out_pixels / gt_pixels

    return attack_rate, out_pixels, gt_pixels

def precision(public_mask, output_mask):
    """
    计算准确率
    :param public_mask: 图片公共部分
    :param output_mask: 模型输出图片
    :return: 准确率
    """
    # p_mask = cv2.imread(public_mask, cv2.IMREAD_GRAYSCALE)
    # p_pixels = cv2.countNonZero(p_mask)
    p_pixels = cv2.countNonZero(public_mask)

    out_mask = cv2.imread(output_mask, cv2.IMREAD_GRAYSCALE)
    out_pixels = cv2.countNonZero(out_mask)

    pre_rate = p_pixels / out_pixels
    return pre_rate

def recall(public_mask, ground_truth_mask):
    """
    计算召回率
    :param public_mask: 图片公共部分
    :param ground_truth_mask: 原图片对应的gt_mask
    :return: 召回率
    """
    # p_mask = cv2.imread(public_mask, cv2.IMREAD_GRAYSCALE)
    # p_pixels = cv2.countNonZero(p_mask)
    p_pixels = cv2.countNonZero(public_mask)

    gt_mask = cv2.imread(ground_truth_mask, cv2.IMREAD_GRAYSCALE)
    gt_pixels = cv2.countNonZero(gt_mask)

    re_rate = p_pixels / gt_pixels
    return re_rate

def f_score(precision_rate, recall_rate, beta=2):
    """
    计算F分数
    :param precision_rate: 准确率
    :param recall_rate: 召回率
    :param beta: 计算权重
    :return: F分数
    """
    numerator = precision_rate * recall_rate
    denominator = ((beta ** 2) * precision_rate) + recall_rate
    ratio = 1 + (beta ** 2)
    if denominator < 0.001:
        score = 0
    else:
        score = ratio * numerator / denominator
    return score

def usage(ground_truth_mask, output_mask, beta=2):
    """
    具体图片计算方法
    :param ground_truth_mask: 原图片对应的gt_mask
    :param output_mask: 模型输出图片
    :param beta: 计算权重
    :return: F分数，准确率，召回率
    """
    public_mask = cal_IOU(ground_truth_mask, output_mask)
    pre_rate = precision(public_mask, output_mask)
    re_rate = recall(public_mask, ground_truth_mask)
    # print(pre_rate, re_rate)
    F_score = f_score(pre_rate, re_rate, beta=beta)
    # print(F_score)
    return F_score, pre_rate, re_rate

if __name__ == '__main__':
    img1 = '../example_gt.png'
    img2 = '../output/fgsm/3_fgsm_output_eps_0.1.jpg'
    # cal_IOU(img1, img2)
    # pre_rate = precision(img3, img2)
    # re_rate = recall(img3, img1)
    # print(pre_rate, re_rate)
    # F_score = f_score(pre_rate, re_rate)
    # print(F_score)
    F_score, _, _ = usage(img1, img2, beta=2)
    print(F_score)


import numpy as np
from ..fileio import FileIO as psopen
from ...common import pandas
#import pysal_examples
from ... import examples as pysal_examples
import unittest as ut

PANDAS_EXTINCT = pandas is None

class Test_Table(ut.TestCase):
    def setUp(self):
        self.filehandler = psopen(pysal_examples.get_path('columbus.dbf'))
        self.df = self.filehandler.to_df()
        self.filehandler.seek(0)
        self.shapefile = psopen(pysal_examples.get_path('columbus.shp'))
        self.csvhandler = psopen(pysal_examples.get_path('usjoin.csv'))
        self.csv_df = self.csvhandler.to_df()
        self.csvhandler.seek(0)

    @ut.skipIf(PANDAS_EXTINCT, 'missing pandas')
    def test_to_df(self):
        for column in self.csv_df.columns:
            if column.lower() == 'name':
                continue
            np.testing.assert_allclose(self.csvhandler.by_col(column),
                                       self.csv_df[column].values)
        for column in self.df.columns:
            if column == 'geometry':
                continue
            np.testing.assert_allclose(self.filehandler.by_col(column),
                                       self.df[column])


'''
448. Find All Numbers Disappeared in an Array

Given an array of integers where 1 ≤ a[i] ≤ n (n = size of array), some elements appear twice and others appear once.

Find all the elements of [1, n] inclusive that do not appear in this array.

Could you do it without extra space and in O(n) runtime? You may assume the returned list does not count as extra space.

Example:

Input:
[4,3,2,7,8,2,3,1]

Output:
[5,6]
'''

class Solution(object):
    def findDisappearedNumbers(self, nums):
        """
        :type nums: List[int]
        :rtype: List[int]
        """
        if len(nums) == 0: return []
        Disappeared  = []
        nums.sort()
        nums = [0] + nums
        nums = nums + [len(nums)]
        for i in range(0,len(nums)-1):
            j = i+1
            if nums[j] - nums[i] <=1: continue
            a, b = nums[i]+1, nums[j]
            interval = [item for item in range(a,b)]
            Disappeared = Disappeared + interval
        return Disappeared

Arrays/448-Find All Numbers Disappeared in an Array.py


# Day7 of my 100DaysOfCode Challenge
# Program to calculate factorial using recursive function

def factorial_iter(n):
    factorial = 1
    for i in range(n):
        factorial = factorial * (i+1)
    return factorial

def factorial_recursive(n):
    if n == 1 or n == 0:
        return 1
    return n * factorial_recursive(n-1)

num = int(input("Enter a number to calculate factorial: "))
# f = factorial_iter(num)
f = factorial_recursive(num)
print(f"Factorial of {num} is: {f}")