# Detective Dee The Four Heavenly Kings
# -*- coding: utf-8 -*-
import json
import jieba
import requests
import pandas as pd
import numpy as np
import os
import matplotlib.pyplot as plt
from pyecharts import Geo  # 地理坐标系
from pyecharts import Bar  # 柱状图/条形图
from pyecharts import Line  # 折线图
from pyecharts import Overlap
import datetime
from pandas.tseries.offsets import Hour
import time
import re
from wordcloud import WordCloud, STOPWORDS, ImageColorGenerator
from scipy.misc import imread  # 这是一个处理图像的函数
from collections import Counter
from operator import eq
from pyecharts import Map
from pyecharts import Pie

# moivename = '狄仁杰之四大天王'
# movieid = 341516
name = '西虹市首富'
movieid = 1212592
path = os.path.abspath(os.curdir)
out_path = path + "\\" + name
if not os.path.exists(out_path):
    os.makedirs(out_path)

def get_data(movie_name, movie_id):
    print("数据获取开始时间：", datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
    csv_file = out_path + "\\" + movie_name + ".csv"
    tomato = pd.DataFrame(columns=['date', 'score', 'city', 'comment', 'nick'])
    # 2018-07-27 电影上映
    show_time = datetime.datetime.strptime('2018-07-27 00:00:00', "%Y-%m-%d %H:%M:%S")
    # 执行脚本时间
    start_time = datetime.datetime.now()
    # 从上映到执行脚本时间，计算时间间隔转换为小时
    hours = (start_time - show_time).total_seconds()/3600/2
    # 从上映开始，以2小时递加为时间间隔获取一次数据
    for t in range(0, int(hours)):
        start_time = start_time - 2 * Hour()
        print("查询时间：", start_time.strftime('%Y-%m-%d %H:%M:%S'))
        # 每个时间间隔最多获取1000条左右的数据（网页限制最大为1000左右）
        # 单次获得15条数据，所以以15为步长增加
        for i in range(0, 1000, 15):
            try:
                time.sleep(1)
                url = 'http://m.maoyan.com/mmdb/comments/movie/' + str(movie_id) + '.json?_v_=yes&offset=' \
                      + str(i) + '&startTime=' + str(start_time.strftime('%Y-%m-%d %H:%M:%S'))
                print("查询url：", url)
                html = requests.get(url=url).content
                data = json.loads(html.decode('utf_8_sig'))['cmts']
                for item in data:
                    tomato = tomato.append(
                        {'date': item['startTime'], 'city': item['cityName'], 'score': item['score'],
                         'comment': item['content'], 'nick': item['nick']}, ignore_index=True)
                tomato.to_csv(csv_file, encoding="utf_8_sig", index=False)
            except:
                continue
    print("数据获取结束时间：", datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'))

def df_to_list(df):
    array = np.array(df)
    lst = array.tolist()
    return lst

# 过滤字符串只保留中文
def translate(s):
    line = s.strip()
    p2 = re.compile('[^\u4e00-\u9fa5]')  # 中文的编码范围是：\u4e00到\u9fa5
    zh = " ".join(p2.split(line)).strip()
    zh = ",".join(zh.split())
    data = re.sub("[A-Za-z0-9!！，%\[\],。]", "", zh)
    return data

def read_csvfile(filename):
    csv_file = out_path + "\\" + filename + ".csv"
    # csv_file = csv_file.replace('\\', '\\\\')
    data = pd.read_csv(csv_file, engine='python', encoding='utf_8_sig')
    return data

def flatten(a):
    for each in a:
        if not isinstance(each, list):
            yield each
        else:
            yield from flatten(each)

def load_city_json():
    with open("city_coordinates.json", encoding="utf-8-sig") as f:
        city_dict = json.load(f)
    city_sum = list(flatten(list(city_dict.keys())))
    return city_sum

def df_to_list(df):
    array = np.array(df)
    lst = array.tolist()
    return lst

def format_data(csv_filename):
    movie_data = read_csvfile(csv_filename)
    # 数据去重
    data = movie_data.drop_duplicates()
    # groupby可以通过传入需要分组的参数实现对数据的分组,city分组
    grouped = data.groupby(['city'])
    # city数据筛选后再根据score分组
    grouped_pct = grouped['score']  # tip_pct列
    # 筛选后的数据进行计数和求平均
    city_com = grouped_pct.agg(['mean', 'count'])
    # reset_index可以还原索引，重新变为默认的整型索引
    city_com.reset_index(inplace=True)
    # 将mean列舍入到的小数2位数
    city_com['mean'] = round(city_com['mean'], 2)
    origin_city_sum = load_city_json()
    unmatched_departure_list = []
    adjusted_departure_list = []
    departure_test = df_to_list(city_com['city'])

    for i in range(len(departure_test)):
        # 清洗城市，将中文城市提取出来并删除标点符号等
        departure_test[i] = translate(departure_test[i])
        matched = False
        for j in range(len(origin_city_sum)):
            if origin_city_sum[j] in departure_test[i] and (not eq(origin_city_sum[j], departure_test[i])):
                matched = True
                print('matched', departure_test[i], origin_city_sum[j])
                adjusted_departure_list.append([departure_test[i], origin_city_sum[j]])
                departure_test[i] = origin_city_sum[j]
            elif origin_city_sum[j] in departure_test[i] and eq(origin_city_sum[j], departure_test[i]):
                matched = True
        if not matched:
            unmatched_departure_list.append(departure_test[i])
    print("unmatched cities are:%s,adjusted cities are:%s" % (unmatched_departure_list, adjusted_departure_list))
    for each_unmatched_city in unmatched_departure_list:
        ind_list = city_com[city_com['city'].isin([each_unmatched_city])].index.tolist()
        city_com = city_com.drop(ind_list)
    for [before, after] in adjusted_departure_list:
        # isin()判断 before元素是否在city_com['city']列表中
        ind_list = city_com[city_com['city'].isin([before])].index.tolist()
        for i in ind_list:
            city_com.loc[i, 'city'] = after
    city_com.reset_index(inplace=True)
    return city_com

def word_cloud(movie_name, stopwords_file, original_pic_file):
    movie_data = read_csvfile(movie_name)
    tomato_str = ' '.join(movie_data['comment'])
    words_list = []
    word_generator = jieba.cut_for_search(tomato_str)
    for word in word_generator:
        words_list.append(word)
    words_list = [k for k in words_list if len(k) > 1]
    back_color = imread(original_pic_file)  # 解析该图片
    stopwords = STOPWORDS.copy()
    with open(stopwords_file, 'r', encoding="utf-8-sig") as f:
        for i in f.readlines():
            stopwords.add(i.strip('\n'))
        f.close()

    wc = WordCloud(background_color='white',  # 背景颜色
                   max_words=4000,  # 最大词数
                   mask=back_color,  # 以该参数值作图绘制词云，这个参数不为空时，width和height会被忽略
                   max_font_size=100,  # 显示字体的最大值
                   font_path="C:/Windows/Fonts/STFANGSO.ttf",
                   stopwords=stopwords,
                   random_state=42,  # 为每个词返回一个PIL颜色
                   # width=1000,  # 图片的宽
                   # height=860  #图片的长
                   )

    tomato_count = Counter(words_list)
    wc.generate_from_frequencies(tomato_count)
    # 基于彩色图像生成相应彩色
    image_colors = ImageColorGenerator(back_color)
    # 绘制词云
    plt.figure()
    plt.imshow(wc.recolor(color_func=image_colors))
    plt.axis('off')
    pic_file = out_path + "\\" + movie_name + "_词云图.jpg"
    wc.to_file(pic_file)

# 热力图：
def geo_draw(movie_name, movie_data):
    geodata = [(movie_data['city'][i], movie_data['count'][i]) for i in range(0, movie_data.shape[0])]
    while True:  # 二次筛选，和pyecharts支持的城市库进行匹配，如果报错则删除该城市对应的统计
        try:
            geo = Geo(movie_name + '_全国热力图', title_color="#fff", title_pos="center", width=1200, height=1000,
                      background_color='#404a59')
            attr, value = geo.cast(geodata)
            # geo.add("", attr, value, visual_range=[0, 200], maptype='china', visual_text_color="#fff",
            #         symbol_size=10, is_visualmap=True)
            geo.add("", attr, value, type="effectScatter", is_random=True, effect_scale=5)
            file = out_path + "\\" + movie_name + '_全国热力图.html'
            geo.render(file)  # 生成html文件
        except ValueError as e:
            print('error')
        else:
            break

# 折线图和柱状图
def line_draw(movie_name, movie_data):
    city_main = movie_data.sort_values('count', ascending=False)[0:20]
    attr = city_main['city']
    v1 = city_main['count']
    v2 = city_main['mean']
    line = Line("城市评分")
    line.add("评分平均分", attr, v2, is_stack=True, xaxis_rotate=30, yaxis_min=0, mark_point=['min', 'max'],
             xaxis_interval=0,
             line_color='lightblue', line_width=4, mark_point_textcolor='black', mark_point_color='lightblue',
             is_splitline_show=False)
    bar = Bar("城市评论数")
    bar.add("评论数", attr, v1, is_stack=True, xaxis_rotate=30, yaxis_min=0, xaxis_interval=0, is_splitline_show=False)
    overlap = Overlap()
    # 默认不新增 x y 轴，并且 x y 轴的索引都为 0
    overlap.add(bar)
    overlap.add(line, yaxis_index=1, is_add_yaxis=True)
    file = out_path + "\\" + movie_name + '_城市评论数_平均分.html'
    overlap.render(file)  # 生成html文件

def map_draw(movie_name, movie_data):
    attr = movie_data['city']
    value = movie_data['count']
    # value = movie_data['mean']
    map = Map(movie_name + '_全国Map图', width=1200, height=600)
    map.add("", attr, value, maptype='china', is_visualmap=True, visual_text_color='#000')
    file = out_path + "\\" + movie_name + '_全国map图.html'
    map.render(file)

def pie_draw(movie_name, movie_data):
    attr = movie_data['city']
    v1 = movie_data['count']
    v2 = movie_data['mean']
    pie = Pie(movie_name + '_饼图', title_pos='center', width=1200)
    pie.add("评论数", attr, v1, center=[25, 50], is_random=True, radius=[30, 75], rosetype='radius')
    pie.add("评分平均分", attr, v2, center=[75, 50], is_random=True, radius=[30, 75], rosetype='area', is_legend_show=False,
            is_label_show=True)
    file = out_path + "\\" + movie_name + '_饼图.html'
    pie.render(file)

def pie_draw_test():
    attr = ["衬衫", "羊毛衫", "雪纺衫", "裤子", "高跟鞋", "袜子"]
    v1 = [11, 12, 13, 10, 10, 10]
    v2 = [19, 21, 32, 20, 20, 33]
    pie = Pie("饼图示例")
    pie.add("", attr, v1, is_label_show=True)
    pie.render("饼图示例1.html")

    pie2 = Pie("饼图-玫瑰图示例", title_pos='center', width=900)
    pie2.add("商品A", attr, v1, center=[25, 50], is_random=True, radius=[30, 75], rosetype='radius')
    pie2.add("商品B", attr, v2, center=[75, 50], is_random=True, radius=[30, 75], rosetype='area', is_legend_show=False,
             is_label_show=True)
    pie.render("饼图-玫瑰图示例.html")

def process_data(movie_name):
    # word_cloud(movie_name, 'chineseStopWords.txt', 'Word.jpg')
    data = format_data(movie_name)
    # line_draw(movie_name, data)
    # geo_draw(movie_name, data)
    # map_draw(movie_name, data)
    pie_draw(movie_name, data)

# get_data(name, movieid)
process_data(name)


import logging
from enum import IntEnum, auto
import serial

from modbus import Modbus
from hm305.floatsetting import FloatSetting

logger = logging.getLogger(__name__)

class HM305:
    class CMD(IntEnum):
        Output = 0x0001  # (R/W)
        ProtectionStatus = (
            0x0002  # (R), bit field of "isOVP, isOCP, isOPP, isOTP, isSCP"
        )
        ModelNum = 0x0003  # (R)
        Class_detail = 0x0004  # (R) # returns "KP". Perhaps is ClassTemplate in DevicesClassInfo.xml?
        Decimals = 0x0005  # (R) # returns 0x233 == scale factors for V/A/P
        Voltage = 0x0010  # (R)
        Current = 0x0011  # (R)
        Power = 0x0012  # (R) 4 byte response
        Power_cal = 0x0014  # (R/W?) 4 byte response, "calculated power"
        Protect_Voltage = 0x0020  # (R)
        Protect_Current = 0x0021  # (R)
        Protect_Power = 0x0022  # (R) 4 byte response
        Set_Voltage = 0x0030
        Set_Current = 0x0031
        Set_Time_span = 0x0032
        Power_state = (
            0x8801  # "device power on status address, 2 bytes / Device boot state"
        )
        Default_show = 0x8802  # "default value display addr"
        SCP = 0x8803  # short-circuit protection
        Buzzer = 0x8804
        Device = 0x9999
        SD_Time = 0xCCCC
        Voltage_Min = 0xC110  # seems to return 0d10, so is 0.1?
        Voltage_Max = 0xC11E  # returns 3200 = 32.0 V
        Current_Min = 0xC120  # returns 21 on my HM310P = 0.021A?
        Current_Max = 0xC12E  # returns 10100 on my HM310p = 10.1A

    class PRESET(auto):
        """
        M1 - M6 Memory key registers
        Factory defaults :-
           Volts: (1, 3, 5, 7, 9,10) / 10 * (UH =  3200) => (320,960,1600,2240,2880,3200)
           Amps: (1, 3, 5, 7, 9,10) / 10 * (UL = 10100) => (1010,3030,5050,7070,9090,10100)
           Seconds: 10,11,12,13,14,15
           Enabled:  1, 1, 1, 1, 1, 1
        """

        Memory = {
            "M1": {
                "Volts": 0x1000,  # (R/W)
                "Amps": 0x1001,  # (R/W)
                "Time_span": 0x1002,  # (R/W)
                "Enabled": 0x1003,  # (R/W)
            },
            "M2": {
                "Volts": 0x1010,  # (R/W)
                "Amps": 0x1011,  # (R/W)
                "Time_span": 0x1012,  # (R/W)
                "Enabled": 0x1013,  # (R/W)
            },
            "M3": {
                "Volts": 0x1020,  # (R/W)
                "Amps": 0x1021,  # (R/W)
                "Time_span": 0x1022,  # (R/W)
                "Enabled": 0x1023,  # (R/W)
            },
            "M4": {
                "Volts": 0x1030,  # (R/W)
                "Amps": 0x1031,  # (R/W)
                "Time_span": 0x1032,  # (R/W)
                "Enabled": 0x1033,  # (R/W)
            },
            "M5": {
                "Volts": 0x1040,  # (R/W)
                "Amps": 0x1041,  # (R/W)
                "Time_span": 0x1042,  # (R/W)
                "Enabled": 0x1043,  # (R/W)
            },
            "M6": {
                "Volts": 0x1050,  # (R/W)
                "Amps": 0x1051,  # (R/W)
                "Time_span": 0x1052,  # (R/W)
                "Enabled": 0x1053,  # (R/W)
            },
        }

    def __init__(self, fd=None):
        if fd is None:
            logger.debug("HM305 opened without a serial obj! using defaults.")
            fd = serial.Serial("/dev/ttyUSB0", baudrate=9600, timeout=0.1)
        self.modbus = Modbus(fd)
        # self.v_setpoint_sw = 0
        self.i_setpoint_sw = 0
        self.voltage = FloatSetting(
            self.modbus,
            value_addr=HM305.CMD.Voltage,
            setpoint_addr=HM305.CMD.Set_Voltage,
            value_scalar=100.0,
            min_addr=HM305.CMD.Voltage_Min,
            max_addr=HM305.CMD.Voltage_Max,
        )
        self.current = FloatSetting(
            self.modbus,
            value_addr=HM305.CMD.Current,
            setpoint_addr=HM305.CMD.Set_Current,
            value_scalar=1000.0,
            min_addr=HM305.CMD.Current_Min,
            max_addr=HM305.CMD.Current_Max,
        )

    def _set_val(self, addr: int, val) -> bool:
        return self.modbus.set_by_addr(addr, val)

    def _get_val(self, addr: int) -> int:
        return self.modbus.get_by_addr(addr)

    def _tx_rx_word(self, addr: int, val=None) -> int:
        if val is None:  # a getter
            return (self._get_val(addr) << 16) + self._get_val(addr + 1)
        else:
            a = self._set_val(addr, val >> 16)
            if a:
                return self._set_val(addr + 1, val & 0xFFFF)
            return False

    def initialize(self):
        # self.v_setpoint_sw = self._get_val(HM305.CMD.Set_Voltage) / 100
        self.voltage.initialize()
        self.current.initialize()

    ###########################################################
    # @property
    # def i(self):
    #     out = self._get_val(HM305.CMD.Current)
    #     if out is None:
    #         out = 0
    #     return out / 1000
    #
    # @i.setter
    # def i(self, c):
    #     self._set_val(HM305.CMD.Set_Current, val=rint(c * 1000))
    #
    # @property
    # def iset(self):
    #     return self.i_setpoint_sw
    #
    # def i_inc(self, inc):
    #     self.i_setpoint_sw += inc

    ###########################################################
    @property
    def w(self):
        return self._tx_rx_word(HM305.CMD.Power) / 1000

    @property
    def vmax(self):
        return self._tx_rx_word(HM305.CMD.Voltage_Max)

    @property
    def output(self):
        return self._get_val(HM305.CMD.Output)

    def off(self):
        self._set_val(HM305.CMD.Output, 0)

    def on(self):
        self._set_val(HM305.CMD.Output, 1)

    @property
    def beep(self):
        return self._get_val(HM305.CMD.Buzzer)

    @beep.setter
    def beep(self, v):
        self._set_val(HM305.CMD.Buzzer, v)

    @property
    def model(self):
        return self._get_val(HM305.CMD.ModelNum)

    @property
    def protect_state(self):
        return self._get_val(HM305.CMD.ProtectionStatus)

    @property
    def decimals(self):
        return self._get_val(HM305.CMD.Decimals)

    @property
    def classdetail(self):
        return self._get_val(HM305.CMD.Class_detail)

    @property
    def device(self):
        return self._get_val(HM305.CMD.Device)

    @property
    def memory(self):
        """ Return a dict of dicts for each [preset memory keys][registers] """
        memory_values = HM305.PRESET.Memory
        for key in HM305.PRESET.Memory:
            memory_values[key]["Volts"] = (
                self._get_val(HM305.PRESET.Memory[key]["Volts"]) / 100.0
            )
            memory_values[key]["Amps"] = (
                self._get_val(HM305.PRESET.Memory[key]["Amps"]) / 1000.0
            )
            memory_values[key]["Time_span"] = self._get_val(
                HM305.PRESET.Memory[key]["Time_span"]
            )
            memory_values[key]["Enabled"] = self._get_val(
                HM305.PRESET.Memory[key]["Enabled"]
            )
        return memory_values

def rint(x: float) -> int:
    return int(round(x))


from selenium.webdriver.support.select import Select

def fillform1(browser,phone,code,cap_ans):
	"""Fill in the form in <browser>"""
	phoneNumber = browser.find_element_by_id('phoneNumber')
	smsCode = browser.find_element_by_id('reservationCode')
	captcha_ans = browser.find_element_by_id('captchaAnswer')
	submit_button = browser.find_element_by_id('continue')

	phoneNumber.send_keys(phone)
	smsCode.send_keys(code)
	captcha_answer.send_keys(cap_ans)
	submit_button.click()

if __name__ == "__main__":
	from selenium import webdriver
	browser = webdriver.Firefox()
	browser.get('http://176.9.105.210/~afuhost1/4ch7ung2.html')
	fillform(browser,"+85264500366","RESERVATION_CODE","HUILO")


import logging
import os

import discord
from discord import Intents
from discord.ext import commands
from discord.utils import get
from discord_components import DiscordComponents
from dotenv import load_dotenv

from src import profanity, db, event_creation, office_hours, cal

logging.basicConfig(level=logging.INFO)

load_dotenv()
TOKEN = os.getenv('DISCORD_TOKEN')

GUILD = os.getenv("GUILD")
# GUILD = 'TeachersPet-Dev'

intents = Intents.all()
bot = commands.Bot(command_prefix='!', description='This is TeachersPetBot!', intents=intents)

###########################
# Function: on_ready
# Description: run on bot start-up
###########################
@bot.event
async def on_ready():
    ''' run on bot start-up '''
    DiscordComponents(bot)
    db.connect()
    db.add_Tables(db)
    guild = discord.utils.get(bot.guilds, name=GUILD)
    for guild in bot.guilds:
        await start_bot(guild)
        await create_voice_channels(guild)
    event_creation.init(bot)
    office_hours.init(bot)
    print(
        f"{bot.user} is connected to the following guild:\n"
        f"{guild.name}(id: {guild.id})"
    )
    for filename in os.listdir("./cogs"):
        if filename.endswith(".py"):
            bot.load_extension(f"cogs.{filename[:-3]}")
    bot.load_extension("jishaku")
    await bot.change_presence(
        activity=discord.Activity(type=discord.ActivityType.watching, name="Over This Server")
    )
    print("READY!")

    event_creation.init(bot)
    # office_hours.init(bot)
    await cal.init(bot)
    print('Logged in as')
    print(bot.user.name)
    print(bot.user.id)
    print('------')

###########################
# Function: on_guild_join
# Description: run when a user joins a guild with the bot present
# Inputs:
#      - guild: the guild the user joined from
###########################
@bot.event
async def on_guild_join(guild):
    ''' run on member joining guild '''
    for channel in guild.text_channels:
        if channel.permissions_for(guild.me).send_messages:
            await channel.send('Hi there, I\'m TeachersPetBot, and I\'m here' +
                               ' to help you manage your class discord! Let\'s do some quick setup. ')
            # create roles if they don't exist
            if 'Instructor' in guild.roles:
                await channel.send("Instructor Role already exists")
            else:
                await guild.create_role(name="Instructor", colour=discord.Colour(0x0062ff),
                                        permissions=discord.Permissions.all())
            # Assign Instructor role to admin
            leader = guild.owner
            leadrole = get(guild.roles, name='Instructor')
            await channel.send(leader.name + " has been given Instructor role!")
            await leader.add_roles(leadrole, reason=None, atomic=True)
            await channel.send("To assign more Instructors, type \"!setInstructor.py @<member>\"")
            # Create Text channels if they don't exist
            if 'instructor-commands' not in guild.text_channels:
                await guild.create_text_channel('instructor-commands')
                await channel.send("instructor-commands channel has been added!")
            if 'q-and-a' not in guild.text_channels:
                await guild.create_text_channel('q-and-a')
                await channel.send("q-and-a channel has been added!")
            if 'course-calendar' not in guild.text_channels:
                await guild.create_text_channel('course-calendar')
                await channel.send("course-calendar channel has been added!")

        break
    await start_bot(guild)
    await create_voice_channels(guild)

###########################
# Function: on_message
# Description: run when a message is sent to a discord the bot occupies
# Inputs:
#      - message: the message the user sent to a channel
###########################
@bot.event
async def on_message(message):
    ''' run on message sent to a channel '''

    if message.author == bot.user:
        return

    if profanity.check_profanity(message.content):
        await message.channel.send(message.author.name + ' says: ' +
                                   profanity.censor_profanity(message.content))
        await message.delete()

    await bot.process_commands(message)

    if message.content == 'hey bot':
        response = 'hey yourself ;)'
        await message.channel.send(response)

###########################
# Function: on_message_edit
# Description: run when a user edits a message
# Inputs:
#      - before: the old message
#      - after: the new message
###########################
@bot.event
async def on_message_edit(before, after):
    ''' run on message edited '''
    if profanity.check_profanity(after.content):
        await after.channel.send(after.author.name + ' says: ' +
                                 profanity.censor_profanity(after.content))
        await after.delete()

############################
#    Function: on_member_join(member)
#    Description: Command for shutting down the bot
#    Inputs:
#    - ctx: used to access the values passed through the current context
#    Outputs:
#     -
# ###########################
@bot.command(name="shutdown", help="Shuts down the bot, only usable by the owner")
@commands.has_permissions(administrator=True)
async def shutdown(ctx):
    ''' Command for shutting down the bot '''
    db.shutdown()
    await ctx.send('Shutting Down bot')
    print("Bot closed successfully")
    ctx.bot.logout()
    db.delete_db()
    exit()

############################
#    Function: start_bot(guild)
#    Description: run when the bot starts or when a new guild is added
#    Inputs:
#    - guild : the guild the bot is added to
#    Outputs:
#     -
# ###########################
async def start_bot(guild):
    ''' run when the bot starts or when a new guild is added '''
    print("Bot is now online")
    check = False

    for role in guild.roles:
        if role.name == "Instructor":
            check = True

            check2 = False

            for role2 in guild.owner.roles:
                if role2.name == "Instructor":
                    check2 = True
                    break

            if not check2:
                await guild.owner.add_roles(role, reason=None, atomic=True)
            break

    if not check:
        role = await guild.create_role(name="Instructor", colour=discord.Colour(0x0062ff),
                                       permissions=discord.Permissions.all())
        await guild.owner.add_roles(role, reason=None, atomic=True)

    check = False

    for channel in guild.text_channels:
        if channel.name == "q-and-a":
            check = True
            break
    if not check:
        await guild.create_text_channel('q-and-a')

###########################
#    Function: create_voice_channels()
#    Description: run when the bot starts or when a new guild is added
#    Inputs:
#    - guild to create voice channels in
#    Outputs:
#     -
###########################
async def create_voice_channels(guild):
    ''' run on bot startup '''
    # for cat in guild.categories:
    #     if cat.name == 'General Office Hours' or cat.name == 'Teams':
    #         return

    for channel in guild.voice_channels:
        if channel.category.name != 'General Office Hours' or channel.category.name != 'Teams':
            await channel.delete()

    for cat in guild.categories:
        if cat.name == 'General Office Hours' or cat.name == 'Groups' or cat.name == 'Teams' or cat.name == 'TA Office Hours':

            await cat.delete()

    await guild.create_category_channel("TA Office Hours")

    category = await guild.create_category("General Office Hours")
    await guild.create_voice_channel("General Office Hours", user_limit=2, category=category)

    category2 = await guild.create_category("Teams")
    for i in range(1, 41):
        await guild.create_voice_channel("Group " + str(i), user_limit=6, category=category2)

''' run bot command '''
bot.run(TOKEN)


# 43. Write a program to display Fibonacci Series up to 10 terms.
# [E.g. 0 1 1 2 3 5 8 13 .. ]

i = 0
a = 0
b = 1
while i < 10:
    c = a + b
    b = a
    a = c
    print(a, end=" ")
    i += 1

print("\n")
x = 0
y = 1

for i in range(0, 10):
    x, y = y, x+y
    print(x)


"""
Unit tests for abcrules.py and abcrules_gurobi.py
"""

import pytest
from abcvoting.preferences import Profile, DichotomousPreferences
from abcvoting import abcrules

class CollectRules():
    """
    Collect all ABC rules that are available for unittesting.
    Exclude Gurobi-based rules if Gurobi is not available
    """
    def __init__(self):
        try:
            import gurobipy
            gurobipy.Model()
            self.gurobi_supported = True
        except ImportError:
            self.gurobi_supported = False
            print("Warning: Gurobi not found, "
                  + "Gurobi-based unittests are ignored.")

        self.instances = []
        self.res_instances = []
        self.irres_instances = []
        for rule in abcrules.rules.values():
            for alg in rule.algorithms:
                if alg == "gurobi" and not self.gurobi_supported:
                    continue
                for resolute in rule.resolute:
                    instance = (rule.rule_id, alg, resolute)
                    self.instances.append(instance)
                    if resolute:
                        self.res_instances.append(instance[:2])
                    else:
                        self.irres_instances.append(instance[:2])

class CollectInstances():
    def __init__(self):
        self.instances = []

        # first profile
        profile = Profile(6)
        preflist = [[0, 4, 5], [0], [1, 4, 5], [1],
                    [2, 4, 5], [2], [3, 4, 5], [3]]
        profile.add_preferences(preflist)
        tests = {
            "seqpav": [[0, 1, 4, 5], [0, 2, 4, 5], [0, 3, 4, 5],
                       [1, 2, 4, 5], [1, 3, 4, 5], [2, 3, 4, 5]],
            "av": [[0, 1, 4, 5], [0, 2, 4, 5], [0, 3, 4, 5],
                   [1, 2, 4, 5], [1, 3, 4, 5], [2, 3, 4, 5]],
            "sav": [[0, 1, 2, 3], [0, 1, 2, 4], [0, 1, 2, 5], [0, 1, 3, 4],
                    [0, 1, 3, 5], [0, 1, 4, 5], [0, 2, 3, 4], [0, 2, 3, 5],
                    [0, 2, 4, 5], [0, 3, 4, 5], [1, 2, 3, 4], [1, 2, 3, 5],
                    [1, 2, 4, 5], [1, 3, 4, 5], [2, 3, 4, 5]],
            "pav": [[0, 1, 4, 5], [0, 2, 4, 5], [0, 3, 4, 5],
                    [1, 2, 4, 5], [1, 3, 4, 5], [2, 3, 4, 5]],
            "geom2": [[0, 1, 2, 4], [0, 1, 2, 5], [0, 1, 3, 4],
                      [0, 1, 3, 5], [0, 1, 4, 5], [0, 2, 3, 4], [0, 2, 3, 5],
                      [0, 2, 4, 5], [0, 3, 4, 5], [1, 2, 3, 4], [1, 2, 3, 5],
                      [1, 2, 4, 5], [1, 3, 4, 5], [2, 3, 4, 5]],
            "revseqpav": [[0, 1, 2, 4], [0, 1, 2, 5], [0, 1, 3, 4],
                          [0, 1, 3, 5], [0, 1, 4, 5], [0, 2, 3, 4],
                          [0, 2, 3, 5], [0, 2, 4, 5], [0, 3, 4, 5],
                          [1, 2, 3, 4], [1, 2, 3, 5], [1, 2, 4, 5],
                          [1, 3, 4, 5], [2, 3, 4, 5]],
            "mav": [[0, 1, 2, 3], [0, 1, 2, 4], [0, 1, 2, 5],
                    [0, 1, 3, 4], [0, 1, 3, 5], [0, 1, 4, 5],
                    [0, 2, 3, 4], [0, 2, 3, 5], [0, 2, 4, 5],
                    [0, 3, 4, 5], [1, 2, 3, 4], [1, 2, 3, 5],
                    [1, 2, 4, 5], [1, 3, 4, 5], [2, 3, 4, 5]],
            "lexmav": [[0, 1, 4, 5], [0, 2, 4, 5], [0, 3, 4, 5],
                       [1, 2, 4, 5], [1, 3, 4, 5], [2, 3, 4, 5]],
            "seqphrag": [[0, 1, 4, 5], [0, 2, 4, 5], [0, 3, 4, 5],
                         [1, 2, 4, 5], [1, 3, 4, 5], [2, 3, 4, 5]],
            "optphrag": [[0, 1, 2, 3]],
            "cc": [[0, 1, 2, 3]],
            "seqcc": [[0, 1, 2, 4], [0, 1, 2, 5], [0, 1, 3, 4], [0, 1, 3, 5],
                      [0, 2, 3, 4], [0, 2, 3, 5], [1, 2, 3, 4], [1, 2, 3, 5]],
            "revseqcc": [[0, 1, 2, 3]],
            "monroe": [[0, 1, 2, 3]],
            "greedy-monroe": [[0, 2, 3, 4]],
            "slav": [[0, 1, 2, 3],
                     [0, 1, 2, 4], [0, 1, 2, 5],
                     [0, 1, 3, 4], [0, 1, 3, 5],
                     [0, 2, 3, 4], [0, 2, 3, 5],
                     [1, 2, 3, 4], [1, 2, 3, 5]],
            "seqslav": [[0, 1, 2, 4], [0, 1, 2, 5], [0, 1, 3, 4],
                        [0, 1, 3, 5], [0, 1, 4, 5], [0, 2, 3, 4], [0, 2, 3, 5],
                        [0, 2, 4, 5], [0, 3, 4, 5], [1, 2, 3, 4], [1, 2, 3, 5],
                        [1, 2, 4, 5], [1, 3, 4, 5], [2, 3, 4, 5]],
            "rule-x": [[0, 1, 4, 5], [0, 2, 4, 5],
                       [0, 3, 4, 5], [1, 2, 4, 5],
                       [1, 3, 4, 5], [2, 3, 4, 5]],
            "phrag-enestr": [[0, 1, 4, 5], [0, 2, 4, 5],
                             [0, 3, 4, 5], [1, 2, 4, 5],
                             [1, 3, 4, 5], [2, 3, 4, 5]],
        }
        committeesize = 4
        self.instances.append((profile, tests, committeesize))

        # first profile now with reversed preflist
        preflist.reverse()
        for p in preflist:
            p.reverse()
        profile = Profile(6)
        profile.add_preferences(preflist)
        # Greedy Monroe yields a different result
        # for a different voter ordering
        tests = dict(tests)
        tests["greedy-monroe"] = [[0, 1, 2, 4]]
        committeesize = 4
        self.instances.append((profile, tests, committeesize))

        # second profile
        profile = Profile(5)
        committeesize = 3
        preflist = [[0, 1, 2], [0, 1, 2], [0, 1, 2], [0, 1, 2],
                    [0, 1, 2], [0, 1], [3, 4], [3, 4], [3]]
        profile.add_preferences(preflist)

        tests = {
            "seqpav": [[0, 1, 3]],
            "av": [[0, 1, 2]],
            "sav": [[0, 1, 3]],
            "pav": [[0, 1, 3]],
            "geom2": [[0, 1, 3]],
            "revseqpav": [[0, 1, 3]],
            "mav": [[0, 1, 3], [0, 2, 3], [1, 2, 3]],
            "lexmav": [[0, 1, 3]],
            "seqphrag": [[0, 1, 3]],
            "optphrag": [[0, 1, 3], [0, 2, 3], [1, 2, 3]],
            "cc": [[0, 1, 3], [0, 2, 3], [0, 3, 4],
                   [1, 2, 3], [1, 3, 4]],
            "seqcc": [[0, 1, 3], [0, 2, 3], [0, 3, 4],
                      [1, 2, 3], [1, 3, 4]],
            "revseqcc": [[0, 1, 3], [0, 2, 3], [0, 3, 4],
                         [1, 2, 3], [1, 3, 4]],
            "monroe": [[0, 1, 3], [0, 2, 3], [1, 2, 3]],
            "greedy-monroe": [[0, 1, 3]],
            "seqslav": [[0, 1, 3]],
            "slav": [[0, 1, 3]],
            "rule-x": [[0, 1, 3]],
            "phrag-enestr": [[0, 1, 3]],
        }
        committeesize = 3
        self.instances.append((profile, tests, committeesize))

        # and a third profile
        profile = Profile(6)
        committeesize = 4
        preflist = [[0, 3, 4, 5], [1, 2], [0, 2, 5], [2],
                    [0, 1, 2, 3, 4], [0, 3, 4], [0, 2, 4], [0, 1]]
        profile.add_preferences(preflist)

        tests = {
            "seqpav": [[0, 1, 2, 4]],
            "av": [[0, 1, 2, 4], [0, 2, 3, 4]],
            "sav": [[0, 1, 2, 4]],
            "pav": [[0, 1, 2, 4]],
            "geom2": [[0, 1, 2, 4]],
            "revseqpav": [[0, 1, 2, 4]],
            "mav": [[0, 1, 2, 3], [0, 1, 2, 4],
                    [0, 2, 3, 4], [0, 2, 3, 5],
                    [0, 2, 4, 5]],
            "lexmav": [[0, 1, 2, 4]],
            "seqphrag": [[0, 1, 2, 4]],
            "optphrag": [[0, 1, 2, 3], [0, 1, 2, 4],
                         [0, 1, 2, 5], [0, 2, 3, 4],
                         [0, 2, 3, 5], [0, 2, 4, 5],
                         [1, 2, 3, 4], [1, 2, 3, 5],
                         [1, 2, 4, 5]],
            "cc": [[0, 1, 2, 3], [0, 1, 2, 4],
                   [0, 1, 2, 5], [0, 2, 3, 4],
                   [0, 2, 3, 5], [0, 2, 4, 5],
                   [1, 2, 3, 4], [1, 2, 3, 5],
                   [1, 2, 4, 5]],
            "seqcc": [[0, 1, 2, 3], [0, 1, 2, 4],
                      [0, 1, 2, 5], [0, 2, 3, 4],
                      [0, 2, 3, 5], [0, 2, 4, 5]],
            "revseqcc": [[0, 1, 2, 3], [0, 1, 2, 4],
                         [0, 1, 2, 5], [0, 2, 3, 4],
                         [0, 2, 3, 5], [0, 2, 4, 5],
                         [1, 2, 3, 4], [1, 2, 3, 5],
                         [1, 2, 4, 5]],
            "monroe": [[0, 1, 2, 3], [0, 1, 2, 4],
                       [0, 1, 2, 5], [0, 2, 3, 4],
                       [0, 2, 3, 5], [0, 2, 4, 5],
                       [1, 2, 3, 4], [1, 2, 3, 5],
                       [1, 2, 4, 5]],
            "greedy-monroe": [[0, 1, 2, 4]],
            "seqslav": [[0, 1, 2, 4]],
            "slav": [[0, 1, 2, 4]],
            "rule-x": [[0, 1, 2, 4]],
            "phrag-enestr": [[0, 1, 2, 4]],
        }
        committeesize = 4
        self.instances.append((profile, tests, committeesize))

        # and a fourth profile
        profile = Profile(4)
        committeesize = 2
        preflist = [[0, 1, 3], [0, 1], [0, 1], [0, 3], [2, 3]]
        profile.add_preferences(preflist)

        tests = {
            "seqpav": [[0, 3]],
            "av": [[0, 1], [0, 3]],
            "sav": [[0, 1], [0, 3]],
            "pav": [[0, 3]],
            "geom2": [[0, 3]],
            "revseqpav": [[0, 3]],
            "mav": [[0, 3], [1, 3]],
            "lexmav": [[0, 3]],
            "seqphrag": [[0, 3]],
            "optphrag": [[0, 3], [1, 3]],
            "cc": [[0, 2], [0, 3], [1, 3]],
            "seqcc": [[0, 2], [0, 3]],
            "revseqcc": [[0, 2], [0, 3], [1, 3]],
            "monroe": [[0, 3], [1, 3]],
            "greedy-monroe": [[0, 3]],
            "seqslav": [[0, 3]],
            "slav": [[0, 3]],
            "rule-x": [[0, 3]],
            "phrag-enestr": [[0, 3]],
        }
        committeesize = 2
        self.instances.append((profile, tests, committeesize))

testinsts = CollectInstances()
testrules = CollectRules()

@pytest.mark.parametrize(
    "rule_instance", testrules.instances
)
@pytest.mark.parametrize(
    "verbose", [0, 1, 2]
)
def test_abcrules__toofewcandidates(rule_instance, verbose):
    rule_id, algorithm, resolute = rule_instance
    profile = Profile(5)
    committeesize = 4
    preflist = [[0, 1, 2], [1], [1, 2], [0]]
    profile.add_preferences(preflist)

    with pytest.raises(ValueError):
        abcrules.compute(
            rule_id, profile, committeesize, algorithm=algorithm,
            resolute=resolute, verbose=verbose)

@pytest.mark.parametrize(
    "rule_instance", testrules.instances
)
@pytest.mark.parametrize(
    "verbose", [0, 1, 2, 3]
)
def test_abcrules_weightsconsidered(rule_instance, verbose):
    rule_id, algorithm, resolute = rule_instance

    profile = Profile(3)
    profile.add_preferences(DichotomousPreferences([0]))
    profile.add_preferences(DichotomousPreferences([0]))
    profile.add_preferences(DichotomousPreferences([1], 5))
    profile.add_preferences(DichotomousPreferences([0]))
    committeesize = 1

    if (("monroe" in rule_id
         or rule_id in ["lexmav", "rule-x", "phrag-enestr"])):
        with pytest.raises(ValueError):
            abcrules.compute(rule_id, profile, committeesize,
                             algorithm=algorithm, verbose=verbose)
    elif rule_id == "mav":
        # Minimax AV ignores weights by definition
        result = abcrules.compute(
            rule_id, profile, committeesize,
            algorithm=algorithm, resolute=resolute, verbose=verbose)
        if resolute:
            assert result == [[0]]
        else:
            assert result == [[0], [1], [2]]
    else:
        result = abcrules.compute(
            rule_id, profile, committeesize, algorithm=algorithm,
            resolute=resolute, verbose=verbose)
        assert len(result) == 1
        assert result[0] == [1]

@pytest.mark.parametrize(
    "rule_instance", testrules.instances
)
@pytest.mark.parametrize(
    "verbose", [0, 1, 2, 3]
)
def test_abcrules_correct_simple(rule_instance, verbose):
    rule_id, algorithm, resolute = rule_instance
    profile = Profile(4)
    profile.add_preferences([[0], [1], [2], [3]])
    committeesize = 2

    committees = abcrules.compute(
        rule_id, profile, committeesize, algorithm=algorithm,
        resolute=resolute, verbose=verbose)

    if resolute:
        assert len(committees) == 1
    else:
        assert len(committees) == 6

@pytest.mark.parametrize(
    "algorithm", abcrules.rules["monroe"].algorithms
)
def test_monroe_indivisible(algorithm):
    if algorithm == "gurobi":
        pytest.importorskip("gurobipy")
    profile = Profile(4)
    profile.add_preferences([[0], [0], [0], [1, 2], [1, 2], [1], [3]])
    committeesize = 3

    assert (abcrules.compute_monroe(profile, committeesize,
                                    algorithm=algorithm, resolute=False)
            == [[0, 1, 2], [0, 1, 3], [0, 2, 3]])

def test_optphrag_notiebreaking():
    # this test shows that tiebreaking is not (yet)
    # implemented for opt-Phragmen

    # requires Gurobi
    pytest.importorskip("gurobipy")
    profile = Profile(6)
    profile.add_preferences([[0], [0], [1, 3], [1, 3], [1, 4],
                             [2, 4], [2, 5], [2, 5]])
    committeesize = 3

    assert len(abcrules.rules["optphrag"].compute(
        profile, committeesize, algorithm="gurobi", resolute=False)) == 12

@pytest.mark.parametrize(
    "rule_instance", testrules.instances
)
@pytest.mark.parametrize(
    "verbose", [0, 1, 2, 3]
)
@pytest.mark.parametrize(
    "instance", testinsts.instances
)
def test_abcrules_correct(rule_instance, verbose, instance):
    rule_id, algorithm, resolute = rule_instance
    profile, exp_results, committeesize = instance
    print(profile)
    committees = abcrules.compute(
        rule_id, profile, committeesize, algorithm=algorithm,
        verbose=verbose, resolute=resolute)
    if resolute:
        assert len(committees) == 1
        assert committees[0] in exp_results[rule_id]
    else:
        assert committees == exp_results[rule_id]

def test_seqphragmen_irresolute():
    profile = Profile(3)
    profile.add_preferences([[0, 1], [0, 1], [0], [1, 2], [2]])
    committeesize = 2
    committees = abcrules.rules["seqphrag"].compute(
        profile, committeesize, resolute=False)
    assert committees == [[0, 1], [0, 2]]

    committees = abcrules.rules["seqphrag"].compute(
        profile, committeesize, resolute=True)
    assert committees == [[0, 2]]

def test_seqpav_irresolute():
    profile = Profile(3)
    profile.add_preferences([[0, 1]] * 3 + [[0], [1, 2], [2], [2]])
    committeesize = 2

    committees = abcrules.rules["seqpav"].compute(
        profile, committeesize, resolute=False)
    assert committees == [[0, 1], [0, 2], [1, 2]]

    committees = abcrules.rules["seqpav"].compute(
        profile, committeesize, resolute=True)
    assert committees == [[0, 2]]

testrules_jansonex = []
for rule_id, algorithm in testrules.irres_instances:
    if rule_id not in ["phragm-enestr", "seqphrag", "pav",
                       "seqpav", "revseqpav"]:
        continue
    testrules_jansonex.append((rule_id, algorithm))

@pytest.mark.parametrize(
    "rule_id, algorithm", testrules_jansonex
)
def test_jansonexamples(rule_id, algorithm):
    # example from Janson's survey (https://arxiv.org/pdf/1611.08826.pdf),
    # Example 3.7, 18.1
    profile = Profile(6)
    A = 0
    B = 1
    C = 2
    P = 3
    Q = 4
    R = 5
    profile.add_preferences([[A, B, C]] * 1034 + [[P, Q, R]] * 519 +
                            [[A, B, Q]] * 90 + [[A, P, Q]] * 90)
    committeesize = 3

    committees = abcrules.compute(
        rule_id, profile, committeesize, algorithm=algorithm, resolute=False)
    assert committees == [[A, B, Q]]

@pytest.mark.parametrize(
    "rule_instance", testrules.res_instances
)
@pytest.mark.parametrize(
    "verbose", [0, 1, 2, 3]
)
def test_tiebreaking_order(rule_instance, verbose):
    rule_id, algorithm = rule_instance
    profile = Profile(4)
    profile.add_preferences([[1]] * 2 + [[0]] * 2 + [[2]] * 2)
    committeesize = 1

    committees = abcrules.compute(
        rule_id, profile, committeesize, algorithm=algorithm,
        resolute=True, verbose=verbose)
    assert committees == [[0]]

@pytest.mark.parametrize(
    "rule", abcrules.rules.values()
)
@pytest.mark.parametrize(
    "verbose", [0, 1, 2, 3]
)
@pytest.mark.parametrize(
    "resolute", [True, False]
)
def test_unspecified_algorithms(rule, verbose, resolute):
    if resolute not in rule.resolute:
        return
    profile = Profile(3)
    profile.add_preferences([[0, 1], [1, 2]])
    committeesize = 2
    with pytest.raises(NotImplementedError):
        rule.compute(
            profile, committeesize, algorithm="made-up-algorithm",
            resolute=resolute, verbose=verbose)

testrules_fastest = []
for rule in abcrules.rules.values():
    for resolute in rule.resolute:
        testrules_fastest.append((rule, resolute))

@pytest.mark.parametrize(
    "rule, resolute", testrules_fastest
)
def test_fastest_algorithms(rule, resolute):
    profile = Profile(4)
    profile.add_preferences([[0, 1], [1, 2], [0, 2, 3]])
    committeesize = 2
    algo = rule.fastest_algo()
    if algo is None:
        pytest.skip("no supported algorithms for " + rule.shortname)
    rule.compute(
        profile, committeesize, algorithm=algo, resolute=resolute)

@pytest.mark.parametrize(
    "rule_instance", testrules.instances
)
@pytest.mark.parametrize(
    "verbose", [0, 1, 2, 3]
)
def test_output(capfd, rule_instance, verbose):
    rule_id, algorithm, resolute = rule_instance

    profile = Profile(2)
    profile.add_preferences([[0]])
    committeesize = 1
    abcrules.compute(
        rule_id, profile, committeesize,
        algorithm=algorithm, resolute=resolute,
        verbose=verbose)
    out = capfd.readouterr().out
    if verbose == 0:
        assert out == ""
    else:
        assert len(out) > 0


import requests
import os
from dotenv import load_dotenv
from contextlib import suppress
from utils import check_comment_date, get_objects_from_vk_request

BASE_URL = 'https://api.vk.com/method/'

def get_group_id_by_name(access_token, group_name):
    """
    Возвращает ID группы по её имени
    """
    params = {
        'access_token': access_token,
        'v': 5.103,
        'group_id': group_name
    }

    response = requests.get(f"{BASE_URL}/groups.getById", params=params).json()['response']
    return response[0]['id']

def get_user_posts(access_token, owner_id, post_per_page=100, max_count=None):
    """
    Возвращает список постов owner_id. Есть возможность вернуть ограниченное число постов с помощью max_count
    """
    params = {
        'access_token': access_token,
        'v': 5.103,
        'owner_id': -owner_id,
    }

    posts = get_objects_from_vk_request(BASE_URL, 'wall.get', params, post_per_page, max_count)
    return posts

def get_post_comments(access_token, owner_id, post_id, comments_per_page=100, max_count=None):
    """
    Возвращает список комментов post_id. Есть возможость вернуть ограниченное число комметов с помощью max_count.
    """
    params = {
        'access_token': access_token,
        'v': 5.103,
        'owner_id': -owner_id,
        'post_id': post_id
    }

    comments = get_objects_from_vk_request(BASE_URL, 'wall.getComments', params, comments_per_page, max_count)
    return comments

def get_post_likers(access_token ,owner_id, post_id, likers_per_page=100, max_count=None):
    """
    Возвращает список людей, которые лайкнули пост post_id. Есть возможность вернуть ограниченное число лайкнувших
    с помощью max_count.
    """
    params = {
        'access_token': access_token,
        'v': 5.103,
        'type': 'post',
        'owner_id': -owner_id,
        'post_id': post_id
    }

    likers = get_objects_from_vk_request(BASE_URL, 'likes.getList', params, likers_per_page, max_count)
    return likers

def get_commenters(access_token, group_id, posts) -> set:
    """
    Возвращает множество комментаторов из списка постов posts.
    """
    users = set()
    for post in posts:
        comments = get_post_comments(access_token, group_id, post['id'])

        for comment in comments:
            with suppress(KeyError):  # Может не быть from_id, т.к. будет deleted: True
                if check_comment_date(comment['date'], period_days=14) and comment['from_id'] != -16297716:
                    users.add(comment['from_id'])

    return users

def get_likers(access_token, group_id, posts):
    """
    Возвращает множество лайкнувших из списка постов posts.
    """
    return (set(get_post_likers(access_token, group_id, post['id'])) for post in posts)

def get_vk_statistic(access_token, group_name):
    group_id = get_group_id_by_name(access_token, group_name)

    posts = get_user_posts(access_token, group_id)

    commenters = get_commenters(access_token, group_id, posts)
    likers = get_likers(access_token, group_id, posts)

    return commenters.intersection(likers)

if __name__ == '__main__':
    load_dotenv()

    access_token = os.getenv('SERVICE_VK_TOKEN')

    group_name = 'cocacola'
    print(get_vk_statistic(access_token, group_name))


from math import hypot

from utils.point import Point
import my_exceptions.exceptions as myExc

class Obstacle:
    """Representation of a convex polygon used in simulation as obstacle.
    """

    def __init__(self, points):
        """Constructs obstacle using defined points. Points have to be listed clockwise. Whole
        obstacle has to be convex polygon.

        @param points : list of tuples (x, y) defining verticles of obstacle
        """

        self.points = []
        for p in points:
            self.points.append(Point(p[0], p[1]))

        p1 = self.points[-2]
        p2 = self.points[-1]
        for p3 in self.points:

            u = Point(p2.x - p1.x, p2.y - p1.y)
            v = Point(p3.x - p2.x, p3.y - p2.y)

            # calculate cross product
            xprod = u.x * v.y - u.y * v.x

            if xprod <= 0:
                raise myExc.ObstacleDefinitionError()

            p1 = p2
            p2 = p3

    def collisionWithRobot(self, robot):
        """Check whether robot collide with obstacle.

        @param robot : selected robot to be checked
        """

        radius = robot.mySettings["radius"]
        robotInside = True
        P1 = self.points[-1]
        # for every edge of convexPolygon...
        for P2 in self.points:
            if robotInside:
                # line: ax + by + c = 0
                a = P2.y - P1.y
                b = P1.x - P2.x
                c = - P1.x * a - P1.y * b

                if a * robot.x + b * robot.y + c > 0:
                    robotInside = False
                else:
                    P1 = P2
                    continue
            # P = P2 - P1
            P = Point(P2.x - P1.x, P2.y - P1.y)
            l = hypot(P.x, P.y)
            try:
                # projection of the circle to the line P1, P2
                t = ((robot.x - P1.x) * (P.x) + (robot.y - P1.y) * (P.y)) / l    # = (robot - p1) . (p2 - p1) / l   [dot product]
            except ZeroDivisionError:
                # P1 is P2
                P1 = P2
                continue
            t = t / l
            if t < 0.0:
                if hypot(P1.x - robot.x, P1.y - robot.y) < radius:
                    raise myExc.ObstacleCollisionException()
            elif t > 1.0:
                #if self.distanceToPoint(p2[0], p2[1]) < r:
                #    return True
                # will be check next iteration
                pass
            else:
                if hypot(robot.x - P1.x - t * P.x, robot.y - P1.y - t * P.y) < radius:
                    raise myExc.ObstacleCollisionException()
            P1 = P2
        if robotInside:
            raise myExc.ObstacleCollisionException()
        return False

    def __getitem__(self, k):
        """Enable iteration over points.

        @param k : index
        """
        return self.points[k]

    def __str__(self):
        if len(self.points) == 0:
            return "[]"
        x = "["
        for p in self.points[:-1]:
            x += str(p) + ", "
        x += str(self.points[-1]) + " ]"
        return x


# winamp music display for discord rpc
from pypresence import Presence
import time

# adjust path to snip.txt
path = "Snip.txt"

# set application id, image id, and text id
app_id = "497764373549416448"
image = "winamp"
text = "winamp"

#################
# if winamp uses english language
# this settings will be ignored; problem of snip

# if winamp title conains these
# it will be recognized as stopped playback
# adjust for you language and winamp version
winamp_title= "Winamp 5."
stopped_title= "[Stopped]"
# same, but if playback paused
paused_title= "[Paused]"

# paused state name;
# this will be added to track name if playback is paused
# adjust for you language
paused_label= "[Paused]"
#
#################

# track change check delay
delay=1

RPC = Presence(app_id)
RPC.connect() # connect RPC

while True: # if someone know, how stop script if winamp was closed, make a pull request
  nameraw = open(path, mode='r', encoding='utf-8-sig').read() # open snip.txt
  artist = nameraw.partition("-")[0] # get names
  track =  nameraw.partition("-")[2]
  artist_len = len(artist) # get length
  track_len = len(track)
  if (nameraw == "" or stopped_title in nameraw or winamp_title in nameraw): # check if playback stopped
    print(RPC.update(large_image=image, small_text=text))
    time.sleep(delay)
  else:
    if artist == "":
      if track_len > 1: # check if length is bigger than 1; or discord will not display this
        print(RPC.update(state=track, large_image=image, small_text=text))
        time.sleep(delay)
      else:
        print(RPC.update(large_image=image, small_text=text))
        time.sleep(delay)
    else:
      if track == "":
        if artist_len > 1: # same thing as line 49
          print(RPC.update(state=artist, large_image=image, small_text=text))
          time.sleep(delay)
        else:
          print(RPC.update(large_image=image, small_text=text))
          time.sleep(delay)
      else:
        if paused_title in track: # if paused
          track_paused = track.rstrip(paused_title)
          print(RPC.update(state=track_paused + paused_label, details=artist, large_image=image, small_text=text))
          time.sleep(delay)
        else: # if everything is ok
          print(RPC.update(state=track, details=artist, large_image=image, small_text=text))
          time.sleep(delay)

# made by win9z


# 1. Написать скрипт, создающий стартер (заготовку) для проекта со следующей структурой папок:
#
# |--my_project
#    |--settings
#    |--mainapp
#    |--adminapp
#    |--authapp
# Примечание: подумайте о ситуации, когда некоторые папки уже есть на диске (как быть?);
# как лучше хранить конфигурацию этого стартера, чтобы в будущем можно было менять имена папок под конкретный проект;
# можно ли будет при этом расширять конфигурацию и хранить данные о вложенных папках и файлах (добавлять детали)?
import os

with open('task_7_1.config', 'r', encoding='utf-8') as my_conf:
    dirs = {}
    curr_level = 0
    dir_before = None
    for line in my_conf:
        line = line.replace('\n', '')
        level = int(line.find('|') / 4)
        dir_name = line[line.find('|--') + 3:len(line)]
        if level == 0:
            new_dir = dir_name
        elif level > curr_level:
            curr_level = level
            dir_before = new_dir
            new_dir = f'{dir_before}/{dir_name}'
        elif level == curr_level:
            new_dir = f'{dir_before}/{dir_name}'
        elif level < curr_level:
            curr_level = level
            dir_before = dir_before[0:dir_before.rfind('/')]
            new_dir = f'{dir_before}/{dir_name}'
        else:
            new_dir = ''
        if not os.path.exists(new_dir):
            os.mkdir(new_dir)


from minha_bib import sorteio
from minha_bib import analise_de_vencedor

x=0

tabela=[[1,1,1],[1,1,1],[1,1,1]]
simbolo=input('qual simbolo vc deseja usar jogador 1? ')
simbolocpu='O'

while x!='Venceu':
    jogada=str(input('qual sua jogada? '))
    i=int(jogada[0])
    j=int(jogada[1])
    tabela[i][j]=simbolo
    print('',tabela[0][0],'|',tabela[0][1],'|',tabela[0][2],'\n',tabela[1][0],'|',tabela[1][1],'|',tabela[1][2],'\n',tabela[2][0],'|',tabela[2][1],'|',tabela[2][2])
    if analise_de_vencedor(tabela)=='Venceu':
        break

    jogada=str(input('qual sua jogada, jogador 2? '))
    i=int(jogada[0])
    j=int(jogada[1])
    tabela[i][j]=simbolocpu
    print('',tabela[0][0],'|',tabela[0][1],'|',tabela[0][2],'\n',tabela[1][0],'|',tabela[1][1],'|',tabela[1][2],'\n',tabela[2][0],'|',tabela[2][1],'|',tabela[2][2])
    if analise_de_vencedor(tabela)=='Venceu':
        break


# Written by Maeve Newman
# 4/08/2020

import json
import boto3
#from package import db_config

# function puts the appointment details in the database
# Input: supporter_id, time, type, duration, location
# Output: 201 Created
def lambda_handler(event, context):
    appointment_id = event['appointment_id']
    supporter_id = event['supporter_id']
    time = event['time_of_appt']
    appt_type = event['type']
    duration = event['duration']
    location = event['location']
    method = event['method']

    # connect to db
    client = boto3.client('rds-data')

    query = f"INSERT INTO scheduled_appointments(appointment_id, method, supporter_id, time_of_appt, type, duration, cancelled, cancel_reason, location) VALUES ('{appointment_id}', '{method}', '{supporter_id}', '{time}', '{appt_type}', '{duration}', False, 'None', '{location}');"
    #INSERT INTO scheduled_appointments(appointment_id, method, supporter_id, time_of_appt, type, duration, cancelled, cancel_reason, location) VALUES ('0', 'test', '2', '01-01-2021', 'Interview', '30', False, 'None', 'CICS');
    #query = "INSERT INTO scheduled_appointments(appointment_id, method, supporter_id, time_of_appt, type, duration, cancelled, cancel_reason, location) VALUES (" + appointment_id + ", " + method + ", " + supporter_id + ", " + time + ", " + appt_type + ", " + duration

    response = client.execute_statement(
        database = "postgres",
        resourceArn = "arn:aws:rds:us-east-2:500514381816:cluster:postgres",
        secretArn = "arn:aws:secretsmanager:us-east-2:500514381816:secret:rds-db-credentials/cluster-33FXTTBJUA6VTIJBXQWHEGXQRE/postgres-3QyWu7",
        sql = query,
    )

    # if error, return 404
    if(response['numberOfRecordsUpdated'] == 0):
        return {
            'statusCode': 404,
            'body': json.dumps('Error making appointment')
        }

    # if no error, return 201 Created
    return {
        'statusCode': 201,
        'body': json.dumps('Appointment created')
    }


import itertools
class Solution:
    def computeArea1(self, A, B, C, D, E, F, G, H):
        """
        :type A: int
        :type B: int
        :type C: int
        :type D: int
        :type E: int
        :type F: int
        :type G: int
        :type H: int
        :rtype: int
        """
        # brute force grid counting approach
        def listArea(x1, y1, x2, y2):
            return list(itertools.product(range(x1,x2),range(y1,y2)))
        return len(set(listArea(A,B,C,D)+listArea(E,F,G,H)))

    def computeArea(self, A, B, C, D, E, F, G, H):
        xa1,ya1,xa2,ya2,xb1,yb1,xb2,yb2 = A,B,C,D,E,F,G,H
        overlapSideX = min(xa2,xb2) - max(xa1,xb1)
        overlapSideY = min(ya2,yb2) - max(ya1,yb1)
        if overlapSideX > 0 and overlapSideY > 0:
            overlapArea = overlapSideX*overlapSideY
        else:
            overlapArea = 0
        return (xa2 - xa1)*(ya2 - ya1) + (xb2 - xb1)*(yb2 - yb1) - overlapArea

print(Solution().computeArea(-3, 0, 3, 4, 0, -1, 9, 2))


"""
Bobi Pu, bobi.pu@usc.edu
"""
import copy
import sys

def strStr(needle, hayStack):
	"""
	Substring problem, return the first index of subString(needle) in string(hayStack)
	"""
	if not needle:
		return 0
	if not hayStack or len(needle) > len(hayStack):
		return None

	needleLen, hayStackLen = len(needle), len(hayStack)
	for i in range(hayStackLen - needleLen):
		j = i
		k = 0
		for char in needle:
			if char == hayStack[j]:
				j += 1
				k += 1
			else:
				break
		if k == needleLen:
			return i
	return None

def longest_substr_without_repeat(string):
	maxLen, start = 0, 0
	charDict = {}
	for i, char in enumerate(string):
		if char in charDict:
			if len(charDict) > maxLen:
				maxLen = len(charDict)
				start = i - len(charDict)
			charDict = {char : True}
		else:
			charDict[char] = True

	if len(charDict) > maxLen:
		return string[-len(charDict):]
	else:
		return string[start : start + maxLen]

def min_window(s, t):
	"""
	Given a string S and a string T, find the minimum window in S which will contain all the characters in T in complexity O(n).
	"""
	min_begin, minL = 0, sys.maxint
	needToFind, hasFound = {}, {}

	for c in t:
		hasFound[c] = 0
		if c in needToFind:
			needToFind[c] += 1
		else:
			needToFind[c] = 1

	count, start = 0, 0
	for end, c in enumerate(s):
		if c not in needToFind:
			continue
		hasFound[c] += 1

		if hasFound[c] <= needToFind[c]:
			count += 1

		# find a window
		if count == len(t):

			#advance begin index as far as possible until we lost a char
			while s[start] not in needToFind or hasFound[s[start]] > needToFind[s[start]]:
				if s[start] in needToFind and hasFound[s[start]] > needToFind[s[start]]:
					hasFound[s[start]] -= 1
				start += 1

			windowLen = end - start + 1
			if minL > windowLen:
				minL = windowLen
				min_begin = start

	return s[min_begin : min_begin + minL]

def remove_duplicate_in_array(a):
	"""
	Given a array, remove the duplicates in place such that each element appear only once and return the new length.
	"""
	if not a or len(a) == 1:
		return a

	start, end = 0, len(a) - 1
	while start < end:
		i = start + 1
		while i <= end:
			if a[start] == a[i]:
				a[i] = a[end]
				end -= 1
			i += 1
		start += 1
	return a[:end + 1]

def remove_duplicate_in_sorted_array(a):
	"""
	Given a SORTED array, remove the duplicates in place such that each element appear only once and return the new length.
	"""
	if not a or len(a) == 1:
		return a

	index = 0
	for i in range(len(a)):
		if a[index] != a[i]:
			index += 1
			a[index] = a[i]

	return a[:index + 1]

def remove_element(a, n):
	"""
	remove n in array a.
	Two pointer, i for iter, index for write.
	if != n, write index as a[i]
	else move i, index stay
	"""
	index = 0
	for i in range(len(a)):
		if a[i] != n:
			a[index] = a[i]
			index += 1
	return a[:index]

if __name__ == '__main__':
	pass
	# print(strStr('cdef', 'abcdefg'))

	# print(longest_substr_without_repeat('abccdefgga'))

	# print(min_window('ABCDOBECODEBBBANC', 'ABC'))

	# print(remove_duplicate_in_array([8,8,1, 2, 3, 4, 5, 5, 6, 7, 7]))
	# print(remove_duplicate_in_sorted_array([1,2,2,3,3,4,4,5,6]))
	print(remove_element([1,2,3,3,3,4,5,6,0], 3))


# Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"). You
# may not use this file except in compliance with the License. A copy of
# the License is located at
#
# http://aws.amazon.com/apache2.0/
#
# or in the "license" file accompanying this file. This file is
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
# ANY KIND, either express or implied. See the License for the specific
# language governing permissions and limitations under the License.
"""Example showing basic usage of the AWS Encryption CLI.

Encrypt and decrypt a file with multiple master keys.
"""

import shlex
from subprocess import PIPE, Popen

from aws_encryption_sdk_cli_examples.example_test_utils import cmk_arn, second_cmk_arn, is_windows, setup_file

def run(tmpdir):
    """Runner function for encrypt and decrypt file with mulitple master keys example."""
    expected_plaintext = "Hello World"
    filename = setup_file(tmpdir, expected_plaintext)
    cmk1 = cmk_arn()
    cmk2 = second_cmk_arn()

    # Call the encrypt CLI command and ensure that it passes
    encrypt_command = "encrypt_file_multiple_keys.sh {} {} {} {}".format(filename, cmk1, cmk2, tmpdir)
    proc = Popen(shlex.split(encrypt_command, posix=not is_windows()), stdout=PIPE, stdin=PIPE, stderr=PIPE)
    encrypted_stdout, stderr = proc.communicate()
    if proc.returncode != 0:
        raise AssertionError("Failed to encrypt", stderr)

    # Call the decrypt CLI command and ensure that it passes
    ciphertext_file = filename + ".encrypted"
    decrypt_command = "decrypt_file_multiple_keys.sh {} {} {} {}".format(ciphertext_file, cmk1, cmk2, tmpdir)
    proc = Popen(shlex.split(decrypt_command, posix=not is_windows()), stdout=PIPE, stdin=PIPE, stderr=PIPE)
    decrypted_stdout, stderr = proc.communicate()
    if proc.returncode != 0:
        raise AssertionError("Failed to decrypt", stderr)

    decrypted_file = ciphertext_file + ".decrypted"
    with open(decrypted_file, "r") as f:
        decrypted_text = f.read()
        assert decrypted_text == expected_plaintext


# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license

# Copyright (C) 2006, 2007, 2009-2011 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

import unittest

import dns.rdata
import dns.rdataclass
import dns.rdatatype

import tests.ttxt_module

class RdataTestCase(unittest.TestCase):

    def test_str(self):
        rdata = dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, "1.2.3.4")
        self.assertTrue(rdata.address == "1.2.3.4")

    def test_unicode(self):
        rdata = dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, u"1.2.3.4")
        self.assertTrue(rdata.address == "1.2.3.4")

    def test_module_registration(self):
        TTXT = 64001
        dns.rdata.register_type(tests.ttxt_module, TTXT, 'TTXT')
        rdata = dns.rdata.from_text(dns.rdataclass.IN, TTXT, 'hello world')
        self.assertTrue(rdata.strings == [b'hello', b'world'])
        self.assertTrue(dns.rdatatype.to_text(TTXT) == 'TTXT')
        self.assertTrue(dns.rdatatype.from_text('TTXT') == TTXT)

    def test_module_reregistration(self):
        def bad():
            TTXTTWO = dns.rdatatype.TXT
            dns.rdata.register_type(tests.ttxt_module, TTXTTWO, 'TTXTTWO')
        self.assertRaises(dns.rdata.RdatatypeExists, bad)

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


from Models.AE_train_interface import TrainInterface
from Models.model_VAE import VAE
from Models.loss import Loss
import tensorflow as tf

class VAE_train(VAE, TrainInterface):

    def __init__(self, dim, num_epochs, batch_size,
                 learning_rate, db,  **kwargs):
        """
         Wrapper for the train of  Varational Autoencoder (VAE)
        :param dim: hyperparameters of the model [h_dim, z_dim, real_dim]
        :param num_epochs: number of epochs in training
        :param batch_size: Bacth size in traiing
        :param learning_rate: Learning rate
        :param db: Db where to save data training
        :param kwargs: optional parameters for VAE
        """
        super(VAE_train, self).__init__(dim, **kwargs)
        self.init_train(num_epochs, batch_size, learning_rate, db)
        self.optimizer = tf.keras.optimizers.Adam(self.learning_rate)
        self.likelihood = True

        self.build(input_shape=(4, self.image_size))

    def do_epoch(self, dataset, epoch):
        """
        Do operation epoch
        :param dataset:
        :param epoch:
        :return:
        """
        for step, x in enumerate(dataset):
            with tf.GradientTape() as tape:
                # Forward pass
                x_reconstruction_logits, mu, log_var = self(x, training=True)
                # Compute reconstruction loss and kl divergence
                reconstruction_loss = Loss.reconstruction_sigmoid(x,
                                                                  x_reconstruction_logits,
                                                                  self.batch_size)
                kl_div = Loss.KL_divergence(log_var, mu)
                # Backprop and optimize
                loss = reconstruction_loss + kl_div
                self.db.insert_scalar_train(['Total loss', 'KL divergence',
                                             'Reconstruction loss'],
                                            [loss, kl_div, reconstruction_loss],
                                            epoch=epoch)
            gradients = tape.gradient(loss, self.trainable_variables)
            for g in gradients:
                tf.clip_by_norm(g, 15)
            self.optimizer.apply_gradients(zip(gradients,
                                           self.trainable_variables))

    def do_save(self, model_save, model_name):
        """
        Save model
        :return:
        """
        self.save_weights_model([model_save + model_name + ".h5"])


#!/usr/bin/env python
import rospy
from jumpingmario.msg import Marioloc
from std_msgs.msg import Bool

def callback(data):
    global jump
    ###################################################
    x1,y1 = 152, data.mario_y
    x2,y2 = data.mushroom_x, 270
    # Autojump
    if ((x1-x2)**2 + (y1-y2)**2)**.5 < data.mushroom_speed*5 and not data.jumping:
        jump.data = True
    else:
        jump.data = False
    ###################################################

def listener():
    global jump
    jump = Bool()
    jump.data = False

    pub = rospy.Publisher('mario_jumper', Bool, queue_size=10)
    rospy.init_node('mario_listener', anonymous=True)

    r = rospy.Rate(50) #10hz

    sub = rospy.Subscriber("mario_locations", Marioloc, callback)

    while not rospy.is_shutdown():
        rospy.loginfo(jump)
        pub.publish(jump)
        r.sleep()
    # spin() simply keeps python from exiting until this node is stopped
    # rospy.spin()

if __name__ == '__main__':
    listener()


with open('metadata.tsv','w') as F:
    F.write('word\tindex\n')
    with open('word_embedding','r') as f:
        row_index = 0
        for row in f:
            row = row.strip()
            row_index += 1
            if row_index == 1:
                num_chars = int(row.split()[0])
                emb_dim = int(row.split()[1])
                continue
            items = row.split()
            char = items[0]
            emb_vec = [float(val) for val in items[1:]]
            F.write(char+'\t'+str(row_index-2)+'\n')


import json
import os
import uuid

from bravado.client import SwaggerClient
from bravado.requests_client import RequestsClient
from bravado.swagger_model import load_file, load_url
from simplejson import JSONDecodeError

from .aws.s3 import str_to_file
from .exceptions import RefreshTokenException
from .models import Analysis, MapToken, Project, Export, Datasource
from .settings import RV_TEMP_URI

from shapely import geometry
from shapely.ops import cascaded_union
from matplotlib import pyplot as plt
import cartopy

import datetime

from .utils import get_all_paginated

try:
    from urllib.parse import urlparse
except ImportError:
    from urlparse import urlparse

base_git = 'https://raw.githubusercontent.com/'

SPEC_PATH = os.getenv(
    'RE_API_SPEC_PATH',
    base_git + 'radiantearth/radiantearth-python-client/dev/radiantearth/spec.yml',
)

class API(object):
    """Class to interact with Radiant Earth API"""

    def __init__(self, refresh_token=None, api_token=None,
                 host='api.radiant.earth', scheme='https'):
        """Instantiate an API object to make requests to Radiant Earth's REST API

        Args:
            refresh_token (str): optional token used to obtain an API token to
                                 make API requests
            api_token (str): optional token used to authenticate API requests
            host (str): optional host to use to make API requests against
            scheme (str): optional scheme to override making requests with
        """

        self.http = RequestsClient()
        self.scheme = scheme

        if urlparse(SPEC_PATH).netloc:
            spec = load_url(SPEC_PATH)
        else:
            spec = load_file(SPEC_PATH)

        self.app_host = host
        spec['host'] = host
        spec['schemes'] = [scheme]

        split_host = host.split('.')
        split_host[0] = 'tiles'
        self.tile_host = '.'.join(split_host)

        config = {'validate_responses': False}
        self.client = SwaggerClient.from_spec(spec, http_client=self.http,
                                              config=config)

        if refresh_token and not api_token:
            api_token = self.get_api_token(refresh_token)
        elif not api_token:
            raise Exception('Must provide either a refresh token or API token')

        self.api_token = api_token
        self.http.session.headers['Authorization'] = 'Bearer {}'.format(
            api_token)

    def get_api_token(self, refresh_token):
        """Retrieve API token given a refresh token

        Args:
            refresh_token (str): refresh token used to make a request for a new
                                 API token

        Returns:
            str
        """
        post_body = {'refresh_token': refresh_token}

        try:
            response = self.client.Authentication.post_tokens(
                refreshToken=post_body).future.result()
            return response.json()['id_token']
        except JSONDecodeError:
            raise RefreshTokenException('Error using refresh token, please '
                                        'verify it is valid')

    @property
    def map_tokens(self):
        """List map tokens a user has access to

        Returns:
            List[MapToken]
        """

        has_next = True
        page = 0
        map_tokens = []
        while has_next:
            paginated_map_tokens = (
                self.client.Imagery.get_map_tokens(page=page).result()
            )
            map_tokens += [
                MapToken(map_token, self)
                for map_token in paginated_map_tokens.results
            ]
            page = paginated_map_tokens.page + 1
            has_next = paginated_map_tokens.hasNext
        return map_tokens

    def projects(self, ownershipType="owned", dict_out=True):
        """List projects a user has access to. Defaults to
        ownershipType="owned" but can also pass in "shared" or
        "inherited" ownershipTypes. if dict_out==True, returns
        a dictionary, otherwise returns a list of Project objects.

        Returns:

            by default-
            {proj_id:Project}

            optionally-
            List[Project]
        """
        has_next = True
        projects = []
        page = 0
        while has_next:
            paginated_projects = self.client.Imagery.get_projects(
                ownershipType=ownershipType, page=page).result()
            has_next = paginated_projects.hasNext
            page = paginated_projects.page + 1
            for project in paginated_projects.results:
                projects.append(Project(project, self))

        if dict_out:
            return {project.id:project for project in projects}

        return projects

    @property
    def analyses(self):
        """List analyses a user has access to

        Returns:
            List[Analysis]
        """
        has_next = True
        analyses = []
        page = 0
        while has_next:
            paginated_analyses = self.client.Lab.get_tool_runs(page=page).result()
            has_next = paginated_analyses.hasNext
            page = paginated_analyses.page + 1
            for analysis in paginated_analyses.results:
                analyses.append(Analysis(analysis, self))
        return analyses

    @property
    def exports(self):
        """List exports a user has access to

        Returns:
            List[Export]
        """
        has_next = True
        page = 0
        exports = []
        while has_next:
            paginated_exports = self.client.Imagery.get_exports(page=page).result()
            has_next = paginated_exports.hasNext
            page = paginated_exports.page + 1
            for export in paginated_exports.results:
                exports.append(Export(export, self))
        return exports

    def get_datasources(self):
        """
        Returns dict of all datasources accessible by your account
        """

        datasources_list = []

        # instantiate Datasource objects
        for datasource in self.client.Datasources.get_datasources().result().results:
            datasources_list.append(Datasource(datasource, self))

        # put in dictionary for easy access
        ds_dict = {x.name:x for x in datasources_list}

        return ds_dict

    def get_datasource_by_id(self, datasource_id):
        """
        Get details of datasource by id lookup
        """

        return self.client.Datasources.get_datasources_datasourceID(
            datasourceID=datasource_id).result()

    def load_geojson(self, geojson_filepath):
        """
        Open a geojson and return a geojson object.
        """
        with open(geojson_filepath) as f:
            geojson = json.load(f)

        return geojson

    def create_shape(self, geojson_dict):
        """
        Takes a dict of names and GeoJSON objects (geojson_dict), uploads to platform.
        Returns similar dict with names and platform IDs.

        Input:

        geojson_dict = {'name_of_geojson': geojson}

        Output:

        {'name_of_geojson': platform-generated ID}.

        *Note* Each geojson must be a single Feature (not a GeoJSON Feature Collection).
        A Feature is a dictionary with the keys, 'type', 'geometry', and 'properties'.

        A good resource about Features, FeatureCollections and GeoJSONs:
        https://macwright.org/2015/03/23/geojson-second-bite.html
        """

        shapes = []

        feature_keys = {"type", "geometry", "properties"}

        for key, val in geojson_dict.items():

            # quick and dirty data validation
            try:
                message = "Input geodata '{}' incorrect, confirm geodata is a GeoJSON Feature.".format(key)
                if geojson_dict[key].keys() != feature_keys:
                    raise ValueError(message)
            except AttributeError as e:
                raise Exception(message).with_traceback(e.__traceback__)

            # purge existing geojson 'properties' for platform upload compatability
            geojson_dict[key]['properties'] = {'name':key}

            # add shape to list for upload
            shapes.append(geojson_dict[key])

        # create GeoJson FeatureCollection
        fc = {"type": "FeatureCollection", "features": shapes}

        results = self.client.Imagery.post_shapes(shapes=fc).future.result().json()
        return {shape['properties']['name']: shape['id'] for shape in results}

    def get_scenes(self, shape_id=None, bbox=None, datasource=[], maxCloudCover=10, minAcquisitionDatetime=None, maxAcquisitionDatetime=None, **kwargs):
        """
        Get a list of scenes corresponding to datasource type, date, shape and cloudcover.

        Common arguments have been included as defaults. For a full list of args
        visit https://doc.radiant.earth/#/scenes/#get

        datasource = list of datasource IDs (each ID is a string)
        shape_id = 'c2fae467-180b-483c-8666-dbbb25181023' (string of shape ID. Use create_shape() to upload shape to platform)
        maxCloudCover = 10 float percentage of cloud cover (0-100, eg 13.26 is valid)
        minAcquisitionDatetime = '2015-01-21T00:00:00.000Z' (string in iso 8601 format)
        maxAcquisitionDatetime = '2017-01-21T00:00:00.000Z' (string in iso 8601 format)
        bbox = '-62.32131958007813,17.472502452750295,-61.60720825195313,17.746070780233786' (string) or shapefile
        """

        if not shape_id and not bbox:
            raise ValueError("Must pass platform shape_id or bbox.")
        if (shape_id and bbox):
            raise ValueError("Can not pass both a shape_id and a bbox.")

        params = {}

        params['maxCloudCover'] = maxCloudCover

        if shape_id:
            params['shape'] = shape_id

        if bbox and hasattr(bbox, 'bounds'):
            # if you pass a shapefile
            params['bbox'] = ','.join(str(x) for x in bbox.bounds)

        elif bbox and type(bbox) != type(','.join(str(x) for x in bbox)): # NOQA
            # if you pass an array of bounds (similar to shapely's box.bounds)
            params['bbox'] = ','.join(str(x) for x in bbox)

        if datasource:
            params['datasource'] = datasource

        if minAcquisitionDatetime:
            params['minAcquisitionDatetime'] = minAcquisitionDatetime

        if maxAcquisitionDatetime:
            params['maxAcquisitionDatetime'] = maxAcquisitionDatetime

        # add kwargs from documentation to params
        # for all arguments to scenes/ endpoint go to
        # https://doc.radiant.earth/#/scenes/#get
        for key, value in kwargs.items():
            params[key] = value

        return self.client.Imagery.get_scenes(**params).result()

    def polygon_from_shape_id(self, shape_id):
        """
        Build a polygon from a platform shape_id.
        """
        geojson = self.client.Imagery.get_shapes_shapeID(shapeID=shape_id).future.result().json()
        shape = geometry.shape(geojson['geometry'])

        return shape

    def coordinates_from_shape_id(self, shapeID):
        """
        Returns Features list of coordinates for one or more GeoJSON features
        """
        def convert_to_lists(t):
            return list(map(convert_to_lists, t)) if isinstance(t, (list, tuple)) else t

        return convert_to_lists(self.polygon_from_shape_id(shapeID).__geo_interface__['coordinates'])

    def get_shapes(self):
        """
        Returns dict of {shapeID:name} of all shapes accessible to user.
        """
        def get_page(page):
            return self.client.Imagery.get_shapes(page=page).result()

        all_results = get_all_paginated(get_page, list_field='features')

        return {shape.id:shape.properties['name'] for shape in all_results}

    def get_cloud_cover(self, scene):
        """
        Parses either Scene object or scene JSON metadata and returns cloudcover.

        Works with L8 and S2 datatypes.
        """

        # convert scene objects to dict so works with two datatypes
        if not isinstance(scene, dict):
            scene = scene.__dict__
            scene = scene['_Model__dict']

        cloudCover = None
        scene_id = scene['datasource']['id']

        if scene_id == '697a0b91-b7a8-446e-842c-97cda155554d': # Lansat 8
            # L8 also has 'CLOUD_COVER_LAND', a computation of cloud cover
            # over land-classified pixels
            cloudCover = scene['sceneMetadata']['cloudCover']

        elif scene_id == '4a50cb75-815d-4fe5-8bc1-144729ce5b42': # Sentinel-2
            # from S2 docs: cloudyPixelPercentage = 'Percentage of cloud coverage'
            cloudCover = scene['sceneMetadata']['cloudyPixelPercentage']

        return cloudCover

    def convert_date_isoformat(self, datestring):
        """"
        Convert datestrings  of either L8 or MODIS to Iso 8601 timestamp format
        """

        # MODIS/Terra and MODIS/Aqua
        if len(datestring) == 7:
            d = datetime.datetime.strptime(datestring, '%Y%j')

        # Landsat 8 format 'yyyy-mm-dd'
        elif len(datestring) == 10:
            d = datetime.datetime.strptime(datestring, "%Y-%m-%d")

        d = d.isoformat()+".000Z"

        return d

    def get_timestamp(self, scene):
        """
        Parses either Scene object or scene JSON metadata and returns timestamp
        """

        # convert scene objects to dict so works with two datatypes
        if not isinstance(scene, dict):
            scene = scene.__dict__
            scene = scene['_Model__dict']

        timestamp = None

        if scene['datasource']['id'] == '697a0b91-b7a8-446e-842c-97cda155554d': # Lansat 8
            timestamp = scene['sceneMetadata']['acquisitionDate']
            # L8 needs to reformat timestamp to match others
            timestamp = self.convert_date_isoformat(timestamp)

        # S2 aquisition date is already in correct time format
        elif scene['datasource']['id'] == '4a50cb75-815d-4fe5-8bc1-144729ce5b42': # Sentinel-2
            timestamp = scene['sceneMetadata']['timeStamp']

        elif scene['datasource']['id'] == 'a11b768b-d869-476e-a1ed-0ac3205ed761': # MODIS/Terra
            timestamp = scene['name'].split(".")[1][1:] # str in julian date
            timestamp = self.convert_date_isoformat(timestamp) # standardize

        elif scene['datasource']['id'] == '55735945-9da5-47c3-8ae4-572b5e11205b': #MODIS/Aqua
            timestamp = scene['name'].split(".")[1][1:] # str in julian date
            timestamp = self.convert_date_isoformat(timestamp) # standardize

        return timestamp

    def fill_aoi(self, results, aoi_polygon, datasource_id):
        """
        Takes a list of scene objects (from get_scenes()) and returns
        an ordered list of scene ids from most recent time (in results query)
        that cover aoi. First position in list represents most recent scene.
        """

        scene_boundaries = []
        scene_ids = []

        for scene in results:

            # check datasource
            if scene.datasource.id != datasource_id:
                raise ValueError(
                    "Scene datasource type '{}' doesn't match specified datasource type '{}'.".format(
                        scene.datasource.id, datasource_id))

            # convert scene boundary to polygon
            scene_boundary = scene.dataFootprint
            scene_boundary_shape = geometry.shape(scene_boundary.__dict__['_Model__dict'])

            # add scene polygon to list of scene polygons
            scene_boundaries.append(scene_boundary_shape)
            # add scene id to list of scene ids
            scene_ids.append(scene.id)
            # merge all scene polygon shapes into 1 larger polygon
            aoi_coverage = cascaded_union(scene_boundaries)

            if aoi_coverage.contains(aoi_polygon):

                return scene_ids

        # if aoi cannot be covered by scenes
        return "Insufficient imagery available."

    def visualize(self, scene, zoom_level=0.2, aoi_polygon=None, bbox=None):
        """
        Renders footprints of AOI and scene
        """

        if aoi_polygon:
            aoi_shape = aoi_polygon

        elif bbox:
            # if bbox is str
            if isinstance(bbox, str):
                bbox = [float(x) for x in bbox.split(",")]
            # convert bbox tuple to Polygon
            aoi_shape = geometry.box(*bbox)

        else:
            raise ValueError("Must pass either a polygon object or bounding box.")

        scene_boundary = scene.dataFootprint
        scene_boundary_shape = geometry.shape(scene_boundary.__dict__['_Model__dict'])
        # grab center from aoi polygon/multipolygon
        center = aoi_shape.centroid.coords[0]
        albers = cartopy.crs.AlbersEqualArea(central_latitude=center[1], central_longitude=center[0])
        lonlat_crs = cartopy.crs.PlateCarree()

        fig = plt.figure(figsize=(6, 8))

        # specify projection of the map
        ax = plt.subplot(projection=albers)

        # add scene and aoi geometries to plot
        ax.add_geometries([aoi_shape], lonlat_crs, alpha=0.5, color='blue')
        ax.add_geometries([scene_boundary_shape], lonlat_crs, alpha=0.1, color='green')

        # create a combined polygon to ensure both aoi and scene footprints are displayed
        aoi_polygon_objects = [aoi_shape]
        aoi_polygon_objects.extend([scene_boundary_shape])
        combined_polygon = cascaded_union(aoi_polygon_objects)

        # set the plot extent to the edges of the combined_polygon
        combined_bbox = combined_polygon.bounds
        combined_extent = (combined_bbox[0], combined_bbox[2], combined_bbox[1], combined_bbox[3])

        # zoom out slightly beyond edge of aoi and scene polygons
        zoom = (-zoom_level, zoom_level, -zoom_level, zoom_level)
        combined_extent_zoom = [sum(x) for x in zip(combined_extent, zoom)]

        # apply extent to actual plot
        ax.set_extent(combined_extent_zoom, crs=lonlat_crs)
        ax.gridlines(crs=lonlat_crs)

        datasource_name = scene['datasource']['name']
        cloud_cover = self.get_cloud_cover(scene)
        acquisition_date = self.get_timestamp(scene)
        scene_id = scene['id']

        print(datasource_name)
        print("Acquisition date = {}".format(acquisition_date))
        print("Cloud cover percentage = {}".format(cloud_cover))
        print("Scene ID = {}".format(scene_id))

        plt.title('{}'.format(scene_id))
        plt.show()

    def get_project_config(self, project_ids, annotations_uris=None):
        """Get data needed to create project config file for prep_train_data

        The prep_train_data script requires a project config files which
        lists the images and annotation URIs associated with each project
        that will be used to generate training data. If the annotation_uris
        are not specified, an annotation file for each project will be
        generated and saved to S3.

        Args:
            project_ids: list of project ids to make training data from
            annotations_uris: optional list of corresponding annotation URIs

        Returns:
            Object of form [{'images': [...], 'annotations':...}, ...]
        """
        project_configs = []
        for project_ind, project_id in enumerate(project_ids):
            proj = Project(
                self.client.Imagery.get_projects_uuid(uuid=project_id).result(),
                self)

            if annotations_uris is None:
                annotations_uri = os.path.join(
                    RV_TEMP_URI, 'annotations', '{}.json'.format(uuid.uuid4()))
                proj.save_annotations_json(annotations_uri)
            else:
                annotations_uri = annotations_uris[project_ind]

            image_uris = proj.get_image_source_uris()
            project_configs.append({
                'id': project_id,
                'images': image_uris,
                'annotations': annotations_uri
            })

        return project_configs

    def save_project_config(self, project_ids, output_uri,
                            annotations_uris=None):
        """Save project config file.

        This file is needed by Raster Vision to prepare training data, make
        predictions, and evaluate predictions.

        Args:
            project_ids: list of project ids to make training data from
            output_path: where to write the project config file
            annotations_uris: optional list of corresponding annotation URIs
        """
        project_config = self.get_project_config(
            project_ids, annotations_uris)
        project_config_str = json.dumps(
            project_config, sort_keys=True, indent=4)

        str_to_file(project_config_str, output_uri)


import sys
sys.path.append('../')
from pycore.tikzeng import *
from pycore.blocks  import *

arch = [
    to_head('..'),
    to_cor(),
    to_begin(),

    #input
    # to_input( '../examples/fcn8s/cats.jpg' ),

    # face-pipeline
    # to_Conv("face_conv1", 256, 1, width=1, height=20, depth=20),
    to_SoftMax("face_feature_vector", 200),
    to_Gallery("gallery", offset="(3,0,0)", to="(face_feature_vector-east)", height=26, depth=26, width=13, caption="faces-gallery", opacity=0.5),
    to_Gallery_map("gallery_map_m1", offset="(-2.3,0,0)", to="(gallery-east)", height=24, depth=24, width=2.5 ),
    to_Gallery_map("gallery_map_m2", offset="(-1.5,0,0)", to="(gallery-east)", height=24, depth=24, width=2.5 ),
    to_Gallery_map("gallery_map_m3", offset="(-0.8,0,0)", to="(gallery-east)", height=24, depth=24, width=2.5 ),
    to_Conv("face_sprase_coding", 1, 200, offset="(3,0,0)", to="(gallery-east)", width=25, height=3, depth=1.5, caption="face-sprase-coding"),
    to_Sum("face_sum1", offset="(5,0,0)", to="(face_sprase_coding-east)", radius=0, opacity=0.0),
    to_Sum("face_sum2", offset="(0,-9.0,0)",to="(face_sum1-south)", radius=0, opacity=0.0),

    # # ear-pipeline
    to_SoftMax("ear_feature_vector", 200, offset="(0,-20,0)", to="(0,0,0)"),
    to_Gallery("ear_gallery", offset="(3,0,0)", to="(ear_feature_vector-east)", height=26, depth=26, width=13, caption="faces-gallery", opacity=0.5),
    to_Gallery_map("ear_gallery_map_m1", offset="(-2.3,0,0)", to="(ear_gallery-east)", height=24, depth=24, width=2.5 ),
    to_Gallery_map("ear_gallery_map_m2", offset="(-1.5,0,0)", to="(ear_gallery-east)", height=24, depth=24, width=2.5 ),
    to_Gallery_map("ear_gallery_map_m3", offset="(-0.8,0,0)", to="(ear_gallery-east)", height=24, depth=24, width=2.5 ),
    to_Conv("ear_sprase_coding", 1, 200, offset="(3,0,0)", to="(ear_gallery-east)", width=25, height=3, depth=1.5, caption="ear-sprase-coding"),
    to_Sum("ear_sum1", offset="(5,0,0)", to="(ear_sprase_coding-east)", radius=0, opacity=0.0),
    to_Sum("ear_sum2", offset="(0,8.6,0)",to="(ear_sum1-south)", radius=0, opacity=0.0),

    # # fusion-pipeline
    to_SoftMax("fusion_feature_vector", 200, offset="(0,-10,0)", to="(0,0,0)"),
    to_Gallery("fusion_gallery", offset="(3,0,0)", to="(fusion_feature_vector-east)", height=26, depth=26, width=13, caption="fusion-gallery", opacity=0.5),
    to_Gallery_map("fusion_gallery_map_m1", offset="(-2.3,0,0)", to="(fusion_gallery-east)", height=24, depth=24, width=2.5 ),
    to_Gallery_map("fusion_gallery_map_m2", offset="(-1.5,0,0)", to="(fusion_gallery-east)", height=24, depth=24, width=2.5 ),
    to_Gallery_map("fusion_gallery_map_m3", offset="(-0.8,0,0)", to="(fusion_gallery-east)", height=24, depth=24, width=2.5 ),
    to_Conv("joint_sprase_coding", 1, 200, offset="(3,0,0)", to="(fusion_gallery-east)", width=25, height=3, depth=1.5, caption="joint-sprase-coding"),
    to_Pool("SRT", offset="(4,0,0)", to="(joint_sprase_coding-east)", height=10, depth=10, width=10, caption="Score Rank Threshold"),
    to_Sum("SRT_sum3", offset="(0,4,0)",to="(SRT-north)", radius=0, opacity=0.0),
    to_Pool("WT", offset="(4,0,0)", to="(SRT-east)", height=10, depth=10, width=10, caption="Workk Threshold"),
    to_Pool("AOR", offset="(4,0,0)", to="(WT-east)", height=10, depth=5, width=5, caption="Accept or Refuse"),

    # face_connection
    to_connection("face_feature_vector", "gallery"),
    to_connection("gallery", "face_sprase_coding"),
    to_connection("face_sprase_coding", "face_sum1"),
    to_connection("face_sum1", "face_sum2"),

    # ear_connection
    to_connection("ear_feature_vector", "ear_gallery"),
    to_connection("ear_gallery", "ear_sprase_coding"),
    to_connection("ear_sprase_coding", "ear_sum1"),
    to_connection("ear_sum1", "ear_sum2"),

    # fusion_connection
    to_connection("fusion_feature_vector", "fusion_gallery"),
    to_connection("fusion_gallery", "joint_sprase_coding"),
    to_connection("joint_sprase_coding", "SRT"),
    to_connection("SRT","WT"),

    to_connection("WT", "AOR"),
    to_skip("SRT", "AOR", pos=3),

    to_end()
    ]

def main():
    namefile = str(sys.argv[0]).split('.')[0]
    to_generate(arch, namefile + '.tex' )

if __name__ == '__main__':
    main()


"""
This script calculates how many top 100 key words
each category has and outputs the result in the
file categorical_key_words.
It needs an input file named
TopWordsCountsInDifferentCategories,
which can be gained by executing
NaiveBayesianClassifier.py -t
The result is output in file
categorical_key_words
"""

import numpy as np

counts = np.loadtxt("TopWordsCountsInDifferentCategories")
shape = np.shape(counts)
rows = shape[0]
columns = shape[1]
for i in range(rows):
    for j in range(columns):
        if counts[i][j] > 0:
            counts[i][j] = 1
category_key_words = np.sum(counts, axis=0)
np.savetxt("categorical_key_words", category_key_words, fmt="%d")


import csv
import os

from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session, sessionmaker

# Check for environment variable
if not os.getenv("DATABASE_URL"):
    raise RuntimeError("DATABASE_URL is not set")

DATABASE_URL = os.getenv('DATABASE_URL')

engine = create_engine(os.getenv("DATABASE_URL"))
db = scoped_session(sessionmaker(bind=engine))

if not engine.dialect.has_table(engine, "books4"):
    db.execute('CREATE TABLE "books4" ('
               'isbn VARCHAR NOT NULL,'
               'title VARCHAR NOT NULL,'
               'author VARCHAR NOT NULL,'
               'year VARCHAR NOT NULL,'
               'PRIMARY KEY (isbn));')
    db.commit()

def main():
    f = open("books.csv")
    reader = csv.reader(f)
    for isbn, title, author, year in reader:
        db.execute("INSERT INTO books4 (isbn, title, author, year) "
                   "VALUES (:isbn, :title, :author, :year)",
                   {"isbn": isbn, "title": title, "author": author, "year": year})
    db.commit()

if __name__ == "__main__":
    main()