import yaml
import logging

import pomodorobot.lib as lib

class Config:
    """ Represents a configuration loader, that loads configurations from
        a file into a dictionary

        The file must have its values stored with the format 'key: value'
        Current supported values are strings (including multi-line ones),
        booleans, integers, lists and dictionaries.

        Integers and booleans are also saved as strings if a tag is not
        specified, but are converted to the correct type when get_int or
        get_boolean are used.
        Valid tags are [i] for integers and [b] for booleans, so for example:
            key_1: [i] 1
            key_2: [b] True
        Will load correct integer and boolean values, correspondingly.
        Valid boolean values are specified in the documentation for get_boolean.

        For multi-line strings, the first line must be such that the first line
        is just three double quotes ("), and each new line must start with an
        underscore (_), and either the last line must end with the same three
        double quotes or the last line itself must be the double quotes.
            For example (ignore the back-slash next to the quotes):
            multi-line: \"""
            _This is the first line of a multi-line string configuration value
            _and this is the second.
            _It now ends
            _\"""

        For lists, the format is the same than that of the
        python notation, so it would be:
            list: [element_1, element_2, element_3]
        and a dictionary format is almost the same, but uses ' - ' instead
        of ':', thus a dictionary would be noted as:
            dict: {key_1 - value_1, key_2 - value_2, key_3 - value_3}

        For values too big to be worth holding in memory, you can add a [heavy]
        tag at the beggining of the value. This will make the formatter ignore
        the value until it's called for, at which moment it will load it
        directly from the file. For example, to use with a multi-line string,
        the first line of such value would look like (Again, no backslash):
            heavy-string: [heavy] \"""

        Comments are allowed within the file by starting a line with #.
    """

    _file_name = None
    _config_map = {}

    def __init__(self):
        pass

    def set_file(self, file_name: str):
        self._file_name = file_name

    def is_set(self):
        return self._config_map and self._file_name is not None

    def reload(self):
        """ Reloads the configuration dictionary from the given file.

        :return: Itself to allow easier statement chaining
        """
        file = open(self._file_name, 'r')
        self._config_map = yaml.safe_load(file)
        file.close()

        return self

    def get_section(self, path):
        """ Gets a section of the configuration.
            The path is a list of super-sections, in order, or a string of them
            separated by dots
            Ex.: If a config file has the structure
                server:
                    channel_1:
                        person_A:
                            name: 'John'
                            last: 'Doe"

            You can get person_A's section by using the path
            'server.channel_1.person_A'.

        :param path: The path to the dictionary.
        :type path: str or list

        :return: The configuration section, as a dictionary, or None if it's not
            a dictionary type.
        """
        if isinstance(path, str):
            keys = path.split('.')
        else:
            keys = path

        section = self._config_map
        for key in keys:
            if key in section.keys():
                section = section[key]
                if not isinstance(section, dict):
                    return None
        return section

    def get_element(self, path: str):
        """ Gets the element corresponding to the path.
            See `get_section` to see how paths work.

            One should avoid using this method, as it's not type-safe. Instead,
            use the methods `get_str`, `get_int`, `get_boolean` or `get_list`

        :param path: The path of the element to get.
        :type path: str

        :return: The configuration element.
        """
        keys = path.split('.')
        element_key = keys.pop(-1)

        section = self.get_section(keys)
        return section[element_key] if\
            section is not None and element_key in section.keys() else None

    def get_str(self, path: str):
        """ Returns the string corresponding to the given key, if valid.

        :param path: The key to look for.
        :type path: str

        :return: The configuration value pertaining to the key, or None if there
            is no value associated with the given key.

        :raises: TypeError: if the value cannot be parsed to `str`.
        """

        string = self.get_element(path)
        if isinstance(string, str):
            return string
        raise TypeError("Configuration value {} could not be parsed to `str`"
                        .format(path))

    def get_int(self, path: str):
        """ Returns the value corresponding to the given key.

        :param path: The key to look for.
        :type path: str

        :return: The configuration value, parsed to int, or None if the
            key is not valid.

        :raises: TypeError: if the value cannot be parsed to `int`.
        """

        number = self.get_element(path)
        if isinstance(number, int):
            return number
        raise TypeError("Configuration value {} could not be parsed to `int`"
                        .format(path))

    def get_boolean(self, path: str):
        """ Returns the value corresponding to the given key.

        :param path: The key to look for.
        :type path: str

        :return: The configuration value, evaluated as boolean, or None
            if the key is not a valid configuration key.

        :raises: TypeError: if the value cannot be parsed as boolean.

        .. note::
            The valid values are not just True or False.
            It can be either 'true', 'on', 'yes' or 'y' for True
            or 'false', 'off', 'no' or 'n' for False
            and is not case-sensitive (so something like TruE is valid).
        """

        boolean = self.get_element(path)
        try:
            return None if boolean is None else\
                lib.to_boolean(boolean)
        except TypeError:
            raise TypeError(("Configuration value {} could not be parsed to " +
                            "`boolean`").format(path))

    def get_list(self, path):
        """ Returns the list corresponding to the given key.

        :param path: The key to look for.
        :type path: str

        :return: The list corresponding to the given key, or None if there is
            no value associated to that key.

        :raises: TypeError: if the value is not a list.
        """
        e_list = self.get_element(path)
        if isinstance(e_list, list):
            return e_list
        raise TypeError("Configuration value {} could not be parsed to `list`"
                        .format(path))

_instance = Config()

def load(file_name: str):
    _instance.set_file(file_name)
    _instance.reload()

def get_config():
    if _instance.is_set():
        return _instance
    else:
        lib.log("Configuration instance was asked for before it was set up.",
                level=logging.ERROR)


import sched
import time

import functions
import sheet
import gspread

sa = gspread.service_account(filename='keys.json')
sh = sa.open_by_key(sheet.sheet_id)
wks = sh.worksheet("Sheet1")

delay_time = 60 * 30

def do_something(scheduler):
    scheduler.enter(delay_time, 1, do_something, (scheduler,))
    try:
        functions.reload()
        sheet.main()
        functions.export()
        data_limits = wks.col_values(9)
        names = wks.col_values(3)
        status = wks.col_values(6)
        days = wks.col_values(5)

        for i in range(1, len(names)):
            if names[i] not in functions.peerMap.keys():
                continue
            if status[i] == "0":
                continue
            if days[i] == "31" and status[i] == "1":
                functions.pause_user(names[i])
            elif data_limits[i] == "0":
                continue
            elif functions.peerMap[names[i]].transfer >= float(data_limits[i]):
                functions.pause_user(names[i])
    except Exception as err:
        print(type(err).__name__ + " " + str(err))

def auto():
    my_scheduler = sched.scheduler(time.time, time.sleep)
    my_scheduler.enter(1, 1, do_something, (my_scheduler,))
    my_scheduler.run()


for t in range(int(input())):
	n = int(input())
	a = list(map(int, input().split()))
	s = sum(a)
	z = 1
	if s == 0:
		z = n
	else:
		for i in range(1, s + 1):
			if s % i == 0:
				f = True
				c = 0
				for j in a:
					c += j
					if c == i:
						c = 0
					elif c > i:
						f = False
						break
				if f:
					z = s // i
					break
	print(n - z)


import sys
sys.stdout = open('dynamic_programming/output.txt', 'w')
sys.stdin = open('dynamic_programming/input.txt', 'r')

def partion(a,n,sum,dp):
    if sum==0:
        return True
    if n==0 and sum!=0:
         return False

    if dp[n]==True:
        return dp[n]
    if a[n]>sum:
        return partion(a,n,sum,dp)

    dp[n]=partion(a,n-1,sum,dp) or partion(a,n-1,sum-a[n],dp)
    return dp[n]

a=list(map(int,input().split()))
sum=0
for i in a:
    sum+=i
if sum%2!=0:
    print(False)
else:
    dp=[False]*len(a)
    print(partion(a,len(a)-1,sum//2,dp))
    print(dp)


from django.shortcuts import get_object_or_404, render
from django.shortcuts import redirect
from django.contrib.auth.decorators import login_required
from django.urls import reverse

from .models import Follow, Group, Post, User
from .forms import PostForm, CommentForm
from .paginator_custom import paginator_custom

def index(request):
    template = 'posts/index.html'

    post_list = Post.objects.select_related('author', 'group')
    page_obj = paginator_custom(request, post_list)

    context = {
        'page_obj': page_obj,
    }

    return render(request, template, context)

def group_posts(request, slug):
    template = 'posts/group_list.html'

    group = get_object_or_404(Group, slug=slug)
    post_list = Post.objects.select_related('author').filter(group=group)
    page_obj = paginator_custom(request, post_list)

    context = {
        'group': group,
        'page_obj': page_obj,
    }

    return render(request, template, context)

def profile(request, username):
    author = get_object_or_404(User, username=username)
    post_list = author.posts.select_related('group')
    page_obj = paginator_custom(request, post_list)

    following = (
        request.user.is_authenticated
        and Follow.objects.filter(
            author=author,
            user=request.user
        ).exists
    )

    context = {
        'page_obj': page_obj,
        'author': author,
        'following': following
    }

    return render(request, 'posts/profile.html', context)

def post_detail(request, post_id):
    post = get_object_or_404(Post, pk=post_id)
    comments = post.comments.all()
    form = CommentForm()

    context = {
        'post': post,
        'comments': comments,
        'form': form,
    }

    return render(request, 'posts/post_detail.html', context)

@login_required
def post_create(request):
    form = PostForm(
        request.POST or None,
        files=request.FILES or None,
    )

    if form.is_valid():
        post = form.save(commit=False)
        post.author = request.user
        post.save()
        return redirect('posts:profile', post.author)

    return render(request, 'posts/create_post.html', {'form': form})

@login_required
def post_edit(request, post_id):
    post = get_object_or_404(Post, pk=post_id)
    form = PostForm(
        request.POST or None,
        files=request.FILES or None,
        instance=post,
    )

    if not request.user == post.author:
        return redirect('posts:post_detail', post_id)

    if form.is_valid():
        post = form.save()
        return redirect('posts:post_detail', post_id)

    context = {
        'is_edit': True,
        'form': form,
        'post_id': post_id,
    }
    return render(request, 'posts/create_post.html', context)

@login_required
def add_comment(request, post_id):
    post = Post.objects.get(pk=post_id)

    form = CommentForm(request.POST or None)
    if form.is_valid():
        comment = form.save(commit=False)
        comment.author = request.user
        comment.post = post
        comment.save()

    return redirect('posts:post_detail', post_id=post_id)

@login_required
def follow_index(request):
    """Публикации избранных авторов"""

    posts = Post.objects.filter(author__following__user=request.user)

    if posts.exists():
        page_obj = paginator_custom(request, posts)
        context = {
            'page_obj': page_obj,
        }
    else:
        empty_page = paginator_custom(request, [])
        context = {
            'page_obj': empty_page,
        }

    return render(request, 'posts/follow.html', context)

@login_required
def profile_follow(request, username):
    """Подписаться на автора"""

    author = get_object_or_404(User, username=username)

    if request.user == author:
        return redirect(reverse('posts:follow_index'))

    Follow.objects.get_or_create(
        author=author,
        user=request.user,
    )

    return redirect(reverse('posts:follow_index'))

@login_required
def profile_unfollow(request, username):
    """Дизлайк, отписка"""

    author = get_object_or_404(User, username=username)
    Follow.objects.filter(author=author, user=request.user).delete()

    return render(request, 'posts/follow.html')


import os
import yadisk
from tqdm import tqdm
from cfg import app_id, secret_id, ya_token
from main import LOAD_PATH
import excel_converter

def load_files():
    # создаем подключение к яндекс диску
    y = yadisk.YaDisk(app_id, secret_id, ya_token)

    # проверяем валидность токена
    if y.check_token():
        print('Token is valid')
    else:
        print('Check OAUTH token')

    # создаем список с именами файлов
    list_of_files = []
    for el in list(y.listdir('for_test')):
        if el['path'].endswith('.xlsx'):
            list_of_files.append(el['path'].split('disk:/')[1])

    # создаем папку загрузки
    if not os.path.exists(LOAD_PATH):
        os.mkdir(LOAD_PATH)
        print('Directory created: ', LOAD_PATH)
    os.chdir(LOAD_PATH)

    # загружаем файлы
    print('Downloading files from yandex disk:')
    for file in tqdm(list_of_files, colour='#FC46AA'):
        y.download(file, file.split('/')[-1])
    print(f'Download complete. {len(os.listdir())} files in work folder.')
    excel_converter.convert_excel()


from typing import List

#Runtime: O(n * a) where a = number of neighbors
#Memory: O(1)
class Solution:
    def exist(self, board: List[List[str]], word: str) -> bool:
        self.res = False
        self.board = board
        self.word = word
        self.backtrack(0, 0, len(board), 0, len(board[0]))
        return self.res

    def backtrack(self, word_letter_idx, board_start_i, board_end_i, board_start_j, board_end_j):
        if word_letter_idx == len(self.word):
            self.res = True
            return
        start_i = max(0, board_start_i)
        end_i = min(len(self.board), board_end_i + 1)
        start_j = max(0, board_start_j)
        end_j = min(len(self.board[-1]), board_end_j + 1)
        for i in range(start_i, end_i):
            for j in range(start_j, end_j):
                if self.board[i][j] == self.word[word_letter_idx]:
                    if self.res is False:
                        temp = self.board[i][j]
                        self.board[i][j] = "_"
                        self.backtrack(word_letter_idx + 1, i - 1, i + 1, j, j)
                        self.backtrack(word_letter_idx + 1, i, i, j - 1, j + 1)
                        self.board[i][j] = temp


# list1=[2, 4, 8]
# i=0
# b=[]
# while i<len(list1):
#     if list1[i] in list1:
#         add_value = list1[i] + 2
#         b.append(add_value)
#     i=i+1
# print(b)

list=[0,1,2,3,5]
i=0
b=[]
while i<len(list):
    if list[i] not in list:
        b.append(i)
    i=i+1
print(b)
#     j=0
#     b=[]
#     while j<len(list):
#         if (list[i][j]) not in list1:
#             b.append(list[i][j])
#         j=j+1
#     i=i+1
# print(b)


from django import forms

from .models import Post

class PostForm(forms.ModelForm):
    class Meta:
        model = Post
        fields = ('group', 'text')
        labels = {
            "group": ("Выберете группу"),
            "text": ("Текст"),
        }
        help_texts = {
            "group": ("Выберете группу из списка доступных."),
            "text": ("Введите текст Вашего поста."),
        }

    def clean_text(self):
        data = self.cleaned_data['text']
        if len(data) < 10:
            raise forms.ValidationError("Слишком короткий текст!")
        return data


import socket

# create a TCP/IP socket object
HOST_IP = socket.gethostbyname(socket.gethostname())
HOST_PORT = 12345
ENCODER = "utf-16"
BYTESIZE = 1024
# create a server socket, bind it to a ip/port, and listen
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind((HOST_IP, HOST_PORT))
server_socket.listen()

# Accept any incoming connection and let them know they are connected
print("Server is running...\n")
client_socket, client_address = server_socket.accept()
print(f"connected to client : {client_address}")

# open the file
import os
filename = './temp.mp4'  # replace with the path to your file
filesize = os.path.getsize(filename)
client_socket.send(str(filesize).encode('utf-8'))
with open(filename, 'rb') as f:
    # read the file in chunks and send them to the server
    while True:
        data = f.read(1024)
        if not data:
            break
        client_socket.sendall(data)

# close the file and socket
server_socket.close()


''' Money Change Question
Convert money into min no. of coins [Denominations 1,5,10 only]
'''
import time

n = int(input())
# starting time
start = time.time()

def minCoins(n):
    a = n//10
    b = (n%10)//5
    c = (n%10)%5
    print("{1} : Rs.{0} coins ".format(10,a))
    print("{1} : Rs.{0} coins ".format(5,b))
    print("{1} : Rs.{0} coins ".format(1,c))

    return a+b+c

print(minCoins(n))

# end time
end = time.time()
print(f"Runtime of the program is {end - start} seconds")


import cv2
from src.main.python.myLibs.ImageProcessing.MorphologicalImageProcessing import morpho, myhisto

imagename = "../../../../resources/images/chat.jpg"

image = cv2.imread(imagename)

morpho.displayImage("Original Image", image)

# Objectif : reequalize only the light

# Use of the colorspace HSV (Hue, Saturation, VLight? :D)
image = cv2.cvtColor(image,cv2.COLOR_BGR2HSV)
image[:,:,2]=myhisto.equalizeHist(image[:,:,2])

image = cv2.cvtColor(image,cv2.COLOR_HSV2BGR)
morpho.displayImage("Image equalized", image)

key = cv2.waitKey(0)
cv2.destroyAllWindows()


from typing import List
class Solution:
    def maxProduct(self, nums: List[int]) -> int:
        max_= float('-inf')
        max_num = 1
        min_num = 1
        for n in nums:
            if n < 0:
                max_num, min_num = min_num, max_num
            max_num = max(max_num*n, n)
            min_num = min(min_num*n, n)
            max_ = max(max_num, max_)
            print(max_num, min_num, max_)
        return max_

if __name__ == "__main__":
    l = [2, 3, -2, 4]
    r = Solution().maxProduct(l)
    print(r)


from tkinter import Tk, Label
from converter import Converter

class Win(Tk):

    def __init__(self):

        Tk.__init__(self, None, None)
        self.wm_title('Converts KM to Miles')
        self.geometry('640x480')
        self.label = Label(self, text='KM : 100' )
        self.label.pack()
        kilo = str(Converter.get_miles_from_km(100))
        self.label2 = Label(self, text='Miles : ' + kilo)

        self.label2.pack()

        self.mainloop()


N = int(input())
S = [None] * N

for i in range(N):
    inp = input()
    S[i] = [s for s in inp]

for i in range(N - 1, -1, -1):
    for j in range(0, 2 * N - 2):
        if S[i][j] == "#":
            try:
                if S[i+1][j-1] == "X":
                    S[i][j] = "X"
            except IndexError:
                continue
            try:
                if S[i+1][j] == "X":
                    S[i][j] = "X"
            except IndexError:
                continue
            try:
                if S[i+1][j+1] == "X":
                    S[i][j] = "X"
            except IndexError:
                continue

for i in range(N):
    print("".join(S[i]))


import pk_aug.augmentation as pkaug

EXPECTED_DICTS_2 = [
    {"unit": "ng·h·ml", "num": "ng·h·ml", "denom": ""},  # passed
    {"unit": "h-1", "num": "", "denom": "h"},  # passed
    {"unit": "/h", "num": "", "denom": "h"},  # passed
    {"unit": "h(-1)", "num": "", "denom": "h"},  # passed
    {"unit": "μM·h", "num": "μM·h", "denom": ""},  # passed
    {"unit": "ng·h/ml", "num": "ng·h", "denom": "ml"},  # passed
    {"unit": "l/[h·kg]", "num": "l", "denom": "h·kg"},  # passed
    {"unit": "ng/ml·h", "num": "ng", "denom": "ml·h"},  # passed
    {"unit": "mM/(l·h)", "num": "mM", "denom": "l·h"},  # passed
    {"unit": "l/h/kg", "num": "l", "denom": "h·kg"},  # passed
    {"unit": "ml·h-1·kg-1", "num": "ml", "denom": "h·kg"},  # passed
    {"unit": "mg·l-1·h-1", "num": "mg", "denom": "l·h"},  # passed
    {"unit": "l/h/70·kg", "num": "l", "denom": "h·70·kg"},  # passed
    {"unit": "μl/min/mg·protein", "num": "μl", "denom": "min·mg·protein"},  # passed
    {"unit": "(ml·h−1)·kg−1", "num": "ml", "denom": "h·kg"},  # passed
    {"unit": "l·h(-1)·70·kg(-1)", "num": "l", "denom": "h·70·kg"},
    {"unit": "l·(kg·h)-1", "num": "l", "denom": "kg·h"},
    {"unit": "mg h l–1", "num": "mg·h", "denom": "l"},
    #{"unit": "microg h ml(-l)", "num": "mg·h", "denom": "ml"},

]

def test_standardise_divide():
    for sample in EXPECTED_DICTS_2:
        inp_mention = sample["unit"]
        unit = pkaug.standardise_unit(inp_mention)
        num, denom = pkaug.standardise_divide(unit)
        assert num == sample["num"]
        assert denom == sample["denom"]

EXPECTED_DICTS_3 = [
    {"unit": "ml·h−1·kg−1·nM-19", "num": "ml", "denom": "h·kg·(nM)^19"}
]

def test_minusmany():
    for sample in EXPECTED_DICTS_3:
        inp_mention = sample["unit"]
        unit = pkaug.standardise_unit(inp_mention)
        num, denom = pkaug.standardise_divide(unit)
        assert num == sample["num"]
        assert denom == sample["denom"]


from django.urls import path
from . import views
from .apis import views as api_views
from cool_fts import open_feature as ft_views

urlpatterns = [
    path('',views.home),
    path('login/', views.message),
    path('register/', views.register),
    path('signout', views.signout),
    path('signin', views.signin),
    path('contact', views.contact),
    path('features/', views.features),
    path('signup', views.signup),
    path('profile', views.profile),
    path('activate/<uidb64>/<token>', views.activate, name="activate"),

    path('apis/home-content', api_views.home_content_api)
]


from __future__ import absolute_import, division, print_function

import locale
import re
import os
import sys
import stat
from glob import glob
from os.path import (basename, dirname, join, splitext, isdir, isfile, exists,
                     islink, realpath, relpath)
try:
    from os import readlink
except ImportError:
    readlink = False
import io
from subprocess import call, Popen, PIPE

from conda_build.config import config
from conda_build import external
from conda_build import environ
from conda_build import utils
from conda_build import source
from conda.compat import lchmod
from conda.misc import walk_prefix

if sys.platform.startswith('linux'):
    from conda_build import elf
elif sys.platform == 'darwin':
    from conda_build import macho

SHEBANG_PAT = re.compile(r'^#!.+$', re.M)

def is_obj(path):
    assert sys.platform != 'win32'
    return bool((sys.platform.startswith('linux') and elf.is_elf(path)) or
                (sys.platform == 'darwin' and macho.is_macho(path)))

def fix_shebang(f, osx_is_app=False):
    path = join(config.build_prefix, f)
    if is_obj(path):
        return
    elif os.path.islink(path):
        return
    with io.open(path, encoding=locale.getpreferredencoding()) as fi:
        try:
            data = fi.read()
        except UnicodeDecodeError: # file is binary
            return
    m = SHEBANG_PAT.match(data)
    if not (m and 'python' in m.group()):
        return

    py_exec = ('/bin/bash ' + config.build_prefix + '/bin/python.app'
               if sys.platform == 'darwin' and osx_is_app else
               config.build_prefix + '/bin/' + basename(config.build_python))
    new_data = SHEBANG_PAT.sub('#!' + py_exec, data, count=1)
    if new_data == data:
        return
    print("updating shebang:", f)
    with io.open(path, 'w', encoding=locale.getpreferredencoding()) as fo:
        fo.write(new_data)
    os.chmod(path, int('755', 8))

def write_pth(egg_path):
    fn = basename(egg_path)
    with open(join(environ.get_sp_dir(),
                   '%s.pth' % (fn.split('-')[0])), 'w') as fo:
        fo.write('./%s\n' % fn)

def remove_easy_install_pth(files, preserve_egg_dir=False):
    """
    remove the need for easy-install.pth and finally remove easy-install.pth
    itself
    """
    absfiles = [join(config.build_prefix, f) for f in files]
    sp_dir = environ.get_sp_dir()
    for egg_path in glob(join(sp_dir, '*-py*.egg')):
        if isdir(egg_path):
            if preserve_egg_dir or not any(i in absfiles for i in walk_prefix(egg_path, False)):
                write_pth(egg_path)
                continue

            print('found egg dir:', egg_path)
            try:
                os.rename(join(egg_path, 'EGG-INFO/PKG-INFO'),
                          egg_path + '-info')
            except OSError:
                pass
            utils.rm_rf(join(egg_path, 'EGG-INFO'))
            for fn in os.listdir(egg_path):
                if fn == '__pycache__':
                    utils.rm_rf(join(egg_path, fn))
                else:
                    # this might be a name-space package
                    # so the package directory already exists
                    # from another installed dependency
                    if os.path.exists(join(sp_dir, fn)):
                        utils.copy_into(join(egg_path, fn), join(sp_dir, fn))
                        utils.rm_rf(join(egg_path, fn))
                    else:
                        os.rename(join(egg_path, fn), join(sp_dir, fn))

        elif isfile(egg_path):
            if not egg_path in absfiles:
                continue
            print('found egg:', egg_path)
            write_pth(egg_path)

    utils.rm_rf(join(sp_dir, 'easy-install.pth'))

def rm_py_along_so():
    "remove .py (.pyc) files alongside .so or .pyd files"
    for root, dirs, files in os.walk(config.build_prefix):
        for fn in files:
            if fn.endswith(('.so', '.pyd')):
                name, unused_ext = splitext(fn)
                for ext in '.py', '.pyc':
                    if name + ext in files:
                        os.unlink(join(root, name + ext))

def compile_missing_pyc():
    sp_dir = environ.get_sp_dir()
    stdlib_dir = environ.get_stdlib_dir()

    need_compile = False
    for root, dirs, files in os.walk(sp_dir):
        for fn in files:
            if fn.endswith('.py') and fn + 'c' not in files:
                need_compile = True
                break
    if need_compile:
        print('compiling .pyc files...')
        utils._check_call([config.build_python, '-Wi',
                           join(stdlib_dir, 'compileall.py'),
                           '-q', '-x', 'port_v3', sp_dir])

def post_process(files, preserve_egg_dir=False):
    remove_easy_install_pth(files, preserve_egg_dir=preserve_egg_dir)
    rm_py_along_so()
    if not config.PY3K:
        compile_missing_pyc()

def osx_ch_link(path, link):
    assert path.startswith(config.build_prefix + '/')
    reldir = utils.relative(path[len(config.build_prefix) + 1:])

    prefix_lib = config.build_prefix + '/lib'
    if link.startswith(prefix_lib):
        return '@loader_path/%s/%s' % (reldir, link[len(prefix_lib) + 1:])

    if link.startswith(('lib', '@executable_path/')):
        return '@loader_path/%s/%s' % (reldir, basename(link))

    if link == '/usr/local/lib/libgcc_s.1.dylib':
        return '/usr/lib/libgcc_s.1.dylib'

def mk_relative_osx(path):
    assert sys.platform == 'darwin' and is_obj(path)
    s = macho.install_name_change(path, osx_ch_link)

    if macho.is_dylib(path):
        names = macho.otool(path)
        if names:
            args = ['install_name_tool', '-id', basename(names[0]), path]
            print(' '.join(args))
            p = Popen(args, stderr=PIPE)
            stdout, stderr = p.communicate()
            stderr = stderr.decode('utf-8')
            if "Mach-O dynamic shared library stub file" in stderr:
                print("Skipping Mach-O dynamic shared library stub file %s\n" % path)
                return
            else:
                print(stderr, file=sys.stderr)
                if p.returncode:
                    raise RuntimeError("install_name_tool failed with exit status %d"
                % p.returncode)

    if s:
        # Skip for stub files, which have to use binary_has_prefix_files to be
        # made relocatable.
        assert_relative_osx(path)

def mk_relative_linux(f, rpaths=('lib',)):
    path = join(config.build_prefix, f)
    rpath = ':'.join('$ORIGIN/' + utils.relative(f, d) for d in rpaths)
    patchelf = external.find_executable('patchelf')
    print('patchelf: file: %s\n    setting rpath to: %s' % (path, rpath))
    call([patchelf, '--set-rpath', rpath, path])

def assert_relative_osx(path):
    for name in macho.otool(path):
        assert not name.startswith(config.build_prefix), path

def mk_relative(m, f):
    assert sys.platform != 'win32'
    path = join(config.build_prefix, f)
    if not is_obj(path):
        return

    if sys.platform.startswith('linux'):
        mk_relative_linux(f, rpaths=m.get_value('build/rpaths', ['lib']))
    elif sys.platform == 'darwin':
        mk_relative_osx(path)

def fix_permissions(files):
    for root, dirs, unused_files in os.walk(config.build_prefix):
        for dn in dirs:
            lchmod(join(root, dn), int('755', 8))

    for f in files:
        path = join(config.build_prefix, f)
        st = os.lstat(path)
        lchmod(path, stat.S_IMODE(st.st_mode) | stat.S_IWUSR) # chmod u+w

def post_build(m, files):
    print('number of files:', len(files))
    fix_permissions(files)

    if sys.platform == 'win32':
        return

    binary_relocation = bool(m.get_value('build/binary_relocation', True))
    if not binary_relocation:
        print("Skipping binary relocation logic")
    osx_is_app = bool(m.get_value('build/osx_is_app', False))

    for f in files:
        if f.startswith('bin/'):
            fix_shebang(f, osx_is_app=osx_is_app)
        if binary_relocation:
            mk_relative(m, f)

    check_symlinks(files)

def check_symlinks(files):
    if readlink is False:
        return  # Not on Unix system
    msgs = []
    for f in files:
        path = join(config.build_prefix, f)
        if islink(path):
            link_path = readlink(path)
            real_link_path = realpath(path)
            if real_link_path.startswith(config.build_prefix):
                # If the path is in the build prefix, this is fine, but
                # the link needs to be relative
                if not link_path.startswith('.'):
                    # Don't change the link structure if it is already a
                    # relative link. It's possible that ..'s later in the path
                    # can result in a broken link still, but we'll assume that
                    # such crazy things don't happen.
                    print("Making absolute symlink %s -> %s relative" % (f, link_path))
                    os.unlink(path)
                    os.symlink(relpath(real_link_path, dirname(path)), path)
            else:
                # Symlinks to absolute paths on the system (like /usr) are fine.
                if real_link_path.startswith(config.croot):
                    msgs.append("%s is a symlink to a path that may not "
                        "exist after the build is completed (%s)" % (f, link_path))

    if msgs:
        for msg in msgs:
            print("Error: %s" % msg, file=sys.stderr)
        sys.exit(1)

def get_build_metadata(m):
    if exists(join(source.WORK_DIR, '__conda_version__.txt')):
        with open(join(source.WORK_DIR, '__conda_version__.txt')) as f:
            version = f.read().strip()
            print("Setting version from __conda_version__.txt: %s" % version)
            m.meta['package']['version'] = version
    if exists(join(source.WORK_DIR, '__conda_buildnum__.txt')):
        with open(join(source.WORK_DIR, '__conda_buildnum__.txt')) as f:
            build_number = f.read().strip()
            print("Setting build number from __conda_buildnum__.txt: %s" %
                  build_number)
            m.meta['build']['number'] = build_number
    if exists(join(source.WORK_DIR, '__conda_buildstr__.txt')):
        with open(join(source.WORK_DIR, '__conda_buildstr__.txt')) as f:
            buildstr = f.read().strip()
            print("Setting version from __conda_buildstr__.txt: %s" % buildstr)
            m.meta['build']['string'] = buildstr


# 思路
"""
不旋转节点，只平移节点里存的值,注意保存当前节点的值和下一个节点的值
"""

# 代码

# Definition for singly-linked list.

class ListNode(object):

    def __init__(self, x):
        self.val = x
        self.next = None

class Solution(object):
    def rotateRight(self, head, k):
        """
        :type head: ListNode
        :type k: int
        :rtype: ListNode
        """
        if head is None or head.next is None:
            return head
        else:

            phead = head
            length = 0
            while phead:
                length += 1
                phead = phead.next

            k = k % length  # 旋转长度大于length时，相当于旋转k % length

            loop = 1
            while loop <= k:
                valtemp = 0
                ptemp = head
                curvaltemp = ptemp.val  # 报存当前节点的值
                while ptemp and ptemp.next:
                    valtemp = ptemp.next.val  # 保存下一个节点的值
                    ptemp.next.val = curvaltemp  # 之后把当前节点的值赋值给下一个节点
                    curvaltemp = valtemp  # 然后把下一个节点的值保存为当前节点的值
                    ptemp = ptemp.next  # 指针后移
                head.val = valtemp  # 把最后一个节点的值给头节点
                loop += 1  # 下一趟移动
            return head

if __name__ =="__main__":
    head = ListNode(1)
    temp = head
    for i in range(2, 6):
        temp.next = ListNode(i)
        temp = temp.next

    s = Solution()
    k = 2
    pphead = s.rotateRight(head, k)
    while pphead:
        print(pphead.val)
        pphead = pphead.next

链表中等难度/#61旋转链表_解法一.py

#61旋转链表_解法一.py


import datetime as dt
import requests
from html import unescape
from twilio.rest import Client

account_sid = '*******************************'
auth_token = '********************************'
client = Client(account_sid, auth_token)

STOCK = "TSLA"
COMPANY_NAME = "Tesla Inc"

## STEP 1: Use https://www.alphavantage.co
# When STOCK price increase/decreases by 5% between yesterday and the day before yesterday then print("Get News").

stock_market_parameters= {
    "function": "TIME_SERIES_DAILY_ADJUSTED",
    "symbol": STOCK,
    "apikey": "***************"
}

yesterdays_date= str(dt.datetime.today() - dt.timedelta(days=3)).split(" ")[0]
before_yesterdays_date = str(dt.datetime.today() - dt.timedelta(days=4)).split(" ")[0]

stock_response= requests.get(url="https://www.alphavantage.co/query", params= stock_market_parameters)
stock_response.raise_for_status()
yesterdays_closed_rate = float(stock_response.json()["Time Series (Daily)"][yesterdays_date]["4. close"])
before_yesterdays_closed_rate = float(stock_response.json()["Time Series (Daily)"][before_yesterdays_date]["4. close"])
print(f"{yesterdays_date}: {yesterdays_closed_rate}")
print(f"{before_yesterdays_date}: {before_yesterdays_closed_rate}")

percentage_rate = round((yesterdays_closed_rate/before_yesterdays_closed_rate)*100 - 100)

print(f"{percentage_rate}%")

if abs(percentage_rate) >= 5:
## STEP 2: Use https://newsapi.org
# Instead of printing ("Get News"), actually get the first 3 news pieces for the COMPANY_NAME.
    news_parameters = {
        "q": COMPANY_NAME,
        "from": yesterdays_date,
        "sortBy":"publishedAt",
        "apiKey": "************************"
    }

    news_response = requests.get(url="https://newsapi.org/v2/everything", params=news_parameters)
    news_response.raise_for_status()
    for index in range(0,3):
        news_title= unescape(news_response.json()["articles"][index]["title"])
        news_details= unescape(news_response.json()["articles"][index]["description"])
        news_url = news_response.json()["articles"][index]["url"]
        # print(f"{news_title}:\n{news_details}\n{news_url}\n\n")

## STEP 3: Use https://www.twilio.com
# Send a separate message with the percentage change and each article's title and description to your phone number.
    if percentage_rate < 0:
        sign = "ðŸ”»"
    else:
        sign = "ðŸ”º"

    message = client.messages.create(
        body=f"{STOCK}:{sign}{percentage_rate}%\nHeadline: {news_title}\nBrief: {news_details}",
        from_='whatsapp:*********',
        to='whatsapp:**********'
    )

    print(message.status)

#Optional: Format the SMS message like this:
"""
TSLA: ðŸ”º2%
Headline: Were Hedge Funds Right About Piling Into Tesla Inc. (TSLA)?.
Brief: We at Insider Monkey have gone over 821 13F filings that hedge funds and prominent investors are required to file by the SEC The 13F filings show the funds' and investors' portfolio positions as of March 31st, near the height of the coronavirus market crash.
or
"TSLA: ðŸ”»5%
Headline: Were Hedge Funds Right About Piling Into Tesla Inc. (TSLA)?.
Brief: We at Insider Monkey have gone over 821 13F filings that hedge funds and prominent investors are required to file by the SEC The 13F filings show the funds' and investors' portfolio positions as of March 31st, near the height of the coronavirus market crash.
"""

Day 36- Stock Trading News Alert/main.py


#!/usr/bin/env python

import nltk, inspect
import itertools
from nltk.corpus import brown
from nltk.tag import map_tag

from nltk.probability import ConditionalProbDist,ConditionalFreqDist, LidstoneProbDist

assert map_tag('brown', 'universal', 'NR-TL') == 'NOUN', '''
Brown-to-Universal POS tag map is out of date.'''

class HMM:
    def __init__(self, train_data, test_data):
        """
        Initialise a new instance of the HMM.

        :param train_data: The training dataset, a list of sentences with tags
        :type train_data: list(list(tuple(str,str)))
        :param test_data: the test/evaluation dataset, a list of sentence with tags
        :type test_data: list(list(tuple(str,str)))
        """
        self.train_data = train_data
        self.test_data = test_data

        # Emission and transition probability distributions
        self.emission_PD: ConditionalProbDist = None
        self.transition_PD: ConditionalProbDist = None
        self.states = []

        self.viterbi = []
        self.backpointer = []

    # Compute emission model using ConditionalProbDist with the estimator:
    # Lidstone probability distribution with +0.01 added to the sample count for each bin and an extra bin
    def emission_model(self, train_data):
        """
        Compute an emission model using a ConditionalProbDist.

        :param train_data: The training dataset, a list of sentences with tags
        :type train_data: list(list(tuple(str,str)))
        :return: The emission probability distribution and a list of the states
        :rtype: Tuple[ConditionalProbDist, list(str)]
        """
    #   print(train_data)
        # TODO prepare data

        # Don't forget to lowercase the observation otherwise it mismatches the test data

        # I want to make train_data into one list of tagged_words with type:(tuple(str,str))
        data = []
        for x in train_data:
        #    data += [ (tag, word.lower() if word.isalpha() else (tag, word)) for (word, tag) in x]  # lower case and check word
            data += [ (tag, word.lower() )for (word, tag) in x]  # lower case

        # TODO compute the emission model
        emission_FD = ConditionalFreqDist(data)
        # need Lidstone bin parameter
        lidstone_estimator = lambda fd: LidstoneProbDist(fd, 0.01, fd.B() + 1)
        self.emission_PD = ConditionalProbDist(emission_FD, lidstone_estimator)

        self.states = emission_FD.keys()

        return self.emission_PD, self.states

    # Compute transition model using ConditionalProbDist with the estimator:
    # Lidstone probability distribution with +0.01 added to the sample count for each bin and an extra bin
    def transition_model(self, train_data):
        """
        Compute an transition model using a ConditionalProbDist.

        :param train_data: The training dataset, a list of sentences with tags
        :type train_data: list(list(tuple(str,str)))
        :return: The transition probability distribution
        :rtype: ConditionalProbDist
        """
        # TODO: prepare the data
        data = []
        tagged_sentences = train_data
        for s in tagged_sentences:

            data.append(("<s>",s[0][1]))          # s.insert(0, "<s>")
            for i in range(len(s)-1):
                data.append((s[i][1], s[i+1][1]))
            data.append((s[len(s)-1][1],"</s>"))  # s.insert((len(s)-1), "</s>")

        # The data object should be an array of tuples of conditions and observations,
        # in our case the tuples will be of the form (tag_(i),tag_(i+1)).
        # DON'T FORGET TO ADD THE START SYMBOL <s> and the END SYMBOL </s>

   #     for s in tagged_sentences:
         #   (["<s>"] + s + ["</s>"])

        # tagged_sentencts: list(list(str or tuple))
       # tagGenerators=(((s[i][1],s[i+1][1]) for i in range(len(s)-1)) for s in tagged_sentences)

        # tagGenerators is an iterator of iterators of pairs of tags
      #  data = itertools.chain.from_iterable(tagGenerators)

        # TODO compute the transition model

        transition_FD = ConditionalFreqDist(data)

        lidstone_estimator = lambda fd: LidstoneProbDist(fd, 0.01, fd.B() + 1)
        self.transition_PD = ConditionalProbDist(transition_FD, lidstone_estimator)

    #    print (data)

        return self.transition_PD

    def test_emission(self):
        print ("test emission")
        transition_PD = self.transition_model(self.train_data)
        t1 = -self.emission_PD['NOUN'].logprob('fulton')         # the printed result is positive = logprob return negatives
        print(t1)

    def test_transition(self):
        print ("test transition")
        transition_PD = self.transition_model(self.train_data)
        t1 = -transition_PD['<s>'].logprob('NOUN')
        t2 = -transition_PD['VERB'].logprob('</s>')
        t3 = -transition_PD['NOUN'].logprob('VERB')
        print(t1,t2,t3)

    # Train the HMM
    def train(self):
        """
        Trains the HMM from the training data
        """
        self.emission_model(self.train_data)
        self.transition_model(self.train_data)

    # Part B: Implementing the Viterbi algorithm.

    # Initialise data structures for tagging a new sentence.
    # Describe the data structures with comments.
    # Use the models stored in the variables: self.emission_PD and self.transition_PD
    # Input: first word in the sentence to tag
    def initialise(self, observation):
        """
        Initialise data structures for tagging a new sentence.

        :param observation: the first word in the sentence to tag
        :type observation: str
        """

        # use costs (-log-base-2 probabilities)

        # viterbi is a list if libraries, i want it to store a T*N table
        # viterbi[time step][ending state]
        self.viterbi = [{}]

        # backpointer library
        self.backpointer = {}   # a list of tags

        # At initialise, cost with +logprob or *prob?
        for state in self.states:
           #  transition from <s> to observation
           # self.viterbi[0][state] = self.transition_PD["<s>"].prob(state) * self.transition_PD[state].prob(observation)

            self.viterbi[0][state] = self.transition_PD["<s>"].logprob(state) + self.emission_PD[state].logprob(observation)

            self.backpointer[state] = [state]

    # Tag a new sentence using the trained model and already initialised data structures.
    # Use the models stored in the variables: self.emission_PD and self.transition_PD.
    # Update the self.viterbi and self.backpointer datastructures.
    # Describe your implementation with comments.
    # Input: list of words
    def tag(self, observations):
        """
        Tag a new sentence using the trained model and already initialised data structures.

        :param observations: List of words (a sentence) to be tagged
        :type observations: list(str)
        :return: List of tags corresponding to each word of the input
        """
        tags = []
        index = 0
        current_decision = []             #   0.8959

        for t in range(1, len(observations)):
            self.viterbi.append({})
            newbackpointer = {}   # index-state key-the list of my states

            for state in self.states:

                # viterbi min
                # logprob return negative numbers, adding more negative value => want a result closer to + => max

                (prob,prob_state) = max(
                    [(self.viterbi[t-1][previous_state] + self.transition_PD[previous_state].logprob(state)
                      + self.emission_PD[state].logprob(observations[t]),previous_state) for previous_state in self.states])

                self.viterbi[t][state] = prob     # update the probability

                # backpointer
                newbackpointer[state] = self.backpointer[prob_state] + [state]

            self.backpointer = newbackpointer

        # Return the tag sequence corresponding to the best path as a list.

        # viterbi[time step][ending state]
        # choose the best match

        # termination cost
        for state in self.states:
            self.viterbi[len(observations) -1][state] += self.transition_PD["<\s>"].logprob(state)
     #   print(self.viterbi[len(observations) -1][state])   # like -200

        (probability,state) = max([(self.viterbi[len(observations) -1][state], state) for state in self.states])

        # Reconstruct the tag sequence using the backpointer list.
        # Return the tag sequence corresponding to the best path as a list.
        tags = self.backpointer[state]

        return tags

def answer_question4b():
    """ Report a tagged sequence that is incorrect
    :rtype: str
    :return: your answer [max 280 chars]"""

    # entries saves the first 10 incorrectly tagged sentences with their correct version
    entries = []
    incorrect = []
    for sentence in test_data_universal:
        s = [word.lower() for (word, tag) in sentence]
        model.initialise(s[0])
        tags = model.tag(s)

        # append till 10 entries
        for ((word,gold),tag) in zip(sentence,tags):
            if tag != gold:
                incorrect.append(tags)
                entries.append(sentence)
                break

        if(len(entries) >= 10):
            break

    # to print the zip file
  # print('length of entries is %f\n'%len(entries))
  # for e,o in zip(entries,incorrect):
  #     print(e)
  #     print(o)

    tagged_sequence = incorrect[0]
    correct_sequence = entries[0]

    # Why do you think the tagger tagged this example incorrectly?
    answer =  inspect.cleandoc("The Fulton County, if tagged correctly, should be DET NOUN NOUN, while tagger returns DET ADJ NOUN. Fulton is tagged wrong because it is tagged highly based on its previous word, however, in this case Fulton County should be regarded as a multiple-word phrase with both being NOUN")[0:280]

    return tagged_sequence, correct_sequence, answer

def answer_question5():
    """Suppose you have a hand-crafted grammar that has 100% coverage on
        constructions but less than 100% lexical coverage.
        How could you use a POS tagger to ensure that the grammar
        produces a parse for any well-formed sentence,
        even when it doesn't recognise the words within that sentence?

    :rtype: str
    :return: your answer [max 500 chars]"""

    return inspect.cleandoc("Using Lidstone and negative log probability, the model returns us the tag which is most probable given the tag of the previous word. If my tagger does recognize the word, it probably does better because we analyze the current state by transition and emission model. It may not do better if there is ambiguity of which tag the word could have. Given a word unrecognized, my approach might not be better because we cannot infer the state with emission model being considered P(o|state).")[0:500]

# Useful for testing
def isclose(a, b, rel_tol=1e-09, abs_tol=0.0):
    # http://stackoverflow.com/a/33024979
    return abs(a - b) <= max(rel_tol * max(abs(a), abs(b)), abs_tol)

def answers():
    global tagged_sentences_universal, test_data_universal, \
           train_data_universal, model, test_size, train_size, ttags, \
           correct, incorrect, accuracy, \
           good_tags, bad_tags, answer4b, answer5

    # Load the Brown corpus with the Universal tag set.
    tagged_sentences_universal = brown.tagged_sents(categories='news', tagset='universal')

    # Divide corpus into train and test data.
    test_size = 1000
    train_size = len(tagged_sentences_universal) - 1000

    test_data_universal = tagged_sentences_universal[:test_size]
    train_data_universal = tagged_sentences_universal[-train_size:]

    # Create instance of HMM class and initialise the training and test sets.
    model = HMM(train_data_universal, test_data_universal)

    # Train the HMM.
    model.train()

    # Inspect the model to see if emission_PD and transition_PD look plausible
    print('states: %s\n'%model.states)
    # Add other checks

    ######
    # Try the model, and test its accuracy [won't do anything useful
    #  until you've filled in the tag method
    ######

    # self designed tests

 #   model.test_emission()

 #   model.test_transition()

    s='the cat in the hat came back'.split()
  #  s='Tell me olo cat is gooood'.split()
    model.initialise(s[0])
    ttags = model.tag(s)
    print("Tag a trial sentence")
    print(list(zip(s,ttags)))

    # check the model's accuracy (% correct) using the test set
    correct = 0
    incorrect = 0

    for sentence in test_data_universal:
        s = [word.lower() for (word, tag) in sentence]
        model.initialise(s[0])
        tags = model.tag(s)

        for ((word,gold),tag) in zip(sentence,tags):
            if tag == gold:
                correct += 1
            else:
                incorrect += 1

    accuracy = (correct / (correct + incorrect))
    print('Tagging accuracy for test set of %s sentences: %.4f'%(test_size,accuracy))

    # Print answers for 4b and 5
    bad_tags, good_tags, answer4b = answer_question4b()
    print('\nAn incorrect tagged sequence is:')
    print(bad_tags)
    print('The correct tagging of this sentence would be:')
    print(good_tags)
    print('\nA possible reason why this error may have occurred is:')
    print(answer4b[:280])
    answer5=answer_question5()
    print('\nFor Q5:')
    print(answer5[:500])

if __name__ == '__main__':
    answers()


import json
from yahoo_fin.stock_info import get_day_gainers, get_day_losers
import sys
def extract_stock_info(stock_data):
    stock_info = {}
    for index, row in stock_data.iterrows():
        price = row['Price (Intraday)']
        stock_info[row['Symbol']] = {
            'Price': price,
            'Price Gain': row['Change'],
            'Price Gain (%)': (row['Change'] / (price - row['Change'])) * 100 if price - row['Change'] != 0 else 0
        }
    return stock_info

# Get top gainers and extract stock info
gainers_data = get_day_gainers()
gainers_info = extract_stock_info(gainers_data)

# Get top losers and extract stock info
losers_data = get_day_losers()
losers_info = extract_stock_info(losers_data)

# Merge gainers and losers info
merged_info = {'Top Gainers': gainers_info, 'Top Losers': losers_info}

print(json.dumps(merged_info));
sys.stdout.flush()

# # Write merged info to JSON file
# with open('top_gainers_losers.json', 'w') as file:
#     json.dump(merged_info, file, indent=4)

# print("Top gainers and losers merged and saved to a JSON file.")


from gpiozero import Servo, PWMOutputDevice
from gpiozero.pins.pigpio import PiGPIOFactory
from pyPS4Controller.controller import Controller
from multiprocessing import Process
import os, time
from fsm import *
from state import *
from vehicle import *
MR_FW = 17
MR_BW = 27
ML_FW = 23
ML_BW = 24
STEER_PIN = 18
STEER_MAX = (-0.8,0.8)
FWD_MAX = 1.0
BWD_MAX = 0.9
COLOURS = {"idle":[0,255,0],"playing":[255,50,100],"break":[255,0,0]}

def num_to_range(num, inMin, inMax, outMin, outMax):
  return outMin + (float(num - inMin) / float(inMax - inMin) * (outMax - outMin))

class MyController(Controller):
    def __init__(self, vehicle:vehicle, *args, **kwargs):
        Controller.__init__(self, *args, **kwargs)
        self.vehicle = vehicle
        #self.vehicle.change_state("recon")
        self.steering = Servo(STEER_PIN, pin_factory=PiGPIOFactory())
        self.ml_fw = PWMOutputDevice(ML_FW)
        self.ml_bw = PWMOutputDevice(ML_BW)
        self.mr_fw = PWMOutputDevice(MR_FW)
        self.mr_bw = PWMOutputDevice(MR_BW)
        self.set_led_colour(COLOURS["idle"])

    def set_led_colour(self, colour):
        # Use bash to set LED colour for right permissions
        cmd = f"/home/pi/ExArb/RRR/leds.sh -r{colour[0]} -g{colour[1]} -b{colour[2]}"
        os.system(cmd)
    '''
    def on_circle_press(self):
        current_state = self.vehicle.get_current_state()
        self.set_led_colour(COLOURS["playing"])
        if current_state == "mobile":
            self.vehicle.change_state("idle")

        elif current_state == "idle":
            self.set_led_colour(COLOURS["break"])
            self.vehicle.change_state("recon")

    def on_square_press(self):
        current_state = self.vehicle.get_current_state()
        self.set_led_colour(COLOURS["idle"])

        if current_state == "recon":
            self.vehicle.change_state("idle")

        elif current_state == "idle":
            self.vehicle.change_state("mobile")
    '''

    def on_R2_press(self, value):
        current_state = self.vehicle.get_current_state()
        if current_state == "mobile":
            self.drive(value)

    def on_R2_release(self):
        current_state = self.vehicle.get_current_state()
        if current_state == "mobile":
            self.halt()

    def on_L2_press(self, value):
        current_state = self.vehicle.get_current_state()
        if current_state == "mobile":
            self.drive(value, False)

    def on_L2_release(self):
        current_state = self.vehicle.get_current_state()
        if current_state == "mobile":
            self.halt()

    def on_x_press(self):
        current_state = self.vehicle.get_current_state()
        self.set_led_colour(COLOURS["break"])
        if current_state == "mobile":
            self.halt()

    def on_x_release(self):
        current_state = self.vehicle.get_current_state()
        if current_state == "mobile":
            self.set_led_colour(COLOURS["idle"])

    def steer(self, value):
        current_state = self.vehicle.get_current_state()
        if current_state == "mobile":
            value = num_to_range(value, -32767, 32767, STEER_MAX[0], STEER_MAX[1])
            self.steering.value = value

    def drive(self, value, fwd=True):
        max = FWD_MAX if fwd else BWD_MAX
        value = num_to_range(value, -32767, 32767, 0, max)
        if fwd:
            self.ml_bw.value = 0
            self.mr_bw.value = 0
            self.ml_fw.value = value
            self.mr_fw.value = value
        else:
            self.ml_fw.value = 0
            self.mr_fw.value = 0
            self.ml_bw.value = value
            self.mr_bw.value = value

    def halt(self):
        self.ml_fw.value = 0
        self.mr_fw.value = 0
        self.ml_bw.value = 0
        self.mr_bw.value = 0
        time.sleep(0.1)
        self.set_led_colour(COLOURS["idle"])

    def on_L3_left(self, value):
        current_state = self.vehicle.get_current_state()
        if current_state == "mobile":
            self.steer(-abs(value))

    def on_L3_right(self, value):
        current_state = self.vehicle.get_current_state()
        if current_state == "mobile":
            self.steer(value)

    def on_L3_x_at_rest(self):
        current_state = self.vehicle.get_current_state()
        if current_state == "mobile":
            self.steer(0)

    def our_listen(self, vehicle:vehicle):
        self.vehicle = vehicle
        self.vehicle.change_state('mobile')
        self.listen()

def run_controller(vehicle:vehicle):
    controller = MyController(vehicle, interface="/dev/input/js0", connecting_using_ds4drv=False)
    print("före listen")
    controller.listen()
    print("efter listen")

'''
if __name__ == '__main__':
    my_fsm = fsm([idle(), recon(), mobile()])
    p1 = Process(target=run_controller(my_fsm))
    p1.start()
    run = True
    while run:
        print("asd")
'''


import csv
import os
import re

import frappe
import frappe.permissions
from frappe import _
from frappe.core.doctype.access_log.access_log import make_access_log
from frappe.model.utils import is_virtual_doctype
from frappe.utils import cint, cstr, format_datetime, format_duration, formatdate, parse_json
from frappe.utils.csvutils import UnicodeWriter

reflags = {"I": re.I, "L": re.L, "M": re.M, "U": re.U, "S": re.S, "X": re.X, "D": re.DEBUG}

def get_data_keys():
	return frappe._dict(
		{
			"data_separator": _("Start entering data below this line"),
			"main_table": _("Table") + ":",
			"parent_table": _("Parent Table") + ":",
			"columns": _("Column Name") + ":",
			"doctype": _("DocType") + ":",
		}
	)

@frappe.whitelist()
def export_data(
	doctype=None,
	parent_doctype=None,
	all_doctypes=True,
	with_data=False,
	select_columns=None,
	file_type="CSV",
	template=False,
	filters=None,
	export_without_column_meta=False,
):
	_doctype = doctype
	if isinstance(_doctype, list):
		_doctype = _doctype[0]
	make_access_log(
		doctype=_doctype,
		file_type=file_type,
		columns=select_columns,
		filters=filters,
		method=parent_doctype,
	)

	template_bool = template
	if isinstance(template, str):
		template_bool = template.lower() == "true"

	export_without_column_meta_bool = export_without_column_meta
	if isinstance(export_without_column_meta, str):
		export_without_column_meta_bool = export_without_column_meta.lower() == "true"

	exporter = DataExporter(
		doctype=doctype,
		parent_doctype=parent_doctype,
		all_doctypes=all_doctypes,
		with_data=with_data,
		select_columns=select_columns,
		file_type=file_type,
		template=template_bool,
		filters=filters,
		export_without_column_meta=export_without_column_meta_bool,
	)
	exporter.build_response()

class DataExporter:
	def __init__(
		self,
		doctype=None,
		parent_doctype=None,
		all_doctypes=True,
		with_data=False,
		select_columns=None,
		file_type="CSV",
		template=False,
		filters=None,
		export_without_column_meta=False,
	):
		self.doctype = doctype
		self.parent_doctype = parent_doctype
		self.all_doctypes = all_doctypes
		self.with_data = cint(with_data)
		self.select_columns = select_columns
		self.file_type = file_type
		self.template = template
		self.filters = filters
		self.export_without_column_meta = export_without_column_meta
		self.data_keys = get_data_keys()

		self.prepare_args()

	def prepare_args(self):
		if self.select_columns:
			self.select_columns = parse_json(self.select_columns)
		if self.filters:
			self.filters = parse_json(self.filters)

		self.docs_to_export = {}
		if self.doctype:
			if isinstance(self.doctype, str):
				self.doctype = [self.doctype]

			if len(self.doctype) > 1:
				self.docs_to_export = self.doctype[1]
			self.doctype = self.doctype[0]

		if not self.parent_doctype:
			self.parent_doctype = self.doctype

		self.column_start_end = {}

		if self.all_doctypes:
			self.child_doctypes = [
				dict(doctype=df.options, parentfield=df.fieldname)
				for df in frappe.get_meta(self.doctype).get_table_fields()
			]

	def build_response(self):
		self.writer = UnicodeWriter()
		self.name_field = "parent" if self.parent_doctype != self.doctype else "name"

		if self.template:
			self.add_main_header()

		# No need of empty row at the start
		if not self.export_without_column_meta:
			self.writer.writerow([""])

		self.tablerow = [self.data_keys.doctype]
		self.labelrow = [_("Column Labels:")]
		self.fieldrow = [self.data_keys.columns]
		self.mandatoryrow = [_("Mandatory:")]
		self.typerow = [_("Type:")]
		self.inforow = [_("Info:")]
		self.columns = []

		self.build_field_columns(self.doctype)

		if self.all_doctypes:
			for d in self.child_doctypes:
				self.append_empty_field_column()
				if (
					self.select_columns and self.select_columns.get(d["doctype"], None)
				) or not self.select_columns:
					# if atleast one column is selected for this doctype
					self.build_field_columns(d["doctype"], d["parentfield"])

		self.add_field_headings()
		self.add_data()
		if self.with_data and not self.data:
			frappe.respond_as_web_page(
				_("No Data"), _("There is no data to be exported"), indicator_color="orange"
			)

		if self.file_type == "Excel":
			self.build_response_as_excel()
		else:
			# write out response as a type csv
			frappe.response["result"] = cstr(self.writer.getvalue())
			frappe.response["type"] = "csv"
			frappe.response["doctype"] = self.doctype

	def add_main_header(self):
		self.writer.writerow([_("Data Import Template")])
		self.writer.writerow([self.data_keys.main_table, self.doctype])

		if self.parent_doctype != self.doctype:
			self.writer.writerow([self.data_keys.parent_table, self.parent_doctype])
		else:
			self.writer.writerow([""])

		self.writer.writerow([""])
		self.writer.writerow([_("Notes:")])
		self.writer.writerow([_("Please do not change the template headings.")])
		self.writer.writerow([_("First data column must be blank.")])
		self.writer.writerow(
			[_('If you are uploading new records, leave the "name" (ID) column blank.')]
		)
		self.writer.writerow(
			[_('If you are uploading new records, "Naming Series" becomes mandatory, if present.')]
		)
		self.writer.writerow(
			[
				_(
					"Only mandatory fields are necessary for new records. You can delete non-mandatory columns if you wish."
				)
			]
		)
		self.writer.writerow([_("For updating, you can update only selective columns.")])
		self.writer.writerow(
			[_("You can only upload upto 5000 records in one go. (may be less in some cases)")]
		)
		if self.name_field == "parent":
			self.writer.writerow([_('"Parent" signifies the parent table in which this row must be added')])
			self.writer.writerow(
				[_('If you are updating, please select "Overwrite" else existing rows will not be deleted.')]
			)

	def build_field_columns(self, dt, parentfield=None):
		meta = frappe.get_meta(dt)

		# build list of valid docfields
		tablecolumns = []
		table_name = "tab" + dt
		for f in frappe.db.get_table_columns_description(table_name):
			field = meta.get_field(f.name)
			if field and (
				(self.select_columns and f.name in self.select_columns[dt]) or not self.select_columns
			):
				tablecolumns.append(field)

		tablecolumns.sort(key=lambda a: int(a.idx))

		_column_start_end = frappe._dict(start=0)

		if dt == self.doctype:
			if (meta.get("autoname") and meta.get("autoname").lower() == "prompt") or (self.with_data):
				self._append_name_column()

			# if importing only child table for new record, add parent field
			if meta.get("istable") and not self.with_data:
				self.append_field_column(
					frappe._dict(
						{
							"fieldname": "parent",
							"parent": "",
							"label": "Parent",
							"fieldtype": "Data",
							"reqd": 1,
							"info": _("Parent is the name of the document to which the data will get added to."),
						}
					),
					True,
				)

			_column_start_end = frappe._dict(start=0)
		else:
			_column_start_end = frappe._dict(start=len(self.columns))

			if self.with_data:
				self._append_name_column(dt)

		for docfield in tablecolumns:
			self.append_field_column(docfield, True)

		# all non mandatory fields
		for docfield in tablecolumns:
			self.append_field_column(docfield, False)

		# if there is one column, add a blank column (?)
		if len(self.columns) - _column_start_end.start == 1:
			self.append_empty_field_column()

		# append DocType name
		self.tablerow[_column_start_end.start + 1] = dt

		if parentfield:
			self.tablerow[_column_start_end.start + 2] = parentfield

		_column_start_end.end = len(self.columns) + 1

		self.column_start_end[(dt, parentfield)] = _column_start_end

	def append_field_column(self, docfield, for_mandatory):
		if not docfield:
			return
		if for_mandatory and not docfield.reqd:
			return
		if not for_mandatory and docfield.reqd:
			return
		if docfield.fieldname in ("parenttype", "trash_reason"):
			return
		if docfield.hidden:
			return
		if (
			self.select_columns
			and docfield.fieldname not in self.select_columns.get(docfield.parent, [])
			and docfield.fieldname != "name"
		):
			return

		self.tablerow.append("")
		self.fieldrow.append(docfield.fieldname)
		self.labelrow.append(_(docfield.label))
		self.mandatoryrow.append(docfield.reqd and "Yes" or "No")
		self.typerow.append(docfield.fieldtype)
		self.inforow.append(self.getinforow(docfield))
		self.columns.append(docfield.fieldname)

	def append_empty_field_column(self):
		self.tablerow.append("~")
		self.fieldrow.append("~")
		self.labelrow.append("")
		self.mandatoryrow.append("")
		self.typerow.append("")
		self.inforow.append("")
		self.columns.append("")

	@staticmethod
	def getinforow(docfield):
		"""make info comment for options, links etc."""
		if docfield.fieldtype == "Select":
			if not docfield.options:
				return ""
			else:
				return _("One of") + ": %s" % ", ".join(filter(None, docfield.options.split("\n")))
		elif docfield.fieldtype == "Link":
			return "Valid %s" % docfield.options
		elif docfield.fieldtype == "Int":
			return "Integer"
		elif docfield.fieldtype == "Check":
			return "0 or 1"
		elif docfield.fieldtype in ["Date", "Datetime"]:
			return cstr(frappe.defaults.get_defaults().date_format)
		elif hasattr(docfield, "info"):
			return docfield.info
		else:
			return ""

	def add_field_headings(self):
		if not self.export_without_column_meta:
			self.writer.writerow(self.tablerow)

		# Just include Labels in the first row
		self.writer.writerow(self.labelrow)

		if not self.export_without_column_meta:
			self.writer.writerow(self.fieldrow)
			self.writer.writerow(self.mandatoryrow)
			self.writer.writerow(self.typerow)
			self.writer.writerow(self.inforow)

		if self.template:
			self.writer.writerow([self.data_keys.data_separator])

	def add_data(self):
		from frappe.query_builder import DocType

		if self.template and not self.with_data:
			return

		frappe.permissions.can_export(self.parent_doctype, raise_exception=True)

		# sort nested set doctypes by `lft asc`
		order_by = None
		table_columns = frappe.db.get_table_columns(self.parent_doctype)
		if "lft" in table_columns and "rgt" in table_columns:
			order_by = f"`tab{self.parent_doctype}`.`lft` asc"
		# get permitted data only
		self.data = frappe.get_list(
			self.doctype, fields=["*"], filters=self.filters, limit_page_length=None, order_by=order_by
		)

		for doc in self.data:
			op = self.docs_to_export.get("op")
			names = self.docs_to_export.get("name")

			if names and op:
				if op == "=" and doc.name not in names:
					continue
				elif op == "!=" and doc.name in names:
					continue
			elif names:
				try:
					sflags = self.docs_to_export.get("flags", "I,U").upper()
					flags = 0
					for a in re.split(r"\W+", sflags):
						flags = flags | reflags.get(a, 0)

					c = re.compile(names, flags)
					m = c.match(doc.name)
					if not m:
						continue
				except Exception:
					if doc.name not in names:
						continue
			# add main table
			rows = []

			self.add_data_row(rows, self.doctype, None, doc, 0)

			if self.all_doctypes:
				# add child tables
				for c in self.child_doctypes:
					if is_virtual_doctype(c["doctype"]):
						continue
					child_doctype_table = DocType(c["doctype"])
					data_row = (
						frappe.qb.from_(child_doctype_table)
						.select("*")
						.where(child_doctype_table.parent == doc.name)
						.where(child_doctype_table.parentfield == c["parentfield"])
						.orderby(child_doctype_table.idx)
					)
					for ci, child in enumerate(data_row.run(as_dict=True)):
						self.add_data_row(rows, c["doctype"], c["parentfield"], child, ci)

			for row in rows:
				self.writer.writerow(row)

	def add_data_row(self, rows, dt, parentfield, doc, rowidx):
		d = doc.copy()
		meta = frappe.get_meta(dt)
		if self.all_doctypes:
			d.name = f'"{d.name}"'

		if len(rows) < rowidx + 1:
			rows.append([""] * (len(self.columns) + 1))
		row = rows[rowidx]

		_column_start_end = self.column_start_end.get((dt, parentfield))

		if _column_start_end:
			for i, c in enumerate(self.columns[_column_start_end.start : _column_start_end.end]):
				df = meta.get_field(c)
				fieldtype = df.fieldtype if df else "Data"
				value = d.get(c, "")
				if value:
					if fieldtype == "Date":
						value = formatdate(value)
					elif fieldtype == "Datetime":
						value = format_datetime(value)
					elif fieldtype == "Duration":
						value = format_duration(value, df.hide_days)

				row[_column_start_end.start + i + 1] = value

	def build_response_as_excel(self):
		from frappe.desk.utils import provide_binary_file
		from frappe.utils.xlsxutils import make_xlsx

		filename = frappe.generate_hash(length=10)
		with open(filename, "wb") as f:
			f.write(cstr(self.writer.getvalue()).encode("utf-8"))
		f = open(filename)
		reader = csv.reader(f)
		xlsx_file = make_xlsx(reader, "Data Import Template" if self.template else "Data Export")

		f.close()
		os.remove(filename)

		provide_binary_file(self.doctype, "xlsx", xlsx_file.getvalue())

	def _append_name_column(self, dt=None):
		self.append_field_column(
			frappe._dict(
				{
					"fieldname": "name" if dt else self.name_field,
					"parent": dt or "",
					"label": "ID",
					"fieldtype": "Data",
					"reqd": 1,
				}
			),
			True,
		)


from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from song_namescollection import namesCollections
import sys

# Where you access Youtube and collect the links and appropriate name for mp3 conversion

class Download(namesCollections):

    def goToYoutubeAndSearch(self, search):
        self.searchresult = search
        self.driver.get("https://youtube.com")
        time.sleep(1)
        self.Search(search)
        time.sleep(1)

        return self.SearchResult()

    def Search(self, search):

        s = self.driver.find_element_by_id("search")
        s.send_keys(search)
        s.send_keys(Keys.RETURN)

    def SearchResult(self):
        try:
            resultcontainer = WebDriverWait(self.driver, 10).until(
                EC.presence_of_all_elements_located(
                    (By.CLASS_NAME, "ytd-item-section-renderer"))
                # EC.presence_of_elements_located((By.CLASS_NAME, "KKHQ8c"))
            )

            # print(resultcontainer[3])
            results = resultcontainer[3].find_elements_by_tag_name(
                "ytd-video-renderer")

            tmp = []
            counter = 0
            for index, i in enumerate(results):

                ls = i.text.split("\n")
                href = i.find_element_by_id("thumbnail")
                authors = i.find_elements_by_class_name("yt-simple-endpoint")
                ls.append(href.get_attribute("href"))
                author = authors[3].text
                timetag = i.find_elements_by_class_name(
                    "ytd-thumbnail-overlay-time-status-renderer")

                try:

                    time = timetag[1]
                    if "hour" in time.get_attribute("aria-label"):
                        continue
                    ls.append(time.get_attribute("aria-label"))
                    title = ls[0]
                    timestamp = ls[-1].split(", ")
                    link = ls[-2]
                    # print(timestamp[1][0], title.lower(), self.search in title.lower(), len(
                    #     timestamp), timestamp, end="\n")
                    if counter > 30:
                        print(counter, 2)
                        break
                    if len(timestamp) <= 2 and self.searchresult.lower() in title.lower() and int(timestamp[0].split(" ")[0]) <= 6:
                        counter += 1

                        tmp.append(
                            {"title": title, "timestamp": timestamp, "link": link, "author": author, "searchresult": self.searchresult})
                except:
                    continue
            return tmp

        except:
            print(sys.exc_info())
            # self.driver.quit()

# test = Download()
# print(test.goToYoutubeAndSearch("who you say I am"))


import cadquery as cq

from lib import cqlib

cqlib.setup(locals())

# Alpha cutout is 10x10 mm
# Alpha spacing is 14.25 x 14.20 mm (width / height)

# Num cutout diameter is 10 mm

result = (
    cq.Workplane()
    .rect(10, 10)
    .extrude(10)
    .faces('<Y')
    .workplane()
    .rect(5, 5)
    .extrude(3)

)
# result = (
#    cq.Workplane()
#    .rounded_rect(10, 10, 1)
#    .extrude(2)
#    .edges('>Z')
#    .fillet(1)
# )


# ---ROCK PAPER SCISSORS---

#PART 1

#Part 1 Answer: 10718

#Input data (these are pairs of letters):

#input1 = ```Input data goes here```

#Solution:

possible_endings_1 = {'A X' : 4, 'A Y' : 8, 'A Z' : 3, 'B X' : 1, 'B Y' : 5, 'B Z' : 9, 'C X' : 7, 'C Y': 2, 'C Z': 6}
#I created a dictionaries with every possible outcome and its corresponding score as key-value pairs.

strategy = input1.splitlines()
#get each line of the strategy input

print (sum([possible_endings_1[each] for each in strategy]))
#using the dictionary, parse through to get the score for each ending in the strategy, and find its sum.

#PART 2

#Part 2 Answer: 14652

#Input data same as part 1

possible_endings_2 = {'A X': 3, 'A Y': 4, 'A Z': 8, 'B X': 1, 'B Y': 5, 'B Z': 9, 'C X': 2, 'C Y': 6, 'C Z': 7}
#follow same logic to create dict of possible endings and scores.
#calculate cumulative score from win/draw/lose and the points you get from choosing Rock/Paper/Scissors.

print (sum([possible_endings_2[each] for each in strategy]))


import argparse
import os
import numpy as np
from sklearn.feature_extraction.text import CountVectorizer, TfidfTransformer
from sklearn.model_selection import GridSearchCV
from sklearn.pipeline import Pipeline, FeatureUnion
from sklearn.metrics import f1_score, make_scorer
from pk_classifier.bootstrap import read_in_distributional, simple_tokenizer, TextSelector
import xgboost as xgb
import pandas as pd
import joblib

HYPERPARAMETER_GRID = {
    'encoder__bow__vect__min_df': 2 ** np.arange(1, 10, 1),
    'clf__max_depth': 2 ** np.arange(1, 7, 1),
    'clf__colsample_bytree': [1 / 3, 2 / 3, 3 / 3],
}

def cross_validate_pk(training_embeddings: str, training_optimal_bow: str, training_labels: str, output_dir: str):
    all_features, all_labs = read_in_distributional(path_preproc=training_embeddings, path_labels=training_labels,
                                                    is_specter=False, path_optimal_bow=training_optimal_bow)
    all_labs = all_labs['label']
    rd_seed = 10042006

    # =====================================================================================================
    #               Define pipeline
    # ======================================================================================================
    hyp_grid = HYPERPARAMETER_GRID
    balancing_factor = all_labs.value_counts()["Not Relevant"] / all_labs.value_counts()["Relevant"]
    encoder = CountVectorizer(tokenizer=simple_tokenizer, ngram_range=(1, 1), lowercase=False, preprocessor=None)
    normalizer = TfidfTransformer(norm="l1", use_idf=False)
    decoder = xgb.XGBClassifier(random_state=rd_seed,
                                n_estimators=148,  # Median value of the optimal n_estimators across 200 bootstrapping
                                # iterations when early stopping was applied
                                objective='binary:logistic',
                                learning_rate=0.1,
                                scale_pos_weight=balancing_factor, nthread=-1, n_jobs=-1, )

    EncDecPip = Pipeline([
        ('encoder', FeatureUnion(transformer_list=[
            ('bow', Pipeline([
                ('selector', TextSelector('BoW_Ready', emb=False)),
                ('vect', encoder),
                ('norm', normalizer)
            ])
             ),
            ('abs', Pipeline([
                ('selector', TextSelector('embedding', emb=True))
            ]))
        ])),
        ('clf', decoder)
    ])

    f1_scorer = make_scorer(f1_score, pos_label="Relevant")
    grid_obj = GridSearchCV(EncDecPip, hyp_grid, scoring=f1_scorer, cv=5, n_jobs=-1, verbose=51)
    # Train
    model_trained = grid_obj.fit(all_features, all_labs)
    best_param = model_trained.best_params_
    best_param['Mean F1-score'] = model_trained.best_score_
    best_param['Time'] = model_trained.refit_time_
    print("Optimal parameter combination ", best_param)
    results_df = pd.DataFrame.from_dict(best_param, orient='index')
    # save your model and results
    results_df.to_pickle(os.path.join(output_dir, "cv_results.pkl"))
    joblib.dump(model_trained, os.path.join(output_dir, "cv_optimal_pipeline.pkl"))

def run(training_embeddings: str, training_optimal_bow: str, training_labels: str, output_dir: str):
    if not os.path.isdir(output_dir):
        os.makedirs(output_dir, exist_ok=True)
    cross_validate_pk(training_embeddings=training_embeddings, training_optimal_bow=training_optimal_bow,
                      training_labels=training_labels, output_dir=output_dir)

def main():
    parser = argparse.ArgumentParser()

    parser.add_argument("--training-embeddings",
                        type=str,
                        help="Parquet file with the embeddings of the training data.",
                        default="../data/encoded/biobert/training_biobert_avg.parquet")

    parser.add_argument("--training-optimal-bow",
                        type=str,
                        help="Path to the parquet file with the optimal BoW features of the training set.",
                        default="../data/encoded/ngrams/training_unigrams.parquet")

    parser.add_argument("--training-labels",
                        type=str,
                        help="Path to the CSV file containing the labels of the training data.",
                        default="../data/labels/training_labels.csv")

    parser.add_argument("--output-dir",
                        type=str,
                        help="Directory to save the CV results and output files.",
                        default="../data/results/final-pipeline")

    args = parser.parse_args()
    run(training_embeddings=args.training_embeddings, training_optimal_bow=args.training_optimal_bow,
        training_labels=args.training_labels, output_dir=args.output_dir)

if __name__ == '__main__':
    main()


from typing import Callable

from fastapi import (
    FastAPI,
    Request,
)
from fastapi.middleware.cors import CORSMiddleware
from fastapi_jwt_auth.exceptions import AuthJWTException
from fastapi_pagination import add_pagination

from core.apps.localization.middlewares import localization_middleware
from core.common.config import config
from core.common.exception_handlers import authjwt_exception_handler

API_V1_PREFIX = '/api/v1/'

class AppFactory:
    @classmethod
    def add_middleware(
        cls,
        app: FastAPI,
        protocol: str,
        middleware: Callable[[Request, Callable], None],
    ):
        app.middleware(protocol)(middleware)

    @classmethod
    def create_app(cls) -> FastAPI:
        """Returns the FastAPI app with instantiated DB."""
        app = FastAPI(
            debug=config.DEBUG_MODE,
            title='Classroom API',
            openapi_url='/api/openapi.json',
            docs_url='/api/docs',
        )

        app.add_middleware(
            CORSMiddleware,
            allow_origins=config.ALLOWED_CORS_ORIGINS,
            allow_credentials=True,
            allow_methods=['*'],
            allow_headers=['*'],
        )
        cls._register_views(app)
        cls.add_middleware(app, 'http', localization_middleware)

        app.exception_handler(AuthJWTException)(authjwt_exception_handler)

        add_pagination(app)
        return app

    @classmethod
    def _register_views(cls, app: FastAPI):
        from core.apps.attachments.views import router as attachment_router
        from core.apps.chat.views import router as chat_router
        from core.apps.classroom.views import router as classroom_router
        from core.apps.localization.views import router as localization_router
        from core.apps.users.views import router as user_router

        app.include_router(
            localization_router,
            prefix=''.join([API_V1_PREFIX, 'localization']),
        )
        app.include_router(
            user_router,
            prefix=''.join([API_V1_PREFIX, 'auth/user']),
        )
        app.include_router(
            classroom_router,
            prefix=''.join([API_V1_PREFIX, 'classroom']),
        )
        app.include_router(
            attachment_router,
            prefix=''.join([API_V1_PREFIX, 'attachments']),
        )
        app.include_router(
            chat_router,
            prefix=''.join([API_V1_PREFIX, 'chat']),
        )


from src.main.python.utils.row_cleaners_utils import domain_cleaner
import unittest

class TestDomainCleaner(unittest.TestCase):
    """
    Our basic test class
    """

    def test_domain_cleaner(self):
        """
        The actual test.
        Any method which starts with ``test_`` will considered as a test case.
        """
        res = domain_cleaner('com.scan.booster.memory')
        self.assertEqual(res,'scan.booster.memory')
        res = domain_cleaner('com.apalon.myclockfree')
        self.assertEqual(res,'apalon.myclockfree')
        res = domain_cleaner("com.https://www.'\x00\x11Hello'flash.comlight.brightest.BEACON'\x00\x11Hello'conQUESO437364525289.torch.comr")
        self.assertEqual(res,'helloflash.comlight.brightest.beaconhelloconqueso437364525289.torch.comr')
        res = domain_cleaner("com.com.otracoasa.com.helloflash.com/light.brightest/.beaconhelloconqueso437364525289.torch.comr")
        self.assertEqual(res,'helloflash.com')
        res = domain_cleaner("1564646165")
        self.assertEqual(res,'1564646165')
        res = domain_cleaner('498464684')
        self.assertEqual(res,'498464684')
        res = domain_cleaner("46\x01string87167681\x01string6")
        self.assertEqual(res,'46string87167681string6')
        res = domain_cleaner('www.mainDomain111/domain2/domain3.com')
        self.assertEqual(res,'maindomain111')
        res = domain_cleaner("com.com.otracoasa.com.https://www.'\x00\x11Hello'flash.com/light.brightest/.BEACON'\x00\x11Hello'")
        self.assertEqual(res,'helloflash.com')
        res = domain_cleaner("http://hello.domain.com")
        self.assertEqual(res,'domain.com')
        res = domain_cleaner("health.drinkwater.reminder}")
        self.assertEqual(res,'health.drinkwater.reminder')

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


# To find the team, we loop through each team object
# to find the boolean property win being toggled.
# If it is a tie, the function returns nothing
def get_winning_team(teams):
    for t in teams:
        if t['win']:
            return t['teamId']

# Prepares the objective arrays, similar to how
# `get_winning_team` operates. a first objective
# represents which team got the first one. For
# example, if Blue side killed another champion
# for first blood, objectives['champion']
# would equal to 100, so on so forth.
def get_objectives(teams):
    objectives = {
        'baron': None,
        'champion': None,
        'dragon': None,
        'inhibitor': None,
        'riftHerald': None,
        'tower': None
    }
    for t in teams:
        for objective, info in t['objectives'].items():
            # Get firsts
            if info['first']:
                objectives[objective] = t['teamId']
    # breakpoint()
    return objectives

def get_patch_version(patch):
    return ".".join(patch.split('.')[:2])

# Accepts a match DTO, and extracts relevant information regarding overall game statistics
def parse_match(match_dto):
    match_id = match_dto['metadata']['matchId']
    patch = get_patch_version(match_dto['info']['gameVersion'])
    game_duration = match_dto['info']['gameDuration']
    region = match_dto['info']['platformId']

    # Get the winning team
    winning_team = get_winning_team(match_dto['info']['teams'])
    objectives = get_objectives(match_dto['info']['teams'])

    return (
        match_id,
        patch,
        game_duration,
        region,
        winning_team,
        objectives['champion'],
        objectives['tower'],
        objectives['inhibitor'],
        objectives['baron'],
        objectives['dragon'],
        objectives['riftHerald'],
    )


from typing import Callable

import pytest
from httpx import AsyncClient, Headers
from logrich.logger_ import log  # noqa

from src.auth.conftest import Routs
from src.auth.tests.ads.conftest import insert_fake_ads, insert_fake_images

skip = False
# skip = True
reason = "Temporary off!"
pytestmark = pytest.mark.django_db(transaction=True, reset_sequences=True)

@pytest.mark.skipif(skip, reason=reason)
@pytest.mark.asyncio
async def test_list_ads_with_paginate(
    client: AsyncClient, routes: Routs, user_active_auth_headers: Headers, add_test_ad: Callable
) -> None:
    """Тест списка объявлений с пагинацией"""
    AMOUNT_ADS = 27
    SIZE = 5
    PAGE = 1

    await insert_fake_ads(amount_ads=AMOUNT_ADS)
    await insert_fake_images(amount_ads=AMOUNT_ADS)

    params = {"page": PAGE, "size": SIZE}

    resp = await client.get(routes.read_ads, params=params)
    log.debug(resp)
    data = resp.json()
    log.debug("список объявлений с пагинацией..", o=data)
    assert resp.status_code == 200
    assert data.get("total") == AMOUNT_ADS + 1
    # assert len(data) == 2
    # return
    assert len(data.get("items")) == SIZE
    assert data.get("page") == PAGE
    assert data.get("size") == SIZE


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

class Solution:
    def longestUnivaluePath(self, root: TreeNode) -> int:
        self.longest_length = 0

        def helper(node):
            # if the node is None or a leaf node, return 0
            if not node:
                return 0
            if not node.left and not node.right:
                return 0
            # left and right are the branch values that possibly form a longer path with its prescendants; so either of them would be kept
            left = helper(node.left)
            right = helper(node.right)
            if node.left:
                # if leftnode.val == parent.val, then it's possible to form a longer path with its parent
                if node.left.val == node.val:
                    left += 1
                else:
                    left = 0 # already not possible to form a path with its parent, so it's OK (and necessary) to set it to 0
            if node.right:
                if node.right.val == node.val:
                    right += 1
                else:
                    right = 0
            # if left + node + right form a non-zero path, should compare before passing the longer branch result
            self.longest_length = max(self.longest_length, left + right)
            # only pass the longer result to upper layer to see if could form longer path
            return max(left, right)

        helper(root)
        return self.longest_length


import logging

from flask import Blueprint, jsonify
from blueprint_api.dao.postsDAO import PostDAO

logging.basicConfig(level=logging.INFO, filename="api.log", filemode="w",
                    format="%(asctime)s %(levelname)s %(message)s")

postsDAO = PostDAO()

api_blueprint = Blueprint("api_blueprint",
                          __name__)

@api_blueprint.route("/api/posts")
def api_posts():
    posts = postsDAO.get_posts_all()
    logging.info(f"api/posts")
    return jsonify(posts)

@api_blueprint.route("/api/posts/<int:post_id>")
def api_post(post_id):
    post = postsDAO.get_post_by_pk(post_id)
    logging.info(f"api/posts/{post_id}")
    return jsonify(post)


from . import views
from django.urls import path, include

app_name = 'Signin'
urlpatterns = [
    path('', views.index, name = 'index'),
    path('login/', views.login, name='login'),
    path('gotoprofile/', views.gotoprofile, name = 'gotoprofile'),
    path('logoff/', views.logoff, name = 'logoff'),
    path('addCourse/<int:course_id>', views.addCourse, name='addCourse'),
    path('deleteCourse/<int:course_id>', views.deleteCourse, name = 'deleteCourse'),
    path('areatable/', views.areatable, name = 'areatable'),
    path('jobtable', views.jobtable, name = 'jobtable'),
    # path('search_course', views.search_course, name = 'search_course'),
    #path('profile/', views.profile, name='profile'),
    # path('changepassword/', views.changepassword, name = 'changepassword'),
    # path('updatepassword/', views.updatepassword, name = 'updatepassword'),

]


"""Regression test."""
import numpy as np
import json
import gw_eccentricity
from gw_eccentricity import load_data
from gw_eccentricity import measure_eccentricity

# locally it passs without problem but on github action, we need to set this tolerance
atol = 1e-9

def test_regression():
    """Regression test using all methods."""
    # List of all available methods
    available_methods = gw_eccentricity.get_available_methods()
    for method in available_methods:
        # Load regression data
        regression_data_file = f"test/regression_data/{method}_regression_data.json"
        # Load the regression data
        fl = open(regression_data_file, "r")
        regression_data = json.load(fl)
        fl.close()
        # waveform kwargs
        lal_kwargs = regression_data["waveform_kwargs"]
        # load waveform data
        dataDict = load_data.load_waveform(**lal_kwargs)
        extra_kwargs = regression_data["extra_kwargs"]

        # Try evaluating at times where regression data are saved
        regression_data_at_tref = regression_data["tref"]
        tref_in = regression_data_at_tref["time"]
        gwecc_dict = measure_eccentricity(
            tref_in=tref_in,
            method=method,
            dataDict=dataDict,
            extra_kwargs=extra_kwargs)
        tref_out = gwecc_dict["tref_out"]
        ecc_ref = gwecc_dict["eccentricity"]
        meanano_ref = gwecc_dict["mean_anomaly"]
        # Compare the measured data with the saved data
        np.testing.assert_allclose(
            ecc_ref, regression_data_at_tref["eccentricity"],
            atol=atol,
            err_msg="measured and saved eccentricity at saved times do not match.")
        np.testing.assert_allclose(
            meanano_ref, regression_data_at_tref["mean_anomaly"],
            atol=atol,
            err_msg="measured and saved mean anomaly at saved times do not match.")

        # Try evaluating at frequencies where regression data are saved
        regression_data_at_fref = regression_data["fref"]
        fref_in = regression_data_at_fref["frequency"]
        gwecc_dict = measure_eccentricity(
            fref_in=fref_in,
            method=method,
            dataDict=dataDict,
            extra_kwargs=extra_kwargs)
        fref_out = gwecc_dict["fref_out"]
        ecc_ref = gwecc_dict["eccentricity"]
        meanano_ref = gwecc_dict["mean_anomaly"]
        # Compare the measured data with the saved data
        np.testing.assert_allclose(
            ecc_ref, regression_data_at_fref["eccentricity"],
            atol=atol,
            err_msg="measured and saved eccentricity at saved frequencies do not match.")
        np.testing.assert_allclose(
            meanano_ref, regression_data_at_fref["mean_anomaly"],
            atol=atol,
            err_msg="measured and saved mean anomaly at saved frequencies do not match.")