import endpoints
from protorpc import message_types
from protorpc import messages
from protorpc import remote

from multitest_transport.api import base
from multitest_transport.models import messages as mtt_messages
from multitest_transport.models import ndb_models

@base.MTT_API.api_class(resource_name='test', path='tests')
class TestApi(remote.Service):
  """A handler for Test API."""

  @base.ApiMethod(
      endpoints.ResourceContainer(message_types.VoidMessage),
      mtt_messages.TestList, path='/tests', http_method='GET',
      name='list')
  def List(self, request):
    """Lists test suites."""
    tests = list(ndb_models.Test.query().order(ndb_models.Test.name))
    test_msgs = mtt_messages.ConvertList(tests, mtt_messages.Test)
    return mtt_messages.TestList(tests=test_msgs)

  @base.ApiMethod(
      endpoints.ResourceContainer(mtt_messages.Test),
      mtt_messages.Test, path='/tests', http_method='POST',
      name='create')
  def Create(self, request):
    """Creates a test suite.

    Body:
      Test suite data
    """
    test = mtt_messages.Convert(
        request, ndb_models.Test, from_cls=mtt_messages.Test)
    test.put()
    return mtt_messages.Convert(test, mtt_messages.Test)

  @base.ApiMethod(
      endpoints.ResourceContainer(
          message_types.VoidMessage,
          test_id=messages.StringField(1, required=True)),
      mtt_messages.Test, path='{test_id}', http_method='GET',
      name='get')
  def Get(self, request):
    """Fetches a test suite.

    Parameters:
      test_id: Test ID, or zero for an empty test suite
    """
    if request.test_id == '0':
      # For ID 0, return an empty test object to use as a template in UI.
      test = ndb_models.Test(name='')
    else:
      test = mtt_messages.ConvertToKey(ndb_models.Test, request.test_id).get()
    if not test:
      raise endpoints.NotFoundException(
          'no test found for ID %s' % request.test_id)
    return mtt_messages.Convert(test, mtt_messages.Test)

  @base.ApiMethod(
      endpoints.ResourceContainer(
          mtt_messages.Test, test_id=messages.StringField(1, required=True)),
      mtt_messages.Test, path='{test_id}', http_method='PUT',
      name='update')
  def Update(self, request):
    """Updates a test suite.

    Body:
      Test suite data
    Parameters:
      test_id: Test ID
    """
    test = mtt_messages.ConvertToKey(ndb_models.Test, request.test_id).get()
    if not test:
      raise endpoints.NotFoundException(
          'no test found for ID %s' % request.test_id)
    request.id = request.test_id
    test = mtt_messages.Convert(request, ndb_models.Test, mtt_messages.Test)
    test.put()
    return mtt_messages.Convert(test, mtt_messages.Test)

  @base.ApiMethod(
      endpoints.ResourceContainer(
          message_types.VoidMessage,
          test_id=messages.StringField(1, required=True)),
      message_types.VoidMessage, path='{test_id}', http_method='DELETE',
      name='delete')
  def Delete(self, request):
    """Deletes a test suite.

    Parameters:
      test_id: Test ID
    """
    test_key = mtt_messages.ConvertToKey(ndb_models.Test, request.test_id)
    test_key.delete()
    return message_types.VoidMessage()


import ffmpeg
import os
import sys
import cv2
import argparse

def downscale(input, output, mode, ratio):
    video_extension = ('.mp4','.avi')
    image_extension = ('.jpg','.png','.jpeg')
    _,file_extension = os.path.splitext(input)
    print(f'확장자: {file_extension}')
    if file_extension in image_extension:
        print('이미지 파일입니다.')
        img_downscale(input,output,mode,ratio)
    elif file_extension in video_extension:
        print('비디오 파일입니다.')
        video_downscale(input,output,mode,ratio)
    else:
        print(f'{file_extension} 은(는) 지원하지 않는 파일 형식입니다.')
        print('아래의 확장자를 따르는 이미지 또는 비디오 파일을 입력해주세요.')
        print('이미지 확장자: .png, .jpg, .jpeg')
        print('비디어 확장자: .mp4','.avi')
        sys.exit(1)

def set_output(input, output, mode):
    file_path = os.path.basename(input)
    file_name, file_extension = os.path.splitext(file_path)
    file_name = f'{file_name}_resized_{mode}{file_extension}'
    output_file = os.path.join(output, file_name)

    return output_file

def set_ratio(ratio, width, height, mode):
    if not ratio:
        ratio = f'{width}:{height}'

    modes = {'FHD' : 1080,'HD' : 720,'SD' : 480}
    rationum = ratio.split(":")
    width_r = int(rationum[0])
    height_r = int(rationum[1])
    new_height = modes[mode]
    new_width = int(new_height*width_r/height_r)

    if width < new_width:
        print(f'너비가 {new_width}보다 작습니다. 다른 비율을 입력해주세요.')
        sys.exit(1)
    elif height < new_height:
        print(f'높이가 {new_height}보다 작습니다. 다른 비율을 입력해주세요.')
        sys.exit(1)

    print(f'변경 해상도: {new_width} x {new_height}')

    return new_width, new_height

def video_downscale(input, output, mode, ratio):
    try:
        # 입력 및 출력 파일 경로 설정
        input_file = input
        output_file = set_output(input, output, mode)

        # 비디오 파일 열기
        cap = cv2.VideoCapture(input)

        # 비디오 파일 정보 얻기
        if cap.isOpened():
            width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))  # 비디오 프레임의 너비
            height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))  # 비디오 프레임의 높이
            print(f'현재 해상도: {width} x {height}')
        else:
            print("비디오를 열 수 없습니다. 파일 경로 또는 코덱을 확인하세요.")
            sys.exit(1)

        if width < 600 or height < 1080:
            print('해상도가 너무 작습니다. 너비가 600 이상이고 높이가 1080 이상의 해상도를 가진 파일을 입력해주세요.')
            sys.exit(1)

        # 해상도 변경
        new_width,new_height = set_ratio(ratio, width, height, mode)
        resolution = f'scale={new_width}:{new_height}'

        # 입력 동영상 스트림 생성
        input_stream = ffmpeg.input(input_file)
        output_stream = ffmpeg.output(input_stream, output_file, vf=resolution, vcodec='libx264',acodec='copy')

        # FFmpeg 명령 실행
        ffmpeg.run(output_stream)
        print('비디오 다운스케일 완료')

    except Exception as e:
        print(f"예외 발생: {e}")

def img_downscale(input, output, mode, ratio):
    try:
         #저장 경로 설정
        output_file = set_output(input, output, mode)

        # 이미지 불러오기
        input_image = cv2.imread(input)

        # 이미지가 성공적으로 불러와졌는지 확인
        if input_image is None:
            raise FileNotFoundError("이미지를 불러올 수 없습니다.")

        # 이미지 크기 구하기
        height, width, _ = input_image.shape

        print(f'현재 해상도: {width} x {height}')

        if width < 600 or height < 450:
            print('해상도가 너무 작습니다. 너비가 600 이상이고 높이가 450이상의 해상도를 가진 파일을 입력해주세요.')
            sys.exit(1)

        # 원하는 해상도로 이미지 크기 조정
        new_width,new_height = set_ratio(ratio, width, height, mode)
        resized_image = cv2.resize(input_image, (new_width, new_height), interpolation = cv2.INTER_LANCZOS4)

        # 이미지 저장
        cv2.imwrite(output_file, resized_image)
        print('이미지 다운스케일 완료')

    except Exception as e:
        print(f"예외 발생: {e}")

def main():
    parser = argparse.ArgumentParser(description = '명령줄에서 해상도 설정을 변경하는 스크립트')
    parser.add_argument('-input','-i', type = str, help = '이미지 또는 비디오 파일 경로를 입력해주세요.')
    parser.add_argument('-output','-o', type = str, default = '.', help = '출력 파일 경로를 입력해주세요. (기본 값: 현재 폴더)')
    parser.add_argument('-mode','-m', choices = ['FHD', 'HD', 'SD'], default = 'FHD', help = '해상도 모드(FHD,HD,SD)를 대문자로 입력해주세요. (기본값: FHD)')
    parser.add_argument('-ratio','-r', type = str, help = '다운 스케일 비율 설정, 너비:높이(ex 21:9) 형식으로 입력해주세요. (기본값: 원본 비율 유지)')

    args = parser.parse_args()
    if not args.input:
        print('usage: python down_resolution.py [-h] [-input INPUT] [-output OUTPUT] [-mode {FHD,HD,SD}] [-ratio RATIO]')
        print("-h 옵션을 사용하여 자세한 도움말을 확인하세요.")
        sys.exit(1)

    input = args.input
    output = args.output
    mode = args.mode
    ratio = args.ratio

    print(f'입력 파일 경로: {input}')
    print(f'출력 파일 저장 경로: {output}')
    print(f'해상도 모드: {mode}')
    print(f'다운 스케일 비율: {ratio if ratio else "원본 비율을 유지합니다."}')

    downscale(input, output, mode, ratio)

if __name__ == '__main__':
    main()


import json
import asyncio
from urllib.parse import urljoin

import pytest
import aiohttp

@pytest.mark.asyncio
@pytest.mark.parametrize("root", ['/', 'tailon/', 'tailon/tailon/'])
async def test_relativeroot(server, client, root):
    proc = server('--relative-root', root, 'testdata/ex1/var/log/1.log')
    for path in '', 'ws', 'vfs/dist/main.js':
        url = urljoin('http://localhost', root + path)
        res = await client.get(url)
        assert res.status == 200

    url = urljoin('http://localhost', root + 'vfs/dist/non-existant')
    res = await client.get(url)
    out = await res.text()
    assert res.status == 404, out

@pytest.mark.asyncio
async def test_sockjs_list(server, client):
    proc = server('testdata/ex1/var/log/1.log')
    async with client.ws_connect('http://localhost/ws/0/0/websocket') as ws:
        await ws.send_json(['list'])
        res = await get_sockjs_response(ws)

        assert '__default__' in res
        assert res['__default__'][0]['path'] == 'testdata/ex1/var/log/1.log'

@pytest.mark.asyncio
async def test_sockjs_frontendmessage(server, client):
    proc = server('testdata/ex1/var/log/1.log', 'testdata/ex1/var/log/2.log')

    msg_tail = '''{"command":"tail","script":null,"entry":{"path":"testdata/ex1/var/log/1.log","alias":"/tmp/t1","size":14342,"mtime":"2018-07-14T15:07:33.524768369+02:00","exists":true},"nlines":10}'''

    msg_grep = '''{"command":"grep","script":".*","entry":{"path":"testdata/ex1/var/log/1.log","alias":"/tmp/t1","size":14342,"mtime":"2018-07-14T15:07:33.524768369+02:00","exists":true},"nlines":10}'''

    async with client.ws_connect('http://localhost/ws/0/0/websocket') as ws:
        await ws.send_json([msg_tail])
        await asyncio.sleep(0.1)

        assert len(proc.get_children()) == 1

        await ws.send_json([msg_grep])
        await asyncio.sleep(0.1)
        assert len(proc.get_children()) == 2

        await ws.send_json([msg_tail])
        await asyncio.sleep(0.1)
        assert len(proc.get_children()) == 1

async def get_sockjs_response(ws):
        assert (await ws.receive()).data == 'o'
        res = (await ws.receive()).data[1:]
        res = json.loads(res)
        return json.loads(res[0])


import bisect, collections, functools, heapq, itertools, math, operator, string
from typing import List, Optional, Tuple
import sortedcontainers

# 1700 - Number of Students Unable to Eat Lunch - EASY
class Solution:
    def countStudents(self, students: List[int], sandwiches: List[int]) -> int:
        cnt = collections.Counter(students)
        st = collections.deque(students)
        ans = len(students)
        for v in sandwiches:
            if cnt[v] == 0:
                break
            while st and st[0] != v:
                st.append(st.popleft())
            st.popleft()
            cnt[v] -= 1
            ans -= 1
        return ans

    def countStudents(self, students: List[int], sandwiches: List[int]) -> int:
        s1 = sum(students)
        s0 = len(students) - s1
        for v in sandwiches:
            if v == 0 and s0:
                s0 -= 1
            elif v == 1 and s1:
                s1 -= 1
            else:
                break
        return s0 + s1

# 1701 - Average Waiting Time - MEDIUM
class Solution:
    def averageWaitingTime(self, customers: List[List[int]]) -> float:
        finish = wait = 0
        for a, t in customers:
            wait += max(0, finish - a) + t
            finish = max(finish, a) + t
        return wait / len(customers)

    def averageWaitingTime(self, customers: List[List[int]]) -> float:
        wait = cur = 0
        for a, t in customers:
            cur = max(cur, a) + t
            wait += cur - a
        return wait / len(customers)

# 1702 - Maximum Binary String After Change - MEDIUM
class Solution:
    # 1. 开头的 1 不动, 找到第一个开头为 0 的子串
    # 2. 子串含至少两个 0 时, 可以把子串的 1 都挪到右边, 用左边的 0 生成 1, 直到耗尽 00
    # O(n) / O(1)
    def maximumBinaryString(self, binary: str) -> str:
        i = 0
        while i < len(binary) and binary[i] == "1":
            i += 1

        # 68 ms
        zero = binary[i:].count("0")
        one = len(binary) - i - zero

        # 352 ms
        # one = sum(map(int, binary[i:]))
        # zero = len(binary) - i - one

        # 660 ms
        # zero = sum(1 - int(binary[j]) for j in range(i, len(binary)))
        # one = len(binary) - i - zero

        if zero < 2:
            return binary
        return binary[:i] + "1" * (zero - 1) + "0" + "1" * one

# 1704 - Determine if String Halves Are Alike - EASY
class Solution:
    def halvesAreAlike(self, s: str, p: str = "aeiouAEIOU") -> bool:
        return sum(c in p for c in s[: len(s) // 2]) == sum(
            c in p for c in s[len(s) // 2 :]
        )

p = set("aeiouAEIOU")

class Solution:
    def halvesAreAlike(self, s: str) -> bool:
        return sum(c in p for c in s[: len(s) // 2]) == sum(
            c in p for c in s[len(s) // 2 :]
        )

# 1705 - Maximum Number of Eaten Apples - MEDIUM
class Solution:
    def eatenApples(self, apples: List[int], days: List[int]) -> int:
        pq, i, ans = [], 0, 0
        while i < len(apples) or pq:
            while pq and pq[0][0] <= i:
                heapq.heappop(pq)
            if i < len(apples) and apples[i]:
                heapq.heappush(pq, [i + days[i], apples[i]])
            if pq:
                pq[0][1] -= 1
                ans += 1
                if not pq[0][1]:
                    heapq.heappop(pq)
            i += 1
        return ans

    def eatenApples(self, apples: List[int], days: List[int]) -> int:
        pq, i, ans = [], 0, 0
        while i < len(apples):
            while pq and pq[0][0] <= i:
                heapq.heappop(pq)
            if apples[i]:
                heapq.heappush(pq, [i + days[i], apples[i]])
            if pq:
                pq[0][1] -= 1
                if not pq[0][1]:
                    heapq.heappop(pq)
                ans += 1
            i += 1
        while pq:
            cur = heapq.heappop(pq)
            d = min(cur[0] - i, cur[1])
            i += d
            ans += d
            while pq and pq[0][0] <= i:
                heapq.heappop(pq)
        return ans

# 1706 - Where Will the Ball Fall - MEDIUM
class Solution:
    def findBall(self, grid: List[List[int]]) -> List[int]:
        ans = []
        m, n = len(grid), len(grid[0])
        for b in range(n):
            i = 0
            j = b
            succ = True
            while i < m:
                if grid[i][j] == 1 and j + 1 < n and grid[i][j + 1] == 1:
                    j += 1
                    i += 1
                elif grid[i][j] == -1 and j - 1 >= 0 and grid[i][j - 1] == -1:
                    j -= 1
                    i += 1
                else:
                    succ = False
                    break
            if succ:
                ans.append(j)
            else:
                ans.append(-1)
        return ans

    # for-else
    def findBall(self, grid: List[List[int]]) -> List[int]:
        n = len(grid[0])
        ans = [-1] * n
        for j in range(n):
            col = j
            for row in grid:
                dir = row[col]
                col += dir
                if col < 0 or col == n or row[col] != dir:
                    break
            else:
                ans[j] = col
        return ans

# 1710 - Maximum Units on a Truck - EASY
class Solution:
    def maximumUnits(self, boxTypes: List[List[int]], truckSize: int) -> int:
        ans = 0
        for t, v in sorted(boxTypes, key=lambda x: x[1], reverse=True):
            if t > truckSize:
                ans += truckSize * v
                break
            truckSize -= t
            ans += t * v
        return ans

# 1711 - Count Good Meals - MEDIUM
class Solution:
    global arr
    arr = [2**i for i in range(22)]

    # O(nlogC) / O(n), 21n
    def countPairs(self, deliciousness: List[int]) -> int:
        mod = 10**9 + 7
        cnt = collections.defaultdict(int)
        ans = 0
        for v in deliciousness:
            for t in arr:
                ans += cnt[t - v]
            ans %= mod
            cnt[v] += 1
        return ans

    def countPairs(self, deliciousness: List[int]) -> int:
        mod = 10**9 + 7
        ans = 0
        cnt = collections.Counter(deliciousness)
        p = 1
        for k in sorted(cnt):
            if k == 0:
                continue
            while p < k:
                p *= 2
            ans += cnt[k] * cnt[p - k]
            if k == p:  # 自身是一个 2 的幂次
                ans += cnt[k] * (cnt[k] - 1) // 2
            ans %= mod
        return ans

    def countPairs(self, deliciousness: List[int]) -> int:
        # TODO
        def nextPower(x: int):
            x -= 1
            x |= x >> 1
            x |= x >> 2
            x |= x >> 4
            x |= x >> 8
            x |= x >> 16
            return x + 1

        mod = 10**9 + 7
        cnt = collections.Counter(deliciousness)
        ans = 0
        # 由于每个数只遍历了最接近自己的 2 的次幂的组合, 所以不可能重复
        # 比如说 1 + 3 = 4，只在 3 的时候计算, 3 + 5 = 8 只在 5 的时候计算
        for k in cnt:
            if k == 0:
                continue
            # k 的下一个 2 的幂次
            p = nextPower(k)
            # 自身是一个 2 的幂次
            if k == p:
                ans += cnt[k] * (cnt[k] - 1) // 2
            ans += cnt[k] * cnt[p - k]
        return ans % mod

# 1716 - Calculate Money in Leetcode Bank - EASY
class Solution:
    def totalMoney(self, n: int) -> int:
        div, mod = divmod(n, 7)
        ans = 0
        for i in range(mod):
            ans += i + 1 + div
        while div:
            ans += 28 + (div - 1) * 7
            div -= 1
        return ans

    def totalMoney(self, n: int) -> int:
        div, mod = divmod(n, 7)
        ans = 0
        for i in range(mod):
            ans += i + 1 + div
        ans += div * 28 + (div - 1) * div * 7 // 2 if div else 0
        return ans

# 1725 - Number Of Rectangles That Can Form The Largest Square - EASY
class Solution:
    def countGoodRectangles(self, rectangles: List[List[int]]) -> int:
        count = pre = 0
        for l, w in rectangles:
            sq = min(l, w)
            if sq > pre:
                count = 1
                pre = sq
            elif sq == pre:
                count += 1
        return count

# 1732 - Find the Highest Altitude - EASY
class Solution:
    # O(n) / O(n)
    def largestAltitude(self, gain: List[int]) -> int:
        h = [0]
        for v in gain:
            h.append(h[-1] + v)
        return max(h)

    # O(n) / O(1)
    def largestAltitude(self, gain: List[int]) -> int:
        ans = h = 0
        for v in gain:
            h += v
            ans = max(ans, h)
        return ans

    # O(n) / O(1)
    def largestAltitude(self, gain: List[int]) -> int:
        return max(itertools.accumulate(gain, initial=0))

# 1736 - Latest Time by Replacing Hidden Digits - EASY
class Solution:
    def maximumTime(self, time: str) -> str:
        ans = list(time)
        if time[0] == "?":
            ans[0] = "2" if time[1] == "?" or int(time[1]) < 4 else "1"
        if time[1] == "?":
            ans[1] = "3" if ans[0] == "2" else "9"
        if time[3] == "?":
            ans[3] = "5"
        if time[4] == "?":
            ans[4] = "9"
        return "".join(ans)

# 1739 - Building Boxes - HARD
class Solution:
    def minimumBoxes(self, n: int) -> int:
        s = 0
        k = 1
        # 放满, 1, 1 + 2, 1 + 2 + 3, 1 + 2 + ... + k
        while s + k * (k + 1) // 2 <= n:
            s += k * (k + 1) // 2
            k += 1
        # 还有剩余, 从最低一层继续摆放, 假设摆放 m 个, 那么累计可摆放的盒子个数为 1 + 2 + 3 + ... + i >= m
        ans = k * (k - 1) // 2
        k = 1
        while s < n:
            ans += 1
            s += k
            k += 1
        return ans

# 1742 - Maximum Number of Balls in a Box - EASY
class Solution:
    def countBalls(self, lowLimit: int, highLimit: int) -> int:
        d = collections.defaultdict(int)
        for i in range(lowLimit, highLimit + 1):
            x = 0
            while i:
                x += i % 10
                i //= 10
            d[x] += 1
        return max(d.values())

# 1748 - Sum of Unique Elements - EASY
class Solution:
    def sumOfUnique(self, nums: List[int]) -> int:
        freq = [0] * 100
        for n in nums:
            freq[n - 1] += 1
        ans = 0
        for i in range(len(freq)):
            ans += i + 1 if freq[i] == 1 else 0
        return ans

    def sumOfUnique(self, nums: List[int]) -> int:
        return sum(k for k, v in collections.Counter(nums).items() if v == 1)

# 1749 - Maximum Absolute Sum of Any Subarray - MEDIUM
class Solution:
    def maxAbsoluteSum(self, nums: List[int]) -> int:
        ans = p = n = 0
        for v in nums:
            if v >= 0:
                p += v
                ans = max(ans, p)
                n = min(0, n + v)
            if v <= 0:
                n += v
                ans = max(ans, -n)
                p = max(0, p + v)
        return ans

    def maxAbsoluteSum(self, nums: List[int]) -> int:
        ans = p = n = 0
        for v in nums:
            p = max(0, p + v)
            n = min(0, n + v)
            ans = max(ans, p, -n)
        return ans

    def maxAbsoluteSum(self, nums: List[int]) -> int:
        ans = p = n = 0
        for v in nums:
            p = p + v if p > 0 else v
            n = n + v if n < 0 else v
            ans = max(ans, abs(p), abs(n))
        return ans

    # 子数组和最大 -> 某两个位置(i, j)的前缀和的差值 最大 (i <= j)
    # 子数组和最小 -> 某两个位置(i, j)的前缀和的差值 最小 (i <= j)
    # 子数组和的 abs 最大 -> 某两个位置(i, j)的前缀和的差距 最大, i 和 j 相对位置随意
    def maxAbsoluteSum(self, nums: List[int]) -> int:
        summ = mx = mn = 0
        for v in nums:
            summ += v
            if summ > mx:
                mx = summ
            if summ < mn:
                mn = summ
        return mx - mn

# 1750 - Minimum Length of String After Deleting Similar Ends - MEDIUM
class Solution:
    def minimumLength(self, s: str) -> int:
        dq = collections.deque()
        for c, g in itertools.groupby(s):
            dq.append((c, len(tuple(g))))
        while dq:
            if dq[0][0] == dq[-1][0]:
                if len(dq) == 1:
                    return 1 if dq.pop()[1] == 1 else 0
                else:
                    dq.pop()
                    dq.popleft()
            else:
                break
        return sum(v[1] for v in dq)

    def minimumLength(self, s: str) -> int:
        l = 0
        r = len(s) - 1
        while l < r and s[l] == s[r]:
            while l + 1 < r and s[l] == s[l + 1]:
                l += 1
            while l < r - 1 and s[r - 1] == s[r]:
                r -= 1
            l += 1
            r -= 1
        return max(0, r - l + 1)

    def minimumLength(self, s: str) -> int:
        l = 0
        r = len(s) - 1
        while l < r and s[l] == s[r]:
            c = s[l]
            while l <= r and s[l] == c:
                l += 1
            while l <= r and s[r] == c:
                r -= 1
        return r - l + 1

# 1752 - Check if Array Is Sorted and Rotated - EASY
class Solution:
    # O(n^2) / O(n)
    def check(self, nums: List[int]) -> bool:
        n = len(nums)
        a = sorted(nums)
        return any(all(nums[i] == a[(i + x) % n] for i in range(n)) for x in range(n))

    # O(n) / O(1)
    def check(self, nums: List[int]) -> bool:
        cnt = 0
        n = len(nums)
        for i in range(n):
            if nums[i] > nums[(i + 1) % n]:
                cnt += 1
            if cnt > 1:
                return False
        return True

# 1753 - Maximum Score From Removing Stones - MEDIUM
class Solution:
    # O(nlogn) / O(1)
    def maximumScore(self, a: int, b: int, c: int) -> int:
        h = sorted([-a, -b, -c])
        ans = 0
        while len(h) > 1:
            x = -heapq.heappop(h) - 1
            y = -heapq.heappop(h) - 1
            ans += 1
            if x:
                heapq.heappush(h, -x)
            if y:
                heapq.heappush(h, -y)
        return ans

    # O(1) / O(1)
    def maximumScore(self, a: int, b: int, c: int) -> int:
        arr = sorted([a, b, c])
        if arr[0] + arr[1] <= arr[2]:
            return arr[0] + arr[1]
        return sum(arr) // 2

# 1754 - Largest Merge Of Two Strings - MEDIUM
class Solution:
    # O(m^2 + n^2) / O(m^2 + n^2)
    def largestMerge(self, word1: str, word2: str) -> str:
        if word1 >= word2 and word2 > "":
            return word1[0] + self.largestMerge(word1[1:], word2)
        if word2 >= word1 and word1 > "":
            return word2[0] + self.largestMerge(word1, word2[1:])
        return word1 + word2

    # O(m^2 + n^2) / O(1)
    def largestMerge(self, word1: str, word2: str) -> str:
        ans = ""
        i = j = 0
        m = len(word1)
        n = len(word2)
        while i < m and j < n:
            # k = 0
            # while i + k < m and j + k < n and word1[i + k] == word2[j + k]:
            #     k += 1
            # if j + k == n or i + k < m and word1[i + k] > word2[j + k]:
            #     ans += word1[i]
            #     i += 1
            # else:
            #     ans += word2[j]
            #     j += 1

            if word1[i:] > word2[j:]:
                ans += word1[i]
                i += 1
            else:
                ans += word2[j]
                j += 1

        while i < m:
            ans += word1[i]
            i += 1
        while j < n:
            ans += word2[j]
            j += 1
        return ans

# 1758 - Minimum Changes To Make Alternating Binary String - EASY
class Solution:
    # O(n) / O(n)
    def minOperations(self, s: str) -> int:
        n = len(s)
        a = "01" * ((n + 1) // 2)
        b = "10" * ((n + 1) // 2)
        ans = 1e4
        ans = min(ans, sum(x != y for x, y in zip(a, s)))
        ans = min(ans, sum(x != y for x, y in zip(b, s)))
        return ans

    def minOperations(self, s: str) -> int:
        x = y = 0  # x: 1010... y: 0101...
        for i, c in enumerate(s):
            if c != str(i % 2):
                x += 1
            else:
                y += 1
        return min(x, y)

    # 变成 01010... 的步骤数是 x,
    # 变成 10101... 的步骤数是 y,
    # 一定有 x + y = n
    # 任意计算其中一种, 返回 min(x, n-x) 就行
    def minOperations(self, s: str) -> int:
        x = 0
        for i, c in enumerate(s):
            if c != str(i % 2):
                x += 1
        return min(x, len(s) - x)

# 1759 - Count Number of Homogenous Substrings - MEDIUM
class Solution:
    def countHomogenous(self, s: str) -> int:
        ans = 0
        for _, g in itertools.groupby(s):
            l = len(list(g))
            ans += (l + 1) * l // 2
        return ans % (10**9 + 7)

    def countHomogenous(self, s: str) -> int:
        ans = t = 1
        for i in range(1, len(s)):
            if s[i - 1] == s[i]:
                t += 1
            else:
                t = 1
            ans += t
        return ans % (10**9 + 7)

# 1760 - Minimum Limit of Balls in a Bag - MEDIUM
class Solution:
    def minimumSize(self, nums: List[int], maxOperations: int) -> int:
        def check(x: int) -> int:
            t = 0
            for v in nums:
                t += (v - 1) // x
            return t <= maxOperations

        l = 1
        r = max(nums)
        while l < r:
            m = (l + r) // 2
            if check(m):
                r = m
            else:
                l = m + 1
        return l

    def minimumSize(self, nums: List[int], maxOperations: int) -> int:
        return (
            bisect.bisect_left(
                range(1, max(nums) + 1),
                x=True,
                key=lambda m: sum((v - 1) // m for v in nums) <= maxOperations,
            )
            + 1
        )

# 1761 - Minimum Degree of a Connected Trio in a Graph - HARD
class Solution:
    def minTrioDegree(self, n: int, edges: List[List[int]]) -> int:
        d = [0] * (n + 1)
        g = [[False] * (n + 1) for _ in range(n + 1)]
        for x, y in edges:
            d[x] += 1
            d[y] += 1
            g[x][y] = g[y][x] = True
        return min(
            (
                d[x] + d[y] + d[z] - 6
                for x in range(1, n + 1)
                for y in range(x + 1, n + 1)
                if g[x][y]
                for z in range(y + 1)
                if g[x][z] and g[y][z]
            ),
            default=-1,
        )

        # return min(
        #     (
        #         d[x] + d[y] + d[z] - 6
        #         for x in range(1, n - 1)
        #         for y in range(x + 1, n)
        #         for z in range(y + 1, n + 1)
        #         if g[x][y] and g[y][z] and g[z][x]
        #     ),
        #     default=-1,
        # )

    def minTrioDegree(self, n: int, edges: List[List[int]]) -> int:
        d = collections.defaultdict(list)
        for x, y in edges:
            d[x].append(y)
            d[y].append(x)
        ans = math.inf
        for i in range(1, n + 1):
            if len(d[i]) < 2:
                continue
            # 对相邻节点的度数进行排序, 这样可以保证先遍历的元组组合的度数更小
            conn = sorted(d[i], key=lambda x: len(d[x]))
            q = [(0, 1)]
            vis = set(q)
            found = False
            for l, r in q:
                if found:
                    # 找到一个有效三元组了, 其度数组合一定是包含节点i的三元组中最小的, 不再继续遍历其他的
                    break
                j, k = conn[l], conn[r]
                if j in d[k]:
                    found = True
                    ans = min(ans, len(d[i]) + len(d[j]) + len(d[k]) - 6)
                else:
                    # 否则两个方向继续找下一个元组组合
                    for nl, nr in ((l + 1, r), (l, r + 1)):
                        if (
                            0 <= nl < len(conn)
                            and 0 <= nr < len(conn)
                            and nl != nr
                            and (nl, nr) not in vis
                        ):
                            vis.add((nl, nr))
                            q.append((nl, nr))
        return -1 if ans == math.inf else ans

# 1762 - Buildings With an Ocean View - MEDIUM
class Solution:
    def findBuildings(self, heights: List[int]) -> List[int]:
        ans, maxH = [], 0
        for i in range(len(heights) - 1, -1, -1):
            if heights[i] > maxH:
                ans.append(i)
                maxH = heights[i]
        ans.reverse()
        return ans

# 1763 - Longest Nice Substring - EASY
class Solution:
    def longestNiceSubstring(self, s: str) -> str:
        if not s:
            return ""
        ss = set(s)
        for i, c in enumerate(s):
            if c.swapcase() not in ss:
                s0 = self.longestNiceSubstring(s[:i])
                s1 = self.longestNiceSubstring(s[i + 1 :])
                return max(s0, s1, key=len)
        return s

# 1764 - Form Array by Concatenating Subarrays of Another Array - MEDIUM
class Solution:
    # O(nm) / O(1)
    def canChoose(self, groups: List[List[int]], nums: List[int]) -> bool:
        i = j = 0
        while i < len(groups) and j < len(nums):
            g = groups[i]
            if g == nums[j : j + len(g)]:
                i += 1
                j += len(g)
            else:
                j += 1
        return i == len(groups)

# 1765 - Map of Highest Peak - MEDIUM
class Solution:
    def highestPeak(self, isWater: List[List[int]]) -> List[List[int]]:
        dq = collections.deque([])
        m, n = len(isWater), len(isWater[0])
        for i in range(m):
            for j in range(n):
                if isWater[i][j] == 1:
                    dq.append((i, j))
                isWater[i][j] -= 1
        while dq:
            x, y = dq.popleft()
            for nx, ny in [(x + 1, y), (x - 1, y), (x, y + 1), (x, y - 1)]:
                if 0 <= nx < m and 0 <= ny < n and isWater[nx][ny] == -1:
                    dq.append((nx, ny))
                    isWater[nx][ny] = isWater[x][y] + 1
        return isWater

# 1768 - Merge Strings Alternately - EASY
class Solution:
    def mergeAlternately(self, word1: str, word2: str) -> str:
        return "".join(
            a + b for a, b in itertools.zip_longest(word1, word2, fillvalue="")
        )

# 1769 - Minimum Number of Operations to Move All Balls to Each Box - MEDIUM
class Solution:
    # O(n) / O(n)
    def minOperations(self, boxes: str) -> List[int]:
        n = len(boxes)
        l = [0] * n
        step = 0
        for i in range(1, len(boxes)):
            if boxes[i - 1] == "1":
                step += 1
            l[i] += l[i - 1] + step
        r = [0] * n
        step = 0
        for i in range(len(boxes) - 2, -1, -1):
            if boxes[i + 1] == "1":
                step += 1
            r[i] += r[i + 1] + step
        return [a + b for a, b in zip(l, r)]

    # O(n) / O(1)
    def minOperations(self, boxes: str) -> List[int]:
        l = int(boxes[0])
        r = operations = 0
        for i in range(1, len(boxes)):
            if boxes[i] == "1":
                r += 1
                operations += i
        ans = [operations]
        for i in range(1, len(boxes)):
            operations += l - r
            if boxes[i] == "1":
                l += 1
                r -= 1
            ans.append(operations)
        return ans

    def minOperations(self, boxes: str) -> List[int]:
        n = len(boxes)
        l = r = cost = 0
        for i, v in enumerate(map(int, boxes)):
            r += v
            cost += v * (i + 1)
        ans = [-1] * n
        for i, v in enumerate(map(int, boxes)):
            cost += l - r
            l += v
            r -= v
            ans[i] = cost
        return ans

# 1770 - Maximum Score from Performing Multiplication Operations - MEDIUM
class Solution:
    def maximumScore(self, nums: List[int], multipliers: List[int]) -> int:
        n = len(nums)
        m = len(multipliers)
        f = [[0] * (m + 1) for _ in range(m + 1)]
        for i in range(1, m + 1):
            f[i][0] = f[i - 1][0] + nums[i - 1] * multipliers[i - 1]
        for j in range(1, m + 1):
            f[0][j] = f[0][j - 1] + nums[n - j] * multipliers[j - 1]
        ans = f[0][m] if f[0][m] > f[m][0] else f[m][0]
        # i: 左边拿走数量, j: 右边拿走数量
        for i in range(1, m + 1):
            for j in range(1, m - i + 1):
                left = f[i - 1][j] + nums[i - 1] * multipliers[i + j - 1]
                right = f[i][j - 1] + nums[n - j] * multipliers[i + j - 1]
                f[i][j] = max(left, right)
            ans = max(ans, f[i][m - i])
        return ans

    def maximumScore(self, nums: List[int], multipliers: List[int]) -> int:
        n = len(nums)
        m = len(multipliers)
        # l, r 是左右下标, i 是 mul 里的下标
        f = [[0] * (m + 1) for _ in range(m + 1)]
        for l in range(m - 1, -1, -1):
            for i in range(m - 1, -1, -1):
                r = n - (i - l) - 1
                if r < 0 or r >= n:
                    break
                a = f[l + 1][i + 1] + nums[l] * multipliers[i]
                b = f[l][i + 1] + nums[r] * multipliers[i]
                f[l][i] = max(a, b)
        return f[0][0]

    # cache maxsize is set to None will TLE
    def maximumScore(self, nums: List[int], multipliers: List[int]) -> int:
        @functools.lru_cache(len(multipliers))
        def dfs(l: int, r: int, k: int) -> int:
            if k == len(multipliers):
                return 0
            a = nums[l] * multipliers[k] + dfs(l + 1, r, k + 1)
            b = nums[r] * multipliers[k] + dfs(l, r - 1, k + 1)
            return max(a, b)
            dfs.cache_clear()

        return dfs(0, len(nums) - 1, 0)

# 1773 - Count Items Matching a Rule - EASY
class Solution:
    def countMatches(self, items: List[List[str]], ruleKey: str, ruleValue: str) -> int:
        if ruleKey == "type":
            return sum(x == ruleValue for x, _, _ in items)
        if ruleKey == "color":
            return sum(x == ruleValue for _, x, _ in items)
        if ruleKey == "name":
            return sum(x == ruleValue for _, _, x in items)

    def countMatches(self, items: List[List[str]], ruleKey: str, ruleValue: str) -> int:
        idx = {"type": 0, "color": 1, "name": 2}[ruleKey]
        return sum(v[idx] == ruleValue for v in items)

# 1774 - Closest Dessert Cost - MEDIUM
class Solution:
    # O(n * 3**m) / O(m)
    def closestCost(
        self, baseCosts: List[int], toppingCosts: List[int], target: int
    ) -> int:
        def dfs(i: int, cur: int) -> None:
            nonlocal ans
            if i == len(toppingCosts):
                # 放外面也可以, 表示后面的都不选
                if abs(ans - target) > abs(cur - target):
                    ans = cur
                elif abs(ans - target) == abs(cur - target):
                    ans = min(ans, cur)
                return
            dfs(i + 1, cur)
            if cur <= target:
                dfs(i + 1, cur + toppingCosts[i])
                dfs(i + 1, cur + 2 * toppingCosts[i])
            return

        ans = math.inf
        for v in baseCosts:
            dfs(0, v)
        return ans

    def closestCost(
        self, baseCosts: List[int], toppingCosts: List[int], target: int
    ) -> int:
        def dfs(i: int, cur: int) -> None:
            nonlocal ans
            a = abs(ans - target)
            b = abs(cur - target)
            if cur > target and a < b:
                return
            if a > b:
                ans = cur
            if a == b:
                ans = min(ans, cur)
            if i == len(toppingCosts):
                return
            dfs(i + 1, cur + toppingCosts[i] * 2)
            dfs(i + 1, cur + toppingCosts[i])
            dfs(i + 1, cur)
            return

        ans = math.inf
        for v in baseCosts:
            dfs(0, v)
        return ans

# 1775 - Equal Sum Arrays With Minimum Number of Operations - MEDIUM
class Solution:
    def minOperations(self, nums1: List[int], nums2: List[int]) -> int:
        s1 = sum(nums1)
        s2 = sum(nums2)
        if s1 == s2:
            return 0
        if s1 < s2:
            return self.minOperations(nums2, nums1)
        diff = s1 - s2
        cnt = collections.Counter(v - 1 for v in nums1) + collections.Counter(
            6 - v for v in nums2
        )
        ans = 0
        for k in range(5, 0, -1):
            if diff >= cnt[k] * k:
                diff -= cnt[k] * k
                ans += cnt[k]
            else:
                ans += (diff + k - 1) // k
                diff = 0
                break

        # for i in range(5, 0, -1):
        #     if diff <= 0:
        #         break
        #     for _ in range(cnt[i]):
        #         if diff <= 0:
        #             break
        #         ans += 1
        #         diff -= i

        return ans if diff == 0 else -1

# 1779 - Find Nearest Point That Has the Same X or Y Coordinate - EASY
class Solution:
    def nearestValidPoint(self, x: int, y: int, points: List[List[int]]) -> int:
        ans = -1
        mi = math.inf
        for i, (a, b) in enumerate(points):
            if a == x or b == y:
                d = abs(a - x) + abs(b - y)
                if d < mi:
                    mi = d
                    ans = i
        return ans

# 1780 - Check if Number is a Sum of Powers of Three - MEDIUM
class Solution:
    def checkPowersOfThree(self, n: int) -> bool:
        p3 = [3**i for i in reversed(range(15))]
        for p in p3:
            if n >= 2 * p:
                return False
            elif n >= p:
                n -= p
        return True

    def checkPowersOfThree(self, n: int) -> bool:
        while n > 0:
            if n % 3 == 2:
                return False
            n //= 3
        return True

# 1781 - Sum of Beauty of All Substrings - MEDIUM
class Solution:
    # O(n * n * C) / O(C)
    def beautySum(self, s: str) -> int:
        ans = 0
        for i in range(len(s)):
            d = collections.defaultdict(int)
            for j in range(i, len(s)):
                d[s[j]] += 1
                ans += max(d.values()) - min(d.values())
        return ans

# 1782 - Count Pairs Of Nodes - HARD
class Solution:
    def countPairs(
        self, n: int, edges: List[List[int]], queries: List[int]
    ) -> List[int]:
        d = [0] * (n + 1)
        for x, y in edges:
            d[x] += 1
            d[y] += 1
        cnt = collections.Counter(tuple(sorted(e)) for e in edges)
        # cnt = collections.Counter(x * (n + 1) + y if x < y else y * (n + 1) + x for x, y in edges)
        ans = [0] * len(queries)
        sd = sorted(d)
        for i, q in enumerate(queries):
            l = 1
            r = n
            while l < r:
                if sd[l] + sd[r] <= q:
                    l += 1
                else:
                    ans[i] += r - l
                    r -= 1
            for (x, y), v in cnt.items():
                # if q < d[k // (n + 1)] + d[k % (n + 1)] <= q + v:
                if q < d[x] + d[y] <= q + v:
                    ans[i] -= 1
        return ans

# 1784 - Check if Binary String Has at Most One Segment of Ones - EASY
class Solution:
    def checkOnesSegment(self, s: str) -> bool:
        return len(list(v for v in s.split("0") if v != "")) <= 1
        return "01" not in s

# 1785 - Minimum Elements to Add to Form a Given Sum - MEDIUM
class Solution:
    def minElements(self, nums: List[int], limit: int, goal: int) -> int:
        return math.ceil(abs(goal - sum(nums)) / limit)
        return (abs(goal - sum(nums)) - 1) // limit + 1

# 1790 - Check if One String Swap Can Make Strings Equal - EASY
class Solution:
    def areAlmostEqual(self, s1: str, s2: str) -> bool:
        cnt1 = collections.Counter(s1)
        cnt2 = collections.Counter(s2)
        if cnt1 != cnt2:
            return False
        diff = 0
        for x, y in zip(s1, s2):
            if x != y:
                diff += 1
        if diff == 0 or diff == 2:
            return True
        return False

    def areAlmostEqual(self, s1: str, s2: str) -> bool:
        px = py = ""
        for x, y in zip(s1, s2):
            if x != y:
                if px == "used":
                    return False
                if px == "":
                    px = x
                    py = y
                elif px != y or py != x:
                    return False
                else:
                    px = "used"
        return True if px in "used" else False

    def areAlmostEqual(self, s1: str, s2: str) -> bool:
        px = py = ""
        for x, y in zip(s1, s2):
            if x != y:
                if px == y and py == x:
                    px = "used"
                elif px == "":
                    px = x
                    py = y
                else:
                    return False
        return True if px in "used" else False

    def areAlmostEqual(self, s1: str, s2: str) -> bool:
        i = j = -1
        for idx, (x, y) in enumerate(zip(s1, s2)):
            if x != y:
                if i < 0:
                    i = idx
                elif j < 0:
                    j = idx
                else:
                    return False
        return i < 0 or j >= 0 and s1[i] == s2[j] and s1[j] == s2[i]

    def areAlmostEqual(self, s1: str, s2: str) -> bool:
        arr = []
        for x, y in zip(s1, s2):
            if x != y:
                arr.append(x)
                arr.append(y)
        return len(arr) <= 4 and arr == arr[::-1]

# 1791 - Find Center of Star Graph - EASY
class Solution:
    def findCenter(self, edges: List[List[int]]) -> int:
        n = len(edges)
        d = [0] * (n + 1)
        for o, i in edges:
            d[o - 1] += 1
            d[i - 1] += 1
        for i in range(len(d)):
            if d[i] == n:
                return i + 1
        return -1

    def findCenter(self, edges: List[List[int]]) -> int:
        if edges[0][0] in edges[1]:
            return edges[0][0]
        else:
            return edges[0][1]

# 1792 - Maximum Average Pass Ratio - MEDIUM
class Solution:
    # O((n + e) * logn) / O(n)
    def maxAverageRatio(self, classes: List[List[int]], extraStudents: int) -> float:
        h = list((p / t - (p + 1) / (t + 1), p, t) for p, t in classes)
        heapq.heapify(h)
        for _ in range(extraStudents):
            _, p, t = heapq.heappop(h)
            p += 1
            t += 1
            heapq.heappush(h, (p / t - (p + 1) / (t + 1), p, t))
        return sum(p / t for _, p, t in h) / len(classes)

# 1796 - Second Largest Digit in a String - EASY
class Solution:
    def secondHighest(self, s: str) -> int:
        a = b = -1
        for c in s:
            if c.isdigit():
                if int(c) > a:
                    a, b = int(c), a
                elif a > int(c) > b:
                    b = int(c)
        return b

# 1797 - Design Authentication Manager - MEDIUM
class AuthenticationManager:
    def __init__(self, timeToLive: int):
        self.t = timeToLive
        self.d = {}

    # O(1)
    def generate(self, tokenId: str, currentTime: int) -> None:
        self.d[tokenId] = currentTime + self.t
        return

    # O(1)
    def renew(self, tokenId: str, currentTime: int) -> None:
        if self.d.get(tokenId, 0) > currentTime:
            self.d[tokenId] = currentTime + self.t
        return

    # O(n)
    def countUnexpiredTokens(self, currentTime: int) -> int:
        return sum(v > currentTime for v in self.d.values())

class AuthenticationManager:
    def __init__(self, timeToLive: int):
        self.t = timeToLive
        self.d = collections.OrderedDict()

    # O(1)
    def generate(self, tokenId: str, currentTime: int) -> None:
        self.d[tokenId] = currentTime + self.t
        return

    # O(1)
    def renew(self, tokenId: str, currentTime: int) -> None:
        while self.d and next(iter(self.d.values())) <= currentTime:
            self.d.popitem(last=False)
        if tokenId in self.d:
            self.d[tokenId] = currentTime + self.t
            self.d.move_to_end(tokenId)
        return

    # O(1), Average-case time complexity
    def countUnexpiredTokens(self, currentTime: int) -> int:
        while self.d and next(iter(self.d.values())) <= currentTime:
            self.d.popitem(last=False)
        return len(self.d)

class AuthenticationManager:
    def __init__(self, timeToLive: int):
        """
        lazy update (extra element in heap and deleted in counting)
        is possible because the currentTime is strictly increasing
        which implies that if the renewal before counting is conducted,
        the old record will be automatically deleted before counting.
        """
        self.t = timeToLive
        self.d = {}
        self.q = []

    def generate(self, tokenId: str, currentTime: int) -> None:
        heapq.heappush(self.q, (currentTime + self.t, tokenId))
        self.d[tokenId] = currentTime + self.t
        return

    def renew(self, tokenId: str, currentTime: int) -> None:
        if tokenId in self.d and self.d[tokenId] > currentTime:
            self.d[tokenId] = currentTime + self.t  # add another record (new_time, id)
            heapq.heappush(self.q, (currentTime + self.t, tokenId))
        return

    def countUnexpiredTokens(self, currentTime: int) -> int:
        while self.q and self.q[0][0] <= currentTime:
            # decide whether this record is the most up-to-date one for the given token
            # only one record in dict()
            if self.q[0][0] == self.d[self.q[0][1]]:
                self.d.pop(self.q[0][1])
            heapq.heappop(self.q)
        return len(self.d)

# 1798 - Maximum Number of Consecutive Values You Can Make - MEDIUM
class Solution:
    def getMaximumConsecutive(self, coins: List[int]) -> int:
        coins.sort()
        ans = 0
        for c in coins:
            if c > ans + 1:
                break
            ans += c
        return ans + 1

# 1799 - Maximize Score After N Operations - HARD
class Solution:
    # 2400 ms
    def maxScore(self, nums: List[int]) -> int:
        def gcd(x: int, y: int) -> int:
            while y:
                x, y = y, x % y
            return x

        # 1600 ms
        # d = collections.defaultdict(dict)
        # for i in range(len(nums)):
        #     for j in range(i + 1, len(nums)):
        #         g = gcd(nums[i], nums[j])
        #         d[nums[i]][nums[j]] = g
        #         d[nums[j]][nums[i]] = g

        @functools.lru_cache(None)
        def dfs(t: tuple) -> int:
            m = 0
            l = list(t)
            for i in range(len(l)):
                for j in range(i + 1, len(l)):
                    new = l[:]
                    new.pop(j)
                    new.pop(i)
                    m = max(m, len(l) // 2 * gcd(l[i], l[j]) + dfs(tuple(new)))
                    # m = max(m, len(l) // 2 * d[l[i]][l[j]] + dfs(tuple(new)))
            return m

        return dfs(tuple(nums))

    # O(2**n * n^2 + logU * n^2) / O(2**n + n^2), 1500 ms, U = max(nums)
    def maxScore(self, nums: List[int]) -> int:
        def gcd(x: int, y: int) -> int:
            while y:
                x, y = y, x % y
            return x

        n = len(nums)
        g = [[0] * n for _ in range(n)]
        for i in range(n):
            for j in range(i + 1, n):
                g[i][j] = gcd(nums[i], nums[j])
        f = [0] * (1 << n)
        for k in range(1 << n):
            cnt = bin(k).count("1")
            if cnt % 2 == 0:
                for i in range(n):
                    if (k >> i) & 1:
                        for j in range(i + 1, n):
                            if (k >> j) & 1:
                                f[k] = max(
                                    f[k],
                                    f[k ^ (1 << i) ^ (1 << j)] + cnt // 2 * g[i][j],
                                )
        return f[(1 << n) - 1]

    def maxScore(self, nums: List[int]) -> int:
        def gcd(x: int, y: int) -> int:
            while y:
                x, y = y, x % y
            return x

        @functools.lru_cache(None)
        def dfs(mask: int, k: int) -> int:
            if k == len(nums) // 2 + 1:
                return 0
            r = 0
            for i in range(len(nums)):
                if mask & 1 << i:
                    continue
                for j in range(i + 1, len(nums)):
                    if mask & 1 << j:
                        continue
                    r = max(
                        r,
                        k * gcd(nums[i], nums[j]) + dfs(mask | 1 << i | 1 << j, k + 1),
                    )
            return r

        return dfs(0, 1)

    def maxScore(self, nums: List[int]) -> int:
        def gcd(x: int, y: int) -> int:
            while y:
                x, y = y, x % y
            return x

        @functools.lru_cache(None)
        def dfs(mask: int, k: int) -> int:
            if k == len(nums) // 2 + 1:
                return 0
            r = 0
            for i in range(len(nums)):
                if mask & 1 << i:
                    continue
                for j in range(i + 1, len(nums)):
                    if mask & 1 << j:
                        continue
                    r = max(
                        r,
                        k * gcd(nums[i], nums[j]) + dfs(mask ^ 1 << i ^ 1 << j, k + 1),
                    )
            return r

        return dfs(0, 1)


from sanic import Request
from sanic.exceptions import SanicException

def extract_request(*args) -> Request:
    request: Request
    if args and isinstance(args[0], Request):
        request = args[0]
    elif len(args) > 1:
        request = args[1]
    else:
        raise SanicException("Request could not be found")
    return request


import time
from json import dumps

from gatherer import Gatherer

def main():
    gatherer = Gatherer()
    try:
        while True:
            print(dumps(gatherer.collect(), indent=2))
            time.sleep(1)
    except KeyboardInterrupt:
        print("Closing script")

if __name__ == "__main__":
    main()


import json

from django.contrib import auth
from django.contrib.auth.middleware import RemoteUserMiddleware

class NginxAuthMiddleware(RemoteUserMiddleware):
    header = "HTTP_REMOTE_USER"
    roles_header = "HTTP_REMOTE_USER_ROLES"
    profile_header = "HTTP_REMOTE_USER_PROFILE"
    auth_header = "HTTP_REMOTE_USER_AUTH"

    def process_request(self,request):
        ###################################################################################
        ##Code Copied from RemoteUserMiddleware,  just comment auth.login(reuqest.user) ###
        ##############################################################################$####
        # AuthenticationMiddleware is required so that request.user exists.
        if not hasattr(request, 'user'):
            raise ImproperlyConfigured(
                "The Django remote user auth middleware requires the"
                " authentication middleware to be installed.  Edit your"
                " MIDDLEWARE_CLASSES setting to insert"
                " 'django.contrib.auth.middleware.AuthenticationMiddleware'"
                " before the RemoteUserMiddleware class.")
        try:
            username = request.META[self.header]
        except KeyError:
            # If specified header doesn't exist then remove any existing
            # authenticated remote-user, or return (leaving request.user set to
            # AnonymousUser by the AuthenticationMiddleware).
            if request.user.is_authenticated():
                self._remove_invalid_user(request)
            return
        # If the user is already authenticated and that user is the user we are
        # getting passed in the headers, then the correct user is already
        # persisted in the session and we don't need to continue.
        if request.user.is_authenticated():
            if request.user.get_username() == self.clean_username(username, request):
                return
            else:
                # An authenticated user is associated with the request, but
                # it does not match the authorized user in the header.
                self._remove_invalid_user(request)

        # We are seeing this user for the first time in this session, attempt
        # to authenticate the user.
        user = auth.authenticate(remote_user=username)
        if user:
            # User is valid.  Set request.user and persist user in the session
            # by logging the user in.
            request.user = user
            user_auth = request.META[self.auth_header]
            if not user_auth or user_auth != "basic":
                auth.login(request, user)

        ###################################################################################

        if request.user and request.user.is_authenticated():
            #user is authenticated
            user_roles = []
            try:
                user_roles_str = request.META[self.roles_header]
                if user_roles_str:
                    user_roles = [r.strip() for r in user_roles_str.split(";")]
            except:
                pass

            request.user._groups = user_roles
            request.user.is_staff = False
            request.user.is_active = True
            request.user.is_superuser = "admin" in user_roles

            user_profile = {}
            try:
                user_profile_str = request.META[self.profile_header]
                if user_profile_str:
                    user_profile = json.loads(user_profile_str)
            except:
                pass

            request.user.first_name = user_profile.get("first_name",None)
            request.user.last_name = user_profile.get("last_name",None)
            request.user.email = user_profile.get("email",None)


import math
from typing import Callable, List, Union

def load_data() -> List[str]:
    with open("data.txt", "r") as file:
        data = file.read().splitlines()
    return data

def round_half_up(number: Union[str, float], decimals: int = 0) -> int:
    multiplier = 10 ** decimals
    return int(math.floor(number * multiplier + 0.5) / multiplier)

def round_half_down(number: Union[str, float]) -> int:
    return round(float(number))

def process_position_mean(data: List[str]) -> List[float]:
    sums = [0] * len(data[0])
    for line in data:
        for i, d in enumerate(map(int, line)):
            sums[i] += d

    return [x / len(data) for x in sums]

def most_common_value(data: List[str], rounding_function: Callable = round) -> str:
    return "".join([str(rounding_function(number=x)) for x in process_position_mean(data=data)])

def least_common_value(data: List[str], rounding_function: Callable = round) -> str:
    return "".join([str(rounding_function(number=(-1 * (x - 1)))) for x in process_position_mean(data=data)])

def part_one() -> float:
    data = load_data()

    gamma = int(most_common_value(data=data), 2)
    epsilon = int(least_common_value(data=data), 2)

    return gamma * epsilon

def part_two() -> float:
    oxygen_generator_rating = load_data()
    co2_scrubber_rating = load_data()

    idx = 0
    while len(oxygen_generator_rating) > 1:
        _most_common = most_common_value(data=oxygen_generator_rating, rounding_function=round_half_up)[idx]
        oxygen_generator_rating = list(filter(lambda x: x[idx] == _most_common, oxygen_generator_rating))
        idx += 1
    oxygen_rating = int(oxygen_generator_rating[0], 2)

    idx = 0
    while len(co2_scrubber_rating) > 1:
        _least_common = least_common_value(data=co2_scrubber_rating, rounding_function=round_half_down)[idx]
        co2_scrubber_rating = list(filter(lambda x: x[idx] == _least_common, co2_scrubber_rating))
        idx += 1

    co2_rating = int(co2_scrubber_rating[0], 2)

    return oxygen_rating * co2_rating

if __name__ == "__main__":
    print("Day 3: Binary Diagnostic")
    print("-" * 80)
    result_part_1 = part_one()
    print(f"Part 1: What is the power consumption of the submarine?: {result_part_1}")
    print("-" * 80)
    result_part_2 = part_two()
    print(f"Part 2: What is the life support rating of the submarine?: {result_part_2}")
    print("-" * 80)


import datetime

class Interview:
    def __init__(self,vacancy,programmer,recruiter,candidate,dt,feedback,result):
        self.vacancy = vacancy
        self.programmer = programmer
        self.recruiter = recruiter
        self.candidate = candidate
        self.dt = dt
        self.feedback = feedback
        self.result = result

    @classmethod
    def next_day(cls,obj):
        #method that will add interview to next day
        vac = obj.vacancy
        prog = obj.programmer
        recr = obj.recruiter
        cand = obj.candidate
        real_dt = datetime.datetime.strptime(obj.dt,"%Y-%m-%d")
        dt = datetime.datetime(real_dt.year, real_dt.month, real_dt.day + 1).strftime("%Y-%m-%d")
        return cls(vac,prog,recr,cand,dt,"","")

#testing
new_int = Interview("C#","Ivanov","Zhorov","Alex","2020-01-12","","")
print(new_int.dt)
next_day_int = Interview.next_day(new_int)
print(next_day_int.dt)


#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2020/12/19 1:48
# @Author  : strawsyz
# @File    : win_utils.py
# @desc:
import numpy
import win32api
import win32con
import win32gui
import win32ui
from PIL import Image

def get_window(class_name, title_name):
    window = win32gui.FindWindow(class_name, title_name)
    return window

def get_window_position(window):
    left, top, right, bottom = win32gui.GetWindowRect(window)
    return left, top, right, bottom

def get_sub_windows(parent_window):
    sub_windows = []
    win32gui.EnumChildWindows(parent_window, lambda window, param: param.append(window), sub_windows)
    return sub_windows

def get_window_title(window):
    title = win32gui.GetWindowText(window)
    return title

def get_class_name(window):
    class_name = win32gui.GetClassName(window)
    return class_name

def left_click(position: list):
    win32api.SetCursorPos(position)
    win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP | win32con.MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0)

def right_click(position: list):
    win32api.SetCursorPos(position)
    win32api.mouse_event(win32con.MOUSEEVENTF_RIGHTTUP | win32con.MOUSEEVENTF_RIGHTDOWN, 0, 0, 0, 0)

def close_window(window):
    win32gui.PostMessage(window, win32con.WM_CLOSE, 0, 0)

def show_all_windows():
    windows = []
    win32gui.EnumWindows(lambda window, param: param.append(window), windows)
    print("num of windows : {}".format(len(windows)))

    for window in windows:
        title = win32gui.GetWindowText(window)
        class_name = win32gui.GetClassName(window)
        print("window's title : {}\t class name : {}".format(title, class_name))

def capture_window(class_name: str, save_path: str):
    # get window
    window = win32gui.FindWindow(class_name, None)
    left, top, right, bottom = win32gui.GetWindowRect(window)
    width = right - left
    height = bottom - top
    # get window DC
    window_DC = win32gui.GetWindowDC(window)
    # create DC
    new_window_DC = win32ui.CreateDCFromHandle(window_DC)
    # create Compatible DC
    compatible_DC = new_window_DC.CreateCompatibleDC()
    # create bitmap
    bitmap = win32ui.CreateBitmap()
    # create space for bitmap
    bitmap.CreateCompatibleBitmap(new_window_DC, width, height)
    # save window shot  at compatible DC
    compatible_DC.SelectObject(bitmap)
    # save bitmap at window DC
    compatible_DC.BitBlt((0, 0), (width, height), new_window_DC, (0, 0), win32con.SRCCOPY)
    # save bitmap at local file
    bitmap.SaveBitmapFile(compatible_DC, save_path)

    # return PIL.Image
    bitmap_info = bitmap.GetInfo()
    bitmap_bits = bitmap.GetBitmapBits(True)
    image = Image.frombuffer("RGB", (bitmap_info['bmWidth'], bitmap_info['bmHeight']), bitmap_bits, "raw", "BGRX", 0, 1)

    # return numpy array
    bitmap_bits = bitmap.GetBitmapBits(True)
    np_array = numpy.frombuffer(bitmap_bits, dtype='uint8')
    np_array.shape = (height, width, 4)

    # release memory
    win32gui.DeleteObject(bitmap.GetHandle())
    compatible_DC.DeleteDC()
    new_window_DC.DeleteDC()
    win32gui.ReleaseDC(window, window_DC)

    return image, np_array


import logging
from plugin import Plugin
from pyglui import ui
from circle_detector import find_pupil_circle_marker
import cv2
import methods
import msgpack
import file_methods as fm
import csv
from video_capture import EndofVideoError
import cv2
import numpy as np
import os

logger = logging.getLogger(__name__)

class Gaze_Accuracy(Plugin):
    """
    This file is supposed to be used with Pupil's lab player software.
    Copy this file to player's plugin folder.
    """

    order = 1
    icon_chr = chr(0xEC11)
    icon_font = "pupil_icons"

    def __init__(self, g_pool):
        super().__init__(g_pool)
        self.frames = {}
        # self.export()
        video_path = self.g_pool.capture.source_path
        self.export_calibration_markers(
            video_path, intrinsics=self.g_pool.capture.intrinsics
        )

    def export(self):
        gaze_data = self.g_pool.gaze_positions.data
        cap = self.g_pool.capture

        with open("export_gazeframe.csv", "a", newline="") as csvfile:
            fieldnames = ["index", "gaze", "timestamp", "confidence"]
            writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
            writer.writeheader()
            for i in range(len(gaze_data)):
                frame = {}
                gaze = msgpack.unpackb(gaze_data[i].serialized, encoding="utf-8")
                norm_pos = gaze["norm_pos"]
                gaze_x = int(norm_pos[0] * cap.frame_size[1])
                gaze_y = int((1 - norm_pos[1]) * cap.frame_size[0])
                frame["index"] = i
                frame["gaze"] = (gaze_x, gaze_y)
                frame["timestamp"] = gaze["timestamp"]
                frame["confidence"] = gaze["confidence"]
                writer.writerow(frame)
        # world_frames = cap.get_frame_count()
        # while True:
        #     try:
        #         input_frame = cap.get_frame()
        #         gray = input_frame.gray
        #         frame_timestamp = input_frame.timestamp
        #         frame_index = input_frame.index
        #     except EndofVideoError:
        #         break
        # pass

    def recent_events(self, events):
        # asdf(events)
        pass

    def asdf(self, events):
        frame_index = events["frame"].index
        img = events["frame"].gray
        if not frame_index in self.frames:
            pos = find_pupil_circle_marker(img, scale=1)

            def get_gazes():
                for gaze_data in events["gaze"]:
                    gaze = msgpack.unpackb(gaze_data.serialized, encoding="utf-8")
                    norm_pos = gaze["norm_pos"]
                    gaze_x = int(norm_pos[0] * img.shape[1])
                    gaze_y = int((1 - norm_pos[1]) * img.shape[0])
                    yield [gaze_x, gaze_y, gaze["timestamp"], gaze["confidence"]]

            def get_circle():
                circles = pos[-1]["ellipses"] if len(pos) > 0 else None
                if circles is None:
                    return None
                circle_center = circles[0][0]
                y = int(circle_center[1])
                x = int(circle_center[0])
                radius = circles[-1][1][-1]
                marker_type = pos[-1]["marker_type"]
                return [x, y, radius, marker_type]

            circle = get_circle()
            # marker_type = None
            # if circle is not None:
            #     marker_type = circle[-1]
            #     circle.remove(marker_type)

            with open("export_dataframe.csv", "a", newline="") as csvfile:
                fieldnames = [
                    "index",
                    "gaze",
                    "circle",
                    "timestamp",
                    "confidence",
                    "marker_type",
                ]
                writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
                # writer.writeheader()
                i = 0
                for gaze in get_gazes():
                    frame = {}
                    frame["index"] = frame_index + i
                    frame["gaze"] = (gaze[0], gaze[1])
                    frame["circle"] = circle
                    frame["timestamp"] = gaze[2]
                    frame["confidence"] = gaze[3]
                    writer.writerow(frame)
                    self.frames[frame_index] = frame
                    # i += 1

            # img = cv2.circle(img, gaze, int(10), (0, 0, 255), 2)
            # img = cv2.circle(img, circle[0], int(20), (0, 0, 255), 2)
            # cv2.imshow("img", img)
            # cv2.waitKey(1)

    def init_ui(self):
        self.add_menu()
        self.menu.label = "Export Markers"
        self.menu.append(
            ui.Info_Text(
                "Calibration marker will be automatically exported "
                "if this plugin is activated. "
            )
        )

    def deinit_ui(self):
        self.remove_menu()

    def write_to_csv(self, save_path, locations):
        save_path = os.path.join(save_path, "markers_norm_3d.csv")
        with open(save_path, "w", newline="") as csvfile:
            fieldnames = ["world_index", "marker", "marker_norm", "marker_type"]
            writer = csv.DictWriter(
                csvfile,
                fieldnames=fieldnames,
                quoting=csv.QUOTE_NONE,
                delimiter=",",
                quotechar="",
            )
            writer.writeheader()
            writer.writerows(locations)

    def export_calibration_markers(self, video_path, intrinsics):
        markers = self.get_location_from_frame(video_path)
        locations = [sample[0]["marker"] for sample in markers]
        undistorted_3d = intrinsics.unprojectPoints(locations, normalize=True)
        calibration_markers = []
        for dis, loc in zip(undistorted_3d, markers):
            temp = {}
            temp["marker_norm"] = dis
            temp["marker"] = loc[0]["marker"]
            temp["world_index"] = loc[0]["world_index"]
            temp["marker_type"] = loc[0]["marker_type"]
            calibration_markers.append(temp)
        save_path = os.path.dirname(video_path)
        self.write_to_csv(save_path, calibration_markers)

    def find_circle_marker(self, img, frame_num):
        img = cv2.medianBlur(img, 5)
        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        circles = cv2.HoughCircles(
            gray,
            cv2.HOUGH_GRADIENT,
            1,
            700,
            param1=300,
            param2=30,
            minRadius=15,
            maxRadius=100,
        )

        marker_list = []
        if circles is not None:
            circles = np.uint16(np.around(circles))
            for i in circles[0, :]:
                marker_dict = {}
                midpoint = img[i[1]][i[0]]
                bgr_sum = sum(midpoint)
                if bgr_sum > 400:
                    marker_dict["marker_type"] = "Stop"
                else:
                    marker_dict["marker_type"] = "Ref"
                marker_dict["marker"] = np.array([i[0], i[1]])
                marker_dict["world_index"] = frame_num
                marker_list.append(marker_dict)
        return marker_list

    def get_location_from_frame(self, video_path):
        locations = []
        cap = cv2.VideoCapture(video_path)
        frame_num = 0
        frames_count = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
        while cap.isOpened():
            err, frame = cap.read()
            if not err:
                break
            print((frame_num / frames_count) * 100)
            marker = self.find_circle_marker(frame, frame_num)
            if len(marker) > 0:
                locations.append(marker)
            # if frame_num>10:
            #     break
            frame_num += 1
        cap.release()
        return locations


from flask import Blueprint, render_template
from app.forms import TradeForm
from app.extensions import db
import pandas as pd
from app.models import Player_Stats

trades_bp = Blueprint('trades', __name__)

@trades_bp.route('/trades')
def index():
    form = TradeForm()
    return render_template('trades/index.html', form=form)

@trades_bp.route('/trades/create', methods=['GET', 'POST'])
def create():
    form = TradeForm()

    #####
    # Raw SQL
    sql_check_player = f"select * from players where name = '{form.PlayerName.data}'"
    df_check = pd.read_sql_query(sql_check_player, db.get_engine())
    #####

    if df_check.shape[0] == 0:
        message = f"{form.PlayerName.data} is not a valid player name. Try again."
        return render_template("trades/index.html", form=form, message=message)

    #####
    # Raw SQL
    sql_get_tm_abbrev = f"select teamabbr from teams where teamname = '{form.TeamName.data}'"
    df = pd.read_sql_query(sql_get_tm_abbrev, db.get_engine())
    #####

    team_abbr = df.teamabbr[0]

    #####
    # ORM
    db.session.query(Player_Stats)\
       .filter(Player_Stats.player == form.PlayerName.data)\
       .update({Player_Stats.tm: team_abbr})
    db.session.commit()
    #####

    message = f"Success! {form.PlayerName.data} is now on team: {form.TeamName.data} ({team_abbr})"
    return render_template("trades/index.html", form=form, message=message)


from django.conf.urls import include, url
from django.views.generic.base import RedirectView
from rest_framework import routers
from django.contrib import admin
from rest_framework.authtoken.views import obtain_auth_token

from api.views import AllViewSet, RandomJokes
import obcy.views as obcy
import api.views as api
import accounts.views as accounts

admin.autodiscover()

router = routers.DefaultRouter()
router.register(r'obcy', AllViewSet, 'obcy')
router.register(r'random', RandomJokes, 'random')

urlpatterns = [
    url(r'^admin/', include(admin.site.urls)),
    # obcy
    url(r'^$', obcy.all_sites),
    url(r'^obcy/random/$', obcy.all_random),
    url(r'^obcy/unverified/$', obcy.unverified),
    url(r'^obcy/(?P<jokeslug>.+)/$', obcy.one_joke),
    url(r'^(wykop|codzienny|zacny)/(?P<key>.+)$',
        RedirectView.as_view(url='/obcy/%(key)s', permanent=True)),
    url(r'^obcy/edit/(?P<pk>.+)$', obcy.edit_joke),
    url(r'^obcy/delete/(?P<pk>.+)$', obcy.delete_joke),
    url(r'^obcy/duplicate/(?P<pk>.+)/(?P<key>.+)$', obcy.duplicate_joke),
    url(r'^obcy/clean$', obcy.clean_joke),
    url(r'^obcy/verify/(?P<pk>.+)$', obcy.verify_joke),
    url(r'^obcy/revisions/(?P<pk>.+)$', obcy.get_revisions),
    # autorski
    # url(r'^autorskie/$', 'autorski.views.all_jokes'),
    # url(r'^autorskie/(?P<jokeslug>.+)/$', 'autorski.views.one_joke'),
    # accounts
    url(r'^signin/', accounts.signin),
    url(r'^signup/', accounts.signup),
    url(r'^logout/', accounts.logout_view),
    url(r'^fb-login/', accounts.fb_login),
    # api
    url(r'^api/', include(router.urls)),
    url(r'^register/$', api.register_device),
    url(r'^unregister/$', api.deactivate_device),
    url(r'^api/token/$', obtain_auth_token),
    # other
    url(r'^favicon\.ico$', RedirectView.as_view(url='/static/images/favicon.ico', permanent=True)),
    url(r'^apk/$', RedirectView.as_view(url='/static/files/suchary.apk', permanent=True)),
]

from django.contrib.staticfiles.urls import staticfiles_urlpatterns

urlpatterns += staticfiles_urlpatterns()


import matplotlib.pyplot as plt

a = 1.43
b = 0.5
c = -1.8

x0 = 0.1
y0 = 0.2
z0 = 0.3

x = 0
y = 0
z = 0

fx = []
fy = []
fz = []

r = []

n = 1000
m = 1000

for j in range(m):
    for i in range(n):
        z = b * x0 + a * z0 + c * y0 - y0 ** 2
        x = y0
        y = z0

        z0 = z
        x0 = x
        y0 = y

    for i in range(n):
        z = b * x0 + a * z0 + c * y0 - y0 ** 2
        x = y0
        y = z0

        z0 = z
        x0 = x
        y0 = y

        fz.append(z0)
        fx.append(x0)
        fy.append(y0)
        r.append(c)

    c += 0.001

fig, ax1 = plt.subplots()
ax1.plot(r, fx, 'r.', ms=0.01);

fig, ax2 = plt.subplots()
ax2.plot(fy, fx, 'g.', ms=0.01);

plt.show()


'''Resnet-18 in PyTorch
Inspired by https://github.com/kuangliu/pytorch-cifar/blob/master/models/resnet.py
'''

import torch
from torch import nn, optim
import torch.nn.functional as F
from models.models_nn import AE

class ResizeConv2d(nn.Module):

    def __init__(self, in_channels, out_channels, kernel_size, scale_factor, mode='nearest'):
        super().__init__()
        self.scale_factor = scale_factor
        self.mode = mode
        self.conv = nn.Conv2d(in_channels, out_channels, kernel_size, stride=1, padding=1)

    def forward(self, x):
        x = F.interpolate(x, scale_factor=self.scale_factor, mode=self.mode)
        x = self.conv(x)
        return x

class BasicBlockEnc(nn.Module):

    def __init__(self, in_planes, stride=1):
        super().__init__()

        planes = in_planes*stride

        self.conv1 = nn.Conv2d(in_planes, planes, kernel_size=3, stride=stride, padding=1, bias=False)
        self.bn1 = nn.BatchNorm2d(planes)
        self.conv2 = nn.Conv2d(planes, planes, kernel_size=3, stride=1, padding=1, bias=False)
        self.bn2 = nn.BatchNorm2d(planes)

        if stride == 1:
            self.shortcut = nn.Sequential()
        else:
            self.shortcut = nn.Sequential(
                nn.Conv2d(in_planes, planes, kernel_size=1, stride=stride, bias=False),
                nn.BatchNorm2d(planes)
            )

    def forward(self, x):
        out = torch.relu(self.bn1(self.conv1(x)))
        out = self.bn2(self.conv2(out))
        out += self.shortcut(x)
        out = torch.relu(out)
        return out

class BasicBlockDec(nn.Module):

    def __init__(self, in_planes, stride=1):
        super().__init__()

        planes = int(in_planes/stride)

        self.conv2 = nn.Conv2d(in_planes, in_planes, kernel_size=3, stride=1, padding=1, bias=False)
        self.bn2 = nn.BatchNorm2d(in_planes)
        # self.bn1 could have been placed here, but that messes up the order of the layers when printing the class

        if stride == 1:
            self.conv1 = nn.Conv2d(in_planes, planes, kernel_size=3, stride=1, padding=1, bias=False)
            self.bn1 = nn.BatchNorm2d(planes)
            self.shortcut = nn.Sequential()
        else:
            self.conv1 = ResizeConv2d(in_planes, planes, kernel_size=3, scale_factor=stride)
            self.bn1 = nn.BatchNorm2d(planes)
            self.shortcut = nn.Sequential(
                ResizeConv2d(in_planes, planes, kernel_size=3, scale_factor=stride),
                nn.BatchNorm2d(planes)
            )

    def forward(self, x):
        out = torch.relu(self.bn2(self.conv2(x)))
        out = self.bn1(self.conv1(out))
        out += self.shortcut(x)
        out = torch.relu(out)
        return out

class ResNet18Enc(nn.Module):

    def __init__(self, num_Blocks=[2,2,2,2], z_dim=10, nc=3):
        super().__init__()
        self.in_planes = 64
        self.z_dim = z_dim
        self.conv1 = nn.Conv2d(nc, 64, kernel_size=3, stride=2, padding=1, bias=False)
        self.bn1 = nn.BatchNorm2d(64)
        self.layer1 = self._make_layer(BasicBlockEnc, 64, num_Blocks[0], stride=1)
        self.layer2 = self._make_layer(BasicBlockEnc, 128, num_Blocks[1], stride=2)
        self.layer3 = self._make_layer(BasicBlockEnc, 256, num_Blocks[2], stride=2)
        self.layer4 = self._make_layer(BasicBlockEnc, 512, num_Blocks[3], stride=2)
        self.linear = nn.Linear(512, 2 * z_dim)

    def _make_layer(self, BasicBlockEnc, planes, num_Blocks, stride):
        strides = [stride] + [1]*(num_Blocks-1)
        layers = []
        for stride in strides:
            layers += [BasicBlockEnc(self.in_planes, stride)]
            self.in_planes = planes
        return nn.Sequential(*layers)

    def forward(self, x):
        x = torch.relu(self.bn1(self.conv1(x)))
        x = self.layer1(x)
        x = self.layer2(x)
        x = self.layer3(x)
        x = self.layer4(x)
        x = F.adaptive_avg_pool2d(x, 1)
        x = x.view(x.size(0), -1)
        x = self.linear(x)
        mu = x[:, :self.z_dim]
        return mu

class ResNet18Dec(nn.Module):

    def __init__(self, num_Blocks=[2,2,2,2], z_dim=10, nc=3):
        super().__init__()
        self.in_planes = 512

        self.linear = nn.Linear(z_dim, 512)

        self.layer4 = self._make_layer(BasicBlockDec, 256, num_Blocks[3], stride=2)
        self.layer3 = self._make_layer(BasicBlockDec, 128, num_Blocks[2], stride=2)
        self.layer2 = self._make_layer(BasicBlockDec, 64, num_Blocks[1], stride=2)
        self.layer1 = self._make_layer(BasicBlockDec, 64, num_Blocks[0], stride=1)
        self.conv1 = ResizeConv2d(64, nc, kernel_size=3, scale_factor=2)
        self.nc = nc

    def _make_layer(self, BasicBlockDec, planes, num_Blocks, stride):
        strides = [stride] + [1]*(num_Blocks-1)
        layers = []
        for stride in reversed(strides):
            layers += [BasicBlockDec(self.in_planes, stride)]
        self.in_planes = planes
        return nn.Sequential(*layers)

    def forward(self, z):
        x = self.linear(z)
        x = x.view(z.size(0), 512, 1, 1)
        x = F.interpolate(x, scale_factor=4)
        x = self.layer4(x)
        x = self.layer3(x)
        x = self.layer2(x)
        x = self.layer1(x)
        x = torch.sigmoid(self.conv1(x))
        x = x.view(x.size(0), self.nc, 64, 64)
        return x

class ResnetV2(AE):
    # 64x64
    def __init__(self, latent_dim, nc, action_dim, encoding, fc_hidden1=1024, fc_hidden2=768, drop_p=0.3, CNN_embed_dim=256):
        encoder = ResNet18Enc(z_dim=latent_dim, nc=nc)
        decoder = ResNet18Dec(z_dim=latent_dim, nc=nc)

        super(ResnetV2, self).__init__(encoder, decoder, latent_dim, action_dim, encoding)

class ResnetV2_Lie(AE):
    # 64x64
    def __init__(self, extra_dim, nc, action_dim, group_dim, encoding, regularization, fc_hidden1=1024, fc_hidden2=768, drop_p=0.3, CNN_embed_dim=256):
        latent_dim = extra_dim + action_dim
        encoder = ResNet18Enc(z_dim=latent_dim, nc=nc)
        decoder = ResNet18Dec(z_dim=extra_dim + group_dim, nc=nc)

        super(ResnetV2_Lie, self).__init__(encoder, decoder, latent_dim, action_dim, encoding, regularization)

class Decoder(nn.Module):
    def __init__(self, extra_dim, group_dim, nc):
        super().__init__()
        self.decoder = ResNet18Dec(z_dim=extra_dim + group_dim, nc=nc)

    def forward(self, z):
        return self.decoder(z)

    def decode(self, z):
        return self.decoder(z)


import os
import re
import math
import sys
import json

mainHash  = {}
stopwords = {}

def getWordHash(pathOfRoot):
    HashOfWords = {}
    for rootPath, subdirs, allFiles in os.walk(pathOfRoot):
        for everyFile in allFiles:
            if everyFile.endswith(".txt") and everyFile != 'README.txt':
                eachFle = os.path.join(rootPath, everyFile)
                with open(eachFle, 'r') as openedFile:
                    dataInFile = openedFile.read()
                    for oneLine in dataInFile.splitlines():
                        oneLine = re.sub('[^A-Za-z0-9\@#\$_]', ' ', oneLine)
                        wordsInLine = oneLine.split()
                        for eachword in wordsInLine:
                            word1 = eachword.lower()
                            if stopwords.has_key(word1) : continue
                            if word1 != '':
                                if HashOfWords.has_key(word1):
                                    countOfWords = HashOfWords[word1]
                                    countOfWords += 1
                                    HashOfWords[word1] = countOfWords
                                else:
                                    HashOfWords[word1] = 1

    return HashOfWords
#_______________________________________________________________
def populateHash(currentClassWords,classToBeMatched):

    wordsFromOtherClasses = {}
    if classToBeMatched != 'negTru':
        for word in negTruWordHash:
            if not currentClassWords.has_key(word): wordsFromOtherClasses[word] = 1
    if classToBeMatched != 'posDec':
        for word in posDecWordHash:
            if not currentClassWords.has_key(word): wordsFromOtherClasses[word] = 1
    if classToBeMatched != 'posTru':
        for word in posTruWordHash:
            if not currentClassWords.has_key(word): wordsFromOtherClasses[word] = 1
    if classToBeMatched != 'negDec':
        for word in negDecWordHash:
            if not currentClassWords.has_key(word): wordsFromOtherClasses[word] = 1

    for word in wordsFromOtherClasses:
        currentClassWords[word] = 1
    for word in currentClassWords:
        if not wordsFromOtherClasses.has_key(word):
            earlierCount = int(currentClassWords[word])
            earlierCount += 1
            currentClassWords[word] = earlierCount
    return currentClassWords
#_______________________________________________________
def getProbabilityHash(hashOfWords):
    totalCount = 0
    for i in hashOfWords.keys():
        totalCount+=hashOfWords[i]
    probTable = {}
    for i in hashOfWords.keys():
        probTable[i] = math.log10(float(hashOfWords[i])) - math.log10(totalCount)
    return probTable
#___________________________________________________
with open('stopwords.txt', 'r') as fp:
    stopwords = json.load(fp)

mainPath = sys.argv[1]
negDecPath = mainPath + 'negative_polarity/deceptive_from_MTurk'
negDecWordHash = getWordHash(negDecPath)
negTruPath = mainPath + 'negative_polarity/truthful_from_Web'
negTruWordHash = getWordHash(negTruPath)
posDecPath = mainPath + 'positive_polarity/deceptive_from_MTurk'
posDecWordHash = getWordHash(posDecPath)
posTruPath = mainPath + 'positive_polarity/truthful_from_TripAdvisor'
posTruWordHash = getWordHash(posTruPath)

negTruWordHash = populateHash(negTruWordHash,'negTru')
posDecWordHash = populateHash(posDecWordHash,'posDec')
posTruWordHash = populateHash(posTruWordHash,'posTru')
negDecWordHash = populateHash(negDecWordHash,'negDec')

negDecProbHash = getProbabilityHash(negDecWordHash)
mainHash['negative_deceptive'] = negDecProbHash
negTruProbHash = getProbabilityHash(negTruWordHash)
mainHash['negative_truthful'] = negTruProbHash
posDecProbHash = getProbabilityHash(posDecWordHash)
mainHash['positive_deceptive'] = posDecProbHash
posTruProbHash = getProbabilityHash(posTruWordHash)
mainHash['positive_truthful'] = posTruProbHash
with open('nbmodel.txt', 'w') as fp:
    json.dump(mainHash, fp)


import sys
import csv
import requests
import xml.etree.ElementTree as ET

# read the WXR input file (just an RSS XML file) from STDIN
wxr = sys.stdin.read()
wxrRoot = ET.fromstring(wxr)
namespaces = {
	'wp': 'http://wordpress.org/export/1.2/'
}

# prep the CSV output
output = csv.writer(sys.stdout)

# parse through each item in the RSS file
channel = wxrRoot.find('channel')
for item in channel.findall('item'):

	# skip anything that's not a media post type
	postTypeTag = item.find('wp:post_type', namespaces)
	if postTypeTag.text != 'attachment':
		continue

	# gather all the necessary data from the XML file
	id = item.find('wp:post_id', namespaces).text
	title = item.find('title').text
	url = item.find('wp:attachment_url', namespaces).text

	# get the file size from the server
	response = requests.head(url)
	filesize = 0
	if response.status_code == requests.codes.ok:
		filesize = response.headers['Content-Length']

	# print the data in CSV format
	output.writerow([id, title, url, filesize])


import cv2

trained_face_data = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')

# On lit test.jpg
img = cv2.imread("images_test\\test.jpg")

# changement vers un format non RGB
grayScaled_img = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)

# On récupère les coordonnées (x y w h) du visage sur la photo
face_coordinates = trained_face_data.detectMultiScale(grayScaled_img)
# print(face_coordinates)

# Pour chaque visages detecté on dessine un rectangle autour des visages
for (x, y, w, h) in face_coordinates:
    # param_1 = l'image sur laquel nous voulons afficher nos rectangles
    # param_2 = un tuple des coordonnées en haut à gauche
    # param_3 = un tuple des coordonnées en bas à droit
    # param_4 = un tuple de couleur BGR
    # param_5 = L'épaisseur du rectangle
    cv2.rectangle(img, (x, y), (x+w, y+h), (0, 255, 0), 3)

# Affiche une image
cv2.imshow("test", img)     # affichage de l'image originale
# imshow("test", grayScaled_img)     # affichage de l'image grisé

# Attend la pression d'une touche
cv2.waitKey()


from chests.chest import Chest
from chests.chest_color import ChestColor
from common.helpers import get_user_int_input

CHESTS = [
    Chest(name='Regular'),
    Chest(name='Wooden', color=ChestColor.BROWN),
    Chest(name='Metal', color=ChestColor.PURPLE),
    Chest(name='Gold', color=ChestColor.GOLD),
    Chest(name='Crystal', color=ChestColor.BLUE),
    Chest(name='Jail', color=ChestColor.GRAY),
    Chest(name='Adventure', color=ChestColor.RED)
]

def find_chest_by_color(color: ChestColor) -> Chest | None:
    for chest in CHESTS:
        if chest.color == color:
            return chest
    return None

def calculate_chest_bcoin_rewards(chest: Chest, quantity) -> float:
    return chest.get_bcoin_rewards() * quantity

if __name__ == '__main__':
    wooden_chest = find_chest_by_color(ChestColor.BROWN)
    metal_chest = find_chest_by_color(ChestColor.PURPLE)
    gold_chest = find_chest_by_color(ChestColor.GOLD)
    crystal_chest = find_chest_by_color(ChestColor.BLUE)
    adventure_chest = find_chest_by_color(ChestColor.RED)
    jail_chest = find_chest_by_color(ChestColor.GRAY)

    wooden_chests_quantity = get_user_int_input("Quantity of wood (brown) chests: ")
    metal_chests_quantity = get_user_int_input("Quantity of metal (purple) chests: ")
    gold_chests_quantity = get_user_int_input("Quantity of gold (yellow) chests: ")
    crystal_chests_quantity = get_user_int_input("Quantity of crystal (blue) chests: ")
    adventure_chests_quantity = get_user_int_input("Quantity of adventure (red) chests: ")
    jail_chests_quantity = get_user_int_input("Quantity of jail (gray) chests: ")

    wooden_chest_rewards = calculate_chest_bcoin_rewards(wooden_chest, wooden_chests_quantity)
    metal_chest_rewards = calculate_chest_bcoin_rewards(metal_chest, metal_chests_quantity)
    gold_chest_rewards = calculate_chest_bcoin_rewards(gold_chest, gold_chests_quantity)
    crystal_chest_rewards = calculate_chest_bcoin_rewards(crystal_chest, crystal_chests_quantity)
    adventure_chest_rewards = calculate_chest_bcoin_rewards(adventure_chest, adventure_chests_quantity)
    jail_chest_rewards = calculate_chest_bcoin_rewards(jail_chest, jail_chests_quantity)

    print()
    print(f'Wooden chests rewards: {wooden_chest_rewards:.5f}')
    print(f'Metal chests rewards: {metal_chest_rewards:.5f}')
    print(f'Gold chests rewards: {gold_chest_rewards:.5f}')
    print(f'Crystal chests rewards: {crystal_chest_rewards:.5f}')
    print(f'Adventure chests rewards: {adventure_chest_rewards:.5f}')
    print(f'Jail chests rewards: {jail_chest_rewards:.5f}')

    print()
    total_bcoins = wooden_chest_rewards + metal_chest_rewards + gold_chest_rewards + crystal_chest_rewards
    print(f'Total bcoins: {total_bcoins:.5f}')

    input('Press any key to exit.')


from django.test import TestCase
from datetime import datetime, timedelta
from django.utils.crypto import get_random_string

from apps.student.repositories.downloadinformationrepository import DownloadInformationRepository
from apps.student.queries.downloadinformationquery import DownloadInformationQuery

class DownloadInformationRepositoryTestCase(TestCase):

    def test(self):

        report_id = "R000001"
        user_id = "U0001"

        DownloadInformationRepository().insert(report_id, user_id)

        result_list = DownloadInformationQuery().select_all_by_report_id(report_id)
        download_information = result_list[0]

        self.assertEqual(download_information.report_id, report_id)
        self.assertEqual(download_information.user_id, user_id)

        DownloadInformationRepository().delete(download_information)

        result_list = DownloadInformationQuery().select_all_by_report_id(report_id)

        self.assertEqual(len(result_list), 0)


import numpy as np
from numpy import ndarray
from pydicom import dcmread, FileDataset

def convert_dicom(case_id, img_id, with_metadata=False):

    ds: FileDataset = dcmread(f'assets/dcm/{case_id}/{case_id}_{img_id}.dcm')

    dicom_hu = ds.pixel_array * ds.RescaleSlope + ds.RescaleIntercept

    pixel_data_uint32_scaled: ndarray = np.uint32(dicom_hu)

    output_json = {
        "pixelData": pixel_data_uint32_scaled.tolist()
    }

    if with_metadata:
        output_json["metadata"] = ds.to_json_dict()

    return output_json


import wx

from db import LineSamplePrescription
from misc import calc_quantity, note_str_to_db
from state.linedrug_states import NewLineDrugListState, NewLineDrugListStateItem
from ui.dialogs.sample_prescription_dialog import SampleDialog
from ui.generics import AddBitmapBtn, DeleteBitMapBtn
from ui.mainview_widgets.order_book.prescription_page import page

class AddDrugButton(AddBitmapBtn):
    def __init__(self, parent):
        super().__init__(parent)
        self.parent: page.PrescriptionPage

    def Add(self):
        page = self.parent
        mv = self.parent.mv
        state = mv.state
        wh = state.warehouse
        ld = state.linedrug
        if wh is None:
            return

        times = int(page.times.Value.strip())
        dose = page.dose.Value.strip()
        quantity = int(page.quantity.Value.strip())
        note = note_str_to_db(
            wh.usage, times, dose, wh.usage_unit, self.parent.note.Value
        )

        if page.check_wh_do_ti_qua_filled():
            if ld:
                ld.times = times
                ld.dose = dose
                ld.quantity = quantity
                ld.usage_note = note
                idx: int = page.drug_list.GetFirstSelected()
                page.drug_list.update_ui(idx, ld)
            else:
                new_ld = NewLineDrugListStateItem(
                    wh.id, times, dose, quantity, note, False
                )
                NewLineDrugListState.append_state(mv, new_ld)
            state.warehouse = None
            state.linedrug = None
            mv.price.FetchPrice()
            page.drug_picker.SetFocus()

class DeleteDrugButton(DeleteBitMapBtn):
    def __init__(self, parent):
        super().__init__(parent)
        self.parent: page.PrescriptionPage

    def Delete(self):
        idx: int = self.parent.drug_list.GetFirstSelected()
        if idx != -1:
            old = self.parent.mv.state.old_linedrug_list
            new = self.parent.mv.state.new_linedrug_list
            if idx < len(old):
                self.parent.mv.state.to_delete_old_linedrug_list.append(old[idx])
                old.pop(idx)
            else:
                idx -= len(old)
                new.pop(idx)
            self.parent.drug_list.pop_ui(idx)
            self.parent.mv.state.warehouse = None
            self.parent.mv.state.linedrug = None
            self.parent.mv.price.FetchPrice()

class ReuseDrugListButton(wx.Button):
    def __init__(self, parent: "page.PrescriptionPage"):
        super().__init__(parent, label="Lượt khám mới với toa cũ này")
        self.parent = parent
        self.mv = parent.parent.mv
        self.Bind(wx.EVT_BUTTON, self.onClick)

    def onClick(self, _):
        _list = self.mv.state.old_linedrug_list.copy()
        weight = self.mv.weight.GetWeight()
        self.mv.state.visit = None
        self.mv.weight.SetWeight(weight)
        self.mv.state.old_linedrug_list = []
        self.parent.drug_list.rebuild(_list)
        for old_linedrug in _list:
            self.mv.state.new_linedrug_list.append(
                NewLineDrugListStateItem(
                    warehouse_id=old_linedrug.warehouse_id,
                    times=old_linedrug.times,
                    dose=old_linedrug.dose,
                    quantity=old_linedrug.quantity,
                    usage_note=old_linedrug.usage_note,
                    outclinic=old_linedrug.outclinic,
                )
            )
        self.mv.updatequantitybtn.update_quantity()

class UseSamplePrescriptionBtn(wx.Button):
    def __init__(self, parent: "page.PrescriptionPage"):
        super().__init__(parent, label="Sử dụng toa mẫu")
        self.parent = parent
        self.mv = parent.parent.mv
        self.Bind(wx.EVT_BUTTON, self.onClick)

    def onClick(self, _):
        dlg = SampleDialog(self.mv)
        if dlg.ShowModal() == wx.ID_OK:
            idx: int = dlg.samplelistctrl.GetFirstSelected()
            sp_id: int = int(dlg.samplelistctrl.GetItemText(idx))
            if idx != -1:
                self.parent.drug_list.DeleteAllItems()
                self.mv.state.to_delete_old_linedrug_list.extend(
                    self.mv.state.old_linedrug_list.copy()
                )
                self.mv.state.old_linedrug_list.clear()
                self.mv.state.new_linedrug_list.clear()
                sp = self.mv.state.all_sampleprescription[sp_id]
                for lsp in (
                    LineSamplePrescription(*row)
                    for row in self.mv.connection.execute(
                        f"SELECT * FROM {LineSamplePrescription.__tablename__} WHERE sample_id = {sp.id}"
                    ).fetchall()
                ):
                    item = NewLineDrugListStateItem(
                        warehouse_id=lsp.warehouse_id,
                        times=lsp.times,
                        dose=lsp.dose,
                        quantity=calc_quantity(
                            lsp.times,
                            lsp.dose,
                            self.mv.days.Value,
                            self.mv.state.all_warehouse[lsp.warehouse_id].sale_unit,
                            self.mv.config,
                        ),
                        usage_note=None,
                        outclinic=False,
                    )
                    self.parent.drug_list.append_ui(item)
                    self.mv.state.new_linedrug_list.append(item)
                self.mv.price.FetchPrice()


# imports:
import os
import sys
import copy
import json
import subprocess

# constants:
TITLE = """
███████╗██╗    ██╗██╗████████╗ ██████╗██╗  ██╗███████╗██████╗
██╔════╝██║    ██║██║╚══██╔══╝██╔════╝██║  ██║██╔════╝██╔══██╗
███████╗██║ █╗ ██║██║   ██║   ██║     ███████║█████╗  ██████╔╝
╚════██║██║███╗██║██║   ██║   ██║     ██╔══██║██╔══╝  ██╔══██╗
███████║╚███╔███╔╝██║   ██║   ╚██████╗██║  ██║███████╗██║  ██║
╚══════╝ ╚══╝╚══╝ ╚═╝   ╚═╝    ╚═════╝╚═╝  ╚═╝╚══════╝╚═╝  ╚═╝
"""

BUFFER_SIZE = 32
TYPING_DILAY = 0.05

file_path = sys.argv[0]
WORK_DIR = file_path[:len(file_path) - file_path[::-1].find('/')]

with open(os.path.join(WORK_DIR, 'run.command')) as f:
    lines = f.readlines()

PRIME_TYPING_CHANGE_ACTIVATION = [c for c in \
                                  lines[0][lines[0].find("'") + 1: len(lines[0]) - lines[0][::-1].find("'") - 1]]

ACTIVATION_SIZE = len(PRIME_TYPING_CHANGE_ACTIVATION)

CONFIG_JSON_PATH = os.path.join(WORK_DIR, 'language_config.json')
CONVERSION_JSON_PATH = os.path.join(WORK_DIR, 'conversion_chart_ABC_Hebrew.json')

LAYOUT_RETURN_PREFIX = '"KeyboardLayout Name" = '
LAYOUT_RETURN_POSTFIX = ';\n    }\n)'

# apple scripts:
CHANGE_LANGUAGE_SCRIPT = "osascript -e 'tell application \"System Events\" to tell process \"SystemUIServer\" to " \
                         "keystroke space using {control down}' "

GET_CURRENT_LAYOUT_SCRIPT = "defaults read ~/Library/Preferences/com.apple.HIToolbox.plist AppleSelectedInputSources"

GET_ACTIVE_WINDOW_SCRIPT = "osascript -e 'tell app \"System Events\" to get name of first process whose frontmost is " \
                           "true' "

# functions:
def load_json(path):
    """
    Load a json file.
    :param path: the path to the json file.
    :return: the json file as a dict.
    """
    with open(path) as f:
        return json.load(f)

MAIN_LAYOUT, SECONDARY_LAYOUT = list(load_json(CONVERSION_JSON_PATH).keys())
CONVERSION_PAIRS = load_json(CONVERSION_JSON_PATH)

def run_script(script):
    """
    Run a script and return the output.
    :param script: applescript string to run.
    :return: the output from the activation.
    """
    return subprocess.check_output(script, shell=True).decode('utf-8').strip()

def get_current_layout():
    """
    Get the current keyboard layout.
    :return: the current keyboard layout.
    """

    current_layout = run_script(GET_CURRENT_LAYOUT_SCRIPT)
    return current_layout[current_layout.find(LAYOUT_RETURN_PREFIX) + len(LAYOUT_RETURN_PREFIX):
                          current_layout.find(LAYOUT_RETURN_POSTFIX)]

def convert_typing(layout, stack):
    """
    Convert the typing from one language to another.
    :param stack: text to convert as a list.
    :param layout: current keyboard language.
    :return: the converted text.
    """
    if layout != MAIN_LAYOUT and layout != SECONDARY_LAYOUT:
        return copy.deepcopy(stack)
    else:
        return [CONVERSION_PAIRS[layout][key] if key in CONVERSION_PAIRS[layout] else key
                for key in stack]

SECONDARY_TYPING_CHANGE_ACTIVATION = convert_typing(MAIN_LAYOUT, PRIME_TYPING_CHANGE_ACTIVATION)

def start_message():
    print(TITLE)
    print('=' * 65)
    print(' ' * 25,  'Activities log:')
    print('=' * 65)
    print()