import argparse
import yaml
import pandas as pd
import os
from utils import load_pkl

def subset_df(dataf):
    target_columns = dataf.columns.tolist()[2:5]
    return dataf[target_columns]

def main(args):
    DATASET = args.dataset
    results_root = args.results_root
    is_zero_shot = args.is_zero_shot
    # print(f'Working with {DATASET}; zero-shot? {is_zero_shot}')

    files = os.listdir(results_root)
    files_filtered = [file for file in files if DATASET in file]

    if is_zero_shot:
        files_filtered = [file for file in files_filtered if 'zero_shot' in file]

    print('Working with the following files: ', files_filtered)

    for file in files_filtered:
        path = os.path.join(results_root, file)
        df = load_pkl(path)

        df_subset = subset_df(df)
        # print(df_subset.describe())
        print(df_subset.mean())

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('--dataset', type=str,
                        default='CUB',
                        choices=['CUB', 'ABO', 'fashion200k', 'coco', 'f30k'],
                        help='dataset type')
    parser.add_argument('--results_root', type=str, default='CLIP/data/results',
                    help='Configuration file')
    parser.add_argument('--is_zero_shot', type=bool, default=False,
                        help='Do we use CLIP in zero-shot way?')
    args = parser.parse_args()
    main(args)


import logging
import sys
import os
import os.path
from copy import deepcopy
from xml.etree import ElementTree
import csv

logger = logging.getLogger('x4.' + __name__)

def require_python_version(major, minor):
    if sys.version_info.major < major or sys.version_info.minor < minor:
        logger.error('This script requires python 3.6 or higher.')
        exit(0)

def get_config():
    try:
        config = __import__('config')
    except ImportError:
        logger.exception('config.py not found, please run setup.sh before using this script!')
        exit(1)
    return config

class ModUtilMixin(object):

    @classmethod
    def clone(cls, xml):
        return deepcopy(xml)

    @classmethod
    def read_xml(cls, filepath, allow_fail=False):
        try:
            xml = ElementTree.parse(filepath)
        except Exception:
            if allow_fail:
                logger.info('read_xml failed', extra=dict(filepath=filepath, allow_fail=allow_fail))
                return
            logger.exception('read_xml error!', extra=dict(filepath=filepath, allow_fail=allow_fail))
            raise
        return xml

    @classmethod
    def write_xml(cls, filename, xml):
        os.makedirs(os.path.dirname(filename), exist_ok=True)
        with open(filename, 'wb') as of:
            xml.write(of, encoding='utf-8', xml_declaration=True)

    @classmethod
    def set_xml(cls, xml, path, key, value_template, row, label):
        el = xml.find(path)
        if el is None:
            logger.warning("path '{}' not found in {}".format(path, label))
            exit(0)
        try:
            value = value_template.format(**row)
        except Exception:
            logger.error('set_xml: {}, {}'.format(value_template, row), exc_info=True)
            exit(0)
        if value != '':
            # skip on blank value
            el.set(key, value)
        return True

    @classmethod
    def update_xml(cls, xml, row, mapping, label):
        for path, key, value_template in mapping:
            cls.set_xml(xml, path, key, value_template, row, label=label)

    @classmethod
    def get_macros(cls, src_path):
        xml = cls.read_xml(src_path + '/index/macros.xml')
        return {e.get('name'): e.get('value').replace('\\', '/') for e in xml.findall('./entry')}

    @classmethod
    def get_components(cls, src_path):
        xml = cls.read_xml(src_path + '/index/components.xml')
        return {e.get('name'): e.get('value').replace('\\', '/') for e in xml.findall('./entry')}

    @classmethod
    def get_wares(cls, src_path, allow_fail=False):
        return cls.read_xml(src_path + '/libraries/wares.xml', allow_fail=allow_fail)

    @classmethod
    def get_ts(cls, src_path, allow_fail=False, language=44):
        return cls.read_xml(src_path + '/t/0001-l{:03d}.xml'.format(language), allow_fail=allow_fail)

    @classmethod
    def read_csv(cls, filename: str, csv_data: dict):
        reader_rows = csv.reader(open(filename))
        header = None
        rows = None
        for row in reader_rows:
            col0 = row[0].strip().lower()
            if col0.startswith('h'):
                ware_type = col0[1:].lstrip()
                header = [h for h in row[1:] if h != '']
                rows = csv_data.setdefault(ware_type, [])
            elif col0 == 'd':
                rows.append({h: d for h, d in zip(header, row[1:])})

    @classmethod
    def pat_replace(cls, text, pat, repl_fn):
        out = []
        matches = pat.finditer(text)
        start = 0
        for m in matches:
            out.extend([
                text[start:m.start()],
                repl_fn(*m.groups()),
            ])
            start = m.end()
        out.append(text[start:])
        had_replacements = start > 0
        return u''.join(out), had_replacements


#
# @lc app=leetcode id=113 lang=python3
#
# [113] Path Sum II
#
# https://leetcode.com/problems/path-sum-ii/description/
#
# algorithms
# Medium (55.13%)
# Likes:    5417
# Dislikes: 119
# Total Accepted:    626.7K
# Total Submissions: 1.1M
# Testcase Example:  '[5,4,8,11,null,13,4,7,2,null,null,5,1]\n22'
#
# Given the root of a binary tree and an integer targetSum, return all
# root-to-leaf paths where the sum of the node values in the path equals
# targetSum. Each path should be returned as a list of the node values, not
# node references.
#
# A root-to-leaf path is a path starting from the root and ending at any leaf
# node. A leaf is a node with no children.
#
#
# Example 1:
#
#
# Input: root = [5,4,8,11,null,13,4,7,2,null,null,5,1], targetSum = 22
# Output: [[5,4,11,2],[5,8,4,5]]
# Explanation: There are two paths whose sum equals targetSum:
# 5 + 4 + 11 + 2 = 22
# 5 + 8 + 4 + 5 = 22
#
#
# Example 2:
#
#
# Input: root = [1,2,3], targetSum = 5
# Output: []
#
#
# Example 3:
#
#
# Input: root = [1,2], targetSum = 0
# Output: []
#
#
#
# Constraints:
#
#
# The number of nodes in the tree is in the range [0, 5000].
# -1000 <= Node.val <= 1000
# -1000 <= targetSum <= 1000
#
#
#

# @lc code=start
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def pathSum(self, root: Optional[TreeNode], targetSum: int) -> List[List[int]]:
        res = []
        accum = []
        self.helper(root, targetSum, res, accum)
        return res

    def helper(self, root, targetSum, res, accum):
        if root is None:
            return

        accum.append(root.val)

        if root.left is None and root.right is None:
            if sum(accum) == targetSum:
                res.append(accum[:])

        self.helper(root.left, targetSum, res, accum)
        self.helper(root.right, targetSum, res, accum)
        accum.pop()
# @lc code=end


from ball import Ball
from paddle import Paddle
import random

class Game:

    def __init__(self, width : int, height : int, offset=10, max_points=10):
        # boundaries of the game board
        self.w = width
        self.h = height
        # score of the two players
        self.score = [0,0]
        print(self.score[1])
        # game ball
        self.ball = Ball(self.w//2, self.h//2)

        # paddles
        self.paddle1 = Paddle(offset, height//2)
        self.paddle2 = Paddle(width-offset, height//2)
        self.max_points = max_points

    def is_scored(self):
        position = self.ball.get_position()

        if position[1] >= self.w:
            self.score[1] += 1

        if position[0] <= 0:
            self.score[0] += 1

    def collision(self):
        x,y = self.ball.get_position()
        r = self.ball.r

        # check collision with paddles
        if x - r == self.paddle1.x + self.paddle1.w//2 and y <= self.paddle1.y + self.paddle1.l and y >= self.paddle1.y - self.paddle1.l:
            self.ball.dx = -self.ball.dx

        if x + r == self.paddle2.x - self.paddle2.w//2 and y <= self.paddle2.y + self.paddle2.l and y >= self.paddle2.y - self.paddle2.l:
            self.ball.dx = -self.ball.dx

        # change y component of the velocity if a collision on the top or bottom
        if y == r or y == self.h - r:
            self.ball.dy = -self.ball.dy

        # # change x cmoponent of the velocity if a collision on right or left
        if x == r or x == self.w - r:
            self.ball.set_velocity(0,0)
            self.point_scored()
        #     self.ball.dx = -self.ball.dx

    def point_scored(self):
        print(self.score)
        x,_ = self.ball.get_position()
        r = self.ball.r

        if x == r:
            self.score[0] += 1
            if self.score[0] == 10:
                self.game_won()
            self.reset_game()

        elif x == self.w - r:
            self.score[1] += 1
            if self.score[1] == 10:
                self.game_won()
            self.reset_game()

        else:
            print("Something went horribly wrong")

    # function used to reset the game
    def reset_game(self):
        init_velocity = random.choice([[1,1],[1,-1],[-1,1],[-1,-1]])

        self.ball.set_velocity(init_velocity[0], init_velocity[1])
        self.ball.x = self.w//2
        self.ball.y = self.h//2

        if self.score[0] == self.max_points or self.score[1] == self.max_points:
            self.score = [0,0]

    # movement of each paddle
    def move_paddle1(self, addY):

        if self.paddle1.y-self.paddle1.l//2 > 0 and self.paddle1.y+self.paddle1.l//2 < self.h:
            self.paddle1.move(addY)

        if self.paddle1.y-self.paddle1.l//2 == 0 and addY > 0:
            self.paddle1.move(addY)

        if self.paddle1.y+self.paddle1.l//2 == self.h and addY < 0:
            self.paddle1.move(addY)

    def move_paddle2(self, addY):
        if self.paddle2.y - self.paddle2.l // 2 > 0 and self.paddle2.y+self.paddle2.l//2 < self.h:
            self.paddle2.move(addY)

        if self.paddle2.y-self.paddle2.l//2 == 0 and addY > 0:
            self.paddle2.move(addY)

        if self.paddle2.y+self.paddle2.l//2 == self.h and addY < 0:
            self.paddle2.move(addY)

    # update per game loop
    def update(self):
        self.ball.move()
        self.collision()


#Exercise 5: This program records the domain name (instead of the address)
#where the message was sent from instead of who the mail came from
#(i.e., the whole email address). At the end of the program,
#print out the contents of your dictionary.

name = input('Enter a file name: ')
counts = dict()
try:
    handle = open(name)
    for line in handle:
        if line.startswith('From '):
            words = line.split()
            twords = words[1]
            swords = twords.split('@')
            ewords = swords[1]
            #print(ewords)
            counts[ewords] = counts.get(ewords,0) + 1
    print(counts)
except:
    print('File not found:',name)


"""
@file lexer.py
@author Nathan Houwaart (nathan.houwaart@student.hu.nl)
@brief This file contains all lexer related functions
@version 0.1
@date 11-05-2021
"""
import sys
import os

sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

import re

from typing import Tuple, Callable, Optional
from misc.token_types import *
from misc.error_message import generate_error_message

def search_match(
    characters: str,
    token_expressions: List[Tuple[str, TokenTypes]],
    total_index=0
) -> Optional[Tuple[re.match, str]]:
    """Function searches for a matching token expression. Starts searching for a match from the given index.

    Args:
        characters          : The characters that need to be matched.
        token_expressions   : A list of tuples each containing a regex string and identifier.
        total_index         : Try to find a match from this index in characters. Can be seen as characters[total_index:].

    Returns:
        If a match is found:
            A tuple containing a match that has been found and a tag saying what token it has found
        If no match was found:
            A tuple containing (None, None)
    """
    if len(token_expressions) == 0:
        return None, None
    head, *tail = token_expressions
    pattern, tag = head

    regex = re.compile(pattern)
    match = regex.match(characters, total_index)
    return (match, tag) if match else search_match(characters, tail, total_index)

def lex(
    characters: str,
    search_match_f: Callable[[str, List[Tuple[str, TokenTypes]], int], Optional[Tuple[re.match, str]]],
    token_expressions: List[Tuple[str, TokenTypes]],
    line_no: int=1,
    index: int=0,
    total_index: int=0
) -> List[Token]:
    """Function converts the provided characters into tokens. Uses a provided function to search for matches in characters

    Args:
        characters          : The characters that need to be lexed.
        search_match_f      : A function to match the provided characters with the provided tokens
        token_expressions   : Try to find a match from this index in characters. Can be seen as characters[total_index:].
        line_no             : The current line number that is being lexed, default=1.
        index               : The current line index that is being lexed, default=0.
        total_index         : The total index in characters that is being lexed, default=0

    Returns:
        If no errors occured:
            Returns a list of lexed tokens
        If no match was found:
            Raises a Syntax Error with a message of where the error occured
    """
    if len(characters) == total_index: # If the end characters has been reached return an EOF token
        return [Token(
            loc_={"start":{"line": line_no, "index":index}, "end":{"line": line_no, "index": index+3}},
            range_=[total_index,total_index+3] ,
            value_="\00",
            tokentype_=TokenTypes.EOF
        )]

    match, tokentype = search_match_f(characters, token_expressions, total_index)
    if not match:
        generate_error_message(line_no, index, characters, "Invalid Syntax", True)

    matched_text    = match.group(0)
    offset          = match.end(0) - match.start(0)
    token_location  = {"start":{"line": line_no, "index":index}, "end":{"line": line_no, "index": index+offset}}
    token_range     = [match.start(0), match.end(0)]

    token   = Token(loc_=token_location, range_=token_range, value_=matched_text, tokentype_=tokentype)

    if tokentype == TokenTypes.NEW_LINE: line_no +=1; index =0; offset = 0
    return [token] + lex(characters, search_match_f, token_expressions, line_no, index + offset, match.end(0))

if __name__ == "__main__":
    if len(sys.argv) < 2:
        print("No source file provided")
        exit()

    with open(sys.argv[1], 'rb') as f:
        code = f.read().decode("utf-8")

    lexed = lex(code, search_match, TokenExpressions)
    list(map(print, lexed))


__author__ = 'Daniel'

class Solution(object):
    def hIndex(self, A):

        n = len(A)
        cnt = [0 for _ in xrange(n+1)]
        for e in A:
            if e >= n:
                cnt[n] += 1
            else:
                cnt[e] += 1

        F = [0 for _ in xrange(n+2)]
        for i in xrange(n, -1, -1):
            F[i] += F[i+1] + cnt[i]
            if F[i] >= i:
                return i

        return 0

    def hIndex_sort(self, citations):

        n = len(citations)
        citations.sort()
        for i in xrange(n):
            if citations[i] >= n-i:
                return n-i

        return 0

    def hIndex_reverse_sort(self, citations):

        citations.sort(reverse=True)
        citations.append(0)
        h = 0
        for i in xrange(len(citations)-1):
            if citations[i] >= i+1 >= citations[i+1]:
                h = i+1
            elif h:
                break

        return h

if __name__ == "__main__":
    assert Solution().hIndex([3, 0, 6, 1, 5]) == 3


#!/home/ubuntu/env/spider/bin/python3

import sys
sys.path.append('./')

import proxyGetter.xiciProxyGetter as getter
import proxyVerify.proxyVerify as verify

if __name__ == '__main__':
    g = getter.xiciProxyGetter()
    counter = 1
    ver = verify.proxyVerify()
    proxies = g.get(500)
#    for i in proxies:
#        print(i)
    print('---------------------')
    ver.verifyMultiThreading(proxies, 300)

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


# Inner function

# def outer_function():
#     message1 = "Hi"
#     message2 = "Hello"

#     def inner_function():
#         return (message1, message2)

#     return inner_function()

# print(outer_function())

# print(inner_function())

# Closures

# def outer_function():
#     message1 = "Hi"
#     message2 = "Hello"

#     def inner_function():
#         return message1, message2

#     return inner_function

# my_func = outer_function()
# print(my_func())

# Example for Closure

def generate_power(exponent):
    def power(base):

        return base ** exponent

    return power

raise_two = generate_power(2)
raise_three = generate_power(3)
raise_four = generate_power(4)

print(raise_two(30))
print(raise_three(100))
print(raise_four(70))

# def outer_func(msg):
#     message = msg

#     def inner_func():
#         print(message)

#     return inner_func

# hi_func = outer_func("Hi")
# hi_func()

# hello_func = outer_func("Hello")
# hello_func()


#! /usr/bin/env python
# Maged Goubran @ 2022, maged.goubran@utoronto.ca

# coding: utf-8

import argparse
import sys

from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import *

# Inputs #########

def helpmsg():
    return '''miracl_conv_gui_options.py -t title -f [ fields separated by space] -v [volumes to open] -d [dirs to open]
    -hf helpfun

Takes list of strings as options for entries for a gui options, and a gui title

example: miracl_conv_gui_options.py -t "Reg options" -v clar labels -f orient label resolution

Input options will be printed as output

'''

def parsefn():
    parser = argparse.ArgumentParser(description='Sample argparse py', usage=helpmsg())
    parser.add_argument('-t', '--title', type=str, help="gui title", required=True)
    parser.add_argument('-f', '--fields', type=str, nargs='+', help="fields for options")
    parser.add_argument('-v', '--vols', type=str, nargs='+', help="volumes for reading")
    parser.add_argument('-d', '--dirs', type=str, nargs='+', help="directories for reading")
    parser.add_argument('-c', '--combo', type=str, nargs='+', help="dropdown of options")
    parser.add_argument('-hf', '--helpfun', type=str, help="help fun")

    return parser

def parse_inputs(parser, args):
    args, unknown = parser.parse_known_args()

    title = args.title
    fields = args.fields
    vols = args.vols
    dirs = args.dirs
    combo = args.combo if args.combo else None
    helpfun = args.helpfun

    return title, vols, dirs, fields, combo, helpfun

def OptsMenu(title, vols=None, dirs=None, fields=None, combo=None, helpfun=None):
    # create GUI
    main = QtWidgets.QMainWindow()

    widget = QtWidgets.QWidget()
    widget.setWindowTitle('%s' % title)

    layout = QFormLayout()
    layout.setFieldGrowthPolicy(QtWidgets.QFormLayout.AllNonFixedFieldsGrow)

    linedits = {}
    buttons = {}
    labels = {}

    if vols:

        for v, vol in enumerate(vols):
            # Create buttons for vols
            labels["%s" % vol] = QtWidgets.QLabel('No file selected')
            buttons["%s" % vol] = QtWidgets.QPushButton('Select %s' % vol)

            # Layout for widgets
            layout.addRow(labels["%s" % vol], buttons["%s" % vol])

            buttons["%s" % vol].clicked.connect(lambda state, vol=vol: get_fname(main, labels, vol))

    if dirs:

        for d, dir in enumerate(dirs):
            # Create buttons for vols
            labels["%s" % dir] = QtWidgets.QLabel('No Dir selected')
            buttons["%s" % dir] = QtWidgets.QPushButton('Select %s' % dir)

            # Layout for widgets
            layout.addRow(labels["%s" % dir], buttons["%s" % dir])

            buttons["%s" % dir].clicked.connect(lambda state, dir=dir: get_dname(main, labels, dir))

    for f, field in enumerate(fields):
        # Create inputs (line edts)
        linedits["%s" % field] = QLineEdit()
        linedits["%s" % field].setAlignment(QtCore.Qt.AlignRight)

        # Layout for widgets
        layout.addRow("%s" % field, linedits["%s" % field])

    if combo:
        combo_field = combo[0]
        cb = QtWidgets.QComboBox()
        cb.addItems(combo[1:])
        layout.addRow(combo_field, cb)
    else:
        combo_field = None
        cb = None

    # Create push button
    helpbutton = QtWidgets.QPushButton('Help')
    enter = QtWidgets.QPushButton('Enter')
    submit = QtWidgets.QPushButton('Run')

    layout.addRow(helpbutton, enter)
    layout.addWidget(submit)

    widget.setLayout(layout)

    helpbutton.clicked.connect(lambda: print_help(main, helpfun))
    enter.clicked.connect(lambda: print_input(labels, linedits, vols, dirs, fields, combo_field, cb))
    submit.clicked.connect(QtCore.QCoreApplication.instance().quit)

    return widget, linedits, labels

def get_fname(main, labels, vol):
    vfile = QtWidgets.QFileDialog.getOpenFileName(main, 'Select %s' % vol)[0]
    if vfile:
        vfilestr = "%s : %s" % (vol, str(vfile).lstrip())
        labels["%s" % vol].setText(vfilestr)
        # print('%s path: %s' % (vol, vfile))
    else:
        labels["%s" % vol].setText('No file selected')

def get_dname(main, labels, dir):
    dfile = str(QFileDialog.getExistingDirectory(main, "Select %s" % dir, "."))
    if dfile:
        dfilestr = "%s : %s" % (dir, dfile.lstrip())
        labels["%s" % dir].setText(dfilestr)
        # print('%s path: %s' % (dir, dfile))
    else:
        labels["%s" % dir].setText('No Dir selected')

def print_input(labels, linedits, volumes=None, dirs=None, fields=None, combo_field=None, cb=None):
    if volumes:
        for v, volume in enumerate(volumes):
            text = str(labels[volume].text()).lstrip()
            if text == 'No file selected':
                text = ''
            if volume in text:
                text = text.lstrip("%s :" % volume)
            print("%s :%s" % (volume, text))
    if dirs:
        for d, directory in enumerate(dirs):
            text = str(labels[directory].text()).lstrip()
            if text == 'No Dir selected':
                text = ''
            if directory in text:
                print(text)
                text = text.lstrip("%s :" % directory)
    if fields:
        for f, field in enumerate(fields):
            print("%s :%s" % (field, str(linedits["%s" % field].text()).lstrip()))
    if combo_field and cb:
        print("%s :%s" % (combo_field, cb.currentText()))

def print_help(main, helpfun):
    helpwidget = QtWidgets.QDialog()
    main.setCentralWidget(helpwidget)
    helpwidget.setAttribute(QtCore.Qt.WA_DeleteOnClose)

    main.setWindowTitle('Help function')

    helplayout = QVBoxLayout()
    helplbl = QtWidgets.QLabel(helpfun)
    helplayout.addWidget(helplbl)

    helpwidget.setLayout(helplayout)

    main.show()

    QApplication.processEvents()

def main(args):
    parser = parsefn()
    title, vols, dirs, fields, combo, helpfun = parse_inputs(parser, args)

    # Create an PyQT4 application object.
    app = QApplication(sys.argv)
    menu, linedits, labels = OptsMenu(title=title, vols=vols, dirs=dirs, fields=fields, combo=combo, helpfun=helpfun)
    menu.show()
    app.exec_()
    app.processEvents()

if __name__ == "__main__":
    sys.exit(main(sys.argv))


# coding: utf-8

#import modules
from utils import *
from vgg16 import Vgg16
import os, sys

#Create references to important directories
path = 'data/dogscatsredux/'
#path = 'data/dogscatsredux/sample/'

# Code assumes data has been downloaded from Kaggle and organized in directory structure similar to:
'''
					     				data
					      				||
									cats-dogs-redux
                 ____________________________||__________________
                 |	 |	             |	                |
              train	test  	       valid              sample
	       ___ |___              ___|___          ______|_______
           |       |           |         |        |              |
          cats    dogs        cats     dogs    train            valid
                                       	     ___|___          ____|____
                                       	    |       |        |         |
                                    	    cats   dogs     cats      dogs

'''

# # Outline:
#
# 1. Finetune and Train Model
# 2. Generate Predictions
# 3. Validate Predictions
# 4. Submit Predictions to Kaggle

# # Finetuning and Training

#Set paths to data
test_path = path+'/test/'
train_path = path+'/train/'
valid_path = path+'/valid/'
results_path = path+'/results/'

#import Vgg16
vgg = Vgg16()

#Set hyper-parameters
batch_size = 64
n_epochs = 3

#Finetune the model
batches = vgg.get_batches(train_path, batch_size=batch_size)
val_batches = vgg.get_batches(valid_path, batch_size=batch_size*2)
vgg.finetune(batches)

#Fit and generate weights for each epoch
latest_weights_filename = None
for epoch in range(n_epochs):
    print('Running epoch: %d' % epoch)
    vgg.fit(batches, val_batches, nb_epoch=1)
    latest_weights_filename = 'ft%d.h5' % epoch
    vgg.model.save_weights(results_path+latest_weights_filename)

print('Comleted %s fit operations' % n_epochs)

# # Generate Predictions
#Make predictions on the test dataset using our new model
batches, preds = vgg.test(test_path, batch_size=batch_size*2)

#vgg.test() generates two probabilities per image
#Need to check which column is cats and which is dogs
filenames = batches.filenames
print(preds[:5])
print(filenames[:5])

#Verify column ordering by viewing some images
from PIL import Image
Image.open(test_path + filenames[2])

# From the above, it appears that column 1 is cats and column 2 is dogs

#Save test results arrays for future use
save_array(results_path+'test_preds.dat', preds)
save_array(results_path+'filenames.dat', filenames)

# # Validate Predictions

#Calculate predictions on validation set for debugging of model
vgg.model.load_weights(results_path+latest_weights_filename)
val_batches, probs = vgg.test(valid_path, batch_size=batch_size)

#Find correct and incorrect examples
filenames = val_batches.filenames
expected_labels = val_batches.classes #Assigns '0' or '1'

#Round predictions to '0' or '1' to generate labels
our_predictions = probs[:,0]
our_labels = np.round(1 - our_predictions)

# Looking at examples of each of:
#
# 1. A few correct labels at random
# 2. A few incorrect labels at random
# 3. Those with highest probability of being correct labels
# 4. Those with highest probability of being incorrect labels
# 5. Those with probability closest to 0.5, i.e. most uncertain labels

#Set-up for analysing above examples (not included in this file)
from keras.preprocessing import image

#Print out confusion matrix
from sklearn.metrics import confusion_matrix
cm = confusion_matrix(expected_labels, our_labels)
plot_confusion_matrix(cm, val_batches.class_indices)

# # Submit Predictions to Kaggle
preds = load_array(results_path+'test_preds.dat')
filenames = load_array(results_path+'filenames.dat')

#Grab the dog prediction column (column 2)
isdog = preds[:,1]

#To play it safe, round down our edge predictions to avoid punishment from log-loss
isdog = isdog.clip(min=0.05, max=0.95)

#Extract imageIds from the filenames in our test directory
filenames = batches.filenames
ids = np.array([int(f[5:f.find('.')]) for f in filenames])
#Join the two columns into an array [imageId, isDog]
subm = np.stack([ids, isdog], axis=1)
subm[:5]

submission_file_name = 'submission1.csv'
np.savetxt(submission_file_name, subm, fmt='%d,%.5f', header='id,label', comments='')


from django.conf.urls import url
from bike import views

urlpatterns=[
    url('post_bike/', views.post_bike),
    url('view_bike/', views.view_bike),
    url('view_user/', views.view_user),
    url('update/(?P<idd>\w+)', views.update, name='update'),
    url('delete/(?P<idd>\w+)', views.delete, name='delete'),
    # url('Rent/(?P<idd>\w+)', views.Rent, name='fg')

]


from trie import Trie

# TrieNode => {children, is_end_word, char, mark_as_leaf(), unmark_as_leaf()}
def total_words(root):
    result = 0

    # Leaf denotes end of a word
    if root.is_end_word:
        result += 1

    for i in range(26):
        # Check if the node has children
        if root.children[i] is not None:
            # Recursively return the word count
            result += total_words(root.children[i])
    return result

keys = ["the", "a", "there", "answer", "any", "by", "bye", "their", "abc"]

trie = Trie()

for key in keys:
    trie.insert(key)

print(total_words(trie.root))


"""
Transformer module.
"""

import logging
import numpy as np
import pandas as pd
from sklearn.base import BaseEstimator, TransformerMixin
from sklearn.preprocessing import (
    StandardScaler,
    LabelEncoder,
    PolynomialFeatures,
)

transformer_logger = logging.getLogger("transformer")

class WeatherTransformer(BaseEstimator, TransformerMixin):
    """
    Custom transformer for weather dataset.
    """

    def __init__(self, mode="linear"):
        """
        Class constructor;
        :param mode: "linear" or "forest".
        Uses different preprocessing technics:
            1) Adding numerical polynomial features;
            2) Label-encoding categorical features.
        """
        self.mode = mode
        self.numeric_cols = None
        self.categorical_cols = None
        self.scaler = StandardScaler()
        self.transformer = PolynomialFeatures()

        transformer_logger.debug(
            "Created an instance of WeatherTransformer; mode=%s.", self.mode
        )

    def fit(self, data: pd.DataFrame, target=None):
        """
        Fit transformer with data;
        :param target: target array;
        :param data: dataframe;
        :return: None.
        """
        target *= 1
        data = self._replace(data, {"Yes": 1, "No": 0})

        self.numeric_cols = list(data.select_dtypes(include=np.number).columns)
        self.categorical_cols = list(
            data.select_dtypes(include="object").columns
        )

        data = self._fill_nans(data, self.numeric_cols, self.categorical_cols)

        self.scaler.fit(data[self.numeric_cols])
        self.transformer.fit(data[self.numeric_cols])

        transformer_logger.debug("WeatherTransformer fitted.")
        return self

    def transform(self, data: pd.DataFrame) -> np.array:
        """
        Transform data;
        :param data: dataframe;
        :return: numpy array.
        """
        data = self._replace(data, {"Yes": 1, "No": 0})

        data = self._fill_nans(data, self.numeric_cols, self.categorical_cols)

        data[self.numeric_cols] = self.scaler.transform(
            data[self.numeric_cols]
        )

        data = self._encode(data)

        if self.mode == "linear":
            transformer_logger.debug("WeatherTransformer preprocessed data.")
            return self.transformer.transform(data[self.numeric_cols])
        if self.mode == "forest":
            data = np.array(data)
            transformer_logger.debug("WeatherTransformer preprocessed data.")
            return data
        transformer_logger.warning(
            "mode=%s is not supported, using default=linear.", self.mode
        )
        return self.transformer.transform(data[self.numeric_cols])

    @staticmethod
    def _drop(data: pd.DataFrame, columns: list[str]) -> pd.DataFrame:
        data = data.drop(columns, axis=1)
        return data

    @staticmethod
    def _replace(data: pd.DataFrame, replace_dict: dict) -> pd.DataFrame:
        data = data.replace(replace_dict)
        return data

    @staticmethod
    def _fill_nans(
        data: pd.DataFrame,
        numeric_cols: list[str],
        categorical_cols: list[str],
    ) -> pd.DataFrame:
        for column in data.columns:
            if column in numeric_cols:
                data[column] = data[column].fillna(np.mean(data[column]))
            elif column in categorical_cols:
                data[column] = data[column].fillna("unknown")
        return data

    @staticmethod
    def _encode(data: pd.DataFrame) -> pd.DataFrame:
        encoder = LabelEncoder()
        for column in data.columns:
            data[column] = encoder.fit_transform(data[column])
        return data


#In[]:

import os
import win32com.client as win32
import fitz
import openpyxl

#In[]:

Word_Path = r"C:\Python\MR_APP\MR-App-Repo\Word"
Path_Toetsingen= r"C:\Python\MR_APP\MR-App-Repo\Toetsingen\Botova_1449959 + 1449958 + 1449957 + 1449956_T3.xlsx"
Path_C = r"C:\Python\MR_APP\MR-App-Repo\Certificaten"

#In[]:

# # create a new instance of Word application
# word = win32.gencache.EnsureDispatch('Word.Application')

# # open the document
# doc = word.Documents.Open(Word_Path)

# # save the document as PDF
# pdf_path = os.path.splitext(doc.FullName)[0] + ".pdf"
# doc.ExportAsFixedFormat(pdf_path, win32.constants.wdExportFormatPDF)

# # close the document and quit Word application
# doc.Close()
# word.Quit()

#In[]:

lines = []

# iterate over all files in the folder
for filename in os.listdir(Word_Path):
    if filename.endswith(".pdf"):
        filepath = os.path.join(Word_Path, filename)
        with fitz.open(filepath) as doc:
            # iterate over all pages in the PDF
            for page_num in range(doc.page_count):
                page = doc.load_page(page_num)
                text = page.get_text("text")
                # split the text content into lines and add them to the list
                lines.extend(text.splitlines())

#In[]:

Monster_MHPoly = []
for filename in os.listdir(Path_C):
    f = os.path.join(Path_C, filename)
    # Load the Excel file
    workbook = openpyxl.load_workbook(f)
    # Select the active worksheet
    ws  = workbook.active
    # Iterate through the first 10 rows
    for row in ws.iter_rows(min_row=1, max_row=10):
        # Check if column A contains the target text
        if row[0].value == "Projectomschrijving":
            # Extract values after column C
            Monster_MHPoly.extend(cell.value for cell in row[3:])

#In[]:

Useless_List = []

for val in Monster_MHPoly:
    if val != None :
        Useless_List.append(val)

Monster_MHPoly = Useless_List
Useless_List = []
for x in Monster_MHPoly:
    Useless_List.append(x + " ")

Monster_MHPoly = Useless_List

#In[]:

Index = []
for i, entry in enumerate(lines):
    if "Hoofd grondsoort" in entry:
        Index.append(i)

#In[]:

Output_Monsters = []
Output_Grondstof = []
Useless_List = []
Row = 13942

for x in Index:
    Useless_List = [elem for elem in lines[x-70:x] if elem in Monster_MHPoly]
    Output_Monsters.extend(Useless_List)
    for item in lines[x+2:x+2+len(Useless_List)]:
        Output_Grondstof.append(item)
    Useless_List = []

#In[]:

import pandas as pd

df = pd.DataFrame({'Monster': Output_Monsters, 'Grondsoort': Output_Grondstof})

#In[]:


import os
import pandas as pd
from sklearn.preprocessing import LabelEncoder
from sklearn.model_selection import cross_val_score
from sklearn.linear_model import LogisticRegression

SCRIPT_PATH = os.path.dirname(os.path.abspath( __file__ ))
dataset = pd.read_csv(SCRIPT_PATH + "/train.csv")

#features = ['Pclass', 'Name', 'Sex', 'Age', 'SibSp', 'Parch', 'Ticket', 'Fare', 'Cabin', 'Embarked']

features = ['Pclass', 'Sex', 'Age', 'SibSp', 'Parch', 'Fare', 'Cabin', 'Embarked']
training_data = dataset[features]

training_label = dataset['Survived']

#from above plt, it showed that Sex/Age/Fare matters in the importance
features = ['Sex', 'Age', 'Fare']
training_data = dataset[features]
training_data = training_data.fillna(0)
training_data['Sex'] = LabelEncoder().fit_transform(training_data['Sex'])#only sex needs to label encode
model = LogisticRegression(penalty='l2', class_weight='balanced', solver='newton-cg')
model.fit(training_data, training_label)

test_data = pd.read_csv(SCRIPT_PATH + "/test.csv")
preidction_data = test_data[features]
preidction_data = preidction_data.fillna(0)
preidction_data['Sex'] = LabelEncoder().fit_transform(preidction_data['Sex'])#only sex needs to label encode
result_labels = model.predict(preidction_data)
results = pd.DataFrame({
    'PassengerId' : test_data['PassengerId'],
    'Survived' : result_labels
})
results.to_csv(SCRIPT_PATH + "/submission5.csv", index=False)

cv_scores = cross_val_score(model, training_data, training_label, scoring = 'roc_auc', cv=5)
print(cv_scores)


import json
import boto3

def lambda_handler(event, context):
    region = "us-east-1"
    EC2_RESOURCE = boto3.resource('ec2', region_name=region)
    INSTANCE_NAME_TAG_VALUE = 'DevOps'

    instancesTag = EC2_RESOURCE.instances.filter(
        Filters=[
            {
                'Name': 'tag:Group',
                'Values': [
                INSTANCE_NAME_TAG_VALUE
                ]
            }
        ]
    )

    for instance in instancesTag:
            try:
                instance.stop()
                #print(f'Starting EC2 instance: {instance.id}')
                #instance.wait_until_stopped()
                #print(f'EC2 instance "{instance.id}" has been started')
                print('Parou')
            except:
                print(f'Error stopping {instance}')


import numpy as np
from scipy.spatial.distance import pdist, squareform

elements_map = {'H': 0,
                'C': 1,
                'N': 2,
                'O': 3,
                'S': 4,
                'X': 5}

def one_hot_elements_map(x):
    arr = np.zeros(len(elements_map))
    arr[elements_map[x[0]]] = 1
    return arr

def PDBdf2npArray(atoms, res, size=np.Inf):
    num_channels = len(elements_map)

    x_coord = (((atoms.x_coord - atoms.x_coord.min()) / res).astype(int)).values
    y_coord = (((atoms.y_coord - atoms.y_coord.min()) / res).astype(int)).values
    z_coord = (((atoms.z_coord - atoms.z_coord.min()) / res).astype(int)).values
    channel_coord = np.vectorize(lambda x: elements_map[x])(atoms.element_symbol.values)

    max_size = max([x_coord.max(), y_coord.max(), z_coord.max()]) + 1

    if size >= max_size:
        max_size = size
        clip_flag = False
    else:
        clip_flag = True

    shape = (max_size, max_size, max_size, num_channels)

    arr = np.zeros(shape=shape, dtype=np.bool)
    arr[x_coord, y_coord, z_coord, channel_coord] = 1

    if clip_flag:
        arr = arr[:size, :size, :size, :]

    return arr, clip_flag

def PDBdf2linearArray(atoms, size=np.Inf):
    x_coord = (atoms.x_coord - atoms.x_coord.min()).values
    y_coord = (atoms.y_coord - atoms.y_coord.min()).values
    z_coord = (atoms.z_coord - atoms.z_coord.min()).values
    coords = np.stack([x_coord, y_coord, z_coord], axis=-1)

    atom_type = np.apply_along_axis(one_hot_elements_map, -1, np.expand_dims(atoms.element_symbol.values, axis=-1))
    # np.vectorize(one_hot_elements_map)(atoms.element_symbol.values)

    distances = squareform(pdist(coords))
    distances.partition(distances.shape[-1] - 4, axis=-1)
    dist = distances[:, -3:]

    arr = np.concatenate((coords, atom_type, dist), axis=-1)

    return arr

def rotatePDBdf(df, angles):
    # 3D rotation of the x,y,z coordinates in a dataframe

    cos = np.cos(angles)
    sin = np.sin(angles)

    # Rotation matrix
    R = np.array(
            [[cos[1] * cos[2], cos[2] * sin[0] * sin[1] - cos[0] * sin[2], cos[0] * cos[2] * sin[1] + sin[0] * sin[2]],
             [cos[1] * sin[2], cos[0] * cos[2] + sin[0] * sin[1] * sin[2], -cos[2] * sin[0] + cos[0] * sin[1] * sin[2]],
             [-sin[1], cos[1] * sin[0], cos[0] * cos[1]]])

    M = np.array([df.x_coord.values, df.y_coord.values, df.z_coord.values])

    rotM = np.matmul(R, M)

    df.x_coord = rotM[0]
    df.y_coord = rotM[1]
    df.z_coord = rotM[2]

    return df

def rotateArray(arr, angles):
    # 3D rotation of the x,y,z coordinates in a dataframe

    cos = np.cos(angles)
    sin = np.sin(angles)

    # Rotation matrix
    R = np.array(
            [[cos[1] * cos[2], cos[2] * sin[0] * sin[1] - cos[0] * sin[2], cos[0] * cos[2] * sin[1] + sin[0] * sin[2]],
             [cos[1] * sin[2], cos[0] * cos[2] + sin[0] * sin[1] * sin[2], -cos[2] * sin[0] + cos[0] * sin[1] * sin[2]],
             [-sin[1], cos[1] * sin[0], cos[0] * cos[1]]])

    M = arr[:, :3]

    rotM = np.matmul(R, M.transpose())

    rot_arr = np.concatenate((rotM.transpose(), arr[:, 3:]), axis=-1)

    return rot_arr


import cv2
import os
import tkinter as tk
import glob
import tkinter.filedialog
from tkinter import *
from PIL import Image, ImageTk, ImageGrab
from math import sqrt

screen = tk.Tk()
pixelVirtual = tk.PhotoImage(width=1, height=1)
txtvar = tk.StringVar() # Для поля ввода мм в пкс
screen_name_jpg = ()
pic = 0
cnt = 0
tmp1 = [] # Координаты 1-го овала
tmp2 = [] # Координаты 2-го овала

# Захват кадра и сохранение
def jpg_camera():
    global screen_name_jpg
    cap = cv2.VideoCapture(0)
    if cap.isOpened():
        ret, frame = cap.read()
        if ret:
            screen_name_jpg = 'file000.jpg'
            cv2.imwrite(screen_name_jpg, frame)
    cap.release()

# Открытие выбранного изображения
def openfile():
    global pic
    canvas.delete(tk.ALL)
    zz = Image.open(tk.filedialog.askopenfilename(title="Open Photo",
                                                filetypes=(
                                                ("jpeg files", "*.jpg"), ("all files", "*.*"))))
    pic = ImageTk.PhotoImage(zz)
    canvas.create_image(0, 0, anchor='nw', image=pic)

# Сохранение файла с запоминанием места сохранения(создаётся txt файл)
def savefile():
    if not os.path.exists('./config.txt'):
        savefolder = tkinter.filedialog.askdirectory(mustexist=True, title="Выбрать папку для сохранения")
        with open("config.txt", encoding='utf-8', mode="w") as file:
            file.write(savefolder+"\n")
            file.close()
        savefile()
    else:
        with open("config.txt", encoding='utf-8', mode="r") as file:
            savefolder = file.readline()[0:-1]
        filepaths = glob.glob(savefolder + '/' + 'file_*.jpg')
        image = ImageGrab.grab(bbox=(canvas.winfo_rootx(), canvas.winfo_rooty(), canvas.winfo_rootx() + canvas.winfo_width(),
           canvas.winfo_rooty() + canvas.winfo_height()))
        if len(filepaths) == 0:
            image.save("{}file_000.jpg".format(savefolder+'/'))
        else:
            string = filepaths[-1]
            first_index = string.find("_", string.find("file_"))
            last_digits = string[first_index+1: first_index+4]
            image.save("{}file_{:03d}.jpg".format(savefolder+'/', int(last_digits)+1))

# Точка в меcте клика и вырисовка линии
def click(event):
    global cnt, tmp1, tmp2, im, screen_name_jpg, line, text_line
    if cnt == 0 or cnt == 2:
        cnt = 0
        tmp1.clear()
        tmp2.clear()
        canvas.create_oval(event.x - 3, event.y - 3, event.x + 3, event.y + 3,
                      fill="#FF0000", activefill="#00FF00")
        tmp1.extend((event.x, event.y, event.x, event.y))
        print(tmp1)
        cnt += 1
    elif cnt == 1:
        canvas.create_oval(event.x - 3, event.y - 3, event.x + 3, event.y + 3,
                      fill="#FF0000", activefill="#00FF00")
        tmp2.extend((event.x, event.y, event.x, event.y))
        print(tmp2)
        line = canvas.create_line(tmp1[0], tmp1[1], event.x, event.y)
        text_line = canvas.create_text((sum((tmp1[0], event.x))/2)+15, (sum((tmp1[1], event.y))/2)+10,
                      text=linelen(tmp1[0], event.x, tmp1[1], event.y))
        cnt += 1

    print("x: {}, y: {}".format(event.x, event.y))

# Расчёт расстояния
def linelen(x1, x2, y1, y2):
    return "{0:.2f} mm".format(float((sqrt((x2-x1)**2+(y2-y1)**2))*float(txtvar.get())))

# Удаление всех элементов
def clear_items():
    canvas.delete(tk.ALL)

# Ф-ция чтобы удалить запоминание места сохранения
def del_config():
    os.remove('config.txt')

# Ф-ция для передвижения точек
def move_item(event):
    item_teg = tk.CURRENT
    canvas.coords(item_teg, event.x - 3, event.y - 3, event.x + 3, event.y + 3)
    canvas.delete(line)
    canvas.delete(text_line)
    canvas.bind('<ButtonRelease-3>', create_line)

# Ф-ция, перед перемещением получаем координаты для сравнения, чтобы понимать какую точку двигаем
def info(event):
    global x_y_current
    item_teg = tk.CURRENT
    x_y_current = canvas.coords(item_teg)
    x_y_current = x_y_current[0] + 3, x_y_current[1] + 3, x_y_current[2] - 3, x_y_current[3] - 3
    x_y_current = list(map(int, x_y_current))
    print(x_y_current)

# Ф-ция, после передвижения точки строит линию и перезаписывает координаты точки
def create_line(event):
    global line, text_line
    if x_y_current[0] == tmp2[0]:
        line = canvas.create_line((tmp1[0], tmp1[1], event.x, event.y))
        text_line = canvas.create_text((sum((tmp1[0], event.x)) / 2) + 15, (sum((tmp1[1], event.y)) / 2) + 10,
                                       text=linelen(tmp1[0], event.x, tmp1[1], event.y))
        tmp2.clear()
        x_y_current.clear()
        tmp2.extend((event.x, event.y, event.x, event.y))
    elif x_y_current[0] == tmp1[0]:
        line = canvas.create_line((tmp2[0], tmp2[1], event.x, event.y))
        text_line = canvas.create_text((sum((tmp2[0], event.x)) / 2) + 15, (sum((tmp2[1], event.y)) / 2) + 10,
                                       text=linelen(tmp2[0], event.x, tmp2[1], event.y))
        tmp1.clear()
        x_y_current.clear()
        tmp1.extend((event.x, event.y, event.x, event.y))

# Ф-ция для удаления объектов
def delete_item(event):
    item_teg = tk.CURRENT
    canvas.delete(item_teg, event.x - 3, event.y - 3, event.x + 3, event.y + 3)

# Вызов ф-ции для начала работы с кадром
jpg_camera()

# Кнопка для открытия файла
open_btn = tk.Button(screen, text="Открыть файл", image=pixelVirtual,
                          width=150,
                          height=20,
                          compound="c", command=openfile)
open_btn.place(x=640, y=0)

# Кнопка для сохранения файла
save_btn = tkinter.Button(text="Сохранить в файл", image=pixelVirtual,
                          width=150,
                          height=20,
                          compound="c", command=savefile)
save_btn.place(x=640, y=30)

# Кнопка чтобы удалить запоминание места сохранения
del_config_btn = tk.Button(screen, text="Удалить привязку", image=pixelVirtual,
                          width=150,
                          height=20,
                          compound="c", command=del_config)
del_config_btn.place(x=640, y=60)

# Кнопка для очистки окна
clear_btn = tk.Button(screen, text="Удалить ВСЕ элементы", image=pixelVirtual,
                          width=150,
                          height=20,
                          compound="c", command=clear_items)
clear_btn.place(x=640, y=90)

# Поле ввода кол-ва мм в пкс
ent = tk.Entry(screen, textvariable=txtvar)
ent.insert(0, "Тут пкс в мм надо")
ent.place(x=642, y=120)

# Определение размера окна
im = Image.open(screen_name_jpg)
(width_screen, height_screen) = im.size
print("Разрешение изображения:", im.size)

screen.geometry('800x481')
canvas = tk.Canvas(screen, width = width_screen, height = height_screen)
canvas.pack()
photo = ImageTk.PhotoImage(im)
canvas.create_image(0, 0, anchor = 'nw', image = photo)
canvas.place(x = 0, y = 0)
canvas.bind('<Button-1>', click)
canvas.bind('<B3-Motion>', move_item)
canvas.bind('<Button-3>', info)
canvas.bind('<Button-2>', delete_item)
screen.mainloop()

'''
#Сохранение элемента
def save_screen():
    global im, screen_name_jpg
    box = (canvas.winfo_rootx(), canvas.winfo_rooty(), canvas.winfo_rootx() + canvas.winfo_width(),
           canvas.winfo_rooty() + canvas.winfo_height())
    im = ImageGrab.grab(bbox=box)
    im.save(screen_name_jpg)

save_btn = tk.Button(screen, text="Сохранить элементы",
                              command=save_screen)
save_btn.place(x=150, y=480)

'''


import re
from abc import abstractmethod
from typing import Any, Optional

# The purpose of this construction is to use shared strings when
# they have the same value. This way comparisons can happen on the
# memory address rather than looping through the content.
XSD_STRING = 'http://www.w3.org/2001/XMLSchema#string'
XSD_INT = 'http://www.w3.org/2001/XMLSchema#int'
XSD_LONG = 'http://www.w3.org/2001/XMLSchema#long'
XSD_DOUBLE = 'http://www.w3.org/2001/XMLSchema#double'
XSD_FLOAT = 'http://www.w3.org/2001/XMLSchema#float'
XSD_INTEGER = 'http://www.w3.org/2001/XMLSchema#integer'
XSD_DECIMAL = 'http://www.w3.org/2001/XMLSchema#decimal'
XSD_DATETIME = 'http://www.w3.org/2001/XMLSchema#dateTime'
XSD_DATE = 'http://www.w3.org/2001/XMLSchema#date'
XSD_TIME = 'http://www.w3.org/2001/XMLSchema#time'
XSD_BOOLEAN = 'http://www.w3.org/2001/XMLSchema#boolean'

datatype_dict = {
    '': '',
    XSD_STRING: XSD_STRING,
    XSD_INT: XSD_INT,
    XSD_LONG: XSD_LONG,
    XSD_DOUBLE: XSD_DOUBLE,
    XSD_FLOAT: XSD_FLOAT,
    XSD_INTEGER: XSD_INTEGER,
    XSD_DECIMAL: XSD_DECIMAL,
    XSD_DATETIME: XSD_DATETIME,
    XSD_DATE: XSD_DATE,
    XSD_TIME: XSD_TIME,
    XSD_BOOLEAN: XSD_BOOLEAN
}

# noinspection PyPep8Naming
def Datatype(value):
    """
    Replace the string with a shared string.
    intern() only works for plain strings - not unicode.
    We make it look like a class, because it conceptually could be.
    """
    if value is None:
        r = None
    elif value in datatype_dict:
        r = datatype_dict[value]
    else:
        r = datatype_dict[value] = value
    return r

class RDFTerm:
    """
    Super class containing methods to override. :class:`IRI`,
    :class:`Literal` and :class:`BlankNode` all inherit from :class:`RDFTerm`.
    """
    __allow_access_to_unprotected_subobjects__ = {'n3': 1}

    def __init__(self, value: str = None):
        self.value: Optional[str] = value

    def __str__(self) -> str:
        return str(self.value)

    def __eq__(self, other) -> bool:
        return type(self) == type(other) and self.value == other.value

    @abstractmethod
    def n3(self) -> str:
        """
        :return: A Notation3 representation of this term
        """
        raise NotImplementedError('Subclasses of RDFTerm must implement `n3`')

    def __repr__(self) -> str:
        return f'<{self.__class__.__name__} {self.n3()}>'

    # Matches everything outside 0x20 - 0x7e, plus double quote and backslash
    # See N-Triples syntax: http://www.w3.org/TR/rdf-testcases/#ntriples
    _chars_to_escape = re.compile(r'[^ -~]|["\\]')
    _n3_quote_map = {
        '\t': r'\t',
        '\n': r'\n',
        '\r': r'\r',
        '"': r'\"',
        '\\': r'\\',
    }

    @classmethod
    def _n3_quote(cls, txt: str):
        def escape(m):
            ch = m.group()
            code = ord(ch)
            if ch in cls._n3_quote_map:
                return cls._n3_quote_map[ch]
            if 0x20 <= code < 0x7f:
                # We should not be hitting this (thanks to re)
                return ch
            if code < 0x10000:
                return f'\\u{ord(ch):04x}'
            return f'\\U{ord(ch):08x}'

        return '"' + cls._chars_to_escape.sub(escape, txt) + '"'

class IRI(RDFTerm):
    """ An RDF resource. """
    def __init__(self, value: str):
        super().__init__(value)

    def n3(self) -> str:
        return f'<{self.value}>'

class Literal(RDFTerm):
    """
    Literals. These can take a data type or a language code.
    """
    def __init__(self, value: Any, datatype: str = None, lang: str = None):
        super().__init__(str(value))
        self.lang = lang
        self.datatype = datatype

    def __eq__(self, other):
        return type(self) == type(other) and \
               self.value == other.value and \
               self.lang == other.lang and \
               self.datatype == other.datatype

    def n3(self) -> str:
        n3_value = self._n3_quote(self.value)
        n3_type = f'^^<{self.datatype}>' if self.datatype is not None else ''
        n3_lang = f'@{self.lang}' if self.lang is not None else ''
        return f'{n3_value}{n3_type}{n3_lang}'

class BlankNode(RDFTerm):
    """ Blank node. Similar to `IRI` but lacks a stable identifier. """
    def __init__(self, value):
        super().__init__(value)

    def n3(self):
        return f'_:{self.value}'


#!/usr/bin/python3

# average_ratings.py
# CMPT 318 Exercise 4 - Movie Title Entity Resolution
# Alex Macdonald
# ID#301272281
# October 6, 2017

# Objective:
# . Determine the average rating for each movie, compensating for bad spelling
# . It should produce a CSV file with 'title' as the first column
# . . and (average) 'rating' rounded to two decimal places as the second
# . The output should be sorted by title.

import sys
import difflib
import numpy as np
import pandas as pd

movie_titles = sys.argv[1]
movie_ratings = sys.argv[2]
output_file = sys.argv[3]

# Read data from movie_list.txt, store in a df
movie_list = open(movie_titles).read().splitlines()

# Reading data from movie_ratings.csv
ratings = open(movie_ratings).read().splitlines()

# Dump it all into a dataframe
df_ratings = pd.DataFrame(ratings, columns=["all"])

# Remove the header line, I'll re-add it soon
df_ratings.drop(df_ratings["all"].index[[0]], inplace=True)

# Regex out the movie titles into a column
df_ratings['title'] = df_ratings['all'].str.extract('(.*?),\d\.?\d?$', expand=True)

# Regex out the movie ratings into a column
df_ratings['rating'] = df_ratings['all'].str.extract('.*?,(\d\.?\d?)$', expand=True)
df_ratings['rating'] = df_ratings['rating'].astype('float')

# Remove the column that contained a monolithic dump of the data
df_ratings.drop('all', axis=1, inplace=True)

# Find the closest match for every movie title from movie_list
def get_closest_movie_name(t):
  result = difflib.get_close_matches(t, movie_list)
  return ''.join(result)

df_ratings['title'] = df_ratings['title'].apply(get_closest_movie_name)

# Remove the entries that had no closest match
df_ratings = df_ratings[df_ratings['title'].str.len() != 0]

# Sort (and group) by title & aggregate & round to 2 decimal places
df_ratings = df_ratings.groupby('title').aggregate('mean').round(2)

# Write dataframe to a csv file
df_ratings.to_csv(output_file)


import os
import time

from tensorflow import estimator as tf_estimator
from tfx.components.trainer.rewriting import rewriter
from tfx.dsl.io import fileio

def _invoke_rewriter(src: str, dst: str, rewriter_inst: rewriter.BaseRewriter,
                     src_model_type: rewriter.ModelType,
                     dst_model_type: rewriter.ModelType):
  """Converts the provided model by invoking the specified rewriters.

  Args:
    src: Path to the source model.
    dst: Path where the destination model is to be written.
    rewriter_inst: instance of the rewriter to invoke.
    src_model_type: the `rewriter.ModelType` of the source model.
    dst_model_type: the `rewriter.ModelType` of the destination model.

  Raises:
    ValueError: if the source path is the same as the destination path.
  """

  if src == dst:
    raise ValueError('Source path and destination path cannot match.')

  original_model = rewriter.ModelDescription(src_model_type, src)
  rewritten_model = rewriter.ModelDescription(dst_model_type, dst)

  rewriter_inst.perform_rewrite(original_model, rewritten_model)

class RewritingExporter(tf_estimator.Exporter):
  """This class invokes the base exporter and a series of rewriters."""

  def __init__(self, base_exporter: tf_estimator.Exporter,
               rewriter_inst: rewriter.BaseRewriter):
    """Initializes the rewriting exporter.

    Args:
      base_exporter: The exporter of the original model.
      rewriter_inst: The rewriter instance to invoke. Must inherit from
        `rewriter.BaseRewriter`.
    """
    self._base_exporter = base_exporter
    self._rewriter_inst = rewriter_inst

  @property
  def name(self):
    """Name of the exporter."""
    return self._base_exporter.name

  def export(self, estimator, export_path, checkpoint_path, eval_result,
             is_the_final_export):
    """Exports the given `Estimator` to a specific format.

    Performs the export as defined by the base_exporter and invokes all of the
    specified rewriters.

    Args:
      estimator: the `Estimator` to export.
      export_path: A string containing a directory where to write the export.
      checkpoint_path: The checkpoint path to export.
      eval_result: The output of `Estimator.evaluate` on this checkpoint.
      is_the_final_export: This boolean is True when this is an export in the
        end of training.  It is False for the intermediate exports during the
        training. When passing `Exporter` to `tf.estimator.train_and_evaluate`
        `is_the_final_export` is always False if `TrainSpec.max_steps` is
        `None`.

    Returns:
      The string path to the base exported directory or `None` if export is
        skipped.

    Raises:
      RuntimeError: Unable to create a temporary rewrite directory.
    """
    base_path = self._base_exporter.export(estimator, export_path,
                                           checkpoint_path, eval_result,
                                           is_the_final_export)
    if not base_path:
      return None

    tmp_rewrite_folder = 'tmp-rewrite-' + str(int(time.time()))
    tmp_rewrite_path = os.path.join(export_path, tmp_rewrite_folder)
    if fileio.exists(tmp_rewrite_path):
      raise RuntimeError('Unable to create a unique temporary rewrite path.')
    fileio.makedirs(tmp_rewrite_path)

    _invoke_rewriter(base_path, tmp_rewrite_path, self._rewriter_inst,
                     rewriter.ModelType.SAVED_MODEL,
                     rewriter.ModelType.ANY_MODEL)

    fileio.rmtree(base_path)
    fileio.rename(tmp_rewrite_path, base_path)
    return base_path

def rewrite_saved_model(
    src: str,
    dst: str,
    rewriter_inst: rewriter.BaseRewriter,
    dst_model_type: rewriter.ModelType = rewriter.ModelType.SAVED_MODEL):
  """Rewrites the provided SavedModel.

  Args:
    src: location of the saved_model to rewrite.
    dst: location of the rewritten saved_model.
    rewriter_inst: the rewriter instance to invoke. Must inherit from
      `rewriter.BaseRewriter`.
    dst_model_type: the `rewriter.ModelType` of the destination model.
  """
  _invoke_rewriter(src, dst, rewriter_inst, rewriter.ModelType.SAVED_MODEL,
                   dst_model_type)


'''
Created on Feb 5, 2015

@author: Robert PASTOR
'''
import time

from Home.Environment.Atmosphere import Atmosphere
from Home.Environment.Earth import Earth

from Home.Environment.RunWaysDatabaseFile import RunWayDataBase
from Home.Environment.AirportDatabaseFile import AirportsDatabase

from Home.Guidance.GroundRunLegFile import GroundRunLeg
from Home.Guidance.DescentGlideSlopeFile import DescentGlideSlope

from Home.BadaAircraftPerformance.BadaAircraftDatabaseFile import BadaAircraftDatabase
from Home.BadaAircraftPerformance.BadaAircraftFile import BadaAircraft

Knots2MetersPerSecond = 0.514444444

if __name__ == '__main__':

    t0 = time.clock()
    print ( "time start= ", t0 )

    print ( '================ get aircraft =================' )
    aircraftIcaoCode = 'A320'
    atmosphere = Atmosphere()
    earth = Earth()

    acBd = BadaAircraftDatabase()
    assert acBd.read()

    if ( acBd.aircraftExists(aircraftIcaoCode)
            and acBd.aircraftPerformanceFileExists(acBd.getAircraftPerformanceFile(aircraftIcaoCode))):

        aircraft = BadaAircraft(aircraftIcaoCode,
                                  acBd.getAircraftPerformanceFile(aircraftIcaoCode),
                                  atmosphere,
                                  earth)
        aircraft.dump()
    else:
        raise ValueError(': aircraft not found= ' + aircraftIcaoCode)

    print ( '====================  find the run-ways ==================== '+ time.strftime("%c") )
    runWaysDb = RunWayDataBase()
    assert (runWaysDb.read())

    arrivalAirportICAOcode = 'LFPO'
    arrivalRunway =  runWaysDb.getFilteredRunWays(airportICAOcode = arrivalAirportICAOcode,
                           TakeOffLanding='Landing',
                           aircraftWakeTurbulence=aircraft.getWakeTurbulenceCategory())

    print ( '==================== read Airports Database ==================== '+ time.strftime("%c") )
    airportsDB = AirportsDatabase()
    assert (airportsDB.read())

    print ( '========== departure is LONDON ================' )
    departureAirport = airportsDB.getAirportFromICAOCode('EGLL')
    assert not(departureAirport is None)

    print ( '========== ' + str(arrivalRunway) + ' =================' )
    airportIcaoCode = arrivalRunway.getAirportICAOcode()
    arrivalAirport = airportsDB.getAirportFromICAOCode(airportIcaoCode)
    print ( 'arrival airport= {0}'.format(arrivalAirport) )

    aircraft.setArrivalAirportElevationMeters(arrivalAirport.fieldElevationAboveSeaLevelMeters)

    print ( '=========== add final turn, descent and ground run ===================' )
    arrivalGroundRun = GroundRunLeg( runway   = arrivalRunway,
                                         aircraft = aircraft,
                                         airport  = arrivalAirport )
    touchDownWayPoint = arrivalGroundRun.computeTouchDownWayPoint()
    print ( touchDownWayPoint )

    print ( '===================== final 3 degrees descending glide slope ================' )
    dummyDescentGlideSlope = DescentGlideSlope( runway   = arrivalRunway,
                                               aircraft = aircraft,
                                               arrivalAirport = arrivalAirport,
                                               descentGlideSlopeDegrees = 3.0)
    dummyDescentGlideSlope.buildSimulatedGlideSlope()
    firstGlideSlopeWayPoint = dummyDescentGlideSlope.getVertex(v=0).getWeight()

    print ( '=============== init aircraft state vector =================' )

    casKnots = 107.0
    casMetersPerSecond = casKnots * Knots2MetersPerSecond
    tasMetersPerSecond = atmosphere.cas2tas(casMetersPerSecond, 950.0, speed_units='m/s', altitude_units='m')

    elapsedTimeSeconds = 0.0
    aircraft.initStateVector(elapsedTimeSeconds = elapsedTimeSeconds ,
                          trueAirSpeedMetersSecond = tasMetersPerSecond ,
                          altitudeMeanSeaLevelMeters = firstGlideSlopeWayPoint.getAltitudeMeanSeaLevelMeters(),
                          deltaDistanceFlownMeters = 0.0)

    aircraft.setApproachConfiguration(0.0)
    aircraftMassKilograms = 49000.0
    aircraft.setAircraftMassKilograms(aircraftMassKilograms)

    print ( '===================== final 3 degrees descending glide slope ================' )
    descentGlideSlope = DescentGlideSlope( runway   = arrivalRunway,
                                               aircraft = aircraft,
                                               arrivalAirport = arrivalAirport,
                                               descentGlideSlopeDegrees = 3.0)

    descentGlideSlope.buildGlideSlope(elapsedTimeSeconds=0.0,
                                      initialWayPoint=firstGlideSlopeWayPoint,
                                      flownDistanceMeters = 300000.0,
                                      distanceStillToFlyMeters=10000.0)
    print ( '================= create output files =========================' )

    descentGlideSlope.createXlsxOutputFile()
    descentGlideSlope.createKmlOutputFile()
    aircraft.createStateVectorOutputFile()

    print ( '===================== end of simulation ================' )


from unittest import TestCase
import cnatra

class Test_cnatra(TestCase):
    def test__date_string_to_date_number(self):
        date_string_1 = '2019-04-04'
        date_string_2 = '2015-06-17'
        date_number_1 = cnatra._date_string_to_date_number(date_string_1)
        date_number_2 = cnatra._date_string_to_date_number(date_string_2)
        self.assertEqual(date_number_1, '7033')
        self.assertEqual(date_number_2, '5646')

    def test__get_front_page_url(self):
        vt7 = 'vt-7'
        vt9 = 'vt-9'
        date_1 = '2021-12-18'
        date_2 = '2002-03-21'
        self.assertEqual(cnatra._get_front_page_url(vt7, date_1), 'https://www.cnatra.navy.mil/scheds/tw1/SQ-VT-7/!2021-12-18!VT-7!Frontpage.pdf')
        self.assertEqual(cnatra._get_front_page_url(vt9, date_2), 'https://www.cnatra.navy.mil/scheds/tw1/SQ-VT-9/!2002-03-21!VT-9!Frontpage.pdf')


#!/usr/bin/env python3

import json
import os
import re
import requests
import shutil
import sqlite3
import shlex
import subprocess
import sys
import threading
import time
import zipfile

from cpe_search.cpe_search import update as update_cpe

NVD_DATAFEED_DIR = os.path.join(os.path.dirname(os.path.realpath(__file__)), "nvd_data_feeds")
VULNDB_FILE = os.path.join(os.path.dirname(os.path.realpath(__file__)), "vulndb.db3")
VULNDB_BACKUP_FILE = os.path.join(os.path.dirname(os.path.realpath(__file__)), "vulndb.db3.bak")
VULNDB_ARTIFACT_URL = "https://github.com/ra1nb0rn/search_vulns/releases/latest/download/vulndb.db3"
CVE_EDB_MAP_FILE = os.path.join(os.path.dirname(os.path.realpath(__file__)), "cveid_to_edbid.json")
CPE_DICT_FILE = os.path.join(os.path.dirname(os.path.realpath(__file__)), "cpe_search/cpe-search-dictionary_v2.3.csv")
CPE_DICT_ARTIFACT_URL = "https://github.com/ra1nb0rn/search_vulns/releases/latest/download/cpe-search-dictionary_v2.3.csv"
POC_IN_GITHUB_REPO = "https://github.com/nomi-sec/PoC-in-GitHub.git"
POC_IN_GITHUB_DIR = os.path.join(os.path.dirname(os.path.realpath(__file__)), "PoC-in-GitHub")
REQUEST_HEADERS = {"User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/62.0"}
NVD_UPDATE_SUCCESS = None
QUIET = False

def update_vuln_db():
    """Update the vulnerability database"""

    global NVD_UPDATE_SUCCESS

    if os.path.isfile(VULNDB_FILE):
        shutil.move(VULNDB_FILE, VULNDB_BACKUP_FILE)

    # start CVE ID <--> EDB ID mapping creation in background thread
    cve_edb_map_thread = threading.Thread(target=create_cveid_edbid_mapping)
    cve_edb_map_thread.start()

    # download NVD datafeeds from https://nvd.nist.gov/vuln/data-feeds
    if os.path.exists(NVD_DATAFEED_DIR):
        shutil.rmtree(NVD_DATAFEED_DIR)
    os.makedirs(NVD_DATAFEED_DIR)

    if not QUIET:
        print('[+] Downloading NVD data feeds and EDB information')

    # first download the data feed overview to retrieve URLs to all data feeds
    try:
        nvd_response = requests.get("https://nvd.nist.gov/vuln/data-feeds", timeout=20)
    except:
        NVD_UPDATE_SUCCESS = False
        communicate_warning('An error occured when trying to download webpage: https://nvd.nist.gov/vuln/data-feeds')
        rollback()
        cve_edb_map_thread.join()
        return 'An error occured when trying to download webpage: https://nvd.nist.gov/vuln/data-feeds'
    if nvd_response.status_code != requests.codes.ok:
        NVD_UPDATE_SUCCESS = False
        rollback()
        cve_edb_map_thread.join()
        return 'An error occured when trying to download webpage: https://nvd.nist.gov/vuln/data-feeds'

    # match the data feed URLs
    nvd_nist_datafeed_html = nvd_response.text
    jfeed_expr = re.compile(r"/feeds/json/cve/1\.1/nvdcve-1\.1-\d\d\d\d.json\.zip")
    nvd_feed_urls = re.findall(jfeed_expr, nvd_nist_datafeed_html)

    if not nvd_feed_urls:
        NVD_UPDATE_SUCCESS = False
        communicate_warning('No data feed links available on https://nvd.nist.gov/vuln/data-feeds')
        rollback()
        cve_edb_map_thread.join()
        return 'No data feed links available on https://nvd.nist.gov/vuln/data-feeds'

    # download all data feeds
    with open(os.devnull, "w") as outfile:
        zipfiles = []
        for nvd_feed_url in nvd_feed_urls:
            nvd_feed_url = "https://nvd.nist.gov" + nvd_feed_url
            outname = os.path.join(NVD_DATAFEED_DIR, nvd_feed_url.split("/")[-1])
            return_code = subprocess.call("wget %s -O %s" % (shlex.quote(nvd_feed_url), shlex.quote(outname)),
                                          stdout=outfile, stderr=subprocess.STDOUT, shell=True)
            if return_code != 0:
                NVD_UPDATE_SUCCESS = False
                communicate_warning('Retrieving NVD data feed %s failed' %  nvd_feed_url)
                rollback()
                cve_edb_map_thread.join()
                return 'Retrieving NVD data feed %s failed' %  nvd_feed_url
            zipfiles.append(outname)

    if os.path.isfile("wget-log"):
        os.remove("wget-log")

    # unzip data feeds
    if not QUIET:
        print("[+] Unzipping data feeds")

    for file in zipfiles:
        try:
            zip_ref = zipfile.ZipFile(file, "r")
            zip_ref.extractall(NVD_DATAFEED_DIR)
            zip_ref.close()
            os.remove(file)
        except:
            NVD_UPDATE_SUCCESS = False
            communicate_warning('Unzipping data feed %s failed' % file)
            rollback()
            cve_edb_map_thread.join()
            return 'Unzipping data feed %s failed' % file

    # build local NVD copy with downloaded data feeds
    print('[+] Building vulnerability database')
    create_db_call = ["./create_db", NVD_DATAFEED_DIR, VULNDB_FILE]
    with open(os.devnull, "w") as outfile:
        return_code = subprocess.call(create_db_call, stdout=outfile, stderr=subprocess.STDOUT)

    if return_code != 0:
        NVD_UPDATE_SUCCESS = False
        communicate_warning('Building NVD database failed')
        rollback()
        cve_edb_map_thread.join()
        return 'Building NVD database failed'

    shutil.rmtree(NVD_DATAFEED_DIR)
    NVD_UPDATE_SUCCESS = True
    cve_edb_map_thread.join()

    # build and add table of PoC-in-GitHub
    print('[+] Adding PoC-in-GitHub information')
    try:
        create_poc_in_github_table()
    except:
        communicate_warning('Building PoCs in GitHub table failed')
        rollback()
        return 'Building PoCs in GitHub table failed'

    # remove backup file on success
    if os.path.isfile(VULNDB_BACKUP_FILE):
        os.remove(VULNDB_BACKUP_FILE)

def rollback():
    """Rollback the DB / module update"""

    communicate_warning('An error occured, rolling back database update')
    if os.path.isfile(VULNDB_FILE):
        os.remove(VULNDB_FILE)
    if os.path.isfile(VULNDB_BACKUP_FILE):
        shutil.move(VULNDB_BACKUP_FILE, VULNDB_FILE)
    if os.path.isdir(NVD_DATAFEED_DIR):
        shutil.rmtree(NVD_DATAFEED_DIR)

def communicate_warning(msg: str):
    """Communicate warning via logger or stdout"""

    if not QUIET:
        print("Warning: " + msg)

def get_all_edbids():
    """ Return a list of all existing EDB IDs """
    files_exploits_resp = requests.get("https://raw.githubusercontent.com/offensive-security/exploitdb/master/files_exploits.csv", headers=REQUEST_HEADERS)
    files_exploits = files_exploits_resp.text
    return re.findall(r"^(\d+),.*$", files_exploits, re.MULTILINE)

def create_cveid_edbid_mapping():
    """ Create a CVE ID --> EDB ID mapping and store in local vuln DB """

    # get all unknown EDB IDs
    all_edbids, edbids_no_cveid = set(get_all_edbids()), set()
    if os.path.isfile(CVE_EDB_MAP_FILE):
        with open(CVE_EDB_MAP_FILE) as f:
            cve_edb_map = json.load(f)
        mapped_edbids = set()
        edbids_no_cveid = set(cve_edb_map["N/A"])
        for ebdids in cve_edb_map.values():
            mapped_edbids |= set(ebdids)
        remaining_edbids = all_edbids - mapped_edbids
    elif os.path.isfile(VULNDB_BACKUP_FILE):
        # if the DB is updated and previously built map is not available, build
        # incremental CVE ID --> EDB ID mapping based on previous version of DB
        cve_edb_map = recover_map_data_from_db()
        mapped_edbids = set()
        for edbids in cve_edb_map.values():
            mapped_edbids |= set(edbids)
        gh_map_edb_cve_resp = requests.get("https://raw.githubusercontent.com/andreafioraldi/cve_searchsploit/master/cve_searchsploit/exploitdb_mapping.json", headers=REQUEST_HEADERS)
        edb_cve_map = json.loads(gh_map_edb_cve_resp.text)
        edbids_no_cveid = set()
        for edbid, cveids in edb_cve_map.items():
            if not cveids:
                edbids_no_cveid.add(edbid)
        remaining_edbids = all_edbids - mapped_edbids - edbids_no_cveid
    else:
        # if a full DB installation is done, build CVE ID --> EDB ID mapping from scratch
        # use the mapping data from andreafioraldi's cve_searchsploit as base
        gh_map_cve_edb_resp = requests.get("https://raw.githubusercontent.com/andreafioraldi/cve_searchsploit/master/cve_searchsploit/exploitdb_mapping_cve.json", headers=REQUEST_HEADERS)
        cve_edb_map = json.loads(gh_map_cve_edb_resp.text)
        gh_map_edb_cve_resp = requests.get("https://raw.githubusercontent.com/andreafioraldi/cve_searchsploit/master/cve_searchsploit/exploitdb_mapping.json", headers=REQUEST_HEADERS)
        edb_cve_map = json.loads(gh_map_edb_cve_resp.text)
        edbids_no_cveid = set()
        for edbid, cveids in edb_cve_map.items():
            if not cveids:
                edbids_no_cveid.add(edbid)
        gh_captured_edbids = set(edb_cve_map.keys())
        remaining_edbids = all_edbids - gh_captured_edbids

    # manually crawl the mappings not yet created
    cveid_expr = re.compile(r"https://nvd.nist.gov/vuln/detail/(CVE-\d\d\d\d-\d+)")
    pause_time, last_time, printed_wait = 0.51, time.time(), False
    for i, edbid in enumerate(remaining_edbids):
        # wait at least pause_time seconds before making another request to not put heavy load on servers
        time_diff = time.time() - last_time
        if time_diff < pause_time:
            time.sleep(pause_time - time_diff)
        last_time = time.time()

        if not QUIET and NVD_UPDATE_SUCCESS and not printed_wait:
            print("Waiting for CVE ID <--> EDB ID map creation to finish ...")
            printed_wait = True
        elif (NVD_UPDATE_SUCCESS is not None) and (not NVD_UPDATE_SUCCESS):
            return

        exploit_page_resp = requests.get("https://www.exploit-db.com/exploits/%s" % edbid, headers=REQUEST_HEADERS, timeout=30)
        cveids = cveid_expr.findall(exploit_page_resp.text)

        if not cveids:
            edbids_no_cveid.add(edbid)

        for cveid in cveids:
            if cveid not in cve_edb_map:
                cve_edb_map[cveid] = []
            cve_edb_map[cveid].append(edbid)

    cve_edb_map["N/A"] = list(edbids_no_cveid)  # store all EDBIDs without CVE
    with open(CVE_EDB_MAP_FILE, "w") as f:
        f.write(json.dumps(cve_edb_map))

    while NVD_UPDATE_SUCCESS is None:
        time.sleep(1)

    if NVD_UPDATE_SUCCESS:
        fill_database_with_mapinfo(cve_edb_map)

def fill_database_with_mapinfo(cve_edb_map):
    """ Put the given mapping data into the database specified by the given cursor """

    db_conn = sqlite3.connect(VULNDB_FILE)
    db_cursor = db_conn.cursor()

    update_statement = "UPDATE cve SET edb_ids=? WHERE cve_id=?"
    for cveid, edbids in cve_edb_map.items():
        if cveid == "N/A":  # skip the fake item holding EDBIDs without CVEID
            continue

        edbids = sorted(set(edbids), key=lambda eid: int(eid))
        db_cursor.execute(update_statement, (",".join(edbids), cveid))

    db_conn.commit()
    db_conn.close()

def recover_map_data_from_db():
    """ Return stored CVE ID <--> EDB ID mapping from DB backup file """

    db_conn = sqlite3.connect(VULNDB_BACKUP_FILE)
    db_cursor = db_conn.cursor()

    # recover CVE ID --> EDB ID data
    db_cursor.execute("SELECT cve_id, edb_ids FROM cve")
    map_data = db_cursor.fetchall()
    cve_edb_map = {}
    for cve_id, edb_ids in map_data:
        if edb_ids:
            cve_edb_map[cve_id] = edb_ids.split(",")

    db_conn.close()
    return cve_edb_map

def create_poc_in_github_table():
    """ Create CVE ID <--> GitHub PoC URL mapping"""

    if os.path.isdir(POC_IN_GITHUB_DIR):
        shutil.rmtree(POC_IN_GITHUB_DIR)

    # download PoC in GitHub Repo
    return_code = subprocess.call(
        "git clone --depth 1 %s '%s'"
        % (POC_IN_GITHUB_REPO, POC_IN_GITHUB_DIR),
        shell=True,
        stderr=subprocess.DEVNULL
    )
    if return_code != 0:
        raise (Exception("Could not download latest resources of PoC-in-GitHub"))

    # add PoC / exploit information to DB
    db_conn = sqlite3.connect(VULNDB_FILE)
    db_cursor = db_conn.cursor()
    db_cursor.execute('CREATE TABLE cve_poc_in_github_map (cve_id VARCHAR(25), reference text, PRIMARY KEY (cve_id, reference));')
    db_conn.commit()

    for file in os.listdir(POC_IN_GITHUB_DIR):
        yearpath = os.path.join(POC_IN_GITHUB_DIR, file)
        if not os.path.isdir(yearpath):
            continue
        try:
            int(file)
        except:
            continue

        for cve_file in os.listdir(yearpath):
            cve_filepath = os.path.join(yearpath, cve_file)
            cve_id = os.path.splitext(cve_file)[0]
            with open(cve_filepath) as cve_fh:
                cve_json = json.loads(cve_fh.read())
                for poc_item in cve_json:
                    db_cursor.execute('INSERT INTO cve_poc_in_github_map VALUES (?, ?)', (cve_id, poc_item['html_url']))

    db_conn.commit()
    db_conn.close()

    if os.path.isdir(POC_IN_GITHUB_DIR):
        shutil.rmtree(POC_IN_GITHUB_DIR)

def run(full=False):
    if full:
        print("[+] Updating stored software information")
        update_cpe("2.3")
        print("[+] Updating vulnerability database")
        error = update_vuln_db()
        if error:
            print(error)
            sys.exit(1)
    else:
        print("[+] Downloading latest versions of resources ...")
        if os.path.isfile(CPE_DICT_FILE):
            shutil.move(CPE_DICT_FILE, CPE_DICT_FILE+".bak")
        if os.path.isfile(VULNDB_FILE):
            shutil.move(VULNDB_FILE, VULNDB_BACKUP_FILE)

        try:
            quiet_flag = ""
            if QUIET:
                quiet_flag = "-q"
            else:
                quiet_flag = "-q --show-progress"

            return_code = subprocess.call("wget %s %s -O %s" % (quiet_flag, shlex.quote(CPE_DICT_ARTIFACT_URL),
                                          shlex.quote(CPE_DICT_FILE)), shell=True)
            if return_code != 0:
                raise(Exception("Could not download latest resource files"))
            return_code = subprocess.call("wget %s %s -O %s" % (quiet_flag, shlex.quote(VULNDB_ARTIFACT_URL),
                                          shlex.quote(VULNDB_FILE)), shell=True)
            if return_code != 0:
                raise(Exception("Could not download latest resource files"))

            if os.path.isfile(CPE_DICT_FILE+".bak"):
                os.remove(CPE_DICT_FILE+".bak")
            if os.path.isfile(VULNDB_BACKUP_FILE):
                os.remove(VULNDB_BACKUP_FILE)
        except Exception as e:
            print("[!] Encountered an error: %s" % str(e))
            if os.path.isfile(CPE_DICT_FILE+".bak"):
                shutil.move(CPE_DICT_FILE+".bak", CPE_DICT_FILE)
                print("[+] Restored software infos from backup")
            if os.path.isfile(VULNDB_BACKUP_FILE):
                shutil.move(VULNDB_BACKUP_FILE, VULNDB_FILE)
                print("[+] Restored vulnerability infos from backup")

if __name__ == "__main__":
    if len(sys.argv) > 1 and sys.argv[1] == "--full":
        run(True)
    else:
        run(False)


"""
Given a linked list, remove the n-th node from the end of list and return its head.

Example:

Given linked list: 1->2->3->4->5, and n = 2.

After removing the second node from the end, the linked list becomes 1->2->3->5.
Note:

Given n will always be valid.

Follow up:

Could you do this in one pass?
"""

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def removeNthFromEnd(self, head, n):
        """
        :type head: ListNode
        :type n: int
        :rtype: ListNode
        """
        dummy = ListNode(0)
        dummy.next = head
        slow = quick = dummy
        while quick:
            if n >= 0:
                n -= 1
                quick = quick.next
            else:
                quick = quick.next
                slow = slow.next
        slow.next = slow.next.next
        return dummy.next

class Solution(object):
    def removeNthFromEnd(self, head, n):
        """
        :type head: ListNode
        :type n: int
        :rtype: ListNode
        """
        dummy = ListNode(0)
        dummy.next = head

        count, p = 0, dummy
        while p:
            count += 1
            p = p.next
        k = count - n - 1

        p = dummy
        while k:
            p = p.next
            k -= 1

        p.next = p.next.next
        return dummy.next

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode:

        m = 0
        cur = head
        while cur:
            m += 1
            cur = cur.next

        n = m - n
        dummy = cur = ListNode()
        dummy.next = head
        while n:
            cur = cur.next
            n-=1

        cur.next = cur.next.next

        return dummy.next


import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
import pandas as pd

import calendar
from datetime import date

from scipy import stats
import collections

import os
import re # reg ex

def main():
    #makeFiles()
    #clean_csv('www.google.com', day=['2018-03-25', '2018-03-24'])
    create_plot_temporal_v(site = "aggregate", fshow_hours = False, fshow_daily = True, savefig = True)
    #create_plot_cdf(site = "aggregate", showfig = True)
    #create_plot_all(savefig = True)
    #create_plot_all(showfig = True)
    #create_plot_cdf(showfig = True, day = "2018-02-11 Sunday")
    #create_plot_violin(site = "aggregate")
    #create_plot_violin("www.taobao.com")
    #create_plot_cdf(showfig = True, savefig = True)
    #create_plot_cdf(showfig = True, day = "2018-02-13 Tuesday")
    #create_plot_cdf(site = "www.google.com", showfig = True)
    #create_plot_cdf(site = "www.google.com", showfig = True)

def clean_csv(site = "aggregate", day = ['all'], show_hours = False, show_daily = False):
# get the important variables into the dataFrame. For specific site or aggregate,
# and also return only specific days in the dataframe if specified other than 'all'
    df = pd.read_csv("aggregate.txt")
    df = df.loc[:, ['tstamp', 'sitename', 'RTT', 'RTTtwo', 'RTTthree', 'pingRTT']]
    df = df if site == "aggregate" else df[df.sitename.str.match('^' + site + '$')] #regex for getting the exact site if specified
    #df = df if day == ['all'] else df[df.tstamp.str.contains('|'.join([x for x in day])) if len(day) > 1 else df.tstamp.str.contains(day[0])] #this line isolates specific days as specified by the array day otherwise it shows all the days if default value of ['all'] is used for days
    df = df[~df.pingRTT.str.match("None")]
    df.pingRTT.apply(lambda val: float(val))
    df.pingRTT = df.pingRTT.astype('float64')
    if show_hours:
        df.tstamp = df.tstamp.apply(lambda val: convert_tstamp_to_hour(val))
        print(df)
    if show_daily:
        df.tstamp = df.tstamp.apply(lambda val: convert_tstamp_to_day_of_week(val))
        print(df)
    return df

def convert_tstamp_to_hour(tstamp):
    '''
    used in the clean_csv function to change a noisy tstamp
    to just the hour, rounded down
    '''
    p = re.compile('(2018-03-\d\d) ((\d\d).*)') # group 3 contains the hour
    m = p.match(tstamp)
    hour = m.group(3)
    return hour

def convert_tstamp_to_day_of_week(tstamp):
    p = re.compile('(2018)-(03)-(\d\d)')
    m = p.match(tstamp)
    year = int(m.group(1))
    month = int(m.group(2))
    day = int(m.group(3))
    number = date.weekday(date(year, month, day))
    return calendar.day_name[number]

def makeFiles(file = "aggregate.txt"):
#the purpose of this function is to create
#a separate log file for each website in the
#directory folder logs.
    wd = os.getcwd() # this is where to get the files
    data = clean_csv() # get the values from the aggregate
    sites = data.sitename.unique() # get the unique sitenames
    for site in sites: # for each site
        f = open(wd + '/logs/' + site, 'w') # create new file with sitename in logs
        f.write(data[data.sitename.str.match('^' + site + '$')].to_csv()) # and write site specific data

def create_plot_all(savefig = False, showfig = False, day = ['all']):
    wd = os.getcwd() + '/logs/' # this is where to get the files
    sites = os.listdir(wd) # the list of sites in the directory
    create_plot_cdf(site = "aggregate", showfig = showfig, savefig = savefig)
    for site in sites:
        f = open(wd + site) # open individual site
        create_plot_cdf(site, showfig, savefig)

def create_plot_cdf(site, showfig = False, savefig = False, day = ['all'], show_hours = False):
    data = clean_csv(site, show_hours)
    data = data.loc[:, ['RTT', 'RTTtwo', 'RTTthree', 'pingRTT']] # only want the relevant columns in dataframe
    y = np.arange(1, len(data.RTT)+1) / len(data.RTT)
    for col in data.columns:
        _ = plt.plot(np.sort(data[col]), np.linspace(0, 1, len(data[col]), endpoint=False))
    _ = plt.ylabel('ECDF')
    _ = plt.legend(['ping RTT', 'TTFB - PRET', 'TTFB - PRET 2ND LOAD', 'TTFB - PRET 3RD LOAD'])
    ax1 = plt.subplot(111)
    total = [data[x] for x in data]
    xlim_max = np.percentile(total, 97.5)
    ax1.set_xlim([0, xlim_max])
    plt.savefig('graphs/CDF-of-' + site.replace('www.','') + '.png') if savefig else {}
    plt.show() if showfig else {plt.close()}

def create_plot_temporal(site, showfig = True, savefig = False, day = ['all'], show_hours = True):
    data = clean_csv(site, show_hours = True)
    #data = dict(data)
    #print(data)
    for key, value in data.iteritems():
        df = data[key]
        _ = plt.plot(np.sort(df['RTTtwo']), np.linspace(0, 1, len(df['RTTtwo']), endpoint=False))
    _ = plt.ylabel('ECDF')
    _ = plt.legend([key for key, value in data.iteritems()])
    ax1 = plt.subplot(111)
    ax1.set_xlim([0, 1000])
    plt.show() if showfig else {plt.close()}

def create_plot_temporal_v(site = "aggregate", showfig = True, savefig = False, day = ['all'], fshow_hours = False, fshow_daily = False):
    dataf = clean_csv(site, show_hours = fshow_hours, show_daily = fshow_daily)
    sns.set_style("whitegrid")
    yposlist = dataf.groupby(['tstamp'])['RTTtwo'].median().tolist()
    # print(yposlist)
    # print(dataf.groupby(['tstamp'])['RTTtwo'])
    xposlist = range(len(yposlist))
    grouped = dataf.groupby('tstamp')
    print(np.std(dataf.RTTtwo, ddof=0))
    print(np.mean(dataf.RTTtwo))
    # print(grouped['RTTtwo'].agg('std'))
    stringlist = ["std:" + str(x) for x in grouped['RTTtwo'].agg(np.std)]
    ax1 = plt.subplot(111)
    ax1 = sns.violinplot(x = 'tstamp', y = 'RTTtwo', data = dataf)
    for i in range(len(stringlist)):
        ax1.text(xposlist[i], yposlist[i], stringlist[i])
    ax1.set_ylim([0, 750])
    plt.savefig('graphs/VIOLIN-of-weekly' + site.replace('www.','') + '.png', dpi = 600) if savefig else {}
    plt.show() if showfig else {plt.close()}

def create_plot_violin(site = "aggregate", day = ""):
    data = clean_csv(site)
    data = data.loc[:, ['RTT', 'RTTtwo', 'RTTthree', 'pingRTT']]
    sns.set_style("whitegrid")
    sns.violinplot(data=data)
    ax1 = plt.subplot()
    total = [data[x] for x in data]
    ylim_max = np.percentile(total, 97.5)
    ax1.set_ylim([0, ylim_max])
    plt.show()

main()


import torch
from safetensors.torch import save_file
import urllib.request
import os
import sys
import argparse

data_path = os.path.join(os.path.dirname(__file__), "../data/")
vocab_filename = "bpe_simple_vocab_16e6.txt"

def ensure_data_dir(safetensors):
    print("Ensuring empty data directory...")

    if os.path.exists(data_path):
        # Fail if conflicting files exist
        files = os.listdir(data_path)
        newfiles = [x for name in safetensors for x in (f"{name}.bin", f"{name}.safetensors")]
        newfiles += [vocab_filename, f"{vocab_filename}.gz"]
        conflicts = set(files) & set(newfiles)
        if len(conflicts) != 0:
            print("Error: please remove the following files from data directory:")
            print(conflicts)
            sys.exit("Found conflicting files in data directory.")
    else:
        os.mkdir(data_path)

    print("Found no conflicts!")

def get_safetensors(safetensors, weight_bits):
    for name, url in safetensors.items():
        print(f"Getting {name} {weight_bits} bit tensors...")

        # Download bin file
        urllib.request.urlretrieve(url, os.path.join(data_path, f"{name}.bin"))

        # Make safetensors file
        model = torch.load(os.path.join(data_path, f"{name}.bin"), map_location=torch.device("cpu"))
        tensors = {k: v.clone().detach() for k, v in model.items() if 'text_model' in k} if name in ["clip_v2.1", "pytorch_model"] else dict(model)
        save_file(tensors, os.path.join(data_path, f"{name}.safetensors"))

        # Remove bin file
        os.remove(os.path.join(data_path, f"{name}.bin"))

def get_vocab(vocab_url):
    print("Getting vocab...")
    urllib.request.urlretrieve(vocab_url, os.path.join(data_path, f"{vocab_filename}.gz"))
    import gzip
    with gzip.open(os.path.join(data_path, f"{vocab_filename}.gz"), 'rb') as g:
        with open(os.path.join(data_path, vocab_filename), "xb") as f:
            f.write(g.read())
    os.remove(os.path.join(data_path, f"{vocab_filename}.gz"))

def get_urls(sd_version, weight_bits):
    branch = "main"
    if weight_bits == "16":
        branch = "fp16" # fp16 for float16 weights or main for float32 weights

    safetensors_v1_5 = {
        "vae": f"https://huggingface.co/runwayml/stable-diffusion-v1-5/resolve/{branch}/vae/diffusion_pytorch_model.bin",
        "unet": f"https://huggingface.co/runwayml/stable-diffusion-v1-5/resolve/{branch}/unet/diffusion_pytorch_model.bin",
        "pytorch_model": f"https://huggingface.co/openai/clip-vit-large-patch14/resolve/main/pytorch_model.bin"
    }
    safetensors_v2_1 = {
        "vae_v2.1": f"https://huggingface.co/stabilityai/stable-diffusion-2-1/resolve/{branch}/vae/diffusion_pytorch_model.bin",
        "unet_v2.1": f"https://huggingface.co/stabilityai/stable-diffusion-2-1/resolve/{branch}/unet/diffusion_pytorch_model.bin",
        "clip_v2.1": f"https://huggingface.co/stabilityai/stable-diffusion-2-1/resolve/{branch}/text_encoder/pytorch_model.bin"
    }
    vocab_url = "https://github.com/openai/CLIP/raw/main/clip/bpe_simple_vocab_16e6.txt.gz"

    return safetensors_v1_5 if sd_version == "1.5" else safetensors_v2_1, vocab_url

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="Download weights for diffusers-rs.")
    parser.add_argument("--sd_version", "-v", choices=["2.1", "1.5"], default="2.1")
    parser.add_argument("--weight_bits", "-w", choices=["16", "32"], default="16")
    args = parser.parse_args()

    print("Setting up model weights for diffusers-rs...")

    safetensors, vocab_url = get_urls(args.sd_version, args.weight_bits)
    ensure_data_dir(safetensors)
    get_vocab(vocab_url)
    get_safetensors(safetensors, args.weight_bits)

    print("Finished!")


import cv2
import numpy as np

capture = cv2.VideoCapture('move.mp4')
ret,frame1 = capture.read()
ret,frame2 = capture.read()
frame2 = cv2.resize(frame2,(500,500))
frame1 = cv2.resize(frame1,(500,500))

while True:
    diff = cv2.absdiff(frame1,frame2)
    gray = cv2.cvtColor(diff,cv2.COLOR_BGR2GRAY)
    blur = cv2.GaussianBlur(gray,(5,5),0)
    _,thresh = cv2.threshold(blur,20,225,cv2.THRESH_BINARY)
    dilute = cv2.dilate(thresh,None,iterations=3)
    contour,_ = cv2.findContours(dilute,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)

    for coun in contour:
        x,y,w,h = cv2.boundingRect(coun)

        if cv2.contourArea(coun)<900:
            continue

        cv2.rectangle(frame1,(x,y),(x+w,y+h),(0,255,0),thickness=2)
        cv2.putText(frame1,'statue : moving',(7,10),cv2.FONT_HERSHEY_PLAIN,2,(0,21,34),thickness=1)

    #cv2.drawContours(frame1,contour,-1,(0,255,0),thickness=2)
    cv2.imshow('image',frame1)

    frame1 = frame2
    ret,frame2 = capture.read()
    frame2 = cv2.resize(frame2, (500, 500))

    k = cv2.waitKey(20)
    if k==ord('s'):
        break


import sys
from PyQt5.QtWidgets import *

class MyWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setupUi()

    def setupUi(self):
        self.setGeometry(800, 400, 260, 150)

        label = QLabel("이름:", self)
        label.move(20, 20)

        self.line_edit = QLineEdit("", self)
        self.line_edit.move(80, 20)
        self.line_edit.textChanged.connect(self.line_edit_changed)

        self.status_bar = QStatusBar(self)
        self.setStatusBar(self.status_bar)

    def line_edit_changed(self):
        self.status_bar.showMessage("당신의 이름은: " + self.line_edit.text())

if __name__ == "__main__":
    app = QApplication(sys.argv)
    my_window = MyWindow()
    my_window.show()
    app.exec_()


from .pages.product_page import ProductPage
from .pages.basket_page import BasketPage
from .pages.login_page import LoginPage
import pytest

link_product_page = "http://selenium1py.pythonanywhere.com/catalogue/coders-at-work_207"
link_product_page_another = "http://selenium1py.pythonanywhere.com/en-gb/catalogue/the-city-and-the-stars_95/"
link_user_product_page = "http://selenium1py.pythonanywhere.com/catalogue/coders-at-work_207"

@pytest.mark.need_review
@pytest.mark.parametrize('link', ["http://selenium1py.pythonanywhere.com/catalogue/coders-at-work_207/?promo=offer0",
                                   "http://selenium1py.pythonanywhere.com/catalogue/coders-at-work_207/?promo=offer1",
                                  "http://selenium1py.pythonanywhere.com/catalogue/coders-at-work_207/?promo=offer2",
                                  "http://selenium1py.pythonanywhere.com/catalogue/coders-at-work_207/?promo=offer3",
                                  "http://selenium1py.pythonanywhere.com/catalogue/coders-at-work_207/?promo=offer4",
                                  "http://selenium1py.pythonanywhere.com/catalogue/coders-at-work_207/?promo=offer5",
                                  "http://selenium1py.pythonanywhere.com/catalogue/coders-at-work_207/?promo=offer6",
                                  pytest.param("http://selenium1py.pythonanywhere.com/catalogue/coders-at-work_207/?promo=offer7", marks=pytest.mark.xfail),
                                  "http://selenium1py.pythonanywhere.com/catalogue/coders-at-work_207/?promo=offer8",
                                  "http://selenium1py.pythonanywhere.com/catalogue/coders-at-work_207/?promo=offer9"])
def test_guest_can_add_product_to_basket(browser, link):
    page = ProductPage(browser, link)
    page.open()
    page.add_product_to_basket()
    page.solve_quiz_and_get_code()
    page.should_be_add_to_basket_message()
    page.should_be_product_cost_equal_basket_cost()

@pytest.mark.xfail(reason="known message issue")
def test_guest_cant_see_success_message_after_adding_product_to_basket(browser):
    page = ProductPage(browser, link_product_page)
    page.open()
    page.add_product_to_basket()
    page.should_not_be_add_to_basket_message()

def test_guest_cant_see_success_message(browser):
    page = ProductPage(browser, link_product_page)
    page.open()
    page.should_not_be_add_to_basket_message_at_product_page()

@pytest.mark.xfail(reason="known message disappear issue")
def test_message_disappeared_after_adding_product_to_basket(browser):
    page = ProductPage(browser, link_product_page)
    page.open()
    page.add_product_to_basket()
    page.should_disappear_add_to_basket_message()

def test_guest_should_see_login_link_on_product_page(browser):
    page = ProductPage(browser, link_product_page_another)
    page.open()
    page.should_be_login_link()

@pytest.mark.need_review
def test_guest_can_go_to_login_page_from_product_page(browser):
    page = ProductPage(browser, link_product_page_another)
    page.open()
    page.go_to_login_page()

@pytest.mark.need_review
def test_guest_cant_see_product_in_basket_opened_from_product_page(browser):
    page = ProductPage(browser, link_product_page_another)
    page.open()
    page.go_to_basket_page()
    basket_page = BasketPage(browser, browser.current_url)
    basket_page.should_be_basket_empty()

@pytest.mark.user_work_with_basket
class TestUserAddToBasketFromProductPage():
    @pytest.fixture(scope="function", autouse=True)
    def setup(self, browser):
        link = "http://selenium1py.pythonanywhere.com/accounts/login/"
        page = LoginPage(browser, link)
        #prepare test data
        email_test_data, password_test_data = page.prepare_register_test_data()
        #setup step
        page.open()
        page.register_new_user(email_test_data, password_test_data)
        page.should_be_authorized_user()

    @pytest.mark.need_review
    def test_user_can_add_product_to_basket(self, browser):
        page = ProductPage(browser, link_user_product_page)
        page.open()
        page.add_product_to_basket()
        page.should_be_add_to_basket_message()
        page.should_be_product_cost_equal_basket_cost()

    def test_user_cant_see_success_message(self, browser):
        page = ProductPage(browser, link_user_product_page)
        page.open()
        page.should_not_be_add_to_basket_message_at_product_page()


def inverse(n):
    def expo(n):
        x = str(n)
        return len(x)-1
    if n//10 == 0:
        res = n
    else:
        i = expo(n)
        res = (n%10)*10**i + inverse(n//10)
    return res

print(inverse(4567))