import logging
import json
import datetime

from datetime import datetime as dt
from textwrap import dedent

from django.db.models import Q
from django.utils import timezone

from app.events.models import Event, EventParticipant
from app.users.models import User
from app.calendars.models import Calendar

from .models import TelegramBot
from .serializers import GetSerializer, CalendarSerializer, MeetingDetailSerializer  # noqa 501

from telegram import ReplyKeyboardMarkup, KeyboardButton, ReplyKeyboardRemove, InlineKeyboardMarkup, InlineKeyboardButton  # noqa 501

# timezone
timezone.now()

# Set logging
logging.basicConfig(
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
    level=logging.INFO
)
logger = logging.getLogger(__name__)

def text_after_command(update):
    text = update.message.text
    entities = update.message.entities
    command_len = entities[0]['offset'] + entities[0]['length'] + 1
    return text[command_len:] if len(text) > command_len else ''

def event_handle(i):
    calendar_id = ''.join(str(c) for c in i['calendars'])
    calendar = Calendar.objects.filter(id=calendar_id)
    i['calendars'] = calendar[0].name
    i['行程'] = i.pop('title')
    i['開始時間'] = i.pop('start_at').replace('T', ' ').replace('+08:00', '')
    i['結束時間'] = i.pop('end_at').replace('T', ' ').replace('+08:00', '')
    i['備註'] = i.pop('description')
    i['地點'] = i.pop('location')
    i['行事曆'] = i.pop('calendars')

    i = json.dumps(i, ensure_ascii=False)
    i = i.replace('"', '')
    i = i.replace('[', '')
    i = i.replace(']', '')
    i = i.replace('id:', '')
    i = i.replace('{', '')
    i = i.replace('}', '')
    i = i.replace(',', '\n')
    return i

def start(update, context):
    chat_id = update.message.chat.id
    context.bot.send_message(
        chat_id,
        dedent('''\
        歡迎使用一訂行☺請先進行身分綁定來獲得所有的功能！
        沒有綁定的話大部份功能皆無法使用🙁欲綁定請輸入 /login 你的訂閱網址
        訂閱網址請在本系統網頁服務中的"我的訂閱"中獲取
        ''')
    )
    context.bot.send_message(
        chat_id,
        dedent('''\
        範例:/login https://calendar.ntub.tw//feed/3ce855c-8f65-8c8949365f34
        網頁服務請到
        https://fir-project-44c79.firebaseapp.com/#/
        '''),
    )

def help(update, context):
    chat_id = update.message.chat.id
    context.bot.send_message(
        chat_id=chat_id,
        text=dedent('''\
            /login - 貼上你的訂閱網址  »綁定並開始使用一訂行！
            /help - 查看所有功能
            /website - 前往一訂行網頁服務
            /event - 接上關鍵字來搜尋特定行程!
            /meeting - 查看今日會議或是以關鍵字來搜尋會議
            /subscribe - 訂閱行事曆
        '''),
    )

def website(update, context):
    chat_id = update.message.chat.id
    keyboard = [
        [InlineKeyboardButton('GO!', url='https://fir-project-44c79.firebaseapp.com/#/')]  # noqa 501
    ]
    context.bot.send_message(
        chat_id=chat_id,
        text='點選按鈕前往一訂行網頁服務',
        reply_markup=InlineKeyboardMarkup(keyboard)
    )

def login(update, context):
    chat_id = update.message.chat.id
    reply = text_after_command(update)
    get_id = TelegramBot.objects.filter(chat_id=chat_id)
    if get_id:
        context.bot.send_message(chat_id, '您已經綁定完成囉🤗不用再重新綁定~')
    else:
        if not reply:
            context.bot.send_message(chat_id, '沒有網址沒辦法綁定唷🙁，綁定請輸入 /login 你的訂閱網址(URL)')  # noqa 501
        else:
            reply_list = reply.split('/')
            reply = reply_list[4]
            user_id = User.objects.values_list('id', flat=True).filter(code=reply)  # noqa 501
            if user_id:
                TelegramBot.objects.get_or_create(
                    chat_id=chat_id,
                    user_id=user_id[0]
                )
                context.bot.send_message(
                    chat_id,
                    f'綁定成功！歡迎{update.message.chat.first_name}！🥰如果之後您更換了訂閱網址，不需要重新綁定喔！接下來使用 /help 來查看所有功能吧👉'  # noqa 501
                    )
            else:
                context.bot.send_messag(
                    chat_id,
                    '沒有找到符合訂閱網址的使用者，您是否已經更換過網址或是尚未在一訂行網頁登入呢?'
                )

def get_event(update, context):
    chat_id = update.message.chat.id
    get_id = TelegramBot.objects.values_list('user_id', flat=True).filter(chat_id=chat_id)  # noqa 501

    search = text_after_command(update)
    event = None
    if get_id:
        if not search:
            context.bot.send_message(chat_id, '接上關鍵字才能查詢')
        else:
            event = Event.objects \
                .filter(
                    Q(calendars__groups__user=get_id[0]) &
                    (
                        Q(title__contains=search) &
                        Q(start_at__gte=datetime.date.today())
                    ) |
                    Q(participants=get_id[0]) &
                    (
                        Q(title__contains=search) &
                        Q(start_at__gte=datetime.date.today())
                    ) |
                    Q(calendars__display='public') &
                    (
                        Q(title__contains=search) &
                        Q(start_at__gte=datetime.date.today())
                    )
                ).distinct()
            if not event:
                context.bot.send_message(chat_id, '沒有搜尋到相關行程或會議🤔')

            if event:
                serializer = GetSerializer(event, many=True)

                data = json.loads(json.dumps(serializer.data))
                for i in data:
                    event_id = i.pop('id')
                    i = event_handle(i)
                    keyboard = [
                        [InlineKeyboardButton('單獨訂閱此行程', callback_data=event_id)],
                    ]
                    context.bot.send_message(
                        chat_id=chat_id,
                        text=i,
                        reply_markup=InlineKeyboardMarkup(keyboard)
                    )

                context.bot.send_message(chat_id, '以上是這次的查詢結果🥰')
    else:
        context.bot.send_message(chat_id, '請先綁定!')

def meeting_handle(i):
    i['行程'] = i.pop('title')
    i['開始時間'] = i.pop('start_at').replace('T', ' ').replace('+08:00', '')
    i['結束時間'] = i.pop('end_at').replace('T', ' ').replace('+08:00', '')
    i['備註'] = i.pop('description')
    i['地點'] = i.pop('location')
    i['參與人員'] = i.pop('eventparticipant_set')

    i = json.dumps(i, ensure_ascii=False)
    i = i.replace('"', '')
    i = i.replace('[', '')
    i = i.replace(']', '')
    i = i.replace('}', '')
    i = i.replace('{', '')
    i = i.replace("user:", '')
    i = i.replace('editors, response: accept', '(發起人)')
    i = i.replace('editors, response: maybe', '(發起人)')
    i = i.replace('editors, response: no_reply', '(發起人)')
    i = i.replace('editors, response: decline', '(發起人)')
    i = i.replace(', role:', '')
    i = i.replace('participants', '')
    i = i.replace(", response:", ':')
    i = i.replace('accept', '參加')
    i = i.replace('maybe', '不確定')
    i = i.replace('no_reply', '未回應')
    i = i.replace('decline', '不參加')
    i = i.replace(',', '\n')
    return i

def meeting(update, context):
    chat_id = update.message.chat.id
    get_id = TelegramBot.objects.filter(chat_id=chat_id)
    search = text_after_command(update)
    if search:
        edit_meeting = Event.objects.filter(
            Q(nature='meeting'),
            Q(eventparticipant__user_id=get_id[0].user_id),
            Q(eventparticipant__role='editors'),
            Q(start_at__gte=datetime.date.today()),
            Q(title__contains=search),
        )
        attend_meeting = Event.objects.filter(
            Q(nature='meeting'),
            Q(eventparticipant__user_id=get_id[0].user_id),
            Q(eventparticipant__role='participants'),
            Q(start_at__gte=datetime.date.today()),
            Q(title__contains=search),
        )
    else:
        edit_meeting = Event.objects.filter(
            Q(nature='meeting'),
            Q(eventparticipant__user_id=get_id[0].user_id),
            Q(eventparticipant__role='editors'),
            Q(start_at__contains=datetime.date.today()),
        )
        attend_meeting = Event.objects.filter(
            Q(nature='meeting'),
            Q(eventparticipant__user_id=get_id[0].user_id),
            Q(eventparticipant__role='participants'),
            Q(start_at__contains=datetime.date.today()),
        )
    if edit_meeting or attend_meeting:
        if edit_meeting:
            serializer = MeetingDetailSerializer(edit_meeting, many=True)
            edit_data = json.loads(json.dumps(serializer.data))
            for i in edit_data:  # 使用者發起的會議
                i = meeting_handle(i)
            context.bot.send_message(chat_id, i)

        if attend_meeting:
            attend_serializer = MeetingDetailSerializer(attend_meeting, many=True)  # noqa 501
            attend_data = json.loads(json.dumps(attend_serializer.data))

            for i in attend_data:  # 使用者受邀的會議
                i = meeting_handle(i)

                keyboard = [
                    [InlineKeyboardButton('修改出席狀態', callback_data='edit_meeting')]
                ]
                reply_markup = InlineKeyboardMarkup(keyboard)
                context.bot.send_message(
                    chat_id=chat_id,
                    text=i,
                    reply_markup=reply_markup,
                )

        search_keyboard = [
            [InlineKeyboardButton('查詢其他時間區段的會議', callback_data='search')],
        ]
        context.bot.send_message(
            chat_id=chat_id,
            text='如果需要查詢其他日期的會議請點選以下按鈕',
            reply_markup=InlineKeyboardMarkup(search_keyboard),
        )
    else:
        search_keyboard = [
            [InlineKeyboardButton('查詢其他時間區段的會議', callback_data='search')],
        ]
        context.bot.send_message(
            chat_id=chat_id,
            text=dedent('''\
                    今日沒有需出席的會議~
                    如果需要查詢其他日期的會議請點選以下按鈕
                '''),
            reply_markup=InlineKeyboardMarkup(search_keyboard),
        )

def meeting_callback(update, context):
    query = update.callback_query.data

    chat_id = update.callback_query.message.chat_id

    if query == 'accept' or query == 'maybe' or query == 'decline':
        text = update.callback_query.message.text
        text = text.replace('行程:', '')
        text = text.replace('開始時間:', '')
        text = text.replace('結束時間:', '')
        text = text.replace('備註:', '')
        text = text.replace('地點:', '')
        text = text.replace('參與人員:', '')
        text = text.replace(' ', '')
        text = text.replace('(會議發起人)', '')
        text = text.replace('不參加:', '')
        text = text.replace('參加', '')
        text = text.replace('不確定:', '')

        text = text.split('\n')
        event = Event.objects.filter(
            Q(title=text[0]) &
            Q(start_at__date=dt.strptime(text[1], '%Y-%m-%d%H:%M:%S')) &
            Q(end_at__date=dt.strptime(text[2], '%Y-%m-%d%H:%M:%S'))
        )

    if query == 'edit_meeting':
        reply_markup = InlineKeyboardMarkup(
            [
                [
                    InlineKeyboardButton('參加', callback_data='accept'),
                    InlineKeyboardButton('不確定', callback_data='maybe'),
                    InlineKeyboardButton('不參加', callback_data='decline')
                ]
            ]
        )
        context.bot.edit_message_reply_markup(
            chat_id=chat_id,
            message_id=update.callback_query.message.message_id,
            reply_markup=reply_markup
        )

    elif query == 'accept':
        user = TelegramBot.objects.filter(chat_id=chat_id)
        reply = EventParticipant.objects.filter(
            Q(event_id=event[0].id) &
            Q(user=user[0].user_id)
        )
        reply.update(response='accept')
        reply_markup = InlineKeyboardMarkup(
            [
                [InlineKeyboardButton('已修改出席狀態爲參加', callback_data='nothing')]
            ]
        )
        event = Event.objects.filter(id=event[0].id)

        serializer = MeetingDetailSerializer(event, many=True)
        data = json.loads(json.dumps(serializer.data))

        data[0] = meeting_handle(data[0])

        context.bot.edit_message_reply_markup(
            chat_id=chat_id,
            message_id=update.callback_query.message.message_id,
            reply_markup=reply_markup
        )
        context.bot.send_message(chat_id, f'已幫您修改出席狀態爲參加:\n{data[0]}')

    elif query == 'maybe':
        user = TelegramBot.objects.filter(chat_id=chat_id)
        reply = EventParticipant.objects.filter(
            Q(event_id=event[0].id) &
            Q(user=user[0].user_id)
        )
        reply.update(response='maybe')

        event = Event.objects.filter(id=event[0].id)

        serializer = MeetingDetailSerializer(event, many=True)
        data = json.loads(json.dumps(serializer.data))

        data[0] = meeting_handle(data[0])

        reply_markup = InlineKeyboardMarkup(
            [
                [InlineKeyboardButton('已修改出席狀態爲不確定', callback_data='nothing')]
            ]
        )
        context.bot.edit_message_reply_markup(
            chat_id=chat_id,
            message_id=update.callback_query.message.message_id,
            reply_markup=reply_markup
        )
        context.bot.send_message(chat_id, f'已幫您修改出席狀態爲不確定:\n{data[0]}')

    elif query == 'decline':
        user = TelegramBot.objects.filter(chat_id=chat_id)
        reply = EventParticipant.objects.filter(
            Q(event_id=event[0].id) &
            Q(user=user[0].user_id)
        )
        reply.update(response='decline')

        event = Event.objects.filter(id=event[0].id)

        serializer = MeetingDetailSerializer(event, many=True)
        data = json.loads(json.dumps(serializer.data))

        data[0] = meeting_handle(data[0])

        reply_markup = InlineKeyboardMarkup(
            [
                [InlineKeyboardButton('已修改出席狀態爲不參加', callback_data='nothing')]
            ]
        )
        context.bot.edit_message_reply_markup(
            chat_id=chat_id,
            message_id=update.callback_query.message.message_id,
            reply_markup=reply_markup
        )
        context.bot.send_message(chat_id, f'已幫您修改出席狀態爲不參加\n{data[0]}')

    elif query == 'nothing':
        pass

    elif query == 'search':
        search_keyboard = [
            [InlineKeyboardButton('查看三天內的會議', callback_data='3天')],
            [InlineKeyboardButton('查看一個禮拜內的會議', callback_data='7天')],
            [InlineKeyboardButton('查看一個月內的會議', callback_data='30天')],
        ]
        context.bot.edit_message_reply_markup(
            chat_id=chat_id,
            message_id=update.callback_query.message.message_id,
            reply_markup=InlineKeyboardMarkup(search_keyboard)
        )

    elif query == '3天':
        today = datetime.date.today()
        end = today + datetime.timedelta(days=3)
        user = TelegramBot.objects.filter(chat_id=chat_id)
        meeting = Event.objects.filter(
            Q(eventparticipant__user_id=user[0].user_id),
            Q(eventparticipant__role='editors'),
            Q(nature='meeting'),
            Q(start_at__range=[today, end]),
        )
        attend_meeting = Event.objects.filter(
            Q(eventparticipant__user_id=user[0].user_id),
            Q(eventparticipant__role='participants'),
            Q(nature='meeting'),
            Q(start_at__range=[today, end]),
        )
        if meeting or attend_meeting:
            if meeting:
                serializer = MeetingDetailSerializer(meeting, many=True)
                data = json.loads(json.dumps(serializer.data))
                for i in data:
                    i = meeting_handle(i)
                    context.bot.send_message(chat_id, i)

            if attend_meeting:
                attend_serializer = MeetingDetailSerializer(attend_meeting, many=True)
                attend_data = json.loads(json.dumps(attend_serializer.data))
                for i in attend_data:
                    i = meeting_handle(i)

                    keyboard = [
                        [InlineKeyboardButton('修改出席狀態', callback_data='edit_meeting')]
                    ]

                    context.bot.send_message(
                        chat_id=chat_id,
                        text=i,
                        reply_markup=InlineKeyboardMarkup(keyboard)
                    )
            context.bot.send_message(chat_id, '以上就是這三天的會議☺')
        else:
            context.bot.send_message(chat_id, '這三天沒有受邀或是參與會議')

    elif query == '7天':
        today = datetime.date.today()
        end = today + datetime.timedelta(days=7)
        user = TelegramBot.objects.filter(chat_id=chat_id)
        meeting = Event.objects.filter(
            Q(eventparticipant__user_id=user[0].user_id),
            Q(eventparticipant__role='editors'),
            Q(nature='meeting'),
            Q(start_at__range=[today, end]),
        )
        attend_meeting = Event.objects.filter(
            Q(eventparticipant__user_id=user[0].user_id),
            Q(eventparticipant__role='participants'),
            Q(nature='meeting'),
            Q(start_at__range=[today, end]),
        )
        if meeting or attend_meeting:
            if meeting:
                serializer = MeetingDetailSerializer(meeting, many=True)
                data = json.loads(json.dumps(serializer.data))
                for i in data:
                    i = meeting_handle(i)
                    context.bot.send_message(chat_id, i)
            if attend_meeting:
                attend_serializer = MeetingDetailSerializer(attend_meeting, many=True)
                attend_data = json.loads(json.dumps(attend_serializer.data))
                for i in attend_data:
                    i = meeting_handle(i)

                    keyboard = [
                        [InlineKeyboardButton('修改出席狀態', callback_data='edit_meeting')]
                    ]

                    context.bot.send_message(
                        chat_id=chat_id,
                        text=i,
                        reply_markup=InlineKeyboardMarkup(keyboard)
                    )
            context.bot.send_message(chat_id, '以上就是最近七天的會議☺')
        else:
            context.bot.send_message(chat_id, '最近七天沒有受邀或是參與會議')

    elif query == '30天':
        today = datetime.date.today()
        end = today + datetime.timedelta(days=31)
        user = TelegramBot.objects.filter(chat_id=chat_id)
        meeting = Event.objects.filter(
            Q(eventparticipant__user_id=user[0].user_id),
            Q(eventparticipant__role='editors'),
            Q(nature='meeting'),
            Q(start_at__range=[today, end]),
        )
        attend_meeting = Event.objects.filter(
            Q(eventparticipant__user_id=user[0].user_id),
            Q(eventparticipant__role='participants'),
            Q(nature='meeting'),
            Q(start_at__range=[today, end]),
        )
        if meeting or attend_meeting:
            if meeting:
                serializer = MeetingDetailSerializer(meeting, many=True)
                data = json.loads(json.dumps(serializer.data))
                for i in data:
                    i = meeting_handle(i)
                    context.bot.send_message(chat_id, i)
            if attend_meeting:
                attend_serializer = MeetingDetailSerializer(attend_meeting, many=True)
                attend_data = json.loads(json.dumps(attend_serializer.data))
                for i in attend_data:
                    i = meeting_handle(i)

                    keyboard = [
                        [InlineKeyboardButton('修改出席狀態', callback_data='edit_meeting')],
                    ]

                    context.bot.send_message(
                        chat_id=chat_id,
                        text=i,
                        reply_markup=InlineKeyboardMarkup(keyboard)
                    )
            context.bot.send_message(chat_id, '以上就是最近一個月的會議☺')
        else:
            context.bot.send_message(chat_id, '最近一個月內沒有受邀或是參與會議')

    else:
        event_id = int(query)
        user_id = TelegramBot.objects.filter(chat_id=chat_id)
        user = User.objects.filter(id=user_id[0].user_id)
        event = Event.objects.filter(id=event_id).exclude(subscribers__in=user)
        if event:
            event[0].subscribers.add(user[0])
            keyboard = [
                [InlineKeyboardButton('已幫您訂閱此行程😊', callback_data='nothing')]
            ]
            context.bot.edit_message_reply_markup(
                chat_id=chat_id,
                message_id=update.callback_query.message.message_id,
                reply_markup=InlineKeyboardMarkup(keyboard),
            )
        else:
            keyboard = [
                [InlineKeyboardButton('這個行程已經訂閱過了😊', callback_data='nothing')]
            ]
            context.bot.edit_message_reply_markup(
                chat_id=chat_id,
                message_id=update.callback_query.message.message_id,
                reply_markup=InlineKeyboardMarkup(keyboard),
            )

def calendar(update, context):
    chat_id = update.message.chat.id
    user_id = list(TelegramBot.objects.values_list('user_id', flat=True).filter(chat_id=chat_id))  # noqa 501
    user = User.objects.filter(id__in=user_id)
    if user:
        calendar = Calendar.objects.filter(
            Q(display='public') |
            (
                Q(permissions__role=user[0].role) &
                Q(permissions__group__user=user[0])
            ),
        ).exclude(subscribers__in=user_id).distinct()
        if calendar:

            serializer = CalendarSerializer(calendar, many=True)
            data = json.dumps(serializer.data, ensure_ascii=False)

            data = data.replace('"', '')
            data = data.replace('[', '')
            data = data.replace(']', '')
            data = data.replace('}', '')
            data = data.replace('{', '')
            data = data.replace(':', '')
            data = data.replace('name', '')
            data = data.replace(' ', '')
            data = data.split(',')
            keyboard = [
                [KeyboardButton(text='結束訂閱')],
            ]

            for i in data:
                keyboard.append([KeyboardButton(text=i)])

            reply_markup = ReplyKeyboardMarkup(
                keyboard,
                resize_keyboard=True,
            )
            context.bot.send_message(
                chat_id=chat_id,
                text='點選想訂閱的行事曆',
                reply_markup=reply_markup,
                )
        else:
            context.bot.send_message(chat_id, '行事曆都已訂閱，沒有可以訂閱的行事曆了')
    else:
        context.bot.send_message(chat_id, '您尚未綁定無法使用此功能😢')

def calendarSubscribe(update, context):
    chat_id = update.message.chat.id
    user_id = list(TelegramBot.objects.values_list('user_id', flat=True).filter(chat_id=chat_id))  # noqa 501
    user = User.objects.filter(id__in=user_id)
    text = update.message.text
    calendar = Calendar.objects.filter(
            Q(display='public') |
            (
                Q(permissions__role=user[0].role) &
                Q(permissions__group__user=user[0])
            ),
        ).exclude(subscribers__in=user_id).distinct()
    serializer = CalendarSerializer(calendar, many=True)
    data = json.dumps(serializer.data, ensure_ascii=False)
    if text in data:
        c = Calendar.objects.filter(name=text)
        c[0].subscribers.add(user[0].id)
        context.bot.send_message(chat_id, '已訂閱此行事曆😉')
    elif text == '結束訂閱':
        calendar = Calendar.objects.filter(subscribers__in=user_id).distinct()
        if calendar:
            serializer = CalendarSerializer(calendar, many=True)
            data = json.dumps(serializer.data, ensure_ascii=False)

            data = data.replace('"', '')
            data = data.replace('[', '')
            data = data.replace(']', '')
            data = data.replace('}', '')
            data = data.replace('{', '')
            data = data.replace(':', '')
            data = data.replace('name', '')
            data = data.replace(' ', '')
            data = data.replace(',', '\n')
            context.bot.send_message(chat_id, text=f'已經訂閱的行事曆：\n{data}')

        context.bot.send_message(
            chat_id, text='如果想再訂閱請用 /subscribe',
            reply_markup=ReplyKeyboardRemove()
        )


# -*- coding: utf-8 -*-
"""
Created on Tue May  9 23:01:36 2023

@author: Shreya Thekkiniyedath Kudalvalli
"""

#Importing the necessary libraries
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
import scipy.optimize as opt
from sklearn import cluster
import errors as err

#Read and clean the datafile
def read_file(fn):
    """
    Reads a CSV file and returns a pandas DataFrame.

    Parameters:
    ------------
    fn (str): The filename of the CSV file to be read.

    Returns:
    ---------
    df (pandas.DatFrame): The DataFrame containing the data
    read from the CSV file.
    """
    address = "C:\\Users\\user\\OneDrive\\ASD1 Assignment3\\" + fn
    df = pd.read_csv(address)
    df = df.drop(df.columns[:2], axis=1)
    df=df.drop(columns=['Country Code'])

    # Remove the string of year from column names
    df.columns = df.columns.str.replace(' \[YR\d{4}\]', '', regex=True)
    countries=['Japan','India']
    country_code=['JPN','IND']

    #Transpose the dataframe
    df = df[df['Country Name'].isin(countries)].T
    #Rename columns
    df = df.rename({'Country Name': 'year'})
    df = df.reset_index().rename(columns={'index': 'year'})

    df.columns = df.iloc[0]
    df = df.iloc[1:]
    df = df.replace('..', np.nan)
    df = df.replace(np.nan,0)

    df["year"] = df["year"].astype(int)
    df["India"]=df["India"].astype(float)
    df["Japan"]=df["Japan"].astype(float)

    return df

def curve_fun(t, scale, growth):
 """

 Parameters
 ----------
 t : TYPE
 List of values
 scale : TYPE
 Scale of curve.
 growth : TYPE
 Growth of the curve.
 Returns
 -------
 c : TYPE
 Result
 """
 c = scale * np.exp(growth * (t-1990))
 return c

def gdp(df_gdp):
  """
    plots the GDP per capita for Japan and India.

    Parameters:
    ------------
    df_gdp(pandas.DataFrame): A DataFrame containing
    the data of GDP per capita.

    Returns:
    ---------
    None
   """

  plt.plot(df_gdp["year"], df_gdp["India"], c="crimson", label="India")
  plt.plot(df_gdp["year"], df_gdp["Japan"], c="darkviolet", label="Japan")
  plt.xlim(1990,2019)
  plt.xlabel("Year")
  plt.ylabel(" GDP per capita growth (annual %)")
  plt.legend()
  plt.title("GDP per capita for india and japan")
  plt.savefig("GDP.png", dpi = 300, bbox_inches='tight')
  plt.show()

#Calling the file read function
df_co2=read_file("Co2_Emissions.csv")
df_gdp=read_file("GDP_per_Capita.csv")
df_renew= read_file("Renewable_Energy.csv")

#Performing curve fit for India

param, cov = opt.curve_fit(
    curve_fun,
    df_co2["year"],
    df_co2["India"],
    p0=[4e8, 0.1]
    )

#  np.sqrt() is used to return the
# non-negetive square root of an array element-wise.

# np.diag() will extract or construct a diagonal array.
sigma = np.sqrt(np.diag(cov))

#Error
low,up = err.err_ranges(df_co2["year"],curve_fun,param,sigma)
df_co2["fit_value"] = curve_fun(df_co2["year"], * param)

# 1: Plotting the co2 emission values for India
plt.figure()
plt.title("CO2 emissions (metric tons per capita) - India")
plt.plot(df_co2["year"],df_co2["India"], c="crimson", label="data")
plt.plot(df_co2["year"],df_co2["fit_value"],c="darkviolet",label="fit")
plt.fill_between(df_co2["year"],low,up,alpha=0.4)
plt.legend()
plt.xlim(1990,2019)
plt.xlabel("Year")
plt.ylabel("CO2")
plt.savefig("Co2_India.png", dpi = 300, bbox_inches='tight')
plt.show()

# 2: Plotting the predicted values for India co2 emission
plt.figure()
plt.title("CO2 emission prediction of India")
pred_year = np.arange(1990,2030)
pred_ind = curve_fun(pred_year,*param)
plt.plot(df_co2["year"],df_co2["India"],c="crimson", label="data")
plt.plot(
    pred_year,
    pred_ind,
    c="darkviolet",
    label="predicted values"
    )
plt.legend()
plt.xlabel("Year")
plt.ylabel("CO2")
plt.savefig("Co2_India_Predicted.png", dpi = 300, bbox_inches='tight')
plt.show()

#Curve fit for Japan
param, cov = opt.curve_fit(
    curve_fun,
    df_co2["year"],
    df_co2["Japan"],
    p0=[4e8, 0.1]
    )
sigma = np.sqrt(np.diag(cov))
low,up = err.err_ranges(df_co2["year"],curve_fun,param,sigma)
df_co2["fit_value"] = curve_fun(df_co2["year"], * param)

# 3: Plotting co2 emission prediction for Japan
plt.figure()
plt.title("Japan CO2 emission prediction For 2030")
pred_year = np.arange(1990,2030)
pred_ind = curve_fun(pred_year,*param)
plt.plot(df_co2["year"],df_co2["Japan"],c="crimson", label="data")
plt.plot(pred_year,pred_ind, c="darkviolet", label="predicted values")
plt.legend()
plt.xlabel("Year")
plt.ylabel("CO2")
plt.savefig("Co2_Japan_Predicted.png", dpi = 300, bbox_inches='tight')
plt.show()

# 4: Renewable energy use as a percentage of total energy - India
#Curve fit for India
param, cov = opt.curve_fit(
    curve_fun,
    df_renew["year"],
    df_renew["India"],
    p0=[4e8, 0.1]
    )
sigma = np.sqrt(np.diag(cov))
low,up = err.err_ranges(df_renew["year"],curve_fun,param,sigma)
df_renew["fit_value"] = curve_fun(df_renew["year"], * param)

plt.figure()
plt.title("Renewable energy use as a percentage of total energy - India")
plt.plot(
    df_renew["year"],
    df_renew["India"],
    c="crimson",
    label="data"
    )
plt.plot(
    df_renew["year"],
    df_renew["fit_value"],
    c="darkviolet",
    label="fit"
    )
plt.fill_between(df_renew["year"],low,up,alpha=0.3)
plt.legend()
plt.xlim(1990,2019)
plt.xlabel("Year")
plt.ylabel("Renewable energy(% of total energy use)")
plt.savefig("Renewable_India.png", dpi = 300, bbox_inches='tight')
plt.show()

#5) Renewable energy prediction - India

plt.figure()
plt.title("Renewable energy prediction - India")
pred_year = np.arange(1990,2030)
pred_ind = curve_fun(pred_year,*param)
plt.plot(df_renew["year"],df_renew["India"],c="crimson", label="data")
plt.plot(pred_year,pred_ind, c="darkviolet", label="predicted values")
plt.legend()
plt.xlabel("Year")
plt.ylabel("Renewable energy(% of total energy use)")
plt.savefig(
    "Renewable_energy_prediction_India.png",
    dpi = 300,
    bbox_inches='tight'
    )
plt.show()

#6) Renewable energy prediction - Japan

param, cov = opt.curve_fit(
    curve_fun,
    df_renew["year"],
    df_renew["Japan"],
    p0=[4e8, 0.1]
    )
sigma = np.sqrt(np.diag(cov))
low,up = err.err_ranges(df_renew["year"],curve_fun,param,sigma)
df_renew["fit_value"] = curve_fun(df_renew["year"], * param)

plt.figure()
plt.title("Renewable energy prediction - Japan")
pred_year = np.arange(1990,2030)
pred_ind = curve_fun(pred_year,*param)
plt.plot(df_renew["year"],df_renew["Japan"], c="crimson", label="data")
plt.plot(pred_year,pred_ind, c="darkviolet", label="predicted values")
plt.legend()
plt.xlabel("Year")
plt.ylabel("Renewable energy(% of total energy use)")
plt.savefig(
    "Renewable_Prediction_Japan.png",
    dpi = 300,
    bbox_inches='tight'
    )
plt.show()

# 7) Gdp per capita

#Calling the gdp() for visualizing gdp per capita of India and Japan
gdp(df_gdp)

# 8) Japan and India - CO2 Emission

df_co2= df_co2.iloc[:,1:3]
#Normalize data
df_co2_norm=(df_co2 - df_co2.mean()) / df_co2.std()
df_renew_norm=(df_renew - df_renew.mean()) / df_renew.std()

#Create cluster and visualize co2 emissions of given countries
# Kmeans Clustering

kmean = cluster.KMeans(n_clusters=4).fit(df_co2_norm)
label = kmean.labels_
plt.scatter(df_co2_norm["Japan"],df_co2_norm["India"],c=label,cmap="coolwarm")
plt.title("Japan and India - CO2 Emission")
plt.xlabel("Co2 emission of Japan")
plt.ylabel("co2 emission of India")
c = kmean.cluster_centers_
plt.savefig("Scatter_Japan_India_CO2.png",
            dpi = 300,
            bbox_inches='tight'
            )
plt.show()

#9) co2 emission vs renewable enery usage - India

india = pd.DataFrame()
india["co2_emission"] = df_co2_norm["India"]
india["renewable_energy"] = df_renew_norm["India"]

kmean = cluster.KMeans(n_clusters=4).fit(india)
label = kmean.labels_
plt.scatter(india["co2_emission"], india["renewable_energy"],
            c=label,cmap="coolwarm")
plt.title("co2 emission vs renewable enery usage - India")
plt.xlabel("co2 emission")
plt.ylabel("Renewable energy")

plt.savefig(
    "Scatter_CO2_vs_Renewable_India.png",
    dpi = 300,
    bbox_inches='tight'
    )
c = kmean.cluster_centers_

for t in range(2):
 xc,yc = c[t,:]
 plt.plot(xc,yc,"ok",markersize=8)
plt.figure()

plt.show()


"""
특정 조건이 부합할 때만 사용 가능하지만 매우 빠르게 동작하는 정렬 알고리즘.
    계수 정렬은 데이터 크기 범위가 제한되어 정수 형태로 표현 가능할 때 사용 가능하다.
데이터의 개수가 N, 데이터(양수)중 최댓값이 K일 때 최악의 경우에도 수행시간 O(N+K)를 보장한다

해당 데이터가 몇 번 등장했는지 카운트하여 값 증가시킨다.
정렬할 데이터 : 7 5 9 0 3 1 6 2 9 1 4 8 0 5 2
step 0. 가장 작은 데이터부터 가장 큰 데이터까지의 범위가 모두 담길 수 있도록 리스트 생성
인덱스
0 1 2 3 4 5 6 7 8 9
개수(count)
0 0 0 0 0 0 0 0 0 0

step 1. 데이터를 하나씩 확인하여 데이터의 값과 동일한 인덱스의 데이터를 1씩 증가
정렬할 데이터 : *7 5 9 0 3 1 6 2 9 1 4 8 0 5 2
개수(count)
0 0 0 0 0 0 0 1 0 0

step 15.
2 2 2 1 1 2 1 1 1 2

결과를 확인할 때는 리스트의 첫 번째 데이터부터 하나씩 그 값을 반복하여 인덱스를 출력한다.
0 0 1 1 2 2 .... 9 9

배열이 필요하므로 공간복잡도가 높다.
"""

# 모든 원소의 값이 0보다 크거나 같다고 가정
array = [7, 5, 9, 0, 3, 1, 6, 2, 9, 1, 4, 8, 0, 5, 2]
# 모든 범위를 포함하는 리스트 선언(모든 값은 0으로 초기화)
count = [0] * (max(array) + 1)

for i in range(len(array)):
    count[array[i]] += 1  # 각 데이터에 해당하는 인덱스의 값 증가

for i in range(len(count)):  # 리스트에 기록된 정렬 정보 확인
    for j in range(count[i]):
        print(i, end=" ")  # 띄어쓰기를 구분으로 등장한 횟수만큼 인덱스 출력
"""
시간 복잡도, 공간 복잡도 모두 O(N+K)이다
계수 정렬은 때에 따라서 심각한 비효율성 초래 가능
   - 데이터가 0,999999 단 2개만 존재하는 경우
계수 정렬은 동일한 값을 가지는 데이터가 여러 번 등장할 때 효과적.
   - 성적의 경우 100점의 학생이 여러 명일 수 있기 때문에 계수 정렬이 효과적이다.
"""


import config

from createsend import Subscriber, Client, CreateSend, List

a_test_client_auth = config.a_test_client_auth
account_auth = config.account_auth

def create_new_list(clientid, list_name):
    my_list = List(account_auth)
    my_list.create(clientid, list_name, "", False, "")

def list_names(client_id):
    my_client=Client(a_test_client_auth, client_id=client_id)
    results=my_client.lists()
    list_names_dir={}
    list_names=[]
    for r in results:
        list_names_dir[r.Name]=r.ListID
        list_names.append(r.Name)
    if 'Main List' not in list_names:
          create_new_list(clientid=client_id)
    return(list_names_dir['Main List'])

# my_client=Client(account_auth, client_id="9cde80d058d8e4955a076d33b6ec2294")
#
# client_details = my_client.details()
#
# print(client_details.ApiKey)

#print(a_test_client_auth)

# #print("hello world")
#
# my_subscriber = Subscriber(a_test_client_auth)
#
# my_custom_fields = [{"Key": "Favorite Cuisine", "Value": "Pizza"},{'Key': 'Hobby', "Value": "Football"}]
#
# my_subscriber.add("5926ac888cffa2665144bae9127a89a5", "jashton+api6@sailthru.com", "Subscriber", my_custom_fields, True, "yes")
#
my_client=Client(account_auth, client_id="9cde80d058d8e4955a076d33b6ec2294")
results=my_client.lists()
list_names_ids={}
list_names=[]
for r in results:
    list_names_ids[r.Name]=r.ListID
    list_names.append(r.Name)

print(list_names)
if 'Main List' not in list_names:
    print("its not there")
else:
    print("It exists!")
#
#
# print(type(dir(results[0])))
#
# print(type(results[0]))
#
# print([r.Name, r.ListID for r in results])


import re
import torch
import numpy as np
import math
import torch.nn as nn
import time
import subprocess
import torch.nn.functional as F
from model.generator import Beam
from data.data import DocField, DocDataset, DocIter
from utils.config import is_cqa_task
from model.graph_model import *
from utils.train_helper import *

class CqaNet(PointerNet):
    def __init__(self, args):
        super().__init__(args)
        d_mlp = args.d_mlp
        mlp_output_d=2
        self.linears = nn.ModuleList([nn.Linear(args.d_rnn, d_mlp),
                                      nn.Linear(args.d_rnn * 2, d_mlp),
                                      nn.Linear(d_mlp, mlp_output_d),
                                      nn.Linear(args.ehid, d_mlp)])
        answer_type_class_num=4
        self.answer_type_paragraph_linear=nn.Linear(args.d_rnn, d_mlp)
        self.answer_type_question_linear=nn.Linear(args.d_rnn, d_mlp)
        self.answer_type_linear=nn.Linear(d_mlp, answer_type_class_num)
        self.multi_task_loss_weight = nn.Parameter(torch.ones(2))

    def forward(self, src_and_len, tgt_and_len, doc_num, ewords_and_len, elocs,label_of_one_batch_and_len,answer_types):
        entity_logics, answer_type_logics=self.gen_logics(src_and_len,doc_num,ewords_and_len,elocs)

        entity_class_weight =get_weights_inverse_num_of_samples(2,np.array([6770678,103586]))
        answer_type_class_weight =get_weights_inverse_num_of_samples(4,np.array([10987,8448,87836,1376]))
        # entity_class_weight = torch.tensor([1,50], dtype=torch.float32,device=torch.device("cuda"))
        # answer_type_class_weight = torch.tensor([10,10,1,10], dtype=torch.float32,device=torch.device("cuda"))
        entity_loss=self.gen_loss(label_of_one_batch_and_len[0],entity_logics,True,ewords_and_len,entity_class_weight)
        answer_type_loss=self.gen_loss(answer_types,answer_type_logics,False,None,answer_type_class_weight)

        loss=self.gen_multi_task_loss( entity_loss,answer_type_loss,False)
        return loss
        # return  entity_loss

    def gen_multi_task_loss(self,entity_loss,answer_type_loss,is_fixed_weight):
        if is_fixed_weight:
            fixed_weight=get_weights_inverse_num_of_samples(2,np.array([6874264,108647]))
            loss=  entity_loss*fixed_weight[0]+answer_type_loss*fixed_weight[1]
        else:
            loss=0.5 * torch.stack((entity_loss,answer_type_loss)) / self.multi_task_loss_weight**2
            loss=loss.sum() + torch.log(self.multi_task_loss_weight.prod())
        return loss

    def gen_loss(self,label_of_one_batch,logics,need_mask,ewords_and_len,class_weight):
        if need_mask:
            entity_mask=self.gen_entity_mask( ewords_and_len[1],logics)
            logics.masked_fill_(entity_mask , -1e9)

        logp = F.log_softmax(logics, dim=-1)
        logp = logp.view(-1, logp.size(-1))

        loss_function = nn.NLLLoss(weight= class_weight )
        loss = loss_function(logp, label_of_one_batch.contiguous().view(-1))
        loss = loss.sum()/label_of_one_batch.size(0)
        return loss

    #some entities are padded fake entity
    def gen_entity_mask(self, entity_num,e):
        entity_mask=torch.ones_like(e ,dtype=torch.bool)
        # entity_mask  = e.new_zeros(label_of_one_batch.size(0), label_of_one_batch.size(1))
        # [e.new_zeros(e.size(0), 1, e.size(2)).byte()]
        for i in range(len(entity_num)):
            entity_mask[i,:entity_num[i],:]=False
        return entity_mask

    def gen_logics(self, src_and_len,   doc_num, ewords_and_len, elocs ):
        document_matrix, _, hcn, key,entity_h,paragraph_h = self.encode(src_and_len, doc_num, ewords_and_len, elocs)
        cur_question_h=self.gen_question_h(key,doc_num)

        # cur_question_h=cur_question_h.unsqueeze(1)
        entity_logics=self.gen_entity_relation(cur_question_h,entity_h )
        answer_type_logics=self.gen_answer_type_relation(cur_question_h,paragraph_h )
        return entity_logics, answer_type_logics

    def gen_entity_relation(self,question_hidden, compared_hidden ):
        compared_hidden = self.linears[3](compared_hidden)
        question_hidden = self.linears[0](question_hidden)
        relations=question_hidden+compared_hidden
        e = torch.tanh(relations)
        e = self.linears[2](e)
        return e

    def gen_answer_type_relation(self,question_hidden, compared_hidden ):
        compared_hidden = self.answer_type_paragraph_linear(compared_hidden)
        question_hidden = self.answer_type_question_linear(question_hidden)
        relations=question_hidden+compared_hidden
        e = torch.tanh(relations)
        e = self.answer_type_linear(e)
        return e

    def gen_question_h(self,key,doc_num):
        question_h_list=[]
        for i in range(len(doc_num)):
            one_question_h=key[i,doc_num[i]-1,:]
            question_h_list.append(one_question_h)
        batch_question_h=torch.stack(question_h_list,dim=0)
        batch_question_h=batch_question_h.unsqueeze(1)
        return batch_question_h

    def predict(self, src_and_len, doc_num, ewords_and_len, elocs):
        entity_logics, answer_type_logics=self.gen_logics(src_and_len,doc_num,ewords_and_len,elocs)
        m = nn.Softmax(dim=-1)
        predicted_entity_labels=self.gen_predicted_labels(entity_logics,m)
        predicted_answer_type_labels=self.gen_predicted_labels(answer_type_logics,m)

        return predicted_entity_labels   ,predicted_answer_type_labels

    def gen_predicted_labels(self,logics,m):
        classes_probability = m(logics)
        predicted_labels = torch.argmax(classes_probability, axis=-1)
        return predicted_labels

    def predict_coqa_answer(self, src_and_len, doc_num, ewords_and_len, elocs,ewords_str,paragraph_id_list,turn_id_list):
        entity_logics, answer_type_logics=self.gen_logics(src_and_len,doc_num,ewords_and_len,elocs)
        m = nn.Softmax(dim=-1)
        predicted_entity_labels=self.gen_predicted_labels(entity_logics,m)
        predicted_answer_type_labels=self.gen_predicted_labels(answer_type_logics,m)

        answer,answer_json_array=self.gen_coqa_answer(predicted_entity_labels,predicted_answer_type_labels,ewords_str,paragraph_id_list,turn_id_list)

        return predicted_entity_labels   ,predicted_answer_type_labels    ,answer,answer_json_array

    def gen_coqa_answer(self,predicted_entity_labels,predicted_answer_type_labels,ewords_str,paragraph_id_list,turn_id_list):
        coqa_predictions = []
        answer_json_array=[]
        for i, (answer_type,entity,entity_name,paragraph_id,turn_id) in enumerate(zip(predicted_answer_type_labels, predicted_entity_labels,ewords_str,paragraph_id_list,turn_id_list)):
            answer_type=int(answer_type)
            if answer_type==0:
                prediction="YES"
            elif answer_type==1:
                prediction="NO"
            elif answer_type==3:
                prediction="UNKNOWN"
            else:
                prediction=predict_by_entity(entity.cpu().numpy(),entity_name)
            answer_json={"id":paragraph_id ,"turn_id":int(turn_id) ,"answer":prediction}
            answer_json_array.append(answer_json)
            coqa_predictions.append(prediction)

        return coqa_predictions,answer_json_array

def predict_by_entity(entity,ewords_str):
    entity_list=np.where(entity==1,ewords_str,"")
    entity_str=" ".join(entity_list).strip()
    if len(entity_str)>0:
        return entity_str
    else:
        return "YES"


from PyQt5.QtWidgets import (QDialog, QListWidget, QVBoxLayout, QLabel, QPushButton, QHBoxLayout,
                             QApplication, QInputDialog, QWidget, QMainWindow, QSizePolicy, QMessageBox)

from PyQt5.QtGui import QIcon

from database import Command

from ItemManager import Cart

import sys

class ScanWindow(QWidget):
    def __init__(self):

        self.cart = Cart()
        self.total_price = 0

        self.barcode_dict = {}

        self.database = Command() # connect to database

        # You can use "super().__init__()" instead
        super(ScanWindow, self).__init__()

        self.list = QListWidget() # Create scan list

        self.total = QLabel("0") # Create total money label
        self.total.setStyleSheet("background-color: lightgreen")

        vbox = QVBoxLayout() # Group widget in vertical box layout

        vbox.addWidget(self.total)

        for text, func in (("Add", self.add),
                           ("Edit", self.edit),
                           ("Remove", self.remove),
                           ("Checkout", self.checkout),
                           ("Return", self.returnToMain)
                           ):

            buttons = QPushButton(text)
            buttons.clicked.connect(func)

            vbox.addWidget(buttons)

        hbox = QHBoxLayout()
        hbox.addWidget(self.list)
        hbox.addLayout(vbox)
        self.setLayout(hbox)

        self.setWindowTitle("Scan mode")
        self.setWindowIcon(QIcon(".icon\\icon.png"))
        self.show()

    def add(self):
        ''' This function use for add item to cart list by manual '''

        row = self.list.currentRow()

        title = "Add item"
        message = "Enter BAR CODE"
        barcode, ok_barcode = QInputDialog.getText(self, title, message)

        item = self.database.getItem(barcode)

        if self.cart.isExist(barcode):
            print(barcode, "Already exist")
            return

        if ok_barcode and item:
            title = "Quantity"
            message = "Enter quantity"
            quantity, ok_quantity = QInputDialog.getText(self, title, message)

            if ok_quantity and quantity is not None and not quantity.isspace() and not quantity == "":

                item_name, item_price, item_type = item
                string_item = "{0}; {1} จำนวน : {2} ราคา : {3}".format(barcode, item_name, quantity, item_price)

                self.cart.addItem(barcode, item_name, item_price, item_type, quantity)

                self.update_price()

                self.list.insertItem(row, string_item)

                print(self.list.item(row))

    def edit(self):
        row = self.list.currentRow()
        item = self.list.item(row)
        barcode = self.getBCodeInDisplay(item)

        current_item = self.cart.getItemByBarCode(barcode)

        title = "Edit quantity"
        message = "Enter new quantity at {0}".format(current_item.getName())

        quantity, ok = QInputDialog.getText(self, title, message)

        if ok and quantity is not None and not quantity.isspace() and not quantity == "":
            name = current_item.item_name
            price = current_item.item_price
            item.setText("{0}; {1} จำนวน : {2} ราคา : {3}".format(barcode, name, quantity, price))
            self.cart.editQuantity(current_item, quantity)
            self.update_price()

    def checkout(self):
        ''' This function use for checkout item by manual '''

        print("checkout")

    def remove(self):
        ''' This function use for remove item by manual '''

        row = self.list.currentRow()
        item = self.list.item(row)

        if item is None:
            return

        reply = QMessageBox.question(self, "Remove item",
                                     "Remove {0} ?".format(str(item.text())),
                                     QMessageBox.Yes | QMessageBox.No)

        if reply == QMessageBox.Yes:
            item = self.list.takeItem(row)
            self.cart.remove(self.getBCodeInDisplay(item))
            del item
            self.update_price()

    def returnToMain(self):

        self.new_window = Main()
        self.new_window.show()
        self.hide()

    def update_price(self):
        self.total_price = self.cart.getCartPrice()
        self.total.setText(str(self.total_price))

    def getBCodeInDisplay(self, item):
        string = item.text()
        barcode = ""
        for char in string:
            if char == ';':
                break
            barcode += char
        return barcode

class Main(QMainWindow):
    def __init__(self):

        super().__init__()
        layout = QVBoxLayout()

        for text, func in (("Scan", self.openScanWindow),
                           ("Data", self.openDataWindow)):

            buttons = QPushButton(text)
            buttons.setSizePolicy(
                                    QSizePolicy.Preferred,
                                    QSizePolicy.Preferred
                                 )

            buttons.clicked.connect(func)

            layout.addWidget(buttons)

        widget = QWidget()
        widget.setLayout(layout)

        self.setCentralWidget(widget)

        self.show()
    def openScanWindow(self):

        self.new_window = ScanWindow()
        self.new_window.show()
        self.close()
        return self.new_window

    def openDataWindow(self):

        print("Data")

if __name__ == "__main__":
    app = QApplication(sys.argv)
    scan_window = Main()
    sys.exit(app.exec())


# https://www.analyticsindiamag.com/understanding-the-basics-of-svm-with-example-and-python-implementation/

import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.svm import SVC
from sklearn.metrics import confusion_matrix
from sklearn.preprocessing import LabelEncoder
from sklearn.model_selection import KFold
import os
import sys
from define import MINIMUM_ACCURACY

""" GLOBAL VARIABLES """

GAMMA = 1

C_ERROR = 1

INCR_GAMMA = 10
INCR_C_ERROR = 10

KFOLD_SPLITS = 10

""" FUNCTIONS """

def svm_train_and_validate(X_values, Y_values):
    count = 0

    print(" dentro svm train and validate valori xvalues yvalues")
    print(X_values)
    print()
    print(Y_values)

    gamma_value = GAMMA
    c_value = C_ERROR

    classifier = SVC(kernel='rbf', random_state = 1, gamma=gamma_value, C=c_value)

    skf = KFold(n_splits=KFOLD_SPLITS, random_state=None, shuffle=False)

    for train_idx, validation_idx in skf.split(X_values):
        count += 1
        X_train = []
        Y_train = []
        X_validation = []
        Y_validation = []
        for idx in train_idx:
            X_train.append(X_values[idx])
            Y_train.append(Y_values[idx])
        for idx in validation_idx:
            X_validation.append(X_values[idx])
            Y_validation.append(Y_values[idx])
        print(Y_train)
        classifier.fit(X_train, Y_train)
        accuracy = svm_test(classifier, X_validation, Y_validation)

        if accuracy < MINIMUM_ACCURACY:
            gamma_value += INCR_GAMMA
            c_value += INCR_C_ERROR
            classifier = SVC(kernel='rbf', random_state = 1, gamma=gamma_value, C=c_value)
            if count == KFOLD_SPLITS:
                classifier.fit(X_train, Y_train)

    return classifier

def svm_test(classifier, X_values, Y_values):
    Y_pred = classifier.predict(X_values)

    cm = confusion_matrix(Y_values,Y_pred)
    accuracy = float(cm.diagonal().sum())/len(Y_values)

    return accuracy


from __future__ import print_function
from __future__ import absolute_import
import argparse
import collections
import logging
import os
import six
import shutil
import subprocess
import sys
import tempfile
import zipfile

sys.path.append(os.path.join(os.path.dirname(__file__), '..', 'py_utils'))

from py_utils import cloud_storage
from dependency_manager import base_config

_CHROME_BINARIES_CONFIG = os.path.join(
    os.path.dirname(os.path.abspath(__file__)), '..', '..', 'common',
    'py_utils', 'py_utils', 'chrome_binaries.json')

_CHROME_GS_BUCKET = 'chrome-unsigned'
_CHROMIUM_GS_BUCKET = 'chromium-browser-snapshots'

# How many commit positions to search below and above omaha branch position to
# find closest chromium build snapshot. The value 10 is chosen because it looks
# more than sufficient from manual inspection of the bucket.
_CHROMIUM_SNAPSHOT_SEARCH_WINDOW = 10

# Remove a platform name from this list to disable updating it.
# Add one to enable updating it. (Must also update _PLATFORM_MAP.)
_PLATFORMS_TO_UPDATE = ['mac_arm64', 'mac_x86_64', 'win_x86',
                        'win_AMD64', 'linux_x86_64',
                        'android_k_armeabi-v7a', 'android_l_arm64-v8a',
                        'android_l_armeabi-v7a', 'android_n_armeabi-v7a',
                        'android_n_arm64-v8a', 'android_n_bundle_armeabi-v7a',
                        'android_n_bundle_arm64-v8a']

# Add platforms here if you also want to update chromium binary for it.
# Must add chromium_info for it in _PLATFORM_MAP.
_CHROMIUM_PLATFORMS = ['mac_arm64', 'mac_x86_64', 'win_x86', 'win_AMD64',
                       'linux_x86_64']

# Remove a channel name from this list to disable updating it.
# Add one to enable updating it.
_CHANNELS_TO_UPDATE = ['stable', 'canary', 'dev']

# Omaha is Chrome's autoupdate server. It reports the current versions used
# by each platform on each channel.
_OMAHA_PLATFORMS = { 'stable':  ['mac_arm64', 'mac', 'linux', 'win',
                                 'win64', 'android'],
                    'dev':  ['linux'], 'canary': ['mac', 'win']}

# All of the information we need to update each platform.
#   omaha: name omaha uses for the platforms.
#   zip_name: name of the zip file to be retrieved from cloud storage.
#   gs_build: name of the Chrome build platform used in cloud storage.
#   chromium_info: information needed to update chromium (optional).
#   destination: Name of the folder to download the reference build to.
UpdateInfo = collections.namedtuple('UpdateInfo',
    'omaha, gs_folder, gs_build, chromium_info, zip_name')
# build_dir: name of the build directory in _CHROMIUM_GS_BUCKET.
# zip_name: name of the zip file to be retrieved from cloud storage.
ChromiumInfo = collections.namedtuple('ChromiumInfo', 'build_dir, zip_name')
_PLATFORM_MAP = {'mac_x86_64': UpdateInfo(
                     omaha='mac',
                     gs_folder='desktop-*',
                     gs_build='mac64',
                     chromium_info=ChromiumInfo(
                         build_dir='Mac',
                         zip_name='chrome-mac.zip'),
                     zip_name='chrome-mac.zip'),
                 'mac_arm64': UpdateInfo(
                     omaha='mac_arm64',
                     gs_folder='desktop-*',
                     gs_build='mac-arm64',
                     chromium_info=ChromiumInfo(
                         build_dir='Mac_Arm',
                         zip_name='chrome-mac.zip',
                     ),
                     zip_name='chrome-mac.zip'),
                 'win_x86': UpdateInfo(
                     omaha='win',
                     gs_folder='desktop-*',
                     gs_build='win-clang',
                     chromium_info=ChromiumInfo(
                         build_dir='Win',
                         zip_name='chrome-win.zip'),
                     zip_name='chrome-win-clang.zip'),
                 'win_AMD64': UpdateInfo(
                     omaha='win',
                     gs_folder='desktop-*',
                     gs_build='win64-clang',
                     chromium_info=ChromiumInfo(
                        build_dir='Win_x64',
                        zip_name='chrome-win.zip'),
                     zip_name='chrome-win64-clang.zip'),
                 'linux_x86_64': UpdateInfo(
                     omaha='linux',
                     gs_folder='desktop-*',
                     gs_build='linux64',
                     chromium_info=ChromiumInfo(
                         build_dir='Linux_x64',
                         zip_name='chrome-linux.zip'),
                     zip_name='chrome-linux64.zip'),
                 'android_k_armeabi-v7a': UpdateInfo(
                     omaha='android',
                     gs_folder='android-*',
                     gs_build='arm',
                     chromium_info=None,
                     zip_name='Chrome.apk'),
                 'android_l_arm64-v8a': UpdateInfo(
                     omaha='android',
                     gs_folder='android-*',
                     gs_build='arm_64',
                     chromium_info=None,
                     zip_name='ChromeModern.apk'),
                 'android_l_armeabi-v7a': UpdateInfo(
                     omaha='android',
                     gs_folder='android-*',
                     gs_build='arm',
                     chromium_info=None,
                     zip_name='Chrome.apk'),
                 'android_n_armeabi-v7a': UpdateInfo(
                     omaha='android',
                     gs_folder='android-*',
                     gs_build='arm',
                     chromium_info=None,
                     zip_name='Monochrome.apk'),
                 'android_n_arm64-v8a': UpdateInfo(
                     omaha='android',
                     gs_folder='android-*',
                     gs_build='arm_64',
                     chromium_info=None,
                     zip_name='Monochrome.apk'),
                 'android_n_bundle_armeabi-v7a': UpdateInfo(
                     omaha='android',
                     gs_folder='android-*',
                     gs_build='arm',
                     chromium_info=None,
                     zip_name='Monochrome.apks'),
                 'android_n_bundle_arm64-v8a': UpdateInfo(
                     omaha='android',
                     gs_folder='android-*',
                     gs_build='arm_64',
                     chromium_info=None,
                     zip_name='Monochrome.apks')
}

VersionInfo = collections.namedtuple('VersionInfo',
                                     'version, branch_base_position')

def _ChannelVersionsMap(channel):
  rows = _OmahaReportVersionInfo(channel)
  omaha_versions_map = _OmahaVersionsMap(rows, channel)
  channel_versions_map = {}
  for platform in _PLATFORMS_TO_UPDATE:
    omaha_platform = _PLATFORM_MAP[platform].omaha
    if omaha_platform in omaha_versions_map:
      channel_versions_map[platform] = omaha_versions_map[omaha_platform]
  return channel_versions_map

def _OmahaReportVersionInfo(channel):
  url ='https://omahaproxy.appspot.com/all?channel=%s' % channel
  lines = six.moves.urllib.request.urlopen(url).readlines()
  return [six.ensure_str(l).split(',') for l in lines]

def _OmahaVersionsMap(rows, channel):
  platforms = _OMAHA_PLATFORMS.get(channel, [])
  if (len(rows) < 1 or
      rows[0][0:3] != ['os', 'channel', 'current_version'] or
      rows[0][7] != 'branch_base_position'):
    raise ValueError(
        'Omaha report is not in the expected form: %s.' % rows)
  versions_map = {}
  for row in rows[1:]:
    if row[1] != channel:
      raise ValueError(
          'Omaha report contains a line with the channel %s' % row[1])
    if row[0] in platforms:
      versions_map[row[0]] = VersionInfo(version=row[2],
                                         branch_base_position=int(row[7]))
  logging.warn('versions map: %s' % versions_map)
  if not all(platform in versions_map for platform in platforms):
    raise ValueError(
        'Omaha report did not contain all desired platforms '
        'for channel %s' % channel)
  return versions_map

RemotePath = collections.namedtuple('RemotePath', 'bucket, path')

def _ResolveChromeRemotePath(platform_info, version_info):
  # Path example: desktop-*/30.0.1595.0/precise32/chrome-precise32.zip
  return RemotePath(bucket=_CHROME_GS_BUCKET,
                    path=('%s/%s/%s/%s' % (platform_info.gs_folder,
                                           version_info.version,
                                           platform_info.gs_build,
                                           platform_info.zip_name)))

def _FindClosestChromiumSnapshot(base_position, build_dir):
  """Returns the closest chromium snapshot available in cloud storage.

  Chromium snapshots are pulled from _CHROMIUM_BUILD_DIR in CHROMIUM_GS_BUCKET.

  Continuous chromium snapshots do not always contain the exact release build.
  This function queries the storage bucket and find the closest snapshot within
  +/-_CHROMIUM_SNAPSHOT_SEARCH_WINDOW to find the closest build.
  """
  min_position = base_position - _CHROMIUM_SNAPSHOT_SEARCH_WINDOW
  max_position = base_position + _CHROMIUM_SNAPSHOT_SEARCH_WINDOW

  # Getting the full list of objects in cloud storage bucket is prohibitively
  # slow. It's faster to list objects with a prefix. Assuming we're looking at
  # +/- 10 commit positions, for commit position 123456, we want to look at
  # positions between 123446 an 123466. We do this by getting all snapshots
  # with prefix 12344*, 12345*, and 12346*. This may get a few more snapshots
  # that we intended, but that's fine since we take the min distance anyways.
  min_position_prefix = min_position // 10;
  max_position_prefix = max_position // 10;

  available_positions = []
  for position_prefix in range(min_position_prefix, max_position_prefix + 1):
    query = '%s/%d*' % (build_dir, position_prefix)
    try:
      ls_results = cloud_storage.ListDirs(_CHROMIUM_GS_BUCKET, query)
    except cloud_storage.NotFoundError:
      # It's fine if there is no chromium snapshot available for one prefix.
      # We will look at the rest of the prefixes.
      continue

    for entry in ls_results:
      # entry looks like '/Linux_x64/${commit_position}/'.
      position = int(entry.split('/')[2])
      available_positions.append(position)

  if len(available_positions) == 0:
    raise ValueError('No chromium build found +/-%d commit positions of %d' %
                     (_CHROMIUM_SNAPSHOT_SEARCH_WINDOW, base_position))

  distance_function = lambda position: abs(position - base_position)
  min_distance_snapshot = min(available_positions, key=distance_function)
  return min_distance_snapshot

def _ResolveChromiumRemotePath(channel, platform, version_info):
  platform_info = _PLATFORM_MAP[platform]
  branch_base_position = version_info.branch_base_position
  omaha_version = version_info.version
  build_dir = platform_info.chromium_info.build_dir
  # Look through chromium-browser-snapshots for closest match.
  closest_snapshot = _FindClosestChromiumSnapshot(
      branch_base_position, build_dir)
  if closest_snapshot != branch_base_position:
    print('Channel %s corresponds to commit position ' % channel +
          '%d on %s, ' % (branch_base_position, platform) +
          'but closest chromium snapshot available on ' +
          '%s is %d' % (_CHROMIUM_GS_BUCKET, closest_snapshot))
  return RemotePath(bucket=_CHROMIUM_GS_BUCKET,
                    path = ('%s/%s/%s' % (build_dir, closest_snapshot,
                                        platform_info.chromium_info.zip_name)))

def _QueuePlatformUpdate(binary, platform, version_info, config, channel):
  """ platform: the name of the platform for the browser to
      be downloaded & updated from cloud storage. """
  platform_info = _PLATFORM_MAP[platform]

  if binary == 'chrome':
    remote_path = _ResolveChromeRemotePath(platform_info, version_info)
  elif binary == 'chromium':
    remote_path = _ResolveChromiumRemotePath(channel, platform, version_info)
  else:
    raise ValueError('binary must be \'chrome\' or \'chromium\'')

  if not cloud_storage.Exists(remote_path.bucket, remote_path.path):
    cloud_storage_path = 'gs://%s/%s' % (remote_path.bucket, remote_path.path)
    logging.warn('Failed to find %s build for version %s at path %s.' % (
        platform, version_info.version, cloud_storage_path))
    logging.warn('Skipping this update for this platform/channel.')
    return

  reference_builds_folder = os.path.join(
      os.path.dirname(os.path.abspath(__file__)), 'chrome_telemetry_build',
      'reference_builds', binary, channel)
  if not os.path.exists(reference_builds_folder):
    os.makedirs(reference_builds_folder)
  local_dest_path = os.path.join(reference_builds_folder,
                                 platform,
                                 platform_info.zip_name)
  cloud_storage.Get(remote_path.bucket, remote_path.path, local_dest_path)
  _ModifyBuildIfNeeded(binary, local_dest_path, platform)
  config.AddCloudStorageDependencyUpdateJob('%s_%s' % (binary, channel),
      platform, local_dest_path, version=version_info.version,
      execute_job=False)

def _ModifyBuildIfNeeded(binary, location, platform):
  """Hook to modify the build before saving it for Telemetry to use.

  This can be used to remove various utilities that cause noise in a
  test environment. Right now, it is just used to remove Keystone,
  which is a tool used to autoupdate Chrome.
  """
  if binary != 'chrome':
    return

  if platform in ['mac_x86_64', 'mac_arm64']:
    _RemoveKeystoneFromBuild(location)
    return

  if 'mac' in platform:
    raise NotImplementedError(
        'Platform <%s> sounds like it is an OSX version. If so, we may need to '
        'remove Keystone from it per crbug.com/932615. Please edit this script'
        ' and teach it what needs to be done :).')

def _RemoveKeystoneFromBuild(location):
  """Removes the Keystone autoupdate binary from the chrome mac zipfile."""
  logging.info('Removing keystone from mac build at %s' % location)
  temp_folder = tempfile.mkdtemp(prefix='RemoveKeystoneFromBuild')
  try:
    subprocess.check_call(['unzip', '-q', location, '-d', temp_folder])
    keystone_folder = os.path.join(
        temp_folder, 'chrome-mac', 'Google Chrome.app', 'Contents',
        'Frameworks', 'Google Chrome Framework.framework', 'Frameworks',
        'KeystoneRegistration.framework')
    shutil.rmtree(keystone_folder)
    os.remove(location)
    subprocess.check_call(['zip', '--quiet', '--recurse-paths', '--symlinks',
                           location, 'chrome-mac'],
                           cwd=temp_folder)
  finally:
    shutil.rmtree(temp_folder)

def _NeedsUpdate(config, binary, channel, platform, version_info):
  channel_version = version_info.version
  print('Checking %s (%s channel) on %s' % (binary, channel, platform))
  current_version = config.GetVersion('%s_%s' % (binary, channel), platform)
  print('current: %s, channel: %s' % (current_version, channel_version))
  if current_version and current_version == channel_version:
    print('Already up to date.')
    return False
  return True

def UpdateBuilds(args):
  config = base_config.BaseConfig(_CHROME_BINARIES_CONFIG, writable=True)
  for channel in _CHANNELS_TO_UPDATE:
    channel_versions_map = _ChannelVersionsMap(channel)
    for platform in channel_versions_map:
      version_info = channel_versions_map.get(platform)
      if args.update_chrome:
        if _NeedsUpdate(config, 'chrome', channel, platform, version_info):
          _QueuePlatformUpdate('chrome', platform, version_info, config,
                               channel)
      if args.update_chromium and platform in _CHROMIUM_PLATFORMS:
        if _NeedsUpdate(config, 'chromium', channel, platform, version_info):
          _QueuePlatformUpdate('chromium', platform, version_info,
                               config, channel)

  print('Updating builds with downloaded binaries')
  config.ExecuteUpdateJobs(force=True)

def main():
  logging.getLogger().setLevel(logging.DEBUG)
  parser = argparse.ArgumentParser(
      description='Update reference binaries used by perf bots.')
  parser.add_argument('--no-update-chrome', action='store_false',
                      dest='update_chrome', default=True,
                      help='do not update chrome binaries')
  parser.add_argument('--no-update-chromium', action='store_false',
                      dest='update_chromium', default=True,
                      help='do not update chromium binaries')
  args = parser.parse_args()
  UpdateBuilds(args)

if __name__ == '__main__':
  main()


import cv2
import numpy as np

class PersonAuthentication():

    #HOG特徴量計算(体)
    hog = cv2.HOGDescriptor()
    hog.setSVMDetector(cv2.HOGDescriptor_getDefaultPeopleDetector())
    hogParams = {'winStride':(8,8),'padding':(32,32),'scale':1.05}

    #カスケード分類器の特徴量を取得する
    cascade = cv2.CascadeClassifier("haarcascade_frontalface_alt.xml")

    #枠の色
    face_color = (255,0,0)
    body_color = (0,255,0)

    def personDetect(self,frame,log):

        human,r = self.hog.detectMultiScale(frame,**self.hogParams)
        face = self.cascade.detectMultiScale(frame, scaleFactor=1.2, minNeighbors=2, minSize=(10, 10))

        if len(human) != 0:
            for(x,y,w,h) in human:
                cv2.rectangle(frame,(x,y),(x+w,y+h),self.body_color,3)
            log.write("detect dody\n")
        if len(face) != 0:
            for rect in face:
                cv2.rectangle(frame, tuple(rect[0:2]),tuple(rect[0:2] + rect[2:4]), self.face_color, thickness=2)
            log.write("detect face\n")

        if len(human) != 0 and len(face) != 0:
            log.write("detect person\n")
            return (True,frame)
        else:
            log.write("detect person\n")
            return (False,frame)


import json
from api import module_path

path2json = module_path / 'api' / 'swagger' / 'openapis'
with open(path2json / "openapi.json", "r") as _f:
    dic = json.load(_f)

dic["paths"] = {x:dic["paths"][x] for x in dic['paths'] if "rd-natural_history" in x }

tag_descr = "Natural history of rare diseases"
dic["tags"] = [x for x in dic["tags"] if tag_descr in x["name"]]

with open(path2json / "openapi_history.json", "w") as _f:
    _f.write(json.dumps(dic, indent=2))


def solution(files):
    answer = []

    special_char = [' ', '.', '-']
    middle_s = 0
    copy_files = files[:]
    my_files = []

    while copy_files:
        file = copy_files.pop()
        find_head, find_middle = False, False
        for index, char in enumerate(file):
            if not find_head:
                if char.isalpha() or char in special_char:
                    continue
                else:
                    head = file[:index]
                    find_head = True
                    middle_s = index
                    middle_count = 1
            elif find_head and not find_middle:
                if char.isdigit() and middle_count < 5:
                    middle_count += 1
                    continue
                else:
                    middle = file[middle_s:index]
                    find_middle = True
                    tail = file[index:]
                    break
        if not find_middle:
            middle = file[middle_s:]
            tail = ''
        my_files.append((head, middle, tail))

    my_files.sort(key=lambda x : [x[0].lower(), int(x[1]), files.index(''.join(x))], reverse=True)

    while my_files:
        answer.append(''.join(my_files.pop()))
    return answer

Kakao Blind Recruitment 2018/fileSort.py


T = int(input())
for tc in range(1,T+1):
    N = int(input())
    bits = int(input(),16)

    cnt = 0
    ans = 0
    for j in range(4*N): #4비트니까 bit0 ~ MSB(최상위 비트)까지 체크
        if bits&(1<<j): #bit j가 0이 아닌 경우
            cnt+=1
            ans = max(cnt,ans)
        else:
            cnt=0
    print(f'#{tc} {ans}')

EXAM/6회차_과목평가_알고리즘/1번 교수님.py


from django.db import models

from product.models import ProductVariation

from account.models import Address
from django.conf import settings  # Here

# Create your models here.
class Order(models.Model):

    variation = models.ForeignKey(ProductVariation,
                                  on_delete=models.DO_NOTHING)
    created_at = models.DateField(auto_now_add=True)
    uploaded_at = models.DateField(auto_now=True)
    quantity = models.IntegerField()
    total = models.FloatField()
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)

    def unity_price(self):
        return self.total / self.quantity

class Orders(models.Model):
    STATUS_CHOICES = (('C', 'CREATED'), ('P', 'PAID_TO_DELIEVER'),('D', 'DELIVERED'))

    order = models.ManyToManyField(Order)
    created_at = models.DateField(auto_now_add=True)
    uploaded_at = models.DateField(auto_now=True)
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)

    address = models.ForeignKey(Address,
                                on_delete=models.DO_NOTHING,
                                blank=False,
                                null=False)
    status = models.CharField(max_length=1,
                              choices=STATUS_CHOICES,
                              blank=False,
                              null=False)
    total_paid = models.FloatField()


#!/usr/bin/python3
"""This module has the class GUID."""
import uuid
from sqlalchemy import String
from sqlalchemy.types import TypeDecorator

class GUID(TypeDecorator):
    """Representation of a GUID"""

    impl = String(32)

    def process_bind_param(self, value, dialect):
        """ process_bind_param """
        if value is not None:
            return uuid.UUID(value)
        return None

    def process_result_value(self, value, dialect):
        """ process_result_value """
        if value is None:
            return value
        return uuid.UUID(value)


from typing import Any
from django.http import JsonResponse
from jwt import decode, exceptions

class JWTMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        # Verifica se a solicitação possui o cabeçalho de autenticação com o token JWT
        if 'login' not in request.path:
            try:
                if 'HTTP_AUTHORIZATION' not in request.META:
                    return JsonResponse({'error': 'Token JWT não informado'}, status=401)

                # Extrai o token do cabeçalho
                token = request.META['HTTP_AUTHORIZATION'].split(' ')[1]

                # Decodifica o token JWT
                payload = decode(token, 'secret_key', algorithms=['HS256'])

                # Armazena os dados do token no objeto de solicitação para uso posterior
                request.jwt_payload = payload

            except exceptions.DecodeError:
                return JsonResponse({'error': 'Token JWT inválido'}, status=401)

        response = self.get_response(request)
        return response


import tkinter as tk
from classes.Game import Minesweeper
from tkinter import messagebox
from pygame import mixer

PROXIMITY_COLORS = {
    1: "grey",
    2: "orange",
    3: "red",
    4: "purple",
    5: "blue"
}

root = tk.Tk()

def create_top_menu():
    menubar = tk.Menu(root)
    menubar.add_command(
        label="Restart", command=lambda: create_game(game.difficulty))

    difficulty_menu = tk.Menu(menubar, tearoff=0)
    difficulty_menu.add_command(
        label="Easy", command=lambda: create_game("easy"))
    difficulty_menu.add_command(
        label="Medium", command=lambda: create_game("medium"))
    difficulty_menu.add_command(
        label="Hard", command=lambda: create_game("hard"))

    menubar.add_cascade(label="Difficulty", menu=difficulty_menu)

    menubar.add_command(label="Quit", command=root.quit)

    root.config(menu=menubar)

def create_game(difficulty):
    for x in root.winfo_children():
        if type(x) != tk.Menu:
            x.destroy()

    tag = tk.Label(root, text="Mine Sweeper", bg="white", font=(
        "Calibri", 15, "italic"), borderwidth=2, relief="solid")
    tag.pack(fill="x")

    global game
    game = Minesweeper(difficulty)

    global game_frame
    game_frame = tk.Frame(root, width=500, height=500, bg="white")
    game_frame.pack()

    for row in range(game.board.rows):
        for col in range(game.board.columns):
            temp = tk.Button(game_frame, text="", width=3,
                            bg="#9ed8af", height=2, font=("Helvetica", 11))
            temp.grid(row=row, column=col)
            temp.bind("<Button-1>", clicked)
            temp.bind("<Button-3>", flag)

    bar_frame = tk.Frame(root, height=50)
    bar_frame.pack(side="bottom", fill="x")
    global counter_mine
    counter_mine = tk.Label(bar_frame, text=f"Remaining Mines: {game.flags}")
    counter_mine.pack(side="left")

# LEFT CLICK
def clicked(event):
    r = event.widget.grid_info()["row"]
    c = event.widget.grid_info()["column"]

    cell = game.board.field[r][c]

    if cell.is_flagged:
        return

    if cell.is_mine:
        for x, y in game.board.pos_mines:
            game_frame.grid_slaves(x, y)[0].config(
                text="M", fg="red", bg="white", font=("Helvetica", 11, "bold italic"))
        game.gameover = True
        show_gameover_message()
    else:
        show_or_expand(r, c)

    if game.check_victory():
        show_victory_message()

def show_or_expand(r, c):
    if game.check_limits(r, c):
        return

    curr = game.board.field[r][c]
    on_grid = game_frame.grid_slaves(r, c)[0]

    if not curr.is_visible and not curr.is_flagged:

        curr.is_visible = True
        game.decrement_squares_to_win()
        on_grid.config(state="disabled")

        if curr.proximity != 0:
            on_grid.config(text=str(
                curr.proximity), disabledforeground=PROXIMITY_COLORS[curr.proximity], bg="white", font=("Helvetica", 11))
        else:
            on_grid.config(bg="white")
            for x, y in game.SURROUNDINGS:
                show_or_expand(r + x, c + y)

# RIGHT CLICK
def flag(event):
    r = event.widget.grid_info()["row"]
    c = event.widget.grid_info()["column"]

    cell = game.board.field[r][c]

    if not cell.is_visible:
        cell.flag()
        if cell.is_flagged:
            event.widget.config(text="?", fg="red", font=(
                "Helvetica", 11, "bold italic"))
            game.decrement_counter_mines()
        else:
            event.widget.config(text="", font=("Helvetica", 11, "normal"))
            game.increment_counter_mines()
        counter_mine.config(text=f"Remaining Mines: {game.flags}")

def show_victory_message():
    result = messagebox.askyesno(
        "Congratulations", "You won the game !\nOne more game, perhaps ?")
    if result == True:
        create_game(game.difficulty)
    else:
        root.quit()

def show_gameover_message():
    result = messagebox.askyesno(":( ", "BOOM BITCH !\nWant to play again?")
    if result == True:
        create_game(game.difficulty)
    else:
        root.quit()

def main():
    mixer.init()
    mixer.music.load("clock_bg.mp3")
    mixer.music.set_volume(0.10)
    mixer.music.play(-1)

    create_top_menu()
    create_game("easy")
    root.mainloop()

if __name__ == "__main__":
    main()


import xbmc, xbmcaddon, os.path

userAgent = 'Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20100101 Firefox/17.0'
addonPath = xbmc.translatePath(xbmcaddon.Addon().getAddonInfo('path'))
resourcesPath = os.path.join(addonPath, 'resources')
imagesPath = os.path.join(resourcesPath, 'images')

def getMenu(menuId, userAgent):
    menu = {
        'main' : [{
                    'id' : 'gma',
                    'name' : 'GMA',
                    'url' : 'gma',
                    'icon' : os.path.join(imagesPath, 'gma_logo.jpg'),
                    'isFolder' : True
                }],
        'gma' : [{
                'id' : 'live',
                'name' : 'Live',
                'url' : 'rtmp://fms.ilive.to:1935/app/_definst_/dfo8ebwnnh37rfv',
                'icon' : os.path.join(imagesPath, 'gma_logo.jpg'),
                'isFolder' : False,
                'kwargs' : {'listProperty' : {'SWFPlayer' : 'http://static.ilive.to/jwplayer/player.swf'}}
            }]
    }
    return (__name__, menu[menuId])


class Solution:
    def shortestPathBinaryMatrix(self, grid: List[List[int]]) -> int:

        def inbound(row ,col):
            return 0 <= row < len(grid) and 0 <= col < len(grid[0])

        rowLength = len(grid) - 1
        directions = [ (1,1) , (1,0) , (1,-1) , (0,1) , (0,-1) , (-1,1) , (-1,0) , (-1,-1) ]
        visited = set()
        visited.add(grid[0][0])
        if grid[0][0] == 1 or grid[-1][-1] == 1:
            return -1

        queue = deque([(0,0,1)])

        while queue:
            row , col , path = queue.popleft()

            if row == rowLength and col == rowLength:
                return path

            for r , c in directions:
                r += row
                c += col

                if inbound(r , c) and grid[r][c] == 0 and (r , c) not in visited:
                    queue.append((r , c , path + 1))
                    visited.add((r , c))

        return -1


import asyncio
import os
import re
import select
import shlex
from subprocess import PIPE, Popen
import sys
from typing import Iterable, List

from metomi.rose.reporter import Event
from metomi.rose.resource import ResourceLocator

class WorkflowFileNotFoundError(Exception):

    """Error: Workflow file not found.

    Expected error for fcm_make remote where the flow.cylc is
    not included in the file installation.
    """

    def __str__(self):
        return "No workflow file found."

class RosePopenError(Exception):

    """An error raised when a shell command call fails."""

    def __init__(self, command, ret_code, stdout, stderr, stdin=None):
        self.command = command
        self.ret_code = ret_code
        self.stdout = stdout
        self.stderr = stderr
        self.stdin = stdin
        Exception.__init__(self, command, ret_code, stdout, stderr)

    def __str__(self):
        cmd_str = str(RosePopenEvent(self.command, self.stdin))
        tail = ""
        if self.stderr:
            tail = ", stderr=\n%s" % self.stderr
        return "%s # return-code=%d%s" % (cmd_str, self.ret_code, tail)

class RosePopenEvent(Event):

    """An event raised before a shell command call."""

    LEVEL = Event.VV

    def __init__(self, command, stdin):
        self.command = command
        self.stdin = stdin
        Event.__init__(self, command, stdin)

    def __str__(self):
        command = self.command
        if len(command) == 1:
            command = command[0]
        if isinstance(command, str):
            ret = command
        else:
            ret = RosePopener.shlex_join(self.command)

        try:
            # real file or real stream
            self.stdin.fileno()
            # ask select if it is readable (real files can hang)
            readable = bool(select.select([self.stdin], [], [], 0.0)[0])
        except (AttributeError, IOError, ValueError):
            # file like
            readable = True

        if self.stdin:
            if isinstance(self.stdin, str):
                # string
                stdin = self.stdin
            elif isinstance(self.stdin, bytes):
                # byte string
                stdin = self.stdin.decode()
            elif readable:
                # file like
                try:
                    pos = self.stdin.tell()
                    stdin = self.stdin.read()
                    self.stdin.seek(pos)
                    if not isinstance(stdin, str):
                        stdin = stdin.decode()
                except Exception:
                    # purposefully vague for safety (catch any exception)
                    stdin = ''
            else:
                stdin = ''

            if stdin:
                ret += f" <<'__STDIN__'\n{stdin}\n__STDIN__"

        return ret

class RosePopener:

    """Wrap Python's subprocess.Popen."""

    CMDS = {
        "diff_tool": ["diff", "-u"],
        "editor": ["vi"],
        "fs_browser": ["nautilus"],
        "gdiff_tool": ["gvimdiff"],
        "geditor": ["gedit"],
        "image_viewer": ["eog", "--new-instance"],
        "rsync": [
            "rsync",
            "-a",
            "--exclude=.*",
            "--timeout=1800",
            "--rsh=ssh -oBatchMode=yes -oConnectTimeout=10",
        ],
        "ssh": ["ssh", "-oBatchMode=yes", "-oConnectTimeout=10"],
        "terminal": ["xterm"],
    }
    ENVS_OF_CMDS = {"editor": ["VISUAL", "EDITOR"]}

    @staticmethod
    def shlex_join(args: Iterable[str]) -> str:
        """Convert a list of strings into a shell command, safely quoting
        when the strings contain whitespace and special chars.

        Basically a back-port of shlex.join(), needed for py 3.7.

        Examples:
        >>> RosePopener.shlex_join([])
        ''
        >>> RosePopener.shlex_join(["echo", "-n", "Multiple words"])
        "echo -n 'Multiple words'"
        >>> RosePopener.shlex_join(["ls", "my_dir;foiled_injection"])
        "ls 'my_dir;foiled_injection'"
        >>> RosePopener.shlex_join(["what", "about", "globs*"])
        "what about 'globs*'"
        """
        return " ".join(shlex.quote(arg) for arg in args)

    @staticmethod
    def list_to_shell_str(args: Iterable[str]) -> str:
        """Convert a list of strings into a shell command, escaping whitespace
        and quotes, but otherwise allowing special chars so user defined
        commands can run without sanitisation.

        Examples:
        >>> RosePopener.list_to_shell_str([])
        ''
        >>> _ = RosePopener.list_to_shell_str(["it's"])
        >>> print(_)
        it\\'s
        >>> _
        "it\\\\'s"
        >>> RosePopener.list_to_shell_str(["echo", "-n", "Multiple words"])
        'echo -n Multiple\\\\ words'
        >>> RosePopener.list_to_shell_str(["ls", "my_dir;allow_this"])
        'ls my_dir;allow_this'
        >>> RosePopener.list_to_shell_str(["what", "about", "globs*"])
        'what about globs*'
        """
        return " ".join(re.sub(r"([\"'\s])", r"\\\1", arg) for arg in args)

    def __init__(self, event_handler=None):
        self.event_handler = event_handler
        self.cmds = {}

    def handle_event(self, *args, **kwargs):
        """Handle an event using the runner's event handler."""
        if callable(self.event_handler):
            return self.event_handler(*args, **kwargs)

    def get_cmd(self, key: str, *args: str) -> List[str]:
        """Return default options and arguments of a known command as a list.

        If a setting [external] <key> is defined in the site/user
        configuration, use the setting.

        Otherwise, if RosePopener.ENVS_OF_CMDS[key] exists, it looks for each
        environment variable in the list in RosePopener.ENVS_OF_CMDS[key] in
        order. If the environment variable is defined and is not a null string,
        use the value of the environment variable.

        Otherwise, return RosePopener.CMDS[key]

        key: must be a key of RosePopener.CMDS
        args: if specified, will be added to the returned list

        """
        if key not in self.cmds:
            root_node = ResourceLocator.default().get_conf()
            node = root_node.get(["external", key], no_ignore=True)
            if node is not None:
                self.cmds[key] = shlex.split(node.value)
        if key not in self.cmds:
            for name in self.ENVS_OF_CMDS.get(key, []):
                env_var = os.getenv(name)
                if env_var:  # not None, not null str
                    self.cmds[key] = shlex.split(env_var)
                    break
        if key not in self.cmds:
            self.cmds[key] = self.CMDS[key]
        return self.cmds[key] + list(args)

    def run(self, *args, **kwargs):
        """Provide a Rose-friendly interface to subprocess.Popen.

        Return ret_code, out, err.

        If kwargs["stdin"] is a str, communicate it to the command via a pipe.

        """
        proc = self.run_bg(*args, **kwargs)
        stdin = None
        if isinstance(kwargs.get("stdin"), str):
            stdin = kwargs.get("stdin")
        stdout, stderr = proc.communicate(stdin)
        retcode = proc.wait()

        return retcode, stdout, stderr

    def run_bg(self, *args, **kwargs):
        """Provide a Rose-friendly interface to subprocess.Popen.

        Return a subprocess.Popen object.

        If kwargs["stdin"] is a str, turn it into subprocess.PIPE.
        However, it cannot communicate stdin to the Popen object,
        because the Popen.communicate() method implies a wait().

        """
        for key in ["stdout", "stderr"]:
            if kwargs.get(key) is None:
                kwargs[key] = PIPE
        stdin = kwargs.get("stdin")
        if isinstance(stdin, str):
            kwargs["stdin"] = PIPE
        elif stdin is None:
            kwargs["stdin"] = open(os.devnull)
        self.handle_event(RosePopenEvent(args, stdin))
        sys.stdout.flush()
        try:
            if kwargs.get("shell"):
                proc = Popen(args[0], text=True, **kwargs)
            else:
                proc = Popen(args, text=True, **kwargs)
        except OSError as exc:
            if exc.filename is None and args:
                exc.filename = args[0]
            raise RosePopenError(args, 1, "", str(exc))
        return proc

    def run_nohup_gui(self, cmd):
        """Launch+detach a GUI command with nohup.

        Launch the GUI command with `nohup bash -c 'exec ...'` redirecting
        standard input and outputs from and to `/dev/null`, and setting it to
        become a process group leader. Equivalent to a double fork.

        Arguments:
            cmd (str): command string of the GUI.

        Return (subprocess.Popen):
            Return the process object for the "nohup" command.
            Return None if no DISPLAY is set.
        """
        if 'DISPLAY' not in os.environ:
            return
        return self.run_bg(
            r'nohup',
            r'bash',
            r'-c',
            r'exec ' + cmd + r' <"/dev/null" >"/dev/null" 2>&1',
            preexec_fn=os.setpgrp,
            stdin=open(os.devnull),
            stdout=open(os.devnull, "wb"),
            stderr=open(os.devnull, "wb"),
        )

    def run_ok(self, *args, **kwargs):
        """Same as RosePopener.run, but raise RosePopenError if ret_code != 1.

        Return out, err.

        """
        ret_code, stdout, stderr = self.run(*args, **kwargs)
        if ret_code:
            raise RosePopenError(
                args, ret_code, stdout, stderr, kwargs.get("stdin")
            )
        return stdout, stderr

    def run_simple(self, *args, **kwargs):
        """Similar to RosePopener.run_ok, but event handle stdout and stderr.

        kwargs["stderr_level"] -- set event level of stderr
        kwargs["stdout_level"] -- set event level of stdout

        Return None.

        """
        stderr_level = kwargs.pop("stderr_level", None)
        stdout_level = kwargs.pop("stdout_level", None)
        ret_code, stdout, stderr = self.run(*args, **kwargs)
        if stdout:
            self.handle_event(stdout, level=stdout_level)
        if ret_code:
            raise RosePopenError(
                args, ret_code, stdout, stderr, kwargs.get("stdin")
            )
        if stderr:
            self.handle_event(stderr, level=stderr_level)

    @staticmethod
    def which(name):
        """Search an executable file name in PATH, and return its full path.

        If name is an absolute path and is an executable file, return name.
        If name is not found in PATH, return None.

        """
        if os.path.isabs(name) and os.access(name, os.F_OK | os.X_OK):
            return name
        for dir_ in os.getenv("PATH").split(os.pathsep):
            file_name = os.path.join(dir_, name)
            if os.access(file_name, os.F_OK | os.X_OK):
                return file_name

    async def run_bg_async(self, *args, **kwargs):
        """Provide a Rose-friendly interface to subprocess.Popen.

        Return a subprocess.Popen object.

        If kwargs["stdin"] is a str, turn it into subprocess.PIPE.
        However, it cannot communicate stdin to the Popen object,
        because the Popen.communicate() method implies a wait().

        """
        for key in ["stdout", "stderr"]:
            if kwargs.get(key) is None:
                kwargs[key] = asyncio.subprocess.PIPE
        stdin = kwargs.get("stdin")
        if isinstance(stdin, str):
            kwargs["stdin"] = asyncio.subprocess.PIPE
        elif stdin is None:
            kwargs["stdin"] = open(os.devnull)
        self.handle_event(RosePopenEvent(args, stdin))
        sys.stdout.flush()
        try:
            if kwargs.get("shell"):
                proc = Popen(args[0], **kwargs)
            else:
                command = ' '.join(map(shlex.quote, args))
                proc = await asyncio.create_subprocess_shell(command, **kwargs)
        except OSError as exc:
            if exc.filename is None and args:
                exc.filename = args[0]
            raise RosePopenError(args, 1, "", str(exc))
        return proc

    async def run_async(self, *args, **kwargs):
        """Provide a Rose-friendly interface to subprocess.Popen.

        Return ret_code, out, err.

        If kwargs["stdin"] is a str, communicate it to the command via a pipe.

        """
        proc = await self.run_bg_async(*args, **kwargs)
        stdin = None
        if isinstance(kwargs.get("stdin"), str):
            stdin = kwargs.get("stdin")
        stdout, stderr = await proc.communicate(stdin)
        await proc.wait()
        return proc.returncode, stdout, stderr

    async def run_ok_async(self, *args, **kwargs):
        ret_code, stdout, stderr = await self.run_async(*args, **kwargs)
        if ret_code:
            if stderr:
                stderr = stderr.decode()
            else:
                stderr = ''
            raise RosePopenError(
                args, ret_code, stdout, stderr, kwargs.get("stdin")
            )
        return stdout, stderr

    __call__ = run_ok


import os
import sys
import mock
from twisted.python import runtime
from twisted.internet import reactor
from twisted.trial import unittest
from buildbot.test.util import steps
from buildbot.status.results import SUCCESS, FAILURE
from buildbot.steps import master

class TestMasterShellCommand(steps.BuildStepMixin, unittest.TestCase):

    def setUp(self):
        if runtime.platformType == 'win32':
            self.comspec = os.environ.get('COMPSPEC')
            os.environ['COMSPEC'] = r'C:\WINDOWS\system32\cmd.exe'
        return self.setUpBuildStep()

    def tearDown(self):
        if runtime.platformType == 'win32':
            if self.comspec:
                os.environ['COMSPEC'] = self.comspec
            else:
                del os.environ['COMSPEC']
        return self.tearDownBuildStep()

    def patchSpawnProcess(self, exp_cmd, exp_argv, exp_path, exp_usePTY,
                          exp_env, outputs):
        def spawnProcess(pp, cmd, argv, path, usePTY, env):
            self.assertEqual([cmd, argv, path, usePTY, env],
                        [exp_cmd, exp_argv, exp_path, exp_usePTY, exp_env])
            for output in outputs:
                if output[0] == 'out':
                    pp.outReceived(output[1])
                elif output[0] == 'err':
                    pp.errReceived(output[1])
                elif output[0] == 'rc':
                    so = mock.Mock(name='status_object')
                    so.value.exitCode = output[1]
                    pp.processEnded(so)
        self.patch(reactor, 'spawnProcess', spawnProcess)

    def test_real_cmd(self):
        cmd = [ sys.executable, '-c', 'print "hello"' ]
        self.setupStep(
                master.MasterShellCommand(command=cmd))
        if runtime.platformType == 'win32':
            self.expectLogfile('stdio', "hello\r\n")
        else:
            self.expectLogfile('stdio', "hello\n")
        self.expectOutcome(result=SUCCESS, status_text=["Ran"])
        return self.runStep()

    def test_real_cmd_fails(self):
        cmd = [ sys.executable, '-c', 'import sys; sys.exit(1)' ]
        self.setupStep(
                master.MasterShellCommand(command=cmd))
        self.expectLogfile('stdio', "")
        self.expectOutcome(result=FAILURE, status_text=["failed (1)"])
        return self.runStep()

    def test_constr_args(self):
        self.setupStep(
                master.MasterShellCommand(description='x', descriptionDone='y',
                                env={'a':'b'}, path=['/usr/bin'], usePTY=True,
                                command='true'))
        if runtime.platformType == 'win32':
            exp_argv = [ r'C:\WINDOWS\system32\cmd.exe', '/c', 'true' ]
        else:
            exp_argv = [ '/bin/sh', '-c', 'true' ]
        self.patchSpawnProcess(
                exp_cmd=exp_argv[0], exp_argv=exp_argv,
                exp_path=['/usr/bin'], exp_usePTY=True, exp_env={'a':'b'},
                outputs=[
                    ('out', 'hello!\n'),
                    ('err', 'world\n'),
                    ('rc', 0),
                ])
        self.expectOutcome(result=SUCCESS, status_text=['y'])
        return self.runStep()


from xmlrpc.client import ServerProxy
import sys

# Create the proxy in a nice way so it gets closed when we are done.
with ServerProxy('http://localhost:9000') as proxy:
    # Ensure we got enough arguments coming in
    assert len(sys.argv) >= 3, "Must supply at least 2 arguments.\n" + \
        "Usage: rpc_sync_client.py function argument1 [argument2 ...]"
    # Split incoming arguments into the name of the function to call and
    # the arguments to supply to that function. Note that sys.argv[0] is
    # the name of the script itself.
    scriptname, function, *arguments = sys.argv
    # Get the indicated remote function.
    remote_function = getattr(proxy, function)
    # Print the result of executing the remote function.
    print(remote_function(arguments))

31380 Intelligent Systems/python projects/Week2D1/comm_exercise/rpc/rpc_sync_master.py


"""
ID: aarush31
LANG: PYTHON3
TASK: gift1
"""
fin = open ('gift1.in', 'r')
fout = open ('gift1.out', 'w')

gifts = {}
lst = list(fin.readlines())
l = [i.strip() for i in lst]

for p in range(1, int(l[0])+1):
	gifts.update({l[p]: 0})

curr = 1 + int(l[0])
for val in range(int(l[0])):
	if (curr + 1 == len(l)):
		break
	temp = l[curr + 1].split(' ')
	tot = int(temp[0])
	ppl = int(temp[1])
	if (tot == 0):
		curr = curr + ppl + 2
		continue
	add = tot // ppl
	for pers in range(curr + 2, curr + 2 + ppl):
		gifts[l[pers]] += add
	gifts[l[curr]] += tot % ppl
	gifts[l[curr]] -= tot
	curr = curr + ppl +2
	print(gifts)

seq = []

for key,value in gifts.items():
	seq.append(str(key) + " " + str(value) + "\n")

fout = open ('gift1.out', 'w')
fout.writelines(seq)
fout.close()
fin.close()