import os
import json
import shutil
import compress_json
import dateparser
import pandas as pd
import numpy as np
from numba import typed, types
import warnings
from datetime import datetime
from userinput.utils import closest
from tqdm.auto import tqdm
from multiprocessing import Pool, cpu_count
from typing import Dict, Generator, List, Tuple
from .utils import get_available_genomes, get_available_chromosomes, download_chromosome_wrapper, get_genome_informations
from .utils import multiprocessing_gaps
from .utils import extract_sequence, extract_sequences

class Genome:
    """Class to automatically retrieve informations and sequences for a Genome from the UCSC Genome Browser assembly database.

    Usage examples
    --------------

    Simply instanziate a new genome
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    .. code:: python

        from ucsc_genomes_downloader import Genome
        hg19 = Genome("hg19")

    Getting gaps regions
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    .. code:: python

        all_gaps = hg19.gaps() # Returns gaps for all chromosomes
        # Returns gaps for chromosome chrM
        chrM_gaps = hg19.gaps(chromosomes=["chrM"])

    Getting filled regions
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    .. code:: python

        all_filled = hg19.filled() # Returns filled for all chromosomes
        # Returns filled for chromosome chrM
        chrM_filled = hg19.filled(chromosomes=["chrM"])

    Removing genome's cache
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    .. code:: python

        hg19.delete()

    """

    def __init__(
        self,
        assembly: str,
        chromosomes: Tuple[str] = None,
        filters: Tuple[str] = ("chru", "chrmt", "scaffold", "contig", "super", "chrbin", "random", "hap", "alt", "fix"),
        verbose: bool = True,
        cache_directory: str = "genomes"
    ):
        """Instantiate a new Genome object.

        Parameters
        ----------
        assembly: str,
            UCSC Genome Browser assembly ID for required genome [1]_.
        chromosomes: Tuple[str] = None,
            Tuple with the chromosomes to download.
            If None (default) all the chromosomes except
            the one filtered out are downloaded.
        filters: Tuple[str] = ("chru", "scaffold", "contig", "super", "chrbin", "random", "hap", "alt", "fix"),
            Tuple containing substring of chromosomes NOT to download.
            If the `chromosomes` parameter is used, no such filter is applied.
        verbose: bool = True,
            Whetever to show a loading bar when retrieving chromosomes.
        cache_directory: str = "genomes",
            Position where to store the downloaded genomes.

        Raises
        ------
        ValueError:
            If the given genome cannot be retrieved either from the given
            cache directory or from the UCSC website [3]_.
        ValueError:
            If the given genome, once the filters have been applied,
            does not contain any chromosome.

        Returns
        -------
        A newly instantiated Genome object.

        References
        ----------
        .. [1] https://genome.ucsc.edu/FAQ/FAQdownloads.html
        """

        self._chromosomes_lenghts = None
        self._genome_informations = None
        self._verbose = verbose
        self._assembly = assembly

        self._cache_directory = os.path.join(cache_directory, self.assembly)

        # If cache is enabled and a directory for the genome
        # exists within the cache we try to load the genome data
        if os.path.exists(self._cache_directory):
            self._genome_informations = self._load_genome_informations()
            self._chromosomes_lenghts = self._load_chromosomes()
        # Otherwise we check if the genome is available
        else:
            available_genomes = get_available_genomes()
            if self.assembly not in available_genomes:
                # If the genome is not available we raise a proper exception
                raise ValueError(
                    (
                        "Given genome {assembly} is not within the available genomes. "
                        "Did you mean to specify the {closest} genomic assembly?"
                    ).format(
                        assembly=self.assembly,
                        closest=closest(
                            self.assembly,
                            available_genomes
                        )
                    ))

        # Download genome informations if list is not already loaded
        if self._genome_informations is None:
            self._genome_informations = get_genome_informations(self.assembly)
            # If cache is enabled we store the obtained genome informations
            self._store_genome_informations()

        # Download chromosomes if list is not already loaded
        if self._chromosomes_lenghts is None:
            self._chromosomes_lenghts = get_available_chromosomes(
                self.assembly)
            # If cache is enabled we store the obtained chromosomes lenghts
            self._store_chromosomes()

        # Filtering chromosomes
        self._chromosomes = typed.Dict.empty(
            types.unicode_type,
            types.unicode_type
        )
        for chrom in self._chromosomes_lenghts:
            if all(target not in chrom.lower() for target in filters) and chromosomes is None or chromosomes is not None and chrom in chromosomes:
                self._chromosomes[str(chrom)] = ""

        # If no chromosome remains after filtering,
        # for instance when the raw data are not yet mapped
        # we raise a userwarning
        if len(self) == 0:
            raise ValueError(
                "No chromosome remaining in chosen genome {assembly}"
                "after executing desired filters"
                "and checking for online availability".format(
                    assembly=self.assembly)
            )

        self.NUCLEOTIDES_MAPPING = typed.Dict.empty(types.string, types.string)

        for src, dst in {
            "a": "t",
            "A": "T",
            "g": "c",
            "G": "C",
            "t": "a",
            "T": "A",
            "c": "g",
            "C": "G",
            "N": "n",
            "n": "N",
        }.items():
            self.NUCLEOTIDES_MAPPING[src] = dst

        self._download()
        self._load()

    def _genome_informations_path(self) -> str:
        """Return path for the JSON file with current genome informations."""
        return "{cache_directory}/genome_informations.json".format(
            cache_directory=self._cache_directory
        )

    def _load_genome_informations(self) -> Dict:
        """Return a dictionary with genome informations if available.

        Raises
        ------
        RuntimeWarning:
            If genome informations are not available
            locally.
        """
        try:
            compress_json.load(self._genome_informations_path())
        except Exception:
            warnings.warn(
                "Failed to load genome {genome} informations. "
                "I will try to download them again afterwards.".format(
                    genome=self.assembly
                ),
                RuntimeWarning
            )
        return None

    def _store_genome_informations(self):
        """Store genome informations into default cache directory."""
        compress_json.dump(
            self._genome_informations,
            self._genome_informations_path()
        )

    def _chromosomes_path(self) -> str:
        """Return path to default chromosomes informations."""
        return "{cache_directory}/chromosomes.json".format(
            cache_directory=self._cache_directory
        )

    def _load_chromosomes(self) -> Dict:
        """Return a dictionary with genome chromosomes if available.

        Raises
        ------
        RuntimeWarning:
            If genome chromosomes are not available
            locally.
        """
        try:
            return compress_json.load(self._chromosomes_path())
        except Exception:
            warnings.warn(
                "Failed to load chromosomes for genome {genome}. "
                "I will try to download them again afterwards.".format(
                    genome=self.assembly
                ),
                RuntimeWarning
            )
        return None

    def _store_chromosomes(self):
        """Store chromosomes informations into default cache directory."""
        compress_json.dump(
            self._chromosomes_lenghts,
            self._chromosomes_path()
        )

    def _chromosome_path(self, chromosome: str) -> str:
        """Return path to the given chromosome.

        Parameters
        ----------
        chromosome: str,
            The chromosome identifier, such as chr1, chrX, chrM...
        """
        return "{cache_directory}/chromosomes/{chromosome}.json.gz".format(
            cache_directory=self._cache_directory,
            chromosome=chromosome
        )

    def _load_chromosome(self, chromosome: str) -> str:
        """Return the nucleotides sequence for the given chromosome.
        Parameters
        ----------
        chromosome: str,
            The chromosome identifier, such as chr1, chrX, chrM...

        Raises
        ------
        RuntimeWarning:
            If given chromosome are not available locally.
        """
        path = self._chromosome_path(chromosome)
        try:
            return compress_json.load(path)["dna"]
        except json.decoder.JSONDecodeError:
            os.remove(path)
            raise Exception(
                "Chromosome at path {path} is corrupt and has been deleted.".format(path=path))

    def delete(self):
        """Remove the genome cache."""
        if os.path.exists(self._cache_directory):
            shutil.rmtree(self._cache_directory)

    def _download(self):
        """Download the missing chromosomes."""
        tasks = [
            {
                "assembly": self.assembly,
                "chromosome": chromosome,
                "start": 0,
                "end": self._chromosomes_lenghts[chromosome],
                "path": self._chromosome_path(chromosome)
            }
            for chromosome in self
            if not self.is_chromosome_cached(chromosome)
        ]
        if len(tasks):
            with Pool(min(cpu_count(), len(tasks))) as p:
                list(tqdm(
                    p.imap(
                        download_chromosome_wrapper,
                        tasks
                    ),
                    desc="Downloading chromosomes for genome {assembly}".format(
                        assembly=self.assembly
                    ),
                    total=len(tasks),
                    disable=not self._verbose,
                    dynamic_ncols=True,
                    leave=False
                ))
                p.close()
                p.join()

    def _load(self):
        """Load into memory all the genome's chromosomes, downloading them when necessary."""
        for chromosome in tqdm(
            self,
            desc="Loading chromosomes for genome {assembly}".format(
                assembly=self.assembly
            ),
            total=len(self),
            disable=not self._verbose,
            dynamic_ncols=True,
            leave=False
        ):
            self._chromosomes[chromosome] = self._load_chromosome(
                chromosome
            )

    def __len__(self) -> int:
        """Return the number of chromosomes in current genome."""
        return len(self._chromosomes)

    def __contains__(self, chromosome: str) -> bool:
        """Return boolean representing if given chromosome is contained in current genome.

        Parameters
        ----------
        chromosome: str,
            The chromosome identifier, such as chr1, chrX, chrM...

        Returns
        -------
        Boolean representing if given chromosome is contained in current genome.
        """
        return chromosome in self._chromosomes

    def __getitem__(self, chromosome: str):
        """Return sequence data for given chromosome.

        Parameters
        ----------
        chromosome: str,
            The chromosome identifier, such as chr1, chrX, chrM...

        Returns
        -------
        String containing sequence data for given chromosome.
        """
        return self._chromosomes[chromosome]

    def items(self) -> Generator:
        """Return generator to iterate through tuples of chromosomes and corresponding sequences."""
        for chromosome in self:
            yield chromosome, self[chromosome]

    def __iter__(self) -> Generator:
        """Return generator to iterate through the genome's chromosomes."""
        for chromosome in self._chromosomes:
            yield chromosome

    def is_chromosome_cached(self, chromosome: str) -> bool:
        """Return a boolean representing if given chromosome is cached.

        Parameters
        ----------
        chromosome: str,
            The chromosome identifier, such as chr1, chrX, chrM...

        Returns
        -------
        Boolean representing if given chromosome is available locally.
        """
        return os.path.exists(self._chromosome_path(chromosome))

    def __str__(self):
        """Return string representation of current genome."""
        return "{organism}, {scientific_name}, {genome}, {date}, {chromosomes} chromosomes".format(
            organism=self.organism,
            scientific_name=self.scientific_name,
            genome=self.assembly,
            date=self.date,
            chromosomes=len(self)
        )

    __repr__ = __str__

    def gaps(self, chromosomes: List[str] = None):
        """Return dataframe in BED format with informations on the gaps.

        Parameters
        ----------
        chromosomes: List[str] = None,
            List of the chromosomes to parse, by default all.

        FAQs
        ----
        Why don't you just retrieve the gaps from the APIs?
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        The gaps track is not always available, therefore for providing a consistent
        usage experience we compute the gaps when required. Additionally, this method
        will work also when you make an offline request, that may sometimes be quite
        useful.

        Returns
        -------
        A DataFrame in BED format containing the gapped regions.
        """
        if chromosomes is None:
            chromosomes = list(self)
        with Pool(min(cpu_count(), len(self))) as p:
            gaps = pd.concat(list(tqdm(
                p.imap(multiprocessing_gaps, (
                    (
                        chromosome, self[chromosome]
                    )
                    for chromosome in chromosomes
                )),
                total=len(chromosomes),
                desc="Rendering gaps in {assembly}".format(
                    assembly=self.assembly
                ),
                leave=False,
                dynamic_ncols=True,
                disable=not self._verbose
            ))).reset_index(drop=True)
            p.close()
            p.join()
        return gaps

    def filled(self,  chromosomes: List[str] = None):
        """Return dataframe with BED-like columns with informations on the gaps.

        Parameters
        ----------
        chromosomes: List[str] = None,
            List of the chromosomes to parse, by default all.

        Returns
        -------
        A DataFrame in BED format containing the filled regions.
        """
        non_gap = []
        gapped_chromosomes = []
        if chromosomes is None:
            chromosomes = list(self)
        for chrom, values in self.gaps(chromosomes).groupby("chrom"):
            # We need to sort by the chromStart
            # as we will need the rows to be ordered
            # to be able to generate the complementary windows
            values = values.sort_values(["chromStart"])
            non_gap_values = pd.DataFrame({
                "chrom": chrom,
                "chromStart": values["chromEnd"][:-1].values,
                "chromEnd": values["chromStart"][1:].values,
            })

            # If the chromosome lenght is not contained
            # within the various chromEnd values it means that
            # the final part of the chromosome is known
            # and therefore considered filled.
            # We need to add this additional row.
            chromosome_lenght = self._chromosomes_lenghts[chrom]
            if not values.chromEnd.isin([chromosome_lenght]).any():
                non_gap_values = non_gap_values.append({
                    "chrom": chrom,
                    "chromStart": values.chromEnd.max(),
                    "chromEnd": chromosome_lenght
                }, ignore_index=True)

            # If the chromosome start, the 0 value,
            # is not contained within the various chromStart values
            # it means that the initial part of the chromosome
            # is known and therefore considered filled.
            # We need to add this additional row.
            if not values.chromStart.isin([0]).any():
                non_gap_values = non_gap_values.append({
                    "chrom": chrom,
                    "chromStart": 0,
                    "chromEnd": values.chromStart.min(),
                }, ignore_index=True)

            non_gap.append(non_gap_values)
            gapped_chromosomes.append(chrom)

        # When a chromosome does not appear to have
        # any gap is considered fully filled
        non_gap.append(pd.DataFrame([
            {
                "chrom": chrom,
                "chromStart": 0,
                "chromEnd": self._chromosomes_lenghts[chrom]
            } for chrom in chromosomes if chrom not in gapped_chromosomes
        ]))
        return pd.concat(non_gap).sort_values(["chrom"]).reset_index(drop=True)

    def extract_sequence(self, chrom: str, chromStart: int, chromEnd: int, strand: str = ".") -> str:
        """Return genomic sequence for given coordinates.

        Parameters
        ------------------------------------
        chrom: str,
            Chromosome to use.
        chromStart: int,
            Position from where to start slicing.
        chromEnd: int,
            Position where to stop the slice.

        Returns
        -------------------------------------
        Sequence of nucleotides.
        """
        return extract_sequence(
            self._chromosomes,
            chrom,
            chromStart,
            chromEnd,
            strand,
            self.NUCLEOTIDES_MAPPING
        )

    def bed_to_sequence(self, bed: pd.DataFrame) -> List[str]:
        """Return bed with an additional column containing the sequences."""
        return extract_sequences(
            self._chromosomes,
            bed.chrom.values.astype(str),
            bed.chromStart.values.astype(int),
            bed.chromEnd.values.astype(int),
            bed.strand.values.astype(str) if "strand" in bed.columns else None,
            self.NUCLEOTIDES_MAPPING
        )

    @property
    def assembly(self) -> str:
        """Return genome's UCSC Genome Browser assembly ID."""
        return self._assembly

    @property
    def date(self) -> datetime:
        """Return release date."""
        return dateparser.parse(self.description.split("(")[0]).date()

    @property
    def organism(self) -> str:
        """Return genome's organism."""
        return self._genome_informations["organism"]

    @property
    def scientific_name(self):
        """Return genome's organism scientific name."""
        return self._genome_informations["scientificName"]

    @property
    def description(self):
        """Return genome's description as provided by UCSC."""
        return self._genome_informations["description"]

    @property
    def path(self):
        """Return genome's path."""
        return self._cache_directory


""" A message dispatcher.

This is a module for a message dispatcher
for both incoming messages and outgoing messages.
However, the outgoing message dispatcher is not in used.

@author: Thanakorn Sueverachai
"""

import logging
import threading
import zmq

from NetworkSearch2.QuerySubsystem.echoMessage import ECHOMessage

# for profiling
from NetworkSearch2.ProfileTools.myProfiler import Profiler
import time

#############################
# read a configuration file #
#############################
from ConfigParser import SafeConfigParser
from sys import path

confparser = SafeConfigParser()
confparser.read([str(path[0])+'/config.cfg'])

# get values
DISPATCHER_PORT = confparser.getint('Dispatcher','dispatcher_port')

del confparser

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

class IncomingDispatcher(threading.Thread):
    """ A thread that receives incoming messages, multiplexes
    and load-balances to workers (echoProcesses)."""

    def __init__(self,process_queue_list):
        # base class initialization
        super(IncomingDispatcher,self).__init__()

        self.process_queue_list = process_queue_list
        self.Nprocess = len(process_queue_list)

        # open message receiving socket.
        self.context = zmq.Context()
        self.receiver = self.context.socket(zmq.PULL)
        self.receiver.bind("tcp://*:"+str(DISPATCHER_PORT))

        logging.info("Incoming dispatcher initiated Successfully.")

    def run(self):
        """ Override method run() in a Thread"""

        #assign function addresses locally
        dispatch = self.dispatch
        receiver = self.receiver

        while 1:
            #receive a digested message from other nodes
            digested_message = receiver.recv()

            dispatch(ECHOMessage.deserialize(digested_message))

    def dispatch(self, echoMessage):
        """ dispatch a message to a echoProcess worker based on load-balancing scheme."""

        if Profiler.enabled:
            Profiler.send_data(('transmission_of_msg_type_%i' % echoMessage.get_type()),time.time()-echoMessage.t0)
            # re-measure t0 for queuing time
            echoMessage.t0 = time.time()

        #TODO: add proper load balancing. For now, use id%Nprocess
        invoke_id = echoMessage.get_id()
        # send to a queue
        self.process_queue_list[invoke_id%self.Nprocess].put(echoMessage)

        #print "{}".format(self.process_queue_list[0].qsize())

        #Correct load balance
#         #TODO: need a capped dict, reduce CPU usage or come up with the new idea to LB
#         try:
#             # send to the queue in case of its invoke id has been visited before
#             self.process_queue_list[self.multiplex_table[invoke_id]].put(echoMessage)
#         except KeyError:
#             # send to a queue by apply load balancing
#             #TODO: what if all queue empty all the time
#             min_queue = min(self.process_queue_list, key=lambda x: x.qsize())
#             min_queue.put(echoMessage)
#             self.multiplex_table[invoke_id] = self.process_queue_list.index(min_queue)
#
#         #print "{} {} {}".format(self.process_queue_list[0].qsize(),self.process_queue_list[1].qsize(),self.process_queue_list[2].qsize())

#TODO: not in used
# class OutgoingDispatcher(threading.Thread):
#     """ It receives outgoing messages from workers (echoProcesses) and transmits to destinations."""
#
#     def __init__(self,neighbor_list):
#         # base class initialization
#         super(OutgoingDispatcher,self).__init__()
#
#         self.context = zmq.Context()
#         self.receiver = self.context.socket(zmq.PULL)
#         self.receiver.bind("ipc:///tmp/outgoing") # ipc : local inter-process communication
#
#         #setup queues and outgoing_socket_thread
#         self.setup_outgoing_queue_and_socket(neighbor_list)
#
#         logging.info("Outgoing dispatcher initiated Successfully.")
#
#     def setup_outgoing_queue_and_socket(self,neighbor_list):
#         """ initialize outgoing queues and sockets"""
#
#         #setup queues and outgoing_socket_thread
#         self.outgoing_queues = {}
#         for neighbor in neighbor_list:
#             self.outgoing_queues[neighbor] = Queue.Queue()
#             threading.Thread(target=self.outgoing_socket_thread,
#                              args=(self.outgoing_queues[neighbor],neighbor,DISPATCHER_PORT)).start()
#
#         #add a special outgoing_socket_thread for sending a return message
#         self.outgoing_queues['localhost'] = Queue.Queue()
#         threading.Thread(target=self.outgoing_socket_thread,
#                         args=(self.outgoing_queues['localhost'],'localhost',INTERFACE_PORT)).start()
#
#     def outgoing_socket_thread(self,queue,neighbor_address,port):
#         """ a thread for getting a message from the queue and send it to destination """
#
#         sender = self.context.socket(zmq.PUSH)
#         sender.connect("tcp://{0}:{1}".format(neighbor_address,port))
#
#         while 1:
#             sender.send(queue.get())
#
#
#     #override method run() in a Thread
#     def run(self):
#         #assign function addresses locally
#         dispatch = self.dispatch
#         receiver = self.receiver
#
#         while 1:
#             #receive a message tuple from echoProcess
#             message_tuple = receiver.recv_multipart()
#             dispatch(message_tuple)
#
#
#     def dispatch(self, message_tuple):
#         """ dispatch a message from a echoProcess worker and place in outgoing queue."""
#         message_content = message_tuple[0]
#         destination_list = message_tuple[1:]
#
#         for destination_name in destination_list:
#             try:
#                 self.outgoing_queues[destination_name].put(message_content)
#             except KeyError:
#                 logging.error("Can't find destination to {0} for sending a message".format(destination_name))
#


#import os
#import random
import discord

client = discord.Client()

@client.event
async def on_ready():
  print('We have logged in as {0.user}'.format(client))

@client.event
async def on_message(message):

	async def test():
	  await	message.channel.send("Blackjack Test Starting")

	if message.content.startswith('//test'):
		await test()
		#await message.channel.send("Blackjack Test Starting")

'''
#Blackjack Game
#-------------------------------------------------------------------------------------------------------------------#

		deck = [2, 3, 4, 5, 6, 7, 8, 9, 10, 2, 3, 4, 5, 6, 7, 8, 9, 10, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]

		async	def deal(deck):
					hand = []
					for i in range(1):
						random.shuffle(deck)
						card = deck.pop()
						if card == 11:card = "J"
						if card == 12:card = "Q"
						if card == 13:card = "K"
						if card == 14:card = "A"
						hand.append(card)
					return hand

		async	def total(hand):
					total = 0
					for card in hand:
						if card == "J" or card == "Q" or card == "K": total+= 10
						elif card == "A":
								if total >= 1: total+= 1;
								else: total+= 11
						else: total+= card
					return total

		async	def hit(hand):
				card = deck.pop()
				if card == 11:card = "J"
				if card == 12:card = "Q"
				if card == 13:card = "K"
				if card == 14:card = "A"
				hand.append(card)
				return hand

		async	def clear():
				if os.name == 'nt':
					os.system('CLS')
				if os.name == 'posix':
					os.system('clear')

		async	def print_results(dealer_hand, player_hand):
				await clear()
				print("The dealer has a/n " + str(dealer_hand) + " for a total of " + str(total(dealer_hand)))
				print("You have a " + str(player_hand) + " for a total of " + str(total(player_hand)))

		async	def blackjack(dealer_hand, player_hand):
				if total(player_hand) == 21:
					print_results(dealer_hand, player_hand)
					print("Congratulations! You got a Blackjack!\n")
				elif total(dealer_hand) == 21:
					print_results(dealer_hand, player_hand)
					print("Sorry, you lose. The dealer got a blackjack.\n")

		async	def score(dealer_hand, player_hand):
				if total(player_hand) == 21:
					print_results(dealer_hand, player_hand)
					print("Congratulations! You got a Blackjack!\n")
				elif total(dealer_hand) == 21:
					print_results(dealer_hand, player_hand)
					print("Sorry, you lose. The dealer got a blackjack.\n")
				elif total(player_hand) > 21:
					print_results(dealer_hand, player_hand)
					print("Sorry. You busted. You lose.\n")
				elif total(dealer_hand) > 21:
					print_results(dealer_hand, player_hand)
					print("Dealer busts. You win!\n")
				elif total(player_hand) < total(dealer_hand):
					print_results(dealer_hand, player_hand)
					print("Sorry. Your score isn't higher than the dealers. You lose.\n")
				elif total(player_hand) > total(dealer_hand):
					print_results(dealer_hand, player_hand)
					print("Congratulations. Your score is higher than the dealers. You win\n")

		async	def Dealers_choice(player_hand, dealer_hand):
				if 22 > total(player_hand):
					choice = input("Do you want to [H]it, [S]tand, or [Q]uit: ").lower()
				else:
					choice = "s"
					await clear()
					#Dealers choice
				if choice == "h":
					hit(player_hand)
					while total(dealer_hand) < 17:
						await hit(dealer_hand)
					await score(dealer_hand, player_hand)
				elif choice == "s":
					while total(dealer_hand) < 17:
						await hit(dealer_hand)
					await score(dealer_hand, player_hand)
				elif choice == "q":
					print("Bye!")
					exit()

		async def game():
				choice = 0
				await clear()
				message.channel.send("Welcome to Blackjack")
				dealer_hand = deal(deck)
				player_hand = deal(deck)
				while choice != "q":
					print("The dealer is showing a " + str(dealer_hand[0]))
					print("You have a " + str(player_hand) + " for a total of " + str(total(player_hand)))
					await blackjack(dealer_hand, player_hand)

					await Dealers_choice(player_hand, dealer_hand)
		await game()

#-------------------------------------------------------------------------------------------------------------------#
'''

client.run('TOKEN')


import numpy as np
import matplotlib.pyplot as plt

matrix = np.random.randint(1, 101, (5, 5))

matrix *= 10

determinant_before = np.linalg.det(matrix)

inverse_matrix = np.linalg.inv(matrix)

determinant_after = np.linalg.det(inverse_matrix)

labels = ['Детерминант до', 'Детерминант после']
values = [determinant_before, determinant_after]

plt.bar(labels, values, color=['blue', 'green'])
plt.ylabel('Значение определителя')
plt.title('Сравнение определителей')
plt.show()


import networkx as nx
import matplotlib.pyplot as plt

def dfs(graph, start):
    visited = set()  # Conjunto para almacenar los nodos visitados
    stack = [start]  # Pila para almacenar los nodos por visitar

    while stack:
        node = stack.pop()  # Extraer el último nodo agregado a la pila

        if node not in visited:
            visited.add(node)
            print(node)  # Imprimir el nodo visitado

            # Agregar los vecinos no visitados a la pila
            neighbors = graph[node]
            stack.extend([neighbor for neighbor in neighbors if neighbor not in visited])

def draw_graph(graph):
    G = nx.Graph()
    for node, neighbors in graph.items():
        for neighbor in neighbors:
            G.add_edge(node, neighbor)

    pos = nx.spring_layout(G)
    nx.draw(G, pos, with_labels=True, node_color='lightblue', node_size=500, edge_color='gray', width=1, alpha=0.7)
    plt.show()

# Grafo de ejemplo
graph = {
    'A': ['B', 'C'],
    'B': ['A', 'D', 'E'],
    'C': ['A', 'F'],
    'D': ['B'],
    'E': ['B', 'F'],
    'F': ['C', 'E']
}

# Realizar la búsqueda en profundidad desde el nodo 'A'
dfs(graph, 'A')

# Generar el gráfico del grafo
draw_graph(graph)


import logging
from datetime import datetime

import requests
from dateutil.relativedelta import relativedelta

logger = logging.getLogger('exporter')

def get_sensor_metadata(url, port):
    r = requests.get('https://{}:{}/api/v1/sensor'.format(url, port))
    r.raise_for_status()
    return reformat_sensor_metadata(r.json())

def reformat_sensor_metadata(metadata_json):
    sensor_metadata = {}
    for row in metadata_json:
        sensor_metadata[row['sensor_id']] = {'description': row['description'], 'unit': row['unit']}

    return sensor_metadata

def get_station_metadata_for(url, port, station_id=None):
    r = requests.get('https://{}:{}/api/v1/station'.format(url, port))
    r.raise_for_status()

    return reformat_station_metadata(r.json(), station_id)

def reformat_station_metadata(metadata_json, station_id):
    if not station_id:
        return metadata_json

    for row in metadata_json:
        if row['station_id'] == station_id:
            return [row]

    raise ValueError('Station {} is not available on the backend'.format(station_id))

def get_weather_data_for(month, year, station_id, url, port):
    first_timepoint = datetime(day=1, month=month, year=year)
    last_timepoint = first_timepoint + relativedelta(months=1)

    logger.debug('Requesting data from backend {}:{} for station {}'.format(url, port, station_id))
    r = requests.get('https://{}:{}/api/v1/data?first_timepoint={}&last_timepoint={}&stations={}'.format(
        url,
        port,
        first_timepoint,
        last_timepoint,
        station_id
    ))
    logger.debug('Received data for period {} - {}'.format(first_timepoint, last_timepoint))
    r.raise_for_status()
    month_data = r.json()
    return month_data


import sys
from collections import Counter

input_file = sys.argv[1] if len(sys.argv) > 1 else "inputs/14.txt"
with open(input_file) as file:
    sequence = file.readline().strip()
    file.readline()
    rules = dict([line.strip().split(" -> ") for line in file.readlines()])

def part_1():
    current_sequence = sequence
    for _ in range(10):
        new_sequence = ""
        for first, second in zip(current_sequence, current_sequence[1:]):
            new_sequence += first + rules[first + second]
        # the final letter was not added so add it to the sequence
        current_sequence = new_sequence + second
    sorted_counts = Counter(current_sequence).most_common()
    return sorted_counts[0][1] - sorted_counts[-1][1]

def part_2():
    pair_counts = Counter()
    for first, second in zip(sequence, sequence[1:]):
        pair_counts[first + second] += 1
    for _ in range(40):
        updated_double_counts = Counter()
        for current, count in pair_counts.items():
            updated_double_counts[current[0] + rules[current]] += count
            updated_double_counts[rules[current] + current[1]] += count
        pair_counts = updated_double_counts
    single_letter_counter = Counter()
    for pattern, count in pair_counts.items():
        single_letter_counter[pattern[0]] += count
    # the final letter was not counted so add 1 to its count
    single_letter_counter[sequence[-1]] += 1
    sorted_counts = single_letter_counter.most_common()
    return sorted_counts[0][1] - sorted_counts[-1][1]

print(f"Part 1: {part_1()}")
print(f"Part 2: {part_2()}")


#serialize.py
import json

from graph import *
from hypergraph import *

class MyJSONEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, Graph):
            dct = obj.__dict__.copy()
            dct.pop('edges', None)
            dct.pop('trace_recode', None)
            return dct
        elif isinstance(obj, HyperGraph):
            dct = obj.__dict__.copy()
            dct.pop('trace_recode', None)
            return dct
        elif isinstance(obj, Node):
            dct = obj.__dict__.copy()
            dct.pop('edges_in', None)
            dct.pop('edges_out', None)
            dct.pop('trace', None)
            return dct
        elif isinstance(obj, HyperNode):
            dct = obj.__dict__.copy()
            dct.pop('trace')
            dct.pop('hyperedges')
            dct['hyperedges'] = list(obj.__dict__['hyperedges'])
            return dct
        elif isinstance(obj, HyperEdge):
            dct = obj.__dict__.copy()
            dct.pop('trace')
            dct.pop('middle_hover_trace')
            dct.pop('hypernodes')
            dct['hypernodes'] = list(obj.__dict__['hypernodes'])
            return dct
        elif isinstance(obj, nx.Graph):
            return {'name': 'nx.Graph', 'data': nx.adjacency_data(obj)}
        elif isinstance(obj, nx.DiGraph):
            return {'name': 'nx.DiGraph', 'data': nx.adjacency_data(obj)}
        elif isinstance(obj, np.ndarray):
            return {'name': 'np.array', 'data': obj.tolist()}
        elif isinstance(obj, list):
            return [MyJSONEncoder.default(self, x) for x in obj]
        return json.JSONEncoder.default(self, obj)

def MyJSONDecode(dct):
    if isinstance(dct, dict) and 'name' in dct:
        name = dct['name']
        #if name == 'Graph':
        #    print('decoding graph', dct)
        dct.pop('name', None)
        if name == 'nx.Graph':
            return nx.adjacency_graph(dct['data'], directed=False)
        elif name == 'nx.DiGraph':
            return nx.adjacency_graph(dct['data'], directed=True)
        elif name == 'np.array':
            return np.array(dct['data'])
        return getattr(modules[__name__], name)(**dct)
    return dct


from abc import ABC, abstractmethod
import logging as log
import cv2
from openvino.inference_engine import IENetwork, IECore
from timer import timeit

class Model_X(ABC):
    """
    Abstract Class for the Face Detection Model.
    """

    def __init__(self, model_name, device="CPU", threshold=0.5, extensions=None):
        self.model_weights = model_name + ".bin"
        self.model_structure = model_name + ".xml"
        self.device = device
        self.threshold = threshold
        self.extensions = extensions

    @timeit
    def load_model(self):
        """
        This method is for loading the model to the device specified by the user.
        If your model requires any Plugins, this is where you can load them.
        """
        self.network = IENetwork(self.model_structure, self.model_weights)
        self.input_name = next(iter(self.network.inputs))
        self.input_shape = self.network.inputs[self.input_name].shape
        self.output_name = next(iter(self.network.outputs))
        self.output_shape = self.network.outputs[self.output_name].shape

        self.core = IECore()

        if self.extensions and "CPU" in self.device:
            self.core.add_extension(self.extensions, self.device)

        supported_layers = self.core.query_network(
            network=self.network, device_name=self.device
        )
        unsupported_layers = [
            l for l in self.network.layers.keys() if l not in supported_layers
        ]

        if unsupported_layers:
            log.error(f"Unsupported layers found: {unsupported_layers}")
            exit(1)

        self.exec_network = self.core.load_network(self.network, self.device)

    @timeit
    def predict(self, image):
        """
        This abstractmethod is meant for running predictions on the input image.
        """
        outputs = self.exec_network.infer(
            {self.input_name: self.preprocess_input(image)}
        )
        return self.preprocess_output(outputs, image)

    def check_model(self):
        raise NotImplementedError

    def preprocess_input(self, image):
        """
        Before feeding the data into the model for inference,
        you might have to preprocess it. This function is where you can do that.
        """
        ret = cv2.resize(image, (self.input_shape[3], self.input_shape[2]))
        ret = ret.transpose((2, 0, 1))
        ret = ret.reshape(1, *ret.shape)

        return ret

    @abstractmethod
    def preprocess_output(self, outputs):
        """
        Before feeding the output of this model to the next model,
        you might have to preprocess the output. This function is where you can do that.
        """

        pass


from numpy import sin, cos, pi, sqrt, shape, linspace, meshgrid, zeros, mod
from math import factorial
import matplotlib.pyplot as plt
import mpl_toolkits.mplot3d as mp3d
def Shperical2Cartesian(r, theta, phi):
    x = r*sin(theta)*cos(phi)
    y = r*sin(theta)*sin(phi)
    z = r*cos(theta)
    return x, y, z
def Legendre_Poly(n, x):
    if n == 0:
        p = 1
    elif n == 1:
        p = x
    else:
        p = (1/n)*((2*n-1)* x* Legendre_Poly(n-1, x) - (n-1)* Legendre_Poly(n-2, x))
    return p
def Asso_Leg(l,m,x):
    try:
        if m == 0:
            p = Legendre_Poly(l,x)
        elif m > 0:
            p = (1/ sqrt(1-x**2))*((l-m+1)* x* Asso_Leg(l,m-1,x) - (l+m-1)* Asso_Leg(l-1,m-1,x))

        elif m < 0:
            m = abs(m)
            p = ((-1)**m)*(factorial(l-m)/ factorial(l+m))* Asso_Leg(l,m,x)
    except ZeroDivisionError:
        p = 0
    return p
l = int(input('Azimuthal quantum number "l": '))
if l<0:
    print('"l" can not be a negative number')

m = int(input('Magnetic quantum number "m": '))
if m>l or m<(-l):
    print('quantum number "m" belong to "[-l,l]" ')
K = sqrt( ((2*l+1)* factorial(l-abs(m)))/(4*pi*factorial(l+abs(m))) )
phi = linspace(0, 2*pi, 100)
tht = linspace(0, pi, 100)

phi,tht = meshgrid(phi,tht)
p,q = shape(phi)
Y = zeros([p,q])

for i in range(0+1,p-1):
    for j in range(0+1,q-1):
        if m>0:
            Y[i,j] = sqrt(2)*K*cos(m*phi[i,j])* Asso_Leg(l,m,cos(tht[i,j]))
        elif m<0:
            Y[i,j] = sqrt(2)*K*sin(abs(m)*phi[i,j])* Asso_Leg(l, abs(m), cos(tht[i,j]))
        elif m == 0:
            Y[i,j] = K* Legendre_Poly(l, cos(tht[i,j]))

p,q = shape(Y)

for i in range(0,p):
    for j in range(0,q):
        if Y[i,j]<0:
            tht[i,j] = tht[i,j]+pi
x,y,z = Shperical2Cartesian(Y, tht, phi)

fig = plt.figure('Harmonics')
ax = fig.add_subplot(111, projection='3d')

ax.plot_surface(x,y,z, cmap = 'cool', edgecolor = 'k')

plt.title('Spherical Harmonics', fontsize = 14, fontweight = 'bold')
ax.set_xlabel('X', fontsize =12, fontweight = 'bold')
ax.set_ylabel('Y', fontsize =12, fontweight = 'bold')
ax.set_zlabel('Z', fontsize =12, fontweight = 'bold')

plt.show()


import nltk
import pickle
from nltk.tokenize import word_tokenize
from nltk.util import ngrams

def process_file(file):

    with open(file, 'r', encoding='utf-8') as f:
        raw_text = f.read()
    f.close()

    unigrams = word_tokenize(raw_text)
    bigrams = list(ngrams(unigrams, 2))

    #dictionaries
    unigram_dict = {t:unigrams.count(t) for t in set(unigrams)}
    bigram_dict = {b:bigrams.count(b) for b in set(bigrams)}

    #tuple
    return bigram_dict, unigram_dict

#-----Main-----
print('processing English..')
eng_bigrams, eng_unigrams = process_file('LangId.train.English')
print('processing Italian..')
ita_bigrams, ita_unigrams = process_file('LangId.train.Italian')
print('processing French..')
fre_bigrams, fre_unigrams = process_file('LangId.train.French')

print('pickling..')
pickle.dump(eng_bigrams, open('eng_bigrams.p', 'wb'))
pickle.dump(eng_unigrams, open('eng_unigrams.p', 'wb'))
pickle.dump(ita_bigrams, open('ita_bigrams.p', 'wb'))
pickle.dump(ita_unigrams, open('ita_unigrams.p', 'wb'))
pickle.dump(fre_bigrams, open('fre_bigrams.p', 'wb'))
pickle.dump(fre_unigrams, open('fre_unigrams.p', 'wb'))
print('done')


import argparse
import model
import json
import os

import tensorflow as tf
from tensorflow.contrib.learn.python.learn import learn_runner

if __name__ == '__main__':
  parser = argparse.ArgumentParser()
  parser.add_argument(
      '--traindata',
      help='Training data can have wildcards',
      required=True
  )
  parser.add_argument(
      '--evaldata',
      help='Training data can have wildcards',
      required=True
  )
  parser.add_argument(
      '--job-dir',
      help='this model ignores this field, but it is required by gcloud',
      default='./junk'
  )
  parser.add_argument(
      '--output_dir',
      help='Output directory',
      required=True
  )
  parser.add_argument(
      '--num_training_epochs',
      help='Number of passes through training dataset',
      type=int,
      default=10
  )

  # for hyper-parameter tuning
  parser.add_argument(
      '--batch_size',
      help='Number of examples to compute gradient on',
      type=int,
      default=100
  )
  parser.add_argument(
      '--nbuckets',
      help='Number of bins into which to discretize lats and lons',
      type=int,
      default=5
  )
  parser.add_argument(
      '--hidden_units',
      help='Architecture of DNN part of wide-and-deep network',
      default='64,64,64,16,4'
  )
  parser.add_argument(
      '--learning_rate',
      help='Controls size of step in gradient descent.',
      type=float,
      default=0.0606
  )

  # parse args
  args = parser.parse_args()
  arguments = args.__dict__

  # unused args provided by service
  arguments.pop('job-dir', None)
  arguments.pop('job_dir', None)
  output_dir = arguments.pop('output_dir')

  # when hp-tuning, we need to use different output directories for different runs
  output_dir = os.path.join(
      output_dir,
      json.loads(
          os.environ.get('TF_CONFIG', '{}')
      ).get('task', {}).get('trial', '')
  )

  # run
  tf.logging.set_verbosity(tf.logging.INFO)
  learn_runner.run(model.make_experiment_fn(**arguments), output_dir)


#!/usr/bin/env python3
import scipy.io.wavfile as wav
import speech_recognition as sr
import os
import sys
from deepspeech import Model
from tts import tts
from brain import brain

#Functioning Variables
home = os.path.expanduser("~")
music_path = os.path.join(home, "Music")

def main():
    #Obtain audio from the microphone and record it to a wav file
    r = sr.Recognizer()
    with sr.Microphone() as source:
        print("I'm Listening!")
        audio = r.listen(source)
        with open("recording.wav", "wb") as f:
            f.write(audio.get_wav_data())

    #Comment the following part if you wish to use another speech recognition module

    try:
        os.system("deepspeech --model models/output_graph.pbmm --alphabet models/alphabet.txt --lm models/lm.binary --trie models/trie --audio recording.wav >> data.txt")
        f = open("data.txt", "r")
        if f.mode == "r":
            speech_text = f.read()
            print("Aida thinks you said: " + speech_text)
            f = open("data.txt", "w+")   #+w means write/create. +a means append/create. r means read
            f.write("")                 #delete contents of text file
            f.close()
            os.remove("recording.wav")  #delete wav file

    #Uncomment this part if you intend to recognize speech using CMU Pocket Sphinx Speech Recognition instead of Deep Speech

    # try:
    #     speech_text = r.recognize_sphinx(audio).lower().replace(".","")
    #     print("Aida thinks you said : " + speech_text +"'")

    except sr.UnknownValueError:
        print("Aida couldn't understand audio")

    #Uncomment this part ONLY if you intend to use an online speech recognition above (for example: r.recognize_google) BUT IT'S INSECURE !

    # except sr.RequestError as e:
    #     print("Couldn't request results from the internet; {0}".format(e))

    brain(speech_text, music_path)

while True:
    main()


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

from django.db import models, migrations
from django.conf import settings

class Migration(migrations.Migration):

    dependencies = [
        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
    ]

    operations = [
        migrations.CreateModel(
            name='Auction',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('auction_start_date', models.DateTimeField(auto_now_add=True)),
                ('auction_end_date', models.DateTimeField()),
                ('opening_bid', models.DecimalField(default=1.0, max_digits=7, decimal_places=2)),
                ('price', models.DecimalField(default=0.0, max_digits=7, decimal_places=2)),
                ('increment', models.DecimalField(default=1.0, max_digits=7, decimal_places=2)),
                ('auction_ended', models.BooleanField(default=False)),
            ],
        ),
        migrations.CreateModel(
            name='Bid',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('bid_amount', models.DecimalField(default=1.0, max_digits=7, decimal_places=2)),
                ('auction', models.ForeignKey(to='auction.Auction')),
                ('bidder', models.ForeignKey(to=settings.AUTH_USER_MODEL)),
            ],
            options={
                'ordering': ['bid_amount'],
            },
        ),
        migrations.CreateModel(
            name='Item',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('name', models.CharField(max_length=255)),
                ('seller', models.ForeignKey(to=settings.AUTH_USER_MODEL)),
            ],
        ),
        migrations.AddField(
            model_name='auction',
            name='item',
            field=models.ForeignKey(to='auction.Item'),
        ),
    ]


from django.db.models import Model, ManyToManyField, ForeignKey, CASCADE, CharField, BooleanField, DateTimeField#, DateField, TimeField
from django.conf import settings
from gallery.models import Gallery
#from medium.models import Medium
AUTH_USER_MODEL=settings.AUTH_USER_MODEL

class GoodsExchange(Model):
	#launcher=ForeignKey(AUTH_USER_MODEL, related_name='launcher_goodsexchange', on_delete=CASCADE)
	gallery=ForeignKey(Gallery, related_name='gallery_goodsexchange', on_delete=CASCADE)
	ge2ge=ForeignKey('self', related_name='goodsexchange_goodsexchange', null=True, on_delete=CASCADE)
	coordinate=CharField(max_length=30, null=True)
	datetime=DateTimeField(null=True)
	isDealt=BooleanField(default=False)
	timestamp=DateTimeField(auto_now=True)
	class Meta:
		db_table='goodsexchange'


import sys

from django.conf import settings
from django.conf.urls import *
from django.contrib import admin
from django.contrib.staticfiles.urls import staticfiles_urlpatterns

from mezzanine.core.views import direct_to_template

admin.autodiscover()

# Add the urlpatterns for any custom Django applications here.
# You can also change the ``home`` view to add your own functionality
# to the project's homepage.

#urlpatterns = staticfiles_urlpatterns()

if settings.DEBUG:
    import debug_toolbar
    urlpatterns = patterns('',
        url(r'^__debug__/', include(debug_toolbar.urls)),
        url(r'^media/(?P<path>.*)$', 'django.views.static.serve', {
            'document_root': settings.MEDIA_ROOT,
        }),
        url(r'^assets/(?P<path>.*)$', 'django.views.static.serve', {
            'document_root': settings.STATIC_ROOT,
        }),
    )
else:
    urlpatterns = []

urlpatterns += patterns("",

    # Change the admin prefix here to use an alternate URL for the
    # admin interface, which would be marginally more secure.
    ("^admin/", include(admin.site.urls)),
    ("^", include("invites.urls")),
    ("^", include("captcha.urls")),
    ("^", include("mezzanine.urls")),
    url("^$", direct_to_template, {"template": "index.html"}, name="home"),

)

# Adds ``STATIC_URL`` to the context of error pages, so that error
# pages can use JS, CSS and images.
handler404 = "mezzanine.core.views.page_not_found"
handler500 = "mezzanine.core.views.server_error"


'''
Created on Jun 18, 2018

@author: sajid
'''

import tempfile

tempfile.tempdir = '/Users/sajid/Desktop'

print('gettempdir():', tempfile.gettempdir())

def main():
    text_content = 'Lorem ipsum dolor sit amet, te stet diceret impedit cum. Ea est noster option, ut mei elitr suscipit, sed ne docendi urbanitas. Eum persecuti persequeris mediocritatem ne, ferri aperiam accommodare sea ad, usu id sumo justo maiestatis. Mel eu populo sensibus consectetuer, qui ei noluisse indoctum, labore numquam id mei. Altera quaerendum interpretaris cu eam, ius cu dicat fierent convenire, ex dolorum inciderint has.'
    create_temp_file('_suffix','prefix_', text_content)

def create_temp_file(_suffix, prefix_, content):
    with tempfile.NamedTemporaryFile(mode='w+t', suffix=_suffix, prefix=prefix_, delete=False) as temp:
        temp.writelines(content)

        #testing the written contents
#         temp.seek(0)
#         for line in temp:
#             print(line.rstrip())
#         print(temp.name)
        return temp.name

if __name__=="__main__":
    main()


from django.conf.urls import url
from rest_framework.urlpatterns import format_suffix_patterns

from drf_yasg.views import get_schema_view
from drf_yasg import openapi
from webservices import views
from rest_framework.documentation import include_docs_urls

GET_SAMPLE_INGESTION = url(
    regex=r'^sample-ingestion/(?P<name_and_gene_collection>[A-za-z0-9\-_]+)/$',
    view=views.SampleIngestionViewSet.as_view({'get': 'retrieve', 'delete': 'destroy'}),
    name='get-sample-ingestion'
)

LIST_CREATE_SAMPLE_INGESTION = url(
    regex=r'^sample-ingestion/$',
    view=views.SampleIngestionViewSet.as_view({'get': 'list', 'post': 'create'}),
    name='list-sample-ingestion'
)

LIST_GENE_COVERAGE = url(
    regex=r'^gene-coverage/$',
    view=views.GeneCoverageView.as_view({'post': 'list'}),
    name='gene-coverage-list'
)

GET_GENE_COVERAGE = url(
    regex=r'^gene-coverage/(?P<sample_name>[A-za-z0-9\-_]+)/(?P<gene_collection>[A-za-z0-9\-_]+)/(?P<gene>[A-za-z0-9\-_]+)/$',
    view=views.GeneCoverageView.as_view({'get': 'retrieve'}),
    name='gene-coverage-detail'
)

LIST_SAMPLE_METRICS = url(
    regex=r'^sample-metrics/$',
    view=views.SampleMetricsView.as_view({'post': 'list'}),
    name='sample-metrics-list'
)

GET_SAMPLE_METRICS = url(
    regex=r'^sample-metrics/(?P<sample_name>[A-za-z0-9\-_]+)/(?P<gene_collection>[A-za-z0-9\-_]+)$',
    view=views.SampleMetricsView.as_view({'get': 'retrieve'}),
    name='sample-metrics-detail'
)

schema_view = get_schema_view(
   openapi.Info(
      title="Calypso",
      default_version='v1',
      description="Calypso is a service to store and analyse coverage metrics from whole genome sequences",
   ),
   public=True,
)

urls = [LIST_CREATE_SAMPLE_INGESTION,
        GET_SAMPLE_INGESTION,
        GET_GENE_COVERAGE,
        LIST_GENE_COVERAGE,
        GET_SAMPLE_METRICS,
        LIST_SAMPLE_METRICS,
        url(r'^docs/$', schema_view.with_ui('swagger', cache_timeout=None), name='schema-swagger-ui')
        ]

urlpatterns = format_suffix_patterns(urls)


"""
Written by:
Dr. Eamon K. Conway
Geospatial Development Center (GDC)
Kostas Research Institute for Homeland Security
Northeastern University

Contact:
e.conway@northeastern.edu

Date:
9/19/2022

DARPA Critical Mineral Challenge 2022

Purpose:
Considers all keywords and fuses nearby keywords together

Args:
keywords,
bboxes
centers

Out:
keywords,
bboxes,
centers

"""

import math
import numpy as np
from tqdm import tqdm
import time

def main(keywords,bboxes,centers,clue_x,clue_y):

            if(abs(int(clue_x))<100):
                clue_x = str(clue_x)[1:3]
            else:
                clue_x = str(clue_x)[1:4]

            clue_y = str(clue_y)[0:2]

            new_keywords = []
            new_bboxes = []
            new_centers=[]
            append = []
            tz = time.time()
            done=False
            success = False
            while done==False:
                # merge keywords if close together
                x = []
                for i in tqdm(range(len(keywords))):
                    tnow = (time.time() - tz)
                    app=True
                    contin = True
                    if(keywords[i]!=''):
                        if(clue_x in keywords[i] or clue_y in keywords[i]):
                            print(keywords[i])
                            top_left_1 = [bboxes[i][0][0],bboxes[i][0][1]]
                            top_right_1 = [bboxes[i][1][0],bboxes[i][0][1]]
                            bot_right_1 = [bboxes[i][1][0],bboxes[i][1][1]]
                            bot_left_1 = [bboxes[i][0][0],bboxes[i][1][1]]
                            tnow = (time.time() - tz)
                            if(tnow > 100):
                                break
                                done=True
                            loop_done = False
                            while loop_done == False:
                                for j in range(len(keywords)):
                                    if(keywords[j]!=''):
                                        if(('scale' in keywords[i]) or ('scale' in keywords[j])):
                                            tol=35
                                        else:
                                            tol=35
                                        top_left_2 = [bboxes[j][0][0],bboxes[j][0][1]]
                                        top_right_2 = [bboxes[j][1][0],bboxes[j][0][1]]
                                        bot_right_2 = [bboxes[j][1][0],bboxes[j][1][1]]
                                        bot_left_2 = [bboxes[j][0][0],bboxes[j][1][1]]
                                        # is box 2 close to box 1 on left side of 1
                                        if(math.isclose(bot_right_2[0],bot_left_1[0],abs_tol=tol) and \
                                          math.isclose(bot_right_2[1],bot_left_1[1],abs_tol=tol) and i!=j and \
clue_x not in keywords[j] and clue_y not in keywords[j]):
                                            app = True
                                            for en in x:
                                                if([j,i] in x):
                                                    app=False
                                            #print('1 ',x,[j,i],app,keywords[j],keywords[i])
                                            if(app==True):
                                                contin=False
                                                new_word = keywords[j]+keywords[i]
                                                #print('nw = ',new_word)
                                                new_keywords.append(new_word)
                                                new_bboxes.append(bboxes[i])
                                                new_centers.append(centers[i])
                                                x.append([j,i])
                                            loop_done=True
                                        # is box 2 close to box 1 on right side of 1
                                        if(math.isclose(bot_right_1[0],bot_left_2[0],abs_tol=tol) and \
                                          math.isclose(bot_right_1[1],bot_left_2[1],abs_tol=tol) and i!=j and \
clue_x not in keywords[j] and clue_y not in keywords[j]):
                                            app = True
                                            for en in x:
                                                if([i,j] in x):
                                                    app=False
                                            #print('2 ',x,[i,j],app,keywords[i],keywords[j])
                                            if(app==True):
                                                contin = False
                                                new_word = keywords[i]+keywords[j]
                                                new_keywords.append(new_word)
                                                new_bboxes.append(bboxes[i])
                                                new_centers.append(centers[i])
                                                x.append([i,j])
                                            loop_done=True
                                    if(j==len(keywords)-1):
                                        loop_done=True
                        if(contin == True):
                                for en in x:
                                    for yn in en:
                                        if(i == yn):
                                            app=False
                                if(app==True):
                                    new_keywords.append(keywords[i])
                                    new_bboxes.append(bboxes[i])
                                    new_centers.append(centers[i])
                if(tnow<=100):
                    success = True
                    done=True
                    print('MergeKeys Successful, Time =  ',(time.time() - tz))
                else:
                    break
                    print('MergeKeys Not Successful, Time =  ',(time.time() - tz))
            if(success==True):
                keywords = new_keywords
                bboxes = new_bboxes
                centers = new_centers

            return keywords,bboxes,centers

if __name__=="__main__":

    fname = 'GEO_0050.txt'
    with open('/scratch/e.conway/DARPA_MAPS/TrainingKeys/'+fname,'r') as f:
        data = f.readlines()
    tot_numbers = []
    for x in data:
        tot_numbers.append(x.split('\n')[0])

    with open('/scratch/e.conway/DARPA_MAPS/TrainingCenters/'+fname,'r') as f:
        data = f.readlines()
    tot_centers = []
    for x in data:
        tot_centers.append([np.float64(x.split(' ')[0]),np.float64(x.split(' ')[1].split('\n')[0])])

    with open('/scratch/e.conway/DARPA_MAPS/TrainingBBoxes/'+fname,'r') as f:
        data = f.readlines()
    tot_bboxes = []
    for x in data:
        tot_bboxes.append([[np.float64(x.split(' ')[0]),np.float64(x.split(' ')[1])],\
                           [np.float64(x.split(' ')[2]),np.float64(x.split(' ')[3].split('\n')[0])]])

    clues = np.genfromtxt('/scratch/e.conway/DARPA_MAPS/CluesTesting/'+fname.split('.txt')[0]+'_clue.csv',delimiter=',')
    clue_x = clues[0]
    clue_y = clues[1]

    keywords,bboxes,centers = main(tot_numbers,tot_bboxes,tot_centers,clue_x,clue_y)

    print('New Keys = ',keywords)
    """
    tot_numbers = ['105','030']
    print('Old Keys = ',tot_numbers)
    tot_num_centers = [[100,505],[120,505]]
    tot_num_boxes = [[[100,500],[110,510]],[[110,510],[120,520]]]
    clue_x = -105.3
    clue_y = 30
    keywords,bboxes,centers = main(tot_numbers,tot_num_boxes,tot_num_centers,clue_x,clue_y)
    print('New Keys = ',keywords)
    """


from collections import deque

secondary_dict = {"orange": ["red", "yellow"], "purple": ["red", "blue"], "green": ["yellow", "blue"]}
main_colors = ["red", "yellow", "blue"]
secondary_colors = ["orange", "purple", "green"]
matched_main = []
str_list = deque([ch for ch in input().split(" ")])

while len(str_list) > 0:
    current_str = ''
    reversed_current_str = ''

    if len(str_list) > 1:
        part_one = str_list.popleft()
        part_two = str_list.pop()
        current_str = part_one + part_two
        reversed_current_str = part_two + part_one

        if current_str in main_colors:
            matched_main.append(current_str)
            continue
        elif current_str in secondary_colors:
            matched_main.append(current_str)
            continue
        elif reversed_current_str in main_colors:
            matched_main.append(reversed_current_str)
        elif reversed_current_str in secondary_colors:
            matched_main.append(reversed_current_str)
        else:
            current_one = part_one[:-1]
            current_two = part_two[:-1]

            if len(str_list) > 1:
                index = len(str_list) // 2

                if current_two != "":
                    str_list.insert(index, current_two)

                if current_one != "":
                    str_list.insert(index, current_one)

            elif len(str_list) <= 1:

                if current_two != "":
                    str_list.appendleft(current_two)

                if current_one != "":
                    str_list.appendleft(current_one)

    else:
        part_one = str_list.popleft()
        current_str = part_one

        if current_str in main_colors:
            matched_main.append(current_str)
            continue
        elif current_str in secondary_colors:
            matched_main.append(current_str)
            continue
        else:
            current_one = part_one[:-1]

            if current_one != "":
                str_list.append(current_one)

final_list = []

for ch in matched_main:
    count = 0

    if ch in secondary_colors:
        for key in secondary_dict[ch]:
            if key in matched_main:
                count += 1
    else:
        final_list.append(ch)

    if count == 2:
        final_list.append(ch)

print(final_list)


""""

This file is part of the suite of provided scripts to assist in summarising and presenting the training and validation statistics
from the granular-tags tool.

Run summarise.py with relevant command line arguments for generation of summary documents in the same directory as the logs.

"""
import os

from certifi import where

import extractor
import matplotlib.pyplot as plt

import argparse
from datetime import timedelta, date
# import shutil

import pandas as pd

parser = argparse.ArgumentParser(description='Summarise the training runs of a dataset')
parser.add_argument('--dataset', type=str, help='Input the dataset you want to summarise')
parser.add_argument('--save_dir', help='Save where?', required=True)
parser.add_argument('--log_dir', help='BiT output where?', required=True)

args = parser.parse_args()
highest_validation_accuracy = 0.00
highest_validation_path = ''

final_validation_by_hyperparam = []

for folder in os.listdir(args.log_dir):
    if args.dataset in folder:
        full_path = f'{args.log_dir}{folder}'
        #print(full_path)

        training, validation, header = extractor.get_info_from_log(f'{full_path}/train.log')

        print(f'saving some csvs in {folder}')
        pd.DataFrame.to_csv(training,os.pjoin(folder,'training.csv'))
        pd.DataFrame.to_csv(validation,os.pjoin(folder,'validation.csv'))

        modeltype, base_lr, batch, batch_split, examples_per_class = extractor.make_summary_txt(full_path,validation,folder,args,header)

        this_run_info = f'{modeltype}_{base_lr}_{batch}_{batch_split}_{examples_per_class}'

        plt.figure()
        extractor.plot_multi(training[['Training loss', 'Learning rate']],figsize=(10,5))
        plt.tight_layout()
        plt.savefig(f"{full_path}/training_curves_{folder}_{this_run_info}.png")
        plt.close()

        plt.figure()
        extractor.plot_multi(validation['Validation loss', 'Precision', 'Recall','Accuracy','Specificity','Balanced Accuracy','F1','Dataset Cardinality', 'Label density','Naive Accuracy','Hamming loss','Adjusted accuracy','Exact matches'],figsize=(20,10))
        plt.tight_layout()
        plt.savefig(f"{full_path}/validation_curves_{folder}_{this_run_info}.png")
        plt.close()

        new_dir_path = f'{full_path[:39]}_{this_run_info}'
        os.rename(full_path,new_dir_path)

        if validation.empty != True:
            this_run_final_f1 = validation['F1'][-1]
            if this_run_final_f1 > highest_validation_f1:
                highest_validation_f1 = this_run_final_f1
                highest_validation_path = new_dir_path

            final_validation_by_hyperparam.append({'Final validation f1':pd.to_numeric(this_run_final_f1, errors='coerce'),'Batch size':pd.to_numeric(batch[6:], errors='coerce'),'Batch splitting divisor':pd.to_numeric(batch_split[12:]),'Examples per class':pd.to_numeric(examples_per_class[19:], errors='coerce'),'Base learning rate':pd.to_numeric(base_lr[8:], errors='coerce')})

        # elif validation.empty:
        #     if args.delete_old:
        #         print("HOW DID I GET HERE?????")
        #         continue

print(f'Highest validation accuracy for dataset {args.dataset} acheived with full_path = {highest_validation_path} with {highest_validation_accuracy}%.')

#what I want: end val accuracies by param (base_lr, examples_per_class, batch_size)
final_validation_by_hyperparam = pd.DataFrame.from_records(final_validation_by_hyperparam)
print(final_validation_by_hyperparam)

final_validation_by_hyperparam = final_validation_by_hyperparam.groupby(['Batch size','Batch splitting divisor','Examples per class','Base learning rate'],dropna=False).mean().reset_index()

# where_duplicated_runs = final_validation_by_hyperparam.duplicated(subset=['Batch size','Batch splitting divisor','Examples per class','Base learning rate'],keep=False)

print(final_validation_by_hyperparam)
# print(where_duplicated_runs)

dataframe_save_path = f'{args.save_dir}/{args.dataset}.csv'

pd.DataFrame.to_csv(final_validation_by_hyperparam,dataframe_save_path)


"""
author: LSH9832
"""
from yolox import Detector, draw_bb
import cv2

if __name__ == '__main__':
    detector = Detector(
        model_path="E:/图像检测平台/webyolox-main/settings/test/output/last.pth",
        model_size="s",
        class_path="E:/图像检测平台/webyolox-main/yolox/datasets/classes.txt",
        conf=0.25,
        nms=0.4,
        input_size=640,
        fp16=True
    )

    """
    or create detector as follows
    """
    # from yolox import create_detector_from_settings
    # detector = create_detector_from_settings("./detect_settings.yaml")

    detector.loadModel()

    cap = cv2.VideoCapture(0)
    while cap.isOpened():
        success, image = cap.read()
        if success:
            result = detector.predict(image)

            draw_bb(image, result, detector.get_all_classes())
            cv2.imshow("image", image)
            if cv2.waitKey(1) == 27:    # esc
                cv2.destroyAllWindows()
                break


import requests

def run(data_tuple):
    data = data_tuple[-1]
    session = requests.session()
    if data["method"] == "get":
        res = session.request(method="GET", url=data["api"], params=data["params"], headers=data["headers"])
        return res.json()
    elif data["method"] == "post":
        res = session.request(method="POST", url=data["api"], data=data["params"], headers=data["headers"])
        return res.json()

if __name__ == '__main__':
    data = {'api': 'http://192.168.1.96:8092/jcw/produce/safetyTool/sync/list', 'params': {'syncDeptId': '145425940813211', 'syncLastTime': ''}, 'headers': {'token': '2100000000000000'}, 'method': 'get'}
    print(run(data))


class Solution:
    # 直接计数，统计出现三次的数字即可
    def arraysIntersection(self, arr1: List[int], arr2: List[int], arr3: List[int]) -> List[int]:
        arr1.extend(arr2)
        arr1.extend(arr3)
        from collections import Counter
        obj = Counter(arr1)
        res = []
        for k in sorted(obj):
            if obj[k] == 3:
                res.append(k)
        return res


import re
if __package__:
    from scripts.intent import *
    from scripts.answer_dictionary import DEFAULT,INIT_GREETINGS,SHOW_LIST
else:
    from intent import *
    from answer_dictionary import DEFAULT,INIT_GREETINGS,SHOW_LIST

input_intents=['keyword','source','domain']
sort_intents=['relevant','popular']
KEYWORD_NER=True

import spacy
nlp=spacy.load('en_core_web_md')

def match_date(message):
    connections=['\.','/','-']
    l=['([0-9]{4})','([0-9]{1,2})','([0-9]{1,2})']
    pattern_string=['('+conn.join(l)+')' for conn in connections]
    pattern_string='|'.join(pattern_string)
    date_pattern=re.compile(pattern_string)
    return date_pattern.search(message)

def match_num(message):
    pattern=re.compile('[1-9]')
    return pattern.match(message)

def interpret(message,last_state):
    words=message.split()
    if 'news' in words:
        return 'read_news',None
    date=match_date(message)
    if date:
        if last_state==INPUT:
            return 'date',date.group()
        elif last_state==GIVEN:
            return 'date_sort',date.group()
        else:
            return 'none',None
    if last_state==INPUT:
        if KEYWORD_NER:
            intent='keyword'
            doc=nlp(message)
            if doc.ents:
                addition=doc.ents[-1]
                return intent,addition
        else:
            for input_intent in input_intents:
                if input_intent in words:
                    index=words.index(input_intent)
                    addition=words[index+1]
                    return input_intent,addition
    for sort_intent in sort_intents:
        if sort_intent in words:
            return sort_intent,None
    num=match_num(message)
    if last_state==GIVEN and num:
        return 'choose',int(num.group(0))
    return 'none',None

def respond(message,state,search_sequence,policy=policy_rules):
    intent,addition=interpret(message,state)
    print('get intent:'+intent+' state is:'+str(state))
    if (state,intent) in policy:
        new_state,answer=policy[(state,intent)]
        if new_state in GIVEN_STATES:
            assert hasattr(answer,'__call__')
            answer=answer(intent,addition)
            assert type(answer)==list
            #print(answer)
            answer=format_list(answer)
            #print(answer)
            search_sequence=intent,addition
        if new_state in SORTED_STATES:
            assert hasattr(answer,'__call__')
            (search_intent,search_addition)=search_sequence
            answer=answer(search_intent,search_addition,intent,addition)
            assert type(answer)==list
            answer=format_list(answer)
        if new_state==GIVEN_CHOOSE:
            assert hasattr(answer,'__call__')
            (search_intent,search_addition)=search_sequence
            answer=answer(search_intent,search_addition,return_type='url',num=addition)
        if (new_state,None) in policy:
            new_state,_=policy[new_state,None]
        return answer,new_state,search_sequence
    else:
        return DEFAULT[0],state,search_sequence

def format_list(title_list):
    return SHOW_LIST[0].format('
'.join(['"'+title+'"' for title in title_list]))

def start():
    state=0
    answer=INIT_GREETINGS[0]
    search_sequence=('','')
    return answer,state,search_sequence

def bot_template(answer):
    if type(answer)==str:
        print('bot:{0}'.format(answer))
    else:
        print('bot:{0}'.format(''))

if __name__=='__main__':
    from generate import read,sort
    TEST_TYPE=1
    user_template='user:{0}'
    bot_template='bot:{0}'
    answer,state,search_sequence=start()
    if TEST_TYPE==0:
        message=''
        while(message!='\n'):
            print(bot_template.format(answer))
            message=input('user:')
            answer,state,search_sequence=respond(message,state,search_sequence)
    if TEST_TYPE==1:
        messages=['hi, I want to read some news','keyword France']
        print(bot_template.format(answer))
        for message in messages:
            print(user_template.format(message))
            answer,state,search_sequence=respond(message,state,search_sequence)
            print(bot_template.format(answer))


#!/usr/bin/env python

'Take Photo Tests.'

import os
import sys
import unittest
os.environ['take_photo_disable_rotation_adjustment'] = '0'
import take_photo
import numpy as np
try:
    import farmware_tools
except ImportError:
    FT_IMPORTED = False
else:
    FT_IMPORTED = True
try:
    import cv2
except ImportError:
    CV2_IMPORTED = False
else:
    CV2_IMPORTED = True
try:
    from unittest import mock
except ImportError:
    import mock

OUTPUT_FILENAME = 'output.txt'

def read_output_file(output_file):
    'Read test output file.'
    output_file.close()
    with open(OUTPUT_FILENAME, 'r') as output_file:
        output = output_file.read().lower()
    sys.stdout = sys.__stdout__
    print('')
    print(os.environ)
    print('>' * 20)
    print(output)
    print('<' * 20)
    return output

os.environ.clear()
ENVS = [
    'take_photo_logging',
    'camera',
    'IMAGES_DIR',
    'take_photo_width',
    'take_photo_height',
    'take_photo_disable_rotation_adjustment',
    'CAMERA_CALIBRATION_total_rotation_angle',
    'FARMBOT_OS_VERSION',
    'FARMWARE_URL',
    'FARMWARE_TOKEN',
    'FARMWARE_API_V2_REQUEST_PIPE',
    'FARMWARE_API_V2_RESPONSE_PIPE',
]

def re_import():
    try:
        reload(take_photo)
    except NameError:
        import importlib
        importlib.reload(take_photo)

def _prepare_fuser_mock(**kwargs):
    def _fuser_mock(*_args):
        if kwargs.get('missing'):
            try:
                MissingError = FileNotFoundError
            except NameError:
                MissingError = OSError
            raise MissingError
        if kwargs.get('busy'):
            return b' 1 2 3'
        else:
            import subprocess
            raise subprocess.CalledProcessError
    return _fuser_mock

def _prepare_mock_capture(**kwargs):
    def mocked_video_capture(*_args):
        'Used by mock.'
        class MockVideoCapture():
            'Mock cv2.VideoCapture'

            @staticmethod
            def isOpened():
                'is camera open?'
                ret = kwargs.get('isOpened')
                return True if ret is None else ret

            @staticmethod
            def getBackendName():
                'get capture backend'
                if kwargs.get('raise_backend'):
                    raise NameError('mock error')
                return 'mock'

            @staticmethod
            def grab():
                'get frame'
                ret = kwargs.get('grab_return')
                return True if ret is None else ret

            @staticmethod
            def read():
                'get image'
                if kwargs.get('raise_read'):
                    raise NameError('mock error')
                default_return = True, np.zeros([10, 10, 3], np.uint8)
                return kwargs.get('read_return') or default_return

            @staticmethod
            def set(*_args):
                'set parameter'
                return

            @staticmethod
            def release():
                'close camera'
                return

        if kwargs.get('raise_open'):
            raise IOError('mock error')
        return MockVideoCapture()
    return mocked_video_capture

def _prepare_mock_socket(**_kwargs):
    def mocked_socket(*_args):
        class MockSocket():
            @staticmethod
            def connect(_): return
            @staticmethod
            def sendall(req): print(req)
            @staticmethod
            def recv(_): return
            @staticmethod
            def close(): return
        return MockSocket()
    return mocked_socket

class TakePhotoTest(unittest.TestCase):
    'Test Take Photo.'

    def setUp(self):
        for env in ENVS:
            try:
                del os.environ[env]
            except KeyError:
                pass
        os.environ['IMAGES_DIR'] = '/tmp'
        os.environ['take_photo_disable_rotation_adjustment'] = '0'
        self.outfile = open(OUTPUT_FILENAME, 'w')
        sys.stdout = self.outfile

    def test_default(self):
        'Test default Take Photo.'
        re_import()
        take_photo.take_photo()
        output = read_output_file(self.outfile)
        self.assertGreater(output.count('[ '), 3)
        self.assertLess(output.count('send_message'), 3)
        self.assertFalse('rotated' in output)

    def test_quiet(self):
        'Test quiet log level.'
        os.environ['take_photo_logging'] = 'quiet'
        re_import()
        take_photo.take_photo()
        output = read_output_file(self.outfile)
        self.assertFalse('[ ' in output)

    def test_verbose(self):
        'Test verbose log level.'
        os.environ['take_photo_logging'] = 'verbose'
        re_import()
        take_photo.take_photo()
        output = read_output_file(self.outfile)
        self.assertFalse('[ ' in output)
        if FT_IMPORTED:
            self.assertGreater(output.count('send_message'), 3)

    def test_timed_verbose(self):
        'Test timed verbose log level.'
        os.environ['take_photo_logging'] = 'verbose_timed'
        re_import()
        take_photo.take_photo()
        output = read_output_file(self.outfile)
        self.assertTrue('[ ' in output)
        if FT_IMPORTED:
            self.assertGreater(output.count('send_message'), 3)

    @unittest.skipIf(FT_IMPORTED, '')
    @mock.patch('requests.post', mock.Mock())
    def test_verbose_legacy(self):
        'Test verbose log level with legacy log.'
        os.environ['take_photo_logging'] = 'verbose'
        os.environ['FARMWARE_URL'] = 'url'
        os.environ['FARMWARE_TOKEN'] = 'token'
        re_import()
        take_photo.take_photo()
        output = read_output_file(self.outfile)
        self.assertFalse('[ ' in output)

    @mock.patch('os.listdir', mock.Mock(side_effect=lambda _: ['video0']))
    @mock.patch('os.path.exists', mock.Mock())
    @mock.patch('cv2.VideoCapture', _prepare_mock_capture())
    def test_capture_success(self):
        'Test image capture.'
        del os.environ['IMAGES_DIR']
        re_import()
        take_photo.take_photo()
        output = read_output_file(self.outfile)
        self.assertTrue('saved' in output)
        self.assertTrue('directory does not exist' in output)

    @mock.patch('os.listdir', mock.Mock(
        side_effect=lambda _: ['video0', 'video1', 'video2']))
    def test_not_at_port(self):
        'Test not at video ports.'
        del os.environ['IMAGES_DIR']
        re_import()
        take_photo.take_photo()
        output = read_output_file(self.outfile)
        self.assertFalse('saved' in output)

    @mock.patch('os.listdir', mock.Mock(side_effect=lambda _: ['video0']))
    @mock.patch('os.path.exists', mock.Mock())
    @mock.patch('cv2.VideoCapture', _prepare_mock_capture(raise_open=True))
    def test_camera_open_error(self):
        'Test error on camera open.'
        re_import()
        take_photo.take_photo()
        output = read_output_file(self.outfile)
        self.assertTrue('mock error' in output)
        self.assertTrue('could not connect' in output)

    @mock.patch('os.listdir', mock.Mock(side_effect=lambda _: ['video0']))
    @mock.patch('os.path.exists', mock.Mock())
    @mock.patch('cv2.VideoCapture', _prepare_mock_capture(raise_backend=True))
    def test_camera_get_backend_error(self):
        'Test error on get backend.'
        re_import()
        take_photo.take_photo()
        output = read_output_file(self.outfile)
        self.assertTrue('not available' in output)

    @mock.patch('os.listdir', mock.Mock(side_effect=lambda _: ['video0']))
    @mock.patch('os.path.exists', mock.Mock())
    @mock.patch('cv2.VideoCapture', _prepare_mock_capture(raise_read=True))
    def test_camera_read_error(self):
        'Test error on camera read.'
        re_import()
        take_photo.take_photo()
        output = read_output_file(self.outfile)
        self.assertTrue('mock error' in output)
        self.assertTrue('image capture error' in output)

    @mock.patch('os.listdir', mock.Mock(side_effect=lambda _: ['video0']))
    @mock.patch('os.path.exists', mock.Mock())
    @mock.patch('subprocess.check_output',
                mock.Mock(side_effect=_prepare_fuser_mock(missing=True)))
    @mock.patch('cv2.VideoCapture', _prepare_mock_capture())
    def test_camera_no_busy_check(self):
        'Test unable to check if camera is busy.'
        re_import()
        take_photo.take_photo()
        output = read_output_file(self.outfile)
        self.assertTrue('unable to check' in output)

    @mock.patch('os.listdir', mock.Mock(side_effect=lambda _: ['video0']))
    @mock.patch('os.path.exists', mock.Mock())
    @mock.patch('subprocess.check_output',
                mock.Mock(side_effect=_prepare_fuser_mock(busy=True)))
    @mock.patch('cv2.VideoCapture', _prepare_mock_capture())
    def test_camera_busy(self):
        'Test camera busy.'
        re_import()
        take_photo.take_photo()
        output = read_output_file(self.outfile)
        self.assertTrue('attempting to close' in output)

    @mock.patch('os.listdir', mock.Mock(side_effect=lambda _: ['video0']))
    @mock.patch('os.path.exists', mock.Mock())
    @mock.patch('cv2.VideoCapture', _prepare_mock_capture(isOpened=False))
    def test_camera_not_open(self):
        'Test camera not open.'
        re_import()
        take_photo.take_photo()
        output = read_output_file(self.outfile)
        self.assertTrue('could not connect' in output)

    @mock.patch('os.listdir', mock.Mock(side_effect=lambda _: ['video0']))
    @mock.patch('os.path.exists', mock.Mock())
    @mock.patch('cv2.VideoCapture',
                _prepare_mock_capture(read_return=(False, None)))
    def test_no_image(self):
        'Test no image.'
        re_import()
        take_photo.take_photo()
        output = read_output_file(self.outfile)
        self.assertTrue('no image' in output)

    @mock.patch('os.listdir', mock.Mock(side_effect=lambda _: ['video0']))
    @mock.patch('os.path.exists', mock.Mock())
    @mock.patch('cv2.VideoCapture', _prepare_mock_capture(grab_return=False))
    def test_no_grab_image(self):
        'Test no grab return.'
        re_import()
        take_photo.take_photo()
        output = read_output_file(self.outfile)
        self.assertTrue('could not get frame' in output)

    @mock.patch('os.listdir', mock.Mock(side_effect=lambda _: ['video0']))
    @mock.patch('os.path.exists', mock.Mock())
    @mock.patch('os.path.isdir', mock.Mock())
    @mock.patch('cv2.VideoCapture', _prepare_mock_capture())
    def test_rotated(self):
        'Test image rotation.'
        os.environ['CAMERA_CALIBRATION_total_rotation_angle'] = '45'
        re_import()
        take_photo.take_photo()
        output = read_output_file(self.outfile)
        self.assertTrue('rotated' in output)
        self.assertFalse('directory does not exist' in output)

    @mock.patch('os.listdir', mock.Mock(side_effect=lambda _: ['video0']))
    @mock.patch('os.path.exists', mock.Mock())
    @mock.patch('os.path.isdir', mock.Mock())
    @mock.patch('cv2.VideoCapture', _prepare_mock_capture())
    def test_large_rotation(self):
        'Test large image rotation.'
        os.environ['CAMERA_CALIBRATION_total_rotation_angle'] = '75'
        re_import()
        take_photo.take_photo()
        output = read_output_file(self.outfile)
        self.assertTrue('rotated' in output)
        self.assertFalse('directory does not exist' in output)

    def test_none_camera(self):
        'Test none camera selection.'
        os.environ['camera'] = 'none'
        re_import()
        take_photo.take_photo()
        output = read_output_file(self.outfile)
        self.assertTrue('no camera selected' in output)
        self.assertFalse('USB' in output)

    def test_rpi_camera(self):
        'Test rpi camera selection.'
        os.environ['camera'] = 'rpi'
        re_import()
        take_photo.take_photo()
        output = read_output_file(self.outfile)
        self.assertTrue('raspberry pi' in output)
        self.assertTrue('raspistill' in output)
        self.assertTrue('-w 640 -h 480' in output)
        self.assertFalse('-md 3' in output)
        self.assertFalse('USB' in output)

    def test_rpi_camera_small_size(self):
        'Test capture with rpi camera selection and small size inputs.'
        os.environ['camera'] = 'rpi'
        os.environ['take_photo_width'] = '200'
        os.environ['take_photo_height'] = '100'
        re_import()
        take_photo.take_photo()
        output = read_output_file(self.outfile)
        self.assertTrue('raspistill' in output)
        self.assertTrue('-w 200 -h 100' in output)
        self.assertFalse('-md 3' in output)

    def test_rpi_camera_large_size(self):
        'Test capture with rpi camera selection and large size inputs.'
        os.environ['camera'] = 'rpi'
        os.environ['take_photo_width'] = '2000'
        os.environ['take_photo_height'] = '2000'
        re_import()
        take_photo.take_photo()
        output = read_output_file(self.outfile)
        self.assertTrue('raspistill' in output)
        self.assertTrue('-md 3' in output)
        self.assertFalse('-w' in output)

    @mock.patch('cv2.imread', mock.Mock(side_effect=lambda _:
                                        np.zeros([10, 10, 3], np.uint8)))
    @mock.patch('os.remove', mock.Mock())
    @mock.patch('subprocess.call', mock.Mock(side_effect=lambda _: 0))
    def test_rpi_camera_capture(self):
        'Test rpi camera capture success.'
        os.environ['camera'] = 'rpi'
        re_import()
        take_photo.take_photo()
        output = read_output_file(self.outfile)
        self.assertTrue('raspberry pi' in output)
        self.assertTrue('image captured' in output)

    @mock.patch('subprocess.call', mock.Mock(side_effect=lambda _: 1))
    def test_rpi_camera_capture_failure(self):
        'Test rpi camera capture failure.'
        os.environ['camera'] = 'rpi'
        re_import()
        take_photo.take_photo()
        output = read_output_file(self.outfile)
        self.assertTrue('raspberry pi' in output)
        self.assertTrue('not detected' in output)

    @mock.patch('subprocess.call', mock.Mock(side_effect=lambda _: 0))
    def test_quick_rpi_camera(self):
        'Test quick capture with rpi camera selection.'
        os.environ['take_photo_disable_rotation_adjustment'] = '1'
        os.environ['camera'] = 'rpi'
        with self.assertRaises(SystemExit):
            re_import()
        output = read_output_file(self.outfile)
        self.assertTrue('raspistill' in output)
        self.assertFalse('fswebcam' in output)
        self.assertFalse('no camera selected' in output)

    @mock.patch('os.listdir', mock.Mock(side_effect=lambda _: ['video0']))
    @mock.patch('subprocess.call', mock.Mock(side_effect=lambda _: 0))
    def test_quick_usb_camera(self):
        'Test quick capture with usb camera selection.'
        os.environ['take_photo_disable_rotation_adjustment'] = '1'
        os.environ['camera'] = 'usb'
        with self.assertRaises(SystemExit):
            re_import()
        output = read_output_file(self.outfile)
        self.assertFalse('raspistill' in output)
        self.assertTrue('fswebcam' in output)
        self.assertFalse('no camera selected' in output)

    @mock.patch('os.listdir', mock.Mock(side_effect=lambda _: ['video0']))
    @mock.patch('subprocess.call', mock.Mock(side_effect=lambda _: 0))
    def test_quick_usb_camera_image_size(self):
        'Test quick capture with usb camera and image size selection.'
        os.environ['take_photo_disable_rotation_adjustment'] = '1'
        os.environ['take_photo_width'] = '200'
        os.environ['take_photo_height'] = '100'
        os.environ['camera'] = 'usb'
        with self.assertRaises(SystemExit):
            re_import()
        output = read_output_file(self.outfile)
        self.assertFalse('raspistill' in output)
        self.assertTrue('fswebcam' in output)
        self.assertTrue('200x100' in output)
        self.assertFalse('no camera selected' in output)

    @mock.patch('subprocess.call', mock.Mock(side_effect=lambda _: 0))
    def test_quick_usb_camera_missing_port(self):
        'Test quick capture with usb camera selection, video port missing.'
        os.environ['take_photo_disable_rotation_adjustment'] = '1'
        os.environ['camera'] = 'usb'
        with self.assertRaises(SystemExit):
            re_import()
        output = read_output_file(self.outfile)
        self.assertFalse('raspistill' in output)
        self.assertFalse('fswebcam' in output)
        self.assertFalse('no camera selected' in output)
        self.assertTrue('not detected' in output)

    def test_quick_none_camera(self):
        'Test quick capture with none camera selection.'
        os.environ['take_photo_disable_rotation_adjustment'] = '1'
        os.environ['camera'] = 'none'
        with self.assertRaises(SystemExit):
            re_import()
        output = read_output_file(self.outfile)
        self.assertFalse('raspistill' in output)
        self.assertFalse('fswebcam' in output)
        self.assertTrue('no camera selected' in output)

    @unittest.skipIf(sys.version_info[0] < 3, '')
    @mock.patch('socket.socket', _prepare_mock_socket())
    def test_quick_none_camera_with_log(self):
        'Test quick capture with none camera selection and log.'
        os.environ['FARMWARE_API_V2_REQUEST_PIPE'] = ''
        os.environ['FARMWARE_API_V2_RESPONSE_PIPE'] = ''
        os.environ['take_photo_disable_rotation_adjustment'] = '1'
        os.environ['camera'] = 'none'
        with self.assertRaises(SystemExit):
            re_import()
        output = read_output_file(self.outfile)
        self.assertFalse('raspistill' in output)
        self.assertFalse('fswebcam' in output)
        self.assertTrue('no camera selected' in output)

    def test_quick_none_camera_quiet(self):
        'Test quick capture with none camera selection: quiet.'
        os.environ['take_photo_disable_rotation_adjustment'] = '1'
        os.environ['camera'] = 'none'
        os.environ['take_photo_logging'] = 'quiet'
        with self.assertRaises(SystemExit):
            re_import()
        output = read_output_file(self.outfile)
        self.assertFalse('no camera selected' in output)

    @unittest.skipIf(CV2_IMPORTED, '')
    def test_opencv_missing(self):
        'Test for cv2 import error.'
        with self.assertRaises(SystemExit):
            re_import()
        output = read_output_file(self.outfile)
        self.assertTrue('import error' in output)

    def tearDown(self):
        self.outfile.close()
        sys.stdout = sys.__stdout__
        os.remove(OUTPUT_FILENAME)


from selenium import webdriver
from bs4 import BeautifulSoup
import time
import re
import pandas as pd

# Creating a webdriver instance
driver = webdriver.Chrome("C:/Users/Lenovo/Downloads/Compressed/chromedriver/chromedriver.exe")
# This instance will be used to log into LinkedIn

# Opening linkedIn's login page
driver.get("https://linkedin.com/uas/login")

# waiting for the page to load
time.sleep(5)

# entering username
username = driver.find_element_by_id("username")
# Enter Your Email Address
username.send_keys("insert email here")

# entering password
pword = driver.find_element_by_id("password")
# Enter Your Password
pword.send_keys("insert password here")

# Clicking on the log in button
# Format (syntax) of writing XPath -->
# //tagname[@attribute='value']
driver.find_element_by_xpath("//button[@type='submit']").click()
# In case of an error, try changing the
# XPath used here.

df = pd.DataFrame()

profile_urls = [line.strip() for line in open('links.txt', 'r')]

for urls in profile_urls:

    driver.get(urls)
    # this will open the link

    time.sleep(3)

    initialScroll = 0
    finalScroll = 1000

    driver.execute_script(f"window.scrollTo({initialScroll},{finalScroll}) ")

    try:

        src = driver.page_source

        # Now using beautiful soup
        soup = BeautifulSoup(src, 'lxml')

        # Extracting the HTML of the complete introduction box
        # that contains the name, company name, and the location
        intro = soup.find('ul', {'class': 'pvs-list'})

        name = soup.find('div', {'class': 'artdeco-entity-lockup__title'})

        name = ''.join(re.split("[\n\s]{2,}", name.text)).replace("(He/Him)",'').replace("(She/Her)",'')

        experience = intro.find_all('li', {'class': 'pvs-list__paged-list-item'})

        n=0
        for k in experience:
            if k.find('li', {'class': ['pvs-list__paged-list-item','artdeco-list__item','pvs-list__item--line-separated']}):
                company = k.find('span', {'class': 'visually-hidden'}).text
                n=len(k.find_all('li', {'class': ['pvs-list__paged-list-item','artdeco-list__item','pvs-list__item--line-separated']}))
                continue
            else:
                if n>0:
                    if not any(char.isdigit() for char in k.find_all('span', {'class': 'visually-hidden'})[1].text):
                        duration = k.find_all('span', {'class': 'visually-hidden'})[2].text
                    else:
                        duration = (k.find_all('span', {'class': 'visually-hidden'})[1].text)
                    df = df.append({"Nama": name,
                                    "Perusahaan": company,
                                    "Posisi": k.find_all('span', {'class': 'visually-hidden'})[0].text,
                                    "Durasi": duration,
                                    "Link": urls
                                    }, ignore_index=True)
                    n-=1
                else:
                    try:
                        df = df.append({"Nama": name,
                                    "Posisi": k.find_all('span', {'class': 'visually-hidden'})[0].text,
                                    "Perusahaan": k.find_all('span', {'class': 'visually-hidden'})[1].text,
                                    "Durasi": k.find_all('span', {'class': 'visually-hidden'})[2].text,
                                    "Link": urls
                                    }, ignore_index=True)
                    except:
                        continue
    except:
        continue