"""
    Toolbar giving access to experimental MXS -> Python translation
"""
#pylint: disable= import-error, invalid-name, too-few-public-methods
from PySide2.QtWidgets import (QApplication, QWidget, QDockWidget,
        QVBoxLayout, QLabel, QTextEdit, QStyle, QToolBar, QCommonStyle)
from PySide2.QtGui import (QSyntaxHighlighter, QTextCharFormat,
        QFont, Qt, QBrush, QColor, QKeyEvent)
from PySide2 import QtCore
from PySide2.QtCore import QMimeData, QEvent
from pygments.lexers.python import PythonLexer
from pygments.token import Token
from mxs2py import topy
from qtmax import GetQMaxMainWindow

def makeFormat(weight, color):
    """Create a format from a font weight and color"""
    f = QTextCharFormat()
    f.setFontWeight(weight)
    f.setForeground(color)
    return f

# Color scheme for the syntax highlighted QTextEdit

COMMENT_FORMAT=makeFormat(QFont.Normal, QBrush(QColor(0xd8, 0x98, 0x68)))
OPERATOR_FORMAT=makeFormat(QFont.Bold, QBrush(QColor(0x66, 0x87, 0x99)))
KEYWORD_FORMAT=makeFormat(QFont.Normal, QBrush(QColor(0x8b,0xe5,0x7a)))
LITERAL_FORMAT=makeFormat(QFont.Normal, QBrush(QColor(0xcf,0x6a,0xa0)))
IDENTIFIER_FORMAT=makeFormat(QFont.Normal, QBrush(QColor(220, 220, 220)))
BUILTIN_FORMAT=makeFormat(QFont.Normal, QBrush(QColor(200, 100, 150)))
DEFAULT_FORMAT = makeFormat(QFont.Normal, QBrush(QColor(220, 0, 0)))

COLOR_SCHEME = {
    Token.Text: IDENTIFIER_FORMAT,
    Token.Text.Whitespace: IDENTIFIER_FORMAT,
    Token.Error: IDENTIFIER_FORMAT,
    Token.Other: IDENTIFIER_FORMAT,
    Token.Keyword: KEYWORD_FORMAT,
    Token.Keyword.Namespace: KEYWORD_FORMAT,
    Token.Keyword.Constant: LITERAL_FORMAT,
    Token.Name: IDENTIFIER_FORMAT,
    Token.Name.Function: IDENTIFIER_FORMAT,
    Token.Name.Builtin: BUILTIN_FORMAT,
    Token.Name.Builtin.Pseudo: BUILTIN_FORMAT,
    Token.Name.Namespace: LITERAL_FORMAT,
    Token.Literal: LITERAL_FORMAT,
    Token.Literal.String: LITERAL_FORMAT,
    Token.Literal.String.Double: LITERAL_FORMAT,
    Token.Literal.String.Single: LITERAL_FORMAT,
    Token.Literal.Number: LITERAL_FORMAT,
    Token.Literal.Number.Integer: LITERAL_FORMAT,
    Token.Literal.Number.Float: LITERAL_FORMAT,
    Token.Operator: OPERATOR_FORMAT,
    Token.Operator.Word: OPERATOR_FORMAT,
    Token.Punctuation: OPERATOR_FORMAT,
    Token.Comment: COMMENT_FORMAT,
    Token.Comment.Single: COMMENT_FORMAT,
    Token.Generic: IDENTIFIER_FORMAT
}

class GenericHighlighter(QSyntaxHighlighter):
    """Initialize a syntax highlighter"""
    def highlightBlock(self, text):
        """higlight a block of text"""
        results = self.lexer.get_tokens_unprocessed(text)
        for index, tokentype,value in results:
            style = COLOR_SCHEME[tokentype] if tokentype in COLOR_SCHEME else DEFAULT_FORMAT
            if tokentype not in COLOR_SCHEME:
                print(tokentype)
            self.setFormat(index, len(value),style)

class PythonHighlighter(GenericHighlighter):
    """Intialize a python syntax highlighter"""
    lexer = PythonLexer()

class CustomEditor(QTextEdit):
    """Custom editor for showing python code and
    converting mxs code to python when dropped or pasted."""
    def insertFromMimeData(self, source):
        """Insert code from mime data"""
        if source.hasText():
            # get the text
            snippet = source.text()
            # try to convert it to python
            QApplication.setOverrideCursor(Qt.WaitCursor)
            try:
                (output, err) = topy(snippet)
                pysnippet = output + "\n"
                source = QMimeData()
                source.setText(pysnippet)
                if err:
                    print(err)
            except Exception as e: #pylint: disable=broad-exception-caught
                print(e)
            QApplication.restoreOverrideCursor()
        super().insertFromMimeData(source)

    def keyPressEvent (self, event):
        """Simulate a tab"""
        if event.key() == Qt.Key_Tab:
            event = QKeyEvent (QEvent.KeyPress, Qt.Key_Space,
                Qt.KeyboardModifiers(event.nativeModifiers()),
                "    ")
        super().keyPressEvent(event)

class ScriptEditor(QWidget):
    """
    Custom dialog attached to the 3ds Max main window
    Message label and action push button to create a cylinder in the 3ds Max scene graph
    """
    def __init__(self, parent=None):
        """Initialize the script editor"""
        super().__init__(parent)
        self.init_ui()
    def init_ui(self):
        """ Prepare Qt UI layout for custom dialog """
        main_layout = QVBoxLayout()
        # Add some explanation of what to do
        main_layout.addWidget(QLabel("Drop or Paste MXS Snippets to get them translated to Python"))
        # Add a toolbar
        toolbar = QToolBar()

        def clear_it():
            """Clear editor contents"""
            self.pyEdit.clear()
        def run_it():
            """Run editor contents"""
            exec(self.pyEdit.toPlainText()) #pylint: disable=exec-used
        main_layout.addWidget(toolbar)
        self.common_style=QCommonStyle()
        print(self.common_style)
        self.runAction = toolbar.addAction(
                self.common_style.standardIcon(QStyle.SP_ArrowRight), "Run Snippet", run_it)
        self.clearAction = toolbar.addAction(
                self.common_style.standardIcon(QStyle.SP_DialogCancelButton), "Clear", clear_it)

        self.pyEdit=CustomEditor()
        self.pyEdit.setStyleSheet("background-color: #333333;")
        def enable_text_actions():
            empty = self.pyEdit.document().isEmpty()
            self.runAction.setEnabled(not empty)
            self.clearAction.setEnabled(not empty)
        self.pyEdit.textChanged.connect(enable_text_actions)

        main_layout.addWidget(self.pyEdit)
        self.setLayout(main_layout)
        # syntax highlighting
        self.pyHighlighter = PythonHighlighter(self.pyEdit.document())
        enable_text_actions()

def new_editor(tabto=None, floating=False, dockingarea=QtCore.Qt.RightDockWidgetArea):
    """Create an editor dock widget."""
    main_window = GetQMaxMainWindow()
    # create and setup a console
    recorder = ScriptEditor()
    dock_widget = QDockWidget(main_window)
    dock_widget.setWidget(recorder)
    dock_widget.setObjectName("py_editor")
    dock_widget.setWindowTitle("Experimental MXS -> Python Translator")
    main_window.addDockWidget(dockingarea, dock_widget)
    if not tabto is None:
        tabw = main_window.findChild(QWidget, tabto)
        main_window.tabifyDockWidget(tabw, dock_widget)
    dock_widget.setFloating(floating)
    dock_widget.show()
    return recorder

if __name__ == "__main__":
    theEditor = new_editor()


#!/usr/bin/python
# ex:set fileencoding=utf-8:

from __future__ import unicode_literals

VERSION = ((0, 1, 5), ('a', 0))  # all alpha versions
# VERSION = ((0, 2), ('b', 0)) # first beta
# VERSION = ((0, 3), ('b', 0)) # second beta
# VERSION = ((0, 9), ('rc', 0)) # first official release
# VERSION = ((1, 0), ('final', 0)) # first final version

def get_version(dev=True):
    """
    return a version number consistent with PEP386
    """
    assert len(VERSION) == 2
    assert VERSION[1][0] in ('a', 'b', 'rc', 'final')

    version = '.'.join(map(str, VERSION[0]))

    if VERSION[1][0] == "final":  # pragma: no cover
        return version

    version += VERSION[1][0] + str(VERSION[1][1])

    if VERSION[1][1] == 0 and dev:
        import os
        import subprocess
        import datetime

        # get version information from git
        repo_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
        get_time = subprocess.Popen(
            'git log --pretty=format:%ct --quiet -1 HEAD',
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            shell=True,
            cwd=repo_dir,
            universal_newlines=True,
        )

        timestamp = get_time.communicate()[0]
        try:
            timestamp = datetime.datetime.utcfromtimestamp(int(timestamp))
            version += '.dev%s' % timestamp.strftime('%Y%m%d%H%M%S')
        except ValueError:  # pragma: no cover
            pass

    return version

__version__ = get_version(dev=False)
__author__ = 'Sebastian Braun'
__contact__ = 'sebastian@elmnt.de'
__homepage__ = 'http://www.igelware.de'
__docformat__ = 'restructuredtext'

default_app_config = 'djangobmf.apps.BMFConfig'


import os
import sys
import subprocess
import datetime
import pickle
import pandas as pd
from django.core.wsgi import get_wsgi_application
import json
from dateutil import parser

def find_latest_csvname(specific_date='<YYYYMMDD>'):
    """Finds the newest csv name in the drive.  Can pull a specific date
       by filling in the specific date field.

    Keyword arguments:
        specific date: [string in YYYYMMDD date format ] This is optional.  Standard it to leave blank and it will
                        pull the latest.

    Returns:
        returns a csv filename to pull from google storage bucket.
    """
    command = ['gsutil','ls','gs://rooftop-data/properties_data/']
    out = subprocess.check_output(command)
    csv_list = str(out).split('\\n')
    parsed_csv_list = [x[x.find('data_')+5:-4] for x in csv_list]
    date_csv_list = [x for x in parsed_csv_list if len(x)==8]
    dates = [parser.parse(x) for x in date_csv_list]
    now = datetime.datetime.now()
    newest = max(dt for dt in dates if dt < now)
    csv_filename = 'data_{}.csv'.format(newest.strftime('%Y%m%d'))
    return csv_filename

def fetch_from_google_storage(google_storage_bucket, path_to_file, filename, destination_folder):
    """Pulls file from google cloud storage bucket

    Keyword arguments:
        google_storage_bucket: [string] name of google storage bucket e.g. django-uploads
        path_to_file: [string] path to the folder of the file you want to pull from
        google storage
        filename: [string] name of the file you want to pull e.g. data_<YYYYMMDD>.csv
        destination_folder: [string] path to the folder you want to save the pulled file in

    Returns:
    returns success status if successful
    """
    pull_path = 'gs://{}/{}/{}'.format(google_storage_bucket, path_to_file, filename)
    print('pull path is {}'.format(pull_path))
    destination_path = os.getcwd() + '/{}/{}'.format(destination_folder, filename)
    print('destination path is {}'.format(destination_path))
    gsutil_command = ['gsutil', 'cp', pull_path,destination_path]
    try:
        subprocess.call(gsutil_command)
        print('pulled file {} successfully from the {} google storage bucket'.format(filename,google_storage_bucket))
    except Exception as e:
        print('pull failed. error message: {}'.format(e))

def pull_last_run_date(pickle_path):
    """Pulls the last run date from a pickle file.

    Keyword arguments:
        pickle_path: [string] path to the pickle file that has the last_run_date

    Returns:
    last_run_date_str: [string] path to
    """
    pickle_path = os.path.join(os.getcwd(), pickle_path)
    last_run_date_file= open(pickle_path, 'rb')
    last_run_date = pickle.load(last_run_date_file)
    last_run_date_str = last_run_date.strftime('%Y%m%d')
    return last_run_date_str

def generate_csv_filename(last_run_date_str):
    """Generates name of csv file given a date

    Keyword arguments:
        last_run_date_str: [string] the last run date for the cron job, as a string

    Returns:
        csv_filename: [string] the filename for the csv file with the data stored in it
    """
    csv_filename = 'data_{}.csv'.format(last_run_date_str)
    return csv_filename

def create_property_object(df, idx):
    """Creates django property model object when given a dataframe of new
       listing data and index number

    Keyword arguments:
        df: [pandas dataframe object] dataframe object of home listing data
        idx: index in the dataframe of the house we are turning into a property object

    Returns:
        home: [django model] property object generated from the data in the row
        of the listing dataframe
    """
    home, created = ListProperty.objects.update_or_create(

            # Address
            street_address_1 = df.iloc[idx]['address_address_line1'],
            street_address_2 = df.iloc[idx]['address_unit'],
            city = df.iloc[idx]['address_city'],
            state = df.iloc[idx]['address_state'],
            zip_code = df.iloc[idx]['address_zipcode'],
            latitude = df.iloc[idx]['address_lat'],
            longitude = df.iloc[idx]['address_lon'],

            # Address keys
            hc_slug=df.iloc[idx]['Unnamed: 0'],
            lowercase_slug = df.iloc[idx]['Unnamed: 0'].lower(),

            # Listing data
            list_price = df.iloc[idx]['listing_data_list_price'],
            num_bedrooms = df.iloc[idx]['listing_data_num_bedrooms'],
            num_bathrooms = df.iloc[idx]['listing_data_num_bathrooms'],
            building_area_sq_ft = df.iloc[idx]['listing_data_building_area_sq_ft'],
            home_type = df.iloc[idx]['listing_data_home_type'],

            # Features
            num_floors = df.iloc[idx]['features_floors'],
            year_built = df.iloc[idx]['features_year_built'],
            listing_status = df.iloc[idx]['features_listing_status'],
            interior_features = df.iloc[idx]['features_interior_features'],
            flooring = df.iloc[idx]['features_flooring'],
            is_foreclosure = df.iloc[idx]['features_is_foreclosure'],
            local_school_quality = df.iloc[idx]['features_school_score'],
            remax_url = df.iloc[idx]['features_remax_url'],
            rx_num_half_bath = df.iloc[idx]['features_num_half_bath'],
            has_septic = df.iloc[idx]['features_has_septic'],
            has_pool = df.iloc[idx]['features_has_pool'],
            rx_date_listed = df.iloc[idx]['features_start_date_on_site'],
            subdivision = df.iloc[idx]['features_subdivision'],
            has_established_subdivision = df.iloc[idx]['features_has_established_subdivision'],
            has_well = df.iloc[idx]['features_has_well'],
            has_garage = df.iloc[idx]['features_has_garage'],
            no_pool_well_septic = df.iloc[idx]['features_no_pool_well_septic'],
            garage_size = df.iloc[idx]['features_garage_detail'],
            rx_num_full_bath = df.iloc[idx]['features_num_full_bath'],
            mls_listing_id = df.iloc[idx]['features_MLS'],
            description = df.iloc[idx]['features_desc'],

            # Images
            img_path_header = '/img/'+df.iloc[idx]['Unnamed: 0']+'/img1.jpg',
            img_paths_gallery = url_string_to_json(';'.join(['/img/' + df.iloc[idx]['Unnamed: 0'] + '/img'
                                     + str(x) + '.jpg' for x, y in enumerate(df.iloc[idx]
                                     ['images_img_gallery'].split(';'))]))
        )
    return home, created

def cleaned_dataframe_from_csv(csv_file_path):
    """Takes a csv, turns it into a dataframe, and cleans with ribbon buy box

    Keyword arguments:
        csv_file_path: [string] location of the csv dataframe

    Returns:
        cleaned_and_filtered_df: [pandas dataframe object] dataframe object
    """
    csv_path = os.path.join(os.getcwd(), csv_file_path)
    df = pd.read_csv(csv_path)
    df = df.where((pd.notnull(df)), None)
    df = df.drop_duplicates(subset='Unnamed: 0')
    cleaned_and_filtered_df = df[
        (df['listing_data_num_bathrooms']>=2)
        & (df['listing_data_num_bedrooms']>=3)
        & (df['listing_data_home_type']=='Single Family')
        & (df['listing_data_list_price']>=150000)
        & (df['listing_data_list_price']<=500000)
        & (df['features_year_built']>=1990)
        ]
    return cleaned_and_filtered_df

def iterate_through_properties_and_create_models(df):
    """Iterates through homes in a dataframe, creates a property object, and saves to db

    Keyword arguments:
        df: [django dataframe object] this is the cleaned and filtered dataframe of
        the houses

    Returns:
        There is no output but this simply loops through the dataframe, creates a property
        object of each home which is represented by a row in the dataframe, and then
        attempts to save the created property object to the database.

        If a property object with the same slug already exists in the dataframe,
        this will fail.
    """
    print('Loading list properties to db:')
    save_count = 0
    fail_count = 0
    for idx in range(len(df)):
        try:
            property_object, created = create_property_object(df, idx)
            save_count += created
        except Exception as e:
            fail_count += 1
            print('saving home failed, exception: {}'.format(e))
    print('saved: {} failed: {}  success_rate: {}%'.format(save_count,fail_count,
                                                            str(100*float(save_count/(save_count
                                                                      +fail_count)))))
def setup_environment():
    """Setup the environment"""
    sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "ribbonsemble.settings")
    application = get_wsgi_application()
    print('import properties...')

def check_currentdir_location():
    """Checks if you are running script from the correct directory (one with manage.py)

    Returns:
        True if you are current in current working directory, else raise exception
        and abort.
    """
    managepy_exists = os.path.isfile('manage.py')
    README_exists = os.path.isfile('README.md')
    if managepy_exists and README_exists:
        return True
    else:
        sys.exit('You must run this script from the main working directory (with manage.py)')

def url_string_to_json(url_string):
    """This take is string of urls and returns a JSON of image gallery paths

    Keyword arguments:
        url_string: [string] string of image gallery paths

    Returns:
        image_gallery_json: [JSON] a json of the image gallery paths
    """
    json_list = url_string.split(';')
    image_gallery_json = json.dumps(json_list)
    return image_gallery_json

if __name__ == '__main__':
    # Check current location
    check_currentdir_location()
    # Setup django environment.  Note must run from the rooftop
    setup_environment()
    # Need to import Property here and not at top of script because need env setup first.
    from hedonic_model.models import ListProperty
    # Get the name of the more recently updated csv file
    csv_filename = find_latest_csvname()
    # Pull csv from google cloud storage
    fetch_from_google_storage('rooftop-data','properties_data',csv_filename,
                              'scripts/csv_data')
    properties_df = cleaned_dataframe_from_csv('scripts/csv_data/{}'.format(csv_filename))
    iterate_through_properties_and_create_models(properties_df)


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

import random
import sys
import time

import mido

onames = mido.get_output_names()
fluid = list(filter(lambda x: 'FP-30' in x, onames))

if len(fluid) == 0:
    print("Fluid synth not started")
    sys.exit(1)

fport = mido.open_output(fluid[0])
print(f'Connected to {fluid[0]}')

int_names = [
        'Прима',            # 0
        'малка Секунда',    # 1
        'голяма Секунда',   # 2
        'малка Терца',      # 3
        'голяма Терца',     # 4
        'Кварта',           # 5
        'увеличена Кварта', # 6
        'Квинта',           # 7
        'малка Секста',     # 8
        'голяма Секста',    # 9
        'малка Септима',    # 10
        'голяма Септима',   # 11
        'Октава',     # 12
        ]

def play_notes(notes, delay=0, duration=1.0, arp=False):
    for note in notes:
        msg=mido.Message('note_on', note=note)
        fport.send(msg)
        time.sleep(delay)
        if arp:
            msg=mido.Message('note_off', note=note)
            fport.send(msg)
    if not arp:
        time.sleep(duration)
        for note in notes:
            msg=mido.Message('note_off', note=note)
            fport.send(msg)

def play_random_intervals(n=10, choice=list(range(13)), base=None):
    for _ in range(n):
        if base is None:
            base_note = 48 + random.randrange(25)  # C3 - C5
        else:
            case_note = base
        interval = random.choice(choice)
        resp = ''
        while resp == '':
            play_notes((base_note, base_note+interval), delay=1.0, arp=True)
            resp = input(f"Press Enter for repeat, or {choice}: ")
        try:
            resp = int(resp)
            if resp == interval:
                print(f"Correct: {int_names[interval]}")
            else:
                print(f"                 ******* Wrong: {int_names[interval]}, not {int_names[resp]}")
        except ValueError:
            break
        time.sleep(1)

def print_intervals():
    for i, n in enumerate(int_names):
        print(i, n)

if __name__ == '__main__':
    print_intervals()
    play_random_intervals(100,[3,4])


"""
<Implementation>
<BFS>
"""
from sys import *
from collections import deque

dx = [1, 0, -1, 0]
dy = [0, 1, 0, -1]

# INPUT
N, M = map(int, stdin.readline().rstrip().split())
BOARD = [list(stdin.readline().rstrip()) for _ in range(N)]
VISIT = [[[[False] * M for _ in range(N)] for _ in range(M)] for _ in range(N)]

def move(x, y, dx, dy):
    dd = 0
    while BOARD[x][y] != "O" and BOARD[x + dx][y + dy] != "#":
        x += dx
        y += dy
        dd += 1

    return x, y, dd

def bfs():
    QUEUE = deque()  # queue

    # Red, Blue
    for i in range(N):
        for j in range(M):
            if BOARD[i][j] == "R":
                rx, ry = i, j
            elif BOARD[i][j] == "B":
                bx, by = i, j

    # start
    QUEUE.append([rx, ry, bx, by, 1])
    VISIT[rx][ry][bx][by] = True

    # BFS
    while QUEUE:
        rx, ry, bx, by, d = QUEUE.popleft()

        if d > 10:
            return -1
        for i in range(4):
            nrx, nry, rd = move(rx, ry, dx[i], dy[i])
            nbx, nby, bd = move(bx, by, dx[i], dy[i])

            if BOARD[nbx][nby] != "O":
                if BOARD[nrx][nry] == "O":
                    return d

                if nrx == nbx and nry == nby:
                    if rd > bd:
                        nrx -= dx[i]
                        nry -= dy[i]
                    else:
                        nbx -= dx[i]
                        nby -= dy[i]

                if not VISIT[nrx][nry][nbx][nby]:
                    VISIT[nrx][nry][nbx][nby] = True
                    QUEUE.append([nrx, nry, nbx, nby, d + 1])
    return -1

print(bfs())


from flask import Flask, render_template, request, session
import datetime
from flask_session import Session

# set FLASK_APP=application.py
app = Flask(__name__)

@app.route("/")
def index():
    headline = "Nazgulz rock!"
    return render_template("index.html", headline=headline)

@app.route("/hello", methods=["GET", "POST"])
def hello():
    if request.method == "GET":
        return "You should submit the post to get here"
    else:
        name = request.form.get("name")
        return render_template("hello.html", jname=name)

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

notes_list = []

@app.route("/notes", methods=["GET", "POST"])
def notes():
    if request.method == "POST":
        note = request.form.get("note")
        notes_list.append(note)
    return render_template("notes.html", notes=notes_list)

app.config["SESSION_PERMANENT"] = False
app.config["SESSION_TYPE"] = "filesystem"
Session(app)

@app.route("/session_notes_", methods=["GET", "POST"])
def session_notes_():
    if session.get("notes") is None:
        session["notes"] = []
    if request.method == "POST":
        note = request.form.get("note")
        session["notes"].append(note)
    return render_template("session_notes_.html", notes=session["notes"])

@app.route("/names")
def forloop():
    names = ["Alice", "Józsibácsi", "Nazgul"]
    return render_template("forloop.html", names=names)

@app.route("/new")
def n_y():
    now = datetime.datetime.now()
    new_year = now.month == 1 and now.day == 1
    #new_year = True
    return render_template("newyear.html", new_year=new_year, date_=str(now))

@app.route("/KZ")
def zottya():
    return "
Hello, MelaKZ!!!
"

@app.route("/<string:name>")
def valami(shhhh):
    return f"Hello, {shhhh}!"


from django.db.models.query import QuerySet
from django.shortcuts import render
from rest_framework import generics, serializers
from Base.models import Post, Response
from Base.serializers import GetQuestionsSerializer
from Base.models import Question
from Base.models import Category
from Base.serializers import GetPostsSerializer
from Base.models import SubscribedPosts
from Base.serializers import SubscribedPostSerializer
from Base.serializers import ResponseSerializer
from Base.serializers import FinalResponseSerializer
from Base.models import FinalResponse

class QuestionList(generics.ListCreateAPIView):
   # queryset=Question.objects.all()
    # ssociatedPost
    serializer_class = GetQuestionsSerializer

    def get_queryset(self):
        PostId = self.kwargs['AssociatedPost']
        return Question.objects.filter(AssociatedPost=PostId)

class PostByCategory(generics.ListAPIView):

    serializer_class = GetPostsSerializer

    def get_queryset(self):
        CategoryId = self.kwargs['Category']
        return Post.objects.filter(category=CategoryId,isPublished=False)

class SinglePost(generics.RetrieveUpdateAPIView):
    queryset = Post.objects.all()
    serializer_class = GetPostsSerializer

class AllPosts(generics.ListAPIView):
    queryset = Post.objects.all()
    serializer_class = GetPostsSerializer

class PostListByUser(generics.ListAPIView):
    serializer_class = GetPostsSerializer

    def get_queryset(self):

        userId = self.request.user.id
        # print(userId)
       # print('BUN', userId)
        return Post.objects.filter(author=userId)

class SubscribedPostsByUser(generics.ListAPIView):
    serializer_class = SubscribedPostSerializer

    def get_queryset(self):

        userId = self.request.user.id
        # print(userId)
        #print('BUN', userId)
        return SubscribedPosts.objects.filter(User=userId)

class AddPost(generics.CreateAPIView):
    serializer_class = GetPostsSerializer

class AddSubscription(generics.CreateAPIView):
    serializer_class = SubscribedPostSerializer

class getSubscriptions(generics.ListAPIView):
    serializer_class = SubscribedPostSerializer

    def get_queryset(self):
        PostId = self.kwargs['PostId']
        return SubscribedPosts.objects.filter(AssociatedPost=PostId)

class getAproovedSubscriptions(generics.ListAPIView):
    serializer_class = SubscribedPostSerializer

    def get_queryset(self):
        #PostId = self.kwargs['PostId']
        UserId=self.request.user.id
        return SubscribedPosts.objects.filter( isAprooved=True,User=UserId)

class getSingleSubscription(generics.RetrieveUpdateAPIView):
    queryset = SubscribedPosts.objects.all()

    serializer_class = SubscribedPostSerializer

class PostResponses(generics.ListCreateAPIView):
    queryset = Response.objects.all()
    serializer_class = ResponseSerializer

class PostFinalResponse(generics.ListCreateAPIView):
    queryset = FinalResponse.objects.all()
    serializer_class = FinalResponseSerializer

class FinalResponseByPost(generics.ListCreateAPIView):
    #queryset = FinalResponse.objects.all()
    serializer_class = FinalResponseSerializer
    def get_queryset(self):
        PostId=self.kwargs['AssociatedPost']
        return FinalResponse.objects.filter(AssociatedPost=PostId)

class MyFinalAnswers(generics.ListAPIView):
    serializer_class = FinalResponseSerializer

    def get_queryset(self):
        return FinalResponse.objects.filter(User=self.request.user.id)

class AnswerByQuestion(generics.ListAPIView):
    serializer_class = ResponseSerializer

    def get_queryset(self):
        QuestionId = self.kwargs['questionId']
        return Response.objects.filter(question=QuestionId)


import pytest
import allure
import logging
from util.assert_util import assert_keyword
from util.request_util import api_request
from util.global_var import *
from util.excel_util import excel_util

register_test_data = excel_util.get_sheet_data("注册")
login_test_data = excel_util.get_sheet_data("登录")

@allure.feature("登录模块")
@pytest.mark.dependency(name="TestLoginModule")
class TestLoginModule:

    @allure.story("注册功能")
    @allure.title('用户注册')  # 指定测试用例标题，默认是函数名
    @allure.description('通过接口进行用户注册')  # 添加测试用例描述
    @allure.severity(allure.severity_level.BLOCKER)  # 阻塞级别
    @pytest.mark.run(order=1)
    @pytest.mark.parametrize('case_data', register_test_data)
    def test_register(self, case_data):
        with allure.step("读取请求数据，调用接口"):
            logging.info("接口用例数据：%s" % case_data)
            response = api_request(case_data[API_IP], case_data[API_URI], case_data[REQUEST_METHOD],
                                   case_data[API_REQUEST_DATA], case_data[RESPONSE_EXTRACT_VAR],
                                   case_data[REQUEST_HEADER], case_data[REQUEST_COOKIE])
        with allure.step("获取响应数据，进行断言"):
            assert_keyword(response, case_data[RESPONSE_ASSERT_KEYWORD])

    @allure.story("登录功能")
    @allure.title('用户登录')  # 指定测试用例标题，默认是函数名
    @allure.description('通过接口进行用户登录')  # 添加测试用例描述
    @allure.severity(allure.severity_level.BLOCKER)  # 阻塞级别
    @pytest.mark.run(order=2)
    @pytest.mark.parametrize('case_data', login_test_data)
    def test_login(self, case_data):
        with allure.step("读取请求数据，调用接口"):
            logging.info("接口用例数据：%s" % case_data)
            response = api_request(case_data[API_IP], case_data[API_URI], case_data[REQUEST_METHOD],
                                   case_data[API_REQUEST_DATA], case_data[RESPONSE_EXTRACT_VAR],
                                   case_data[REQUEST_HEADER], case_data[REQUEST_COOKIE])
        with allure.step("获取响应数据，进行断言"):
            assert_keyword(response, case_data[RESPONSE_ASSERT_KEYWORD])

if __name__ == "__main__":
    test_dir = os.path.dirname(__file__)
    pytest.main(['-s', '-q', test_dir, '--alluredir', '../test_result/', "--clean-alluredir"])
    os.system('allure generate ../test_result/ -o ../test_report/ --clean')
    os.system('allure open -h 127.0.0.1 -p 8881 ../test_report/')


# views handling halaman dashboard admin
import pandas as pd
import pathlib

from flask import Blueprint, render_template, redirect, url_for, request, flash
from flask_login import login_required, current_user

from .models import User, Kecamatan, Rumah, Agen, FixedBunga, GambarRumah
from .handle_image_upload import upload_image, delete_image
from .handle_dataset_upload import (
    upload_dataset,
    delete_dataset,
    input_dataset_to_database,
)
from . import db

admin_views = Blueprint("admin_views", __name__)

######################################
# functions
######################################

# fungsi untuk mengecek apakah user adalah admin atau tidak
def check_admin():
    user_object = User.query.get(current_user.get_id())
    return user_object.is_admin

######################################

#
#
# API untuk handle admin dashboard, query jumlah rumah, kecamatan, user
# untuk di tampilkan di halaman dashboard admin
@admin_views.route("/admin_dashboard", methods=["GET"])
@login_required
def admin_dashboard():
    if not check_admin():
        return redirect(url_for("public_views_loggedin.profile_page"))

    count_rumah = Rumah.query.count()
    count_kecamatan = Kecamatan.query.count()
    count_user = User.query.count()
    admin_user = User.query.get(current_user.get_id())
    fixed_bunga = FixedBunga.query.get(1)

    return render_template(
        "admin/dashboard.html",
        admin_user=admin_user,
        count_rumah=count_rumah,
        count_kecamatan=count_kecamatan,
        count_user=count_user,
        fixed_bunga=fixed_bunga,
    )

# handle editing fixed bunga ke dalam database
@admin_views.route("/handle_edit_bunga", methods=["POST"])
@login_required
def handle_edit_bunga():
    if not check_admin():
        return redirect(url_for("public_views_loggedin.profile_page"))

    fixed_bunga = request.form.get("fixed_bunga")

    to_edit_bunga = FixedBunga.query.get(1)

    if to_edit_bunga:
        to_edit_bunga.fixed_bunga = fixed_bunga
        db.session.commit()
        flash(
            f"berhasil mengedit fixed bunga menjadi {to_edit_bunga.fixed_bunga}",
            category="success",
        )
        return redirect("/admin_dashboard")

    flash(f"gagal mengedit fixed bunga")
    return redirect("/admin_dashboard")

#
#
# API untuk handle halaman kecamatan pada admin dashboard
# query semua kecamatan dalam database dan ditampilkan pada
# dahsboard admin
@admin_views.route("/admin_kecamatan", methods=["GEt"])
@login_required
def admin_kecamatan():
    if not check_admin():
        return redirect(url_for("public_views_loggedin.profile_page"))

    all_kecamatan = Kecamatan.query.all()

    return render_template("admin/kecamatan.html", all_kecamatan=all_kecamatan)

# menampilkan halaman penambahan kecamatan pada dashboard admin
@admin_views.route("/tambah_kecamatan", methods=["GET"])
@login_required
def tambah_kecamatan():
    if not check_admin():
        return redirect(url_for("public_views_loggedin.profile_page"))

    return render_template("admin/tambah-kecamatan.html")

# handle penambahan kecamatan pada halaman tambah kecamatan
@admin_views.route("/handle_tambah_kecamatan", methods=["POST"])
@login_required
def handle_tambah_kecamatan():
    if not check_admin():
        return redirect(url_for("public_views_loggedin.profile_page"))

    kecamatan = request.form.get("kecamatan")

    to_add_kecamatan = Kecamatan(nama_kecamatan=kecamatan)
    db.session.add(to_add_kecamatan)
    db.session.commit()

    flash(f"Berhasil menambah kecamatan {kecamatan}", category="success")
    return redirect("/tambah_kecamatan")

# menampilkan halaman edit kecamatan pada admin dashboard
@admin_views.route("/edit_kecamatan/<int:id>", methods=["GET"])
@login_required
def edit_kecamatan(id):
    if not check_admin():
        return redirect(url_for("public_views_loggedin.profile_page"))

    to_edit_kecamatan = Kecamatan.query.get(id)

    return render_template(
        "admin/edit-kecamatan.html", to_edit_kecamatan=to_edit_kecamatan
    )

# handle edit kecamatan pada halaman edit kecamatan
@admin_views.route("/handle_edit_kecamatan/<int:id>", methods=["POST"])
@login_required
def handle_edit_kecamatan(id):
    if not check_admin():
        return redirect(url_for("public_views_loggedin.profile_page"))

    to_edit_kecamatan = Kecamatan.query.get(id)

    nama_kecamatan_baru = request.form.get("kecamatan")

    if to_edit_kecamatan:
        to_edit_kecamatan.nama_kecamatan = nama_kecamatan_baru
        db.session.commit()
        flash(
            f"berhasil mengedit data kecamatan {to_edit_kecamatan.nama_kecamatan}",
            category="success",
        )
        return redirect(f"/edit_kecamatan/{id}")

    flash(
        f"gagal mengedit data kecamatan {to_edit_kecamatan.nama_kecamatan}",
        category="error",
    )
    return redirect(f"/edit_kecamatan/{id}")

# handle penghapusan data kecamatan melalui admin dashboard
@admin_views.route("/delete_kecamatan/<int:id>", methods=["POST"])
def delete_kecamatan(id):
    to_delete_kecamatan = Kecamatan.query.get(id)
    if to_delete_kecamatan:
        flash(
            f"berhasil menghapus data kecamatan {to_delete_kecamatan.nama_kecamatan}",
            category="warning",
        )
        db.session.delete(to_delete_kecamatan)
        db.session.commit()
        return redirect("/admin_kecamatan")

    flash(
        f"gagal menghapus data kecamtan {to_delete_kecamatan.nama_kecamatan}",
        category="error",
    )
    return redirect("/admin_kecamatan")

#
#
# API untuk handle admin rumah
# mengqueru semua rumah dan ditampilkan di halaman dashboard admin
# pada menu rumah
@admin_views.route("/admin_rumah", methods=["GET"])
@login_required
def admin_rumah():
    if not check_admin():
        return redirect(url_for("admin_views_loggedin.profile_page"))

    all_rumah = Rumah.query.all()

    return render_template("admin/rumah.html", all_rumah=all_rumah)

# menampilkan halaman tambah rumah pada dashboard admin
@admin_views.route("/tambah_rumah", methods=["GET"])
@login_required
def tambah_rumah():
    if not check_admin():
        return redirect(url_for("public_views_loggedin.profile_page"))

    all_rumah = Rumah.query.all()
    all_agen = Agen.query.all()
    all_kecamatan = Kecamatan.query.all()

    return render_template(
        "admin/tambah-rumah.html",
        all_rumah=all_rumah,
        all_agen=all_agen,
        all_kecamatan=all_kecamatan,
    )

# handle penambahan rummah pada dashboard admin
@admin_views.route("/handle_tambah_rumah", methods=["POST"])
@login_required
def handle_tambah_rumah():
    if not check_admin():
        return redirect(url_for("public_views_loggedin.profile_page"))

    nama_perumahan = request.form.get("nama_perumahan")
    alamat = request.form.get("alamat")
    kecamatan = request.form.get("kecamatan")
    luas = request.form.get("luas")
    harga = request.form.get("harga")
    lantai = request.form.get("lantai")
    kamar_tidur = request.form.get("kamar_tidur")
    kamar_mandi = request.form.get("kamar_mandi")

    get_kontak_agen = request.form.get("kontak_agen").split(",")
    kontak_agen = get_kontak_agen[0]
    kontak_agen_id = int(get_kontak_agen[1])

    data_agen = Agen.query.get(kontak_agen_id)
    agen_nomor_telepon = data_agen.nomor_telepon
    agen_email = data_agen.email
    agen_whatsapp = data_agen.whatsapp

    latitude = request.form.get("latitude")
    longitude = request.form.get("longitude")
    deskripsi = request.form.get("deskripsi")
    gambar = request.files["gambar-rumah"]
    fasilitas = request.values.getlist("fasilitas")

    if gambar:
        if gambar == "":
            flash("Gambar Kosong", category="error")
            return redirect("/tambah_rumah")

        nama_file_gambar = upload_image(gambar, None)

    to_add_rumah = Rumah(
        nama_perumahan=nama_perumahan,
        alamat=alamat,
        kecamatan=kecamatan,
        luas=luas,
        harga=harga,
        lantai=lantai,
        kamar_tidur=kamar_tidur,
        kamar_mandi=kamar_mandi,
        kontak_agen=kontak_agen,
        kontak_agen_id=kontak_agen_id,
        agen_nomor_telepon=agen_nomor_telepon,
        agen_email=agen_email,
        agen_whatsapp=agen_whatsapp,
        latitude=latitude,
        longitude=longitude,
        deskripsi=deskripsi,
        fasilitas=", ".join(fasilitas),
    )
    db.session.add(to_add_rumah)
    db.session.commit()

    to_add_gambar = GambarRumah(
        nama_gambar=nama_file_gambar,
        rumah=Rumah.query.filter(Rumah.alamat == alamat).first().id,
    )
    db.session.add(to_add_gambar)
    db.session.commit()

    flash(f"Rumah {alamat} berhasil ditambah", category="success")
    return redirect("/tambah_rumah")

@admin_views.route("/handle_tambah_rumah_upload_dataset", methods=["POST"])
def handle_tambah_rumah_upload_dataset():
    dataset_file = request.files["dataset-rumah"]

    dataset_is_uploaded, message = upload_dataset(dataset_file)

    if dataset_is_uploaded:
        flash(message, category="success")
        input_dataset_to_database(dataset_file)
        return redirect("/admin_rumah")

    flash(message, category="error")
    return redirect("/admin_rumah")

# menampilkan halaman edit rumah pada dashboard admin
@admin_views.route("/edit_rumah/<int:id>", methods=["GET"])
@login_required
def edit_rumah(id):
    if not check_admin():
        return redirect(url_for("public_views_loggedin.profile_page"))

    to_edit_rumah = Rumah.query.get(id)
    all_agen = Agen.query.all()
    all_kecamatan = Kecamatan.query.all()

    return render_template(
        "admin/edit-rumah.html",
        to_edit_rumah=to_edit_rumah,
        all_agen=all_agen,
        all_kecamatan=all_kecamatan,
    )

# handle pengeditan data rummah pada dashboard admin
@admin_views.route("/handle_edit_rumah/<int:id>", methods=["POST"])
@login_required
def handle_edit_rumah(id):
    if not check_admin():
        return redirect(url_for("public_views_loggedin.profile_page"))

    to_edit_rumah = Rumah.query.get(id)

    nama_perumahan = request.form.get("nama_perumahan")
    alamat = request.form.get("alamat")
    kecamatan = request.form.get("kecamatan")
    luas = request.form.get("luas")
    harga = request.form.get("harga")
    lantai = request.form.get("lantai")
    kamar_tidur = request.form.get("kamar_tidur")
    kamar_mandi = request.form.get("kamar_mandi")
    kontak_agen = request.form.get("kontak_agen")
    latitude = request.form.get("latitude")
    longitude = request.form.get("longitude")
    deskripsi = request.form.get("deskripsi")
    fasilitas = request.values.getlist("fasilitas")

    if to_edit_rumah:
        to_edit_rumah.nama_perumahan = nama_perumahan
        to_edit_rumah.alamat = alamat
        to_edit_rumah.kecamatan = kecamatan
        to_edit_rumah.luas = luas
        to_edit_rumah.harga = harga
        to_edit_rumah.lantai = lantai
        to_edit_rumah.kamar_tidur = kamar_tidur
        to_edit_rumah.kamar_mandi = kamar_mandi
        to_edit_rumah.kontak_agen = kontak_agen
        to_edit_rumah.latitude = latitude
        to_edit_rumah.longitude = longitude
        to_edit_rumah.gambar = to_edit_rumah.gambar
        to_edit_rumah.deskripsi = deskripsi
        to_edit_rumah.fasilitas = ", ".join(fasilitas)
        db.session.commit()
        flash(
            f"berhasil mengedit data rumah {to_edit_rumah.alamat}", category="warning"
        )
        return redirect(f"/edit_rumah/{id}")

    flash(f"gagal mengedit data rumah {to_edit_rumah.alamat}", category="error")
    return redirect(f"/edit_rumah/{id}")

@admin_views.route("/handle_tambah_gambar_rumah/<int:id>", methods=["POST"])
def handle_tambah_gambar_rumah(id):
    gambar = request.files["gambar-rumah"]

    nama_file_gambar = upload_image(gambar, None)
    to_add_gambar = GambarRumah(
        nama_gambar=nama_file_gambar,
        rumah=id,
    )
    db.session.add(to_add_gambar)
    db.session.commit()

    flash("Berhasil menambah gambar rumah")
    return redirect(f"/edit_rumah/{id}")

@admin_views.route("/handle_hapus_gambar_rumah/<int:id>", methods=["POST"])
def handle_hapus_gambar_rumah(id):
    id_gambar = int(request.form.get("id-gambar"))
    to_edit_rumah = Rumah.query.get(id)

    print(id_gambar)

    for gambar in to_edit_rumah.gambar:
        print(gambar.id, id_gambar)
        if gambar.id == id_gambar:
            to_delete_gambar = GambarRumah.query.get(gambar.id)
            print(f"{gambar.id} == {id_gambar}")
            flash(f"Berhasil menghapus gambar {gambar.nama_gambar}")
            delete_image(gambar.nama_gambar)
            db.session.delete(to_delete_gambar)
            db.session.commit()

    return redirect(f"/edit_rumah/{id}")

# handle penghapusan rumah pada dashboard admin
@admin_views.route("/delete_rumah/<int:id>", methods=["POST"])
@login_required
def delete_rumah(id):
    if not check_admin():
        return redirect(url_for("public_views_loggedin.profile_page"))

    to_delete_rumah = Rumah.query.get(id)

    if to_delete_rumah:
        for gambar in to_delete_rumah.gambar:
            delete_image(gambar.nama_gambar)

        flash(
            f"berhasil menghapus data rumah {to_delete_rumah.alamat}",
            category="warning",
        )
        db.session.delete(to_delete_rumah)
        db.session.commit()
        return redirect("/admin_rumah")

    flash(f"gagal menghapus data rumah {to_delete_rumah.alamat}", category="error")
    return redirect("/admin_rumah")

#
#
# API untuk handle kontak agen
# query semua data agen untuk di tampilkan pada halaman
# dashboard admin pada menu rumah
@admin_views.route("/admin_kontak_agen", methods=["GET"])
@login_required
def admin_kontak_agen():
    if not check_admin():
        return redirect(url_for("public_views_loggedin.profile_page"))

    all_agen = Agen.query.all()

    return render_template("admin/kontak-agen.html", all_agen=all_agen)

# menampilkan halaman penambahan admin pada admin dashboard
@admin_views.route("/tambah_agen", methods=["GET"])
@login_required
def tambah_agen():
    if not check_admin():
        return redirect(url_for("public_views_loggedin.profile_page"))

    return render_template("admin/tambah-agen.html")

# handle penambahan agen pada dashboard admin
@admin_views.route("/handle_tambah_agen", methods=["POST"])
@login_required
def handle_tambah_agen():
    if not check_admin():
        return redirect(url_for("public_views_loggedin.profile_page"))

    nama = request.form.get("nama_agen")
    nomor_telepon = request.form.get("nomor_telepon")
    email_agen = request.form.get("email")
    whatsapp_agen = request.form.get("whatsapp")

    to_add_agen = Agen(
        nama_agen=nama,
        nomor_telepon=nomor_telepon,
        email=email_agen,
        whatsapp=whatsapp_agen,
    )
    db.session.add(to_add_agen)
    db.session.commit()

    flash(f"Berhasil menambahkan agen {nama}")
    return redirect("/tambah_agen")

# menampilkan halaman edit agen pada dashboard admin
@admin_views.route("/edit_agen/<int:id>", methods=["GET"])
@login_required
def edit_agen(id):
    if not check_admin():
        return redirect(url_for("public_views_loggedin.profile_page"))

    to_edit_agen = Agen.query.get(id)

    return render_template("admin/edit-agen.html", to_edit_agen=to_edit_agen)

# handle pengeditan data agen pada dashboard admin
@admin_views.route("/handle_edit_agen/<int:id>", methods=["POST"])
@login_required
def handle_edit_agen(id):
    if not check_admin():
        return redirect(url_for("public_views_loggedin.profile_page"))

    to_edit_agen = Agen.query.get(id)

    nama_agen = request.form.get("nama_agen")
    nomor_telepon = request.form.get("nomor_telepon")
    email = request.form.get("email")
    whatsapp = request.form.get("whatsapp")

    if to_edit_agen:
        to_edit_agen.nama_agen = nama_agen
        to_edit_agen.nomor_telepon = nomor_telepon
        to_edit_agen.email = email
        to_edit_agen.whatsapp = whatsapp
        db.session.commit()

        flash(
            f"berhasil mengedit data agen {to_edit_agen.nama_agen}", category="warning"
        )
        return redirect(f"/edit_agen/{id}")

    flash(f"gagal mengedit data agen {to_edit_agen.nama_agen}", category="error")
    return redirect("/admin_agen")

# handle penghapusan data agen pada halaman dashboard admin
@admin_views.route("/delete_agen/<int:id>", methods=["POST"])
@login_required
def delete_agen(id):
    if not check_admin():
        return redirect(url_for("public_views_loggedin.profile_page"))

    to_delete_agen = Agen.query.get(id)
    if to_delete_agen:
        flash(
            f"berhasil menghapus data agen {to_delete_agen.nama_agen}",
            category="warning",
        )
        db.session.delete(to_delete_agen)
        db.session.commit()
        return redirect("/admin_kontak_agen")

    flash(f"gagal menghapus data agen {to_delete_agen.nama_agen}", category="error")
    return redirect("/admin_kontak_agen")

#
#
# API untuk handle admin user
@admin_views.route("/admin_user", methods=["GET"])
@login_required
def admin_user():
    if not check_admin():
        return redirect(url_for("public_views_loggedin.profile_page"))

    non_admin_user = User.query.filter(User.is_admin == False)

    return render_template("admin/user.html", non_admin_user=non_admin_user)

# untuk menampilkan halaman edit user pada dashboard admin
@admin_views.route("/edit_user/<int:id>", methods=["GET"])
@login_required
def edit_user(id):
    if not check_admin():
        return redirect(url_for("public_views_loggedin.profile_page"))

    to_edit_user = User.query.get(id)

    return render_template("admin/edit-user.html", to_edit_user=to_edit_user)

# handle pengeditan data user pada dashboard admin
@admin_views.route("/handle_edit_user/<int:id>", methods=["POST"])
@login_required
def handle_edit_user(id):
    if not check_admin():
        return redirect(url_for("public_views_loggedin.profile_page"))

    to_edit_user = User.query.get(id)

    nama_lengkap = request.form.get("nama_lengkap")
    email = request.form.get("email")
    range_gaji = request.form.get("range_gaji")

    if to_edit_user:
        to_edit_user.nama_lengkap = nama_lengkap
        to_edit_user.email = email
        to_edit_user.range_gaji = range_gaji
        db.session.commit()
        flash(
            f"berhasil edit data user {to_edit_user.nama_lengkap}", category="success"
        )
        return redirect(f"/edit_user/{id}")

    flash(f"gagal edit data user {to_edit_user.nama_lengkap}", category="error")
    return redirect(f"/edit_user/{id}")

# handle penghapusan user pada halaman dashboard admin
@admin_views.route("/delete_user/<int:id>", methods=["POST"])
@login_required
def delete_user(id):
    if not check_admin():
        return redirect(url_for("public_views_loggedin.profile_page"))

    to_delete_user = User.query.get(id)

    if to_delete_user:
        flash(
            f"berhasil delete data user {to_delete_user.nama_lengkap}",
            category="success",
        )
        db.session.delete(to_delete_user)
        db.session.commit()
        return redirect("/admin_user")

    flash(f"gagal delete data user {to_delete_user.nama_lengkap}", category="error")
    return redirect("/admin_user")


"""
Environment

"""
# numpy
import numpy as np
# pytorch
import torch as T
# misc
import pdb # use with set_trace() for the debugger

class CliffEnv():
    # constructor
    def __init__(self, params):
        # parameters and spaces
        self.params = params
        self.spaces = {'t_space' : np.arange(params["T"]),
                      'pos_space' : np.linspace(-1, 12, 51),
                      'u_space' : np.linspace(-params["max_u"], params["max_u"], 41)}
        self.device = T.device('cuda:0' if T.cuda.is_available() else 'cpu')

    # initialization of the environment with its true initial state
    def reset(self, Nsims=1):
        pos = T.zeros(Nsims)

        return pos

    # initialization of the environment with multiple random states
    def random_reset(self, time, Nsims=1):
        temp = time*(time <= self.params["T"]/2) + self.params["T"]/2*(time > self.params["T"]/2)
        pos = temp*(self.params["max_u"]+2.3*self.params["sigma"])*T.rand(Nsims, device=self.device)

        return pos

    # simulation engine
    def step(self, pos_t, time_t, u_t):
        sizes = pos_t.shape

        pos_tp1 = pos_t + u_t
        time_tp1 = time_t + 1

        r = - self.params["C_time"]*T.ones(sizes) \
            - self.params["C_cliff"]*((pos_tp1 < self.params["cliff"]) & (time_tp1 != self.params["T"]-1)) \
            - self.params["C_move"](u_t)

        return pos_tp1, time_tp1, -r

    # terminal penalty on the inventory
    def get_final_cost(self, pos_T):
        r = -self.params["C_terminal"](pos_T)

        return -r


"""
多头版的 GeneralMemoryBank
"""
import torch
from torch import nn

from finedial.modules.memory_bank.GeneralMemoryBank import GeneralMemoryBankAgent

class MultiHeadGeneralMemoryBankAgent(nn.Module):
    memory_bank: object
    memory_bank_length: object
    memory_bank_value: object

    def __init__(self, agent_name, attn_params, attn_input_param, head_names, placeholder_mode):
        num_heads = len(head_names)
        assert num_heads > 1, 'head number must larger than 1'
        super(MultiHeadGeneralMemoryBankAgent, self).__init__()
        heads = [GeneralMemoryBankAgent(agent_name+'_'+head_name, attn_params, attn_input_param, placeholder_mode)
                 for head_name in head_names]
        self.heads = nn.ModuleDict()
        self.copy_mode = False
        self.placeholder_mode = False
        for head_name, head in zip(head_names, heads):
            self.heads[head_name] = head
            self.copy_mode = head.copy_mode
            self.placeholder_mode = head.placeholder_mode

    def init_memory_bank(self, memory_bank, memory_bank_value, memory_bank_length, time_major=False):
        for head_name in self.heads:
            head = self.heads[head_name]
            head.init_memory_bank(memory_bank, memory_bank_value, memory_bank_length, time_major)

    def create_beams(self, beam_width):
        for head_name in self.heads:
            head = self.heads[head_name]
            head.create_beams(beam_width)

    def get_output_dim(self):
        """
        Attention的输出维度
        """
        res = 0
        for head_name in self.heads:
            head = self.heads[head_name]
            res += head.get_output_dim()
        return res

    def get_gen_mode_name(self):
        """
        当前的Memory是否可以进行拷贝
        """
        res = []
        for head_name in self.heads:
            head = self.heads[head_name]
            res += head.get_gen_mode_name()
        return res

    def get_gen_mode_num(self):
        """
        当前的Memory是否可以进行拷贝
        """
        res = 0
        for head_name in self.heads:
            head = self.heads[head_name]
            res += head.get_gen_mode_num()
        return res

    def access(self, query, output_distribution=False):
        """
            Args:
                query : [batch, query_dim]
                output_distribution :
            Returns:
                attention_vector:
        """
        res = []
        distributions = []
        for head_name in self.heads:
            head = self.heads[head_name]
            if output_distribution:
                tmp = head.access(query, output_distribution)
                res.append(tmp[0])
                distributions.append(tmp[1])
            else:
                res.append(head.access(query))

        if output_distribution:
            return torch.cat(res, -1), distributions
        else:
            return torch.cat(res, -1)

    def generate(self, query, pad_to_max=True):
        res = []
        for head_name in self.heads:
            head = self.heads[head_name]
            res.append(head.generate(query, pad_to_max))
        return res

    def create_vocab_predictor(self, input_size, hidden_size, fixed_vocab_size, dropout, vocab_predictor_mode):
        for head in self.heads.values():
            head.create_vocab_predictor(input_size, hidden_size, fixed_vocab_size, dropout, vocab_predictor_mode)

    def generate_vocab(self, query, state, dynamic_projections=None, pad_to_max=True):
        res = []
        for head in self.heads.values():
            tmp = head.generate_vocab(query, state, dynamic_projections, pad_to_max)
            res += tmp
        return res


import os

from ogb.nodeproppred import PygNodePropPredDataset, Evaluator

import torch
import torch_geometric.transforms as T

from .get_graph_partitions import get_graph_partitions, get_train_node_per_part, neighbor_approx
from .get_label_partitions import get_label_partitions

def load_dataset(dataset_name, num_parts,
                 partition_method=0):
    # load OGB dataset
    dataset = PygNodePropPredDataset(name      = dataset_name,
                                     transform = T.ToSparseTensor())
    data      = dataset[0]
    split_idx = dataset.get_idx_split()

    # Create local partitions
    if partition_method == 0 or 2: # use metis based on graph structure
        print('Partition with metis based on graph structure')
        parts = get_graph_partitions(dataset      = dataset_name,
                                     num_clusters = num_parts,
                                     data = data,
                                     root = os.getcwd())
    elif partition_method == 1: # use label heterogeneous
        print('Partition based on label heterogeneous')
        parts = get_label_partitions(dataset      = dataset_name,
                                     num_clusters = num_parts,
                                     data = data,
                                     root = os.getcwd())
    else:
        print('Unknown partition method')

    train_parts = get_train_node_per_part(num_nodes   = data.x.size(0),
                                          train_nodes = split_idx['train'].numpy(),
                                          parts       = parts)
    if partition_method == 2:
        # convert PyG data structure to scipy's sparse_coo for metis partition
        import numpy as np
        from scipy.sparse import csr_matrix

        row = data.adj_t.storage.row().numpy()
        col = data.adj_t.storage.col().numpy()
        num_nodes = data.adj_t.size(0)

        all_nodes = np.arange(num_nodes)
        sparse_coo_adj = csr_matrix((np.ones_like(row), (row, col)), shape=(num_nodes, num_nodes))

        parts_with_approx = [neighbor_approx(sparse_coo_adj, part) for part in parts]

        data.parts = [torch.tensor(part) for part in parts_with_approx]
    else:
        data.parts = [torch.tensor(part) for part in parts]
    data.train_parts = [torch.tensor(part) for part in train_parts]

    # add eval
    evaluator = Evaluator(name=dataset_name)

    return dataset, data, split_idx, evaluator

def sparse_tensor_to_edge_indices(adj):
    row = adj.storage.row()
    col = adj.storage.col()
    return torch.stack([row, col])


from sklearn.model_selection import train_test_split
import pandas as pd
import os
import numpy as np

# ===================================================================== #
# ========================  Combine Data ======================== #
# ===================================================================== #

# NOTE: The reason that I am using pandas even thought is not necessrary,
# I would like to improve my skill on pandas.

def get_dir_names(FLAGS):
    """Obtain directory names where data are saved.
    Returns:
       List of folders names
    """
    folders = []
    root_dir, dirs, files = next(os.walk('./data'))
    for name in dirs:
        folders.append(os.path.join(root_dir, name))

    folders = np.array(folders)
    folders_include = FLAGS.folders_include.split(',')
    # add the root to the names of the folders
    folders_include = np.core.defchararray.add(root_dir + '/',folders_include)
    return  np.extract(np.isin(folders , folders_include),folders)

def combine_data(folders,rec_data=False):
    """combine all driving logs files into one.
    Arguments:
        folders: List of folders names
    Returns:
       Path of the new driving log file.
    """
    driving_log_file = "./data/combine_driving_log.csv"
    if rec_data:
        list_ = []
        headers = ['center', 'left', 'right',
                   'steering', 'throttle', 'break', 'speed']
        for folder in folders:
            df = pd.read_csv(folder + "/driving_log.csv",
                             header=None, names=headers)
            # get the relative path of the images

            def get_image_path(row):
                for image in headers[:3]:
                    row[image] = folder + '/' + \
                        '/'.join(row[image].split('/')[-2:])

                return row

            df = df.apply(get_image_path, axis=1)
            list_.append(df)

        pd.concat(list_).to_csv(driving_log_file, index=False)

    return driving_log_file

# ===================================================================== #
# ============================ split Data ============================= #
# ===================================================================== #

# @return pandas DataFrame
def split_data(path_to_csv):
    # read  driveing log csv file
    data = pd.read_csv(path_to_csv)
    return train_test_split(data, test_size=0.2)


import requests
import re
import time
import enchant
from bs4 import BeautifulSoup

# Variables
# Strings
# start_url = 'https://en.wikipedia.org/wiki/Solar_eclipse'
start_url = ''
appendText = "https://en.wikipedia.org"

# Structures
total_hyper_links = set()
scraped_urls = set()
path = []
depth = {}
keyword_list = []

#CONSTANTS
_MAX_URLS = 1000
_DEPTH = 6

# Settings
dictionary = enchant.Dict("en_US")

def main():

    global start_url
    global keyword_list

    # Input
    start_url = str(input("Please enter the URL to crawl: \n"))
    keywords = str(input("Enter the keywords to search: "))

    # Split the input keywords based on the whitespace character
    keyword_list = keywords.split(" ")

    # With SEED URLs as the node, run DFS algorithm through them
    dfs_search(start_url)

    # Print the length of the URL Set containing the scraped URLs
    print("Total length of URL set: " + str(len(total_hyper_links)))

    # Print the contents of the DFS Search to a file
    print_to_file(total_hyper_links, "focused-bfs-urls.txt")

def process():
    # Set the URL to crawl
    global start_url
    global total_hyper_links
    global scraped_urls
    global dictionary

    # Variables
    curr_hyper_links = []
    scraped_urls = set()

    print("Crawling: " + start_url + "\n")

    # Place a HTTPS request
    # Politeness Policy
    time.sleep(1)
    try:
        pageAddress = requests.get(start_url)
    except:
        print("Invalid URL: " + start_url)
        exit(1)

    # Retrieve all the content
    pageContent = pageAddress.content

    # Create a soup object
    soupObject = BeautifulSoup(pageContent, "html.parser")

    # Finding title of the URL
    title = soupObject.find('title')

    # Store each HTML as plain text
    with open("FOCUSED-BFS_HTML_FILES/%s.html" % title.string, 'wb+') as file:
        file.write(pageContent)

    # Find all the elements of the div tag with the class name: mw-parser-output
    container = soupObject.find(class_='mw-parser-output')

    # Find all the para tags in the main div tag
    para_tags = container.find_all('p')

    for value in para_tags:
        # Find all the anchor tags in each para tag
        anchor_tags = value.find_all('a')

        # Reiterate all the anchor tags to retrieve the hyper links
        for item in anchor_tags:
            if item is not None:
                data = item.contents
                href = item.get("href")
                # scraped_urls.add(href)

                for key in keyword_list:
                    for content in data:
                        if re.search(key, str(content), re.IGNORECASE):
                            pattern = '(.*?)(' + str(key) + ')(.*?)'
                            spell = re.match(pattern, str(content))
                            if spell:
                                if dictionary.check(str(spell.group(1) + spell.group(2) + spell.group(3))):
                                    scraped_urls.add(href)
                    if re.search(key, href, re.IGNORECASE):
                        if href not in scraped_urls:
                            scraped_urls.add(href)

    if scraped_urls.__contains__(None):
        scraped_urls.remove(None)
    # Reiterate all the Hyper Links and filter out the links
    # which do not start with the prefix https://en.wikipedia.org/wiki/
    for value in scraped_urls:
        result = re.match('^.+/wiki/.*$', value)

        if result and (result.group().count(':') == 1) and len(total_hyper_links) < 1000:
            if result.group().count('#') >= 1:
                result = re.match('(.*)#.*', result.group())
                result = result.group(1)
                curr_hyper_links.append(result)
            else:
                curr_hyper_links.append(result.group())

            total_hyper_links.update(curr_hyper_links)

        result = re.match('^/wiki/.*$', value)
        if result and (result.group().count(':') == 0) and len(total_hyper_links) < 1000:
            if result.group().count('#') >= 1:
                result = re.match('(.*)#.*', result.group())
                result = result.group(1)
                curr_hyper_links.append(appendText + result)
            else:
                curr_hyper_links.append(appendText + result.group())

            total_hyper_links.update(curr_hyper_links)

    return curr_hyper_links

# DFS_Loop:
def dfs_search(start):
    # Global Variables
    global start_url
    global total_hyper_links
    global _MAX_URLS
    global _DEPTH
    global depth

    # Local Declarations
    scraped, stack = set(), []
    depth = {"1": [start_url], "2": [], "3": [], "4": [], "5": [], "6": []}
    # stack.append(start)
    scraped.add(start)

    for d in range(1, _DEPTH + 1):
        # Debug Information
        print("Depth: " + str(d) + "/ Crawled URLS: " + str(len(total_hyper_links)) + "\n")

        # While the stack of the depth is not empty and
        # total number of hyoer links did not exceed 1000
        while depth[str(d)] and len(total_hyper_links) < _MAX_URLS:
            stack = depth[str(d)]

            # Debug Information
            print("Current Stack: ")
            print(stack)

            # Until the url_list is not empty
            while stack:
                # Retrieve the last element of the list(stack)
                # print(stack)
                vertex = stack.pop(0)

                # Set the Global URL as the popped value
                start_url = vertex
                # print("in dfs loop: " + start_url)

                # Capture the scraped URLs achieved by the scraping the current
                # URL in context and check if the total number of scraped URLs
                # are less than the required maximum.
                if len(total_hyper_links) < _MAX_URLS and d+1 <= _DEPTH:
                    vertex_url_stack = process()

                    # If the vertex has not been scraped, add it to the scraped list
                    for item in vertex_url_stack:
                        if item not in scraped:
                            # print("item in dfs loop: " + item)
                            # Merge the scraped URLs to the end of the current url_list
                            depth[str(d+1)].append(item)

                            # Add it to the scraped list
                            scraped.add(item)
                else:
                    break

def print_to_file(print_set, print_filename):
    with open(print_filename, 'w+') as file:
        for value in print_set:
            file.write(value + "\n")

if __name__ == "__main__":
    main()


# Write RAW output to text file

import sys
import serial
import time
from pick import pick
import serial.tools.list_ports
import re

def use_regex(input):
    pattern = re.compile(r"[0-9]*\.[0-9]+")
    return pattern.search(input, re.IGNORECASE)

comlist = serial.tools.list_ports.comports()

port = []
name = []
for element in comlist:

    port.append(element.device)  # Device : COM name full length
    name.append(element.description)  # Description : Full description of port

indicator: str = "=>"

title = "Select COM port :"

# Exit with error code 1 if no ports found
if len(port) <= 0:
    print("No device connected")
    sys.exit(1)

options = []

for i in range(0, len(port)):
    options.append(port[i] + " : " + name[i])

option, index = pick(options, title, indicator)

ser = serial.Serial(port[index], 115200, timeout=1)
time.sleep(1)

# Print all serial port data
def print_serial_data():
    while(True):
        line = ser.readline()
        if line:
            string = line.decode()
            print(string)

# One time function - Stackoverflow
def run_once(f):
    def wrapper(*args, **kwargs):
        if not wrapper.has_run:
            wrapper.has_run = True
            return f(*args, **kwargs)
    wrapper.has_run = False
    return wrapper

@run_once
def my_function():
    ser.write("AT+RUNIMPULSE".encode())
    # Enter Key
    ser.write("\r".encode())

action = run_once(my_function)

val = input("Enter value : ")

while(True):
    line = ser.readline()
    action()
    if line:
        string = line.decode()
        # change "none: 	" to any matching string
        if val in string:
            num = float(use_regex(string).group(0))
            # add custom condition here
            print(num)
            f = open("data.txt", "a")
            f.write(str(num) + "\n")
            f.close()

ser.close()


"""

    PROJECT: Face Detector App
    MADE BY: Mohd Ali Bin Naser
    GITHUB : github.com/mohdalibn

"""

# Importing the Libraries required for this project
from tkinter import *
from tkinter import filedialog
from PIL import Image, ImageTk
import cv2

# Loading the Pre-Trained Haar Cascaade Face Model Using OpenCV
trained_faced_data = cv2.CascadeClassifier(
    './haarcascade_frontalface_default.xml')

# Destroys and Creates a New Output Label when a the Mode is changed or a new file is selected
def DestroyOutputLabel():
    global OutputWindowLabel

    # This removes and image/video on the Label when the Upload button is click
    OutputWindowLabel.destroy()
    OutputWindowLabel = Label(FaceDetectionApp, bg="#000")
    OutputWindowLabel.place(x=417, y=95)

def FilePrompt():
    global ImageVar, VideoVar, FaceCount

    # Setting the FaceCount to Zero each time the function is called
    FaceCount = 0

    # Executes when DetectionMode is set to Image
    if not VideoMode:
        FilePath = filedialog.askopenfilename(filetypes=[(
            "PNG Image File", "*.png"), ("JPG Image File", "*.jpg"), ("JPEG Image File", "*.jpeg")])

    # Executes when DetectionMode is set to Video
    else:
        FilePath = filedialog.askopenfilename(filetypes=[(
            "MP4 File", "*.mp4"), ("AVI File", "*.avi")])

    # Checks whether the length of the file path is greater than 0
    if len(FilePath) > 0:

        if not VideoMode:
            ImageVar = cv2.imread(FilePath)
        else:
            VideoVar = cv2.VideoCapture(FilePath)

        # Getting the Image Name From the Image File Path
        PathStr = FilePath
        PathStr = PathStr.split('/')
        FileName = PathStr[-1]

        # Update the Image File Name to Display
        FileNameLabel.configure(text="File Name: " + FileName)

        # Removing the Output Window Image/Video when a new image/video is chosen
        OutputWindowLabel.image = ""
        FaceCountLabel.configure(text="Result: None")

    else:
        FileNameLabel.configure(text="File Name: No File Selected!")

    # This removes and image/video on the Label when the Upload button is click
    DestroyOutputLabel()

# This function displays the face count on the FaceCountLabel using the FaceCount variable
def FaceCounter():
    global FaceCount

    if FaceCount > 0:
        if FaceCount == 1:
            FaceCountLabel.configure(
                text="Result: " + str(FaceCount) + " Face Detected!")
        else:
            FaceCountLabel.configure(
                text="Result: " + str(FaceCount) + " Faces Detected!")
    else:
        FaceCountLabel.configure(text="Result: No Faces Detected!")

# This function creates a new image/video frame with the original proportions to fit within the Black Output Window
def NewFrameSize(frame):
    height, width, channels = frame.shape
    ratio = height/width

    new_width = width
    new_height = height

    if height > 400 or width > 300:
        if ratio < 1:
            new_width = 300
            new_height = int(new_width * ratio)
        else:
            new_height = 400
            new_width = int(new_height * (width / height))

    ratio = height / new_height
    frame = cv2.resize(
        frame, (new_width, new_height))

    newImage = Image.fromarray(frame)
    FinalImage = ImageTk.PhotoImage(image=newImage)

    return FinalImage, new_width, new_height

# This function centers the image/video frame within the Black Output Window
def LabelPositionCalc(FrameWidth, FrameHeight):
    # Calculating the label position according to the frame size
    # The Values 375, 391, 454, 70 are pre defined width, xpos, height, ypos of the Black Output Window respectively
    BlackWindowWidth = 375
    BlackWindowXPos = 391
    BlackWindowHeight = 454
    BlackWindowYPos = 70

    # Calculating the new X Position of the Black Output Label
    NewXPos = BlackWindowWidth - FrameWidth
    NewXPos = (NewXPos // 2) + BlackWindowXPos

    # Calculating the new Y Position of the Black Output Label
    NewYPos = BlackWindowHeight - FrameHeight
    NewYPos = (NewYPos // 2) + BlackWindowYPos

    # Updating the Black Output Label position with the new values
    OutputWindowLabel.place(x=NewXPos, y=NewYPos)

# This function is executed when it is called through the FaceDetection function when the VideoMode is set to true
def PlayVideo():
    global VideoVar, FaceCount

    FaceCount = 0  # Initially setting FaceCount to 0 for each frame of a video so that sum doesn't add up the count of faces for all the frames played

    success, frame = VideoVar.read()

    if success == True:
        # frame = imutils.resize(frame, width=550)

        grayscaled_img = cv2.cvtColor(frame, cv2.COLOR_BGRA2GRAY)

        face_coordinates = trained_faced_data.detectMultiScale(
            grayscaled_img)

        for cell in face_coordinates:  # this code is used to draw rectangles around multiple faces

            # Incrementing the Facecount
            FaceCount += 1

            x1, y1, width, height = cell

            # opencv color format is bgr instead of rgb. '2' here is the thickness of the rectangle
            cv2.rectangle(frame, (x1, y1), (x1 + width, y1 + height),
                          (0, 0, 255), 4)

            DisplayText = "Face " + str(FaceCount)

            cv2.putText(frame, DisplayText,
                        (x1 + (width//4), y1 + height + 100), cv2.FONT_HERSHEY_COMPLEX_SMALL, 3, (0, 0, 0), 5, cv2.LINE_AA)

        OutputImage = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)

        FinalFrame, _, _ = NewFrameSize(OutputImage)

        OutputWindowLabel.configure(image=FinalFrame)
        OutputWindowLabel.image = FinalFrame
        OutputWindowLabel.after(1, PlayVideo)

        # Updates the count of faces on the Result Label
        FaceCounter()

# This function is executed when the Detect Face Button is Clicked
def FaceDetection():
    global ImageVar, VideoVar, FaceCount, DetectionMode

    if not VideoMode and len(ImageVar) < 1:
        FileNameLabel.configure(text="File Name: Select An Image")

    elif FaceCount >= 1:  # This if statement prevents the user from spamming the Detect Face Button
        if not VideoMode:
            FaceCountLabel.configure(text="Result: Select a new image!")
        else:
            FaceCountLabel.configure(text="Result: Select a new video!")

    else:

        if VideoMode:

            _, frame = VideoVar.read()  # The purpose this line is to get the first frame of the video so that we can calculate and update the Black Output Label position just once instead of repeating it in the video loop

            # Unpacking the values returned by the function
            _, NewWidth, NewHeight = NewFrameSize(frame)

            # Updating the new Black Output Label Position
            LabelPositionCalc(NewWidth, NewHeight)

            PlayVideo()

        else:
            # Converting the Image to GrayScale
            grayscaled_img = cv2.cvtColor(ImageVar, cv2.COLOR_BGRA2GRAY)

            face_coordinates = trained_faced_data.detectMultiScale(
                grayscaled_img)

            for cell in face_coordinates:  # this code is used to draw rectangles around multiple faces

                # Incrementing the Facecount
                FaceCount += 1

                x1, y1, width, height = cell

                # opencv color format is bgr instead of rgb. '2' here is the thickness of the rectangle
                cv2.rectangle(ImageVar, (x1, y1), (x1 + width, y1 + height),
                              (0, 0, 255), 4)

                DisplayText = "Face " + str(FaceCount)

                cv2.putText(ImageVar, DisplayText,
                            (x1 + (width//4), y1 + height + 100), cv2.FONT_HERSHEY_SIMPLEX, 3, (0, 0, 0), 10, cv2.LINE_AA)

            OutputImage = cv2.cvtColor(ImageVar, cv2.COLOR_BGR2RGB)

            FinalImage, new_width, new_height = NewFrameSize(OutputImage)

            # Calculating the label position according to the frame size
            LabelPositionCalc(new_width, new_height)

            # Updating the SecondaryImgLabel to Display
            OutputWindowLabel.configure(image=FinalImage)
            OutputWindowLabel.image = FinalImage

            # Updates the count of faces on the Result Label
            FaceCounter()

# Changes The Upload Button Image On Hover
def UploadBtnHover(e):
    # Initially, DetectionMode is zero
    if not VideoMode:
        hoverImg = PhotoImage(file=f"AppImages/HoverUploadImg.png")
    else:
        hoverImg = PhotoImage(file=f"AppImages/HoverVideoUploadImg.png")

    UploadBtn['image'] = hoverImg
    UploadBtn.image = hoverImg

# Changes The Upload Button Image Off Hover
def UploadBtnLeave(e):
    if not VideoMode:
        leaveImg = PhotoImage(file=f"AppImages/UploadImg.png")
    else:
        leaveImg = PhotoImage(file=f"AppImages/VideoUploadImg.png")

    UploadBtn['image'] = leaveImg
    UploadBtn.image = leaveImg

# Changes The Detect Button Image On Hover
def DetectBtnHover(e):
    hoverImg = PhotoImage(file=f"AppImages/HoverDetectImg.png")
    DetectBtn['image'] = hoverImg
    DetectBtn.image = hoverImg

# Changes The Upload Button Image Off Hover
def DetectBtnLeave(e):
    leaveImg = PhotoImage(file=f"AppImages/DetectImg.png")
    DetectBtn['image'] = leaveImg
    DetectBtn.image = leaveImg

# Function that Updates the App when either of the Modes are choosen
def DetectMode():
    global VideoMode

    DestroyOutputLabel()

    # Code to Change the image of the upload button if detection mode is video
    if DetectionMode.get() == 2:
        VideoMode = True
        VideoImg = PhotoImage(file=f"AppImages/VideoUploadImg.png")
        UploadBtn['image'] = VideoImg
        UploadBtn.image = VideoImg

    else:

        VideoMode = False
        VideoImg = PhotoImage(file=f"AppImages/UploadImg.png")
        UploadBtn['image'] = VideoImg
        UploadBtn.image = VideoImg

    # Resets the Output Window and Text Labels
    OutputWindowLabel.image = ""
    FileNameLabel.configure(text="File Name: No File Selected")
    FaceCountLabel.configure(text="Result: None")

ImageVar = ""  # Initializing the ImageVar Variable with Empty String
VideoVar = ""  # Initializing the VideoVar Variable with Empty String
# Variable to keep track of whether the Video Radio Button is Active or not
VideoMode = False
FaceCount = 0  # Variable to keep track of number of faces on an Image/Video Frame

# Initializing Tkinter instanct
FaceDetectionApp = Tk()
FaceDetectionApp.title("Face Detection App")
FaceDetectionApp.geometry("800x550")  # Size of the tkinter window
# Added an Icon for the App
FaceDetectionApp.iconbitmap('AppImages/AppIcon.ico')
FaceDetectionApp.configure(bg="#fff")
FaceDetectionApp.resizable(False, False)

# Creating a Canvas for the App
canvas = Canvas(FaceDetectionApp, bg="#ffffff", height=550,
                width=800, bd=0, highlightthickness=0, relief="ridge")
canvas.place(x=0, y=0)

# Loading the Background Image of the App
background_img = PhotoImage(file=f"AppImages/background.png")
background = canvas.create_image(400.0, 275.0, image=background_img)

# Adding Radio Buttons for the user to choose between Image Mode and Video Mode
DetectionMode = IntVar()
ImageRadBtn = Radiobutton(FaceDetectionApp, text=" IMAGE", font=('Helvatical bold', 12),
                          activebackground='black', activeforeground='#FF9393', bg="black", fg="#FF9393", value=1,
                          variable=DetectionMode, cursor='hand2', command=DetectMode)
VideoRadBtn = Radiobutton(FaceDetectionApp, text=" VIDEO", font=('Helvatical bold', 12), activebackground='black', activeforeground='#FF9393', bg="black",  fg="#FF9393", value=2,
                          variable=DetectionMode, cursor='hand2', command=DetectMode)

ImageRadBtn.place(x=82, y=115)
VideoRadBtn.place(x=187, y=115)

# Upload Image/Video Button
BtnImg1 = PhotoImage(file=f"AppImages/UploadImg.png")
UploadBtn = Button(
    image=BtnImg1,
    borderwidth=0,
    highlightthickness=0,
    bg="#000",
    cursor="hand2",
    command=FilePrompt,
    relief="flat")

UploadBtn.place(
    x=55, y=164,
    width=244,
    height=44)

# Binding Functions for Hover Effect on the Upload Button
UploadBtn.bind("<Enter>", UploadBtnHover)
UploadBtn.bind("<Leave>", UploadBtnLeave)

# Label to Display the File Name that the user uploads
FileNameLabel = Label(FaceDetectionApp, bg="#C4C4C4",
                      text="File Name: No File Selected", font=('Helvatical bold', 15))
FileNameLabel.place(x=40, y=237)

# Detect Faces Button
BtnImg2 = PhotoImage(file=f"AppImages/DetectImg.png")
DetectBtn = Button(
    image=BtnImg2,
    borderwidth=0,
    highlightthickness=0,
    bg="#000",
    cursor="hand2",
    command=FaceDetection,
    relief="flat")

DetectBtn.place(
    x=55, y=297,
    width=244,
    height=44)

# Binding Functions for Hover Effect on the Detect Button
DetectBtn.bind("<Enter>", DetectBtnHover)
DetectBtn.bind("<Leave>", DetectBtnLeave)

# Label to Display the Result
FaceCountLabel = Label(FaceDetectionApp, bg="#C4C4C4", text="Result: None",
                       font=('Helvatical bold', 15))
FaceCountLabel.place(x=40, y=370)

# Main Label For the Output Window
OutputWindowLabel = Label(FaceDetectionApp, bg="#000")
OutputWindowLabel.place(x=417, y=95)

# Starting the Tkinter MainLoop
FaceDetectionApp.mainloop()


#!/usr/bin/python
import boto3
import sys

# by Rafael Klock

ec2 = boto3.client('ec2')
security_group_id = 'sg-080ce2a7c35e04bca'

ip_revoke = sys.argv[1]

retorno = ec2.revoke_security_group_ingress(
        GroupId=security_group_id,
        IpPermissions=[
	    {'IpProtocol': '-1',
             'IpRanges': [{'CidrIp': ip_revoke}]
	    }
        ]
)

#print retorno


from typing import List

class Solution:
    def leftRightDifference(self, nums: List[int]) -> List[int]:

        left_sum = [0 for _ in range(len(nums))]
        running_total = 0
        for idx in range(1, len(nums)):
            left_sum[idx] = nums[idx - 1] + running_total
            running_total = left_sum[idx]

        right_sum = [0 for _ in range(len(nums))]
        running_total = 0
        for idx in range(len(nums) - 2, -1, -1):
            right_sum[idx] = nums[idx + 1] + running_total
            running_total = right_sum[idx]

        return [
            abs(x - y) for x, y in zip(left_sum, right_sum)
        ]

if __name__ == '__main__':
    Solution().leftRightDifference([10, 4, 8, 3])


import argparse
import os
import json
import matplotlib.pyplot as plt

def get_output_filename(inp_fname):
    return inp_fname.replace('output', 'graph.png')

def get_x_value(graph_type, x):
    if graph_type == "trials":
        return int(x[11:-1])
    elif graph_type == "initpolicy":
        return int(x[15:-2])
    elif graph_type == "maxiter":
        return int(x[12: -1])
    elif graph_type == "revert":
        return int(x[11:-1])
    elif graph_type == "target":
        return int(x[11:-1])

def get_json_name(graph_type):
    return '{}_test_results.json'.format(graph_type)

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("graph_type", help="type of graphs (eg., cweights, trials etc)", type=str)
    parser.add_argument("inp_file", help="input file whose data should be plotted", type=str)
    args = parser.parse_args()

    with open(args.inp_file, mode='r', encoding='utf-8') as json_file:
        data = json.load(json_file)

    data_to_plot = list()
    for k in data.keys():
        print(k)
        data_to_plot.append(data[k])

    # for a in data_to_plot:
    #     print(a)
    #     print()

    # fig = plt.figure(1)
    # ax = fig.add_subplot(111)
    # bp = ax.boxplot(data_to_plot)
    # plt.show()
    plt.boxplot(data_to_plot)
    plt.show()

    # with open(args.inp_file, mode='r', encoding='utf-8') as input_file:
    #     file_content = input_file.readlines()

    # x_vals = list()
    # y_vals = list()
    # for line in file_content:
    #     x, y = line.strip().split(' ')
    #     x_vals.append(get_x_value(args.graph_type, x))
    #     # x_vals.append(x)
    #     y_vals.append(y)
    #
    # for a, b in zip(x_vals, y_vals):
    #     print(a, b)
    #
    # plt.plot(x_vals, y_vals, marker='o')
    # plt.xlabel('{} setting'.format(args.inp_file))
    # plt.ylabel('runtime (millisecond)')
    # fig = plt.gcf()
    # plt.show()
    # # fig.savefig('{}.png'.format(args.inp_file), dpi=100)
    # fig.savefig(get_output_filename(args.inp_file))

if __name__ == '__main__':
    main()


## package for dim reduction of data

from sklearn.decomposition import PCA,KernelPCA
import numpy as np
from mb_pandas.src.dfload import load_any_df
import pandas as pd
from mb_utils.src.logging import logger
import ast
from scipy.spatial import distance as dist_scipy
from sklearn.manifold import TSNE
import umap

__all__ = ['distance_scipy','get_data','get_avg_per_label','get_distance_mean']

def distance_scipy(event1,event2):
    """
    Distance between two points
    Inputs:
        event1 : list of coordinates of the points
        event2 : list of coordinates of the points
    Returns:
        distance between the points
    """
    return dist_scipy.euclidean(event1,event2)

def get_data(df_np,label,ids=None,dim_type= 'pca',dim_comp =2, logger=None):
    """
    Get the data from the file
    Inputs:
        df_np : numpy array (numpy array) or list
        label : label of the data (list)
        ids : ids of the data (list)
        dim_type : dimensionality reduction type. Options are 'pca','tsne' and 'umap'. Default is 'pca'
        dim_comp : number of pca components , also can be tsne or umap components. Default is 2
        logger : logger
    Returns:
        data : dataframe
    """

    assert type(df_np) == np.ndarray or type(df_np) == list, 'df_np should be numpy array or list'
    assert dim_type in ['pca','tsne','umap'] , 'dim_type should be pca, tsne or umap'
    assert type(dim_comp) == int, 'dim_comp should be integer'
    assert type(label) == list, 'label should be list'

    if type(df_np) == np.ndarray:
        data = list(df_np)
    else:
        data = df_np

    if dim_type == 'pca':
        pca = PCA(n_components=dim_comp)
        pca_emb = pca.fit_transform(data)
    elif dim_type == 'tsne':
        tsne = TSNE(n_components=dim_comp, perplexity=15, random_state=42, init='random', learning_rate=200)
        pca_emb = tsne.fit_transform(np.array(data))
        #pca_emb = TSNE(n_components=dim_comp).fit_transform(list(data['embedding']))
    elif dim_type == 'umap':
        pca_emb = umap.UMAP(n_components=dim_comp).fit_transform(data)
    if logger:
        logger.info(pca_emb[:3])
    temp_pca = list(pca_emb)

    data_pd = pd.DataFrame()
    data_pd['original_embedding'] = data
    data_pd['embedding'] = temp_pca
    data_pd['taxcode'] = label
    if ids:
        data['event_id'] = ids

    if logger:
        df_unique_taxcode = data['taxcode'].unique()
        logger.info('Number of unique taxcodes {}'.format(len(df_unique_taxcode)))

    return data

def get_avg_per_label(df,logger=None):
    """
    Get the average of the data per label
    Inputs:
        df : dataframe
        logger : logger
    Returns:
        df_avg : dataframe
    """
    assert type(df) == pd.DataFrame, 'df should be pandas dataframe'
    assert 'taxcode' in df.columns, 'taxcode should be in the dataframe'
    assert 'embedding' in df.columns, 'embedding should be in the dataframe'

    df_unique_taxcode = df['taxcode'].unique()

    pca_mean = {}
    for taxcode in df_unique_taxcode:
        df_temp = df[df['taxcode']==taxcode]
        pca_mean[taxcode]  = np.mean(df_temp['pca_res'],axis=0)
    if logger:
        logger.info('Length of PCA avg dict : {}'.format(str(len(pca_mean))))
    return pca_mean

def get_distance_mean(dm1,dm2,dm_mean=False,logger=None):
    """
    Get the distance of the data from the average of the data per label
    Inputs:
        dm1 : dataframe , one whos avg. might me needed
        dm2 : dataframe
        logger : logger
    Returns:
        df : dataframe
    """

    assert type(dm1) == pd.DataFrame, 'dm1 should be pandas dataframe'
    assert type(dm2) == pd.DataFrame, 'dm2 should be pandas dataframe'
    assert 'taxcode' in dm1.columns, 'taxcode should be in the dataframe'
    assert 'embedding' in dm1.columns, 'embedding should be in the dataframe'
    assert 'taxcode' in dm2.columns, 'taxcode should be in the dataframe'
    assert 'embedding' in dm2.columns, 'embedding should be in the dataframe'

    df = pd.DataFrame()
    df['event_id'] = dm2['event_id']
    df['taxcode'] = dm2['taxcode']
    if dm_mean == True:
        pca_mean = get_avg_per_label(dm1,logger=logger)

    dist = []
    dist_1 = []
    for i in range(len(dm2)):
        dist_all = []
        for j in range(len(dm1)):
            if dm_mean == True:
                dist_all.append(distance_scipy(dm2['embedding'][i],pca_mean[dm1['taxcode'][j]]))
            else:
                dist.append(distance_scipy(dm2['embedding'][i],dm1['embedding'][j]))
        dist_1.append(dist_all)
    if sum(dist_all)==0:
        dist_f = dist_all
    else:
        dist_f = dist
    df['distance'] = dist_f

    if logger:
        logger.info('Length of df : {}'.format(str(len(df))))
    return df


import requests
from bs4 import BeautifulSoup
import httpx
import asyncio
import time

def fetch_html_content(url):
    response = requests.get(url)
    return response.text

def find_matching_domains(td_texts, domain):
    printed_strings = set()
    for td_text in td_texts:
        if domain in td_text.lower() and td_text.count('.') == 2 and td_text not in printed_strings:
            printed_strings.add(td_text)
    return printed_strings

def prepare_urls(printed_strings):

    urls = set()
    for x in printed_strings:
        urls.add("http://" + x)
        urls.add("https://" + x)
    return urls

async def sc_check(urls):

    check_urls = list(urls)
    start_time = time.time()

    for x in check_urls:
        try:
            async with httpx.AsyncClient(verify=True, timeout=5.0) as client:
                check = await client.get(x)
                print(f"{x}: {check.status_code}")

        except httpx.RequestError as e:
            print(f"{x}: Error - {e}")

    print("\n", "Process finished --- %s seconds ---" % (time.time() - start_time))

    return x, check.status_code

def main():

    domain = input("What is the domain? Example: google.nl: ")
    url = "https://crt.sh/?q=" + domain

    try:
        response = fetch_html_content(url)
        soup = BeautifulSoup(response, "html.parser")
        td_texts = [td.get_text() for td in soup.find_all("td")]
        printed_strings = find_matching_domains(td_texts, domain)
        urls = prepare_urls(printed_strings)
        asyncio.run(sc_check(urls))

    except requests.RequestException as e:
        print("Error fetching or parsing data:", e)
    except KeyboardInterrupt:
        print("Operation interrupted by user.")

if __name__ == "__main__":
    main()


# Group 23

# Code to implement the perceptron network on season by season

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn import model_selection
from sklearn.metrics import classification_report
from sklearn.metrics import confusion_matrix
from sklearn.metrics import accuracy_score
'''with open('C:/Users/user/Downloads/indian-premier-league-csv-dataset/data/season9.csv','w') as f:
    for l in lines:
         f.write('('+l+'),\n')'''
         #shuffle=True, random_state=None,

class linear_network:
    def __init__(self,eta=0.01,n_iter=1000):  # new
        self.eta = eta
        self.n_iter = n_iter

    def initializeWeights(self,data):
        self.w=np.zeros(1 + data.shape[1]) # +1 has been done to include bias weight

    def train(self,data,target):
        for epoch in range(self.n_iter):
            for x, y in zip(data, target):
                delta= self.eta * (y - self.predict(x))
                self.w[1:] += delta * x
                self.w[0] += delta
        return self

    def netvalue(self, X):
        """Calculate net input"""
        return np.dot(X, self.w[1:]) + self.w[0]

    def predict(self, X):
        """Return class label after unit step"""
        return np.where(self.netvalue(X) >= 0.0, 1, -1)

    def test(self,data,target):
        y=np.dot(data,self.w[1:])+self.w[0]
        output=np.where(y>=0.0,1,-1)
        print(accuracy_score(target,output))
        print(confusion_matrix(target,output))
        print(classification_report(target,output))
        self.accuracy(target,output)

    def accuracy(self,target,output):
        correct=0
        n=len(target)
        for i in range(n):
            if(output[i]==target[i]):
                correct+=1
        print( correct / float(len(target)) * 100)

df_train=pd.read_csv('C:/Users/user/Downloads/indian-premier-league-csv-dataset/season1.csv')
df_test=pd.read_csv('C:/Users/user/Downloads/indian-premier-league-csv-dataset/season8.csv')

df_train['Average_runs']=pd.to_numeric(df_train['Average_runs'], errors='coerce').fillna(0.0).astype(np.float)
df_train['Average_wickets']=pd.to_numeric(df_train['Average_wickets'], errors='coerce').fillna(0.0).astype(np.float)
df_train['Performance_rating']=pd.to_numeric(df_train['Performance_rating'], errors='coerce').fillna(-1.0).astype(np.float)
df_train['Player_Id']=pd.to_numeric(df_train['Player_Id'], errors='coerce').fillna(0).astype(np.int64)
df_train['Runs_Scored']=pd.to_numeric(df_train['Runs_Scored'], errors='coerce').fillna(0).astype(np.int64)
df_train['Wickets_Taken']=pd.to_numeric(df_train['Wickets_Taken'], errors='coerce').fillna(0).astype(np.int64)
df_train['Outs']=pd.to_numeric(df_train['Outs'], errors='coerce').fillna(0).astype(np.int64)
df_train['Matches_Played']=pd.to_numeric(df_train['Matches_Played'], errors='coerce').fillna(0).astype(np.int64)

df_test['Average_runs']=pd.to_numeric(df_test['Average_runs'], errors='coerce').fillna(0.0).astype(np.float)
df_test['Average_wickets']=pd.to_numeric(df_test['Average_wickets'], errors='coerce').fillna(0.0).astype(np.float)
df_test['Performance_rating']=pd.to_numeric(df_test['Performance_rating'], errors='coerce').fillna(-1.0).astype(np.float)
df_test['Player_Id']=pd.to_numeric(df_test['Player_Id'], errors='coerce').fillna(0).astype(np.int64)
df_test['Runs_Scored']=pd.to_numeric(df_test['Runs_Scored'], errors='coerce').fillna(0).astype(np.int64)
df_test['Wickets_Taken']=pd.to_numeric(df_test['Wickets_Taken'], errors='coerce').fillna(0).astype(np.int64)
df_test['Outs']=pd.to_numeric(df_test['Outs'], errors='coerce').fillna(0).astype(np.int64)
df_test['Matches_Played']=pd.to_numeric(df_test['Matches_Played'], errors='coerce').fillna(0).astype(np.int64)

X = df_train.iloc[1:,1:-1].values
y=df_train.iloc[1:,-1].values

X1 = df_test.iloc[1:,1:-1].values
y1=df_test.iloc[1:,-1].values

ppn = linear_network(0.01,100)
ppn.initializeWeights(X)
ppn.train(X, y)

ppn.test(X1,y1)


import discord
from discord import app_commands
from discord.ext import commands

class purgeCommand(commands.Cog):
	def __init__(self, bot: commands.Bot):
		self.bot = bot

	@app_commands.command(name="purge", description="Purge the specified amount of messages.")
	@app_commands.describe(amount="The amount of messages to purge.")
	@commands.has_permissions(manage_messages=True)
	async def purge(self, interaction: discord.Interaction, amount: int):
		await interaction.response.send_message(f"Purged {amount} messages.", ephemeral=True)
		await interaction.channel.purge(limit=amount + 1)

async def setup(bot: commands.Bot) -> None:
	await bot.add_cog(purgeCommand(bot))