from flask import Flask, request
import json
from database import *
import payment

import logging
import coloredlogs

loggerTest = logging.getLogger("bee_TEST")
loggerTest.setLevel(logging.DEBUG)
coloredlogs.install(level='DEBUG', logger=loggerTest, milliseconds=True, fmt='[%(levelname)s]-> %(message)s')

app = Flask(__name__)

# CRUD - READ requests
@app.route('/get_all_users')
def get_all_users():
    all_users_dict = get_all_users_from_db()
    all_users_resp = {}
    all_users_resp['users'] = all_users_dict
    all_users_resp['code'] = 200
    return json.dumps(all_users_resp)

@app.route('/set_current_active_user', methods=['POST'])
def set_current_active_user():
    new_vehicle_name = request.json["vehicle_name"]
    resp = {}
    resp['msg'] = "Success"
    resp['code'] = 200
    return json.dumps(resp)

@app.route('/get_all_vehicles')
def get_all_vehicles():
    all_vehicles_dict = get_all_vehicles_from_db()
    all_vehicles_resp = {}
    all_vehicles_resp['vehicles'] = all_vehicles_dict
    all_vehicles_resp['code'] = 200
    return json.dumps(all_vehicles_resp)

@app.route('/get_all_vehicle_items')
def get_all_vehicle_items():
    all_vehicle_items_dict = get_all_vehicle_items_from_db()
    all_vehicle_items_resp = {}
    all_vehicle_items_resp['items'] = all_vehicle_items_dict
    all_vehicle_items_resp['code'] = 200
    return json.dumps(all_vehicle_items_resp)

@app.route('/get_all_user_vehicle_items', methods=['POST'])
def get_all_user_vehicle_items():
    selected_user_name = request.json["user_name"]
    all_vehicle_items_dict = get_all_user_vehicle_items_from_db(selected_user_name)
    all_vehicle_items_resp = {}
    all_vehicle_items_resp['items'] = all_vehicle_items_dict
    all_vehicle_items_resp['code'] = 200
    return json.dumps(all_vehicle_items_resp)

# CRUD - CREATE requests
@app.route('/create_new_user', methods=['POST'])
def create_new_user():
    new_user_name = request.json["user_name"]
    create_user(new_user_name)
    resp = {}
    resp['msg'] = "Success"
    resp['code'] = 200
    return json.dumps(resp)

@app.route('/create_new_vehicle', methods=['POST'])
def create_new_vehicle():
    new_vehicle_name = request.json["vehicle_name"]
    create_vehicle(user_name="BeeSuppDefUser", user_vehicle_name=new_vehicle_name)
    resp = {}
    resp['msg'] = "Success"
    resp['code'] = 200
    return json.dumps(resp)

''' TODO
@app.route('/create_new_vehicle_item', methods=['POST'])
def create_new_vehicle_item():
    new_item_category = request.json["new_item_category"]
    new_item_name = request.json["new_item_name"]
    new_item_description = request.json["new_item_description"]
    new_item_price = request.json["item_name"]
    new_item_category = request.json["item_name"]
    new_vehicle_item = request.json["item_name"]
    create_vehicle_item(new_item_category, new_item_name, new_item_description, new_item_price, new_item_image, "BeeSuppDefVehicle", "BeeSuppDefUser")
    resp = {}
    resp['msg'] = "Success"
    resp['code'] = 200
    return json.dumps(resp)
'''

@app.route('/buy_vehicle_item', methods=['POST'])
def buy_vehicle_item():
    buy_item_name = request.json["buy_item_name"]
    loggerTest.warning("satin alinan: " + buy_item_name)
    pay_res = payment.buy(buy_item_name)
    resp = {}
    if pay_res:
        resp['msg'] = "Success"
        resp['code'] = 200
        change_item_owner(buy_item_name, "Ertan")
    else:
        resp['msg'] = "Failure"
        resp['code'] = 1001
    return json.dumps(resp)

@app.route('/logged_user', methods=['POST'])
def logged_user():
    logged_user_id = request.json["user_id"]
    if logged_user_id == 0:
        loggerTest.warning("log user alinan: Kivanc")
    else:
        loggerTest.warning("log user alinan: Ertan")
    resp = {}
    resp['msg'] = "Success"
    resp['code'] = 200
    return json.dumps(resp)

if __name__ == "__main__":
    init_database_tables()
    app.run(debug=True, host='0.0.0.0', port=5888)


import streamlit as st
import yfinance as yf
import pandas as pd
import plotly.graph_objects as go
from datetime import datetime, date
from libs.streamlithelper import plot_indicators
from itertools import combinations

@st.cache
def get_data(stocks, start_dt, end_dt):
    data = yf.download(stocks, start=start_dt, end=end_dt)['Adj Close']
    return data

def compute_rolling_returns(indexed, years):
    window = 252 * years
    indexed['portfolio'] = indexed.sum(axis=1)
    indexed['portfolio'] = indexed.portfolio*100 / indexed.portfolio.iloc[0]
    indexed['window_return'] = indexed['portfolio'] / indexed['portfolio'].shift(window) - 1
    indexed['max_roll'] = indexed['portfolio'].rolling(window, min_periods=window).max()
    indexed['daily_dd'] = indexed['portfolio'] / indexed['max_roll'] - 1.0
    indexed['window_dd'] = indexed['daily_dd'].rolling(window, min_periods=1).min()
    # indexed.dropna(inplace=True)
    return indexed

def app():

    # inputs
    start_dt = st.sidebar.date_input('Start Date', date(2010, 1, 1))
    end_dt = st.sidebar.date_input('End Date (Today)', datetime.now().date())
    benchmark = st.sidebar.text_input('Benchmark', '^NSEI')
    years = st.sidebar.slider('Years', 1, 10, 1, 1)
    tickers = st.text_input('Stocks', 'ALKYLAMINE.NS, ASIANPAINT.NS,ASTRAL.NS,AXISBANK.NS,BAJFINANCE.NS,DIVISLAB.NS,GARFIBRES.NS,GMM.BO,HDFCAMC.NS,HDFCBANK.NS,HDFCLIFE.NS,ISEC.NS,KOTAKBANK.NS,LALPATHLAB.NS,LUMAXIND.NS,MOLDTKPAC.NS,NAUKRI.NS,PIDILITIND.NS,RELAXO.NS,STERTOOLS.NS')
    quantities = st.text_input('Quantity', '2,11,3,3,8,3,2,2,1,25,10,15,19,2,2,5,2,14,5,15')

    # Header
    st.title("Evaluate Portfolio!")
    st.write(f'Number of Stocks : {len(tickers.split(","))}')

    tickers = [x.strip() for x in tickers.split(',')]
    quantities = [int(x.strip()) for x in quantities.split(',')]
    portfolio_data = get_data(tickers, start_dt, end_dt)
    benchmark_data = get_data(benchmark, start_dt, end_dt)

    if len(tickers) == 1:
        values = [portfolio_data.iloc[-1] for x in tickers]
    else:
        values = [portfolio_data[x].iloc[-1] for x in tickers]

    st.header('Portfolio table')
    port_table = pd.DataFrame({
        'Stocks':tickers,
        'Price': values,
        'Qty': quantities,
    }).set_index('Stocks')
    port_table['Value'] = port_table.Price * port_table.Qty
    port_table['Weight'] = port_table['Value']*100/port_table.Value.sum()
    port_table = port_table.sort_values('Weight', ascending=False)
    st.table(port_table)

    st.header(f'Investment Amount : {round(port_table.Value.sum(),2)}')

    indexed = portfolio_data*100/portfolio_data.iloc[0]
    if len(tickers) == 1:
        indexed = indexed * quantities
        indexed = indexed.to_frame()
    else:
        for ticker, qty in zip(tickers,quantities):
            indexed[ticker] = indexed[ticker]*qty

    benchmark_indexed = benchmark_data*100*sum(quantities)/benchmark_data.iloc[0]

    # computing returns
    portfolio_returns = compute_rolling_returns(indexed, years)
    other_cols = [x for x in portfolio_returns.columns if x not in tickers]

    if len(tickers) > 1:
        null_tickers = portfolio_returns[tickers].isnull().sum()
        if len(null_tickers[null_tickers > 0].index) > 0:
            st.write('Not enough data for computing drawdowns for:', ','.join(list(null_tickers[null_tickers > 0].index)))
        non_null_tickers = [x for x in tickers if x not in list(null_tickers[null_tickers > 0].index)]
        portfolio_returns = portfolio_returns[non_null_tickers + other_cols]

    benchmark_returns = compute_rolling_returns(benchmark_indexed.to_frame(), years)

    st.subheader(f'Portfolio vs {benchmark} - Indexed Returns')
    # stock plot return plot
    fig_stock = go.Figure()
    fig_stock.add_trace(go.Scatter(
        x=benchmark_returns.index,
        y=benchmark_returns.portfolio,
        name=benchmark,
    ))
    fig_stock.add_trace(go.Scatter(
        x=portfolio_returns.index,
        y=portfolio_returns.portfolio,
        name='Portfolio',
    ))
    fig_stock.update_layout(
        margin=dict(l=50, r=20, b=20, t=20, pad=0),
        template='plotly_white',
        paper_bgcolor='white',
        plot_bgcolor='white',
        width=1200,
        height=500,
        yaxis=dict(zeroline=True),
        legend=dict(orientation='h', y=1.02, x=1, xanchor="right", yanchor="bottom", )
    )
    st.plotly_chart(fig_stock)

    st.title(f'Rolling Returns for Portfolio')

    col1, col2 = st.beta_columns(2)
    col1.subheader('Benchmark')
    col2.subheader('Portfolio')

    # # Daily return plot
    # st.subheader(f'Adjusted Close')
    # st.plotly_chart(fig_stock)
    #
    # median returns
    median_return = round(benchmark_returns.window_return.quantile(0.5) * 100, 2)
    fig_median_returns = plot_indicators(median_return, f'Median {years} year Return (%)', 300, 150)
    col1.plotly_chart(fig_median_returns)

    # median returns
    median_return = round(portfolio_returns.window_return.quantile(0.5) * 100, 2)
    fig_median_returns = plot_indicators(median_return, f'Median {years} year Return (%)', 300, 150)
    col2.plotly_chart(fig_median_returns)

    # Min Return
    min_return = round(benchmark_returns.window_return.min() * 100, 2)
    fig_min_returns = plot_indicators(min_return, f'Min {years} year Return (%)', 300, 150)
    col1.plotly_chart(fig_min_returns)

    min_return = round(portfolio_returns.window_return.min() * 100, 2)
    fig_min_returns = plot_indicators(min_return, f'Min {years} year Return (%)', 300, 150)
    col2.plotly_chart(fig_min_returns)

    # Avg Max drawdown
    avg_max_dd = round(benchmark_returns.window_dd.mean() * 100, 2)
    fig_avg_max_dd = plot_indicators(avg_max_dd, f'Average {years} year Max Drawdown (%)', 300, 150)
    col1.plotly_chart(fig_avg_max_dd)

    avg_max_dd = round(portfolio_returns.window_dd.mean() * 100, 2)
    fig_avg_max_dd = plot_indicators(avg_max_dd, f'Average {years} year Max Drawdown (%)', 300, 150)
    col2.plotly_chart(fig_avg_max_dd)

    # Avg drawdown
    avg_dd = round(benchmark_returns.daily_dd.mean() * 100, 2)
    fig_avg_dd = plot_indicators(avg_dd, f'Average {years} year Drawdown (%)', 300, 150)
    col1.plotly_chart(fig_avg_dd)

    # Avg drawdown
    avg_dd = round(portfolio_returns.daily_dd.mean() * 100, 2)
    fig_avg_dd = plot_indicators(avg_dd, f'Average {years} year Drawdown (%)', 300, 150)
    col2.plotly_chart(fig_avg_dd)

    # daily return plot
    fig_returns = go.Figure()
    fig_returns.add_trace(go.Scatter(
        x=benchmark_returns.dropna().index,
        y=benchmark_returns.dropna().window_return,
        name='Benchmark Returns',
    ))
    fig_returns.add_trace(go.Scatter(
        x=portfolio_returns.dropna().index,
        y=portfolio_returns.dropna().window_return,
        name='Portfolio Returns',
    ))
    fig_returns.update_layout(
        margin=dict(l=50, r=0, b=0, t=20, pad=0),
        template='plotly_white',
        paper_bgcolor='white',
        plot_bgcolor='white',
        width=1200,
        height=400,
        yaxis=dict(zeroline=True),
        legend=dict(orientation='h', y=1.02, x=1, xanchor="right", yanchor="bottom", )
    )

    # Daily return plot
    st.subheader(f'{int(years)} year rolling returns')
    st.plotly_chart(fig_returns)

    # drawdown plot
    fig_dd = go.Figure()
    fig_dd.add_trace(go.Scatter(
        x=benchmark_returns.dropna().index,
        y=benchmark_returns.dropna().daily_dd,
        name='Benchmark Drawdown',
        opacity=0.5

    ))
    fig_dd.add_trace(go.Scatter(
        x=portfolio_returns.dropna().index,
        y=portfolio_returns.dropna().daily_dd,
        name='Portfolio Drawdown',
        opacity=0.5

    ))
    y_axis_min = abs(benchmark_returns.window_dd.min())
    y_axis_min_p = abs(portfolio_returns.window_dd.min())
    y_min = max(y_axis_min, y_axis_min_p)*1.10
    fig_dd.update_layout(
        margin=dict(l=50, r=0, b=0, t=20, pad=0),
        template='plotly_white',
        paper_bgcolor='white',
        plot_bgcolor='white',
        width=1200,
        height=400,
        yaxis=dict(zeroline=True, range=[-y_min, 0.01]),
        legend=dict(orientation='h', y=1.02, x=1, xanchor="right", yanchor="bottom", )
    )

    # Daily return plot
    st.subheader(f'{int(years)} year drawdowns')
    st.plotly_chart(fig_dd)

    hp_ticker = st.selectbox('Holding period for positive returns', tickers)
    print(hp_ticker)
    if len(tickers) > 1:
        dfhp = portfolio_data[hp_ticker].dropna().reset_index(drop=True).values
    else:
        dfhp = portfolio_data.dropna().reset_index(drop=True).values
    hp_combos = list(combinations(range(0, len(dfhp)), 2))
    st.write('Number of data points :',len(hp_combos))
    hpdf = pd.DataFrame([(x[1]-x[0], (dfhp[x[1]]/dfhp[x[0]] - 1)) for x in hp_combos[:10000]], columns =['Holding Period','Return'])
    hpgroup = hpdf.groupby('Holding Period').min()
    hpgroup2 = hpdf.groupby('Holding Period').max()
    fighp = go.Figure()
    fighp.add_trace(go.Scatter(
        x=hpgroup.index,
        y=hpgroup.Return,
        name='MIN Return for that holding period',
    ))
    fighp.add_trace(go.Scatter(
        x=hpgroup2.index,
        y=hpgroup2.Return,
        name='MAX Return for that holding period',
    ))
    fighp.update_layout(
        margin=dict(l=50, r=0, b=0, t=20, pad=0),
        template='plotly_white',
        paper_bgcolor='white',
        plot_bgcolor='white',
        width=1200,
        height=400,
        legend=dict(orientation='h', y=1.02, x=1, xanchor="right", yanchor="bottom", )
    )
    fighp.update_xaxes(title_text='Holding Period')
    fighp.update_yaxes(title_text='Min Return')
    st.plotly_chart(fighp)


from requests import get
from bs4 import BeautifulSoup
import re

def index(letter:str='a', page:int=1):
    """

    Retrieve all the authors whom name starts with a given letter

    Args:
        letter (str, optional): The letter to filter by (case unsensitive), defaults to 'a'.
        page: (int, optional): Due to high number of authors, the authors are split in pages (typically 200 per page). Make sure the letter you're giving contains enough authors. Defaults to 1.

    Returns:
        list<``Author``>: The authors related to this letter

    Raises:
        TypeError: In case you gave a param of wrong type

    Examples:
        Viewing the first a author's snippet

        >>> print(all()['authors'][0].snippet())
        {'nationality': 'American', 'occupation': 'Musician', 'dates': {'birth': {'date': 'December 6', 'year': '1995'}, 'death': None}, 'related_authors': [<__main__.Athor object at 0x033898D0>, <__main__.Author object at 0x03389890>, <__main__.Author object at 0x03389D10>, <__main__.Author object at 0x03389D50>, <__main__.Author object at 0x03389D70>, <__main__.Author object at 0x03389DB0>, <__main__.Author object at 0x03389DD0>, <__main__.Author object at 0x03389DF0>]}

        Viewing all of 'a' letter authors

        >>> print(all()['authors'])
        {'authors': [<__main__.Author object at 0x03242CB0>...200], 'total_pages': 12, 'on_page': 200}
    """
    try:
        if(not type(page) == int):
            raise TypeError('The page must be a string')
        authors = f'https://www.brainyquote.com/authors/{letter.lower()}{str(page)}'
        body = get(authors).text
        parsed_body = BeautifulSoup(body, 'html.parser')
        data = {
            'authors': [],
            'total_pages': int(parsed_body.select_one('body > div.container.bqTopLevel > div > div.col-sm-8.col-md-8 > div:nth-child(4) > div > div > div > div > div > div > nav > ul').find_all('li')[len(parsed_body.select_one('body > div.container.bqTopLevel > div > div.col-sm-8.col-md-8 > div:nth-child(4) > div > div > div > div > div > div > nav > ul').find_all('li')) - 2].get_text()),
        }
        for tr in parsed_body.find('tbody').find_all('tr'):
            data['authors'].append(Author(tr.select_one('td:nth-child(1) > a').get('href').strip()))
        data['on_page'] = len(data['authors'])
        return data
    except Exception as e:
        raise e

def most_viewed(letter:str='a'):
    """

    Retrieve the most viewed authors of a given letter

    Args:
        letter (str, optional): The letter to filter by (case unsensitive), defaults to 'a'.

    Returns:
        list<``Author``>: The authors.

    Raises:
        TypeError: In case you gave a param of wrong type

    """
    try:
        endpoint = f'https://www.brainyquote.com/authors/{letter.lower()}'
        body = get(endpoint).text
        parsed_body = BeautifulSoup(body, 'html.parser')
        data = []
        for a in parsed_body.select('a.block-sm-az'):
            data.append(Author(re.sub('/authors/','',a.get('href'))))
        return data
    except Exception as e:
        raise e

class Author():
    def __init__(self, UUID:str):
        """
        Create an author object wich allows access to every piece of data available on the author including the name, a set of his quotes, biography and full on social info.

        Args:
            UUID (str): A special formatted version of the author's name , all lowercase and special chars removed. Check the ``misc.toUUID()`` to convert a name to an UUID
        """
        self.UUID = UUID

    def snippet(self):
        """
        Basic info about the author such as nationality, occupation, birth/death and related authors

        Returns:
            dict<`str`>: The dict that holds the info.

        Raises:
            ValueError: That UUID is probably wrong bud.

        Note:
            Includes instances of the ``Author`` class
        """
        try:
            endpoint = f'https://www.brainyquote.com/authors/{self.UUID}'
            body = get(endpoint).text
            parsed_body  = BeautifulSoup(body, 'html.parser')
            data = {
                'name': re.sub('Quotes', '',parsed_body.select_one('#bqNavBarCtrl > div > nav > div.navbar-header > h1').get_text()),
                'nationality': parsed_body.select_one('body > div.subnav-below-p > a:nth-child(1)').get_text(),
                'occupation': parsed_body.select_one('body > div.subnav-below-p > a:nth-child(2)').get_text(),
                'related_authors': []
            }
            for author in parsed_body.select_one('body > div.infScrollFooter > div.container-fluid > div > div.col-sm-7.col-md-8.block-style > div.bq_s > div').find_all('div'):
                data['related_authors'].append(Author(re.sub('Quotes', '', author.select_one('.link-name').get_text().strip())))
            return data
        except Exception as e:
            raise ValueError('That UUID is probably wrong bud.')

    def biography(self):
        """
        Retrieve the author's biography if available.

        Returns:
            str: The biography.

        Raises:
            ValueError: That UUID is wrong or the biography is not available.
        """
        try:
            endpoint = f'https://www.brainyquote.com/quotes/biography/{self.UUID}'
            body = get(endpoint).text
            parsed_body  = BeautifulSoup(body, 'html.parser')
            return parsed_body.select_one('div.bio-content').get_text().strip()
        except Exception as e:
            raise ValueError('That UUID is wrong or the biography is not available.')

    def quotes(self, page:int=1):
        """
        Retrieve the author's set of quotes, instances of the ``Quote`` class

        Args:
            page: (int, optional): Due to high number of quotes sometimes, they are split in pages. Make sure the author you've selected has enough pages. Defaults to 1.

        Returns:
            list<``quotes.Quote``>: The set of quotes.

        Raises:
            ValueError: That UUID is probably wrong bud.
            TypeError: Invalid type or format of the page parameter.

        Example:
            Retrieve the first page of abraham lincoln quotes

            >>> print(Author('abraham-lincoln').quotes())
            {'current_page': 1, 'total_pages': 9, 'elements': [<quotes.Quote object at 0x031A6C10>...165], 'on_page': 165}
        """
        from advanced_quotes.quotes import Quote
        try:
            if(not type(page) == int or page < 1):
                raise TypeError('Invalid type or format of the page parameter.')
            endpoint = f'https://www.brainyquote.com/authors/{self.UUID}-quotes_{page}'
            body = get(endpoint).text
            parsed_body  = BeautifulSoup(body, 'html.parser')
            data = {
                'current_page': page,
                'total_pages': int(parsed_body.select_one('body > div.infScrollFooter > div.bq_s.hideInfScroll.bq_pageNumbersCont > nav > ul').find_all('li')[len(parsed_body.select_one('body > div.infScrollFooter > div.bq_s.hideInfScroll.bq_pageNumbersCont > nav > ul').find_all('li')) - 2].get_text()),
                'elements': []
            }
            for quote in parsed_body.select_one('#quotesList').find_all('div'):
                try:
                    data['elements'].append(Quote(re.sub('/quotes/','',quote.select_one('div > div:nth-child(1) > div > a').get('href'))))
                except Exception as e:
                    continue
            data['on_page'] = len(data['elements'])
            return data
        except Exception as e:
            raise ValueError('That UUID is probably wrong bud.')


import pygame
import mextures
import os

WHITE = (255, 255, 255)
BLUE = (0, 0, 255)
GREY_BLUE = (132, 141, 160)
PURPLE = (217, 216, 227)
RED = (255, 0, 0)

def text_at_center(screen, font, message, x, y, is_active=False):
    text = font.render(message, True, BLUE if is_active else GREY_BLUE)
    text_rect = text.get_rect(center=(x, y))
    screen.blit(text, text_rect)

def text_at_left(screen, font, message, x, y, is_active=False):
    text = font.render(message, True, BLUE if is_active else GREY_BLUE)
    text_rect = text.get_rect(center=(0, y))
    text_rect.left = x
    screen.blit(text, text_rect)

def text_at_90_deg(screen, message, x, y, is_active=False):
    font = pygame.font.SysFont('Comic Sans MS', 15)
    for i in message:
        text = font.render(i, True, BLUE if is_active else GREY_BLUE)
        text_rect = text.get_rect(center=(x, y))
        screen.blit(text, text_rect)
        y -= 8
        x += 8

def button_with_text(screen, font, message, x, y, wight, is_active):
    pygame.draw.rect(screen, BLUE if is_active else GREY_BLUE, (x, y, wight, 50), 1)
    text_at_center(screen, font, message, wight / 2 + x, y + 20, is_active)

def radio_buttons(screen, font, box_name, labels, y, select_button_x, is_our_y, activ):
    text_at_center(screen, font, box_name, 1200 / 2, y - 50)
    lambda_x = 1200 / (len(labels) * 1.5)
    x = 1200 / (len(labels) * 1.8)
    for i in labels:
        color_activ = BLUE if labels.index(i) == select_button_x and is_our_y else GREY_BLUE
        text_at_left(screen, font, i, x + 20, y, color_activ == BLUE)
        pygame.draw.circle(screen, color_activ, [x, y], 10, 1)
        if activ == labels.index(i):
            pygame.draw.circle(screen, color_activ, [x, y], 5)
        x += lambda_x

def window_for_text(screen, font, labels, x, y, is_active):
    text_at_left(screen, font, labels[0], x + 30, y)
    button_with_text(screen, font, labels[1], x * 3 + 30, y - 20, 1200 / 4, is_active)

def is_degit_in_list(list):
    for i in list:
        if i[0]=='-':
            if not i[1:2].isdigit():
                return False
        else:
            if not i.isdigit():
                return False
    return True

def is_degit_float_for_list(content):
    for i in content:
        c = i.split('.')
        if len(c) > 2 or not is_degit_in_list(c):
            return False
    return True

class Window(object):
    def __init__(self):
        self.file_name = ""
        self.direction_objective_function = 0  # 0 - max, 1 - min
        self.tab = False
        self.decision_in = 0  # 0 - Процентах 1 - Количествах
        self.quantity = ["", ""]  # кол-во элементов | кол-во свойств
        self.target_function = []
        self.components = []
        self.select_window = 0
        self.select_button_x = self.select_button_y = 0
        self.step = [0, 0]
        self.no_errors = True

        self.label = {
            0: ["Выбрать файл", "Внести новые данные", "Выйти"],
            1: [0, 0, 0, 0, 0],
            2: [],
            3: [0, 0, 0, 0],
            4: [0],
            5: [],
            6: []
        }

    def window(self, screen):
        clock = pygame.time.Clock()
        while True:
            clock.tick(10)
            if self.tab and (self.select_window in [2, 4, 6] or (self.select_window == 5 and len(self.label[5]) != 1)):
                screen.fill(PURPLE)
            else:
                screen.fill(WHITE)
            font = pygame.font.SysFont('Comic Sans MS', 25)
            y = 720 / 4 + (self.step[0] * 70)
            if self.select_window == 1:
                window_for_text(screen, font, ["Введите название файла", self.file_name], 1200 / 6, y - 20, \
                                self.select_button_y == 0)
                window_for_text(screen, font, ["Введите кол-во элементов", self.quantity[0]], 1200 / 6, y + 50, \
                                self.select_button_y == 1)
                window_for_text(screen, font, ["Введите кол-во свойств", self.quantity[1]], 1200 / 6, y + 120, \
                                self.select_button_y == 2)
                button_with_text(screen, font, "Далее", 1200 / 4, y + 220, 1200 / 2, self.select_button_y == 3)
                button_with_text(screen, font, "Назад", 1200 / 4, y + 290, 1200 / 2, self.select_button_y == 4)
            elif self.select_window == 3:
                radio_buttons(screen, font, "Выберите направление функции", ["MAX", "MIN"], y, \
                              self.select_button_x, self.select_button_y == 0, self.direction_objective_function)
                text_at_center(screen, font, "Введите значения для целевой функции:", 1200 / 2, y + 90)
                x = 1200 / 4
                for i in range(int(self.quantity[0]) + 1):
                    text_at_90_deg(screen, "C" if i > int(self.quantity[0]) - 1 else self.label[2][i], \
                                   x + 15 + self.step[1] * -70, y + 170, \
                                   self.select_button_y == 1 and self.select_button_x == i)
                    button_with_text(screen, font, self.target_function[i], x + self.step[1] * -70, y + 180, 80, \
                                     self.select_button_y == 1 and self.select_button_x == i)
                    x += 80
                button_with_text(screen, font, "Далее", 1200 / 4, y + 260, 1200 / 2, self.select_button_y == 2)
                button_with_text(screen, font, "Назад", 1200 / 4, y + 330, 1200 / 2, self.select_button_y == 3)
            elif self.select_window == 4:
                message = self.label[2] + ["Знак", "Ограничено"]
                x = 110
                for i in range(len(message)):
                    if self.step[1] <= i:
                        text_at_90_deg(screen, message[i], x + 15, 230, not self.tab and self.select_button_x == i)
                        x += 100
                y = 250
                for i in range(int(self.quantity[1])):
                    if self.step[0] <= i:
                        x = 110
                        text_at_left(screen, font, str(i + 1), 30, y + 25, not self.tab and self.select_button_y == i)
                        for l in range(len(self.components[0])):
                            if self.step[1] <= l:
                                button_with_text(screen, font, self.components[i][l], x, y, 100, \
                                                 not self.tab and self.select_button_y == i and self.select_button_x == l)
                                x += 100
                        y += 50
            elif self.select_window == 5:
                mexture = mextures.Mextures('mixtures/' + str(self.file_name) + '.txt')
                self.quantity[0] = str(len(mexture.matrix.elements_name))
                if mexture.create_answer:
                    self.label[5] = [0, 0]
                    y = 180
                    answer = self.create_answer_format(mexture.answer)
                    for i in range(len(mexture.matrix.elements_name)):
                        text_at_center(screen, font, str(mexture.matrix.elements_name[i]) + ' = ' + str(answer[i]), \
                                       1200 / 2, y + self.step[0] * (-40), self.select_button_y == i and not self.tab)
                        y += 40
                    pygame.draw.rect(screen, WHITE if self.tab else PURPLE, (0, 0, 1200, 140))
                    pygame.draw.rect(screen, GREY_BLUE, (-1, -1, 1200 + 1, 140 + 1), 1)
                    text_at_center(screen, font, "Для составления смеси по вашему запросу, потребуется:", 1200 / 2, 100)
                    pygame.draw.rect(screen, WHITE if self.tab else PURPLE, (0, 420, 1200, 500))
                    pygame.draw.rect(screen, GREY_BLUE, (-1, 420, 1200 + 1, 500 + 1), 1)
                    text_at_center(screen, font, "Итоговая сумма будет равна:  " + str(mexture.summ), 1200 / 2, 450)
                    radio_buttons(screen, font, "Вывести ответ в ...", ['Процентах', "Количествах"], 570, \
                                  self.select_button_x, self.tab and self.select_button_y == 0, self.decision_in)
                    button_with_text(screen, font, "Завершить", 1200 / 4, 630, 1200 / 2, \
                                     self.tab and self.select_button_y == 1)
                else:
                    self.label[5] = [0]
                    text_at_center(screen, font, "Задача не имеет решения", 1200 / 2, 720 / 2 - 50)
                    button_with_text(screen, font, "Завершить", 1200 / 4, 630, 1200 / 2, self.select_button_y == 0)
            elif self.select_window in [0, 2, 6]:
                if self.select_window == 0:
                    y = 300
                for i in range(len(self.label[self.select_window])):
                    button_with_text(screen, font, self.label[self.select_window][i], 1200 / 4,
                                     y - 70 + self.step[0] * -140, 1200 / 2, \
                                     i == self.select_button_y and (not self.tab or self.select_window not in [2, 6]))
                    y += 70
            if self.select_window == 0:
                font = pygame.font.SysFont('Comic Sans MS', 40)
            else:
                font = pygame.font.SysFont('Comic Sans MS', 25)
            if self.select_window in [2, 6]:
                pygame.draw.rect(screen, WHITE if self.tab else PURPLE, (0, 0, 1200, 100))
                pygame.draw.rect(screen, GREY_BLUE, (-1, -1, 1200 + 1, 100 + 1), 1)
            window_name = ["Задача о смесях", "Введите данные:", "Введите названия элементов:", \
                           "Введите данные о целевой функции:", "Введите значения для ячеек:", "", \
                           "Выберите файл с данными для повторного расчета"]
            text_at_center(screen, font, window_name[self.select_window], 1200 / 2, 70)

            if self.select_window in [2, 4, 6]:
                pygame.draw.rect(screen, WHITE if self.tab else PURPLE, (0, 625, 1200, 500))
                pygame.draw.rect(screen, GREY_BLUE, (-1, 626, 1200 + 1, 500 + 1), 1)

                if self.select_window != 6:
                    button_with_text(screen, font, "Далее", 1200 / 4 - 20, 650, 1200 / 4, \
                                     self.tab and self.select_button_x == 0)
                    button_with_text(screen, font, "Назад", 1200 / 2 + 20, 650, 1200 / 4, \
                                     self.tab and self.select_button_x == 1)
                else:
                    button_with_text(screen, font, "Назад", 1200 / 4, 650, 1200 / 2, \
                                     self.tab and self.select_button_x == 0)
                font = pygame.font.SysFont('Comic Sans MS', 20)
                text_at_left(screen, font, "Нажмите: Tab для смены слоя", 1200 / 2 + 1200 / 4 - 20, 20)
            font = pygame.font.SysFont('Comic Sans MS', 20)
            if not self.no_errors:
                text = font.render("Данные введены неверно", True, RED)
                text_rect = text.get_rect(center=(0, 20))
                text_rect.left = 20
                screen.blit(text, text_rect)
            if self.select_window == 5:
                text_at_left(screen, font, "Нажмите: Tab для смены слоя", 1200 / 2 + 1200 / 4 - 20, 20)
            pygame.display.update()
            self.button()

    def button(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                exit()
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_UP or event.key == pygame.K_DOWN:
                    if self.select_window != 4:
                        self.select_button_x = 0
                if event.key == pygame.K_TAB and self.select_window not in [0, 1, 3]:
                    self.tab = not self.tab
                    self.select_button_y = 0
                    self.select_button_x = 0
                    self.step = [0, 0]
                if event.key == pygame.K_RETURN:
                    if self.select_window == 0:
                        self.file_name = ""
                        self.quantity = ["", ""]
                        if self.select_button_y == 0:
                            self.label[6] = []
                            for i in os.listdir('mixtures'):
                                self.label[6].append(i.replace('.txt', ''))
                            self.select_window = 6
                        elif self.select_button_y == 1:
                            self.select_window += 1
                            self.select_button_y = 0
                        else:
                            quit()
                    elif self.select_window == 1:
                        if self.select_button_y == 4:
                            self.select_window -= 1
                            self.x_y_0
                        elif self.select_button_y == 3:
                            self.no_errors = True
                            if "" == self.file_name or not is_degit_in_list(self.quantity):
                                self.no_errors = False
                            if self.no_errors:
                                self.label[2] = ["" for i in range(int(self.quantity[0]))]
                                self.target_function = ["" for i in range(int(self.quantity[0]))] + [""]
                                self.components = []
                                for i in range(int(self.quantity[1])):
                                    self.components.append(["" for l in range(int(self.quantity[0]))] + ["=", ""])
                                self.select_window += 1
                                self.x_y_0
                    elif self.select_window in [2, 4, 6] and self.tab:
                        if self.select_button_x == 0:
                            if self.select_window == 2:
                                self.no_errors = True
                                if "" not in self.label[2]:
                                    self.select_window += 1
                                    self.x_y_0
                                else:
                                    self.no_errors = False
                            elif self.select_window == 6:
                                self.select_window = 0
                                self.x_y_0
                            else:
                                self.no_errors = True
                                for i in self.components:
                                    elements = i.copy()
                                    elements.pop(-2)
                                    if i[-2] not in ["=", "<=", ">="] or (not is_degit_in_list(elements) and \
                                                                          not is_degit_float_for_list(elements)):
                                        self.no_errors = False
                                if self.no_errors:
                                    self.create_file
                                    self.select_window += 1
                                    self.x_y_0
                        else:
                            self.select_window -= 1
                            self.x_y_0
                    elif self.select_window == 3:
                        if self.select_button_y == 0:
                            self.direction_objective_function = self.select_button_x
                        elif self.select_button_y == 2:
                            self.no_errors = True
                            if not is_degit_in_list(self.target_function) and \
                                    not is_degit_float_for_list(self.target_function):
                                self.no_errors = False
                            if self.no_errors:
                                self.select_window += 1
                                self.x_y_0
                        elif self.select_button_y == 3:
                            self.select_window -= 1
                            self.x_y_0
                    elif self.select_window == 5 and len(self.label[5]) == 1:
                        self.select_window = 0
                        self.x_y_0
                    elif self.select_window == 5 and self.tab:
                        if self.select_button_y == 0:
                            self.decision_in = self.select_button_x
                        if self.select_button_y == 1:
                            self.select_window = 0
                            self.x_y_0
                    elif self.select_window == 6:
                        self.file_name = self.label[6][self.select_button_y]
                        self.select_window = 5
                        self.x_y_0
                elif event.key == pygame.K_DOWN or event.key == pygame.K_UP:
                    text = {pygame.K_UP: "top", pygame.K_DOWN: "bottom"}
                    if self.select_window == 4:
                        self.top_bottom(text[event.key], len(self.components))
                    elif self.select_window == 5 and len(self.label[5]) != 1 and not self.tab:
                        self.top_bottom(text[event.key], int(self.quantity[0]))
                    elif self.select_window != 2 or not self.tab:
                        self.top_bottom(text[event.key], len(self.label[self.select_window]))
                elif event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
                    text = {pygame.K_LEFT: "left", pygame.K_RIGHT: "right"}
                    if self.tab and self.select_window in [2, 4, 5]:
                        self.left_right(text[event.key], 2)
                    elif self.select_window == 4:
                        self.left_right(text[event.key], len(self.components[0]))
                    elif self.select_window == 3:
                        if self.select_button_y == 0:
                            self.left_right(text[event.key], 2)
                        if self.select_button_y == 1:
                            self.left_right(text[event.key], len(self.components[0]) - 1)
                elif event.key == pygame.K_BACKSPACE:
                    if self.select_window == 4 and not self.tab:
                        self.components[self.select_button_y][self.select_button_x] = \
                            self.components[self.select_button_y][self.select_button_x][:-1]
                    elif self.select_window == 2 and not self.tab:
                        self.label[2][self.select_button_y] = self.label[2][self.select_button_y][:-1]
                    elif self.select_window == 1:
                        if self.select_button_y in [1, 2]:
                            self.quantity[self.select_button_y - 1] = self.quantity[self.select_button_y - 1][:-1]
                        elif self.select_button_y == 0:
                            self.file_name = self.file_name[:-1]
                    elif self.select_window == 3 and self.select_button_y == 1:
                        self.target_function[self.select_button_x] = self.target_function[self.select_button_x][:-1]
                elif self.select_window in [1, 2, 3, 4] and event.key != pygame.K_TAB:
                    if self.select_window == 4 and not self.tab \
                            and len(self.components[self.select_button_y][self.select_button_x]) < 7 and ( \
                                    (self.select_button_x != len(self.components[0]) - 2 and str(
                                        event.unicode) in "0123456789.-") or \
                                    (self.select_button_x == len(self.components[0]) - 2 and str(
                                        event.unicode) in ">=<")):
                        self.components[self.select_button_y][self.select_button_x] += str(event.unicode)
                    elif self.select_window == 2 and not self.tab:
                        self.label[2][self.select_button_y] += str(event.unicode)
                    elif self.select_window == 1:
                        if self.select_button_y in [1, 2] and str(event.unicode) in "0123456789":
                            self.quantity[self.select_button_y - 1] += str(event.unicode)
                        elif self.select_button_y == 0:
                            self.file_name += str(event.unicode)
                    elif self.select_window == 3 and self.select_button_y == 1 and str(event.unicode) in "0123456789.-" \
                            and len(self.target_function[self.select_button_x]) < 6:
                        self.target_function[self.select_button_x] += str(event.unicode)

    @property
    def create_file(self):
        with open('mixtures/' + str(self.file_name) + '.txt', 'w', encoding='utf-8') as f:
            f.write(str(" ".join(self.label[2]) + '\n'))
            mm = ["max", "min"]
            f.write(str(" ".join(self.target_function)) + ' -> ' + mm[self.direction_objective_function] + '\n')
            for i in self.components:
                f.write(str(" ".join(i)) + '\n')
            elem = ['1' for l in range(len(self.label[2]))]
            f.write(str(' '.join(elem)) + ' = 1\n')
            for i in range(len(self.label[2])):
                elem = ['0' for l in range(len(self.label[2]))]
                elem[i] = '1'
                f.write(str(' '.join(elem)) + ' <= 1\n')
                f.write(str(' '.join(elem)) + ' >= 0\n')

    @property
    def x_y_0(self):
        self.no_errors = True
        self.select_button_y = 0
        self.select_button_x = 0
        self.step = [0, 0]
        self.tab = False

    def top_bottom(self, orientation, count):
        if orientation == "top":
            self.select_button_y -= 1
            if count > 7 and self.select_button_y < count - 6 and self.step[0] != 0:
                self.step[0] -= 1
            if self.select_button_y < 0:
                self.select_button_y = count - 1
                if count > 7:
                    self.step[0] = count - 7
        else:
            self.select_button_y += 1
            if count > 7 and self.step[0] != count - 7:
                self.step[0] += 1
            if self.select_button_y == count:
                self.select_button_y = 0
                self.step[0] = 0

    def left_right(self, orientation, count):
        if orientation == "left":
            self.select_button_x -= 1
            if count > 10 and self.select_button_x < count - 9:
                self.step[1] -= 1
            if self.select_button_x < 0:
                self.select_button_x = count - 1
                if count > 10:
                    self.step[1] = count - 10
        else:
            self.select_button_x += 1
            if count > 10 and self.step[1] != count - 10:
                self.step[1] += 1
            if self.select_button_x == count:
                self.select_button_x = 0
                self.step[1] = 0

    def create_answer_format(self, mexture):
        if self.decision_in == 1:
            return mexture
        elif self.decision_in == 0:
            for i in range(len(mexture)):
                mexture[i] = str(round(mexture[i] * 100)) + '%'
            return mexture

pygame.init()
WIGHT, HEIGHT = 1200, 720
screen = pygame.display.set_mode((1200, 720), pygame.SCALED)

wind = Window()
wind.window(screen)


import os

import dotenv
from discord.ext import commands

dotenv.load_dotenv("../../")

BOT_PREFIX = os.getenv('PREFIX')

class guideonping(commands.Cog):

    def __init__(self, bot):

        self.bot = bot

    @commands.Cog.listener()
    async def on_message(self, message):

        ping = f"@!{self.bot.user.id}"

        if ping in message.content:

            await message.channel.send(f"What is it {message.author.mention}?\nPlease do `{BOT_PREFIX}help` if you want to know how to use me!\nYou can also DM me to use me!")

def setup(bot):

    bot.add_cog(guideonping(bot))


from pathlib import Path

import mock
import numpy as np
import pytest

from eddington.io_util import save_as_csv, save_as_excel
from tests.util import assert_calls

CONTENT = [np.random.uniform(0, 1, size=12) for _ in range(20)]
EPSILON = 1e-3
DEFAULT_SHEET = "default_sheet"

@pytest.fixture
def mock_openpyxl_workbook(mocker):
    workbook_mock = mocker.patch("openpyxl.Workbook")
    workbook_mock.return_value.active.title = DEFAULT_SHEET
    return workbook_mock

@pytest.fixture
def mock_csv_writer(mocker):
    return mocker.patch("csv.writer")

def assert_workbook(mock_openpyxl_workbook, sheet_name, saved_file_path):
    mock_openpyxl_workbook.assert_called_once_with()
    workbook = mock_openpyxl_workbook.return_value
    worksheet = workbook.active
    assert worksheet.title == sheet_name
    assert_calls(worksheet.append, [([record], {}) for record in CONTENT], rel=EPSILON)
    workbook.save.assert_called_once_with(saved_file_path)

def test_save_as_excel_without_sheet_name(mock_openpyxl_workbook):
    output_directory = "/path/to/directory"
    file_name = "data"
    save_as_excel(
        content=CONTENT, output_directory=output_directory, file_name=file_name
    )
    assert_workbook(
        mock_openpyxl_workbook,
        sheet_name=DEFAULT_SHEET,
        saved_file_path=Path("/path/to/directory/data.xlsx"),
    )

def test_save_as_excel_with_sheet_name(mock_openpyxl_workbook):
    output_directory = "/path/to/directory"
    file_name = "data"
    sheet_name = "sheet1"
    save_as_excel(
        content=CONTENT,
        output_directory=output_directory,
        file_name=file_name,
        sheet=sheet_name,
    )
    assert_workbook(
        mock_openpyxl_workbook,
        sheet_name=sheet_name,
        saved_file_path=Path("/path/to/directory/data.xlsx"),
    )

def test_save_as_csv(mock_csv_writer):
    output_directory = "/path/to/directory"
    file_name = "data"
    mock_open = mock.mock_open()
    with mock.patch("eddington.io_util.open", mock_open):
        save_as_csv(
            content=CONTENT, file_name=file_name, output_directory=output_directory
        )
    mock_open.assert_called_once_with(
        Path("/path/to/directory/data.csv"), mode="w+", newline="", encoding="utf-8"
    )
    mock_csv_writer.return_value.writerows.assert_called_once_with(CONTENT)


from typing import List

def read4(buf4: List[str]) -> int:
    # Assume this function is provided and reads 4 characters from a file.
    pass

class Solution:
    def __init__(self):
        self.leftover = [None] * 4
        self.leftover_count = 0
        self.leftover_start = 0

    def read(self, buf: List[str], n: int) -> int:
        total_read = 0

        while total_read < n:
            if self.leftover_count > 0:
                # Copy leftover characters to buf
                to_copy = min(self.leftover_count, n - total_read)
                buf[total_read:total_read + to_copy] = self.leftover[self.leftover_start:self.leftover_start + to_copy]
                total_read += to_copy
                self.leftover_count -= to_copy
                self.leftover_start += to_copy
            else:
                # Call read4 and copy characters to buf
                buf4 = [""] * 4
                read4_count = read4(buf4)
                if read4_count == 0:
                    break  # No more characters to read

                to_copy = min(read4_count, n - total_read)
                buf[total_read:total_read + to_copy] = buf4[:to_copy]
                total_read += to_copy

                # Update leftover characters
                self.leftover[:read4_count - to_copy] = buf4[to_copy:read4_count]
                self.leftover_count = read4_count - to_copy
                self.leftover_start = 0

        return total_read

import unittest

class Test(unittest.TestCase):
    def test_read(self):
        solution = Solution()
        self.assertEqual(solution.read(["a", "b", "c", "d"], 4), 4)
        self.assertEqual(solution.read(["a", "b", "c", "d"], 1), 1)

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

coding-challenges/sources/leetcode/158. Read N Characters Given read4 II - Call Multiple Times/158-ReadNCharactersGivenread4II-CallMultipleTimes.py


import itertools

import numpy as np
import pytest
import torch

from ..internal_graph import *
from ..torchir_passes import *

def _build_flattening_test_graph():
    # This test graph is:
    #    graph(
    #        %1 : (Tensor[1, 1], (Tensor[1, 2], Tensor[1, 3]))
    #    ):
    #    %2, %3 = tupleunpack[](%1)
    #    %4, %5 = tupleunpack[](%3)
    #    %6 = tupleconstruct[](%2, %4)
    #    %7 = tupleconstruct[](%6, %5)
    #    return (%7)
    #
    # And if you were to run the graph it would turn
    #    (a, (b, c))
    # into
    #    ((a, b), c)

    graph_params = {}
    graph_inputs = OrderedDict()
    graph_inputs["1"] = (
        torch.rand(1, 1),
        (
            torch.rand(1, 2),
            torch.rand(1, 3),
        ),
    )
    graph_nodes = [
        InternalTorchIRNode(
            inputs=["1"],
            outputs=["2", "3"],
            kind="tupleunpack",
        ),
        InternalTorchIRNode(
            inputs=["3"],
            outputs=["4", "5"],
            kind="tupleunpack",
        ),
        InternalTorchIRNode(
            inputs=["2", "4"],
            outputs=["6"],
            kind="tupleconstruct",
        ),
        InternalTorchIRNode(
            inputs=["6", "5"],
            outputs=["7"],
            kind="tupleconstruct",
        ),
    ]
    graph_outputs = ["7"]

    return InternalTorchIRGraph(
        nodes=graph_nodes,
        params=graph_params,
        inputs=graph_inputs,
        outputs=graph_outputs,
    )

class TestTorchPasses:
    """Class containing tests for InternalTorchIR optimization passes.
    """

    @pytest.fixture
    def set_random_seeds(self):
        torch.manual_seed(1)
        np.random.seed(1)

    def test_flatten_input_values(self):
        graph = _build_flattening_test_graph()

        flatten_graph_input_values(graph)

        # The graph input tuple should have been flattened.
        np.testing.assert_equal(len(graph.inputs.keys()), 3)
        # Tuple flattening should introduce two new ops.
        np.testing.assert_equal(len(graph.nodes), 6)
        # The new ops at the beginning of the graph should be a tupleconstruct.
        np.testing.assert_equal(graph.nodes[0].kind, "tupleconstruct")
        np.testing.assert_equal(graph.nodes[1].kind, "tupleconstruct")
        # The inputs to the tupleconstructs should be the new flattened inputs.
        input_names = [k for k in graph.inputs.keys()]
        np.testing.assert_equal(input_names[1:], graph.nodes[0].inputs)
        np.testing.assert_equal(input_names[0], graph.nodes[1].inputs[0])
        np.testing.assert_equal(graph.nodes[0].outputs[0], graph.nodes[1].inputs[1])
        # The last inserted tuple construct should produce the input for the
        # next op.
        np.testing.assert_equal(graph.nodes[1].outputs[0], graph.nodes[2].inputs[0])

    def test_flatten_output_values(self):
        graph = _build_flattening_test_graph()

        flatten_graph_output_values(graph)

        # The graph output tuple should have been flattened.
        np.testing.assert_equal(len(graph.outputs), 3)
        # The outputs of the graph should come from intermediate ops.
        np.testing.assert_equal(graph.outputs[0], graph.nodes[0].outputs[0])
        np.testing.assert_equal(graph.outputs[1], graph.nodes[1].outputs[0])
        np.testing.assert_equal(graph.outputs[2], graph.nodes[1].outputs[1])

    def test_transform_inplace_ops_graph(self):
        # The test graph is:
        #    graph(
        #        %x : Tensor[1],
        #    ):
        #      %1 = constant[value=0]()
        #      %2 = constant[value=10]()
        #      %3 = listconstruct[](%1)
        #      %4 = append[](%3, %2)
        #      return (%3)
        graph_params = {}
        graph_inputs = OrderedDict()
        graph_inputs["x"] = torch.rand(1)
        graph_nodes = [
            InternalTorchIRNode(
                inputs=[],
                attr={"value": 0},
                outputs=["1"],
                kind="constant",
            ),
            InternalTorchIRNode(
                inputs=[],
                attr={"value": 10},
                outputs=["2"],
                kind="constant",
            ),
            InternalTorchIRNode(
                inputs=["1"],
                outputs=["3"],
                kind="listconstruct",
            ),
            InternalTorchIRNode(
                inputs=["3", "2"],
                outputs=["4"],
                kind="append",
            ),
        ]
        graph_outputs = ["3"]
        graph = InternalTorchIRGraph(
            nodes=graph_nodes,
            params=graph_params,
            inputs=graph_inputs,
            outputs=graph_outputs,
        )
        for node in graph.nodes:
            node.parent = graph

        transform_inplace_ops(graph)

        np.testing.assert_equal(len(graph.outputs), 1)
        np.testing.assert_equal(graph.outputs[0], graph.nodes[-1].outputs[0])

    def test_transform_inplace_ops_loop(self):
        # The test graph is:
        #    graph(
        #        %x : Tensor[1],
        #    ):
        #      %1 = constant[value=True]()
        #      %2 = constant[value=-1]()
        #      %3 = constant[value=10]()
        #      %4 = listconstruct[](%2)
        #       = loop[](%3, %1)
        #        block(%i.1):
        #          %6 = append[](%4, %i.1)
        #        return (%1)
        #    return (%4)
        graph_params = {}
        graph_inputs = OrderedDict()
        graph_inputs["x"] = torch.rand(1)
        loop_block = InternalTorchIRBlock(
            inputs=["i.1"],
            outputs=["1"],
            nodes=[
                InternalTorchIRNode(
                    inputs=["4", "i.1"],
                    outputs=["6"],
                    kind="append",
                ),
            ],
        )
        loop_block.nodes[0].parent = loop_block
        loop_node = InternalTorchIRNode(
            inputs=["3", "1"],
            outputs=[],
            kind="loop",
            blocks=[loop_block],
        )
        loop_block.parent = loop_node
        graph_nodes = [
            InternalTorchIRNode(
                inputs=[],
                attr={"value": True},
                outputs=["1"],
                kind="constant",
            ),
            InternalTorchIRNode(
                inputs=[],
                attr={"value": -1},
                outputs=["2"],
                kind="constant",
            ),
            InternalTorchIRNode(
                inputs=[],
                attr={"value": 10},
                outputs=["3"],
                kind="constant",
            ),
            InternalTorchIRNode(
                inputs=["2"],
                outputs=["4"],
                kind="listconstruct",
            ),
            loop_node,
        ]
        graph_outputs = ["4"]
        graph = InternalTorchIRGraph(
            nodes=graph_nodes,
            params=graph_params,
            inputs=graph_inputs,
            outputs=graph_outputs,
        )
        for node in graph.nodes:
            node.parent = graph

        transform_inplace_ops(graph)

        # There should be an additional input to the loop.
        np.testing.assert_equal(len(loop_node.inputs), 3)
        # That input should be the output of the previous op.
        np.testing.assert_equal(loop_node.inputs[2], graph.nodes[3].outputs[0])
        # The loop block should have an additional input.
        np.testing.assert_equal(len(loop_block.inputs), 2)
        # The loop block's new input should be the input to append.
        np.testing.assert_equal(loop_block.inputs[1], loop_block.nodes[0].inputs[0])
        # The loop block should have an additional output.
        np.testing.assert_equal(len(loop_block.outputs), 2)
        # Append's output should be returned from the loop block.
        np.testing.assert_equal(loop_block.outputs[1], loop_block.nodes[0].outputs[0])
        # The loop should now have an output.
        np.testing.assert_equal(len(loop_node.outputs), 1)
        # The loop's name should now be the name of its output.
        np.testing.assert_equal(loop_node.name, loop_node.outputs[0])
        # That graph output should now be the output of the graph.
        np.testing.assert_equal(loop_node.outputs[0], graph.outputs[0])

    @pytest.mark.xfail(reason="rdar://64235006")
    def test_transform_inplace_ops_if(self):
        # The test graph is:
        #    graph(
        #        %x : Tensor[1],
        #    ):
        #      %1 = constant[value=True]()
        #      %2 = constant[value=0]()
        #      %3 = constant[value=1]()
        #      %4 = listconstruct[](%2)
        #       = if[](%1)
        #        block0():
        #          %5 = append[](%4, %3)
        #        return ()
        #        block1():
        #          %6 = append[](%4, %2)
        #        return ()
        #    return (%4)
        graph_params = {}
        graph_inputs = OrderedDict()
        graph_inputs["x"] = torch.rand(1)
        if_true_block = InternalTorchIRBlock(
            inputs=[],
            outputs=[],
            nodes=[
                InternalTorchIRNode(
                    inputs=["4", "3"],
                    outputs=["5"],
                    kind="append",
                ),
            ],
        )
        if_true_block.nodes[0].parent = if_true_block
        if_false_block = InternalTorchIRBlock(
            inputs=[],
            outputs=[],
            nodes=[
                InternalTorchIRNode(
                    inputs=["4", "2"],
                    outputs=["6"],
                    kind="append",
                ),
            ],
        )
        if_false_block.nodes[0].parent = if_false_block
        if_node = InternalTorchIRNode(
            inputs=["1"],
            outputs=[],
            kind="if",
            blocks=[if_true_block, if_false_block],
        )
        if_true_block.parent = if_node
        if_false_block.parent = if_node
        graph_nodes = [
            InternalTorchIRNode(
                inputs=[],
                attr={"value": True},
                outputs=["1"],
                kind="constant",
            ),
            InternalTorchIRNode(
                inputs=[],
                attr={"value": 0},
                outputs=["2"],
                kind="constant",
            ),
            InternalTorchIRNode(
                inputs=[],
                attr={"value": 1},
                outputs=["3"],
                kind="constant",
            ),
            InternalTorchIRNode(
                inputs=["2"],
                outputs=["4"],
                kind="listconstruct",
            ),
            if_node,
        ]
        graph_outputs = ["4"]
        graph = InternalTorchIRGraph(
            nodes=graph_nodes,
            params=graph_params,
            inputs=graph_inputs,
            outputs=graph_outputs,
        )
        for node in graph.nodes:
            node.parent = graph

        transform_inplace_ops(graph)

        # The true block should now have an output.
        np.testing.assert_equal(len(if_true_block.outputs), 1)
        # The true block should output the result of the append op.
        np.testing.assert_equal(if_true_block.outputs[0], if_true_block.nodes[0].outputs[0])
        # The false block should now have an output.
        np.testing.assert_equal(len(if_false_block.outputs), 1)
        # The false block should output the result of the append op.
        np.testing.assert_equal(if_false_block.outputs[0], if_false_block.nodes[0].outputs[0])
        # The if op should have an additional output.
        np.testing.assert_equal(len(if_node.outputs), 1)
        # The if's name should now be the name of its output.
        np.testing.assert_equal(if_node.name, if_node.outputs[0])
        # The graph output should be the if op output.
        np.testing.assert_equal(if_node.outputs[0], graph.outputs[0])


import auth
import threading
from random import randint

SPREADSHEET_ID = '1BkeZPUWZ87pGjaAkgoRSOeBhuOSn0Nw9V856wOgWZsM'
RHYME_NAME = "rhymes"
COMPLAINT_NAME = "complaints"
INDEX_COL = "A"
INDEX_ROW = "1"
DATA_COLUMN = "B"

def get_cell(sheet, cell : str) -> str:
    result = sheet.values().get(spreadsheetId=SPREADSHEET_ID,
                                range=cell).execute()
    vales = result.get("values")
    return str(vales[0][0])

def get_free_index(sheet, name : str) -> int:
    try:
        idx = get_cell(sheet, name + "!" + INDEX_COL + INDEX_ROW)
    except TypeError:
        return 1
    return int(idx)

def get_free_range(sheet, name : str) -> str:
    return name + "!" + DATA_COLUMN + str(get_free_index(sheet, name))

def increment_idx(sheet, name):
    idx = get_free_index(sheet, name)
    update_cell(sheet, idx+1, name + "!" + INDEX_COL + INDEX_ROW)

def update_cell(sheet, value, range_):
    update_body = {"values": [[value]]}
    respond = sheet.values().update(spreadsheetId=SPREADSHEET_ID, range=range_, body=update_body,
                                    valueInputOption="USER_ENTERED").execute()
    return respond

def add_text(text, name):
    sheet = auth.get_service().spreadsheets()
    range_ = get_free_range(sheet, name)

    respond = update_cell(sheet, text, range_)
    increment_idx(sheet, name)
    return respond

def add_rhyme(rhyme):
    t = threading.Thread(target=add_text, args=[rhyme, RHYME_NAME])
    t.deamon = True
    t.start()

def _save_rhyme_to_file():
    sheet = auth.get_service().spreadsheets()
    free_idx = get_free_index(sheet, RHYME_NAME)

    rhyme = ""
    if free_idx <= 1:
        rhyme = "Niestety, ale nic nie mam :/"
    else:
        idx = randint(1, free_idx-1)
        rhyme = get_cell(sheet, RHYME_NAME + "!" + DATA_COLUMN + str(idx))

    with open("rhyme.txt", 'w') as f:
        f.write(rhyme)

def save_rhyme_to_file(wait=False):
    t = threading.Thread(target=_save_rhyme_to_file, args=[])
    t.deamon = True
    t.start()
    if wait:
        t.join()

def load_rhyme_from_file():
    rhyme = ""
    with open("rhyme.txt", 'r') as f:
        rhyme = f.read()

    return rhyme

def add_complaint(complaint):
    t = threading.Thread(target=add_text, args=[complaint, COMPLAINT_NAME])
    t.deamon = True
    t.start()

if __name__=="__main__":
    pass


import numpy as np
import pylab as plt
from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
from skimage import io

from tracenet.utils.points import denormalize_points

COLORS = [[0.000, 0.447, 0.741], [0.850, 0.325, 0.098], [0.929, 0.694, 0.125],
          [0.494, 0.184, 0.556], [0.466, 0.674, 0.188], [0.301, 0.745, 0.933]]
CLASSES = [
    'cell'
]

def plot_traces(img, traces, return_image=False, size=6, n_points=2, ax=None):
    '''
    Plotting of the traces return by TraceNet on top of the original image.
    Input traces and images are provided as torch tensors. Traces are normalized between 0 and 1.
    '''
    img = normalize(img.numpy())

    traces = denormalize_points(traces.reshape(-1, 2), img.shape[-2:]).reshape(-1, n_points * 2)

    if ax is None:
        fig = plt.figure(figsize=(size, size))
    plt.imshow(img)
    ax = plt.gca()
    colors = COLORS * 100
    for i in range(len(traces)):
        trace = np.fliplr(traces[i].reshape(-1, 2))
        ax.add_patch(plt.Polygon(trace, fill=False, color=colors[i], linewidth=3, closed=False))
    plt.axis('off')
    plt.tight_layout()

    if return_image:
        return __get_canvas(fig)

def plot_keypoints(img, points, labels, return_image=False, size=6):
    '''
    Plot keypoints (debugging).
    Points are provided in pixel coordinates.
    '''
    # normalize the image
    img = normalize(img.numpy())

    fig = plt.figure(figsize=(size, size))
    plt.imshow(img)
    ax = plt.gca()
    colors = COLORS * 100
    for i, lb in enumerate(np.unique(labels)):
        ind = np.where(labels == lb)
        ax.add_patch(plt.Polygon(np.fliplr(points[ind]), fill=False, color=colors[i], linewidth=3, closed=False))
    plt.axis('off')
    plt.tight_layout()

    if return_image:
        return __get_canvas(fig)
    plt.show()

def show_imgs(imgs, s=4, norm=True, titles=None):
    if titles is None:
        titles = [''] * len(imgs)
    fig, ax = plt.subplots(1, len(imgs), figsize=(len(imgs) * s, s))
    for i, img in enumerate(imgs):
        plt.sca(ax[i])
        im = img.numpy()
        if norm:
            im = normalize(im)
        io.imshow(im)
        plt.sca(ax[i])
        plt.title(titles[i])

def normalize(img):
    img = img - img.min()
    img = img / img.max()
    return img

def __get_canvas(fig):
    canvas = FigureCanvas(fig)
    canvas.draw()
    return np.frombuffer(canvas.tostring_rgb(),
                         dtype='uint8').reshape(fig.canvas.get_width_height()[::-1] + (3,))


from django.forms import ModelForm
from django.utils.translation import gettext_lazy as _
from django import forms

from administrativo.models import Persona, \
        Barrio, Casa, Departamento

class PersonaForm(ModelForm):
    class Meta:
        model = Persona
        fields = ['nombres', 'apellidos', 'cedula', 'correo']
        labels = {
            'nombres': _('Ingrese nombre por favor'),
            'apellidos': _('Ingrese apellido por favor'),
            'cedula': _('Ingrese cédula por favor'),
            'correo': _('Ingrese correo por favor'),
        }

class BarrioForm(ModelForm):
    class Meta:
        model = Barrio
        fields = ['nombre', 'siglas']
        labels = {
            'nombre': _('Ingrese nombre por favor'),
            'siglas': _('Ingrese siglas por favor'),
        }

class CasaForm(ModelForm):
    class Meta:
        model = Casa
        fields = ['propietario', 'direccion', 'barrio', 'valor', 'color', 'cuartos', 'pisos']

class CasaPersonaForm(ModelForm):

    def __init__(self, persona, *args, **kwargs):
        super(CasaPersonaForm, self).__init__(*args, **kwargs)
        self.initial['propietario'] = persona
        self.fields["propietario"].widget = forms.widgets.HiddenInput()
        print(persona)

    class Meta:
        model = Casa
        fields = ['propietario', 'direccion', 'barrio', 'valor', 'color', 'cuartos', 'pisos']

class DepartamentoForm(ModelForm):
    class Meta:
        model = Departamento
        fields = ['propietario', 'direccion', 'barrio', 'valor_bien', 'cuartos', 'valor_mensual']

class DepartamentoPersonaForm(ModelForm):

    def __init__(self, persona, *args, **kwargs):
        super(DepartamentoPersonaForm, self).__init__(*args, **kwargs)
        self.initial['propietario'] = persona
        self.fields["propietario"].widget = forms.widgets.HiddenInput()
        print(persona)

    class Meta:
        model = Departamento
        fields = ['propietario', 'direccion', 'barrio', 'valor_bien', 'cuartos', 'valor_mensual']


from __future__ import absolute_import, unicode_literals
import pytest
from psd_tools.psd.header import FileHeader

@pytest.fixture
def fixture():
    return (
        b'8BPS\x00\x01\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x96\x00'
        b'\x00\x00d\x00 \x00\x03'
    )

def test_header_from_to(fixture):
    header = FileHeader.frombytes(fixture)
    assert header.tobytes() == fixture

def test_header_exception(fixture):
    with pytest.raises(ValueError):
        FileHeader.frombytes(b' ' + fixture)


#!/usr/bin/python3

import pygame
from pygame.locals import *
import random
from math import ceil

from tetrominos import *

class GameState:
    READY, RUNNING, ANIMATING, PAUSED, LOST = range(5)

POINTS_FOR_LINES = (40, 100, 300, 1200)
CELL_SIZE = 25
WIDTH = 14
HEIGHT = 20
SIDEBAR_WIDTH = 6

EMPTY_CELL_COLOR = (20, 20, 20)
SEPARATOR_CELL_COLOR = (80, 80, 80)
TEXT_COLOR = (200, 200, 200)
FINAL_POSITION_COLOR = (40, 40, 40)

SHAPES = (TetrominoT, TetrominoI, TetrominoL, TetrominoJ, TetrominoS, TetrominoZ, TetrominoO)

FPS = 60

KEY_FIRST_REPEAT_DELAY = 250
KEY_REPEAT_INTERVAL = 20

HARD_DROP_ANIMATION_TIME = 200
MOVE_ANIMATION_TIME = 20

DROP_EVENT = pygame.USEREVENT

class Animation:
    __slots__ = ['obj', 'attr', 'start', 'end', 'interval', 'callback']
    def __init__(self, **kwargs):
        for k in kwargs:
            setattr(self, k, kwargs[k])

class Game:
    def __init__(self):
        pygame.init()
        pygame.display.set_caption('Tetrys')

        self.display = pygame.display.set_mode(((WIDTH + 1 + SIDEBAR_WIDTH) * CELL_SIZE, HEIGHT * CELL_SIZE),
                                               pygame.HWSURFACE | pygame.DOUBLEBUF)

        self.small_font = pygame.font.SysFont('droidsansmono', 15)
        self.large_font = pygame.font.SysFont('droidsansmono', 45)

        self.clock = pygame.time.Clock()
        self.delta = 0

        pygame.key.set_repeat(KEY_FIRST_REPEAT_DELAY, KEY_REPEAT_INTERVAL)

        self.shadow = pygame.Surface((WIDTH * CELL_SIZE, HEIGHT * CELL_SIZE), SRCALPHA)
        self.shadow.fill((0, 0, 0, 150))

        self.cell_images = { 'TetrominoL': pygame.image.load('L.png').convert_alpha(),
                             'TetrominoJ': pygame.image.load('J.png').convert_alpha(),
                             'TetrominoS': pygame.image.load('S.png').convert_alpha(),
                             'TetrominoZ': pygame.image.load('Z.png').convert_alpha(),
                             'TetrominoT': pygame.image.load('T.png').convert_alpha(),
                             'TetrominoO': pygame.image.load('O.png').convert_alpha(),
                             'TetrominoI': pygame.image.load('I.png').convert_alpha() }
        self.running = True
        self.space_pressed = False
        self.show_final = True
        self.animations = []

        self.start()

    def start(self):
        self.state = GameState.READY

        self.locked = [[None] * HEIGHT for _ in range(WIDTH)]

        self.level = 1
        self.lines = 0
        self.score = 0

        shape = random.choice(SHAPES)
        self.next = shape()
        self.pick_next()

        self.reset_drop_timer()

    def on_event(self, event):
        if event.type == pygame.QUIT:
            self.running = False
        elif event.type == KEYDOWN:
            if self.state == GameState.READY:
                self.state = GameState.RUNNING
            elif self.state == GameState.PAUSED:
                self.toggle_pause()
            elif self.state == GameState.LOST:
                if event.key == K_r:
                    self.start()
                    self.state = GameState.RUNNING
                elif event.key == K_q:
                    self.running = False
            elif event.key == K_RIGHT:
                self.right()
            elif event.key == K_LEFT:
                self.left()
            elif event.key == K_UP:
                self.rotate()
            elif event.key == K_DOWN:
                self.drop()
            # We don't want to repeat hard drops
            elif event.key == K_SPACE and not self.space_pressed:
                self.space_pressed = True
                self.hard_drop()
            elif event.key == K_q:
                self.running = False
            elif event.key == K_p:
                self.toggle_pause()
            elif event.key == K_g:
                self.add_garbage()
            elif event.key == K_f:
                self.show_final = not self.show_final
        elif event.type == KEYUP:
            if event.key == K_SPACE:
                self.space_pressed = False
        elif event.type == DROP_EVENT:
            self.drop()

    def reset_drop_timer(self):
        pygame.time.set_timer(DROP_EVENT, (11 - self.level) * 50)

    def pick_next(self):
        self.current = self.next
        shape = random.choice(SHAPES)
        self.next = shape()
        self.current.x = (WIDTH - self.current.get_width()) // 2
        if not self.can_place():
            self.state = GameState.LOST
        self.reset_drop_timer()

    def move(self, dx, dy):
        self.current.move(dx, dy)
        if not self.can_place():
            self.current.move(-dx, -dy)
            return False
        return True

    def can_place(self):
        for x, y in self.current:
            x = ceil(x)
            y = ceil(y)
            if x < 0 or x >= WIDTH or y < 0 or y >= HEIGHT or self.locked[x][y]:
                return False
        return True

    def update_final_y(self):
        dy = 0
        while self.can_place():
            self.current.move(0, 1)
            dy += 1
        self.final_y = ceil(self.current.y - 1)
        self.current.move(0, -dy)

    def animate(self, obj, attr, start, end, interval, callback=None):
        #self.state = GameState.ANIMATING
        animation = Animation(obj=obj, attr=attr, start=start, end=end,
                              interval=interval, callback=callback)
        self.animations.append(animation)

    def can_move(self, dx, dy):
        self.current.move(dx, dy)
        if self.can_place():
            self.current.move(-dx, -dy)
            return True
        else:
            self.current.move(-dx, -dy)
            return False

    def left(self):
        if self.state != GameState.RUNNING:
            return
        if self.can_move(-1, 0):
            self.animate(self.current, 'x', self.current.x, self.current.x - 1, MOVE_ANIMATION_TIME)

    def right(self):
        if self.state != GameState.RUNNING:
            return
        if self.can_move(1, 0):
            self.animate(self.current, 'x', self.current.x, self.current.x + 1, MOVE_ANIMATION_TIME)

    def rotate(self):
        if self.state != GameState.RUNNING:
            return
        self.current.rotate()
        if self.can_place():
            return
        # Try a wall kick to the left...
        self.current.move(-1, 0)
        if self.can_place():
            return
        # ...then a wall kick to the right...
        self.current.move(2, 0)
        if self.can_place():
            return
        # ...didn't work out
        self.current.rotate(-1)
        self.current.move(-1, 0)

    def drop(self):
        if self.state != GameState.RUNNING:
            return
        if self.can_move(0, 1):
            self.animate(self.current, 'y', self.current.y, self.current.y + 1,
                         MOVE_ANIMATION_TIME)
        else:
            self.on_drop_finished()

    def hard_drop(self):
        if self.state != GameState.RUNNING:
            return
        self.animate(self.current, 'y', self.current.y, self.final_y,
                     HARD_DROP_ANIMATION_TIME, self.on_drop_finished)

    def on_drop_finished(self):
        self.lock()
        self.pick_next()
        self.handle_complete_lines()

    def update_animations(self):
        #now = pygame.time.get_ticks()
        #delta = now - self.last_time
        #self.last_time = now

        next_animations = []
        for a in self.animations:
            #obj, attr, start, end, interval, callback = animation
            current = getattr(a.obj, a.attr) + (a.end - a.start) * self.delta / a.interval
            if current >= a.end >= a.start or current <= a.end <= a.start:
                setattr(a.obj, a.attr, a.end)
                if a.callback:
                    (a.callback)()
            else:
                setattr(a.obj, a.attr, current)
                next_animations.append(a)

        self.animations = next_animations
        #if not self.animations:
        #    self.state = GameState.RUNNING

    def handle_complete_lines(self):
        completed = 0
        for y in range(HEIGHT):
            if all(self.locked[x][y] for x in range(WIDTH)):
                completed += 1
                for x in range(WIDTH):
                    del self.locked[x][y]
                    self.locked[x].insert(0, None)

        self.lines += completed
        if completed > 0:
            self.score += (self.level + 1) * POINTS_FOR_LINES[completed - 1]
        self.level = min(10, 1 + self.lines // 10)

    def lock(self):
        for x, y in self.current:
            self.locked[ceil(x)][ceil(y)] = self.current.__class__.__name__
        self.current = None

    def add_garbage(self):
        if self.state != GameState.RUNNING:
            return

        for x in range(WIDTH):
            del self.locked[x][0]
            filler = random.choice([None, random.choice(list(self.cell_images))])
            self.locked[x].append(filler)

        self.score += 100

    def toggle_pause(self):
        if self.state == GameState.RUNNING:
            self.state = GameState.PAUSED
        elif self.state == GameState.PAUSED:
            self.state = GameState.RUNNING

    def on_loop(self):
        #delta = self.clock.tick(FPS)
        self.update_final_y()
        self.update_animations()

    def on_render(self):
        self.delta = self.clock.tick(FPS)

        self.display.fill((0, 0, 0))

        for x in range(WIDTH):
            for y in range(HEIGHT):
                if self.locked[x][y]:
                    self.draw_tetromino_cell((x, y), self.locked[x][y])
                else:
                    self.draw_cell((x, y), EMPTY_CELL_COLOR)

        if self.show_final:
            for x, y in self.current:
                self.draw_cell((x, int(y - self.current.y + self.final_y)), FINAL_POSITION_COLOR)

        for cell in self.current:
            self.draw_tetromino_cell(cell, self.current.__class__.__name__)

        for cell in self.next:
            self.draw_tetromino_cell(cell, self.next.__class__.__name__,
                                     WIDTH + 1 + (SIDEBAR_WIDTH - self.next.get_width()) / 2,
                                     (5 - self.next.get_height()) / 2)

        for y in range(HEIGHT):
            self.draw_cell((WIDTH, y), SEPARATOR_CELL_COLOR)

        for y in (5, 10, 15):
            for x in range(SIDEBAR_WIDTH):
                self.draw_cell((x + WIDTH + 1, y), SEPARATOR_CELL_COLOR)

        center_x = (WIDTH + 1 + SIDEBAR_WIDTH / 2) * CELL_SIZE
        self.display_text(self.small_font, 'LEVEL',
                          center_x, 7 * CELL_SIZE)
        self.display_text(self.large_font, str(self.level),
                          center_x, 7 * CELL_SIZE + 40)
        self.display_text(self.small_font, 'LINES',
                          center_x, 12 * CELL_SIZE)
        self.display_text(self.large_font, str(self.lines),
                          center_x, 12 * CELL_SIZE + 40)
        self.display_text(self.small_font, 'SCORE',
                          center_x, 17 * CELL_SIZE)
        self.display_text(self.large_font, str(self.score),
                          center_x, 17 * CELL_SIZE + 40)

        center_x = WIDTH * CELL_SIZE / 2
        center_y = HEIGHT * CELL_SIZE / 2
        if self.state == GameState.READY:
            self.display.blit(self.shadow, (0, 0))
            self.display_text(self.small_font, 'PRESS ANY KEY', center_x, center_y - 25)
            self.display_text(self.small_font, 'TO START', center_x, center_y + 25)
        if self.state == GameState.LOST:
            self.display.blit(self.shadow, (0, 0))
            self.display_text(self.large_font, 'GAME OVER', center_x, center_y - 25)
            self.display_text(self.small_font, 'PRESS "R" TO RESTART', center_x, center_y + 25)
        if self.state == GameState.PAUSED:
            self.display.blit(self.shadow, (0, 0))
            self.display_text(self.large_font, 'PAUSED', center_x, center_y - 25)
            self.display_text(self.small_font, 'ANY KEY TO CONTINUE', center_x, center_y + 25)

        pygame.display.flip()

    def display_text(self, font, text, x, y):
        text_surface = font.render(text, True, TEXT_COLOR)
        rect = text_surface.get_rect()
        rect.left = x - rect.width / 2
        rect.top = y - rect.height / 2
        self.display.blit(text_surface, rect)

    def draw_cell(self, cell, color, x_offset=0, y_offset=0):
        x, y = cell
        x, y = x + x_offset, y + y_offset
        r = pygame.Rect(CELL_SIZE * x + 1, CELL_SIZE * y + 1, CELL_SIZE - 1, CELL_SIZE - 1)
        pygame.draw.rect(self.display, color, r)

    def draw_tetromino_cell(self, cell, color, x_offset=0, y_offset=0):
        x, y = cell
        x, y = x + x_offset, y + y_offset
        self.display.blit(self.cell_images[color], (x * CELL_SIZE + 1, y * CELL_SIZE + 1))

    def mainloop(self):
        while self.running:
            for event in pygame.event.get():
                self.on_event(event)
            self.on_loop()
            self.on_render()
        pygame.quit()

if __name__ == "__main__":
    game = Game()
    game.mainloop()


import asyncio
import json
import logging
import socket
from asyncio.streams import StreamReader, StreamWriter
from contextlib import asynccontextmanager
from typing import Optional, Tuple

async def open_chat_connection(
    host: str,
    port: int,
    attempts: int = 2,
    delay: int = 3,
) -> Tuple[StreamReader, StreamWriter]:
    """
    Establish connection with a chat server.

    It will try to reconnect after failing attempt.

    :param host: Chat server address
    :param port: Chat server port
    :param attempts: How many times to try before using delays
    :param delay: Delay before retry, seconds.
    """
    total_attempts = 0
    while True:
        try:
            reader, writer = await asyncio.wait_for(
                asyncio.open_connection(host, port), timeout=60,
            )
            logging.info(f'Connection to the chat server {host}:{port} has been established.')
            return reader, writer
        except (ConnectionRefusedError, asyncio.TimeoutError, socket.gaierror):
            if total_attempts < attempts:
                logging.error('Connection error, retrying...')
                total_attempts += 1
            else:
                logging.error(f'Connection error. Retrying after {delay} sec.')
                await asyncio.sleep(delay)

@asynccontextmanager
async def connect_to_chat(
    host: str,
    port: int,
    attempts: int = 2,
    delay: int = 3,
) -> Tuple[StreamReader, StreamWriter]:
    """
    Context manager to provide reader&writer from chat connection.

    :param host: Chat server address
    :param port: Chat server port
    :param attempts:  How many times to try before using delays
    :param delay: Delay before retry, seconds
    """
    reader, writer = None, None
    try:
        logging.info('Trying to connect to the server.')
        reader, writer = await open_chat_connection(host, port, attempts, delay)
        yield reader, writer
    finally:
        logging.info('Closing connection to the server')
        if writer:
            writer.close()
            await writer.wait_closed()

async def read_line_from_chat(reader: StreamReader) -> str:
    """Grabs bytes string from connection and decode it into text."""
    chat_data = await reader.readline()
    try:
        return chat_data.decode(encoding='utf-8').strip()
    except (SyntaxError, UnicodeDecodeError):
        logging.error('Got message that can not be decoded', exc_info=True)
        return ''

def sanitize_message(message: str) -> str:
    r"""
    Clears message from `new line` symbols.

    new line symbol (`\\n`) means an end of the message as stated in chat protocol specification.
    """
    return message.replace('\r', '').replace('\n', ' ').strip()

async def write_line_to_chat(writer: StreamWriter, message: str) -> None:
    """Encode message and send it to the server."""
    message = sanitize_message(message).encode(encoding='utf-8') + b'\n'
    writer.write(message)
    await writer.drain()
    logging.debug(f'Send a message: {message}')

async def authorise(reader: StreamReader, writer: StreamWriter, token: str) -> Optional[str]:
    """Authorisation process."""
    logging.debug('Trying to authorise')
    greetings = await read_line_from_chat(reader)
    logging.debug(f'Greetings from the chat: {greetings}')
    await write_line_to_chat(writer, token)
    response = await read_line_from_chat(reader)
    response = json.loads(response)
    if not response:
        logging.error('Wrong token. Please check it or register new user with `--username` parameter')
        return None
    logging.debug(response)
    logging.info(f'Authorised as: {response.get("nickname")}')
    return response.get('nickname')

async def register(reader: StreamReader, writer: StreamWriter, nickname: str) -> str:
    """New user registration."""
    logging.debug('Trying to register')
    greetings = await read_line_from_chat(reader)
    logging.debug(f'Greetings from the chat: {greetings}')
    await write_line_to_chat(writer, '')  # say 'we don't have a token'
    ask_for_nickname = await read_line_from_chat(reader)
    logging.debug(f'Chat asks about nickname: {ask_for_nickname}')
    await write_line_to_chat(writer, nickname)
    response_content = await read_line_from_chat(reader)
    if not response_content:
        logging.error('Registration failed. Please try again later.')
        return ''
    response = json.loads(response_content)
    logging.debug(response)
    logging.debug(f'Registered as {response.get("nickname")}')
    logging.debug(f'New access token {response.get("account_hash")}')
    return response.get('account_hash')


from typing import Dict

import requests

from ukpn.load import (
    GetCenterCoordinatesGSP,
    construct_url,
    get_gsp_names,
    get_metadata_from_ukpn_api,
)

def test_metadata_api():
    # Testing if the constructed url is callable
    url = construct_url(get_complete_records=True)
    # Testing url resposne
    url_resposne = requests.get(url)

    assert url_resposne.status_code == 200

def test_get_url_gsp_names():
    # Testing the url api resposne for each GSP location
    gsp_names = get_gsp_names()
    for gsp_name in gsp_names:
        gsp_name = gsp_name.split(" ")
        gsp_name = "+".join(gsp_name)
        api_url = construct_url(gsp_names=gsp_name)

        url_resposne = requests.get(api_url)

        assert url_resposne.status_code == 200

def test_coords_from_csv_files():
    # Testing to check
    # Testing for all files
    folder_destination = "tests/data"
    data = GetCenterCoordinatesGSP(folder_destination=folder_destination)
    data = next(iter(data))

    assert data is not None

def test_get_all_the_records():
    # Testing to get the entire UKPN ECR (Embedded Capacity Register) dataset
    api_url = construct_url(get_complete_records=True)
    data = get_metadata_from_ukpn_api(api_url=api_url)
    if isinstance(data, Dict):
        total_records = data["nhits"]
        # Total GSP records including PV Solar output, wind, biofuel etc.
        assert total_records == 1040
    else:
        return AssertionError

    assert data is not None

def test_get_gsp_names():
    # Testing to ge the gsp names
    gsp_names = get_gsp_names()
    assert gsp_names is not None


import struct
import socket
import ipaddress

class Network:
    def __init__(self, address):
        self.address = address

    def __str__(self):
        return self.address

    def __sub__(self, other):
        # get ranges
        ip_ranges = self.diff_ranges(other)

        networks = []

        # iterate over the ip_ranges, find to which subnet they belong and append it to the networks list
        for ip_range in ip_ranges:
            # i have been a little cheeky here and used the built-in ippaddress to find the subnets
            networks.extend(str(ipaddr) for ipaddr in ipaddress.summarize_address_range(ip_range[0], ip_range[-1]))

        return networks

    # method for getting the range of ip adresses in a subnet
    def get_range(self):
        # get the network prefix and mask by splitting the address on the '/'
        prefix, mask = self.address.split('/')
        mask = int(mask)
        # get the host bits, IPv4 addresses consist of 32 bits, so 32- the mask bits
        host_bits = 32 - mask

        # prefix string to integer
        # convert IPv4 string to binary format
        prefix_bin = socket.inet_aton(prefix)
        # unpack the binary prefix to integer
        # i'm assuming the host system is little-endian, so i enforce big-endian
        # struct.unpack always returns a tuple, therefor i take the first element
        ip_integer = struct.unpack('>I', prefix_bin)[0]

        # define a start and end point for the range by clearing the host_bits (using the bitwise shift operators)
        start = (ip_integer >> host_bits) << host_bits
        end = start | ((1 << host_bits) - 1)
        end += 1

        ip_range = []
        # convert each address from binary back to string, create an ip_address object form it, append it to the range list
        for i in range(start, end):
            addr = ipaddress.ip_address(socket.inet_ntoa(struct.pack('>I',i)))
            ip_range.append(addr)

        # sort the range
        ip_range.sort()

        return ip_range

    # method that removes duplicate addresses from this network's range and returns the ranges that are left
    def diff_ranges(self, other):
        # get ranges
        self_range = self.get_range()
        other_range = other.get_range()

        # find where the other_range is located in the self_range
        start_remove = self_range.index(other_range[0])
        end_remove = self_range.index(other_range[-1])

        ranges = []
        # remove the other_range from the self range, in some cases this gives one range back, sometimes two
        if start_remove != 0:
            ranges.append(self_range[:start_remove])
        ranges.append(self_range[end_remove + 1:])

        return ranges

a = Network('192.168.1.0/24')
b = Network('192.168.1.16/29')

print(a) # prints 192.168.1.0/24
print(b) # prints 192.168.1.16/29
print(a-b) # prints ['192.168.1.0/28', '192.168.1.24/29', '192.168.1.32/27', '192.168.1.64/26', '192.168.1.128/25']


import copy
import logging
import os
from tempfile import NamedTemporaryFile

import h5py
import numpy as np
import torch

from pytorch3dunet.datasets.hdf5 import get_train_loaders
from pytorch3dunet.train import _create_optimizer, _create_lr_scheduler
from pytorch3dunet.unet3d.losses import get_loss_criterion
from pytorch3dunet.unet3d.metrics import get_evaluation_metric
from pytorch3dunet.unet3d.model import get_model
from pytorch3dunet.unet3d.trainer import UNet3DTrainer
from pytorch3dunet.unet3d.utils import get_logger, DefaultTensorboardFormatter

CONFIG_BASE = {
    'model': {
        'name': 'UNet3D',
        'in_channels': 3,
        'out_channels': 2,
        'f_maps': 16
    },
    'optimizer': {
        'learning_rate': 0.0002,
        'weight_decay': 0.0001
    },
    'lr_scheduler': {
        'name': 'MultiStepLR',
        'milestones': [2, 3],
        'gamma': 0.5
    },
    'loaders': {
        'raw_internal_path': 'raw',
        'label_internal_path': 'label',
        'weight_internal_path': None,

        'train': {
            'slice_builder': {
                'name': 'SliceBuilder',
                'patch_shape': (32, 64, 64),
                'stride_shape': (32, 64, 64)
            },
            'transformer': {
                'raw': [{'name': 'Normalize'}, {'name': 'ToTensor', 'expand_dims': True}],
                'label': [{'name': 'ToTensor', 'expand_dims': False}],
                'weight': [{'name': 'ToTensor', 'expand_dims': False}]
            }
        },
        'val': {
            'slice_builder': {
                'name': 'SliceBuilder',
                'patch_shape': (32, 64, 64),
                'stride_shape': (32, 64, 64)
            },
            'transformer': {
                'raw': [{'name': 'Normalize'}, {'name': 'ToTensor', 'expand_dims': True}],
                'label': [{'name': 'ToTensor', 'expand_dims': False}],
                'weight': [{'name': 'ToTensor', 'expand_dims': False}]
            }
        }
    }
}

class TestUNet3DTrainer:
    def test_ce_loss(self, tmpdir, capsys):
        with capsys.disabled():
            trainer = self._train_save_load(tmpdir, 'CrossEntropyLoss', 'MeanIoU')

            assert trainer.max_num_epochs == 1
            assert trainer.log_after_iters == 2
            assert trainer.validate_after_iters == 2
            assert trainer.max_num_iterations == 4

    def test_wce_loss(self, tmpdir, capsys):
        with capsys.disabled():
            trainer = self._train_save_load(tmpdir, 'WeightedCrossEntropyLoss', 'MeanIoU')

            assert trainer.max_num_epochs == 1
            assert trainer.log_after_iters == 2
            assert trainer.validate_after_iters == 2
            assert trainer.max_num_iterations == 4

    def test_bce_loss(self, tmpdir, capsys):
        with capsys.disabled():
            trainer = self._train_save_load(tmpdir, 'BCEWithLogitsLoss', 'DiceCoefficient')

            assert trainer.max_num_epochs == 1
            assert trainer.log_after_iters == 2
            assert trainer.validate_after_iters == 2
            assert trainer.max_num_iterations == 4

    def test_dice_loss(self, tmpdir, capsys):
        with capsys.disabled():
            trainer = self._train_save_load(tmpdir, 'DiceLoss', 'MeanIoU')

            assert trainer.max_num_epochs == 1
            assert trainer.log_after_iters == 2
            assert trainer.validate_after_iters == 2
            assert trainer.max_num_iterations == 4

    def test_pce_loss(self, tmpdir, capsys):
        with capsys.disabled():
            trainer = self._train_save_load(tmpdir, 'PixelWiseCrossEntropyLoss', 'MeanIoU', weight_map=True)

            assert trainer.max_num_epochs == 1
            assert trainer.log_after_iters == 2
            assert trainer.validate_after_iters == 2
            assert trainer.max_num_iterations == 4

    def test_residual_unet(self, tmpdir, capsys):
        with capsys.disabled():
            trainer = self._train_save_load(tmpdir, 'CrossEntropyLoss', 'MeanIoU', model='ResidualUNet3D')

            assert trainer.max_num_epochs == 1
            assert trainer.log_after_iters == 2
            assert trainer.validate_after_iters == 2
            assert trainer.max_num_iterations == 4

    def _train_save_load(self, tmpdir, loss, val_metric, model='UNet3D', max_num_epochs=1, log_after_iters=2,
                         validate_after_iters=2, max_num_iterations=4, weight_map=False):
        binary_loss = loss in ['BCEWithLogitsLoss', 'DiceLoss', 'GeneralizedDiceLoss']

        device = torch.device("cuda:0" if torch.cuda.is_available() else 'cpu')

        test_config = copy.deepcopy(CONFIG_BASE)
        test_config['model']['name'] = model
        test_config.update({
            # get device to train on
            'device': device,
            'loss': {'name': loss, 'weight': np.random.rand(2).astype(np.float32), 'pos_weight': 3.},
            'eval_metric': {'name': val_metric}
        })
        test_config['model']['final_sigmoid'] = binary_loss

        if weight_map:
            test_config['loaders']['weight_internal_path'] = 'weight_map'

        loss_criterion = get_loss_criterion(test_config)
        eval_criterion = get_evaluation_metric(test_config)
        model = get_model(test_config)
        model = model.to(device)

        if loss in ['BCEWithLogitsLoss']:
            label_dtype = 'float32'
        else:
            label_dtype = 'long'
        test_config['loaders']['train']['transformer']['label'][0]['dtype'] = label_dtype
        test_config['loaders']['val']['transformer']['label'][0]['dtype'] = label_dtype

        train, val = TestUNet3DTrainer._create_random_dataset((3, 128, 128, 128), (3, 64, 64, 64), binary_loss)
        test_config['loaders']['train']['file_paths'] = [train]
        test_config['loaders']['val']['file_paths'] = [val]

        loaders = get_train_loaders(test_config)

        optimizer = _create_optimizer(test_config, model)

        test_config['lr_scheduler']['name'] = 'MultiStepLR'
        lr_scheduler = _create_lr_scheduler(test_config, optimizer)

        logger = get_logger('UNet3DTrainer', logging.DEBUG)

        formatter = DefaultTensorboardFormatter()
        trainer = UNet3DTrainer(model, optimizer, lr_scheduler,
                                loss_criterion, eval_criterion,
                                device, loaders, tmpdir,
                                max_num_epochs=max_num_epochs,
                                log_after_iters=log_after_iters,
                                validate_after_iters=validate_after_iters,
                                max_num_iterations=max_num_iterations,
                                tensorboard_formatter=formatter)
        trainer.fit()
        # test loading the trainer from the checkpoint
        trainer = UNet3DTrainer.from_checkpoint(os.path.join(tmpdir, 'last_checkpoint.pytorch'),
                                                model, optimizer, lr_scheduler,
                                                loss_criterion, eval_criterion,
                                                loaders, tensorboard_formatter=formatter)
        return trainer

    @staticmethod
    def _create_random_dataset(train_shape, val_shape, channel_per_class):
        result = []

        for shape in [train_shape, val_shape]:
            tmp = NamedTemporaryFile(delete=False)

            with h5py.File(tmp.name, 'w') as f:
                l_shape = w_shape = shape
                # make sure that label and weight tensors are 3D
                if len(shape) == 4:
                    l_shape = shape[1:]
                    w_shape = shape[1:]

                if channel_per_class:
                    l_shape = (2,) + l_shape

                f.create_dataset('raw', data=np.random.rand(*shape))
                f.create_dataset('label', data=np.random.randint(0, 2, l_shape))
                f.create_dataset('weight_map', data=np.random.rand(*w_shape))

            result.append(tmp.name)

        return result