import open3d as o3d
import cv2
import yaml
import numpy as np
import argparse
import os

def read_camera_configuration(filepath, width=None, height=None):
    """ Reads yaml file containing camera matrices. Can be downsampled"""
    if height is not None and width is None:
        raise ValueError("Height can't be set if width is None")
    intrinsic_all = []
    extrinsic_all = []

    inv_intrinsic_all = []
    inv_extrinsic_all = []

    width_all = []
    height_all = []
    k0_all = []
    k1_all = []

    intrinsic = np.eye(4, dtype=np.float32)
    extrinsic = np.eye(4, dtype=np.float32)
    dist_coeffs = np.zeros((2, 1))
    with open(filepath, 'r') as file:
        camera_params = yaml.load(file, Loader=yaml.Loader)
        num_cam = len(camera_params["intrinsics"])

    for i in range(num_cam):
        img_width = camera_params["intrinsics"][i]["img_width"]
        img_height = camera_params["intrinsics"][i]["img_height"]

        if width is None:
            width = img_width
        ratio = img_height / img_width
        if height is None:
            height = int(width * ratio)

        width_factor = width / img_width
        height_factor = height / img_height

        intrinsic[0, 0] = camera_params["intrinsics"][i]["fx"] * width_factor
        intrinsic[1, 1] = camera_params["intrinsics"][i]["fy"] * height_factor
        intrinsic[0, 2] = camera_params["intrinsics"][i]["cx"] * width_factor
        intrinsic[1, 2] = camera_params["intrinsics"][i]["cy"] * height_factor

        k0 = camera_params["intrinsics"][i]["dist_k0"]
        k1 = camera_params["intrinsics"][i]["dist_k1"]
        rotation = np.array(camera_params["extrinsics"][i]["rotation"]["data"], dtype=float)

        if rotation.shape[0] == 3:
            extrinsic[:3, :3], _ = cv2.Rodrigues(rotation)
        else:
            extrinsic[:3, :3] = rotation.reshape(3, 3)
        extrinsic[:3, 3] = np.array(camera_params["extrinsics"][i]["translation"]["data"])

        #  append to output
        intrinsic_all.append(np.copy(intrinsic))
        extrinsic_all.append(np.copy(extrinsic))
        inv_intrinsic_all.append(np.linalg.inv(intrinsic))
        inv_extrinsic_all.append(np.linalg.inv(extrinsic))
        width_all.append(width)
        height_all.append(height)
        k0_all.append(k0)
        k1_all.append(k1)

    intrinsic_all = np.stack(intrinsic_all)
    extrinsic_all = np.stack(extrinsic_all)
    inv_intrinsic_all = np.stack(inv_intrinsic_all)
    inv_extrinsic_all = np.stack(inv_extrinsic_all)
    width_all = np.stack(width_all)
    height_all = np.stack(height_all)

    return {
        "intrinsic": intrinsic_all,
        "extrinsic": extrinsic_all,
        "inv_intrinsic": inv_intrinsic_all,
        "inv_extrinsic": inv_extrinsic_all,
        "width": width_all,
        "height": height_all,
        "k0": k0_all,
        "k1": k1_all
    }

def generate_masks_from_mesh(conf_filepath, mesh_filepath, output_folder="output"):
    camera_opt = read_camera_configuration(conf_filepath)
    mesh = o3d.io.read_triangle_mesh(mesh_filepath)
    os.makedirs(output_folder, exist_ok=True)
    pose_folder = os.path.join(output_folder, 'pose')
    mask_folder = os.path.join(output_folder, 'mask')

    os.makedirs(output_folder, exist_ok=True)
    os.makedirs(pose_folder, exist_ok=True)
    os.makedirs(mask_folder, exist_ok=True)
    base_intrinsic = camera_opt['intrinsic'][0, :3, :3]
    np.savetxt(os.path.join(output_folder,'camera.txt'), base_intrinsic)

    for i in range(len(camera_opt['intrinsic'])):
        intrinsic = o3d.camera.PinholeCameraIntrinsic(camera_opt["width"][i], camera_opt["height"][i],
                                                       camera_opt['intrinsic'][i, :3, :3])
        extrinsic_matrix = camera_opt['extrinsic'][i]
        np.save(os.path.join(pose_folder, 'pose' + str(i)), extrinsic_matrix[:3, :])
        render = o3d.visualization.rendering.OffscreenRenderer(camera_opt["width"][i], camera_opt["height"][i])

        # background color
        render.scene.set_background([0.0, 0.0, 0.0, 1.0])
        # mesh color
        mesh.paint_uniform_color([1.0, 1.0, 1.0])
        mtl = o3d.visualization.rendering.MaterialRecord()
        mtl.base_color = [1.0, 1.0, 1.0, 1.0]
        mtl.shader = "defaultUnlit"

        render.scene.add_geometry("mesh", mesh, mtl)

        # render the scene with respect to the camera
        render.setup_camera(intrinsic, extrinsic_matrix)
        img_o3d = render.render_to_image()

        o3d.io.write_image(os.path.join(mask_folder, "mask" + str(i)+".png"), img_o3d, 9)
        # must delete to work inside loop
        del render


# WORKING WITH THE TAR FILES
import tarfile # importing the "tarfile" module

file = tarfile.open('us-climate-normals_1991-2020_monthly_multivariate_by-station_c20210609.tar.gz') # open file FOR MONTHLY
file.extractall('./monthly') # extract files
file.close() # close file

file = tarfile.open('us-climate-normals_1991-2020_annualseasonal_multivariate_by-station_c20210609.tar.gz') #open file FOR ANNUAL
file.extractall('./annual') #extract files
file.close() #close file

# DELETEING ALL CSV FILES THAT ARE NOT TEXAS STATIONS
import os
import pandas as pd

directory = "C:/Users/vnelliott/Downloads/monthly" #PROCESS FOR MONTHLY
target_string = "TX US"

for filename in os.listdir(directory): # iterate over files in directory
    if filename.endswith(".csv"):
        filepath = os.path.join(directory, filename)

        df = pd.read_csv(filepath) # read in CSV data

        match_found = any(df.apply(lambda x: target_string in str(x), axis=0)) # check if target string is present in any column

        if not match_found: # if no match is found, delete the file
            os.remove(filepath)

directory = "C:/Users/vnelliott/Downloads/annual" #PROCESS FOR ANNUAL
target_string = "TX US"

for filename in os.listdir(directory): # iterate over files in directory
    if filename.endswith(".csv"):
        filepath = os.path.join(directory, filename)

        df = pd.read_csv(filepath) # read in CSV data

        match_found = any(df.apply(lambda x: target_string in str(x), axis=0)) # check if target string is present in any column

        if not match_found: # if no match is found, delete the file
            os.remove(filepath)

#MERGING CSV FILES INTO ONE (able to include all columns even if not all files have them)
folder_path = 'C:/Users/vnelliott/Downloads/monthly' #DEFINING PATH FOR MONTHLY FOLDER

merged_df = pd.DataFrame() # Create an empty DataFrame to store the merged data

for filename in os.listdir(folder_path): # Loop through all CSV files in the folder
    if filename.endswith('.csv'):
        df = pd.read_csv(os.path.join(folder_path, filename)) # Load the CSV file into a pandas DataFrame

        merged_df = pd.concat([merged_df, df], ignore_index=True) # Merge the DataFrame with the merged_df DataFrame

merged_df.to_csv('monthlymerged.csv', index=False) # Write the merged DataFrame to a new CSV file

folder_path = 'C:/Users/vnelliott/Downloads/annual' #DEFINING PATH FOR ANNUAL FOLDER

merged_df = pd.DataFrame() # Create an empty DataFrame to store the merged data

for filename in os.listdir(folder_path): # Loop through all CSV files in the folder
    if filename.endswith('.csv'):
        df = pd.read_csv(os.path.join(folder_path, filename)) # Load the CSV file into a pandas DataFrame

        merged_df = pd.concat([merged_df, df], ignore_index=True) # Merge the DataFrame with the merged_df DataFrame

merged_df.to_csv('annualmerged.csv', index=False) # Write the merged DataFrame to a new CSV file

#DELETEING UNNEEDED COLUMNS
df = pd.read_csv('monthlymerged.csv', usecols=['STATION', 'NAME', 'LATITUDE', 'LONGITUDE', 'ELEVATION', 'DATE', 'MLY-PRCP-NORMAL']) # Read in the CSV file and keep only needed columns for MONTHLY

df.to_csv('monthly.csv', index=False) # Write the modified dataframe to a new CSV file

df = pd.read_csv('annualmerged.csv', usecols=['STATION', 'NAME', 'LATITUDE', 'LONGITUDE', 'ELEVATION', 'ANN-SNOW-NORMAL', 'ANN-HTDD-NORMAL', 'DJF-TMIN-NORMAL', 'JJA-TMAX-NORMAL', 'ANN-TMIN-AVGNDS-LSTH032', 'ANN-CLDD-BASE72', 'ANN-TMIN-PRBGSL-T32FP50', 'ANN-TMIN-PRBLST-T32FP10', 'ANN-TMIN-PRBFST-T32FP10', 'ANN-TMIN-PRBFST-T32FP50', 'ANN-PRCP-AVGNDS-GE001HI', 'ANN-SNOW-AVGNDS-GE001TI', 'ANN-SNWD-AVGNDS-GE001WI', 'ANN-TMIN-PRBLST-T32FP50']) # Read in the CSV file and keep only needed columns for ANNUAL

df.to_csv('annual.csv', index=False) # Write the modified dataframe to a new CSV file


from my_task.main import app

# 任务队列的链接地址
broker_url = "redis://192.168.92.128:6379/11"
# 结果队列的链接地址
result_backend = "redis://192.168.92.128:6379/12"

# 定时任务调度
app.conf.beat_schedule = {
    'check_order_status': {
        # 指定定时执行的哪个任务  直接写任务名
        'task': 'check_order',
        # 定时任务执行的周期
        'schedule': 90.0,
        # 定时任务所需参数 有参数就传递
        # 'args': (16, 16)
    },
}

# 1. 现在终端中启动celery定时任务
# 		celery -A my_task.main beat
# 2. 再新开一个终端，执行celery的异步任务
#


# Jonathan Lynch
# 4/4/20
# https://youtu.be/1ZXSwZqXeZ4
# "I have not given or received any unauthorized assistance on this assignment."

def coprime(a,b):
    'funtion that determines whether two numbers are coprime'
    divisors = []
    for x in range(2, min(a,b)+1):           # iterate from 2 through min number
        if min(a,b)%x == 0:                  # determine divisors of lowest number
            divisors.append(x)               # add divisors to empty list
    for y in divisors:
        if max(a,b)%y == 0:                  # test if any divisors of min are also divisors of max
            return False                     # if max and min share a common divisor return False
    return True                              # return True if no divisors shared

def coprime_test_loop():
    'function that requires user input to generate coprime message response'
    while True:
        a = input('Please enter a number: ')                     # prompt user to enter number
        a = int(a)                                               # convert str input into an int
        b = input('Please enter a number: ')                     # prompt user to enter number
        b = int(b)                                               # convert str input into an int
        if coprime(a,b) == False:                                # test whether coprime
            print('The numbers you entered are not coprime.')    # print message if not coprime
        else:
            print('The numbers you entered are coprime.')        # print message if coprime
        stop = input('Would you like to stop (yes/no)? ')        # determine if user wants to stop
        if stop == 'yes':
            break                                                # exit while loop if user wants to stop


from functools import reduce

from django_jinja import library
from dateutil.parser import parse

@library.global_function
def updated_querystring(request, params):
    """Updates current querystring with a given dict of params, removing
    existing occurrences of such params. Returns a urlencoded querystring."""
    original_params = request.GET.copy()
    for key in params:
        if key in original_params:
            original_params.pop(key)
    original_params.update(params)
    return original_params.urlencode()

@library.filter
def format_date(s):
    try:
        dt = parse(s, yearfirst=True)
        return dt.strftime("%d/%m/%Y")
    except ValueError:
        return s

def ukr_plural(value, *args):
    value = int(value) % 100
    rem = value % 10
    if value > 4 and value < 20:
        return args[2]
    elif rem == 1:
        return args[0]
    elif rem > 1 and rem < 5:
        return args[1]
    else:
        return args[2]

@library.filter
def uk_plural(value, args):
    args = args.split(',')
    return ukr_plural(value, *args)

def deepgetattr(obj, attr):
    """Recurses through an attribute chain to get the ultimate value."""

    try:
        return reduce(getattr, attr.split('.'), obj)
    except AttributeError:
        return None

@library.filter
def highlight(obj, field_name):
    if hasattr(obj.meta, "highlight") and hasattr(obj.meta.highlight, field_name):
        return " ".join(getattr(obj.meta.highlight, field_name))
    else:
        return deepgetattr(obj, field_name)


#!/usr/bin/python3

"""
Script that queries the Reddit API and prints the titles of the first
10 hot posts listed for a given subreddit
"""

import requests

def top_ten(subreddit):
    """Prints a subreddits 10 of hotposts"""

    listing = "hot"
    url = "https://www.reddit.com/r/{}/{}.json".format(subreddit, listing)
    headers = {"User-agent": "Mozilla/5.0"}
    response = requests.get(url, headers=headers)

    if response.status_code == 200:
        json_data = response.json()
        hot_posts = []
        for i, post in enumerate(json_data['data']['children']):
            if i >= 10:
                break
            titles = post['data']['title']
            hot_posts.append(titles)
        for items in hot_posts:
            print(items)
    else:
        print('None')


import json
import boto3

def get_input(prompt, validation=None):
    try:
        s = raw_input(prompt + ': ')
    except EOFError:
        if validation == 'NONBLANK':
            print("Sorry, I can't accept this treatment.")
            s = get_input(prompt, validation)
        else:
            s = ''
    return s.lower()

def main():
    client = boto3.client('lambda')
    response = client.invoke(FunctionName='AddTokenFunction')
    if response['StatusCode'] == 200:
        payload = json.loads(response['Payload'].read())
        AccessKey = payload['AccessKey']
        AccessKeyId = AccessKey['AccessKeyId']
        SecretKey = AccessKey['SecretAccessKey']
        UserName = AccessKey['UserName']
        s = get_input("Would you like to add owner/location details? y/n", 'NONBLANK')
        if s.startswith('y'):
            location = get_input("Please enter the location you'll store these credentials (optional)")
            owner = get_input("Please enter the owner of these credentials (optional)")
            notes = get_input("Please enter any notes about these credentials (optional)")
            expiry = get_input("Please enter an expiry for these credentials  (optional, yyyy-mm-dd)")
            payload = {"Location": location, "Owner": owner, "Notes": notes, "AccessKeyId": AccessKeyId}
            if expiry != "":
                payload['ExpiresAt'] = expiry
            payload = json.dumps(payload)
            r = client.invoke(
                FunctionName='UpdateTokenFunction',
                Payload=payload
                )
            import pprint
            pprint.pprint(r)
        s = get_input("Store credentials to file? Y/n")
        if s == "" or s.startswith('y'):
            with open('%s-credentials' % UserName, 'w') as f:
                f.write("[default]\naws_access_key_id = %s\naws_secret_access_key = %s\n" %
                        (AccessKeyId, SecretKey))
            print("Wrote aws configuration for %s to %s" % (UserName, UserName+'-credentials'))
        s = get_input("print environment variable exports? Y/n")
        if s == "" or s.startswith('y'):
            print("export AWS_ACCESS_KEY_ID=%s\nexport AWS_SECRET_ACCESS_KEY=%s\n" %
                  (AccessKeyId, SecretKey))

main()


import torch

import numpy as np
import torch.nn.functional as F

from geoopt import linalg

class SPDSW:
    """
        Class for computing SPDSW distance and embedding

        Parameters
        ----------
        shape_X : int
            dim projections
        num_projections : int
            Number of projections
        num_ts : int
            Number of timestamps for quantiles, default 20
        device : str
            Device for computations, default None
        dtype : type
            Data type, default torch.float
        random_state : int
            Seed, default 123456
        sampling : str
            Sampling type
                - "spdsw": symetric matrices + geodesic projection
                - "logsw": unit norm matrices + geodesic projection
                - "sw": unit norm matrices + euclidean projection
            Default "spdsw"
        """

    def __init__(
        self,
        shape_X,
        num_projections,
        num_ts=20,
        device=None,
        dtype=torch.float,
        random_state=123456,
        sampling="spdsw",
    ):

        if device is None:
            device = "cuda" if torch.cuda.is_available() else "cpu"

        if sampling not in ["spdsw", "logsw", "sw", "aispdsw"]:
            raise Exception(
                "'sampling' should be in ['spdsw', 'logsw', 'sw', 'aispdsw']"
            )

        self.generate_projections(
            shape_X, num_projections, num_ts,
            device, dtype, random_state, sampling
        )

        self.sampling = sampling

    def generate_projections(self, shape_X, num_projections, num_ts,
                             device, dtype, random_state, sampling):
        """
        Generate projections for sampling

        Parameters
        ----------
        shape_X : int
            dim projections
        num_projections : int
            Number of projections
        device : str
            Device for computations
        dtype : type
            Data type
        random_state : int
            Seed
        sampling : str
            Sampling type
                - "spdsw": symetric matrices + geodesic projection
                - "logsw": unit norm matrices + geodesic projection
                - "sw": unit norm matrices + euclidean projection
        """

        rng = np.random.default_rng(random_state)

        if sampling == "spdsw":

            # Random projection directions, shape (d-1, num_projections)
            theta = rng.normal(size=(num_projections, shape_X))
            theta = F.normalize(
                torch.from_numpy(theta), p=2, dim=-1
            ).type(dtype).to(device)

            D = theta[:, None] * torch.eye(
                theta.shape[-1],
                device=device,
                dtype=dtype
            )

            # Random orthogonal matrices
            Z = rng.normal(size=(num_projections, shape_X, shape_X))
            Z = torch.tensor(
                Z,
                dtype=dtype,
                device=device
            )
            Q, R = torch.linalg.qr(Z)
            lambd = torch.diagonal(R, dim1=-2, dim2=-1)
            lambd = lambd / torch.abs(lambd)
            P = lambd[:, None] * Q

            self.A = torch.matmul(
                P,
                torch.matmul(D, torch.transpose(P, -2, -1))
            )

        elif sampling in ["logsw", "sw"]:

            self.A = torch.tensor(
                rng.normal(size=(num_projections, shape_X, shape_X)),
                dtype=dtype,
                device=device
            )

            self.A /= torch.norm(self.A, dim=(1, 2), keepdim=True)

        elif sampling == "aispdsw":
            # Random projection directions, shape (d-1, num_projections)
            theta = rng.normal(size=(num_projections, shape_X))
            theta = F.normalize(
                torch.from_numpy(theta), p=2, dim=-1
            ).type(dtype).to(device)
            theta_sorted, sorter = torch.sort(theta, descending=False)

            perm_matrix = F.one_hot(sorter).type(dtype)
            D_sorted = theta_sorted[:, None] * torch.eye(
                theta.shape[-1],
                dtype=dtype,
                device=device
            )

            # Random orthogonal matrices
            Z = rng.normal(size=(num_projections, shape_X, shape_X))
            Z = torch.tensor(
                Z,
                dtype=dtype,
                device=device
            )
            Q, R = torch.linalg.qr(Z)
            lambd = torch.diagonal(R, dim1=-2, dim2=-1)
            lambd = lambd / torch.abs(lambd)
            P = lambd[:, None] * Q

            self.P = torch.matmul(P, torch.transpose(perm_matrix, -2, -1))
            self.A = D_sorted

        self.ts = torch.linspace(0, 1, num_ts, dtype=dtype, device=device)

    def emd1D(self, u_values, v_values, u_weights=None, v_weights=None, p=1):
        n = u_values.shape[-1]
        m = v_values.shape[-1]

        device = u_values.device
        dtype = u_values.dtype

        if u_weights is None:
            u_weights = torch.full((n,), 1/n, dtype=dtype, device=device)

        if v_weights is None:
            v_weights = torch.full((m,), 1/m, dtype=dtype, device=device)

        # Sort
        u_values, u_sorter = torch.sort(u_values, -1)
        v_values, v_sorter = torch.sort(v_values, -1)

        u_weights = u_weights[..., u_sorter]
        v_weights = v_weights[..., v_sorter]

        # Compute CDF
        u_cdf = torch.cumsum(u_weights, -1)
        v_cdf = torch.cumsum(v_weights, -1)

        cdf_axis, _ = torch.sort(torch.cat((u_cdf, v_cdf), -1), -1)

        u_index = torch.searchsorted(u_cdf, cdf_axis)
        v_index = torch.searchsorted(v_cdf, cdf_axis)

        u_icdf = torch.gather(u_values, -1, u_index.clip(0, n-1))
        v_icdf = torch.gather(v_values, -1, v_index.clip(0, m-1))

        cdf_axis = torch.nn.functional.pad(cdf_axis, (1, 0))
        delta = cdf_axis[..., 1:] - cdf_axis[..., :-1]

        if p == 1:
            return torch.sum(delta * torch.abs(u_icdf - v_icdf), axis=-1)
        if p == 2:
            return torch.sum(delta * torch.square(u_icdf - v_icdf), axis=-1)

        return torch.sum(
            delta * torch.pow(torch.abs(u_icdf - v_icdf), p),
            axis=-1
        )

    def spdsw(self, Xs, Xt, u_weights=None, v_weights=None, p=2):
        """
            Parameters:
            Xs: ndarray, shape (n_batch, d, d)
                Samples in the source domain
            Xt: ndarray, shape (m_batch, d, d)
                Samples in the target domain
            device: str
            p: float
                Power of SW. Need to be >= 1.
        """
        n, _, _ = Xs.shape
        m, _, _ = Xt.shape

        n_proj, d, _ = self.A.shape

        if self.sampling in ["spdsw", "logsw"]:
            # Busemann Coordinates
            log_Xs = linalg.sym_logm(Xs)
            log_Xt = linalg.sym_logm(Xt)

            prod_Xs = (self.A[None] * log_Xs[:, None]).reshape(n, n_proj, -1)
            prod_Xt = (self.A[None] * log_Xt[:, None]).reshape(m, n_proj, -1)

        elif self.sampling in ["sw"]:
            # Euclidean Coordinates
            prod_Xs = (self.A[None] * Xs[:, None]).reshape(n, n_proj, -1)
            prod_Xt = (self.A[None] * Xt[:, None]).reshape(m, n_proj, -1)

        elif self.sampling in ["aispdsw"]:
            Xs2 = torch.matmul(
                torch.matmul(
                    torch.transpose(self.P, -2, -1)[:, None],
                    Xs[None]
                ),
                self.P[:, None]
            )
            Xt2 = torch.matmul(
                torch.matmul(
                    torch.transpose(self.P, -2, -1)[:, None],
                    Xt[None]
                ),
                self.P[:, None]
            )

            LD, pivots = torch.linalg.ldl_factor(Xs2)
            P, L, D_Xs = torch.lu_unpack(LD, pivots)

            LD, pivots = torch.linalg.ldl_factor(Xt2)
            P, L, D_Xt = torch.lu_unpack(LD, pivots)

            log_Xs = torch.transpose(linalg.sym_logm(D_Xs), 0, 1)
            log_Xt = torch.transpose(linalg.sym_logm(D_Xt), 0, 1)

            prod_Xs = (self.A[None]*log_Xs).reshape(n, n_proj, -1)
            prod_Xt = (self.A[None]*log_Xt).reshape(m, n_proj, -1)

        Xps = prod_Xs.sum(-1)
        Xpt = prod_Xt.sum(-1)

        return torch.mean(
            self.emd1D(Xps.T, Xpt.T, u_weights, v_weights, p)
        )

    def get_quantiles(self, x, ts, weights=None):
        """
            Inputs:
            - x: 1D values, size: n_projs * n_batch
            - ts: points at which to evaluate the quantile
        """
        n_projs, n_batch = x.shape

        if weights is None:
            X_weights = torch.full(
                (n_batch,), 1/n_batch, dtype=x.dtype, device=x.device
            )
            X_values, X_sorter = torch.sort(x, -1)
            X_weights = X_weights[..., X_sorter]

        X_cdf = torch.cumsum(X_weights, -1)

        X_index = torch.searchsorted(X_cdf, ts.repeat(n_projs, 1))
        X_icdf = torch.gather(X_values, -1, X_index.clip(0, n_batch-1))

        return X_icdf

    def get_features(self, x, weights=None, p=2):
        """
            Inputs:
            - x: ndarray, shape (n_batch, d, d)
                Samples of SPD
            - weights: weight of each sample, if None, uniform weights
            - p
        """
        num_unifs = len(self.ts)
        n_proj, d, _ = self.A.shape
        n, _, _ = x.shape

        if self.sampling in ["spdsw", "logsw"]:
            log_x = linalg.sym_logm(x)
            Xp = (self.A[None] * log_x[:, None]).reshape(n, n_proj, -1).sum(-1)
        elif self.sampling == "sw":
            Xp = (self.A[None] * x[:, None]).reshape(n, n_proj, -1).sum(-1)
        elif self.sampling == "aispdsw":
            x2 = torch.matmul(
                torch.matmul(
                    torch.transpose(self.P, -2, -1)[:, None],
                    x[None]
                ),
                self.P[:, None]
            )
            LD, pivots = torch.linalg.ldl_factor(x2)
            P, L, D_x = torch.lu_unpack(LD, pivots)
            log_x = torch.transpose(linalg.sym_logm(D_x), 0, 1)
            Xp = (self.A[None]*log_x).reshape(n, n_proj, -1).sum(-1)

        q_Xp = self.get_quantiles(Xp.T, self.ts, weights)

        return q_Xp / ((n_proj * num_unifs) ** (1 / p))


import json
from datetime import date
import calendar

class Pizeria:
    def __init__(self):
        data = {"Monday": {"name": "Four seasons", "price": 100},
                "Tuesday": {"name": "Margarita", "price": 80},
                "Wednesday": {"name": "Gavaian", "price": 150},
                "Thursday": {"name": "Pineappled", "price": 50},
                "Friday": {"name": "Four cheeses", "price": 120},
                "Saturday": {"name": "Family-pizza", "price": 350},
                "Sunday": {"name": "Cono-pizza", "price": 115}
                }
        with open("pizzaoftheday.json", "w") as json_file:
            json.dump(data, json_file, indent=2)

    def __str__(self):
        with open("pizzaoftheday.json", "r") as json_file:
            json_object = json.load(json_file)
        data = "\n".join(list(map(str, json_object.items())))
        data = data.replace("{", " ")
        data = data.replace("}", " ")
        return data

class Pizzaoftheday():
    def __init__(self):
        today = date.today()
        self.day = calendar.day_name[today.weekday()]
        print(self.day)
        if self.day == "Monday":
            self.pizza = Monday()
        elif self.day == "Thursday":
            self.pizza = Thursday()
        elif self.day == "Tuesday":
            self.pizza = Tuesday()
        elif self.day == "Wednesday":
            self.pizza = Wednesday()
        elif self.day == "Friday":
            self.pizza = Friday()
        elif self.day == "Saturday":
            self.pizza = Saturday()
        else:
            self.pizza = Sunday()

    def get_price(self):
        return self.pizza.price

    def get_info(self):
        return self.pizza.name

class Monday(Pizzaoftheday):
    def __init__(self):
        with open("pizzaoftheday.json", "r") as json_file:
            json_object = json.load(json_file)
        self.day = "Monday"
        self.price = json_object["Monday"]["price"]
        self.name = json_object["Monday"]["name"]

    def __str__(self):
        return f'Monday pizza: {self.name}, price: {self.price}'

class Wednesday(Pizzaoftheday):
    def __init__(self):
        with open("pizzaoftheday.json", "r") as json_file:
            json_object = json.load(json_file)
        self.day = "Wednesday"
        self.price = json_object["Wednesday"]["price"]
        self.name = json_object["Wednesday"]["name"]

    def __str__(self):
        return f'Wednesday pizza: {self.name}, price: {self.price}'

class Tuesday(Pizzaoftheday):
    def __init__(self):
        with open("pizzaoftheday.json", "r") as json_file:
            json_object = json.load(json_file)
        self.day = "Tuesday"
        self.price = json_object["Tuesday"]["price"]
        self.name = json_object["Tuesday"]["name"]

    def __str__(self):
        return f'Tuesday pizza: {self.name}, price: {self.price}'

class Thursday(Pizzaoftheday):
    def __init__(self):
        with open("pizzaoftheday.json", "r") as json_file:
            json_object = json.load(json_file)
        self.day = "Thursday"
        self.price = json_object["Thursday"]["price"]
        self.name = json_object["Thursday"]["name"]

    def __str__(self):
        return f'Thursday pizza: {self.name}, price: {self.price}'

class Friday(Pizzaoftheday):
    def __init__(self):
        with open("pizzaoftheday.json", "r") as json_file:
            json_object = json.load(json_file)
        self.day = "Friday"
        self.price = json_object["Friday"]["price"]
        self.name = json_object["Friday"]["name"]

    def __str__(self):
        return f'Friday pizza: {self.name}, price: {self.price}'

class Saturday(Pizzaoftheday):
    def __init__(self):
        with open("pizzaoftheday.json", "r") as json_file:
            json_object = json.load(json_file)
        self.day = "Saturday"
        self.price = json_object["Saturday"]["price"]
        self.name = json_object["Saturday"]["name"]

    def __str__(self):
        return f'Saturday pizza: {self.name}, price: {self.price}'

class Sunday(Pizzaoftheday):
    def __init__(self):
        with open("pizzaoftheday.json", "r") as json_file:
            json_object = json.load(json_file)
        self.day = "Sunday"
        self.price = json_object["Sunday"]["price"]
        self.name = json_object["Sunday"]["name"]

    def __str__(self):
        return f'Sunday pizza: {self.name}, price: {self.price}'

class CustomPizza:

    def __init__(self):
        self.pizza = Pizzaoftheday()
        self.add_ingredients
        self.price = self.add_ingredients()

    def add_ingredients(self):
        with open("ingredients.json", "r") as json_file:
            json_object = json.load(json_file)
        total = self.pizza.get_price()
        print(json_object)
        while 1 == 1:
            data = input("Enter ingredient you want to add (enter 'x' for exit): ")
            if data in json_object.keys():
                total += json_object[str(data)]
                print(total)
            if data == "x":
                break
        return total

    def get_price(self):
        return self.price

    def get_info(self):
        return f'Custom pizza-of-the-day'

class Order():
    def __init__(self):
        self.make_order
        self.total_price = self.make_order()

    def make_order(self):

        order = {}
        number = input("How many pizzas u want to order? ")
        dayspizzas = input("How many of them is pizza-of-the-day? ")
        custompizzas = int(number) - int(dayspizzas)
        for item in range(int(dayspizzas)):
            order[item] = Pizzaoftheday()
        for value in range(int(custompizzas)):
            order[value + int(dayspizzas)] = CustomPizza()
        total = 0
        for item in order:
            total += order[item].get_price()

        return total

    def get_price(self):
        return f'Total price of order: {self.total_price}'

x = Pizeria()
z = Order()
print(z.get_price())


"""Credential proposal message."""

from typing import Sequence

from marshmallow import EXCLUDE, ValidationError, fields, validates_schema

from .....messaging.agent_message import AgentMessage, AgentMessageSchema
from .....messaging.decorators.attach_decorator import (
    AttachDecorator,
    AttachDecoratorSchema,
)
from ..message_types import CRED_20_PROPOSAL, PROTOCOL_PACKAGE
from .cred_format import V20CredFormat, V20CredFormatSchema
from .inner.cred_preview import V20CredPreview, V20CredPreviewSchema

HANDLER_CLASS = (
    f"{PROTOCOL_PACKAGE}.handlers.cred_proposal_handler.V20CredProposalHandler"
)

class V20CredProposal(AgentMessage):
    """Credential proposal."""

    class Meta:
        """V20CredProposal metadata."""

        handler_class = HANDLER_CLASS
        schema_class = "V20CredProposalSchema"
        message_type = CRED_20_PROPOSAL

    def __init__(
        self,
        _id: str = None,
        *,
        comment: str = None,
        credential_preview: V20CredPreview = None,
        formats: Sequence[V20CredFormat] = None,
        filters_attach: Sequence[AttachDecorator] = None,
        **kwargs,
    ):
        """Initialize credential proposal object.

        Args:
            comment: optional human-readable comment
            credential_proposal: proposed credential preview
            formats: acceptable attachment formats
            filters_attach: list of attachments filtering credential proposal

        """
        super().__init__(_id=_id, **kwargs)
        self.comment = comment
        self.credential_preview = credential_preview
        self.formats = list(formats) if formats else []
        self.filters_attach = list(filters_attach) if filters_attach else []

    def attachment(self, fmt: V20CredFormat.Format = None) -> dict:
        """Return attached filter.

        Args:
            fmt: format of attachment in list to decode and return

        """
        target_format = (
            fmt
            if fmt
            else next(
                filter(
                    lambda ff: ff,
                    [V20CredFormat.Format.get(f.format) for f in self.formats],
                ),
                None,
            )
        )
        return (
            target_format.get_attachment_data(self.formats, self.filters_attach)
            if target_format
            else None
        )

class V20CredProposalSchema(AgentMessageSchema):
    """Credential proposal schema."""

    class Meta:
        """Credential proposal schema metadata."""

        model_class = V20CredProposal
        unknown = EXCLUDE

    comment = fields.Str(
        required=False,
        allow_none=True,
        metadata={"description": "Human-readable comment"},
    )
    credential_preview = fields.Nested(
        V20CredPreviewSchema,
        required=False,
        allow_none=False,
        metadata={"description": "Credential preview"},
    )
    formats = fields.Nested(
        V20CredFormatSchema,
        many=True,
        required=True,
        metadata={"description": "Attachment formats"},
    )
    filters_attach = fields.Nested(
        AttachDecoratorSchema,
        data_key="filters~attach",
        required=True,
        many=True,
        metadata={
            "description": (
                "Credential filter per acceptable format on corresponding identifier"
            )
        },
    )

    @validates_schema
    def validate_fields(self, data, **kwargs):
        """Validate attachments per format."""

        def get_attach_by_id(attach_id):
            """Return attachment with input identifier."""
            for atch in attachments:
                if atch.ident == attach_id:
                    return atch
            raise ValidationError(f"No attachment for attach_id {attach_id} in formats")

        formats = data.get("formats") or []
        attachments = data.get("filters_attach") or []
        if len(formats) != len(attachments):
            raise ValidationError("Formats/attachments length mismatch")

        for fmt in formats:
            atch = get_attach_by_id(fmt.attach_id)
            cred_format = V20CredFormat.Format.get(fmt.format)

            if cred_format:
                cred_format.validate_fields(CRED_20_PROPOSAL, atch.content)