import threading
import time
from playsound import playsound

# 警報器，當溫度超出正常範圍時觸發
class Buzzer():

    __labelList = []
    __labelShinyTask = None  # 警報進行中的執行緒，負責閃爍溫度字體
    __labelShinyActive = False
    __alertSoundTask = None  # 警報進行中的執行緒，負責不斷撥放警報語音
    __alertSoundActive = False
    __alertSoundPath = "./resource/alert.mp3"
    __alertOn = False # 是否啟動警報機制，預設關閉

    # 初始化，建立字體閃爍與警報語音撥放執行緒
    def __init__(self):
        # 判斷如果執行緒沒開啟，則建立字體閃爍的執行緒
        if self.__labelShinyTask is None:
            self.__labelShinyTask = threading.Thread(target=self.__labelShinyEvent)
            self.__labelShinyTask.setDaemon(True)
            self.__labelShinyTask.start()
        # 判斷如果執行緒沒開啟，則建立播放警報語音的執行緒
        if self.__alertSoundTask is None:
            self.__alertSoundTask = threading.Thread(target=self.__alertSoundEvent)
            self.__alertSoundTask.setDaemon(True)
            self.__alertSoundTask.start()

    # 觸發警報，除了將傳進來的溫度Label物件字體變為紅白閃爍，同時也不斷撥放警報語音
    def trigger(self, label):
        # 判斷如果關閉警報，則不觸發
        if self.__alertOn is False:
            return
        # 判斷該Label物件是否存在，存在就不需要append到需處理清單
        if label in self.__labelList:
            return
        self.__labelList.append(label)
        # 啟動字體顏色閃爍與播放告警語音
        self.__labelShinyActive = True
        self.__alertSoundActive = True

    # 關閉警報，字體顏色恢復，停止撥放語音，執行緒停止
    def close(self):
        # 判斷警報器沒有觸發，則不動作
        if self.__labelShinyActive is False:
            return
        # 恢復字體為白色
        for label in self.__labelList:
            label.config(fg="white")
        # 清空狀態與停止執行緒
        self.__labelList = []
        self.__labelShinyActive = False
        self.__alertSoundActive = False

    # 執行溫度字體閃爍動作
    def __labelShinyEvent(self):
        fgColor = ""
        while True:
            if self.__labelShinyActive is True:
                fgColor = "white" if fgColor is "red" else "red"
                for label in self.__labelList:
                    label.config(fg=fgColor)
            time.sleep(0.5)

    # 執行不斷撥放警報語音動作
    def __alertSoundEvent(self):
        while True:
            if self.__alertSoundActive is True:
                playsound(self.__alertSoundPath)
            time.sleep(0.5)

    # 給予外界判斷，是否關閉該警報器
    def switchOnOff(self, switch):
        self.__alertOn = switch


import numpy as np

class Distances(object):
    def __init__(self, P, Q):
        if sum(P) < 1e-20 or sum(Q) < 1e-20:
            raise "One or both vector are zero (empty)..."
        if len(P) != len(Q):
            raise "Arrays need to be of equal sizes..."
        # use numpy arrays for efficient coding
        P = np.array(P, dtype=float)
        Q = np.array(Q, dtype=float)
        # Correct for zero values
        P[np.where(P < 1e-20)] = 1e-20
        Q[np.where(Q < 1e-20)] = 1e-20
        self.P = P
        self.Q = Q

    def sqEuclidean(self):
        P = self.P
        Q = self.Q
        d = len(P)
        return sum((P - Q) ** 2)

    def probsymm(self):
        P = self.P
        Q = self.Q
        d = len(P)
        return 2 * sum((P - Q) ** 2 / (P + Q))

    def topsoe(self):
        P = self.P
        Q = self.Q
        return sum(P * np.log(2 * P / (P + Q)) + Q * np.log(2 * Q / (P + Q)))

    def hellinger(self):
        P = self.P
        Q = self.Q
        return 2 * np.sqrt(1 - sum(np.sqrt(P * Q)))


import numpy as np
import pylab as plt
from astropy.io import fits

#this code opens up the galaxy info fits files we need this for the redshift
hdu = fits.open('galSpecInfo-dr8.fits')

#grabbing the table associated with the file
galaxy_info_table = hdu[1].data

#opening up the file with the spectrum lines
hdu1 = fits.open('galSpecLine-dr8.fits')

#grabbing the table associated with the galaxy line file
galaxy_lines = hdu[1].data

#grabbing the spec_objID
spec_objID = galaxy_info_table['SpecObjID']

#Grabbing the redshift
redshift = galaxy_info_table['Z']

#making a filter for galaxies within our specific redhsift regime
z_filt = np.array([True if x > .025 and x < .06 else False for x in z])

#applying the filter to spec_objID and redshift
spec_objID_valid = spec_objID[z_filt]
valid_z = redshift[z_filt]

#################
#MAKING THE BPT DIAGRAM FROM SDSS GALAXIES
#################

NII_6584 = table1['NII_6584_FLUX'][z_filt]
Halpha = table1['H_ALPHA_FLUX'][z_filt]

ratio_NII_HA = []

OIII_5007 = table1['OIII_5007_FLUX'][z_filt]
Hbeta = table1['H_BETA_FLUX'][z_filt]

ratio_NII_HA = []
ratio_OIII_HB = []

for i in range(len(OIII_5007)):

    if Halpha[i] == 0 or Hbeta[i] == 0:
        continue

    elif NII_6584[i] < 0 or Halpha[i] < 0 or OIII_5007[i] < 0 or Hbeta[i] < 0:
        continue

    else:
        ratio_NII_HA.append(NII_6584[i]/Halpha[i])
        ratio_OIII_HB.append(OIII_5007[i]/Hbeta[i])

plt.figure(figsize = (10,10))
plt.loglog(ratio_NII_HA, ratio_OIII_HB)
plt.show()


import logging
import mammoth
import os
import shutil
import time
import yaml

logging.basicConfig(level=logging.INFO)

class Step:

    def __init__(self, doc):
        self.doc = doc
        self.pth = os.path.abspath('..')

    @staticmethod
    def working_dir():
        pth = os.path.abspath('..')
        if os.path.exists('{}/results_dir'.format(pth)):
            shutil.rmtree('{}/results_dir'.format(pth))             #removing the directory before executing the process.
        if not os.path.exists('{}/results_dir'.format(pth)):
            os.makedirs('{}/results_dir'.format(pth))

    @property
    def docx_to_html(self):
        with open(self.doc, 'r') as f:
            html_result = mammoth.convert_to_html(self.doc)
            logging.debug("Finished converting {} to html file".format((self.doc.split('/')[-1]).split('.')[0]))
            # output_data = self.working_dir(html_result.value)
            file_pth = '{0}/results_dir/{1}.html'.format(self.pth, (self.doc.split('/')[-1]).split('.')[0])
            with open(file_pth, 'w+') as f:
                f.write(html_result.value)

    def soso(self):
        logging.debug("Finished soso")
        pass

# decorator to calculate the entire process time
def timetaken(some_function):
    t1 = time.time()
    def wrapper_function(*args, **kwargs):
        some_function(*args, **kwargs)
        t2 = time.time()
        t3 = t2-t1
        logging.info("Process finished in {} seconds".format(t3.__round__(2)))
    return wrapper_function

@timetaken
def main():    # This is the main method that we are going to trigger.
    try:
        with open('pass.yaml', 'r') as f:
            data = yaml.safe_load(f)
            list_of_todo = data['load']
            Step.working_dir()
            for todo in list_of_todo:
                # functions to be executed are:
                logging.info('starting to {}'.format(todo['step']))
                docs = todo['docs']
                for doc in docs:
                    getattr(Step(doc), todo['action'])

    except Exception as e:
        print ("There is an error {}".format(str(e)))

if __name__ == "__main__":
    main()


model.eval()
model.binary_out = True

sensitivity, specificity = [0, 0]
stats = {'true_positives': 0, 'false_positives': 0, 'true_negatives': 0, 'false_negatives': 0}

for i, (inputs, targets) in enumerate(test_loader):

    if model.is_cuda:
        inputs, targets = inputs.cuda(), targets.cuda()
    target = targets['main'].cpu().numpy()

    outputs = model(inputs)
    pred = outputs['main']
    _, pred = torch.max(pred, 1)
    _, binary = torch.max(outputs['binary'], 1)

    pred = pred.squeeze().data.cpu().numpy()

    ###!!! Comment in/ Comment out to include/exlude binary classification !!!###
    if binary.data.numpy() == 0:
        pred = pred * 0

    target_present = 1 in target
    pred_present = 1 in pred

    if target_present and pred_present: #correctly predicted presence of a nerve
        stats['true_positives'] += 1
    elif not target_present and pred_present: #wrongly predicted presence of a nerve
        stats['false_positives'] += 1
    elif not target_present and not pred_present: #correctly predicted absence of a nerve
        stats['true_negatives'] += 1
    elif target_present and not pred_present: #wrongly predicted absence of a nerve
        stats['false_negatives'] += 1

if((stats['true_positives'] + stats['false_negatives']) > 0):
    sensitivity = stats['true_positives'] / (stats['true_positives'] + stats['false_negatives'])
if((stats['true_negatives'] + stats['false_positives']) > 0):
    specificity = stats['true_negatives'] / (stats['true_negatives'] + stats['false_positives'])

print("Stats %s \n Sensitivity: %s \n Specificity: %s" % (stats, sensitivity, specificity))


import discord

import logging
import os

from utils.bot import MyClient

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger("discord")
handler = logging.FileHandler(filename="discord.log", encoding="utf-8", mode="w")
handler.setFormatter(logging.Formatter("%(asctime)s:%(levelname)s:%(name)s: %(message)s"))
logger.addHandler(handler)

client = MyClient()

cog_directories = ['./commands', './events']

for i in range(2):
    for directory in [cog_directories[i][2:]]:
        for file in os.listdir(directory):
            if file.endswith(".py"):
                client.load_extension(f"{directory}.{file[:-3]}")

if __name__ == "__main__":
    client.run("Token")


import sys
import os
import getopt

def myfunc(argv):
    arg_json_file = ""
    arg_output = ""
    arg_user = ""
    arg_help = "{0} -j <json-file> -p <project-id> -i <instance-name> -b <bucket-name>".format(argv[0])

    try:
        opts, args = getopt.getopt(argv[1:], "hj:p:i:b:", ["help", "json-file=", "project-id=", "instance-name=", "bucket-name="])
    except:
        print(arg_help)
        sys.exit(2)

    for opt, arg in opts:
        if opt in ("-h", "--help"):
            print(arg_help) # print the help message
            sys.exit(2)
        elif opt in ("-j", "--json-file"):
            arg_json_file = arg
        elif opt in ("-p", "--project-id"):
            arg_project_id = arg
        elif opt in ("-i", "--instance-name"):
            arg_instance_name = arg
        elif opt in ("-b", "--bucket-name"):
            arg_bucket_name = arg

    print("export GOOGLE_APPLICATION_CREDENTIALS={json_file}".format(json_file=arg_json_file))
    print("export GOOGLE_CLOUD_PROJECT={project_id}".format(project_id=arg_project_id))

    # gcloud auth login

    print("gcloud beta compute --project={project_id} instances create {instance_name} --zone={zone_name} --machine-type={machine_type} --image=ubuntu-2004-focal-v20220419 --image-project=ubuntu-os-cloud".format(project_id=arg_project_id, instance_name=arg_instance_name, zone_name=arg_zone_name, machine_type=arg_machine_type))
    print("gsutil mb gs://{bucket_name}".format(bucket_name=arg_bucket_name))

    print("gsutil rsync -r data gs://gcp-bucket-andre/snakemake-testing-data")

    print("snakemake --google-lifesciences --default-remote-prefix gs://gcp-bucket-andre/snakemake-testing-data --use-conda --google-lifesciences-region us-east4-c -j 1")
    print("gcloud beta compute instances stop testinstance --zone=us-east4-c")
    print("gcloud beta compute --project=vocal-cyclist-349310 instances delete testinstance --zone=us-east4-c")
    print("gsutil rm gs://bucket-test2-andre/*")
    print("gsutil rb gs://bucket-test2-andre")

if __name__ == "__main__":
    myfunc(sys.argv)


import os
import csv
import json
import socket
import requests
import ipaddress
from Constants import *
from scapy.all import *
from pprint import pprint
from ipwhois import IPWhois
from PacketsRegister import PacketsRegister

debug = False

# TODO: Consider having library instead of class
# TODO: Comprehensive Sankey? flow data NET-DESC > IPS > PORTS/SERVICES > IPS > PORTS/SERVICES > NET-DESC

# TODO: FILTER TOR EXIT NODES
# TODO: FILTER VPNS
# TODO: Filter universities
# TODO: FIlter sinlge-packet university sources?

# NOTE: Very useful list of VPN IPs @ https://github.com/ejrv/VPNs

class TIRegister:
    """ PER-FLOW TI register. Bound to data file source (a json register)
        Serves as a collector for all file-related intelligence information
    """

    # Intelligence to get:
    #   - IPs information (source/dest) such as location, number of associated flows
    #   - Ports/services used. Maybe focus first on destination ports of interested device

    def __init__(self, data, devname):
        """ Initialization for TI register
            Params:
            - data:     ABSOLUTE_PATH to pcap file to get information from
                    OR  ASOLUTE_PATH to json file derived from PacketsRegister
        """

        self.devname = devname

        # Data initialization
        if not os.path.isfile(data):
            raise ValueError('>>> Unknown or invalid data: {}\n Data parameter must be a file path.'.format(data))
        if not (data.endswith('.json') or data.endswith('.pcap')):
            raise ValueError('>>> Unsupported data format for TIRegister instantiation: {}\nSupported formats are ".pcap" and ".json", \
                where the json file is expected to be of PacketsRegister type.'.format(data))

        self.data = data

        # Rejected flows population
        if self.data.endswith('.json'):
            register = PacketsRegister.from_json(self.data)
        elif self.data.endswith('.pcap'):
            print('Gathering flows from pcap file {}....\n'.format(data))
            register = PacketsRegister(type='RejectedTrafficOnly')
            register.populate_flows_from_pcap(self.data)
        self.rejected_flows = register.get_core_flows(REJECTED_TRAFFIC)

        self.ips_info = {
            # dict content: ip_address : {@staticmethod.ip_info_entry()}}
            ORIGIN_SOURCE_TAG : {},
            ORIGIN_DESTINATION_TAG : {}
        }
        self.ports_info = {
            # dict content: port/service: {@staticmethod.port_info_entry()}}
            #                             {'number' : port_number, 'transport_proto' : tr_proto, 'cntr_flows' : cntr_flows}
            ORIGIN_SOURCE_TAG : {},
            ORIGIN_DESTINATION_TAG : {}
        }

        # Notorious backends IP addresses spaces
        self.amazon_ip_ranges = {}
        self.microsoft_ip_ranges = {}
        self.google_ip_ranges = {}

    def to_json(self):
        return json.dumps(self, default=lambda o: o.__dict__, indent=4)

    ########################################################################
    #                            GET IPS INFO                              #
    ########################################################################

    def gather_ips_infos(self, api='geoip'):
        """ Gathers IP-address related information and stores them to class instance registers.
            Populates both SRC and DST IPs info registers.

            Params:
            - api: supports either 'geoip' or 'ipwhois', specifies the method for IP information resolution

            NOTE (s)
                - It gathers and processes the data from PacketsRegister.get_core_flows() format
                - Behaves the same way in case of monodirectional flows
        """
        # Refer to PacketsRegister class, generated from json data

        if not api == 'geoip' or api == 'ipwhois':
            raise ValueError('Unsupported or unrecognized "api" parameter for IPs info resolution: {}\nSupported values are "geoip" or "ipwhois".'.format(api))

        for rejected_flow in self.rejected_flows:

            # Get flow source and testination IPs
            src_addr = str(rejected_flow[SIP_TAG])
            dst_addr = str(rejected_flow[DIP_TAG])

            print('processing src_addr, dst_addr: {}, {}'.format(src_addr, dst_addr)) if debug else None

            is_src_addr_registered = src_addr in self.ips_info[ORIGIN_SOURCE_TAG].keys()
            is_dst_addr_registered = dst_addr in self.ips_info[ORIGIN_DESTINATION_TAG].keys()

            if is_src_addr_registered:
                # NOTE: ips_info entries are as returned by class.ip_info_entry()
                print('src_addr [ {} ] is already registered'.format(src_addr)) if debug else None
                self.ips_info[ORIGIN_SOURCE_TAG][src_addr]['cntr_flows'] += 1
            if is_dst_addr_registered:
                print('dst_addr [ {} ] is already registered'.format(dst_addr)) if debug else None
                self.ips_info[ORIGIN_DESTINATION_TAG][dst_addr]['cntr_flows'] += 1

            # Append new IP info entries to registers. They will be populated (/resolved) after, according to the specified API parameter
            if not is_src_addr_registered:
                if ipaddress.ip_address(src_addr).is_private:
                    self.ips_info[ORIGIN_SOURCE_TAG][src_addr] = TIRegister.ip_info_entry(LOCAL_ADDRESS_TAG, LOCAL_ADDRESS_TAG, 0, 0, 1)
                else:
                    self.ips_info[ORIGIN_SOURCE_TAG][src_addr] = TIRegister.unresolved_ip_entry() #self.query_ip_whois(src_addr)

            if not is_dst_addr_registered:
                if ipaddress.ip_address(dst_addr).is_private:
                    self.ips_info[ORIGIN_DESTINATION_TAG][dst_addr] = TIRegister.ip_info_entry(LOCAL_ADDRESS_TAG, LOCAL_ADDRESS_TAG, 0, 0, 1)
                else:
                    self.ips_info[ORIGIN_DESTINATION_TAG][dst_addr] = TIRegister.unresolved_ip_entry() #self.query_ip_whois(dst_addr)

        # Resolve ip infos with specified API
        if (api == 'geoip'):
            self.resolve_ips_info_with_geoip()
        elif (api == 'ipwhois'):
            self.resolve_ips_info_with_ipwhois()

    def resolve_ips_info_with_geoip(self):
        # Resolve information in batches
        # GEOIP APIS Info at https://ip-api.com/docs/api:batch
        # NOTE: UP TO 100 REQUESTS PER QUERY
        src_geoip_queries = []
        dst_geoip_queries = []

        print('################## GEOIPs QUERIES ##################') if debug else None

        for ip in self.ips_info[ORIGIN_SOURCE_TAG].keys():
            src_geoip_queries.append({"query":str(ip)})
        for ip in self.ips_info[ORIGIN_DESTINATION_TAG].keys():
            dst_geoip_queries.append({"query":str(ip)})

        print('src_geoip queries list length: {}'.format(len(src_geoip_queries))) if debug else None
        print('dst_geoip queries list length: {}'.format(len(dst_geoip_queries))) if debug else None

        # APIS limit of 100 queries per batch,
        # managed with list of sublists (ref code: https://www.geeksforgeeks.org/break-list-chunks-size-n-python/)
        n = 100
        src_geoip_queries_batches = [src_geoip_queries[i:i+n] for i in range(0, len(src_geoip_queries), n)]
        dst_geoip_queries_batches = [dst_geoip_queries[i:i+n] for i in range(0, len(dst_geoip_queries), n)]

        try:
            src_response = []
            for batch in src_geoip_queries_batches:
                src_response.extend(requests.post(GEOIP_API_BATCH_URL, json=batch).json())

            dst_response = []
            for batch in dst_geoip_queries_batches:
                dst_response.extend(requests.post(GEOIP_API_BATCH_URL, json=batch).json())

            for ip_info in src_response:
                ref_ip = ip_info['query']
                entry_data = self.ips_info[ORIGIN_SOURCE_TAG][ref_ip]
                if ip_info['status'] == 'success':
                    # Refer to query param (the IP from the keys), and populate (lat, lon) data
                    self.ips_info[ORIGIN_SOURCE_TAG][ref_ip] = TIRegister.ip_info_entry(ip_info['countryCode'], ip_info['isp'], ip_info['lat'], ip_info['lon'], entry_data['cntr_flows'])
                else:
                    pass # Ignore

            for ip_info in dst_response:
                ref_ip = ip_info['query']
                entry_data = self.ips_info[ORIGIN_DESTINATION_TAG][ref_ip]
                if ip_info['status'] == 'success':
                    # Refer to query param (the IP from the keys), and populate (lat, lon) data
                    self.ips_info[ORIGIN_DESTINATION_TAG][ref_ip] = TIRegister.ip_info_entry(ip_info['countryCode'], ip_info['isp'], ip_info['lat'], ip_info['lon'], entry_data['cntr_flows'])
                else:
                    pass # Ignore

        except Exception as e:
            raise ValueError('Failed to solve batch IP geo-lookup requests - reference class data attribute: {}'.format(self.data))

    def resolve_ips_info_with_ipwhois(self):
        # NOTE: Does not resolve latitude and longitude
        # TODO: Resolve latitude and longitude...
        for ip in self.ips_info[ORIGIN_SOURCE_TAG].keys():
            if not self.ips_info[ORIGIN_SOURCE_TAG][ip]['desc'] == LOCAL_ADDRESS_TAG:
                self.ips_info[ORIGIN_SOURCE_TAG][ip] = self.query_ip_whois(ip)
        for ip in self.ips_info[ORIGIN_DESTINATION_TAG].keys():
            if not self.ips_info[ORIGIN_DESTINATION_TAG][ip]['desc'] == LOCAL_ADDRESS_TAG:
                self.ips_info[ORIGIN_DESTINATION_TAG][ip] = self.query_ip_whois(ip)
    def query_ip_whois(self, ip_addr):
        """ Given an ip_address, returns a dict containing IP-related information. Uses the IPWhois library
        """
        ret = None
        try:
            dom_obj = IPWhois(ip_addr)
            dom = dom_obj.lookup_whois()
            country_code = dom[IPWHOIS_ASN_CC_TAG]
            asn_desription = dom[IPWHOIS_ASN_DESC_TAG]

            # TODO: Add domain (from abuse email or emails)

            lat, lon = 0, 0 # Populated after cycle not to exceed API limits: https://ip-api.com/docs/api:batch
            ret = TIRegister.ip_info_entry(country_code, asn_desription, lat, lon, 1)

        except Exception as e:
            print('Exception: {}'.format(e)) if debug else None
            if str(e).__contains__('Multicast'):
                ret = TIRegister.ip_info_entry('Multicast', 'Multicast', 0, 0, 1)
            else:
                ret = TIRegister.ip_info_entry('Excepted', 'Excepted', 0, 0, 1)

        return ret

    ########################################################################
    #                           GET PORTS INFO                             #
    ########################################################################

    # TODO: Merge with ips function? Cycles over whole thing just once, dumps all info?
    def gather_ports_infos(self):
        """ Gathers used-ports related information and stores them to class instance register.
            Params:
                - side: string (constant)
                    ORIGIN_SOURCE_TAG : get ports infos of source port fields from input flows (self.data > to flows)
                    ORIGIN_DESTINATION_TAG : as above but takes destination ports
            NOTE:
                It gathers and processes the data from PacketsRegister.get_core_flows() format
        """

        for rejected_flow in self.rejected_flows:

            src_port = int(rejected_flow[SPORT_TAG]) if rejected_flow[SPORT_TAG] != '?' else -1
            dst_port = int(rejected_flow[DPORT_TAG]) if rejected_flow[DPORT_TAG] != '?' else -1

            if rejected_flow[TRANSPORT_PROTO_TAG] == '6': proto = 'tcp'
            elif rejected_flow[TRANSPORT_PROTO_TAG] == '17': proto = 'udp'
            else: proto = None
            print('processing sport -> dport: {} -> {}'.format(src_port, dst_port)) if debug else None

            try:
                src_service = socket.getservbyport(src_port, proto)
            except Exception as e:
                src_service = EPHEMERAL_TAG
                #src_service = str(src_port)

            try:
                dst_service = socket.getservbyport(dst_port, proto)
            except Exception as e:
                dst_service = EPHEMERAL_TAG
                #dst_service = str(dst_port)

            if src_service in self.ports_info[ORIGIN_SOURCE_TAG].keys():
                # Update counter of flows from specified port
                print('port/service {}/{} already in src ports register'.format(src_port, src_service)) if debug else None
                self.ports_info[ORIGIN_SOURCE_TAG][src_service]['cntr_flows'] += 1 # Counter is last index of list entry
            else:
                # Populate new entry
                print('Retrieving infos for src port/service {}/{}'.format(src_port, src_service)) if debug else None
                self.ports_info[ORIGIN_SOURCE_TAG][src_service] = TIRegister.port_info_entry(src_port, proto, 1)

            if dst_service in self.ports_info[ORIGIN_DESTINATION_TAG].keys():
                print('port/service {}/{} already in dst ports register'.format(dst_port, dst_service)) if debug else None
                self.ports_info[ORIGIN_DESTINATION_TAG][dst_service]['cntr_flows'] += 1 # Counter is last index of list entry
            else:
                print('Retrieving infos for dst port/service {}/{}'.format(dst_port, dst_service)) if debug else None
                self.ports_info[ORIGIN_DESTINATION_TAG][dst_service] = TIRegister.port_info_entry(dst_port, proto, 1)

    ##################################################################
    #                      Rule-out filtering                        #
    ##################################################################

    def filter_out_known_backend_flows_from_csv(self, csv_file):
        pass

    def filter_out_known_backends_pkts_from_pcap(self, pcap_file=None, flow_based=False):
        # TODO: INEFFICIENT, IMPROVE EFFICIENCY
        # NOTE: SRC addresses can be assumed benign, but malicious communication to DST backend ip addresses can happen. How TODO?
        #   > NOTE: Assuming that the scenario where BOTH SRC and DST are NOT-KNOWN is SUSPICIOUS
        """ Function that filters out all traffic that is very likely not harmful, as in
            it pertains to
                - IP Addresses from the Vendor
                - Amazon backends
                - Google backends
                - Microsoft backends
                - Notorious cloud supports and/or analysis
                - National security agencies?

                ALL AMAZON IPs
                https://docs.aws.amazon.com/general/latest/gr/aws-ip-ranges.html#filter-json-file

                ALL MICROSOFT IPs
                https://www.microsoft.com/en-us/download/confirmation.aspx?id=53602

                ALL GOOGLE IPs
                Google services https://www.gstatic.com/ipranges/goog.json
                Google CLOUD https://www.gstatic.com/ipranges/cloud.json

                ALL APPLE IPs - BEWARE NOT OFFICIAL
                https://ipinfo.io/AS714#blocks

            Params:
                pcap_file=None : pcap file to filter known backends from. If set to none, tries to use TIRegister self file.
                                checking if it's a pcap. Otherwise, has to be run with a generic pcap file

        """

        # Checks
        if pcap_file is not None and not os.path.isfile(pcap_file):
            raise ValueError('>>> File not found: {} \nBe sure to pass in a valid reachable path.'.format(pcap_file))
        if pcap_file is not None and not pcap_file.endswith('.pcap'):
            raise ValueError('>>> Passed file is not .pcap. Only .pcap is supported. File: {}'.format(pcap_file))
        file_ref = ''
        if pcap_file is None and self.data.endswith('.pcap'):
            file_ref = self.data
            print('\n>>> Generating known-backends-filtered rejected pcap from TIRegister instance data file: {}'.format(self.data))
        elif pcap_file is not None:
            file_ref = pcap_file
            print('\n>>> Generating known-backends-filtered rejected pcap from function argument file: {}'.format(pcap_file))
        if file_ref == '':
            raise ValueError('\n>>> Unable to resolve pcap file to filter. Either generate TIRegister instance with a pcap file as data param, or pass a pcap to this function')
        # / Chekcs

        out_name = os.path.splitext(os.path.basename(os.path.normpath(file_ref)))[0] + SUSPICIOUS_DATA_FILE_TAG + '.pcap'
        output_pcap = OUTPUTS_FOLDER + self.devname + '/' + out_name

        # NOTE: I pondered over having the filtered_backends register refer to already solved 'ranges', but DB-wise, I think
        #       it's better to have IP addresses as unique table keys, with respective information, eventually replicated over other IP addresses.
        #       I believe this would make practical the grouping, unions and retrieval of various information
        filtered_backends_ips = {}
        sus_ips = {}
        outpcap_writer = PcapWriter(output_pcap, append=False, sync=True)
        util_reg = PacketsRegister(type='Utility')

        # Inner per-packet scapy filtering function
        def refilter_on_knonw_backends(outpcap_writer, filtered_backends_ips, register):
            def inner(pkt):
                register.increment_tot_packets_counter()
                simple_progress_print(register.get_counter_tot_packets())

                if pkt.haslayer('IP'):
                    net_tag = 'IP'
                elif pkt.haslayer('IPv6'):
                    net_tag = 'IPv6'
                else:
                    raise ValueError('\n>>> Impossible to filter IPs from file, excepted packet without IP/v6 layer: {}'.format(pkt.summary()))
                    # TODO: Consider non-blocking ignore handling

                src = pkt[net_tag].src
                dst = pkt[net_tag].dst

                notorious_src = False
                notorious_dst = False

                src_already_sus = False
                dst_already_sus = False

                if src in sus_ips.keys():
                    #print('MATCH ON SUS SOURCE') if debug else None
                    src_already_sus = True
                    sus_ips[src] +=1
                if dst in sus_ips.keys():
                    #print('MATCH ON SUS DESTINATION') if debug else None
                    dst_already_sus = True
                    sus_ips[dst] +=1

                if not src_already_sus:
                    if src in filtered_backends_ips.keys():
                        print('MATCH ON SOURCE') if debug else None
                        notorious_src = True
                        filtered_backends_ips[src]['counter_src'] += 1
                    else:
                        print('NEW PACKET SRC {}'.format(src)) if debug else None
                        known_backend_src, service_src, range_src = self.is_known_backend(src)
                        if known_backend_src:
                            notorious_src = True
                            filtered_backends_ips[src] = {}
                            filtered_backends_ips[src]['service'] = service_src
                            filtered_backends_ips[src]['range'] = range_src
                            filtered_backends_ips[src]['counter_src'] = 1
                            filtered_backends_ips[src]['counter_dst'] = 0

                if not dst_already_sus:
                    if dst in filtered_backends_ips.keys():
                        print('MATCH ON DESTINATION') if debug else None
                        notorious_dst = True
                        filtered_backends_ips[dst]['counter_dst'] += 1
                    else:
                        print('NEW PACKET DST {}'.format(dst)) if debug else None
                        known_backend_dst, service_dst, range_dst = self.is_known_backend(dst)
                        if known_backend_dst:
                            notorious_dst = True
                            filtered_backends_ips[dst] = {}
                            filtered_backends_ips[dst]['service'] = service_dst
                            filtered_backends_ips[dst]['range'] = range_dst
                            filtered_backends_ips[dst]['counter_src'] = 0
                            filtered_backends_ips[dst]['counter_dst'] = 1

                # TODO: Add ranges to use for catching to utility register

                if not notorious_src and not src_already_sus: sus_ips[src] = 1
                if not notorious_dst and not dst_already_sus: sus_ips[dst] = 1

                # Save packet as suspicious if neither src and dst are known services
                if not notorious_src and not notorious_dst:
                    outpcap_writer.write(pkt)

            return inner

        sniff(offline=file_ref, prn=refilter_on_knonw_backends(outpcap_writer, filtered_backends_ips, util_reg), store=10)
        print('\n>>> The capture containing traffic from only non-notorious addresses has been saved at > \n{}'.format(output_pcap))

    ########################################################################
    #                               UTILITY                                #
    ########################################################################

    ############################## IPs Utility ##############################

    # Utility ip_info_entry
    @staticmethod
    def ip_info_entry(country_code, desc, lat, lon, cntr_flows):
        return {'country_code' : country_code, 'desc' : desc, 'lat_lon' : (lat, lon), 'cntr_flows' : cntr_flows}
    @staticmethod
    def unresolved_ip_entry():
        return TIRegister.ip_info_entry(UNRESOLVED_TAG, UNRESOLVED_TAG, 0, 0, 1)

    def get_ips_infos(self, side):
        """ Returns list of per-flow IP information, as saved in the ips_info instance dictionary
            Params:
            - side: either ORIGIN_SOURCE_TAG or ORIGIN_DESTINATION_TAG,
                Specifies wether to get ips_info about
                    source addresses of flows in traffic data, or
                    destination addresses of flows in traffic data
        """

        # Parameter checks
        if not (side == ORIGIN_SOURCE_TAG or side == ORIGIN_DESTINATION_TAG):
            print('Unknown IP side type for register: {}. Accepted sides: {}, {}'.format(side, ORIGIN_SOURCE_TAG, ORIGIN_DESTINATION_TAG))

        if len(self.ips_info[side]) == 0:
            raise ValueError('Looks like registers are empty. Try run <ti_register>.gather_ips_info() first.')

        return self.ips_info[side]

    def get_ips_graph_data_description_per_flows(self):
        """ Gives information of flow-based frequencies of IP addresses found in source or destination fields, taken
                from the ips_info class register
        """
        if len(self.ips_info[ORIGIN_DESTINATION_TAG]) == 0 or len(self.ips_info[ORIGIN_SOURCE_TAG]) == 0:
            raise ValueError('Looks like registers are empty. Try run <ti_register>.gather_ips_info() first.')

        src_ips_graph_data = {}
        dst_ips_graph_data = {}

        src_ips_info = self.ips_info[ORIGIN_SOURCE_TAG]
        dst_ips_info = self.ips_info[ORIGIN_DESTINATION_TAG]

        for ip in src_ips_info.keys():
            asn = src_ips_info[ip]['desc']
            if asn in src_ips_graph_data.keys():
                src_ips_graph_data[asn] += int(src_ips_info[ip]['cntr_flows'])
            else:
                src_ips_graph_data[asn] = int(src_ips_info[ip]['cntr_flows'])

        for ip in dst_ips_info.keys():
            asn = dst_ips_info[ip]['desc']
            if asn in dst_ips_graph_data.keys():
                dst_ips_graph_data[asn] += int(dst_ips_info[ip]['cntr_flows'])
            else:
                dst_ips_graph_data[asn] = int(dst_ips_info[ip]['cntr_flows'])

        # Order by number of flows
        src_ips_graph_data = {k: v for k, v in sorted(src_ips_graph_data.items(), key=lambda item : (item[1], item[-1]))}
        dst_ips_graph_data = {k: v for k, v in sorted(dst_ips_graph_data.items(), key=lambda item : (item[1], item[-1]))}

        return src_ips_graph_data, dst_ips_graph_data

    ############################## Ports Utility ##############################

    @staticmethod
    def port_info_entry(port_number, tr_proto, cntr_flows):
        return {'number' : port_number, 'transport_proto' : tr_proto, 'cntr_flows' : cntr_flows}

    def get_ports_infos(self, side):
        """ Returns list of per-flow ports information, as saved in the ports_info instance dictionary
            Params:
            - side: either ORIGIN_SOURCE_TAG or ORIGIN_DESTINATION_TAG,
                Specifies wether to get ports_info about
                    source ports of flows in traffic data, or
                    destination ports of flows in traffic data
        """

        # Parameter checks
        if not (side == ORIGIN_SOURCE_TAG or side == ORIGIN_DESTINATION_TAG):
            print('Unknown origin side type for register: {}. Accepted sides: {}, {}'.format(side, ORIGIN_SOURCE_TAG, ORIGIN_DESTINATION_TAG))

        if len(self.ports_info[side]) == 0:
            raise ValueError('Looks like registers are empty. Try run <ti_register>.gather_ports_info() first.')
        return self.ports_info[side]

    def get_ports_graph_data_service_per_flows(self):
        """ Gives information of per-flow frequency of utilized ports in source and destination fields, from the ports_info
                class register.
            Returns:
                - <origin>_ports_graphs_data : {service/port : #flows}
                - src_dst_ports_graph_data = [src_port, dst_port, #packets]
        """
        if len(self.ports_info[ORIGIN_DESTINATION_TAG]) == 0 or len(self.ports_info[ORIGIN_SOURCE_TAG]) == 0:
            raise ValueError('Looks like registers are empty. Try run <ti_register>.gather_ports_info() first.')

        src_ports_graph_data = {}
        dst_ports_graph_data = {}

        src_dst_ports_graph_data = []

        src_ports_info = self.ports_info[ORIGIN_SOURCE_TAG]
        dst_ports_info = self.ports_info[ORIGIN_DESTINATION_TAG]

        for service in src_ports_info.keys():
            if service in src_ports_graph_data.keys():
                src_ports_graph_data[service] += int(src_ports_info[service]['cntr_flows'])
            else:
                src_ports_graph_data[service] = int(src_ports_info[service]['cntr_flows'])

        for service in dst_ports_info.keys():
            if service in dst_ports_graph_data.keys():
                dst_ports_graph_data[service] += int(dst_ports_info[service]['cntr_flows'])
            else:
                dst_ports_graph_data[service] = int(dst_ports_info[service]['cntr_flows'])

        for rejected_flow in self.rejected_flows:
            # TODO: Add UDP/TCP information
            src_port = int(rejected_flow[SPORT_TAG]) if rejected_flow[SPORT_TAG] != '?' else -1
            dst_port = int(rejected_flow[DPORT_TAG]) if rejected_flow[DPORT_TAG] != '?' else -1

            if rejected_flow[TRANSPORT_PROTO_TAG] == '6': proto = 'tcp'
            elif rejected_flow[TRANSPORT_PROTO_TAG] == '17': proto = 'udp'
            else: proto = None

            try:
                src_service = socket.getservbyport(src_port, proto)
            except Exception as e:
                src_service = EPHEMERAL_TAG
                #src_service = str(src_port)

            try:
                dst_service = socket.getservbyport(dst_port, proto)
            except Exception as e:
                #dst_service = str(dst_port)
                dst_service = EPHEMERAL_TAG

            src_dst_ports_graph_data.append([src_service, dst_service, rejected_flow[PACKETS_NUMBER_TAG]])

        """
            # Merge one-flow ports
            src_one_flow_only = {SINGLETON_SRC_PORT_PER_FLOW_TAG : 0}
            for k, v in src_ports_graph_data.items():
                if int(v) == 1:
                    src_one_flow_only[SINGLETON_SRC_PORT_PER_FLOW_TAG] += v
            src_ports_graph_data[SINGLETON_SRC_PORT_PER_FLOW_TAG] = src_one_flow_only[SINGLETON_SRC_PORT_PER_FLOW_TAG]

            dst_one_flow_only = {SINGLETON_DST_PORT_PER_FLOW_TAG : 0}
            for v in dst_ports_graph_data.values():
                if int(v) == 1:
                    dst_one_flow_only[SINGLETON_DST_PORT_PER_FLOW_TAG] += v
            dst_ports_graph_data[SINGLETON_DST_PORT_PER_FLOW_TAG] = dst_one_flow_only[SINGLETON_DST_PORT_PER_FLOW_TAG]

            # for src_dst_ports_graph_data, single flow is given on single packet

            src_ports_graph_data = {k: v for k, v in src_ports_graph_data.items() if int(v) > 1}
            dst_ports_graph_data = {k: v for k, v in dst_ports_graph_data.items() if int(v) > 1}

            src_ports_graph_data = {k: v for k, v in sorted(src_ports_graph_data.items(), key=lambda item : item[1], reverse=True) if int(v) > 1}
            dst_ports_graph_data = {k: v for k, v in sorted(dst_ports_graph_data.items(), key=lambda item : item[1], reverse=True) if int(v) > 1}
        """
        return src_ports_graph_data, dst_ports_graph_data, src_dst_ports_graph_data

    ############################## Class Utility ##############################

    def populate_known_ranges(self):
        """ Populates class dictionaries with IP ranges from well-known service providers
        """
        # Amazon
        try:
            amz_ip_ranges = requests.get('https://ip-ranges.amazonaws.com/ip-ranges.json').json()['prefixes']
            amazon_ips = {data['ip_prefix']: data['service'] for data in amz_ip_ranges}
            self.amazon_ip_ranges = amazon_ips
        except Exception as e:
            print('>>> {}'.format(e))
            print('>>> Failed to fetch IP ranges from Amazon @ https://ip-ranges.amazonaws.com/ip-ranges.json')

        # Microsoft
        try:
            msft_ip_ranges = {}
            with open(MICROSOFT_IP_RANGES_CSV, newline='') as csv_file:
                csv_reader = csv.DictReader(csv_file, delimiter=',')
                for row in csv_reader:
                    msft_ip_ranges[row['Prefix']] = row['Type']
            self.microsoft_ip_ranges = msft_ip_ranges
        except Exception as e:
            print('>>> {}'.format(e))
            print('>>> Failed to fetch IP ranges from Microsoft @ file {}'.format(MICROSOFT_IP_RANGES_CSV))

        # Google
        try:
            ggl_ip_ranges = requests.get('https://www.gstatic.com/ipranges/goog.json').json()['prefixes']
            pprint(ggl_ip_ranges) if debug else None
        except Exception as e:
            print('>>> {}'.format(e))
            print('>>> Failed to fetch IP ranges from Google @ https://www.gstatic.com/ipranges/goog.json')
        try:
            ggl_cloud_ip_ranges = requests.get('https://www.gstatic.com/ipranges/cloud.json').json()['prefixes']
            pprint(ggl_cloud_ip_ranges) if debug else None
        except Exception as e:
            print('>>> {}'.format(e))
            print('>>> Failed to fetch cloud IP ranges from Google Clouds @ https://www.gstatic.com/ipranges/cloud.json')
        ggl_ips = {list(data.values())[0] : list(data.keys())[0] for data in ggl_ip_ranges}
        ggl_cl_ips = {list(data.values())[0] : data['scope'] for data in ggl_cloud_ip_ranges}
        pprint(ggl_ips) if debug else None
        pprint(ggl_cl_ips) if debug else None
        self.google_ip_ranges = {**ggl_ips, **ggl_cl_ips}
        pprint(self.google_ip_ranges) if debug else None

    def is_known_vpn(self, ip_addr):
        """ Checks saved numpy array list of known VPN IP ranges and addresses
        """
        ip = ''
        i = 0
        try:
            ip = ipaddress.ip_address(ip_addr)
        except Exception as e:
            print(e)
            print('Could not solve ip [ {} ] to a valid ipaddress library object'.format(ip_addr))
        if (type(ip) == ipaddress.IPv4Address):
            for item in KNOWN_IPV4_VPNS:
                i += 1
                print(i)
                if ip in ipaddress.ip_network(item):
                    return True, item
        elif (type(ip) == ipaddress.IPv6Address):
            for item in KNOWN_IPV6_VPNS:
                if ip in ipaddress.ip_network(item):
                    return True, item
        else:
            raise ValueError('Could not match ip address [ {} ] to a valid ipaddress library type'.format(ip_addr))
        # Did not return anything before, so no matches
        return False, None

    def is_known_backend(self, ip_addr):

        # TODO: Make more efficient with IPv4, IPv6 distinction, and smarter lookup iterating on IP param possible subnets
        # REVERSE(/8, /9, ..., /23, /24) for IPv4 (constant time check instead of whole register)
        # Idk how IPv6 works exactly

        for range in self.amazon_ip_ranges.keys():
            if ipaddress.ip_address(ip_addr) in ipaddress.ip_network(range):
                return True, AMAZON_ADDRESS_TAG, range
        for range in self.microsoft_ip_ranges.keys():
            if ipaddress.ip_address(ip_addr) in ipaddress.ip_network(range):
                return True, MICROSOFT_ADDRESS_TAG, range
        for range in self.google_ip_ranges.keys():
            if ipaddress.ip_address(ip_addr) in ipaddress.ip_network(range):
                return True, GOOGLE_ADDRESS_TAG, range

        # If here, address was not resolved
        return False, None, None

if __name__ == '__main__':
    file = OUTPUTS_FOLDER + 'ieee-ezviz-complete/mirai-httpflooding-all-ezviz-rejected.json'
    ti_reg_test = TIRegister(file, 'ieee-ezviz')
    ti_reg_test.populate_known_ranges()
    #pcap = OUTPUTS_FOLDER + 'ieee-ezviz-complete/mirai-httpflooding-all-ezviz-rejected.pcap'
    pcap = OUTPUTS_FOLDER + 'ieee-ezviz/mirai-httpflooding-all-ezviz-rejected-sus.pcap'
    ti_reg_test.filter_out_known_backends_pkts_from_pcap(pcap_file=pcap)


from project.task import Task

class Section:

    def __init__(self, name):
        self.name = name
        self.tasks = []

    def add_task(self, new_task: Task):
        if new_task in self.tasks:
            return f"Task is already in the section {self.name}"
        self.tasks.append(new_task)
        return f"Task {Task.details(new_task)} is added to the section"

    def complete_task(self, task_name):
        for current_task in self.tasks:
            if current_task.name == task_name:
                current_task.completed = True
            return f"Completed task {task_name}"
        return f"Could not find task with the name {task_name}"

    def clean_section(self):
        cleared = 0
        for current_task in self.tasks:
            if current_task.completed:
                self.tasks.remove(current_task)
                cleared += 1
        return f"Cleared {cleared} tasks."

    def view_section(self):
        x = "\n"
        result = f"Section {self.name}:{x}"
        for obj in self.tasks:
            result += obj.details()
            result += x

        return result.strip()


class Node():
	"""
	Binary Search Tree Node, represented by Pointers to its parent, its left child, and right child
	"""
	def __init__(self, val=None, parent=None, lchild=None, rchild=None):
		self.val = val
		self.parent = parent
		self.lchild = lchild
		self.rchild = rchild

class BinarySearchTree():
	"""
	Binary Search Tree, where each left child is less than parent, and each right child is greater than parent
	There are no duplicate values in this implementation
	It is important to recognize that a BST with the same values can have different structrue based on insertion order
	The smaller the height of the tree, the more efficient it is
	"""
	def __init__(self):
		self.length = 0
		self.root = None

	def search(self, val):
		# Empty Check
		if self.root == None:
			return None

		# Search for the proper placement of given value
		current_node = self.root

		while current_node != None and current_node.val != val:
			if val < current_node.val:
				current_node = current_node.lchild
			else:
				current_node = current_node.rchild

		return current_node

	def insert(self, val):
		# First, make sure this value isnt already in the BST
		#if self.search(val) == None:
			#return

		to_insert = Node(val)

		# if this is the first insertion, make insertion the root
		if self.root == None:
			self.root = to_insert
			return

		current_node = self.root
		current_parent = None

		# Traverse through the BST based on value
		while current_node != None:
			# Move one level down the BST
			current_parent = current_node

			if val < current_parent.val:
				current_node = current_parent.lchild
			else:
				current_node = current_parent.rchild

		to_insert.parent = current_parent

		if val < current_parent.val:
			current_parent.lchild = to_insert
		elif val > current_parent.val:
			current_parent.rchild = to_insert

	def delete(self, val):
		# first get the val
		node = self.search(val)
		# if its not in the tree, then i guess we can just say it was successfully deleted
		if node == None:
			return 0

		# if no lchild, replace node with its rchild (even if its None), effectively handling no children case
		if node.lchild == None:
			parent = node.parent
			node = node.rchild
			node.parent = parent
			return 0

		# same as above, but for rchild
		elif node.rchild == None:
			parent = node.parent
			node = node.lchild
			node.parent = parent
			return 0

		else:
			# if successor is rchild, replace node with rchild
			if self.get_successor(node.val) == node.rchild:
				parent  = node.parent
				lchild = node.lchild
				rchild = node.rchild
				node = self.get_successor(node.val)
				print("hello", node.val)
				node.parent = parent
				node.lchild = lchild
				node.rchild = rchild
				return 0

			# this is where it gets weird
			# if successor is not rchild, then replace successor(p) with its rchild, and replace node with successor
			else:
				parent = node.parent
				lchild = node.lchild
				rchild = node.rchild
				p = self.get_successor(node.val)
				p.parent.lchild = p.rchild
				node = p
				node.parent = parent
				node.lchild = lchild
				node.rchild = rchild
				return 0

	def get_max(self, node=None):
		# return the node with max value
		if node == None:
			node = self.root
		while node.rchild != None:
			node = node.rchild

		return node

	def get_min(self, node):
		# return the node with min value
		if node == None:
			node = self.root
		while node.lchild != None:
			node = node.lchild

		return node

	def get_successor(self, val):
		# return the smallest key that is greater than parameter val, None if val is not in the tree
		# first, search for this val
		node = self.search(val)
		if node == None:
			return None

		# if there is a right subtree, then it is the minimum of that
		if node.rchild != None:
			return self.get_min(node.rchild)
		# else, it is the first ancestor that is greater than node
		while node.parent != None and node.parent.val <= node.val:
			node = node.parent
		return node.parent

	def get_predecessor(self, val):
		# return the greatest key that is less than parameter val, None if val is not in the tree
		# search for val
		node = self.search(val)
		if node == None:
			return None

		# if there is a left subtree, then it is the max of that tree
		if node.lchild != None:
			return self.get_max(node.lchild)
		# else, it is first ancestor that is less than val
		while node.parent != None and node.parent.val >= node.val:
			node = node.parent
		return node.parent

	def __repr__(self):
		string = str(self.root.val) + str(self.root.lchild.val) + str(self.root.lchild.rchild.val) + str(self.root.rchild.val)
		return string

if __name__ == '__main__':
	array = [15, 6, 7, 13, 3, 2, 9, 4, 18, 20]
	bst = BinarySearchTree()

	for i in range(0, len(array)):
		#print (array[i])
		bst.insert(array[i])

	for i in range(0, len(array) - 1):
		bst.delete(i)

	print(bst)


"""Basic stick plot"""
from vacumm.config import data_sample
from vacumm.misc.plot import stick2

# Read speed
import cdms2
f = cdms2.open(data_sample('mars3d.t.nc'))
u = f('u')
v = f('v')
f.close()

# Plot
stick2(u, v,  title='Current in the Iroise Sea', units='m/s',
    bottom=.2, top=.85, quiver_headwidth=2, close=True,
    quiverkey_value=.5, quiver_width=0.002, quiver_scale=5.,
    savefigs=__file__, figsize=(5.5,  3),  show=False)


from random_gen.random_gen import RandomGen
from collections import defaultdict

if __name__=='__main__': # We reproduce the example here
    probabilities = [0.01, 0.3, 0.58, 0.1, 0.01]
    random_nums = [-1, 0, 1, 2, 3]

    rg = RandomGen(random_nums, probabilities)

    # Run the next_num() function 100 times and collect the results to reproduce the example (of course not exactly)
    example_range=100
    example_values={}
    example_values=defaultdict(lambda: 0, example_values) # If key is non-existent, initialize with 0
    for i in range(example_range):
            example_values[rg.next_num()]+=1

    # print out the result
    for k in random_nums:
        print(k,':',example_values[k],'times')


import os
CD=os.getcwd()
fileout=open('report.csv', 'w')
print>>fileout,  ('name', 'evalue', 'Inflation_x10', 'Clusters', 'Single_prot', 'Total')

for file in os.listdir(CD):
    fh=open(file, 'r')
    Cluster=0
    Singleton=0
    name=fh.name
    evalue=fh.name.split('.')[1].split('evalue')[-1]
    Inflation_x10=fh.name.split('.')[-1]
    for line in fh:
        Length=len(line.strip().split('\t'))
        if Length>1:
            Cluster=Cluster+1
        else:
            Singleton=Singleton+1
    Total=Cluster+Singleton
    print>>fileout, ('%s, %s, %s, %s,  %s, %s')%(name, evalue, Inflation_x10, Cluster, Singleton, Total)


#Para que una tupla sea considerada tupla debe tener mas de 1 elementos
#A la tupla no se le pueden cambiar los valores

days = ('lunes','Martes','Miercoles','Jueves','Viernes','Sabado','Domingo',)
lista = [1,2,3] #lista
tupla = tuple(lista) #tuple transforma una lista a tupla
print(type(days))
print(days)
print(dir(days)) #Mostrar opciones de la tupla
del x; #Del elimina una variable

locations = {
    ('35.123324', '35.000') : "Tokio",
    ('35.123324', '33.000') : "New York",
}


#csapat;versenyzo;eletkor;palya;korido;kor
#   0       1        2      3      4    5
#Versenylovak;Fürge Ferenc;29;Gran Prix Circuit;00:01:11;1

f = open('autoverseny.csv','r',encoding='utf-8-sig')
fejlec = f.readline()
lista = []
for i in f:
    lista.append(i.strip().split(';'))

f.close()

print(f'3. feladat: {len(lista)}')

for i in lista:
    if i[1] == 'Fürge Ferenc':
        if i[3] == 'Gran Prix Circuit':
            if i[5] == '3':
                ora = int(i[4][0:2])
                perc = int(i[4][3:5])
                mperc = int(i[4][6:])
                korido_s = ora * 3600 + perc * 60 + mperc
                print(f'4. feladat: {korido_s} másodperc')

print(f'5. feladat: ')
print(f'Kérem egy versenyező nevét:')
versenyzo = input()

mini = 9999999
flag = False
for i in lista:
    if i[1] == versenyzo:
        flag = True
        ora = int(i[4][0:2])
        perc = int(i[4][3:5])
        mperc = int(i[4][6:])
        korido_s = ora * 3600 + perc * 60 + mperc
        if korido_s < mini:
            mini = korido_s
            palya = i[3]
            ido = i[4]

if flag:
    print(f'6. feladat: {palya}, {ido}')
else:
    print(f'Nincs ilyen versenyző az állomanyban')


from jt808.tools import data_config
from jt808.tools import tools
from jt808.message.gpsInfo_0x0200_append_assistance import GPSInfoAppendAssistance
from jt808.message.gpsInfo_0x0200_append_condition import GPSInfoAppendCondition
import random

class GPSInfoAppend:
    # 从GPSinfo.txt 和Config.py中获取数据
    def __init__(self, GPSList, dID):
        self.t = tools.Tools()
        self.GPSList = GPSList
        self.dID = dID
        self.alarm = self.GPSList[5]

        # -----------胎压监测系统报警信息----------- #
        self.setTirePressure(data_config.TIRE_PRESSURE)

        # ----------- 盲区监测系统报警信息----------- #
        self.setBlindArea(data_config.BLIND_AREA)

    # -----------附加信息组装----------- #
    # 选取附加信息
    def getAppendData(self):
        ass_alarm_dict = {
            '前向碰撞报警': '01',
            '车道偏离报警': '02',
            '车距过近报警': '03',
            '行人碰撞报警': '04',
            '频繁变道报警': '05',
            '道路标识超限报警': '06',
            '障碍物报警': '07',
            '用户自定义': '08~0F',
            '道路标志识别事件': '10',
            '主动抓拍事件': '11'}
        con_alarm_dict = {
            '疲劳驾驶报警': '01',
            '接打电话报警': '02',
            '抽烟报警': '03',
            '分神驾驶报警': '04',
            '驾驶员异常报警': '05',
            '用户自定义': '12~1F',
            '自动抓拍事件': '10',
            '驾驶员变更事件': '11'}
        ass_alarm_list = [
            '前向碰撞报警',
            '车道偏离报警',
            '车距过近报警',
            '行人碰撞报警',
            '频繁变道报警',
            '道路标识超限报警']
        con_alarm_list = ['疲劳驾驶报警', '接打电话报警', '抽烟报警', '分神驾驶报警', '驾驶员异常报警', ]
        # print(sign)
        if self.alarm in ass_alarm_list:
            data_config.ASS_ALARM = ass_alarm_dict[self.alarm]
            # print(data_config.ASS_ALARM)
            appendData = self.getAssData()
        elif self.alarm in con_alarm_list:
            data_config.CON_ALARM = con_alarm_dict[self.alarm]
            # print(data_config.CON_ALARM)
            appendData = self.getConData()
        else:
            appendData = self.getRandomAppendData()
        return appendData

    def getRandomAppendData(self):
        data_list = ['Assistance', 'Condition']
        choice = random.choice(data_list)
        if choice == 'Condition':
            self.data = self.getConData()
        else:
            self.data = self.getAssData()
        return self.data

    # -----------高级驾驶辅助报警信息----------- #

    def getAssData(self):
        gaa = GPSInfoAppendAssistance(self.GPSList, self.dID)
        return gaa.getDrivingAssistanceData()

    # -----------驾驶员状态监测系统报警信----------- #
    def getConData(self):
        gac = GPSInfoAppendCondition(self.GPSList, self.dID)
        return gac.getDrivingConditionMonitor()

    # -----------胎压监测系统报警信息----------- #

    def setTirePressure(self, TIRE_PRESSURE):
        pass

    # ----------- 盲区监测系统报警信息----------- #
    def setBlindArea(self, BLIND_AREA):
        pass

if __name__ == '__main__':
    g = GPSInfoAppend([120.091645, 30.277906, 38, 9, 0, '疲劳驾驶报警'], '8888888')
    print('GPS测试附加信息:', g.getAppendData())
    # print(data_config.IS_ATTACH)


import re
import xbmc
from ..functions import add_dir, add_link, make_request, fanart, logos
import xbmcgui
import xbmcplugin
import xbmcaddon
import urllib.parse as urllib_parse
import logging
from urllib.parse import urlparse, urljoin
def process_porngo_content(url, page=1):
    if "search" not in url and "/latest-updates/" not in url and "/categories/" not in url:
        url = url + "/latest-updates/"

    if url == 'https://www.porngo.com/categories/':
        process_porngo_categories(url)

    if page == 1:
        add_dir(f'Search porngo', 'porngo', 5, logos + 'porngo.png', fanart)

    add_dir("Categories", "https://www.porngo.com/categories/", 2, logos + 'porngo.png', fanart)
    content = make_request(url)
    match = re.compile('.+?
.+?<img src="([^"]*)" alt="([^"]*)".+?([:\d]+)', re.DOTALL).findall(content)

    # Get the base URL part from the input URL
    parsed_url = urlparse(url)
    base_url = f"{parsed_url.scheme}://{parsed_url.netloc}"

    for url, thumb, name, duration in match:
        add_link(name + ' [COLOR lime]('+ duration + ')[/COLOR]', url,  4, thumb, fanart)
    try:
        match = re.compile('href="(.+?)">Next
').findall(content)
        add_dir('[COLOR blue]Next  Page  >>>>[/COLOR]', base_url + match[0], 2, logos + 'porngo.png', fanart)
    except:
        pass

def process_porngo_categories(url):
    content = make_request(url)
    parsed_url = urlparse(url)
    base_url = f"{parsed_url.scheme}://{parsed_url.netloc}"
    categories = re.compile('.+?(.+?)', re.DOTALL).findall(content)
    for video_url, name in categories:
        full_url = urljoin(base_url, video_url)  # Properly format the URL
        add_dir(name, full_url, 2, logos + 'porngo.png', fanart)

def play_porngo_video(url):
    logging.info('play_porngo_video function called with URL: %s', url)
    content = make_request(url)
    media_url = re.compile("<source src='(.+?)' type='video/mp4'").findall(content)[0]
    return media_url


# PROGRAM BetterBubblesortBooleanModule:

def Swap(a,b):
    TempValue = b
    b = a
    a = TempValue
    return a, b
# END Swap

Age = [44, 23, 42, 33, 18, 54, 34, 16]
reducingindex = len(Age)-1
DidSwap = False
for outerindex in range(0,len(Age)):
# DO
    for index in range(0,reducingindex):
    # DO
        if Age[index+1] < Age[index]:
        # THEN
            Age[index],Age[index+1] = Swap(Age[index],Age[index+1])
            DidSwap = True
        # ENDIF;
    # ENDFOR;
    reducingindex = reducingindex - 1
    if DidSwap == False:
        break
# ENDFOR;
print(Age)
# END.


#!/usr/bin/env python

"""
Obtain the correspondence of a local GPU name to its cuda compute capability
Names match the output of nvidia-smi --query-gpu=gpu_name --format=csv,noheader

Usage:
----
./get_ccompute.py <GPU_NAME>
"""
import sys
try:
    from urllib.request import urlopen
except ImportError:
    from urllib2 import urlopen
import collections

from bs4 import BeautifulSoup

def process(url):
    page = urlopen(url)

    text = page.read()
    page.close()

    soup = BeautifulSoup(text, "lxml")
    d = collections.defaultdict(str)

    for table in soup.findAll('table', {'class': 'table table-striped'}):
        for line in table.findAll('tr'):
            gpu = line.findNext('td').text.strip()
            compute = line.findNext('td').findNext('td').text.strip()
            d[gpu] = compute
    return d

def main():
    if len(sys.argv) > 1:
        gpu = sys.argv[1]
    if len(sys.argv) == 1:
        print("Usage: %s <GPU_NAME> ..." % sys.argv[0])
        sys.exit(1)
    # at least one gpu was passed
    d = process("https://developer.nvidia.com/cuda-gpus")
    print(d[gpu])

if __name__ == "__main__":
    main()


#0을 입력하면 입력은 종료가 되고 앞서 입력한 숫자를 더하여 출력
#while문 이용
#음수 포함
sum = 0 #총 합
print("종료하려면 0 입력")
while True:#무한루프 생성
    num = int(input(""))#사용자로부터 값 받음
    sum +=num#총합 구함
    if num == 0:#사용자에게 받은 값이 0일때 출
        print("총합은 ",sum,"입니다")
        break


#!/usr/bin/env python3
import rospy
import subprocess

from duckietown.dtros import DTROS, NodeType
from sensor_msgs.msg import CompressedImage
from custom_msgs.msg import TagInfo
from custom_msgs.srv import Shutdown
from turbojpeg import TurboJPEG
import cv2
from cv_bridge import CvBridge
from duckietown_msgs.msg import Twist2DStamped, BoolStamped
import numpy as np

LANE_COLOR = [(30, 60, 0), (50, 255, 255)]
# Mask resource: https://cvexplained.wordpress.com/2020/04/28/color-detection-hsv/#:~:text=The%20HSV%20values%20for%20true,10%20and%20160%20to%20180.
STOP_COLOR = [(0, 100, 20), (10, 255, 255)]
DUCK_COLOR = [(10, 100, 0), (20, 255, 255)]
TAG_LEFT = 50
TAG_RIGHT = 48
TAG_STRAIGHT = 56
TAG_WALK = 163
TAG_PARKS = [207, 226, 228, 75]
TAG_PARK_ENTRANCE = 227

DEBUG = True
ENGLISH = False

class DriveNode(DTROS):
    """
    Initializes the drive node with PID control variables, Service Proxies, Subscribers, and Publishers.
    """
    def __init__(self, node_name):
        super(DriveNode, self).__init__(
            node_name=node_name,
            node_type=NodeType.GENERIC
        )
        self.node_name = node_name
        self.veh = rospy.get_param("~veh")

        self.jpeg = TurboJPEG()

        # Parking lot ID
        self.lot_id = 4

        # Image related parameters
        self.width = None
        self.height = None
        self.lower_thresh = 150

        # PID Variables
        self.proportional = None
        if ENGLISH:
            self.offset = -180
        else:
            self.offset = 180

        self.dummy = CvBridge().cv2_to_compressed_imgmsg(np.zeros((2, 2), np.uint8))

        self.velocity = 0.3
        self.twist = Twist2DStamped(v=self.velocity, omega=0)

        # Information related to apriltag
        self.cur_tag_id = -1
        self.cur_tag_area = -1
        self.cur_tag_aratio = -1

        # PID related terms
        self.P = 0.034
        self.D = -0.005
        self.last_error = 0
        self.last_time = rospy.get_time()

        # Variables to track on
        self.in_front = False
        self.is_stop = False
        self.is_stop_digit = False
        self.duck_front = False

        self.stage3 = False

        # Timer for stopping at the intersection
        self.t_stop = 5     # stop for this amount of seconds at intersections
        self.t_start = 0    # Measures the amount of time it stops

        # Timer for turning/going straight at the intersection
        self.turning = False
        self.t_turn = 2
        self.t_turn_start = 0

        ### Service proxies
        # Service for shutting down the apriltag detection node
        rospy.wait_for_service(f"/{self.veh}/apriltag_detection_node/shutdown")
        self.shutdown_tag = rospy.ServiceProxy(
            f"/{self.veh}/apriltag_detection_node/shutdown",
            Shutdown
        )

        # Service for shutting down the duckiebot detection node
        rospy.wait_for_service(f"/{self.veh}/duckiebot_detection_node/shutdown")
        self.shutdown_det = rospy.ServiceProxy(
            f"/{self.veh}/duckiebot_detection_node/shutdown",
            Shutdown
        )

        # Service for shutting down the duckiebot distance node
        rospy.wait_for_service(f"/{self.veh}/duckiebot_distance_node/shutdown")
        self.shutdown_dist = rospy.ServiceProxy(
            f"/{self.veh}/duckiebot_distance_node/shutdown",
            Shutdown
        )

        ### Subscribers
        # Camera images
        self.sub_img = rospy.Subscriber(
            "/" + self.veh + "/camera_node/image/compressed",
            CompressedImage,
            self.cb_image,
            queue_size=1,
            buff_size="20MB"
        )

        self.sub_taginfo = rospy.Subscriber(
            f"/{self.veh}/apriltag_detection_node/taginfo",
            TagInfo,
            self.cb_tag,
            queue_size=1
        )

        self.sub_breakdown = rospy.Subscriber(
            f"/{self.veh}/breakdown_node/breakdown",
            BoolStamped,
            self.cb_breakdown,
            queue_size=1)

        ### Publishers
        # Publish mask image for debug
        self.pub = rospy.Publisher(
            "/" + self.veh + "/output/image/mask/compressed",
            CompressedImage,
            queue_size=1
        )

        # Publish car command to control robot
        self.vel_pub = rospy.Publisher(
            "/" + self.veh + "/car_cmd_switch_node/cmd",
            Twist2DStamped,
            queue_size=1
        )

        # Shutdown hook
        rospy.on_shutdown(self.hook)

    def cb_tag(self, msg):
        """
        Store the currently detected tag information.
        """
        if msg.area != -1:
            self.cur_tag_id = msg.tag_id
            #rospy.loginfo(f"Tag ID: {self.cur_tag_id}, Area: {msg.area}, Area Ratio: {msg.area_ratio}")

        if not self.is_stop:
            self.cur_tag_area = msg.area
            self.cur_tag_aratio = msg.area_ratio
        else:
            self.cur_tag_area = -1
            self.cur_tag_aratio = -1

        if (self.cur_tag_id == TAG_WALK and self.cur_tag_aratio > 0.017) or \
           (self.cur_tag_id in TAG_PARKS and self.cur_tag_aratio > 0.03):
            # Prevent is_stop condition to be indefinitely true
            # by constantly updating the tag area (and its ratio)
            self.is_stop = True
            self.t_start = rospy.get_rostime().secs

    def get_max_contour(self, contours):
        """
        Returns the index of contour with maximum area.
        """
        max_area = 20
        max_idx = -1
        for i in range(len(contours)):
            area = cv2.contourArea(contours[i])
            if area > max_area:
                max_idx = i
                max_area = area

        return max_area, max_idx

    def get_contour_center(self, contours, idx):
        """
        Returns the center coordinate of specified contour.
        """
        x, y = -1, -1
        if idx != -1:
            M = cv2.moments(contours[idx])
            try:
                x = int(M['m10'] / M['m00'])
                y = int(M['m01'] / M['m00'])
            except:
                pass

        return x, y

    def compute_contour_location(
        self,
        cropped_img,
        contour_color
    ):
        """
        Get the location of contour based on image and color range.
        """
        # Convert corpped image to HSV and get mask corresponding to the
        # specified color
        hsv = cv2.cvtColor(cropped_img, cv2.COLOR_BGR2HSV)
        mask = cv2.inRange(hsv, contour_color[0], contour_color[1])

        # Etract contours from mask
        contours, _ = cv2.findContours(mask,
                                       cv2.RETR_EXTERNAL,
                                       cv2.CHAIN_APPROX_NONE)

        # Only get contour with maximum area, and compute center of it
        mx_area, mx_idx = self.get_max_contour(contours)
        x, y = self.get_contour_center(contours, mx_idx)

        return x, y, mx_area

    def cb_image(self, msg):
        """
        Callback for image message.
        """
        img = self.jpeg.decode(msg.data)

        if self.width == None:
            self.height, self.width = img.shape[:2]

        # Get location of red intersection line
        red_crop = img[300:-1, 200:-200, :]
        _, ry, _ = self.compute_contour_location(red_crop, STOP_COLOR)

        # Update status of stopping or not
        if not self.is_stop and not self.turning and ry >= self.lower_thresh:
            # Start a timer and turn the stop flag
            self.is_stop = True
            self.t_start = rospy.get_rostime().secs

        # Get location of line
        crop = img[int(0.7 * self.height):-1, :450, :]
        lx, _, _ = self.compute_contour_location(crop, LANE_COLOR)

        # Set proportional values if needed
        if lx != -1:
            self.proportional = lx - int(self.width / 2) + self.offset + (20 if self.stage3 else 0)
        else:
            self.proportional = None

        if self.is_stop and self.cur_tag_id == TAG_WALK:
            # Only check for the pedestrian (duck) when robot is stopping
            duck_crop = img[:, int(self.width * 0.2):int(self.width * 0.8), :]
            _, _, mx_area = self.compute_contour_location(duck_crop, DUCK_COLOR)

            # Indefinitely stop if the pedestrain is in front
            if mx_area > 1000:
                self.duck_front = True
            else:
                self.duck_front = False

        if DEBUG:
            rect_img_msg = CompressedImage(format="jpeg", data=self.jpeg.encode(img))
            self.pub.publish(rect_img_msg)

    def cb_breakdown(self, msg):
        """
        Callback for breakdown message.
        """
        if msg.data:
            self.in_front = True
        else:
            self.in_front = False

    def lane_follow(self):
        """
        Compute odometry values with PID.
        """
        if self.proportional is None:
            P = 0
            D = 0
        else:
            # P Term
            P = -self.proportional * self.P

            # D Term
            d_error = (self.proportional - self.last_error) / (rospy.get_time() - self.last_time)
            self.last_error = self.proportional
            self.last_time = rospy.get_time()
            D = d_error * self.D

        return self.velocity, P + D

    def stop(self):
        """
        Stop the vehicle completely.
        """
        return 0, 0

    def straight(self):
        """
        Move vehicle in forward direction.
        """
        rospy.loginfo("Moving straight...")
        return self.velocity + 0.2, -0.7

    def turn(self, right=True, is_stage3=False, lot_id=None):
        """
        Turn the car at the intersection according to the direction given.
        """
        omega = 0.0
        if is_stage3:
            if lot_id == 1:
                omega = 2.2
            elif lot_id == 2:
                omega = 3.4
            elif lot_id == 3:
                omega = -3.5
            else:
                omega = -3.9
        else:
            if right:
                omega = -4.6
            else:
                omega = 2.3

        if DEBUG:
            rospy.loginfo(f"Turning {'right' if right else 'left'}...")
        return self.velocity, omega

    def breakdown_turn(self):
        """
        Turn the duckiebot around the broken duckiebot.
        """
        rospy.loginfo("Breakdown turn")
        self.twist.v = 0
        self.twist.omega = 0
        self.vel_pub.publish(self.twist)
        rospy.sleep(2)

        # define range
        omega = 0
        k = 2
        a = 1.7

        for v in np.linspace(0, 2*np.pi - (np.pi/4), num=10):
            s = np.sin(k * v) * k * a

            if s > 0:
                if v < np.pi/2:
                    omega = s
                else:
                    omega = 1.7*-s
            else:
                if v < (np.pi*3/2):
                    omega = 1.6*s
                else:
                    omega = -s

            self.twist.v = 0.3
            self.twist.omega = omega
            self.vel_pub.publish(self.twist)
            rospy.sleep(0.5)

        self.in_front = False
        rospy.loginfo("Breakdown turn done")

    def drive(self):
        """
        Decide how to move based on the given information and flags.
        """
        if self.is_stop and \
            not self.duck_front and \
            (rospy.get_rostime().secs - self.t_start) >= self.t_stop:
            # Move in a desired direction after stopping
            self.is_stop = False

            if self.cur_tag_id != TAG_WALK:
                # When the stop is not at the crosswalk, duckiebot requires turning
                # i.e. continue with PID when it is after the crosswalk
                self.turning = True
                if self.cur_tag_id == TAG_PARK_ENTRANCE:
                    # Transition to stage 3 (parking) and get the user input
                    self.stage3 = True
                self.t_turn_start = rospy.get_rostime().secs

        elif self.turning and ((rospy.get_rostime().secs - self.t_turn_start) >= self.t_turn):
            # Switch from manual control to PID control (TURN to DRIVE)
            self.turning = False

        # Determine the velocity and angular velocity
        v, omega = 0, 0
        if self.is_stop:
            # Track the center of leader robot to decide the direction to turn
            v, omega = self.stop()
            if self.cur_tag_id in TAG_PARKS:
                rospy.signal_shutdown("Done")

        elif self.turning and ((rospy.get_rostime().secs - self.t_turn_start) < self.t_turn):
            if self.cur_tag_id in [TAG_LEFT, TAG_RIGHT] or self.stage3:
                v, omega = self.turn(True if self.cur_tag_id == TAG_RIGHT else False, self.stage3, self.lot_id)
            else:
                v, omega = self.straight()
        else:
            v, omega = self.lane_follow()

        self.twist.v, self.twist.omega = v, omega

        # Publish the resultant control values
        self.vel_pub.publish(self.twist)

    def hook(self):
        """
        Hook for shutting down the entire system.
        """
        rospy.loginfo("SHUTTING DOWN")
        self.twist.v = 0
        self.twist.omega = 0
        self.vel_pub.publish(self.twist)
        for i in range(8):
            self.vel_pub.publish(self.twist)

        self.shutdown_tag(0)
        self.shutdown_dist(0)
        self.shutdown_det(0)

        subprocess.run(["rosnode", "kill", "breakdown_node"])

if __name__ == "__main__":
    node = DriveNode("drive_node")
    rate = rospy.Rate(8)  # 8hz
    while not rospy.is_shutdown():
        # Periodically send the driving command
        if node.in_front:
            node.breakdown_turn()
        node.drive()
        rate.sleep()


import csv
from time import time
import serial
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import sys
np.set_printoptions(threshold=sys.maxsize)

plt.ion()
fig = plt.figure() #Create a figure

ser = serial.Serial('/dev/arduinoNano', timeout=None) #Change serial port

t_0 = float(time()) #Time when code is first run
noise_accx = 0  #Dummy variable for accelerometer noise in x axes
noise_accy = 0  #Dummy variable for accelerometer noise in y axes
noise_accz = 0  #Dummy variable for accelerometer noise in z axes

rowlist = []
calibratedData = []
rawDataList = []
calibratedDataList = []
vel = [0, 0 , 0]
dist = [0, 0, 0]

# i = 0
# for i in range(100):
while True: #To terminate this code, you have to ctrl+c or close the terminal. Closing the graph is not enough.
    ser_bytes = ser.readline()
    if ser_bytes != "": #Make sure that the line is not empty

        decoded_bytes = str(ser_bytes.decode("ascii"))
        rawData = [float(x) for x in decoded_bytes.split(",")]
        t_from_start = round(float(time()) - t_0,3) #Time from when the code when initally run
        rawData.insert(0, t_from_start)   #Insert time for each respective point
        #rowlist.append(rows)   #Append row to l
        calibratedData = rawData

        calibratedData[1] = rawData[1] - noise_accx
        calibratedData[2] = rawData[2] - noise_accy
        calibratedData[3] = rawData[3] - noise_accz

        #Method 2: Creating threshold to get rid of noise
        if abs(calibratedData[1])<0.03:
            calibratedData[1] = 0
        if abs(calibratedData[2])<0.03:
            calibratedData[2] = 0
        if abs(calibratedData[3])<0.03:
            calibratedData[3] = 0

        #Plotting the acceleration for each axes
        plt.scatter(t_from_start, calibratedData[1], s=10, c='r', marker="s")    #acc_x
        plt.scatter(t_from_start, calibratedData[2], s=10, c='y', marker="s")    #acc_y
        plt.scatter(t_from_start, calibratedData[3], s=10, c='k', marker="s")    #acc_z
        plt.show()  #Show the plot
        plt.pause(0.000001)

        #Converting raw data into a dataframe
        rawDataList.append(rawData)

        #Converting 'calibrating' data in a dataframe
        calibratedDataList.append(calibratedData)

        acc = np.array([calibratedData[1], calibratedData[2],calibratedData[3]])

        #Method 1: Subtracting off bias
        #This is to get rid of noise. To use you have to make sure that the IMU is stationary for ~10 seconds.
        #The code will collect 100 data points, average them, and subtract that number from all
        #incoming accelerometer data in each respective axes.
        print(len(rawDataList))
        if len(rawDataList)== 100:
            calibratedDataDF = pd.DataFrame(calibratedDataList, columns =['time', 'accx','accy', 'accz','gyrx', 'gyry','gyrz', 'magx','magy', 'magz'])
            rawDataDF = pd.DataFrame(rawDataList, columns =['time', 'accx','accy', 'accz','gyrx', 'gyry','gyrz', 'magx','magy', 'magz'])
            noise_accx = np.sum(rawDataDF['accx'])/np.size(rawDataDF['accx'])
            noise_accy = np.sum(rawDataDF['accy'])/np.size(rawDataDF['accy'])
            noise_accz = np.sum(rawDataDF['accz'])/np.size(rawDataDF['accz'])
            vel = [0, 0 , 0]
            dist = [0, 0, 0]
            print('CALIBRATION DONE!')
        else:
            dt = 25/1000
            if acc[0] == 0:
                vel[0] = 0
            if acc[1] == 0:
                vel[1] = 0
            if acc[2] == 0:
                vel[2] = 0
            vel = vel + acc*dt
            dist = dist + vel*dt

        # print(np.sum(rawDataDF['accz']),np.size(rawDataDF['accz']), noise_accz)

        print(rawData)
        t_from_start_old = t_from_start


from keras.preprocessing import sequence
from keras.models import Sequential
from keras.layers import Dense, Embedding, Flatten
from keras.datasets import imdb
from keras.callbacks import EarlyStopping

max_features = 20000
maxlen = 80 # cut texts after this number of words (among top max_features most common words)
batch_size = 32

print('Loading data...')
(x_train, y_train), (x_test, y_test) = imdb.load_data(num_words=max_features) # Replace this and create your own data loader and pre-processing for the given data on e-dimension

print(len(x_train), 'train sequences')
print(len(x_test), 'test sequences')

print('Pad sequences (samples x time)')
x_train = sequence.pad_sequences(x_train, maxlen=maxlen)
x_test = sequence.pad_sequences(x_test, maxlen=maxlen)
print('x_train shape:', x_train.shape)
print('x_test shape:', x_test.shape)

print('Build model...')
model = Sequential()
# keras.layers.Embedding(input_dim, output_dim, embeddings_initializer='uniform', embeddings_regularizer= None, activity_regularizer=None, embeddings_constraint=None, mask_zero=False, input_length=None)
model.add(Embedding(max_features, 128,input_shape=(maxlen,),trainable=True))
model.add(Flatten())
model.add(Dense(128))
model.add(Dense(1, activation='sigmoid'))
print(model.summary())

from keras.utils import plot_model
plot_model(model, to_file='model.png')
es = EarlyStopping(monitor='val_loss', mode='min', patience=10)
# try using different optimizers and different optimizer configs
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])

print('Train...')
model.fit(x_train, y_train, batch_size=batch_size, epochs=15, validation_split=0.1, callbacks=[es])

score, acc = model.evaluate(x_test, y_test, batch_size=batch_size)
print('Test score:', score)
print('Test accuracy:', acc)


fhand = open('mbox-short.txt')
for line in fhand:
    line = line.rstrip()
    if not line.startswith('From '): continue
    #print(line)
    words = line.split()
    email = words[1]
    pieces = email.split('@')
    #print(pieces)
    print('Emails came from these domains: ', pieces[1])


"""empty message

Revision ID: 0b00d294218b
Revises: b0310bee4efe
Create Date: 2020-11-02 17:01:18.231579

"""
from alembic import op
import sqlalchemy as sa

# revision identifiers, used by Alembic.
revision = '0b00d294218b'
down_revision = 'b0310bee4efe'
branch_labels = None
depends_on = None

def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.create_table('user',
    sa.Column('id', sa.Integer(), nullable=False),
    sa.Column('username', sa.String(length=64), nullable=True),
    sa.PrimaryKeyConstraint('id')
    )
    op.create_table('reservation',
    sa.Column('id', sa.Integer(), nullable=False),
    sa.Column('user_id', sa.Integer(), nullable=False),
    sa.Column('hotel_id', sa.Integer(), nullable=False),
    sa.Column('start_date', sa.DateTime(), nullable=True),
    sa.Column('end_date', sa.DateTime(), nullable=True),
    sa.ForeignKeyConstraint(['hotel_id'], ['hotel.id'], ),
    sa.ForeignKeyConstraint(['user_id'], ['user.id'], ),
    sa.PrimaryKeyConstraint('id')
    )
    op.drop_table('the_user')
    # ### end Alembic commands ###

def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.create_table('the_user',
    sa.Column('id', sa.INTEGER(), autoincrement=True, nullable=False),
    sa.Column('username', sa.VARCHAR(length=64), autoincrement=False, nullable=True),
    sa.Column('password', sa.VARCHAR(length=64), autoincrement=False, nullable=True),
    sa.PrimaryKeyConstraint('id', name='the_user_pkey')
    )
    op.drop_table('reservation')
    op.drop_table('user')
    # ### end Alembic commands ###


# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models, migrations

class Migration(migrations.Migration):

    dependencies = [
        ('mealmatcher_app', '0004_auto_20150426_2124'),
    ]

    operations = [
        migrations.AddField(
            model_name='meal',
            name='user1',
            field=models.CharField(max_length=100, verbose_name=b'Person 1 username', blank=True),
            preserve_default=True,
        ),
        migrations.AddField(
            model_name='meal',
            name='user2',
            field=models.CharField(max_length=100, verbose_name=b'Person 2 username', blank=True),
            preserve_default=True,
        ),
    ]


from datetime import datetime
from pyspark.context import SparkContext
import pyspark.sql.functions as f
from awsglue.utils import getResolvedOptions
from awsglue.context import GlueContext
from awsglue.dynamicframe import DynamicFrame
from awsglue.job import Job
spark_context = SparkContext.getOrCreate()
glue_context = GlueContext(spark_context)
session = glue_context.spark_session

glue_db = "dbname"
glue_table = "tablename"
s3_write_path = "s3outputpath"

dt_start = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
print("Start time:", dt_start)

dynamic_frame_read = glue_context.create_dynamic_frame.from_catalog(database = glue_db, table_name = glue_table)
data_frame = dynamic_frame_read.toDF()

df_dropna = data_frame.dropna()
multipledf = (df_dropna.groupby('Order ID').count().where(f.col('count') > 1).sort('count', ascending=False)
             .withColumnRenamed('count', 'total_item_in_order'))
multipledf.count()
df_dropna_tmp = df_dropna
multipledf2 = multipledf.join(df_dropna_tmp, ['Order ID'], 'leftouter')
multipledf2.count()
multipledf3 =(multipledf2.groupby('Order ID').agg(f.concat_ws(", ", f.collect_list(f.col('Product'))).alias('items_order'),
             *[f.first(cl).alias(cl) for cl in multipledf2.columns if not cl == 'Order ID']))

dynamic_frame_write = DynamicFrame.fromDF(multipledf3, glue_context, "dynamic_frame_write")
glue_context.write_dynamic_frame.from_options(frame = dynamic_frame_write,connection_type = "s3",
connection_options = {"path": s3_write_path},format = "csv")

dt_end = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
print("Start time:", dt_end)


n = int(input())

for _ in range(n):
    arr = input()
    count = [0] * len(arr)
    flag = 0
    for i in range(len(arr)):
        if (arr[i] == 'O'):
            count[i] = flag + 1
            flag += 1
        else:
            flag = 0
    print(sum(count))


import pandas as pd
from src.monash_battery.param import *

class Forecast:

    def __init__(self):
        self.minutes_interval = 0
        self.num_intervals_hour = 0
        self.num_intervals_day = 0
        self.dataset = pd.DataFrame()
        self.col_datetime = ""
        self.forecast_demands = pd.DataFrame()

    def new_dataset(self, file_name):
        df = pd.read_csv(f"{file_name}")
        col_datetime = df.columns[0]
        df[col_datetime] = pd.to_datetime(df[col_datetime])
        freq = df[col_datetime][1].minute - df[col_datetime][0].minute

        self.dataset = df
        self.col_datetime = col_datetime
        self.minutes_interval = freq
        self.num_intervals_hour = int(60 / freq)
        self.num_intervals_day = int(1440 / self.minutes_interval)

        print("Forecast load dataset is added. ")

    def read_forecast_loads(self, start_time):
        loads_df = self.dataset
        mask = (loads_df[self.col_datetime] == start_time)
        df = loads_df.loc[mask]
        self.forecast_demands = pd.DataFrame()
        try:
            loads2 = list(df.iloc[0, 1:])
            self.forecast_demands[d_datetime] = pd.date_range(start=start_time, periods=len(loads2),
                                                              freq=f"{self.minutes_interval}min")
            self.forecast_demands[d_demand] = [l * self.num_intervals_hour for l in loads2]
            return True
        except IndexError:
            return False

class Historical:

    def __init__(self):
        self.minutes_interval = 0
        self.num_intervals_hour = 0
        self.num_intervals_day = 0
        self.dataset = ""
        self.col_datetime = ""
        self.col_loads = ""
        self.forecast_demands = pd.DataFrame()
        self.historical_demands = pd.DataFrame()

    def new_dataset(self, file_name):
        df = pd.read_csv(f"{file_name}")
        col_datetime = df.columns[0]
        col_loads = df.columns[1]
        df[col_datetime] = pd.to_datetime(df[col_datetime])
        freq = df[col_datetime][1].minute - df[col_datetime][0].minute
        df.set_index(col_datetime)

        self.dataset = df
        self.col_datetime = col_datetime
        self.col_loads = col_loads
        self.minutes_interval = freq
        self.num_intervals_hour = int(60 / freq)
        self.num_intervals_day = int(1440 / self.minutes_interval)

        print("Actual load dataset is added. ")

    def read_historical_loads(self, start_time, reschedule_freq):
        loads_df = self.dataset
        col_datetime = self.col_datetime
        col_loads = self.col_loads
        end_time = start_time + reschedule_freq
        mask = (loads_df[col_datetime] >= start_time) & (loads_df[col_datetime] < end_time)
        df = loads_df.loc[mask]
        loads = list(df[col_loads])
        self.historical_demands = pd.DataFrame()
        self.historical_demands[d_datetime] = \
            pd.date_range(start=start_time, periods=len(loads), freq=f"{self.minutes_interval}min")
        self.historical_demands[d_demand] = [l * self.num_intervals_hour for l in loads]

        end_time1 = start_time + pd.Timedelta(minutes=self.minutes_interval * self.num_intervals_day)
        mask2 = (loads_df[col_datetime] >= start_time) & (loads_df[col_datetime] < end_time1)
        df2 = loads_df.loc[mask2]
        loads2 = list(df2[col_loads])
        self.forecast_demands = pd.DataFrame()
        self.forecast_demands[d_datetime] = pd.date_range(start=start_time, periods=len(loads2),
                                                          freq=f"{self.minutes_interval}min")
        self.forecast_demands[d_demand] = [l * self.num_intervals_hour for l in loads2]


import random

from sfml.system import *
from sfml.window import *
from sfml.graphics import *

window = None
event_handlers = {}
background_color = Color.BLACK

def create_window(width = 850, height = 550, title = "Game Window"):
    global window

    window = RenderWindow(VideoMode(width, height), title)
    window.framerate_limit = 60
    # window.settings.antialiasing_level = 8

def close_window():
    global window

    window.close()

def is_open():
    global window

    return window.is_open

def set_handler(event, handler):
    global event_handlers

    event_handlers[event] = handler

def set_background(color):
    global background_color

    background_color = color

def do_events():
    global window
    global event_handlers

    for event in window.events:
        if type(event) in event_handlers:
            event_handlers[type(event)](window, event);

def clear():
    global window
    global background_color

    window.clear(background_color)

def draw(shape):
    global window

    window.draw(shape)

def present():
    global window

    window.display()

def random_color():
    return Color(
        random.randint(0, 255),
        random.randint(0, 255),
        random.randint(0, 255)
    )

if __name__ == "__main__":
    create_window()
    set_handler(CloseEvent, lambda sender, args : close_window())
    set_background(Color(31, 45, 53))

    while is_open():
        do_events()
        clear()
        present()


'''Youtube video provier - youtube-dl'''
from io import BytesIO
from math import inf
import re
from . import DownloadResult
import logging,youtube_dl,requests
__desc__ = '''Youtube 视频'''
__cfg_help__ = '''format - 同 youtube-dl -f
( 另可跟随其他 yotube-dl 参数 e.g. format=best;quiet=True )'''
logger = logging.getLogger('youtube')
youtube_dl.utils.std_headers['User-Agent'] = 'Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)'
params = {
    'logger':logger,
    'merge-output-format':'mp4',
    'outtmpl':'%(id)s.%(ext)s',
    'format':'best',
    'writethumbnail':True
} # default params,can be overridden
ydl = youtube_dl.YoutubeDL(params)
def __to_yyyy_mm_dd(date):
    return date[:4] + '/' + date[4:6] + '/' + date[6:]
def update_config(cfg):
    ydl = youtube_dl.YoutubeDL({**params,**cfg})
def download_video(res) -> DownloadResult:
    with DownloadResult() as results:
        # downloading the cover
        def append_result(entry):
            with DownloadResult() as result:
                result.title = entry['title']
                result.soruce = entry['webpage_url']
                result.video_path = '%s.%s'%(entry['display_id'],entry['ext'])
                '''For both total results and local sub-results'''
                results.cover_path = result.cover_path = '%s.%s'%(entry['display_id'],'jpg')
                date = __to_yyyy_mm_dd(entry['upload_date'])
                results.description = result.description = f'''作者 : {entry['uploader']} [{date} 上传]

来源 : {result.soruce}

{entry['description']}'''
            results.results.append(result)

        info = ydl.extract_info(res,download=True)
        results.soruce = info['webpage_url']
        results.title = info['title']
        '''Appending our results'''
        if 'entries' in info:
            for entry in info['entries']:
                append_result(entry)
        else:
            append_result(info)
    return results


from django.template import RequestContext
from django.shortcuts import render_to_response
from django.shortcuts import get_object_or_404
from django.contrib.auth.decorators import login_required
from django.http import HttpResponseRedirect
from csesoc.game.models import *
from django.conf import settings
import datetime
from django.db.models import Sum

# presently using generic views for everything. add custom views here as needed

def get_player(username):
   p = Player.objects.filter(username=username)
   if len(p) > 0:
      return p[0]
   else:
      p = Player()
      p.username = username
      p.save()
      return p

def get_progress(puzzle, username):
   player = get_player(username)
   game = get_object_or_404(Game, year = datetime.datetime.now().year)

   progress = PlayerProgress.objects.filter(player=player, puzzle=puzzle, game=game)
   if len(progress) > 0:
      return progress[0]
   else:
      progress = PlayerProgress()
      progress.game = game
      progress.puzzle = puzzle
      progress.player = player
      progress.reached_time = datetime.datetime.now()
      progress.save()

def solved_puzzle(puzzle, username):
   progress = get_progress(puzzle, username)
   if progress.solved_time == None:
      progress.solved_time = datetime.datetime.now()
      progress.save()

# check whether what they entered is the answer
def check_solved(puzzle, username, answer):
   # exact matches are always good
   if answer.lower() == puzzle.answer.lower():
      return True
   elif ";" in puzzle.answer:
      answerParts = answer.split(" ")
      ansParts = puzzle.answer.split(";")

      # we should not have way more tems in answerParts than puzzle answer parts
      if len(answerParts) > len(ansParts) + 5:
         return False

      # check that all the parts are in there
      for ans in ansParts:
         if ans not in answerParts:
            return False

      return True
   else:
      return False

def reached_puzzle(puzzle, username):
   # automatically creates it if required
   progress = get_progress(puzzle, username)

def made_attempt(puzzle, username, value):
   progress = get_progress(puzzle, username)

   attempt = PlayerAttempt()
   attempt.progress = progress
   attempt.attempt_time = datetime.datetime.now()
   attempt.attempt = value
   attempt.save()

#TODO: check that the user is logged in and player.isAdmin()
# requires the player.isAdmin() function to be written first

# returns "th", where "th" can be "st", "nd", "rd", or "th"
def ordinal(n):
    return dict([(x,'th') for x in range(10,20)]).get(n%100,{1:'st',2:'nd',3:'rd'}.get(n%10,'th'))

def get_player_scores(request, year):
   return PlayerProgress.objects.filter(game__year__startswith=2010).filter(solved_time__isnull=False).values('player__username').annotate(Sum('puzzle__points')).order_by('-puzzle__points__sum')

def game_scores(request, year):
   if year == "":
      year = datetime.datetime.now().year
   else:
      year = int(year)

   # the magical line that calculates the scores
   scores = get_player_scores(request, year)
   return render_to_response('scores.html', {'scores': scores})

@login_required
def game_static_latest(request):
    p = get_player(request.user.username)
    last_puzzle = p.upto()
    return HttpResponseRedirect(last_puzzle.slug)

@login_required
def game_static(request, path):
   if request.method == "POST":
      p = get_object_or_404(Puzzle, slug=path.replace('/','_'))
      answer = request.POST['answer']
      made_attempt(p, request.user.username, answer)
      if check_solved(p, request.user.username, answer) and p.next_puzzle != None:
         # we can go to the next puzzle!
         next = p.next_puzzle

         solved_puzzle(p, request.user.username)

         return HttpResponseRedirect(next.slug)

   p = get_object_or_404(Puzzle, slug=path.replace('/','_'))
   reached_puzzle(p, request.user.username)

   # get the player's rank
   player_rank = get_player(request.user.username).rank()
   rank = "You are "
   if player_rank['tied']:
      rank += "tied in"
   else:
      rank += "ranked"
   rank += " "+str(player_rank['rank'])+ordinal(player_rank['rank'])+" place!"

   return render_to_response('game.html', { 'object' : p, 'user': request.user, 'showanswer' : (p.next_puzzle != None), 'rank' : rank }, context_instance=RequestContext(request) )


def find(n):
    if n==parent[n]:
        return n
    parent[n] = find(parent[n])
    return parent[n]

def union(pa, pb):
    if R[pa]>=R[pb]:
        R[pa]+=R[pb]
        parent[pb]=pa
    else:
        R[pb]+=R[pa]
        parent[pa] = pb

check = []
parent = [i for i in range(26)]
R = [1 for i in range(26)]

for edge in equations:
    u, v = ord(edge[0])-97, ord(edge[-1])-97
    pu, pv = find(u), find(v)
    if pu!=pv:
        union(pu, pv)

def find(x):
    if ancestor[x] != x:
        ancestor[x] = find(ancestor[x])
    return ancestor[x]

def union(a, b):
    if rank[a]<rank[b]:
        ancestor[find(a)] = find(b)
        rank[b]+=1
    else:
        ancestor[find(b)] = find(a)
        rank[a]+=1

rank = [0 for i in s]
ancestor = list(range(len(s)))
for a, b in pairs:
    union(a, b)

class DSU:
    def __init__(self, n):
        self.parent = [i for i in range(n)]
        self.rank = [0] * n

    def find(self, x):
        if self.parent[x] != x:
            self.parent[x] = self.find(self.parent[x])
        return self.parent[x]

    def union(self, a, b):
        a, b = self.find(a), self.find(b) #this line is important for some cases
        if self.rank[a]<self.rank[b]:
            self.parent[self.find(a)] = self.find(b)
            self.rank[b]+=1
        else:
            self.parent[self.find(b)] = self.find(a)
            self.rank[a]+=1