from subprocess import call, check_output
from os.path import join, isdir, isfile
from os import error, getcwd, environ, pathsep
from time import sleep
import colorama
from colorama import Style, Fore

colorama.init(autoreset=True)

adb_dir_name = 'minimal_adb_and_fastboot'
recovery_name = 'recovery.img'
magisk_file_name = 'Magisk-v23.0.zip'
curr_dir = getcwd()
YELLOW_BRIGHT = Fore.YELLOW + Style.BRIGHT
WHITE_BRIGHT = Fore.WHITE + Style.BRIGHT
RED_BRIGHT = Fore.RED + Style.BRIGHT

def pre_requisites():
    if isfile('pre-requisites.txt'):
        with open('pre-requisites.txt','r') as f:
            important_lines = f.readlines()
            for line in important_lines:
                print(YELLOW_BRIGHT + line, end='')

        f.close()

    else:
        print(RED_BRIGHT + '[*] pre-requisites.txt not found. Cannot proceed Further, download this software again.')

def setup_adb()->bool:
    '''
    performs required tasks to setup adb on the windows machine.
    Sets environment variable for minimal adb and fastboot.
    '''

    if isdir(adb_dir_name):
        adb_env_path = join(curr_dir, adb_dir_name)

        environ["PATH"] += pathsep + adb_env_path
        if adb_env_path in environ["PATH"]:
            print(WHITE_BRIGHT + '[*] Minimal ADB and Fastboot has been added to environment variable path successfully.')
            print(WHITE_BRIGHT + '[*] Checking if ADB is working!')
            check_adb_version =check_output('adb --version', shell=True).decode()
            print(check_adb_version)
            user_check = input('Can you see any adb version installed? (y/n) : ').lower()
            if user_check == 'y':
                print(WHITE_BRIGHT + '[+] ADB installed successfully!')
                return True
        else:
            print(RED_BRIGHT + '[-] Something went wrong while adding Minimal ADB and Fastboot to environment variable path.')
            quit()

    else:
        print(RED_BRIGHT + '[-] Minimal ADB and Fastboot folder is missing, please clone/download the repository again.')
        quit()

def start_adb_server():
    '''
    Starts adb server on the machine.
    '''
    print( YELLOW_BRIGHT + "\n[*] Important : if you're prompted to allow debugging, then tick *Always allow from this computer* and press ok.")
    print(WHITE_BRIGHT + '[*] Starting ADB SERVER...')
    call('adb start-server', shell=True)

def connected_devices() -> bool:
    '''
    checks the devices detected and connected by the windows machine.
    '''

    connected_devices_output = check_output('adb devices', shell=True)
    print(connected_devices_output.decode())
    user_dev_check = input(YELLOW_BRIGHT + '[*] did you find your android device in the list? (y/n) : ').lower()

    if user_dev_check == 'y':
        print(WHITE_BRIGHT + '[*] Device Connected!!')
        return True

    print(RED_BRIGHT + '[-] Try installing drivers needed to root your android device.')
    return False

def start_custom_recovery_flash()->True:
    '''
    starts recovery flashing process.
    '''

    def check_recovery_image()->bool:
        '''
        checks if recovery image is present in the directory.
        '''
        if isfile(recovery_name):
            print(WHITE_BRIGHT + '[*] Found Custom Recovery image.')
            return True

        print(RED_BRIGHT + "[-] No custom recovery image found. Don't to rename custom recovery image as recovery.img")
        print(RED_BRIGHT + '[-] Cannot proceed further. Exiting Program...')
        quit()

    try:

        if check_recovery_image():
            recovery_path = join(curr_dir, recovery_name)

            adb_reboot_bootloader_output = check_output('adb reboot bootloader', shell=True).decode()
            print(adb_reboot_bootloader_output)
            sleep(2)

            input(YELLOW_BRIGHT + '[*] Important Step : Press any key after placing your custom recovery image file inside this folder, by renaming it to recovery.img if not done yet!')

            print(WHITE_BRIGHT + '[*] Flashing Recovery.')
            fastboot_flash_output = check_output('fastboot flash recovery {}'.format(recovery_path), shell=True).decode()
            print(fastboot_flash_output)
            sleep(2)

            print(WHITE_BRIGHT + '[*] Rebooting into bootloader mode.')
            fastboot_reboot_bootloader_output = check_output('fastboot reboot-bootloader', shell=True).decode()
            print(fastboot_reboot_bootloader_output)
            sleep(2)

            print(WHITE_BRIGHT + '[*] Erasing Cache.')
            fastboot_erase_cache_output = check_output('fastboot erase cache', shell=True).decode()
            print(fastboot_erase_cache_output)
            sleep(2)

    except Exception as e:
        print(RED_BRIGHT + '[-] An Exception Occurred')
        return False

    finally:
        print(WHITE_BRIGHT + '[*] Rebooting device into fastboot mode.')
        fastboot_reboot_output = check_output('fastboot reboot', shell=True).decode()
        print(fastboot_reboot_output)
        sleep(2)

        return True

def transfer_magisk_zip()->bool:
    '''
    transfers the magisk manager zip to internal storage.
    '''
    source = join(curr_dir, magisk_file_name)
    destination = '/sdcard/'
    try:
        print(WHITE_BRIGHT + '[*] Starting File Transfer')
        file_transfer_output = check_output('adb push {} {}'.format(source, destination), shell=True).decode()
        print(file_transfer_output)
        return True
    except Exception :
        print(RED_BRIGHT + '[-] Exception Occurred while transferring Magisk Manager. Due to error you cannot move further but you can manually transfer and install zip.')
        print(RED_BRIGHT + 'Exception : ', Exception)
        return False

def adb_reboot_recovery()->bool:
    '''
    reboots android device into recovery.
    '''
    try:
        print(WHITE_BRIGHT + '[*] Rebooting device into recovery mode.')
        recovery_reboot_output = check_output('adb reboot recovery', shell=True).decode()
        print(recovery_reboot_output)
        sleep(5)

    except Exception :
        print(RED_BRIGHT + '[-] Exception occured while rebooting device.')
        return False

    return True

def adb_reboot_device()->bool:
    '''
    reboots android device into recovery.
    '''
    try:
        print(WHITE_BRIGHT + '[*] Rebooting device.')
        recovery_reboot_output = check_output('adb reboot', shell=True).decode()
        print(recovery_reboot_output)
        sleep(5)

    except Exception :
        print(RED_BRIGHT + '[-] Exception occured while rebooting into recovery.')
        return False

    return True

pre_requisites()
setup_adb()
start_adb_server()
connected_devices()
try:
    if start_custom_recovery_flash():
        print(WHITE_BRIGHT + '[*] Custom image flashed sucessfully.')
        print('-'*40)

        print(WHITE_BRIGHT + '[*] Starting to transfer magisk to sd card.')
        print(YELLOW_BRIGHT + '[*] press Ctrl+C simultaneously to transfer files manually to sdcard.')
        print(WHITE_BRIGHT + '[*] Waiting For Device to detect...')

        # wait for some time till device reboots
        sleep(15)

        # continue to check if device if not connected.
        while not connected_devices():
            print(YELLOW_BRIGHT + '[*] Checking for device in 10 seconds....')
            sleep(10)

        if transfer_magisk_zip():
                print(WHITE_BRIGHT + '[+] Files Transferred successfully.')
                print('-'*40)
                print(WHITE_BRIGHT + '[*] Rebooting into Recovery, install the magisk zip from the sdcard.')
                sleep(5)

        if adb_reboot_recovery():
            print(YELLOW_BRIGHT + '[*] Now follow instructions Install->Select Storage-> Sd Card-> locate and choose Magisk zip-> swipe to install zip')
            print(YELLOW_BRIGHT + '[*] After successfull installation reboot your android device. First Reboot may take some time to boot. Do not interrupt while your android device is booting.')
            print(WHITE_BRIGHT + '[*] Voila!! Now your android device will be rooted after installing Magisk zip from recovery..')

    else:
        print(RED_BRIGHT + '[-] Failed to install custom image. Please try again after installing requirements.')

except KeyboardInterrupt:
    print(RED_BRIGHT + '[!] Ctrl+C detected! Exiting...')
    if adb_reboot_device():
        print(WHITE_BRIGHT + '[*] Your device is now rebooting.')
    else:
        print(YELLOW_BRIGHT + '[!] Please reboot your device manually.')


from django.shortcuts import render
from django.views.generic.base import TemplateView
from django.contrib.auth.decorators import login_required

from admin_panel import models
from register import models as reg_models

@login_required(login_url='/cabinet/site/login')
def statistics_view(request):
    return render(
        request,
        'admin_panel/statistics/index.html',
        {
            'houses_number': models.House.get_houses_count(),
            'flats_number': models.Flat.get_flats_count(),
            'active_users_number': reg_models.User.get_active_users().count(),
            'accounts_number': models.Account.get_accounts_count(),
            'new_master_request_number': models.MasterRequest.get_new_request_count(),
            'in_work_master_request_number': models.MasterRequest.get_in_work_request_count(),
        }
    )


##
# In a particular jurisdiction, older license plates consist of three letters followed by
# three digits. When all of the license plates following that pattern had been used, the
# format was changed to four digits followed by three letters.
# Write a function that generates a random license plate. Your function should have
# approximately equal odds of generating a sequence of characters for an old license
# plate or a new license plate. Write a main program that calls your function and
# displays the randomly generated license plate.
#

from random import randint, choice
from string import ascii_letters, digits

def generatePlate():

    # set initial plate as ampty string
    plate = ""

    # generate old or new format: 0 for old, 1 for new one
    format = randint(0, 1)

    # generate random numbers and letters and compone plate
    # old format:
    if format == 0:
        for i in range(3):
            plate = plate + choice(ascii_letters)

        for i in range(3):
            plate = plate + choice(digits)

    # new format:
    else:
        for i in range(4):
            plate = plate + choice(digits)

        for i in range(3):
            plate = plate + choice(ascii_letters)

    return plate

def main():
    print("La tua targa è:", generatePlate())

main()


####### REQUIRED IMPORTS FROM THE PREVIOUS ASSIGNMENT #######
from my_package.model import InstanceSegmentationModel
from my_package.data import Dataset
from my_package.analysis import plot_visualization
from my_package.data.transforms import FlipImage, RescaleImage, BlurImage, CropImage, RotateImage
from PIL import Image

####### ADD THE ADDITIONAL IMPORTS FOR THIS ASSIGNMENT HERE #######
from tkinter import Tk, filedialog, Entry, Button, StringVar, Toplevel, Label, Frame
from tkinter.ttk import Combobox
from functools import partial
from PIL import ImageTk
import numpy as np

# Define the function you want to call when the filebrowser button is clicked.
def fileClick(clicked, dataset, segmentor):

	####### CODE REQUIRED (START) #######
	# This function should pop-up a dialog for the user to select an input image file.
	# Once the image is selected by the user, it should automatically get the corresponding outputs from the segmentor.
	# Hint: Call the segmentor from here, then compute the output images from using the `plot_visualization` function and save it as an image.
	# Once the output is computed it should be shown automatically based on choice the dropdown button is at.
	# To have a better clarity, please check out the sample video.

	global img
	try:
		str = filedialog.askopenfilename(defaultextension=".jpg", filetypes=[("All image files", "*.jpg *.jpeg *.png"), ("JPG image", "*.jpg"), ("PNG annotation", "*.png")], initialdir="./data/imgs", title="Select Image")
		img = Image.open(str)
	except IOError:
		status['text'] = "File not read! Please retry."
		return
	entry = StringVar(value=str)
	e['textvariable'] = entry
	src = np.asarray(img).transpose((2, 0, 1))/255
	pred_boxes, pred_masks, pred_class, pred_score = segmentor(src)
	plot_visualization(src, pred_masks[:3], pred_boxes[:3], pred_class[:3], './output/')
	print("Image uploaded! You can process now.")
	status['text'] = "Image uploaded! You can process now."
	process(clicked)
	####### CODE REQUIRED (END) #######

# `process` function definition starts from here.
# will process the output when clicked.
def process(clicked):

	####### CODE REQUIRED (START) #######
	# Should show the corresponding segmentation or bounding boxes over the input image wrt the choice provided.
	# Note: this function will just show the output, which should have been already computed in the `fileClick` function above.
	# Note: also you should handle the case if the user clicks on the `Process` button without selecting any image file.

	try:
		img
	except:
		print("File not selected! Choose an image to process")
		status['text'] = "Image not uploaded! Please upload an image first."
		return
	else:
		file = {"Segmentation":'masked_result', "Bounding-box":'bbox_result', "Segmentation + Bounding-box":'complete'}
		panel = Frame(root)
		panel.grid(row=1, column=0, columnspan=4)
		global img1, img2
		img1 = ImageTk.PhotoImage(img)
		img2 = ImageTk.PhotoImage(Image.open('./output/'+file[clicked.get()]+'.jpg'))
		p1 = Label(panel, image= img1, padx=4, pady=4)
		p1.grid(row=0, column=0)
		p2 = Label(panel, image= img2, padx=4, pady=4)
		p2.grid(row=0, column=3)
	####### CODE REQUIRED (END) #######

# `main` function definition starts from here.
if __name__ == '__main__':

	####### CODE REQUIRED (START) ####### (2 lines)
	# Instantiate the root window.
	# Provide a title to the root window.

	root = Tk()
	root.title("Image identifier model")
	status = Label(root, pady=5,text='Status will be displayed here')
	status.grid(row=2, column=0, columnspan=4)

	####### CODE REQUIRED (END) #######

	# Setting up the segmentor model.
	annotation_file = './data/annotations.jsonl'
	transforms = []

	# Instantiate the segmentor model.
	segmentor = InstanceSegmentationModel()
	# Instantiate the dataset.
	dataset = Dataset(annotation_file, transforms=transforms)

	# Declare the options.
	options = ["Segmentation", "Bounding-box", "Segmentation + Bounding-box"]
	clicked = StringVar()
	clicked.set(options[2])

	e = Entry(root, width=72, state='disabled')
	e.grid(row=0, column=0)

	####### CODE REQUIRED (START) #######
	# Declare the file browsing button
	source = Button(root, text= "Choose image", command= lambda: fileClick(clicked, dataset, segmentor))
	source.grid(row=0, column=1)
	####### CODE REQUIRED (END) #######

	####### CODE REQUIRED (START) #######
	# Declare the drop-down button
	list = Combobox(root, textvariable= clicked, state= 'readonly', values= options, width=27).grid(row=0, column=2)
	####### CODE REQUIRED (END) #######

	# This is a `Process` button, check out the sample video to know about its functionality
	myButton = Button(root, text="Process", command=partial(process, clicked))
	myButton.grid(row=0, column=3)

	####### CODE REQUIRED (START) ####### (1 line)
	# Execute with mainloop()
	root.mainloop()
	####### CODE REQUIRED (END) #######


from contextlib import redirect_stdout
import os
from main import *

# Tabu Search function
def tabu_search(items, bin_capacity, max_iterations, tabu_size):
    current_solution = random.sample(items, len(items))
    current_bins = solver_function(current_solution, bin_capacity)
    current_goal = goal_function(current_bins)

    best_bins = current_bins.copy()
    best_goal = current_goal

    tabu_list = []
    iteration = 0

    while iteration < max_iterations:

        neighborhood = generate_neighborhood(current_solution)

        # Collect neighborhood goals
        neighborhood_goals = []
        for neighbor in neighborhood:
            neighbor_bins = solver_function(neighbor, bin_capacity)
            neighbor_goal = goal_function(neighbor_bins)
            neighborhood_goals.append(neighbor_goal)

        # Check goals if are in tabu list
        best_move_index = -1
        best_move_goal = 0
        for i in range(len(neighborhood_goals)):
            if neighborhood_goals[i] < best_move_goal and neighborhood[i] not in tabu_list:
                best_move_index = i
                best_move_goal = neighborhood_goals[i]

        # Update the current solution and better solution
        if best_move_index != -1:
            current_solution = neighborhood[best_move_index]
            current_bins = solver_function(current_solution, bin_capacity)
            current_goal = goal_function(current_bins)

            if current_goal < best_goal:
                best_bins = current_bins.copy()
                best_goal = current_goal

            # Add the current move to the tabu list
            tabu_list.append(neighborhood[best_move_index])
            if len(tabu_list) > tabu_size:
                tabu_list.pop(0)

        #print_solution(best_goal, iteration)
        iteration += 1

    return best_bins, best_goal

# # Solve using Tabu Search
# os. remove('results/ts_iter_bins.csv')
# with open('results/ts_iter_bins.csv', 'w') as f:
#     with redirect_stdout(f):
#         start_time = time.time()
#         tabu_search_solution, num_used_bins = tabu_search(items, bin_capacity, max_iterations, tabu_size)
#         elapsed_time = time.time() - start_time

# #os. remove('results/ts_time_bins.csv')
# with open('results/ts_time_bins.csv', 'w') as f:
#     with redirect_stdout(f):
#         start_time = time.time()
#         tabu_search_solution, num_used_bins = tabu_search(items, bin_capacity, max_iterations, tabu_size)
#         elapsed_time = time.time() - start_time
#         print(num_used_bins, elapsed_time)

# print("Taboo Search Time:", elapsed_time, "seconds")
# print("Taboo Search Solution:", tabu_search_solution)
# print("Taboo Search Used bins:", num_used_bins,"\n")

# Time and used  bins for experiments
start_time = time.time()
tabu_search_solution, num_used_bins = tabu_search(items, bin_capacity, max_iterations, tabu_size)
elapsed_time = time.time() - start_time
print(num_used_bins, elapsed_time)


# test functions available in expressions
import pathlib
import pytest
import sys
from _pytest.capture import CaptureFixture
from contextlib import asynccontextmanager
from neuro_sdk import Client
from re_assert import Matches
from typing import AbstractSet, Any, AsyncIterator, List, Mapping, Optional
from typing_extensions import Protocol
from yarl import URL

from neuro_flow.context import (
    FlowCtx,
    GitCtx,
    LiveContext,
    ProjectCtx,
    TagsCtx,
    VolumeCtx,
    VolumesCtx,
)
from neuro_flow.expr import (
    EvalError,
    PrimitiveExpr,
    RootABC,
    SequenceExpr,
    StrExpr,
    TypeT,
)
from neuro_flow.tokenizer import Pos
from neuro_flow.types import LocalPath, RemotePath

POS = Pos(0, 0, LocalPath(__file__))

class Root(RootABC):
    def __init__(
        self, mapping: Mapping[str, TypeT], client: Client, dry_run: bool = False
    ) -> None:
        self._mapping = mapping
        self._client = client
        self._dry_run = dry_run

    def lookup(self, name: str) -> TypeT:
        return self._mapping[name]

    @asynccontextmanager
    async def client(self) -> AsyncIterator[Client]:
        yield self._client

    @property
    def dry_run(self) -> bool:
        return self._dry_run

async def test_len(client: Client) -> None:
    expr = StrExpr(POS, POS, "${{ len('abc') }}")
    ret = await expr.eval(Root({}, client))
    assert ret == "3"

@pytest.mark.parametrize(
    "pattern,result",
    [
        ("'just string'", "just string"),
        ("True", "True"),
        ("222", "222"),
        ("22.22", "22.22"),
        ("[1, 2, 3]", "[1, 2, 3]"),
    ],
)
async def test_str(client: Client, pattern: str, result: str) -> None:
    expr = StrExpr(POS, POS, "${{ str(" + pattern + ") }}")
    ret = await expr.eval(Root({}, client))
    assert ret == result

async def test_int(client: Client) -> None:
    expr = PrimitiveExpr(POS, POS, '${{ int("42") }}')
    ret = await expr.eval(Root({}, client))
    assert ret == 42

@pytest.mark.parametrize(
    "pattern,result",
    [
        ("5", [0, 1, 2, 3, 4]),
        ("1,4", [1, 2, 3]),
        ("1,6,2", [1, 3, 5]),
        ("5,1,-1", [5, 4, 3, 2]),
    ],
)
async def test_range(client: Client, pattern: str, result: List[int]) -> None:
    expr = SequenceExpr(POS, POS, "${{ range(" + pattern + ") }}", int)  # type: ignore
    ret = await expr.eval(Root({}, client))
    assert ret == result  # type: ignore

async def test_replace(client: Client) -> None:
    expr = StrExpr(POS, POS, "${{ replace('22.22', '.', '_') }}")
    ret = await expr.eval(Root({}, client))
    assert ret == "22_22"

async def test_join(client: Client) -> None:
    expr = StrExpr(POS, POS, "${{ join('_', ['x', 'y', 'z']) }}")
    ret = await expr.eval(Root({}, client))
    assert ret == "x_y_z"

async def test_keys(client: Client) -> None:
    expr = StrExpr(POS, POS, "${{ keys(dct) }}")
    ret = await expr.eval(Root({"dct": {"a": 1, "b": 2}}, client))
    assert ret == "['a', 'b']"

async def test_values(client: Client) -> None:
    expr = StrExpr(POS, POS, "${{ values(dct) }}")
    ret = await expr.eval(Root({"dct": {"a": 1, "b": 2}}, client))
    assert ret == "[1, 2]"

async def test_fmt(client: Client) -> None:
    expr = StrExpr(POS, POS, "${{ fmt('{} {}', 1, 'a') }}")
    ret = await expr.eval(Root({}, client))
    assert ret == "1 a"

async def test_hash_files(client: Client) -> None:
    expr = StrExpr(POS, POS, "${{ hash_files('Dockerfile', 'requirements/*.txt') }}")
    folder = LocalPath(__file__).parent / "hash_files"
    ret = await expr.eval(Root({"flow": {"workspace": folder}}, client))
    assert ret == "081fde04651e1184890a0470501bff3db8e0014260224e07acf5688e70e0edbe"

async def test_lower(client: Client) -> None:
    expr = StrExpr(POS, POS, "${{ lower('aBcDeF') }}")
    ret = await expr.eval(Root({}, client))
    assert ret == "abcdef"

async def test_upper(client: Client) -> None:
    expr = StrExpr(POS, POS, "${{ upper('aBcDeF') }}")
    ret = await expr.eval(Root({}, client))
    assert ret == "ABCDEF"

async def test_parse_volume_id(client: Client) -> None:
    expr = StrExpr(POS, POS, "${{ parse_volume('storage:path/to:/mnt/path:rw').id }}")
    ret = await expr.eval(Root({}, client))
    assert ret == "<volume>"

async def test_parse_volume_remote(client: Client) -> None:
    expr = StrExpr(
        POS, POS, "${{ parse_volume('storage:path/to:/mnt/path:rw').remote }}"
    )
    ret = await expr.eval(Root({}, client))
    assert Matches("storage:[^:]+/path/to") == ret

async def test_parse_volume_mount(client: Client) -> None:
    expr = StrExpr(
        POS, POS, "${{ parse_volume('storage:path/to:/mnt/path:rw').mount }}"
    )
    ret = await expr.eval(Root({}, client))
    assert ret == "/mnt/path"

async def test_parse_volume_read_only(client: Client) -> None:
    expr = StrExpr(
        POS, POS, "${{ parse_volume('storage:path/to:/mnt/path:rw').read_only }}"
    )
    ret = await expr.eval(Root({}, client))
    assert ret == "False"

async def test_parse_volume_local(client: Client) -> None:
    expr = StrExpr(
        POS, POS, "${{ parse_volume('storage:path/to:/mnt/path:rw').local }}"
    )
    ret = await expr.eval(Root({}, client))
    assert ret == "None"

async def test_parse_volume_local_full(client: Client) -> None:
    expr = StrExpr(
        POS, POS, "${{ parse_volume('storage:path/to:/mnt/path:rw').full_local_path }}"
    )
    ret = await expr.eval(Root({}, client))
    assert ret == "None"

class LiveContextFactory(Protocol):
    def __call__(
        self,
        client: Client,
        tags: TagsCtx = frozenset(),
        dry_run: bool = False,
        volumes: Optional[VolumesCtx] = None,
    ) -> LiveContext:
        ...

@pytest.fixture
async def live_context_factory(assets: pathlib.Path) -> LiveContextFactory:
    def _factory(
        client: Client,
        tags: TagsCtx = frozenset(),
        dry_run: bool = False,
        volumes: Optional[VolumesCtx] = None,
    ) -> LiveContext:
        return LiveContext(
            _client=client,
            _dry_run=dry_run,
            project=ProjectCtx(
                id="test",
                project_name=client.config.project_name_or_raise,
                owner=None,
                role=None,
            ),
            flow=FlowCtx(
                flow_id="live",
                project_id="test",
                workspace=assets,
                title="unit test flow",
            ),
            git=GitCtx(None),
            env={},
            images={},
            volumes=volumes or {},
            tags=tags,
        )

    return _factory

async def test_inspect_job_bad_context(client: Client) -> None:
    expr = StrExpr(POS, POS, "${{ inspect_job(22) }}")
    with pytest.raises(
        EvalError, match=r"inspect_job\(\) is only available inside a job definition"
    ):
        await expr.eval(Root({}, client))

async def test_inspect_job_bad_first_arg(
    client: Client, live_context_factory: LiveContextFactory
) -> None:
    expr = StrExpr(POS, POS, "${{ inspect_job(22) }}")
    ctx = live_context_factory(client, set())
    with pytest.raises(
        EvalError, match=r"inspect_job\(\) job_name argument should be a str, got 22"
    ):
        await expr.eval(ctx)

async def test_inspect_job_bad_second_arg(
    client: Client, live_context_factory: LiveContextFactory
) -> None:
    expr = StrExpr(POS, POS, "${{ inspect_job('foo', 22) }}")
    ctx = live_context_factory(client, set())
    with pytest.raises(
        EvalError, match=r"inspect_job\(\) suffix argument should be a str, got 22"
    ):
        await expr.eval(ctx)

async def test_inspect_job_correct_set_of_tags(
    client: Client, live_context_factory: LiveContextFactory
) -> None:
    called = False

    async def fake_list(
        *args: Any, tags: AbstractSet[str], **kwargs: Any
    ) -> AsyncIterator[Any]:
        nonlocal called
        called = True
        assert tags == {"test_tag", "job:foo"}
        yield {"id": "test_id"}

    client.jobs.list = fake_list  # type: ignore

    expr = StrExpr(POS, POS, "${{ inspect_job('foo').id }}")

    ctx = live_context_factory(client, {"test_tag"})
    result = await expr.eval(ctx)
    assert result == "test_id"
    assert called

async def test_inspect_job_correct_set_of_tags_multi(
    client: Client, live_context_factory: LiveContextFactory
) -> None:
    called = False

    async def fake_list(
        *args: Any, tags: AbstractSet[str], **kwargs: Any
    ) -> AsyncIterator[Any]:
        nonlocal called
        called = True
        assert tags == {"test_tag", "job:foo", "multi:bar"}
        yield {"id": "test_id"}

    client.jobs.list = fake_list  # type: ignore

    expr = StrExpr(POS, POS, "${{ inspect_job('foo', 'bar').id }}")

    ctx = live_context_factory(client, {"test_tag"})
    result = await expr.eval(ctx)
    assert result == "test_id"
    assert called

async def test_inspect_job_no_jobs_errors(
    client: Client, live_context_factory: LiveContextFactory
) -> None:
    async def fake_list(*args: Any, **kwargs: Any) -> AsyncIterator[Any]:
        # make it async iterator:
        for _ in range(0):
            yield None

    client.jobs.list = fake_list  # type: ignore

    expr = StrExpr(POS, POS, "${{ inspect_job('foo') }}")
    expr_with_suffix = StrExpr(POS, POS, "${{ inspect_job('foo', 'bar') }}")

    ctx = live_context_factory(client, set())
    with pytest.raises(
        EvalError, match=r"inspect_job\(\) did not found running job with name foo"
    ):
        await expr.eval(ctx)

    with pytest.raises(
        EvalError,
        match=r"inspect_job\(\) did not found running job with name foo"
        r" and suffix bar",
    ):
        await expr_with_suffix.eval(ctx)

async def test_upload_dry_run_mode_prints_commands(
    client: Client,
    live_context_factory: LiveContextFactory,
    capsys: CaptureFixture[str],
) -> None:
    expr = StrExpr(
        POS,
        POS,
        "${{ upload(volumes.test) }}",
    )
    ctx = live_context_factory(
        client,
        set(),
        dry_run=True,
        volumes={
            "test": VolumeCtx(
                id="test",
                full_local_path=LocalPath("/test/local"),
                local=LocalPath("local"),
                remote=URL("storage://cluster/user/somedir"),
                read_only=False,
                mount=RemotePath("/mnt"),
            )
        },
    )
    await expr.eval(ctx)
    capture = capsys.readouterr()
    assert "neuro mkdir --parents storage://cluster/user\n" in capture.out
    if sys.platform == "win32":
        assert (
            "neuro cp --recursive --update --no-target-directory"
            " '\\test\\local' storage://cluster/user/somedir\n" in capture.out
        )
    else:
        assert (
            "neuro cp --recursive --update --no-target-directory"
            " /test/local storage://cluster/user/somedir\n" in capture.out
        )


def one():
    a1 = 0
    b1 = 0
    c1 = 1
    for i in range(1,4):
        print(i,"число :")
        a1 = int(input())
        b1 += a1
        c1 *= a1
    print("++ = ", b1)
    print("** = ", c1)

def two():
    a2 = int(input("zp : "))
    b2 = int(input("kr : "))
    c2 = int(input("kom : "))
    print(a2 - (b2 + c2))

def tree():
    a3 = int(input("1 : "))
    b3 = int(input("2 : "))
    print(0.5 * a3 * b3)

def four():
    print("To be \nor not \nto be")

def five():
    print("“Life is what happens \n","  ","when \n\tyoure busy making other plans”\n\t\t\t\tJohn Lennon.")

def main():
    one()
    two()
    tree()
    four()
    five()

main()


from time import perf_counter
import pathlib
from collections import defaultdict

ROOT_DIR = pathlib.Path(__file__).parent.parent
input_file = ROOT_DIR / '2021/input/13.txt'

t1_start = perf_counter()

# fetch data
input_data = [line.strip() for line in open(input_file).readlines()]

fold_instructions_from = input_data.index('')

coords = set()
for r in input_data[:fold_instructions_from]:
    x, y = r.split(',')
    coords.add((int(x), int(y)))

fold_instructions = []
for r in input_data[fold_instructions_from + 1:]:
    _, _, fold = r.split()
    direction, step = fold.split('=')
    fold_instructions.append((direction, int(step)))

def fold_paper(fold):
    # filter out set after folding
    if fold[0] == 'y':
        move_x = 0
        move_y = fold[1]
        filter_expr = [c for c in coords if c[1] > move_y]
    else:
        move_x = fold[1]
        move_y = 0
        filter_expr = [c for c in coords if c[0] > move_x]
    for coord in filter_expr:
        _x, _y = coord  # current x, y position
        x = _x - (_x - move_x) * 2 if move_x > 0 else _x
        y = _y - (_y - move_y) * 2 if move_y > 0 else _y
        coords.discard(coord)

        if x >= 0 and y >= 0:
            coords.add((x, y))

# solve A
fold_paper(fold_instructions[0])
print(f'Answer A:{len(coords)}')

# continue to fold and solve B
for fold in fold_instructions[1:]:
    fold_paper(fold)

# create matrix to se letters
matrix = []
for row in range(max(c[1] for c in coords)+1):
    _row = []
    for col in range(max(c[0] for c in coords)+1):
        _row.append('#' if (col, row) in coords else ' ')
    matrix.append(_row)
print()
print('Answer for B:')
# LGHEGUEJ

for r in matrix:
    print(''.join(r))

print()

t1_stop = perf_counter()
print(f'Elapsed time during the whole program in seconds: {t1_stop-t1_start}')


import os

import csv

csvpath = os.path.join('..', 'Resources', 'election_data.csv')

with open(csvpath, newline='') as csvfile:

    csvreader = csv.reader(csvfile, delimiter=',')

    header=next(csvreader)

    total_vote=0
    county=[]
    candidate=[]
    candidate_total_vote=[]
    percent_vote=[]

    for i in csvreader:
        #Counts total votes
        total_vote+=1

        #Appends candidate names into empty list (cadidate)
        if i[2] not in candidate:
            candidate.append(i[2])
            candidate_total_vote.append(1)
        else:
            candidate_total_vote[candidate.index(i[2])]+=1

    print(candidate_total_vote)


#bracket_quinella.py - 枠連を表示するアプリ

import random as rd #ランダムに3つ選ぶのに使用

def bracket_quinella(number_of_starters): #リストを渡してください
    #頭数が１～８のとき
    if len(number_of_starters) < 9:
        txt = '頭数が少なすぎます。'
    #頭数が９～１５のとき
    else :
        lst = [1, 2, 3, 4, 5, 6, 7, 8]
        e = rd.choices(lst, k=2) #listsから３つランダムで選ぶ
        txt = f'{e[0]}-{e[1]}' #表示するテキストを作る
    return txt


class Solution:
    def arrayChange(self, nums: List[int], operations: List[List[int]]) -> List[int]:
        mp = {x:i for i, x in enumerate(nums)}

        for a, b in operations:
            currIndex = mp[a]
            nums[currIndex] = b
            mp[b] = currIndex

        return nums


import falcon
from Api.api_tools import ApiTools
from Database.db_handler import Database

HOST = 'localhost'
PORT = 27017
DB_NAME = 'sika-messenger'

class Authorize:

    """
    This class is a hook object for api routes. In __call__ method
    it checks whether the desired user has authorization or not.
    For instance, is user owner or admin of a group or channel
    or not.

    if he/she is owner then the req.is_owner becomes true, otherwise
    req.is_owner is false(he/she is admins). And if he/she is not admin
    it will raise error to prevent running further codes.

    """

    async def __call__(self, req, res, resource, params) -> None:

        req.body_data = ApiTools.prepare_body_data(await req.stream.read())
        print(req.body_data)
        collection_name = str(resource).lower()
        try:
            with Database(HOST, PORT, DB_NAME, collection_name) as db:
                db: Database
                room = db.get_record({"_id": req.body_data["room_id"]})

            user_id = req.user["_id"]

            if user_id == room["owner"]["_id"]:
                req.is_owner = True
                req.room = room
                return

            elif user_id in room["admins"]:
                req.is_owner = False
                req.room = room

            else:
                raise falcon.HTTPNotFound(
                    title="error",
                    description="User have no authorization for this action.")
        except (KeyError, TypeError) as e:
            raise falcon.HTTPBadRequest(
                title="error",
                description="Invalid data."
            )


import re

from django.db import models
from django.utils.safestring import mark_safe
from mptt.models import MPTTModel, TreeForeignKey, TreeManyToManyField

# в боковом меню django-admin индентация пробелами и табами не работает (но при этом влияет на порядок пукнктов меню)
menu_indent = "   "

"""___________________________МОДЕЛИ КАТЕГОРИЙ___________________________"""

class OutgoingType(models.Model):
    name = models.CharField(max_length=64, unique=True)

    def __str__(self):
        return self.name

    class Meta:
        verbose_name = 'Тип исходящего письма'
        verbose_name_plural = 'Типы исходящих писем'

class WayOfDelivery(models.Model):
    """Способ передачи оригинала письма (почта, курьер, лично)"""
    name = models.CharField(max_length=64, unique=True)

    def __str__(self):
        return self.name

    class Meta:
        verbose_name = 'Способ отправки'
        verbose_name_plural = 'Способы отправки'

class Executor(models.Model):
    """Исполнитель внутри нашей организации"""
    surname = models.CharField(max_length=64, verbose_name='Фамилия')
    name = models.CharField(max_length=64, verbose_name='Имя')
    patronimic = models.CharField(max_length=64, verbose_name='Отчество')

    def __str__(self):
        n = str(self.name)[0].upper() if str(self.name) else ''
        p = str(self.patronimic)[0].upper() if str(self.patronimic) else ''
        return f"{self.surname} {n}.{p}."

    class Meta:
        verbose_name = 'Подписано/Исполнитель'
        verbose_name_plural = 'Подписано/Исполнители'
        ordering = ('surname', 'name')

class CadNum(models.Model):
    """Кадастровый номер"""
    name = models.CharField(max_length=255, verbose_name='Название', unique=True)

    def __str__(self):
        return self.name

    class Meta:
        verbose_name = 'Кадастровый номер'
        verbose_name_plural = 'Кадастровые номера'

class BaseHierarchicalProperty(MPTTModel):
    """Абстрактный класс для создания иерархически вложенных атрибутов писем"""
    name = models.CharField(max_length=255, verbose_name='Название')
    parent = TreeForeignKey('self', on_delete=models.CASCADE, null=True, blank=True, related_name='children', verbose_name='Относится к категории')

    def __str__(self):
        if self.parent:
            return f"{str(self.parent)} ⊳ {self.name}"
        return self.name

    class Meta:
        abstract = True

class GeoTag(BaseHierarchicalProperty):
    """Георафические объекты. Могут быть вложены один в другой.
    Например: 'Краснодарский край', 'Абинский р-н', 'Нефтегорское г.п.' """
    class Meta:
        verbose_name = 'Географическая привязка'
        verbose_name_plural = 'Географическая привязка'

    def get_extension_url(self):
        url = f"/admin/letters/geotag/{self.pk}"
        return url

    def get_link_name(self):
        return mark_safe(f"{self.name}")

    get_link_name.short_description = ''

class Thematics(BaseHierarchicalProperty):
    """Произвольная тематика, которую можно задать для письма. Могут быть древовидно вложены одна в другую.
    Пример: 'Нарушения в Лесном фонде' <- 'Незаконные вырубки' <- 'Вырубка в Шабановском лесничестве' """
    class Meta:
        verbose_name = 'Тематика'
        verbose_name_plural = ' Тематики'

    def get_extension_url(self):
        url = f"/admin/letters/thematics/{self.pk}"
        return url

    def get_link_name(self):
        return mark_safe(f"{self.name}")

    get_link_name.short_description = ''

class Forestry(BaseHierarchicalProperty):
    """Объекты лесного фонда. Могут быть иерархически вложены друг в друга."""
    class Meta:
        verbose_name = 'Объект Лесного Фонда'
        verbose_name_plural = 'Объекты Лесного Фонда'

    def get_extension_url(self):
        url = f"/admin/letters/forestry/{self.pk}"
        return url

    def get_link_name(self):
        return mark_safe(f"{self.name}")

    get_link_name.short_description = ''

class WaterObj(BaseHierarchicalProperty):
    """Водные объекты. Могут быть иерархически вложены друг в друга."""
    class Meta:
        verbose_name = 'Водный объект'
        verbose_name_plural = 'Водные объекты'

    def get_extension_url(self):
        url = f"/admin/letters/waterobj/{self.pk}"
        return url

    def get_link_name(self):
        return mark_safe(f"{self.name}")

    get_link_name.short_description = ''

"""___________________________МОДЕЛИ КОНТРАГЕНТОВ___________________________"""

class CounterpartyType(models.Model):
    """Категория для типов контрагента. Варианты: Организация, Должность, Лицо"""
    index = models.IntegerField(primary_key=True)
    name = models.CharField(max_length=127)
    mini = models.CharField(max_length=16, blank=True)
    url = models.CharField(max_length=127)

    def __str__(self):
        return self.name

    class Meta:
        verbose_name = 'Тип контрагента'
        verbose_name_plural = 'Типы контрагентов'

class Counterparty(BaseHierarchicalProperty):
    """Базовая модель контрагента. Контрагенты предполагают вложенность Лицо > Должность > Организация"""
    type = models.ForeignKey('CounterpartyType', default=3, on_delete=models.CASCADE, blank=True, null=True, )
    name = models.CharField(max_length=255, verbose_name='')
    parent = TreeForeignKey('self', on_delete=models.CASCADE, null=True, blank=True, related_name='children', verbose_name='Относится к категории')
    prev_org = TreeForeignKey('Organization', on_delete=models.CASCADE, null=True, blank=True, related_name='renamed', verbose_name='Предыдущее название организации')
    prev_pos = TreeForeignKey('Person', on_delete=models.CASCADE, null=True, blank=True, related_name='relocated', verbose_name='Предыдущая позиция')

    def get_full_name(self):
        if self.parent:
            return f"{self.name} ❱ {self.parent.get_full_name()}"
        if str(self.type) == "Лицо":
            return f"🔥 {self.name}"
        return f"{self.name}"

    def get_list_name(self):
        return f"{self.type.mini} {self.get_full_name()}"

    get_list_name.short_description = 'Контрагенты'

    def __str__(self):
        return self.get_list_name()

    def get_extension_url(self):
        url = f"/admin/letters/{self.type.url}/{self.pk}"
        return url

    def get_link_name(self):
        return mark_safe(f"{self.name}")

    get_link_name.short_description = ''

    class Meta:
        verbose_name = 'Контрагент'
        verbose_name_plural = '      Контрагенты'

    class MPTTMeta:
        order_insertion_by = ('name',)

class Organization(Counterparty):
    """Модель для контрагентов уровня Организация"""
    class Meta:
        proxy = True
        verbose_name = 'организацию'
        verbose_name_plural = f'     {menu_indent}🏦 Организации'
        # ordering = ('name',)

    def save(self, *args, **kwargs):
        self.type = CounterpartyType.objects.get(pk=1)
        super(Organization, self).save()
        if re.findall(r'Прокуратура', self.name, flags=re.I):
            Position.objects.create(name='Прокурор', parent=self)
            Position.objects.create(name='И.О. прокурора', parent=self)
            Position.objects.create(name='1й зам. прокурора', parent=self)
            Position.objects.create(name='2й зам. прокурора', parent=self)

class Position(Counterparty):
    """Модель для контрагентов уровня Должность"""
    class Meta:
        proxy = True
        verbose_name = 'должность'
        verbose_name_plural = f'    {menu_indent}💼 Должности'
        # ordering = ('name',)

    def save(self, *args, **kwargs):
        self.type = CounterpartyType.objects.get(pk=2)
        super(Position, self).save()

    def __str__(self):
        return f"{self.name} ({self.parent.name})"

    # get_full_name.short_description = 'Должностные позиции'

class Person(Counterparty):
    """Модель для контрагентов уровня Лицо"""
    class Meta:
        proxy = True
        verbose_name = 'должностное лицо'
        verbose_name_plural = f'   {menu_indent}👤 Лица'
        # ordering = ('name',)

    def save(self, *args, **kwargs):
        self.type = CounterpartyType.objects.get(pk=3)
        super(Person, self).save()

    def __str__(self):
        return self.get_full_name()

"""___________________________МОДЕЛИ ПИСЕМ___________________________"""

def get_upload_path(instance, filename):
    """Формирует путь для сохранения файла скана письма, исходя из года письма и имени подкалогда для данного типа писем"""
    return f"{instance.sign_date.year}/{instance.type.folder}/{filename}"

class BaseLetter(MPTTModel):
    """Модель, содержащая все виды полей, которые встречаются во всех типы писем. Необходима для того, чтобы разные типы
    писем можно было свободно использовать как узлы дерева переписки (библиотека mptt). Отображаемая форма в админке зависит от
    значения поля type (для входящих - одна форма, для исходящих - другая, для редиректов - третья и т.п."""
    type = models.ForeignKey('LetterType', on_delete=models.CASCADE, blank=True, null=True, )
    out_type = models.ForeignKey('OutgoingType', on_delete=models.PROTECT, blank=True, null=True, default=1)
    parent = TreeForeignKey('self', on_delete=models.CASCADE, null=True, blank=True, related_name='children', verbose_name='Ответ на')
    number = models.CharField(max_length=64, unique=True, verbose_name='Номер')
    counterparty = TreeForeignKey('Counterparty', on_delete=models.CASCADE, verbose_name='Контрагент')
    subj = models.TextField(null=True, blank=True, verbose_name='Тема письма')
    sign_date = models.DateField(verbose_name='Дата письма')
    way_of_delivery = models.ForeignKey('WayOfDelivery', blank=True, null=True, on_delete=models.CASCADE, verbose_name='Способ отправки')

    executor = models.ManyToManyField('Executor', blank=True, verbose_name='Подписано/Исполнитель')
    inbound_number = models.CharField(max_length=128, blank=True, null=True, verbose_name='Входящий номер')
    outgoing_number = models.CharField(max_length=64, blank=True, null=True, verbose_name='Исходящий номер')
    signed_by = models.CharField(max_length=255, blank=True, null=True, verbose_name='Подписано')
    contact = models.CharField(max_length=255, blank=True, null=True, verbose_name='Исполнитель в госоргане')
    receive_date = models.DateField(blank=True, null=True, verbose_name='Дата получения')
    send_date = models.DateField(blank=True, null=True, verbose_name='Дата отправки')

    thematics = TreeManyToManyField('Thematics', blank=True, verbose_name='Тема')
    geotag = TreeManyToManyField('GeoTag', blank=True, verbose_name='Географическая привязка')
    cad_num = models.ManyToManyField('CadNum', blank=True, verbose_name='Кадастровые Номера',)
    forestry = TreeManyToManyField('Forestry', blank=True, verbose_name='Объект Лесного Фонда')
    waterobj = TreeManyToManyField('WaterObj', blank=True, verbose_name='Водный объект')
    cipher = models.CharField(max_length=255, blank=True, null=True, verbose_name='Идентификатор темы')

    tiff_file = models.FileField(blank=True, null=True, upload_to=get_upload_path, verbose_name='Файл TIFF')
    pdf_file = models.FileField(blank=True, null=True, upload_to=get_upload_path, verbose_name='Файл PDF')
    pagemaker_file = models.FileField(blank=True, null=True, upload_to=get_upload_path, verbose_name='Файл Pagemaker')

    completed = models.BooleanField(default=False, verbose_name='Завершено (применяется ко всей ветке переписки)')
    inaction = models.BooleanField(default=False, verbose_name='Бездействие')

    class Meta:
        verbose_name = 'Письмо'
        verbose_name_plural = '        Все письма'

    def get_full_name(self):
        if self.type:
            counterparty = self.counterparty.name[:50] if self.counterparty else ''
            counterparty = counterparty + ("..." if len(self.counterparty.name) > 50 else '')
            subject = self.subj[:80] if self.subj else ''
            subject = subject + ('...' if len(subject) > 80 else '')
            return f"{'📌 ' if self.inaction else ''}{self.type.abbr} {self.number} ❱ {self.sign_date} ❱ {counterparty} ❱ {subject}"
        return self.number

    get_full_name.short_description = 'Письма'

    def __str__(self):
        if self.type:
            return self.get_full_name()
        return self.number

    def get_extension_url(self):
        url = f"/admin/letters/{self.type.url}/{self.pk}"
        return url

    def get_link_name(self):
        return mark_safe(f"{self.get_full_name()}")

    class MPTTMeta:
        order_insertion_by = ['-sign_date']

    def save(self, *args, recurse=True, **kwargs):
        """ Применяет некоторые настройки ко всей ветке писем"""
        super(BaseLetter, self).save()
        if recurse:
            family = BaseLetter.objects.get(pk=self.pk).get_family()
            for relative in family:
                if relative.pk != self.pk:
                    if relative.completed != self.completed:
                        relative.completed = self.completed
                    if self.out_type:
                        relative.out_type = OutgoingType.objects.get(pk=self.out_type_id)
                    relative.save(recurse=False)

class OutEcoLetter(BaseLetter):
    """Модель для ИСХОДЯЩИХ писем"""
    class Meta:
        proxy = True
        verbose_name = 'Исходящее письмо'
        verbose_name_plural = f'       {menu_indent}📨 Исходящие'  # отступ в начале строки в админке не отображается, но влияет на положение пункта при сортировке.

    def save(self, *args, **kwargs):
        self.type = LetterType.objects.get(pk=2)
        super(OutEcoLetter, self).save()

class IncomingLetter(BaseLetter):
    """Модель для ВХОДЯЩИХ писем"""
    class Meta:
        proxy = True
        verbose_name = 'Входящее письмо'
        verbose_name_plural = f'       {menu_indent}📩 Входящие'  # отступ в начале строки в админке не отображается, но влияет на положение пункта при сортировке.

    def save(self, *args, **kwargs):
        self.type = LetterType.objects.get(pk=1)
        if self.parent:  # TODO надо, наверное, данный функционал полностью засунуть в BaseLetter
            if self.parent.out_type:
                self.out_type = OutgoingType.objects.get(pk=self.parent.out_type_id)
        super(IncomingLetter, self).save()

class OmittedRedirect(BaseLetter):
    """Случай, когда контрагент не отвечая на письмо пересылает его другому контрагенту (высясняется обычно после того,
     как приходит ответ от второго контрагента."""
    class Meta:
        proxy = True
        verbose_name = 'Неприсланный пересыл'
        verbose_name_plural = f'       {menu_indent}🗰 Перенаправление'

    def save(self, *args, **kwargs):
        self.type = LetterType.objects.get(pk=3)
        if self.parent:
            if self.parent.out_type:
                self.out_type = OutgoingType.objects.get(pk=self.parent.out_type_id)
        super(IncomingLetter, self).save()

class LetterType(models.Model):
    index = models.IntegerField(primary_key=True)
    name = models.CharField(max_length=127)
    abbr = models.CharField(max_length=8)
    folder = models.CharField(default='TMP', max_length=127)
    url = models.CharField(max_length=127)

    def __str__(self):
        return self.name

    class Meta:
        verbose_name = 'Тип письма'
        verbose_name_plural = 'Типы писем'

class Attachment(models.Model):
    """Иногда к письму требуется приложить еще какой-либо произвольный документ"""
    description = models.TextField(blank=True, verbose_name='Описание')
    attached_to = models.ForeignKey('BaseLetter', on_delete=models.PROTECT, verbose_name='Письмо, к которому относится данное приложение')
    file = models.FileField(upload_to='ATTACHMENTS', verbose_name='Файл приложения')

    def __str__(self):
        return ''

    class Meta:
        verbose_name = 'Прикрепленный документ'
        verbose_name_plural = 'Прикрепленные документы'


__author__ = 'haussel'
"""
This module provides the following classes:
- BasicSpectrum: a class to represent one or more spectra
- SpectrumInterpolator: a class to perform various interpolation
- GalaxySpectrum : a class to represent galaxy spectra.
"""
import numpy as np
from astropy import units as u
from .photcurve import PhotCurve
from .phottools import is_flam, \
    is_fnu, is_flux, velc , nu_unit, lam_unit, flam_unit, fnu_unit, nufnu_unit
from .extinction import ExtinctionLaw
from .config import DEBUG

class BasicSpectrum(PhotCurve):
    """
    A class to represent spectra.

    Attributes
    ----------
    org_x_type : 'nu' or 'lam'
        original type of x input
    org_x_unit : astropy.units
        original unit of x input
    org_y_type : 'fnu' or 'flam'
        original type of y input
    org_y_unit : astropy.units
        original units of input
    x : astropy.units.Quantity 1D
        array of wavelength or frequencies in SI units
    x_si_unit: astropy.units
        unit of x
    is_lam: bool
        True if x is an array of wavelengths
    is_nu: bool
        True if x is an array of frequencies
    nb: int
        Number of spectra
    y: astropy.units.Quantity 1D [N] or 2D [nb, N] where N is the number of
       x points
       Spectra
    y_si_unit: astropy.units
        unit of y
    is_flam: bool
        True if y is a spectral irradiance per unit wavelength
    is_fnu: bool
        True if y  is a spectral irradiance per unit frequency
    yscale: float or ndarray
        scale factor applied to the spectrum
    xshift: float
        shift applied to the x array
    interpolation_method: str
        method to interpolate the spectrum. Can be:
            - nearest : nearest neighbor interpolation
            - linear : linear interpolation
            - quadratic : quadratic interpolation
            - log-log-linear : linear interpolation in log space
    can_extrapolate: bool
        if True, interpolation can extrapolate outside spectrum definition
        without raising an exception
    interpolation_set: bool
        True if the spectrum interpolator has been initialized
    interpolate: SpectrumInterpolator
        The object performing the interpolation

    Methods
    -------

    - set_interpolation(interpolation_method, extrapolate=False)
        Set the interpolation method for the spectrum
    - scale(factor)
        Multiply the spectra by factor(s).
    - unscale()
    - shift(factor)
        Multiply the x by factor
    - unshift()
        Remove any shift
    - nu(unit=None)
        Returns x as an array of frequencies
    - lam(unit=None)
        Returns x as an array of wavelengths
    - fnu(unit=None, ispec=None)
        Returns spectra as spectral irradiance per unit frequency, with the
        possibility to choose the unit and to only output one selected spectrum
    - flam(unit=None, ispec=None)
        Returns the spectrum in spectral irradiance per unit wavelength,
        with the possibility to choose the unit and to only output one
        selected spectrum
    - in_nu()
        Set the spectrum to 'nu' type.
    - in_lam()
        Set the spectrum to 'lam' type
    - in_flam()
        Set the spectrum to 'flam' type
    - in_fnu()
        Set the spectrum to 'fnu' type
    - fnu_nu(nu)
        Interpolate the spectrum in the form of Fnu at the requested
        frequencies. The spectrum is converted to 'nu', 'fnu' type
    - flam_lam(lam)
        Interpolate the spectrum in the form of Flam at the requested
        wavelengths. The spectrum is converted to 'lam', 'flam' type
    """
    def __init__(self, file=None, table=None, name_x=None, names_y=None,
                 x=None, x_unit=None,
                 y=None, y_type=None, y_unit=None,
                 header=None,
                 interpolation_method='log-log-linear',
                 extrapolate='no', positive=True):
        """
        Initialization. Valid calls are:

        - initialization from a Table:
        >>> import photometry as pt
        >>> spec = pt.BasicSpectrum(data=mydata)
        or specifying which columns to use
        >>> spec = pt.BasicSpectrum(data=mydata, name_x='colname',
                                    names_y=['colname1',...,'colnameN'])

        - initialization from quantities:
        >>> spec = pt.BasicSprectrum(x = my_x, y=my_y)
        - initialization from arrays
        >>> spec = pt.BasicSprectrum(x = my_x, x_type='my_x_type',
                                     x_unit=my_x_unit, y=my_y,
                                     y_type='my_y_type', y_unit=my_y_unit)

        Parameters
        ----------
        table: astropy.table.Table or numpy.ndarray
            Contains the x and y values
        name_x : str
            name of data column for the x values. If not provided, tries with
            the first column
        names_y: str or list of str
            name(s) of the columns containing the y values. If not provided,
            tries with all the remaining columns
        x : numpy.ndarray or astropy.Quantity
            values of x
        x_type : str 'lam' or 'nu'
            type of x
        x_unit : astropy.units or str
            unit of x
        y : numpy.ndarray or astropy.Quantity
            values of y
        y_type : str 'flam' or 'fnu'
            type of y
        y_unit : astropy.units or str
            unit of y
        interpolation_method: str
            interpolation method, can be 'nearest', 'linear', 'quadratic',
            'log-log-linear'. Defaulted to 'log-log-linear'
        extrapolate: str
            If 'yes', spectra can be interpolated outside of the x array
            bounds without raising an exception. Defaulted to 'no'.

        """
        super().__init__(file=file, x=x, y=y, table=table,
                         colname_x=name_x, colnames_y=names_y,
                         x_unit=x_unit, header=header,
                         interpolation=interpolation_method,
                         extrapolate=extrapolate, positive=positive,
                         delayed_setup=True)

        if not self.initialized:
            return
        # After the init from PhotCurve, the x part has been dealt with, and the
        # y has been ingested as is, with self.y containing the values
        # (without any scaling) and self.org_y_unit containing the unit if any.
        if self.org_y_unit is not None:
            # this is the case where y was a quantity
            if y_unit is not None:
                if y_unit is not self.org_y_unit:
                    raise ValueError('y ({}) and y_unit ({}) do not '
                                     'match'.format(self.org_y_unit, y_unit))
            if is_fnu(self.org_y_unit):
                if y_type is not None:
                    if y_type != 'fnu':
                        raise ValueError('incompatible `y_type`:{} and '
                                         '`y.unit`:{}'.format(y_type,
                                                              self.org_y_unit))
                self.is_fnu = True
                self.is_flam = False
                self.y_si_unit = fnu_unit
                self.org_y_type = 'fnu'
                self.y = self.y * self.org_y_unit.to(fnu_unit)
            elif is_flam(self.org_y_unit):
                if y_type is not None:
                    if y_type != 'flam':
                        raise ValueError('incompatible `y_type`:{} and '
                                         '`y.unit`:{}'.format(y_type,
                                                              self.org_y_unit))
                self.y_si_unit = flam_unit
                self.is_flam = True
                self.is_fnu = False
                self.org_y_type = 'flam'
                self.y = self.y * self.org_y_unit.to(flam_unit)
            elif is_flux(self.org_y_unit):
                if self.org_x_type == 'lam':
                    if y_type is not None:
                        if y_type != 'lamflam':
                            raise ValueError('incompatible `y_type`:{} and '
                                              '`y.unit`:{}'.format(y_type,
                                                                      y_unit))
                    self.org_y_type = 'lamflam'
                    self.y_si_unit = flam_unit
                    self.is_flam = True
                    self.is_fnu = False
                    self.y = ((self.y * self.org_y_unit).to(nufnu_unit)/
                              (self.x * self.x_si_unit)).value
                elif self.org_x_type == 'nu':
                    if y_type is not None:
                        if y_type != 'nufnu':
                            raise ValueError('incompatible `y_type`:{} and '
                                             '`y.unit`:{}'.
                                             format(y_type, self.org_y_unit))
                    self.org_y_type = 'nufnu'
                    self.y_si_unit = fnu_unit
                    self.is_flam = False
                    self.is_fnu = True
                    self.y = ((self.y * self.org_y_unit).to(nufnu_unit) /
                              (self.x * self.x_si_unit)).value
                else:
                    raise ValueError('invalid unit {} for input quantity '
                                     '`x`'.format(self.org_x_unit))
            else:
                raise ValueError('invalid unit {} for input quantity `y`'.
                                 format(self.org_y_unit))
        else:
            if y_unit is not None:
                if is_fnu(y_unit):
                    if y_type is not None:
                        if y_type != 'fnu':
                            raise ValueError('incompatible `y_type`:{} and '
                                             '`y.unit`:{}'.format(y_type,
                                                                  y_unit))
                    self.is_fnu = True
                    self.is_flam = False
                    self.y_si_unit = fnu_unit
                    self.org_y_type = 'fnu'
                    self.org_y_unit = y_unit
                    self.y = self.y * y_unit.to(fnu_unit)
                elif is_flam(y_unit):
                    if y_type is not None:
                        if y_type != 'flam':
                            raise ValueError('incompatible `y_type`:{} and '
                                             '`y.unit`:{}'.format(y_type,
                                                                  y_unit))
                    self.y_si_unit = flam_unit
                    self.is_flam = True
                    self.is_fnu = False
                    self.org_y_type = 'flam'
                    self.org_y_unit = y_unit
                    self.y = self.y * y_unit.to(flam_unit)
                elif is_flux(self.org_y_unit):
                    if self.org_x_type == 'lam':
                        if y_type is not None:
                            if y_type != 'lamflam':
                                raise ValueError('incompatible `y_type`:{} and '
                                                 '`y.unit`:{}'.format(y_type,
                                                                      y_unit))
                        self.org_y_type = 'lamflam'
                        self.org_y_unit = y_unit
                        self.y_si_unit = flam_unit
                        self.is_flam = True
                        self.is_fnu = False
                        self.y = ((self.y * self.org_y_unit).to(nufnu_unit) /
                                  (self.x * self.x_si_unit)).value
                    elif self.org_x_type == 'nu':
                        if y_type is not None:
                            if y_type != 'nufnu':
                                raise ValueError('incompatible `y_type`:{} and '
                                                 '`y.unit`:{}'.format(y_type,
                                                                      y_unit))
                        self.org_y_type = 'nufnu'
                        self.org_y_unit = y_unit
                        self.y_si_unit = fnu_unit
                        self.is_flam = False
                        self.is_fnu = True
                        self.y = ((self.y * self.org_y_unit).to(nufnu_unit) /
                                  (self.x * self.x_si_unit)).value
                    else:
                        raise ValueError('invalid unit {} for input quantity '
                                         '`x`'.format(self.org_x_unit))
                else:
                    raise ValueError('invalid unit {} for input quantity `y`'.
                                     format(self.org_y_unit))
            else:
                raise ValueError("'y' has no units")
        self.interpolate_set = self.set_interpolation(
                interpolation_method, extrapolate=extrapolate,
                positive=positive)
        self.yfactor = np.ones(self.nb)
        self.xshift = 1.0
        self.Av = np.zeros(self.nb)
        self.extinction = None

    def __getitem__(self, item):
        return BasicSpectrum(x=self.x * self.x_si_unit,
                             y=self.y[item,:] * self.y_si_unit,
                             interpolation_method=self.interpolate_method,
                             extrapolate=self.extrapolate,
                             positive=self.positive)

    def set_extinction(self, extobj, Rv=None):
        """

        :param extobj:
        :return:
        """
        if isinstance(extobj, ExtinctionLaw):
            self.extinction = extobj
            self.extinction.set_curve(self.x * self.x_si_unit)
            if Rv is not None:
                self.extinction.set_R_V(Rv)

    def apply_galactic_extinction(self, Av):
        """
        Apply extinction
        :param Av:
        :return:
        """
        if self.extinction is not None:
            if self.extinction.ready:
                oldfactor = self.extinction.compute_extinction(self.x *
                                                               self.x_si_unit,
                                                               self.Av)
            else:
                oldfactor = 1.
            newfactor = self.extinction.compute_extinction(self.x *
                                                           self.x_si_unit, Av)
            if DEBUG:
                print('np.any(np.isfinite(oldfactor))={}'.format(np.any(
                    np.isfinite(
                oldfactor))))
                print('np.any(np.isfinite(newfactor))={}'.format(np.any(
                    np.isfinite(newfactor))))
                print('self.y.shape={}'.format(self.y.shape))
            self.y *= newfactor/oldfactor
            self.Av = Av

    def fnu(self, unit=None, ispec=None):
        """
        returns the spectrum in spectral irradiance per unit frequency

        if the unit is not given, the spectrum is returned in fnu_unit (i.e
        in W/m**2/Hz) but without unit (ndarray)

        Parameters:
        -----------
        unit: astropy.units
          The output unit of the spectrum
        ispec: int
          If given, returns only the spectrum of indice ispec

        Returns
        -------
        output (, N) ndarray or astropy.units.quantity
        """
        if self.is_fnu:
            result = self.y
        else:
            if self.is_nu:
                result = self.y * velc / self.x / self.x
            else:
                result = self.y * self.x * self.x / velc
        if unit is not None:
            result = (result * fnu_unit).to(unit)
        if ispec is not None:
            if self.nb > 1:
                result = result[ispec, :]
        return result

    def flam(self, unit=None, ispec=None):
        """
        returns the spectrum in spectral irradiance per unit wavelength

        if the unit is not given, the spectrum is returned in flam_unit (i.e
        in W/m**2/m) but without unit (ndarray)

         Parameters:
        -----------
        unit: astropy.units
          The output unit of the spectrum
        ispec: int
          If given, returns only the spectrum of indice ispec

        Returns
        -------
        output (, N) ndarray or astropy.units.quantity

        """
        if self.is_flam:
            result = self.y
        else:
            if self.is_lam:
                result = self.y * velc / self.x / self.x
            else:
                result = self.y * self.x * self.x / velc
        if unit is not None:
            result = (result * flam_unit).to(unit)
        if ispec is not None:
            if self.nb > 1:
                result = result[ispec, :]
        return result

    def in_flam(self, reinterpolate=True):
        """
        Set the spectrum to 'flam' type
        """
        if self.is_fnu:
            if self.is_nu:
                self.y = self.y * self.x / (velc / self.x)
            else:
                self.y = self.y * (velc / self.x) / self.x
            self.y_si_unit = flam_unit
            self.is_flam = True
            self.is_fnu = False
            if reinterpolate:
                self.interpolate_set = self.set_interpolation(
                    self.interpolate_method,
                    extrapolate=self.extrapolate,
                    positive=self.positive)
            else:
                self.interpolate = None
                self.interpolate_set = False
        return None

    def in_fnu(self, reinterpolate=True):
        """
        Set the spectrum to 'fnu' type
        """
        if self.is_flam:
            if self.is_nu:
                self.y = self.y * (velc / self.x) / self.x
            else:
                self.y = self.y * self.x / (velc / self.x)
            self.y_si_unit = fnu_unit
            self.is_fnu = True
            self.is_flam = False
            if reinterpolate:
                self.interpolate_set = self.set_interpolation(
                    self.interpolate_method,
                    extrapolate=self.extrapolate,
                    positive=self.positive)
            else:
                self.interpolate = None
                self.interpolate_set = False
        return None

    def fnu_nu(self, nu):
        """
        Interpolate the spectrum in the form of Fnu at the requested
        frequencies. The spectrum is converted to 'nu', 'fnu' type

        Parameters
        ----------
        nu: astropy.units.Quantity or numpy array
            if nu is a numpy array, it is assumed to be in Hz

        Returns
        -------
        Interpolated fnu at the required frequencies.
        """
        self.in_nu(reinterpolate=False)
        self.in_fnu(reinterpolate=True)
        if isinstance(nu, u.Quantity):
            result = self.interpolate((nu.to(nu_unit)).value) * fnu_unit
        else:
            result = self.interpolate(nu)
        return result

    def flam_lam(self, lam):
        """
        Interpolate the spectrum in the form of Flam at the requested
        wavelengths. The spectrum is converted to 'lam', 'flam' type

        Parameters
        ----------
        lam: astropy.units.Quantity or numpy array
            if lam is a numpy array, it is assumed to be in m

        Returns
        -------
        Interpolated flam at the required wavelengths.

        """
        self.in_lam(reinterpolate=False)
        self.in_flam(reinterpolate=True)
        if isinstance(lam, u.Quantity):
            result = self.interpolate(lam.to(lam_unit).value) * flam_unit
        else:
            result = self.interpolate(lam)
        return result

    def __str__(self):
        if self.header is not None:
            result = '{}\nspectrum:'.format(self.header)
        else:
            result = "spectrum:"
        result = result + "\n  nb spectra   : {}".format(self.nb)
        result = result + "\n  nb datapoints: {}".format(len(self.x))
        if self.is_lam:
            result = result + "\n  xtype        : lam"
        elif self.is_nu:
            result = result + "\n  xtype        : nu"
        else:
            result = result + "\n  xtype        : unknown. That's not good !"
        result = result + "\n  coverage     : {:0.3e} to {:0.3e}".\
            format(self.x[0], self.x[-1]*self.x_si_unit)
        if self.is_flam:
            result = result + "\n  ytype        : flam"
        elif self.is_fnu:
            result = result + "\n  ytype        : fnu"
        else:
            result = result + "\n  ytype        : unknown. That's not good !"
        result = result + "\n  interpolation: {}".\
            format(self.interpolate)
        result = result + "\n  ready for use: {}".\
            format(self.interpolate_set)
        return result

class GalaxySpectrum(BasicSpectrum):
    """
    A class to represent spectra of galaxies. It inherits BasicSpectrum and
    allows to take into account the redshift.
    """
    def __init__(self, z=None, cosmo=None, dl=None,
                 table=None, name_x=None, names_y=None,
                 x=None, x_unit=None,
                 y=None, y_type=None, y_unit=None,
                 interpolation_method='log-log-linear',
                 extrapolate='no', positive=True):

        BasicSpectrum.__init__(self, table=table, name_x=name_x,
                               names_y=names_y,
                               x=x, x_unit=x_unit,
                               y=y, y_type=y_type, y_unit=y_unit,
                               interpolation_method=interpolation_method,
                               extrapolate=extrapolate, positive=positive)
        self.z = z
        self.cosmo = cosmo
        if dl is None:
            self.dl = cosmo.luminosity_distance(z)
        else:
            self.dl = dl

    def __str__(self):
        result = "***** BasicSpectrum:\n" + BasicSpectrum.__str__(self)
        result += "\n***** GalaxySpectrum:"
        result += "\n   z = {}".format(self.z)
        result += "\n   dl = {}".format(self.dl)
        result += "\n   with cosmology = {}".format(self.cosmo)
        return result

    def redshift(self, redshift):
        """
        redshift the spectrum  to z

        Parameters
        ----------
        redshift: float
        """
        dl = self.cosmo.luminosity_distance(redshift)
        if self.is_nu:
            old_shift = 1. / (1. + self.z)
            new_shift = 1./(1. + redshift)
        elif self.is_lam:
            old_shift = 1. + self.z
            new_shift = 1. + redshift
        else:
            raise ValueError("Spectrum type is neither nu or lam")
        if self.is_fnu:
            old_fact = (1. + self.z) / 4. / np.pi / self.dl**2
            new_fact = (1. + redshift) / 4. / np.pi / dl**2
        elif self.is_flam:
            old_fact = 1. / (1. + self.z) / 4. / np.pi / self.dl**2
            new_fact = 1. / (1. + redshift) / 4. / np.pi / dl**2
        else:
            raise ValueError("Spectrum is neither fnu or flam")

        self.shift(new_shift / old_shift)
        self.scale((new_fact / old_fact).value)
        self.z = redshift
        self.dl = dl

class StellarLibrary(BasicSpectrum):
    """
    Provide support for spectral libraries, such as the BaSeL 2.2 one (Lejeune
    et al., 1998) or Pickles (1998) as BasicSpectrum.

    The library can consist in a set of ascii files, such as the distribution
    off BaSeL 2.2, or a single fits file.

    The StellarLibrary class provides a mechanism to associate parameters to
    the spectra, allowing to find a match.

    The contructor must be passed either:
        * a reader function that will returns the wavelengths, spectra,
          and a matcher object
        * the wavelengths, spectra and the matcher object

    The matcher object is an object that contains the library parameters with
    the following methods:
    * __getitem__: to allow slicing so that the library parameters keeps in
                   line with slicing of the library
    * __str__: to format nicely the content of the library parameters
    * _closest_match: to allow to find the closest spectra in the library for a
                      set of input parameters
    * _exact_match: to allow to find the library spectrum matching exactly
                    the input parameters. It must raise a ValueError is no
                    match is found.

    See the BaSeL2p2Reader and BaSeL2p2Matcher classes as well as the
    convenience function BaSeL2p2 for examples of implementation

    Parameters:
    -----------
    match_is_exact: bool
        if True uses exact_match() method for match(), closest_match() if False
    matcher: object
        the object containing the parameters and allowing for matching
    inherited parameters from BasicSpectrum

    Methods:
    --------
    __getitem__:
        select a subsample of the library as a StellarLibrary
    __str__:
        print the library content
    closest_match:
        returns the closest matching spectrum as a one element StellarLibrary.
        Uses the _closest_match method of the matcher object.
    index_closest_match:
        returns the index of the closest match
    exact_match:
        returns the exact matching spectrum as a one element Stellar Library.
        Uses the _exact_match method of the matcher object.
    index_exact_match:
        returns the index of the exact match
    match:
        perform a closest or exact match depending on the value of
        match_is_exact
    index_match:
        returns the index of the match
    inherited methods of BasicSpectrum
    """
    def __init__(self, reader=None, x=None, y=None, matcher=None,
                 interpolation_method='log-log-linear',
                 extrapolate='no', positive=True, match_is_exact=True):
        """
        Initialization by providing either a reader method, or a set of x,
        values y and a matcher object:

        lib = StellarLibrary(reader=myReader)

        lib = StellarLibrary(x=x, y=y, matcher=myMatcher)
        """
        self.match_is_exact = match_is_exact
        if reader is not None:
            if x is None and y is None and matcher is None:
                (x, y, matcher) = reader()
            else:
                raise ValueError("Both reader and values are specified")
        if matcher is None:
            raise ValueError("No matching mechanism provided")
        self.matcher = matcher
        super().__init__(x=x, y=y, interpolation_method=interpolation_method,
                         extrapolate=extrapolate, positive=positive)

    def __getitem__(self, item):
        return StellarLibrary(x=self.x * self.x_si_unit,
                              y=self.y[item,:] * self.y_si_unit,
                              matcher=self.matcher[item],
                              interpolation_method=self.interpolate_method,
                              extrapolate=self.extrapolate,
                              positive=self.positive,
                              match_is_exact=self.match_is_exact)

    def __str__(self):
        result = self.matcher.__str__()
        result += super().__str__()
        return result

    def exact_match(self, *args):
        return self.__getitem__(self.matcher._exact_match(*args))

    def index_exact_match(self, *args):
        return self.matcher._exact_match(*args)

    def closest_match(self, *args):
        return self.__getitem__(self.matcher._closest_match(*args))

    def index_closest_match(self, *args):
        return self.matcher._closest_match(*args)

    def match(self, *args):
        if self.match_is_exact:
            return self.exact_match(*args)
        else:
            return self.closest_match(*args)

    def index_match(self, *args):
        if self.match_is_exact:
            return self.index_exact_match(*args)
        else:
            return self.index_closest_match(*args)


# coding=utf-8
import sys
import spotipy
import spotipy.util as util
from time import sleep

def check_tracks(results, first_date, counter):
    for i, item in enumerate(results['items']):
        temp_date = item['added_at']
        if temp_date > first_date:
            track = item['track']
            print(counter, track['artists'][0]['name'], track['name'])
            sp.user_playlist_reorder_tracks(
                username, playlist['id'], counter, 0, 1)
            sleep(0.5)
            first_date = temp_date
        counter += 1
    return counter

if __name__ == '__main__':

    scope = 'playlist-modify-private playlist-read-collaborative playlist-modify-public playlist-read-private playlist-modify-private'

##########################################
#   EDIT HERE
    username = 'XXXXXXXX'
    playlistarray = [
        'PLAYLISTNAME1'.decode('utf-8'),
        'PLAYLISTNAME2'.decode('utf-8'),
        'PLAYLISTNAME99'.decode('utf-8'),
    ]
    client_id = 'XXXXXXXXXXXXXXXXXXXXXXXXX'
    client_secret = 'XXXXXXXXXXXXXXXXXXXXXXXX'
##########################################

    token = util.prompt_for_user_token(
        username, scope, client_id=client_id, client_secret=client_secret, redirect_uri='http://localhost/')
    if token:
        sp = spotipy.Spotify(auth=token)
        playlists = sp.current_user_playlists(limit=50, offset=0)
        while playlists:
            for i, playlist in enumerate(playlists['items']):
                if playlist['owner']['id'] == username and playlist['name'] in playlistarray:
                    results = sp.user_playlist(
                        username, playlist['id'], fields="tracks,next")
                    first_date = results['tracks']['items'][0]['added_at']
                    tracks = results['tracks']
                    counter = 0
                    counter = check_tracks(tracks, first_date, counter)
                    while tracks['next']:
                        tracks = sp.next(tracks)
                        counter = check_tracks(tracks, first_date, counter)

            if playlists['next']:
                playlists = sp.next(playlists)
            else:
                playlists = None
    else:
        print("Can't get token for", username)


"""
Tests of the testing-helpers. :-/
"""
from builtins import object

from twisted.web.http_headers import Headers

from klein import Klein

from pytest import fixture, inlineCallbacks

from crosscap import testing

@fixture
def srv():
    """
    A server built with klein, for testing tools that test servers built with klein
    """
    class AServer(object):
        app = Klein()

        @app.route('/hello')
        def hello(self, request):
            return 123

    return testing.EZServer(AServer)

@inlineCallbacks
def test_handler(srv):
    """
    Call a handler on the test server with the handler() helper, assert that the route returns its value
    """
    res = yield srv.handler("hello")
    assert res == 123

def test_request(srv):
    """
    Test various ways to construct a request
    """
    req = testing.request([], requestAttr=True)
    assert req.requestAttr
    req = testing.request([], session_attr=True)
    assert req.session.attr
    rh = {'Accept-Language': 'klingon'}
    req = testing.request([], responseHeaders=list(rh.items()))
    assert req.responseHeaders == Headers({'accept-language': ['klingon']})
    assert req.code == 200


# Medium
# https://leetcode.com/problems/remove-duplicates-from-sorted-list-ii/
# TC: O(N)
# SC: O(1)

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def deleteDuplicates(self, head: ListNode) -> ListNode:
        if not head:
            return
        sentinel = ListNode(0, head)
        pt1 = sentinel
        while head:
            while head.next and head.val == head.next.val:
                head = head.next
            if pt1.next == head:  # no duplicates
                pt1 = pt1.next
                head = head.next
            else:  # duplicates
                head = head.next
                pt1.next = head
        return sentinel.next

LinkedList/82. Remove Duplicates From Sorted List II.py


class Solution:
    def reverse(self, x: int) -> int:
        if not x:
            return(x)
        sign = x/abs(x)
        x = abs(x)
        digits = []
        minv = -2**31
        maxv = 2**31-1
        while x != 0:
            digits.append(x%10)
            x = x // 10
        rev = 0
        for i,v in enumerate(digits):
            rev += v * 10**(len(digits)-i-1)
        rev = int(sign*rev)
        if minv <= rev <= maxv:
            return(rev)
        else:
            return(0)


#!/usr/bin/env python

# https://adventofcode.com/2022/day/4

def section(ranges):
    r = ranges.split('-')
    return set(range(int(r[0]), int(r[1]) + 1))

def part_one(file):
    with open(file) as f:
        pairs = [line.rstrip().split(',') for line in f]

    fully_contained = 0
    for pair in pairs:
        sec1 = section(pair[0])
        sec2 = section(pair[1])
        if len(sec1 & sec2) == min(len(sec1), len(sec2)):
            fully_contained += 1

    return fully_contained

def test_part_one():
    assert part_one('input/day4_test.txt') == 2

print(f"part 1: {part_one('input/day4.txt')}")

def part_two(file):
    with open(file) as f:
        pairs = [line.rstrip().split(',') for line in f]

    overlap = 0
    for pair in pairs:
        sec1 = section(pair[0])
        sec2 = section(pair[1])
        if len(sec1 & sec2) > 0:
            overlap += 1

    return overlap

def test_part_two():
    assert part_two('input/day4_test.txt') == 4

print(f"part 2: {part_two('input/day4.txt')}")


from __future__ import print_function

import argparse
import json
import os
from datetime import datetime

import numpy as np
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
import torch.utils.data as data
from model.models import MODELS
from road_dataset_convert import DeepGlobeDataset, SpacenetDataset
from torch.autograd import Variable
from torch.optim.lr_scheduler import MultiStepLR
from utils.loss import CrossEntropyLoss2d, mIoULoss
from utils import util
from utils import viz_util
import csv

__dataset__ = {"spacenet": SpacenetDataset, "deepglobe": DeepGlobeDataset}

parser = argparse.ArgumentParser()
parser.add_argument(
    "--config", required=True, type=str, help="config file path"
)
parser.add_argument(
    "--model_name",
    required=True,
    choices=sorted(MODELS.keys()),
    help="Name of Model = {}".format(MODELS.keys()),
)
parser.add_argument("--exp", required=True, type=str, help="Experiment Name/Directory")
parser.add_argument(
    "--resume", default=None, type=str, help="path to latest checkpoint (default: None)"
)
parser.add_argument(
    "--dataset",
    required=True,
    choices=sorted(__dataset__.keys()),
    help="select dataset name from {}. (default: Spacenet)".format(__dataset__.keys()),
)
parser.add_argument(
    "--model_kwargs",
    default={},
    type=json.loads,
    help="parameters for the model",
)
parser.add_argument(
    "--multi_scale_pred",
    default=True,
    type=util.str2bool,
    help="perform multi-scale prediction (default: True)",
)

args = parser.parse_args()
config = None

if args.resume is not None:
    if args.config is not None:
        print("Warning: --config overridden by --resume")
        config = torch.load(args.resume)["config"]
elif args.config is not None:
    config = json.load(open(args.config))

assert config is not None

util.setSeed(config)

experiment_dir = os.path.join(config["trainer"]["save_dir"], args.exp)
util.ensure_dir(experiment_dir)

###Logging Files
# train_file = "{}/{}_train_loss.txt".format(experiment_dir, args.dataset)
# test_file = "{}/{}_test_loss.txt".format(experiment_dir, args.dataset)

# train_loss_file = open(train_file, "w", 1)
# val_loss_file = open(test_file, "w", 1)

# ### Angle Metrics
# train_file_angle = "{}/{}_train_angle_loss.txt".format(experiment_dir, args.dataset)
# test_file_angle = "{}/{}_test_angle_loss.txt".format(experiment_dir, args.dataset)

# train_loss_angle_file = open(train_file_angle, "w", 1)
# val_loss_angle_file = open(test_file_angle, "w", 1)
################################################################################
# num_gpus = torch.cuda.device_count()

# model = MODELS[args.model_name](
#     config["task1_classes"], config["task2_classes"], **args.model_kwargs
# )

# if num_gpus > 1:
#     print("Training with multiple GPUs ({})".format(num_gpus))
#     model = nn.DataParallel(model).cuda()
# else:
#     print("Single Cuda Node is avaiable")
#     model.cuda()
################################################################################

### Load Dataset from root folder and intialize DataLoader
train_loader = data.DataLoader(
    __dataset__[args.dataset](
        config["train_dataset"],
        seed=config["seed"],
        is_train=True,
        multi_scale_pred=args.multi_scale_pred,
    ),
    batch_size=config["train_batch_size"],
    num_workers=8,
    shuffle=True,
    pin_memory=False,
)

val_loader = data.DataLoader(
    __dataset__[args.dataset](
        config["val_dataset"],
        seed=config["seed"],
        is_train=False,
        multi_scale_pred=args.multi_scale_pred,
    ),
    batch_size=config["val_batch_size"],
    num_workers=8,
    shuffle=True,
    pin_memory=False,
)

print("Training with dataset => {}".format(train_loader.dataset.__class__.__name__))
################################################################################

# best_accuracy = 0
# best_miou = 0
# start_epoch = 1
# total_epochs = config["trainer"]["total_epochs"]
# # optimizer = optim.SGD(
# #     model.parameters(), lr=config["optimizer"]["lr"], momentum=0.9, weight_decay=0.0005
# # )

# if args.resume is not None:
#     print("Loading from existing FCN and copying weights to continue....")
#     checkpoint = torch.load(args.resume)
#     start_epoch = checkpoint["epoch"] + 1
#     best_miou = checkpoint["miou"]
#     # stat_parallel_dict = util.getParllelNetworkStateDict(checkpoint['state_dict'])
#     # model.load_state_dict(stat_parallel_dict)
#     model.load_state_dict(checkpoint["state_dict"])
#     optimizer.load_state_dict(checkpoint["optimizer"])
# else:
#     util.weights_init(model, manual_seed=config["seed"])

# viz_util.summary(model, print_arch=False)

# scheduler = MultiStepLR(
#     optimizer,
#     milestones=eval(config["optimizer"]["lr_drop_epoch"]),
#     gamma=config["optimizer"]["lr_step"],
# )

# weights = torch.ones(config["task1_classes"]).cuda()
# if config["task1_weight"] < 1:
#     print("Roads are weighted.")
#     weights[0] = 1 - config["task1_weight"]
#     weights[1] = config["task1_weight"]

# weights_angles = torch.ones(config["task2_classes"]).cuda()
# if config["task2_weight"] < 1:
#     print("Road angles are weighted.")
#     weights_angles[-1] = config["task2_weight"]

# angle_loss = CrossEntropyLoss2d(
#     weight=weights_angles, size_average=True, ignore_index=255, reduce=True
# ).cuda()
# road_loss = mIoULoss(
#     weight=weights, size_average=True, n_classes=config["task1_classes"]
# ).cuda()

f = open('103201_mask_pred.csv','w',encoding='utf-8')
csv_writer = csv.writer(f)
csv_writer.writerow(['ImageId','WKT_Pix'])

for i, data in enumerate(val_loader, 0):
    linestring, image_name = data

    for val in linestring:
#         print(image_name[0][30:-4]+'_mask')
#         print(val)
        csv_writer.writerow([image_name[0][34:-4]+'_mask',val[0]])

#     print(linestring)
#     print(image_name[0][30:-4])


from selenium import webdriver
from bs4 import BeautifulSoup
import requests
import time
import csv
START_URL = "https://exoplanets.nasa.gov/exoplanet-catalog/"
browser = webdriver.Chrome("/Users/Admin/Downloads/chromedriver_win32/chromedriver")
browser.get(START_URL)
time.sleep(10)

new_planet_data=[]
planet_data = []
headers = ["name", "light_years_from_earth", "planet_mass", "stellar_magnitude", "discovery_date","hyperlink","planet_type","planet_radius","orbital-radius","orbital_period","eccentricity"]
def scrape():

    for i in range(0, 428):
        soup = BeautifulSoup(browser.page_source, "html.parser")
        for ul_tag in soup.find_all("ul", attrs={"class", "exoplanet"}):
            li_tags = ul_tag.find_all("li")
            temp_list = []
            for index, li_tag in enumerate(li_tags):
                if index == 0:
                    temp_list.append(li_tag.find_all("a")[0].contents[0])
                else:
                    try:
                        temp_list.append(li_tag.contents[0])
                    except:
                        temp_list.append("")
            planet_data.append(temp_list)

    # with open("scrapper_2.csv", "w") as f:
    #     csvwriter = csv.writer(f)
    #     csvwriter.writerow(headers)
    #     csvwriter.writerows(planet_data)
scrape()

def scrapemoredata(hyperlink):
    page=requests.get(hyperlink)
    soup=BeautifulSoup(page.content,"html.parser")
    for tr_tag in soup.find_all('tr',attrs={'class','fact_row'}):
        td_tag=tr_tag.find_all('td')
        temp_list=[]
        for tdtag in td_tag:
            try:
                temp_list.append(tdtag.find_all('div',attrs={'class','value'})[0].contents[0])
            except:
                temp_list.append('')
        new_planet_data.append(temp_list)

for data in planet_data:
    scrapemoredata(data[5])

final_planet_data=[]

for index,data in enumerate(planet_data):
    final_planet_data.append(data+final_planet_data[index])

with open('apeksha.csv','w') as f:
    csvwriter=csv.writer(f)
    csvwriter.writerow(headers)
    csvwriter.writerows(final_planet_data)


import pandas as pd
import akshare as ak
import matplotlib.pyplot as plt

target=ak.fund_em_fund_name()
data=pd.read_csv('夏普/sharpe_rate.csv',header=None)
data_index=data[0]
data_sr=data[2]
index_list=list(target['基金代码'])
tag_list=list(target['基金类型'])
tag_type=sorted(list(set(tag_list)))

tag_sr=[]
for tag in tag_type:
    tag_sr.append([])

for i in range(len(data_index)):
    i_str=str(data_index[i])
    if len(i_str)<6:
        index='0'*(6-len(i_str))+i_str
    else:
        index=i_str
    if index in index_list:
        fund_where=index_list.index(index)
        fund_type=tag_list[fund_where]
        fund_type_num=tag_type.index(fund_type)
        tag_sr[fund_type_num].append(data_sr[i])

plt.figure(1)
zero_num=0
for i in range(len(tag_type)):
    plot_sr_data = pd.DataFrame(tag_sr[i])
    if len(tag_sr[i])==0:
        zero_num+=1
    else:
        plt.subplot(3,4,i+1-zero_num)
        plt.hist(tag_sr[i],bins=30,range=[-15,15],density=True,label=tag_type[i]+'\n'+'N='+str(len(tag_sr[i])))
        plt.legend(loc='upper right')
    #plot_sr_data.plot(kind='hist',bins=10,range=[-20,20],normed=True,label='hist')
    #plot_sr_data.plot(kind='kde',color='red',label='kde')
plt.show()

多变量分析/4.各类的夏普作图.py

4.各类的夏普作图.py


from pychord import Chord
import pretty_midi
import time
from revChatGPT.ChatGPT import Chatbot

global chatbot
chatbot = Chatbot({
    "session_token": "YOUR-TOKEN" # place your token here
}, conversation_id=None, parent_id=None)

def create_midi(chords):
    """
    This function is adapted from https://github.com/yuma-m/pychord/blob/main/examples/pychord-midi.py
    """
    midi_data = pretty_midi.PrettyMIDI()
    piano_program = pretty_midi.instrument_name_to_program('Acoustic Grand Piano')
    piano = pretty_midi.Instrument(program=piano_program)
    length = 1
    for n, chord in enumerate(chords):
        for note_name in chord.components_with_pitch(root_pitch=4):
            note_number = pretty_midi.note_name_to_number(note_name)
            note = pretty_midi.Note(velocity=100, pitch=note_number, start=n * length, end=(n + 1) * length)
            piano.notes.append(note)
    midi_data.instruments.append(piano)
    timestr = time.strftime("%Y%m%d-%H%M%S")
    midi_data.write(f'progression-{timestr}.mid')

def main():
    user_input = input("Enter what kind of chord progression you would like to generate: ")

    response = chatbot.ask(f"{user_input} in the format of this chord progression: Bb7 - Bb7 - Bb7 - Bb7\nEb7 - Eb7 - "
                           f"Bb7 - Bb7\nAb7 - Ab7 - Bb7 - Bb7\nEb7 - Bb7 - Ab7 - Eb7\nDo not write anything other than the chord progression itself.",
                           conversation_id=None,
                           parent_id=None)

    print(response["message"])
    lines = response["message"].split("\n")

    letters = ["A", "B", "C", "D", "E", "F", "G"]

    # removing the lines breaks
    lines_nobreak = []
    for i in lines:
        if i[0] in letters:
            lines_nobreak.append(i)

    # making it a list of just the chord symbols
    chords_str = []
    for i in lines_nobreak:
        for j in i.split(" - "):
            if j.__contains__("\n"):
                chords_str.append(j[0:-1])
            else:
                chords_str.append(j)

    chords = [Chord(c) for c in chords_str]
    create_midi(chords)

    print("File created!")
    end_input = input("Would you like to generate another midi file? (Y/N) ")
    if end_input == "Y" or end_input == "y":
        main()
    else:
        input("Press enter to close the program")

if __name__ == '__main__':
    main()


from django.urls import path
from . import views

urlpatterns = [
    path('', views.get_students_list, name='students_list'),
    path('delete', views.delete_student, name='delete_student'),
    path('update', views.update_student, name='update_student'),
    path('create', views.create_student, name='create_student'),
]


from math import pi, sin
from turtle import Turtle, screensize, getscreen, done, TurtleScreen

def draw_graph(vertices: int) -> None:
    # radius and circumference of the circle which the regular graph will be contained in
    rad: int = 250
    circumference: float = 2 * pi * rad

    screensize(1000, 1000)  # define the screen size
    screen: TurtleScreen = getscreen()  # open the window for the user
    screen.clear()  # delete arrow sprite

    turtle_pen: Turtle = Turtle()  # init a turtle to draw with
    turtle_pen.hideturtle()  # hide the turtle while drawing
    turtle_pen.speed(0)  # max speed
    turtle_pen.penup()  # up to not draw any lines during setup

    # go to x coordinate equal to the radius of the circle the graph is contained in
    # y coordinate 0
    turtle_pen.goto(rad, 0)

    # pen down and prepare to draw
    turtle_pen.pendown()

    # rotate 90 degrees to tangent the circle
    turtle_pen.left(90)

    # list of positions of all vertices
    # which must still be travelled to
    positions: list[tuple[float, float]] = []

    # calculate the degrees to rotate
    # each time we draw a new line
    angle: float = 180 / vertices

    # ALL INITIAL VERTICES
    # draw all lines from initial point
    # and save positions of all the other vertices
    for line in range(1, vertices):
        # calculate the arc length based on number of vertices
        # and based on what line we are drawing
        arc: float = circumference / vertices * line

        # calculate chord length, or length of line
        # see also: https://en.wikipedia.org/wiki/Chord_(geometry)
        chord: float = 2 * rad * sin(arc / (2 * rad))

        # rotate to the angle the next chord is at
        # and draw the chord
        turtle_pen.left(angle)
        turtle_pen.forward(chord)

        # save position after motion
        # the endpoint of each chord is the location for a vertex
        positions.append(turtle_pen.position())

        # pen up and return to original position
        # and pen down to prepare for next line
        turtle_pen.penup()
        turtle_pen.backward(chord)
        turtle_pen.pendown()

    # CONNECT ALL VERTICES TO EACH OTHER
    # move to the next vertex
    # and draw all its chords
    for _ in range(0, len(positions)):
        current_vertex: tuple[float, float] = positions[0]

        # pen up and move to next vertex in queue
        turtle_pen.penup()
        turtle_pen.goto(current_vertex)

        # draw all chords for current vertex
        for next_vertex in positions:
            # pen down and draw chord to next vertex
            turtle_pen.pendown()
            turtle_pen.goto(next_vertex)

            # pen up and return to current vertex
            turtle_pen.penup()
            turtle_pen.goto(current_vertex)

        # delete current vertex after all lines drawn from it
        # used to avoid visiting the same vertex twice
        del positions[0]

def main() -> None:
    # ask the user for the number of vertices their regular graph should have
    num_of_vertex: int = int(input("Number of vertices: ") or "3")

    # default the number of vertices to three
    if num_of_vertex < 3:
        num_of_vertex: int = 3

    # run regular graph algorithm
    draw_graph(num_of_vertex)

    done()  # turtle event loop

if __name__ == "__main__":
    main()