from linkedin_utils import *
import pandas as pd
import numpy as np

Industries = ['Airlines and Aviation',
              'Appliances,Electrical and Electronics Manufacturing',
              'Chemical Manufacturing',
              'Computers and Electronics Manufacturing',
              'Food and Beverage Manufacturing',
              'Transportation, Logistics, Supply Chain and Storage']

position = "HR"

def search_profiles(position,location,Indutry,title_keyword):
    # try:
    driver.find_element(By.CSS_SELECTOR,"input[placeholder='Search']").click()
    time.sleep(3)
    driver.find_element(By.CSS_SELECTOR,"input[placeholder='Search']").send_keys(position)
    time.sleep(4.5)
    driver.find_element(By.CSS_SELECTOR,"input[placeholder='Search']").send_keys(Keys.ENTER)
    time.sleep(6)

    scroll_to_half()
    scroll_to_bottom()
    scroll_to_top()

    time.sleep(5)

    try:
        wait_and_click(By.XPATH, "//ul[contains(@class,'filter-list')]/li//button[contains(.,'People')]")   # select people tab
    except:
        page_not_found()

    time.sleep(4)

    wait_and_click(By.XPATH, "//ul[contains(@class,'filter-list')]/li//button[contains(.,'Locations')]")  # select location tab
    time.sleep(3)

    driver.find_element(By.XPATH, "//ul[contains(@class,'filter-list')]/li//input[contains(@placeholder,'location')]").send_keys(location)   # send location name
    time.sleep(2)

    wait_and_click(By.CSS_SELECTOR, "div[role='listbox'] div[role='option']:first-child")    # select 1st suggestion
    time.sleep(3)

    wait_and_click(By.XPATH, "//ul[contains(@class,'filter-list')]/li//div[contains(@id,'locations-filter')]//button[contains(.,'Show results')]")   # select show results
    time.sleep(5)

    wait_and_click(By.CSS_SELECTOR,"button[class*='all-filters']")
    time.sleep(1)

    wait_and_click(By.XPATH,"//button[contains(.,'Add an industry')]")
    time.sleep(2)
    wait_for_element_to_load(By.XPATH,"(//input[@placeholder='Add an industry'])[1]").send_keys(Indutry)
    time.sleep(1)
    wait_and_click(By.CSS_SELECTOR, "div[role='listbox'] div[role='option']:first-child")
    time.sleep(1)
    wait_for_element_to_load(By.XPATH,"(//label[contains(.,'Title')])[1]//input").send_keys(title_keyword)
    time.sleep(1)
    wait_and_click(By.XPATH,"//ul[contains(@class,'filter-list')]/li//div[contains(@id,'locations-filter')]//button[contains(.,'Show results')]")
    time.sleep(3)

    return 0

def scrape_profiles(filename):
    column = ['linkedin_url']
    profiles = []
    try:
        while True:
            try:

            # all_results = driver.find_elements(By.XPATH, "//ul[contains(@class,'result-list')]/li[@class]//div[contains(@class,'result__item')]")
                all_results = wait_for_elements_to_load(By.XPATH, "//ul[contains(@class,'result-list')]/li[@class]//div[contains(@class,'result__item')]")
            except Exception as e:
                print(e)
                while True:
                    pass

            print("-> filtering profiles")
            for result in all_results:
                try:
                    active_profile = result.find_element(By.XPATH, "./div[2]//a[not(contains(.,'LinkedIn Member'))]")
                except:
                    active_profile = None

                if active_profile:
                    profile_url = result.find_element(By.XPATH, "./div[2]//a").get_attribute("href")
                    profiles.append({'linkedin_url':profile_url})
            try:
                scroll_to_bottom()
                time.sleep(1)
                next_btn = driver.find_element(By.XPATH,"//button[@aria-label='Next']")
                if next_btn.is_enabled():
                    next_btn.click()
                    time.sleep(2)
                else:
                    break

            except Exception as e:
                print(e)
                pass
        df = pd.DataFrame(profiles,columns=column)
        df.to_csv(filename,index=False)
        return 0
    except Exception as e:
        print(e)
        return 1

    keep_open()
def keep_open():
    while True:
        pass

def scrape_profiles_info(csv,industry,start,stop):
    columns = ['first_name', 'last_name', 'linkedin_url', 'email','linkedin_headline', 'city', 'state', 'country', 'location_text','position_title', 'company', 'location', 'company_linkedin_url','industry']
    data = []
    df1 = pd.read_csv(csv)

    profiles = df1.loc[start:stop,'linkedin_url']
    # try:
    for profile in profiles:
        try:
            driver.get(profile)
            print(f'=> scraping {profile}')
            time.sleep(3)
            scroll_to_bottom()
            scroll_to_half()
            scroll_to_top()
            time.sleep(3)
            first_name, last_name, linkedin_headline, city, state, country, location_text,email = get_profile_info()
            position_title, company, location, company_linkedin_url = get_experience()
            row = {'first_name' : first_name, 'last_name' : last_name, 'linkedin_url' : profile  , 'email': email, 'linkedin_headline' : linkedin_headline, 'city' : city, 'state' : state, 'country' : country, 'location_text' : location_text,'position_title' : position_title, 'company' : company , 'location' : location, 'company_linkedin_url' : company_linkedin_url, 'industry': industry}
            data.append(row)
        except:
            pass
    df = pd.DataFrame(data,columns=columns)
    df.to_csv('Scraped_profiles_206.csv',index=False)
    return 0
    # except Exception as e:
    #     print(e)
    #     pass

def scrape_comp_profiles_info(csv,industry,start,stop):
    columns = ['first_name', 'last_name', 'linkedin_url', 'email','linkedin_headline', 'city', 'state', 'country', 'location_text','position_title', 'company', 'location', 'company_linkedin_url','industry']
    data = []
    df1 = pd.read_csv(csv)

    profiles = df1.loc[start:stop,'linkedin_url']
    # try:
    for profile in profiles:
        try:
            driver.get(profile)
            print(f'=> scraping {profile}')
            time.sleep(3)
            scroll_to_bottom()
            scroll_to_half()
            scroll_to_top()
            time.sleep(3)
            try:
                wait_and_click(By.XPATH,"//a[contains(@id,'certifications')]")
            except:
                pass
            time.sleep(3)
            comp_urls = wait_for_elements_to_load(By.XPATH,"//section[contains(.,'Licenses & certifications')]//ul[contains(@class,'pvs-list')]//li//a")
            certified = False
            print(comp_urls)
            for i in comp_urls:
                print(i.get_attribute("href"))
                if i.get_attribute("href") == "https://www.linkedin.com/company/6047514/":
                    print('in')
                    certified = True
            time.sleep(3)
            try:
                wait_and_click(By.XPATH,"//button[contains(@aria-label,'Back')]")
            except:
                pass
            time.sleep(3)

            if certified == True:

                print('in2')
                first_name, last_name, linkedin_headline, city, state, country, location_text,email = get_profile_info()
                position_title, company, location, company_linkedin_url = get_experience()
                row = {'first_name' : first_name, 'last_name' : last_name, 'linkedin_url' : profile  , 'email': email, 'linkedin_headline' : linkedin_headline, 'city' : city, 'state' : state, 'country' : country, 'location_text' : location_text,'position_title' : position_title, 'company' : company , 'location' : location, 'company_linkedin_url' : company_linkedin_url, 'industry': industry}
                data.append(row)
                print(row)
        except:
            pass
    print('creating_csv')
    print(data)
    df = pd.DataFrame(data,columns=columns)
    df.to_csv('Scraped_profiles_comp.csv',index=False)
    return 0
    # except Ex

# search_profiles(position,'United kingdom',Industries[5],'Training')
# scrape_profiles('scraped_url_205.csv')
# scrape_comp_profiles_info('scraped_urls_404_PE.csv','all',2,3)


# 若想组合 Palindrome回文，每个字母都要偶数，最多只能1个奇数
class Solution:
    def canPermutePalindrome(self, s: str) -> bool:
        d = defaultdict(int) # 用字典来统计，值预设整数0
        for c in s: # 每个字母
            d[c] += 1 # 对应的次数+1
        odd = 0 # 有几个字母出现奇数?
        for c in d: # 针对字典里每个字母的出现次数分析
            if d[c]%2==1: odd += 1 # 这个字母出现次数“奇数”
        if odd<=1: return True # 不超过1个奇数，可！
        else: return False


#!/usr/bin/env python

import socket
import time
import asyncio

async def send_n_recv_data(question):
    ip = '127.0.0.1'
    tcp_port = 5005

    sockfd = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sockfd.connect((ip, tcp_port))
    sockfd.send(question.encode())
    data = sockfd.recv(1024)
    await asyncio.sleep(1)
    sockfd.close()

    return(data)

async def get_answer_by_question(question):
    print(f"Quesion: {question}")
    reply = send_n_recv_data(question)
	#await asyncio.sleep(1)
    print(f"Asnwer : {reply}")
    print()

async def main():
    task1 = loop.create_taskget_answer_by_question("One-page question")
    #await asyncio.sleep(1)
    task2 = loop.create_taskget_answer_by_question("One-line question")
    task3 = loop.create_taskget_answer_by_question("Booleon question")

    await asyncio.wait([task1, task2, task3])
    return task1, task2, task3

if (__name__ == "__main__"):
    print(f"started at {time.strftime('%X')}")
    try:
        loop = asyncio.get_event_loop()
        r1, r2, r3 = loop.run_until_complete(main())
        print(f"{r1.result()}")
        print(f"{r2.result()}")
        print(f"{r3.result()}")
    except Exception as e:
        pass
    finally:
        loop.close()
    print(f"Ended at {time.strftime('%X')}")


from class_resources import *
from class_building import *

class Recipe():
    ALL_RECIPES = []

    def __init__(self, unlocked_resource, required_resources):
        self.unlocked_resource = unlocked_resource
        self.name = unlocked_resource.name
        self.required_resources = required_resources
        self.unlocked = False
        Recipe.ALL_RECIPES.append(self)

    def check_requirements(self):
        if not self.unlocked:
            count = 0
            for resource in self.required_resources:
                if self.required_resources[resource] <= resource.get():
                    count += 1
                    if resource.label is not None:
                        resource.label.config(fg="dark green")
                    print(f"I've got enough {resource.name} ({resource.get()}/{self.required_resources[resource]})")
                else:
                    # resource.color_var.set("red")
                    if resource.label is not None:
                        resource.label.config(fg="red")
                    # resource.label.config(bg="black").pack()
                    print(f"Not enough {resource.name} ({resource.get()}/ {self.required_resources[resource]})")
            if count >= len(self.required_resources):
                print(f"UNLOCKED {self.name}")
                self.unlocked = True
                return True

wood_unlock = Recipe(Lumberjack_Hut, {Food: 10})
stone_unlock = Recipe(Stonemason, {Food: 10, Wood: 20})
water_unlock = Recipe(Water_Well, {Food: 100, Wood: 20, Stone: 50})
wheat_unlock = Recipe(Farm, {Food: 10, Wood: 50, Stone: 25, Water: 20})
bread_unlock = Recipe(Bakery, {Food: 5, Wood: 5, Water: 10, Wheat: 15})
hunters_cabin_unlock = Recipe(Hunters_Cabin, {Food: 10, Wood: 20, Stone: 5})


import enum
import json
from typing import Dict

import discord

class DiscordEvent(enum.Enum):
    MESSAGE = "message"
    MENTION = "mention"
    USER_STATUS = "user_status"
    USER_TYPING = "user_typing"

# Create a new client object
intents = discord.Intents.all()
client = discord.Client(intents=intents)

# function to log event and data
def log_event(event: DiscordEvent, data: Dict):
    print(f"Event: {event.value}, Data: {json.dumps(data)}")

# Use the on_ready() event to know when the bot is connected and authenticated
@client.event
async def on_ready():
    log_event(DiscordEvent.USER_STATUS, {"status": "authenticated"})

# Use the on_message() event to listen for new messages
@client.event
async def on_message(message):
    log_event(DiscordEvent.MESSAGE, {"content": message.content})

# Use the on_member_update() event to listen for user status message changes
@client.event
async def on_member_update(before, after):
    if before.status != after.status:
        log_event(
            DiscordEvent.USER_STATUS,
            {"username": after.name, "before": before.status, "after": after.status},
        )

# Use the on_mention() event to listen for new mentions
@client.event
async def on_message(message):
    if message.mention_everyone or message.mentions:
        log_event(DiscordEvent.MENTION, {"content": message.content})

# Listen for when a user starts typing
@client.event
async def on_typing(channel, user, when):
    log_event(
        DiscordEvent.USER_TYPING,
        {"channel": channel.name, "user": user.name, "when": when},
    )

# Authenticate with Discord using your token
client.run("<your bot token>")


def first_perfect_square(lst):
    l = list(enumerate(lst))
    if l == [] or l[0][1] < 0:
        return -1
    else:
        temp = int(l[0][1]**0.5)
        if temp**2 == l[0][1]:
            return l[0][0]
        else:
            return first_perfect_square(lst[1:])

def first_perfect_square(numbers):
    for i in range(0, len(numbers)):
        if numbers[i] >= 0:
            if numbers[i]**0.5 - int(numbers[i]**0.5) == 0:
                return i
    return -1

def num_perfect_square(numbers):
    cnt=0
    for i in range(0, len(numbers)):
        if numbers[i] >= 0:
            if numbers[i]**0.5 - int(numbers[i]**0.5) == 0:
                cnt += 1
    return cnt

def second_largest(values):
    max=values[0]
    smax=values[0]
    for val in values:
        if val > max:
            smax = max
            max = val
        elif val > smax:
            smax = val

    return smax


from os import listdir
from easygui import diropenbox
import tweet_tk.tweets_to_df as tweets_to_df
from pandas import DataFrame
from time import strftime
from pickle import dump

# open path containing all jsion files
path = diropenbox()
datasets = [f for f in listdir(path) if f.split('.')[1] == 'json']
agg_dataset = DataFrame()

# load all jsons into agg_dataset
for f in datasets:
    curr_path = path+'\\'+f
    print(curr_path)
    df = tweets_to_df.tweet_json_to_df(curr_path)
    print('loaded',f,'size:',len(df))
    agg_dataset = agg_dataset.append(df)

print('\ndone aggregating. total size:',len(agg_dataset))

# drop aggregated dataset into pickle
agg_file_name = path+'/agg_' + strftime("%Y_%m_%d_%H_%M_%S") + '.pickle'

save_file = open(agg_file_name,'wb')
dump(agg_dataset,save_file)
save_file.close()
# agg_dataset


import os
import sys
import hashlib

truclientbrowser_root = r'E:\Shared\Firefox58-truclientbrowser-release'

def is_same_file(path0, path1):
	if os.path.isfile(path0) and os.path.isfile(path1):
		s0 = os.stat(path0)
		s1 = os.stat(path1)
		if s0.st_size == s1.st_size:
			m0 = hashlib.md5()
			m1 = hashlib.md5()
			m0.update(open(path0, 'rb').read())
			md5_0 = m0.digest()
			m1.update(open(path1, 'rb').read())
			md5_1 = m1.digest()
			return md5_0 == md5_1
	return False

def total_file_size(root, files):
	'''
	size is in mb
	'''
	size = 0
	for f in files:
		f = os.path.join(root, f)
		if os.path.isfile(f):
			size += os.stat(f).st_size
	return size / (1024 * 1024)

def get_all_files(path):
	all_files = []
	for root, dirs, files in os.walk(path):
		for f in files:
			file_path = os.path.join(root, f)
			all_files.append(file_path)
	return all_files

def convert2file2copy_lines(root, file_pathes):
	lines = []
	for file_path in file_pathes:
		relative_path = file_path.replace(root, '')
		relative_path = relative_path if relative_path[0] == '\\' else '\\' + relative_path
		lines.append('<FileRelativePathTARGETDIR Include="bin\\TruClientBrowser%s" />\n' % relative_path)
	return lines

def filter_difference(tcb_path0, tcb_path1):
	'''
	if only specify one path then list all the files
	if specify two pathes then filter out the different files between the two
	folders base on the first path
	'''
	files0 = [f[1:] if f[0] == '\\' else f for f in [f.replace(tcb_path0, '') for f in get_all_files(tcb_path0)]]
	files1 = [f[1:] if f[0] == '\\' else f for f in [f.replace(tcb_path1, '') for f in get_all_files(tcb_path1)]]

	same_files, diff_files = [], []
	files1 = set(files1)
	while files0:
		f = files0.pop()
		if f in files1:
			file0 = os.path.join(tcb_path0, f)
			file1 = os.path.join(tcb_path1, f)
			if is_same_file(file0, file1):
				same_files.append(f)
			else:
				diff_files.append(f)
	return same_files, diff_files

def save_tcb2file2copy(path):
	files = get_all_files(path)
	lines = convert2file2copy_lines(path, files)
	open('f:/files2copy.txt', 'w').writelines(lines)

if __name__ == '__main__':
	arg_length = len(sys.argv)
	if arg_length == 1:
		save_tcb2file2copy(truclientbrowser_root)
	elif arg_length == 3:
		path0, path1 = sys.argv[1], sys.argv[2]
		same_files, diff_files = filter_difference(path0, path1)
		lines = convert2file2copy_lines(path0, diff_files)
		lines.append('total file size %.2fMB' % total_file_size(path0, diff_files))
		open('f:/diff_files2copy.txt', 'w').writelines(lines)
		lines = convert2file2copy_lines(path0, same_files)
		lines.append('total file size %.2fMB' % total_file_size(path0, same_files))
		open('f:/same_files2copy.txt', 'w').writelines(lines)
	else:
		print('Incorrect argument numbers, recieve no or 2 path arguments to TruClientBrowser root')


def make_graph(costs):
    graph = {}
    for node_i, node_j, _ in costs:
        registered_nodes = graph.keys()
        if node_i not in registered_nodes:
            graph[node_i] = [node_j]
        else:
            graph[node_i].append(node_j)
        if node_j not in registered_nodes:
            graph[node_j] = [node_i]
        else:
            graph[node_j].append(node_i)
    return graph

def bfs(node, graph, n):
    visited = [False] * n
    visited[node] = True
    queue = graph[node]
    while len(queue) > 0:
        next_node = queue.pop(0)
        visited[next_node] = True
        queue += [neighbor for neighbor in graph[next_node]
                  if not visited[neighbor] and neighbor not in queue]
    return visited

def solution(n, costs):
    costs.sort(key=lambda x: x[2])
    real_costs = []
    visited = [False] * n
    while not all(visited):
        real_costs.append(costs.pop(0))
        graph = make_graph(real_costs)
        visited = bfs(list(graph.keys())[0], graph, n)
    answer = sum([cost[2] for cost in real_costs])
    return answer


# 2 EXERCISE
# TUPLES AND SETS

# Write a program that reads a text from the console and counts the occurrences of each character in it. Print the
# results in alphabetical (lexicographical) order.

text = input()
count_dict = {}

text_tuple = tuple([v for v in text])

for a_letter in text_tuple:
    number = text_tuple.count(a_letter)
    if not a_letter in count_dict:
        count_dict[a_letter] = number

for key in sorted(count_dict):
    print(f"{key}: {count_dict[key]} time/s")

# example
# SoftUni rocks


import argparse
import datetime
import json
import os
import time
import tqdm

import numpy as np
import pandas as pd
import sklearn.metrics as sm

import torch
import torch.nn as nn
from torch.utils.data import DataLoader

from atom3d.datasets import LMDBDataset
from scipy.stats import spearmanr

from model import CNN3D_PPI
from data import CNN3D_Dataset

def major_vote(results):
    data = []
    for ensemble, df in results.groupby('id'):
        true = int(df['true'].unique()[0])
        num_zeros = np.sum(df['pred'] == 0)
        num_ones = np.sum(df['pred'] == 1)
        majority_pred = int(df['pred'].mode().values[0])
        avg_prob = df['prob'].astype(np.float).mean()
        data.append([ensemble, true, majority_pred, avg_prob, num_zeros, num_ones])
    vote_df = pd.DataFrame(data, columns=['id', 'true', 'pred', 'avg_prob',
                                          'num_pred_zeros', 'num_pred_ones'])
    return vote_df

def compute_stats(df):
    results = major_vote(df)
    res = {}
    all_true = results['true'].astype(np.int8)
    all_pred = results['pred'].astype(np.int8)
    res['auroc'] = sm.roc_auc_score(all_true, all_pred)
    res['auprc'] = sm.average_precision_score(all_true, all_pred)
    res['acc'] = sm.accuracy_score(all_true, all_pred.round())
    res['bal_acc'] = \
        sm.balanced_accuracy_score(all_true, all_pred.round())
    return res

# Construct model
def conv_model(in_channels, spatial_size, args):
    num_conv = args.num_conv
    conv_filters = [32 * (2**n) for n in range(num_conv)]
    conv_kernel_size = 3
    max_pool_positions = [0, 1]*int((num_conv+1)/2)
    max_pool_sizes = [2]*num_conv
    max_pool_strides = [2]*num_conv
    fc_units = [512]
    top_fc_units = [512]*args.num_final_fc_layers

    model = CNN3D_PPI(
        in_channels, spatial_size,
        args.conv_drop_rate,
        args.fc_drop_rate,
        args.top_nn_drop_rate,
        conv_filters, conv_kernel_size,
        max_pool_positions,
        max_pool_sizes, max_pool_strides,
        fc_units,
        top_fc_units,
        batch_norm=args.batch_norm,
        dropout=not args.no_dropout)
    return model

def train_loop(model, loader, criterion, optimizer, device):
    model.train()

    loss_all = 0
    total = 0
    progress_format = 'train loss: {:6.6f}'
    with tqdm.tqdm(total=len(loader), desc=progress_format.format(0)) as t:
        for i, data in enumerate(loader):
            feature_left = data['feature_left'].to(device).to(torch.float32)
            feature_right = data['feature_right'].to(device).to(torch.float32)
            labels = data['label'].to(device).to(torch.float32)
            # zero the parameter gradients
            optimizer.zero_grad()
            # forward + backward + optimize
            output = model(feature_left, feature_right)
            loss = criterion(output, labels)
            loss.backward()
            loss_all += loss.item() * len(labels)
            total += len(labels)
            optimizer.step()
            # stats
            t.set_description(progress_format.format(np.sqrt(loss_all/total)))
            t.update(1)

    return np.sqrt(loss_all / total)

@torch.no_grad()
def test(model, loader, criterion, device):
    model.eval()

    loss_all = 0
    total = 0

    ids = []
    y_true = []
    y_probs = []
    y_pred = []

    for data in loader:
        feature_left = data['feature_left'].to(device).to(torch.float32)
        feature_right = data['feature_right'].to(device).to(torch.float32)
        labels = data['label'].to(device).to(torch.float32)
        output = model(feature_left, feature_right)

        loss = criterion(output, labels)
        loss_all += loss.item() * len(labels)
        total += len(labels)

        ids.extend(data['id'])
        y_true.extend(labels.int().tolist())
        y_probs.extend(output.tolist())

        preds = torch.round(output).int()
        y_pred.extend(preds.tolist())

    results_df = pd.DataFrame(
        np.array([ids, y_true, y_probs, y_pred]).T,
        columns=['id', 'true', 'prob', 'pred'],
        )

    stats = compute_stats(results_df)
    return np.sqrt(loss_all / total), stats, results_df

def save_weights(model, weight_dir):
    torch.save(model.state_dict(), weight_dir)

def train(args, device, test_mode=False):
    print("Training model with config:")
    print(str(json.dumps(args.__dict__, indent=4)) + "\n")

    # Save config
    with open(os.path.join(args.output_dir, 'config.json'), 'w') as f:
        json.dump(args.__dict__, f, indent=4)

    np.random.seed(args.random_seed)
    torch.manual_seed(args.random_seed)

    train_dataset = CNN3D_Dataset(
        os.path.join(args.data_dir, 'train'),
        testing=False,
        random_seed=args.random_seed,
        )
    val_dataset = CNN3D_Dataset(
        os.path.join(args.data_dir, 'val'),
        testing=False,
        random_seed=args.random_seed,
        )
    test_dataset = CNN3D_Dataset(
        os.path.join(args.data_dir, 'test'),
        testing=True,
        random_seed=args.random_seed,
        )

    train_loader = DataLoader(train_dataset, args.batch_size)
    val_loader = DataLoader(val_dataset, args.batch_size)
    test_loader = DataLoader(test_dataset, args.batch_size)

    for data in train_loader:
        in_channels, spatial_size = data['feature_left'].size()[1:3]
        print('num channels: {:}, spatial size: {:}'.format(in_channels, spatial_size))
        break

    model = conv_model(in_channels, spatial_size, args)
    print(model)
    model.to(device)

    prev_val_loss = np.Inf
    best_val_loss = np.Inf
    best_val_auroc = 0
    best_stats = None

    criterion = nn.BCELoss()
    criterion.to(device)
    optimizer = torch.optim.Adam(model.parameters(), lr=args.learning_rate)

    for epoch in range(1, args.num_epochs+1):
        start = time.time()
        train_loss = train_loop(model, train_loader, criterion, optimizer, device)
        val_loss, stats, val_df = test(model, val_loader, criterion, device)
        elapsed = (time.time() - start)
        print(f'Epoch {epoch:03d} finished in : {elapsed:.3f} s')
        print(f"\tTrain loss {train_loss:.4f}, Val loss: {val_loss:.4f}, "
              f"Val AUROC: {stats['auroc']:.4f}, Val AUPRC: {stats['auroc']:.4f}")
        #if stats['auroc'] > best_val_auroc:
        if val_loss < best_val_loss:
            print(f"\nSave model at epoch {epoch:03d}, val_loss: {val_loss:.4f}, "
                  f"auroc: {stats['auroc']:.4f}, auprc: {stats['auroc']:.4f}")
            save_weights(model, os.path.join(args.output_dir, f'best_weights.pt'))
            best_val_loss = val_loss
            best_val_auroc = stats['auroc']
            best_stats = stats
        if args.early_stopping and val_loss >= prev_val_loss:
            print(f"Validation loss stopped decreasing, stopping at epoch {epoch:03d}...")
            break
        prev_val_loss = val_loss

    if test_mode:
        model.load_state_dict(torch.load(os.path.join(args.output_dir, f'best_weights.pt')))
        test_loss, stats, test_df = test(model, test_loader, criterion, device)
        test_df.to_pickle(os.path.join(args.output_dir, 'test_results.pkl'))
        print(f"Test loss: {test_loss:.4f}, Test AUROC: {stats['auroc']:.4f}, "
              f"Test AUPRC: {stats['auprc']:.4f}")
        test_file = os.path.join(args.output_dir, f'test_results.txt')
        with open(test_file, 'w') as f:
            f.write(f"test_loss\tAUROC\tAUPRC\n")
            f.write(f"{test_loss:}\t{stats['auroc']:}\t{stats['auprc']:}\n")

if __name__=="__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument('--data_dir', type=str, default=os.environ['PPI_DATA'])
    parser.add_argument('--mode', type=str, default='test',
                        choices=['train', 'test'])
    parser.add_argument('--output_dir', type=str, default=os.environ['LOG_DIR'])
    parser.add_argument('--unobserved', action='store_true', default=False)

    parser.add_argument('--learning_rate', type=float, default=0.00001)
    parser.add_argument('--conv_drop_rate', type=float, default=0.1)
    parser.add_argument('--fc_drop_rate', type=float, default=0.25)
    parser.add_argument('--top_nn_drop_rate', type=float, default=0.25)
    parser.add_argument('--num_epochs', type=int, default=30)

    parser.add_argument('--num_conv', type=int, default=4)
    parser.add_argument('--num_final_fc_layers', type=int, default=2)
    parser.add_argument('--batch_norm', action='store_true', default=False)
    parser.add_argument('--no_dropout', action='store_true', default=False)

    parser.add_argument('--batch_size', type=int, default=16)
    parser.add_argument('--early_stopping', action='store_true', default=False)
    parser.add_argument('--random_seed', type=int, default=int(np.random.randint(1, 10e6)))

    args = parser.parse_args()

    device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')

    # Set up output dir
    args.output_dir = os.path.join(args.output_dir, 'ppi')
    assert args.output_dir != None
    if args.unobserved:
        args.output_dir = os.path.join(args.output_dir, 'None')
        os.makedirs(args.output_dir, exist_ok=True)
    else:
        num = 0
        while True:
            dirpath = os.path.join(args.output_dir, str(num))
            if os.path.exists(dirpath):
                num += 1
            else:
                args.output_dir = dirpath
                print('Creating output directory {:}'.format(args.output_dir))
                os.makedirs(args.output_dir)
                break

    print(f"Running mode {args.mode:} with seed {args.random_seed:} "
          f"and output dir {args.output_dir}")
    train(args, device, args.mode=='test')


from reader import PelFile
import numpy as np
import os

def orthonorm(list):
    betas = []
    for a in list:
        u=a
        for x in betas:
            u -= x*np.inner(u,x)/np.inner(x,x)
        print(u)
        print(np.linalg.norm(u))
        betas.append(u)
    b = [x/np.linalg.norm(x) for x in betas]
    print(b)
    print("Orthonormed")
    return b

def project(data,basis):
    co = [] #coefficients
    for x in basis:
        co.append(np.inner(data,x))
    return co

if __name__ == "__main__":
    dir = "C:/Documents and Settings/adlwashi/My Documents/Variable Gains"
    files = ["11122009n.pel","11122009r.pel","11122009t.pel","11122009u.pel",
             "11122009y.pel","11132009c.pel","11132009g.pel"]
    files = [dir+"/"+file for file in files]
    data = PelFile()
    ws = [data.getgains(data.peakheader(file)) for file in files]

    alphas = []
    for file in files[:2]:
        data = PelFile()
        data.readfileimage(file)
        alphas.append(data.make2d(0,0x7FFFFFFF).reshape(256*256))
    print(alphas)
    betas = orthonorm(alphas)
    perfect = np.ones(shape=(256*256),dtype=np.double)
#    perfect=perfect/np.linalg.norm(perfect)
#    print(perfect)
    co = project(perfect,betas)
    print(co)
    a = np.zeros(shape=(256*256),dtype=np.double)
    for i in range(len(co)):
        a += co[i]*betas[i]
        print(np.inner(betas[i],betas[i]))

#    print(np.linalg.norm(a))
#    print(np.linalg.norm(perfect))

#    arr = [np.array([1.0,1.0,1.0]),np.array([1.0,2.0,3.0]),np.array([1.0,3.0,2.0]),np.array([1.0,0.0,0.0])]
#    print(orthonorm(arr))

#    files = os.listdir(dir)
#    files = [dir +"/"+ x for x in files]

#    ws = [(file,data.getgains(data.peakheader(file))) for file in files]
#    deltaws = []
#    for i in range(len(ws)-1):
#        deltaws.append((ws[i+1][0],ws[i+1][1]-ws[i][1]))
#    for i in range(19):
#        for d in deltaws:
#            if d[1][i] != 0 and d[1][19] != -505:
#                print((i,d[0],d[1]))


"""
Problem 27
"""

from core import is_prime

def quad(a, b):
    return lambda n: n**2+a*n+b

def efficient_quad_primes(max_coeff=1000):
    list_primes = list(x for x in range(2, 1000) if is_prime(x))
    coefficients = 0, 0
    current_max = 0
    for a in list(-x for x in list_primes)+list_primes:
        for b in list(-x for x in list_primes)+list_primes:
            n = 0
            print(a, b)
            quad_func = quad(a, b)
            val = quad_func(n)
            while val > 1 and is_prime(val):
                n += 1
                val = quad_func(n)
            print(n)
            if n > current_max:
                current_max = n
                coefficients = a, b
    return coefficients, current_max

if __name__ == "__main__":
    print(efficient_quad_primes(1000))


import datetime

from backend.models.mysql_connection_pool import MySQLPool

class participacionModel:
    def __init__(self):
        self.mysql_pool = MySQLPool()

    def get_participacion(self, id_participacion):
        params = {'id_participacion' : id_participacion}
        rv = self.mysql_pool.execute("""SELECT p.id_participacion, p.nota_final, s.nombre_seccion, concat(u.nombre, ' ', u.apellido) as estudiante from Participacion p
                                    inner join Horario h on p.id_horario = h.id_horario
                                    inner join Seccion s on h.id_seccion = s.id_seccion
                                    inner join Estudiante e on p.id_estudiante = e.id_estudiante
                                    inner join Usuario u on e.dni = u.dni where p.id_participacion=%(id_participacion)s""", params)
        data = []
        content = {}
        for result in rv:
            content = {'id_participacion': result[0], 'fecha': result[1], 'nota_final': result[2], 'id_horario': result[3], 'nombre_seccion': result[11]}
            data.append(content)
            content = {}
        return data

    def get_participacions(self):
        rv = self.mysql_pool.execute("""SELECT p.id_participacion, p.nota_final, s.nombre_seccion, concat(u.nombre, ' ', u.apellido) as estudiante from Participacion p
                                    inner join Horario h on p.id_horario = h.id_horario
                                    inner join Seccion s on h.id_seccion = s.id_seccion
                                    inner join Estudiante e on p.id_estudiante = e.id_estudiante
                                    inner join Usuario u on e.dni = u.dni""")
        data = []
        content = {}
        for result in rv:
            content = {'id_participacion': result[0], 'nota_final': result[1], 'nombre_seccion': result[2], 'estudiante': result[3]}
            data.append(content)
            content = {}
        return data

    def create_participacion(self, nota_final, id_horario, id_estudiante):
        data = {
            'fecha' : datetime.date.today().strftime('%Y-%m-%d'),
            'nota_final' : nota_final,
            'id_horario' : id_horario,
            'id_estudiante' : id_estudiante
        }
        query = """insert into Participacion(fecha, nota_final, id_horario, id_estudiante)
        values (%(fecha)s, %(nota_final)s, %(id_horario)s, %(id_estudiante)s)"""
        cursor = self.mysql_pool.execute(query, data, commit=True)

        data['id_participacion'] = cursor.lastrowid
        return data

    def update_participacion(self, id_participacion, nota_final):
        data = {
            'id_participacion' : id_participacion,
            'nota_final' : nota_final
        }
        query = """update Participacion set nota_final = %(nota_final)s
                    where id_participacion = %(id_participacion)s"""
        cursor = self.mysql_pool.execute(query, data, commit=True)
        result = {'result':1}
        return result

    def delete_participacion(self, id_participacion):
        params = {'id_participacion' : id_participacion}
        query = """delete from Participacion where id_participacion = %(id_participacion)s"""
        self.mysql_pool.execute(query, params, commit=True)
        result = {'result': 1}
        return result


with open("Text_3 Name and salary.txt", "r", encoding="utf-8") as text_3:
    salary = []
    Losers = []
    list_1 = text_3.read().split('\n')
    for i in list_1:
        i = i.split()

        if float(i[1]) < 20000.00:
            Losers.append(i[0])
        salary.append(i[1])

print(f'Люди с окладом меньше 20000.00: {Losers}, \nСредний оклад: {sum(map(float, salary)) / len(salary)}')


import keyboard
import os
from pygame import mixer # Load the required library

def play_audio(filename):

    print(os.path.dirname(os.path.abspath(__file__)) + "\\" + filename)

    mixer.init()
    mixer.music.load(os.path.dirname(os.path.abspath(__file__)) + "\\" + filename)
    mixer.music.play()
    while mixer.music.get_busy() == True:
        try:
            if keyboard.is_pressed('esc'):
                print('Music Stopped')
                mixer.music.stop()
                break
            else:
                pass
        except:
            continue

if __name__ == "__main__":
    play_audio("lullaby_goodnight.mp3")


import pytest
from ..horizontal_rule_parser import parse_horiontal_rule

@pytest.mark.parametrize("content, start, end", [('***', 0, 3), ('____', 0, 4),
                                                 ('-----', 0, 5),
                                                 (' ------', 0, 7),
                                                 ('______ ', 0, 7),
                                                 ('______ \n', 0, 8),
                                                 ('''

-----

''', 3, 9)])
def test_parse(content, start, end):
    (start_index, end_index, hori_rule) = parse_horiontal_rule(content)
    assert start_index == start
    assert end_index == end
    assert hori_rule._content == ''

@pytest.mark.parametrize(
    "content",
    [
        # not match
        ('**'),
        ('*_-'),
        (r'\---'),
        ('a___'),
        ('*****a'),
        ('***a**'),
        ('*** ***'),
    ])
def test_parse_not_match(content):
    (start_index, end_index, hori_rule) = parse_horiontal_rule(content)
    assert start_index == -1
    assert end_index == -1
    assert hori_rule is None


#! /usr/bin/env python
'''Test of the glDrawArrays function (draws flower)'''
from __future__ import print_function
from OpenGLContext import testingcontext
BaseContext = testingcontext.getInteractive()
from OpenGL.GL import *
import flower_geometry

def bit_pattern( *args ):
    args = list(args[:16])
    args = args + [0]*(16-len(args))
    base = 0
    for arg in args:
        base = base << 1
        base += bool(arg)
    return base

class TestContext( BaseContext):
    def OnInit( self ):
        """Initialisation"""
        print("""Should see flower pattern in gray over white background""")
        glLineStipple( 3, bit_pattern(
            0,0,1,1,
            0,1,0,1,
            0,0,1,1,
            0,0,1,0,
        ))
        glEnable( GL_LINE_STIPPLE )
    def Render( self, mode = 0):
        BaseContext.Render( self, mode )
        glVertexPointerd(flower_geometry.points_expanded )
        glNormalPointerf(flower_geometry.normals_expanded )
        glEnableClientState(GL_VERTEX_ARRAY);
        glEnableClientState(GL_NORMAL_ARRAY);
        glDrawArrays(GL_LINES, 0, len(flower_geometry.points_expanded))

if __name__ == "__main__":
    TestContext.ContextMainLoop()


from django.http import HttpResponseRedirect
from decimal import Decimal
from django.conf import settings
from datetime import date
from datetime import datetime
from inventory.models import Inventory

class Carrito(object):
	def __init__(self,request):
		self.session = request.session
		cart = self.session.get(settings.CART_SESSION_ID)
		if not cart:
			cart = self.session[settings.CART_SESSION_ID] = {}
		self.cart = cart
		self.request = request

	def save(self):
		self.session[settings.CART_SESSION_ID]=self.cart
		self.session.modified = True

	def add(self,product,quanty):

		total = float(product.price) * float(quanty)
		if str(product.pk) in self.cart:
			if int(quanty) == 0:
				del self.cart[str(product.pk)]
				if int(self.request.session['carrito']) > 0:
					n = int(self.request.session['carrito']) - 1
					self.request.session['carrito'] = n
				self.save()
			else:
				total = float(product.price) * float(quanty)
				self.cart[str(product.pk)]['quanty'] = quanty
				self.cart[str(product.pk)]['total'] = total
				self.save()

		else:
			if int(quanty) >= 1:
				self.request.session['carrito'] +=1
				self.cart[str(product.pk)] = {'pk':product.pk,'code':product.code,'product':product.name,'quanty':quanty,'price':product.price,
															'total':total,'img':'http://localhost:8000'+product.img.url,'shipping_price':product.shipping_price,'user':product.user.pk}
		print(self.cart)
		self.save()

	def remove(self,product):
		product_id = str(product.pk)
		if product_id in self.cart:
			del self.cart[product_id]
			self.save()

	def __iter__(self):
		product_ids = self.cart.keys()
		products = Inventory.objects.filter(id__in=product_ids)
		'''for product in products:
			self.cart[str(product.id)]['product']=product'''

		for item in self.cart.values():
			#item['precio']=Decimal(item['precio'])
			#item['total']=item['precio']*item['cantidad']
			yield item

	def __len__(self):
		return sum(int(item['quanty']) for item in self.cart.values())

	def clear(self):
		del self.session[settings.CART_SESSION_ID]
		self.session.modified = True


import numpy as np
from scipy.signal import fftconvolve
from scipy.ndimage import zoom
import warnings

from astropy.modeling import models
from astropy.units import Unit, Quantity

from specklepy.exceptions import SpecklepyTypeError, SpecklepyValueError
from specklepy.io import config
from specklepy.io import fits
from specklepy.logging import logger

class Telescope(object):
	"""Class carrying the parameters of a telescope.

	Attributes:
		diameter (astropy.units.Quantity):
		psf_source (str):
			Name of the PSF model or of the file, from which the PSF frames are extracted.
		psf_frame (int):
			Current frame of the PSF file.

	Optional attributes:
		central_obscuration (float, optional):
	"""

	__name__ = 'telescope'
	TIME_STEP_KEYS = ['TIMESTEP', 'INTTIME', 'CDELT3']
	RESOLUTION_KEYS = ['PIXSIZE', 'CDELT1']

	def __init__(self, diameter, psf_source, central_obscuration=None, psf_frame=0, **kwargs):
		"""Instantiate Telescope class:

		Args:
			diameter (float or astropy.units.Quantity):
				Telescope diameter, used to compute the light collecting area.
			psf_source (str):
				File name to read PSFs from or model name. Models can be either 'AiryDisk' or 'Gaussian'. The models
				require central_obscuration (float, optional): Radial fraction of the
				telescope aperture that is blocked by the secondary.
			central_obscuration (float, optional):
				Radial fraction that is centrally obscured, by the secondary mirror.
			psf_frame (int, optional):
				Index of the first frame to read from psf_source.
			kwargs:
				Are forwarded to the psf_source model.
		"""

		# Input parameters
		if isinstance(diameter, Quantity):
			self.diameter = diameter
		elif isinstance(diameter, (int, float)):
			logger.warning(f"Interpreting scalar type diameter as {diameter} m")
			self.diameter = Quantity(f"{diameter} m")
		elif isinstance(diameter, str):
			self.diameter = Quantity(diameter)
		else:
			raise SpecklepyTypeError('Telescope', 'diameter', type(diameter), 'Quantity')

		if isinstance(psf_source, str):
			self.psf_source = psf_source
		else:
			raise SpecklepyTypeError('Telescope', 'psf_source', type(psf_source), 'str')

		if isinstance(central_obscuration, float) or central_obscuration is None:
			self.central_obscuration = central_obscuration
		elif isinstance(central_obscuration, str):
			self.central_obscuration = float(central_obscuration)
		else:
			raise SpecklepyTypeError('Telescope', 'central_obscuration', type(central_obscuration), 'float')

		if isinstance(psf_frame, int):
			self.psf_frame = psf_frame
		else:
			raise SpecklepyTypeError('Telescope', 'psf_frame', type(psf_frame), 'int')

		# Derive secondary parameters
		if self.central_obscuration is not None:
			self.area = (1. - self.central_obscuration**2) * np.pi * (self.diameter / 2)**2
		else:
			self.area = np.pi * (self.diameter / 2)**2

		if psf_source.lower() in ['airydisk', 'gaussian']:
			self.model_psf(psf_source, **kwargs)
		else:
			psf, time_resolution, angular_resolution = self.read_psf_file(psf_source)
			self.psf = psf
			self.psf_resolution = angular_resolution
			if time_resolution is not None:
				self.timestep = time_resolution

	@staticmethod
	def from_file(par_file):
		params = config.read(par_file)

		# Try known first-level keys
		for key in ['TELESCOPE', 'Telescope', 'telescope']:
			if key in params.keys():
				return Telescope(**params[key])

		# Try full parameter set
		try:
			return Telescope(**params)
		except TypeError:
			raise RuntimeError(f"Could not identify parameters for initializing a Telescope instance in parameter "
							   f"file {par_file}")

	def __call__(self, *args, **kwargs):
		return self.get_photon_rate(*args, **kwargs)

	def __str__(self):
		tmp = "Telescope:\n"
		for key in self.__dict__:
			if key == 'psf':
				continue
			tmp += f"{key}: {self.__dict__[key]}\n"
		return tmp

	def model_psf(self, model, radius, psf_resolution, shape=256, **kwargs):
		"""Models the PSF given the desired model function and kwargs.

		Args:
			model (str):
				Must be either 'airydisk' or 'gaussian'.
			radius (int, float, astropy.unit.Quantity):
				Radius of the PSF model that is the radius of the first zero in an AiryDisk model or the standard
				deviation of the Gaussian model. Scalar values will be interpreted in units of arcseconds.
			psf_resolution (int, float, astropy.unit.Quantity):
				Resolution of the model PSF, equivalent to the pixel scale of the array. Scalar values will be
				interpreted in units of arcseconds.
			shape (int, optional):
				Size of the model PSF along both axes.
			kwargs are forwarded to the model function.
		"""

		# Check input parameters
		if not isinstance(model, str):
			raise SpecklepyTypeError('model_psf', 'model', type(model), 'str')

		if isinstance(radius, Quantity):
			self.radius = radius
		elif isinstance(radius, (int, float)):
			logger.warning(f"Interpreting scalar type radius as {radius} arcsec")
			self.radius = Quantity(f"{radius} arcsec")
		elif isinstance(radius, str):
			self.radius = Quantity(radius)
		else:
			raise SpecklepyTypeError('model_psf', 'radius', type(radius), 'Quantity')

		if isinstance(psf_resolution, Quantity):
			self.psf_resolution = psf_resolution
		elif isinstance(psf_resolution, (int, float)):
			logger.warning(f"Interpreting scalar type psf_resolution as {psf_resolution} arcsec")
			self.psf_resolution = Quantity(f"{psf_resolution} arcsec")
		elif isinstance(psf_resolution, str):
			self.psf_resolution = Quantity(psf_resolution)
		else:
			raise SpecklepyTypeError('model_psf', 'psf_resolution', type(psf_resolution), 'Quantity')

		if isinstance(shape, int):
			center = (shape / 2, shape / 2)
			shape = (shape, shape)
		elif isinstance(shape, tuple):
			center = (shape[0] / 2, shape[1] / 2)
		else:
			raise SpecklepyTypeError('model_psf', 'shape', type(shape), 'int or tuple')

		if model.lower() == 'airydisk':
			model = models.AiryDisk2D(x_0=center[0], y_0=center[1], radius=float(self.radius / self.psf_resolution))
		elif model.lower() == 'gaussian':
			stddev = float(self.radius / self.psf_resolution)
			model = models.Gaussian2D(x_mean=center[0], y_mean=center[1], x_stddev=stddev, y_stddev=stddev)
		else:
			raise SpecklepyValueError('model_psf', 'model', model, 'either AiryDisk or Gaussian')

		y, x = np.mgrid[0:shape[0], 0:shape[1]]
		self.psf = model(x, y)
		self.psf = self.normalize(self.psf)

	def read_psf_file(self, filename, hdu=None):
		"""Read PSF information from a FITS file.

		Args:
			filename (str):
				Name of the FITS file containing the PSF frames.
			hdu (int, str, optional):
				Specification of the HDU to read from the file. Default is the first HD
		"""

		# Set
		psf = None
		time_resolution = None
		angular_resolution = None

		# Extract header
		header = fits.get_header(filename, extension=hdu)

		if header['NAXIS'] == 2:
			psf = self.normalize(fits.get_data(filename, extension=hdu))
		else:
			# Iterate over list of known header cards containing the time resolution
			for key in self.TIME_STEP_KEYS:
				try:
					time_resolution = self.get_header_quantity(header, key)
					break
				except KeyError:
					continue

			# Check whether time resolution was found in the header
			if time_resolution is None:
				raise RuntimeError("Function read_psf_file could failed extracting the PSF time resolution.")

		# Iterate over list of known header cards containing the angular resolution
		for key in self.RESOLUTION_KEYS:
			try:
				angular_resolution = self.get_header_quantity(header, key)
				break
			except KeyError:
				continue

		# Check whether angular resolution was found in the header
		if angular_resolution is None:
			raise RuntimeError("Function read_psf_file could failed extracting the PSF angular resolution.")

		return psf, time_resolution, angular_resolution

	@staticmethod
	def get_header_quantity(header, key, aliases=None):
		"""Extract unit quantities from FITS headers, based on the unit in the comment.

		Args:
			header:
				Header of the FITS file.
			key (str):
				Key or name of the FITS header card.
			aliases (dict, optional):
				The aliases dictionary maps unit strings such that they are understood by Unit(str).

		Returns:
			quantity (Quantity):
				Quantity derived from the combination of the FITS header card value and comment.
		"""

		# Read header card
		value = header[key]
		comment = header.comments[key]

		# Handle empty comment
		if not comment:
			logger.warning("Function 'get_value()' received an empty comment string and returns scalar value.")
			return value

		# Apply fall back values
		if aliases is None:
			aliases = {'sec': 's', 'milliarcsec': 'mas', 'microns': 'micron'}

		# Replace comment entries that are not understood by astropy.units by corresponding aliases
		if comment in aliases.keys():
			comment = aliases[comment]

		return value * Unit(comment)

	def get_photon_rate(self, photon_rate_density, photon_rate_density_resolution=None, integration_time=None,
						debug=False):
		"""Propagates the 'photon_rate_density' array through the telescope.

		The photon_rate_density is multiplied by the telescope collecting area and then
		convolved with the PSF. If the resolution of the flux array is different
		from the telescopes psf_resolution, then one is resampled. If the PSF is
		non-static, it will be integrated over the 'integration_time' value.

		Args:
			photon_rate_density (np.ndarray, dtype=Quantity):
			photon_rate_density_resolution (Quantity, optional):
			integration_time(Quantity, optional):
				Required only if the PSF is non-static.
			debug (bool, optional):
				Show additional information for debugging. Default is False.

		Returns:
			photon_rate (Quantity): PSF-convolved photon rate array.
		"""

		# Input parameters
		if not isinstance(photon_rate_density, Quantity):
			raise SpecklepyTypeError('get_photon_rate', 'photon_rate_density', type(photon_rate_density), 'Quantity')

		if photon_rate_density_resolution is not None:
			if not isinstance(photon_rate_density_resolution, Quantity):
				raise SpecklepyTypeError('get_photon_rate', 'photon_rate_density_resolution',
										 type(photon_rate_density_resolution), 'Quantity')
			psf_resample_mode = True
		else:
			psf_resample_mode = False

		if integration_time is None and hasattr(self, 'timestep'):
			raise ValueError("If the PSF source of Telescope is non-static, the call function requires the "
							 "integration_time.")
		elif isinstance(integration_time, (int, float)):
			logger.warning(f"Interpreting scalar type integration_time as {integration_time} s")
			integration_time = Quantity(f"{integration_time} s")
		elif not isinstance(integration_time, Quantity):
			raise SpecklepyTypeError('get_photon_rate', 'integration_time', type(integration_time), 'Quantity')

		# Apply telescope collecting area
		photon_rate = photon_rate_density * self.area
		total_flux = np.sum(photon_rate)
		photon_rate_unit = photon_rate.unit

		# Prepare PSF if non-static
		if hasattr(self, 'timestep'):
			self.integrate_psf(integration_time=integration_time)

		# Resample photon_rate_density to psf resolution
		if psf_resample_mode:

			# Compute the zoom factor
			ratio = float(photon_rate_density_resolution / self.psf_resolution)
			# try:
			# 	ratio = float(photon_rate_density_resolution / self.psf_resolution)
			# except UnitConversionError as e:
			# 	raise UnitConversionError(f"The resolution values of the image ({photon_rate_density_resolution}) and "
			# 							  f"PSF ({self.psf_resolution}) have different units!")

			# Zoom either the image or the PSF, depending on the zoom factor
			with warnings.catch_warnings():
				warnings.simplefilter('ignore')
				if ratio < 1.0:
					self.psf = zoom(self.psf, 1/ratio, order=1) / ratio**2
					self.psf = self.normalize(self.psf)
				else:
					memory_sum = np.sum(photon_rate)
					photon_rate = zoom(photon_rate, ratio, order=1) / ratio**2
					photon_rate = photon_rate / np.sum(photon_rate) * memory_sum

		# Convolve the array with the PSF
		convolved = fftconvolve(photon_rate, self.psf, mode='same') * photon_rate_unit

		# Report on flux conservation
		logger.debug(f"Flux conservation during convolution: {total_flux} > {np.sum(convolved)}")

		return convolved.decompose()

	@staticmethod
	def normalize(array, mode='sum_circular'):
		"""Normalizes the input array depending on the mode.

		Args:
			array (np.ndarray):
				Array to be normalized.
			mode (str, optional):
				Can be either 'sum' for having a sum of 1, 'max' for having a peak value 1, or 'sum_circular' for
				subtracting a constant and then normalizing to a sum of 1. Default is 'sum_circular'.

		Returns:
			normalized (np.ndarray):
				Normalized array, according to mode.
		"""

		if not isinstance(array, np.ndarray):
			raise SpecklepyTypeError('normalize', 'array', type(array), 'np.ndarray')
		if np.sum(array) == 0:
			raise ValueError("Normalize received an array of zeros!")

		if mode not in ['sum', 'max', 'peak', 'sum_circular']:
			raise SpecklepyValueError('normalize', 'mode', mode, "'sum', 'max', or 'sum_circular'")

		if mode == 'sum':
			normalized = array / np.sum(array)
		elif mode == 'max':
			normalized = array / np.max(array)
		elif mode == 'sum_circular':
			x, y = array.shape
			low_cut = array[0, int(y/2)]
			array = np.maximum(array - low_cut, 0)
			normalized = array / np.sum(array)
		else:
			normalized = None

		return normalized

	def integrate_psf(self, integration_time, hdu=None):
		"""Integrates psf frames over the input time.

		Args:
			integration_time (Quantity):
				This is used for computing the number of frames 'n_frames', via floor division by the 'timestep'
				attribute.
			hdu (int, str, optional):
				Specifier of the HD Default is None for the first HD
		"""

		# Check input parameters
		if isinstance(integration_time, (int, float)):
			logger.warning(f"Interpreting scalar type integration_time as {integration_time} s")
			integration_time = integration_time * Unit('s')
		elif not isinstance(integration_time, Quantity):
			raise SpecklepyTypeError('integrate_psf', 'integration_time', type(integration_time), 'Quantity')

		if integration_time < self.timestep:
			raise ValueError(f"integrate_psf received integration time {integration_time} shorter than the time "
							 f"resolution of the psf source ({self.timestep})!")

		n_frames = int(integration_time / self.timestep)

		# Read PSF frames from source file
		data = fits.get_data(self.psf_source, extension=hdu)

		self.psf_frame += 1
		if self.psf_frame + n_frames < data.shape[0]:
			self.psf = np.sum(data[self.psf_frame : self.psf_frame+n_frames], axis=0)
		else:
			self.psf = np.sum(data[self.psf_frame : ], axis=0)
			self.psf += np.sum(data[ : (self.psf_frame+n_frames) % data.shape[0]], axis=0)
		self.psf_frame += n_frames - 1
		self.psf_frame = self.psf_frame % data.shape[0]

		# Normalize the integrated PSF
		self.psf = self.normalize(self.psf)


import logging
import os
import traceback
from pathlib import Path
from typing import Optional

from vdk.internal.core import errors

log = logging.getLogger(__name__)

def whom_to_blame(
    exception,
    executor_module: Optional[str] = None,
    data_job_path: Optional[Path] = None,
) -> errors.ResolvableBy:
    """
    :param exception: Exception object that has led to Data Job failure.
    :param executor_module: name of module that executes User Code.
                It must be the exact module that starts the user code.
                The next called module must be the user's modules/code.
                Otherwise the logic below will not work.
                 If the name of the module is not known, set to None
    :param data_job_path: path object of the data job directory.
    :return: ResolvableBy.PLATFORM_ERROR if exception was recognized as Platform Team responsibility.
             errors.ResolvableBy.USER_ERROR if exception was recognized as User Error.
    """
    if is_classified(exception):
        return errors.find_whom_to_blame_from_exception(exception)
    if is_user_error(exception, data_job_path):
        return errors.ResolvableBy.USER_ERROR
    if _is_exception_from_vdk_code(
        exception, executor_module
    ):  # We want to avoid blaming users for errors raised from VDK code
        return (
            errors.ResolvableBy.PLATFORM_ERROR
        )  # Because we can't be 100% sure if they are user errors
    else:
        return errors.ResolvableBy.USER_ERROR

def _is_exception_from_vdk_code(exception, executor_module):
    if executor_module is None:
        log.warning(
            "Executor module is not set. "
            "Cannot infer if exception is from user code. "
            "This may lead to misclassification of the error resolvable by type."
        )
        return False
    executor_module = os.path.abspath(executor_module)
    vdk_code_directory = os.path.dirname(executor_module)
    call_list = traceback.format_tb(exception.__traceback__)
    call_list.reverse()  # First element is most recent call
    if len(call_list) == 0:
        return True

    for call in call_list:
        # Extract module path from stacktrace call.
        caller_module = call.split('"')[1]
        if vdk_code_directory in caller_module and caller_module != executor_module:
            return True
        elif (
            caller_module == executor_module
        ):  # User code starts from this module always.
            break

    return False

def is_user_error(
    received_exception: Exception, data_job_path: Optional[Path] = None
) -> bool:
    """
    Returns if exception should be user error
    """
    return (
        _is_file_size_limit_exceeded(received_exception)
        or _is_new_thread_error(received_exception)
        or _is_timeout_error(received_exception)
        or _is_memory_limit_exceeded(received_exception)
        or _is_direct_user_code_error(received_exception, job_path=data_job_path)
    )

def is_classified(exception: BaseException):
    return isinstance(exception, errors.BaseVdkError) or hasattr(
        exception, errors.ATTR_VDK_RESOLVABLE_BY
    )

def _is_memory_limit_exceeded(exception):
    return errors.exception_matches(
        exception,
        classname_with_package="MemoryError",
        exception_message_matcher_regex=".*",
    )

def _is_file_size_limit_exceeded(exception):
    return errors.exception_matches(
        exception,
        classname_with_package="OSError",
        exception_message_matcher_regex=".*File size limit.*",
    )

def _is_new_thread_error(exception):
    return errors.exception_matches(
        exception,
        classname_with_package="RuntimeError",
        exception_message_matcher_regex=".*new thread.*",
    )

def _is_timeout_error(exception):
    return errors.exception_matches(
        exception,
        classname_with_package=".*TimeoutError.*",
        exception_message_matcher_regex=".*Duration of Data Job exceeded.*seconds.*",
    )

def _is_direct_user_code_error(exception: Exception, job_path: Optional[Path]):
    data_job_path = str(job_path) if job_path else None
    if not data_job_path:
        return False

    # Get exception traceback as a list
    call_list = traceback.format_tb(exception.__traceback__)
    if len(call_list) == 0:
        return False

    last_call = call_list[-1]
    last_caller_module = last_call.split('"')[1]

    # Check if the data job path is contained in the last exception call from the exception
    # traceback. If it is, it is safe to assume that the exception was generated directly in
    # user code, and not somewhere else in the vdk code or one of vdk's plugins.
    return True if data_job_path in last_caller_module else False


import string
olgas_dict = {}

with open('./dir2json.txt', 'r+') as data:
    for line in data:
        list_of_2 = line.split("--")
        seq_num, img_title = list_of_2[0].split("_")
        img_title_list = img_title.split("-")
        #dfi_img_number = ''.join(re.findall('\d+', list_of_2[1]))
        dfi_img_number = list_of_2[1].translate(list_of_2[1], string.digits)
        int_seq = seq_num.translate(seq_num, string.digits)
        olgas_dict[dfi_img_number] = [seq_num, img_title_list, "Peter Elfelt", line]

with open("amost_db.txt", 'w') as txt_file:
     txt_file.write(str(olgas_dict))


"""
Kth Smallest Element in a Sorted Matrix

Given an n x n matrix where each of the rows and columns are sorted in ascending order, return the kth smallest element in the matrix.
Note that it is the kth smallest element in the sorted order, not the kth distinct element.

Example 1:

Input: matrix = [[1,5,9],[10,11,13],[12,13,15]], k = 8
Output: 13
Explanation: The elements in the matrix are [1,5,9,10,11,12,13,13,15], and the 8th smallest number is 13

Example 2:

Input: matrix = [[-5]], k = 1
Output: -5

Constraints:

n == matrix.length
n == matrix[i].length
1 <= n <= 300
-10^9 <= matrix[i][j] <= 10^9
All the rows and columns of matrix are guaranteed to be sorted in non-decreasing order.
1 <= k <= n^2
"""

class Solution:
    def kthSmallest(self, matrix: List[List[int]], k: int) -> int:
        n = len(matrix)
        l, r = matrix[0][0], matrix[n - 1][n - 1]
        while l < r:
            mid = (l + r) // 2
            c, j = 0, n - 1
            for i in range(n):
                while j >= 0 and matrix[i][j] > mid:
                    j -= 1
                c += j + 1

            if c < k:
                l = mid + 1
            else:
                r = mid

        return l

Kth Smallest Element in a Sorted Matrix.py


"""
Desc: AIND Sudoku project submission code. Program intelligently solves any
sudoku puzzle, includes naked_twins() heuristic code and support for diagonal
sudoku puzzles. Portions of this code are adapted from the Udacity - Artificial
Intelligence Nanodegree (May 2017 session) online MOOC.
Input: initial puzzle configuration
Output: 2-D puzzle solution
Author: Daniel R Rines
Github: drines
Created: Friday, May 23, 2017
Version: 2017.05.25.003
"""
import logging

logging.basicConfig(filename='error.log',
                    format='%(asctime)s %(message)s',
                    datefmt='%m/%d/%Y %I:%M:%S %p',
                    level=logging.ERROR)

def update_log(level, message):
    """
    Function makes it easier to output logging messages instead of adding
    format instructions each time a message is sent to the logging module
    code base. Warning is the default level.
    """
    log_message = ' :: ' + message
    if level == 'debug':
        logging.debug(log_message)
    elif level == 'error':
        logging.error(log_message)
    else:
        logging.warning(log_message)

update_log('debug', 'starting execution: solution.py')
assignments = []

def assign_value(values, box, value):
    """
    Please use this function to update your values dictionary!
    Assigns a value to a given box. If it updates the board record it.
    """
    if values[box] == value:
        return values

    values[box] = value
    if len(value) == 1:
        assignments.append(values.copy())
    return values

def naked_twins(values):
    """Eliminate values using the naked twins strategy.
    Args:
        values(dict): a dictionary of the form {'box_name': '123456789', ...}
    Returns:
        the values dictionary with the naked twins eliminated from peers.
    Overall logic:
        function obtains a list of all boxes that currently contain only two
        digits. It then loops through these boxes on a peer-by-peer manner to
        identify any set of idential two digit boxes. of course, these must
        be within the same peer group. assuming a set of naked twins are found
        in a peer group, then function will search for each of the digits in
        other peer associated boxes and remove them, leaving just the non-
        twin digits.
    """
    # find all instances of naked twins
    values = find_twins(values,
                        [box for box in values.keys()
                         if len(values[box]) == 2])
    return values

def find_twins(values, two_digit_boxes):
    """
    Modularized code to handle the search aspects of the naked_twins algorithm.
    Args:
        two_digit_boxes(list): a list of all the boxes with the two digit
        values.
    Returns:
        the values dictionary with the naked twins eliminated from peers.
    """
    for box in two_digit_boxes:
        for peer_group in units[box]:
            for twin_box in peer_group:    # loop through peer groups
                if values[box] == values[twin_box] and box != twin_box:
                    update_log('debug', 'Found a twin: ' + box +
                               ' -> (' + values[twin_box] + ')')
                    # now isolate and eliminate the digits if possible
                    values = eliminate_twins(values, box, twin_box,
                                             peer_group, values[box])
    return values

def eliminate_twins(values, box, twin_box, group, digits):
    """
    Modularized code to handle the search aspects of the naked_twins algorithm.
    Args:
        values(dict) - a dictionary with key: box and value: digits
        box(string) - the first two digit box in the peer
        twin_box(string) - the second two digit box in the peer
        group(list) - the list of all keys in current peer
        digits(string) - a successfully ident. set of naked twin digits
    Returns:
        the values dictionary with the naked twins eliminated from peers.
    """
    for digit in digits:
        # eliminate the naked twins as possibilities in
        # their peers.
        for fix_box in group:
            # make sure you don't remove digits from either
            # of the naked twins and don't remove any digits
            # from a single digit (assigned) box.
            if box != fix_box and fix_box != twin_box and \
                    len(values[fix_box]) > 1:
                update_log('debug',
                           'eliminating digit from non-twins box: ' +
                           fix_box + '-> ' +
                           values[fix_box] + '(' +
                           digit + ')')
                values = assign_value(values, fix_box,
                                      values[fix_box].replace(digit, ''))
    return values

def cross(A, B):
    "Cross product of elements in A and elements in B."
    return [s+t for s in A for t in B]

def grid_values(grid):
    """
    Convert grid into a dict of {square: char} with '123456789' for empties.
    Args:
        grid(string) - A grid in string form.
    Returns:
        A grid in dictionary form
            Keys: The boxes, e.g., 'A1'
            Values: The value in each box, e.g., '8'. If the box has no value,
            then the value will be '123456789'.
    """
    update_log('debug', 'convert input sudoku grid')
    chars = []
    digits = '123456789'
    for cpos in grid:
        if cpos in digits:
            chars.append(cpos)
        if cpos == '.':
            chars.append(digits)
    assert len(chars) == 81
    return dict(zip(boxes, chars))

def display(values):
    """
    Display the values as a 2-D grid.
    Args:
        values(dict): The sudoku in dictionary form
    """
    width = 1+max(len(values[s]) for s in boxes)
    line = '+'.join(['-'*(width*3)]*3)
    for r in rows:
        print(''.join(values[r+c].center(width)+('|' if c in '36' else '')
                      for c in cols))
        if r in 'CF': print(line)
    return

def eliminate(values):
    """
    Go through all the boxes, and whenever there is a box with a value,
    eliminate this value from the values of all its peers.
    Input: A sudoku in dictionary form.
    Output: The resulting sudoku in dictionary form.
    """
    update_log('debug', 'executing eliminate()')
    solved_values = [box for box in values.keys() if len(values[box]) == 1]
    for box in solved_values:
        digit = values[box]
        for peer in peers[box]:
            values = \
                assign_value(values, peer, values[peer].replace(digit, ''))
    return values

def only_choice(values):
    """
    Go through all the units, and whenever there is a unit with a value that
    only fits in one box, assign the value to this box.
    Input: A sudoku in dictionary form.
    Output: The resulting sudoku in dictionary form.
    """
    update_log('debug', 'executing only_choice()')
    for unit in unitlist:
        for digit in '123456789':
            dplaces = [box for box in unit if digit in values[box]]
            if len(dplaces) == 1:
                # values[dplaces[0]] = digit
                values = assign_value(values, dplaces[0], digit)
    return values

def reduce_puzzle(values):
    """
    Iterate eliminate() and only_choice(). If at some point, there is a box
    with no available values, return False.
    If the sudoku is solved, return the sudoku.
    If after an iteration of both functions, the sudoku remains the same,
    return the sudoku.
    Input: A sudoku in dictionary form.
    Output: The resulting sudoku in dictionary form.
    """
    update_log('debug', 'executing reduce_puzzle()')
    stalled = False
    while not stalled:
        solved_values_before = \
            len([box for box in values.keys() if len(values[box]) == 1])
        # extended the constraint propogation to include the diagonal
        # peer constraint via the eliminate() function execution. the peer
        # groups are initially defined with global 'unit' constants.
        values = eliminate(values)
        values = only_choice(values)
        # also extended the constraint propogation loop to include the
        # test for naked twins (two boxes with idential set of paired
        # digits). this heuristic removes digits from other peer
        # associated boxes that are already included in any twins.
        values = naked_twins(values)
        solved_values_after = \
            len([box for box in values.keys() if len(values[box]) == 1])
        stalled = solved_values_before == solved_values_after
        if stalled:
            update_log('debug', 'reduce_puzzle() stalled')
        if len([box for box in values.keys() if len(values[box]) == 0]):
            return False
    return values

def search(values):
    """Using depth-first search and propagation, create a search tree
    and solve the sudoku."""
    update_log('debug', 'executing search()')
    # First, reduce the puzzle using the previous function
    # Choose one of the unfilled squares with the fewest possibilities
    values = reduce_puzzle(values)
    if values is False:
        return False  # Failed earlier
    if all(len(values[s]) == 1 for s in boxes):
        return values  # Solved!
    # Choose one of the unfilled squares with the fewest possibilities
    _, s = min((len(values[s]), s) for s in boxes if len(values[s]) > 1)
    # Now use recurrence to solve each one of the resulting sudokus, and
    for value in values[s]:
        new_sudoku = values.copy()
        new_sudoku[s] = value
        attempt = search(new_sudoku)
        if attempt:
            return attempt

def solve(grid):
    """
    Find the solution to a Sudoku grid.
    Args:
        grid(string): a string representing a sudoku grid.
            Example:
            '2.............62....1....7...6..8...3...9...7...6..4...4.
            ...8....52.............3'
    Returns:
        The dictionary representation of the final sudoku grid. False if no
        solution exists.
    """
    update_log('debug', 'executing solve()')
    return search(grid_values(grid))

# Initialize global constants
update_log('debug', 'global constant initialization')
rows = 'ABCDEFGHI'
cols = '123456789'
boxes = cross(rows, cols)
row_units = [cross(r, cols) for r in rows]
column_units = [cross(rows, c) for c in cols]
square_units = [cross(rs, cs) for rs in ('ABC', 'DEF', 'GHI')
                for cs in ('123', '456', '789')]
# added two additional peer groups for any units located along
# either of the matrix diagnols. these are then included with the
# unitlist definition and, thus, 'baked in' into the constraint
# propogation process.
diag_units = [[r+c for r, c in zip(rows, cols)],
              [r+c for r, c in zip(rows, cols[::-1])]]
unitlist = row_units + column_units + square_units + diag_units
units = dict((s, [u for u in unitlist if s in u]) for s in boxes)
peers = dict((s, set(sum(units[s], []))-set([s])) for s in boxes)

if __name__ == '__main__':
    """
    Entry point for Sudoku solution.py code base.
    """
    update_log('debug', 'called: __main__')

    diag_sudoku_grid = \
        '2.............62....1....7...6..8...3...9...7' + \
        '...6..4...4....8....52.............3'
    display(solve(diag_sudoku_grid))

    try:
        from visualize import visualize_assignments
        visualize_assignments(assignments)

    except SystemExit:
        pass
    except:
        update_log('debug', 'problems with pygame execution')
        print('We could not visualize your board due to a pygame issue.' +
              ' Not a problem! It is not a requirement.')


import re
import csv
from pathlib import Path

def readTaggedAnimalsCsvFile(path: str) -> list[list[str]]:
    """Read in the latset/greatest animals CSV file"""
    rows: list[list[str]] = []
    with open(path, "r") as csvfile:
        # create a csv reader object
        csvReader = csv.reader(csvfile)

        # extracting field names through first row
        next(csvReader)

        # extracting each data row one by one
        row: list[str]
        for row in csvReader:
            rows.append(row)
    return rows

def getPathImageIndex(path: Path) -> int:
    """Extracts the image # from the file name"""
    stem = path.stem
    numbers = re.findall(r"\d+", stem)
    fileIndexStr = numbers[0]  # File index # as a string
    fileIndex = int(fileIndexStr)  # File index as a number
    return fileIndex

def determineIfNewGroup(previousPath: Path, currentPath: Path) -> bool:
    """Determines if this is a new image group"""
    # First - if the images are in different folders it's obviously a different group
    if previousPath.parent != currentPath.parent:
        return True

    # If the indexes are not offset by 1, then it's a different group
    previousIndex = getPathImageIndex(previousPath)
    currentIndex = getPathImageIndex(currentPath)
    return (previousIndex + 1) != currentIndex

def main():
    inputFilename = "./animals.final.csv"
    animalRecords = readTaggedAnimalsCsvFile(inputFilename)

    previousPath: Path = Path(r"c:\does_not\exist.png")
    for row in animalRecords:
        tagged = row[0] == "TRUE"
        currentPath = Path(str(row[1]).strip())

        # Determine if this image group starts with a tagged image
        # (which I really don't want for DL training purposes)
        isNewGroup = determineIfNewGroup(previousPath, currentPath)
        if isNewGroup and tagged:
            print(f"Tagged image at start of group: {currentPath}")

        # Prepare for the next loop iteration
        previousPath = currentPath

main()


import svgwrite
import math

GOLDEN_RATIO = 0.618
COLOR = 'blue'

def step_fractal_tree(img, iterations, color, x1, y1, angle, length):
    """
    Recursive procedure creating a line and than calls itself twice for
    making two separate branches.
    """
    x2 = x1 + length*math.sin(math.radians(angle))
    y2 = y1 + length*math.cos(math.radians(180-angle))
    img.add(img.line((x1, y1), (x2, y2), stroke=color))
    if iterations > 1:
        step_fractal_tree(img, iterations - 1, color, x2,
                          y2, angle - 30, 0.7*length)
        step_fractal_tree(img, iterations - 1, color, x2,
                          y2, angle + 30, 0.7*length)

def fractal_tree(img, iterations, size, color):
    """
    Initial step for making a fractal tree.
    """
    step_fractal_tree(img, iterations, color, 0, 0, 0, size)

def step_fractal_triangle(img, iterations, color, triangle_coordinates):
    """
    Makes one iteration of splitting the triangle into four equal triangles.
    Than it recursively continues by splitting three triangles in the corners.
    """
    new = []
    old = triangle_coordinates

    #Finds coordinates for splitting the triangle.
    for i in ([0, 1], [1, 2], [2, 0]):
        new.append([(old[i[0]][0] + old[i[1]][0])/2,
                    (old[i[0]][1] + old[i[1]][1])/2])

    #Makes three lines splitting old triangle into four equal triangles.
    for i in ([0, 1], [1, 2], [2, 0]):
        img.add(img.line(new[i[0]], new[i[1]], stroke=color))

    #Starts recursion on new triangles made in the corners of the old triangle.
    if iterations>1:
        step_fractal_triangle(img, iterations - 1, color,
                              [old[0], new[0], new[2]])
        step_fractal_triangle(img, iterations - 1, color,
                              [new[0], old[1], new[1]])
        step_fractal_triangle(img, iterations - 1, color,
                              [new[2], new[1], old[2]])

def fractal_triangle(img, iterations, size, color):
    """
    Initial step of making Sierpinski triangle. Than it activates the
    recursive procedure of splitting the triangle.
    """
    angle = math.radians(60)
    new = [(0, 0), (size*math.cos(angle), -size*math.sin(angle)), (size, 0)]

    for i in ([0, 1], [1, 2], [2, 0]):
        img.add(img.line(new[i[0]], new[i[1]], stroke=color))

    step_fractal_triangle(img, iterations - 1, color, new)

def golden_fractal_step(img, iterations, color, center, start, dir, mode):
    """
    Recursive procedure for making fractals based on golden spiral.
    """
    p = img.path('m' + str(start[0]) + ',' + str(start[1]),
                 fill = 'none', stroke = color)

    n = (center[1] - start[1], -center[0] + start[0])

    if dir==mode:
        target = (center[0] + n[0], center[1] + n[1])
    else:
        target = (center[0] - n[0], center[1] - n[1])

    next1 = (target[0] + n[0]*GOLDEN_RATIO, target[1] + n[1]*GOLDEN_RATIO)
    next2 = (target[0] - n[0]*GOLDEN_RATIO, target[1] - n[1]*GOLDEN_RATIO)

    p.push_arc(target, r=math.fabs(n[0] + n[1]), rotation=0,
               large_arc=False, absolute=True, angle_dir=dir)
    img.add(p)

    if iterations>1:
        golden_fractal_step(img, iterations - 1, color,
                            next1, target, '-', mode)
        golden_fractal_step(img, iterations - 1, color,
                            next2, target, '+', mode)

def golden_fractal_imp(img, iterations, size, color):
    """
    Initial step for making a fractal based on golden spiral.
    """
    golden_fractal_step(img, iterations - 1, color,
                        (-size,0), (0, 0), '-', '-')
    golden_fractal_step(img, iterations - 1, color,
                        (size,0), (0, 0), '+', '-',)

def golden_fractal_exp(img, iterations, size, color):
    """
    Initial step for making an expansive fractal based on golden spiral.
    """
    golden_fractal_step(img, iterations - 1, color,
                        (-size,0), (0, 0), '-', '+')
    golden_fractal_step(img, iterations - 1, color,
                        (size,0), (0, 0), '+', '+')

def make_fractal(fname, function, iterations, base_size, color):
    """
    General function for creating fractal based on the given function.
    """
    img = svgwrite.Drawing(fname, profile='full')
    function(img, iterations, base_size, color)
    img.save()

#make_fractal("ftree.svg", fractal_tree, 12, 300, COLOR)
#make_fractal("ftriangle.svg", fractal_triangle, 7, 300, COLOR)
#make_fractal('goldenf1.svg', golden_fractal_imp, 10, 300, COLOR)
#make_fractal('goldenf2.svg', golden_fractal_exp, 10, 300, COLOR)


from datetime import date
nascimento = int(input("Qual o ano que você nasceu? "))
alistamento = date.today().year - nascimento

if alistamento < 18:
    print("Você ainda irá se alistar!")
    saldo = 18 - alistamento
    if saldo == 1:
        print("Você terá que se alistar daqui {} ano".format(saldo))
    else:
        print("Você terá que se alistar daqui {} anos".format(saldo))
elif alistamento > 18:
    saldo = alistamento - 18
    print("Você deveria ter se alistado!")
    if saldo == 1:
        print("Deveria ter se alistado a {} ano".format(saldo))
    else:
        print("Deveria ter se alistado a {} anos".format(saldo))
else:
    print("Esta na hora de se alistar!!")


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

from django.db import models, migrations
from django.conf import settings

class Migration(migrations.Migration):

    dependencies = [
        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
    ]

    operations = [
        migrations.CreateModel(
            name='Quote',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('title', models.CharField(max_length=255)),
                ('body', models.TextField()),
                ('type', models.CharField(max_length=15, choices=[(b'internal', b'internal source'), (b'external', b'external source')])),
                ('created', models.DateTimeField(auto_now_add=True)),
                ('image', models.ImageField(null=True, upload_to=b'', blank=True)),
                ('involved', models.ManyToManyField(related_name='quotes', null=True, to=settings.AUTH_USER_MODEL, blank=True)),
                ('poster', models.ForeignKey(to=settings.AUTH_USER_MODEL)),
            ],
            options={
            },
            bases=(models.Model,),
        ),
        migrations.CreateModel(
            name='Screenshot',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
            ],
            options={
            },
            bases=(models.Model,),
        ),
    ]


class Triangle:
    def __init__(self,side1,side2,side3):
         self.side1=side1
         self.side2=side2
         self.side3=side3

    def biggest_side(self):
        sides=[self.side1,self.side2,self.side3]
        bigg_side= max(sides)
        print(f"El mayor lado mide una longitud de : {bigg_side}")

    def return_type_triangle(self) :
        if self.side1==self.side2==self.side3:
            return "equilatero"
        elif self.side1 == self.side2 or self.side1 == self.side3 or self.side2 == self.side3:
            return "isosceles"
        else:
          return "escaleno"


#You're painting a wall the instructions on the paint can says that
# (one can of paint can 5 squares meters) of the wall. Given a random
# height and width of the wall to calculate how many cans of pait you need to buy

import  math

def paint_calc(height, width, cover):
    area = height * width
    num_of_can = math.ceil(area / cover)
    print(f"You'll need {num_of_can} can of paint")

test_h = int(input("Height of the wall: "))
test_w = int(input("Width of the wall: "))
coverage = 5
paint_calc(height= test_h, width= test_w, cover= coverage)


import nltk
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
from scipy import stats
import numpy as np
from nltk.tag import pos_tag
from nltk import word_tokenize
from nltk.corpus import stopwords
import string
from collections import defaultdict
from collections import Counter
from nltk.stem import WordNetLemmatizer
from sklearn.metrics.pairwise import cosine_similarity
import ast
from statannot import add_stat_annotation
import copy
from statistics import mean, stdev
from math import sqrt
#import eval_lib as elib
import linguistic_stats_functions as elib
import sys

stop = stopwords.words('english') + list(string.punctuation)

## these variables are the same as the ones in the last two tables of appendix G
compression = ['text_len_content', 'content_prop',
                          'cont_noun_prop', 'cont_adj_prop', 'cont_verb_prop']
givenness = ['prop_the', 'prop_a',
                        'prop_seen_markers',
                        'prop_givenness_markers']
reuse = ['prop_content_from_prev', 'prop_reused_content_bigrams',
                 'prop_nouns_in_reused_content_tokens', 'prop_adjs_in_reused_content_tokens', 'prop_verbs_in_reused_content_tokens',
                 'prop_nn_content_bigrams_reused']

### functions
def get_prop_tag_content(tag, taglist, wdlist):
    tags = 0
    denom = 0
    for i in range(len(taglist)):
        if wdlist[i] not in stop: ## only content
            denom += 1
            if taglist[i] == tag:
                tags += 1
    return np.NaN if denom < 1 else tags/denom

if len(sys.argv) == 1:
    print('specify files to process as a list of command line arguments')
    sys.exit()

## Create dataframe from output files
print('loading files...')
files = sys.argv[1:]
#files = ['all_copy_TEST.txt', 'all_base_TEST.txt', 'all_histatt_TEST.txt']
print(files)
res = elib.get_dataframe_from_files(files)
#res.to_csv('model_output_summary.csv')

## Calculate stats
print('tagging...')
res['tags'] = res.apply(lambda row: [item[1] for item in pos_tag(row.text, tagset='universal')], axis = 1)
res['prev_tokens'] = res.apply(lambda row: [item[1] for item in pos_tag(row.prev_utt_full, tagset='universal')], axis = 1)

res['content_text'] = res.apply(lambda row: [i for i in row.text if i not in stop], axis = 1)
res['content_tokens'] = res.apply(lambda row: elib.content_tag_list(row.text, row.tags), axis = 1)
res['content_prev'] = res.apply(lambda row: [i for i in row.prev_utt_full if i not in stop], axis = 1)
res['content_tokens_prev'] = res.apply(lambda row: elib.content_token_list(row.prev_utt_full, row.prev_tokens), axis = 1)

res['reused_wds'] = res.apply(lambda row:  elib.get_shared_words(row.text, row.prev_utt_full), axis = 1)
res['reused_tags'] = res.apply(lambda row:  elib.get_shared_wd_tags(row.text, row.prev_utt_full, row.tags), axis = 1)

print('compression stats...')
res['text_len_content'] = res.apply(lambda row: len(row.content_text), axis = 1)
res['content_prop'] = res.apply(lambda row: elib.content_prop_text(row.text), axis = 1)

res['temp'] = res.apply(lambda row: elib.content_token_prop(row.text), axis = 1)
res['cont_adj_prop'] = res.apply(lambda row: row.temp[0], axis = 1)
res['cont_verb_prop'] = res.apply(lambda row: row.temp[1], axis = 1)
res['cont_noun_prop'] = res.apply(lambda row: row.temp[2], axis = 1)

print('givenness stats...')
res['prop_givenness_markers'] = res.apply(lambda row: elib.prop_givenness(row.text), axis = 1)
res['prop_the'] = res.apply(lambda row: elib.prop_the(row.text), axis = 1)
res['prop_a'] = res.apply(lambda row: elib.prop_a(row.text), axis = 1)
res['prop_seen_markers'] = res.apply(lambda row: elib.prop_seen_markers(row.text), axis = 1)

print('reuse stats...')

res['prop_content_from_prev'] = res.apply(lambda row:   elib.prop_content_reused(row.text, row.prev_utt_full), axis = 1)

res['content_bigrams'] = res.apply(lambda row: elib.get_content_bigram_strings(row.text), axis = 1)
res['content_bigrams_prev'] = res.apply(lambda row: elib.get_content_bigram_strings(row.prev_utt_full), axis = 1)
res['count_content_bigrams_reused'] = res.apply(lambda row: elib.count_words_reused(row.content_bigrams_prev, row.content_bigrams), axis = 1)
res['prop_reused_content_bigrams'] = res.apply(lambda row: row.count_content_bigrams_reused/float(max(1, len(row.content_bigrams))), axis = 1)

res['prop_nouns_in_reused_content_tokens'] = res.apply(lambda row:  elib.get_prop_tag_content('NOUN', row.reused_tags, row.reused_wds), axis = 1)
res['prop_adjs_in_reused_content_tokens'] = res.apply(lambda row:  elib.get_prop_tag_content('ADJ', row.reused_tags, row.reused_wds), axis = 1)
res['prop_verbs_in_reused_content_tokens'] = res.apply(lambda row:  elib.get_prop_tag_content('VERB', row.reused_tags, row.reused_wds), axis = 1)

res['prop_nn_content_bigrams_reused'] = res.apply(lambda row:   elib.prop_nn_bigrams_reused(row.text, row.tags, row.prev_utt_full), axis = 1)

#res.to_csv('model_output_summary_stats.csv')
res['mention'] = res.first_mention

## firstly calculate the compression and givenness stats: first vs the later are compared
rows = []
cols = ['comparison', 'model', 'version', 'meanFirst', 'meanLater', 'cohensD', 'sig', 'pval', 'tstat']
aspects = compression + givenness
for aspect in aspects:
    for version in res.version.unique():
        row = elib.compare(res, 'first', 'later', version, aspect, aspect)
        rows.append(row)
first_later = pd.DataFrame(rows, columns=cols)
first_later.to_csv('firstVlater_stats_out.csv')

## now reuse: only the later utterances are inspected: thus we test differences between human and model
cols = ['comparison', 'model', 'version', 'meanHuman', 'meanGenerated', 'cohensD', 'sig', 'pval', 'tstat', 'mention']
rows = []
versions = res.version.unique()
versions = [i for i in versions if i not in ['origional']]
human = 'origional'
for col_name in reuse:
    mention = 'later'
    for version in versions:
        row = elib.get_rows(res, version, mention, human, col_name)
        rows.append(row)
reuse = pd.DataFrame(rows, columns=cols)
reuse.to_csv('reuse_stats_out.csv')


from text_embeddings.preprocessing.read_pdf import *
from user_interface.cli import *
import gensim
from gensim.models import Word2Vec

'''------Different word embeddings-------'''

def main(file_paths: list):
    # https://www.geeksforgeeks.org/python-word-embedding-using-word2vec/

    lower_case_tokens = []
    for path in file_paths:
        text = pdf_to_str(path)

        tokens = tokenize(text)
        lower_case_tokens.append(list(map(lambda x: x.lower(), tokens)))

    # Create CBOW model of both files
    model1 = gensim.models.Word2Vec(lower_case_tokens, min_count = 1, vector_size = 100, window = 5)

    # Print results
    print("Cosine similarity between 'bahamas' " + "and 'wealth' - CBOW : ", model1.wv.similarity('bahamas', 'wealth'))

    print("Cosine similarity between 'bahamas' " + "and 'credit' - CBOW : ", model1.wv.similarity('bahamas', 'credit'))

    # Create Skip Gram model of both files
    model2 = gensim.models.Word2Vec(lower_case_tokens, min_count = 1, vector_size = 100, window = 5, sg = 1)

    # Print results
    print("Cosine similarity between 'bahamas' " + "and 'wealth' - Skip Gram : ", model2.wv.similarity('bahamas', 'wealth'))

    print("Cosine similarity between 'bahamas' " + "and 'credit' - Skip Gram : ", model2.wv.similarity('bahamas', 'credit'))