#Import's
import random
#Variáveis

    #Classes
guerreiro = [
        #Nome(0)               Vida(1)
        'Guerreiro',            50,
        #Ataque básico(2)      dano(3)
        'Corte de espada',      10,
        #Ataque especial(4)    dano(5)
        'Lamina ardente',       20
        ]
arqueiro = [
        #Nome(0)               Vida(1)
        'Arqueiro',             50,
        #Ataque básico(2)      dano(3)
        'Flecha veloz',         10,
        #Ataque especial(4)    dano(5)
        'Three shot',           20
    ]
mago = [
        #Nome(0)               Vida(1)
        'Mago',                 50,
        #Ataque básico(2)      Dano(3)
        'Bola de fogo',         10,
        #Ataque especial(4)    Dano(5)
        'Maldição',             20
    ]

oponente = [
        #Nome(0)               Vida(1)
        'Sr.Maldade',           100,
        #Ataque básico(2)      Dano(3)
        'Pedrada',              10,
        #Ataque especial(4)    Dano(5)
        'Lamina de sangue',     20
]
#Funções
def escolher_classe():
    try:
        print("""
            1. Guerreiro
            2. Arqueiro
            3. Mago
        """)
        classe = int(input('Escolha sua classe de acordo ao número.'))
    except ValueError:
	    print("Somente números sao aceitos. Tente novamente.")
    if classe != int():
        print("Positivo")
    if classe == 1 :
        print("Sua classe é guerreiro")
    elif classe == 2:
        print("Sua classe é arqueiro")
    elif classe == 3:
        print("Sua classe é mago")

def batalha():
    oponente = random.randint(1,20)
    player = random.randint(1,20)
    print(oponente)
    print(player)
    if oponente > player:
        print("Você tomou dano!")
    elif player > oponente:
        print("Causou dano!")
    else:
        print("Dados iguiais! Relancando dados...")
        batalha()

#Executando o programa
escolher_classe()


__authors__ = ["T. Vincent"]
__license__ = "MIT"
__date__ = "06/03/2018"

from .. import qt

class BoxLayoutDockWidget(qt.QDockWidget):
    """QDockWidget adjusting its child widget QBoxLayout direction.

    The child widget layout direction is set according to dock widget area.
    The child widget MUST use a QBoxLayout

    :param parent: See :class:`QDockWidget`
    :param flags: See :class:`QDockWidget`
    """

    def __init__(self, parent=None, flags=qt.Qt.Widget):
        super(BoxLayoutDockWidget, self).__init__(parent, flags)
        self._currentArea = qt.Qt.NoDockWidgetArea
        self.dockLocationChanged.connect(self._dockLocationChanged)
        self.topLevelChanged.connect(self._topLevelChanged)

    def setWidget(self, widget):
        """Set the widget of this QDockWidget

        See :meth:`QDockWidget.setWidget`
        """
        super(BoxLayoutDockWidget, self).setWidget(widget)
        # Update widget's layout direction
        self._dockLocationChanged(self._currentArea)

    def _dockLocationChanged(self, area):
        self._currentArea = area

        widget = self.widget()
        if widget is not None:
            layout = widget.layout()
            if isinstance(layout, qt.QBoxLayout):
                if area in (qt.Qt.LeftDockWidgetArea, qt.Qt.RightDockWidgetArea):
                    direction = qt.QBoxLayout.TopToBottom
                else:
                    direction = qt.QBoxLayout.LeftToRight
                layout.setDirection(direction)
                self.resize(widget.minimumSize())
                self.adjustSize()

    def _topLevelChanged(self, topLevel):
        widget = self.widget()
        if widget is not None and topLevel:
            layout = widget.layout()
            if isinstance(layout, qt.QBoxLayout):
                layout.setDirection(qt.QBoxLayout.LeftToRight)
                self.resize(widget.minimumSize())
                self.adjustSize()

    def showEvent(self, event):
        """Make sure this dock widget is raised when it is shown.

        This is useful for tabbed dock widgets.
        """
        self.raise_()


from typing import List

class Solution:
    def calculate(self, nums, k, max_len, s, nums_len):
        if nums[s:] == []:
            print("max_len=",max_len)
            return max_len
        else:
            i = 0
            temp = k
            ans = []
            temp_nums = nums[s:]
            print("nums=", temp_nums)
            while i != len(temp_nums):
                if temp == 0 and temp_nums[i] == 0:
                    break
                else:
                    print("*=", temp_nums[i])
                    if temp_nums[i] == 1:
                        ans.append(temp_nums[i])
                    elif temp_nums[i] == 0:
                        temp = temp - 1
                        ans.append(1)
                i += 1
            print("###########################")
            max_len = max(max_len, len(ans))
            print("max=",max_len)
            s = s + 1
            print("s=",s)
            self.calculate(nums, k, max_len, s, nums_len)

    def longestOnes(self, nums: List[int], k: int) -> int:
        max_len = 0
        max_len = self.calculate(nums, k, max_len, 0, len(nums))
        # print(max_len)

obj = Solution()
obj.longestOnes([1,1,1,0,0,0,1,1,1,1,0],2)
obj.longestOnes([0,0,1,1,0,0,1,1,1,0,1,1,0,0,0,1,1,1,1],3)


from django.urls import path
from user import views

urlpatterns = [

    path('fun',views.fun),
    path('fun1',views.fun1),
    path('u',views.us, name='uuu'),
    path('user',views.user, name='aaaa'),
]


# Python Number Guessing Game

import random

game_over = False  # To check if out of guesses.
guesses = 0  # Set value for guesses

def play_again():
    """Function to reset game"""
    global game_over
    if again == 'y':
        game_over = False

def check_num():
    """Function to check if guess is correct, if not tell high or low."""
    global guesses
    global game_over
    if current_guess > 100 or current_guess < 1:
        print("You number is not in range.")
    elif current_guess == secret_number:
        print("You are correct!")
        game_over = True
    elif current_guess < secret_number:
        print("That is too low.")
    elif current_guess > secret_number:
        print("That is too high.")

while not game_over:
    # Pick random number between 1 - 100 for player to guess.
    secret_number = random.randint(1, 100)

    # Ask if easy or hard mode, set guesses hard = 5, easy = 10.
    mode = input("Do you wish to play on Easy 'e' or Hard 'h' mode?: ")
    if mode == "e":
        guesses = 10
    elif mode == "h":
        guesses = 5

    # Ask player to guess a number
    current_guess = int(input("What number do you guess?: "))

    while guesses > 0:
        check_num()
        guesses -= 1
        if game_over:
            again = input("Do you wish to play again?: ")
            play_again()
            break
        # Tell number of remaining guesses and ask for new guess.
        current_guess = int(input(f"You have {guesses} guesses remaining. Pick another number.: "))


# Input: s and t : strings
# Output: bool

# Input: s = "anagram", t = "nagaram"
# Output: true
# QED
def is_anagram(s: str, t: str) -> bool:
    return sorted(s) == sorted(t)

# Input: s and t: str
# Output: true or false: bool

# We'll frequency count
# Loop through strings s and t, then store the chars
# and freqs for s in s_dict. do the same for t in the same loop
#  Loop through one of the maps and check if the value at that key
#  corresponds with the value at that key in the other map
# If there's a mismatch, return false early
# Once loop ends return true
def is_anagram_2(s: str, t: str) -> bool:
    if len(s) != len(t):
        return False

    s_map = {}
    t_map = {}

    for idx in range(len(s)):
        s_char = s[idx]
        t_char = t[idx]

        s_map[s_char] = s_map.get(s_char, 0) + 1
        t_map[t_char] = t_map.get(t_char, 0) + 1

    for k, v in s_map:
        if v != t_map.get(k):
            return False
    return True

# Longest substring without repeating characters
# Given a string s, find the length of the longest substring without repeating characters.

# Sample input: "abcabcbb"
# Expected output: 3

# We need a count and a map to store characters
# Double loop through the string
# if we have not seen a character in our current iteration (if map value is 0)
# - increase the freq of the char in the map
# - update max
# - update max_count if it is longer
# else
# - add item to map
# - break inner loop
def length_of_longest_substring_naive(s: str) -> int:
    max_count = 0
    for start_idx in range(len(s)):
        char_map = {}
        curr_count = 0
        for end_idx in range(start_idx, len(s)):
            curr_char = s[end_idx]
            curr_char_count = char_map.get(curr_char, 0)
            if curr_char_count != 0:
                break
            else:
                char_map[curr_char] = 1
                curr_count = curr_count + 1
                max_count = max(max_count, curr_count)

    return max_count

# Loop through string with a dynamic sliding window
# If char exists in map
# - Move window start forward until no duplicates exist in the window
# - reduce the curr window count
# Else
# - Add the char to map
# - update the window count
# - update the max count

# Sample input: "abcabcbb"
# Expected output:3
def length_of_longest_substring_optimised(s: str) -> int:
    window_start = 0
    curr_count = 0
    max_count = 0
    s_map = {}

    for window_end in range(len(s)):
        curr_count = curr_count + 1
        curr_char = s[window_end]
        char_frequency = s_map.get(curr_char, 0) + 1
        s_map[curr_char] = char_frequency

        while char_frequency > 1:
            char_frequency = char_frequency - 1
            s_map[curr_char] = char_frequency
            window_start = window_start + 1
            curr_count = curr_count - 1
        max_count = max(max_count, curr_count)

    return max_count


import os.path
import unittest
from pathlib import Path

from sflkit.analysis.analysis_type import AnalysisType
from sflkit.analysis.spectra import Spectrum
from sflkit.analysis.suggestion import Location

from tests4py import framework
from tests4py.constants import DEFAULT_WORK_DIR
from utils import BaseTest

class TestSFL(BaseTest):
    @unittest.skip
    def test_middle(self):
        project_name = "middle"
        bug_id = 2
        report = framework.default.tests4py_checkout(project_name, bug_id)
        if report.raised:
            raise report.raised
        src = Path(report.location)
        dst = DEFAULT_WORK_DIR / "sfl"
        report = framework.sfl.tests4py_sfl_instrument(src, dst)
        if report.raised:
            raise report.raised

        dst_src = dst / "src"
        dst_src_middle = dst_src / "middle"
        dst_src_middle___init___py = dst_src_middle / "__init__.py"
        dst_tests = dst / "tests"
        dst_tests_test_middle_py = dst_tests / "test_middle.py"
        dst_gitignore = dst / ".gitignore"
        dst_license = dst / "LICENSE"
        dst_readme_md = dst / "README.md"
        dst_setup_cfg = dst / "setup.cfg"
        dst_setup_py = dst / "setup.py"

        src_src = src / "src"
        src_src_middle = src_src / "middle"
        src_src_middle___init___py = src_src_middle / "__init__.py"
        src_tests = src / "tests"
        src_tests_test_middle_py = src_tests / "test_middle.py"
        src_gitignore = src / ".gitignore"
        src_license = src / "LICENSE"
        src_readme_md = src / "README.md"
        src_setup_cfg = src / "setup.cfg"
        src_setup_py = src / "setup.py"

        exist_files = [
            dst_src_middle___init___py,
            dst_tests_test_middle_py,
            dst_gitignore,
            dst_license,
            dst_readme_md,
            dst_setup_cfg,
            dst_setup_py,
        ]
        exist_dirs = [dst_src, dst_src_middle, dst_tests]

        for d in exist_dirs:
            self.assertTrue(d.exists())
            self.assertTrue(d.is_dir())

        for f in exist_files:
            self.assertTrue(f.exists())
            self.assertTrue(f.is_file())

        for d, s in [
            (dst_tests_test_middle_py, src_tests_test_middle_py),
            (dst_gitignore, src_gitignore),
            (dst_license, src_license),
            (dst_readme_md, src_readme_md),
            (dst_setup_cfg, src_setup_cfg),
            (dst_setup_py, src_setup_py),
        ]:
            with open(d, "r") as fp:
                d_content = fp.read()
            with open(s, "r") as fp:
                s_content = fp.read()
            self.assertEqual(s_content, d_content, f"{d} has other content then {s}")

        for d, s in [
            (dst_src_middle___init___py, src_src_middle___init___py),
        ]:
            with open(d, "r") as fp:
                d_content = fp.read()
            with open(s, "r") as fp:
                s_content = fp.read()
            self.assertNotEqual(
                s_content, d_content, f"{d} has the same content then {s}"
            )

        report = framework.sfl.tests4py_sfl_events(dst)
        if report.raised:
            raise report.raised

        report = framework.sfl.tests4py_sfl_analyze(dst, src, predicates="line")
        if report.raised:
            raise report.raised

        suggestions = report.analyzer.get_sorted_suggestions(
            base_dir=src,
            type_=AnalysisType.LINE,
            metric=Spectrum.Ochiai,
        )
        self.assertAlmostEqual(
            0.7071067811865475, suggestions[0].suspiciousness, delta=0.0000001
        )
        self.assertEqual(1, len(suggestions[0].lines))
        self.assertIn(
            Location(os.path.join("src", "middle", "__init__.py"), 6),
            suggestions[0].lines,
        )


# Author:Zhang Yuan
from MyPackage import *
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.patches as patches
import seaborn as sns
import statsmodels.api as sm
from scipy import stats

# ------------------------------------------------------------
__mypath__ = MyPath.MyClass_Path("")  # 路径类
mylogging = MyDefault.MyClass_Default_Logging(activate=False)  # 日志记录类，需要放在上面才行
myfile = MyFile.MyClass_File()  # 文件操作类
myword = MyFile.MyClass_Word()  # word生成类
myexcel = MyFile.MyClass_Excel()  # excel生成类
myini = MyFile.MyClass_INI()  # ini文件操作类
mytime = MyTime.MyClass_Time()  # 时间类
myparallel = MyTools.MyClass_ParallelCal()  # 并行运算类
myplt = MyPlot.MyClass_Plot()  # 直接绘图类(单个图窗)
mypltpro = MyPlot.MyClass_PlotPro()  # Plot高级图系列
myfig = MyPlot.MyClass_Figure(AddFigure=False)  # 对象式绘图类(可多个图窗)
myfigpro = MyPlot.MyClass_FigurePro(AddFigure=False)  # Figure高级图系列
myplthtml = MyPlot.MyClass_PlotHTML()  # 画可以交互的html格式的图
mypltly = MyPlot.MyClass_Plotly()  # plotly画图相关
mynp = MyArray.MyClass_NumPy()  # 多维数组类(整合Numpy)
mypd = MyArray.MyClass_Pandas()  # 矩阵数组类(整合Pandas)
mypdpro = MyArray.MyClass_PandasPro()  # 高级矩阵数组类
myDA = MyDataAnalysis.MyClass_DataAnalysis()  # 数据分析类
myDefault = MyDefault.MyClass_Default_Matplotlib()  # 画图恢复默认设置类
# myMql = MyMql.MyClass_MqlBackups() # Mql备份类
# myBaidu = MyWebCrawler.MyClass_BaiduPan() # Baidu网盘交互类
# myImage = MyImage.MyClass_ImageProcess()  # 图片处理类
myBT = MyBackTest.MyClass_BackTestEvent()  # 事件驱动型回测类
myBTV = MyBackTest.MyClass_BackTestVector()  # 向量型回测类
myML = MyMachineLearning.MyClass_MachineLearning()  # 机器学习综合类
mySQL = MyDataBase.MyClass_MySQL(connect=False)  # MySQL类
mySQLAPP = MyDataBase.MyClass_SQL_APPIntegration()  # 数据库应用整合
myWebQD = MyWebCrawler.MyClass_QuotesDownload(tushare=False)  # 金融行情下载类
myWebR = MyWebCrawler.MyClass_Requests()  # Requests爬虫类
myWebS = MyWebCrawler.MyClass_Selenium(openChrome=False)  # Selenium模拟浏览器类
myWebAPP = MyWebCrawler.MyClass_Web_APPIntegration()  # 爬虫整合应用类
myEmail = MyWebCrawler.MyClass_Email()  # 邮箱交互类
myReportA = MyQuant.MyClass_ReportAnalysis()  # 研报分析类
myFactorD = MyQuant.MyClass_Factor_Detection()  # 因子检测类
myKeras = MyDeepLearning.MyClass_tfKeras()  # tfKeras综合类
myTensor = MyDeepLearning.MyClass_TensorFlow()  # Tensorflow综合类
myMT5 = MyMql.MyClass_ConnectMT5(connect=False)  # Python链接MetaTrader5客户端类
myMT5Pro = MyMql.MyClass_ConnectMT5Pro(connect=False)  # Python链接MT5高级类
myMT5Indi = MyMql.MyClass_MT5Indicator()  # MT5指标Python版
myMT5Report = MyMT5Report.MyClass_StratTestReport(AddFigure=False)  # MT5策略报告类
myMT5Analy = MyMT5Analysis.MyClass_ForwardAnalysis()  # MT5分析类
myMT5Lots_Fix = MyMql.MyClass_Lots_FixedLever(connect=False)  # 固定杠杆仓位类
myMT5Lots_Dy = MyMql.MyClass_Lots_DyLever(connect=False)  # 浮动杠杆仓位类
myMT5run = MyMql.MyClass_RunningMT5()  # Python运行MT5
myMT5code = MyMql.MyClass_CodeMql5()  # Python生成MT5代码
myMoneyM = MyTrade.MyClass_MoneyManage()  # 资金管理类
myDefault.set_backend_default("Pycharm")  # Pycharm下需要plt.show()才显示图
# ------------------------------------------------------------
# Jupyter Notebook 控制台显示必须加上：%matplotlib inline ，弹出窗显示必须加上：%matplotlib auto
# %matplotlib inline
# import warnings
# warnings.filterwarnings('ignore')

# %%
# 简介
# A CNN-LSTM-Based Model to Forecast Stock Prices (Wenjie Lu, Jiazheng Li, Yifan Li, Aijun Sun, Jingyang Wang, Complexity magazine, vol. 2020, Article ID 6622927, 10 pages, 2020) 一文的作者比较了各种股票价格预测模型：

# 股票价格数据具有时间序列的特点。
# 同时，基于机器学习长短期记忆（LSTM）具有通过记忆功能分析时间序列数据之间关系的优势，我们提出了一种基于CNN-LSTM的股票价格预测方法。
# 同时，我们使用MLP、CNN、RNN、LSTM、CNN-RNN等预测模型逐一对股票价格进行了预测。此外，还对这些模型的预测结果进行了分析和比较。
# 本研究利用的数据涉及1991年7月1日至2020年8月31日的每日股票价格，包括7127个交易日。
# 在历史数据方面，我们选择了八个特征，包括开盘价、最高价、最低价、收盘价、成交量、成交额、涨跌幅和变化。
# 首先，我们采用CNN从数据中有效提取特征，即前10天的项目。然后，我们采用LSTM，用提取的特征数据来预测股票价格。
# 根据实验结果，CNN-LSTM可以提供可靠的股票价格预测，并且预测精度最高。
# 这种预测方法不仅为股票价格预测提供了一种新的研究思路，也为学者们研究金融时间序列数据提供了实践经验。

# 在所有考虑的模型中，CNN-LSTM模型在实验中产生了最好的结果。在这篇文章中，我们将考虑如何创建这样一个模型来预测金融时间序列，以及如何在MQL5专家顾问中使用创建的ONNX模型。

#%%
#Python libraries
import matplotlib.pyplot as plt
import MetaTrader5 as mt5
import tensorflow as tf
import numpy as np
import pandas as pd
import tf2onnx
from sklearn.model_selection import train_test_split
from sys import argv

#check tensorflow version
print(tf.__version__)
#check GPU support
print(len(tf.config.list_physical_devices('GPU'))>0)
#initialize MetaTrader5 for history data
if not mt5.initialize():
    print("initialize() failed, error code =",mt5.last_error())
    quit()

#show terminal info
terminal_info=mt5.terminal_info()
print(terminal_info)
#show file path
file_path=terminal_info.data_path+"\\MQL5\\Files\\"
print(file_path)
#data path to save the model
# data_path=argv[0]
# last_index=data_path.rfind("\\")+1
# data_path=data_path[0:last_index]
data_path = __mypath__.get_desktop_path() + "\\"
print("data path to save onnx model",data_path)

#set start and end dates for history data
from datetime import timedelta,datetime
end_date = datetime.now()
start_date = end_date - timedelta(days=120)

#print start and end dates
print("data start date=",start_date)
print("data end date=",end_date)
#get EURUSD rates (H1) from start_date to end_date
eurusd_rates = mt5.copy_rates_range("EURUSD", mt5.TIMEFRAME_H1, start_date, end_date)
#create dataframe
df = pd.DataFrame(eurusd_rates)
df.head()
df.shape

#prepare close prices only
data = df.filter(['close']).values

#show close prices
plt.figure(figsize = (18,10))
plt.plot(data,'b',label = 'Original')
plt.xlabel("Hours")
plt.ylabel("Price")
plt.title("EURUSD_H1")
plt.legend()
plt.show()

#%%
#scale data using MinMaxScaler
from sklearn.preprocessing import MinMaxScaler
scaler=MinMaxScaler(feature_range=(0,1))
scaled_data = scaler.fit_transform(data)

#training size is 80% of the data
training_size = int(len(scaled_data)*0.80)
print("training size:",training_size)

#create train data and check size
train_data_initial = scaled_data[0:training_size,:]
print(len(train_data_initial))

#create test data and check size
test_data_initial= scaled_data[training_size:,:1]
print(len(test_data_initial))

#split a univariate sequence into samples
def split_sequence(sequence, n_steps):
    X, y = list(), list()
    for i in range(len(sequence)):
       #find the end of this pattern
       end_ix = i + n_steps
       #check if we are beyond the sequence
       if end_ix > len(sequence)-1:
          break
       #gather input and output parts of the pattern
       seq_x, seq_y = sequence[i:end_ix], sequence[end_ix]
       X.append(seq_x)
       y.append(seq_y)
    return np.array(X), np.array(y)

#split into samples
time_step = 120
x_train, y_train = split_sequence(train_data_initial, time_step)
x_test, y_test = split_sequence(test_data_initial, time_step)
#reshape input to be [samples, time steps, features] which is required for LSTM
x_train =x_train.reshape(x_train.shape[0],x_train.shape[1],1)
x_test = x_test.reshape(x_test.shape[0],x_test.shape[1],1)

#%%
#import keras libraries for the model
import math
from keras.models import Sequential
from keras.layers import Dense,Activation,Conv1D,MaxPooling1D,Dropout
from keras.layers import LSTM
from keras.utils.vis_utils import plot_model
from keras.metrics import RootMeanSquaredError as rmse
from keras import optimizers

#define the model
model = Sequential()
model.add(Conv1D(filters=256, kernel_size=2,activation='relu',padding = 'same',input_shape=(120,1)))
model.add(MaxPooling1D(pool_size=2))
model.add(LSTM(100, return_sequences = True))
model.add(Dropout(0.3))
model.add(LSTM(100, return_sequences = False))
model.add(Dropout(0.3))
model.add(Dense(units=1, activation = 'sigmoid'))
model.compile(optimizer='adam', loss= 'mse' , metrics = [rmse()])

#show model
model.summary()

#measure time
import time
time_calc_start = time.time()

#fit model with 300 epochs
history=model.fit(x_train,y_train,epochs=300,validation_data=(x_test,y_test),batch_size=32,verbose=1)

#calculate time
fit_time_seconds = time.time() - time_calc_start
print("fit time =",fit_time_seconds," seconds.")

#show training history keys
history.history.keys()

#show iteration-loss graph for training and validation
plt.figure(figsize = (18,10))
plt.plot(history.history['loss'],label='Training Loss',color='b')
plt.plot(history.history['val_loss'],label='Validation-loss',color='g')
plt.xlabel("Iteration")
plt.ylabel("Loss")
plt.title("LOSS")
plt.legend()
plt.show()

#show iteration-rmse graph for training and validation
plt.figure(figsize = (18,10))
plt.plot(history.history['root_mean_squared_error'],label='Training RMSE',color='b')
plt.plot(history.history['val_root_mean_squared_error'],label='Validation-RMSE',color='g')
plt.xlabel("Iteration")
plt.ylabel("RMSE")
plt.title("RMSE")
plt.legend()
plt.show()

#evaluate training data
model.evaluate(x_train, y_train, batch_size = 32)
#evaluate testing data
model.evaluate(x_test, y_test, batch_size = 32)
#prediction using training data
train_predict = model.predict(x_train)
plot_y_train = y_train.reshape(-1,1)

#show actual vs predicted (training) graph
plt.figure(figsize=(18,10))
plt.plot(scaler.inverse_transform(plot_y_train),color = 'b', label = 'Original')
plt.plot(scaler.inverse_transform(train_predict),color='red', label = 'Predicted')
plt.title("Prediction Graph Using Training Data")
plt.xlabel("Hours")
plt.ylabel("Price")
plt.legend()
plt.show()

#prediction using testing data
test_predict = model.predict(x_test)
plot_y_test = y_test.reshape(-1,1)

#%%
# 为了计算度量，我们需要将数据从区间[0,1]转换过来。同样，我们使用MinMaxScaler。
#calculate metrics
from sklearn import metrics
from sklearn.metrics import r2_score
#transform data to real values
value1=scaler.inverse_transform(plot_y_test)
value2=scaler.inverse_transform(test_predict)
#calc score
score = np.sqrt(metrics.mean_squared_error(value1,value2))
print("RMSE         : {}".format(score))
print("MSE          :", metrics.mean_squared_error(value1,value2))
print("R2 score     :",metrics.r2_score(value1,value2))

#show actual vs predicted (testing) graph
plt.figure(figsize=(18,10))
plt.plot(scaler.inverse_transform(plot_y_test),color = 'b',  label = 'Original')
plt.plot(scaler.inverse_transform(test_predict),color='g', label = 'Predicted')
plt.title("Prediction Graph Using Testing Data")
plt.xlabel("Hours")
plt.ylabel("Price")
plt.legend()
plt.show()

# save model to ONNX
output_path = data_path+"model.eurusd.H1.120.onnx"
onnx_model = tf2onnx.convert.from_keras(model, output_path=output_path)
print(f"model saved to {output_path}")
# 保存到MQL5的Files中
output_path = file_path+"model.eurusd.H1.120.onnx"
onnx_model = tf2onnx.convert.from_keras(model, output_path=output_path)
print(f"saved model to {output_path}")

# finish
mt5.shutdown()
# Python脚本的完整代码附在文章的Jupyter笔记本中。
# 在《基于CNN-LSTM的模型预测股票价格》一文中，采用CNN-LSTM架构的模型获得了R^2=0.9646的最佳结果。在我们的例子中，CNN-LSTM网络产生的最佳结果是R^2=0.9684。根据这些结果，这种类型的模型在解决预测问题时可以很有效率。
# 我们考虑了一个Python脚本的例子，它建立和训练CNN-LSTM模型来预测金融时间序列。

#%% Using the Model in MetaTrader 5
# 2.1. 在你开始之前要知道的好事
# 有两种方法来创建一个模型： 你可以使用OnnxCreate从onnx文件创建模型，或者使用OnnxCreateFromBuffer从数据阵列创建模型。
# 如果ONNX模型被用作EA中的资源，你需要在每次改变模型时重新编译EA。
# 并非所有模型都有完全定义的尺寸输入和/或输出张量。这通常是负责包尺寸的第一个维度。在运行一个模型之前，你必须使用OnnxSetInputShape和OnnxSetOutputShape函数明确指定尺寸。模型的输入数据应该以训练模型时的相同方式准备。
# 对于输入和输出数据，我们建议使用模型中使用的相同类型的数组、矩阵和/或向量。在这种情况下，你将不必在运行模型时转换数据。如果数据不能以所需类型表示，数据将被自动转换。
# 使用OnnxRun来推理（运行）你的模型。请注意，一个模型可以被多次运行。使用模型后，使用 OnnxRelease 函数释放它。

# 2.2. 读取onnx文件并获得输入和输出的信息
# 为了使用我们的模型，我们需要知道模型的位置、输入数据类型和形状，以及输出数据类型和形状。根据之前创建的脚本，model.eurusd.H1.120.onnx与生成onnx文件的Python脚本位于同一个文件夹中。输入是float32，120个归一化的收盘价（用于在批量大小等于1的情况下工作）；输出是float32，这是一个由模型预测的归一化价格。
# 我们还在MQL5\Files文件夹中创建了onnx文件，以便使用MQL5脚本获得模型输入和输出数据。

# 参见MT5


from Chem_Equation_Balancer import *
from EmpiricalFormulas import *
from Number_Validation import *
def Chapter4_Menu(): #Submenu for Chaper 4
    print ("\nChapter 4 Menu:\n")
    while True:
        print ("Enter 0 to find total mass of a compound")
        print ("Enter 1 to test whether an equation is balanced")
        print ("Enter 2 to get the percent of a compund by mass")
        print ("Enter 3 to get the Emperical formula by mass % of each element")
        print ("Enter 4 to return to the main Menu")

        inp = input('\n')

        while inp not in ["1", "2", "3", "0", "4"]:
            inp = input("Enter either 0, 1, 2, 3, or 4 please! ")

        if inp == '0':
            Total_Mass_Menu()
        if inp == '1':
            Balanced_Check_Menu()
        if inp == '2':
            Perc_Mass_Menu()
        if inp == '3':
            GetEP_Menu()
        if inp == '4':
            return ()

        print ("\n")

def Total_Mass_Menu(): # Finds the total mass per mol of a substance
    equation = input("Please input a chemical compund (Letters that are not chemicals will be equal to 0) ")

    try:
        print ("One mol of", equation,'is',get_total_mass(equation), "g")
    except:
        print ("This is not a valid compound")
        Total_Mass_Menu()

def Balanced_Check_Menu(): # Checks to see if a chemical equation is balanced
    #Example of balanced equation- NO2 + H2O -> HNO3
    equation = input("Please input a chemical equation ")

    try: # Equations without 2 sides will result in a failure
        if is_balanced_equ(equation):
            print ("The equation is balanced")
        else:
            print ("The equation is not balanced")
    except ValueError: # Catches this Error
        print ("You must have exactly 1 recactant and exactly 1 product")

def Perc_Mass_Menu(): # Gets each elements mass percentage in the compound
    equation = input("Please input a chemical compund to calculate the percent of each element by mass ")

    try: # Any non-elements put into the equation will result in failure
        GetPercByMass(equation)
    except:
        print ("This is not a valid compound")
        Perc_Mass_Menu()

def GetEP_Menu(): # Inverse of the previous function
    rem_perc = 100
    total_input = []
    while rem_perc >1: # Needs sum of percents to total 99 - 101
        ele = input("Input an element ")
        perc = input("What percent "+ele+" by mass is the compund? ").replace("%", "")
        if perc == "a" or perc == "all":
            perc = str(rem_perc)
        while valid_num(perc, domain = "(0, "+str(rem_perc)+"]") == False:
            print ("You must input a number greater than 0 and less than or equal to "+ str(rem_perc) + " because you cannot have more than 100% total")
            if perc == "a" or perc == "all":
                perc = rem_perc
            perc = input("What percent "+ele+" by mass is the compund? ").replace("%", "")
        total_input.append([ele, float(perc)])
        rem_perc -= float(perc)
    try:
        print ("The emperical formula of this compound is "+GetEP(total_input))
    except:
        print ("One or more of the inputted elements were not actual elements")


#!/usr/bin/env python3
"""
Program to decode the first sprite of a CTHG 2 file.
Mainly intended as a test for the checking the encoder, but also a
demonstration of how to decode.
"""

_license = """
Copyright (c) 2013 Alberth "Alberth" Hofkamp

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
"""

from PIL import Image

class Infile:
    def __init__(self, fname):
        self.fname = fname
        self.handle = open(self.fname, "rb")

        # Read header
        for h in [ord('C'), ord('T'), ord('H'), ord('G'), 2, 0]:
            v = self.getByte()
            assert v == h

    def getByte(self):
        v = self.handle.read(1)[0]
        return v

    def getWord(self):
        b = self.getByte()
        return b | (self.getByte() << 8)

    def getLong(self):
        w = self.getWord()
        return w | (self.getWord() << 16)

    def getData(self, size):
        data = []
        for i in range(size):
            data.append(self.getByte())
        return data

def decode_xy(pix_idx, w, h):
    y = pix_idx // w
    x = pix_idx - w * y
    assert x >= 0 and x < w
    assert y >= 0 and y < h
    return x, y

def get_colour(table, idx):
    if table == 0:
        return (0, 0, 0, 255)
    if table == 1:
        return (idx, 0, 0, 255)
    if table == 2:
        return (0, idx, 0, 255)
    if table == 3:
        return (0, 0, idx, 255)
    if table == 4:
        return (0, idx, idx, 255)
    if table == 5:
        return (idx, 0, idx, 255)
    assert False

class Sprite:
    def __init__(self, infile):
        size = infile.getLong() - 2 - 2 - 2
        self.number = infile.getWord()
        self.width = infile.getWord()
        self.height = infile.getWord()
        self.data = infile.getData(size)

        print("Sprite number {}".format(self.number))
        print("Width {}".format(self.width))
        print("Height {}".format(self.height))
        print("Size {}".format(size))
        print("Data size {}".format(len(self.data)))

    def get_data(self, idx):
        return self.data[idx], idx + 1

    def save(self):
        im = Image.new("RGBA", (self.width, self.height), (0, 0, 0, 0))
        pix = im.load()

        idx = 0
        pix_idx = 0
        while idx < len(self.data):
            length, idx = self.get_data(idx)

            if length <= 63: # Fixed non-transparent 32bpp pixels (RGB)
                length = length & 63
                x, y = decode_xy(pix_idx, self.width, self.height)
                for i in range(length):
                    d = (self.data[idx], self.data[idx+1], self.data[idx+2], 255)
                    pix[x, y] = d
                    idx = idx + 3
                    pix_idx = pix_idx + 1
                    x = x + 1
                    if x == self.width:
                        x = 0
                        y = y + 1
                continue

            elif length <= 64+63: # Partially transparent 32bpp pixels (RGB)
                length = length & 63
                opacity, idx = self.get_data(idx)
                x, y = decode_xy(pix_idx, self.width, self.height)
                for i in range(length):
                    d = (self.data[idx], self.data[idx+1], self.data[idx+2], opacity)
                    pix[x, y] = d
                    idx = idx + 3
                    pix_idx = pix_idx + 1
                    x = x + 1
                    if x == self.width:
                        x = 0
                        y = y + 1
                continue

            elif length <= 128+63: # Fixed fully transparent pixels
                length = length & 63
                pix_idx = pix_idx + length
                continue

            else: # Recolour layer.
                length = length & 63
                table, idx = self.get_data(idx)
                opacity, idx = self.get_data(idx)
                x, y = decode_xy(pix_idx, self.width, self.height)
                for i in range(length):
                    col, idx = self.get_data(idx)
                    pix[x, y] = get_colour(table, col)
                    pix_idx = pix_idx + 1
                    x = x + 1
                    if x == self.width:
                        x = 0
                        y = y + 1
                continue

        im.save("sprite_{}.png".format(self.number))

inf = Infile("x.out")
spr = Sprite(inf)
spr.save()


"""Pure Python implementation of EM algorithm."""
from array import array
import random

class Cluster:
    """Implementation of EM clustering."""
    def __init__(self, filename, dim, num_entry, num_cluster=10):
        self.float_size = 4
        self.dim = dim
        self.num_entry = num_entry
        self.data = self.import_data(filename)
        self.num_cluster = num_cluster
        self.centroids = random.sample(self.data, self.num_cluster)
        self.labels = {cluster_idx: [] for cluster_idx in range(self.num_cluster)}

    def import_data(self, filename):
        """Read and process the binary data."""
        raw_data = array('f')
        with open(filename, 'rb') as file_desc:
            raw_data.frombytes(file_desc.read())
        data = [[] for _ in range(self.num_entry)]
        for i in range(self.num_entry):
            for j in range(self.dim):
                idx = i * self.dim + j
                data[i].append(raw_data[idx])
        return data

    def distance(self, lhs, rhs):
        """Euclidean distance between two vectors 'lhs' and 'rhs'."""
        return sum([(lhs[idx] - rhs[idx]) ** 2 for idx in range(self.dim)]) ** 0.5

    def vectors_mean(self, vectors):
        """Calculate the mean of a set of vectors."""
        total = [0 for _ in range(self.dim)]
        for vector in vectors:
            total = [lhs + rhs for lhs, rhs in zip(total, vector)]
        return [elem / len(vectors) for elem in total]

    def e_step(self):
        """E-step in EM algorithm: Expectation."""
        self.labels = {cluster_idx: [] for cluster_idx in range(self.num_cluster)}
        for vector_idx, vector in enumerate(self.data):
            distances_to_clusters = []
            for cluster in self.centroids:
                distances_to_clusters.append(self.distance(vector, cluster))
            min_cluster = distances_to_clusters.index(min(distances_to_clusters))
            self.labels[min_cluster].append(vector_idx)

    def m_step(self):
        """M-step in EM algorithm: Maximization."""
        new_centroids = []
        for _, member_indices in self.labels.items():
            member_vectors = [self.data[idx] for idx in member_indices]
            new_centroids.append(self.vectors_mean(member_vectors))
        loss = sum([self.distance(new, old)
                    for new, old
                    in zip(new_centroids, self.centroids)]) / self.num_cluster
        self.centroids = new_centroids
        return loss

    def fit(self, epsilon=0.001, max_iter=200):
        """Fitting to data."""
        for idx in range(max_iter):
            self.e_step()
            loss = self.m_step()
            print('step {}: loss {}.'.format(idx, loss))
            if loss < epsilon:
                for member_indices in self.labels.items():
                    print(member_indices)
                for cluster_idx, centroid in enumerate(self.centroids):
                    print('cluster {}: {}'.format(cluster_idx, centroid))
                break

    def cluster_vectors(self, cluster):
        """Return vectors of a cluster."""
        return [self.data[idx] for idx in self.labels[cluster]]


#!/usr/bin/python3

import argparse
from iCEburn.libiceblink import ICE40Board

def rtype(x):
    return ('R', int(x, 16))

def wtype(x):
    return ('W', [int(i,16) for i in x.split(':')])

def main():
    ap = argparse.ArgumentParser()
    ap.add_argument("-r", "--read", dest='actions', type=rtype, action='append')
    ap.add_argument("-w", "--write", dest='actions', type=wtype, action='append')
    args = ap.parse_args()

    board = ICE40Board()
    with board.get_board_comm() as comm:
        for atype, arg in args.actions:
            if atype == 'R':
                addr = arg
                print("READ  %02x: %02x" % (addr, comm.readReg(addr)))
            elif atype == 'W':
                addr, value = arg
                print("WRITE %02x: %02x" % (addr, value))
                comm.writeReg(addr, value)

if __name__ == "__main__":
    main()


import pytest
from src.error import InputError
from src.auth import auth_register_v2
from src.user import user_profile_v2
from src.other import clear_v1

@pytest.fixture
def register_user():
    clear_v1()
    user = auth_register_v2("johnsmith@gmail.com", "123456", "john", "smith")
    token = user['token']
    id = user['auth_user_id']
    return token, id

def test_valid_input(register_user):
    token, id = register_user
    res = user_profile_v2(token, id)
    assert res['user']['u_id'] == id
    assert res['user']['email'] == 'johnsmith@gmail.com'
    assert res['user']['name_first'] == 'john'
    assert res['user']['name_last'] == 'smith'
    assert res['user']['handle_str'] == 'johnsmith'

def test_invalid_uid(register_user):
    token, id = register_user
    id += 1
    with pytest.raises(InputError):
        user_profile_v2(token, id)


import time
import logging

from django.contrib import admin
from django.contrib import messages
from django.contrib.admin import helpers
from django.urls import reverse
from django.db import transaction
from django.db.models import Count
from django.template.response import TemplateResponse
from django.utils.html import format_html, format_html_join

from mangaki.models import (
    Work, TaggedWork, WorkTitle, Genre, Track, Tag, Artist, Studio, Editor, Rating, Page,
    Suggestion, Evidence, Announcement, Recommendation, Pairing, Reference, Top, Ranking,
    Role, Staff, FAQTheme,
    FAQEntry, Trope, Language,
    ExtLanguage, WorkCluster,
    UserBackgroundTask,
    ActionType,
    get_field_changeset
)
from mangaki.utils.anidb import AniDBTag, client, diff_between_anidb_and_local_tags
from mangaki.utils.db import get_potential_posters

from collections import defaultdict
from enum import Enum

from mangaki.utils.work_merge import WorkClusterMergeHandler

ActionTypeColors = {
    ActionType.DO_NOTHING: 'black',  # INFO_ONLY
    ActionType.JUST_CONFIRM: 'green',
    ActionType.CHOICE_REQUIRED: 'red'
}

class MergeErrors(Enum):
    NO_ID = 'no ID'
    FIELDS_MISSING = 'missing fields'
    NOT_ENOUGH_WORKS = 'not enough works'

def handle_merge_errors(response, request, final_work, nb_merged,
                        message_user):
    if response == MergeErrors.NO_ID:
        message_user(request,
                     "Aucun ID n'a été fourni pour la fusion.",
                     level=messages.ERROR)
    if response == MergeErrors.FIELDS_MISSING:
        message_user(request,
                     """Un ou plusieurs des champs requis n'ont pas été remplis.
                          (Détails: {})""".format(", ".join(final_work)),
                     level=messages.ERROR)
    if response == MergeErrors.NOT_ENOUGH_WORKS:
        message_user(request,
                     "Veuillez sélectionner au moins 2 œuvres à fusionner.",
                     level=messages.WARNING)
    if response is None:  # Confirmed
        message_user(request,
                     format_html('La fusion de {:d} œuvres vers {:s} a bien été effectuée.'
                                 .format(nb_merged, final_work.get_absolute_url(), final_work.title)))

def create_merge_form(works_to_merge_qs):
    work_dicts_to_merge = list(works_to_merge_qs.values())
    field_changeset = get_field_changeset(work_dicts_to_merge)

    fields_to_choose = []
    fields_required = []
    template_rows = []

    suggestions = {}
    for field, choices, action, suggested, _ in field_changeset:
        suggestions[field] = suggested
        template_rows.append({
            'field': field,
            'choices': choices,
            'action_type': action,
            'suggested': suggested,
            'color': ActionTypeColors[action],
        })

        if field != 'id' and action != ActionType.DO_NOTHING:
            fields_to_choose.append(field)

        if action == ActionType.CHOICE_REQUIRED:
            fields_required.append(field)

    template_rows.sort(key=lambda row: int(row['action_type']), reverse=True)
    rating_samples = [(Rating.objects.filter(work_id=work_dict['id']).count(),
                       Rating.objects.filter(work_id=work_dict['id'])[:10]) for work_dict in work_dicts_to_merge]  # FIXME: too many queries
    return fields_to_choose, fields_required, template_rows, rating_samples, suggestions

@transaction.atomic  # In case trouble happens
def merge_works(request, selected_queryset, force=False, extra=None):
    user = request.user if request else None
    if selected_queryset.model == WorkCluster:  # Author is reviewing an existing WorkCluster
        from_cluster = True
        cluster = selected_queryset.first()
        works_to_merge_qs = cluster.works.order_by('id').prefetch_related('rating_set', 'genre')
    else:  # Author is merging those works from a Work queryset
        from_cluster = False
        works_to_merge_qs = selected_queryset.order_by('id').prefetch_related('rating_set', 'genre')
    nb_works_to_merge = works_to_merge_qs.count()

    if request and request.POST.get('confirm'):  # Merge has been confirmed
        rich_context = request.POST
    else:
        fields_to_choose, fields_required, template_rows, rating_samples, suggestions = create_merge_form(works_to_merge_qs)
        context = {
            'fields_to_choose': ','.join(fields_to_choose),
            'fields_required': ','.join(fields_required),
            'template_rows': template_rows,
            'rating_samples': rating_samples,
            'queryset': selected_queryset,
            'opts': Work._meta if not from_cluster else WorkCluster._meta,
            'action': 'merge' if not from_cluster else 'trigger_merge',
            'action_checkbox_name': helpers.ACTION_CHECKBOX_NAME
        }
        if all(field in suggestions for field in fields_required):
            rich_context = dict(context)
            for field in suggestions:
                rich_context[field] = suggestions[field]
            if extra is not None:
                for field in extra:
                    rich_context[field] = extra[field]
            if force:
                rich_context['confirm'] = True

    if rich_context.get('confirm'):  # Merge has been confirmed
        works_to_merge = list(works_to_merge_qs)
        if not from_cluster:
            cluster = WorkCluster(user=user, checker=user)
            cluster.save()  # Otherwise we cannot add works
            cluster.works.add(*works_to_merge)

        # Happens when no ID was provided
        if not rich_context.get('id'):
            return None, None, MergeErrors.NO_ID

        final_id = int(rich_context.get('id'))
        final_work = Work.objects.get(id=final_id)

        # Notice how `cluster` always exist in this scope.

        # noinspection PyUnboundLocalVariable
        merge_handler = WorkClusterMergeHandler(cluster,
                                                works_to_merge,
                                                final_work)

        missing_required_fields = merge_handler.overwrite_fields(
            set(filter(None, rich_context.get('fields_to_choose').split(','))),
            set(filter(None, rich_context.get('fields_required').split(','))),
            rich_context)

        # Happens when a required field was left empty
        if missing_required_fields:
            return None, missing_required_fields, MergeErrors.FIELDS_MISSING

        merge_handler.perform_redirections()
        merge_handler.accept_cluster(user)
        return len(works_to_merge), merge_handler.target_work, None

    # Just show a warning if only one work was checked
    if nb_works_to_merge < 2:
        return None, None, MergeErrors.NOT_ENOUGH_WORKS

    return nb_works_to_merge, None, TemplateResponse(request, 'admin/merge_selected_confirmation.html', context)

logger = logging.getLogger(__name__)

class TaggedWorkInline(admin.TabularInline):
    model = TaggedWork
    fields = ('work', 'tag', 'weight')

    def get_queryset(self, request):
        qs = super().get_queryset(request)
        return qs.select_related('work', 'tag')

class StaffInline(admin.TabularInline):
    model = Staff
    fields = ('role', 'artist')
    raw_id_fields = ('artist',)

class WorkTitleInline(admin.TabularInline):
    model = WorkTitle
    fields = ('title', 'language', 'type')

class ReferenceInline(admin.TabularInline):
    model = Reference
    fields = ('source', 'identifier')

class AniDBaidListFilter(admin.SimpleListFilter):
    title = 'AniDB aid'
    parameter_name = 'AniDB aid'

    def lookups(self, request, model_admin):
        return ('Vrai', 'Oui'), ('Faux', 'Non')

    def queryset(self, request, queryset):
        if self.value() == 'Faux':
            return queryset.filter(anidb_aid=0)
        elif self.value() == 'Vrai':
            return queryset.exclude(anidb_aid=0)
        else:
            return queryset

@admin.register(FAQTheme)
class FAQAdmin(admin.ModelAdmin):
    ordering = ('order',)
    search_fields = ('theme',)
    list_display = ('theme', 'order')

@admin.register(Work)
class WorkAdmin(admin.ModelAdmin):
    search_fields = ('id', 'title', 'worktitle__title')
    list_display = ('id', 'category', 'title', 'nsfw')
    list_filter = ('category', 'nsfw', AniDBaidListFilter)
    raw_id_fields = ('redirect',)
    actions = ['make_nsfw', 'make_sfw', 'refresh_work_from_anidb', 'merge',
               'refresh_work', 'update_tags_via_anidb', 'change_title']
    inlines = [StaffInline, WorkTitleInline, ReferenceInline, TaggedWorkInline]
    readonly_fields = (
        'sum_ratings',
        'nb_ratings',
        'nb_likes',
        'nb_dislikes',
        'controversy',
    )

    def make_nsfw(self, request, queryset):
        rows_updated = queryset.update(nsfw=True)
        if rows_updated == 1:
            message_bit = "1 œuvre est"
        else:
            message_bit = "%s œuvres sont" % rows_updated
        self.message_user(request, "%s désormais NSFW." % message_bit)

    make_nsfw.short_description = "Rendre NSFW les œuvres sélectionnées"

    def update_tags_via_anidb(self, request, queryset):
        works = queryset.all()

        if request.POST.get('confirm'): # Updating tags has been confirmed
            to_update_work_ids = set(map(int, request.POST.getlist('to_update_work_ids')))
            nb_updates = len(to_update_work_ids)

            work_ids = list(map(int, request.POST.getlist('work_ids')))

            tag_titles = request.POST.getlist('tag_titles')
            tag_weights = list(map(int, request.POST.getlist('weights')))
            tag_anidb_tag_ids = list(map(int, request.POST.getlist('anidb_tag_ids')))
            tags = list(map(AniDBTag, tag_titles, tag_weights, tag_anidb_tag_ids))

            # Checkboxes to know which tags have to be kept regardless of their pending status
            tag_checkboxes = request.POST.getlist('tag_checkboxes')
            tags_to_process = set(tuple(map(int, tag_checkbox.split(':'))) for tag_checkbox in tag_checkboxes)

            # Make a dict with work_id -> tags to keep
            tags_final = {}
            for index, work_id in enumerate(work_ids):
                if work_id not in to_update_work_ids:
                    continue
                if work_id not in tags_final:
                    tags_final[work_id] = []
                if (work_id, tags[index].anidb_tag_id) in tags_to_process:
                    tags_final[work_id].append(tags[index])

            # Process selected tags for works that have been selected
            for work in works:
                if work.id in to_update_work_ids:
                    client.update_tags(work, tags_final[work.id])

            if nb_updates == 0:
                self.message_user(request,
                                  "Aucune oeuvre n'a été marquée comme devant être mise à jour.",
                                  level=messages.WARNING)
            elif nb_updates == 1:
                self.message_user(request,
                                  "Mise à jour des tags effectuée pour une œuvre.")
            else:
                self.message_user(request,
                                  "Mise à jour des tags effectuée pour {} œuvres.".format(nb_updates))
            return None

        # Check for works with missing AniDB AID
        if not all(work.anidb_aid for work in works):
            self.message_user(request,
            """Certains de vos choix ne possèdent pas d'identifiant AniDB.
            Le rafraichissement de leurs tags a été omis. (Détails: {})"""
            .format(", ".join(map(lambda w: w.title,
                                  filter(lambda w: not w.anidb_aid, works)))),
            level=messages.WARNING)

        # Retrieve and send tags information to the appropriate form
        all_information = {}
        for index, work in enumerate(works, start=1):
            if work.anidb_aid:
                if index % 25 == 0:
                    logger.info('(AniDB refresh): Sleeping...')
                    time.sleep(1)  # Don't spam AniDB.

                anidb_tags = client.get_tags(anidb_aid=work.anidb_aid)
                tags_diff = diff_between_anidb_and_local_tags(work, anidb_tags)
                tags_count = 0

                for tags_info in tags_diff.values():
                    tags_count += len(tags_info)

                if tags_count > 0:
                    all_information[work.id] = {
                        'title': work.title,
                        'deleted_tags': tags_diff["deleted_tags"],
                        'added_tags': tags_diff["added_tags"],
                        'updated_tags': tags_diff["updated_tags"],
                        'kept_tags': tags_diff["kept_tags"]
                    }

        if all_information:
            context = {
                'all_information': all_information.items(),
                'queryset': queryset,
                'opts': TaggedWork._meta,
                'action': 'update_tags_via_anidb',
                'action_checkbox_name': helpers.ACTION_CHECKBOX_NAME
            }
            return TemplateResponse(request, "admin/update_tags_via_anidb.html", context)
        else:
            self.message_user(request,
                              "Aucune des œuvres sélectionnées n'a subit de mise à jour des tags chez AniDB.",
                              level=messages.WARNING)
            return None

    update_tags_via_anidb.short_description = "Mettre à jour les tags des œuvres depuis AniDB"

    def make_sfw(self, request, queryset):
        rows_updated = queryset.update(nsfw=False)
        if rows_updated == 1:
            message_bit = "1 œuvre n'est"
        else:
            message_bit = "%s œuvres ne sont" % rows_updated
        self.message_user(request, "%s désormais plus NSFW." % message_bit)

    make_sfw.short_description = "Rendre SFW les œuvres sélectionnées"

    @transaction.atomic
    def refresh_work_from_anidb(self, request, queryset):
        works = queryset.all()

        # Check for works with missing AniDB AID
        offending_works = []
        if not all(work.anidb_aid for work in works):
            offending_works = [work for work in works if not work.anidb_aid]
            self.message_user(request,
            "Certains de vos choix ne possèdent pas d'identifiant AniDB. "
            "Leur rafraichissement a été omis. (Détails: {})"
            .format(", ".join(map(lambda w: w.title, offending_works))),
            level=messages.WARNING)

        # Check for works that have a duplicate AniDB AID
        aids_with_works = defaultdict(list)
        for work in works:
            if work.anidb_aid:
                aids_with_works[work.anidb_aid].append(work)

        aids_with_potdupe_works = defaultdict(list)
        for work in Work.objects.filter(anidb_aid__in=aids_with_works.keys()):
            aids_with_potdupe_works[work.anidb_aid].append(work)

        works_with_conflicting_anidb_aid = []
        for anidb_aid, potdupe_works in aids_with_potdupe_works.items():
            if len(potdupe_works) > 1:
                works_with_conflicting_anidb_aid.extend(aids_with_works[anidb_aid])

                # Alert the user for each work he selected that has a duplicate AniDB ID
                self.message_user(
                    request,
                    """Le rafraichissement de {} a été omis car d'autres œuvres possèdent
                    le même identifiant AniDB #{}. (Œuvres en conflit : {})"""
                    .format(
                        ", ".join(map(lambda w: w.title, aids_with_works[anidb_aid])),
                        anidb_aid,
                        ", ".join(map(lambda w: w.title, aids_with_potdupe_works[anidb_aid]))
                    ),
                    level=messages.WARNING
                )

        # Refresh works from AniDB
        refreshed = 0
        for index, work in enumerate(works, start=1):
            if work.anidb_aid and work not in works_with_conflicting_anidb_aid:
                logger.info('Refreshing {} from AniDB.'.format(work))
                if client.get_or_update_work(work.anidb_aid) is not None:
                    refreshed += 1
                if index % 25 == 0:
                    logger.info('(AniDB refresh): Sleeping...')
                    time.sleep(1)  # Don't spam AniDB.

        if refreshed > 0:
            self.message_user(request,
                              "Le rafraichissement de {} œuvre(s) a été effectué avec succès."
                              .format(refreshed))

    refresh_work_from_anidb.short_description = "Rafraîchir les œuvres depuis AniDB"

    def merge(self, request, queryset):
        nb_merged, final_work, response = merge_works(request, queryset)
        handle_merge_errors(response, request, final_work, nb_merged,
                            self.message_user)
        return response

    merge.short_description = "Fusionner les œuvres sélectionnées"

    def refresh_work(self, request, queryset):
        if request.POST.get('confirm'):  # Confirmed
            downloaded_titles = []
            for obj in queryset:
                chosen_poster = request.POST.get('chosen_poster_{:d}'.format(obj.id))
                if not chosen_poster:
                    continue
                if obj.retrieve_poster(chosen_poster):
                    downloaded_titles.append(obj.title)
            if downloaded_titles:
                self.message_user(
                    request,
                    "Des posters ont été trouvés pour les anime suivants : %s." % ', '.join(downloaded_titles))
            else:
                self.message_user(request, "Aucun poster n'a été trouvé, essayez de changer le titre.")
            return None
        bundle = []
        for work in queryset:
            bundle.append((work.id, work.title, get_potential_posters(work)))
        context = {
            'queryset': queryset,
            'bundle': bundle,
            'opts': self.model._meta,
            'action_checkbox_name': helpers.ACTION_CHECKBOX_NAME
        }
        return TemplateResponse(request, 'admin/refresh_poster_confirmation.html', context)

    refresh_work.short_description = "Mettre à jour la fiche de l'anime (poster)"

    @transaction.atomic
    def change_title(self, request, queryset):
        if request.POST.get('confirm'):  # Changing default title has been confirmed
            work_ids = request.POST.getlist('work_ids')
            titles_ids = request.POST.getlist('title_ids')

            titles = WorkTitle.objects.filter(
                pk__in=titles_ids, work__id__in=work_ids
            ).values_list('title', 'work__title', 'work__id')

            for new_title, current_title, work_id in titles:
                if new_title != current_title:
                    Work.objects.filter(pk=work_id).update(title=new_title)

            self.message_user(request, 'Les titres ont bien été changés pour les œuvres sélectionnées.')
            return None

        work_titles = WorkTitle.objects.filter(work__in=queryset.values_list('pk', flat=True))
        full_infos = work_titles.values(
            'pk', 'title', 'language__code', 'type', 'work_id', 'work__title'
        ).order_by('title').distinct('title')

        titles = {}
        for infos in full_infos:
            if infos['work_id'] not in titles:
                titles[infos['work_id']] = {}

            titles[infos['work_id']].update({
                infos['pk']: {
                    'title': infos['title'],
                    'language': infos['language__code'] if infos['language__code'] else 'inconnu',
                    'type': infos['type'] if infos['title'] != infos['work__title'] else 'current'
                }
            })

        if titles:
            context = {
                'work_titles': titles,
                'queryset': queryset,
                'opts': Work._meta,
                'action': 'change_title',
                'action_checkbox_name': helpers.ACTION_CHECKBOX_NAME
            }
            return TemplateResponse(request, 'admin/change_default_work_title.html', context)
        else:
            self.message_user(request,
                              'Aucune des œuvres sélectionnées ne possèdent de titre alternatif.',
                              level=messages.WARNING)
            return None

    change_title.short_description = "Changer le titre par défaut"

@admin.register(Artist)
class ArtistAdmin(admin.ModelAdmin):
    search_fields = ('id', 'name')

@admin.register(Tag)
class TagAdmin(admin.ModelAdmin):
    list_display = ("title",)
    readonly_fields = ("nb_works_linked",)

    def get_queryset(self, request):
        qs = super().get_queryset(request)
        return qs.annotate(works_linked=Count('work'))

    def nb_works_linked(self, obj):
        return obj.works_linked

    nb_works_linked.short_description = 'Nombre d\'œuvres liées au tag'

@admin.register(TaggedWork)
class TaggedWorkAdmin(admin.ModelAdmin):
    search_fields = ('work__title', 'tag__title')

@admin.register(WorkCluster)
class WorkClusterAdmin(admin.ModelAdmin):
    list_display = ('user', 'get_work_titles', 'resulting_work', 'reported_on', 'merged_on', 'checker', 'status', 'difficulty')
    list_filter = ('status',)
    list_select_related = ('user', 'resulting_work', 'checker')
    raw_id_fields = ('user', 'works', 'checker', 'resulting_work', 'origin')
    search_fields = ('id',)
    actions = ('trigger_merge', 'reject')

    def get_queryset(self, request):
        qs = super().get_queryset(request)
        return qs.prefetch_related('works')

    def trigger_merge(self, request, queryset):
        nb_merged, final_work, response = merge_works(request, queryset)
        handle_merge_errors(response, request, final_work, nb_merged,
                            self.message_user)
        return response

    trigger_merge.short_description = "Fusionner les œuvres de ce cluster"

    def reject(self, request, queryset):
        rows_updated = queryset.update(status='rejected')
        if rows_updated == 1:
            message_bit = "1 cluster"
        else:
            message_bit = "%s clusters" % rows_updated
        self.message_user(request, "Le rejet de %s a été réalisé avec succès." % message_bit)

    reject.short_description = "Rejeter les clusters sélectionnés"

    def get_work_titles(self, obj):
        cluster_works = obj.works.all()  # Does not include redirected works
        if cluster_works:
            def get_admin_url(work):
                if work.redirect is None:
                    return reverse('admin:mangaki_work_change', args=(work.id,))
                else:
                    return '#'
            return (
                '
' +
                format_html_join('', '
{} ({}{})
',
                    ((work.title, 'was ' if work.redirect is not None else '',
                      get_admin_url(work), work.id) for work in cluster_works)) +
                '
'
            )
        else:
            return '(all deleted)'

    get_work_titles.allow_tags = True

@admin.register(Suggestion)
class SuggestionAdmin(admin.ModelAdmin):
    list_display = ('work', 'problem', 'date', 'user', 'is_checked')
    list_filter = ('problem',)
    actions = ['check_suggestions', 'uncheck_suggestions']
    raw_id_fields = ('work',)
    search_fields = ('work__title', 'user__username')

    def view_on_site(self, obj):
        return obj.work.get_absolute_url()

    def check_suggestions(self, request, queryset):
        rows_updated = queryset.update(is_checked=True)
        for suggestion in queryset:
            if suggestion.problem == 'ref':  # Reference suggestion
                reference, created = Reference.objects.get_or_create(work=suggestion.work, url=suggestion.message)
                reference.suggestions.add(suggestion)
        if rows_updated == 1:
            message_bit = "1 suggestion"
        else:
            message_bit = "%s suggestions" % rows_updated
        self.message_user(request, "La validation de %s a été réalisé avec succès." % message_bit)

    check_suggestions.short_description = "Valider les suggestions sélectionnées"

    def uncheck_suggestions(self, request, queryset):
        rows_updated = queryset.update(is_checked=False)
        if rows_updated == 1:
            message_bit = "1 suggestion"
        else:
            message_bit = "%s suggestions" % rows_updated
        self.message_user(request, "L'invalidation de %s a été réalisé avec succès." % message_bit)

    uncheck_suggestions.short_description = "Invalider les suggestions sélectionnées"

@admin.register(Announcement)
class AnnouncementAdmin(admin.ModelAdmin):
    exclude = ('title',)

@admin.register(Pairing)
class PairingAdmin(admin.ModelAdmin):
    list_display = ('artist', 'work', 'date', 'user', 'is_checked')
    actions = ['make_director', 'make_composer', 'make_author']

    def make_director(self, request, queryset):
        rows_updated = 0
        director = Role.objects.get(slug='director')
        for pairing in queryset:
            _, created = Staff.objects.get_or_create(work_id=pairing.work_id, artist_id=pairing.artist_id,
                                                     role=director)
            if created:
                pairing.is_checked = True
                pairing.save()
                rows_updated += 1
        if rows_updated == 1:
            message_bit = "1 réalisateur a"
        else:
            message_bit = "%s réalisateurs ont" % rows_updated
        self.message_user(request, "%s été mis à jour." % message_bit)

    make_director.short_description = "Valider les appariements sélectionnés pour réalisation"

    def make_composer(self, request, queryset):
        rows_updated = 0
        composer = Role.objects.get(slug='composer')
        for pairing in queryset:
            _, created = Staff.objects.get_or_create(work_id=pairing.work_id, artist_id=pairing.artist_id,
                                                     role=composer)
            if created:
                pairing.is_checked = True
                pairing.save()
                rows_updated += 1
        if rows_updated == 1:
            message_bit = "1 compositeur a"
        else:
            message_bit = "%s compositeurs ont" % rows_updated
        self.message_user(request, "%s été mis à jour." % message_bit)

    make_composer.short_description = "Valider les appariements sélectionnés pour composition"

    def make_author(self, request, queryset):
        rows_updated = 0
        author = Role.objects.get(slug='author')
        for pairing in queryset:
            _, created = Staff.objects.get_or_create(work_id=pairing.work_id, artist_id=pairing.artist_id, role=author)
            if created:
                pairing.is_checked = True
                pairing.save()
                rows_updated += 1
        if rows_updated == 1:
            message_bit = "1 auteur a"
        else:
            message_bit = "%s auteurs ont" % rows_updated
        self.message_user(request, "%s été mis à jour." % message_bit)

    make_author.short_description = "Valider les appariements sélectionnés pour écriture"

@admin.register(Rating)
class RatingAdmin(admin.ModelAdmin):
    raw_id_fields = ('user', 'work')

@admin.register(Reference)
class ReferenceAdmin(admin.ModelAdmin):
    list_display = ['work', 'url']
    raw_id_fields = ('work', 'suggestions')

class RankingInline(admin.TabularInline):
    model = Ranking
    fields = ('content_type', 'object_id', 'name', 'score', 'nb_ratings', 'nb_stars',)
    readonly_fields = ('name',)

    def name(self, instance):
        return str(instance.content_object)

@admin.register(Top)
class TopAdmin(admin.ModelAdmin):
    inlines = [
        RankingInline,
    ]
    readonly_fields = ('category', 'date',)

    def has_add_permission(self, request):
        return False

@admin.register(Role)
class RoleAdmin(admin.ModelAdmin):
    model = Role
    prepopulated_fields = {'slug': ('name',)}

@admin.register(Evidence)
class EvidenceAdmin(admin.ModelAdmin):
    list_display = ['user', 'suggestion', 'agrees', 'needs_help']

admin.site.register(Genre)
admin.site.register(Track)
admin.site.register(Studio)
admin.site.register(Editor)
admin.site.register(Page)
admin.site.register(FAQEntry)
admin.site.register(Recommendation)
admin.site.register(Trope)
admin.site.register(Language)
admin.site.register(ExtLanguage)
admin.site.register(UserBackgroundTask)
admin.site.site_header = "Administration Mangaki"


MAX_QSIZE = 10
class CircularQueue :
    def __init__( self ) :
        self.front = 0
        self.rear = 0
        self.items = [None] * MAX_QSIZE

    def isEmpty( self ) : return self.front == self.rear
    def isFull( self ) : return self.front == (self.rear+1)%MAX_QSIZE
    def clear( self ) : self.front = self.rear

    def enqueue( self, item ):
        if not self.isFull():
            self.rear = (self.rear+1)% MAX_QSIZE
            self.items[self.rear] = item

    def dequeue( self ):
        if not self.isEmpty():
            self.front = (self.front+1)% MAX_QSIZE
            return self.items[self.front]

    def peek( self ):
        if not self.isEmpty():
            return self.items[(self.front + 1) % MAX_QSIZE]

    def size( self ) :
       return (self.rear - self.front + MAX_QSIZE) % MAX_QSIZE

    def display( self ):
        out = []
        if self.front < self.rear :
            out = self.items[self.front+1:self.rear+1]
        else:
            out = self.items[self.front+1:MAX_QSIZE] \
                + self.items[0:self.rear+1]
        print("[f=%s,r=%d] ==> "%(self.front, self.rear), out)

class TNode:
    def __init__ (self, data, left, right):
        self.data = data
        self.left = left
        self.right = right
def preorder(n) :
    if n is not None :
        print(n.data, end=' ')
        preorder(n.left)
        preorder(n.right)

def inorder(n) :
    if n is not None :
        inorder(n.left)
        print(n.data, end=' ')
        inorder(n.right)

def postorder(n) :
    if n is not None :
        postorder(n.left)
        postorder(n.right)
        print(n.data, end=' ')

def levelorder(root) :
    queue = CircularQueue()
    queue.enqueue(root)
    while not queue.isEmpty() :
        n = queue.dequeue()
        if n is not None :
            print(n.data, end=' ')
            queue.enqueue(n.left)
            queue.enqueue(n.right)

def count_node(n) :
    if n is None :
        return 0
    else :
        return 1 + count_node(n.left) + count_node(n.right)

def count_leaf(n) :
    if n is None :
        return 0
    elif n.left is None and n.right is None :
        return 1
    else :
        return count_leaf(n.left) + count_leaf(n.right)

def calc_height(n) :
    if n is None :
        return 0
    hLeft = calc_height(n.left)
    hRight = calc_height(n.right)
    if (hLeft > hRight) :
        return hLeft + 1
    else:
        return hRight + 1

def full_tree(root):
    if root.left != None and root.right != None:
        return True
    else:
        return False
def is_complete_binary_tree(root):
    queue = CircularQueue()
    queue.enqueue(root)
    while not queue.size != 0 :
        n = queue.dequeue()
        if not full_tree(root):
            if n.left == None and n.right == None:
                return False
            else:
                if n.left != None:
                    queue.enqueue(n.left)
                queue.dequeue()
                break
        else:
          queue.enqueue(n.left)
          queue.enqueue(n.right)
          queue.dequeue();
    while queue.size != 0:
        n = queue.dequeue()
        if root.left != None and root.right != None:
            return False
        else:
            return True

def is_balanced(root):
    if root == None:
        return True
    leftheigh = calc_height(root.left)
    rightheigh = calc_height(root.right)
    if (leftheigh - rightheigh <2) and (leftheigh - rightheigh > -1):
        return True
    return False

d = TNode('D', None, None)
b = TNode('B', d, None)
g = TNode('G', None, None)
h = TNode('H',None, None)
e = TNode('E', g,h)
f = TNode('F', None, None)
c = TNode('C', f,e)
root = TNode('A', b, c)

a2 = TNode('A', None, None)
b2 = TNode('B', None, None)
sla = TNode('/', a2, b2)
c2 = TNode('C', None, None)
star = TNode('*', sla, c2)
d2 = TNode('D', None, None)
star2 = TNode('*', star, d2)
e2 = TNode('E', None, None)
root2 = TNode('+', star2, e2)

c3 = TNode('C', None, None)
d3 = TNode('D', None, None)
b3 = TNode('B', c3,d3)
f2 = TNode('F',None, None)
e3 = TNode('E', f2, None)
root3 = TNode('A', b3,e3)

print('\n   In-Order : ', end='')
inorder(root)
print('\n  Pre-Order : ', end='')
preorder(root)
print('\n Post-Order : ', end='')
postorder(root)
print('\nLevel-Order : ', end='')
levelorder(root)
print()

print('\n   In-Order : ', end='')
inorder(root2)
print('\n  Pre-Order : ', end='')
preorder(root2)
print('\n Post-Order : ', end='')
postorder(root2)
print('\nLevel-Order : ', end='')
levelorder(root2)
print()

print('\n   In-Order : ', end='')
inorder(root3)
print('\n  Pre-Order : ', end='')
preorder(root3)
print('\n Post-Order : ', end='')
postorder(root3)
print('\nLevel-Order : ', end='')
levelorder(root3)
print()

print(" 노드의 개수 = %d개" % count_node(root))
print(" 단말의 개수 = %d개" % count_leaf(root))
print(" 트리의 높이 = %d" % calc_height(root))
print()
print(" 노드의 개수 = %d개" % count_node(root2))
print(" 단말의 개수 = %d개" % count_leaf(root2))
print(" 트리의 높이 = %d" % calc_height(root2))
print()
print(" 노드의 개수 = %d개" % count_node(root3))
print(" 단말의 개수 = %d개" % count_leaf(root3))
print(" 트리의 높이 = %d" % calc_height(root3))
print()
if is_complete_binary_tree(root3) == True:
    print('완전 이진 트리입니다.')
else:
    print('완전 이진 트리가 아닙니다.')
print()
if is_balanced(root3) == True:
    print('균형잡힌 트리입니다.')
else:
    print('균형이 안 잡힌 트리입니다.')


class Item:

    owners = []

    def __init__(self, name, quantity, price, owners):
        self.name = name
        self.quantity = quantity
        self.price = price
        self.owners = owners

# Define the parts of a basic restaurant check
class Check:

    def __init__(self, items):
        self.title = ""
        self.items = items    # creates a new list of items in the check

    def addItem(self, item):
        self.items.append(item)

    def print(self):
        for i in self.items:
            print(i.name, i.price, i.quantity, i.owners)

itemsList = [Item('steak tacos', 3, 42, []), Item('chicken taco', 1, 12, [])]
itemsList[0].owners = ['Johnny', 'Billy', 'Samantha']
print(itemsList[0].owners)
checkTest = Check(itemsList)

checkTest.print()
checkTest.addItem(Item('carnitas', 17, 1, []))
checkTest.print()


lista = []

try:
    #assert False
    # lista[0]
    a = 1 / 0
#except: <-- łap wszystkie błędy - zła praktyka
#except Exception: --//--
except ZeroDivisionError:
    print("Dzielono przez zero, ale idziemy dalej")
    a = 0
except IndexError as e:
    print("Pojwił się błąd indeksowania:", e)
    a = None
else:  # kiedy nie ma żadnego wyjątu
    print("Wszystko ok, nie ma co się zatrzymywać, idziemy dalej")
finally:
    print("Zamykamy pliki itp.")

print(a)

print("Reszta programu")

# ----- rzucanie błędów

class DistanceTooLarge(ValueError):
    pass

class ContentCensored(Exception):
    pass

def _czas_przejazdu(odleglosc):
    if odleglosc < 0:
        raise ValueError("Odległość nie może być mniejsza od zera")
    if odleglosc > 400000:
        raise DistanceTooLarge("Odległość zbyt duża")
    if odleglosc == 666:
        raise ContentCensored(f"Nieetyczna treść: {odleglosc}")
    czas = 1 / (24.5 / odleglosc)
    return czas

def czas_przejazdu(odleglosc):
    try:
        _czas_przejazdu(odleglosc)
    except ValueError as e:
        print("Nie można policzyć czasu przejazdu ponieważ:", e)
    except ZeroDivisionError:
        print("O, dzielenie przez zero! tego nie oczekiwaliśmy")
        raise  # <-- ponowne rzucenie wyjątku który złapaliśmy
    except ContentCensored:
        print("Zablokowano nieetyczne użycie programu")
    finally:
        print("Zdziałało finally")

czas_przejazdu(-1)
czas_przejazdu(1000000)
czas_przejazdu(666)
czas_przejazdu(0)


# general imports for EMISSOR and the BRAIN
from cltl import brain
from emissor.representation.scenario import ImageSignal

# specific imports
from datetime import datetime
import time
import cv2
import pathlib
import emissor_api

#### The next utils are needed for the interaction and creating triples and capsules
import chatbots.util.driver_util as d_util
import chatbots.util.capsule_util as c_util
import chatbots.util.face_util as f_util

def get_next_image(camera, imagefolder):
    what_is_seen = None

    success, frame = camera.read()
    if success:
        current_time = int(time.time() * 1e3)
        imagepath = f"{imagefolder}/{current_time}.png"
        image_bbox = (0, 0, frame.shape[1], frame.shape[0])
        cv2.imwrite(imagepath, frame)
        print(imagepath)

        what_is_seen = f_util.detect_objects(imagepath)

    return what_is_seen, current_time, image_bbox

def create_imageSignal_and_annotations_in_emissor (results, image_time, image_bbox, scenario_ctrl):

    #### We create an imageSignal
    imageSignal = d_util.create_image_signal(scenario_ctrl, f"{image_time}.png", image_bbox, image_time)
    scenario_ctrl.append_signal(imageSignal)
    what_is_seen = []
    ## The next for loop creates a capsule for each object detected in the image and posts a perceivedIn property for the object in the signal
    ## The "front_camera" is the source of the signal
    for result in results:
        current_time = int(time.time() * 1e3)

        bbox = [int(num) for num in result['yolo_bbox']]
        object_type = result['label_string']
        object_prob = result['det_score']
        what_is_seen.append(object_type)
        mention = f_util.create_object_mention(imageSignal, "front_camera", current_time, bbox, object_type,
                                               object_prob)
        imageSignal.mentions.append(mention)

    return what_is_seen, imageSignal

def add_perception_to_episodic_memory (imageSignal: ImageSignal, object_list, my_brain,  scenario_ctrl, location, place_id):
    response_list = []
    for object in object_list:
        ### We created a perceivedBy triple for this experience,
        ### @TODO we need to include the bouding box somehow in the object
        #print(object)
        capsule = c_util.scenario_image_triple_to_capsule(scenario_ctrl,
                                                          imageSignal,
                                                          location,
                                                          place_id,
                                                          "front_camera",
                                                          object,
                                                          "perceivedIn",
                                                          imageSignal.id)

        #print(capsule)
        # Create the response from the system and store this as a new signal
        # We use the throughts to respond
        response = my_brain.update(capsule, reason_types=True, create_label=True)
        response_list.append(response)
    return response_list

def watch_and_remember(scenario_ctrl,
                       camera,
                       imagefolder,
                       my_brain,
                       location,
                       place_id):

    t1 = datetime.now()
    while (datetime.now()-t1).seconds <= 60:
        ###### Getting the next input signals
        what_did_i_see, current_time, image_bbox = get_next_image(camera, imagefolder)
        object_list, imageSignal = create_imageSignal_and_annotations_in_emissor(what_did_i_see, current_time, image_bbox, scenario_ctrl)
        response = add_perception_to_episodic_memory(imageSignal, object_list, my_brain, scenario_ctrl, location, place_id)
        print(response)
        reply = "\nI saw: "
        if len(object_list) > 1:
            for index, object in enumerate(object_list):
                if index == len(object_list) - 1:
                    reply += " and"
                reply += " a " + object
        elif len(object_list) == 1:
            reply += " a " + object_list[0]
        else:
            reply = "\nI cannot see! Something wrong with my camera."

        print(reply + "\n")

def main():
    ### Link your camera
    camera = cv2.VideoCapture(0)
    # Initialise the brain in GraphDB

   ##### Setting the agents
    AGENT = "Leolani2"
    HUMAN_NAME = "Stranger"
    HUMAN_ID = "stranger"
    scenarioStorage, scenario_ctrl, imagefolder, rdffolder, location, place_id = emissor_api.start_a_scenario(AGENT, HUMAN_ID, HUMAN_NAME)

    log_path = pathlib.Path(rdffolder)
    my_brain = brain.LongTermMemory(address="http://localhost:7200/repositories/sandbox",
                                    log_dir=log_path,
                                    clear_all=True)

    watch_and_remember(scenario_ctrl, camera, imagefolder, my_brain, location, place_id)
    scenario_ctrl.scenario.ruler.end = int(time.time() * 1e3)
    scenarioStorage.save_scenario(scenario_ctrl)
    camera.release()

if __name__ == '__main__':
    main()


import pandas as pd
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
import time
import requests
import shutil
import os.path
import docx2txt
from webdriver_manager.chrome import ChromeDriverManager
from datetime import datetime
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

driver = webdriver.Chrome(ChromeDriverManager().install())

action = ActionChains(driver)
url_path = pd.read_csv("urls_data.csv")
url_list = list(url_path['0'])
base_dir = './ctcfp.org'

for i in url_list:
    title1 = ''
    title = ''
    transcript = ''
    audio_path = ''
    audio = ''
    post_date = ''
    file_name = ''
    try:
        print(i)
        driver.get(i)
        time.sleep(5)
        CHECK=driver.find_element_by_xpath('//li[@class="jupiterx-post-meta-categories list-inline-item"]/a')
        CHECK=CHECK.text
        if CHECK=="Podcasts":
            title1 = driver.find_element_by_xpath('//div[@class="container-fluid"]/h1')
            title = title1.text
            print(title)
            # transcript = driver.find_element_by_xpath('//div[@class="jet-button__container"]/a')
            # transcript = transcript.get_attribute('href')
            date_ = driver.find_element_by_xpath('//li[@class="jupiterx-post-meta-date list-inline-item"]/time')
            date_ = date_.text
            from dateutil.parser import parse

            date_ = parse(date_, fuzzy=True)
            print(date_, 'parse')
            post_date = datetime.strptime(str(date_), '%Y-%m-%d %H:%M:%S').strftime('%m/%d/%Y')
            print(post_date, "post_date")
            file_name = title.replace(" ", "_")
            if os.path.exists('./ctcfp.org/' + file_name):
                pass
            else:
                time.sleep(10)
                try:
                    try:
                        try:
                            audio_path = driver.find_element_by_xpath('//div[@class="jet-button__container"]/a')
                        except:
                            audio_path = driver.find_element_by_xpath('//div[@class ="jupiterx-content"]/article/div/div[1]/ul/li[1]/a')
                    except:
                        audio_path = driver.find_element_by_xpath('//div[@class="jupiterx-post-content clearfix"]/div/div[1]/a')
                    link = audio_path.get_attribute('href')
                    print(link, "audio_link")
                    text = "audio_file"
                    params = {
                        "ie": "UTF-8",
                        "client": "tw-ob",
                        "q": text,
                        "tl": "en",
                        "total": "1",
                        "idx": "0",
                        "textlen": str(len(text))
                    }
                    response = requests.get(link, params=params)
                    response.raise_for_status()

                    assert response.headers["Content-Type"] == "audio/mpeg"
                    with open("output.mp3", "wb") as file:
                        file.write(response.content)
                    print("Done.")

                    os.rename("output.mp3", file_name + ".mp3")
                    path = os.path.join(base_dir, file_name)
                    os.mkdir(path)
                    try:
                        try:
                            driver.find_element_by_xpath('//div[@class="elementor-container elementor-column-gap-default"]/div[2]/div/div/div/div/div/a/div[4]/span').click()
                        except:
                            driver.find_element_by_xpath('//div[@class ="jupiterx-content"]/article/div/div[1]/ul/li[2]/a').click()
                    except:
                        try:
                            driver.find_element_by_xpath('//div[@class="jupiterx-post-content clearfix"]/ul/li[1]/a').click()
                        except:
                            driver.find_element_by_xpath('//div[@class="jupiterx-post-content clearfix"]/div/div[2]/a').click()
                    time.sleep(20)
                    filepath = '/home/webtunixi5/Downloads'
                    filename = max([filepath + "/" + f for f in os.listdir(filepath)], key=os.path.getctime)
                    print(filename)
                    time.sleep(10)
                    shutil.move(os.path.join('.', filename), file_name + '_orig.docx')
                    text = docx2txt.process(file_name + '_orig.docx')
                    time.sleep(5)
                    with open(file_name + '_orig.txt', 'w') as f:
                        for line in text:
                            f.write(line)
                    with open(file_name + '.txt', 'w') as f:
                        for line in title:
                            f.write(line)
                    with open(file_name + '_info.txt', 'w') as f:
                        f.write(i + '\n')
                        f.write(post_date)
                    print("Scraped transcript data")

                    shutil.move(file_name + ".mp3", path + "/" + file_name + ".mp3")
                    print('audio moved successful')
                    shutil.move(file_name + '_orig.txt', path + '/' + file_name + '_orig.txt')
                    shutil.move(file_name + '.txt', path + '/' + file_name + '.txt')
                    shutil.move(file_name + '_info.txt', path + '/' + file_name + '_info.txt')
                    print("Done.")
                    if os.path.exists('./'+file_name + '_orig.docx'):
                        os.remove('./'+file_name + '_orig.docx')
                except Exception as e:
                    print(e)
                    pass
        else:
            print("Not a podcast.")
            pass
    except Exception as e:
        print("++++++++++++++++++")
        pass


import sys
input = sys.stdin.readline

n = int(input())
sell = {}

for i in range(n):
    name = input()
    if name not in sell:
        sell[name] = 1
    else:
        sell[name] += 1

max_value = max(sell.values())

best = []
for key, value in sell.items():
    if value == max_value:
        best.append(key)

best = sorted(best)
print(best[0])


import numpy as np

from collaborativefiltering import top_users, b2
from cfub import cfub

from cfib import recommend_similar_books
from new import new_user

# Initialisation de l'utilisateur
def run():
    print("(paramètre de requête API) : ID utilisateur, ou 'NEW' pour un nouvel utilisateur.")
    print("Liste d'ID utilisateur ayant servi à entraîner l'IA.",top_users, "\n")
    ID = input()
    print ('(paramètre de requête API) : au moins un genre de livre renseigné par l\'utilisateur parmis la liste \n')
    reco_u1 = new_user()
    print('(paramètre de requête API) : id du livre actuellement ou récemment consulté\n', b2)
    iid = int(input())
    if ID.isnumeric():
        if int(ID) in top_users:
            cfub(int(ID))
        else :
            print('l\'id renseigné n\'est pas dans la liste proposée')
    print("(réponse de requête API) recommandation basée sur les genres favoris :\n", list(reco_u1['original_title']))
    recommend_similar_books(iid)

run()


import torch
from safetensors.torch import save_file
import argparse
from pathlib import Path

def main(args):
    input_path = Path(args.input_path).resolve()
    output_path = args.output_path
    overwrite = args.overwrite

    if input_path.suffix == ".safetensors":
        raise ValueError(
            f"{input_path} is already a safetensors file. / {input_path} は既に safetensors ファイルです。"
        )

    if output_path is None:
        output_path = input_path.parent / f"{input_path.stem}.safetensors"
    else:
        output_path = Path(output_path).resolve()

    if output_path.exists() and not overwrite:
        raise FileExistsError(
            f"{output_path.name} already exists. Use '--overwrite' or '-w' to overwite. / {output_path.name} は既に存在します。'--overwrite' か '-w' を指定すると上書きします。"
        )

    print(f"Loading...")

    model = torch.load(input_path, map_location="cpu")
    save_file(model, output_path)

    print("Done!")

    print(f"Saved to {output_path} /\n {output_path} に保存しました。")

if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument(
        "input_path",
        type=str,
        help="input path",
    )
    parser.add_argument(
        "--output_path",
        "-o",
        type=str,
        help="output path",
    )
    parser.add_argument(
        "--overwrite",
        "-w",
        action="store_true",
        help="overwrite output file",
    )
    args = parser.parse_args()

    main(args)