from flask import Flask, url_for, request, render_template
from python.structural_issues import StructuralIssuesDetector
from python.thermal_issues import ThermalIssuesDetector, RgbImage
from python.file_management import FileManagement
from PIL import Image
from datetime import datetime
from tqdm import tqdm
import os
from collections import Counter
import json
import ssl
ssl._create_default_https_context = ssl._create_unverified_context

################################################################################################
#####> GLOBAL VARIABLES
################################################################################################

# Folders
TEMPLATES_FOLDER                		= os.path.join("templates", "html")
STATIC_FOLDER                   		= "static"
ASSETS_FOLDER                   		= "assets"
STORAGE_FOLDER							= os.path.join(STATIC_FOLDER, "storage")

# Files
STORAGE_NORMAL_INITIAL_IMAGE_FILE_NAME 	= "normal-initial-image"
STORAGE_NORMAL_RESULT_IMAGE_FILE_NAME  	= "normal-result-image"
STORAGE_THERMAL_INITIAL_IMAGE_FILE_NAME = "thermal-initial-image"
STORAGE_THERMAL_RESULT_IMAGE_FILE_NAME  = "thermal-result-image"
STORAGE_RESULT_DATA_FILE_NAME   		= "result-data"

# Structural issues detector
STRUCTURAL_ISSUES_MODEL_WEIGHTS_PATH 	= os.path.join(ASSETS_FOLDER, "weights/best_weights.pt")
STRUCTURAL_ISSUES_DETECTOR  			= StructuralIssuesDetector(STRUCTURAL_ISSUES_MODEL_WEIGHTS_PATH)

# initial_img, result_image, result_predictions = STRUCTURAL_ISSUES_DETECTOR.detectFromImage(Image.open("_.jpeg"))
# initial_img.show()
# exit()

# Thermal issues detector
THERMAL_ISSUES_DETECTOR					= ThermalIssuesDetector()

# Launch app
FileManagement.createFoldersIfNotExists([ TEMPLATES_FOLDER, STATIC_FOLDER, ASSETS_FOLDER, STORAGE_FOLDER ])
app = Flask(__name__, template_folder=TEMPLATES_FOLDER, static_folder=STATIC_FOLDER)

################################################################################################
#####> UTIL METHODS
################################################################################################

# Upload the report files in the STORAGE_FOLDER
def uploadReportFiles(data : dict, normal_arr : list, thermal_arr : list):

	# Sanitize data
	date_time             = datetime.now()
	data["date"]          = FileManagement.sanitizeFileName(date_time.strftime('%Y-%m-%d'))
	data["time"]          = FileManagement.sanitizeFileName(date_time.strftime('%H-%M-%S'))
	data["building_name"] = FileManagement.sanitizeFileName(data["building_name"])
	data["row"] 		  = FileManagement.sanitizeFileName(int(data["row"]))
	data["column"] 		  = FileManagement.sanitizeFileName(int(data["column"]))

	# Create base folder
	base_folder_path = os.path.join(STORAGE_FOLDER, data["building_name"], data["date"], data["row"], data["column"])
	if FileManagement.folderExists(base_folder_path):
		raise Exception("Data already exists for the id (building_name, time, row, column)")
	FileManagement.createFolderIfNotExists(base_folder_path)

	# Create paths
	normal_initial_image_full_path  = os.path.join(base_folder_path, STORAGE_NORMAL_INITIAL_IMAGE_FILE_NAME  + ".png")
	normal_result_image_full_path   = os.path.join(base_folder_path, STORAGE_NORMAL_RESULT_IMAGE_FILE_NAME   + ".png")
	thermal_initial_image_full_path = os.path.join(base_folder_path, STORAGE_THERMAL_INITIAL_IMAGE_FILE_NAME + ".png")
	thermal_result_image_full_path  = os.path.join(base_folder_path, STORAGE_THERMAL_RESULT_IMAGE_FILE_NAME  + ".png")
	result_data_full_path           = os.path.join(base_folder_path, STORAGE_RESULT_DATA_FILE_NAME   + "." + "json")

	# Make detections
	normal_initial_img, normal_result_image, normal_result_predictions = STRUCTURAL_ISSUES_DETECTOR.detectFromArray(normal_arr)
	thermal_initial_img, thermal_result_image, thermal_result_predictions = THERMAL_ISSUES_DETECTOR.detectFromArray(thermal_arr)

	# Save result images
	normal_initial_img.save(normal_initial_image_full_path)
	thermal_initial_img.save(thermal_initial_image_full_path)
	normal_result_image.save(normal_result_image_full_path)
	thermal_result_image.save(thermal_result_image_full_path)

	# Merge predictions for json
	all_predictions = normal_result_predictions + thermal_result_predictions
	all_predictions_class_name = map(lambda pred: pred["class"], all_predictions)
	result_json = {
		"metadata": {
			"building_name": str(data["building_name"]),
			"day"          : str(data["date"]),
			"time"         : str(data["time"]),
			"column"       : str(data["column"]),
			"row"          : str(data["row"])
		},
		"images": {
			"normal": {
				"initial": normal_initial_image_full_path,
				"result" : normal_result_image_full_path
			},
			"thermal": {
				"initial": thermal_initial_image_full_path,
				"result" : thermal_result_image_full_path
			}
		},
		"predictions": all_predictions,
		"issues_nb": dict(Counter(all_predictions_class_name))
	}

	# Save result data
	with open(result_data_full_path, 'w') as f:
		f.write(json.dumps(result_json, indent=4))

	# Return full paths
	return getPartialAnalysis(data["building_name"], data["date"], data["row"], data["column"])

# Get the report data for a wall cell of a building at a time
def getPartialAnalysis(building_name : str, day_string : str, row : int, column : int):

	# Get JSON data
	analysis_json = os.path.join(STORAGE_FOLDER, FileManagement.sanitizeFileName(building_name), FileManagement.sanitizeFileName(day_string), FileManagement.sanitizeFileName(row), FileManagement.sanitizeFileName(column), STORAGE_RESULT_DATA_FILE_NAME + ".json")
	with open(analysis_json, "r") as f:
		analysis_data = json.load(f)

	return analysis_data

# Get the report data for a building at a time
def getCompleteAnalysis(building_name : str, day_string : str):

	result = {}

	# All analysis results
	analysis_results = []
	main_directory = os.path.join(STORAGE_FOLDER, FileManagement.sanitizeFileName(building_name), FileManagement.sanitizeFileName(day_string))
	for (row_folder_name, row_folder_full_path) in FileManagement.subFolders(main_directory):
		for (col_folder_name, col_folder_full_path) in FileManagement.subFolders(row_folder_full_path):
			# An analysis result
			analysis_results.append(getPartialAnalysis(building_name, day_string, row_folder_name, col_folder_name))
	result["analysis_results"] = analysis_results

	# Building issues counter
	class_name_predictions = [ prediction_data["class"] for analysis_data in analysis_results for prediction_data in analysis_data["predictions"] ]
	class_name_counter     = Counter(class_name_predictions)
	result["class_name_count"] = class_name_counter

	# Building big image
	max_column      = max([ int(analysis_data["metadata"]["column"]) for analysis_data in analysis_results  ])
	max_row         = max([ int(analysis_data["metadata"]["row"])    for analysis_data in analysis_results  ])
	big_original_image_matrix  = [ [ None for j in range(max_column + 1) ]  for i in range(max_row + 1) ]
	for analysis_data in analysis_results:
		col = int(analysis_data["metadata"]["column"])
		row = int(analysis_data["metadata"]["row"])

		big_original_image_matrix[max_row-row][col] = {
			"normal_initial_image_path"  : str(analysis_data["images"]["normal"]["initial"]),
			"normal_result_image_path"   : str(analysis_data["images"]["normal"]["result"]),
			"thermal_initial_image_path" : str(analysis_data["images"]["thermal"]["initial"]),
			"thermal_result_image_path"  : str(analysis_data["images"]["thermal"]["result"]),
		}
	result["big_original_image_matrix"] = big_original_image_matrix

	return result

# Get all the analysis dates of a bulding
def getAllAnalysisDatesOfBuilding(building_name : str):
    return [
		{
			"human"    : getReadableDate(date_file_path),
			"program" : date_file_path
		}
		for (date_file_path, date_file_full_path)
		in FileManagement.subFolders(os.path.join(STORAGE_FOLDER, FileManagement.sanitizeFileName(building_name)))
	]

# Get a readable data from the storage date
def getReadableDate(storageDate : str):
    return datetime.strptime(storageDate, '%Y%m%d').date().strftime('%d/%m/%Y')

################################################################################################
#####> DELETE REQUESTS
################################################################################################

# Delete completely the file storage
@app.route('/api/clear', methods=['DELETE'])
def apiClear():
	FileManagement.deleteFoldersRecursively(STORAGE_FOLDER)
	FileManagement.createFolderIfNotExists(STORAGE_FOLDER)

	return "Cleared"

################################################################################################
#####> POST REQUESTS
################################################################################################

# Upload images
@app.route('/api/upload', methods=['POST'])
def apiUpload():

	json_data = request.json
	building_name = json_data["building_name"]
	images = json_data["images"]

	for image_data in images:

		row, col, normal_arr, thermal_arr = image_data["row"], image_data["col"], image_data["normal_array"], image_data["thermal_array"]

		uploadReportFiles(
			{
				"building_name": building_name,
				"row"          : row,
				"column"       : col
			},
			normal_arr,
			thermal_arr
		)

	# TODO: return the link
	return ""

################################################################################################
#####> GET REQUESTS
################################################################################################

# Historic report (historic evolution of a wall cell)
@app.route('/historic-report/<building_name>/<row>/<column>', methods=['GET'])
def historic_report(building_name : str, row : int, column : int):

	day_analysis = {}
	day_predictions_count = []

	building_folder_full_path = os.path.join(STORAGE_FOLDER, FileManagement.sanitizeFileName(building_name))
	for (date_file_path, date_file_full_path) in FileManagement.subFolders(building_folder_full_path):
		day_string = date_file_path
		analysis = getPartialAnalysis(building_name, day_string, row, column)
		day_analysis[getReadableDate(day_string)] = analysis

		predictions_count = dict(Counter([ prediction["class"] for prediction in analysis["predictions"] ]))
		predictions_count["date"] = getReadableDate(day_string)
		day_predictions_count.append(predictions_count)

	return render_template("part/historic_report.html", day_analysis=day_analysis, day_predictions_count=day_predictions_count)

# Report page (report of a wall)
@app.route('/report/<building_name>/<day_string>', methods=['GET'])
def report(building_name : str, day_string : str = "_"):

	analysis_dates = getAllAnalysisDatesOfBuilding(building_name)

	# Last report date by default
	if day_string == "_":
		day_string = analysis_dates[-1]["program"]

	analysis = getCompleteAnalysis(building_name, day_string)

	return render_template(
		"pages/report.html",
  		building_name=building_name,
		analysis_date=day_string,
		analysis_dates=analysis_dates,
		analysis=analysis
	)

# Home page (company info + all reports links)
@app.route('/', methods=['GET'])
def home():

	reports = []

	# For each buildings
	main_directory = STORAGE_FOLDER
	for (building_path, building_full_path) in FileManagement.subFolders(main_directory):
		building_name = building_path

		# Add an entry
		reports.append({
			"building_name" : building_name,
			"link"          : url_for("report", building_name=building_name, day_string="_")
		})

	return render_template(
		"pages/home.html",
		reports=reports
	)

# Test structural defects AI
@app.route('/test/structural_defects', methods=['GET'])
def test_structural_defects_ai():

	search_folder = "/Users/ewenbouquet/Downloads/initial"
	insert_folder = "/Users/ewenbouquet/Downloads/result"

	FileManagement.createFoldersIfNotExists([search_folder, insert_folder])

	for (file_name, file_full_path) in tqdm(FileManagement.subFiles(search_folder)):
		img = Image.open(file_full_path)
		init_img, result_img, result_arr = STRUCTURAL_ISSUES_DETECTOR.detectFromImage(img)
		result_img.save(os.path.join(insert_folder, file_name))

	return "Done"

################################################################################################
#####> LAUNCH SERVER
################################################################################################

if __name__ == '__main__':
	app.run(debug=True)


# -*- coding: utf-8 -*-
import numpy as np
from sa import SA
from copy import deepcopy
import matplotlib.pyplot as plt
import argparse

parser = argparse.ArgumentParser(description='Use simulated annealing to solve TSP problem')
parser.add_argument('--file_path', type=str, default='location.txt', help='data path to be solved')
parser.add_argument('--seed', type=int, default=800, help='one of [800,689,308,556,112] is good choice.(default:800)')
parser.add_argument('--init_T', type=float, default=200, help='initial temperature(default:200)')
parser.add_argument('--anneal_rate', type=float, default=0.95, help='initial temperature anneal rate(default:0.95)')
parser.add_argument('--final_T', type=float, default=0.001, help='final temperature(default:0.001)')
parser.add_argument('--inner_iters', type=float, default=120, help='inner loop  iterations(default:120)')
parser.add_argument('--random_init', action='store_false', default=True,
                    help='whether to initial solution randomly(default:True)')
parser.add_argument('--mode', type=str, default='reverse',
                    help='the method of get new solution. It must be one of [reverse,cross](default:reverse)')
parser.add_argument('--anneal_mode', type=int, default=0, help='anneal mode. It must be one of [0,1,2](default:0)')
ars = parser.parse_args()

np.random.seed(ars.seed)  # set random seed for reproducing experiment results
data = np.loadtxt(ars.file_path, delimiter=',', usecols=[1, 2])  # load data
# init algorithm
sa = SA(data, T=ars.init_T, anneal_rate=ars.anneal_rate, final_T=ars.final_T, inner_iters=ars.inner_iters, random_init=ars.random_init)
# run algorithm
log = sa.train(mode=ars.mode, anneal_mode=ars.anneal_mode)
# log information
t = log['time']
dis = log['dis']
path = log['path']
dis_lst = deepcopy(sa.dis_lst)
print('time:{:.3f}\tbest distance:{}'.format(t, dis))
print('Now you can use test.exe to verify solution.')
# save best result. So you can excute test.exe to verify the solution
np.savetxt('city.txt', path + 1, fmt='%d', newline=',')
# plot distance over time
fig = plt.figure()
ax = fig.add_subplot(211)
ax.plot(dis_lst)
ax.set_xlabel('num')
ax.set_ylabel('distance')
ax.set_title('best distance:' + str(dis))
# plot best path. It is similar to the result of running test.exe
ax = fig.add_subplot(212, aspect='equal')
ax.plot(data[:, 0], data[:, 1], 'x', color='blue')
for i, loc in enumerate(data):
    ax.text(loc[0], loc[1], str(i))
ax.plot(data[path, 0], data[path, 1], color='red')
plt.show()


import os
import numpy as np
import pandas as pd

class ZBD(object):

    # This is -15 dBm, or about 32 uW, which is the maximum power that keeps the output compression under 0.5 dB.
    #maximum_linear_power = 1e-3 * 10**(-15 / 10)

    def __init__(self):
        this_directory = os.path.dirname(__file__)
        self.frequency_data_Hz = np.load(os.path.join(this_directory, 'frequency_data_Hz.npy'))
        self.responsivity_data_V_per_W = np.load(os.path.join(this_directory, 'responsivity_data_V_per_W.npy'))
        self.high_linearity_polynomial = np.load(os.path.join(this_directory, 'high_linearity_polynomial.npy'))
        self.high_linearity_domain = np.load(os.path.join(this_directory, 'high_linearity_domain.npy'))

    def responsivity(self, frequency):
        return np.interp(frequency, self.frequency_data_Hz, self.responsivity_data_V_per_W)

    def linearity(self, voltage):
        linear = np.ones(voltage.size, dtype=np.float)
        voltage = np.array(voltage)
        mask = (self.high_linearity_domain[0] <= voltage) & (voltage <= self.high_linearity_domain[1])
        linear[mask] = np.polyval(self.high_linearity_polynomial, voltage[mask])
        # The fit is not currently believable outside the fit domain.
        linear[self.high_linearity_domain[1] < voltage] = np.nan
        return linear

    """
    def maximum_linear_voltage(self, frequency):
        return self.maximum_linear_power * self.responsivity(frequency)
    """

def excel_to_npy():
    xlsx_filename = '13067-columbia-wr6.5zbd-datapoints.xlsx'
    this_directory = os.path.dirname(__file__)
    data = pd.ExcelFile(os.path.join(this_directory, xlsx_filename)).parse('Sheet1')
    frequency_data_Hz = 1e9 * np.array(data['Freq (GHz)'])
    responsivity_data_V_per_W = np.array(data['Responsivity (V/W)'])
    np.save(os.path.join(this_directory, 'frequency_data_Hz.npy'), frequency_data_Hz)
    np.save(os.path.join(this_directory, 'responsivity_data_V_per_W.npy'), responsivity_data_V_per_W)


import argparse

class Recipe:
    def __init__(self) -> None:
        self.c_sources = list[str]()
        self.c_include = list[str]()
        self.c_libs = list[str]()
        self.c_defs = list[str]()
        self.mcu = list[str]()
        self.ldscript = str()

    def to_cmake(self) -> str:
        cmake = str()

        cmake += "set(LINKER_SCRIPT ${CMAKE_CURRENT_LIST_DIR}/%s)\n" % (
            self.ldscript)
        cmake += "\n"

        cmake += Recipe.create_cmake_list(
            "set(BSP_SOURCES\n",
            self.c_sources,
            base_dir="${CMAKE_CURRENT_LIST_DIR}/")
        cmake += "\n"

        cmake += Recipe.create_cmake_list(
            "include_directories(\n",
            self.c_include,
            remove=[' ', '-I'],
            base_dir="${CMAKE_CURRENT_LIST_DIR}/")
        cmake += "\n"

        cmake += Recipe.create_cmake_list("set(MCU_OPTS\n", self.mcu)
        cmake += "\n"

        cmake += "add_link_options(\n"
        cmake += "\t${MCU_OPTS}\n"
        cmake += "\t-T ${LINKER_SCRIPT}\n"
        cmake += "\t)\n"
        cmake += "\n"

        self.c_defs.append("${MCU_OPTS}")
        cmake += "\n"

        cmake += Recipe.create_cmake_list(
            "add_compile_options(\n", self.c_defs)
        cmake += "\n"

        return cmake

    @staticmethod
    def create_cmake_list(
            header: str, content: list[str],
            remove=[' '], footer="\t)\n",
            base_dir="") -> str:
        result = header
        for c in content:
            for s in remove:
                c = c.strip(s)
            result += "\t%s%s\n" % (base_dir, c)
        result += footer

        return result

    @staticmethod
    def from_cubemx_makefile(makefile_path: str):
        makefile = dict[str, list[str]]()
        recipe = Recipe()
        with open(makefile_path, 'r') as f:
            rawData = f.read()

        rawData = rawData.replace('\\\n', ',').split('\n')
        for line in rawData:
            if '=' not in line:
                continue
            line = line.split(' = ')
            key = line[0]

            if key not in makefile.keys():
                makefile[key] = line[1:]
            else:
                makefile[key] += line[1:]

        recipe.mcu = Recipe.parse_makefile_mcu(makefile)
        recipe.c_sources = Recipe.parse_path_list(makefile, 'C_SOURCES')
        recipe.c_sources += Recipe.parse_path_list(makefile, 'ASM_SOURCES')
        recipe.c_include = Recipe.parse_path_list(makefile, 'C_INCLUDES')
        recipe.c_libs = Recipe.parse_path_list(makefile, 'LIBS', separator=' ')
        recipe.c_defs = Recipe.parse_path_list(makefile, 'C_DEFS')
        recipe.ldscript = makefile['LDSCRIPT'][0]

        return recipe

    @ staticmethod
    def parse_makefile_mcu(makefile: dict[str, list[str]]) -> list[str]:
        mcu = makefile['MCU'][0]
        mcu = mcu.replace('$(CPU)', makefile['CPU'][0])
        mcu = mcu.replace('$(FPU)', makefile['FPU'][0])
        mcu = mcu.replace('$(FLOAT-ABI)', makefile['FLOAT-ABI'][0])
        mcu = mcu.split(' ')

        return mcu

    @ staticmethod
    def parse_path_list(
            makefile: dict[str, list[str]],
            target: str, separator=',') -> list[str]:
        line = makefile[target][0].split(separator)
        if line[0] == ' ':
            return line[1:]
        else:
            return line

if __name__ == '__main__':
    parse = argparse.ArgumentParser()

    parse.add_argument('f', help='Makefile path')

    args = parse.parse_args()

    recipe = Recipe.from_cubemx_makefile(args.f)
    print(recipe.to_cmake())


import os
import csv
import gzip
import base64
import hashlib
import requests
import numpy as np
import pandas as pd
from tqdm import tqdm
import copy

from file_utils import *

###################################################################################################
#                    Functions to download and process WMT document splits
###################################################################################################

# Code from deepmind repo
def get_year_hashes(year, raw_splits_dir, lang):
  """
  Read gzipped splits files and output hashes, dates, and base64 encoded text

  Args:
      year (int): the year of the given split to read
      raw_splits_dir (string): the path to the outputs folder

  Yields:
      string, (string, string, string): docid, (date, sentence_split_text, unsplit_text)
  """
  with gzip.open(raw_splits_dir + "news-docs." + str(year) + "." + lang + ".filtered.gz", 'rb') as gz_file:
    for line in gz_file:
      date, sentence_split_text, unsplit_text = line.decode('utf-8').strip().split('\t')
      docid = hashlib.sha256(unsplit_text.encode('utf-8')).hexdigest()
      yield docid, (date, sentence_split_text, unsplit_text)

def decode_and_write_wmt_splits(split_year, raw_splits_dir, decoded_splits_dir, lang):
  """ Unzips and decodes WMT doc splits for a given year, writes articles with metadata to
      a csv in the given directory

  Args:
      split_year (int): the year of the split to decode and save
      raw_splits_dir (string): path to the directory containing the unzipped downloaded splits
      decoded_splits_dir (string): path to the output directory
  """
  year_data = get_year_hashes(split_year, raw_splits_dir, lang)
  # Save a csv with docid, date, and sentence split text cols
  with open(decoded_splits_dir + "decoded_splits_" + str(split_year) + ".csv", "w") as splits_csv:
    splits_writer = csv.writer(splits_csv, delimiter="\t")
    splits_writer.writerow(["docid", "date", "sentence_split_text"])
    for docid, (date, sentence_split_text, unsplit_text) in tqdm(year_data):
      decoded_text = base64.b64decode(sentence_split_text)
      splits_writer.writerow([docid, date, decoded_text.decode().replace("\n", " ")])

def download_WMT_doc_splits(year, lang, raw_splits_dir):
  """ Downloads document split articles of the given year and language from the WMT database

  Args:
      year (int): the year of the splits to download
      lang (string): the abbreviated language of the splits to download (e.g. "en", "zh", ...)
      raw_splits_dir (string): the path to the output directory
  """
  r = requests.get("https://data.statmt.org/news-crawl/doc/" + lang + "/news-docs." +
                   str(year) + "." + lang + ".filtered.gz",
                   auth=("newscrawl", "acrawl4me"))
  with open(raw_splits_dir + "news-docs." + str(year) +  "." +
            lang + ".filtered.gz", 'wb') as raw_file:
    raw_file.write(r.content)

def load_shuffled_wmt_texts(year, decoded_splits_dir):
  """ Loads and shuffles already decoded splits from the given year

  Args:
      year (int): the year of the decoded splits to load
      decoded_splits_dir (string): the directory where decoded splits are stored

  Returns:
      string[], string[], string[]: shuffled docids, dates, and texts for all decoded articles
                                    in the decoded split
  """
  fp = decoded_splits_dir + "decoded_splits_" + str(year) + ".csv"
  year_df = pd.read_csv(fp, delimiter="\t", header=0)
  # Randomly shuffle rows of the dataframe without replacement and reset indices
  year_df = year_df.sample(frac=1).reset_index(drop=True)
  docids = list(year_df.docid)
  dates = list(year_df.date)
  texts = list(year_df.sentence_split_text)
  return docids, dates, texts

###################################################################################################
#                                     Example splits creation
###################################################################################################

LANG = "de" # WMT only has document splits for en, de, and cs. Other datasets only use "en"
SPLIT_YEARS = list(range(2012, 2022)) # 2012 - 2021
DATA_DIR = "./WMTdata/" + LANG + "/"
SPLITS_TYPE = "bytes"
SAVE_METADATA = False

WMT_RAW_SPLITS_DIR =  DATA_DIR + "raw_doc_splits/"
WMT_DECODED_SPLITS_DIR = DATA_DIR + "decoded_doc_splits/"

TR_YEAR_BYTES = 200000000
TR_MONTH_BYTES = 30000000
TR_DAY_BYTES = 0
EV_YEAR_BYTES = 10000000
EV_MONTH_BYTES = 3000000
EV_DAY_BYTES = 0

PERCENT_TRAIN_TO_TEST_TEXTS = 0.9

if __name__ == "__main__":
  for dir_name in [DATA_DIR, WMT_RAW_SPLITS_DIR, WMT_DECODED_SPLITS_DIR,
                 DATA_DIR + "train/", DATA_DIR + "test/"]:
    if not os.path.isdir(dir_name):
      os.makedirs(dir_name)

  # Download and save splits using python requests
  print("Downloading " + LANG + " WMT datasets")
  for split_year in tqdm(SPLIT_YEARS):
    download_WMT_doc_splits(split_year, LANG, WMT_RAW_SPLITS_DIR)

  # Create year, month, and day splits from decoded files
  for split_year in SPLIT_YEARS:
    print(str(split_year) + " -----------------------------------")

    # Decode base64 encoded text for the given years and output in csv files with date and docid
    print("Decoding texts...")
    decode_and_write_wmt_splits(split_year, WMT_RAW_SPLITS_DIR, WMT_DECODED_SPLITS_DIR, LANG)

    # Shuffle texts and partition into train/text parts
    print("Shuffling texts...")
    docids, dates, texts = load_shuffled_wmt_texts(split_year, WMT_DECODED_SPLITS_DIR)
    num_train_texts = round(len(texts) * PERCENT_TRAIN_TO_TEST_TEXTS)
    train_dates = dates[:num_train_texts]
    train_texts = texts[:num_train_texts]
    test_dates = dates[num_train_texts:]
    test_texts = texts[num_train_texts:]

    # Create splits for each year/month/day from the train/test sets
    # with the given number of tokens/articles/bytes
    print("Creating year/month/day article splits...")
    # Create train splits
    tr_year_vocab, tr_month_vocabs, tr_day_vocabs, \
    tr_year_non_lang, tr_month_non_lang, tr_day_non_lang = \
      year_texts_to_splits(DATA_DIR + "train/", LANG, train_texts, train_dates,
                    year_size=TR_YEAR_BYTES,
                    month_size=TR_MONTH_BYTES,
                    day_size=TR_DAY_BYTES,
                    split_type=SPLITS_TYPE)

    # Create test splits
    te_year_vocab, te_month_vocabs, te_day_vocabs, \
    te_year_non_lang, te_month_non_lang, te_day_non_lang = \
      year_texts_to_splits(DATA_DIR + "test/", LANG, test_texts, test_dates,
                    year_size=EV_YEAR_BYTES,
                    month_size=EV_MONTH_BYTES,
                    day_size=EV_DAY_BYTES,
                    split_type=SPLITS_TYPE)

    if SAVE_METADATA:
      tr_vocabs = {
        "year": [],
        "month": [],
        "day": []
      }
      te_vocabs = copy.deepcopy(tr_vocabs)

      tr_non_lang_counts = {
        "year": [],
        "month": [],
        "day": []
      }
      te_non_lang_counts = copy.deepcopy(tr_non_lang_counts)

      tr_vocabs["year"].append(tr_year_vocab)
      tr_vocabs["month"].append(tr_month_vocabs)
      tr_vocabs["day"].append(tr_day_vocabs)
      tr_non_lang_counts["year"].append(tr_year_non_lang)
      tr_non_lang_counts["month"].append(tr_month_non_lang)
      tr_non_lang_counts["day"].append(tr_day_non_lang)

      te_vocabs["year"].append(te_year_vocab)
      te_vocabs["month"].append(te_month_vocabs)
      te_vocabs["day"].append(te_day_vocabs)
      te_non_lang_counts["year"].append(te_year_non_lang)
      te_non_lang_counts["month"].append(te_month_non_lang)
      te_non_lang_counts["day"].append(te_day_non_lang)

      np.save(DATA_DIR + SPLITS_TYPE + "_vocabs" + str(split_year),
            {"train": tr_vocabs, "test": te_vocabs})
      np.save(DATA_DIR + SPLITS_TYPE + "_non_lang_counts" + str(split_year),
            {"train": tr_non_lang_counts, "test": te_non_lang_counts})

  # Create a blank text file to use as a dummy target for huggingface's Trainer
  with open(DATA_DIR + "blank.txt", 'w') as blank_file:
    blank_file.write("<START>")


class Fraction:
    """ This class represents one single fraction that consists of
        numerator and denominator """

    def __init__(self, numerator, denominator):
        """
        Constructor. Checks that the numerator and denominator are of
        correct type and initializes them.

        :param numerator: fraction's numerator
        :param denominator: fraction's denominator
        """

        if not isinstance(numerator, int) or not isinstance(denominator, int):
            raise TypeError
        elif denominator == 0:
            raise ValueError

        self.__numerator = numerator
        self.__denominator = denominator

    def return_string(self):
        """ Returns a string-presentation of the fraction in the format
        numerator/denominator """

        if self.__numerator * self.__denominator < 0:
            sign = "-"
        else:
            sign = ""
        return "{:s}{:d}/{:d}".format(sign, abs(self.__numerator), abs(self.__denominator))

    def __str__(self):
        if self.__numerator * self.__denominator < 0:
            sign = "-"
        else:
            sign = ""
        return "{:s}{:d}/{:d}".format(sign, abs(self.__numerator), abs(self.__denominator))

    def simplify(self):
        gcd = greatest_common_divisor(self.__numerator, self.__denominator)
        self.__numerator //= gcd
        self.__denominator //= gcd

def greatest_common_divisor(a, b):
    """
    Euclidean algorithm.
    """

    while b != 0:
        a, b = b, a % b
    return a

def least_common_divisor(a, b):
    """Compute the lowest common multiple of a and b"""

    return int(a * b // greatest_common_divisor(a, b))

def main():
    print("Enter fractions in the format integer/integer.")
    print("One fraction per line. Stop by entering an empty line.")
    fraction_list = []
    while True:
        user_input = input()
        if user_input == "":
            break
        split_value = user_input.split("/")
        numerator = int(split_value[0])
        denominator = int(split_value[1])
        fraction_list.append(Fraction(numerator, denominator))

    print("The given fractions in their simplified form:")
    for fraction in fraction_list:
        # simplify =
        print(fraction, "=", end=" ")
        fraction.simplify()
        print(fraction)

main()

11.More on classes and objects/11.6.list_of_fractions.py


# dataset : https://www.kaggle.com/competitions/dog-breed-identification/data

import numpy as np
import cv2

IMAGE_SIZE = (331,331)
IMAGE_FULL_SIZE = (331,331,3)

trainMyImageFolder = "E:/Data-sets/Dog Breed Identification/train"

# load the csv file
import pandas as pd

df = pd.read_csv('E:/Data-sets/Dog Breed Identification/labels.csv')
print("head of lables :")
print("================")

print(df.head())
print(df.describe())

print("Group by labels : ")
grouplables = df.groupby("breed")["id"].count()
print(grouplables.head(10))

# display one image

imgPath = "E:/Data-sets/Dog Breed Identification/train/00a366d4b4a9bbb6c8a63126697b7656.jpg"
img = cv2.imread(imgPath)
#cv2.imshow("img",img)
#cv2.waitKey(0)

# prepare all the images and lables as Numpy arrays

allImages = []
allLabes = []
import os

for ix , (image_name , breed) in enumerate(df[['id' , 'breed']].values):
    img_dir = os.path.join(trainMyImageFolder, image_name + '.jpg')
    print(img_dir)

    img = cv2.imread(img_dir)
    resized = cv2.resize(img,IMAGE_SIZE, interpolation= cv2.INTER_AREA)
    allImages.append(resized)
    allLabes.append(breed)

print(len(allImages))
print(len(allLabes))

print("save the data :")
np.save("e:/temp/allDogsImages.npy",allImages)
np.save("e:/temp/allDogsLables.npy",allLabes)

print("finish save the data ....")


'''
Operations with database
'''

import pandas as pd
#from sqlalchemy import create_engine
from datetime import datetime
from datetime import date

class db_manager:
    def __init__(self, schema, engine):
        self.schema = schema
        self.engine = engine

    def db_import_table(self, importing_table, destination_table, if_exists_opt):
        """
        Execute table import to database
        """
        importing_table.to_sql(destination_table, con=self.engine, schema=self.schema, if_exists=if_exists_opt, index=False)

    def db_select_quotes_table(self, start_date, end_date, ticker):
        """
        Execute select from quotes table in database
        """
        start_dt = str(datetime(start_date.year, start_date.month, start_date.day))
        end_dt = str(datetime(end_date.year, end_date.month, end_date.day))

        sql = f"""
        SELECT *
        FROM {self.schema}.quotes
        WHERE tradeDate BETWEEN '{start_dt}' AND '{end_dt}'
        AND ticker = '{ticker}';
        """

        data_table = pd.read_sql(sql, self.engine)
        return data_table

    def db_select_table(self, table_name):
        """
        Execute select from exact table in database
        """

        sql = f"""
        SELECT *
        FROM {self.schema}.{table_name};
        """

        data_table = pd.read_sql(sql, self.engine)
        return data_table

    def db_quotes_actuality_table(self):
        """
        Updates actuality of data for quotes table
        """
        sql_create_actuality_table = f"""
        CREATE TABLE IF NOT EXISTS quotes_actuality (
            ticker VARCHAR(12) NOT NULL,
            tradeDate TIMESTAMP NOT NULL,
            createDate TIMESTAMP
        ) ENGINE=INNODB;
        """

        sql_update_table = f"""
        DELETE FROM {self.schema}.quotes_actuality
        """

        sql_actuality_data = f"""
        SELECT ticker, max(tradeDate)
        FROM {self.schema}.quotes
        GROUP BY ticker
        """

        #self.engine.execute(sql_create_actuality_table)
        self.engine.execute(sql_update_table)

        quotes_actuality_table = pd.read_sql(sql_actuality_data, self.engine)
        quotes_actuality_table.columns = ["ticker", "tradeDate"]
        quotes_actuality_table['createDate'] = datetime.today()
        quotes_actuality_table.to_sql("quotes_actuality", con=self.engine, schema=self.schema, if_exists='append', index=False)
        return quotes_actuality_table

    def db_user_instrument_table(self, tip_id):
        """
        Select unused tips requests
        """

        sql_select_instr_table = f"""
                SELECT * FROM {self.schema}.user_instrument a
                WHERE a.id = '{tip_id}'
                """

        data_table = pd.read_sql(sql_select_instr_table, self.engine)
        return data_table

    def db_check_quotes_actuality(self, ticker):
        """
        Check data actuality for ticker
        :param ticker:
        :return: last available data in DB for a ticker
        """
        sql = f"""
        SELECT *
        FROM {self.schema}.quotes_actuality
        """

        actuality_table = pd.read_sql(sql, self.engine)
        act_dt = actuality_table[actuality_table["ticker"] == ticker]["tradeDate"]
        if act_dt.empty:
            actuality_date = date(2015, 1, 1)
        else:
            actuality_date = list(act_dt)[0]
        return actuality_date.date()

    def db_update_quotes_table(self, importing_table):
        """
        Updates quotes table
        :param engine:
        :param importing_table:
        :return:
        """
        ticker = list(importing_table["ticker"])[0]
        tradedate_min = min(importing_table["tradeDate"])
        tradedate = str(datetime(tradedate_min.year, tradedate_min.month, tradedate_min.day))

        sql_delete = f"""
        DELETE FROM {self.schema}.quotes
        WHERE tradeDate >= '{tradedate}' AND ticker='{ticker}';

        """
        self.engine.execute(sql_delete)
        importing_table.to_sql("quotes", con=self.engine, schema=self.schema, if_exists='append')


from django.urls import path
from .views import PhotoCreate, PhotoList, PhotoUpdate, PhotoDelete, PhotoSearchView, create_comment, delete_comment, \
    PhotoDetail, Like, TagPhotoView, TagcloudTV

from django.conf.urls.static import static
from django.conf import settings

app_name = 'photo'

urlpatterns = [
    path("", PhotoList.as_view(), name='index'),
    path("create/", PhotoCreate.as_view(), name='create'),
    path("<int:pk>/", PhotoDetail.as_view(), name='detail'),
    path('<int:pk>/comment/create/', create_comment, name='create_comment'),
    path('<int:pk>/comment/delete/', delete_comment, name='delete_comment'),
    path("update/<int:pk>/", PhotoUpdate.as_view(), name='update'),
    path("delete/<int:pk>/", PhotoDelete.as_view(), name='delete'),
    path("search/", PhotoSearchView.as_view(), name='search'),
    path("<int:pk>/like", Like, name='like'),
    path('tag/', TagcloudTV.as_view(), name='tag_cloud'),
    path('tag/search/<str:tag>', TagPhotoView.as_view(), name='tagged_object_list'),
]

urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)


# Write your code below:
from contextlib import contextmanager

@contextmanager
def generic(card_type, sender_name, recipient):
  card_file = open("card_file", "r")
  order = open("{} >_ generic.txt".format(sender_name), "w")
  try:
    order.write("Dear {}".format(recipient))
    order.write(card_file.read())
  finally:
    card_file.close()
    order.close()

with generic("thankyou_card.txt", "Mewnda", "Amanda") as order1:
  print("Card generated!!!!")

# Uncomment to run!
# with generic("thankyou_card.txt", "Mwenda", "Amanda") as order1:
#   print('Card Generated! \n')

# with open("Mwenda_generic.txt", "r") as first_order:
#   print(first_order.read())


from django.urls import path
from . import views

app_name = 'queueforRestaurant'

urlpatterns = [
    path('', views.index, name='index'),  # <-- This is the new URL pattern for the homepage
    path('add/', views.add_to_queue, name='add_to_queue'),
]


import sqlite3
from tabulate import tabulate
import pandas as pd
# Conexión a la base de datos
def connect_database():
    conn = sqlite3.connect('biblioteca.db')
    return conn
##############################################################################################################3
def exportar_a_excel(data, headers):
    nombre_archivo = input("Ingrese el nombre del archivo Excel: ")
    ruta_archivo = f"{nombre_archivo}.xlsx"
    df = pd.DataFrame(data, columns=headers)
    df.to_excel(ruta_archivo, index=False)
    print(f"El reporte se ha exportado a {ruta_archivo}")

# Crear la tabla si no existe
def create_table(conn):
    cursor = conn.cursor()
    cursor.execute('''
        CREATE TABLE IF NOT EXISTS ejemplares (
            id INTEGER PRIMARY KEY,
            titulo TEXT,
            autor TEXT,
            genero TEXT,
            anio INTEGER,
            isbn TEXT,
            fecha_adquisicion TEXT
        )
    ''')
    conn.commit()
    #####

# Creación de la tabla autores
def create_table__(conn):
    cursor2 = conn.cursor()
    cursor.execute('''
    CREATE TABLE autores (
        id INTEGER PRIMARY KEY,
        nombres TEXT,
        apellidos TEXT
    )
''')
    conn.commit()
# Cierre de la conexión a la base de datos

###############3

#####################################3*********

# C

# Verificar si existen datos previos
def check_previous_data(conn):
    cursor = conn.cursor()
    cursor.execute('SELECT * FROM ejemplares')
    return cursor.fetchall()

# Guardar datos en la base de datos
def save_data(conn, data):
    cursor = conn.cursor()
    cursor.executemany('INSERT INTO ejemplares (id, titulo, autor, genero, anio, isbn, fecha_adquisicion) VALUES (?, ?, ?, ?, ?, ?, ?)', data)
    conn.commit()

# Generar un identificador único
def generate_id(conn):
    cursor = conn.cursor()
    cursor.execute('SELECT MAX(id) FROM ejemplares')
    result = cursor.fetchone()
    max_id = result[0] if result[0] else 0
    new_id = max_id + 1
    return new_id

# Presentar el menú principal
def menu_principal(conn):
    while True:
        print("Menu principal:")
        print("1. Registrar la adquisición de un ejemplar")
        print("2. Registrar un autor")
        print("3. Consultas en pantalla")
        print("4. Salir")

        option = input("Seleccione una opción: ")
        if option == "1":
            registrar_ejemplar(conn)
        elif option == "2":
            registrar_autor(conn)
        elif option == "3":
            menu_consultas(conn)
        elif option == "4":
            conn.close()
            break
        else:
            print("Opción no válida. Intente de nuevo.")

# Presentar el menú de consultas
def menu_consultas(conn):
    while True:
        print("Menú de consultas:")
        print("1. Consultar los datos de un título.")
        print("2. Reporte de todos los ejemplares existentes.")
        print("3. Reporte de ejemplares para un autor específico.")
        print("4. Reporte de ejemplares para un género específico.")
        print("5. Reporte de ejemplares para un año específico.")
        print("6. Consultar un autor por su nombre.")  # Nueva opción agregada
        print("7. Volver al menú principal")

        option = input("Seleccione una opción: ")

        if option == "1":
            buscar_ejemplar(conn)
        elif option == "2":
            reporte_general(conn)
        elif option == "3":
            reporte_autor(conn)
        elif option == "4":
            reporte_genero(conn)
        elif option == "5":
            reporte_anio(conn)
        elif option == "6":
            consultar_autor_por_nombre(conn)  # Nueva función agregada
        elif option == "7":
            break
        else:
            print("Opción no válida. Intente de nuevo.")

# Registrar la adquisición de un ejemplar
def registrar_ejemplar(conn):
    print("Registrar adquisición de un ejemplar:")
    titulo = input("Título: ").upper()
    autor = input("Autor: ").upper()
    genero = input("Género: ").upper()
    anio = input("Año de publicación: ")
    isbn = input("ISBN: ")
    fecha = input("Fecha de adquisición (en formato DD/MM/AAAA): ")

    data = [(generate_id(conn), titulo, autor, genero, anio, isbn, fecha)]
    save_data(conn, data)
    print("Ejemplar registrado exitosamente.")

    # Función para buscar un ejemplar por título
def buscar_ejemplar(conn):
    titulo = input("Ingrese el título a buscar: ").upper()
    cursor = conn.cursor()
    cursor.execute('SELECT * FROM ejemplares WHERE titulo = ?', (titulo,))
    result = cursor.fetchall()
    if result:
        print("Ejemplar encontrado:")
        for row in result:
            print("ID:", row[0])
            print("Título:", row[1])
            print("Autor:", row[2])
            print("Género:", row[3])
            print("Año de publicación:", row[4])
            print("ISBN:", row[5])
            print("Fecha de adquisición:", row[6])
    else:
        print("No se encontraron ejemplares con ese título.")

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

# ...

# Función para generar el reporte tabular de todos los ejemplares
def reporte_general(conn):
    cursor = conn.cursor()
    cursor.execute('SELECT * FROM ejemplares')
    result = cursor.fetchall()
    if result:
        headers = ["ID", "Título", "Autor", "Género", "Año de publicación", "ISBN", "Fecha de adquisición"]
        print("Reporte de todos los ejemplares:")
        print(tabulate(result, headers=headers, tablefmt="grid"))
    else:
        print("No hay ejemplares registrados.")

    exportar = input("¿Desea exportar el reporte a Excel? (Sí/No): ")
    if exportar.lower() == "sí" or exportar.lower() == "si":
        exportar_a_excel(result, headers)
    else:
        print(tabulate(result, headers=headers, tablefmt="grid"))

# Función para generar el reporte tabular de ejemplares para un autor específico
def reporte_autor(conn):
    autor = input("Ingrese el autor a buscar: ").upper()
    cursor = conn.cursor()
    cursor.execute('SELECT * FROM ejemplares WHERE autor = ?', (autor,))
    result = cursor.fetchall()
    if result:
        headers = ["ID", "Título", "Autor", "Género", "Año de publicación", "ISBN", "Fecha de adquisición"]
        print(f"Reporte de ejemplares para el autor {autor}:")
        print(tabulate(result, headers=headers, tablefmt="grid"))
    else:
        print("No hay ejemplares registrados para ese autor.")

    exportar = input("¿Desea exportar el reporte a Excel? (Sí/No): ")
    if exportar.lower() == "sí" or exportar.lower() == "si":
        exportar_a_excel(result, headers)
    else:
        print(tabulate(result, headers=headers, tablefmt="grid"))

# Función para generar el reporte tabular de ejemplares para un género específico
def reporte_genero(conn):
    genero = input("Ingrese el género a buscar: ").upper()
    cursor = conn.cursor()
    cursor.execute('SELECT * FROM ejemplares WHERE genero = ?', (genero,))
    result = cursor.fetchall()
    if result:
        headers = ["ID", "Título", "Autor", "Género", "Año de publicación", "ISBN", "Fecha de adquisición"]
        print(f"Reporte de ejemplares para el género {genero}:")
        print(tabulate(result, headers=headers, tablefmt="grid"))
    else:
        print("No hay ejemplares registrados para ese género.")

    exportar = input("¿Desea exportar el reporte a Excel? (Sí/No): ")
    if exportar.lower() == "sí" or exportar.lower() == "si":
        exportar_a_excel(result, headers)
    else:
        print(tabulate(result, headers=headers, tablefmt="grid"))

# Función para generar el reporte de ejemplares para un año específico
def reporte_anio(conn):
    anio = input("Ingrese el año a buscar: ")
    cursor = conn.cursor()
    cursor.execute('SELECT * FROM ejemplares WHERE anio = ?', (anio,))
    result = cursor.fetchall()
    if result:
        print(f"Reporte de ejemplares para el año {anio}:")
        for row in result:
            print("ID:", row[0])
            print("Título:", row[1])
            print("Autor:", row[2])
            print("Género:", row[3])
            print("Año de publicación:", row[4])
            print("ISBN:", row[5])
            print("Fecha de adquisición:", row[6])
    else:
        print("No hay ejemplares registrados para ese año.")

# #################funcion para ver la consulta por autor
def consultar_autor_por_nombre(conn):
    nombre = input("Ingrese el nombre del autor: ")
    cursor = conn.cursor()
    cursor.execute("SELECT * FROM autores WHERE nombre = ?", (nombre,))
    result = cursor.fetchall()

    if result:
        print(f"Registros del autor {nombre}:")
        for row in result:
            print(row)
    else:
        print("No hay registros para ese autor.")

# Registrar un autor
def registrar_autor(conn):
    print("Registrar un autor:")
    nombre = input("Apellidos y Nombres: ")

    cursor = conn.cursor()
    cursor.execute('INSERT INTO autores (nombre) VALUES (?)', (nombre,))
    conn.commit()
    print("Autor registrado exitosamente.")

# Registrar un género
def registrar_genero(conn):
    print("Registrar un género:")
    nombre = input("Nombre del género: ")

    cursor = conn.cursor()
    cursor.execute('INSERT INTO generos (nombre) VALUES (?)', (nombre,))
    conn.commit()
    print("Género registrado exitosamente.")

# ...

# Programa principal
def main():
    conn = connect_database()
    create_table(conn)
    previous_data = check_previous_data(conn)
    if previous_data:
        print("Se han encontrado datos previos.")
    else:
        print("No se ha encontrado una versión de datos previa. Se procederá a crear la base de datos por primera vez.")
        save_data(conn, previous_data)
    menu_principal(conn)

if __name__ == '__main__':
    main()


from core.opds_import import SimplifiedOPDSLookup
from core.util.http import HTTP
from tests.core.mock import MockRequestsResponse

class MockSimplifiedOPDSLookup(SimplifiedOPDSLookup):
    def __init__(self, *args, **kwargs):
        self.requests = []
        self.responses = []
        super().__init__(*args, **kwargs)

    def queue_response(self, status_code, headers={}, content=None):
        self.responses.insert(0, MockRequestsResponse(status_code, headers, content))

    def _get(self, url, *args, **kwargs):
        self.requests.append((url, args, kwargs))
        response = self.responses.pop()
        return HTTP._process_response(
            url,
            response,
            kwargs.get("allowed_response_codes"),
            kwargs.get("disallowed_response_codes"),
        )


# -*- coding: utf-8 -*-
# @File    : SmallestSubsequenceOfDistinctCharacters.py
# @Date    : 2022-06-20
# @Author  : tc
"""
1081. 不同字符的最小子序列
返回 s 字典序最小的子序列，该子序列包含 s 的所有不同字符，且只包含一次。

注意：该题与 316 https://leetcode.com/problems/remove-duplicate-letters/ 相同

示例 1：

输入：s = "bcabc"
输出："abc"
示例 2：

输入：s = "cbacdcbc"
输出："acdb"

用last_appear_index 存储字符串中字符最后一次出现的位置。
使用单调栈保证字典序最小，但前提是不能缺少唯一的字符，例如:addcbd，前面两个dd可以直接pop出去，因为后面还有一个d。

"""
class Solution:
    def smallestSubsequence(self, s: str) -> str:
        n = len(s)
        last_appear_index = [0] * 26
        for i in range(n):
            last_appear_index[ord(s[i]) - 97] = i
        stack = []
        for i in range(n):
            if s[i] in stack:
                continue
            # 使用单调栈保证字符串的字典序最小，如果ord(stack[-1]) - 97 在后面还会出现，在这里可以直接pop掉
            while stack and ord(stack[-1]) > ord(s[i]) and last_appear_index[ord(stack[-1]) - 97] > i:
                stack.pop()
            stack.append(s[i])
        return ''.join(stack)


__author__ = 'Wei Wen'

from caffe.proto import caffe_pb2

def add_conv_layer(net_msg,name,bottom,num_output,pad,kernel_size,stride,bias_term=True):
    conv_layer = net_msg.layer.add()
    conv_layer.name = name
    conv_layer.type = 'Convolution'
    conv_layer.bottom._values.append(bottom)
    conv_layer.top._values.append(conv_layer.name)
    # param info for weight and bias
    lr_param = caffe_pb2.ParamSpec()
    lr_param.lr_mult = 1
    conv_layer.param._values.append(lr_param)
    if bias_term:
        lr_param = caffe_pb2.ParamSpec()
        lr_param.lr_mult = 2
        conv_layer.param._values.append(lr_param)
    # conv parameters
    conv_layer.convolution_param.num_output = num_output
    conv_layer.convolution_param.pad._values.append(pad)
    conv_layer.convolution_param.kernel_size._values.append(kernel_size)
    conv_layer.convolution_param.stride._values.append(stride)
    conv_layer.convolution_param.weight_filler.type = 'msra'
    conv_layer.convolution_param.bias_term = bias_term
    if bias_term:
        conv_layer.convolution_param.bias_filler.type = 'constant'

def add_relu_layer(net_msg,name,bottom):
    relulayer = net_msg.layer.add()
    relulayer.name = name
    relulayer.type = 'ReLU'
    relulayer.bottom._values.append(bottom)
    relulayer.top._values.append(name)

def add_eltwise_add_layer(net_msg,name,bottom1,bottom2):
    eltlayer = net_msg.layer.add()
    eltlayer.name = name
    eltlayer.type = 'Eltwise'
    eltlayer.bottom._values.append(bottom1)
    eltlayer.bottom._values.append(bottom2)
    eltlayer.top._values.append(name)

def add_BN_layer(net_msg,name,bottom):
    # norm layer
    batchnormlayer = net_msg.layer.add()
    batchnormlayer.name = name+'_norm'
    batchnormlayer.type = 'BatchNorm'
    batchnormlayer.bottom._values.append(bottom)
    batchnormlayer.top._values.append(batchnormlayer.name)
    for i in range(0,3):
        lr_param = caffe_pb2.ParamSpec()
        lr_param.lr_mult = 0
        batchnormlayer.param._values.append(lr_param)
    # scale layer
    scalelayer = net_msg.layer.add()
    scalelayer.name = name+'_scale'
    scalelayer.type = 'Scale'
    scalelayer.bottom._values.append(batchnormlayer.name)
    scalelayer.top._values.append(name)

    lr_param = caffe_pb2.ParamSpec()
    lr_param.lr_mult = 1
    scalelayer.param._values.append(lr_param)
    lr_param = caffe_pb2.ParamSpec()
    lr_param.lr_mult = 2
    lr_param.decay_mult = 0
    scalelayer.param._values.append(lr_param)

    scalelayer.scale_param.bias_term = True
    scalelayer.scale_param.filler.type = 'msra'

def add_global_avg_pooling_layer(net_msg,name,bottom):
    glb_avg_pl_layer = net_msg.layer.add()
    glb_avg_pl_layer.name = name
    glb_avg_pl_layer.type = 'Pooling'
    glb_avg_pl_layer.bottom._values.append(bottom)
    glb_avg_pl_layer.top._values.append(name)
    glb_avg_pl_layer.pooling_param.pool = caffe_pb2.PoolingParameter.AVE
    glb_avg_pl_layer.pooling_param.global_pooling = True

def add_downsampling_layer(net_msg,name,bottom,stride):
    downsampling_layer = net_msg.layer.add()
    downsampling_layer.name = name
    downsampling_layer.type = 'Pooling'
    downsampling_layer.bottom._values.append(bottom)
    downsampling_layer.top._values.append(name)
    downsampling_layer.pooling_param.pool = caffe_pb2.PoolingParameter.MAX
    downsampling_layer.pooling_param.kernel_size = 1
    downsampling_layer.pooling_param.stride = stride

def add_ip_layer(net_msg,name,bottom,num):
    ip_layer = net_msg.layer.add()
    ip_layer.name = name
    ip_layer.type = 'InnerProduct'
    ip_layer.bottom._values.append(bottom)
    ip_layer.top._values.append(name)
    # param info for weight and bias
    lr_param = caffe_pb2.ParamSpec()
    lr_param.lr_mult = 1
    lr_param.decay_mult = 1
    ip_layer.param._values.append(lr_param)
    lr_param = caffe_pb2.ParamSpec()
    lr_param.lr_mult = 2
    lr_param.decay_mult = 0
    ip_layer.param._values.append(lr_param)
    # inner product parameters
    ip_layer.inner_product_param.num_output = num
    ip_layer.inner_product_param.weight_filler.type = 'msra'
    ip_layer.inner_product_param.bias_filler.type = 'constant'
    ip_layer.inner_product_param.bias_filler.value = 0.0

def add_accuracy_layer(net_msg,bottom):
    accuracy_layer = net_msg.layer.add()
    accuracy_layer.name = 'accuracy'
    accuracy_layer.type = 'Accuracy'
    accuracy_layer.bottom._values.append(bottom)
    accuracy_layer.bottom._values.append('label')
    accuracy_layer.top._values.append('accuracy')
    include_param = caffe_pb2.NetStateRule()
    include_param.phase = caffe_pb2.TEST
    accuracy_layer.include._values.append(include_param)

def add_loss_layer(net_msg,bottom):
    loss_layer = net_msg.layer.add()
    loss_layer.name = 'loss'
    loss_layer.type = 'SoftmaxWithLoss'
    loss_layer.bottom._values.append(bottom)
    loss_layer.bottom._values.append('label')
    loss_layer.top._values.append('loss')


"""Test with

curl localhost:5000/-/alive | python -m json.tool
curl localhost:5000/my-model/v1/prediction -d @examples/api_logging.json | python -m json.tool
"""

import logging

from porter.datascience import BaseModel
from porter.services import ModelApp, PredictionService
from porter.utils import JSONLogFormatter

class Model(BaseModel):
    def predict(self, X):
        return (X['foo'] % 3) * X['bar']

prediction_svc = PredictionService(
    model=Model(),
    name='my-model',
    api_version='v1',
    batch_prediction=True,
    log_api_calls=True)

app = ModelApp([prediction_svc])

if __name__ == '__main__':
    import logging
    stream_handler = logging.StreamHandler()
    formatter = JSONLogFormatter(
        'asctime', 'levelname', 'module', 'name', 'message',
        'request_id', 'request_data', 'response_data', 'service_class',
        'event')
    stream_handler.setFormatter(formatter)
    logger = logging.getLogger('porter')
    logger.setLevel('INFO')
    logger.addHandler(stream_handler)
    app.run()


import torch.nn as nn
import torch.nn.functional as F
from const import N, M, OUTPLANES

class PolicyNet(nn.Module):
    """
    This network is used in order to predict which move has the best potential to lead to a win
    given the same 'state' described in the Feature Extractor model.
    """

    def __init__(self, inplanes):
        super(PolicyNet, self).__init__()
        self.conv = nn.Conv2d(inplanes, 2, kernel_size=1)
        self.bn = nn.BatchNorm2d(2)
        self.logsoftmax = nn.LogSoftmax(dim=1)
        self.fc1 = nn.Linear(2*N*M, 512)
        self.fc2 = nn.Linear(512, OUTPLANES)

    def forward(self, x):
        """
        x : feature maps extracted from the state
        probas : a 1*N vector where N is the length of the sequence
                 Each value in this vector represent the likelihood
                 of next action
        """

        x = F.relu(self.bn(self.conv(x)))
        x = x.view(-1, 2*N*M)
        x = F.relu(self.fc1(x))
        x = self.fc2(x)
        probs = self.logsoftmax(x).exp()

        return probs


from argparse import ArgumentDefaultsHelpFormatter, ArgumentParser

from pytorch_lightning import Trainer, seed_everything
from pytorch_lightning.loggers import TensorBoardLogger

from data_module import (UMPDataModule, df_to_input_feat, df_to_input_id,
                         load_data)
from litmodule import UMPLitModule, UMPLitModuleMem

def get_name(args):
    return '-'.join(filter(None, [  # Remove empty string by filtering
        'x'.join(str(sz) for sz in args.szs),
        'x'.join(str(mha) for mha in args.mhas),
        f'n_mem{args.n_mem}',
        f'epch{args.max_epochs}',
        f'btch{args.batch_size}x{args.accumulate_grad_batches}',
        f'{args.optimizer}',
        f'drop{args.dropout}',
        f'schd{args.lr_scheduler}',
        f'loss{args.loss}',
        f'lr{args.lr}',
        f'wd{args.weight_decay}',
        f'swa{args.swa}',
        f'emb{args.emb_dim}',
    ])).replace(' ', '')

def get_litmodule_cls(args):
    if args.n_mem > 0:
        return UMPLitModuleMem
    return UMPLitModule

def get_litmodule(args):
    cls = get_litmodule_cls(args)
    return cls(args)

def submit(args, ckpts):

    litmodels = [
        get_litmodule_cls(args).load_from_checkpoint(ckpt, args=args).eval()
        for ckpt in ckpts
    ]

    import ubiquant
    env = ubiquant.make_env()   # initialize the environment

    for test_df, submit_df in env.iter_test():
        input_ids = df_to_input_id(test_df).unsqueeze(0)
        input_feats = df_to_input_feat(test_df).unsqueeze(0)

        with torch.no_grad():
            submit_df['target'] = torch.cat([
                litmodel.predict(input_ids, input_feats)
                for litmodel in litmodels
            ]).mean(dim=0)

        env.predict(submit_df)   # register your predictions

def test(args):
    seed_everything(args.seed)

    litmodel = get_litmodule_cls(args).load_from_checkpoint(args.checkpoint,
                                                            args=args)
    dm = UMPDataModule(args)

    Trainer.from_argparse_args(args).test(litmodel, datamodule=dm)

def train_single(args, seed):
    seed_everything(seed)

    litmodel = get_litmodule(args)
    dm = UMPDataModule(args)

    name = get_name(args)
    logger = TensorBoardLogger(save_dir='logs', name=name)

    trainer = Trainer.from_argparse_args(args,
                                         logger=logger,
                                         deterministic=True,
                                         precision=16)
    trainer.fit(litmodel, dm)

    best_ckpt = trainer.checkpoint_callback.best_model_path
    test_result = trainer.test(ckpt_path=best_ckpt,
                               datamodule=dm)

    return {
        'ckpt_path': best_ckpt,
        'test_pearson': test_result[0]['test_pearson']
    }

def train(args):
    return [
        train_single(args, seed)
        for seed in range(args.seed, args.seed + args.n_fold)
    ]

def parse_args(is_kaggle=False):
    parser = ArgumentParser(formatter_class=ArgumentDefaultsHelpFormatter)
    parser = Trainer.add_argparse_args(parser)

    parser.add_argument('--workers', type=int, default=2,
                        help='# of workers')
    parser.add_argument(
        '--input', default='../input/ubiquant-parquet/train_low_mem.parquet',
        help='path to train data')

    # Hyperparams
    parser.add_argument('--batch_size', type=int, default=8,
                        help='batch size')
    parser.add_argument('--lr', type=float, default=0.001,
                        help='learning rate')
    parser.add_argument('--weight_decay', type=float, default=1e-4,
                        help='weight decay rate')
    parser.add_argument('--seed', type=int, default=42,
                        help='random seed')
    parser.add_argument('--optimizer', default='adam',
                        choices=['adam', 'adamw'],
                        help='optimizer')
    parser.add_argument('--lr_scheduler', default=None,
                        choices=['plateau'],
                        help='learning rate scheduler')
    parser.add_argument('--loss', default='pcc', choices=['mse', 'pcc'],
                        help='loss function')
    parser.add_argument('--emb_dim', type=int, default=32,
                        help='investment embedding dimension')
    parser.add_argument('--n_fold', type=int, default=1,
                        help='Number of folds')
    parser.add_argument('--split_ratios', type=float, nargs='+',
                        default=[0.7, 0.15, 0.15],
                        help='train, val, and test set (optional) split ratio')
    parser.add_argument('--early_stop', action='store_true',
                        help='whether to early stop')
    parser.add_argument('--swa', action='store_true',
                        help='whether to perform Stochastic Weight Averaging')

    # Model structure
    parser.add_argument('--szs', type=int, nargs='+',
                        default=[512, 256, 128, 64],
                        help='sizes of each layer')
    parser.add_argument(
        '--mhas', type=int, nargs='+', default=[],
        help=('Insert MHA layer (BertLayer) at the i-th layer (start from 0). '
              'Every element should be 0 <= * < len(szs)'))
    parser.add_argument('--dropout', type=float, default=0.0,
                        help='dropout rate, set to 0.0 to disable')
    parser.add_argument('--n_mem', type=int, default=0,
                        help='# of memory tokens for mha, set to 0 to disable')

    # Test
    parser.add_argument('--test', action='store_true',
                        help='whether to test')

    # Checkpoint
    parser.add_argument('--checkpoint', help='path to checkpoints (for test)')

    # Handle kaggle platform
    args, unknown = parser.parse_known_args()

    if not is_kaggle:
        assert not unknown, f'unknown args: {unknown}'

    assert all(0 <= i < len(args.szs) for i in args.mhas)

    args.with_memory = args.n_mem > 0
    if args.with_memory:
        assert len(args.mhas) == 1, 'Currently support one mha with memory'
    return args

def run_local():
    args = parse_args()

    if args.test:
        test(args)
        return

    best_results = train(args)
    test_pearsons = [res['test_pearson'] for res in best_results]
    print(f'mean={sum(test_pearsons)/len(test_pearsons)}, {test_pearsons}')
    print(best_results)

def kaggle():
    args = parse_args(True)
    # On kaggle mode, we are using only the args with default value
    # To changle arguments, please hard code it below, e.g.:
    # args.loss = 'mse'
    # args.szs = [512, 128, 64, 64, 64]

    args.max_epochs = 20
    args.gpus = 1

    do_submit = False
    train_on_kaggle = False

    if train_on_kaggle:
        assert args.n_fold == 1, (
            'Otherwise it will meet out of memory problem. '
            'Probably memory leak problem on kaggle.'
        )
        best_results = train(args)
        best_ckpts = [ckpt for ckpt, _ in best_results]

        test_pearsons = [res['test_pearson'] for res in best_results]
        print(f'mean={sum(test_pearsons)/len(test_pearsons)}, {test_pearsons}')
    else:
        # TODO fill in the ckpt paths
        best_ckpts = []

    assert best_ckpts

    if do_submit:
        submit(args, best_ckpts)

if __name__ == '__main__':
    is_kaggle = False
    if is_kaggle:
        kaggle()
    else:
        run_local()


import numpy as np
import pandas as pd
from pathlib import Path
import faiss
from transformers import AutoModel, AutoTokenizer
import torch
import torch.nn as nn
from faiss.contrib.client_server import run_index_server, ClientIndex

### load all the stuff
def load_db(data_root, model, csv_fn):
    ftrs_root = data_root / 'features'

    db_feats = np.load(ftrs_root / model / 'results_2M' / 'embeds_test.npy')
    videoids = pd.read_csv(ftrs_root / model / 'results_2M' / 'ids_test.csv')
    df = pd.read_csv(data_root / 'metadata' / csv_fn)
    videoids['videoid'] = videoids['0'].str.split('/').str[1].str.split('.').str[0]
    df = df[df['videoid'].isin(videoids['videoid'])].set_index('videoid')
    videoids.set_index('videoid', inplace=True)
    videoids.index = videoids.index.astype(int)
    df.index = df.index.astype(int)

    videoids['name'] = df['name']

    return db_feats, df, videoids

def main():
    data_root = Path('/scratch/shared/beegfs/maxbain/datasets/ShutterVids')
    model = Path('CC-WebVid2M-4f-pt1f/0522_143949')
    csv_fn = 'results_2M_test.csv'
    ### set up the index
    d = 256
    nlist = 100
    k = 5

    server_query = True

    text_arch = 'distilbert-base-uncased'
    checkpoint_fp = '/users/maxbain/Libs/frozen-in-time/exps/models/CC-WebVid2M-4f-pt1f/0522_143949/checkpoint-epoch6_statedict.pth'
    queries = ['beautiful woman dancing', 'aerial mountain view', 'man running down the street']
    queries = [queries[0]]

    text_model = AutoModel.from_pretrained(text_arch)
    chkpt_state = torch.load(checkpoint_fp)
    tokenizer = AutoTokenizer.from_pretrained(text_arch)
    txt_proj = nn.Sequential(nn.ReLU(),
                             nn.Linear(text_model.config.hidden_size, d),
                             )
    txt_statedict = {}
    txtproj_statedict = {}
    for key, val in chkpt_state.items():
        if key.startswith('module.text_model.'):
            newkey = key[18:]
            txt_statedict[newkey] = val
        elif key.startswith('module.txt_proj.'):
            newkey = key[16:]
            txtproj_statedict[newkey] = val

    text_model.load_state_dict(txt_statedict)
    txt_proj.load_state_dict(txtproj_statedict)

    text_model = text_model.eval()

    query_tokens = tokenizer(queries, return_tensors='pt', padding=True, truncation=True)
    text_feats = text_model(query_tokens['input_ids'], attention_mask=query_tokens['attention_mask']).last_hidden_state[
                 :, 0, :]
    text_feats = txt_proj(text_feats).cpu().detach().numpy()
    db_feats, df, videoids = load_db(data_root, model, csv_fn)
    if server_query:
        machine_ports = [
            ('localhost', 12010),
        ]
        client_index = ClientIndex(machine_ports)
        print('index size:', client_index.ntotal)
        D, I = client_index.search(text_feats, 5)
        print(D, I)
        import pdb;
        pdb.set_trace()
    else:

        # quantizer = faiss.IndexFlatIP(d)
        # index = faiss.IndexIVFFlat(quantizer, d, nlist)

        index = faiss.index_factory(d, f"IVF{nlist},Flat", faiss.METRIC_INNER_PRODUCT)
        print(index.is_trained)

        # normalise
        faiss.normalize_L2(db_feats)
        faiss.normalize_L2(text_feats)

        # train
        print('training...')
        index.train(db_feats)
        print('... done')
        print(index.is_trained)
        index.add_with_ids(db_feats, df.index.values)  # add vec    tors to the index
        print(index.ntotal)

        D, I = index.search(text_feats, k)
        print(D, I)
        for idx, quer in enumerate(queries):
            topknn = I[idx]
            similarities = pd.Series(D[idx])
            similarities.index = topknn
            tdf = videoids.loc[topknn]
            tdf['sim_score'] = similarities
            # tdf.sort_values('sim_score', inplace=True, ascending=False)
            print(f"#### query: {quer} ####\n", tdf[['name', 'sim_score']])

main()


import numpy as np
import cv2

def get_text_size(text, font_size):
    font = cv2.FONT_HERSHEY_TRIPLEX
    text_size = cv2.getTextSize(text, font, font_size, 1)[0]
    return text_size

# Get position of text on image
def get_text_position(text, font_size, image_size):
    text_size = get_text_size(text, font_size)
    text_position = (image_size[1] // 2 - text_size[0] // 2,
                     image_size[0] // 2 + text_size[1] // 2)
    return text_position

def watermark(
    image,
    text,
    font_size,
    color=(255, 255, 255),
    thickness=1
):
    font_size = int(font_size)
    thickness = int(thickness)

    # Make watermark
    watermark = np.zeros((image.shape[0], image.shape[1], 3), np.uint8)

    # Get text position
    position = get_text_position(text, font_size, image.shape)

    # Draw text
    cv2.putText(watermark, text, position, cv2.FONT_HERSHEY_TRIPLEX,
                font_size, color, thickness)

    # Merge watermark
    merge_img = cv2.addWeighted(watermark, 0.5, image, 1.0, 0)

    return merge_img

if __name__ == "__main__":
    test_image = cv2.imread('assets/book.jpg')
    test_image_arr = np.asarray(test_image, np.uint8)
    watermark_image = watermark(
        test_image_arr, 'Watermarked', 1, (255, 255, 255), 3)

    cv2.imwrite('assets/book_watermark.jpg', watermark_image)


import tkinter as tk

# Créer une fenêtre
window = tk.Tk()

# Créer un widget Canvas
canvas = tk.Canvas(window, width=500, height=500)
canvas.pack()

# Dessiner un cercle
circle = canvas.create_oval(50, 50, 100, 100, fill="blue")

# Fonction pour mettre à jour le cercle
def update_circle():
    canvas.move(circle, 10, 0)
    window.after(50, update_circle)

# Mettre à jour le cercle
update_circle()

# Afficher la fenêtre
window.mainloop()


import logging

import numpy as np

from .convert import GRIB_TO_CF, GRIB_TO_XARRAY_PL, GRIB_TO_XARRAY_SFC

LOG = logging.getLogger(__name__)

def save_output_xarray(
    *,
    output,
    target_variables,
    write,
    all_fields,
    ordering,
    lead_time,
    hour_steps,
    lagged,
):
    LOG.info("Converting output xarray to GRIB and saving")

    output["total_precipitation_6hr"] = output.data_vars[
        "total_precipitation_6hr"
    ].cumsum(dim="time")

    all_fields = all_fields.order_by(
        valid_datetime="descending",
        param_level=ordering,
        remapping={"param_level": "{param}{levelist}"},
    )

    for time in range(lead_time // hour_steps):
        for fs in all_fields[: len(all_fields) // len(lagged)]:
            param, level = fs["shortName"], fs["level"]

            if level != 0:
                param = GRIB_TO_XARRAY_PL.get(param, param)
                if param not in target_variables:
                    continue
                values = output.isel(time=time).sel(level=level).data_vars[param].values
            else:
                param = GRIB_TO_CF.get(param, param)
                param = GRIB_TO_XARRAY_SFC.get(param, param)
                if param not in target_variables:
                    continue
                values = output.isel(time=time).data_vars[param].values

            # We want to field north=>south

            values = np.flipud(values.reshape(fs.shape))

            write(
                values,
                template=fs,
                step=(time + 1) * hour_steps,
            )


from django.db.models.signals import post_save
from django.contrib.auth.models import User
from django.contrib.auth.models import Group
from .models import Customer

def customer_profile(sender, instance, created, **kwargs):
	if created:
		#after registration the user will be added to the customer group
		#and will get a customer profile
		group = Group.objects.get(name='customer')
		instance.groups.add(group)
		print('DONE TILL GROUPING')
		Customer.objects.create(
			user = instance,
			name = instance.username,
			)

		print('Customer created')
	else:
		print('NO SIGNALS BEEING ACTIVATED')
		print(sender, instance, created)

post_save.connect(customer_profile, sender=User)


from django.core.paginator import Paginator
from django.shortcuts import render, get_object_or_404, redirect
from django.contrib.auth.decorators import login_required
from survey.models import Test, Question, Choice, User, Color

def get_page(tests, request, count=3):
    """Пагинатор."""
    paginator = Paginator(tests, count)
    page_number = request.GET.get('page')
    return paginator.get_page(page_number)

@login_required
def index(request):
    """Главная страница."""
    user = get_object_or_404(User, id=request.user.id)
    test_list = Test.objects.all()
    page_obj = get_page(test_list, request)
    context = {
        'page_obj': page_obj,
        'user': user,
    }
    return render(request, 'survey/index.html', context)

@login_required
def start_survey(request, slug):
    """Функция тестирования."""
    user = get_object_or_404(User, id=request.user.id)
    test_object = get_object_or_404(Test, slug=slug)
    questions = Question.objects.filter(test=test_object)
    context = {
        'questions': questions,
        'user': user,
    }
    if request.method == 'POST':
        score, correct, wrong = 0, 0, 0
        for q in questions:
            if q.correct_answer == request.POST.get(q.text):
                score += 5
                correct += 1
                user.currency += 5
                user.save()
            else:
                wrong += 1
        context['score'] = score
        context['correct'] = correct
        context['wrong'] = wrong
        user.count_test += 1
        user.save()
        return render(request, 'survey/result.html', context)
    else:
        return render(request, 'survey/questions.html', context)

@login_required
def get_user_list(request):
    """Список пользователей."""
    users = User.objects.all()
    page_obj = get_page(users, request, count=5)
    context = {
        'page_obj': page_obj,
    }
    return render(request, 'survey/all_users.html', context)

@login_required
def profile(request):
    """Профиль, покупка цветов. Не реализовано."""
    user = get_object_or_404(User, id=request.user.id)
    user_color_active = user.color.get(is_active=True)
    colors = Color.objects.all()
    context = {
        'colors': colors,
        'user_color_active': user_color_active,
    }
    if request.method == 'POST':
        balance = user.currency
        cost = Color.objects.get(name=list(request.POST.values())[-1]).price
        user.currency -= cost
        print(balance)
        user.color.is_active = True
        user.color.is_available = True
        user.save()
        return redirect('survey:get_user_list')
    return render(request, 'survey/profile.html', context)


from sys import stdin
def suma (a,t,i):
    if t == 23 and i > len(a)-1:
        return True
    elif i>=len(a):
        return False
    else:
        return suma(a,t-int(a[i]),i+1) or suma(a,t+int(a[i]),i+1) or suma(a,t*int(a[i]),i+1)

def main():
    a = stdin.readline().split()
    res = suma(a,int(a[0]),1)
    if res == True:
        print("Possible")
    else:
        print("Impossible")
main()


cars = ["BMW", "Mercedes", "Ford"]

for car in cars:
    print("Car:", car)

for time in range(2):
    print("How are you?\nI'm fine")

# print a letter 50 times

for letter in range(50):
    print("x", end="$")

sports = ["\nRugby", "Cricket", "Tennis", "Afl"]

for sport in sports:
    print(sport)
print(sports[2])

word = input("Enter a word: ")
for letter in word:
    if letter == "n":
        print("The letter n was found in your word")

# n, i and uppercase detector
word = input("\nEnter a word: ")
for letter in word:
    if letter == "n":
        print("The letter n was found in your word")
    if letter == "i":
        print("The letter i was found in your word")
    if letter == letter.upper():
        print("An upper case letter was detected")

# For each character in the word it will check each of the if statements because of the for function.


from cv2 import cv2
import os
import skimage.measure
import numpy as np
import pandas as pd
import torch

#list video's for analysis
os.chdir('.\\vids\\')
vids = os.listdir()
#get first two numbers of video name and sort in right ordering 1 to 42
vids = list(map(lambda v: float(v[0:2]) , vids ))
vids.sort()
#add .mp4 to filename for indexing
vids = list(map(lambda v: str(v).split('.')[0] + '.mp4' , vids ))
print(vids) #works

#calculate visual entropy and optical flow variance
# https://docs.opencv.org/3.4/d4/dee/tutorial_optical_flow.html

#jpeg compression size seems to be related to visual complexity
#Dense optical flow, returns matrix of magnitude and direction of motion in video

#add preprocessing (resize images to the same size and blur them to reduce noise (e.g., lighting))
#https://towardsdatascience.com/image-pre-processing-c1aec0be3edf

#image characteristics such as size and sharpness could affect the measurement, maybe we should correct for that
def preprocessing(img):
    #resize frame for faster processing
    scale_percent = 50 # percent of original size
    width = int(img.shape[1] * scale_percent / 100)
    height = int(img.shape[0] * scale_percent / 100)
    dim = (width, height)
    preprocessed_img = cv2.resize(img, dim, interpolation = cv2.INTER_AREA)
    #blur frames to reduce noise? Alexia said no

    return(preprocessed_img)

#create list of dicts for all videos
output_list = []

for vid in vids:
    cap = cv2.VideoCapture(vid)
    ret, frame1 = cap.read()
    prvs = cv2.cvtColor(frame1,cv2.COLOR_BGR2GRAY)
    hsv = np.zeros_like(frame1)
    hsv[...,1] = 255
    print('Processing video: {}'.format(vid))

    entropy_list = []
    avg_motion_list = []
    mag_entropy_list = []
    ang_var_list = []
    ang_entropy_list = []

    while(1):
        ret, frame2 = cap.read()
        #break from loop when there are no more frames to process
        if ret == False:
            #calc entropy for last frame
            entropy = skimage.measure.shannon_entropy(prvs)
            entropy_list.append(entropy)
            break
        next = cv2.cvtColor(frame2,cv2.COLOR_BGR2GRAY)
        #calculate dense optical flow
        flow = cv2.calcOpticalFlowFarneback(prvs,next, None, 0.5, 3, 25, 3, 5, 1.2, 0)
        mag, ang = cv2.cartToPolar(flow[...,0], flow[...,1])
        hsv[...,0] = ang*180/np.pi/2
        hsv[...,2] = cv2.normalize(mag,None,0,255,cv2.NORM_MINMAX)
        bgr = cv2.cvtColor(hsv,cv2.COLOR_HSV2BGR)

        #entropy
        entropy = skimage.measure.shannon_entropy(prvs)
        #average magnitude of motion
        avg_motion = mag.mean()
        #angle of motion variance
        ang_var = ang.var()
        #angle of motion entropy
        ang_entropy = skimage.measure.shannon_entropy(ang)
        #magnitude of motion entropy
        mag_entropy = skimage.measure.shannon_entropy(mag)

        #optional: show output
        #cv2.imshow('Original frame',prvs)
        #cv2.imshow('Dense Optical Flow',bgr)
        #k = cv2.waitKey(30) & 0xff
        #if k == 27:
        #    break

        #update frame
        prvs = next
        #append lists
        entropy_list.append(entropy)
        avg_motion_list.append(avg_motion)
        ang_var_list.append(ang_var)
        ang_entropy_list.append(ang_entropy)
        mag_entropy_list.append(mag_entropy)

    #save lists to dict for current video and append dict to output_list (JSON/list of dicts)
    curr_vid = {'video': vid,
                'fps': cap.get(cv2.CAP_PROP_FPS),
                'entropy': entropy_list,
                'avg_motion':avg_motion_list,
                'ang_var': ang_var_list,
                'ang_entropy': ang_entropy_list,
                'mag_entropy': mag_entropy_list
                }
    output_list.append(curr_vid)

#plot
import matplotlib.pyplot as plt
plt.plot(avg_motion_list)
plt.ylabel('Average Motion Magnitude')
plt.show()

plt.plot(ang_entropy_list)
plt.ylabel('Motion Angle Entropy')
plt.show()

plt.plot(entropy_list)
plt.ylabel('Static visual entropy per frame')
plt.show()

plt.plot(mag_entropy_list)
plt.ylabel('Motion Magnitude Entropy')
plt.show()

#possibly do some smoothing based on fps/preprocessing

# turn output into a pickle
import pickle

os.getcwd()
os.chdir('..')
os.getcwd()

try:
    output = open('visual_complexity_data', 'wb')
    pickle.dump(output_list, output)
    output.close()

except:
    print("Something went wrong")

plt.plot(output_list[15]['avg_motion'])
plt.ylabel('Average Motion Magnitude')
plt.show()

plt.plot(output_list[15]['ang_entropy'])
plt.ylabel('Average Motion Angle Entropy')
plt.show()


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# ---
# jupyter:
#   jupytext:
#     text_representation:
#       extension: .py
#       format_name: light
#       format_version: '1.4'
#       jupytext_version: 1.1.4
#   kernelspec:
#     display_name: Python 3
#     language: python
#     name: python3
# ---

# # S_UnconditionalEstimateMLFP [<img src="https://www.arpm.co/lab/icons/icon_permalink.png" width=30 height=30 style="display: inline;">](https://www.arpm.co/lab/redirect.php?code=S_UnconditionalEstimateMLFP&codeLang=Python)
# For details, see [here](https://www.arpm.co/lab/redirect.php?permalink=ex-log-like-estim-mfp).

# ## Prepare the environment

# +
import os
import os.path as path
import sys

sys.path.append(path.abspath('../../functions-legacy'))
from collections import namedtuple

import numpy as np
from numpy import arange, sort, where, round, log, exp, sqrt, r_
from numpy import sum as npsum, min as npmin, max as npmax

from scipy.stats import pareto
from scipy.io import loadmat

import matplotlib.pyplot as plt
from matplotlib.pyplot import figure, plot, bar, legend, xlim, title

np.seterr(divide='ignore')
plt.style.use('seaborn')

from CONFIG import GLOBAL_DB, TEMPORARY_DB
from ARPM_utils import save_plot
from HistogramFP import HistogramFP
from EffectiveScenarios import EffectiveScenarios
from MaxLikelihoodFPLocDispT import MaxLikelihoodFPLocDispT
from FitGenParetoMLFP import FitGenParetoMLFP
from HFPquantile import HFPquantile
from QuantileGenParetoMLFP import QuantileGenParetoMLFP
# -

# ## Upload database

# +
try:
    db = loadmat(os.path.join(GLOBAL_DB, 'db_MomStratPL'), squeeze_me=True)
except FileNotFoundError:
    db = loadmat(os.path.join(TEMPORARY_DB, 'db_MomStratPL'), squeeze_me=True)

dailypnl = db['dailypnl']
dates = db['dates']
# -

# ## Select data and compute autocorrelations

# +
y = dailypnl.reshape(1,-1)  # select observations
t_ = len(dates)
date = dates

lam = log(2) / 180
p = exp(-lam *arange(y.shape[1],0,-1)).reshape(1,-1)
p = p /npsum(p)  # FP-profile: exponential decay 6 months
# -

# ## Estimate unconditional MaxLikelihoodLFP-mean and covariance

# +
nu = 4  # degrees of freedom
tolerance = 10 ** -7  # Set lower tolerance for higher precision

mu_MLFP, sigma2_MLFP,_ = MaxLikelihoodFPLocDispT(y, p, nu, tolerance, 1)
# -

# ## Estimate unconditional MLFP (EVT) quantile

# +
p_bar = 0.1  # probability threshold
p_quant = r_[arange(10**-4,p_bar+10**-4,10**-4), arange(p_bar+0.001,1.001,0.001)].reshape(1,-1) # quantile probability levels
q_HFP = HFPquantile(y, p_quant, p)
y_bar = q_HFP[p_quant == p_bar]  # threshold
# data below the threshold
l_1 = where(y[0] < y_bar)[0]
l_2 = where(p_quant[0] <= p_bar)[0]
y_ex = y_bar - y[[0],l_1]  # dataset of the conditional excess distribution

csi_MLFP, sigma_MLFP = FitGenParetoMLFP(y_ex, p[0,l_1])  # Maximum Likelihood optimization with Generalized Pareto Distribution
f_MLFP = pareto.pdf(sort(y_ex), csi_MLFP, sigma_MLFP, 0)  # estimated pdf

q_MLFP, *_ = QuantileGenParetoMLFP(y_bar, p_bar, csi_MLFP, sigma_MLFP, p_quant[0,l_2])  # MLFP-quantile

q_bt = q_HFP[0,l_2]  # historical quantile below the threshold
# -

# ## Generate figures showing the unconditional MLFP-mean and standard deviation and the estimated unconditional quantile function

# +
typ = namedtuple('type','Entropy')
typ.Entropy = 'Exp'
ens = EffectiveScenarios(p, typ)
option = namedtuple('option', 'n_bins')

option.n_bins = round(30*log(ens))
hgram, x_hgram = HistogramFP(y, p, option)

g = figure()
# unconditional pdf with mean and dispersion superimposed
ax = plt.subplot2grid((6,1), (0,0), rowspan=3)
b = bar(x_hgram[:-1], hgram[0], width=x_hgram[1]-x_hgram[0],facecolor=[.7, .7, .7], edgecolor=[.3, .3, .3])
plt.axis([npmin(x_hgram), npmax(x_hgram), 0, npmax(hgram) + (npmax(hgram) / 20)])
title('P&L unconditional pdf')
stddev_plot = plot(r_[mu_MLFP - sqrt(sigma2_MLFP), mu_MLFP + sqrt(sigma2_MLFP)],[0, 0], color= [.3, .3, .9], lw=7)
mean_plot = plot(r_[mu_MLFP, mu_MLFP], [0, 0.4*10**-7], color= [.9, .3, 0], lw=7)
legend(['Unconditional MLFP-dispersion','Unconditional MLFP-mean'])

# unconditional quantile
y_min = min([npmin(q_bt), npmin(q_MLFP)])
y_max = max([npmax(q_bt), npmax(q_MLFP)])
ax = plt.subplot2grid((6,1), (3,0), rowspan=2)
xlim([0, npmax(p_quant[0,l_2])])
Q_bt = plot(p_quant[0,l_2], q_bt, color= [.3, .3, .9], lw=2)
Q_MLFP = plot(p_quant[0,l_2], q_MLFP, color= [.9, .3, 0], lw=2)
plt.axis([-10 ** -6, p_bar, y_min - .05*(y_max - y_min), y_max + .05*(y_max - y_min)])
title('Unconditional MLFP-quantile approximation')
legend(['Unconditional quantile','MLFP-quantile approximation'])
plt.tight_layout();
# save_plot(ax=plt.gca(), extension='png', scriptname=os.path.basename('.')[:-3], count=plt.get_fignums()[-1])