from django.shortcuts import render
from django.views.decorators.csrf import csrf_exempt
import json
# import datetime
from datetime import datetime
from .models import Departments,Roles
from str2bool import str2bool
from django.http import JsonResponse
import ast
from django.core.paginator import Paginator

# Create your views here.

@csrf_exempt
def adding_departments(request):
    status = ''
    message = ''
    status_code = ''

    try:
        requestData = json.loads(request.body)
    except:
        requestData = request.POST

    try:
        departments_name = requestData.get(u"departments_name", None)
        added_by = requestData.get(u"added_by", None)
        added_date = datetime.now()

        # [{"name":"Android","status":"true"}, {"name":"Web","status":"true"}]
        departments_name = ast.literal_eval(str(departments_name))

        try:
            for i in departments_name:
            #for i in jintu
                Departments.objects.get_or_create(department_name=(i['name']),\
                                                defaults={'status': str2bool(i['status']), 'added_by': added_by,
                                                            'added_datetime': added_date})
                #checking department_name is already exist
                status = "Success"
                message = "Successfully Departments created"
                status_code = 200
        except Exception as e:
            import traceback
            traceback.print_exc()
            status = "Failed"
            message = str(e)
            status_code = 400

    except Exception as e:
        status = "Failed"
        message = str(e)
        status_code = 400
    return JsonResponse({"status": status, "message": message, "status_code": status_code})

@csrf_exempt
def getting_departments(request):
    status = ''
    message = ''
    status_code = ''
    total_page = ''
    index_page = ''
    json_data = []
    data = dict()
    try:
        requestData = json.loads(request.body)
    except:
        requestData = request.POST
    try:
        page = requestData.get(u"page", None)
        total_departments = Departments.objects.all()

        if total_departments.exists():
            departments_paginator = Paginator(total_departments, 10)
            if int(page) > 0:
                pag_num = departments_paginator.get_page(page)
                n_deppg = str(pag_num)[1:-1]
                n = [int(i) for i in n_deppg.split() if i.isdigit()]
                total_page = str(n[1])

                if int(page) <= int(total_page):
                    for obj in pag_num:
                        data1 = {"primary_key": obj.primary_key, "department_name": obj.department_name,\
                                 "status": obj.status,\
                                 "added_by": obj.added_by, "added_datetime": obj.added_datetime,\
                                 "updated_datetime": obj.updated_datetime}
                        json_data.append(data1)

                    index_page = str(n[0])
                    status = "Success"
                    message = "Successfully received the departments"
                    status_code = 200
                else:
                    status = "Failed"
                    message = "Total department pages across the limit"
                    status_code = 409
            else:
                status = "Failed"
                message = "Total department pages beyond the limit"
                status_code = 409
    except Exception as e:
        status = "Failed"
        message = str(e)
        status_code = 404
    return JsonResponse({"status": status, "data": json_data, "message": message, \
                         "status_code": status_code, "total_page": total_page, "index_page": index_page})

###updating departments
@csrf_exempt
def updating_departments(request):
    status = ''
    message = ''
    status_code = ''

    try:
        requestData = json.loads(request.body)
    except:
        requestData = request.POST

    try:
        primary_key = requestData.get(u"primary_key", None)
        new_department_name = requestData.get(u"new_department_name", None)
        new_status = requestData.get(u"new_status", None)
        updated_datetime = datetime.now()

        try:
            get_departments = Departments.objects.get(primary_key=primary_key)

            if new_department_name != None and new_department_name != "":
                check_department = Departments.objects.filter(department_name__iexact=new_department_name)
                                                            #(department_name__iexact = "jintu")

                if check_department.exists() == False:
                    #jintu in not there
                    get_departments.department_name = new_department_name
                    get_departments.status = str2bool(new_status)
                    get_departments.updated_datetime = updated_datetime
                    get_departments.save()

                    status = "Success"
                    message = "Department details updated successfully"
                    status_code = 200
                else:
                    status = "Failed"
                    message = "Department name already exists"
                    status_code = 409
            else:
                status = "Failed"
                message = "Department name cannot be empty"
                status_code = 403
        except Exception as e:
            status = "Failed"
            message = str(e)
            status_code = 400
    except Exception as e:
        status = "Failed"
        message = str(e)
        status_code = 400
    return JsonResponse({"status": status, "message": message, "status_code": status_code})

###adding roles
@csrf_exempt
def adding_roles(request):
    status = ''
    message = ''
    status_code = ''

    try:
        requestData = json.loads(request.body)
    except:
        requestData = request.POST

    try:
        department_name = requestData.get(u"department_name", None)
        role_name = requestData.get(u"role_name", None)
        added_by = requestData.get(u"added_by", None)
        added_date = datetime.now()

        # [{"name":"Role","status":"true"}, {"name":"Role1","status":"true"}]
        role_name = ast.literal_eval(str(role_name))
        try:
            departments = Departments.objects.get(primary_key=department_name)
            for i in role_name:
                Roles.objects.get_or_create(department_name=departments, \
                                            role_name=(i['name']), \
                                            defaults={'status': str2bool(i['status']), 'added_by': added_by,
                                                      'added_datetime': added_date})
                status = "Success"
                message = "Roles was created successfully"
                status_code = 200
        except Exception as e:
            status = "Failed"
            message = str(e)
            status_code = 404
    except Exception as e:
        status = "Failed"
        message = str(e)
        status_code = 404
    return JsonResponse({"status": status, "message": message, "status_code": status_code})

###getting roles
@csrf_exempt
def getting_roles(request):
    status = ''
    message = ''
    status_code = ''
    index_page = ''
    total_page = ''
    json_data = []
    data = dict()

    try:
        requestData = json.loads(request.body)
    except:
        requestData = request.POST
    try:
        page = requestData.get(u"page", None)
        department_name = requestData.get(u"department_name")

        departments = Departments.objects.get(primary_key=department_name)
        total_roles = Roles.objects.filter(department_name=departments)

        if total_roles.exists():
            roles_paginator = Paginator(total_roles, 10)
            if int(page) > 0:
                pag_num = roles_paginator.get_page(page) #page = 1,2,3,4... whatever
                n_rolepg = str(pag_num)[1:-1]
                # print("n_rolepg:"n_rolepg) -> o/p n_rolepg: input_page of total page
                n = [int(i) for i in n_rolepg.split() if i.isdigit()]
                total_page = str(n[1])

                if int(page) <= int(total_page):
                    for obj in pag_num:
                        data1 = {"primary_key": obj.primary_key,\
                                 "role_name": obj.role_name, "status": obj.status, "added_by": obj.added_by,\
                                 "added_datetime": obj.added_datetime, "updated_datetime": obj.updated_datetime}
                        json_data.append(data1)

                    index_page = str(n[0])
                    status = "Success"
                    message = "Successfully received the roles"
                    status_code = 200
                else:
                    status = "Failed"

                    message = "Total roles pages across the limit"
                    status_code = 409
            else:
                status = "Failed"
                message = "Total roles pages beyond the limit"
                status_code = 409

    except Exception as e:
        status = "Failed"
        message = str(e)
        status_code = 400
    return JsonResponse({"status": status, "data": json_data, "message": message, \
                         "status_code": status_code, "total_page": total_page, "index_page": index_page})

###update the roles
@csrf_exempt
def updating_roles(request):
    status = ''
    message = ''
    status_code = ''
    try:
        requestData = json.loads(request.body)
    except:
        requestData = request.POST
    try:
        primary_key = requestData.get(u"primary_key", None)
        department_name = requestData.get(u"department_name", None)
        new_role_name = requestData.get(u"new_role_name", None)
        new_status = requestData.get(u"status", None)
        updated_datetime = datetime.now()

        try:
            departments = Departments.objects.get(primary_key=department_name)
            get_roles = Roles.objects.get(primary_key=primary_key, department_name=departments)

            if new_role_name != None and new_role_name != "":
                check_role = Roles.objects.filter(role_name__iexact=new_role_name) #check the new_role name is exist or not
                if check_role.exists() == False: #if exist is FAlse value . mean not exist the new role name . It will update with new value
                    get_roles.role_name = new_role_name
                    get_roles.status = str2bool(new_status)
                    get_roles.updated_datetime = updated_datetime
                    get_roles.save()

                    status = "Success"
                    message = "Successfully update the roles"
                    status_code = 200
                else:
                    status = "Failed"
                    message = "Roles name already exists"
                    status_code = 409
            else:
                status = "Failed"
                message = "Roles name can not be empty"
                status_code = 403

        except Exception as e:
            status = "Failed"
            message = str(e)
            status_code = 400
    except Exception as e:
        status = "Failed"
        message = str(e)
        status_code = 400
    return JsonResponse({"status": status, "message": message, "status_code": status_code})


import openai
import json
from sqlalchemy import *

# Common pricol
from conversation import conversation_Victoria
from config import *

openai.api_key = openai_api
chat_json = json.dumps(conversation_Victoria, ensure_ascii=False)
query_exec1 = f"""
create or replace procedure update_chat_info(in p_username varchar, in p_add json)
language plpgsql
as $$
begin
    if p_username not in (select user_name from chat_info) then
        insert into chat_info (user_name, chat) values (p_username, '{chat_json}'::json);
    else
         update chat_info SET chat = p_add where user_name = p_username;
    end if;
end;
$$;
"""
conn.execute(text(query_exec1))
conn.commit()
print("update_chat_info created or replaced...")

def update_history(message, role, user_name):
    message = message.replace("'", "`")
    info_json = chat_json
    info = conn.execute(
        text(f"SELECT chat FROM chat_info WHERE user_name = '{user_name}'")).fetchall()

    if info:
        new_message = {"role": role, "content": message}
        #print(f"UPDATING DATA as {role}")
        chat_list_json = info[0][0]
        chat_list = json.loads(chat_list_json)
        chat_list.append(new_message)
        info_json = json.dumps(chat_list, ensure_ascii=False)
        conn.execute(
            text(f"CALL update_chat_info('{user_name}', '{info_json}')"))
        #print("DATA COMMITTED")
        conn.commit()
    else:
        conn.execute(
            text(f"CALL update_chat_info('{user_name}', '{info_json}')"))
        update_history(message, role, user_name)
        #print(f"No chat info found for user {user_name}")

def generate_response(conversation):
    #print(conversation)
    #print("GENERATING RESPONSE")
    if conversation == []:
        return "I don't know"
    else:
        response = openai.ChatCompletion.create(
            model="gpt-3.5-turbo",
            messages=conversation,
            temperature=0.2
        )
    #print(f"generated: {response.choices[0].message.content}")
    return response.choices[0].message.content


#!/usr/bin/env python
import sys
WORD=8192
BITS=32
MUX=16
MEM_WIDTH=512
MEM_HEIGHT=512
def get_row_col(addr):
    row = int(addr/MUX)
    col = addr & (MUX-1)
    return (row, col)
def get_bit_vector(data, col=0):
    """ Return data at specific column """
    d = []
    for i in range(0,BITS):
        d.append(((data >> i) & 0x1)<<col)
    return d
def gen_ram_hex(spi_stim, output_file):
    mems = []
    for i in range(0, MEM_HEIGHT):
        mems.append([0 for i in range(0,BITS)])
    with open(spi_stim) as f:
        for l in f:
            addr,data=l.replace("@", "").split(" ")
            row,col = get_row_col(int(addr,16))
            b = get_bit_vector(int(data,16), col)
            old_data = mems[row]
            new_data = [b[i] | old_data[i] for i in range(0,BITS)]
            # b_str = [("%04X" % b[i]) for i in range(0, BITS)]
            # b_str = " ".join(b_str)
            # new_data_str = [("%04X" % new_data[i]) for i in range(0, BITS)]
            mems[row] = new_data
            # print addr, row, col, data, b_str
            # print " ".join(new_data_str)
    with open(output_file, 'w') as f:
        for row in range(0, MEM_HEIGHT):
            row_data = [("%04X" % mems[row][i]) for i in range(BITS-1,-1,-1)]
            f.write("".join(row_data))
            f.write("\n")

if __name__ == "__main__":
    gen_ram_hex(sys.argv[1], sys.argv[2])


'''
Exercise 11-4.
---------------
Modify reverse_lookup so that it builds and returns a list of all keys that map to v , or
an empty list if there are none.'''

def reverseLookup(d, v):
    # d - dict, v - value
    keyList = []
    for k in d:
        if d[k] == v:
            keyList.append(k)
    return keyList

print(reverseLookup({'n':1, 'i':3, 'k':1}, 1))


from falcons.check import Checker
from falcons.com.nick import feature, story, step, fixture

from main.actions.sprint import SprintAction
from main.api import project as api
from main.params import more

@fixture(scope='module')
def _storage():
    p = {}

    return p

# 初始化迭代
@fixture(scope='module', autouse=True)
def init_sprint(_storage):
    sprint_uuid = SprintAction.sprint_add()

    _storage |= {'sprint_uuid': sprint_uuid}

@feature('工时管理相关')
class TestWorkHourOne(Checker):

    def time_log_operate(self, body, token=None):
        """工时日志操作"""
        param = more.graphql_body(body)[0]
        q = self.call(api.ItemGraphql, param, token)

        return q.json()['data']

    @story('工时日志：列表信息')
    def test_list_info(self, _storage):
        param = more.time_log_list()[0]
        info = self.call(api.ItemGraphql, param)

        # 获取默认的分组'工时分析'key
        default_key = [r['key'] for r in info.json()['data']['reportCategories'] if r['name'] == '工时分析'][0]
        repost_info = [r for r in info.json()['data']['teamReports']]

        _storage |= {'default_key': default_key, 'repost_info': repost_info}

    @story('工时日志-分组：新建分组')
    def test_group_add(self, _storage):
        param = more.group_add()
        rp = self.time_log_operate(body=param)

        _storage |= {'group_key': rp['addReportCategory']['key']}

    @story('122337 工时日志-分组：重命名')
    def test_group_rename(self, _storage):
        param = more.group_rename()
        param['variables']['key'] = _storage['group_key']

        self.time_log_operate(body=param)

    def edit_report(self, repost_name, storage, token=None, **kwargs):
        """
        编辑各报表
        :param
            'repost_name'  # 对应修改的 报表名称
        """
        repost_key = [k['key'] for k in storage if k['name'] == repost_name][0]

        param = more.report_update(repost_key)[0]
        param.json['variables'] |= dict(**kwargs)
        q = self.call(api.ItemGraphql, param, token)

        key = q.json()['data']['updateTeamReport']['key']
        return repost_key, key

    @story('142467 部门工时日志报表：编辑分析维度（X轴）')
    def test_department_hour_log_edit_1(self, _storage):
        with step('分析维度（X轴）选择维度默认为：部门'):
            param = more.update_dimension('department')
            q_key, r_key = self.edit_report(repost_name='部门工时日志报表', storage=_storage['repost_info'],
                                            config=param)

            assert q_key == r_key

    @story('142465 部门工时日志报表：编辑分析维度（X轴）')
    def test_department_hour_log_edit_2(self, _storage):
        with step('分析维度（X轴）选择"所属迭代"'):
            param = more.update_dimension('sprint')
            q_key, r_key = self.edit_report(repost_name='部门工时日志报表', storage=_storage['repost_info'],
                                            config=param)

            assert q_key == r_key

    @story('142460 「部门工时日志报表」-编辑态-筛选：默认值')
    def test_department_hour_log_edit_default(self):
        """"""

    @story('142466 部门工时日志报表：编辑筛选')
    def test_department_hour_log_edit_3(self, _storage):
        with step('添加筛选条件为：所属迭代包含A、创建时间等于 今天'):
            param = more.update_filter(_storage['sprint_uuid'])
            q_key, r_key = self.edit_report(repost_name='部门工时日志报表', storage=_storage['repost_info'],
                                            config=param)

            assert q_key == r_key

    @story('T142472 部门工时日志报表：更改所属分组')
    def test_department_hour_log_edit_4(self, _storage):
        category = (_storage['default_key']).split('-')[1]
        repost_key = [k['key'] for k in _storage['repost_info'] if k['name'] == '部门工时日志报表'][0]

        with step('选择分组A'):
            param = more.change_group()[0]
            param.json['variables']['key'] = repost_key
            param.json['variables']['report_category'] = category
            q = self.call(api.ItemGraphql, param)

            q.check_response('data.updateTeamReport.key', repost_key)

    @story('142540 成员（登记人）-每天工时总览：编辑分析维度（X轴）')
    def test_register_every_day_1(self, _storage):
        with step('分析维度（X轴）选择"工作项负责人"'):
            param = more.register_every_1()
            q_key, r_key = self.edit_report(repost_name='成员 (登记人)-每天工时总览', config=param,
                                            storage=_storage['repost_info'])

            assert q_key == r_key

    @story('142541 成员（登记人）-每天工时总览：编辑分析维度（X轴）')
    def test_register_every_day_2(self, _storage):
        with step('分析维度（X轴）选择"周"；分析维度（Y轴）选择"状态"'):
            param = more.register_every_update('week', 'task_status')
            q_key, r_key = self.edit_report(repost_name='成员 (登记人)-每天工时总览', config=param,
                                            storage=_storage['repost_info'])

            assert q_key == r_key

    @story('142547 成员（登记人）-每天工时总览：编辑筛选')
    def test_register_every_day_3(self, _storage):
        with step('添加筛选条件为：所属迭代包含A、创建时间等于 今天'):
            param = more.register_every_3(_storage['sprint_uuid'])
            q_key, r_key = self.edit_report(repost_name='成员 (登记人)-每天工时总览', config=param,
                                            storage=_storage['repost_info'])

            assert q_key == r_key

    @story('142549 成员（登记人）-每天工时总览：分析维度（X轴）和（Y轴）默认值')
    def test_register_every_day_4(self, _storage):
        param = more.register_every_update('day', 'user')
        q_key, r_key = self.edit_report(repost_name='成员 (登记人)-每天工时总览', config=param,
                                        storage=_storage['repost_info'])

        assert q_key == r_key

    @story('142530 「成员（登记人）-每天工时总览」-编辑态-筛选：默认值')
    def test_register_every_day_6(self):
        """"""

    @story('142562 成员（登记人）-每天工时总览：更改所属分组')
    def test_register_every_day_5(self, _storage):
        category = (_storage['default_key']).split('-')[1]
        repost_key = [k['key'] for k in _storage['repost_info'] if k['name'] == '成员 (登记人)-每天工时总览'][0]

        with step('选择分组A'):
            param = more.change_group()[0]
            param.json['variables']['key'] = repost_key
            param.json['variables']['report_category'] = category
            q = self.call(api.ItemGraphql, param)

            q.check_response('data.updateTeamReport.key', repost_key)

    @story('142552 「成员（登记人）-每天工时总览」-编辑态：分析维度（Y轴）默认值')
    def test_register_every_day_7(self):
        """"""

    @story('122335 工时日志-分组：删除分组和报表')
    def test_group_report_delete(self):
        # 新建分组
        param = more.group_add()
        rp = self.time_log_operate(body=param)

        _key = rp['addReportCategory']['key']

        with step('点击删除分组和报表'):
            param = more.group_report_delete()
            param['variables']['key'] = _key

            self.time_log_operate(body=param)

    @story("T142452 「部门-项目工时总览」-更多：更改所属分组")
    def test_depart_proj_hour_overview_edit_group(self, _storage):
        with step("更改所属分组"):
            category = (_storage['group_key']).split('-')[1]
            repost_key = [k['key'] for k in _storage['repost_info'] if k['name'] == '部门-项目工时总览'][0]

            with step('选择分组A'):
                param = more.change_group()[0]
                param.json['variables']['key'] = repost_key
                param.json['variables']['report_category'] = category
                q = self.call(api.ItemGraphql, param)

                q.check_response('data.updateTeamReport.key', repost_key)

    @story('122332 工时日志-分组：删除分组')
    def test_group_delete(self, _storage):
        param = more.group_delete()
        param['variables']['key'] = _storage['group_key']

        self.time_log_operate(body=param)

    @story('142567 「成员（登记人）-每天工时总览」-更多：删除')
    def test_register_every_delete(self):
        """"""

    @story("T142443 「部门-项目工时总览」-编辑态：编辑分析指标（Y轴）")
    def test_depart_proj_hour_overview_edit_y(self, _storage):
        with step('分析维度（X轴）选择"周"；分析维度（Y轴）选择"状态"'):
            param = more.register_every_update('week', 'task_status')
            q_key, r_key = self.edit_report(repost_name='部门-项目工时总览', config=param,
                                            storage=_storage['repost_info'])

            assert q_key == r_key

    @story("T142442 「部门-项目工时总览」-编辑态：编辑分析维度（X轴）")
    def test_depart_proj_hour_overview_edit_x(self, _storage):
        with step('分析维度（X轴）选择"工作项负责人"'):
            param = more.register_every_1()
            q_key, r_key = self.edit_report(repost_name='部门-项目工时总览', config=param,
                                            storage=_storage['repost_info'])

            assert q_key == r_key

    @story("T142444 「部门-项目工时总览」-编辑态：编辑筛选")
    def test_depart_proj_hour_overview_edit_screen(self, _storage):
        with step('添加筛选条件为：所属迭代包含A、创建时间等于 今天'):
            param = more.register_every_3(_storage['sprint_uuid'])
            q_key, r_key = self.edit_report(repost_name='部门-项目工时总览', config=param,
                                            storage=_storage['repost_info'])

            assert q_key == r_key

    @story("T142466 「部门工时日志报表」-编辑态：编辑筛选")
    def test_depart_hour_log_edit_screen(self, _storage):
        with step('添加筛选条件为：所属迭代包含A、创建时间等于 今天'):
            param = more.register_every_3(_storage['sprint_uuid'])
            q_key, r_key = self.edit_report(repost_name='部门工时日志报表', config=param,
                                            storage=_storage['repost_info'])

            assert q_key == r_key


import numpy as np
import matplotlib.pyplot as plt
from pathlib import Path
from os import sep

home = str(Path.home())
cur_dir = str(Path.cwd())
layer_number = [2, 4, 8]
neuron_number = [20, 10, 5]
training_number = 100
value_number = 10000
val_range = [np.pi/2-.17, -(np.pi/2-.17)]

#### Print out Variables ####
x = np.load(''.join([cur_dir, sep, 'evaluation_xvals.npy']))
p = np.load(''.join([cur_dir, sep, 'evaluation_pvals.npy']))

approx = []
real = []

fig1 = plt.figure()
color = ['k','g','b']
for i in range(0, len(layer_number)):
    output_file = ''.join(['layer_num_', str(layer_number[i]), '-neuron_number_',
                     str(neuron_number[i]), '-training_number_', str(training_number)])
    data = np.load(''.join([cur_dir, sep, output_file, '.npz']))
    p = data.f.p
    predict_approx=data.f.approx
    batch = data.f.batch
    error = data.f.error
    y = data.f.y
    ypts_real = data.f.ypts_real
    hist = data.f.history

    #### Print Figures ####
    if i == 1:
        real.append(plt.scatter(p, 1/np.cos(p), color = 'r', s = 4))
    approx.append(plt.scatter(p, predict_approx, color = color[i], s = 4))
    plt.title('Approximation of Secant(x) Using a Neural Network')
    plt.xlabel('x (radians)')
    plt.ylabel('sec(x)')
plt.legend((real[0], approx[0], approx[1], approx[2]), ('Analytical Value', 'Approx 2:20', 'Approx 4:10', 'Approx 8:5'))
fig1.savefig(''.join([cur_dir, sep, 'comparison_', 'layer_num_', str(layer_number), '-neuron_number_',
                         str(neuron_number), '-training_number_', str(training_number), '_multiple.svg']))

loss = []
fig2 = plt.figure()
for i in range(0, 3):
    output_file = ''.join(['layer_num_', str(layer_number[i]), '-neuron_number_',
                     str(neuron_number[i]), '-training_number_', str(training_number)])
    data = np.load(''.join([cur_dir, sep, output_file, '.npz']))
    p = data.f.p
    predict_approx = data.f.approx
    batch = data.f.batch
    error = data.f.error
    y = data.f.y
    ypts_real = data.f.ypts_real
    hist = data.f.history
    loss.append(plt.plot(range(0, len(error)), error))

plt.axis((-2.5, 100, -.1, 3))
plt.title('Neural Network Loss Progression with Training\nApproximation of Secant(x)')
plt.xlabel('Number of Training Iterations')
plt.ylabel('Mean Squared Error')
plt.legend((loss[0][0], loss[1][0], loss[2][0]), ('Loss 2:20', 'Loss 4:10', 'Loss 8:5'))
fig2.savefig(''.join([cur_dir, sep, 'error_', 'layer_num_', str(layer_number), '-neuron_number_',
                             str(neuron_number), '-training_number_', str(training_number), '_multiple.svg']))


import socket
import time

server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_address = ('127.0.0.1', 12345)
server_socket.bind(server_address)
server_socket.listen(1)
while True:
    print("Server listening at {}:{}".format(server_address[0], server_address[1]))
    print("CONNECT ALREADY")
    client_socket, client_address = server_socket.accept()
    print("Connected with client {}".format(client_address))
    while True:
        received_data = client_socket.recv(1024)

        received_text = received_data.decode('utf-8')
        expected_size = client_socket.recv(1024).decode('utf-8')
        if received_text.lower() == "exit":
            print("Connection terminated by user.")
            break
        current_time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())
        print("Client says: {}".format(received_text))
        print("at time: {}".format(current_time))

        response = "Server received your message: '{}'".format(received_text)
        if int(len(received_text)) == int(expected_size):
            print("String length is consistent.")
        else:
            print("String length is INCONSISTENT: stated {}, received {}".format(expected_size, len(received_text)))
            response += ", but data was lost in transmission."
        client_socket.send(response.encode('utf-8'))

    client_socket.close()

server_socket.close()


from usr.snmp_utils import *
from usr.snmp_common import *

def decode(data: bytes, start_index: int = 0, enforce_type=None, strict=False):
    if start_index >= len(data):
        raise IndexError("Attempting to read from position {} on data with length {}".format(start_index, len(data)))

    start_index = start_index or 0
    type_ = TypeInfo.from_bytes(data[start_index])
    try:
        cls = X690Type.get(type_.cls, type_.tag, type_.nature)
    except Exception:
        cls = UnknownType

    data_slice, next_tlv = get_value_slice(data, start_index)
    output = cls.from_bytes(data, data_slice)
    if cls is UnknownType:
        output.tag = data[start_index]  # type: ignore

    if enforce_type and not isinstance(output, enforce_type):
        raise UnexpectedType(
            "Unexpected decode result. Expected instance of type {} but got {} instead".format(enforce_type,
                                                                                type(output)))

    if strict and next_tlv < len(data) - 1:
        remainder = data[next_tlv:]
        raise IncompleteDecoding("Strict decoding still had {} remaining bytes!".format(len(remainder)),
                                 remainder=remainder)

    return output, next_tlv

class _SENTINEL_UNINITIALISED:  # pylint: disable=invalid-name
    """
    Helper for specific sentinel values
    """

#: sentinel value for uninitialised objects (used for lazy decoding)
UNINITIALISED = _SENTINEL_UNINITIALISED()

class X690Type(object):
    __slots__ = ["pyvalue", "_raw_bytes"]
    TYPECLASS: TypeClass = TypeClass.UNIVERSAL
    NATURE = [TypeNature.CONSTRUCTED]
    INIT = False
    TAG: int = -1
    _raw_bytes: bytes
    registry_map: dict = dict()
    bounds = None

    def __init__(self, value=UNINITIALISED):
        self.pyvalue = value
        self._raw_bytes = b""

    @property
    def value(self):
        """
        Returns the value as a pure Python type
        """
        if not isinstance(self.pyvalue, _SENTINEL_UNINITIALISED):
            return self.pyvalue
        return self.decode_raw(self.raw_bytes, self.bounds)

    @property
    def raw_bytes(self) -> bytes:
        if self._raw_bytes != b"":
            return self._raw_bytes
        if self.pyvalue is UNINITIALISED:
            return b""
        self._raw_bytes = self.encode_raw()
        return self._raw_bytes

    @staticmethod
    def decode_raw(data, slc=None):
        return get_slice_data(data, slc)

    @staticmethod
    def get(typeclass, typeid, nature=TypeNature.CONSTRUCTED):
        cls = X690Type.registry_map[(typeclass, typeid, nature)]
        return cls

    @staticmethod
    def register(cls):
        for nature in cls.NATURE:
            X690Type.registry_map[(cls.TYPECLASS, cls.TAG, nature)] = cls

    @staticmethod
    def all():
        return list(X690Type.registry_map.values())

    @classmethod
    def validate(cls, data: bytes) -> None:
        """
        Given a bytes object, checks if the given class *cls* supports decoding
        this object. If not, raises a ValueError.
        """
        tinfo = TypeInfo.from_bytes(data[0])
        if tinfo.cls != cls.TYPECLASS or tinfo.tag != cls.TAG:
            raise ValueError(
                "Invalid type header! "
                "Expected a %s class with tag "
                "ID 0x%02x, but got a %s class with "
                "tag ID 0x%02x" % (cls.TYPECLASS, cls.TAG, tinfo.cls, data[0])
            )

    @classmethod
    def decode(
            cls, data: bytes
    ):  # pragma: no cover
        """
        This method takes a bytes object which contains the raw content octets
        of the object. That means, the octets *without* the type information
        and length.

        This function must be overridden by the concrete subclasses.
        """
        slc = get_value_slice(data).bounds
        output = cls.decode_raw(data, slc)
        return cls(output)

    @classmethod
    def from_bytes(
            cls, data, slc=None
    ):
        try:
            instance = cls()
        except TypeError as exc:
            raise X690Error(
                "Custom types must have a no-arg constructor allowing "
                "x690.types.UNINITIALISED as value. Custom type %r does not "
                "support this!" % cls
            ) from exc
        instance.raw_bytes = data
        instance.bounds = slc
        return instance

    @property
    def raw_bytes(self):
        if self._raw_bytes != b"":
            return self._raw_bytes
        if self.pyvalue is UNINITIALISED:
            return b""
        self._raw_bytes = self.encode_raw()
        return self._raw_bytes

    @raw_bytes.setter
    def raw_bytes(self, value: bytes) -> None:
        self._raw_bytes = value

    def to_bytes(self) -> bytes:  # pragma: no cover
        if self.bounds is not None:
            value = get_slice_data(self.raw_bytes, self.bounds)
        else:
            value = self.encode_raw()
        tinfo = TypeInfo(self.TYPECLASS, self.NATURE[0], self.TAG)
        return tinfo.to_bytes() + encode_length(len(value)) + value

    def __repr__(self) -> str:
        repr_value = repr(self.value)
        return "%s(value = %s)" % (self.__class__.__name__, repr_value)

    def encode_raw(self):
        if isinstance(self.pyvalue, _SENTINEL_UNINITIALISED):
            return b""
        return self.pyvalue

    def pythonize(self):
        return self.value

class UnknownType(X690Type):
    """
    A fallback type for anything not in X.690.

    Instances of this class contain the raw information as parsed from the
    bytes as the following attributes:

    * ``value``: The value without leading metadata (as bytes value)
    * ``tag``: The *unparsed* "tag". This is the type ID as defined in the
      reference document. See :py:class:`~puresnmp.x690.util.TypeInfo` for
      details.
    * ``typeinfo``: unused (derived from *tag* and only here for consistency
      with ``__repr__`` of this class).
    """

    TAG = 0x99

    def __init__(self, value: bytes = b"", tag: int = -1) -> None:
        super().__init__(value or UNINITIALISED)
        self.tag = tag

    def __repr__(self) -> str:
        typeinfo = TypeInfo.from_bytes(self.tag)
        tinfo = "{}/{}/{}".format(typeinfo.cls, typeinfo.nature, typeinfo.tag)
        return "<{} {} {} {}>".format(self.__class__.__name__, self.tag, self.value, tinfo)

    def __eq__(self, other: object) -> bool:
        return (
                isinstance(other, UnknownType)
                and self.value == other.value
                and self.tag == other.tag
        )

class Boolean(X690Type):
    TAG = 0x01
    NATURE = [TypeNature.PRIMITIVE]

    @staticmethod
    def decode_raw(data, slc=None) -> bool:
        return data[slc] != b"\x00"

    @classmethod
    def validate(cls, data) -> None:
        super().validate(data)
        if data[1] != 1:
            raise ValueError(
                "Unexpected Boolean value. Length should be 1,"
                " it was %d" % data[1]
            )

    def encode_raw(self) -> bytes:
        return b"\x01" if self.pyvalue else b"\x00"

    def __eq__(self, other):
        return isinstance(other, Boolean) and self.value == other.value

class Null(X690Type):
    TAG = 0x05
    NATURE = [TypeNature.PRIMITIVE]

    @classmethod
    def validate(cls, data: bytes) -> None:
        super().validate(data)
        if data[1] != 0:
            raise ValueError(
                "Unexpected NULL value. Length should be 0, it "
                "was %d" % data[1]
            )

    @staticmethod
    def decode_raw(data: bytes, slc: slice = None) -> None:
        return None

    def encode_raw(self) -> bytes:
        """
        Overrides :py:meth:`.X690Type.encode_raw`

        >>> Null().encode_raw()
        b'\\x00'
        """
        # pylint: disable=no-self-use
        return b"\x00"

    def to_bytes(self) -> bytes:
        return b"\x05\x00"

    def __eq__(self, other: object) -> bool:
        return isinstance(other, Null) and self.value == other.value

    def __repr__(self) -> str:
        return "Null(value = None)"

    def __bool__(self) -> bool:
        return False

    def __nonzero__(self) -> bool:  # pragma: no cover
        return False

class OctetString(X690Type):
    TAG = 0x04
    NATURE = [TypeNature.PRIMITIVE, TypeNature.CONSTRUCTED]

    def __init__(
            self, value=b""
    ) -> None:
        if isinstance(value, str):
            value = value.encode()
        if not value:
            value = UNINITIALISED
        super().__init__(value)

    def __eq__(self, other: object) -> bool:
        return isinstance(other, OctetString) and self.value == other.value

class Sequence(X690Type):
    """
    Represents an X.690 sequence type. Instances of this class are iterable and
    indexable.
    """

    TAG = 0x10

    @staticmethod
    def decode_raw(data: bytes, slc: slice = None):
        start_index = get_slice_start(slc, default=0)
        if not get_slice_data(data, slc) or start_index > len(data):
            return []
        item, next_pos = decode(data, start_index)
        items = [item]
        end = get_slice_end(slc, default=len(data))
        while next_pos < end:
            item, next_pos = decode(data, next_pos)
            items.append(item)
        return items

    def encode_raw(self) -> bytes:
        """
        Overrides :py:meth:`.X690Type.encode_raw`
        """
        if isinstance(self.pyvalue, _SENTINEL_UNINITIALISED):
            return b""
        items = []
        for item in self.pyvalue:
            items.append(item.to_bytes())
        output = b"".join(items)
        return output

    def __eq__(self, other: object) -> bool:
        if not isinstance(other, Sequence):
            return False
        return self.raw_bytes[self.bounds] == other.raw_bytes[other.bounds]

    def __repr__(self) -> str:
        item_repr = list(self)
        return "Sequence(value = %r)" % item_repr

    def __len__(self) -> int:
        return len(self.value)

    def __getitem__(self, idx: int):
        return self.value[idx]

    def pythonize(self):
        """
        Overrides :py:meth:`~.X690Type.pythonize`
        """
        return [obj.pythonize() for obj in self]

class Integer(X690Type):
    SIGNED = True
    TAG = 0x02
    NATURE = [TypeNature.PRIMITIVE]

    @classmethod
    def decode_raw(cls, data: bytes, slc=None) -> int:
        """
        Converts the raw byte-value (without type & length header) into a
        pure Python type

        Overrides :py:meth:`~.X690Type.decode_raw`
        """
        data = get_slice_data(data, slc)
        return int.from_bytes(bytes(data), "big", cls.SIGNED)

    def encode_raw(self) -> bytes:
        """
        Overrides :py:meth:`.X690Type.encode_raw`
        """
        if isinstance(self.pyvalue, _SENTINEL_UNINITIALISED):
            return b""
        octets = [self.pyvalue & 0b11111111]

        # Append remaining octets for long integers.
        remainder = self.pyvalue
        while remainder not in (0, -1):
            remainder = remainder >> 8
            octets.append(remainder & 0b11111111)

        if remainder == 0 and octets[-1] == 0b10000000:
            octets.append(0)
        octets.reverse()

        # remove leading octet if there is a string of 9 zeros or ones
        while len(octets) > 1 and (
                (octets[0] == 0 and octets[1] & 0b10000000 == 0)
                or (octets[0] == 0b11111111 and octets[1] & 0b10000000 != 0)
        ):
            del octets[0]
        return bytes(octets)

    def __eq__(self, other: object) -> bool:
        return isinstance(other, Integer) and self.value == other.value

class ObjectIdentifier(X690Type):
    TAG = 0x06
    NATURE = [TypeNature.PRIMITIVE]

    def __init__(self, value=UNINITIALISED):
        if (
                not isinstance(value, _SENTINEL_UNINITIALISED)
                and value
                and value.startswith(".")
        ):
            value = value[1:]
        super().__init__(value)

    @property
    def nodes(self):
        if not self.value:
            return tuple()
        return tuple(int(n) for n in self.value.split("."))

    @staticmethod
    def decode_large_value(current_char, stream) -> int:

        """
        If we encounter a value larger than 127, we have to consume from the
        stram until we encounter a value below 127 and recombine them.

        See: https://msdn.microsoft.com/en-us/library/bb540809(v=vs.85).aspx
        """
        buffer = []
        while current_char > 127:
            buffer.append(current_char ^ 0b10000000)
            current_char = next(stream)
        total = current_char
        for i, digit in enumerate(reversed(buffer)):
            total += digit * 128 ** (i + 1)
        return total

    @staticmethod
    def encode_large_value(value):
        """
        Inverse function of :py:meth:`~.ObjectIdentifier.decode_large_value`
        """
        if value <= 127:
            return [value]
        output = [value & 0b1111111]
        value = value >> 7
        while value:
            output.append(value & 0b1111111 | 0b10000000)
            value = value >> 7
        output.reverse()
        return output

    @staticmethod
    def decode_raw(data: bytes, slc: slice = None):
        """
        Converts the raw byte-value (without type & length header) into a
        pure Python type

        Overrides :py:meth:`~.X690Type.decode_raw`
        """
        # Special case for "empty" object identifiers which should be returned
        # as "0"
        data = get_slice_data(data, slc)
        if not data:
            return ""

        # unpack the first byte into first and second sub-identifiers.
        data0 = data[0]
        first, second = data0 // 40, data0 % 40
        output = [first, second]

        remaining = iter(data[1:])

        for node in remaining:
            # Each node can only contain values from 0-127. Other values need
            # to be combined.
            if node > 127:
                collapsed_value = ObjectIdentifier.decode_large_value(
                    node, remaining
                )
                output.append(collapsed_value)
                continue
            output.append(node)

        instance = ".".join([str(n) for n in output])
        return instance

    def collapse_identifiers(self):
        identifiers = self.nodes
        if len(identifiers) == 0:
            return tuple()

        if len(identifiers) > 1:
            first, second, rest = (
                identifiers[0],
                identifiers[1],
                identifiers[2:],
            )
            first_output = (40 * first) + second
        else:
            first_output = identifiers[0]
            rest = tuple()

        # Values above 127 need a special encoding. They get split up into
        # multiple positions.
        exploded_high_values = []
        for char in rest:
            if char > 127:
                exploded_high_values.extend(
                    ObjectIdentifier.encode_large_value(char)
                )
            else:
                exploded_high_values.append(char)

        collapsed_identifiers = [first_output]
        for subidentifier in rest:
            collapsed_identifiers.extend(
                ObjectIdentifier.encode_large_value(subidentifier)
            )
        return tuple(collapsed_identifiers)

    def encode_raw(self):
        """
        Overrides :py:meth:`.X690Type.encode_raw`
        """
        if isinstance(self.pyvalue, _SENTINEL_UNINITIALISED):
            return b""
        collapsed_identifiers = self.collapse_identifiers()
        if collapsed_identifiers == ():
            return b""
        try:
            output = bytes(collapsed_identifiers)
        except ValueError as exc:
            raise ValueError(
                "Unable to collapse %r. First two octets are too large!"
                % (self.nodes,)
            ) from exc
        return output

    def __int__(self):
        nodes = self.nodes
        if len(nodes) != 1:
            raise ValueError(
                "Only ObjectIdentifier with one node can be "
                "converted to int. %r is not convertable. It has %d nodes."
                % (self, len(self))
            )
        return nodes[0]

    def __str__(self):
        return "ObjectIdentifier(value = %s)" % (self.value)

    def __repr__(self):
        return "ObjectIdentifier(value = %s)" % (self.value)

    def __eq__(self, other) -> bool:
        return isinstance(other, ObjectIdentifier) and self.value == other.value

    def __len__(self) -> int:
        return len(self.nodes)

    def __contains__(self, other):
        a, b = other.nodes, self.nodes
        if len(a) == len(b):
            return a == b

        if len(b) > len(a):
            return False

        zipped = zip_longest(a, b, fillvalue=None)
        tail = []
        for tmp_a, tmp_b in zipped:
            if tmp_a == tmp_b and not tail:
                continue
            tail.append((tmp_a, tmp_b))

        _, unzipped_b = zip(*tail)
        if all([x is None for x in unzipped_b]):
            return True

        return False

    def __lt__(self, other) -> bool:
        return self.nodes < other.nodes

    def __hash__(self) -> int:
        return hash(self.value)

    def __add__(self, other):
        nodes = ".".join([self.value, other.value])
        return ObjectIdentifier(nodes)

    def __getitem__(self, index):
        if isinstance(index, int):
            return self.nodes[index]
        output = self.nodes[index]
        return ObjectIdentifier(".".join([str(n) for n in output]))

    def parentof(self, other):
        return other in self

    def childof(self, other):
        return self in other

class ObjectDescriptor(X690Type):
    TAG = 0x07
    NATURE = [TypeNature.PRIMITIVE, TypeNature.CONSTRUCTED]

class External(X690Type):
    TAG = 0x08

class Real(X690Type):
    TAG = 0x09
    NATURE = [TypeNature.PRIMITIVE]

class Enumerated(X690Type):
    TAG = 0x0A
    NATURE = [TypeNature.PRIMITIVE]

class EmbeddedPdv(X690Type):
    TAG = 0x0B

class Utf8String(X690Type):
    TAG = 0x0C
    NATURE = [TypeNature.PRIMITIVE, TypeNature.CONSTRUCTED]

class RelativeOid(X690Type):
    TAG = 0x0D
    NATURE = [TypeNature.PRIMITIVE]

class Set(X690Type):
    TAG = 0x11

class NumericString(X690Type):
    TAG = 0x12
    NATURE = [TypeNature.PRIMITIVE, TypeNature.CONSTRUCTED]

class PrintableString(X690Type):
    TAG = 0x13
    NATURE = [TypeNature.PRIMITIVE, TypeNature.CONSTRUCTED]

class T61String(X690Type):
    TAG = 0x14
    NATURE = [TypeNature.PRIMITIVE, TypeNature.CONSTRUCTED]
    __INITIALISED = False

    def __init__(self, value="") -> None:
        if isinstance(value, str):
            super().__init__(value or UNINITIALISED)
        else:
            super().__init__(T61String.decode_raw(value))

    def __eq__(self, other: object) -> bool:
        return isinstance(other, T61String) and self.value == other.value

    @staticmethod
    def decode_raw(data: bytes, slc=(None, None)):
        """
        Converts the raw byte-value (without type & length header) into a
        pure Python type

        Overrides :py:meth:`~.X690Type.decode_raw`
        """
        data = data[slc]
        if not T61String.__INITIALISED:
            # t61codec.register()
            T61String.__INITIALISED = True
        return data.decode("t61")

    def encode_raw(self) -> bytes:
        """
        Overrides :py:meth:`.X690Type.encode_raw`
        """
        if not T61String.__INITIALISED:  # pragma: no cover
            # t61codec.register()
            T61String.__INITIALISED = True
        if isinstance(self.pyvalue, _SENTINEL_UNINITIALISED):
            return b""
        return self.pyvalue.encode("t61")

class VideotexString(X690Type):
    TAG = 0x15
    NATURE = [TypeNature.PRIMITIVE, TypeNature.CONSTRUCTED]

class IA5String(X690Type):
    TAG = 0x16
    NATURE = [TypeNature.PRIMITIVE, TypeNature.CONSTRUCTED]

class UtcTime(X690Type):
    TAG = 0x17
    NATURE = [TypeNature.PRIMITIVE, TypeNature.CONSTRUCTED]

class GeneralizedTime(X690Type):
    TAG = 0x18
    NATURE = [TypeNature.PRIMITIVE, TypeNature.CONSTRUCTED]

class GraphicString(X690Type):
    TAG = 0x19
    NATURE = [TypeNature.PRIMITIVE, TypeNature.CONSTRUCTED]

    @staticmethod
    def decode_raw(data: bytes, slc: slice = None) -> str:
        data = data[slc]
        return data.decode("ascii")

class VisibleString(X690Type):
    TAG = 0x1A
    NATURE = [TypeNature.PRIMITIVE, TypeNature.CONSTRUCTED]

class GeneralString(X690Type):
    TAG = 0x1B
    NATURE = [TypeNature.PRIMITIVE, TypeNature.CONSTRUCTED]

class UniversalString(X690Type):
    TAG = 0x1C
    NATURE = [TypeNature.PRIMITIVE, TypeNature.CONSTRUCTED]

class CharacterString(X690Type):
    TAG = 0x1D

class BmpString(X690Type):
    TAG = 0x1E
    NATURE = [TypeNature.PRIMITIVE, TypeNature.CONSTRUCTED]

class EOC(X690Type):
    TAG = 0x00
    NATURE = [TypeNature.PRIMITIVE]

class BitString(X690Type):
    TAG = 0x03
    NATURE = [TypeNature.PRIMITIVE, TypeNature.CONSTRUCTED]

class Counter64(Integer):
    """
    As defined in RFC 2578
    """

    SIGNED = False
    TYPECLASS = TypeClass.APPLICATION
    TAG = 0x06

    def __init__(
            self, value=UNINITIALISED
    ) -> None:
        if not isinstance(value, _SENTINEL_UNINITIALISED):
            value &= 0xFFFFFFFFFFFFFFFF if value >= 2 ** 64 else value
            if value <= 0:
                value = 0
        super().__init__(value)

class Counter(Integer):
    SIGNED = False
    TYPECLASS = TypeClass.APPLICATION
    TAG = 0x01

    def __init__(
            self, value=UNINITIALISED
    ) -> None:
        if not isinstance(value, _SENTINEL_UNINITIALISED):
            value &= 0xFFFFFFFF if value >= 2 ** 32 else value
            if value <= 0:
                value = 0
        super().__init__(value)

class IpAddress(X690Type):
    NATURE = OctetString.NATURE
    TYPECLASS = TypeClass.APPLICATION
    TAG = 0x00

    def encode_raw(self) -> bytes:
        if b"." in self.value:
            self.pyvalue = bytes([int(x) for x in self.value.split(b".")])
        return self.value

    @staticmethod
    def decode_raw(data, slc=None):
        raw_value = get_slice_data(data, slc)
        pyvalue = b".".join([str(x).encode() for x in raw_value])
        return pyvalue  # type: ignore

    def __eq__(self, other: object) -> bool:
        # TODO: no longer necessary in x690 > 0.5.0a4
        return isinstance(other, IpAddress) and self.value == other.value

class Gauge(Integer):
    SIGNED = False
    TYPECLASS = TypeClass.APPLICATION
    TAG = 0x02

class TimeTicks(Integer):
    SIGNED = False
    TYPECLASS = TypeClass.APPLICATION
    TAG = 0x03

class Opaque(OctetString):
    TYPECLASS = TypeClass.APPLICATION
    TAG = 0x04

class NsapAddress(Integer):
    TYPECLASS = TypeClass.APPLICATION
    TAG = 0x05

class PDU(X690Type):
    """
    The superclass for SNMP Messages (GET, SET, GETNEXT, ...)
    """

    #: The typeclass identifire for type-detection in :py:mod:`x690`
    TYPECLASS = TypeClass.CONTEXT

    #: The tag for type-detection in :py:mod:`x690`
    TAG = 0

    @classmethod
    def decode_raw(cls, data: bytes, slc: slice = None):
        if not data:
            raise EmptyMessage("No data to decode!")
        request_id, nxt = decode(data, get_slice_start(slc, default=0), enforce_type=Integer)
        error_status, nxt = decode(data, nxt, enforce_type=Integer)
        error_index, nxt = decode(data, nxt, enforce_type=Integer)

        if error_status.value:
            error_detail, nxt = decode(data, nxt, enforce_type=Sequence)
            varbinds = [VarBind(oid, value) for oid, value in error_detail]  # type: ignore
            offending_oid = None
            if error_index.value != 0:
                offending_oid = varbinds[error_index.value - 1].oid
            exception = ErrorResponse.construct(
                error_status.value, offending_oid or ObjectIdentifier()
            )
            raise exception

        values, nxt = decode(data, nxt, enforce_type=Sequence)

        if not isinstance(values, Sequence):
            raise TypeError(
                "PDUs can only be decoded from sequences but got "
                "%r instead" % type(values)
            )

        varbinds = []
        for oid, value in values:  # type: ignore
            varbinds.append(VarBind(oid, value))

        return PDUContent(
            request_id.value, varbinds, error_status.value, error_index.value
        )

    def encode_raw(self) -> bytes:

        wrapped_varbinds = [
            Sequence([vb.oid, vb.value]) for vb in self.value.varbinds
        ]
        data = [
            Integer(self.value.request_id),
            Integer(self.value.error_status),
            Integer(self.value.error_index),
            Sequence(wrapped_varbinds),  # type: ignore
        ]
        payload_list = []
        for chunk in data:
            payload_list.append(chunk.to_bytes())
        payload = b"".join(payload_list)
        return payload

    def __repr__(self) -> str:
        try:
            return "%s(%r, %r)" % (
                self.__class__.__name__,
                self.value.request_id,
                self.value.varbinds,
            )
        except:  # pylint: disable=bare-except
            print(
                "ERROR Exception caught in __repr__ of %s", self.__class__.__name__
            )
            return "<{} (error-in repr)>".format(self.__class__.__name__)

    def __eq__(self, other):
        return type(other) == type(self) and self.value == other.value

class NoSuchObject(X690Type):
    TYPECLASS = TypeClass.CONTEXT
    NATURE = [TypeNature.PRIMITIVE]
    TAG = 0

    def __init__(
            self,
            value=UNINITIALISED,
    ) -> None:
        if value is UNINITIALISED:
            super().__init__(value=None)
        else:
            super().__init__(value=value)

class NoSuchInstance(X690Type):
    TYPECLASS = TypeClass.CONTEXT
    NATURE = [TypeNature.PRIMITIVE]
    TAG = 1

    def __init__(
            self,
            value=UNINITIALISED,
    ) -> None:
        if value is UNINITIALISED:
            super().__init__(value=None)
        else:
            super().__init__(value=value)

class EndOfMibView(X690Type):
    TYPECLASS = TypeClass.CONTEXT
    NATURE = [TypeNature.PRIMITIVE]
    TAG = 2

    def __init__(
            self,
            value=UNINITIALISED,
    ) -> None:
        if value is UNINITIALISED:
            super().__init__(value=None)
        else:
            super().__init__(value=value)

class GetRequest(PDU):
    TAG = 0

class GetResponse(PDU):
    TAG = 2

class GetNextRequest(GetRequest):
    TAG = 1

class SetRequest(PDU):
    TAG = 3

class BulkGetRequest(PDU):
    TYPECLASS = TypeClass.CONTEXT
    TAG = 5

    def __init__(self, request_id, non_repeaters, max_repeaters, *oids):
        if len(oids) > MAX_VARBINDS:
            raise TooManyVarbinds(len(oids))
        self.request_id = request_id
        self.non_repeaters = non_repeaters
        self.max_repeaters = max_repeaters
        self.varbinds = []
        for oid in oids:
            self.varbinds.append(VarBind(oid, Null()))
        super().__init__()

    def to_bytes(self) -> bytes:
        wrapped_varbinds = [
            Sequence([vb.oid, vb.value]) for vb in self.varbinds
        ]
        data = [
            Integer(self.request_id),
            Integer(self.non_repeaters),
            Integer(self.max_repeaters),
            Sequence(wrapped_varbinds),  # type: ignore
        ]
        payload = b"".join([chunk.to_bytes() for chunk in data])

        tinfo = TypeInfo(TypeClass.CONTEXT, TypeNature.CONSTRUCTED, self.TAG)
        length = encode_length(len(payload))
        return tinfo.to_bytes() + length + payload

    def __repr__(self) -> str:
        try:
            oids = [repr(oid) for oid, _ in self.varbinds]
            return "%s(%r, %r, %r, %s)" % (
                self.__class__.__name__,
                self.request_id,
                self.non_repeaters,
                self.max_repeaters,
                ", ".join(oids),
            )
        except:  # pylint: disable=bare-except
            print("ERROR Exception caught in __repr__ of %s" % (self.__class__.__name__))
            return "<{} (error-in repr)>".format(self.__class__.__name__)

    def __eq__(self, other):
        return (
                type(other) == type(self)
                and self.request_id == other.request_id
                and self.non_repeaters == other.non_repeaters
                and self.max_repeaters == other.max_repeaters
                and self.varbinds == other.varbinds
        )

class InformRequest(PDU):
    TAG = 6

class Trap(PDU):
    TAG = 7

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.source = None

class Report(PDU):
    TAG = 8


# coding: utf-8

import re
from six import iteritems
from gensim import corpora, models

def get_dict(filepath, dictpath):
    f = open(filepath, "r", encoding="utf-8")
    dictionary = corpora.Dictionary(line.strip().split() for line in f)
    f.close()

    stop_words = [word.strip() for word in open("stop_words/stop_words.txt", "r", encoding="utf-8")]
    stop_ids = [dictionary.token2id[stopword] for stopword in stop_words if stopword in dictionary.token2id]
    non_zh_ids = [dictionary.token2id[word] for word,_ in dictionary.token2id.items() if re.match(r"[^\u4E00-\u9FA5]+", word)]
    once_ids = [tokenid for tokenid, docfreq in iteritems(dictionary.dfs) if docfreq == 1]
    dictionary.filter_tokens(stop_ids + once_ids + non_zh_ids)
    dictionary.compactify()
    print(dictionary)
    dictionary.save(dictpath)
    print("Save dictionary to %s for later use" % dictpath)

def _iter_(filepath, dictpath):
    dictionary = corpora.Dictionary.load(dictpath)
    f = open(filepath, "r", encoding="utf-8")
    for line in f:
        line = line.strip().split()
        yield dictionary.doc2bow(line)

def get_corpus(filepath, dictpath, corpuspath):
    corpus_iter = _iter_(filepath, dictpath)
    corpus_tf = [vector for vector in corpus_iter]
    print("Corpus example:%s" % corpus_tf[:5])
    corpora.MmCorpus.serialize(corpuspath, corpus_tf)
    print("Save corpus to %s for later use" % corpuspath)

def get_tfidf(dictpath, corpuspath, tfidfpath):
    dictionary = corpora.Dictionary.load(dictpath)
    print(dictionary)
    corpus_tf = corpora.MmCorpus(corpuspath)
    print(corpus_tf)
    tfidf_model = models.TfidfModel(corpus_tf)
    corpus_tfidf = tfidf_model[corpus_tf]
    corpora.MmCorpus.serialize(tfidfpath, corpus_tfidf)
    print("Save tfidf to %s for later use" % tfidfpath)

def get_lsi(dictpath, tfidfpath, lsipath, num_topics):
    dictionary = corpora.Dictionary.load(dictpath)
    print(dictionary)
    corpus_tfidf = corpora.MmCorpus(tfidfpath)
    print(corpus_tfidf)
    lsi = models.lsimodel.LsiModel(corpus=corpus_tfidf, id2word=dictionary, num_topics=num_topics)
    lsi.save(lsipath)
    print("Save lsi model to %s" % lsipath)

def get_lda(dictpath, tfidfpath, ldapath, num_topics):
    dictionary = corpora.Dictionary.load(dictpath)
    print(dictionary)
    corpus_tfidf = corpora.MmCorpus(tfidfpath)
    print(corpus_tfidf)
    lda = models.ldamodel.LdaModel(corpus=corpus_tfidf, id2word=dictionary, num_topics=num_topics, update_every=1, chunksize=10000, passes=1)
    lda.save(ldapath)
    print("Save lda model to %s" % ldapath)

def apply_labels(tfidfpath, ldapath, labelspath):
    corpus_tfidf = corpora.MmCorpus(tfidfpath)
    lda = models.LdaModel.load(ldapath)
    f = open(labelspath, "w", encoding="utf-8")
    for tfidf in corpus_tfidf:
        if tfidf:
            label,_ = sorted(lda[tfidf], key=lambda tup:tup[1], reverse=True)[0]
            f.write(str(label) + "\n")
        else:
            f.write("未分类" + "\n")
    f.close()
    print("Save label of documents to %s for classification" % labelspath)


import os
import cv2
import numpy as np
import matplotlib.pyplot as plt

import random as rng

def pltShowCV(img, title="img"):
    if len(img.shape) == 2:
        img = cv2.cvtColor(img, cv2.COLOR_GRAY2RGB)
        print('Image is single-channel (grayscale)')
    elif len(img.shape) == 3:
        print('Image is three-channel (RGB)')
        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    plt.imshow(img)
    plt.title(title)
    plt.show()

def pltShowCVDot(img, point, title="img"):
    global cnt
    if len(img.shape) == 2:
        img = cv2.cvtColor(img, cv2.COLOR_GRAY2RGB)
        print('Image is single-channel (grayscale)')
    elif len(img.shape) == 3:
        print('Image is three-channel (RGB)')
        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    cv2.circle(img, point, 20, (255, 0, 0), -1)
    plt.imshow(img)
    plt.title(title + str(cnt))
    plt.show()
    cnt += 1

def draw_contours(img_gray, contours, hierarchy):
    drawing = np.zeros((img_gray.shape[0], img_gray.shape[1], 3), dtype=np.uint8)
    for i in range(len(contours)):
        color = (rng.randint(0,256), rng.randint(0,256), rng.randint(0,256))
        cv2.drawContours(drawing, contours, i, color, 2, cv2.LINE_8, hierarchy, 0)
    return drawing

class _TKDWater_Defect:
    def __init__(self):
        self.rtRect = None
        self.iArea = 0

class CAlgo_KDWater:
    def __init__(self):
        self.m_imgTempl = None
        self.m_ptStdOffs = None
        self.DEF_THRESD_AREA = 0
        self.DEF_THRESD_NOR = 50
        self.DEF_THRESD_DIFF = 60

    def LoadTemplate(self):
        self.m_imgTempl = cv2.imread("Template\\nm_block.bmp", cv2.IMREAD_GRAYSCALE)
        self.m_ptStdOffs = (213, 213)
        return True

    def FindDefect(self, vecDefect, srcImgGray):
        vecDefect.clear()

        ptCent = [0, 0]
        if self._GetBestMatchPos(ptCent, srcImgGray):
            self._SearchDefect(vecDefect, ptCent, srcImgGray)

    def _SearchDefect(self, vecDefect, cent, srcImgGray):
        global filename
        vecBoxCent = [cent]
        iIndex_R = 0

        ret = True
        while iIndex_R < len(vecBoxCent):
            curCent = vecBoxCent[iIndex_R]
            iIndex_R += 1
            pltShowCVDot(srcImgGray, curCent, "curCent")
            self._SearchDefect_Box(vecDefect, vecBoxCent, curCent, srcImgGray)
            if len(vecDefect) > 0:
                # ret = False
                # break
                pass

        imgColor = cv2.cvtColor(srcImgGray, cv2.COLOR_GRAY2BGR)

        for idx in range(len(vecDefect)):
            boxRT = vecDefect[idx].rtRect
            boxRT[0] -= 5
            boxRT[1] -= 5
            boxRT[2] += 10
            boxRT[3] += 10
            if boxRT[0] < 0:
                boxRT[0] = 0
            if boxRT[1] < 0:
                boxRT[1] = 0
            if boxRT[0] + boxRT[2] > imgColor.shape[1]:
                boxRT[2] = imgColor.shape[1] - boxRT[0]
            if boxRT[1] + boxRT[3] > imgColor.shape[0]:
                boxRT[3] = imgColor.shape[0] - boxRT[1]

            cv2.rectangle(imgColor, boxRT, (0, 0, 255), 2)
            # buf = f"{vecDefect[idx].iArea}"
            # cv2.putText(imgColor, buf, vecDefect[idx].rtRect.tl(), cv2.FONT_HERSHEY_SIMPLEX, 2, (0, 0, 255), 2)

        imgOut = imgColor.copy()

        iHalfW = self.m_imgTempl.shape[1] >> 1
        iHalfH = self.m_imgTempl.shape[0] >> 1
        for idx in range(len(vecBoxCent)):
            rect = (vecBoxCent[idx][0] - iHalfW, vecBoxCent[idx][1] - iHalfH, self.m_imgTempl.shape[1],
                    self.m_imgTempl.shape[0])
            cv2.rectangle(imgOut, rect, (0, 255, 0), 2)

        buf = [0] * 128
        cnt = 0
        if len(vecDefect) > 0:
            cnt += 1
            buf = f"d:\\1\\{filename}_[{len(vecDefect)}]_NG.bmp"
            cv2.imwrite(buf, imgColor)
        else:
            cnt += 1
            buf = f"d:\\1\\{filename}_OK.bmp"
            cv2.imwrite(buf, imgColor)

        # imgC2 = cv2.pyrDown(imgColor)
        # cv2.imshow("1", imgC2)
        # cv2.waitKey(0)

        if len(vecDefect) > 0:
            ret = False

        return ret

    def _addBoxPos(self, vecBoxCent, cent):
        total = len(vecBoxCent)
        ret = True
        for idx in range(total):
            dx = abs(vecBoxCent[idx][0] - cent[0])
            dy = abs(vecBoxCent[idx][1] - cent[1])

            if dx < 100 and dy < 100:
                ret = False
                break

        if ret:
            vecBoxCent.append(cent)

    #
    def _SearchDefect_Box(self, vecDefect, vecBoxCent, cent, srcImgGray):
        curRect = (
            cent[0] - (self.m_imgTempl.shape[1] >> 1), cent[1] - (self.m_imgTempl.shape[0] >> 1),
            self.m_imgTempl.shape[1],
            self.m_imgTempl.shape[0])
        imgCur = srcImgGray[curRect[1]:curRect[1] + curRect[3], curRect[0]:curRect[0] + curRect[2]]

        bNeib = [False] * 4
        imgNeib = [np.zeros((251, 247), dtype=np.uint8) for i in range(4)]
        ptNeib = [[0, 0] for i in range(4)]

        funcList = [self._GetImage_ByBox_Left, self._GetImage_ByBox_Right, self._GetImage_ByBox_Up, self._GetImage_ByBox_Down]
        for idx in range(4):
            ret, imgNeib[idx] = funcList[idx](imgNeib[idx], ptNeib[idx], srcImgGray, cent, imgCur)
            if ret:
                bNeib[idx] = True
                self._addBoxPos(vecBoxCent, ptNeib[idx])
            else:
                imgNeib[idx] = imgCur.copy()

        DEF_THRESD_AREA = self.DEF_THRESD_AREA
        DEF_THRESD_NOR = self.DEF_THRESD_NOR        # 50
        DEF_THRESD_DIFF = self.DEF_THRESD_DIFF      # 60

        diff = [np.zeros((1, 1), dtype=np.uint8)] * 4
        for idx in range(4):
            diff[idx] = cv2.absdiff(imgNeib[idx], imgCur)
            _, diff[idx] = cv2.threshold(diff[idx], DEF_THRESD_DIFF, 1, cv2.THRESH_BINARY)

        diff[0] += diff[1] + diff[2] + diff[3]

        imgBin = cv2.threshold(diff[0], 1, 255, cv2.THRESH_BINARY)[1]

        imgBaseBin = cv2.threshold(imgCur, DEF_THRESD_NOR, 255, cv2.THRESH_BINARY_INV)[1]
        imgBin &= imgBaseBin

        kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (7, 7))
        imgBin = cv2.erode(imgBin, kernel)
        imgBin = cv2.dilate(imgBin, kernel)

        kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (7, 7))
        imgBin = cv2.dilate(imgBin, kernel)
        imgBin = cv2.dilate(imgBin, kernel)
        imgBin = cv2.erode(imgBin, kernel)
        imgBin = cv2.erode(imgBin, kernel)
        pltShowCV(imgBin, "imgBin")
        contours, hierarchy = cv2.findContours(imgBin, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
        drawing = draw_contours(imgBin, contours, hierarchy)
        pltShowCV(drawing, "drawing")
        #vecDefect = []
        for cnt in contours:
            area = cv2.contourArea(cnt)
            if area > DEF_THRESD_AREA:
                defect = _TKDWater_Defect()
                defect.iArea = area
                defect.rtRect = list(cv2.boundingRect(cnt))
                defect.rtRect[0] += curRect[0]
                defect.rtRect[1] += curRect[1]
                vecDefect.append(defect)

    def _GetImage_ByBox_Left(self, outImg, outCent, srcImg, cent, curImgTempl):
        iHalfWid = (self.m_imgTempl.shape[1] >> 1) + 30
        iHalfHei = (self.m_imgTempl.shape[0] >> 1) + 30

        roiRect = (cent[0] - iHalfWid - self.m_ptStdOffs[0], cent[1] - iHalfHei, iHalfWid << 1, iHalfHei << 1)
        if roiRect[0] < 0 or roiRect[1] < 0 or roiRect[0] + roiRect[2] > srcImg.shape[1] or roiRect[1] + roiRect[3] > \
                srcImg.shape[0]:
            return False, None

        roiImg = srcImg[roiRect[1]:roiRect[1] + roiRect[3], roiRect[0]:roiRect[0] + roiRect[2]]
        ret, outImg = self._GetMaxMatch(outImg, outCent, roiImg, curImgTempl)
        if ret:
            outCent[0] += roiRect[0]
            outCent[1] += roiRect[1]

        return ret, outImg

    def _GetImage_ByBox_Right(self, outImg, outCent, srcImg, cent, curImgTempl):
        iHalfWid = (self.m_imgTempl.shape[1] >> 1) + 30
        iHalfHei = (self.m_imgTempl.shape[0] >> 1) + 30

        roiRect = (cent[0] - iHalfWid + self.m_ptStdOffs[0], cent[1] - iHalfHei, iHalfWid << 1, iHalfHei << 1)
        if (roiRect[0] < 0) or (roiRect[1] < 0) or (roiRect[0] + roiRect[2] > srcImg.shape[1]) or (
                roiRect[1] + roiRect[3] > srcImg.shape[0]):
            return False, None

        roiImg = srcImg[roiRect[1]:roiRect[1] + roiRect[3], roiRect[0]:roiRect[0] + roiRect[2]]
        ret, outImg = self._GetMaxMatch(outImg, outCent, roiImg, curImgTempl)
        if ret:
            outCent[0] += roiRect[0]
            outCent[1] += roiRect[1]

        return ret, outImg

    def _GetImage_ByBox_Up(self, outImg, outCent, srcImg, cent, curImgTempl):
        iHalfWid = (self.m_imgTempl.shape[1] >> 1) + 30
        iHalfHei = (self.m_imgTempl.shape[0] >> 1) + 30

        roiRect = (cent[0] - iHalfWid, cent[1] - iHalfHei - self.m_ptStdOffs[1], iHalfWid << 1, iHalfHei << 1)
        if (roiRect[0] < 0) or (roiRect[1] < 0) or (roiRect[0] + roiRect[2] > srcImg.shape[1]) or (
                roiRect[1] + roiRect[3] > srcImg.shape[0]):
            return False, None

        roiImg = srcImg[roiRect[1]:roiRect[1] + roiRect[3], roiRect[0]:roiRect[0] + roiRect[2]]
        ret, outImg = self._GetMaxMatch(outImg, outCent, roiImg, curImgTempl)
        if ret:
            outCent[0] += roiRect[0]
            outCent[1] += roiRect[1]

        return ret, outImg

    def _GetImage_ByBox_Down(self, outImg, outCent, srcImg, cent, curImgTempl):
        iHalfWid = (self.m_imgTempl.shape[1] >> 1) + 30
        iHalfHei = (self.m_imgTempl.shape[0] >> 1) + 30

        roiRect = (cent[0] - iHalfWid, cent[1] - iHalfHei + self.m_ptStdOffs[1], iHalfWid << 1, iHalfHei << 1)
        if roiRect[0] < 0 or roiRect[1] < 0 or roiRect[0] + roiRect[2] > srcImg.shape[1] or roiRect[1] + roiRect[3] > \
                srcImg.shape[0]:
            return False, None

        roiImg = srcImg[roiRect[1]:roiRect[1] + roiRect[3], roiRect[0]:roiRect[0] + roiRect[2]]
        ret, outImg = self._GetMaxMatch(outImg, outCent, roiImg, curImgTempl)
        if ret:
            outCent[0] += roiRect[0]
            outCent[1] += roiRect[1]

        return ret, outImg

    def _GetMaxMatch(self, outImg, outCent, roiImg, imgTempl):
        result = cv2.matchTemplate(roiImg, imgTempl, cv2.TM_CCOEFF_NORMED)
        result = np.clip(result, 0, np.inf)
        result = result * 255
        #result = cv2.normalize(result, None, 0, 255, cv2.NORM_MINMAX, cv2.CV_8U)

        dMax = 0
        _, dMax, _, maxLoc = cv2.minMaxLoc(result)
        iVal = dMax
        if iVal < 100:
            return False, None
        iSumX = 0
        iSumY = 0
        cnt = 0
        for row in range(result.shape[0]):
            pLine = result[row, :]
            for col in range(result.shape[1]):
                if pLine[col] >= iVal:
                    iSumX += col
                    iSumY += row
                    cnt += 1

        if cnt <= 0:
            return False

        outCent[0] = iSumX // cnt
        outCent[1] = iSumY // cnt

        roiRect = (outCent[0], outCent[1], imgTempl.shape[1], imgTempl.shape[0])    # row:行数 高度 251  cols: 宽度 247
        outImg = roiImg[roiRect[1]:roiRect[1] + roiRect[3], roiRect[0]:roiRect[0] + roiRect[2]]

        outCent[0] += imgTempl.shape[1] // 2
        outCent[1] += imgTempl.shape[0] // 2

        return True, outImg

    def _GetMaxMatch_jianhua(self, outImg, outCent, roiImg, imgTempl):
        result = cv2.matchTemplate(roiImg, imgTempl, cv2.TM_CCOEFF_NORMED)
        result = cv2.normalize(result, None, 0, 255, cv2.NORM_MINMAX, cv2.CV_8U)

        dMax = 0
        _, dMax, _, maxLoc = cv2.minMaxLoc(result)
        if dMax < 100:
            return False

        outCent[0] = maxLoc[0] + imgTempl.shape[1] // 2
        outCent[1] = maxLoc[1] + imgTempl.shape[0] // 2

        roiRect = (maxLoc[0], maxLoc[1], imgTempl.shape[1], imgTempl.shape[0])
        outImg = roiImg[roiRect[1]:roiRect[1] + roiRect[3], roiRect[0]:roiRect[0] + roiRect[2]]

        return True

    def _GetBestMatchPos(self, ptCent, srcImgGray):
        result = cv2.matchTemplate(srcImgGray, self.m_imgTempl, cv2.TM_CCOEFF_NORMED)
        # result = result * 255
        # result = np.uint8(result)
        result = cv2.normalize(result, None, 0, 255, cv2.NORM_MINMAX, cv2.CV_8U)

        dMax = 0
        _, dMax, _, _ = cv2.minMaxLoc(result)

        dMax -= 1.0
        if dMax < 100:
            dMax = 100

        _, imgBin = cv2.threshold(result, dMax, 255, cv2.THRESH_BINARY)

        vecCont, _ = cv2.findContours(imgBin, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
        vecRect = []
        iMaxV = 0
        iMaxIdx = -1
        for idx in range(len(vecCont)):
            area = len(vecCont[idx])
            if area > iMaxV:
                iMaxV = area
                iMaxIdx = idx

        ret = False

        if iMaxIdx >= 0:
            rect = cv2.boundingRect(vecCont[iMaxIdx])

            ptCent[0] = rect[0] + (rect[2] >> 1) + (self.m_imgTempl.shape[1] >> 1)
            ptCent[1] = rect[1] + (rect[3] >> 1) + (self.m_imgTempl.shape[0] >> 1)

            ret = True

        return ret

        # DEF_THRESD_AREA = self.DEF_THRESD_AREA
        # DEF_THRESD_NOR = self.DEF_THRESD_NOR        # 50
        # DEF_THRESD_DIFF = self.DEF_THRESD_DIFF      # 60
    def setDEF_THRESD_AREA(self, DEF_THRESD_AREA):
        self.DEF_THRESD_AREA = DEF_THRESD_AREA

    def setDEF_THRESD_NOR(self, DEF_THRESD_NOR):
        self.DEF_THRESD_NOR = DEF_THRESD_NOR

    def setDEF_THRESD_DIFF(self, DEF_THRESD_DIFF):
        self.DEF_THRESD_DIFF = DEF_THRESD_DIFF

def test_water():
    global filename
    water = CAlgo_KDWater()
    water.LoadTemplate()

    vecFiles = []
    _scan_files("D:\\LGCBTray\\Test_Image\\NM", vecFiles)

    vecDefect = []
    for idx in range(len(vecFiles)):
        img = cv2.imread(vecFiles[idx], cv2.IMREAD_GRAYSCALE)
        pltShowCV(img, "OriImg")
        file_name = os.path.basename(vecFiles[idx])
        filename = os.path.splitext(file_name)[0]
        water.FindDefect(vecDefect, img)

def _scan_files(directory, vecFiles):
    for file in os.listdir(directory):
        if file.endswith(".jpg") or file.endswith(".png") or file.endswith(".bmp"):
            vecFiles.append(os.path.join(directory, file))

filename = ""
cnt = 1
if __name__ == '__main__':
    test_water()

"""
    cv2.imwrite("test.jpg", result)
"""


"""initial migration

Revision ID: f52c4f9eb3d5
Revises: c83b808fab81
Create Date: 2017-05-22 13:55:52.981000

"""
from alembic import op
import sqlalchemy as sa

# revision identifiers, used by Alembic.
revision = 'f52c4f9eb3d5'
down_revision = 'c83b808fab81'
branch_labels = None
depends_on = None

def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.add_column('users', sa.Column('create_time', sa.DateTime(), nullable=True))
    op.add_column('users', sa.Column('group_id', sa.Integer(), nullable=True))
    op.add_column('users', sa.Column('update_time', sa.DateTime(), nullable=True))
    op.create_foreign_key(None, 'users', 'users_group', ['group_id'], ['id'])
    # ### end Alembic commands ###

def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.drop_constraint(None, 'users', type_='foreignkey')
    op.drop_column('users', 'update_time')
    op.drop_column('users', 'group_id')
    op.drop_column('users', 'create_time')
    # ### end Alembic commands ###


"""
Title         :  Keywords Generator
About         :  Simple program to find how much times a word repeat a webpage.
Author        :  Satheesh Kumar D
Date          :  07-05-2017
Organisation  :  LICO TECH
"""

import requests
from bs4 import BeautifulSoup
import operator

def start(url):
    word_list = []
    error = 0
    src = requests.get(url).text
    soup = BeautifulSoup(src)
    for para in soup.findAll('p'):
        content = para.string
        try:
            words = content.lower().split()
        except AttributeError:
            error += 1
        for word in words:
            word_list.append(word)
    clean_list(word_list)

def clean_list(word_list):
    cleaned = []
    for word in word_list:
        symbols = "!@#$%^&*()_-+=~`{[}]|\\:;'\"\<\,\.\>\/\?"
        for i in range(0, len(symbols)):
            word = word.replace(symbols[i], "")
        if len(word) > 0:
            cleaned.append(word)
    frequency(cleaned)

def frequency(uncleanlist):
    words_list = {}
    for word in uncleanlist:
        if word in words_list:
            words_list[word] += 1
        else:
            words_list[word] = 1
    for key, value in sorted(words_list.items(), key=operator.itemgetter(1)):
        print(key, value)

start("http://localhost/Aplus_Inc/index.html")


from rest_framework.exceptions import NotAcceptable

class NumberTranslationService:

    MAX_LIMIT_ERROR = 'Número fora do limite válido'
    ZERO = 'zero'
    CEM = 'cem'

    UNITS = {
        '1': 'um',
        '2': 'dois',
        '3': 'três',
        '4': 'quatro',
        '5': 'cinco',
        '6': 'seis',
        '7': 'sete',
        '8': 'oito',
        '9': 'nove'
    }

    TEN_TO_NINETEEN = {
        '10': 'dez',
        '11': 'onze',
        '12': 'doze',
        '13': 'treze',
        '14': 'quatorze',
        '15': 'quinze',
        '16': 'dezesseis',
        '17': 'dezessete',
        '18': 'dezoito',
        '19': 'dezenove'
    }

    DOZENS = {
        '2': 'vinte',
        '3': 'trinta',
        '4': 'quarenta',
        '5': 'cinquenta',
        '6': 'sessenta',
        '7': 'setenta',
        '8': 'oitenta',
        '9': 'noventa'
    }

    HUNDREDS = {
        '2': 'duzentos',
        '3': 'trezentos',
        '4': 'quatrocentos',
        '5': 'quinhentos',
        '6': 'seiscentos',
        '7': 'setecentos',
        '8': 'oitocentos',
        '9': 'novecentos'
    }

    THOUSANDS = {
        '1': 'mil',
        '2': 'dois mil',
        '3': 'três mil',
        '4': 'quatro mil',
        '5': 'cinco mil',
        '6': 'seis mil',
        '7': 'sete mil',
        '8': 'oito mil',
        '9': 'nove mil'
    }

    def get_number_in_portuguese(self, number, result=""):
        """
        Given a number, returns it extension name in portuguese

        :param number: a valid number between -99999 and 99999
        :param result: the final result as string
        :return: result
        """
        number_as_str = str(number)

        # Check if the first char is a "-" sign
        first_position = number_as_str[0]
        if "-" == first_position:
            result = "menos"
            # Removes the negative sign from number
            return self.get_number_in_portuguese(number=number_as_str[1::], result=result)

        number_len = len(number_as_str)

        if number_len > 1 and self._is_zero_sequence(number_as_str):
            # the rest of the number ends in a zero sequence
            return result.strip()

        if first_position == '0':
            if number_len > 1:
                # Cut off the leading zero
                return self.get_number_in_portuguese(number=number_as_str[1::], result=result)
            if not result or result == '-':
                # The number is zero
                return self.ZERO

        if number_len > 5:
            # Out of range
            raise NotAcceptable(detail=self.MAX_LIMIT_ERROR)

        if number_len == 5:
            # Extract the dozen-thounsands
            first_two_positions = number_as_str[0] + number_as_str[1]
            result = ' '.join([result, self._get_two_digits_number_in_extension(first_two_positions), 'mil'])

            if self._is_zero_sequence(number_as_str[2::]):
                # Number ends in a zero sequence
                return result.strip()
            result = ' '.join([result, 'e'])

            return self.get_number_in_portuguese(number=number_as_str[2::], result=result)

        if number_len == 4:
            result = ' '.join([result, self.THOUSANDS[first_position]])

            if self._is_zero_sequence(number_as_str[1::]):
                # Number ends in a zero sequence
                return result.strip()
            result = ' '.join([result, 'e'])

            return self.get_number_in_portuguese(number=number_as_str[1::], result=result)

        if number_len == 3:
            is_following_zeros = self._is_zero_sequence(number_as_str[1::])

            if first_position == '1':
                # Number ends in 1xx
                if is_following_zeros:
                    # Number is 100
                    result = ' '.join([result, self.CEM])
                    return result.strip()
                result = ' '.join([result, 'cento e'])
                return self.get_number_in_portuguese(number=number_as_str[1::], result=result)
            result = ' '.join([result, self.HUNDREDS[first_position]])
            if is_following_zeros:
                # Number ends in a zero sequence
                return result.strip()
            result = ' '.join([result, 'e'])
            return self.get_number_in_portuguese(number=number_as_str[1::], result=result)

        if number_len == 2:
            result = ' '.join([result, self._get_two_digits_number_in_extension(number_as_str)])
            return result.strip()

        if number_len == 1:
            result = ' '.join([result, self.UNITS[number_as_str]])

        return result.strip()

    def _get_two_digits_number_in_extension(self, numeric_string):
        first_position = numeric_string[0]

        if first_position == '1':
            # Number is 10-19
            return self.TEN_TO_NINETEEN[numeric_string]

        # Number is 20-99
        result = self.DOZENS[first_position]
        second_position = numeric_string[1]
        if second_position == '0':
            # Number has two digitis, ending in zero
            return result
        # Number has two digits, ending in a number 1-9
        return ' e '.join([result, self.UNITS[second_position]])

    def _is_zero_sequence(self, numeric_string):
        """ Returns true if numeric_string is composed by zeros """
        for number in numeric_string:
            if number != '0':
                return False
        return True


from collections import defaultdict
from functools import partial
from itertools import permutations

from nltk.stem import PorterStemmer

def get_final_feature_descriptors(nltk_features, dep_features):
    stemmer = PorterStemmer()
    nltk_features_stemmed = [feat.split(' ') for feat in nltk_features]
    nltk_features_stemmed = map(partial(map, stemmer.stem), nltk_features_stemmed)
    for dep_feat in dep_features:
        dep_feat['token_stemmed'] = stemmer.stem(str(dep_feat['token']))
        dep_feat['compounds_stemmed'] = map(str, dep_feat['compounds'])
        dep_feat['compounds_stemmed'] = map(stemmer.stem, dep_feat['compounds_stemmed'])

    filtered = defaultdict(list)
    for nltk_feat, nltk_feat_stemmed in zip(nltk_features, nltk_features_stemmed):
        for dep_feat in dep_features:
            if nltk_feat_equals_dep_feat(nltk_feat_stemmed, dep_feat):
                filtered[nltk_feat] += dep_feat['descriptors']
    return filtered

def nltk_feat_equals_dep_feat(nltk_feat_stemmed, dep_feat):
    num_compounds = len(nltk_feat_stemmed) - 1
    for compounds_stemmed in permutations(dep_feat['compounds_stemmed'], num_compounds):
        compound_dep_feat = list(compounds_stemmed) + [dep_feat['token_stemmed']]
        if compound_dep_feat == nltk_feat_stemmed:
            return True
    return False

def dependency_features(doc):
    '''
    output ::= list<occurance>
    occurance ::= {'token': token, 'compunds': list<token>, 'descriptors': list<descriptor>}
    descriptor ::= {'token': token, 'negs': list<token>, 'advs': list<token>}
    '''

    descriptor_map = defaultdict(list)  # feat_index -> list<desc_index>
    compound_map = defaultdict(list)  # feat_index -> list<compound_index>
    neg_map = defaultdict(list)  # desc_index -> list<neg_index>
    adv_map = defaultdict(list)  # desc_index -> list<adv_index>

    for token in doc:
        if token.dep_ == 'amod':
            descriptor_map[token.head.i].append(token.i)
        elif token.dep_ in ['dobj', 'nmod', 'nsubj']:
            descriptor_map[token.i].append(token.head.i)
        elif token.dep_ == 'compound':
            compound_map[token.head.i].append(token.i)
        elif token.dep_ == 'neg':
            neg_map[token.head.i].append(token.i)
        elif token.dep_ == 'advmod':
            adv_map[token.head.i].append(token.i)

    occurances = []
    for feat_index, desc_indices in descriptor_map.iteritems():
        descriptors = []
        feat_negs = map(doc.__getitem__, neg_map[feat_index])
        for desc_index in desc_indices:
            negs = map(doc.__getitem__, neg_map[desc_index])
            advs = map(doc.__getitem__, adv_map[desc_index])
            descriptors.append({'token': doc[desc_index], 'negs': negs + feat_negs, 'advs': advs})
        compounds = map(doc.__getitem__, compound_map[feat_index])
        occurance = {'token': doc[feat_index], 'compounds': compounds, 'descriptors': descriptors}
        occurances.append(occurance)

    return occurances


# -*- coding: utf8 -*-

import socket

HOST='192.168.6.66' #localhost
PORT=8765 #서버와 같은 포트사용
print("소켓생성시작")
s=socket.socket(socket.AF_INET, socket.SOCK_STREAM) #소켓생성
print("소켓생성완료")
s.connect((HOST,PORT))
print("connect!")
s.send(b'Hello, python from client') #문자를 보냄
data=s.recv(1024) #서버로 부터 정보를 받음
data2=s.recv(1024) #서버로 부터 정보를 받음
s.close()
print('Received',repr(data))
print('Received',repr(data2))


import time
import sys

from learners.data_structs.Example import Example

def usage(train_flag, predict_flag):
    """
    Prints usage messages for train and predict statements.

    :param train_flag: flag to display "train" usage message.
    :param predict_flag: flag to display "predict" usage message.
    :return: none
    """
    time.sleep(0.1)  # used to make sure these usage messages are printed after the error
    if train_flag:
        print("To train the classifier algorithm: ")
        print("\tjava lab3.java train <examples> <hypothesisOut> <learningType>")
    if predict_flag:
        print("To predict with the classifier algorithm: ")
        print("\tjava lab3.java predict <hypothesisFile> <dataFile>")
    sys.exit()

def parse(file, test_flag):
    """
    Converts the lines of data file into Example data structure.

    :param file: the file to read and convert lines into Examples.
    :param test_flag: flag to tell if the file contains training data or testing data.
    :return: an array of Examples.
    """
    examples = []

    for line in open(file, encoding="UTF-8"):
        examples.append(Example(line, test_flag))

    return examples


import requests
import datetime
import dateutil.parser, dateutil.tz
import time
import logging

from http import HTTPStatus

URL = "https://api.crackwatch.com/api/games?&sort_by=crack_date&is_cracked=true"
URL_AAA = "https://api.crackwatch.com/api/games?&sort_by=crack_date&is_cracked=true&is_aaa=true"

LAST_CHECK_DATE = datetime.datetime.now(dateutil.tz.tzlocal())

class GameInfo:
    def __init__(self, title, id, is_AAA, crack_date, image, image_poster, url, groups):
        self.title = title
        self.id = id
        self.is_AAA = is_AAA
        self.crack_date = crack_date
        self.image = image
        self.image_poster = image_poster
        self.url = url
        self.groups = groups

    @classmethod
    def from_data(cls, data):
        title = data["title"]
        id = data["_id"]
        is_AAA = data["isAAA"]
        crack_date = dateutil.parser.parse(data["crackDate"])
        image = data["image"]
        image_poster = data["imagePoster"]
        url = data["url"]
        groups = ", ".join(data["groups"])
        return GameInfo(title, id, is_AAA, crack_date, image, image_poster, url, groups)

    def __str__(self):
        return f"Title: {self.title}, crack date: {self.crack_date}, AAA: {self.is_AAA}"

    __repr__ = __str__

class CrackWatch:
    def __init__(self, url=None, url_AAA=None, last_date=None):
        if url is None:
            url = URL
        if url_AAA is None:
            url_AAA = URL_AAA
        if last_date is None:
            last_date = LAST_CHECK_DATE

        self.url = url
        self.url_AAA = url_AAA
        self.last_check_date = last_date
        self.last_game_infos = None

    def load_data(self, is_AAA=False):
        for _ in range(5):
            response = requests.get(self.url_AAA if is_AAA else self.url)
            if response.status_code == HTTPStatus.OK:
                break
            logging.info(f"{response.status_code} from {self.url_AAA if is_AAA else self.url}")
            time.sleep(5)
            response = None

        if response is None:
            return None

        data = response.json()

        return data

    def last_cracked_n(self, is_AAA=False, n=30):
        data = self.load_data(is_AAA)
        if data is None:
            return None

        game_infos = []
        for game_data in data:
            game_info = GameInfo.from_data(game_data)

            game_infos.append(game_info)
            if len(game_infos) == n:
                break

        return game_infos

    def load_new_cracked(self):
        data = self.load_data()
        if data is None:
            return False

        game_infos = []
        for game_data in data:
            game_info = GameInfo.from_data(game_data)
            if game_info.crack_date < self.last_check_date:
                break

            game_infos.append(game_info)

        self.last_game_infos = game_infos
        self.update_check_date()
        return True

    def update_check_date(self, date=None):
        if date is None:
            date = datetime.datetime.now(dateutil.tz.tzlocal())
        self.last_check_date = date

    def new_cracked(self, is_AAA=False):
        game_infos = self.last_game_infos
        if game_infos is None:
            return None

        res = []

        if not is_AAA:
            res.extend(game_infos)
            return res

        for game_info in game_infos:
            if not game_info.is_AAA:
                continue
            res.append(game_info)

        return res


# -*- coding: utf-8 -*-
"""
Created on Thu Dec 08 01:44:04 2016

@author: Ben
"""

try:
    from mpi4py import MPI
    comm = MPI.COMM_WORLD
    nprocs = comm.size
    myrank = comm.rank
except ImportError:
    print('MPI not found')
    myrank = 0
    nprocs = 1

import src
import pdb
import numpy as np
import time
import sys, os
from langreth import *
import shutil
from util import *
from functions import *
import integration
from matsubara import *
from plotting import *
import time
from itertools import product

def main():

    if myrank==0:
        time0 = time.time()
        print(' ')
        print('nprocs = ',nprocs)

    Nkx = 1
    Nky = 1
    k2p, k2i, i2k = init_k2p_k2i_i2k(Nkx, Nky, nprocs, myrank)
    kpp = np.count_nonzero(k2p==myrank)

    beta = 10.0
    ARPES = False
    pump = 0
    g2 = None
    omega = None
    tmax = 1.0
    #dt_fine = 0.001
    dt_fine = 0.001
    order = 6
    ntau = 800

    #nts = [10, 50, 100, 500]

    nts = [100]

    diffs = {}
    diffs['nts'] = nts
    diffs['U']  = []
    diffs['M']  = []
    diffs['IR'] = []
    diffs['R']  = []
    diffs['L']  = []

    delta = 0.3
    omega = 0.2
    V = 0.5
    norb = 2

    def H(kx, ky, t):
        #Bx = 2.0*V*np.cos(2.0*omega*t)
        #By = 2.0*V*np.sin(2.0*omega*t)
        #Bz = 2.0*delta
        #return 0.5*np.array([[Bz, Bx-1j*By], [Bx+1j*By, -Bz]], dtype=complex)
        return np.array([[delta, V*np.exp(-2.0*1j*omega*t)], [V*np.exp(+2.0*1j*omega*t), -delta]], dtype=complex)

    def compute_time_dependent_G0(H, myrank, Nkx, Nky, ARPES, kpp, k2p, k2i, tmax, nt, beta, ntau, norb, pump):
        # check how much slower this is than computing G0 using U(t,t')

        norb = np.shape(H(0,0,0))[0]
        def H0(kx, ky, t): return np.zeros([norb,norb])
        constants = (myrank, Nkx, Nky, ARPES, kpp, k2p, k2i, tmax, nt, beta, ntau, norb, pump)
        UksR, UksI, eks, fks, Rs, Ht = init_Uks(H0, dt_fine, *constants, version='higher order')
        G0M_ref = compute_G0M(0, 0, UksI, eks, fks, Rs, *constants)
        G0_ref  = compute_G0R(0, 0, UksR, UksI, eks, fks, Rs, *constants)

        dt = 1.0*tmax/(nt-1)

        G0M = compute_G00M(0, 0, *constants)
        G0  = compute_G00R(0, 0, *constants)

        print('test G00')
        differences(G0_ref, G0)

        '''
        G00M = compute_G00M(0, 0, *constants)
        G00  = compute_G00R(0, 0, G0M, *constants)

        print('shpae G0M', np.shape(G0M.M))
        print('shape G00M', np.shape(G00M.M))

        #for (i,j) in product(range(norb), repeat=2):
        #    plt(np.linspace(0,beta,ntau), [G0M.M[:,i,j].imag, G00M.M[:,i,j].imag], 'G00M %d %d'%(i,j))
        #    plt(np.linspace(0,beta,ntau), [G0M.M[:,i,j].real, G00M.M[:,i,j].real], 'G00M %d %d'%(i,j))

        print('diffs')
        print(dist(G0M.M, G00M.M))
        print(dist(G0.R, G00.R))
        print(dist(G0.L, G00.L))
        print(dist(G0.IR, G00.IR))
        exit()
        '''

        GM = matsubara(beta, ntau, norb, -1)
        SigmaM  = matsubara(beta, ntau, norb, -1)
        SigmaM.deltaM = H(0, 0, 0)
        integrator.dyson_matsubara(G0M, SigmaM, GM)

        # check if SigmaM is the same as before

        G = langreth(norb, nt, tmax, ntau, beta, -1)
        Sigma = langreth(norb, nt, tmax, ntau, beta, -1)
        for it in range(nt):
            Sigma.deltaR[it] = H(0, 0, it*dt)
        integrator.dyson_langreth(G0M, SigmaM, G0, Sigma, G)

        return GM, G

    for nt in nts:

        constants = (myrank, Nkx, Nky, ARPES, kpp, k2p, k2i, tmax, nt, beta, ntau, norb, pump)

        integrator = integration.integrator(6, nt, beta, ntau)

        #---------------------------------------------------------
        # compute U(t,t') exactly and the corresponding G0

        #Uexact = np.array([expm(-1j*H(0,0,0)*t) for t in ts])

        ts = np.linspace(0, tmax, nt)
        _, UksI, eks, fks, Rs, _ = init_Uks(H, dt_fine, *constants)

        Omega = sqrt((delta-omega)**2 + V**2)
        Uexact = np.zeros([1, nt, norb, norb], dtype=np.complex128)
        Uexact[0, :, 0, 0] = np.exp(-1j*omega*ts)*(np.cos(Omega*ts) - 1j*(delta-omega)/Omega*np.sin(Omega*ts))
        Uexact[0, :, 0, 1] = -1j*V/Omega*np.exp(-1j*omega*ts)*np.sin(Omega*ts)
        Uexact[0, :, 1, 0] = -1j*V/Omega*np.exp(1j*omega*ts)*np.sin(Omega*ts)
        Uexact[0, :, 1, 1] = np.exp(1j*omega*ts)*(np.cos(Omega*ts) + 1j*(delta-omega)/Omega*np.sin(Omega*ts))

        print('check unitary ')
        p = np.einsum('tba,tbc->tac', np.conj(Uexact[0,:]), Uexact[0,:])
        print(dist(p, np.einsum('t,ab->tab', np.ones(nt), np.diag(np.ones(norb)))))

        GMexact = compute_G0M(0, 0, UksI, eks, fks, Rs, *constants)
        Gexact = compute_G0R(0, 0, Uexact, UksI, eks, fks, Rs, *constants)

        #---------------------------------------------------------
        # compute G0 computed with U(t,t') via integration
        UksR, UksI, eks, fks, Rs, _ = init_Uks(H, dt_fine, *constants, version='higher order')
        G0M = compute_G0M(0, 0, UksI, eks, fks, Rs, *constants)
        G0  = compute_G0R(0, 0, UksR, UksI, eks, fks, Rs, *constants)

        # test for U(t,t')
        d = dist(Uexact, UksR)
        print('diff Uexact UksR', d)
        print("done computing G0 using U(t,t')")
        diffs['U'].append(d)

        #---------------------------------------------------------
        # compute non-interacting G for the norb x norb problem
        # we compute this by solving Dyson's equation with the time-dependent hamiltonian as the selfenergy

        GdysonM, Gdyson = compute_time_dependent_G0(H, *constants)
        print('done computing G0 via Dyson equation')

        '''
        ts = np.linspace(0,tmax,nt)
        Uexact = np.array([expm(-1j*H(0,0,0)*t) for t in ts])
        print('diff Uexact UksR', dist(Uexact, UksR[0]))
        for (i,j) in product(range(2), repeat=2):
            plt(ts, [UksR[0,:,i,j].real, Uexact[:,i,j].real], 'real part %d %d'%(i,j))
            plt(ts, [UksR[0,:,i,j].imag, Uexact[:,i,j].imag], 'imag part %d %d'%(i,j))
        exit()
        '''

        #for (i,j) in product(range(norb), repeat=2):
        #    plt(np.linspace(0, beta, ntau), [G0.M[:,i,j].imag, GdysonM.M[:,i,j].imag], 'G0M')

        '''
        for (i,j) in product(range(norb), repeat=2):
            im([Gexact.L[:,i,:,j].real, G0.L[:,i,:,j].real, Gdyson.L[:,i,:,j].real], [0,tmax,0,tmax], 'G0 real L %d %d'%(i,j))
            im([Gexact.L[:,i,:,j].imag, G0.L[:,i,:,j].imag, Gdyson.L[:,i,:,j].imag], [0,tmax,0,tmax], 'G0 imag L %d %d'%(i,j))
        '''

        print('differences between G0 and Gexact')
        differences(G0, Gexact)

        print('differences between Gdyson and Gexact')
        differences(Gdyson, Gexact)

        '''
        for (i,j) in product(range(norb), repeat=2):
            print('i j %d %d'%(i,j))
            im([G0.R[:,i,:,j].imag, Gexact.R[:,i,:,j].imag], [0,tmax,0,tmax], 'R imag')
            im([G0.R[:,i,:,j].real, Gexact.R[:,i,:,j].real], [0,tmax,0,tmax], 'R real')
        '''

    plt_diffs(diffs)

    if 'MPI' in sys.modules:
        MPI.Finalize()

if __name__=='__main__':
    main()
    print('\nPASSED TEST')