import json
from gdata.spreadsheet.service import CellQuery, ListQuery

from googlesheets.util import normalize_header

class Sheet(object):
    """ A sheet is a particular table of data within the context
    of a ``Spreadsheet``. Each sheet is comprised of a set of rows
    which can be iterated over, filtered, added, updated and
    removed. The title of the sheet is also mutable. """

    def __init__(self, spreadsheet, ws):
        self._ss = spreadsheet
        self._ws = ws
        self.id = ws.id.text.rsplit('/', 1)[-1]
        self._headers = None

    @property
    def _service(self):
        # Alias for brevity
        return self._ss.conn.sheets_service

    def _add_column(self, label, field):
        """ Add a new column to the table. It will have the header
        text ``label``, but for data inserts and queries, the
        ``field`` name must be used. If necessary, this will expand
        the size of the sheet itself to allow for the new column. """
        # Don't call this directly.
        assert self.headers is not None
        cols = 0
        if len(self._headers) > 0:
            cols = max([int(c.cell.col) for c in self._headers])
        new_col = cols + 1
        if int(self._ws.col_count.text) < new_col:
            self._ws.col_count.text = str(new_col)
            self._update_metadata()

        cell = self._service.UpdateCell(1, new_col, label,
                                        self._ss.id, self.id)
        self._headers.append(cell)

    def _create_columns(self, columns):
        columns = {normalize_header(c): c for c in columns}
        # existing = set(self.headers)
        for column in set(columns.keys()).difference(self.headers):
            self._add_column(columns[column], column)
        self._headers = None

    def _convert_value(self, row):
        assert isinstance(row, dict) or hasattr(row, 'items')
        self._create_columns(row.keys())
        data = {}
        for k, v in row.items():
            if v is None:
                v = ''
            data[normalize_header(k)] = unicode(v)
        return data

    @property
    def headers(self):
        """ Return the name of all headers currently defined for the
        table. """
        if self._headers is None:
            query = CellQuery()
            query.max_row = '1'
            feed = self._service.GetCellsFeed(self._ss.id, self.id,
                                              query=query)
            self._headers = feed.entry
        return [normalize_header(h.cell.text) for h in self._headers]

    def _update_metadata(self):
        self._ws = self._service.UpdateWorksheet(self._ws)

    def insert(self, row):
        """ Insert a new row. The row will be added to the end of the
        spreadsheet. Before inserting, the field names in the given
        row will be normalized and values with empty field names
        removed. """
        data = self._convert_value(row)
        self._service.InsertRow(data, self._ss.id, self.id)

    def update(self, row, keys=[]):
        changed = 0
        data = self._convert_value(row)
        keys = [normalize_header(k) for k in keys]
        filters = {k: data.get(k) for k in keys}
        for entry in self._find_entries(**filters):
            row = self._entry_data(entry)
            row.update(data)
            self._service.UpdateRow(entry, row)
            changed += 1
        return changed

    def upsert(self, row, keys=[]):
        if self.update(row, keys=keys) == 0:
            self.insert(row)

    def remove(self, _query=None, **kwargs):
        """ Remove all rows matching the current query. If no query
        is given, this will truncate the entire table. """
        for entry in self._find_entries(_query=_query, **kwargs):
            self._service.DeleteRow(entry)

    @property
    def title(self):
        """ The title of the sheet. """
        return self._ws.title.text

    @title.setter
    def title(self, title):
        self._ws.title.text = unicode(title)
        self._update_metadata()

    def delete(self):
        """ Delete the entire sheet. """
        self._ss.conn.sheets_service.DeleteWorksheet(self._ws)

    def _find_entries(self, _query=None, **kwargs):
        query = None
        if _query is not None:
            query = ListQuery()
            query.sq = _query
        elif len(kwargs.keys()):
            text = []
            for k, v in kwargs.items():
                k = normalize_header(k)
                v = json.dumps(unicode(v))
                text.append("%s = %s" % (k, v))
            query = ListQuery()
            query.sq = ' and '.join(text)
        feed = self._service.GetListFeed(self._ss.id, wksht_id=self.id,
                                         query=query)
        return feed.entry

    def _entry_data(self, entry):
        row = {}
        for k, v in entry.custom.items():
            row[k] = v.text
        return row

    def find(self, _query=None, **kwargs):
        for entry in self._find_entries(**kwargs):
            yield self._entry_data(entry)

    def find_one(self, _query=None, **kwargs):
        for row in self.find(**kwargs):
            return row

    def __iter__(self):
        return self.find()

    def __len__(self):
        # This is not precise.
        return int(self._ws.row_count.text)

    def __repr__(self):
        return '<Sheet(%r, %r, %r)>' % (self._ss, self.id, self.title)

    def __unicode__(self):
        return self.title


from osv import osv, fields

class stock_picking(osv.osv):

    _inherit = 'stock.picking'

    def _prepare_invoice_line(self, cr, uid, group, picking, move_line, invoice_id,
        invoice_vals, context=None):
        """ Builds the dict containing the values for the invoice line
            @param group: True or False
            @param picking: picking object
            @param: move_line: move_line object
            @param: invoice_id: ID of the related invoice
            @param: invoice_vals: dict used to created the invoice
            @return: dict that will be used to create the invoice line
        """
        if context == None:
            context = {}

        res = super(stock_picking, self)._prepare_invoice_line(cr, uid, group, picking, move_line, invoice_id,
        invoice_vals, context=context)

        res['sec_qty'] = res['quantity']
        res['sec_uom_id'] = res['uos_id']
        res['quantity'] = move_line.product_qty
        res['uos_id'] = move_line.product_uom.id
        res['price_unit'] = move_line.sale_line_id.price_unit

        return res

stock_picking()


from uuid import UUID

from sqlalchemy import asc
from sqlalchemy import delete
from sqlalchemy import desc
from sqlalchemy import select
from sqlalchemy.orm import Session

from danswer.configs.constants import QAFeedbackType
from danswer.configs.constants import SearchFeedbackType
from danswer.datastores.document_index import get_default_document_index
from danswer.datastores.interfaces import UpdateRequest
from danswer.db.models import Document as DbDocument
from danswer.db.models import DocumentRetrievalFeedback
from danswer.db.models import QueryEvent
from danswer.search.models import SearchType

def fetch_query_event_by_id(query_id: int, db_session: Session) -> QueryEvent:
    stmt = select(QueryEvent).where(QueryEvent.id == query_id)
    result = db_session.execute(stmt)
    query_event = result.scalar_one_or_none()

    if not query_event:
        raise ValueError("Invalid Query Event ID Provided")

    return query_event

def fetch_docs_by_id(doc_id: str, db_session: Session) -> DbDocument:
    stmt = select(DbDocument).where(DbDocument.id == doc_id)
    result = db_session.execute(stmt)
    doc = result.scalar_one_or_none()

    if not doc:
        raise ValueError("Invalid Document ID Provided")

    return doc

def fetch_docs_ranked_by_boost(
    db_session: Session, ascending: bool = False, limit: int = 100
) -> list[DbDocument]:
    order_func = asc if ascending else desc
    stmt = select(DbDocument).order_by(order_func(DbDocument.boost)).limit(limit)
    result = db_session.execute(stmt)
    doc_list = result.scalars().all()

    return list(doc_list)

def update_document_boost(db_session: Session, document_id: str, boost: int) -> None:
    stmt = select(DbDocument).where(DbDocument.id == document_id)
    result = db_session.execute(stmt).scalar_one_or_none()
    if result is None:
        raise ValueError(f"No document found with ID: '{document_id}'")

    result.boost = boost

    update = UpdateRequest(
        document_ids=[document_id],
        boost=boost,
    )

    get_default_document_index().update([update])

    db_session.commit()

def create_query_event(
    query: str,
    selected_flow: SearchType | None,
    llm_answer: str | None,
    user_id: UUID | None,
    db_session: Session,
) -> int:
    query_event = QueryEvent(
        query=query,
        selected_search_flow=selected_flow,
        llm_answer=llm_answer,
        user_id=user_id,
    )
    db_session.add(query_event)
    db_session.commit()

    return query_event.id

def update_query_event_feedback(
    feedback: QAFeedbackType,
    query_id: int,
    user_id: UUID | None,
    db_session: Session,
) -> None:
    query_event = fetch_query_event_by_id(query_id, db_session)

    if user_id != query_event.user_id:
        raise ValueError("User trying to give feedback on a query run by another user.")

    query_event.feedback = feedback

    db_session.commit()

def create_doc_retrieval_feedback(
    qa_event_id: int,
    document_id: str,
    document_rank: int,
    user_id: UUID | None,
    db_session: Session,
    clicked: bool = False,
    feedback: SearchFeedbackType | None = None,
) -> None:
    """Creates a new Document feedback row and updates the boost value in Postgres and Vespa"""
    if not clicked and feedback is None:
        raise ValueError("No action taken, not valid feedback")

    query_event = fetch_query_event_by_id(qa_event_id, db_session)

    if user_id != query_event.user_id:
        raise ValueError("User trying to give feedback on a query run by another user.")

    doc_m = fetch_docs_by_id(document_id, db_session)

    retrieval_feedback = DocumentRetrievalFeedback(
        qa_event_id=qa_event_id,
        document_id=document_id,
        document_rank=document_rank,
        clicked=clicked,
        feedback=feedback,
    )

    if feedback is not None:
        if feedback == SearchFeedbackType.ENDORSE:
            doc_m.boost += 1
        elif feedback == SearchFeedbackType.REJECT:
            doc_m.boost -= 1
        elif feedback == SearchFeedbackType.HIDE:
            doc_m.hidden = True
        elif feedback == SearchFeedbackType.UNHIDE:
            doc_m.hidden = False
        else:
            raise ValueError("Unhandled document feedback type")

    if feedback in [SearchFeedbackType.ENDORSE, SearchFeedbackType.REJECT]:
        document_index = get_default_document_index()
        update = UpdateRequest(
            document_ids=[document_id],
            boost=doc_m.boost,
        )
        # Updates are generally batched for efficiency, this case only 1 doc/value is updated
        document_index.update([update])

    db_session.add(retrieval_feedback)
    db_session.commit()

def delete_document_feedback_for_documents(
    document_ids: list[str], db_session: Session
) -> None:
    """NOTE: does not commit transaction so that this can be used as part of a
    larger transaction block."""
    stmt = delete(DocumentRetrievalFeedback).where(
        DocumentRetrievalFeedback.document_id.in_(document_ids)
    )
    db_session.execute(stmt)


#
# @lc app=leetcode id=415 lang=python3
#
# [415] Add Strings
#

# @lc code=start
class Solution:
    def addStrings(self, num1: str, num2: str) -> str:

        res = []

        carry = 0
        p1 = len(num1) - 1
        p2 = len(num2) - 1
        while p1 >= 0 or p2 >= 0:
            x1 = ord(num1[p1]) - ord('0') if p1 >= 0 else 0
            x2 = ord(num2[p2]) - ord('0') if p2 >= 0 else 0

            carry, value = divmod(x1 + x2 + carry, 10)
            res.append(value)
            p1 -= 1
            p2 -= 1

        if carry:
            res.append(carry)

        return ''.join(str(x) for x in res[::-1])

# @lc code=end


"""Select images with class A present, but not class B"""

from pycocotools.coco import COCO
import numpy as np

img_dir = r"/home/user/coco2017val/val2017"
annot_path = r"/home/user/coco2017val/annotations/instances_val2017.json"

cat_A = 72
cat_B = 7

coco = COCO(annot_path)

imgIds = coco.getImgIds(catIds=cat_A)
imgs = coco.loadImgs(imgIds)
for imgId in imgIds:
    annIds = coco.getAnnIds(imgIds=imgId)
    anns = coco.loadAnns(annIds)
    img_catsIds = [ann["category_id"] for ann in anns]
    if not np.isin(cat_B, img_catsIds):
        for ann in anns:
            if ann["category_id"] == cat_A:
                print(ann["id"])
        #         break
        # else:
        #     continue
        # break

print("\n")
print("\n")
print("\n")
print("\n")

imgIds = coco.getImgIds(catIds=cat_B)
imgs = coco.loadImgs(imgIds)
for imgId in imgIds:
    annIds = coco.getAnnIds(imgIds=imgId)
    anns = coco.loadAnns(annIds)
    img_catsIds = [ann["category_id"] for ann in anns]
    if not np.isin(cat_A, img_catsIds):
        for ann in anns:
            if ann["category_id"] == cat_B:
                # print(ann["id"])
                pass
        #         break
        # else:
        #     continue
        # break


"""
**Author** : {{ cookiecutter.author_name }}

**Institution** : {{ cookiecutter.author_institution }}

**Position** : {{ cookiecutter.author_position }}

**Contact** : {{ cookiecutter.author_mail }}

**Date** : {% now 'utc', '%Y-%m-%d' %}

**Project** : {{ cookiecutter.repo_name }}

**Test {{ cookiecutter.repo_name }} project **

"""
import sys
import os
from datetime import datetime
import pytest
import shutil
from pathlib import Path
from cookiecutter import main
import subprocess

ROOT = Path(__file__).parents[1]
TESTS_ROOT = ROOT / 'test_output'
EXTRA_CONTEXT = {
    "project_name": "Awesome test",
    "description": "Description",
    "remote_url": "github.com",

    "author_name": "John Doe",
    "author_institution": "john.doe@lambda.com",
    "author_position": "Intern",
    "author_github": "https://github.com/JohnDoe"
}

def test_generate_project() -> None:
    """
    Test project generation

    :return: None
    """
    # Clean
    if TESTS_ROOT.exists():
        shutil.rmtree(TESTS_ROOT)
    TESTS_ROOT.mkdir()

    # Get path
    output_dir = TESTS_ROOT.resolve()

    # Launch project generation
    main.cookiecutter(
        str(ROOT),
        no_input=True,
        extra_context=EXTRA_CONTEXT,
        output_dir=output_dir
    )

    # Test project generation
    project_name = 'awesome-test'
    assert (TESTS_ROOT / project_name).exists()


import datetime as dt

def build_menu(recipes: list[dict], start_date: dt.date) -> list[tuple[dt.date, str]] :
    res = []
    for i in recipes :
        tup = (start_date,i["title"])
        res.append(tup)
        start_date = start_date + dt.timedelta(days= 1)
    return res

def save_menu(meals: list[tuple[dt.date, str]]) :
    with open("menu.txt", "w") as f :
        for i in meals :
            res = i[0].strftime("%A %d %B %Y")
            f.write(res + ": " + i[1] + "\n")


"""
拉勾网requests爬虫
"""
# -*- coding:utf-8 -*-
import time
import random
import requests
import xlwt

from pymongo import MongoClient
from scrapy.selector import Selector

class Crawler(object):
    database = None
    collection = None

    def __init__(self, source_url=''):
        self.source_url = source_url
        self.session = requests.Session()

    @staticmethod
    def random_user_agent():
        """
        返回一个随机请求头
        :return:
        """
        ua_list = [
            # Chrome UA
            'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)'
            ' Chrome/73.0.3683.75 Safari/537.36',
            # IE UA
            'Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko',
            # Microsoft Edge UA
            'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)'
            ' Chrome/64.0.3282.140 Safari/537.36 Edge/18.17763'
        ]
        ua = random.choice(ua_list)
        return ua

    def login_mongodb(self, database_name, collection_name):
        """
        连接Mongodb客户端
        :param database_name: 数据库名称
        :param collection_name: 集合名称
        :return:
        """
        client = MongoClient(host='localhost', port=27017)
        self.database = client[database_name]
        self.collection = self.database[collection_name]
        print('Login mongodb successfully, database_name="{}", collection_name="{}"'.format(database_name,
                                                                                collection_name))

    @staticmethod
    def write_excel_table(write_info, table_name='excel_example.xls', sheet_name='first_page'):
        """
        写入Excel表格
        :param write_info: 要写入Excel表格的数据
        :param table_name: Excel表格名称
        :param sheet_name: Excel页面名称
        :return:
        """
        ex_wt = xlwt.Workbook()
        sheet1 = ex_wt.add_sheet(sheet_name, cell_overwrite_ok=True)

        for row_index, each_row in enumerate(write_info):
            if isinstance(each_row, (list, tuple)):
                # 如果是列表或者元组，循环写入每条数据
                for column_index, each_column in enumerate(each_row):
                    sheet1.write(row_index, column_index, each_column)
            else:
                # 写入一条数据
                sheet1.write(row_index, 0, each_row)
        ex_wt.save(table_name)

    def get_cookies(self, get_url):
        """
        返回一个cookie字符串
        :param get_url:
        :return:
        """
        resp = requests.get(get_url, headers={'User-Agent': self.random_user_agent()})
        # 获取的cookie是字典类型的
        cookies = resp.cookies.get_dict()
        # 因为请求头中cookie需要字符串，将字典转化为字符串类型
        cookie = ''
        for key, value in cookies.items():
            cookie += (key + '=' + value + '; ')
        print('Cookie: {}'.format(cookie))
        return cookie

    def main(self):
        host_url = 'https://www.lagou.com/jobs/list_%E7%88%AC%E8%99%AB%E5%BC%80%E5%8F%91%E5%B7%A5%E7%A8%8B%E5%B8%88?' \
                   'labelWords=&fromSearch=true&suginput='
        headers = {
            'User-Agent': self.random_user_agent(),
            'Referer': host_url,
            'Cookie': self.get_cookies(host_url),
        }
        data = {
            'first': 'false',
            'pn': 20,
            'kd': '爬虫开发工程师',
        }
        resp = requests.post(self.source_url, headers=headers, data=data)
        if resp.status_code == 200:
            print(resp.json())

            # selector = Selector(resp)
        else:
            print('No data found!')
            print('url: {}'.format(resp.url))
            print('status code: {}'.format(resp.status_code))
            print('history: {}'.format(resp.history))

if __name__ == '__main__':
    url = 'https://www.lagou.com/jobs/positionAjax.json?city=%E6%B7%B1%E5%9C%B3&needAddtionalResult=false'
    crawler = Crawler(source_url=url)
    crawler.main()


"""
    客户端
        register_check():检查注册情况:1.判断.\reg.zh文件是否存在 2.判断HKEY_CURRENT_USER/Software/RegisInfo的子项TIME是否存在
                         3.比对两文件中保存的时间信息是否存在且对应
        register(activate_code):通过Server端生成的激活码进行激活
        client_init():客户端启动,先调用register_check()检查注册情况,然后读取时间 再进入While STATE死循环,每隔一分钟执行write_time()向注册表和文件中写入时间信息
                      以及time_left()以DD:HH:MM的方式显示时间
"""
import os
import subprocess
import winreg
import base64
import time
import baseconvert
from keygen import verify_signature

# CURRENT_MACHINE_ID 获取机器的UUID, Windows平台下使用
CURRENT_MACHINE_ID = subprocess.check_output('wmic csproduct get uuid').decode().split('\n')[1].strip().replace('-', '')
PUBLIC_KEY = (270916549932685597202772283447247505705092774070722510140833201833867826517, 65537)

STATE = False
dd, hh, mm = 0, 0, 0

def register_check():
    if os.path.exists(r"../log/reg.zh"):
        with open(r'../log/reg.zh', 'r') as f:
            base64_time = f.read()
        decode_time = base64.b64decode(base64_time).decode("utf-8")
        try:
            key = winreg.OpenKey(winreg.HKEY_CURRENT_USER, r'Software\RegisInfo')
            value, _ = winreg.QueryValueEx(key, "TIME")
        except OSError:
            return "found no register info in regedit, need register"
        if decode_time == value:
            global STATE
            STATE = True
            return "register_check success"
        else:
            return "register info are not compatible, need register"
    else:
        return "register file doesn't exist, need register"

def register(activate_code_base62):
    if register_check() == "register_check success":
        return "you have been registered, do not register again"
    activate_code = int(baseconvert.f(activate_code_base62, 62, 10))
    info = verify_signature(activate_code, PUBLIC_KEY)
    machine_id_base10 = int(CURRENT_MACHINE_ID, base=16)
    check_machine_id = int(str(info)[:-4])
    check_time = str(info)[-4:]
    if machine_id_base10 == check_machine_id:
        # 将check_time(天)时间转为秒写入注册表和reg.zh文件中
        winreg.CreateKeyEx(winreg.HKEY_CURRENT_USER, r'SOFTWARE\RegisInfo', reserved=0, access=winreg.KEY_WRITE)
        second = int(check_time) * 86400
        write_time(second)
        return "register OK"
    else:
        return "machine id is wrong, please reinsert the activate code"

def client_init():
    global STATE
    if register_check() == "register_check success":
        with open(r'../log/reg.zh', 'r') as f:
            base64_time = f.read()
            seconds = int(base64.b64decode(base64_time).decode("utf-8"))
        while STATE:
            global dd, hh, mm
            dd, hh, mm, = time_left(seconds)
            time.sleep(60)
            seconds = seconds - 60
            if seconds > 0:
                write_time(seconds)
            else:
                STATE = False
                return "time is over"
        STATE = False
        return "client_close is called"
    else:
        return register_check()

def write_time(seconds):
    if not os.path.isdir(r'../log'):
        os.mkdir(r'../log')
    base64_time = base64.b64encode(str(seconds).encode()).decode("utf-8")
    with open(r'../log/reg.zh', 'w') as f:
        f.write(base64_time)

    key = winreg.OpenKey(winreg.HKEY_CURRENT_USER, r'Software\RegisInfo', 0, access=winreg.KEY_WRITE)
    winreg.SetValueEx(key, 'TIME', 0, winreg.REG_SZ, str(seconds))

def time_left(seconds):
    global dd, hh, mm
    dd = seconds // 86400
    hh = (seconds % 86400) // 3600
    mm = (seconds - dd * 86400 - hh * 3600) // 60

    return dd, hh, mm

def client_close():
    global STATE
    STATE = False

if __name__ == "__main__":
    print(register("5w8fZl7lBa0TdiBB4aHIrpoeMJfeF2pZZHl7T0N95k"))


n = int(input())
array = list(map(int, input().split()))

if all([x >= 0 for x in array]):
    sw = False
    for element in array:
        aux = list(str(element))
        original = list(str(element))
        aux.reverse()
        if aux == original:
            print(True)
            sw = True
            break
    if sw == False:
        print(False)
else:
    print(False)

## sol2
n = int(input())
array = list(map(int, input().split()))

if all([x >= 0 for x in array]):
        print(any([str(element) == str(element)[::-1] for element in array]))
else:
    print(False)

## sol3

n = int(input())
array = list(map(int, input().split()))
print(all([x >= 0 for x in array]) and any([str(element) == str(element)[::-1] for element in array]))


from unittest import TestCase
from unittest import main as run_tests
from time import sleep

from src.pyetllib.etllib.utils import log_timed_statistics

def func():
    """Some help"""
    sleep(1)

class TestLogTimedStatistics(TestCase):
    def setUp(self) -> None:
        self.logger_name = "test_utils"
        self.timed_function = log_timed_statistics(
            logger_name=self.logger_name)(func)

    def test_decoration(self):
        self.assertEqual(self.timed_function.__name__, func.__name__)
        self.assertEqual(self.timed_function.__doc__, func.__doc__)
        self.assertTrue(callable(self.timed_function))

    def test_correct_logging(self):
        with self.assertLogs(logger=self.logger_name, level='INFO') as cm:
            self.timed_function()
        self.assertGreater(len(cm.output), 0)
        self.assertIn(f'INFO:{self.logger_name}:time elapsed (seconds)',
                      cm.output[0])

if __name__ == "__main__":
    run_tests(verbosity=2)


from datetime import datetime
import re

def output_last_operations(data):
    for item in data[:5]:
        date_str = item.get("date", "")
        date = datetime.strptime(date_str, "%Y-%m-%dT%H:%M:%S.%f")
        formatted_date = date.strftime("%d.%m.%Y")
        description = item["description"]
        from_account = item.get("from", "")

        # Extract card number and card name
        card_number = from_account[-16:]
        card_name = from_account.split()[:-1]  # Extract all words except the last one
        card_name = " ".join(card_name)  # Join the words with a space

        #hide card number
        visible_digits = 6
        hidden_part = "*" * (len(card_number) - visible_digits)
        masked_card = " ".join([card_number[:visible_digits], hidden_part, card_number[-4:]])

        to_account = item.get("to", "")

        #hide account number
        account_number = to_account[-20:]
        account_name = to_account.split()[:-1]  # Extract all words except the last one
        account_name = " ".join(account_name)
        visible_digits_account = 4
        hidden = "*" * (len(account_number) - visible_digits_account)
        masked_account = " ".join([account_name, hidden, account_number[-4:]])

        amount = item["operationAmount"]["amount"]
        currency = item["operationAmount"]["currency"]["name"]

        output = f"{formatted_date} {description}\n {card_name} {masked_card} -> {masked_account}\n{amount} {currency}"
        print(output)
        print()


import numpy as np
import csv

class UE_selection:

    def __init__(self):
        self.ue_num = 6
        self.step_threshold = 8
        self.POP_SIZE = 100
        self.N_GENERATIONS = 100
        self.MUTATION_RATE = 0.003

    def init_population(self, num):
        population = np.random.randint(low=0, high=self.ue_num, size=(num, self.step_threshold))
        return population

    def get_population_fitness(self, population):
        num = len(population)
        fitness = np.zeros(num)
        for i in range(num):
            fitness[i] = self.get_fitness(population[i])
        return fitness

    def get_fitness(self, individual):
        unique = np.unique(individual)
        if len(unique) < self.ue_num/2:
            return len(unique)*0.5
        else:
            return len(unique)

    def select(self, population, fitness):
        idx = np.random.choice(np.arange(self.POP_SIZE), size=int(self.POP_SIZE / 2), replace=True,
                               p=fitness / fitness.sum())
        return population[idx]

    def crossover(self, population):
        count = len(population)
        children = np.zeros([count, self.step_threshold])
        for i in range(count):
            father = population[i]
            mother = population[count-1-i]
            first_part = father[0:int(self.step_threshold/2)]
            second_part = mother[int(self.step_threshold/2):self.step_threshold]
            child = np.append(first_part, second_part)
            children[i] = child
        return children

    def mutate(self, population):
        for i in range(len(population)):
            # 对数据进行交换
            if np.random.rand() < self.MUTATION_RATE:
                index = np.random.randint(self.step_threshold)
                ue_index = np.random.randint(self.ue_num)
                population[i][index] = ue_index
        return population

    def evaluate_population(self, index, population):
        fitness = self.get_population_fitness(population)
        max_index = np.argmax(fitness)
        # print("best individual ", population[max_index])
        print("iteration count:", index)
        print("best fitness:", fitness[max_index])
        print("best individual", population[max_index])
        print("average fitness",np.average(fitness))
        return fitness[max_index]

    def run(self):
        # init population
        population = self.init_population(self.POP_SIZE)
        self.evaluate_population(0, population)
        result_list = []
        for index in range(self.N_GENERATIONS):
            # # get fitness
            fitness = self.get_population_fitness(population)
            # # select good individuals
            population = self.select(population, fitness)
            # # crossover
            children = self.crossover(population)
            # #补充保持种群不变
            population = np.vstack([population, children])
            # # mutate
            population = self.mutate(population)
            best_fitness = self.evaluate_population(index+1, population)
            result_list.append(best_fitness)
        with open('ga_result.csv', 'a', newline='') as f:
            writer = csv.writer(f)
            writer.writerow(result_list)

if __name__ == '__main__':
    selection = UE_selection()
    #population = selection.init_population(10)
    #print(selection.get_population_fitness(population))
    selection.run()


"""
Interface for the nPoint LC400 Tip/Tilt closed loop controller.
Connects to the controller via usb using pvisa and FTDI drivers.
"""

import enum
import functools
import math
import os
import struct
import time

import pyvisa

from catkit.interfaces.ClosedLoopController import ClosedLoopController

class Parameters(enum.Enum):
    # The hex codes get summed with the channel to yield an address so for convenience leave these as ints.
    # param = (hex_Code, data_length, data_type_fmt)
    LOOP = (0x84, 1, 'I')
    P_GAIN = (0x720, 2, 'd')
    I_GAIN = (0x728, 2, 'd')
    D_GAIN = (0x730, 2, 'd')

    def __init__(self, hex_code, data_length, data_type_fmt):
        self.hex_code = hex_code
        self.data_length = data_length
        self.data_type_fmt = data_type_fmt

    @classmethod
    def _missing_(cls, value):
        for item in cls:
            if value == item.hex_code:
                return item

class Commands(enum.Enum):
    SET = b'\xa2'
    SECOND_MSG = b'\xa3'
    GET_SINGLE = b'\xa0'
    GET_ARRAY = b'\xa4'

class NPointLC400(ClosedLoopController):

    instrument_lib = pyvisa

    endpoint = b'\x55'
    # The channels get summed with the parameters to yield an address so for convenience leave these as ints.
    base_channel_address = 0x11830000
    channel_address_offset = 0x1000
    channels = (1, 2)
    endian = '<'  # Little endian.

    def initialize(self, com_id, timeout=5):
        """Initial function to set vendor and product id parameters.
        Parameters
        ----------
        com_id : str
            The serial port com.
        """

        self.instrument_lib = self.instrument_lib.ResourceManager("@py")

        # Device specifics
        self.com_id = com_id
        self.timeout = timeout

    @classmethod
    def build_address(cls, parameter, channel):
        """ Builds the address to send to the controller.
        Memory offsets are summed with a channel base address to set the parameter for a specific channel.
        Channels are separated by an offset of 0x1000.
        0x11831000 := Ch1 base address
        0x11832000 := Ch2 base address
        """

        if parameter not in Parameters:
            raise ValueError(f"Parameter must be one of {[param for param in Parameters]}.")

        if channel not in cls.channels:
            raise ValueError(f"Channel must be one of {cls.channels}")

        # + := int addition.
        address = cls.base_channel_address + channel*cls.channel_address_offset + parameter.hex_code

        return struct.pack(cls.endian + 'I', address)  # 'I' := unsigned int.

    def _close(self):
        # Reset everything to 0.
        for channel in self.channels:
            for parameter in Parameters:
                self.set(parameter, channel, 0)
        self.instrument.close()

    def _open(self):
        # Instantiate the device.
        self.instrument = self.instrument_lib.open_resource(self.com_id,
                                                            access_mode=pyvisa.constants.AccessModes.exclusive_lock,
                                                            open_timeout=self.timeout)
        self.log.info('npointLC400 instantiated and logging online.')
        return self.instrument

    def _read(self, byte_count):
        """ Read a response from controller. """
        start = time.time()
        resp = self.instrument.read_bytes(byte_count)
        self.log.debug(f'It took {start - time.time()}s to read response.')
        return resp

    def _send(self, message):
        """ Send the message(s) to the controller. """
        message = message if isinstance(message, (tuple, list)) else [message]
        for msg in message:
            self.instrument.write_raw(msg)

    def get(self, parameter, channel):
        """
        (addr and data are 32b (4B) each).
        Read Single Location
            Number of bytes written: 6
            Format: 0xA0 [addr] 0x55
            Number of bytes read: 10
            Return Value: 0xA4 [addr] [data] 0x55
        Read Array Command
            Number of bytes written: 10
            Format: 0xA4 [addr] [numReads] 0x55
            Number of bytes read: 6 + numReads*4
            Return Value: 0xA4 [addr] [data 1].....[data N] 0x55
        """
        # Construct message.
        address = self.build_address(parameter, channel)
        n_reads = parameter.data_length
        if n_reads == 1:
            message = b''.join([Commands.GET_SINGLE.value, address, self.endpoint])
        else:
            n_reads_message = struct.pack(self.endian + 'I', n_reads)
            message = b''.join([Commands.GET_ARRAY.value, address, n_reads_message, self.endpoint])

        # Send GET.
        self._send(message)

        # Read response.
        bytes_to_read = 1 + 4 + n_reads*4 + 1  # command + address + n_reads*data + endpoint.
        resp = self._read(bytes_to_read)

        # Parse response.
        resp_command, resp_parameter, resp_address, resp_channel, value = self.parse_message(resp)

        # Check to ensure that reads are in sync.
        if resp_command not in (Commands.GET_SINGLE, Commands.GET_ARRAY):
            raise RuntimeError(f"Reads and writes out of sync. Expected GET Command but got '{resp_command}")
        if resp_parameter is not parameter:
            raise RuntimeError(f"Reads and writes out of sync. Expected Parameter '{parameter}' but got '{resp_parameter}")
        if address != resp_address:
            raise RuntimeError(f"Reads and writes out of sync. Expected address '{address}' but got '{resp_address}")
        if resp_channel != channel:
            raise RuntimeError(f"Reads and writes out of sync. Expected channel '{channel}' but got '{resp_channel}")

        return value

    def set(self, parameter, channel, value):
        """
        (addr and data are 32b (4B) each).
        Write Single Location Command
            Number of bytes written: 10
            Format: 0xA2 [addr] [data] 0x55
            Return Value: none
        Write Next Command
            Number of bytes written: 6
            Format: 0xA3 [data] 0x55
            Return Value: none
        """
        if not isinstance(value, (int, float)):
            raise TypeError(f"Parameter values must be int or float not {type(value)}")

        address = self.build_address(parameter, channel)

        data_type_fmt = parameter.data_type_fmt
        if data_type_fmt == 'I':
            value = struct.pack(self.endian + data_type_fmt, 1 if value else 0)
            self._send(b''.join([Commands.SET.value, address, value, self.endpoint]))
        elif data_type_fmt == 'd':
            value = struct.pack(self.endian + data_type_fmt, float(value))
            # Send value in two halves.
            self._send([b''.join([Commands.SET.value, address, value[:4], self.endpoint]),
                        b''.join([Commands.SECOND_MSG.value, value[4:], self.endpoint])])
        else:
            raise NotImplementedError("Supports only 32b ints and 64b floats.")

    def set_and_check(self, parameter, channel, value):
        self.set(parameter, channel, value)
        set_value = self.get(parameter, channel)
        if value != set_value:
            raise ValueError(f'Command was NOT successful : {value} != {set_value}.')  # RT error?
        self.log.debug(f'Command successful: {value} == {set_value}.')

    def get_status(self, channel):
        """ Get the value of all parameter: loop, and p/i/d_gain for the specified channel. Returns a dict. """
        value_dict = {}
        for parameter in Parameters:
            value_dict[parameter] = self.get(parameter, channel)
        self.log.info(f"Status: {value_dict}")
        return value_dict

    def set_closed_loop(self, active=True):
        """ Activate closed-loop control on all channels. """
        for channel in self.channels:
            self.set_and_check(Parameters.LOOP, channel, active)

    @classmethod
    def parse_message(cls, message):
        """ Parse message.

        (addr and data are 32b (4B) each).
        Read Single Location
            Number of bytes written: 6
            Format: 0xA0 [addr] 0x55
            Number of bytes read: 10
            Return Value: 0xA4 [addr] [data] 0x55
        Read Array Command
            Number of bytes written: 10
            Format: 0xA4 [addr] [numReads] 0x55
            Number of bytes read: 6 + numReads*4
            Return Value: 0xA4 [addr] [data 1].....[data N] 0x55
        Write Single Location Command
            Number of bytes written: 10
            Format: 0xA2 [addr] [data] 0x55
            Return Value: none
        Write Next Command
            Number of bytes written: 6
            Format: 0xA3 [data] 0x55
            Return Value: none

        Returns:
            Command, Parameter, address, channel, data
        """

        # Parse command
        try:
            command = Commands(message[:1])
        except ValueError as error:
            raise NotImplementedError('Non implemented command found in message.') from error

        parameter = None
        address = None
        channel = None
        if command in (Commands.GET_SINGLE, Commands.GET_ARRAY, Commands.SET):
            # Parse address
            address = message[1:5]

            # Parse channel
            int_address = struct.unpack(cls.endian + 'I', address)[0]
            channel = math.floor((int_address - cls.base_channel_address) / cls.channel_address_offset)
            if channel not in cls.channels:
                raise ValueError(f"Channel out of bounds. Received '{channel}' expected one of ({cls.channels})")

            # Parse parameter
            try:
                parameter = Parameters(int_address - cls.base_channel_address - cls.channel_address_offset * channel)
            except ValueError as error:
                raise NotImplementedError('Non implemented parameter found in message.') from error

        # Parse value.
        if command in (Commands.SET, Commands.SECOND_MSG):
            data = struct.unpack(cls.endian + 'I', message[-5:-1])[0]
        elif command is Commands.GET_SINGLE:
            # 0xA0 [addr] 0x55
            # 0xA0 [addr] [data] 0x55
            data = struct.unpack(cls.endian + parameter.data_type_fmt, message[5:-1])[0] if len(message) > 6 else None
        elif command is Commands.GET_ARRAY:
            # For GET, message could be either that sent or that received. E.g., one of the following:
            # 0xA4 [addr] [numReads] 0x55
            # 0xA4 [addr] [data 1].....[data N] 0x55
            data_block = message[5:-1]
            n_data = len(data_block)//4
            if n_data == 1:
                data_type_fmt = 'I'
            elif n_data == 2:
                data_type_fmt = 'd'
            else:
                raise NotImplementedError(f"Supports only 32b ints and 64b floats. Received {n_data * 32}b data block.")
            data = struct.unpack(cls.endian + data_type_fmt, data_block)[0]
        else:
            raise NotImplementedError('Non implemented command found in message.')

        return command, parameter, address, channel, data


#! /usr/bin/python

# Positional Arguments
def describe_pet(animal_type, pet_name):
	"""Display information about a pet."""
	print("\nI have a " + animal_type + ".")
	print("My " + animal_type + "'s name is " + pet_name.title() + ".")

describe_pet('hamster', 'harry')
# Multiple Function Calls
describe_pet('dog', 'willie')

# Keyword Arguments
# keyword argument is a name-value pair that you pass to a function
# When you use keyword arguments, be sure to use the exact names of the parameters in the function’s definition.
describe_pet(animal_type='hamster', pet_name='harry')
describe_pet(pet_name='willie', animal_type='dog')

# Default Values
# When writing a function, you can define a default value for each parameter.
def describe_pet2(pet_name, animal_type='dog'):
	# When you use default values, any parameter with a default value needs to be listed after all the parameters that don’t have default values.
	# This allows Python to continue interpreting positional arguments correctly.

	"""Display information about a pet."""
	print("\nI have a " + animal_type + ".")
	print("My " + animal_type + "'s name is " + pet_name.title() + ".")

describe_pet2(pet_name='willie')
describe_pet2(pet_name='harry', animal_type='hamster')

print()
# Equivalent Function Calls

# A dog named Willie.
describe_pet2('willie')
describe_pet2(pet_name='willie')
# A hamster named Harry.
describe_pet2('harry', 'hamster')
describe_pet2(pet_name='harry', animal_type='hamster')
describe_pet2(animal_type='hamster', pet_name='harry')

Python Crash Course/Part 1 - Basics/Ch8 - Functions/Passing_Arguments.py


import logging
from enum import Enum

from PyQt5.QtCore import QUrl
from PyQt5.QtGui import QDesktopServices

logger = logging.getLogger(__name__)

class BanPeriod(Enum):
    HOUR = 'HOUR'
    DAY = 'DAY'
    WEEK = 'WEEK'
    MONTH = 'MONTH'
    YEAR = 'YEAR'

class PowerActions:
    def __init__(self, lobby_connection, playerset, settings):
        self._lobby_connection = lobby_connection
        self._playerset = playerset
        self._settings = settings

    @classmethod
    def build(cls, lobby_connection, playerset, settings, **kwargs):
        return cls(lobby_connection, playerset, settings)

    def close_fa(self, username):
        player = self._playerset.get(username, None)
        if player is None:
            return False
        logger.info('Closing FA for {}'.format(player.login))
        self._lobby_connection.send({
            "command": "admin",
            "action": "closeFA",
            "user_id": player.id,
        })
        return True

    def kick_player(self, username):
        player = self._playerset.get(username, None)
        if player is None:
            return False
        logger.info('Closing lobby for {}'.format(player.login))
        self._lobby_connection.send({
            "command": "admin",
            "action": "closelobby",
            "user_id": player.id,
        })
        return True

    def ban_player(self, username, reason, duration, period):
        player = self._playerset.get(username, None)
        if player is None:
            return False
        message = {
            "command": "admin",
            "action": "closelobby",
            "ban": {
                "reason": reason,
                "duration": duration,
                "period": period,
            },
            "user_id": player.id,
        }
        self._lobby_connection.send(message)
        return True

    def send_the_orcs(self, username):
        player = self._playerset.get(username, None)
        target = username if player is None else player.id
        route = self._settings.get('mordor/host')
        QDesktopServices.openUrl(QUrl("{}/users/{}".format(route, target)))


from sqlalchemy import Column, SMALLINT, BIGINT, String,Integer, engine
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

#코드매칭 테이블
class code_matching(Base): # 식별하기 쉽게 테이블명으로 지정
    __tablename__= 'code_matching'

    id = Column("id", Integer, primary_key=True, autoincrement=True)
    original_code = Column("original_code", String(50))
    storage = Column("storage", String(100))
    mintit_code = Column("mintit_code", String(100))
    bunjang_code = Column("bunjang_code", String(100))
    joongabi_code = Column("joongabi_code", String(100))
    price_code = Column("price_code", String(100))

    def __init__(self, original_code,storage,mintit_code,bunjang_code,joongabi_code,price_code):
        self.original_code = original_code
        self.storage = storage
        self.mintit_code = mintit_code
        self.bunjang_code = bunjang_code
        self.joongabi_code = joongabi_code
        self.price_code = price_code

    def __repr__(self):
        return "<code_matching('%d', '%s', '%s', '%s', '%s', '%s', '%s')>" \
            % (self.id,self.original_code, self.storage, self.mintit_code, \
                self.bunjang_code, self.joongabi_code,self.price_code)

###또다른 테이블
#
#
# ...


import tkinter as tk
from tkinter import *
from tkinter import messagebox
from tkinter import ttk
from tkinter import filedialog
from tkinter.filedialog import asksaveasfile

from PIL import ImageTk, Image
import socket
from fileinput import filename
import os
import socket,cv2, pickle,struct

HEADER = 1024
FORMAT = "utf-8"
port = 1010
ip_addr = ''
cn = 0
filename = ''

try:
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except socket.error as err:
    print("socket creartion failed with error %s"%(err))

def send(str):
    s.sendall(str.encode(FORMAT))
    msg = s.recv(HEADER)
    if msg == b"Msg received":
        return 1
    return 1

def connect():
    global ip_addr
    global cn
    ip_addr = textIp.get()
    try:
        s.connect((ip_addr,port))
        messagebox.showinfo("Message", "Connected susseccfully")
        cn = 1
    except socket.error as err:
        messagebox.showinfo("Message", "Error connecting to server.")

def disconnect():
    send('EXIT')

def keystroke_keylock():
    def hook():
        send("HOOK")

    def unhook():
        send("UNHOOK")

    def print_kb():
        send("PRINT KEYBOARD")
        msg = s.recv(HEADER).decode(FORMAT)
        if msg != "None!!!":
            text_keystroke.insert(END,msg)
    def lock():
        send("LOCK")

    def unlock():
        send("UNLOCK")

    def clear_kb():
        text_keystroke.delete("1.0","end")

    def on_closing_ks():
            send("QUIT")
            ks.destroy()

    if cn == 0:
        messagebox.showinfo("Message", "Not connect to server")
        return
    rt = send("KEYLOG")
    if rt == 0:
      messagebox.showinfo("Message", "Can't send data to server")
      return

    ks = Toplevel(gui)
    ks.title("Keylogger")
    button_lock = Button(ks, text="Lock", width=10, command=lock)
    button_unlock = Button(ks, text="Unlock", width=10, command=unlock)
    button_hook = Button(ks, text="Hook", width=10, command=hook)
    button_unHook = Button(ks, text="Unhook", width=10, command=unhook)
    button_print = Button(ks, text="Print", width=10, command=print_kb)
    button_clear = Button(ks, text="Clear", width =10, command=clear_kb)

    button_lock.grid(row=0,column=0,padx=5,pady=5,sticky='NSEW')
    button_unlock.grid(row=1,column=0,padx=5,pady=5,sticky='NSEW')
    button_hook.grid(row=2,column=0,padx=5,pady=5,sticky='NSEW')
    button_unHook.grid(row=3,column=0,padx=5,pady=5,sticky='NSEW')
    button_print.grid(row=4,column=0,padx=5,pady=5,sticky='NSEW')
    button_clear.grid(row=5,column=0,padx=5,pady=5,sticky='NSEW')

    text_frame = Frame(ks)
    text_frame.grid(rowspan=6,row=0, column=1,pady=5,sticky='NSEW')
    text_keystroke = Text(text_frame, width=48)
    text_keystroke.grid(rowspan=6,row=0, column=0,padx=5,pady=5,sticky='NSEW')

    bar = Scrollbar(text_frame, orient="vertical", command=text_keystroke.yview)
    bar.grid(rowspan=6, row=0, column=2, sticky='NS')
    text_keystroke.configure(yscrollcommand=bar.set)

    ks.protocol("WM_DELETE_WINDOW", on_closing_ks)

def shutdown():
    global cn
    if cn == 0:
        messagebox.showinfo("Message", "Not connect to server")
        return
    send("SHUTDOWN")
    disconnect()
    cn = 0

def logout():
    global cn
    if cn == 0:
        messagebox.showinfo("Message", "Not connect to server")
        return
    send("LOGOUT")
    disconnect()
    cn = 0

def app_running():
    if cn == 0:
        messagebox.showinfo("Message", "Not connect to server")
        return
    rt = send("APPLICATION")
    if rt == 0:
      messagebox.showinfo("Message", "Can't send data to server")
      return

    def xem():
        send("XEM")
        full_msg = ''
        msg = s.recv(HEADER).decode(FORMAT)
        splits = msg.split('\n')
        data = []
        for e in splits:
            t = e.split(' ')
            data.append((t[0], t[len(t)-1]))
        x = data.pop(0)
        x = data.pop(0)

        for i in app_tree.get_children():
            app_tree.delete(i)

        for setA in data:
            app_tree.insert('', END, values = setA)

    def kill():
        def on_closing_kill():
            send("QUIT")
            kill.destroy()
        def killID():
            send("KILLID")
            msg = inputID.get()
            send(msg)
            req = s.recv(HEADER).decode(FORMAT)
            if req == 'Done!!!':
                messagebox.showinfo("Message", "App was killed")
            if req == 'Error!!!':
                messagebox.showinfo("Message", "App not found")

        msg = send("KILL")
        kill = Toplevel(ar)
        kill.title("Kill")

        inputID = Entry(kill, width=30)
        button_killid = tk.Button(kill, text="Kill",width=15,command=killID)

        inputID.grid(row=0,column=0,padx=10,pady=10,sticky='NSEW')
        button_killid.grid(row=0,column=1,padx=10,pady=10,sticky='NSEW')
        inputID.insert(END,"Input ID")

        kill.protocol("WM_DELETE_WINDOW", on_closing_kill)

    def xoa():
        for i in app_tree.get_children():
            app_tree.delete(i)

    def start():
        def on_closing():
            send("QUIT")
            start.destroy()
        def startID():
            send("STARTID")
            msg = inputID.get()
            send(msg)
            req = s.recv(HEADER).decode(FORMAT)
            if req == 'Done!!!':
                messagebox.showinfo("Message", "App was started")
            if req == 'Error!!!':
                messagebox.showinfo("Message", "Error")

        msg = send("START")
        start = Toplevel(ar)
        start.title("Start")

        inputID = Entry(start, width=30)
        button_killid = tk.Button(start, text="Start", width=15,command=startID)

        inputID.grid(row=0,column=0,padx=10,pady=10,sticky='NSEW')
        button_killid.grid(row=0,column=1,padx=10,pady=10,sticky='NSEW')
        inputID.insert(END,"Input name")
        start.protocol("WM_DELETE_WINDOW", on_closing)

    def on_closing_ar():
            send("QUIT")
            ar.destroy()

    ar = Toplevel(gui)
    ar.title("App")
    button_kill = Button(ar, text="Kill", width=10, command=kill)
    button_xem = Button(ar, text="View", width=10, command=xem)
    button_xoa = Button(ar, text="Clear", width=10, command=xoa)
    button_start = Button(ar, text="Start", width =10, command=start)

    button_kill.grid(row=0,column=0,padx=5,pady=5,sticky='NSEW')
    button_xem.grid(row=0,column=1,padx=5,pady=5,sticky='NSEW')
    button_xoa.grid(row=0,column=2,padx=5,pady=5,sticky='NSEW')
    button_start.grid(row=0,column=3,padx=5,pady=5,sticky='NSEW')

    list_frame = Frame(ar)
    list_frame.grid(columnspan=4,row=1, column=0,pady=5,sticky='NSEW')

    columns = ('namea', 'id')
    app_tree = ttk.Treeview(list_frame, columns=columns, show='headings')

    app_tree.heading('namea', text='Name')
    app_tree.heading('id', text='ID')

    app_tree.grid(columnspan=4,row=0, column=0,padx=5,pady=5,sticky='NSEW')

    bar = Scrollbar(list_frame, orient="vertical", command=app_tree.yview)
    bar.grid(row=0, column=4, sticky='NS')
    app_tree.configure(yscrollcommand=bar.set)

    ar.protocol("WM_DELETE_WINDOW", on_closing_ar)

def process_running():
    if cn == 0:
        messagebox.showinfo("Message", "Not connect to server")
        return
    rt = send("PROCESS")
    if rt == 0:
      messagebox.showinfo("Message", "Can't send data to server")
      return
    def xem():
        msg = send("XEM")
        full_msg = ''
        while True:
            msg = s.recv(HEADER).decode(FORMAT)
            if msg == "Complete!":
                break
            full_msg += msg
        text_process.delete("1.0","end")
        text_process.insert(END,full_msg)

    def kill():
        def on_closing_kill():
            send("QUIT")
            kill.destroy()
        def killID():
            send("KILLID")
            msg = inputID.get()
            send(msg)
            req = s.recv(HEADER).decode(FORMAT)
            if req == 'Done!!!':
                messagebox.showinfo("Message", "Process was killed")
            if req == 'Error!!!':
                messagebox.showinfo("Message", "Error")

        msg = send("KILL")
        kill = Toplevel(process)
        kill.title("Kill")
        inputID = Entry(kill, width =30)
        button_killid = Button(kill, text="Kill", width=15,command=killID)

        inputID.grid(row=0,column=0,padx=10,pady=10,sticky='NSEW')
        button_killid.grid(row=0,column=1,padx=10,pady=10,sticky='NSEW')
        inputID.insert(END,"Input ID")

        kill.protocol("WM_DELETE_WINDOW", on_closing_kill)

    def xoa():
        text_process.delete("1.0","end")

    def start():
        def on_closing():
            send("QUIT")
            start.destroy()
        def startID():
            send("STARTID")
            msg = inputID.get()
            send(msg)
            req = s.recv(HEADER).decode(FORMAT)
            if req == 'Done!!!':
                messagebox.showinfo("Message", "Process was started")
            if req == 'Error!!!':
                messagebox.showinfo("Message", "Error")

        msg = send("START")
        start = Toplevel(process)
        start.title("Start")
        inputID = Entry(start, width =30)
        button_killid = Button(start, text="Start", width=15,command=startID)

        inputID.grid(row=0,column=0,padx=10,pady=10,sticky='NSEW')
        button_killid.grid(row=0,column=1,padx=10,pady=10,sticky='NSEW')
        inputID.insert(END,"Input name")
        start.protocol("WM_DELETE_WINDOW", on_closing)

    def on_closing_pr():
            send("QUIT")
            process.destroy()

    process = Toplevel(gui)
    process.title("Process")
    button_kill = Button(process, text="Kill", width=10, command=kill)
    button_xem = Button(process, text="View", width=10, command=xem)
    button_xoa = Button(process, text="Clear", width=10, command=xoa)
    button_start = Button(process, text="Start", width =10, command=start)

    button_kill.grid(row=0,column=0,padx=5,pady=5,sticky='NSEW')
    button_xem.grid(row=0,column=1,padx=5,pady=5,sticky='NSEW')
    button_xoa.grid(row=0,column=2,padx=5,pady=5,sticky='NSEW')
    button_start.grid(row=0,column=3,padx=5,pady=5,sticky='NSEW')

    text_frame = Frame(process)
    text_frame.grid(columnspan=4,row=1, column=0,pady=5,sticky='NSEW')
    text_process = Text(text_frame, width=48)
    text_process.grid(columnspan=4,row=0, column=0,padx=5,pady=5,sticky='NSEW')

    bar = Scrollbar(text_frame, orient="vertical", command=text_process.yview)
    bar.grid(row=0, column=4, sticky='NS')
    text_process.configure(yscrollcommand=bar.set)

    process.protocol("WM_DELETE_WINDOW", on_closing_pr)

def screenshot():
    if cn == 0:
        messagebox.showinfo("Message", "Not connect to server")
        return

    def take():
        send('SCREENSHOT')
        img = open("img_short.png", "wb")
        msg = s.recv(HEADER)
        while msg != b'Complete!':
            img.write(msg)
            s.sendall("rc".encode(FORMAT))
            msg = s.recv(HEADER)
        img.close()
        img = Image.open("img_short.png")
        resize_img = img.resize((710,400))
        img_show = ImageTk.PhotoImage(resize_img)
        img_label.config(image=img_show)
        img_label.update()
        scr.mainloop()

    def save():
        send('SCREENSHOT')
        files = [('Image', '*.png*'),('All Files', '*.')]
        file = asksaveasfile(mode = "wb", filetypes = files, defaultextension = files)
        print(file)
        msg = s.recv(HEADER)
        while msg != b'Complete!':
            file.write(msg)
            s.sendall("rc".encode(FORMAT))
            msg = s.recv(HEADER)
        file.close()

    send('SCREENSHOT')
    img = open("img_short.png", "wb")
    msg = s.recv(HEADER)
    while msg != b'Complete!':
        img.write(msg)
        s.send("rc".encode(FORMAT))
        msg = s.recv(HEADER)
    img.close()

    scr = Toplevel(gui)
    scr.title("Screen shot")

    button_take = Button(scr, text="Take", width=9, font=('Arial',13), height=6, command=take)
    button_save = Button(scr, text="Save", width=9, font=('Arial',13), height=6, command=save)

    button_take.grid(row=0, column=1, padx=10, pady=10, sticky = 'EW')
    button_save.grid(row=1, column=1, padx=10, pady=10, sticky = 'EW')

    img_frame = Frame(scr)
    img_frame.grid(row=0, column=0, rowspan=2, padx=5, pady=5, sticky = 'NSEW')

    img = Image.open("img_short.png")
    resize_img = img.resize((710,400))
    img_show = ImageTk.PhotoImage(resize_img)

    img_label = Label(img_frame, image=img_show)
    img_label.grid(rowspan=2, row=0, column=0, padx=5, pady=10, sticky='NSEW')
    scr.mainloop()

def videostream():
    if cn == 0:
        messagebox.showinfo("Message", "Not connect to server")
        return
    rt = send('VIDEO')
    if rt == 0:
      messagebox.showinfo("Message", "Can't send data to server")
      return

    data = b""
    payload_size = struct.calcsize("Q")
    while True:
        while len(data) < payload_size:
            packet = s.recv(4*1024) # 4K
            s.send(" ".encode(FORMAT))
            if not packet: break
            data+=packet

        packed_msg_size = data[:payload_size]
        data = data[payload_size:]
        msg_size = struct.unpack("Q",packed_msg_size)[0]
        while len(data) < msg_size:
            data += s.recv(4*1024)
            s.send(" ".encode(FORMAT))
        frame_data = data[:msg_size]
        data  = data[msg_size:]
        frame = pickle.loads(frame_data)
        cv2.imshow("RECEIVING VIDEO",frame)
        if cv2.waitKey(1) == 27:
            msg = s.recv(HEADER*HEADER*HEADER)
            s.sendall("Complete!Complete!Complete!".encode(FORMAT))
            cv2.destroyAllWindows()
            break

def registry():
    def browser():
        global filename
        filename = filedialog.askopenfilename(initialdir = "/", title= "Select a file", filetype=(("registry files","*.reg"),("all files","*.*")))
        show_addr.delete(0, END)
        show_addr.insert(END, filename)
        file_reg = open(filename,"r")
        r_reg = file_reg.read(HEADER*4)
        text_reg.delete("1.0","end")
        text_reg.insert(END, r_reg)
        file_reg.close()

    def send_f():
        send("send file")
        file_reg = open(filename,"rb")
        r_reg = file_reg.read(HEADER*4)
        s.sendall(r_reg)
        file_reg.close()
        msg = s.recv(HEADER).decode(FORMAT)
        if msg == 'done':
            messagebox.showinfo("Message", "Sửa thành công.")
        else:
            messagebox.showinfo("Message", "Sửa thất bại.")

    def def_chosen(event):
        choo = reg_choosen.get()
        if choo == 'Get value':
            input_name.delete(0, END)
            input_name.insert(END,"Name value")
            input_name.grid(row=2, column=0,padx = 5,pady=10,sticky='W')

            input_value.grid_forget()
            type_value_choosen.grid_forget()
        if choo == 'Set value':
            input_name.delete(0, END)
            input_name.insert(END,"Name value")
            input_name.grid(row=2, column=0,padx = 5,pady=10, sticky='W')

            input_value.delete(0, END)
            input_value.insert(END,"Value")
            type_value_choosen.delete(0, END)

            input_value.grid(row=2, column=1,padx = 2,pady=5, sticky='W')
            type_value_choosen.set('Kiểu dữ liệu')
            type_value_choosen.grid(row=2, column=2,padx=5, sticky='EW')
        if choo == 'Delete value':
            input_name.delete(0, END)
            input_name.insert(END,"Name value")
            input_name.grid(row=2, column=0,padx = 5,pady=10, sticky='W')

            input_value.grid_forget()
            type_value_choosen.grid_forget()
        if choo == 'Create key':
            input_name.grid_forget()
            input_value.grid_forget()
            type_value_choosen.grid_forget()
        if choo == 'Delete key':
            input_name.grid_forget()
            input_value.grid_forget()
            type_value_choosen.grid_forget()

    def send_request():
        choo = reg_choosen.get()
        if choo == 'Get value':
            send('Get value')
            path = input_addr.get()
            valueName = input_name.get()
            send(path)
            send(valueName)
            msg = s.recv(HEADER).decode(FORMAT)
            if msg != 'error':
                text_reg2.insert(END, msg + '\n')
            else:
                text_reg2.insert(END, 'Lỗi \n')

        if choo == 'Set value':
            send('Set value')
            path = input_addr.get()
            valueName = input_name.get()
            value = input_value.get()
            typeValue = type_value_choosen.get()
            send(path)
            send(valueName)
            send(value)
            send(typeValue)
            msg = s.recv(HEADER).decode(FORMAT)
            if msg == 'done':
                text_reg2.insert(END, 'Set value thành công.\n')
            else:
                text_reg2.insert(END, 'Set value thất bại.\n')

        if choo == 'Delete value':
            send('Delete value')
            path = input_addr.get()
            valueName = input_name.get()
            send(path)
            send(valueName)
            msg = s.recv(HEADER).decode(FORMAT)
            if msg == 'done':
                text_reg2.insert(END, 'Delete value thành công.\n')
            else:
                text_reg2.insert(END, 'Delete value thất bại.\n')

        if choo == 'Create key':
            send('Create key')
            path = input_addr.get()
            send(path)
            msg = s.recv(HEADER).decode(FORMAT)
            if msg == 'done':
                text_reg2.insert(END, 'Create key thành công.\n')
            else:
                text_reg2.insert(END, 'Create key thất bại.\n')

        if choo == 'Delete key':
            send('Delete key')
            path = input_addr.get()
            send(path)
            msg = s.recv(HEADER).decode(FORMAT)
            if msg == 'done':
                text_reg2.insert(END, 'Delete key thành công.\n')
            else:
                text_reg2.insert(END, 'Delete key thất bại.\n')

    def del_text():
        text_reg2.delete("1.0","end")

    def on_closing_reg():
        send("QUIT")
        reg.destroy()

    if cn == 0:
        messagebox.showinfo("Message", "Not connect to server")
        return
    rt = send("REGISTRY")
    if rt == 0:
      messagebox.showinfo("Message", "Can't send data to server")
      return
    reg = Toplevel(gui)
    reg.title("Registry")

    #frame top
    frame_top = LabelFrame(reg,padx=20,pady=10)

    frame_top.grid(row=0,column=0)
    button_browser = Button(frame_top, text="Browser...", width=15, height = 1, command=browser)
    button_browser.grid(row=0, column=1)

    button_send = tk.Button(frame_top, text="Gởi nội dung", width=15, height=5, command=send_f)
    button_send.grid(row=1, column=1)

    show_addr = Entry(frame_top, width=80)
    show_addr.insert(END,"Đường dẫn...")
    show_addr.grid(row=0, column=0,padx = 5, pady=1)

    text_reg = Text(frame_top, width=60, height=8)
    text_reg.insert(END, "Nội dung")
    text_reg.grid(row=1,column=0,padx=5, pady=5)

    #frame bot
    frame_bot = LabelFrame(reg,text="Sửa giá trị trực tiếp", padx=20,pady=10)
    frame_bot.grid(row=1,column=0, columnspan=1)

    n=tk.StringVar()
    reg_choosen = ttk.Combobox(frame_bot,width = 97,textvariable = n)
    reg_choosen['values'] = ('Get value',
                          'Set value',
                          'Delete value',
                          'Create key',
                          'Delete key')

    reg_choosen.grid(row=0, column=0,padx=5, pady=5, columnspan=3)
    reg_choosen.set('Chọn chức năng')
    reg_choosen.bind("<<ComboboxSelected>>", def_chosen)

    input_addr = Entry(frame_bot, width=100)
    input_addr.insert(END,"Đường dẫn...")
    input_addr.grid(row=1, column=0,padx=5, pady=5, columnspan=3)

    input_name = Entry(frame_bot, width=30)
    input_name.insert(END,"Name value")
    input_name.grid(row=2, column=0,padx = 5,pady=10, sticky='W')

    input_value = Entry(frame_bot, width=30)
    input_value.insert(END,"Value")
    input_value.grid(row=2, column=1,padx = 2,pady=5, sticky='W')

    n1=tk.StringVar()
    type_value_choosen = ttk.Combobox(frame_bot,textvariable = n1, width=30)
    type_value_choosen['values'] = ('String',
                'Binary',
                'DWORD',
                'QWORD',
                'Multi-String',
                'Expandable String')

    type_value_choosen.set('Kiểu dữ liệu')
    type_value_choosen.grid(row=2, column=2,padx=5, sticky='EW')

    text_reg2 = Text(frame_bot, width=70, height=8)
    text_reg2.grid(row=4,column=0,padx=5, pady=5, columnspan=3, sticky='NSEW')

    button_send2 = tk.Button(frame_bot, text="Gởi", width=15, command=send_request)
    button_send2.grid(row=5, column=0, padx = 5, sticky=E)

    button_del = tk.Button(frame_bot, text="Xóa", width=15, command=del_text)
    button_del.grid(row=5, column=2, padx = 5, sticky=W)
    reg.protocol("WM_DELETE_WINDOW", on_closing_reg)
    reg.mainloop()

def macaddress():
    if cn == 0:
        messagebox.showinfo("Message", "Not connect to server")
        return
    rt = send("MAC")
    if rt == 0:
      messagebox.showinfo("Message", "Can't send data to server")
      return
    msg = s.recv(HEADER).decode(FORMAT)

    mac = Toplevel(gui)
    mac.title("Mac address")

    frameMA = LabelFrame(mac,bg = "black", padx=0,pady=0)
    frameMA.grid(row=0,column=0)

    text_mac = Text(frameMA, background = "black",fg = "white",font = ("Arial", 12), width=50, height=3)
    text_mac.insert(END, "\n  Physical Adress..........: " + msg)
    text_mac.grid(row=0,column=0,padx=0, pady=0)

    mac.mainloop()

def folderstructure():
    if cn == 0:
        messagebox.showinfo("Message", "Not connect to server")
        return
    rt = send("FOLDER")
    if rt == 0:
      messagebox.showinfo("Message", "Can't send data to server")
      return

    f_name = ""

    def double_click(event):
        for click_item in tree.selection():
            item = tree.item(click_item)
            record = item['values']
            if record[1] != "File folder":
                messagebox.showinfo("Message", "This is not a folder, can not access")
                return
            send("GOTO")
            s.sendall(str(record[0]).encode(FORMAT))
            msg = s.recv(HEADER)
            data = pickle.loads(msg)

            files = splitListFile(data)

            for i in tree.get_children():
                tree.delete(i)
            for file in files:
                tree.insert('', END, values = file)

    def right_click(event):
        for click_item in tree.selection():
            item = tree.item(click_item)
            global f_name
            f_name = item['values']
            try:
                filemenu.tk_popup(event.x_root, event.y_root)
            finally:
                filemenu.grab_release()

    def recvf():
        global f_name
        fileadrr = filedialog.askopenfilename(initialdir = "/", title= "Select a file",
                                                filetype=(("all files","*.*"),("jpeg files","*.jpg")))
        filename = fileadrr.split("/")
        send("RECEIVE")
        s.send((str(f_name[0]) + "\\" + filename[len(filename) - 1]).encode(FORMAT))
        file_s = open(fileadrr,"rb")
        dataf = file_s.read(HEADER)
        while (dataf):
            s.send(dataf)
            msg = s.recv(HEADER)
            dataf = file_s.read(HEADER)
        file_s.close()
        s.send("Done!".encode(FORMAT))

    def deletef():
        global f_name
        send("DELETE")
        if f_name[1] == "File folder":
            s.send(str(f_name[0]).encode(FORMAT))
        else:
            s.send((str(f_name[0]) + '.' + str(f_name[1])).encode(FORMAT))
        selected_item = tree.selection()[0]
        tree.delete(selected_item)

    def on_closing_fol():
        send("QUIT")
        fol.destroy()

    def splitListFile(data):
        files = []
        i = 0
        for f in data:
            if "." in f:
                splits = f.split(".")
                files.append(splits)
                i += 1
            else:
                files.append((f, "File folder"))
                i += 1
        return files

    def back():
        send("BACK")
        msg = s.recv(HEADER)
        data = pickle.loads(msg)

        files = splitListFile(data)
        print(files)
        for i in tree.get_children():
            tree.delete(i)
        for file in files:
            tree.insert('', END, values = file)

    msg = s.recv(HEADER)
    data = pickle.loads(msg)

    fol = Toplevel(gui)
    fol.title("Folder")

    files = splitListFile(data)

    frame = Frame(fol)
    frame.grid(row=0, column=0, pady=5,sticky='NSEW')

    columns = ('namef', 'type')
    tree = ttk.Treeview(frame, columns=columns, show='headings')

    tree.heading('namef', text='Name')
    tree.heading('type', text='Type')

    for file in files:
        tree.insert('', END, values = file)

    menubar = Menu(gui)

    filemenu = Menu(menubar, tearoff=0)
    filemenu.add_command(label="Receive", command=recvf)
    filemenu.add_command(label="Delete", command=deletef)

    tree.bind('<Double-1>', double_click)
    tree.bind('<Button-3>', right_click)

    tree.grid(row=0, column=0, sticky='NSEW')
    scrollbar = ttk.Scrollbar(frame, orient = "vertical", command=tree.yview)
    tree.configure(yscroll=scrollbar.set)
    scrollbar.grid(row=0, column=1, sticky='NS')

    button_back=Button(fol, text="Back",width=10, bg="BLACK", fg="WHITE", command = back)
    button_back.grid(columnspan=2, row=2, column=0, padx=10, pady=5, sticky='NS')

    fol.protocol("WM_DELETE_WINDOW", on_closing_fol)
    fol.mainloop()

def close():
    global cn
    if cn == 0:
        gui.destroy()
        return

    disconnect()
    s.shutdown(2)
    s.close()
    cn = 0
    gui.destroy()

gui = tk.Tk()
gui.title("Client")
textIp = Entry(gui,text="Input", width =32)
textIp.insert(END,"Nhập địa chỉ IP")
textIp.grid(row=0, column=0, columnspan=6, padx=5, pady=10, sticky='NSEW')

button_connect=Button(gui, text="Connect",width=7, bg="BLACK", fg="WHITE", command = connect)
button_connect.grid(columnspan=2, row=0, column=4, padx=5, pady=10, sticky='E')

button_process=Button(gui,text="Folder",width=18,height=3, command = folderstructure)
button_process.grid(columnspan=2, row=1, column=0, padx=5, pady=5, sticky='NSEW')

button_video=Button(gui,text="Video screen",width=35,height=3, command = videostream)
button_video.grid(columnspan=4, row=1, column=2, padx=5, pady=5, sticky='NSEW')

button_process=Button(gui,text="Process\nRunning",width=10,height=3, command = process_running)
button_process.grid(rowspan=3, row=2, column=0, padx=5, pady=5, sticky='NSEW')

button_app=Button(gui,text="App Running",width=20,height=4, command = app_running)
button_app.grid(columnspan=2, row=2, column=1, padx=5, pady=5, sticky='NSEW')

button_shutdown=Button(gui,text="Shutdown",width=8,height=4, command=shutdown)
button_shutdown.grid(columnspan=1, row=2, column=3, padx=5, pady=5, sticky='NSEW')

button_shutdown=Button(gui,text="Logout",width=8,height=4, command=logout)
button_shutdown.grid(columnspan=1, row=3, column=1, padx=5, pady=5, sticky='NSEW')

button_screenshot=Button(gui,text="ScreenShot",width=20,height=4, command=screenshot)
button_screenshot.grid(columnspan=2, row=3, column=2, padx=5, pady=5, sticky='NSEW')

button_keystroke=Button(gui,text="Keystroke\n&\nKeylock",width=15,height=4, command=keystroke_keylock)
button_keystroke.grid(columnspan=2, rowspan=2, row=2, column=4, padx=5, pady=5, sticky='NSEW')

button_registry=Button(gui,text="Registry",width=40,height=3, command=registry)
button_registry.grid(columnspan=4, row=4, column=1, padx=5, pady=5, sticky='NSEW')

button_close=Button(gui,text="Mac\nAdress",width=7,height=3, command=macaddress)
button_close.grid(columnspan=1, row=4, column=5, padx=5, pady=5, sticky='NSEW')

gui.protocol("WM_DELETE_WINDOW", close)
gui.mainloop()


n = int(input())
money = 0
if n // 5 > 0:
    money += n//5
    n %= 5
    if n % 2 == 1: #5로 나눈 나머지가 홀수이면 5로 나눈 몫을 하나 줄이고 나머지에 5를 더함
        money -= 1
        n += 5
if n // 2 > 0:
    money += n//2
    n %= 2

if n != 0:
    print(-1)
else:
    print(money)


import os
import openai
import streamlit as st
from dotenv import load_dotenv

load_dotenv()
openai.api_type = "azure"
openai.api_version = "2023-05-15"
openai.api_key  = os.environ['OPENAI_API_KEY']
openai.api_base = os.getenv("OPENAI_API_BASE")

response = openai.ChatCompletion.create(
    engine="gpt-4",
    messages=[
        {"role": "system", "content": "Assistant is a large language model trained by OpenAI."},
        {"role": "user", "content": "Where are the headquarters of Just Eat Takeaway.com?"}
    ]
)

st.title('Hackathon 2023')
st.write(response['choices'][0]['message']['content'])
# print(response['choices'][0]['message']['content'])


"""
Readymade spherical lens optical object.

References:
.. [1] Warren J. Smith, Modern Optical engineering, SPIE Press, 4th ed., 2008
"""

from ..object import AssembledObject
from ..surface import Surface
from ..flat_surface import RoundPlateGM
from ..sphere_surface import CutSphereGM
from ..boundary_shape import BoundaryPlane
from ..cylinder import FiniteCylinder
from ..optics_callables import RefractiveHomogenous as Refractive
from ..spatial_geometry import rotx

import numpy as N

class SphericalLens(AssembledObject):
    def __init__(self, diameter, depth, R1, R2, refr_idx, transform=None):
        """
        Create at least two lens surfaces (back and front), and possibly a
        cylindrical face to close the object if its diameter is smaller than
        the diameter at which the two surfaces intersect each other.

        Note: if the optical path is thought of as going from left to right,
        the the positive Z axis is 'left'. It is also called 'up' due to the
        usual terminology in solar systems.

        Arguments:
        diameter - of the lens aperture.
        depth - distance between back and front surfaces along the lens's
            optical axis.
        R1, R2 - the radii of the front and back surfaces, respectively (the
            front is the surface facing rays coming down the Z axis). Positive
            radius indicates that the center of curvature is down the Z axis
            from the surface, and either 0, None or infinity indicate planar face.
        refr_idx - refractive index of the material of the lens.
        """
        flip_side = rotx(N.pi)[:3,:3]

        # Front surface:
        if R1 in [0, None, N.inf, -N.inf]:
            self._front = Surface(
                RoundPlateGM(diameter/2.),
                Refractive(1., refr_idx))
            R1 = B.inf
        else:
            z = N.sqrt(R1**2 - diameter**2/4.) # location of cut plane
            if R1 > 0:
                sect1 = BoundaryPlane(location=N.r_[0, 0, z])
            else:
                sect1 = BoundaryPlane(location=N.r_[0, 0, -z], rotation=flip_side)
            sphere = CutSphereGM(radius=abs(R1), bounding_volume=sect1)

            refr=Refractive(1., refr_idx)
            self._front = Surface(geometry=sphere, optics=refr)

        # Back surface:
        if R2 in [0, None, N.inf, -N.inf]:
            self._back = Surface(
                RoundPlateGM(diameter/2.),
                Refractive(1., refr_idx),
                rotation=flip_side)
            R2 = N.inf
        else:
            z = N.sqrt(R2**2 - diameter**2/4.) # location of cut plane
            if R2 > 0:
                sect2 = BoundaryPlane(location=N.r_[0, 0, z])
            else:
                sect2 = BoundaryPlane(location=N.r_[0, 0, -z], rotation=flip_side)
            sphere = CutSphereGM(radius=abs(R2), bounding_volume=sect2)

            refr=Refractive(1., refr_idx)
            self._back = Surface(geometry=sphere, optics=refr)

        # While locating the surfaces, we'll calculate bounding cylinder
        # dimensions, and create it after the fact.
        cyl_height = 0
        cyl_loc = 0

        # Locate the planes such that the second focal point is at Z = -f,
        # where f is the focal length found from the lensmaker equation.
        # see [1] p.46, eqn. 3.21a
        opt_power = (refr_idx - 1)*(1./R1 - 1./R2 + depth*(refr_idx - 1)/R1/R2/refr_idx)
        f = 1./opt_power

        # Back primary point's distance from back surface:
        pd = f*depth*(refr_idx - 1)/refr_idx/R1
        if R2 != N.inf:
            locb = pd - R2
            self._back.set_location(N.r_[0., 0., locb])

            cyl_loc += (locb + sect2.get_location()[2])/2.
            cyl_height -= locb + sect2.get_location()[2]

        # Front primary point's distance from front surface:
        if R1 != N.inf:
            locf = pd + depth - R1
            self._front.set_location(N.r_[0., 0., locf])

            cyl_loc += (locf + sect1.get_location()[2])/2.
            cyl_height += locf + sect1.get_location()[2]

        # Create the bounding cylinder:
        if cyl_height > 0:
            self._cyl = Surface(
                FiniteCylinder(diameter, cyl_height),
                Refractive(refr_idx, 1.), location=N.r_[0., 0., cyl_loc])
            surfs = [self._front, self._back, self._cyl]
        else:
            surfs=[self._front, self._back]

        # Finalize the object:
        AssembledObject.__init__(self, surfs=surfs, transform=transform)
        self._f = f

    def focal_length(self):
        """
        Reports the lens' calculated effective focal length - the distance from
        the back primary point (at Z=0) to the back focal point.
        """
        return self._f


from django.core.management.base import BaseCommand, CommandError
from django.utils import timezone

from ranker.models import Domain

import csv

class Command(BaseCommand):
    help = "import a list of domains at first launch"

    def add_arguments(self, parser):
        parser.add_argument('file_path', nargs=1, type=str)
        #This is a positional argument, which, since added first, evaluates the first word to come after the command
        # The nargs='+' command says to take every word in the command and combine it together into a list and error if no words are found

    def handle(self, *args, **options):
        #handle is a special method that the django manage command will run, with the args and options provided

        if Domain.objects.count() > 0:
            self.stderr.write(f"There are already {Domain.objects.count()} domains in the database. Skipping import.")
            return

        myfile = options["file_path"][0]
        start_time = timezone.now()

        with open(myfile, "r") as csv_file: #with replaces a try/finally syntax and ensures all files that are opened are closed and resources released.
            data = csv.reader(csv_file, delimiter=",")
            domains = []
            next(data) #Skip header row
            def maybe_int(val):
                try:
                    return int(val)
                except:
                    return val
            for row in data:
                if maybe_int(row[5]) == 0:
                    adult = True
                else:
                    adult = False
                domain = Domain(
                    rank=row[0],
                    domain=row[1],
                    keywords=row[2],
                    traffic=row[3],
                    cost=row[4],
                    ad_keywords=row[5],
                    ad_traffic=row[6],
                    ad_cost=row[7],
                    adult_content = adult
                )
                domains.append(domain)
                if len(domains) > 5000:
                    Domain.objects.bulk_create(domains
                            , update_conflicts=True
                            , update_fields=["rank", "keywords", "traffic", "cost", "ad_keywords", "ad_traffic", "ad_cost", "adult_content"]
                            , unique_fields=["domain"]
                    )
                    self.stdout.write(f"Bulk upsert completed: {len(domains)} records")
                    domains = []
            if domains:
                    Domain.objects.bulk_create(domains
                            , update_conflicts=True
                            , update_fields=["rank", "keywords", "traffic", "cost", "ad_keywords", "ad_traffic", "ad_cost", "adult_content"]
                            , unique_fields=["domain"]
                    )
            self.stdout.write(f"Bulk upsert completed: {len(domains)} records")

        end_time = timezone.now()
        self.stdout.write(
            self.style.SUCCESS(
                f"Loading CSV took: {(end_time-start_time).total_seconds()} seconds."
            )
        )


"""
Provides a set of functions for checking resource sufficiency, making coffee,
and generating a report on the coffee machine's resources.
"""

resources = {
    "water": 300,
    "milk": 200,
    "coffee": 100,
}

def is_resource_sufficient(drink):
    """
    Checks if there are enough resources to make a given drink.
    """
    order_ingredients = drink["ingredients"]
    for item in order_ingredients:
        if order_ingredients[item] > resources[item]:
            print(f"Sorry there is not enough {item}.")
            return False
    return True

def make_coffee(drink):
    """
    Makes a drink and updates resource values.
    """
    order_ingredients = drink["ingredients"]
    for item in order_ingredients:
        resources[item] -= order_ingredients[item]
    print(f"Here is your {drink['name']}. Enjoy!")

def report():
    """
    Prints the current resources values.
    """
    print(f"Water: {resources['water']}ml")
    print(f"Milk: {resources['milk']}ml")
    print(f"Coffee: {resources['coffee']}g")


import random
import multiprocessing
import unittest

from . import auto_retry, STMValue, atomic, retry, STMObject, ConflictError, on_commit, transactional, retries, conflicts

class BankAccount(object):
    def __init__(self, account_number, initial_balance):
        self.account_number = account_number
        self.balance = STMObject(initial_balance) #STMValue("i", initial_balance)

@auto_retry()
#@auto_retry()
def do_trade(accts, count):
    acct1 = acct2 = random.choice(accts)
    while acct1 == acct2:
        acct2 = random.choice(accts)

    # transactify
    with atomic():
        try:
            amt = random.randint(0, acct1.balance.value-1)
        except ValueError:
            retry() # raise ConflictError?

        # try nesting to make sure it doesn't crash
        with atomic():
            acct1.balance.value -= amt
            acct2.balance.value += amt

def trader(accts, count):
    for _ in range(0, count):
        do_trade(accts, count)

class TestBasic(unittest.TestCase):
    def test_main(self):
        n = 10 # num threads
        c = 1000 # num xact
        a = 30 # num accounts
        cash = 100

        accts = []

        for account_number in range(0, a):
            accts.append(BankAccount(account_number, cash))

        processes = []

        for _ in range(0, n):
            processes.append(multiprocessing.Process(target=trader, args=(accts, c)))
            processes[-1].start()

        for p in processes:
            p.join()

        self.check(cash, a, accts)

    @auto_retry()
    def check(self, cash, a, accts):
        nonhundo = False
        with atomic():
            total_cash = cash * a
            for acct in accts:
                if acct.balance.value != 100:
                    nonhundo = True
                total_cash -= acct.balance.value

        self.assertTrue(nonhundo)
        self.assertEqual(0, total_cash)

    def test_pickle(self):
        a = STMObject(128)
        with atomic():
            a.value = "pete"
            self.assertEqual(a.value, "pete")
        # test mutation
        with atomic():
            a.value = [1,2,3]
            self.assertEqual(a.value, [1,2,3])
            a.value.append(7)
            self.assertEqual(a.value, [1,2,3,7])

    @transactional()
    def helper(self):
        on_commit(self.l.append, 1)

        if conflicts() < 3:
            raise ConflictError

    def test_on_commit(self):
        self.l = []
        self.helper()
        self.helper()
        self.helper()
        self.assertEqual(3, sum(self.l))

    def test_exception(self):
        x = STMValue("i",0)
        try:
            with atomic():
                x.value += 1
                raise ValueError
            self.fail()
        except ValueError:
            pass
        with atomic():
            self.assertEqual(x.value, 0)

if __name__ == "__main__":
    unittest.main()


import json
import logging
import os
import random
import time
from concurrent.futures.thread import ThreadPoolExecutor
from enum import Enum
from typing import List
from urllib.parse import urlencode

import requests

from src.utils import *

class Mode(Enum):
    MODE_MONTH = "monthly"
    MODE_WEEK = "weekly"
    MODE_DAY = "daily"
    MODE_ROOKIE = "rookie"
    MODE_ORIGINAL = "original"
    MODE_MALE = "male"
    MODE_FEMALE = "female"
    MODE_R18 = "_r18"

ONLY_ILLUST = True
ONLY_COVER = True
TIMEOUT = 60
MODE: Mode = Mode.MODE_WEEK
SAVE_PATH = "../images/"
DELAY_SECONDS = 3
r18 = False

HEADER = {
    "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
                  "Chrome/90.0.4430.212 Safari/537.36 "

}
PROXY = {"http": "socks5://127.0.0.1:19527", "https": "socks5://127.0.0.1:19527"}

def create_rank_url(index: int) -> str:
    qurey = {
        "mode": MODE.value,
        "p": index,
        "format": "json"
    }
    if r18:
        qurey["mode"] += MODE.MODE_R18.value
    if ONLY_ILLUST:
        qurey["content"] = "illust"
    return f"https://www.pixiv.net/ranking.php?{urlencode(qurey)}"

def task_generator():
    item_count = 0
    index = 1
    while True:
        url = create_rank_url(index)
        resp = session.get(url)
        data = json.loads(resp.text)
        contents: List = data["contents"]
        for content in contents:
            yield int(content["illust_id"])

        item_count += len(contents)
        if item_count >= data["rank_total"]:
            break
        index += 1

def task_pages(illust_id: int):
    pages_url = f"https://www.pixiv.net/ajax/illust/{illust_id}/pages?lang=zh"
    data = json.loads(session.get(pages_url).text)
    for item in data["body"]:
        yield item["urls"]["original"]

def task_img_download(img_url: str, name: str, delay: float = 0) -> bool:
    path = get_img_save_path(name)
    try:
        if len(name) == 0:
            return False

        if delay >= 0:
            logging.info(f"休眠{delay}秒")
            time.sleep(delay)

        resp = session.get(url=img_url, stream=True, timeout=TIMEOUT, headers={"referer": "https://www.pixiv.net"})
        total_size = int(resp.headers["content-length"])
        logging.info(f"{img_url}({format_file_size(total_size)})开始下载")
        size = 0

        with open(path, "wb") as f:
            for chunk in resp.iter_content(chunk_size=4 * 1024):
                f.write(chunk)
                size += len(chunk)
                # logging.info(f'{img_url}已下载:{percentage(size / total_size)}')
            f.close()
        logging.info(f"{img_url}：下载成功")
        return True
    except Exception as e:
        logging.error(img_url + "：下载失败")
        logging.exception(e)
        if os.path.exists(path):
            os.remove(path)
        return False

def get_img_save_path(name):
    return SAVE_PATH + "/" + name

def main():
    tasks = []
    if not os.path.exists(SAVE_PATH):
        os.makedirs(SAVE_PATH)
    thread_pool = ThreadPoolExecutor(max_workers=5)
    img_count = 0
    exist_count = 0
    for illust_id in task_generator():
        for img_url in task_pages(illust_id):
            img_count += 1
            name = get_name_from_url(img_url)
            path = get_img_save_path(name)
            if os.path.exists(path):
                exist_count += 1
                logging.info(f"{img_url}：已存在")
                if ONLY_COVER:
                    break
                else:
                    continue

            delay = DELAY_SECONDS + random.randint(0, 5)
            tasks.append(thread_pool.submit(task_img_download, img_url, name, delay))

            if ONLY_COVER:
                break
        # if img_count >= 10:
        #     break

    success = 0
    for task in tasks:
        if task.result():
            success += 1

    logging.info(f"图片数：{img_count},成功下载数：{success},已下载数：{exist_count},失败下载数：{img_count - success - exist_count}")

if __name__ == '__main__':
    logging.basicConfig(level=logging.INFO)

    session = requests.session()
    session.proxies = PROXY
    session.headers = HEADER
    main()