import sys
sys.path.insert(0, r'D:\Projects\aaadoc')

from statistics import mean, median
from collections import Counter
from src.utils.utils import get_files_in_from_directory
from src.loaders.NvdLoader import NvdLoader
from src.loaders.OsvLoader import OsvLoader
from src.loaders.OmniLoader import OmniLoader
import json
import dateutil.parser as parser
import pandas as pd
import matplotlib.pyplot as plt
import random
import regex as re

input_data_location = r'D:\Projects\aaa\results\checkpoints_fixMapper'
keywords_regexes_path = r'D:\Projects\aaadoc\src\2_phrase_search\bigquery\keywords_v2.csv'
vfm_classified_commits = r'D:\Projects\aaadoc\src\recalls\data\sap_result_training_excluded.json'
security_relevant_commits_file = r'src\recalls\data\security_relevant_commits.csv'
security_relevant_commits_info_file = r'src\recalls\data\security_relevant_commits_info.json'

fb_predictions_all = r'D:\Projects\aaadoc\src\recalls\data\prediction_all.json'
fb_predictions_npm = r'D:\Projects\aaadoc\src\recalls\data\prediction_npm.json'
fb_predictions_pypi = r'D:\Projects\aaadoc\src\recalls\data\prediction_pypi.json'
fb_predictions_mvn = r'D:\Projects\aaadoc\src\recalls\data\prediction_mvn.json'

commits_info_data = {}
commits_data = {}
security_label_keywords  = ['secur', 'vulnerab', 'exploit']

phrases_to_ids = {}

# General
def _get_ref_date(ref):
    ref_data = ref['data_obj']
    if ref['reference_type'] == 'commit':
        date1 = parser.parse(ref_data['commit']['committer']['date'])
        date2 = parser.parse(ref_data['commit']['author']['date'])
        first = date1 if date1 < date2 else date2
        return first

    if ref['reference_type'] == 'issue':
        date2 = parser.parse(ref_data['created_at'])
        return date2

    if ref['reference_type'] == 'compare':
        dates = []
        for x in ref_data['commits']:
            dates.append(parser.parse(x['commit']['author']['date']))
            dates.append(parser.parse(x['commit']['committer']['date']))
        first = min(dates)
        return first

# General
def _get_ref_id(ref):
    return f'{ref["repo_owner"]}/{ref["repo_name"]}/{ref["reference_type"]}/{ref["reference_value"]}'

# General
def _commit_size(ref):
    global commits_info_data
    if ref["reference_type"] == 'commit':
        commit_id = f'{ref["repo_owner"]}/{ref["repo_name"]}/{ref["reference_value"]}'
        if commit_id in commits_info_data:
            return commits_info_data[commit_id]['commit_info']['stats']['total']
        else:
            return None
    else:
        return None

def _commit_size_by_commit_id(commit_id):
    global commits_info_data
    if commit_id in commits_info_data:
        return commits_info_data[commit_id]['commit_info']['stats']['total']
    else:
        return None

def _get_matched_ref_object(ref, ref_date):
    ref_id = _get_ref_id(ref)
    ref_commit_size = _commit_size(ref)
    repo_full_name = f'{ref["repo_owner"]}/{ref["repo_name"]}'
    matched_ref_obj = {
        'ref_id':ref_id,
        'ref_repo_full_name':repo_full_name,
        'ref_commit_size':ref_commit_size,
        'ref_date': ref_date
    }
    return matched_ref_obj

def _get_matched_ref_object_by_commit_id(commit_id, first):
    segments = commit_id.split('/')
    ref_id = f'{segments[0]}/{segments[1]}/commit/{segments[2]}'
    ref_commit_size = _commit_size_by_commit_id(commit_id)
    repo_full_name = f'{segments[0]}/{segments[1]}'
    matched_ref_obj = {
                    'ref_id':ref_id,
                    'ref_repo_full_name':repo_full_name,
                    'ref_commit_size':ref_commit_size,
                    'ref_date': first
                }

    return matched_ref_obj

# First commit helper
def _get_commits_from_issue(repo_owner, repo_name, issue_data):
    global commits_data

    repo_full_name = f'{repo_owner}/{repo_name}'
    issue_commits = []

    timeline_commits = _extract_commits_from_timeline(repo_owner, repo_name, issue_data['timeline_data'])
    issue_commits += [f'{repo_owner}/{repo_name}/{c}' for c in timeline_commits]
    if 'pull_request' in issue_data:
        if 'pull_request_commits' in issue_data:
            pr_commits = issue_data['pull_request_commits']
            for c in pr_commits:
                c_id = f'{repo_owner}/{repo_name}/{c["sha"]}'
                issue_commits.append(c_id)
    else:
        cross_referenced_issues = [x['source']['issue'] for x in issue_data['timeline_data'] if x['event']=='cross-referenced']
        cross_referenced_events_in_the_same_repo = [x for x in cross_referenced_issues if x['repository']['full_name']==repo_full_name]
        for referenced_issue in cross_referenced_events_in_the_same_repo:
            try:
                timeline_commits =  _extract_commits_from_timeline(repo_owner, repo_name, referenced_issue['timeline_data'])
                issue_commits += [f'{repo_owner}/{repo_name}/{c}' for c in timeline_commits]
                if 'pull_request' in referenced_issue:
                    if 'pull_request_commits' in referenced_issue:
                        pr_commits = referenced_issue['pull_request_commits']
                        for c in pr_commits:
                            c_id = f'{repo_owner}/{repo_name}/{c["sha"]}'
                            issue_commits.append(c_id)
            except:
                print('Failed to process ref issue')

    commits = []
    for x in list(set(issue_commits)):
        if x in commits_data:
            commits.append(commits_data[x])
    return commits

# First commit helper
def _extract_commits_from_timeline(repo_owner, repo_name, timeline):
    try:
        result = []
        referenced_commits = [x for x in timeline if 'commit_id' in x and x['commit_id'] != None]
        for c in referenced_commits:
            if 'html_url' in c:
                seg = c['html_url'].split('/')
                ref_repo_owner = seg[3]
                ref_repo_name = seg[4]
            else:
                seg = c['commit_url'].split('/')
                ref_repo_owner = seg[4]
                ref_repo_name = seg[5]

            if repo_owner == ref_repo_owner and repo_name == ref_repo_name:
                result.append(c['commit_id'])
        return result
    except:
        return []

# Security phrases helper
def _safe_add(text, stuff):
    return text + ' ' + stuff if stuff else text

# Security phrases helper
def _contains_secuirty_related_phrases(ref, regexes, report_id):
    text = ''
    asd = ref['data_obj']
    if ref['reference_type'] == 'commit':
        text = _safe_add(text, asd['commit']['message'])
    elif ref['reference_type'] == 'issue':
        text = _safe_add(text, asd['title'])
        text = _safe_add(text, asd['body'])
        for t in asd['timeline_data']:
            if t['event']=='renamed':
                text = _safe_add(text, t['rename']['from'])
                text = _safe_add(text, t['rename']['to'])
            elif t['event']=='commented':
                text = _safe_add(text, t['body'])
            elif t['event']=='committed':
                text = _safe_add(text, t['message'])

        if 'pull_request_data' in asd:
            text = _safe_add(text, asd['pull_request_data']['title'])
            text = _safe_add(text, asd['pull_request_data']['body'])
        if 'pull_request_commits' in asd:
            for c in asd['pull_request_commits']:
                text = _safe_add(text, c['commit']['message'])
        if 'pull_request_comments' in asd:
            for c in asd['pull_request_comments']:
                text = _safe_add(text, c['body'])
    elif ref['reference_type'] == 'compare':
        for c in asd['commits']:
            text = _safe_add(text, c['commit']['message'])

    global phrases_to_ids
    found_phrases = False
    if text:
        for req in regexes:
            if regexes[req].search(text):
                if req not in phrases_to_ids:
                    phrases_to_ids[req] = set()
                phrases_to_ids[req].add(report_id)
                found_phrases = True

    return found_phrases

# Security labels helper
def _security_related_label(label_name):
    for keyword in security_label_keywords:
        if keyword in label_name:
            return True
    return False

# Security labels helper
def _get_labelling_date(issue):
    if 'labels' not in issue:
        return None

    label_names = [xx['name'].lower() for xx in issue['labels']]
    has_security_ralted_label = False
    for label_name in label_names:
        if _security_related_label(label_name):
            has_security_ralted_label = True
            break

    if not has_security_ralted_label:
        return None

    labelled_events = [evt for evt in issue['timeline_data'] if evt['event']=='labeled' and _security_related_label(evt['label']['name'].lower())]
    actual_labelling_date = None
    if len(labelled_events) == 0:
        actual_labelling_date = parser.parse(issue['created_at'])
    else:
        labelling_dates = [parser.parse(evt['created_at']) for evt in labelled_events]
        actual_labelling_date = min(labelling_dates)

    return actual_labelling_date

def load_creation_date(data, omni):
    for x in data.keys():
        dates = omni.publish_date_of_report(x)
        dates = [x['publish_date'] for x in dates]
        first = min(dates)
        if first.year < 2017:
            continue

        data[x]['creation_date'] = first

def load_ecosystem(data, omni):
    for x in data.keys():
        asd = omni.publish_date_of_report(x)
        asd = [x['publish_date'] for x in asd]
        first = min(asd)
        if first.year < 2017:
            continue

        ecosystems = list(set([xx.lower() for xx in omni.ecosystems_of_a_report(x)]))
        data[x]['ecosystem'] = ecosystems

def load_severity(data, omni):
    for x in data.keys():
        asd = omni.publish_date_of_report(x)
        asd = [x['publish_date'] for x in asd]
        first = min(asd)
        if first.year < 2017:
            continue

        severity = omni.highest_severity(x)
        data[x]['severity'] = severity

def load_repositories(data, references_data):
    for x in data.keys():
        if x not in references_data:
            data[x]['repositories'] = []
            continue

        repos = set()
        for ref in references_data[x]:
            repos.add(f'{ref["repo_owner"]}/{ref["repo_name"]}')

        data[x]['repositories'] = list(repos)

def load_all_refs(data, references_data):
    for x in data.keys():
        if x not in references_data:
            data[x]['all_refs'] = None
            continue

        dates = []
        for ref in references_data[x]:
            ref_date = _get_ref_date(ref)
            if ref_date != None:
                matched_ref_obj = _get_matched_ref_object(ref, ref_date)
                dates.append(matched_ref_obj)

        if len(dates) == 0:
            data[x]['all_refs'] = None
        else:
            data[x]['all_refs'] = dates

def load_first_ref(data, references_data):
    for x in data.keys():
        if x not in references_data:
            data[x]['first_ref'] = None
            continue

        dates = {}
        for ref in references_data[x]:
            ref_date = _get_ref_date(ref)
            if ref_date != None:
                repo_full_name = f'{ref["repo_owner"]}/{ref["repo_name"]}'
                if repo_full_name not in dates:
                    dates[repo_full_name]= []
                dates[repo_full_name].append(ref_date)

        if len(dates) == 0:
            data[x]['first_ref'] = None
        else:
            min_dates = [(k,min(v)) for k,v in dates.items()]
            data[x]['first_ref'] = min_dates

def load_first_issue(data, references_data):
    for x in data.keys():
        if x not in references_data:
            data[x]['first_issue'] = None
            continue

        dates = {}
        for ref in references_data[x]:
            if ref['reference_type'] != 'issue':
                continue

            ref_date = _get_ref_date(ref)
            if ref_date != None:
                repo_full_name = f'{ref["repo_owner"]}/{ref["repo_name"]}'
                if repo_full_name not in dates:
                    dates[repo_full_name]= []
                dates[repo_full_name].append(ref_date)

        if len(dates) == 0:
            data[x]['first_issue'] = None
        else:
            min_dates = [(k,min(v)) for k,v in dates.items()]
            data[x]['first_issue'] = min_dates

def load_first_commit(data, references_data):
    for x in data.keys():
        if x not in references_data:
            data[x]['first_commit'] = None
            continue

        dates = {}
        for ref in references_data[x]:
            if ref['reference_type'] == 'issue':
                commits = _get_commits_from_issue(ref['repo_owner'], ref['repo_name'], ref['data_obj'])
                if commits == None or len(commits) ==0:
                    continue

                min_date = parser.parse(commits[0]['commit']['committer']['date'])
                for c in commits:
                    commiter_date = parser.parse(c['commit']['committer']['date'])
                    author_date = parser.parse(c['commit']['author']['date'])
                    if commiter_date < min_date:
                        min_date = commiter_date
                    if author_date < min_date:
                        min_date = author_date

                repo_full_name = f'{ref["repo_owner"]}/{ref["repo_name"]}'
                if repo_full_name not in dates:
                    dates[repo_full_name]= []
                dates[repo_full_name].append(min_date)

            if ref['reference_type'] == 'commit' or ref['reference_type'] == 'compare':
                ref_date = _get_ref_date(ref)
                if ref_date != None:
                    repo_full_name = f'{ref["repo_owner"]}/{ref["repo_name"]}'
                    if repo_full_name not in dates:
                        dates[repo_full_name]= []
                    dates[repo_full_name].append(ref_date)

        if len(dates) == 0:
            data[x]['first_commit'] = None
        else:
            min_dates = [(k,min(v)) for k,v in dates.items()]
            data[x]['first_commit'] = min_dates

def load_first_sec_phrase(data, references_data):
    with open(keywords_regexes_path, 'r') as f:
        regexes = {x.strip(): re.compile(x.strip()) for x in f.readlines()}

    for x in data.keys():
        if x not in references_data:
            data[x]['first_sec_phrase'] = None
            continue

        dates = []
        for ref in references_data[x]:
            if not _contains_secuirty_related_phrases(ref, regexes, x):
                continue

            ref_date = _get_ref_date(ref)
            if ref_date != None:
                matched_ref_obj = _get_matched_ref_object(ref, ref_date)
                dates.append(matched_ref_obj)

        if len(dates) == 0:
            data[x]['first_sec_phrase'] = None
        else:
            data[x]['first_sec_phrase'] = dates

def load_first_sec_label(data, references_data):
    for x in data.keys():
        if x not in references_data:
            data[x]['first_sec_label'] = None
            continue

        dates = []
        for ref in references_data[x]:
            if ref['reference_type'] == 'issue':
                ref_date  = _get_labelling_date(ref['data_obj'])
                if ref_date != None:
                    matched_ref_obj = _get_matched_ref_object(ref, ref_date)
                    dates.append(matched_ref_obj)

        if len(dates) == 0:
            data[x]['first_sec_label'] = None
        else:
            data[x]['first_sec_label'] = dates

def load_fb_commit_classification(data):
    global commits_info_data

    predictions = {}
    prediction_files = [
        fb_predictions_all,
        fb_predictions_npm,
        fb_predictions_pypi,
        fb_predictions_mvn,
    ]
    for prediction_file in prediction_files:
        with open(prediction_file, 'r') as f:
            temp = json.load(f)
            for x in temp:
                if x['actual_value']:
                    if x['commit_id'] not in predictions:
                        predictions[x['commit_id']] = x['prediction'] == 'True'
                    else:
                        if not predictions[x['commit_id']]:
                            predictions[x['commit_id']] = x['prediction'] == 'True'

    sighted_vulnerabilities = set()
    per_vulnerability = {}
    for commit_id in predictions:
        if commit_id not in commits_info_data:
            continue

        commit = commits_info_data[commit_id]['commit_info']
        sighted_vulnerabilities.update(commits_info_data[commit_id]['report_ids'])

        if predictions[commit_id]:
            date1 = parser.parse(commit['commit']['committer']['date'])
            date2 = parser.parse(commit['commit']['author']['date'])
            first = date1 if date1 < date2 else date2
        else:
            first = 'not_spotted'

        for report_id in commits_info_data[commit_id]['report_ids']:
            if report_id not in per_vulnerability:
                per_vulnerability[report_id]=[]

            matched_ref_obj = _get_matched_ref_object_by_commit_id(commit_id, first)
            per_vulnerability[report_id].append(matched_ref_obj)

    for x in sighted_vulnerabilities:
        data[x]['fb_commit_classification'] = per_vulnerability[x]

def load_vfm_commit_classification(data):
    global commits_info_data

    with open(vfm_classified_commits, 'r') as f:
        vfm_classified = json.load(f)

    sighted_vulnerabilities = set()
    per_vulnerability_msg = {}
    per_vulnerability_patch = {}
    per_vulnerability_combined = {}
    for x in vfm_classified:
        if not x['is_security_related']:
            continue

        if x['id'] not in commits_info_data:
            continue

        commit_id = x['id']
        commit = commits_info_data[x['id']]['commit_info']
        sighted_vulnerabilities.update(commits_info_data[x['id']]['report_ids'])

        date1 = parser.parse(commit['commit']['committer']['date'])
        date2 = parser.parse(commit['commit']['author']['date'])
        first = date1 if date1 < date2 else date2
        if x['msg_prob'][0] >= 0.5 :
            spotted_date = first
        else:
            spotted_date = 'not_spotted'
        for report_id in commits_info_data[x['id']]['report_ids']:
            if report_id not in per_vulnerability_msg:
                per_vulnerability_msg[report_id]=[]

            matched_ref_obj = _get_matched_ref_object_by_commit_id(commit_id, spotted_date)
            per_vulnerability_msg[report_id].append(matched_ref_obj)

        if x['patch_prob'][0] >= 0.5 :
            spotted_date = first
        else:
            spotted_date = 'not_spotted'
        for report_id in commits_info_data[x['id']]['report_ids']:
            if report_id not in per_vulnerability_patch:
                per_vulnerability_patch[report_id]=[]
            matched_ref_obj = _get_matched_ref_object_by_commit_id(commit_id, spotted_date)
            per_vulnerability_patch[report_id].append(matched_ref_obj)

        if x['msg_prob'][0]*x['msg_prob'][0] + x['patch_prob'][0]*x['patch_prob'][0] >= 0.25 :
            spotted_date = first
        else:
            spotted_date = 'not_spotted'
        for report_id in commits_info_data[x['id']]['report_ids']:
            if report_id not in per_vulnerability_combined:
                per_vulnerability_combined[report_id]=[]
            matched_ref_obj = _get_matched_ref_object_by_commit_id(commit_id, spotted_date)
            per_vulnerability_combined[report_id].append(matched_ref_obj)

    for x in sighted_vulnerabilities:
        data[x]['vfm_message_classification'] = per_vulnerability_msg[x]

    for x in sighted_vulnerabilities:
        data[x]['vfm_patch_classification'] = per_vulnerability_patch[x]

    for x in sighted_vulnerabilities:
        data[x]['vfm_combined_classification'] = per_vulnerability_combined[x]

def main():
    global commits_data
    # Import data on additional commits
    with open(r'src\recalls\data\commit_data_for_rq1.json', 'r') as f:
        commits_data = json.load(f)

    global commits_info_data
    # Import data on security commits
    with open(security_relevant_commits_info_file, 'r') as f:
        commits_info_data = json.load(f)

    # Import data from vulnerability databases
    nvd = NvdLoader(r'D:\Projects\VulnerabilityData\new_nvd')
    osv = OsvLoader(r'D:\Projects\VulnerabilityData\new_osv')
    ghsa = OsvLoader(r'D:\Projects\VulnerabilityData\advisory-database\advisories\github-reviewed')
    omni = OmniLoader(nvd, osv, ghsa)

    # Import data from fix mapper result
    references_data = {}
    data_files = get_files_in_from_directory(input_data_location, '.json')
    for data_file in data_files:
        with open(data_file, 'r') as f:
            data_temp = json.load(f)

        for report_id in data_temp:
            for x in data_temp[report_id]:
                x['data_obj'] = json.loads(x['data'])
                x['data'] = None
        for report_id in data_temp:
            references_data[report_id] = data_temp[report_id]

    data = {x:{} for x in omni.all_ids}

    # Import creation dates
    load_creation_date(data, omni)

    # Load ecosystems
    load_ecosystem(data, omni)

    # Load repositories
    load_repositories(data, references_data)

    # Import severity
    load_severity(data, omni)

    # Load all refs in new format
    load_all_refs(data, references_data)

    # Load first ref
    load_first_ref(data, references_data)

    # Load first issue
    load_first_issue(data, references_data)

    # Load first commit
    load_first_commit(data, references_data)

    # Load first ref with security phrases
    load_first_sec_phrase(data, references_data)

    # # Most found phrases
    # global phrases_to_ids
    # asd = sorted({k:len(v) for k,v in phrases_to_ids.items()}.items(), key=lambda x: x[1])

    # Load first issue with security label
    load_first_sec_label(data, references_data)

    # # Load first commit classified as security related (Feature-based)
    load_fb_commit_classification(data)

    # Load first commit classified as security related (own-models)
    # load_dl_commit_classification(data)

    # Load first commit classified as security related (VulFixMiner)
    load_vfm_commit_classification(data)

    with open('recall_analysis.json', 'w') as f:
        json.dump(data, f, default=str)

if __name__ == '__main__':
    main()
    print('ok')


import hdgeom.mesh.rules.AbstractRule as AbstractRule
import hdgeom.mesh.rules.AbstractFactoryRule as AbstractFactoryRule
import hdgeom.mesh.rules.FaceRules as FaceRules
import hdgeom.mesh.Mesh as Mesh
import hdgeom.mesh.Face as Face
from random import randint
from Constants import *

# class which extends the AbstractRule class
class Lowrise(AbstractRule):
    def __init__(self):
        self.minExtrude = 3
        self.maxExtrude = 12
        self.minSplit = 0.4
        self.maxSplit = 0.6
        self.splits = 0.75

    #method for subdivision, has to be named replace
    def replace(self, mesh):
        newMesh=Mesh()
        for face in mesh.faces:
            if face.group == typePlotLowrise:
                if random(1) < self.splits:
                    extruded = FaceRules.extrude(face,randint(int(self.minExtrude/3),int(self.maxExtrude/3))*3)
                    splitted = FaceRules.splitRel(extruded[4],randint(0,1),random(self.minSplit,self.maxSplit))
                    extrudedSec = FaceRules.extrude(splitted[0],PVector(0,0,randint(0,2)*3))
                    extruded.remove(extruded[4])
                    splitted.remove(splitted[0])
                    for i,element in enumerate(extruded):
                        if i != 4:
                            if random(1) > 0.5:
                                element.group = typeFacade1
                            else:
                                element.group = typeFacade2
                    #splitted[0].group = typeTerrace
                    for i,element in enumerate(extrudedSec):
                        if i == 4:
                            element.group = typeRoof
                        elif random(1) > 0.5:
                            element.group = typeFacade1
                        else:
                            element.group = typeFacade2
                    newFaces = extruded
                    newFaces.extend(splitted)
                    newFaces.extend(extrudedSec)
                else:
                    extruded = FaceRules.extrude(face,randint(int(self.minExtrude/3),int(self.maxExtrude/3))*3)
                    for i,element in enumerate(extruded):
                        if i == 4:
                            element.group = typeRoof
                        elif random(1) > 0.5:
                            element.group = typeFacade1
                        else:
                            element.group = typeFacade2
                    newFaces = extruded
                for cFace in newFaces:
                    newMesh.addFace(cFace)
            else:
                newMesh.addFace(face)

        newMesh.constructTopology()
        return newMesh

# class which extends the AbstractFactoryRule class, used to fabricate the Rule
class FactoryLowrise(AbstractFactoryRule):
    def fabricateRule(self):
        ruleLowrise=Lowrise()
        ruleLowrise.minExtrude=self.minExtrude.getValue()
        ruleLowrise.maxExtrude=self.maxExtrude.getValue()
        ruleLowrise.minSplit=self.minSplit.getValue()
        ruleLowrise.maxSplit=self.maxSplit.getValue()
        ruleLowrise.splits=self.splits.getValue()
        return ruleLowrise

    #add slider to the GUI, has to be named addComponents
    def addComponents(self,component):
        self.minExtrude=self.engine.cp5.addSlider(component.getName()+"minExtrude")
        self.minExtrude.setPosition(10,20)
        self.minExtrude.setRange(3,18)
        self.minExtrude.setLabel("minExtrude")
        self.minExtrude.moveTo(component)

        self.maxExtrude=self.engine.cp5.addSlider(component.getName()+"maxExtrude")
        self.maxExtrude.setPosition(10,40)
        self.maxExtrude.setRange(3,18)
        self.maxExtrude.setLabel("maxExtrude")
        self.maxExtrude.moveTo(component)

        self.splits=self.engine.cp5.addSlider(component.getName()+"splits")
        self.splits.setPosition(10,60)
        self.splits.setRange(0,1)
        self.splits.setLabel("splits")
        self.splits.moveTo(component)

        self.minSplit=self.engine.cp5.addSlider(component.getName()+"minSplit")
        self.minSplit.setPosition(10,80)
        self.minSplit.setRange(0.2,0.8)
        self.minSplit.setLabel("minSplit")
        self.minSplit.moveTo(component)

        self.maxSplit=self.engine.cp5.addSlider(component.getName()+"maxSplit")
        self.maxSplit.setPosition(10,100)
        self.maxSplit.setRange(0.2,0.8)
        self.maxSplit.setLabel("maxSplit")
        self.maxSplit.moveTo(component)


import matplotlib.pyplot as plt

def small_graph():
    small_graph_dict = dict(kivi={'visoki', 'viroza'},
                            viroza={'zarazni'},
                            zarazni={'niski', 'nitrati', 'niti'},
                            niski={'kivi'},
                            visoki={'kivi'},
                            nitrati={'tikovina'},
                            virulentni={'niski', 'nitrati'},
                            tikovina=set(),
                            niti={'tikovina'})
    graph = small_graph_dict
    dfs(small_graph_dict, 'kivi')
    # e = next(iter(graph))
    # print(e.startswith('Ki'.casefold()))
    # dfs(visited_set, graph, 'kivi')

def writing_ending_letters():
    ending_letters = set()
    with open('words_filled.csv', 'r') as file:
        reader = csv.reader(file, delimiter=',')
        for row in reader:
            # 0 index, 1 rijec, 2, pocetna slova, 3 zavrsna slova
            ending_letters.add(row[3])

    print(len(ending_letters))
    with open('ending_letters.txt', 'w') as f:
        f.write(str(ending_letters))

    ending_letters_dict = dict()
    for last_two_letters in ending_letters:
        with open('words_filled.csv', 'r') as file:
            reader = csv.reader(file, delimiter=',')
            set_of_connecting_words = set()
            for row in reader:
                if row[2] == last_two_letters:
                    set_of_connecting_words.add(row[1])
            ending_letters_dict[last_two_letters] = set_of_connecting_words

    print(ending_letters_dict)
    with open('ending_letters_dict.txt', 'w') as f:
        f.write(str(ending_letters_dict))

class Word:
    def __init__(self, text, visited: bool, ending_letters: string):
        self.connect_to_set = set()
        self.text = text
        self.visited = visited
        self.ending_letters = ending_letters

    def add_to_set(self, word_to_add):
        self.connect_to_set.add(word_to_add)

    def print_set_of_connecting_words(self):
        for w in self.connect_to_set:
            print(w.text)

def drawing_graph(list_of_words: [Word]):
    directed_graph = nx.DiGraph()
    for node in list_of_words:
        for edge in node.connect_to_set:
            directed_graph.add_edge(node.text, edge.text)
    nx.draw(directed_graph, with_labels=True)
    plt.show()
    # G.add_edges_from([('kivi', 'viroza'), ('kivi', 'visoki')])
    # print(G.nodes())
    # print(G.edges().data())

def reading_file_words_objects():
    with open('words_filled.csv', 'r') as file:
        reader = csv.reader(file, delimiter=',')
        words = []
        for row in itertools.islice(reader, 500):
            # print(row)
            # 0 index, 1 rijec, 2, pocetna slova, 3 zavrsna slova
            word = Word(row[1], False, row[3])
            words.append(word)
        for word_item in words:
            for w in words:
                if w.text.startswith(word_item.ending_letters):
                    word_item.add_to_set(w)

def playing_with_word_objects():
    kivi = Word('kivi', False, 'vi')
    visoki = Word('visoki', False, 'ki')
    viroza = Word('viroza', False, 'za')
    zarazni = Word('zarazni', False, 'ni')
    niski = Word('niski', False, 'ki')
    nitrati = Word('nitrati', False, 'ti')
    virulentni = Word('virulentni', False, 'ni')
    tikovina = Word('tikovina', False, 'na')

    graph_objects = {kivi: set([visoki, viroza]),
                     viroza: set([zarazni]),
                     zarazni: set([niski, nitrati]),
                     niski: set([kivi]),
                     visoki: set([kivi]),
                     nitrati: set([tikovina]),
                     virulentni: set([niski, nitrati]),
                     tikovina: set()}

def print_a_graph(visited: set(), graph, source):
    # This is not working properly
    print("==========")
    print(f"Source: {source}")
    visited_list.append(source)
    for node in graph:
        queue = [source]
        while len(queue) > 0:
            current = queue.pop()
            print(current)
            visited.add(current)
            for c in graph[current]:
                if c not in visited:
                    queue.append(c)


import numpy as np
from sklearn import svm
from sklearn.metrics import accuracy_score, confusion_matrix
import matplotlib.pyplot as plt
import seaborn as sns

def data_split(x, y, db):
    train_indexes = np.where(db.tr == 1)[0]
    test_indexs = [i for i in range(len(x)) if i not in train_indexes]
    x_train, y_train = x[train_indexes], y[train_indexes]
    x_test, y_test = x[test_indexs], y[test_indexs]

    return x_train, y_train, x_test, y_test

def plot_confusion_matrix(matrix, class_names):

    plt.figure(figsize=(6, 4))
    sns.heatmap(matrix, annot=True, fmt="d", cbar=False,
                xticklabels=class_names,
                yticklabels=class_names)
    plt.xlabel("Predicted labels")
    plt.ylabel("Real labels")
    plt.show()

def test_approach(x, db):
    y = db.label
    x_train, y_train, x_test, y_test = data_split(x, y, db)

    model = svm.SVC(C=20)
    model.fit(x_train, y_train)
    y_pred = model.predict(x_test)

    accuracy = accuracy_score(y_test, y_pred)
    print("Accuracy is: ", accuracy)

    # Calcola la matrice di confusione
    cf_matrix = confusion_matrix(y_test, y_pred)
    class_names = [db.id_class2name[id_label] for id_label in np.unique(y)]

    plot_confusion_matrix(cf_matrix, class_names)


from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_bcrypt import Bcrypt
from flask_login import LoginManager

# Initialize SQLAlchemy and Bcrypt extensions (not yet associated with any Flask app).
db = SQLAlchemy()
bcrypt = Bcrypt()

def create_app(config_name=None):
    """
    Create an instance of the Flask application.
    """
    app = Flask(__name__)

    # A secret key for signing session cookies
    app.config["SECRET_KEY"] = "93220d9b340cf9a6c39bac99cce7daf220167498f91fa"

    # Application configuration
    app.config["SQLALCHEMY_DATABASE_URI"] = "mysql+mysqldb://24_webapp_031:dGlvdf65@mysql.lab.it.uc3m.es/24_webapp_031c"
    # Uncomment the following line to use MySQL
    # app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///recipes.db'
    app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True

    db.init_app(app)

    # Login manager.
    login_manager = LoginManager()
    login_manager.login_view = 'auth.login'
    login_manager.init_app(app)

    # User loader for login management
    from . import model
    @login_manager.user_loader
    def load_user(user_id):
        return db.session.get(model.User, int(user_id))

    # Register blueprints
    from . import main, auth, explore
    app.register_blueprint(main.bp)
    app.register_blueprint(auth.bp)
    app.register_blueprint(explore.bp)

    return app


class SagresSimbaObj:
    nmFornecedor = ""
    cpf_cnpj = ""
    somaSimba = 0
    somaSagres = 0
    listaPagsSimba = []
    listaPagsSagres = []
    dictPagsMensaisSagres = {1: 0, 2: 0, 3: 0, 4: 0,
                             5: 0, 6: 0, 7: 0, 8: 0, 9: 0, 10: 0, 11: 0, 12: 0}
    dictPagsMensaisSimba = {1: 0, 2: 0, 3: 0, 4: 0,
                            5: 0, 6: 0, 7: 0, 8: 0, 9: 0, 10: 0, 11: 0, 12: 0}

    def __init__(self, _cpf_cnpj, _nmFornecedor, _listaSimba, _listaSagres):

        self.cpf_cnpj = _cpf_cnpj
        self.nmFornecedor = _nmFornecedor
        self.listaPagsSimba = _listaSimba
        self.listaPagsSagres = _listaSagres

        dictSimba = {1: 0, 2: 0, 3: 0, 4: 0, 5: 0,
                     6: 0, 7: 0, 8: 0, 9: 0, 10: 0, 11: 0, 12: 0}
        dictSagres = {1: 0, 2: 0, 3: 0, 4: 0, 5: 0,
                      6: 0, 7: 0, 8: 0, 9: 0, 10: 0, 11: 0, 12: 0}

        for s in self.listaPagsSagres:
            if (s != "\n"):
                l = s.split(",")
                vl = float(l[0])
                listaDt = str(l[1]).split("-")
                mes = int(listaDt[1])
                dictSagres[mes] += vl
                self.somaSagres += vl

        for s in self.listaPagsSimba:
            if (s != "\n"):
                l = s.split(",")
                vl = float(l[0])
                listaDt = str(l[1]).split("-")
                mes = int(listaDt[1])
                dictSimba[mes] += vl
                self.somaSimba += vl

        self.dictPagsMensaisSagres = dictSagres
        self.dictPagsMensaisSimba = dictSimba


#!usr/bin/env python3
# coding=utf-8
# @IDE    :PyCharm
# @File   :vtk_save.py
# @Date   :2019/5/8

from vtk.util.vtkImageImportFromArray import *
import vtk
import SimpleITK as sitk
import cv2
import numpy as np

def getSeg(source, mask):
    source = np.reshape(source,(512,512))
    mask = np.reshape(mask,(512,512))*255
    kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
    masks = cv2.erode(mask, kernel)
    _, contours, _ = cv2.findContours(masks, cv2.RETR_TREE,
                                      cv2.CHAIN_APPROX_SIMPLE)
    for i in range(512):
        for j in range(512):
            res = cv2.pointPolygonTest(contours[0], (i, j), False)
            if res == -1:
                source[j, i] = 0.0
    return source

v_path = r'F:\sliver_07\volume-0.nii'
s_path = r'F:\sliver_07\segmentation-0.nii'  # segmentation volume
ds = sitk.ReadImage(s_path)
s_data = sitk.GetArrayFromImage(ds)
s_data[s_data == 2] = 1
s_data = s_data[40:]
s_data = s_data.astype(np.uint8)
print(s_data.shape)
# print('------------read end segmentation---------------')
# dv = sitk.ReadImage(v_path)
# v_data = sitk.GetArrayFromImage(dv)
# print('------------read end volume---------------')
# result = []
# for i in range(v_data.shape[0]):
#     if np.sum(s_data[i] == 1) < 5:
#         data = np.zeros(shape=[512, 512], dtype=np.float32)
#         result.append(data)
#         continue
#     print(i)
#     data = getSeg(v_data[i],s_data[i])
#     result.append(data)
# result = np.array(result)
# print('------------seg end---------------')
spacing = ds.GetSpacing()
print(spacing)

img_arr = vtkImageImportFromArray()
img_arr.SetArray(s_data)
img_arr.SetDataSpacing(spacing)
origin = (0, 0, 0)
img_arr.SetDataOrigin(origin)
img_arr.Update()
srange = img_arr.GetOutput().GetScalarRange()
print(srange)
print(img_arr.GetOutput().GetSpacing())
min = srange[0]
max = srange[1]
diff = max - min
slope = 4000 / diff
inter = -slope * min
shift = inter / slope

shifter = vtk.vtkImageShiftScale()  # 对偏移和比例参数来对图像数据进行操作 数据转换
shifter.SetShift(shift)
shifter.SetScale(slope)
shifter.SetOutputScalarTypeToUnsignedShort()
shifter.SetInputData(img_arr.GetOutput())
shifter.ReleaseDataFlagOff()
shifter.Update()

print(shifter.GetOutput().GetSpacing())

skinExtractor = vtk.vtkContourFilter()
skinExtractor.SetInputConnection(shifter.GetOutputPort())
skinExtractor.SetValue(0,10)

# vtkWriter = vtk.vtkXMLImageDataWriter()
vtkWriter = vtk.vtkPolyDataWriter()
vtkWriter.SetInputConnection(skinExtractor.GetOutputPort())
vtkWriter.SetFileName('../result/seg.vtk')
vtkWriter.Write()
print('------------write end---------------')

# def StartInteraction():
#     renWin.SetDesiredUpdateRate(10)
#
# def EndInteraction():
#     renWin.SetDesiredUpdateRate(0.001)
#
# def ClipVolumeRender(obj):
#     obj.GetPlanes(planes)
#     volumeMapper.SetClippingPlanes(planes)
#
# ren = vtk.vtkRenderer()
# renWin= vtk.vtkRenderWindow()
# renWin.AddRenderer(ren)
# iren = vtk.vtkRenderWindowInteractor()
# iren.SetRenderWindow(renWin)
#
# tfun = vtk.vtkPiecewiseFunction()  # 梯度不透明度函数
# tfun.AddPoint(1000.0, 0)
# tfun.AddPoint(2300.0, 0.3)
# tfun.AddPoint(2501.0, 0.4)
# tfun.AddPoint(2600.0, 0.5)
# tfun.AddPoint(2700.0, 0.6)
# tfun.AddPoint(2900.0, 0.7)
# tfun.AddPoint(3024.0, 1)
#
#
# ctfun = vtk.vtkColorTransferFunction()  # 颜色传输函数
# ctfun.AddRGBPoint(0.0, 0.5, 0.0, 0.0)
# ctfun.AddRGBPoint(600.0, 1.0, 0.5, 0.5)
# ctfun.AddRGBPoint(1280.0, 0.9, 0.2, 0.3)
# ctfun.AddRGBPoint(1960.0, 0.81, 0.27, 0.1)
# ctfun.AddRGBPoint(2200.0, 0.9, 0.2, 0.3)
# ctfun.AddRGBPoint(2500.0, 1, 0.5, 0.5)
# ctfun.AddRGBPoint(3024.0, 0.5, 0.5, 0.5)
#
# volumeMapper = vtk.vtkGPUVolumeRayCastMapper()
# volumeMapper.SetInputData(shifter.GetOutput())
# volumeProperty = vtk.vtkVolumeProperty()
# volumeProperty.SetColor(ctfun)
# volumeProperty.SetScalarOpacity(tfun)
# volumeProperty.SetInterpolationTypeToLinear()
# volumeProperty.ShadeOn()
#
# newvol = vtk.vtkVolume()
# newvol.SetMapper(volumeMapper)
# newvol.SetProperty(volumeProperty)
#
# outline = vtk.vtkOutlineFilter()
# outline.SetInputConnection(shifter.GetOutputPort())
#
# outlineMapper = vtk.vtkPolyDataMapper()
# outlineMapper.SetInputConnection(outline.GetOutputPort())
#
# outlineActor = vtk.vtkActor()
# outlineActor.SetMapper(outlineMapper)
#
# ren.AddActor(outlineActor)
# ren.AddVolume(newvol)
# ren.SetBackground(0, 0, 0)
# renWin.SetSize(600, 600)
#
# planes = vtk.vtkPlanes()
#
# boxWidget = vtk.vtkBoxWidget()
# boxWidget.SetInteractor(iren)
# boxWidget.SetPlaceFactor(1.0)
# boxWidget.PlaceWidget(0,0,0,0,0,0)
# boxWidget.InsideOutOn()
# boxWidget.AddObserver("StartInteractionEvent", StartInteraction)
# boxWidget.AddObserver("InteractionEvent",  ClipVolumeRender)
# boxWidget.AddObserver("EndInteractionEvent",  EndInteraction)
#
# outlineProperty = boxWidget.GetOutlineProperty()
# outlineProperty.SetRepresentationToWireframe()
# outlineProperty.SetAmbient(1.0)
# outlineProperty.SetAmbientColor(1, 1, 1)
# outlineProperty.SetLineWidth(9)
#
# selectedOutlineProperty = boxWidget.GetSelectedOutlineProperty()
# selectedOutlineProperty.SetRepresentationToWireframe()
# selectedOutlineProperty.SetAmbient(1.0)
# selectedOutlineProperty.SetAmbientColor(1, 0, 0)
# selectedOutlineProperty.SetLineWidth(3)
#
# ren.ResetCamera()
# iren.Initialize()
# renWin.Render()
# iren.Start()


from flask import Flask, render_template, url_for, request, redirect
import json
from datetime import datetime

app = Flask(__name__)
print(__name__)

@app.route("/")
def my_home():
    return render_template("index.html")

@app.route("/success.html")
def my_success():
    return render_template("success.html")

def save_to_db(data):
    print(f"Saving to db: {data}")
    return True

@app.route("/submit_form", methods=["POST"])
def submit_form():
    data_dict = request.form.to_dict()
    print(f"Received: {data_dict}")

    name = data_dict["name"]

    dob = data_dict["dob"]
    current_year = int(datetime.now().strftime("%Y"))
    dob_year = int(dob.split("-")[0])
    age = current_year - dob_year

    # Address: City State Country
    address = data_dict["address"]
    address_parts = address.split(" ")
    city = address_parts[0]
    state = address_parts[1]
    country = address_parts[2]
    location = f"{city},{state},{country}"

    save_data = {
        "name": name,
        "age": age,
        "location": location
    }

    saved = save_to_db(save_data)
    if saved:
       return redirect("success.html")


from __future__ import print_function
import Pyro4
import person

Pyro4.config.SERIALIZER = 'pickle'
Pyro4.config.SERIALIZERS_ACCEPTED.add('pickle')
Pyro4.config.REQUIRE_EXPOSE = True
Pyro4.config.DETAILED_TRACEBACK = True

class Warehouse(object):
    def __init__(self):
        self.contents = ["chair", "bike", "flashlight", "laptop", "couch"]

    def list_contents(self):
        return self.contents

    def take(self, name, item):
        self.contents.remove(item)
        print("{0} took the {1}.".format(name, item))

    def store(self, name, item):
        self.contents.append(item)
        print("{0} stored the {1}.".format(name, item))

def main():
    warehouse = Warehouse()
    #Pyro4.config.HOST = "129.174.126.30:5555"
    daemon = Pyro4.Daemon()
    Pyro4.Daemon.serveSimple(
            {
                warehouse: "example.warehouse"
            },
	    daemon=daemon,
            ns = False)

if __name__=="__main__":
    main()


# Created by matveyev at 04.08.2021
import numpy as np
from PyQt5 import QtWidgets, QtCore
import logging

from petra_viewer.main_window import APP_NAME
from petra_viewer.gui.array_selector_ui import Ui_ArraySelector

logger = logging.getLogger(APP_NAME)

class ArraySelector(QtWidgets.QWidget):

    def __init__(self, my_id, cut_selector, data_pool, frame_viewer):
        """
        """
        super(ArraySelector, self).__init__()
        self._ui = Ui_ArraySelector()
        self._ui.setupUi(self)

        self._my_id = my_id
        self.limit_range = 0
        self._max_frame = 0

        self._old_z_min = None
        self._old_z_max = None

        self._data_pool = data_pool
        self._frame_viewer = frame_viewer
        self._cut_selector = cut_selector

        self._ui.sl_frame.valueChanged.connect(self._update_from_frame_slider)
        self._ui.sl_range.sliderMoved.connect(self._update_from_range_slider)

        self._ui.but_first.clicked.connect(lambda: self._update_from_navigation_buttons('first'))
        self._ui.but_previous.clicked.connect(lambda: self._update_from_navigation_buttons('previous'))
        self._ui.but_next.clicked.connect(lambda: self._update_from_navigation_buttons('next'))
        self._ui.but_last.clicked.connect(lambda: self._update_from_navigation_buttons('last'))

        self._ui.sp_value_from.editingFinished.connect(self._update_from_sp)
        self._ui.sp_value_to.editingFinished.connect(self._update_from_sp)

        self._ui.cmd_show_all.clicked.connect(self._show_all)

    # ----------------------------------------------------------------------
    def _new_cut(self):
        self._old_z_min = self._ui.sl_range.low()
        self._old_z_max = self._ui.sl_range.high()
        self._cut_selector.new_range(self._my_id)

    # ----------------------------------------------------------------------
    def switch_integration_mode(self, state):

        self._ui.sl_frame.setVisible(not state)
        self._ui.sl_range.setVisible(state)
        self._ui.sp_value_to.setVisible(state)
        self._ui.lb_to.setVisible(state)

    # ----------------------------------------------------------------------
    def _show_all(self):
        self._set_spin_boxes(0, self._max_frame)
        self._set_slider_value(0, self._max_frame)

        self._old_z_min = self._ui.sl_range.low()
        self._old_z_max = self._ui.sl_range.high()

        self._cut_selector.set_integration(self._my_id)

    # ----------------------------------------------------------------------
    def _update_from_frame_slider(self, value):
        """
        Set value of range slider and spin_boxes
        """
        self._set_spin_boxes(value, value)
        self._set_slider_value(value, value)
        self._new_cut()

    # ----------------------------------------------------------------------
    def _update_from_range_slider(self, z_min, z_max):
        """
        Set value of range slider and spin_boxes
        """
        z_min, z_max = self._apply_range_limit(z_min, z_max)
        self._set_spin_boxes(z_min, z_max)
        self._set_slider_value(z_min, z_max)
        self._new_cut()

    # ----------------------------------------------------------------------
    def _update_from_navigation_buttons(self, mode):
        """
        Process button_clink on navigation buttons
        """
        z_min = self._ui.sl_range.low()
        z_max = self._ui.sl_range.high()

        new_min = z_min
        new_max = z_max

        if mode == 'first':
            new_min = 0
        elif mode == 'previous':
            new_min -= 1
            new_max -= 1
        elif mode == 'next':
            new_min += 1
            new_max += 1
        elif mode == 'last':
            new_max = self._max_frame
            if z_min == z_max:
                new_min = self._max_frame

        new_max = min(max(0, new_max), self._max_frame)
        new_min = min(max(0, new_min), self._max_frame)
        new_min, new_max = self._apply_range_limit(new_min, new_max)

        self._set_spin_boxes(new_min, new_max)
        self._set_slider_value(new_min, new_max)
        self._new_cut()

    # ----------------------------------------------------------------------
    def _update_from_sp(self):
        """
        Set values to slider given in the SpinBox.
        """
        z_min = self._value_to_frame(self._ui.sp_value_from.value())
        z_max = self._value_to_frame(self._ui.sp_value_to.value())
        z_min, z_max = self._apply_range_limit(z_min, z_max)

        if z_min != self._old_z_min or z_max != self._old_z_max:
            self._set_slider_value(z_min, z_max)
            self._set_spin_boxes(z_min, z_max)
            self._new_cut()

    # ----------------------------------------------------------------------
    def _set_slider_value(self, z_min, z_max):
        """
        Set values to slider.
        """
        self.blockSignals(True)
        self._ui.sl_frame.setValue(z_min)
        self._ui.sl_range.setLow(z_min)
        self._ui.sl_range.setHigh(z_max)
        self.blockSignals(False)

    # ----------------------------------------------------------------------
    def units_changed(self):
        self.blockSignals(True)

        decimals = self._data_pool.get_axis_resolution(self._frame_viewer.current_file(), self._my_id)

        self._ui.sp_value_from.setDecimals(decimals)
        self._ui.sp_value_from.setSingleStep(np.power(10., -decimals))
        self._ui.sp_value_to.setDecimals(decimals)
        self._ui.sp_value_to.setSingleStep(np.power(10., -decimals))

        self._ui.sp_step.setDecimals(decimals)
        self._ui.sp_step.setSingleStep(np.power(10., -decimals))
        self._ui.sp_step.setValue(np.power(10., -decimals))

        self._ui.sl_range.setSingleStep(np.power(10., -decimals))
        self._ui.sl_frame.setSingleStep(np.power(10., -decimals))

        self._ui.sp_value_to.setMinimum(self._frame_to_value(0))
        self._ui.sp_value_to.setMaximum(self._frame_to_value(self._ui.sl_range.maximum()))

        self._ui.sp_value_from.setMinimum(self._frame_to_value(0))
        self._ui.sp_value_from.setMaximum(self._frame_to_value(self._ui.sl_range.maximum()))

        self._ui.sp_value_from.setValue(self._frame_to_value(self._ui.sl_range.low()))
        self._ui.sp_value_to.setValue(self._frame_to_value(self._ui.sl_range.high()))

        self.blockSignals(False)

    # ----------------------------------------------------------------------
    def _frame_to_value(self, frame):
        return self._data_pool.get_value_for_frame(self._frame_viewer.current_file(), self._my_id, frame)

    # ----------------------------------------------------------------------
    def _value_to_frame(self, frame):
        return self._data_pool.get_frame_for_value(self._frame_viewer.current_file(), self._my_id, frame)

    # ----------------------------------------------------------------------
    def _set_spin_boxes(self, z_min, z_max):
        """
        Set value of spin_boxes sp_value_from, sp_value_to and sp_step
        """
        self.blockSignals(True)

        z_min = self._frame_to_value(z_min)
        z_max = self._frame_to_value(z_max)

        self._ui.sp_value_from.setValue(z_min)
        self._ui.sp_value_to.setValue(z_max)

        self.blockSignals(False)

    # ----------------------------------------------------------------------
    def _apply_range_limit(self, z_min, z_max):
        z_min = max(0, min(z_min, z_max))
        if 0 < self.limit_range - 1 < (z_max - z_min):
            z_max = self.limit_range + z_min - 1
        return z_min, z_max

    # ----------------------------------------------------------------------
    def setup_limits(self, max_frame):
        """
        Set limits to sliders and spin_boxes
        """
        self.blockSignals(True)
        logger.debug(f"Setup_limits of {max_frame} for {self._my_id}")

        self._ui.sl_frame.setMaximum(max_frame)
        self._ui.sl_range.setMaximum(max_frame)
        self._ui.sl_range.setMinimum(0)

        self._ui.sp_value_to.setMinimum(self._frame_to_value(0))
        self._ui.sp_value_to.setMaximum(self._frame_to_value(max_frame))

        self._ui.sp_value_from.setMinimum(self._frame_to_value(0))
        self._ui.sp_value_from.setMaximum(self._frame_to_value(max_frame))

        self._max_frame = max_frame

        self.blockSignals(False)

    # ----------------------------------------------------------------------
    def set_section(self, section):

        decimals = self._data_pool.get_axis_resolution(self._frame_viewer.current_file(), self._my_id)

        self._ui.sp_value_from.setDecimals(decimals)
        self._ui.sp_value_to.setDecimals(decimals)
        self._ui.sp_step.setDecimals(decimals)

        self._ui.sp_step.setMinimum(np.power(10., -decimals))

        if section['axis'] in ['X', 'Y']:
            self.switch_integration_mode(True)
        else:
            self.switch_integration_mode(section['integration'])

        self.limit_range = section['range_limit']
        self._ui.sp_step.setValue(section['step'])
        self._set_slider_value(section['min'], section['max'])
        self._set_spin_boxes(section['min'], section['max'])
        self._old_z_min = section['min']
        self._old_z_max = section['max']

    # ----------------------------------------------------------------------
    def get_values(self):
        return int(self._ui.sl_range.low()), int(self._ui.sl_range.high())

    # ----------------------------------------------------------------------
    def blockSignals(self, flag):
        self._ui.sl_frame.blockSignals(flag)
        self._ui.sl_range.blockSignals(flag)
        self._ui.sp_step.blockSignals(flag)
        self._ui.sp_value_from.blockSignals(flag)
        self._ui.sp_value_to.blockSignals(flag)


"""
Hacker Rank - Missing numbers
https://www.hackerrank.com/challenges/missing-numbers
"""

def find_missing(size_smaller, smaller_list, size_larger, larger_list):
    count_freq_smaller = {} #count the freq of smaller list
    count_freq_larger = {}  #count freq of larger list
    for num in smaller_list:
        if num in count_freq_smaller:
            count_freq_smaller[num] += 1
        else:
            count_freq_smaller[num] = 1
    for num in larger_list:
        if num in count_freq_larger:
            count_freq_larger[num] += 1
        else:
            count_freq_larger[num] = 1
    missing_nums = []
    for key in sorted(count_freq_larger.keys()):
        if (key not in count_freq_smaller) or (count_freq_larger[key] > count_freq_smaller[key]):
            missing_nums.append(key)
    return missing_nums

def main():
    size_list1 = int(input().strip())
    num_list1 = [int(i) for i in input().strip().split(' ')]
    size_list2 = int(input().strip())
    num_list2 = [int(i) for i in input().strip().split(' ')]
    missing_nos = find_missing(size_list1, num_list1, size_list2, num_list2)
    for miss in missing_nos:
        print(miss, end=' ')

if __name__ == '__main__':
    main()


import setuptools

with open("./README.md", "r") as file:
    long_description = file.read()

setuptools.setup(
    name="httpcats",
    version="1.1.1",
    author="itsmewulf",
    author_email="wulf.developer@gmail.com",
    description="Get URLs to your favourite HTTP Cats easily!",
    long_description=long_description,
    long_description_content_type="text/markdown",
    url="https://github.com/itsmewulf/httpcats",
    keywords="cat, http, request, api, wrapper",
    packages=setuptools.find_packages(),
    include_package_data=True,
    classifiers=[
        "Programming Language :: Python :: 3",
        "License :: OSI Approved :: MIT License",
        "Operating System :: OS Independent",
    ],
    python_requires='>=3.6'
)


# # 10 5 4 2 1 4
# # 10 9 3 1 3

# # [10, 10, 10]
# # [9, 5, 10]
# # [3, 8, 9], [4, 5, 5]
# # [1, 4]

# # [K] * 3 + [K]*3 +[K]+ 3
# n = int(input())
# nums = [n]
# tmp = []
# c = 0

# while 1 not in nums:
#     for i in range(len(nums)):
#         if nums[i] % 3 == 0 and nums[i]%3 not in tmp:
#             tmp.append(nums[i]//3)
#         if nums[i] % 2 == 0 and nums[i]%2 not in tmp:
#             tmp.append(nums[i]//2)
#         if nums[i]-1 not in tmp:
#             tmp.append(nums[i]-1)
#     nums = tmp
#     tmp = []
#     c += 1
# print(c)

n = int(input())
nums = set()
nums.add(n)
tmp = set()
c = 0

while 1 not in nums:
    for i in nums:
        if i % 3 == 0:
            tmp.add(i//3)
        if i % 2 == 0:
            tmp.add(i//2)
        if i-1 not in tmp and i-1 > 0:
            tmp.add(i-1)
    nums = tmp.copy()
    tmp = set()
    c += 1

print(c)

알고리즘 단계/동적 계획법1/1로 만들기.py


import random
rock = '''
    _______
---'   ____)
      (_____)
      (_____)
      (____)
---.__(___)
'''

paper = '''
    _______
---'   ____)____
          ______)
          _______)
         _______)
---.__________)
'''

scissors = '''
    _______
---'   ____)____
          ______)
       __________)
      (____)
---.__(___)
'''

images = [rock, paper, scissors]

print("Welcome to Rock, Paper, Scissor Game!\n")

player = int(input("Type 0 for Rock, 1 for Paper or 2 for Scissors. \n"))

computer = random.randint(0, 2)
if player < 0 or player > 3:
    print("You enter wrong number!")
else:
    print(images[player])
    print(f"Computer chose... {computer}")
    print(images[computer])

if player == computer:
    print("It's a Tie!")

elif (player == 0 and computer == 2) or \
     (player == 2 and computer == 1) or \
     (player == 1 and computer == 0):
      print("You Win!")
elif (computer == 0 and player == 2) or \
     (computer == 2 and player == 1) or \
     (computer == 1 and player == 0):
      print("You Loose!")

else:
    print("No one Wins!")


print('='*12 + ' DESAFIO 41 ' + '='*12)
from datetime import date
ano = int(input('Digite seu ano de nascimento: '))
idade = date.today().year - ano
print('O atleta tem {} anos.'.format(idade))
if idade <= 9:
    classe = 'Mirim'
elif 9 < idade <= 14:
    classe = 'Infantil'
elif 14 < idade <= 19:
    classe = 'Junior'
elif 19 < idade <= 25:
    classe = 'Sênior'
else:
    classe = 'Master'
print('Classificação: \033[1m{}\033[m'.format(classe))


from setuptools import setup, find_packages

VERSION = '0.0.1'
DESCRIPTION = 'A package with useful functions relating to space.'

setup(
    name="Spacemath",
    version=VERSION,
    author="Periareion (Anton Sollman)",
    author_email="<periareion05@gmail.com>",
    description=DESCRIPTION,
    packages=find_packages(),
    install_requires=['numpy'],
    keywords=['space', 'math'],
    classifiers=[
        "Programming Language :: Python :: 3",
        "Operating System :: Unix",
        "Operating System :: MacOS :: MacOS X",
        "Operating System :: Microsoft :: Windows",
    ]
)


import os
import traceback
from django.core.management.base import BaseCommand, CommandError, NoArgsCommand
from django.conf import settings
from azurepython3.blobservice import BlobService

class Command(NoArgsCommand):
    help = """Migrate from an existing FileSystemStorage to AzureStorage.
When executing the command "azuremigrate" it will scan for media files in MEDIA_ROOT
and upload all the files to the configured default container."""

    def handle_noargs(self, **options):
        # ensure that project has required configuration
        if not os.path.exists(settings.MEDIA_ROOT):
            raise CommandError('Cannot migrate files from non existing MEDIA_ROOT (%s)' % settings.MEDIA_ROOT)
        if not hasattr(settings, 'AZURE_ACCOUNT_NAME'):
            raise CommandError('AZURE_ACCOUNT_NAME setting missing')
        if not hasattr(settings, 'AZURE_ACCOUNT_KEY'):
            raise CommandError('AZURE_ACCOUNT_KEY setting missing')
        if not hasattr(settings, 'AZURE_DEFAULT_CONTAINER'):
            raise CommandError('AZURE_DEFAULT_CONTAINER settings missing')

        # get service interface
        service = BlobService(settings.AZURE_ACCOUNT_NAME, settings.AZURE_ACCOUNT_KEY)

        self.stdout.write('Starting migration from "%s" to '
                          'Cloud Storage container "%s"' % (settings.MEDIA_ROOT, settings.AZURE_DEFAULT_CONTAINER))

        for root, dirs, files in os.walk(settings.MEDIA_ROOT):
            for file in files:
                path = os.path.join(root, file)
                blobname = os.path.relpath(path, settings.MEDIA_ROOT).replace('\\', '/')
                self.stdout.write(blobname + "...", ending='')
                try:
                    with open(path, 'rb') as f:
                        if service.create_blob(settings.AZURE_DEFAULT_CONTAINER, blobname, bytearray(f.read())):
                            self.stdout.write('ok')
                        else:
                            self.stdout.write('fail')
                except Exception as e:
                    self.stdout.write('fail')
                    traceback.print_exc()
                    self.stdout.write('aborted migration.')
                    return

        self.stdout.write('migration complete')


#-----------------------------------------------------------------------------
# ------------------------------------------------------- wortlabyrinth.py m n
# ------------------------------------------------------- erstellt: 01.02.2022
#-----------------------------------------------------------------------------
# Beschreibung: Ein Programm zum Erstellen von Wortlabyrinthen. Der Lösungsweg
# wird entlang eines Lösungssatzes gezeichnet. Das Labyrinth
import os
os.environ['PYGAME_HIDE_SUPPORT_PROMPT'] = "hide" # unterdrücke die pygame-Nachricht in der Konsole
import pygame
import random
import string # nötig für Buchstaben
string.ascii_letters # 'abcde....ABCDE...'
import sys
sys.setrecursionlimit(4000) # höhere Rekursionstiefe für komplexere Labyrinthe (>20x20)

m = int(sys.argv[1]) # Anzahl der ZEILEN
n = int(sys.argv[2]) # Anzahl der SPALTEN

if n < 3 or m < 3: # Fehlerbehandlung für zu kleine Matrix
	print('Error: n and m Dimensionen müssen mindestens 2x2 sein!')
	sys.exit()
if n > 40 or m > 40:  # Fehlerbehandlung für zu große Matrix
	print('Error: n and m Dimensionen dürfen nicht größer als 40 sein!')
	sys.exit()

satz = input('Gib deinen Lösungssatz ein:')
if len(satz) < n + m:
	print('FEHLER: Lösungssatz ist zu kurz für die gewünschte Labyrinthgröße.')
	sys.exit()

# Input String formatieren
satz = satz.upper() # alle Buchstaben in Grossbuchstaben
satz = ''.join(filter(str.isalnum, satz)) # Sonderzeichen entfernen
satz = ''.join([i for i in satz if not i.isdigit()]) # Zahlen entfernen
print('formatierter Lösungssatz:',satz, '| Buchstabenzahl:',len(satz))

BREITE = n * 50  # Bildschirmgröße in Pixel (angepasst auf Labyrinth-Maße)
HÖHE = m * 50
# BREITE = 1000  # Bildschirmgröße in Pixel (vordefinierte Maße)
# HÖHE = 1000

SPALTEN = n
ZEILEN = m
ZE_BH = BREITE // SPALTEN # Zellengröße (Breite-Höhe)

delta_linien = {'l':[(0,0),(0,ZE_BH)], 'r':[(ZE_BH,0),(ZE_BH,ZE_BH)], 'o':[(0,0),(ZE_BH,0)], 'u': [(0,ZE_BH),(ZE_BH,ZE_BH)]} # Wandpositionen (Linien)
delta_nachbarn = {'l':(-ZE_BH,0), 'r':(ZE_BH,0), 'o':(0,-ZE_BH), 'u':(0,ZE_BH)} # l = links, r = rechts, o = oben, u = unten
richtung_invers = {'l':'r', 'r':'l', 'o':'u', 'u':'o'} # gegenüberliegende Seiten

pygame.init() # Anfangsbildschirm initialisieren
screen = pygame.display.set_mode([BREITE,HÖHE])
farbe_hintergrund = pygame.Color('White')
farbe_linie = pygame.Color('Black')
# farbe_weg = pygame.Color('Green') # momentan nicht in Verwendung

def raster_erstellen():
	for i in range(SPALTEN*ZEILEN):
		pos = i % SPALTEN * ZE_BH, i // SPALTEN * ZE_BH
		raster[pos] = {b for b in 'lrou'} # 4 Zellwände an einer Raster-Position (set comprehension)

def add_pos(pos1,pos2):
	return pos1[0] + pos2[0], pos1[1] + pos2[1]

def zeichne_zelle(pos,wände):
	for wand in wände:
		delta_von, delta_bis = delta_linien[wand]
		von = add_pos(pos,delta_von)
		bis = add_pos(pos,delta_bis)
		pygame.draw.line(screen,farbe_linie,von,bis,4) # strichstärke 4

def nachbarn_ermitteln(pos):
	nachb = []
	for richtung, delta in delta_nachbarn.items():
		neue_pos = add_pos(pos,delta)
		if neue_pos not in raster: continue # schnappt sich die nächste Richtung
		nachb.append((richtung,neue_pos))
	random.shuffle(nachb)
	return nachb

def labyrinth_erstellen(pos_aktuell,richtung_von):
	besucht.add(pos_aktuell)
	raster[pos_aktuell].remove(richtung_von)
	nachb = nachbarn_ermitteln(pos_aktuell)
	for richtung_nach, pos_neu in nachb:
		if pos_neu in besucht: continue
		raster[pos_aktuell].remove(richtung_nach)
		labyrinth_erstellen(pos_neu, richtung_invers[richtung_nach]) # lösche die Wand aus der neuen Zelle in die ich reingehe

def mögliche_richtungen(pos):
	richtungen = []
	for richtung,delta in delta_nachbarn.items():
		neue_pos = add_pos(pos,delta)
		if neue_pos not in raster: continue
		if richtung in raster[pos]: continue
		richtungen.append(neue_pos)
	return richtungen

def labyrinth_lösen(pos_aktuell):
	besucht.append(pos_aktuell)
	if pos_aktuell == ziel:
		# print('aktuelle position ist das Ziel!',pos_aktuell,'Ziel:',ziel)
		return True
	for pos_neu in mögliche_richtungen(pos_aktuell):
		if pos_neu in besucht: continue
		if labyrinth_lösen(pos_neu):
			weg.append(pos_neu)
			# print('Weg nimmt zu:',weg) # überprüfen der Lösungs-Wegpukte
			return True

ziel = ((SPALTEN-1)*ZE_BH,(ZEILEN-1)*ZE_BH) # Koordinaten der Zielzelle
solution = False
iteration = 0

while solution == False:
	iteration += 1
	if iteration > 2000: # definiertes Limit für Anzahl an zufällig generierten Labyrinthen
		print('Keine Lösung nach 2000 Iterationen gefunden!')
		sys.exit()
	raster = {}
	raster_erstellen()
	weg = []
	besucht = set()
	labyrinth_erstellen((0,0),'l')
	besucht = []
	labyrinth_lösen((0,0))
	weg.append((0,0)) # Startposition hinzufügen
	if len(satz) == len(weg):
		solution = not solution # boolean auf 'True' setzen um 'while' Loop zu beenden
		print('Lösung nach',iteration,'Iterationen gefunden!')

screen.fill(farbe_hintergrund)
for pos,wände in raster.items():
	zeichne_zelle(pos,wände)
pygame.display.flip()
pygame.image.save(screen,'lab_1.png') # Screenshot 1 mit dem leeren Labyrinth

schrift = pygame.font.SysFont('Arial',40)
invers_satz = satz[::-1] # Inverse des Lösungssatzes

i = 0
while i < len(invers_satz):
	buchstabe = schrift.render(invers_satz[i], 1, (0,0,1), None) # Attribute: 'string', antialias, color, ?
	x,y = weg[i]
	x = x + ZE_BH // 3.5 # Buchstaben in mittlere Position innerhalb einer Zelle schieben
	screen.blit(buchstabe,(x,y)) # Buchstabe zeichnen
	pygame.display.flip()
	i += 1
pygame.image.save(screen,'lab_2.png') # Screenshot 2 mit dem Lösungsweg

for pos in raster.items(): # Zufällige Buchstaben in alle Felder setzen, die nicht Teil der Lösung sind
	if pos[0] not in weg:
		buchstabe = schrift.render(random.choice(string.ascii_letters).upper(), 1, (0,0,1), None) # Attribute: 'string', antialias, color, ?
		x,y = pos[0]
		x = x + ZE_BH // 3.5 # Buchstaben in mittlere Position innerhalb einer Zelle schieben
		screen.blit(buchstabe,(x,y)) # Buchstabe zeichnen
		pygame.display.flip()
pygame.image.save(screen,'lab_3.png') # Screenshot 3 mit dem kompletten Labyrinth

pygame.quit()


from __future__ import annotations

import re
import urllib.parse
from functools import partial
from typing import Any

from bs4 import BeautifulSoup
from markdownify import MarkdownConverter  # type: ignore
import aiohttp

try:
    import lxml  # type: ignore

    HTML_PARSER = "lxml"
except ImportError:
    HTML_PARSER = "html.parser"

class DocMarkdownConverter(MarkdownConverter):
    def convert_pre(self, el, text):
        """Wrap any codeblocks in `py` for syntax highlighting."""
        code = "".join(el.strings)

        return f"```py\n{code}```"

def markdownify(html: Any):
    return DocMarkdownConverter(bullets="\N{BULLET}").convert(html)

async def get_url_response(url: str):
    async with aiohttp.ClientSession() as session:
        return await session.get(url)

async def _process_mozilla_doc(url: str):
    """
    From a given url from developers.mozilla.org, processes format,
    returns tag formatted content
    """
    response = await get_url_response(url)
    if response.status == 404:
        return "No results"
    if response.status != 200:
        return f"An error occurred (status code: {response.status}). Retry later."

    body = BeautifulSoup(await response.text(), HTML_PARSER).find("body")

    contents = body.find(id="wikiArticle").find(lambda x: x.name == "p" and x.text)
    return markdownify(contents).replace(
        "(/en-US/docs", "(https://developer.mozilla.org/en-US/docs"
    )

async def html_ref(text: str):
    """Displays informations on an HTML tag"""
    text = text.strip("<>`")

    base_url = f"https://developer.mozilla.org/en-US/docs/Web/HTML/Element/{text}"
    url = urllib.parse.quote_plus(base_url, safe=";/?:@&=$,><-[]")

    output = await _process_mozilla_doc(url)
    if not isinstance(output, str):
        # Error message already sent
        return

    return output

async def _http_ref(part, text: str):
    """Displays informations about HTTP protocol"""
    base_url = f"https://developer.mozilla.org/en-US/docs/Web/HTTP/{part}/{text}"
    url = urllib.parse.quote_plus(base_url, safe=";/?:@&=$,><-[]")

    output = await _process_mozilla_doc(url)
    if not isinstance(output, str):
        # Error message already sent
        return

    return output

http_headers = partial(_http_ref, "Headers")
http_methods = partial(_http_ref, "Methods")
http_status = partial(_http_ref, "Status")
csp_directives = partial(_http_ref, "Headers/Content-Security-Policy")

async def _git_main_ref(part: str, text: str):
    """Displays a git help page"""
    text = text.strip("`")

    if part and text == "git":
        # just 'git'
        part = ""
    if not part and not text.startswith("git"):
        # gittutorial, giteveryday...
        part = "git"
    base_url = f"https://git-scm.com/docs/{part}{text}"
    url = urllib.parse.quote_plus(base_url, safe=";/?:@&=$,><-[]")

    response = await get_url_response(url)
    if response.status != 200:
        return f"An error occurred (status code: {response.status}). Retry later."
    if str(response.url) == "https://git-scm.com/docs":
        # Website redirects to home page
        return "No results"

    soup = BeautifulSoup(await response.text(), HTML_PARSER)
    sectors = soup.find_all("div", {"class": "sect1"}, limit=3)

    title = sectors[0].find("p").text

    ls = []
    for tag in sectors[1:]:
        content = "\n".join(
            [markdownify(p) for p in tag.find_all(lambda x: x.name in ["p", "pre"])]
        )
        ls.append(content)

    return f"**{title}**\n\n" + "\n\n".join(ls)

git_ref = partial(_git_main_ref, "git-")
git_tutorial_ref = partial(_git_main_ref, "")

async def sql_ref(text: str):
    """Displays reference on an SQL statement"""
    text = text.strip("`").lower()
    if text in {"check", "unique", "not null"}:
        text += " constraint"
    text = re.sub(" ", "-", text)
    base_url = f"http://www.sqltutorial.org/sql-{text}/"
    url = urllib.parse.quote_plus(base_url, safe=";/?:@&=$,><-[]")
    response = await get_url_response(url)
    if response.status != 200:
        return f"An error occurred (status code: {response.status}). Retry later."

    body = BeautifulSoup(await response.text(), HTML_PARSER).find("body")
    intro = body.find(lambda x: x.name == "h2" and "Introduction to " in x.string)
    title = body.find("h1").string
    ps = []
    for tag in tuple(intro.next_siblings):
        if tag.name == "h2" and tag.text.startswith("SQL "):
            break
        if tag.name == "p":
            ps.append(tag)
    description = "\n".join([markdownify(p) for p in ps])[:2048]
    return f"**{title}**\n\n{description}"

async def haskell_ref(text: str):
    """Displays informations on given Haskell topic"""
    text = text.strip("`")

    snake = "_".join(text.split(" "))

    base_url = f"https://wiki.haskell.org/{snake}"
    url = urllib.parse.quote_plus(base_url, safe=";/?:@&=$,><-[]")

    response = await get_url_response(url)
    if response.status == 404:
        return f"No results for `{text}`"
    if response.status != 200:
        return f"An error occurred (status code: {response.status}). Retry later."

    soup = BeautifulSoup(await response.text(), HTML_PARSER).find("div", id="content")

    title = soup.find("h1", id="firstHeading").string
    description = "\n".join(
        [
            markdownify(p)
            for p in soup.find_all(
                lambda x: x.name in ["p", "li"]
                and tuple(x.parents)[1].name not in ("td", "li"),
                limit=6,
            )
        ]
    )[:2048]

    return f"**{title}**\n\n{description}"


#!/usr/bin/python3

import os
import sys
import re
import operator
from pathlib import Path

RECURSION_LIMIT = 9500
sys.setrecursionlimit(RECURSION_LIMIT + 10)

def count(word_list, ignore_words, word_freqs):
    if word_list == []:
        return
    else:
        word = word_list[0]
        if word not in ignore_words:
            if word in word_freqs:
                word_freqs[word] += 1
            else:
                word_freqs[word] = 1
        count(word_list[1:], ignore_words, word_freqs)

def wf_print(word_freqs):
    if word_freqs == []:
        return
    else:
        (w, c) = word_freqs[0]
        print(f'{w} - {c}')
        wf_print(word_freqs[1:])

ignore_words = set(open(os.path.join(Path.cwd(), 'res/ignore-words.txt')).read().split(','))
words = re.findall('[a-z]{2,}', open(sys.argv[1]).read().lower())
word_freqs = {}

for i in range(0, len(words), RECURSION_LIMIT):
    count(words[i:i + RECURSION_LIMIT], ignore_words, word_freqs)

wf_print(sorted(word_freqs.items(), key=operator.itemgetter(1), reverse=True)[:25])


from typing import Tuple

import torch
import torch.nn as nn
import torch.nn.functional as F
from torch.distributions import RelaxedOneHotCategorical

class Codebook(torch.nn.Embedding):
    """VQ-VAE Codebook.

    Implements the algorithm presented in "Neural Discrete Representation Learning"
    [https://arxiv.org/abs/1711.00937], corresponding to the distribution:

    ..math
        q_\varphi(z_q = e_k | z_e) = \delta_k ( \argmin_{l=1}^K \| z_e - e_l \| )
        \quad \forall 1 \leq k \leq K

    This module stores a finite set of codebooks, used to compute quantization of input tensors.

    Note
    ----
    This module inherits from the `torch.nn.Embedding` module, and uses its
    forward implementation for the `codebook_lookup` function.

    Parameters
    ----------
    num_codebook: number of codebooks.
    dim_codebook: dimension of codebooks.
    """

    def __init__(self, num_codebook: int, dim_codebook: int, **kwargs):
        super().__init__(num_embeddings=num_codebook, embedding_dim=dim_codebook)
        self.weight.data.uniform_(-1 / num_codebook, 1 / num_codebook)
        self._eps = torch.finfo(torch.float32).eps

    def quantize(self, encoding: torch.Tensor) -> Tuple[torch.Tensor, dict]:
        """Quantize an encoding vector with respect to the codebook.

        Compute the distances between the encoding and the codebook vectors, and assign
        the closest codebook to each point in the feature map. The gradient from the
        return quantized tensor is copied to the encoding. This function also returns
        the latent loss and the normalized perplexity.

        Parameters
        ----------
        encoding: input tensor with shape `(*, D)`.

        Returns
        -------
        quantized: quantized tensor with the same shape as the input vector.
        indices: indices sampled with shape `(*, K)`.
        losses: dictionary containing the latent loss between encodings and selected
        codebooks, and the normalized perplexity.
        """
        distances = self.compute_distances(encoding)
        indices = torch.argmin(distances, dim=-1)
        quantized = self.codebook_lookup(indices)
        loss_latent = F.mse_loss(encoding, quantized)
        quantized = encoding + (quantized - encoding).detach()
        # Compute perplexity
        indices_onehot = F.one_hot(indices, num_classes=self.num_codebook)
        probs = (
            indices_onehot
            .view(-1, self.num_codebook)
            .float()
            .mean(dim=0)
        )
        perplexity = torch.exp(-torch.sum(probs * torch.log(probs + self._eps)))
        perplexity = perplexity / self.num_codebook
        return quantized, indices_onehot, {
            "loss_latent": loss_latent,
            "perplexity": perplexity,
        }

    def compute_distances(self, encodings: torch.Tensor) -> torch.Tensor:
        """Compute distance between encodings and codebooks.

        Parameters
        ----------
        encodings: encoding tensor with shape `(*, D)`.

        Returns
        -------
        Distances with shape `(*, K)`.
        """
        distances = (encodings.unsqueeze(-2) - self.weight).square().sum(-1)
        return distances

    def codebook_lookup(self, indices: torch.Tensor) -> torch.Tensor:
        """Associate tensor of indices with the corresponding codebooks.

        Parameters
        ----------
        indices: Discrete vector with shape (*).

        Returns
        -------
        Tensor of codebooks with shape `(*, D)`.
        """
        return self(indices)

    @property
    def num_codebook(self):
        return self.num_embeddings

    @property
    def dim_codebook(self):
        return self.embedding_dim

class EMACodebook(Codebook):
    """VQ-VAE Codebook with Exponential Moving Avergage (EMA).

    This modules is similar to the `Codebook` module, with the addition of updating
    codebook positions with EMA.

    Parameters
    ----------
    num_codebook: number of codebooks.
    dim_codebook: dimension of codebooks.
    gamma: degree of weighting decrease. Must be between `0` and `1`. Default is `0.99`.
    epsilon: pseudocount for the Laplace smoothing. Default is `1e-5`.
    """

    def __init__(
        self,
        num_codebook: int,
        dim_codebook: int,
        gamma: float = 0.99,
        epsilon: float = 1e-5,
        **kwargs
    ):
        super().__init__(num_codebook=num_codebook, dim_codebook=dim_codebook, **kwargs)
        self.gamma = gamma
        self.epsilon = epsilon
        self.register_buffer("ema_cluster_size", torch.zeros(self.num_codebook))
        self.register_buffer("ema_positions", self.weight.clone())

    def quantize(self, encoding: torch.Tensor) -> Tuple[torch.Tensor, dict]:
        """Quantize an encoding vector with respect to the codebook.

        Note
        ----
        Because codebooks are updated using EMA, the latent loss does not back propagate
        gradient toward the codebooks.

        Parameters
        ----------
        encoding: input tensor with shape `(*, D)`.

        Returns
        -------
        quantized: quantized tensor with the same shape as the input vector.
        indices: indices sampled with shape `(*, K)`.
        losses: dictionary containing the latent loss between encodings and selected
        codebooks, and the normalized perplexity.
        """
        encoding_flatten = encoding.reshape(-1, self.dim_codebook)
        distances = self.compute_distances(encoding_flatten)
        indices = torch.argmin(distances, dim=-1)
        indices_onehot = F.one_hot(indices, num_classes=self.num_codebook)
        probs = indices_onehot.float().mean(dim=0)
        perplexity = torch.exp(-torch.sum(probs * torch.log(probs + self._eps)))
        perplexity = perplexity / self.num_codebook
        if self.training:
            # Update cluster size
            instant_cluster_size = indices_onehot.sum(dim=0)
            self.ema_cluster_size = (
                self.gamma * self.ema_cluster_size
                + (1 - self.gamma) * instant_cluster_size
            )
            total_cluster_size = self.ema_cluster_size.sum(dim=-1, keepdims=True)
            # Laplace smoothing to avoid empty clusters
            self.ema_cluster_size = (
                (self.ema_cluster_size + self.epsilon)
                / (total_cluster_size + self.num_codebook * self.epsilon)
                * total_cluster_size
            )
            # Update positions
            instant_positions = indices_onehot.T.float() @ encoding_flatten
            self.ema_positions = (
                self.gamma * self.ema_positions + (1 - self.gamma) * instant_positions
            )
            # Update codebook
            self.weight.data = self.ema_positions / self.ema_cluster_size.unsqueeze(-1)
        quantized = self.codebook_lookup(indices).view(encoding.shape)
        loss_latent = F.mse_loss(encoding, quantized)
        quantized = encoding + (quantized - encoding).detach()
        return quantized, indices_onehot, {
            "loss_latent": loss_latent,
            "perplexity": perplexity,
        }

class GumbelCodebook(Codebook):
    """VQ-VAE Codebook with Gumbel Sotmax Reparametrization.

    Parameters
    ----------
    num_codebook: number of codebooks.
    dim_codebook: dimension of codebooks.
    tau: temperature for the Gumbel Softmax distribution. Default is `0.5`.
    """

    def __init__(self, num_codebook: int, dim_codebook: int, tau: float = 0.5):
        super().__init__(num_codebook=num_codebook, dim_codebook=dim_codebook)
        self.tau = tau

    def quantize(self, encoding: torch.Tensor) -> Tuple[torch.Tensor, dict]:
        """Quantize the encoded vector using Gumbel Softmax.

        Implements a quantization based on the distribution:
        ..math
            q_\varphi(z_q = e_k | z_e) = \frac{\exp{ - \| z_e - e_k \|^2 }}
            {\sum_{l=1}^K \exp { - \| z_e - e_l \|^2 }}
            \quad \forall 1 \leq k \leq K

        Note
        ----
        During training, we sample instead from the associated Gumbel Softmax
        distribution in order to allow gradient propagation.

        Returns
        -------
        quantized: quantized tensor with the same shape as the input vector.
        losses: dictionary containing the latent loss between encodings and selected
        codebooks, and the normalized perplexity.
        """
        encoding_flatten = encoding.reshape(-1, self.dim_codebook)
        distances = self.compute_distances(encoding_flatten)
        gumbel_softmax = RelaxedOneHotCategorical(
            logits=-distances, temperature=self.tau
        )
        indices = gumbel_softmax.rsample()
        if self.training:
            quantized = indices @ self.weight
        else:
            quantized = self.codebook_lookup(indices.argmax(-1))
        # KL divergence
        kl = gumbel_softmax.probs * torch.log(
            gumbel_softmax.probs * self.num_codebook + self._eps
        )
        kl = kl.sum()
        # Compute perplexity
        probs = indices.mean(dim=0)
        perplexity = torch.exp(-torch.sum(probs * torch.log(probs + self._eps)))
        perplexity = perplexity / self.num_codebook
        quantized = quantized.view(encoding.shape)
        indices = indices.view(*encoding.shape[:-1], -1)
        return quantized, indices, {"loss_latent": kl, "perplexity": perplexity}


# -*- coding:utf-8 -*-
# --Based on YOLOX made by Megavii Inc.--
import os
from pathlib import Path

import torch.nn as nn

from experiments.ours_exp import Exp as MyExp

class Exp(MyExp):
    def __init__(self):
        super(Exp, self).__init__()
        self.memory = True
        self.heads = 4
        self.memory_num=100

        self.input_size = (320, 320)  # (height, width)
        self.test_size = (320, 320)# (480, 640)

        self.data_num_workers = 4

        self.data_dir = Path('D:/Liyi/Datasets/DETRAC').resolve(strict=True)

        self.batch_size = 2


import logging
from calendar import day_abbr, month_abbr, month_name
from datetime import date, datetime, timedelta
from typing import List, Optional, Tuple, Dict

import discord
from discord import app_commands
import requests
from dateutil.rrule import rrulestr
from discord.ext import commands
from icalendar import Calendar
from pytz import timezone, utc

from uqcsbot.bot import UQCSBot

UQCS_CALENDAR_URL = (
    "https://calendar.google.com/calendar/ical/"
    "q3n3pce86072n9knt3pt65fhio%40group.calendar.google.com/public/basic.ics"
)
# EXTERNAL_CALENDAR_URL =d "https://calendar.google.com/calendar/ical/" \
#                         "72abf01afvsl3bjd9oq2g1avgg%40group.calendar.google.com/public/basic.ics"
# Testing calendar: "https://calendar.google.com/calendar/ical/7djv171v2mdr4dmufq612j6uj4%40group.calendar.google.com/public/basic.ics"

MONTH_NUMBER: Dict[str, int] = {
    month.lower(): index for index, month in enumerate(month_abbr)
}

BRISBANE_TZ = timezone("Australia/Brisbane")

MAX_RECURRING_EVENTS = 3

class EventFilter(object):
    def __init__(self, full=False, weeks=None, cap=None, month=None, is_valid=True):
        self.is_valid = is_valid
        self._full = full
        self._weeks = weeks
        self._cap = cap
        self._month = month

    @classmethod
    def from_argument(cls, args: Tuple):
        if len(args) == 0:
            return cls(weeks=2)
        else:
            if "full" in args or "all" in args:
                return cls(full=True)
            elif "weeks" in args:
                i = args.index("weeks") + 1
                return cls(weeks=int(args[i]))
            else:
                # No valid input
                return cls(weeks=2)

    def filter_events(self, events: List["Event"], start_time: datetime):
        if self._weeks is not None:
            end_time = start_time + timedelta(weeks=self._weeks)
            return [e for e in events if e.start < end_time]
        if self._month is not None:
            return [e for e in events if e.start.month == self._month]
        elif self._cap is not None:
            return events[: self._cap]
        return events

    def get_header(self):
        if self._full:
            return "List of *all* upcoming events:"
        elif self._weeks is not None:
            return f"Events in the next *{self._weeks} weeks*:"
        elif self._month is not None:
            return f"Events in *{month_name[self._month]}*:"
        else:
            return f"The *next {self._cap} events*:"

    def get_no_result_msg(self):
        if self._weeks is not None:
            return (
                f"There don't appear to be any events in the next *{self._weeks}* weeks"
            )
        elif self._month is not None:
            return f"There don't appear to be any events in *{month_name[self._month]}*"
        else:
            return "There don't appear to be any upcoming events..."

class Event(object):
    def __init__(
        self,
        start: datetime,
        end: datetime,
        location: str,
        summary: str,
        recurring: bool,
        link: Optional[str],
        source: Optional[str] = None,
    ):
        self.start = start
        self.end = end
        self.location = location
        self.summary = summary
        self.recurring = recurring
        self.link = link
        self.source = source

    @classmethod
    def encode_text(cls, text: str) -> str:
        """
        Encodes user-specified text so that it is not interpreted as command characters
        by Slack. Implementation as required by: https://api.slack.com/docs/message-formatting
        Note that this encoding process does not stop injection of text effects (bolding,
        underlining, etc.), or a malicious user breaking the text formatting in the events
        command. It should, however, prevent <, & and > being misinterpreted and including
        links where they should not.
        --
        :param text: The text to encode
        :return: The encoded text
        """
        return text.replace("&", "&").replace("<", "<").replace(">", ">")

    @classmethod
    def from_cal_event(
        cls, cal_event, source: str = "UQCS", recurrence_dt: datetime = None
    ):
        """
        Converts an ical event to an Event

        :param cal_event: event to convert
        :param source: the calendar the event was sourced from
        :param recurrence_dt: if this is a one off event then None
                                else the date of this instance of a recurring event
        """
        if recurrence_dt:
            start = recurrence_dt
            end = recurrence_dt + (
                cal_event.get("DTEND").dt - cal_event.get("DTSTART").dt
            )

        else:
            start = cal_event.get("dtstart").dt
            end = cal_event.get("dtend").dt
            # ical 'dt' properties are parsed as a 'DDD' (datetime, date, duration) type.
            # The below code converts a date to a datetime, where time is set to midnight.
            if isinstance(start, date) and not isinstance(start, datetime):
                start = datetime.combine(start, datetime.min.time()).astimezone(utc)
            if isinstance(end, date) and not isinstance(end, datetime):
                end = datetime.combine(end, datetime.max.time()).astimezone(utc)
        location = cal_event.get("location", "TBA")
        summary = cal_event.get("summary")
        return cls(
            start,
            end,
            location,
            f"{'[External] ' if source == 'external' else ''}{summary}",
            recurrence_dt is not None,
            None,
            source,
        )

    def get_title(self):
        # TODO: fix for case with link
        return Event.encode_text(
            ("[Recurring] " if self.recurring else "") + self.summary
        )

    def get_time_loc(self):
        d1 = self.start.astimezone(BRISBANE_TZ)
        d2 = self.end.astimezone(BRISBANE_TZ)

        start_str = (
            f"{day_abbr[d1.weekday()].upper()}"
            + f" {month_abbr[d1.month].upper()} {d1.day} {d1.hour}:{d1.minute:02}"
        )
        if (d1.month, d1.day) != (d2.month, d2.day):
            end_str = (
                f"{day_abbr[d2.weekday()].upper()}"
                + f" {month_abbr[d2.month].upper()} {d2.day} {d2.hour}:{d2.minute:02}"
            )
        else:
            end_str = f"{d2.hour}:{d2.minute:02}"

        # Encode user-provided text to prevent certain characters
        # being interpreted as slack commands.
        location_str = Event.encode_text(self.location)
        return f"**{start_str} - {end_str}** {'*(' + location_str + ')*' if location_str else ''}"

class Events(commands.Cog):
    """
    Display events
    """

    CHANNEL_NAME = "events"

    def __init__(self, bot: UQCSBot):
        self.bot = bot
        self.bot.schedule_task(
            self.scheduled_message,
            trigger="cron",
            hour=9,
            day_of_week="mon",
            timezone="Australia/Brisbane",
        )

    async def scheduled_message(self):
        channel = discord.utils.get(
            self.bot.uqcs_server.channels, name=self.CHANNEL_NAME
        )
        if channel is not None:
            await self.send_events(channel)
        else:
            logging.warning(f"Could not find required channel #{self.CHANNEL_NAME}")

    @classmethod
    def _get_current_time(cls):
        """
        Returns the current date and time
        This function exists purely so it can be mocked for testing
        """
        return datetime.now(tz=BRISBANE_TZ).astimezone(utc)

    def _handle_calendar(self, calendar) -> List[Event]:
        """
        Returns a list of events from a calendar
        """
        events = []
        current_time = self._get_current_time()
        # subcomponents are how icalendar returns the list of things in the calendar
        for component in calendar.subcomponents:
            # we are only interested in ones with the name VEVENT as they
            # are events
            if component.name != "VEVENT":
                continue
            elif component.get("RRULE") is not None:
                # If the until date exists, update it to UTC
                if component["RRULE"].get("UNTIL") is not None:
                    until = datetime.combine(
                        component["RRULE"]["UNTIL"][0], datetime.min.time()
                    ).astimezone(utc)
                    component["RRULE"]["UNTIL"] = [until]
                rule = rrulestr(
                    "\n".join(
                        [
                            line
                            for line in component.content_lines()
                            if line.startswith("RRULE") or line.startswith("EXDATE")
                        ]
                    ),
                    dtstart=component.get("DTSTART").dt,
                )
                rule = [dt for dt in list(rule) if dt > current_time]
                for dt in rule[:MAX_RECURRING_EVENTS]:
                    dt = dt.replace(tzinfo=BRISBANE_TZ)
                    event = Event.from_cal_event(component, recurrence_dt=dt)
                    events.append(event)
            else:
                # we convert it to our own event class
                event = Event.from_cal_event(component)
                # then we want to filter out any events that are not after the current time
                if event.start > current_time:
                    events.append(event)

        return events

    async def send_events(
        self,
        channel: discord.abc.Messageable,
        interaction: discord.Interaction = None,
        *args,
    ):
        current_time = self._get_current_time()
        event_filter = EventFilter.from_argument(args)
        events = []

        uqcs_calendar = Calendar.from_ical(self._get_calendar_file())
        events += self._handle_calendar(uqcs_calendar)

        # then we apply our event filter as generated earlier
        events = event_filter.filter_events(events, current_time)
        # then, we sort the events by date
        events = sorted(events, key=lambda event_: event_.start)

        if not events:
            message_text = (
                f"_{event_filter.get_no_result_msg()}_\n"
                f"For a full list of events, visit: "
                f"https://uqcs.org/events "
            )
            if interaction == None:
                await channel.send(message_text)
            else:
                await interaction.response.send_message(message_text)
        else:
            message_text = f"{event_filter.get_header()}"
            if interaction == None:
                await channel.send(message_text)
            else:
                await interaction.response.send_message(message_text)

            for event in events:
                colour = discord.Colour.from_rgb(82, 151, 209)

                embed = discord.Embed()
                embed.colour = colour
                embed.title = f"{event.get_title()}"
                embed.description = f"{event.get_time_loc()}"
                await channel.send(embed=embed)

    @app_commands.command()
    @app_commands.describe(weeks="Number of weeks to return, defaults to 2")
    async def events(self, interaction: discord.Interaction, weeks: int = 2):
        """Shows the upcoming UQCS events for the next 2 weeks."""
        await self.send_events(interaction.channel, interaction, "weeks", weeks)

    @app_commands.command()
    async def allevents(self, interaction: discord.Interaction):
        """Shows all upcoming UQCS events."""
        await self.send_events(interaction.channel, interaction, "full")

    @classmethod
    def _get_calendar_file(cls) -> bytes:
        """
        Loads the UQCS or External Events calender .ics file from Google Calendar.
        This method is mocked by unit tests.
        :return: The returned ics calendar file, as a stream
        """
        http_response = requests.get(UQCS_CALENDAR_URL)
        return http_response.content

async def setup(bot: commands.Bot):
    await bot.add_cog(Events(bot))


#!/usr/bin/env python
"""
Thomas:

"""

########################################
# Imports
########################################

import ROOT

########################################
# Functions
########################################

def Read_unfitted_datafile( filename ):

    f_in = open( filename, 'r' )

    x_values = []
    x_errors = []
    y_values = []
    y_errors = []

    while True:
        line = f_in.readline()
        if not line: break
        line = line.strip()

        points_list = line.split(',')
        x_values.append( float( points_list[0] ) )
        x_errors.append( float( points_list[1] ) )
        y_values.append( float( points_list[2] ) )
        y_errors.append( float( points_list[3] ) )

    f_in.close()

    return ( x_values, x_errors, y_values, y_errors )

def Get_TGraph( filename ):

    ( x_values, x_errors, y_values, y_errors ) = Read_unfitted_datafile( filename )

    n_points = len(x_values)

    gr = ROOT.TGraphErrors( n_points )

    for i in range( n_points ):

        gr.SetPoint(
            i,
            x_values[i],
            y_values[i] )

        gr.SetPointError(
            i,
            x_errors[i],
            x_errors[i] )

    gr.SetTitle( 'TGraph_{0}'.format( filename.split('.')[0] ) )

    gr.SetMarkerColor(4)
    gr.SetMarkerStyle(22)
    gr.SetMarkerSize(0.8)

    return gr

def Fit_TGraph( gr ):

    #func_str = "sqrt([0]*[0] + x*[1]*[1] + x*x*[2]*[2])"
    #func_init = [ "0", "0", "0" ]

    func_str = '[0]*1.0/x + [1]*x*x*x+[2]*x*x+[3]*x+[4]'

    func_init = []

    f1 = ROOT.TF1( "fit1", func_str )

    for i, init_val in enumerate( func_init ):
        f1.SetParameter( i, float(init_val) )

    #f1.SetRange( 30.0, 300.0 )

    gr.Fit(f1,'Q')
    gr.Fit(f1,'Q')
    gr.Fit(f1,'Q')

def Draw_TGraph( gr, c1 ):

    gr.Draw('AP')
    c1.Update()

    out_name = 'plots/' + gr.GetTitle()

    c1.Print( out_name , 'pdf')

    img = ROOT.TImage.Create()
    img.FromPad(c1)
    img.WriteImage( out_name + '.png' )

    setattr( gr, 'out_name', out_name )

########################################
# Main
########################################

def main():

    ROOT.gROOT.SetBatch(True)
    ROOT.gROOT.ProcessLine("gErrorIgnoreLevel = 1001;")

    c1 = ROOT.TCanvas("c1","c1",500,400)
    c1.SetGrid()

    filenames = [
        'unfittedpoints_2_b0.txt',
        'unfittedpoints_2_b1.txt',
        'unfittedpoints_2_l0.txt',
        'unfittedpoints_2_l1.txt',
        ]

    f_html = open( 'overview_2.html' , 'w' )
    f_html.write( '\n
Fittest overview\n
\n
\n
' )

    number_of_cols = 2
    plot_count = 0

    for filename in filenames:
        gr = Get_TGraph( filename )
        Fit_TGraph( gr )
        Draw_TGraph( gr, c1 )

        f_html.write('\n'.format(gr.out_name) )

        plot_count += 1
        if plot_count == number_of_cols:
            f_html.write( '
\n' )

########################################
# End of Main
########################################
if __name__ == "__main__":
    main()


from tracardi.process_engine.action.v1.sort_dictionary import SortedDictAction
from tracardi.service.plugin.service.plugin_runner import run_plugin

def test_sort_dictionary_plugin():
    properties = {"data": {"first": 1, "second": 2, "fifth": 5, "third": 3}}
    init = dict(
        data='payload@data',
        direction='asc',
        sort_by="value"
    )

    result = run_plugin(SortedDictAction, init, properties)
    assert result.output.value == {"result": [("first", 1), ("second", 2), ("third", 3), ("fifth", 5)]}