import ipaddress
import re
import urllib.request
from bs4 import BeautifulSoup
import socket
import requests
from googlesearch import search
import whois
import random
import requests
import networkx as nx
import hashlib
import networkx as nx
import requests
from bs4 import BeautifulSoup
from datetime import date, datetime
import time
from dateutil.parser import parse as date_parse
from urllib.parse import urlparse
import threading
import concurrent.futures
from urllib.parse import urlparse
import csv
import requests
from bs4 import BeautifulSoup
import re
from urllib.parse import urlparse
from urllib.parse import urlparse
import csv
import requests
from bs4 import BeautifulSoup
import re
from urllib.parse import urlparse
import numpy as np
import pandas as pd
import pickle
import urllib
import urllib.request
from datetime import datetime
from bs4 import BeautifulSoup
import ipaddress
import ssl
from urllib.parse import urlparse
import re
import requests
import json
import time
import threading
import random
import socket
import ssl
import math
from datetime import datetime
import sys
from concurrent.futures import ThreadPoolExecutor
import asyncio
import socket
import re
import aiohttp
import aiodns
import whois
import re
from urllib.parse import urlparse
from bs4 import BeautifulSoup
import tldextract
import os
import aiohttp
import time
import concurrent.futures
import difflib
import redis

async def contains_IP_address(url, socurce_code, soup, whois_response):
    domain = urlparse(url).hostname
    try:
        ip_address = socket.gethostbyname(domain)
    except:
        return -1
    if ip_address in domain:
        return -1
    else:
        return 1

async def UrlLength(url, source_code, soup, whois_response):
    if (len(url) < 54):
        return 1
    elif (len(url) >= 54 and len(url) <= 75):
        return 0
    return -1

shortening_services = r"bit\.ly|goo\.gl|shorte\.st|go2l\.ink|x\.co|ow\.ly|t\.co|tinyurl|tr\.im|is\.gd|cli\.gs|" \
                      r"yfrog\.com|migre\.me|ff\.im|tiny\.cc|url4\.eu|twit\.ac|su\.pr|twurl\.nl|snipurl\.com|" \
                      r"short\.to|BudURL\.com|ping\.fm|post\.ly|Just\.as|bkite\.com|snipr\.com|fic\.kr|loopt\.us|" \
                      r"doiop\.com|short\.ie|kl\.am|wp\.me|rubyurl\.com|om\.ly|to\.ly|bit\.do|t\.co|lnkd\.in|db\.tt|" \
                      r"qr\.ae|adf\.ly|goo\.gl|bitly\.com|cur\.lv|tinyurl\.com|ow\.ly|bit\.ly|ity\.im|q\.gs|is\.gd|" \
                      r"po\.st|bc\.vc|twitthis\.com|u\.to|j\.mp|buzurl\.com|cutt\.us|u\.bb|yourls\.org|x\.co|" \
                      r"prettylinkpro\.com|scrnch\.me|filoops\.info|vzturl\.com|qr\.net|1url\.com|tweez\.me|v\.gd|" \
                      r"tr\.im|link\.zip\.net"

async def TinyURL(url, source_code, soup, whois_response):
    match = re.search(shortening_services, url)
    if match:
        return -1
    return 1

async def Have_At(url, source_code, soup, whois_response):
    if ('@' in url):
        return -1
    return 1

async def redirection(url, source_code, soup, whois_response):
    if (url.rfind('//') > 6):
        return -1
    return 1

async def PrefixSuffix(url, source_code, soup, whois_response):
    if ('-' in url):
        return -1
    return 1

async def subDomains(url, source_code, soup, whois_response):
    x = tldextract.extract(url).subdomain + "." + tldextract.extract(url).domain
    if(x.count('.') == 1):
      return 1
    elif (x.count('.') == 2):
      return 0
    else:
      return -1

async def HTTPS(url, source_code, soup, whois_response):
    if (url.startswith('https')):
        return 1
    return -1

async def Domain_Registration_Len(url, source_code, soup, whois_response):
    try:
        expiration_date = whois_response.expiration_date
        creation_date = whois_response.creation_date
        try:
            if (len(expiration_date)):
                expiration_date = expiration_date[0]
        except:
            return -1
        try:
            if (len(creation_date)):
                creation_date = creation_date[0]
        except:
            return -1
        age = (expiration_date.year - creation_date.year)
        if (age >= 12):
            return 1
        return -1
    except:
        print("Error at the Domain_Registration_Len")
        return -1

async def Favicon(url, source_code, soup, whois_response):
    try:
        x = url
        x = tldextract.extract(x).subdomain + "." + tldextract.extract(x).domain
        if(x.endswith('/')):
            x = requests.get(x + '/favicon.ico')
        else :
            x = requests.get(x + 'favicon.ico')
        if (x.status_code == 200):
            return 1
        a = soup.find_all('link', rel='shortcut icon')
        if(len(a) !=  0):
            return 1
        return -1
    except:
        print("Error at has_favicon")
        return -1

async def nonStdPort(url, source_code, soup, whois_response):
    try:
        port = urlparse(url).port
        if (port):
            if (port == 80 or port == 443):
                return 1
            else:
                return -1
        else:
            return 1
    except:
        return -1

async def HTTPSDomain(url, source_code, soup, whois_response):
    try:
        domain = urlparse(url).netloc.lower()
        if("https" in domain):
            return -1
        else:
            return 1
    except:
        print("Error at HTTPSDomain")
        return -1

async def RequestURL(url, source_code, soup, whois_response):
    try:
        urls = []
        urls += [img['src'] for img in soup.find_all('img', src=True)]
        urls += [audio['src'] for audio in soup.find_all('audio', src=True)]
        urls += [embed['src'] for embed in soup.find_all('embed', src=True)]
        urls += [iframe['src'] for iframe in soup.find_all('iframe', src=True)]
        num_urls = len(urls)
        num_external_urls = 0

        for url in urls:
            parsed_url = urlparse(url)
            if parsed_url.netloc != urlparse(url).netloc:
                num_external_urls += 1

        percentage_external = num_external_urls / num_urls * 100
        if percentage_external < 22:
            return 1
        elif percentage_external < 61:
            return 0
        else:
            return -1

    except:
        return -1

async def AnchorURL(url, source_code, soup, whois_response):
    try:
        urls = [a['href'] for a in soup.find_all('a', href=True)]
        num_urls = len(urls)
        num_external_urls = 0

        for url in urls:
            if url.startswith('#') or url.lower().startswith('javascript') or url.lower().startswith('mailto'):
                continue
            parsed_url = urlparse(url)
            if parsed_url.netloc != urlparse(url).netloc:
                num_external_urls += 1

        percentage_external = num_external_urls / num_urls * 100
        if percentage_external < 31:
            return 1
        elif percentage_external < 67:
            return 0
        else:
            return -1

    except:
        print("Error at AnchorURL")
        return -1

async def LinksInScriptTags(url, source_code, soup, whois_response):
    try:
        url_parse = urlparse(url)
        domain = url_parse.netloc
        metas = soup.find_all('meta')
        scripts = soup.find_all('script')
        links = soup.find_all('link')

        meta_count = 0
        script_count = 0
        link_count = 0
        total_count = 0

        for meta in metas:
            if 'http-equiv' in meta.attrs:
                if domain in meta.attrs['content']:
                    meta_count += 1
            elif 'name' in meta.attrs:
                if domain in meta.attrs['content']:
                    meta_count += 1

        for script in scripts:
            if 'src' in script.attrs:
                if domain in script.attrs['src']:
                    script_count += 1

        for link in links:
            if 'href' in link.attrs:
                if domain in link.attrs['href']:
                    link_count += 1

        total_count = meta_count + script_count + link_count

        percent_links = (total_count / len(soup.find_all())) * 100

        if percent_links < 17:
            return 1
        elif percent_links >= 17 and percent_links <= 81:
            return 0
        else:
            return -1
    except:
        return -1

async def ServerFormHandler(url, source_code, soup, whois_response):
    try:
        forms = soup.find_all('form')
        if not forms:
            return 1
        for form in forms:
            if form.has_attr('action') and (form['action'] == 'about:blank' or form['action'] == ''):
                return -1
            elif form.has_attr('action'):
                parsed_url = urlparse(form['action'])
                domain_name = parsed_url.hostname
                if domain_name and domain_name != urlparse(url).hostname:
                    return 0
        return 1
    except:
        return -1

async def InfoEmail(url, source_code, soup, whois_response):
    try:
        elements = soup.find_all(lambda tag: (tag.name == 'a' or tag.name == 'button') and tag.has_attr('href') and tag['href'].startswith('mailto:'))
        for element in elements:
            return -1
        return 1
    except:
        print("Error at InfoEmail")
        return -1

async def AbnormalURL(url, source_code, soup, whois_response):
    try:
        whois_response = whois_response.text

        if whois_response and 'Domain Name' in whois_response:
            return 1
        else:
            return -1
    except:
        return -1

async def WebsiteForwarding(url, source_code, soup, whois_response):
    try:
        response = requests.get(url, allow_redirects=False, timeout=3)
        count = 0
        while 300 <= response.status_code < 400:
            count += 1
            location = response.headers['location']
            response = requests.get(location, allow_redirects=False, timeout=3)
        if count <= 1:
            return 0 # Legitimate
        elif 2 <= count < 4:
            return 1 # Suspicious
        else:
            return -1 # Phishing
    except:
        print("Error at WebsiteForwarding")
        return -1

async def StatusBarCustomization(url, source_code, soup, whois_response):
    try:
        if (re.search("<script>.+onmouseover.+</script>", source_code)):
            return -1
        else:
            return 1
    except:
        print("Error at the StatusBarCustomization")
        return -1

async def DisablingRightClick(url, source_code, soup, whois_response):
    try:
        elements = soup.find_all(lambda tag: tag.has_attr('onmousedown'))
        for element in elements:
            event_str = element['onmousedown']
            if(re.search(r'event\.button\s*==\s*2', event_str)):
                return -1
        return 1
    except:
        print("Error at DisablingRightClick")
        return -1

async def UsingPopupWindow(url, source_code, soup, whois_response):
    try:
        if (re.findall(r"alert\(", str(soup)) == 0):
            return -1
        else:
            return 1
    except:
        print("Error at UsingPopupWindow")
        return -1

async def IframeRedirection(url, source_code, soup, whois_response):
    try:
        if (re.findall(r"[<iframe> | <frameBoder>]", str(soup))):
            return 1
        else:
            return -1
    except:
        print("Error in IframeRedirection")
        return -1

async def AgeOfDomain(url, source_code, soup, whois_response):
    try:
        creation_date = whois_response.creation_date
        try:
            if (len(creation_date)):
                creation_date = creation_date[0]
        except:
            print("Error in AgeOfDomain")
            return -1
        today = date.today()
        age = (today.year - creation_date.year)
        if (age >= 6):
            return 1
        return -1
    except:
        print("Error in AgeOfDomain")
        return -1

async def DNS_Recording(url, source_code, soup, whois_response):
    try:
        if(whois_response.status is None):
            return -1
        else :
            return 1
    except:
        print("Error at DNS_Recording")
        return -1

async def websiteTraffic(url, source_code, soup, whois_response):
    return 1

async def pageRank(url, source_code, soup, whois_response):
    try:
        links = soup.find_all('a')

        G = nx.DiGraph()
        for link in links:
            href = link.get('href')
            if href:
                if href.startswith('https'):
                    G.add_edge(url, href)
                else:
                    G.add_edge(url, url + href)

        pr = nx.pagerank(G, alpha=0.9)
        if(pr[url] > 0.02):
            return 1
        else:
            return  -1

    except:
        print("Error in page_rank")
        return -1

async def GoogleIndex(url, source_code, soup, whois_response):
    try:
        site = search(url, 5)
        print("the site is" , site)
        if (site):
            return 1
        else:
            return -1
    except:
        print("Error in GoogleIndex")
        return -1

async def LinksPointingToPage(url, source_code, soup, whois_response):
    try:
        num_of_links = len(soup.find_all(r"<a href=", soup))
        if (num_of_links == 0):
            return 1
        elif num_of_links <= 2:
            return 0
        else:
            return -1
    except:
        print("Error in LinksPointingToPage")
        return -1

async def StatsReport(url, source_code, soup, whois_response):
    try:
        url = urlparse(url)
        domain_name = url.hostname
        url_match = re.search(
            'at\.ua|usa\.cc|baltazarpresentes\.com\.br|pe\.hu|esy\.es|hol\.es|sweddy\.com|myjino\.ru|96\.lt|ow\.ly', domain_name)
        ip_address = socket.gethostbyname(domain_name)
        ip_match = re.search('146\.112\.61\.108|213\.174\.157\.151|121\.50\.168\.88|192\.185\.217\.116|78\.46\.211\.158|181\.174\.165\.13|46\.242\.145\.103|121\.50\.168\.40|83\.125\.22\.219|46\.242\.145\.98|'
                             '107\.151\.148\.44|107\.151\.148\.107|64\.70\.19\.203|199\.184\.144\.27|107\.151\.148\.108|107\.151\.148\.109|119\.28\.52\.61|54\.83\.43\.69|52\.69\.166\.231|216\.58\.192\.225|'
                             '118\.184\.25\.86|67\.208\.74\.71|23\.253\.126\.58|104\.239\.157\.210|175\.126\.123\.219|141\.8\.224\.221|10\.10\.10\.10|43\.229\.108\.32|103\.232\.215\.140|69\.172\.201\.153|'
                             '216\.218\.185\.162|54\.225\.104\.146|103\.243\.24\.98|199\.59\.243\.120|31\.170\.160\.61|213\.19\.128\.77|62\.113\.226\.131|208\.100\.26\.234|195\.16\.127\.102|195\.16\.127\.157|'
                             '34\.196\.13\.28|103\.224\.212\.222|172\.217\.4\.225|54\.72\.9\.51|192\.64\.147\.141|198\.200\.56\.183|23\.253\.164\.103|52\.48\.191\.26|52\.214\.197\.72|87\.98\.255\.18|209\.99\.17\.27|'
                             '216\.38\.62\.18|104\.130\.124\.96|47\.89\.58\.141|78\.46\.211\.158|54\.86\.225\.156|54\.82\.156\.19|37\.157\.192\.102|204\.11\.56\.48|110\.34\.231\.42', ip_address)
        if url_match:
            return -1
        elif ip_match:
            return -1
        return 1
    except:
        print("Error in StatsReport")
        return -1

# list all the function name
funcs = [contains_IP_address, UrlLength, TinyURL, Have_At,
        redirection, PrefixSuffix, subDomains, HTTPS, Domain_Registration_Len, Favicon, nonStdPort, HTTPSDomain,
        RequestURL,AnchorURL, LinksInScriptTags, ServerFormHandler,
        InfoEmail, AbnormalURL, WebsiteForwarding, StatusBarCustomization,DisablingRightClick , UsingPopupWindow,
        IframeRedirection, AgeOfDomain,DNS_Recording,  websiteTraffic, pageRank, GoogleIndex, LinksPointingToPage, StatsReport]
feature_names = ['contains_IP_address', ' UrlLength', ' TinyURL', ' Have_At',
       ' redirection', ' PrefixSuffix', ' subDomains', ' HTTPS',
       ' Domain_Registration_Len', ' Favicon', ' nonStdPort', ' HTTPSDomain',
       'RequestURL', 'AnchorURL', ' LinksInScriptTags', ' ServerFormHandler',
       'InfoEmail', ' AbnormalURL', ' WebsiteForwarding',
       ' StatusBarCustomization', 'DisablingRightClick ', ' UsingPopupWindow',
       'IframeRedirection', ' AgeOfDomain', 'DNS_Recording',
       '  websiteTraffic', ' pageRank', ' GoogleIndex', ' LinksPointingToPage',
       ' StatsReport']

async def run_whois(url):
    return whois.whois(url)
async def extract_features(url):
    async with aiohttp.ClientSession() as session:
        async with session.get(url) as response:
            x = time.time()
            source_code = await response.text()
            print(f"the get request takes {time.time() - x}")

        soup = BeautifulSoup(source_code, 'html.parser')
        x1 = time.time()
        whois_time = time.time()
        whois_response = await run_whois(url)
        print(f"the whois process takes {time.time() - whois_time}")

        features = []
        tasks = [func(url, source_code, soup, whois_response) for func in funcs]
        start_time = time.monotonic()
        results = await asyncio.gather(*tasks)
        for i, result in enumerate(results):
            features.append(result)
            print(f"{funcs[i]} took {time.monotonic()-start_time} seconds to complete.")
            print(f"{funcs[i]}: {result}")
        return features

model = pickle.load(open("/home/xuananle/Documents/URL_net/Backend/ML Models/model.pkl", "rb"))

with open("/home/xuananle/Documents/URL_net/Backend/data/test.txt") as fp:
    chrome_warning_contents = fp.read()

async def predict(url):
    try:
        response = requests.get(url, timeout= 3)
    except:
        print("Cannot connect to the website")
        return -1

    if(response.status_code >= 400):
        print("the link is not valid")
        return -1

    content_type = response.headers.get("content-type")
    if "charset" in content_type:
        encoding = content_type.split("charset=")[-1]
        content = response.content.decode(encoding)
    else:
        content = response.content

    matcher = difflib.SequenceMatcher(None, chrome_warning_contents, content)
    ratio = matcher.ratio()
    print("the ratio is: ", ratio)
    if(ratio >= 0.9):
        return -1

    features = await extract_features(url)
    # First condition
    if(features[5] + features[8] + features[23] == -3):
        return -1

    features = np.array(features).reshape(1, -1)
    features = pd.DataFrame(features, columns=feature_names)
    probabilities = model.predict_proba(features)
    return probabilities[0][1]

# black_list = redis.Redis(host='localhost', port=6379, decode_responses=True, db = 0)
# white_list = redis.Redis(host='localhost', port=6379, decode_responses=True, db = 1)

with open("/home/xuananle/Documents/URL_net/Backend/data/blacklist.txt") as fp:
    lists = fp.read().splitlines()
with open("/home/xuananle/Documents/URL_net/Backend/data/whitelist.txt") as fp:
    white = fp.read().splitlines()
import tldextract
def main(url):
    new_url = tldextract.extract(url).domain + "." + tldextract.extract(url).suffix
    print("The new url is: ", new_url)
    if(lists.count(new_url) or lists.count(url)
       or lists.count("https://" + new_url + "/*") or lists.count("http://" + new_url + "/*")):
        return -1
    if(white.count(new_url) or white.count(url)):
        return 1
    s = asyncio.run(predict(url))
    print("I am predicting  ", url)
    print("The result is: ", s)
    return s
url = "https://www.google.com"
print(main(url))


number_of_orders = int(input())
total_price = 0
for i in range(number_of_orders):
    price = float(input())
    days = int(input())
    capsules = int(input())
    if 0.01<=price<=100 and 1<=days<=31 and 1<=capsules<=2000:
        price_of_coffee = price*days*capsules
        print(f'The price for the coffee is: ${price_of_coffee:.2f}')
        total_price += price_of_coffee
    else: continue

print(f'Total: ${total_price:.2f}')


from base.base_data_loader import BaseDataLoader
from keras.preprocessing.image import ImageDataGenerator

class ImageGeneratorDataloader(BaseDataLoader):

    def __init__(self, config):
        super(ImageGeneratorDataloader, self).__init__(config)

        train_datagen = ImageDataGenerator(
            rescale=1./255,  # regularise RGB channels (doesn't affect the actual color)
            zoom_range=[.65, 1],  # we are zooming in at most 35%, so in the range of 0 to 35%
            horizontal_flip=True,  # flipping the image horizontally
            brightness_range=[0.2,1.0], #brightness image augmentation randomly darken the image between 1.0 (no change) and 0.2 or 20%
            fill_mode='constant')

        test_datagen = ImageDataGenerator(rescale=1./255)

        self.train_generator = train_datagen.flow_from_directory(
            self.config.data_loader.train_data_path,
            target_size=(self.config.trainer.dim, self.config.trainer.dim),  # resize train image to dim * dim
            batch_size=self.config.trainer.batch_size,
            class_mode='categorical',  # class mode is categorical - list with n-classes that points to the class it is
            shuffle = "false")
        self.validation_generator = test_datagen.flow_from_directory(
            self.config.data_loader.validation_data_path,
            target_size=(self.config.trainer.dim, self.config.trainer.dim),  # resize validation image to dim * dim
            batch_size=self.config.trainer.batch_size,
            class_mode='categorical',  # class mode is categorical - list with n-classes that points to the class it is
            shuffle = "false")

        print(self.validation_generator.class_indices)  # allows us to see where the model will point to each class

    def get_train_generator(self):
        return self.train_generator

    def get_validation_generator(self):
        return self.validation_generator


from sys import stdin
from collections import deque

read = lambda: stdin.readline().rstrip()

t = int(read())

for _ in range(t):
    n, m = map(int, read().split())

    docp = list(map(int, read().split()))

    pq = deque()

    for i in range(n):
        pq.append([docp[i], i])

    c = 0
    docp.sort(reverse=True)
    mi = 0
    while True:
        v, idx = pq.popleft()
        if v == docp[mi]:
            c += 1
            mi += 1
            if idx == m:
                break
            continue
        else:
            pq.append([v, idx])

    print(c)


from django.test import TestCase

from database.models import (
    Description,
    OldnameNewnameTableLeft,
    OldnameNewnameTableRight,
    PesticidalProteinDatabase,
    PesticidalProteinPrivateDatabase,
    ProteinDetail,
    StructureDatabase,
    UserUploadData,
)

class PesticidalProteinDatabaseModelTest(TestCase):
    @classmethod
    def setUpTestData(cls):
        PesticidalProteinDatabase.objects.create(name="Cry1001Aa1", oldname="R1")

    def test_name_label(self):
        protein = PesticidalProteinDatabase.objects.get(id=1)
        field_label = PesticidalProteinDatabase._meta.get_field("name").verbose_name
        self.assertEquals(field_label, "Protein Name")

    def test_name_max_length(self):
        protein = PesticidalProteinDatabase.objects.get(id=1)
        max_length = PesticidalProteinDatabase._meta.get_field("name").max_length
        self.assertEquals(max_length, 15)

    def setUp(self):
        self.database = PesticidalProteinDatabase.objects.create(
            submittersname="Suresh",
            submittersemail="admin@bpprc.org",
            name="Rpp1001Aa1",
            oldname="",
            othernames="",
            accession="M7829DHR",
            year="2023",
            sequence="MEKYMLLAQFPAEKTLNETDIPSATLQLLTGKQAGVARPGGIFTKEDLINIKLYV",
            bacterium="True",
            bacterium_textbox="Photorhabdus khanii",
            taxonid="1004151",
            partnerprotein="False",
            partnerprotein_textbox="",
            toxicto="",
            nontoxic="",
            dnasequence="",
            publication="",
        )

    def test_post_model(self):
        data = self.database
        self.assertTrue(isinstance(data, PesticidalProteinDatabase))

    def test_PesticidalProteinDatabase_name(self):
        database = self.database
        self.assertEqual(database.__str__(), "Rpp1001Aa1")

    def test_category_name(self):
        database = str(self.database.name)
        print(database[:3])
        category_name = database[:3]
        self.assertEqual(category_name, "Rpp")


# This transmitter uses QPSK modulation to transmit a byte, an array of bytes or an array of bits
# over a channel with 'added white gaussian noise' (AWGN). All arrays must use np.uint8 integers.

# import logging
import numpy as np
from komm import PSKModulation, AWGNChannel, int2binlist, binlist2int

# logging.basicConfig(level=logging.DEBUG)
# logger = logging.getLogger(__name__)

class QPSKTransmitter:
	"""The QPSKTransmitter class provides methods for transmitting integers and 1D arrays of bits or integers."""

	def __init__(self, snr: float = np.inf):
		self.channel = AWGNChannel(snr=snr)
		self.qpsk = PSKModulation(4, phase_offset=np.pi / 4)

	def set_snr(self, snr: float = np.inf) -> None:
		self.channel.snr = snr

	# TRANSMISSION FUNCTIONS

	def transmit_byte(self, input_int: np.uint8) -> np.uint8:
		"""Takes a uint8 integer value, modulates it via QPSK, transmits it over the channel
		and converts it back to a uint8 integer value."""

		if np.dtype(input_int) is not np.dtype(np.uint8):
			raise TypeError("The integer parameter must be of type uint8")

		# Modulate
		modulated = self.qpsk.modulate(int2binlist(input_int, 8))
		# Transmit over the channel channel with 'additive white gaussian noise'
		channel_out = self.channel(modulated)
		# Demodulate
		demodulated = self.qpsk.demodulate(channel_out)
		# Return the received integer
		return np.uint8(binlist2int(demodulated))

	def transmit_bitstream(self, input_bitstream: np.ndarray) -> np.ndarray:
		"""Takes a uint8 bitstream array, modulates it via QPSK, transmits it over the channel
		and converts it back to a bitstream."""

		if type(input_bitstream) is not np.ndarray:
			raise TypeError("The input bitstream must be a numpy array")
		if input_bitstream.dtype is not np.dtype(np.uint8):
			raise TypeError("The input bitstream must consist of uint8 integers")
		if len(input_bitstream) % 2 is not 0:
			raise TypeError("The input array must have an even number of bits")

		# Modulate
		modulated = self.qpsk.modulate(input_bitstream)
		# Transmit over the channel channel with 'additive white gaussian noise'
		channel_out = self.channel(modulated)
		# Demodulate
		demodulated = np.array(self.qpsk.demodulate(channel_out), dtype=np.uint8)

		return demodulated

	def transmit_byte_array(self, input_array: np.ndarray) -> np.ndarray:
		"""Takes a 1D array of uint8 bytes, transmits it and converts it back to a 1D array."""

		# Allocate an output array of correct size
		number_of_ints = len(input_array)
		output_array = np.zeros(number_of_ints, dtype=np.uint8)

		if type(input_array) is not np.ndarray:
			raise TypeError("The input array must be a numpy array")
		if input_array.dtype is not np.dtype(np.uint8):
			raise TypeError("The input array must consist of uint8 integers")
		if len(input_array.shape) is not 1:
			raise TypeError("The input array must be of flat shape")

		# Transmit the array item-wise
		for i in range(number_of_ints):
			output_array[i] = self.transmit_byte(input_array[i])
		return output_array


import rospy
from geometry_msgs.msg import Twist
from std_msgs.msg import String
import time
import sys, select, termios, tty
import donkeycar as dk

# import keyboard  # using module keyboard
from pynput import keyboard

#############################################################################################
# keyboard

moveBindings = {
    'w': (1, 0),
    'a': (0, -1),
    's': (-1.2, 0),
    'd': (0, 1),
    'wa': (1, -1),
    'wd': (1, 1),
    'sa': (-1.2, -1),
    'sd': (-1.2, 1)
}

speedBindings={
    'z': (1.1, 1),
    'x': (.9, 1),
    'c': (1, 1.1),
    'v': (1, .9)
}

msg = '''

Reading from the keyboard  and Publishing to Twist!
---------------------------
Moving around:
  w
a s d

anything else : stop
z/x : increase/decrease only linear speed by 10%
c/v : increase/decrease only angular speed by 10%
CTRL-C to quit

'''

class KeyboardRun:

    key_w = False
    key_a = False
    key_s = False
    key_d = False
    key_z = False
    key_x = False
    key_c = False
    key_v = False
    key_esc = False

    cmd_controller_pub_str = 'keyboard'

    def __init__(self):
        # settings = termios.tcgetattr(sys.stdin)

        rospy.init_node('keyboard_node')
        self.cmd_vel_pub = rospy.Publisher('cmd_vel', Twist, queue_size=1)
        self.cmd_controller_pub = rospy.Publisher('cmd_controller', String, queue_size=1)

        self.speed = rospy.get_param("~speed", 0.19)
        self.turn = rospy.get_param("~turn", 0.7)
        self.x = 0
        self.y = 0
        self.z = 0
        self.th = 0
        self.status = 0
        self.switch = False

    def run(self):
        self.listener = keyboard.Listener(
            on_press=self.on_press,
            on_release=self.on_release)
        self.listener.start()
        self.switch = True

        try:
            print(msg)
            print(self.vels(self.speed, self.turn))

            while (self.listener.isAlive()):
                if self.key_w == True and self.key_a == False and self.key_d == False:
                    self.x, self.th = moveBindings['w']
                elif self.key_s == True and self.key_a == False and self.key_d == False:
                    self.x, self.th = moveBindings['s']

                elif self.key_w == True and self.key_a == True:
                    self.x, self.th = moveBindings['wa']
                elif self.key_w == True and self.key_d == True:
                    self.x, self.th = moveBindings['wd']
                elif self.key_s == True and self.key_a == True:
                    self.x, self.th = moveBindings['sa']
                elif self.key_s == True and self.key_d == True:
                    self.x, self.th = moveBindings['sd']

                elif self.key_d == True:
                    self.x, self.th = moveBindings['d']
                elif self.key_a == True:
                    self.x, self.th = moveBindings['a']

                elif self.key_z == True:
                    self.speed *= speedBindings['z'][0]
                    self.turn *= speedBindings['z'][0]
                    print(self.vels(self.speed, self.turn))
                    if (self.status == 14):
                        print(msg)
                    self.status = (self.status + 1) % 15
                elif self.key_x == True:
                    self.speed *= speedBindings['x'][0]
                    self.turn *= speedBindings['x'][0]
                    print(self.vels(self.speed, self.turn))
                    if (self.status == 14):
                        print(msg)
                    self.status = (self.status + 1) % 15
                elif self.key_c == True:
                    self.speed *= speedBindings['c'][0]
                    self.turn *= speedBindings['c'][0]
                    print(self.vels(self.speed, self.turn))
                    if (self.status == 14):
                        print(msg)
                    self.status = (self.status + 1) % 15
                elif self.key_v == True:
                    self.speed *= speedBindings['v'][0]
                    self.turn *= speedBindings['v'][0]
                    print(self.vels(self.speed, self.turn))
                    if (self.status == 14):
                        print(msg)
                    self.status = (self.status + 1) % 15
                elif self.key_esc== True:
                    print('exit')
                    self.switch = False
                else:
                    self.x = 0
                    self.y = 0
                    self.z = 0
                    self.th = 0

                twist = Twist()
                twist.linear.x = self.x * self.speed
                twist.linear.y = 0
                twist.linear.z = 0
                twist.angular.x = 0
                twist.angular.y = 0
                twist.angular.z = self.th * self.turn
                self.cmd_controller_pub.publish(self.cmd_controller_pub_str)
                self.cmd_vel_pub.publish(twist)

                print('twist value : ',twist.linear.x,twist.angular.z)

                time.sleep(0.1)

        except Exception as e:
            print(e)

    def on_press(self, key):
        try:
            print('alphanumeric key {0} pressed'.format(key.char))
            _key = key.char
            if _key == 'w':
                self.key_w = True
            elif _key == 'a':
                self.key_a = True
            elif _key == 's':
                self.key_s = True
            elif _key == 'd':
                self.key_d = True
            elif _key == 'z':
                self.key_z = True
            elif _key == 'x':
                self.key_x = True
            elif _key == 'c':
                self.key_c = True
            elif _key == 'v':
                self.key_v = True

        except AttributeError:
            print('special key {0} pressed'.format(key.char))

    def on_release(self, key):
        try:
	        print('{0} released'.format(key))
	        _key = key.char
	        if _key == 'w':
	            self.key_w = False
	        elif _key == 'a':
	            self.key_a = False
	        elif _key == 's':
	            self.key_s = False
	        elif _key == 'd':
	            self.key_d = False
	        elif _key == 'z':
	            self.key_z = False
	        elif _key == 'x':
	            self.key_x = False
	        elif _key == 'c':
	            self.key_c = False
	        elif _key == 'v':
	            self.key_v = False

        except AttributeError:
            print('special key {0} pressed'.format(key.char))

    def vels(self, speed, turn):
        return "currently:\tspeed %s\tturn %s " % (speed, turn)

if __name__=="__main__":
    cfg = dk.load_config()
    keyboardRun = KeyboardRun() #
    keyboardRun.run()


from train import create_model_train
import numpy as np
from sklearn.preprocessing import LabelEncoder
from data_prepare import get_data

#get test data
x_test,y_test = get_data(mode = "test")

#process the data
x_test = np.expand_dims(x_test, axis=3)
en_t = LabelEncoder()
en_t.fit(y_test)
y_test_encoded = en_t.transform(y_test)

#prediction
model = create_model_train()
prediction = model.predict(x_test)

#print 10 sample test results
print("10 sample test results")
test_truth = [ y_test_encoded[i] for i in range(10) ]
test_result = [ np.argmax(prediction[i]) for i in range(10) ]
testdata = {'test_truth': test_truth, 'test_result': test_result}
result_table = pd.DataFrame(testdata)
print(result_table)


import torch

def augment_obs_oracle(obs, tasks, use_env_obs):
    if use_env_obs:
        return torch.cat([obs, tasks], 1)
    return tasks

def augment_obs_optimal(obs, latent_dim, posterior, use_env_obs, is_prior):
    num_proc = obs.shape[0]

    if type(posterior) == list:
        posterior = torch.tensor([posterior[i].flatten().tolist() for i in range(num_proc)])
    elif not is_prior:
        posterior[:, latent_dim:] = posterior[:, latent_dim:].exp()

    posterior_sample = torch.normal(posterior[:, 0:latent_dim], posterior[:, latent_dim:].sqrt())

    if use_env_obs:
        new_obs = torch.cat([obs, posterior_sample], 1)
        return new_obs

    return posterior_sample

def augment_obs_posterior(obs, latent_dim, posterior, use_env_obs, is_prior):
    num_proc = obs.shape[0]

    if type(posterior) == list:
        posterior = torch.tensor([posterior[i].flatten().tolist() for i in range(num_proc)])
    elif not is_prior:
        posterior[:, latent_dim:] = posterior[:, latent_dim:].exp()

    if use_env_obs:
        new_obs = torch.cat([obs, posterior], 1)
    else:
        new_obs = posterior.clone().detach()

    return new_obs

def get_posterior(vi, action, reward, prior, env_obs, use_env_obs, use_prev_state=True):
    num_proc = action.shape[0]
    flatten_prior = torch.tensor([prior[i].flatten().tolist() for i in range(num_proc)])

    # To feed VI, i need (n_batch, 1, 2)
    context = torch.empty(num_proc, 1, 1 + env_obs.shape[1] + action.shape[1]) if use_env_obs \
        else torch.empty(num_proc, 1, 1 + action.shape[1])

    if use_env_obs:
        context[:, 0, :] = torch.cat([action.float(), reward, env_obs], 1)
    else:
        context[:, 0, :] = torch.cat([action.float(), reward], 1)

    res = vi(context=context, prior=flatten_prior, use_prev_state=use_prev_state)
    res = res[1:]
    res = torch.cat([res[0].detach(), res[1].detach()], 1)
    return res

class RunningMeanStd(object):
    # https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#Parallel_algorithm
    # PyTorch version.
    def __init__(self, epsilon=1e-4, shape=()):
        self.mean = torch.zeros(shape).float()
        self.var = torch.ones(shape).float()
        self.count = epsilon

    def update(self, x):
        x = x.view((-1, x.shape[-1]))
        batch_mean = x.mean(dim=0)
        batch_var = x.var(dim=0)
        batch_count = x.shape[0]
        self.update_from_moments(batch_mean, batch_var, batch_count)

    def update_from_moments(self, batch_mean, batch_var, batch_count):
        self.mean, self.var, self.count = update_mean_var_count_from_moments(
            self.mean, self.var, self.count, batch_mean, batch_var, batch_count)

def update_mean_var_count_from_moments(mean, var, count, batch_mean, batch_var, batch_count):
    delta = batch_mean - mean
    tot_count = count + batch_count

    new_mean = mean + delta * batch_count / tot_count
    m_a = var * count
    m_b = batch_var * batch_count
    M2 = m_a + m_b + torch.pow(delta, 2) * count * batch_count / tot_count
    new_var = M2 / tot_count
    new_count = tot_count

    return new_mean, new_var, new_count


import numpy as np

def computer_loss():
    pass

def getDist(pre, labels, num_classes):
        """
        input:
                pre: [batchsize, 14]
                labels: [batchsize, 14]
        return:
                dist: [batchsize, 7]
        """
        # pre = pre.reshape([-1, 17, 2])
        pre = pre.reshape([-1, num_classes, 2])
        # labels = labels.reshape([-1, 17, 2])
        labels = labels.reshape([-1, num_classes, 2])
        res = np.power(pre[:,:,0]-labels[:,:,0],2)+np.power(pre[:,:,1]-labels[:,:,1],2)
        return res

def getAccRight(dist, th):
        """
        input:
                dist: [batchsize, 7]

        return:
                dist: [7,]    right count of every point
        """
        res = np.zeros(dist.shape[1], dtype=np.int64)
        for i in range(dist.shape[1]):
                res[i] = sum(dist[:,i]<th)

        return res

def myAcc(output, target, size: int, num_classes: int):
    '''
    return [7,] ndarray
    '''
    # print(output.shape)
    #64, 7, 40, 40     gaussian
    #(64, 14)                !gaussian
    # b
    #if hm_type == 'gaussian':
    if len(output.shape) == 4:
            output = heatmap2locate(output)
            target = heatmap2locate(target)

    #offset方式还原坐标
    # [h, ls, rs, lb, rb, lr, rr]
    # output[:,6:10] = output[:,6:10]+output[:,2:6]
    # output[:,10:14] = output[:,10:14]+output[:,6:10]

    dist = getDist(output, target, num_classes)
    cate_acc = getAccRight(dist, 5/size)
    return cate_acc


# 인구이동

# N*N 땅, 1*1에 1나라, 그나라엔 A[r][c] 명 존재, 국경선은 정사각형
# 인구이동은 하루진행
# 국경선 공유하는 두나라 L<=인구차<=R 일때 국경선 열림
# 각각의 국경선들이 모두 열렸다면 인구이동 시작, 국경선 열려서 이어진나라들이 연합. 이사이에서 이동
# 각 연합을 이루는 각 칸 인구수는 연합인구수/연합이루는 칸 개수. 소수점 버림
# 연합 해체후 국경선 닫기
# 인구이동 몇일 발생할까

import sys
import math
from collections import deque
input = sys.stdin.readline

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

N,L,R = map(int, input().split())
popular = []
for _ in range(N):
    popular.append(list(map(int, input().split())))
visited = [[-1]*N for _ in range(N)]
union = deque([i,j] for i in range(N) for j in range(i%2,N,2))
count = 0

while 1 :
    queue = deque()
    for _ in range(len(union)):
        i,j = union.popleft()
        if visited[j][i] == count: continue
        visited[j][i] = count
        lands = set([(i,j)])
        people= popular[j][i]
        queue.append((i,j))

        while queue:
            x,y = queue.popleft()
            for i in range(4):
                nx = x+dx[i]
                ny = y+dy[i]

                if 0<=nx<N and 0<=ny<N and visited[ny][nx]!=count:
                    if L<=abs(popular[ny][nx]-popular[y][x])<=R:
                        visited[ny][nx]=count
                        lands.add((nx,ny))
                        people+=popular[ny][nx]
                        queue.append((nx,ny))
        if len(lands)>1:
            avg = people//len(lands)
            for x,y in lands:
                popular[y][x] = avg
                union.append((x,y))

    if union:
        count+=1
    else:
        break
print(count)


import math as _math

import numpy as _np
import pandas as _pd

def cleanText(t):
    #Cleans text from LaTeX equation wrapper ($)
    t = t[1:] if t.startswith('$') else t
    return t[:-1] if t.endswith('$') else t

def findNearestValueIndex(array, value):
    #returns index of nearest element to value in array
    return (_np.abs(_np.asarray(array) - value)).argmin()

def roundToFirstSignifficantDigit(value):
    #returns error rounded to first signifficant digit
    return round(value, -int(_math.floor(_math.log10(abs(value))))) if value != 0 else 0

def roundToError(value, error):
    #returns value rounded to error's first signifficant digit
    s = _np.array(list(str('{0:.1000f}').format(abs(error))))
    if error == 0:
        return value
    elif s[0] == '0':
        d = _np.where(s[2:] != '0')[0][0]
        return round(value, d + 1)
    else:
        error = int(error)
        digits = int(_math.log10(error))+1
        return round(int(value), -(digits))

def latexValuePM(value, error):
    return str(value) + ' $\\pm$ ' + str(error)

def createSeriesPanda(values, error = None, label = '$x$', units = None, relativeError = False, separated = False, rounded = True):
    #Returns a panda DataFrame with values and error, formatted according to function params
    pLabel = label + ' (' + units + ')' if units is not None else label
    pErrorLabel = '$\\Delta$ ' + pLabel

    if error is None:
        return _pd.DataFrame(values, columns = [pLabel])
    else:
        col = None
        perrors = [roundToFirstSignifficantDigit(x) for x in error] if rounded else error
        pvalues = [roundToError(values[i], perrors[i]) for i in range(len(values))] if rounded else values
        if separated:
            col = _pd.DataFrame({pLabel: pvalues, pErrorLabel: perrors}, columns = [pLabel, pErrorLabel])
        else:
            col = _pd.DataFrame([latexValuePM(pvalues[i], perrors[i]) for i in range(len(pvalues))], columns = [pLabel])

        if relativeError:
            relErrors = _pd.DataFrame([error[i]/values[i] if values[i] != 0 else '-' for i in range(len(values))], \
                                        columns = ['$\\Delta$ ' + label + ' (rel)'])
            return _pd.concat([col, relErrors], axis = 1, join = 'inner')
        else:
            return col

def R2(x, y, fn):
    average = _np.average(y)
    SSres = _np.sum(_np.array([(y[i] - fn(x[i]))**2 for i in range(len(x))]))
    SStot = _np.sum(_np.array([(point - average)**2 for point in y]))
    return 1 - SSres / SStot


import os
import calculate
from PIL import Image
from model import MyModel
from skimage import io

# s = "(3+657579)/2+7="
def cal(s):
    s+="="
    # print(s)
    stknum= []
    stkope= []
    i = 0
    p = 0
    q = 0
    while 1:
        if p==0:
            #print "i=",i,
            ope = s[i]
            if ope>='0' and ope<='9':
                #print ope
                num = 0
                while s[i] >= '0' and s[i]<= '9':
                    num *= 10
                    num += int(s[i])
                    i =i+1
                    #print "++",
                stknum.append(float(num))
                ope = s[i]
        #print stknum,stkope,
        if len(stkope)==0 or ope == '(' or (stkope[len(stkope)-1] == '(' and ope != ')') :
            #print "kk",
            stkope.append(ope)
        elif (stkope[len(stkope)-1] == '-' or stkope[len(stkope)-1] == '+') and (ope == '*' or ope == '/'):
            stkope.append(ope)
        elif stkope[len(stkope)-1] == '(' and ope == ')':
            stkope.pop()
        else:
            num1 = stknum[len(stknum)-1]
            stknum.pop()
            num2 = stknum[len(stknum)-1]
            stknum.pop()
            val = 0
            if stkope[len(stkope)-1] == '+':
                val = num2+num1
            if stkope[len(stkope)-1] == '-':
                val = num2-num1
            if stkope[len(stkope)-1] == '*':
                val = num2 * num1
            if stkope[len(stkope)-1] == '/':
                val = num2 / num1
            stkope.pop()
            stknum.append(val)
            i =i-1

            if ope == '=':
                if len(stkope)==0:
                    #print "!!!!!",
                    print ('%s %.3f'%(s,stknum[len(stknum)-1]) )
                    stknum.pop()
                    q = 1
                else:
                    p = 1
        #print stknum,stkope
        i = i+1
        if i==len(s):
            break
        if q==1:
            break
# cal(s)

def splitimage(src, dstpath):
    mystr=''
    img = Image.open(src)
    w, h = img.size
    colnum = int(w/100)
    # print(colnum)
    rownum = 1
    if rownum <= h and colnum <= w:
        # print('Original image info: %sx%s, %s, %s' % (w, h, img.format, img.mode))
        print('开始识别, 请稍候...')

        s = os.path.split(src)
        if dstpath == '':
            dstpath = s[0]
        fn = s[1].split('.')
        basename = fn[0]
        ext = fn[-1]

        num = 0
        rowheight = h // rownum
        colwidth = w // colnum
        for r in range(rownum):
            for c in range(colnum):
                box = (c * colwidth, r * rowheight, (c + 1) * colwidth, (r + 1) * rowheight)
                img.crop(box).save(os.path.join(dstpath, basename + '_' + str(num) + '.' + ext))
                infile = basename + '_' + str(num) + '.' + ext
                # print(infile)
                outfile = os.path.splitext(infile)[0] + ".jpg"
                try:
                    Image.open(infile).save(outfile)
                    model = MyModel()
                    singleImage = io.imread(outfile, as_grey=True)
                    # print(model.recognize(singleImage))
                    mystr+=model.recognize(singleImage)
                except IOError:
                    print("load....")

                num = num + 1

        print('图片识别完毕，共识别出 %s 个字符' % num)
    else:
        print('不合法的行列切割参数！')
    cal(mystr)

src = input('请输入图片文件路径：')
if os.path.isfile(src):
    dstpath =''
    if (dstpath == '') or os.path.exists(dstpath):
        splitimage(src, dstpath)

    # else:
    #     print('图片输出目录 %s 不存在！' % dstpath)
else:
    print('图片文件 %s 不存在！' % src)


'''
Usage:
    python get_IHME_forecasts_for_TMC.py --market_share [0.03]
'''

import pandas as pd
import argparse

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('--market_share', default='0.03')
    args = parser.parse_args()
    market_share = float(args.market_share)

    df = pd.read_csv("IHME_forecasts/Hospitalization_all_locs.csv")
    mass = df.loc[df['location_name'] == 'Massachusetts']

    for interval in ['mean', 'lower', 'upper']:
        adict = {}
        adict['date'] = mass['date']
        adict['n_InGeneralWard'] = (mass['allbed_' + interval] - mass['ICUbed_' + interval])*market_share
        adict['n_InICU'] = (mass['ICUbed_' + interval])*market_share
        adict['n_OnVentInICU'] = (mass['InvVen_' + interval])*market_share
        adict['n_TERMINAL'] = (mass['deaths_' + interval])*market_share
        df = pd.DataFrame(adict)
        df.to_csv("IHME_forecasts/IHME-for-TMC-mktshare=%.3f-%s.csv" % (market_share, interval))


from django.shortcuts import render
from classroom.models import  Subject
from accounts.models import Student, Teacher
# Create your views here.
def home(request):
    studentCount = Student.objects.all().count()
    subjectCount = Subject.objects.all().count()
    teacherCount = Teacher.objects.all().count()

    context = {
        'studentCount' : studentCount,
        'subjectCount' : subjectCount,
        'teacherCount' : teacherCount,
    }

    return render(request, 'index.html', context)


###
# Michael Buffone
# March 29th, 2021
# COSC4106 Assignment 4 : Question 2
#
# Recursive problem involving calculating the max value for a work schedule
###

def solve(workSchedule, n):
    # Base case 1: the "none" case
    if(n == 0):
        return 0

    # Base case 2: return the better job if for low / high stress
    if(n == 1):
        return max(workSchedule[0][n-1], workSchedule[1][n-1])

    return max(workSchedule[0][n-1] + solve(workSchedule, n-1), workSchedule[1][n-1] + solve(workSchedule, n-2))

def main():
    print("-----")

    n = 4
    workSchedule = [[10, 1, 10, 10],
                    [5, 50, 5, 1]]

    print("The best value of the work schedule:\n", workSchedule[0], "\n", workSchedule[1], "\nis:", solve(workSchedule, n))

    print("-----")

if __name__ == "__main__":
    main()


import pygame
import random

# Setting up constants
WIDTH, HEIGHT = 800, 600
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
GREEN = (0, 255, 0)
RED = (255, 0, 0)
BLUE = (0, 0, 255)
GRAY = (211, 211, 211)

# Initialize Pygame
pygame.init()
programIcon = pygame.image.load('assets/icon.png')
pygame.display.set_icon(programIcon)
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Maze Generator")

# Grid settings
GRID_SIZE = 20
GRID_WIDTH = WIDTH // GRID_SIZE
GRID_HEIGHT = HEIGHT // GRID_SIZE
DIRS = [(0, -1), (1, 0), (0, 1), (-1, 0)]

# Initialize the maze
maze = [[1 for _ in range(GRID_WIDTH)] for _ in range(GRID_HEIGHT)]

def is_valid(x, y):
    return 0 <= x < GRID_WIDTH and 0 <= y < GRID_HEIGHT

def generate_maze(x, y):
    maze[y][x] = 0
    random.shuffle(DIRS)
    for dx, dy in DIRS:
        nx, ny = x + dx * 2, y + dy * 2
        if is_valid(nx, ny) and maze[ny][nx] == 1:
            maze[y + dy][x + dx] = 0
            generate_maze(nx, ny)

generate_maze(0, 0)

# Start and finish positions
start_x, start_y = 0, 0
finish_x, finish_y = GRID_WIDTH - 2, GRID_HEIGHT - 2

# Player position
player_x, player_y = start_x, start_y

def move_player(dx, dy):
    global player_x, player_y, has_moved, completed
    new_x, new_y = player_x + dx, player_y + dy
    if is_valid(new_x, new_y) and maze[new_y][new_x] == 0:
        player_x, player_y = new_x, new_y
        has_moved = True  # Update the flag when the player moves
        # Check for completion
        if player_x == finish_x and player_y == finish_y:
            completed = True

def get_possible_moves_and_highlight(x, y):
    moves = []
    for dx, dy in DIRS:
        nx, ny = x + dx, y + dy
        if is_valid(nx, ny) and maze[ny][nx] == 0:
            if dx == 1: moves.append("Right")
            if dx == -1: moves.append("Left")
            if dy == 1: moves.append("Down")
            if dy == -1: moves.append("Up")
            # Highlight possible moves
            pygame.draw.rect(screen, GRAY, (nx * GRID_SIZE, ny * GRID_SIZE, GRID_SIZE, GRID_SIZE))
    return moves

# Additional flags
has_moved = True
completion_message_printed = False
possible_moves = []
completed = False

# Main game loop
running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        elif not completed and event.type == pygame.KEYDOWN:
            if event.key == pygame.K_w:
                move_player(0, -1)
            elif event.key == pygame.K_s:
                move_player(0, 1)
            elif event.key == pygame.K_a:
                move_player(-1, 0)
            elif event.key == pygame.K_d:
                move_player(1, 0)

    screen.fill(WHITE)
    # Draw the maze
    for y in range(GRID_HEIGHT):
        for x in range(GRID_WIDTH):
            if maze[y][x] == 1:
                pygame.draw.rect(screen, BLACK, (x * GRID_SIZE, y * GRID_SIZE, GRID_SIZE, GRID_SIZE))

    # Draw start and finish points
    pygame.draw.rect(screen, GREEN, (start_x * GRID_SIZE, start_y * GRID_SIZE, GRID_SIZE, GRID_SIZE))
    pygame.draw.rect(screen, GREEN, (finish_x * GRID_SIZE, finish_y * GRID_SIZE, GRID_SIZE, GRID_SIZE))

    # Draw the player
    pygame.draw.rect(screen, RED, (player_x * GRID_SIZE, player_y * GRID_SIZE, GRID_SIZE, GRID_SIZE))

    if not completed:
        if has_moved:
            # Highlight and get possible moves only if player has moved
            possible_moves = get_possible_moves_and_highlight(player_x, player_y)
            print("Possible Moves:", possible_moves)
            has_moved = False
        else:
            # Highlight possible moves without updating the list
            get_possible_moves_and_highlight(player_x, player_y)

    if completed:
        if not completion_message_printed:
            print("Congratulations! You've completed the maze!")
            completion_message_printed = True
        # Display completion message
        font = pygame.font.Font(None, 60)
        text = font.render("Congratulations! Maze Completed!", True, RED)
        text_rect = text.get_rect(center=(WIDTH // 2, HEIGHT // 2))
        screen.blit(text, text_rect)

    pygame.display.flip()

pygame.quit()


import tkinter as tk
from PIL import Image,ImageTk
from tkinter import Toplevel
import numpy as np

length = 80
side_margin = 50
top_margin = 80
line_thickness = 2
font_style = "Times New Roman"
box_top_margin = top_margin + 10

def get_min_tuple(tuple_list):
    min_cell = list(map(min, zip(*tuple_list)))
    min_cell = (min_cell[0], min_cell[1])
    if min_cell not in tuple_list:
        min_cell = tuple_list[0]
        for index, cell in enumerate(tuple_list):
            if index == len(tuple_list) - 1:
                break

            next_cell = tuple_list[index + 1]
            if next_cell[1] < min_cell[1]:
                min_cell = next_cell

            elif next_cell[1] == min_cell[1]:
                if next_cell[0] < min_cell[0]:
                    min_cell = next_cell
    return min_cell

def prepare_solution(solutions, board_size):
    sol = np.zeros((board_size, board_size), dtype=np.int8)
    for element in solutions:
        values = solutions[element]
        for i, e in enumerate(element):
            i1 = e[0] - 1
            i2 = e[1] - 1
            sol[i2][i1] = values[i]
    return sol

def draw_group_condition(canvas, cell, op, number):
    number = '(' + str(number) + ')'
    op = '' if(op == '.') else op
    txt = number + ' ' + op
    offset = 10 if (len(number)<3) else 16
    top_offset = offset - 2 if (len(number)<3) else offset - 5
    col = cell[0] - 1
    row = cell[1] - 1
    r_start = box_top_margin + row * length
    start = side_margin + col * length
    canvas.create_text(3 + offset + start, top_offset + r_start, text = txt, font=(font_style, 10), fill="red")

def draw_cell_bh_line(canvas, cell):
    col = cell[0]
    row = cell[1]
    # bottom horizontal line
    x1 = side_margin + (col-1) * length
    x2 = x1 + length
    y1 = box_top_margin + row * length
    canvas.create_line(x1, y1, x2, y1, fill="black", width=line_thickness)

def draw_cell_rv_line(canvas, cell):
    col = cell[0]
    row = cell[1]
    # right vertical line
    x1 = side_margin + col * length
    y1 = box_top_margin + (row-1) * length
    y2 = y1 + length
    canvas.create_line(x1, y1, x1, y2, fill="black", width=line_thickness)

def draw_groups_borders(canvas, groups, board_size):
    for g in groups:
        cells_list = g[0]
        min_cell = get_min_tuple(cells_list)
        op = g[1]
        num = g[2]
        draw_group_condition(canvas, min_cell, op, num)
        if len(cells_list) == 1:
            draw_cell_bh_line(canvas, cells_list[0])
            draw_cell_rv_line(canvas, cells_list[0])
        else:
            for cell in cells_list:
                # skip the last cell
                if cell == (board_size, board_size):
                    continue
                # check if the right next cell is not in the group of the current cell, then draw vertical line
                # and make sure that this is not a cell in the last column
                right_next_cell = (cell[0]+1, cell[1])
                # right_next_cell[0] += 1
                if cell[0] != board_size and right_next_cell not in cells_list:
                    draw_cell_rv_line(canvas, cell)

                # check if the below cell is in the group of the current cell, then draw horizontal line
                # and make sure that this is not a cell in the last row
                below_cell = (cell[0], cell[1]+1)
                if cell[1] != board_size and below_cell not in cells_list:
                    draw_cell_bh_line(canvas, cell)

def draw_border_grid(canvas, board_size):
    ## draw thick four lines around the whole grid
    box_top_margin = top_margin + 10
    size = board_size * length
    # top line
    canvas.create_line(side_margin, box_top_margin, side_margin + size, box_top_margin, fill="black", width=line_thickness)
    # bottom line
    canvas.create_line(side_margin, size + box_top_margin, side_margin + size, size + box_top_margin, fill="black", width=line_thickness)
    # left line
    canvas.create_line(side_margin, box_top_margin, side_margin, size + box_top_margin, fill="black", width=line_thickness)
    # right line
    canvas.create_line(size + side_margin, box_top_margin, size + side_margin, size + box_top_margin, fill="black", width=line_thickness)

def create_grid(canvas, board_size, sol_arr):
    for row in range(board_size):
        r_start = box_top_margin + row * length
        r_end = box_top_margin + (row+1) * length
        for i in range(board_size):
            start = side_margin + i * length
            end = side_margin + (i+1) * length
            canvas.create_rectangle(start, r_start, end, r_end, outline="grey", fill="white")
            ## write numbers inside the cell
            offset = length/2
            txt = str(sol_arr[row][i])
            canvas.create_text(offset + start, offset + r_start, text = txt, font=(font_style, 20), fill="black")

def solve(window, board_size, groups, solutions):
    # Create board
    size = board_size * length
    width = 2 * side_margin + size
    height = 2 * top_margin + size
    geometry = str(width) + "x" + str(height)
    board = Toplevel(window)
    board.title("Solution Board "+ str(board_size) + "x"+ str(board_size))
    board.iconphoto(False, tk.PhotoImage(file='assets/logo.png'))
    board.geometry(geometry)
    board.resizable(False, False)

    if board_size > 8:
        board.resizable(True, True)
        v = tk.Scrollbar(board, orient='vertical')
        v.pack(side = tk.RIGHT, fill = tk.Y)

    # Creating a canvas to put all the widgets inside
    canvas = tk.Canvas(board, width = 600, height = 360)
    canvas.pack(fill='both', expand = True)

    # Load logo image in the script
    img= (Image.open("assets/wide_logo.png"))
    #Resize the Image using resize method
    resized_logo= img.resize((200,33), Image.ANTIALIAS)
    logo= ImageTk.PhotoImage(resized_logo)
    canvas.create_image(width/2, 40, image=logo, anchor = "center")

    # Now Solve
    sol_arr = prepare_solution(solutions, board_size)
    create_grid(canvas, board_size, sol_arr)
    draw_border_grid(canvas, board_size)
    draw_groups_borders(canvas, groups, board_size)
    board.mainloop()
    return canvas, board

# def solve(window, board_size, groups, solutions):
#     canvas, board = create_board_new_window(window, board_size)
#     sol_arr = prepare_solution(solutions, board_size)
#     create_grid(canvas, board_size, sol_arr)
#     draw_border_grid(canvas, board_size)
#     draw_groups_borders(canvas, groups, board_size)
#     board.mainloop()


# import os
# import concurrent.futures
# import cv2
# import numpy as np

# # Define the directory path
# dir_path = 'data'

# # Initialize an empty list to store the file contents
# file_contents = []
# img1 = cv2.imread('image_not_available.jpg')
# # Loop through all the files in the directory and its subdirectories
# for root, dirs, files in os.walk(dir_path):
#     for file in files:
#         img2 = cv2.imread(os.path.join(root, file))
#         try:
#             mse = np.mean((img1 - img2) ** 2)
#             if mse < 10:
#                 print("The images are similar")
#             else:
#                 print("The images are different")
#         except ValueError:
#             pass

import os
import concurrent.futures
import cv2
import numpy as np
from PIL import Image

# Define the directory path
dir_path = '../data'

# Initialize an empty list to store the file contents
file_contents = []
img1 = cv2.imread('image_not_available.jpg')

# Define a function to compare two images
def compare_images(img2, loc):
    try:
        mse = np.mean((img1 - img2) ** 2)
        if mse < 10:
            os.remove(loc)
            print("deleted, score: ", str(mse))
        else:
            print("The images are different")
    except ValueError:
        pass

def remove_mp4(img2):
    imgval = img2[:-4]
    img2_name = imgval.split("_")
    if "mp4" == img2_name[-1] or "gif" == img2_name[-1]:
        os.remove(img2)
        print("deleted mp4")

def corrupted_img(img2):
    try:
        with Image.open(img2) as img:
            img.verify()
    except Exception as e:
        print("damn")
    # except (IOError, SyntaxError) as e:
    #     os.remove(img2)
    #     print("deleted corrupted image")

# 0 - COMPARE IMAGE DELETION ACC TO IMGUR TEMPLATE
# 1 - MP4, GIF DELETION
# 2 - CORRUPTED IMAGE DELETION
flag = 2

# Loop through all the files in the directory and its subdirectories
with concurrent.futures.ThreadPoolExecutor(max_workers=50) as executor:
    for root, dirs, files in os.walk(dir_path):
        print("Hello")
        for file in files:
            if flag == 0:
                img2 = cv2.imread(os.path.join(root, file))
                loc = os.path.join(root, file)
                executor.submit(compare_images, img2, loc)
            elif flag == 1:
                img2 = os.path.join(root, file)
                executor.submit(remove_mp4, img2)
            elif flag == 2:
                img2 = os.path.join(root, file)
                executor.submit(corrupted_img, img2)


n, k = map(int, input().split())
c = list(map(int, input().split()))

# dict = {}
# r = 0
# ans = 0
# for l in range(n):
#     pre_r = r
#     while(r < n and not c[r] in dict):
#         dict[c[r]] = 1
#         r += 1
#     if pre_r != r:
#         dict[c[r]] += 1
#     ans = max(ans, len(dict))
#     dict[c[l]] -= 1
#     if dict[c[l]] == 0:
#         del dict[c[l]]
# if ans < k:
#     print(ans)
# else:
#     print(k)

# s = set()
# ans = 0
# for i in range(n-k):
#     for j in range(i,i+k):
#         s.add(c[j])
#     ans = max(ans, len(s))

# print(ans)

r = 0
dict = {}
ans = 0
for l in range(n):
    while(r < n and r - l + 1<= k):
        if c[r] in dict:
            dict[c[r]] += 1
        else:
            dict[c[r]] = 1
        r += 1
    ans = max(ans, len(dict))
    dict[c[l]] -= 1
    if dict[c[l]] == 0:
        del dict[c[l]]

print(ans)


# -*- coding: utf-8 -*-
"""
This files makes up the main point of the backend of the system

Created on Tue Dec  3 18:02:46 2019

@authors: Basem Rizk, Ibram Medhat, Steven Nassef
"""

# from schedule_parser import ScheduleParser
from schedule_parser_with_teachers import ScheduleParserWithTeachers
from query_formater import QueryFormater
from pyswip import Prolog

parser = ScheduleParserWithTeachers(filename="MET_Winter19_schedule_31131.xlsx",
                                    teachers_filename="modifiedSchedule2.xlsx",
                                    list_of_discarded_subjects=['ae','as',
                                                                'en', 'de',
                                                                'physics',
                                                                'embedded systems',
                                                                'video & audio'])

# hadwa pasha is teaching video-and-audio-lab, and csen-lab at the same time
days_schedules, sheet_names, headers = parser.parse_schedule()
teachers_schedules = parser.parse_teachers_schedules()
all_slots = parser.listify_slots()
query_formater = QueryFormater()
all_slots = query_formater.clean_formatted_slots(all_slots)

# parser.convert_to_excel(all_slots)
# to_json_fixture(all_slots)

all_slots_digitized = query_formater.digitize(all_slots)

holidays = [0, 1]
group = "5 csen i"
compensation_slots = query_formater.get_holiday_to_compensate(all_slots,
                                                              specific_group=None,
                                                              holidays=holidays,
                                                              limit=20,
                                                              verbose=True)

query_statement = query_formater.create_query(all_slots_digitized,
                                              compensation_slots,
                                              holidays)

limit = 2
print("INIT PROLOG")
prolog = Prolog()
prolog.consult("constraint_based_approach.pl")
query_answers = prolog.query(query_statement)
num_of_sols = 0
for soln in prolog.query(query_statement):
    num_of_sols += 1
    print("Solution " + str(num_of_sols) + " :: "  + str(soln))
    if limit == num_of_sols:
        break
print("END PROLOG")

def sample_weekson_dict(query_formater, all_slots):
    all_groups = query_formater.get_all_groups(all_slots)
    weekson_dict = {}
    for group in list(all_groups):
        if "1engineering" in group:
            weekson_dict[group] = [0] + [i for i in range(3, 15)]
        else:
            weekson_dict[group] = [0] + [i for i in range(1, 13)]
    return weekson_dict

def to_json_fixture(query_formater, all_slots, model_name = "api.slot"):
    import json

    weekson_dict = sample_weekson_dict(query_formater, all_slots)

    slot_counter = 0
    all_slots_records = []
    for slot in all_slots:
        slot_num, slot_subject, slot_type,\
        slot_group, slot_subgroup, slot_location, slot_teacher = slot

        weekson = weekson_dict[slot_group]
        if not weekson:
            print("WARNING:: HALTING..")
            return

        for slot_week in weekson:
            slot_record = {}
            slot_record["slot_num"] = slot_num
            slot_record["slot_subject"] = slot_subject
            slot_record["slot_type"] = slot_type
            slot_record["slot_group"] = slot_group
            slot_record["slot_subgroup"] = slot_subgroup
            slot_record["slot_location"] = slot_location
            slot_record["slot_teacher"] = slot_teacher
            slot_record["slot_week"] = slot_week
    #        slot_record = json.dumps(slot_record)
            # print(slot_record)

            db_record = {}
            db_record["model"] = model_name
            slot_counter += 1
            db_record["pk"] = slot_counter
            db_record["fields"] = slot_record
    #        db_record = json.dumps(db_record)
            all_slots_records.append(db_record)
            # print(db_record)

    all_slots_records = json.dumps(all_slots_records)
    with open("schedule_slots_fixture.json", "w") as f:
        f.write(all_slots_records)

#
with open("query_example.txt", "w") as f:
    query_rest = query_statement
    while(True):
        limit = 1000
        if len(query_rest) < limit:
            break
        f.write(query_rest[:limit])
        f.write("\n")
        query_rest = query_rest[limit:]
    f.write(query_rest)


import run_umls_classifier_2 as ruc
from tqdm import tqdm
import csv
from absl import app, flags,logging
import os
from collections import defaultdict
FLAGS = flags.FLAGS

def count_lines(filein):
    'Count total number of lines present in a file, helps with presenting correct loading bar via tqdm'
    return sum(1 for line in open(filein))

def gen_mrc_atom(mrc_atoms_fp, ulms_fp,id):
    print('in gen_mrc_atoms...')
    """Given mrconso_master file, converts to mrc_atoms dictionary where key = aui_id, value = CUI,LUI, SCUI,SG, STR, ID

    Args:
        mrc_atoms_fp (string): filepath where you want to store mrc_atoms dictionary
        ulms_fp (string): mrconso_master filepath
        id (int): integer to put as unique ID

    Returns:
        dict: key is AUI and value is dictionary containing CUI, LUI, SCUI, SG, STR, ID
        int: last unused integer for ID
    """
    if(os.path.isfile(mrc_atoms_fp)):
        logging.info('MRC_ATOMS found')
        return ruc.load_pickle(mrc_atoms_fp), id
    else:
        aui_dict = dict()
        logging.info('generating MRC_ATOM...')
        with open(ulms_fp, 'r') as f:
            reader = csv.DictReader(f, fieldnames=FLAGS.mrconso_master_fields, delimiter=FLAGS.delimiter)
            with tqdm(total = count_lines(ulms_fp)) as pbar:
                for idx,row in enumerate(reader):
                    pbar.update(1)
                    aui_dict[row['AUI']] = {'CUI': row['CUI'], 'LUI':row['LUI'], 'SCUI': row['SCUI'], 'SG':row['SG'], 'STR': row['STR'], 'ID': id}
                    id += 1

        #euc_test_dict(aui_dict) #save for unit testing
        ruc.dump_pickle(aui_dict, mrc_atoms_fp)
        return aui_dict, id

def compare(ab_mrc_atoms, aa_mrc_atoms, paths):
    """Takes in mrc_atoms dictionary and finds which auis intersect and which are unique to 2020AB, stores multiple dicts

    Args:
        aa_mrc_atoms (dict): mrc_atoms for UMLS version 2020AA
        ab_mrc_atoms (dict): mrc_atoms for UMLS version 2020AB
        intersect_id2aui_pickle_fp (string): filepath to write dictionary of auis present in both 2020AA and 2020AB, key = (int) id , value = aui id
        unique_id2aui_pickle_fp (string): filepath of dictionary of auis unique to 2020AB, key = (int) id, value = aui_id
        intersect_aui2id_pickle_fp (string): filepath of dictionary where key = aui_id, value = (int) id
        unique_aui2id_pickle_fp (string): filepath of dictionary of auis unique to 2020AB, key = aui_id, value = (int) id
    """
    intersect_id2aui = dict()
    unique_id2aui = dict()

    intersect_aui2id = dict()
    unique_aui2id = dict()

    intersect_sg2id = defaultdict(list)
    unique_sg2id = defaultdict(list)
    aui_info = dict()
    for aui, row in ab_mrc_atoms.items():
        temp_dict = {'AUI': aui, 'CUI': row['CUI'], "SG": row["SG"]}

        if aui in aa_mrc_atoms:
            intersect_id2aui[row['ID']] = aui
            intersect_aui2id[aui] = row['ID']
            sg = row["SG"].split(",")[0]
            if FLAGS.use_sg:
                intersect_sg2id[sg].append(row['ID'])
        else:
            unique_id2aui[row['ID']] = aui
            unique_aui2id[aui] = row['ID']
            if FLAGS.use_sg:
                unique_sg2id[sg].append(row['ID'])
                temp_dict["IDX"] = len(unique_sg2id[sg]) - 1
        aui_info[row["ID"]] = temp_dict

    logging.info('generating intersect, unique_terms pickles...')
    ruc.dump_pickle(intersect_id2aui, paths['intersect_id2aui_pickle_fp'])
    ruc.dump_pickle(intersect_aui2id, paths['intersect_aui2id_pickle_fp'])
    ruc.dump_pickle(unique_id2aui, paths['unique_id2aui_pickle_fp'])
    ruc.dump_pickle(unique_aui2id, paths['unique_aui2id_pickle_fp'])
    ruc.dump_pickle(aui_info, paths['aui_info_fp'])
    if FLAGS.use_sg:
        ruc.dump_pickle(unique_sg2id, paths['unique_sg2id_pickle_fp'])
        ruc.dump_pickle(intersect_sg2id, paths['intersect_sg2id_pickle_fp'])

def gen_intersect_unique(paths, logger):
     global logging
     logging = logger
     ruc.logger = logger
     aa_mrc_atoms, end_id = gen_mrc_atom(paths['aa_mrc_atoms_fp'], paths['aa_umls_fp'],0)
     ab_mrc_atoms, _ = gen_mrc_atom(paths['ab_mrc_atoms_fp'], paths['ab_umls_fp'],end_id)
     compare(ab_mrc_atoms, aa_mrc_atoms, paths)