import setuptools
from setuptools import find_namespace_packages

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

setuptools.setup(
    name="JarvisAI",
    version="3.9",
    author="Dipesh",
    author_email="dipeshpal17@gmail.com",
    description="JarvisAI is python library to build your own AI virtual assistant with natural language processing.",
    long_description=long_description,
    long_description_content_type="text/markdown",
    url="https://github.com/Dipeshpal/Jarvis_AI",
    include_package_data=True,
    packages=find_namespace_packages(include=['JarvisAI.*', 'JarvisAI']),
    install_requires=['numpy', 'gtts==2.2.1', 'playsound==1.2.2',
                      'SpeechRecognition==3.8.1', 'pipwin==0.5.0', 'lxml==4.6.1', 'pyjokes',
                      'beautifulsoup4==4.9.3', 'wikipedia==1.4.0', 'auto_face_recognition', 'transformers==4.3.2',
                      'lazyme==0.0.23', 'librosa==0.8.0', "torch==1.7.1", "requests", "opencv-contrib-python==4.5.2.52",
                      "opencv-python==4.5.2.52", "cvzone==1.1.1", "pyttsx3", "googlesearch-python", "spacy",
                      "mediapipe==0.8.8", "googlesearch-python==1.0.1", "youtube-search-python==1.5.3", "shutup==0.1.3"],

    classifiers=[
        "Programming Language :: Python :: 3",
        "License :: OSI Approved :: MIT License",
        "Operating System :: OS Independent",
    ],
    python_requires='>=3.6',
    project_urls={
        'Documentation': 'https://github.com/Dipeshpal/Jarvis_AI',
        'Donate': 'https://www.buymeacoffee.com/dipeshpal',
        'Say Thanks!': 'https://youtube.com/techportofficial',
        'Source': 'https://github.com/Dipeshpal/Jarvis_AI',
    },
)


__author__ = 'Vincent'

from scrapy.spiders import CrawlSpider, Rule
from scrapy.contrib.linkextractors import LinkExtractor
from scrapy.selector import HtmlXPathSelector
from mediascrap.items import NewsItem
import datetime

from pymongo import MongoClient

class ChokomagSpider(CrawlSpider):
    """
    A spider crawls domains (in accordance with some  rules we will define
    to collect all the pages that we wish to extract our LemondeItems instances
    from. Most of this crawling logic is provided by Scrapy in the CrawlSpider class, so we
    can extend this class when writing our first spider.
    """

    name = "chokomag"
    allowed_domains =["chokomag.com"]
    start_urls =[
       "http://chokomag.com/beaute/cheveux/",
        "http://chokomag.com/tag/make-up/",

        "http://chokomag.com/beaute/box/",
    "http://chokomag.com/beaute/soins/",
    "http://chokomag.com/beaute/parfums/",
    "http://chokomag.com/mode/",
    "http://chokomag.com/tag/concours/",
    "http://chokomag.com/non-classe/"
    ]
    rules = [
        #site which should be saved
        Rule(
            LinkExtractor(
                allow = ['/(\d+|\w+)']),
                'parse_page')]

    def parse_page(self,response):
        hxs = HtmlXPathSelector(response)

        body = ''.join(hxs.select('//div[@class="entry-content clearfix"]/p//text()').extract()).strip()

        item = NewsItem()

        if len(body)> 0 :
            item['body'] = body
            item['url'] = response.url
            item['timeOfScrap'] = datetime.datetime.now()

            return item
        else :
            pass


"""
Data readers for remote sensing devices
=======================================
Written by Eliot Quon (eliot.quon@nrel.gov)

This is a collection of readers to be used with the NWTC datatools.wfip2
module for processing WFIP2 data downloaded from the A2e Data Archive
and Portal (DAP). No effort is made to standardize the names of the
dataframe columns and the original data headers are retained wherever
possible.

"""
import numpy as np
import pandas as pd

import codecs # for utf-8 handling

#
# Lidar data readers
#

def windcube_v1(fname,
                return_header=False,
                default_columns=None,
                default_altitudes=None,
                ):
    """WindCube v1
    Users: CU Boulder, ...

    The default columns and altitudes are used when there is no header
    in the file. Can optionally return a dictionary of lidar operating
    parameters parsed from the header.
    """
    scan_info = dict()

    # gives "UnicodeDecodeError: 'utf-8' codec can't decode byte ... in
    #   position ...: invalid start byte" error
    #with open(fname,'r') as f:

    with open(fname,'r',encoding='utf-8',errors='ignore') as f:
        firstline = f.readline()
        if '=' in firstline:
            # we have a header
            Nheader = int(firstline.split('=')[-1])
            for _ in range(Nheader):
                line = f.readline()
                if '=' in line:
                    param_value = line.strip().split('=')
                    try:
                        ival = int(param_value[1])
                        scan_info[param_value[0]] = ival # integer
                    except ValueError:
                        try:
                            fval = float(param_value[1])
                            scan_info[param_value[0]] = fval # float
                        except ValueError:
                            scan_info[param_value[0]] = param_value[1] # string
            # assume first column is "Date" which actuatlly corresponds to two
            #   separate date and time columns
            columns = ['date','time'] + f.readline().split()[1:]
            altitudes = np.array([ float(h)
                    for h in scan_info['Altitudes(m)'].strip().split('\t') ])
        else:
            # some files have no header, let's hope for the best...
            f.seek(0)
            columns = default_columns
            altitudes = default_altitudes

        df = pd.read_table(f,
                           delim_whitespace=True,
                           names=columns,
                           parse_dates=[['date', 'time']],
                           dayfirst=True)

    # unpivot the columns
    um_vars = [ 'um'+str(i) for i in range(1,len(altitudes)+1) ]
    vm_vars = [ 'vm'+str(i) for i in range(1,len(altitudes)+1) ]
    um = pd.melt(df, id_vars=['date_time'], var_name='um_var', value_name='um', value_vars=um_vars)
    vm = pd.melt(df, id_vars=['date_time'], var_name='vm_var', value_name='vm', value_vars=vm_vars)
    um['height'] = um['um_var'].map(dict(zip(um_vars, altitudes)))
    vm['height'] = vm['vm_var'].map(dict(zip(vm_vars, altitudes)))
    newdf = pd.merge(um, vm, on=['date_time','height'])

    # calculate wind speed and direction
    newdf['speed'] = np.sqrt(newdf['um']**2 + newdf['vm']**2)
    newdf['direction'] = 270.0 - 180.0/np.pi*np.arctan2(newdf['vm'],newdf['um'])
    newdf.loc[newdf['direction'] > 360.0,'direction'] -= 360.0

    # return calculated columns only
    newdf = newdf[['date_time','height','speed','direction']]
    if return_header:
        return newdf, scan_info
    else:
        return newdf

#
# Radar data readers
#

def read_profiler_data_block(f,datatypes=['WINDS','RASS']):
    """Dependency for wind_profiler radar"""
    # Line 1 (may not be present for subsequent blocks within the same file
    if f.readline().strip() == '':
        f.readline() # Line 2: station name
    assert(f.readline().split()[0] in datatypes) # Line 3: WINDS, version
    f.readline() # Line 4: lat (N), long (W), elevation (m)
    Y,m,d,H,M,S,_ = f.readline().split() # Line 5: date
    date_time = pd.to_datetime('20{}{}{} {}{}{}'.format(Y,m,d,H,M,S))
    f.readline() # Line 6: consensus averaging time
    f.readline() # Line 7: beam info
    f.readline() # Line 8: beam info
    f.readline() # Line 9: beam info
    f.readline() # Line 10: beam info
    header = f.readline().split()
    header = [ col + '.' + str(header[:i].count(col))
               if header.count(col) > 1
               else col
               for i,col in enumerate(header) ]
    block = []
    line = f.readline()
    while not line.strip()=='$' and not line=='':
        block.append(line.split())
        line = f.readline()
    df = pd.DataFrame(data=block,columns=header,dtype=float)
    df['date_time'] = date_time
    return df

def radar_profiler(fname,
                   modes=2,
                   check_na=['SPD','DIR'],
                   na_values=999999):
    """Wind Profiler radar with RASS
    Users: Earth Sciences Research Laboratory (ESRL)

    Assumed data format for consensus data format rev 5.1 based on
    provided reference for rev 4.1 from:
    https://a2e.energy.gov/data/wfip2/attach/915mhz-cns-winds-data-format.txt

    Set 'modes' to None to read all blocks in the file

    Additional data format reference:
    https://www.esrl.noaa.gov/psd/data/obs/formats/
    """
    dataframes = []
    with open(fname,'r') as f:
        if modes is not None:
            for _ in range(modes):
                dataframes.append(read_profiler_data_block(f))
        else:
            while True:
                try:
                    dataframes.append(read_profiler_data_block(f))
                except (IOError,IndexError):
                    break
    df = pd.concat(dataframes)
    if na_values is not None:
        nalist = []
        for col in check_na:
            if col in df.columns:
                matches = [col]
            else:
                matches = [ c for c in df.columns if c.startswith(col+'.') ]
            if len(matches) > 0:
                nalist += matches
            else:
                print('Note: column '+col+'* not found')
        check_na = nalist
        if not hasattr(na_values,'__iter__'):
            na_values = [na_values]
        #print('Checking',check_na,'for',na_values)
        for val in na_values:
            #df.loc[df['SPD']==val,'SPD'] = np.nan # flag bad values
            #df.loc[df['DIR']==val,'DIR'] = np.nan # flag bad values
            for col in check_na:
                df.loc[df[col]==val,col] = np.nan # flag bad values
    return df

# aliases, for backward compatibility
ESRL_wind_profiler = radar_profiler
"""ESRL profiler configuration for WFIP 2 experiment:
* 'WINDS' output has 2 sets of returns (configuration modes) per file
* 'RASS' has only 1
                                 WINDS(1)  WINDS(2)      RASS
consensus averaging time [min]       24.0      24.0       3.0
beams                                 3.0       3.0       1.0
range gates                          44.0      61.0      25.0
coherant integrations               160.0      76.0      10.0
spectral averages                    50.0      50.0      28.0
pulse width [ns]                    417.0     708.0     417.0
inner pulse period [ms]              25.0      53.0       2.0
full-scale Doppler value [m/s]       20.5      20.3     409.6
delay to first gate [ns]           3792.0    4958.0    4000.0
"""

TTU_radar_profiler = radar_profiler

#
# Sodar data readers
#

# PCSodar data block format description: https://a2e.energy.gov/data/wfip2/attach/variables-in-datafile.pdf
PCSodar_header = [
        'height_m','windspeed_ms','winddirection_deg','reliability',
        'w_speed_ms','w_reliability','w_count','w_stdev_ms','w_amplitude','w_noise','w_SNR','w_valid_count',
        'v_speed_ms','v_reliability','v_count','v_stdev_ms','v_amplitude','v_noise','v_SNR','v_valid_count',
        'u_speed_ms','u_reliability','u_count','u_stdev_ms','u_amplitude','u_noise','u_SNR','u_valid_count',
        ]

def ARL_wind_profiler(fname,
                      bad_speed_value=-99.9,
                      bad_direction_value=999):
    """ARL Wind Profiler
    Users: Air Resources Laboratory (ARL), ...

    Read each block within a file (in PCSodar format) as a separate
    dataframe, and then return a concatenated dataframe
    """
    dataframes = []
    Nh = len(range_gates)
    with open(fname,'r') as f:
        firstline = f.readline()
        while not firstline=='':
            _,year,month,day,time,_ = firstline.replace('"','').split(',')
            date_time = pd.to_datetime('{}{}{} {}'.format(year,month,day,time[:5])) # time format is "HH:MM"
            f.readline() # ignore sodar operating parameters
            block = []
            for _ in range(Nh):
                block.append(f.readline().strip().split(','))
            df = pd.DataFrame(data=block,columns=header,dtype=float)
            assert(np.all(df['height_m'].values==range_gates)) # make sure we're always reading the number of rows we think we are
            df['date_time'] = date_time
            df.loc[df['windspeed_ms']==bad_speed_value,'windspeed_ms'] = np.nan # flag bad values
            df.loc[df['winddirection_deg']==bad_direction_value,'winddirection_deg'] = np.nan # flag bad values
            dataframes.append(df)
            firstline = f.readline()
    return pd.concat(dataframes)

def scintec_profiler(fname):
    """Scintec MFAS Flat Array Sodar

    Reads files in the APRun file format:
    https://a2e.energy.gov/data/wfip2/attach/sodar-aprun-software-manual-1-27.pdf (p.20)

    Returned timestamps correspond to the BEGINNING of each measurement
    interval
    """
    dflist = []
    with open(fname,'r') as f:
        f.readline() # FORMAT-1
        dateline = f.readline() # YYYY-MM-DD HH:MM:SS file_count
        datetime0 = pd.to_datetime(' '.join(dateline.split()[:2]))
        f.readline() # type of instrument
        number_of = f.readline().split() # comment lines, variables, height levels
        Ncomments,Nvar,Nz = [ int(val) for val in number_of ]
        f.readline() # blank
        for _ in range(3): f.readline() # file information section
        for _ in range(Ncomments): f.readline()
        for _ in range(3): f.readline() # file type section
        assert(f.readline().strip() == 'Main Data')
        for _ in range(3): f.readline() # variable defintions section
        columns = []
        na_values = {}
        for _ in range(Nvar+1):
            defn = f.readline().strip().split('#') # e.g. "wind speed # speed # m/s # G1 # 0 # 99.99"
            col = defn[0].strip()
            columns.append(col)
            try:
                na_values[col] = float(defn[-1])
            except ValueError: pass
        for _ in range(3): f.readline() # beginning of data block
        firstread = True
        f.readline()
        # read profiles
        while True:
            timedata = f.readline().split() #  [YYYY-MM-DD, day] [HH:MM:SS, end time of interval] [HH:MM:SS, interval duration]
            if len(timedata) < 3: break
            datetime_end = pd.to_datetime(timedata[0]+' '+timedata[1])
            duration = pd.to_timedelta(timedata[2])
            datetime_start = datetime_end - duration
            if firstread:
                assert(datetime_end == datetime0)
                firstread = False
            data = []
            f.readline() # skip column names
            for _ in range(Nz): data.append(f.readline().split())
            df = pd.DataFrame(data=data,columns=columns)
            df['datetime'] = datetime_start
            dflist.append(df)
            f.readline()
    df = pd.concat(dflist)
    df['height'] = pd.to_numeric(df['height'])
    for col,nan in na_values.items():
        df.loc[df[col]==nan,col] = np.nan # flag bad values
    return df

#
# Microwave radiometer data readers
#

def ESRL_radiometrics_mwr(fname,verbose=True):
    """NOAA/PSD Microwave Radiometer level 2 files

    https://a2e.energy.gov/data/wfip2/attach/level2-files-record-types.pdf
    Additional formatting are inferred...
    """
    records = dict()
    with open(fname,'r') as f:
        for line in f:
            line = line.strip().split(',')
            if not line[0] == 'Record': break
            rec_id = int(line[2])
            records[rec_id] = line[3:]
    Nrecords = len(records.keys())
    if verbose: print(Nrecords, 'records', records.keys(), 'read')

    def record_header(record_id):
        header_id = record_id - record_id%10
        assert(header_id in records.keys())
        return ['datetime','id'] + records[header_id]

    # read entire file at once
    with open(fname,'r') as f:
        for _ in range(Nrecords): f.readline()
        #rawdata = [ line.strip().split(',')[1:] for line in f.readlines() ]
        rawdata = [ line.strip().rstrip(',').split(',')[1:] for line in f.readlines() ]
    if verbose: print(len(rawdata),'lines read')

    # sort data by record type (can't read all at once because each line
    # has a different length)
    data = dict()
    datanames = dict()
    for linesplit in rawdata:
        # split line format: datetime, record_number, record_data
        rec = int(linesplit[1])
        if rec == 99:
            if verbose: print('[99] ',' '.join(linesplit[2:]))
        elif rec == 101:
            datanames[int(linesplit[2])] = linesplit[3]
        else:
            try:
                data[rec].append(linesplit)
            except KeyError:
                data[rec] = [linesplit]
    if verbose: print(len(data.keys()), 'data sets', data.keys(), 'read')
    if verbose: print('data names:',datanames)

    for record_id in data.keys():
        if verbose: print('Processing',record_id,record_header(record_id))
        df = pd.DataFrame(data=data[record_id],
                          columns=record_header(record_id),
                          dtype=float)
        df['datetime'] = pd.to_datetime(df['datetime'])
        data[record_id] = df

    for record_id, record_name in datanames.items():
        if verbose: print('Renaming record',record_id,' --> ',record_name)
        data[record_name] = data.pop(record_id)

    return data

#
# Ceilometer
#

def Vaisala_CL31(fname,verbose=True,zcol=8,unpack=True,
                 status_col='Status',
                 cloud_cols=['Height1','Height2','Height3']):
    """Vaisala CL31 ceilometer XLSX output processed with CL-VIEW software
    Assume we want heights in meters

    https://a2e.energy.gov/data/wfip2/attach/datafilexlsx-example.pdf
    """
    if verbose: print('Loading '+fname+'...')
    xlsx = pd.read_excel(fname)
    header = xlsx.iloc[2].values
    header2 = xlsx.iloc[3].values
    header[0] = 'Date'
    header[1] = 'Time'
    if verbose:
        # note: first row of excel spreadsheet gets put into the header # (skipped row)
        print(xlsx.iloc[0,0]) # skipped row
        print(xlsx.iloc[1,0]) # skipped row
        print('Cloud height units:',header2[3:6])
        print('Backscatter height units:',header2[zcol-1])
        print(xlsx.iloc[-1,0]) # skipped row
    header[zcol-1:] = header2[zcol-1:]

    # now create a new dataframe without extra header information
    df = pd.DataFrame(data=xlsx.iloc[4:-1].values, columns=header)
    df = df.replace('/////', np.nan)

    # create timestamps
    df['date_time'] = df[['Date','Time']].apply(lambda x: pd.datetime.combine(x[0].date(),x[1]), axis=1)
    df = df.set_index('date_time')

    df = df.drop(['Date','Time','Sig. Sum','Meters'],axis=1)

    # split up dataframe
    if unpack:
        status = df[status_col]
        clouds = df[cloud_cols]
        backscatter = df.drop([status_col]+cloud_cols, axis=1)
        return backscatter, clouds, status
    else:
        return df


from  Data import Data
class Delete:
    def __init__(self):
        self.Data=Data()
    def run(self,arr):
        print(arr[1][1])
        if arr[1][0]=='@':
            num=Data.find_name_or_id_by_id_or_name(arr[1][1],1)
        else:
            num='#'+str(arr[1][1])

        z=self.Data.find(arr[1])
        print(z)
        print("Do you really want to delete " + str(z[1]) +": " +str(z[2]) +" ?" )
        print("Please confirm by 'y' or 'Y', or cancel by 'n' or 'N'.")
        value = input("> confirm >>>")
        if value=="y" or value=="Y":
            print(num)
            self.Data.delete(num)
        elif value!= "n" or value!="N":
            print("You have typed an invalid response. Please either confirm by 'y'/'Y', orcancel by 'n'/'N'.")


import cv2
import os
import argparse

def image_folder_to_video(folder_path, output_path):
    # Get the list of image filenames
    filenames = [os.path.join(folder_path, f) for f in os.listdir(folder_path) if f.lower().endswith('.jpg')]
    filenames.sort()  # Sort the filenames

    # Get the dimensions of the first image
    image = cv2.imread(filenames[0])
    height, width, _ = image.shape

    # Define the codec and create a video writer object
    fourcc = cv2.VideoWriter_fourcc(*'mp4v')
    out = cv2.VideoWriter(output_path, fourcc, 30.0, (width, height))

    # Add each image to the video with 0.2 seconds of duration
    for filename in filenames:
        image = cv2.imread(filename)
        for i in range(15):
            out.write(image)

    # Release the video writer object
    out.release()

def main():
    parser = argparse.ArgumentParser(description='Convert a folder of images to a video.')
    parser.add_argument('input_folder', metavar='input_folder', type=str,
                        help='The path to the folder containing the input images.')
    parser.add_argument('output_video', metavar='output_video', type=str,
                        help='The path to the output video file.')
    args = parser.parse_args()
    input_folder = args.input_folder
    output_video = args.output_video
    image_folder_to_video(input_folder, output_video)

if __name__ == "__main__":
    main()


#David Crespo, 2017
class Web:
	def __init__(self, datos):
		self.frm = self.partir(datos)
		self.pttn = self.get_peticion()
		self.mtd = self.pttn[0]
		self.webfile = self.pttn[1]
		self.direccion = None
		self.tiene_extension = False
		self.cmds = self.get_comandos()
		self.get_direccion()
	def partir(self, datos):
		datos = datos.decode('utf-8')
		return datos.split('\r\n')
	def get_peticion(self):
		datos = self.frm[0]
		return datos.split(' ')
	def get_metodo(self):
		return self.mtd
	def not_found(self):
		self.direccion = 'sistema/404.html'
	def get_direccion(self):
		if self.webfile == '/':
			self.direccion = 'webs/index.html'
		else:
			try:
				ext = self.extension(self.webfile)
				if self.tiene_extension == False:
					self.direccion = self.get_directorio()+self.webfile+'.'+ext
				else:
					self.direccion = self.get_directorio()+self.webfile
				return self.direccion
			except:
				self.not_found()
				return self.direccion
	def get_directorio(self):
		ext = self.extension(self.webfile)
		sel_directorio = {
						'htm': 'webs',
						'html': 'webs',
						'css': 'css',
						'ico': 'imgs',
						'jpg': 'imgs',
						'jpeg': 'imgs',
						'pdf': 'docs',
						'js': 'scripts',
						'avi': 'media',
						'mp3': 'media',
						'zip': 'varios',
						'ogg': 'media',
						'ttf': 'fonts',
						'mp4': 'media',
						'mkv': 'media',
						'png': 'imgs',
						'rar': 'varios'}
		return sel_directorio.get(ext)
	def comandos(self):
		return self.cmds.split('&')
	def ordenes(self):
		lista = []
		com = []
		for i in self.comandos():
			com = i.split('=')
			lista += [com]
		return lista
	def get_comandos(self):
		a=0
		for i in self.frm:
			if i == '':
				#print(self.frm[a+1])
				return str(self.frm[a+1])
				break
			else:
				a = a + 1
	def metodo_post(self):
		print(self.ordenes())
	def es_texto(self):
		ext = self.extension(self.webfile)
		sel_contenido = {
						'htm': True,
						'html': True,
						'css': True,
						'ico': False,
						'jpg': False,
						'jpeg': False,
						'pdf': False,
						'js': True,
						'avi': False,
						'mp3': False,
						'zip': False,
						'ogg': False,
						'ttf': False,
						'mp4': False,
						'mkv': False,
						'png': False,
						'rar': False}
		return sel_contenido.get(ext)
	def tipos_mime(self):
		ext = self.extension(self.direccion)
		sel_tipo = {
					'htm': 'text/html',
					'html': 'text/html',
					'css': 'text/css',
					'ico': 'image/x-icon',
					'jpg': 'image/jpeg',
					'jpeg': 'image/jpeg',
					'pdf': 'application/pdf',
					'js': 'application/javascript',
					'avi': 'video/avi',
					'mp3': 'audio/mpeg3',
					'zip': 'application/zip',
					'ogg': 'application/ogg',
					'ttf': 'application/x-font-ttf',
					'mp4': 'video/mp4',
					'mkv': 'video/x-matroska',
					'png': 'image/png',
					'rar': 'application/x-rar-compressed'}
		return sel_tipo.get(ext)
	def extension(self, nombre):
		try:
			ext = nombre.split('.')
			self.tiene_extension = True
			return ext[1]
		except:
			self.tiene_extension = False
			return 'html'
	def web_head(self):
		return 'HTTP/1.1 200 OK\r\nContent-Type: %s\r\n\r\n'%(self.tipos_mime())


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

__author__ = "stdrickforce"  # Tengyuan Fan
# Email: <stdrickforce@gmail.com> <tfan@xingin.com>

# Definition for binary tree with next pointer.
# class TreeLinkNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
#         self.next = None

class Solution(object):

    def connect(self, root):
        """
        :type root: TreeLinkNode
        :rtype: nothing
        """

if __name__ == '__main__':
    Solution().connect()


# -*- coding: utf-8 -*-
"""
Created on Tue Jun 11 14:09:58 2019

@author: Neel Tiruviluamala

Description: More efficient way to merge datasets. Note: This code was written
by Dr. Tiruviluamala of the USC Math department.
"""
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import time

df1 = pd.read_csv('Data.csv', encoding = "ISO-8859-1", low_memory=False)
df2 = pd.read_csv('Data_stats.csv', encoding = "ISO-8859-1", low_memory=False)

#Create a base date so that we can recast dates in df1 and df2 as integers
#that represent the number of days since the base date
base_date = pd.to_datetime('1-1-2000')

#Create the elapsed days (from the base date) field in df1 and df2
df1.Date = pd.to_datetime(df1.Date, format = '%d/%m/%Y')
df1['el_date'] = (df1.Date - base_date).dt.days
df2['el_date'] = (pd.to_datetime(df2.Changed_Date, format = '%m/%d/%Y') - base_date).dt.days

#Create a list of winner/loser pairs apparent in both df1 and df2
df1['Winner_Loser'] = df1.apply(lambda x: str(x.Winner)+str(x.Loser), axis = 1)
df2['Winner_Loser'] = df2.apply(lambda x: str(x.wchangedname) + str(x.lchangedname), axis = 1)

A = set(df1.Winner_Loser.unique())
B = set(df2.Winner_Loser.unique())
winner_loser_pairs = A.union(B)

winner_loser_pairs = list(winner_loser_pairs)

#Create a dictionary mapping between winner_loser_pairs and multiples of 100,000
#This is done because there are ~7000 integers in the 'el_date' fields and we want
#to place the winner_loser_pairs at different orders of magnitude

stp = 100000
dict_vals = np.arange(0, stp*len(winner_loser_pairs),stp)
wl_dict = dict(zip(winner_loser_pairs, dict_vals))

#Create the corresponding fields in df1 and df2 that contain the integer values associated
#with each winner/loser pair
df1['wl_number'] = df1.apply(lambda x: wl_dict[x.Winner_Loser],axis = 1)
df2['wl_number'] = df2.apply(lambda x: wl_dict[x.Winner_Loser],axis = 1)

#Create a merge number in df1 and df2 that adds the wl_number to the el_date number
#Note that the only way a merge number in df1 will be "close" to a merge number in df2 is if
#they correspond to the same row (and should thus be merged together)
df1['merge_number'] = df1.wl_number + df1.el_date
df2['merge_number'] = df2.wl_number + df2.el_date

df1 = df1.sort_values('merge_number')
df2 = df2.sort_values('merge_number')

#pd.merge_asof will merge two data frames based on "close" values.  We have done
#all the work to create this close value (merge_number) and so we proceed naturally

df1.to_csv('df1.csv')
df2.to_csv('df2.csv')
# df_merged = pd.merge_asof(df1, df2, on  = "merge_number", tolerance = 10)

# df_merged.to_csv('merger.csv')

left = pd.read_csv('df1.csv', encoding = "ISO-8859-1", low_memory=False)

right = pd.read_csv('df2.csv', encoding = "ISO-8859-1", low_memory=False)

df_merged = pd.merge_asof(left, right, on  = "merge_number", tolerance = 25)

df3 = df_merged.dropna(subset = ['wchangedname'])

df3 = df3.drop(columns = ['Unnamed: 0_x', 'el_date_x', 'Unnamed: 0_y', 'Source.Name', 'surface',
                    'Unnamed: 13', 'Unnamed: 14', 'wlastname', 'wchangedname', 'winner_name',
                    'llastname', 'lmiddlename', 'lfirstname', 'lchangedname', 'loser_name',
                    'best_of', 'Winner_Loser_y'])

df3.to_csv('Final Merged.csv')


from operator import attrgetter
import pyangbind.lib.xpathhelper as xpathhelper
from pyangbind.lib.yangtypes import RestrictedPrecisionDecimalType, RestrictedClassType, TypedListType
from pyangbind.lib.yangtypes import YANGBool, YANGListType, YANGDynClass, ReferenceType
from pyangbind.lib.base import PybindBase
from decimal import Decimal
from bitarray import bitarray
import __builtin__
class bgp(PybindBase):
  """
  This class was auto-generated by the PythonClass plugin for PYANG
  from YANG module brocade-system-capabilities - based on the path /capabilities/bgp. Each member element of
  the container is represented as a class variable - with a specific
  YANG type.
  """
  __slots__ = ('_pybind_generated_by', '_path_helper', '_yang_name', '_rest_name', '_extmethods', '__next_hop_mpls','__redistribute_isis',)

  _yang_name = 'bgp'
  _rest_name = 'bgp'

  _pybind_generated_by = 'container'

  def __init__(self, *args, **kwargs):

    path_helper_ = kwargs.pop("path_helper", None)
    if path_helper_ is False:
      self._path_helper = False
    elif path_helper_ is not None and isinstance(path_helper_, xpathhelper.YANGPathHelper):
      self._path_helper = path_helper_
    elif hasattr(self, "_parent"):
      path_helper_ = getattr(self._parent, "_path_helper", False)
      self._path_helper = path_helper_
    else:
      self._path_helper = False

    extmethods = kwargs.pop("extmethods", None)
    if extmethods is False:
      self._extmethods = False
    elif extmethods is not None and isinstance(extmethods, dict):
      self._extmethods = extmethods
    elif hasattr(self, "_parent"):
      extmethods = getattr(self._parent, "_extmethods", None)
      self._extmethods = extmethods
    else:
      self._extmethods = False
    self.__redistribute_isis = YANGDynClass(base=YANGBool, is_leaf=True, yang_name="redistribute-isis", rest_name="redistribute-isis", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='urn:brocade.com:mgmt:brocade-system-capabilities', defining_module='brocade-system-capabilities', yang_type='boolean', is_config=False)
    self.__next_hop_mpls = YANGDynClass(base=YANGBool, is_leaf=True, yang_name="next-hop-mpls", rest_name="next-hop-mpls", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='urn:brocade.com:mgmt:brocade-system-capabilities', defining_module='brocade-system-capabilities', yang_type='boolean', is_config=False)

    load = kwargs.pop("load", None)
    if args:
      if len(args) > 1:
        raise TypeError("cannot create a YANG container with >1 argument")
      all_attr = True
      for e in self._pyangbind_elements:
        if not hasattr(args[0], e):
          all_attr = False
          break
      if not all_attr:
        raise ValueError("Supplied object did not have the correct attributes")
      for e in self._pyangbind_elements:
        nobj = getattr(args[0], e)
        if nobj._changed() is False:
          continue
        setmethod = getattr(self, "_set_%s" % e)
        if load is None:
          setmethod(getattr(args[0], e))
        else:
          setmethod(getattr(args[0], e), load=load)

  def _path(self):
    if hasattr(self, "_parent"):
      return self._parent._path()+[self._yang_name]
    else:
      return [u'capabilities', u'bgp']

  def _rest_path(self):
    if hasattr(self, "_parent"):
      if self._rest_name:
        return self._parent._rest_path()+[self._rest_name]
      else:
        return self._parent._rest_path()
    else:
      return [u'capabilities', u'bgp']

  def _get_next_hop_mpls(self):
    """
    Getter method for next_hop_mpls, mapped from YANG variable /capabilities/bgp/next_hop_mpls (boolean)
    """
    return self.__next_hop_mpls

  def _set_next_hop_mpls(self, v, load=False):
    """
    Setter method for next_hop_mpls, mapped from YANG variable /capabilities/bgp/next_hop_mpls (boolean)
    If this variable is read-only (config: false) in the
    source YANG file, then _set_next_hop_mpls is considered as a private
    method. Backends looking to populate this variable should
    do so via calling thisObj._set_next_hop_mpls() directly.
    """
    if hasattr(v, "_utype"):
      v = v._utype(v)
    try:
      t = YANGDynClass(v,base=YANGBool, is_leaf=True, yang_name="next-hop-mpls", rest_name="next-hop-mpls", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='urn:brocade.com:mgmt:brocade-system-capabilities', defining_module='brocade-system-capabilities', yang_type='boolean', is_config=False)
    except (TypeError, ValueError):
      raise ValueError({
          'error-string': """next_hop_mpls must be of a type compatible with boolean""",
          'defined-type': "boolean",
          'generated-type': """YANGDynClass(base=YANGBool, is_leaf=True, yang_name="next-hop-mpls", rest_name="next-hop-mpls", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='urn:brocade.com:mgmt:brocade-system-capabilities', defining_module='brocade-system-capabilities', yang_type='boolean', is_config=False)""",
        })

    self.__next_hop_mpls = t
    if hasattr(self, '_set'):
      self._set()

  def _unset_next_hop_mpls(self):
    self.__next_hop_mpls = YANGDynClass(base=YANGBool, is_leaf=True, yang_name="next-hop-mpls", rest_name="next-hop-mpls", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='urn:brocade.com:mgmt:brocade-system-capabilities', defining_module='brocade-system-capabilities', yang_type='boolean', is_config=False)

  def _get_redistribute_isis(self):
    """
    Getter method for redistribute_isis, mapped from YANG variable /capabilities/bgp/redistribute_isis (boolean)
    """
    return self.__redistribute_isis

  def _set_redistribute_isis(self, v, load=False):
    """
    Setter method for redistribute_isis, mapped from YANG variable /capabilities/bgp/redistribute_isis (boolean)
    If this variable is read-only (config: false) in the
    source YANG file, then _set_redistribute_isis is considered as a private
    method. Backends looking to populate this variable should
    do so via calling thisObj._set_redistribute_isis() directly.
    """
    if hasattr(v, "_utype"):
      v = v._utype(v)
    try:
      t = YANGDynClass(v,base=YANGBool, is_leaf=True, yang_name="redistribute-isis", rest_name="redistribute-isis", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='urn:brocade.com:mgmt:brocade-system-capabilities', defining_module='brocade-system-capabilities', yang_type='boolean', is_config=False)
    except (TypeError, ValueError):
      raise ValueError({
          'error-string': """redistribute_isis must be of a type compatible with boolean""",
          'defined-type': "boolean",
          'generated-type': """YANGDynClass(base=YANGBool, is_leaf=True, yang_name="redistribute-isis", rest_name="redistribute-isis", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='urn:brocade.com:mgmt:brocade-system-capabilities', defining_module='brocade-system-capabilities', yang_type='boolean', is_config=False)""",
        })

    self.__redistribute_isis = t
    if hasattr(self, '_set'):
      self._set()

  def _unset_redistribute_isis(self):
    self.__redistribute_isis = YANGDynClass(base=YANGBool, is_leaf=True, yang_name="redistribute-isis", rest_name="redistribute-isis", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='urn:brocade.com:mgmt:brocade-system-capabilities', defining_module='brocade-system-capabilities', yang_type='boolean', is_config=False)

  next_hop_mpls = __builtin__.property(_get_next_hop_mpls)
  redistribute_isis = __builtin__.property(_get_redistribute_isis)

  _pyangbind_elements = {'next_hop_mpls': next_hop_mpls, 'redistribute_isis': redistribute_isis, }


import time

from tadek.core import utils
from tadek.engine.testresult import TestCaseResult
from tadek.engine.channels import register, TestResultChannel
from tadek.engine.testexec import *

__all__ = ["SummaryChannel", "COUNTER_N_TESTS", "COUNTER_TESTS_RUN",
           "COUNTER_CORE_DUMPS", "COUNTER_RUN_TIME"]

# Counters names
COUNTER_N_TESTS = "ntests"
COUNTER_TESTS_RUN = "testsRun"
COUNTER_CORE_DUMPS = "coreDumps"
COUNTER_RUN_TIME = "runTime"

# A list of status counters
STATUS_COUNTERS = (
    STATUS_NO_RUN,
    STATUS_NOT_COMPLETED,
    STATUS_PASSED,
    STATUS_FAILED,
    STATUS_ERROR
)

# Time stamp counters:
_START_STAMP = "startStamp"
_STOP_STAMP = "stopStamp"

def _countCaseResults(result):
    '''
    Counts all test case results in the given test result tree.
    '''
    if isinstance(result, TestCaseResult):
        return 1
    count = 0
    for child in result.children:
        count += _countCaseResults(child)
    return count

class SummaryChannel(TestResultChannel):
    '''
    Channel used to gain summary of tests.
    '''
    def __init__(self, name, enabled=True, verbose=False, **params):
        TestResultChannel.__init__(self, name, enabled, verbose, **params)
        self._counters = {}

    def start(self, result):
        '''
        Initializes all the channel counters.
        '''
        TestResultChannel.start(self, result)
        stamp = time.time()
        self._counters = {
            _START_STAMP: stamp,
            _STOP_STAMP: stamp,
            COUNTER_N_TESTS: _countCaseResults(result),
            COUNTER_TESTS_RUN: 0,
            COUNTER_CORE_DUMPS: 0
        }
        for status in STATUS_COUNTERS:
            self._counters[status] = 0

    def startTest(self, result, device):
        '''
        Processes a test start execution for the summary channel.
        '''
        TestResultChannel.startTest(self, result, device)
        if isinstance(result, TestCaseResult):
            self._counters[STATUS_NOT_COMPLETED] += 1
            self._counters[COUNTER_TESTS_RUN] += 1

    def stopTest(self, result, device):
        '''
        Processes a test stop execution for the summary channel.
        '''
        TestResultChannel.stopTest(self, result, device)
        if isinstance(result, TestCaseResult):
            self._counters[STATUS_NOT_COMPLETED] -= 1
            self._counters[device.status] += 1
            self._counters[_STOP_STAMP] = time.time()
        if device.cores:
            self._counters[COUNTER_CORE_DUMPS] += len(device.cores)

    def getSummary(self):
        '''
        Gets a summary of test results.
        '''
        runTime = self._counters[_STOP_STAMP] - self._counters[_START_STAMP]
        summary = {
            COUNTER_RUN_TIME: utils.runTimeToString(runTime),
            COUNTER_N_TESTS: self._counters[COUNTER_N_TESTS],
            COUNTER_TESTS_RUN: self._counters[COUNTER_TESTS_RUN],
            COUNTER_CORE_DUMPS: self._counters[COUNTER_CORE_DUMPS]
        }
        # Copy all status counters except STATUS_NO_RUN
        for status in STATUS_COUNTERS[1:]:
            summary[status] = self._counters[status]
        return summary

register(SummaryChannel)


import ast

import os, glob

_bBeVerbose = False

def _InsertLine(sFilename: str, index: int, sContent: str):
    """Insert string content at line index into source file f
    Args:
        sFilename (str): File to be modified
        index (int): Line number to be inserted at
        sContent (str): Line to be inserted
    """
    with open(sFilename, "r") as f:
        lsContents = f.readlines()
    # EndWith

    lsContents.insert(index, sContent)

    with open(sFilename, "w") as f:
        lsContents = "".join(lsContents)
        f.write(lsContents)
    # EndWith

# EndDef

def _CountLeadingBlanks(s: str):
    """Calculate number of leading blanks
    Args:
        s (str): Input string
    Returns:
        int: Number of leading blanks
    """
    return (len(s) - len(s.lstrip())) if s != "\n" else 0

# EndDef

def _PermutateBlockEnd(_sBlockId):
    sBlockID_lower = f"{_sBlockId[0:1]}".lower() + _sBlockId[1:]
    sBlockID_upper = f"{_sBlockId[0:1]}".upper() + _sBlockId[1:]

    sComment = f"# End{sBlockID_upper}"

    lsAlternatives = [
        f"# end{sBlockID_lower}",
        f"# end{sBlockID_upper}",
        f"# end {sBlockID_lower}",
        f"# end {sBlockID_upper}",
        f"# End{sBlockID_lower}",
        f"# End{sBlockID_upper}",
        f"# End {sBlockID_lower}",
        f"# End {sBlockID_upper}",
    ]

    return {"_sComment": sComment, "_lsAlternatives": lsAlternatives}

# EndDef

class CFormatCodeBlocksAnalyzer(ast.NodeVisitor):
    """Code analyzer class derived from ast.Nodevisitor checking for
    Catharsys Coding Guidelines infractions
    """

    def __init__(self, _sFilename):
        with open(_sFilename, "r") as source:
            self.lsCode = source.readlines()
        # EndWith

        self.sFilename = _sFilename
        # break switch to stop traversing the AST, since adding a line requires reloading
        self.bContinue = True

    # EndDef

    """ Per default the visitor functions for the nodes are ``'visit_'`` +
        class name of the node.  So a `TryFinally` node visit function would
        be `visit_TryFinally`.  This behavior can be changed by overriding
        the `visit` method.  If no visitor function exists for a node
        (return value `None`) the `generic_visit` visitor is used instead.

        see https://docs.python.org/3/library/ast.html#node-classes
    """

    def visit_If(self, _xNode):
        self._VisitGeneric(_xNode, **_PermutateBlockEnd("if"))
        self.generic_visit(_xNode)

    # EndDef

    def visit_For(self, _xNode):
        self._VisitGeneric(_xNode, **_PermutateBlockEnd("for"))
        self.generic_visit(_xNode)

    # EndDef

    def visit_ClassDef(self, _xNode):
        self._VisitGeneric(_xNode, **_PermutateBlockEnd("class"))
        self.generic_visit(_xNode)

    # EndDef

    def visit_FunctionDef(self, _xNode):
        self._VisitGeneric(_xNode, **_PermutateBlockEnd("def"))
        self.generic_visit(_xNode)

    # EndDef

    def visit_While(self, _xNode):
        self._VisitGeneric(_xNode, **_PermutateBlockEnd("while"))
        self.generic_visit(_xNode)

    # EndDef

    def visit_Try(self, _xNode):
        self._VisitGeneric(_xNode, **_PermutateBlockEnd("try"))
        self.generic_visit(_xNode)

    # EndDef

    def visit_With(self, _xNode):
        self._VisitGeneric(_xNode, **_PermutateBlockEnd("with"))
        self.generic_visit(_xNode)

    # EndDef

    def _VisitGeneric(self, _xNode, _sComment: str, _lsAlternatives=None):
        """Generic visit functionality
        Args:
            node (ast.node): Node being visited
            commentstring (str): String that is expected to show up at the end of
            the code belonging to the node.
            altstrings (List of strings): Alternatives to commentstring that are also acceptable.
            Defaults to None.
        """
        if _lsAlternatives is None:
            lsTargets = [_sComment]
        else:
            _lsAlternatives.append(_sComment)
            lsTargets = _lsAlternatives
        # EndIf

        if self.bContinue:
            # skip over potential # Endwhatever comments, till the correct indentation level is reached or EOF

            iCurrentInvestionLineNo = _xNode.end_lineno
            iEndLineNo4Insertion = iCurrentInvestionLineNo
            iMaxLineCnt = len(self.lsCode)
            bExpectedStartFound = False
            while iCurrentInvestionLineNo < iMaxLineCnt:
                sCurrentLine = self.lsCode[iCurrentInvestionLineNo]
                iLeadingBlanks = _CountLeadingBlanks(sCurrentLine)
                if len(sCurrentLine.strip()) > 0 and iLeadingBlanks <= _xNode.col_offset:
                    if len(sCurrentLine) > _xNode.col_offset:
                        bExpectedStartFound = any(
                            [sCurrentLine[_xNode.col_offset :].startswith(sComment) for sComment in lsTargets]
                        )
                    # EndIf
                    break
                # EndIf

                iCurrentInvestionLineNo += 1
                if iLeadingBlanks > _xNode.col_offset:
                    iEndLineNo4Insertion = iCurrentInvestionLineNo
                # EndIf
            # EndWhile

            if not bExpectedStartFound:
                global _bBeVerbose
                if _bBeVerbose:
                    # Endwhatever not found at the correct indent level
                    if hasattr(_xNode, "name"):
                        print(f"{_sComment} in line {_xNode.end_lineno} missing for {_xNode.name}")
                    else:
                        print(f"{_sComment} in line {_xNode.end_lineno} missing")
                    # endif
                # EndIf
                sInsertion = " " * _xNode.col_offset + f"{_sComment}\n"
                _InsertLine(self.sFilename, iEndLineNo4Insertion, sInsertion)
                self.bContinue = False
            # EndIf
        # EndIf

    # EndDef

# EndClass

def _FormatCodeBlocks(_sFilename: str):
    """Main formatting loops
    Args:
        filename (str): Code file to be formatted
    """
    global _bBeVerbose
    if _bBeVerbose:
        print(f"opening {_sFilename} to analyse FormatCodeBlocks")
    # EndIf

    # Read file contents
    with open(_sFilename, "r") as source:
        xTree = ast.parse(source.read())
    # EndWith

    # set up Python AST analyzer, set continue flag to False.
    # This flag ensures that only one one code change is performed,
    # since insertion changes the linenumbers.
    # If Analyzer.visit terminates without setting the continue flag,
    # no more changes need to be made to the code
    xAnalyzer = CFormatCodeBlocksAnalyzer(_sFilename)
    xAnalyzer.bContinue = False

    # Fix issues one by one till no findings are left
    while not xAnalyzer.bContinue:
        # Reread the file contents, set up AST and visit
        with open(_sFilename, "r") as source:
            xTree = ast.parse(source.read())
        # EndWith
        xAnalyzer = CFormatCodeBlocksAnalyzer(_sFilename)
        xAnalyzer.visit(xTree)
    # EndWhile
    return

# EndDef

####################################################################
def RunFormat(
    *,
    _bCodeBlocks=False,
    _bVerbose=False,
    _lsFilename=None,
    _lsFolder=None,
    _bFolderRecursive=False,
):
    if not _bCodeBlocks:
        raise RuntimeError("RunFormat expects at least one action [--code-blocks, ]")
    # EndIf

    lsResultingFiles = []

    global _bBeVerbose
    _bBeVerbose = _bVerbose

    if _lsFilename is not None:
        if not isinstance(_lsFilename, list):
            raise ValueError("RunFormat expected a list of filenames as input")
        # EndIf
        for sFilename in _lsFilename:
            if os.path.isfile(sFilename):
                lsResultingFiles.append(os.path.realpath(sFilename))
            # EndIf
        # EndFor
    # EndIf

    if _lsFolder is not None:
        if not isinstance(_lsFolder, list):
            raise ValueError("RunFormat expected a list of folder as input")
        # EndIf

        for sFolder in _lsFolder:
            if _bFolderRecursive:
                lsDirFiles = []
                for sRoot, lsDirectories, lsFiles in os.walk(sFolder):
                    for sFile in lsFiles:
                        if sFile.endswith(".py"):
                            lsDirFiles.append(os.path.realpath(os.path.join(sRoot, sFile)))
                        # EndIf
                    # EndFor
                # EndFor

            else:
                lsDirFiles = [os.path.realpath(sFile) for sFile in glob.glob(sFolder + "/*.py")]
            # EndIf

            for sFile in lsDirFiles:
                lsResultingFiles.append(sFile)
            # EndFor
        # EndFor
    # EndIf

    if _bVerbose:
        print("filenames:")
        for sFile in lsResultingFiles:
            print(sFile)
        # EndFor
    # EndIf

    for sFile in lsResultingFiles:
        if _bCodeBlocks:
            _FormatCodeBlocks(sFile)
        # EndIf
    # EndFor

# enddef

# ------------------------------------------------------------------------------------------------------------
if __name__ == "__main__":
    import sys

    # filepath = "D:/TOOLS/common/catharsys/image-render-setup-develop/src/catharsys/setup/cmd/devl_code_format.py"
    if len(sys.argv) >= 2:
        filepath = sys.argv[1]
        if os.path.isfile(filepath):
            _FormatCodeBlocks(filepath)
        # EndIf
    # EndIf
# EndIf


import requests
from bs4 import BeautifulSoup
import re

def loastone_login():
    print('http://na.finalfantasyxiv.com/lodestone/account/login/')

#Get a page from the Loadstone
# returns a BeautifulSoup object
def get_loadstone_page(url,session_id):
    #Time format used for cookies
    #import time
    #time.strftime('%a, %d-%b-%Y %H:%M:%S %Z')
    #ldst_is_support_browser=1, ldst_touchstone=1,  ldst_bypass_browser=1", expires=session_expiration
    cookies = dict(ldst_sess=session_id,domain='finalfantasyxiv.com', path='/')
    raw_page = requests.get(url, cookies=cookies)

    if(raw_page.status_code != 200):
        raise Exception("Unable to download web page!")

    return BeautifulSoup(raw_page.text,'html.parser')

#Each item has a separate detail page that must be loaded to determine if it's HQ or not
def is_item_hq(raw_item,session_id):
        tooltip_url = 'http://na.finalfantasyxiv.com/' + item.find('div', attrs={"class": 'item_txt'})['data-lazy_load_url']
        tooltip_page = get_loadstone_page(tooltip_url,session_id)
        return bool(tooltip_page.find("img", src = re.compile('http://img\.finalfantasyxiv\.com/lds/pc/global/images/common/ic/hq.png.*')))

#Debug function to write some data to 'test.html'
def write_data(data):
    out_file=open('test.html','w')
    #for i in data:
        #out_file.write(str(i))
    out_file.write(str(data))
    out_file.close()

#Debug function to write a pretty parsed version of a Loadstone page
def write_loadstone_page(url,session_id):
    soup_page = get_loadstone_page(url,session_id)
    write_data(soup_page.prettify().encode('utf8'))

#Use this to convert the provided items into something useful
def list_items_table(items):
    item_row_format='
	{name}	{quantity}	{location}	{sub_location}
\n'
    item_buffer = '
\n'
    for i in items:
        item_buffer += item_row_format.format(**i)
    item_buffer += '
\n'
    return item_buffer

#Get all items in the Free company chest (does not get number of crystals or gil)
#Does not handle HQ Items yet
def get_fc_items(fc_id,session_id):
    url = 'http://na.finalfantasyxiv.com/lodestone/freecompany/'+str(fc_id)+'/chest/'
    soup_page = get_loadstone_page(url,session_id)
    #Get all items
    raw_items=soup_page.find_all("tr", attrs={"data-default_sort": True})
    #Parse the items
    items=[]
    for item in raw_items:
        tmp = {}
        tmp['name']         = item.find("h2", attrs={"class": 'db-tooltip__item__name'}).text.strip()
        tmp['quantity']     = int(item['data-stack'])
        tmp['image']        = item.find("img")['src']
        tmp['location']     = 'Company Chest'
        tmp['sub_location'] = item.find_parent('tbody')['id']
        items.append(tmp)
    return items

#Get all items in a retainers inventory (does not get number of crystals or gil)
#Does not handle HQ Items yet
def get_retainer_items(char_id,retainer_id,session_id):
    url = 'http://na.finalfantasyxiv.com/lodestone/character/'+str(char_id)+'/retainer/'+retainer_id+'/baggage/'
    soup_page = get_loadstone_page(url,session_id)
    #Get retainers name
    retainer_name = soup_page.find("div", attrs={"class": 'retainer--name'}).p.text.strip()
    #Get all items
    raw_items=soup_page.find_all("tr", attrs={"data-default_sort": True})
    #Parse the items
    items=[]
    for item in raw_items:
        #if(is_item_hq(item,session_id)):
            #print("HQ")
        tmp = {}
        tmp['name']         = item.find("a", attrs={"class": 'highlight'}).text.strip()
        tmp['quantity']     = int(item['data-stack'])
        tmp['image']        = item.find("img")['src']
        tmp['location']     = 'Retainer:  ' + retainer_name
        tmp['sub_location'] = 'Inventory'
        items.append(tmp)
    return items

#Get all items a retainer is selling (does not get number of crystals or gil)
#HQ Item handling is suspect
#Note:  This may return already sold items:
#       sale_inventory is supposed to filter those out, but I din't think it's working correctly
def get_retainer_selling(char_id,retainer_id,session_id):
    url = 'http://na.finalfantasyxiv.com/lodestone/character/'+str(char_id)+'/retainer/'+retainer_id+'/market/'
    soup_page = get_loadstone_page(url,session_id)
    #Get retainers name
    retainer_name = soup_page.find("div", attrs={"class": 'retainer--name'}).p.text.strip()
    #Get all items
    sale_inventory=soup_page.find("div", attrs={"class": 'active'}).find('tbody')
    #If no items, just return an empty set
    if not sale_inventory:
        return []
    raw_items=sale_inventory.find_all("tr")
    #Parse the items
    items=[]
    for item in raw_items:
        tmp = {}
        tmp['name']         = item.find("a", attrs={"class": 'highlight'}).text.strip()
        tmp['quantity']     = int(item.find("td", attrs={"class": 'even'}).text.strip())
        tmp['image']        = item.find("img")['src']
        tmp['location']     = 'Retainer:  ' + retainer_name
        tmp['sub_location'] = 'Selling'
        tmp['is_hq']        = bool(item.find("img", src = re.compile('http://img\.finalfantasyxiv\.com/lds/pc/global/images/common/ic/hq.png.*')))
        items.append(tmp)
    return items


from kubecepodvs.sumo.mapmessage.trafficmap import TrafficMap

class SumotrInputHandle:

    def __init__(self, filename, map_: TrafficMap):
        self._map = map_
        # 这里去掉了traffic log相关的属性

        with open(str(filename), 'r') as file:

            time = 0.0
            time_step_flag = True

            # edge
            edge_id = ''

            # lane
            lane_id = ''

            # vehicle id
            vehicle_id = ''
            # pos
            pos = 0.0
            # speed
            speed = 0.0

            while True:
                sline = str(file.readline(1024))
                if not sline:
                    break

                if sline.find('timestep') != -1 and time_step_flag:
                    vec = sline.split('"')

                    time = float(vec[1])
                    time_step_flag = False

                elif sline.find('timestep') != -1:
                    time_step_flag = True

                elif sline.find('edge id') != -1:
                    vec = sline.split('"')

                    edge_id = vec[1]

                elif sline.find('lane id') != -1:
                    vec = sline.split('"')

                    lane_id = vec[1]

                elif sline.find('vehicle id') != -1:
                    vec = sline.split('"')

                    vehicle_id = vec[1]
                    pos = float(vec[3])
                    speed = float(vec[5])

                    # 这里去掉了vehicle status和traffic log相关的代码


import pandas as pd
import datetime as dt
from kucoincli.client import Client

def test_lending_liquidity(quote='USDT'):
    """Obtain max point-in-time liquidity for lending markets in USDT terms"""
    client = Client()
    l = client.symbols(marginable=True).baseCurrency
    liq = {}

    for curr in l:
        try:
            df = client.lending_rate(curr)
            stats = client.get_stats(curr + '-' + quote)
            max_borrow = (((stats.buy + stats.sell) / 2) * df['size'].sum())
            liq[curr] = max_borrow
        except:
            pass

    return pd.Series(liq).sort_values(ascending=False)

def test_trading_liquidity(lookback=90, interval='1day'):
    """Calculate mean turnover for marginable currencies in `interval` granularity over `lookback` days"""
    client = Client()
    l = client.symbols(marginable=True).index
    liq = {}

    start = dt.datetime.now() - dt.timedelta(days=lookback)

    for curr in l:
        mean_vol = client.ohlcv(
            tickers=curr,
            interval=interval,
            start=start
        ).turnover.mean()
        liq[curr] = mean_vol

    return pd.Series(liq).sort_values(ascending=False)

def get_csv_data(path):
    """Reads in CSV file exported from SQL db"""
    df = pd.read_csv(path, index_col="time")
    df.index = pd.to_datetime(df.index)
    df = df.astype(float)
    return df.sort_index(ascending=True)


# SPDX-License-Identifier: LGPL-3.0-only

"""Package for the doorstop.core tests."""

import logging
import os
from typing import List
from unittest.mock import MagicMock, Mock, patch

from doorstop.core.base import BaseFileObject
from doorstop.core.document import Document
from doorstop.core.item import Item
from doorstop.core.validators.item_validator import ItemValidator
from doorstop.core.vcs.mockvcs import WorkingCopy

ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", ".."))

TESTS_ROOT = os.path.dirname(__file__)
FILES = os.path.join(os.path.dirname(__file__), "files")
FILES_MD = os.path.join(os.path.dirname(__file__), "files_md")
SYS = os.path.join(FILES, "parent")
TST = os.path.join(FILES, "child")
EMPTY = os.path.join(FILES, "empty")  # an empty directory
EXTERNAL = os.path.join(FILES, "external")  # external files to reference
NEW = os.path.join(FILES, "new")  # new document with no items

ENV = "TEST_INTEGRATION"  # environment variable to enable integration tests
REASON = "'{0}' variable not set".format(ENV)

if not os.path.exists(EMPTY):
    os.makedirs(EMPTY)

class DocumentNoSkip(Document):
    """Document class that is never skipped."""

    SKIP = "__disabled__"  # never skip test Documents

class MockFileObject(BaseFileObject):  # pylint: disable=W0223,R0902
    """Mock FileObject class with stubbed file IO."""

    def __init__(self, *args, **kwargs):
        self._file = kwargs.pop("_file", "")  # mock file system contents
        with patch("os.path.isfile", Mock(return_value=True)):
            super().__init__(*args, **kwargs)  # type: ignore
        self._read = Mock(side_effect=self._mock_read)
        self._write = Mock(side_effect=self._mock_write)

    _create = Mock()

    def _mock_read(self, path):
        """Mock read method."""
        logging.debug("mock read path: {}".format(path))
        text = self._file
        logging.debug("mock read text: {}".format(repr(text)))
        return text

    def _mock_write(self, text, path):
        """Mock write method."""
        logging.debug("mock write text: {}".format(repr(text)))
        logging.debug("mock write path: {}".format(path))
        self._file = text

    def __bool__(self):
        return True

class MockItem(MockFileObject, Item):  # pylint: disable=W0223,R0902
    """Mock Item class with stubbed file IO."""

class MockItemValidator(ItemValidator):  # pylint: disable=W0223,R0902
    """Mock Item class with stubbed file IO."""

    def _no_get_issues_document(self, item, document, skip):  # pylint: disable=W0613
        return
        yield  # pylint: disable=W0101

    def disable_get_issues_document(self):
        self._get_issues_document = self._no_get_issues_document

class MockDocument(MockFileObject, Document):  # pylint: disable=W0223,R0902
    """Mock Document class with stubbed file IO."""

class MockSimpleDocument:
    """Mock Document class with basic default members."""

    def __init__(self):
        self.parent = None
        self.prefix = "RQ"
        self.itemformat = "yaml"
        self._items: List[Item] = []
        self.extended_reviewed: List[str] = []

    def __iter__(self):
        yield from self._items

    def set_items(self, items):
        self._items = items

class MockDocumentSkip(MockDocument):  # pylint: disable=W0223,R0902
    """Mock Document class that is always skipped in tree placement."""

    skip = True

class MockDocumentNoSkip(MockDocumentSkip):  # pylint: disable=W0223,R0902
    """Mock Document class that is never skipped in tree placement."""

    SKIP = "__disabled__"  # never skip mock Documents

class MockItemAndVCS(MockItem):  # pylint: disable=W0223,R0902
    """Mock item class with stubbed IO and a mock VCS reference."""

    def __init__(self, *args, **kwargs):
        super().__init__(None, *args, **kwargs)
        self.tree = Mock()
        self.tree.vcs = WorkingCopy(None)

class MockDataMixIn:  # pylint: disable=R0903
    """Data for test cases requiring mock items and documents."""

    # purely mock objects

    mock_document = MagicMock()
    mock_document.prefix = "MOCK"
    mock_document.items = []
    mock_document.assets = None
    mock_document.template = None
    mock_tree = MagicMock()
    mock_tree.documents = [mock_document]

    # mock objects that behave like the real thing

    item = MockItemAndVCS(
        "path/to/req3.yml",
        _file=(
            "links: [sys3]" + "\n"
            "text: 'Heading'" + "\n"
            "level: 1.1.0" + "\n"
            "normative: false"
        ),
    )

    item2 = MockItemAndVCS(
        "path/to/req3.yml",
        _file=("links: [sys3]\ntext: '" + ("Hello, world! " * 10) + "'\nlevel: 1.2"),
    )
    _mock_item = Mock()
    _mock_item.uid = "sys3"
    _mock_item.document.prefix = "sys"
    item2.tree = Mock()
    item2.tree.find_item = Mock(return_value=_mock_item)
    _mock_item2 = Mock()
    _mock_item2.uid = "tst1"
    _mock_item2.document.prefix = "tst"
    # pylint: disable=undefined-variable
    item2.find_child_links = lambda: [MockDataMixIn._mock_item2.uid]  # type: ignore
    item2.find_child_items = lambda: [MockDataMixIn._mock_item2]  # type: ignore

    document = MagicMock(spec=["items"])
    document.items = [
        item,
        item2,
        MockItemAndVCS(
            "path/to/req1.yml", _file="links: []\ntext: 'abc\n123'\nlevel: 1.1"
        ),
        MockItemAndVCS("path/to/req2.yml", _file="links: []\ntext: ''\nlevel: 2"),
        MockItemAndVCS(
            "path/to/req4.yml",
            _file="links: []\nref: 'CHECK_PUBLISHED_CONTENT'\n" "level: 2.1.1",
        ),
        MockItemAndVCS(
            "path/to/req2.yml",
            _file="links: [sys1]\ntext: 'Heading 2'\nlevel: 2.1.0\n" "normative: false",
        ),
    ]
    document.copy_assets = Mock()
    document.assets = None
    document.template = None

    item3 = MockItem(
        None,
        "path/to/req4.yml",
        _file=(
            "links: [sys4]" + "\n"
            "text: 'This shall...'" + "\n"
            "ref: Doorstop.sublime-project" + "\n"
            "level: 1.2" + "\n"
            "normative: true"
        ),
    )
    _mock_item3 = Mock()
    _mock_item3.uid = "sys4"
    _mock_item3.document.prefix = "sys"
    item3.tree = Mock()
    item3.tree.find_item = Mock(return_value=_mock_item3)
    item3.tree.vcs.paths = [
        (
            "Doorstop.sublime-project",
            "Doorstop.sublime-project",
            "Doorstop.sublime-project",
        )
    ]

    item4 = MockItemAndVCS(
        "path/to/req3.yml",
        _file=(
            "links: [sys3]" + "\n"
            "text: 'Heading'" + "\n"
            "long: " + ('"' + "0" * 66 + '"') + "\n"
            "level: 1.1.0" + "\n"
            "normative: false"
        ),
    )

    item5 = MockItemAndVCS(
        "path/to/req3.yml",
        _file=(
            "links: [sys3]" + "\n"
            "text: 'Heading'" + "\n"
            "level: 2.1.2" + "\n"
            "normative: false" + "\n"
            "ref: 'abc123'"
        ),
    )

    item6 = MockItemAndVCS(
        "path/to/req3.yml",
        _file=(
            "links: [sys3]" + "\n"
            "text: 'Heading'" + "\n"
            "level: 2.1.2" + "\n"
            "normative: false" + "\n"
            "references:" + "\n"
            "  - path: abc1" + "\n"
            "    type: file" + "\n"
            "  - path: abc2" + "\n"
            "    type: file" + "\n"
        ),
    )


# ----------------------------------------------------------------------------#
# Imports
# ----------------------------------------------------------------------------#
import random

from flask import Flask, abort, jsonify, request
from flask_cors import CORS

from models import setup_db, Category, Question

# ----------------------------------------------------------------------------#
# App Config.
# ----------------------------------------------------------------------------#
app = Flask(__name__)
setup_db(app)
cors = CORS(app, resources={r"/api/*": {"origins": "*"}})

# ----------------------------------------------------------------------------#
# PAGINATION LOGIC
# ----------------------------------------------------------------------------#
QUES_PER_PAGE = 10

def paginate_questions(request, selection):
    page = request.args.get('page', 1, type=int)
    start = (page - 1) * QUES_PER_PAGE
    end = start + QUES_PER_PAGE
    questions = [question.format() for question in selection]
    current_questions = questions[start:end]
    return current_questions

# ----------------------------------------------------------------------------#
# AFTER REQUEST
# ----------------------------------------------------------------------------#
@app.after_request
def after_request(response):
    response.headers.add('Access-Control-Allow-Headers', 'Content-Type,Authorization,true')
    response.headers.add('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS')
    return response

# ----------------------------------------------------------------------------#
# GET CATEGORIES ENDPOINT
# ----------------------------------------------------------------------------#
@app.route('/categories', methods=['GET'])
def retrieve_categories():
    categories = Category.query.order_by(Category.type).all()
    if len(categories) == 0:
        abort(404)
    else:
        categories_dict = {}
        for category in categories:
            categories_dict[category.id] = category.type

        return jsonify({
            'success': True,
            'categories': categories_dict
        })

# ----------------------------------------------------------------------------#
# GET QUESTIONS ENDPOINT
# ----------------------------------------------------------------------------#
@app.route('/questions')
def get_questions():
    all_questions = Question.query.order_by(Question.id).all()
    total_questions = len(all_questions)
    pagenated_questions = paginate_questions(request, all_questions)
    if (len(pagenated_questions) == 0):
        abort(404)
    try:
        categories = Category.query.all()
        categoriesDict = {}
        for category in categories:
            categoriesDict[category.id] = category.type

        return jsonify({
            'success': True,
            'questions': pagenated_questions,
            'total_questions': total_questions,
            'categories': categoriesDict
        })
    except Exception as e:
        print(e)
        abort(400)

# ----------------------------------------------------------------------------#
# DELETE QUESTIONS ENDPOINT
# ----------------------------------------------------------------------------#
@app.route('/questions/<int:id>', methods=['DELETE'])
def delete_questions(id):
    try:
        question_to_be_deleted = Question.query.filter_by(id=id).one_or_none()
        if question_to_be_deleted is None:
            abort(404)
        else:
            question_to_be_deleted.delete()

            return jsonify({
                'success': True,
                'deleted': str(id)
            })
    except Exception as e:
        print(e)
        abort(400)

# ----------------------------------------------------------------------------#
# POST QUESTIONS ENDPOINT
# ----------------------------------------------------------------------------#
@app.route("/questions", methods=['POST'])
def add_question():
    body = request.get_json()
    if body is None:
        abort(400)
    new_question = body.get('question', None)
    new_answer = body.get('answer', None)
    new_category = body.get('category', None)
    new_difficulty = body.get('difficulty', None)
    if new_question is None or new_answer is None or new_category is None or new_difficulty is None:
        abort(400)
    else:
        try:
            added_question = Question(question=new_question, answer=new_answer, category=new_category,
                                      difficulty=new_difficulty)
            added_question.insert()
            all_questions = Question.query.order_by(Question.id).all()
            current_questions = paginate_questions(request, all_questions)
            return jsonify({
                'success': True,
                'created': added_question.id,
                'questions': current_questions,
                'total_questions': len(all_questions)
            })

        except Exception as e:
            print(e)
            abort(422)

# ----------------------------------------------------------------------------#
# SEARCH QUESTIONS ENDPOINT
# ----------------------------------------------------------------------------#
@app.route("/questions/search", methods=['POST'])
def search_question():
    body = request.get_json()
    search_ques = body.get('searchTerm', None)
    if search_ques:
        searched_question = Question.query.filter(Question.question.ilike(f'%{search_ques}%')).all()
        return jsonify({
            'success': True,
            'questions': [question.format() for question in searched_question],
            'total_questions': len(searched_question),
            'current_category': None
        })
    else:
        abort(404)

# ----------------------------------------------------------------------------#
# GET QUESTIONS BY CATEGORY ENDPOINT
# ----------------------------------------------------------------------------#
@app.route("/categories/<int:id>/questions")
def questions_by_category(id):
    searched_category = Category.query.filter_by(id=id).one_or_none()
    if searched_category:
        questions_in_category = Question.query.filter_by(category=str(id)).all()
        current_questions = paginate_questions(request, questions_in_category)

        return jsonify({
            'success': True,
            'questions': current_questions,
            'total_questions': len(questions_in_category),
            'current_category': searched_category.type
        })
    else:
        abort(404)

# ----------------------------------------------------------------------------#
# POST QUIZ ENDPOINT
# ----------------------------------------------------------------------------#
@app.route('/quizzes', methods=['POST'])
def get_quiz():
    body = request.get_json()
    quiz_category = body.get('quiz_category')
    previous_question = body.get('previous_questions')
    if quiz_category is None:
        abort(422)
    try:
        if (quiz_category['id'] == 0):
            # To handle all categories
            questions_query = Question.query.all()
        else:
            questions_query = Question.query.filter_by(category=quiz_category['id']).all()
        random_ques_index = random.randint(0, len(questions_query) - 1)

        next_question = questions_query[random_ques_index]
        while next_question.id not in previous_question:
            next_question = questions_query[random_ques_index]
            return jsonify({
                'success': True,
                'question': {
                    "id": next_question.id,
                    "question": next_question.question,
                    "answer": next_question.answer,
                    "difficulty": next_question.difficulty,
                    "category": next_question.category
                },
                'previousQuestion': previous_question
            })
    except Exception as e:
        print(e)
        abort(404)

# ----------------------------------------------------------------------------#
# ERROR HANDLERS FOR HTTP CODES
# ----------------------------------------------------------------------------#
@app.errorhandler(404)
def not_found(error):
    return jsonify({
        "success": False,
        "error": 404,
        "message": "Resource not found"
    }), 404

@app.errorhandler(422)
def unprocessable_entity(error):
    return jsonify({
        "success": False,
        "error": 422,
        "message": "Unprocessable entity"
    }), 422

@app.errorhandler(400)
def bad_request(error):
    return jsonify({
        "success": False,
        "error": 400,
        "message": "Bad request"
    }), 400

# ----------------------------------------------------------------------------#
# Launch.
# ----------------------------------------------------------------------------#

# Default port:
if __name__ == '__main__':
    app.run()

def create_app():
    return app


import cv2
import numpy as np
class VideoCamera(object):
    def __init__(self):
        self.video = cv2.VideoCapture(0)
    def __del__(self):
        self.video.release()
    def get_frame(self):
        while True:
            a="Not Found"
            lower_green = np.array([45, 140, 50])
            upper_green = np.array([75, 255, 255])
            success, frame = self.video.read()
            hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
            hsv = cv2.medianBlur(hsv, 5)
            imgThreshHighgreen = cv2.inRange(hsv, lower_green, upper_green)
            circlesgreen = cv2.HoughCircles(imgThreshHighgreen, cv2.HOUGH_GRADIENT, 1, 20, param1=50, param2=30,
                                            minRadius=0, maxRadius=0)
            if circlesgreen is not None:
                a="Green Ball"
            ret, jpeg = cv2.imencode('.jpg',frame)
            return jpeg.tobytes(),a
VideoCamera().get_frame()


from django.urls import path
from rest_framework.routers import DefaultRouter

from src.dates_api.views import DateViewSet, PopularMonthListView

app_name = "dates_api"

router = DefaultRouter()
router.register("dates", DateViewSet, basename="dates")

urlpatterns = [
    path("popular/", PopularMonthListView.as_view(), name="popular_month"),
]
urlpatterns += router.urls


from django.urls import path
from django.conf.urls import include
from django.contrib import admin
from app.accounts.api.v1.views import (
    UserCreatView,
    UserUpdateView,
    GetAuthToken,
    AvatarAPIView,
    ClubAPIView,
)

app_name = 'accounts'

urlpatterns = [
    path('login/', GetAuthToken.as_view(),              name='user-login'),
    path('create/', UserCreatView.as_view(),            name='user-create'),
    path('update/<int:pk>/', UserUpdateView.as_view(),  name='user-update'),
    path('avatar/<int:pk>/', AvatarAPIView.as_view(),   name='user-avatar'),

    path('club/', ClubAPIView.as_view(),                name='club-details')

]


from faker import Faker
from faker.providers import person, job, company, internet, phone_number

class BaseCard:
    def __init__(self, name, family_name, e_mail, priv_phone):
        self.name = name
        self.family_name = family_name
        self.e_mail = e_mail
        self.priv_phone = priv_phone
        self._length = len(self.name) + len(self.family_name)

    def __str__(self):
        return 'Name:' + self.name + '; Family Name:' + self.family_name + '; E-mail:' + self.e_mail + \
            '; Phone:' + self.priv_phone

    def contacts(self):
        print(f'Please contact with: {self.name} {self.family_name} private phone:{self.priv_phone}')

    @property
    def length(self):
        return self._length

    @length.setter
    def length(self, value):
        if value != len(self.name) + len(self.family_name) + 1:
            raise ValueError(f' Value {value} not eq to len of name and family name')
        else:
            self._length = value

class BusinessCard(BaseCard):
    def __init__(self, position, company, business_phone, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.position = position
        self.company = company
        self.business_phone = business_phone

    def contacts(self):
        print(f'Please contact with: {self.name} {self.family_name} corporate phone:{self.business_phone}')

    def __str__(self):
        return super().__str__() + '; Position:' + self.position + ' ;Company:' + self.company + \
            ' ;Buss Phone:' + self.business_phone + ' ;LEN:' + str(self._length)

def create_contacts(type='Base', quantity=1):
    fake = Faker()
    fake.add_provider(person)
    fake.add_provider(job)
    fake.add_provider(internet)
    list_of_cards = []
    if type == 'Base':
        for i in range(quantity):
            card = BaseCard(name=fake.first_name_male(), family_name=fake.last_name_male(),
                            e_mail=fake.company_email(), priv_phone=fake.phone_number())
            list_of_cards.append(card)
    elif type == 'Business':
        fake.add_provider(company)
        for i in range(quantity):
            card = BusinessCard(name=fake.first_name_male(), family_name=fake.last_name_male(),
                                e_mail=fake.company_email(), priv_phone=fake.phone_number(), position=fake.job(),
                                company=fake.company(), business_phone=fake.phone_number())
            list_of_cards.append(card)
    else:
        ValueError('fWrong card type provided - Base or Business')
    return list_of_cards

cards = create_contacts(type='Business', quantity=10)
for card in cards:
    print(card)


#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2022/5/6 20:48
# @Author  : nujaijey
# @File    : 字符串.py
# @Desc    :

# s1 = ""
# s2 = "   "
# print("s1的长度：", len(s1))
# print("s2的长度：", len(s2))

# s3 = '1234567'
# res3 = s3[0:7:3]
# print(res3)

# s4 = '    python    '
# print(s4)
# res = s4.strip()
# print(res)

s5 = '***python***'
print(s5)
res = s5.strip('*')
print(res)

# 给你一个字符串 s，由若干单词组成，单词前后用一些空格字符隔开。返回字符串中 最后一个 单词的长度。
# 单词 是指仅由字母组成、不包含任何空格字符的最大子字符串。
# 提示：
# 1 <= s.length <= 104
# s 仅有英文字母和空格 ' ' 组成
# s 中至少存在一个单词
def lengthOfLastWord(s):
    """
    :type s: str
    :rtype: int
    """
    # length = ''
    # if s.strip() == '':
    #     print('s不包含字母')
    # elif s.split()[-1] == ' ':
    #     strip_str = s.strip()
    #     length = len(strip_str.split()[-1])
    # else:
    #     length = len(s.split()[-1])
    # print(length)

    strip_s = s.strip()
    split_s = strip_s.split()
    length = len(split_s[-1]) if split_s else 0
    print(length)

lengthOfLastWord('   ')
lengthOfLastWord('Hello World')
lengthOfLastWord('   fly me   to   the moon  ')


import logging
import concurrent.futures
import pandas as pd
import random
import time
import requests
import os
import sys

from datetime import datetime
from utils.vars import *
from utils.common import *
from requests.structures import CaseInsensitiveDict

# Output the logs to the stdout
logging.basicConfig(stream=sys.stdout, level=logging.INFO)
logger = logging.getLogger(__file__)

class AzureAuthScaleAutomation:
    def __init__(self,
                microsoft_groups_token: str,
                microsoft_create_apps_token: str,
                windows_consent_app_token: str,
                redirect_urls: list):
        self.microsoft_groups_headers = CaseInsensitiveDict()
        self.microsoft_groups_headers["Accept"] = "application/json"
        self.microsoft_groups_headers["Content-Type"] = "application/json"
        self.microsoft_groups_headers["Authorization"] = microsoft_groups_token
        self.microsoft_create_apps_headers = CaseInsensitiveDict()
        self.microsoft_create_apps_headers["Accept"] = "application/json"
        self.microsoft_create_apps_headers["Content-Type"] = "application/json"
        self.microsoft_create_apps_headers["Authorization"] = microsoft_create_apps_token
        self.windows_consent_app_headers = CaseInsensitiveDict()
        self.windows_consent_app_headers["Accept"] = "application/json"
        self.windows_consent_app_headers["Content-Type"] = "application/json"
        self.windows_consent_app_headers["Authorization"] = windows_consent_app_token
        self.redirect_urls = redirect_urls
        self.groups_size = None
        self.groups_df = None

    def __create_group_scale(self, scale_group_index: int):
        """
        Creates an azure group

        This function simply creates a group in an azure directory

        Parameters
        ----------
        scale_group_index : int
            This is a just a number to add at the end of the group name
        """
        index_str = str(scale_group_index)

        json_body = {
            "displayName": f"scale_group{index_str}",
            "mailEnabled": True,
            "securityEnabled": True,
            "groupTypes": [
            "Unified"
            ],
            "description": f"scale_group{index_str}",
            "mailNickname": f"scale_group{index_str}",
            "visibility": "private"
        }
        requests.post(url=GROUPS_AZURE_LINK, headers=self.microsoft_groups_headers, json=json_body)

    def create_group_scale_threading(self, start_index: int, number_of_groups: int):
        """
        Creates multiple azure groups

        This function creates azure groups using multi-threading approach

        Parameters
        ----------
        start_index : int
            The sequential number that will be the suffix of the credential name
        number_of_groups : int
            The number of accounts that will be created
        """
        with concurrent.futures.ThreadPoolExecutor() as executor:
            executor.map(self.__create_group_scale, range(start_index, start_index + number_of_groups))

    def create_azure_app_registration(self, app_name: str):
        """
        Creates a web app in azure

        This function simply creates a web app in azure with a specific name which is requested as a parameter

        Parameters
        ----------
        app_name : str

        Returns
        -------
        Response
        """
        create_app_body = {
            "displayName": app_name,
            "spa": {
                "redirectUris": []
            },
            "publicClient": {
                "redirectUris": []
            },
            "web": {
                "redirectUris": []
            },
            "signInAudience": "AzureADMyOrg",
            "requiredResourceAccess": [
                {
                    "resourceAppId": "00000003-0000-0000-c000-000000000000",
                    "resourceAccess": [
                        {
                            "id": "e1fe6dd8-ba31-4d61-89e7-88639da4683d",
                            "type": "Scope"
                        }
                    ]
                }
            ]
        }
        return requests.post(APPS_AZURE_LINK, headers=self.microsoft_create_apps_headers, json=create_app_body)

    def __assign_groups_to_members(self, user_id):
        """
        Assigns 1 to 6 random groups

        This function is called from assign_groups_to_members_threading, because it uses a multi-threading
        approach to call this function. This function assigns randomly from 1 to 6 groups to this user.

        Parameters
        ----------
        user_id : str
            The id of the user
        """
        json_body = {
            "requests": []
        }

        num_of_groups = random.randint(1, 6)
        random_groups = random.sample(range(0, self.groups_size), num_of_groups)
        for group_index in random_groups:
            group_id = self.groups_df.iloc[group_index]
            tmp_request = {
                "id": f"member_{group_id}_{user_id}",
                "method": "POST",
                "url": f"/groups/{group_id}/members/$ref",
                "headers": {
                    "Content-Type": "application/json"
                },
                "body": {
                    "@odata.id": f"https://graph.microsoft.com/beta/directoryObjects/{user_id}"
                }
            }
            json_body["requests"].append(tmp_request)
        requests.post(ASSIGN_GROUPS_AZURE_LINK, headers=self.microsoft_groups_headers, json=json_body)

    def assign_groups_to_members_threading(self, users_csv_path: str, groups_csv_path: str):
        """
        Assigns randomly assigns 1 to 6 groups to users in azure

        This function loads a csv with users info and groups info, then selects 1000 to 1000 users
        to call a function that assigns a user with groups. After that, it needs an sleep time because
        azure rejects many requests at the same, maybe it's something about DDOS protection. Be aware that the
        execution may be interrupted or something, that's because you selected too many users. If that's
        the case, then you should wait the program to end and watch manually who was the last users with
        groups assigned.

        Parameters
        ----------
        users_csv_path : str
            The path for the csv of the users you want to assign to groups
        groups_csv_path : str
            The path for the csv file of the groups you want to be assign
        """
        users_df = pd.read_csv(users_csv_path)
        groups_df = pd.read_csv(groups_csv_path)

        self.groups_df = groups_df["id"]
        users_df = users_df["id"]
        users_size = users_df.size
        self.groups_size = self.groups_df.size

        start_index = end_index = 0
        end_index = clamp(end_index+1000, 0, users_size-1)
        while start_index < users_size:
            tmp_users_df = users_df.loc[start_index:end_index]

            with concurrent.futures.ThreadPoolExecutor() as executor:
                executor.map(self.__assign_groups_to_members, tmp_users_df)

            logger.info(f"Execution finished from {start_index} to {end_index}, waiting to run 1000 more...")
            time.sleep(130)
            start_index = end_index+1
            end_index = clamp(end_index+1000, 0, users_size-1)
        logger.info(f"start index is: {start_index} and last index is: {end_index}")

    def grant_read_permissions(self, app_object_id: str):
        """
        Grants the basic permissions to an app

        This function grants Read permissions to User, Directory and Group to the app. This only receives
        the app_object_id of the app to work.

        Parameters
        ----------
        app_object_id : str
        """
        grant_read_permissions = {
            "requiredResourceAccess": [
                {
                    "resourceAppId": "00000003-0000-0000-c000-000000000000",
                    "resourceAccess": [
                        {
                            "id": "e1fe6dd8-ba31-4d61-89e7-88639da4683d",
                            "type": "Scope"
                        },
                        {
                            "id": "df021288-bdef-4463-88db-98f22de89214",
                            "type": "Role"
                        },
                        {
                            "id": "5b567255-7703-4780-807c-7be8301ae99b",
                            "type": "Role"
                        },
                        {
                            "id": "7ab1d382-f21e-4acd-a863-ba3e13f7da61",
                            "type": "Role"
                        }
                    ]
                }
            ]
        }
        requests.patch(f"{APPS_AZURE_LINK}/{app_object_id}",
                    headers=self.microsoft_create_apps_headers, json=grant_read_permissions)

    def consent_admin_permissions(self, app_client_id: str):
        """
        Consents the permissions of an app

        This function gives admin consent of all the permissions in the app. By default, the app
        has only Read permissions.

        Parameters
        ----------
        app_client_id: str
        """
        admin_consent_body = {
            "clientAppId": f"{app_client_id}",
            "onBehalfOfAll": True,
            "checkOnly": False,
            "tags": [],
            "constrainToRra": True,
            "dynamicPermissions": [
                {
                    "appIdentifier": "00000003-0000-0000-c000-000000000000",
                    "appRoles": [
                        "User.Read.All",
                        "Group.Read.All",
                        "Directory.Read.All"
                    ],
                    "scopes": [
                        "User.Read"
                    ]
                }
            ]
        }
        # Gives the consent to the app permissions as an admin
        requests.post(ADMIN_CONSENT_FOR_APP_URL, headers=self.windows_consent_app_headers,
                    json=admin_consent_body)

    def __create_secret_client(self, app_object_id: str, years_to_expire: int = 3):
        """
        Creates api permission credentials to the app

        This function generates an api key and client secret to access the app. This function has to be
        private because you need to catch the client secret that is only shown once.

        Parameters
        ----------
        app_object_id : str
        years_to_expire : int

        Output
        ------
        json
        """
        start_date_time = datetime.now()
        end_date_time = start_date_time.replace(year=start_date_time.year + years_to_expire)

        parsed_start_dt = get_datetime_to_ISO_format(start_date_time)
        parsed_end_dt = get_datetime_to_ISO_format(end_date_time)

        app_secret_client_body = {
            "passwordCredential": {
                "displayName": "test-description",
                "endDateTime": f"{parsed_end_dt}",
                "startDateTime": f"{parsed_start_dt}"
            }
        }

        return requests.post(f"{APPS_AZURE_LINK}/{app_object_id}/addPassword",
                                                headers=self.microsoft_create_apps_headers, json=app_secret_client_body)

    def modify_redirect_urls_of_app(self, app_object_id: str):
        """
        Updates the redirect_urls of a web app

        This function sends a patch request to modify the redirect urls of a specific web app. It is important to
        know that this functions fully updates the redirect urls, so make sure to initialize this class
        with all urls you want your app to have.

        Parameters
        ----------
        app_object_id : str

        """
        redirect_url_body = {
            "spa": {
                "redirectUris": []
            },
            "publicClient": {
                "redirectUris": []
            },
            "web": {
                "redirectUris": self.redirect_urls
            }
        }
        requests.patch(f"{APPS_AZURE_LINK}/{app_object_id}", headers=self.microsoft_create_apps_headers,
                    json=redirect_url_body)

    def modify_redirect_urls_of_app_threading(self, object_id_csv_path: str):
        """
        Modifies multiple redirect urls from a csv

        This function reads a csv containing the object ids of the azure apps, then executes
        the funcion modify_redirect_urls_of_app using multi-threading

        Parameters
        ----------
        object_id_csv_path : str
            The path of the parameter of the csv
        """
        df = pd.read_csv(object_id_csv_path)
        df = df['object_id']

        with concurrent.futures.ThreadPoolExecutor() as executor:
            executor.map(self.modify_redirect_urls_of_app, df)

    def create_azure_app_registrations_apis(self, tenant_id: str, start: int, number_of_apps: int):
        """
        Registers, configures an azure app and returns a csv with API credentials

        This function calls several functions to fully configure an azure app. The first one is for the
        creation of the app, then another to grant User.Read.All, Directory.Read.All, Group.Read.All. Then,
        you it calls a function that works from another API to give admin consent the previous permissions
        of the app. Furthermore, creates an API key and saves the secret key. After that, adds the
        redirect urls in the app and at last, creates two csv with the credentials of the app.

        Parameters
        ----------
        start : int
            The start index for the app name that will be created
        number_of_apps: int
            The number of apps that will be created starting from the ``start`` index
        tenant_id: str
            The id of the azure active directory

        Returns
        -------
        None
            Doesn't return anything but creates two csv files

        Examples
        --------
        >>> create_azure_app_registrations_apis("89f8652e-c99e-43a0-ab1f-9273081e5aaa", 10, 5)
        >>> create_azure_app_registrations_apis("89f8652e-c99e-43a0-ab1f-9273081e5aaa", 5, 1)
        """

        tenant_id_list = list()
        client_id_list = list()
        client_secret_list = list()
        object_id_list = list()
        for app_index in range(start, start + number_of_apps):
            try:
                create_request_response = self.create_azure_app_registration(f"aruba-cloudauth-cred-scale-{app_index}")
                app_object_id = create_request_response.json()["id"]
                app_client_id = create_request_response.json()["appId"]

                self.grant_read_permissions(app_object_id)

                self.consent_admin_permissions(app_client_id)

                app_secret_client_request = self.__create_secret_client(app_object_id)

                secret_client_content = app_secret_client_request.json()
                client_secret = secret_client_content["secretText"]

                self.modify_redirect_urls_of_app(app_object_id)

                tenant_id_list.append(tenant_id)
                client_id_list.append(app_client_id)
                client_secret_list.append(client_secret)
                object_id_list.append(app_object_id)

            except Exception:
                logger.error(Exception("The script didn't finished as expected! Saving the results in the csv"))
                break

        df = pd.DataFrame({'tenant_id': tenant_id_list,
                            'client_id': client_id_list,
                            'client_secret': client_secret_list})
        does_file_exists = os.path.isfile(r"azure_app_credentials.csv")
        df.to_csv(r"azure_app_credentials.csv", index=False, header=(not does_file_exists), mode='a')

        df_object_id = pd.DataFrame({'object_id': object_id_list})
        does_file_exists_object_id = os.path.isfile(r"azure_app_object_id.csv")
        df_object_id.to_csv(r"azure_app_object_id.csv", index=False, header=(not does_file_exists_object_id), mode='a')

    def __delete_active_application(self, app_object_id: str):
        """
        Deletes permanently an application

        This function deletes temporary an active azure application, then deletes it permanently from that
        temporary directory.

        Parameters
        ----------
        app_object_id: str
            The object id of the application
        """

        requests.delete(f"{APPS_AZURE_LINK}/{app_object_id}", headers=self.microsoft_create_apps_headers)

        requests.delete(f"{APP_AZURE_DELETE_PERMANENTLY_LINK}/{app_object_id}", headers=self.microsoft_create_apps_headers)

    def delete_active_application_threading(self, object_id_csv_path):
        """
        Deletes multiple applications

        This function reads a csv with the object ids of the application that will be deleted, then deletes
        each of them twice; the first one is temporary and the second one is permanently.

        Parameters
        ----------
        object_id_csv_path: csv
            The csv containing one or more objects id for applications
        """

        df = pd.read_csv(object_id_csv_path)
        df = df['object_id']

        with concurrent.futures.ThreadPoolExecutor() as executor:
            executor.map(self.__delete_active_application, df)


from lib.cuckoo.common.abstracts import Signature

class DropBox(Signature):
    name = "cloud_dropbox"
    description = "Looks up the Dropbox cloud service"
    severity = 2
    categories = ["cloud"]
    authors = ["RedSocks"]
    minimum = "2.0"

    domains = [
        "dropbox.com",
        "www.dropbox.com",
        "dl.dropboxusercontent.com",
        "dl.dropbox.com",
        "dl-balancer.x.dropbox.com",
        "www.v.dropbox.com",
        "duc-balancer.x.dropbox.com",
    ]

    def on_complete(self):
        for indicator in self.domains:
            if self.check_domain(pattern=indicator):
                self.mark_ioc("domain", indicator)
                return True


import pyautogui

# Returns two integers, the width and height of the screen. (The primary monitor, in multi-monitor setups.)
screenWidth, screenHeight = pyautogui.size()
# Returns two integers, the x and y of the mouse cursor's current position.
currentMouseX, currentMouseY = pyautogui.position()
print(screenWidth, screenHeight, currentMouseX, currentMouseY)

def moveMouse(start, finish):
    pyautogui.mouseUp(button="left")
    pyautogui.moveTo(start["x"], start["y"])
    pyautogui.mouseDown()
    # pyautogui.moveTo(finish["x"], finish["y"])
    pyautogui.dragTo(finish["x"], finish["y"], 1, button='left')
    pyautogui.mouseUp(button="left")

def mouseTo(point):
    pyautogui.moveTo(point["x"], point["y"])

def withinGameBox(screen):
    currentMouseX, currentMouseY = pyautogui.position()
    if currentMouseX < screen['x1'] or \
       currentMouseY < screen['y1'] or \
       currentMouseX > screen['x2'] or \
       currentMouseY > screen['y2']:
        # Out of game box
        return False
    return True


from abc import ABC,abstractmethod

class Shape(ABC):
    def __init__(self,dim1,dim2):
        self.dim1=dim1
        self.dim2=dim2

    @abstractmethod
    def area(self):
        #print("Shape has no area")
        pass
        #this method have no body other method will overwrite this and use this

class Triangle(Shape):

    #As this class inherit Shape class it must use area or abstract method otherwise error will be shown
    def area(self):
        area=0.5* self.dim1*self.dim2
        print("Area of Triangle is :",area)

class Rectangle(Shape):
    def area(self):
        area=self.dim1*self.dim2
        print("Area of Rectangle is :",area)

# we can't create abstract class object
# s1= Shape(10,20)
# s1.area()

t1=Triangle(20,30)
t1.area()

r1=Rectangle(20,30)
r1.area()


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

class Solution:
    def deleteDuplicates(self, head: ListNode) -> ListNode:
        if not head or not head.next:
            return head
        cur_val = head.val
        last_head = head
        start_head = head
        while head:
            if head.val != cur_val:
                last_head.next = head
                last_head = head
            if not head.next:
                last_head.next = None
                return start_head
            cur_val = head.val

            head = head.next

        return start_head