import discord
import requests

intents = discord.Intents.all()
client = discord.Client(intents=intents)
intents.typing = False
intents.presences = False
intents.messages = True

bot = discord.Client(intents=intents)
prefix = '!'

@bot.event
async def on_ready():
    print(f'Bot is ready! Logged in as {bot.user.name}')

@bot.event
async def on_message(message):
    print('Message content:', message.content)
    print('Message author:', message.author)

    if message.author == bot.user:
        return

    if message.content.startswith(prefix):
        command = message.content[len(prefix):].lower()

        if command.startswith('weather'):
            location = command[len('weather'):].strip()

            if not location:
                await message.channel.send('Please provide a location.')
                return

            try:
                weather_data = fetch_weather_data(location)
                await message.channel.send(f"The weather in {location} is {weather_data['weather']} with {weather_data['temperature']}\N{DEGREE SIGN}C")
            except Exception as e:
                print(e)
                await message.channel.send('An error occurred while fetching the weather.')

def fetch_weather_data(location):
    api_key = 'YOUR_WEATHER_API'
    api_url = f'https://api.weatherapi.com/v1/current.json?key={api_key}&q={location}'

    response = requests.get(api_url)
    data = response.json()

    if response.status_code != 200 or 'error' in data:
        raise Exception('Invalid location or error in weather API response.')

    return {
       'weather': data['current']['condition']['text'],
        'temperature': data['current']['temp_c'],
    }

bot.run('YOUR_BOT_TOKEN')


from math import sqrt
from itertools import islice
from one_way_alg import one_way_func
import scipy
import numpy

#генерация простых чисел

def is_prime(n):
    if (n <= 1):
        return False
    if (n == 2):
        return True
    if (n % 2 == 0):
        return False

    i = 3
    while i <= sqrt(n):
        if n % i == 0:
            return False
        i = i + 2

    return True

def prime_generator():
    n = 1
    while True:
        n += 1
        if is_prime(n):
            yield n

# шаг 1
y = int(input('Введите y = '))
a = int(input('Введите a = '))
p = int(input('Введите p = '))

# количество простых чисел
t = int(input('Введите t = '))

#!!значения из примера
#y = 37
#a = 10
#p = 47
#t = 3
# список S простых чисел
S = [x for x in islice(prime_generator(), t)]

#eps = int(input('Введите небольшое целое число eps = '))
eps =1
# шаг 2

# разложение числа на простые множетели
def Factor(n):
    Ans = []
    d = 2
    while d * d <= n:
        if n % d == 0:
            Ans.append(d)
            n //= d
        else:
            d += 1
    if n > 1:
        Ans.append(n)
    return Ans

# список степеней
k = list()

# матрица для поиска u на трерьем шаге
u_matrix = list()

# поиск степеней и гладкий чисел
i = 1
while len(k) < (t + eps):
    #вводим словарь для подсчета коэффициентов u для каждой строки, офк обнуляем его для каждой строки
    koef_u = dict()
    for j in S:
        koef_u[j] = 0
    # переводим в множества и делаем проверку на подмножество
    if set(Factor(one_way_func(a, i, p))) <= set(S):
        k.append(i)
        for j in Factor(one_way_func(a, i, p)):
            koef_u[j] += 1
        P = list()
        for g, v in koef_u.items():
            P.append(v)
        u_matrix += [P]
    i += 1

# шаг 3

# перевод списков левой и правой части системы в матрицу
u_matrix = numpy.array(u_matrix)
k_matrix = numpy.array(k)

print('Левая часть системы в матричном представлении:\n', u_matrix)
print('Правая часть системы в матричном представлении:\n', k_matrix)

#Вводим значения u,полученные в ходе решения системы
print('Введите решение системы уравненией:')
i = 1

# список для записи результатов системы уравнений
u_result = list()

while i <= t:
    u_result.append(int(input(f'Введите значение {i} переменной:\n')))
    i += 1

# шаг 4

r = 1

# словаь для записи частоты простого числа, на которые раскладывается гладкое число p_t
koef_p = list()

while r <= 5:
    # наше гладное число
    p_t = y * one_way_func(a, r, p) % p
    # гладкое число p_t раскладываем на простые и смотрим чтобы все они входили в S, для этого
    # переводим в множества и делаем проверку на подмножество
    if set(Factor(p_t)) <= set(S):
        # подсчитываем каждое простое число из которого состоит наше гладкое
        for l in S:
            h = 0
            while p_t % l == 0:
                h += 1
                p_t /= l
            koef_p.append(h)
        break
    r += 1

# шаг 5

i = 0
# запишем сюда результат

res = 0
# считаем значение "под суммой"
while i < t:
    res += koef_p[i] * u_result[i]
    i += 1
res -= r

x = (res % (p - 1))
print('Найденный x равен: ', x)

print('Проверка:', one_way_func(a, x, p))

""" НЕ РАБОТАЕТ!
Q, R = numpy.linalg.qr(u_matrix)
# решаем систему уравнений и находим u
x = scipy.linalg.solve_triangular(R, Q.T.dot(k_matrix), lower=False)
print(x)
from decimal import Decimal
print(Decimal(x[1]).as_integer_ratio())

a, b = x[1].as_integer_ratio()

print(a)
print(b)

from инверсия import inversia

c = inversia(p-1, b)
print(c)
print(c*a)
print((c*a)%(46))
"""

Лаба 7 - Алгоритм исчисления порядка/main.py


from django.shortcuts import render
from config.settings import get_secret
from users.models import CustomUser
from .models import *
from cart.cart import Cart
from .forms import *
from django.views.generic.base import View
from django.http import JsonResponse
import logging
from logging import StreamHandler
import logstash
import datetime

# 로그스태시
host = get_secret('LOGSTASH_HOST')
port = get_secret('LOGSTASH_PORT')
logger = logging.getLogger('python-logstash-logger')
logger.setLevel(logging.INFO)
logger.addHandler(logstash.TCPLogstashHandler(host, port, version=1))
logger.addHandler(StreamHandler())

def order_list(request):
    #오브젝트 불러오기
    order_list = OrderItem.objects.all()
    total_price = 0
    for order in order_list:
        total_price += order.price
    return render(request, 'order/orderitem_list.html', {'order_list':order_list, 'total_price' : total_price})

def customer_order_list(request):
    #오브젝트 불러오기
    order_list = OrderItem.objects.all()
    return render(request, 'order/common_orderitem_list.html', {'order_list':order_list})

def order_create(request):
    cart = Cart(request)
    if request.method == 'POST':
        form = OrderCreateForm(request.POST)
        if form.is_valid():
            order = form.save(commit=False)
            order.save()
            for item in cart:
                OrderItem.objects.create(order=order,
                                         product=item['product'],
                                         price=item['price'],
                                         quantity=item['quantity'],
                                         size=item['size'],
                                         temp=item['temp'],
                                         )
            cart.clear()
            return render(request, 'order/created.html', {'order': order})
    else:
        form = OrderCreateForm()
    return render(request, 'order/create.html', {'cart': cart, 'form': form})

def order_complete(request):
    order_id = request.GET.get('order_id')
    order = Order.objects.get(id=order_id)
    order_item_list = OrderItem.objects.all()
    Current_user = request.user
    c_user = CustomUser.objects.get(username=Current_user)

    for order_item in order_item_list:
        if int(order_id) == int(order_item.order_id):
            # UTC 타임을 한국에 맞게 수정
            order_date = str(datetime.datetime.now())
            order_date = order_date.replace(' ', 'T')
            order_date = order_date + "+09:00"

            extra = {'order_date':order_date,
                     'order_number':int(order_item.order_id),
                     'uid': c_user.username,
                     'sex':c_user.u_sex,
                     'birth':int(c_user.birth_year),
                     'email':order.email,
                     'total_price':int(order.total_price),
                     'product_name':order_item.product.name,
                     'product_price':int(order_item.price),
                     'quantity':int(order_item.quantity),
                     'size':order_item.size,
                     'temp':order_item.temp
                     }
            # 로그스태시 전송
            logger.info(" 주문내역전송 ", extra=extra)
    return render(request, 'order/complete.html', {'order': order})

class OrderCreateAjaxView(View):
    def post(self, request, *args, **kwargs):
        if not request.user.is_authenticated:
            return JsonResponse({"authenticated": False}, status=403)
        cart = Cart(request)
        total_price = cart.get_total_price()
        Current_user = request.user
        form = OrderCreateForm(request.POST)
        if form.is_valid():
            order = form.save(commit=False)
            order.total_price = total_price
            order.user = Current_user
            order.save()
            for item in cart:
                OrderItem.objects.create(order=order,
                                         product=item['product'],
                                         price=item['price'],
                                         quantity=item['quantity'],
                                         size=item['size'],
                                         temp=item['temp']
                                         )
            cart.clear()
            data = {
                "order_id": order.id
            }
            return JsonResponse(data)
        else:
            return JsonResponse({}, status=401)

class OrderCheckoutAjaxView(View):
    def post(self, request, *args, **kwargs):
        if not request.user.is_authenticated:
            return JsonResponse({"authenticated": False}, status=403)
        order_id = request.POST.get('order_id')
        order = Order.objects.get(id=order_id)
        amount = request.POST.get('amount')

        try:
            merchant_order_id = OrderTransaction.objects.create_new(
                order=order,
                amount=amount
            )
        except:
            merchant_order_id = None

        if merchant_order_id is not None:
            data = {
                "works": True,
                "merchant_id": merchant_order_id
            }
            return JsonResponse(data)
        else:
            return JsonResponse({}, status=401)

class OrderImpAjaxView(View):
    def post(self, request, *args, **kwargs):
        if not request.user.is_authenticated:
            return JsonResponse({"authenticated": False}, status=403)
        order_id = request.POST.get('order_id')
        order = Order.objects.get(id=order_id)
        merchant_id = request.POST.get('merchant_id')
        imp_id = request.POST.get('imp_id')
        amount = request.POST.get('amount')

        try:
            trans = OrderTransaction.objects.get(
                order=order,
                merchant_order_id=merchant_id,
                amount=amount
            )
        except:
            trans = None

        if trans is not None:
            trans.transaction_id = imp_id
            trans.success = True
            trans.save()
            order.paid = True
            order.save()

            data = {
                "works": True
            }

            return JsonResponse(data)
        else:
            return JsonResponse({}, status=401)


from flask import render_template
from flask_babel import gettext as _
from pgadmin.utils.ajax import internal_server_error
from pgadmin.utils.exception import ExecuteError
from pgadmin.browser.server_groups.servers.databases.schemas.utils \
    import DataTypeReader
from pgadmin.browser.server_groups.servers.utils import parse_priv_from_db, \
    parse_priv_to_db
from pgadmin.browser.server_groups.servers.databases.utils \
    import make_object_name
from functools import wraps

def get_template_path(f):
    """
    This function will behave as a decorator which will prepare
    the template path based on database server version.
    """

    @wraps(f)
    def wrap(*args, **kwargs):
        # Here args[0] will hold the connection object
        conn_obj = args[0]
        if 'template_path' not in kwargs:
            kwargs['template_path'] = 'columns/sql/#{0}#'.format(
                conn_obj.manager.version)

        return f(*args, **kwargs)
    return wrap

@get_template_path
def get_parent(conn, tid, template_path=None):
    """
    This function will return the parent of the given table.
    :param conn: Connection Object
    :param tid: Table oid
    :param template_path: Optional template path
    :return:
    """

    SQL = render_template("/".join([template_path,
                                    'get_parent.sql']), tid=tid)
    status, rset = conn.execute_2darray(SQL)
    if not status:
        raise ExecuteError(rset)

    schema = ''
    table = ''
    if 'rows' in rset and len(rset['rows']) > 0:
        schema = rset['rows'][0]['schema']
        table = rset['rows'][0]['table']

    return schema, table

def _check_primary_column(data):
    """
    To check if column is primary key
    :param data: Data.
    """
    if 'attnum' in data and 'indkey' in data:
        # Current column
        attnum = str(data['attnum'])

        # Single/List of primary key column(s)
        indkey = str(data['indkey'])

        # We will check if column is in primary column(s)
        if attnum in indkey.split(" "):
            data['is_pk'] = True
            data['is_primary_key'] = True
        else:
            data['is_pk'] = False
            data['is_primary_key'] = False

def _fetch_inherited_tables(tid, data, fetch_inherited_tables, template_path,
                            conn):
    """
    This function will check for fetch inherited tables, and return inherited
    tables.
    :param tid: Table Id.
    :param data: Data.
    :param fetch_inherited_tables: flag to fetch inherited tables.
    :param template_path: Template path.
    :param conn: Connection.
    """
    if fetch_inherited_tables:
        SQL = render_template("/".join(
            [template_path, 'get_inherited_tables.sql']), tid=tid)
        status, inh_res = conn.execute_dict(SQL)
        if not status:
            return True, internal_server_error(errormsg=inh_res)
        for row in inh_res['rows']:
            if row['attrname'] == data['name']:
                data['is_inherited'] = True
                data['tbls_inherited'] = row['inhrelname']
    return False, ''

@get_template_path
def column_formatter(conn, tid, clid, data, edit_types_list=None,
                     fetch_inherited_tables=True, template_path=None):
    """
    This function will return formatted output of query result
    as per client model format for column node
    :param conn: Connection Object
    :param tid: Table ID
    :param clid: Column ID
    :param data: Data
    :param edit_types_list:
    :param fetch_inherited_tables:
    :param template_path: Optional template path
    :return:
    """

    # To check if column is primary key
    _check_primary_column(data)

    # Fetch length and precision
    data = fetch_length_precision(data)

    # We need to fetch inherited tables for each table
    is_error, errmsg = _fetch_inherited_tables(
        tid, data, fetch_inherited_tables, template_path, conn)

    if is_error:
        return errmsg

    # We need to format variables according to client js collection
    if 'attoptions' in data and data['attoptions'] is not None:
        data['attoptions'] = parse_column_variables(data['attoptions'])

    # Need to format security labels according to client js collection
    if 'seclabels' in data and data['seclabels'] is not None:
        seclabels = []
        for seclbls in data['seclabels']:
            k, v = seclbls.split('=')
            seclabels.append({'provider': k, 'label': v})

        data['seclabels'] = seclabels

    # Get formatted Column Options
    if 'attfdwoptions' in data and data['attfdwoptions'] != '':
        data['coloptions'] = parse_options_for_column(data['attfdwoptions'])

    # We need to parse & convert ACL coming from database to json format
    SQL = render_template("/".join([template_path, 'acl.sql']),
                          tid=tid, clid=clid)
    status, acl = conn.execute_dict(SQL)

    if not status:
        return internal_server_error(errormsg=acl)

    # We will set get privileges from acl sql so we don't need
    # it from properties sql
    data['attacl'] = []

    for row in acl['rows']:
        priv = parse_priv_from_db(row)
        data.setdefault(row['deftype'], []).append(priv)

    # we are receiving request when in edit mode
    # we will send filtered types related to current type
    type_id = data['atttypid']

    if edit_types_list is None:
        edit_types_list = []
        SQL = render_template("/".join([template_path,
                                        'edit_mode_types.sql']),
                              type_id=type_id)
        status, rset = conn.execute_2darray(SQL)
        edit_types_list = [row['typname'] for row in rset['rows']]

    # We will need present type in edit mode
    edit_types_list.append(data['typname'])
    data['edit_types'] = sorted(edit_types_list)
    data['cltype'] = DataTypeReader.parse_type_name(data['cltype'])
    return data

def parse_options_for_column(db_variables):
    """
        Function to format the output for variables.

        Args:
            db_variables: Variable object

                Expected Object Format:
                    ['option1=value1', ..]
                where:
                    user_name and database are optional
        Returns:
            Variable Object in below format:
                {
                'variables': [
                    {'name': 'var_name', 'value': 'var_value',
                    'user_name': 'user_name', 'database': 'database_name'},
                    ...]
                }
                where:
                    user_name and database are optional
        """
    variables_lst = []

    if db_variables is not None:
        for row in db_variables:
            # The value may contain equals in string, split on
            # first equals only
            var_name, var_value = row.split("=", 1)
            var_dict = {'option': var_name, 'value': var_value}
            variables_lst.append(var_dict)
    return variables_lst

@get_template_path
def get_formatted_columns(conn, tid, data, other_columns,
                          table_or_type, template_path=None,
                          with_serial=False):
    """
    This function will iterate and return formatted data for all
    the columns.
    :param conn: Connection Object
    :param tid: Table ID
    :param data: Data
    :param other_columns:
    :param table_or_type:
    :param template_path: Optional template path
    :return:
    """
    SQL = render_template("/".join([template_path, 'properties.sql']),
                          tid=tid, show_sys_objects=False)

    status, res = conn.execute_dict(SQL)
    if not status:
        raise ExecuteError(res)

    all_columns = res['rows']
    edit_types = {}
    # Add inherited from details from other columns - type, table
    for col in all_columns:
        edit_types[col['atttypid']] = []
        for other_col in other_columns:
            if col['name'] == other_col['name']:
                col['inheritedfrom' + table_or_type] = \
                    other_col['inheritedfrom']

        if with_serial:
            # Here we assume if a column is serial
            serial_seq_name = make_object_name(
                data['name'], col['name'], 'seq')
            # replace the escaped quotes for comparison
            defval = (col.get('defval', '') or '').replace("''", "'").\
                replace('""', '"')

            if serial_seq_name in defval and defval.startswith("nextval('")\
                    and col['typname'] in ('integer', 'smallint', 'bigint'):

                serial_type = {
                    'integer': 'serial',
                    'smallint': 'smallserial',
                    'bigint': 'bigserial'
                }[col['typname']]

                col['displaytypname'] = serial_type
                col['cltype'] = serial_type
                col['typname'] = serial_type
                col['defval'] = ''

    data['columns'] = all_columns

    if 'columns' in data and len(data['columns']) > 0:
        SQL = render_template("/".join([template_path,
                                        'edit_mode_types_multi.sql']),
                              type_ids=",".join(map(lambda x: str(x),
                                                    edit_types.keys())))
        status, res = conn.execute_2darray(SQL)
        for row in res['rows']:
            edit_types[row['main_oid']] = sorted(row['edit_types'])

        for column in data['columns']:
            column_formatter(conn, tid, column['attnum'], column,
                             edit_types[column['atttypid']], False)

    return data

def _parse_column_actions(final_columns, column_acl):
    """
    Check action and access for it.
    :param final_columns: final column list
    :param column_acl: Column access.
    """
    for c in final_columns:
        if 'attacl' in c:
            if 'added' in c['attacl']:
                c['attacl']['added'] = parse_priv_to_db(
                    c['attacl']['added'], column_acl
                )
            elif 'changed' in c['attacl']:
                c['attacl']['changed'] = parse_priv_to_db(
                    c['attacl']['changed'], column_acl
                )
            elif 'deleted' in c['attacl']:
                c['attacl']['deleted'] = parse_priv_to_db(
                    c['attacl']['deleted'], column_acl
                )
        if 'cltype' in c:
            # check type for '[]' in it
            c['cltype'], c['hasSqrBracket'] = \
                type_formatter(c['cltype'])

        c = convert_length_precision_to_string(c)

def _parse_format_col_for_edit(data, columns, column_acl):
    """
    This function parser columns for edit mode.
    :param data: Data from req.
    :param columns: Columns list from data
    :param column_acl: Column access.
    """
    for action in ['added', 'changed']:
        if action in columns:
            final_columns = []
            for c in columns[action]:
                if 'inheritedfrom' not in c:
                    final_columns.append(c)

            _parse_column_actions(final_columns, column_acl)

            data['columns'][action] = final_columns

def parse_format_columns(data, mode=None):
    """
    This function will parse and return formatted list of columns
    added by user.

    :param data:
    :param mode:
    :return:
    """
    column_acl = ['a', 'r', 'w', 'x']
    columns = data['columns']
    # 'EDIT' mode
    if mode is not None:
        _parse_format_col_for_edit(data, columns, column_acl)
    else:
        # We need to exclude all the columns which are inherited from other
        # tables 'CREATE' mode
        final_columns = []

        for c in columns:
            if c.get('inheritedfrom', None) is None:
                final_columns.append(c)

        # Now we have all lis of columns which we need
        # to include in our create definition, Let's format them
        for c in final_columns:
            if 'attacl' in c:
                c['attacl'] = parse_priv_to_db(
                    c['attacl'], column_acl
                )

            if 'cltype' in c:
                # check type for '[]' in it
                c['cltype'], c['hasSqrBracket'] = type_formatter(c['cltype'])

            c = convert_length_precision_to_string(c)

        data['columns'] = final_columns

    return data

def convert_length_precision_to_string(data):
    """
    This function is used to convert length & precision to string
    to handle case like when user gives 0 as length.

    :param data:
    :return:
    """

    if 'attlen' in data and data['attlen'] == '':
        data['attlen'] = None
    elif 'attlen' in data and data['attlen'] is not None:
        data['attlen'] = str(data['attlen'])

    if 'attprecision' in data and data['attprecision'] == '':
        data['attprecision'] = None
    elif 'attprecision' in data and data['attprecision'] is not None:
        data['attprecision'] = str(data['attprecision'])

    return data

def type_formatter(data_type):
    """
    We need to remove [] from type and append it
    after length/precision so we will set flag for
    sql template.

    :param data_type:
    :param template_path: Optional template path
    :return:
    """

    if '[]' in data_type:
        return data_type[:-2], True
    else:
        return data_type, False

def fetch_length_precision(data):
    """
    This function is used to fetch the length and precision.

    :param data:
    :return:
    """
    # Find length & precision of column data type
    fulltype = DataTypeReader.get_full_type(
        data['typnspname'], data['typname'],
        data['isdup'], data['attndims'], data['atttypmod'])

    length = False
    precision = False
    if 'elemoid' in data:
        length, precision, typeval = \
            DataTypeReader.get_length_precision(data['elemoid'])

    # Set length and precision to None
    data['attlen'] = None
    data['attprecision'] = None

    import re

    # If we have length & precision both
    if length and precision:
        match_obj = re.search(r'(\d+),(\d+)', fulltype)
        if match_obj:
            data['attlen'] = match_obj.group(1)
            data['attprecision'] = match_obj.group(2)
    elif length:
        # If we have length only
        match_obj = re.search(r'(\d+)', fulltype)
        if match_obj:
            data['attlen'] = match_obj.group(1)
            data['attprecision'] = None

    return data

def parse_column_variables(col_variables):
    # We need to format variables according to client js collection
    spcoptions = []
    if col_variables is not None:
        for spcoption in col_variables:
            k, v = spcoption.split('=')
            spcoptions.append({'name': k, 'value': v})
    return spcoptions


from setuptools import setup
from setuptools.command.build_py import build_py

import os
import shutil
import subprocess
import sys

from pathlib import Path
long_description = (Path(__file__).parent / "README.md").read_text()

def try_exec(*cmds):
    proc = subprocess.run(cmds)

    if proc.returncode != 0:
        print('`{}` failed'.format(' '.join(cmds)), file=sys.stderr)
        proc.check_returncode()

class libdash_build_py(build_py):
    def run(self):
        build_py.run(self)

        if sys.platform == 'darwin':
            libtoolize = "glibtoolize"
        else:
            libtoolize = "libtoolize"

        try_exec(libtoolize)
        try_exec('aclocal')
        try_exec('autoheader')
        try_exec('automake', '--add-missing')
        try_exec('autoconf')
        try_exec('./configure')
        try_exec('make')

        shutil.copy2('src/.libs/dlldash.so', os.path.join(self.build_lib, 'libdash/libdash.so'))
        if sys.platform == 'darwin':
            shutil.copy2('src/.libs/libdash.dylib', os.path.join(self.build_lib, 'libdash/libdash.dylib'))

setup(name='libdash',
      packages=['libdash'],
      cmdclass={'build_py': libdash_build_py},
      version='0.3.1',
      long_description=long_description,
      long_description_content_type='text/markdown',
      include_package_data=True,
      has_ext_modules=lambda: True)


import torch
from math import log
from torch.distributions import Normal
from normalizing_flows.utils import squeeze, unsqueeze
from normalizing_flows.blocks import RealNVPBlock, GlowBlock
from normalizing_flows.utils import FinalScale, StepOfGlow
import logging

"""This package contains the flow models, e.g RealNVP and GLOW.
"""

class RealNVP(torch.nn.Module):
    def __init__(
        self,
        n_bits=8,
        base_input_shape=[3, 32, 32],
        num_scales=2,  # L
        num_step_of_flow=1,  # K
        num_resnet_blocks=8,
    ) -> None:
        super().__init__()
        c, h, w = base_input_shape
        self.flow_blocks = torch.nn.ModuleList(
            [
                RealNVPBlock(
                    base_input_shape=[
                        c * 2**i,
                        h // 2**i,
                        w // 2**i,
                    ],  # after each scale h and w area halved and added to channel, half of the channel is truncated before the next scale hence c * 2^i
                    num_step_of_flow=num_step_of_flow,
                    num_resnet_blocks=num_resnet_blocks,
                )
                for i in range(num_scales)
            ]
        )
        self.final_scale = FinalScale(
            base_input_shape=[
                c * 2 ** (num_scales),
                h // 2 ** (num_scales),
                w // 2 ** (num_scales),
            ],
        )  # the shape of this depends on howmany splits we are going to have
        self.output_shape = self.final_scale.base_input_shape
        self.normal = Normal(0.0, 1.0)
        self.n_pixels = c * h * w
        self.n_bins = 2**n_bits

    def forward(self, x):
        x_splits = []
        total_logdet = 0

        for scale in self.flow_blocks:
            x, logdet = scale(
                x
            )  # x will be squeezed as the outcome of this e.g 3, 32, 32 --> 12, 16, 16
            total_logdet += logdet

            # split
            x, z = torch.chunk(
                x, chunks=2, dim=1
            )  # chunks x on channel dim e.g 12, 16, 16, --> (6, 6), 16, 16
            x_splits.append(z)

        x, logdet = self.final_scale(x)
        total_logdet += logdet
        # unsqueeze to get back to original shape
        for split in x_splits[::-1]:
            x = torch.concat([x, split], dim=1)
            x = unsqueeze(x)

        z_log_prob = torch.sum(self.normal.log_prob(x), dim=[1, 2, 3])
        log_prob = z_log_prob + total_logdet

        loss = (
            -log(self.n_bins) * self.n_pixels
        )  # log det implicit transformation that converts [0, 255] values to [0, 1]
        loss = log_prob + loss
        final_loss = (-loss / (log(2.0) * self.n_pixels)).mean()  # per pixed loss
        return x, final_loss

    @torch.no_grad()
    def reverse(self, z, device):
        z = self.final_scale.reverse(z)
        for scale in self.flow_blocks[::-1]:
            # sample from a normal
            x = self.normal.sample(sample_shape=z.shape).to(device)
            z = torch.concat([z, x], dim=1)
            z = scale.reverse(z)
        return z

    @torch.no_grad()
    def sample(self, device, num_samples=1, z_base_sample=None):
        """
        if z_samples are provided, use that as the base tensor, if not sample from normal.
        z_samples can be provided in order to see how the model generates images over the course of training.
        """
        if z_base_sample is None:
            num_channels, height, width = self.output_shape
            sample_size = [num_samples, num_channels, height, width]
            z_base_sample = self.normal.sample(sample_shape=sample_size)
        else:
            # z_sample zero'th dimention is the sample size
            assert list(z_base_sample.shape[1:]) == self.output_shape
        z_base_sample = z_base_sample.to(device)
        generated_image = self.reverse(z_base_sample, device=device)
        return generated_image

class Glow(torch.nn.Module):
    """implements a GLOW model.
    this is composed of L-1 blocks
    a block is composed of **K** steps of flow, where each step of flow is
    composed of
    1. Actnorm 2. Invertible 1x1 Convolution 3. Affine Coupling
    """

    def __init__(
        self,
        K,
        L,
        base_input_shape,
        num_resnet_filters=512,
        n_bits=256,
    ) -> None:
        """
        K: number of steps of flow
        L: number of blocks
        """
        super().__init__()
        self.normal = Normal(0.0, 1.0)
        c, h, w = base_input_shape
        self.n_pixels = c * h * w
        self.n_bins = 2**n_bits
        self.blocks = torch.nn.ModuleList()
        input_channels = c
        self.output_shape = [c * 2 ** (L + 1), h // 2**L, w // 2**L]
        for i in range(L - 1):
            self.blocks.append(GlowBlock(K=K, num_channels=input_channels))
            input_channels *= 2

        self.blocks.append(
            GlowBlock(
                is_final_block=True,
                K=K,
                num_channels=input_channels,
                num_filters=num_resnet_filters,
            )
        )

    def forward(self, x):
        total_logdet = 0
        total_log_prob = 0
        splits = []
        for block in self.blocks:
            x, logdet, z, z_log_prob = block(x)
            total_logdet += logdet
            splits.append(z if z is not None else x)

            total_log_prob += (
                z_log_prob
            )

        log_prob = total_log_prob + total_logdet
        loss = -log(self.n_bins) * self.n_pixels
        loss = log_prob + loss
        final_loss = (-loss / (log(2.0) * self.n_pixels)).mean()
        return (
            x,
            final_loss,
            (total_log_prob / (log(2) * self.n_pixels)).mean(),
            (total_logdet / (log(2) * self.n_pixels)).mean(),
        )

    @torch.no_grad()
    def reverse(self, z_l, device, fixed_sample, seed, T=1.0):
        for block in self.blocks[::-1]:
            z_l = block.reverse(
                T=T, z_l=z_l, device=device, fixed_sample=fixed_sample, seed=seed
            )
        return z_l

    @torch.no_grad()
    def sample(self, device, fixed_sample: bool, seed=None, num_samples=1, T=1.0):
        """
        fixed_sample (bool): fixed sample helps with reproducibiliy of images during training. is fixed_sample is enabled
        all normal distributions will use the same seed for sampling.
        if z_samples are provided, use that as the base tensor, if not sample from normal.
        z_samples can be provided in order to see how the model generates images over the course of training.
        """
        logging.info(f"using temperature {T} for sampling")
        num_channels, height, width = self.output_shape
        sample_size = [num_samples, num_channels, height, width]
        if fixed_sample is True:
            assert seed, "when fixed sample is required, seed needs to be provided"
            torch.manual_seed(seed)
        elif fixed_sample is False and seed is not None:
            logging.info(f"fixed_sample is set to False, seed {seed} will be ignored")
        else:
            raise ValueError("fixed sample needs to be either True or False")

        z_base_sample = self.normal.sample(sample_shape=sample_size)
        torch.random.seed()  # to make sure seed is reset
        z_base_sample = z_base_sample * T  #  apply temperature
        z_base_sample = z_base_sample.to(device)
        generated_image = self.reverse(
            z_base_sample, T=T, device=device, fixed_sample=fixed_sample, seed=seed
        )
        return generated_image


import numpy as np
import pyomo.environ as pyomo
from warnings import warn
import pycity_base.classes.demand.electrical_demand as ed

from pycity_scheduling.classes.electrical_entity import ElectricalEntity
from pycity_scheduling import util

class DeferrableLoad(ElectricalEntity, ed.ElectricalDemand):
    """
    Extension of pyCity_base class ElectricalDemand for scheduling purposes.

    The Load will always run once in the op_horizon

    Parameters
    ----------
    environment : Environment
        Common Environment instance.
    p_el_nom : float
        Nominal electric power in [kW].
    e_consumption : float
         Power to be consumed over the op_horizon in [kWh].
    load_time : array of binaries, optional
        Indicator when deferrable load can be turned on. Defaults to always.
        `load_time[t] == 0`: device is off in t
        `load_time[t] == 1`: device can be turned on in t
        It must contain at least one `0` otherwise the model will become
        infeasible. Its length has to be consistent with `lt_pattern`.
    lt_pattern : str, optional
        Define how the `load_time` profile is to be used

        - `None` : Profile matches simulation horizon.
        - 'daily' : Profile matches one day.
        - 'weekly' : Profile matches one week.

    Raises
    ------
    ValueError :
        If `lt_pattern` does not match `load_time`.

    Notes
    -----
    - DLs offer sets of constraints for operation. In the `convex` mode the following
      constraints and bounds are generated by the DL:

    .. math::
        p_{el\\_nom} \\geq p_{el\\_i} \\geq 0, & \\quad \\text{if} \\quad lt\\_pattern_i = 1  \\\\
        p_{el\\_i} = 0, & \\quad \\text{else}

    .. math::
        \\sum_i p_{el\\_i} * \\Delta t = e_{consumption}

    - The constraints are replaced in integer mode with the following constraints:

    .. math::
        \\sum_i p_{state\\_i} &=& 1 \\\\
        runtime &=& \\lfloor \\frac{p_{el\\_nom} * \\Delta t}{e_{consumption}} \\rceil \\\\
        p_{el\\_i} &=& p_{el\\_nom} * \\sum_{j=i-runtime+1}^{i} p_{state\\_j} \\\\
        p_{state\\_i} &=& 0, \\quad \\text{if} \\quad \\sum_{j=i}^{i+runtime-1}
        lt\\_pattern_j = runtime \\\\

    - These constraints do not take the previous values before the current optimization
      horizon into account. In the optimization horizon :math:`e_{consumption}` always
      has to be consumed.
    """

    def __init__(self, environment, p_el_nom, e_consumption, load_time=None, lt_pattern=None):
        shape = environment.timer.timesteps_total
        super().__init__(environment, 0, np.zeros(shape))

        self._long_id = "DL_" + self._id_string

        self.p_el_nom = p_el_nom
        self.e_consumption = e_consumption
        if load_time is None:
            lt_pattern = None
            load_time = np.ones(self.simu_horizon)
        self.load_time = util.compute_profile(self.timer, load_time, lt_pattern)

        if len(load_time) != self.op_horizon:
            warn(
                ("The DeferrableLoad {} will always run once in the op_horizon and not once in the lt_pattern.\n" +
                 "If a different behaviour is intended, initializing multiple DeferrableLoads should be considered.")
                .format(self._long_id)
            )

        self.new_var("p_start", dtype=np.bool, func=self._get_start)

        self.runtime = int(round(self.e_consumption / (self.p_el_nom * self.time_slot)))

    def _get_start(self, model):
        cumsum = np.cumsum(self.schedule["p_el"][self.op_slice])
        runtime_consumptions = cumsum[self.runtime:] - cumsum[:-self.runtime]
        starts = np.zeros(self.op_horizon, dtype=np.bool)
        starts[np.argmax(runtime_consumptions)] = True
        return starts

    def populate_model(self, model, mode="convex"):
        """
        Add device block to pyomo ConcreteModel

        Call parent's `populate_model` method and set the upper bounds to the
        nominal power or zero depending on `self.load_time`. Also set a constraint
        for the minimum load. If mode == `integer` add binary variables to model
        load as one block that can be shifted in time.

        Parameters
        ----------
        model : pyomo.ConcreteModel
        mode : str, optional
            Specifies which set of constraints to use.

            - `convex`  : Use linear constraints
            - `integer`  : Uses integer variables to restrict the DL to operate
               at nominal load or no load and restricts the DL to consume
               E_Min_Consumption when DL is started without returning to a no
               load state

        """
        super().populate_model(model, mode)
        m = self.model
        if mode == "convex":
            if self.e_consumption > self.op_horizon * self.time_slot * self.p_el_nom:
                warn(
                    ("DeferrableLoad {} is not able to consume enough power in the given op_horizon," +
                     "which will render the model infeasible")
                    .format(self._long_id)
                )

            # consume e_consumption the op_horizon
            def p_consumption_rule(model):
                return pyomo.sum_product(model.p_el_vars) * self.time_slot == self.e_consumption
            m.P_consumption_constr = pyomo.Constraint(rule=p_consumption_rule)

        elif mode == "integer":
            self.runtime = self.e_consumption / (self.p_el_nom * self.time_slot)
            rounded_runtime = int(round(self.runtime))
            if not np.isclose(self.runtime, rounded_runtime):
                warn("Consumption of DLs is in integer mode always a multiple of " +
                     "p_el_nom * dt, which is larger than e_consumption.")
            self.runtime = rounded_runtime

            if self.runtime > self.op_horizon:
                warn(
                    ("DeferrableLoad {} is not able to complete its operation in the given op_horizon, " +
                     "which will render the model infeasible.")
                    .format(self._long_id)
                )

            # create binary variables representing if operation begins in timeslot t
            # Since the DL has to finish operation when the op_horizon ends, binary variables representing a too late
            # start can be omitted.
            m.p_start_vars = pyomo.Var(pyomo.RangeSet(0, self.op_horizon-self.runtime), domain=pyomo.Binary)

            # coupling the start variable to the electrical variables following
            def state_coupl_rule(model, t):
                return model.p_el_vars[t] == self.p_el_nom * pyomo.quicksum(
                       (model.p_start_vars[t] for t in range(max(0, t+1-self.runtime),
                                                             min(self.op_horizon-self.runtime+1, t+1))))
            m.state_coupl_integer_constr = pyomo.Constraint(m.t, rule=state_coupl_rule)

            # run once in the op_horizon
            def state_once_rule(model):
                return pyomo.sum_product(model.p_start_vars) == 1.0
            m.state_once_integer_constr = pyomo.Constraint(rule=state_once_rule)

        else:
            raise ValueError(
                "Mode %s is not implemented by class DeferrableLoad." % str(mode)
            )
        return

    def update_model(self, mode="convex"):
        m = self.model
        if mode == "convex":
            load_time = self.load_time[self.op_slice]

            for t in self.op_time_vec:
                if load_time[t] == 1:
                    m.p_el_vars[t].setub(self.p_el_nom)
                else:
                    m.p_el_vars[t].setub(0.0)

        elif mode == "integer":
            if (self.timestep + self.op_horizon < self.simu_horizon and
                    self.load_time[self.timestep + self.op_horizon - 1] == 1 and
                    self.load_time[self.timestep + self.op_horizon] == 1):
                warn(
                    ("DeferrableLoad {} will not consider a start which would result in power consumption" +
                     "outside the op_horizon")
                    .format(self._long_id)
                     )

            load_time = self.load_time[self.op_slice]

            for t, start_var in m.p_start_vars.items():
                if all(lt == 1 for lt in load_time[t:t+self.runtime]):
                    start_var.setub(1.0)
                else:
                    start_var.setub(0.0)

        else:
            raise ValueError(
                "Mode %s is not implemented by DL." % str(mode)
            )
        return

    def get_objective(self, coeff=1):
        """
        Objective function for entity level scheduling.

        Return the objective function of the deferrable load weighted with
        coeff. Quadratic term minimizing the deviation from the optimal
        loadcurve.

        Parameters
        ----------
        coeff : float, optional
            Coefficient for the objective function.

        Returns
        -------
        ExpressionBase :
            Objective function.
        """
        m = self.model
        max_loading_time = sum(self.load_time) * self.time_slot
        optimal_p_el = self.e_consumption / max_loading_time
        obj = coeff * pyomo.sum_product(m.p_el_vars, m.p_el_vars)
        obj += -2 * coeff * optimal_p_el * pyomo.sum_product(m.p_el_vars)
        return obj


### Set the input and output file names
import time
import datetime
filename = 'A-small-attempt0'
input_filename = filename + '.in'
output_filename = filename + '.out.' + datetime.datetime.fromtimestamp(time.time()).strftime('%Y%m%d-%H%M%S') + '.txt'

### Import other libraries
#import pickle

### Open input file for reading
with open(input_filename) as f:
    lines = f.read().splitlines()

    ### Open output file for writing
    with open(output_filename, 'w') as output:

        ######################################################
        ### Initialise variables from first line of the file
        ######################################################
        vars = lines[0].split(' ')
        cases = int(vars[0])                    # number of cases
        print(str(cases) + ' cases detected.')  # [soft validation]
        lineNum = 1                             # first case starts here
        caseNum = 0                             # for counting the num of cases
        caseSize_r = 4                          # number of rows in each case; default = 1
        caseSize_c = 4                          # number of columns in each case; default = 1

        infoLines = True                        # Toggle according to question
        #infoLines = False                       # Toggle according to question

        ### i.e. infoLines == True
        if infoLines:
            while lineNum < len(lines):
                ### A new case! Initialize some variables
                caseNum += 1                                    # case number count

                ### PART 1
                guess1 = int(lines[lineNum].split(' ')[0])

                ### Case data saved into myArr
                myArr = [[] for x in range(caseSize_r)]
                for r in range(0, caseSize_r):
                    for c in range(0, caseSize_c):
                        myArr[r] = lines[lineNum + r + 1].split(' ')

                ### Do the Work! PART 1
                potentials1 = myArr[guess1-1]

                ### Step
                lineNum += caseSize_r + 1

                ### PART 2
                guess2 = int(lines[lineNum].split(' ')[0])

                ### Case data saved into myArr
                myArr = [[] for x in range(caseSize_r)]
                for r in range(0, caseSize_r):
                    for c in range(0, caseSize_c):
                        myArr[r] = lines[lineNum + r + 1].split(' ')

                ### Do the Work! PART 2
                potentials2 = myArr[guess2-1]
                results = set(potentials1) & set(potentials2)
                if len(results) == 0:
                    msg = 'Volunteer cheated!'
                elif len(results) == 1:
                    msg = ''.join(list(results))
                elif len(results) > 1:
                    msg = 'Bad magician!'

                ### Output myArr
                print('Case #%d: %s' % (caseNum, msg))
                #print(potentials1)
                #print(potentials2)
                #print(set(potentials1) & set(potentials2))
                output.write('Case #%d: %s\n' % (caseNum, msg))

                ### Step
                lineNum += caseSize_r + 1

        ### i.e. infoLines == False
        else:
            for caseNum in range(1, cases+1):

                ### Do the Work!
                ### TODO!
                myAns = len(lines[lineNum])
                lineNum += 1

                ### Output myAns
                print('Case #%d: %d\n' % (caseNum, myAns))
                output.write('Case #%d: %d\n' % (caseNum, myAns))

### END


# -*- coding: utf-8 -*-
# @Time   : 2021/7/5 22:36
# @Author : beyoung
# @Email  : linbeyoung@stu.pku.edu.cn
# @File   : inverse.py

import cv2

src_path = '/Users/Beyoung/Desktop/Projects/AC_OCR/pkuocrtest-20210705/00049.tif'
src = cv2.imread(src_path, 1)
print(src.shape)
src = cv2.resize(src, (round(1/4 * src.shape[1]), round(1/4 * src.shape[0])))
# src = cv2.resize(src, (176, 704))
Img = 255 - src
print(Img.shape)
# cv2.imshow("Img",Img)
# cv2.imshow("src",src)
# cv2.waitKey(0)
cv2.imwrite(src_path[:-4] + '_inverse.tif', Img)