import argparse
import datetime
import json
import os
from itertools import zip_longest
from pathlib import Path
from typing import List, Optional, Tuple

import gpxpy
from rich import box

from hiking.import_export import JSON_IMPORT_EXAMPLE
from hiking.models import Hike
from hiking.utils import DATA_HOME, DEFAULT_BOX_STYLE, SlimDateRange

# TODO: find a way to auto-detect this from rich
BOX_FORMATS = [
    "ASCII",
    "ASCII2",
    "ASCII_DOUBLE_HEAD",
    "SQUARE",
    "SQUARE_DOUBLE_HEAD",
    "MINIMAL",
    "MINIMAL_HEAVY_HEAD",
    "MINIMAL_DOUBLE_HEAD",
    "SIMPLE",
    "SIMPLE_HEAD",
    "SIMPLE_HEAVY",
    "HORIZONTALS",
    "ROUNDED",
    "HEAVY",
    "HEAVY_EDGE",
    "HEAVY_HEAD",
    "DOUBLE",
    "DOUBLE_EDGE",
    "MARKDOWN",
]

def get_valid_fields_for_args(exclude: Optional[List] = None):
    exclude = exclude or []
    return [
        field.info["name"]
        for field in Hike.FIELDS
        if field.info["data_view"] and field.info["name"] not in exclude
    ]

class DateRangeType:
    description = (
        "Only include hikes contained in provided daterange (default: all hikes)"
    )
    examples = (
        "Valid examples:\n"
        "1970-01-01\n"
        "1970-01-01/1970-02-01\n"
        "1970-01-01/ (all hikes from start date)\n"
        "/1970-01-01 (all hikes until end date)"
    )
    help = f"{description}\n{examples}"

    def __call__(self, raw: str, *args, **kwargs):
        start = end = raw
        splitted = raw.split("/")
        if len(splitted) == 2 and all(splitted):
            start, end = splitted
        elif start.endswith("/"):
            start = start.rstrip("/")
            end = None
        elif end.startswith("/"):
            end = end.lstrip("/")
            start = None

        try:
            start = (
                datetime.datetime.strptime(start, "%Y-%m-%d").date()
                if start
                else datetime.date.min
            )
            end = (
                datetime.datetime.strptime(end, "%Y-%m-%d").date()
                if end
                else datetime.date.max
            )
        except ValueError as e:
            raise argparse.ArgumentTypeError(f"{e.args[0]}\n{self.examples}")
        return SlimDateRange(start, end)

class WritableDirPathType:
    def __call__(self, raw: str, *args, **kwargs):
        directory = Path(raw)
        if (
            not directory.exists()
            or not directory.is_dir()
            or not os.access(directory, os.W_OK)
        ):
            raise argparse.ArgumentTypeError(
                f'Cannot write to directory: "{directory.absolute()}". '
                f"Make sure it exists and is writable."
            )
        return directory

class GPXFileType(argparse.FileType):
    def __call__(self, *args, **kwargs):
        file = super().__call__(*args, **kwargs)
        try:
            gpx_xml = file.read()
            gpxpy.parse(gpx_xml)
        except Exception as e:
            raise argparse.ArgumentTypeError(f"Cannot read *.gpx file: {str(e)}")
        return gpx_xml

class JsonFileType(argparse.FileType):
    def __call__(self, *args, **kwargs):
        file = super().__call__(*args, **kwargs)
        try:
            data = json.load(file)
        except Exception as e:
            raise argparse.ArgumentTypeError(f"Cannot read *.json file: {str(e)}")
        return data

def validate_order_key(value: str) -> Tuple[str, bool]:
    reverse = False
    if value.startswith("-"):
        reverse = True
        value = value.lstrip("-")
    if value not in get_valid_fields_for_args():
        raise argparse.ArgumentTypeError("Invalid order_key")
    return value, reverse

def validate_plot(value: str) -> Tuple[str, str]:
    try:
        x, y = tuple(value.split(","))
        for i in x, y:
            assert i in get_valid_fields_for_args(["name"])
        return x, y
    except (ValueError, AssertionError):
        raise argparse.ArgumentTypeError("plot")

def validate_table_style(value: str) -> Tuple[str, str]:
    try:
        box_style = getattr(box, value.upper())
    except AttributeError:
        raise argparse.ArgumentTypeError("Invalid table-style")
    return box_style

def set_default_subparser(
    parser: argparse.ArgumentParser, default_subcommand: str, raw_args: List[str]
):
    subparser_found = False
    for arg in raw_args:
        if arg in ["-h", "--help"]:  # pragma: no cover
            break
    else:
        for x in parser._subparsers._actions:
            if not isinstance(x, argparse._SubParsersAction):
                continue
            for sp_name in x._name_parser_map.keys():
                if sp_name in raw_args:
                    subparser_found = True
        if not subparser_found:
            raw_args.insert(0, default_subcommand)

def parse_arguments(raw_args: List[str]) -> argparse.Namespace:
    """
    Parse all arguments.
    """

    def format_list(data: List[str]):
        data.sort()
        col_1 = data[: int(round(len(data) / 2))]
        col_2 = data[int(round(len(data) / 2)) :]
        table_data = list(zip_longest(col_1, col_2, fillvalue=""))
        longest = 0
        for i in table_data:
            if len(i[0]) > longest:
                longest = len(i[0])
        result = [f"{i[0].ljust(longest)}{' ' * 5}{i[1]}" for i in table_data]
        return "\n".join(result)

    parser = argparse.ArgumentParser(
        formatter_class=argparse.RawTextHelpFormatter, prog="hiking"
    )

    debug_arg_dict = {
        "help": "Show debug information (log queries)",
        "action": "store_true",
    }

    subparsers = parser.add_subparsers(dest="command")

    show = subparsers.add_parser(
        "show",
        help="Show hike(s) (default)",
        description="Show hike(s) (default)",
        formatter_class=argparse.RawTextHelpFormatter,
    )

    show.add_argument(
        "ids",
        metavar="ID",
        help="Hike ID",
        nargs="*",
        type=int,
    )

    show.add_argument(
        "-d",
        "--daterange",
        help=DateRangeType.help,
        type=DateRangeType(),
        default=SlimDateRange(datetime.date.min, datetime.date.max),
    )

    show.add_argument(
        "-s",
        "--search",
        help="Search for text in name and body (case insensitive)",
        type=str,
    )

    show.add_argument(
        "-t",
        "--table-style",
        help=(
            "Table format style (default: simple)\n"
            f"Available options:\n{format_list(BOX_FORMATS)}"
        ),
        default=DEFAULT_BOX_STYLE,
        type=validate_table_style,
    )

    show.add_argument(
        "-o",
        "--order-key",
        help=(
            'Key to use for hike sorting. To reverse, prepend with "-".\n'
            "Available options:\n"
            f"{format_list(get_valid_fields_for_args())}"
        ),
        default=("date", False),
        type=validate_order_key,
    )

    show.add_argument(
        "--plot",
        help=(
            "Fields to plot in a graph.\n"
            "*experimental*\n"
            "Example:\n"
            '"date,distance"\n'
            "Available options:\n"
            f"{format_list(get_valid_fields_for_args(exclude=['name']))}"
        ),
        default=(),
        type=validate_plot,
    )

    show.add_argument("--debug", **debug_arg_dict)

    create = subparsers.add_parser(
        "create",
        help="Create a new record",
        description="Create a new record.",
        formatter_class=argparse.RawTextHelpFormatter,
    )

    create.add_argument(
        "--gpx",
        metavar="GPX_FILE",
        type=GPXFileType("r"),
        help="Import from *.gpx-file",
    )

    create.add_argument("--debug", **debug_arg_dict)

    edit = subparsers.add_parser(
        "edit",
        help="Edit a record",
        description="Edit a record.",
        formatter_class=argparse.RawTextHelpFormatter,
    )

    edit.add_argument(
        "id",
        metavar="ID",
        help="Hike ID",
        type=int,
    )

    edit.add_argument(
        "--gpx",
        metavar="GPX_FILE",
        type=GPXFileType("r"),
        help="Import from *.gpx-file",
    )

    edit.add_argument("--debug", **debug_arg_dict)

    delete = subparsers.add_parser(
        "delete",
        help="Delete records by ID",
        description="Delete records by ID.",
        formatter_class=argparse.RawTextHelpFormatter,
    )

    delete.add_argument(
        "-f",
        "--force",
        help="Do not ask before deletion",
        action="store_true",
    )

    delete.add_argument(
        "-q",
        "--quiet",
        help="Do not display hikes before deletion",
        action="store_true",
    )

    delete.add_argument(
        "-a",
        "--all",
        help="Delete all hikes",
        action="store_true",
    )

    delete.add_argument(
        "ids",
        metavar="ID",
        help="Hike ID",
        nargs="*",
        type=int,
    )

    delete.add_argument("--debug", **debug_arg_dict)

    _import = subparsers.add_parser(
        "import",
        help="Import records from JSON",
        description=f"Import records from JSON.\nFormat:\n{JSON_IMPORT_EXAMPLE}",
        formatter_class=argparse.RawTextHelpFormatter,
    )

    _import.add_argument(
        "json_data",
        metavar="JSON_FILE",
        help="Path to JSON file",
        type=JsonFileType("r"),
    )

    _import.add_argument("--debug", **debug_arg_dict)

    export = subparsers.add_parser(
        "export",
        help="Export records as JSON and GPX",
        description="Export records as JSON and GPX.",
        formatter_class=argparse.RawTextHelpFormatter,
    )

    export.add_argument(
        "export_dir",
        metavar="EXPORT_DIR",
        help="Path to export directory",
        type=WritableDirPathType(),
    )

    export.add_argument(
        "ids",
        metavar="ID",
        help="Hike ID",
        nargs="*",
        type=int,
    )

    export.add_argument(
        "-d",
        "--daterange",
        help=DateRangeType.help,
        type=DateRangeType(),
        default=SlimDateRange(datetime.date.min, datetime.date.max),
    )

    export.add_argument(
        "-i",
        "--include-ids",
        help='Include IDs in export. Needed for "update", must be omitted for "create"',
        action="store_true",
    )

    export.add_argument("--debug", **debug_arg_dict)

    set_default_subparser(parser, "show", raw_args)

    args = parser.parse_args(raw_args)

    if args.command == "delete" and not args.ids and not args.all:
        raise parser.error("IDs or --all must be provided")
    elif args.command == "delete" and args.ids and args.all:
        raise parser.error("Ambiguous argument: IDs and --all provided")

    try:
        WritableDirPathType()(DATA_HOME.parent)
    except argparse.ArgumentTypeError:
        raise parser.error(f"Cannot write to user data director: {DATA_HOME.parent}")

    return args


#!/usr/bin/python
# -*- coding: UTF-8 -*-
# from multiprocessing.pool import ThreadPool
import threading
from time import sleep
import requests
from selenium import webdriver
from bs4 import BeautifulSoup
import output as op
class FlaskScraper:

	# groupName: webUrl
	dictOfNameAndWebUrl = {}

	# weburl: webCont
	dictOfNameAndWebCont = {}

	# weburl: webCOnt without mark
	dictOfNameAndWebContWithoutMk = {}

	# initialize
	def __init__(self, chatBot, dictOfNameAndWebsite):
		for key in dictOfNameAndWebsite:
			web = dictOfNameAndWebsite[key]
			if(key in FlaskScraper.dictOfNameAndWebUrl.keys()):
				FlaskScraper.dictOfNameAndWebUrl[key] = web
				# if(not web in FlaskScraper.dictOfNameAndWebCont.keys()):
				FlaskScraper.dictOfNameAndWebCont.setdefault(web, ['null'])
				FlaskScraper.dictOfNameAndWebContWithoutMk.setdefault(web, ['null'])
				# FlaskScraper.dictOfNameAndWebCont.setdefault(web, self.ScraperFromFlaskByCheck(key))
			else:
				FlaskScraper.dictOfNameAndWebUrl.setdefault(key, web)
				# if(not web in FlaskScraper.dictOfNameAndWebCont.keys()):
				FlaskScraper.dictOfNameAndWebCont.setdefault(web, ['null'])
				FlaskScraper.dictOfNameAndWebContWithoutMk.setdefault(web, ['null'])
				# FlaskScraper.dictOfNameAndWebCont.setdefault(web, self.ScraperFromFlaskByCheck(key))
				self.MultiClientController(chatBot, {key : web})
		# self.UpdateWebsiteUrl(chatBot, dictOfNameAndWebsite)
		# self.UpdateWebsiteCont(dictOfNameAndWebsite)

	def Scraper(weburl):
		driver = webdriver.Chrome("/usr/local/share/chromedriver")
		driver.get(weburl)
		try:
			driver.find_element_by_xpath("//a[contains(text(),'Show all completed tasks')]").click()
		except:
			pass

		# driver.find_element_by_id()
		# print("------------", driver.page_source)
		sleep(2)
		soup = BeautifulSoup(driver.page_source, "html.parser")
		spanlist = soup.find_all('span', attrs={'class':'best_in_place'})
		driver.quit()
		return spanlist

	# bind group name with url & bind group name with web content
	def UpdateWebsiteUrl(self, chatBot, key, web):
		# for key in incDicOfNameAndWebsite:
		# 	web = incDicOfNameAndWebsite[key]
		# print(1)
		if(web in FlaskScraper.dictOfNameAndWebUrl.values()):
			return "fail"
		# print(2)
		if(key in FlaskScraper.dictOfNameAndWebUrl.keys()):
			FlaskScraper.dictOfNameAndWebUrl[key] = web
			# if(not web in FlaskScraper.dictOfNameAndWebCont.keys()):
			FlaskScraper.dictOfNameAndWebCont.setdefault(web, ['null'])
			FlaskScraper.dictOfNameAndWebContWithoutMk.setdefault(web, ['null'])
			# FlaskScraper.dictOfNameAndWebCont.setdefault(web, self.ScraperFromFlaskByCheck(key))
		else:
			FlaskScraper.dictOfNameAndWebUrl.setdefault(key, web)
			# if(not web in FlaskScraper.dictOfNameAndWebCont.keys()):
			FlaskScraper.dictOfNameAndWebCont.setdefault(web, ['null'])
			FlaskScraper.dictOfNameAndWebContWithoutMk.setdefault(web, ['null'])
			# FlaskScraper.dictOfNameAndWebCont.setdefault(web, self.ScraperFromFlaskByCheck(key))
			self.MultiClientController(chatBot, {key : web})
		return "succeed"

	# multiple clients generator
	def MultiClientController(self, chatBot, nameOfGrp):
		for k in nameOfGrp:
			try:
				thread = threading.Thread(target=ScraperTimeController, args=(k, chatBot, ))
				thread.start()
			except:
				print ("Error: unable to start thread for %s !" %(k))

	# check command
	def ScraperFromFlaskByCheck(self, nameOfGrp):
		# print(dictOfNameAndWebsite.value[0])
		# html = requests.get(dictOfNameAndWebsite.values()[0]).content
		thisKey = FlaskScraper.dictOfNameAndWebUrl[nameOfGrp]
		# html = requests.get(thisKey).content

		# driver.get(thisKey)
		# driver.find_element_by_xpath("//a[contains(text(),'Show all completed tasks')]").click()
		# sleep(2)
		# soup = BeautifulSoup(driver.page_source, "html.parser")
		# spanlist = soup.find_all('span', attrs={'class':'best_in_place'})

		spanlist = FlaskScraper.Scraper(thisKey)

		# print("before")

		MessageWithoutMk, Message = op.ChangeFormatOfOutput(spanlist)
		# print("in")
		if (Message != FlaskScraper.dictOfNameAndWebCont[thisKey]):
			# print("in if")
			FlaskScraper.dictOfNameAndWebCont[thisKey] = Message
			# print("in if 2")
			FlaskScraper.dictOfNameAndWebContWithoutMk[thisKey] = MessageWithoutMk
			# print("in if 3")
		# print("after")

		# Message = []
		# for i in range(1,len(spanlist)):
		# 	checkbox=str(spanlist[i].find_previous_sibling('input'))
		# 	if 'checked' in checkbox:
		# 		Message.append(spanlist[i].text+'-completed')
		# 	else:
		# 		Message.append(spanlist[i].text+'-uncompleted')
		# if (Message != FlaskScraper.dictOfNameAndWebCont[thisKey]):
		# 	FlaskScraper.dictOfNameAndWebCont[thisKey] = Message

		return Message

# time controller, send news to users
def ScraperTimeController(key, chatBot):
	while True:
		weburl = FlaskScraper.dictOfNameAndWebUrl[key]
		Message = ScraperFromFlaskByTime(weburl)
		if(Message != ['null']):
			# News=weburl + '\n' +'Update: \n'
			News = ""
			for strMessage in Message:
				News = News + strMessage + '\n'
			News = News + weburl
			my_friend = chatBot.search(puid=key)[0]
			my_friend.send(News)
		sleep(3)

# listen to the website, return news
def ScraperFromFlaskByTime(weburl):

	spanlist = FlaskScraper.Scraper(weburl)
	print("test1")
	# driver.get(thisKey)
	# driver.find_element_by_xpath("//a[contains(text(),'Show all completed tasks')]").click()
	# sleep(2)
	# soup = BeautifulSoup(driver.page_source, "html.parser")
	# spanlist = soup.find_all('span', attrs={'class':'best_in_place'})

	# html = requests.get(weburl).content
	# soup = BeautifulSoup(html,"html.parser")
	# spanlist = soup.find_all('span',attrs={'class':'best_in_place'})

	MessageWithoutMk, Message = op.ChangeFormatOfOutput(spanlist)
	oldContent = []
	for v in FlaskScraper.dictOfNameAndWebContWithoutMk[weburl]:
		oldContent.append(v)

	# first time to log
	if (FlaskScraper.dictOfNameAndWebCont[weburl] == ['null'] and \
			Message != FlaskScraper.dictOfNameAndWebCont[weburl]):
		FlaskScraper.dictOfNameAndWebCont[weburl] = Message
		FlaskScraper.dictOfNameAndWebContWithoutMk[weburl] = MessageWithoutMk
		return Message
	elif (Message != FlaskScraper.dictOfNameAndWebCont[weburl]):
		print(Message)
		print(MessageWithoutMk)
		print(oldContent)
		print(FlaskScraper.dictOfNameAndWebContWithoutMk[weburl])
		# print("Message",Message)
		# print("FlaskScraper.dictOfNameAndWebCont[weburl])", FlaskScraper.dictOfNameAndWebCont[weburl])
		tmplist = []
		cnt = 0
		for i in range(len(MessageWithoutMk)):
			if MessageWithoutMk[i] in oldContent:
				if Message[i] not in FlaskScraper.dictOfNameAndWebCont[weburl]:
					print("Message[%d]" %(i), Message[i])
					print("oldContent index", oldContent.index(MessageWithoutMk[i]))
					print("oldCOntent", oldContent)
					print("cont",FlaskScraper.dictOfNameAndWebCont[weburl])
					tmplist.append("\u2713 " + MessageWithoutMk[i]) # finished
				oldContent.remove(MessageWithoutMk[i])
				cnt = cnt + 1
			else:
				# print("not in MessageWithoutMk[%d]" %(i), MessageWithoutMk[i])
				# print("oldContent", oldContent)
				# print("tmplist[0]", MessageWithoutMk[i])
				print("--------------------------------")
				tmplist.append("\u2610 " + MessageWithoutMk[i])     # added
		for i in range(len(oldContent)):
			tmplist.append("\u2717 " + oldContent[i])         # delete

		print("final",tmplist)
		if(tmplist != []):
			FlaskScraper.dictOfNameAndWebCont[weburl] = Message
			FlaskScraper.dictOfNameAndWebContWithoutMk[weburl] = MessageWithoutMk
			return tmplist
		else:
			return ['null']
		# cnt = 0

	else:
		return ['null']
	# newContent = []
	# Message = []
	# oldContent = FlaskScraper.dictOfNameAndWebCont[weburl]
	# dictOldContent = {}
	# for cont in oldContent:
	# 	if cont.find('-completed') > 0:
	# 		dictOldContent[cont[:cont.find('-completed')]] ='-completed'
	# 	elif cont.find('-uncompleted') > 0:
	# 		dictOldContent[cont[:cont.find('-uncompleted')]] ='-uncompleted'
	# for i in range(1,len(spanlist)):
	# 	checkbox=str(spanlist[i].find_previous_sibling('input'))
	# 	if 'checked' in checkbox:
	# 		newContent.append(spanlist[i].text+'-completed')
	# 		if spanlist[i].text in dictOldContent.keys():
	# 			if dictOldContent[spanlist[i].text] == '-uncompleted':
	# 				Message.append('completed: '+spanlist[i].text)
	# 			dictOldContent[spanlist[i].text] = '-checked'
	# 		else:
	# 			Message.append('add: '+spanlist[i].text)
	# 	else:
	# 		newContent.append(spanlist[i].text+'-uncompleted')
	# 		if spanlist[i].text in dictOldContent.keys():
	# 			if dictOldContent[spanlist[i].text] == '-completed':
	# 				Message.append('uncompleted: '+spanlist[i].text)
	# 			dictOldContent[spanlist[i].text] = '-checked'
	# 		else:
	# 			Message.append('add: '+spanlist[i].text)
	# for cont in dictOldContent:
	# 	if dictOldContent[cont] != '-checked':
	# 		Message.append('delete: ' + cont)
	# if Message !=[]:
	# 	FlaskScraper.dictOfNameAndWebCont[weburl]=newContent
	# 	return Message
	# else:
	# 	return ['null']


import pyperclip
import re

matchPhone = re.compile(r'''(
                        (\d{3}|\(\d{3}\))   # area code
                        (\s|-|\.)           # separator
                        (\d{3})             # first 3 digits
                        (\s|-|\.)           # separator
                        (\d{4})             # last 4 digits
                        (\s*(ext|x|ext.)\s*(\d{2,5}))? #extension
                        )''', re.VERBOSE)

matchEmail = re.compile(r'''(
                        [a-zA-Z0-9._%+-]+    # address
                        @[a-zA-Z0-9.-]+      # domain name
                        \.(\w*)              # domain suffix
                        )''', re.VERBOSE)

matchURL = re.compile(r'''(
                      (http://|https://)   # prefix
                      (.*)                 # domain name
                      (\.\w{2,})           # suffix
                      )''', re.VERBOSE)

text = pyperclip.paste()

matches = []

for match in matchPhone.findall(text):
    phoneNum = '-'.join([match[1], match[3], match[5]])
    if match[8] != '':
        phoneNum += ' x' + match[8]
    matches.append(phoneNum)

for match in matchEmail.findall(text):
    matches.append(match[0])

for match in matchURL.findall(text):
    matches.append(match[0])

print('\n'.join(matches))
pyperclip.copy('\n'.join(matches))


from os import name
from django.urls import path
from . import views

urlpatterns = [
    path('', views.home, name="home"),
    path('about/', views.about, name="about"),
    path('join_us/', views.join_us, name="join_us"),
    path('hotel_detail/<int:hotel_id>/',
         views.hotel_detail, name="hotel_detail"),
    path('hotel_detail/<int:hotel_id>/<slug:extra>/',
         views.hotel_detail, name="hotel_detail"),
    path('cart/', views.my_cart, name="my_cart"),
    path('cart/plus', views.plus_cart, name="plus_cart"),
    path('cart/minus', views.minus_cart, name="minus_cart"),
    path('verify_payment/', views.verifyPayment, name='verify_payment'),
    path('order/', views.orders, name="order"),
    path('search/', views.search_items, name="search"),
    path('all_hotel/', views.all_hotel, name="all_hotel"),
    path('all_menu/', views.all_menu, name="all_menu"),
    path('health/', views.health, name="health"),
]


# coding=utf8
from validate_email import validate_email

if __name__ == '__main__':
	f = open("stargazers_email.txt", "r")
	emails = f.readlines()
	emails = [line.rstrip('\n') for line in emails]
	valid_email = []

	for i in range(len(emails)):
		is_valid = validate_email(emails[i], verify=True)
		print(is_valid)
		if is_valid == 'True':
			valid_email.append(emails[i])

	print(len(valid_email))
	with open('valid_email.txt', 'w') as f:
		for item in valid_email:
			f.write("%s\n" % item)


import numpy as np
import cv2 as cv

image = cv.imread('lena.jpg')
image = cv.cvtColor(image, cv.COLOR_BGR2GRAY)

img = np.array(image)
height = image.shape[0]
width = image.shape[1]

kernel= np.array([[-1, -1, -1],[-1, 8, -1], [-1, -1, -1]])
#print(kernel)
m= kernel.shape[0]//2
w=h=3
conv= np.zeros(image.shape)
for i in range(m,height-m):
    for j in range(m, width-m):
        s=0
        for k in range(h):
            for l in range(w):
                s=s+img[i-m+k][j-m+l]*kernel[k][l]

        conv[i][j]=s

#print(img)
cv.imshow('img', conv)
cv.waitKey()
#cv.destroyAllWindows()


import urllib.request, json
import pytz
from datetime import datetime
dateTimeStr=datetime.utcnow().replace(tzinfo=pytz.utc)
def jsonReaderScooter(urlToOpen):
    with urllib.request.urlopen(urlToOpen) as url:
        data = json.loads(url.read().decode())
    retStr='lat,lon,isdisabled,time\n'
    try:
        with open('outputDataUpdated.csv','r') as reader:
            if retStr in reader:
                retStr=''
    except:
        pass
    for item in data["data"]["bikes"]:
        retStr+=str(item['lat'])+','+str(item['lon'])+','+str(item['is_disabled'])+','+str(dateTimeStr)+'\n'
    with open('outputDataUpdated.csv', 'a+') as writer:
        writer.writelines(retStr)
    return True
url = ["https://mds.bird.co/gbfs/los-angeles/free_bikes","https://s3.amazonaws.com/lyft-lastmile-production-iad/lbs/lax/free_bike_status.json","https://la-gbfs.getwheelsapp.com/free_bike_status.json"]
for i in url:
    jsonReaderScooter(i)


import sys
import pygame
from setting import Settings
from setting import Ship
import game_functions as gf

def run_game():
    # Initialize game and create a screen object.
    pygame.init()

    ai_settings = Settings()

    screen = pygame.display.set_mode(
        (ai_settings.screen_width, ai_settings.screen_height))
    ship = Ship(screen)
    pygame.display.set_caption("Andy and Mr. Umair's Rocket game")
    bg_color = (30,67,78)
    # Start the main loop for the game.
    while True:
        gf.check_events(ship)
        ship.update()
        # Watch for keyboard and mouse events.

        # Make the most recently drawn screen visible.
        gf.update_screen(ai_settings, screen, ship)

run_game()


#!/usr/bin/env python3
import time
from pymavlink import mavutil
from trunk import *
#from colored import fg, bg, attr
from colored import fg, bg, attr

#if get_Setting('mainLoopStatus', 'status.json', 0) == "closed":
#	print("Warning: Manual override enabled")
#	set_Setting('mainLoopStatus', 'manual', 'status.json', 1)

print("Hello, Launching MavLink viewer...")
timer1 = time.time()

# Start a connection listening to a UDP port
#the_connection = mavutil.mavlink_connection('udpin:localhost:14540')

time.sleep(1)
print("--->Looking for ports, please wait... Can take up to a minute...")
print("")

port1 = '/dev/ttyACM1'
port2 = '/dev/ttyACM2'
current = port1

while 1:
	try:
		the_connection = mavutil.mavlink_connection(current)
		time.sleep(1)
		the_connection.wait_heartbeat()
		break
	except:
		pass
		if current == port1:
			current = port2
		elif current == port2:
			current = port1
		time.sleep(1)

print("Connected to port: " + current)
print("Heartbeat from System %u, Component %u" % (the_connection.target_system, the_connection.target_system))
time.sleep(4)
#https://mavlink.io/en/messages/common.html#MAV_DATA_STREAM_EXTENDED_STATUS
for i in range(0, 3):
	the_connection.mav.request_data_stream_send(the_connection.target_system, the_connection.target_component, mavutil.mavlink.MAV_DATA_STREAM_ALL, 4, 1)

pevent = mavutil.periodic_event(5)

while(1):
	the_connection.recv_msg()
	if pevent.trigger():
		try:
			IMU = the_connection.messages['RAW_IMU']
			IMU2= the_connection.messages['SCALED_IMU2']
			try:
				IMU3= the_connection.messages['SCALED_IMU3']
			except:
				pass
			PR1= the_connection.messages['SCALED_PRESSURE']
			GPS_RAW= the_connection.messages['GPS_RAW_INT']
			#print(IMU)
			print("\tAx\tAy\tAz\t|Gx\tGy\tGz\t|Mx\tMy\tMz")
			print(f"0|\t{IMU.xacc:.0f}\t{IMU.yacc:.0f}\t{IMU.zacc:.0f}\t|{IMU.xgyro:.0f}\t{IMU.ygyro:.0f}\t{IMU.zgyro:.0f}\t|{IMU.xmag:.0f}\t{IMU.ymag:.0f}\t{IMU.zmag:.0f}")
			print(f"1|\t{IMU2.xacc:.0f}\t{IMU2.yacc:.0f}\t{IMU2.zacc:.0f}\t|{IMU2.xgyro:.0f}\t{IMU2.ygyro:.0f}\t{IMU2.zgyro:.0f}\t|{IMU2.xmag:.0f}\t{IMU2.ymag:.0f}\t{IMU2.zmag:.0f}")
			print(f"2|\t{IMU3.xacc:.0f}\t{IMU3.yacc:.0f}\t{IMU3.zacc:.0f}\t|{IMU3.xgyro:.0f}\t{IMU3.ygyro:.0f}\t{IMU3.zgyro:.0f}\t|{IMU3.xmag:.0f}\t{IMU3.ymag:.0f}\t{IMU3.zmag:.0f}")
			print(f"Pressure1 Abs: {PR1.press_abs:.2f} \tDif: {PR1.press_diff:.1f} \tTemp: {PR1.temperature:.0f}" + "\tSats in View: " + str(GPS_RAW.satellites_visible))
			#print("Sats in View: " + str(GPS_RAW.satellites_visible))

		except:
			print("Error")

		try:
			PR2= the_connection.messages['SCALED_PRESSURE2']
			print(f"Pressure2 Abs: {PR2.press_abs:.2f} \tDif: {PR2.press_diff:.1f} \tTemp: {PR2.temperature:.0f}")
			#print(" ")
		except:
			print(f"Pressure2 Abs: INOP \tDif: INOP \tTemp: INOP")

		#print("...Press ctrl+c to exit...")
		print('%s ...Press ctrl+c to exit... %s' % (fg(3), attr(0)))
		print(" ")

	time.sleep(.005)

	#ALL = the_connection.recv_match(blocking=True)
	#print(ALL)


from flask import Flask, g, render_template, request, send_from_directory, url_for
import sqlite3, os, datetime

from werkzeug.utils import redirect, secure_filename

SITENAME = 'SaLeeMas - PicShare'
# Définir le dossier dans lequel les photos
# vont petre uploadés
UPLOAD_FOLDER = 'uploads'
ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif'}
app = Flask(__name__)
# Attention, à préciser le répertoire local !
DATABASE = 'app.db'
# On définit une variable globale qui rendra
# nos fichiers accesssibles même via les templates
# récupéré de la doc FLASK
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER

# Se connecter à la DB (code récupéré de la doc FLASK)
def get_db():
    db = getattr(g, '_database', None)
    if db is None:
        db = g._database = sqlite3.connect(DATABASE)
    return db

# La fonction pour spécifier les types de fichier autorisés
def allowed_file(filename):
    return '.' in filename and \
           filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS

# La route de la homepage
@app.route("/", methods=["GET", "POST"])
def show_pictures():
    db = get_db()
    print("All categories")
    if request.method == 'GET':
        categories = db.execute("SELECT name from categories order by id")
        pictures = db.execute("SELECT id, title, filename \
                               from pictures order by upload_date desc")
        # print(pictures.fetchall())
        return render_template("index.html",
                all_pictures=pictures, all_categories=categories)

# La route de la homepage avec la categorie name en argument
@app.route("/<category>", methods=["GET", "POST"])
def show_category_pictures(category):
    db = get_db()
    if request.method == 'GET':
        # print("Chosen category", category)
        categories = db.execute("SELECT name from categories order by id")
        if category:
            print("category", category)

            pictures = db.execute("SELECT pictures.id, title, filename \
                                   from pictures left join categories \
                                   on category_id = categories.id \
                                   where categories.name = (?) \
                                   order by upload_date desc", [category])
            # print(pictures.fetchall())
            return render_template("index.html",
                                    all_pictures=pictures,
                                    all_categories=categories,
                                    chosen_category=category)

# La route du chemin d'accès à l'image à renvoyer, avec
# le nom du répertoire "uploads/", suivi du nom du fichier image
@app.route('/uploads/<filename>')
def download_file(filename):
    print("send_from_directory",
          send_from_directory(app.config["UPLOAD_FOLDER"], filename))
    return send_from_directory(app.config["UPLOAD_FOLDER"], filename)

# La route de la page upload
@app.route("/upload",  methods=["GET", "POST"])

def upload():
    db = get_db()
    categories_cursor = db.execute("select name from categories order by id;")
    categories_name = categories_cursor.fetchall()
    print("I am the result of your query: ", categories_name)
    list_of_categories = []
    for category in categories_name:
        name = category[0]
        list_of_categories.append(name)
    print("i am the list of cat : ", list_of_categories)
    if request.method == 'POST':
        file = request.files['file']
        print("I am the files.filename : ", file.filename)
        if allowed_file(file.filename):
            filename = secure_filename(file.filename) #  c'est le path
            title = request.form.get("title")
            description = request.form.get("description")
            print(description, " - ", request.form.get("description"))
            category = request.form.get("category")
            file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
            upload_date = datetime.datetime.now()
            # print("datetime.datetime.now()", datetime.datetime.now())
            # sauvegarder le fichier dans la DB
            db = get_db()
            if category:
                cursor1 = db.execute("SELECT id from categories \
                                where name = ?", [category])
                category_id = cursor1.fetchone()
                # print(category_id[0])
            db.execute("INSERT into pictures (title, filename, upload_date, category_id, description) \
                                      values (?    ,     ?   ,       ?    ,      ?     ,      ?     )",
                        [title, filename, upload_date, int(category_id[0]), description])
            # # vérifier si le titre existe déjà
            # cursor_title = db.execute(
            # "SELECT id, title FROM pictures WHERE title = (?)", [title])
            # print("I'am the cursor: ", cursor_title)
            # # On l'enregistre dans une variable et on l'affiche
            # # avec fetchone, si le résultat n'est pas None on retourne 404
            # title_request = cursor_title.fetchone()
            # print("hey I'm the request title ", title_request)
            # if title_request is not None: abort(404)
            db.commit()
            return render_template("picture_uploaded.html")
    return render_template('upload.html', list_of_categories=list_of_categories)

#  La route de la page picture
@app.route("/picture/<picture_id>", methods=["GET", "POST"])
def picture_id(picture_id):
    if picture_id and request.method == 'POST':
        comment = request.form.get("comment")
        # print("I am the comment :", comment)
        comment_date = datetime.datetime.now()

        # print("datetime.datetime.now()", comment_date)
        # sauvegarder le fichier dans la DB
        db = get_db()
        db.execute("INSERT into comments (comment, comment_date, picture_id) \
                                  values (?      ,        ?    , ?)",
                    [comment, comment_date, picture_id])
        db.commit()
    if picture_id and request.method == 'GET':
        # print("I am the id of the chosen picture :", picture_id)
        db = get_db()
        pictures = db.execute("SELECT title, filename, upload_date, description, categories.name \
                               from pictures inner join categories \
                               on category_id = categories.id \
                               where pictures.id = (?)", [picture_id])
        # print(pictures)
        comments = db.execute("SELECT comment, comment_date \
                               from comments inner join pictures \
                               on picture_id = pictures.id \
                               where pictures.id = (?) \
                               order by comment_date desc", [picture_id])
        # print(comments)
        return render_template("picture.html",
                                all_pictures=pictures,
                                all_comments=comments)
    # print("not picture_id")
    return redirect("/picture/" + picture_id)

if __name__ == "__main__":
    app.run(debug=True)


import os
import sys
import time
from functools import partial
from multiprocessing import Pool
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager

chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument('--headless')
chrome_options.add_argument('window-size=1920,1080')
chrome_options.add_argument('start-maximised')
chrome_options.add_argument('--no-sandbox')
chrome_options.add_argument('--disable-dev-shm-usage')

def scroll_to_page_end_n_times(browser, s, page_load_wait_seconds):
  for _ in range(s):
    print(f'ScrollHeight before scrolling: {browser.execute_script("return document.documentElement.scrollHeight")}')
    browser.execute_script('window.scrollTo(0, document.body.scrollHeight);')
    print(f'Scrolled, waiting for {page_load_wait_seconds} seconds to load page')
    time.sleep(page_load_wait_seconds)
    print(f'ScrollHeight after scrolling: {browser.execute_script("return document.documentElement.scrollHeight")}')
  return

def links_collection(main_page_link, num_links, start_at_link_num, scroll_limit, page_load_wait_seconds, element_load_wait_seconds):
  print('Working in background...')

  n = 0
  s = 0
  link_num = start_at_link_num
  links_dict = {}

  chrome_driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()), options=chrome_options)
  with chrome_driver as browser:
    browser.get(main_page_link)
    while n < num_links:
      try:
        link_path = '/html/body/div[1]/div/div[1]/div/div[3]/div/div/div/div[1]/div[1]/div[2]/div/div/div/div/div/div/div[' + str(
            link_num) + ']/a/div[1]/div/div/div/div/div[2]/div[1]/div/div/div/div[2]/span/span/object/a'
        page = WebDriverWait(browser, element_load_wait_seconds).until(EC.visibility_of_element_located((By.XPATH, link_path)))
        event_url_long = page.get_attribute('href')
        event_url_cutoff = event_url_long[event_url_long.find('events/') + 7:].find('/')
        event_url = event_url_long[:event_url_long.find('events/') + 7 + event_url_cutoff + 1]
        event_title = page.text
        print(f'Fetching link for event: {event_title}')
        links_dict[event_title + str(n)] = event_url
        link_num += 1
        n += 1
      except Exception as e:
        # print(f'links_collection exception:\n{e}')
        if s < scroll_limit:
          s += 1
          scroll_to_page_end_n_times(browser, s, page_load_wait_seconds)
        else:
          break
  print(f'\nNumber of links: {str(len(links_dict.items()))}')
  return links_dict

def get_location(browser, element_load_wait_seconds):
  try:
    link_path = '/html/body/div[1]/div/div[1]/div/div[3]/div/div/div/div[1]/div[1]/div[2]/div/div/div[1]/div[1]/div[2]/div/div[2]/div/div[1]/div/div/div[3]'
    page = WebDriverWait(browser, element_load_wait_seconds).until(EC.visibility_of_element_located((By.XPATH, link_path)))
    e_location = page.text
  except Exception as e:
    e_location = 'n/a'
    #print(f'get_location exception:\n{e}')
  return e_location

def get_datetime(browser, element_load_wait_seconds):
  try:
    link_path = '/html/body/div[1]/div/div[1]/div/div[3]/div/div/div/div[1]/div[1]/div[2]/div/div/div[1]/div[1]/div[2]/div/div[2]/div/div[1]/div/div/div[1]/span'
    page = WebDriverWait(browser, element_load_wait_seconds).until(EC.visibility_of_element_located((By.XPATH, link_path)))
    e_datetime_str = page.text

  except Exception as e:
    e_datetime_str = 'n/a'
    # print(f'get_datetime exception:\n{e}')

  return e_datetime_str

def get_host_and_num_people_responded(browser, element_load_wait_seconds):
  try:
    link_path = '/html/body/div[1]/div/div[1]/div/div[3]/div/div/div/div[1]/div[1]/div[2]/div/div/div[2]/div/div/div/div/div[1]/div/div/div'
    page = WebDriverWait(browser, element_load_wait_seconds).until(EC.visibility_of_element_located((By.XPATH, link_path)))

    children = page.find_elements(By.XPATH, './child::*')
    e_host = ''
    e_num_people_responded = ''
    for child in children:
      textContent = child.text
      if 'Event by' in textContent:
        e_host = textContent[textContent.find('Event by') + 9:]
      elif 'people responded' in textContent:
        e_num_people_responded = textContent[:textContent.find('people responded')].strip()
      elif 'person responded' in textContent:
        e_num_people_responded = textContent[:textContent.find('person responded')].strip()
      else:
        pass

    if e_host == '':
      e_host = 'n/a'
    if e_num_people_responded == '':
      e_num_people_responded = 'n/a'

  except Exception as e:
    e_host = 'n/a'
    e_num_people_responded = 'n/a'
    # print(f'get_host_and_num_people_responded exception:\n{e}')
  return e_host, e_num_people_responded

def get_description(browser, element_load_wait_seconds):
  try:
    link_path = '/html/body/div[1]/div/div[1]/div/div[3]/div/div/div/div[1]/div[1]/div[2]/div/div/div[2]/div/div/div/div/div[1]/div/div/div/div[last()]/div/span'
    page = WebDriverWait(browser, element_load_wait_seconds).until(EC.visibility_of_element_located((By.XPATH, link_path)))

    children = page.find_elements(By.XPATH, './child::*')
    for child in children:
      try:
        see_more_btn = child.find_element(By.XPATH, "./div[@role='button']")
        see_more_btn.click()
      except:
        pass

    children = page.find_elements(By.XPATH, './child::*')
    e_description = ''
    for child in children:
      e_description += child.text
      e_description += '\n'

    if 'See less' in e_description:
      e_description = e_description[:e_description.find(' See less')]
    elif 'See more' in e_description:
      e_description = e_description[:e_description.find('... See more')]
    else:
      pass

    if e_description == '':
      e_description = 'n/a'

  except Exception as e:
    e_description = 'n/a'
    # print(f'get_description exception:\n{e}')
  return e_description

def get_image_url(browser, element_load_wait_seconds):
  try:
    link_path = '/html/body/div[1]/div/div[1]/div/div[3]/div/div/div/div[1]/div[1]/div[2]/div/div/div[1]/div[1]/div[1]/div/div/div[2]/div/a/div/div/div/div/div/img'
    page = WebDriverWait(browser, element_load_wait_seconds).until(EC.visibility_of_element_located((By.XPATH, link_path)))
    img_path = page.get_attribute('src')
  except Exception as ignore:
    try:
      link_path = '/html/body/div[1]/div/div[1]/div/div[3]/div/div/div/div[1]/div[1]/div[2]/div/div/div[1]/div[1]/div[1]/div/div/div[2]/div/a/div/div/div/div/img'
      page = WebDriverWait(browser, element_load_wait_seconds).until(EC.visibility_of_element_located((By.XPATH, link_path)))
      img_path = page.get_attribute('src')
    except Exception as e:
      img_path = 'n/a'
      # print(f'get_image_url exception:\n{e}')
  return img_path

def crawl_links(element_load_wait_seconds, current_link):
  e_location = 'n/a'
  e_datetime = 'n/a'
  e_host = 'n/a'
  e_num_people_responded = 'n/a'
  e_description = 'n/a'
  img_path= 'n/a'
  try:
    chrome_driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()), options=chrome_options)
    with chrome_driver as browser:
      print(f'Crawling on: {current_link}')

      # Using Selenium
      browser.get(current_link)

      e_location = get_location(browser, element_load_wait_seconds)
      e_datetime = get_datetime(browser, element_load_wait_seconds)
      e_host, e_num_people_responded = get_host_and_num_people_responded(browser, element_load_wait_seconds)
      e_description = get_description(browser, element_load_wait_seconds)
      img_path = get_image_url(browser, element_load_wait_seconds)

  except Exception as e:
    print(f'crawl_links exception:\n{e}')  # if the links are not found in a page, print exception

  return e_location, e_host, e_num_people_responded, e_datetime, e_description, img_path

def main(dict):
  num_links = dict['num_links']
  start_at_link_num = dict['start_at_link_num']
  scroll_limit = dict['scroll_limit']
  page_load_wait_seconds = dict['page_load_wait_seconds']
  element_load_wait_seconds = dict['element_load_wait_seconds']
  event_search_keyword = dict['event_search_keyword']
  main_page_link = f'https://www.facebook.com/events/search/?q={event_search_keyword}'
  pool_size = dict['pool_size']

  links_dict = links_collection(main_page_link, num_links, start_at_link_num, scroll_limit, page_load_wait_seconds, element_load_wait_seconds)

  print('\nInitiating scraping...')
  #pool = Pool(processes=pool_size)  # creates pool of n processes at a time
  #func = partial(crawl_links, element_load_wait_seconds)
  #e_details_list = pool.map(func, list(links_dict.values()))  # maps the function crawl_links (with arg element_load_wait_seconds) with the links_dict.items() input
  e_details_list = [crawl_links(element_load_wait_seconds, link) for link in list(links_dict.values())]

  return_dict = { 'payload' : [] }
  e_details_labels = ['location', 'host', 'numPeopleResponded', 'datetime', 'details', 'imgPath']
  for (e_name, e_link), e_details in zip(links_dict.items(), e_details_list):
    event_dict = {}
    event_dict['link'] = e_link
    event_dict['name'] = e_name[:-1]
    for e_detail_item_label, e_detail_item  in zip(e_details_labels, e_details):
        event_dict[e_detail_item_label] = e_detail_item
    return_dict['payload'].append(event_dict)

    return return_dict


#Brownian Motion Simulator
#Simulate first on $R^1$
import numpy as np
import numpy
import matplotlib as mpl
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
import matplotlib.pyplot as plt

def graph(points):

	data = np.array(points)
	fig = plt.figure()
	ax = fig.add_subplot(111)
	ax.scatter(data[:,0],data[:,1])
	ax.set_xlabel("X")
	ax.set_ylabel("Y")
	plt.axis('scaled')
	plt.show()

	return

def run1d(n):
	function = BMinterval(n)
	pointlist = convert(function)
	graph(pointlist)
	return

def grapher(func):
	a = convert(func)
	graph(a)
	return

def convert(func):
	a = []
	for term in func:
		a.append([term, func[term]])
	return a

def BMinterval(n,startpos,starttime):
	#creates a 1-d Brownian motion on $[0,1]$ with $D_n$ dyadic level.

	B = {}
	i = 1
	B[starttime] = startpos
	B[starttime + 1] = startpos + np.random.randn()

	while i < n:
		k = 0
		while 2*k + 1 <= np.power(2,i):
			diadic = float(np.power(2,i))
			d = (2*k + 1) / diadic
			B[starttime + d] = startpos + .5 * ( B[starttime + (d - 1 / diadic)] + B[starttime + (d + 1 / diadic)] - 2*startpos) + .5 * np.random.randn()/ diadic
			k = k + 1
		i = i + 1

	return B

def BM(n,t):
	#creates a depth n brownian motion on [0,t], where t is an integer:
	i = 1
	B = BMinterval(n,0,0)
	while i < t:
		B = dict(B.items() + BMinterval(n, B[i], i).items())
		i = i + 1
	return B

def BM2d(n,t):
	B1 = BM(n,t)
	B2 = BM(n,t)
	list = []
	for term in B1:
		list.append([B1[term],B2[term]])
	return list

def fracpart(number):
	return number - np.floor(number)

def inbox(points):
	##Returns percentage of in points that are (up to ZxZ) in a the box, [0,1/2]x[0,1/2]
	c = 0
	for term in points:
		if (fracpart(term[0]) <= .5) and (fracpart(term[1]) <= .5):
			c = c + 1
	return c / float(len(points))

def fold(points):
	new = []
	for term in points:
		new.append([fracpart(term[0]),fracpart(term[1])])
	return new

def inint(points,k):
	c = 0
	for term in points:
		if (fracpart(points[term])) <= k:
			c = c + 1
	return c / float(len(points))

def fold2(points):
	new = []
	for term in points:
		new.append([fracpart(points[term])])
	return new


#! /usr/bin/python

import os
import sys
import json

import luigi
import numpy as np
import vigra
import nifty.ufd as nufd

import cluster_tools.utils.volume_utils as vu
import cluster_tools.utils.function_utils as fu
from cluster_tools.cluster_tasks import SlurmTask, LocalTask, LSFTask

#
# Find Labeling Tasks
#

class MergeAssignmentsBase(luigi.Task):
    """ MergeAssignments base class
    """

    task_name = "merge_assignments"
    src_file = os.path.abspath(__file__)
    allow_retry = False

    output_path = luigi.Parameter()
    output_key = luigi.Parameter()
    shape = luigi.ListParameter()
    # task that is required before running this task
    dependency = luigi.TaskParameter()

    def requires(self):
        return self.dependency

    def run_impl(self):
        shebang, block_shape, roi_begin, roi_end = self.global_config_values()
        self.init(shebang)

        block_list = vu.blocks_in_volume(self.shape, block_shape, roi_begin, roi_end)
        n_jobs = min(len(block_list), self.max_jobs)

        config = self.get_task_config()
        config.update({"output_path": self.output_path, "output_key": self.output_key,
                       "tmp_folder": self.tmp_folder, "n_jobs": n_jobs, "block_list": block_list})

        # we only have a single job to find the labeling
        self.prepare_jobs(1, None, config)
        self.submit_jobs(1)

        # wait till jobs finish and check for job success
        self.wait_for_jobs()
        # log the save-path again
        self.check_jobs(1)

class MergeAssignmentsLocal(MergeAssignmentsBase, LocalTask):
    """
    MergeAssignments on local machine
    """
    pass

class MergeAssignmentsSlurm(MergeAssignmentsBase, SlurmTask):
    """
    MergeAssignments on slurm cluster
    """
    pass

class MergeAssignmentsLSF(MergeAssignmentsBase, LSFTask):
    """
    MergeAssignments on lsf cluster
    """
    pass

def merge_assignments(job_id, config_path):

    fu.log("start processing job %i" % job_id)
    fu.log("reading config from %s" % config_path)

    with open(config_path, "r") as f:
        config = json.load(f)
    output_path = config["output_path"]
    output_key = config["output_key"]

    tmp_folder = config["tmp_folder"]
    n_jobs = config["n_jobs"]
    block_list = config["block_list"]

    id_prefix = "ids"
    assignment_prefix = "cc_assignments"

    # load labels
    label_paths = [os.path.join(tmp_folder, f"{id_prefix}_{block_id}.npy") for block_id in block_list]
    labels = [np.load(pp) if os.path.exists(pp) else [0] for pp in label_paths]
    labels = np.unique(np.concatenate(labels))

    # load assignments
    assignment_paths = [os.path.join(tmp_folder, f"{assignment_prefix}_{job_id}.npy") for job_id in range(n_jobs)]
    assignments = [np.load(pp) for pp in assignment_paths if os.path.exists(pp)]

    if assignments:
        assignments = np.concatenate(assignments, axis=0)
        assignments = np.unique(assignments, axis=0)
        assert assignments.shape[1] == 2
        fu.log("have %i pairs of node assignments" % len(assignments))
        have_assignments = True
    else:
        fu.log("did not find any node assignments and will not merge any components")
        have_assignments = False

    if have_assignments:
        ufd = nufd.boost_ufd(labels)
        ufd.merge(assignments)
        label_assignments = ufd.find(labels)
    else:
        label_assignemnts = labels.copy()

    n_labels = len(labels)
    label_assignemnts, max_id, _ = vigra.analysis.relabelConsecutive(label_assignments, keep_zeros=True, start_label=1)
    assert len(label_assignments) == n_labels
    fu.log("reducing the number of labels from %i to %i" % (n_labels, max_id + 1))

    label_assignments = np.concatenate([labels[:, None], label_assignments[:, None]], axis=1).astype("uint64")
    chunks = (min(65334, n_labels), 2)
    with vu.file_reader(output_path) as f:
        f.create_dataset(output_key, data=label_assignments, compression="gzip", chunks=chunks)
    fu.log_job_success(job_id)

if __name__ == "__main__":
    path = sys.argv[1]
    assert os.path.exists(path), path
    job_id = int(os.path.split(path)[1].split(".")[0].split("_")[-1])
    merge_assignments(job_id, path)


from typing import List

class Solution:
    def canJump(self, nums: List[int]) -> bool:
        if not nums or len(nums) < 2:
            return True

        max_arrive = nums[0]
        for i in range(1, len(nums)):
            if max_arrive < i:
                return False
            max_arrive = max(max_arrive, i + nums[i])
        return True
nums = [0,1]
print(Solution().canJump(nums))


import random
from itertools import zip_longest
from typing import List

from config import MuZeroConfig
from game.game import AbstractGame
import _pickle as cPickle
import os
import numpy as  np

class ReplayBuffer(object):

    def __init__(self, config: MuZeroConfig, fighter):
        self.window_size = config.window_size
        self.batch_size = config.batch_size
        self.buffer = []
        self.loaded_games = []
        self.current_games = []
        self.memory_path = config.memory_path
        self.fighter = fighter

    def save_game(self, game):
        if sum([len(i.root_values) for i in self.buffer])  > self.window_size:
            self.buffer.pop(0)
        if game.player1_historic_network == True:
            game.game_player1_priority = 0
            game.player1_priorities = list(np.full(len(game.root_values), 0))
        else:
            game.game_player1_priority = 1e3*len(game.root_values)
            game.player1_priorities = list(np.full(len(game.root_values), 1e3))
            player1_zero_move_idx = [i for i, j in enumerate(game.child_visits) if j[0][0] == 1.]
            for idx in player1_zero_move_idx:
                game.player1_priorities[idx] = 0
        if game.player2_historic_network == True:
            game.game_player2_priority = 0
            game.player2_priorities = list(np.full(len(game.root_values), 0))
        else:
            game.game_player2_priority = 1e3*len(game.root_values)
            game.player2_priorities = list(np.full(len(game.root_values), 1e3))
            player2_zero_move_idx = [i for i, j in enumerate(game.child_visits) if j[1][0] == 1.]
            for idx in player2_zero_move_idx:
                game.player2_priorities[idx] = 0
        self.buffer.append(game)

    def update_buffer(self):
        new_files = [f for f in os.listdir(self.memory_path) if f not in self.loaded_games]
        new_files = [f for f in new_files if (f.split('_')[-1][:-4] == self.fighter) | (f.split('_')[-2] == self.fighter)]
        new_files.sort(key = lambda x: int(x.split('_')[1]))
        if len(new_files) > self.window_size // 1100:
            self.loaded_games = self.loaded_games + new_files[:-self.window_size // 1100]
            new_files = new_files[-self.window_size // 1100:]
        if len(new_files) != 0:
            for new_file in new_files:
                with open(os.path.join(self.memory_path,new_file), 'rb') as game_file:
                    game = cPickle.load(game_file)
                self.save_game(game)
                self.loaded_games.append(new_file)
                if sum([len(i.root_values) for i in self.buffer]) > self.window_size:
                    self.current_games.pop(0)
                self.current_games.append(new_file)

    def sample_batch(self, num_unroll_steps: int, unroll_step_size : int, td_steps: int, fighter):
        # Generate some sample of data to train on
        games = self.sample_games(fighter)
        game_pos = [(g, self.sample_position(self.buffer[g], fighter), 'player1' if self.buffer[g].player1 == fighter else 'player2') for g in games]
        game_data = [(self.buffer[g].make_image(i, p), [action.index for action in [j[int(p[-1]) - 1] for j in self.buffer[g].history[i:i + num_unroll_steps]]],
                      self.buffer[g].make_target(i, num_unroll_steps, unroll_step_size, td_steps, p))
                     for (g, i, p) in game_pos]
        sample_weights = [self.buffer[g].player1_priorities[i] if p == 'player1' else self.buffer[g].player2_priorities[i] for (g, i, p) in game_pos]
        game_weights = [self.buffer[g].game_player1_priority if p == 'player1' else self.buffer[g].game_player2_priority for (g, i, p) in game_pos]
        weight_batch = 1 / (np.array(sample_weights) * np.array(game_weights))
        weight_batch = weight_batch / np.max(weight_batch)
        # Pre-process the batch
        image_batch, actions_time_batch, targets_batch = zip(*game_data)
        targets_init_batch, *targets_time_batch = zip(*targets_batch)
        actions_time_batch = list(zip_longest(*actions_time_batch, fillvalue=0))

        # Building batch of valid actions and a dynamic mask for hidden representations during BPTT

        batch = image_batch, targets_init_batch, targets_time_batch, actions_time_batch
        return batch, game_pos, weight_batch**0.4

    def sample_games(self, fighter) -> List[AbstractGame]:
        # Sample game from buffer either uniformly or according to some priority.
        game_probs = np.array([game.game_player1_priority if game.player1 == fighter else game.game_player2_priority for game in self.buffer])
        game_probs /= np.sum(game_probs)
        return np.random.choice(len(self.buffer), size=self.batch_size, p = game_probs)

    def sample_position(self, game: AbstractGame, fighter) -> int:
        # Sample position from game either uniformly or according to some priority.
        if game.player1 == fighter:
            pos_probs = game.player1_priorities / sum(game.player1_priorities)
        if game.player2 == fighter:
            pos_probs = game.player2_priorities / sum(game.player2_priorities)
        return np.random.choice(len(pos_probs), p=pos_probs)

    def sample_position_value_bias(self, game: AbstractGame) -> int:
        # Sample position from game either uniformly or according to some priority.
        history = [i.index for i in game.history]
        counts = np.bincount(history)
        common = np.argmax(counts)
        above_avg = [i[0] for i in np.argwhere(history==common)]
        below_avg = [i[0] for i in np.argwhere(history!=common)]
        if random.randint(0,5) != 5:
            return np.random.choice(below_avg)
        else:
            return np.random.choice(above_avg)
    def update_priorities(self, priorities, idx_info, fighter):
        for i in range(len(idx_info)):
            game_id, game_pos, _ = idx_info[i]
            priority = priorities[i,:]
            start_idx = game_pos

            if self.buffer[game_id].player1 == fighter:
                end_idx = min(game_pos+len(priority), len(self.buffer[game_id].player1_priorities))
                self.buffer[game_id].player1_priorities[start_idx:end_idx] = priority[:end_idx-start_idx]
                self.buffer[game_id].game_player1_priority = np.mean(self.buffer[game_id].player1_priorities) * len(self.buffer[game_id].root_values)
            if self.buffer[game_id].player2 == fighter:
                end_idx = min(game_pos+len(priority), len(self.buffer[game_id].player2_priorities))
                self.buffer[game_id].player2_priorities[start_idx:end_idx] = priority[:end_idx-start_idx]
                self.buffer[game_id].game_player2_priority = np.mean(self.buffer[game_id].player2_priorities) * len(self.buffer[game_id].root_values)


# -*- coding: utf-8 -*-
"""
Created on Wed Jan 23 17:29:26 2019

@author: dell
"""

from selenium import webdriver
from time import sleep
from bs4 import BeautifulSoup as bs

url = "https://www.google.com/"
browser = webdriver.Chrome("E:\\Study\\Project_4_Web_Scrapping\\chromedriver.exe")
browser.get(url)

sleep(2)

search = browser.find_element_by_xpath('//*[@id="tsf"]/div[2]/div/div[1]/div/div[1]/input')
search.click()
type_search = "wikipedia"
search.send_keys(type_search)

sleep(2)

search1 = browser.find_element_by_xpath('//*[@id="tsf"]/div[2]/div/div[2]/div[2]/div/center/input[1]')
search1.click()

sleep(5)

browser.quit()


from flask import Flask, request, render_template
from chatXYZ import run, run_test
import logging

# API Key
from config import openai_api_key

log_handler = logging.StreamHandler()
log_formatter = logging.Formatter("%(asctime)s - %(message)s")
log_handler.setFormatter(log_formatter)

logger = logging.getLogger()
logger.setLevel(logging.INFO)
logger.addHandler(log_handler)

app = Flask(__name__)

api_key_mode = "system"  # "user"" or "system"
SHOW_API_KEY_BOX = True if api_key_mode == "user" else False

@app.route("/", methods=["GET", "POST"])
def index():
    if request.method == "POST":
        query = request.form["query"]

        # Get answer or error message
        try:
            if api_key_mode == "user":
                api_key = request.form["api_key"].strip()
                if api_key == "":  # API key is not provided in user mode; show error
                    result = f"Please enter your OpenAI API Key!"
                elif api_key != "":  # If API key provided in user mode; use it
                    result = run_test(query, api_key=api_key, victim="Oppie")
            elif api_key_mode == "system":  # API key is not required in system mode; use system key
                api_key = openai_api_key["OPENAI_API_KEY"]
                result = run_test(query, api_key=api_key, victim="Oppie")
                logger.info(f"User input: {query}")  # Using logger
            else:
                raise NotImplementedError("Please set api_key_mode to either 'user' or 'system'.")
        except Exception as e:
            result = f"Ah, it seems something terrible has happened. Perhaps too many people are trying to ask me questions at the moment, or the test has gone wrong. Error: {e}"
        return render_template("index.html", result=result, query=query, show_api_key_box=SHOW_API_KEY_BOX)
    else:
        return render_template("index.html", show_api_key_box=SHOW_API_KEY_BOX)

@app.route("/")
def home():
    return render_template("index.html", show_api_key_box=SHOW_API_KEY_BOX)

if __name__ == "__main__":
    app.run(host="127.0.0.1", port=8080, debug=True)


import sys
import enum

from sqlalchemy import Column, DateTime, Integer, String, ForeignKey, Table
from sqlalchemy.orm import relationship, backref

from rhinventory.extensions import db

class SimpleAssetAttribute():
    name: str
    def __str__(self) -> str:
        return f"{self.name}"

def asset_n_to_n_table(other_table: db.Model) -> Table:
    other_name = other_table.__name__.lower()
    return Table(
        f"asset_{other_name}",
        db.Model.metadata,
        Column("asset_id", ForeignKey("assets.id")),
        Column(f"{other_name}_id", ForeignKey(other_table.id)),
    )

class Platform(db.Model, SimpleAssetAttribute):
    __tablename__ = 'platforms'
    id: int          = Column(Integer, primary_key=True)  # type: ignore
    slug: str        = Column(String, nullable=False)  # type: ignore
    name: str        = Column(String, nullable=False)  # type: ignore
    last_used        = Column(DateTime, nullable=True)

asset_platform_table = asset_n_to_n_table(Platform)

class AssetTag(db.Model, SimpleAssetAttribute):
    __tablename__ = 'tags'
    id: int          = Column(Integer, primary_key=True)  # type: ignore
    name: str        = Column(String, nullable=False)  # type: ignore
    description: str = Column(String, nullable=False)  # type: ignore
    last_used        = Column(DateTime, nullable=True)

asset_tag_table = asset_n_to_n_table(AssetTag)

class Packaging(db.Model, SimpleAssetAttribute):
    __tablename__ = 'packagings'
    id: int          = Column(Integer, primary_key=True)  # type: ignore
    name: str        = Column(String, nullable=False)  # type: ignore
    last_used        = Column(DateTime, nullable=True)

# An asset can have a single packaging multiple times so we need a middle table
class AssetPackaging(db.Model):
    __tablename__ = 'asset_packaging'
    id: int           = Column(Integer, primary_key=True)  # type: ignore
    asset_id: int     = Column(Integer, ForeignKey('assets.id'))  # type: ignore
    packaging_id: int = Column(Integer, ForeignKey(Packaging.id))  # type: ignore

    #asset = relationship("Asset")
    #packaging = relationship(Packaging)

class Medium(db.Model, SimpleAssetAttribute):
    __tablename__ = 'media'
    id: int          = Column(Integer, primary_key=True)  # type: ignore
    name: str        = Column(String, nullable=False)  # type: ignore
    last_used        = Column(DateTime, nullable=True)

class AssetMedium(db.Model):
    __tablename__ = 'asset_mediums'
    id: int           = Column(Integer, primary_key=True)  # type: ignore
    asset_id: int     = Column(Integer, ForeignKey('assets.id'))  # type: ignore
    medium_id: int    = Column(Integer, ForeignKey(Medium.id))  # type: ignore

    #asset = relationship("Asset")
    #medium = relationship(Medium)

class Company(db.Model, SimpleAssetAttribute):
    __tablename__ = 'companies'
    id: int          = Column(Integer, primary_key=True)  # type: ignore
    name: str        = Column(String, nullable=False)  # type: ignore
    last_used        = Column(DateTime, nullable=True)

class CompanyAlias(db.Model):
    __tablename__ = 'company_aliases'
    id: int          = Column(Integer, primary_key=True)  # type: ignore
    alias: str       = Column(String, nullable=False)  # type: ignore
    company_id = Column(Integer, ForeignKey(Company.id), nullable=False)
    company = relationship(Company, backref="aliases")

asset_company_table = asset_n_to_n_table(Company)


import time
import json

from scrape_linkedin.utils import AnyEC
from scrape_linkedin.Profile import Profile
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException, NoSuchElementException

class ProfileScraper:
    """
    Scraper for Personal LinkedIn Profiles. See inherited Scraper class for
    details about the constructor.
    """
    MAIN_SELECTOR = '.core-rail'
    ERROR_SELECTOR = '.profile-unavailable'

    def __init__(self, driver):
        self.timeout = 10
        self.driver = driver
        self.scroll_pause = 0.1
        self.scroll_increment = 300

    def scrape_by_email(self, email):
        self.load_profile_page(
            'https://www.linkedin.com/sales/gmail/profile/proxy/{}'.format(email))
        return self.get_profile()

    def scrape(self, url='', user=None):
        self.load_profile_page(url, user)
        return self.get_profile()

    def load_profile_page(self, url='', user=None):
        """Load profile page and all async content
        Params:
            - url {str}: url of the profile to be loaded
        Raises:
            ValueError: If link doesn't match a typical profile url
        """
        if user:
            url = 'http://www.linkedin.com/in/' + user
        if 'com/in/' not in url and 'sales/gmail/profile/proxy/' not in url:
            raise ValueError(
                "Url must look like... .com/in/NAME or... '.com/sales/gmail/profile/proxy/EMAIL")
        self.driver.get(url)
        # Wait for page to load dynamically via javascript
        try:
            myElem = WebDriverWait(self.driver, self.timeout).until(AnyEC(
                EC.presence_of_element_located(
                    (By.CSS_SELECTOR, self.MAIN_SELECTOR)),
                EC.presence_of_element_located(
                    (By.CSS_SELECTOR, self.ERROR_SELECTOR))
            ))
        except TimeoutException as e:
            raise ValueError(
                """Took too long to load profile.  Common problems/solutions:
                1. Invalid LI_AT value: ensure that yours is correct (they
                   update frequently)
                2. Slow Internet: increase the time out parameter in the Scraper
                   constructor
                3. Invalid e-mail address (or user does not allow e-mail scrapes) on scrape_by_email call
                """)

        # Check if we got the 'profile unavailable' page
        try:
            self.driver.find_element_by_css_selector(self.MAIN_SELECTOR)
        except:
            raise ValueError(
                'Profile Unavailable: Profile link does not match any current Linkedin Profiles')
        # Scroll to the bottom of the page incrementally to load any lazy-loaded content
        self.scroll_to_bottom()

    def get_profile(self):
        try:
            profile = self.driver.find_element_by_css_selector(
                self.MAIN_SELECTOR).get_attribute("outerHTML")
        except:
            raise Exception(
                "Could not find profile wrapper html. This sometimes happens for exceptionally long profiles.  Try decreasing scroll-increment.")
        contact_info = self.get_contact_info()
        return Profile(profile + contact_info)

    def get_contact_info(self):
        try:
            # Scroll to top to put clickable button in view
            self.driver.execute_script("window.scrollTo(0, 0);")
            button = self.driver.find_element_by_css_selector(
                'a[data-control-name="contact_see_more"]')
            button.click()
            contact_info = self.wait_for_el('.pv-contact-info')
            return contact_info.get_attribute('outerHTML')
        except Exception as e:
            print(e)
            return ""

    def scroll_to_bottom(self):
        """Scroll to the bottom of the page
        Params:
            - scroll_pause_time {float}: time to wait (s) between page scroll increments
            - scroll_increment {int}: increment size of page scrolls (pixels)
        """
        expandable_button_selectors = [
            'button[aria-expanded="false"].pv-skills-section__additional-skills',
            'button[aria-expanded="false"].pv-profile-section__see-more-inline',
            'button[aria-expanded="false"].pv-top-card-section__summary-toggle-button',
            'button[data-control-name="contact_see_more"]'
        ]

        current_height = 0
        while True:
            for name in expandable_button_selectors:
                try:
                    self.driver.find_element_by_css_selector(name).click()
                except:
                    pass

            # Use JQuery to click on invisible expandable 'see more...' elements
            self.driver.execute_script(
                'document.querySelectorAll(".lt-line-clamp__ellipsis:not(.lt-line-clamp__ellipsis--dummy) .lt-line-clamp__more").forEach(el => el.click())')

            # Scroll down to bottom
            new_height = self.driver.execute_script(
                "return Math.min({}, document.body.scrollHeight)".format(current_height + self.scroll_increment))
            if (new_height == current_height):
                break
            self.driver.execute_script(
                "window.scrollTo(0, Math.min({}, document.body.scrollHeight));".format(new_height))
            current_height = new_height
            # Wait to load page
            time.sleep(self.scroll_pause)

    def wait(self, condition):
        return WebDriverWait(self.driver, self.timeout).until(condition)

    def wait_for_el(self, selector):
        return self.wait(EC.presence_of_element_located((
            By.CSS_SELECTOR, selector
        )))


# -*- coding: utf-8 -*-
"""
Created on Tue Feb  8 11:01:20 2022

@author: sonne
"""
#0. Imports

from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure
import matplotlib.patches as patches
import matplotlib.animation as animation
import matplotlib.ticker as ticker
import tkinter as Tk #Interface
import numpy as np #Numerische Mathematik
import itertools #für Iteration
import random #Zufallszahlen
from scipy.constants import k #Boltzmann-Konstante

#1. Dictionaries für die Edelgase

Masse = {"Helium" : 6.642e-27,
         "Neon" : 3.351e-26,
         "Argon" : 6.634e-26,
         "Krypton" : 1.392e-25,
         "Xenon": 2.180e-25}

Durchmesser = {"Helium" : 36.58,  # 1.4e-10m
         "Neon" : 44.22,       # 1.58e-10m
         "Argon" : 65.96,      # 1.88e-10m
         "Krypton" : 76.15,    # 2.00e-10m
         "Xenon": 87.07}       # 2.18e-10m

Farbe = {"Helium" : "blue",
         "Neon" : "darkblue",
         "Argon" : "blueviolet",
         "Krypton" : "purple",
         "Xenon": "indigo"}

LennardJones_epsilon = {"Helium" : 14e-23,
         "Neon" : 50e-23,
         "Argon" : 167e-23,
         "Krypton" : 225e-23,
         "Xenon": 320e-23}

LennardJones_sigma = {"Helium" : 2.56e-10,
         "Neon" : 2.74e-10,
         "Argon" : 3.4e-10,
         "Krypton" : 3.65e-10,
         "Xenon": 3.98e-10}

#2. Figure für Plot erstellen

#2.1 für die Simulation

fig = Figure(figsize = (6,6))
ax = fig.add_subplot(111)

#2.2 für Beschleunigungspfeil

arrow = Figure(figsize = (1.5,1.5)) #Zweites Plotfenster für den Beschleunigungsvektor
arr = arrow.add_subplot(111)
arr.set_xlim(-1,1)
arr.set_ylim(-1,1)
arr.axes.xaxis.set_visible(False) #Achsen zur Übersichtlichkeit ausgeblendet
arr.axes.yaxis.set_visible(False)
Inaktiv_text = arr.text(0,0,'Aktiviere \n"Teilchen verfolgen"', ha="center", va = "center", fontsize = 8.) #Text in der Figure zu Beginn
Pfeil = patches.Arrow(0, 0, 0, 0) #Pfeilobjekt mit Länge 0 erstellen
patch = arr.add_patch(Pfeil) #Pfeil zu Plot hinzufügen

#3. Interface mit Tkinter

class Interface():

    def __init__(self,  Teilchentracker_aus = True):
        self.root = Tk.Toplevel()
        self.Teilchentracker_aus = Teilchentracker_aus

    #3.1 Tkinter-Fenster konfigurieren

        self.root.title("C5 Molecular Dynamics") #Titel des Fensters
        self.root.geometry("1400x800") #Größe des Fensters in Pixel
        self.root.config(bg = "white") #weißer Hintergrund
        self.root.columnconfigure(0, weight=3)
        self.root.columnconfigure(1, weight=1)
        self.root.columnconfigure(2, weight =1)

        self.Ueberschrift = Tk.Label(self.root,text="Thermal motion", font = "Verdana 20 bold", \
                                     bg = "white").grid(column=0, row=0)

        #3.2 Canvas für die Simulation und für den Beschleunigungspfeil erstellen

        self.canvas = FigureCanvasTkAgg(fig, master=self.root) #für Simulation
        self.canvas.get_tk_widget().grid(column=0, row=1, rowspan = 9, sticky = Tk.N)

        self.Label_Beschleunigungspfeil = Tk.Label(self.root, text = "Acceleration",\
                                                   font = "Verdana 10 bold", bg = "white").grid(column = 2, row = 1)
        self.canvas_arrow = FigureCanvasTkAgg(arrow, master=self.root) #für Pfeil
        self.canvas_arrow.get_tk_widget().grid(column=2, row =2, rowspan = 2, sticky = Tk.N, pady = 10)

        #3.2 Schieberegler für Änderung der Temperatur

        self.Label_Temperatur = Tk.Label(self.root, text = "Temperature in K", font = "Verdana 10 bold",\
                                         bg = "white").grid(column = 1, row =1)
        self.Slider_Temperatur = Tk.Scale(self.root, from_=1, to=2000, orient = "horizontal",\
                                          bg = "white") #Schieberegler
        self.Slider_Temperatur.grid(column = 1, row = 2) #Schieberegler platzieren
        self.Slider_Temperatur.set(300) #Startwert
        self.Button_Temperatur = Tk.Button(self.root, text="Change temperature", bg= "lightgreen", \
                                           compound = "left", width = 18, command= \
                                           self.update_Temperatur).grid(column = 1, row = 3)
                                           #Knopf, ruft Funktion für Temperatur auf

        #3.3 Schieberegler für Änderung der Teilchenzahl

        self.Label_Teilchenzahl = Tk.Label(self.root, text = "Number of particles", \
                                           font = "Verdana 10 bold", bg = "white").grid(column = 1, row = 4, sticky= Tk.S)
        self.Slider_Teilchenzahl = Tk.Scale(self.root, from_=1, to=20,\
                                            orient = "horizontal", bg = "white") #Schieberegler
        self.Slider_Teilchenzahl.grid(column = 1, row = 5) #Schieberegler platzieren
        self.Slider_Teilchenzahl.set(5) #Startwert
        self.Button_Teilchenzahl = Tk.Button(self.root, text="Change number of particles",\
                                             bg = "lightgreen", compound = "left", width = 18,\
                                             command=self.update_Teilchenzahl).grid(column = 1, row = 6)
                                             #Knopf, ruft Funktion für Teilchenzahl auf

        #3.4 Dropdownmenü für Änderung der Teilchenart

        self.Label_Teilchenart = Tk.Label(self.root, text = "Gas type", font = "Verdana 10 bold",\
                                          bg = "white").grid(column = 1, row = 7, sticky = Tk.S)
        Edelgase = ["Helium","Neon", "Argon","Krypton","Xenon"] #Liste der Optionen
        Variable = Tk.StringVar() #Definition des Wert des Widgets, Hält eine Zeichenfolge; Standardwert ""
        Variable.set(Edelgase[0]) #gibt an welches Element der Liste im Menü angezeigt wird
        self.dropdown = Tk.OptionMenu(self.root, Variable, *Edelgase, command= \
                                      self.update_Teilchenart).grid(column = 1, row = 8)  #Widget für Dropdown-Menü erstellen

        #3.5 Label mit Informationen zur aktuellen Simulation

        self.Infos = Tk.Label(self.root, text = "Informationen", bg = "white", font = \
                              "Verdana 10 bold").grid(column = 2, row = 7, sticky = Tk.S)
        self.Label_Infos = Tk.Label(self.root, text = "Infos", justify = "left") #Label erstellen
        self.Label_Infos.grid(column = 2, row = 8) #Label platzieren

        #3.6 Teilchentracker zum An- und Ausschalten

        self.Label_Teilchentracker = Tk.Label(self.root, text = "Track particle", font = \
                                              "Verdana 10 bold", bg = "white").grid(column = 2, row = 4, sticky = Tk.S)
        self.Button_teilchen_verfolgen = Tk.Button(self.root, fg = "darkgreen", text="Teilchen verfolgen", bg = "white",\
                                                   height = 2, command=self.teilchen_verfolgen).grid(column = 2, row = 5, \
                                                   rowspan = 2, sticky = Tk.N, pady = 12)
                                                   #Knopf, aktiviert Teilchentracker

        #3.7 Stopp-Knopf zum Beenden des Programms

        self.Beenden = Tk.Button(self.root, text = "Interrupt", fg= "white", bg="maroon",\
                                 command = self.stopp, width = 65).grid(column = 1, row = 9, columnspan = 2)
                                 #Knopf, ruft Stopp-Funktion auf

    #Funktionen für Tkinter-Schaltflächen:

    def update_Temperatur(self):
        box.Temperatur = self.Slider_Temperatur.get() #Wert des Schiebereglers abrufen
        box.start_Animation() #Startbedingungen aktualisieren

    def update_Teilchenzahl(self):
        box.Teilchenzahl = self.Slider_Teilchenzahl.get() #Wert des Schiebereglers abrufen
        box.particles = [Particle(i) for i in range(box.Teilchenzahl)] #neue Teilchen erstellen
        box.start_Animation() #Startbedingungen aktualisieren

    def update_Teilchenart(self, Variable):
        partikel.Teilchenart = str(Variable) #Teilchenart als String speichern (für Infolabel)
        partikel.m = Masse.get(Variable) #Masse im Dictionary nachschlagen und aktualisieren
        partikel.R = Durchmesser.get(Variable) #Teilchenradius im Dictionary nachschlagen und aktualisieren
        partikel.color = Farbe.get(Variable) #Farbe im Dictionary nachschlagen und aktualisieren
        partikel.epsilon = LennardJones_epsilon.get(Variable) #Parameter im Dictionary nachschlagen und aktualisieren
        partikel.sigma = LennardJones_sigma.get(Variable) #Parameter im Dictionary nachschlagen und aktualisieren
        box.start_Animation() #Startbedingungen aktualisieren

    def teilchen_verfolgen(self): #Möglichkeit die Farbe eines Teilchens zu ändern und den Beschleunigungsvektor zu verfolgen
        global patch, Inaktiv_text
        if self.Teilchentracker_aus: #wenn noch nicht aktiv
            Inaktiv_text.remove() #Text aus Plot entfernen
            arrow.canvas.draw()
            self.Button_teilchen_verfolgen = Tk.Button(self.root, foreground = "white",\
                                                       text="Teilchen entfolgen", bg = "darkgreen", height = 2,\
                                                       command=self.teilchen_verfolgen).grid(column = 2, row = 5,\
                                                       rowspan = 2, sticky = Tk.N, pady = 12)
                                                       #Knopf ändert sein Aussehen
            self.Teilchentracker_aus = False

        else: #falls schon aktiv
            Inaktiv_text = arr.text(0,0,'Aktiviere \n"Teilchen verfolgen"', ha="center", va = "center", fontsize = 8.)
                #Text in Plot einfügen
            arrow.canvas.draw()
            self.Button_teilchen_verfolgen = Tk.Button(self.root, foreground = "darkgreen",\
                                                       text="Teilchen verfolgen", bg = "white", height = 2,\
                                                       command=self.teilchen_verfolgen).grid(column = 2, row = 5,\
                                                       rowspan = 2, sticky = Tk.N, pady = 12)
                                                       #Knopf ändert sein Aussehen
            patch.remove() #Pfeil entfernen
            Pfeil = patches.Arrow(0, 0, 0, 0) #einen neuen Pfeil der Länge 0 erstellen
            patch = arr.add_patch(Pfeil) #Pfeil hinzufügen
            arrow.canvas.draw() #Pfeil anzeigen
            self.Teilchentracker_aus = True

    def stopp(self):
       self.root.destroy() #Tkinter-Fenster schließen
       self.root.quit() #Programmausführung stoppen

interface = Interface() #auf die Klasse Interface() mit interface zugreifen

#4. Beschleunigungspfeil für das erste Teilchen

def pfeil(Beschleunigung):
    global patch
    if interface.Teilchentracker_aus == False: #nur wenn Teilchentracker aktiv ist
        Betrag_Beschleunigung = np.sqrt(Beschleunigung[0]**2 + Beschleunigung[1]**2)
        if Betrag_Beschleunigung != 0:
            patch.remove() #Pfeil entfernen
            Pfeil_x = Beschleunigung[0]/np.abs(Beschleunigung[0]) \
                * np.log(np.abs(Beschleunigung[0]))/50 #logarithmisch skalierte Beschleunigung,
                                                        #um die nötigen Größenordnungen abzudecken
            Pfeil_y = Beschleunigung[1]/np.abs(Beschleunigung[1]) \
                * np.log(np.abs(Beschleunigung[1]))/50 #logarithmisch skalierte Beschleunigung
            Pfeil = patches.FancyArrow(0, 0, Pfeil_x, Pfeil_y, color = "maroon", width = 0.05, overhang = 0.2,\
                                       head_width = 0.25, head_length = 0.3) #Pfeil mit den Komponenten der
                                                                                #Beschleunigung erstellen
            patch = arr.add_patch(Pfeil) #Pfeil hinzufügen
            arrow.canvas.draw() #Pfeil anzeigen

#5. Kritischer Radius

kritischerRadius = 4e-9 # entspricht 40% der Boxgröße, um Rechenaufwand zu reduzieren

#6. Teilchen als Klasse:

class Particle(): #Ordnet jedem Teilchen einen Radius (R), Masse (m), Farbe (color),
                    #und die Parameter für das Lennard-Jones-Potential (sigma, epsilon) zu
   def __init__(self, R = 36.58, m = 6.642e-27, color = "blue", epsilon = 14e-23, sigma = 2.56e-10, Teilchenart = "Helium"):
       self.R, self.m, self.color, self.epsilon, self.sigma, self.Teilchenart = R, m, color, epsilon, sigma, Teilchenart

partikel = Particle() #auf Klasse Particle() als partikel zugreifen

# 7. Funktionen für die Bewegung der Teilchen in der Box

class Box(): #enthält die Funktionen für die Bewegung der Teilchen in der Box

    def __init__(self, Teilchenzahl = 5, dt=4E-15, Temperatur = 300, Boxgroesse = 1e-8,\
                 Anfangsgeschwindigkeit = 1367.8, E_gesamt = 3.1e-20):
                 #Default-Werte für Anzahl der Teilchen, Zeitintervall, Temperatur, Boxgröße, Anfangsgeschwindigkeit, Gesamtenergie
        self.dt, self.Teilchenzahl, self.Temperatur, self.Boxgroesse, self.Anfangsgeschwindigkeit, \
            self.E_gesamt  = dt, Teilchenzahl, Temperatur, Boxgroesse, Anfangsgeschwindigkeit, E_gesamt
        self.particles = [Particle(i) for i in range(self.Teilchenzahl)] #für jedes Teilchen eine Instanz der Particle-Klasse erstellen

    #7.1 Startbedingungen für die Simulation berechnen und festlegen

    def start_Animation(self):
        self.scatter = ax.scatter([],[], s= partikel.R) #Streudiagramm mit Teilchen als Marker, Größe entsprechend des Teilchenradius
        self.Anfangsgeschwindigkeit = self.mittlere_Geschwindigkeit(self.Temperatur) #Anfangsgeschwindigkeit aus Temperatur berechnen
        self.E_gesamt = self.gesamtenergie(self.Teilchenzahl, self.Anfangsgeschwindigkeit) #Gesamtenergie aus kinetischer Energie bestimmen
        Infos = "Edelgas: " + partikel.Teilchenart + \
            "\nMasse: %10.3e kg \nGesamtenergie: %10.3e J \nMittlere Geschwindigkeit: %8.2f m/s" \
            % (partikel.m, box.E_gesamt, box.Anfangsgeschwindigkeit) #Text für das Info-Label
        interface.Label_Infos.configure(text = Infos) #Labelinhalt aktualisieren
        box.startpositionen() #Startpositionen-Funktion aufrufen
        for particle in self.particles:
            angle = random.uniform(-1, 1) #zufälliger Winkel für Richtung der Geschwindigkeit
            particle.v = np.array([(np.cos(angle * np.pi/2)), (np.sin(angle * np.pi/2))]) \
                * self.Anfangsgeschwindigkeit #Anfangsgeschwindigkeit als Array definieren
            particle.a = np.zeros(2) #Beschleunigung zum Zeitpunkt t=0 ist Null

    #7.1.1 Anfangsgeschwindigkeit der Teilchen als mittlere Geschwindigkeit festlegen

    def mittlere_Geschwindigkeit(self, T):
        return np.sqrt(3*k*T/partikel.m) #Als mittlere Geschwindigkeit über Temperatur berechnen

    #7.1.2 Gesamtenergie aller Teilchen berechnen

    def gesamtenergie(self, Teilchenzahl, v):
        return Teilchenzahl * 0.5 * partikel.m * v**2 #Summe der kinetischen Energie

    #7.1.3 Startpostitionen der Teilchen zufällig bestimmen

    def startpositionen(self):
        for particle in self.particles:
            particle.r = 100*np.random.uniform(0, self.Boxgroesse/100, size=2) #Startposition zufällig
                                                                                #innerhalb des Kastens festlegen

        #Wiederholung der zufälligen Teilchenverteilung bei Überlappung von 2 Teilchen zu Beginn der Animation

        for particle, particle2 in itertools.combinations(self.particles, 2): #für jedes Teilchenpaar
              # Abstand berechnen
              x_diff = particle.r[0] - particle2.r[0]
              y_diff = particle.r[1] - particle2.r[1]
              Abstand = np.sqrt(x_diff**2 + y_diff**2)

              if Abstand < 1.12*partikel.sigma: #wenn Abstand kleiner abstoßende Wechselwirkunegn
                  box.startpositionen() #neue Startpositionen berechnen

    #7.2 Trajektorien der Teilchen über Velocity-Verlet-Algorithmus bestimmen

    def zeitliche_Entwicklung(self, particles, Boxgroesse, dt, E_gesamt):
        box.kollision_Box(particles, Boxgroesse) #elastische Stöße mit Wand berücksichtigen
        for particle in particles:
            particle.r += dt * particle.v + dt**2*particle.a #Ort nach Velocity-Verlet-Algorithmus bestimmen
            particle.a_vorher = particle.a #Wert für die Beschleunigung für nächsten Zeitschritt speichern
            particle.a = np.zeros(2) #Beschleunigung wieder auf Null setzen vor neuer Evaluation des Potentials
            box.beschleunigung(particles) #Beschleunigung aus dem Potential berechnen
            particle.v = (particle.v + dt/2 * (particle.a + particle.a_vorher)) \
                * box.normierung(particles, E_gesamt) #Geschwindigkeit nach Velocity-Verlet-Algorithmus bestimmen und normieren
        pfeil(box.particles[0].a)  #Beschleunigungspfeil updaten

    #7.2.1 Elastische Stöße mit den Wänden der Box

    def kollision_Box(self, particles, Boxgroesse):
       for particle in self.particles:
           for i in range(0,2): #für x- und y-Koordinate
               if particle.r[i] >= Boxgroesse:
                       particle.r[i] = Boxgroesse #Verhindert 'Tunneling', wo die Geschwind. eines sehr schnellen
                                             # Teilchens vor Rückkehr in den Kasten zweimal gespiegelt wird
                       particle.v[i] *=-1 #Spiegelung der Geschwindigkeit
               if particle.r[i] <= 0:
                       particle.r[i] = 0 #s.o.
                       particle.v[i] *=-1

    #7.2.2 Abstand und Beschleunigung der Teilchen bestimmen

    def beschleunigung(self, particles):
       for particle, particle2 in itertools.combinations(self.particles, 2):  #über alle Paare von Teilchen iterieren

           #Abstand berechnen
           x_diff = particle.r[0] - particle2.r[0]
           y_diff = particle.r[1] - particle2.r[1]
           Abstand = np.sqrt(x_diff**2 + y_diff**2)

           #Wechselwirkung aus Potential berechnen:

           if Abstand < kritischerRadius: #nur Wechselwirkung bestimmen, wenn innerhalb des kritischen Radius
                Wechselwirkung = self.lennardJones_Kraft(Abstand) #Abstand in Lennard-Jones-Potential einsetzen
                particle.a[0] -= 1/(partikel.m) * Wechselwirkung * x_diff/Abstand
                particle.a[1] -= 1/(partikel.m) * Wechselwirkung * y_diff/Abstand
                particle2.a[0] += 1/(partikel.m) * Wechselwirkung * x_diff/Abstand
                particle2.a[1] += 1/(partikel.m) * Wechselwirkung * y_diff/Abstand

    #7.2.3 Lennard-Jones-Potential

    def lennardJones_Kraft(self, Distanz): #Kraft als Gradient des LennardJones-Potentials in Abhängigkeit
                                            #vom Abstand der Teilchen
        return (-24 * partikel.epsilon) * (2 *(partikel.sigma**12 / Distanz**13) -(partikel.sigma**6 / Distanz**7))

    #7.2.4 Geschwindigkeiten für Energieerhaltung normieren

    def normierung(self, particles, E_gesamt):
        Summe_v=0
        for particle in particles:
            Summe_v += particle.v**2 #alle Geschwindigkeitsquadrate aufaddieren
        return np.sqrt(E_gesamt /(0.5*Particle().m*Summe_v)) #neue Gesamtenergie bestimmen und Skalierungsfaktor zurückgeben

    #7.3 Position der Teilchen zurückgeben

    def position(self, particles): #Funktion um den Ort jedes Teilchens an die Animation zu übergeben
        return [particle.r for particle in particles]

box = Box() #auf die Klasse Box() als box zugreifen

#8. Animation starten und Programm ausführen

def particle_Farbe(particles):
    for particle in box.particles:
     particle.color = partikel.color #jedem Teilchen die Farbe des Edelgases aus der Particle-Klasse zuweisen
    if interface.Teilchentracker_aus == False: #wenn Teiclhentracker aktiviert
        box.particles[0].color = "red" #erstes Teilchen wird rot eingefärbt
    return [particle.color for particle in box.particles] #Farben zurückgeben

def init(): #Box darstellen
    ax.set_xlim (0, box.Boxgroesse) #Boxgröße einstellen
    ax.set_ylim (0, box.Boxgroesse)
    ax.xaxis.set_major_locator(ticker.FixedLocator(np.arange(0,12e-9, 2e-9))) #Ticklabels einstellen
    ax.yaxis.set_major_locator(ticker.FixedLocator(np.arange(0,12e-9, 2e-9)))
    ax.xaxis.set_ticklabels(np.arange(0,11,2)) #Beschriftungen in nm festlegen
    ax.yaxis.set_ticklabels(np.arange(0,11,2))
    ax.set_xlabel("Boxbreite in nm") #Achsenbeschriftung
    return box.scatter,

def update(frame): #Funktion für die Animation (FunAn)
    box.zeitliche_Entwicklung(box.particles, box.Boxgroesse, box.dt, box.E_gesamt) #Funktion für zetilche Entwicklung aufrufen
    box.scatter.set_offsets(np.array(box.position(box.particles))) #neuen Ort der Marker übernehmen
    box.scatter.set_color(particle_Farbe(box.particles)) #Farbe der Teilchen ggf. ändern
    return box.scatter,

box.start_Animation() #Funktion für Startbedingungen aufrufen

ani = animation.FuncAnimation(fig, update , frames=range(10000), init_func = init, blit=True,\
                              interval = 1/2000, repeat = True) #Animation abrufen
Tk.mainloop() #Tkinter-Fenster aufrufen