#####################################################################################
# ADLINK USB-1902 to acquire/measure DATA
# This sample program shows how to import DLL
# AI One shot acquisition for USB-1902
# This sample program run on Python 3.x
# ADLINK Technologies 2020.04.13
#####################################################################################

import os
import numpy as np
from ctypes import *
import matplotlib.pyplot as plt  #used to pilot chart
#if not installed , use following command to install
#python -m pip install -U pip setuptools
#python -m pip install matplotlib
#also use python -m pip install pillow to save image

import time
u16 = np.dtype(np.uint16)
F64 = np.dtype(np.float64)

def is_64_windows():
    return 'PROGRAMFILES(X86)' in os.environ

def cal_interval(sampling_rate, num_of_channel):
    p190x_timebase = np.uint32(80000000)
    global var_scan_intv
    var_scan_intv = np.uint32(p190x_timebase/(sampling_rate*num_of_channel))

if  is_64_windows():
    dll = WinDLL("USB-Dask64.dll")
    print("On 64 bit OS using USB-Dask64.dll")
else:
    dll = WinDLL("USB-Dask.dll")
    print("On 32 bit OS using USB-Dask.dll")

dll.UD_Register_Card.restype = c_int16
dll.UD_Register_Card.argtypes = [c_uint16,c_uint16]
dll.UD_Release_Card.restype = c_int16
dll.UD_Release_Card.argtypes = [c_uint16]
dll.UD_AI_1902_Config.restype = c_int16
dll.UD_AI_1902_Config.argtypes = [c_uint16, c_uint16, c_uint16, c_uint32, c_uint32, c_uint32]
dll.UD_AI_AsyncDblBufferMode.restype = c_int16
dll.UD_AI_AsyncDblBufferMode.argtypes = [c_uint16, c_bool]
dll.UD_AI_1902_CounterInterval.restype = c_int16
dll.UD_AI_1902_CounterInterval.argtypes = [c_uint16, c_uint32, c_uint32]
dll.UD_AI_ContReadChannel.restype = c_int16
dll.UD_AI_ContReadChannel.argtypes = [c_uint16, c_uint16, c_uint16, POINTER(c_uint16), c_uint32, c_double, c_uint16]
dll.UD_AI_AsyncCheck.restype = c_int16
dll.UD_AI_AsyncCheck.argtypes = [c_uint16, POINTER(c_bool), POINTER(c_uint32)]
dll.UD_AI_AsyncClear.restype = c_int16
dll.UD_AI_AsyncClear.argtypes = [c_uint16, POINTER(c_uint32)]
dll.UD_AI_ContVScale.restype = c_int16
dll.UD_AI_ContVScale.argtypes = [c_uint16, c_uint16, POINTER(c_uint16), POINTER(c_double) ,c_uint32]

cfg_card_type = np.int16(0x01) #USB-1902
cfg_inputtype = np.int16(0x01)#P1902_AI_SingEnded
cfg_convsrc = np.int16(0x00)#P1902_AI_CONVSRC_INT
cfg_trigsrc = np.int16(0x030)#P1902_AI_TRGSRC_SOFT
cfg_trigpolarity = np.int16(0x040)#P1902_AI_TrgPositive
cfg_trigmode = np.int16(0x000)#P1902_AI_TRGMOD_POST
cfg_triglevel = np.int32(0)
cfg_retrigcnt = np.int32(0)
cfg_delaycnt = np.int32(0)
cfg_doublebuf_mode = np.bool_(False)
cfg_num_of_channel = np.int16(1)
cfg_channel_num = np.int16(0)
cfg_sampling_rate = np.int32(250000) #250k single channel or 250k/N channel
cfg_AI_read_cnt = np.int32(1024)
cfg_AD_RANGE = np.int16(1)#AD_B_10_V
cfg_sync_mode = np.int16(2)#ASYNCH_OP

var_card = np.int16(-1)
var_card_num = np.int16(7)
var_ret = np.int16(-1)
var_scan_intv = np.int32(320)
var_sample_intv = np.int32(320)

var_Buffer = (c_uint16*cfg_AI_read_cnt)()
cast(var_Buffer, POINTER(c_uint16))
var_Vol_Buffer = (c_double*cfg_AI_read_cnt)()
cast(var_Vol_Buffer, POINTER(c_double))

var_card = dll.UD_Register_Card(cfg_card_type,var_card_num)
if var_card < 0:
	print("UD_Register_Card fail, error = %d\n",var_card)
	exit()
print("Register card successfully")

var_ret = dll.UD_AI_1902_Config(var_card \
                               ,cfg_inputtype | cfg_convsrc \
                               ,cfg_trigsrc | cfg_trigpolarity | cfg_trigmode \
                               ,cfg_triglevel \
                               ,cfg_retrigcnt \
                               ,cfg_delaycnt \
                               )
if var_ret < 0:
    dll.UD_Release_Card(var_card)
    print("UD_AI_1902_Config fail, error = %d\n",var_ret)
    exit()

dll.UD_AI_AsyncDblBufferMode(var_card,cfg_doublebuf_mode)

cal_interval(cfg_sampling_rate,cfg_num_of_channel)
print("scan_intv = ",var_scan_intv,",sample_intv = ",var_sample_intv)

var_ret = dll.UD_AI_1902_CounterInterval(var_card,var_scan_intv,var_sample_intv)
if var_ret < 0:
    dll.UD_Release_Card(var_card)
    print("UD_AI_1902_CounterInterval fail, error = %d\n",var_ret)
    exit()

var_ret = dll.UD_AI_ContReadChannel(var_card,cfg_channel_num,cfg_AD_RANGE,var_Buffer,cfg_AI_read_cnt,cfg_sampling_rate,cfg_sync_mode)
if var_ret < 0:
    dll.UD_Release_Card(var_card)
    print("UD_AI_ContReadChannel fail, error = %d\n",var_ret)
    exit()

print("Start AI");
Stopped = c_bool(False)
AccessCnt = c_uint32()
Startpos = c_uint32()

while Stopped.value == bool(False):
    var_ret = dll.UD_AI_AsyncCheck(var_card,Stopped,AccessCnt)
    if var_ret < 0:
        dll.UD_AI_AsyncClear(var_card,AccessCnt)
        dll.UD_Release_Card(var_card)
        exit()
    if Stopped == True:
        break
    time.sleep(0.01)
    print(".")

print("Stop AI")

var_ret = dll.UD_AI_AsyncClear(var_card,AccessCnt)
var_ret = dll.UD_AI_ContVScale(var_card, cfg_AD_RANGE, var_Buffer, var_Vol_Buffer, cfg_AI_read_cnt)
print("UD_AI_ContVScale ret = ",var_ret)

dll.UD_Release_Card(var_card)
print("Release card successfully")

x = np.arange(0,cfg_AI_read_cnt)

plt.plot(x,var_Vol_Buffer,lw=3)
plt.plot(x,var_Vol_Buffer,"b-o")
#plt.plot(x,VBuffer0,"-o")
#plt.plot(x,VBuffer0,"ro")
#plt.plot(x,VBuffer0,"y--")
plt.xlabel("count")
plt.ylabel("Voltage")
plt.title("USB-1902")
plt.ylim(-10,10)
plt.savefig("USB-1902_python_example_result.jpg",dpi=800,format="jpg")
plt.show()

print("Done...");


import base64

from django.core.files.base import ContentFile
from django.db.models import Count, Q
from rest_framework.decorators import api_view
from rest_framework.pagination import PageNumberPagination
from rest_framework.response import Response
from django.contrib.auth import get_user_model

from account.models import Profile
from community.models import Community, CommunityBlackList, CommunityHistory, Member, MemberInfo, CommunityBlackListDetail, BlackListType
from post.models import PositivePoint, Post
from post.serializers import CommunityGraphSerializer, CommunitySerializer
from redditv1.message import Message
from redditv1.name import Role
from django.utils import timezone
from function.file import get_image
from redditv1.name import ModelName, BLType
from function.paginator import get_paginated_queryset_response
from function.file import isValidHexaCode
import datetime
from service.post.post_service import timestamp_in_the_past_by_day
from functools import reduce
import operator

User = get_user_model()

def create_community(request):
    if request.user.is_authenticated:
        community = request.data.get("community")
        sub_community = request.data.get("sub_community")
        background = request.data.get("background")
        description = request.data.get("description")
        avatar = request.data.get("avatar")
        rule = request.data.get("rule")
        background_color = request.data.get("background_color")
        if request.user.positivepoint.point <= 10:
            return Response({Message.SC_NOT_ENOUGH_POINT}, status=400)
        if not sub_community:
            if Community.objects.filter(community_type=community):
                return Response({Message.SC_CM_EXIST}, status=200)
            if not request.user.is_staff:
                return Response({Message.SC_PERMISSION_DENIED}, status=403)
            community = Community.objects.create(community_type=community,
                                                 description=description,
                                                 rule=rule,
                                                 creator=request.user)
            if isValidHexaCode(background_color):
                community.background_color = background_color
            if background:
                if len(background) > len('data:,'):
                    community.background = get_image(background)
            if avatar:
                if len(avatar) > len('data:,'):
                    community.avatar = get_image(avatar)
            community.save()
            positive_point = PositivePoint.objects.filter(
                user=request.user).first()
            positive_point.point = positive_point.point - 10
            positive_point.save()
            serializer = CommunitySerializer(community,
                                             context={'request': request})
            return Response(serializer.data, status=201)
        if not Community.objects.filter(community_type=community):
            return Response({Message.SC_CM_NOT_FOUND}, status=204)

        community_exist = Community.objects.filter(
            community_type=sub_community).first()
        if community_exist:
            return Response({Message.SC_CM_EXIST}, status=200)
        parent = Community.objects.filter(community_type=community).first()
        community = Community.objects.create(community_type=sub_community,
                                             parent=parent,
                                             description=description,
                                             rule=rule,
                                             creator=request.user)
        if isValidHexaCode(background_color):
            community.background_color = background_color
        positive_point = PositivePoint.objects.filter(
            user=request.user).first()
        positive_point.point = positive_point.point - 10
        positive_point.save()
        if background:
            if len(background) > len('data:,'):
                community.background = get_image(background)
        if avatar:
            if len(avatar) > len('data:,'):
                community.avatar = get_image(avatar)
        community.save()
        serializer = CommunitySerializer(community,
                                         context={"request": request})
        return Response(serializer.data, status=201)

def get_community(request):
    page_size = request.data.get("page_size")
    community_type = request.data.get('community')
    print(community_type)
    if community_type:
        community = Community.objects.filter(
            community_type__icontains=community_type)
        return get_paginated_queryset_response(community, request, page_size,
                                               ModelName.COMMUNITY)
    return Response({Message.SC_NOT_FOUND}, status=204)

def get_list_community_by_user(request):
    page_size = request.data.get("page_size")
    if not request.user.is_authenticated:
        return Response({Message.SC_NO_AUTH}, status=401)
    query = Community.objects.filter(user=request.user)
    return get_paginated_queryset_response(query, request, page_size,
                                               ModelName.COMMUNITY)

def community_action(request):
    if request.user.is_authenticated:
        community_type = request.data.get('community')
        action = request.data.get('action')
        community = Community.objects.filter(
            community_type=community_type).first()
        if community:
            member = Member.objects.filter(user=request.user).first()
            if not member:
                member = Member.objects.create(user=request.user)
            check_member(member, community, request.user, action)
            if action == "follow":
                community.user.add(request.user)
            if action == "un_follow":
                community.user.remove(request.user)
            return Response({Message.SC_OK}, status=200)
        return Response({Message.SC_NOT_FOUND}, status=204)
    return Response({Message.SC_LOGIN_REDIRECT}, status=401)

def check_member(member, community, user, action):
    if community:
        if not member:
            print('member not ex')
            member = Member.objects.create(user=user)
            if action == 'follow':
                member_info = MemberInfo.objects.create(
                    community=community, timestamp=datetime.datetime.now())
                member_info.save()
                member.member_info.add(member_info)
                member.save()
            if action == 'un_follow':
                member.save()
        else:
            check_member_exist = Member.objects.filter(
                user=user, member_info__community=community).first()
            if not check_member_exist:
                print('member info not ex')
                member_info = MemberInfo.objects.create(
                    community=community, timestamp=datetime.datetime.now())
                if action == 'follow':
                    member_info.save()
                    member.member_info.add(member_info)
                    member.save()
            else:
                print('member info ex')
                member_info = MemberInfo.objects.filter(
                    member=check_member_exist, community=community).first()
                member_info.timestamp = datetime.datetime.now()
                if action == 'un_follow':
                    member_info.state = False
                if action == 'follow':
                    member_info.state = True
                member_info.save()
                member.save()

def get_list_community(request):
    page_size = request.data.get("page_size")
    print(page_size)
    query = Community.objects.all()
    return get_paginated_queryset_response(query, request, page_size,
                                           ModelName.COMMUNITY)

def change_state(request, community_type):
    if request.user.is_authenticated:
        if community_type:
            community = Community.objects.filter(
                creator=request.user, community_type=community_type).first()
            if community:
                community.state = not community.state
                community.save()
                return Response(Message.SC_OK, status=200)
            return Response(Message.SC_PERMISSION_DENIED, status=403)
        return Response(Message.SC_BAD_RQ, status=400)
    return Response(Message.SC_LOGIN_REDIRECT, status=403)

def community_update(request):
    if not request.user.is_authenticated:
        return Response({}, status=401)
    user = request.user
    community_type = request.data.get('community_type')
    community = Community.objects.filter(
        creator=request.user, community_type=community_type).first()
    background = request.data.get("background")
    description = request.data.get("description")
    avatar = request.data.get("avatar")
    background_color = request.data.get("background_color")
    title_background_color = request.data.get("title_background_color")
    description_background_color = request.data.get(
        "description_background_color")
    button_background_color = request.data.get("button_background_color")
    button_text_color = request.data.get("button_text_color")
    text_color = request.data.get("text_color")
    post_background_color = request.data.get("post_background_color")

    if community:
        if background:
            if len(background) > len('data:,'):
                community.background = get_image(background)
        if avatar:
            if len(avatar) > len('data:,'):
                community.avatar = get_image(avatar)
        if description:
            community.description = description
        if background_color:
            if isValidHexaCode(background_color):
                community.background_color = background_color
            else:
                return Response({Message.DETAIL: Message.WRONG_INPUT_COLOR},
                                status=400)
        if description_background_color:
            if isValidHexaCode(description_background_color):
                community.description_background_color = description_background_color
            else:
                return Response({Message.DETAIL: Message.WRONG_INPUT_COLOR},
                                status=400)
        if title_background_color:
            if isValidHexaCode(title_background_color):
                community.title_background_color = title_background_color
            else:
                return Response({Message.DETAIL: Message.WRONG_INPUT_COLOR},
                                status=400)
        if button_background_color:
            if isValidHexaCode(button_background_color):
                community.button_background_color = button_background_color
            else:
                return Response({Message.DETAIL: Message.WRONG_INPUT_COLOR},
                                status=400)
        if button_text_color:
            if isValidHexaCode(button_text_color):
                community.button_text_color = button_text_color
            else:
                return Response({Message.DETAIL: Message.WRONG_INPUT_COLOR},
                                status=400)
        if text_color:
            if isValidHexaCode(text_color):
                community.text_color = text_color
            else:
                return Response({Message.DETAIL: Message.WRONG_INPUT_COLOR},
                                status=400)
        if post_background_color:
            if isValidHexaCode(post_background_color):
                community.post_background_color = post_background_color
            else:
                return Response({Message.DETAIL: Message.WRONG_INPUT_COLOR},
                                status=400)
        user.save()
        community.save()
        return Response({Message.DETAIL: Message.SC_OK}, status=200)
    return Response({Message.DETAIL: Message.SC_CM_NOT_FOUND}, status=400)

def recommend_sub_community(request, community):
    page_size = request.data.get("page_size")
    sub_community = Community.objects.filter(parent__community_type=community)
    if request.user.is_authenticated:
        sub_community = Community.objects.filter(
            parent__community_type=community).exclude(user=request.user)
    return get_paginated_queryset_response(sub_community, request, page_size,
                                           ModelName.COMMUNITY)

def recommend_community(request):
    page_size = request.data.get("page_size")
    community = Community.objects.all().annotate(
        user_count=Count('user')).order_by('user_count')
    if request.user.is_authenticated:
        community = Community.objects.all().exclude(
            user=request.user).annotate(
                user_count=Count('user')).order_by('user_count')
    return get_paginated_queryset_response(community, request, page_size,
                                           ModelName.COMMUNITY)

def community_graph(request):
    from_timestamp = request.data.get('from_timestamp')
    to_timestamp = request.data.get('to_timestamp')
    page_size = request.data.get('page_size')
    print('detect')
    if from_timestamp:
        print("timestamp: ", from_timestamp)
    if from_timestamp is not None and to_timestamp is not None:
        query = Community.objects.filter(
            timestamp__gte=from_timestamp,
            timestamp__lte=to_timestamp,
        )
        return get_paginated_queryset_response(query, request, page_size,
                                               ModelName.COMMUNITY_GRAPH)
    query = Community.objects.filter(
        timestamp__gte=timestamp_in_the_past_by_day(30),
        timestamp__lte=timezone.now(),
    )
    return get_paginated_queryset_response(query, request, page_size,
                                           ModelName.COMMUNITY_GRAPH)

def mod_action(request):
    community = request.data.get('community')
    user_id = request.data.get('user_id')
    action = request.data.get('action')
    if not action:
        return Response({Message.DETAIL: Message.SC_BAD_RQ}, status=400)
    if request.user.is_authenticated:
        user = User.objects.filter(id=user_id).first()
        community = Community.objects.filter(community_type=community).first()
        if not community or not user:
            return Response({Message.DETAIL: Message.SC_NOT_FOUND}, status=204)
        community_check = community.creator == request.user
        if not community_check:
            return Response({Message.DETAIL: Message.SC_PERMISSION_DENIED},
                            status=403)
        history = CommunityHistory.objects.filter(user=request.user,
                                                  community=community,
                                                  target=user).first()
        if not history:
            history = CommunityHistory.objects.create(user=request.user,
                                                      community=community,
                                                      target=user)
        member = Member.objects.filter(user=user).first()
        if member:
            member_info = MemberInfo.objects.filter(
                member=member, community=community).first()
            if member_info:
                current_member = MemberInfo.objects.filter(
                    member=member, community=community).first()
                print('has member info, old role: ', current_member.role)
                print('action:', action)
                if action == 'promote':
                    print('current role', current_member.role, Role.MOD)
                    if current_member.role == Role.MEMBER:
                        history.old_role = current_member.role
                        history.new_role = Role.MOD
                        current_member.role = history.new_role
                        print('new_role', history.new_role)
                        community.mod.add(user)
                        history.timestamp = timezone.now()
                        history.save()
                        community.save()
                elif action == 'demote':
                    if current_member.role == Role.MOD:
                        print('demote')
                        history.old_role = current_member.role
                        history.new_role = Role.MEMBER
                        current_member.role = history.new_role
                        community.mod.remove(user)
                        history.timestamp = timezone.now()
                        community.save()
                        history.save()
                current_member.save()
            history.timestamp = timezone.now()
            print(current_member.role, history.new_role, 'after update')
            return Response({Message.DETAIL: Message.SC_OK}, status=200)
        return Response({Message.DETAIL: Message.USER_MUST_BE_MEMBER},
                        status=403)
    return Response({Message.DETAIL: Message.SC_NO_AUTH}, status=401)

def member_list(request):
    """
        data = "community":"community"
    """
    page_size = request.data.get('page_size')
    community = request.data.get('community')
    if community:
        community = Community.objects.filter(community_type=community).first()
        if community:
            member_info = MemberInfo.objects.filter(community=community)
            member = Member.objects.filter(member_info__in=member_info)
            profile = Profile.objects.filter(
                reduce(operator.or_, (Q(user=x.user) for x in member)))
            return get_paginated_queryset_response(profile, request, page_size,
                                                   ModelName.PROFILE)
    return Response({Message.DETAIL: Message.SC_BAD_RQ}, 400)

def add_use_to_community_blacklist(request):
    user_id = request.data.get('user_id')
    community = request.data.get('community')
    type = request.data.get('type')
    from_timestamp = request.data.get('from_timestamp')
    to_timestamp = request.data.get('to_timestamp')
    '''
        mod and mod can not add another mod or admin into blacklist
        default in black list is 1 day
    '''
    if request.user.is_authenticated:
        if user_id and community and type:
            changed_by = request.user
            target_profile = Profile.objects.filter(user__id=user_id).first()
            community = Community.objects.filter(
                community_type=community).first()
            if target_profile and community:
                if target_profile.user == community.creator:
                    return Response(
                        {Message.DETAIL: Message.SC_PERMISSION_DENIED},
                        status=403)

                member = Member.objects.filter(user=request.user).first()
                if request.user == community.creator:
                    if not member:
                        member = Member.objects.create(user=request.user)
                        member_info = MemberInfo.objects.create(community=community, role=Role.ADMIN)
                        member.member_info.add(member_info)
                        member.save()
                member_info = MemberInfo.objects.filter(
                    member=member, community=community).first()
                target_member = Member.objects.filter(
                    user=target_profile.user).first()
                target_member_info = MemberInfo.objects.filter(
                    member=target_member, community=community).first()
                print('change by',member_info.role, 'target',target_member_info.role)
                if member_info and target_member_info:
                    if member_info.role == Role.ADMIN or target_member_info.role == Role.MOD:
                        blacklist = CommunityBlackList.objects.filter(
                            community=community).first()
                        if not blacklist:
                            blacklist = CommunityBlackList.objects.create(
                                community=community)
                        blacklist_detail = CommunityBlackListDetail.objects.filter(
                            user=target_profile.user,
                            communityblacklist=blacklist).first()
                        if not blacklist_detail:
                            blacklist_detail = CommunityBlackListDetail.objects.create(communityblacklist=blacklist)
                            blacklist_detail.user.add(target_profile.user)
                        default_blacklist_type()
                        blacklist_type = BlackListType.objects.filter(
                            type=type).first()
                        blacklist.blacklist_detail = blacklist_detail
                        blacklist.save()
                        blacklist_detail.user.add(target_profile.user)
                        blacklist_detail.blacklist_type = blacklist_type
                        if not from_timestamp or not to_timestamp:
                            blacklist_detail.from_timestamp = timezone.now()
                            blacklist_detail.to_timestamp = timestamp_in_the_past_by_day(
                                1)
                        else:
                            blacklist_detail.from_timestamp = from_timestamp
                            blacklist_detail.to_timestamp = to_timestamp
                        blacklist_detail.save()
                        return Response({Message.DETAIL:Message.SC_OK}, status=200)
                return Response({Message.DETAIL: Message.SC_NOT_FOUND},
                                status=204)
            return Response({Message.DETAIL: Message.SC_CM_NOT_FOUND},
                            status=204)
        return Response({Message.DETAIL: Message.SC_BAD_RQ},
                            status=400)
    return Response({Message.DETAIL: Message.SC_NO_AUTH},
                            status=401)

def default_blacklist_type():
    blacklist_type = BlackListType.objects.all()
    if blacklist_type.count() == 0:
        type_1 = BlackListType.objects.create(
            type=BLType.VIEW_ONLY,
            description=
            'User can not search, see post, post on target community')
        type_1.save()
        type_2 = BlackListType.objects.create(
            type=BLType.BLOCK,
            description='User can not post in target community')
        type_2.save()

def get_followed_community_by_username(request, username):
    if username:
        community_list = Community.objects.filter(user__username=username)
        return get_paginated_queryset_response(community_list, request, 10,
                                               ModelName.COMMUNITY)
    return Response({Message.DETAIL: Message.SC_BAD_RQ},
                            status=400)

def hidden_post(request):
    if not request.user.is_authenticated:
        return Response({Message.SC_NO_AUTH}, status=401)
    post_id = request.data.get('post_id')
    post = Post.objects.filter(id=post_id).first()
    if post:
        author = post.user
        if request.user == author:
            post.hidden = True
            post.save()
            return Response({Message.SC_OK}, status=200)
        community = post.community
        member = Member.objects.filter(user=request.user).first()
        member_info = member.member_info.filter(community=community).first()
        if member_info:
            if member_info.role == "MOD" or member_info.role == "ADMIN":
                post.hidden_in_community = True
                post.save()
                return Response({Message.SC_OK}, status=200)
        return Response({Message.SC_PERMISSION_DENIED}, status=403)
    return Response({Message.SC_NOT_FOUND}, status=400)

def timestamp_in_the_past_by_day(days):
    return timezone.now() - datetime.timedelta(days)


#
# UserAttributes
#
# Authors: Stijn Wopereis (Wopster)
# Description: Adds to the option to add and modify I3D user attributes.
#
# Copyright (c) Stijn Wopereis, 2018

import maya.cmds as cmds
import maya.OpenMaya as OpenMaya

import random
import string

from functools import partial

from I3DExporter import TEXT_WIDTH, DEFAULT_FIELD_WIDTH, I3DUpdateLayers, I3DSaveAttributeBool, I3DSaveAttributeString, I3DSaveAttributeFloat, I3DSaveAttributeInt, \
    I3DAttributeExists

# UserAttributes
UI_OPTIONS_PREDEFINED_USERATTRIBUTETYPES = 'wopster_optionsUserAttributeTypes'
UI_OPTIONS_PREDEFINED_USERATTRIBUTE_NAME = 'wopster_optionsUserAttributeName'
UI_OPTIONS_PREDEFINED_USERATTRIBUTE_VALUE = 'wopster_optionsUserAttributeValue'

UI_CONTROL_USERATTRIBUTES_STRING_NODE_NAME = 'wopster_attributeObjectName'
UI_CONTROL_USERATTRIBUTES_STRING_NODE_INDEX = 'wopster_attributeObjectIndex'

UI_CONTROL_LAYOUT_USERATTRIBUTES = 'wopster_layoutUserAtrributes'
UI_CONTROL_LAYOUT_USERATTRIBUTES_ROWS = 'wopster_attributesRows'
UI_CONTROL_LAYOUT_USERATTRIBUTES_ADD_ATTRIBUTE = 'wopster_layoutUserAtrributesAddNew'
UI_CONTROL_BUTTON_USERATTRIBUTES_ADD_ATTRIBUTE = 'wopster_buttonUserAtrributesAddNew'

TYPE_BOOL = 1
TYPE_INT = 2
TYPE_FLOAT = 3
TYPE_STRING = 4
TYPE_SCRIPTCALLBACK = 5

UI_MENU_USERATTRIBUTES = {
    'bool': TYPE_BOOL,
    'integer': TYPE_INT,
    'long': TYPE_INT,
    'string': TYPE_STRING,
    'float': TYPE_FLOAT,
    'double': TYPE_FLOAT,
    'scriptCallback': TYPE_SCRIPTCALLBACK,
}

class UserAttributes:

    def __init__(self):
        self.userAttributes_type_settings = []

    def delete(self):
        self.userAttributes_type_settings = []
        # pass

    def showWarning(self, text):
        OpenMaya.MGlobal.displayWarning(text)

    def initUI(self, parent):
        tab = cmds.formLayout('TabUserAttributes', parent=parent)
        cmds.columnLayout(adjustableColumn=True)

        # Frame for the current selection
        selection_frame = cmds.frameLayout('ua_selectionFrame', label='Current Selection', parent=tab, w=390, cll=False, mh=2, mw=2)
        current_node_layout = cmds.columnLayout(adjustableColumn=True, parent=selection_frame)

        self.addTextFieldElement(current_node_layout, 'Node Name', UI_CONTROL_USERATTRIBUTES_STRING_NODE_NAME, '', '', editable=False, width=245)
        self.addTextFieldElement(current_node_layout, 'Node Index', UI_CONTROL_USERATTRIBUTES_STRING_NODE_INDEX, '', '', editable=False, width=245)

        attributes_main_frame = cmds.frameLayout(parent=tab, label='Attributes', w=390, cll=False, mh=2, mw=2)
        attributes_scroll_layout = cmds.scrollLayout('scrollAttributes', parent=attributes_main_frame, cr=True, verticalScrollBarAlwaysVisible=False)

        # Add user attribute
        new_attributes_layout = cmds.frameLayout(UI_CONTROL_LAYOUT_USERATTRIBUTES_ADD_ATTRIBUTE, parent=attributes_scroll_layout, label='Add new attribute', w=390, cll=False, mh=2, mw=2)

        # Type of new attribute
        attributes_type_row_layout = cmds.rowLayout(adjustableColumn=2, numberOfColumns=2, parent=new_attributes_layout)
        cmds.text(parent=attributes_type_row_layout, label='Type', width=TEXT_WIDTH, align='left', annotation='')

        type_option_menu = cmds.optionMenu(UI_OPTIONS_PREDEFINED_USERATTRIBUTETYPES, parent=attributes_type_row_layout, annotation='Type',
                                           changeCommand=self.onChangeUserAttributeType)

        for k, _ in UI_MENU_USERATTRIBUTES.iteritems():
            cmds.menuItem(parent=type_option_menu, label=k)

        self.onChangeUserAttributeType(UI_MENU_USERATTRIBUTES['bool'])

        attributes_frame = cmds.frameLayout(UI_CONTROL_LAYOUT_USERATTRIBUTES, label='Current attributes', parent=attributes_scroll_layout, w=390, cll=True, mh=2, mw=2)
        attributes_layout = cmds.columnLayout(adjustableColumn=True, parent=attributes_frame)

        attributes_row_layout = cmds.rowLayout(UI_CONTROL_LAYOUT_USERATTRIBUTES_ROWS, parent=attributes_layout, columnWidth4=(TEXT_WIDTH, TEXT_WIDTH * 2, TEXT_WIDTH, 10),
                                               adjustableColumn=4, numberOfColumns=4, )
        cmds.text(parent=attributes_row_layout, label='Name', width=TEXT_WIDTH, align='left', annotation='')
        cmds.text(parent=attributes_row_layout, label='Value', width=TEXT_WIDTH * 2, align='left', annotation='')
        cmds.text(parent=attributes_row_layout, label='Type', width=TEXT_WIDTH, align='right', annotation='')

        attribute_button_items = cmds.formLayout('AttributeButtons', parent=tab)

        button_load = cmds.button(parent=attribute_button_items, label='Load', height=30, width=150, align='right', command=self.loadObjectUserAttribute)
        button_save = cmds.button(parent=attribute_button_items, label='Save', height=30, width=150, align='left', command=self.updateObjectUserAttribute)
        cmds.formLayout(attribute_button_items, edit=True, attachPosition=((button_load, 'left', 0, 0), (button_load, 'right', 5, 50),
                                                                           (button_save, 'left', 0, 50), (button_save, 'right', 5, 100)))
        cmds.formLayout(tab, edit=True, attachForm=(
            (selection_frame, 'top', 2), (selection_frame, 'left', 2), (selection_frame, 'right', 2),
            (attributes_main_frame, 'top', 74), (attributes_main_frame, 'left', 2), (attributes_main_frame, 'right', 2), (attributes_main_frame, 'bottom', 32),
            (attribute_button_items, 'bottom', 2), (attribute_button_items, 'left', 2), (attribute_button_items, 'right', 2)
        ))

        return tab

    def updateCurrentSelectionNode(self, index, node):
        cmds.textField(UI_CONTROL_USERATTRIBUTES_STRING_NODE_INDEX, edit=True, text=index)
        cmds.textField(UI_CONTROL_USERATTRIBUTES_STRING_NODE_NAME, edit=True, text=node)

    def loadObjectUserAttribute(self, unused):
        object_name = str(cmds.textField(UI_CONTROL_USERATTRIBUTES_STRING_NODE_NAME, q=True, text=True))

        if not len(object_name) > 0:
            self.showWarning('Nothing selected')
            return

        if not self.userAttributes_type_settings is None:
            for v in self.userAttributes_type_settings:
                cmds.deleteUI('userAttribute' + v['key'])

        self.userAttributes_type_settings = []

        if not object_name is None:
            attributes = cmds.listAttr(object_name, userDefined=True)

            if attributes is None:
                self.showWarning('No user attributes found!')
                return

            for name in attributes:
                key = ''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(5))
                object_key = object_name + "." + name
                type_name = cmds.getAttr(object_key, type=True)
                attribute_type = UI_MENU_USERATTRIBUTES[type_name]

                self.userAttributes_type_settings.append({'type': attribute_type, 'typeName': type_name, 'name': name, 'value': cmds.getAttr(object_key), 'key': key})

            self.updateUserAttributeUI()
        else:
            self.showWarning('Nothing selected')

    def updateObjectUserAttribute(self, unused):
        for v in self.userAttributes_type_settings:
            if v['type'] == TYPE_BOOL:
                updated_value = cmds.checkBox('userAttributeValue' + v['key'], q=True, v=True)
            elif v['type'] == TYPE_INT:
                updated_value = cmds.intField('userAttributeValue' + v['key'], q=True, v=True)
            elif v['type'] == TYPE_FLOAT:
                updated_value = cmds.floatField('userAttributeValue' + v['key'], q=True, v=True)
            else:
                updated_value = cmds.textField('userAttributeValue' + v['key'], q=True, text=True)

            v['value'] = updated_value

        self.saveObjectUserAttribute()

    def updateUserAttributeUI(self):
        attributes_layout = cmds.frameLayout(UI_CONTROL_LAYOUT_USERATTRIBUTES, edit=True)
        for v in self.userAttributes_type_settings:
            layout = cmds.rowLayout('userAttribute' + v['key'], columnWidth4=(TEXT_WIDTH, TEXT_WIDTH * 2, TEXT_WIDTH, 10), adjustableColumn=4, numberOfColumns=4,
                                    parent=attributes_layout)

            cmds.text(label=v['name'], width=TEXT_WIDTH, align='left', annotation='', parent=layout)

            # Switch display type
            if v['type'] == TYPE_BOOL:
                cmds.checkBox('userAttributeValue' + v['key'], label=v['name'], v=v['value'], width=TEXT_WIDTH * 2, parent=layout, annotation='', editable=True)
            elif v['type'] == TYPE_INT:
                cmds.intField('userAttributeValue' + v['key'], v=v['value'], editable=True, width=TEXT_WIDTH * 2, parent=layout)
            elif v['type'] == TYPE_FLOAT:
                cmds.floatField('userAttributeValue' + v['key'], v=v['value'], editable=True, width=TEXT_WIDTH * 2, parent=layout)
            else:
                cmds.textField('userAttributeValue' + v['key'], text=v['value'], width=TEXT_WIDTH * 2, editable=True, parent=layout)

            cmds.text(label=v['typeName'], width=200, annotation='', parent=layout)
            cmds.button('userAttributeDeleteButton', parent=layout, label='X', width=10, align='right', command=partial(self.deleteObjectUserAttribute, v['name']))

    def saveObjectUserAttributes(self, unused):
        object_name = cmds.textField(UI_CONTROL_USERATTRIBUTES_STRING_NODE_NAME, q=True, text=True)

        if not len(object_name) > 0:
            self.showWarning('Nothing selected')
            return

        name = cmds.textField(UI_OPTIONS_PREDEFINED_USERATTRIBUTE_NAME, q=True, text=True)
        type_name = cmds.optionMenu(UI_OPTIONS_PREDEFINED_USERATTRIBUTETYPES, q=True, value=True)

        if type_name == "bool":
            value = cmds.checkBox(UI_OPTIONS_PREDEFINED_USERATTRIBUTE_VALUE, q=True, v=True)
        elif type_name == "integer" or type_name == "long":
            value = cmds.intField(UI_OPTIONS_PREDEFINED_USERATTRIBUTE_VALUE, q=True, v=True)
        elif type_name == "float":
            value = cmds.floatField(UI_OPTIONS_PREDEFINED_USERATTRIBUTE_VALUE, q=True, v=True)
        else:
            value = cmds.textField(UI_OPTIONS_PREDEFINED_USERATTRIBUTE_VALUE, q=True, text=True)

        if not type_name is None and len(name) > 0:
            if not self.userAttributes_type_settings is None:
                for v in self.userAttributes_type_settings:
                    cmds.deleteUI('userAttribute' + v['key'])

            attribute_type = UI_MENU_USERATTRIBUTES[type_name]
            key = ''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(5))

            self.userAttributes_type_settings.append(
                {'type': attribute_type, 'typeName': type_name, 'name': name, 'value': value, 'key': key})

            self.saveObjectUserAttribute()
            self.updateUserAttributeUI()
            I3DUpdateLayers(str(object_name))
        else:
            self.showWarning('Not all fields are valid!')

    def saveObjectUserAttribute(self):
        object_name = str(cmds.textField(UI_CONTROL_USERATTRIBUTES_STRING_NODE_NAME, q=True, text=True))

        if not len(object_name) > 0:
            self.showWarning('Nothing selected')
            return

        for v in self.userAttributes_type_settings:
            if v['type'] == TYPE_BOOL:
                I3DSaveAttributeBool(object_name, v['name'], v['value'])
            elif v['type'] == TYPE_INT:
                I3DSaveAttributeInt(object_name, v['name'], v['value'])
            elif v['type'] == TYPE_FLOAT:
                I3DSaveAttributeFloat(object_name, v['name'], v['value'])
            elif v['type'] == TYPE_STRING or v['type'] == TYPE_SCRIPTCALLBACK:
                I3DSaveAttributeString(object_name, v['name'], v['value'])

    def onChangeUserAttributeType(self, selected):
        if not selected is None:
            # Delete current UI and redraw
            if cmds.rowLayout(UI_OPTIONS_PREDEFINED_USERATTRIBUTE_NAME + "layout", exists=True):
                cmds.deleteUI(UI_OPTIONS_PREDEFINED_USERATTRIBUTE_NAME + "layout")

            if cmds.rowLayout(UI_OPTIONS_PREDEFINED_USERATTRIBUTE_VALUE + "layout", exists=True):
                cmds.deleteUI(UI_OPTIONS_PREDEFINED_USERATTRIBUTE_VALUE + "layout")

            if cmds.button(UI_CONTROL_BUTTON_USERATTRIBUTES_ADD_ATTRIBUTE, exists=True):
                cmds.deleteUI(UI_CONTROL_BUTTON_USERATTRIBUTES_ADD_ATTRIBUTE)

            attribute_layout = cmds.frameLayout(UI_CONTROL_LAYOUT_USERATTRIBUTES_ADD_ATTRIBUTE, label='Add new attribute', w=390, edit=True, cll=True, mh=2, mw=2)

            self.addTextFieldElement(attribute_layout, 'Name', UI_OPTIONS_PREDEFINED_USERATTRIBUTE_NAME, '', '', editable=True, width=245)

            layout_value = cmds.rowLayout(UI_OPTIONS_PREDEFINED_USERATTRIBUTE_VALUE + "layout", adjustableColumn=2, numberOfColumns=2, parent=attribute_layout)
            cmds.text(UI_OPTIONS_PREDEFINED_USERATTRIBUTE_VALUE + "label", label='Value', width=TEXT_WIDTH, align='left', annotation='', parent=layout_value)

            if selected == "bool":
                cmds.checkBox(UI_OPTIONS_PREDEFINED_USERATTRIBUTE_VALUE, label="", width=245, parent=layout_value, annotation='', editable=True)
            elif selected == "integer" or selected == "long":
                cmds.intField(UI_OPTIONS_PREDEFINED_USERATTRIBUTE_VALUE, editable=True, value=0, width=245, parent=layout_value)
            elif selected == "float":
                cmds.floatField(UI_OPTIONS_PREDEFINED_USERATTRIBUTE_VALUE, editable=True, value=0, width=245, parent=layout_value)
            else:
                cmds.textField(UI_OPTIONS_PREDEFINED_USERATTRIBUTE_VALUE, width=245, editable=True, parent=layout_value)

            cmds.button(UI_CONTROL_BUTTON_USERATTRIBUTES_ADD_ATTRIBUTE, parent=attribute_layout, label='Add', width=126, align='right', command=self.saveObjectUserAttributes)

    def deleteObjectUserAttribute(self, name, unused):
        object_name = str(cmds.textField(UI_CONTROL_USERATTRIBUTES_STRING_NODE_NAME, q=True, text=True))
        object_key = object_name + "." + name

        if I3DAttributeExists(object_name, name):
            cmds.deleteAttr(object_key)

        self.loadObjectUserAttribute(None)

    def addTextFieldElement(self, parent, label, textFieldName, defaultValue='', annotation='', editable=True,
                            width=DEFAULT_FIELD_WIDTH):
        layout = cmds.rowLayout(textFieldName + 'layout', parent=parent, adjustableColumn=2, numberOfColumns=2)
        cmds.text(parent=layout, label=label, width=TEXT_WIDTH, align='left', annotation=annotation)
        cmds.textField(textFieldName, parent=layout, text=defaultValue, annotation=annotation, editable=editable,
                       width=width)

try:
    if not main is None:
        main.delete()
except NameError as e:
    pass

main = UserAttributes()


import os

class BFF_Reader():
	'''
	This class is used to read the BFF file and extract the useful information
	including grid, lasers, and points.

	To use this function, change the file_path to the absolute path of lasor BFF file.
	'''

	def __init__(self, file_path):
		self.file_path = file_path
		self.grid = []
		self.blocks = {}
		self.lasers = []
		self.points = []

	def read_file(self):
		'''
		This function will read in the lazor board BFF file.
		The BFF file will contain information about the lazor board.

			**Parameters**
				file_path: *str*
					The file path to be read in.

			**Returns**
				open(self.file_path, "r").read(): *str*
				The relative board information inside the file, including the shape of the grid,
				numbers and types of the blocks, location and direction of all the laser points,
				location of all the final points.
		'''
		return open(self.file_path, "r").readlines()

	def get_grid(self):
		'''
		The function can extract the information about the grid from board_data, and transfer it into a
		list of matrix.
		The way to realize it is to go through each line of the board_data, and if the first character of
		the line is string 'o' or 'x', then this line is a part of the grid.

			**Returns**
				self.grid: *list*
					Grid information where lines are in different lists,
					and rows are separated by commas.
		'''
		board_data = self.read_file()
		for i in range(len(board_data)):
			if board_data[i] == 'GRID START\n':
				for j in range(1, len(board_data)):
					if board_data[i+j] == 'GRID STOP\n':
						break
					self.grid.append(board_data[i+j].strip('\n').strip('').split())
				break

		return self.grid

	def get_blocks(self):
		'''
		The function can extract the information about the blocks from board_data.
		The way to realize it is to go through each line of the board_data, and if the first character of
		the line is string 'A' or 'B' or 'C', then this line is a part of the blocks information.

		**Parameters**
			board_data: *str*
				Information about the lazor board. The return of the load_file function.

		**Returns**
			self.blocks *list*
				Information of block type and the number for each type.
		'''
		after_grids = ''.join(self.read_file()).split('\nGRID STOP')
		after_grids = after_grids[1]
		lines = after_grids.split('\n')
		Block_list = []

		for i in range(len(lines)):
			if lines[i].startswith(str('A')) or\
		 	   lines[i].startswith(str('B')) or\
		 	   lines[i].startswith(str('C')):
		 		Block_line = lines[i].strip('\n').split()
		 		Block_list.append(Block_line)
		for j in range(len(Block_list)):
			self.blocks[Block_list[j][0]] = int(Block_list[j][1])

		return self.blocks

	def get_lasers(self):
		'''
		The function can extract the information about the lasers from board_data.
		The way to realize it is to go through each line of the board_data, and if the first character of
		the line is string 'L', then this line is a part of the laser.

		**Returns**
			self.lasers: *list*
				laser information including x,y values and laser direction.
				For each laser(sublist), the starting point is in the first tuple
				and the direction is in the second tuple.
		'''
		laser_list = []

		for i in range(len(self.read_file())):
			if self.read_file()[i].startswith(str('L')):
				lines = self.read_file()[i].strip('\n')
				laser_list.append(lines.split())

		for num in laser_list:
			start_point = tuple([int(num[1]), int(num[2])])
			direction = tuple([int(num[3]), int(num[4])])
			self.lasers.append([start_point, direction])

		return self.lasers

	def get_points(self):
		'''
		The function can extract the information about the final points from board_data.
		The way to realize it is to go through each line of the board_data, and if the first character of
		the line is string 'P', then this line is a part of the blocks information.

		**Returns**
			self.points: *list*
				Points information including x,y values as a tuple.
		'''
		point_list = []

		for i in range(len(self.read_file())):
			if self.read_file()[i].startswith(str('P')):
				lines = self.read_file()[i].strip('\n')
				point_list.append(lines.split())

		for num in point_list:
			position = tuple([int(num[1]), int(num[2])])
			self.points.append(position)

		return self.points

	def save_as_TXT(self):
		'''
		This code is used to read the BFF file and save the content into
		a .txt file under the same directory of the path.

		**Returns**
			A .txt file under the same director of the path with the same name of BFFfile.
		'''
		File = os.path.basename(self.file_path)
		file_name = os.path.splitext(File)[0]
		txt_path = os.path.dirname(self.file_path)
		txt_file = open("%s/" % txt_path + file_name + ".txt", "w")
		txt_file.write(''.join(map(str, self.read_file())))
		txt_file.close()

if __name__ == '__main__':
	BR = BFF_Reader("tiny_5.bff")
	# print(BR.read_file())
	print("Grid is", BR.get_grid())
	print("Blocks are", BR.get_blocks())
	print("Lasers are", BR.get_lasers())
	print("Points are", BR.get_points())
	#BR.save_as_TXT()


import sys
import os
from sys import stdin

stdin = open(os.path.dirname(__file__) + '/input.txt')  # local test
input = stdin.readline
sys.setrecursionlimit(20000000)

n, k = list(map(int, input().split()))
weights = list(map(int, input().split()))
weights += [0] * (k + 3)

dp = [9999999999] * (n + k + 3)
dp[0] = 0

for i in range(n - 1):
    current = weights[i]
    for step in range(1, k + 1):
        cost = abs(current - weights[i + step])
        dp[i + step] = min(dp[i + step], dp[i] + cost)

print(dp[n - 1])


import logging
from utils import *
from forex.candle.candle import Candle
from config import CONFIG

# create logger
p_logger = logging.getLogger(__name__)
p_logger.setLevel(logging.INFO)

class Pivot(object):
    """
    Class that represents a single Pivot as identified
    by the Zigzag indicator

    Class variables
    ---------------
    type : int, Required
           Type of pivot. It can be 1 or -1
    candle : Dict
             Candle representing the pivot
    pre : Segment object
          Segment object before this pivot
    aft : Segment object
          Segment object after this pivot
    score : int
            Result of adding the number
            of candles of the 'pre' and 'aft' segment (if defined). Optional
    """

    def __init__(self, type, candle, pre, aft,
                 score=None):
        self.type = type
        self.candle = candle
        self.pre = pre
        self.aft = aft
        self.score = score

    def merge_pre(self, slist, n_candles, diff_th):
        """
        Function to merge 'pre' Segment. It will merge self.pre with previous segment
        if self.pre and previous segment are of the same type (1 or -1) or count of
        previous segment is less than CONFIG.getint('pivots', 'n_candles')

        Parameters
        ----------
        slist : SegmentList object
                SegmentList for PivotList of this Pivot.
                Required
        n_candles : int
                    Skip merge if Segment is greater than 'n_candles'
        diff_th : int
                  % of diff in pips threshold

        Returns
        -------
        Nothing
        """
        p_logger.debug("Running merge_pre")
        p_logger.debug("Analysis of pivot {0}".format(self.candle['time']))
        p_logger.debug("self.pre start pre-merge: {0}".format(self.pre.start()))

        extension_needed = True # if extension_needed is False then no further attempts of extending this self.pre
                                # will be tried
        while extension_needed is True:
            # reduce start of self.pre by one candle in order to retrieve the previous segment
            # by its end
            start_dt = self.pre.start() - periodToDelta(1, self.candle['granularity'])

            # fetch previous segment
            s = None
            if CONFIG.has_option('pivots', 'max_diff'):
                s = slist.fetch_by_end(start_dt, max_diff=0)
            else:
                s = slist.fetch_by_end(start_dt)

            if s is None:
                # This is not necessarily an error, it could be that there is not the required Segment in slist
                # because it is out of the time period
                p_logger.info("No Segment could be retrieved for pivot falling in time {0} "
                              "by using s.fetch_by_end and date: {1} in function 'merge_pre'".format(self.candle['time'],
                                                                                start_dt))
                extension_needed = False
                continue
            if self.pre.type == s.type:
                # merge if type of previous (s) is equal to self.pre
                p_logger.debug("Merge because of same Segment type")
                self.pre = self.pre.prepend(s)
            elif self.pre.type != s.type and s.count < n_candles:
                # merge if types of previous (s) and self.pre are different but
                # s.count is less than CONFIG.getint('pivots', 'n_candles')
                # calculate the % that s.diff is with respect to self.pre.diff
                perc_diff = s.diff*100/self.pre.diff
                # do not merge if perc_diff that s represents with respect
                # to s.pre is > than the defined threshold
                if perc_diff < diff_th:
                    p_logger.debug("Merge because of s.count < n_candles")
                    self.pre = self.pre.prepend(s)
                else:
                    p_logger.debug("Skipping merge because of %_diff")
                    extension_needed = False
            else:
                # exit the while loop, as type of previous (s) and self.pre are different
                # and s.count is greater than CONFIG.getint('pivots', 'n_candles')
                extension_needed = False

        p_logger.debug("self.pre start after-merge: {0}".format(self.pre.start()))
        p_logger.debug("Done merge_pre")

    def merge_aft(self, slist, n_candles, diff_th):
        """
        Function to merge 'aft' Segment. It will merge self.aft with next segment
        if self.aft and next segment are of the same type (1 or -1) or count of
        next segment is less than 'n_candles'

        Parameters
        ----------
        slist : SegmentList object
                SegmentList for PivotList of this Pivot.
                Required
        n_candles : int
                    Skip merge if Segment is greater than 'n_candles'
        diff_th : int
                  % of diff in pips threshold

        Returns
        -------
        Nothing
        """

        p_logger.debug("Running merge_aft")
        p_logger.debug("Analysis of pivot {0}".format(self.candle['time']))
        p_logger.debug("self.aft end before the merge: {0}".format(self.aft.end()))

        extension_needed = True
        while extension_needed is True:
            # increase end of self.aft by one candle
            start_dt = self.aft.end()+periodToDelta(1, self.candle['granularity'])

            # fetch next segment
            s = None
            if CONFIG.has_option('pivots', 'max_diff'):
                s = slist.fetch_by_start(start_dt, max_diff=0)
            else:
                s = slist.fetch_by_start(start_dt)
            if s is None:
                # This is not necessarily an error, it could be that there is not the required Segment in slist
                # because it is out of the time period
                p_logger.info("No Segment could be retrieved for pivot falling in time {0} by using s.fetch_by_"
                              "start and date: {1} in function 'merge_aft'. ".format(self.candle['time'], start_dt))
                extension_needed = False
                continue

            if self.aft.type == s.type:
                p_logger.debug("Merge because of same Segment type")
                # merge
                self.aft = self.aft.append(s)
            elif self.aft.type != s.type and s.count < n_candles:
                # calculate the % that s.diff is with respect to self.pre.diff
                perc_diff = s.diff * 100 / self.aft.diff
                # do not merge if perc_diff that s represents with respect
                # to s.aft is > than the defined threshold
                if perc_diff < diff_th:
                    p_logger.debug("Merge because of s.count < n_candles")
                    self.aft = self.aft.append(s)
                else:
                    p_logger.debug("Skipping merge because of %_diff")
                    extension_needed = False
            else:
                extension_needed = False

        p_logger.debug("self.aft end after-merge: {0}".format(self.aft.end()))
        p_logger.debug("Done merge_aft")

    def calc_score(self, type='diff'):
        """
        Function to calculate the score for this Pivot
        The score will be the result of adding the 'diff'
        values or adding the number of candles of the 'pre' and 'aft'
        segments (if defined)

        Parameters
        ----------
        type : Type of score that will be
               calculated. Possible values: 'diff' , 'candles'
               Default: 'diff'

        Returns
        -------
        int /float with the score of this pivot.
                   It will also set the score class attribute
        """

        if self.pre:
            score_pre = 0
            if type == 'diff':
                score_pre = self.pre.diff
            elif type == 'candles':
                score_pre = self.pre.count
        else:
            score_pre = 0

        if self.aft:
            score_aft = 0
            if type == 'diff':
                score_aft = self.aft.diff
            elif type == 'candles':
                score_aft = self.aft.count
        else:
            score_aft = 0

        self.score = score_pre+score_aft

        return score_pre+score_aft

    def adjust_pivottime(self, clistO):
        '''
        Function to adjust the pivot time
        This is necessary as sometimes the Zigzag algorithm
        does not find the correct pivot

        Parameters
        ----------
        clistO : CandleList object used to identify the
                PivotList, Required
        Returns
        -------
        New adjusted datetime
        '''
        clist = clistO.data['candles'][:-1] # reduce index by 1 so start candle+1 is not included
        new_pc = pre_colour = None
        it = True
        ix = -1
        while it is True:
            c_dict = clist[ix]
            c = Candle(dict_data=c_dict)
            c.set_candle_features()
            if c.colour == "undefined":
                it = False
                new_pc = c
                continue
            if pre_colour is None:
                pre_colour = c.colour
                ix -= 1
            elif c.colour == pre_colour:
                ix -= 1
                continue
            else:
                # change in candle colour
                new_pc = c
                it = False
        return new_pc.time

    def __repr__(self):
        return "Pivot"

    def __str__(self):
        out_str = ""
        for attr, value in self.__dict__.items():
            out_str += "%s:%s " % (attr, value)
        return out_str


#!/usr/bin/env python
# -*- coding: utf-8 -*-
import unittest
import sys
from nose.tools import *
from kpi.antennaOffsetFilesDecoderModule.antennaOffsetParser import AntennaOffsetParser

class testAntennaOffsetParser(unittest.TestCase):

    def setUp(self):
        """
        setup call, runs before each test
        """

        self.confiFile = "test/resources/Configuration.cfg"
        self.classToTest = AntennaOffsetParser()
        self.resourcePathTest = "test/resources/antennaOffsetParserModule/"
        self.prnIdList = ["E08", "E09", "E11", "E12",
                          "E14", "E18", "E19", "E20",
                          "E22", "E24", "E26", "E30", "E51", "E52"]
        self.prnIdTempList = ["E08"]
        self.prnIdListNotExist = ["AAA"]
        self.timeTagCal = ["2016 05 01 15 05 0", "2016 05 02 0 0 0",
                           "2016 05 03 15 05 0", "2016 05 04 15 05 0",
                           "2016 05 05 15 05 0", "2016 05 06 15 05 0",
                           "2016 05 07 15 05 0", "2016 05 08 15 05 0",
                           "2016 05 09 15 05 0", "2016 05 10 15 05 0",
                           "2016 05 11 15 05 0", "2016 05 12 15 05 0",
                           "2016 05 13 15 05 0", "2016 05 14 15 05 0",
                           "2016 05 15 15 05 0", "2016 05 16 15 05 0",
                           "2016 05 17 15 05 0"]
        self.apcOffRefFile = self.resourcePathTest + "test_igs08_1887.atx"
        self.apcOffBceFile = self.resourcePathTest + "test_igs08_1887_bce.atx"
        self.apcTypeTagNotExist = self.resourcePathTest + \
            "test_format_exp_type_tag_Not_exist.atx"
        self.apcNumFreqTag = self.resourcePathTest + \
            "test_format_exp_num_freq_notExist.atx"
        self.apcOffRefFileNotExist = (self.resourcePathTest +
                                      "test_igs08_1887_notexist.atx")
        self.apcGregoruanFormatTest = self.resourcePathTest + \
            "test_gregorian_format.atx"

    def testApcDataExtractor(self):
        """
        Test for single PRN with all timetagcals
        The result should return pro PNR pro timetagcal

        Test with single Data (prnIdTempList = ["E08"])
        """
        apc_nav, apc_pro = self.classToTest.antennaOffsetParser(
            self.apcOffRefFile, self.apcOffBceFile)
        apcOffRef, apcOffBce = self.classToTest.apcDataExtractor(
            apc_nav, apc_pro, self.timeTagCal, self.prnIdTempList)
        assert len(apcOffRef) == len(self.timeTagCal) * \
            len(self.prnIdTempList)
        assert len(apcOffBce) == len(self.timeTagCal) * \
            len(self.prnIdTempList)

    def testApcDataExtractorListPrn(self):
        """
        Test for single PRN with all timetagcals
        The result should return pro PNR pro timetagcal

        Test with List Data (prnIdList = ["E08"])
        """
        apc_nav, apc_pro = self.classToTest.antennaOffsetParser(
            self.apcOffRefFile, self.apcOffBceFile)
        apcOffRef, apcOffBce = self.classToTest.apcDataExtractor(
            apc_nav, apc_pro, self.timeTagCal, self.prnIdList)
        assert len(apcOffRef) == len(self.timeTagCal) * \
            len(self.prnIdList)
        assert len(apcOffBce) == len(self.timeTagCal) * \
            len(self.prnIdList)

    def testApcDataExtractorNonExistingPrn(self):
        """
        Test for single PRN with all timetagcals
        The result should return pro PNR pro timetagcal

        Test with invalid Data (prnIdList = ["AAA"])
        """
        apc_nav, apc_pro = self.classToTest.antennaOffsetParser(
            self.apcOffRefFile, self.apcOffBceFile)
        apcOffRef, apcOffBce = self.classToTest.apcDataExtractor(
            apc_nav, apc_pro, self.timeTagCal, self.prnIdListNotExist)
        assert len(apcOffRef) == len(self.timeTagCal) * \
            len(self.prnIdListNotExist)
        assert len(apcOffBce) == len(self.timeTagCal) * \
            len(self.prnIdListNotExist)

    def testAntennaOffsetParserFunction(self):
        # Test parsing of files and list output
        apc_nav, apc_pro = self.classToTest.antennaOffsetParser(
            self.apcOffRefFile, self.apcOffBceFile)
        assert len(apc_pro) > 1
        assert len(apc_nav) > 1

    @raises(Exception)
    def testFileNotExist(self):
        """
        Raises Exception if file is not found
        """
        apcPro, apcNav = self.classToTest.antennaOffsetParser(
            self.apcOffRefFileNotExist, self.apcOffBceFile)

    @raises(Exception)
    def testFormatExceptionNumFreqTag(self):
        # Test type tag after start antenna tag
        apc_nav, apc_pro = self.classToTest.antennaOffsetParser(
            self.apcNumFreqTag, self.apcOffBceFile)

    @raises(Exception)
    def testValidFromTagNotExist(self):
        # Test parsing of files and list output
        apc_nav, apc_pro = self.classToTest.antennaOffsetParser(
            self.apcTypeTagNotExist, self.apcOffBceFile)

    @raises(Exception)
    def testGregorianFormat(self):
        # Test if there are 6 calender elements in Date
        self.classToTest.antennaOffsetParser(
            self.apcGregoruanFormatTest, self.apcOffBceFile)

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


#1
'''Возьмите задачу 1
Создайте класс наследник Market
Создайте конструктор с аргументами material, color, number (def 0), price (def 0)
Величины, которые присутствуют в Market, не должны быть заданы в Market через self
Создайте объект для красного дерева с количеством 10 и ценой 1500
Напечатайте переменные объекта, в том числе те, которые заданы в классе Building '''

class Building:

    def __init__(self, material, color, number):
        self.material = material
        self.color = color
        self.number = number

    def calc(self):
        if self.number <= 0:
            print("out of stock")
        elif 0 < self.number < 100:
            print("warehouse")
        else:
            print("Remote warehouse")

class Market(Building):

    def __init__(self, material, color, number=0, price=0):
        self.price = price
        Building.__init__(self, material, color, number)
        super().__init__(material, color, number)

board = Market('board', 'brown', 10, 50)
print(board.price)

#2
'''Фабричный метод:
Создать класс Document и его наследники: ODFDocument, MSOfficeDocument.
В каждом из них должен быть реализован метод show(), который печатает название программы,
которая должна открывать тип документа.
Создать класс, который в зависимости от типа документа, вызывает метод show().
например, для 'odf' - печатается, что этот файл открывается с помощью OpenOffice,
для 'doc' - MSOffice.'''

class Document:
    def factory(self, type):
        if type == "odf":
            return ODFDocument()
        elif type == "doc":
            return MSOfficeDocument()

class ODFDocument(Document):
    def show(self):
        print('Файл открывается с помощью OpenOffice')

class MSOfficeDocument(Document):
    def show(self):
        print('Файл открывается с помощью MSOffice')

d = Document().factory('odf')
d.show()

#d = Document()
#c = d.factory('doc')
#c.show()


from flask import request
from app.v2.models.parties_model import Party
from app.v2.util.validate import response, not_admin, response_error
from app.v2.blueprints import bp
from flask_jwt_extended import (jwt_required)
from app.v2.util.jwt_utils import admin_required

@bp.route('/parties', methods=['POST', 'GET'])
@jwt_required
def create_party():
    if request.method == 'POST':
        """ Create party end point """

        restricted = not_admin()
        if restricted:
            return restricted

        data = request.get_json()

        if not data:
            return response("No data was provided", 400)

        try:
            name = data['name']
            hqaddress = data['hqaddress']
        except KeyError as e:
            return response("{} field is required".format(e.args[0]), 400)

        party = Party(name, hqaddress)

        if not party.validate_object():
            return response(party.error_message, party.error_code)

        party.save()

        # return added party
        return response("Your political party was created successfully",
                        201, [party.as_json()])

    elif request.method == 'GET':
        """ Get all parties end point """
        model = Party()
        return response('Success', 200, model.load_all())

@bp.route('/parties/<int:id>', methods=['GET', 'DELETE'])
@jwt_required
def get_party(id):

    model = Party()
    data = model.find_by('id', id)

    if not data:
        return response('Party not found', 404)

    if request.method == 'GET':
        return response('Request was successful', 200, [data])
    else:
        restricted = not_admin()
        if restricted:
            return restricted
        party = model.from_json(data)
        party.delete(party.id)
        return response(
            '{} deleted successfully'.format(party.name), 200, [data])

@bp.route('/parties/<int:id>/name', methods=['PATCH'])
@admin_required
def edit_party(id):

    data = request.get_json()

    if not data:
        return response_error("No data was provided", 400)

    try:
        name = data['name']
    except KeyError as e:
        return response_error(
            "{} field is required".format(e.args[0]), 400)

    model = Party()
    data = model.find_by('id', id)

    if not data:
        return response('Party not found', 404)

    party = model.from_json(data)
    party.name = name

    if not party.validate_object():
        return response(party.error_message, party.error_code)

    party.edit(name)

    return response(
        '{} updated successfully'.format(party.name), 200, [data])


#calss header
class _IMBIBE():
	def __init__(self,):
		self.name = "IMBIBE"
		self.definitions = [u'to drink, especially alcohol: ', u'to receive and accept information, etc.']

		self.parents = []
		self.childen = []
		self.properties = []
		self.jsondata = {}

		self.specie = 'verbs'

	def run(self, obj1 = [], obj2 = []):
		return self.jsondata


# Course: CS261 - Data Structures
# Assignment: 5
# Student: Srikanth Medicherla
# Description: Part 1. Hash Map Implementation. This file has several functions including empty buckets, table_load,
# clear, put, contains_key, get, remove, resize_table, and get_keys. With these functions we can access the hash table
# as well as the chained single linked lists. We can do the above functions to them.

# Import pre-written DynamicArray and LinkedList classes
from a5_include import *

def hash_function_1(key: str) -> int:
    """
    Sample Hash function #1 to be used with A5 HashMap implementation
    DO NOT CHANGE THIS FUNCTION IN ANY WAY
    """
    hash = 0
    for letter in key:
        hash += ord(letter)
    return hash

def hash_function_2(key: str) -> int:
    """
    Sample Hash function #2 to be used with A5 HashMap implementation
    DO NOT CHANGE THIS FUNCTION IN ANY WAY
    """
    hash, index = 0, 0
    index = 0
    for letter in key:
        hash += (index + 1) * ord(letter)
        index += 1
    return hash

class HashMap:
    def __init__(self, capacity: int, function) -> None:
        """
        Init new HashMap based on DA with SLL for collision resolution
        DO NOT CHANGE THIS METHOD IN ANY WAY
        """
        self.buckets = DynamicArray()
        for _ in range(capacity):
            self.buckets.append(LinkedList())
        self.capacity = capacity
        self.hash_function = function
        self.size = 0

    def __str__(self) -> str:
        """
        Return content of hash map t in human-readable form
        DO NOT CHANGE THIS METHOD IN ANY WAY
        """
        out = ''
        for i in range(self.buckets.length()):
            list = self.buckets.get_at_index(i)
            out += str(i) + ': ' + str(list) + '\n'
        return out

    def clear(self) -> None:
        """
        This method clears the contents of the hash map. It doesn't change the underlying hash table capacity
        """
        for i in range(self.buckets.length()):
            self.buckets.set_at_index(i, LinkedList())
        self.size = 0

    def get(self, key: str) -> object:
        """
        This method returns the value associated with the given key. If the key is not in the hash map, the method
        returns None.
        """
        # First we compute the element's bucket using the hash function
        value = self.hash_function(key)
        bucket = value % self.capacity

        # Finds the data value in the Hash Table using the value's index/bucket:
        index_value = self.buckets.get_at_index(bucket)

        # We search the data structure by iterating using contains LinkedList method to see if the key matches a value:

        # If there is no match, we return None:
        if index_value.contains(key) is None:
            return None

        # If value is a match, we return the value of the SLNode:
        if index_value.contains(key) is not None:
            slnode_pointer = index_value.contains(key)
            return slnode_pointer.value

    def put(self, key: str, value: object) -> None:
        """
        This method updates the key: value pair in the hash map. If a given key already exists inside, it's value will
        be updated to the new value. If the key is not in the hash map, the key/value pair will be added there.
        """
        # First we compute the element's bucket using the hash function
        hash_num = self.hash_function(key)
        bucket = hash_num % self.capacity

        # Finds the data value in the Hash Table using the value's index/bucket:
        index_value = self.buckets.get_at_index(bucket)

        # We search the data structure by iterating using contains LinkedList method to see if the key matches a value:

        # If there is a match, we remove the key and update it with the new key/value pair:
        if index_value.contains(key) is not None:
            index_value.remove(key)
            index_value.insert(key, value)

        # if no match, we insert the key/value pair:
        if index_value.contains(key) is None:
            index_value.insert(key, value)
            self.size = self.size + 1

    def remove(self, key: str) -> None:
        """
        This method removes the given key and it's associated value from the hash map. If the given key is not in the
        hash map, the method does nothing.
        """
        # First we compute the element's bucket using the hash function
        hash_num = self.hash_function(key)
        bucket = hash_num % self.capacity

        # Finds the data value in the Hash Table using the value's index/bucket:
        index_value = self.buckets.get_at_index(bucket)

        # We search the data structure by iterating using contains LinkedList method to see if the key matches a value:
        if index_value.contains(key) is None:
            return

        # if it matches, we remove it using the LinkedList's remove method
        index_value.remove(key)
        self.size -= 1

    def contains_key(self, key: str) -> bool:
        """
        This method returns True if the given key is in the hash map. If it isn't, it returns False. An empty hash
        map does not contain any keys.
        """
        # First we compute the element's bucket using the hash function
        hash_num = self.hash_function(key)
        bucket = hash_num % self.capacity

        # Finds the data value in the Hash Table using the value's index/bucket:
        index_value = self.buckets.get_at_index(bucket)

        # Search the data structure at this bucket's value using the key

        # if it is found, we return True:
        if index_value.contains(key) is not None:
            return True

        # if not found, we return False:
        if index_value.contains(key) is None:
            return False

    def empty_buckets(self) -> int:
        """
        This method will return the number of empty buckets in the hash table.
        """
        num = 0
        # Based on the self.capacity, we will find the value in the hash table and then see the length of each list.
        for i in range(self.capacity):
            value = self.buckets.get_at_index(i)
            if value.length() == 0:
                # if length() for each list is 0, we increment num:
                num += 1
        return num

    def table_load(self) -> float:
        """
        This method returns the current hash table's load factor
        """
        # self.size is the total number of elements stored in the table
        n = self.size

        # self.capacity is the number of buckers
        m = self.capacity

        # load factor is calculated by n/m:
        table_load = n/m

        return table_load

    def resize_table(self, new_capacity: int) -> None:
        """
        This method changes the capacity of the internal hash table. All existing key/value pairs will remain in the new
        hash map and all the hash table links must be rehashed. If the new_capacity is less than 1, this method should
        do nothing.
        """

        if new_capacity < 1:
            return

        # We make a new DynamicArray, then we append LinkedList() int(new_capacity) times so it can hold new_capacity.
        new_array = DynamicArray()
        for i in range(new_capacity):
            new_array.append(LinkedList())

        # We create a temp LinkedList which can store all the values. After, transfer them to the new dynamic array
        temp = LinkedList()

        # we pop the self.buckets and add the key/value object to our new temp.
        while self.buckets.length() > 0:
            value = self.buckets.pop()
            for j in value:
                temp.insert(j.key, j.value)

        # We change the private data members so that we can create a new dynamic array from scratch correctly:
        self.capacity = new_capacity
        self.buckets = new_array
        self.size = 0

        # We add the objects from our temp LinkedList into our dynamic array using self.put.
        for item in temp:
            self.put(item.key, item.value)

    def get_keys(self) -> DynamicArray:
        """
        This method returns a DynamicArray that contains all the keys stored in your hash map. The order of the keys
        in the DA will not be in any order.
        """
        # We simply pop the SLNode which we can directly access. We grab the key and append it to new array.
        new_array = DynamicArray()
        new_array2 = DynamicArray()
        while self.buckets.length() > 0:
            value = self.buckets.pop()
            new_array2.append(value)
            for i in value:
                new_array.append(i.key)
        # We rebuild the self.buckets so further calls to get_keys() can work properly.
        self.buckets = new_array2
        return new_array

# BASIC TESTING
if __name__ == "__main__":

    print("\nPDF - empty_buckets example 1")
    print("-----------------------------")
    m = HashMap(100, hash_function_1)
    print(m.empty_buckets(), m.size, m.capacity)
    m.put('key1', 10)
    print(m.empty_buckets(), m.size, m.capacity)
    m.put('key2', 20)
    print(m.empty_buckets(), m.size, m.capacity)
    m.put('key1', 30)
    print(m.empty_buckets(), m.size, m.capacity)
    m.put('key4', 40)
    print(m.empty_buckets(), m.size, m.capacity)

    print("\nPDF - empty_buckets example 2")
    print("-----------------------------")
    m = HashMap(50, hash_function_1)
    for i in range(150):
        m.put('key' + str(i), i * 100)
        if i % 30 == 0:
            print(m.empty_buckets(), m.size, m.capacity)

    print("\nPDF - table_load example 1")
    print("--------------------------")
    m = HashMap(100, hash_function_2)
    print(m.table_load())
    m.put('key1', 10)
    print(m.table_load())
    m.put('key2', 20)
    print(m.table_load())
    m.put('key1', 30)
    print(m.table_load())

    print("\nPDF - table_load example 2")
    print("--------------------------")
    m = HashMap(50, hash_function_2)
    for i in range(50):
        m.put('key' + str(i), i * 100)
        if i % 10 == 0:
            print(m.table_load(), m.size, m.capacity)

    print("\nPDF - clear example 1")
    print("---------------------")
    m = HashMap(100, hash_function_1)
    print(m.size, m.capacity)
    m.put('key1', 10)
    m.put('key2', 20)
    m.put('key1', 30)
    print(m.size, m.capacity)
    m.clear()
    print(m.size, m.capacity)

    print("\nPDF - clear example 2")
    print("---------------------")
    m = HashMap(50, hash_function_1)
    print(m.size, m.capacity)
    m.put('key1', 10)
    print(m.size, m.capacity)
    m.put('key2', 20)
    print(m.size, m.capacity)
    m.resize_table(100)
    print(m.size, m.capacity)
    m.clear()
    print(m.size, m.capacity)

    print("\nPDF - put example 1")
    print("-------------------")
    m = HashMap(50, hash_function_1)
    for i in range(150):
        m.put('str' + str(i), i * 100)
        if i % 25 == 24:
            print(m.empty_buckets(), m.table_load(), m.size, m.capacity)

    print("\nPDF - put example 2")
    print("-------------------")
    m = HashMap(40, hash_function_2)
    for i in range(50):
        m.put('str' + str(i // 3), i * 100)
        if i % 10 == 9:
            print(m.empty_buckets(), m.table_load(), m.size, m.capacity)

    print("\nPDF - contains_key example 1")
    print("----------------------------")
    m = HashMap(10, hash_function_1)
    print(m.contains_key('key1'))
    m.put('key1', 10)
    m.put('key2', 20)
    m.put('key3', 30)
    print(m.contains_key('key1'))
    print(m.contains_key('key4'))
    print(m.contains_key('key2'))
    print(m.contains_key('key3'))
    m.remove('key3')
    print(m.contains_key('key3'))

    print("\nPDF - contains_key example 2")
    print("----------------------------")
    m = HashMap(75, hash_function_2)
    keys = [i for i in range(1, 1000, 20)]
    for key in keys:
        m.put(str(key), key * 42)
    print(m.size, m.capacity)
    result = True
    for key in keys:
        # all inserted keys must be present
        result &= m.contains_key(str(key))
        # NOT inserted keys must be absent
        result &= not m.contains_key(str(key + 1))
    print(result)

    print("\nPDF - get example 1")
    print("-------------------")
    m = HashMap(30, hash_function_1)
    print(m.get('key'))
    m.put('key1', 10)
    print(m.get('key1'))

    print("\nPDF - get example 2")
    print("-------------------")
    m = HashMap(150, hash_function_2)
    for i in range(200, 300, 7):
        m.put(str(i), i * 10)
    print(m.size, m.capacity)
    for i in range(200, 300, 21):
        print(i, m.get(str(i)), m.get(str(i)) == i * 10)
        print(i + 1, m.get(str(i + 1)), m.get(str(i + 1)) == (i + 1) * 10)

    print("\nPDF - remove example 1")
    print("----------------------")
    m = HashMap(50, hash_function_1)
    print(m.get('key1'))
    m.put('key1', 10)
    print(m.get('key1'))
    m.remove('key1')
    print(m.get('key1'))
    m.remove('key4')

    print("\nPDF - resize example 1")
    print("----------------------")
    m = HashMap(20, hash_function_1)
    m.put('key1', 10)
    print(m.size, m.capacity, m.get('key1'), m.contains_key('key1'))
    m.resize_table(30)
    print(m.size, m.capacity, m.get('key1'), m.contains_key('key1'))

    print("\nPDF - resize example 2")
    print("----------------------")
    m = HashMap(75, hash_function_2)
    keys = [i for i in range(1, 1000, 13)]
    for key in keys:
        m.put(str(key), key * 42)
    print(m.size, m.capacity)

    for capacity in range(111, 1000, 117):
        m.resize_table(capacity)

        m.put('some key', 'some value')
        result = m.contains_key('some key')
        m.remove('some key')

        for key in keys:
            result &= m.contains_key(str(key))
            result &= not m.contains_key(str(key + 1))
        print(capacity, result, m.size, m.capacity, round(m.table_load(), 2))

    print("\nPDF - get_keys example 1")
    print("------------------------")
    m = HashMap(10, hash_function_2)
    for i in range(100, 200, 10):
        m.put(str(i), str(i * 10))
    print(m.get_keys())

    m.resize_table(1)
    print(m.get_keys())

    m.put('200', '2000')
    m.remove('100')
    m.resize_table(2)
    print(m.get_keys())


'''
Created on Jul 13, 2017

This file contains methods for plotting a single, classified set of data for this practice example
and for plotting two sets in the same window

@author: Chris Newby
'''

from matplotlib import pyplot as plt

def Plot_Data(dat_in, dat_class, title = 'Sample Data'):
    '''
    Function for plotting the data
    specific to the data I'm generating in Making_Data
    '''
    x_list = []
    y_list = []
    color_list = []

    for elem in dat_in:
        x_list.append(elem[0])
        y_list.append(elem[1])

    for elem in dat_class:
        if elem[0] == 1:
            color_list.append("r")
        else:
            color_list.append('b')

    plt.scatter(x = x_list, y = y_list, c=color_list)
    plt.xlabel('x')
    plt.xlim([-1,1])
    plt.ylabel('y')
    plt.ylim([-1,1])
    plt.title(title)
    plt.axes().set_aspect('equal')
    plt.show()

def Plot_two_data(dat_1,class_1,dat_2,class_2, name_1 = 'Sample Data',name_2 = 'Classified Data'):
    '''
    Function for plotting two sets of data together
    '''

    #setting up first data set
    x1_list = []
    y1_list = []
    color1_list = []

    for elem in dat_1:
        x1_list.append(elem[0])
        y1_list.append(elem[1])

    for elem in class_1:
        if elem[0] == 1:
            color1_list.append("r")
        else:
            color1_list.append('b')

    #setting up second data set
    x2_list = []
    y2_list = []
    color2_list = []

    for elem in dat_2:
        x2_list.append(elem[0])
        y2_list.append(elem[1])

    for elem in class_2:
        if elem[0] == 1:
            color2_list.append("r")
        else:
            color2_list.append('b')

    plt.figure(1)
    plt.subplot(121, aspect = 'equal')
    plt.scatter(x = x1_list, y = y1_list, c=color1_list)
    plt.xlim([-1,1])
    plt.ylim([-1,1])
    plt.title(name_1)

    plt.subplot(122, aspect = 'equal')
    plt.scatter(x = x2_list, y = y2_list, c=color2_list)
    plt.xlim([-1,1])
    plt.ylim([-1,1])
    plt.title(name_2)

    plt.show()


# Author: Abel
# !/usr/bin/python3
# -*- coding: utf-8 -*-
# This program is optimized for python 3.6
# 从HTTP服务器下载数据

import argparse
import http.client  #(python3代替httplib)

REMOTE_SERVER_HOST = 'www.python.org'
REMOTE_SERVER_PATH = '/'

class HTTPClient:

    def __init__(self, host):
        self.host = host

    def fetch(self, path):
        h = http.client.HTTPConnection(self.host)

        # Prepare header
        h.putrequest("GET", path)
        h.putheader("User-Agent", __file__)
        h.putheader("Host", self.host)
        h.putheader("Accept", "*/*")
        h.endheaders()

        try:

            r = h.getresponse()
        except Exception as e:
            errcode, errmsg, headers = r
            print(
                "Client failed error code:%s message:%s headers:%s" % (errcode, errmsg, headers))
        else:
            print("Got homepage from %s" % self.host)
        return r.read()

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description='HTTP Client Example')
    parser.add_argument(
        '--host', action='store', dest="host", default=REMOTE_SERVER_HOST)
    parser.add_argument(
        '--path', action="store", dest="path", default=REMOTE_SERVER_PATH)
    given_args = parser.parse_args()
    host, path =given_args.host, given_args.path
    client = HTTPClient(host)
    print(client.fetch(path).decode())


from BinaryInsertionSort import BinaryInsertionSort
from BubbleSort import BubbleSort
from QuickSort import QuickSort
from typing import List
import easygui
import _io
import sys
import timeit

class FileUtils():

    def getNumerosFromFile(self) -> List[int]:
        numbers = []
        file_content = self._abrir_arquivo()
        for line in file_content:
            valor = int(self._remover_break_line(line))
            numbers.append(valor)
        return numbers

    def _remover_break_line(self, text: str) -> str:
        return text.replace("\n", "")

    def _abrir_arquivo(self) -> _io.TextIOWrapper:
        file_path = self._obter_caminho_do_arquivo_usando_easygui()
        file = open(f"{file_path}", "r")
        return file

    def _obter_caminho_do_arquivo_usando_easygui(self) -> str:
        return easygui.fileopenbox()

class TempoAlgoritmos:

    def obter_tempo_de_execucao_de_cada_algoritmo(self, lista) -> List[float]:
        """Uma lista de contendo o tempo de algoritmo é retornada.

            posicao[0] -> Bubble Sort
            posicao[1] -> Binary Insertion Sort
            posicao[2] -> Quick Sort

        """
        lista_binary = lista.copy()
        lista_quick = lista.copy()
        lista_bubble = lista.copy()

        return [
            self._tempo_do_bubble_sort_para_ordenar_a_lista(lista_bubble),
            self._tempo_do_binary_insertion_sort_para_ordernar_a_lista(lista_binary),
            self._tempo_do_quick_sort_para_ordernar_a_lista(lista_quick)
        ]

    def _tempo_do_binary_insertion_sort_para_ordernar_a_lista(self, lista) -> float:
        binary_insertion_sort = BinaryInsertionSort()
        start = timeit.default_timer()
        binary_insertion_sort.binary_insertion_sort(lista)
        end = timeit.default_timer()

        return end - start

    def _tempo_do_quick_sort_para_ordernar_a_lista(self, lista) -> float:
        quick_sort = QuickSort()
        start = timeit.default_timer()
        quick_sort.quick_sort(lista, 0, len(lista)-1)
        end = timeit.default_timer()

        return end - start

    def _tempo_do_bubble_sort_para_ordenar_a_lista(self, lista) -> float:
        bubble_sort = BubbleSort()
        start = timeit.default_timer()
        bubble_sort.bubble_sort(lista)
        end = timeit.default_timer()

        return end - start


from js9 import j

JSBASE = j.application.jsbase_get_class()
class BlockchainDB(JSBASE):
    '''
    a blockchain modeled on a DB
    '''

    def __init__(self, name, db):
        JSBASE.__init__(self)
        self.name
        self.db


# Копилка
# class MoneyBox:
#     def __init__ (self, capacity):
#         self.capacity = capacity # конструктор с аргументом – вместимость копилки
#         self.kolvo = 0 # колов монет в копилке
#
#     def can_add(self, v):
#         if v <= (self.capacity - self.kolvo):
#             return True # если можно добавить v монет True, False иначе
#         else: return False
#         #вообще эти 3 строки пишутся в 1 строку return v <= (self.capacity - self.kolvo)
#
#     def add(self, v):
#         if self.can_add(v) is True:
#             self.kolvo += v
#         else: print('На хер')
# Правильно
class MoneyBox:
    def __init__ (self, capacity):
        self.capacity = capacity # конструктор с аргументом – вместимость копилки
        self.kolvo = 0 # колво монет в копилке в данный момент

    def can_add(self, v):
      return v <= (self.capacity - self.kolvo)  # True or False

    def add(self, v):
        if self.can_add(v):
            self.kolvo += v
        else: print('На хер! Места в копилке больше нет!')

    def reset(self):
        self.kolvo = 0

a=MoneyBox(10)

print(a.can_add(12))
a.add(5) # добавили
a.add(1) # еще добавили
print(a.can_add(1))
a.add(1)
print(a.kolvo)
a.add(3)
print(a.kolvo)
a.reset()
print(a.kolvo)

КЛАССЫ/Копилка.py


#calss header
class _ONE():
	def __init__(self,):
		self.name = "ONE"
		self.definitions = [u'the number 1: ', u'a member of a group of people or things: ', u'used to refer to a time in the future that is not yet decided: ', u'used to refer to a particular occasion while avoiding stating the exact moment: ', u'a single thing; not two or more: ', u'combined in a single person or object: ', u'used when saying there is no other person or thing: ', u'used before the name of someone who is not known: ', u'used to emphasize an adjective: ']

		self.parents = []
		self.childen = []
		self.properties = []
		self.jsondata = {}

		self.specie = 'numbers'

	def run(self, obj1 = [], obj2 = []):
		return self.jsondata


import json
from src.biz.dao import dao_case
import src.utils.comm as comm
from src.utils.enum import exec_status

class CaseMatch:
    _source_sql = ''
    _source_connect_id = 0
    _destination_sql = ''
    _destination_connect_id = 0
    _test_case_type = ''
    _threshlod_low = 0
    _threshlod_high = 0
    _duration_limit = 0

    def __init__(self, case_params):
        self._source_sql = case_params[0]
        self._source_connect_id = case_params[1] if case_params[1] is not None else 0
        self._destination_sql = case_params[2]
        self._destination_connect_id = case_params[3] if case_params[3] is not None else 0
        self._test_case_type = case_params[4]
        self._threshlod_low = case_params[5]
        self._threshlod_high = case_params[6]
        self._duration_limit = case_params[7]

class ExactlyMatch(CaseMatch):
    def __init__(self, case_params):
        CaseMatch.__init__(self, case_params)

    def RunCase(self):
        # step 1 Init
        current_status = exec_status.FAILED
        source_list = dao_case.get_list(
            self._source_connect_id, self._duration_limit, self._source_sql)
        target_list = dao_case.get_list(
            self._destination_connect_id, self._duration_limit, self._destination_sql)
        source_result = json.dumps(source_list)
        target_result = json.dumps(target_list)
        source_set = set(source_list)
        target_set = set(target_list)
        # step 2 duplicate data checking
        if len(source_list) > len(source_set):
            diff = "Source total count:{0}, distinct count:{1}".format(
                len(source_list), len(source_set))
            result_message = "Source side data is duplicate"
            return current_status, diff, result_message, source_result, target_result
        if len(target_list) > len(target_set):
            diff = "Target total count:{0}, distinct count:{1}".format(
                len(target_list), len(target_set))
            result_message = "Target side data is duplicate"
            return current_status, diff, result_message, source_result, target_result
        # step 3 compare the diff between source and target
        source_diff = source_set - target_set
        target_diff = target_set - source_set
        if(len(source_diff) == 0 and len(target_diff) == 0):
            current_status = exec_status.SUCCESS
            diff = ""
            result_message = "Source is totally matched with target --> Source count:{0},target count:{1}".format(
                len(source_list), len(target_list))
            return current_status, diff, result_message, source_result, target_result
        _diff = {
            "source-target": list(source_diff),
            "target-source": list(target_diff)
        }
        diff = json.dumps(_diff)
        result_message = "Source is not matched with target"
        return current_status, diff, result_message, source_result, target_result

class RangeMatch(CaseMatch):
    def __init__(self, case_params):
        CaseMatch.__init__(self, case_params)

    def RunCase(self):
        current_status = exec_status.FAILED
        source_result = ""
        target_result = ""
        diff = ""
        result_message = "execution is not success"

        if (self._source_connect_id > 0 and self._destination_connect_id == 0):
            source_count = dao_case.get_one(
                self._source_connect_id, self._duration_limit, self._source_sql)
            source_num = comm.int_val(source_count[0])
            if(len(source_count) > 0 and source_num is not None):
                source_result = source_num
                if(source_num >= self._threshlod_low and source_num <= self._threshlod_high):
                    current_status = exec_status.SUCCESS
                    result_message = "The value:{0} is in range".format(
                        source_num)
                else:
                    diff = "The value:{0} not in range".format(source_num)

        elif(self._source_connect_id == 0 and self._destination_connect_id > 0):
            target_count = dao_case.get_one(
                self._destination_connect_id, self._duration_limit, self._destination_sql)
            target_num = comm.int_val(target_count[0])
            if(len(target_count) > 0 and target_num is not None):
                target_result = target_num
                if(target_num >= self._threshlod_low and target_num <= self._threshlod_high):
                    current_status = exec_status.SUCCESS
                    result_message = "The value:{0} is in range".format(
                        target_num)
                else:
                    diff = "The value:{0} not in range".format(target_num)

        elif(self._source_connect_id > 0 and self._destination_connect_id > 0):
            source_count = dao_case.get_one(
                self._source_connect_id, self._duration_limit, self._source_sql)
            target_count = dao_case.get_one(
                self._destination_connect_id, self._duration_limit, self._destination_sql)
            if(len(source_count) > 0 and len(target_count) > 0):
                source_result = source_num
                target_result = target_num
                source_num = comm.int_val(source_count[0])
                target_num = comm.int_val(target_count[0])
                if(source_num is not None and target_num is not None):
                    gap_num = abs(source_num - target_num)
                    if(gap_num >= self._threshlod_low and gap_num <= self._threshlod_high):
                        current_status = exec_status.SUCCESS
                        result_message = "The value:{0} is in range".format(
                            gap_num)
                    else:
                        diff = "source_num:{0} - target_num:{1} = {2} not in range".format(
                            source_num, target_num, gap_num)

        return current_status, diff, result_message, source_result, target_result


import numpy as np
import os.path as osp

from unittest import TestCase

from datumaro.components.project import Project
from datumaro.components.extractor import Extractor, DatasetItem
from datumaro.util.test_utils import TestDir
from datumaro.util.image import save_image

class ImageDirFormatTest(TestCase):
    class TestExtractor(Extractor):
        def __iter__(self):
            return iter([
                DatasetItem(id=1, image=np.ones((10, 6, 3))),
                DatasetItem(id=2, image=np.ones((5, 4, 3))),
            ])

    def test_can_load(self):
        with TestDir() as test_dir:
            source_dataset = self.TestExtractor()

            for item in source_dataset:
                save_image(osp.join(test_dir.path, '%s.jpg' % item.id),
                    item.image)

            project = Project.import_from(test_dir.path, 'image_dir')
            parsed_dataset = project.make_dataset()

            self.assertListEqual(
                sorted(source_dataset.subsets()),
                sorted(parsed_dataset.subsets()),
            )

            self.assertEqual(len(source_dataset), len(parsed_dataset))

            for subset_name in source_dataset.subsets():
                source_subset = source_dataset.get_subset(subset_name)
                parsed_subset = parsed_dataset.get_subset(subset_name)
                self.assertEqual(len(source_subset), len(parsed_subset))
                for idx, (item_a, item_b) in enumerate(
                        zip(source_subset, parsed_subset)):
                    self.assertEqual(item_a, item_b, str(idx))

            self.assertEqual(
                source_dataset.categories(),
                parsed_dataset.categories())