# Attach / exec / logs utilities

import asyncio
import codecs
import enum
import logging
import signal
import sys
import threading
from contextlib import AsyncExitStack
from datetime import datetime
from typing import Any, Awaitable, Callable, List, NoReturn, Optional, Sequence, Tuple

import aiohttp
import click
from prompt_toolkit.formatted_text import HTML, merge_formatted_text
from prompt_toolkit.input import create_input
from prompt_toolkit.key_binding import KeyPress
from prompt_toolkit.key_binding.key_bindings import KeyBindings
from prompt_toolkit.key_binding.key_processor import KeyPressEvent
from prompt_toolkit.keys import Keys
from prompt_toolkit.output import Output, create_output
from prompt_toolkit.shortcuts import PromptSession
from rich.markup import escape as rich_escape

from neuro_sdk import (
    JobDescription,
    JobStatus,
    ResourceNotFound,
    StdStream,
    StdStreamError,
)

from .const import EX_IOERR, EX_PLATFORMERROR
from .formatters.jobs import JobStopProgress
from .root import Root

log = logging.getLogger(__name__)

JOB_STARTED_NEURO_HAS_TTY = (
    "[green]√[/green] "
    "[dim]===== Job is running, press Ctrl-C to detach/kill =====[/dim]"
)

JOB_STARTED_NEURO_HAS_NO_TTY = (
    "[dim]===== Job is running, press Ctrl-C to detach =====[/dim]"
)

JOB_STARTED_TTY = "\n".join(
    "[green]√[/green] " + line
    for line in [
        "[dim]=========== Job is running in terminal mode ===========[/dim]",
        "[dim](If you don't see a command prompt, try pressing enter)[/dim]",
        "[dim](Use Ctrl-P Ctrl-Q key sequence to detach from the job)[/dim]",
    ]
)

ATTACH_STARTED_AFTER_LOGS = (
    "[dim]========= Job's output, may overlap with logs =========[/dim]"
)

class InterruptAction(enum.Enum):
    NOTHING = enum.auto()
    DETACH = enum.auto()
    KILL = enum.auto()

class AttachHelper:
    attach_ready: bool
    log_printed: bool
    job_started_msg: str
    write_sem: asyncio.Semaphore
    quiet: bool
    action: InterruptAction

    def __init__(self, *, quiet: bool) -> None:
        self.attach_ready = False
        self.log_printed = False
        self.job_started_msg = ""
        self.write_sem = asyncio.Semaphore()
        self.quiet = quiet
        self.action = InterruptAction.NOTHING

async def process_logs(
    root: Root,
    job: str,
    helper: Optional[AttachHelper],
    *,
    cluster_name: Optional[str],
    since: Optional[datetime] = None,
    timestamps: bool = False,
) -> None:
    codec_info = codecs.lookup("utf8")
    decoder = codec_info.incrementaldecoder("replace")
    separator = "<================ Live logs ==============>"
    async with root.client.jobs.monitor(
        job,
        cluster_name=cluster_name,
        since=since,
        timestamps=timestamps,
        separator=separator,
        debug=root.verbosity >= 2,
    ) as it:
        async for chunk in it:
            if not chunk:
                txt = decoder.decode(b"", final=True)
                if not txt:
                    break
            else:
                txt = decoder.decode(chunk)
            if helper is not None:
                if helper.attach_ready:
                    return
                async with helper.write_sem:
                    if not helper.log_printed:
                        if not root.quiet:
                            root.print(helper.job_started_msg, markup=True)
                        helper.log_printed = True
                    sys.stdout.write(txt)
                    sys.stdout.flush()
            else:
                sys.stdout.write(txt)
                sys.stdout.flush()

async def process_exec(
    root: Root, job: str, cmd: str, tty: bool, *, cluster_name: Optional[str]
) -> NoReturn:
    try:
        if tty:
            exit_code = await _exec_tty(root, job, cmd, cluster_name=cluster_name)
        else:
            exit_code = await _exec_non_tty(root, job, cmd, cluster_name=cluster_name)
    finally:
        root.soft_reset_tty()

    if not root.quiet:
        status = await root.client.jobs.status(job)
        print_job_result(root, status)

    sys.exit(exit_code)

async def _exec_tty(
    root: Root, job: str, cmd: str, *, cluster_name: Optional[str]
) -> int:
    loop = asyncio.get_event_loop()
    helper = AttachHelper(quiet=True)

    stdout = create_output()
    h, w = stdout.get_size()

    async with root.client.jobs.exec(
        job,
        cmd,
        tty=True,
        stdin=True,
        stdout=True,
        stderr=False,
        cluster_name=cluster_name,
    ) as stream:
        status = await root.client.jobs.status(job)

        if status.status is not JobStatus.RUNNING:
            raise ValueError(f"Job {job!r} is not running")

        await stream.resize(h=h, w=w)

        resize_task = loop.create_task(_process_resizing(stream.resize, stdout))
        input_task = loop.create_task(_process_stdin_tty(stream, helper))
        output_task = loop.create_task(
            _process_stdout_tty(root, stream, stdout, helper)
        )

        try:
            tasks = [resize_task, input_task, output_task]
            await asyncio.wait(tasks, return_when=asyncio.FIRST_COMPLETED)
        finally:
            await root.cancel_with_logging(resize_task)
            await root.cancel_with_logging(input_task)
            return await _cancel_exec_output(root, output_task)

async def _exec_non_tty(
    root: Root, job: str, cmd: str, *, cluster_name: Optional[str]
) -> int:
    loop = asyncio.get_event_loop()
    helper = AttachHelper(quiet=True)

    async with root.client.jobs.exec(
        job,
        cmd,
        tty=False,
        stdin=True,
        stdout=True,
        stderr=True,
        cluster_name=cluster_name,
    ) as stream:
        status = await root.client.jobs.status(job)

        if status.status is not JobStatus.RUNNING:
            raise ValueError(f"Job {job!r} is not running")

        input_task = None
        if root.tty:
            input_task = loop.create_task(_process_stdin_non_tty(root, stream))
        output_task = loop.create_task(_process_stdout_non_tty(root, stream, helper))

        try:
            tasks = [output_task]
            if input_task:
                tasks.append(input_task)
            await asyncio.wait(tasks, return_when=asyncio.FIRST_COMPLETED)
        finally:
            if input_task:
                await root.cancel_with_logging(input_task)
            return await _cancel_exec_output(root, output_task)

async def _cancel_exec_output(root: Root, output_task: "asyncio.Task[Any]") -> int:
    if output_task.done():
        ex = output_task.exception()
        if ex and isinstance(ex, StdStreamError):
            return ex.exit_code
    await root.cancel_with_logging(output_task)
    return EX_PLATFORMERROR

class RetryAttach(Exception):
    pass

async def process_attach(
    root: Root,
    job: JobDescription,
    tty: bool,
    logs: bool,
    port_forward: List[Tuple[int, int]],
) -> None:
    max_retry_timeout = 10
    while True:
        retry_timeout = 1
        try:
            await _process_attach_single_try(root, job, tty, logs, port_forward)
        except RetryAttach:
            while True:
                root.print(f"Connection lost. Retrying in {retry_timeout} seconds")
                await asyncio.sleep(retry_timeout)
                retry_timeout = min(retry_timeout * 2, max_retry_timeout)
                try:
                    job = await root.client.jobs.status(job.id)
                except aiohttp.ClientConnectionError:
                    pass
                else:
                    break

async def _process_attach_single_try(
    root: Root,
    job: JobDescription,
    tty: bool,
    logs: bool,
    port_forward: List[Tuple[int, int]],
) -> None:
    # Note, the job should be in running/finished state for this call,
    # passing pending job is forbidden

    while True:
        restarts = job.history.restarts
        async with AsyncExitStack() as stack:
            for local_port, job_port in port_forward:
                root.print(
                    f"Port localhost:{local_port} will be forwarded to port {job_port}"
                )
                await stack.enter_async_context(
                    root.client.jobs.port_forward(
                        job.id, local_port, job_port, cluster_name=job.cluster_name
                    )
                )

            helper = AttachHelper(quiet=root.quiet)
            if tty:
                helper.job_started_msg = JOB_STARTED_TTY
            elif root.tty:
                helper.job_started_msg = JOB_STARTED_NEURO_HAS_TTY
            else:
                helper.job_started_msg = JOB_STARTED_NEURO_HAS_NO_TTY
            loop = asyncio.get_event_loop()
            if logs:
                logs_printer = loop.create_task(
                    process_logs(root, job.id, helper, cluster_name=job.cluster_name)
                )
            else:
                # Placeholder, prints nothing
                logs_printer = loop.create_task(asyncio.sleep(0))

            try:
                job = await root.client.jobs.status(job.id)
                if job.status.is_finished:
                    await logs_printer
                    print_job_result(root, job)
                    if job.status == JobStatus.FAILED:
                        sys.exit(job.history.exit_code or EX_PLATFORMERROR)
                    else:
                        sys.exit(job.history.exit_code)

                if tty:
                    action = await _attach_tty(
                        root, job.id, helper, cluster_name=job.cluster_name
                    )
                else:
                    action = await _attach_non_tty(
                        root, job.id, helper, cluster_name=job.cluster_name
                    )

                if action == InterruptAction.KILL:
                    with JobStopProgress.create(
                        root.console, quiet=root.quiet
                    ) as progress:
                        progress.kill(job)
                    sys.exit(128 + signal.SIGINT)
                elif action == InterruptAction.DETACH:
                    with JobStopProgress.create(
                        root.console, quiet=root.quiet
                    ) as progress:
                        progress.detach(job)
                    sys.exit(0)
            except ResourceNotFound:
                # Container already stopped, so we can ignore such error.
                pass
            finally:
                await root.cancel_with_logging(logs_printer)
                root.soft_reset_tty()

            # We exited attach function not because of detach or kill,
            # probably we lost connectivity?
            try:
                job = await root.client.jobs.status(job.id)
            except aiohttp.ClientConnectionError:
                raise RetryAttach
            # Maybe it is spurious disconnect, and we should re-attach back?
            # Check container liveness by calling attach once
            try:
                async with root.client.jobs.attach(
                    job.id, stdin=True, cluster_name=job.cluster_name
                ):
                    raise RetryAttach
            except (asyncio.CancelledError, RetryAttach):
                raise
            except Exception:
                pass  # Was unable to reconnect, most likely container is dead

            # The class pins the current time in counstructor,
            # that's why we need to initialize
            # it AFTER the disconnection from attached session.
            with JobStopProgress.create(root.console, quiet=root.quiet) as progress:
                while (not job.status.is_finished) and (
                    job.history.reason == "Restarting"
                    or job.history.restarts == restarts
                ):
                    if not progress.step(job):
                        sys.exit(EX_IOERR)
                    await asyncio.sleep(0.2)
                    job = await root.client.jobs.status(job.id)
                progress.end(job)

async def _attach_tty(
    root: Root, job: str, helper: AttachHelper, *, cluster_name: Optional[str]
) -> InterruptAction:
    stdout = create_output()
    h, w = stdout.get_size()

    async with root.client.jobs.attach(
        job, tty=True, stdin=True, stdout=True, stderr=False, cluster_name=cluster_name
    ) as stream:
        await stream.resize(h=h, w=w)

        loop = asyncio.get_event_loop()
        resize_task = loop.create_task(_process_resizing(stream.resize, stdout))
        input_task = loop.create_task(_process_stdin_tty(stream, helper))
        output_task = loop.create_task(
            _process_stdout_tty(root, stream, stdout, helper)
        )

        try:
            tasks = [resize_task, input_task, output_task]
            await asyncio.wait(tasks, return_when=asyncio.FIRST_COMPLETED)
        finally:
            await root.cancel_with_logging(resize_task)
            await root.cancel_with_logging(input_task)
            await _cancel_attach_output(root, output_task)

        return helper.action

async def _process_resizing(
    resizer: Callable[..., Awaitable[None]], stdout: Output
) -> None:
    loop = asyncio.get_event_loop()
    resize_event = asyncio.Event()

    def resize() -> None:
        resize_event.set()

    has_sigwinch = (
        hasattr(signal, "SIGWINCH")
        and threading.current_thread() is threading.main_thread()
    )
    if has_sigwinch:
        previous_winch_handler = signal.getsignal(signal.SIGWINCH)
        loop.add_signal_handler(signal.SIGWINCH, resize)
        if previous_winch_handler is None:
            # Borrowed from the Prompt Toolkit.
            # In some situations we receive `None`. This is
            # however not a valid value for passing to
            # `signal.signal` at the end of this block.
            previous_winch_handler = signal.SIG_DFL

    prevh = prevw = None
    try:
        while True:
            if has_sigwinch:
                await resize_event.wait()
                resize_event.clear()
            else:
                # Windows or non-main thread
                # The logic is borrowed from docker CLI.
                # Wait for 250 ms
                # If there is no resize event -- check the size anyway on timeout.
                # It makes resizing to work on Windows.
                await asyncio.sleep(0.25)
            h, w = stdout.get_size()
            if prevh != h or prevw != w:
                prevh = h
                prevw = w
                await resizer(w=w, h=h)
    finally:
        if has_sigwinch:
            loop.remove_signal_handler(signal.SIGWINCH)
            signal.signal(signal.SIGWINCH, previous_winch_handler)

def _has_detach(keys: Sequence[KeyPress], term: Sequence[Keys]) -> bool:
    for i in range(len(keys) - len(term) + 1):
        if keys[i].key == term[0]:
            for j in range(1, len(term)):
                if keys[i + j].key != term[j]:
                    break
            else:
                return True
    return False

async def _process_stdin_tty(stream: StdStream, helper: AttachHelper) -> None:
    ev = asyncio.Event()

    def read_ready() -> None:
        ev.set()

    term = (Keys.ControlP, Keys.ControlQ)
    prev: List[KeyPress] = []

    inp = create_input()
    with inp.raw_mode():
        with inp.attach(read_ready):
            while True:
                await ev.wait()
                ev.clear()
                if inp.closed:
                    return
                keys = inp.read_keys()  # + inp.flush_keys()
                prev.extend(keys)
                if _has_detach(prev, term):
                    helper.action = InterruptAction.DETACH
                if len(prev) >= len(term):
                    oldest_key = len(prev) - len(term) + 1
                    prev = prev[oldest_key:]
                buf = b"".join(key.data.encode("utf8") for key in keys)
                await stream.write_in(buf)
                if helper.action == InterruptAction.DETACH:
                    return

async def _process_stdout_tty(
    root: Root, stream: StdStream, stdout: Output, helper: AttachHelper
) -> None:
    codec_info = codecs.lookup("utf8")
    decoder = codec_info.incrementaldecoder("replace")
    while True:
        chunk = await stream.read_out()
        if chunk is None:
            txt = decoder.decode(b"", final=True)
            if not txt:
                return
        else:
            txt = decoder.decode(chunk.data)
        async with helper.write_sem:
            if not helper.attach_ready:
                await _print_header(root, helper)
                helper.attach_ready = True
            stdout.write_raw(txt)
            stdout.flush()

async def _attach_non_tty(
    root: Root, job: str, helper: AttachHelper, *, cluster_name: Optional[str]
) -> InterruptAction:
    async with root.client.jobs.attach(
        job, stdin=True, stdout=True, stderr=True, cluster_name=cluster_name
    ) as stream:
        input_task = None
        loop = asyncio.get_event_loop()
        if root.tty:
            input_task = loop.create_task(_process_stdin_non_tty(root, stream))
        output_task = loop.create_task(_process_stdout_non_tty(root, stream, helper))
        ctrl_c_task = loop.create_task(_process_ctrl_c(root, job, helper))

        try:
            tasks = [output_task, ctrl_c_task]
            if input_task:
                tasks.append(input_task)
            await asyncio.wait(tasks, return_when=asyncio.FIRST_COMPLETED)
        finally:
            if input_task:
                await root.cancel_with_logging(input_task)
            await _cancel_attach_output(root, output_task)
            await root.cancel_with_logging(ctrl_c_task)
        return helper.action

async def _process_stdin_non_tty(root: Root, stream: StdStream) -> None:
    ev = asyncio.Event()

    def read_ready() -> None:
        ev.set()

    inp = create_input()
    with inp.attach(read_ready):
        while True:
            await ev.wait()
            ev.clear()
            if inp.closed:
                return
            keys = inp.read_keys()  # + inp.flush_keys()
            buf = b"".join(key.data.encode("utf8") for key in keys)
            await stream.write_in(buf)

async def _process_stdout_non_tty(
    root: Root, stream: StdStream, helper: AttachHelper
) -> None:
    codec_info = codecs.lookup("utf8")
    decoders = {
        1: codec_info.incrementaldecoder("replace"),
        2: codec_info.incrementaldecoder("replace"),
    }
    streams = {1: sys.stdout, 2: sys.stderr}

    async def _write(fileno: int, txt: str) -> None:
        f = streams[fileno]
        async with helper.write_sem:
            if not helper.attach_ready:
                await _print_header(root, helper)
                helper.attach_ready = True
            f.write(txt)
            f.flush()

    while True:
        chunk = await stream.read_out()
        if chunk is None:
            for fileno in (1, 2):
                txt = decoders[fileno].decode(b"", final=True)
                if txt:
                    await _write(fileno, txt)
            break
        else:
            txt = decoders[chunk.fileno].decode(chunk.data)
            await _write(chunk.fileno, txt)

async def _print_header(root: Root, helper: AttachHelper) -> None:
    if not helper.quiet and not helper.attach_ready:
        # Print header to stdout only,
        # logs are printed to stdout and never to
        # stderr (but logs printing is stopped by
        # helper.attach_ready = True regardless
        # what stream had receive text in attached mode.
        if helper.log_printed:
            s = ATTACH_STARTED_AFTER_LOGS
            if root.tty:
                s = "[green]√[/green] " + s
            root.print(s, markup=True)
        else:
            if not root.quiet:
                root.print(helper.job_started_msg, markup=True)

def _create_interruption_dialog() -> PromptSession[InterruptAction]:
    bindings = KeyBindings()

    @bindings.add(Keys.Enter)
    @bindings.add(Keys.Escape)
    def nothing(event: KeyPressEvent) -> None:
        event.app.exit(result=InterruptAction.NOTHING)

    @bindings.add("c-c")
    @bindings.add("C")
    @bindings.add("c")
    def kill(event: KeyPressEvent) -> None:
        event.app.exit(result=InterruptAction.KILL)

    @bindings.add("c-d")
    @bindings.add("D")
    @bindings.add("d")
    def detach(event: KeyPressEvent) -> None:
        event.app.exit(result=InterruptAction.DETACH)

    @bindings.add(Keys.Any)
    def _(event: KeyPressEvent) -> None:
        # Disallow inserting other text.
        pass

    message = HTML("  <b>Interrupted</b>. Please choose the action:\n")
    suffix = HTML(
        "<b>Ctrl-C</b> or <b>C</b> -- Kill\n"
        "<b>Ctrl-D</b> or <b>D</b> -- Detach \n"
        "<b>Enter</b> or <b>ESC</b> -- Continue the attached mode"
    )
    complete_message = merge_formatted_text([message, suffix])
    session: PromptSession[InterruptAction] = PromptSession(
        complete_message, key_bindings=bindings
    )
    return session

async def _process_ctrl_c(root: Root, job: str, helper: AttachHelper) -> None:
    # Exit from _process_ctrl_c() task finishes the outer _attach_non_tty() task
    # Return True if kill/detach was asked.
    # The returned value can be used for skipping the job termination
    queue: asyncio.Queue[Optional[int]] = asyncio.Queue()
    loop = asyncio.get_event_loop()

    def on_signal(signum: int, frame: Any) -> None:
        loop.call_soon_threadsafe(queue.put_nowait, signum)

    # Windows even loop has no add_signal_handler() method
    prev_signal = signal.signal(signal.SIGINT, on_signal)

    try:
        while True:
            getter = queue.get()
            if sys.platform == "win32":
                # On Python < 3.8 the interruption handling
                # responds not smoothly because the loop is blocked
                # in proactor for relative long time period.
                # Simple busy loop interrupts the proactor every 100 ms,
                # giving a chance to process other tasks
                getter = asyncio.wait_for(getter, 0.1)
            try:
                signum = await getter
            except asyncio.TimeoutError:
                continue
            if signum is None:
                return
            if not root.tty:
                click.secho("Detach terminal", dim=True, fg="green")
                helper.action = InterruptAction.DETACH
                return
            async with helper.write_sem:
                session = _create_interruption_dialog()
                answer = await session.prompt_async(set_exception_handler=False)
                if answer == InterruptAction.DETACH:
                    click.secho("Detach terminal", dim=True, fg="green")
                    helper.action = answer
                    return
                elif answer == InterruptAction.KILL:
                    click.secho("Kill job", fg="red")
                    await root.client.jobs.kill(job)
                    helper.action = answer
                    return
    finally:
        signal.signal(signal.SIGINT, prev_signal)

async def _cancel_attach_output(root: Root, output_task: "asyncio.Task[Any]") -> None:
    if output_task.done():
        ex = output_task.exception()
        if ex and isinstance(ex, StdStreamError):
            return
    await root.cancel_with_logging(output_task)

def print_job_result(root: Root, job: JobDescription) -> None:
    if job.status == JobStatus.SUCCEEDED and root.verbosity > 0:
        msg = f"Job [b]{job.id}[/b] finished successfully"
        if root.tty:
            msg = "[green]√[/green] " + msg
        root.print(msg, markup=True)
    if job.status == JobStatus.CANCELLED and root.verbosity >= 0:
        msg = f"Job [b]{job.id}[/b] was cancelled"
        if root.tty:
            msg = "[green]√[/green] " + msg
        if job.history.reason:
            msg += f" ({rich_escape(job.history.reason)})"
        root.print(msg, markup=True)
    if job.status == JobStatus.FAILED and root.verbosity >= 0:
        msg = f"Job [b]{job.id}[/b] failed"
        if root.tty:
            msg = "[red]×[/red] " + msg
        if job.history.reason:
            msg += f" ({rich_escape(job.history.reason)})"
        root.print(msg, markup=True)


# هنا هعمل هثبت المكتبات ال محتاجينها وهعمل استدعاء ليها
#from unittest import result
from sys import excepthook

import requests
import bs4
import csv
from itertools import zip_longest
job_title=[]
company_name=[]
location_name=[]
job_skill=[]
date=[]
links=[]
#هنا بعمل طلب على شان ادخل على اللنك واحفظ الصفحة
page_num=0
while True:
    url = f"https://wuzzuf.net/search/jobs/?a=hpb&q=e-marketer&start={page_num}"
    result = requests.get(url)
    src = result.content

    #print(src)

    #هنا هنعمل اوبجت جديد  على شان نقدر نفصل فى المعلومات ال طالعة (parse content)

    soup = bs4.BeautifulSoup(src, "lxml")
    #print(soup)
    page_limit=int(soup.find("strong").text)
    if(page_num>page_limit//15):
        print("page ended, terminate")
        break
    # هنطلع الحاجات ال محتاجنها من الصفة مثل اسم الوظيفة ,اسم الشركة , الموقع , المهارات المطلوبة , وقت الطرح

    job_titles=soup.find_all("h2",{"class":"css-m604qf"})
    #print(job_title)

    company_names=soup.find_all("a",{"class":"css-17s97q8"})
    #print(campany_name)

    locations_names=soup.find_all("span",{"class":"css-5wys0k"})
    #print(locations_name)

    job_skills=soup.find_all("div",{"class":"css-y4udm8"})
    #print(job_skills)

    posteds_old=soup.find_all("div",{"class":"css-do6t5g"})
    posteds_new=soup.find_all("div",{"class":"css-4c4ojb"})
    posted=[*posteds_new,*posteds_old]
    #هنا هنعمل لوب على شان نلف فى الكونتت كلها ونستخرج ال احنا محتاجينه منها

    for i in range(len(job_titles)):
        job_title.append(job_titles[i].text)
        links.append("https://wuzzuf.net"+job_titles[i].find("a").attrs['href'])
        company_name.append(company_names[i].text)
        location_name.append(locations_names[i].text)
        job_skill.append(job_skills[i].text)
        date.append(posted[i].text)
    f_list = [job_title, company_name, date, location_name, job_skill, links]  # """هنا هنعمل حاجة اسمعها ان باكنج"""

    for all in zip(*f_list):
        print(all)
    page_num+=1
    print("\npage switched\n")

#print(posted)

# print(job_title)
# print("\n")
# print(company_name)
# print("\n")
# print(locations_name)
# print("\n")
# print(job_skil ls)

#هنا هنخزن المعلومات ال اتستخرجنها ونملى بيها الفايل الخاص بنا

exp=zip_longest(*f_list)
with open("D:\تالتة حاسبات\python\python3.csv","w") as thefile:
    wrr=csv.writer(thefile)
    wrr.writerow(["job title","company name", "date","location","skills","links"])
    wrr.writerows(exp)


from tqdm import tqdm
import pandas as pd
import numpy as np
import json
import argparse

import bokeh.models as bm
import bokeh.plotting as pl
from bokeh.io import output_notebook

from sklearn.decomposition import PCA
from sklearn.preprocessing import StandardScaler

import fasttext.util

class word_embeddings:
    def __init__(self, model, df, text_column, batch_size=5):
        self.model = model
        self.df = df
        self.text_column = text_column
        self.batch_size = batch_size
        self.num_batches = int(np.ceil(len(df) / batch_size))

    def batch_generator(self):
        while True:
            for i in range(self.num_batches):
                batch = self.df[i*self.batch_size : (i+1)*self.batch_size]
                X_batch = batch[self.text_column].values
                yield X_batch

    def predict(self, X):
        return [self.model.get_sentence_vector(x) for x in X]

    def draw_vectors(
        self, x, y, radius=10, alpha=0.25, color="blue", width=600, height=400, show=True, **kwargs
        ):
        """draws an interactive plot for data points with auxilirary info on hover"""

        output_notebook()
        if isinstance(color, str):
            color = [color] * len(x)
        data_source = bm.ColumnDataSource({"x": x, "y": y, "color": color, **kwargs})

        fig = pl.figure(active_scroll="wheel_zoom", width=width, height=height)
        fig.scatter("x", "y", size=radius, color="color", alpha=alpha, source=data_source)

        fig.add_tools(bm.HoverTool(tooltips=[(key, "@" + key) for key in kwargs.keys()]))
        if show:
            pl.show(fig)
        return fig

def main(config_file: str) -> None:
    """
    The main function for data preprocessing.

    Args:
        config_file (str): Path to the JSON configuration file.
    """

    # Load the JSON configuration file
    with open(config_file, "r") as f:
        config = json.load(f)

    # Extract values from the configuration file
    texts_data_path = config["data_paths"]["texts"]
    embeddings_data_path = config["data_paths"]["embeddings"]

    ft = fasttext.load_model('cc.en.300.bin')
    df = pd.read_csv(texts_data_path, index_col=0)

    to_vec = word_embeddings(ft, df, 'title')
    num_batches = to_vec.num_batches

    data_generator = to_vec.batch_generator()

    X = []
    for i in tqdm(range(num_batches)):
        X_batch = next(data_generator)
        X.extend(to_vec.predict(X_batch))
    X = np.asarray(X)

    np.save(embeddings_data_path, X)

    """
    pca = PCA(2)
    scaler = StandardScaler()

    phrase_vectors_2d = pca.fit_transform(X)
    phrase_vectors_2d = scaler.fit_transform(phrase_vectors_2d)

    to_vec.draw_vectors(
        phrase_vectors_2d[:, 0],
        phrase_vectors_2d[:, 1],
        phrase=[phrase[:50] for phrase in df.title.to_list()],
        radius=20,
    )"""

if __name__ == "__main__":
    # Parse the arguments from the command line
    parser = argparse.ArgumentParser()
    parser.add_argument("-config_path", type=str, help="Path to JSON configuration file")
    args = parser.parse_args()

    # Call the main function with the parsed arguments
    main(args.config_path)


from huey.contrib.djhuey import db_periodic_task, db_task, periodic_task, task
import datetime
from .twilio_api import send_message

# @db_task()
# def do_some_queries():
# This task executes queries. Once the task finishes, the connection
# will be closed.

# @db_periodic_task(crontab(minute='*/5'))
# def every_five_mins():
# This is a periodic task that executes queries.

@task()
def test_task(message):
    print('message: ' + str(datetime.datetime.utcnow()) + '; ' + message)
    return

@task()
def send_reminder(patient, reminder_id, message):
    # print('send reminder: ' + str(datetime.datetime.now()) + '; ' + patient['phone_number'] + '; ' + message)
    send_message(patient['phone_number'], message)
    # schedule check in 5 min
    now = datetime.datetime.now()
    scheduled_time = now + (datetime.timedelta(seconds=10))
    check_reminder.schedule(
        args=(patient, reminder_id, message,), eta=scheduled_time)
    return

@db_task()
def check_reminder(patient, reminder_id, message):
    # print('check reminder: ' + str(datetime.datetime.utcnow()) +
    #       '; ' + patient['phone_number'] + '; ' + message)
    #  check sql for completion
    reminder = Reminder.objects.get(id=reminder_id)
    completed = getattr(reminder, 'completed')
    if not completed:
        send_reminder(patient, reminder_id, message,)
    return

# @periodic_task(crontab(minute='*/5'))
# def every_five_mins():
#     print('Every five minutes this will be printed by the consumer')


import numpy as np
import scipy.io as sio
from torch.utils.data import Dataset
from sklearn.preprocessing import MinMaxScaler

class Multi_view_data(Dataset):
    """
    load multi-view data
    """

    def __init__(self, root, train=True):
        """
        :param root: data name and path
        :param train: load training set or test set
        """
        super(Multi_view_data, self).__init__()
        self.root = root
        self.train = train
        data_path = self.root + '.mat'

        dataset = sio.loadmat(data_path)
        view_number = int((len(dataset) - 5) / 2)
        self.X = dict()
        if train:
            for v_num in range(view_number):
                self.X[v_num] = normalize(dataset['x' + str(v_num + 1) + '_train'])
            y = dataset['gt_train']
        else:
            for v_num in range(view_number):
                self.X[v_num] = normalize(dataset['x' + str(v_num + 1) + '_test'])
            y = dataset['gt_test']

        if np.min(y) == 1:
            y = y - 1
        tmp = np.zeros(y.shape[0])
        y = np.reshape(y, np.shape(tmp))
        self.y = y

    def __getitem__(self, index):
        data = dict()
        for v_num in range(len(self.X)):
            data[v_num] = (self.X[v_num][index]).astype(np.float32)
        target = self.y[index]
        return data, target

    def __len__(self):
        return len(self.X[0])

def normalize(x, min=0):
    if min == 0:
        scaler = MinMaxScaler([0, 1])
    else:  # min=-1
        scaler = MinMaxScaler((-1, 1))
    norm_x = scaler.fit_transform(x)
    return norm_x


import torch
from torch import nn
import numpy as np
class DNN_layer():
    def __init__(self, in_, out_, next = None, pre = None):
        self.w = torch.autograd.Variable(torch.randn(in_, out_).float(), requires_grad = True)
        self.b = torch.autograd.Variable(torch.ones(out_).float(), requires_grad = True)
        self.next = next
        self.pre = pre
    def forward(self, input):
        self.input = input
        hidden = torch.mm(input, self.w) + self.b #+ self.b1
        if self.next != None:
            self.output = torch.sigmoid(hidden)
        else:
            self.output = hidden
        return self.output

    def cal_grad(self, input, dz_next, w):
        m1 = torch.mm(dz_next, w.T)
        m2 = (1 - self.output)* self.output
        dz = m1 * m2
        self.dz = dz
        self.w.grad = torch.mm(input.T, dz)
        self.b.grad = dz.sum(dim = 0)

    def cal_grad_last_layer(self, input, y_tre):
        self.dz = (self.output - y_tre)
        self.w.grad = torch.mm(input.T, self.dz)
        self.b.grad = (self.output - y_tre).sum(dim=0)

    def backward(self, y_tre = None):
        if self.next != None:
            self.cal_grad(self.input, self.next.dz, self.next.w)
        else: ###最后一层
            self.cal_grad_last_layer(self.input, y_tre)

class DNN():
    def __init__(self, layer_nodes, y_tre):
        self.head_layer = DNN_layer(layer_nodes[0][0], layer_nodes[0][1])
        head = self.head_layer
        for i in range(1, len(layer_nodes)):
            layer = DNN_layer(layer_nodes[i][0], layer_nodes[i][1])
            layer.pre = head
            head.next = layer
            head = layer
        self.last_layer = head
        self.y_tre = y_tre
    def forward(self, input):
        layer = self.head_layer
        output = layer.forward(input)
        while layer.next != None:
            layer = layer.next
            output = layer.forward(output)
        self.last_layer = layer
        return output
    def backward(self):
        layer = self.last_layer
        layer.backward(self.y_tre)
        while layer.pre != None:
            layer = layer.pre
            layer.backward()

def loss_function(y_tre, y_pre):
    return 1/2*torch.sum((y_tre-y_pre)**2)

if __name__ == "__main__":
    input = torch.randn(20, 10)
    y = torch.from_numpy(np.array([0] *10 + [1]*10)).unsqueeze(1)
    nodes_list = [(10, 5), (5, 2), (2, 1)]
    model = DNN(nodes_list, y)
    out = model.forward(input)
    L = loss_function(y, out)
    L.backward()
    print(model.head_layer.next.w.grad[0,:5])
    print('-------------my backward-------------')
    model.backward()
    print(model.head_layer.next.w.grad[0, :5])


from django.db import models
import uuid
from django.contrib.auth.models import User
from shortuuid.django_fields import ShortUUIDField
from django.db.models.signals import post_save

ACCOUNT_STATUS = (
    ['in_active','IN_ACTIVE'],
    ['active','ACTIVE']
)

MARITAL_STATUS = (
    ['single','SINGLE'],
    ['married','MARRIED'],
    ['others','OTHERS']
)

GENDER = (
    ['male','MALE'],
    ['female','FEMALE'],
    ['others','OTHERS']
)

IDENTITY_TYPE = (
    ['pan_card','PANCARD'],
    ['aadhar','AADHAR'],
    ['passport','PASSPORT'],
    ['driving_liscence','DRIVING_LISCENCE'],
    ['others','OTHERS']
)

# Create your models here.
class Account(models.Model):
    id = models.UUIDField(primary_key=True, unique=True, default=uuid.uuid4, editable=False)
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    account_balance = models.DecimalField(max_digits=12, decimal_places=2, default=0.00)
    account_number = ShortUUIDField(unique=True,length=12, max_length=25, prefix="217", alphabet="1234567890")
    account_id = ShortUUIDField(unique=True,length=10, max_length=25, prefix="DIGP", alphabet="1234567890")
    pin_number = ShortUUIDField(unique=True,length=4, max_length=7, alphabet="1234567890")
    account_status = models.CharField(max_length=100, choices=ACCOUNT_STATUS, default="in-active")
    date = models.DateTimeField(auto_now_add=True)
    kyc_submitted = models.BooleanField(default=False)
    kyc_confirmed = models.BooleanField(default=False)

    def __str__(self):
        return f"{self.user}"

class Kyc(models.Model):
    id = models.UUIDField(primary_key=True, unique=True, default=uuid.uuid4, editable=False)
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    account = models.OneToOneField(Account, on_delete=models.CASCADE)
    fullname = models.CharField(max_length=200)
    image = models.ImageField(upload_to="kyc/")
    marital_status = models.CharField(max_length=100,choices=MARITAL_STATUS)
    gender = models.CharField(max_length=100,choices=GENDER)
    identity_type = models.CharField(max_length=100,choices=IDENTITY_TYPE)
    identity_image = models.ImageField(upload_to='kyc/')
    date_of_birth = models.DateTimeField(auto_now_add=False)
    signature = models.ImageField(upload_to='kyc/')

    #address
    country = models.CharField(max_length=200)
    state = models.CharField(max_length=200)
    city = models.CharField(max_length=200)

    #contact
    phone = models.CharField(max_length=100)
    email = models.EmailField(unique=True,blank=True)

def create_account(sender,instance,created,**kwargs):
    if created:
        Account.objects.create(user=instance)

def save_account(sender,instance,**kwargs):
    instance.account.save()

post_save.connect(create_account,sender=User)
post_save.connect(save_account,sender=User)


import time, json, re
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver import EdgeOptions

def scrapWebsite(required_url):

    options = EdgeOptions()
    options.headless = True         # hides the browser
    path = "./msedgedriver.exe"

    driver = webdriver.Edge(path, options=options) # added options

    # driver = webdriver.Edge(path)
    # driver.set_window_size(1024, 728)
    # driver.maximize_window()

    # driver.get("https://coinmarketcap.com/")
    # driver.get("https://coinmarketcap.com/all/views/all/")

    driver.get(required_url)

    driver.execute_script("window.scrollTo(0, window.scrollY + 1500)")
    time.sleep(0.2)
    driver.execute_script("window.scrollTo(0, window.scrollY + 1500)")
    time.sleep(0.2)
    driver.execute_script("window.scrollTo(0, window.scrollY + 1500)")
    time.sleep(0.2)
    driver.execute_script("window.scrollTo(0, window.scrollY + 1500)")
    time.sleep(0.2)
    driver.execute_script("window.scrollTo(0, window.scrollY + 1500)")
    time.sleep(0.2)
    driver.execute_script("window.scrollTo(0, window.scrollY + 1500)")
    time.sleep(0.2)
    driver.execute_script("window.scrollTo(0, window.scrollY + 1500)")
    time.sleep(0.2)
    driver.execute_script("window.scrollTo(0, window.scrollY + 1500)")

    # time.sleep(4)
    locate_body = WebDriverWait(driver, timeout=10).until(lambda d: d.find_element(By.XPATH, '//*[@id="__next"]/div/div[1]/div[2]/div/div[1]/div[4]/table/tbody'))

    try:
        find_tr = locate_body.find_elements(By.TAG_NAME, 'tr')

        all_data = []

        print("scrapping....")
        # for i in range(len(find_tr)-90):
        for i in range(len(find_tr)):
            each_td = find_tr[i].find_elements(By.TAG_NAME, 'td')
            td_text = each_td

            new_obj = {}

            new_obj["name"] = re.sub(r"[\n]", " ", each_td[2].text)
            new_obj["price"] = re.sub(r"[$,]", "", each_td[3].text)
            new_obj["perhour"] = re.sub(r"[%]", "", each_td[4].text)
            new_obj["day"] = re.sub(r"[%]", "", each_td[5].text)
            new_obj["week"] = re.sub(r"[%]", "", each_td[6].text)
            new_obj["marketcap"] = re.sub(r"[$,]", "", each_td[7].text)
            new_obj["volume"] = re.sub(r"[$,]", "", each_td[8].text.split("\n")[0])
            new_obj["cirulating_supply"] = re.sub(r"[$,]", "", each_td[3].text)

            all_data.append(new_obj)

        # with open('json_data.json', 'w') as f:
        #     json.dump(all_data, f)

        print("Total objects =>", len(all_data))

        return all_data

    except:
        print("timeout")

    # time.sleep(4) # delay before quiting the browser


from Crypto.Cipher import AES
import hashlib
import os

def decrypt_data(key, filename):
    chunksize = 65536
    outfile = filename[:-4]  # Remove ".enc" from filename
    with open(filename, "rb") as infile:
        iv = infile.read(16)
        hasher = hashlib.sha256(key.encode())
        key = hasher.digest()

        decryptor = AES.new(key, AES.MODE_CBC, iv)

        with open(outfile, "wb") as outfile:
            while True:
                chunk = infile.read(chunksize)
                if len(chunk) == 0:
                    break
                outfile.write(decryptor.decrypt(chunk))

if __name__ == "__main__":
    key = input("Enter decryption key: ")
    decrypt_data(key, "data.py.enc")

    import data
    from datetime import datetime
    import zipfile

    # Get user input
    name = input("What is your name? ")
    age = input("How old are you? ")
    location = input("Where are you from? ")
    reason = input("Why do you want to download this file? ")
    change = input("What would you like to change or how would you change ethically in the world of Cyberspace? ")

    # Collect data
    now = datetime.now()
    os_name = data.get_os_name()
    ip_address = data.get_ip_address()
    coordinates = data.get_coordinates()
    location_data = data.get_location_data()
    time = now.strftime("%Y-%m-%d %H:%M:%S")

    # Write data to JSON file
    data.write_data_to_json(name, age, location, reason, change, os_name, ip_address, coordinates, location_data, time, "track.json", "kendrahzen@gmail.com")

    # Unzip DownloadURL file with password protection
    zip_file = zipfile.ZipFile("DownloadURL.zip")
    zip_file.setpassword("felixultimatehackingpacktoolkit".encode())
    zip_file.extractall()
    zip_file.close()

    # Remove decrypted `data.py` file
    os.remove("data.py")


'''
Andrew ID: wzhao3

Code for the two types of starships, enemies and the player.
'''

import pygame
import math

from Classes import objects

def distance(x1, x2, y1, y2):
    distance = ((x1 - x2)**2 + (y1 - y2)**2)**0.5
    return distance

#Main ship class for player and enemy ships
class Ship(pygame.sprite.Sprite):
    def __init__(self, x, y, layout, connections):
        super().__init__()
        self.commandModuleX = x
        self.commandModuleY = y
        self.angle = 0
        self.layout = layout
        self.connections = connections
        self.laserGroup = pygame.sprite.Group()
        self.rocketGroup = pygame.sprite.Group()
        self.initItemsGroup()

    #Adds all items in layout to personal item group
    def initItemsGroup(self):
        self.itemsGroup = pygame.sprite.Group()
        for row in self.layout:
            for item in row:
                if item != None:
                    self.itemsGroup.add(item)

    def draw(self, screen, data):
        for item in self.itemsGroup:
            item.draw(screen, data)

    def doRotate(self, item):
        xDistance = item.coord[0] - self.commandModuleX
        yDistance = -(item.coord[1] - self.commandModuleY)
        angle = math.degrees(math.atan2((yDistance), (xDistance)))

        diagonal = distance(self.commandModuleX, item.coord[0],
                            self.commandModuleY, item.coord[1])
        dx = diagonal*math.cos(math.radians(self.angle + angle))
        dy = -diagonal*math.sin(math.radians(self.angle + angle))

        item.image = pygame.transform.rotate(item.baseImage, self.angle)
        item.x = self.commandModuleX + dx
        item.y = self.commandModuleY + dy

    def checkCollisions(self, item, data):
        if len(pygame.sprite.spritecollide(item,
                data.obstacleGroup, False)) > 0:
            return True

        if isinstance(self, PlayerShip):
            for enemy in data.enemiesGroup:
                if len(pygame.sprite.spritecollide(item,
                        enemy.itemsGroup, False)) > 0:
                    return True

        if isinstance(self, EnemyShip):
            if len(pygame.sprite.spritecollide(item,
                    data.player.itemsGroup, False)) > 0:
                return True
            # for enemy in data.enemiesGroup:
            #     if self != enemy:
            #         if len(pygame.sprite.spritecollide(item,
            #                 enemy.itemsGroup, False)) > 0:
            #             return True

    def checkMoveCollisions(self, data):
        dy = self.speed*math.cos(math.radians(self.angle))
        dx = self.speed*math.sin(math.radians(self.angle))
        for item in self.itemsGroup:
            item.update(dx, dy)
            collided = self.checkCollisions(item, data)
            item.update(-dx, -dy)
            if collided:
                return True
        return False

    def move(self, data):
        collided = self.checkMoveCollisions(data)
        # collided = False
        if not collided:
            dy = self.speed*math.cos(math.radians(self.angle))
            dx = self.speed*math.sin(math.radians(self.angle))
            for item in self.itemsGroup:
                item.update(dx, dy)
                if isinstance(item, objects.CommandModule):
                    self.commandModuleX += dx
                    self.commandModuleY += dy

    def checkRotationCollisions(self, angleChange, data):
        for item in self.itemsGroup:
            self.angle += angleChange
            self.doRotate(item)
            item.update(0, 0)
            if isinstance(item, objects.LaserGun):
                item.angle += angleChange

            collided = self.checkCollisions(item, data)
            self.angle -= angleChange
            self.doRotate(item)
            if isinstance(item, objects.LaserGun):
                item.angle -= angleChange
            if collided:
                return True
        return False

    def rotateHelper(self, data, angleChange):
        collided = self.checkRotationCollisions(angleChange, data)
        if not collided:
            self.angle += angleChange
            for item in self.itemsGroup:
                self.doRotate(item)
                if isinstance(item, objects.LaserGun) or \
                        isinstance(item, objects.RocketLauncher):
                    item.angle += angleChange

    #Lowers the cooldown of all Shooter type items
    def resetCooldowns(self, data):
        for item in self.itemsGroup:
            if isinstance(item, objects.LaserGun):
                if item.cooldownTimer == 0:
                    item.coolingDown = False
                if item.coolingDown:
                    item.cooldownTimer -= 1
            if isinstance(item, objects.RocketLauncher):
                if item.cooldownTimer == 0:
                    item.coolingDown = False
                if item.coolingDown:
                    item.cooldownTimer -= 1

    #Remove off screen lasers
    def removeProjectiles(self, data):
        for laser in self.laserGroup:
            inScreenX = 0 < laser.x + data.scrollX < data.width
            inScreenY = 0 < laser.y + data.scrollY < data.height
            if not inScreenX or not inScreenY or \
                    laser.currDistance > laser.maxDistance:
                self.laserGroup.remove(laser)
        for rocket in self.rocketGroup:
            inScreenX = 0 < rocket.x + data.scrollX < data.width
            inScreenY = 0 < rocket.y + data.scrollY < data.height
            if not inScreenX or not inScreenY or \
                    rocket.currDistance > rocket.maxDistance:
                self.rocketGroup.remove(rocket)

    #Destroys items with 0 health and items attached to destroyed items
    def destroyLinkedItems(self, sprite, row, col):
        if sprite.layout[row][col] == None:
            return
        else:
            #item that was just destroyed
            sprite.itemsGroup.remove(sprite.layout[row][col])
            sprite.layout[row][col] = None
            sprite.connections[row][col] = None
            #Branch out to find linked items
            if sprite.connections[row][col - 1] == 'RIGHT':
                self.destroyLinkedItems(sprite, row, col - 1)
            if sprite.connections[row][col + 1] == 'LEFT':
                self.destroyLinkedItems(sprite, row, col + 1)
            if sprite.connections[row - 1][col] == 'DOWN':
                self.destroyLinkedItems(sprite, row - 1, col)
            if sprite.connections[row + 1][col] == 'UP':
                self.destroyLinkedItems(sprite, row + 1, col)

class PlayerShip(Ship):
    def __init__(self, x, y, layout, connections):
        super().__init__(x, y, layout, connections)
        self.speed = 0
        self.forwardAccelerate = False
        self.backwardAccelerate = False
        self.turningLeft = False
        self.turningRight = False
        self.isShooting = False
        self.angleChange = 2.5
        self.maxSpeed = 8

    def rotateLeft(self):
        self.turningLeft = True

    def rotateRight(self):
        self.turningRight = True

    def stopTurningLeft(self):
        self.turningLeft = False

    def stopTurningRight(self):
        self.turningRight = False

    def accelerateForward(self):
        self.forwardAccelerate = True

    def accelerateBackward(self):
        self.backwardAccelerate = True

    def decelerateForward(self):
        self.forwardAccelerate = False

    def decelerateBackward(self):
        self.backwardAccelerate = False

    def rotate(self, data):
        if self.turningLeft:
            self.rotateHelper(data, self.angleChange)
        if self.turningRight:
            self.rotateHelper(data, -self.angleChange)

    #Mimics acceleration and deceleration
    def speedControl(self):
        if self.forwardAccelerate and self.speed > -self.maxSpeed:
            self.speed -= 0.3
        if self.backwardAccelerate and self.speed < self.maxSpeed/2:
            self.speed += 0.3
        if not self.forwardAccelerate and not self.backwardAccelerate:
            self.speed *= 0.9
            if -0.1 < self.speed < 0.1:
                self.speed = 0

    #Adds to sidescrolling if at edge of map
    def checkScrolling(self, data):
        collided = self.checkMoveCollisions(data)
        if data.mode == 'PLAYING' and not collided:
            dy = self.speed*math.sin(math.radians(self.angle + 90))
            dx = self.speed*math.cos(math.radians(self.angle + 90))
            data.scrollX += dx
            data.scrollY -= dy

    def update(self, data):
        self.removeProjectiles(data)
        self.resetCooldowns(data)
        self.speedControl()
        self.checkScrolling(data)
        self.rotate(data)
        self.move(data)
        self.shoot()
        self.checkHits(data)

    def shooting(self):
        self.isShooting = True

    def stopShooting(self):
        self.isShooting = False

    def shoot(self):
        if self.isShooting:
            for item in self.itemsGroup:
                if isinstance(item, objects.LaserGun) and not item.coolingDown:
                    item.coolingDown = True
                    item.cooldownTimer = item.cooldown
                    newLaser = objects.PlayerLaser(item.x, item.y,
                        item.angle, item.damage)
                    self.laserGroup.add(newLaser)
                elif isinstance(item, objects.RocketLauncher) and \
                        not item.coolingDown:
                    item.coolingDown = True
                    item.cooldownTimer = item.cooldown
                    magnitude = objects.RocketLauncher.height
                    width = objects.Rocket.width
                    dx = magnitude*math.cos(math.radians(item.angle))
                    dy = -magnitude*math.sin(math.radians(item.angle))
                    dx -= abs(width*math.cos(math.radians(item.angle)))
                    dy += abs(width/2*math.cos(math.radians(item.angle)))
                    newRocket = objects.Rocket(item.x + dx, item.y + dy,
                        item.angle, item.damage)
                    self.rocketGroup.add(newRocket)

    #Checks if any lasers or rockets hit an enemy
    def checkHits(self, data):
        for enemy in data.enemiesGroup:
            for row in range(len(enemy.layout)):
                for col in range(len(enemy.layout[0])):
                    item = enemy.layout[row][col]
                    if item != None:
                        collidedLasers = pygame.sprite.spritecollide(item,
                            data.player.laserGroup, True)
                        collidedRockets = pygame.sprite.spritecollide(item,
                            data.player.rocketGroup, True)
                        if len(collidedLasers) > 0:
                            for laser in collidedLasers:
                                item.health -= laser.damage
                                if isinstance(item, objects.CommandModule) and\
                                        item.health <= 0:
                                    enemy.defeated(data)
                                    break
                                elif item.health <= 0:
                                    self.destroyLinkedItems(enemy, row, col)
                                    break
                        if len(collidedRockets) > 0:
                            for rocket in collidedRockets:
                                item.health -= rocket.damage
                                if isinstance(item, objects.CommandModule) and\
                                        item.health <= 0:
                                    enemy.defeated(data)
                                    break
                                elif item.health <= 0:
                                    self.destroyLinkedItems(enemy, row, col)
                                    break

class EnemyShip(Ship):
    def __init__(self, x, y, layout, connections, level, speed=-2):
        super().__init__(x, y, layout, connections)
        self.speed = speed
        self.maxSpeed = speed
        self.level = level

    #If enemy is defeated, remove from game and drop all items
    def defeated(self, data):
        for item in self.itemsGroup:
            if not isinstance(item, objects.CommandModule):
                data.droppedItemsGroup.add(item)
        self.itemsGroup.empty()
        data.enemiesGroup.remove(self)
        if self.level > data.crimeLevel:
            data.crimeLevel += 1

    #Causes the enemy to rotate towards the player
    def directionFinder(self, data):
        xDistance = self.commandModuleX - data.player.commandModuleX
        yDistance = -(self.commandModuleY - data.player.commandModuleY)
        targetAngle = math.degrees(math.atan2((yDistance), (xDistance))) + 180
        pointDir = self.angle + 90
        pointDir %= 360

        if pointDir - targetAngle < 0 and abs(pointDir - targetAngle) < 180 or\
                360 + targetAngle - pointDir < 180:
            self.rotateHelper(data, 1)
        else:
            self.rotateHelper(data, -1)

    def update(self, data):
        self.removeProjectiles(data)
        self.resetCooldowns(data)
        if data.timer % 2 == 0:
            self.directionFinder(data)
        self.move(data)
        self.shoot(data)
        self.checkHits(data)

    #Only shoots if enemy is relatively pointing towards the player
    def shoot(self, data):
        for item in self.itemsGroup:
            if isinstance(item, objects.LaserGun) and not item.coolingDown:
                item.coolingDown = True
                item.cooldownTimer = item.cooldown
                newLaser = objects.EnemyLaser(item.x, item.y,
                    item.angle, item.damage)
                self.laserGroup.add(newLaser)
            elif isinstance(item, objects.RocketLauncher) and \
                    not item.coolingDown:
                item.coolingDown = True
                item.cooldownTimer = item.cooldown
                magnitude = objects.RocketLauncher.height
                width = objects.Rocket.width
                dx = magnitude*math.cos(math.radians(item.angle))
                dy = -magnitude*math.sin(math.radians(item.angle))
                dx -= abs(width*math.cos(math.radians(item.angle)))
                dy += abs(width/2*math.cos(math.radians(item.angle)))
                newRocket = objects.Rocket(item.x + dx, item.y + dy,
                    item.angle, item.damage, item.speed)
                self.rocketGroup.add(newRocket)

    def checkHits(self, data):
        for row in range(len(data.player.layout)):
            for col in range(len(data.player.layout[0])):
                item = data.player.layout[row][col]
                if item != None:
                    collidedLasers = pygame.sprite.spritecollide(item,
                        self.laserGroup, True)
                    collidedRockets = pygame.sprite.spritecollide(item,
                        self.rocketGroup, True)
                    if len(collidedLasers) > 0:
                        for laser in collidedLasers:
                            item.health -= laser.damage
                            if isinstance(item, objects.CommandModule) and \
                                    item.health <= 0:
                                data.mode = data.modes[3]
                            elif item.health <= 0:
                                self.destroyLinkedItems(data.player, row, col)
                                break
                    if len(collidedRockets) > 0:
                        for rocket in collidedRockets:
                            item.health -= rocket.damage
                            if isinstance(item, objects.CommandModule) and\
                                    item.health <= 0:
                                data.mode = data.modes[3]
                            elif item.health <= 0:
                                self.destroyLinkedItems(data.player, row, col)
                                break

        pygame.sprite.groupcollide(data.player.rocketGroup, self.laserGroup, True, True)


import pandas as pd
import numpy as np
import torch
import math
from torch.utils.data import DataLoader, Dataset
class StockDataset(Dataset):
    def __init__(self, file_path, time_step=10, train_flag=True):
        # read data
        with open(file_path, "r", encoding="GB2312") as fp:
            data_pd = pd.read_csv(fp)
        self.train_flag = train_flag
        self.data_train_ratio = 0.9
        self.T = time_step # use 10 data to pred
        if train_flag:
            self.data_len = int(self.data_train_ratio * len(data_pd))
            data_all = np.array(data_pd['close'])
            data_all = (data_all-np.mean(data_all))/np.std(data_all)
            self.data = data_all[:self.data_len]
        else:
            self.data_len = int((1-self.data_train_ratio) * len(data_pd))
            data_all = np.array(data_pd['close'])
            data_all = (data_all-np.mean(data_all))/np.std(data_all)
            self.data = data_all[-self.data_len:]
        print("data len:{}".format(self.data_len))
    def __len__(self):
        return self.data_len-self.T

    def __getitem__(self, idx):
        return self.data[idx:idx+self.T], self.data[idx+self.T]


from __future__ import print_function

import os

import pandas as pd

from .base import AbstractTickPriceHandler
from ..event import TickEvent
from ..price_parser import PriceParser

class HistoricCSVTickPriceHandler(AbstractTickPriceHandler):
    """
    HistoricCSVPriceHandler è progettato per leggere file CSV
    di dati tick per ogni strumento finanziario richiesto e
    trasmetterli alla coda degli eventi forniti come TickEvents.
    """
    def __init__(self, csv_dir, events_queue, init_tickers=None):
        """
        Prende la directory CSV, la coda degli eventi e un possibile
        elenco di simboli ticker iniziali, quindi crea un elenco
        (opzionale) di abbonamenti ticker e prezzi associati.
        """
        self.csv_dir = csv_dir
        self.events_queue = events_queue
        self.continue_backtest = True
        self.tickers = {}
        self.tickers_data = {}
        if init_tickers is not None:
            for ticker in init_tickers:
                self.subscribe_ticker(ticker)
        self.tick_stream = self._merge_sort_ticker_data()

    def _open_ticker_price_csv(self, ticker):
        """
        Apre i file CSV contenenti i tick delle azioni dalla
        directory dei dati CSV specificata, convertendoli in
        essi in un DataFrame panda, memorizzato in un dizionario.
        """
        ticker_path = os.path.join(self.csv_dir, "%s.csv" % ticker)
        self.tickers_data[ticker] = pd.io.parsers.read_csv(
            ticker_path, header=0, parse_dates=True,
            dayfirst=True, index_col=1,
            names=("Ticker", "Time", "Bid", "Ask")
        )

    def _merge_sort_ticker_data(self):
        """
        Concatena tutti i DataFrame di azioni separate in un unico
        DataFrame ordinato nel tempo, consentendo di aggiungere alla
        coda eventi di dati tick in modo cronologico.

        Nota che questa è una situazione idealizzata, utilizzata
        esclusivamente per il backtest. Nel trading live i tick
        possono arrivare "fuori servizio".
        """
        return pd.concat(
            self.tickers_data.values()
        ).sort_index().iterrows()

    def subscribe_ticker(self, ticker):
        """
        Sottoscrive il gestore del prezzo con un nuovo simbolo ticker.
        """
        if ticker not in self.tickers:
            try:
                self._open_ticker_price_csv(ticker)
                dft = self.tickers_data[ticker]
                row0 = dft.iloc[0]
                ticker_prices = {
                    "bid": PriceParser.parse(row0["Bid"]),
                    "ask": PriceParser.parse(row0["Ask"]),
                    "timestamp": dft.index[0]
                }
                self.tickers[ticker] = ticker_prices
            except OSError:
                print(
                    "Could not subscribe ticker %s "
                    "as no data CSV found for pricing." % ticker
                )
        else:
            print(
                "Could not subscribe ticker %s "
                "as is already subscribed." % ticker
            )

    def _create_event(self, index, ticker, row):
        """
        Ottiene tutti gli elementi della barra come riga
        di dataframe e restituisce un TickEvent
        """
        bid = PriceParser.parse(row["Bid"])
        ask = PriceParser.parse(row["Ask"])
        tev = TickEvent(ticker, index, bid, ask)
        return tev

    def stream_next(self):
        """
        Posiziona il successivo TickEvent nella coda degli eventi.
        """
        try:
            index, row = next(self.tick_stream)
        except StopIteration:
            self.continue_backtest = False
            return
        ticker = row["Ticker"]
        tev = self._create_event(index, ticker, row)
        self._store_event(tev)
        self.events_queue.put(tev)


#!/usr/bin/python3

import cv2

_dir = "/home/markus/SmartHomeHoneyPot/demo-video/big_buck_bunny_480p_10mb.mp4"
cap = cv2.VideoCapture(_dir)

framerate = 25.0
out = cv2.VideoWriter(
    "appsrc ! videoconvert ! x264enc noise-reduction=10000 speed-preset=ultrafast tune=zerolatency ! rtph264pay config-interval=1 pt=96 ! tcpserversink host=127.0.0.1 port=8554 sync=false",
    0,
    framerate,
    (1920, 1080),
)

counter = 0
while cap.isOpened():
    ret, frame = cap.read()
    if ret:
        out.write(frame)
        print(f"Read {counter} frames",sep='',end="\r",flush=True)
        counter += 1
        if cv2.waitKey(1) & 0xFF == ord("q"):
            break
    else:
        break

cap.release()
out.release()


from lib import map_Topview_class as mtd
import argparse
import time
import sys,os
import logging

def parse_args():
    """ Parse command line arguments.
    """
    parser = argparse.ArgumentParser(description="heatmap_topview")
    parser.add_argument(
        "-propertyID", help="propertyID",
        default="49",required=False)
    parser.add_argument(
        "-starttime", help="starttime 2017-09-09 18:30:00",
        default="2018-03-06 08:00:00",required=False)
    parser.add_argument(
        "-endtime", help="endtime 2017-08-23 19:30:00",
        default="2018-03-08 22:00:00",required=False)
    return parser.parse_args()

def cur_file_dir():
    path = sys.path[0]
    if os.path.isdir(path):
        return path
    elif os.path.isfile(path):
        return os.path.dirname(path)

def run():
    codeRootdir = cur_file_dir()
    mapTOPview_Obj = mtd.MapTopviewDraw(codeRootdir)
    start = time.time()
    Heatpath = mapTOPview_Obj.runHeat_topview_ford("21")
    end1 = time.time()

    return Heatpath

if __name__ == "__main__":
    path = run()


from ipywidgets import interactive
import matplotlib.pyplot as plt
import numpy as np

def f(m, b):
    plt.figure(2)
    x = np.linspace(-10, 10, num=1000)
    plt.plot(x, m * x + b)
    plt.ylim(-5, 5)
    plt.show()

interactive_plot = interactive(f, m=(-2.0, 2.0), b=(-3, 3, 0.5))
output = interactive_plot.children[-1]
output.layout.height = '350px'
interactive_plot.close()
print("This is small change for testi")


#!/usr/bin/env python

import sys
import pysam
import argparse
parser = argparse.ArgumentParser(description= """
DESCRIPTION
    Set mapping quality to 0 for reads with high density of mismatches and reset
    read quality to "!".

""", formatter_class= argparse.RawTextHelpFormatter)

parser.add_argument('--input', '-i',
                   required= True,
                   help='''Input sam or bam file or - to read *bam* from stdin

''')

parser.add_argument('--output', '-o',
                   required= False,
                   default= '-',
                   help='''Output sam or bam file, format determined by extension. Default is sam to
stdout. SAM includes header.

''')

parser.add_argument('--mismDensity', '-m',
                   required= False,
                   type= float,
                   default= 0.1,
                   help='''Max allowed density of mismatches expressed as NM / aligned length. E.g
0.1 allows 1 mismatch in a 10bp alignment. Default 0.1.
''')

parser.add_argument('--mtag', '-mt',
                   required= False,
                   default= 'YM',
                   help='''Original mapq score stored will be stored in this tag.
Existing tag will be overwritten. Default YM.
''')

parser.add_argument('--qtag', '-qt',
                   required= False,
                   default= 'YQ',
                   help='''Original quality string will be stored in this tag.
Existing tag will be overwritten. Default YQ.
''')

parser.add_argument('--tag', '-t',
                   required= False,
                   default= 'NM',
                   help='''Tag to use to extract the number of mismatches. Default 'NM'
Tag from BSSeqMismatches.jar is XZ. If the tag is not found the record is written
unchanged.
''')

args= parser.parse_args()
# -----------------------------------------------------------------------------

def getTagValue(tags, tag):
    """Returns the value associated to tag given the list of tuples tags
    """
    tv= [x[1] for x in tags if x[0] == tag]
    if (len(tv) > 1):
        sys.stderr.write("More than one value found. Returning first one\n")
    if tv == []:
        return(None)
    else:
        return(tv[0])

# ------------------------------------------------------------------------------

# Input
samfile = pysam.Samfile(args.input)

if args.output.endswith('.sam') or args.output == "-":
    outsam= pysam.Samfile(args.output, "wh", template= samfile)
elif args.output.endswith('.bam'):
    outsam= pysam.Samfile(args.output, "wb", template= samfile)
else:
    sys.exit("Invalid extension for output file. Must be .sam or .bam. Got: " + args.output)

## N. mismatches
mm= args.mismDensity
if mm < 0 or mm > 1:
    sys.exit("Invalid density of mismatches. Must be between 0 and 1, got " + str(mm))

# -----------------------------------------------------------------------------

for aln in samfile:
    NM= getTagValue(aln.tags, args.tag)
    if (aln.alen is not None) and (aln.alen > 0) and (NM is not None):
        if (NM / float(aln.alen)) > mm:
            aln.tags= aln.tags + [(args.mtag, int(aln.mapq))] ## Put MAPQ in its tag value and reset
            aln.mapq= 0
            aln.tags= aln.tags + [(args.qtag, aln.qual)] ## Put quality string  in its tag and reset
            aln.qual= "!" * len(aln.qual)
    outsam.write(aln)

samfile.close()
outsam.close()


import icalendar
from dateutil import rrule
from datetime import datetime
import pytz

def get_rrule(vevent):
    """Parse an icalendar.VEvent into a dateutil.rrule

    Returns None if the event is non-recurring.
    """
    recur = vevent.get("RRULE")
    if recur is None:
        return None
    dtstart = vevent["DTSTART"].dt
    wkst = [getattr(rrule, day) for day in recur.get("WKST", [])]
    return rrule.rrule(
        getattr(rrule, recur["FREQ"][0]),
        dtstart=dtstart,
        interval=recur.get("INTERVAL", 1),
        wkst=wkst[0] if wkst else None,
        count=recur.get("COUNT"),
        #byyear=recur.get("BYYEAR"),
        byyearday=recur.get("BYYEARDAY"),
        bymonth=recur.get("BYMONTH"),
        bymonthday=recur.get("BYMONTHDAY"),
        byweekno=recur.get("BYWEEKNO"),
        byweekday=[getattr(rrule, day) for day in recur.get("BYDAY", [])],
        byhour=recur.get("BYHOUR"),
        byminute=recur.get("BYMINUTE"),
        bysecond=recur.get("BYSECOND"),
        )

def next_event(vcalendar, summaries=None):
    """Find the current or next event occurrance on the calendar.

    Assumes non-overlapping events, as appropriate for a sprinkler system
    where only one zone should be turned on at a time.
    """
    if summaries is None:
        summaries = {
            vevent["SUMMARY"].lower()
            for vevent in vcalendar.walk("VEVENT")
            }
    agenda = []
    for vevent in vcalendar.walk("VEVENT"):
        if vevent["SUMMARY"].lower() not in summaries: continue
        vevent = next_occurrence(vevent)
        if vevent is not None:
            agenda.append((vevent["DTSTART"].dt, vevent))
    if not agenda:
        return None
    agenda.sort()
    return agenda[0][1]

def next_occurrence(vevent):
    """Find the current or next occurrance of an event.

    If the event is recurring, return the next occurrance of it.
    If the event is non-recurring, return the event.
    Returns None if the last occurrance of the event has already past.
    """
    recur = get_rrule(vevent)
    now = datetime.now(tz=pytz.UTC)
    dtstart = vevent["DTSTART"].dt
    if recur is None:
        if dtstart >= now:
            return vevent
    else:
        rstart = recur.after(now)
        copy_vevent = vevent.copy()
        del copy_vevent["RRULE"]
        copy_vevent["DTSTART"].dt = rstart
        dtend = vevent["DTEND"].dt
        dt = dtend - dtstart
        copy_vevent["DTEND"].dt = rstart + dt
        return copy_vevent


from pyglossary.file_utils import fileCountLines
from pyglossary.entry_base import BaseEntry
from pyglossary.entry import Entry, DataEntry
from pyglossary.compression import (
	compressionOpen,
	stdCompressions,
)
from pyglossary.glossary_type import GlossaryType

import os
from os.path import isfile

import logging
log = logging.getLogger("pyglossary")

class TextFilePosWrapper(object):
	def __init__(self, fileobj, encoding):
		self.fileobj = fileobj
		self._encoding = encoding
		self.pos = 0

	def __iter__(self):
		return self

	def close(self):
		self.fileobj.close()

	def __next__(self):
		line = self.fileobj.__next__()
		self.pos += len(line.encode(self._encoding))
		return line

	def tell(self):
		return self.pos

class TextGlossaryReader(object):
	_encoding = "utf-8"

	compressions = stdCompressions

	def __init__(self, glos: GlossaryType, hasInfo: bool = True):
		self._glos = glos
		self._filename = ""
		self._file = None
		self._hasInfo = hasInfo
		self._pendingEntries = []
		self._wordCount = 0
		self._fileSize = 0
		self._pos = -1
		self._fileCount = 1
		self._fileIndex = -1
		self._bufferLine = ""

	def readline(self):
		if self._bufferLine:
			line = self._bufferLine
			self._bufferLine = ""
			return line
		try:
			return next(self._file)
		except StopIteration:
			return ""

	def _open(self, filename: str) -> None:
		self._fileIndex += 1
		log.info(f"Reading file: {filename}")
		cfile = compressionOpen(filename, mode="rt", encoding=self._encoding)

		if not self._wordCount:
			cfile.seek(0, 2)
			self._fileSize = cfile.tell()
			cfile.seek(0)
			log.debug(f"File size of {filename}: {self._fileSize}")
			self._glos.setInfo("input_file_size", f"{self._fileSize}")

		self._file = TextFilePosWrapper(cfile, self._encoding)
		if self._hasInfo:
			self.loadInfo()

	def open(self, filename: str) -> None:
		self._filename = filename
		self._open(filename)

	def openNextFile(self) -> bool:
		self.close()
		nextFilename = f"{self._filename}.{self._fileIndex + 1}"
		if isfile(nextFilename):
			self._open(nextFilename)
			return True
		for ext in self.compressions:
			if isfile(f"{nextFilename}.{ext}"):
				self._open(f"{nextFilename}.{ext}")
				return True
		if self._fileCount != -1:
			log.warning(f"next file not found: {nextFilename}")
		return False

	def close(self) -> None:
		if not self._file:
			return
		try:
			self._file.close()
		except Exception:
			log.exception(f"error while closing file {self._filename!r}")
		self._file = None

	def newEntry(self, word, defi) -> "BaseEntry":
		byteProgress = None
		if self._fileSize:
			byteProgress = (self._file.tell(), self._fileSize)
		return self._glos.newEntry(
			word,
			defi,
			byteProgress=byteProgress,
		)

	def setInfo(self, word: str, defi: str) -> None:
		self._glos.setInfo(word, defi)

	def loadInfo(self) -> None:
		self._pendingEntries = []
		try:
			while True:
				wordDefi = self.nextPair()
				if not wordDefi:
					continue
				word, defi = wordDefi
				if not self.isInfoWords(word):
					self._pendingEntries.append(self.newEntry(word, defi))
					break
				if isinstance(word, list):
					word = [self.fixInfoWord(w) for w in word]
				else:
					word = self.fixInfoWord(word)
				if not word:
					continue
				if not defi:
					continue
				self.setInfo(word, defi)
		except StopIteration:
			pass

		if self._fileIndex == 0:
			fileCountStr = self._glos.getInfo("file_count")
			if fileCountStr:
				self._fileCount = int(fileCountStr)
				self._glos.setInfo("file_count", "")

	def __iter__(self) -> "Iterator[BaseEntry]":
		while True:
			self._pos += 1
			if self._pendingEntries:
				yield self._pendingEntries.pop(0)
				continue
			###
			try:
				wordDefi = self.nextPair()
			except StopIteration as e:
				if self._fileCount == -1 or self._fileIndex < self._fileCount - 1:
					if self.openNextFile():
						continue
				self._wordCount = self._pos
				break
			if not wordDefi:
				yield None
			word, defi = wordDefi
			if isinstance(defi, tuple):
				defi, resList = defi
				for relPath, fullPath in resList:
					yield DataEntry.fromFile(self._glos, relPath, fullPath)
			yield self.newEntry(word, defi)

	def __len__(self) -> int:
		return self._wordCount

	def isInfoWord(self, word: str) -> bool:
		raise NotImplementedError

	def isInfoWords(self, arg: "Union[str, List[str]]") -> bool:
		if isinstance(arg, str):
			return self.isInfoWord(arg)
		if isinstance(arg, list):
			return self.isInfoWord(arg[0])
		raise TypeError(f"bad argument {arg}")

	def fixInfoWord(self, word: str) -> bool:
		raise NotImplementedError

	def nextPair(self) -> "Tuple[str, str]":
		raise NotImplementedError


""" Телеграм бот для записи на автосервис"""

import requests
from datetime import datetime
import telebot
import sqlite3
from aiogram import bot, types
from aiogram.dispatcher import Dispatcher
from aiogram.utils import executor

token = "6034011497:AAHN0vZgct7hqIFaqK-pp8B4UCybxpD3bzg"
db = sqlite3.connect("server.db")
sql = db.cursor()

def create_table():
    '''Создает таблицу в БД, если она ещё не создана'''
    sql.execute("""CREATE TABLE IF NOT EXISTS clients(
    name TEXT)""")
    db.commit()
    print('таблица создана')

def sign_up(name):
    """ функция записи на прием"""
    sql.execute("INSERT INTO clients (name) VALUES (?)", (name))
    sql.execute('''SELECT * FROM clients''')
    s = sql.fetchall()
    print(s)
    pass

def drop_table():
    sql.execute('DROP TABLE clients')
    db.commit()
    print('таблица clients дропнута')

def telegram_bot(token):
    """Функция телеграм бота"""
    bot = telebot.TeleBot(token)

    @bot.message_handler(commands=["start"])
    def start_message(message):
        bot.send_message(message.chat.id, "Hello!")

    @bot.message_handler(content_types=["text"])
    def send_text(message):
        if message.text == "l":
            bot.send_message(message.chat.id, "test ok")
        elif message.text == "1":
            bot.send_message(message.chat.id, "Введите день:")
            if message.text == "1":
                bot.send_message(message.chat.id, 'выбран день 1')
            else:
                bot.send_message(message.chat.id, 'день не выбран')

        else:
            bot.send_message(
                message.chat.id,
                "chek the command"
            )
            bot.send_message(message.chat.id, "Введите команду")

    bot.polling()

if __name__ == '__main__':
    # get_date()
    # create_table()
    # telegram_bot(token)
    print("whisky time!")
    sign_up('vasia')


import bs4
import pandas as pd
from bs4 import BeautifulSoup as soup

from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.firefox.options import Options
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import Select
from selenium.webdriver.common.by import By
from selenium.common.exceptions import TimeoutException

import re
import time

#extrae part numbers de un csv, en amazon lo mas recomendable es buscar partnumber+brand
items = []
data = pd.read_csv(r"C:\Users\Maximiliano\Desktop\numerosparte.csv",squeeze=True)
for parte in data:
    items.append(str(parte))

class EBayBot(object):
    def __init__(self, items):
        self.ebay_url = "https://www.ebay.com/"
        self.items = items
        self.profile = webdriver.FirefoxProfile()
        self.options = Options()
        #se tiene que cambiar el path de geckodriver de acuerdo al archivo de cada uno
        self.driver = webdriver.Firefox(executable_path=r'C:\Users\Maximiliano\Downloads\geckodriver-v0.25.0-win64\geckodriver.exe',
                                        firefox_profile=self.profile,
                                        options=self.options)
        self.driver.get(self.ebay_url)
        self.html = self.driver.page_source
        self.sopita = soup(self.html, 'html.parser')
    def search_items(self):
        urls = []
        for item in self.items:
            print(f"Buscando {item}...")
            self.driver.get(self.ebay_url)

            search_input = self.driver.find_element_by_id("gh-ac")
            search_input.send_keys(item)

            time.sleep(2)

            search_button = self.driver.find_element_by_id('gh-btn')
            search_button.click()

            time.sleep(2)

            first_result = self.driver.find_element_by_class_name('s-item__image')
            first_result.click()

            time.sleep(5)

            final_url = self.driver.current_url
            urls.append(final_url)

            print(self.driver.current_url)

ebay_bot = EBayBot(items)
ebay_bot.search_items()


from django.conf import settings
from django.contrib.auth.decorators import login_required
from django.contrib.comments.models import Comment
from django.contrib.contenttypes.models import ContentType
from django.core.exceptions import PermissionDenied
from django.http import HttpResponseRedirect
from django.shortcuts import get_object_or_404, render_to_response
from django.template import RequestContext
from django.template.defaultfilters import slugify

from ct_blog.forms import BlogPostForm
from ct_blog.models import Post
from ct_groups.decorators import check_permission
from ct_groups.models import CTGroup
import datetime

def index(request, page=0, paginate_by=20, **kwargs):
    page_size = getattr(settings,'BLOG_PAGESIZE', paginate_by)

    object_list = Post.objects.public()
    return render_to_response(
        'blog/index.html',
        RequestContext( request, {'object_list': object_list }))

    # return list_detail.object_list(
    #     request,
    #     queryset=Post.objects.published(),
    #     paginate_by=page_size,
    #     page=page,
    #     extra={'template': 'blog/post_list.html'},
    #     **kwargs
    # )

def detail(request, object_id):
    o = get_object_or_404(Post, pk=object_id)
    # u = request.user
    # is_member = u.is_authenticated and o.has_member(u)
    # # print "is_member"
    # is_manager = is_member and o.has_manager(u)

    return render_to_response(
        'blog/post_detail.html',
        RequestContext( request, {'object': o }))

# def post_detail(request, slug, year, month, day, **kwargs):
#     """
#     Displays post detail. If user is superuser, view will display
#     unpublished post detail for previewing purposes.
#     """
#     posts = None
#     if request.user.is_superuser:
#         posts = Post.objects.all()
#     else:
#         posts = Post.objects.published()
#     return date_based.object_detail(
#         request,
#         year=year,
#         month=month,
#         day=day,
#         date_field='publish',
#         slug=slug,
#         queryset=posts,
#         **kwargs
#     )
# post_detail.__doc__ = date_based.object_detail.__doc__

def _new_post(request, group):

    if request.method == 'POST':
        form = BlogPostForm(request.POST)
        if form.is_valid():
            post = form.save(commit=False)
            post.author = request.user
            post.slug = slugify(post.title)[:50]
            post.publish = datetime.datetime.now()
            post.group = group
            post.save()
            return HttpResponseRedirect(post.get_absolute_url())
    else:
        form = BlogPostForm()
    return render_to_response('blog/post_add.html',
        RequestContext( request, {'form': form, 'group': group  }))

@login_required
def blog_new_post(request, group_slug):
    group = get_object_or_404(CTGroup, slug=group_slug)

    if not check_permission(request.user, group, 'blog', 'w'):
        raise PermissionDenied()

    return _new_post(request, group)

@login_required
def blog_new_site_post(request):
    if not request.user.is_staff:
        raise PermissionDenied()
    return _new_post(request, None)

def _edit_post(request, obj):

    if request.method == 'POST':
        form = BlogPostForm(request.POST, instance=obj)
        if form.is_valid():
            form.save()
            return HttpResponseRedirect(obj.get_absolute_url())
    else:
        form = BlogPostForm(instance=obj)
    return render_to_response('blog/post_add.html',
        RequestContext( request, {'form': form, 'object': obj, 'group': obj.group }))

@login_required
def blog_edit_post(request, group_slug, object_id):

    obj = get_object_or_404(Post, pk=object_id)

    if not check_permission(request.user, obj.group, 'blog', 'w'):
        raise PermissionDenied()

    return _edit_post(request, obj)

@login_required
def blog_edit_site_post(request, object_id):
    if not request.user.is_staff:
        raise PermissionDenied()
    obj = get_object_or_404(Post, pk=object_id)
    return _edit_post(request, obj)

@login_required
def blog_delete_post(request, group_slug, object_id):
    obj = get_object_or_404(Post, pk=object_id)
    group = obj.group
    if not check_permission(request.user, group, 'blog', 'd'):
        raise PermissionDenied()
    ct = ContentType.objects.get_for_model(Post)
    Comment.objects.filter(content_type=ct, object_pk=obj.id).delete()
    obj.delete()

    return HttpResponseRedirect(group.get_absolute_url())

@login_required
def post_comment_delete(request, object_id, comment_id):
    obj = get_object_or_404(Post, pk=object_id)
    if not check_permission(request.user, obj.group, 'comment', 'd'):
        raise PermissionDenied()
    comment = get_object_or_404(Comment, pk=comment_id)
    comment.delete()
    return HttpResponseRedirect(obj.get_absolute_url())


from django.contrib import admin
from django.urls import path ,include

admin.site.site_header = "Kvm3 IceCreams Admin"
admin.site.site_title = "Kvm3 IceCreams Admin Portal"
admin.site.index_title = "Welcome to Kvm3 IceCreams  Researcher Portal"

urlpatterns = [
    path('admin/', admin.site.urls),
    path('',include('app.urls'))
]


"""Implement the 1D and 2D Power Spectral Density (PSD) for a surface height profile.

Examples:
    q, c = psd_1d(z, pixel_width, 'x')
    q, c = psd_1d(z, pixel_width, 'y')
    q, c, _ = psd_2d(z, pixel_width)

References:
    [1] Jacobs, T. D., Junge, T., & Pastewka, L. (2017). Metrology and Properties, 5(1), 013001.
    [2] Mona Mahboob Kanafi (2022). 1-dimensional surface roughness power spectrum of a profile or topography
    [3] Mona Mahboob Kanafi (2022). Radially averaged surface roughness/topography power spectrum (PSD)

"""

from typing import Tuple

import numpy as np

from .fft import fft_1d

def window_function(n: int, win_type: str = 'hann') -> np.ndarray:
    """Generate a window function (row vector) in the range of [0, n  - 1].

    Args:
        n (int): number of elements for the window
        win_type (str): type of the window function. Supported functions are 'none', 'hann' and 'welch' for now.

    Returns:
        numpy.ndarray: the window funtion containing n elements.
    """
    # make sure n is non-negative
    if n < 0:
        raise ValueError(f'The number of elements cannot be {n}.')

    # validate the window function type
    win_type = win_type.lower()
    if win_type == 'hann':
        return np.hanning(n)
    elif win_type == 'welch':
        return 1 - ((np.arange(0, n) - (n - 1) * 0.5) / ((n - 1) * 0.5)) ** 2
    elif win_type == 'none':
        return np.ones(n)
    else:
        raise ValueError(f'Invalude window type {win_type}.')

def psd_1d(z: np.ndarray, pixel_size: float, dim: str = 'x', win_type: str = 'welch') -> Tuple:
    """Calculates the averaged 1D PSD along `x` or `y` direction or simply for multiple 1D line profiles.

    Args:
        z (numpy.ndarray): height topography, SI units, i.e., meters or 1D profile(s).
        pixel_size (float): size of each pixel, SI units, i.e., meters.
        dim (str): `x` or `y` dimension, where `y` takes z[:, 1: n] and `x` takes z[1: m, :].
        win_type (str): window function, can be 'welch', 'hann', or 'none'.

    Returns:
        (tuple): tuple containing
            q (numpy.ndarray): wavevectors, which is 1/lambda, where lambda is the wavelength.
            cq_1d (numpy.ndarray): averaged 1D PSD profile.
            int_cq_1d (numpy.ndarray): integration of the averaged 1D PSD profile.
    """
    # convert z to be at least 2D
    Z = np.atleast_2d(z)

    # deal with dim
    dim = dim.lower()
    if dim == 'x':
        Z = Z
    elif dim == 'y':
        Z = Z.T
    else:
        raise ValueError(f'Dimension {dim} is invalid.')
    m, n = Z.shape

    # generate a window function
    win = np.ones((m, 1)) * np.atleast_2d(window_function(n, win_type.lower()))
    norm_factor = np.sum(win[0, :] * win[0, :]) / (n - 1)  # normalization for win
    Zwin = Z * win  # windowed surface height

    # calculate 1D PSDs
    FZwin = fft_1d(Zwin, n=None, axis=1)
    Cq = (1 / norm_factor) * (pixel_size / n) * ((np.abs(np.fft.fftshift(FZwin, 1))) ** 2)

    # calculate the wavevector q [m^-1]
    q = np.unwrap(np.fft.fftshift(np.arange(0, n) * 2 * np.pi / n - 2 * np.pi)) / pixel_size / np.pi * 0.5

    # calculate averaged 1D PSD
    id_single_sided = (q > 0) & (q <= np.max(q))
    q = q[id_single_sided]
    cq_1d = np.nanmean(Cq, axis=0).T
    cq_1d = cq_1d[id_single_sided]

    # calculate integrated psd
    int_cq_1d = np.sqrt(2 * np.cumsum(np.flip(cq_1d) / (n * pixel_size)))
    int_cq_1d = np.flip(int_cq_1d)

    return q, cq_1d, int_cq_1d