from os import name
import discord
from discord import player
from discord import member
from discord import embeds
from discord.embeds import Embed
from discord.ext import tasks, commands
import json
import math
from time import sleep

"""Help messages"""
help_dict = {
    'level': discord.Embed(title="Command : level",
                           description="Give your level and experience if no user is specified. \n \
                To know someone else type : `$level @User#0001`",
                           color=0xff0000),

    'coins': discord.Embed(title="Command : coins",
                           description="Gives your amount of coins if no user is specified. \n \
               To know someone else type : `$coins @User#0001`",
                           color=0xff0000),

    'give-coins': discord.Embed(title="Command : give-coins",
                                description="This command is used to give (or remove) coins from the mentionned player. \n \
               Usage is `$give-coins @User#0001 amount` the amount can be negative to remove coins",
                                color=0xff0000),

    'richest': discord.Embed(title="Command : richest",
                             description="Sends the top 10 richest players on the server and the total amount of coins. \n \
               Usage : `$richest`, no parameter is required (or expected)",
                             color=0xff0000),

    'buy': discord.Embed(title="Command : buy",
                         description="You can buy items from the shop with this function. \n \
               It accepts the item ID or its name : `$buy 001` or `$buy Beautiful Role`",
                         color=0xff0000),

    'shop': discord.Embed(title="Command : shop",
                          description="To see the entire shop simple type `$shop`. \n \
               If you want to see only a specific item you can use `$shop item_id` or `$shop item_name`",
                          color=0xff0000),

    'inventory': discord.Embed(title="Command : inventory",
                               description="Lists all the items you own : `$inventory`. \n",
                               color=0xff0000),

    'use': discord.Embed(title="Command : shop",
                         description="Uses the item specified : `$use item_id` or `$use item_name`. \n \
               It will notify staff, they will quickly get in touch with you",
                         color=0xff0000),

    'add-item': discord.Embed(title="Command : shop",
                              description="Restricted to staff. \
               The expected arguments (in order and separated by '$') are : item_id, item_name, price, item_description, item_image. \n \
               Example : `$add-item 0001 $Role#1 $1000 $This role is important $https://imgur.com/y3ls2gX`",
                              color=0xff0000),

    'modify-item': discord.Embed(title="Command : shop",
                                 description="Restricted to staff. \
               Works similar to add-item except that the item with the id item_id will be changed with the new info provided. \n \
               Example : `$modify-item 0001 $RoleChange#1 $2000 $This role is even more important $https://imgur.com/y3ls2gX`",
                                 color=0xff0000),

    'remove-item': discord.Embed(title="Command : shop",
                                 description="Restricted to staff. \
               The item corresponding to the given item id will be deleted. \n \
               Example : `$remove-item 0001`",
                                 color=0xff0000),

    'help': discord.Embed(title='**All available commands**',
                          description='Some displayed are restricted to staff (and will not allow you to execute them)',
                          color=0xff0000),

}
fields_values = ['coins', '`$help coins`', True], ['give-coins', '`$help give-coins`', True], ['richest', '`$help richest`', True],\
                ['buy', '`$help buy`', True], ['shop', '`$help shop`', True], ['inventory', '`$help inventory`', True],\
                ['use', '`$help use`', True], ['level', '`$help level`', True], ['help', '`$help help`', True], \
                ['add-item (staff-only)', '`$help add-item`', True], ['modify-item (staff-only)', '`$help modify-item`', True], \
                ['remove-item (staff-only)', '`$help remove-item`', True]
for val in fields_values:
    help_dict['help'].add_field(name=val[0], value=val[1], inline=val[2])

allow_userIDs = [425337707825201152, 892805391870726164, 508950406076825621, 367344593911545856,
                 198373115892465664, 257501547246780416, 511165011637436416, 533584123600830466]

client = commands.Bot(command_prefix='$', help_command=None)

"""Functions"""

def update_money(change_dict: dict):
    """
    change_dict = {userID : amount,}
    with amount being positive or negative
    """
    pass

    with open('data.json', 'r') as f:
        current_info = json.load(f)

    for userID, amount in change_dict.items():
        userID = str(userID)
        if userID not in current_info:
            current_info[userID] = amount
        else:
            if current_info[userID] + amount < 30000:
                current_info[userID] += amount
            else:
                current_info[userID] = 30000

    with open('data.json', 'w') as f:
        json.dump(current_info, f, indent=4)

def get_amounts():
    """
    :return: dict with {userID : amount,}
    """
    with open('data.json', 'r') as f:
        current_info = json.load(f)

    return current_info

"""Auto-Giving Coins (activity)"""
info = {"messages": {},
        "vocal": {},
        "user_vocal": []}

#   Message Counter #
@client.event
async def on_message(msg):
    await client.process_commands(msg)
    authorID = msg.author.id

    member = await FNTK_guild.fetch_member(int(authorID))

    multiplier = 1
    for role in member.roles:
        if role.id == 923161171744411668:
            multiplier = 1.5
            break
    if authorID not in info['messages']:
        info['messages'][authorID] = 1*multiplier
    else:
        info['messages'][authorID] += 1*multiplier

#   Vocal Counter   #

@client.event
async def on_voice_state_update(user, before, after):
    userID = user.id

    if after.channel == None or after.channel.id == 893189817322602537:
        info['user_vocal'].remove(userID)
    else:
        # in vc and not afk vc
        if userID not in info['user_vocal'] and after.channel.id != 893189817322602537:
            info['user_vocal'].append(userID)
        else:  # he muted/unmuted deafened/undeafened himself/herself
            pass

@tasks.loop(seconds=10)
async def update():

    #   Update vocal amount #
    for userID in info['user_vocal']:
        member = await FNTK_guild.fetch_member(int(userID))

        multiplier = 1
        for role in member.roles:
            if role.id == 923161171744411668:
                multiplier = 1.5
                break
        if userID not in info['vocal']:
            info['vocal'][userID] = 10*multiplier
        else:
            info['vocal'][userID] += 10*multiplier

    give_dict = {}

    #   10 messages = 1 coin    #
    for userID, amount in info['messages'].items():
        #   Calculating coins   #
        if amount >= 10:  # user getting at least 1 coin
            fntk_coins = amount // 10
            info['messages'][userID] = amount % 10
        else:
            fntk_coins = 0

        if userID not in give_dict:
            give_dict[userID] = fntk_coins
        else:
            give_dict[userID] += fntk_coins

    #   1 hour of vc = 20 coins #
    for userID, time in info['vocal'].items():
        #   Calculating coins   #
        if time >= 3600:  # user getting at least 20 coins
            fntk_coins = (time // 3600)*20
            info['vocal'][userID] = time % 3600
        else:
            fntk_coins = 0

        if userID not in give_dict:
            give_dict[userID] = fntk_coins
        else:
            give_dict[userID] += fntk_coins
    # updating the levels
    with open('level.json', 'r') as f:
        lvl = json.load(f)

    for user, xp in give_dict.items():
        user = str(user)
        if user not in lvl:
            lvl[user] = {'xp': xp, 'lvl': 0}

        else:
            lvl[user]['xp'] += xp
            if lvl[user]['lvl'] < 10:
                if lvl[user]['xp'] >= (lvl[user]['lvl']+1)*1000:
                    lvl[user]['xp'] -= (lvl[user]['lvl']+1)*1000
                    lvl[user]['lvl'] += 1
            elif lvl[user]['lvl'] < 16:
                if lvl[user]['xp'] >= 10000:
                    lvl[user]['xp'] -= 10000
                    lvl[user]['lvl'] += 1
            elif lvl[user]['lvl'] < 21:
                if lvl[user]['xp'] >= 20000:
                    lvl[user]['xp'] -= 20000
                    lvl[user]['lvl'] += 1
            name = f"Level {lvl[user]['lvl']}"
            if lvl[user]['lvl'] != 0:
                roles = FNTK_guild.roles
                role = discord.utils.get(roles, name=name)
                member = await FNTK_guild.fetch_member(int(user))
                await member.add_roles(role)

    with open('level.json', 'w') as f:
        json.dump(lvl, f, indent=4)

    update_money(give_dict)

"""User Commands"""

@client.event
async def on_ready():
    global FNTK_guild
    print('Ready !')
    FNTK_guild = await client.fetch_guild(692749537219051531)
    update.start()

@client.command(name='coins')
async def coins(ctx, *user):

    current_info = get_amounts()
    return_embed = discord.Embed(description='Empty', color=6345206)

    if not user:  # wants his/her amount of coins
        authorID = ctx.message.author.id
        for userID, amount in current_info.items():
            if int(userID) == authorID:
                return_embed.description = f"**You** have {amount} coins !"

        if return_embed.description == 'Empty':
            return_embed.description = f"**You** don't have **any** coins"
        await ctx.channel.send(embed=return_embed)
    else:  # wants someone else's amount of coins
        memberID = user[0]
        for char in '<@!>':
            memberID = memberID.replace(char, '')
        member = await client.fetch_user(memberID)

        for userID, amount in current_info.items():
            if int(memberID) == int(userID):

                return_embed.description = f"**{member.name}** has {amount} coins !"

        if return_embed.description == 'Empty':
            return_embed.description = f"**{member.name}** doesn't  have **any** coins !"
        await ctx.channel.send(embed=return_embed)

@client.command(name='give-coins')
async def give_coins(ctx, user_id, amount):
    userID = ctx.message.author.id
    if userID not in allow_userIDs:
        await ctx.channel.send(embed=discord.Embed(description='You are not part of the whitelist :x:', color=6345206))
    else:

        for char in '<@!>':
            user_id = user_id.replace(char, '')

        update_money({user_id: int(amount)})
        pseudo = await client.fetch_user(user_id)
        amount = int(amount)
        if 1 < amount:
            description = f":white_check_mark: {amount} <:fanatikCoins:894584412166058014> have been given to {pseudo.mention}"
        if 1 == amount:
            description = f":white_check_mark: {amount} <:fanatikCoins:894584412166058014> has been given to {pseudo.mention}"
        elif 0 == amount:
            description = "I cannot give 0 coins."
        elif 1 == amount:
            description = f":white_check_mark: {amount-(2*amount)} <:fanatikCoins:894584412166058014> has been removed from {pseudo.mention}"
        elif 1 > amount:
            description = f":white_check_mark: {amount-(2*amount)} <:fanatikCoins:894584412166058014> have been removed from {pseudo.mention}"
        color = 6345206
        embed = discord.Embed(description=description, color=color)
        await ctx.channel.send(embed=embed)

@client.command(name='richest')
async def richest(ctx):
    dico = get_amounts()
    valeur = []
    user_list = []
    am_total = 0
    for userID, amount in dico.items():
        valeur.append(amount)
        user_list.append(userID)
        am_total += amount

    embed = discord.Embed(
        title="Richest", description="List of the richest people on the server", color=6345206)
    embed.set_thumbnail(
        url="https://cdn.discordapp.com/icons/692749537219051531/0c98647b4dd76cdecc2c670556c75f7e.png?size=4096")
    embed.add_field(name=f':bank: - Server Total',
                    value=f"{am_total} coins", inline=False)
    am_total = 0
    for i in range(10):
        rech_am = max(valeur)
        j = valeur.index(rech_am)
        if rech_am == 0:
            rech_us = None
        else:
            rech_us = await client.fetch_user(user_list[j])
            rech_us = rech_us.name
        valeur[j] = 0
        if i == 0:
            embed.add_field(
                name=f':first_place: - {rech_us}', value=f"<:fanatikCoins:894584412166058014> {rech_am} coins", inline=False)
        elif i == 1:
            embed.add_field(
                name=f':second_place: - {rech_us}', value=f"<:fanatikCoins:894584412166058014> {rech_am} coins", inline=False)
        elif i == 2:
            embed.add_field(
                name=f':third_place: - {rech_us}', value=f"<:fanatikCoins:894584412166058014> {rech_am} coins", inline=False)
        else:
            embed.add_field(
                name=f'{i+1} - {rech_us}', value=f"<:fanatikCoins:894584412166058014> {rech_am} coins", inline=False)
    await ctx.channel.send(embed=embed)

@client.command(name='buy')
async def buy(ctx, *item_id):
    with open('inventory.json', 'r') as f:
        inv = json.load(f)

    with open('shop.json', 'r') as f:
        shop = json.load(f)

    item_id = ' '.join(item_id).lower()

    authorID = ctx.message.author.id
    current_info = get_amounts()
    for userID, amount in current_info.items():
        if int(userID) == authorID:
            try:
                shop[item_id]
            except:
                for i in shop.keys():
                    if item_id == shop[i][0]:
                        item_id = i
            if amount >= shop[item_id][2]:
                if userID not in inv:
                    inv[userID] = {item_id: 1}
                else:
                    if str(item_id) in inv[userID]:
                        inv[userID][str(item_id)] += 1
                    else:
                        inv[userID][str(item_id)] = 1
                update_money({userID: -shop[item_id][2]})
                pseudo = await client.fetch_user(authorID)
                description = f'**{pseudo.name}** bought **{shop[item_id][0]}**'
            else:
                description = f"You don't have enough coins"
    embed = discord.Embed(description=description, color=6345206)
    await ctx.channel.send(embed=embed)

    with open('inventory.json', 'w') as f:
        json.dump(inv, f, indent=4)

@client.command(name='shop')
async def shop(ctx, *id):
    with open('shop.json', 'r') as f:
        shop = json.load(f)

    title = '**Boutique de TEAM FANATIK**'
    description = "Use `$shop <item name>` or `$shop <item id>` to get more details about an item.\nUse `$buy <item name>` or `$buy <item id>`to buy an item\n\n:money_with_wings: **Here are our items:**"
    color = 6345206

    new_embed = discord.Embed(
        title=title, description=description, color=color)

    msg = ""
    if id == ():
        for i in shop.items():
            new_embed.add_field(name=f"{str(i[1][0])} - <:fanatikCoins:894584412166058014> {str(i[1][2])}:",
                                value=f"{str(i[1][1])} \n`id : {str(i[0])}`", inline=False)
            msg += "ok"
    else:
        id = ' '.join(id).lower()
        id = str(id)
        description2 = "Use `$shop <item name>` or `$shop <item id>` to get more details about an item.\nUse `$buy <item name>` or `$buy <item id>`to buy an item\n\n:money_with_wings: **Here is the item you requested:**"
        new_embed = discord.Embed(
            title=title, description=description2, color=color)
        for i in shop.items():
            if i[1][0] == id or i[0] == id:
                new_embed.add_field(name=f"{str(i[1][0])} - <:fanatikCoins:894584412166058014> {str(i[1][2])}:",
                                    value=f"{str(i[1][1])} \nid : `{str(i[0])}`", inline=False)
                new_embed.set_image(url=str(i[1][3]))
                msg += "ok"
        if msg == "":
            msg = "bug"
            new_embed = discord.Embed(
                title="Error !", description="The item you asked for does not exist.", color=color)
    await ctx.channel.send(embed=new_embed)

@client.command(name='inventory')
async def inventory(ctx):
    with open('inventory.json', 'r') as f:
        inv = json.load(f)

    with open('shop.json', 'r') as f:
        shop = json.load(f)

    authorID = str(ctx.message.author.id)
    try:
        playerInv = inv[authorID]
    except KeyError:  # user has no inventory
        playerInv = {}

    member = await client.fetch_user(authorID)

    title = f"{member.name}'s inventory"
    description = "Use `$shop <item name>` or `$shop <item id>` to get more details about an item.\nUse `$buy <item name>` or `$buy <item id>`to buy an item\nUse `$use <item name>` or `$use <item id>` to use an item\n\n**You have :**"
    color = 6345206

    new_embed = discord.Embed(
        title=title, description=description, color=color)

    for i in playerInv.items():
        for y in shop.keys():
            if str(shop[i[0]][0]) == shop[y][0]:
                item_id = y
        new_embed.add_field(name=f"{str(i[1])} {str(shop[i[0]][0])}:",
                            value=f"{str(shop[item_id][1])}\nid : `{item_id}`", inline=False)
    await ctx.channel.send(embed=new_embed)

@client.command(name='help')
async def help(ctx, *cmd):
    if not cmd:
        await ctx.channel.send(embed=help_dict['help'])
    else:
        if cmd[0] in help_dict:

            await ctx.channel.send(embed=help_dict[cmd[0]])
        else:
            await ctx.channel.send(embed=discord.Embed(title='**Comand not found**', description=f'{cmd[0]} is not a valid command, type `$help` for a complete list'))

@client.command(name='use')
async def use(ctx, *item_id):
    with open('inventory.json', 'r') as f:
        inv = json.load(f)

    with open('shop.json', 'r') as f:
        shop = json.load(f)

    item_id = ' '.join(item_id).lower()
    item_id = str(item_id)
    authorID = str(ctx.message.author.id)
    color = 6345206
    if authorID in inv:
        try:
            shop[item_id]
        except:
            for i in shop.keys():
                if item_id == shop[i][0]:
                    item_id = i
        if item_id in inv[authorID]:
            inv[authorID][item_id] -= 1
            if shop[item_id][0] == "banana":
                title = "Stop everything"
                embed = discord.Embed(title=title, color=color)
                await ctx.channel.send(embed=embed)
                sleep(0.5)
                title = "Kris get the banana!"
                embed = discord.Embed(title=title, color=color)
                await ctx.channel.send(embed=embed)
                sleep(0.5)
                title = "The banana !"
                embed = discord.Embed(title=title, color=color)
                await ctx.channel.send(embed=embed)
                sleep(0.5)
                title = "**POTASSIUM**"
                description = "Kris got the banana"
                await ctx.channel.send("https://images-ext-1.discordapp.net/external/7XU8lcCaOUnWQYywFUHc4mLDqDAIYTC5Bu6MVQNVIF4/https/i.kym-cdn.com/photos/images/newsfeed/002/206/266/b53.gif")
            else:
                if inv[authorID][item_id] == 0:
                    del inv[authorID][item_id]
                member = await client.fetch_user(authorID)
                title = "Use"
                description = f"**{member.name}** used **{shop[item_id][0]}**"
                await ctx.channel.send(f"<@892805391870726164>")
        else:
            title = "Error !"
            description = "You don't own this item"
    else:
        title = "Error !"
        description = "You don't own this item"

    new_embed = discord.Embed(
        title=title, description=description, color=color)
    await ctx.channel.send(embed=new_embed)

    with open('inventory.json', 'w') as f:
        json.dump(inv, f, indent=4)

@client.command(name='add-item')
async def add_item(ctx, *msg):
    userID = ctx.message.author.id
    if userID not in allow_userIDs:
        await ctx.channel.send(embed=discord.Embed(description='You are not part of the whitelist :x:', color=6345206))
    else:
        msg = ' '.join(msg)
        msg = msg.split(" $")
        item_id, item_name, price, item_description, item_image = msg[0], msg[1].lower(
        ), msg[2], msg[3], str(msg[4])
        try:
            int(price)
        except ValueError:
            await ctx.channel.send(f"{price} isn't a valid price")
            return(None)  # To prevent the function from creating an invalid item

        try:
            int(item_id)
        except ValueError:
            await ctx.channel.send(f"{item_id}isn't a valid id")
            return(None)  # To prevent the function from creating an invalid item

        with open('shop.json', 'r') as f:
            shop = json.load(f)

        if type(item_description) == list or type(item_description) == tuple:
            item_description = ' '.join(item_description)

        shop[item_id] = [item_name, item_description, int(price), item_image]

        with open('shop.json', 'w') as f:
            json.dump(shop, f, indent=4)

        title = "Added to shop :"
        color = 6345206
        name = f"{item_name} - <:fanatikCoins:894584412166058014> {price}:"
        value = f"{item_description} \n`id:{item_id}`"
        embed = discord.Embed(title=title, color=color)
        embed.add_field(name=name, value=value)
        embed.set_image(url=item_image)
        await ctx.channel.send(embed=embed)

@client.command(name='modify-item')
async def modify_item(ctx, *msg):
    userID = ctx.message.author.id
    if userID not in allow_userIDs:
        await ctx.channel.send(embed=discord.Embed(description='You are not part of the whitelist :x:', color=6345206))
    else:
        msg = ' '.join(msg)
        msg = msg.split(" $")
        item_id, item_name, price, item_description, item_image = msg[0], msg[1].lower(
        ), msg[2], msg[3], str(msg[4])
        try:
            int(price)
        except ValueError:
            await ctx.channel.send(f"{price} isn't a valid price")
            return(None)  # To prevent the function from creating an invalid item

        try:
            int(item_id)
        except ValueError:
            await ctx.channel.send(f"{item_id}isn't a valid id")
            return(None)  # To prevent the function from creating an invalid item

        with open('shop.json', 'r') as f:
            shop = json.load(f)

        if type(item_description) == list or type(item_description) == tuple:
            item_description = ' '.join(item_description)

        shop[item_id] = [item_name, item_description, int(price), item_image]

        with open('shop.json', 'w') as f:
            json.dump(shop, f, indent=4)

        title = "Modified from shop :"
        color = 6345206
        name = f"{item_name} - <:fanatikCoins:894584412166058014> {price}:"
        value = f"{item_description} \n`id:{item_id}`"
        embed = discord.Embed(title=title, color=color)
        embed.add_field(name=name, value=value)
        embed.set_image(url=item_image)
        await ctx.channel.send(embed=embed)

@client.command(name='remove-item')
async def remove_item(ctx, item_id):
    userID = ctx.message.author.id
    if userID not in allow_userIDs:
        await ctx.channel.send(embed=discord.Embed(description='You are not part of the whitelist :x:', color=6345206))
    else:
        with open('shop.json', 'r') as f:
            shop = json.load(f)

        name = shop[item_id][0]

        del shop[item_id]

        with open('shop.json', 'w') as f:
            json.dump(shop, f, indent=4)

        title = "Removed from shop :"
        color = 6345206
        description = f"{name} was successfully removed from shop"
        embed = discord.Embed(
            title=title, description=description, color=color)
        await ctx.channel.send(embed=embed)

@client.command(name='level')
async def level(ctx, *user):
    with open('level.json', 'r') as f:
        current_info = json.load(f)

    if not user:  # wants his/her level
        authorID = ctx.message.author.id

    else:  # wants someone else's level
        authorID = user[0]
        for char in '<@!>':
            authorID = authorID.replace(char, '')
    member = await client.fetch_user(authorID)

    title = f"{member.name}'s level"
    description = "You can earn levels by sending messages or spending time in a voice channel. \nBe careful, You won't earn any xp in afk channel."
    color = 6345206
    return_embed = discord.Embed(
        title=title, description=description, color=color)

    for userID, infos in current_info.items():

        if int(userID) == int(authorID):
            name = f"Level {infos['lvl']}"
            if infos['lvl'] < 10:
                needed = (infos['lvl']+1)*1000
            elif infos['lvl'] < 16:
                needed = 10000
            elif infos['lvl'] < 21:
                needed = 20000
            value = f"xp : {infos['xp']}/{needed}\n {infos['xp']*100/needed}% to the next level"
            return_embed.add_field(name=name, value=value)

    await ctx.channel.send(embed=return_embed)

client.run('ODYxNTI5MjM5Njc3NTY2OTg2.YOLHoQ.s-UFtmIyvXQfpyd5l93o8YprY_w')


def is_pangram(sentence):
    # characters = list(sentence)
    # characters.sort()
    # isogram_characters = []
    #
    # for character in characters:
    #     if character.isalpha():
    #         pass
    #     elif character.upper() in isogram_characters:
    #         pass
    #     isogram_characters.append(character.upper())
    # return False
    characters = list(sentence)
    pangram = []
    for character in characters:
        if character.isalpha() and character not in pangram:
            pangram.append(character.lower())

    temp = 'abcdefghijklmnopqrstuvwxyz'
    pangram.sort()
    pangram = "".join(pangram)
    return pangram == temp


from selenium.webdriver.chrome.options import Options
from selenium import webdriver
import time

#how many times the message required to send will be specified here.

with open("references.dat", 'r') as mc:
    message_count = mc.read()

#used to write in message block and finding the users.

with open("message.dat", 'r') as cm:
    custom_message = cm.read()

with open('filename.dat', 'r') as un:
    all_user_names = un.read().splitlines()

#USERDATA for adding to the cookeies automatically after scanning.

options = Options()
options.add_argument("user-data-dir=~/USERDATA")

#user defines the path where chromedriver extracted.

driver = webdriver.Chrome(chrome_options = options, executable_path = '/home/tugce/WhatsappWebProject/WhatsappBot/chromedriver')
driver.get('https://web.whatsapp.com/')

# suggested waiting time.

time.sleep(3)

'''
    Procedure:

    identifies the user name, finds the message box and button, writes the message and sends.

'''

for row in all_user_names:

    user = driver.find_element_by_xpath('//span[@title = "{}"]'.format(row))
    user.click()
    msg_box = driver.find_element_by_class_name('_3u328')

    for i in range(0,int(message_count)):

        msg_box.send_keys(custom_message)
        button = driver.find_element_by_class_name('hnQHL')
        button.click()

driver.close()


import statistics
import pandas as pd
import os
os.system("cls")
df = pd.read_csv("Internet Users.csv")
users = df["InternetUsers"].tolist()
sum = 0
for i in users:
    sum+=float(i)
mean = sum/len(users)

n = len(users)
if n%2==0:
    n1 = users[n//2]
    n2 = users[(n//2)-1]
    median = (n1+n2)/2
else:
    median = users[n//2]

mode = statistics.mode(users)
print("Mode: " + str(mode))
print("Median: " + str(median))
print("Mean: " + str(mean))


"""
Problem Link: https://leetcode.com/problems/maximum-product-subarray/

Given an integer array nums, find the contiguous subarray within an array (containing at least one number) which has
the largest product.

Example 1:
Input: [2,3,-2,4]
Output: 6
Explanation: [2,3] has the largest product 6.

Example 2:
Input: [-2,0,-1]
Output: 0
Explanation: The result cannot be 2, because [-2,-1] is not a subarray.
"""
class Solution:
    def maxProduct(self, nums: List[int]) -> int:
        max_prod = min_prod = res = nums[0]

        for i in range(1, len(nums)):
            if nums[i] < 0:
                max_prod, min_prod = min_prod, max_prod

            max_prod = max(nums[i], nums[i] * max_prod)
            min_prod = min(nums[i], nums[i] * min_prod)
            res = max(res, max_prod)

        return res

# TLE
class Solution1:
    def maxProduct(self, nums: List[int]) -> int:
        max_prod = float('-inf')

        for i in range(len(nums)):
            cur_prod = 1
            for j in range(i, len(nums)):
                cur_prod *= nums[j]
                max_prod = max(max_prod, cur_prod)

        return max_prod


import numpy as np
import matplotlib.pyplot as plt
import utilities_lib as ul
import copy

from matplotlib.patches import Rectangle
import datetime as dt
from matplotlib import collections  as mc
from matplotlib.lines import Line2D

def barchart(self, X = [],Y = [],  # X-Y points in the graph.
        labels = [], legend = [],       # Basic Labelling
        color = None,  lw = 2, lw2 = 2,alpha = 1.0,  # Basic line properties
        nf = 0, na = 0,          # New axis. To plot in a new axis         # TODO: shareX option
        ax = None, position = [], projection = "2d", # Type of plot
        sharex = None, sharey = None,
        fontsize = 20,fontsizeL = 10, fontsizeA = 15,  # The font for the labels in the axis
        xlim = None, ylim = None, xlimPad = None, ylimPad = None, # Limits of vision
        ws = None, Ninit = 0,
        loc = "best",
        dataTransform = None,
        xaxis_mode = None,yaxis_mode = None,AxesStyle = None   # Automatically do some formatting :)
       ):

    # Management of the figure and properties
    ax = self.figure_management(nf, na, ax = ax, sharex = sharex, sharey = sharey,
                      projection = projection, position = position)
    ## Preprocess the data given so that it meets the right format
    X, Y = self.preprocess_data(X,Y,dataTransform)
    NpY, NcY = Y.shape
    NpX, NcX = Y.shape
    plots,plots_typ =  self.init_WidgetData(ws)

    ############### CALL PLOTTING FUNCTION ###########################

#    X = X.astype(dt.datetime)
#    self.X = self.X.astype(dt.datetime)
#    print X.shape
    High,Low, Open,Close = Y[:,0], Y[:,1], Y[:,2], Y[:,3]

#    print X
    width_unit = self.get_barwidth(X)
    dist = width_unit /2.2
    # High-Low
    linesHL = [[(X[i].astype(dt.datetime),Low[i]),(X[i].astype(dt.datetime), High[i])] for i in range(NpX)]
    linesO = [[(X[i].astype(dt.datetime) - dist,Open[i]),(X[i].astype(dt.datetime), Open[i])] for i in range(NpX)]
    linesC = [[(X[i].astype(dt.datetime),Close[i]),(X[i].astype(dt.datetime) + dist, Close[i])] for i in range(NpX)]

#    lines = [[(0, 1), (1, 1)], [(2, 3), (3, 3)], [(1, 2), (1, 3)]]
#    print mdates.date2num(X[i,0].astype(dt.datetime)), type(mdates.date2num(X[i,0].astype(dt.datetime)))
    self.zorder = self.zorder + 1  # Setting the properties
    colorFinal = self.get_color(color)

    # TODO: Handle the legend better
    if len(legend)>0:
        label_legend = legend[0]
    else:
        label_legend = None
    lcHL = mc.LineCollection(linesHL, colors= colorFinal, linewidths=lw, antialiased=True, label = label_legend)
    lcO = mc.LineCollection(linesO, colors= colorFinal, linewidths=lw2, antialiased=True)
    lcC = mc.LineCollection(linesC, colors= colorFinal, linewidths=lw2, antialiased=True)
    ax.add_collection(lcHL)
    ax.add_collection(lcO)
    ax.add_collection(lcC)

    ax.autoscale()  # TODO: The zoom is not changed if we do not say it !
#    ax.margins(0.1)
    ############### Last setting functions ###########################
    self.store_WidgetData(plots_typ, plots)     # Store pointers to variables for interaction

    self.update_legend(legend,NcY,ax = ax, loc = loc)    # Update the legend
    self.set_labels(labels)
    self.set_zoom(ax = ax, xlim = xlim,ylim = ylim, xlimPad = xlimPad,ylimPad = ylimPad)
    self.format_xaxis(ax = ax, xaxis_mode = xaxis_mode)
    self.format_yaxis(ax = ax, yaxis_mode = yaxis_mode)
    self.apply_style(nf,na,AxesStyle)

#    xfmt = mdates.DateFormatter('%b %d')
#    ax.xaxis.set_major_formatter(xfmt)
    return ax

def candlestick(self, X = [],Y = [],  # X-Y points in the graph.
        labels = [], legend = [],       # Basic Labelling
        color = None,  lw = 2, alpha = 1.0,  # Basic line properties
        nf = 0, na = 0,          # New axis. To plot in a new axis         # TODO: shareX option
        ax = None, position = [], projection = "2d", # Type of plot
        sharex = None, sharey = None,
        fontsize = 20,fontsizeL = 10, fontsizeA = 15,  # The font for the labels in the axis
        xlim = None, ylim = None, xlimPad = None, ylimPad = None, # Limits of vision
        ws = None, Ninit = 0,
        loc = "best",
        dataTransform = None,
        xaxis_mode = None,yaxis_mode = None,AxesStyle = None,   # Automatically do some formatting :)
        barwidth = None, colorup = "g", colordown = "r"
       ):

    # Management of the figure and properties
    ax = self.figure_management(nf, na, ax = ax, sharex = sharex, sharey = sharey,
                      projection = projection, position = position)
    ## Preprocess the data given so that it meets the right format
    X, Y = self.preprocess_data(X,Y,dataTransform)
    NpY, NcY = Y.shape
    plots,plots_typ =  self.init_WidgetData(ws)

    ##################### PREPROCESSING AND PLOTTING #######################

    # Prepare the data
    openp = Y[self.start_indx:self.end_indx,0]
    closep = Y[self.start_indx:self.end_indx,1]
    highp = Y[self.start_indx:self.end_indx,2]
    lowp = Y[self.start_indx:self.end_indx,3]

    dates = X[self.start_indx:self.end_indx]
    dates = ul.preprocess_dates(dates)
    if (type(barwidth) == type(None)):
        barwidth = self.get_barwidth(dates, barwidth) * 0.8

    # PLOTTING !!
    Npoints = dates.size

    OFFSET = barwidth / 2.0

    line_factor = 0.15
    barwidth_HL = barwidth * line_factor
    OFFSET_HL = barwidth_HL / 2.0

    lines = []
    patches = []
    for i in range(Npoints):
        if closep[i] >= openp[i] :
            color = colorup
            baseRectable = openp[i]
        else:
            color = colordown
            baseRectable = closep[i]

        height = np.abs(openp[i]  - closep[i])

        ## High-low line

#        line_HL = Line2D(
#            xdata=(dates[i],dates[i]), ydata=(lowp[i], highp[i]),
#            color=color,
#            linewidth=lw,
#            antialiased=True,
#        )

        rect_HL = Rectangle(
            xy=(dates[i] - OFFSET_HL, lowp[i]),
            width=barwidth_HL,
            height=highp[i] - lowp[i],
            facecolor=color,
            edgecolor=color,
        )

#        print type(dates[i]), type(OFFSET)
        ## Open Close rectangle
        rect_OP = Rectangle(
            xy=(dates[i] - OFFSET, baseRectable),
            width=barwidth,
            height=height,
            facecolor=color,
            edgecolor=color,
        )
        rect_OP.set_alpha(alpha)
#
#        lines.append(line_HL)
#        patches.append(rect_OP)

#        ax.add_line(line_HL)
        ax.add_patch(rect_OP)
        ax.add_patch(rect_HL)

#    lines = mc.LineCollection(lines)
#    ax.add_collection(lines)
#    ax.add_collection(patches)

    ax.autoscale()  # TODO: The zoom is not changed if we do not say it !
    ############### Last setting functions ###########################
    self.store_WidgetData(plots_typ, plots)     # Store pointers to variables for interaction

    self.update_legend(legend,NcY,ax = ax, loc = loc)    # Update the legend
    self.set_labels(labels)
    self.set_zoom(ax = ax, xlim = xlim,ylim = ylim, xlimPad = xlimPad,ylimPad = ylimPad)
    self.format_xaxis(ax = ax, xaxis_mode = xaxis_mode)
    self.format_yaxis(ax = ax, yaxis_mode = yaxis_mode)
    self.apply_style(nf,na,AxesStyle)

    self.plots_type.append(["candlestick"])
#    self.plots_list.append([plotting]) # We store the pointers to the plots

    data_i = [Y, ax]
    self.Data_list.append(data_i)

    return ax

def histogram(self, X,  bins = 20, orientation = "vertical",
        *args, **kwargs):

    hist, bin_edges = np.histogram(X, density=True, bins = bins)
    self.bar(bin_edges[:-1], hist, orientation = orientation,*args, **kwargs)

#    if (orientation == "vertical"):
#        self.plot(x_grid, y_values, nf = 0, *args, **kwargs)
#    else:
#        self.plot(y_values, x_grid, nf = 0, *args, **kwargs)

def Velero_graph(self, data,
                 labels = [],nf = 1,
                fake_dates = 1,
                 ws = -1):
    """ This function plots the Heiken Ashi of the data
    data[4][Ns] """

    colorFill = "green"  # Gold
    colorBg = "#7fffd4" # Aquamarine
    colorInc = '#FFD700'
    colorDec = "red"

    Close = data["Close"]
    Open = data["Open"]
    High = data["High"]
    Low = data["Low"]
    Volume = data["Volume"]
    dates = data.index

    if (fake_dates == 1):
        dates = np.array(range(len(dates)))

    Nsam = len(dates)  # Number of samples
    incBox = []
    decBox = []
    allBox = []
    # Calculate upper and lowe value of the box and the sign
    for i in range(Nsam):
        diff = Close[i] - Open[i]
    #        print diff
        if (diff >= 0):
            incBox.append(i)
        else:
            decBox.append(i)
        allBox.append(i)

    ## All_bars !!
    self.bar(dates[allBox], High[allBox] - Low[allBox], bottom = Low[allBox],
             barwidth = 0.1, color = colorFill, ws = ws, nf = 1)

    self.bar(dates[allBox], abs(Open[allBox] - Close[allBox]),
             bottom = np.min((Close[allBox],Close[allBox]),axis = 0),
             barwidth = 0.9, color = colorDec, ws = ws, nf = 0)

#    ## Increasing bars !!
#    self.bar(dates[incBox], Close[incBox] - Open[incBox], bottom = Open[incBox],
#             width = 0.9, color = colorInc, ws = ws, nf = nf)
#    self.bar(dates[incBox], High[incBox] - Close[incBox], bottom = Close[incBox],
#             width = 0.1, color = colorFill, ws = ws, nf = 0)
#    self.bar(dates[incBox], Open[incBox] - Low[incBox], bottom = Low[incBox],
#             width = 0.1, color = colorFill, ws = ws, nf = 0)
#
#    ## Decreasing bars !!
#    self.bar(dates[decBox], Open[decBox] - Close[decBox], bottom = Close[decBox],
#             width = 0.9, color = colorDec, ws = ws, nf = 0)
#    self.bar(dates[decBox], High[decBox] - Open[decBox], bottom = Open[decBox],
#             width = 0.1, color = colorFill, ws = ws, nf = 0)
#    self.bar(dates[decBox], Close[decBox] - Low[decBox], bottom = Low[decBox],
#             width = 0.1, color = colorFill, ws = ws, nf = 0)

#
    plt.ylim(min(Low)* (0.95))

#     Plot the volume
    self.bar(dates, Volume, alpha = 0.5,
             barwidth = 0.9, color = colorBg, ws = ws, nf = 0, na = 1)

    plt.ylim(plt.ylim()[0], max(Volume)* 4)

def Heiken_Ashi_graph(self, data, labels = [], nf = 1):
    r_close = data["Close"].values
    r_open = data["Open"].values
    r_max = data["High"].values
    r_min = data["Low"].values
    x_close  = (r_close + r_open + r_max + r_min)/4
    x_open = (r_close[1:] + x_close[:-1])/2  # Mean of the last

    # Insert the first open sin we cannot calcualte the prevoius
    # The other opion is to eliminate the first of everyone
    x_open = np.insert(x_open, 0, r_open[0], axis = 0)

#    print x_close.shape, x_open.shape
    x_max = np.max(np.array([r_max,x_close,x_open]), axis = 0)
    x_min = np.min(np.array([r_min,x_close,x_open]), axis = 0)

    ### Lets create another pandas dataframe with this data
    new_data = copy.deepcopy(data)
    new_data["Close"] = x_close
    new_data["Open"] = x_open
    new_data["High"] = x_max
    new_data["Low"] = x_min

    self.Velero_graph(new_data, labels = [], nf = 1)

#    x_close  = np.mean(data,0)
#    x_open = data[0][1:] + upper_box[:-1]  # Mean of the last

def plot_timeSeriesRange(self, X, Y, sigma, k = 1.96, nf = 0, legend = ["95% CI f(x)"]):
    # Plots the time series with its 1.96 percent interval
    gl = self
    gl.plot(X,Y, nf = 0,legend = legend)
    gl.plot_filled(X, np.concatenate([Y - 1.9600 * sigma,
           Y + 1.9600 * sigma],axis = 1), alpha = 0.5, nf = 0)

def plot_timeRegression(self,Xval, Yval, sigma,
                        Xtr, Ytr,sigma_eps = None,
                        labels = ["Gaussian Process Estimation","Time","Price"], nf = 0):
    # This is just a general plotting funcion for a timeSeries regression task:
    # Plot the function, the prediction and the 95% confidence interval based on
    # the MSE
    # eps is the estimated noise of the training samples.
    """
    sigma is the std of each of the validation samples
    sigma_eps is the considered observation noise
    """

    Xval = ul.fnp(Xval)
    Yval = ul.fnp(Yval)
    Xtr = ul.fnp(Xtr)
    Ytr = ul.fnp(Ytr)

    sigma = ul.fnp(sigma)
    sigma_eps = ul.fnp(sigma_eps)

    gl = self
    gl.plot(Xval,Yval, labels = labels, legend = ["Estimated Mean"], nf = nf)

    gl.plot_filled(Xval, np.concatenate([Yval - 1.9600 * sigma,
           Yval + 1.9600 * sigma],axis = 1), alpha = 0.5, legend = ["95% CI f(x)"])

    # If we are given some observaiton noise we also plot the estimation of it
    if type(sigma_eps) != type(None):
        # Ideally we have a func that tells us for each point, what is the observation noise.
        # We are suposed to know what is those values for training,
        # TODO: And for testing ? Would that help ? I think we are already assuming so in the computation of K.
        # The inner gaussian process can also be specified "alpha", we will research more about that later.
        # I guess it is for hesterodasticity.
        # We are gonna consider that the observation noise of the predicted samples is homocedastic.
        sigma = np.sqrt(sigma**2 + ul.fnp(sigma_eps)[0]**2)
        # TODO: maybe in the future differentiate between sigma_eps and dy
        gl.plot_filled(Xval, np.concatenate([Yval - 1.9600 * sigma,
               Yval + 1.9600 * sigma],axis = 1), alpha = 0.2, legend = ["95% CI y(x)"])

    # TODO: what is this     ec='None'

    if type(sigma_eps) != type(None):
        if (ul.fnp(sigma_eps).size == 1):
            sigma_eps = np.ones((Xtr.size,1)) * sigma_eps
        plt.errorbar(Xtr.ravel(), Ytr, sigma_eps, fmt='k.', markersize=10, label=u'Observations')
    else:
        gl.scatter(Xtr, Ytr, legend = ["Training Points"], color = "k")

def putamadere(wd):
    ## Previous velero plotting
    # The width of the bowes is the same for all and the x position is given by
    # the position

    ## Obtain the 4 parameters of the square
    ## Box parameters

    """ WE are gonna plot the Velas in one axis and the volume in others """

    ####### Plot all the cubes !!!!
    fig, ax = plt.subplots()

    fig.facecolor = colorBg

    for i in range(Ns):
        # Calculate upper and lowe value of the box and the sign
        diff = r_close[i] - r_open[i]
#        print diff
        if (diff >= 0):
            low_box = r_open[i]
            sign = colorInc
        else:
            low_box = r_close[i]
            sign = colorDec

        # Create the box
        ax.broken_barh([(date_indx[i] + 0.05, 1 - 0.1)],
                        (low_box, abs(diff)),
                         facecolors=sign)

        # Create the box upper line
        ax.broken_barh([(date_indx[i] + 0.45, 0.1)],
                        (low_box + abs(diff), r_max[i] - low_box + abs(diff)),
                         facecolors= "red")

        # Create the box lower line
        ax.broken_barh([(date_indx[i] + 0.45, 0.1)],
                        (r_min[i] , low_box - r_min[i]),
                         facecolors= "red")

    """ PLOT VOLUME """
    ax1_2 = ax.twinx()

    #ax1_2.plot(date, (ask-bid))
#    print volume.shape
#    print len(date)
    ax1_2.bar(date, volume, facecolor= colorFill,alpha=.5)
#    ax1_2.fill_between(date, 0, volume, facecolor= colorFill,alpha=.5)

#    broken_barh ( xranges, yrange, **kwargs)
#        xranges	sequence of (xmin, xwidth)
#        yrange	 sequence of (ymin, ywidth)

    plt.title(labels[0])
    plt.xlabel(labels[1])
    plt.ylabel(labels[2])

    if (len(labels) >3 ):
        plt.legend(labels[3])

#    plt.grid()
    plt.show()


from __future__ import annotations

import typing

if typing.TYPE_CHECKING:
    import hikari

    EventImpl = typing.Callable[..., typing.Coroutine[typing.Any, typing.Any, None]]

__all__: tuple[str, ...] = ("mark",)

def mark(event_impl: EventImpl) -> EventImpl:
    setattr(event_impl, "__mark__", get_event_type(event_impl))
    return event_impl

def get_event_type(event_impl: EventImpl) -> hikari.Event:
    return typing.get_type_hints(event_impl)["event"]


import sys

sys.path.append("../")
import os
import time
import argparse
import numpy as np

import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.tensorboard import SummaryWriter
import torch.backends.cudnn as cudnn

from utils import dataloader, GaussianBlurAll, AverageMeter, save_model, accuracy
from models import AlexNetCifar10

# Training settings
parser = argparse.ArgumentParser()
parser.add_argument(
    "--no-cuda", action="store_true", default=False, help="Disables CUDA training."
)
parser.add_argument("--seed", type=int, default=42, help="Random seed.")
parser.add_argument(
    "--mode",
    type=str,
    choices=["normal", "blur-all", "blur-half-epochs", "blur-step", "blur-half-data"],
    help="Training mode.",
)
parser.add_argument(
    "--blur-val", action="store_true", default=False, help="Blur validation data."
)
parser.add_argument("--exp-name", "-n", type=str, default="", help="Experiment name.")
parser.add_argument(
    "--sigma", "-s", type=float, default=1, help="Sigma of Gaussian Blur."
)
parser.add_argument(
    "--kernel-size",
    "-k",
    type=int,
    nargs=2,
    default=(7, 7),
    help="Kernel size of Gaussian Blur.",
)
parser.add_argument(
    "--epochs", "-e", type=int, default=60, help="Number of epochs to train."
)
parser.add_argument(
    "--start-epoch",
    default=0,
    type=int,
    metavar="N",
    help="manual epoch number (useful on restarts)",
)
parser.add_argument("--batch-size", "-b", type=int, default=64, help="Batch size.")
parser.add_argument("--lr", type=float, default=0.01, help="Initial learning rate.")
parser.add_argument(
    "--weight-decay",
    "-w",
    type=float,
    default=5e-4,
    help="Weight decay (L2 loss on parameters).",
)
parser.add_argument(
    "--resume",
    default="",
    type=str,
    metavar="PATH",
    help="path to latest checkpoint (default: none)",
)

def main():
    args = parser.parse_args()
    if args.exp_name == "":
        print(
            "ERROR: USE '--exp-name' or '-n' option to define this experiment's name."
        )
        sys.exit()

    # directories settings
    os.makedirs("../logs/outputs", exist_ok=True)
    os.makedirs("../logs/models/{}".format(args.exp_name), exist_ok=True)

    OUTPUT_PATH = "../logs/outputs/{}.log".format(args.exp_name)
    MODEL_PATH = "../logs/models/{}/".format(args.exp_name)

    if os.path.exists(OUTPUT_PATH):
        print(
            "ERROR: This '--exp-name' is already used. Use another name for this experiment."
        )
        sys.exit()

    # recording outputs
    sys.stdout = open(OUTPUT_PATH, "w")
    sys.stderr = open(OUTPUT_PATH, "a")

    # tensorboardX
    writer = SummaryWriter(log_dir="../logs/tb/{}".format(args.exp_name))

    # cuda settings
    args.cuda = not args.no_cuda and torch.cuda.is_available()
    device = torch.device("cuda:0" if args.cuda else "cpu")
    print("device: {}".format(device))

    # for fast training
    cudnn.benchmark = True

    np.random.seed(args.seed)
    torch.manual_seed(args.seed)
    if args.cuda:
        torch.cuda.manual_seed(args.seed)

    # data settings
    trainloader, testloader, _ = dataloader(batch_size=args.batch_size)

    # Model, Criterion, Optimizer
    model = AlexNetCifar10().to(device)
    criterion = nn.CrossEntropyLoss().to(device)
    optimizer = optim.SGD(
        model.parameters(), lr=args.lr, momentum=0.9, weight_decay=args.weight_decay
    )

    # optionally resume from a checkpoint
    if args.resume:
        if os.path.isfile(args.resume):
            print("=> loading checkpoint '{}'".format(args.resume))
            checkpoint = torch.load(args.resume)
            args.start_epoch = checkpoint["epoch"]
            model.load_state_dict(checkpoint["state_dict"])
            optimizer.load_state_dict(checkpoint["optimizer"])
            print(
                "=> loaded checkpoint '{}' (epoch {})".format(
                    args.resume, checkpoint["epoch"]
                )
            )
        else:
            print("=> no checkpoint found at '{}'".format(args.resume))

    # print settings
    print("=" * 5 + " settings " + "=" * 5)
    print("TRAINING MODE: {}".format(args.mode))
    if args.mode == "blur-step":
        print("### BLUR CHANGING STEPS ###")
        print("Step: 1-10 -> 11-20 -> 21-30 -> 31-40 -> 41-{}".format(args.epochs))
        print("Sigma: 4 -> 3 -> 2 -> 1 -> none")
        # print('Kernel-size: (25, 25) -> (19, 19) -> (13, 13) -> (7, 7) -> none')
        print("#" * 20)
    elif args.mode == "blur-half-epochs":
        print("### NO BLUR FROM EPOCH {:d} ###".format(args.epochs // 2))
        print("Sigma: {}".format(args.sigma))
        # print('Kernel-size: {}'.format(tuple(args.kernel_size)))  # radius = sigma * 3 * 2 + 1
    elif args.mode == "blur-all":
        print("Sigma: {}".format(args.sigma))
        # print('Kernel-size: {}'.format(tuple(args.kernel_size)))  # radius = sigma * 3 * 2 + 1
    if args.blur_val:
        print("VALIDATION MODE: blur-val")
    print("Random seed: {}".format(args.seed))
    print("Epochs: {}".format(args.epochs))
    print("Learning rate: {}".format(args.lr))
    print("Weight_decay: {}".format(args.weight_decay))
    print()
    print(model)
    print("=" * 20)
    print()

    # training
    print("Start Training...")
    train_time = time.time()
    blur = True
    for epoch in range(
        args.start_epoch, args.epochs
    ):  # loop over the dataset multiple times
        if args.mode == "normal":
            blur = False
        elif args.mode == "blur-step":
            ### BLUR-STEP SETTINGS ###
            if epoch < 10:
                args.sigma = 4
                # args.kernel_size = (25, 25)  # radius = sigma * 3 * 2 + 1
            elif epoch < 20:
                args.sigma = 3
                # args.kernel_size = (19, 19)
            elif epoch < 30:
                args.sigma = 2
                # args.kernel_size = (13, 13)
            elif epoch < 40:
                args.sigma = 1
                # args.kernel_size = (7, 7)
            else:
                blur = False
        elif args.mode == "blur-half-epochs":
            if epoch >= args.epochs // 2:
                blur = False

        # ===== train mode =====
        train_acc = AverageMeter("train_acc", ":6.2f")
        train_loss = AverageMeter("train_loss", ":.4e")
        model.train()
        for i, data in enumerate(trainloader, 0):
            # get the inputs; data is a list of [inputs, labels]
            inputs, labels = data[0], data[1].to(device)

            # Blur images
            if blur:
                if args.mode == "blur-half-data":
                    half1, half2 = inputs.chunk(2)
                    # blur first half images
                    half1 = GaussianBlurAll(half1, (0, 0), args.sigma)
                    inputs = torch.cat((half1, half2))
                else:
                    inputs = GaussianBlurAll(inputs, (0, 0), args.sigma)
            inputs = inputs.to(device)

            # zero the parameter gradients
            optimizer.zero_grad()

            # forward + record
            outputs = model(inputs)
            loss = criterion(outputs, labels)
            acc1 = accuracy(outputs, labels, topk=(1,))
            train_loss.update(loss.item(), inputs.size(0))
            train_acc.update(acc1[0], inputs.size(0))

            # backward + optimize
            loss.backward()
            optimizer.step()

        # record the values in tensorboard
        writer.add_scalar("loss/train", train_loss.avg, epoch + 1)  # average loss
        writer.add_scalar("acc/train", train_acc.avg, epoch + 1)  # average acc

        # ===== val mode =====
        val_acc = AverageMeter("val_acc", ":6.2f")
        val_loss = AverageMeter("val_loss", ":.4e")
        model.eval()
        with torch.no_grad():
            for data in testloader:
                inputs, labels = data[0], data[1].to(device)
                if args.blur_val:
                    inputs = GaussianBlurAll(inputs, (0, 0), args.sigma)
                inputs = inputs.to(device)
                outputs = model(inputs)
                loss = criterion(outputs, labels)
                acc1 = accuracy(outputs, labels, topk=(1,))
                val_loss.update(loss.item(), inputs.size(0))
                val_acc.update(acc1[0], inputs.size(0))

        # record the values in tensorboard
        writer.add_scalar("loss/val", val_loss.avg, epoch + 1)  # average loss
        writer.add_scalar("acc/val", val_acc.avg, epoch + 1)  # average acc

        # ===== save the model =====
        if (epoch + 1) % 10 == 0:
            save_model(
                {
                    "epoch": epoch + 1,
                    "arch": "alexnet-cifar10",
                    "val_loss": val_loss.avg,
                    "val_acc": val_acc.avg,
                    "state_dict": model.state_dict(),
                    "optimizer": optimizer.state_dict(),
                },
                MODEL_PATH,
                epoch + 1,
            )

    print("Finished Training")
    print("Training time elapsed: {:.4f}mins".format((time.time() - train_time) / 60))
    print()

    writer.close()  # close tensorboardX writer

if __name__ == "__main__":
    run_time = time.time()
    main()
    mins = (time.time() - run_time) / 60
    hours = mins / 60
    print("Total run time: {:.4f}mins, {:.4f}hours".format(mins, hours))


import socket
from threading import Thread

print("""
\033[1;31m\033[1;37m
███╗   ███╗ █████╗ ██╗  ██╗██╗██████╗  ██████╗
████╗ ████║██╔══██╗██║  ██║██║██╔══██╗██╔═══██╗
██╔████╔██║███████║███████║██║██████╔╝██║   ██║
██║╚██╔╝██║██╔══██║██╔══██║██║██╔══██╗██║   ██║
██║ ╚═╝ ██║██║  ██║██║  ██║██║██║  ██║╚██████╔╝
╚═╝     ╚═╝╚═╝  ╚═╝╚═╝  ╚═╝╚═╝╚═╝  ╚═╝ ╚═════╝

\033[1;31mSERVER SIDE                   coded by  kiana\033[1;31m\033[1;37m""")
print("")

# server address
SERVER_HOST = input("input ur address: " ) # u can change this with ur ip private or server
SERVER_PORT = 5500 # i'll use this port
separator_token = "<sep>" # to separate client name and message

# initialize
client_sockets = set()
# tcp socket
s = socket.socket()
# make reusable port
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# bind socket
s.bind((SERVER_HOST, SERVER_PORT))
# listen
s.listen(5)
print(f"[!] Listening as {SERVER_HOST}:{SERVER_PORT}")

# lsiten the client
def listen_client(cs):
  while True:
    try:
      # keep listening a message from socket
      msg = cs.recv(1024).decode()
    except Exception as e:
      # if client no longer connected, remove it from server
      print(f"[!] Error: {e}")
      client_sockets.remove(cs)
    else:
      # replace <sep> if server get an message
      msg = msg.replace(separator_token, ": ")
    # iterate
    for client_socket in client_sockets:
      # send message
      client_socket.send(msg.encode())

while True:
  # keep listening for new connections
  client_socket, client_address = s.accept()
  print(f"[!] {client_address} connected")
  # add new connection
  client_sockets.add(client_socket)
  # start new thread to listen client messages
  t = Thread(target=listen_client, args=(client_socket,))
  t.daemon = True
  # start thread
  t.start()

# close socket (client)
for cs in client_sockets:
  cs.close()
# close socket (server)
s.close()


"""\
Tensorflow skin lesion classification example
"""
import argparse
import os
import random
import sys
from datetime import datetime

import imgaug.augmenters as iaa
import numpy as np
# os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import optimizers

import models
import utils
from dataset import ISICClassification

# Set seed value
seed_value = 50
os.environ['PYTHONHASHSEED'] = str(seed_value)
random.seed(seed_value)
np.random.seed(seed_value)
tf.random.set_seed(seed_value)

def main(args):
    # Print settings
    for k, v in vars(args).items():
        print(f'{k}: {v}')

    display_step = 5
    num_classes = 8
    size = (224, 224, 3)  # size of images

    # Runtime initialization will not allocate all memory on GPU
    physical_devices = tf.config.list_physical_devices('GPU')
    try:
        tf.config.experimental.set_memory_growth(physical_devices[0], True)
    except:
        # Invalid device or cannot modify virtual devices once initialized.
        pass
    # Create checkpoints dir
    os.makedirs('saved_models', exist_ok=True)

    optimizer = optimizers.SGD(learning_rate=args.learning_rate, momentum=0.9)
    loss_fn = keras.losses.SparseCategoricalCrossentropy(from_logits=False)

    # model = models.vgg16(input_shape=size, num_classes=num_classes, classifier_activation='softmax')
    model = models.resnet50(input_shape=size, num_classes=num_classes, classifier_activation='softmax')
    model.build(input_shape=size)
    model.summary()

    if args.checkpoints:
        if os.path.exists(args.checkpoints):
            print(f'Loading checkpoints: {args.checkpoints}')
            model.load_weights(args.checkpoints)
        else:
            print(f'Checkpoints `{args.checkpoints}` not found', file=sys.stderr)

    os.makedirs("logs/scalars/", exist_ok=True)
    logdir = "logs/scalars/" + datetime.now().strftime("%Y%m%d-%H%M%S") + f"-{args.name}"
    summary_writer = tf.summary.create_file_writer(logdir)

    if args.train:
        # Same augs as C++
        train_aug = iaa.Sequential([
            iaa.Resize(size=size[:-1], interpolation='cubic'),
            iaa.Fliplr(p=0.5),
            iaa.Flipud(p=0.5),
            iaa.Rotate(rotate=(-180, 180)),
            iaa.AdditivePoissonNoise(lam=(0, 10)),
            iaa.GammaContrast(gamma=(.8, 1.5)),
            iaa.GaussianBlur(sigma=(.0, .8)),
            iaa.CoarseDropout(p=(.02, .1), size_percent=(0.02, 0.05), per_channel=0.5),
        ])

        val_aug = iaa.Sequential([iaa.Resize(size=size[:-1], interpolation='cubic')])

        training_dataset = ISICClassification(args.dataset, 'training', args.batch_size, train_aug)
        training_tfdata = training_dataset.map_samples(args.epochs)
        training_iter = iter(training_tfdata)

        validation_dataset = ISICClassification(args.dataset, 'validation', args.batch_size, val_aug, shuffle=False)
        validation_tfdata = validation_dataset.map_samples(args.epochs)
        validation_iter = iter(validation_tfdata)

        train_loss = tf.keras.metrics.Mean(name='train_loss')
        train_metric = tf.keras.metrics.SparseCategoricalAccuracy(name='train_accuracy')
        val_metric = tf.keras.metrics.SparseCategoricalAccuracy(name='val_accuracy')

        best_accuracy = 0.
        for e in range(1, args.epochs + 1):
            train_loss.reset_states()
            train_metric.reset_states()
            val_metric.reset_states()

            total_preds = []
            total_labels = []
            for step in range(1, len(training_dataset)):
                images, labels = next(training_iter)

                # Run the optimization to update W and b values
                with tf.GradientTape() as tape:
                    pred = model(images)
                    loss = loss_fn(labels, pred)
                total_preds.append(pred)
                total_labels.append(labels)

                gradients = tape.gradient(loss, model.trainable_variables)

                # Update W and b following gradients
                optimizer.apply_gradients(zip(gradients, model.trainable_variables))

                # Log loss and metric
                train_loss.update_state(loss)
                train_metric.update_state(labels, pred)
                if step % display_step == 0:
                    print("\rTraining {:d}/{:d} (batch {:d}/{:d}) - Loss: {:.4f} - Accuracy: {:.4f}".format(
                        e, args.epochs, step, len(training_dataset), train_loss.result(), train_metric.result()
                    ), end="", flush=True)

            cm = utils.calculate_confusion_matrix(tf.concat(total_labels, axis=0), tf.concat(total_preds, axis=0))
            with summary_writer.as_default():
                tf.summary.scalar('loss/' + train_loss.name, train_loss.result(), step=e - 1)
                tf.summary.scalar('accuracy/' + train_metric.name, train_metric.result(), step=e - 1)
                tf.summary.image("cm/training_cm", cm, step=e)

            total_preds = []
            total_labels = []

            # Do validation
            print("\nValidation {:d}/{:d}".format(e, args.epochs), end="", flush=True)
            for step in range(1, len(validation_dataset)):
                images, labels = next(validation_iter)
                pred = model(images)
                val_metric.update_state(labels, pred)
                total_preds.append(pred)
                total_labels.append(labels)

            cm = utils.calculate_confusion_matrix(tf.concat(total_labels, axis=0), tf.concat(total_preds, axis=0))
            with summary_writer.as_default():
                tf.summary.scalar('accuracy/' + val_metric.name, val_metric.result(), step=e - 1)
                tf.summary.image("cm/validation_cm", cm, step=e)

            # Compute accuracy and save checkpoints
            accuracy = val_metric.result()
            print(" - Accuracy: {:.4f}".format(accuracy), flush=True)

            if accuracy > best_accuracy:
                print(f"Saving checkpoints (accuracy: {accuracy:.4f} > {best_accuracy:.4f})", flush=True)
                best_accuracy = accuracy
                model.save_weights(f'saved_models/{args.name}.h5')

    if args.test:
        # Test model on test set
        test_aug = iaa.Sequential([iaa.Resize(size=size[:-1], interpolation='cubic')])
        test_dataset = ISICClassification(args.dataset, 'test', args.batch_size, test_aug)
        test_tfdata = test_dataset.map_samples(1)
        tensorboard = keras.callbacks.TensorBoard(log_dir=logdir)
        results = model.evaluate(test_tfdata, verbose=1, callbacks=[tensorboard])
        print("Test set loss and accuracy:", results)

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument('dataset', metavar='DATASET_YAML_PATH')
    parser.add_argument('-e', '--epochs', type=int, metavar='INT', default=50)
    parser.add_argument('-b', '--batch-size', type=int, metavar='INT', default=32)
    parser.add_argument('-l', '--learning-rate', type=float, metavar='FLOAT', default=1e-3)
    parser.add_argument('-n', '--name', metavar='DIR', help='Experiment name', default='isic_class')
    parser.add_argument('-c', '--checkpoints', metavar='CHECKPOINTS_PATH', help='Continue training from a checkpoint')
    parser.add_argument('--train', dest='train', action='store_true', help='Do train')
    parser.add_argument('--no-train', dest='train', action='store_false', help='Do not train')
    parser.add_argument('--test', dest='test', action='store_true', help='Do inference')
    parser.add_argument('--no-test', dest='test', action='store_false', help='Do not inference')
    parser.set_defaults(train=True, test=False)

    main(parser.parse_args())


import sys

while True:
    try:
        n = input("Please enter an integer: ")
        n = int(n)
        break
    except ValueError:
        print("Error: ", sys.exc_info()[0])
        raise ValueError("Mal ingreso")
print("Great, you successfully entered an integer!")


import pandas as pd
from time import time
from nltk.sentiment import SentimentIntensityAnalyzer

DATASET = "amazon_reviews_us_Grocery_v1_00.tsv"

rtime = time()

print("loading dataset...")
ds = pd.read_table(DATASET, error_bad_lines=False, header=0, warn_bad_lines=False)
print("done!")

# Drop null rows
ds = ds.dropna()

sia = SentimentIntensityAnalyzer()

def sentiment_heuristic(row):
    return sia.polarity_scores(row)['compound']

#ds = ds.head()

print("calculating sentiment...")
ds["sentiment_score"] = ds["review_body"].apply(sentiment_heuristic)
print("done!")

ds.to_csv("sentiment_ds.csv")

rtime = time() - rtime
print("The program ran in", rtime, "seconds")


import operator
import os

import torch
from parse import parse

from core.tags import *

__all__ = ['Saver']

class Saver(object):
    def __init__(self, config, save_range=50):
        self.config = config
        self.save_range = save_range
        self.param_dir = os.path.join(self.config.ckpt_path, 'param')
        if not os.path.exists(self.param_dir):
            os.makedirs(self.param_dir)

        self.params = self.get_params_on_path(self.config.max_to_keep)
        self.best_perf, self.best_list = self.get_best_perf()

    def get_best_perf(self):
        perf = None

        best_epochs = list()
        if os.path.exists(self.param_dir):
            file_list = os.listdir(self.param_dir)
            for param in file_list:
                parsed_list = parse(BEST_CKPT, param)
                if parsed_list:
                    best_epoch = parsed_list[0]
                    best_epochs.append(best_epoch)

        best_epochs = sorted(best_epochs)

        # best_ckpt = os.path.join(self.param_dir, BEST
        if len(best_epochs) > 0:
            ckpt = torch.load(os.path.join(self.param_dir, BEST_CKPT.format(best_epochs[-1])))
            perf = ckpt[PERFORMANCE]

        return perf, best_epochs

    def get_params_on_path(self, max_to_keep):
        params = []
        if os.path.exists(self.param_dir):
            file_list = os.listdir(self.param_dir)
            for param in file_list:
                parsed_list = parse(CKPT_FMT, param)
                if parsed_list:
                    epoch = parsed_list[0]
                    params.append(epoch)

                    params = sorted(params)
                    params = params[-max_to_keep:]

        return params

    def load(self):
        model, optim, step, epoch = self.create()

        if self.params:
            ckpt = torch.load(os.path.join(self.param_dir, CKPT_FMT.format(self.params[-1])),
                              map_location=self.config.device)
            model.load_state_dict(ckpt[STATE])
            model.to(self.config.device)
            optim.load_state_dict(ckpt[OPTIM])  # may create new optimizer

            step = ckpt[STEP]
            epoch = ckpt[EPOCH]
            print("Loaded the model at {} epoch and {} step".format(epoch, step))
        else:
            print("Start from scratch ... ")

        return model, optim, step, epoch

    def load_target(self, target_epoch):
        model, optim, step, epoch = self.create()

        for dirpath, dirnames, filenames in os.walk(self.param_dir):
            for filename in filenames:
                parsed_list = parse(CKPT_FMT, filename)
                if parsed_list is not None:
                    epoch = parsed_list[-1]
                    if epoch == target_epoch:
                        ckpt = torch.load(
                            os.path.join(self.param_dir, filename))
                        model.load_state_dict(ckpt[STATE])
                        optim.load_state_dict(ckpt[OPTIM])
                        step = ckpt[STEP]
                        epoch = ckpt[EPOCH]

                        return model, optim, step, epoch

        raise Exception('Cannot find specific model: epoch %d' % target_epoch)

    def save(self, model, optim, step, epoch, performance=None, perf_op='gt'):
        if perf_op == 'gt':
            _op = operator.gt
        elif perf_op == 'lt':
            _op = operator.lt
        else:
            raise ValueError("perf_op ({})is not supported".format(perf_op))

        filename_to_save = os.path.join(self.param_dir, CKPT_FMT.format(epoch))

        torch.save(
            {
                STATE: model.state_dict(),
                OPTIM: optim.state_dict(),
                STEP: step,
                EPOCH: epoch,
                PERFORMANCE: performance
            },
            filename_to_save
        )
        self.params.append(epoch)

        if len(self.params) > self.config.max_to_keep:
            param_to_del = self.params.pop(0)
            filepath_to_del = os.path.join(self.param_dir,
                                           CKPT_FMT.format(param_to_del))
            os.remove(filepath_to_del)

        if performance:
            quot = epoch // self.save_range
            lquot = 0
            if len(self.best_list) > 0:
                latest_best_epoch = self.best_list[-1]
                lquot = latest_best_epoch // self.save_range

            if quot > lquot:
                # save new perf
                filename_to_save = os.path.join(self.param_dir, BEST_CKPT.format(epoch))
                torch.save(
                    {
                        STATE: model.state_dict(),
                        OPTIM: optim.state_dict(),
                        STEP: step,
                        EPOCH: epoch,
                        PERFORMANCE: performance
                    },
                    filename_to_save
                )
                self.best_perf = performance
                self.best_list.append(epoch)

            if not self.best_perf or _op(performance, self.best_perf):
                if len(self.best_list) > 0:
                    param_to_del = self.best_list.pop()  # get last best perf
                    filepath_to_del = os.path.join(self.param_dir, BEST_CKPT.format(param_to_del))
                    os.remove(filepath_to_del)  # remove

                torch.save(
                    {
                        STATE: model.state_dict(),
                        OPTIM: optim.state_dict(),
                        STEP: step,
                        EPOCH: epoch,
                        PERFORMANCE: performance
                    },
                    os.path.join(self.param_dir, BEST_CKPT.format(epoch))
                )
                self.best_perf = performance
                self.best_list.append(epoch)

    def create(self):
        model = self.config.model(**self.config.model_param).to(self.config.device)
        if hasattr(model, 'init_weights'):
            model.init_weights()

        if hasattr(model, 'transfer_weights') and hasattr(self.config, 'transfer_param'):
            model.transfer_weights(**self.config.transfer_param)

        optim = self.config.optim(model.parameters(), **self.config.optim_param)
        step = 0
        epoch = -1
        return model, optim, step, epoch


import os

import requests

from flask import Flask, request, redirect
from flask_cors import CORS

app = Flask(__name__)
CORS(app)

def render_rows(form):
    return "".join(
        map(lambda f: f"""

                {f[0]}
                {f[1]}

        """, form.items())
    )

def create_message(form):
    subject = "New submission"
    for key in "name", "Name", "email", "Email":
        name = form.get(key)
        if name:
            subject += f" from {name}"
            break
    html = f"""

New submission

    {render_rows(form)}

"""
    return {
        "from": os.environ["EMAIL_FROM"],
        "to": os.environ["EMAIL_TO"],
        "subject": subject,
        "html": html,
    }

@app.route("/", methods=["POST"])
def send_email():
    domain = os.environ["MG_DOMAIN"]
    key = os.environ["MG_API_KEY"]
    url = f"https://api.mailgun.net/v3/{domain}/messages"
    form = request.form
    resp = requests.post(url, data=create_message(form), auth=("api", key))
    resp.raise_for_status()
    return redirect(os.environ["REDIRECT_URL"])


def solution(str1, str2):
    answer = 0

    str1_list = [str1[i-2:i].upper() for i in range(2, len(str1) + 1) if str1[i-2:i].isalpha()]
    str2_list = [str2[i-2:i].upper() for i in range(2, len(str2) + 1) if str2[i-2:i].isalpha()]

    inter = set(str1_list) & set(str2_list)
    union = set(str1_list) | set(str2_list)

    # 만약 공집합일경우 65536이라는 조건이 있다
    if len(union) == 0:
        answer = 65536
    else:
        # 각 부분 문자열에서 교집합의 원소의 해당하는 값의 개수가 가장 적게나온쪽이 교집합의 수가된다.
        inter_cnt_list = [min(str1_list.count(s), str2_list.count(s)) for s in inter]
        # 각 부분 문자열에서 합집합의 원소의 해당하는 값의 개수가 가장 많이나온쪽이 합집합의 개수가된다.
        union_cnt_list = [max(str1_list.count(s), str2_list.count(s)) for s in union]

        inter_cnt = sum(inter_cnt_list)
        union_cnt = sum(union_cnt_list)

        answer = (inter_cnt / union_cnt) * 65536

    return int(answer)

# print(solution("FRANCE", "french"))
print(solution("handshake", "shake hands"))
# print(solution("aa1+aa2", "AAAA12"))
# print(solution("E=M*C^2", "e=m*c^2"))


from colorama import init
init()
from colorama import Fore, Back, Style
import numpy as np

size = 30

lst = np.array(["'"]*30 + ['♡', '♧'])

for i in range(0, size):
    if i == 0:
        print(Fore.YELLOW + "★".center(size, " "))
    elif i % 2 == 0 and i > 0:
        print(Fore.GREEN + ''.join(np.random.choice(lst, size=i)).center(size, " "))
    else:
        print(Fore.RED + ("'"*(i+1)).center(size, " "))

for i in range(5):
    print(Fore.GREEN + "■".center(size, " "))

init(autoreset=True)
print()
print(Back.RED + "Merry Christmas...!!".center(size+2, " "))
print()


from .Base    import *;
from .Log     import Log;
from .Stage   import Stage;

class Delivery(Base):

	__tablename__ = "Deliveries";
	__repr_list__ = ("started", "stage", "ignored", "ended", "log_start",
	                 "log_end");

	id        = Column(Integer,               primary_key=True);
	started   = Column(DateTime,              nullable=False, default=datetime.now);
	stage     = Column(Enum(Stage),           nullable=False, default=Stage.INIT);
	ignored   = Column(Boolean,               nullable=False, default=False, index=True);
	ended     = Column(DateTime,              nullable=True,                 index=True);
	log_start = Column(ForeignKey('Logs.id'), nullable=False);
	log_end   = Column(ForeignKey('Logs.id'), nullable=True);

	re_log_start = relationship("Log", foreign_keys=[log_start]);
	re_log_end   = relationship("Log", foreign_keys=[log_end]);
	re_gathering = relationship("Gathering", back_populates="re_delivery", uselist=False);

	def __init__(self,
			started   : datetime = None,
			stage     : Stage    = None,
			ignored   : bool     = None,
			ended     : datetime = None,
			log_start : Log      = None,
			log_end   : Log      = None):
		self.started      = started;
		self.stage        = stage;
		self.ignored      = ignored;
		self.ended        = ended;
		self.re_log_start = log_start;
		self.re_log_end   = log_end;


# -*- coding: utf-8 -*-
"""
Created on Fri May 10 02:18:03 2019

@author: 吳嵩裕
"""

import pandas as pd
import numpy as np
import torch

from torch import nn, optim
from torch.autograd import Variable
import torch.nn.functional as F

from sklearn.utils import shuffle

net = torch.nn.Sequential()
net.add_module("dropout1",torch.nn.Dropout(p=0.2))
net.add_module("dense1",torch.nn.Linear(784,500))
net.add_module("relu1",torch.nn.ReLU())
net.add_module("dropout2",torch.nn.Dropout(p=0.5))
net.add_module("dense2",torch.nn.Linear(500,300))
net.add_module("relu2",torch.nn.ReLU())
net.add_module("dropout3",torch.nn.Dropout(p=0.5))
net.add_module("dense3",torch.nn.Linear(300,25))

use_gpu = torch.cuda.is_available()
if use_gpu:
    net = net.cuda()
    print ('USE GPU')
else:
    print ('USE CPU')

criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(net.parameters(), lr=0.001)

print ("1. Loading data")
train1 = pd.read_csv("train_data.csv").values
train = shuffle(train1)
test  = pd.read_csv("test_data.csv").values

print ("2. Converting data")
X_data  = train[:, 1:].reshape(train.shape[0], 1, 28, 28)
X_data  = X_data.astype(float)
X_data /= 255.0
X_data  = torch.from_numpy(X_data);
X_label = train[:,0];
X_label = X_label.astype(int);
X_label = torch.from_numpy(X_label);
X_label = X_label.view(train.shape[0],-1);
print (X_data.size(), X_label.size())

print ("3. Training phase")
nb_train = train.shape[0]
nb_epoch = 1000000
nb_index = 0
nb_batch = 5491

for epoch in range(nb_epoch):
    if nb_index + nb_batch >= nb_train:
        nb_index = 0
    else:
        nb_index = nb_index + nb_batch

    mini_data  = Variable(X_data[nb_index:(nb_index+nb_batch)].clone())
    mini_label = Variable(X_label[nb_index:(nb_index+nb_batch)].clone(), requires_grad = False)
    mini_data  = mini_data.type(torch.FloatTensor)
    mini_label = mini_label.type(torch.LongTensor)
    mini_data  = mini_data.view(mini_data.size(0),-1)
    if use_gpu:
        mini_data  = mini_data.cuda()
        mini_label = mini_label.cuda()
    optimizer.zero_grad()
    mini_out   = net(mini_data)
    mini_label = mini_label.view(nb_batch)
    mini_loss  = criterion(mini_out, mini_label)
    mini_loss.backward()
    optimizer.step()
    correct = int(torch.sum(torch.argmax(mini_out, dim=1) == mini_label))
    a=correct/nb_batch
    b=mini_loss.data
    if(b<0.1 or a>0.98):
        print("Epoch = %d, Loss = %10f Accuracy = %10f" %(epoch+1, mini_loss.data, correct/nb_batch))
        break;
    if (epoch + 1) % 100 == 0:
        print("Epoch = %d, Loss = %10f Accuracy = %10f" %(epoch+1, mini_loss.data, correct/nb_batch))

print ("4. Testing phase")

Y_data  = test.reshape(test.shape[0],-1)
Y_data  = Y_data.astype(float)
Y_data /= 255.0
Y_data  = torch.from_numpy(Y_data);
print (Y_data.size())
nb_test = test.shape[0]

net.eval()

final_prediction = np.ndarray(shape = (nb_test, 2), dtype=int)
for each_sample in range(nb_test):
	sample_data = Variable(Y_data[each_sample:each_sample+1].clone())
	sample_data = sample_data.type(torch.FloatTensor)
	if use_gpu:
		sample_data = sample_data.cuda()
	sample_out = net(sample_data)
	_, pred = torch.max(sample_out, 1)
	final_prediction[each_sample][0] = 1 + each_sample
	final_prediction[each_sample][1] = pred.data[0]
	if (each_sample + 1) % 2000 == 0:
		print("Total tested = %d" %(each_sample + 1))

print ('5. Generating submission file')

submission = pd.DataFrame(final_prediction, dtype=int, columns=['samp_id', 'label'])
submission.to_csv('pytorch_LeNet.csv', index=False, header=True)

# 保存模型
torch.save(net.state_dict(), './cnn.pth')


from flask_wtf import FlaskForm
from wtforms import StringField, DateField, TimeField, FloatField, SelectField, PasswordField, SubmitField, EmailField, TextAreaField, FieldList, FormField, IntegerField, DateField, TimeField, BooleanField
from wtforms.validators import InputRequired, length, optional, email, DataRequired, Email
from datetime import datetime

class CallForm(FlaskForm):
    date = DateField("Date", validators=[DataRequired()])
    time = TimeField("Time", validators=[DataRequired()])
    customer_name = StringField("Customer Name", validators=[DataRequired()])
    phone_number = StringField("Phone Number", validators=[DataRequired()])
    community = StringField("Community")
    area = SelectField("Area", choices=[(''), ('north'), ('northwest'), ('northeast'), ('central-west'), ('central'), ('central-east'), ('southeast'), ('south'), ('southwest'), ('ocean north'), ('ocean'), ('ocean south')])
    address = StringField("Address", validators=[DataRequired()])
    customer_type = SelectField("Customer Type", choices=[('existing'),('new'), ('?')], validators=[DataRequired()])
    call_type = SelectField("Call Type", choices=[('schedule'),('complaint'), ('payment'), ('estimate'), ('call out'), ('?')], validators=[DataRequired()])
    comments = StringField("Comments", validators=[DataRequired()])
    received_type = SelectField("Received Type", choices=[('msg'), ('call'), ('RO')],validators=[DataRequired()])
    response = SelectField("Response", choices=[('yes'), ('no')])
    card = SelectField("Card", choices=[('yes'), ('no')])
    database = SelectField("Database", choices=[('yes'), ('no')])
    resolved = SelectField("Resolved", choices=[('yes'), ('no')])

# Search Forms
class PhoneSearchForm(FlaskForm):
    phone_number = StringField('PHONE NUMBER:', validators=[DataRequired()])

class ResolvedSearchForm(FlaskForm):
    resolved = SelectField('RESOLVED:', choices=[('no'),('yes')], validators=[DataRequired()])

class NameSearchForm(FlaskForm):
    customer_name = StringField('CUSTOMER NAME:', validators=[DataRequired()])

class ResponseSearchForm(FlaskForm):
    response = SelectField('RESPONSE:', choices=[('no'),('yes')], validators=[DataRequired()])

class CommunitySearchForm(FlaskForm):
    community = StringField('COMMUNITY:', validators=[DataRequired()])

class AreaSearchForm(FlaskForm):
    area = StringField('AREA:', validators=[DataRequired()])

class TypeSearchForm(FlaskForm):
    call_type = SelectField('CALL TYPE:', choices=[('schedule'),('complaint'), ('payment'), ('estimate'), ('call out')], validators=[DataRequired()])


import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import multiLateration as ml
def main():
    #initializes the points
    x0, y0, z0 = 4, 1, 10  # point we are trying to find

    x1, y1, z1 = 3, 2, 3    #AP1
    x2, y2, z2 = -1, -3, 5  #AP2
    x3, y3, z3 = 1, 4, -2   #AP3
    p0 = [x0, y0, z0]
    p1 = [x1, y1, z1]
    p2 = [x2, y2, z2]
    p3 = [x3, y3, z3]
    points = [p0, p1, p2, p3]
    print(points)

    #distance between AP's and unknown point
    r1=ml.distance(points[0],points[1])
    r2=ml.distance(points[0],points[2])
    r3=ml.distance(points[0],points[3])

    points=ml.multiLateration(points[1],points[2],points[3],r1,r2,r3)

    # Plots the points into a 3d graph
    fig = plt.figure()
    ax = fig.add_subplot(111, projection='3d')

    ax.scatter(points[0][0], points[0][1], points[0][2], label="unkown point", c="black")
    ax.scatter(points[1][0], points[1][1], points[1][2], label="AP 1", c="red")
    ax.scatter(points[2][0], points[2][1], points[2][2], label="AP 2", c="red")
    ax.scatter(points[3][0], points[3][1], points[3][2], label="AP 3", c="red")
    ax.legend()
    plt.show()

main()


import asyncio
import logging
from motor import motor_asyncio
from ... import di

logger = logging.getLogger(__name__)

@di.desc('storage', reg=False)
class MongodbInterface:
    """
    https://github.com/mongodb/motor
    """

    def __init__(self,
                 uri='localhost',
                 db_name='bots',
                 user_collection_name='user',
                 session_collection_name='session',
                 ):
        self.cx = None
        self.db = None
        self.session_collection = None
        self.user_collection = None
        self.uri = uri
        self.db_name = db_name
        self.session_collection_name = session_collection_name
        self.user_collection_name = user_collection_name

    async def start(self):
        loop = asyncio.get_event_loop()
        logger.debug('start')
        self.cx = motor_asyncio.AsyncIOMotorClient(self.uri, io_loop=loop)
        logger.debug(' create client for: {}'.format(self.uri))
        self.db = self.cx.get_database(self.db_name)
        logger.debug(' get db: {}'.format(self.db_name))
        self.session_collection = self.db.get_collection(self.session_collection_name)
        logger.debug(' get session collection: {}'.format(self.session_collection_name))
        self.user_collection = self.db.get_collection(self.user_collection_name)
        logger.debug(' get user collection: {}'.format(self.user_collection_name))

    async def stop(self):
        self.cx = None
        self.db = None
        self.session_collection = None
        self.user_collection = None

    async def clear_collections(self):
        await self.session_collection.drop()
        self.session_collection = self.db.get_collection(self.session_collection_name)
        await self.user_collection.drop()
        self.user_collection = self.db.get_collection(self.user_collection_name)

    async def get_session(self, **kwargs):
        session = await self.session_collection.find_one(kwargs)
        if not session:
            return None
        session.pop('lastModified', None)
        return session

    async def set_session(self, session):
        logger.info('set_session {}'.format(session))
        if '_id' in session:
            _id = session['_id']
            session.pop('lastModified', None)
            res = await self.session_collection.update_one(
                {'_id': _id},
                {
                    '$set': session,
                    '$currentDate': {
                        'lastModified': True
                    },
                },
            )

            if res.matched_count != 0:
                return _id

        return await self.session_collection.insert(session)

    async def new_session(self, user, **kwargs):
        logger.info('new_session for {}'.format(user))
        kwargs['user_id'] = kwargs.get('user_id', user['_id'])
        kwargs['stack'] = kwargs.get('stack', [])
        _id = await self.session_collection.insert(kwargs)
        return await self.session_collection.find_one({'_id': _id})

    async def get_user(self, **kwargs):
        if 'id' in kwargs:
            kwargs['_id'] = kwargs.get('id', None)
            del kwargs['id']
        user = await self.user_collection.find_one(kwargs)
        if not user:
            return None
        user.pop('lastModified', None)
        return user

    async def set_user(self, user):
        logger.info('set_user {}'.format(user))
        if '_id' in user:
            _id = user['_id']
            user.pop('lastModified', None)
            res = await self.user_collection.update_one(
                {'_id': _id},
                {
                    '$set': user,
                    '$currentDate': {
                        'lastModified': True
                    },
                },
            )
            if res.matched_count != 0:
                return _id
        return await self.user_collection.insert(user)

    # TODO: should be able to process dictionary
    async def new_user(self, **kwargs):
        logger.debug('store new user {}'.format(kwargs))
        _id = await self.user_collection.insert(kwargs)
        return await self.user_collection.find_one({'_id': _id})


#Cristina
#Python

"""
Escribe un programa que reciba un número del usuario e imprima ``Bravo!'' si es mayor a -10 y menor a 10, ambos incluidos.
"""

x = float(input("x= "))
if x > 10:
    print("Bravo!")
elif x < 10:
    print("no:(")


#!/usr/bin/env python
import sys, re
argvs = sys.argv
import os
import collections
import numpy as np
import pandas as pd
pd.set_option("display.max_colwidth", 200)
pd.set_option("display.max_columns", 200)
pd.set_option("display.max_rows", 300)

import glob

## input
blast_f = argvs[1]
output_f = argvs[2]

## calculate coverage
# read blast_f: coverage, evalue, pident

coverage_d = {}
evalue_d = {}
pident_d = {}

for line in open(blast_f):
	if "#" not in line:
		info_l = line.strip().split("\t")
		query, subject, alen, qlen, slen, mis, gap, qstart,qend,sstart,send,evalue,pident = info_l[:13]
		alen,qlen,slen,qstart,qend = [int(c) for c in [alen,qlen,slen,qstart, qend]]
		evalue,pident = [float(c) for c in [evalue, pident]]

		if query not in coverage_d.keys():
			coverage_d[query] = {}
			evalue_d[query] = {}
			pident_d[query] = {}

		if subject not in coverage_d[query].keys():
			coverage_d[query][subject] = [0] * qlen
			evalue_d[query][subject] = 100
			pident_d[query][subject] = 0

		## coverageの計算
		alen_l = list(range(qstart,qend))

		for i,a in enumerate(coverage_d[query][subject]):
			if i in alen_l:
				coverage_d[query][subject][i] = 1
			else:
				pass

		## evalue
		if evalue < evalue_d[query][subject]:
			evalue_d[query][subject] = evalue

		## pident
		if pident > pident_d[query][subject]:
			pident_d[query][subject] = pident

# read blast_f: summarize
blast_l = []
for query in coverage_d.keys():
	for subject in coverage_d[query].keys():
		coverage_l = coverage_d[query][subject]
		alignment_l = [i for i in coverage_l if i == 1]

		coverage = len(alignment_l)/len(coverage_l) * 100
		evalue = evalue_d[query][subject]
		pident = pident_d[query][subject]

		l = [query, subject, coverage, evalue, pident]
		blast_l.append(l)

# read blast_f: dataframe
df_blast = pd.DataFrame(blast_l, columns=["query", "subject", "coverage", "evalue", "pident"])
df_blast = df_blast.sort_values(["query", "coverage"], ascending=[True, False])
df_blast.to_csv(output_f, sep="\t")


def räknare(x, y, z): #Här definierar jag en funktion som har tre parametrar som en använadre har satt i huvudprogrammet.
    if z=="/":
        return(x/y)
    if z=="*":
        return(x*y)
    if z=="+":
        return(x+y)
    if z=="-":
        return(x-y)
    else:
        return("Du har angivit fel symbol.")
#Här är huvudprogrammet
x=float(input("Skriv in tal 1: "))
y=float(input("Skriv in tal 2: "))
z=str(input("Vilket räknesätt vill du använda? Svara med + - / eller * "))
print(räknare(x, y, z))
input()


def land_perimeter(arr):
    """
    land_perimeter(arr)
        arr - list of strings.
        Function return total perimeter of all the islands.
        Each piece of land marked with 'X'
        while the water fields are represented as 'O'.
        i.e. ['XOOXO',
              'XOOXO',
              'OOOXO',
              'XXOXO',
              'OXOOO']
        return "Total land perimeter: 24"
    """
    p = 0
    for i, row in enumerate(arr):
        for j, el in enumerate(row):
            if el == 'X':
                if i == 0 or arr[i-1][j] != 'X':
                    p += 1
                if j == 0 or arr[i][j-1] != 'X':
                    p += 1
                if j == len(row) - 1 or arr[i][j+1] != 'X':
                    p += 1
                if i == len(arr) - 1 or arr[i+1][j] != 'X':
                    p += 1
    return f'Total land perimeter: {p}'


import pandas as pd
import geopandas as gpd
import statsmodels.api as sm
import seaborn as sns
from matplotlib import rcParams
from shapely.geometry import Point

rcParams.update({"figure.autolayout": True})

input_filenames = {
    "tracts": "data/Cook_County_Census_Tract_Boundaries_2010/Cook_County_Census_Tract_Boundaries_2010.shp",
    "stations": "data/CTA_L_Stops.csv",
    "ridership": "data/CTA_L_Ridership_200101-201906.csv",
    "finances": "data/ACSS_2017_Financial_Characteristics_Cook_County.csv",
}
output_filenames = {
    "stations": "results/StationData.csv",
    "ols_results": "results/LinearRegressionResults.txt",
    "ols_plot": "results/LinearRegressionPlot.png",
}
year = "2017"

"""
tracts
    tract_name: str
    geometry: MultiPolygon
"""
tracts = gpd.read_file(
    input_filenames["tracts"], usecols=["NAME10", "geometry"]
).rename(columns={"NAME10": "tract_name"})

"""
ridership
    station_id: int (index)
        this is equal to the MAP_ID in `stations`
    rides: int
        rides starting from this station during all of 2018
"""
ridership = pd.read_csv(input_filenames["ridership"])
ridership = (
    ridership[ridership.date.str.endswith(year)]
    .groupby("station_id", as_index=False)["rides"]
    .sum()
)

"""
housing
    tract_name: str
    monthly_housing_cost: int
        median estimated monthly housing costs
"""
monthly_housing_cost_key = "Estimate!!Occupied housing units!!Occupied housing units!!MONTHLY HOUSING COSTS!!Median (dollars)"
housing = pd.read_csv(
    input_filenames["finances"],
    header=1,
    usecols=["Geographic Area Name", monthly_housing_cost_key],
).rename(
    columns={
        "Geographic Area Name": "tract_name",
        monthly_housing_cost_key: "monthly_housing_cost",
    }
)
housing["tract_name"] = [
    name.strip("Census Tract ").strip(", Cook County, Illinois")
    for name in housing["tract_name"]
]

"""
stations
    station_name: str
    station_id: int
        the original data set includes both directions by default,
        so we use this id to filter for unique stations
    tract_name: str
    rides: int
        rides starting from this station during the given year
    monthly_housing_cost: int
        median estimated monthly housing costs
    geometry: Point
        latitude, longitude
"""
stations = (
    pd.read_csv(
        input_filenames["stations"],
        usecols=["STATION_DESCRIPTIVE_NAME", "MAP_ID", "Location"],
    )
    .drop_duplicates("MAP_ID")
    .rename(
        columns={"STATION_DESCRIPTIVE_NAME": "station_name", "MAP_ID": "station_id"}
    )
)
stations_points = []
stations_tracts = []
for location in stations["Location"]:
    lon, lat = [float(coord) for coord in location.strip("()").split(", ")]
    point = Point(lat, lon)
    tract_name = "0"
    for name, multipolygon in zip(tracts["tract_name"], tracts["geometry"]):
        if point.within(multipolygon):
            tract_name = name
            break
    stations_tracts.append(tract_name)
    stations_points.append(point)

stations = gpd.GeoDataFrame(stations, geometry=stations_points)[
    ["station_id", "station_name", "geometry"]
]
stations["tract_name"] = stations_tracts
stations = pd.merge(stations, ridership, on="station_id")
stations = pd.merge(stations, housing, how="left", on="tract_name")
stations = stations[stations["monthly_housing_cost"] != "-"].astype(
    {"monthly_housing_cost": "int64"}
)
stations.to_csv(output_filenames["stations"])

# linear regression with OLS
# independent variable: housing costs
X = sm.add_constant(stations["monthly_housing_cost"])
# dependent variable: ridership
y = stations["rides"]

with open(output_filenames["ols_results"], "r+") as results_txt:
    model = sm.OLS(y, X)  ## sm.OLS(output, input)
    results = model.fit()
    print(results.summary(), file=results_txt)
    print(
        "P values: constant = {}, housing = {}".format(
            results.pvalues[0], results.pvalues[1]
        ),
        file=results_txt,
    )

ax = sns.regplot(x=stations["monthly_housing_cost"], y=stations["rides"])
ax.set(
    xlabel="Median Estimated Monthly Housing Cost (dollars)",
    ylabel="Rides Starting at Station",
    title="CTA Ridership vs Housing Cost in Station's Census Tract (2017)"
)
ax.get_figure().savefig(output_filenames["ols_plot"])


# 17276번 배열 돌리기
import sys

t_num = int(sys.stdin.readline())
# input보다는 sys.stdin.readline.rstrip() rstrip()은 줄바꿈 문자 제외

def plus_turn(array, n):
    num = n // 2
    for i in range(n):
        array[i][i], array[i][num] = array[i][num], array[i][i]
        array[i][i], array[i][n - 1 - i] = array[i][n - 1 - i], array[i][i]
        array[i][i], array[num][i] = array[num][i], array[i][i]

    for i in range(num):
        array[num][i], array[num][n - 1 - i] = array[num][n - 1 - i], array[num][i]

    return array

def minus_turn(array, n):
    num = n // 2
    for i in range(n):
        array[i][n - 1 - i], array[i][num] = array[i][num], array[i][n - 1 - i]
        array[i][n - 1 - i], array[i][i] = array[i][i], array[i][n - 1 - i]
        array[i][n - 1 - i], array[num][i] = array[num][i], array[i][n - 1 - i]

    for i in range(num):
        array[n - 1 - i][i], array[i][n - 1 - i] = array[i][n - 1 - i], array[n - 1 - i][i]
    return array

for _ in range(t_num):
    n, d = map(int, input().split())
    array = [list(map(int, input().split())) for _ in range(n)]
    if d >= 0:
        p_d = d // 45
        for _ in range(p_d):
            array = plus_turn(array, n)
        for i in range(n):
            for j in range(n):
                print(array[i][j], end=' ')
            print()

    else:
        p_d = abs(d) // 45
        for _ in range(p_d):
            array = minus_turn(array, n)
        for i in range(n):
            for j in range(n):
                print(array[i][j], end=' ')
            print()

# for i in range(n):
#     print(*array[i])
# *을 사용하면, 리스트의 대괄호를 제거하고 출력할 수 있다.


""" This file tests the outputs of the CleanFlowline function
"""
import os
import pytest
import arcpy

from fg_tests_utils import *
from _05_CleanFlowline import CleanFlowline

# Define test parameters
output_workspace = "//mvrdfs/egis/Work/Office/Regional/ERDC/EMRRP_Sediment/Methods/FluvialGeomorph/tests/data/test.gdb"
stream_network   = os.path.join(output_workspace, "stream_network_edited")

# Create test fixtures
@pytest.fixture(scope = "module")
def flowline():
    # Call the CleanFlowline function with test data
    CleanFlowline(output_workspace, stream_network)
    # Return the flowline feature class
    flowline = arcpy.MakeFeatureLayer_management(
                   in_features = os.path.join(output_workspace,
                                              "flowline"),
                   out_layer = "flowline")
    return flowline

@pytest.fixture(scope = "module")
def flowline_stats(flowline):
    stat_fields = [["Name", "FIRST"]]
    case_field = "Name"
    fc_stat_table = fc_stats(workspace = output_workspace,
                             fc = flowline,
                             stat_fields = stat_fields,
                             case_field = case_field)
    yield fc_stat_table
    arcpy.Delete_management(
                  in_data = os.path.join(output_workspace, "fc_stat_table"))

# Test if feature class exists
def test_fc_exists_flowline(flowline):
    assert "flowline" in list_fcs(output_workspace)

# Test if field exists
def test_field_exists_Name(flowline):
    assert "Name" in list_fields(flowline)

# Test attribute values
def test_Name_first(flowline_stats):
    # The value of `Name` should be "Sinsinawa"
    assert field_stat(fc_stat_table = flowline_stats,
                      stat_field = "Name",
                      stat = "FIRST",
                      route_id_field = "Name",
                      route_name = "Sinsinawa") == "Sinsinawa"