from threading import Thread

from flask import Flask, request, redirect, session, render_template, send_file, Response, flash
from flask_session import Session
import os, json

from bs4 import BeautifulSoup, SoupStrainer
import requests, lxml, cchardet

app = Flask('')
app.config["SESSION_PERMANENT"] = False
app.config["SESSION_TYPE"] = "filesystem"
Session(app)

from requests_oauthlib import OAuth2Session
import getpass
import random, string, asyncio

import os
import shutil

app.config['GITHUB_CLIENT_ID'] = os.environ['GITHUB_CLIENT_ID']
app.config['GITHUB_CLIENT_SECRET'] = os.environ['GITHUB_CLIENT_SECRET']

# Disable SSL requirement
os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = '1'

# Settings for your app
base_discord_api_url = 'https://discordapp.com/api'
client_id = os.environ['DISCORD_CLIENT_ID'] # Get from https://discordapp.com/developers/applications
client_id.encode('unicode_escape')
client_secret = os.environ['DISCORD_CLIENT_SECRET']
redirect_uri='https://DataPak.coolcodersj.repl.co/oauth_callback'
scope = ['identify', 'email', 'connections', 'guilds', 'applications.builds.read']
token_url = 'https://discord.com/api/oauth2/token'
authorize_url = 'https://discord.com/api/oauth2/authorize'

app = Flask(__name__)
app.secret_key = os.environ['APP_SECRET_KEY'].encode('utf-8')

@app.route("/")
def home():
	if 'discord_token' not in session.keys():
		disc = ""
	else:
		discord = OAuth2Session(client_id, token=session['discord_token'])
		response = discord.get(base_discord_api_url + '/users/@me')
		disc = response.json()['username'] + "#" + response.json()['discriminator']
	if not "gh_token" in session.keys():
		gh = ""
	else:
		r = requests.get("https://api.github.com/user", headers={
			"Authorization": f"token {session['gh_token']}"
		})
		gh = r.json()['login']

	if not "spotify_token" in session.keys():
		spotify = ""
	else:
		r = requests.get("https://api.spotify.com/v1/me", headers={
			"Authorization": f"Bearer {session['spotify_token']}"
		})
		if "error" in r.json() and r.json()['error']['message'] == "The access token expired":
				spotify_client_id, spotify_client_secret = os.environ['SPOTIFY_CLIENT_ID'], os.environ['SPOTIFY_CLIENT_SECRET']
				r = requests.post("https://accounts.spotify.com/api/token", data={
					"grant_type": "refresh_token",
					"refresh_token": session['spotify_refresh_token'],
					"redirect_uri": "https://datapak.coolcodersj.repl.co/spotify/callback",
					'client_id': spotify_client_id,
					"client_secret": spotify_client_secret
				})
				session['spotify_token'] = r.json()['access_token']
				if "refresh_token" in r.json():
					session['spotify_refresh_token'] = r.json()['refresh_token']
		r = requests.get("https://api.spotify.com/v1/me", headers={
			"Authorization": f"Bearer {session['spotify_token']}"
		})
		spotify = r.json()['display_name']

	return render_template("index.html", replitusername=request.headers['X-Replit-User-Name'], discordusername=disc, gh=gh, spotify=spotify)

@app.route('/discord')
def discord():
	oauth = OAuth2Session(client_id, redirect_uri=redirect_uri, scope=scope)
	login_url, state = oauth.authorization_url(authorize_url)
	session['state'] = state
	return redirect(login_url)

@app.route("/oauth_callback")
def oauth_callback():
	print(type(client_id))
	discord = OAuth2Session(client_id, redirect_uri=redirect_uri, state=session['state'], scope=scope)
	token = discord.fetch_token(
		token_url,
		client_secret=client_secret,
		authorization_response=request.url,
	)
	session['discord_token'] = token
	return redirect("/")

@app.route("/discord/generate")
def gendisc():
	if not 'discord_token' in session:
		disc = ""
		return redirect("/")
	else:
		discord = OAuth2Session(client_id, token=session['discord_token'])
		response1 = discord.get(base_discord_api_url + '/users/@me')
		response2 = discord.get(base_discord_api_url + '/users/@me/connections')
		response3 = discord.get(base_discord_api_url + '/users/@me/guilds')
		disc = {"account": response1.json(), "connections": response2.json(), "guilds": response3.json()}
		resp = Response(json.dumps(disc))
		resp.headers['Content-Type'] = 'application/json'
		return resp

@app.route('/discord/info')
def discordinfo():
	return render_template("discordinfo.html")

@app.route('/replit/info')
def replitinfo():
	return render_template("replitinfo.html")

@app.route("/replit/generate")
def replit():
	try:
		username = request.headers['X-Replit-User-Name']
		os.remove(f'DataPak{username}.zip')
	except:
		pass
	globals()['replurls'] = []
	def findrepls(r):
		global replurls
		if r.status_code == 200:
			soup = BeautifulSoup(r.content, "lxml")
			btn = soup.find_all('a', class_='jsx-688104393')
			repls = soup.find_all("a", class_='repl-item-wrapper')
			for g in repls:
				globals()['replurls'].append(str(g['href']))
			if btn != []:
				r = requests.get(f"https://replit.com{btn[0]['href']}")
				findrepls(r)
			else:
				return
	r = requests.get(f"https://replit.com/@{request.headers['X-Replit-User-Name']}")
	findrepls(r)
	username = request.headers['X-Replit-User-Name']
	os.mkdir(f"DataPak{username}")
	for repl in replurls:
		r = requests.get(f'https://replit.com{repl}.zip')
		f = open(f'DataPak{username}/{repl.split("/")[-1]}.zip', "w+")
		print(r.content, file=f)
		f.close()
	r = requests.get(f"https://replit.com/data/profiles/{request.headers['X-Replit-User-Name']}").json()
	f = open(f'DataPak{username}/account.json', "a")
	del r['repls']
	print(r, file=f)
	f.close()
	shutil.make_archive(f'DataPak{username}', 'zip', f'DataPak{username}/')
	shutil.rmtree(f'DataPak{username}/')
	return send_file(f'DataPak{username}.zip', mimetype="application/zip", as_attachment=True)

@app.route('/spotify/info')
def spotinfo():
	return render_template('spotifyinfo.html')

@app.route('/spotify')
def spot():
	client_id, client_secret = os.environ['SPOTIFY_CLIENT_ID'], os.environ['SPOTIFY_CLIENT_SECRET']
	scopes = [
	'user-read-recently-played',
    'user-top-read',
    'user-read-playback-position',
	'user-read-playback-state',
    'user-read-currently-playing',
	'playlist-read-private',
    'playlist-read-collaborative',
	'user-follow-read',
	'user-follow-modify',
	'user-library-read',
	'user-read-email',
    'user-read-private',
	]
	scopes = " ".join(scopes)
	if not "spotify_token" in session.keys():
		return redirect(f"https://accounts.spotify.com/authorize?response_type=code&client_id={client_id}&scope={scopes}&redirect_uri=https://datapak.coolcodersj.repl.co/spotify/callback")
	else:
		artists = requests.get("https://api.spotify.com/v1/me/following?type=artist", headers={
			"Authorization": f"Bearer {session['spotify_token']}"
		})

		if artists.text == "":
			artists = {"None": "None"}
		else:
			if "message" in artists.json() and artists.json()['message'] == "The access token expired":
				client_id, client_secret = os.environ['SPOTIFY_CLIENT_ID'], os.environ['SPOTIFY_CLIENT_SECRET']
				r = requests.post("https://accounts.spotify.com/api/token", data={
					"grant_type": "refresh_token",
					"refresh_token": session['spotify_refresh_token'],
					"redirect_uri": "https://datapak.coolcodersj.repl.co/spotify/callback",
					'client_id': client_id,
					"client_secret": client_secret
				})
				session['spotify_token'] = r.json()['access_token']
				if "refresh_token" in r.json():
					session['spotify_refresh_token'] = r.json()['refresh_token']
				artists = requests.get("https://api.spotify.com/v1/me/following?type=artist", headers={
			"Authorization": f"Bearer {session['spotify_token']}"
				})
			artists = artists.json()['artists']['items']

		albums = []
		album_req = requests.get("https://api.spotify.com/v1/me/albums", headers={
			"Authorization": f"Bearer {session['spotify_token']}"
		})
		for item in album_req.json()['items']:
			albums.append(item)
		while "next" in album_req.json() and album_req.json()['next'] != None:
			album_req = requests.get(album_req.json()['next'], headers={
			"Authorization": f"Bearer {session['spotify_token']}"
			})
			for item in album_req.json()['items']:
				albums.append(item)

		playlists = []
		playlist_req = requests.get("https://api.spotify.com/v1/me/playlists", headers={
			"Authorization": f"Bearer {session['spotify_token']}"
		})
		for item in playlist_req.json()['items']:
			playlists.append(item)
		while "next" in playlist_req.json() and playlist_req.json()['next'] != None:
			playlist_req = requests.get(playlist_req.json()['next'], headers={
			"Authorization": f"Bearer {session['spotify_token']}"
			})
			for item in playlist_req.json()['items']:
				playlists.append(item)

		liked_songs = []
		track_req = requests.get("https://api.spotify.com/v1/me/tracks", headers={
			"Authorization": f"Bearer {session['spotify_token']}"
		})
		for item in track_req.json()['items']:
			liked_songs.append(item)
		while "next" in track_req.json() and track_req.json()['next'] != None:
			track_req = requests.get(track_req.json()['next'], headers={
			"Authorization": f"Bearer {session['spotify_token']}"
			})
			for item in track_req.json()['items']:
				liked_songs.append(item)

		liked_episodes = []
		episode_req = requests.get("https://api.spotify.com/v1/me/episodes", headers={
			"Authorization": f"Bearer {session['spotify_token']}"
		})
		for item in episode_req.json()['items']:
			liked_episodes.append(item)
		while "next" in episode_req.json() and episode_req.json()['next'] != None:
			episode_req = requests.get(episode_req.json()['next'], headers={
			"Authorization": f"Bearer {session['spotify_token']}"
			})
			for item in episode_req.json()['items']:
				liked_episodes.append(item)

		shows = []
		show_req = requests.get("https://api.spotify.com/v1/me/shows", headers={
			"Authorization": f"Bearer {session['spotify_token']}"
		})
		for item in show_req.json()['items']:
			shows.append(item)
		while "next" in show_req.json() and show_req.json()['next'] != None:
			show_req = requests.get(show_req.json()['next'], headers={
			"Authorization": f"Bearer {session['spotify_token']}"
			})
			for item in show_req.json()['items']:
				shows.append(item)

		top_tracks = []
		track_req = requests.get("https://api.spotify.com/v1/me/top/tracks", headers={
			"Authorization": f"Bearer {session['spotify_token']}"
		})
		for item in track_req.json()['items']:
			top_tracks.append(item)
		while "next" in track_req.json() and track_req.json()['next'] != None:
			track_req = requests.get(track_req.json()['next'], headers={
			"Authorization": f"Bearer {session['spotify_token']}"
			})
			for item in track_req.json()['items']:
				top_tracks.append(item)

		top_artists = []
		artist_req = requests.get("https://api.spotify.com/v1/me/top/tracks", headers={
			"Authorization": f"Bearer {session['spotify_token']}"
		})
		for item in artist_req.json()['items']:
			top_artists.append(item)
		while "next" in artist_req.json() and artist_req.json()['next'] != None:
			artist_req = requests.get(artist_req.json()['next'], headers={
			"Authorization": f"Bearer {session['spotify_token']}"
			})
			for item in artist_req.json()['items']:
				top_artists.append(item)

		current_playback = requests.get("https://api.spotify.com/v1/me/player", headers={
			"Authorization": f"Bearer {session['spotify_token']}"
		})
		if current_playback.text == '':
			current_playback = {"error": "Nothing was playing while backing up."}
		else:
			current_playback = current_playback.json()

		devices = requests.get("https://api.spotify.com/v1/me/player/devices", headers={
			"Authorization": f"Bearer {session['spotify_token']}"
			})

		if devices.text == '':
			devices = {"error": "No devices available."}
		else:
			devices = devices.json()

		recently_played = []
		req = requests.get("https://api.spotify.com/v1/me/player/recently-played", headers={
			"Authorization": f"Bearer {session['spotify_token']}"
		})
		for item in req.json()['items']:
			recently_played.append(item)
		while "next" in req.json() and req.json()['next'] != None:
			req = requests.get(req.json()['next'], headers={
			"Authorization": f"Bearer {session['spotify_token']}"
			})
			for item in req.json()['items']:
				recently_played.append(item)

		profile = requests.get("https://api.spotify.com/v1/me", headers={
			"Authorization": f"Bearer {session['spotify_token']}"
		})

		username = profile.json()['display_name']
		os.mkdir(f"DataPak{username}/")

		f = open(f"DataPak{username}/library.json", "w")
		print({"artists": artists, "albums": albums, "playlists": playlists, "liked_songs": liked_songs, "liked_episodes": liked_episodes, "shows": shows, "top_tracks": top_tracks, "top_artists": top_artists}, file=f)
		f.close()

		f = open(f"DataPak{username}/playback.json", "w")
		print({"current_playback": current_playback, "devices": devices, "recently_played": recently_played}, file=f)
		f.close()

		f = open(f"DataPak{username}/profile.json", "w")
		print(profile.json(), file=f)
		f.close()

		shutil.make_archive(f'DataPak{username}', 'zip', f'DataPak{username}/')
		shutil.rmtree(f'DataPak{username}/')
		return send_file(f'DataPak{username}.zip', mimetype="application/zip", as_attachment=True)

@app.route('/spotify/callback')
def spotcallback():
	code = request.args.get("code")
	client_id, client_secret = os.environ['SPOTIFY_CLIENT_ID'], os.environ['SPOTIFY_CLIENT_SECRET']
	r = requests.post("https://accounts.spotify.com/api/token", data={
		"grant_type": "authorization_code",
		"type": "authorization_code",
		"code": code,
		"redirect_uri": "https://datapak.coolcodersj.repl.co/spotify/callback",
		'client_id': client_id,
		"client_secret": client_secret
	})
	session['spotify_token'] = r.json()['access_token']
	session['spotify_refresh_token'] = r.json()['refresh_token']
	return redirect('/')

@app.route('/github/info')
def ghinfo():
	return render_template("ghinfo.html")

@app.route('/github')
def github():
	if not "gh_token" in session:
		state = "irajfvnqehrtdfwbejktrbnvfbiwkjetrnfgcwkjenrsflwejkbtnfjbrethvbw3urskejg"
		session['state'] = state
		return redirect(f"https://github.com/login/oauth/authorize?state={state}&client_id={os.environ['GITHUB_CLIENT_ID']}&scope=repo read:repo_hook read:org read:public_key gist user read:discussion read:packages read:gpg_key&redirect_uri=https://DataPak.coolcodersj.repl.co/github/callback")
	else:
		r = requests.get("https://api.github.com/user", headers={
			"Authorization": f"token {session['gh_token']}"
		})
		account = r.json()
		r = requests.get(f"https://api.github.com/users/{account['login']}/followers", headers={
			"Authorization": f"token {session['gh_token']}"
		})
		followers = r.json()
		r = requests.get(f"https://api.github.com/users/{account['login']}/following", headers={
			"Authorization": f"token {session['gh_token']}"
		})
		following = r.json()
		r = requests.get(f"https://api.github.com/users/{account['login']}/gists", headers={
			"Authorization": f"token {session['gh_token']}"
		})
		gists = r.json()
		r = requests.get(f"https://api.github.com/users/{account['login']}/starred", headers={
			"Authorization": f"token {session['gh_token']}"
		})
		starred = r.json()
		r = requests.get(f"https://api.github.com/users/{account['login']}/subscriptions", headers={
			"Authorization": f"token {session['gh_token']}"
		})
		watchlist = r.json()
		r = requests.get(f"https://api.github.com/users/{account['login']}/orgs", headers={
			"Authorization": f"token {session['gh_token']}"
		})
		organizations = r.json()
		r = requests.get(f"https://api.github.com/users/{account['login']}/repo", headers={
			"Authorization": f"token {session['gh_token']}"
		})
		repos = r.json()
		os.mkdir(f"DataPak{account['login']}/")
		print(account, file=open(f"DataPak{account['login']}/account.json", "w"))
		print(followers, file=open(f"DataPak{account['login']}/followers.json", "w"))
		print(following, file=open(f"DataPak{account['login']}/following.json", "w"))
		print(gists, file=open(f"DataPak{account['login']}/gists.json", "w"))
		print(starred, file=open(f"DataPak{account['login']}/starred.json", "w"))
		print(watchlist, file=open(f"DataPak{account['login']}/watchlist.json", "w"))
		print(organizations, file=open(f"DataPak{account['login']}/orgs.json", "w"))
		print(repos, file=open(f"DataPak{account['login']}/repos.json", "w"))

		username = account['login']

		for repo in repos:
			name = repo['name']
			branch = repo['default_branch']
			r = requests.get(f'https://github.com/{username}/{name}/archive/refs/heads/{branch}.zip')
			f = open(f'DataPak{username}/{name}.zip', "w+")
			print(r.content, file=f)
			f.close()

		shutil.make_archive(f'DataPak{username}', 'zip', f'DataPak{username}/')
		shutil.rmtree(f'DataPak{username}/')
		return send_file(f'DataPak{username}.zip', mimetype="application/zip", as_attachment=True)

@app.route('/github/callback')
def authorized():
	code = request.args.get("code")
	r = requests.post("https://github.com/login/oauth/access_token", data={
		"client_id": os.environ['GITHUB_CLIENT_ID'],
		"client_secret": os.environ['GITHUB_CLIENT_SECRET'],
		"code": code,
		"state": session['state']
	},
	headers={
		"Accept": "application/json"
	})
	session['gh_token'] = r.json()['access_token']
	return redirect("/")

app.run(host="0.0.0.0", port=8080)


import matplotlib.pyplot as plt
import cv2
import numpy as np
# from pyradar.classifiers.isodata import isodata_classification
from isodataclassifier import isodata_classification

def equalize_histogram(img, histogram, cfs):
    """
    Equalize pixel values to [0:255].
    """
    total_pixels = img.size
    N, M = img.shape
    min_value = img.min()
    L = 256  # Number of levels of grey
    cfs_min = cfs.min()
    img_corrected = np.zeros_like(img)
    corrected_values = np.zeros_like(histogram)

    divisor = np.float32(total_pixels) - np.float32(cfs_min)

    if not divisor:  # this happens when the image has all the values equals
        divisor = 1.0

    factor = (np.float32(L) - 1.0) / divisor

    corrected_values = ((np.float32(cfs) -
                         np.float32(cfs_min)) * factor).round()

    img_copy = np.uint64(img - min_value)
    img_corrected = corrected_values[img_copy]

    return img_corrected

def equalization_using_histogram(img):

    # Create histogram, bin edges and cumulative distributed function
    max_value = img.max()
    min_value = img.min()

    assert min_value >= 0, \
        "ERROR: equalization_using_histogram() img have negative values!"

    start, stop, step = int(min_value), int(max_value + 2), 1

    histogram, bin_edge = np.histogram(img, xrange(start, stop, step))
    cfs = histogram.cumsum()  # cumulative frencuency table
    img_corrected = equalize_histogram(img, histogram, cfs)

    return img_corrected

params = {"K": 100, "I" : 1000, "P" : 10, "THETA_M" : 10, "THETA_S" : 0.01,"THETA_C" : 8, "THETA_O" : 0.02}

img = cv2.imread('dataset/original/before.jpg',0)
# kernel = np.ones((5,5),np.uint8)
plt.imshow(img)
plt.show()

kernel 	= cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(1,1))
# print('Before')
img = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel, iterations=7)
img = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel, iterations=7)

# print('Operated Image')
#plt.imshow(img)
#plt.show()

# img = cv2.imread('dataset/after.jpg',0)
# # kernel = np.ones((5,5),np.uint8)
# kernel 	= cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(1,1))
# print('After')
# img = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel, iterations=7)
# img = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel, iterations=7)

# print("After Operated Image")
# imgplot = plt.imshow(img)
# plt.show()

# run Isodata
class_image = isodata_classification(img, parameters=params)
# plt.imshow(class_image);
# plt.show()

# # equalize class image to 0:255

class_image_eq = equalization_using_histogram(class_image)

# # save it
save_image(IMG_DEST_DIR, "image_eq", image_eq)

# print("Equalized image classified using histogram 1")
# imgplot = plt.imshow(class_image_eq)
# plt.show()

# # also save original image
# image_eq = equalization_using_histogram(image)
# # save it
# print("Equalized image classified using histogram 2")
# #imgplot = plt.imshow(image_eq)
# #plt.show()


import cv2
import numpy as np

def get_crops(img, annotations, padding=0):
	crops = []
	new_img = img.copy() # Prevent drawing on original image
	for a in annotations:
		c = a['coordinates']

		y1, y2 = int(c['y'] - c['height'] / 2 - padding), int(c['y'] + c['height'] / 2 + padding)
		x1, x2 = int(c['x'] - c['width'] / 2 - padding), int(c['x'] + c['width'] / 2 + padding)

		crop = new_img[y1: y2, x1:x2]
		crops.append(crop)
	return crops

def segment(crops):
	segs = []
	for c in crops:
		gray = cv2.cvtColor(c, cv2.COLOR_BGR2GRAY)
		ret, thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)

		# noise removal
		kernel = np.ones((3,3),np.uint8)
		opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN,kernel, iterations = 4)
		# sure background area
		sure_bg = cv2.dilate(opening,kernel, iterations=3)
		# Finding sure foreground area
		dist_transform = cv2.distanceTransform(opening,cv2.DIST_L2,5)
		ret, sure_fg = cv2.threshold(dist_transform,0.7*dist_transform.max(),255,0)
		# Finding unknown region
		sure_fg = np.uint8(sure_fg)
		unknown = cv2.subtract(sure_bg,sure_fg)
		# Marker labelling
		ret, markers = cv2.connectedComponents(sure_fg)
		# Add one to all labels so that sure background is not 0, but 1
		markers = markers+1
		# Now, mark the region of unknown with zero
		markers[unknown==255] = 0

		markers = cv2.watershed(c, markers)
		markers[:,[0,-1]] = markers[[0,-1]] = 1
		c[markers != 1] = [255,191,0]

		segs.append(c)

	return segs

def draw(img, annotations, segs, padding=0):
	overlay = img.copy()

	for i in range(len(annotations)):
		a = annotations[i]
		c = a['coordinates']

		y1, y2 = int(c['y'] - c['height'] / 2 - padding), int(c['y'] + c['height'] / 2 + padding)
		x1, x2 = int(c['x'] - c['width'] / 2 - padding), int(c['x'] + c['width'] / 2 + padding)

		overlay[y1: y2, x1:x2] = segs[i]

	alpha = 0.5
	cv2.addWeighted(overlay, alpha, img, 1 - alpha,0, img)

	return img


import random
from turtle import Screen
from display import DisplaySet
from paddle import Paddle
from ball import Ball
from score import Score
import time

screen = Screen()
screen.title('PONG')
screen.bgcolor('black')
screen.setup(height=600, width=800)
screen.tracer(0)
set_game_field = DisplaySet()
game_on = True
ball = Ball()
score = Score()
score_p1 = Score()
score_p2 = Score()
paddle_1 = Paddle()
paddle_2 = Paddle()

paddle_1.paddle_position(-350)
score_p1.score_position(-120)
paddle_2.paddle_position(350)
score_p2.score_position(100)

screen.listen()
screen.onkey(paddle_1.paddle_up, 'q')
screen.onkey(paddle_1.paddle_down, 'a')

screen.onkey(paddle_2.paddle_up, 'Up')
screen.onkey(paddle_2.paddle_down, 'Down')

while game_on:
    time.sleep(ball.ball_speed)
    screen.update()
    ball.ball_on_the_run()
    tilt_angle = random.randrange(4, 8)
    if ball.ycor() > 280 or ball.ycor() < -280:
        new_angle = 360 - ball.heading()
        ball.setheading(new_angle)

    elif ball.distance(paddle_1) < 50 and ball.xcor() < -330:
        new_angle = 360 - (ball.heading() * 2 - tilt_angle)
        ball.setheading(new_angle)

    elif ball.distance(paddle_2) < 50 and ball.xcor() > 330:
        new_angle = 180 - (ball.heading() * 2 + tilt_angle)
        ball.setheading(new_angle)

    elif ball.xcor() > 370:
        ball.p1_score_set()
        score_p1.score_count()

    elif ball.xcor() < -370:
        ball.p2_score_set()
        score_p2.score_count()

    if score_p1.score == 10 or score_p2.score == 10:
        score.end_game()
        game_on = False

screen.exitonclick()


import cv2
import os
from ultralytics import YOLO
from datetime import datetime, timedelta

# Load the YOLOv8 model
modelo_pt = r'Modelos\Deploys_Ultralytics_Hub\detector_de_placas_yolov8_nano.pt'
model = YOLO(f'{modelo_pt}')

# Open the video file
video_path = r"Video\Video_teste.mp4"
cap = cv2.VideoCapture(video_path)

# Certifique-se de que o diretório de saída existe, senão crie-o
save_path_cortadas = r"Resultado_de_dados\imagens_cortadas"
if not os.path.exists(save_path_cortadas):
    os.makedirs(save_path_cortadas)

save_path_inteiras = r"Resultado_de_dados\imagens_inteiras"
if not os.path.exists(save_path_inteiras):
    os.makedirs(save_path_inteiras)

# Defina manualmente o horário de início da gravação IMPORTANTISSIMO!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
start_time = datetime(2023, 10, 30, 17, 35, 9)

# Loop through the video frames
file_num = 0
unique_id = set()

# Define a nova largura e altura desejada
new_width, new_height = 1100, 600

while cap.isOpened():
    # Read a frame from the video
    success, frame = cap.read()

    if success:
        # Resize the frame to 640x640
        frame = cv2.resize(frame, (new_width, new_height))

        # Run YOLOv8 inference on the frame
        results = model.track(frame, persist=True, conf=0.95, save_txt=True)
        #results = model.predict(frame, conf=0.95, save_txt=True)

        if results[0].boxes.id is not None:
            boxes = results[0].boxes.xyxy.cpu().numpy().astype(int)
            ids = results[0].boxes.id.cpu().numpy().astype(int)

            for box, id in zip(boxes, ids):
                int_id = int(id)

                if int_id not in unique_id:
                    unique_id.add(int_id)
                    box = box[:4]

                    # Crop the image using the bounding box coordinates
                    cropped_img = frame[box[1]:box[3], box[0]:box[2]]
                    class_id = int(id)

                    # Calcular o horário de detecção somando os segundos desde o início do vídeo ao horário de início
                    seconds_elapsed = cap.get(cv2.CAP_PROP_POS_FRAMES) / cap.get(cv2.CAP_PROP_FPS)
                    detection_time = start_time + timedelta(seconds=seconds_elapsed)

                    # Salvar a imagem recortada com o horário relativo
                    filename = f"imagem_destacada_do_id_{int_id}_horario_{detection_time.strftime('%H-%M-%S')}.jpg"
                    filepath = os.path.join(save_path_cortadas, filename)
                    cv2.imwrite(filepath, cropped_img)

                    filename_inteira = f"foto_inteira_do_id_{int_id}_horario_{detection_time.strftime('%H-%M-%S')}.jpg"
                    filepath_inteira = os.path.join(save_path_inteiras, filename_inteira)
                    cv2.imwrite(filepath_inteira, frame)

                frame = results[0].plot()

        # Display the annotated frame
        cv2.imshow(f"Detectando pelo modelo: {modelo_pt}", frame)

        # Break the loop if 'q' is pressed
        if cv2.waitKey(1) & 0xFF == ord("q"):
            break
    else:
        # Break the loop if the end of the video is reached
        break

# Release the video capture object and close the display window
cap.release()
cv2.destroyAllWindows()


import pandas as pd
import numpy as np
import sqlite3
from datetime import timedelta
import matplotlib.pyplot as plt
import pandas as pd
from copy import deepcopy
from ipywidgets import IntProgress
import warnings
warnings.filterwarnings(action='ignore', category=FutureWarning) # setting ignore as a parameter and further adding category

def percentile(n):
    '''Calculate n - percentile of data'''
    def percentile_(x):
        return np.percentile(x, n)
    percentile_.__name__ = 'pctl%s' % n
    return percentile_

def fill_missing_dates(x, date_col):

    min_date, max_date = x[date_col].min(), x[date_col].max()
    groupby_day = x.groupby(pd.PeriodIndex(x[date_col], freq='D'))
    results = groupby_day.sum(min_count=1).sort_values(by=date_col)
    return results

    idx = pd.period_range(min_date, max_date)
    results = results.reindex(idx, fill_value=np.nan)

    results.index.rename(date_col, inplace=True)

    return results

def calc_preag_fill(data, group_col, date_col, target_cols, preagg_method):
    ## calc preaggregation
    data_preag = data.groupby(group_col).agg(
        preagg_method)[target_cols].reset_index().sort_values(by=date_col)

    ## fill missing dates
    data_preag_filled = data_preag.groupby(group_col[:-1]).apply(
        fill_missing_dates, date_col=date_col).drop(group_col[:-1],
                                                    axis=1).reset_index()

    ## return DataFrame with calculated preaggregation and filled missing dates
    return data_preag_filled

def calc_ewm(data_preag_filled, group_col, date_col, span):
    ## calc ewm stats

    lf_df_filled = data_preag_filled.groupby(group_col[:-1]).        apply(lambda x: x.set_index(date_col).ewm(span=span).mean()).drop(group_col[:-1], axis=1)

    ## return DataFrame with rolled columns from target_vars
    return lf_df_filled

def shift(lf_df_filled, group_col, date_col, lag):

    lf_df = lf_df_filled.groupby(
        level=group_col[:-1]).apply(lambda x: x.shift(lag)).reset_index()
    lf_df[date_col] = pd.to_datetime(lf_df[date_col].astype(str))

    ## return DataFrame with following columns: filter_col, id_cols, date_col and shifted stats
    return lf_df

def calc_rolling(data_preag_filled, group_col, date_col, method, w):

    ## calc rolling stats
    lf_df_filled = data_preag_filled.groupby(group_col[:-1]).        apply(lambda x: x.set_index(date_col).rolling(window=w, min_periods=1).agg(method)).drop(group_col[:-1], axis=1)

    ## return DataFrame with rolled columns from target_vars
    return lf_df_filled

def day_features(result2):
    result2["weekday"] = result2.period_dt.dt.weekday
    result2["monthday"] = result2.period_dt.dt.day
    result2['is_weekend'] = result2.weekday.isin([5,6])*1

    return result2

def generate_lagged_features(
        data: pd.DataFrame,
        target_cols: list = ['Demand'],
        id_cols: list = ['SKU_id', 'Store_id'],
        date_col: str = 'Date',
        lags: list = [7, 14, 21, 28],
        windows: list = ['7D', '14D', '28D', '56D'],
        preagg_methods: list = ['mean'],
        agg_methods: list = ['mean', 'median', percentile(10), pd.Series.skew],
        dynamic_filters: list = ['weekday', 'Promo'],
        ewm_params: dict = {'weekday': [14, 28], 'Promo': [14, 42]}) -> pd.DataFrame:

    '''
    data - dataframe with default index
    target_cols - column names for lags calculation
    id_cols - key columns to identify unique values
    date_col - column with datetime format values
    lags - lag values(days)
    windows - windows(days/weeks/months/etc.),
        calculation is performed within time range length of window
    preagg_methods - applied methods before rolling to make
        every value unique for given id_cols
    agg_methods - method of aggregation('mean', 'median', percentile, etc.)
    dynamic_filters - column names to use as filter
    ewm_params - span values(days) for each dynamic_filter
    '''

    data = data.sort_values(date_col)
    out_df = deepcopy(data)
    dates = [min(data[date_col]), max(data[date_col])]

    total = len(target_cols) * len(lags) * len(windows) * len(preagg_methods) * len(agg_methods) * len(dynamic_filters)
    progress = IntProgress(min=0, max=total)
    display(progress)

    for filter_col in dynamic_filters:
        group_col = [filter_col] + id_cols + [date_col]

        for lag in lags:
            for preagg in preagg_methods:
                data_preag_filled = calc_preag_fill(data, group_col, date_col,
                                                    target_cols, preagg)
                ## add ewm features
                for alpha in ewm_params.get(filter_col, []):

                    #print("%s %s %s %s" % (filter_col, lag, preagg, alpha))
                    ewm_filled = calc_ewm(data_preag_filled, group_col,
                                          date_col, alpha)

                    ewm = shift(ewm_filled, group_col, date_col, lag)
                    new_names = {x: "{0}_lag{1}d_alpha{2}_{3}".                        format(x, lag, alpha, filter_col) for x in target_cols}

                    out_df = pd.merge(out_df,
                                      ewm.rename(columns=new_names),
                                      how='outer',
                                      on=group_col)

                ## add rolling features
                for w in windows:
                    for method in agg_methods:
                        rolling_filled = calc_rolling(data_preag_filled,
                                                      group_col, date_col,
                                                      method, w)

                        ## lf_df - DataFrame with following columns: filter_col, id_cols, date_col, shifted rolling stats
                        rolling = shift(rolling_filled, group_col, date_col,
                                        lag)

                        method_name = method.__name__ if type(
                            method) != str else method

                        new_names = {x: "{0}_lag{1}d_w{2}_{3}".                                     format(x, lag, w, filter_col) for x in target_cols}
                        out_df = pd.merge(out_df,
                                          rolling.rename(columns=new_names),
                                          how='outer',
                                          on=group_col)
                        progress.value += 1

    return out_df

def preABT_modification(data : pd.DataFrame) -> (pd.DataFrame):

    target_cols = ['TGT_QTY']
    id_cols = ['PRODUCT_ID', 'LOCATION_ID']
    date_col = 'PERIOD_DT'
    built_in_funcs = [pd.Series.kurtosis, pd.Series.skew]

    # flts = {'Promo': {'oprm':'>0', 'npromo':'==0', 'aprm':'>-1'}, 'weekday' : {'md':'==0', 'tue':'==1', 'wd':'==2', 'th':'==3', 'fr':'==4', 'sa':'==5', 'su':'==6', 'anyday':'>-1'}}

    data['NoFilter'] = 1

    data_lagged_features = generate_lagged_features(data
                        , target_cols = target_cols
                        , id_cols = id_cols
                        , date_col = date_col
                        , lags = [22, 28, 35]
                        , windows = ['14D', '21D', '28D', '56D']
                        , preagg_methods = ['sum'] # ['mean', 'count']
                        , agg_methods = ['mean'] #, percentile(10),  percentile(90)]
                        , dynamic_filters = ['PROMO_FLG', 'NoFilter']
                        , ewm_params={'NoFilter': [14, 28], 'PROMO_FLG': [14, 28]}
                        )

    return data_lagged_features


"""Parameter Store Loader
Use (setting_name, cast function) or setting_name as lookup value.
If no cast function is passed, the parameter will be stored as retrieved
from Parameter Store, typically string or stringList.

Usage:
from awstanding.parameter_store import load_parameters

LOOKUP_DICT = {
    '/my/parameter/path': 'NEW_VARIABLE'
}

load_parameters(LOOKUP_DICT)

# Now NEW_VARIABLE can be obtained from environment variables.

"""
import os
from typing import Union, Iterable

import boto3
from boto3.exceptions import Boto3Error
from botocore.exceptions import BotoCoreError, ClientError

from .exceptions import ParameterNotFoundException

_ssm_client = boto3.client(service_name='ssm')

def load_parameters(lookup_dict: dict, allow_invalid=True) -> dict:
    """
    Loads each parameter defined in the lookup_dict as env. variables.
    The lookup_dict should look like this:
    {
        '/path/to/parameter1': 'PARAMETER_AS_ENV_VAR_1',
        '/path/to/parameter2': 'PARAMETER_AS_ENV_VAR_2',
        ...
        '/path/to/parameterN': 'PARAMETER_AS_ENV_VAR_N',
    }
    The values (Env. variables names) could be anything you want.
    It returns the loaded parameters for debugging purposes
    """
    paginated_keys = (list(lookup_dict.keys())[i:i+10] for i in range(0, len(lookup_dict), 10))

    parameters_ps = []
    invalid_parameters = []
    for keys in paginated_keys:
        parameters_page = _ssm_client.get_parameters(Names=keys, WithDecryption=True)
        parameters_ps += parameters_page['Parameters']
        invalid_parameters += parameters_page['InvalidParameters']

    if invalid_parameters and not allow_invalid:
        raise ParameterNotFoundException(invalid_parameters)

    parameters_ps = {param['Name']: param['Value'] for param in parameters_ps}

    # Override configuration for requested keys
    for key in parameters_ps:
        if isinstance(lookup_dict[key], (tuple, list)):
            setting_name, cast = lookup_dict[key]
            os.environ[setting_name] = cast(parameters_ps[key])
        elif isinstance(lookup_dict[key], str):
            os.environ[lookup_dict[key]] = parameters_ps[key]

    return parameters_ps

def load_path(*paths: Union[Iterable[str], str]) -> dict:
    """
    Loads each parameter behind `paths` recursively as env. variables.
    It returns the loaded parameters for debugging purposes
    """
    all_parameters = {}
    for path in paths:
        parameters_page = _ssm_client.get_parameters_by_path(Path=path, Recursive=True)
        parameters_ps = parameters_page['Parameters']

        while parameters_page.get('NextToken'):
            parameters_page = _ssm_client.get_parameters_by_path(Path=path, Recursive=True, NextToken=parameters_page.get('NextToken'))
            parameters_ps += parameters_page['Parameters']

        parameters_ps = {param['Name']: param['Value'] for param in parameters_ps}
        all_parameters.update(**parameters_ps)

        # Override configuration for requested keys
        for key in parameters_ps:
            os.environ[key.strip('/')
                .replace('/', '_')
                .replace('-', '_')
                .upper()
            ] = parameters_ps[key]

    return all_parameters

class DynamicParameter(object):
    @property
    def _value(self):
        try:
            parameter_page = _ssm_client.get_parameter(Name=self.key, WithDecryption=True)
        except (ClientError, Boto3Error, BotoCoreError):
            if self.fail_on_boto_error:
                raise
            else:
                return ''
        else:
            return parameter_page['Parameter']['Value']

    def __init__(self, key, fail_on_boto_error=True, *args, **kwargs):
        super().__init__()
        self.key = key
        self.fail_on_boto_error = fail_on_boto_error

    def __eq__(self, other):
        return self._value == other

    def __len__(self, other):
        return len(self._value)

    def __add__(self, other):
        return self._value + other

    def __radd__(self, other):
        return other + self._value

    def __unicode__(self):
        return str(self._value)

    def __str__(self):
        return str.__str__(self._value)

    def __repr__(self):
        return str.__repr__(self._value)


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Sun Oct  7 20:18:11 2018

@author: tanthanhnhanphan

MECH2700: Assignment 2
"""
import matplotlib.pyplot as plt
from numpy import *

from math import *

D = 100*10**3 #Dynamic Pressure
Ly = 1 #m
Lx = 5 #m
a = 20*pi/180
E = 70*10**9 #Young's Modulus
S = 96.5#Fatigue strength Mpa
Izz = 5*10**-5 #m4
ymax = 0.05 #m
FOS = 1.2

def q(i, n):
    load = D*Ly*sin(a)*(1-(i*Lx/n)**2/Lx**2)
    return load

"""
def x(n):
    for i in range(n+1):
        xx = i*Lx/n
        print(xx)

print(x(7))
"""
"""
A = array([[7, -4, 1, 0, 0, 0, 0],
            [-4, 6, -4, 1, 0, 0, 0],
            [1, -4, 6, -4, 1, 0, 0],
            [0, 1, -4, 6, -4, 1, 0],
            [0, 0, 1, -4, 6, -4, 1],
            [0, 0, 0, 1, -4, 5, -2],
            [0, 0, 0, 0, 2, -4, 2]], float)
"""
#trial
"""
def s(n):
    space = Lx/n
    return space

h = s(7)
"""
#c = array([[q(1,7), q(2,7), q(3,7), q(4,7), q(5,7), q(6,7), q(7,7)]])*h**4/(E*Izz)

#b
#print(linspace(0,5,7))
def rhs(n):
    h= Lx/n
    q_1 = D*Ly*sin(a)*(1-(Lx/n)**2/Lx**2)*h**4/(E*Izz)
    load = array([[q_1]])
    #print(D*Ly*sin(a)*(1-(Lx/n)**2/Lx**2))
    for i in range(2, n+1):
        q_i = D*Ly*sin(a)*(1-(i*Lx/n)**2/Lx**2)*h**4/(E*Izz)
        #print(D*Ly*sin(a)*(1-(i*Lx/n)**2/Lx**2))
        #print(i*Lx/n)
        load = vstack((load, [[q_i]]))
    return load
"""
def rhs_1(n):
    h = Lx/n
    x = linspace(1,5,n)
    q_1 = D*Ly*sin(a)*(1-(x[1]**2/Lx**2)*h**4/(E*Izz))
    load = array([[q_1]])
    print(load)
    print(x)
    #for i in range(n+1):
    q_i = D*Ly*sin(a)*(1-x**2/Lx**2)*h**4/(E*Izz)
    print(q_i)
        #load = vstack((load, [[q_i]]))
        #load = vstack((load, q_i))
    return load
"""

#print("RHS",rhs(7))
#b = c.transpose()

def deflection(n):
    w = zeros((n,n))
    w[0,0] = 7
    w[n-2, n-2] = 5
    w[n-2, n-1] = -2
    w[n-1, n-3] = 2
    w[n-1, n-1] = 2
    for k in range(0,n-1):
        w[k+1, k] = -4
    for k in range(0, n-3):
        w[k+1,k+1] = 6
    for k in range(0, n-2):
        w[k, k+2] = 1
    for k in range(0, n-3):
        w[k+2,k] = 1
    for k in range(0, n-2):
        w[k, k+1] = -4
    return w

#print(deflection((7)))
#print("~~~~")
#print(b)

#Direct Solver Gauss-Jordan Elimination

def solve(A,b, testmode = True):
    """
    Input:
        A: nxn matrix of coefficients
        b: nx1 matrix of rhs values
    Output:
        x: solutions of Ax=b

    """
    nrows, ncols = A.shape
    c = hstack([A,b])
    #print(c)
    for j in range(0, nrows):
        p = j
        for i in range(j+1, nrows):
            #Select pivot
            if abs(c[i,j]) > abs(c[p,j]): p = i
        #Swap the rows
        c[p,:], c[j,:] = c[j,:].copy(), c[p,:].copy()
        #Elimination
        c[j,:] = c[j,:]/c[j,j]
        for i in range(0,nrows):
            if i!=j:
                c[i,:] = c[i,:] - c[i,j]*c[j,:]
    I, x = c[:,nrows], c[:,-1]

    return x
Alist = []
Blist = []
Clist = []
Dlist = []
Elist = []
rhslist = []
def solve_optimise(A,b):
    nrows, ncols = A.shape
    c = hstack([A,b])
    print(b)
    #b.tolist()
    #print(b)
    #print(c)
    for i in range(n-2):
        Alist.append(A[i, i+2])
    for i in range(n-1):
        Blist.append(A[i, i+1])
    for i in range(n):
        Clist.append(A[i,i])
    for i in range(n-1):
        Dlist.append(A[i+1, i])
    for i in range(n-2):
        Elist.append(A[i+2, i])
    for i in range(n):
        rhslist.append(b[i,0])
    rhslistcopy = rhslist.copy()
    """
    alpha = []
    mu = []
    gamma = []
    beta = []
    z = []
    mu_1 = Clist[0]
    alpha_1 =  Blist[0]/mu_1
    beta_1 = Alist[0]/mu_1
    z_1 = rhslist[0]/mu_1
    gamma_2 = Dlist[0]
    mu_2 = Clist[1] - alpha_1*gamma_2
    alpha_2 = (Blist[1]-beta_1*gamma_2)/mu_2
    beta_2 = Alist[1]/mu_2
    z_2 = (rhslist[1]-z_1*gamma_2)/mu_2
    alpha_minus2 = alpha_1
    alpha.append(alpha_1)
    alpha.append(alpha_2)
    mu.append(mu_1)
    mu.append(mu_2)
    gamma.append(gamma_2)
    beta.append(beta_1)
    z.append(z_1)
    z.append(z_2)
    print(gamma)
    for i in range(3, n-3):
        gamma_i = Dlist[i-2] - alpha[i-3]*Elist[i-3]
        mu_i = Clist[i-2] - beta[i-3]*Elist[i-3] - alpha[i-2]*gamma[i-2]
        beta_i = Alist[i-2]/mu_i
        gamma.append(gamma_i)

        beta.append(beta_i)
        z_i = (rhslist[i-1]-z[i-3])
    """

    print(Alist)
    print(Blist)
    print(Clist)
    print(Dlist)
    print(Elist)
    print(rhslist)
    for i in range(n-1):
        multiplier_1 = Dlist[i]/Clist[i]
        #print('multi ',multiplier_1)
        #print(multiplier_1)
        #Dlist[i] = Dlist[i] - multiplier_1*Clist[i]
        #print('before ', rhslist[i+1])
        #rhslist[i+1] = rhslistcopy[i+1] - multiplier_1*rhslistcopy[i]
        #print('after', rhslist[i+1])
    #print(rhslist)
    #print(rhslistcopy)
    #print('~~~')
    for i in range(n-2):
        multiplier_2 = Elist[i]/Clist[i]
        #print('multi ', multiplier_2)
        #print(multiplier_2)
        Elist[i] = Elist[i] - multiplier_2*Clist[i]
        #print('Before ',rhslist[i+2])
        #rhslist[i+2] = rhslist[i+2] - multiplier_2*rhslistcopy[i]
        #print('After ', rhslist[i+2])

    print(Dlist)
    print(Elist)

    #print(rhslist)
    #print(Clist[n-1])
    #x_n = rhslist[n-1]/Clist[n-1]
    #print(x_n)
    #for i in reversed(range(n)):
        #print(i)

    #for i in range(n-1):

        #print(multiplier_1)
    #print(Alist)
    return

solve_optimise(deflection(n), rhs(n))
#print(A)
#print(c)
#print(x)
#print(solve(deflection(280),rhs(280)))
for i in [7,14,28,280]:
    A = deflection(i)
    b = rhs(i)
    x = solve(A,b)
    xx= append(0, x)
    position = []
    for j in range(0,i+1):
        position.append(j*Lx/i)
    #print(position)
    plt.plot(position, xx, label=i)
    plt.xlabel('x(m)')
    plt.ylabel('Deflection (m)')
    plt.legend()
plt.show()

space = []
free_end_deflection = []
node = []

n = 280
#print(deflection(n))
#print(rhs(n))
sol = solve(deflection(n),rhs(n))
#print(sol)
sol_free_end = sol[[n-1]]
#print("Solution",sol_free_end)

for i in range(7, 50):
    A = deflection(i)
    b = rhs(i)
    x = solve(A,b)
    xx = x[[i-1]]
    free_end_deflection.append(xx)
    node.append(i)
    h = Lx/i
    space.append(h)
    if abs(xx - sol_free_end) < 0.1/100*sol_free_end:
        print(i)
        break

    #print(xx)
    #print(h)
#print(space)
plt.plot(space, free_end_deflection)
plt.show()

def moment_stress(n):
    A = deflection(n)
    b = rhs(n)
    x = solve(A,b)
    h = Lx/n
    #M_0 = E*Izz/(h**2)*(x[1]-2*x[0])
    M_1 = E*Izz/(h**2)*(x[1] - 2*x[0])
    #M = array([M_0])
    #M = hstack((M, [M_1]))
    M = array([M_1])
    #Stress
    #sigma_0 = M_0*ymax/Izz*10**-6
    sigma_1 = M_1*ymax/Izz*10**-6
    #sigma = array([sigma_0])
    #sigma = hstack((sigma, sigma_1))
    sigma = array([sigma_1])
    #print(M)
    for i in range(1,n-1):
        M_i = E*Izz/(h**2)*(x[[i+1]]- 2*x[i] + x[i-1])
        sigma_i = M_i*ymax/Izz*10**-6
        #print(M_i)
        M = hstack((M, M_i))
        sigma = hstack((sigma, sigma_i))
        #load = vstack((load, [[q_i]]))
    M = hstack((M, [0]))
    sigma = hstack((sigma, [0]))

    position = []
    for j in range(1, n+1):
        position.append(j*Lx/n)
    print(max(sigma))
    #print(sigma[1])
    print(len(position))
    print(len(M))
    Izz_new = max(M)*ymax*FOS/(S*10**6)*10**5
    print("Izz hey baby cum at me",Izz_new)
    plt.plot(position, M)
    plt.title('Bending moment vs. length')
    plt.xlabel('x (m)')
    plt.ylabel('Bending moment (Nm)')
    plt.show()

    plt.plot(position, sigma)
    plt.title('Bending stress vs. length')
    plt.xlabel('x (m)')
    plt.ylabel('Bending stress (MPa)')
    plt.show()

    #print(M)

    return

moment_stress(17)

#print('RHS: ',rhs(7))
#print('RHS 1: "',rhs_1(7))
#print(rhs(7))
"""
#First line of matrix
import time
A = deflection(n)
b = rhs(n)

##################Computation time using optimised solver######################

start_op = time.time()

deflect_op = solve(A, b)

end_op = time.time()
compute_time_op = end_op - start_op
print("Computation time using optimised solver:", compute_time_op)

###############Computation time using numpy in-built solver#####################

start = time.time()

deflect = np.linalg.solve(A, b)

end = time.time()
compute_time = end - start
print("Computation time using numpy in-built solver:", compute_time)

###############Computation time using Gauss-Jordan solver#######################

start_g = time.time()

deflect_g = solve(A, b)

end_g = time.time()
compute_time_g = end_g - start_g

print("Computation time using Gauss-Jordan solver:", compute_time_g)

print("Does the solver work? \n", check(deflect_op, deflect))
"""


"""

Usage:
    trajectory.py <path> <start_time> <resolution> <x0> <y0> <z0> <t0> [<output_path>]
    trajectory.py (-h | --help)

Arguments:
    <path>
    <start_time>
    <resolution>

Options:
    -h --help
        Show this screen.
"""
import datetime
import warnings

import numpy as np

from twinotter.util.scripting import parse_docopt_arguments
from pylagranto import caltra
from pylagranto.datasets import MetUMStaggeredGrid

from moisture_tracers import grey_zone_forecast

trajectory_filename = "{start_time}_{resolution}_{x0}E_{y0}N_{z0}{units}_" \
                      "T+{lead_time:02d}.pkl"

# Inner-domain centre: x0=302.5, y0=13.5, t0=48
# HALO: x0=302.283, y0=13.3
# Ron Brown (2nd Feb): x0=305.5, y0=13.9
# 24th Jan Case study:
#   x0=302.5, y0=11.75, t0=T+24h
#   x0=310.0, y0=15.0,  t0=T+48h

def _command_line_interface(path, start_time, resolution, x0, y0, z0, t0, output_path="./"):
    forecast = grey_zone_forecast(
        path, start_time, resolution=resolution, grid=None, lead_times=range(1, 48 + 1)
    )

    traout = calculate_trajectory(
        forecast, float(x0), float(y0), float(z0), int(t0), "height_above_reference_ellipsoid"
    )

    traout.save(
        output_path + trajectory_filename.format(
            start_time=forecast.start_time.strftime("%Y%m%d"),
            resolution=resolution,
            x0=format_float_for_file(x0),
            y0=format_float_for_file(y0),
            z0=format_float_for_file(z0),
            t0=t0,
            units="m",
        )
    )

def calculate_trajectory(forecast, x0, y0, z0, t0, zcoord):
    levels = (zcoord, [z0])
    trainp = np.array([[x0, y0, z0]])

    times = list(forecast._loader.files)
    datasource = MetUMStaggeredGrid(forecast._loader.files, levels=levels)

    time_traj = forecast.start_time + datetime.timedelta(hours=t0)
    if time_traj == times[0]:
        traout = caltra.caltra(
            trainp, times, datasource, tracers=["x_wind", "y_wind"]
        )
    elif time_traj == times[-1]:
        traout = caltra.caltra(
            trainp, times, datasource, fbflag=-1, tracers=["x_wind", "y_wind"]
        )
    else:
        times_fwd = [time for time in times if time <= time_traj]
        traout_fwd = caltra.caltra(
            trainp, times_fwd, datasource, tracers=["x_wind", "y_wind"]
        )

        times_bck = [time for time in times if time >= time_traj]
        traout_bck = caltra.caltra(
            trainp, times_bck, datasource, fbflag=-1, tracers=["x_wind", "y_wind"]
        )
        traout = traout_bck + traout_fwd

    return traout

def format_float_for_file(x):
    # Replace decimal point with a p (copying what was done for the UM files)
    return str(x).replace(".", "p")

if __name__ == "__main__":
    warnings.filterwarnings("ignore")
    parse_docopt_arguments(_command_line_interface, __doc__)


from flask import Flask,render_template,flash,redirect,session,url_for,logging,request,Blueprint,json,session
from flask_json import FlaskJSON, JsonError, json_response, as_json
from smartiot.bin.config.db_config import mysql
from smartiot.routes.route_Permissions.userPermissions import getPermissions
import RPi.GPIO as GPIO # Import Raspberry Pi GPIO library
import time

iot_ultraSonic_bp = Blueprint(
    'iot_ultra-sonic_bp',
    __name__
)

#define led oin
led_pin = 7

@iot_ultraSonic_bp.route("/ultra",methods=['POST'])
def ultraSonic():

    try:
        content = request.get_json()
        action = content['action']
        userid = content['userId']
        endpoint = content['endPoint']
    except:
        #response
        return json_response(
        message="Internal server error",
        status = 500
        )
    permissions = getPermissions(userid,endpoint)

    print(str(permissions))

    if permissions is "granted":
        print('granted')
        if action == "measure":
            #mysql
            #execute query
            sql ="INSERT INTO logs(info,value,dataType,deviceName,deviceId,userId) VALUES('',%s,%s,%s,'2',%s)"
            #print(str(sql))
            #get data from sensor
            distance = measure()
            d=round(distance ,2)
            distance_cm = format(d)
#            print( "Distance : {0} cm".distance_cm)

            #create a cursur
            cur = mysql.connection.cursor()
            result  = cur.execute(sql,(distance_cm,"proximity",endpoint,userid))
            #commit to Datebase
            mysql.connection.commit()

            return json_response(
                distance = distance,
                message = "Distance in cm",
                status  =200
                )

        if action == "":#other fuctions
            #mysql
            #execute query
            sql ="INSERT INTO logs(info,value,dataType,deviceName,deviceId,userId) VALUES('',%s,%s,%s,'1',%s)"
            print(str(sql))
            #create a cursur
            cur = mysql.connection.cursor()
            result  = cur.execute(sql,("on","state",endpoint,userid))
            #commit to Datebase
            mysql.connection.commit()

            #close connection
            cur.close()
            GPIO.cleanup()

            return
            print('granted')

    if permissions is "denied":

        #mysql
        #execute query
        sql ="INSERT INTO logs(info,value,dataType,deviceName,deviceId,userId) VALUES(%s,'','',%s,'1',%s)"
        print(str(sql))
        #create a cursur
        cur = mysql.connection.cursor()
        result  = cur.execute(sql,("Permission Denied",endpoint,userid))
        #commit to Datebase
        mysql.connection.commit()
        #close connection
        cur.close()

        #response
        return json_response(
        distance = "",
        message="Permission denied for this user",
        status = 403
        )
        print('denied')

# measure distance

def measure():
    GPIO.setmode(GPIO.BCM)

    TRIG = 4
    ECHO  = 18

    GPIO.setup(TRIG , GPIO.OUT)
    GPIO.setup(ECHO , GPIO.IN)

    GPIO.output(TRIG , True)
    time.sleep(0.0001)
    GPIO.output(TRIG , False)

    while GPIO.input(ECHO) == False:
        start = time.time();

    while GPIO.input(ECHO) == True:
        end = time.time();

    sig_time = end-start

#cm:
    dis = sig_time/0.000058

    print('Dist : {} cm'.format(dis))

    GPIO.cleanup()

    return dis

def measure_average():
    # This function takes 3 measurements and
    # returns the average.
    distance1=measure()
    time.sleep(0.1)
    distance2=measure()
    time.sleep(0.1)
    distance3=measure()
    distance = distance1 + distance2 + distance3
    distance_avg = distance / 3
    return distance_avg


"""
    @Time    : 30/03/2023
    @Author  : qinghua
    @Software: PyCharm
    @File    : process_data.py

"""
import os.path
import pickle
import lgsvl
import pandas as pd
import json

from config import Config
from tqdm import tqdm

"""Processing deep scenario data"""

def get_ds_data(runner):
    """pair paths of scenarios and scenario attributes"""
    scene_attr_path_pairs = []
    for root, dirs, files in os.walk(Config.scenario_dir):
        depth = root.count(os.path.sep)
        if depth == 4:
            scenario_dirs = sorted([os.path.join(root, name) for name in os.listdir(root) if not name.endswith(".csv")])
            attribute_fnames = sorted([os.path.join(root, name) for name in os.listdir(root) if name.endswith(".csv")])
            scene_attr_path_pairs += list(zip(scenario_dirs, attribute_fnames))
    """
    pair contents of scenarios and scenario attributes by each run
    Output Example:
        [
            # run 0
            [
                # timestep 0
                (
                    # variables
                    [1.2,2.1,...]
                    # attribute
                    {"ttc":xxx,"tto":xxx}

                )
                # timestep 1
                ....
            ]
            # run 1
            ....
        ]
    """
    print(scene_attr_path_pairs)
    greedy_pairs = [(scene_dir, attr_path) for scene_dir, attr_path in scene_attr_path_pairs if
                    "greedy-strategy" in scene_dir]
    random_pairs = [(scene_dir, attr_path) for scene_dir, attr_path in scene_attr_path_pairs if
                    "random-strategy" in scene_dir]
    rl_pairs = [(scene_dir, attr_path) for scene_dir, attr_path in scene_attr_path_pairs if
                "rl_based-strategy" in scene_dir]
    dto_pairs = [(scene_dir, attr_path) for scene_dir, attr_path in scene_attr_path_pairs if
                 "reward-dto" in scene_dir]
    jerk_pairs = [(scene_dir, attr_path) for scene_dir, attr_path in scene_attr_path_pairs if
                  "reward-jerk" in scene_dir]
    ttc_pairs = [(scene_dir, attr_path) for scene_dir, attr_path in scene_attr_path_pairs if
                 "reward-ttc" in scene_dir]
    greedy_ttc_pairs = [(scene_dir, attr_path) for scene_dir, attr_path in scene_attr_path_pairs if
                        "greedy-strategy" in scene_dir and "reward-ttc" in scene_dir]
    random_ttc_pairs = [(scene_dir, attr_path) for scene_dir, attr_path in scene_attr_path_pairs if
                        "random-strategy" in scene_dir and "reward-ttc" in scene_dir]
    rl_ttc_pairs = [(scene_dir, attr_path) for scene_dir, attr_path in scene_attr_path_pairs if
                    "rl_based-strategy" in scene_dir and "reward-ttc" in scene_dir]
    r1_ttc_pairs = [(scene_dir, attr_path) for scene_dir, attr_path in scene_attr_path_pairs if
                    "road1" in scene_dir and "reward-ttc" in scene_dir]
    r2_ttc_pairs = [(scene_dir, attr_path) for scene_dir, attr_path in scene_attr_path_pairs if
                    "road2" in scene_dir and "reward-ttc" in scene_dir]
    r3_ttc_pairs = [(scene_dir, attr_path) for scene_dir, attr_path in scene_attr_path_pairs if
                    "road3" in scene_dir and "reward-ttc" in scene_dir]
    r4_ttc_pairs = [(scene_dir, attr_path) for scene_dir, attr_path in scene_attr_path_pairs if
                    "road4" in scene_dir and "reward-ttc" in scene_dir]
    all_runs = get_all_runs(scene_attr_path_pairs)
    greedy_runs = get_all_runs(greedy_pairs)
    random_runs = get_all_runs(random_pairs)
    rl_runs = get_all_runs(rl_pairs)
    dto_runs = get_all_runs(dto_pairs)
    jerk_runs = get_all_runs(jerk_pairs)
    ttc_runs = get_all_runs(ttc_pairs)
    greedy_ttc_runs = get_all_runs(greedy_ttc_pairs)
    random_ttc_runs = get_all_runs(random_ttc_pairs)
    rl_ttc_runs = get_all_runs(rl_ttc_pairs)
    r1_ttc_runs = get_all_runs(r1_ttc_pairs)
    r2_ttc_runs = get_all_runs(r2_ttc_pairs)
    r3_ttc_runs = get_all_runs(r3_ttc_pairs)
    r4_ttc_runs = get_all_runs(r4_ttc_pairs)
    return all_runs, greedy_runs, random_runs, rl_runs, dto_runs, jerk_runs, ttc_runs, greedy_ttc_runs, random_ttc_runs, rl_ttc_runs, r1_ttc_runs, r2_ttc_runs, r3_ttc_runs, r4_ttc_runs

def get_all_runs(scene_attr_path_pairs):
    all_runs = []
    clean_key = lambda k: k.replace("Attribute[", "").replace("]", "")
    for scene_dir, attr_path in tqdm(scene_attr_path_pairs):
        runs = [[] for _ in range(20)]
        # get scenario attributes
        attr_pdf = pd.read_csv(attr_path)
        for row_id, row in attr_pdf.iterrows():
            run_id = int(row["Execution"])
            scene_fname = row["ScenarioID"] + ".deepscenario"
            attrs = row.to_dict()
            attrs = {clean_key(k): v for k, v in attrs.items()}
            runner.load_scenario_file(os.path.join(scene_dir, scene_fname))
            for i in range(1, 7):
                timeframe = runner.get_scene_by_timestep(timestep=i)
                timeframe = json.loads(timeframe)
                runs[run_id].append([timeframe, attrs])
        all_runs += runs
    return all_runs

class Vocab:
    def __init__(self):
        super(Vocab, self).__init__()
        self.id2str = []
        self.str2id = {}

    def add_if_not_exist(self, s):
        if s not in self.str2id:
            self.str2id[s] = len(self.id2str)
            self.id2str.append(s)

    def tokenize(self, s):
        return self.str2id[s]

    def size(self):
        return len(self.id2str)

def build_vocab(str_list):
    vocab = Vocab()
    for s in str_list:
        vocab.add_if_not_exist(s)
    return vocab

"""Process elevator data"""

def get_ele_passenger_profiles(fname):
    """
    Arrival Time; Arrival Floor; Destination Floor; Mass; Capacity;Loading time; Unloading time;Placeholder

    :param fname:
    :return:
    """
    colnames = ["arrival_time", "arrival_floor", "destination_floor", "mass", "capacity", "loading_time",
                "unloading_time", "placeholder"]
    pdf = pd.read_csv(fname, header=None, names=colnames, index_col=False)
    pdf = pdf[colnames[:-1]]  # remove last column
    pdf["arrival_time"] = pdf["arrival_time"].astype("float")
    pdf["arrival_floor"] = pdf["arrival_floor"].astype("int")
    pdf["destination_floor"] = pdf["destination_floor"].astype("int")
    return pdf

def get_ele_simulator_result(fname):
    """
    Document;Passenger;Source;Destination;ArrivalTime;LiftArrivalTime;DestinationArrivalTime
    """
    colnames = ["document", "id", "arrival_floor", "destination_floor", "arrival_time", "lift_arrival_time",
                "lift_destination_time"]
    pdf = pd.read_csv(fname, names=colnames, delimiter=";", skiprows=1)
    pdf = pdf[colnames[2:-1]]
    pdf["arrival_time"] = pdf["arrival_time"].astype("float")
    pdf["arrival_floor"] = pdf["arrival_floor"].astype("int")
    pdf["destination_floor"] = pdf["destination_floor"].astype("int")
    return pdf

def get_ele_data(dispatcher, peak_type):
    """

    :param dispatcher: list of integers
    :param peak_type: ["lunchpeak","uppeak"]
    :return: joined data of profiles and results
    """
    print(dispatcher, peak_type)
    peak_type = "LunchPeak" if "lunch" in peak_type.lower() else "Uppeak"
    profile_dir = Config.lunchpeak_profile_dir if peak_type == "LunchPeak" else Config.uppeak_profile_dir
    dispatcher_name = "Dispatch_00" if dispatcher == 0 else "Dispatch_M{:2d}".format(dispatcher)
    result_dir = os.path.join(Config.result_dir, dispatcher_name)
    if not os.path.exists(result_dir):
        return False
    result_pdfs = []
    for i in range(10):
        n_variable = "4" if peak_type == "LunchPeak" else "Four"
        profile_fname = "{}_mass_capacity_loading_unloading(CIBSE-office-{}){}.txt".format(n_variable, peak_type, i)
        result_fname = "{}_mass_capacity_loading_unloading(CIBSE-office-{}){}.csv".format(n_variable, peak_type, i)
        profile_pdf = get_ele_passenger_profiles(os.path.join(profile_dir, profile_fname))
        result_pdf = get_ele_simulator_result(os.path.join(result_dir, result_fname))
        result_pdf = profile_pdf.merge(result_pdf, how="right",
                                       on=["arrival_time", "arrival_floor", "destination_floor"])
        result_pdfs.append(result_pdf)
    result_pdf = pd.concat(result_pdfs)
    result_fname = "Dispatcher_{:2d}_{}.pkl".format(dispatcher, peak_type)
    pickle.dump(result_pdf,
        open( os.path.join(Config.elevator_save_dir, result_fname),"wb")
    )
    return result_pdf

if __name__ == '__main__':
    """collect data by runs"""
    # runner = lgsvl.scenariotoolset.ScenarioRunner()
    # all_runs, greedy_runs, random_runs, rl_runs, dto_runs, jerk_runs, ttc_runs, greedy_ttc_runs, random_ttc_runs, rl_ttc_runs, r1_ttc_runs, r2_ttc_runs, r3_ttc_runs, r4_ttc_runs = get_ds_data(
    #     runner)
    # pickle.dump(all_runs, open(Config.all_runs_pkl_path, "wb"))
    # pickle.dump(greedy_runs, open(Config.greedy_runs_pkl_path, "wb"))
    # pickle.dump(random_runs, open(Config.random_runs_pkl_path, "wb"))
    # pickle.dump(rl_runs, open(Config.rl_runs_pkl_path, "wb"))
    # pickle.dump(dto_runs, open(Config.dto_runs_pkl_path, "wb"))
    # pickle.dump(jerk_runs, open(Config.jerk_runs_pkl_path, "wb"))
    # pickle.dump(rl_runs, open(Config.rl_runs_pkl_path, "wb"))
    # pickle.dump(random_ttc_runs, open(Config.random_ttc_runs_pkl_path, "wb"))
    # pickle.dump(greedy_ttc_runs, open(Config.greedy_ttc_runs_pkl_path, "wb"))
    # pickle.dump(rl_ttc_runs, open(Config.rl_ttc_runs_pkl_path, "wb"))
    # pickle.dump(r1_ttc_runs, open(Config.r1_ttc_runs_pkl_path, "wb"))
    # pickle.dump(r2_ttc_runs, open(Config.r2_ttc_runs_pkl_path, "wb"))
    # pickle.dump(r3_ttc_runs, open(Config.r3_ttc_runs_pkl_path, "wb"))
    # pickle.dump(r4_ttc_runs, open(Config.r4_ttc_runs_pkl_path, "wb"))
    # process elevator data

    ele_names = ["dispatch_00_lunchpeak", "dipatcher_00_uppeak"]
    ele_names += ["dispatcher_{:02d}_lunchpeak_variant".format(i) for i in range(1, 100)]
    ele_names += ["dispatcher_{:02d}_uppeak_variant".format(i) for i in range(1, 100)]
    peak_types = ["lunchpeak", "uppeak"]
    for i in range(100):
        for peak_type in peak_types:
            pdf = get_ele_data(i, peak_type)