from stellargraph.layer import (
    DeepGraphInfomax,
    GCN,
    APPNP,
    GAT,
    PPNP,
    GraphSAGE,
    DirectedGraphSAGE,
)

from stellargraph.mapper import (
    FullBatchNodeGenerator,
    CorruptedGenerator,
    GraphSAGENodeGenerator,
    DirectedGraphSAGENodeGenerator,
    FullBatchLinkGenerator,
)
from ..test_utils.graphs import example_graph_random
import tensorflow as tf
import pytest
import numpy as np

@pytest.mark.parametrize("model_type", [GCN, APPNP, GAT, PPNP])
@pytest.mark.parametrize("sparse", [False, True])
def test_dgi(model_type, sparse):

    if sparse and model_type is PPNP:
        pytest.skip("PPNP doesn't support sparse=True")

    G = example_graph_random()
    emb_dim = 16

    generator = FullBatchNodeGenerator(G, sparse=sparse)
    corrupted_generator = CorruptedGenerator(generator)
    gen = corrupted_generator.flow(G.nodes())

    base_model = model_type(
        generator=generator, activations=["relu"], layer_sizes=[emb_dim]
    )
    infomax = DeepGraphInfomax(base_model)

    model = tf.keras.Model(*infomax.in_out_tensors())
    model.compile(loss=tf.nn.sigmoid_cross_entropy_with_logits, optimizer="Adam")
    model.fit(gen)

    emb_model = tf.keras.Model(*infomax.embedding_model())
    embeddings = emb_model.predict(generator.flow(G.nodes()))

    assert embeddings.shape == (len(G.nodes()), emb_dim)

def test_dgi_stateful():
    G = example_graph_random()
    emb_dim = 16

    generator = FullBatchNodeGenerator(G)
    corrupted_generator = CorruptedGenerator(generator)
    gen = corrupted_generator.flow(G.nodes())

    infomax = DeepGraphInfomax(
        GCN(generator=generator, activations=["relu"], layer_sizes=[emb_dim])
    )

    model_1 = tf.keras.Model(*infomax.in_out_tensors())
    model_2 = tf.keras.Model(*infomax.in_out_tensors())

    # check embeddings are equal before training
    embeddings_1 = tf.keras.Model(*infomax.embedding_model()).predict(
        generator.flow(G.nodes())
    )
    embeddings_2 = tf.keras.Model(*infomax.embedding_model()).predict(
        generator.flow(G.nodes())
    )

    assert np.array_equal(embeddings_1, embeddings_2)

    model_1.compile(loss=tf.nn.sigmoid_cross_entropy_with_logits, optimizer="Adam")
    model_1.fit(gen)

    # check embeddings are still equal after training one model
    embeddings_1 = tf.keras.Model(*infomax.embedding_model()).predict(
        generator.flow(G.nodes())
    )
    embeddings_2 = tf.keras.Model(*infomax.embedding_model()).predict(
        generator.flow(G.nodes())
    )

    assert np.array_equal(embeddings_1, embeddings_2)

    model_2.compile(loss=tf.nn.sigmoid_cross_entropy_with_logits, optimizer="Adam")
    model_2.fit(gen)

    # check embeddings are still equal after training both models
    embeddings_1 = tf.keras.Model(*infomax.embedding_model()).predict(
        generator.flow(G.nodes())
    )
    embeddings_2 = tf.keras.Model(*infomax.embedding_model()).predict(
        generator.flow(G.nodes())
    )

    assert np.array_equal(embeddings_1, embeddings_2)

@pytest.mark.parametrize("model_type", [GCN, APPNP, GAT])
def test_dgi_link_model(model_type):
    G = example_graph_random()
    emb_dim = 16

    generator = FullBatchLinkGenerator(G)

    with pytest.warns(
        UserWarning,
        match=r"base_model: expected a node model .* found a link model \(multiplicity = 2\)",
    ):
        infomax = DeepGraphInfomax(
            model_type(generator=generator, activations=["relu"], layer_sizes=[emb_dim])
        )

    # build should work
    _ = infomax.in_out_tensors()

@pytest.mark.parametrize("is_directed", [False, True])
def test_dgi_graphsage(is_directed):

    G = example_graph_random(is_directed=is_directed)

    if is_directed:
        generator = DirectedGraphSAGENodeGenerator(
            G, batch_size=5, in_samples=[2, 3], out_samples=[4, 1]
        )
        base_model = DirectedGraphSAGE(generator=generator, layer_sizes=[4, 4])
    else:
        generator = GraphSAGENodeGenerator(G, batch_size=5, num_samples=[2, 3])
        base_model = GraphSAGE(generator=generator, layer_sizes=[4, 4])

    corrupted_generator = CorruptedGenerator(generator)
    gen = corrupted_generator.flow(G.nodes())

    infomax = DeepGraphInfomax(base_model)

    model = tf.keras.Model(*infomax.build())
    model.compile(loss=tf.nn.sigmoid_cross_entropy_with_logits, optimizer="Adam")
    model.fit(gen)

    emb_model = tf.keras.Model(*infomax.embedding_model())
    embeddings = emb_model.predict(generator.flow(G.nodes()))

    assert embeddings.shape == (len(G.nodes()), 4)


def fibonacci(n):
    memo = [0] * (n + 1)
    if n == 0 or n == 1:
        return n
    memo[1] = 1

    for i in range(2, n + 1):
        memo[i] = memo[i - 2] + memo[i - 1]
        print(memo)
    return memo[-1]

print(fibonacci(10))


# -*- coding: utf-8 -*-
from business import model as business_model
from business.order.encode_delivery_item_service import EncodeDeliveryItemService

class EncodeOrderService(business_model.Service):
	def get_base_info(self, order):
		return {
			'id': order.id,
			'bid': order.bid,
			'pay_interface_type_code': order.pay_interface_type_code,
			'payment_time': order.payment_time,
			'final_price': order.final_price,
			'product_price': order.product_price,
			'edit_money': order.edit_money,
			'bid_with_edit_money': order.bid_with_edit_money,
			'ship_name': order.ship_name,
			'ship_tel': order.ship_tel,
			'ship_area': order.ship_area,
			'ship_area_text': order.ship_area_text,
			'ship_address': order.ship_address,
			'bill_type': order.bill_type,
			'bill': order.bill,
			'postage': order.postage,
			'integral': order.integral,
			'integral_money': order.integral_money,
			'coupon_money': order.coupon_money,
			'coupon_id': order.coupon_id,
			'status_code': order.status_code,
			'customer_message': '',  # todo 删除
			'created_at': order.created_at,

			'webapp_id': order.webapp_id,
			'webapp_user_id': order.webapp_user_id,
			'weizoom_card_money': order.weizoom_card_money,
			'member_card_money': order.member_card_money,
			'delivery_time': order.delivery_time,
			'is_first_order': order.is_first_order,
			'is_weizoom_order': order.is_weizoom_order,
			'remark': order.remark,
			'pay_money': order.pay_money,
			'promotion_saved_money': order.promotion_saved_money
		}

	def get_extra_promotion_info(self, order):
		return {
			'integral_type': order.integral_type
		}

	def get_extra_coupon_info(self, order):
		return {
			'extra_coupon_info': {
				'bid': order.extra_coupon_info['bid'],
				'type': order.extra_coupon_info['type'],
				'name': order.extra_coupon_info['name']
			}

		}

	def get_weizoom_card_info(self, order):
		return {
			'weizoom_card_info': {
				'used_card': order.weizoom_card_info['used_card']
			}
		}

	def get_delivery_items(self, order, delivery_fill_options):
		encode_delivery_item_service = EncodeDeliveryItemService.get(self.corp)

		datas = []
		with_operation_logs = delivery_fill_options.get('with_operation_logs', False)
		for delivery_item in order.delivery_items:
			data = {}
			data.update(encode_delivery_item_service.get_base_info(delivery_item))
			data.update(encode_delivery_item_service.get_refunding_info(delivery_item))
			data.update(encode_delivery_item_service.get_express_details(delivery_item))
			data.update(encode_delivery_item_service.get_supplier(delivery_item))
			data.update(encode_delivery_item_service.get_products(delivery_item))

			if with_operation_logs:
				data.update(encode_delivery_item_service.get_operation_logs(delivery_item))

			datas.append(data)
		return {
			'delivery_items': datas
		}

	def get_operation_logs(self, order):
		return {
			'operation_logs': [{
				                   'action_text': log['action_text'],
				                   'time': log['time'],
				                   'operator': log['operator']
			                   } for log in order.operation_logs]}

	def get_status_logs(self, order):
		return {
			'status_logs':
				[{
					 'from_status_code': log['from_status_code'],
					 'to_status_code': log['to_status_code'],
					 'time': log['time']
				 } for log in order.status_logs]}

	def get_group_buy_info(self, order):
		return {
			'is_group_buy': order.is_group_buy
		}

	def get_refunding_info(self, order):
		return {
			'refunding_info': {
				'cash': order.refunding_info['cash'],
				'weizoom_card_money': order.refunding_info['weizoom_card_money'],
				'member_card_money': order.refunding_info['member_card_money'],
				'integral_money': order.refunding_info['integral_money'],
				'integral': order.refunding_info['integral'],
				'coupon_money': order.refunding_info['coupon_money'],
				'total': order.refunding_info['total'],
			}
		}

	def get_full_money_info(self, order):
		return {
			'origin_weizoom_card_money': order.origin_weizoom_card_money,
			'origin_member_card_money': order.origin_member_card_money,
			'origin_final_price': order.origin_final_price,
			'save_money': order.save_money
		}

	def get_member_info(self, order):
		return {
			'member_info': {
				'name': order.member_info['name'],
				'id': order.member_info['id'],
				'is_subscribed': order.member_info['is_subscribed'],
			}
		}


from brownie import *
from dotenv import load_dotenv, find_dotenv
from brownie.convert.normalize import format_input
from brownie.convert import to_bytes
from utils.deploy_helpers import deploy_proxy, deploy_admin
import os
import json

def main():
    load_dotenv(dotenv_path="./.env", override=True)
    load_dotenv(find_dotenv())
    user = accounts.add(os.getenv("USER_PRIVATE_KEY"))

    f = open('./scripts/deploy_script/deploy_info.json')
    data = json.load(f)
    tokens = data["tokens"]
    deployed_contracts_addresses = data["deployedContracts"]

    # Getting instances of contracts
    usdc = ERC20PresetMinterPauserMock.at(tokens["USDC"])
    usdc_market = MErc20.at(deployed_contracts_addresses["UsdcMarketToken"])
    controller = Controller.at(deployed_contracts_addresses["Controller"])

    # Set amount of USDC to deposit(currently 5 USDC)
    amount_to_deposit = 5e6

    # Approving USDC
    usdc.approve(usdc_market, amount_to_deposit, {"from": user})

    # Depositing USDC tokens to USDC Market Token
    print("Your balance of USDC before depositing: ", usdc.balanceOf(user) / 1e6)
    print("Your balance of USDC Market Token before depositing:", usdc_market.balanceOf(user) / 1e8)

    usdc_market.mint(amount_to_deposit, {"from": user})

    print("Your balance of USDC after depositing: ", usdc.balanceOf(user) / 1e6)
    print("Your balance of USDC Market Token after depositing:", usdc_market.balanceOf(user) / 1e8)

    # Entering the market, marking that asset can be used as collateral
    controller.enterMarkets([usdc_market], {"from": user})


"""
Skinning tools for maya.

Installation
============
Copy the **rjSkinningTools** folder to your Maya scripts directory
::
    C:/Users/<USER>/Documents/maya/scripts

Usage
=====
Add skinning shelf
::
    import rjSkinningTools
    rjSkinningTools.install()

Tools
=====
**paintSmoothWeightsCtx**
    * Paint smooth weights tool in Maya using the weights of neighbouring vertices.

**paintRemoveInfluenceCtx**
    * Remove a specific influence on vertices with the paint tool.

**tweakVertexWeights**
    * Tweak influence weights on a vertex level.

**softSelectionToWeights**
    * Convert soft selection to skin weights.

**delinearWeights**
    * De-linearize skin weights.

Code
====
"""

from maya import cmds, mel
from . import ui
import paintSmoothWeightsCtx
import paintRemoveInfluenceCtx
import ReorderAttr
__author__    = "Robert Joosten"
__version__   = "0.0.1"
__email__     = "rwm.joosten@gmail.com"

# ----------------------------------------------------------------------------

SHELF_NAME = "Skinning"
TOOLS = [
    {
        "label":"paintSkinWeights",
        "command":"ArtPaintSkinWeightsTool;",
        "annotation":"Paint Skin Weights Tool: Paint weights on smooth bound skins",
        "image1":ui.findIcon("paintSkinWeightsCtx.png"),
        "sourceType":"mel"
    },
    {
        "label":"paintSmoothWeights",
        "command":"from rjSkinningTools import paintSmoothWeightsCtx; paintSmoothWeightsCtx.paint()",
        "annotation":"Paint Smooth Weights Tool: Smooth weights on smooth bound skins",
        "image1":ui.findIcon("paintSmoothWeightsCtx.png"),
        "sourceType":"python"
    },
    {
        "label":"paintRemoveInfluence",
        "command":"import rjSkinningTools.paintRemoveInfluenceCtx.ui; rjSkinningTools.paintRemoveInfluenceCtx.ui.show()",
        "annotation":"Paint Remove Influence Tool: Remove influence on smooth bound skins",
        "image1":ui.findIcon("paintRemoveInfluenceCtx.png"),
        "sourceType":"python"
    },
    {
        "label":"tweakVertexWeights",
        "command":"import rjSkinningTools.tweakVertexWeights.ui; rjSkinningTools.tweakVertexWeights.ui.show()",
        "annotation":"Tweak Influences on a vertex level",
        "image1":ui.findIcon("tweakVertexWeights.png"),
        "sourceType":"python"
    },
    {
        "label":"softSelectionToWeights",
        "command":"import rjSkinningTools.softSelectionToWeights.ui; rjSkinningTools.softSelectionToWeights.ui.show()",
        "annotation":"Convert soft selection to skin weights",
        "image1":ui.findIcon("softSelectionToWeights.png"),
        "sourceType":"python"
    },
	{
        "label":"delinearWeights",
        "command":"import rjSkinningTools.delinearWeights.ui; rjSkinningTools.delinearWeights.ui.show()",
        "annotation":"De-linearize skin weights",
        "image1":ui.findIcon("delinearWeights.png"),
        "sourceType":"python"
    }
]

# ----------------------------------------------------------------------------

def install():
    """
    Add a new shelf in Maya with all the tools that are provided in the TOOLS
    variable. If a tab already exist new buttons that weren't registered yet
    will be added to the shelf.
    """
    # get top shelf
    gShelfTopLevel = mel.eval("$tmpVar=$gShelfTopLevel")

    # get top shelf names
    shelves = cmds.tabLayout(gShelfTopLevel, query=1, ca=1)

    # create shelf if it doesn't exist yet
    if not SHELF_NAME in shelves:
        cmds.shelfLayout(SHELF_NAME, parent=gShelfTopLevel)

    # get existing members
    existing = cmds.shelfLayout(SHELF_NAME, query=True, childArray=True ) or []
    existing = [cmds.shelfButton(e, query=True, label=True) for e in existing]

    # add modules
    for tool in TOOLS:
        if tool.get("label") in existing:
            continue

        if tool.get("image1"):
            cmds.shelfButton(style="iconOnly", parent=SHELF_NAME, **tool)
        else:
            cmds.shelfButton(style="textOnly", parent=SHELF_NAME, **tool)


from response_builder.response_builder import ResponseBuilder
import json

class JsonBuilder(ResponseBuilder):
    def build(self, result):
        return [to_dict(r) for r in result]

def to_dict(param):
    position, date, name, value = param
    longitude, latitude = position
    return dict(
        latitude=latitude,
        longitude=longitude,
        date=date.isoformat(),
        name=name,
        value=value,
    )


from Models.EnumMatchEventType import MatchEventType
import Scraper.HelperMethods
import re
from Soup import Soup

class MatchEventsHeadingSoup(Soup):

    def __init__(self,soup):
        Soup.__init__(self, soup)

    event_dict = {
        'i-report-ball': MatchEventType.GOAL,
        'i-yellow-card': MatchEventType.CARD_YELLOW,
        'i-red-card': MatchEventType.CARD_RED,
        'i-report-arrow-up': MatchEventType.SUB_ON,
        'i-report-arrow-down': MatchEventType.SUB_OFF
    }

    def get_event_type(self):
        event_name = self.get_soup().find('div', class_='action-icon grid-3 grid-mt-4 grid-msw-5 grid-ms-5').i['class'][0]
        event_type = self.event_dict[event_name]
        return event_type

    def get_event_time(self):
        return self.__extract_event_minute()

    def get_event_player_id(self):
        url = self.get_soup().find('a')['href']
        return int(Scraper.HelperMethods.extract_player_id_from_url(url))

    def __extract_event_minute(self):
        minuta = self.get_soup().find('div', re.compile('action-time')).text.strip()
        minuta = re.search(r'(\d+\+\d+|\d+)', minuta)
        if minuta is not None:
            minuta = minuta.group(0)
            if re.search(r'\d+\+\d+', minuta):
                minuta = int(minuta.split('+')[0]) + int(minuta.split('+')[1])
        return int(minuta)


weight = input("enter your weight in KG:")
height = input("enter your height in M: ")

# heightt = height[1]
# weightt = weight[0]

total_weight = int(weight) / float(height) ** 2
# fat = round(total_weight, 2)
# print int(fat)

total = int(total_weight)
print(total)


import time

import bge

import bgui
import ui
import sudo
import weapons
from item import Item

class InventoryWindow(bgui.Widget):
	""" A bgui widget that displays the contents of an inventory. Displays a single inventory, which can be linked to another one
	so items can be dragged from inventory to inventory.
	"""

	def __init__(self, parent, name, inventory=None, pos=[0, 0], size=[6, 8], options=bgui.BGUI_NONE):
		""" pos is in grid spaces, not pixels! One grid space is 50x50 px
		don't pass size in normalized values!
		"""
		super().__init__(parent, name, size=[size[0] * 50, size[1] * 50], pos=pos, options=options)

		self.border = ui.MetalBorder(self, 'border', size=[320, 420], pos=[-10, -10], options=bgui.BGUI_NONE)
		self.bg = bgui.Image(self, 'bg', img='./data/textures/ui/inventory_back.png', size=[300, 400], pos=[0, 0],
			options=bgui.BGUI_NONE)

		# The description window displays info and stats about the item the mouse is hovered over
		self.description_window = bgui.Frame(self, 'description_window', size=[200, 100], pos=[0, 0],
			sub_theme='description_window', options=bgui.BGUI_THEMED)
		self.description_window.visible = False
		self.description = bgui.Label(self.description_window, 'description', '', sub_theme='description', pos=[5, 80], options=bgui.BGUI_THEMED)

		self.context_menu = None  # The context menu is created when its required
		self.context_item = None  # The grid_id that the context menu was requested for
		self.delete_context_menu = False  # When true, context menu will be deleted at end of frame

		self.inventory = inventory  # The inventory which is being displayed
		self.linked_inventory = None  # other inventory that can be dragged to
		self.items = []  # A list of bgui.Images, arranged in a grid fashion

		self.hover_item = None  # The bgui.Image the mouse is hovering over
		self.hover_time = 0.0  # The time when the mouse began hovering

		self.drag_item = None  # The image being dragged
		self.dragging = False  # True when an image is being dragged
		self.drag_offset = [0, 0]  # mouse_pos - image_pos
		self.drag_start = [0, 0]  # The grid coordinates where the dragged image began
		self.drag_grid_id = 0  # The grid id of the dragged image

		self.redraw()

	def handle_context_menu(self):
		""" Call the context menu when requested (this method is called from handle_item_hover) """
		if self.hover_item is None:
			return
		mouse = bge.logic.mouse

		if mouse.events[bge.events.RIGHTMOUSE] == bge.logic.KX_INPUT_JUST_ACTIVATED:
			if self.context_menu:
				# Remove context menu
				self.remove_context_menu()
			else:
				# Create context menu
				item = Item.items[self.hover_item.item_id]
				pos = [(self.mouse[0] - self.position[0]) / self.size[0],
						(self.mouse[1] - self.position[1]) / self.size[1]]

				if self.inventory.id == 'Player':
					if item.type == 'weapons':
						self.context_menu = ui.ContextMenu(self, 'context_menu',
							[('Equip as primary', self.cm_equip_primary),
							('Equip as secondary', self.cm_equip_secondary),
							('Drop', self.cm_drop)],
							pos=pos, sub_theme='context_menu')
						self.context_item = self.hover_item.grid_id

				else:
					self.context_menu = ui.ContextMenu(self, 'context_menu',
						[('Take', self.cm_take)],
						pos=pos, sub_theme='context_menu')
					self.context_item = self.hover_item.grid_id

				# Remove linked inventory context menu
				if self.linked_inventory and self.linked_inventory.context_menu:
					self.linked_inventory.remove_context_menu()

			self.description_window.visible = False

	def remove_context_menu(self):
		""" Mark the context menu for removal, it is removed at the end of the draw function """
		self.delete_context_menu = True
		if self.context_menu:
			self.context_menu.visible = False

	def cm_equip_primary(self):
		""" Context menu action - equip weapon as primary weapon """
		self.remove_context_menu()

		item = Item.items[self.inventory._items[self.context_item][0]]
		if self.inventory.primary_weapon:
			self.inventory.primary_weapon.unequip(sudo.player)
		self.inventory.primary_weapon = getattr(weapons, item.properties['weapon'])(self.context_item)
		self.inventory.primary_weapon.equip(sudo.player)

		self.redraw()

	def cm_equip_secondary(self):
		""" Context menu action - equip weapon as seconday weapon """
		pass

	def cm_drop(self):
		""" Context menu action - drop item """
		pass

	def cm_take(self):
		""" Context menu action - take item from linked inventory """
		self.remove_context_menu

		item_id, item_amount = self.inventory._items[self.context_item]
		self.inventory.remove_grid_id(self.context_item)
		self.linked_inventory.inventory.add_item(item_id, item_amount)

		self.redraw()
		self.linked_inventory.redraw()

	def redraw(self):
		""" Re-calculate what items are where """
		for item in self.items:
			# Remove any existing images
			self._remove_widget(item)

		self.items = []

		if self.inventory is not None:  # The inventory is None in the swap screen
			for grid_id, (item_id, item_amount) in self.inventory._items.items():
				pos = self.inventory.get_pos(grid_id)

				icon = './data/textures/inventory_icons/' + Item.items[item_id].icon
				size = Item.items[item_id].size
				item = bgui.Image(self, 'item_' + str(grid_id), img=icon, size=[size[0] * 50, size[1] * 50],
					pos=[pos[0] * 50, pos[1] * 50], options=bgui.BGUI_NONE)
				if self.inventory.primary_weapon and grid_id == self.inventory.primary_weapon.grid_id:
					bgui.Frame(item, 'frame__' + str(grid_id), size=[1, 1], pos=[0, 0], sub_theme='equip')

				# display the number of items in the stack, and give it a shadow
				item.label1 = bgui.Label(item, 'amount1', str(item_amount), pos=[6, 4], sub_theme='inventory_amount_shadow',
					options=bgui.BGUI_THEMED)
				item.label2 = bgui.Label(item, 'amount2', str(item_amount), pos=[5, 5], sub_theme='inventory_amount',
					options=bgui.BGUI_THEMED)

				# Assign item data
				item.item_id = item_id
				item.grid_id = grid_id
				item.item_amount = item_amount
				item.item_size = size
				item.item_name = Item.items[item_id].name
				item.item_description = Item.items[item_id].description

				# Setup event callbacks
				item.on_hover = self.handle_item_hover
				item._handle_mouse_exit = self.handle_item_exit
				item._handle_click = self.handle_item_click
				item._handle_release = self.handle_item_release

				self.items.append(item)

		self.remove_context_menu()

	def link(self, inventory):
		""" Link another inventory to drag to """
		self.linked_inventory = inventory
		inventory.link2(self)

	def link2(self, inventory):
		""" Link another inventory to drag to """
		self.linked_inventory = inventory

	def handle_item_click(self):
		""" Initiate item dragging """
		if self.context_menu:
			# Remove context menu if it is active
			#self.remove_context_menu()
			return

		if self.linked_inventory and self.linked_inventory.context_menu:
			# Remove context menu in linked inventory if its active
			self.linked_inventory.remove_context_menu()

		if self.linked_inventory and self.linked_inventory.dragging:
			# don't initiate a drag if the linked inventory is already dragging
			return

		if self.hover_item:
			self.drag_item = self.hover_item
			self.hover_item = None

			# Calculate offset from mouse cursor to drag item origin
			self.drag_offset = [self.mouse[0] - self.drag_item.position[0],
				self.mouse[1] - self.drag_item.position[1]]

			# Store the position the drag item is initiall in (for returning it when drag fails)
			self.drag_start = [int(self.drag_item.position[0] - self.position[0]) // 50,
				int(self.drag_item.position[1] - self.position[1]) // 50]
			self.drag_grid_id = self.inventory._item_grid[self.drag_start[0]][self.drag_start[1]]
			self.inventory.clear_pos(self.drag_start, self.drag_item.item_size)

			# Detatching and re-attaching to bring widget to the front
			self._remove_widget(self.drag_item)
			self._attach_widget(self.drag_item)
			self.parent._remove_widget(self)
			self.parent._attach_widget(self)

			self.dragging = True

	def handle_item_release(self):
		""" Finish item dragging, either set the item to a new position or revert it to its old one """

		if self.linked_inventory and self.linked_inventory.dragging or not self.drag_item:
			# the release is not associated with this inventory
			return

		self.dragging = False

		if self.position[0] < self.mouse[0] and self.mouse[0] < self.position[0] + self.size[0] \
			and self.position[1] < self.mouse[1] and self.mouse[1] < self.position[1] + self.size[1]:
			# dropped in current inventory
			pos = [int(round((self.drag_item.position[0] - self.position[0]) / 50) * 50) // 50,
				int(round((self.drag_item.position[1] - self.position[1]) / 50) * 50) // 50]

			check = self.inventory.check_pos(pos, self.drag_item.item_size)
			if check is True:
				# The item can be dropped here
				self.inventory.set_pos(self.drag_grid_id, pos, self.drag_item.item_size)
				self.drag_item.position = [pos[0] * 50, pos[1] * 50]
			else:
				# The item can't be dropped here, return to it's original position
				self.drag_item.position = [self.drag_start[0] * 50, self.drag_start[1] * 50]
				self.inventory.set_pos(self.drag_grid_id, self.drag_start, self.drag_item.item_size)

		elif (self.linked_inventory
				and self.linked_inventory.position[0] < self.mouse[0]
				and self.mouse[0] < self.linked_inventory.position[0] + self.linked_inventory.size[0]
				and self.linked_inventory.position[1] < self.mouse[1]
				and self.mouse[1] < self.linked_inventory.position[1] + self.linked_inventory.size[1]):
			# dropped in linked inventory
			pos = [int(round((self.drag_item.position[0] - self.linked_inventory.position[0]) / 50) * 50) // 50,
				int(round((self.drag_item.position[1] - self.linked_inventory.position[1]) / 50) * 50) // 50]

			check = self.linked_inventory.inventory.check_pos(pos, self.drag_item.item_size)
			if  check is True:
				# dragged to an empty spot
				self.linked_inventory.inventory.add_item(self.drag_item.item_id, self.drag_item.item_amount, pos)
				self.inventory.remove_grid_id(self.drag_grid_id)
				self.redraw()
				self.linked_inventory.redraw()

			elif check == self.drag_item.item_id:
				# dragged onto same item type
				# add to stack in other inventory
				leftover = self.linked_inventory.inventory.add_to_stack(self.drag_item.item_id, self.drag_item.item_amount, pos)
				self.inventory.remove_grid_id(self.drag_grid_id)

				if leftover is not True and leftover > 0:
					# if not all the items could be added to the other inventory add leftovers back to the original spot
					self.inventory.add_item(self.drag_item.item_id, leftover, self.drag_start)

				self.redraw()
				self.linked_inventory.redraw()

			else:
				# dropped onto different item spot
				self.drag_item.position = [self.drag_start[0] * 50, self.drag_start[1] * 50]
				self.inventory.set_pos(self.drag_grid_id, self.drag_start, self.drag_item.item_size)

		else:
			# dropped in neither inventory, add to world
			# TODO
			pass

		self.drag_item = None

	def handle_item_exit(self):
		""" Hides the description window if an item is not being dragged """

		if self.linked_inventory and self.linked_inventory.dragging:
			return

		if not self.dragging:
			self.item_hover = None

	def handle_item_hover(self, item=None):
		""" Summon the description winndow if the mouse is over an item long enough """
		if self.linked_inventory and self.linked_inventory.dragging:
			return

		if item is None or self.dragging:
			# don't bother about the description window while an item is being dragged
			return

		self.handle_context_menu()

		if self.hover_item != item:
			# mouse has just entered an item
			self.hover_item = item
			self.hover_time = time.time()

		else:
			if time.time() > self.hover_time + 0.3 and not self.context_menu:
				# mouse was already on the item and has been for that last .3 seconds
				self.description_window.visible = True
				self.description_window.position = [self.mouse[0] - self.position[0] + 5, self.mouse[1] - self.position[1] - 100 - 5]
				self.description.text = self.hover_item.item_name + "\n" + self.hover_item.item_description

				# removing and reattaching brings the description window's z position to the top
				self._remove_widget(self.description_window)
				self._attach_widget(self.description_window)

	def _draw(self):
		# grab the mouse coordinates
		pos = list(bge.logic.mouse.position)
		pos[0] *= bge.render.getWindowWidth()
		pos[1] = bge.render.getWindowHeight() - (bge.render.getWindowHeight() * pos[1])
		self.mouse = pos

		if self.dragging:
			# move the item thats being dragged
			self.drag_item.position = [self.mouse[0] - self.position[0] - self.drag_offset[0],
				self.mouse[1] - self.position[1] - self.drag_offset[1]]

		super()._draw()

		# hide the description window, it will be recalled if its still needed
		self.description_window.visible = False

		# Remove the context menu if it has been marked for removal
		if self.delete_context_menu:
			if self.context_menu is not None:
				self._remove_widget(self.context_menu)
				self.context_menu = None
				self.hover_time = time.time()
			self.delete_context_menu = False


vueltas=[]
while True:
  v=input("")#ventas
  (n,m)=v.split(" ")
  n=int(n)
  m=int(m)
  if(m==0 and n==0):
    break
  r=m-n
  vueltas.append(r)
caja=[7,12,22,52,102,15,25,55,105,30,60,110,70,120,150]
for i in vueltas:
  if(caja.count(i)==1):
    print("possible")
  else:
    print("impossible")


import os
from PIL import Image
import requests
from io import BytesIO
from flask import Flask, flash, request, redirect, url_for, render_template, send_from_directory
import tweepy
from flask_limiter import Limiter
from flask_limiter.util import get_remote_address

app = Flask(__name__)
limiter = Limiter(
    app,
    key_func=get_remote_address,
    default_limits=["200 per day", "50 per hour"]
)
from werkzeug.utils import secure_filename

SECRET_KEY = "2*S28~NQ{p~c.aT"
UPLOAD_FOLDER = "C:/Users/tensor/Desktop/leaflet/static/uploads"
ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif'}
MAX_IMAGE_FILESIZE = 0.5 * 1024 * 1024

app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
app.config['SECRET_KEY'] = SECRET_KEY

import base64

def allowed_file(filename):
    return '.' in filename and \
           filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS

@app.route('/', methods=["GET", "POST"])
def index():
    return render_template("index.html")

@app.route('/test', methods=["GET", "POST"])
def test():
    return render_template("test.html")

@app.route('/uploads/<filename>')
def uploaded_file(filename):
    return send_from_directory(app.config['UPLOAD_FOLDER'],
                               filename)

@app.route("/twitter", methods=['GET', 'POST'])
@limiter.limit("100/day")
@limiter.limit("15/hour")
def twitter():
    if request.method == 'POST':
        username = request.form.get('text')
        auth = tweepy.OAuthHandler("VkrreD50glR0MKTM60ds2twHd", "TfVrWJumsxTcK9Aj8UAbk9jeGxnoZGikNFY9beQEP4DxOShc87")
        auth.set_access_token("878974576570617856-mDJZap5Jy3OeS9TxoLcgII9z6TM7SH9", "4BgyiRsxxkORNe0FApchpFgVLUsjAb6HMPPojnbCJa4gq")
        api = tweepy.API(auth)
        user = None
        try:
                user = api.get_user(screen_name=username)
                print(user)

        except tweepy.errors.TweepyException as e:
                flash("User not found")
                print(e)

                return render_template('index.html')
        else:
                global user_profile_image
                user_profile_image = user.profile_image_url.replace('normal', '400x400')

        data1 = BytesIO()
        data2 = BytesIO()
        data3 = BytesIO()
        data4 = BytesIO()
        data5 = BytesIO()
        data6 = BytesIO()
        data7 = BytesIO()
        data8 = BytesIO()
        data9 = BytesIO()
        data10 = BytesIO()

        data11 = BytesIO()
        data12 = BytesIO()
        data13 = BytesIO()

        response = requests.get(user_profile_image)

        userimage1 = Image.open(BytesIO(response.content))
        #userimage1 = userimage1.resize((280,280),Image.ANTIALIAS)
        image1 = Image.open('static/img/nullframes/are_you_hired_son.png')
        userimage1.paste(image1, (0,0), image1)
        userimage1.save(data1, 'PNG', quality=100)
        img1 = base64.b64encode(data1.getvalue())

        userimage2 = Image.open(BytesIO(response.content))
        #image2 = userimage2.resize((280,280),Image.ANTIALIAS)
        image2 = Image.open('static/img/nullframes/blood_red.png')
        userimage2.paste(image2, (0,0), image2)
        userimage2.save(data2, 'PNG', quality=100)
        img2 = base64.b64encode(data2.getvalue())

        userimage3 = Image.open(BytesIO(response.content))
        #image3 = userimage3.resize((280,280),Image.ANTIALIAS)
        image3 = Image.open('static/img/nullframes/chroma.png')
        userimage3.paste(image3, (0,0), image3)
        userimage3.save(data3, 'PNG', quality=100)
        img3 = base64.b64encode(data3.getvalue())

        userimage4 = Image.open(BytesIO(response.content))
        #image4 = userimage4.resize((280,280),Image.ANTIALIAS)
        image4 = Image.open('static/img/nullframes/finedog.png')
        userimage4.paste(image4, (0,0), image4)
        userimage4.save(data4, 'PNG', quality=100)
        img4 = base64.b64encode(data4.getvalue())

        userimage5 = Image.open(BytesIO(response.content))
        #image5 = userimage5.resize((280,280),Image.ANTIALIAS)
        image5 = Image.open('static/img/nullframes/mini_world.png')
        userimage5.paste(image5, (0,0), image5)
        userimage5.save(data5, 'PNG', quality=100)
        img5 = base64.b64encode(data5.getvalue())

        userimage6 = Image.open(BytesIO(response.content))
        #image6 = userimage6.resize((280,280),Image.ANTIALIAS)
        image6 = Image.open('static/img/nullframes/party_hard.png')
        userimage6.paste(image6, (0,0), image6)
        userimage6.save(data6, 'PNG', quality=100)
        img6 = base64.b64encode(data6.getvalue())

        userimage7 = Image.open(BytesIO(response.content))
        #image7 = userimage7.resize((280,280),Image.ANTIALIAS)
        image7 = Image.open('static/img/nullframes/finedog.png')
        userimage7.paste(image7, (0,0), image7)
        userimage7.save(data7, 'PNG', quality=100)
        img7 = base64.b64encode(data7.getvalue())

        userimage8 = Image.open(BytesIO(response.content))
        #image8 = userimage8.resize((280,280),Image.ANTIALIAS)
        image8 = Image.open('static/img/nullframes/shootme.png')
        userimage8.paste(image8, (0,0), image8)
        userimage8.save(data8, 'PNG', quality=100)
        img8 = base64.b64encode(data8.getvalue())

        userimage9 = Image.open(BytesIO(response.content))
        #image9 = userimage9.resize((280,280),Image.ANTIALIAS)
        image9 = Image.open('static/img/nullframes/sunger.png')
        userimage9.paste(image9, (0,0), image9)
        userimage9.save(data9, 'PNG', quality=100)
        img9 = base64.b64encode(data9.getvalue())

        userimage10 = Image.open(BytesIO(response.content))
        #image10 = userimage10.resize((280,280),Image.ANTIALIAS)
        image10 = Image.open('static/img/nullframes/natural.png')
        userimage10.paste(image10, (0,0), image10)
        userimage10.save(data10, 'PNG', quality=100)
        img10 = base64.b64encode(data10.getvalue())

        userimage11 = Image.open(BytesIO(response.content))
        #image11 = userimage11.resize((280,280),Image.ANTIALIAS)
        image11 = Image.open('static/img/nullframes/finedog_s.png')
        userimage11.paste(image11, (0,0), image11)
        userimage11.save(data11, 'PNG', quality=100)
        img11 = base64.b64encode(data11.getvalue())

        userimage12 = Image.open(BytesIO(response.content))
        #image8 = userimage12.resize((280,280),Image.ANTIALIAS)
        image12 = Image.open('static/img/nullframes/shootme_s.png')
        userimage12.paste(image12, (0,0), image12)
        userimage12.save(data12, 'PNG', quality=100)
        img12 = base64.b64encode(data12.getvalue())

        userimage13 = Image.open(BytesIO(response.content))
        #image9 = userimage13.resize((280,280),Image.ANTIALIAS)
        image13 = Image.open('static/img/nullframes/sunger_s.png')
        userimage13.paste(image13, (0,0), image13)
        userimage13.save(data13, 'PNG', quality=100)
        img13 = base64.b64encode(data13.getvalue())

    return render_template('processing.html' , filename=user_profile_image, are_you_hired_son=img1.decode('utf-8'), blood_red=img2.decode('utf-8'), chroma=img3.decode('utf-8'), mini_world=img5.decode('utf-8'), nature=img10.decode('utf-8'), party_hard= img6.decode('utf-8'), finedog=img7.decode('utf-8'), shootme=img8.decode('utf-8'), sunger=img9.decode('utf-8'), finedog_s=img11.decode('utf-8'), shootme_s=img12.decode('utf-8'), sunger_s=img13.decode('utf-8'))

@app.route("/processing", methods=['GET', 'POST'])
def processing():
    return render_template('processing.html')

@app.errorhandler(404)
def page_not_found(e):
    return render_template('404.html'), 404


class Node:
    def __init__(self, id):
        self.id = id
        self.children = {}
        self.count = 1

    def add_child(self, c):
        assert c.id not in self.children
        self.children[c.id] = c
        self.count += c.count

def to_tree(id, graph):
    root = Node(id)
    for cid in graph[id]:
        graph[cid].remove(id)
        root.add_child(to_tree(cid, graph))
    return root

def Func(root):
    assert root.count > 0
    if root.count <= 2:
        return 0

    r = 0
    for c in root.children.values():
        if c.count % 2 == 0:
            r += Func(c) + 1
        else:
            r += Func(c)

    return r

n, m = [int(w) for w in input().split()]
assert m == n-1
graph = {}
for i in range(m):
    u, v = [int(w) for w in input().split()]
    u -= 1
    v -= 1
    graph.setdefault(u,set()).add(v)
    graph.setdefault(v,set()).add(u)

root = to_tree(0, graph)

res = Func(root)
print(res)


import re
import socket
import time

class Client:
    def __init__(self, address, port, timeout=None):
        self.address = address
        self.port = port
        self.timeout = timeout
        self.sock = socket.create_connection((self.address, self.port), self.timeout)

    def put(self, metric_type, value, timestamp=None):
        timestamp = int(time.time()) if timestamp is None else timestamp
        data = f"put {metric_type} {value} {timestamp}\n"
        try:
            self.sock.sendall(data.encode("utf8"))
            data = self.sock.recv(1024).decode()
            if "error" in data:
                raise ClientError
        except Exception:
            raise ClientError

    def get(self, args):
        data = f"get {args}\n"
        try:
            self.sock.sendall(data.encode("utf8"))
            data = self.sock.recv(1024).decode()
            if data == "ok\n\n":
                return {}
            pattern = r"(^ok\n)(([\w.]*(\s[\d]*(\.[\d]*)*)\s(\d*)\n)*)(\n$)"
            if not re.match(pattern, data):
                raise ClientError
            m = re.search(pattern, data)
            parce_data = m.group(2)
            parce_data = parce_data.strip().split("\n")
            response = {}
            for i in parce_data:
                key, *val = i.split()
                tmp_data = [(int(timestamp), float(value)) for value, timestamp in zip(val[0::2], val[1::2])]
                if key in response:
                    response[key].extend(tmp_data)
                    response[key] = sorted(response[key], key=lambda x: x[0])
                else:
                    response[key] = tmp_data
            return response
        except Exception:
            raise ClientError

class ClientError(Exception):
    pass


import Tkinter
from Tkinter import *
import webbrowser
import thrain
import Tkinter, Tkconstants, tkFileDialog

'''
-----------------------------------------------------------------
OPEN FILE AND DIRECTORY
-----------------------------------------------------------------
'''
def openfileEnc():
	filename = tkFileDialog.askopenfilename(initialdir = "/home/parth/Desktop",title = "Select file",filetypes = (("text files","*.txt"),("all files","*.*")))
	fileToEncrptyEntryUpdate(filename)

def opendirectoryEnc():
	directory = tkFileDialog.askdirectory(initialdir = "/home/parth/Desktop",title = "Select directory")
	destinationFolderEncEntryUpdate(directory)

def openfileDec():
	filename = tkFileDialog.askopenfilename(initialdir = "/home/parth/Desktop",title = "Select file",filetypes = (("text files","*.txt"),("all files","*.*")))
	fileToDecryptEntryUpdate(filename)
def opendirectoryDec():
	directory = tkFileDialog.askdirectory(initialdir = "/home/parth/Desktop",title = "Select directory")
	destinationFolderDecEntryUpdate(directory)
'''
-----------------------------------------------------------------
OPEN SOCIAL LINKS
-----------------------------------------------------------------
'''
def sendfilepage():
	webbrowser.open_new(r"http://127.0.0.1:5000/upload-file")

def recievefilepage():
	webbrowser.open_new(r"http://127.0.0.1:5000/file-directory")

def opengithub(event):
	webbrowser.open_new(r"https://github.com/parthendo/thrain")

def openparthlinkedin(event):
	webbrowser.open_new(r"https://in.linkedin.com/in/parth-trehan")

def openhardiklinkedin(event):
	webbrowser.open_new(r"https://in.linkedin.com/in/hardik-gaur-135891122")
'''
-----------------------------------------------------------------
UPDATE ENTRY LABELS
-----------------------------------------------------------------
'''
def fileToEncrptyEntryUpdate(filename):
	# Delete old value of entry
	inputEncFileEntry.delete(0,END)
	# Input new value of entry
	inputEncFileEntry.insert(0,filename)
def destinationFolderEncEntryUpdate(directory):
	# Delete old value of entry
	inputEncDirEntry.delete(0,END)
	# Input new value of entry
	inputEncDirEntry.insert(0,directory)
def fileToDecryptEntryUpdate(filename):
	# Delete old value of entry
	outputDecFileEntry.delete(0,END)
	# Input new value of entry
	outputDecFileEntry.insert(0,filename)
def destinationFolderDecEntryUpdate(directory):
	# Delete old value of entry
	outputDecDirEntry.delete(0,END)
	# Input new value of entry
	outputDecDirEntry.insert(0,directory)
'''
-----------------------------------------------------------------
ENCRYPT-DECRYPT TRIGGER BUTTON
-----------------------------------------------------------------
'''
def encryptor():
	EncryptBTN.config(state="disabled")
	public_key = publicKeyOfRecieverEntry.get()
	private_key = privateKeyOfSenderEntry.get()
	directory = inputEncDirEntry.get()
	filename = inputEncFileEntry.get()
	thrain.encrypt(filename,directory,public_key,private_key)

def decryptor():
	DecryptBTN.config(state="disabled")
	public_key = publicKeyOfSenderEntry.get()
	private_key = privateKeyOfRecieverEntry.get()
	directory = outputDecDirEntry.get()
	filename = outputDecFileEntry.get()
	thrain.decrypt(filename,directory,public_key,private_key)

def main():

	global filename
	global directory

	filename = ""
	directory = ""

	# Attributes of main dialog box
	global form
	form = Tkinter.Tk()
	form.wm_title('thrain')
	'''
	-------------------------------------------------------------
	Form Label Configuration
	-------------------------------------------------------------
	'''
	EncryptStep = LabelFrame(form, text=" 1. File Encryption: ")
	EncryptStep.grid(row=0, columnspan=7, sticky='W', \
		padx=5, pady=5, ipadx=5, ipady=5)

	DecryptStep = LabelFrame(form, text=" 2. File Decryption: ")
	DecryptStep.grid(row=2, columnspan=7, sticky='W', \
    	             padx=5, pady=5, ipadx=5, ipady=5)

	Aboutus = LabelFrame(form, text=" About ")
	Aboutus.grid(row=0, column=9, columnspan=2, rowspan=8, \
		sticky='NS', padx=5, pady=5)
	'''
	-------------------------------------------------------------
	Menu Bar
	-------------------------------------------------------------
	'''
	menu = Menu(form)
	form.config(menu=menu)

	menufile = Menu(menu)
	menufile.add_command(label = 'Send file', command = lambda:sendfilepage())
	menufile.add_command(label = 'Recieve file', command = lambda:recievefilepage())
	menufile.add_command(label = 'Exit', command = lambda:exit())
	menu.add_cascade(label = 'Menu', menu = menufile)
	'''
	-------------------------------------------------------------
	ENCRYPT-SECTION
	-------------------------------------------------------------
	'''
	global inputEncFileEntry
	global inputEncDirEntry
	global publicKeyOfRecieverEntry
	global privateKeyOfSenderEntry

	global EncryptBTN

	#-------------------------Select a file----------------------
	inputEncFile = Label(EncryptStep, text="Select the File:")
	inputEncFile.grid(row=0, column=0, sticky='E', padx=5, pady=2)

	inputEncFileEntry = Entry(EncryptStep)
	inputEncFileEntry.grid(row=0, column=1, columnspan=7, sticky="WE", pady=3)

	inputEncBtn = Button(EncryptStep, text="Browse ...", command = openfileEnc)
	inputEncBtn.grid(row=0, column=8, sticky='W', padx=5, pady=2)
	#-------------------------Save file to ----------------------
	inputEncDir = Label(EncryptStep, text="Save File to:")
	inputEncDir.grid(row=1, column=0, sticky='E', padx=5, pady=2)

	inputEncDirEntry = Entry(EncryptStep)
	inputEncDirEntry.grid(row=1, column=1, columnspan=7, sticky="WE", pady=2)

	inputEncDirBtn = Button(EncryptStep, text="Browse ...", command = opendirectoryEnc)
	inputEncDirBtn.grid(row=1, column=8, sticky='W', padx=5, pady=2)
	#-------------------------Public Key-------------------------
	publicKeyOfReciever = Label(EncryptStep, text="Public-Key of reciever:")
	publicKeyOfReciever.grid(row=2, column=0, sticky='E', padx=5, pady=2)

	publicKeyOfRecieverEntry = Entry(EncryptStep)
	publicKeyOfRecieverEntry.grid(row=2, column=1, sticky='E', pady=2)
	#-------------------------Private Key------------------------
	privateKeyOfSender = Label(EncryptStep, text="Private-Key of sender:")
	privateKeyOfSender.grid(row=2, column=5, padx=5, pady=2)

	privateKeyOfSenderEntry = Entry(EncryptStep)
	privateKeyOfSenderEntry.grid(row=2, column=7, pady=2)
	#-------------------------Encrypt Button---------------------
	EncryptBTN = Tkinter.Button(EncryptStep, text="Encrypt   ", command=encryptor)
	EncryptBTN.grid(row=2, column=8, sticky='W', padx=5, pady=2)
	'''
	-------------------------------------------------------------
	DECRYPT-SECTION
	-------------------------------------------------------------
	'''
	global outputDecFileEntry
	global outputDecDirEntry
	global publicKeyOfSenderEntry
	global privateKeyOfRecieverEntry

	global DecryptBTN
	#-------------------------Select a file----------------------
	outputDecFile = Label(DecryptStep, text="Select the File:")
	outputDecFile.grid(row=0, column=0, sticky='E', padx=5, pady=2)

	outputDecFileEntry = Entry(DecryptStep)
	outputDecFileEntry.grid(row=0, column=1, columnspan=7, sticky="WE", pady=3)

	outputDecBtn = Button(DecryptStep, text="Browse ...", command = openfileDec)
	outputDecBtn.grid(row=0, column=8, sticky='W', padx=5, pady=2)
	#-------------------------Save file to ----------------------
	outputDecDir = Label(DecryptStep, text="Save File to:")
	outputDecDir.grid(row=1, column=0, sticky='E', padx=5, pady=2)

	outputDecDirEntry = Entry(DecryptStep)
	outputDecDirEntry.grid(row=1, column=1, columnspan=7, sticky="WE", pady=2)

	outputDecDirBtn = Button(DecryptStep, text="Browse ...", command = opendirectoryDec)
	outputDecDirBtn.grid(row=1, column=8, sticky='W', padx=5, pady=2)
	#-------------------------Public Key-------------------------
	publicKeyOfSender = Label(DecryptStep, text="Public-Key of sender:")
	publicKeyOfSender.grid(row=2, column=0, sticky='E', padx=5, pady=2)

	publicKeyOfSenderEntry = Entry(DecryptStep)
	publicKeyOfSenderEntry.grid(row=2, column=1, sticky='E', pady=2)
	#-------------------------Private Key------------------------
	privateKeyOfReciever = Label(DecryptStep, text="Private-Key of reciever:")
	privateKeyOfReciever.grid(row=2, column=5, padx=5, pady=2)

	privateKeyOfRecieverEntry = Entry(DecryptStep)
	privateKeyOfRecieverEntry.grid(row=2, column=7, pady=2)
	#-------------------------Decrypt Button---------------------
	DecryptBTN = Tkinter.Button(DecryptStep, text="Decrypt   ", command = decryptor)
	DecryptBTN.grid(row=2, column=8, sticky='W', padx=5, pady=2)
	'''
	-------------------------------------------------------------
	ABOUTUS-SECTION
	-------------------------------------------------------------
	'''
	intro = Label(Aboutus, text="\nthrain - A secure file transfer system")
	intro.grid(row=0)
	text1 = Label(Aboutus, text="\nThrain enables its users to securely\ntransfer files in 'txt' format without\nany third party eavesdropping\n")
	text1.grid(row=1)
	githublink = Label(Aboutus, text="Know More", fg="blue", cursor="hand2")
	githublink.bind("<Button-1>", opengithub)
	githublink.grid(row=2)
	# Add more content and remove padding newline accordingly
	padding = Label(Aboutus, text="\n\n\n\n")
	padding.grid(row=3)
	text2 = Label(Aboutus, text="Contributed by: ")
	text2.grid(row=4, sticky='S')
	hardiksocial = Label(Aboutus, text="Hardik Gaur")
	hardiksocial.bind("<Button-1>",openhardiklinkedin)
	hardiksocial.grid(row=5, sticky='SW',padx = 8)
	text3 = Label(Aboutus, text="|")
	text3.grid(row=5)
	parthsocial = Label(Aboutus, text="Parth Trehan")
	parthsocial.bind("<Button-1>",openparthlinkedin)
	parthsocial.grid(row=5, sticky='SE',padx = 8)

	form.mainloop()

if __name__ == "__main__":
	main()


from django.urls import path, include
from . import views

urlpatterns = [
    path('',views.homePage,name='home'),
    path('accounts/',include('allauth.urls')),
    path('dashboard',views.dashbo,name='dashboard'),
    path('profile/<str:pk>', views.profile, name='users-profile'),
    path('update-user',views.update,name='update-user'),

]


## 기존 풀이
# n = int(input())
# number = input()
# list = []

# for i in range(n):
#     list.append(int(number[i]))

# print(sum(list))

## 피드백
# 1. list는 파이썬 내장함 수 이름이므로 다른 이름으로 바꿔보기
# 2. 애초에 input을 받을 때 map을 통해서 받아보기

## 새로운 풀이
n = int(input())
numbers = list(map(int, input()))
print(sum(numbers))


import torch
import torch.nn.functional as F
import numpy as np
from torch import nn
from torchvision import models

from .base import accuracy, time_distributed, time_distributed_apply, load_network
from .framework import Framework
from .lstm import SeqPredFramework

def stack_frames(frames, reverse=False):
    '''
    frames : [time_step, batch_size, channels, ...]
    output : [time_step - 1, batch_size, channels * 2, ...]
    '''
    T = frames.size(0)
    if reverse:
        return torch.cat([frames.narrow(0, 1, T - 1), frames.narrow(0, 0, T - 1)], dim=2)
    else:
        return torch.cat([frames.narrow(0, 0, T - 1), frames.narrow(0, 1, T - 1)], dim=2)

class StackCL(nn.Module):
    def __init__(self, classes, lstm_units, sync_bn=False, load_lstm=None, load_backbone=None):
        super().__init__()
        resnet = models.resnet50(pretrained=False)
        resnet.conv1 = nn.Conv2d(3 * 2, 64, kernel_size=(7, 7), stride=(2, 2), padding=(3, 3), bias=False)
        in_planes = resnet.fc.in_features
        resnet.fc = nn.Sequential()
        if load_backbone is not None:
            load_network(resnet, load_backbone, 'module.backbone.')
        if sync_bn:
            print('Convert model using sync bn')
            resnet = convert_model(resnet)
        self.backbone = resnet

        self.lstm = nn.LSTM(in_planes, lstm_units)
        if load_lstm is not None:
            load_network(self.lstm, load_lstm, 'module.lstm.')
        self.fc = nn.Linear(lstm_units, classes)

    def forward(self, frames):
        self.lstm.flatten_parameters()
        frames = stack_frames(frames)
        features = time_distributed(self.backbone, frames)
        features, _ = self.lstm(features)
        return time_distributed(self.fc, features)

class StackCLOrder(nn.Module):
    def __init__(self, lstm_units, sync_bn=False, load_lstm=None, load_backbone=None):
        super().__init__()
        resnet = models.resnet50(pretrained=False)
        resnet.conv1 = nn.Conv2d(3 * 2, 64, kernel_size=(7, 7), stride=(2, 2), padding=(3, 3), bias=False)
        in_planes = resnet.fc.in_features
        resnet.fc = nn.Sequential()
        if load_backbone is not None:
            load_network(resnet, load_backbone, 'module.backbone.')
        if sync_bn:
            print('Convert model using sync bn')
            resnet = convert_model(resnet)
        self.backbone = resnet

        self.lstm = nn.LSTM(in_planes, lstm_units)
        self.fc = nn.Sequential(
            nn.Linear(in_planes, lstm_units))
        self.predict_mlp = nn.Sequential(
            nn.Linear(lstm_units * 2, lstm_units * 2),
            nn.ReLU(),
            nn.Linear(lstm_units * 2, 2)
            )

        self.register_buffer('label', torch.LongTensor([1, 0]))

    def forward(self, orig_frames):
        self.lstm.flatten_parameters()
        # stack sequence with length - 1
        frames = stack_frames(orig_frames)
        T, batch_size = frames.size()[:2]
        features = time_distributed(self.backbone, frames)
        lstm_features, _ = self.lstm(features.narrow(0, 0, T - 1))

        frames_r = stack_frames(orig_frames, reverse=True).narrow(0, 1, T - 1) # remove first pair
        features_r = time_distributed_apply(frames_r, self.backbone, self.fc)
        features = time_distributed_apply(features.narrow(0, 1, T - 1), self.fc) # remove first pair

        T = T - 1
        lstm_features = lstm_features.repeat(1, 1, 2).view(T * batch_size * 2, -1)
        diff_features = torch.cat([features, features_r], dim = -1).view(T * batch_size * 2, -1) # P, N, P, N, ...
        concat_features = torch.cat([lstm_features, diff_features], dim = -1)
        logits = self.predict_mlp(concat_features).view(T, batch_size * 2, 2)
        labels = self.label.repeat(T, batch_size, 1).view(T, batch_size * 2)

        return logits, labels

class StackCLPredFramework(SeqPredFramework):
    def build_network(self):
        self.model = StackCLOrder(**self.config['network'])

def stackcl_framework(config):
    if config['framework'] == 'stackcl-order':
        return StackCLPredFramework(config)


from django.shortcuts import render

# Create your views here.
def Employee(request):
    return render(request,'basic.html')
    #render(request,'html file,context = variablename)

# How to inject dynamic content from views to template folder
# DTL : django template librabry     "  {{}} "

# Variables¶
# A variable outputs a value from the context,
# which is a dict-like object mapping keys to values.
#
# Variables are surrounded by {{ and }} like this:

def Student(request):
    stu_dict = {
        'name':'Padma Priya',
        'age': 20,
        'location':'Smartcity'
    }
    return render(request,'stu_Info.html',context=stu_dict)


#!/usr/bin/env python3
import firebase_admin
import datetime
from firebase_admin import credentials, db
from firebase_admin import firestore

from chair_calculations import chair_analysis

last_read_timestamps = {'SonicWaves-C-001': 0, 'SonicWaves-C-002':0, 'SonicWaves-C-003':0,
                        'SonicWaves-T-001': 0, 'SonicWaves-T-002':0, 'SonicWaves-D-001': 0}

# Used for global access to firebase client
db_pointer = None

def init_firestore():
    # Using a service account credentials to verify the user
    cred = credentials.Certificate('./iot-app-3386d-firebase-adminsdk-notbj-6b009a7f9d.json')
    firebase_admin.initialize_app(cred, {'databaseURL': 'https://iot-app-3386d.firebaseio.com'})

def filter_sort_data(documents, last_timestamp, device_name):
    data = []
    largest_timestamp = datetime.datetime(year=datetime.MINYEAR, month=1, day=1)
    for document in documents:
    # for document in documents:
        timestamp = document.id
        doc = document.to_dict()
        data_datetime = parse_datetime(timestamp)
        if data_datetime >= last_timestamp:
            if data_datetime > largest_timestamp:
                largest_timestamp = data_datetime
            data.append((doc, data_datetime))
    last_read_timestamps[device_name] = largest_timestamp
    data = sorted(data, key=lambda x: x[1])
    data = [x[0] for x in data]
    print("Working")
    return data

def get_firebase_data(db, name):
    if '-C-' in name:
        ref = db.collection('chair_data').document(name)
    elif '-T-' in name:
        ref = db.collection('table_data').document(name)
    elif '-D-' in name:
        ref = db.collection('door_data').document(name)
    else:
        print("Did not recognize name of change")
        return
    docs = ref.get()
    print(docs)
    doc = docs.to_dict()
    print(doc)
    # print(docs.toString())
    data = []
    if not docs.to_dict() == {}:
        data = filter_sort_data(docs, last_read_timestamps[name], name)
    return data

def setFirebaseData():
        doc_ref = db.collection(u'data-visual').document(u'room_occupancy')
        doc_ref.set({
            'current_occupants': 4
        })

def calculate_chairs():
    filter_values = last_read_timestamps['']
    pass

def calculate_occupancy(timestamp):
    pass

def calculate_chair_position(timestamp):
    pass

def chair_snapshot(chairs, changes, readTime):
    print("Chair Triggered!")
    current_used_chairs = 0
    chair_history = {}
    for doc in changes:
        print('In Snapshot {}'.format(doc.document.id))
        chair_data = get_firebase_data(db_pointer, doc.document.id)
        current_flag, chair_usage = chair_analysis(chair_data)
        if current_flag:
            current_used_chairs+=1
        else:
            current_used_chairs-=1
        chair_history["chair_id"] = chair_usage #TODO add in chair id

    return (current_used_chairs, chair_history)
    # TODO call data_visual to update the values there

def table_snapshot(tables, changes, readTime):
    print("Tables Triggered!")
    for doc in tables:
        print('{}'.format(doc.id))

def door_snapshot(doors, changes, readTime):
    print("Door Triggered!")
    person_count = 0
    for doc in doors:
        print('{}'.format(doc.id))
        # make a count of the latest people in the room
        # TODO need to pull the values in data_visual and update them with this new count
        door_data = get_firebase_data(db_pointer, doc.document.id)
        if door_data['activated']:
            person_count+=1
        else:
            person_count-=1

def make_timestamp_pairs():
    pass

def update_averages(value_dictionary, weeks=True):
    if weeks:
        collection_names = ['monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday']
    else:
        collection_names = []
        for i in range(0, 25):
            if i == 24:
                break
            time = str(i) + '-' + str(i+1)
            collection_names.append(time)
        collection_names.append('24-0')
    for i in collection_names:
        for document_name in ['average_chair_count', 'average_missing_chairs', 'average_table_count', 'total_occupancy']:
            collection = realtime_db.collection('data-visual').document('average_week').collection(i).document(
                document_name)
            values = collection.get().to_dict()
            average_count = values[document_name]
            num_updates = values['num_updates']
            total_count = average_count * num_updates
            total_count += value_dictionary[document_name]
            new_average = total_count / num_updates + 1
            collection.set({document_name: new_average, 'num_updates': num_updates + 1})

if __name__ == '__main__':
    init_firestore()

    db_pointer = firestore.client()
    db_pointer.collection('chair_data').document('SonicWaves-C-001').collection('detections').on_snapshot(chair_snapshot)
    db_pointer.collection('chair_data').document('SonicWaves-C-002').collection('detections').on_snapshot(chair_snapshot)
    db_pointer.collection('chair_data').document('SonicWaves-C-003').collection('detections').on_snapshot(chair_snapshot)

    door_callback = db_pointer.collection('door_data').on_snapshot(door_snapshot)
    table_callback = db_pointer.collection('table_data').on_snapshot(table_snapshot)

    while True:
        continue
    # update_averages(value_dictionary={}, weeks=True)

    # getFirebaseData()
    # setFirebaseData()


import unittest
from disjoint_set import DisjointSet
"""
Time complexity: O(E * LogE)
Space complexity: O(V)
"""
def kruskals(n, edges):
  ds = DisjointSet()
  edge_count = 0
  total_weight = 0
  for w, a, b in sorted(edges):
    ds.add(a)
    ds.add(b)
    if ds.union(a, b):
      edge_count += 1
      total_weight += w
      if edge_count == n-1:
        break
  return total_weight

class TestKruskals(unittest.TestCase):
  def test_kruskals(self):
    graph = {
      'A': [(2, 'B'), (3, 'C')],
      'B': [(2, 'A'), (1, 'C'), (1, 'D'), (4, 'E')],
      'C': [(3, 'A'), (1, 'B'), (5, 'F')],
      'D': [(1, 'B'), (1, 'E')],
      'E': [(4, 'B'), (1, 'D'), (1, 'F')],
      'F': [(5, 'C'), (1, 'E'), (1, 'G')],
      'G': [(1, 'F')],
    }

    edges = []
    for a in graph:
      for w, b in graph[a]:
        edges.append((w, a, b))
    self.assertEqual(kruskals(len(graph), edges), 7)
if __name__ == "__main__":
  unittest.main()


import json
import csv

with open('entailmentbank/data/chains_train.json','r') as f:
    true_train=json.load(f)

with open('entailmentbank/outputs/pre_train_top50.json','r') as f:
    pre_train=json.load(f)

with open("entailmentbank/data/worldtree_corpus_sentences_extended.json", 'r') as f:
    knowledge_corpus = json.load(f)

with open("entailmentbank/data/hypotheses_train.json", 'r') as f:
    hypotheses_train = json.load(f)

output=open('entailmentbank/train/rerank_train_2th.csv','w')

for i,j in pre_train.items():
    true_k=true_train[i] #true list k
    for k in j:
        if k in true_k:

            print(hypotheses_train[i] + "\t" + knowledge_corpus[k] + "\t" + str(1), file=output)
        else:
            print(hypotheses_train[i] + "\t" + knowledge_corpus[k] + "\t" + str(0), file=output)

    # print(i,j)
    # break


import typer
from pathlib import Path
from typing import Optional, List

from src.pipelines.transcribe import transcribe_audios_in_folder
from src.pipelines.export import export_corpus_dataset

from src.clients.scp_transfer import FileTransfer
from src.clients.database import Database

from src.models.file import AudioFormat

app = typer.Typer(
    no_args_is_help=True,
    help="Run data pipelines for diarization, transcription, metadata extraction for feeding the BrazSpeechData platform.",
)

DATA_PATH = Path("./data/")

@app.command(name="export")
def export(
    corpus_id: int = typer.Option(..., help="Corpus ID"),
    output_folder: Path = typer.Option(DATA_PATH / "export", help="Output folder"),
    csv: bool = typer.Option(False, help="Export to CSV"),
    json_metadata: bool = typer.Option(False, help="Export to JSON metadata"),
    textgrid: bool = typer.Option(False, help="Export to TextGrid"),
    continuous_text: bool = typer.Option(False, help="Export to continuous text"),
    speakers_text: bool = typer.Option(False, help="Export to speakers text"),
    original_audios: bool = typer.Option(False, help="Export original audios"),
    export_audio_to_formats: List[AudioFormat] = typer.Option(
        [AudioFormat.WAV, AudioFormat.MP3], help="Export audio to formats"
    ),
    google_drive_folder_ids: Optional[List[str]] = typer.Option(
        None, help="Google Drive folder IDs"
    ),
    filter_format: Optional[AudioFormat] = typer.Option(
        None, help="Filter audios by format"
    ),
    sample_rate: int = typer.Option(48000, help="Sample rate"),
    all: bool = typer.Option(False, help="Export all"),
    debug: bool = typer.Option(False, help="Debug mode"),
):
    if all:
        csv = True
        textgrid = True
        continuous_text = True
        speakers_text = True
        original_audios = True
        json_metadata = True

    with Database() as db:
        export_corpus_dataset(
            corpus_id=corpus_id,
            output_folder=output_folder,
            db=db,
            export_original_audios=original_audios,
            export_audio_to_formats=export_audio_to_formats,
            google_drive_folder_ids=google_drive_folder_ids,
            sample_rate=sample_rate,
            filter_format=filter_format,
            export_concanated_text=continuous_text,
            export_json_metadata=json_metadata,
            export_speakers_text=speakers_text,
            export_text_grid=textgrid,
            export_to_csv=csv,
            debug=debug,
        )

@app.command(name="transcribe")
def transcribe(
    corpus_id: int = typer.Option(..., help="Corpus ID"),
    folder_ids: List[str] = typer.Option(
        ..., help="Google Drive folder IDs that contain the audios to transcribe"
    ),
    output_folder: Path = typer.Option(DATA_PATH, help="Output folder"),
    storage_output_folder_id: str = typer.Option(
        None,
        help="Google Drive folder ID to save the transcriptions. If none is provided, the transcriptions will be saved in the same folder as the audios.",
    ),
    format_filter: Optional[AudioFormat] = typer.Option(
        None, help="Filter audios by format"
    ),
    save_to_db: bool = typer.Option(False, help="Save transcriptions to database"),
    save_to_drive: bool = typer.Option(
        False, help="Save transcriptions to Google Drive"
    ),
    transfer_to_server: bool = typer.Option(
        False, help="Transfer transcriptions to server"
    ),
):
    get_db_search_key = lambda x: x

    # Handle MUPE special case:
    if corpus_id == 1:
        format_filter = AudioFormat.MP4
        get_db_search_key = lambda x: "_".join(x.split("_")[:3])
    elif corpus_id == 2:
        format_filter = AudioFormat.WAV

    with FileTransfer() as ft:
        with Database() as db:
            transcribe_audios_in_folder(
                corpus_id=corpus_id,
                folder_ids=folder_ids,
                output_folder=output_folder,
                db=db if save_to_db else None,
                storage_output_folder_id=storage_output_folder_id,
                format_filter=format_filter,
                file_transfer_client=ft if transfer_to_server else None,
                save_to_drive=save_to_drive,
                get_db_search_key=get_db_search_key,
            )

if __name__ == "__main__":
    app()


import random

def random_walk():
    x = 0
    cnt = 0
    while True:
        cnt += 1
        if random.random() < 0.1:
            x += 1
        else:
            x -= 1
        if abs(x) >= 2:
            # print(cnt)
            return cnt

def main():
    num_of_trial = 100000
    sum = 0
    for _ in range(num_of_trial):
        sum += random_walk()
    print("average:", sum / num_of_trial)

if __name__ == "__main__":
    main()


# import pdb
import argparse
import os
import subprocess

from defaults import template_str_profile as template_str
from jinja2 import Template
from itertools import product
from rsparse.utils import params_to_filename, params_dict_to_str

from defaults import var_dict, CKPT_DIR, DATA_DIR, LOG_DIR

# all possible combinations for the python script's parameters

var_lists = list()

for k in var_dict.keys():
    var_lists.append([(k, v) for v in var_dict[k]])

def main(vars_, script_dir, overwrite, **args):
    script = os.path.join(script_dir, 'profile.py')
    template = Template(template_str)
    ckpt_dir = os.path.join(script_dir, CKPT_DIR)
    data_dir = os.path.join(script_dir, DATA_DIR)
    log_dir = os.path.join(script_dir, LOG_DIR)

    if not os.path.exists(ckpt_dir):
        os.mkdir(ckpt_dir)
    if not os.path.exists(data_dir):
        os.mkdir(data_dir)
    if not os.path.exists(log_dir):
        os.mkdir(log_dir)

    for i, x in enumerate(product(*var_lists)):
        x = dict(x)

        # exclude product + proximal
        if x['prox'] and x['reg'] == 'linfprod':
            continue
        if x['prox'] and x['reg'] == 'linfpath':
            args['time'] = '7:00:00'
        else:
            args['time'] = '1:00:00'

        if x['reg'] == 'linfproj':
            if x['prox'] and x['lambda_'] < 1e-2:
                continue
        else:
            if x['lambda_'] > 1e2:
                continue

        filename_ = params_to_filename(**x)
        ckpt = os.path.join(ckpt_dir, filename_ + '.pt')

        if os.path.isfile(ckpt) and not overwrite:
            continue

        x['ckpt_dir'] = ckpt_dir
        x['data_dir'] = data_dir
        x['overwrite'] = overwrite
        params = params_dict_to_str(x)

        with open('job_script.sh', 'w') as f:
            f.write(template.render(
                params=params, script=script, log_dir=log_dir, **args))

        subprocess.run('sbatch job_script.sh', shell=True)

    if os.path.isfile('job_script.sh'):
        os.remove('job_script.sh')

if __name__ == '__main__':
    parser = argparse.ArgumentParser()

    # python interpreter and where the project folder is located
    parser.add_argument(
            '--interpreter', type=str,
            default='/home/latorre/miniconda3/envs/pytorch/bin/python')
    parser.add_argument(
            '--script_dir', type=str,
            default='/home/latorre/robust_sparsity')

    # SLURM parameters
    parser.add_argument('--job_name', type=str, default='robsparse')
    parser.add_argument('--time', type=str, default='2:30:00')
    parser.add_argument('--mem', type=str, default='4GB')
    # parser.add_argument('--partition', type=str, default='gpu')
    parser.add_argument('--nodes', type=str, default='1')
    parser.add_argument('--overwrite', action='store_true')
    args = parser.parse_args()
    main(vars_=var_dict, **vars(args))


from os import kill
from functions.player import (
    findRank,
    perMin,
    killParticipation,
    lowestGPMFiveMin,
    killsPerMinTen,
    percentageGoldGained,
    common,
    commonCore,
    commonSup,
    rivalResponse,
    pos1Rival,
    pos2Rival,
    pos3Rival,
    pos4Rival,
    pos5Rival,
    checkRanks,
    fixExcess,
    findHighestAndLowest,
    findRole,
)

class TestFindRank:
    def test_herald(self):
        assert findRank(10) == "herald"

    def test_guardian(self):
        assert findRank(20) == "guardian"

    def test_crusader(self):
        assert findRank(30) == "crusader"

    def test_archon(self):
        assert findRank(40) == "archon"

    def test_legend(self):
        assert findRank(50) == "legend"

    def test_ancient(self):
        assert findRank(60) == "ancient"

    def test_divine(self):
        assert findRank(70) == "divine"

    def test_immortal(self):
        assert findRank(80) == "immortal"

class TestPerformance:
    def test_per_min(self):
        assert perMin(60, 360) == 10

    def test_per_min_rounding(self):
        assert perMin(56, 360) == 9.33

    def test_kill_participation(self):
        assert killParticipation(True, 10, 20, 10, 10) == 1
        assert killParticipation(True, 10, 20, 10, 0) == 0.5

        assert killParticipation(False, 10, 20, 6, 1) == 0.7
        assert killParticipation(False, 0, 20, 0, 0) == 0
        assert killParticipation(True, 10, 0, 0, 0) == 0

    def test_lowest_gpm_five_min(self):
        #lowest gpm of 10 at 10 min
        gold_array_1 = [1,2,3,4,5,6,7,8,9,10,100,100,100,100,100, 150, 700, 800, 1100]
        #lowest gpm of 4 at 12 min
        gold_array_2 = [1,2,3,4,5,6,7,8,9,10,100,100,130,130,130, 130, 130, 150, 1100]
        #too short of a game
        gold_array_3 = [1,2,3,4,5,6,7,8,9,10]
        assert lowestGPMFiveMin(gold_array_1) == [10, 10]
        assert lowestGPMFiveMin(gold_array_2) == [4, 12]
        assert lowestGPMFiveMin(gold_array_3) == 0

    def test_kills_per_min_for_ten_min(self):
        kills_log=[

            {
                'time': 678
            }]
        assert killsPerMinTen(kills_log) == 0
        kills_log.append({'time': 555})
        kills_log.append({'time': 442})
        assert killsPerMinTen(kills_log) == 0.2

    def test_percentage_gold_gained(self):
        max_gold =  4185
        assert percentageGoldGained(max_gold)== 1
        assert percentageGoldGained(max_gold/2) == 0.5

class TestRivals:
    def test_common(self):
        player = setupPlayerTestingObject(1)
        common_resp = common(player, "immortal")
        player["name"] = player["personaname"]
        player["HDM"] = round(player["hero_damage"] / (player["duration"] / 60), 2)
        player["buybacks"] = player["buyback_log"]
        player["deaths_per_min"] = round(
            player["deaths"] / (player["duration"] / 60), 2
        )
        player["predicted_win"] = 99.666
        del (
            player["gpm"],
            player["xpm"],
            player["last_hits"],
            player["personaname"],
            player["buyback_log"],
            player["duration"],
            player["kill_streaks"],
            player["multi_kills"],
            player["kills_log"],
            player["camps_stacked"],
            player["stuns"],
            player["max_hero_hit"],
            player["runes_log"],
            player["tower_damage"],
            player["damage_taken"],
            player["is_roaming"],
            player["obs_placed"],
            player["sen_placed"],
            player["hero_healing"],
        )
        assert common_resp == player

    def test_commonCore(self):
        player = setupPlayerTestingObject(1)
        commonCore_resp = commonCore(player)
        expected_resp = {
            "last_hits": player["last_hits"],
            "lane_kills": 2,
            "multi_kills": 4,
            "XPM": 550,
            "GPM": 500,
            "kill_streaks": 2,
            "lane_performance": 0.003,
        }
        assert commonCore_resp == expected_resp

    def test_commonSup(self):
        player = setupPlayerTestingObject(5)
        commonSup_resp = commonSup(player)
        expected_resp = {
            "camps_stacked": player["camps_stacked"],
            "stuns": player["stuns"],
        }
        assert commonSup_resp == expected_resp

    def test_pos1Rival(self):
        player = setupPlayerTestingObject(1)
        pos1Rival_resp = pos1Rival(player)
        expected_resp = {
            "KPM": 0.48,
            "max_hero_hit": player["max_hero_hit"],
            "lowest_gpm": [1.0, 10],
            "LHM": 6.0,
        }
        assert pos1Rival_resp == expected_resp

    def test_pos2Rival(self):
        player = setupPlayerTestingObject(2)
        pos2Rival_resp = pos2Rival(player)
        expected_resp = {
            "runes_picked_up": player["runes_log"],
            "KPM": 0.48,
            "max_hero_hit": player["max_hero_hit"],
            "lowest_gpm": [1.0, 10],
            "LHM": 6.0,
        }
        assert pos2Rival_resp == expected_resp

    def test_pos3Rival(self):
        player = setupPlayerTestingObject(3)
        pos3Rival_resp = pos3Rival(player)
        expected_resp = {
            "tower_damage": player["tower_damage"],
            "TDM": 60.0,
            "damage_taken": player["damage_taken"],
            "stuns": round(player["stuns"], 2),
        }
        assert pos3Rival_resp == expected_resp

    def test_pos4Rival(self):
        player = setupPlayerTestingObject(4)
        pos4Rival_resp = pos4Rival(player)
        expected_resp = {
            "runes_picked_up": player["runes_log"],
            "is_roaming": player["is_roaming"],
        }
        assert pos4Rival_resp == expected_resp

    def test_pos5Rival(self):
        player = setupPlayerTestingObject(5)
        pos5Rival_resp = pos5Rival(player)
        expected_resp = {
            "obs_placed": player["obs_placed"],
            "sen_placed": player["sen_placed"],
            "hero_healing": player["hero_healing"],
            "HHM": 33.96,
        }
        assert pos5Rival_resp == expected_resp

    def test_rivalResponse1(self):
        player = setupPlayerTestingObject(1)
        rivalResponse_1 = rivalResponse(player, "immortal")
        player["name"] = player["personaname"]
        player["HDM"] = round(player["hero_damage"] / (player["duration"] / 60), 2)
        player["buybacks"] = player["buyback_log"]
        player["deaths_per_min"] = round(
            player["deaths"] / (player["duration"] / 60), 2
        )
        player["predicted_win"] = 99.666
        player["GPM"] = 500
        player["XPM"] = 550
        player["lane_kills"] = 2
        player["lane_performance"] = 0.003
        player["LHM"] = 6.0
        player["KPM"] = 0.48
        player["lowest_gpm"] = [1.0, 10]
        del (
            player["gpm"],
            player["xpm"],
            player["personaname"],
            player["buyback_log"],
            player["duration"],
            player["kills_log"],
            player["camps_stacked"],
            player["stuns"],
            player["runes_log"],
            player["tower_damage"],
            player["damage_taken"],
            player["is_roaming"],
            player["obs_placed"],
            player["sen_placed"],
            player["hero_healing"],
        )
        assert rivalResponse_1 == player

    def test_rivalResponse2(self):
        player = setupPlayerTestingObject(2)
        player["rune_pickups"] = player["runes_log"]
        rivalResponse_2 = rivalResponse(player, "immortal")
        player["name"] = player["personaname"]
        player["HDM"] = round(player["hero_damage"] / (player["duration"] / 60), 2)
        player["buybacks"] = player["buyback_log"]
        player["deaths_per_min"] = round(
            player["deaths"] / (player["duration"] / 60), 2
        )
        player["predicted_win"] = 99.966
        player["GPM"] = 500
        player["XPM"] = 550
        player["lane_kills"] = 2
        player["lane_performance"] = 0.003
        player["LHM"] = 6.0
        player["KPM"] = 0.48
        player["lowest_gpm"] = [1.0, 10]
        player["runes_picked_up"] = player["runes_log"]
        del (
            player["gpm"],
            player["xpm"],
            player["personaname"],
            player["buyback_log"],
            player["duration"],
            player["kills_log"],
            player["camps_stacked"],
            player["stuns"],
            player["runes_log"],
            player["tower_damage"],
            player["damage_taken"],
            player["is_roaming"],
            player["obs_placed"],
            player["sen_placed"],
            player["hero_healing"],
            player["rune_pickups"],
        )
        assert rivalResponse_2 == player

    def test_rivalResponse3(self):
        player = setupPlayerTestingObject(3)
        rivalResponse_3 = rivalResponse(player, "immortal")
        player["name"] = player["personaname"]
        player["HDM"] = round(player["hero_damage"] / (player["duration"] / 60), 2)
        player["buybacks"] = player["buyback_log"]
        player["deaths_per_min"] = round(
            player["deaths"] / (player["duration"] / 60), 2
        )
        player["predicted_win"] = 99.573
        player["GPM"] = 500
        player["XPM"] = 550
        player["lane_kills"] = 2
        player["lane_performance"] = 0.003
        player["TDM"] = 60
        del (
            player["gpm"],
            player["xpm"],
            player["personaname"],
            player["buyback_log"],
            player["duration"],
            player["kills_log"],
            player["camps_stacked"],
            player["runes_log"],
            player["is_roaming"],
            player["obs_placed"],
            player["sen_placed"],
            player["hero_healing"],
            player["max_hero_hit"],
        )
        assert rivalResponse_3 == player

    def test_rivalResponse4(self):
        player = setupPlayerTestingObject(4)
        rivalResponse_4 = rivalResponse(player, "immortal")
        player["name"] = player["personaname"]
        player["HDM"] = round(player["hero_damage"] / (player["duration"] / 60), 2)
        player["buybacks"] = player["buyback_log"]
        player["deaths_per_min"] = round(
            player["deaths"] / (player["duration"] / 60), 2
        )
        player["predicted_win"] = 99.817
        player["runes_picked_up"] = player["runes_log"]
        del (
            player["gpm"],
            player["xpm"],
            player["personaname"],
            player["buyback_log"],
            player["duration"],
            player["kills_log"],
            player["runes_log"],
            player["obs_placed"],
            player["sen_placed"],
            player["hero_healing"],
            player["max_hero_hit"],
            player["damage_taken"],
            player["last_hits"],
            player["multi_kills"],
            player["kill_streaks"],
            player["tower_damage"],
        )
        assert rivalResponse_4 == player

    def test_rivalResponse5(self):
        player = setupPlayerTestingObject(5)
        rivalResponse_5 = rivalResponse(player, "immortal")
        player["name"] = player["personaname"]
        player["HDM"] = round(player["hero_damage"] / (player["duration"] / 60), 2)
        player["buybacks"] = player["buyback_log"]
        player["deaths_per_min"] = round(
            player["deaths"] / (player["duration"] / 60), 2
        )
        player["predicted_win"] = 99.963
        player["HHM"] = 33.96
        del (
            player["gpm"],
            player["xpm"],
            player["personaname"],
            player["buyback_log"],
            player["duration"],
            player["kills_log"],
            player["runes_log"],
            player["max_hero_hit"],
            player["damage_taken"],
            player["last_hits"],
            player["multi_kills"],
            player["kill_streaks"],
            player["tower_damage"],
            player["is_roaming"],
        )
        assert rivalResponse_5 == player

class TestCheckingRanks:
    expected_players = [
        {"hero_id": 1, "lane_role": 1, "ml_lane_role": 1, "net_worth": 10000},
        {"hero_id": 2, "lane_role": 1, "ml_lane_role": 5, "net_worth": 5000},
        {"hero_id": 3, "lane_role": 2, "ml_lane_role": 2, "net_worth": 15000},
        {"hero_id": 4, "lane_role": 3, "ml_lane_role": 4, "net_worth": 7800},
        {"hero_id": 5, "lane_role": 3, "ml_lane_role": 3, "net_worth": 12000},
    ]
    all_expected_players = [
        {
            "hero_id": 1,
            "lane_role": 1,
            "ml_lane_role": 1,
            "net_worth": 10000,
            "is_radiant": True,
        },
        {
            "hero_id": 2,
            "lane_role": 1,
            "ml_lane_role": 5,
            "net_worth": 5000,
            "is_radiant": True,
        },
        {
            "hero_id": 3,
            "lane_role": 2,
            "ml_lane_role": 2,
            "net_worth": 15000,
            "is_radiant": True,
        },
        {
            "hero_id": 4,
            "lane_role": 3,
            "ml_lane_role": 4,
            "net_worth": 7800,
            "is_radiant": True,
        },
        {
            "hero_id": 5,
            "lane_role": 3,
            "ml_lane_role": 3,
            "net_worth": 12000,
            "is_radiant": True,
        },
        {
            "hero_id": 6,
            "lane_role": 1,
            "ml_lane_role": 1,
            "net_worth": 11200,
            "is_radiant": False,
        },
        {
            "hero_id": 7,
            "lane_role": 1,
            "ml_lane_role": 5,
            "net_worth": 6150,
            "is_radiant": False,
        },
        {
            "hero_id": 8,
            "lane_role": 2,
            "ml_lane_role": 2,
            "net_worth": 17500,
            "is_radiant": False,
        },
        {
            "hero_id": 9,
            "lane_role": 3,
            "ml_lane_role": 4,
            "net_worth": 6300,
            "is_radiant": False,
        },
        {
            "hero_id": 10,
            "lane_role": 3,
            "ml_lane_role": 3,
            "net_worth": 14200,
            "is_radiant": False,
        },
    ]

    def test_checkRanksEven(self):
        players = [
            {
                "hero_id": 1,
                "lane_role": 1,
                "ml_lane_role": 1,
                "net_worth": 10000,
                "is_radiant": True,
            },
            {
                "hero_id": 2,
                "lane_role": 1,
                "ml_lane_role": 5,
                "net_worth": 5000,
                "is_radiant": True,
            },
            {
                "hero_id": 3,
                "lane_role": 2,
                "ml_lane_role": 2,
                "net_worth": 15000,
                "is_radiant": True,
            },
            {
                "hero_id": 4,
                "lane_role": 3,
                "ml_lane_role": 4,
                "net_worth": 7800,
                "is_radiant": True,
            },
            {
                "hero_id": 5,
                "lane_role": 3,
                "ml_lane_role": 3,
                "net_worth": 12000,
                "is_radiant": True,
            },
            {
                "hero_id": 6,
                "lane_role": 1,
                "ml_lane_role": 1,
                "net_worth": 11200,
                "is_radiant": False,
            },
            {
                "hero_id": 7,
                "lane_role": 1,
                "ml_lane_role": 5,
                "net_worth": 6150,
                "is_radiant": False,
            },
            {
                "hero_id": 8,
                "lane_role": 2,
                "ml_lane_role": 2,
                "net_worth": 17500,
                "is_radiant": False,
            },
            {
                "hero_id": 9,
                "lane_role": 3,
                "ml_lane_role": 4,
                "net_worth": 6300,
                "is_radiant": False,
            },
            {
                "hero_id": 10,
                "lane_role": 3,
                "ml_lane_role": 3,
                "net_worth": 14200,
                "is_radiant": False,
            },
        ]
        checked_players = checkRanks(players)
        assert checked_players == self.all_expected_players

    def test_checkRanks(self):
        players = [
            {
                "hero_id": 1,
                "lane_role": 1,
                "ml_lane_role": 5,
                "net_worth": 10000,
                "is_radiant": True,
            },
            {
                "hero_id": 2,
                "lane_role": 1,
                "ml_lane_role": 5,
                "net_worth": 5000,
                "is_radiant": True,
            },
            {
                "hero_id": 3,
                "lane_role": 2,
                "ml_lane_role": 2,
                "net_worth": 15000,
                "is_radiant": True,
            },
            {
                "hero_id": 4,
                "lane_role": 3,
                "ml_lane_role": 4,
                "net_worth": 7800,
                "is_radiant": True,
            },
            {
                "hero_id": 5,
                "lane_role": 3,
                "ml_lane_role": 4,
                "net_worth": 12000,
                "is_radiant": True,
            },
            {
                "hero_id": 6,
                "lane_role": 1,
                "ml_lane_role": 1,
                "net_worth": 11200,
                "is_radiant": False,
            },
            {
                "hero_id": 7,
                "lane_role": 1,
                "ml_lane_role": 5,
                "net_worth": 6150,
                "is_radiant": False,
            },
            {
                "hero_id": 8,
                "lane_role": 2,
                "ml_lane_role": 4,
                "net_worth": 17500,
                "is_radiant": False,
            },
            {
                "hero_id": 9,
                "lane_role": 3,
                "ml_lane_role": 4,
                "net_worth": 6300,
                "is_radiant": False,
            },
            {
                "hero_id": 10,
                "lane_role": 3,
                "ml_lane_role": 3,
                "net_worth": 14200,
                "is_radiant": False,
            },
        ]
        checked_players = checkRanks(players)
        assert checked_players == self.all_expected_players

    def test_fixExcess4(self):
        players = [
            {"hero_id": 1, "lane_role": 1, "ml_lane_role": 1, "net_worth": 10000},
            {"hero_id": 2, "lane_role": 1, "ml_lane_role": 5, "net_worth": 5000},
            {"hero_id": 3, "lane_role": 2, "ml_lane_role": 2, "net_worth": 15000},
            {"hero_id": 4, "lane_role": 3, "ml_lane_role": 4, "net_worth": 7800},
            {"hero_id": 5, "lane_role": 3, "ml_lane_role": 4, "net_worth": 12000},
        ]

        checked_players = fixExcess([4], [3], players)
        assert checked_players == self.expected_players

    def test_fixExcess5(self):
        players = [
            {"hero_id": 1, "lane_role": 1, "ml_lane_role": 5, "net_worth": 10000},
            {"hero_id": 2, "lane_role": 1, "ml_lane_role": 5, "net_worth": 5000},
            {"hero_id": 3, "lane_role": 2, "ml_lane_role": 2, "net_worth": 15000},
            {"hero_id": 4, "lane_role": 3, "ml_lane_role": 4, "net_worth": 7800},
            {"hero_id": 5, "lane_role": 3, "ml_lane_role": 3, "net_worth": 12000},
        ]

        checked_players = fixExcess([5], [1], players)
        assert checked_players == self.expected_players

    def test_fixExcess3(self):
        players = [
            {"hero_id": 1, "lane_role": 1, "ml_lane_role": 1, "net_worth": 10000},
            {"hero_id": 2, "lane_role": 1, "ml_lane_role": 5, "net_worth": 5000},
            {"hero_id": 3, "lane_role": 2, "ml_lane_role": 2, "net_worth": 15000},
            {"hero_id": 4, "lane_role": 3, "ml_lane_role": 3, "net_worth": 7800},
            {"hero_id": 5, "lane_role": 3, "ml_lane_role": 3, "net_worth": 12000},
        ]

        checked_players = fixExcess([3], [4], players)
        assert checked_players == self.expected_players

    def test_fixExcess4and5(self):
        players = [
            {"hero_id": 1, "lane_role": 1, "ml_lane_role": 5, "net_worth": 10000},
            {"hero_id": 2, "lane_role": 1, "ml_lane_role": 5, "net_worth": 5000},
            {"hero_id": 3, "lane_role": 2, "ml_lane_role": 2, "net_worth": 15000},
            {"hero_id": 4, "lane_role": 3, "ml_lane_role": 4, "net_worth": 7800},
            {"hero_id": 5, "lane_role": 3, "ml_lane_role": 4, "net_worth": 12000},
        ]

        checked_players = fixExcess([4, 5], [3, 1], players)
        assert checked_players == self.expected_players

    def test_findHighestAndLowest(self):
        players = [
            {"hero_id": 1, "lane_role": 1, "ml_lane_role": 1, "net_worth": 10000},
            {"hero_id": 2, "lane_role": 1, "ml_lane_role": 5, "net_worth": 5000},
        ]
        highest, lowest = findHighestAndLowest(players)
        assert highest == players[0]
        assert lowest == players[1]

class TestFindRole:
    def test_findRole1(self):
        player = {"last_hits": 500, "gpm": 700, "obs_placed": 1, "lane_role": 1}
        role = findRole(player, "immortal")
        assert role == 1

    def test_findRole2(self):
        player = {"last_hits": 500, "gpm": 700, "obs_placed": 1, "lane_role": 2}
        role = findRole(player, "immortal")
        assert role == 2

    def test_findRole3(self):
        player = {"last_hits": 500, "gpm": 700, "obs_placed": 1, "lane_role": 3}
        role = findRole(player, "immortal")
        assert role == 3

    def test_findRole4(self):
        player = {"last_hits": 200, "gpm": 500, "obs_placed": 10, "lane_role": 3}
        role = findRole(player, "immortal")
        assert role == 4

    def test_findRole5(self):
        player = {"last_hits": 200, "gpm": 500, "obs_placed": 10, "lane_role": 1}
        role = findRole(player, "immortal")
        assert role == 5

def setupPlayerTestingObject(ml_lane):
    player = {
        "personaname": "playername",
        "hero_id": 15,
        "gold_t": [0, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20],
        "xp_t": [0, 10],
        "lh_t": [0, 2],
        "is_radiant": True,
        "ml_lane_role": ml_lane,
        "item_0": 5,
        "item_1": 12,
        "item_2": 19,
        "item_3": 34,
        "item_4": 37,
        "item_5": 23,
        "item_neutral": 96,
        "backpack_0": 7,
        "backpack_1": 9,
        "backpack_2": 41,
        "level": 16,
        "net_worth": 12000,
        "gpm": 500,
        "xpm": 550,
        "last_hits": 100,
        "kills": 8,
        "assists": 10,
        "deaths": 4,
        "hero_damage": 10000,
        "tower_damage": 1000,
        "damage_taken": 500,
        "permanent_buffs": 5,
        "rank_tier": 81,
        "life_state_dead": 100,
        "buyback_log": [],
        "kills_log": [{"time": 1}, {"time": 3}],
        "multi_kills": 4,
        "kill_streaks": 2,
        "camps_stacked": 1,
        "stuns": 5,
        "max_hero_hit": 320,
        "runes_log": 0,
        "is_roaming": True,
        "obs_placed": 5,
        "sen_placed": 2,
        "hero_healing": 566,
        "duration": 1000,
    }
    return player


import os
import random
import tempfile

import pytest

import teek

SMILEY_PATH = os.path.join(
    os.path.dirname(os.path.abspath(__file__)), 'data', 'smiley.gif')

def test_width_and_height():
    image = teek.Image(file=SMILEY_PATH)
    assert image.width == 32
    assert image.height == 32

# tests that use this so that it returns True (for loops run) are marked slow
def slow_content_eq_check(image1, image2):
    # magic ftw, the double for loop is slow with big images which is why the
    # test images are small
    return (
        image1.width == image2.width and
        image1.height == image2.height and
        all(
            image1.get(x, y) == image2.get(x, y)
            for x in range(image1.width)
            for y in range(image1.height)
        )
    )

@pytest.mark.slow
def test_images_contain_same_data_util():
    image1 = teek.Image(file=SMILEY_PATH)
    image2 = teek.Image(file=SMILEY_PATH)
    assert slow_content_eq_check(image1, image1)
    assert slow_content_eq_check(image1, image2)

    image3 = teek.Image(width=1, height=2)
    assert not slow_content_eq_check(image1, image3)

def test_config(check_config_types):
    check_config_types(teek.Image(file=SMILEY_PATH).config, 'Image')

@pytest.mark.slow
def test_data_base64():
    with open(SMILEY_PATH, 'rb') as file:
        binary_data = file.read()

    assert slow_content_eq_check(teek.Image(file=SMILEY_PATH),
                                 teek.Image(data=binary_data))

@pytest.mark.slow
def test_from_to_tcl():
    image1 = teek.Image(file=SMILEY_PATH)
    teek.tcl_eval(None, 'proc returnArg {arg} {return $arg}')
    image2 = teek.tcl_call(teek.Image, 'returnArg', image1)
    assert image1.to_tcl() == image2.to_tcl()   # no implicit copying
    assert image1 is not image2                 # no implicit cache
    assert slow_content_eq_check(image1, image2)

def test_eq_hash():
    image1 = teek.Image(file=SMILEY_PATH)
    image2 = teek.Image.from_tcl(image1.to_tcl())
    image3 = teek.Image(file=SMILEY_PATH)

    assert image1 == image2
    assert {image1: 'woot'}[image2] == 'woot'
    assert image1 != image3
    assert image2 != image3
    assert image2 != 'woot'

def test_delete_and_all_images():
    old_images = set(teek.Image.get_all_images())
    new_image = teek.Image()
    assert set(teek.Image.get_all_images()) == old_images | {new_image}
    new_image.delete()
    assert set(teek.Image.get_all_images()) == old_images

def test_repr():
    image = teek.Image(file=SMILEY_PATH)
    assert repr(image) == '<Image: from %s, 32x32>' % repr(SMILEY_PATH)
    image.delete()
    assert repr(image) == '<Image: from %s, deleted>' % repr(SMILEY_PATH)

    image2 = teek.Image(width=123, height=456)
    assert repr(image2) == '<Image: 123x456>'
    image2.delete()
    assert repr(image2) == '<Image: deleted>'

def test_in_use():
    image = teek.Image(file=SMILEY_PATH)
    assert image.in_use() is False
    window = teek.Window()
    assert image.in_use() is False

    widget = teek.Label(window, image=image)
    assert image.in_use() is True
    widget2 = teek.Label(window, image=image)
    assert image.in_use() is True
    widget.destroy()
    assert image.in_use() is True
    widget2.destroy()
    assert image.in_use() is False

def test_blank():
    image1 = teek.Image(file=SMILEY_PATH)
    image2 = image1.copy()
    image2.blank()
    assert not slow_content_eq_check(image1, image2)      # not slow

@pytest.mark.slow
def test_read():
    image1 = teek.Image(file=SMILEY_PATH)
    assert image1.width > 0 and image1.height > 0

    image2 = teek.Image()
    assert image2.width == image2.height == 0
    image2.read(SMILEY_PATH)
    assert (image2.width, image2.height) == (image1.width, image1.height)
    assert slow_content_eq_check(image1, image2)

def test_redither():
    # no idea what this should do, so let's test that it does something...
    # except that it doesn't seem to actually do anything to the smiley, so
    # just test that it calls the Tcl redither command
    called = []
    fake_image = teek.create_command(called.append, [str])
    teek.Image.from_tcl(fake_image).redither()
    assert called == ['redither']

def test_transparency():
    image = teek.Image(file=SMILEY_PATH)
    x = random.randint(0, image.width - 1)
    y = random.randint(0, image.height - 1)
    assert image.transparency_get(x, y) is False
    image.transparency_set(x, y, True)
    assert image.transparency_get(x, y) is True
    image.transparency_set(x, y, False)
    assert image.transparency_get(x, y) is False

@pytest.mark.slow
def test_write():
    image1 = teek.Image(file=SMILEY_PATH)
    with tempfile.TemporaryDirectory() as tmpdir:
        asd = os.path.join(tmpdir, 'asd.gif')
        image1.write(asd, format='gif')
        image2 = teek.Image(file=asd)
    assert slow_content_eq_check(image1, image2)

def test_get_bytes():
    image = teek.Image(file=SMILEY_PATH)

    with tempfile.TemporaryDirectory() as tmpdir:
        asd = os.path.join(tmpdir, 'asd.gif')
        image.write(asd, format='gif')
        with open(asd, 'rb') as file:
            actual_gif_bytes = file.read()

    assert image.get_bytes('gif') == actual_gif_bytes