import time
import unittest
from unittest.mock import Mock, patch

from nuplan.common.actor_state.state_representation import TimePoint
from nuplan.planning.scenario_builder.test.mock_abstract_scenario import MockAbstractScenario
from nuplan.planning.simulation.history.simulation_history_buffer import SimulationHistoryBuffer
from nuplan.planning.simulation.planner.abstract_planner import PlannerInput
from nuplan.planning.simulation.planner.log_future_planner import LogFuturePlanner
from nuplan.planning.simulation.planner.planner_report import MLPlannerReport
from nuplan.planning.simulation.simulation_time_controller.simulation_iteration import SimulationIteration

class TestLogFuturePlanner(unittest.TestCase):
    """
    Test LogFuturePlanner class
    """

    def _get_mock_planner_input(self) -> PlannerInput:
        """
        Returns a mock PlannerInput for testing.
        :return: PlannerInput.
        """
        buffer = SimulationHistoryBuffer.initialize_from_list(
            1, [self.scenario.initial_ego_state], [self.scenario.initial_tracked_objects]
        )
        return PlannerInput(iteration=SimulationIteration(TimePoint(0), 0), history=buffer, traffic_light_data=None)

    def setUp(self) -> None:
        """Inherited, see superclass."""
        self.scenario = MockAbstractScenario(number_of_future_iterations=20)
        self.num_poses = 10
        self.future_time_horizon = 5
        self.planner = LogFuturePlanner(self.scenario, self.num_poses, self.future_time_horizon)

    def test_name(self) -> None:
        """Tests planner name is set correctly."""
        # Call method under test
        result = self.planner.name()

        # Assertions
        self.assertEqual(result, "LogFuturePlanner")

    @patch('nuplan.planning.simulation.planner.log_future_planner.DetectionsTracks')
    def test_observation_type(self, mock_detection_tracks: Mock) -> None:
        """Tests observation type is set correctly."""
        # Call method under test
        result = self.planner.observation_type()

        # Assertions
        self.assertEqual(result, mock_detection_tracks)

    def test_compute_trajectory(self) -> None:
        """Test compute_trajectory"""
        planner_input = self._get_mock_planner_input()
        start_time = time.perf_counter()

        # Call method under test
        result = self.planner.compute_trajectory(planner_input)

        compute_trajectory_time = time.perf_counter() - start_time
        self.assertEqual(len(result.get_sampled_trajectory()), self.num_poses + 1)

        # Basic sanity checks on the planner report
        planner_report = self.planner.generate_planner_report()
        self.assertEqual(len(planner_report.compute_trajectory_runtimes), 1)
        self.assertNotIsInstance(planner_report, MLPlannerReport)
        self.assertAlmostEqual(planner_report.compute_trajectory_runtimes[0], compute_trajectory_time, delta=0.1)

    def test_compute_trajectory_fail_extraction_previous_available(self) -> None:
        """
        Test compute_trajectory when future ego extraction from scenario fails and planner should fall back on previous
        trajectory.
        """
        previous_trajectory = Mock()
        self.planner._trajectory = previous_trajectory
        planner_input = self._get_mock_planner_input()

        with patch.object(self.scenario, 'get_ego_future_trajectory', side_effect=AssertionError):
            # Call method under test
            result = self.planner.compute_trajectory(planner_input)

        # Should fall back on previous trajectory
        self.assertEqual(result, previous_trajectory)

    def test_compute_trajectory_fail_extraction_no_previous(self) -> None:
        """
        Test compute_trajectory when future ego extraction from scenario fails and there is no prior trajectory
        to fall back on.
        """
        self.planner._trajectory = None
        planner_input = self._get_mock_planner_input()

        with patch.object(self.scenario, 'get_ego_future_trajectory', side_effect=AssertionError):
            with self.assertRaises(RuntimeError):
                # Call method under test
                _ = self.planner.compute_trajectory(planner_input)

if __name__ == '__main__':
    unittest.main()


# -*- coding: utf-8 -*-
"""
Created on Tue Dec  1 00:55:44 2020

@author: EVer
"""

import numpy as np

def softmax(a):
    c = np.max(a)
    exp_a = np.exp(a - c)
    exp_sum_a = np.sum(exp_a)
    y = exp_a / exp_sum_a

    return y

a = np.array([0.3, 2.9, 4.0])
y = softmax(a)
print(y)
print(np.sum(y))


from module.processing import *
# from module.firebaseupload import *
import pickle, os
import configparser
from tqdm import tqdm

def clear():
    if os.name in ('nt', 'dos'):
        os.system('cls')
    else:
        os.system('clear')

def main():
    clear()
    conf = configparser.ConfigParser()
    conf.read('version.ini', encoding='utf-8')
    version = conf['DEFAULT']['version']
    print(f'''
    화학테러 논문조 더미 및 계측기 데이터 가공 프로그램 ({version})

    - 이 프로그램을 통해 CSV파일을 엑셀파일로 가공하게 됩니다.

    중요!!!: 폴더 안에 가공된 파일이 이미 있다면 덮어씌워집니다.
    주의!! : 동시에 실험했던 같은 종류의 데이터만 한 폴더에 넣으세요.
    참고   : 엑셀 내 차트 디자인은 프로그램에서 적용할 수 없습니다. 엑셀에서 직접 서식파일을 선택하세요.''')

    # try:
    #     rtdb = Database()
    #     print('\n\n[정보] 인터넷 연결 성공')
    # except:
    #     rtdb = None
    #     print('\n\n[경고] 인터넷 연결 실패 - 가공된 데이터가 인터넷에 업로드되지 않습니다.')

    # DIALOG

    while True:
        time = TimeInfo()
        errCount = 0

        # 실험 차수 수집
        # try:
        #     with open('order.pkl', 'rb') as f:
        #         order = pickle.load(f)
        # except:
        #     order = None

        # if order != None:
        #     try:
        #         print('[ 실험 차수 확인 ]\n')
        #         print(f'이전에 데이터를 가공했던 실험의 차수가 [{order}차] 입니다.')
        #         print(f'이번에 가공할 데이터의 차수는 [{order+1}차]가 맞습니까?')
        #         print('\n맞으면 엔터를, 아니라면 실험 차수를 숫자로 입력해주세요.')
        #         order = int(input('> '))
        #         try:
        #             with open('order.pkl', 'wb') as f:
        #                 pickle.dump(order, f)
        #         except:
        #             pass
        #     except:
        #         order += 1
        #         try:
        #             with open('order.pkl', 'wb') as f:
        #                 pickle.dump(order, f)
        #         except:
        #             pass
        # else:
        #     while True:
        #         try:
        #             print('실험이 "몇차" 실험인지 "차수"를 "숫자"로 입력해주세요.')
        #             order = int(input('> '))
        #             try:
        #                 with open('order.pkl', 'wb') as f:
        #                     pickle.dump(order, f)
        #             except:
        #                 pass
        #             break
        #         except:
        #             print('[오류] 숫자를 입력하셔야 합니다.')

        print('\n\n\n[ 데이터 종류 설정 ]\n')
        print('가공할 데이터 종류를 선택해주세요.')
        print('1. 이산화탄소 계측기')
        print('2. 헬륨 계측기')
        print('3. 산소 계측기')
        print('4. 더미')
        while True:
            n = input('번호를 입력해주세요 > ')
            sel = {'1':'CO2', '2':'He', '3':'O2', '4':'dummy'}
            if n in sel:
                file_type = sel[n]
                break
            print('잘못 입력하셨습니다.')

        print("\n\n\n[ 폴더 경로 설정 ]\n")
        print("처리해야되는 폴더의 경로를 입력해주세요.")
        while True:
            try:
                lists = filter_csv_from_dir(input("> "), file_type=file_type)
                break
            except FileNotFoundError:
                print('[오류] 해당 경로가 존재하지 않습니다. 다시 시도하세요.\n')
            except NotADirectoryError:
                print('[오류] 해당 경로는 폴더가 아닙니다. 다시 시도하세요.\n')

        print("\n\n\n[ 실험 시작시간 설정 ]\n")
        while True:
            try:
                print("실험 시작시간을 직접 입력해주세요 ( 예시[14시 8분] -> 14:8 )")
                _time = input("> ")
                _time = list(map(int, _time.split(':')))
                time.set_time(_time, only_time=True)
                break
            except:
                print('\n잘못 입력하신 것 같습니다.')

        # print("\n\n\n[ 안정화 시간 설정 ]\n")
        # while True:
        #     try:
        #         print('실험 시작 후 반응시간을 계산하기 위해서 안정화 시간을 입력해야합니다.')
        #         print('실험 안정화 시간을 초로 입력해주세요.')
        #         __stabililze_period = int(input('>' ))
        #         time.set_stab_period(__stabililze_period)
        #         break
        #     except:
        #         print('\n잘못 입력하셨습니다.')
        # 임시로 0초 설정
        time.set_stab_period(0)

        try:
            print('\n\n\n[ 실험 지속시간(진행시간) 설정 ]\n')
            print(f'기본 설정되어있는 실험 지속시간(진행시간)은 [{time.get_duration()}초] 입니다.')
            print('\n맞으면 엔터를, 아니라면 지속시간(단위:초)을 숫자로 입력해주세요.')
            du = int(input('> '))
            time.set_duration(du)
        except:
            pass

        # PROCESS

        clear()
        print(f'이제 실험 데이터 가공을 시작하겠습니다. 아래의 내용을 확인해주세요.\n')
        # print(f'> {order}차 실험 데이터')
        print(f'> 데이터 종류: {file_type}')
        print(f'> 실험 시작시간: {time.timedatalist[0]}시 {time.timedatalist[1]}분')
        print(f'> 실험 지속시간: {time.get_duration()}초')
        input("\n>> 진행하려면 엔터키를 눌러주세요.\n\n")

        for i, e in enumerate(lists):
            try:
                bar = tqdm(total = 100, desc=f'[{i+1}/{len(lists)}] {e.name}', bar_format='{desc:30.28}{percentage:3.0f}%|{bar:30}|', smoothing=1)

                df = preprocess_to_df(e, time)
                bar.update(20)

                # 그래프 분석을 위한 데이터 생성
                if e.type == 'CO2': #TODO: 계측기 데이터 늘어나면 맞게 수정한다.
                    calculated_dict = calculate_df(df, time.get_stab_period())
                else:
                    calculated_dict = None

                wb = dataframe_to_excel(df)
                bar.update(10)

                wb = formular_process(wb, e.type)
                bar.update(10)

                # if e.type != "dummy" and rtdb != None: # dummy 데이터 외(dummy는 total로만) 백업하기
                #     dataDict = firebase_process(wb, e, e.type)
                #     bar.update(10)

                #     rtdb.upload_dummy(time, order, dataDict, e.type)
                #     bar.update(20)
                # else:
                #     bar.update(30)
                bar.update(30)

                wb = expression_process(wb, e)
                bar.update(10)

                if calculated_dict != None:
                    wb = insert_calculated_values(wb, calculated_dict)

                chart_process(wb, e)
                bar.update(10)

                wb.save(f"{e.dirPath}/{e.name[:-4]} 정리.xlsx")
                bar.update(10)
                bar.close()

            except Exception as err:
                bar.close()
                errCount += 1
                print('\r[오류] ', end='')
                print(err)
                print('[오류] ' + e.name + "의 파일 변환 중 오류가 발생하여 가공하지 않고 넘어갑니다.\n")

        # FINISH

        print(f'\n총 {len(lists)}개의 파일 중에서 {len(lists)-errCount}개의 파일 가공에 성공하였습니다.')
        print("새로운 폴더에서 가공을 시작하시려면 'Y'를, 종료하시려면 'N'을 입력해주세요.")
        while True:
            isLoop = input('> ')
            if isLoop == "Y" or isLoop == "y" or isLoop == "N" or isLoop == "n":
                break
            print("\n새로운 폴더에서 가공을 시작하시려면 'Y'를, 종료하시려면 'N'을 입력해주세요.")

        if isLoop == 'N' or isLoop == "n":
            break

if __name__ == '__main__':
    main()


phonebook = {}

# Add a contact
def add_contact(name, number):
    phonebook[name] = number
    print("Contact added successfully!")

# Search for a contact
def search_contact(name):
    if name in phonebook:
        print(f"{name}: {phonebook[name]}")
    else:
        print(f"{name} not found in phonebook.")

# Display all contacts
def display_contacts():
    for name, number in phonebook.items():
        print(f"{name}: {number}")

# Delete a contact
def delete_contact(name):
    if name in phonebook:
        del phonebook[name]
        print(f"{name} deleted from phonebook.")
    else:
        print(f"{name} not found in phonebook.")

while True:
    print("1. Add Contact")
    print("2. Search Contact")
    print("3. Display All Contacts")
    print("4. Delete Contact")
    print("5. Exit")
    choice = input("Enter your choice: ")
    if choice == '1':
        name = input("Enter contact name: ")
        number = input("Enter contact number: ")
        add_contact(name, number)
    elif choice == '2':
        name = input("Enter contact name: ")
        search_contact(name)
    elif choice == '3':
        display_contacts()
    elif choice == '4':
        name = input("Enter contact name: ")
        delete_contact(name)
    elif choice == '5':
        break
    else:
        print("Invalid choice. Please try again.")


from sweetpea import *
import os
_dir=os.path.dirname(__file__)
### REGULAR FACTORS
CxEjz= Factor("CxEjz", [Level("jCYEbtvELwwE*o", 8), Level("myFH", 1), Level("ymHJiHBNgE", 1), Level("J2FUQ", 1)])

design=[CxEjz]
crossing=[CxEjz]

### APPENDIX
block=CrossBlock(design,crossing,[])
experiment=synthesize_trials(block,1)
save_experiments_csv(block, experiment, os.path.join(_dir, "out_code_2/4_1_1"))

### END


import dataset
import requests
from lxml import html
import time
import sqlalchemy

INFO = {
    'en': {
        'url': 'https://cambodiadaily.com',
        'db': 'sqlite:///archive_en.db'
    },
    'kh': {
        'url': 'https://cambodiadailykhmer.com',
        'db': 'sqlite:///archive_kh.db'
    }
}

def scrape_page(url, table, language):
    page = requests.get(url)
    tree = html.fromstring(page.content)
    article_urls = tree.xpath('//*[contains(concat( " ", @class, " " ), concat( " ", "entry-title", " " ))]//a/@href')
    for url in article_urls:
        url = url.strip()
        try:
            table.insert(dict(url=url))
        except sqlalchemy.exc.IntegrityError:
            pass
    if language == 'kh':
        paginated_url = tree.xpath('//*[contains(concat( " ", @class, " " ), concat( " ", "alignright", " " ))]//a/@href')
    else:
        paginated_url = tree.xpath('//*[contains(concat( " ", @class, " " ), concat( " ", "pagination-next", " " ))]//a/@href')
    time.sleep(5)
    return paginated_url

def scrape_site(url, table, language):
    homepage = requests.get(url)
    tree = html.fromstring(homepage.content)
    date_urls = [url for url in tree.xpath('//*[@id="archivesdropfront"]/select/option/@value') if url]
    for url in date_urls:
        table.insert(dict(url=url))
        page = 1
        print('scraping: {}'.format(url))
        paginated_url = scrape_page(url, table, language)
        print('...page {}'.format(page))
        while paginated_url:
            table.insert(dict(url=paginated_url))
            page += 1
            url = paginated_url[0]
            print('...page {}'.format(page))
            paginated_url = scrape_page(url, table, language)

def run(language):
    print('beginning scrape of {} site'.format(language))
    db = dataset.connect(INFO[language]['db'])
    table = db.get_table('url', primary_id='url', primary_type='String')
    scrape_site(INFO[language]['url'], table, language)

if __name__ == '__main__':
    run('en')
    run('kh')


import numpy as np
import tkinter as tk
import time as time
import random as rand

#Variables globales
UP=(-1,0)
DOWN=(1,0)
LEFT=(0,-1)
RIGHT=(0,1)

MOVES=[UP,DOWN,LEFT,RIGHT]

EMPTY = 0
FOOD = 99

class Game:
    def __init__(self, size, numSnakes, players, gui=None, display=False, maxTurns=100):
        self.size= size
        self.numSnakes = numSnakes
        self.players = players
        self.gui = gui
        self.display = display
        self.maxTurns = maxTurns

        self.numFood = 4
        self.turn = 0
        self.snakeSize = 3

        self.snakes = [[((j+1)*size//(2*self.numSnakes),self.size//2+i)for i in range (self.snakeSize)]
                     for j in range(self.numSnakes)]

        self.food = [(self.size//4, self.size//4),(3*self.size//4, self.size//4),
                     (self.size//4, 3*self.size//4),(3*self.size//4, 3*self.size//4)]

        self.playerIDs = [i for i in range (self.numSnakes)]

        self.board = np.zeros([self.size,self.size])
        for i in self.playerIDs:
            for tupla in self.snakes[i]:
                self.board[tupla[0]][tupla[1]] = i+1
        for tupla in self.food:
            self.board[tupla[0]][tupla[1]] = FOOD

        self.foodIndex = 0
        self.foodXY = [(rand.randint(0,9),rand.randint(0,9))for _ in range (200)]

    def move(self):
        moves = []
        #mover la cabeza del snake
        for i in self.playerIDs:
            snake_i = self.snakes[i]
            move_i = self.players[i].get_move(self.board, snake_i)
            moves.append(move_i)
            new_square = (snake_i[-1][0] + move_i[0], snake_i[-1][1] + move_i[1]) #a donde se mueve el snake
            snake_i.append(new_square)

        #acomodar su cola (si la cabeza no encuentra comida se actualiza la cola, sino se remueve la comida)
        for i in self.playerIDs:
            head_i=self.snakes[i][-1]
            if head_i not in self.food:
                self.board[self.snakes[i][0][0]][self.snakes[i][0][1]] = EMPTY
                self.snakes[i].pop(0)
            else:
                self.food.remove(head_i)

        #mirar que no salga de los limites
        for i in self.playerIDs:
            head_i=self.snakes[i][-1]
            if head_i[0] >= self.size or head_i[1] >=self.size or head_i[0] < 0 or head_i[1] < 0:
                self.playerIDs.remove(i)
            else:
                self.board[head_i[0]][head_i[1]] = i+1

        # mirar colisiones
        for i in self.playerIDs:
            head_i=self.snakes[i][-1]
            for j in range(self.numSnakes):
                if i==j:
                    if head_i in self.snakes[i][:-1]:
                        self.playerIDs.remove(i)
                else:
                    if head_i in self.snakes[j]:
                        self.playerIDs.remove(i)

        # aparecer comida
        while len(self.food)<self.numFood:
            x = self.foodXY[self.foodIndex][0]
            y = self.foodXY[self.foodIndex][1]
            while self.board[x][y] != EMPTY:
                self.foodIndex += 1
                x = self.foodXY[self.foodIndex][0]
                y = self.foodXY[self.foodIndex][1]

            self.food.append((x, y))
            self.board[x][y] = FOOD
            self.foodIndex += 1

        return moves

    def play(self, display, termination = False):
        #if display:
            #print("self.displayBoard()")
        while True:
            if termination:
                for i in self.playerIDs:
                    if len(self.snakes[0]) - self.turn/20 <= 0:
                        self.playerIDs.remove(i)
                        return -2
            if len(self.playerIDs) == 0:
                return -1
            if self.turn >= self.maxTurns:
                return 0
            moves = self.move()

            self.turn += 1
            if display:
                if self.gui is not None:
                    self.gui.update()
                time.sleep(0.75)

    def displayBoard(self):
        for i in range (self.size):
            for j in range (self.size):
                if self.board[i][j]==EMPTY:
                    print("|_",end="")
                elif self.board[i][j]==FOOD:
                    print("|#",end="")
                else:
                    print("|"+str(int(self.board[i][j])),end="")
            print("|")

class GUI:
    def __init__(self, game, size):
        self.game = game
        self.game.gui = self
        self.size = size

        self.ratio = self.size/self.game.size

        self.app= tk.Tk()
        self.app.title("Auto Snake")
        self.canvas=tk.Canvas(self.app, width=self.size,height=self.size,bg='#000000')
        self.canvas.pack()

        for i in range(len(self.game.snakes)):
            snake=self.game.snakes[i]
            self.canvas.create_rectangle(self.ratio*(snake[-1][1]), self.ratio*(snake[-1][0]),
                                         self.ratio*(snake[-1][1]+1), self.ratio*(snake[-1][0]+1),fill='white')
            for j in range(len(snake) - 1):
                self.canvas.create_rectangle(self.ratio * (snake[j][1]), self.ratio * (snake[j][0]),
                                             self.ratio * (snake[j][1] + 1), self.ratio * (snake[j][0] + 1), fill='white')
        for food in self.game.food:
            self.canvas.create_rectangle(self.ratio*(food[1]),self.ratio*(food[0]),
                                         self.ratio*(food[1]+1),self.ratio*(food[0]+1),fill='red')

    def update(self):
        self.canvas.delete("all")

        for i in range(len(self.game.snakes)):
            snake = self.game.snakes[i]
            self.canvas.create_rectangle(self.ratio * (snake[-1][1]), self.ratio * (snake[-1][0]),
                                         self.ratio * (snake[-1][1] + 1), self.ratio * (snake[-1][0] + 1), fill='white')
            for j in range(len(snake) - 1):
                self.canvas.create_rectangle(self.ratio * (snake[j][1]), self.ratio * (snake[j][0]),
                                             self.ratio * (snake[j][1] + 1), self.ratio * (snake[j][0] + 1),
                                             fill='white')
        for food in self.game.food:
            self.canvas.create_rectangle(self.ratio * (food[1]), self.ratio * (food[0]),
                                         self.ratio * (food[1] + 1), self.ratio * (food[0] + 1), fill='red')

        self.canvas.pack()
        self.app.update()


import cv2
import sys
import os
from os.path import join
from glob import glob
import numpy as np
from c3dmodel import *
import torch
import argparse

BATCH_SIZE = 32

parser = argparse.ArgumentParser()
parser.add_argument('--root', help="videos data root")
parser.add_argument('--out', help="dir for output")
parser.add_argument('-f', help="number of frames per clip", default=16)
parser.add_argument('-l', help="specify output layer", default=FC6_LAYER)
args = parser.parse_args()

def extract_frames(video, frame_dir):
    if os.path.isdir(frame_dir):
        print("[Warning] frame_dir={} does exist. Will overwrite".format(frame_dir))
    else:
        os.makedirs(frame_dir)

    cap = cv2.VideoCapture(video)
    if not cap.isOpened():
        print("[Error] video={} can not be opened.".format(video))
        sys.exit(-6)

    ret, frame = cap.read()
    frame_num = 0
    while ret:
        frame_file = os.path.join(
                frame_dir,
                '{0:06d}.jpg'.format(frame_num)
                )
        cv2.imwrite(frame_file, frame)
        ret, frame = cap.read()
        frame_num += 1

    return frame_num - 1

def delete_frames(frame_dir):
    for filename in os.listdir(frame_dir):
        file_path = os.path.join(frame_dir, filename)
        try:
            os.remove(file_path)
        except Exception as e:
            print('Failed to delete file %s. Reason: %s' % (file_path, e))
    try:
        os.rmdir(frame_dir)
    except Exception as e:
        print('Failed to delete dir %s. Reason: %s' % (frame_dir, e))

def get_clips(frame_dir, num_frames_per_clip):
    overlap = int(num_frames_per_clip / 2)
    clips = sorted(glob(join(frame_dir, '*.jpg')))
    clips = np.array([cv2.resize(cv2.cvtColor(cv2.imread(frame), cv2.COLOR_BGR2RGB), (200, 112)) for frame in clips])
    clips = clips[:, :, 44:44 + 112, :]
    clips = np.array([clips[i : i + num_frames_per_clip] for i in range(0, len(clips), overlap) if len(clips[i : i + num_frames_per_clip]) == num_frames_per_clip])
    clips = clips.transpose(0, 4, 1, 2, 3)
    clips = np.float32(clips)
    return torch.from_numpy(clips)

def extractC3D1(video_file, out_layer_type=FC6_LAYER, num_frames_per_clip=16):
    video_id, _ = os.path.splitext(os.path.basename(video_file))

    tmp_dir = './tmp'
    print("Frames extraction started")
    frame_dir = os.path.join(tmp_dir, video_id)
    frames = extract_frames(video_file, frame_dir)
    print("Frames extraction finished, extracted {} frames".format(frames))

    print("Clips extraction started")
    clips = get_clips(frame_dir, num_frames_per_clip)
    if torch.cuda.is_available():
        clips = clips.cuda()
    print("Clips extraction finished")

    model = C3D()
    model.load_state_dict(torch.load('c3d.pickle'))
    if torch.cuda.is_available():
        model.cuda()
    model.eval()

    print("Features extraction started")
    features = []
    for i in range(0, len(clips), BATCH_SIZE):
        print("Batch:", str(i + 1))
        feats = model(torch.from_numpy(np.expand_dims(clips[i:BATCH_SIZE], axis=0)), out_layer_type)
        batch_features = feats.data.cpu()
        features.append(batch_features)

    features = torch.cat(features, 0)
    features = features.numpy()
    print("Features extraction finished, extracted {} features".format(features.shape[0]))

    np.save(os.path.join(args.out, video_id), features)

    print("Deleting frames")
    delete_frames(frame_dir)

def extractC3D(videos_path, out_layer_type=FC6_LAYER, num_frames_per_clip=16):
    videos = [join(videos_path, f) for f in os.listdir(videos_path) if not f.startswith('.')]
    for video in videos:
        print("############## PROCESSING VIDEO {} ##############".format(video))
        video_path = os.path.join(videos_path, video)
        print("Video path:", video_path)
        extractC3D1(video_path, out_layer_type, num_frames_per_clip)

if __name__ == '__main__':
    extractC3D(args.root, args.l, args.f)


num=int(input())
for i in range(num):
    n=int(input())
    hash = {}
    result=1
    for j in range(n):
        str1,str2=input().split()
        hash[str2]=hash.setdefault(str2,0)+1

    for v in hash.values():
        result*=(v+1)

    print(result-1)

백준/Silver/9375. 패션왕 신해빈/패션왕 신해빈.py


from django.shortcuts import render
from user.models import Userprofile, UsersUserrating, FriendsFriendshipFriends,FriendsFriendship, FriendsFriendshiprequest,UserActivitys,UserPost
from minus.models import DjangoComments, ForumPost
from messanger.models import Channels
from album.models import PhotosPhotoalbum,PhotosPhoto
from minusstore.models import MinusstoreMinusauthor, MinusstoreMinusrecord
from main.models import ModeratorMessages
from shop.models import BlurbsBlurb,SelectedBlurb
from django.http import HttpResponse, HttpResponseRedirect
from django.db.models import Q
from django.contrib.auth.forms import AuthenticationForm
from django.contrib.auth.views import LoginView
from django.template import RequestContext
from django.contrib.auth.models import User
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.contrib.auth import logout, login
from django.views.generic.edit import FormView,UpdateView
from django.contrib.auth.forms import UserCreationForm
from .forms import UserCreateForm, EmailAuthenticationForm,AddUserPost,AddModeratorMessagesForm,AddPhotoForm
from user.tokens import account_activation_token
from django.template.loader import render_to_string
from django.contrib.sites.shortcuts import get_current_site
from django.utils.encoding import force_bytes, force_text
from django.utils.http import urlsafe_base64_encode, urlsafe_base64_decode
from django.core.mail import EmailMessage
from user.filter import UserFilter
from .serializers import UserSerializer
from rest_framework import viewsets
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.views import APIView

import lxml.html
import datetime
import json

def user_page(request, pk):
    user=Userprofile.objects.get(user_id=pk)
    try:
        friendship=FriendsFriendship.objects.get(user_id = user.user.id)
    except FriendsFriendship.DoesNotExist:
        friendship = 0

    friendshipfriends=FriendsFriendshipFriends.objects.filter(from_friendship_id=friendship.id).order_by('-id')
    friendship_id = friendshipfriends.values_list('to_friendship_id')
    friends=FriendsFriendship.objects.filter(id__in=friendship_id).order_by('-id')[:10]
    user.comments = DjangoComments.objects.filter(user_id=user.user_id).order_by('-id')[:10]
    user.forum = ForumPost.objects.filter(author_id=user.user_id).order_by('-id')[:10]
    for u_f in user.forum:
        u_f.body = lxml.html.fromstring(u_f.body).text_content()

    # user.u = User.objects.get(pk=user.user_id)
    is_friend=0
    add_post_form = AddUserPost(request.POST,request.FILES)
    if request.user.is_authenticated:
        for f in friends:
            if f.user_id==request.user.id:
                is_friend=1
        if request.method == "POST":
            if add_post_form.is_valid():
                print("addING POST")
                add_post = add_post_form.save(request,commit=True)

    try:
        user.rating = UsersUserrating.objects.get(user_id=user.user.id)
    except UsersUserrating:
        user.rating = 0
    user_post = UserPost.objects.filter(userprofile_id = user.id).order_by('-pub_date')
    return render(request, 'user/index.html', {
        'user': user,
        'friends':friends,
        'is_friend':is_friend,
        'posts':user_post,
        'add_post_form':add_post_form,
    })

class ProfileUpdate(UpdateView):
    model = Userprofile
    fields = ['gender','city','country','avatar','birthdate','icq','skype','website','about',]
    template_name_suffix = '_update_form'

def all_friends(request,pk):
    try:
        friendship=FriendsFriendship.objects.get(user_id = pk)
    except FriendsFriendship.DoesNotExist:
        friendship = 0

    friendshipfriends=FriendsFriendshipFriends.objects.filter(from_friendship_id=friendship.id).order_by('-id')
    friendship_id = friendshipfriends.values_list('to_friendship_id')
    friends=FriendsFriendship.objects.filter(id__in=friendship_id).order_by('-id')
    friends_request = FriendsFriendshiprequest.objects.filter(to_user_id=request.user.id)

    return render(request, 'user/all_friends.html', {
        'friends_request':friends_requests,
        'users':friends,
    })

def userlist(request):
    users = User.objects.all()
    paginator = Paginator(users, 25)
    page = request.GET.get('page')
    try:
        users = paginator.page(page)
        print('first')
    except PageNotAnInteger:
        users = paginator.page(1)
        print('second')
    except EmptyPage:
        users = paginator.page(paginator.num_pages)
        print('third')

    return render(request, 'user/list.html', {'users': users})

class RegisterFormView(FormView):
    form_class = UserCreateForm

    # Ссылка, на которую будет перенаправляться пользователь в случае успешной регистрации.
    # В данном случае указана ссылка на страницу входа для зарегистрированных пользователей.
    success_url = "http://127.0.0.1:8000"

    # Шаблон, который будет использоваться при отображении представления.
    template_name = "user/registration.html"

    def form_valid(self, form):
        # Создаём пользователя, если данные в форму были введены корректно.

        self.last_login = datetime.datetime.now()
        # self.is_active = False
        form_data = form.save()
        # form_data.is_active = 0
        current_site = get_current_site(self.request)
        mail_subject = 'Активація акаунту minus.lviv.ua'
        message = render_to_string('user/sucees_registration.html', {
            'user': form_data,
            'domain': current_site.domain,
            'uid': urlsafe_base64_encode(force_bytes(form_data.id)),
            'token': account_activation_token.make_token(form_data),
        })

        to_email = form_data.email
        email = EmailMessage(
            mail_subject, message, to=[to_email]
        )
        email.send()

        return super(RegisterFormView, self).form_valid(form)

def advertisement(request):
    if request.user.is_authenticated:
        z = True
        selected_blurbs = SelectedBlurb.objects.filter(user_id = request.user.id)
        blurbs = BlurbsBlurb.objects.filter(user_id = request.user.id)
        try:
            blurbs = paginator.page(page)
            print('first')
        except PageNotAnInteger:
            blurbs = paginator.page(1)
            print('second')
        except EmptyPage:
            blurbs = paginator.page(paginator.num_pages)
            print('third')
        for g in blurbs:
            try:
                ph_a = PhotosPhotoalbum.objects.get(content_type_id=52,object_pk = g.id)
                g.photo = PhotosPhoto.objects.filter(album_id = ph_a.id)
                try:
                    g.photo = g.photo[0].image
                except:
                    g.photo='pass'
            except PhotosPhotoalbum.DoesNotExist:
			# print("except")
                g.photo = "http://praktikaprava.ru/wp-content/uploads/2017/11/obmen-tovara-v-techenii-14-dnej.jpg"
            # print("end--------------------")
        for g in selected_blurbs:
            try:
                ph_a = PhotosPhotoalbum.objects.get(content_type_id=52,object_pk = g.blurb.id)
                g.photo = PhotosPhoto.objects.filter(album_id = ph_a.id)
                try:
                    g.photo = g.photo[0].image
                except:
                    g.photo='pass'
            except PhotosPhotoalbum.DoesNotExist:
                g.photo = "http://praktikaprava.ru/wp-content/uploads/2017/11/obmen-tovara-v-techenii-14-dnej.jpg"
        return render(request, 'user/user_goods.html',{'blurbs':blurbs,'selected_blurbs':selected_blurbs,'z':z,})

class AddPhoto(FormView):
    form_class = AddPhotoForm
    template_name = "user/add_photo.html"
    success_url = '/'

    def form_valid(self, form):
        print(self.request.user.id)
        photo_album = PhotosPhotoalbum.objects.get(content_type_id = 20,user_id = self.request.user.id)
        form.instance.album = photo_album
        return super().form_valid(form)

def delete_selected_blurbs(request, pk):
    if request.user.is_authenticated:
        selected_blurb = SelectedBlurb.objects.get(pk=pk).delete()
        return HttpResponseRedirect('/user/user-advertisement/')

class UserLoginView(LoginView):
    form_class = EmailAuthenticationForm
    template_name = 'user/false_auth.html'
    redirect_authenticated_user = True

    def post(self, request, *args, **kwargs):

        form = self.get_form()  # type: AuthenticationForm
        if form.is_valid():
            return self.form_valid(form)
        else:

            if 'username' in form.cleaned_data:
                username = form.cleaned_data['username']
                try:
                    user = User.objects.get(username=username)
                    userprofile = Userprofile.objects.get(user_id = user.id)
                except User.DoesNotExist:
                    return HttpResponseRedirect('../../')

            return self.form_invalid(form)

def false_auth(request):
    return render(request, 'user/false_auth.html', {})

def logout_view(request):
    Channels.objects.get(user_id=request.user.pk).delete()
    logout(request)

    return HttpResponseRedirect('../../')

def userminuses(request, user_id):
    minuses = MinusstoreMinusrecord.objects.filter(user_id=user_id).order_by('-id')
    paginator = Paginator(minuses, 10)
    page = request.GET.get('page')
    try:
        minuses = paginator.page(page)
        print('first')
    except PageNotAnInteger:
        minuses = paginator.page(1)
        print('second')
    except EmptyPage:
        minuses = paginator.page(paginator.num_pages)
        print('third')

    return render(request, 'user/user_minuses.html', {'minus': minuses})

def user_goods(request,user_id):
    blurbs = BlurbsBlurb.objects.filter(user_id = user_id)
    paginator = Paginator(blurbs, 10)
    page = request.GET.get('page')
    try:
        blurbs = paginator.page(page)
        print('first')
    except PageNotAnInteger:
        blurbs = paginator.page(1)
        print('second')
    except EmptyPage:
        blurbs = paginator.page(paginator.num_pages)
        print('third')
    for g in blurbs:
        print("work hard")
        try:
            print("try")
            ph_a = PhotosPhotoalbum.objects.get(content_type_id=52,object_pk = g.id)
            g.photo = PhotosPhoto.objects.filter(album_id = ph_a.id)
            try:
                g.photo = g.photo[0].image
            except:
                g.photo='pass'
        except PhotosPhotoalbum.DoesNotExist:
            print("except")
            g.photo = "http://praktikaprava.ru/wp-content/uploads/2017/11/obmen-tovara-v-techenii-14-dnej.jpg"
        print("end--------------------")
    return render(request, 'user/user_goods.html',{'blurbs':blurbs,})

def activate(request, uidb64, token):
    try:
        uid = force_text(urlsafe_base64_decode(uidb64))
        user = User.objects.get(pk=uid)
    except(TypeError, ValueError, OverflowError, User.DoesNotExist):
        user = None
    if user is not None and account_activation_token.check_token(user, token):
        user.is_active = True
        user.save()
        login(request, user)
        return render(request, 'user/succes_reg_true.html', {})
    else:
        return HttpResponse('Вибачте але лінк активації якийсь поганий(')

def user_search(request):
    users = User.objects.filter(
        Q(first_name__startswith=request.GET['search']) | Q(last_name__startswith=request.GET['search'])| Q(username__startswith=request.GET['search'])| Q(email__startswith=request.GET['search'])
    )
    print('---------------------------------------------')
    print(users)
    print('-----------------------------------------')
    # users = users.qs
    print('gello')
    print(users)
    paginator = Paginator(users, 25)
    page = request.GET.get('page')
    try:
        users = paginator.page(page)
        print('first')
    except PageNotAnInteger:
        users = paginator.page(1)
        print('second')
    except EmptyPage:
        users = paginator.page(paginator.num_pages)

    return render(request, 'user/list.html', {'users': users})

def activities(request):
    last_forum = ForumPost.objects.order_by('-id')[:10]
    last_comments = DjangoComments.objects.order_by('-id')[:30]
    if request.user.is_authenticated:
        activities = UserActivitys.objects.filter(to_user_id=request.user.id)
        z = True
    else:
        activities = UserActivitys.objects.all()
        z = False
    return render(request, 'user/activities.html', {
        'activities': activities,
        'z': z,
        'last_forum': last_forum,
        'last_comments': last_comments,
    })

def moderator_messages(request):
    if request.user.is_authenticated:
        if request.user.is_staff:
            moderator_messages = ModeratorMessages.objects.all().order_by('-id')
            return render(request,'user/moderator_messages.html',{'moderator_messages':moderator_messages,})

def add_moderator_message(request,object_pk,content_id):
    form = AddModeratorMessagesForm(request.POST)
    if request.method == "POST":

        if request.user.is_authenticated:

            print("form prevalidation")
            if form.is_valid():
                print("form moderator_messages is valid")
                # if content_id == '17':
                    # minus = MinusstoreMinusrecord.objects.get(id = object_pk)
                    # print(minus.author)
                    # print(minus.title)
                    # ModeratorMessages.objects.create(object_pk=object_pk,content_id=content_id,user=request.user,attention_message="Повідомлення про мінусовку"+minus.title)
                form = form.save(request,content_id,object_pk,commit=True)
    return render(request, 'user/add_moderator_messages.html', {'form':form,})

# def list_friends_request(request):
#     if request.user.is_authenticated:
#         friends_request =  FriendsFriendshiprequest.objects.filter(to_user_id=request.user.id)

def friends_requests(request,pk):
    if request.user.is_authenticated:
        friends_request = FriendsFriendshiprequest.objects.filter(to_user_id=request.user.id)
        return render(request,'user/friends_requests.html',{'friends_request':friends_requests
        })

# API
class FriendsRequest(APIView):
    def get(self,request,to_user_id,format=None):
        print(to_user_id)
        friend_request = FriendsFriendshiprequest.objects.create(from_user_id=request.user.id,to_user_id=to_user_id,accepted=0)
        return Response('{"1":1}')

class GetUser(APIView):

    # permission_classes = (IsAuthenticated,)

    def get_object(self, pk):
        try:
            return User.objects.get(pk=pk)
        except User.DoesNotExist:
            raise Http404

    def get(self, request,pk ,format=None):

        user = self.get_object(pk = pk)
        user = UserSerializer(user,many=False)

        return Response(user.data)


from requests import Session
from json import loads

class Room:
    URL = "https://mafia.gg/api/rooms"

    def __init__(self, payload):
        self.payload = payload

    def list_rooms(self):
        with Session() as s:
            self.json = loads(s.get(self.URL, cookies=self.payload).content)
        rooms = self.json['rooms']
        num = len(rooms)
        lobbies = []
        if num > 0:
            lobbies = [r['name'] for r in rooms]
        return num, lobbies


from salesforce_prototype_app.utilities.rsa_tools import get_user_secret_from_aws, get_snowflake_rsa_keys_connection
from salesforce_prototype_app.utilities.get_fieldnames import dict_of_lists

def copyinto_snowflake(salesforce_entity_name, filename):
    secret_dict = get_user_secret_from_aws()
    # connect to snowflake as service user and read Snowflake version
    con = get_snowflake_rsa_keys_connection(secret_dict)
    cursor = con.cursor()

    print(f'Copying {salesforce_entity_name} into Snowflake')
    # cursor.execute("SELECT CURRENT_VERSION()")
    # value = cursor.fetchone()[0]
    # print('Snowflake version: ' + value)

    column_names = dict_of_lists(salesforce_entity_name)
    snowflake_query_select = ''
    snowflake_query_final_select = ''
    for x, col_name in enumerate(column_names):
        #sf_datatype = get_snowflake_datatype(destination_table_name, x)

        # below - replace "VARIANT" with something dynamic for datatype.
        # perhaps this could come from the Source? check with CB
        snowflake_query_select += f'parse_json($1):{col_name}::VARIANT as {col_name}, '
        snowflake_query_final_select  += f's.{col_name}, '

    snowflake_query_select = snowflake_query_select[:-2]

    sql = f"COPY INTO DEV_AG_SALESFORCE.SALESFORCE_LOAD.SALESFORCE_{salesforce_entity_name}" \
                      f" FROM (" \
                      f"SELECT " \
                      f"{snowflake_query_select} " \
                      f"from @DEV_AG_SALESFORCE.SALESFORCE_LOAD.S3_STAGE)" \
                      f" FILE_FORMAT = (FORMAT_NAME = 'DEV_AG_SALESFORCE.SALESFORCE_LOAD.BASIC_JSON')" \
                      f" PATTERN = '.*{filename}.*';"

    #f" FILE_FORMAT = (FORMAT_NAME = 'DEV_AG_SALESFORCE.SALESFORCE_LOAD.BASIC_CSV')" \

    cursor.execute(sql)

    print(f'{salesforce_entity_name} has been copied into Snowflake')

def truncate_snowflaketable(salesforce_entity_name):
    secret_dict = get_user_secret_from_aws()
    # connect to snowflake as service user and read Snowflake version
    con = get_snowflake_rsa_keys_connection(secret_dict)
    cursor = con.cursor()

    print(f'Preparing to truncate DEV_AG_SALESFORCE.SALESFORCE_LOAD.SALESFORCE_{salesforce_entity_name}')
    sql = f"TRUNCATE DEV_AG_SALESFORCE.SALESFORCE_LOAD.SALESFORCE_{salesforce_entity_name};"
    cursor.execute(sql)
    print(f'DEV_AG_SALESFORCE.SALESFORCE_LOAD.SALESFORCE_{salesforce_entity_name} has been truncated')

def test_snowflake_service_user_authentication():
    # get existing user secret
    secret_dict = get_user_secret_from_aws()
    # connect to snowflake as service user and read Snowflake version
    con = get_snowflake_rsa_keys_connection(secret_dict)
    cursor = con.cursor()
    cursor.execute("SELECT CURRENT_VERSION()")
    value = cursor.fetchone()[0]
    print('Snowflake version: ' + value)
    print('Service user successfully established connection to Snowflake.')

def lookup_snowflake_datatype(datatype: int):
    # change!! this is almost certainly not the way to do it. discuss with CB.
    snowflake_datatype = {0: 'NUMBER', 1: 'REAL', 2: 'TEXT', 3: 'DATE', 4: 'TIMESTAMP', 5: 'VARIANT',
                          6: 'TIMESTAMP_LTZ', 7: 'TIMESTAMP_TZ', 8: 'TIMESTAMP_NTZ', 9: 'OBJECT', 10: 'ARRAY',
                          11: 'BINARY', 12: 'TIME', 13: 'BOOLEAN'}
    return snowflake_datatype.get(datatype)

def get_snowflake_datatype(destination_table_name, position_in_iteration):

    secret_dict = get_user_secret_from_aws()
    # connect to snowflake as service user and read Snowflake version
    con = get_snowflake_rsa_keys_connection(secret_dict)
    csr = con.cursor()
    metadata = csr.describe(f"SELECT * FROM DEV_AG_SALESFORCE.SALESFORCE_LOAD.{destination_table_name}")
    snowflake_column_metadata = metadata[(position_in_iteration)]
    snowflake_column_datatype_code = snowflake_column_metadata[1]
    return lookup_snowflake_datatype(snowflake_column_datatype_code)


from setuptools import find_packages, setup

__plugin_name__ = 'AddTorrentCheck'
__author__ = 'idiocrazy'
__author_email__ = 'yourname@example.com'
__version__ = '0.3'
__url__ = ''
__license__ = 'GPLv3'
__description__ = ''
__long_description__ = """Automatically forces re-announces on newly added torrent where tracker does not report 'Announce OK' for 5 min."""
__pkg_data__ = {'deluge_'+__plugin_name__.lower(): ['data/*']}

setup(
    name=__plugin_name__,
    version=__version__,
    description=__description__,
    author=__author__,
    author_email=__author_email__,
    url=__url__,
    license=__license__,
    long_description=__long_description__,

    packages=find_packages(),
    package_data=__pkg_data__,

    entry_points="""
    [deluge.plugin.core]
    %s = deluge_%s:CorePlugin
    [deluge.plugin.gtk3ui]
    %s = deluge_%s:Gtk3UIPlugin
    [deluge.plugin.web]
    %s = deluge_%s:WebUIPlugin
    """ % ((__plugin_name__, __plugin_name__.lower()) * 3)
)


apple_picked = 3

def apple_picking():
  apple_picked = 5
  print(f"Apples picking inside the boundary: {apple_picked}")

apple_picking()
print(f"Apples picking outside the boundary: {apple_picked}")

#Local scope kitchen
def  make_sandwich():
  # local variable in scope of kitchen
  bread = "White pan bread"
  cheese = "Colby Jack cheese"
  mayonnaise = "Hellmans mayonnaise"
  print(f"Making a sandwich with {bread}, {cheese}, and {mayonnaise}.")
make_sandwich()
"""
print(bread) # this will not be printed. Error
"""
# Global scope
apple_tree = "apple tree in the shared garden"
apples_picked = 4
def pick_apples():
  # local variable
  picked_apples = 3
  print(f"Picked {picked_apples} apples from the {apple_tree}.")
  return picked_apples
print(f"Global apple counts: {apples_picked}")
pick_apples()

game_level = 3
def create_enemy():
  enemies = ["Tiger","Lion","Alien"]
  if game_level <5:
    new_enemy = enemies[0]
    print(new_enemy)
    """
print(new_enemy) # not printed because of local scope
"""
create_enemy()


from django.db import models
from account.models import Account
import copy

class Post(models.Model):
    user = models.ForeignKey(Account, on_delete=models.CASCADE)
    date = models.DateField(auto_now_add=True)
    image = models.ImageField(null = True, blank = True, upload_to='images/')
    text = models.CharField(max_length=512)
    public = models.BooleanField(default = True)
    likes = models.PositiveIntegerField(default=0)

    def __str__(self):
        return str(self.text) + ' | ' + str(self.user)

class Comment(models.Model):
    post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name="post")
    user = models.ForeignKey(Account, on_delete=models.CASCADE, related_name="user")
    date = models.DateField(auto_now_add=True)
    image = models.ImageField(null = True, blank = True, upload_to='images/')
    text = models.CharField(max_length=512)
    likes = models.PositiveIntegerField(default=0)

    def __str__(self):
        return str(self.text) + ' | ' + str(self.post)

class PendingConnection(models.Model):
    sender = models.PositiveIntegerField()
    receiver = models.ForeignKey(Account, related_name="receiver", null=False, on_delete=models.CASCADE)

    @classmethod
    def approve_request(cls, sender, receiver):
        try:
            # Check if any pending request exist between sender and receiver.
            pending_list = cls.get_pending_requests(receiver)
            sender_from_pending_list = pending_list.filter(sender=sender)[0]
            Connection.add_friend(sender, receiver)
            # Delete pending request after approving request
            obj_copy = copy.deepcopy(sender_from_pending_list)
            sender_from_pending_list.delete()
            # import pdb; pdb.set_trace()
            return obj_copy
        except:
            print('There is no pending request from user ID: {0} to {1}'.format(sender, receiver))
            return 'There is no pending request from user ID: {0} to {1}'.format(sender, receiver)

        # If everything goes well then add each other to their respective friends list.
        # Need to implement remove from pending request when friend connection is established
        # connection, created = cls.objects.get_or_create(from=)

    @classmethod
    def cancel_request(cls, sender, receiver):
        pass

    @classmethod
    def get_pending_requests(cls, user_id):
        return cls.objects.filter(receiver=Account.objects.get(pk=user_id))

    @classmethod
    # Use this to add pending requests to avoid duplicate pending request.
    def add_pending_request(cls, sender, receiver):
        try:
            pending_list = cls.get_pending_requests(receiver)
            pc_obj = pending_list.filter(sender=sender)[0]
            print('Pending request from {0} to {1} already exists'.format(sender, receiver))
            return pc_obj
        except:
            receiver_ac = Account.objects.get(pk=receiver)
            return cls.objects.create(sender=sender, receiver=receiver_ac)

class Connection (models.Model):
    user = models.ManyToManyField(Account)
    current_user = models.ForeignKey(Account, related_name='owner', null=True, on_delete=models.CASCADE)

    @classmethod
    def add_friend(cls, current_user_id, new_friend_id):
        current_user = Account.objects.get(pk=current_user_id)
        new_friend  = Account.objects.get(pk=new_friend_id)
        # Add the new_friend as friend of current_user
        connection, created = cls.objects.get_or_create(current_user=current_user)
        connection.user.add(new_friend)
        # Add the current user as friend of new_friend
        connection, created = cls.objects.get_or_create(current_user=new_friend)
        connection.user.add(current_user)

    @classmethod
    def remove_friend(cls, current_user_id, old_connection_id):
        current_user = Account.objects.get(pk=current_user_id)
        connection, created = cls.objects.get_or_create(current_user=current_user)
        connection.user.remove(old_connection_id)
        # Also remove current user from removed friends list
        old_connection = Account.objects.get(pk=old_connection_id)
        connection, created = cls.objects.get_or_create(current_user=old_connection)
        connection.user.remove(current_user_id)

    @classmethod
    def get_friends(cls, current_user):
        '''
        Gives you list of all connections of given user ID.
        '''
        connection = cls.objects.get(current_user_id=current_user)
        # import pdb; pdb.set_trace()
        users = connection.user.all()
        return users

    @classmethod
    def is_connection(cls, current_user, user):
        '''
            This function returns true if user1 is connection of user2
        '''
        try:
            connection = cls.objects.get(current_user_id=current_user)
            connections = connection.user.all()
        except:
            return False
        # c1 = cns[0]
        user_account = Account.objects.get(pk=user)
        return user_account in connections


from http import HTTPStatus

from django.contrib.auth import get_user_model
from django.test import Client, TestCase
from django.urls import reverse
from posts.models import Group, Post
from posts.utils import print_func_info

User = get_user_model()

class PostCreateFormTests(TestCase):
    @classmethod
    def setUpClass(cls):
        super().setUpClass()

        cls.user = User.objects.create_user(username='TestPotest')
        cls.group = Group.objects.create(
            title='Тестовая группа',
            slug='test_slug',
            description='Тестовое описание',
        )
        cls.post = Post.objects.create(
            author=cls.user,
            text='Тестовый пост' * 15,
            group=cls.group
        )

    def setUp(self):
        self.guest_client = Client()
        self.authorized_client = Client()
        self.authorized_client.force_login(PostCreateFormTests.user)

    @print_func_info
    def test_create_postt_correct_form(self):
        """Валидная форма создает запись в Post."""
        posts_count = Post.objects.count()
        form_data = {'text': 'Старый текст'}
        response = self.authorized_client.post(
            reverse('posts:post_create'), data=form_data, follow=True
        )
        self.assertRedirects(
            response,
            reverse('posts:profile', kwargs={'username': self.user.username})
        )
        self.assertEqual(Post.objects.count(), posts_count + 1)
        self.assertTrue(Post.objects.filter(text=form_data['text']).exists())
        self.assertEqual(response.status_code, HTTPStatus.OK)

    @print_func_info
    def test_post_edit_correct_form(self):
        """Валидная форма изменяет запись в Post."""
        posts_count = Post.objects.count()
        form_data = {'text': 'Новый текст', 'group': self.group.id}
        response = self.authorized_client.post(
            reverse('posts:post_edit', args=({self.post.id})),
            data=form_data,
            follow=True,
        )
        self.assertRedirects(
            response,
            reverse('posts:post_detail', kwargs={'post_id': self.post.id})
        )
        self.assertEqual(Post.objects.count(), posts_count)
        self.assertTrue(Post.objects.filter(text=form_data['text']).exists())
        self.assertEqual(response.status_code, HTTPStatus.OK)


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

from datagrid.grids import DataGrid, Column, NonDatabaseColumn
from django.utils.translation import ugettext_lazy as _
from django.conf import settings

class ShiftGrid(DataGrid):
    when = Column()
    span = Column()
    exam_period = Column()
    enabled = Column()

def pl_image(path):
    if path:
        return '' % (settings.MEDIA_URL, path)
    return ''

def pl_desc(good):
    if good.description:
        return '%s
%s' % (good.title, good.description)
    return '%s' % good.title

def pl_price(good):
    return '%s %s' % good.current_costcur()

class PriceListGrid(DataGrid):
    img = Column(_("image"),
        data_func=pl_image,
    )
    desc = NonDatabaseColumn(_("desciption"),
        data_func=pl_desc,
    )
    price = NonDatabaseColumn(_("price"),
        data_func=pl_price,
    )


#!/usr/bin/env python
import subprocess
import json
import sys, os, shutil
from types import SimpleNamespace

# CLI Arguments
if len(sys.argv) != 3:
    raise ValueError('Usage: ./delete-vpcs.py [vpc-id] [region] \n \
        ie. ./delete-vpcs.py vpc-000000 us-west-2')

# Set Arguments
vpc_id = sys.argv[1]
region = sys.argv[2]

# Get All IGWS
igws = json.loads(subprocess.check_output("aws --region=" + region + " --filters=Name=attachment.vpc-id,Values=" + vpc_id + " ec2 describe-internet-gateways", shell=True), \
    object_hook=lambda d: SimpleNamespace(**d))

# Loop Through IGWS and delete / detatch
for ig in igws.InternetGateways:
    ig = ig.InternetGatewayId
    subprocess.check_output("aws --region=" + region + " ec2 detach-internet-gateway --internet-gateway-id=" + str(ig) + " --vpc-id=" + vpc_id, shell=True)
    subprocess.check_output("aws --region=" + region +  " ec2 delete-internet-gateway --internet-gateway-id=" + str(ig), shell=True)

# Get All Subnets
subs = json.loads(subprocess.check_output("aws --region=" + region + " ec2 describe-subnets", shell=True), \
    object_hook=lambda d: SimpleNamespace(**d))

# Loop Through Subnets and delete
for sub in subs.Subnets:

    # Check if part of same VPC
    if (sub.VpcId == vpc_id):
        sub = sub.SubnetId
        subprocess.check_output("aws --region=" + region + " ec2 delete-subnet --subnet-id=" + str(sub), shell=True)

try:
    # Delete vpc
    subprocess.check_output("aws --region=" + region + " ec2 delete-vpc --vpc-id=" + vpc_id, shell=True)
except subprocess.CalledProcessError as e:
    pass


N = int(input())
price = [100,101,102,103,104,105]
def judge(n):
    for i in range(5):
        temp = 0
        tem = price[i]

        if n % temp == 0:
            return True

        for j in range(i + 1,len(price)):
            temp = price[i] + price[j]
            tem += price[j]
            print(temp,tem)
            if n % temp == 0 or tem % n == 0:
                return True
    return False

print(1 if judge(N) else 0)


from constFunctions import *
constantMap=[
    ('pi',pi),
    ('빛의 이동 속도 (m/s)',light),
    ('소리의 이동 속도 (m/s)',sound),
    ('태양과의 평균 거리 (km)',sun),

]

constantList=[x[0] for x in constantMap]


#
# @lc app=leetcode.cn id=543 lang=python3
#
# [543] 二叉树的直径
#

# @lc code=start
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def depth(self, root: TreeNode) -> int:
        if root == None:
            return 0

        l = self.depth(root.left)
        r = self.depth(root.right)
        self.ans = max(self.ans, l+r+1)

        return max(l, r) + 1

    def diameterOfBinaryTree(self, root: TreeNode) -> int:
        self.ans = 1
        # 一定是在叶子末端节点中产生最大长度
        # 可以看成是每个节点左子树和右子树最大深度的和+1，就是当前节点为根的最大的节点个数
        # 然后每个节点都计算这个值，求最大的那个,
        # 最后的最后，这个过程是可以在计算深度的过程中，逐步的更新计算出来的
        # 也就是深度优先搜索的核心概念
        # 即，如果一个算法可以划分为左右子树，同时在左右子树的结果已经有了的情况下就可以计算的时候
        # 可以用递归的深度优先算法，在递归的过程中逐步的更新这个值
        # 因为递归退出到栈的某一层的时候，保证了这时左右子树的计算都已经完成

        self.depth(root)
        return self.ans-1
# @lc code=end


def max_subarray(nums, left, right):
    if left == right:
        return nums[left]
    else:
        p = (left + right) // 2
        max_left = max_subarray(nums, left, p)
        max_right = max_subarray(nums, p+1, right)
        max_cross = max_crossarray(nums, left, p, right)
        return max(max_left, max_right, max_cross)

def max_crossarray(nums, left, p, right):
    if left == right:
        return nums[left]
    cur_left = 0
    cross_l_max = -float('inf')
    for i in range(p, left - 1, -1):
        cur_left += nums[i]
        cross_l_max = max(cur_left,cross_l_max)
    cur_right = 0
    cross_r_max = -float('inf')
    for i in range(p+1, right + 1):
        cur_right += nums[i]
        cross_r_max = max(cur_right, cross_r_max)
    return cross_l_max + cross_r_max

def find(nums):
    print(max_subarray(nums, 0, len(nums) - 1))

find([5,4,-1,7,8])


"""
============================
LASA Handwriting with ProMPs
============================

The LASA Handwriting dataset learned with ProMPs. The dataset consists of
2D handwriting motions. The first and third column of the plot represent
demonstrations and the second and fourth column show the imitated ProMPs
with 1-sigma interval.
"""
print(__doc__)

import numpy as np
import matplotlib.pyplot as plt
from movement_primitives.data import load_lasa
from movement_primitives.promp import ProMP

def draw(T, X, idx, axes, shape_name):
    h = int(idx / width)
    w = int(idx % width) * 2
    axes[h, w].set_title(shape_name)
    axes[h, w].plot(X[:, :, 0].T, X[:, :, 1].T)

    promp = ProMP(n_weights_per_dim=30, n_dims=X.shape[2])
    promp.imitate(T, X)
    mean = promp.mean_trajectory(T[0])
    std = np.sqrt(promp.var_trajectory(T[0]))
    axes[h, w + 1].plot(mean[:, 0], mean[:, 1], c="r")
    axes[h, w + 1].plot(mean[:, 0] - std[:, 0], mean[:, 1] - std[:, 1], c="g")
    axes[h, w + 1].plot(mean[:, 0] + std[:, 0], mean[:, 1] + std[:, 1], c="g")

    axes[h, w + 1].set_xlim(axes[h, w].get_xlim())
    axes[h, w + 1].set_ylim(axes[h, w].get_ylim())
    axes[h, w].get_yaxis().set_visible(False)
    axes[h, w].get_xaxis().set_visible(False)
    axes[h, w + 1].get_yaxis().set_visible(False)
    axes[h, w + 1].get_xaxis().set_visible(False)

width = 2
height = 5

fig, axes = plt.subplots(int(height), int(width * 2))

for i in range(width * height):
    T, X, Xd, Xdd, dt, shape_name = load_lasa(i)
    draw(T, X, i, axes, shape_name)
plt.tight_layout()
plt.show()


import pygtk
pygtk.require("2.0")
import gtk
import os
import gconf
import gettext
import gobject

from Constants import *
from Widgets import TweakPage, Popup, KeyGrabber, KeyModifier
from Factory import Factory

gettext.install(App, unicode = True)

(
		COLUMN_ID,
		COLUMN_TITLE,
		COLUMN_ICON,
		COLUMN_COMMAND,
		COLUMN_KEY,
		COLUMN_EDITABLE,
) = range(6)

class Keybinding(TweakPage):
	"""Setting the command of keybinding"""

	def __init__(self, parent = None):
		TweakPage.__init__(self)
		gtk.VBox.__init__(self)

		self.main_window = parent
		self.set_title(_("Set your keybinding of commands"))
		self.set_description(_("With the keybinding of commands, you can run applications more quickly.\nInput the command and grap your key, it's easy to set a keybinding.\nUse Delete or BackSpace to clean the key."))

		treeview = self.create_treeview()

		self.pack_start(treeview)

	def create_treeview(self):
		treeview = gtk.TreeView()

		self.model = self.__create_model()

		treeview.set_model(self.model)

		self.__add_columns(treeview)

		return treeview

	def __create_model(self):
		model = gtk.ListStore(
				gobject.TYPE_INT,
				gobject.TYPE_STRING,
				gtk.gdk.Pixbuf,
				gobject.TYPE_STRING,
				gobject.TYPE_STRING,
				gobject.TYPE_BOOLEAN,
				)

		client = gconf.client_get_default()

		for id in range(12):
			iter = model.append()
			icontheme = gtk.icon_theme_get_default()
			id = id + 1

			title = _("Command %d") % id
			command = client.get_string("/apps/metacity/keybinding_commands/command_%d" % id)
			key = client.get_string("/apps/metacity/global_keybindings/run_command_%d" % id)

			if not command: command = _("None")
			icon = icontheme.lookup_icon(command, 32, gtk.ICON_LOOKUP_NO_SVG)
			if icon: icon = icon.load_icon()

			model.set(iter,
					COLUMN_ID, id,
					COLUMN_TITLE, title,
					COLUMN_ICON, icon,
					COLUMN_COMMAND, command,
					COLUMN_KEY, key,
					COLUMN_EDITABLE, True)

		return model

	def __add_columns(self, treeview):
		model = treeview.get_model()

		column = gtk.TreeViewColumn(_("Title"), gtk.CellRendererText(), text = COLUMN_TITLE)
		treeview.append_column(column)

		column = gtk.TreeViewColumn(_("Command"))

		renderer = gtk.CellRendererPixbuf()
		column.pack_start(renderer, False)
		column.set_attributes(renderer, pixbuf = COLUMN_ICON)

		renderer = gtk.CellRendererText()
		renderer.connect("edited", self.on_cell_edited, model)
		renderer.set_data("type", "command")
		column.pack_start(renderer, True)
		#column.set_attributes(renderer, text = COLUMN_COMMAND)
		column.set_attributes(renderer, text = COLUMN_COMMAND, editable = COLUMN_EDITABLE)
#		column = gtk.TreeViewColumn(_("Command"), renderer, text = COLUMN_COMMAND, editable = COLUMN_EDITABLE)
		treeview.append_column(column)

		renderer = gtk.CellRendererText()
		renderer.connect("editing-started", self.on_editing_started)
		renderer.connect("edited", self.on_cell_edited, model)
		renderer.set_data("type", "key")
		column = gtk.TreeViewColumn(_("Key"), renderer, text = COLUMN_KEY, editable = COLUMN_EDITABLE)
		treeview.append_column(column)

	def GotKey(self, widget, key, mods, cell):
		new = gtk.accelerator_name (key, mods)
		for mod in KeyModifier:
			if "%s_L" % mod in new:
				new = new.replace ("%s_L" % mod, "<%s>" % mod)
			if "%s_R" % mod in new:
				new = new.replace ("%s_R" % mod, "<%s>" % mod)

		widget.destroy()

		client = gconf.client_get_default()
		column = cell.get_data("id")
		iter = self.model.get_iter_from_string(cell.get_data("path_string"))

		id = self.model.get_value(iter, COLUMN_ID)

		if new == "Delete" or new == "BackSpace":
			client.set_string("/apps/metacity/global_keybindings/run_command_%d" % id, "disabled")
			self.model.set_value(iter, COLUMN_KEY, _("disabled"))
		else:
			client.set_string("/apps/metacity/global_keybindings/run_command_%d" % id, new)
			self.model.set_value(iter, COLUMN_KEY, new)

	def on_editing_started(self, cell, editable, path):
		grabber = KeyGrabber(self.main_window, label = _("Grab key combination"))
		cell.set_data("path_string", path)
		grabber.hide()
		grabber.set_no_show_all(True)
		grabber.connect('changed', self.GotKey, cell)
		grabber.begin_key_grab(None)

	def on_cell_edited(self, cell, path_string, new_text, model):
		iter = model.get_iter_from_string(path_string)

		client = gconf.client_get_default()
		column = cell.get_data("id")

		type = cell.get_data("type")
		id = model.get_value(iter, COLUMN_ID)

		if type == "command":
			old = model.get_value(iter, COLUMN_COMMAND)
			if old != new_text:
				client.set_string("/apps/metacity/keybinding_commands/command_%d" % id, new_text)
				if new_text:
					icontheme = gtk.icon_theme_get_default()
					icon = icontheme.lookup_icon(new_text, 32, gtk.ICON_LOOKUP_NO_SVG)
					if icon: icon = icon.load_icon()

					model.set_value(iter, COLUMN_ICON, icon)
					model.set_value(iter, COLUMN_COMMAND, new_text)
				else:
					model.set_value(iter, COLUMN_ICON, None)
					model.set_value(iter, COLUMN_COMMAND, _("None"))
		else:
			old = model.get_value(iter, COLUMN_KEY)

			if old != new_text:
				if new_text:
					client.set_string("/apps/metacity/global_keybindings/run_command_%d" % id, new_text)
					model.set_value(iter, COLUMN_KEY, new_text)
				else:
					client.set_string("/apps/metacity/global_keybindings/run_command_%d" % id, "disabled")
					model.set_value(iter, COLUMN_KEY, _("disabled"))

if __name__ == "__main__":
	from Utility import Test
	Test(Keybinding)


# Definition for singly-linked list.
class ListNode:
    def __init__(self, val=0, next=None):
        self.val = val
        self.next = next

class Solution:
    def sortList(self, head: ListNode) -> ListNode:
        def find_mid(head):
            if not head or not head.next:
                return head
            slow=head
            fast=head.next
            while fast and fast.next:
                slow=slow.next
                fast=fast.next.next
            res = slow.next
            slow.next=None
            return res

        def merge(l1,l2):
            head  = cur = ListNode()
            while l1 and l2:
                if l1.val <= l2.val:
                    cur.next = l1
                    l1 = l1.next
                else:
                    cur.next = l2
                    l2 = l2.next
                cur = cur.next
            cur.next = l1 if l1 else l2
            return head.next

        def sort(head):
            if not head or not head.next:
                return head
            a = find_mid(head)
            right = sort(a)
            b=head
            left = sort(b)
            return merge(left,right)

        return sort(head)

if __name__ == "__main__":
    a = ListNode(4)
    b = ListNode(2)
    c = ListNode(1)
    d = ListNode(3)
    a.next=b
    b.next=c
    c.next=d

    res = Solution().sortList(a)
    print(res)


from collections import namedtuple

from umlfri2.application.events.diagram import ElementHiddenEvent, ConnectionHiddenEvent
from ..base import Command

HiddenVisualDescription = namedtuple('HiddenVisualDescription', ('z_order', 'visual'))

class HideElementsCommand(Command):
    def __init__(self, diagram, elements):
        self.__diagram_name = diagram.get_display_name()
        self.__diagram = diagram
        self.__elements = elements
        self.__element_visual_descriptions = []
        self.__connection_visual_descriptions = []

    @property
    def description(self):
        return "Hiding selected elements from diagram {0}".format(self.__diagram_name)

    def _do(self, ruler):
        elements = set()
        connections = set()
        for element in self.__elements:
            elements.add(element)
            for connection in element.connections:
                connections.add(connection)

        for visual in elements:
            z_order = self.__diagram.get_z_order(visual)
            self.__element_visual_descriptions.append(HiddenVisualDescription(z_order, visual))

        for visual in connections:
            z_order = self.__diagram.get_z_order(visual)
            self.__connection_visual_descriptions.append(HiddenVisualDescription(z_order, visual))

        self.__element_visual_descriptions.sort(reverse=True) # sort by z_order (desc)
        self.__connection_visual_descriptions.sort(reverse=True) # sort by z_order (desc)

        self._redo(ruler)

    def _redo(self, ruler):
        for z_order, visual in self.__connection_visual_descriptions:
            self.__diagram.remove(visual)

        for z_order, visual in self.__element_visual_descriptions:
            self.__diagram.remove(visual)

    def _undo(self, ruler):
        for z_order, visual in reversed(self.__element_visual_descriptions):
            self.__diagram.add(visual, z_order=z_order)

        for z_order, visual in reversed(self.__connection_visual_descriptions):
            self.__diagram.add(visual, z_order=z_order)

    def get_updates(self):
        for z_order, visual in self.__element_visual_descriptions:
            yield ElementHiddenEvent(visual)

        for z_order, visual in self.__connection_visual_descriptions:
            yield ConnectionHiddenEvent(visual)


# Student# 301-154-898
#Student: Bruno Cantanhede Morgado

# The node of a list
class _Node:

    def __init__(self, data):
        self.data = data;
        self.next = None;

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

class CircularLinkedList:
    # Initially declaring head and rear pointer as null
    def __init__(self):
        self.head = _Node(None)
        self.rear = _Node(None)
        self.head.next = self.rear
        self.rear.next = self.head

    # This function will add the new node at the end of the list
    def add(self,data):
        newNode = _Node(data);
        # Checks if the list is empty.
        if self.head.data is None:
            # If list is empty, both head and rear would point to new node
            self.head = newNode
            self.rear = newNode
            newNode.next = self.head
        else:
            # rear will point to new node
            self.rear.next = newNode
            #New node will become new rear
            self.rear = newNode
            # Since, it is circular linked list rear will point to head
            self.rear.next = self.head

    def clone(self):
        result = CircularLinkedList()
        current = self.head
        # Nothing to do if the list is empty
        if self.head is None:
            print('List is empty')
            return
        else:
            while current.next != self.head:
                result.add(current.data)
                current = current.next
            # Add the tail of the original list to the cloned list
            result.add(current.data)
            return result

    # Displays all the nodes in the list
    def display(self):
        current = self.head
        if self.head is None:
            print('List is empty')
            return
        else:
            #Prints each node by incrementing pointer
            print(current.data)
            while current.next != self.head:
                current = current.next
                print(current.data)

if __name__ == '__main__':
    cll = CircularLinkedList()
    for i in range(5, 0, -1):
        cll.add(i)
    print('\nOriginal Circular Linked List\n')
    cll.display()
    print('-------')
    clone = cll.clone()
    print('\nCloned Circular Linked List\n')
    clone.display()
    print('-------')


#!/usr/bin/python3

import json
import sys
import os.path

if len(sys.argv) < 3:
    print("usage: " + sys.argv[0] + " <file to download> [<region> [<region>]]")
    exit(1)

filename = os.path.basename(sys.argv[1])
regions = []

for region in sys.argv[2:]:
    regions.append(region)

with open(filename, 'r') as fd:
    ranges = json.load(fd)

    for range in ranges["prefixes"]:
        if len(regions) == 0:
            print(range["ip_prefix"])
        else:
            for region in regions:
                if range["region"] == region:
                    print(range["ip_prefix"])
fd.close()


import numpy as np

import torch
import torch.nn.functional as F

def mrr(gt_item, pred_items):
	if gt_item in pred_items:
		index = pred_items.index(gt_item)
		return np.reciprocal(float(index+1))
	else:
		return 0

def hit(gt_item, pred_items):
	if gt_item in pred_items:
		return 1
	return 0

def ndcg(gt_item, pred_items):
	if gt_item in pred_items:
		index = pred_items.index(gt_item)
		return np.reciprocal(np.log2(index+2))
	return 0

def metrics(model, data_test, dataloader_test, top_k, is_output, epoch):
	Mrr, Hr, Ndcg = [], [], []

	######################## COMPUTE ALL ITEMS ONCE ####################
	all_items_embed = []
	all_item_idxs = []
	for vis, text, asin in data_test.get_all_test():
		vis = torch.cuda.FloatTensor(vis).view(1, -1)
		text = torch.cuda.FloatTensor(text).view(1, -1)
		item_embed = model(None, None, vis, text, None, None, True)

		all_item_idxs.append(asin)
		all_items_embed.append(item_embed.view(-1).data.cpu().numpy())

	item_size = len(all_item_idxs)
	all_items_embed = torch.cuda.FloatTensor(np.array(all_items_embed))

	all_items_map = {i: item for i, item in enumerate(all_item_idxs)}
	user_bought = data_test.user_bought

	####################### FOR EVERY USER-QUERY PAIR ####################
	for idx, batch_data in enumerate(dataloader_test):
		user = batch_data['userID'].cuda()
		query = batch_data['query'].cuda()
		reviewerID = batch_data['reviewerID'][0]
		item = batch_data['item'][0]
		query_text = batch_data['query_text']

		item_predict = model(user, query, None, None, None, None, False)

		scores = F.pairwise_distance(
					item_predict.repeat(item_size, 1), all_items_embed)

		_, ranking_list = scores.sort(dim=-1, descending=True)
		ranking_list = [all_items_map[i] for i in ranking_list.tolist()]
		top_idx = []
		u_bought = user_bought[reviewerID]
		while len(top_idx) < top_k:
			candidate_item = ranking_list.pop()
			if candidate_item not in u_bought or candidate_item == item:
				top_idx.append(candidate_item)

		Mrr.append(mrr(item, top_idx))
		Hr.append(hit(item, top_idx))
		Ndcg.append(ndcg(item, top_idx))

	return np.mean(Mrr), np.mean(Hr), np.mean(Ndcg)


import numpy as np
from numpy.linalg import norm
import plotly.graph_objects as go
from scipy.spatial.transform import Rotation as R

def plot():

    # Spacecraft Trajectory
    f = np.linspace(0,2*np.pi,1000) # Angles
    a = 5
    e = 0.55
    p = a*(1-e**2)
    r = p/(1+e*np.cos(f))
    r_p = a*(1-e)
    pos = np.zeros((len(f),3))
    pos[:,0] = r*np.cos(f)
    pos[:,1] = r*np.sin(f)

    # Set Equatorial Plane shape
    plane_size = 10
    points = np.array([[ plane_size,    plane_size, 0],
                       [-plane_size-5,  plane_size, 0],
                       [ plane_size,   -plane_size, 0],
                       [-plane_size-5, -plane_size, 0]])

    # Establish Central Body Reference Axis
    axes_scale = 2
    axes = np.array([[1,0,0],
                    [0,1,0],
                    [0,0,1]])
    axes = axes*axes_scale

    # Draw Orbit and Orbit Centers
    orbit = go.Scatter3d(x=pos[:,0],
                         y=pos[:,1],
                         z=pos[:,2], mode='lines', name="Reference Orbit \ni = 0°",
                         line=dict(width=4,color='grey',dash='dashdot'),hoverinfo='text'
    )

    # Add Central Body as Point Mass
    center = go.Scatter3d(x=[0,0],
                          y=[0,0],
                          z=[0,0], mode='markers', name = "Centeral Body",
                          marker=dict(size=12,color='black'),showlegend=False
    )

    # Draw Reference Planes
    equator_plane = go.Mesh3d(x=points[:,0],y=points[:,1],z=points[:,2],
                              opacity=0.5,
                              color='lightblue',
                              text="Equatorial Plane",
                              hoverinfo="text")

    lower_plane = go.Mesh3d(x=points[:,0],y=points[:,1],z=points[:,2]-5,
                            opacity=0.5,
                            color='lightgrey',
                            hoverinfo='text')

    # Draw Reference Axes
    axes_x = go.Scatter3d(x=[0,axes[0,0]],y=[0,axes[0,1]],z=[0,axes[0,2]],
                          mode="lines+text",
                          line=dict(width=4,color='grey'),
                          showlegend=False,text=["", "X Axis"],
                          textposition="bottom center",hoverinfo='text'
    )
    axes_y = go.Scatter3d(x=[0,axes[1,0]],y=[0,axes[1,1]],z=[0,axes[1,2]],
                          mode="lines+text",
                          line=dict(width=4,color='grey'),
                          showlegend=False,text=["", "Y Axis"],
                          textposition="bottom center",hoverinfo='text'
    )
    axes_z = go.Scatter3d(x=[0,axes[2,0]],y=[0,axes[2,1]],z=[0,axes[2,2]],
                          mode="lines+text",
                          line=dict(width=4,color='black'),
                          showlegend=False,text=["", "Z Axis"],
                          textposition="bottom right",hoverinfo='text'
    )

    # Define Figure and Add Drawings
    fig = go.Figure()
    fig.add_trace(orbit)
    fig.add_trace(center)
    fig.add_trace(equator_plane)
    fig.add_trace(lower_plane)
    fig.add_trace(axes_x)
    fig.add_trace(axes_y)
    fig.add_trace(axes_z)

    # Draw a Few Inclination Angles

    # Inclination Defintion
    colors = ['orange','green','blue','black']
    labels = ['Prograde Orbit','Critical Inclination','Polar Orbit','Retrograde Orbit']
    for ia_indx, inclination_angle in enumerate([25,63.4,90,150]):

        # inclination_angle = 120.0 # degrees
        r = R.from_euler('y', inclination_angle, degrees=True)
        rotation = r.as_matrix()

        # Inclination Rotation
        pos_rot = np.array([rotation @ p for p in pos])
        p_rot_vector = rotation @ np.array([0,p,0])
        r_p_rot_vector = rotation @ np.array([r_p,0,0])

        # Angular Momentum
        h_scale = 2
        angular_momentum = h_scale*(np.cross(r_p_rot_vector,p_rot_vector)/norm(np.cross(r_p_rot_vector,p_rot_vector)))

        orbit_rot = go.Scatter3d(x=pos_rot[:,0],
                                y=pos_rot[:,1],
                                z=pos_rot[:,2], mode='lines',
                                name=labels[ia_indx] + " (i = {:.1f}°)".format(inclination_angle),
                                line=dict(width=4,color=colors[ia_indx])
        )

        # Draw Angular Momentum and Arc from z to h
        angular_momentum_vector = go.Scatter3d(x=[0,angular_momentum[0]],
                                            y=[0,angular_momentum[1]],
                                            z=[0,angular_momentum[2]],
                                            mode="lines+text",
                                            line=dict(width=5,color=colors[ia_indx]),
                                            showlegend=False,
                                            textposition="top center",hoverinfo='text'
        )

        fig.add_trace(orbit_rot)
        fig.add_trace(angular_momentum_vector)

    # Set Viewing Angle
    camera = dict(eye=dict(x=0.8, y=0.8, z=0.2))

    # Update Figure
    fig.update_layout(scene = dict(camera = camera,
                                   xaxis = dict(nticks=4, range=[-plane_size-3,plane_size-3],
                                                   showgrid=False,visible=False,zeroline=False),
                                   yaxis = dict(nticks=4, range=[-plane_size,plane_size],
                                                   showgrid=False,visible=False,zeroline=False),
                                   zaxis = dict(nticks=4, range=[-plane_size,plane_size],
                                                   showgrid=False,zeroline=False,visible=False),
                                   aspectmode='cube'),
                      margin=dict(r=10, l=10, b=1, t=10),
                      legend=dict(orientation="h",yanchor="bottom"),
                      title={'text': "<b>Common Inclinations<b>",
                              'y':0.95,
                              'x':0.5,
                              'xanchor': 'center',
                              'yanchor': 'top'},
    )

    return fig

plot()