import os
import openai
import json
from keys import openai_APIKEY, openai_BASE, zhipuai_APIKEY
import zhipuai
from datetime import datetime
import re
class GPTProcessor:
    def __init__(self):
        openai.api_key = openai_APIKEY
        openai.api_base = openai_BASE
        zhipuai.api_key = zhipuai_APIKEY
        self.id = 0

    def ask_chatgpt(self, my_messages): #可以做异步，和GPT连接请求发出后，在全部完成前可以切换到其它线程
        print({"role": "user", "content": my_messages[0]['content'] + '\n' + my_messages[1]['content']})
        response = zhipuai.model_api.sse_invoke(
            model="chatglm_pro",
            prompt=[
                {"role": "user", "content": my_messages[0]['content']},
                {"role": "assistant", "content": "好的"},
                {"role": "user", "content": my_messages[1]['content']},
            ],
            temperature=0.95,
            top_p=0.1,
            incremental=True
        )
        result = ''
        for event in response.events():
            if event.event == "add":
                result += event.data
        #delete ' ' from the first
        while (len(result) > 0 and result[0] == ' '):
            result = result[1:]
        print('ANS=',result)
        return result

    # def ask_chatgpt(self, my_messages): #可以做异步，和GPT连接请求发出后，在全部完成前可以切换到其它线程
    #     ans = openai.ChatCompletion.create(
    #             model="gpt-3.5-turbo",
    #             messages=my_messages,
    #         ).choices[0].message.content
    #     print('ANS=',ans)
    #     return ans

    def txt2json(self, text):
        result = self.ask_chatgpt(text)
        return result

    def first_guess(self,title,text):
        my_messages = [
            {"role": "system", "content": "根据下面这个标题和部分文字，你觉得是否可能是某种活动 的 预告 售票 报名，请直接告诉我答案为'是'或'否'。请不要回复任何其它内容。请回复一个字，不要回复多个字。如果是活动的总结请返回'否'，如果你觉得不确定，也请回复'是'。请严格地以唯一的格式回复我"},
            {"role": "user", "content": title + '\n' + text[:20]},
        ]
        ans = self.ask_chatgpt(my_messages)
        if ans == '否':
            return False
        return True

    def Text_to_JSON(self, text):
        try:
            my_messages = [
                {"role": "system", "content": "Now that you are engaged in professional text processing, please let me know if the push below is a preview of an event (such as a lecture or ticket collection) （不包括活动总结). If so, please use JSON format to tell me the 'event_name', 'event_time', 'location', 'organizational_unit'. 时间尽可能规范到特定的时刻，如果有多个时间请一并输出，如没有则以null存在，推送发布时间为2023年，如果有多个活动，请返回list，如果没有则返回空list。Otherwise, tell me the activity category it belongs to. please use JSON format!去除内容中的所有引号的存在"},
                {"role": "user", "content": text + "please use JSON format!! 如果出现了内容中的引号,请不要存在,以防止json格式无法读取"},
            ]
            infolist = self.ask_chatgpt(my_messages)
            infolist = infolist.replace('\n', ' ')
        except:
            my_messages = [
                {"role": "system", "content": "请获取下文（这是一篇推送的前半部分）的摘要，不要忽略所有的，时间，地点，主办方，主题，摘要，尤其是时间"},
                {"role": "user", "content": text[-1500:]},
            ]
            summary1 = self.ask_chatgpt(my_messages)
            my_messages = [
                {"role": "system", "content": "Now that you are engaged in professional text processing, please let me know if the push below is a preview of an event (such as a lecture or ticket collection) (不包括活动总结). If so, please use JSON format to tell me the 'event_name', 'event_time', 'location', 'organizational_unit'. 时间尽可能规范到特定的时刻，如果有多个时间请一并输出，如没有则以null存在，推送发布时间为2023年。Otherwise, tell me the activity category it belongs to."},
                {"role": "user", "content": summary + '\n' + text[:-1500]},
            ]
            infolist = self.ask_chatgpt(my_messages)
            infolist = infolist.replace('\n', ' ')

        try:
            # print(infolist)
            #contrive json from string, from first '{ to the first '}' after the first '{'
            json_list = infolist[infolist.find('{'):infolist.find('}')+1]
            json_list = json.loads(json_list)
            my_messages = [
                {"role": "system", "content": "请获取下面活动信息的摘要，请包含主要内容但不要太长，请以描述的方式返回，请直接返回摘要，不要回答任何其它内容"},
                {"role": "user", "content": text},
            ]
            zhaiyao = self.ask_chatgpt(my_messages)
            # zhaiyao = zhaiyao.replace('\n', ' ')
            # zhaiyao = zhaiyao.replace(' ', '')
            # zhaiyao = zhaiyao[zhaiyao.find('{'):zhaiyao.find('}')+1]
            #add event_summary : zhaiyao to json_list
            json_list['event_summary'] = zhaiyao

        except Exception as e:
            print('Error: json.loads error')
            print(e)
            return []
        if type(json_list) != list:
            json_list = [json_list]
        should_exist = ['event_name', 'event_time', 'location', 'organizational_unit', 'event_summary']
        result_list = []
        for info in json_list:
            all_exist = True
            for key in should_exist:
                if key not in info:
                    print('Error: ', key, ' not exist')
                    all_exist = False
                    break
            if not all_exist:
                continue

            ask_time_message = [
                {"role": "system", "content": "提取下面的时间中最早的时刻，并严格转化为以 ????-??-?? ??:??:?? 的格式回复我。如果没有时间，请回复'没有'，以上格式代表年月日时分秒，如2023-09-11 15:00:00。严格转化格式，不要是其它的格式，必须以`-`和`:`分割，且每个部分都是数字。请一定保留 秒，即使没有显示的表现，默认以 00 填充"},
                {"role": "user", "content": str(info.get('event_time', None))},
            ]
            start_time_str = self.ask_chatgpt(ask_time_message)
            pattern = r'(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})'
            match = re.search(pattern, start_time_str)
            if match is None:
                pattern = r'(\d{4}-\d{2}-\d{2} \d{2}:\d{2})'
                match = re.search(pattern, start_time_str)
            try:
                extracted_datetime = match.group(1)
                start_time = str(extracted_datetime)
                if len(start_time) == 16:
                    start_time += ':00'
            except Exception as e:
                print('Error: datetime.strptime error')
                print(e)
                continue

            ask_time_message = [
                {"role": "system", "content": "提取下面的时间中最晚的时刻，并严格转化为以 ????-??-?? ??:??:?? 的格式回复我。如果没有时间，请回复'没有'，以上格式代表年月日时分秒，如2023-09-11 15:00:00。严格转化格式，不要是其它的格式，必须以`-`和`:`分割，且每个部分都是数字。请一定保留 秒，即使没有显示的表现，默认以 00 填充"},
                {"role": "user", "content": str(info.get('event_time', None))},
            ]
            end_time_str = self.ask_chatgpt(ask_time_message)
            pattern = r'(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})'
            match = re.search(pattern, end_time_str)
            if match is None:
                pattern = r'(\d{4}-\d{2}-\d{2} \d{2}:\d{2})'
                match = re.search(pattern, end_time_str)
            try:
                extracted_datetime = match.group(1)
                end_time = str(extracted_datetime)
                if len(end_time) == 16:
                    end_time += ':00'
            except:
                print('Error: datetime1.strptime error')
                continue

            json_data = {
                'event_name': info.get('event_name', None),
                'date1': start_time[:10],
                'time1': start_time[11:],
                'date2': end_time[:10],
                'time2': end_time[11:],
                'event_time': str(info.get('event_time', None)),
                'location': info.get('location', None),
                'organizational_unit': info.get('organizational_unit', None),
                'event_summary': info.get('event_summary', None),
            }
            print(json_data)
            result_list.append(json_data)
        return result_list

    def process_dir(self, current_dir):
        for filename in os.listdir(current_dir):
            try:
                file_path = os.path.join(current_dir, filename)

                if os.path.isdir(file_path):
                    self.process_dir(file_path)

                elif filename.endswith('.txt'):
                    with open(file_path,encoding='utf-8') as f:
                        text = f.read()
                    json_data = self.Text_to_JSON(text)

            except:
                print('Error processing file: ', filename)
                continue
        print('Done!')

if __name__ == '__main__':
    test_text = '''
    你是煞笔
'''
    processor = GPTProcessor()
    print ( processor.Text_to_JSON(test_text) )


"""
Streaming and collision step
============================
The streaming step is the first step of the Lattice Boltzmann Method (LBM).
The streaming step is a simple shift of the pdf in the direction of the
velocity. The collision step is the second step of the LBM. The collision step
is a relaxation of the pdf towards the equilibrium pdf. The equilibrium pdf is
the pdf that would be obtained if the fluid particles were in equilibrium. The
equilibrium pdf is calculated using the density and the velocity of the fluid
particles.
============================
"""

import numpy as np
import matplotlib.pyplot as plt
from hpc_fluid_dynamics.lbm_utils import *
from matplotlib import animation
from array2gif import write_gif

omega = 1
pdf = init_pdf(mode="circle")

n_steps = 1000
arrays = []

for i in range(n_steps):
    if i % 100 == 0:
        print("step ", i)

    # MOMENT UPDATE
    density = calc_density(pdf)
    local_avg_velocity = calc_local_avg_velocity(pdf)

    # EQULIBRIUM
    equilibrium_pdf = calc_equilibrium_pdf(density, local_avg_velocity)

    # COLLISION STEP
    pdf = pdf + omega*(equilibrium_pdf - pdf)

    # STREAMING STEP
    pdf = streaming(pdf)

    # SAVE FOR PLOTTING
    arrays.append(calc_density(pdf))

    print("density: ", density[125, 125])

# PLOT
# add color channel in order to work with array2gif
arrays = np.array(arrays)[..., np.newaxis] * np.ones(3)
# normalize
arrays = arrays / np.max(arrays) * 255
write_gif(arrays, 'results/ml2_serial_cluster.gif', fps=30)


#Let’s start with an easy one. Determine the order of all elements of the multi-
#plicative groups of:
#1. Z∗5
#2. Z∗7
#3. Z∗13

# EJERCICIO 8 del libro "Undestanding Cryptography"
from Crypto.Util.number import GCD

def generateOrd(mod):

    x=[]
    for num in range(1, mod):
        x.append(num)
    print(f'\nRango manejado: {x}', end='')

    matrix=[[(i*j)%mod for j in range (mod)] for i in range(mod)]
    #Mostrar la matriz sin el 0
    print("\nMatriz: ")
    for i in range(mod):
        for j in range(mod):
            if matrix[i][j]!=0:
                print(matrix[i][j],end=" ")
            else:
                print("",end="")
        print()

    #Mostrar la diagonal de la matriz
    print("Diagonal: ",end="")
    for i in range(mod):
        if matrix[i][i]!=0:
            print(matrix[i][i],end=" ")
        else:
            print("",end="")
    print(f'\nGenerador de {mod}: {find_primitive_roots(mod)}')

def is_primitive_root(g, p):
    order = 1
    while pow(g, order, p) != 1:
        order += 1
    return order == (p - 1)

def find_primitive_roots(p):
    primitive_roots = []
    for g in range(2, p):
        if is_primitive_root(g, p):
            primitive_roots.append(g)
    return primitive_roots

print(f'\n[+] Generators:')
z4969=find_primitive_roots(4969)
print(f'[+] z4969: {len(z4969)}')

#Determine the smallest generator a ∈ Z∗4969 with a > 1000.
print(f'\n[+] Determine the smallest generator a ∈ Z∗4969 with a > 1000.')
print(f'[+] z4969: {z4969[0]}')

## What measures can be taken in order to simplify the search for generators for arbitrary groups Z∗p?
# a: Se puede hacer una lista de los generadores de los grupos y buscar en esa lista


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

import rospy
import readchar
from threading import Thread
from geometry_msgs.msg import PointStamped
from autoware_msgs.msg import DetectedObject, DetectedObjectArray
from visualization_msgs.msg import Marker

class ObstacleGenerator:
    def __init__(self):

        # Run separate thread for controlling point obstacle using keyboard
        thread = Thread(target=self.control_point_obs, args=())
        thread.start()

        # Bool to check if simulation mode is enabled
        self.enable_simulation_mode = rospy.get_param(
            "~enableSimulationMode", default=False)

        # Subscribers
        rospy.Subscriber("/clicked_point",
                         PointStamped, self.clicked_point_callback)

        # If simulation mode is enabled then subscribe to simulated objects and append point obstacle in DetectedObjectArray
        if self.enable_simulation_mode:
            rospy.Subscriber("/detection/contour_tracker/objects",
                             DetectedObjectArray, self.detected_objects_callback)

        # Publishers
        self.point_marker_pub = rospy.Publisher(
            "/point_marker", Marker, queue_size=1)

        self.updated_detections = rospy.Publisher(
            "/detection/objects", DetectedObjectArray, queue_size=1)

        self.point_obstacle = DetectedObject()

    def detected_objects_callback(self, msg):
        """ Callback to recieve simulated tracked vehicle obstacles

        Parameters
        ----------
        msg : DetectedObjectArray
            Array of all simulated tracked objects
        """

        self.point_obstacle.id = msg.objects[-1].id + 1
        self.point_obstacle.pose.position.z = msg.objects[0].pose.position.z
        msg.objects.append(self.point_obstacle)

        self.point_marker_pub.publish(self.get_curr_marker(
            msg.header.stamp, msg.header.frame_id))
        self.updated_detections.publish(msg)

    def clicked_point_callback(self, msg):
        """ Callback to get latest published point in rviz

        Parameters
        ----------
        msg : PointStamped
            Location of published point in rviz
        """

        self.point_obstacle.pose.position = msg.point

    def get_curr_marker(self, stamp, frame_id):
        """ Creates marker message for visualizing static obstacle in rviz

        Parameters
        ----------
        stamp : rospy.Time
            Time stamp on which the marker should be visualized
        frame_id : str
            Frame ID of the marker

        Returns
        -------
        Marker
            A sphere marker created over the latest published point location
        """

        marker = Marker()
        marker.type = marker.SPHERE
        marker.header.frame_id = frame_id
        marker.header.stamp = stamp
        marker.scale.x = 2
        marker.scale.y = 2
        marker.scale.z = 2
        marker.color.r = 0.8
        marker.color.g = 0
        marker.color.b = 1
        marker.color.a = 1
        marker.pose = self.point_obstacle.pose

        return marker

    def publish_point_obs_loop(self):
        """
        Publishes point obstacle if simulation mode is not enabled
        """

        if not self.enable_simulation_mode:
            while not rospy.is_shutdown():
                msg = DetectedObjectArray()
                msg.header.frame_id = "map"
                msg.header.stamp = rospy.Time.now()
                self.point_obstacle.id = 1
                self.point_obstacle.pose.position.z = 34.0
                msg.objects.append(self.point_obstacle)

                self.point_marker_pub.publish(
                    self.get_curr_marker(rospy.Time.now(), "map"))

                self.updated_detections.publish(msg)
                rospy.Rate(10).sleep()

    def control_point_obs(self):
        """
        Control current point obstacle using keyboard
        """

        while not rospy.is_shutdown():
            key = repr(readchar.readchar())

            if key == repr('\x03'):
                rospy.loginfo("Shutting down ...")
                rospy.signal_shutdown("")
                exit(0)

            if key == repr('8'):
                self.point_obstacle.pose.position.y += 0.5
            elif key == repr('5'):
                self.point_obstacle.pose.position.y -= 0.5
            elif key == repr('4'):
                self.point_obstacle.pose.position.x -= 0.5
            elif key == repr('6'):
                self.point_obstacle.pose.position.x += 0.5

    def run(self):
        self.publish_point_obs_loop()
        rospy.spin()

if __name__ == '__main__':
    rospy.init_node('obstacle_generator',
                    anonymous=False, log_level=rospy.INFO)
    node = ObstacleGenerator()
    node.run()


from typing import Any, Dict, List, Type, TypeVar, Union

import attr

from ..types import UNSET, Unset

T = TypeVar("T", bound="LanguageForm")

@attr.s(auto_attribs=True)
class LanguageForm:
    """
    Attributes:
        language_code (Union[Unset, str]):
        country_code (Union[Unset, str]):
        language (Union[Unset, str]):
        country (Union[Unset, str]):
    """

    language_code: Union[Unset, str] = UNSET
    country_code: Union[Unset, str] = UNSET
    language: Union[Unset, str] = UNSET
    country: Union[Unset, str] = UNSET
    additional_properties: Dict[str, Any] = attr.ib(init=False, factory=dict)

    def to_dict(self) -> Dict[str, Any]:
        language_code = self.language_code
        country_code = self.country_code
        language = self.language
        country = self.country

        field_dict: Dict[str, Any] = {}
        field_dict.update(self.additional_properties)
        field_dict.update({})
        if language_code is not UNSET:
            field_dict["languageCode"] = language_code
        if country_code is not UNSET:
            field_dict["countryCode"] = country_code
        if language is not UNSET:
            field_dict["language"] = language
        if country is not UNSET:
            field_dict["country"] = country

        return field_dict

    @classmethod
    def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T:
        d = src_dict.copy()
        language_code = d.pop("languageCode", UNSET)

        country_code = d.pop("countryCode", UNSET)

        language = d.pop("language", UNSET)

        country = d.pop("country", UNSET)

        language_form = cls(
            language_code=language_code,
            country_code=country_code,
            language=language,
            country=country,
        )

        language_form.additional_properties = d
        return language_form

    @property
    def additional_keys(self) -> List[str]:
        return list(self.additional_properties.keys())

    def __getitem__(self, key: str) -> Any:
        return self.additional_properties[key]

    def __setitem__(self, key: str, value: Any) -> None:
        self.additional_properties[key] = value

    def __delitem__(self, key: str) -> None:
        del self.additional_properties[key]

    def __contains__(self, key: str) -> bool:
        return key in self.additional_properties


import datetime

from .service import ServiceStubber

class ExternalAccountStubber(ServiceStubber):

    client_service = "sts"

    def add_assume_role(self):
        return self.add_response(
            "assume_role",
            service_response={
                "Credentials": {
                    "AccessKeyId": "AKIASSUMEROLEASSUMEROLE",
                    "SecretAccessKey": "abcdefghijklmnopqrstuvwxyz",
                    "SessionToken": "zyxwvutsrqpnomlkjihgfedcba",
                    "Expiration": datetime.datetime.now(),
                }
            },
            expected_params={
                "RoleSessionName": "session-name",
                "RoleArn": "arn:aws:iam::123456789012:role/S3Access",
            },
        )


from datetime import datetime
from flask import abort, make_response

def getTimeStamp():
    return datetime.now().strftime(("%Y-%m-%d %H:%M:%S"))

PEOPLE = {
    "Fairy": {
        "fname": "Tooth",
        "lname": "Fairy",
        "timestamp": getTimeStamp(),
    },
    "Ruprecht": {
        "fname": "Knecht",
        "lname": "Ruprecht",
        "timestamp": getTimeStamp(),
    },
    "Bunny": {
        "fname": "Easter",
        "lname": "Bunny",
        "timestamp": getTimeStamp(),
    }
}

def readAll():
    return list(PEOPLE.values())

def create(person):
    lname: str = person.get("lname")
    fname: str = person.get("fname")

    if (lname and lname not in PEOPLE):
        PEOPLE[lname] = {
            "fname": fname,
            "lname": lname,
            "timestamp": getTimeStamp(),
        }
    else:
        abort(
            406, f"Person with lastname {lname} already exists"
        )

    return PEOPLE[lname], 201

def readOne(lname: str):
    if lname in PEOPLE:
        return PEOPLE[lname]
    else:
        abort(
            404, f"Person with last name {lname} not found"
        )

def update(lname, person):
    if lname in PEOPLE:
        PEOPLE[lname]["fname"] = person.get("fname", PEOPLE[lname]["fname"])
        PEOPLE[lname]["timestamp"] = getTimeStamp()
        return PEOPLE[lname]
    else:
        abort(
            404,
            f"Person with last name {lname} not found"
        )

def delete(lname):
    if lname in PEOPLE:
        del PEOPLE[lname]
        return make_response(
            f"{lname} successfully deleted", 200
        )
    else:
        abort(
            404,
            f"Person with last name {lname} not found"
        )


#! /usr/bin/env python3

from ecp_class import *

ecp_list = {'Bi':78, 'Te':46, 'I':46, 'Mo':28, 'W':60, 'Ir':60, 'Pd':28, 'Ag':28, 'Au':60}

for ecp in ecp_list:
    os.chdir(ecp)

    my_ecp = ECP(element = ecp, core = ecp_list[ecp])
    my_ecp.read_ecp_so('pp.d')

    my_ecp.write_molpro(ecp+ '.ccECP.molpro')
    my_ecp.write_nwchem(ecp+ '.ccECP.nwchem')
    my_ecp.write_gamess(ecp+ '.ccECP.gamess')
    my_ecp.write_dirac(ecp+ '.ccECP.dirac')
    my_ecp.write_qwalk_so(ecp+ '.ccECP.qwalk')
    my_ecp.write_manuscript(ecp+ '.ccECP.man')

    os.chdir('../')


"""
5.4 Примеры работы оператора цикла for. Функция enumerate

Подвиг 5. Вводится список в виде целых чисел в одну строку через пробел.
Сначала нужно сформировать список из введенной строки. Затем, каждый элемент
этого списка продублировать один раз. Результат отобразить на экране в виде строки
полученных чисел, записанных через пробел.

Sample Input: 8 11 2
Sample Output: 8 8 11 11 2 2
"""
# Сохраняем в список
numbers_list = list(map(str, input().split()))
string = '' # Делаем пустую строку

for index, value in enumerate(numbers_list): # Сохраняем в список  и перебираем его с помощью enumerate
    string += value + ' ' + value + " " # Ставлю два значения через пробел на каждой итерации

print(string)


import os.path as osp
import os
import glob
import cv2
import numpy as np
import torch
import RRDBNet_arch as arch
import argparse

# RRDB_ESRGAN_x4.pth OR RRDB_PSNR_x4.pth
model_path = "E:\\GAN\\weights\\esrgan\\RRDB_ESRGAN_x4.pth"
output_path = "E:\\GAN\\data\\esrgan"

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

def parse_arg():
    parser = argparse.ArgumentParser()
    parser.add_argument('--input_img_dir_path', help='Image dir', default='E:\\GAN\\data\\baseline')
    parser.add_argument('--output_img_dir_path', type=str, default='E:\\GAN\\data\\esrgan')
    parser.add_argument('--width', help='image width', type=int, default=28)
    parser.add_argument('--height', help='image height', type=int, default=28)
    return parser.parse_args()

def generate_image(input_img_path, output_image_path, img_dim):
    model = arch.RRDBNet(3, 3, 64, 23, gc=32)
    model.load_state_dict(torch.load(model_path), strict=True)
    model.eval()
    model = model.to(device)

    print("Model path {:s}. \nTesting...".format(model_path))

    idx = 0
    for path in glob.glob(input_img_path):
        idx += 1
        base = osp.splitext(osp.basename(path))[0]
        print(idx, base)
        print('Successful !')
        # read images
        img = cv2.imread(path, cv2.IMREAD_COLOR)
        img = img * 1.0 / 255
        img = torch.from_numpy(np.transpose(
            img[:, :, [2, 1, 0]], (2, 0, 1))).float()
        img_LR = img.unsqueeze(0)
        img_LR = img_LR.to(device)

        with torch.no_grad():
            output = model(img_LR).data.squeeze(
            ).float().cpu().clamp_(0, 1).numpy()
        output = np.transpose(output[[2, 1, 0], :, :], (1, 2, 0))
        output = (output * 255.0).round()
        resized = cv2.resize(output, img_dim, interpolation=cv2.INTER_AREA)
        print('Resized Dimensions : ', resized.shape)
        if not os.path.exists(output_image_path):
            os.makedirs(output_image_path)
        cv2.imwrite(os.path.join(output_image_path,
                                 "{:s}_esrgan.jpg".format(base)), resized)

args = parse_arg()
dim = (args.width, args.height)
for class_number in range(10):
    for type in ["train", "val", "test"]:
        input_img_path = os.path.join(args.input_img_dir_path, type, f"{class_number}/*")
        output_image_path = os.path.join(args.output_img_dir_path, type, f"{class_number}")

        generate_image(input_img_path, output_image_path, dim)


import torch
import torch.nn as nn
import torchvision
import torchvision.transforms as trans
import os
import numpy as np
from torch.utils.data import Dataset, DataLoader
from torchvision.transforms import ToTensor
from torchvision import datasets, transforms
from torch.nn.modules.utils import _single, _pair, _triple

inpsiz = 784
hidensiz = 500
numclases = 10
numepchs = 100
bachsiz = 32
l_r = 0.001

data = np.load('data.npy')
test_data = np.load('test_data.npy')
label = np.load('label.npy')
test_label = np.load('test_label.npy')

device = 'cuda' if torch.cuda.is_available() else 'cpu'

def quantize(v, bit=4):
    factor = torch.max(torch.relu(v)) * (2**(bit-1))
    return (v*factor).int()

class MyConv2d(torch.nn.modules.conv._ConvNd):
    """
    Implements a standard convolution layer that can be used as a regular module
    """

    def __init__(self, in_channels, out_channels, kernel_size, stride=1,
                 padding=0, dilation=1, groups=1,
                 bias=True, padding_mode='zeros', use_Q=True):
        kernel_size = _pair(kernel_size)
        stride = _pair(stride)
        padding = _pair(padding)
        dilation = _pair(dilation)
        super(MyConv2d, self).__init__(
            in_channels, out_channels, kernel_size, stride, padding, dilation,
            False, _pair(0), groups, bias, padding_mode)
        self.use_Q = use_Q

    def reset_Q(self):
        self.Q_weight = quantize(torch.tensor(self.weight.view(self.weight.size(0), -1).t()))

    def forward(self, input):
        return myconv2d(input, self.weight, self.bias, self.stride,
                        self.padding, self.dilation, self.groups, self.Q_weight, self.use_Q)

def myconv2d(input, weight, bias=None, stride=(1, 1), padding=(0, 0), dilation=(1, 1), groups=1, Q=None,  use_Q=True):
    """
    Function to process an input with a standard convolution
    """
    batch_size, in_channels, in_h, in_w = input.shape
    out_channels, in_channels, kh, kw = weight.shape
    out_h = int((in_h - kh + 2 * padding[0]) / stride[0] + 1)
    out_w = int((in_w - kw + 2 * padding[1]) / stride[1] + 1)
    unfold = torch.nn.Unfold(kernel_size=(kh, kw), dilation=dilation, padding=padding, stride=stride)
    inp_unf = unfold(input)
    w_ = weight.view(weight.size(0), -1).t()    # w_(9, 32)

    X = inp_unf.transpose(1, 2)
    out_unf = (X @ w_ + bias)

    q_X = quantize(X)
    q_bias = quantize(bias)
    upper = quantize(q_X @ Q + q_bias)

    mask = (upper <= 0)

    if use_Q:
        out_unf[mask] = 0

    out_unf = out_unf.transpose(1, 2)
    out = out_unf.view(batch_size, out_channels, out_h, out_w)  # (1, 32, 26, 26)
    return out.float()

nn.Conv2d = MyConv2d

class MyDS(Dataset):
    """Face Landmarks dataset."""

    def __init__(self, data, label, transform=None):
        self.data = data
        self.label = label
        self.transform = transform

    def __len__(self):
        return len(self.data)

    def __getitem__(self, idx):
        x = self.data[idx]
        y = self.label[idx]

        if self.transform:
            return self.transform(torch.tensor(x.reshape(1, 28, 28), dtype=torch.float32)), torch.tensor(y,
                                                                                dtype=torch.long)
        else:
            return torch.tensor(x, dtype=torch.float32), torch.tensor(y, dtype=torch.long)

t = transforms.Compose([
    transforms.Normalize(mean=(0.5,), std=(0.5,))
])

ds = MyDS(data, label, t)
test_ds = MyDS(test_data, test_label, t)

trainldr = torch.utils.data.DataLoader(dataset=ds,
                                       batch_size=bachsiz,
                                       shuffle=True)
test_trainldr = torch.utils.data.DataLoader(dataset=test_ds,
                                            batch_size=1000)

print('train data len is ', len(trainldr.dataset))
print('test data len is ', len(test_trainldr.dataset))

class neural_network(nn.Module):
    def __init__(self):
        super(neural_network, self).__init__()
        self.conv1 = nn.Conv2d(1, 32, 3, 1, use_Q=True)
        self.conv2 = nn.Conv2d(32, 64, 3, 1, use_Q=False)
        self.dropout1 = nn.Dropout(0.25)
        self.dropout2 = nn.Dropout(0.5)
        self.fc1 = nn.Linear(9216, 128)
        self.fc2 = nn.Linear(128, 10)

    def forward(self, x):
        x = self.conv1(x)
        x = torch.relu(x)
        x = self.conv2(x)
        x = torch.relu(x)
        x = torch.max_pool2d(x, 2)
        x = self.dropout1(x)
        x = torch.flatten(x, 1)
        x = self.fc1(x)
        x = torch.relu(x)
        x = self.dropout2(x)
        x = self.fc2(x)
        return x

modl = neural_network().to(device)
modl.load_state_dict(torch.load('cnn.pt', map_location=device), strict=False)

modl.conv1.reset_Q()
modl.conv2.reset_Q()

modl.eval()
with torch.no_grad():
    correct = 0
    total = 0
    for x, (imgs, lbls) in enumerate(test_trainldr):
        imgs = imgs.reshape(-1, 1, 28, 28).to(device)
        lbls = lbls.to(device)
        outp = modl(imgs)
        pred = outp.data.max(1, keepdim=True)[1].to(device)
        correct += pred.eq(lbls.data.view_as(pred)).sum().detach().cpu().item()
        total += torch.numel(pred)
    print('Acc = {}'.format(correct / total))

torch.save(modl.state_dict(), 'cnn.pt')


from __future__ import annotations

from raincoat import metadata as _metadata_module
from raincoat.match import Checker, Match, NotMatching

__all__ = ["Match", "Checker", "NotMatching"]

_metadata = _metadata_module.extract_metadata()
__author__ = _metadata["author"]
__author_email__ = _metadata["email"]
__license__ = _metadata["license"]
__url__ = _metadata["url"]
__version__ = _metadata["version"]


import numpy as np
from src.utils.common import *

class RewardShaper(object):
    def __init__(self,args):
        self.metric = args.metric
        self.shaping = args.shaping
        self.entcoef = args.entcoef
        self.gamma = 0.5
        self.rate = 0.05
        self.alpha = args.frweight # to make tune the ratio of finalreward and midreward
        if "0" in self.shaping and "1" in self.shaping:
            raise ValueError("arguments invalid")
        self.hashistorymean,self.hashistoryvar = False,False
        if "3" in self.shaping:
            self.historymean = np.zeros((1000,args.batchsize))
        if "4" in self.shaping:
            self.histrvar = np.zeros((1000,args.batchsize))
        pass

    def reshape(self,rewards_all,finalrewards_all,logprobs):
        rewards_sub, finalrewards = self._roughProcess(rewards_all,finalrewards_all)
        self.componentRatio(rewards_sub,finalrewards,logprobs)
        rewards = np.zeros_like(rewards_sub)
        if "0" in self.shaping:
            rewards += rewards_sub
        if "1" in self.shaping:
            for i in range(rewards_sub.shape[0]-1,0,-1):
                rewards_sub[i-1] += self.gamma*rewards_sub[i]
            rewards += rewards_sub
        if "2" in self.shaping: #2
            rewards += finalrewards*self.alpha

        if "3" in self.shaping:
            if not self.hashistorymean:
                self.historymean[:rewards_sub.shape[0], :] += rewards.mean(1,keepdims=True)
                self.hashistorymean = True
            else:
                self.historymean[:rewards_sub.shape[0], :] = self.historymean[:rewards_sub.shape[0], :] * (1 - self.rate) + self.rate * rewards.mean(1,keepdims=True)
            rewards = rewards - self.historymean[:rewards.shape[0], :]

        if "4" in self.shaping:
            if not self.hashistoryvar:
                self.histrvar[:rewards_sub.shape[0], :] += (rewards**2).mean(1,keepdims=True)
                self.hashistoryvar = True
            else:
                self.histrvar[:rewards_sub.shape[0], :] = self.histrvar[:rewards.shape[0], :] * (
                            1 - self.rate) + self.rate * (rewards**2).mean(1,keepdims=True)
            rewards = rewards/np.power(self.histrvar[:rewards.shape[0], :],0.5)
        return rewards

    def _roughProcess(self,rewards_all,finalrewards_all):
        mic,mac = [np.array(x) for x in list(zip(*rewards_all))]
        finalmic,finalmac = [np.array(x) for x in finalrewards_all]
        if self.metric == "microf1":
            rewards = mic
            finalrewards = finalmic
        elif self.metric == "macrof1":
            rewards = mac
            finalrewards = finalmac
        elif self.metric == "mix":
            rewards = (mic+mac)/2
            finalrewards = (finalmic+finalmac)/2
        else:
            raise NotImplementedError("metric <{}> is not implemented".format(self.metric))
        rewards_sub = rewards[1:,:]-rewards[:-1,:]
        return rewards_sub,finalrewards

    def componentRatio(self,rewards_sub,finalrewards_all,logprobs):
        r_mean = np.mean(np.abs(rewards_sub))
        f_mean = np.mean(finalrewards_all)
        lp_mean = np.mean(np.abs(logprobs))
        f_ratio = f_mean/r_mean*self.alpha
        lp_ratio = lp_mean/r_mean*self.entcoef
        logger.debug("rmean {:.4f},fratio {:.2f}x{:.4f}={:.3f}, "
                    "lpratio {:.1f}x{:.5f}={:.3f}".format(r_mean,
                                                           f_mean/r_mean,self.alpha,f_ratio,
                                                           lp_mean/r_mean,self.entcoef,lp_ratio))


import os
import sys
import json
import zipfile
import construct
import argparse
import subprocess
import shutil
import importlib

import validators
import colorama
from Crypto.PublicKey import RSA

sys.path.append("..")

from Updater import settings
from Updater import registry
from Updater import rsa_signing
from Updater import updater
from Updater import messages
from Updater.messages import MessageType

DEFAULT_SETTINGS_PATH = "settings.json"
BUILD_DIRECTORY = "build"
SERVICE_EXECUTABLE = "service.exe"
LAUNCHER_EXECUTABLE = "launcher.exe"
PYINSTALLER_OUTPUT_DIR = "dist"
INSTALLER_SETUP_SCRIPT = "setup_script.iss"
INSTALLER_SETUP_TEMPLATE = "setup_template.iss"
INNO_SETUP_INSTALL_FOLDER = r"C:\Program Files (x86)\Inno Setup 6"
INNO_SETUP_COMPILER = os.path.join(INNO_SETUP_INSTALL_FOLDER, "ISCC.exe")

def load_settings():
    try:
        with open(DEFAULT_SETTINGS_PATH, "r") as settings_file:
            data = settings_file.read()
            return json.loads(data)
    except FileNotFoundError:
        # If settings file is not found, use default settings
        pass
    return dict()

def save_settings(values):
    try:
        with open(DEFAULT_SETTINGS_PATH, "w") as settings_file:
            data = json.dumps(values)
            settings_file.write(data)
    except PermissionError:
        return False
    return True

def add_to_settings(values):
    current_settings = load_settings()

    current_settings.update(values)
    return save_settings(current_settings)

def zip_directory(path, zip_handler):
    for root, dirs, files in os.walk(path):
        for file in files:
            file_path = os.path.join(root, file)
            relative_path = os.path.relpath(file_path, path)
            zip_handler.write(file_path, relative_path)

        for dir_name in dirs:
            dir_path = os.path.join(root, dir_name)
            relative_path = os.path.relpath(dir_path, path)
            zip_handler.write(dir_path, relative_path)

def generate_rsa_keys(display_keys=True):
    key_pair = RSA.generate(bits=settings.RSA_KEY_SIZE)

    # Adds the keys to settings file
    rsa_settings = dict(
        RSA_MODULO=hex(key_pair.n),
        PUBLIC_KEY=hex(key_pair.e),
    )
    if not add_to_settings(rsa_settings):
        print(f"Failed to add rsa key to {DEFAULT_SETTINGS_PATH}")
        return False

    # Adds the keys to registry
    if not registry.exists(settings.REGISTRY_PATH):
        registry.create_key(settings.REGISTRY_PATH)
    registry.set_value(settings.RSA_MODULO_REGISTRY, hex(key_pair.n))
    registry.set_value(settings.RSA_PUBLIC_REGISTRY, hex(key_pair.e))
    registry.set_value(settings.RSA_PRIVATE_REGISTRY, hex(key_pair.d))

    # Displays the keys to the user
    print("RSA keys were generated!")
    print("")
    if display_keys:
        show_rsa_keys()
    return True

def show_rsa_keys():
    print("RSA Modulo (n):")
    if registry.exists(settings.RSA_MODULO_REGISTRY):
        print(registry.get_value(settings.RSA_MODULO_REGISTRY))
    else:
        print("Not available.")
    print("")

    print("RSA Public Key (e):")
    if registry.exists(settings.RSA_PUBLIC_REGISTRY):
        print(registry.get_value(settings.RSA_PUBLIC_REGISTRY))
    else:
        print("Not available.")
    print("")

    print("RSA Private Key (d):")
    if registry.exists(settings.RSA_PRIVATE_REGISTRY):
        print(registry.get_value(settings.RSA_PRIVATE_REGISTRY))
    else:
        print("Not available.")
    return True

def show_server_information():
    address_id = "Not available"
    if registry.exists(settings.ADDRESS_ID_REGISTRY):
        address_id = registry.get_value(settings.ADDRESS_ID_REGISTRY)

    ip = "Not available"
    if registry.exists(settings.UPDATING_SERVER_REGISTRY):
        ip = registry.get_value(settings.UPDATING_SERVER_REGISTRY)

    port = "Not available"
    if registry.exists(settings.PORT_REGISTRY):
        port = registry.get_value(settings.PORT_REGISTRY)

    print(f"Address ID: \t{address_id}")
    print(f"Domain (IP): \t{ip}")
    print(f"Port: \t\t{port}")
    return True

def send_server_information(ip, port, spread=True):
    # Validates the ip or domain (syntax only)
    if validators.domain(ip) is not True:
        if validators.ip_address.ipv4(ip) is not True:
            if validators.ip_address.ipv6(ip) is not True:
                print(f"Failed to validate ip or domain: {ip}. Check for typing mistakes.")
                return False

    # Validates port number
    if validators.between(port, min=1, max=65535) is not True:
        print(f"Invalid port number: {port} is not between 1 and 65535")
        return False

    if not registry.exists(settings.ADDRESS_ID_REGISTRY):
        print(f"Address ID was not found in the registry! (Location: {settings.ADDRESS_ID_REGISTRY})")
        return False
    if not registry.exists(settings.RSA_PRIVATE_REGISTRY):
        print(f"RSA Private Key was not found in the registry! (Location: {settings.RSA_PRIVATE_REGISTRY})")
        return False
    address_id = registry.get_value(settings.ADDRESS_ID_REGISTRY)

    # Creates server message
    server_update_dict = dict(
        type=MessageType.SERVER_UPDATE,
        signature=0,
        address_id=address_id + 1,  # Increases the address id, to indicate the information is new and up to date.
        address_size=len(ip),
        address=ip.encode("ascii"),
        port=port,
        spread=spread
    )

    # Calculate signature of message
    try:
        server_update_message = messages.SERVER_UPDATE_MESSAGE.build(server_update_dict)

        # Update signature
        server_update_dict["signature"] = messages.sign_message(server_update_message)
        server_update_message = messages.SERVER_UPDATE_MESSAGE.build(server_update_dict)
    except construct.ConstructError as e:
        # Should never occur
        print(f"Failed to build server update message: {e.args}")
        return False

    # Sends server information update (should also update local server information)
    updater.send_broadcast(server_update_message)
    print("Server information was sent to services!")
    return True

def create_update(update_path, major, minor):
    version = updater.Version(major, minor)

    try:
        update_filepath = settings.UPDATE_PATH
        update_filepath = f"{update_filepath}.{version}"
        update_file = open(update_filepath, "wb")
    except PermissionError:
        print(f"Failed to write update file {settings.UPDATE_PATH}. Insufficient permission or file is locked.")
        return False

    # Creating update zip
    with update_file:
        update_zip = zipfile.ZipFile(update_file, "w")
        zip_directory(update_path, update_zip)
        update_zip.close()

    # Updating registry with update info
    version_registry = version.get_update_registry_path()
    registry.set_value(version_registry, os.path.abspath(update_filepath))
    version.update_current_version()

    print(f"Created update version {version} successfully!")
    return True

def broadcast_update_version(spread=True):
    # Gets the update info and update file
    update_version = updater.Version.get_current_version()
    version_registry = update_version.get_update_registry_path()
    update_filepath = registry.get_value(version_registry)

    # Tries to open update file (might fail if clients are downloading it)
    try:
        file_size = os.stat(update_filepath).st_size
        update_file = open(update_filepath, "rb")
    except PermissionError:
        print(f"Failed to write update file {settings.UPDATE_PATH}. Insufficient permission or file is locked.")
        return False

    # Calculates size and signature of update
    data_received = 0
    hash_object = settings.HASH_MODULE()

    # Calculate update signature
    with update_file:
        while data_received < file_size:
            chunk = update_file.read(settings.VERSION_CHUNK_SIZE)
            hash_object.update(chunk)
            data_received += len(chunk)
    signature = rsa_signing.sign_hash(hash_object)

    # Creates broadcast message
    version_update_dict = dict(
        type=MessageType.VERSION_UPDATE,
        header_signature=0,
        major=update_version.major,
        minor=update_version.minor,
        size=file_size,
        update_signature=signature,
        spread=spread
    )

    # Calculate signature of message
    try:
        version_update_message = messages.VERSION_UPDATE_MESSAGE.build(version_update_dict)

        # Update signature
        version_update_dict["header_signature"] = messages.sign_message(version_update_message)
        print(f"Spread: {version_update_dict['spread']}")
        version_update_message = messages.VERSION_UPDATE_MESSAGE.build(version_update_dict)
    except construct.ConstructError:
        # Should never occur
        print(f"Failed to build request update message")
        return False

    # Sends the message
    updater.send_broadcast(version_update_message)
    # After the update is announced, the service will send it to the clients, when they ask for it
    print(f"Broadcast was sent with version {update_version} !")
    return True

def execute_program(program, script, parameters="", **kwargs):
    command = f"{program} {parameters} {script}"
    print(f"Executing: {command}" + colorama.Fore.LIGHTBLUE_EX)
    result = subprocess.call(command, **kwargs)
    print(colorama.Fore.RESET)
    return result == 0

def clean_installer():
    # Delete all registry keys
    if registry.key_exists(settings.REGISTRY_PATH):
        registry.delete_key_recursive(settings.REGISTRY_PATH)
        print(f"Deleted registry key {settings.REGISTRY_PATH} successfully!")

    # Delete settings file
    if os.path.exists(DEFAULT_SETTINGS_PATH):
        os.remove(DEFAULT_SETTINGS_PATH)
        print(f"Deleted {DEFAULT_SETTINGS_PATH} successfully!")

    # Delete all setup file

    # Updater
    if os.path.isdir(r"..\Updater\build"):
        shutil.rmtree(r"..\Updater\build")
    if os.path.isdir(r"..\Updater\dist"):
        shutil.rmtree(r"..\Updater\dist")
    if os.path.exists(r"..\Updater\service.spec"):
        os.remove(r"..\Updater\service.spec")

    # Launcher
    if os.path.isdir(r"..\Launcher\build"):
        shutil.rmtree(r"..\Launcher\build")
    if os.path.isdir(r"..\Launcher\dist"):
        shutil.rmtree(r"..\Launcher\dist")
    if os.path.exists(r"..\Launcher\launcher.spec"):
        os.remove(r"..\Launcher\launcher.spec")

    # Server
    if os.path.exists(INSTALLER_SETUP_SCRIPT):
        os.remove(INSTALLER_SETUP_SCRIPT)
    if os.path.isdir(BUILD_DIRECTORY):
        shutil.rmtree(BUILD_DIRECTORY)
    if os.path.isdir("Output"):
        shutil.rmtree("Output")

    pass

def create_installer(program_name, major, minor, software_path, updater_path, launcher_path, ip, port):
    # Validate server, port
    # Validates the ip or domain (syntax only)
    if validators.domain(ip) is not True:
        if validators.ip_address.ipv4(ip) is not True:
            if validators.ip_address.ipv6(ip) is not True:
                print(f"Failed to validate ip or domain: {ip}. Check for typing mistakes.")
                return False

    # Validates port number
    if validators.between(port, min=1, max=65535) is not True:
        print(f"Invalid port number: {port} is not between 1 and 65535")
        return False

    # Save software name, program name, major, minor, ip, port to settings
    program_settings = dict(
        SOFTWARE_NAME=program_name.capitalize(),
        PROGRAM=f"{program_name}.exe",
        UPDATING_SERVER=ip,
        PORT=port,
        UPDATE_MAJOR=major,
        UPDATE_MINOR=minor,
        VERSION_MAJOR=major,
        VERSION_MINOR=minor,
    )
    importlib.reload(settings)
    settings.__values__.update(program_settings)
    settings.init_settings(save=False, load=False)

    if not add_to_settings(program_settings):
        print(f"Failed to write settings file {DEFAULT_SETTINGS_PATH}")
        return False
    print("Created new settings file!\n")

    # Generate RSA keys and add to settings/registry
    generate_rsa_keys(display_keys=False)

    # Create build directory
    if not os.path.isdir(BUILD_DIRECTORY):
        os.mkdir(BUILD_DIRECTORY)

    # Run pyinstaller for updater and copy executable to build directory (Create folder as well)
    service_folder = os.path.join(BUILD_DIRECTORY, "Updater")
    if not os.path.isdir(service_folder):
        os.mkdir(service_folder)
    service_script = SERVICE_EXECUTABLE.replace(".exe", ".py")
    if not execute_program("pyinstaller", os.path.join(updater_path, service_script), r"--hidden-import win32timezone --onefile", cwd=updater_path):
        print(f"Failed to run pyinstaller for {updater_path}")
        return False
    shutil.copyfile(os.path.join(updater_path, PYINSTALLER_OUTPUT_DIR, SERVICE_EXECUTABLE),
                    os.path.join(service_folder, SERVICE_EXECUTABLE))
    print("Built service successfully!\n")

    # Run pyinstaller for launcher and copy executable to build directory
    launcher_script = LAUNCHER_EXECUTABLE.replace(".exe", ".py")
    if not execute_program("pyinstaller", os.path.join(launcher_path, launcher_script), r"-p ..\ --onefile -w", cwd=launcher_path):
        print(f"Failed to run pyinstaller for {launcher_path}")
        return False
    shutil.copyfile(os.path.join(launcher_path, PYINSTALLER_OUTPUT_DIR, LAUNCHER_EXECUTABLE),
                    os.path.join(BUILD_DIRECTORY, LAUNCHER_EXECUTABLE))
    print("Built launcher successfully!\n")

    # Copy files for program_path to build directory
    program_folder = os.path.join(BUILD_DIRECTORY, program_name)
    if not os.path.isdir(program_folder):
        os.mkdir(program_folder)
    shutil.copytree(software_path, program_folder, dirs_exist_ok=True)
    print("Copied program files to build directory.\n")

    # Copy settings file to build directory
    settings_filename = os.path.basename(DEFAULT_SETTINGS_PATH)
    shutil.copyfile(DEFAULT_SETTINGS_PATH, os.path.join(service_folder, settings_filename))
    print("Copied settings file to build directory.\n")

    # Create Inno Setup Script using template
    inno_setup_script_parameters = f"""
        #define MyAppName "{program_name}"
        #define MyAppVersion "{major}.{minor}"
        #define UpdaterFolder "Updater"
        #define SettingsFile "{settings_filename}"
        #define LauncherName "{LAUNCHER_EXECUTABLE}"
        #define ServiceName "{SERVICE_EXECUTABLE}"
        #define BuildDir "{BUILD_DIRECTORY}"
    """
    with open(INSTALLER_SETUP_TEMPLATE, "r") as setup_template:
        template = setup_template.read()
    with open(INSTALLER_SETUP_SCRIPT, "w") as setup_script:
        setup_script.write(inno_setup_script_parameters)
        setup_script.write(template)
    print("Created Inno Setup script for installer!")

    # Compile script and create setup
    if not execute_program(INNO_SETUP_COMPILER, INSTALLER_SETUP_SCRIPT):
        print(f"Failed to compile setup script {INSTALLER_SETUP_SCRIPT}")
        return False
    print("Compiled setup script successfully!")
    print("Created installer in Output folder!")

    return True

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

    # Top level commands
    rsa_group = subparsers.add_parser("rsa")
    update_group = subparsers.add_parser("update")
    server_group = subparsers.add_parser("server")
    setup_group = subparsers.add_parser("setup")

    # Sub-commands of rsa

    subparsers = rsa_group.add_subparsers()
    # generate
    rsa_generate = subparsers.add_parser("generate")
    rsa_generate.set_defaults(func=generate_rsa_keys)
    # show
    rsa_show = subparsers.add_parser("show")
    rsa_show.set_defaults(func=show_rsa_keys)

    # Sub-commands of update

    subparsers = update_group.add_subparsers()
    # create
    update_create = subparsers.add_parser("create")
    update_create.add_argument("update_path", metavar="<Path to Update Folder>", type=str,
                              help="The path to the update folder (the folder that contains all the files of the software).")
    update_create.add_argument("major", metavar="<major>", type=int,
                               help="The major number of the version.")
    update_create.add_argument("minor", metavar="<minor>", type=int,
                               help="The minor number of the version.")
    update_create.set_defaults(func=create_update)

    # broadcast
    update_broadcast = subparsers.add_parser("broadcast")
    update_broadcast.add_argument("-s", "--spread", action="store_true",
                                  help="Sets 'spread' bit flag in broadcast message, will tell other clients to forward this message.")
    update_broadcast.set_defaults(func=broadcast_update_version)

    # Sub-commands of server

    subparsers = server_group.add_subparsers()
    # show
    server_show = subparsers.add_parser("show")
    server_show.set_defaults(func=show_server_information)
    # update
    server_update = subparsers.add_parser("update")
    server_update.add_argument("ip", metavar="<ip or domain>", type=str,
                               help="The ip or the domain of the update server.")
    server_update.add_argument("port", metavar="<port>", type=int,
                               help="The port that the updating service will listen on.")
    server_update.add_argument("-s", "--spread", action="store_true",
                               help="Sets 'spread' bit flag in broadcast message, will tell other clients to forward this message.")
    server_update.set_defaults(func=send_server_information)

    # Sub-commands of setup

    subparsers = setup_group.add_subparsers()
    # create
    setup_create = subparsers.add_parser("create")
    setup_create.add_argument("program_name", metavar="<Program Name>", type=str,
                              help=r"The program's executable name. Needs to be stored at <Program Folder>\<Program Name>.exe")
    setup_create.add_argument("major", metavar="<major>", type=int,
                              help="The major number of the version.")
    setup_create.add_argument("minor", metavar="<minor>", type=int,
                              help="The minor number of the version.")
    setup_create.add_argument("-s", "--software_path", metavar="[Path to Software Folder]", type=str, default=r"..\Program",
                              help=r"The path to the software folder. Defaults to ..\Program")
    setup_create.add_argument("-u", "--updater_path", metavar="[Path to Updater Folder]", type=str, default=r"..\Updater",
                              help=r"The path to the updater folder.  Defaults to ..\Updater")
    setup_create.add_argument("-l", "--launcher_path", metavar="[Path to Launcher Folder]", type=str, default=r"..\Launcher",
                              help=r"The path to the launcher folder.  Defaults to ..\Launcher")
    setup_create.add_argument("-i", "--ip", metavar="[Updating Server Address]", type=str, default=r"127.0.0.1",
                              help=r"The IP address or domain of the update server.  Defaults to 127.0.0.1")
    setup_create.add_argument("-p", "--port", metavar="[Updating Server Port]", type=int, default=r"55555",
                              help=r"The port of the update service. Defaults to 55555")
    setup_create.set_defaults(func=create_installer)
    # clean
    setup_clean = subparsers.add_parser("clean")
    setup_clean.set_defaults(func=clean_installer)

    # Parse everything
    args = parser.parse_args()

    # Initialize settings
    colorama.init()
    installer_settings = load_settings()
    settings.__values__.update(installer_settings)
    settings.init_settings(save=False)

    # call command function
    try:
        func = args.func
    except AttributeError:
        print(f"Invalid command. Run with `{sys.argv[0]} -h` for usage.")
        return
    del args.func
    func(**vars(args))

if __name__ == "__main__":
    main()


# -*- coding: utf-8 -*-
import string

import pandas as pd

def main():
    column = [string.ascii_lowercase[i] for i in range(14)]
    df = pd.read_csv(
        "http://logopt.com/data/wine.data",
        names=column
    )
    print(df.head())

if __name__ == '__main__':
    main()


from tkinter import *
import pandas as pd
import random

BACKGROUND_COLOR = "#B1DDC6"
current_card = {}
df_words_to_learn = pd.DataFrame()

# Get data from CSV file. If there are words to learn, upload from that file.
try:
    df_words_to_learn = pd.read_csv("./data/words_to_learn.csv")
except FileNotFoundError:
    df_words_to_learn = pd.read_csv("./data/french_words.csv")
finally:
    words_to_learn = df_words_to_learn.to_dict(orient="records")
    original_language = df_words_to_learn.columns[0]
    translated_language = df_words_to_learn.columns[1]

def generate_card():
    global current_card, flip_timer
    window.after_cancel(flip_timer)

    current_card = random.choice(words_to_learn)
    original_word = current_card[original_language]

    canvas.itemconfig(card_background, image=card_front_img)
    canvas.itemconfig(card_title, text=original_language)
    canvas.itemconfig(card_word, text=original_word)

    flip_timer = window.after(3000, func=flip_card)

def flip_card():
    translated_word = current_card[translated_language]
    canvas.itemconfig(card_background, image=card_back_img)
    canvas.itemconfig(card_title, text=translated_language)
    canvas.itemconfig(card_word, text=translated_word)

def is_known():
    # If user knows the word, remove card from words_to_learn
    words_to_learn.remove(current_card)
    data = pd.DataFrame(words_to_learn)
    data.to_csv(path_or_buf="./data/words_to_learn.csv", index=False)
    generate_card()

# UI Setup
window = Tk()
window.title("Flash Cards")
window.config(bg=BACKGROUND_COLOR, padx=50, pady=50)

flip_timer = window.after(3000, func=flip_card)

canvas = Canvas(bg=BACKGROUND_COLOR, width=800, height=526, highlightthickness=0)

card_front_img = PhotoImage(file="./images/card_front.png")
card_back_img = PhotoImage(file="./images/card_back.png")
card_background = canvas.create_image(400, 263, image=card_front_img)
canvas.grid(row=0, column=0, columnspan=2)

card_title = canvas.create_text(400, 150, text="", font=("Ariel", 40, "italic"))
card_word = canvas.create_text(400, 270, text="", font=("Ariel", 60, "bold"))
generate_card()

wrong_img = PhotoImage(file="./images/wrong.png")
wrong_button = Button(image=wrong_img, bg=BACKGROUND_COLOR, highlightthickness=0, command=generate_card)
wrong_button.grid(row=1, column=0)

right_img = PhotoImage(file="./images/right.png")
right_button = Button(image=right_img, bg=BACKGROUND_COLOR, highlightthickness=0, command=is_known)
right_button.grid(row=1, column=1)

window.mainloop()


import unittest
from datetime import datetime

from ognom.base import Collection
from ognom.fields import StringField
from ognom.helpers.lifecycle import DocWithLifeCycle

class FooDoc(DocWithLifeCycle):
    objects = Collection(
        db_name='main',
        collection_name='testmodel'
    )

    bar = StringField()

class TestLifeCycleMixin(unittest.TestCase):

    def test_created_at_should_be_inplace(self):
        td = FooDoc.objects.create({'bar': 'baz'})
        assert isinstance(td.created_at, datetime)
        assert td.bar == 'baz'

    def test_updated_at_should_not_be_inplace(self):
        td = FooDoc.objects.create({})
        assert td.updated_at is None

    def test_updated_at_should_present(self):
        td = FooDoc.objects.create({})
        td.updated_at = datetime.utcnow()
        td.save()
        assert isinstance(td.updated_at, datetime)

    def test_deleted_at_should_present(self):
        td = FooDoc.objects.create({})
        td.deleted_at = datetime.utcnow()
        td.save()
        assert isinstance(td.deleted_at, datetime)


from typing import Any

import ctypes

import numpy.ctypeslib as ctl

class CompiledController:
    """
    Controller class to handle using compiled controllers.
    This class expects that your function has the form: myFunction(*inputs, *outputs)
    where *inputs is a pointer to an inputs structure and
    *outputs is a pointer to an outputs structure.
    You can define these input and output structures however you please.
    See examples folder of repo for examples.

    Parameters:
        library_name (string): The name of the compiled library file, without the *.so
        library_path (string): The path to the directory containing the library. See examples for how to get working directory of parent script.
        main_function_name (string): Name of the main function to call within the library. This is the function that will get called via the run() method
        initialization_function_name (string): Name of an initialization function for your library. This gets called only once when the library is loaded. If you don't have an initialization function, pass None.
        cleanup_function_name (string): Name of a cleanup function for your library. This gets called when the CompiledController class has gone out of scope and is garbage collected. Again, pass None if you don't need this functionality.

    Authors:
        Kevin Best, Senthur Raj Ayyappan
        Neurobionics Lab
        Robotics Department
        University of Michigan
        October 2023
    """

    def __init__(
        self,
        library_name,
        library_path,
        main_function_name,
        initialization_function_name,
        cleanup_function_name,
    ) -> None:
        self.lib = ctl.load_library(library_name, library_path)
        self.cleanup_func = self._load_function(cleanup_function_name)
        self.main_function = self._load_function(main_function_name)
        self.init_function = self._load_function(initialization_function_name)
        # Note if requested function name is None, returned handle is also none

        if not self.init_function == None:
            self.init_function()

        # This alias makes defining types from top script easier without second import
        self.types = ctypes

        self.DEFAULT_SENSOR_LIST = [
            ("knee_angle", self.types.c_double),
            ("ankle_angle", self.types.c_double),
            ("knee_velocity", self.types.c_double),
            ("ankle_velocity", self.types.c_double),
            ("Fz", self.types.c_double),
        ]

        self._input_type = None
        self.inputs = None
        self._output_type = None
        self.outputs = None

    def __del__(self):
        if not self.cleanup_func == None:
            self.cleanup_func()

    def __repr__(self):
        return f"CompiledController"

    def _load_function(self, function_name):
        if function_name == None:
            return None
        else:
            try:
                function_handle = getattr(self.lib, function_name)
            except AttributeError:
                raise AttributeError(
                    f"Function {function_name} not found in library {self.lib}"
                )
            return function_handle

    def define_inputs(self, input_list: list[Any]) -> None:
        """
        This method defines the input structure to your function.
        See example folder and tutorials for help on using this method.

        Parameters
        -----------
        input_list: Input parameters given as a list of [('field_name', field_type)...]
            field_name is a string you choose as the title of the field.
            field_type is a type either given by a native c_types value or
                a custom type defined via the define_type() method.
                All types can be accessed as CompiledController.types.(type_name)
        """
        self._input_type = self.define_type("inputs", input_list)
        self.inputs = self._input_type()  # type: ignore

    def define_outputs(self, output_list: list[Any]) -> None:
        """
        This method defines the output structure to your function.
        See example folder and tutorials for help on using this method.

        Parameters
        ------------
        output_list: Output parameters given as a list of [('field_name', field_type)...]
            field_name is a string you choose as the title of the field.
            field_type is a type either given by a native c_types value or
                a custom type defined via the define_type() method.
                All types can be accessed as CompiledController.types.(type_name)
        """
        self._output_type = self.define_type("outputs", output_list)
        self.outputs = self._output_type()  # type: ignore

    def define_type(self, type_name: str, parameter_list: list[Any]):
        """
        This method defines a new type to be used in the compiled controller.
        After calling this method, the datatype with name type_name will be
        available in my_controller.types.type_name for use.
        See example folder and tutorials for help on using this method.

        Parameters
        ------------
        type_name : A string defining the name of your new datatype
        parameter_list: A list of [('field_name', field_type)...]
            field_name is a string you choose as the title of the field.
            field_type is a type either given by a native c_types value or
                a custom type defined via the define_type() method.
                All types can be accessed as CompiledController.types.(type_name)

        Example Usage
        ------------
            my_controller.DefineType('vector3D', [('x', my_controller.types.c_double),
                                                  ('y', my_controller.types.c_double),
                                                  ('z', my_controller.types.c_double)])
        """
        slots = []
        for param in parameter_list:
            slots.append(param[0])

        class CustomStructure(ctypes.Structure):
            _fields_ = parameter_list
            __slots__ = slots

        setattr(self.types, type_name, CustomStructure)
        return getattr(self.types, type_name)

    def run(self):
        """
        This method calls the main controller function of the library.
        Under the hood, it calls library_name.main_function_name(*inputs, *outputs),
        where library_name and main_function_name were given in the constructor.

        Parameters -> None

        Returns:
            The output structure as defined by the define_outputs() method.

        Raises:
            ValueError: If define_inputs() or define_outputs() have not been called.
        """
        if self.inputs is None:
            raise ValueError(
                "Must define input type before calling controller.run(). Use define_inputs() method."
            )
        if self.outputs is None:
            raise ValueError(
                "Must define output type before calling controller.run(). Use define_outputs() method."
            )
        self.main_function(ctypes.byref(self.inputs), ctypes.byref(self.outputs))
        return self.outputs

if __name__ == "__main__":
    pass


import numpy as np

class InfeasibleProblemError(ValueError):
    pass

def convert_socp_to_cvxopt_format(c, socp_constraints):
    """
    socp_constraints = [(Nameₖ, (Aₖ, bfbₖ, bfcₖ, dₖ), ...]

    min_u   cᵀu
       s.t. dₖ + bfcₖ u ≻ |Aₖ u + bfbₖ|₂

    min cᵀu
    s.t Gₖ x + sₖ = hₖ,    k = 0, ..., M
        A x = b
        h₀ - G₀ x ⪰ 0     # Component wise inequalities
        hₖ[0] - Gₖ[0, :] x ⪰ | hₖ[1:] - Gₖ[1:, :] x |₂,    k = 1, ..., M

    """
    m = np.asarray(c).shape[-1]
    Gqs = []
    hqs = []
    for name, (A, bfb, bfc, d) in socp_constraints:
        # (name, (A, b, c, d))
        # |Au + bfb| < bfc' u + d
        # s.t. ||Ax + b||_2 <= c'x + d
        # But || h₁ - G₁x ||₂ ≺ h₀ - g₀' x
        # G = [g₀'; G₁] = [-c'; -A]
        # h = [h₀; h₁] = [d; b]
        Gqi = np.zeros((A.shape[0]+1, m))
        Gqi[0, :] = -bfc
        Gqi[1:, :] = -A
        Gqs.append(Gqi)
        hqi = np.zeros((A.shape[0]+1, 1))
        hqi[0, 0] = d.reshape(1, 1)
        hqi[1:, 0] = bfb
        hqs.append(hqi)

    return c, Gqs, hqs

def optimizer_socp_cvxopt(u0, linear_objective, socp_constraints):
    """
    Solve the optimization problem

    min_u   A u + b
       s.t. h₀ - (G u)₀ ≻ |h₁ - (Gu)₁ |₂

    u0: reference control signal
    linear_objective: (

    convert to cvxopt format and pass to cvxopt

    min cᵀu
    s.t Gₖ x + sₖ = hₖ,    k = 0, ..., M
        A x = b
        s₀ ⪰ 0            # Component wise inequalities
        sₖ₀ ⪰ | sₖ₁ |₂,    k = 1, ..., M

    min cᵀu
    s.t Gₖ x + sₖ = hₖ,    k = 0, ..., M
        A x = b
        h₀ - G₀ x ⪰ 0     # Component wise inequalities
        hₖ[0] - Gₖ[0, :] x ⪰ | hₖ[1:] - Gₖ[1:, :] x |₂,    k = 1, ..., M

    """
    from cvxopt import solvers, matrix
    c, Gqs, hqs = convert_socp_to_cvxopt_format(linear_objective,
                                                socp_constraints)
    inputs_socp = dict(c = matrix(c),
                       Gq = list(map(matrix, Gqs)),
                       hq = list(map(matrix, hqs)))
    #print("optimizers.py:72", inputs_socp)
    sol = solvers.socp(**inputs_socp)
    if sol['status'] != 'optimal':
        if sol['status'] == 'primal infeasible':
            y_uopt = sol.get('z', u0)
        else:
            y_uopt = u0

        print("{c}.T [y, u]\n".format(c=c)
              + "s.t. "
              + "".join((" sq = {hq} - {Gq} [{y_uopt}]\n".format(hq=np.asarray(hq),
                                                             Gq=np.asarray(Gq),
                                                             y_uopt=np.asarray(y_uopt))
                     for Gq, hq in zip(Gqs, hqs))))
        raise InfeasibleProblemError("Infeasible problem: %s" % sol['status'])

    return np.asarray(sol['x']).astype(u0.dtype).reshape(-1)

def optimizer_socp_cvxpy(u0, linear_objective, socp_constraints, solver='GUROBI'):
    import cvxpy as cp
    x = cp.Variable(u0.shape)
    x.value = u0
    constraints = []
    for name, (A, bfb, bfc, d) in socp_constraints:
        constraints.append(cp.norm(A @ x + bfb) <= bfc @ x + d)

    obj = cp.Minimize(linear_objective @ x)
    prob = cp.Problem(obj, constraints)
    prob.solve(solver=solver)
    return x.value

def optimizer_qp_cvxpy(u0, quadratic_objective, linear_constraints, solver='GUROBI'):
    import cvxpy as cp
    x = cp.Variable(u0.shape)
    x.value = u0
    constraints = []
    for name, (bfc, d) in linear_constraints:
        constraints.append(0 <= bfc @ x + d)
    A, bfb = quadratic_objective
    obj = cp.Minimize(cp.sum_squares(A @ x + bfb))
    prob = cp.Problem(obj, constraints)
    prob.solve(solver=solver)
    return x.value


#!/usr/bin/env python3
#encoding: UTF-8

# This file is used to parse data within the config file.
# Those functions are moslty used to get informations.

def getConfigPathFile():
    ConfigPathFile = "/opt/Code_Pr00filer/config"
    return ConfigPathFile

def getVersion(ConfigPathFile):
    """
    return the VERSION number : string
    """
    version = "none"
    line = ""
    line_split = ""
    with open(ConfigPathFile) as conf:
        for line in conf:
            line_split = line.split()
            if line_split[0] == "VERSION":
                version = line_split[2]
    return version

def getPathSource(ConfigPathFile):
    """
    return the Path of the code source (default /opt/Code_Pr00filer/) : string
    """
    PathSource = "/opt/Code_Pr00filer/"
    line = ""
    line_split = ""
    with open(ConfigPathFile) as conf:
        for line in conf:
            line_split = line.split()
            if line_split[0] == "PATH_SOURCE":
                PathSource = line_split[2]
    return PathSource

def getPathScan(ConfigPathFile):
    """
    return the absolut path in wich the usb is mounted and scanned : string
    """
    PathScan = "/media/pi/"
    line = ""
    line_split = ""
    with open(ConfigPathFile) as conf:
        for line in conf:
            line_split = line.split()
            if line_split[0] == "PATH_SCAN":
                PathScan = line_split[2]
    return PathScan

def getAddrServer(ConfigPathFile):
    """
    return the server address : string
    """
    AddrServer = "none"
    line = ""
    line_split = ""
    with open(ConfigPathFile) as conf:
        for line in conf:
            line_split = line.split()
            if line_split[0] == "ADDR_SERVER":
                AddrServer = line_split[2]
    return AddrServer

def getNameAdmin(ConfigPathFile):
    """
    return the admin name used to send data to the database : string
    """
    NameAdmin = "admin"
    line = ""
    line_split = ""
    with open(ConfigPathFile) as conf:
        for line in conf:
            line_split = line.split()
            if line_split[0] == "NAME_ADMIN":
                NameAdmin = line_split[2]
    return NameAdmin

def getFileAdminHash(ConfigPathFile):
    """
    return the path where is stored the admin hash used to send data to the database : string
    """
    FileAdminHash = "doc/hash_user.txt"
    line = ""
    line_split = ""
    with open(ConfigPathFile) as conf:
        for line in conf:
            line_split = line.split()
            if line_split[0] == "FILE_ADMIN_HASH":
                FileAdminHash = line_split[2]
    return FileAdminHash

def getFileConfigHash(ConfigPathFile):
    """
    return the path where is stored the hash used to received data from the server : string
    """
    FileConfigHash = "doc/hash_config.txt"
    line = ""
    line_split = ""
    with open(ConfigPathFile) as conf:
        for line in conf:
            line_split = line.split()
            if line_split[0] == "FILE_CONFIG_HASH":
                FileConfigHash = line_split[2]
    return FileConfigHash

def getFileVirusHash(ConfigPathFile):
    """
    return the path where is stored the hash of the virus : string
    """
    FileVirusHash = "doc/hash_virus.txt"
    line = ""
    line_split = ""
    with open(ConfigPathFile) as conf:
        for line in conf:
            line_split = line.split()
            if line_split[0] == "FILE_VIRUS_HASH":
                FileVirusHash = line_split[2]
    return FileVirusHash

def getCheckVirusTotalScript(ConfigPathFile):
    """
    return the value True or False for CheckVirusTotal Script : Boolean
    """
    CheckVirusTotalScript = "True"
    line = ""
    line_split = ""
    with open(ConfigPathFile) as conf:
        for line in conf:
            line_split = line.split()
            if line_split[0] == "CHECK_VIRUSTOTAL_SCRIPT":
                if line_split[2] == "True":
                    CheckVirusTotalScript = True
                else:
                    CheckVirusTotalScript = False

    return CheckVirusTotalScript

def getCheckExtensionsScript(ConfigPathFile):
    """
    return the value True or False for CheckExtenions Script : Boolean
    """
    CheckExtensionsScript = "True"
    line = ""
    line_split = ""
    with open(ConfigPathFile) as conf:
        for line in conf:
            line_split = line.split()
            if line_split[0] == "CHECK_EXTENSIONS_SCRIPT":
                if line_split[2] == "True":
                    CheckExtensionsScript = True
                else:
                    CheckExtensionsScript = False

    return CheckExtensionsScript

def getDataExtensionsDelete(ConfigPathFile):
    """
    return all the extenions checked into the CheckExtensions Script : array
    """
    DataExtensionsDelete = []
    line = ""
    line_split = ""
    Temp_split = ""
    with open(ConfigPathFile) as conf:
        for line in conf:
            line_split = line.split()
            if line_split[0] == "DATA_EXTENSIONS_DELETE":
                Temp_split = line_split[2]
                DataExtensionsDelete = Temp_split.split(",")
    return DataExtensionsDelete

def getRulesPath(ConfigPathFile):
    """
    return the path where the yara-rules are stored
    """
    yara_rules_path = "doc/rules/"
    line = ""
    line_split = ""
    with open(ConfigPathFile) as conf:
        for line in conf:
            line_split = line.split()
            if line_split[0] == "YARA_RULES_PATH":
                yara_rules_path = line_split[2]
    return yara_rules_path


import tinify
import os

# https://tinypng.com/dashboard/api key从这里获取，每月500次调用次数
tinify.key = 'you key '

fileArray = []

# 递归深度遍历文件
def traverse(f):
    fs = os.listdir(f)
    for f1 in fs:
        tmp_path = os.path.join(f, f1)
        if not os.path.isdir(tmp_path):
            if is_img(tmp_path):
                fileArray.append(tmp_path)
        else:
            traverse(tmp_path)

# 根据路径判断文件是不是img
def is_img(path):
    path = path.split('.')[-1].upper()
    return True if (path == 'PNG') | (path == 'JPG') | (path=='JPEG') else False

traverse('E:\codeingSpace\zipimg\img')
for imgpath in fileArray:
    print("compressing ..." + imgpath)
    tinify.from_file(imgpath).to_file(imgpath)


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

# Step3: calculating the alien index score to predict HGT events.

import math

e_minus = 1e-200

alienindex_min = math.log(7e-48+e_minus, math.e)-math.log(4e-95+e_minus, math.e)

alienindex_max = math.log(1+e_minus, math.e)-math.log(0+e_minus, math.e)

alienindex2 = math.log(1e-10000+e_minus, 10) - math.log(1+e_minus, 10)

minus = math.log(e_minus, 10)

print(alienindex_min)

print(alienindex_max)

# Results:
# -460.51701859880916
# 460.51701859880916


# Task: Write a program that demonstrates a generator yielding
# one timestamp at a time from access_log

import re

for x in [i for i in set(re.split('[\s\[\]]+',open("access_log").read()))
          if re.findall(r"\d{2}/\w{3}/\d{4}", i)]:
    print(x)


from datetime import datetime
from django.shortcuts import render, redirect
from .models import Team
from cars.models import Car
from django.contrib.auth.models import User
from django.core.mail import send_mail
from django.contrib import messages
from django.core.paginator import Paginator

# Create your views here.

def home(request):
    teams = Team.objects.all()

    """Starting the paginating Shit"""

    featured_cars = Car.objects.order_by('-created_date').filter(sold=False,is_featured=True)

    all_cars = Car.objects.order_by('-created_date').filter(sold=False)
    paginator = Paginator(all_cars,6)
    page = request.GET.get('page')
    all_cars = paginator.get_page(page)

    brand_search = Car.objects.filter(sold=False).values_list('brand', flat=True).distinct()
    city_search = Car.objects.filter(sold=False).values_list('city', flat=True).distinct()
    year_search = [x for x in range(2010,datetime.now().year)]
    body_style_search = ['sedan','hatchback','SUV']
    data = {
        'teams': teams,
        'featured_cars': featured_cars,
        'all_cars': all_cars,
        'brand_search': sorted(brand_search),
        'city_search': sorted(city_search),
        'year_search': year_search,
        'body_style_search': body_style_search,
    }
    return render(request, 'pages/home.html', data)

def about(request):
    teams = Team.objects.all()
    data = {
        'teams': teams,
    }
    return render(request, 'pages/about.html', data)

def services(request):
    return render(request, 'pages/services.html')

def contact(request):
    if request.method == 'POST':
        name = request.POST['name']
        email = request.POST['email']
        subject = request.POST['subject']
        phone = request.POST['phone']
        message = request.POST['message']

        email_subject = 'You have a new message from Carzone website regarding ' + subject
        message_body = 'Name: ' + name + '. Email: ' + email + '. Phone: ' + phone + '. Message: ' + message

        admin_info = User.objects.get(is_superuser=True)
        admin_email = admin_info.email
        send_mail(
                email_subject,
                message_body,
                '',
                [admin_email],
                fail_silently=False,
            )
        messages.success(request, 'Thank you for contacting us. We will get back to you shortly')
        return redirect('contact')

    return render(request, 'pages/contact.html')


import logging
import os
from io import StringIO

import pandas as pd
import requests

logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
api_token = os.environ.get('EODHD_API_KEY')

def fetch_exchanges():
    url = f'https://eodhistoricaldata.com/api/exchanges-list/?api_token={api_token}&fmt=json'
    response = requests.get(url)

    if response.status_code == 200:
        return response.json()
    else:
        raise requests.exceptions.RequestException(f'Error: {response.status_code}')

def fetch_country_macro_data(country, indicator):
    url = f'https://eodhistoricaldata.com/api/macro-indicator/{country}?api_token={api_token}&fmt=json&indicator={indicator}'
    response = requests.get(url)
    response.raise_for_status()
    return response.json()

def fetch_exchange_tickers(exchange_code, delisted=0):
    url = f'https://eodhistoricaldata.com/api/exchange-symbol-list/{exchange_code}?api_token={api_token}&delisted={delisted}'
    response = requests.get(url)

    if response.status_code == 200:
        csv_data = StringIO(response.text)
        df = pd.read_csv(csv_data)
        tickers = df.to_dict('records')
        return tickers
    else:
        raise requests.exceptions.RequestException(f'Error {response.status_code} for exchange {exchange_code}')

def fetch_stock_fundamental_data(ticker):
    try:
        url = f'https://eodhistoricaldata.com/api/fundamentals/{ticker}?api_token={api_token}'
        response = requests.get(url)
        response.raise_for_status()
        return response.json()
    except requests.exceptions.HTTPError as e:
        logging.error(f"Error fetching fundamental data for {ticker}")
        write_ticker_to_failed_tickers(ticker)

        logging.error(f"Error: {e}")
        return None

def fetch_stock_ticker_price(ticker):
    try:
        url = f'https://eodhistoricaldata.com/api/eod/{ticker}?api_token={api_token}&period=m'
        response = requests.get(url)
        response.raise_for_status()
        return response.text
    except requests.exceptions.HTTPError as e:
        logging.error(f"Error fetching price data for {ticker}")
        write_ticker_to_failed_tickers(ticker)

        logging.error(f"Error: {e}")
        return None

def fetch_index_price(ticker, exchange):
    try:
        url = f'https://eodhistoricaldata.com/api/eod/{ticker}.{exchange}?api_token={api_token}&period=m'
        response = requests.get(url)
        response.raise_for_status()
        return response.text
    except requests.exceptions.HTTPError as e:
        logging.error(f"Error fetching price data for {ticker}")
        write_ticker_to_failed_tickers(ticker)

        logging.error(f"Error: {e}")
        return None

def fetch_stock_tickers(ticker):
    logging.info(f"Fetching stock tickers for {ticker}")
    url = f'https://eodhistoricaldata.com/api/fundamentals/{ticker}?api_token={api_token}'
    response = requests.get(url)
    response.raise_for_status()

    data = response.json()
    stock_tickers = [data["General"]["PrimaryTicker"]]

    for listing_index in data["General"]["Listings"]:
        stock_tickers.append(f'{data["General"]["Listings"][listing_index]["Code"]}.{data["General"]["Listings"][listing_index]["Exchange"]}')

    logging.info(f"Finished fetching stock tickers for {ticker}" )
    return list(set(stock_tickers))

def fetch_stock_sentiment_data(source, all_tickers):
    logging.info(f"Fetching stock sentiment data for source {source}")
    if source not in {"news", "tweets"}:
        logging.error(f"Invalid source {source}")
        raise ValueError(f"Invalid source {source}")

    url = f'https://eodhistoricaldata.com/api/{source+"-" if source == "tweets" else ""}sentiments?s={",".join(all_tickers)}&api_token={api_token}'
    response = requests.get(url)
    response.raise_for_status()

    logging.info(f"Finished fetching stock sentiment data for source {source}")
    return response.json()

def fetch_index_constituents(index_code,exchange):
    url = f'https://eodhistoricaldata.com/api/fundamentals/{index_code}.{exchange}?api_token={api_token}'
    response = requests.get(url)
    response.raise_for_status()
    json_response = response.json()
    constituents = []
    for listing_index in json_response["Components"]:
        constituents.append(f'{json_response["Components"][listing_index]["Code"]}.{json_response["Components"][listing_index]["Exchange"]}')

    # Also add hitorical constituents if available
    if "HistoricalTickerComponents" in json_response:
        for listing_index in json_response["HistoricalTickerComponents"]:
            constituents.append(f'{json_response["HistoricalTickerComponents"][listing_index]["Code"]}')

    return constituents

def write_ticker_to_failed_tickers(ticker):
    failed_tickers = pd.read_csv("failed_tickers.csv", header=0)
    failed_tickers.loc[len(failed_tickers)] = [ticker]
    failed_tickers.to_csv("failed_tickers.csv", index=False)


"""
Problem:

Assume that an alphabet AA has a predetermined order; that is, we write the alphabet as a permutation A=(a1,a2,…,ak), where a1<a2<⋯<ak. For instance, the English alphabet is organized as (A,B,…,Z).

Given two strings ss and tt having the same length nn, we say that ss precedes tt in the lexicographic order (and write s<Lexts<Lext) if the first symbol s[j] that doesn't match t[j] satisfies sj<tj in A.

Given: A collection of at most 10 symbols defining an ordered alphabet, and a positive integer nn (n≤10).

Return: All strings of length nn that can be formed from the alphabet, ordered lexicographically.

"""

import itertools

a = open("in_23.txt","r").read().split('\n')

o= "".join(sorted(a[0].split(" ")))
l= int(a[1])

for p in itertools.product(o, repeat=l):
        print("".join(p))