from numba import njit
from settings import *
from player import Player
from enemy import Enemy
import pygame
import numpy

@njit
def _display(player_x: float, player_y: float, player_angle: float, textures: numpy.ndarray, map: numpy.ndarray, frame: numpy.ndarray) -> numpy.ndarray:
	for vert_ray in range(VERT_NUM_RAYS):
		angle = player_angle + numpy.deg2rad(vert_ray / FOV - 30)

		sin = numpy.sin(angle)
		cos = numpy.cos(angle)
		fov_cos = numpy.cos(numpy.deg2rad(vert_ray / FOV - 30))

		x, y = player_x, player_y
		while not map[int(x)][int(y)]:
			x, y = x + cos * 0.02, y + sin * 0.02

		n = abs((x - player_x) / cos)
		height = int(HOR_NUM_RAYS / (fov_cos * n + 0.0001))

		xx = int(x * 2 % 1 * (TEXTURE_RES - 1))
		if x % 1 < 0.02 or x % 1 > 0.98:
			xx = int(y * 2 % 1 * (TEXTURE_RES - 1))
		yy = numpy.linspace(0, (TEXTURE_RES - 1) * 2, height * 2) % (TEXTURE_RES - 1)

		shade = 0.3 + (height / HOR_NUM_RAYS) * 0.7
		if shade > 1: shade = 1

		for k in range(height * 2):
			if HOR_NUM_RAYS - height + k >= 0 and HOR_NUM_RAYS - height + k < HOR_NUM_RAYS * 2:
				frame[vert_ray][HOR_NUM_RAYS - height + k] = shade * textures[1][xx][int(yy[k])]

		for hor_ray in range(HOR_NUM_RAYS - height):
			n = (HOR_NUM_RAYS / (HOR_NUM_RAYS - hor_ray)) / fov_cos
			x, y = player_x + cos * n, player_y + sin * n
			xx, yy = int(x * 2 % 1 * (TEXTURE_RES - 1)), int(y * 2 % 1 * (TEXTURE_RES - 1))
			shade = 0.2 + 0.8 * (1 - hor_ray / HOR_NUM_RAYS)

			frame[vert_ray][HOR_NUM_RAYS * 2 - hor_ray - 1] = shade * textures[0][xx][yy]
			frame[vert_ray][hor_ray] = shade * textures[2][xx][yy]

	return frame

def display(player: Player, enemies: list[Enemy], wall_textures: numpy.ndarray, enemy_textures: numpy.ndarray, map: numpy.ndarray, screen: pygame.Surface) -> numpy.ndarray:
	frame = numpy.empty((VERT_NUM_RAYS, HOR_NUM_RAYS * 2, 3))
	frame = _display(player.x, player.y, player.angle, wall_textures, map, frame)

	surface = pygame.surfarray.make_surface(frame * 255)
	surface = pygame.transform.scale(surface, RES)

	screen.blit(surface, (0, 0))

	for enemy in enemies:
		enemy_angle = numpy.arctan((enemy.y - player.y) / (enemy.x - player.x))
		if abs(player.x + numpy.cos(enemy_angle) - enemy.x) > abs(player.x - enemy.x):
			enemy_angle = (enemy_angle - numpy.pi) % (numpy.pi * 2)
		angle_difference = (player.angle - enemy_angle) % (numpy.pi * 2)

		if angle_difference > numpy.pi * 11 / 6 or angle_difference < numpy.pi / 6:
			distance = numpy.sqrt((player.x - enemy.x) ** 2 + (player.y - enemy.y) ** 2)
			enemy.angle_difference, enemy.distance = angle_difference, 1 / distance

			# cos, sin = 0.01 * (player.x - enemy.x) / distance, 0.01 * (player.y - enemy.y) / distance
			# for _ in range(int(distance / 0.01)):
			# 	x, y = enemy.x + cos, enemy.y + sin
			# 	if map[int(x)][int(y)]:
			# 		enemy.distance = 999
		else:
			enemy.distance = 999

	enemies = sorted(enemies, key = lambda enemy: enemy.distance)
	for index, enemy in enumerate(enemies):
		if enemy.distance > MAP_SIZE:
			break

		scaling = min(enemy.distance, 2) / numpy.cos(enemy.angle_difference)
		x = HALF_WIDTH - WIDTH * numpy.sin(enemy.angle_difference) - TEXTURE_RES * scaling / 2
		y = HALF_HEIGHT + HALF_HEIGHT * scaling - TEXTURE_RES * scaling / 2
		surface = pygame.transform.scale(enemy_textures[int(enemy.index)], (TEXTURE_RES * scaling, TEXTURE_RES * scaling))

		screen.blit(surface, (x, y))

		if player.shooting_state:
			if x < HALF_WIDTH < x + TEXTURE_RES * scaling:
				enemy.health -= 1
				if enemy.health <= 0:
					enemies = numpy.delete(enemies, index)
				player.shooting_state = False
	player.shooting_state = False

	return enemies


from selenium.webdriver import ChromeOptions, Chrome
from es_crawler.config import parse_config
from es_crawler.crawler import CrawlerProduct, CrawlerCategoryUrl, CrawlerProductUrl
from es_crawler.settings import Settings
from es_crawler.shop.hm import HM
from es_crawler.shop.lamoda import Lamoda
from es_crawler.shop.ostin import Ostin
from google.cloud import storage
import logging
import argparse
import redis

def build_driver(path_driver):
    chrome_options = ChromeOptions()
    chrome_options.add_argument("--headless")
    chrome_options.add_argument('--ignore-certificate-errors')
    chrome_options.add_argument("--disable-blink-features")
    chrome_options.add_argument('--disable-dev-shm-usage')
    chrome_options.add_argument('--no-sandbox')
    chrome_options.add_experimental_option("excludeSwitches", ["enable-automation"])
    chrome_options.add_experimental_option('useAutomationExtension', False)
    chrome_options.add_argument('--allow-running-insecure-content')
    chrome_options.add_argument("--window-size=1920,1080")
    user_agent = "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 " \
                 "(KHTML, like Gecko) Chrome/89.0.4280.66 Safari/537.36"
    chrome_options.add_argument(f'user-agent={user_agent}')
    driver = Chrome(executable_path=path_driver, options=chrome_options)
    driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {
        "source": """
              const newProto = navigator.__proto__
              delete newProto.webdriver
              navigator.__proto__ = newProto
              """
    })
    return driver

def make_shop(name):
    shops = {
        'hm': HM,
        'lamoda': Lamoda,
        'ostin': Ostin
    }
    return shops[name]()

def make_crawler(settings: Settings, step: str):
    _redis = redis.Redis(host=settings.config.redis_host, port=settings.config.redis_port, db=0)
    shop = make_shop(settings.config.shop)
    driver = build_driver(settings.config.driver)
    if step == 'category_url':
        return CrawlerCategoryUrl(
            driver=driver,
            run_id=settings.run_settings.run_id,
            shop=shop,
            r=_redis,
            num_others=settings.config.count_builder
        )
    elif step == 'product_url':
        return CrawlerProductUrl(
            driver=driver,
            run_id=settings.run_settings.run_id,
            shop=shop,
            r=_redis
        )
    elif step == 'product':
        return CrawlerProduct(
            driver=driver,
            run_id=settings.run_settings.run_id,
            shop=shop,
            r=_redis,
            bucket=storage_client.bucket(settings.config.bucket_name),
            data_dir=settings.run_settings.data_dir
        )
    else:
        raise Exception(f'Wrong step name: {step}')

def run(settings, step):
    c = make_crawler(settings, step)
    c.run()

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument("-c", "--config", help="config file")
    parser.add_argument("-s", "--step", help="step crawling: category_url, product_url, product")
    args = parser.parse_args()
    config = parse_config(args.config)

    logging.basicConfig(level=config.logging_level, filename=config.log_file, filemode='a',
                        format='%(asctime)s : %(levelname)s : %(message)s')
    storage_client = storage.Client()
    run(Settings(config, config.run_id), args.step)


from django.shortcuts import render

# Create your views here.
from rest_framework.decorators import api_view, authentication_classes, permission_classes
from rest_framework import status
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated
from rest_framework_simplejwt.authentication import JWTTokenUserAuthentication
import jwt
from django.conf import settings
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer
from cerberus import Validator
import yaml
from datarepo.models import AccountRole
from users.models import User
from ..models import Industry, Mentorship
import random

@api_view(['POST'])
@authentication_classes([JWTTokenUserAuthentication])
@permission_classes([IsAuthenticated])
def mentorship(request):
    token = request.headers['Authorization']
    decoded_data = jwt.decode(token[7:], settings.JWT_SECRET_KEY, algorithms=['HS256'])
    account_role = decoded_data['account_role']
    if account_role == AccountRole.INDUSTRY_USER:
        mentor_name = request.POST.get('mentor_name', None)
        mentor_email = request.POST.get('mentor_email', None)
        mentor_phone_number = request.POST.get('mentor_phone_number', None)
        designation = request.POST.get('designation', None)
        availability = request.POST.get('availability', None)
        mode = request.POST.get('mode', None)
        linkedin_profile_url = request.POST.get('linkedin_profile_url', None)  # in rupee
        languages = request.POST.get('languages', None)

        request_schema = '''
                mentor_name:
                    type: string
                    empty: false
                    required: true
                mentor_email:
                    type: string
                    empty: false
                    required: true
                mentor_phone_number:
                    type: string
                    empty: false
                    required: true
                designation:
                    type: string
                    empty: false
                    required: true
                availability:
                    type: string
                    empty: false
                    required: true
                mode:
                    type: string
                    empty: false
                    required: true
                linkedin_profile_url:
                    type: string
                    empty: false
                    required: true
                languages:
                    type: string
                    empty: false
                    required: true
                '''
        v = Validator()
        post_data = request.POST.dict()
        schema = yaml.load(request_schema, Loader=yaml.SafeLoader)

        if v.validate(post_data, schema):
            try:
                get_industry = Industry.objects.get(user_id=request.user.id)
            except Industry.DoesNotExist:
                content = {
                    "message": "Please contact admin"
                }
                return Response(content, status.HTTP_400_BAD_REQUEST, content_type='application/json')

            new_mentorship = Mentorship.objects.create(
                industry_id=get_industry.id,
                mentor_name=mentor_name,
                mentor_email=mentor_email,
                mentor_phone_number=mentor_phone_number,
                designation=designation,
                availability=availability,
                mode=mode,
                linkedin_profile_url=linkedin_profile_url,
                languages=languages,
            )
            context = {
                "message": "Mentorship added successfully",
                'mentorship_id': new_mentorship.id
            }
            return Response(context, status.HTTP_200_OK, content_type='application/json')

        else:
            content = {
                'message': "invalid request",
                'errors': v.errors
            }
            return Response(content, status=status.HTTP_400_BAD_REQUEST, content_type='application/json')

    else:
        content = {
            "message": "You dont have the permission"
        }
        return Response(content, status.HTTP_401_UNAUTHORIZED, content_type='application/json')

@api_view(['GET'])
@authentication_classes([JWTTokenUserAuthentication])
@permission_classes([IsAuthenticated])
def mentorships(request):
    token = request.headers['Authorization']
    decoded_data = jwt.decode(token[7:], settings.JWT_SECRET_KEY, algorithms=['HS256'])
    account_role = decoded_data['account_role']
    if account_role in [AccountRole.NM_ADMIN,
                        AccountRole.INDUSTRY_ADMIN,
                        AccountRole.INDUSTRY_STAFF,
                        AccountRole.INDUSTRY_USER]:
        industry_id = request.GET.get('industry_id', None)
        page = request.GET.get('page', 0)
        limit = request.GET.get('limit', 20)
        try:
            page = int(page)
            limit = int(limit)
        except:
            page = 0
            limit = 20

        query = {}
        if industry_id:
            try:
                query['industry_id'] = int(industry_id)
            except:
                pass

        if account_role == AccountRole.INDUSTRY_USER:
            try:
                get_industry = Industry.objects.values('id').get(user_id=request.user.id)
                query['industry_id'] = get_industry['id']
            except Industry.DoesNotExist:
                content = {
                    "message": "Please contact admin"
                }
                return Response(content, status.HTTP_400_BAD_REQUEST, content_type='application/json')

        mentors_objs = Mentorship.objects.select_related('industry').filter(**query).order_by('-created')
        total_count = mentors_objs.count()
        final_mentors_list = []
        for obj in mentors_objs[(page* limit): ((page*limit) + limit)]:
            temp = {
                "industry_id": obj.industry_id,
                "industry_name": obj.industry.organisation_name if obj.industry_id else None,
                "industry_type": obj.industry.industry_type if obj.industry_id else None,

                "mentorship_id": obj.id,
                "mentor_name": obj.mentor_name,
                "mentor_email": obj.mentor_email,
                "mentor_phone_number": obj.mentor_phone_number,
                "designation": obj.designation,
                "availability": obj.availability,
                "mode": obj.mode,
                "linkedin_profile_url": obj.linkedin_profile_url,
                "languages": obj.languages,
                "created": obj.created,
            }
            final_mentors_list.append(temp)
        context = {
            "mentors": final_mentors_list,
            "filters": {
                'page': page,
                'limit': limit,
                'total_count': total_count,
                'industry_id': industry_id,
            }
        }
        return Response(context, status.HTTP_200_OK, content_type='application/json')

    else:
        content = {
            "message": "You dont have the permission"
        }
        return Response(content, status.HTTP_401_UNAUTHORIZED, content_type='application/json')


import requests, pandas as pd
import numpy as np
import math
import pprint
import matplotlib.pyplot as plt
import datetime

#Variable section for start_time and end_time:
year = 2022
month = "10"    #IMPORTANT - JAN, FEB, MARCH ...... SEP must be set to 01, 02, 03 ... 09 as a STRING
start_date = "27"  #IMPORTANT, all single digit dates must have 0 at front as STRING, Ex: 01, 02, 03
end_date = "28"    #IMPORTANT, all single digit dates must have 0 at front as STRING, Ex: 01, 02, 03
start_time = "01"  #IMPORTANT, all hours must have two digits, single digit hours must have 0 at front as a STRING
end_time = 23      #IMPORTANT, all hours must have two digits, single digit hours must have 0 at front as a STRING

data = pd.read_csv (r'C:\Users\yiyan\Downloads\ASC2022 (1).csv')
df = pd.DataFrame(data, columns= ["latitude", "longitude"])
#Read the csv file and only read the columns Latitude and Longitude
#print(df)

Lat_long_pairs = []
Lat = []
Long = []

for ind in df.index:
    Lat_long_pairs.append([df["latitude"][ind], df["longitude"][ind]])

#Create a loop to in take all the latitude and longitude pairs that we are looking to calculate the wind velocity and
#direction for and store them in a list

def get_API(lat, long): #Calls the API on the specific latitude and longitude and returns the output of the json file
    response = requests.get(
        f"https://api.open-meteo.com/v1/forecast?latitude={lat}&longitude={long}&hourly=windspeed_10m,winddirection_10m")
    #print(response.status_code)
    output = response.json()
    return(output)

def get_time(year, month, start_date, start_hour, end_date, end_hour): #Creates the time string that matches the format
    #of the json file
    #May switch to datetime later, currently datetime does not match up with the time strings in the dictionary

    #start_time = datetime.datetime(year,month, start_date, start_hour)
    #end_time = datetime.datetime(year, month, end_date, end_hour)

    start_time_ = str(year) + "-" + str(month) + "-" + str(start_date) + "T" + str(start_hour) + ":00"
    end_time_ = str(year) + "-" + str(month) + "-" + str(end_date) + "T" + str(end_hour) + ":00"
    return([start_time_, end_time_])

def get_average(lat, long, year, month, start_date, start_hour, end_date, end_hour): #Main function
    start_index = 0
    end_index = 0
    #Two variables above are meant to track which wind velocity and wind direction we want given a 7 day API wind forecast

    data_set = get_API(lat,long)
    #pprint.pprint(data_set)
    #Call the API, print function can be deleted

    time_set = get_time(year,month,start_date,start_hour,end_date,end_hour)
    for i in range(len(data_set['hourly']['time'])):
        if data_set['hourly']['time'][i] == time_set[0]:
            start_index += i
            pass
        elif data_set['hourly']['time'][i] == time_set[1]:
            end_index += i
            break

    #Find the starting wind_direction and wind_speed indeces and ending wind_direction and wind_speed indeces

    wind_speed_10m_list = (data_set['hourly']['windspeed_10m'][start_index:end_index])
    wind_direct_10m_list = (data_set['hourly']['winddirection_10m'][start_index:end_index])

    #Create two new lists consist of only the wind direction and wind speed during a specific time frame

    #print(wind_speed_10m_list)
    #print(wind_speed_10m_list)
    #print function can be deleted

    counter = 0
    speed_sum = 0
    direct_sum = 0
    for i in wind_speed_10m_list:
        counter += 1
        speed_sum += i

    for j in wind_direct_10m_list:
        try:
            direct_sum += j
        except:
            print("error occured at" + str(j))
            pass

    #Take the average of the two lists, since they have the same number of items use the same counter for both lists

    return(speed_sum/counter, direct_sum/counter)

#--------------------------------------------------

#Below is the calling of the function
average_velocity = []
average_angle = []

for i in range(len(Lat_long_pairs)):
    print(i)
    if i % 1000 == 0:
        average_velocity.append(get_average(Lat_long_pairs[i][0],Lat_long_pairs[i][1],year,month, start_date, start_time, end_date, end_time)[0])
        average_angle.append(get_average(Lat_long_pairs[i][0],Lat_long_pairs[i][1],year,month, start_date, start_time, end_date, end_time)[1])
        Lat.append(Lat_long_pairs[i][0])
        Long.append(Lat_long_pairs[i][1])
        print(average_velocity)
        print(average_angle)

print(average_angle)

u = []
for i in average_angle:
    u.append(math.cos(i))
v = []
for i in average_angle:
    v.append(math.sin(i))
North_Lat = []
North_Long = []
East_Lat = []
East_Long = []
South_Lat = []
South_Long = []
West_Lat = []
West_Long = []
for i in range(len(average_angle)):
    if (average_angle[i] >= 0 and average_angle[i] <= 45) or (average_angle[i] >= 315 and average_angle[i] <= 0):
        North_Lat.append(Lat[i])
        North_Long.append(Long[i])
    elif (average_angle[i] >= 45 and average_angle[i] <= 135):
        East_Lat.append(Lat[i])
        East_Long.append(Long[i])
    elif (average_angle[i] >= 135 and average_angle[i] <= 225):
        South_Lat.append(Lat[i])
        South_Long.append(Long[i])
    else:
        West_Lat.append(Lat[i])
        West_Long.append(Long[i])

min = min(average_velocity)
max = max(average_velocity)

plt.subplot(1,2,1)
plt.title("Average Wind Velocity")
plt.scatter(Lat, Long, s=100, c=average_velocity, cmap = "Greens", marker='o')
plt.xlabel("Latitude")
plt.ylabel("Longitude")
plt.colorbar()

plt.subplot(1,2,2)
plt.title("Average Wind Direction")

plt.scatter(North_Lat,North_Long, s=100, marker ='^')
plt.scatter(East_Lat, East_Long, s=100, marker ='>')
plt.scatter(South_Lat, South_Long, s=100, marker ='v')
plt.scatter(West_Lat, West_Long, s=100, marker ='<')

plt.show()


from selenium import webdriver
import time
from selenium.webdriver.common.keys import Keys
from selenium.webdriver import ActionChains
from selenium.webdriver.chrome.options import Options
import os
import pandas
import win32com.client
from datetime import datetime, timedelta
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities

def CHGDownloader():
    option = Options()
    option.add_experimental_option("prefs", {
        "download.default_directory": "C:\\path\\to\\Downloads",
        "download.prompt_for_download": False,
        'download.directory_upgrade': True,
        'safebrowsing.enabled': False,
        'safebrowsing.disable_download_protection': True,
    })
    option.add_argument("--disable-extensions")
    option.add_argument("--proxy-server=direct://")
    option.add_argument("--proxy-bypass-list=*")
    option.add_argument("--start-maximized")
    option.add_argument("--headless")
    option.add_argument("--disable-gpu")
    option.add_argument("--allow-insecure-localhost")
    option.add_argument("--disable-dev-shm-usage")
    option.add_argument("--no-sandbox")
    option.add_argument("--ignore-certificate-errors")

    capabilities = DesiredCapabilities.CHROME.copy()
    capabilities['acceptSslCerts'] = True
    capabilities['acceptInsecureCerts'] = True
    driver = webdriver.Chrome(
        executable_path="\\path\\to\\chromedriver.exe", options=option, desired_capabilities=capabilities)
    try:
        print("Initializing")
        driver.command_executor._commands["send_command"] = ("POST", '/session/$sessionId/chromium/send_command')
        params = {'cmd': 'Page.setDownloadBehavior',
                  'params': {'behavior': 'allow', 'downloadPath': "C:\\path\\to\\Downloads"}}
        driver.execute("send_command", params)
        driver.implicitly_wait(10)
        driver.get("https://example.com") # site
        time.sleep(10)
        driver.find_element_by_xpath("//*[@id='favorites_tab']").click()
        time.sleep(2)
        driver.find_element_by_link_text("Reports - View / Run").click()
        time.sleep(5)
        driver.switch_to.frame("gsft_main")
        driver.find_element_by_xpath("//*[@id='li_group_reports_tab']/span").click()
        time.sleep(2)
        driver.find_element_by_link_text("DailyCR_Report_DM").click()
        time.sleep(10)
        element = driver.find_element_by_xpath("/html/body/div[2]/table/tbody/tr/td/div[1]/div/span/div/div[2]/table/tbody/tr/td/div/table/thead/tr/th[3]/span/a")
        actionChains = ActionChains(driver)
        actionChains.context_click(element).perform()
        ActionChains(driver).send_keys(Keys.ARROW_DOWN).perform()
        ActionChains(driver).send_keys(Keys.ARROW_DOWN).perform()
        ActionChains(driver).send_keys(Keys.ARROW_DOWN).perform()
        ActionChains(driver).send_keys(Keys.ARROW_DOWN).perform()
        ActionChains(driver).send_keys(Keys.ARROW_DOWN).perform()
        ActionChains(driver).send_keys(Keys.ARROW_DOWN).perform()
        ActionChains(driver).send_keys(Keys.ENTER).perform()
        ActionChains(driver).send_keys(Keys.ENTER).perform()
        time.sleep(5)
        driver.find_element_by_xpath("//*[@id='download_button']").click()
        time.sleep(2)
        driver.quit()
    except:
        driver.quit()
        print("Re-initializing")
        CHGDownloader()

def emailComplete():
    outlook = win32com.client.Dispatch('Outlook.Application')
    mail_item = outlook.CreateItem(0)
    mail_item.To = 'Email Address'
    mail_item.Cc = '%s' % OnCallName
    mail_item.Subject = "Change Report (%s)" %ReqD
    mail_item.Attachments.Add(Source='C:\\path\\to\\donwloads\\change_request.xlsx')
    body = "
Hi Team,

Please find the changes scheduled today below,
"+DF+"
%s" %HTML
    mail_item.HTMLBody = (body)
    mail_item.Send()

def emailEmpty():
    outlook = win32com.client.Dispatch('Outlook.Application')
    mail_item = outlook.CreateItem(0)
    mail_item.To = 'Email Address'
    mail_item.Cc = '%s' % OnCallName
    mail_item.Subject = "Change Report (%s)" % ReqD
    mail_item.Attachments.Add(Source='C:\\path\\to\\donwloads\\change_request.xlsx')
    body = "
Hi Team,

No changes are scheduled for today.

%s" % HTML
    mail_item.HTMLBody = (body)
    mail_item.Send()

CHGDownloader()
os.chdir("C:\\path\\to\\Downloads")
Sheet = pandas.read_excel("change_request.xlsx", sheet_name=0)
Sheet = Sheet[Sheet["State"] != "Canceled"]
Sheet = Sheet.drop(columns=["Assigned to"])
Sheet = Sheet[Sheet["Short Description / Title"].str.contains(r"SFG|B2B|sfg|b2b")]
DF = Sheet.to_html(index=False)
ReqD = datetime.strftime(datetime.now(), '%m/%d/%y')
Sign = open("C:\\path\\to\\KP Sign.html")
HTML = Sign.read()
OnCall = pandas.read_excel("\\path\\to\\DM_B2B_On_Call.xlsx", sheet_name=0)
OnCallEmail = OnCall['Email'][OnCall[OnCall['Date'] == ReqD].index.tolist()].tolist()
OnCallName = str(OnCallEmail[0])
if Sheet.empty:
    emailEmpty()
else:
    emailComplete()
time.sleep(3)
try:
    os.system("taskkill /f /im  outlook.exe")
except:
    print("No PID found")
os.remove("change_request.xlsx")


# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import migrations, models

class Migration(migrations.Migration):

    dependencies = [
    ]

    operations = [
        migrations.CreateModel(
            name='DetalleFactura',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('cantidad', models.IntegerField()),
            ],
        ),
        migrations.CreateModel(
            name='Factura',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('date', models.DateField(auto_now=True)),
            ],
        ),
        migrations.CreateModel(
            name='Producto',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('name', models.CharField(max_length=50)),
                ('price', models.DecimalField(max_digits=11, decimal_places=2)),
            ],
        ),
        migrations.AddField(
            model_name='detallefactura',
            name='factura',
            field=models.ForeignKey(to='principal.Factura'),
        ),
        migrations.AddField(
            model_name='detallefactura',
            name='producto',
            field=models.ForeignKey(to='principal.Producto'),
        ),
    ]


import gym
import numpy as np
from utils import writeData2File, DataStorage
from config import pqExp_config as configs

def run_controlGame(episode, env, Agent, DataStorage, is_storeQ=False):
    # set_memory_with_random()
    for i_episode in range(episode):
        observation = env.reset()
        if is_storeQ:
            InitState = [observation]
            FirstAction = Agent.choose_action(observation)
        totalR = 0
        while True:
            # env.render()
            action = Agent.choose_action(observation)
            observation_, reward, done, info = env.step(action)
            totalR += reward
            Agent.store_memory(observation, action, reward, observation_, done)
            # Agent.learn(costFlag=done) # costFlag = True 记录 loss
            Agent.learn()
            observation = observation_
            if done:
                print('episode: ', i_episode, ' epsilon: ', Agent.epsilon, 'total_reward:', totalR)
                if is_storeQ:
                    Q_value = Agent.brain.predict_eval_action(InitState)
                    DataStorage.store_Q(Q_value[0][FirstAction])
                DataStorage.store_reward(totalR)
                break

    # Brain.save()  # 存储神经网络

def run_Pendulum(episode, env, Agent, DataStorage, is_storeQ=False):
    ACTION_SPACE = 11
    # set_memory_with_random()
    for i_episode in range(episode):
        observation = env.reset()
        if is_storeQ:
            InitState = [observation]
            FirstAction = Agent.choose_action(observation)
        totalR = 0
        while True:
            # env.render()
            action = Agent.choose_action(observation)
            f_action = (action - (ACTION_SPACE - 1) / 2) / ((ACTION_SPACE - 1) / 4)
            observation_, reward, done, info = env.step(np.array([f_action]))
            totalR += reward
            reward /= 10
            Agent.store_memory(observation, action, reward, observation_, done)
            # Agent.learn(costFlag=done) # costFlag = True 记录 loss
            Agent.learn()
            observation = observation_
            if done:
                print('episode: ', i_episode, ' epsilon: ', Agent.epsilon, 'total_reward:', totalR)
                if is_storeQ:
                    Q_value = Agent.brain.predict_eval_action(InitState)
                    DataStorage.store_Q(Q_value[0][FirstAction])
                DataStorage.store_reward(totalR)
                break

    # Brain.save()  # 存储神经网络

def run_Game(model, env_name, episodes):
    if model == 'DQN':
        from model.mlpBrain import DQN_Brain as Brain
        from model.agent import DQN_Agent as Agent
    elif model == 'DDQN':
        from model.mlpBrain import DDQN_Brain as Brain
        from model.agent import DDQN_Agent as Agent
    elif model == 'PDQN':
        from model.mlpBrain import PDQN_Brain as Brain
        from model.agent import PDQN_Agent as Agent
    elif model == 'PDDQN':
        from model.mlpBrain import PDDQN_Brain as Brain
        from model.agent import PDDQN_Agent as Agent
    elif model == 'DQN_PER':
        from model.mlpBrain import DQN_PER_Brain as Brain
        from model.agent import DQN_PER_Agent as Agent
    elif model == 'DDQN_PER':
        from model.mlpBrain import DDQN_PER_Brain as Brain
        from model.agent import DDQN_PER_Agent as Agent
    elif model == 'DQN_InAday':
        from model.mlpBrain import DQN_InAday_Brain as Brain
        from model.agent import DQN_InAday_Agent as Agent
    elif model == 'DQN_PER_Ipm':
        from model.mlpBrain import DQN_PER_Ipm_Brain as Brain
        from model.agent import DQN_PER_Ipm_Agent as Agent
    elif model == 'DDQN_PER_Ipm':
        from model.mlpBrain import DDQN_PER_Ipm_Brain as Brain
        from model.agent import DDQN_PER_Ipm_Agent as Agent
    elif model == 'PDQN_RePER':
        from model.mlpBrain import PDQN_RePER_Brain as Brain
        from model.agent import PDQN_RePER_Agent as Agent

    env = gym.make(env_name)   # 定义使用 gym 库中的那一个环境
    # env = env.unwrapped  # 注释掉的话 每局游戏 reward之和最高200

    n_actions = 11 if env_name == 'Pendulum-v0' else env.action_space.n

    print('\nThe config:\n', configs, '\n')
    neurons_per_layer = configs['Brain']['neurons_per_layer']
    learning_rate = configs['Brain']['learning_rate']
    output_graph = configs['Brain']['output_graph']
    restore = configs['Brain']['restore']

    reward_decay = configs['Agent']['reward_decay']
    replace_target_iter = configs['Agent']['replace_target_iter']
    memory_size = configs['Agent']['memory_size']
    batch_size = configs['Agent']['batch_size']
    MAX_EPSILON = configs['Agent']['MAX_EPSILON']
    MIN_EPSILON = configs['Agent']['MIN_EPSILON']
    LAMBDA = configs['Agent']['LAMBDA']

    # learning_rate 重要
    # restore 和 MAX_EPSILON 一起调整
    brain = Brain(
        n_actions=n_actions,
        n_features=env.observation_space.shape[0],
        neurons_per_layer=neurons_per_layer,
        learning_rate=learning_rate,
        output_graph=output_graph,
        restore=restore,
        checkpoint_dir=(env_name + '_' + model + '_MLP_Net')
    )
    agent = Agent(
        brain=brain,
        n_actions=n_actions,
        observation_space_shape=env.observation_space.shape,
        reward_decay=reward_decay,
        replace_target_iter=replace_target_iter,
        memory_size=memory_size,
        batch_size=batch_size,
        MAX_EPSILON=MAX_EPSILON,
        MIN_EPSILON=MIN_EPSILON,
        LAMBDA=LAMBDA,
    )

    dataStorage = DataStorage()

    if env_name == 'Pendulum-v0':
        run_Pendulum(episodes, env, agent, False)
    else:
        run_controlGame(episodes, env, agent, dataStorage, True)  # 4-th params = True 记录 q value
    writeData2File(model, env_name, brain, agent, dataStorage)


from django.core.exceptions import ValidationError
from django.test import TestCase
from MaintenancePlanner.equipment.models import Equipment
from MaintenancePlanner.equipment.validators import equipment_name_validator
from tests.common.test_data import create_plant, create_department, create_equipment

class EquipmentCreationModel(TestCase):
    def setUp(self):
        self.plant = create_plant()
        self.department = create_department()

    def test_equipment_creation_with_valid_data(self):
        equipment = create_equipment()
        self.assertEqual(equipment.description, 'TestEquipment')
        self.assertEqual(equipment.type, 'Machine')
        self.assertEqual(equipment.plant.name, 'TestPlant')
        self.assertEqual(equipment.department.name, 'TestDepartment')

    def test_equipment_creation_with_invalid_data(self):
        equipment = Equipment.objects.create(
                description='TestEquipment@',
                type='Machine',
                plant=self.plant,
                department=self.department,
            )
        with self.assertRaises(ValidationError) as context:
            equipment_name_validator(equipment.description)
        message = 'Ensure this value contains only letters, numbers, and underscore.'
        self.assertEqual(message, str(context.exception.message))


from channels.generic.websocket import AsyncWebsocketConsumer
import json
from . import hangedman
from random import randint

class GameConsumer(AsyncWebsocketConsumer):
    games = {}

    def __getUsername(self):
        username = self.scope['user'].username
        if username == "":
            username = "Guest " +  str(self.scope['session'].session_key)[0:5]
        return username

    async def connect(self):
        # print(str(self.scope['session'].session_key))
        # Obtener el room_name a partir de la url
        self.room_name = self.scope['url_route']['kwargs']['room_name']

        # Definir nombre del Group
        self.room_group_name = 'game_%s' % self.room_name

        # Crear el Group
        await self.channel_layer.group_add(
            self.room_group_name,
            # Puntero al channel_layer que va a llegar al consumer
            self.channel_name
        )

        if self.room_group_name not in self.games:
            game = hangedman.HangedMan()
            self.games[self.room_group_name] = game

        await self.accept()

    async def disconnect(self, code):
        game = self.games[self.room_group_name]
        username = self.__getUsername()
        game.removeUsername(
            username
        )
        if len(game.usernames()) != 0:
            username = game.currentUser()
        await self.channel_layer.group_send(
                self.room_group_name,
                {
                    'type': 'send_message',
                    'state': "disconnect",
                    'message': {
                        'username': username,
                        'cUser': username,
                    }
                }
            )
        await self.channel_layer.group_discard(
            self.room_group_name,
            self.channel_name
        )
        return super().disconnect(code)

    async def receive(self, text_data):
        data_json = json.loads(text_data)

        event = data_json['event']
        message = data_json['message']
        inpt = message.pop('input', None)
        cword = None
        guessResult = None
        username = self.__getUsername()
        # Uso del Modelo
        game = self.games[self.room_group_name]
        if event == "start":
            game.addUsername(username)
            state = "init"
            message = {
                'cword' : game.cword(),
                'cUser' : game.currentUser(),
                'username': username,
            }
        else:
            canPlay = game.canPlay(username)

            if canPlay:
                if event == "letter":
                    guessResult = game.guessLetter(inpt)
                    cword = game.cword()
                    if len(inpt) != 0:
                        inpt = inpt[0]
                    else:
                        inpt = '🤐'
                elif event == "word":
                    guessResult = game.guessWord(inpt)
                    cword = game.cword()
                    if len(inpt) == 0:
                        inpt = '🤐'
                # TODO: Evento para ganar
                cUser = game.currentUser()
                gameSolved = game.checkIfSolved()
                if gameSolved:
                    state = "solved"
                else:
                    state = "unsolved"

                message = {
                    'cword': cword,
                    'cUser': cUser,
                    'input': inpt,
                    'guessResult': guessResult,
                    'username': username,
                }
            else:
                state = "invalidTurn"
                message = {
                    'username': username,
                }
        # print(game.usernames())
        await self.channel_layer.group_send(
                self.room_group_name,
                {
                    'type': 'send_message',
                    'state': state,
                    'message': message
                }
            )

    async def send_message(self, event):
        state = event['state']
        message = event['message']

        await self.send(
            text_data=json.dumps({
                'state': state,
                'message': message,
            })
        )


'''
Example 3 : Cops in house 10 can cover houses 1 to 18, and cops in house 51 can cover houses 41 to 91. So, in total, 9 houses are safe.

'''

# Write your code here
def safe_houses(houses, cop_houses, speed, time):
    safe_houses = []
    for house in houses:
        flag = True
        for cop_house in cop_houses:
            if abs(house - cop_house) <= speed * time:
                flag = False
                break
        if flag:
            safe_houses.append(house)
    return len(safe_houses)

if __name__ == '__main__':
    t = int(input())
    for i in range(t):
        m, x, y = map(int, input().split())
        cop_houses = list(map(int, input().split()))
        houses = [i for i in range(1, 101)]
        print(safe_houses(houses, cop_houses, x, y))


import numpy as np
import sklearn.metrics
import model.binary_performance as binary_performance

def test_accuracies():
    np.random.seed(20200218)
    vec_size = 50
    true_vals = np.random.randint(2, size=vec_size)
    pred_vals = np.random.random(vec_size)

    print("Testing accuracies...")
    pred_vals_rounded = np.round(pred_vals)
    acc, pos_acc, neg_acc = binary_performance.accuracies(
        true_vals, pred_vals_rounded
    )

    num_pos, num_neg = 0, 0
    num_pos_right, num_neg_right = 0, 0
    for i in range(vec_size):
        if true_vals[i] == 1:
            num_pos += 1
            if pred_vals[i] >= 0.5:
                num_pos_right += 1
        else:
            num_neg += 1
            if pred_vals[i] < 0.5:
                num_neg_right += 1

    print("\tSame result? %s" % all([
        acc == (num_pos_right + num_neg_right) / vec_size,
        pos_acc == num_pos_right / num_pos,
        neg_acc == num_neg_right / num_neg
    ]))

def test_corrected_precision_auprc():
    np.random.seed(20200218)
    vec_size = 10000
    neg_upsample_factor = 5
    estimate_tolerance = 0.02

    def test_single_result(true_vec, pred_vec):
        """
        Tests similarity of precision/recall/auPRC computation to `sklearn`
        library, without any downsampling of negatives
        """
        precis, recall, thresh = \
            binary_performance.estimate_imbalanced_precision_recall(
                true_vec, pred_vec, neg_upsample_factor=1
            )
        precis_score, recall_score = binary_performance.precision_recall_scores(
            precis, recall, thresh
        )
        auprc = sklearn.metrics.auc(recall, precis)
        sk_precis, sk_recall, sk_thresh = \
            sklearn.metrics.precision_recall_curve(true_vec, pred_vec)
        sk_precis_score = sklearn.metrics.precision_score(
            true_vec, np.round(pred_vec)
        )
        sk_recall_score = sklearn.metrics.recall_score(
            true_vec, np.round(pred_vec)
        )
        sk_auprc = sklearn.metrics.auc(sk_recall, sk_precis)
        print("\tSame result? %s" % all([
            np.allclose(precis, sk_precis),
            np.allclose(recall, sk_recall),
            np.allclose(thresh, sk_thresh),
            precis_score == sk_precis_score,
            recall_score == sk_recall_score,
            auprc == sk_auprc
        ]))

    def test_neg_sampling_result(true_vec, pred_vec, neg_upsample_factor):
        """
        Tests that after down-sampling negatives and re-inflating them using
        `neg_upsample_factor`, the precision/recall/auPRC are roughly the same
        as if no down-sampling had occurred.
        """
        # Get results without downsampling negatives
        precis, recall, thresh = \
            binary_performance.estimate_imbalanced_precision_recall(
                true_vec, pred_vec, neg_upsample_factor=1
            )
        precis_score, recall_score = binary_performance.precision_recall_scores(
            precis, recall, thresh
        )
        auprc = sklearn.metrics.auc(recall, precis)

        # Subsample negatives
        pos_mask = true_vals == 1
        neg_mask = true_vals == 0
        sub_mask = np.random.choice(
            [True, False], size=vec_size,
            p=[1 / neg_upsample_factor, 1 - (1 / neg_upsample_factor)]
        )
        keep_mask = pos_mask | (neg_mask & sub_mask)
        c_precis, c_recall, c_thresh = \
            binary_performance.estimate_imbalanced_precision_recall(
                true_vec[keep_mask], pred_vec[keep_mask],
                neg_upsample_factor=neg_upsample_factor
            )
        c_precis_score, c_recall_score = \
            binary_performance.precision_recall_scores(
                c_precis, c_recall, c_thresh
            )
        c_auprc = sklearn.metrics.auc(c_recall, c_precis)
        print("\tAll within %s? %s" % (
            estimate_tolerance,
            all([
                abs(precis_score - c_precis_score) < estimate_tolerance,
                abs(recall_score - c_recall_score) < estimate_tolerance,
                abs(auprc - c_auprc) < estimate_tolerance
            ])
        ))

    true_vals = np.random.choice(2, size=vec_size)

    # Random predictions
    pred_vals = np.random.random(vec_size)

    print("Testing precision/recall/auPRC on random data without correction...")
    test_single_result(true_vals, pred_vals)

    print("Testing precision/recall/auPRC on random data with correction...")
    test_neg_sampling_result(true_vals, pred_vals, 5)

    # Predictions are a bit closer to being correct; make predictions Gaussian
    # noise centered as 0 or 1, and cut off anything outside [0, 1]
    pred_vals = np.empty(vec_size)
    rand = np.random.randn(vec_size) / 2
    pos_mask = true_vals == 1
    pred_vals[pos_mask] = rand[pos_mask] + 1
    neg_mask = true_vals == 0
    pred_vals[neg_mask] = rand[neg_mask]
    pred_vals[pred_vals < 0] = 0
    pred_vals[pred_vals > 1] = 1

    print("Testing precision/recall/auPRC on good data without correction...")
    test_single_result(true_vals, pred_vals)

    print("Testing precision/recall/auPRC on good data with correction...")
    test_neg_sampling_result(true_vals, pred_vals, 5)

class FakeLogger:
    def log_scalar(self, a, b):
        pass

def test_all_metrics_on_different_predictions():
    np.random.seed(20200218)
    batch_size, num_tasks  = 100, 2
    true_vals = np.random.randint(2, size=(batch_size, num_tasks))

    _run = FakeLogger()

    # Make some "perfect" predictions, which are identical to truth
    print("Testing all metrics on some perfect predictions...")
    pred_vals = true_vals
    metrics = binary_performance.compute_performance_metrics(
        true_vals, pred_vals, 1
    )
    binary_performance.log_performance_metrics(metrics, "Perfect", _run)

    # Make some "good" predictions, which are close to truth; make predictions
    # Gaussian noise centered as 0 or 1, and cut off anything outside [0, 1]
    print("Testing all metrics on some good predictions...")
    pred_vals = np.empty((batch_size, num_tasks))
    rand = np.random.randn(batch_size, num_tasks) / 2
    pos_mask = true_vals == 1
    pred_vals[pos_mask] = rand[pos_mask] + 1
    neg_mask = true_vals == 0
    pred_vals[neg_mask] = rand[neg_mask]
    pred_vals[pred_vals < 0] = 0
    pred_vals[pred_vals > 1] = 1
    metrics = binary_performance.compute_performance_metrics(
        true_vals, pred_vals, 1
    )
    binary_performance.log_performance_metrics(metrics, "Good", _run)

    # Make some "bad" predictions, which are just random
    print("Testing all metrics on some bad predictions...")
    pred_vals = np.random.random((batch_size, num_tasks))
    metrics = binary_performance.compute_performance_metrics(
        true_vals, pred_vals, 1
    )
    binary_performance.log_performance_metrics(metrics, "Bad", _run)

if __name__ == "__main__":
    test_accuracies()
    test_corrected_precision_auprc()
    test_all_metrics_on_different_predictions()


import random

class DailyDoubleSetter:
    def __init__(self, box):
        self.counter = 0
        self.pickedBox = 0
        self.box = box

    """Sets which boxes are daily doubles, 1 for the first round and two for the second"""
    def setDailyDoubles(self):
        dd = random.randrange(36)
        self.counter+=1

        while self.box[dd].getQuestion == "placeholder" or dd == self.pickedBox:
            dd = random.randrange(36)
        if self.counter == 2:
            self.pickedBox == dd
        return dd


input()

sumaImpar = 0
sumaPar = 0
for i in range(4):
    temp = [int(i) for i in input().split()]
    if i % 2 == 0:
        sumaImpar += sum(temp[0::2])
        sumaPar += sum(temp[1::2])
    else:
        sumaImpar += sum(temp[1::2])
        sumaPar += sum(temp[0::2])

print(max([sumaImpar, sumaPar]))


import os

import dash
import dash_core_components as dcc
import dash_html_components as html
import plotly.express as px
import pandas as pd
from dash.dependencies import Input, Output
import plotly.graph_objs as go
import pickle as pkl

external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']

app = dash.Dash(__name__, external_stylesheets=external_stylesheets,
                update_title='Chargement...')
server = app.server

dict_prénoms = pkl.load(open('data/dict_prenoms.pkl', 'rb'))
df_nat = pd.read_feather('data/df_nat.feather')
# Suppression des prénoms trop rares :
masque_prénoms_rares = (
    df_nat.prénoms_s == '_PRENOMS_RARES - ♂') | (df_nat.prénoms_s == '_PRENOMS_RARES - ♀')
# drop des prénoms rares
df_nat = df_nat.drop(df_nat[masque_prénoms_rares].index)

app.layout = html.Div(children=[
    html.H1(children='Naissances France'),

    html.Div(id='sous-titre', children='''
        Fréquence des prénoms de naissance en France de 1900 à nos jours
    '''),
    dcc.Dropdown(
        id='dropdown-prénoms',
        options=dict_prénoms,
        value=[dict_prénoms[888]['value']],
        placeholder="Chercher un prénom",
        multi=True
    ),
    dcc.Graph(
        id='graph-fréquences',
        style={'height': '80vh'},
        config={'displayModeBar': False}
    ),
    html.Div(id='bandeau', children=""),
])

@app.callback(
    Output(component_id='bandeau', component_property='children'),
    [Input(component_id='dropdown-prénoms', component_property='value')]
)
def maj_bandeau(prénoms_selectionnés):
    if len(prénoms_selectionnés) == 0:
        return ""
    else:
        masque = df_nat.prénoms_s == prénoms_selectionnés[0]
        genre = "e" if prénoms_selectionnés[0][-1] == '♀' else ""
        return f"Il y a {df_nat[masque].nombre.sum()} {prénoms_selectionnés[0]} né{genre}s  en France depuis 1900"

@app.callback(
    Output(component_id='graph-fréquences', component_property='figure'),
    [Input(component_id='dropdown-prénoms', component_property='value')]
)
def maj_graph(prénoms_selectionnés):
    fig = go.Figure()
    for prénom_select in prénoms_selectionnés:
        masque = df_nat.prénoms_s == prénom_select
        fig.add_trace(
            go.Scatter(
                x=df_nat[masque].annais,
                y=df_nat[masque].nombre,
                name=prénom_select,
                text=df_nat[masque].rangs,
                mode='markers+lines',
                hovertemplate='Année : %{x}
Nombre : %{y}
Rang : %{text}ème'))
        fig.update_layout(
            xaxis=dict(title="Année de naissance"),
            yaxis=dict(title="Nombre de naissances"),
        )
    return fig

if __name__ == '__main__':
    app.run_server()


#AoC day_08
import math

#input
def input_from_file(file):
    lines = [[]]
    with open(file) as f:
        for i, line in enumerate(f.readlines()):
            if i == 0: lines += line.strip().split()
            elif i > 1: lines[0].append((line[0:3], line[7:10], line[12:15]))
        f.close()
    return lines

#part_1
def calc_number_of_steps(vertices, order):
    dict, current, i = {}, 'AAA', 0
    for vertex in vertices:
        dict[vertex[0]] = (vertex[1], vertex[2])
    while True:
        if current == 'ZZZ': return i
        if order[i % len(order)] == 'L': current = dict[current][0]
        else: current = dict[current][1]
        i += 1

#part_2
def calc_number_of_steps_with_all_a_starts(vertices, order):
    dict, currents, i = {}, [], 0
    for vertex in vertices:
        dict[vertex[0]] = (vertex[1], vertex[2])
        if vertex[0][2] == 'A': currents.append([vertex[0], None])
    while True:
        if all(type(current[1]) == int for current in currents): break
        sign = 0 if order[i % len(order)] == 'L' else 1
        for j, current in enumerate(currents):
            if current[0][2] == 'Z': currents[j][1] = i
            currents[j][0] = dict[current[0]][sign]
        i += 1
    return math.lcm(*[current[1] for current in currents])

#main
if __name__ == '__main__':
    vertices, order = input_from_file("day_08/input.txt")
    print(calc_number_of_steps(vertices, order))
    print(calc_number_of_steps_with_all_a_starts(vertices, order))


import json
import pandas as pd
import requests

from pathlib import Path
from tqdm import tqdm

# -------------
def ConstructRequestUrl(sciName:str) -> str:
  baseUrl = 'http://www.xeno-canto.org/api/2/recordings'
  audioType = 'song'
  country = 'Taiwan'
  return baseUrl + f'?query={sciName}%20cnt:{country}%20type:{audioType}'

def DownloadAudio(speciesCode, url, fileID, q):
  filename = f'{speciesCode}_XC{fileID}_{q}.mp3'
  filePath = Path.cwd().joinpath('audio', 'xeno-canto', f'{filename}')
  res = requests.get(url)
  with open(filePath, 'wb') as f:
    for data in res.iter_content(1024):
      f.write(data)

# -------------
if __name__ == '__main__':
  urlDF = pd.DataFrame(columns=['code', 'audio Url'])

  ## Load species Code
  codeDF = pd.read_csv(Path.cwd().joinpath('assets', 'code.csv'), header=0)
  for _, row in codeDF.iterrows():
    reqUrl = ConstructRequestUrl(row['sci Name'])
    res = requests.get(reqUrl)
    data = json.loads(res.text)

    ### Download and save audio, and save its url
    numberOfRecordings = data['numRecordings']
    recordings = data['recordings']
    for recording in tqdm(
      recordings,
      total=len(recordings),
      desc=f'{"downloading...":>16}',
      bar_format='{l_bar}{bar:32}{r_bar}{bar:-32b}'
    ):
      DownloadAudio(row['code'], recording['file'], recording['id'], recording['q'])
      urlDF = pd.concat(
        [urlDF, pd.DataFrame({
          'code': row['code'],
          'audio Url': recording['file']
        }, index=[0])],
        ignore_index=True
      )
  urlDF.to_csv(Path.cwd().joinpath('assets', 'XC_urls.csv'), header=True, index=False)


import numpy as np

import tinytorch
from tinytorch import init, nn, math
from tinytorch.datasets import mnist, DataLoader

data_train = mnist.train('../dataset/')
data_test = mnist.test('../dataset/')

avg_data = np.average(data_train[0])
std_data = np.std(data_train[0])

data_train[0] = (data_train[0]-avg_data)/std_data
data_test[0] = (data_test[0]-avg_data)/std_data

BATCH_SIZE = 4

train = DataLoader(data_train, BATCH_SIZE, True)
#test = DataLoader(data_test, BATCH_SIZE, True)

input = tinytorch.Tensor.from_numpy(np.empty(784))
label = tinytorch.Tensor.from_numpy(np.empty(10))
seq = tinytorch.nn.Sequential([
	tinytorch.nn.Linear(784, 800, init.Initializer(init.he_normal)),
	tinytorch.nn.ReLU(),
	tinytorch.nn.Linear(800, 10, init.Initializer(init.xavier_normal))
])
loss = tinytorch.nn.SoftmaxCrossEntropyWithLogits()
weight_decay = tinytorch.nn.L2Norm()

import visdom
vis = visdom.Visdom() #for loss visualization

def get_accuracy():
	count = len(data_test[1])
	right_count = 0
	for i in range(len(data_test[1])):
		input.data = data_test[0][i].flatten()
		label = np.argmax(math.softmax(seq(input).data))
		if label == data_test[1][i]:
			right_count += 1
	return(right_count/count)

avg_loss = 0
learning_rate = 0.01
for iter, batch in enumerate(train):
	seq.zero_grad()

	out = 0
	for i in range(BATCH_SIZE):
		input.data = batch[0][i].reshape(784)
		label.data.fill(0.0)
		label.data[batch[1][i]] = 1.0

		out = loss(seq(input), label) #+ 0.01*weight_decay(seq.layer_list[0].weight) + 0.01*weight_decay(seq.layer_list[2].weight)
		out.backward()
		avg_loss += out.data

	for key, value in seq.parameters.items():
		value.data -= learning_rate*value.grad

	if iter % 10 == 0 and iter > 0:
		learning_rate = pow(learning_rate, 1.0001)

	if iter % 100 == 0 and iter > 0:
		avg_loss /= BATCH_SIZE
		avg_loss /= 100.0
		vis.line([avg_loss], [iter], 'avgloss', name='AvgLoss', update='append', opts=dict(title='AvgLoss'))
		avg_loss = 0

	if iter % 1000 == 0 and iter > 0:
		vis.line([get_accuracy()], [iter], 'accuracy', name='Accuracy', update='append', opts=dict(title='Accuracy'))


# -*- coding: utf-8 -*-
#
#   auth
#
# -----------------------------------------------------------------------------

import binascii
import ecdsa
import re
from web3.auto import w3

from neutral.libs.client.hash import HashType, Hasher

# -----------------------------------------------------------------------------

class EcdsaVerifier(object):
    '''Generic ECDSA verifier using python-ecdsa.'''

    def __init__(self, verifying_key):
        assert isinstance(verifying_key, ecdsa.VerifyingKey)
        self.verifying_key = verifying_key

    def verify_bytes(self, sig, data):
        assert isinstance(sig, str), sig
        sig = binascii.unhexlify(str(sig))
        if len(sig) == 65:
            sig = sig[1:]
        elif len(sig) != 64:
            raise ValueError('invalid signature length {}'.format(sig))
        self.verifying_key.verify(sig, data)

    def verify_string(self, sig, text, encoding='utf-8'):
        self.verify_bytes(sig, bytes(text, encoding=encoding))

# -----------------------------------------------------------------------------

class Web3EcdsaSigner(object):
    '''
    Web3 adds a recovery byte to the signature. We have to use this to ensure
    correct extraction of the public key in the backend (since we are not
    transmitting the public key over.
    '''

    def __init__(self, signing_key, hash_type):
        assert isinstance(signing_key, ecdsa.SigningKey)
        assert isinstance(hash_type, HashType)

        self.signing_key = signing_key
        self.private_key = signing_key.to_string()
        self.hash_type = hash_type
        self.hasher = Hasher.create(hash_type)

    def get_hash_type():
        return self.hash_type

    def sign_bytes(self, data):
        return self.sign_hash(self.hasher(data).digest())

    def sign_string(self, text, encoding='utf-8'):
        return self.sign_bytes(bytes(text, encoding=encoding))

    '''
    The backend uses (v + r + s)
    w3.eth.account.signHash returns (r + s + v)
    '''
    def sign_hash(self, data_hash):
        # print('hash ({}}: {}'.format(type(data_hash), data_hash))
        signed = w3.eth.account.signHash(data_hash, private_key=self.private_key)
        signature = re.sub(r'^0x', '', signed.signature.hex())
        signature = signature[-2:] + signature[:-2]
        return signature

# -----------------------------------------------------------------------------

class UserAuthentication(object):
    def __init__(self, signer):
        self.signer = signer
        verifying_key = signer.signing_key.get_verifying_key()
        self.verifier = EcdsaVerifier(verifying_key)

    def gen_authentication_header(self, token_str):
        signature = self.signer.sign_string(token_str)
        print('token: {}'.format(token_str))
        print('signature: {}'.format(signature))
        self.verifier.verify_string(
            signature[2:],  # strip the recovery byte
            token_str
        )
        return [
            ('session-token', token_str),
            ('user-signature', signature),
        ]

# =============================================================================


import requests
from bs4 import BeautifulSoup
import pandas as pd

URL = "https://www.pepcoding.com/resources/online-java-foundation"
page = requests.get(URL)
soup = BeautifulSoup(page.content, "html.parser")

module_list = soup.find_all("li", class_="classResourceList")

question_id = []
question_name = []
topic_name = []
module_name = []

for module in module_list:
    module_div = module.find("div", class_="collapsible-header")
    mname = module_div.text.lstrip().rstrip()

    topic_list = module.find_all("li", class_="list-item")
    for topic in topic_list:
        topic_href = "https://www.pepcoding.com" + topic.find('a', href=True)['href']
        tname = topic.text.lstrip().rstrip()

        topic_page = requests.get(topic_href)
        topic_soup = BeautifulSoup(topic_page.content, "html.parser")
        question_list = topic_soup.find_all("li", attrs={"resource-type":"ojquestion"})

        count = 0
        for question in question_list:
            qname = question.find('a', href=True).text.lstrip().rstrip()
            qid = question['resource-type-id']

            question_id.append(qid)
            question_name.append(qname)
            topic_name.append(tname)
            module_name.append(mname)
            count += 1
        print(count, "->", tname)

dict = {"ID": question_id, "Question": question_name, "Topic": topic_name, "Module": module_name}
df = pd.DataFrame(dict)

df.to_csv('question_list.csv', index=False)


import tweepy
import config
from tweepy.auth import OAuthHandler
from time import sleep

client = tweepy.Client(config.Bearer_Token,config.API_KEY,config.API_KEY_SECRET, config.Access_Token, config.Access_Token_Select)

auth = tweepy.OAuth1UserHandler(config.API_KEY, config.API_KEY_SECRET)
auth.set_access_token(config.Access_Token, config.Access_Token_Select)
api = tweepy.API(auth)

url = ''

long_text = f""

# 將長文切成每一tweet不超過250字元的限制（中文字佔2個字元）
def cutit(chunks, url):
    chunks = [long_text[i:i+140] for i in range(0, len(long_text), 140)]
    # 先發布第一則tweet
    tweet1 = api.update_status(chunks[0])
    # 取得第一則tweet的ID
    previous_tweet_id = tweet1.id
    # 用for迴圈接續第一則tweet的下方，發布第二則tweet，以此類推
    for text in chunks[1:]:
        tweet = api.update_status(text, in_reply_to_status_id=previous_tweet_id)
        previous_tweet_id = tweet.id
        sleep(2)
    # 在最後一段tweet貼上新聞網址
    tweet = api.update_status(url,in_reply_to_status_id=previous_tweet_id)

# 手動分行tweet
def selfCut(long_text):
    tweet1=  api.update_status(long_text[0])
    previous_tweet_id = tweet1.id
    for text in long_text[1:]:
        tweet = api.update_status(text, in_reply_to_status_id=previous_tweet_id)
        previous_tweet_id = tweet.id
        sleep(2)
    tweet = api.update_status(url,in_reply_to_status_id=previous_tweet_id)

# execute:
cutit(long_text, url)

# 將每個tweet在後面加上頁數
# for i, chunk in enumerate(chunks):
#     tweet1 = api.update_status(f'{chunk}({i+1}/{len(chunks)})')
#     print(tweet1)

# 驗證twitter的API連線是否成功
# try:
#     api.verify_credentials()
#     print('yes')
# except:
#     print('failed')


from flask import Blueprint, jsonify, request, redirect, url_for
from app.models import db, Task, Project, user

project_routes = Blueprint('projects', __name__)

@project_routes.route('/<int:id>')
def get_projects(id):
    #print('111111111111', id)
    projects = Project.query.filter_by(user_id = id)
    return {'projects': [project.project_to_dict() for project in projects]}

@project_routes.route('/tasks/<int:id>')
def get_project_tasks(id):
    tasks = Task.query.filter_by(project_id = id)
    # for task in tasks:
    #     print('--------------', task.task_to_dict(), '----------')
    return {'project_tasks': [task.task_to_dict() for task in tasks]}

@project_routes.route('/new', methods=['POST'])
def new_project():
    #print('###########')
    user_id=request.json['userId']
    color = request.json['color']
    project_name = request.json['projectName']

    project = Project(
        user_id = user_id,
        project_name = project_name,
        color = color,
    )

    db.session.add(project)
    db.session.commit()

    return project.project_to_dict()

@project_routes.route('/edit/<int:id>', methods = ['PUT'])
def edit_task(id):
    project = Project.query.get(id)

    user_id = request.json['userId']
    project_name = request.json['projectName']
    color = request.json['color']

    project.project_name = project_name
    project.color = color

    db.session.add(project)
    db.session.commit()
    return project.project_to_dict()

@project_routes.route('/delete/<int:id>', methods=['DELETE'])
def delete_project(id):
    project = Project.query.get(id)

    db.session.delete(project)
    db.session.commit()

    return project.project_to_dict()


#!/usr/bin/env python

from math import atan2, sin, cos, pow, sqrt

from dataclasses import dataclass
@dataclass
class EndEffectorWorkingSpace:
    # Pos of The P2, which is the one we resolved for
    P2_x: float
    P2_y: float
    # Orientation of the X axis respect frame 0, which is regulated by Chi
    chi: float

class ComputeIk():

    def __init__(self, DH_parameters):

        # DH parameters
        self.DH_parameters_ = DH_parameters

    def get_dh_param(self, name):

        if name in self.DH_parameters_:
            return self.DH_parameters_[name]
        else:
            assert False, "Asked for Non existen param DH name ="+str(name)

    def compute_ik(self, end_effector_pose, elbow_configuration = "down"):

        # Initialization
        p2_x = end_effector_pose.P2_x
        p2_y = end_effector_pose.P2_y

        # The Angle that Xee makes with frames 0 x axis
        chi = end_effector_pose.chi

        # We get all the DH parameters
        r1 = self.get_dh_param("r1")
        r2 = self.get_dh_param("r2")
        r3 = self.get_dh_param("r3")

        print("Input Data===== ELBOW P1 CONFIG = "+str(elbow_configuration))
        print("p2_x = "+str(p2_x))
        print("p2_y = "+str(p2_y))
        print("chi = "+str(chi))
        print("r1 = "+str(r1))
        print("r2 = "+str(r2))

        # We declare all the equations for theta1, theta2, theta3 and auxiliary
        #########################################################################
        # theta_2
        G = ( pow(p2_x,2) + pow(p2_y,2) - pow(r1,2) - pow(r2,2)) / (2.0 * r1 * r2)

        print(G)

        ## WE HAVE TO CHECK THAT ITS POSSIBLE
        ## -1 <= G <= 1
        possible_solution = False
        if (G <= 1 ) and ( G>= -1):
            possible_solution = True
        else:
            pass

        theta_array = []

        if possible_solution:
            # We have to decide which solution we want
            if elbow_configuration == "down":
                # Positive
                numerator_1 = sqrt(1-pow(G,2))
            else:
                numerator_1 = -1.0 * sqrt(1-pow(G,2))

            denominator_1 = G

            theta_2 = atan2(numerator_1, denominator_1)
            #########################################################################

            #########################################################################
            # theta1
            theta_1 = atan2(p2_y,p2_x) - atan2(r2*sin(theta_2),(r1 + r2*cos(theta_2)))

            #########################################################################

            #########################################################################
            # theta3
            #
            theta_3 = chi - theta_1 - theta_2
            #########################################################################

            theta_array = [theta_1, theta_2, theta_3]

        return theta_array, possible_solution

def calculate_ik(P2_x, P2_y, chi, DH_parameters, elbow_config = "down"):
    ik = ComputeIk(DH_parameters = DH_parameters)
    end_effector_pose = EndEffectorWorkingSpace(P2_x = P2_x,
                                                P2_y = P2_y,
                                                chi = chi)

    thetas, possible_solution = ik.compute_ik(  end_effector_pose=end_effector_pose,
                                                elbow_configuration = elbow_config)

    print("Angles thetas solved ="+str(thetas))
    print("possible_solution = "+str(possible_solution))

if __name__ == '__main__':

    r1 = 1.0
    r2 = 1.0
    r3 = 1.0

    # theta_i here are valriables of the joints
    # We only fill the ones we use in the equations, the others were already
    # replaced in the Homogeneous matrix
    DH_parameters={"r1":r1,
                    "r2":r2,
                    "r3":r3}

    P2_x = 1.0
    P2_y = 1.0
    chi = 0.7

    calculate_ik(P2_x=P2_x, P2_y=P2_y, chi=chi,DH_parameters=DH_parameters, elbow_config = "down")
    calculate_ik(P2_x=P2_x, P2_y=P2_y, chi=chi,DH_parameters=DH_parameters, elbow_config = "up")


# all() in python

numberList = [2, 4, 6, 8, 10, 12, 14, 16, 18]
trueNumbers = [1, 2, 3, 4, 5, 6, 7]
falseNumbers = [0, 1, 2, 3, 4, 5, 6]

check0 = all(trueNumbers)
check1 = all(falseNumbers)

print(f"[1, 2, 3, 4, 5, 6, 7] True sines is : {check0}\n[0, 1, 2, 3, 4, 5, 6] False sines is : {check1}")

even = all(num for num in numberList if num % 2 == 0)

print(f"Even ?? : {even}")


import os
import urllib

from google.appengine.api import users
from google.appengine.ext import ndb

# For Udacity blog
from google.appengine.ext import db

import jinja2
import webapp2

PROJECT_DIR = os.path.dirname(__file__);

JINJA_ENVIRONMENT = jinja2.Environment(
    loader=jinja2.FileSystemLoader(PROJECT_DIR),
    extensions=['jinja2.ext.autoescape'])

# Following Udacity handler stuff for templating
class Handler(webapp2.RequestHandler):
  def write(self, *a, **kw):
      self.response.out.write(*a, **kw)

  def render_str(self, template, **params):
      t = JINJA_ENVIRONMENT.get_template(template)
      return t.render(params)

  def render(self, template, **kw):
      self.write(self.render_str(template, **kw))

# Misc....
class index(webapp2.RequestHandler):
  def get(self):
      template = JINJA_ENVIRONMENT.get_template('index.html')
      self.response.write(template.render())

class banana(webapp2.RequestHandler):
  def get(self):
      template = JINJA_ENVIRONMENT.get_template('banana.html')
      self.response.write(template.render())

class about(webapp2.RequestHandler):
  def get(self):
      template = JINJA_ENVIRONMENT.get_template('about.html')
      self.response.write(template.render())

class resume(webapp2.RequestHandler):
  def get(self):
      template = JINJA_ENVIRONMENT.get_template('resume.html')
      self.response.write(template.render())

class contact(webapp2.RequestHandler):
  def get(self):
      template = JINJA_ENVIRONMENT.get_template('contact.html')
      self.response.write(template.render())

class error404(webapp2.RequestHandler):
  def get(self):
      template = JINJA_ENVIRONMENT.get_template('404.html')
      self.response.write(template.render())

# ------ Udacity HW3: Basic blog -------- #

class blogPostingDB(db.Model):
  # Datastore stuff
  subject = db.StringProperty(required = True)
  content = db.TextProperty(required = True)
  created = db.DateTimeProperty(auto_now_add = True) # Just a time stamp

class blog(Handler):
  # Blog front page
  def get(self):
      # Query all blog posts in database
      blogPosts = db.GqlQuery("SELECT * FROM blogPostingDB ORDER BY created DESC ")
      self.render('blog.html', blogPosts = blogPosts)

class newpost(Handler):
  # Interface to make new blog posts
  def render_newpost(self, subject="", content="", error=""):
      self.render('newpost.html', subject=subject, content=content, error=error)

  def get(self):
      self.render_newpost()

  def post(self):
      subject = self.request.get("subject")
      content = self.request.get("content")

      if subject and content:
        # Successful post
        bp = blogPostingDB(subject = subject, content = content)
        bp_key = bp.put() # Store data in database
        # Redirect to blog posting
        self.redirect('/blog/%d' % bp_key.id())
      else:
        # Error handling
        error = "Need both a subject and content"
        self.render_newpost(subject, content, error)

class permalink(blog):
  # for handling permalink to new blog posting
  def get(self, blog_id):
      s = blogPostingDB.get_by_id(int(blog_id))
      self.render("blog.html", blogPosts=[s])

# App definition stuff
app = webapp2.WSGIApplication([('/',        index),
                               ('/blog',    blog),
                               ('/blog/newpost', newpost),
                               ('/blog/(\d+)',   permalink),
                               ('/index',   index),
                               ('/home',    index),
                               ('/banana',  banana),
                               ('/about',   about),
                               ('/resume',  resume),
                               ('/contact', contact),
                               ('/404',     error404)
                              ],
                              debug=True)


from gi.repository import Gtk, Gdk
import git
import indicator
import settings

class GenericWindow(Gtk.Window):

    def __init__(self, builder_path, object_name, handlers, css_path='../data/styles/commit.css'):
        super().__init__()

        self._create_css_provider(css_path)
        self._init_builder(builder_path, handlers)
        window = self._builder.get_object(object_name)
        window.show_all()

    def _create_css_provider(self, css_path):
        css_provider = Gtk.CssProvider()
        css_provider.load_from_path(css_path)
        Gtk.StyleContext.add_provider_for_screen(Gdk.Screen.get_default(), css_provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)

    def _init_builder(self, builder_path, handles):
        self._builder = Gtk.Builder()
        self._builder.add_from_file(builder_path)
        self._builder.connect_signals(handles)

class SettingsWindow(GenericWindow):
    BUILDER_PATH = '../data/layouts/settings_window.glade'
    OBJECT_NAME = 'SettingsWindow'

    def __init__(self):
        handlers = { 'onSaveClicked': self._save_settings }

        super().__init__(self.BUILDER_PATH, self.OBJECT_NAME, handlers)
        self._load_settings()

    def _load_settings(self):
        dir_entry = self._builder.get_object('DirEntry')
        handle_entry = self._builder.get_object('HandleEntry')
        key_entry = self._builder.get_object('KeyEntry')
        pid_entry = self._builder.get_object('PIDEntry')

        data = settings.load_settings()

        dir_entry.set_text(data['directory'])
        handle_entry.set_text(data['handle'])
        key_entry.set_text(data['key'])
        pid_entry.set_text(data['pid'])

    def _save_settings(self, button):
        dir_entry = self._builder.get_object('DirEntry')
        handle_entry = self._builder.get_object('HandleEntry')
        key_entry = self._builder.get_object('KeyEntry')
        pid_entry = self._builder.get_object('PIDEntry')

        git.set_api_key(dir_entry.get_text(), handle_entry.get_text(), key_entry.get_text())
        git.set_pid(dir_entry.get_text(), pid_entry.get_text())

        settings.save_settings(dir_entry.get_text(), handle_entry.get_text(),\
                               key_entry.get_text(), pid_entry.get_text())

class CommitWindow(GenericWindow):
    BUILDER_PATH = '../data/layouts/commit_window.glade'
    OBJECT_NAME = 'CommitWindow'

    def __init__(self, timer_item):
        handlers = { 'onCommitClicked' : self._commit }
        self._timer_item = timer_item
        super().__init__(self.BUILDER_PATH, self.OBJECT_NAME, handlers)

    def _commit(self, button):
        time_formatted = self._get_time_formatted()

        subject_entry = self._builder.get_object('SubjectEntry')
        handles_entry = self._builder.get_object('HandlesEntry')

        git.commit('/home/kuba/Work/Study/University/10_semester/vcs/python-test', \
                   subject_entry.get_text(), time_formatted, handles_entry.get_text())

    def _get_time_formatted(self):
        time = self._timer_item.current_time
        self._timer_item.reset_timer()

        minutes, _ = divmod(time, 60)
        hours, minutes = divmod(minutes, 60)

        return "%d h %d min" % (hours, minutes)

class OverviewWindow(GenericWindow):
    BUILDER_PATH = '../data/layouts/overview_window.glade'
    OBJECT_NAME = 'OverviewWindow'

    def __init__(self):
        handlers = {'onShaEntered' : self._show_time}
        super().__init__(self.BUILDER_PATH, self.OBJECT_NAME, handlers)

    def _show_time(self):
        commit_label = self._builder.get_object('CommitLabel')
        sha_entry = self._builder.get_object('ShaEntry')
        data = settings.load_settings()
        git_dir = data['directory']
        commit_text = git.show(git_dir, sha_entry.get_text())
        commit_label.set_text(commit_text)


#!/usr/bin/python3

# ## {R2D2919B742E} ##
# ###########################################################################
# What if magic existed?
# What if a place existed where your every thought and dream come to life.
# There is only one catch: it has to be written down.
# Such a place exists, it is called programming.
#    - Scott Taylor Reph, RightThumb.com
# ###########################################################################
# ## {C3P0D40fAe8B} ##

import os, sys, time
##################################################
import _rightThumb._construct as __
appDBA = __.clearFocus( __name__, __file__ )
__.appReg = appDBA
def focus( parentApp='', childApp='', reg=True ):
	global appDBA
	f = __.appName( appDBA, parentApp, childApp )
	if reg:
		__.appReg = f
	return f
__.registeredApps.append( focus() )
import _rightThumb._base3 as _
_.load()
##################################################
import _rightThumb._vars as _v
import _rightThumb._string as _str
##################################################

def appSwitches():
	_.switches.register( 'Test', '-test' )
	_.switches.register( 'Files', '-f,-file,-files','file.txt', isPipe='data', description='Files' )
	_.switches.register( 'Delete', '-d,-delete' )

_.autoBackupData = __.autoCreationConfiguration['backup']
__.releaseAcquiredData = __.autoCreationConfiguration['logs']
__.myFileLocations_SKIP_VALIDATION = False
__.isRequired_Pipe = False
__.isRequired_Pipe_or_File = False
__.pre_error = False
__.switch_raw = []
# __.switch_raw = [ 'Delim' ]
# __.isRequired_or_List = ['Pipe','Files','Plus']
# __.setting( 'app-switches-raw', [ 'Delim' ] )

_.appInfo[focus()] = {
	'file': 'decrypt-docs.py',
	'liveAppName': __.thisApp( __file__ ),
	'description': 'decrypt registered documentation files',
	'categories': [
						'decrypt',
						'docs',
						'tool',
						'file',
						'text',
				],
	'usage': [
						# 'epy another',
						# 'e nmap',
						# '',
	],
	'relatedapps': [
						# 'p another -file file.txt',
						# '',
	],
	'prerequisite': [
						# 'p another -file file.txt',
						# '',
	],
	'examples': [
						_.hp('p decrypt-docs -file file.txt'),
						'',
	],
	'columns': [
					# { 'name': 'name', 'abbreviation': 'n' },
					# { 'name': '{1}', 'abbreviation': '{0}', 'sort': '{2}' },
	],
	'aliases': [
					# 'this',
					# 'app',
	],
	'notes': [
					# {},
	],
}

_.appData[focus()] = {
		'start': __.startTime,
		'uuid': '',
		'audit': [],
		'pipe': False,
		'data': {
					'field': {'sent': [], 'received': [] }, # { 'label': '', 'context': [],  }
					'table': {'sent': [], 'received': [] },
		},
	}

def registerSwitches( argvProcessForce=False ):
	global appDBA
	if not __.appReg == appDBA and appDBA in __.appReg:

		if not __name__ == '__main__':
			_.argvProcess = argvProcessForce
		else:
			_.argvProcess = True

		_.load()
		_.appInfo[__.appReg] = _.appInfo[appDBA]
		_.appData[__.appReg] = _.appData[appDBA]
	__.constructRegistration( _.appInfo[__.appReg]['file'],__.appReg )
	appSwitches()

	_.myFileLocation_Print = False
	_.switches.trigger( 'Files', _.myFileLocations, vs=True )
	_.switches.trigger( 'Folder', _.myFolderLocations )
	_.switches.trigger( 'URL', _.urlTrigger )
	_.switches.trigger( 'Ago', _.timeAgo )
	_.switches.trigger( 'Duration', _.timeFuture )

	_.defaultScriptTriggers()
	_.switches.process()

if not __name__ == '__main__':
	_.argvProcess = False
else:
	_.argvProcess = True

registerSwitches()

def fieldSet( switchName, switchField, switchValue, theFocus=False ):
	if not type( theFocus ) == bool:
		theFocus = theFocus
	_.switches.fieldSet( switchName, switchField, switchValue, theFocus )

if __name__ == '__main__':
	if not sys.stdin.isatty():
		_.setPipeData( sys.stdin.readlines(), __.appReg, clean=True )

_.postLoad( __file__ )

########################################################################################
# START

def identify(row):
	if 'sUW+UyzaAo1BuzZ/2UahGCp4kHgiwk+xKniQeCLCT7GlpF8/aeR6NXE0uVp6/Kb/w3tFeg3Qb+9KnIbZ+6+nWijD//xIEr3Q' in row:
		return True
	if ' ' in row:
		return False
	if '!V!' in row:
		return False
	if row.endswith('='):
		return True
	# if len(row) > 15:
	#   return True

	n = '0123456789'
	l = 'abcdefghijklmnopqrstuvwxyz'
	u = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
	aa = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
	chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ/+='

	hasAlpha=False
	for a in aa:
		if a in row:
			hasAlpha=True
			break
	if not hasAlpha:
		return False

	for ch in row:
		if not ch in chars:
			return False
	if ' ' in row:
		return False
	elif '\\' in row:
		return False
	elif '//' in row:
		return False
	elif 'http' in row:
		return False
	elif '=' in row and not row.endswith('='):
		return False
	elif row.endswith('='):
		return True
	elif len(row) > 15:
		return True
	# elif row.count('/') > 1 or row.count('+') :
	#   return True
	# elif row.count('/') > 5 or row.startswith('/'):
	#   return False

	else:

		if len(row) < 7:
			return False

		if row.endswith('='):
			return True

		if len(row) > 40:
			return True

		doc = []
		nn = 0
		ll = 0
		uu = 0
		for ch in row:
			if ch in n:
				doc.append('n')
				nn+=1
			elif ch in l:
				doc.append('l')
				ll+=1
			elif ch in u:
				doc.append('u')
				uu+=1
		if uu == 0 or ll == 0  or nn == 0:
			return False
		if uu > ll and ll > 3:
			return True

		if nn < 3 and len(row) < 8:
			return False
		if uu < 3 or ll < 3 :
			return False
		p = _.percentageDiffInt( uu, ll )
		if p > 75:
			return True
		# _.pr( p, uu, ll, row )
		# _.pr( doc )
		return False

	return False

records = {}
maxLen = 0
maxLen2 = 0
def vcrypyAA(file):
	if type(file) == list:
		result = 'list'
		file = '\n'.join(file)
	else:
		result = 'str'

	if '!V!' in file:
		lp = _.find_all(file,'\n')
		v = _.find_all(file,'!V!')
		for i in v:
			pA = -1
			pB = -1
			for l in lp:
				if l < i:
					pB = pA
					pA = l
				else:
					pB = pA
					pA = l
					break
			# _.pr( '___' )
			# _.pr( 747, (pA,pB), file[pB:pA].replace('\n','\n') )
			vcrypyA(file[pB:pA].replace('\n','\n'))

			# _.pr( '___' )
	return file

def vcrypyA(row):
	global maxLen2
	# global isMD
	# if not isMD:
	#   return row
	row2 = row
	if '!V!' in row2:
		row2 = row2.replace('!V!','')
		row2 = _str.cleanEnd(row2,'\t')
		row2 = _str.cleanEnd(row2,' ')

		if len(row2) > maxLen2:
			maxLen2 = len(row2)
	return row

def vcrypyB(file):
	global indexP
	global isMD
	# _.pr(505,type(file))
	# return file
	result = 'str'
	if type(file) == list:
		result = 'list'
		file = '\n'.join(file)

	if '!V!' in file:
		has = True
	else:
		has = False
	done = True

	if isMD and indexP:
		done = False
	elif has:
		done = False
	else:
		done = True

	if not done:
		file = file.split('\n')
		if isMD and indexP:
			spent=[]
			for oOo in indexP:
				if not oOo in spent:
					spent.append(oOo)

					try:
						file[oOo] = '~~~'+indexP[oOo]
					except Exception as e:
						pass
						# _.pr(329,oOo,len(file),oOo in indexP,'error: indexP[oOo]')

	if not done:
		if has:
			for i,row in enumerate(file):
				if '!V!' in row:
					row = file[i]
					row = row.replace('!V!','')
					row = _str.cleanEnd(row,'\t')
					row = _str.cleanEnd(row,' ')
					row = row + addSpaces2(row) + '!V!'
					file[i] = row
					# _.pr(404,row)
	if __.fn.saveText:
		_.pr('vcrypyB',result,)
	return file
	if result == 'list':
		return file
	else:
		return '\n'.join(file)

def process(row):
	row = _str.cleanEnd(row,' ')
	row = _str.replaceAll(row, '  !V!',' !V!')
	# if '!V!' in row:
	#   return row
	global records
	global maxLen
	if identify(row):
		try:
			row2 = _vault.imp.s.de( row )
			good = True
			if '\n' in row2:
				good = False
			for ch in row2:
				if ch not in _str.printable2:
					good = False
			if good:
				records[row] = row2
				if not row2.startswith('todo:'):
					if len(row2) > maxLen:
						maxLen = len(row2)
				# row = row2
		except Exception as e:
			pass
		# if row.startswith('!VAULT!'):
		#   _.pr( row )

	return row

def addSpaces(row):
	global maxLen
	y = maxLen - len(row) + 5
	i=0
	t = ''
	while not i == y:
		i+=1
		t+=' '
	return t

def addSpaces2(row):
	global maxLen2
	y = maxLen2 - len(row) + 5
	i=0
	t = ''
	while not i == y:
		i+=1
		t+=' '
	return t
indexP = {}
def md_clean(theFILE):
	# focus()
	global indexP
	done = False
	while not done:
		theFILE = _str.replaceAll(theFILE,' \n','\n')
		theFILE = _str.replaceAll(theFILE,'----','---')
		theFILE = _str.replaceAll(theFILE,'____','___')
		theFILE = _str.replaceAll(theFILE,'* * * *','* * *')
		theFILE = _str.replaceAll(theFILE,'****','***')
		theFILE = _str.replaceAll(theFILE,'~~~~','~~~')
		theFILE = _str.replaceAll(theFILE,'````','```')

		done = True
		for xXx in ['____','----','* * * *','****','````','~~~~']:
			if xXx in theFILE:
				done = False
		if done:
			while '---' in theFILE:
				theFILE = theFILE.replace( '---', '___' )
			while '* * *' in theFILE:
				theFILE = theFILE.replace( '* * *', '___' )
			while '***' in theFILE:
				theFILE = theFILE.replace( '***', '___' )
			while '```' in theFILE:
				theFILE = theFILE.replace( '```', '~~~' )
	file = theFILE.split('\n')
	spent = []
	for i,row in enumerate(file):
		if '!V!' in row:
			vcrypyA(row)
		if '~~~' in row and len(row) > len('~~~'):
			if not i in spent:
				spent.append(i)
				indexP[i] = row.split('~~~')[1]
			file[i] = '~~~'
	theFILE = '\n'.join(file)

	return theFILE
r = 0
def process_doc_sep(theFILE,doc_sep,doc_seps):
	global isMD
	global r
	r+=1
	segments=[]
	if type(theFILE) == list:
		theFILE = '\n'.join(theFILE)
	preFile = '\n'+doc_sep+'\n#testing\n\n'
	theFILE = preFile + theFILE
	for segment in theFILE.split(doc_sep):
		s0 = segment.split('\n')[0].lower()
		try:
			s1 = segment.split('\n')[1].lower()
		except Exception as e:
			s1 = ''
		choice=1
		for dsep in doc_seps:
			if s0 in dsep:
				choice=0
		if '#crypt' in s0.lower():
			choice=1

		file = []
		fileBK = []
		for i,row in enumerate( segment.replace('!vault!','!V!').replace('!VAULT!','!V!').replace('!v!','!V!').replace('!crypt!','!V!').replace('!CRYPT!','!V!').split('\n') ):
			fileBK.append(row)
			row = process(row)
			file.append(row)
		nFile = []
		for i,row in enumerate(file):
			inRec = False
			test = 999
			if row in records:
				inRec = True
				# _.pr(0,s0)
				# _.pr(1,s1)
				# sys.exit()
				# if '#crypt' in segment:
				test = 111
				original = row

				if '#crypt' in s1 or '#crypt' in s0:
					# _.pr("if '#crypt' in segment:")
					row = records[row]
					test = 222

				else:
					# _.pr("if NOT '#crypt' in segment:")
					if records[row].startswith('todo:'):
						test = 333
						done=False
						for test in ['ai','todo']:
							# _.pr(test)
							if not done:
								if test+': ' in records[row]:
									done=True
									# _.pr(test+': !V!')
									# sys.exit()
									row = records[row].replace( test+': ', test+':  !V!  ' )
								elif test+':x' in records[row]:
									done=True
									row = records[row].replace( test+':x', test+':x !V!  ' )
								elif test+':y' in records[row]:
									done=True
									row = records[row].replace( test+':y', test+':y !V!  ' )
								elif test+':z' in records[row]:
									done=True
									row = records[row].replace( test+':z', test+':z !V!  ' )

						if not done:
							done=True
							# row = records[row] + addSpaces(records[row]) + '!V!'
							row = _str.cleanEnd(records[row],' ') + addSpaces(records[row]) + '!V!'
						row=row.replace('!V!   ','!V!  ')
						row=row.replace('!V!   ','!V!  ')
						row=row.replace('   !V!','  !V!')
						row=row.replace('   !V!','  !V!')
						row=vcrypyA(row)
						test = 444
					elif choice:
						test = 555
						row = records[row] + addSpaces(records[row]) + '!V!'
						row=vcrypyA(row)
						# row = records[row]

			# _.pr(test,row)
			# if s0 in doc_sep:
			if choice and inRec:
				if row in records:
					row = records[row]
			if test == 111 or test == 999 or not choice:
				row = fileBK[i]
			vVv = 0
			if ( vVv and 'password' in row ) or ( vVv and '2022-02-04T22:30:00-0500' in row ) or ( vVv and '45.35.203.103' in row ) or ( vVv and 'DNX8ZsjuI1DWelkKipcBZL3j0IB6afSVlAnjXCssy2yIIsn7J9O3Aw==' in row ) or ( vVv and '3Yakcawoid5hXCFWnaYIhgkv5wl5BkdjSAJja5Vifyw=' in row ):
				_.cp(_.linePrint(p=0),'yellow')
				_.pr( s0 )
				_.pr( s1 )
				_.pr(r,choice,test,row,inRec)
			nFile.append(row)
		segments.append('\n'.join(nFile))

	data = doc_sep.join(segments)
	data = data[len(preFile):]
	data = vcrypyB(data)
	return data

deleteSpent = {}

def run(path):

	table = _.getTable('crypt-docs.list')
	if _.switches.isActive('Delete'):
		path=__.path(path)

		found=False
		new=[]
		for fi in table:
			if not fi == path: new.append(fi)
			else: found=True

		if found:
			global deleteSpent
			if not path in deleteSpent:
				deleteSpent[path]=1
				appReg=__.appReg
				_bk=_.regImp( __.appReg, 'fileBackup' ); _bk.switch( 'isPreOpen' ); _bk.switch( 'Silent' );
				_bk.switch( 'Input', path ); bkfi = _bk.action();
				__.appReg=appReg
				# decrypt(path)
				_.cp('decrypted and removed from decrypt-docs database','yellow')
				_.saveTable(new,'crypt-docs.list',p=0)
		__.isExit()
		return None
	if _.switches.isActive('Delete'): return None
	if _.switches.isActive('Delete'): return None

	appReg=__.appReg
	_secureFiles=_.regImp( __.appReg, 'secureFiles' )
	__.appReg=appReg
	_secureFiles.switch( 'Delete' )
	_secureFiles.switch( 'Files', path )
	_secureFiles.action()
	__.appReg=appReg

	global isMD
	if path.lower().endswith('.md'):
		isMD = True
	else:
		isMD = False
	global records
	global maxLen
	global doc_sep
	global indexP
	indexP = {}
	table = _.getTable('crypt-docs.list')
	test=table.copy()
	if not __.path(path) in table:
		table.append( __.path(path) )
	# _.pv( table )
	newTable = []
	for ntf in table:
		if not ntf in newTable:
			newTable.append(ntf)
	table = newTable
	if not str(table)==str(test):
		_.saveTable( table, 'crypt-docs.list', p=0 )
		_.cp('added to secure docs database','yellow')
	else:
		pass
		_.cp('in secure docs database','yellow')
	theFILE = _.getText( path,raw=True )
	if theFILE.startswith(doc_sep.replace('\n','')):
		theFILE='\n'+theFILE

	doc_seps = [
					'\n__________________________________________________________________________________\n',
					'\n___\n',
					'\n~~~\n',
				]

	doc_sep  = doc_seps[0]
	if path.lower().endswith('.md'):
		theFILE = md_clean(theFILE)
		# if theFILE.startswith('\n'):
		#     _.saveText(theFILE[1:],path)
		# else:
		#     _.saveText(theFILE,path)
		theFILE = process_doc_sep(theFILE, doc_seps[2],doc_seps)
		theFILE = process_doc_sep(theFILE, doc_seps[1],doc_seps)

	else:
		theFILE = process_doc_sep(theFILE, doc_sep,[doc_sep])
		theFILE = _str.cleanFirst(theFILE,'\n')

	_.saveText( theFILE, path )

def action():

	if not _.switches.values('Files'):
		_.e('please specify a file')

	if _.switches.isActive('Test'):
		row = ' '.join( _.switches.values('Test') )
		row = process(row)
		return None

	for path in _.switches.values('Files'):
		run(path)

doc_sep = '\n__________________________________________________________________________________\n'

# import _rightThumb._vault as _vault

_vault = _.regImp( __.appReg, '_rightThumb._vault' )
focus()

isMD = True

# run(
# vcrypyA
# vcrypyB
# process_doc_sep
# _.pr(329,oOo,len(file),oOo in indexP,'error: indexP[oOo]')

########################################################################################
if __name__ == '__main__':
	action()
	__.isExit()


# -*- coding: utf-8 -*-
from __future__ import unicode_literals, absolute_import

from django.core.management.base import BaseCommand, CommandError

from kchart.charts.chartservice import CHART_SERVICES
from kchart.charts.models import AggregateHourlySongChart

class Command(BaseCommand):

    help = 'Updates the specified chart'

    def add_arguments(self, parser):
        super(Command, self).add_arguments(parser)
        parser.add_argument('--dry-run', dest='dry_run', action='store_true',
                            help='Do not write chart updates to the database')
        parser.add_argument('--aggregate', dest='aggregate', action='store_true',
                            help='(Re)generate aggregated chart after update')
        parser.add_argument('chart', nargs='*')

    def handle(self, *args, **options):
        for chart in options['chart']:
            if chart not in CHART_SERVICES:
                raise CommandError('Unknown chart: {}'.format(chart))
            service = CHART_SERVICES[chart.lower()]()
            service.fetch_hourly(dry_run=options['dry_run'])
        if options['aggregate']:
            AggregateHourlySongChart.generate(regenerate=True)