from faker import Faker
import random
import os
import csv
import spacy
import re
import email
import nltk
import pandas as pd
from spacy.training.example import Example
import warnings

# Ignore all user warnings globally
warnings.simplefilter("ignore", UserWarning)

fake = Faker('en_GB')  # Use the 'en_GB' locale for UK-specific data

email_files = []

def FindFilePaths(path):

    for root, dirs, files in os.walk(path):
        for file in files:
            if "." not in file:
                email_files.append(os.path.join(root, file))

def ProcessFiles(email_file):

    with open(email_file, 'r') as f:
        raw_email = f.read()
        email_message = email.message_from_string(raw_email)
        body = ""
        for part in email_message.walk():
            if part.get_content_type() == 'text/plain':
                body += part.get_payload()
    return body

def GenNewEmail():

    # Generate a random number of emails to use for the paragraph
    num_emails = random.randint(5, 10)
    email_bodies = []
    for i in range(num_emails):
        email_file = random.choice(email_files)
        email_body = ProcessFiles(email_file)
        email_bodies.append(email_body)

    # Concatenate the email bodies to form a single paragraph
    paragraph = "\n\n".join(email_bodies)

    # Tokenize the paragraph into sentences using NLTK
    sentences = nltk.sent_tokenize(paragraph)

    # Generate a random number of sentences to use for the final paragraph
    num_sentences = random.randint(3, 5)

    # Select random sentences from the original paragraph to form the final paragraph
    final_sentences = []
    for i in range(num_sentences):
        sentence = random.choice(sentences)
        final_sentences.append(sentence)

    # Concatenate the final sentences to form the final paragraph
    final_paragraph = " ".join(final_sentences)

    # define the regular expression pattern to match URLs
    url_pattern = re.compile(
        r'http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+')

    # remove the URLs from the text paragraph
    final_paragraph = re.sub(url_pattern, '', final_paragraph)

    return final_paragraph

def GenName():

    # Randomly choose whether to generate a single name or full name
    rand = fake.boolean()

    if rand:
        # Generate a name
        name = fake.name()
    else:
        if rand:
            name = fake.first_name()
        else:
            name = fake.last_name()

    return name

def GenEmail():

    # Generate an email with a random domain name
    email = fake.email(domain=fake.domain_name())
    return email

def GenPhone():
    # Randomly choose to generate a phone number in different formats
    rand = fake.boolean()

    phone_number = ''

    if rand:
        mobile_prefix = '07'
        mobile_suffix = ''.join([str(random.randint(0, 9)) for i in range(8)])
        mobile_number = f'{mobile_prefix}{mobile_suffix}'

        # Randomly select a format for the mobile number
        mobile_format = random.choice(['07{} {}'.format(mobile_suffix[:3], mobile_suffix[3:]),
                                       '+44 7{} {}'.format(
                                           mobile_suffix[:3], mobile_suffix[3:]),
                                       '07{}-{}'.format(mobile_suffix[:3], mobile_suffix[3:])])
        phone_number = mobile_format

    else:
        # List of 10 UK area codes
        area_codes = ['01', '02', '03', '05', '07',
                      '08', '0161', '01642', '01752', '020']
        # Generate a random landline number within the selected area code
        area_code = random.choice(area_codes)
        landline_number = f'{area_code}{random.randint(10000, 999999)}'
        # Randomly select a format for the landline number
        landline_format = random.choice(['{} {}'.format(landline_number[:5], landline_number[5:]),
                                         '{}-{}'.format(
                                             landline_number[:5], landline_number[5:]),
                                         '+44 {} {}'.format(
                                             landline_number[:4], landline_number[4:]),
                                         '+44-{}-{}'.format(landline_number[:4], landline_number[4:])])
        phone_number = landline_format

    return str(phone_number)

def GenNHS():

    # Generate a random NHS number
    nhs_number = fake.numerify('##########')

    # Choose a random format
    formats = ['nnn nnn nnnn', 'nnnnnnnnnn', 'nnn-nnn-nnnn', 'nnn.nnn.nnnn']
    format_choice = random.choice(formats)

    # Format the NHS number accordingly
    if format_choice == 'nnn nnn nnnn':
        formatted_number = '{} {} {}'.format(
            nhs_number[:3], nhs_number[3:6], nhs_number[6:])
    elif format_choice == 'nnnnnnnnnn':
        formatted_number = nhs_number
    elif format_choice == 'nnn-nnn-nnnn':
        formatted_number = '{}-{}-{}'.format(
            nhs_number[:3], nhs_number[3:6], nhs_number[6:])
    else:
        formatted_number = '{}.{}.{}'.format(
            nhs_number[:3], nhs_number[3:6], nhs_number[6:])

    return str(formatted_number)

def GenAddress():

    # generate a random Building Number
    house_number = fake.building_number()
    # randomly choose either 'A' or 'a' ' '
    letter = random.choice(['A', 'a', ''])

    house_number = str(house_number)+letter

    uk_address = house_number + " " + fake.street_name() + " " + \
        fake.city() + " " + fake.postcode()

    return uk_address

def GenCard():

    # Choose a random format
    formats = ['XXXX XXXX XXXX XXXX',
               'XXXX-XXXX-XXXX-XXXX', 'XXXXXXXXXXXXXXXX']
    chosen_format = random.choice(formats)

    # Choose a random format
    cards = ['visa', 'mastercard', 'amex']
    card_choice = random.choice(cards)
    # Generate a credit card number
    credit_card_number = fake.credit_card_number(card_type=card_choice)

    # Format the credit card number according to the chosen format
    if chosen_format == 'XXXX XXXX XXXX XXXX':
        formatted_card_number = ' '.join(
            [credit_card_number[i:i+4] for i in range(0, 16, 4)])
    elif chosen_format == 'XXXX-XXXX-XXXX-XXXX':
        formatted_card_number = '-'.join([credit_card_number[i:i+4]
                                         for i in range(0, 16, 4)])
    else:
        formatted_card_number = credit_card_number.replace(' ', '')

    return str(formatted_card_number)

def GenBank():

    bank_account_number = fake.random_number(digits=8)

    return str(bank_account_number)

def GenSortCode():

    sort_code = str(fake.random_number(digits=6))

    # randomly choose one of the two formats
    format_choice = random.choice(["xxxxxx", "xx-xx-xx"])

    # format the sort code accordingly
    if format_choice == "xx-xx-xx":
        sort_code = '{}-{}-{}'.format(
            sort_code[:2], sort_code[2:4], sort_code[4:6])

    return str(sort_code)

def GenDOB():

    # Generate a random date of birth and format it as '01 Jan 1990'
    dob = fake.date_of_birth().strftime('%d %b %Y')

    return str(dob)

def GenKeywords():

    KeyWords = []
    # Generate a random number between 0 and 9
    random_number = random.randint(0, 10)

    # Generate a random number between 1 and 2
    random_number_2 = random.randint(1, 2)

    # Create an if-elseif statement based on the generated random number
    if random_number == 0:

        # Create a for loop based on the generated random number
        for i in range(random_number_2):
            KeyWords.append(['SortCode', GenSortCode()])

    elif random_number == 1:

        # Create a for loop based on the generated random number
        for i in range(random_number_2):
            KeyWords.append(['BankAccount', GenBank()])
            KeyWords.append(['SortCode', GenSortCode()])

    elif random_number == 2:

        # Create a for loop based on the generated random number
        for i in range(random_number_2):
            KeyWords.append(['NHS', GenNHS()])
            KeyWords.append(['BankAccount', GenBank()])
            KeyWords.append(['SortCode', GenSortCode()])

    elif random_number == 3:

        # Create a for loop based on the generated random number
        for i in range(random_number_2):
            KeyWords.append(['CreditCard', GenCard()])
            KeyWords.append(['NHS', GenNHS()])
            KeyWords.append(['BankAccount', GenBank()])
            KeyWords.append(['SortCode', GenSortCode()])

    elif random_number == 4:

        # Create a for loop based on the generated random number
        for i in range(random_number_2):
            KeyWords.append(['PhoneNo', GenPhone()])
            KeyWords.append(['CreditCard', GenCard()])
            KeyWords.append(['NHS', GenNHS()])
            KeyWords.append(['BankAccount', GenBank()])
            KeyWords.append(['SortCode', GenSortCode()])

    elif random_number == 5:

        # Create a for loop based on the generated random number
        for i in range(random_number_2):
            KeyWords.append(['Address', GenAddress()])
            KeyWords.append(['PhoneNo', GenPhone()])
            KeyWords.append(['CreditCard', GenCard()])
            KeyWords.append(['NHS', GenNHS()])
            KeyWords.append(['BankAccount', GenBank()])
            KeyWords.append(['SortCode', GenSortCode()])

    elif random_number == 6:

        # Create a for loop based on the generated random number
        for i in range(random_number_2):
            KeyWords.append(['Name', GenName()])
            KeyWords.append(['Address', GenAddress()])
            KeyWords.append(['PhoneNo', GenPhone()])
            KeyWords.append(['CreditCard', GenCard()])
            KeyWords.append(['NHS', GenNHS()])
            KeyWords.append(['BankAccount', GenBank()])
            KeyWords.append(['SortCode', GenSortCode()])

    elif random_number == 7:

        # Create a for loop based on the generated random number
        for i in range(random_number_2):
            KeyWords.append(['Email', GenEmail()])
            KeyWords.append(['Name', GenName()])
            KeyWords.append(['Address', GenAddress()])
            KeyWords.append(['PhoneNo', GenPhone()])
            KeyWords.append(['CreditCard', GenCard()])
            KeyWords.append(['NHS', GenNHS()])
            KeyWords.append(['BankAccount', GenBank()])
            KeyWords.append(['SortCode', GenSortCode()])

    elif random_number == 8:

        # Create a for loop based on the generated random number
        for i in range(random_number_2):
            KeyWords.append(['DOB', GenDOB()])
            KeyWords.append(['Email', GenEmail()])
            KeyWords.append(['Name', GenName()])
            KeyWords.append(['Address', GenAddress()])
            KeyWords.append(['PhoneNo', GenPhone()])
            KeyWords.append(['CreditCard', GenCard()])
            KeyWords.append(['NHS', GenNHS()])
            KeyWords.append(['BankAccount', GenBank()])
            KeyWords.append(['SortCode', GenSortCode()])

    else:

        KeyWords.append([' ', ' '])

    return KeyWords

def GetIndices(keywords, paragraph):

    used_indices = set()

    for keyword in keywords:
        start_index = paragraph.find(keyword[1])
        if start_index != -1:
            end_index = start_index + len(keyword[1]) - 1

            used_indices.add((start_index, end_index))

    return used_indices

def IntroduceNewKeywords():

    KeyWords = GenKeywords()
    KeyWords2 = KeyWords.copy()
    final_paragraph = GenNewEmail()

# Insert keywords into random non-overlapping places in the paragraph
    used_indices = set()

    # Generate a random index that does not overlap with any previous keyword
    index = random.randint(0, len(final_paragraph) - 1)

    final_paragraph = final_paragraph[:index] + ' ' + \
        KeyWords[0][1] + ' ' + final_paragraph[index+len(KeyWords[0][1]):]

    used_indices = GetIndices(KeyWords2, final_paragraph)

    del KeyWords[0]

    for keyword in KeyWords:

        length = len(keyword[1])

        # Generate a random index that does not overlap with any previous keyword
        start = random.randint(0, len(final_paragraph) - 1)

        end = start + length

        for start, end in used_indices:
            start = random.randint(0, len(final_paragraph) - 1)
            end = start + length

        final_paragraph = final_paragraph[:start] + ' ' + \
            keyword[1] + ' ' + final_paragraph[start+len(keyword[1]):]

        used_indices = GetIndices(KeyWords2, final_paragraph)

    return FindIndices(KeyWords2, final_paragraph)

def FindIndices(keywords, paragraph):

    keyword_list = []

    for keyword in keywords:
        start_index = paragraph.find(keyword[1])
        if start_index != -1:
            end_index = start_index + len(keyword[1]) - 1

            item = {'Label': keyword[0], 'Keyword': keyword[1],
                    'Start': start_index, 'End': end_index}

            keyword_list.append(item)

    # append a new row
    return pd.Series({'Text': paragraph, 'Features': keyword_list})

FindFilePaths('maildir')

# create empty dataframe
df = pd.DataFrame(columns=["Text", "Features"])

for i in range(100):

    pd_series = IntroduceNewKeywords()
    delete_row = False
    # Keep track of seen start and end values
    seen_start = set()
    seen_end = set()

    for feat in pd_series['Features']:
        start = feat['Start']
        end = feat['End']
        # Check if start or end value has been seen before
        if start in seen_start or end in seen_end:
            delete_row = True
            break
        seen_start.add(start)
        seen_end.add(end)

    if not delete_row:
        # append the new row to the DataFrame
        df = pd.concat([df, pd_series.to_frame().T],
                       ignore_index=True)
    else:
        print('Delete')

    i = i+1

    # Clear seen sets for next row
    seen_start.clear()
    seen_end.clear()

# Load the spaCy model
nlp = spacy.blank('en')

# Define the new labels
LABELS = ['Name', 'Email', 'NHS', 'DOB', 'Address',
          'PhoneNo', 'CreditCard', 'BankAccount', 'SortCode']

# Add the new labels to the model
ner = nlp.create_pipe("ner")
for label in LABELS:
    ner.add_label(label)
nlp.add_pipe('ner', last=True)
nlp.replace_pipe("ner", "ner")
nlp.initialize()

# Load the training data from the Pandas DataFrame
train_data = []
for i, row in df.iterrows():
    text = row['Text']
    features = row['Features']

    ents = []

    for feat in features:
        label = feat['Label']
        start = feat['Start']
        end = feat['End']
        keyword = feat['Keyword']
        ents.append((start, end, label))

    doc = nlp(text)

    spans = []

    for start, end, label in ents:
        span = doc.char_span(start, end, label=label)
        if span is not None:
            spans.append(span)
    doc.spans['entities'] = spans
    train_data.append(Example.from_dict(doc, {'entities': spans}))

# Train the model

nlp.begin_training()

for i in range(20):
    losses = {}
    nlp.update(train_data, losses=losses, drop=0.2)
    print(losses)

score = nlp.evaluate(train_data)
# print(score)

# Save the trained model to disk
output_dir = "Save/"
nlp.to_disk(output_dir)


import numpy as np
from netCDF4 import Dataset
from enum import  Enum
from Libs.Scaling import ScalerListToArray
from datetime import datetime
from datetime import timedelta
import Libs.SmartOutput.julian
import matplotlib.pyplot as plt
import matplotlib.colors
import os
from sys import platform

import numpy as np
import matplotlib as mpl
import cartopy.crs as ccrs
from cartopy.mpl.ticker import LongitudeFormatter, LatitudeFormatter
import cartopy.feature as cfeature
from cartopy.io.shapereader import Reader
from cartopy.feature import ShapelyFeature
from A03_Hydraulics_Implementation.TRENDY.NetCDF_CVS import NetCDF_CVS_Reader
from A03_Hydraulics_Implementation.TRENDY.extraction import HalfDegreeExtractor
from A03_Hydraulics_Implementation.AutoAnalysis.PaperFigures_N2.Revisions2022.BiomassAmazonConverter \
    import BiomassAmazonAnomalyConverter

import os
rtpath = '../TRENDY/cVeg/conv'
files = [f for f in os.listdir(rtpath) if os.path.isfile(os.path.join(rtpath, f))]

file_str = rtpath + '/' + files[0]

ab_extractor = HalfDegreeExtractor('../Amazon_basin_05.tsv', '\t')
raisg_mask = r"../AB-SHAPE/Amazon_shape.shp"
mask = ShapelyFeature(Reader(raisg_mask).geometries(),
                      ccrs.PlateCarree())

normAGB = mpl.colors.Normalize(-5, 5)
colorsAGB = [[normAGB(-5), "#9C0200"],
             [normAGB(-2.5), "#ff9a00"],
             [normAGB(-0.5), "white"],
             [normAGB(0.0), "white"],
             [normAGB(0.5), "white"],
             [normAGB(5), "tab:blue"]]
cmapAGB = mpl.colors.LinearSegmentedColormap.from_list("", colorsAGB)

yois = [2005, 2007, 2009, 2010]

for yoi in yois:
    index = 1
    fig = plt.figure(figsize=(16, 10))

    yearbeginAGB = 1985
    yearEndAGB = 2010

    for file in files:
        filename = os.path.join(rtpath, file)
        reader = NetCDF_CVS_Reader(filename, incomplete=False)

        cVeg = reader.GetCompleteSpaceOverTimeRange('cVeg', yearbeginAGB, yearEndAGB)
        unit_str = reader.GetVarUnit('cVeg')

        converter = BiomassAmazonAnomalyConverter()
        diff_anomaly = converter.Convert_CVS(cVeg, yoi, yearbeginAGB, yearEndAGB, yearbeginAGB)

        ab_extractor.GetCVSCoords(reader.lons, reader.lats)
        img_ab = ab_extractor.CreateCVSImage(diff_anomaly)
        img_extent = ab_extractor.IMG_extent

        if (unit_str == 'kg m-2') | (unit_str == 'kg m^-2') | (unit_str == 'kg/m$^2$'):
            multiplier = 1.0
        elif (unit_str == 'kgC/m2') | (unit_str == 'kgC m-2') | (unit_str == 'kg C m-2'):
            multiplier = 1.0
        else:
            print("Invalid cVeg unit")
            exit(99)

        # To convert from kg AGB C m-2 to Mg C AGB Ha-1
        img_ab *= 10.0
        # Flip according to the latitude axis
        img_ab = img_ab[::-1, :]

        axGeo = fig.add_subplot(4, 4, index, projection=ccrs.PlateCarree())
        lon_formatter = LongitudeFormatter(zero_direction_label=True, number_format='g')
        lat_formatter = LatitudeFormatter()
        axGeo.xaxis.set_major_formatter(lon_formatter)
        axGeo.yaxis.set_major_formatter(lat_formatter)
        axGeo.add_feature(cfeature.BORDERS, edgecolor='tab:grey')
        axGeo.coastlines(resolution='110m', linewidth=1, color='tab:grey')
        axGeo.set_extent(np.array(img_extent), crs=ccrs.PlateCarree())
        axGeo.add_feature(mask, edgecolor='black', linewidth=1, facecolor="None")
        axGeo.text(0.97, 0.08, file[:len(file) - 11], horizontalalignment='right', verticalalignment='center',
                   transform=axGeo.transAxes, size=10,
                   bbox=dict(facecolor='white', alpha=0.8, edgecolor='white'))
        imsh = axGeo.imshow(img_ab, transform=ccrs.PlateCarree(),
                            extent=img_extent, cmap=cmapAGB, norm=normAGB)

        index += 1

    cax = plt.axes([0.12, 0.15, 0.78, 0.02])

    bar = plt.colorbar(imsh, cax=cax, orientation="horizontal")
    bar.set_label('Absolute AGB anomaly [Mg/ha]', fontsize=12)
    plt.subplots_adjust(wspace=0.1, hspace=0.1, bottom=0.2)
    plt.savefig('cVeg_AB_Anomaly_' + str(yoi) + '.png', dpi=300, bbox_inches='tight',
                    pad_inches=0)
    plt.close()


from collections import deque
import sys

input = sys.stdin.readline

n = int(input())
parent = [-1 for _ in range(n+1)]
edge = [[] for _ in range(n+1)]
parent[1] = 0

def bfs(start):
  dq = deque()

  for i in edge[start]:
    dq.append((i,start))

  while dq:
    a,b = dq.popleft()
    parent[a] = b

    for i in edge[a]:
      if parent[i] == -1:
        dq.append((i,a))

for i in range(n-1):
  a,b = map(int,input().split())
  edge[a].append(b)
  edge[b].append(a)

bfs(1)

for i in range(2,n+1):
  print(parent[i])


from django.urls import re_path, path, include
from rest_framework.routers import DefaultRouter

from .consumers import MessageConsumer

from .api import ChannelViewSet, MessageViewSet, ViewedChannelAPI

router = DefaultRouter()
router.register(r'channel', ChannelViewSet, basename='channel')
router.register(r'message', MessageViewSet, basename='message')

urlpatterns = [
    path('api/', include(router.urls)),
    path(r'api/viewed-channel/<uuid:channel_id>', ViewedChannelAPI.as_view(), name='viewed-channel'),
]

ws_urlpatterns = [
    re_path(r'ws/messages', MessageConsumer.as_asgi())
]


# Shane Sarnac
# APPM 4660 - Numerical Analysis 2
# To get most up-to date code, you may clone this code from my github
# at the following link:
# https://github.com/shanesarnac/IntermediateAnalysis2/tree/master/FinalProject

import sys
import math
import matplotlib.pyplot as plt

class LevelCurvesSolver:
	def __init__(self, h, x, y, function_data):
		self.levelCurveX = [x]
		self.levelCurveY = [y]
		self.minX = min(function_data.x)
		self.maxX = max(function_data.x) + function_data.deltaX
		self.minY = min(function_data.y)
		self.maxY = max(function_data.y) + function_data.deltaY
		self.findLevelCurve(h, x, y, function_data)

		max_index = 40000

		for i in range(max_index):
			x2 = self.levelCurveX[-1]
			y2 = self.levelCurveY[-1]
			self.findLevelCurve(h, x2, y2, function_data)
		self.findLevelCurve(h, x, y, function_data)
		for i in range(max_index):
			x1 = self.levelCurveX[-2]
			y1 = self.levelCurveY[-2]
			self.findLevelCurve(h, x1, y1, function_data)

		#self.plotLevelCurve()

	def findLevelCurve(self, h, x, y, function_data):
		factory = StrategyFactory(function_data)
		strategy = factory.getStrategy(x, y)

		#print(strategy.getStrategyName())

		(x1, y1, x2, y2) = strategy.findValue(h,x,y)

		if function_data.isPointInData(x1,y1):
			self.levelCurveX.append(x1)
			self.levelCurveY.append(y1)
		if function_data.isPointInData(x2,y2):
			self.levelCurveX.append(x2)
			self.levelCurveY.append(y2)

	def plotLevelCurve(self):
		plt.plot(self.levelCurveX, self.levelCurveY, "ro")
		plt.xlabel("x")
		plt.ylabel("y")
		plt.title("Level Curve For Given Point (x0 = " + str(self.levelCurveX[0]) + ", y0 = " + str(self.levelCurveY[0]) + ")")
		plt.axis([self.minX, self.maxX, self.minY, self.maxY])
		plt.show()

# A factory class for generating the proper strategy
class StrategyFactory:
	def __init__(self, function_data):
		self.data = function_data

	def determineEdgeStrategy(self, x, y):
		if float(y) == self.data.y[0]:
				if float(x) in self.data.x:
					return BottomEdgeVertexStrategy(self.data)
				else:
					return BottomEdgeMiddlePointStrategy(self.data)
		if float(y) == self.data.y[-1]:
			if float(x) in self.data.x:
				return TopEdgeVertexStrategy(self.data)
			else:
				return TopEdgeMiddlePointStrategy(self.data)
		if float(x) == self.data.x[0]:
			if float(y) in self.data.y:
				return LeftEdgeVertexStrategy(self.data)
			else:
				return LeftEdgeMiddlePointStrategy(self.data)
		if float(x) == self.data.x[-1]:
			if float(y) in self.data.y:
				return RightEdgeVertexStrategy(self.data)
			else:
				return RightEdgeMiddlePointStrategy(self.data)

	def getStrategy(self, x, y):
		if not self.data.isPointInData(x,y):
			print("Error: Provided data point not in data set")
			exit()
		if self.data.isPointOnEdge(x,y):
			return self.determineEdgeStrategy(x, y)

		if x in self.data.x and y in self.data.y:
			return VertexStrategy(self.data)

		if x in self.data.x and y not in self.data.y:
			return VerticalVertexMiddlePointStrategy(self.data)

		if x not in self.data.x and y in self.data.y:
			return HorizontalVertexMiddlePointStrategy(self.data)

		return MiddlePointStrategy(self.data)

# Abstract strategy class used as the parent for the Strategy Design Pattern
class Strategy:
	def __init__(self, function_data):
		self.strategyName = "Strategy"
		self.function_values = function_data

	def getStrategyName(self):
		return self.strategyName

	def determineVertecies(self, x, y):
		raise NotImplementedError("This is an abstract class")

	def findValue(self, x, y):
		raise NotImplementedError("This is an abstract class")

# The given point is in-between vertices (case A)
class MiddlePointStrategy(Strategy):
	def __init__(self, function_data):
		Strategy.__init__(self, function_data)
		self.strategyName = "Middle Point Strategy"

	def determineVertecies(self, x, y):
		left_vertex = 0
		while self.function_values.x[left_vertex] < x:
			left_vertex += 1
		right_vertex = left_vertex
		left_vertex -=1

		bottom_vertex = 0
		while self.function_values.y[bottom_vertex] < y:
			bottom_vertex += 1
		top_vertex = bottom_vertex
		bottom_vertex -= 1

		top_left = self.function_values.data[left_vertex][top_vertex]
		bottom_left = self.function_values.data[left_vertex][bottom_vertex]
		top_right = self.function_values.data[right_vertex][top_vertex]
		bottom_right = self.function_values.data[right_vertex][bottom_vertex]

		return (top_left, bottom_left, top_right, bottom_right)

	def findValue(self, h, x, y):
		(top_left, bottom_left, top_right, bottom_right) = self.determineVertecies(x,y)
		dfdx = (top_right - top_left + bottom_right - bottom_left)/(4.0*self.function_values.deltaX)
		dfdy = (top_left - bottom_left + top_right - bottom_right)/(4.0*self.function_values.deltaY)

		#print("dfdx = " + str(dfdx))
		#print("dfdy = " + str(dfdy))

		x_new1 = x + h*(dfdy)
		y_new1 = y + h*(-dfdx)
		x_new2 = x + h*(-dfdy)
		y_new2 = y + h*(dfdx)

		return (x_new1, y_new1, x_new2, y_new2)

# The given point is a vertex in the data grid (case B)
class VertexStrategy(Strategy):
	def __init__(self, function_data):
		Strategy.__init__(self, function_data)
		self.strategyName = "Vertex Strategy"

	def determineVertecies(self, x, y):
		left_vertex = 0
		while self.function_values.x[left_vertex] < x:
			left_vertex += 1
		right_vertex = left_vertex+1
		left_vertex -= 1

		bottom_vertex = 0
		while self.function_values.y[bottom_vertex] < y:
			bottom_vertex += 1
		top_vertex = bottom_vertex + 1
		bottom_vertex -= 1

		top = self.function_values.data[left_vertex+1][top_vertex]
		bottom = self.function_values.data[left_vertex+1][bottom_vertex]
		left = self.function_values.data[left_vertex][top_vertex-1]
		right = self.function_values.data[right_vertex][top_vertex-1]

		return (top, bottom, left, right)

	def findValue(self, h, x, y):
		(top, bottom, left, right) = self.determineVertecies(x, y)

		dfdx = (right - left)/(2.0*self.function_values.deltaX)
		dfdy = (top - bottom)/(2.0*self.function_values.deltaY)

		x_new1 = x + h*(dfdy)
		y_new1 = y + h*(-dfdx)
		x_new2 = x + h*(-dfdy)
		y_new2 = y + h*(dfdx)

		return (x_new1, y_new1, x_new2, y_new2)

# The given point is on a vertex on the bottom edge (case C)
class BottomEdgeVertexStrategy(Strategy):
	def __init__(self, function_data):
		Strategy.__init__(self, function_data)
		self.strategyName = "Bottom Edge Vertex Strategy"

	def determineVertecies(self, x, y):
		left_vertex = 0
		while self.function_values.x[left_vertex] < x:
			left_vertex += 1
		right_vertex = left_vertex + 1
		left_vertex -= 1

		top_vertex = 1
		center_vertex = 0

		top = self.function_values.data[left_vertex+1][top_vertex]
		center = self.function_values.data[left_vertex+1][center_vertex]
		left = self.function_values.data[left_vertex][center_vertex]
		right = self.function_values.data[right_vertex][center_vertex]

		return (top, center, left, right)

	def findValue(self, h, x, y):
		(top, center, left, right) = self.determineVertecies(x,y)

		dfdx = (right - left)/(2*self.function_values.deltaX)
		dfdy = (top - center)/(self.function_values.deltaY)

		x_new1 = x + 0.5*h*(dfdy)
		y_new1 = y + 0.5*h*(-dfdx)
		x_new2 = x + 0.5*h*(-dfdy)
		y_new2 = y + 0.5*h*(dfdx)

		return (x_new1, y_new1, x_new2, y_new2)

# The given point is on a vertex on the left edge (case D)
class LeftEdgeVertexStrategy(Strategy):
	def __init__(self, function_data):
		Strategy.__init__(self, function_data)
		self.strategyName = "Left Edge Vertex Strategy"

	def determineVertecies(self, x, y):
		center_vertex = 0
		right_vertex = center_vertex + 1

		bottom_vertex = 0
		while self.function_values.y[bottom_vertex] < y:
			bottom_vertex += 1
		top_vertex = bottom_vertex + 1
		bottom_vertex -= 1

		top = self.function_values.data[center_vertex][top_vertex]
		bottom = self.function_values.data[center_vertex][bottom_vertex]
		center = self.function_values.data[center_vertex][bottom_vertex+1]
		right = self.function_values.data[right_vertex][bottom_vertex+1]

		return (top, bottom, center, right)

	def findValue(self, h, x, y):
		(top, bottom, center, right) = self.determineVertecies(x,y)

		dfdx = (right - center)/(self.function_values.deltaX)
		dfdy = (top - bottom)/(2.0*self.function_values.deltaY)

		x_new1 = x + 0.5*h*(dfdy)
		y_new1 = y + 0.5*h*(-dfdx)
		x_new2 = x + 0.5*h*(-dfdy)
		y_new2 = y + 0.5*h*(dfdx)

		return (x_new1, y_new1, x_new2, y_new2)

# The given point is on a vertex on the left edge (case E)
class RightEdgeVertexStrategy(Strategy):
	def __init__(self, function_data):
		Strategy.__init__(self, function_data)
		self.strategyName = "Right Edge Vertex Strategy"

	def determineVertecies(self, x, y):
		left_vertex = -2
		center_vertex = -1
		bottom_vertex = 0
		while self.function_values.y[bottom_vertex] < y:
			bottom_vertex += 1
		top_vertex = bottom_vertex + 1
		bottom_vertex -= 1

		top = self.function_values.data[center_vertex][top_vertex]
		bottom = self.function_values.data[center_vertex][bottom_vertex]
		center = self.function_values.data[center_vertex][bottom_vertex+1]
		left = self.function_values.data[left_vertex][bottom_vertex+1]

		return (top, bottom, center, left)

	def findValue(self, h, x, y):
		(top, bottom, center, left) = self.determineVertecies(x,y)

		dfdx = (center - left)/(self.function_values.deltaX)
		dfdy = (top - bottom)/(2.0*self.function_values.deltaY)

		x_new1 = x + 0.5*h*(dfdy)
		y_new1 = y + 0.5*h*(-dfdx)
		x_new2 = x + 0.5*h*(-dfdy)
		y_new2 = y + 0.5*h*(dfdx)

		return (x_new1, y_new1, x_new2, y_new2)

# The given point is on a vertex on the left edge (case F)
class TopEdgeVertexStrategy(Strategy):
	def __init__(self, function_data):
		Strategy.__init__(self, function_data)
		self.strategyName = "Top Edge Vertex Strategy"

	def determineVertecies(self, x, y):
		left_vertex = 0
		while self.function_values.x[left_vertex] < x:
			left_vertex += 1
		right_vertex = left_vertex + 1
		left_vertex -= 1

		center_vertex = -1
		bottom_vertex = -2

		left = self.function_values.data[left_vertex][center_vertex]
		right = self.function_values.data[right_vertex][center_vertex]
		center = self.function_values.data[left_vertex+1][center_vertex]
		bottom = self.function_values.data[left_vertex+1][bottom_vertex]

		return (left, right, center, bottom)

	def findValue(self, h, x, y):
		(left, right ,center, bottom) = self.determineVertecies(x,y)

		dfdx = (right - left)/(2.0*self.function_values.deltaX)
		dfdy = (center - bottom)/(self.function_values.deltaY)

		x_new1 = x + 0.5*h*(dfdy)
		y_new1 = y + 0.5*h*(-dfdx)
		x_new2 = x + 0.5*h*(-dfdy)
		y_new2 = y + 0.5*h*(dfdx)

		return (x_new1, y_new1, x_new2, y_new2)

# The given point is in-between vertices on the bottom edge (case G)
class BottomEdgeMiddlePointStrategy(Strategy):
	def __init__(self, function_data):
		Strategy.__init__(self, function_data)
		self.strategyName = "Bottom Edge Middle Point Strategy"

	def determineVertecies(self, x, y):
		left_vertex = 0
		while self.function_values.x[left_vertex] < x:
			left_vertex += 1
		right_vertex = left_vertex
		left_vertex -= 1

		bottom_vertex = 0
		top_vertex = 1

		top_left = self.function_values.data[left_vertex][top_vertex]
		left = self.function_values.data[left_vertex][bottom_vertex]
		top_right = self.function_values.data[right_vertex][top_vertex]
		right = self.function_values.data[right_vertex][bottom_vertex]

		return (top_left, left, top_right, right)

	def findValue(self, h, x, y):
		(top_left, left, top_right, right) = self.determineVertecies(x,y)

		dfdx = (left - right)/(2*self.function_values.deltaX)
		dfdy = (top_left - left + top_right - right)/(2*self.function_values.deltaY)

		x_new1 = x + 0.5*h*(dfdy)
		y_new1 = y + 0.5*h*(-dfdx)
		x_new2 = x + 0.5*h*(-dfdy)
		y_new2 = y + 0.5*h*(dfdx)

		return (x_new1, y_new1, x_new2, y_new2)

# The given point is in-between vertices on the left edge (case H)
class LeftEdgeMiddlePointStrategy(Strategy):
	def __init__(self, function_data):
		Strategy.__init__(self, function_data)
		self.strategyName = "Left Edge Middle Point Strategy"

	def determineVertecies(self, x, y):
		center_vertex = 0
		right_vertex = 1

		bottom_vertex = 0
		while self.function_values.y[bottom_vertex] < y:
			bottom_vertex += 1
		top_vertex = bottom_vertex
		bottom_vertex -= 1

		top = self.function_values.data[center_vertex][top_vertex]
		bottom = self.function_values.data[center_vertex][bottom_vertex]
		top_right = self.function_values.data[right_vertex][top_vertex]
		bottom_right = self.function_values.data[right_vertex][bottom_vertex]

		return (top, bottom, top_right, bottom_right)

	def findValue(self, h, x, y):
		(top, bottom, top_right, bottom_right) = self.determineVertecies(x,y)

		dfdx = (top_right - top + bottom_right - bottom)/(2.0*self.function_values.deltaX)
		dfdy = (top - bottom)/(2*self.function_values.deltaY)

		x_new1 = x + 0.5*h*(dfdy)
		y_new1 = y + 0.5*h*(-dfdx)
		x_new2 = x + 0.5*h*(-dfdy)
		y_new2 = y + 0.5*h*(dfdx)

		return (x_new1, y_new1, x_new2, y_new2)

# The given point is in-between vertices on the right edge (case I)
class RightEdgeMiddlePointStrategy(Strategy):
	def __init__(self, function_data):
		Strategy.__init__(self, function_data)
		self.strategyName = "Right Edge Middle Point Strategy"

	def determineVertecies(self, x, y):
		left_vertex = -2
		right_vertex = -1

		bottom_vertex = 0
		while self.function_values.y[bottom_vertex] < y:
			bottom_vertex += 1
		top_vertex = bottom_vertex
		bottom_vertex -= 1

		top_left = self.function_values.data[left_vertex][top_vertex]
		top = self.function_values.data[right_vertex][top_vertex]
		bottom_left = self.function_values.data[left_vertex][bottom_vertex]
		bottom = self.function_values.data[right_vertex][bottom_vertex]

		return (top_left, top, bottom_left, bottom)

	def findValue(self, h, x, y):
		(top_left, top, bottom_left, bottom) = self.determineVertecies(x,y)

		dfdx = (top - top_left + bottom - bottom_left)/(2.0*self.function_values.deltaX)
		dfdy = (top - bottom)/(2.0*self.function_values.deltaY)

		x_new1 = x + 0.5*h*(dfdy)
		y_new1 = y + 0.5*h*(-dfdx)
		x_new2 = x + 0.5*h*(-dfdy)
		y_new2 = y + 0.5*h*(dfdx)

		return (x_new1, y_new1, x_new2, y_new2)

# The given point is in-between vertices on the top edge (case J)
class TopEdgeMiddlePointStrategy(Strategy):
	def __init__(self, function_data):
		Strategy.__init__(self, function_data)
		self.strategyName = "Top Edge Middle Point Strategy"

	def determineVertecies(self, x, y):
		left_vertex = 0
		while self.function_values.x[left_vertex] < x:
			left_vertex += 1
		right_vertex = left_vertex
		left_vertex -= 1

		top_vertex = -1
		bottom_vertex = -2

		left = self.function_values.data[left_vertex][top_vertex]
		bottom_left = self.function_values.data[left_vertex][bottom_vertex]
		right = self.function_values.data[right_vertex][top_vertex]
		bottom_right = self.function_values.data[right_vertex][bottom_vertex]

		return (left, bottom_left, right, bottom_right)

	def findValue(self, h, x, y):
		(left, bottom_left, right, bottom_right) = self.determineVertecies(x,y)

		dfdx = (left - right)/(2.0*self.function_values.deltaX)
		dfdy = (left - bottom_left + right - bottom_right)/(2.0*self.function_values.deltaY)

		x_new1 = x + 0.5*h*(dfdy)
		y_new1 = y + 0.5*h*(-dfdx)
		x_new2 = x + 0.5*h*(-dfdy)
		y_new2 = y + 0.5*h*(dfdx)

		return (x_new1, y_new1, x_new2, y_new2)

# The given point is in-between vertices on a horizontal edge
# (not in middle of 4 vertices) (case K)
class HorizontalVertexMiddlePointStrategy(Strategy):
	def __init__(self, function_data):
		Strategy.__init__(self, function_data)
		self.strategyName = "Horizontal Vertex Middle Point Strategy"

	def determineVertecies(self, x, y):
		left_vertex = 0
		while self.function_values.x[left_vertex] < x:
			left_vertex += 1
		right_vertex = left_vertex
		left_vertex -= 1

		center_vertex = 0
		while self.function_values.y[center_vertex] != y:
			center_vertex += 1
		bottom_vertex = center_vertex - 1
		top_vertex = center_vertex + 1

		top_left = self.function_values.data[left_vertex][top_vertex]
		left = self.function_values.data[left_vertex][center_vertex]
		bottom_left = self.function_values.data[left_vertex][bottom_vertex]
		top_right = self.function_values.data[right_vertex][top_vertex]
		right = self.function_values.data[right_vertex][center_vertex]
		bottom_right = self.function_values.data[right_vertex][bottom_vertex]

		return (top_left, left, bottom_left, top_right, right, bottom_right)

	def findValue(self, h, x, y):
		(top_left, left, bottom_left, top_right, right, bottom_right) = self.determineVertecies(x,y)

		dfdx = (right - left)/(2.0*self.function_values.deltaX)
		dfdy = (top_left - bottom_left + top_right - bottom_right)/(4.0*self.function_values.deltaY)

		x_new1 = x + 0.5*h*(dfdy)
		y_new1 = y + 0.5*h*(-dfdx)
		x_new2 = x + 0.5*h*(-dfdy)
		y_new2 = y + 0.5*h*(dfdx)

		return (x_new1, y_new1, x_new2, y_new2)

# The given point is in-between vertices on a horizontal edge
# (not in middle of 4 vertices) (case L)
class VerticalVertexMiddlePointStrategy(Strategy):
	def __init__(self, function_data):
		Strategy.__init__(self, function_data)
		self.strategyName = "Vertical Vertex Middle Point Strategy"

	def determineVertecies(self, x, y):
		center_vertex = 0
		while self.function_values.x[center_vertex] != x:
			center_vertex += 1
		left_vertex = center_vertex - 1
		right_vertex = center_vertex + 1

		bottom_vertex = 0
		while self.function_values.y[bottom_vertex] < y:
			bottom_vertex += 1
		top_vertex = bottom_vertex
		bottom_vertex -= 1

		top_left = self.function_values.data[left_vertex][top_vertex]
		bottom_left = self.function_values.data[left_vertex][bottom_vertex]
		top = self.function_values.data[center_vertex][top_vertex]
		bottom = self.function_values.data[center_vertex][bottom_vertex]
		top_right = self.function_values.data[right_vertex][top_vertex]
		bottom_right = self.function_values.data[right_vertex][bottom_vertex]

		return (top_left, bottom_left, top, bottom, top_right, bottom_right)

	def findValue(self, h, x, y):
		(top_left, bottom_left, top, bottom, top_right, bottom_right) = self.determineVertecies(x,y)

		dfdx = (top_right - top_left + bottom_right - bottom_left)/(4.0*self.function_values.deltaX)
		dfdy = (top - bottom)/(2.0*self.function_values.deltaY)

		x_new1 = x + 0.5*h*(dfdy)
		y_new1 = y + 0.5*h*(-dfdx)
		x_new2 = x + 0.5*h*(-dfdy)
		y_new2 = y + 0.5*h*(dfdx)

		return (x_new1, y_new1, x_new2, y_new2)

# Read in the data from the given file
class FunctionData:
	def readDataFromFile(self, filename):
		data_file = open(filename, "r")
		data_string = data_file.readlines()
		self.data_length = len(data_string)-1

		self.x = []
		self.y = []
		self.f = []
		self.data = [[0]* (int) (math.sqrt(self.data_length)) for _ in xrange((int) (math.sqrt(self.data_length)))]

		for i in range(1, len(data_string)):
			temp_string = data_string[i]
			temp_string = temp_string.strip()
			temp_string = temp_string.split(",")

			if float(temp_string[0]) not in self.x:
				self.x.append(float(temp_string[0]))
			if float(temp_string[1]) not in self.y:
				self.y.append(float(temp_string[1]))
			self.f.append(float(temp_string[2]))

		self.deltaX = self.x[1] - self.x[0]
		self.deltaY = self.y[1] - self.y[0]

		for i in range(0, len(self.data)):
			for j in range(0, len(self.data)):
				self.data[i][j] = self.f[i*len(self.data) + j]

		data_file.close()

	def isPointInData(self, x, y):
		if float(x) > max(self.x) or float(x) < min(self.x):
			return False
		if float(y) > max(self.y) or float(y) < min(self.y):
			return False
		return True

	def isPointOnEdge(self, x, y):
		if float(x) == self.x[0] or float(x) == self.x[-1]:
			return True
		if float(y) == self.y[0] or float(y) == self.y[-1]:
			return True
		return False

def testStrategyAssignment(function_data):
	factory = StrategyFactory(function_data)
	strategy1 = factory.getStrategy(1.51,1.51)
	strategy2 = factory.getStrategy(1.5, 1.5)
	strategy3 = factory.getStrategy(1.5, 0.0)
	strategy4 = factory.getStrategy(0.0, 1.5)
	strategy5 = factory.getStrategy(1.9, 1.5)
	strategy6 = factory.getStrategy(1.5, 1.9)
	strategy7 = factory.getStrategy(1.51, 0.0)
	strategy8 = factory.getStrategy(0.0, 1.51)
	strategy9 = factory.getStrategy(1.9, 1.51)
	strategy10 = factory.getStrategy(1.51, 1.9)
	strategy11 = factory.getStrategy(1.51, 1.5)
	strategy12 = factory.getStrategy(1.5, 1.51)

	if strategy1.getStrategyName() != "Middle Point Strategy":
		print("(1.51, 1.51) should have a Middle Point Strategy")

	if strategy2.getStrategyName() != "Vertex Strategy":
		print("(1.5, 1.5) should have a Vertex Strategy")

	if strategy3.getStrategyName() != "Bottom Edge Vertex Strategy":
		print("(1.5, 0) should have a Bottom Edge Vertex Strategy")

	if strategy4.getStrategyName() != "Left Edge Vertex Strategy":
		print("(0, 1.5) should have a Left Edge Vertex Strategy")

	if strategy5.getStrategyName() != "Right Edge Vertex Strategy":
		print("(1.9, 1.5) should have a Right Edge Vertex Strategy")

	if strategy6.getStrategyName() != "Top Edge Vertex Strategy":
		print("(1.5, 1.9) should have a Top Edge Vertex Strategy")

	if strategy7.getStrategyName() != "Bottom Edge Middle Point Strategy":
		print("(1.51, 0) should have a Bottom Edge Middle Point Strategy")

	if strategy8.getStrategyName() != "Left Edge Middle Point Strategy":
		print("(0, 1.51) should have a Left Edge Middle Point Strategy")

	if strategy9.getStrategyName() != "Right Edge Middle Point Strategy":
		print("(1.9, 1.51) should have a Right Edge Middle Point Strategy")

	if strategy10.getStrategyName() != "Top Edge Middle Point Strategy":
		print("(1.51, 1.9) should have a Top Edge Middle Point Strategy")

	if strategy11.getStrategyName() != "Horizontal Vertex Middle Point Strategy":
		print("(1.51, 1.5) should have a Horizontal Vertex Middle Point Strategy")

	if strategy12.getStrategyName() != "Vertical Vertex Middle Point Strategy":
		print("(1.5, 1.51) should have a Vertical Vertex Middle Point Strategy")

def main():
	#x = 0.5
	#y = 0.75
	#h = 0.1
	#print("(x,y) = (" + str(x) + "," + str(y) + ")")
	if len(sys.argv) < 5:
		print("Usage: python level_curves.py filename h x y")
		exit()

	filename = sys.argv[1]
	h = float(sys.argv[2])
	x = float(sys.argv[3])
	y = float(sys.argv[4])

	print("list length = " + str(len(sys.argv)))

	function_data = FunctionData()
	function_data.readDataFromFile(filename)

	testStrategyAssignment(function_data)

	level_curve_solver = LevelCurvesSolver(h, x, y, function_data)
	level_curve_solver.plotLevelCurve()
main()


# YOLOv5 ðŸš€ by Ultralytics, GPL-3.0 license
"""
Run YOLOv5 detection inference on images, videos, directories, globs, YouTube, webcam, streams, etc.

Usage - sources:
    $ python detect.py --weights yolov5s.pt --source 0                               # webcam
                                                     img.jpg                         # image
                                                     vid.mp4                         # video
                                                     screen                          # screenshot
                                                     path/                           # directory
                                                     'path/*.jpg'                    # glob
                                                     'https://youtu.be/Zgi9g1ksQHc'  # YouTube
                                                     'rtsp://example.com/media.mp4'  # RTSP, RTMP, HTTP stream

Usage - formats:
    $ python detect.py --weights yolov5s.pt                 # PyTorch
                                 yolov5s.torchscript        # TorchScript
                                 yolov5s.onnx               # ONNX Runtime or OpenCV DNN with --dnn
                                 yolov5s_openvino_model     # OpenVINO
                                 yolov5s.engine             # TensorRT
                                 yolov5s.mlmodel            # CoreML (macOS-only)
                                 yolov5s_saved_model        # TensorFlow SavedModel
                                 yolov5s.pb                 # TensorFlow GraphDef
                                 yolov5s.tflite             # TensorFlow Lite
                                 yolov5s_edgetpu.tflite     # TensorFlow Edge TPU
                                 yolov5s_paddle_model       # PaddlePaddle
"""

import argparse
import os
import platform
import sys
from pathlib import Path

import torch

FILE = Path(__file__).resolve()
ROOT = FILE.parents[0]  # YOLOv5 root directory
if str(ROOT) not in sys.path:
    sys.path.append(str(ROOT))  # add ROOT to PATH
ROOT = Path(os.path.relpath(ROOT, Path.cwd()))  # relative

from models.common import DetectMultiBackend
from utils.dataloaders import (
    IMG_FORMATS,
    VID_FORMATS,
    LoadImages,
    LoadScreenshots,
    LoadStreams,
)
from utils.general import (
    LOGGER,
    Profile,
    check_file,
    check_img_size,
    check_imshow,
    check_requirements,
    colorstr,
    cv2,
    increment_path,
    non_max_suppression,
    print_args,
    scale_boxes,
    strip_optimizer,
    xyxy2xywh,
)
from utils.plots import Annotator, colors, save_one_box
from utils.torch_utils import select_device, smart_inference_mode

@smart_inference_mode()
def run(
    weights=ROOT / "yolov5s.pt",  # model path or triton URL
    source=ROOT / "data/images",  # file/dir/URL/glob/screen/0(webcam)
    data=ROOT / "data/coco128.yaml",  # dataset.yaml path
    imgsz=(640, 640),  # inference size (height, width)
    conf_thres=0.25,  # confidence threshold
    iou_thres=0.45,  # NMS IOU threshold
    max_det=1000,  # maximum detections per image
    device="",  # cuda device, i.e. 0 or 0,1,2,3 or cpu
    view_img=False,  # show results
    save_txt=False,  # save results to *.txt
    save_conf=False,  # save confidences in --save-txt labels
    save_crop=False,  # save cropped prediction boxes
    nosave=False,  # do not save images/videos
    classes=None,  # filter by class: --class 0, or --class 0 2 3
    agnostic_nms=False,  # class-agnostic NMS
    augment=False,  # augmented inference
    visualize=False,  # visualize features
    update=False,  # update all models
    project=ROOT / "runs/detect",  # save results to project/name
    name="exp",  # save results to project/name
    exist_ok=False,  # existing project/name ok, do not increment
    line_thickness=3,  # bounding box thickness (pixels)
    hide_labels=False,  # hide labels
    hide_conf=False,  # hide confidences
    half=False,  # use FP16 half-precision inference
    dnn=False,  # use OpenCV DNN for ONNX inference
    vid_stride=1,  # video frame-rate stride
):
    source = str(source)
    save_img = not nosave and not source.endswith(".txt")  # save inference images
    is_file = Path(source).suffix[1:] in (IMG_FORMATS + VID_FORMATS)
    is_url = source.lower().startswith(("rtsp://", "rtmp://", "http://", "https://"))
    webcam = source.isnumeric() or source.endswith(".txt") or (is_url and not is_file)
    screenshot = source.lower().startswith("screen")
    if is_url and is_file:
        source = check_file(source)  # download

    # Directories
    save_dir = increment_path(Path(project) / name, exist_ok=exist_ok)  # increment run
    (save_dir / "labels" if save_txt else save_dir).mkdir(
        parents=True, exist_ok=True
    )  # make dir

    # Load model
    device = select_device(device)
    model = torch.load(weights, map_location=torch.device("cpu"))

    # Manual fixes for FasterRCNN model object loaded from weights
    if not str(weights).endswith(".pt"):
        os.rename(
            str(weights), str(weights).replace(os.path.split(str(weights))[-1], ".pt")
        )
        weights = str(weights).replace(os.path.split(str(weights))[-1], ".pt")
    if not isinstance(model, dict):
        model.get = dict.get
        model.names = ["fish_1", "fish_2", "fish_3", "fish_4"]
        model_dict = {"model": model}
        torch.save(model_dict, weights)
    model = DetectMultiBackend(weights, device=device, dnn=dnn, data=data, fp16=half)
    stride, names, pt = model.stride, model.names, model.pt
    imgsz = check_img_size(imgsz, s=stride)  # check image size

    # Dataloader
    bs = 1  # batch_size
    if webcam:
        view_img = check_imshow(warn=True)
        dataset = LoadStreams(
            source, img_size=imgsz, stride=stride, auto=pt, vid_stride=vid_stride
        )
        bs = len(dataset)
    elif screenshot:
        dataset = LoadScreenshots(source, img_size=imgsz, stride=stride, auto=pt)
    else:
        dataset = LoadImages(
            source, img_size=imgsz, stride=stride, auto=pt, vid_stride=vid_stride
        )
    vid_path, vid_writer = [None] * bs, [None] * bs

    # Run inference
    model.warmup(imgsz=(1 if pt or model.triton else bs, 3, *imgsz))  # warmup
    seen, windows, dt = 0, [], (Profile(), Profile(), Profile())
    c = 0
    for path, im, im0s, vid_cap, s in dataset:
        c += 1
        with dt[0]:
            im = torch.from_numpy(im).to(model.device)
            im = im.half() if model.fp16 else im.float()  # uint8 to fp16/32
            im /= 255  # 0 - 255 to 0.0 - 1.0
            if len(im.shape) == 3:
                im = im[None]  # expand for batch dim

        # Inference
        with dt[1]:
            visualize = (
                increment_path(save_dir / Path(path).stem, mkdir=True)
                if visualize
                else False
            )
            pred = model(im, augment=augment, visualize=visualize)

            pred = {
                "boxes": pred["boxes"].detach().cpu(),
                "labels": pred["labels"].cpu(),
                "scores": pred["scores"].detach().cpu(),
            }

            # targets = {
            #    'boxes': targets[0]['boxes'].detach().cpu(),
            #    'labels': targets[0]['labels'].cpu(),
            # }

        # NMS
        with dt[2]:

            from torchvision.ops import box_iou, batched_nms
            from collections import Counter
            import numpy as np
            from PIL import Image

            def apply_mns(results, applyAll=False, iou_thresh=0.3):
                """
                Returns the tensors after applying mns on the boxes and classifications.
                :param applyAll: boolean indicate whether to apply all
                :param iou_thresh: The iou threshold for the nms
                :param results: results\targets object
                """
                results_scores = results["scores"]
                results_boxes = results["boxes"]
                results_labels = results["labels"]

                results_labels_modify = (
                    results_labels
                    if not applyAll
                    else torch.zeros(len(results_boxes), dtype=torch.int32)
                )

                mns_ind = batched_nms(
                    results_boxes, results_scores, results_labels_modify, iou_thresh
                )
                labels_filtered = results_labels[mns_ind]
                scores_filtered = results_scores[mns_ind]
                boxes_filtered = results_boxes[mns_ind]

                return {
                    "boxes": boxes_filtered,
                    "labels": labels_filtered,
                    "scores": scores_filtered,
                }

            def add_bounding_boxes(
                img,
                pred_cls,
                boxes,
                pred_score=None,
                thresh=0.35,
                rect_th=2,
                text_size=0.5,
                text_th=1,
                color_box=(1, 1, 1),
                return_pil=True,
            ):
                """
                Returns the image with boxes and labels as PIL
                :param thresh:
                :param img: The image
                :param pred_cls: Array of classes (as numbers)
                :param pred_score: array of probabilities
                :param boxes: Array of boxes
                :param rect_th: thickness of the rectangle
                :param text_size: Text size
                :param text_th: thickness of the text
                :param color_box: Box and text color
                :param return_pil: Boolean indicate whether to return a pil
                :return: Returns the image with boxes and labels as PIL
                """
                # turn classification tensors to numpy
                pred_cls = pred_cls.numpy()

                if pred_score is not None:
                    pred_score = pred_score.numpy()

                for i in range(len(boxes)):
                    if pred_score is not None and pred_score[i] < thresh:
                        continue
                    cv2.rectangle(
                        img,
                        (int(boxes[i][0]), int(boxes[i][1])),
                        (int(boxes[i][2]), int(boxes[i][3])),
                        color=color_box,
                        thickness=rect_th,
                    )
                    print_text = f"fish{pred_cls[i]}"
                    print_text = (
                        print_text
                        if pred_score is None
                        else print_text + ":{}".format(str(round(pred_score[i], 3)))
                    )
                    cv2.putText(
                        img,
                        print_text,
                        (int(boxes[i][0] + rect_th), int(boxes[i][1]) + 20),
                        cv2.FONT_HERSHEY_SIMPLEX,
                        text_size,
                        color_box,
                        thickness=text_th,
                    )

                # turn to PIL
                if return_pil:
                    return Image.fromarray((img * 255).astype(np.uint8))
                else:
                    return (img * 255).astype(np.uint8)

                return

            # apply NMS on prediction
            pred = apply_mns(pred, iou_thres)
            pred = apply_mns(pred, applyAll=True, iou_thresh=0.8)

            # Update mAp
            # metric.update([pred], [targets])

            # Update IOU
            # iou = box_iou(targets['boxes'].cpu(), pred['boxes'].cpu())

            # max_iou = torch.max(iou, dim=1).values if iou.shape[1] != 0 else torch.Tensor([0])
            # total_iou += torch.mean(max_iou)

            # len_targets = len(targets['boxes'].cpu())

            # if the shape of the iou is zero then it means that the model didn't predict nothing
            # so we need to ignore these cases
            # no_boxes_predicted = iou.shape[1] != 0

            # if no_boxes_predicted and len_targets != 0:
            #    # Calculate miss classification - counting the number of IOU less than 0.3
            #    miss_detections_rate += 0 if len_targets == 0\
            #        else torch.count_nonzero(max_iou < 0.3) / len_targets

            # false_positive_classification
            #    matching_index_iou = torch.argmax(iou, dim=1)
            #    count_miss_class = np.count_nonzero(targets['labels'] != pred['labels'][matching_index_iou])
            #    false_positive_classification += count_miss_class / len_targets

            # log images here

        for i in range(len(dataset)):
            if webcam:  # batch_size >= 1
                p, im0, frame = (
                    path[i],
                    im.squeeze(0).numpy().transpose(1, 2, 0).copy(),
                    dataset.count,
                )
                s += f'{dict(Counter(pred["labels"].cpu().numpy()))}:'
            else:
                p, im0, frame = (
                    path,
                    im.squeeze(0).numpy().transpose(1, 2, 0).copy(),
                    getattr(dataset, "frame", 0),
                )
            # .cpu().numpy()
            # image_to_log = im0.transpose(1, 2, 0)
            proc_img = cv2.cvtColor(im0, cv2.COLOR_BGR2RGB)

            proc_img = add_bounding_boxes(
                proc_img,
                pred["labels"],
                pred["boxes"],
                pred_score=pred["scores"],
                color_box=(1, 1, 1),
                thresh=0.001,
                return_pil=False,
            )
            # image_to_log.save(os.path.join(output_path, "test_" + dataset_test.get_image_name(cur_index)))

            # print("Average IOU all over the images: {}".format(total_iou / len(data_loader_test)))
            # print("Average miss classification all over the images: {}".format(false_positive_classification / len(data_loader_test)))
            # print("Average miss detection all over the images: {}".format(miss_detections_rate / len(data_loader_test)))
            # print("mAP score over all test images:{}".format(metric.compute()))

            # Save results (image with detections)
            p = Path(p)  # to Path
            save_path = str(save_dir / p.name.split(".")[0])  # im.jpg
            txt_path = str(save_dir / "labels" / p.stem) + (
                "" if dataset.mode == "image" else f"_{frame}"
            )  # im.txt
            gn = torch.tensor(im0.shape)[[1, 0, 1, 0]]  # normalization gain whwh
            if True:
                if dataset.mode == "image":
                    cv2.imwrite(save_path, proc_img)
                else:  # 'video' or 'stream'
                    if vid_path[i] != save_path:  # new video
                        vid_path[i] = save_path
                        if isinstance(vid_writer[i], cv2.VideoWriter):
                            vid_writer[i].release()  # release previous video writer
                        if vid_cap:  # video
                            fps = vid_cap.get(cv2.CAP_PROP_FPS)
                            w = int(vid_cap.get(cv2.CAP_PROP_FRAME_WIDTH))
                            h = int(vid_cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
                        else:  # stream
                            fps, w, h = 30, im0.shape[1], im0.shape[0]
                        save_path = str(
                            Path(save_path).with_suffix(".mp4")
                        )  # force *.mp4 suffix on results videos
                        vid_writer[i] = cv2.VideoWriter(
                            save_path, cv2.VideoWriter_fourcc(*"mp4v"), fps, (w, h)
                        )
                    vid_writer[i].write(proc_img)

                # Write results
                for *xyxy, conf, cls in zip(
                    pred["boxes"], pred["scores"], pred["labels"]
                ):
                    if save_txt:
                        # Write to file
                        xywh = (
                            (xyxy2xywh(torch.tensor(xyxy[0]).view(1, 4)) / gn)
                            .view(-1)
                            .tolist()
                        )  # normalized xywh
                        line = (
                            (cls, *xywh, conf) if save_conf else (cls, *xywh)
                        )  # label format
                        with open(f"{txt_path}.txt", "a") as f:
                            f.write(("%g " * len(line)).rstrip() % line + "\n")

        # Print time (inference-only)
        LOGGER.info(
            f"{s}{'' if len(pred['boxes']) else '(no detections), '}{dt[1].dt * 1E3:.1f}ms"
        )
        if c == 10:
            break

    # Print results
    t = tuple(x.t / c * 1e3 for x in dt)  # speeds per image
    LOGGER.info(
        f"Speed: %.1fms pre-process, %.1fms inference, %.1fms NMS per image at shape {(1, 3, *imgsz)}"
        % t
    )
    if save_txt or save_img:
        s = (
            f"\n{len(list(save_dir.glob('labels/*.txt')))} labels saved to {save_dir / 'labels'}"
            if save_txt
            else ""
        )
        LOGGER.info(f"Results saved to {colorstr('bold', save_dir)}{s}")
    if update:
        strip_optimizer(weights[0])  # update model (to fix SourceChangeWarning)

def parse_opt():
    parser = argparse.ArgumentParser()
    parser.add_argument(
        "--weights",
        nargs="+",
        type=str,
        default=ROOT / "yolov5s.pt",
        help="model path or triton URL",
    )
    parser.add_argument(
        "--source",
        type=str,
        default=ROOT / "data/images",
        help="file/dir/URL/glob/screen/0(webcam)",
    )
    parser.add_argument(
        "--data",
        type=str,
        default=ROOT / "data/coco128.yaml",
        help="(optional) dataset.yaml path",
    )
    parser.add_argument(
        "--imgsz",
        "--img",
        "--img-size",
        nargs="+",
        type=int,
        default=[640],
        help="inference size h,w",
    )
    parser.add_argument(
        "--conf-thres", type=float, default=0.25, help="confidence threshold"
    )
    parser.add_argument(
        "--iou-thres", type=float, default=0.45, help="NMS IoU threshold"
    )
    parser.add_argument(
        "--max-det", type=int, default=1000, help="maximum detections per image"
    )
    parser.add_argument(
        "--device", default="", help="cuda device, i.e. 0 or 0,1,2,3 or cpu"
    )
    parser.add_argument("--view-img", action="store_true", help="show results")
    parser.add_argument("--save-txt", action="store_true", help="save results to *.txt")
    parser.add_argument(
        "--save-conf", action="store_true", help="save confidences in --save-txt labels"
    )
    parser.add_argument(
        "--save-crop", action="store_true", help="save cropped prediction boxes"
    )
    parser.add_argument(
        "--nosave", action="store_true", help="do not save images/videos"
    )
    parser.add_argument(
        "--classes",
        nargs="+",
        type=int,
        help="filter by class: --classes 0, or --classes 0 2 3",
    )
    parser.add_argument(
        "--agnostic-nms", action="store_true", help="class-agnostic NMS"
    )
    parser.add_argument("--augment", action="store_true", help="augmented inference")
    parser.add_argument("--visualize", action="store_true", help="visualize features")
    parser.add_argument("--update", action="store_true", help="update all models")
    parser.add_argument(
        "--project", default=ROOT / "runs/detect", help="save results to project/name"
    )
    parser.add_argument("--name", default="exp", help="save results to project/name")
    parser.add_argument(
        "--exist-ok",
        action="store_true",
        help="existing project/name ok, do not increment",
    )
    parser.add_argument(
        "--line-thickness", default=3, type=int, help="bounding box thickness (pixels)"
    )
    parser.add_argument(
        "--hide-labels", default=False, action="store_true", help="hide labels"
    )
    parser.add_argument(
        "--hide-conf", default=False, action="store_true", help="hide confidences"
    )
    parser.add_argument(
        "--half", action="store_true", help="use FP16 half-precision inference"
    )
    parser.add_argument(
        "--dnn", action="store_true", help="use OpenCV DNN for ONNX inference"
    )
    parser.add_argument(
        "--vid-stride", type=int, default=1, help="video frame-rate stride"
    )
    opt = parser.parse_args()
    opt.imgsz *= 2 if len(opt.imgsz) == 1 else 1  # expand
    print_args(vars(opt))
    return opt

def main(opt):
    check_requirements(exclude=("tensorboard", "thop"))
    run(**vars(opt))

if __name__ == "__main__":
    opt = parse_opt()
    main(opt)


import logging
from random import random, choice, seed, randrange
from defined_media.models import Compounds

log=logging.getLogger(__name__)

class MockPostDict(dict):
    def __init__(self, mn0, seeder=None):
        '''
        Mock up the MediaNames POST dict.
        Entries: "compN" -> compound name
                 "amountN" -> float (in string form)
        initialize from mn0
        '''
        if seeder is not None: seed(seeder)

        for field in 'media_name is_defined is_minimal'.split(' '):
            self[field]=getattr(mn0, field)

        for i,mc in enumerate(mn0.mediacompounds_set.all()):
            compkey='comp%d' % i
            self[compkey]=mc.compid.name
            amtkey='amount%d' % i
            self[amtkey]=mc.amount_mm

    def random_changes(self, n_changes):
        ''' change some random entries; return a list of amtkey '''
        changed=[]
        n=len(self)/2
        for i in range(n_changes):
            k=randrange(n)
            amtkey='amount%d' % k
            self[amtkey]=2*self[amtkey]*random()
            changed.append(('comp%d'%k,amtkey))
        return changed

    def random_delete(self, n_del):
        ''' delete some random entries '''
        deleted=[]
        for i in range(n_del):
            compkey=choice(self.compkeys())
            amtkey=self.amountkey_for(compkey)
            del self[compkey]
            del self[amtkey]
            deleted.append((compkey, amtkey))
        return deleted

    def random_add(self, n_add):
        ''' add some random entries '''
        added=[]
        for i in range(n_add):
            n=len(self)
            compid=randrange(Compounds.objects.count())
            comp=Compounds.objects.get(compid=compid)
            self['comp%d'%n]=comp.name
            self['amount%d'%n]=random()*10
            added.append(('comp%d'%n, 'amount%d'%n))
        return added

    def compkeys(self):
        return [k for k in self.keys() if k.startswith('comp')]

    def comp_from_compkey(self, compkey):
        return Compounds.objects.with_name(self[compkey])

    def amountkey_for(self, compkey):
        return 'amount%d' % int(compkey.split('comp')[1]) # using int() in insure assumption

    def amount_for(self, compkey):
        return self[self.amountkey_for(compkey)]


# import bs4 여기에서 일부만 필요하니까 다 가져오지 말자
import requests
url = 'https://www.naver.com'
recvd = requests.get(url)
#print(recvd)   #접근결과코드 : 200(성공)
#print(recvd.text)   #html코드
#print(recvd.encoding)   #인코딩 방식
#print(recvd.headers)
#print(recvd.content)

from bs5 import BeautifulSoup
# 웹페이지에 접근하여 태그 인식
f = open('data\\test.html', encoding='utf-8').read()
# print(f)
# BeautifulSoup(웹페이지, 파싱방식)
# 파싱 : html.paser, html5lib, lxml(태그 계층 구조를 인식하는 것)
# dom = BeautifulSoup(f, 'html.parser')   #body태그 안닫힌 문서도 태그 인식해서 채워준다
dom = BeautifulSoup(f, 'lxml')  # html.parser에 xml 포함. 속도 빠름
# print(dom)

# dom.find('태그')  # 첫번째 태그추출
# = dom.태그
# dom.find_all('태그') # 모든 태그 추출
# div = dom.find('div') 얘랑
# div = dom.div         # 얘랑 동일
# print(div)  # 첫번째 div 태그만 가져옴
# div = dom.find_all('div')
# print(div)  #[div1, div2,...]
# --------------------------------------

firstDiv = dom.div
div2 = firstDiv.div
# print(div2)
ps = div2.find_all('p')

# dom.find('태그', class_='클래스명')   # class_ : 예약어 피하기 위해서
# dom.find('태그', {'class': '클래스명'})
# cl = dom.find('div', class_='ex_class')   #아래와 동일
# print(cl)
# cl = dom.find(class_='ex_class')
# print(cl)

# dom.find_all(class_='클래스명')
# exs = dom.find_all('class_='ex_class')
# print(exs)
# sisters = dom.find_all(class_='sister')
# print(sisters)

# id가 third인 태그
third = dom.find(id='third')
#print(type(third))

# id가 third인 모든 태그
thirds = dom.find_all(id="third")
print(thirds[0])
print(type(thirds))

# import, main()


import os
import vlc
import time
import random

class Player:
    def __init__(self):
        self.Instance = vlc.Instance()
        self.player = self.Instance.media_player_new()
        self.MediaList = self.Instance.media_list_new()
        self.MediaListPlayer = self.Instance.media_list_player_new()
        self.MediaListPlayer.set_media_list(self.MediaList)
        self.MediaListPlayer.set_media_player(self.player)

        self.play_list = []  # Initialize empty queue
        self.original_play_list = []  # For storing the initial playlist when shuffle is disabled
        self.index = 0
        self.is_shuffle_enabled = False
        self.is_paused = False
        self.is_playing = False
        self.current_volume = 50

        self.current_song = "No song playing"
        self.current_time = "0:00"
        self.current_length = "0:00"

    def add_song(self, song_path):
        """
        Adds a single song to the end of the queue
        """
        if song_path.endswith('.mp3'):
            self.play_list.append(song_path)
            self.original_play_list.append(song_path)
            print(f"Added {song_path} to the queue")
        else:
            print(f"Invalid file format: {song_path}")

    def add_playlist(self, folder_path):
        """
        Adds all songs in the given folder to the end of the queue
        """
        playlist = [os.path.join(folder_path, f) for f in os.listdir(folder_path) if f.endswith('.mp3')]
        self.play_list.extend(playlist)
        self.original_play_list.extend(playlist)
        print(f"Added {len(playlist)} songs from {folder_path} to the queue")

    def start(self):
        if not self.is_playing:
            self.is_playing = True
            self.set_volume(self.current_volume)
            self.play()
            print("Music Started")
        else:
            print("Music already playing")

    def play(self):
        if not self.play_list:
            print("No songs to play!")
            return

        self.current_song = os.path.basename(self.play_list[self.index])
        self.player.set_media(vlc.Media(self.play_list[self.index]))
        self.player.play()
        print(f"Playing: {self.current_song}")

    def get_current_time(self):
        """
        Updates and returns the current play time of the song and the total length
        in the format 0:47/2:38
        """
        time = self.player.get_time()  # Get time in milliseconds
        mins, sec = divmod(time // 1000, 60)  # Convert to minutes and seconds
        self.current_time = f"{mins}:{sec:02}"

        length = self.player.get_length()
        mins, sec = divmod(length // 1000, 60)  # Convert to minutes and seconds
        self.current_length = f"{mins}:{sec:02}"

        return f"{self.current_time}/{self.current_length}"

    def resume(self):
        if self.is_paused:
            self.player.play()
            print("Resumed")
            self.is_paused = False
        else:
            print("Nothing to resume")

    def pause(self):
        self.player.pause()
        print("Paused")
        self.is_paused = True

    def skip(self):
        self.index += 1
        if self.index >= len(self.play_list):
            self.index = 0
        self.current_song = os.path.basename(self.play_list[self.index])
        self.player.set_media(vlc.Media(self.play_list[self.index]))
        self.player.play()
        print("Skipped to the next track")

    def stop(self):
        self.player.stop()
        print("Music Stopped")
        self.is_playing = False

    def set_volume(self, volume_level):
        volume = max(0, min(100, volume_level))
        self.current_volume = int(volume)
        self.player.audio_set_volume(self.current_volume)

    def enable_shuffle(self):
        random.shuffle(self.play_list)
        self.is_shuffle_enabled = True
        print("Shuffle enabled")

    def disable_shuffle(self):
        self.play_list = self.original_play_list.copy()
        self.is_shuffle_enabled = False
        print("Shuffle disabled")

    def toggle_shuffle(self):
        if self.is_shuffle_enabled:
            self.disable_shuffle()
        else:
            self.enable_shuffle()


from fabric.api import local, settings, abort, run, cd, env

env.hosts = ['52.10.173.250']
env.user = 'ec2-user'
env.key_filename = '/Users/anirudh/Documents/Python-Projects/Results/key.pem'

def prepare_deploy(message='fab push'):
    local('git add . && git commit'+" -m '"+message+"'")
    local('git push')

def deploy():
    code_dir = '/var/www/html/MSRIT-Results/'
    with cd(code_dir):
        run('sudo git pull')
        with cd(code_dir+'results'):
            run('sudo touch wsgi.py')


from flask import Flask, render_template, request, redirect, url_for
from sklearn.externals import joblib

app = Flask(__name__)

flo = joblib.load("/home/analizer/mysite/flower.pkl" , mmap_mode ='r')

@app.route('/',methods=["POST","GET"])

def pred():
    if request.method=="POST":
        f1=request.form["fname"]
        print(f1)
        f0=list(f1.split(','))
        f01= [f0]
        predict=flo.predict_proba(f01)
        for i in predict:
            if i[0]==1:
                result= 'setosa'
            if i[1]==1:
                result= 'versicolor'
            if i[2]==1:
                result= 'virginica'
        print(result)
        return redirect(url_for("user",usr=result))
    else:
        return render_template("pred.html")

@app.errorhandler(500) # Server error
def error1(error):
   return render_template('500.html'), 500

@app.route("/<usr>")
def user(usr):
    return f"<h1>{usr}</h1>"


#coding=utf-8
import json
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
obj = {'content':"测试内容",'stars':5}
array = []
for i in range(5):
	temp = obj.copy()
	temp['content'] = "测试内容" + str(i)
	temp['stars'] = i;
	array.append(temp.copy())
filecontent = {'name':"jwkuang",'date':20150825,'content':array}
encodedjson = json.dumps(filecontent)
filename = "20150825jwkuang.json"
fileobj = open(filename,"w+")
fileobj.write(encodedjson)


from collections import Counter
import string
import math

def array_int():

    return [int(i) for i in input().split()]
def vary(number_of_variables):
    if number_of_variables==1:
        return int(input())
    if number_of_variables>=2:
        return map(int,input().split())
def makedict(var):
    return dict(Counter(var))
mod=1000000007
m,n=vary(2)
mat=[]
for i in range(m):
    mat.append(array_int())
pat=[]
for i in range(m):
    pat.append([int(-2) for j in range(n)])
for i in range(m):
    for j in range(n):
        if mat[i][j]==0:
            for k in range(n):
                pat[i][k]=0
            for k in range(m):
                pat[k][j]=0
for i in range(m):
    for j in range(n):
        if pat[i][j]==-2:
            pat[i][j]=1

""" for i in range(m):
    print(*pat[i]) """
cat=[]
for i in range(m):
    cat.append([0 for j in range(n)])
for i in range(m):
    for j in range(n):
        for k in range(n):
            if pat[i][k]==1:
                cat[i][j]=1

        for k in range(m):
            if pat[k][j]==1:
                cat[i][j]=1
""" print(cat)
print(mat)
print(pat) """
if cat==mat:
    print('YES')
    for i in range(m):
        print(*pat[i])
else:
    print('NO')


import csv
import json
import requests
import pandas as pd
import random

from firebase_admin import credentials, firestore, initialize_app

cred = credentials.Certificate('./firebase-private.json')
default_app = initialize_app(cred)
db = firestore.client()
itemService = db.collection('items')

# Specify the path to your CSV file
csv_file = '/Users/sarthakrawat/PythonProjects/hackathon/gpt-jam-backend/DataLoadScript/FoodNames.csv'

index = 0

df = pd.read_csv(csv_file)

id = 1

for index, row in df.iterrows():
    # Read the values from the DataFrame row
    food_item = row['FoodItem']
    food_category = row['FoodCategory']
    image_url = row['Image']

    # Create a dictionary for the JSON object
    json_obj = {
        "itemId": "itm"+str(id).zfill(6),
        "name": food_item,
        "description": food_item + " - " + food_category,
        "tags": [food_item.lower(),food_category.lower()],
        "rating": random.randint(3, 5),
        "price": random.randint(3, 8)+0.99,
        "image": image_url
    }
    item_id = json_obj["itemId"]
    # json_string = json.dumps(json_obj)
    itemService.document(item_id).set(json_obj)
    id += 1


#Created by :- AJI
#Created Date :- 24-08-2020

# Standard Library
import requests
import sqlite3
import datetime
import pytz
import json

#User Defined Library
from .configurations import Emergency_Exit_url,TIME_ZONE
from .Log.log import get_logger
from .Messages import error_log , info_log
from .DB_Access import InsertDetail,database_search,RemoveDetails
from .Constant import Const_trueflag,Const_falseflag,Const_check_flag,Emergency_exit_API_Response
from Firmware.WiFi_Network import DeviceName
from .Bluetooth import baseurl_read

app_logger = get_logger("Emergency Exit")

"""

This function inform the server that the Emergency Exit button is pressed

"""
def Emergency_exit(current_time):
	DEVICE_ID=DeviceName()
	data = {"DeviceCode":DEVICE_ID,"AccessTime":current_time}
	url = baseurl_read(Emergency_Exit_url)
	results = requests.post(url, data = data)
	response_message = results.text
	app_logger.info(response_message)
	Response = json.loads(response_message)
	if(Response["Message"] == Emergency_exit_API_Response):
		app_logger.info(info_log["e26"])
	else:
		Emergency_Exit_update_query = """INSERT INTO EmergencyExit(EmergencyExitTime,SynchronizedStatus) VALUES (?,?)"""
		Emergency_Exit_data = (current_time,0)
		print(Emergency_Exit_data)
		InsertDetail(Emergency_Exit_update_query,Emergency_Exit_data)
		app_logger.info(info_log["e27"])

"""

This function Synchronize the Emergency Exit table with the server Database

"""
def Synchronize_Emergency_exit_data():
	Emergency_exit_sync = """ SELECT EmergencyExitId,EmergencyExitTime FROM EmergencyExit Where SynchronizedStatus = 0 """
	Search_Response = database_search(Emergency_exit_sync)
	Synchronization_list = [Sync_item for item in Search_Response for Sync_item in item]
	Sync_flag = Const_falseflag
	for Synchronization_data in Synchronization_list:
		if((Sync_flag % Const_check_flag) != Const_falseflag):

			Emergency_exit(Synchronization_data)
			Sync_flag = Sync_flag + Const_trueflag
		else:
			data = (Synchronization_data, )
			Remove_data = """DELETE FROM EmergencyExit WHERE EmergencyExitId = ?"""
			RemoveDetails(Remove_data ,data)
			Sync_flag = Sync_flag + Const_trueflag


from typing import List, Dict
import os.path
import sys

from  aimslib.access.cache import TripCache, CrewlistCache
from aimslib.common.types import Duty, NoTripDetails, CrewMember
import aimslib.access.brief_roster as Roster

CACHE_DIR = os.path.expanduser("~/.cache/")

def duties(post_func, months: int) -> List[Duty]:
    sparse_dutylist = []
    if months < 0: months += 1
    else: months -= 1
    for r in Roster.retrieve(post_func, months):
        sparse_dutylist.extend(Roster.duties(Roster.parse(r)))
    expanded_dutylist = []
    trip_cache = TripCache(CACHE_DIR + "aimslib.tripcache", post_func)
    last_id = None
    for duty in sorted(sparse_dutylist):
        if duty.trip_id == last_id: continue #avoid duplicates
        last_id = duty.trip_id
        if duty.start is None:
            try:
                expanded_dutylist.extend(trip_cache.trip(duty.trip_id))
            except NoTripDetails:
                print(f"Trip details not found for: {duty.trip_id}",
                      file=sys.stderr)
        else:
            expanded_dutylist.append(duty)
    trip_cache.store()
    return expanded_dutylist

def crew(post_func, dutylist: List[Duty]) -> Dict[str, List[CrewMember]]:
    crew_cache = CrewlistCache(CACHE_DIR + "aimslib.clcache", post_func)
    crewlist_map = {}
    for duty in dutylist:
        if duty.sectors:
            for sector in duty.sectors:
                if not sector.crewlist_id: continue
                crewlist = crew_cache.crewlist(sector.crewlist_id)
                crewlist_map[sector.crewlist_id] = crewlist
    crew_cache.store()
    return crewlist_map


# -*- coding: utf-8 -*-
import jieba
import codecs
from gensim import corpora
from gensim.summarization import bm25
import os
import re
import json
import multiprocessing as mp
import time
from functools import partial

"""
需要以下几个东西：

1. Query list and Query list index to QueryID and vice versa
2. Document list and Document list index to DocumentID and vice versa
3. 完成 bm25 之后，
4.
"""

def getQList_Qmap(input_json):
    """
    :param input_json:
    :return: query list, Listindex2ID and ID2Listindex
    """
    query_list = []
    ql_ind2id = {}
    id2ql_ind = {}

    instances = input_json['questions']
    for ind, instance in enumerate(instances):
        context = instance['context']
        ID = instance['ID']
        query_list.append(context)
        ql_ind2id[ind] = ID
        id2ql_ind[ID] = ind

    return query_list, ql_ind2id, id2ql_ind

def getDlist_Dmap(input_json):
    """
    :param input_json:
    :return: doc list, Listindex2ID and ID2Listindex
    """
    doc_list = []
    dl_ind2id = {}
    id2dl_ind = {}

    instances = input_json['document']
    for ind, instance in enumerate(instances):
        context = instance['context']
        ID = instance['ID']
        doc_list.append(context)
        dl_ind2id[ind] = ID
        id2dl_ind[ID] = ind

    return doc_list, dl_ind2id, id2dl_ind

def split_str(input_str, stop_word_l):
    split_words = jieba.cut(input_str, HMM=True)
    res = list(filter(lambda x: x not in stop_word_l, split_words))
    return res

def tokenization(input_l, stop_word_l):
    res = [split_str(input_str, stop_word_l) for input_str in input_l]
    return res

def get_bm_score(q, bm_model):
    return bm_model.get_scores(q)

def get_score_list(bm_model, query_list, multi_proc):
    if multi_proc:
        partial_work = partial(get_bm_score, bm_model=bm_model)
        pool = mp.Pool()
        scores = pool.map(partial_work, query_list)
    else:
        scores = []
        for query in query_list:
            scores.append(get_bm_score(query, bm_model))
    return scores

def evaluate_res(evaluation_map):
    total_n = len(evaluation_map)
    evaluation_iters = evaluation_map.items()
    print(total_n)
    print(evaluation_iters)
    corrects = sum(any(ele in k for ele in v) for k, v in evaluation_iters)
    acc = corrects/total_n
    return acc

# if __name__ == '__main__':
#     # get stop words from pretrained file
#     stop_word_file = 'stop_words.txt'
#     stop_word_l = []
#     with codecs.open(stop_word_file, 'r', 'utf-8') as f:
#         for line in f:
#             stop_word_l.append(line.rstrip('\n'))
#
#     input_file = os.path.join(os.getcwd(), 'tf_idf_cluster.json')
#     with codecs.open(input_file, 'r', 'utf-8') as file:
#         input_json = json.load(file)
#
#     # get Q_list, D_list and their corresponding mappings
#     Q_list, Qindex2ID, ID2Qindex = getQList_Qmap(input_json)
#     D_list, Dindex2ID, ID2Dindex = getDlist_Dmap(input_json)
#
#     # Tokenization the lists
#     Q_list = tokenization(Q_list, stop_word_l)
#     D_list = tokenization(D_list, stop_word_l)
#     # print(D_list[:5])
#     # print(Q_list[:5])
#
#     # get document dictionary
#     dictionary = corpora.Dictionary(D_list)
#     # print(len(dictionary))
#
#     # bm25 calculation
#     bm25Model = bm25.BM25(D_list)
#     sample_questions = Q_list[:]
#
#     # multiprocessing
#     start_time = time.time()
#     scores = get_score_list(bm25Model, sample_questions, multi_proc=True)
#     end_time = time.time()
#     time_used = (end_time - start_time)
#
#     # evaluation result
#     # evaluation_map should be like {'TRAIN_186_QUERY_0': ['TRAIN_186', 'TRAIN_1278', 'TRAIN_892']}
#     evaluation_map = {}
#     for ind, score in enumerate(scores):
#         query_ID = Qindex2ID[ind]
#         doc_scores = [(i, val) for i, val in enumerate(score)]
#         doc_scores.sort(key=lambda x: x[1], reverse=True)
#         doc_best_ids = [ele[0] for ele in doc_scores][:3]
#         evaluation_map[query_ID] = [Dindex2ID[ele] for ele in doc_best_ids]
#
#     suning_q_IDs = ['DEV_s001_QUERY_0','DEV_s001_QUERY_1','DEV_s001_QUERY_2','DEV_s001_QUERY_3', 'DEV_s001_QUERY_4',
#                     'DEV_s002_QUERY_0','DEV_s002_QUERY_1','DEV_s002_QUERY_2','DEV_s002_QUERY_3',
#                     'DEV_s003_QUERY_0','DEV_s003_QUERY_1','DEV_s003_QUERY_2','DEV_s003_QUERY_3']
#     print({id: evaluation_map[id] for id in suning_q_IDs})
#
#     # Start evaluation how the choice evaluation
#     accuracy = evaluate_res(evaluation_map)
#     print(accuracy)


# Adapted from https://raw.githubusercontent.com/baoboa/pyqt5/master/examples/graphicsview/elasticnodes.py

from PyQt5.QtCore import QPointF, QRectF
from PyQt5.QtCore import Qt
from PyQt5.QtGui import (QBrush, QColor, QLinearGradient, QPainter,
                         QPainterPath, QPen, QPolygonF, QRadialGradient)
from PyQt5.QtGui import QTransform
from PyQt5.QtGui import QPolygonF
from PyQt5.QtGui import QFontMetrics
from PyQt5.QtGui import QFont
from PyQt5.QtGui import QCursor
from PyQt5.QtWidgets import (QGraphicsItem, QGraphicsView, QStyle)
from PyQt5.QtWidgets import QGraphicsSceneContextMenuEvent
#from graphics_rect import graphics_rect
from tv_scale_manager import original_scale

# TV Similarity Lines
class TVGLines(QGraphicsItem):
    Type = QGraphicsItem.UserType + 2

    def __init__(self):
        super(TVGLines, self).__init__()

        # height
        self.h = 200

        # bar width - must match texture_graph
        self.bar_width = 2.0

        # data
        self.tv_data1 = dict()
        self.tv_data2 = dict()
        self.step = 1

        # data width
        self.w = 0

        # scale
        self.scale = original_scale

        # draw fast sketch
        self.draw_sketch = False # must match default in draw_sketch checkbox

    def _prepare(self):

        # width
        # if both are defined then use wider of the two
        if self.tv_data1 and self.tv_data2:
            w1 = len(self.tv_data1["texture_vectors"]) * self.scale
            w2 = len(self.tv_data2["texture_vectors"]) * self.scale
            if w1 > w2:
                self.w = w1
            else:
                self.w = w2
        else:
            self.w = 0

        self.prepareGeometryChange()

    # call this if data or settings change
    def set_data(self, tv_data1, tv_data2, step, similarity_lines):
        self.tv_data1 = tv_data1
        self.tv_data2 = tv_data2
        self.step = step
        self.similarity_lines = similarity_lines
        self._prepare()

    # call this if scale changes
    def set_scale(self, scale):
        self.scale = scale
        self._prepare()

    def type(self):
        return TVGLines.Type

    # draw inside this rectangle
    def boundingRect(self):
        adjust = 2
        return QRectF(0 - adjust, 0 - adjust, self.w + adjust, self.h + adjust)

    def _draw_line(self, painter, bar_width, i, j):
        x1=i*bar_width
        y1=0
        x2=j*bar_width
        y2=200
        painter.drawLine(x1,y1,x2,y2)

    def paint(self, painter, option, widget):
        if not self.tv_data1 or not self.tv_data2:
            return

        painter.save()
        painter.translate(5+4, 20) # same as texture_graph

        bar_width = self.scale
        similarity_lines = self.similarity_lines
        step = self.step

        # paint similarity lines from left to right
        for i, values in similarity_lines.items():
            for j in values:
                 self._draw_line(painter, bar_width, i,j)

        painter.restore()


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

# In[2]:

import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
import datetime as dt
import matplotlib.dates as mdates

weather = pd.read_csv('data/C2A2_data/BinnedCsvs_d400/fb441e62df2d58994928907a91895ec62c2c42e6cd075c2700843b89.csv')
weather['Data_Value']=weather['Data_Value']/10 #to convert tmeperature as degree celcius
weather['D_T'] = pd.to_datetime(weather['Date'])

weather_to_year_2014 = weather[weather['D_T'].dt.year != 2015]
weather_to_year_2014['Day'] = weather_to_year_2014['Date'].str[5:]
weather_to_year_2014.sort_values('Day', inplace=True)
weather_to_year_2014 = weather_to_year_2014.groupby(['Day']).Data_Value.agg([('Min','min'),('Max','max')]).add_prefix('Historic Daily ')

weather_year_2015 = weather[weather['D_T'].dt.year == 2015]
weather_year_2015.sort_values('D_T', inplace=True)
weather_year_2015['Day'] = weather_year_2015['Date'].str[5:]
weather_year_2015 = weather_year_2015.groupby(['Day']).Data_Value.agg([('Min','min'),('Max','max')]).add_prefix('2015 Daily ')

weather_combined = pd.merge(weather_year_2015, weather_to_year_2014, left_index=True, right_index=True)
weather_combined.reset_index(inplace=True)
weather_combined['Day'] = weather_combined['Day']+'-2015'
weather_combined['Day'] = pd.to_datetime(weather_combined['Day'])
weather_combined.set_index('Day', inplace=True)

daily_max = weather_combined['Historic Daily Max']
daily_min = weather_combined['Historic Daily Min']
break_record_2015_max = weather_combined['2015 Daily Max'].loc[combined['2015 Daily Max']>combined['HistMax']]
break_record_2015_min = weather_combined['2015 Daily Min'].loc[combined['2015 Daily Min']<combined['HistMin']]
Base = weather_combined.index

plt.gca().fill_between(x=Base, y1=daily_max, y2=daily_min, facecolor='violet', alpha=0.25)
plt.scatter(break_record_2015_max.index, break_record_2015_max, s=10, c='red', label= 'Record Daily Max Broken in 2015')
plt.scatter(break_record_2015_min.index, break_record_2015_min, s=10, c='blue', label= 'Record Daily Min Broken in 2015')
plt.margins(x=0)

locator = mdates.MonthLocator()
fmt = mdates.DateFormatter('%b')
X = plt.gca().xaxis
plt.ylabel('Degree Celsius')
X.set_major_locator(locator)
X.set_major_formatter(fmt)

plt.gca().spines['right'].set_visible(False)
plt.gca().spines['top'].set_visible(False)
plt.gca().spines['bottom'].set_visible(False)
plt.gca().spines['left'].set_visible(False)

plt.title('Record Daily Max and Min Termperature 10 Years Prior to 2015 \n and Reocrd Broke in 2015 ')

plt.legend()
plt.legend(loc=4, frameon=False)

plt.show()

# In[ ]:

Notebook/Visualization of the National Oceanic and Atmospheric (NOAA) Dataset.py


import openpyxl
from openpyxl import Workbook, load_workbook
import pandas as pd
from pandas import ExcelWriter
from datetime import datetime

now = datetime.now()
dt_string = now.strftime("%d-%m-%Y_%H-%M-%S")

wb = pd.ExcelFile('Client Detail_2021_2H_concat.xlsx', engine='openpyxl')
worksheets = wb.sheet_names # gets sheet names - works but also creates sheet named ' (200)  Storage' that needs to be deleted
new_sheets = []

del worksheets[0]

# could probably use a list comprehension here
for sheet in worksheets:
    sheet_frame = pd.read_excel(wb, sheet, header=0)
    if 'concat' in sheet_frame.columns:
        new_sheets.append(sheet)

# gets clients from weekly pallet counts - works
wpc_df = pd.read_excel(wb, 'Weekly Pallet Counts')
clients = wpc_df['concat'].unique()

for client in clients:
    writer = ExcelWriter(f'{client}_Details_{dt_string}.xlsx')
    for sheet in new_sheets:
        sheet_frame = pd.read_excel(wb, sheet, header=0)
        if 'concat' in sheet_frame.columns:
            client_sheet = sheet_frame[sheet_frame['concat'] == client]
            if client_sheet.shape[0] == 0:
                continue
            # with pd.ExcelWriter(f'{client}_Details_{dt_string}.xlsx') as writer:  # pylint: disable=abstract-class-instantiated
            client_sheet.to_excel(writer, index=False, sheet_name=sheet)
        else:
            pass
    writer.save()