import os
from typing import Union

from constructs import Construct
from aws_cdk import (
    Stack,
    aws_appsync as appsync,
    aws_iam as iam,
    Duration,
    aws_cognito as cognito,
    aws_dynamodb as dynamodb,
    aws_lambda,
)

# https://adrianhesketh.com/2021/02/22/setting-up-appsync-graphql-subscriptions-with-typescript-and-cdk/

class WebsocketsApi(Construct):
    @property
    def graphql_url(self):
        return self._api.graphql_url

    @property
    def graphql_endpoint_name(self):
        return self._graphql_enpoint_name

    def __init__(
        self,
        scope: Construct,
        id: str,
        user_pool_arn: str,
        user_pool_client_id: str,
        query_messages_fn: aws_lambda.Function,
        send_message_fn: aws_lambda.Function,
        request_ai_response_fn: aws_lambda.Function,
        delete_all_messages_fn: aws_lambda.Function,
        **kwargs
    ):
        super().__init__(scope, id, **kwargs)

        self._graphql_enpoint_name = "ChatDemoApi"

        self._api = appsync.GraphqlApi(
            self,
            "Api",
            name=self._graphql_enpoint_name,
            schema=appsync.SchemaFile.from_asset("../shared/schema.graphql"),
            authorization_config=appsync.AuthorizationConfig(
                default_authorization=appsync.AuthorizationMode(
                    authorization_type=appsync.AuthorizationType.USER_POOL,
                    user_pool_config=appsync.UserPoolConfig(
                        user_pool=cognito.UserPool.from_user_pool_arn(
                            self, "UserPool", user_pool_arn
                        ),
                        default_action=appsync.UserPoolDefaultAction.ALLOW,
                    ),
                )
            ),
            xray_enabled=True,
        )

        query_messages_source = self._api.add_lambda_data_source(
            "QueryMessagesSource",
            query_messages_fn,
        )

        query_messages_source.create_resolver(
            "QueryMessageResolver",
            type_name="Query",
            field_name="messages",
        )

        send_message_source = self._api.add_lambda_data_source(
            "SendMessageSource",
            send_message_fn,
        )

        send_message_source.create_resolver(
            "SendMessageResolver",
            type_name="Mutation",
            field_name="sendMessage",
        )

        request_ai_response_source = self._api.add_lambda_data_source(
            "RequestAiResponseSource",
            request_ai_response_fn,
        )

        request_ai_response_source.create_resolver(
            "RequestAiResponseResolver",
            type_name="Mutation",
            field_name="requestAiResponse",
        )

        delete_all_messages_source = self._api.add_lambda_data_source(
            "DeleteAllMessagesSource",
            delete_all_messages_fn,
        )

        delete_all_messages_source.create_resolver(
            "DeleteAllMessagesResolver",
            type_name="Mutation",
            field_name="deleteAllMessages",
        )


"""
Author: Paloma Arellano, arellanp@purdue.edu
Assignment: 01.2 - Interest
Date: 09/04/2022

Description:
    This program displays the balance of the user's bank acccount
    after a certain number of years they input. The program uses
    inputs for intial depost, interest rate, time to earn interest,
    and number of times the interest is compounded per year.

Contributors:
    Name, login@purdue.edu [repeat for each]

My contributor(s) helped me:
    [ ] understand the assignment expectations without
        telling me how they will approach it.
    [ ] understand different ways to think about a solution
        without helping me plan my solution.
    [ ] think through the meaning of a specific error or
        bug present in my code without looking at my code.
    Note that if you helped somebody else with their code, you
    have to list that person as a contributor.

Academic Integrity Statement:
    I have not used source code obtained from any unauthorized
    source, either modified or unmodified; nor have I provided
    another student access to my code.  The project I am
    submitting is my own original work.
"""

"""Import additional modules below this line (starting with unit 6)."""

"""Write new functions below this line (starting with unit 4)."""

def main():
    print("Enter the following parameters.")
    deposit = float(input("  The initial deposit? "))                              # intital deposit
    interest = float(input("  The annual interest rate in percent? "))                 # annual interest rate (%)
    years = float(input("  The number of years the account earn interest? "))         # years the account earns interest
    times = float(input("  The number of times interest is compounded each year: "))  # number of times interest is compounded per year

    balance = deposit * (1 + ((interest / 100) / times)) ** (times * years)
    print("The balance of this account will be $" + "{:,.2f}".format(balance) + " after " + "{:,.1f}".format(years) + " years.")

"""Do not change anything below this line."""
if __name__ == "__main__":
    main()


import math
import argparse
import time
import pyautogui
import numpy
import os
from matplotlib import pyplot
from rtlsdr import *
import webbrowser
import folium

#args
def set_vars():
    parser = argparse.ArgumentParser()
    parser.add_argument("-Tx","--Transmission_Frequency",type=float,help="The transmission frequency(MHz) of your target. (default"
                                                              ":46.515)", default=46.515)
    parser.add_argument("-w", "--Wattage",type=int, help= "The transmission wattage the target frequency is transmitting at. (de"
                                                 "faults:40). Reference: https://wireless2.fcc.gov/UlsApp/UlsSearch/sea"
                                                 "rchLicense.jsp; ", default=40)
    parser.add_argument("-lat","--Latitude", type=float,help="Your Latitude.(default:40)", default=40)
    parser.add_argument("-lon","--Longitude", type=float,help="Your Longitude (default:40)", default=40)
    parser.add_argument("-u","--Update_time", type=int, help="The time between map updates in seconds. (default:10)", default=10)
    #parser.add_argument("-sr", "--Sample_Rate", help="The sample rate of your SDR. (default:auto)", default=None)
    parser.add_argument("-g", "--Gain",type=float, help="SDR Gain. (Automatic if no option provided)", default=None)
    parser.add_argument("-o", "--Overestimate_Distance",type=float, help="Distance overestimation to make up for inaccurate inverse square law.", default=1.3)
    parser.add_argument("-Txd1", "--Transmission_RP_Distance", type=float,help="Tx reference-point distance, This is how far away you a"
                                                               "re on the first received transmission. This is a const"
                                                               "ant in meters >1. (default:1)", default=1)

    return parser.parse_args()

if __name__ == '__main__':
    args = set_vars()

    #gets wattage power from dbm, an unnecessary step and I'm not changing it now.
    def get_watts(dbm):
        return (10 ** (dbm/ 10))/1000
    #return distance from a src using inverse square law
    def get_dist(I1, I2,d1):
        return math.sqrt((I1/I2)*(d1**2)) * args.Overestimate_Distance

    coordinates=[args.Latitude, args.Longitude]
    mapObj=folium.Map(location=coordinates, zoom_start=17)
    mapObj.save('output.html')
    #init_sdr
    sdr = RtlSdr()
    tx_pow = args.Wattage
    sdr.center_freq = args.Transmission_Frequency*1e6
    center_freq_cmp_val=numpy.float64(sdr.center_freq / 1e6)
    if args.Gain is None:
        sdr.gain= 'auto'
    else:
        sdr.gain=args.Gain
    print("Listening on: " + str(center_freq_cmp_val))
    max = 10.2
    dist = 2.8
    #check for output file existing.
    if os.path.exists(os.path.realpath("output.html")):
        webbrowser.open('file://' + os.path.realpath("output.html"), new=0)
    else:
        with open('output.html', 'w') as f:
            f.write('Building map...')
            f.close()
        webbrowser.open('file://' + os.path.realpath("output.html"), new=0)
    #read from SDR.
    avg_dist = 1
    circle = folium.Circle(radius=avg_dist, location=coordinates).add_to(mapObj)
    while True:
        dists = []
        for z in range(100):
            samples = sdr.read_samples(1024)
            ok = pyplot.psd(samples, NFFT=1024, Fs=sdr.sample_rate / 1e6, Fc=sdr.center_freq / 1e6)
            pyplot.xlabel('Frequency (MHz)')
            pyplot.ylabel('Relative power (dB)')
            for y,x in enumerate(ok[1]):
                rx_watts = get_watts(ok[0][y])
                dist = get_dist(tx_pow,rx_watts,args.Transmission_RP_Distance)
                dists.append(dist)

        avg_dist = sum(dists) / 100000
        dists = []
        if avg_dist > max:
            max = float(dist)

        print("\nrcv dbm: "+str(ok[0][y]) )
        print("rcv wat: "+str(rx_watts))
        print("clc dist: "+ str(avg_dist) + "m\n" )

        #Ensure you have some kind of actionable data.
        if max > 20:
            circle.options['radius'] = avg_dist
            circle.render()
            os.remove(os.path.realpath('output.html'))
            mapObj.save('output.html')
            pyautogui.hotkey('f5')
            time.sleep(args.Update_time)


#Asks for user input for the weight of the package
print("Welcome to Sal's Shipping Company!")
weight = float(input("What is the weight of your package, in total pounds?\n"))
cost = 0

print("Calculating......\n")

#Ground Shipping Cost
gship = 0.0
flat_charge = 20.00
if weight <= 2.00:
    cost = 1.50 * weight + flat_charge
elif  2 <= weight <= 6:
     cost = 3.00 * weight + flat_charge
elif 6 <= weight <= 10:
    cost = 4.00 * weight + flat_charge
elif weight >= 10:
    cost = 4.75 * weight + flat_charge
else:
    print ("Error")
gship = cost
print("Ground Shipping Total:$ ", gship, "\n")

#Ground Shipping Premium Cost
gship_premium = 125.00
print("Ground Shipping Premium: $", gship_premium, "\n")

#Drone Shipping Cost
dship = 0.0
if weight <= 2.00:
    cost = 4.50 * weight
elif  2 <= weight <= 6:
     cost = 9.00 * weight
elif 6 <= weight <= 10:
    cost = 12.00 * weight
elif weight >= 10:
    cost = 14.25 * weight
else:
    print ("Error")
dship = cost
print("Drone Shipping: $", dship, "\n")

#Choses the cheapest option
list = [gship, gship_premium, dship]
if min(list) == gship:
    print("Best Deal is Ground Shipping: $", gship)
elif min(list) == gship_premium:
    print( "Best Deal is Ground Shipping Premium: $", gship_premium)
elif min(list) == dship:
    print("Best Deal is Drone Shipping: $", dship)
else:
    print("Error")


"""
Fits linear-log models to the instability v. memory, instability v. dimension,
and instability v. precision trends.
"""

import argparse
import pandas as pd
import numpy as np
import functools
import scipy.stats

def parse_args():
    parser = argparse.ArgumentParser()
    parser.add_argument('--csv-files', type=str, nargs='+', required=True,
        help='CSV file (list) with pair results for emb metrics and DS results')
    parser.add_argument('--tasks', type=str, nargs='+',
        default=[
            'la_sst_no_emb_norm',
            'la_mr_no_emb_norm',
            'la_subj_no_emb_norm',
            'la_mpqa_no_emb_norm',
            'rnn_no_crf_ner'],
        help='List of downstream metrics')
    parser.add_argument('--thresh', type=int, default=1000,
        help='Maximum memory budget')
    parser.add_argument('--dim', action='store_true',
        help='Fit the trend with respect to dimension')
    parser.add_argument('--prec', action='store_true',
        help='Fit the trend with respect to precision')
    return parser.parse_args()

def solve_lstsq_combine(dfs, thresh, tasks):
    """
    Fit a single trend to the downstream stability v. memory results across
    embedding algorithms and downstream tasks.
    """
    ncombos = len(tasks) * len(dfs)
    space_vals = np.log2(dfs[0].loc[dfs[0]['space'] < thresh]['space'].values)
    num_vals = len(space_vals)
    X = np.zeros((num_vals*len(tasks) * len(dfs), ncombos+1))
    y = np.zeros((num_vals*len(tasks) * len(dfs)))
    for i, df in enumerate(dfs):
        # Only consider those results less than thresh space budget
        df_subset = df.loc[df['space'] < thresh]
        for j, t in enumerate(tasks):
            idx = i*len(tasks) + j
            y[idx*num_vals:(idx+1)*num_vals] = df_subset[t].values
            # First column is the log2(m) results
            X[idx*num_vals:(idx+1)*num_vals][:,0] = space_vals
            # Append a 1-hot vector to learn a separate y-intercept per task
            X[idx*num_vals:(idx+1)*num_vals][:,idx+1] = np.ones(num_vals)
    # print(f'Dimensions of data matrix: {X.shape}')
    return np.linalg.inv(X.T @ X) @ X.T @ y

def solve_lstsq_combine_prec(dfs, thresh, tasks, dims=[25, 50, 100, 200, 400, 800]):
    """
    Fit a single trend to the downstream stability v. *precision* results across
    embedding algorithms and downstream tasks and *dimensions*.
    """
    ncombos = len(tasks) * len(dfs) * len(dims)
    num_vals = len(dfs[0].loc[(dfs[0]['space'] < thresh)]['space'].values)
    X = np.zeros((num_vals*len(tasks)*len(dfs), ncombos+1))
    y = np.zeros((num_vals*len(tasks)*len(dfs)))
    row_idx = 0
    col_idx = 0
    for i, df in enumerate(dfs):
        for j, t in enumerate(tasks):
            for k,dim in enumerate(dims):
                df_subset = df.loc[(df['space'] < thresh) & (df['dim'] == dim)]
                prec_vals = np.log2(df_subset['bitrate'].values)
                # Number of values diffs by dimension
                num_vals = len(prec_vals)
                y[row_idx:row_idx+num_vals] = df_subset[t].values
                X[row_idx:row_idx+num_vals][:,0] = prec_vals
                X[row_idx:row_idx+num_vals][:,col_idx+1] = np.ones(num_vals)
                row_idx += num_vals
                # Learn a different y-intercept for each algo/task/dim combination
                col_idx += 1
    # print(f'Dimensions of data matrix: {X.shape}')
    return np.linalg.inv(X.T @ X) @ X.T @ y

def solve_lstsq_combine_dim(dfs, thresh, tasks, bitrates=[1,2,4,8,16,32]):
    """
    Fit a single trend to the downstream stability v. *dimension* results across
    embedding algorithms and downstream tasks and *precisions*.
    """
    ncombos = len(tasks) * len(dfs) * len(bitrates)
    num_vals = len(dfs[0].loc[(dfs[0]['space'] < thresh)]['space'].values)
    X = np.zeros((num_vals*len(tasks)*len(dfs), ncombos+1))
    y = np.zeros((num_vals*len(tasks)*len(dfs)))
    row_idx = 0
    col_idx = 0
    for i, df in enumerate(dfs):
        for j, t in enumerate(tasks):
            for k, bitrate in enumerate(bitrates):
                df_subset = df.loc[(df['space'] < thresh) & (df['bitrate'] == bitrate)]
                space_vals = np.log2(df_subset['dim'].values)
                # Number of values diffs by precision
                num_vals = len(space_vals)
                y[row_idx:row_idx+num_vals] = df_subset[t].values
                X[row_idx:row_idx+num_vals][:,0] = space_vals
                X[row_idx:row_idx+num_vals][:,col_idx+1] = np.ones(num_vals)
                row_idx += num_vals
                # Learn a different y-intercept for each algo/task/prec combination
                col_idx += 1
    # print(f'Dimensions of data matrix: {X.shape}')
    return np.linalg.inv(X.T @ X) @ X.T @ y

def main():
    args = parse_args()
    dfs = []
    for file in args.csv_files:
        dfs.append(pd.read_csv(file))
    if args.dim:
        print('Instability v. dimension trend')
        m = solve_lstsq_combine_dim(dfs=dfs, thresh=args.thresh, tasks=args.tasks)
    elif args.prec:
        print('Instability v. precision trend')
        m = solve_lstsq_combine_prec(dfs=dfs, thresh=args.thresh, tasks=args.tasks)
    else:
        print('Instability v. memory trend')
        m = solve_lstsq_combine(dfs=dfs, thresh=args.thresh, tasks=args.tasks)
    print(f'Slope: {m[0]}')
    print(f'y-intercepts: {m[1:]}')

if __name__ == '__main__':
    main()


import requests
from operator import itemgetter

# Make an API call and store the response
url = "https://hacker-news.firebaseio.com/v0/topstories.json"
r = requests.get(url)
if r.status_code == 200:
    print("Processing")
else:
    print("Error", r.status_code)
    exit(1)

# Process information about each submission
submission_ids = r.json()
submission_dicts = []

for id in submission_ids[:30]:
    url = "https://hacker-news.firebaseio.com/v0/item/" + str(id) + ".json"
    r = requests.get(url)
    if r.status_code != 200:
        print("Error: ", r.status_code)
    submission_item = r.json()
    submission_dict = {
       'title': submission_item['title'],
       'link': submission_item['url'],
       'comments': submission_item.get('descendants', 0)
       }
    submission_dicts.append(submission_dict)

submission_dicts = sorted(submission_dicts, key=itemgetter('comments'),
                          reverse=True)

for item in submission_dicts:
    print("\nTitle:", item['title'])
    print("Discussion link:", item['link'])
    print("Coments: ", item['comments'])


"""
El usuario introduce dos números y la función retornará si es PAR o IMPAR.
"""
def parNoPar():
    numero = int(input("Introduce un número: "))
    if numero%2==0:
        mensaje=("{numero} es PAR".format(numero=numero))
    else:
        mensaje=("{numero} es IMPAR".format(numero=numero))
    return mensaje

print(parNoPar())


import logging
import re
import itertools

import xmltodict
import requests
from selinon import SelinonTask
from selinon import StoragePool
from selinon.errors import NoParentNodeError

_LOGGER = logging.getLogger(__name__)

class StackOverflowKeywordsAggregationTask(SelinonTask):
    """Aggregate keywords from StackOverflow."""

    _STACKOVERFLOW_URL = (
        "https://archive.org/download/stackexchange/stackoverflow.com-Tags.7z"
    )

    def run(self, node_args: dict) -> dict:
        """Aggregate StackOverflow keywords."""
        # Move import here as we run this task locally, there are issues with libarchive.so in Python's s2i.
        import libarchive.public

        response = requests.get(self._STACKOVERFLOW_URL)
        if not response.ok:
            raise RuntimeError(
                "Failed to fetch stack overflow tags, request ended with status code %s: %s",
                response.status_code,
                response.text,
            )

        tags = None
        with libarchive.public.memory_reader(response.content) as archive:
            for entry in archive:
                tags = xmltodict.parse(b"".join(entry.get_blocks()))
                break

        result = {}
        for tag in tags["tags"]["row"]:
            try:
                result[tag["@TagName"]] = int(tag["@Count"])
            except ValueError:
                _LOGGER.warning(
                    "Failed to parse number of occurrences for tag %s", tag["@TagName"]
                )
                continue
            except KeyError:
                _LOGGER.exception("Missing tagname or tag count")
                continue

        return result

class KeywordsAggregationTask(SelinonTask):
    """Combine keywords from multiple sources and aggregate it into a single dict used in model creation."""

    def run(self, node_args: dict) -> dict:
        """Combine keywords from multiple sources."""
        result = {}
        for i in itertools.count():
            try:
                keywords = self.parent_flow_result(
                    "_pypi_keywords_flow", "PyPIProjectKeywordsTask", i
                )
            except NoParentNodeError:
                # This exception is raised if there are no more parent tasks.
                break

            for keyword, count in keywords.items():
                if keyword not in result:
                    result[keyword] = 0

                result[keyword] += count

        return result

class PyPIProjectKeywordsTask(SelinonTask):
    """Get keywords for a single project."""

    def run(self, node_args: dict) -> dict:
        package_name = node_args["package_name"]
        project_info_store = StoragePool.get_connected_storage("ProjectInfoStore")
        document = project_info_store.retrieve_project_info(package_name)

        keywords = document.get("info", {}).get("keywords") or ""
        keywords = re.split(r"[\s+,;]", keywords)

        keywords_dict = {}
        for keyword in keywords:
            if not keyword:
                continue

            keyword = keyword.lower()
            keywords_dict[keyword] = keywords_dict.get(keyword, 0) + 1

        return keywords_dict


from rest_framework import status
from rest_framework.response import Response
from rest_framework.decorators import api_view

from core.serializers import MetalSerializer
from core.models import Metal, CodeParameter
from core.utils import MetalStockUpdation

@api_view(['GET', 'POST'])
def credit_debit_metal(request):
    if request.method == 'GET':
        metals = Metal.objects.all()
        serializer = MetalSerializer(metals, many=True)
        return Response(serializer.data)

    elif request.method == 'POST':

        serializer = MetalSerializer(data=request.data)
        if serializer.is_valid():

            is_credit = bool(request.data['is_credit'])
            quantity = round(float(request.data['quantity']), 3)
            MetalStockUpdation.update_all_metal_stock(is_credit, quantity)
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

@api_view(['GET'])
def get_current_metal_stock(request):
    if request.method == 'GET':
        cp_current_metal_stock = CodeParameter.objects.get(parameter_name='current_metal_stock')
        return Response(cp_current_metal_stock.parameter_value)


# em geral usado com detecção de bordas. Params:
# * Gamma correction: deixa mais claro ou escuro, dependendo do valor de gamma
# * kernel: uma matrix que pega os NxN pixels mais próx e multiplica por ctes e, por fim, soma os valores e devolve o
#           valor do novo pixel
# Existe o problema com as bordas laterais da img que não possuem os NxN necessários para cálculo

import cv2
import matplotlib.pyplot as plt
import numpy as np

def load_img():
    img = cv2.imread('../DATA/bricks.jpg').astype(np.float32) / 255
    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    return img

def display_img(img):
    fig = plt.figure(figsize=(12, 6))
    ax = fig.add_subplot(111)
    ax.imshow(img)

i = load_img()
# display_img(i)

# gamma claro
gamma = 1/4
result = np.power(i, gamma)
# display_img(result)

# gamma escuro
gamma = 8
result = np.power(i, gamma)
# display_img(result)

# escrita
img = load_img()
font = cv2.FONT_HERSHEY_COMPLEX
cv2.putText(img, text='Bricks', org=(10, 600), fontFace=font, fontScale=10, color=(255, 0, 0), thickness=4)
# display_img(img)

# criando kernel: uma matriz 5x5 de valores = 0.04
kernel = np.ones(shape=(5, 5), dtype=np.float32) / 25

dst = cv2.filter2D(img, -1, kernel)
# display_img(dst)

# outro experimento: resetando a img
img = load_img()
font = cv2.FONT_HERSHEY_COMPLEX
cv2.putText(img, text='Bricks', org=(10, 600), fontFace=font, fontScale=10, color=(255, 0, 0), thickness=4)

blurred = cv2.blur(img, ksize=(5, 5))
# display_img(blurred)

blurred = cv2.blur(img, ksize=(10, 10))
# display_img(blurred)

# outro experimento: resetando a img
img = load_img()
font = cv2.FONT_HERSHEY_COMPLEX
cv2.putText(img, text='Bricks', org=(10, 600), fontFace=font, fontScale=10, color=(255, 0, 0), thickness=4)

blurred = cv2.GaussianBlur(img, (5, 5), 10)
# display_img(blurred)

# outro experimento: resetando a img
img = load_img()
font = cv2.FONT_HERSHEY_COMPLEX
cv2.putText(img, text='Bricks', org=(10, 600), fontFace=font, fontScale=10, color=(255, 0, 0), thickness=4)

# como o kernel é uma matrix quadrada por default, passamos apenas um nº
blurred = cv2.medianBlur(img, 5)
# display_img(blurred)

# outro experimento: resetando a img
img = load_img()
font = cv2.FONT_HERSHEY_COMPLEX
cv2.putText(img, text='Bricks', org=(10, 600), fontFace=font, fontScale=10, color=(255, 0, 0), thickness=4)

# é um blur que mantém as letras mais visíveis, embaçando o fundo
blurred = cv2.bilateralFilter(img, 9, 75, 75)
display_img(blurred)

# outra img
img = cv2.imread('../DATA/sammy.jpg')
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
display_img(img)

img_noise = cv2.imread('../DATA/sammy_noise.jpg')
img_noise = cv2.cvtColor(img_noise, cv2.COLOR_BGR2RGB)
display_img(img_noise)

median = cv2.medianBlur(img_noise, 5)
display_img(median)

plt.show()

03 Image Processing/03 Blurring and Smoothing.py


import os
os.chdir("/home/kimjh/2022_gigascience/")

import torch
import numpy as np
from torch.utils.data import TensorDataset, DataLoader
from config import *
from torch.utils.data import DataLoader, Dataset
import cv2
import torchvision.transforms as transforms
from src.normalize import normalize_individual_image

class CustomDataset(Dataset):
    def __init__(self, images : np.array,
                        label_list : np.array,
                        train_mode=True,
                        transforms=None):
        self.transforms = transforms
        self.train_mode = train_mode
        # self.img_path_list = img_path_list
        self.images = images
        self.label_list = label_list

    def __getitem__(self, index):
        image = self.images[index]
        # Get image data
        # image = cv2.imread(img_path)
        if self.transforms is not None:
            image = self.transforms(image)

        if self.train_mode:
            label = self.label_list[index]
            return image, label
        else:
            return image

    def __len__(self):
        return len(self.images)

class AddGaussianNoise(object):
    def __init__(self, mean=0., std=1.):
        self.std = std
        self.mean = mean

    def __call__(self, tensor):
        return tensor + torch.randn(tensor.size()) * self.std + self.mean

    def __repr__(self):
        return self.__class__.__name__ + '(mean={0}, std={1})'.format(self.mean, self.std)

train_transform = transforms.Compose([
    transforms.RandomRotation(20),
    transforms.RandomHorizontalFlip(),
    transforms.RandomVerticalFlip(),
])

test_transform = transforms.Compose([
                ])

def get_augmentation_dataset(x_train_path, y_train_path, x_valid_path, y_valid_path, x_test_path, y_test_path):

    train_df = torch.Tensor(np.float64(np.load(x_train_path))).unsqueeze(1)
    train_dataset = CustomDataset(train_df, torch.LongTensor(np.load(y_train_path)), train_mode=True, transforms=train_transform)

    valid_df = torch.Tensor(np.float64(np.load(x_valid_path))).unsqueeze(1)
    valid_dataset = CustomDataset(valid_df ,torch.LongTensor(np.load(y_valid_path)), train_mode=True, transforms=test_transform)

    test_df = torch.Tensor(np.float64(np.load(x_test_path))).unsqueeze(1)
    test_dataset = CustomDataset(test_df , torch.LongTensor(np.load(y_test_path)), train_mode=True, transforms=test_transform)

    return train_dataset, valid_dataset, test_dataset

def get_augmentation_loader(train, valid, test, batch_size):
    loader = {}

    loader['train'] = DataLoader(train, batch_size = batch_size, shuffle = True,  pin_memory = True, num_workers=8)
    loader['valid'] = DataLoader(valid, batch_size = batch_size, shuffle = False,  pin_memory = True, num_workers=8)
    loader['test'] = DataLoader(test, batch_size = batch_size,  shuffle = False, pin_memory = True, num_workers=8)

    return loader

def get_test_augmentation_loader(test, batch_size):
    loader = {}
    loader['test'] = DataLoader(test, batch_size = batch_size,  shuffle = False, pin_memory = True)
    return loader

def get_test_augmentation_dataset(x_test_path, y_test_path):
    test_df = torch.Tensor(normalize_individual_image(np.load(x_test_path).astype('float64'))).unsqueeze(1)
    test_dataset = CustomDataset(test_df , torch.LongTensor(np.load(y_test_path)), train_mode=True, transforms=test_transform)
    return test_dataset

def get_augmentation_blind_dataset(x_train_path, y_train_path, x_valid_path, y_valid_path, x_test_path, y_test_path):

    train_df = torch.Tensor(normalize_individual_image(np.load(x_train_path))).unsqueeze(1)
    train_dataset = CustomDataset(train_df, torch.LongTensor(np.load(y_train_path)), train_mode=True, transforms=train_transform)

    valid_df = torch.Tensor(normalize_individual_image(np.load(x_valid_path))).unsqueeze(1)
    valid_dataset = CustomDataset(valid_df ,torch.LongTensor(np.load(y_valid_path)), train_mode=True, transforms=test_transform)

    test_df = torch.Tensor(normalize_individual_image(np.load(x_test_path))).unsqueeze(1)
    test_dataset = CustomDataset(test_df , torch.LongTensor(np.load(y_test_path)), train_mode=True, transforms=test_transform)

    return train_dataset, valid_dataset, test_dataset


import configparser

class PolicyGradientParameters:
    """Parameters used by Policy Gradient algorithms."""

    def __init__(self, config_file):
        """Read parameter values from config_file.

        Use default value if the parameter is not present.
        """
        self.config = configparser.ConfigParser()
        self.config.optionxform = str
        self.config.read(config_file)

        # Discount factor.
        self.gamma = self.config.getfloat(
            'General', 'Gamma', fallback=0.95)

        # Name of class that does preprocessing.
        self.preprocessing = self.config.get(
            'General', 'PreProcessing', fallback='')

        # Arguments (except the first argument input_shape) of preprocessing as
        # a tuple.
        self.preprocessing_args = self.config.get(
            'General', 'PreProcessingArgs', fallback='()')

        # If true, policy pi and value function V share all non-output layers.
        # PolicyRepresentation (and/or PolicyNetworkHiddenLayers) define
        # structure for all non-output layers. Policy then has one softmax
        # output layer, and value function has one linear output layer. If
        # false, all non-output layers of policy are still specified by
        # PolicyRepresentation. This is equivalent to defining unnormalized log
        # of policy pi. The value function, however, is completely specified by
        # ValueFunctionRepresentation (and/or ValueNetworkHiddenLayers), which
        # outputs a scalar.
        self.shared_representation = self.config.getboolean(
            'PolicyGradient', 'SharedRepresentation', fallback=False)

        # Representation of policy.
        self.policy_representation = self.config.get(
            'PolicyGradient', 'PolicyRepresentation', fallback='nn')

        # Suppose gradient of policy network is g, gradient of value network
        # is gv, during each update, policy network is updated as
        # \theta <- \theta + \eta * g where \eta is learning rate, and
        # value network is updated as
        # \theta_v <- \theta_v + \eta * relative_step_size * gv. This allows
        # policy network and value network to be updated at different learning
        # rates. Alternatively, this can be viewed as relative weight between
        # policy loss and value function loss.
        self.relative_step_size = self.config.getfloat(
            'PolicyGradient', 'RelativeStepSize', fallback=0.5)

        # Weight of regularization term.
        self.regularization_weight = self.config.getfloat(
            'PolicyGradient', 'RegularizationWeight', fallback=0.001)

        # Number of nodes in each hidden layer of policy network.
        self.policy_network_hidden_layers = self.config.get(
            'NetworkModel', 'PolicyNetworkHiddenLayerNodes', fallback='[10]')

        # Representation of value function.
        self.value_function_representation = self.config.get(
            'PolicyGradient', 'ValueFunctionRepresentation', fallback='nn')

        # Number of nodes in each hidden layer of value network.
        self.value_network_hidden_layers = self.config.get(
            'NetworkModel', 'ValueNetworkHiddenLayerNodes', fallback='[10]')

        # Initial value of eta, which is the learning rate for gradient descent.
        self.initial_eta = self.config.getfloat(
            'Optimization', 'InitialEta', fallback=0.001)

        # Number of steps before eta reaches minimum value.
        self.eta_decay_step_count = self.config.getint(
            'Optimization', 'EtaDecayStepCount', fallback=100000)

        # Minimum value of eta. Since Adam is used as the optimizer, a good
        # starting point is to set EtaMinimum equal to InitialEta, which is
        # equivalent to using a constant global learning rate cap, while Adam
        # continuously adapts individual parameter learning rates.
        self.eta_minimum = self.config.getfloat(
            'Optimization', 'EtaMinimum', fallback=0.001)

        # Momentum used by Adam.
        self.momentum = self.config.getfloat(
            'Optimization', 'Momentum', fallback=0.95)

        # Update frequency for policy network and value network, in the number
        # of time steps.
        self.update_frequency = self.config.getint(
            'PolicyGradient', 'UpdateFrequency', fallback=64)

        # Name of a file containing model of the same structure as policy
        # network (unnormalized log of policy pi), where model is obtained
        # through other methods (e.g. supervised learning), and saved by
        # cntk.ops.functions.Function.save(). Random initialization is
        # performed if value is empty.
        self.initial_policy_network = self.config.get(
            'PolicyGradient', 'InitialPolicy', fallback='')

    def save(self, config_file):
        with open(config_file, 'w') as c:
            self.config.write(c)


def setup():
    global img
    size(700, 700)
    img = loadImage("obrazek.jpg")
    noFill()

def draw():
    try:
        image(img, 200, 200, 400, 400) # tylko to chcemy testować pod kątem wystąpienia błędu

    except:
        stroke("#FF0000")
        text("blad z obrazem", 100, 25)
    else:
        stroke("#0000FF")
    finally:
        rect(199, 199, 401, 401)

#1,5pkt


paintings = ["The Two Fridas", "My Dress Hangs Here", "Tree of Hope", "Self Portrait With Monkeys"]
dates = [1939, 1933, 1946, 1940]
paintings = list(zip(paintings, dates))
print(paintings)

paintings += [("The Broken Column", 1944),("The Wounded Deer", 1946),("Me and My Doll" , 1937)]

print(len(paintings))
print(paintings)

audio_tour_number = [i + 1 for i in range(7)]

master_list = list(zip(audio_tour_number, paintings))
print(master_list)


import json
import socket
from threading import Thread

#HOST = '24.147.10.71'
HOST = '127.0.0.1'
PORT = 6642

def encode(dict):
    return json.dumps(dict).encode('utf-8')

def decode(msg):
    return json.loads(msg)

def receive_loop(sock, bufsize=1024):
    while True:
        data = sock.recv(bufsize)
        print(decode(data))

def send_loop(sock, user):
    while True:
        msg = input()
        sock.sendall(encode({'message': msg, 'from': user}))

with socket.socket() as sock:
    user = input('Enter username: ')
    sock.connect((HOST, PORT))
    print('Connected to host {}'.format(HOST))
    receive_thread = Thread(target=receive_loop, args=(sock,))
    send_thread = Thread(target=send_loop, args=(sock, user))
    receive_thread.start()
    send_thread.start()
    while True: pass


import META
import rasterio
import gdal
import cv2
import numpy as np
import numpy.matlib
import matplotlib.pyplot as plt
import os
from random import randint
from math import cos, sin, asin, sqrt, radians, log, tan, exp, atan2, atan
import warnings
import copy
warnings.simplefilter(action = "ignore", category = RuntimeWarning)

#%%
def file_to_edges(i,file_type,path,luma,gamma_correct,pixel_size,extra_blur,ppp,steps,thresholding,sigma):
    if i == 0:
        print("[0%] Getting edges for target image.")
    else:
        print("["+"{:.0f}".format((1+(i-1)*(ppp+3))/steps)+"%] Getting edges for image nr "+str(i)+".")
    if file_type == 0:
        #edges, array, gt, fact_x, fact_y, x_b, y_b, mask = ortho_to_edges(path,luma,gamma_correct,pixel_size,extra_blur,thresholding,sigma)
        #edges, array, gt, fact_x, fact_y, x_b, y_b, mask = ortho_to_edges_new(path,pixel_size,thresholding,sigma,extra_blur)
        edges, array, gt, fact_x, fact_y, x_b, y_b, mask = ortho_to_edges_newnew(path,pixel_size)
    elif file_type == 1:
        edges, gt, fact_x, fact_y, x_b, y_b, mask = dem_to_edges(path,pixel_size)
    return edges, array, gt, fact_x, fact_y, x_b, y_b, mask

def ortho_to_edges(path,luma,gamma_correct,pixel_size,extra_blur,thresholding,sigma):
    file                               = gdal.Open(path)
    gt                                 = file.GetGeoTransform()
    R                                  = file.GetRasterBand(1).ReadAsArray()
    G                                  = file.GetRasterBand(2).ReadAsArray()
    B                                  = file.GetRasterBand(3).ReadAsArray()
    x_s, y_s                           = calc_pixsize(R,gt)
    R_s                                = cv2.resize(R,(int(B.shape[1]*(y_s/pixel_size)), int(B.shape[0]*(x_s/pixel_size))),interpolation = cv2.INTER_AREA)
    G_s                                = cv2.resize(G,(int(B.shape[1]*(y_s/pixel_size)), int(B.shape[0]*(x_s/pixel_size))),interpolation = cv2.INTER_AREA)
    B_s                                = cv2.resize(B,(int(B.shape[1]*(y_s/pixel_size)), int(B.shape[0]*(x_s/pixel_size))),interpolation = cv2.INTER_AREA)
    if gamma_correct == 1:
        Rlin                           = (R_s**2.2)/255
        Glin                           = (G_s**2.2)/255
        Blin                           = (B_s**2.2)/255
        if   luma == 709:
            Y                          = 0.2126*Rlin + 0.7152*Glin + 0.0722*Blin
        elif luma == 601:
            Y                          = 0.299*Rlin + 0.587*Glin + 0.114*Blin
        elif luma == 240:
            Y                          = 0.212*Rlin + 0.701*Glin + 0.087*Blin
        L                              = 116*Y**(1/3)-16
        arr_sg                         = ((L/np.max(L))*255).astype(np.uint8)
    elif gamma_correct == 0:
        if   luma == 709:
            arr_sg                     = 0.2126*R_s + 0.7152*G_s + 0.0722*B_s
        elif luma == 601:
            arr_sg                     = 0.299*R_s + 0.587*G_s + 0.114*B_s
        elif luma == 240:
            arr_sg                     = 0.212*R_s + 0.701*G_s + 0.087*B_s
    if extra_blur == 1:
            arr_sg                     = cv2.medianBlur(arr_sg.astype(np.uint8),3)
    mask                               = np.zeros(arr_sg.shape)
    mask[arr_sg==255]                  = 1
    mask_b                             = cv2.GaussianBlur(mask,(5,5),0)
    if thresholding == 0:
        ht, thresh_im                      = cv2.threshold(arr_sg[arr_sg<=254], 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
        lt = 0.5*ht
    elif thresholding == 1:
        lt = max((1-sigma) * np.median(arr_sg[arr_sg<=254]),0)
        ht = min((1+sigma) * np.median(arr_sg[arr_sg<=254]),255)
    elif thresholding == 2:
        lt = max((1-sigma) * np.mean(arr_sg[arr_sg<=254]),0)
        ht = min((1+sigma) * np.mean(arr_sg[arr_sg<=254]),255)
    edges                              = cv2.Canny(arr_sg,lt,ht)
    edges[mask_b>=10**-10]             = 0
    fact_x = B.shape[0]/edges.shape[0]
    fact_y = B.shape[1]/edges.shape[1]
    x_b    = edges.shape[0]
    y_b    = edges.shape[1]
    return edges, arr_sg, gt, fact_x, fact_y, x_b, y_b, mask

def ortho_to_edges_new(path,pixel_size,thresholding,sigma,extra_blur):
    file                               = gdal.Open(path)
    gt                                 = file.GetGeoTransform()
    R                                  = file.GetRasterBand(1).ReadAsArray()
    G                                  = file.GetRasterBand(2).ReadAsArray()
    B                                  = file.GetRasterBand(3).ReadAsArray()
    x_s, y_s                           = calc_pixsize(R,gt)
    R_s                                = cv2.resize(R,(int(B.shape[1]*(y_s/pixel_size)), int(B.shape[0]*(x_s/pixel_size))),interpolation = cv2.INTER_AREA)
    G_s                                = cv2.resize(G,(int(B.shape[1]*(y_s/pixel_size)), int(B.shape[0]*(x_s/pixel_size))),interpolation = cv2.INTER_AREA)
    B_s                                = cv2.resize(B,(int(B.shape[1]*(y_s/pixel_size)), int(B.shape[0]*(x_s/pixel_size))),interpolation = cv2.INTER_AREA)
    img_s                              = np.zeros([B_s.shape[0],B_s.shape[1],3], np.uint8)
    mask                               = np.zeros(B_s.shape)
    mask[R_s==255]                     = 1
    mask_b                             = cv2.GaussianBlur(mask,(5,5),0)
    img_s[:,:,0]                       = B_s
    img_s[:,:,1]                       = G_s
    img_s[:,:,2]                       = R_s
    img_s_cielab                       = cv2.cvtColor(img_s, cv2.COLOR_BGR2Lab)
    L                                  = img_s_cielab[:,:,0]
    hist,bins,trash                    = plt.hist(L[mask_b==0],bins=256)
    cdf                                = hist.cumsum()
    cdf_m                              = np.ma.masked_equal(cdf,0)
    cdf_m                              = (cdf_m-cdf_m.min())*255/(cdf_m.max()-cdf_m.min())
    cdf                                = np.ma.filled(cdf_m,0).astype(np.uint8)
    L_eq                               = cdf[L]
    img_s_cielab_eq                    = img_s_cielab.copy()
    img_s_cielab_eq[:,:,0]             = L_eq
    img_s_eq                           = cv2.cvtColor(img_s_cielab_eq, cv2.COLOR_Lab2BGR)
    img_g                              = cv2.cvtColor(img_s_eq, cv2.COLOR_BGR2GRAY)
    if thresholding == 0:
        ht, thresh_im                  = cv2.threshold(img_g[mask_b==0], 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
        lt                             = 0.5*ht
    elif thresholding == 1:
        lt                             = max((1-sigma) * np.median(img_g[mask_b==0]),0)
        ht                             = min((1+sigma) * np.median(img_g[mask_b==0]),255)
    elif thresholding == 2:
        lt                             = max((1-sigma) * np.mean(img_g[mask_b==0]),0)
        ht                             = min((1+sigma) * np.mean(img_g[mask_b==0]),255)
    if extra_blur == 1:
        img_g                          = cv2.GaussianBlur(img_g,(3,3),0)
    edges                              = cv2.Canny(img_g,lt,ht,L2gradient=True)
    edges[mask_b>=10**-10]             = 0
    fact_x                             = B.shape[0]/edges.shape[0]
    fact_y                             = B.shape[1]/edges.shape[1]
    x_b                                = edges.shape[0]
    y_b                                = edges.shape[1]
    return edges, img_s_eq, gt, fact_x, fact_y, x_b, y_b, mask

def ortho_to_edges_newnew(path,pixel_size):
    file                               = gdal.Open(path[3])
    gt                                 = file.GetGeoTransform()
    R                                  = file.GetRasterBand(1).ReadAsArray()
    G                                  = file.GetRasterBand(2).ReadAsArray()
    B                                  = file.GetRasterBand(3).ReadAsArray()
    x_s, y_s                           = calc_pixsize(R,gt)
    R_s                                = cv2.resize(R,(int(B.shape[1]*(y_s/pixel_size)), int(B.shape[0]*(x_s/pixel_size))),interpolation = cv2.INTER_AREA)
    G_s                                = cv2.resize(G,(int(B.shape[1]*(y_s/pixel_size)), int(B.shape[0]*(x_s/pixel_size))),interpolation = cv2.INTER_AREA)
    B_s                                = cv2.resize(B,(int(B.shape[1]*(y_s/pixel_size)), int(B.shape[0]*(x_s/pixel_size))),interpolation = cv2.INTER_AREA)
    img_s                              = np.zeros([B_s.shape[0],B_s.shape[1],3], np.uint8)
    mask                               = np.zeros(B_s.shape)
    mask[R_s==255]                     = 1
    mask_b                             = cv2.GaussianBlur(mask,(5,5),0)
    img_s[:,:,0]                       = B_s
    img_s[:,:,1]                       = G_s
    img_s[:,:,2]                       = R_s
    img_s_cielab                       = cv2.cvtColor(img_s, cv2.COLOR_BGR2Lab)
    L                                  = img_s_cielab[:,:,0]
    hist,bins,trash                    = plt.hist(L[mask_b==0],bins=256)
    cdf                                = hist.cumsum()
    cdf_m                              = np.ma.masked_equal(cdf,0)
    cdf_m                              = (cdf_m-cdf_m.min())*255/(cdf_m.max()-cdf_m.min())
    cdf                                = np.ma.filled(cdf_m,0).astype(np.uint8)
    L_eq                               = cdf[L]
    img_s_cielab_eq                    = img_s_cielab.copy()
    img_s_cielab_eq[:,:,0]             = L_eq
    img_s_eq                           = cv2.cvtColor(img_s_cielab_eq, cv2.COLOR_Lab2BGR)
    img_g                              = cv2.cvtColor(img_s_eq, cv2.COLOR_BGR2GRAY)
    img_b                              = cv2.bilateralFilter(img_g,21,125,250)

    rows = img_b.shape[0]
    cols = img_b.shape[1]
    thMeaningfulLength = int(2*log(rows*cols)/log(8)+0.5)
    gNoise = 1.33333
    VMGradient = 70
    k=7
    gradientMap = np.zeros(img_b.shape)
    dx = cv2.Sobel(src=img_b,ddepth=cv2.CV_16S, dx=1, dy=0, ksize=k, scale=1, delta=0, borderType=cv2.BORDER_REPLICATE)
    dy = cv2.Sobel(src=img_b,ddepth=cv2.CV_16S, dx=0, dy=1, ksize=k, scale=1, delta=0, borderType=cv2.BORDER_REPLICATE)
    dx[mask_b>=10**-10]=0
    dy[mask_b>=10**-10]=0
    if k == 5:
        dx = dx/13.4
        dy = dy/13.4
    if k == 7:
        dx = dx/47.5
        dy = dy/47.5
    totalNum = 0
    histogram = np.zeros(255*8)
    for i in range(gradientMap.shape[0]):
        for j in range(gradientMap.shape[1]):
            ptrG = abs(dx[i,j])+abs(dy[i,j])
            if ptrG > gNoise:
                histogram[int(ptrG + 0.5)] += 1
                totalNum +=1
            else:
                ptrG = 0
            gradientMap[i,j] = ptrG
    N2 = 0
    for i in range(len(histogram)):
        if histogram[i] != 0:
            N2 += histogram[i]*(histogram[i]-1)
    pMax = 1/exp((log(N2)/thMeaningfulLength))
    pMin = 1/exp((log(N2)/sqrt(cols*rows)))
    greaterThan = np.zeros(255*8)
    count = 0
    for i in range(255*8-1,-1,-1):
        count += histogram[i]
        probabilityGreater = count/totalNum
        greaterThan[i] = probabilityGreater
    count = 0
    for i in range(255*8-1,-1,-1):
        if greaterThan[i]>=pMax:
            thGradientHigh = i
            break
    for i in range(255*8-1,-1,-1):
        if greaterThan[i]>=pMin:
            thGradientLow = i
            break
    if thGradientLow <= gNoise:
        thGradientLow = gNoise
    thGradientHigh = sqrt(thGradientHigh*VMGradient)
    edgemap = cv2.Canny(img_b,thGradientLow,thGradientHigh,3)
    edgemap[mask_b>=10**-10]=0
    anglePer = np.pi / 8
    orientationMap = np.zeros(img_b.shape)
    for i in range(orientationMap.shape[0]):
        for j in range(orientationMap.shape[1]):
            ptrO = int((atan2(dx[i,j],-dy[i,j]) + np.pi)/anglePer)
            if ptrO == 16:
                ptrO = 0
            orientationMap[i,j] = ptrO
    maskMap = np.zeros(img_b.shape)
    gradientPoints = []
    gradientValues = []
    for i in range(edgemap.shape[0]):
        for j in range(edgemap.shape[1]):
            if edgemap[i,j] == 255:
                maskMap[i,j] = 1
                gradientPoints.append((i,j))
                gradientValues.append(gradientMap[i,j])
    gradientPoints = [x for _,x in sorted(zip(gradientValues,gradientPoints))]
    gradientValues.sort()
    gradientPoints = gradientPoints[::-1]
    gradientValues = gradientValues[::-1]
    # [A] Initial Chains
    edgeChainsA = []
    for i in range(len(gradientPoints)):
        x = gradientPoints[i][0]
        y = gradientPoints[i][1]
        if maskMap[x,y] == 0 or maskMap[x,y] == 2:
            continue
        chain = []
        chain.append((x,y))
        while x >= 0 and y >= 0:
            x,y = next1(x,y,rows,cols,maskMap,orientationMap)
            if x >= 0 and y >= 0:
                chain.append((x,y))
                maskMap[x,y] = 2
        if len(chain) >= thMeaningfulLength:
            edgeChainsA.append(chain)
            chain = np.array(chain)
    # [B] Splitting orientation shifts
    edgeChainsB = copy.deepcopy(edgeChainsA)
    for i in range(len(edgeChainsB)-1,-1,-1):
        if len(edgeChainsB[i]) >= 2*thMeaningfulLength:
            orientationchain = []
            for x in edgeChainsB[i]:
                orientationchain.append(orientationMap[x[0],x[1]])
            av = moving_average(orientationchain, n=7)
            avchain = np.zeros(len(orientationchain))
            avchain[0:3] = av[0]
            avchain[3:-3] = av
            avchain[-3:] = av[-1]
            d = np.diff(avchain)
            for j in range(len(d)):
                if abs(d[j]) >= 0.3:
                    edgeChainsB.append(edgeChainsB[i][0:j])
                    edgeChainsB.append(edgeChainsB[i][j:])
                    del edgeChainsB[i]
    edgeChainsB = [x for x in edgeChainsB if x != []]
    # # [B] Splitting to meaningful length
    # splitchains = []
    # for i in range(len(edgeChains)-1,-1,-1):
    #     if len(edgeChains[i]) >= 2*thMeaningfulLength:
    #         chainlist = [edgeChains[i][j: j + 2*thMeaningfulLength] for j in range(0, len(edgeChains[i]), 2*thMeaningfulLength)]
    #         if len(chainlist[-1]) <= thMeaningfulLength:
    #             chainlist[-2].extend(chainlist[-1])
    #             del chainlist[-1]
    #         splitchains.extend(chainlist)
    #         del edgeChains[i]
    # edgeChains.extend(splitchains)
    # edgeChains = [x for x in edgeChains if x != []]
    # [B] Line fitting
    metaLinesB = []
    lengthB = []
    for i in range(len(edgeChainsB)):
        chain = np.array(edgeChainsB[i])
        m,c = np.polyfit(chain[:,1],chain[:,0],1)
        xmin = min(chain[:,1])
        xmax = max(chain[:,1])
        xn = np.linspace(xmin,xmax,(max(1,xmax-xmin))*10)
        yn = np.polyval([m, c], xn)
        l = sqrt((xn[0]-xn[-1])**2+(yn[0]-yn[-1])**2)
        metaLinesB.append((xn,yn,m,c))
        lengthB.append(l)
    lengthB = np.array(lengthB)
    metaLinesB = np.array(metaLinesB)
    edgeChainsB = np.array(edgeChainsB)
    indices = lengthB.argsort()
    indices = indices[::-1]
    metaLinesB = metaLinesB[indices]
    edgeChainsB = edgeChainsB[indices]
    lengthB = lengthB[indices]
    # [C] Line merging
    theta_s = thMeaningfulLength / 2
    theta_m = 2*tan(2/thMeaningfulLength)
    connections = []
    for i in range(len(metaLinesB)):
        x1 = metaLinesB[i][0][0]
        y1 = metaLinesB[i][1][0]
        x2 = metaLinesB[i][0][-1]
        y2 = metaLinesB[i][1][-1]
        s = metaLinesB[i][2]
        for j in range(i,len(metaLinesB)):
            s2 = metaLinesB[j][2]
            sd = abs(atan(s)-atan(s2))
            if i!= j and sd <= theta_m:
                a1 = metaLinesB[j][0][0]
                b1 = metaLinesB[j][1][0]
                a2 = metaLinesB[j][0][-1]
                b2 = metaLinesB[j][1][-1]
                d1 = sqrt((x1-a2)**2+(y1-b2)**2)
                d2 = sqrt((x2-a1)**2+(y2-b1)**2)
                if d1 <= 3/pixel_size and a2 < x1: # 2m direct distance
                    p1 = np.array((x1,y1))
                    p2 = np.array((x2,y2))
                    p3 = np.array((a2,b2))
                    d_toline = np.linalg.norm(np.cross(p2-p1, p1-p3))/np.linalg.norm(p2-p1)
                    if d_toline <= 0.08/pixel_size: # 0.1m distance to line
                        connections.append((i,j))
                if d2 <= 3/pixel_size and a1 > x2: # 2m direct distance
                    p1 = np.array((x1,y1))
                    p2 = np.array((x2,y2))
                    p3 = np.array((a1,b1))
                    d_toline = np.linalg.norm(np.cross(p2-p1, p1-p3))/np.linalg.norm(p2-p1)
                    if d_toline <= 0.08/pixel_size: # 0.1m distance to line
                        connections.append((i,j))
    chains = []
    connections = np.array(connections)
    connections_c = connections.copy()
    for i in range(len(connections)):
        if all(connections_c[i] == -1):
            continue
        chain = []
        chain.append(connections_c[i][0])
        chain.append(connections_c[i][1])
        connections_c[i]=-1
        while len(set(chain) & set(connections_c[:,0].tolist())) >= 1 or len(set(chain) & set(connections_c[:,1].tolist())) >= 1:
            num1 = set(chain) & set(connections_c[:,0].tolist())
            num2 = set(chain) & set(connections_c[:,1].tolist())
            if len(num1) >= 1:
                index = np.where(connections_c[:,0]==list(num1)[0])[0][0]
            elif len(num2) >= 1:
                index = np.where(connections_c[:,1]==list(num2)[0])[0][0]
            chain.append(connections_c[index][0])
            chain.append(connections_c[index][1])
            connections_c[index]=-1
        chains.append(sorted(list(set(chain))))
    edgeChainsMerged = []
    for i in range(len(chains)):
        chain = []
        for j in range(len(chains[i])):
            chain.extend(edgeChainsB[chains[i][j]])
        edgeChainsMerged.append(chain)
    edgeChainsNonmerged = []
    alledges = np.linspace(0,len(edgeChainsB)-1,len(edgeChainsB)).astype(int)
    merged = np.unique(connections)
    nonmerged = np.array(list(set(alledges)-set(merged)))
    for i in range(len(nonmerged)):
        edgeChainsNonmerged.append(edgeChainsB[nonmerged[i]])
    edgeChainsC = []
    edgeChainsC.extend(edgeChainsMerged)
    edgeChainsC.extend(edgeChainsNonmerged)
    # [C] Line fitting
    metaLinesC = []
    lengthC = []
    for i in range(len(edgeChainsC)):
        chain = np.array(edgeChainsC[i])
        m,c = np.polyfit(chain[:,1],chain[:,0],1)
        xmin = min(chain[:,1])
        xmax = max(chain[:,1])
        xn = np.linspace(xmin,xmax,(max(1,xmax-xmin))*10)
        yn = np.polyval([m, c], xn)
        l = sqrt((xn[0]-xn[-1])**2+(yn[0]-yn[-1])**2)
        metaLinesC.append((xn,yn,m,c))
        lengthC.append(l)
    lengthC = np.array(lengthC)
    metaLinesC = np.array(metaLinesC)
    edgeChainsC = np.array(edgeChainsC)
    indices = lengthC.argsort()
    indices = indices[::-1]
    metaLinesC = metaLinesC[indices]
    edgeChainsC = edgeChainsC[indices]
    lengthC = lengthC[indices]
    # [D] Remove nonsensical length
    metaLinesD = metaLinesC.tolist()
    edgeChainsD = edgeChainsC.tolist()
    lengthD = lengthC.tolist()
    bullshitlength = 2*thMeaningfulLength
    for i in range(len(metaLinesD)-1,-1,-1):
        if lengthD[i] <= bullshitlength:
            del metaLinesD[i]
            del edgeChainsD[i]
            del lengthD[i]
    maskMap2 = np.zeros(maskMap.shape)
    for i in range(len(edgeChainsD)):
        for x in edgeChainsD[i]:
            maskMap2[x[0],x[1]]=1
    # # [E] Store residuals in quad tree
    # residuList = [item for item in gradientPoints if item not in edgeChainsD]
    # spindex = pyqtree.Index(bbox=(0,0,maskMap.shape[0],maskMap.shape[1]))
    #  for item in residuList:
    #     spindex.insert(item, bbox=(item[0],item[1],item[0],item[1]))
    # # [E] Extending chains
    # edgeChainsE = copy.deepcopy(edgeChainsD)
    # d_t = 0.5/pixel_size
    # d_l_t = 0.04/pixel_size
    # for i in range(len(metaLinesD)):
    #     counta = 0
    #     countb = 0
    #     count1 = 0
    #     count2 = 0
    #     last_point = 0
    #     while counta == 0 or countb == 0:
    #         print(i,counta,countb,count1,count2)
    #         if count1 == 0:
    #             b_x = metaLinesD[i][1][0]
    #             b_y = metaLinesD[i][0][0]
    #         b = np.array((b_x,b_y))
    #         if count2 == 0:
    #             e_x = metaLinesD[i][1][-1]
    #             e_y = metaLinesD[i][0][-1]
    #         e = np.array((e_x,e_y))
    #         # Begin:
    #         while counta == 0:
    #             print(i,counta,countb,count1,count2)
    #             overlapbbox = (b_x-d_t,b_y-d_t,b_x+d_t,b_y+d_t)
    #             nearby_points = np.array(spindex.intersect(overlapbbox))
    #             sorting = abs(nearby_points[:,0]-b_x)+abs(nearby_points[:,1]-b_y)
    #             indices = sorting.argsort()
    #             nearby_points = nearby_points[indices].tolist()
    #             if len(nearby_points) == 0:
    #                 counta += 0.5
    #             for point in nearby_points:
    #                 last_point = nearby_points[-1]
    #                 p = np.array(point)
    #                 d_toline = np.linalg.norm(np.cross(e-b, b-p))/np.linalg.norm(e-b)
    #                 if d_toline <= d_l_t:
    #                     d = sqrt((b_x-point[0])**2+(b_y-point[1])**2)
    #                     if d <= d_t:
    #                         edgeChainsE[i].append(point)
    #                         spindex.remove(tuple(point), bbox=(point[0],point[1],point[0],point[1]))
    #                         count1 += 1
    #                         b_x = point[0]
    #                         b_y = point[1]
    #                         break
    #             if point == last_point:
    #                 counta += 0.5
    #         # End:
    #         while countb == 0:
    #             print(i,counta,countb,count1,count2)
    #             overlapbbox = (e_x-d_t,e_y-d_t,e_x+d_t,e_y+d_t)
    #             nearby_points = np.array(spindex.intersect(overlapbbox))
    #             sorting = abs(nearby_points[:,0]-e_x)+abs(nearby_points[:,1]-e_y)
    #             indices = sorting.argsort()
    #             nearby_points = nearby_points[indices].tolist()
    #             if len(nearby_points) == 0:
    #                 countb += 0.5
    #             for point in nearby_points:
    #                 last_point = nearby_points[-1]
    #                 p = np.array(point)
    #                 d_toline = np.linalg.norm(np.cross(e-b, b-p))/np.linalg.norm(e-b)
    #                 if d_toline <= d_l_t:
    #                     d = sqrt((e_x-point[0])**2+(e_y-point[1])**2)
    #                     if d <= d_t:
    #                         edgeChainsE[i].append(point)
    #                         spindex.remove(tuple(point), bbox=(point[0],point[1],point[0],point[1]))
    #                         count2 += 1
    #                         e_x = point[0]
    #                         e_y = point[1]
    #                         break
    #             if point == last_point:
    #                 countb += 0.5
    # [E] Alternative Extending
    edgeChainsE = copy.deepcopy(edgeChainsD)
    residualMask = (edgemap/255) - maskMap2
    for i in range(len(edgeChainsE)):
        print(i)
        chain = np.array(edgeChainsE[i])
        chain_x = chain[:,0]
        chain_y = chain[:,1]
        indices = chain_y.argsort()
        chain = chain[indices]
        chain_x = chain_x[indices]
        chain_y = chain_y[indices]
        indices = chain_x.argsort()
        chain = chain[indices]
        chain_x = chain_x[indices]
        chain_y = chain_y[indices]
        begin = []
        end = []
        s = metaLinesD[i][2]
        for x in range(len(chain_x)):
            if (chain_x[x]-1 in chain_x)==False and (chain_x[x]-2 in chain_x)==False:
                begin.append(chain_x[x])
            if (chain_x[x]+1 in chain_x)==False and (chain_x[x]+2 in chain_x)==False:
                end.append(chain_x[x])
        begin = sorted(list(set(begin)))
        end = sorted(list(set(end)))
        for m in range(len(begin)):
            if s >= 0:
                begin_i = min(np.where(chain[:,0]==begin[m])[0])
            else:
                begin_i = max(np.where(chain[:,0]==begin[m])[0])
            b_x = chain[begin_i,0]
            b_y = chain[begin_i,1]
            for x in range(len(end)-1,-1,-1):
                if end[x] < b_x:
                    ceil_x  = end[x]
                    break
                else:
                    ceil_x = 0
            while b_x >= 0 and b_y >= 0:
                b_x,b_y = next2(b_x,b_y,rows,cols,residualMask,0,s)
                if b_x <= ceil_x:
                    break
                if b_x >= 0 and b_y >= 0:
                    edgeChainsE[i].append((b_x,b_y))
                    residualMask[b_x,b_y] = 0
        for n in range(len(end)):
            if s >= 0:
                end_i = max(np.where(chain[:,0]==end[n])[0])
            else:
                end_i = min(np.where(chain[:,0]==end[n])[0])
            e_x = chain[end_i,0]
            e_y = chain[end_i,1]
            for x in range(len(begin)):
                if begin[x] > e_x:
                    ceil_x = end[x]
                    break
                else:
                    ceil_x = np.Inf
            while e_x >= 0 and e_y >= 0:
                e_x,e_y = next2(e_x,e_y,rows,cols,residualMask,1,s)
                if e_x >= ceil_x:
                    break
                if e_x >= 0 and e_y >= 0:
                    edgeChainsE[i].append((e_x,e_y))
                    residualMask[e_x,e_y] = 0

    #%%
    plt.imshow(img_s_eq)
    #%%
    plt.imshow(gradientMap)
    #%%
    plt.imshow(orientationMap)
    #%%
    plt.imshow(edgemap)

    #%% [A] Initial chains of linked edge pixels
    for i in range(len(edgeChainsA)):
        chain = np.array(edgeChainsA[i])
        plt.scatter(chain[:,1],-1*chain[:,0],s=2)
    #%% [B] Chains after splitting on orientation
    for i in range(len(edgeChainsB)):
        chain = np.array(edgeChainsB[i])
        plt.scatter(chain[:,1],-1*chain[:,0],s=2)
    #%% [B]
    for i in range(len(metaLinesB)):
        xn = metaLinesB[i][0]
        yn = -1*metaLinesB[i][1]
        plt.plot(xn,yn)
    #%% [C] Chains after merging
    for i in range(len(edgeChainsC)):
        chain = np.array(edgeChainsC[i])
        plt.scatter(chain[:,1],-1*chain[:,0],s=2)
    #%% [C]
    for i in range(len(metaLinesC)):
        xn = metaLinesC[i][0]
        yn = -1*metaLinesC[i][1]
        plt.plot(xn,yn)
    #%% [D] Chains after removing small lines
    for i in range(len(edgeChainsD)):
        chain = np.array(edgeChainsD[i])
        plt.scatter(chain[:,1],-1*chain[:,0],s=2)
    #%% [D]
    plt.imshow(edgemap)
    for i in range(len(metaLinesD)):
        xn = metaLinesD[i][0]
        yn = metaLinesD[i][1]
        plt.plot(xn,yn)
    #%% [E] Chains after extending remaining lines
    for i in range(len(edgeChainsE)):
        chain = np.array(edgeChainsE[i])
        plt.scatter(chain[:,1],-1*chain[:,0],s=2)

    #%% Overlay Image
    plt.imshow(edgemap)
    for i in range(len(edgeChainsE)):
        chain = np.array(edgeChainsE[i])
        plt.scatter(chain[:,1],chain[:,0],s=1,c='r')

    #%%
    plt.imshow(img_s)
    for i in range(len(edgeChainsE)):
        chain = np.array(edgeChainsE[i])
        plt.scatter(chain[:,1],chain[:,0],s=2,c='r')
    for i in range(len(edgeChainsD)):
        chain = np.array(edgeChainsD[i])
        plt.scatter(chain[:,1],chain[:,0],s=2,c='g')
    #chain = np.array(edgeChainsD[-20])
    #plt.scatter(chain[:,1],chain[:,0],s=2,c='b')

    #%%
    chain = np.array(edgeChainsC[1])
    plt.scatter(chain[:,1],-1*chain[:,0],s=2)

    #%%
    fact_x                             = B.shape[0]/edgemap.shape[0]
    fact_y                             = B.shape[1]/edgemap.shape[1]
    x_b                                = edgemap.shape[0]
    y_b                                = edgemap.shape[1]
    return edgemap, img_s_eq, gt, fact_x, fact_y, x_b, y_b, mask

def ortho_to_color(path,pixel_size):
    file                               = gdal.Open(path)
    gt                                 = file.GetGeoTransform()
    R                                  = file.GetRasterBand(1).ReadAsArray()
    G                                  = file.GetRasterBand(2).ReadAsArray()
    B                                  = file.GetRasterBand(3).ReadAsArray()
    x_s, y_s                           = calc_pixsize(R,gt)
    R_s                                = cv2.resize(R,(int(B.shape[1]*(y_s/pixel_size)), int(B.shape[0]*(x_s/pixel_size))),interpolation = cv2.INTER_AREA)
    G_s                                = cv2.resize(G,(int(B.shape[1]*(y_s/pixel_size)), int(B.shape[0]*(x_s/pixel_size))),interpolation = cv2.INTER_AREA)
    B_s                                = cv2.resize(B,(int(B.shape[1]*(y_s/pixel_size)), int(B.shape[0]*(x_s/pixel_size))),interpolation = cv2.INTER_AREA)
    img_s                              = np.zeros([B_s.shape[0],B_s.shape[1],3], np.uint8)
    mask                               = np.zeros(B_s.shape)
    mask[R_s==255]                     = 1
    mask_b                             = cv2.GaussianBlur(mask,(5,5),0)
    img_s[:,:,0]                       = B_s
    img_s[:,:,1]                       = G_s
    img_s[:,:,2]                       = R_s
    img_s_cielab                       = cv2.cvtColor(img_s, cv2.COLOR_BGR2Lab)
    L                                  = img_s_cielab[:,:,0]
    hist,bins,trash                    = plt.hist(L[mask_b==0],bins=256)
    cdf                                = hist.cumsum()
    cdf_m                              = np.ma.masked_equal(cdf,0)
    cdf_m                              = (cdf_m-cdf_m.min())*255/(cdf_m.max()-cdf_m.min())
    cdf                                = np.ma.filled(cdf_m,0).astype(np.uint8)
    L_eq                               = cdf[L]
    img_s_cielab_eq                    = img_s_cielab.copy()
    img_s_cielab_eq[:,:,0]             = L_eq
    img_s_eq                           = cv2.cvtColor(img_s_cielab_eq, cv2.COLOR_Lab2BGR)
    edgemap = np.zeros(img_s_eq.shape)
    fact_x                             = B.shape[0]/edgemap.shape[0]
    fact_y                             = B.shape[1]/edgemap.shape[1]
    x_b                                = edgemap.shape[0]
    y_b                                = edgemap.shape[1]
    return edgemap, img_s_eq, gt, fact_x, fact_y, x_b, y_b, mask

def dem_to_edges(path,pixel_size):
    s                                  = 5
    file                               = gdal.Open(path)
    band                               = file.GetRasterBand(1)
    gt                                 = file.GetGeoTransform()
    arr                                = band.ReadAsArray()
    x_s, y_s                           = calc_pixsize(arr,gt)
    arr_s                              = cv2.resize(arr,(int(arr.shape[1]*(y_s/pixel_size)), int(arr.shape[0]*(x_s/pixel_size))),interpolation = cv2.INTER_AREA)
    mask                               = np.zeros(arr_s.shape)
    mask[arr_s<=0.8*np.nanmin(arr_s)]  = 1
    mask_b                             = cv2.GaussianBlur(mask,(s,s),0)
    mask_hb                            = cv2.GaussianBlur(mask,(21,21),0)
    arr_sc                             = arr_s.copy()
    arr_sc[mask_b>=10**-10]            = np.NaN
    while np.nanmax(arr_sc)-np.nanmin(arr_sc) >= 100:
        s = s+2
        mask_b                         = cv2.GaussianBlur(mask,(s,s),0)
        arr_sc[mask_b>=10**-10]        = np.NaN
    mask_hb                            = cv2.GaussianBlur(mask,(s+6,s+6),0)
    sort                               = np.unique(arr_sc[~np.isnan(arr_sc)])
    sortofmedian                       = sort[int(len(sort)/2)]
    std                                = np.std(arr_s[~np.isnan(arr_sc)])
    cap                                = sortofmedian + 1.5*std
    arr_scc                            = arr_sc.copy()
    arr_scc[arr_scc>=cap]              = cap
    arr_sccg                           = arr_scc.copy()
    un                                 = np.nanmin(arr_sccg)
    arr_sccg                           = arr_sccg-un
    up                                 = np.nanmax(arr_sccg)
    arr_sccg                           = (arr_sccg/up)*255
    arr_sccgb                          = cv2.GaussianBlur(arr_sccg,(3,3),0)
    arr_sccgbf                         = arr_sccgb.copy()
    arr_sccgbf[np.isnan(arr_sccgbf)]   = np.nanmean(arr_sccgbf)
    arr_sccgbf                         = arr_sccgbf.astype(np.uint8)
    arr_sccgbfa                        = cv2.adaptiveThreshold(arr_sccgbf,255,cv2.ADAPTIVE_THRESH_MEAN_C,cv2.THRESH_BINARY_INV,9,2)
    arr_sccgbfa[mask_hb>=10**-10]      = 0
    edges                              = cv2.medianBlur(arr_sccgbfa,5)
    fact_x = arr.shape[0]/edges.shape[0]
    fact_y = arr.shape[1]/edges.shape[1]
    x_b    = edges.shape[0]
    y_b    = edges.shape[1]
    return edges, arr_sc, gt, fact_x, fact_y, x_b, y_b, mask

def patch_match(i, edges, gt, fact_x, fact_y, x_b, y_b, mask, edges_0, gt_0, fact_x_0, fact_y_0, x_b_0, y_b_0, mask_0, ppp, cv_max, dst_max, w, v, steps, s, it_cancel, it_max):
    print("["+"{:.0f}".format((2+(i-1)*(ppp+3))/steps)+"%] Matching patches for image nr "+str(i)+".")
    sumedges_0 = np.zeros(edges_0.shape)
    for x in range(w,x_b_0-w):
        for y in range(w,y_b_0-w):
            sumedges_0[x,y] = sum(sum(edges_0[x-w:x+w,y-w:y+w]))
    minfeatures = np.max(sumedges_0)*0.1
    mask_0_c   = mask_0.copy()
    RECC_s     = np.zeros(edges.shape)
    dist       = np.zeros(ppp)
    dist_lon   = np.zeros(ppp)
    dist_lat   = np.zeros(ppp)
    origin_x   = np.zeros(ppp)
    origin_y   = np.zeros(ppp)
    target_lon = np.zeros(ppp)
    target_lat = np.zeros(ppp)
    o_x        = np.zeros(ppp)
    o_y        = np.zeros(ppp)
    t_x        = np.zeros(ppp)
    t_y        = np.zeros(ppp)
    j=-1
    it = 0
    if it_cancel == 1:
        while j <= ppp-2 and it*it_cancel <= it_max*ppp:
            x_i_0 = randint(w,x_b_0-w)
            y_i_0 = randint(w,y_b_0-w)
            check1 = mask_0_c[x_i_0,y_i_0]
            check2 = sumedges_0[x_i_0,y_i_0]
            if check1 <= 0 and check2 >= minfeatures:
                it = it+1
                target = edges_0[x_i_0-w:x_i_0+w,y_i_0-w:y_i_0+w]
                sum_target = np.sum(target)
                RECC_s.fill(np.NaN)
                for x in range(max(w,x_i_0-s*w),min(x_b-w,x_i_0+s*w)):
                    for y in range(max(w,y_i_0-s*w),min(y_b-w,y_i_0+s*w)):
                        patch = edges[x-w:x+w,y-w:y+w]
                        RECC_s[x,y]=np.sum(np.multiply(target,patch))/(sum_target+np.sum(patch))
                max_one  = np.partition(RECC_s[~np.isnan(RECC_s)].flatten(),-1)[-1]
                max_n    = np.partition(RECC_s[~np.isnan(RECC_s)].flatten(),-4-1)[-4-1]
                x_i    = np.where(RECC_s >= max_one)[1][0]
                y_i    = np.where(RECC_s >= max_one)[0][0]
                x_n      = np.where(RECC_s >= max_n)[1][0:-1]
                y_n      = np.where(RECC_s >= max_n)[0][0:-1]
                cv_score = sum(np.sqrt(np.square(x_i-x_n)+np.square(y_i-y_n)))
                if cv_score <= cv_max:
                    lon = gt[0] + gt[1]*x_i*fact_x + gt[2]*y_i*fact_y
                    lat = gt[3] + gt[4]*x_i*fact_x + gt[5]*y_i*fact_y
                    lon_0 = gt_0[0] + gt_0[1]*y_i_0*fact_x_0 + gt_0[2]*x_i_0*fact_y_0
                    lat_0 = gt_0[3] + gt_0[4]*y_i_0*fact_x_0 + gt_0[5]*x_i_0*fact_y_0
                    dst = calc_distance(lat,lon,lat_0,lon_0)
                    if dst <= dst_max:
                        j=j+1
                        print("["+"{:.0f}".format(((3+j)+(i-1)*(ppp+3))/steps)+"%] ("+"{:.0f}".format(cv_score)+","+"{:.1f}".format(dst)+") Succesful patch-match nr "+str(j+1)+" of "+str(ppp)+".")
                        mask_0_c[x_i_0-v:x_i_0+v,y_i_0-v:y_i_0+v]=1
                        dist[j]       = dst
                        dist_lon[j]   = lon_0-lon
                        dist_lat[j]   = lat_0-lat
                        origin_x[j]   = x_i*fact_x
                        origin_y[j]   = y_i*fact_y
                        target_lon[j] = lon_0
                        target_lat[j] = lat_0
                        o_x[j] = x_i
                        o_y[j] = y_i
                        t_x[j] = x_i_0
                        t_y[j] = y_i_0
                    else:
                        print("["+"{:.0f}".format(((3+j)+(i-1)*(ppp+3))/steps)+"%] ("+"{:.0f}".format(cv_score)+","+"{:.1f}".format(dst)+") Match failed.")
                else:
                    print("["+"{:.0f}".format(((3+j)+(i-1)*(ppp+3))/steps)+"%] ("+"{:.0f}".format(cv_score)+",-) Match failed.")
        dist = dist[dist!=0]
        dist_lon = dist_lon[dist_lon!=0]
        dist_lat = dist_lat[dist_lat!=0]
        origin_x = origin_x[origin_x!=0]
        origin_y = origin_y[origin_y!=0]
        target_lon = target_lon[target_lon!=0]
        target_lat = target_lat[target_lat!=0]
        o_x = o_x[o_x!=0]
        o_y = o_y[o_y!=0]
        t_x = t_x[t_x!=0]
        t_y = t_y[t_y!=0]
        # flip the target x and y for some reason:
        t_x_temp = t_y
        t_y = t_x
        t_x = t_x_temp
    return dist, dist_lon, dist_lat, origin_x, origin_y, target_lon, target_lat, o_x, o_y, t_x, t_y

def remove_outliers(i, ppp, conf, steps, outlier_type, dist, dist_lon, dist_lat, origin_x, origin_y, target_lon, target_lat, o_x, o_y, t_x, t_y):
    gcplist = " "
    size = len(dist)
    if outlier_type == 0:
        flier_indices = np.zeros(1)
        while len(flier_indices) >= 1:
            box_dst = plt.boxplot(dist)
            box_lon = plt.boxplot(dist_lon)
            box_lat = plt.boxplot(dist_lat)
            fliers_dst = box_dst["fliers"][0].get_data()[1]
            fliers_lon = box_lon["fliers"][0].get_data()[1]
            fliers_lat = box_lat["fliers"][0].get_data()[1]
            flier_indices_dst = np.zeros(len(fliers_dst))
            flier_indices_lon = np.zeros(len(fliers_lon))
            flier_indices_lat = np.zeros(len(fliers_lat))
            for j in range(len(fliers_dst)):
                flier_indices_dst[j] = np.where(dist==fliers_dst[j])[0][0]
            for j in range(len(fliers_lon)):
                flier_indices_lon[j] = np.where(dist_lon==fliers_lon[j])[0][0]
            for j in range(len(fliers_lat)):
                flier_indices_lat[j] = np.where(dist_lat==fliers_lat[j])[0][0]
            flier_indices = np.union1d(flier_indices_lon,flier_indices_lat)
            flier_indices = (np.union1d(flier_indices,flier_indices_dst)).astype(int)
            dist       = np.delete(dist,flier_indices)
            dist_lon   = np.delete(dist_lon,flier_indices)
            dist_lat   = np.delete(dist_lat,flier_indices)
            origin_x   = np.delete(origin_x,flier_indices)
            origin_y   = np.delete(origin_y,flier_indices)
            target_lon = np.delete(target_lon,flier_indices)
            target_lat = np.delete(target_lat,flier_indices)
            o_x        = np.delete(o_x,flier_indices)
            o_y        = np.delete(o_y,flier_indices)
            t_x        = np.delete(t_x,flier_indices)
            t_y        = np.delete(t_y,flier_indices)
    elif outlier_type == 1:
        if   conf == 95:
            s = 5.991
        elif conf == 90:
            s = 4.605
        elif conf == 80:
            s = 3.219
        elif conf == 75:
            s = 2.770
        elif conf == 50:
            s = 1.388
        d_x = t_x - o_x
        d_y = t_y - o_y
        d_x_m = d_x - np.median(d_x)
        d_y_m = d_y - np.median(d_y)
        indices = ((d_x_m/sqrt(np.var(d_x_m)))**2 + (d_y_m/sqrt(np.var(d_y_m)))**2 >= s)
        dist       = dist[~indices]
        dist_lon   = dist_lon[~indices]
        dist_lat   = dist_lat[~indices]
        origin_x   = origin_x[~indices]
        origin_y   = origin_y[~indices]
        target_lon = target_lon[~indices]
        target_lat = target_lat[~indices]
        o_x        = o_x[~indices]
        o_y        = o_y[~indices]
        t_x        = t_x[~indices]
        t_y        = t_y[~indices]
    print("["+"{:.0f}".format(((2+ppp)+(i-1)*(ppp+3))/steps)+"%] Removed "+str(size-len(dist))+" outliers.")
    for k in range(len(origin_x)):
        gcplist = gcplist+"-gcp "+str(origin_x[k])+" "+str(origin_y[k])+" "+str(target_lon[k])+" "+str(target_lat[k])+" "
    return gcplist, dist, dist_lon, dist_lat, origin_x, origin_y, target_lon, target_lat, o_x, o_y, t_x, t_y

def georeference(i,wdir,ppp,path,file,steps,gcplist):
    print("["+"{:.0f}".format(((3+ppp)+(i-1)*(ppp+3))/steps)+"%] Georeferencing image nr "+str(i)+".")
    path1 = wdir+"\\temp.tif"
    path2 = wdir+"\\"+file+"_adjusted.tif"
    if os.path.isfile(path1.replace("\\","/")):
        os.remove(path1)
    if os.path.isfile(path2.replace("\\","/")):
        os.remove(path2)
    os.system("gdal_translate -a_srs EPSG:4326 -of GTiff"+gcplist+"\""+path+"\" \""+path1+"\"")
    print("["+"{:.0f}".format(((3+ppp)+(i-1)*(ppp+3))/steps)+"%] Succesful translate, warping...")
    os.system("gdalwarp -r cubicspline -tps -co COMPRESS=NONE \""+path1+"\" \""+path2+"\"")


"""
给定一个范围在  1 ≤ a[i] ≤ n ( n = 数组大小 ) 的 整型数组，数组中的元素一些出现了两次，另一些只出现一次。
找到所有在 [1, n] 范围之间没有出现在数组中的数字。
您能在不使用额外空间且时间复杂度为O(n)的情况下完成这个任务吗? 你可以假定返回的数组不算在额外空间内。

示例:
输入:
[4,3,2,7,8,2,3,1]
输出:
[5,6]
"""

class Solution(object):
    def findDisappearedNumbers(self, nums):
        """
        :type nums: List[int]
        :rtype: List[int]
        """
        # 返回值
        ans = []
        # 去重升序
        s = sorted(set(nums))
        index = 0
        # 遍历整数1到n
        # range[start,end)：左闭右开
        for i in range(1, len(nums)+1):
            if index < len(s) and i == s[index]:
                index += 1
            # 若i不在原数组中，则添加到返回值中
            else:
                ans.append(i)
        return ans

    # 果断超时！
    def findDisappearedNumbers2(self, nums):
        """
        :type nums: List[int]
        :rtype: List[int]
        """
        ans = []
        n = len(nums)
        for i in range(1, n + 1):
            if i not in nums:
                ans.append(i)
        return ans

if __name__ == '__main__':
    solution = Solution()
    # print(solution.findDisappearedNumbers([4, 3, 2, 7, 8, 2, 3, 1]))
    print(solution.findDisappearedNumbers([1, 1]))

数组/448. 找到所有数组中消失的数字.py

448. 找到所有数组中消失的数字.py


# 581. Shortest Unsorted Continuous Subarray

# Nick White's video and Leetcode's solution.

class Solution:
    def findUnsortedSubarray(self, nums: List[int]) -> int:

        sorted_nums = sorted(nums)

        for i in range(len(nums)):
            if nums[i]!=sorted_nums[i]:
                break

        for j in range(len(nums)-1, -1, -1):
            if nums[j]!=sorted_nums[j]:
                break

        return j-i+1 if i<j else 0


class BoardMap:
    xposmap =["a","b","c","d","e","f","g","h"]
    def __init__(self):
        self.fields = [ ["-","-","-","-","-","-","-","-"],
                        ["-","-","-","-","-","-","-","-"],
                        ["-","-","-","-","-","-","-","-"],
                        ["-","-","-","-","-","-","-","-"],
                        ["-","-","-","-","-","-","-","-"],
                        ["-","-","-","-","-","-","-","-"],
                        ["-","-","-","-","-","-","-","-"],
                        ["-","-","-","-","-","-","-","-"]]

    def getFieldPos(self,place: str):
        # print("getFieldPos:",place)
        xName = place[0:1].lower()
        xnum = 0
        px = 0
        for f in self.xposmap:
            if xName == f:
                px = xnum
            xnum +=1
        py = int(place[1:2]) - 1
        return (px, py)

    def setFieldColor(self, place: str, color: str):
        pos = self.getFieldPos(place)
        self.fields[pos[0]][pos[1]] = color

    def clearFieldColor(self, place: str):
        pos = self.getFieldPos(place)
        self.fields[pos[0]][pos[1]] = "-"

    def getFieldColor(self, place: str):
        pos = self.getFieldPos(place)
        if pos[0] < 8 and pos[1] < 8:
            return self.fields[pos[0]][pos[1]]
        else:
            return "-"

    def printBord(self):
        for y in range(0,8):
            for x in range(0,8):
                print("[",self.fields[x][y],"]", end='')
            print("\n")


import os
import sys
from queue import Queue
from threading import Thread
from time import time

from solutions.configurationManger  import processConfigurationCommand, validateCommand, getBotCount

#add top level directory to path
sys.path.insert(0, os.path.join(os.path.dirname(os.path.realpath(__file__)), ".."))

from gui.GUIInMessage import GUIInMessage

solutionFilesPath = os.path.join(os.path.dirname(os.path.realpath(__file__)), "solutions")

def getSolutionsFilesList():
    #get a list of valid solution files to display on gui

    #get all files in solution files directory
    files = os.listdir(solutionFilesPath)

    #filter so only .ex is left
    solutionsFiles = []
    for file in files:
        if ".ex" in file:
            solutionsFiles.append(file)

    return solutionsFiles

def startSolution(fileName: str, GuiInQueue: Queue, SolutionQueue:Queue, OverseerData, killQueue:Queue):
    #start a new thread to handle a solution
    print("Preparing to start a new solution: " + str(fileName))

    #clear solution queue before running
    while( not SolutionQueue.empty()):
        SolutionQueue.get()

    solutionThread = Thread(target=runSolution, args=(fileName, GuiInQueue, SolutionQueue, OverseerData, killQueue))
    solutionThread.isDaemon = True
    solutionThread.start()

def runSolution(fileName: str, GuiInQueue: Queue, SolutionQueue:Queue, OverseerData, killQueue:Queue):
    #run through a solution script

    #clear solution queue
    while not SolutionQueue.empty():
        SolutionQueue.get()

    #load in solution file
    try:
        solutionFile = open(os.path.join(solutionFilesPath, fileName), "r")
    except FileNotFoundError:
        print("Cannot open solutions file: " + fileName + ". Failing!")
        return

    #process the file into commands
    solutionsFileContents = solutionFile.read()
    solutionsFileLines = solutionsFileContents.split("\n")

    #filter to valid commands
    solutionsCommands = []
    for line in solutionsFileLines:
        #if the first line starts with a valid command identifier
        if(line[:1] == "S" or line[:1] == "C" or line[:1] == "B"):

            #split line by space to get parameters and command
            solutionsCommands.append(line.split(" "))

        elif(not (line[:1] == "" or line[:1] == "#")):
            #if line is not command, comment or empty space
            print("Invalid command: " + line + ". Not running command but continuing!")

    #the status/location of all bots
    statuses = dict()

    #wait for all bots to echo their status
    statusRequestStart = time()
    botCount = getBotCount(OverseerData)
    uniqueStatusesRecieved = 0

    #request bot statuses
    statusRequestMessage = GUIInMessage("5010", "CollectStatuses", "1234", Direct=False)
    GuiInQueue.put(statusRequestMessage)

    while(uniqueStatusesRecieved < botCount):

        if(time() > statusRequestStart + 30):
            #timeout
            print("Failed To recieve statuses from all bots in a reasonable time. Check connections. Dumping Statuses! Failing!")

            #stop the entire controller...
            killQueue.put("Kill")
            quit()

        if(not SolutionQueue.empty()):
            #a status has been sent

            status = SolutionQueue.get()

            if(not status[1] == 0):
                #this is a problem
                print("Please ensure no robots are running commands before running a solution! Failing!")
                return

            #check if status is unique or not
            if(status[0] in statuses.keys()):
                #non unique status
                statuses[status[0]] = (status[0], status[1])
            else:
                #unique status
                statuses[status[0]] = (status[0], status[1])
                uniqueStatusesRecieved += 1

    print("All bots are ready to begin solution!")

    #make a list of bots that haven't finished all their commands
    unfinishedBots = statuses.keys()
    solutionStartTime = time()

    #main solution loop - run until all bots are finished
    while(len(unfinishedBots) > 0 and killQueue.empty()):

        #updates statuses
        while(not SolutionQueue.empty()):
            #update the status
            statusUpdate = SolutionQueue.get()

            #if the status is to stop the solution
            if(statusUpdate == str("Stop Solution")):
                quit()

            statuses[statusUpdate[0]] = (statusUpdate[0], statusUpdate[1])

        #if a command for the bot was found
        foundCommand = False

        #issues commands / check for finished bots
        for bot in unfinishedBots:

            for command in solutionsCommands:

                #if the bot is ready for a new command
                if((statuses[bot][1] == 0)):

                    if(command[0] == "B100"):
                        #if the command is a routeing command

                        if(validateCommand(command, OverseerData, 4, True)):
                            #if the command is valid

                            #if the command is for the bot
                            if(command[1] == bot):
                                foundCommand = True

                                if(solutionStartTime + float(command[2]) < time()):
                                    #if the command is supposed to start now
                                    routeRequest = GUIInMessage(bot, "Route", command[3], Direct=False)
                                    GuiInQueue.put(routeRequest)

                                    #mark that the bot is going to complete the command
                                    command[0] = "Complete"

                                    #mark that the bot has been issued a command
                                    statuses[bot] = (bot, 1)

                                else:
                                    #command is good - just need to wait to run it
                                    break

                        else:
                            print("Invalid routing command: " + str(command[0]) + " " + str(command[1]) + ". Skipping!")

                            command[0] = "Skipped"

                    elif(command[0] == "S100"):
                        #if the commmand is a transfer to bot command

                        if(validateCommand(command, OverseerData, 4, True)):
                            #if the command is valid

                            #if the command is for the bot
                            if(command[1] == bot):
                                if(solutionStartTime + float(command[2]) < time()):
                                    #if the command is supposed to start now
                                    #three steps in this
                                    # - 1 send bot wait command
                                    # - 2 send bot item
                                    # - 3 remove item from station

                                    #1
                                    waitCommand = GUIInMessage(bot, "commandIssue", 7, Direct=False)
                                    GuiInQueue.put(waitCommand)

                                    # 2 and 3
                                    stationDispenseRequest = GUIInMessage(command[3], "DispenseStationItem", bot, Direct=False)
                                    GuiInQueue.put(stationDispenseRequest)

                                    #mark that the bot is going to complete the command
                                    command[0] = "Complete"

                                    #mark that the bot has been issued a command
                                    statuses[bot] = (bot, 1)
                                else:
                                    #command is good - just need to wait to run it
                                    break
                        else:
                            print("Invalid transfer command: " + str(command[0]) + " " + str(command[1]) + ". Skipping!")

                            command[0] = "Skipped"

                    elif(command[0] == "S101"):
                        #if the command is a transfer from bot command

                        if(validateCommand(command, OverseerData, 4, True)):
                            #if the command is valid

                            #if the command is for the bot
                            if(command[1] == bot):
                                if(solutionStartTime + float(command[2]) < time()):
                                    #if the command is supposed to start now

                                    #1
                                    waitCommand = GUIInMessage(bot, "commandIssue", 7, Direct=False)
                                    GuiInQueue.put(waitCommand)

                                    # 2 and 3
                                    stationDispenseRequest = GUIInMessage(command[3], "CollectStationItem", bot, Direct=False)
                                    GuiInQueue.put(stationDispenseRequest)

                                    #mark that the bot is going to complete the command
                                    command[0] = "Complete"

                                    #mark that the bot has been issued a command
                                    statuses[bot] = (bot, 1)
                                else:
                                    #command is good - just need to wait to run it
                                    break
                        else:
                            print("Invalid transfer command: " + str(command[0]) + " " + str(command[1]) + ". Skipping!")

                            command[0] = "Skipped"
                    elif(not (command[0] == "Skipped" or command[0] == "Complete")):
                        #send command to configuration manager
                        processConfigurationCommand(command, GuiInQueue, OverseerData)

    print("Finished Solution!")


import sys,os, nltk,string,re
import pandas as pd
from sklearn.multioutput import MultiOutputRegressor
from sklearn.linear_model import Lasso,MultiTaskLasso,ElasticNet
from sklearn.feature_extraction.text import CountVectorizer # To get a vector of occurences
from nltk.corpus import stopwords
sys.path.insert(1, os.path.join(sys.path[0], '..'))
from config import elastic
import pickle
nltk.download('stopwords')
# cleaning the stopwords from the corpus will help in predictions later
stop_words = set(stopwords.words('english'))

# Set up regressor early so it runs  whenever class is called
multiple_class_regression = MultiOutputRegressor(ElasticNet(alpha=0.0001,max_iter=10000,random_state=1999, selection='random',normalize=True))

# helper function
def clean_stop_words(string):
    return ' '.join([word for word in string.split(' ') if word not in stop_words])

class Emotions():
    """
    This class is used to score a song by its emotional content using an ElasticNEt multiclass regressor.
    It first checks for the presence of a pretrained model in .sav format to cu down on processing time.
    if one is not found, it pulls data from ElasticSearch to train and fit the model.
    """
    def __init__(self):
        try: # load both models
            self.emotions_model = pickle.load(open('./saved_models/emotions_model.sav', 'rb'))
            self.vectorize = pickle.load(open('./saved_models/vectorizer.sav', 'rb'))
        except FileNotFoundError: # if  either model isnt present then...
            self.vectorize = CountVectorizer()
            results_dictionary = elastic().search(index='songs',size=100)['hits']['hits']
            data = pd.DataFrame([song['_source']['doc'] for song in results_dictionary])
            y = data[['anger','fear','joy','sadness','surprise']]
            y = [list(y.iloc[row]) for row in range(len(y))]
            X = list(data['cleaned_lyrics'])
            X = [clean_stop_words(lyrics) for lyrics in X]
            X = self.vectorize.fit_transform(X)
            self.emotions_model = multiple_class_regression.fit(X, y)
            # the following write the pickle files out
            pickle.dump(self.emotions_model, open('./saved_models/emotions_model.sav', 'wb'))
            pickle.dump(self.vectorize, open('./saved_models/vectorizer.sav', 'wb')) # this needs to be here so the vectorizer later is using the same instance and avoids fitting issues

    def predict(self,song_string):
        """
        Used for the API endpoint, this returns predictions of emotions based on the model that weve trained above
        """
        song_to_predict = self.vectorize.transform(song_string)
        return self.emotions_model.predict(song_to_predict)
if __name__ == "__main__":
    test = Emotions()
    print(test.predict(['yeah yeah oh love thing  working day long im ready come home mm mm guys roll eyes dont realize want want say im wrapped around finger dont understand got diamond hand  baby love thing whoa baby love thing yeah  sure could hang around complain way things ought yeah theres trouble world youre girl whose open arms really need thats come runnin side let em call crazy cant denied  baby love thing whoa ah baby love thing yeah  last name thing explained make feel inside way hold every night  love thing whoa oh baby love thing yeah  go love thing  say im wrapped around finger dont understand got diamond hand baby love thing whoa oh baby love thing yeah come love thing whoa oh baby love thing yeah oh love thing whoa oh sugar love thing aint diamond ring love thing whoa oh baby love thing love love love thing']))


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

def validate(doc,method):
	if doc.is_subcontracting_warehouse == 1:
		#Allow only 1 Subcontracting Warehouse in System
		other_subcontracting_warehouses = frappe.db.sql("""SELECT name FROM `tabWarehouse`
			WHERE docstatus = 0 AND is_subcontracting_warehouse = 1 AND name != '%s'"""
			%doc.name, as_list=1)
		if other_subcontracting_warehouses:
			frappe.throw(("Warehouse {0} already alloted as Subcontracting Warehouse \
				and only 1 Subcontracting Warehouse is Allowed").\
				format(other_subcontracting_warehouses[0][0]))
	if doc.is_group == 0:
		if not doc.type_of_warehouse:
			frappe.throw("Type of Warehouse is Mandatory for {}".format(doc.name))
		other_serial = frappe.db.sql("""SELECT name FROM `tabWarehouse`
			WHERE docstatus=0 AND is_group=0 AND name!='%s'
			AND listing_serial = %s"""%(doc.name, doc.listing_serial), as_list=1)
		if len(other_serial)>0:
			frappe.throw("Listing Serial: {} already Assigned to Warehouse {}".format(doc.listing_serial, other_serial[0][0]))

		if doc.short_code:
			oth_short_code = frappe.db.sql("""SELECT name FROM `tabWarehouse` WHERE docstatus=0 AND is_group=0
				AND name != '%s' AND short_code = '%s'"""%(doc.name, doc.short_code), as_list=1)
			if len(oth_short_code)>0:
				frappe.throw("Short Code: {} already Assigned to Warehouse {}".format(doc.short_code, oth_short_code[0][0]))
		else:
			frappe.throw("Short Code is Mandatory for {}".format(doc.name))


# My program structure template for AoC:

import sys

def main():
	# read data file
	inputFile = sys.argv[1] if len(sys.argv) >= 2 else "example.txt"
	inputData = []
	with open(inputFile, "r") as fobj:
		lines = fobj.readlines()

	# solve it
	for line in lines:
		line = line.strip()

	# result
	print("Part 1:")

if __name__ == "__main__":
	main()