import cv2
import numpy as np
from typing import Tuple
from nptyping import NDArray
from random import randint
from math import pi, hypot
from typing import Dict, Union, List

COLOR = Tuple[int, int, int]

global default_params
global default_hsv
global default_categories

default_categories = (
    {
        "size": 4.2,
        "name": "High Velocity",
        "causes": (
            "Gunshots",
            "Explosions",
            "High-Speed Vehicle Collision"
        )
    },
    {
        "size": 7.0,
        "name": "Medium Velocity",
        "causes": (
            "Blunt Force Trauma",
            "Cutting",
            "Stabbing"
        )
    },
    {
        "size": 10.0,
        "name": "Low Velocity",
        "causes": (
            "Slashes",
            "Swipes",
            "Running",
            "Idle Blood Loss"
        )
    }
)
default_params = {
    "filterByArea": True,
    "minArea": 20,
    "filterByCircularity": True,
    "minCircularity": 0.35,
    "filterByConvexity": True,
    "minConvexity": 0.40
}
default_hsv = {
    "hsv_range": ((120, 15, 50), (20, 255, 255)),
    "percentage": 0.2
}

def annotate_image_blobs(img: NDArray, keypoints: Tuple, color: COLOR = (0, 0, 255)) -> NDArray:
    blank = np.zeros((1, 1))
    blobs_image = cv2.drawKeypoints(img, keypoints, blank,
                                    color, cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)

    return blobs_image

def detect_blobs(img: NDArray, **kwargs) -> NDArray:

    params = cv2.SimpleBlobDetector_Params()

    params.filterByArea = kwargs.get('filterByArea', False)
    params.minArea = kwargs.get('minArea', 20)

    params.filterByCircularity = kwargs.get('filterByCircularity', False)
    params.minCircularity = kwargs.get('minCircularity', 0.8)

    params.filterByConvexity = kwargs.get('filterByConvexity', False)
    params.minConvexity = kwargs.get('minConvexity', 0.2)

    params.filterByInertia = kwargs.get('filterByInertia', False)
    params.minInertiaRatio = kwargs.get('minInertiaRatio', 0.01)

    detector = cv2.SimpleBlobDetector_create(params)
    keypoints = detector.detect(img)

    return keypoints

def create_solid_image(width: int, height: int, color: COLOR = (255, 255, 255)) -> NDArray:
    img = np.zeros([width, height, 3], dtype=np.uint8)
    img[:] = color

    return img

def draw_random_blobs(img: NDArray, amount: int = 10, blob_size: Tuple = (5, 20), color: COLOR = (0, 0, 0)) -> NDArray:
    min_size, max_size = blob_size
    width, height, _ = img.shape

    # Add Random Black Blobs To Numpy Array
    for _ in range(amount):
        x_pos = randint(0, width)
        y_pos = randint(0, height)
        x_size = randint(min_size, max_size)
        y_size = randint(min_size, max_size)
        cv2.ellipse(img, (x_pos, y_pos), (x_size, y_size), 0, 0, 360, color, -1)

    img = cv2.GaussianBlur(img, (5, 5), 0)

    return img

def overflow_hsv(img: NDArray, hsv_range: Tuple[COLOR, COLOR]) -> NDArray:
    min_hue, min_sat, min_val = hsv_range[0]
    max_hue, max_sat, max_val = hsv_range[1]

    if min_hue > max_hue:
        mask1 = cv2.inRange(img, (min_hue, min_sat, min_val), (180, max_sat, max_val))
        mask2 = cv2.inRange(img, (0, min_hue, min_val), hsv_range[1])
        results = cv2.bitwise_or(mask1, mask2)

    else:
        results = cv2.inRange(img, hsv_range[0], hsv_range[1])

    return results

def create_hsv_range(hsv: Tuple, hue_range=20, sat_range=20, value_range=20) -> Tuple[COLOR, COLOR]:
    hue, saturation, value = hsv

    high_hue = min(hue + hue_range, 255)
    high_sat = min(saturation + sat_range, 255)
    high_val = min(value + value_range, 255)

    high_range = (high_hue, high_sat, high_val)

    low_hue = min(hue - hue_range, 255)
    low_sat = min(saturation - sat_range, 255)
    low_val = min(value - value_range, 255)

    low_range = (low_hue, low_sat, low_val)

    return (low_range, high_range)

def detect_blobs_verbose(img, mask, **kwargs):
    params = cv2.SimpleBlobDetector_Params()

    params.filterByArea = kwargs.get('filterByArea', False)
    params.minArea = kwargs.get('minArea', 20)

    params.filterByCircularity = kwargs.get('filterByCircularity', False)
    params.minCircularity = kwargs.get('minCircularity', 0.8)

    params.filterByConvexity = kwargs.get('filterByConvexity', False)
    params.minConvexity = kwargs.get('minConvexity', 0.2)

    params.filterByInertia = kwargs.get('filterByInertia', False)
    params.minInertiaRatio = kwargs.get('minInertiaRatio', 0.01)

    detector = cv2.SimpleBlobDetector_create(params)
    keypoints, descriptors = detector.detectAndCompute(img)

    return keypoints, descriptors

def hsv_filter_blobs(img: NDArray, keypoints, hsv_range, percentage: float) -> Tuple:
    valid_blobs = []

    # Convert Image To HSV For Better Filtering
    hsv_img = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

    # Construct Binary Mask From HSV Range
    mask = overflow_hsv(hsv_img, hsv_range)

    # Grab Configuration Paramaters From Image
    width, height, _ = img.shape

    for pt in keypoints:
        # Configure Base Area
        radius = int(pt.size // 2)
        diameter = int(radius * 2)

        area =  pi * (radius ** 2)

        # Get Clamped Parameters For Edges
        left = int(pt.pt[0]) - radius
        right = int(pt.pt[0] + radius)
        bottom = int(pt.pt[1]) - radius
        top = int(pt.pt[1] + radius)

        # Generate Cropped Coordinates From Image Size
        crop_left = max(left, 0)
        crop_right = min(right, height)
        crop_top = min(top, width)
        crop_bottom = max(bottom, 0)

        # Cache Displacement For Cropping
        dL = crop_left - left
        dB = crop_bottom - bottom

        if crop_right != right:
            dR = crop_right - right
        else:
            dR = None

        if crop_top != top:
            dT = crop_top - top
        else:
            dT = None

        # Construct Blob Binary Cookie
        blank = np.zeros([right-left, top-bottom, 3], dtype=np.uint8)

        x = blank.shape[0] // 2
        y = blank.shape[1] // 2

        blob = cv2.ellipse(blank, (x, y), (radius, radius), 0, 0, 360, (255, 255, 255), thickness=-1)
        blob = cv2.cvtColor(blob, cv2.COLOR_BGR2GRAY)

        # Crop Generated Cookie
        blob = blob[dB:dT, dL:dR]

        # Crop Blob Segment From HSV Mask
        hsv_mask = mask[crop_bottom: crop_top, crop_left: crop_right]

        # Overlap Both Masks
        overlay = cv2.bitwise_and(blob, blob, mask=hsv_mask)
        valid_pixels = cv2.countNonZero(overlay)

        #Filter Blobs
        if valid_pixels / area >= percentage:
            valid_blobs.append(pt)

    return tuple(valid_blobs)

def create_blob_display(img: NDArray, blobs: Tuple, bg_color: COLOR = (0, 0, 0),
                     weight: float = 1.0) -> NDArray:
    """
    Generates an image with detected blobs highlighted.

    :param img:
    :param blobs:
    :return:
    """

    width, height, _ = img.shape

    xOff, yOff = (20, 20)

    # Generate Mask Array
    fg = np.zeros([width, height, 3], dtype=np.uint8)

    # Apply Background Color Effects
    bg_array = create_solid_image(width, height, bg_color)
    lerped_img = cv2.addWeighted(bg_array, weight, img, (1.0 - weight), 0.0)

    if blobs:
        for i, blob in enumerate(blobs):
            x = int(blob.pt[0])
            y = int(blob.pt[1])

            diameter = int(blob.size)

            fg_mask = cv2.ellipse(fg, ((x, y), (diameter, diameter), 0), (255, 255, 255), thickness=-1)

        fg_mask = cv2.cvtColor(fg_mask, cv2.COLOR_BGR2GRAY)
        bg_mask = cv2.bitwise_not(fg_mask)

        # Generate Colored Masks
        colored_fg = cv2.bitwise_or(img, img, mask=fg_mask)
        colored_bg = cv2.bitwise_or(lerped_img, lerped_img, mask=bg_mask)

        # Combine Colored Masks
        results = colored_bg + colored_fg
    else:
        results = lerped_img

    results = cv2.putText(results, str(len(blobs)), (0, 0), cv2.FONT_HERSHEY_SIMPLEX,
                     50, (255, 255, 255), 2, cv2.LINE_AA)

    return results

def aruco_ratio(img, detector, marker_length) -> Tuple[bool, int, float]:
    img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

    # Detect AruCo Stickers
    corners, ids, rejected = detector.detectMarkers(img)

    if corners:
        # Modify Existing Image With Markers
        detected_image = cv2.aruco.drawDetectedMarkers(img, corners, ids)

        # Format Into Most Salient Marker Corners
        corners = [corner for corner in corners[0][0]]

        # Use Hypotenuse Calculation To Calculate Each Side Length
        sizes = [0.0] * 4
        for i in range(4):
            p1 = corners[i]

            if i < 3:
                p2 = corners[i + 1]
            else:
                p2 = corners[0]

            # Calculate Line Length Between Corners
            deltaX = abs(p1[0] - p2[0])
            deltaY = abs(p1[1] - p2[1])

            sizes[i] = hypot(deltaX, deltaY)

        # Average Corner Sizes To Account For Rotation
        avg_size = np.average(sizes)

        # Return mm To Pixel Ratio
        ratio = marker_length / avg_size

        return (True, ids[0][0], ratio)

    return (False, None, 0.0)

def generate_aruco_detector(type):
    dict = cv2.aruco.getPredefinedDictionary(type)
    params = cv2.aruco.DetectorParameters()
    detector = cv2.aruco.ArucoDetector(dict, params)

    return detector

def categorize_blobs(blobs, ratio: float, categories=default_categories) -> List[str]:
    """
    Categories blobs into named list based on pixel values of blob sizes
    and aruco px2mm ratio. Needs tuple of dict with "name" and "size"
    attributes per grouping.

    :param blobs:
    :param categories:
    :param ratio:
    :return:
    """

    l = len(categories)

    results = []
    for blob in blobs:
        blob_mm = ratio * blob.size

        i = 0
        while True:
            if blob_mm < categories[i]["size"]:
                results.append((categories[i]["name"], blob_mm))
                break

            if i == (l - 1):
                results.append((categories[-1]["name"], blob_mm))
                break

            i += 1

    return results

def draw_blob_categories(img: NDArray, blobs, categories,
                         color: COLOR = (255, 255, 255)) -> NDArray:

    # Draw Top-Left Labels
    img = cv2.putText(img, "Low Velocity", (0, 40), cv2.FONT_HERSHEY_SIMPLEX,
                        0.5, color, 1, cv2.LINE_AA)
    img = cv2.putText(img, "Medium Velocity", (250, 40), cv2.FONT_HERSHEY_SIMPLEX,
                      0.5, color, 1, cv2.LINE_AA)
    img = cv2.putText(img, "High Velocity", (500, 40), cv2.FONT_HERSHEY_SIMPLEX,
                      0.5, color, 1, cv2.LINE_AA)

    for i, blob in enumerate(blobs):
        x = int(blob.pt[0])
        y = int(blob.pt[1])

        name = categories[i][0]

        if name == "Low Velocity":
            x0, y0 = (50, 50)
        elif name == "Medium Velocity":
            x0, y0 = (300, 50)
        else:
            x0, y0 = (550, 50)

        img = cv2.line(img, (x0, y0), (x, y), color, 1)

    return img

def draw_blob_sizes(img: NDArray, blobs, sizes, color: COLOR = (255, 255, 255)) -> NDArray:
    xOff = 0
    yOff = 15

    for i, blob in enumerate(blobs):
        x = int(blob.pt[0])
        y = int(blob.pt[1])

        img = cv2.putText(img, f"{sizes[i]:.2f}mm", (x + xOff, y + yOff),
                          cv2.FONT_HERSHEY_SIMPLEX, 0.2, color, 1, cv2.LINE_AA)

    return img

def binary_range_search(key: Union[float, int], target: Tuple, **kwargs) -> Tuple:
    """Uses Binary Search Algorithm To Clamp Value Into Range In O(log n)"""

    # Grab cached left/right if recursion
    left = kwargs.get("left", 0)
    right = kwargs.get("right", len(target) - 1)

    if left == right:
        if right == 0:
            return (None, target[0])
        else:
            return (target[-1], None)

    mid = (left + right) // 2
    if target[mid] <= key:
        if target[mid + 1] > key:
            return (target[mid], target[mid + 1])
        else:
            return binary_range_search(key, target, left=mid + 1, right=right)
    else:
        return binary_range_search(key, target, left=left, right=mid)


import sys
import re
import json
import pandas as pd
import os

from openpyxl import Workbook, load_workbook

def first_step():
    try:
        sale = pd.read_csv("./商品別売上.csv", encoding="shift-jis")
        saleName_sample = pd.read_csv("./商品一括編集.csv", encoding="shift-jis", usecols=[4])
        janCode_sample = pd.read_csv("./商品一括編集.csv", encoding="shift-jis", usecols=[15])
    except IOError:
        print("Error:商品別売上.csvまたは商品一括編集.csvファイルを見つかりませんでした")
    sampleAll = pd.concat([saleName_sample, janCode_sample], axis=1)
    saleName = sale['商品名']
    saleNameList = saleName.values.tolist()
    sampleAllList = sampleAll.values.tolist()

    janCodeList = []
    k = 0

    for i in saleNameList:
        for j in sampleAllList:
            if i == j[0]:
                if k == 0:
                    if type(j[1]) == float:
                        continue
                    else:
                        j[1] = j[1].replace("#", "")
                        janCodeList.append(j[1])
                else:
                    continue
                k = 1
        if k == 1:
            k = 0
            continue
        else:
            janCodeList.append("null")
            k = 0
    sale['janCode'] = janCodeList
    sale.to_excel("統計済み.xlsx", index=None)

# 统计商品利润
def find_check_result(sheetName):
    try:
        f = pd.ExcelFile('./統計済み.xlsx')
    except IOError:
        print("Error:ファイル統計済み.xlsxは見つかりませんでした")
    output_result = []
    check_result = read_check_result(sheetName)  # 统计商品成本
    df = f.parse(0)  # 使用第一个工作薄
    df_list = list(df)
    rowLength = 0
    wb = Workbook()  # 创建バーコードない記録工作表
    page = wb.active
    page.title = 'バーコードない記録'
    page.append(df_list)
    tempList = []

    for index, row in df[0:].iterrows():  # 从第二行开始加载数据。
        rowLength = rowLength + 1
        if not pd.isnull(df.loc[index, df_list[11]]) and (str(round(row[11])).isdigit()):  # 判断バーコード是否为数字，是否非null,nan
            for check_item in check_result:  # 判断バーコード是否相等
                if check_item[0] == str(round(row[11])):
                    print(index, row[0], row[11], check_item[1], row[3], row[7],
                          int(row[3]) - (int(check_item[1]) * int(row[7])))
                    output_result.append((index, check_item[1], str(int(row[3]) - (int(check_item[1]) * int(row[7])))))
                    tempList.append(index)

    for index, row in df[0:].iterrows():  # 从第二行开始加载数据。
        if index not in tempList:
            page.append(row.tolist())
    wb.save('./商品別売上_バーコードない記録.xlsx')
    return output_result, rowLength

# 统计商品成本
def read_check_result(sheetName):
    check_result_list = []
    file_path = './商品管理表.xlsx'
    try:
        of = pd.ExcelFile(file_path)
    except IOError:
        print("ファイル商品管理表.xlsxは見つかりませんでした")
    odf = of.parse(0) if sheetName == None else of.parse(sheet_name=sheetName)
    odf_list = list(odf)
    for index, row in odf[3:].iterrows():
        # print(index, str(row[5]), str(row[6]), pd.isnull(odf.loc[index, odf_list[10]]))
        if (str(row[6]).isdigit()) and not pd.isnull(odf.loc[index, odf_list[10]]):  # 判断バーコード是否成本和个数是否存在
            check_result_list.append((odf.loc[index, odf_list[6]], round(odf.loc[index, odf_list[10]])))

    return check_result_list

# 将商品利润和商品总计记录下来
def write_excel(output_result, rowLength):
    output_file_path = r'.\統計済み.xlsx'
    wb = load_workbook(filename=output_file_path)
    print("output_result, rowLength ", output_result, rowLength)
    result, lastRow = output_result, rowLength
    total = 0
    for name in wb.sheetnames:
        print(name)
        for output in result:
            total = total + int(output[2])
            wb[name].cell(row=1, column=13).value = "仕入値（税込）"
            wb[name].cell(row=int(output[0]) + 2, column=13).value = output[1]
            wb[name].cell(row=1, column=14).value = "利潤"
            wb[name].cell(row=int(output[0]) + 2, column=14).value = output[2]
            wb[name].cell(row=lastRow + 2, column=13).value = "合計"
            wb[name].cell(row=lastRow + 2, column=14).value = total
    wb.save(output_file_path)

if __name__ == '__main__':
    first_step()
    # sheetName = sys.argv[1] if len(sys.argv) > 1 else None  # 传入店铺名使用对应"店铺名"的工作薄，否则使用第一个工作薄
    sheetName = input("商品管理表のシート名を入力してください:")
    output_result, rowLength = find_check_result(sheetName)  # 统计商品的成本和利润
    write_excel(output_result, rowLength)  # 写入excel文件


# coding: utf-8
# stack
# [입력]
# N : 탑의 수
# a b c d : 탑의 높이
# [출력]
# 자신을 기준으로 왼쪽의 탑 중 키번호가 자기 바로 앞인 탑

import sys
import collections

N = int(sys.stdin.readline())
Height = collections.deque(map(int, sys.stdin.readline().split()))
result = collections.deque([0])
stack = collections.deque([1])
stack.appendleft(Height.popleft())

i = 1
while Height:
    # 스택의 top과 비교하여 작으면 스택에 push
    if not stack or stack[0] > Height[0]:
        p = Height.popleft()
        i += 1
        if stack:
            result.append(stack[1])
        else:
            result.append(0)
        stack.appendleft(i) # 탑 번호 push
        stack.appendleft(p) # 탑 높이 push
    else:
        stack.popleft()
        stack.popleft()

sys.stdout.write(' '.join(map(str, result)) + '\n')


#!/usr/bin/env python
# coding: utf-8

# In[62]:

import pandas as pd

#this helps with the formatting of text, images
from PIL import Image, ImageDraw, ImageFont

#loading the data
#replace ./Names.xlsx with the path to your file
data = pd.read_excel ('./Names.xlsx')

#replace Name with the column containing the names in your file
#assigning the name, date and signature with their respective fonts and font size
for i in data["Name"]:
    if len(i)>20:
        #you can change the font size and font url according to your taste
        font_size = ImageFont.truetype(r"c:\users\latee\appdata\local\microsoft\windows\fonts\product sans 400.ttf", 120)
    else:
        font_size = ImageFont.truetype(r"c:\users\latee\appdata\local\microsoft\windows\fonts\product sans 400.ttf", 100)
    im = Image.open('./certificate.png')
    d = ImageDraw.Draw(im)

    #the values should be changed to fit your text appropriately
    name_location = (1272, 1210)
    signature = (786, 1800)
    date = (2050, 1800)
    text_color = (0, 0, 0)
    font = ImageFont.truetype(r"c:\WINDOWS\FONTS\ITCEDSCR.ttf", 120)
    d.text(name_location, i, fill = text_color, font = font_size)
    d.text(signature, "CinnamonXI", fill = text_color, font = font)
    d.text(date, "01-10-2020", fill = text_color, font = font_size)
    im.save(i + ".png")

#if you encounter any issue you can reach our on twitter twitter.com/CinnamonXi


from django.shortcuts import redirect, render
from django.views.decorators.csrf import csrf_exempt
from collection.apps import CollectionConfig
from .predict import make_wav2img
from .models import Cough, Info

def index(request):

    return render(request, 'index.html')

@csrf_exempt
def audio(request):
    if request.method == 'POST':
        try:
            Cough.objects.create(
                audio = request.FILES['audio_data'],
                title = str(request.FILES['audio_data'])
            )
        except:
            print("Error in Cough create")

    return render(request, 'index.html')

def infer(request):
    cough = Cough.objects.last()
    audio_path = cough.audio.path
    image_path = make_wav2img(audio_path)
    pred, nums = CollectionConfig.predict_audio(image_path)
    cough.mel = image_path[8:]
    cough.prediction = pred
    cough.save()

    return render(request, 'infer.html', {'prediction':pred, 'nums':nums})

'''여러 page version'''

def info(request):
    if request.method == 'POST':
        info = Info.objects.create(
            age = request.POST['age'],
            region = request.POST['region'],
            sex = request.POST['sex'],
            state = request.POST['state'],
            disease = request.POST.getlist('disease')
        )

        return redirect('pred')

    return render(request, 'info.html')

@csrf_exempt
def pred(request):
    if request.method == 'POST':
        try:
            Cough.objects.create(
                audio = request.FILES['audio_data'],
                title = str(request.FILES['audio_data'])
            )
        except:
            print("Error in Cough create")

        return redirect('res')

    return render(request, 'pred.html')

def res(request):
    cough = Cough.objects.last()
    audio_path = cough.audio.path
    image_path = make_wav2img(audio_path)
    prediction, nums = CollectionConfig.predict_audio(image_path)
    cough.mel = image_path[8:]
    cough.prediction = prediction
    cough.save()
    print("--------")
    print(nums)

    return render(request, 'res.html', {'prediction':prediction, 'nums':nums})


h = { 4: 7,
      5: 2,
      2: 8,
      6: 1,
     12: 2,
    }

for k in h:
    print(k, h[k])

print('****')

for k,v in h.items():
    print(k, v)

print('****')

h_keys = list(h.keys())
h_keys.sort()
for k in h_keys:
    print(k, h[k])

print('**** nach Häufigkeit sortieren ')

h_rev = {}
# key und value vertauschen, funktioniert NUR
# wenn die Values auch eindeutig sind!!!
for k,v in h.items():
    h_rev[v] = k

h_rev_keys = list(h_rev.keys())
h_rev_keys.sort()
for k in h_rev_keys:
    print(k, h_rev[k])

print('**** nach Häufigkeit sortieren korrekt')

from collections import OrderedDict

h_sorted_by_val = OrderedDict(sorted(h.items(), key = lambda x: x[1]))
for k,v in h_sorted_by_val.items():
    print(k, v)

print('**** nach Häufigkeit manuell')
from pprint import pprint
'''
teilnehmer = [
        ['Magdalena', 1982],
        ['Herbert', 1973],
        ['Tobias', 1984],
        ['Clemens', 1989],
        ['Sarah', 1994],
        ['Elias', 1997],
        ['Zsolt', 1988],
        ['Birgit', 1987],
        ['Lorenz', 1987],
    ]

teilnehmer.sort()

pprint(teilnehmer)
'''

# h_as_list = [ list(h.values()), list(h.keys()) ]
h_as_list = []
for k,v in h.items():
    h_as_list.append([v,k])

h_as_list.sort()
pprint(h_as_list)


import datetime
from django.db import models
from .assignment import Assignment

GRADES = [
    ('A', 'отлично'),
    ('B', 'хорошо'),
    ('C', 'удовлетворительно'),
    ('D', 'неудовлетворительно'),
    ('F', 'плохо')
]
SCHEDULED = 'S'
ACCEPTED = 'A'
COMPLETED = 'C'
POSTPONED = 'P'
DECLINED = 'D'
STATUSES = [
    (SCHEDULED, 'Запланирована'),
    (ACCEPTED, 'Подтверждена'),
    (POSTPONED, 'Перенесена'),
    (DECLINED, 'Отменена'),
    (COMPLETED, 'Завершена'),
]

class Training(models.Model):
    label = models.CharField(
        'заголовок',
        max_length=55,
        default='Новая'
    )
    assignment = models.ForeignKey(
        Assignment,
        on_delete=models.SET_NULL,
        blank=True,
        null=True,
        verbose_name='назначение'
    )
    dt = models.DateTimeField('дата и время начала тренировки')
    duration = models.DurationField(
        'продолжительность тренировки',
        default=datetime.timedelta(hours=1)
    )
    description = models.TextField(
        'описание',
        blank=True,
        default=''
    )
    coach_notes = models.TextField(
        'замечания тренера',
        blank=True,
        default=''
    )
    coach_grade = models.CharField(
        'оценка тренера',
        max_length=1,
        choices=GRADES,
        blank=True,
        null=True
    )
    member_comment = models.TextField(
        'комментарий занимающегося',
        blank=True,
        default=''
    )
    status = models.CharField(
        'статус тренировки',
        max_length=1,
        choices=STATUSES,
        default=SCHEDULED
    )

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

    def __str__(self):
        return self.label


while True:
    print()
    task = int(input("Введіть номер завдання: "))
    if task == 0:
        break

    # Завдання №1
    elif task == 1:
        print("Завдання №1")

        greeting = "Hello, "
        name = "Sviatoslav"
        print(greeting+name)
        print()

    # Завдання №2
    elif task == 2:
        print("Завдання №2")

        number1 = 20
        x = number1
        number2 = 6
        y = number2
        number3 = x + y
        number4 = x - y
        number5 = x * y
        number6 = x / y
        number7 = x ** y
        number8 = x // y
        number9 = x % y
        print(number3, number4, number5, number6, number7, number8, number9, sep="; ")
        print()

    # Завдання №3
    elif task == 3:
        print("Завдання №3")

        value = input("Введіть число: ")
        if value.isnumeric():
            value = int(value)
            print("Тип даних —", type(value), "\n")
        else:
            print("Ви ввели текст, замість числа", "\n" "Тип даних —", type(value), "\n")

    # Завдання №4
    elif task == 4:
        print("Завдання №4")

        value_1 = input("Введіть число: ")
        if value_1.isnumeric():
            value_1 = int(value_1)
        else:
            print("Ви ввели текст, замість числа", "\n")

        value_2 = input("Введіть друге число: ")
        if value_2.isnumeric():
            value_2 = int(value_2)
            print("Результат:", "\n")
        else:
            print("Ви ввели текст, замість числа", "\n")

        print("Додавання =", value_1 + value_2)
        print("Віднімання =", value_1 - value_2)
        print("Множення =", value_1 * value_2)
        print("Ділення =", value_1 / value_2)
        print("Возведення у ступінь =", value_1 ** value_2)
        print("Цілочисленне ділення =", value_1 // value_2)
        print("Остача при діленні =", value_1 % value_2)
        print()

    # Завдання №5
    elif task == 5:
        print("Завдання №5")
        import datetime

        username = input("Введіть своє ім'я: ")
        birth_year = int(input("Введіть свій рік народження: "))
        current_year = datetime.datetime.now().year
        age = current_year - birth_year
        print("Привіт, " + username + "! Тобі зараз " + str(age) + " років.")
        print()

    # Завдання №---
    elif task >= 6:
        print("Святослав, таких завдань ти ще не робив!", "\n")

Module №1. Python Basics/2. Основні типи даних та операції/1-2.py


from __future__ import absolute_import, division, print_function

import os
import time
import types
import collections
import json

import cv2
import fire
import numpy as np
import pandas as pd
from logzero import logger
from rmexp import client, schema, utils, dbutils
from rmexp.schema import models

def interval_extract(list, slack=30):
    length = len(list)
    i = 0
    while (i < length):
        low = list[i]
        while i < length - 1 and (list[i + 1] - list[i]) < slack:
            i += 1
        high = list[i]
        if (high - low >= 1):
            yield [low, high]
        elif (high - low == 1):
            yield [low, ]
            yield [high, ]
        else:
            yield [low, ]
        i += 1

def get_trace_frames(app, trace_id):
    df = pd.read_sql(
        "select value from DataStat where app=%(app)s and trace=%(trace_id)s",
        schema.engine,
        params={'app': app, 'trace_id': trace_id}
    )
    datastat = json.loads(df['value'].iloc[0])
    total_frs = datastat['frames']
    return total_frs

def get_ss_df(app, trace_id):
    """Return symbolic state dataframes in the same order as they appear in the database.
    By default, they are ordered as frame sequence.
    """
    name = '{}-tr{}'.format(app, trace_id)
    df = pd.read_sql(
        "select * from SS where name like %(name)s",
        schema.engine,
        params={'name': name}
    )
    # SS's database frame index somehow started from 1, this is to fix it
    df['index'] = df['index'].astype('int32') - 1
    return df

def get_gt_active_df(app, trace_id):
    df = pd.read_sql(
        "select * from DutyCycleGT where name=%(app)s and trace=%(trace_id)s",
        schema.engine,
        params={'app': app, 'trace_id': trace_id}
    )
    df['index'] = df['index'].astype('int32')
    return df

def store_to_gt_inst(app, trace_id, stat):
    with dbutils.session_scope(dry_run=False) as sess:
        dbutils.insert_or_update_one(
            sess,
            models.GTInst,
            {'app': app, 'trace': str(trace_id)},
            {'value': stat}
        )

def upload_lego_gt_inst_idx(trace_id, detected_stages, store=False):
    """called by duty-cycle.ipynb
    """
    stage_idx = [int(stage[0]) for stage in detected_stages]
    app = 'lego'
    stat = json.dumps(
        {
            'inst_idx': stage_idx
        }
    )
    logger.info('{} trace {}: {}'.format(app, trace_id, stat))
    if store:
        store_to_gt_inst(app, trace_id, stat)

def upload_ikea_gt_inst_idx(trace_id, key_fids, store=False):
    """called by ikea_stats.ipynb
    """
    app = 'ikea'
    stat = json.dumps(
        {
            'inst_idx': key_fids
        }
    )
    logger.info('{} trace {}: {}'.format(app, trace_id, stat))
    if store:
        store_to_gt_inst(app, trace_id, stat)

def upload_pingpong_gt_inst_idx(trace_id, store=False):
    app = 'pingpong'
    ss_df = get_ss_df(app, trace_id)
    inst_idx = get_pingpong_inst_idx(ss_df)
    stat = json.dumps({
        'inst_idx': inst_idx
    })
    logger.info('{} trace {}: {}'.format(app, trace_id, stat))
    if store:
        store_to_gt_inst(app, trace_id, stat)

def upload_pool_gt_inst_idx(trace_id, store=False):
    app = 'pool'
    ss_df = get_ss_df(app, trace_id)
    inst_idx = get_pool_inst_idx(ss_df)
    stat = json.dumps({
        'inst_idx': inst_idx
    })
    logger.info('{} trace {}: {}'.format(app, trace_id, stat))
    if store:
        store_to_gt_inst(app, trace_id, stat)

def upload_face_gt_inst_idx(trace_id, store=False):
    app = 'face'
    ss_df = get_ss_df(app, trace_id)
    inst_idx = get_face_inst_idx(ss_df)
    stat = json.dumps({
        'inst_idx': inst_idx
    })
    logger.info('{} trace {}: {}'.format(app, trace_id, stat))
    if store:
        store_to_gt_inst(app, trace_id, stat)

def get_lego_inst_idx(ss_df):
    ss_df_inst = ss_df[ss_df['val'].str.contains(
        '!!State Change!!', regex=False)]
    inst_idx = ss_df_inst['index'].values.tolist()
    return inst_idx

def get_pingpong_inst_idx(ss_df):
    ss_df_inst = ss_df[ss_df['val'].str.contains('inst:', regex=False)]
    inst_idx = ss_df_inst['index'].values.tolist()
    return inst_idx

def get_pool_inst_idx(ss_df):
    ss_df_inst = ss_df[ss_df['val'].str.contains('speech:', regex=False)]
    inst_idx = ss_df_inst['index'].values.tolist()
    return inst_idx

def get_ikea_inst_idx(ss_df):
    ss_df_inst = ss_df[ss_df['val'].str.contains('Detected', regex=False)]
    inst_idx = ss_df_inst['index'].values.tolist()
    return inst_idx

def get_face_inst_idx(ss_df):
    labels = ['Edmund', 'Jan', 'Junjue', 'Tom', 'Wenlu', 'Zhuo']
    inst_idx = []
    for label in labels:
        ss_df_inst = ss_df[ss_df['val'] == label]
        label_idx = ss_df_inst['index'].values.tolist()
        label_idx = map(int, label_idx)
        label_idx_intervals = list(interval_extract(label_idx, slack=3))
        label_inst_idx = [interval[0] for interval in label_idx_intervals]
        inst_idx.extend(label_inst_idx)
    inst_idx = sorted(inst_idx)
    return inst_idx

def get_inst_idx(app, df):
    """Get instruction indexs from df.
    df must have a column named val that contains processed results.
    and index that represents frame ids
    """
    func_map = {
        'lego': get_lego_inst_idx,
        'pingpong': get_pingpong_inst_idx,
        'pool': get_pool_inst_idx,
        'face': get_face_inst_idx,
        'ikea': get_ikea_inst_idx
    }
    inst_idx = func_map[app](df)
    return map(int, inst_idx)

def get_gt_inst_idx(app, trace_id):
    df = pd.read_sql(
        "select value from GTInst where app=%(app)s and trace=%(trace_id)s",
        schema.engine,
        params={'app': app, 'trace_id': trace_id}
    )
    assert len(df.index) == 1
    datastat = json.loads(df['value'].iloc[0])
    # correct the index to start from 0
    correct_idx = map(lambda x: int(x) - 1, datastat['inst_idx'])
    return correct_idx

def get_exp_app_inst_for_client(exp, app, client_id):
    df = pd.read_sql(
        "select * from ExpLatency where name=%(exp)s and app=%(app)s and client=%(client_id)s",
        schema.engine,
        params={'app': app, 'client_id': client_id, 'exp': exp}
    )
    df['val'] = df['result']
    return get_inst_idx(app, df)

def get_exp_app_inst_delay_for_client(exp, app, client_id, trace_id):
    """Return the instruction delay in ms
    """
    df = pd.read_sql(
        "select * from ExpLatency where name=%(exp)s and app=%(app)s and client=%(client_id)s",
        schema.engine,
        params={'app': app, 'client_id': client_id,
                'exp': exp}
    )
    exp_inst_idx = get_exp_app_inst_for_client(exp, app, client_id)
    delays = []
    # pool, and pingpong are just proc delays
    # ikea uses proc delays as well for now
    if app == 'pool' or app == 'pingpong':
        for inst_idx in exp_inst_idx:
            proc_delay = df[df['index'] == str(inst_idx)]['reply'].mean()
            delays.append(round(proc_delay))
        return delays
    else:
        # for each state in the ground truth, try to find a corresponding instruction
        # this is done because for IKEA, the results may not actually be a state-change.
        # but we're considering a successsful detection of any object to be a state-change as
        # the video itself is not giving many chances for CV to produce the correct CV state
        gt_idx = np.array(get_gt_inst_idx(app, trace_id))
        prev_gt_idx = -1
        for inst_idx in exp_inst_idx:
            matched_gt_idx = gt_idx[gt_idx <= inst_idx][-1]
            # if a ground truth instruction has been matched then
            # do not match it again.
            if matched_gt_idx <= prev_gt_idx:
                continue
            frame_delay = inst_idx - matched_gt_idx
            prev_gt_idx = matched_gt_idx
            proc_delay = df[df['index'] == str(inst_idx)]['reply'].mean()
            delays.append(round(frame_delay * 1000. / 30. + proc_delay))
        return delays

def get_exp_app_inst_delay(exp, app):
    df = pd.read_sql(
        "select client, val from ExpLatency where name=%(exp)s and app=%(app)s group by client, val",
        schema.engine,
        params={'app': app, 'exp': exp}
    )
    client_ids = df['client'].values.tolist()
    trace_ids = df['val'].values.tolist()
    delays = {}
    for idx, client_id in enumerate(client_ids):
        delays[client_id] = get_exp_app_inst_delay_for_client(
            exp,
            app,
            client_id,
            trace_ids[idx]
        )
    return delays

def run_fsm_on_ss_for_inst(fsm, ss):
    """Run FSM with a sequence of CV symbolic states as inputs and get instructions.
    """
    return ss['val'].apply(fsm.add_symbolic_state_for_instruction)

def run_fsm_on_ss_for_samples_with_dynamic_rate(fsm, ss, dynamic_sampling_rate_func):
    """Simulate dynamic sampling rate.
    sample_rate_func: function of dynamic sample rate. Input should the the time after a given instruction.
    max_mute_t: maximum time this sample_rate_func is in place

    Return simulated trace, stage_frame_idx
    """
    last_inst_t = -np.inf  # timestamp of last instruction
    cur_t = 0.0  # current timestamp in (s)
    # timestamp to get next frame. => no frame is sampled when cur_t < next_frame_t
    next_frame_t = 0.0
    trace_frame_rate = 30.0  # frame rate of trace
    # time between two adjacent records in the traces
    trace_frame_interval = 1.0 / trace_frame_rate
    cur_sample_rate = dynamic_sampling_rate_func(cur_t - last_inst_t)

    sampled_ss = []
    detected_stages = []
    for fid, fss in ss.iterrows():
        # when its' time to sample
        if cur_t >= next_frame_t:
            # sample
            sampled_ss.append(fss)
            # get instruction
            inst = fsm.add_symbolic_state_for_instruction(fss['val'])
            # state transition occurred
            if inst is not None:
                cur_sample_rate = dynamic_sampling_rate_func(
                    1e-6)  # numerical approximation
                last_inst_t = cur_t
                detected_stages.append(fss['index'])
            else:
                cur_sample_rate = dynamic_sampling_rate_func(
                    cur_t - last_inst_t)
            next_frame_t = cur_t + 1.0 / cur_sample_rate
        # advance time
        cur_t += trace_frame_interval
    return pd.DataFrame(sampled_ss), detected_stages

if __name__ == "__main__":
    fire.Fire()


from itertools import izip

from maya import cmds

from brigks.systems.systemBuilder import SystemBuilder
from brigks.utils import constants, attributes, create, umath
from brigks import config

from math3d.transformation import Transformation, TransformationArray
from math3d.vectorN import Vector3, Vector3Array

class BreastSystemBuilder(SystemBuilder):

	def createObjects(self):
		# SIZE
		size = self.translations("Root").distance(self.translations("Eff"))

		# TRANSFORMATION
		# Normal
		normal = self.directions("Root", "z")

		direction = self.translations("Eff") - self.translations("Root")
		rootTfm = Transformation.lookAt(self.translations("Root"), direction, normal, self.nsign()+"yz", self.negate())
		dynTfm = Transformation.lookAt(self.translations("Root"), direction, normal, "xz", self.negate())
		posTfm = dynTfm.copy(translation=self.translations("Eff"))

		upvPos = Vector3([0,0,10]) * dynTfm.asMatrix()

		# OBJECTS
		# Controller
		self.dynBfr = self.addBfr(None, "Part1", dynTfm)
		self.dynCtl = self.addCtl(self.dynBfr, "Part1", dynTfm, "sphere", size=size, po=(self.factor(),0,0), so=(1,1,0), color=self.colorFk())
		attributes.setKeyables(self.dynCtl)
		# self.setInversedParameters(self.dynCtl, middle=["posz", "rotx", "roty"])

		self.posBfr = self.addBfr(self.dynBfr, "Part2", posTfm)
		self.posCtl = self.addCtl(self.posBfr, "Part2", posTfm, "sphere", size=size*1.5, so=[0,1,1], color=self.colorIk())
		attributes.setKeyables(self.posCtl)
		# self.setInversedParameters(self.posCtl, middle=["posz", "rotx", "roty"])

		# Dynamic ----------------------------
		self.harmonic = self.addRig(self.posCtl, "Harmonic", posTfm, "diamond", size=1)

	def createJoints(self):
		self.addJnt(self.harmonic, "Part1")

	#-------------------------------------------------------------------------------
	# PROPERTIES
	def createAttributes(self):
		self.dynamicAttr = self.addAnimAttr("dynamic", "bool", self.settings("dynActive"))
		self.amplitudeAttr = self.addAnimAttr("amplitude", "float", self.settings("amplitude"), 0, 5)

		if self.settings("dynamicAnimatable"):
			self.axisAttr = self.addAnimAttr("axis", "vector", (self.settings("amplitudeX"), self.settings("amplitudeY"), self.settings("amplitudeZ")))
			self.decayAttr = self.addAnimAttr("decay", "float", self.settings("decay"), 0, 10)
			self.terminationAttr = self.addAnimAttr("termination", "float", self.settings("termination"), 0, 1)
			self.frequencyAttr = self.addAnimAttr("frequency", "float", self.settings("frequency"), 0, 1)

	#-------------------------------------------------------------------------------
	# OPERATORS
	def createOperators(self):
		cns = self.addCompound("harmonic", "Dyn", self.harmonic, self.posCtl,
			amplitude=1.0,
			decay=self.settings("decay"),
			frequency=self.settings("frequency"),
			termination=self.settings("termination"),
			amplitudeAxis=(self.settings("amplitudeX"), self.settings("amplitudeY"), self.settings("amplitudeZ")))

		activeNode = self.addNode("multiplyDivide", name="active")
		cmds.connectAttr(self.amplitudeAttr, activeNode+".input1X")
		cmds.connectAttr(self.dynamicAttr, activeNode+".input2X")

		cmds.connectAttr(activeNode+".outputX", cns+".amplitude")

		if self.settings("dynamicAnimatable"):
			cmds.connectAttr(self.axisAttr, cns+".axisAmp")
			cmds.connectAttr(self.decayAttr, cns+".decay")
			cmds.connectAttr(self.terminationAttr, cns+".termination")
			cmds.connectAttr(self.frequencyAttr, cns+".frequencyMult")

		# Vertical controller
		self.addCompound("blendMatrix", "Breast", self.posBfr, [self.dynCtl], maintainOffset=True, rotate=False, scale=False)

	#-------------------------------------------------------------------------------
	# CONNECTION
	def createConnections(self):
		if "Root" in self.connections():
			root = self.getObject(config.USE_BFR, "Part1")
			self.connections("Root").connect(root)


from ctypes import sizeof
import queue
import numpy as np
import random
from typing import List, Callable
import timeit

############################### I-A ##############################################
def matrix_multiplication(m_1: np.ndarray, m_2: np.ndarray)-> np.ndarray:
    c1 = m_1.shape[1]
    r1 = m_1.shape[0]
    r2 = m_2.shape[0]
    c2 = m_2.shape[1]

    if(c1 != r2):
        return None

    r = np.zeros([r1,c2])

    for i in range(r1):
        for j in range(c2):
            s=0
            for u in range(c1):
                s+= m_1[i,u]*m_2[u,j]
            r[i,j] = s
    return r

def mkmat(n):
    dim=10+n
    m = np.random.uniform(0., 1., (dim, dim))
    return m

#if __name__ == "__main__":
#    l_timings = []
#    for i in range(10,100,10):
#        st = "matrix_multiplication(m, m)"
#        sup = "from p103 import mkmat; from p103 import matrix_multiplication; m = mkmat(%d); m = mkmat(%d)" % (i, i)
#        t = timeit.Timer(stmt = st, setup=sup)
#
#        x = t.timeit(30)
#        l_timings += [x]
#    print(l_timings)

############################### I-B ##############################################

def rec_bb(t: List, f: int, l: int, key: int)-> int:
    if(f>l):
        return None
    else:
        med = (f+l) // 2

        if (t[med]==key):
            return med

        elif (t[med]>key):
            return rec_bb(t, f, med-1, key)

        elif (t[med]<key):
            return rec_bb(t, med+1, l, key)

def bb(t: List, f: int, l: int, key: int)-> int:

    while (f<=l):
        med = (f+l) // 2
        if (t[med]==key):
            return med
        elif (t[med]<key):
            f = med + 1
        else:
            l = med - 1
    return None

############################### II-A #############################################
def left(t):
    return 2*t +1

def right(t):
    return 2*t +2

def min_heapify(h: np.ndarray, i: int):
    k=i
    l = left(k)
    r = right(k)

    if (l<len(h) and h[l]<h[i]):
        k=l

    if (r<len(h) and h[r]<h[k]):
        k=r

    if (k!=i):
        h[i], h[k] = h[k], h[i]
        min_heapify(h, k)

def insert_min_heap(h: np.ndarray, k: int)-> np.ndarray:
    if h is None:
        h = []

    h = np.append(h, k)
    j = len(h) - 1

    while j >= 1 and h[(j-1) // 2] > h[j]:
        h[(j-1) // 2], h[j] = h[j], h[(j-1) // 2]
        j = (j-1) // 2

    return h

def create_min_heap(h: np.ndarray):
    for i in range(len(h) // 2,-1, -1):
        min_heapify(h, i)
    return h

############################### II-B #############################################

def pq_ini():
    pq = []
    return pq

def pq_insert(h: np.ndarray, k: int)-> np.ndarray:
    h = np.append(h, k)
    return h

def pq_remove(h: np.ndarray)-> np.ndarray:
    max_val = len(h)-1
    for i in range(len(h)):
        if int(h[i]) < h[max_val]:
            max_val = i
    elem = h[max_val]
    h = np.delete(h, max_val)
    return elem, h

##################################################################################
############################### II-C #############################################

def select_min_heap(h: np.ndarray, k: int)-> int:
    min_heapify(h, 0)
    aux = -1*np.array(h)
    aux2 = aux[:k]

    create_min_heap(aux2)

    for i in range(k, len(h)):
        if aux[i] > aux2[0]:
            lelem = aux2[len(aux2)-1]
            aux2[0] = lelem
            aux2 = np.delete(aux2, len(aux2)-1)
            min_heapify(aux2, 0)
            aux2 = insert_min_heap(aux2, (aux[i]))

    return -1*aux2[0]

#h = create_min_heap(np.array([8, 7, 6, 5, 4, 3, 2, 1]))
#print(h)
#h1 = select_min_heap(h, 0)
#print(h1)


import speech_recognition as sr
import pyttsx3
from datetime import date
from datetime import datetime
import os
import re
import webbrowser
import time
import smtplib
import webbrowser

def speech_text():
    print("Đang lắng nghe...")
    r = sr.Recognizer()
    with sr.Microphone() as source:
        # read the audio data from the default microphone
        robot_listen = r.record(source, duration=5) #tg lắng nghe
        print("Đang Nhận dạng...")
        # convert speech to text
        try:
            yousaid = r.recognize_google(robot_listen,language="vi-VN")
            yousaid = yousaid.lower()
            return yousaid
        except:
            yousaid = ""
            return yousaid

def speak(text):
    engine = pyttsx3.init()
    voices = engine.getProperty('voices')
    engine.setProperty('voice', voices[1].id)
    engine.say(text)
    engine.runAndWait()
    return

def check_input():
    for i in range(3):
        yousaid = speech_text()
        print("Bạn:" + yousaid)
        if(yousaid != ""):
            return yousaid
        else:
            speak("Bot không nghe rõ, bạn nói lại được không!")

    speak("Bot đã không nhận phản hồi từ bạn 3 lần, Tạm biệt hẹn gặp lại!")
    return False

def send_email():
    speak('Bạn cần gởi email cho ai nhỉ')
    #lấy tên mail
    name_mail = check_input()
    if not name_mail:
        return False
    if "khánh" in name_mail or "chánh" in name_mail:

        speak('Nội dung bạn muốn gửi là gì')
        #lấy nd gởi
        content = check_input()
        if not name_mail:
            return False
        mail = smtplib.SMTP('smtp.gmail.com', 587)
        mail.ehlo()
        mail.starttls()

        mail.login('nguyenvannnk@gmail.com','nnkdz123')
        if "chánh" in name_mail:
            mail.sendmail('nguyenvannnk@gmail.com',
                          'chanhn098@gmail.com', content.encode('utf-8'))
        else:
            mail.sendmail('nguyenvannnk@gmail.com',
                          'chanhn1229@gmail.com', content.encode('utf-8'))
        mail.close()

        speak('Email của bạn vùa được gửi. Bạn check lại email nhé hihi.')
        return True
    else:
        speak('Không tìm thấy người gởi, bạn vui lòng thử lại!')
        return False

send_email()


import os
import textwrap

import streamlit as st
from PIL import ImageDraw, ImageFont

from image_editor import fonts

class TextParams:

    FONT_DICT = fonts.FONT_DICT
    FONT_BOLD_DICT = fonts.FONT_BOLD_DICT
    FONT_ITALIC_DICT = fonts.FONT_ITALIC_DICT
    FONT_BOLD_ITALIC_DICT = fonts.FONT_BOLD_ITALIC_DICT
    FONTS_DIR = fonts.FONTS_DIR

    def __init__(self, key) -> None:
        self.key = key

        self.alignment = self.alignment_radio()
        self.font = self.font_selectbox()
        self.font_size = self.font_size_text_input()
        self.color = self.color_picker()
        self.bold = self.bold_checkbox()
        self.italic = self.italic_checkbox()
        self.upper_case = self.upper_case_checkbox()
        self.font_true_type = self.get_font_true_type(
            self.font, self.FONTS_DIR
        )

        # self.checkboxes()

    def alignment_radio(self):

        align_options = ["Left", "Center", "Right"]

        align_selection = st.radio(
            "Text Alignment",
            align_options,
            index=0,
            key=self.key,
            horizontal=True,
        )

        return align_selection

    def font_selectbox(self):

        font_selection = st.selectbox(
            "Font", fonts.FONT_DICT.keys(), index=0, key=self.key
        )

        return font_selection

    def font_size_text_input(self):

        font_size_selection = st.text_input(
            "Font size", value="20", key=self.key
        )

        if not font_size_selection.isnumeric():
            return st.error(
                "Please insert a number for a valid font size in pixels"
            )

        return int(font_size_selection)

    def bold_checkbox(self):

        bold_selection = st.checkbox("Bold", key=self.key)

        return bold_selection

    def italic_checkbox(self):

        italic_selection = st.checkbox("Italic", key=self.key)

        return italic_selection

    def upper_case_checkbox(self):

        upper_case_selection = st.checkbox("Upper Case", key=self.key)

        return upper_case_selection

    def color_picker(self):

        color_selection = st.color_picker(
            "Text color", "#FFFFFF", key=self.key
        )

        return color_selection

    def get_font_true_type(
        self, selected_font: str, font_dir: str = FONTS_DIR
    ):

        if self.bold and self.italic:
            font_name = self.FONT_BOLD_ITALIC_DICT[selected_font]
        elif self.bold:
            font_name = self.FONT_BOLD_DICT[selected_font]
        elif self.italic:
            font_name = self.FONT_ITALIC_DICT[selected_font]
        else:
            font_name = self.FONT_DICT[selected_font]

        font_full_path = os.path.join(font_dir, font_name)
        true_type = ImageFont.truetype(font_full_path, self.font_size)

        return true_type

    def place_text_on_image(self, image, text: str, position: str):

        if position not in ["top", "bottom"]:
            raise ValueError(
                "Text can be placed on top or at the bottom of the image only"
            )

        if self.upper_case:
            text = text.upper()

        WIDTH, HEIGHT = image.size

        left_anchor = {"top": "la", "bottom": "ld"}
        middle_anchor = {"top": "ma", "bottom": "md"}
        right_anchor = {"top": "ra", "bottom": "rd"}

        # text location
        if self.alignment == "Left":
            x_width = 15
            text_anchor = left_anchor[position]
        elif self.alignment == "Center":
            x_width = WIDTH / 2
            text_anchor = middle_anchor[position]
        elif self.alignment == "Right":
            x_width = WIDTH - 15
            text_anchor = right_anchor[position]

        # initalize drawing on inserted image
        draw = ImageDraw.Draw(image)
        # wrapping text
        line_length = (WIDTH / self.font_size) * 2.2
        text_wrap = textwrap.wrap(text, width=line_length)

        # assigning text position for botttom
        if len(text_wrap) == 1:
            bot_text_height_start = HEIGHT - 10
        else:
            bot_text_height_start = HEIGHT - len(text_wrap) * (0.07 * HEIGHT)

        starting_height = {"top": 10, "bottom": bot_text_height_start}

        current_h, pad = starting_height[position], 10
        for line in text_wrap:
            w, h = draw.textsize(line, font=self.font_true_type)
            draw.text(
                (x_width, current_h),
                line,
                fill=self.color,
                font=self.font_true_type,
                anchor=text_anchor,
            )
            current_h += h + pad

        return line_length


from __future__ import print_function, absolute_import
import argparse
from email.policy import strict
import gc
import os.path as osp
import networkx as nx
import argparse
import sys
import time
import os
import pyhocon
import torch.nn as nn
import scipy.sparse as sp
from torch.backends import cudnn
from torch.utils.data import DataLoader
from torch.optim.lr_scheduler import StepLR

# from reid.models.walkbased import DeepWalk, WalkBasedEmbedding, Walker, NegativeSampling, NodeEmbedding
from reid.ge import DeepWalk,Node2Vec
from reid.evaluation.ranking import cmc, mean_ap, mean_ap2, map_cmc
from reid.lib.logging import Logger
from reid.lib.serialization import load_checkpoint, to_torch
from reid.utils.serialization import save_checkpoint
from reid.lib.lr_scheduler import WarmupMultiStepLR
from reid.dataloaders.loader import *
import reid.dataloaders.transforms as T
from reid.dataloaders.dataset import Person
from reid import models
from reid.models.cls_layer import *
from reid.models.backbone import resnet
from reid.evaluation.evaluator import Evaluator
from reid.trainer.trainer import Trainer
from reid.detach_enhancement.hetero_graph import HG
from reid.lib.serialization import copy_state_dict
from reid.img_st_fusion import stmain
from reid.graphsage.dataCenter import *
from reid.graphsage.models import *
from reid.graphsage.utils import *
from reid.models.dsbn import convert_dsbn

def get_data(opt):
    dataset = Person(opt.data_dir, opt.target, opt.source)
    t_pids = dataset.t_train_pids
    s_pids = dataset.s_train_pids
    s_train = dataset.source_train
    t_train_fake = dataset.target_train_fake
    t_train_real = dataset.target_train_real

    s_query = dataset.source_query
    t_query = dataset.target_query
    s_gallery = dataset.source_gallery
    t_gallery = dataset.target_gallery
    t_cam_2_imgs = dataset.t_train_cam_2_imgs
    s_cam_2_imgs = dataset.s_train_cam_2_imgs

    height, width = opt.height, opt.width
    batch_size, workers = opt.batch_size, opt.workers

    if opt.self_norm:
        normalizer = T.Normalize(mean=[0.5, 0.5, 0.5],
                                 std=[0.5, 0.5, 0.5])
    else:
        normalizer = T.Normalize(mean=[0.485, 0.456, 0.406],
                                 std=[0.229, 0.224, 0.225])

    train_transformer = T.Compose([
        T.Resize((height, width), interpolation=3),
        T.RandomHorizontalFlip(p=0.5),
        T.Pad(10),
        T.RandomCrop((height, width)),
        T.ToTensor(),
        normalizer
    ])

    test_graph_transformer = T.Compose([
        T.Resize((height, width), interpolation=3),
        T.ColorJitter(brightness=opt.brightness, saturation=opt.saturation, hue=opt.hue),
        T.ToTensor(),
        normalizer,
    ])

    test_transformer = T.Compose([
        T.Resize((height, width), interpolation=3),
        T.ToTensor(),
        normalizer,
    ])

    t_train_loader = DataLoader(
        dataset=CamStylePreprocessor(t_train_fake, num_cam=len(t_cam_2_imgs),
                                     transform=train_transformer, use_camstyle=opt.use_camstyle), # todo next try
        batch_size=batch_size,
        num_workers=workers,
        shuffle=True,
        pin_memory=True,
        drop_last=True
    )

    t_traintest_loader = DataLoader(
        dataset=Preprocessor(t_train_real, test_graph_transformer),
        batch_size=batch_size,
        shuffle=False,
        num_workers=workers,
        pin_memory=True,
        drop_last=False
    )

    t_query_loader = DataLoader(
        dataset=Preprocessor(t_query, test_transformer),
        batch_size=batch_size,
        shuffle=False,
        num_workers=workers,
        pin_memory=True,
        drop_last=False
    )
    t_gallery_loader = DataLoader(
        dataset=Preprocessor(t_gallery, test_transformer),
        batch_size=batch_size,
        shuffle=False,
        num_workers=workers,
        pin_memory=True,
        drop_last=False
    )
    # s_train_loader = DataLoader(
    #     dataset=Preprocessor(s_train, train_transformer),
    #     batch_size=batch_size,
    #     num_workers=workers,
    #     shuffle=True,
    #     pin_memory=True,
    #     drop_last=True
    # )
    # s_traintest_loader = DataLoader(
    #     dataset=Preprocessor(s_train, test_transformer),
    #     batch_size=batch_size,
    #     shuffle=False,
    #     num_workers=workers,
    #     pin_memory=False,
    #     drop_last=False
    # )
    # s_query_loader = DataLoader(
    #     dataset=Preprocessor(s_query, test_transformer),
    #     batch_size=batch_size,
    #     shuffle=False,
    #     num_workers=workers,
    #     pin_memory=False,
    #     drop_last=False
    # )
    # s_gallery_loader = DataLoader(
    #     dataset=Preprocessor(s_gallery, test_transformer),
    #     batch_size=batch_size,
    #     shuffle=False,
    #     num_workers=workers,
    #     pin_memory=False,
    #     drop_last=False
    # )

    return t_pids, s_pids, t_train_loader, t_train_real,\
           t_query_loader, t_gallery_loader,\
           t_query, t_gallery, [],\
           [], [], \
           s_query, s_gallery, \
           t_traintest_loader, [], \
           t_train_fake, s_train, t_cam_2_imgs, s_cam_2_imgs

# class WalkEmbedding(WalkBasedEmbedding):
#     def __init__(self, graph, dimension, iterations, walker, sampler, model):
#         self.graph = graph
#         self.dimension = dimension
#         self.iterations = iterations

#         self.walker = walker
#         self.sampler = sampler
#         self.model = model

#         self.train()

#     def train(self):
#         sequences = self.walker.walk(self.graph)  # todo modify LINE

#         for it in range(self.iterations):
#             for samples in self.sampler.sample(sequences):
#                 self.model.feed(*samples)
#             self.model.lr_decay()
#             print("===> epoch %d" % it)
#             # embedding = self.model.get_embeddings()
#             # test_gps2img(categories, labels, cams, nodes, embedding, is_save=False)
#             # test_img2img(categories, labels, cams, nodes, embedding, is_save=False)

#         return self

# def DeepWalk(graph, *,
#         # dimension = 128,
#         dimension = 128,
#         num_walks = 10,
#         # walk_length = 80,
#         # window_size = 10,
#         walk_length = 250, # 150
#         window_size = 20,
#         iterations = 3,
#         neg_ratio = 5,
#         learning_rate = 0.001,
#         batch_size = 10000,
#         down_sample_threshold = 1e-3,
#         weighted_walk=False):
#     return WalkEmbedding(graph,
#                          dimension,
#                          iterations,
#                          walker = Walker(num_walks, walk_length, weighted=weighted_walk),
#                          sampler = NegativeSampling(window_size, batch_size, neg_ratio=neg_ratio, down_sampling=down_sample_threshold),
#                          model = NodeEmbedding(graph.number_of_nodes(), dimension, learning_rate),
#                          )

def compute_euclidean_distance(
    features, others=None, cuda=False,
):

    if others is None:
        if cuda:
            features = features.cuda()

        n = features.size(0)
        x = features.view(n, -1)
        dist_m = torch.pow(x, 2).sum(dim=1, keepdim=True) * 2
        dist_m = dist_m.expand(n, n) - 2 * torch.mm(x, x.t())

    else:
        if cuda:
            features = features.cuda()
            others = others.cuda()

        m, n = features.size(0), others.size(0)
        # print(m, n)
        dist_m = (
            torch.pow(features, 2).sum(dim=1, keepdim=True).expand(m, n)
            + torch.pow(others, 2).sum(dim=1, keepdim=True).expand(n, m).t()
        )
        dist_m.addmm_(features, others.t(), beta=1, alpha=-2)

    return dist_m.cpu().numpy()

def symm_kneighbors(sim_matrix, knn, unifyLabel=None):
    k_sim = np.zeros_like(sim_matrix, dtype=np.float32)
    argpart = np.argpartition(-sim_matrix, knn)  # big move before knn，将前knn个相似度大的数排在前面并获得相应下标

    row_index = np.arange(sim_matrix.shape[0])[:, None]
    if unifyLabel:
        k_sim[row_index, argpart[:, 0:knn]] = unifyLabel
    else:
        k_sim[row_index, argpart[:, 0:knn]] = sim_matrix[row_index, argpart[:, 0:knn]]

    k_sim[row_index, row_index] = 1
    print(k_sim[:3,argpart[:3, 0:knn]])

    # b = np.sum(k_sim, axis = 1)
    # for i,_ in enumerate(k_sim):
    #     k_sim[i] /= b[i]
    # d = sp.diags(np.power(np.array(k_sim.sum(1)), -0.5).flatten(), 0)
    # k_norm = k_sim.dot(d).transpose().dot(d)

    # print(np.sum(k_norm, axis=1))
    # print(k_sim[0:3,:])
    k_sim = torch.from_numpy(k_sim)
    return k_sim

# def non_symm_kneighbors(sim_matrix, knn, unifyLabel=None):
#     k_sim = np.zeros_like((len(sim_matrix),len(sim_matrix[0])), dtype=np.float32)
#     argpart = np.argpartition(-sim_matrix, knn)  # big move before knn，将前knn个相似度大的数排在前面并获得相应下标

#     row_index = np.arange(sim_matrix.shape[0])[:, None]
#     if unifyLabel:
#         k_sim[row_index, argpart[:, 0:knn]] = unifyLabel
#     else:
#         k_sim[row_index, argpart[:, 0:knn]] = sim_matrix[row_index, argpart[:, 0:knn]]

#     b = np.sum(k_sim, axis = 1)
#     for i,_ in enumerate(k_sim):
#         k_sim[i] /= b[i]
#     k_norm = torch.from_numpy(k_norm)
#     return k_norm

def qg_kneighbors(sim_matrix, st_matrix, knn, cams, isVision=True):
    len_matrix = len(sim_matrix[0]) + len(sim_matrix)
    k_sim = np.zeros((len(sim_matrix),len_matrix), dtype=np.float32)
    argpart = np.argpartition(-st_matrix, knn)  # big move before knn，将前knn个相似度大的数排在前面并获得相应下标
    # st_argpart = np.argpartition(-st_matrix, 1)

    row_index = np.arange(len(sim_matrix))[:, None]

    k_sim[row_index, argpart[:, 0:knn]] = st_matrix[row_index, argpart[:, 0:knn]]
    # k_sim[row_index, st_argpart[:, 0]] = sim_matrix[row_index, st_argpart[:, 0]]

    # for i in range(len(k_sim)):
    #     index = np.where(k_sim[i] != 0.)
    #     weights = k_sim[i][index]
    #     cd_c = cams[index]
    #     tag_c_set = set(cd_c)
    #     for c in tag_c_set:
    #         c_index = np.where(cd_c == c)
    #         w = weights[c_index]

    #         w = len(w) / len(cd_c) * w / np.sum(w)
    #         k_sim[i][index[0][c_index]] = w

    if isVision:
        for i in range(len(k_sim)):
            k_sim[i][len(sim_matrix[0])+i] = 1

    b = np.sum(k_sim, axis = 1)
    for i,_ in enumerate(k_sim):
        k_sim[i] /= b[i]

    k_sim = torch.from_numpy(k_sim)
    return k_sim

def qg_diff_kneighbors(sim_matrix, top_same_indexs, top_diff_indexs, isVision=True):
    len_matrix = len(sim_matrix[0]) + len(sim_matrix)
    k_sim = np.zeros((len(sim_matrix),len_matrix), dtype=np.float32)

    row_index = np.arange(len(sim_matrix))[:, None]

    k_sim[row_index, top_same_indexs[:, :]] = sim_matrix[row_index, top_same_indexs[:, :]]
    k_sim[row_index, top_diff_indexs[:, :]] = sim_matrix[row_index, top_diff_indexs[:, :]]

    if isVision:
        for i in range(len(k_sim)):
            k_sim[i][len(sim_matrix[0])+i] = 1

    b = np.sum(k_sim, axis = 1)
    for i,_ in enumerate(k_sim):
        k_sim[i] /= b[i]

    k_sim = torch.from_numpy(k_sim)
    return k_sim

def main(opt):
    start = time.time()
    os.environ['CUDA_VISIBLE_DEVICES'] = opt.gpu_ids
    if opt.seed != -1:
        SEED = opt.seed
        np.random.seed(SEED)
        # this set the model state of all parameters
        torch.manual_seed(SEED)
        torch.cuda.manual_seed_all(SEED)
        cudnn.deterministic = True

    # For fast training.
    cudnn.benchmark = True
    # torch.cuda.set_device(opt.gpu_ids)
    # Redirect print ot both console and log file
    # if not opt.evaluate:
    sys.stdout = Logger(osp.join(opt.logs_dir, 'log.txt'))
    print(time.ctime(), 'logs_dir=', opt.logs_dir)

    # Print logs
    print(opt)

    # Create data loaders
    t_pids, s_pids, t_train_loader, t_train_real, \
    t_query_loader, t_gallery_loader, \
    t_query, t_gallery, s_train_loader, \
    s_query_loader, s_gallery_loader, \
    s_query, s_gallery, \
    t_traintest_loader, s_traintest_loader, \
    t_train, s_train, t_cam_2_imgs, s_cam_2_imgs,\
    = get_data(opt)

    # Create model
    if 'resnet' in opt.arch:
        print('use resnet')
        backbone = models.create(opt.arch, num_features=opt.features, dropout=opt.dropout, num_classes=0)
    elif 'vit' in opt.arch:
        print('use vit')
        backbone = models.create(opt.arch,img_size=(opt.height,opt.width),drop_path_rate=opt.drop_path_rate, pretrained_path = opt.pre_train,hw_ratio=opt.hw_ratio, conv_stem=opt.conv_stem)
    elif 'ICE' in opt.arch:
        print('use ICE')
        backbone = resnet.ICEResNet(num_features=args.features, dropout=args.dropout, num_classes=0)
    elif 'SpCL' in opt.arch:
        print('use SpCL')
        backbone = resnet.ICEResNet(num_features=args.features, norm=True, dropout=args.dropout, num_classes=0)
        convert_dsbn(backbone)
    elif 'CAP' in opt.arch:
        print('use CAP')
        backbone = resnet.MemoryBankModel(out_dim=2048)
    elif 'MMT' in opt.arch:
        print('use MMT')
        backbone = resnet.MMTResNet(50, num_features=args.features, dropout=args.dropout, num_classes=0)

    old_cls_tgt = OldClsTarget(
                            len(t_train),
                            opt.features,
                            t_cam_2_imgs,
                            opt.alpha,
                            opt.tao,
                            opt.switch,
                            opt.arch)
    # hyper parameter
    old_cls_tgt.use_single = opt.use_single

    # Set model
    backbone.cuda()
    backbone = nn.DataParallel(backbone) #若使用model.state_dict()保存模型，加载模型时需要先把网络弄成分布式训练
    old_cls_tgt = old_cls_tgt.cuda()

    # Load from checkpoint
    start_epoch = 0
    best_map = 0

    # pre_path = osp.join('./logs/pretrain',args.arch)
    # if opt.source == 'market' and opt.target == 'duke':
    #     checkpoint = load_checkpoint(osp.join(pre_path, 'market2duke/checkpoint.pth.tar'))
    #     copy_state_dict(checkpoint['backbone_dict'], backbone)
    # elif opt.source == 'DukeMTMC-reID' and opt.target == 'market':
    #     checkpoint = load_checkpoint(osp.join(pre_path, 'DukeMTMC-reID2market/checkpoint.pth.tar'))
    #     # copy_state_dict(checkpoint['backbone_dict'], backbone)
    #     backbone.load_state_dict(checkpoint['backbone_dict'], strict=False)
    # elif opt.source == 'duke' and opt.target == 'msmt17':
    #     checkpoint = load_checkpoint(osp.join(pre_path, 'duke2msmt17/checkpoint.pth.tar'))
    #     copy_state_dict(checkpoint['backbone_dict'], backbone)
    # elif opt.source == 'market' and opt.target == 'msmt17':
    #     checkpoint = load_checkpoint(osp.join(pre_path, 'market2msmt17/checkpoint.pth.tar'))
    #     copy_state_dict(checkpoint['backbone_dict'], backbone)

    # if args.pre_train:
    #     checkpoint = load_checkpoint(args.pre_train)
    #     backbone.load_state_dict(checkpoint['backbone_dict'], strict=False)

    # if args.resume:
    #     checkpoint = load_checkpoint(args.resume)
    #     backbone.load_state_dict(checkpoint['backbone_dict'], strict=False)
    #     if 'epoch' in checkpoint.keys():
    #         start_epoch = checkpoint['epoch']
    #         print('checkpoint loaded, start epoch is : {}'.format(start_epoch))

    if args.resume:
        checkpoint = load_checkpoint(args.resume)
        new_state_dict =  {}

        #MMT
        # for key, value in checkpoint['state_dict'].items():
        #     if 'base.0' in key:
        #         name = key.replace('base.0','base.conv1')
        #     elif 'base.1' in key:
        #         name = key.replace('base.1','base.bn1')
        #     elif 'base.3' in key:
        #         name = key.replace('base.3','base.layer1')
        #     elif 'base.4' in key:
        #         name = key.replace('base.4','base.layer2')
        #     elif 'base.5' in key:
        #         name = key.replace('base.5','base.layer3')
        #     elif 'base.6' in key:
        #         name = key.replace('base.6','base.layer4')
        #     else:
        #         name = key
        #     new_state_dict[name] = value

        # #CAP
        # for key,value in checkpoint.items():
        #     if 'embeding' in key:
        #         print('pretrained model has key= {}'.format(key))
        #     elif 'resnet_conv.0' in key:
        #         name = key.replace('resnet_conv.0', 'base.conv1')
        #     elif 'resnet_conv.1' in key:
        #         name = key.replace('resnet_conv.1', 'base.bn1')
        #     elif 'resnet_conv.3' in key:
        #         name = key.replace('resnet_conv.3', 'base.layer1')
        #     elif 'resnet_conv.4' in key:
        #         name = key.replace('resnet_conv.4', 'base.layer2')
        #     elif 'resnet_conv.5' in key:
        #         name = key.replace('resnet_conv.5', 'base.layer3')
        #     elif 'resnet_conv.6' in key:
        #         name = key.replace('resnet_conv.6', 'base.layer4')
        #     elif 'bottleneck' in key:
        #         name = key.replace('bottleneck', 'feat_bn')
        #     else:
        #         name = key
        #     new_state_dict[name] = value

        # #ICE
        # for key, value in checkpoint['state_dict'].items():
        #     if 'base.0' in key:
        #         name = key.replace('base.0','base.conv1')
        #     elif 'base.1' in key:
        #         name = key.replace('base.1','base.bn1')
        #     elif 'base.4' in key:
        #         name = key.replace('base.4','base.layer1')
        #     elif 'base.5' in key:
        #         name = key.replace('base.5','base.layer2')
        #     elif 'base.6' in key:
        #         name = key.replace('base.6','base.layer3')
        #     elif 'base.7' in key:
        #         name = key.replace('base.7','base.layer4')
        #     else:
        #         name = key
        #     new_state_dict[name] = value

        # for key, value in checkpoint['state_dict_1'].items():
        #     if 'net.backbone' in key:
        #         name = key.replace('net.backbone','base')
        #     else:
        #         name = key
        #     new_state_dict[name] = value
        # backbone.load_state_dict(new_state_dict, strict=False)
        if 'resnet' in opt.arch or opt.evaluate:
            backbone.load_state_dict(checkpoint['backbone_dict'], strict=False)
            print("load backbone dict")
        elif 'CAP' in opt.arch:
            backbone.load_state_dict(checkpoint, strict=False)
            print("load checkpoint")
        else:
            backbone.load_state_dict(checkpoint['state_dict'], strict=False)
            print("load state dict")

    if not opt.evaluate and opt.target != 'msmt17':
        evaluator = Evaluator(backbone)
        map,top1,_,_,_,_,_,_ = evaluator.evaluate(t_query_loader, t_gallery_loader, t_query, t_gallery, opt.kl, False)
        best_map = map+top1
    # Evaluator
    if opt.evaluate:
        print("test fusion")
        # evaluator = Evaluator(backbone)
        # indexs = evaluator.transfer(t_traintest_loader, t_train_real, opt.ks, opt.logs_dir)
        # return
        # indexs = np.genfromtxt(opt.logs_dir+"/indexs.txt", dtype=np.int32)
        evaluator = Evaluator(backbone)
        best_map, _, scores, gscores, qgindexs, ggindexs, query_features, gallery_features = evaluator.evaluate(t_query_loader, t_gallery_loader, t_query, t_gallery, opt.kl, False)
        indexs = evaluator.transfer(t_traintest_loader, t_train_real, opt.ks, opt.logs_dir)
        st_scores, gst_scores = stmain(opt, indexs, t_train_real, t_query, t_gallery, qgindexs=qgindexs, ggindexs=ggindexs, flag = False)

        # # 对时空相似性进行max归一化 没用
        # for i in range(len(st_scores)):
        #     # index = np.where((st_scores[i] != 0.) & (st_scores[i] != -1))
        #     max_i = max(st_scores[i])
        #     for j,score in enumerate(st_scores[i]):
        #         if score != 0 and score != -1 and score != -2:
        #             st_scores[i][j] /= max_i

        # for i in range(len(gst_scores)):
        #     # index = np.where((st_scores[i] != 0.) & (st_scores[i] != -1))
        #     max_i = max(gst_scores[i])
        #     for j,score in enumerate(gst_scores[i]):
        #         if score != 0 and score != -1 and score != -2:
        #             gst_scores[i][j] /= max_i

        sum_scores = []
        gg = defaultdict()
        gg_positive = defaultdict(set)
        gg_negetive = defaultdict(set)
        adj_lists = defaultdict(set)

        # vision + st
        for i in range(len(gscores)):
            for index, j in enumerate(ggindexs[i]):
                if index < opt.ks or gst_scores[i][index] > 0:
                # if index < opt.ks:
                    if i != j:
                        adj_lists[i].add(j)
                        adj_lists[j].add(i)
                        gg[i,j] = gscores[i][index]
                        gg[j,i] = gscores[i][index]

            adj_lists[i].add(i)
            gg[i,i] = 1

        query_ids = np.asarray([pid for _, pid, _,_,_ in t_query])
        gallery_ids = np.asarray([pid for _, pid, _ ,_,_ in t_gallery])
        query_cams = np.asarray([cam for _, _, cam,_,_ in t_query])
        gallery_cams = np.asarray([cam for _, _, cam,_,_ in t_gallery])

        ## graphsage

        # load config file
        config = pyhocon.ConfigFactory.parse_file(args.config)
        # load data
        ds = args.target
        dataCenter = DataCenter(config)

        # 构建gallery视觉图
        device = torch.device("cuda", 0)
        dataCenter.load_dataSet(ds, len_g=len(gscores), isVision=True, use_sparse=opt.use_sparse)
        del gscores
        del ggindexs
        # del gst_scores
        # del indexs
        gc.collect()
        torch.cuda.empty_cache()

        # gscores = getattr(dataCenter, ds+'_weight_lists').to(device)
        # gscores = getattr(dataCenter, ds+'_weight_lists')
        gallery_features = gallery_features.to(device)
        query_features = query_features.to(device)
        # gscores = gscores.to(device)
        # scores = scores.to(device)
        # st_scores = st_scores.to(device)

        graphSage1 = GraphSage(config['setting.num_layers'], gallery_features.size(1), config['setting.hidden_emb_size'], gallery_features, gg, adj_lists, device, gcn=True, agg_func=args.agg_func)
        # graphSage1 = nn.DataParallel(graphSage1 ,device_ids=[0])
        graphSage1.to(device)

        # num_labels = 0
        # classification = Classification(config['setting.hidden_emb_size'], num_labels)
        # classification.to(device)

        # unsupervised_loss = UnsupervisedLoss(adj_lists, getattr(dataCenter, ds+'_train'), gg_positive, gg_negetive, device)

        print('GraphSage with vision and spatial-temporal Net Unsupervised Learning')

        # for epoch in range(args.g_epochs):
        #     print('----------------------EPOCH %d-----------------------' % epoch)
        #     graphSage1, classification = apply_model(dataCenter, ds, graphSage1, classification, unsupervised_loss, args.b_sz, args.unsup_loss, device, args.learn_method)

        vg_features = get_gnn_embeddings(graphSage1, len(adj_lists))
        vg_features = vg_features.cpu()
        vg_dir = os.path.join(opt.logs_dir, 'g_features.pth')
        torch.save(vg_features, vg_dir)

        # sum_scores = []
        for i in range(len(scores)):
            # sum_score = 0
            # indexs = np.argsort(-scores[i])[:5]
            for index, j in enumerate(qgindexs[i]):
                if index < opt.ks or (st_scores[i][index] > 0):
                # if index < opt.ks:
                    if i != j:
                        adj_lists[len(gallery_features) + i].add(j)
                        gg[len(gallery_features) + i,j] = scores[i][index]
                            # sum_score += scores[i][index]
            adj_lists[len(gallery_features) + i].add(len(gallery_features) + i)
            gg[len(gallery_features) + i,len(gallery_features) + i] = 1
            # sum_score += 1
            # sum_scores.append(sum_score)

        graphSage1.raw_weight = gg
        features = torch.cat((gallery_features, query_features), dim=0)
        graphSage1.adj_lists = adj_lists
        graphSage1.raw_features = features

        vq_embeddings = get_query_embeddings(graphSage1, len(gallery_features), len(adj_lists))
        vq_embeddings = vq_embeddings.cpu()
        vq_dir = os.path.join(opt.logs_dir, 'q_embeddings.pth')

        torch.save(vq_embeddings, vq_dir)
        torch.cuda.empty_cache()

        q_embeddings =  vq_embeddings
        g_embeddings = vg_features
        distmat = compute_euclidean_distance(q_embeddings, g_embeddings)

        mAP, all_cmc = map_cmc(distmat, query_ids, gallery_ids, query_cams, gallery_cams)
        print('Mean AP: {:4.1%}'.format(mAP))
        print('CMC Scores')
        for k in (1, 5, 10):
            print('  top-{:<4}{:12.1%}'
                .format(k, all_cmc[k - 1]))

        return

    # best_map = 0
    # if opt.evaluate:
    #     # print('Test source {} : '.format(opt.source))
    #     # evaluator.evaluate(s_query_loader, s_gallery_loader, s_query, s_gallery)
    #     print('Test target {} : '.format(opt.target))
    #     evaluator.evaluate(t_query_loader, t_gallery_loader, t_query, t_gallery)
    #     return

    # Optimizer
    params = []
    for key, value in backbone.named_parameters():
        if not value.requires_grad:
            continue
        params += [{"params": [value], "lr": args.lr, "weight_decay": args.weight_decay}]

    optimizer = torch.optim.Adam(params)

    # if args.resume:
    #     optimizer.load_state_dict(checkpoint['optimizer_dict'], strict=False)

    scheduler = WarmupMultiStepLR(optimizer,
                                  [6],
                                  gamma=0.1,
                        warmup_factor=0.01,
                            warmup_iters=6)

    # Start training
    evaluator = Evaluator(backbone)
    t_train_loader = IterLoader(t_train_loader, length=len(t_train_loader))

    for epoch in range(start_epoch, opt.epochs):
        features, fpaths, labels, camids = \
            evaluator.extract_tgt_train_features(
                                t_traintest_loader)
        print("features len:{}".format(len(features)))

        graph = HG(opt.lamd, features, labels, camids)

        # hyper parameter
        graph.general_graph = opt.general_graph
        graph.homo_ap = opt.homo_ap

        start1 = time.time()

        # if opt.only_graph:
        #     graph_target = graph.only_graph(ks=opt.ks, kd=opt.kd, k2=opt.k2)
        # else:
        #     if opt.cos_sim:
        #         graph_target = graph.old_cos_propagation(ks=opt.ks, kd=opt.kd, k2=opt.k2)
        #     else:
        #         if opt.tracklet:
        #             graph_target = graph.old_tracklet_propagation(ks=opt.ks, kd=opt.kd, k2=opt.k2)
        #         else:
        graph_target = graph.old_delta_propagation(k2 = opt.k2, opt = opt, t_train = t_train_real)

        print('###graph time: ', time.time()-start1)
        # Trainer
        trainer = Trainer(backbone, old_cls_tgt)
        trainer.graph_target = graph_target

        t_train_loader.new_epoch()
        print("第%d个epoch的学习率：%f" % (epoch, optimizer.param_groups[0]['lr']))
        trainer.target_train(len(t_train_loader), optimizer,
                        t_train_loader, epoch, opt.arch)
        scheduler.step()

        if (epoch+1)%opt.eval_step==0:
            mAP ,top1 ,_ ,_,_,_,_,_ = evaluator.evaluate(t_query_loader, t_gallery_loader, t_query, t_gallery)
            is_best = (mAP  + top1 > best_map)
            best_map = max(mAP  + top1, best_map)

            save_checkpoint({
                'backbone_dict': backbone.state_dict(),
                'optimizer_dict': optimizer.state_dict(),
                'epoch': epoch + 1,
            }, is_best,fpath=osp.join(opt.logs_dir, 'checkpoint.pth.tar'))
        # print('\n * Finished epoch {:3d} \n'.
        #     format(epoch))

    print('Best mAP:{} : '.format(best_map))
    # evaluator.evaluate(t_query_loader, t_gallery_loader, t_query, t_gallery, eval_path=args.eval_dir)
    # evaluator.evaluate_fusion(t_query, t_gallery, args.fusion_dir)
    print(time.ctime(), ' Need Time:', time.time() - start)

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description="PGM")
    # gpu ids
    parser.add_argument('--gpu_ids', type=str, required=True)
    # random seed
    parser.add_argument('--seed', type=int, default=1)
    # source
    parser.add_argument('-s', '--source', type=str, default='DukeMTMC-reID',
                        choices=['market', 'DukeMTMC-reID', 'msmt17',])
    # target
    parser.add_argument('-t', '--target', type=str, default='market',
                        choices=['market', 'DukeMTMC-reID', 'msmt17', ])
    # imgs setting
    parser.add_argument('-b', '--batch-size', type=int, default=64)   ## 64
    parser.add_argument('-j', '--workers', type=int, default=4)  ## 4
    parser.add_argument('--height', type=int, default=256,
                        help="input height, default: 256")
    parser.add_argument('--width', type=int, default=128,
                        help="input width, default: 128")
    # model
    parser.add_argument('-a', '--arch', type=str, default='resnet50')
    parser.add_argument('--features', type=int, default=0)
    parser.add_argument('--dropout', type=float, default=0)
    #vit
    parser.add_argument('--drop-path-rate', type=float, default=0.3)
    parser.add_argument('--hw-ratio', type=int, default=1)
    parser.add_argument('--self-norm', action="store_true")
    parser.add_argument('--conv-stem', action="store_true")
    # optimizer
    parser.add_argument('--lr', type=float, default=0.00035)
    parser.add_argument('--momentum', type=float, default=0.9)
    parser.add_argument('--weight-decay', type=float, default=5e-4)
    # training configs
    parser.add_argument('--resume', type=str, metavar='PATH', default='')
    parser.add_argument('-pp','--pre_train', type=str, metavar='PATH', default='')
    parser.add_argument('--evaluate', action='store_true', default=False,
                        help="evaluation only")
    parser.add_argument('--wo-st-train', action='store_true', default=False,
                        help="without spatial-temporal training")
    parser.add_argument('--wo-gaussian-sim', action='store_true', default=False,
                        help="without gaussian sim for training")
    parser.add_argument('--use-old-hgo', action='store_true', default=False,
                        help="without gaussian sim for training")
    parser.add_argument('--iters', type=int, default=202)
    parser.add_argument('--epochs', type=int, default=8)
    parser.add_argument('--eval-step', type=int, default=1)
    parser.add_argument('--epochs_decay', type=int, default=40)
    #st
    parser.add_argument('--interval', default=25, type=int, help='')
    # misc
    working_dir = osp.dirname(osp.abspath(__file__))
    parser.add_argument('--data-dir', type=str, metavar='PATH',
                        default='/hdd/sdb/zyb/TFusion/SpCL/data')
    parser.add_argument('--logs-dir', type=str, metavar='PATH',
                        default=osp.join(working_dir, 'logs/old/d2m'))
    # parser.add_argument('--eval_dir', type=str, metavar='PATH',
    #                     default=osp.join(working_dir, 'eval','duke2market'))
    # parser.add_argument('--fusion_dir', type=str, metavar='PATH',
    #                     default=osp.join(working_dir, 'data','DukeMTMC-reID_market-test'))
    parser.add_argument('--re', type=float, default=0.5)

    parser.add_argument('--alpha', type=float, default=0.01)
    parser.add_argument('--tao', type=float, default=0.05)
    parser.add_argument('--switch', type=int, default=1)
    parser.add_argument('--lamd', type=float, default=0.99)
    # parser.add_argument('--ratio', type=float, default=0.65)
    # parser.add_argument('--vision_weight', type=float, default=0.9)
    parser.add_argument('--ks', type=int, default=3)
    parser.add_argument('--kl', type=int, default=60)
    parser.add_argument('--k2', type=int, default=14)
    parser.add_argument('--use-camstyle', action='store_true', default=False)
    parser.add_argument('--use-sparse', action='store_true', default=False)
    parser.add_argument('--general-graph', action='store_true', default=False)
    parser.add_argument('--use-single', action='store_true', default=False)
    parser.add_argument('--only-graph', action='store_true', default=False)
    parser.add_argument('--cos-sim', action='store_true', default=False)
    parser.add_argument('--homo-ap', action='store_true', default=False)

    parser.add_argument('--brightness', type=float, default=0.2)
    parser.add_argument('--saturation', type=float, default=0.0)
    parser.add_argument('--hue', type=float, default=0.0)

    parser.add_argument("--tracklet", action="store_true", default=False)

    parser.add_argument('--describe', type=str)

    ##graphsage
    # parser.add_argument('--dataSet', type=str, default='market')
    parser.add_argument('--agg_func', type=str, default='WEIGHT')
    parser.add_argument('--g_epochs', type=int, default=1)
    parser.add_argument('--b_sz', type=int, default=20)
    parser.add_argument('--gcn', action='store_true')
    parser.add_argument('--learn_method', type=str, default='unsup')
    parser.add_argument('--unsup_loss', type=str, default='margin')
    parser.add_argument('--max_vali_f1', type=float, default=0)
    parser.add_argument('--name', type=str, default='debug')
    parser.add_argument('--config', type=str, default='/home/zyb/projects/h-go/reid/graphsage/experiments.conf')
    args = parser.parse_args()
    main(args)


# -*- encoding: utf-8 -*-
from django.views.generic.edit import CreateView
from django.views.generic.edit import UpdateView
from django.core.urlresolvers import reverse
from django.shortcuts import redirect
from .models import CotizacionOrdenDeTrabajo
from .models import RepuestoCantidad
from apps.orden_de_trabajo.models import OrdenDeTrabajo
from apps.orden_de_trabajo.models import COTIZADO
from django.forms import inlineformset_factory
from django.forms import ModelForm
from apps.inicio.mixins import LoginRequiredMixin

class CotizacionOrdenDeTrabajoForm(LoginRequiredMixin, ModelForm):
    class Meta:
        model = CotizacionOrdenDeTrabajo
        exclude = ('habilitado',)

class RepuestoCantidadForm(LoginRequiredMixin, ModelForm):
    class Meta:
        model = RepuestoCantidad
        fields = ('cotizacion_orden_de_trabajo','repuesto','cantidad')

RepuestoCantidadFormSet = inlineformset_factory(
    CotizacionOrdenDeTrabajo,
    RepuestoCantidad,
    fields=('repuesto','cantidad'),
    extra=1,
    can_delete=False)

class CotizacionOrdenDeTrabajoCreateView(LoginRequiredMixin, CreateView):
    model = CotizacionOrdenDeTrabajo
    form_class = CotizacionOrdenDeTrabajoForm
    template_name = 'cotizacion_orden_de_trabajo/form.html'

    def get_context_data(self,**kwargs):
        context = super(CotizacionOrdenDeTrabajoCreateView,self).get_context_data(**kwargs)
        context['section_title'] = 'Nueva Cotización'
        if self.request.POST:
            context['formset'] = RepuestoCantidadFormSet(self.request.POST)
        else:
            context['formset'] = RepuestoCantidadFormSet()
        return context

    def form_valid(self, form):
        context = self.get_context_data()
        formset = context['formset']
        if formset.is_valid():
            self.object = form.save()
            formset.instance = self.object
            formset.save()
            return redirect(self.get_success_url())
        else:
            return self.render_to_response(
                self.get_context_data(form=form)
            )

    def get_initial(self):
        initial = super(CotizacionOrdenDeTrabajoCreateView,self).get_initial()
        initial = initial.copy()
        orden_de_trabajo = OrdenDeTrabajo.objects.get(id=self.kwargs['opk'])
        initial['orden_de_trabajo'] = orden_de_trabajo
        return initial

    def get_success_url(self):
        orden_de_trabajo = OrdenDeTrabajo.objects.get(id=self.kwargs['opk'])
        sucursal_id = orden_de_trabajo.sucursal.id
        cotizacion_orden_de_trabajo = CotizacionOrdenDeTrabajo.objects.get(id=self.object.id)
        cotizacion_orden_de_trabajo.orden_de_trabajo.estado_reparacion = COTIZADO
        cotizacion_orden_de_trabajo.orden_de_trabajo.save()
        return reverse('cotizacion_orden_de_trabajo:listar')

class CotizacionOrdenDeTrabajoUpdateView(LoginRequiredMixin, UpdateView):
    model = CotizacionOrdenDeTrabajo
    form_class = CotizacionOrdenDeTrabajoForm
    template_name = 'cotizacion_orden_de_trabajo/form.html'

    def get_context_data(self,**kwargs):
        context = super(CotizacionOrdenDeTrabajoUpdateView,self).get_context_data(**kwargs)
        context['section_title'] = 'Actualizar Cotización'
        if self.request.POST:
            context['formset'] = RepuestoCantidadFormSet(self.request.POST,instance=self.object)
        else:
            context['formset'] = RepuestoCantidadFormSet(instance=self.object)
        return context

    def form_valid(self, form):
        context = self.get_context_data()
        formset = context['formset']

        if formset.is_valid():
            form.save(commit=True)
            formset.save(commit=True)
            return redirect(self.get_success_url())
        else:
            return self.render_to_response(
                self.get_context_data(form=form)
            )

    def get_success_url(self):
        return reverse('cotizacion_orden_de_trabajo:listar')


"""
Description:
Calculate normal modes and TL for Pekeris waveguide
Using raw_pykrak

Date:
4/18/2023

Author: Hunter Akins

Institution: Scripps Institution of Oceanography, UC San Diego
"""

import numpy as np
from matplotlib import pyplot as plt
from matplotlib import rc
rc('text', usetex=True)
import matplotlib
matplotlib.rcParams['mathtext.fontset'] = 'stix'
matplotlib.rcParams['font.family'] = 'STIXGeneral'

from pykrak.pykrak_env import Env
from pykrak.raw_pykrak import get_modes
from pykrak.attn_pert import get_attn_conv_factor
from pykrak.sturm_seq import get_arrs, cat_list_to_arr

z_list = [np.array([0, 5000.])]
c_list = [np.array([1500., 1500.])]
rho_list = [np.ones(2)]
attn_list = [.001*np.ones(2)]
c_hs = 2000.
rho_hs = 2.0
attn_hs = .0
attn_units ='dbpkmhz'
freq = 10.
conv_factor = get_attn_conv_factor(attn_units, freq)

env = Env(z_list, c_list, rho_list, attn_list, c_hs, rho_hs, attn_hs, attn_units)
dz = 1500 / (20*freq) #
N_list = [int((z_list[i][-1] - z_list[i][0])/ dz) + 1 for i in range(len(z_list))]
print('N_list', N_list)
z_list, c_list, rho_list, attn_list= env.interp_env_vals(N_list)
h_list = [x[1] - x[0] for x in z_list]
h_arr, ind_arr, z_arr, c_arr, rho_arr = get_arrs(h_list, z_list, c_list, rho_list)
attn_arr,_ = cat_list_to_arr(attn_list)
attn_arr *= conv_factor
attn_hs *= conv_factor

cmin = 1500.
cmax = 1999.

krs, phi, phi_z = get_modes(freq, h_arr, ind_arr, z_arr, c_arr, rho_arr, attn_arr, c_hs, rho_hs, attn_hs, cmin, cmax)
print(krs)

zr = np.array([2500.])
zs = np.array([500.])
r = np.linspace(2*1e5, 2.2*1e5, 1000)

from pykrak import pressure_calc as pc
p = pc.get_grid_pressure(zr, phi_z, phi, krs, zs, r)
tmp_r = np.array([1.0])
tmp_p = pc.get_grid_pressure(zr, phi_z, phi, krs, zr, tmp_r)
print(abs(tmp_p), 1/(4*np.pi))

print(p.shape)
p = np.squeeze(p)
tl = -20*np.log10(np.sqrt(2*np.pi)*abs(p)) # this is actually incorrect, it should be 4pi
# this factor gets agreement with the KRAKEN manual. I think the figure in the manual does not account for the fact that the pressure field calculation has a factor of 1/sqrt(8 pi) in it
plt.figure()
plt.plot(r*1e-3, tl,'k')
plt.xlabel('Range (km)')
plt.ylabel('Loss (dB)')
plt.annotate('f = 10 Hz\nsd=500 m\n rd=2500 m', xy=(0.9, 0.9), xycoords='axes fraction')
plt.ylim([110, 70])
plt.show()


from hitchstory import HitchStoryException
from hitchrun import expected
from commandlib import CommandError
from strictyaml import load
from pathquery import pathquery
from hitchrun import DIR
import dirtemplate
import hitchpylibrarytoolkit
from engine import Engine

PROJECT_NAME = "hitchqs"

toolkit = hitchpylibrarytoolkit.ProjectToolkit(
    "hitchqs",
    DIR,
    Engine,
)

@expected(HitchStoryException)
def bdd(*keywords):
    """Run single story."""
    toolkit.bdd(Engine(DIR), keywords)

@expected(HitchStoryException)
def rbdd(*keywords):
    """
    Run story matching keywords and rewrite story if code changed.
    """
    toolkit.bdd(Engine(DIR, rewrite=True), keywords)

@expected(HitchStoryException)
def bbdd(*keywords):
    """Run individual story matching key words and build."""
    toolkit.bdd(Engine(DIR, build=True), keywords)

@expected(HitchStoryException)
def regression():
    """
    Run regression testing - lint and then run all tests.
    """
    toolkit.regression(Engine(DIR))

def reformat():
    """
    Reformat using black and then relint.
    """
    toolkit.reformat()

def lint():
    """
    Lint project code and hitch code.
    """
    toolkit.lint()

def deploy(version):
    """
    Deploy to pypi as specified version.
    """
    toolkit.deploy(version)

@expected(dirtemplate.exceptions.DirTemplateException)
def docgen():
    """
    Build documentation.
    """
    toolkit.docgen()

@expected(dirtemplate.exceptions.DirTemplateException)
def readmegen():
    """
    Build README.md and CHANGELOG.md.
    """
    toolkit.readmegen()

@expected(CommandError)
def doctests():
    """
    Run doctests in utils.py in python 2 and 3.
    """
    for python_version in ["2.7.14", "3.7.0"]:
        pylibrary = hitchpylibrarytoolkit.project_build(
            PROJECT_NAME, DIR, python_version
        )
        pylibrary.bin.python(
            "-m", "doctest", "-v", DIR.project.joinpath(PROJECT_NAME, "utils.py")
        ).in_dir(DIR.project.joinpath(PROJECT_NAME)).run()

@expected(CommandError)
def rerun(version="3.7.0"):
    """
    Rerun last example code block with specified version of python.
    """
    from commandlib import Command

    Command(DIR.gen.joinpath("py{0}".format(version), "bin", "python"))(
        DIR.gen.joinpath("state", "examplepythoncode.py")
    ).in_dir(DIR.gen.joinpath("state")).run()

@expected(CommandError)
@expected(AssertionError)
def copyback(template_type, name):
    """
    After debugging a template, copy it back to the main repo.
    """
    assert template_type in ["demo", "skeleton"]
    backdir = DIR.project / "hitchqs" / template_type / name
    folder_name = load(backdir.joinpath("hitchqs.yml").text()).data["path"]
    assert backdir.exists()
    tempqs = DIR.project.parent / "tempqs" / folder_name
    template_files = (
        pathquery(tempqs).is_not_dir()
        - pathquery(tempqs).ext("pyc")
        - pathquery(tempqs).named("hitchreqs.txt")
    )

    for filepath in template_files:
        relpath = filepath.relpath(tempqs)
        print("Copying back {}".format(relpath))
        filepath.copy(backdir / relpath)


# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.conf import settings
from django.conf.urls.static import static
from django.conf.urls import url, include
from django.conf.urls.i18n import i18n_patterns
from django.contrib import admin
from django.contrib.sitemaps.views import sitemap
from django.http import HttpResponse
from cms.sitemaps import CMSSitemap
from alby.sitemap import ProductSitemap
from alby.settings import prefix_default_language as is_prefix

# from phone_verify.api import VerificationViewSet

sitemaps = {'cmspages': CMSSitemap,
            'products': ProductSitemap}

def render_robots(request):
    permission = 'noindex' in settings.ROBOTS_META_TAGS and 'Disallow' or 'Allow'
    return HttpResponse(''
                        'User-Agent: *\n'
                        '%s: /\n'
                        'Disallow: /personal-pages/\n'
                        'Disallow: /cart/\n'
                        'Disallow: /register-customer/\n'
                        'Disallow: /request-password-reset/\n'
                        'Disallow: /search/\n'
                        'Sitemap: http://alby.by/sitemap.xml\n'
                        '' % permission, content_type='text/plain')

i18n_urls = (
    url(r'^admin/', admin.site.urls),
    url(r'^', include('cms.urls')),
)
urlpatterns = [
    url(r'^robots\.txt$', render_robots),
    url(r'^sitemap\.xml$', sitemap, {'sitemaps': sitemaps}, name='sitemap'),
    url(r'^shop/', include('shop.urls')),
    url(r'^rest-auth/', include('rest_auth.urls')),
    url(r'^rest-auth/registration/', include('rest_auth.registration.urls')),
    # url(r'^rest-auth/facebook/$', FacebookLogin.as_view(), name='fb_login'),
    # url(r'^', include('phone_verify.urls'))
]

if settings.USE_I18N:
    urlpatterns.extend(i18n_patterns(*i18n_urls, prefix_default_language=is_prefix))
else:
    urlpatterns.extend(i18n_urls)
urlpatterns.extend(
    static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT))