# -*- coding: utf-8 -*-
# Traffic Data Process Automatically
# Xin Meng
# 2015.11.02
# This script is used for process the traffic txt file.
# 1. Set the configure
# 2. Run this script and get the result.
import csv
import os
import logging
import re
import utils.network
__author__ = 'xin'

# configuration variable

# OutputCSVDir = ""
# ReportDir = ""
# NormalDBDir = ""
# InputNormalDir = ""
# InputInfectDir = ""

# 这里5个重要的参数：
# 输出的csv目录
output_csv_dir = ""
# 输出的报告目录
report_dir = ""
# normal db目录
normal_db_dir = ""
# 输入的normal文件目录
input_normal_dir = ""
# 输入的infect文件目录
input_infect_dir = ""
normal_db_file = "normal_db.txt"
public_ip_range_file = "public_ip_range.txt"
output_extension = ".csv"
# remember if you want to change the global variance in function, you need use global xxx
normal_db_size = 0
# Current Path (the Script)
path = os.path.split(os.path.realpath(__file__))[0]
# The Scan Information
num_normal_input_file = 0
num_infect_input_file = 0
normal_input_file_list = []
infect_input_file_list = []
# Globle statistic information
num_normal_packet = 0
num_packet_label_infect = 0
num_packet_label_normal = 0
# remember if you want to change the global variance in function, you need use global xxx
normal_db_size = 0
# Current Path (the Script)
path = os.path.split(os.path.realpath(__file__))[0]
# The Scan Information
num_normal_input_file = 0
num_infect_input_file = 0
normal_input_file_list = []
infect_input_file_list = []
# Global statistic information
num_normal_packet = 0
num_packet_label_infect = 0
num_packet_label_normal = 0

def match_normal_db(b_infect_packet, public_ip_range, str_normal_db):
    # 打开一个DB文件,将所有DB数据读入到String中,
    flag_public_range = 0
    with open(normal_db_dir + normal_db_file, 'a+') as normal_db:
        for normal_db_line in normal_db:
            str_normal_db += normal_db_line
    for public_ip_range_line in public_ip_range:
        # compare the b_infect_packet ip source or ip destination with the IP range whether in the range
        # Because there is one of the two IP is the mobile IP address, so we just find one of [0] [1]
        # in the range, we decide the packet is normal
        if 1 == in_ip_range(public_ip_range_line, b_infect_packet[0]) or \
                        1 == in_ip_range(public_ip_range_line, b_infect_packet[1]):
            flag_public_range = 1
            break
        else:
            flag_public_range = 0
    if 1 == flag_public_range:
        # the infect packet ip in the public ip range
        return 1
    else:
        # 直接用正则表达式 将b_infect_packet 拼接成一个字符串, 在 str_normal_db 进行匹配.
        infect_ip_source_str = str(long(b_infect_packet[0]))
        infect_ip_des_str = str(long(b_infect_packet[1]))
        # infect_ip_source_str_array = infect_ip_source_str.split('.')
        # infect_ip_des_str_array = infect_ip_des_str.split('.')
        str_pattern = ".*" + infect_ip_source_str + " " + infect_ip_des_str
        pattern = re.compile(str_pattern)
        match = pattern.match(str_normal_db)
        if match:
            return 1
        else:
            return 0

####################################################
# FUNCTION: Load Configuration
# RETURN: InputNormalDir
# InputInfectDir
# OutputCSVDir
# ReportDir
# NormalDBDir
####################################################

def load_conf():
    # 主要是获取
    global output_csv_dir
    global report_dir
    global normal_db_dir
    global input_normal_dir
    global input_infect_dir
    # from __future__ import with_statement
    # DataProcess.cfg
    import ConfigParser

    config = ConfigParser.ConfigParser()
    # G:\2015-11-01-Research-experiment\0_MobileBotnetAnalysisLab\TrafficDataProcessAuto_pc.cfg
    with open(path + "\TrafficDataProcessAuto_pc.cfg", "r") as cfgfile:
        # with open(path+"\DataProcess.cfg", "r") as cfgfile:
        config.readfp(cfgfile)
        input_dir = config.get("DIR", "InputDir")
        normal_dir = config.get("DIR", "NormalDir")
        infect_dir = config.get("DIR", "InfectDir")

        output_csv_dir = os.path.normcase(config.get("DIR", "OutputDir"))
        report_dir = os.path.normcase(config.get("DIR", "ReportDir"))
        normal_db_dir = os.path.normcase(config.get("DIR", "NormalDB"))

    input_normal_dir = os.path.normcase(input_dir + normal_dir)
    input_infect_dir = os.path.normcase(input_dir + infect_dir)

    # return (InputNormalDir,InputInfectDir,OutputCSVDir,ReportDir,NormalDBDir)

####################################################
# FUNCTION: Scan the Input Data directory
####################################################

def scan_input_data():
    global num_normal_input_file
    global num_infect_input_file
    global normal_input_file_list
    global infect_input_file_list
    # Load Configuration File to get parameters
    load_conf()
    # List the normal and infect files
    logger.info(input_normal_dir)
    logger.info(input_infect_dir)

    normal_input_file_list = os.listdir(input_normal_dir)
    infect_input_file_list = os.listdir(input_infect_dir)
    num_normal_input_file = len(normal_input_file_list)
    num_infect_input_file = len(infect_input_file_list)

    logger.info(num_infect_input_file)
    logger.info(num_normal_input_file)
    # Show the result of scanning
    show_scan_result(1)

####################################################
# FUNCTION1: Show Scanning Result
# Input:     The level of show 0-Infect 1-Normal 2-Normal&Infect
####################################################

def show_scan_result(level=2):
    print("--------------------Scanning Result--------------------")
    if level > 0:
        print("The number of Normal file:" + str(num_normal_input_file))
        print("Files:")
        for i in range(0, num_normal_input_file):
            print("Input " + str(i + 1) + " to process: " + normal_input_file_list[i])
    if level < 1 or level > 1:
        print("The number of Infect file:" + str(num_infect_input_file))
        print("Files:")
        for i in range(0, num_infect_input_file):
            print("Input " + str(i + 1) + " to process: " + infect_input_file_list[i])
    print("--------------------Scanning End--------------------")

####################################################
# FUNCTION: ip2int
# INPUT:    IP
# RETURN:   int of the IP
####################################################

def ip2int(ip):
    import struct
    import socket

    return struct.unpack("!I", socket.inet_aton(ip))[0]

####################################################
# FUNCTION: int2ip
# INPUT:    int of IP
# RETURN:   IP
####################################################

def int2ip(i):
    import socket
    import struct

    return socket.inet_ntoa(struct.pack("!I", i))

####################################################
########## FUNCTION: change the IP/subset to IP range
########## Input: "216.239.32.0/19"
########## Return: IP range IP cmin cmax  216.239.32.0 216.239.63.255
####################################################
def subnet_mask_to_ip_range(iplist):
    data = iplist.split('/')
    ip = data[0]
    ti = int(data[1])
    d = int(ti / 8)
    c = 256 / (2 ** (ti % 8))
    ip_items = ip.split('.')
    if len(ip_items[d:]) == 1:
        if ti % 8 == 0:
            cmin = '%s.%s' % ('.'.join(ip_items[:d]), '0')
            cmax = '%s.%s' % ('.'.join(ip_items[:d]), '255')
        else:
            for i in range(2 ** (ti % 8)):
                mymax = (i + 1) * c - 1
                mymin = i * c
                data = int(''.join(ip_items[d:]))
                if data < mymax and data >= mymin:
                    cmin = '%s.%s' % ('.'.join(ip_items[:d]), mymin)
                    cmax = '%s.%s' % ('.'.join(ip_items[:d]), mymax)
    else:
        if ti % 8 == 0:
            cmin = '%s.%s.%s' % ('.'.join(ip_items[:d]), '0', ('0.' * (len(ip_items) - d - 1))[:-1])
            cmax = '%s.%s.%s' % ('.'.join(ip_items[:d]), '255', ('255.' * (len(ip_items) - d - 1))[:-1])
        else:
            for i in range(2 ** (ti % 8)):
                mymax = (i + 1) * c - 1
                mymin = i * c
                data = int(''.join(ip_items[d]))
                if data < mymax and data >= mymin:
                    cmin = '%s.%s.%s' % ('.'.join(ip_items[:d]), mymin, ('0.' * (len(ip_items) - d - 1))[:-1])
                    cmax = '%s.%s.%s' % ('.'.join(ip_items[:d]), mymax, ('255.' * (len(ip_items) - d - 1))[:-1])
    # print  cmin, cmax
    return (cmin, cmax)

####################################################
########## FUNCTION: decision for whether the IP in a IP range
########## Input: IP range string "216.239.32.0/19" (string) , IP (int) to decide
########## Return: 1 in the range
##########         0 not in the range
####################################################
def in_ip_range(subnet_mask_ip, ip):
    ip_range_lower, ip_range_upper = subnet_mask_to_ip_range(subnet_mask_ip)
    int_ip_lower = ip2int(ip_range_lower)
    int_ip_upper = ip2int(ip_range_upper)
    # print(int_ip_lower)
    # print(int_ip_upper)
    # print(ip)
    # print(ip_range_lower)
    # print(ip_range_upper)
    # print(int2ip(ip))
    if int_ip_upper >= ip >= int_ip_lower:
        return 1
    else:
        return 0

####################################################
# FUNCTION: compare between normal packet with the normal database
# Input: a: packet from traffic b: packet from normal database
####################################################

def compare(a, b):
    if long(a[0]) == long(b[0]) and long(a[1]) == long(b[1]) and long(a[2]) == long(b[2]):
        return 1
    else:
        return 0

####################################################
# FUNCTION: compare packet in infect traffic file with the packet in normal database,
# find whether the packet is normal or infect
# Input: a: packet from infect traffic file b: packet from normal database
# Return: 1 normal packet match with the packet in database
# 0 infect packet not match the database
####################################################

def decision_normal_infect(a_normal_packet, b_infect_packet):
    # 0 source IP
    # 1 destination IP
    # we use the fuzzy matching to decide whether the packet in the database or not
    # example:  192.168.123.***
    # Step1: compare with google public IP address
    # Step2: wildcard of the last 3 number of the IP address

    # Step 1
    # Load the public IP range address from database dir : public_ip_range.txt
    flag_public_range = 0
    with open(normal_db_dir + public_ip_range_file, 'a+') as public_ip_range:
        for public_ip_range_line in public_ip_range:
            # compare the b_infect_packet ip source or ip destination with the IP range whether in the range
            # Because there is one of the two IP is the mobile IP address, so we just find one of [0] [1]
            # in the range, we decide the packet is normal
            if 1 == in_ip_range(public_ip_range_line, b_infect_packet[0]) or \
                            1 == in_ip_range(public_ip_range_line, b_infect_packet[1]):
                flag_public_range = 1
                break
            else:
                flag_public_range = 0
    if 1 == flag_public_range:
        # the infect packet ip in the public ip range
        return 1
    else:
        # Step 2
        # compare the ip and protocol with the normal database packet, we use fuzzy matching,
        infect_ip_source_str = int2ip(b_infect_packet[0])
        infect_ip_des_str = int2ip(b_infect_packet[1])
        normal_ip_source_str = int2ip(int(a_normal_packet[0]))
        normal_ip_des_str = int2ip(int(a_normal_packet[1]))
        infect_ip_source_str_array = infect_ip_source_str.split('.')
        infect_ip_des_str_array = infect_ip_des_str.split('.')
        normal_ip_source_str_array = normal_ip_source_str.split('.')
        normal_ip_des_str_array = normal_ip_des_str.split('.')

        # logger.debug(infect_ip_source_str)
        # logger.debug(infect_ip_des_str)
        # logger.debug(normal_ip_source_str)
        # logger.debug(normal_ip_des_str)
        #
        #
        # logger.debug(infect_ip_source_str_array)
        # logger.debug(infect_ip_des_str_array)
        # logger.debug(normal_ip_source_str_array)
        # logger.debug(normal_ip_des_str_array)
        # set the level of fuzzy
        # level = 3    xxx.xxx.xxx only match the first 3 ip number
        level = 3
        index = 0
        match_flag = 1
        while index < level:
            if infect_ip_source_str_array[index] == normal_ip_source_str_array[index] and \
                            infect_ip_des_str_array[index] == normal_ip_des_str_array[index]:
                index += 1
            else:
                match_flag = 0
                break
        if match_flag == 1:
            return 1
        else:
            return 0

####################################################
# FUNCTION: Process Normal File
# Input: The number of the files in the normal list
####################################################

def normal_process(normal_file_no):
    global normal_db_size
    # Stream: initial 2 dimensions array to store the packet base on the stream index

    tcp_stream = [[[0 for col in range(0)] for row in range(0)] for high in range(50000)]
    udp_stream = [[[0 for col in range(0)] for row in range(0)] for high in range(20000)]
    num_udp_stream = 0
    num_tcp_stream = 0

    # 获取当前需要处理的文件
    process_normal_file = input_normal_dir + normal_input_file_list[normal_file_no - 1]
    print (process_normal_file)
    # Load Normal Packet database, if the file not exist, create it. And append the file every process
    # normal_db = open(normal_db_dir + normal_db_file, 'a+')
    normal_db_temp = [[0 for col in range(10)] for row in range(0)]
    with open(normal_db_dir + normal_db_file, 'a+') as normal_db:
        for normal_db_line in normal_db:
            # normal_db_array = normal_db_line.split()
            normal_db_line_array = normal_db_line.split()
            normal_db_temp += [normal_db_line_array]
            normal_db_size += 1
    # Open normal csv file and initial the head of the table
    # print (output_csv_dir + normal_input_file_list[normal_file_no - 1] + output_extension)
    # 增加三个属性
    with open(output_csv_dir + normal_input_file_list[normal_file_no - 1] + output_extension, 'wSb+') as csv_file:
        csv_writer = csv.writer(csv_file, dialect='excel')
        csv_writer.writerow(
            ['IP source', 'IP des', 'Protocol', 'Frame duration', 'UDP size', 'TCP size', 'Argument Count', 'TimeStamp',
             'T1', 'T2', 'T3', 'Lable'])

    # Stream: The output file will store the stream information
    # process every line in the normal file
    # -e ip.src -e ip.dst -e ip.proto
    # -e frame.time_delta
    # -e udp.length -e udp.stream
    # -e tcp.len -e tcp.stream
    # -e http.request.uri
    # The structure of every line: 9 if
    # IP source 0 , IP destination 1, IP protocol 2,
    # Frame duration 3,
    # UDP size 4, UDP stream index 5,
    # TCP size 6, TCP stream index 7,
    # URL 8
    # tshark -r %%f -o tcp.calculate_timestamps:true -n -T fields -e ip.src -e ip.dst -e ip.proto -e frame.time_delta
    # -e udp.length -e udp.stream -e tcp.len -e tcp.stream -e http.request.uri -e frame.time_epoch >%%f%outputFormat%
    # UPD  7
    # |--ip.src--|--ip.dst--|--ip.proto--|--frame.time_delta--|--udp.length--|--udp.stream--|--frame.time_epoch--|
    # TCP  8
    # |--ip.src--|--ip.dst--|--ip.proto--|--frame.time_delta--|--tcp.len--|--tcp.stream--|--http.request.uri--|--frame.time_epoch--|
    for txt_line in open(process_normal_file):
        txt_array = txt_line.split()
        # 重新构造txt_array
        # 如果长度小于7，直接过滤掉
        if 7 > len(txt_array):
            continue
        # 首先处理第1，2字段，ip源地址
        if len(txt_array[0]) <= 15:
            # IP地址长度大于255.255.255.255,则为IPv6
            ip_source = ip2int(txt_array[0])
            txt_array[0] = ip_source
            ip_des = ip2int(txt_array[1])
            txt_array[1] = ip_des

            # 6 UPD 将6,7,8字段配置为0
            # 17 TCP 将4,5字段配置0
            if txt_array[2] != '17':
                # TCP 6 UDP 17
                # if not UDP, SET udp size AS 0
                txt_array.insert(4, '0')
                txt_array.insert(5, '0')
            if txt_array[2] != '6':
                txt_array.insert(6, '0')
                txt_array.insert(7, '0')
                txt_array.insert(8, '0')
            else:
                # 如果是TCP并且包含有HTTP URI的话，字段为10，则计算参数个数
                if len(txt_array) == 10:
                    # include the HTTP request uri
                    arg_num = txt_array.pop(8).count('=')
                    txt_array.insert(8, str(arg_num))
                else:
                    arg_num = 0
                    txt_array.insert(8, str(arg_num))
            # 9 --> timestamp
            # txt_array.insert(9, 'normal')
            # 时间戳保留在字段9
            # 这里将lable插入到最后一个位置，这个位置不确定，有可能有带*的行，则多一个元素，所以这里，
            # txt_array.insert(10, 'normal')
            txt_array.append('normal')
            # Decided whether the packet has already existed in the normal_db
            status = 0
            # 遍历临时的db列表，比较该package的IP信息是否存在
            for i in normal_db_temp:
                if 1 == compare(i, txt_array):
                    status = 1
                    break
            # 如果不存在，则加入到 normal db中
            if 0 == status:
                normal_db_temp += [txt_array]
                normal_db_size += 1
                # append the data into to database file
                with open(normal_db_dir + normal_db_file, 'a+') as normal_db:
                    # normal_db_array = normal_db_line.split()
                    n = 0
                    s = ""
                    while n < len(txt_array):
                        s += str(txt_array[n])
                        s += " "
                        n += 1
                    s += "\n"
                    # txt_array_convert = ' '.join(str(txt_array))
                    normal_db.writelines(s)

            # 将该txt_array加入到 Stream中,最后将Stream写入CSV文件
            if '17' == txt_array[2]:
                # UDP process
                udp_stream[int(txt_array[5])].append(txt_array)

            elif '6' == txt_array[2]:
                # TCP process
                # logger.info("index of the stream:")
                # logger.info(txt_array[7])
                tcp_stream[int(txt_array[7])].append(txt_array)

    # 这是已经获得了当前文件的所有的 package，并且根据每个 package 的stream index 信息，将package存放到对应的stream二维数组中了。
    # 下面组合stream
    # 记录之前的Stream开始和结束时间。
    pre_start_timestamp = 0
    pre_end_timestamp = 0
    cur_start_timestamp = 0
    cur_end_timestamp = 0
    for packet_list in udp_stream:
        # 组合udp_stream中的每个stream的packet,将信息存储在CSV文件中.
        if len(packet_list) != 0:
            # 8['IP source', 'IP des', 'Protocol', 'Frame duration', 'UDP size', 'TCP size', 'Argument Count', 'Lable'])
            # 现在开始拼接udp_stream里面的每个packet_list到一个stream
            stream_temp = [0 for col in range(12)]
            stream_temp[0] = packet_list[0][0]
            stream_temp[1] = packet_list[0][1]
            stream_temp[2] = packet_list[0][2]
            for packet in packet_list:
                stream_temp[3] += float(packet[3])
                stream_temp[4] += int(packet[4])
                # 如果packet[9]为 *， 则取下一个做时间戳字段
                if packet[9] == "*":
                    logger.info("Encounter some line with *")
                    packet.pop(9)
                # 将stream中package的最早时间戳和最晚时间戳记录下来。
                if cur_start_timestamp == 0 and cur_end_timestamp == 0:
                    cur_start_timestamp = float(packet[9])
                    cur_end_timestamp = float(packet[9])
                if float(packet[9]) < cur_start_timestamp:
                    cur_start_timestamp = float(packet[9])
                if float(packet[9]) > cur_end_timestamp:
                    cur_end_timestamp = float(packet[9])

            stream_temp[5] = 0
            stream_temp[6] = 0
            # 将第一个package的时间戳，作为本stream的时间戳
            stream_temp[7] = packet_list[0][9]

            # 这里我们需要处理一下时间戳，加入时间戳属性。
            # 这里我们需要加入三个feature
            # 2. The experiment for the more features (time) of stream with ML
            # more features:
            # a) |Ts - Te| time between start and end of every stream
            # b) |Ts2 - Ts1| time between start time of adjacent stream
            # c) |Te1 - Ts2| time between end and start time of adjacent stream
            stream_temp[8] = abs(cur_end_timestamp - cur_start_timestamp)
            stream_temp[9] = abs(cur_start_timestamp - pre_start_timestamp)
            stream_temp[10] = abs(cur_start_timestamp - pre_end_timestamp)

            # 将第一个的label，作为本stream的label
            stream_temp[11] = packet_list[0][10]
            pre_start_timestamp = cur_start_timestamp
            pre_end_timestamp = cur_end_timestamp
            cur_start_timestamp = 0
            cur_end_timestamp = 0
            # Write the CSV file for the normal files.
            with open(output_csv_dir + normal_input_file_list[normal_file_no - 1] + output_extension, 'ab+') \
                    as csv_file:
                csv_writer = csv.writer(csv_file, dialect='excel')
                csv_writer.writerow(stream_temp)
            num_udp_stream += 1
    pre_start_timestamp = 0
    pre_end_timestamp = 0
    cur_start_timestamp = 0
    cur_end_timestamp = 0
    for packet_list in tcp_stream:
        # 组合udp_stream中的每个stream的packet,将信息存储在CSV文件中.
        if len(packet_list) != 0:
            # 8['IP source', 'IP des', 'Protocol', 'Frame duration', 'UDP size', 'TCP size', 'Argument Count', 'Lable'])
            stream_temp = [0 for col in range(12)]
            stream_temp[0] = packet_list[0][0]
            stream_temp[1] = packet_list[0][1]
            stream_temp[2] = packet_list[0][2]
            for packet in packet_list:
                stream_temp[3] += float(packet[3])
                stream_temp[5] += int(packet[6])
                stream_temp[6] += int(packet[8])
                # 将stream中package的最早时间戳和最晚时间戳记录下来。
                if cur_start_timestamp == 0 and cur_end_timestamp == 0:
                    cur_start_timestamp = float(packet[9])
                    cur_end_timestamp = float(packet[9])
                if float(packet[9]) < cur_start_timestamp:
                    cur_start_timestamp = float(packet[9])
                if float(packet[9]) > cur_end_timestamp:
                    cur_end_timestamp = float(packet[9])
            stream_temp[4] = 0
            stream_temp[7] = packet_list[0][9]
            # 这里我们需要处理一下时间戳，加入时间戳属性。
            # 这里我们需要加入三个feature
            # 2. The experiment for the more features (time) of stream with ML
            # more features:
            # a) |Ts - Te| time between start and end of every stream
            # b) |Ts2 - Ts1| time between start time of adjacent stream
            # c) |Te1 - Ts2| time between end and start time of adjacent stream
            stream_temp[8] = abs(cur_end_timestamp - cur_start_timestamp)
            stream_temp[9] = abs(cur_start_timestamp - pre_start_timestamp)
            stream_temp[10] = abs(cur_start_timestamp - pre_end_timestamp)
            # 将第一个的label，作为本stream的label
            stream_temp[11] = packet_list[0][10]
            pre_start_timestamp = cur_start_timestamp
            pre_end_timestamp = cur_end_timestamp
            cur_start_timestamp = 0
            cur_end_timestamp = 0
            # Write the CSV file for the normal files.
            with open(output_csv_dir + normal_input_file_list[normal_file_no - 1] + output_extension, 'ab+') \
                    as csv_file:
                csv_writer = csv.writer(csv_file, dialect='excel')
                csv_writer.writerow(stream_temp)
            num_tcp_stream += 1

####################################################
# FUNCTION: Process Normal File
# Input: The number of the files in the normal list
####################################################

def infect_process(infect_file_no):
    global num_packet_label_infect
    global num_packet_label_normal
    logger.info("Start to process the infect file")
    tcp_stream = [[[0 for col in range(0)] for row in range(0)] for high in range(50000)]
    udp_stream = [[[0 for col in range(0)] for row in range(0)] for high in range(20000)]
    num_udp_stream = 0
    num_tcp_stream = 0

    process_infect_file = input_infect_dir + infect_input_file_list[infect_file_no - 1]
    print (process_infect_file)
    # Load Normal Packet database, if the file not exist, create it. And append the file every process
    # normal_db = open(normal_db_dir + normal_db_file, 'a+')
    public_ip_range_temp = []
    with open(normal_db_dir + public_ip_range_file, 'a+') as public_ip_range:
        for public_ip_range_line in public_ip_range:
            public_ip_range_temp += [public_ip_range_line]

    str_normal_db = ""
    normal_db_temp = [[0 for col in range(10)] for row in range(0)]
    with open(normal_db_dir + normal_db_file, 'a+') as normal_db:
        for normal_db_line in normal_db:
            # normal_db_array = normal_db_line.split()
            normal_db_line_array = normal_db_line.split()
            normal_db_temp += [normal_db_line_array]
            str_normal_db += " "
            normal_db_line = normal_db_line.strip('\n')
            str_normal_db += normal_db_line
    # Open normal csv file and initial the head of the table
    # print (output_csv_dir + normal_input_file_list[normal_file_no - 1] + output_extension)
    with open(output_csv_dir + infect_input_file_list[infect_file_no - 1] + output_extension, 'wSb+') as csv_file:
        csv_writer = csv.writer(csv_file, dialect='excel')
        csv_writer.writerow(
            ['IP source', 'IP des', 'Protocol', 'Frame duration', 'UDP size', 'TCP size', 'Argument Count', 'TimeStamp',
             'T1', 'T2', 'T3', 'Lable'])
    # process every line in the normal
    num_txt_line = 0
    for txt_line in open(process_infect_file):
        logger.info("Process the txt line: " + str(num_txt_line))
        num_txt_line += 1
        txt_array = txt_line.split()
        if 7 > len(txt_array):
            continue
        if len(txt_array[0]) <= 15:
            # IP地址长度大于255.255.255.255,则为IPv6
            IP_source = ip2int(txt_array[0])
            txt_array[0] = IP_source
            IP_des = ip2int(txt_array[1])
            txt_array[1] = IP_des

            if txt_array[2] != '17':
                # TCP 6 UDP 17
                # if not UDP, SET udp size AS 0
                txt_array.insert(4, '0')
                txt_array.insert(5, '0')
            if txt_array[2] != '6':
                txt_array.insert(6, '0')
                txt_array.insert(7, '0')
                txt_array.insert(8, '0')
            else:
                if len(txt_array) == 10:
                    # include the HTTP request uri
                    arg_num = txt_array.pop(8).count('=')
                    txt_array.insert(8, str(arg_num))
                else:
                    arg_num = 0
                    txt_array.insert(8, str(arg_num))

            # Decisied whether the packet is Normal or Infect
            # We use some algorithms to compare with the normal database, and
            # status = 1 : normal packet match the database
            # status = 0 : infect packet not match the database
            # 将这块匹配工作进行重新设计, 使用正则表达式进行匹配, 加快速度.
            status = 0
            # 判断当前txt_array是否为infect:
            status = match_normal_db(txt_array, public_ip_range_temp, str_normal_db)
            if status:
                txt_array.append('normal')
                num_packet_label_normal += 1
            else:
                txt_array.append('infect')
                num_packet_label_infect += 1
            # for i in normal_db_temp:
            #     if 1 == decision_normal_infect(i, txt_array):
            #         status = 1
            #         txt_array.append('normal')
            #         # txt_array.insert(10, 'normal')
            #         num_packet_label_normal += 1
            #         break
            # if 0 == status:
            #     txt_array.append('infect')
            #     # txt_array.insert(10, 'infect')
            #     num_packet_label_infect += 1

            # 将该txt_array加入到 Stream中,最后将Stream写入CSV文件
            if '17' == txt_array[2]:
                # UDP process
                udp_stream[int(txt_array[5])].append(txt_array)
                # print(int(txt_array[5]))
            elif '6' == txt_array[2]:
                # TCP process
                tcp_stream[int(txt_array[7])].append(txt_array)
                # print(int(txt_array[7]))
    logger.info("Start to write the csv file")

    pre_start_timestamp = 0
    pre_end_timestamp = 0
    cur_start_timestamp = 0
    cur_end_timestamp = 0

    for packet_list in udp_stream:
        # 组合udp_stream中的每个stream的packet,将信息存储在CSV文件中.
        if len(packet_list) != 0:
            # 8 ['IP source', 'IP des', 'Protocol', 'Frame duration', 'UDP size', 'TCP size', 'Argument Count', 'Lable'])
            stream_temp = [0 for col in range(12)]
            stream_temp[0] = packet_list[0][0]
            stream_temp[1] = packet_list[0][1]
            stream_temp[2] = packet_list[0][2]
            for packet in packet_list:
                stream_temp[3] += float(packet[3])
                stream_temp[4] += int(packet[4])
                # 如果packet[9]为 *， 则取下一个做时间戳字段
                if packet[9] == "*":
                    logger.info("Encounter some line with *")
                    packet.pop(9)
                # 将stream中package的最早时间戳和最晚时间戳记录下来。
                # 如果packet[9]为 *， 则取下一个做时间戳字段
                if packet[9] == "*":
                    logger.info("Encounter some line with *")
                    packet.pop(9)
                if cur_start_timestamp == 0 and cur_end_timestamp == 0:
                    cur_start_timestamp = float(packet[9])
                    cur_end_timestamp = float(packet[9])
                if float(packet[9]) < cur_start_timestamp:
                    cur_start_timestamp = float(packet[9])
                if float(packet[9]) > cur_end_timestamp:
                    cur_end_timestamp = float(packet[9])
            stream_temp[5] = 0
            stream_temp[6] = 0
            stream_temp[7] = packet_list[0][9]
            # 这里我们需要处理一下时间戳，加入时间戳属性。
            # 这里我们需要加入三个feature
            # 2. The experiment for the more features (time) of stream with ML
            # more features:
            # a) |Ts - Te| time between start and end of every stream
            # b) |Ts2 - Ts1| time between start time of adjacent stream
            # c) |Te1 - Ts2| time between end and start time of adjacent stream
            stream_temp[8] = abs(cur_end_timestamp - cur_start_timestamp)
            stream_temp[9] = abs(cur_start_timestamp - pre_start_timestamp)
            stream_temp[10] = abs(cur_start_timestamp - pre_end_timestamp)
            # 将第一个的label，作为本stream的label
            stream_temp[11] = packet_list[0][10]
            pre_start_timestamp = cur_start_timestamp
            pre_end_timestamp = cur_end_timestamp
            cur_start_timestamp = 0
            cur_end_timestamp = 0
            # Write the CSV file for the normal files.
            with open(output_csv_dir + infect_input_file_list[infect_file_no - 1] + output_extension, 'ab+') \
                    as csv_file:
                csv_writer = csv.writer(csv_file, dialect='excel')
                csv_writer.writerow(stream_temp)

            num_udp_stream += 1
    logger.info("Finish UDP CSV write, the sum of stream: " + str(num_udp_stream))
    pre_start_timestamp = 0
    pre_end_timestamp = 0
    cur_start_timestamp = 0
    cur_end_timestamp = 0
    for packet_list in tcp_stream:
        # 组合udp_stream中的每个stream的packet,将信息存储在CSV文件中.
        if len(packet_list) != 0:
            # 8 ['IP source', 'IP des', 'Protocol', 'Frame duration', 'UDP size', 'TCP size', 'Argument Count', 'Lable'])
            stream_temp = [0 for col in range(12)]
            stream_temp[0] = packet_list[0][0]
            stream_temp[1] = packet_list[0][1]
            stream_temp[2] = packet_list[0][2]
            for packet in packet_list:
                stream_temp[3] += float(packet[3])
                stream_temp[5] += int(packet[6])
                stream_temp[6] += int(packet[8])
                # 将stream中package的最早时间戳和最晚时间戳记录下来。
                if cur_start_timestamp == 0 and cur_end_timestamp == 0:
                    cur_start_timestamp = float(packet[9])
                    cur_end_timestamp = float(packet[9])
                if float(packet[9]) < cur_start_timestamp:
                    cur_start_timestamp = float(packet[9])
                if float(packet[9]) > cur_end_timestamp:
                    cur_end_timestamp = float(packet[9])
            stream_temp[4] = 0
            stream_temp[7] = packet_list[0][9]
            # 这里我们需要处理一下时间戳，加入时间戳属性。
            # 这里我们需要加入三个feature
            # 2. The experiment for the more features (time) of stream with ML
            # more features:
            # a) |Ts - Te| time between start and end of every stream
            # b) |Ts2 - Ts1| time between start time of adjacent stream
            # c) |Te1 - Ts2| time between end and start time of adjacent stream
            stream_temp[8] = abs(cur_end_timestamp - cur_start_timestamp)
            stream_temp[9] = abs(cur_start_timestamp - pre_start_timestamp)
            stream_temp[10] = abs(cur_start_timestamp - pre_end_timestamp)

            # 将第一个的label，作为本stream的label
            stream_temp[11] = packet_list[0][10]
            pre_start_timestamp = cur_start_timestamp
            pre_end_timestamp = cur_end_timestamp
            cur_start_timestamp = 0
            cur_end_timestamp = 0
            # Write the CSV file for the normal files.
            with open(output_csv_dir + infect_input_file_list[infect_file_no - 1] + output_extension, 'ab+') \
                    as csv_file:
                csv_writer = csv.writer(csv_file, dialect='excel')
                csv_writer.writerow(stream_temp)
            num_tcp_stream += 1
    logger.info("Finish TCP CSV write, the sum of stream: " + str(num_tcp_stream))

########
#
# Main Process
#
#######

####################################################
# Logger Configuration
####################################################
# 创建一个logger
logger = logging.getLogger('mainlogger')
logger.setLevel(logging.DEBUG)

# 创建一个handler，用于写入日志文件
fh = logging.FileHandler(path + '/mainlog.log')
fh.setLevel(logging.DEBUG)

# 再创建一个handler，用于输出到控制台
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)

# 定义handler的输出格式
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
fh.setFormatter(formatter)
ch.setFormatter(formatter)

# 给logger添加handler
logger.addHandler(fh)
logger.addHandler(ch)

# 记录一条日志
logger.info('Test mainlog')
# Set Level of the logger,
# NOTSET < DEBUG < INFO < WARNING < ERROR < CRITICAL
# logger.setLevel(logging.WARNING)    #Show Debug Information
# logger.setLevel(logging.INFO)    #Show Debug Information
logger.setLevel(logging.DEBUG)
# logger.setLevel(logging.NOTSET)  #Not show Any Information

# 加载参数
load_conf()
# 处理 normal 目录下文件，生成csv文件并创建 normal db
scan_input_data()
i = 1
for i in range(1, num_normal_input_file + 1):
    logger.info("The current process for normal:")
    logger.info(i)
    normal_process(i)
i = 1
for i in range(1, num_infect_input_file + 1):
    logger.info("The current process for infect:")
    logger.info(i)
    infect_process(i)
# 处理 malware 目录下文件，生成csv文件


from django.shortcuts import render, redirect
from .forms import ContatoForm, ProdutoModelForm, ClienteModelForm
from django.contrib import messages

from .models import Cliente, Produto

# Create your views here.

def index(request):
    prod = Produto.objects.all()

    context ={
        'prod': prod
    }
    return render(request, 'index.html', context)

def contato(request):
    form = ContatoForm(request.POST or None)

    if(str(request.method) == 'POST'):
        if form.is_valid():
            form.send_email()

            messages.success(request, 'Email enviado com sucesso')
            form = ContatoForm

        else:
            messages.error(request, 'Falha ao enviar email')

    context = {
        'form': form
    }

    return render(request, 'contato.html', context)

def produto(request):
    print(dir(request))
    print(dir(request.user))
    print(request.user.is_authenticated)

    if (request.user.is_authenticated == True):
        if str(request.method) == 'POST':
            form = ProdutoModelForm(request.POST, request.FILES)
            if form.is_valid():
                form.save()
                messages.success(request,'Produto salvo com sucesso')
            else:
                messages.error(request, 'Erro ao salvar produto')
            form = ProdutoModelForm()
        else:
            form = ProdutoModelForm()

        context = {
            'form': form
        }
        return render(request, 'produto.html', context)

    else:
        return redirect(index)

def cliente(request):
    if str(request.method) == 'POST':
        form = ClienteModelForm(request.POST)
        if form.is_valid():
            form.save()
            messages.success(request,'Cliente cadastrado com sucesso')
        else:
            messages.error(request,'Não foi possível cadastrar o cliente')
        form = ClienteModelForm()
    else:
        form = ClienteModelForm()

    context = {
        'form': form
    }
    return render(request, 'clientes.html', context)

def mostra_cliente(request):
    clientes = Cliente.objects.all()

    context ={
        'clientes': clientes
    }
    return render(request,'mostra_cliente.html', context)


#!/usr/bin/python3
from fdactuator import FdActuator
from fddevice import FdDevice

class LsSv004ig5a_1(FdActuator):
  def __init__(self, connInfo):
    self.mqttTopic = 'speed'
    self.on = False
    super().__init__(connInfo)

  def writeFreq(self, slaveId, value):  # 주파수 설정
    act = {'atype': 'modbus', 'slaveid': slaveId,
           'func': 6, 'offset': 0x0005-1, 'value': value}
    return act

  def readFreq(self, slaveId):  # 설정된 주파수 확인
    act = {'atype': 'modbus', 'func': 3, 'slaveid': slaveId,
           'offset': 0x0005-1, 'length': 1}
    return act

  def motorOn(self, slaveId, reverse=False):
    val = 2
    if reverse == True:
      val = 4
    act = {'atype': 'modbus', 'slaveid': slaveId,
           'func': 6, 'offset': 0x0006-1, 'value': val}
    return act

  def motorOff(self, slaveId):
    act = {'atype': 'modbus', 'slaveid': slaveId,
           'func': 6, 'offset': 0x0006-1, 'value': 1}
    return act

  def readStatus(self, slaveId):  # On/Off 상태 확인
    act = {'atype': 'modbus', 'func': 3, 'slaveid': slaveId,
           'offset': 0x0006-1, 'length': 1}
    return act


import random
import subprocess as sub
import time

samples = 100
u = 10 ** 9
n = 100

while n <= 1000000:
    stabil = 0
    totalTime = 0
    for i in range(0, samples):
        houses = random.sample(range(0, u), n)
        houses.sort()

        start = time.time()

        p = sub.Popen("./g", stdin=sub.PIPE, stdout=sub.PIPE)
        p.stdin.write((str(u) + " " + str(n) + "\n").encode())
        p.stdin.write(b" ".join([str(h).encode() for h in houses]) + b"\n")
        p.stdin.flush()

        ans = p.stdout.readline().decode("UTF-8").strip()

        end = time.time()
        totalTime += end - start

        if(not ans.startswith("Es wurde keine")):
            stabil += 1
        p.kill()

    print("n=%d"%n)
    print("Stabile Verteilungen:", stabil)
    print("Durchschnittliche Zeit: ", totalTime / samples)
    n *= 10


from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.common.exceptions import TimeoutException

from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
from selenium.webdriver.support.ui import WebDriverWait
import time

def no_delay_output():
    """
    非延迟输出,正常会等页面加载完毕后才进行输出,
    此种方式在加载界面的时候, 会输出
    :return:
    """
    # 修改页面加载策略
    desired_capabilities = DesiredCapabilities.CHROME
    # 注释这两行会导致最后输出结果的延迟, 即等待页面加载完成再输出
    desired_capabilities["pageLoadStrategy"] = "none"

    driver = webdriver.Chrome()

    # 后面可以使用wait对特定元素进行等待
    wait = WebDriverWait(driver, 3)

    driver.get('http://www.dianping.com/shop/98394949')

    time.sleep(2)
    print(driver.get_cookies())
    print("end")

    driver.close()

def no_delay_cookies(url):
    """
    非延迟获取cookies
    :return:
    """
    # 修改页面加载策略
    desired_capabilities = DesiredCapabilities.CHROME
    # 注释这两行会导致最后输出结果的延迟, 即等待页面加载完成再输出
    desired_capabilities["pageLoadStrategy"] = "none"

    # 静默模式
    option = webdriver.ChromeOptions()
    option.add_argument('headless')
    option.add_experimental_option('excludeSwitches', ['enable-automation'])
    # 启动浏览器
    driver = webdriver.Chrome(options=option)
    # driver = webdriver.Chrome()
    driver.delete_all_cookies()
    # 后面可以使用wait对特定元素进行等待
    wait = WebDriverWait(driver, 1)

    # driver.get('http://www.dianping.com/shop/98394949')
    driver.get(url)

    time.sleep(1)
    cookies_list = driver.get_cookies()

    cookie_dict = dict()
    for res in cookies_list:
        key = res.get("name")
        value = res.get("value")
        cookie_dict[key] = value

    print("9991111", cookie_dict)

    if cookie_dict is not None:
        lxsdk_s = cookie_dict.get("_lxsdk_s")
        if lxsdk_s is not None:
            increase_int = lxsdk_s[(int(lxsdk_s.rindex('C')) + 1):]

            with open('incre_cookid_detail', 'w') as f:
                f.write(str(increase_int))
    else:
        with open('incre_cookid_detail', 'w') as f:
            f.write(5)

    # driver.close()
    return cookie_dict

def test(url):
    driver1 = webdriver.Chrome()
    # driver.delete_all_cookies()

    driver1.get(url)

    # cookies_list = driver1.get_cookies()
    #
    # print(cookies_list)

    # driver1.close()

if __name__ == '__main__':
    ss = no_delay_cookies("http://www.dianping.com/shop/98394949")
    print(ss)

    # auto_search()

    # test("http://www.dianping.com/shop/2767525")
    # test("http://www.baidu.com")


import json
from glob import glob
from pathlib import Path
from typing import Any, Dict, List, Optional, Sequence, Union

import numpy as np
import torch
import yaml
from PIL import Image
from sklearn.model_selection import train_test_split
from termcolor import colored
from torch.utils.data import Dataset
from torchvision.transforms import ToTensor
from tqdm import tqdm

from ..metrics import ComputeMetrics
from .utils import Augmentator

def red_bold(x):
    return colored(f"{x}", "red", attrs=["bold"])

def blue_bold(x):
    return colored(f"{x}", "blue", attrs=["bold"])

class KvasirDatasetBase(Dataset):
    """
    Basic Dataset class for Kvasir-SEG
    Initialises dataset with images and masks

    Attributes
    ----------
    says_str : str
        a formatted string to print out what the animal says (default 45)
    """

    def __init__(
        self,
        root_dir: Union[str, Path],
        bboxes_file: Optional[str] = "kavsir_bboxes.json",
        image_format: str = "jpg",
        mask_format: str = "jpg",
        augment_conf: Union[Dict[str, Any], Union[str, Path]] = {},
    ) -> None:
        self.image_format = image_format
        self.mask_format = mask_format
        self.root_dir = Path(root_dir)
        self.images_dir = self.root_dir / "images"
        self.masks_dir = self.root_dir / "masks"
        self.bboxes_file = self.root_dir / bboxes_file

        # prepare data
        self.data_images = {}

        for name in tqdm(glob(f"{self.images_dir}/*.{self.image_format}")):
            try:
                name_key = Path(name).name.split(".")[0]
                image_raw = Image.open(name)
                self.data_images[name_key] = {"pil_image_raw": image_raw}
            except Exception:
                print(f"{red_bold('error during reading image:')}: {name}")

        for name in tqdm(glob(f"{self.masks_dir}/*.{self.mask_format}")):
            try:
                name_key = Path(name).name.split(".")[0]
                if name_key not in self.data_images:
                    print("key error")
                    self.data_images[name_key]
                image_mask = Image.open(name)
                self.data_images[name_key]["pil_image_mask"] = image_mask

                size_image = self.data_images[name_key]["pil_image_raw"].size
                size_mask = self.data_images[name_key]["pil_image_mask"].size
                assert (
                    size_image == size_mask
                ), f"the mask and image size should be the same, name: {name_key}"

            except Exception:
                print(f"{red_bold('error during reading image:')}: {name}")

        self.data_names = list(self.data_images.keys())
        self.data_names.sort()

        # prepare bboxes
        try:
            with open(self.bboxes_file) as f:
                bboxes = json.load(f)

                for name_key in bboxes:
                    if name_key in self.data_images:
                        self.data_images[name_key]["bboxes"] = bboxes.get(name_key)
        except FileNotFoundError:
            print(
                f"Warning! {self.bboxes_file} file not found, dataset will be without bboxes"
            )
        except KeyError:
            print(f"Warning! {self.bboxes_file} doesn't consist of bbox for {name_key}")

        # prepare augmentations

        self.augmentator = Augmentator(augment_conf)
        self.to_tensor = ToTensor()

    def set_up_augmentator(
        self, augment_conf: Union[Dict[str, Any], Union[str, Path]] = {}
    ) -> None:
        self.augmentator = Augmentator(augment_conf)

    def __getitem__(
        self, idx: int, return_bboxes: bool = True
    ) -> Dict["str", Union[torch.Tensor, List[torch.Tensor]]]:
        input_tensor = self.data_images[self.data_names[idx]].get("pil_image_raw")
        target_mask_tensor = self.data_images[self.data_names[idx]].get(
            "pil_image_mask"
        )

        input_tensor = np.array(input_tensor)
        target_mask_tensor = np.array(target_mask_tensor)

        augmentations = self.augmentator()

        transformed = augmentations(image=input_tensor, mask=target_mask_tensor)

        input_tensor = transformed["image"]
        target_mask_tensor = transformed["mask"]

        input_tensor = self.to_tensor(input_tensor)
        target_mask_tensor = self.to_tensor(target_mask_tensor)[0, :, :]
        target_mask_tensor = target_mask_tensor == 1.0
        target_mask_tensor = target_mask_tensor.long()

        result = {"input": input_tensor, "target": target_mask_tensor}

        if "bboxes" in self.data_images[self.data_names[idx]] and return_bboxes:
            curr_bboxes = self.data_images[self.data_names[idx]].get("bboxes")
            height_orig = curr_bboxes["height"]
            weight_orig = curr_bboxes["width"]

            normalized_bboxes = []

            for bbox in curr_bboxes["bbox"]:
                normalized_bboxes.append(
                    torch.tensor(
                        [
                            bbox["xmin"] / weight_orig,
                            bbox["ymin"] / height_orig,
                            bbox["xmax"] / weight_orig,
                            bbox["ymax"] / height_orig,
                        ]
                    )
                )
            result["bboxes"] = normalized_bboxes

            object_area = target_mask_tensor.sum()
            image_area = np.product(target_mask_tensor.shape[-2:])
            relative_area = object_area / image_area

            result["relative_area"] = relative_area
            result["name"] = self.data_names[idx]

        return result

    def __len__(self) -> int:
        return len(self.data_images)

class KvasirDataset(KvasirDatasetBase):
    def __init__(self, names: Optional[List[str]] = None, *args, **kwargs) -> None:
        super().__init__(*args, **kwargs)
        if names is not None:
            self.data_names = names
            self.data_names.sort()
            names_current = list(self.data_images.keys())
            for k in names_current:
                if k not in self.data_names:
                    self.data_images.pop(k)

    def __getitem__(self, idx) -> Dict["str", Union[torch.Tensor, List[torch.Tensor]]]:
        result = super().__getitem__(idx, return_bboxes=False)
        return result

def load_dataset(resource: Union[Path, str, Dict[str, Any]]) -> KvasirDataset:
    config = resource

    if isinstance(resource, Path) or isinstance(resource, str):
        resource = Path(resource)

        with open(resource, "r") as file:
            config = yaml.safe_load(file)

        assert "data_config" in config, f"wrong resource {resource} construction"

    path_to_dataset = config["data_config"]["path_to_dataset"]
    augment_config_path = config["data_config"]["augment_config"]

    dataset = KvasirDataset(root_dir=path_to_dataset, augment_conf=augment_config_path)

    return dataset

def load_datasets(
    resource: Union[Path, str, Dict[str, Any]]
) -> Sequence[KvasirDataset]:
    """
    loss loader from configureation, suppose that resource
    contains field 'loss_config'
    """

    config = resource

    if isinstance(resource, Path) or isinstance(resource, str):
        resource = Path(resource)

        with open(resource, "r") as file:
            config = yaml.safe_load(file)

        assert "data_config" in config, f"wrong resource {resource} construction"

    path_to_dataset = config["data_config"]["path_to_dataset"]
    augment_config_path_train = config["data_config"]["augment_config"]["train"]
    augment_config_path_test = config["data_config"]["augment_config"]["test"]
    seed = config["data_config"]["train_test_split"]["seed"]
    lens = config["data_config"]["train_test_split"]["lens"]

    dataset = KvasirDatasetBase(
        root_dir=path_to_dataset, augment_conf=augment_config_path_train
    )

    compute_metrics = ComputeMetrics(config)
    name_group = [
        [
            item["name"],
            compute_metrics.compute_group_area_by_relarea(item["relative_area"].item()),
        ]
        for item in dataset
    ]

    X = [n[0] for n in name_group]
    y = [n[1] for n in name_group]

    test_size = lens[1] / (sum(lens))
    train_names, test_names, train_y, test_y = train_test_split(
        X, y, test_size=test_size, random_state=seed, stratify=y
    )

    dataset_train = KvasirDataset(
        names=train_names,
        root_dir=path_to_dataset,
        augment_conf=augment_config_path_train,
    )
    dataset_test = KvasirDataset(
        names=test_names,
        root_dir=path_to_dataset,
        augment_conf=augment_config_path_test,
    )

    return dataset_train, dataset_test


#!/usr/bin/env pypy

import math
import fileinput

maxp = int(math.pow(10, 6))
maxn = math.pow(10, 18)

def gen_primes():
    primes = []
    p = [False for _ in range(maxp)]
    for i in range(2, maxp, 1):
        if p[i]:
            continue
        primes.append(i)
        for j in range(i, maxp, i):
            p[j] = True
    return primes

if __name__ == "__main__":
    f = fileinput.input()
    for line in f:
        n = int(line)

    cnt = 0
    primes = gen_primes()
    j = len(primes) - 1
    for i in range(0, len(primes)):
        while (i < j) and ((primes[i] * math.pow(primes[j], 3)) > n):
            j -= 1
        if i >= j:
            break
        cnt += j - i
    print(cnt)


def series(N:int):
    series_sum = 0
    for i in range(1, N+1):
        series_sum = series_sum + i*i

    return series_sum

if __name__ == '__main__':
    print("Problem 4")
    print("ID: 2019-2-60-025")
    print()

    n = int(input("Enter a number: "))
    if n <= 0:
        while True:
            n = int(input("Invalid input. Please enter a positive number: "))
            if n > 0: break

    print(f"Sum of the Series: {series(n)}")


import tensorflow as tf

from nmt import rnn_utils
from nmt.encoders.abstract_encoder import EmbeddingEncoder

class UniRNNEncoder(EmbeddingEncoder):

    def encode(self, inputs, length, mode, params=None):
        default_params = self.default_config()
        if params:
            default_params.update(**params)
        params = default_params

        inputs = self.embedding.embedding(inputs, length, params)
        if params['time_major']:
            inputs = tf.transpose(inputs, perm=[1, 0, 2])

        with tf.variable_scope(self.scope, reuse=tf.AUTO_REUSE) as scope:
            cell = rnn_utils.build_rnn_cells(
                num_layers=params['num_encoder_layers'],
                num_residual_layers=params['num_encoder_residual_layers'],
                unit_type=params['unit_type'],
                num_units=params['num_units'],
                dropout=params['dropout'] if mode == tf.estimator.ModeKeys.TRAIN else 0.0,
                forget_bias=params['forget_bias'],
                residual_fn=None
            )
            outputs, states = tf.nn.dynamic_rnn(
                cell=cell,
                inputs=inputs,
                dtype=self.dtype,
                sequence_length=length,
                time_major=params['time_major'],
                swap_memory=params['swap_memory'])

        if params['time_major']:
            outputs = tf.transpose(outputs, perm=[1, 0, 2])

        return outputs, states

    def default_config(self):
        params = {
            "num_encoder_layers": 2,
            "num_encoder_residual_layers": 0,
            "dropout": 0.5,
            "unit_type": "lstm",
            "time_major": True,
            "swap_memory": True,
            "num_units": 256,
            "forget_bias": 1.0
        }
        return params


fname = "words.txt"

try:
    handle = open(fname,"r")
    words = []
    while True:
        content = handle.readline()
        if content == "":
            break
        else:
            words.append(content)
    handle.close()
except IOError:
    print("No such file!")

words.sort()

print("Words in an alphabetical order:")
for i in words:
    print(i)


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

import os

import glob
import fiona
import matplotlib
import pandas as pd
import numpy as np
import wradlib as wrl
import matplotlib.pyplot as plt

from matplotlib import path
from osgeo import osr

from pathlib import Path
from matplotlib.colors import LinearSegmentedColormap

#base_path = r'C:\Users\hachem\Downloads\SF201907\*'
base_path = r'C:\Users\hachem\Downloads\SF201407.tar\SF201407\*'

state_name = 'Rheinland-Pfalz'

files = glob.glob(base_path)

# hdf5_path = os.path.join(database, 'rain_germany_daily.h5')
# hf = tables.open_file(hdf5_path, 'r')

# ishape = (r"P:\2017_SYNOPSE_II\02_Import\07_Shapefiles\DEU_adm_shp"
#           r"\DEU_adm1.shp")

ishape = r"X:\staff\elhachem\Shapefiles\Neckar_seperate\Danube.shp"
#first = ishape.next()

# shp_objects_all = [shp for shp in list(fiona.open(ishape))
#                    if shp['properties']['NAME_1'] == state_name]

shp_objects_all = [shp for shp in list(fiona.open(ishape))]

#==============================================================================
#
# #============================================================================
# hourly_events = [  # '2016-06-25 00:00:00',
#     '2018-06-11 14:50:00',
#     '2018-06-11 15:50:00',
#     '2018-06-11 16:50:00',
#     '2018-06-11 17:50:00',
#     '2018-06-11 18:50:00']

hourly_events = ['2018-09-06 16:50:00',
                 '2018-09-06 17:50:00',
                 '2018-09-06 18:50:00']
#'2018-09-23 17:00:00',
#'2018-09-23 18:00:00',
#'2018-09-23 19:00:00']

daily_events = [  # '2018-12-23 00:00:00',
    #'2019-05-22 00:00:00',
    '2018-05-14 00:00:00',
    '2019-07-28 00:00:00']

bound = [0., 1,
         2, 5, 8,
         10, 15, 20,
         25, 30]  # , 35, 40, 45]
interval_ppt = np.linspace(0.05, 0.95)
colors_ppt = plt.get_cmap('jet_r')(interval_ppt)
cmap_ppt = LinearSegmentedColormap.from_list('name', colors_ppt)
#cmap_ppt = plt.get_cmap('jet_r')
cmap_ppt.set_over('navy')

norm = matplotlib.colors.BoundaryNorm(bound, cmap_ppt.N)

for i, file in enumerate(files):
    #     file = file + '.gz'

    #     event_date = ('20' + file[50:52] + '-' + file[52:54] + '-' + file[54:56]
    #                   + ' ' + file[56:58] + ':' + file[58:60] + ':00')
    #     print(i, '/', len(files),  event_date)
    # #     if event_date in hourly_events:
    #     event_date_minus_one_hr = pd.DatetimeIndex(
    #         [event_date]) - pd.Timedelta(minutes=60)

    #     shifted_event = event_date_minus_one_hr + pd.Timedelta(minutes=10)

    rwdata, rwattrs = wrl.io.read_radolan_composite(file)
    # mask data
    sec = rwattrs['secondary']
    rwdata.flat[sec] = -9999
    rwdata = np.ma.masked_equal(rwdata, -9999)

    # create radolan projection object
    proj_stereo = wrl.georef.create_osr("dwd-radolan")

    # create wgs84 projection object
    proj_wgs = osr.SpatialReference()
    proj_wgs.ImportFromEPSG(4326)

    # get radolan grid
    radolan_grid_xy = wrl.georef.get_radolan_grid(900, 900)
    x1 = radolan_grid_xy[:, :, 0]
    y1 = radolan_grid_xy[:, :, 1]

    # convert to lonlat
    radolan_grid_ll = wrl.georef.reproject(radolan_grid_xy,
                                           projection_source=proj_stereo,
                                           projection_target=proj_wgs)
    lon1 = radolan_grid_ll[:, :, 0]
    lat1 = radolan_grid_ll[:, :, 1]

    mask = np.ones_like(lon1, dtype=np.bool)
    # first['geometry']['coordinates']
    for n, i_poly_all in enumerate(shp_objects_all):
        i_poly = i_poly_all['geometry']['coordinates']
        if 0 < len(i_poly) <= 1:
            p = path.Path(np.array(i_poly)[0])
            grid_mask = p.contains_points(
                np.vstack((lon1.flatten(),
                           lat1.flatten())).T).reshape(900, 900)
            mask[grid_mask] = 0
        else:
            for ix in range(len(i_poly)):

                p = path.Path(np.array(i_poly[ix]))
                grid_mask = p.contains_points(
                    np.vstack((lon1.flatten(),
                               lat1.flatten())).T).reshape(900, 900)
                mask[grid_mask] = 0
#     mask.dump(r'X:\staff\elhachem\2020_10_03_Rheinland_Pfalz\mask.npy')
#     rwdata[mask] = -1
    rw_maskes = np.ma.masked_array(rwdata, rwdata < 0.)

#         plt.figure()
#     #     min_x = xss[np.argmin([xs - x0 for xs in xss])]
#     #     min_y = yss[np.argmin([ys - y0 for ys in yss])]
#
#         plt.pcolormesh(lon1, lat1, rw_maskes, cmap=cmap_ppt,
#                        vmin=0, norm=norm, vmax=30)
#
#         plt.ylabel('Latitude [°]')
#         plt.xlabel('Longitude [°]')
#
#         plt.xlim([7.1, 10.7])
#         plt.ylim([47.3, 50.0])
#
#     #     plt.axis('equal')
#         # radar.set_aspect('equal', 'box')
#         # plt.xlim([netatmo.get_xlim()[0], netatmo.get_xlim()[1]])
#         # plt.ylim([netatmo.get_ylim()[0], netatmo.get_ylim()[1]])
#         cbar = plt.colorbar(extend='max', label='[mm/h]')
#
#         plt.tight_layout()
#         plt.savefig(
#             Path(os.path.join(
#                 r'C:\Users\hachem\Desktop\radar',
#                 'hourly_event_{}.png'.format(file[50:59]))), dpi=600)
#
#     #     plt.show()
#     #     break
#         plt.close()


import uuid
from abc import ABC, abstractmethod
from decimal import Decimal
from typing import List, Optional, Dict

from pydantic import BaseModel, Field, computed_field

from cache.store import get_provider_html
from models.models import ProviderVehiclesRequest, ProviderStoreItem

class Calculator(ABC, BaseModel):
    vehicle_request: ProviderVehiclesRequest
    price_per_minute: Optional[Decimal]
    price_per_km: Optional[Decimal]

    def total_price(self) -> Decimal:
        return (self.vehicle_request.distance_kilometer * self.price_per_km) + (
            self.vehicle_request.time_minutes * self.price_per_minute
        )

class VehicleOption(BaseModel):
    vehicle_image: str
    electric: bool = Field(default=False)
    provider: str
    type: str

    calculator: Calculator = Field(exclude=True)

    @computed_field
    @property
    def total_price(self) -> Decimal:
        return self.calculator.total_price().quantize(Decimal("0.00"))

    @computed_field
    @property
    def id(self) -> str:
        return str(uuid.uuid4())

class ProviderInterface(ABC, BaseModel):
    vehicle_request: ProviderVehiclesRequest
    pricing_urls: Optional[List[str]] = Field(required=False, default=None)
    free_parking: bool

    def get_pricing_html(self) -> List[ProviderStoreItem]:
        assert self.pricing_urls
        return [get_provider_html(url) for url in self.pricing_urls]

    @abstractmethod
    async def get_vehicles_options(self) -> List[VehicleOption]:
        raise NotImplementedError("Forgot to implement total method")


#!/usr/bin/env python2
# -*- coding: utf-8 -*-
"""
% EEE6230- Scientific Software Development for Biomedical Imaging
% Project 2:: Programming Lab 2
"""
#%% import required libraries
import numpy as np
#%% part 1: Householder reduction to bidiagonal form
def householder_transformation(b, k):
    '''
    Arguments:
        b -- A numpy array of size mx1
        k -- An integer index between 1 and m-1.
             The algorithm will set the entries below index k to zero.

    Returns:
        H -- A numpy array of size mxm: The Householder Matrix
    '''
    # uncomment this line if you index the first matrix element as 1
    # k = k - 1

    m = b.shape[0]
    w = b.copy()
    w[0:k,0] = 0

    s = np.sqrt(np.sum(w**2))

    if b[k,0]>=0:
        s = -s;

    w[k,0] = w[k,0] - s
    w = w/np.sqrt(np.sum(w**2))
    H = np.eye(m,m) - 2*np.dot(w, w.T)
    return H

#%% part 2: Compute the bidiangonal reduction of matrix
def bidiag_reduction(A):
    '''
    Compute the bidiagonal reduction of matrix A = UBV.T
    Arguments:
        A -- A numpy array of size mxn

    Returens:
        B -- A numpy array of size mxn. Upper bidiagonal matrix.
        U -- A numpy array of size mxm. Unitary matrix.
        V -- A numpy array of size nxn. Unitary matrix.
    '''
    m = A.shape[0] # number of rows
    n = A.shape[1] # number of columns

    B = A.copy()
    U = np.eye(m, m)
    V = np.eye(n, n)

    for k in range(n):
        v = np.zeros((m, 1))
        v[0:m, 0] = B[0:m, k]
        Q = householder_transformation(v, k)

        B = np.dot(Q, B)
        U = np.dot(U, Q)

        if (k < n-2):
            v = np.zeros((n, 1))
            v[0:n, 0] = B[k, 0:n]
            P = householder_transformation(v, k+1)
            B = np.dot(B, P)
            V = np.dot(V, P)

    return B, U, V

#%% Follow-up work: part 1
def test_bidiag_reduction(fun, A, eps = 1e-8):
    '''
    Arguments:
        fun -- The function handle
        A   -- A numpy array of size mxn. Data matrix
        eps -- A small value used as a threshold to check
               if a value is zero or not

    Returns:
        True -- If the code is correct
        False -- If the code is not correct
    '''
    B, U, V = fun(A)

    # check if A = U*B*V^T
    newA = np.dot(np.dot(U,B), V.T)
    if np.sum(np.abs(A-newA))> eps:
        return False

    # check if U*U^T = I
    if np.sum(np.abs(np.eye(A.shape[0])-np.dot(U,U.T)))> eps:
        return False

    # check if V*V^T = I
    if np.sum(np.abs(np.eye(A.shape[1])-np.dot(V,V.T)))> eps:
        return False

    # check if B is upper bidiagonal
    if np.abs(np.sum(B) - np.sum(np.diag(B,0)) - np.sum(np.diag(B,1))) > eps:
        return False

    # otherwise
    return True


import beyond.Reaper
import beyond.Screen

@ProgramStart
class Main(Screen):

	def Setup(o, e):

		e.Title("Reaper Transport Example")

		with e.Horizontal():
			e.Stretch()

			e.Button("Play")
			e.Size(200, 200)
			e.Stretch()

			e.Button("Stop")
			e.Size(200, 200)
			e.Stretch()

	def Play(o):
		with Reaper as r: r.OnPlayButton()

	def Stop(o):
		with Reaper as r: r.OnStopButton()

beyond Python V26/Examples Reaper/Transport.py


import os, sys, subprocess, time
import util

thisDir = os.path.dirname(os.path.realpath(__file__))

def osSys(p_input, p_display=True):
    if p_display:
        util.message("# " + p_input)
    rc = os.system(p_input)
    return rc

def exit_rm_backrest(msg):
    util.message(f"{msg}", "error")
    osSys("./nc remove backrest")
    sys.exit(1)

# MAINLINE #######################

if os.path.isdir("/var/lib/pgbackrest"):
    exit_rm_backrest("ERROR: '/var/lib/pgbackrest' directory already exists")

pgV = ""
if os.path.isdir("pg14"):
    pgV = "pg14"
elif os.path.isdir("pg15"):
    pgV = "pg15"
elif os.path.isdir("pg16"):
    pgV = "pg16"

if pgV == "":
    exit_rm_backrest("pg14, 15 or 16 must be installed")

os.chdir(thisDir)
osUsr = util.get_user()
usrUsr = osUsr + ":" + osUsr

# cleanup cruft
osSys("rm -r lib", False)
osSys("rm -r share", False)

util.message("\n## creating /usr/bin/pgbackrest link #################")
osSys("sudo rm -f /usr/bin/pgbackrest")
osSys("sudo ln -s " + thisDir + "/bin/pgbackrest /usr/bin/pgbackrest")
osSys("sudo chmod 755 /usr/bin/pgbackrest")

osSys("sudo mkdir -p -m 770 /var/log/pgbackrest")

util.message("\n## creating '/etc/pgbackrest/pgbackrest.conf' ########")
osSys("sudo chown " + usrUsr + " /var/log/pgbackrest")
osSys("sudo mkdir -p /etc/pgbackrest")
osSys("sudo mkdir -p /etc/pgbackrest/conf.d")
osSys("sudo touch /etc/pgbackrest/pgbackrest.conf")
osSys("sudo chmod 640 /etc/pgbackrest/pgbackrest.conf")
osSys("sudo chown " + usrUsr + " /etc/pgbackrest/pgbackrest.conf")

osSys("sudo mkdir -p /var/lib/pgbackrest")
osSys("sudo chmod 750 /var/lib/pgbackrest")
osSys("sudo chown " + usrUsr + " /var/lib/pgbackrest")

dataDir = os.getenv("MY_HOME") + "/data/" + pgV

util.message("\n## creating '/etc/pgbackrest/pgbackrest.conf' ########")
conf_file = thisDir + "/pgbackrest.conf"
util.replace("pgXX", pgV, conf_file, True)
util.replace("pg1-path=xx", "pg1-path=" + dataDir, conf_file, True)
util.replace("pg1-user=xx", "pg1-user=" + osUsr, conf_file, True)
util.replace("pg1-database=xx", "pg1-database=" + "postgres", conf_file, True)

cmd = "dd if=/dev/urandom bs=256 count=1 2> /dev/null | LC_ALL=C tr -dc 'A-Za-z0-9' | head -c32"
bCipher = subprocess.check_output(cmd, shell=True)
sCipher = bCipher.decode("ascii")
util.replace("repo1-cipher-pass=xx", "repo1-cipher-pass=" + sCipher, conf_file, True)
osSys("cp " + conf_file + "  /etc/pgbackrest/.")

stanza = "--stanza=" + pgV + " "
util.message("\n## Modify 'postgresql.conf' #########################")
aCmd = "pgbackrest " + stanza + " archive-push %p"
util.change_pgconf_keyval(pgV, "archive_command", aCmd, p_replace=True)
util.change_pgconf_keyval(pgV, "archive_mode", "on", p_replace=True)

osSys("../nc restart " + pgV)
time.sleep(3)

osSys("pgbackrest stanza-create " + stanza)
osSys("pgbackrest check " + stanza)


import sys;input=sys.stdin.readline
N=int(input())

stack=[]
s=0
for _ in range(N):
    i=input().rstrip().split()
    if i[0]=='push':
        stack.append(i[1])
        s+=1
    elif i[0]=='pop':
        if s!=0:
            print(stack.pop())
            s-=1
        else:
            print(-1)
    elif i[0]=='size':
        print(s)
    elif i[0]=='empty':
        if s==0:
            print(1)
        else:
            print(0)
    elif i[0]=='top':
        if s==0:
            print(-1)
        else:
            print(stack[-1])


print("hello python")
print("你好世界")
age = 23
message = "Happy " + str(age) + "rd Birsrthday !"
print(message)
row = 1
while row <= 9:
    col = 1
    while col <= row:
        print("%d*%d=%d" % (col, row, col * row ), end="\t")
        col += 1
    print("")
    row += 1


# Importing Module
from pygame import mixer
import customtkinter, tkinter
from PIL import Image
import eyed3
import os

mixer.init()

# Variables
sList = []
musicFolder = "/home/bir/Music/"
current = ''
start = False
fname = "assets/notfound.jpg"

# Functions
def changeThumb():
    global fname, playImg, mImg
    audio_file = eyed3.load(musicFolder+current)

    image = audio_file.tag.images[0]
    fname = f"assets/song.png"
    image_file = open(fname, "wb")
    image_file.write(image.image_data)
    image_file.close()

    playImg.configure(light_image=Image.open(fname))

    os.remove(fname)

def play():
    global start, current
    if current == '':
        current = sList[0]

    i = sList.index(current)
    changeThumb()

    if start:
        mixer.music.unpause()
    else:
        mixer.music.load(musicFolder+current)
        mixer.music.play()
        mixer.music.queue(musicFolder+current)
        start = True

def pause():
    mixer.music.pause()

def resume():
    mixer.music.unpause()

def next():
    global current, start
    length = len(sList)-1
    i = sList.index(current)

    if i < length:
        current = sList[i+1]
    else:
        current = sList[0]

    changeThumb()
    start = False
    play()

def prev():
    global current, start
    length = len(sList)-1
    i = sList.index(current)

    if i != length:
        current = sList[i-1]
    else:
        current = sList[0]

    changeThumb()
    start = False
    play()

def lsSongs():
    for f in os.listdir(musicFolder):
        if '.mp3' in f or '.wav' in f:
            sList.append(f)

def addsongs():
    global current, musicFolder,sList
    songs = list(tkinter.filedialog.askopenfilenames(initialdir=musicFolder,title="Choose a song", filetypes=(("mp3 Files","*.mp3"),)))
    if len(songs) != 0:
        sList = songs
        current = sList[0]
        print(current)
        musicFolder = ''
        next()

# Main GUI Code
root = customtkinter.CTk()
root.geometry("840x545")
root.minsize(840, 545)
root.maxsize(840, 545)
root.title("Music Player")

# Fonts
bg = customtkinter.CTkFont(family="Helevetica", size=35, weight = 'bold')
md = customtkinter.CTkFont(family="Helevetica", size=18, weight='bold')
sm = customtkinter.CTkFont(family="Helevetica", size=15)

lsSongs()

# Menu Bar
mainmenu = customtkinter.CTkFrame(root, height=30, width=830)
mainmenu.grid(row=0, column=0,padx=5, pady=5, sticky="nw")

addSongs = customtkinter.CTkButton(mainmenu, text="Add Songs", width=50, height=20, font=md, corner_radius=0, command=addsongs, fg_color="transparent")
addSongs.grid(padx=5,ipadx=5,ipady=5,sticky="w")

# Music Thumbnail
mThumb = customtkinter.CTkFrame(master=root, width=835, height=370, fg_color="transparent")
mThumb.grid(row=1, column=0, padx=5, pady=5)
playImg = customtkinter.CTkImage(light_image=Image.open(fname), size=(835,370))
mImg = customtkinter.CTkLabel(mThumb, image=playImg, text="")
mImg.grid(padx=0)

# Music Player Options
mPlay = customtkinter.CTkFrame(master=root, width=835, height=110, fg_color='transparent')
mPlay.grid(row=2, columnspan=2, column=0, padx=5, pady=15)

nextBtn = customtkinter.CTkButton(mPlay, text="Prev", width=75, height=75, corner_radius=75, font=md, border_spacing=0, command=prev)
nextBtn.pack(side='left', padx=7)

playBtn = customtkinter.CTkButton(mPlay, text="Play", width=75, height=75, corner_radius=75, font=md, border_spacing=0, command=play)
playBtn.pack(side='left', padx=7)

pauseBtn = customtkinter.CTkButton(mPlay, text="Pause", width=75, height=75, corner_radius=75, font=md, border_spacing=0, command=pause)
pauseBtn.pack(side='left', padx=7)

nextBtn = customtkinter.CTkButton(mPlay, text="Next", width=75, height=75, corner_radius=75, font=md, border_spacing=0, command=next)
nextBtn.pack(side='left', padx=7)

root.mainloop()


"""
Debug ORMAdapter calls within ORM runs.

Demos::

    python tools/trace_orm_adapter.py -m pytest \
        test/orm/inheritance/test_polymorphic_rel.py::PolymorphicAliasedJoinsTest::test_primary_eager_aliasing_joinedload

    python tools/trace_orm_adapter.py -m pytest \
        test/orm/test_eager_relations.py::LazyLoadOptSpecificityTest::test_pathed_joinedload_aliased_abs_bcs

    python tools/trace_orm_adapter.py my_test_script.py

The above two tests should spit out a ton of debug output.  If a test or program
has no debug output at all, that's a good thing!  it means ORMAdapter isn't
used for that case.

You can then set a breakpoint at the end of any adapt step:

    python tools/trace_orm_adapter.py -d 10 -m pytest -s \
        test/orm/test_eager_relations.py::LazyLoadOptSpecificityTest::test_pathed_joinedload_aliased_abs_bcs

"""  # noqa: E501
# mypy: ignore-errors

from __future__ import annotations

import argparse
import contextlib
import contextvars
import sys
from typing import TYPE_CHECKING

from sqlalchemy.orm import util

if TYPE_CHECKING:
    from typing import Any
    from typing import List
    from typing import Optional

    from sqlalchemy.sql.elements import ColumnElement

class _ORMAdapterTrace:
    def _locate_col(
        self, col: ColumnElement[Any]
    ) -> Optional[ColumnElement[Any]]:
        with self._tracer("_locate_col") as tracer:
            return tracer(super()._locate_col, col)

    def replace(self, col, _include_singleton_constants: bool = False):
        with self._tracer("replace") as tracer:
            return tracer(super().replace, col)

    _orm_adapter_trace_context = contextvars.ContextVar("_tracer")

    @contextlib.contextmanager
    def _tracer(self, meth):
        adapter = self
        ctx = self._orm_adapter_trace_context.get(
            {"stack": [], "last_depth": 0, "line_no": 0}
        )
        self._orm_adapter_trace_context.set(ctx)

        stack: List[Any] = ctx["stack"]  # type: ignore
        last_depth = len(stack)
        line_no: int = ctx["line_no"]  # type: ignore
        ctx["last_depth"] = last_depth
        stack.append((adapter, meth))
        indent = "    " * last_depth

        if hasattr(adapter, "mapper"):
            adapter_desc = (
                f"{adapter.__class__.__name__}"
                f"({adapter.role.name}, mapper={adapter.mapper})"
            )
        else:
            adapter_desc = f"{adapter.__class__.__name__}({adapter.role.name})"

        def tracer_fn(fn, arg):
            nonlocal line_no

            line_no += 1

            print(f"{indent} {line_no} {adapter_desc}", file=REAL_STDOUT)
            sub_indent = " " * len(f"{line_no} ")

            print(
                f"{indent}{sub_indent} -> "
                f"{meth} {_orm_adapter_trace_print(arg)}",
                file=REAL_STDOUT,
            )
            ctx["line_no"] = line_no
            ret = fn(arg)

            if DEBUG_ADAPT_STEP == line_no:
                breakpoint()

            if ret is arg:
                print(f"{indent} {line_no} <- same object", file=REAL_STDOUT)
            else:
                print(
                    f"{indent} {line_no} <- {_orm_adapter_trace_print(ret)}",
                    file=REAL_STDOUT,
                )

            if last_depth == 0:
                print("", file=REAL_STDOUT)
            return ret

        try:
            yield tracer_fn
        finally:
            stack.pop(-1)

util.ORMAdapter.__bases__ = (_ORMAdapterTrace,) + util.ORMAdapter.__bases__
util.ORMStatementAdapter.__bases__ = (
    _ORMAdapterTrace,
) + util.ORMStatementAdapter.__bases__

def _orm_adapter_trace_print(obj):
    if obj is None:
        return "None"

    t_print = _orm_adapter_trace_printers.get(obj.__visit_name__, None)
    if t_print:
        return t_print(obj)
    else:
        return f"{obj!r}"

_orm_adapter_trace_printers = {
    "table": lambda t: (
        f'Table("{t.name}", '
        f"entity={t._annotations.get('parentmapper', None)})"
    ),
    "column": lambda c: (
        f'Column("{c.name}", {_orm_adapter_trace_print(c.table)} '
        f"entity={c._annotations.get('parentmapper', None)})"
    ),
    "join": lambda j: (
        f"{j.__class__.__name__}({_orm_adapter_trace_print(j.left)}, "
        f"{_orm_adapter_trace_print(j.right)})"
    ),
    "label": lambda l: f"Label({_orm_adapter_trace_print(l.element)})",
}

DEBUG_ADAPT_STEP = None
REAL_STDOUT = sys.__stdout__

def main():
    global DEBUG_ADAPT_STEP

    parser = argparse.ArgumentParser()
    parser.add_argument(
        "-d", "--debug", type=int, help="breakpoint at this adaptation step"
    )
    parser.add_argument(
        "-m",
        "--module",
        type=str,
        help="import module name instead of running a script",
    )
    parser.add_argument(
        "args", metavar="N", type=str, nargs="*", help="additional arguments"
    )

    argparse_args = []
    sys_argv = list(sys.argv)

    progname = sys_argv.pop(0)

    # this is a little crazy, works at the moment for:
    # module w args:
    #    python tools/trace_orm_adapter.py -m  pytest test/orm/test_query.py -s
    # script:
    #   python tools/trace_orm_adapter.py test3.py
    has_module = False
    while sys_argv:
        arg = sys_argv.pop(0)
        if arg in ("-m", "--module", "-d", "--debug"):
            argparse_args.append(arg)
            argparse_args.append(sys_argv.pop(0))
            has_module = arg in ("-m", "--module")
        else:
            if not has_module:
                argparse_args.append(arg)
            else:
                sys_argv.insert(0, arg)
            break

    options = parser.parse_args(argparse_args)
    sys.argv = ["program.py"] + sys_argv

    if options.module == "pytest":
        sys.argv.extend(["--capture", "sys"])

    import runpy

    if options.debug:
        DEBUG_ADAPT_STEP = options.debug

    if options.module:
        runpy.run_module(options.module, run_name="__main__")
    else:
        progname = options.args[0]

        runpy.run_path(progname)

if __name__ == "__main__":
    main()


#! python3

# from itertools import *
from decimal import Decimal
from copy import copy
from math import floor
from math import sqrt
import sys

GetNthTriangleNumber = lambda n: n*(n+1)/2

def GetDivisors(n):
    divisors = []
    start = floor(n/2)+1
    while start > 0:
        if not n%start:
            divisors.append(start)
        start -= 1
    return divisors + [n]

def GetFirstTriangleNumberWithNDivisors(n):
    leap = 1
    while len(GetDivisors(GetNthTriangleNumber(leap)))<n:
        leap += leap
    peak = leap
    offset = int(peak/4)
    while offset>1:#peak-offset > floor(peak/2):
        if len(GetDivisors(GetNthTriangleNumber(peak-offset)))>n:
            offset += offset/2
        else:
            offset -= offset/2
    return GetNthTriangleNumber(peak-offset)

def test():
    print("3 == GetDivisors(9)", GetDivisors(378))
    #print("Get first triangle number with 500 divisors",GetFirstTriangleNumberWithNDivisors(10))
    past = (0,0)
    x=1
    while past[0] < 500:
        current = len(GetDivisors(GetNthTriangleNumber(x)))
        if current > past[0]:
            past = (current,GetNthTriangleNumber(x))
            print(past)
        x+=1
def main():
    test()

if __name__ == "__main__":
    main()


import ipv6_utils
import log

from static import OF_TABLE_NUM
from static import WLAN_IFACE
from static import GW_IFACE

from switch import OFRule
from switch import Switch
from switch import Link
from switch import AccessPointConf
from switch import GatewayConf

from event import *
# End import from iJOIN solution files

# Start import from Ryu files
from ryu.base import app_manager
from ryu.controller.handler import set_ev_cls
from ryu.controller.handler import MAIN_DISPATCHER
from ryu.ofproto import ofproto_v1_3 as ofproto
from ryu.ofproto import ofproto_v1_3_parser as ofp_parser
from ryu.topology.api import get_switch
from ryu.topology.event import EventSwitchEnter as RyuEventSwitchEnter
from ryu.topology.event import EventSwitchLeave as RyuEventSwitchLeave
from ryu.topology.event import EventLinkAdd as RyuEventLinkAdd
from ryu.topology.event import EventLinkDelete as RyuEventLinkDelete
from ryu.topology.event import EventPortAdd as RyuEventPortAdd
from ryu.topology.event import EventPortModify as RyuEventPortModify
from ryu.topology.event import EventPortDelete as RyuEventPortDelete
# End import from Ryu files

class Nmm(app_manager.RyuApp):
	"""
	================ =========================================================
	Attribute        Description
	================ =========================================================
	OFP_VERSIONS     Declaration of supported OFP version
	_EVENTS          The list of events provided by the RyuApp
	================ =========================================================
	"""
	OFP_VERSIONS = [ofproto.OFP_VERSION]
	_EVENTS = [EventTopologyUpdate, EventSwitchEnter, EventSwitchUpdate,
				EventSwitchLeave, EventLinkAdd, EventLinkDelete]

	def __init__(self, *args, **kwargs):
		"""
		================ =========================================================
		Attribute        Description
		================ =========================================================
		switches         The dictionary storing the switches as
		                 custom Switch isntance
		================ =========================================================
		"""
		super(Nmm, self).__init__(*args, **kwargs)
		self.logger = log.get_logger(self.name)

		self.switches = {}
		self.accesspoints = {}
		self.gateways = {}

		self.of_rules = {}

	def _initialise_switch_of_tables(self, switch):
		"""
		Flush the flow table when the switch connects to the controller.
		"""
		# Flush OpenFlow entries
		match = ofp_parser.OFPMatch()
		instructions = []
		actions = []

		datapath = switch.switch.dp
		ofproto = datapath.ofproto
		parser = datapath.ofproto_parser

		for i in xrange(1, OF_TABLE_NUM):
			mod = parser.OFPFlowMod(datapath = datapath, cookie = 0,
							cookie_mask = 0, command = ofproto.OFPFC_DELETE,
							idle_timeout = 0, hard_timeout = 0, table_id = i,
							buffer_id = ofproto.OFPCML_NO_BUFFER, out_port = ofproto.OFPP_ANY,
							out_group = ofproto.OFPG_ANY, match = match, instructions = instructions)
			datapath.send_msg(mod)

		for i in xrange(0, OF_TABLE_NUM-1):
			instructions = [ofp_parser.OFPInstructionGotoTable(i+1)]
			req = EventWriteOFRule(OFRule(switch, match, actions, instructions, table_id = i, priority = 0))
			self.send_event(req.dst, req)

	def _check_if_ap_port(self, port):
		"""
		Check if a switch port is an access port.
		"""
		return port.name.startswith(WLAN_IFACE)

	def _check_if_gw_port(self, port):
		"""
		Check if a switch port is a gateway port.
		"""
		return port.name.startswith(GW_IFACE)

	def _get_ap_conf(self, switch, port):
		"""
		Get AP configuration.
		"""
		ap_conf = AccessPointConf()
		ap_conf.port = port

		return ap_conf

	def _get_gw_conf(self, switch, port):
		"""
		Get GW configuration.
		"""
		gw_conf = GatewayConf()
		gw_conf.port = port
		# FIXME	HARDCODED
		gw_conf.nw_prefix = ('2020', str(hex(switch.switch.dp.id))[-4:],'0','0','0','0','0','0')
		gw_conf.nw_prefix_len = 32

		return gw_conf

	@set_ev_cls(EventPushPacket)
	def _handler_push_packet(self, ev):
		"""
		Send the Packet pkt through the OFPort port.
		"""
		datapath = ev.switch.switch.dp
		ofproto = datapath.ofproto
		parser = datapath.ofproto_parser

		actions = [parser.OFPActionOutput(port = ev.port.port_no)]
		out = parser.OFPPacketOut(datapath = datapath,
					buffer_id = ofproto.OFP_NO_BUFFER,
					in_port = ofproto.OFPP_CONTROLLER,
					actions = actions, data = ev.pkt.data)
		datapath.send_msg(out)

	@set_ev_cls(EventProcessPacket)
	def _handler_process_packet(self, ev):
		"""
		Send the Packet pkt through the OFPP_TABLE.
		"""
		datapath = ev.switch.switch.dp
		ofproto = datapath.ofproto
		parser = datapath.ofproto_parser

		actions = [parser.OFPActionOutput(port = ofproto.OFPP_TABLE)]
		out = parser.OFPPacketOut(datapath = datapath,
					buffer_id = ofproto.OFP_NO_BUFFER,
					in_port = ofproto.OFPP_CONTROLLER,
					actions = actions, data = ev.pkt.data)
		datapath.send_msg(out)

	@set_ev_cls(EventWriteOFRule)
	def _handler_write_of_rule(self, ev):
		"""
		Write OpenFlow rule on switch.
		If the rule is already present in the switch,
		don't write it again
		"""
		try:
			if ev.of_rule.key not in self.of_rules \
				or self.of_rules[ev.of_rule.key].actions != ev.of_rule.actions:

				datapath = ev.of_rule.switch.switch.dp
				ofproto = datapath.ofproto
				parser = datapath.ofproto_parser

				mod = parser.OFPFlowMod(datapath = datapath, table_id = ev.of_rule.table_id, priority = ev.of_rule.priority, match = ev.of_rule.match, instructions = ev.of_rule.instructions, cookie = ev.of_rule.cookie)
				datapath.send_msg(mod)

				self.of_rules[ev.of_rule.key] = ev.of_rule
		except KeyError:
			pass

	@set_ev_cls(EventDelOFRule)
	def _handler_del_of_rule(self, ev):
		"""
		Delete OpenFlow rule on switch.
		If the rule has been already deleted from the switch,
		don't delete it again
		"""
		try:
			if ev.of_rule.key in self.of_rules:
				datapath = ev.of_rule.switch.switch.dp
				ofproto = datapath.ofproto
				parser = datapath.ofproto_parser

				inst = []
				mod = parser.OFPFlowMod(datapath = datapath, cookie = ev.of_rule.cookie,
									cookie_mask = ev.of_rule.cookie_mask, table_id = ev.of_rule.table_id,
									command = ofproto.OFPFC_DELETE, idle_timeout = 0, hard_timeout = 0,
									priority = ev.of_rule.priority, buffer_id = ofproto.OFPCML_NO_BUFFER,
									out_port = ofproto.OFPP_ANY, out_group = ofproto.OFPG_ANY,
									match = ev.of_rule.match, instructions = inst)
				datapath.send_msg(mod)

				del self.of_rules[ev.of_rule.key]
		except KeyError:
			pass

	@set_ev_cls(EventSwitchRequest)
	def _handler_switch_request(self, req):
		"""
		Get a switch object given the dpid.
		"""
		switches = []
		try:
			if req.dpid is None:
				# reply all list
				switches = self.switches.values()
			elif req.dpid in self.switches:
				switches = [self.switches[req.dpid]]
		except KeyError:
			pass

		rep = EventSwitchReply(req.src, switches)
		self.reply_to_request(req, rep)

	@set_ev_cls(EventLinkRequest)
	def _handler_link_request(self, req):
		"""
		Get switch's links.
		"""
		links = []
		try:
			if req.dpid is None:
				# reply all list
				links = [in_li for sw in self.switches.itervalues() for li_li in sw.links.itervalues() for in_li in li_li]
			elif req.dpid in self.switches:
				links = [in_li for li_li in self.switches[req.dpid].links.itervalues() for in_li in li_li]
		except KeyError:
			pass

		rep = EventLinkReply(req.src, links)
		self.reply_to_request(req, rep)

	@set_ev_cls(RyuEventSwitchEnter, MAIN_DISPATCHER)
	def _handler_switch_enter(self, ev):
		"""
		Handler for event.EventSwitchEnter
		Add a node to the topology.
		"""
		switch = Switch(ev.switch)
		# Check switch capabilities
		self.switches[ev.switch.dp.id] = switch
		# HARDCODED
		for p in switch.switch.ports:
			if self._check_if_ap_port(p):
				ap_conf = self._get_ap_conf(switch, p)
				switch.is_ap = True
				switch.ap_conf = ap_conf
				self.accesspoints[ev.switch.dp.id] = switch
			elif self._check_if_gw_port(p):
				gw_conf = self._get_gw_conf(switch, p)
				switch.is_gw = True
				switch.gw_conf = gw_conf
				self.gateways[ev.switch.dp.id] = switch

		self._initialise_switch_of_tables(switch)

		ev_tu = EventSwitchEnter(switch)
		self.send_event_to_observers(ev_tu)

		ev_tu = EventTopologyUpdate(self.switches)
		self.send_event_to_observers(ev_tu)
		self.logger.info("Switch <" + str(hex(switch.switch.dp.id)) + "> connected")

	@set_ev_cls(RyuEventSwitchLeave, MAIN_DISPATCHER)
	def _handler_switch_leave(self, ev):
		"""
		Handler for event.EventSwitchLeave
		Delete a node from the topology.
		"""
		try:
			ev_tu = EventSwitchLeave(self.switches[ev.switch.dp.id])
			self.send_event_to_observers(ev_tu)

			del self.switches[ev.switch.dp.id]

			ev_tu = EventTopologyUpdate(self.switches)
			self.send_event_to_observers(ev_tu)
			self.logger.info("Switch <" + str(hex(ev.switch.dp.id)) + "> disconnected")
		except KeyError:
			pass

	@set_ev_cls(RyuEventLinkAdd, MAIN_DISPATCHER)
	def _handler_link_add(self, ev):
		"""
		Handler for event.EventLinkAdd
		Add a link to the topology.
		"""
		if ev.link.dst.dpid not in self.switches[ev.link.src.dpid].links:
			self.switches[ev.link.src.dpid].links[ev.link.dst.dpid] = []
		link = Link(ev.link)
		self.switches[ev.link.src.dpid].links[ev.link.dst.dpid].append(link)

		ev_tu = EventLinkAdd(link)
		self.send_event_to_observers(ev_tu)

		ev_tu = EventTopologyUpdate(self.switches)
		self.send_event_to_observers(ev_tu)

		self.logger.info("Link <" + str(hex(ev.link.src.dpid)) + ":" + ev.link.src.name + "> => <" +
						str(hex(ev.link.dst.dpid)) + ":" + ev.link.dst.name +"> appeared")

	@set_ev_cls(RyuEventLinkDelete, MAIN_DISPATCHER)
	def _handler_link_delete(self, ev):
		"""
		Handler for event.EventLinkDelete
		Delete a link from the topology.
		"""
		try:
			tmp_links = []
			link_to_del = None
			for l in self.switches[ev.link.src.dpid].links[ev.link.dst.dpid]:
				if ((ev.link.src.dpid == l.link.src.dpid and ev.link.src.port_no == l.link.src.port_no)
						and (ev.link.dst.dpid == l.link.dst.dpid and ev.link.dst.port_no == l.link.dst.port_no)):
					link_to_del = l
				else:
					tmp_links.append(l)

			if link_to_del:
				self.switches[ev.link.src.dpid].links[ev.link.dst.dpid] = tmp_links

				ev_tu = EventLinkDelete(link_to_del)
				self.send_event_to_observers(ev_tu)

				ev_tu = EventTopologyUpdate(self.switches)
				self.send_event_to_observers(ev_tu)
				self.logger.info("Link <" + str(hex(ev.link.src.dpid)) + ":" + ev.link.src.name + "> => <" +
							str(hex(ev.link.dst.dpid)) + ":" + ev.link.dst.name +"> disappeared")
		except KeyError:
			pass

	@set_ev_cls(RyuEventPortAdd, MAIN_DISPATCHER)
	def _handler_port_add(self, ev):
		"""
		Overwrite the legacy Ryu Event.
		"""
		try:
			switch = self.switches[ev.port.dpid]
			if self._check_if_ap_port(ev.port):
				ap_conf = self._get_ap_conf(switch, ev.port)
				switch.is_ap = True
				switch.ap_conf = ap_conf
				self.accesspoints[ev.port.dpid] = switch
			elif self._check_if_gw_port(ev.port):
				gw_conf = self._get_gw_conf(switch, ev.port)
				switch.is_gw = True
				switch.gw_conf = gw_conf
				self.gateways[ev.port.dpid] = switch

			switch.switch = get_switch(self, ev.port.dpid)[0]

			ev_tu = EventSwitchUpdate(switch)
			self.send_event_to_observers(ev_tu)

			self.logger.info("Port add: " + str(ev.port))
		except KeyError:
			pass

	@set_ev_cls(RyuEventPortModify, MAIN_DISPATCHER)
	def _handler_port_modify(self, ev):
		"""
		Overwrite the legacy Ryu Event.
		"""
		try:
			switch = self.switches[ev.port.dpid]
			switch.switch = get_switch(self, ev.port.dpid)[0]

			ev_tu = EventSwitchUpdate(switch)
			self.send_event_to_observers(ev_tu)

			self.logger.info("Port modify: " + str(ev.port))
		except KeyError:
			pass

	@set_ev_cls(RyuEventPortDelete, MAIN_DISPATCHER)
	def _handler_port_delete(self, ev):
		"""
		Overwrite the legacy Ryu Event.
		"""
		try:
			switch = self.switches[ev.port.dpid]
			if self._check_if_ap_port(ev.port):
				switch.is_ap = False
				switch.ap_conf = AccessPointConf()
				del self.accesspoints[ev.port.dpid]
			elif self._check_if_gw_port(ev.port):
				switch.is_gw = False
				switch.gw_conf = GatewayConf()
				del self.gateways[ev.port.dpid]

			switch.switch = get_switch(self, ev.port.dpid)[0]

			ev_tu = EventSwitchUpdate(switch)
			self.send_event_to_observers(ev_tu)

			self.logger.info("Port delete: " + str(ev.port))
		except KeyError:
			pass