"""
credit to https://github.com/PredatH0r/XonStat/blob/master/xonstat/elo.py .

ELO algorithm to calculate player ranks

"""
from datetime import datetime
import logging
import math
from botocore.exceptions import ClientError
import json
import boto3
from collections import namedtuple
import time as _time

log_level = logging.INFO
logging.basicConfig(format='%(name)s:%(levelname)s:%(message)s')
logger = logging.getLogger("elo_calc")
logger.setLevel(log_level)
debug = False  # very local debug

class PlayerElo(object):
    def __init__(self, player_id=None, game_type_cd=None, elo=None):
        self.create_dt = datetime.utcnow()
        self.player_id = player_id
        self.game_type_cd = game_type_cd
        self.elo = 100.0
        self.g2_r = None
        self.g2_rd = None
        self.score = 0
        self.games = 0
        self.g2_games = 0
        self.g2_dt = None
        self.b_r = None
        self.b_rd = None
        self.b_games = 0
        self.b_dt = None

    def __repr__(self):
        return "<PlayerElo(pid=%s, gametype=%s, elo=%s, games=%s)>" % (self.player_id, self.game_type_cd, self.elo, self.games)

    def to_dict(self):
        return {
          'player_id':self.player_id, 'game_type_cd':self.game_type_cd, 'elo':self.elo, 'games':self.games,
          'g2_r':self.g2_r, 'g2_rd':self.g2_rd,  "g2_games":self.g2_games, "g2_dt":self.g2_dt,
          'b_r':self.b_r, 'b_rd':self.b_rd,  "b_games":self.b_games, "b_dt":self.b_dt
        }

class EloParms:
    def __init__(self, global_K = 15, initial = 100, floor = 80, logdistancefactor = math.log(10)/float(400), maxlogdistance = math.log(10)):
        self.global_K = global_K
        self.initial = initial
        self.floor = floor
        self.logdistancefactor = logdistancefactor
        self.maxlogdistance = maxlogdistance

class KReduction:
    #KREDUCTION = KReduction(900, 75, 0.5, 5, 15, 0.2)
    def __init__(self, fulltime, mintime, minratio, games_min, games_max, games_factor):
        self.fulltime = fulltime
        self.mintime = mintime
        self.minratio = minratio
        self.games_min = games_min
        self.games_max = games_max
        self.games_factor = games_factor

    def eval(self, mygames, mytime, matchtime):
        if mytime < self.mintime:
            return 0
        if mytime < self.minratio * matchtime:
            return 0
        if mytime < self.fulltime:
            k = mytime / float(self.fulltime)
        else:
            k = 1.0
        if mygames >= self.games_max:
            k *= self.games_factor
        elif mygames > self.games_min:
            k *= 1.0 - (1.0 - self.games_factor) * (mygames - self.games_min) / float(self.games_max - self.games_min)

        return k

# parameters for K reduction
# this may be touched even if the DB already exists

KREDUCTION = KReduction(900, 75, 0.5, 3, 10, 0.2)

# parameters for chess elo
# only global_K may be touched even if the DB already exists
# we start at K=200, and fall to K=40 over the first 20 games
ELOPARMS = EloParms(global_K=200)

def process_rtcwpro_elo(ddb_table, ddb_client, match_id, log_stream_name):
    "RTCWPro pipeline specific logic."
    t1 = _time.time()
    sk = match_id

    response = get_item("statsall", sk, ddb_table, log_stream_name)
    if "error" not in response:
        stats = json.loads(response["data"])
        logger.info("Retrieved statsall for " + str(len(stats)) + " players")
        stats = convert_stats_to_dict(stats)
    else:
        message = "Failed to retrieve statsall."
        logger.error(message)
        return message
        logger.error(json.dumps(response))

    response = get_item("wstatsall", sk, ddb_table, log_stream_name)
    if "error" not in response:
        wstats = json.loads(response["data"])
        logger.info("Retrieved wstatsall for " + str(len(wstats)) + " players")
    else:
        message = "Failed to retrieve wstatsall."
        logger.error(message)
        return message
        logger.error(json.dumps(response))

    response = get_item("match", sk + "2", ddb_table, log_stream_name)  # round 2
    if "error" not in response:
        match = json.loads(response["data"])
        match_region = response["lsipk"].split("#")[0]
        match_type = response["lsipk"].split("#")[1]
        match_region_type = match_region + "#" + match_type
        try:
            time_split = match["time_limit"].split(":")
            duration = int(time_split[0]) * 60 + int(time_split[1])
        except Exception:
            duration = 600
        winner = match["winner"]
    else:
        message = "Failed to retrieve match."
        logger.error(message)
        return message
        logger.error(json.dumps(response))

    real_name_request_list = prepare_player_name_list(stats)
    response = get_batch_items(real_name_request_list, ddb_table, log_stream_name)
    real_names = {}
    if "error" not in response:
        for result in response:
            guid = result["pk"].split("#")[1]
            if "data" in result:
                real_names[guid] = result["data"]
                logger.info("Retrieved " + guid + " name: " + result["data"])

    elo_item_list = prepare_player_elo_list(stats, match_region_type)
    response = get_batch_items(elo_item_list, ddb_table, log_stream_name)

    elo_dict = {}
    elo_games = {}
    if "error" not in response:
        for result in response:
            guid = result["pk"].split("#")[1]
            if match_region_type in result["sk"]:
                elo_dict[guid] = result["data"]
                elo_games[guid] = int(result["games"])
                logger.info("Retrieved " + match_region_type + "#elo" + " " + " " + real_names.get(guid,"no_name").ljust(20) + " elo:" + str(elo_dict[guid]) + " games " + str(elo_games[guid]))

    else:
        logger.error("Failed to retrieve any player elos.")
        logger.error(json.dumps(response))

    Player = namedtuple('Player', 'score duration games')

    new_wstats = {}
    for wplayer_wrap in wstats:
        for wplayer_guid, wplayer in wplayer_wrap.items():
            new_wplayer = {}
            for weapon in wplayer:
                new_wplayer[weapon["weapon"]] = weapon
            new_wstats[wplayer_guid] = new_wplayer

    player_scores = {}
    for guid, player_stats in stats.items():
        score_step_1 = player_stats["categories"].get("kills", 0)
        score_step_2 = score_step_1 \
            - wstat(new_wstats, guid, "Panzer", "kills") * .30 \
            - wstat(new_wstats, guid, "Artillery", "kills") * .30 \
            - wstat(new_wstats, guid, "Airstrike", "kills") * .30 \
            - wstat(new_wstats, guid, "Mauser", "kills") * .30

        win_multiplier = 1.5 if player_stats["team"] == winner else 1
        score_step_3 = int(score_step_2 * win_multiplier)

        player_scores[guid] = Player(score_step_3, duration, elo_games.get(guid,0)) # if elo is not there, default will be 0 anyway
        if debug:
            logger.info(player_stats.get("alias", "missing_alias").ljust(20) + str(player_stats["categories"].get("kills", 0)).ljust(5) + str(win_multiplier).ljust(5) + str(score_step_3).ljust(5) + str(player_scores[guid].games).ljust(5))

    (elo_deltas, elos) = process_elos(player_scores, elo_dict)

    items = []
    elo_delta_items = ddb_prepare_eloprogress_items(player_scores, elos, elo_deltas, match_id, match_region_type, real_names)
    player_elo_items = ddb_prepare_player_elo_items(elos, match_region_type, real_names)
    items.extend(elo_delta_items)
    items.extend(player_elo_items)

    try:
        ddb_batch_write(ddb_client, ddb_table.name, items)
    except Exception as ex:
        template = "An exception of type {0} occurred. Arguments:\n{1!r}"
        error_msg = template.format(type(ex).__name__, ex.args)
        message = "Failed to load all eloprogress records for a match " + match_id + "\n" + error_msg
        logger.info(message)
        return message
    else:
        message = "Elo progress records inserted.\n"

    time_to_write = str(round((_time.time() - t1), 3))
    logger.info(f"Time to process ELOs is {time_to_write} s")
    return message

def convert_stats_to_dict(stats):
    if len(stats) == 2 and len(stats[0]) > 1: #stats grouped in teams in a list of 2 teams , each team over 1 player
        logger.info("Number of stats entries 2, trying to merge teams")
        stats_tmp = stats[0].copy()
        stats_tmp.update(stats[1])
    else:
        logger.info("Merging list into dict.")
        stats_tmp = {}
        for player in stats:
            stats_tmp.update(player)
    logger.info("New statsall has " + str(len(stats_tmp)) + " players in a " + str(type(stats_tmp)))
    return stats_tmp

def wstat(new_wstats, guid, weapon, metric):
    """Safely get a number from a deeply nested dict."""
    if guid not in new_wstats:
        value = 0
    elif weapon not in new_wstats[guid]:
        value = 0
    elif metric not in new_wstats[guid][weapon]:
        value = 0
    else:
        value = new_wstats[guid][weapon][metric]
    return value

def process_elos(player_scores, elo_dict):
    """Given the players perforance and previous record, calculate new ELOs."""
    duration = player_scores[list(player_scores.keys())[0]].duration

    scores = {}
    alivetimes = {}
    games = {}

    for guid, p in player_scores.items():
        scores[guid] = p.score
        alivetimes[guid] = p.duration  #quke clan arena only, keeping for code wholesomeness
        games[guid] = p.games

    player_ids = scores.keys()

    elos = {}
    for p in player_ids:
        if p in elo_dict:
            elos[p] = PlayerElo(p)
            elos[p].elo = elo_dict[p]
            elos[p].games = player_scores[p].games

    # ensure that all player_ids have an elo record
    for pid in player_ids:
        if pid not in elos.keys():
            elos[pid] = PlayerElo(pid, None, ELOPARMS.initial)

    for pid in list(player_ids):
        elos[pid].k = KREDUCTION.eval(games[pid], alivetimes[pid], duration)
        if elos[pid].k == 0:
            del(elos[pid])
            del(scores[pid])
            del(alivetimes[pid])

    elos = update_elos(elos, scores, ELOPARMS)

    return elos

def update_elos(elos, scores, ep):
    if len(elos) < 2:
        return elos

    pids = list(elos.keys())

    eloadjust = {}
    for pid in pids:
        eloadjust[pid] = 0.0

    for i in range(0, len(pids)):
        ei = elos[pids[i]]
        for j in range(i+1, len(pids)):
            ej = elos[pids[j]]
            si = scores[ei.player_id]
            sj = scores[ej.player_id]

            # normalize scores
            ofs = min(0, si, sj)
            si -= ofs
            sj -= ofs
            if si + sj == 0:
                si, sj = 1, 1 # a draw

            # real score factor
            scorefactor_real = si / float(si + sj)

            # duels are done traditionally - a win nets
            # full points, not the score factor

            #if game.game_type_cd == 'duel':
            if False:
                # player i won
                if scorefactor_real > 0.5:
                    scorefactor_real = 1.0
                # player j won
                elif scorefactor_real < 0.5:
                    scorefactor_real = 0.0
                # nothing to do here for draws

            # expected score factor by elo
            elodiff = min(ep.maxlogdistance, max(-ep.maxlogdistance,
                (float(ei.elo) - float(ej.elo)) * ep.logdistancefactor))
            scorefactor_elo = 1 / (1 + math.exp(-elodiff))

            # initial adjustment values, which we may modify with additional rules
            adjustmenti = scorefactor_real - scorefactor_elo
            adjustmentj = scorefactor_elo - scorefactor_real

            if debug:
                print("Player i: {0}".format(ei.player_id))
                print("Player i's K: {0}".format(ei.k))
                print("Player j: {0}".format(ej.player_id))
                print("Player j's K: {0}".format(ej.k))
                print("Scorefactor real: {0}".format(scorefactor_real))
                print("Scorefactor elo: {0}".format(scorefactor_elo))
                print("adjustment i: {0}".format(adjustmenti))
                print("adjustment j: {0}".format(adjustmentj))

            if scorefactor_elo > 0.5:
            # player i is expected to win
                if scorefactor_real > 0.5:
                # he DID win, so he should never lose points.
                    adjustmenti = max(0, adjustmenti)
                else:
                # he lost, but let's make it continuous (making him lose less points in the result)
                    adjustmenti = (2 * scorefactor_real - 1) * scorefactor_elo
            else:
            # player j is expected to win
                if scorefactor_real > 0.5:
                # he lost, but let's make it continuous (making him lose less points in the result)
                    adjustmentj = (1 - 2 * scorefactor_real) * (1 - scorefactor_elo)
                else:
                # he DID win, so he should never lose points.
                    adjustmentj = max(0, adjustmentj)

            eloadjust[ei.player_id] += adjustmenti
            eloadjust[ej.player_id] += adjustmentj

    elo_deltas = {}
    for pid in pids:
        old_elo = float(elos[pid].elo)
        new_elo = max(float(elos[pid].elo) + eloadjust[pid] * elos[pid].k * ep.global_K / float(len(elos) - 1), ep.floor)
        elo_deltas[pid] = new_elo - old_elo

        debug_player = "kek"
        if debug_player in elo_deltas:
            print(debug_player + " elo delta: " + str(elo_deltas[debug_player]))

        elos[pid].elo = new_elo
        elos[pid].games += 1
        #elos[pid].update_dt = datetime.utcnow()

        #log.debug("Setting Player {0}'s Elo delta to {1}. Elo is now {2} (was {3}).".format(pid, elo_deltas[pid], new_elo, old_elo))
        if debug:
            print("Setting Player {0}'s Elo delta to {1}. Elo is now {2} (was {3}).".format(pid, elo_deltas[pid], new_elo, old_elo))

    return (elo_deltas, elos)

def make_error_dict(message, item_info):
    """Make an error message for API gateway."""
    return {"error": message + " " + item_info}

def get_item(pk, sk, table, log_stream_name):
    """Get one dynamodb item."""
    item_info = pk + ":" + sk + ". Logstream: " + log_stream_name
    try:
        response = table.get_item(Key={'pk': pk, 'sk': sk})
    except ClientError as e:
        logger.warning("Exception occurred: " + e.response['Error']['Message'])
        result = make_error_dict("[x] Client error calling database: ", item_info)
    else:
        if "Item" in response:
            result = response['Item']
        else:
            result = make_error_dict("[x] Item does not exist: ", item_info)
    return result

def prepare_player_elo_list(stats, match_region_type):
    """Make a list of guids to retrieve from ddb."""
    item_list = []
    for guid, player_stats in stats.items():
        item_list.append({"pk": "player#"+guid, "sk": "elo#" + match_region_type})
    return item_list

def prepare_player_name_list(stats):
    """Make a list of guids to retrieve from ddb."""
    item_list = []
    for guid, player_stats in stats.items():
        item_list.append({"pk": "player#"+guid, "sk": "realname"})
    return item_list

def get_batch_items(item_list, ddb_table, log_stream_name):
    """Get items in a batch."""
    dynamodb = boto3.resource('dynamodb')
    item_info = "get_batch_items. Logstream: " + log_stream_name
    try:
        response = dynamodb.batch_get_item(RequestItems={ddb_table.name: {'Keys': item_list, 'ProjectionExpression': 'pk, sk, #data_value, real_name, games', 'ExpressionAttributeNames': {'#data_value': 'data'}}})
    except ClientError as e:
        logger.warning("Exception occurred: " + e.response['Error']['Message'])
        result = make_error_dict("[x] Client error calling database: ", item_info)
    else:
        if len(response["Responses"][ddb_table.name]) > 0:
            result = response["Responses"][ddb_table.name]
        else:
            result = make_error_dict("[x] Item does not exist: ", item_info)
    return result

def create_batch_write_structure(table_name, items, start_num, batch_size):
    """
    Create item structure for passing to batch_write_item
    :param table_name: DynamoDB table name
    :param items: large collection of items
    :param start_num: Start index
    :param num_items: Number of items
    :return: dictionary of tables to write to
    """

    serializer = boto3.dynamodb.types.TypeSerializer()
    item_batch = { table_name: []}
    item_batch_list = items[start_num : start_num + batch_size]
    if len(item_batch_list) < 1:
        return None
    for item in item_batch_list:
        item_serialized = {k: serializer.serialize(v) for k,v in item.items()}
        item_batch[table_name].append({'PutRequest': {'Item': item_serialized}})

    return item_batch

def ddb_batch_write(client, table_name, items):
        messages = ""
        num_items = len(items)
        logger.info(f'Performing ddb_batch_write to dynamo with {num_items} items.')
        start = 0
        batch_size = 25
        while True:
            # Loop adding 25 items to dynamo at a time
            request_items = create_batch_write_structure(table_name,items, start, batch_size)
            if not request_items:
                break
            try:
                response = client.batch_write_item(RequestItems=request_items)
            except ClientError as err:
                logger.error(err.response['Error']['Message'])
                logger.error("Failed to run full batch_write_item")
                raise
            if len(response['UnprocessedItems']) == 0:
                logger.info(f'Wrote a batch of about {batch_size} items to dynamo')
            else:
                # Hit the provisioned write limit
                logger.warning('Hit write limit, backing off then retrying')
                sleep_time = 5 #seconds
                logger.warning(f"Sleeping for {sleep_time} seconds")
                _time.sleep(sleep_time)

                # Items left over that haven't been inserted
                unprocessed_items = response['UnprocessedItems']
                logger.warning('Resubmitting items')
                # Loop until unprocessed items are written
                while len(unprocessed_items) > 0:
                    response = client.batch_write_item(RequestItems=unprocessed_items)
                    # If any items are still left over, add them to the
                    # list to be written
                    unprocessed_items = response['UnprocessedItems']

                    # If there are items left over, we could do with
                    # sleeping some more
                    if len(unprocessed_items) > 0:
                        sleep_time = 5 #seconds
                        logger.warning(f"Sleeping for {sleep_time} seconds")
                        _time.sleep(sleep_time)

                # Inserted all the unprocessed items, exit loop
                logger.warning('Unprocessed items successfully inserted')
                break
            if response["ResponseMetadata"]['HTTPStatusCode'] != 200:
                messages += f"\nBatch {start} returned non 200 code"
            start += 25

def ddb_prepare_eloprogress_items(player_scores, elos, elo_deltas, match_id, match_region_type, real_names):
    elo_delta_items = []

    for guid in elo_deltas:
        if guid in player_scores:
            performance_score = player_scores[guid].score
        if guid in elos:
            elo = elos[guid].elo
        elo_item = {
            'pk'    : "eloprogress#" + guid,
            'sk'    : match_region_type + "#" + match_id,
            'data'  : int(round(elo_deltas[guid],0)),
            'gsi1pk': "eloprogressmatch",
            'gsi1sk': match_id,
            'real_name': real_names.get(guid,""),
            'elo': int(round(elo, 0)),
            'performance_score': performance_score
            }
        elo_delta_items.append(elo_item)
    return elo_delta_items

def ddb_prepare_player_elo_items(elos, match_region_type, real_names):
    player_elo_items = []
    ts = datetime.now().isoformat()
    for guid, elo in elos.items():
        elo_item = ddb_prepare_elo_item(guid, match_region_type, elo.elo, elo.games, ts, real_names.get(guid,""))
        player_elo_items.append(elo_item)
    return player_elo_items

def ddb_prepare_elo_item(guid, match_region_type, elo, games, ts, real_name):
    elo = int(round(elo, 0))
    elo_item = {
            'pk'            : "player"+ "#" + guid,
            'sk'            : "elo#" + match_region_type,
            # 'lsipk'         : "",
            'gsi1pk'        : "leaderelo#" + match_region_type,
            'gsi1sk'        : str(elo).zfill(3),
            'data'          : str(elo),
            'games'         : games,
            'updated'       : ts,
            "real_name"     : real_name
        }
    logger.info("Setting   " + guid + " " + real_name + " elo:" + str(elo) + " games " + str(games))
    return elo_item


import json

with open("pokemons.json") as file:
    pokemons = json.load(file)["results"]

# ACESSAR UMA CHAVE
# print(pokemons[0]["evolution"])

grass_type_pokemons = [
    pokemon for pokemon in pokemons if "Grass" in pokemon["type"]
]

with open("grass_pokemons.json", "w") as file:
    # json.dumps joga numa variavel
    # json_to_write = json.dumps(grass_type_pokemons) #converte de python pra json
    # file.write(json_to_write)

    # json.dump joga direto no arquivo
    json.dump(grass_type_pokemons, file)


import django_filters
from django_filters import CharFilter

from .models import *

class OrderFilter(django_filters.FilterSet):
    note = CharFilter(field_name='nome', lookup_expr='icontains')
    class Meta:
        model = Pescado
        fields = '__all__'
        exclude = ['nome']

class UsuarioFilter(django_filters.FilterSet):
    note = CharFilter(field_name='nome', lookup_expr='icontains')
    note1 = CharFilter(field_name='sobrenome', lookup_expr='icontains')

    class Meta:
        model = Usuario
        fields = '__all__'
        exclude = ['user', 'nome', 'sobrenome', 'telefone', 'cpf','endereco']

class PescariaFilter(django_filters.FilterSet):

    class Meta:
        model = Pescaria
        fields = '__all__'


from django.http import HttpResponse
from django.http import HttpResponseRedirect
from django.http import Http404
from django.shortcuts import render
from .models import Movie

# data = {
#     'movies': [
#         {
#             'id': 5,
#             'title': 'Jaws',
#             'year': 1669,
#         },
#         {
#             'id': 6,
#             'title': 'Sharknado',
#             'year': 1660,
#         },
#         {
#             'id': 7,
#             'title': 'The Meg',
#             'year': 1670,
#         }
#     ]
# }

def movies(req):
    data = Movie.objects.all()
    return render(req, 'movies/movies.html', {'movies': data})

def home(req):
    return HttpResponse("Home Page")

def detail(req, id):
    try:
        data = Movie.objects.get(pk=id)
    except:
        raise Http404('Movie does not exist')

    return render(req, 'movies/detail.html', {'movie': data})

def add(req):
    title = req.POST.get('title')
    year = req.POST.get('year')

    if title and year:
        movie = Movie(title=title, year=year)
        movie.save()
        return HttpResponseRedirect('/movies')
    return render(req, 'movies/add.html')

def delete(req, id):
    try:
        movie = Movie.objects.get(pk=id)
    except:
        raise Http404('Movie does not exist')

    movie.delete()
    return HttpResponseRedirect('/movies')


from soc import debug_messages
from playing import get_all_messages
from collections import Counter
from edtext import clean
from more_itertools import unique_everseen
import json

def main():
    messages_json = get_all_messages()
    start = 3 * 1500
    finish = start + 1500
    messages_chunk = messages_json[start:finish]
    messages_text = [el['message'] for el in messages_json]
    # debug_messages(messages_text)
    counted_all = Counter()
    edited_messages = list(unique_everseen([clean(' '.join(el)) for el in messages_text]))
    for message in edited_messages:
        counted_all += Counter(message.split())
    with open('result.json', 'w', encoding='utf-8') as file:
        json.dump(counted_all, file)
    # interesting = 'должна'
    # last = '''М, 23, Питер. Ищу с кем сходить на Твое имя в эти выходные. А так же с кем до смотреть Апрельскую ложь. Живу на севере Питера  Vk.com/s.slip'''

if __name__ == '__main__':
    main()


# -*- coding: utf-8 -*-
import scrapy
import time
from scrapy.http import Request
from loguru import logger
from urllib.parse import urljoin

from SafetyInformation.items import SafeInfoItem
from SafetyInformation.settings import SLEEP_TIME, TOTAL_PAGES

class Myhack58Spider(scrapy.Spider):
    name = 'myhack58'
    allowed_domains = ['myhack58.com']
    start_urls = ['http://www.myhack58.com/Article/html/1/4/Article_004_1.htm']
    page = 1
    headers = {
        'Referer': 'http://www.myhack58.com/',
        'Host': 'www.myhack58.com',
    }
    source = 'http://www.myhack58.com/'

    def parse(self, response):
        logger.info("==========当前正在抓取第{}页==========".format(self.page))
        item = SafeInfoItem()
        info_list = response.xpath('//div[@class="ArticleListBox"]/ul')
        for info in info_list:
            title = info.xpath('./li[@class="Noptitle"]/a/text()').extract_first('')
            link = info.xpath('./li[@class="Noptitle"]/a/@href').extract_first('')
            link = urljoin(self.source, link)
            intro = info.xpath('./li[@class="Noptdes"]/text()').extract_first('')
            n_info = info.xpath('./li[@class="Noptinfo"]/text()').extract_first('').split(' ')
            nopt_info = [n for n in n_info if n.strip()]
            tags = nopt_info[0].split('：')[-1]
            date = nopt_info[1].split('：')[-1]
            info_type = nopt_info[2].split('：')[-1] if nopt_info[2].split('：')[-1] else 'news'
            source = self.source
            author = ''
            item['title'] = title
            item['link'] = link
            item['intro'] = intro
            item['date'] = date
            item['source'] = source
            item['type'] = info_type
            item['author'] = author
            logger.info(item)
            yield item

        time.sleep(SLEEP_TIME)
        self.page += 1
        next_url = 'http://www.myhack58.com/Article/html/1/4/Article_004_{}.htm'.format(self.page)
        if self.page <= TOTAL_PAGES:
            yield Request(url=next_url, headers=self.headers, callback=self.parse)


import numpy as np

def Euclidean(point1,point2):
    distance = np.sqrt(np.sum(np.square(point1-point2)))
    return distance

def assign_clusters(data, cluster_centers):
    """
    Assigns every data point to its closest (in terms of Euclidean distance) cluster center.
    :param data: An (N, D) shaped numpy array where N is the number of examples
    and D is the dimension of the data
    :param cluster_centers: A (K, D) shaped numpy array where K is the number of clusters
    and D is the dimension of the data
    :return: An (N, ) shaped numpy array. At its index i, the index of the closest center
    resides to the ith data point.
    """
    belongs_clusters = np.ones(len(data))
    for i in range(len(data)):
        min = 100
        for j in range(len(cluster_centers)):
            distance = Euclidean(cluster_centers[j],data[i])
            if(distance < min):
                min = distance
                belongs_clusters[i] = j

    return belongs_clusters

def calculate_cluster_centers(data, assignments, cluster_centers, k):
    """
    Calculates cluster_centers such that their squared Euclidean distance to the data assigned to
    them will be lowest.
    If none of the data points belongs to some cluster center, then assign it to its previous value.
    :param data: An (N, D) shaped numpy array where N is the number of examples
    and D is the dimension of the data
    :param assignments: An (N, ) shaped numpy array with integers inside. They represent the cluster index
    every data assigned to.
    :param cluster_centers: A (K, D) shaped numpy array where K is the number of clusters
    and D is the dimension of the data
    :param k: Number of clusters
    :return: A (K, D) shaped numpy array that contains the newly calculated cluster centers.
    """
    for i in range(k):
        distance_point = [0,0]
        count = 0
        for j in range(len(data)):
            if(assignments[j] == i ):
                distance_point += data[j]
                count += 1
        if(count != 0 ):
            x = distance_point[0] / count
            y = distance_point[1] / count
            cluster_centers[i] = [x,y]

    return cluster_centers

def kmeans(data, initial_cluster_centers):
    """
    Applies k-means algorithm.
    :param data: An (N, D) shaped numpy array where N is the number of examples
    and D is the dimension of the data
    :param initial_cluster_centers: A (K, D) shaped numpy array where K is the number of clusters
    and D is the dimension of the data
    :return: cluster_centers, objective_function
    cluster_center.shape is (K, D).
    objective function is a float. It is calculated by summing the squared euclidean distance between
    data points and their cluster centers.
    """
    cluster_centers = initial_cluster_centers
    previous_objective_function = 0.0
    while(True):
        belongs_clusters = assign_clusters(data,cluster_centers)
        cluster_centers = calculate_cluster_centers(data,belongs_clusters,cluster_centers,len(cluster_centers))
        objective_function = 0.0
        for i in range(len(cluster_centers)):
            for j in range(len(data)):
                if(belongs_clusters[j] == i ):
                    objective_function += np.square(data[j]-cluster_centers[i])
        objective_function = np.sum(objective_function)
        if(objective_function == previous_objective_function):
            return cluster_centers, objective_function/2
        previous_objective_function = objective_function


class OrderedStream:

    def __init__(self, n: int):
        self.data = [None] * n
        self.ptr = 0

    def insert(self, idKey: int, value: str) -> List[str]:
        self.data[idKey - 1] = value
        res = []
        if (idKey - 1) == self.ptr:
            for i in range(self.ptr, len(self.data)):
                if self.data[self.ptr] is None:
                    break
                res.append(self.data[self.ptr])
                self.ptr += 1
        return res


from math import sqrt
def divisor(n) :
    i = 2
    ans = []
    while i <= sqrt(n):
        if (n % i == 0) :
            if (n // i == i) :
                ans.append(i)
            else :
                ans.append(i)
                ans.append(n//i)
        i = i + 1

    return ans

square = []
for i in range(2, 10**5):
    if i*i>10**9:
        square.append(i*i)
        break
    square.append(i*i)

n = int(input())

count = 0
divi = divisor(n)
for i in range(len(divi)):
    for j in range(len(square)):
        if square[j]>divi[i]:
            break
        elif divi[i]%square[j]==0:
            count+=1
            break
            print(divi[i])

print(len(divi)-count)


######################################################################
# File: retrieval_model.py
# Author: Vishal Dey
# Created on: 11 Dec 2019
#######################################################################
'''
 Synopsis: Create w2v for corresponding string description of each problem
	Reads in pretrianed Word2vec vectors and add each word vector to obtain
	phrase vectors.
	Either compute TF-IDF / w2v based cosine similarity
'''

import os
import json
import sys

import numpy as np
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import linear_kernel, cosine_similarity
from copy import deepcopy

# for reproducibility
np.random.choice(123)

# read json file
def read_json(fname):
	with open(os.path.join('./data/', fname), 'r') as fp:
		return json.load(fp)

# compute TF-iDF based most similar problem
def find_similar_tfidf(tfidf_matrix, tfidf_vector):
	cosine_similarities = linear_kernel(tfidf_vector, tfidf_matrix).flatten()
	related_docs_indices = [i for i in cosine_similarities.argsort()[::-1]]
	#print(related_docs_indices[0], cosine_similarities[related_docs_indices[0]])
	return related_docs_indices[0]

# compute w2v cosine based most similar problem
def find_similar_w2v(w2vmatrix, w2vemb, query, EMB_DIM, minv=0, maxv=1):
	query_emb = []
	for word in query.split():
		if word in w2vemb:
			query_emb.append(np.array(list(map(float, w2vemb[word]))))
		else:
			query_emb.append(np.random.uniform(minv, maxv, EMB_DIM))

	cosine_similarities = linear_kernel(query_emb, w2vmatrix).flatten()
	related_docs_indices = [i for i in cosine_similarities.argsort()[::-1]]
	print(related_docs_indices)
	return related_docs_indices[0]

# load w2v problem
def load_w2v(w2v_file):
	EMB_DIM = 0
	w2v_emb = {}
	minv = sys.float_info.max
	maxv = sys.float_info.min

	with open(os.path.join('./w2v', w2v_file), 'r') as fp:
		EMB_DIM = int(fp.readline().split()[1])
		for line in fp.readlines():
			tmp = line.split()
			tmp = list(map(float, tmp[1:]))
			minv = min(minv, min(tmp))
			maxv = max(maxv, max(tmp))

	print(EMB_DIM, minv, maxv)
	return w2v_emb, EMB_DIM, minv, maxv

# compute w2v matrix (problem x EMB_DIM)
def compute_w2vmatrix(docs, w2v_emb, EMB_DIM, minv=0, maxv=1):
	w2vmatrix = []
	for doc in docs:
		emb = [0]*EMB_DIM
		for word in doc.split():
			if word in w2v_emb:
				emb += np.array(list(map(float, w2v_emb[word])))
			else:
				emb += np.random.uniform(minv, maxv, EMB_DIM)
		emb /= len(doc.split())

		w2vmatrix.append(emb)
	return w2vmatrix

# post fix equation solver
def post_solver(post_equ):
	stack = []
	op_list = ['+', '-', '/', '*', '^']

#	if len(post_equ)-2*len([i for i in post_equ if (any(c.isdigit() for c in i))]) >= 0:
#		print(post_equ)
#		return 0
	for elem in post_equ:
		if elem not in op_list:
			op_v = elem
			if '%' in op_v:
				op_v = float(op_v[:-1])/100.0
			if op_v == 'PI':
				op_v = np.pi
			stack.append(str(op_v))
		elif elem in op_list:
			op_v_1 = stack.pop()
			op_v_1 = float(op_v_1)
			op_v_2 = stack.pop()
			op_v_2 = float(op_v_2)
			if elem == '+':
				stack.append(str(op_v_2+op_v_1))
			elif elem == '-':
				stack.append(str(op_v_2-op_v_1))
			elif elem == '*':
				stack.append(str(op_v_2*op_v_1))
			elif elem == '/':
				if op_v_1 == 0:
					return np.nan
				stack.append(str(op_v_2/op_v_1))
			else:
				stack.append(str(op_v_2**op_v_1))
	return stack.pop()

# get post fix equation from the template
def get_equation(template, num_list):
	equation = []
	for x in template:
		if 'temp' in x:
			equation.append(str(num_list[int(x.split('_')[1])]))
		else:
			equation.append(x)
	return equation

def main():
	math23k = read_json('math23k_final.json')
	#math23k = read_json('final_dolphin_data.json')

	# read in test IDs and answer -  gold truth
	test_ids = []
	with open('./data/id_ans_test', 'r') as fp:
		for line in fp.readlines():
			test_ids.append(line.split('\t')[0])
#	del math23k['1682']

	test_length = len(test_ids)

	train = {}
	test = {}
	corpus = []

	# make training corpus text
	for k, v in math23k.items():
		if k not in test_ids:
			train[k] = v
			corpus.append(v['template_text'])
		else:
			test[k] = v

	corpus = list(corpus)
	indices = list(train.keys())

	print(len(corpus), test_length)

	# tfidf vectorizer
	vectorizer = TfidfVectorizer()
	corpus_tfidf = vectorizer.fit_transform(corpus)

	# load w2v
	#w2v_emb, EMB_DIM, minv, maxv = load_w2v('crawl-300d-2M.vec')
	#w2vmatrix = compute_w2vmatrix(corpus, w2v_emb, EMB_DIM, minv, maxv)

	#print(len(w2vmatrix))
	similar_indices = {}

	for k, v in test.items():
		query_tfidf = vectorizer.transform([v['template_text']])
		i = find_similar_tfidf(corpus_tfidf, query_tfidf)
		#i = find_similar_w2v(w2vmatrix, w2v_emb, v['template_text'], EMB_DIM, minv, maxv)
		#i = jaccard_similarity(corpus, v['template_text'])
		#print(i)
		similar_indices[k] = indices[i]

	num_correct = 0
	# outputs the prediction
	fout = open('pred.txt', 'w')

	for k, v in similar_indices.items():
		template = math23k[v]['post_template']
		num_list = math23k[k]['num_list']
		ans = math23k[k]['ans']

		if (max([int(s.split('temp_')[1]) for s in set(template) if 'temp' in s]) < len(num_list)):
			pred_ans = post_solver(get_equation(template, num_list))
			print(math23k[k]['index'], pred_ans, ans, file=fout)
			if (np.isclose(float(pred_ans), float(ans))):
				num_correct += 1
		else:
			print('wrong template prediction: mismatch with len of num list')

	print('Accuracy = ', str(float(num_correct)/test_length))
	fout.close()

main()


from wall import views
from django.urls import path

urlpatterns = [
	path('deer/',views.deerList.as_view(), name='deerlist'),
	path('realwreath/',views.RealWreathView.as_view(), name ="realwreathview"),
	path('ornament/',views.OrnamentView.as_view(), name ='ornament_list'),
	path('solvequestion/',views.SolveQuestion.as_view(), name="solvequestion"),
	#path('present/',PresentView.as_view(), name = "presentview"),
	path('socks/',views.SocksView.as_view(), name="socks")

]


from nltk.corpus import stopwords
from tensorflow.keras.preprocessing.text import Tokenizer
import gensim
import pandas as pd

from preprocess import process_text_data
from utils import load_epub
from word2vec import Word2Vec

def remove_stopword(book):
    corpus = list()
    stopword = stopwords.words('english')
    for _, sentences in book.items():
        for sentence in sentences:
            stopword_removed = list()
            for word in sentence.split():
                if word in stopword:
                    continue
                stopword_removed.append(word)
            if len(stopword_removed) > 1:
                corpus.append(' '.join(stopword_removed))
    return corpus

def tokenize_corpus(corpus):
    tokenizer = Tokenizer()
    tokenizer.fit_on_texts(corpus)

    sequences = tokenizer.texts_to_sequences(corpus)

    return tokenizer, sequences

if __name__ == '__main__':
    epub_path = \
        './ebook/J. D. Salinger - The Catcher in the Rye '\
        '(1951, Penguin Books Ltd).epub'
    book = load_epub(epub_path)
    book = process_text_data(book)
    book[0] = [' '.join(book[0])]

    corpus = remove_stopword(book)
    tokenizer, sequences = tokenize_corpus(corpus)

    word2idx = tokenizer.word_index

    vocab_size = len(word2idx) + 1
    window_size = 10
    embedding_size = 20
    word2vec = Word2Vec(vocab_size, window_size, embedding_size)

    word2vec.train(sequences, epochs=15)
    embedding = word2vec.get_embedding()
    with open('./output/embedding/word_embedding.txt', 'w') as f:
        f.write(f'{vocab_size-1} {embedding_size}\n')
        for word, idx in word2idx.items():
            word_vec = ' '.join(map(str, list(embedding[idx, :])))
            f.write(f'{word} {word_vec}\n')

    w2v = gensim.models.KeyedVectors.load_word2vec_format(
        fname='./output/embedding/word_embedding.txt'
    )

    targets = [
        'holden', 'phoebe', 'ackley', 'stradlater', 'jane', 'janine', 'rye'
    ]

    for target in targets:
        print(f'What Words are most Similarit to {target}')

        similar_words = w2v.most_similar(positive=[target])
        similar_df = pd.DataFrame(
            similar_words, columns=['word', 'similarity']
        )
        similar_df.to_csv(
            f'./output/dataframes/q3-similar_with_{target}.csv', index=False
        )


"""
File: expo.py
Project 3.4

Defines a function to raise a number to a given power.
Uses a recursive strategy to reduce the complexity to O(log n).
"""

def expo(base, exponent):
    """Raises base to exponent."""
    if exponent == 0:
        return 1
    elif exponent % 2 == 1:
        return base * expo(base, exponent - 1)
    else:
        result = expo(base, exponent // 2)
        return result * result

def main():
    """Tests with powers of 2."""
    for exponent in range (5):
        print(exponent, expo(2, exponent))

if __name__ == "__main__":
    main()


# 실버 1
# 14716. 현수막

import sys
from collections import deque
input = sys.stdin.readline

n, m = map(int, input().split())
mtx = [list(map(int, input().split())) for _ in range(n)]

q = deque()

dx = [-1, 0, 1, 0, -1, 1, -1, 1]
dy = [0, -1, 0, 1, -1, 1, 1, -1]

def bfs(i, j):
    q.append([i, j])
    mtx[i][j] = 0

    while q:
        x, y = q.popleft()

        for k in range(8):
            nx = x + dx[k]
            ny = y + dy[k]

            if 0 <= nx < n and 0 <= ny < m and mtx[nx][ny] == 1:
                q.append([nx, ny])
                mtx[nx][ny] = 0

count = 0

for i in range(n):
    for j in range(m):
        if mtx[i][j] == 1:
            bfs(i, j)
            count += 1

print(count)


import pygame
import random

WIDTH = 480
HEIGHT = 600
FPS = 60

# Задаем цвета
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)

# Создаем игру и окно
pygame.init()
pygame.mixer.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Star Defender")
clock = pygame.time.Clock()

class Player(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.Surface((50, 40))
        self.image.fill(GREEN)
        self.rect = self.image.get_rect()
        self.rect.centerx = WIDTH / 2
        self.rect.bottom = HEIGHT - 10
        self.speed_x = 0

    def update(self):
        self.speed_x = 0
        key_state = pygame.key.get_pressed()

        if key_state[pygame.K_LEFT]:
            self.speed_x = -8
        if key_state[pygame.K_RIGHT]:
            self.speed_x = 8
        self.rect.x += self.speed_x

        if self.rect.right > WIDTH:
            self.rect.right = WIDTH
        if self.rect.left < 0:
            self.rect.left = 0

class Mob(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.Surface((30, 40))
        self.image.fill(RED)
        self.rect = self.image.get_rect()
        self.rect.x = random.randrange(WIDTH - self.rect.width)
        self.rect.y = random.randrange(-100, -40)
        self.speed_x = random.randrange(-3, 3)
        self.speed_y = random.randrange(1, 8)

    def update(self):
        self.rect.x += self.speed_x
        self.rect.y += self.speed_y

        if self.rect.top > HEIGHT + 10:
            self.rect.x = random.randrange(WIDTH - self.rect.width)
            self.rect.y = random.randrange(-100, -40)
            self.speed_x = random.randrange(-3, 3)
            self.speed_y = random.randrange(1, 8)

        if self.rect.left < -20 or self.rect.right > WIDTH + 20:
            self.speed_x = -self.speed_x

all_sprites = pygame.sprite.Group()
mobs = pygame.sprite.Group()
player = Player()
all_sprites.add(player)
for i in range(8):
    m = Mob()
    all_sprites.add(m)
    mobs.add(m)

# Цикл игры
running = True
while running:
    # Держим цикл на правильной скорости
    clock.tick(FPS)

    # Ввод процесса (события)
    for event in pygame.event.get():
        # check for closing window
        if event.type == pygame.QUIT:
            running = False

    # Обновление
    all_sprites.update()

    # Рендеринг
    screen.fill(BLACK)
    all_sprites.draw(screen)

    # После отрисовки всего, переворачиваем экран
    pygame.display.flip()

pygame.quit()


#!/usr/bin/env python3
# dpw@plaza.localdomain
# 2023-07-29 22:24:28

from gtts import gTTS

def say(text, fname):
    tts = gTTS(text)
    tts.save(fname)

if __name__ == "__main__":
    fname = "tts.mp3"
    tts = gTTS(
        "this is a test; a, rather long test; of text 2 speach", lang="en", tld="ca"
    )
    tts.save(fname)


def solution(A):
    A.sort()
    n = len(A)

    product1 = A[n - 1] * A[n - 2] * A[n - 3]

    product2 = A[0] * A[1] * A[n - 1]

    product3 = A[n - 1] * A[n - 2] * A[n - 3]

    return max(product1, product2, product3)

A = [-3, 1, 2, -2, 5, 6]
result = solution(A)
print(result)


from astropy.io import fits
import numpy as np
import astropy.units as u
from agpy import cubes
from FITS_tools import cube_regrid
import agpy

#f2 = fits.open('H2CO_22_speccube.fits')
dpath = '/Volumes/128gbdisk/w51/'
#f2 = fits.open('Darray_H2CO_22_speccube_uniform_contsub_justspw19.image.fits')
f2 = fits.open(dpath+'W51Ku_BD_spw19.small_uniform_contsub19.cvel.clean.image.fits')

#cont2 = (f2[0].data[0,60:350,:,:].sum(axis=0) + f2[0].data[0,600:950,:,:].sum(axis=0))/(950-600+350-60)
cont2 = fits.getdata(dpath+'W51Ku_BD_spw20.small_uniform_continuum.clean.image.fits').squeeze()
ch = fits.getheader(dpath+'W51Ku_BD_spw20.small_uniform_continuum.clean.image.fits')
noisefloor = cont2[100:200,300:500].std()
#cont2 = fits.getdata(dpath+'W51Ku_BD_spw20.small_uniform_continuum.clean.image.fits').squeeze()
#ch = fits.getheader(dpath+'W51Ku_BD_spw20.small_uniform_continuum.clean.image.fits')

beam = (ch['BMAJ']*ch['BMIN'] * np.pi * u.deg**2)
cont_offset = (2.73*u.K).to(u.Jy,u.brightness_temperature(beam,14.488*u.GHz))

extra_cont_offset = 0.05

contlev = cont_offset.value + extra_cont_offset + noisefloor

#spec2 = f2[0].data[0,350:600,:,:] + 0.03
spec2 = f2[0].data[190:293,:,:] + contlev + cont2
# try to "subtract out" the negative continuum...
#spec2[:,cont2<0] -= cont2[cont2<0]
dosmooth = False
if dosmooth:
    spec2s = cube_regrid.spatial_smooth_cube(spec2,kernelwidth=1.5)

    cont2s = agpy.smooth(cont2+contlev,kernelwidth=1.5)
else:
    spec2s = spec2
    cont2s = cont2
spec2s[:,cont2s<0] -= cont2s[cont2s<0]
#cont2s[cont2s<contlev]=contlev

#cont2 += contlev
#cont2[cont2<contlev+noisefloor]=contlev+noisefloor

# "noise floor" (not really)
#spec2[spec2<0.01] = 0.01

#tau2 = -np.log((spec2/cont2))
tau2 = -np.log((spec2s/cont2s))
tau2[np.isnan(tau2)] = 5

f2[0].header['CRPIX3'] -= 190
f2[0].data = tau2
f2.writeto('H2CO_22_Ku_BD_small_taucube_sm.fits',clobber=True)

tau2ds = (tau2[11:83:3,:,:]+tau2[12:83:3,:,:]+tau2[13:83:3,:,:])/3.
h = f2[0].header
f2[0].header['CRVAL3'] = (10-h['CRPIX3']+1)*h['CDELT3']+h['CRVAL3']
f2[0].header['CRPIX3'] = 1
f2[0].header['CDELT3'] = h['CDELT3']*3
f2[0].data = tau2ds
f2.writeto('H2CO_22_Ku_BD_small_taucube_sm_ds.fits',clobber=True)

yy,xx = np.indices(tau2.shape[1:])
rr = ((xx-255.)**2+(yy-255.)**2)**0.5
mask = rr < 200
nanmask = np.zeros_like(mask,dtype='float')
nanmask[True-mask] = np.nan

integ1 = tau2[10:47,:,:].sum(axis=0)
f2[0].data = integ1 + nanmask
f2[0].writeto('H2CO_22_Ku_BD_small_tausummed_48to61.fits',clobber=True)

integ2 = tau2[41:69,:,:].sum(axis=0)
f2[0].data = integ2 + nanmask
f2[0].writeto('H2CO_22_Ku_BD_small_tausummed_59to68.fits',clobber=True)

integ3 = tau2[69:80,:,:].sum(axis=0)
f2[0].data = integ3 + nanmask
f2[0].writeto('H2CO_22_Ku_BD_small_tausummed_68to72.fits',clobber=True)

integ3 = tau2[10:80,:,:].sum(axis=0)
f2[0].data = integ3 + nanmask
f2[0].writeto('H2CO_22_Ku_BD_small_tausummed_48to72.fits',clobber=True)


from flask import Flask, render_template, request, redirect
from models import db, EmployeeModel

app = Flask(__name__)

app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///data.db"
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
db.init_app(app)

@app.before_first_request
def create_table():
    db.create_all()

@app.route('/')
def index():
    return render_template("index.html", title="Flask CRUD")

@app.route("/data/create", methods=["GET", "POST"])
def create():
    if request.method == "GET":
        return render_template("createpage.html", titel="Create data")

    if request.method == "POST":
        employee_id = request.form["employee_id"]
        name = request.form["name"]
        age = request.form["age"]
        position = request.form["position"]
        employee = EmployeeModel(
            employee_id=employee_id, name=name, age=age, position=position)
        db.session.add(employee)
        db.session.commit()
        return redirect("/data")

@app.route("/data")
def RetrieveList():
    employees = EmployeeModel.query.all()
    return render_template("datalist.html", employees=employees, title="Datalist")

@app.route("/data/<int:id>", methods=["GET", "POST"])
def RetrieveEmployee(id):
    if request.method == "POST":
        employee = EmployeeModel.query.filter_by(employee_id=id).first()
        if employee:
            return render_template("data.html", employee=employee, title="Data")
        return f"Employee with id ={id} Doenst exist"

@app.route("/data/<int:id>/update", methods=["GET", "POST"])
def update(id):
    employee = EmployeeModel.query.filter_by(employee_id=id).first()
    if request.method == "POST":
        if employee:
            db.session.delete(employee)
            db.session.commit()
            name = request.form["name"]
            age = request.form["age"]
            position = request.form["position"]
            employee = EmployeeModel(
                employee_id=id, name=name, age=age, position=position)
            db.session.add(employee)
            db.session.commit()
            return redirect(f"/data")

    return render_template("update.html", employee=employee, title="Update")

@app.route("/data/<int:id>/delete", methods=["GET", "POST"])
def delete(id):
    employee = EmployeeModel.query.filter_by(employee_id=id).first()
    if request.method == "POST":
        if employee:
            db.session.delete(employee)
            db.session.commit()
            return redirect("/data")
        abort(404)

    return render_template("delete.html", title="Delete")


import board
import audioio
import audiobusio
import digitalio
import time
import array
import math

buf = bytearray(8000)

print(3)
time.sleep(1)
print(2)
time.sleep(1)
print(1)
time.sleep(1)
print("recording", time.monotonic())
trigger = digitalio.DigitalInOut(board.A1)
trigger.switch_to_output(value = True)
with audiobusio.PDMIn(board.MICROPHONE_CLOCK, board.MICROPHONE_DATA) as mic:
    mic.record(buf, len(buf))
trigger.value = False
print("done recording", time.monotonic())

for i in buf[:10]:
    print(i)
print(min(buf), max(buf))
time.sleep(0.1)

speaker_enable = digitalio.DigitalInOut(board.SPEAKER_ENABLE)
speaker_enable.switch_to_output(value = True)
trigger.value = True

length = 16000 // 440
b = array.array("H", [0] * length)
for i in range(length):
    b[i] = int(math.sin(math.pi * 2 * i / length) * (2 ** 15 - 1) + (2 ** 15))

print(b)
with audioio.AudioOut(board.SPEAKER, b) as sample:
    sample.play(loop=True)
    time.sleep(1)
    sample.stop()

trigger.value = False

time.sleep(1)

trigger.value = True
print("playback", time.monotonic())
with audioio.AudioOut(board.SPEAKER, buf) as speaker:
    speaker.frequency = 8000
    speaker.play()
    while speaker.playing:
        pass

trigger.value = False


# https://www.acmicpc.net/problem/10815
# Solved Date: 20.05.21.

import sys
read = sys.stdin.readline

def search(cards, number):
    left = 0
    right = len(cards) - 1
    while left < right:
        mid = (left + right) // 2
        if cards[mid] < number:
            left = mid + 1
        else:
            right = mid
    if cards[left] == number:
        return '1'
    else:
        return '0'

def binary_search(cards, find_cards):
    ans = []
    for number in find_cards:
        ans.append(search(cards, number))
    return ' '.join(ans)

def hash_map(cards, find_cards):
    ans = []
    for find_num in find_cards:
        if find_num in cards:
            ans.append('1')
        else:
            ans.append('0')
    return ' '.join(ans)

def main(mode=''):
    cards_num = int(read().strip())
    if mode == 'binary':
        cards = sorted([int(x) for x in read().split()])
        find_num = int(read().strip())
        find_cards = [int(x) for x in read().split()]
        print(binary_search(cards, find_cards))
    else:
        cards = set(read().split())
        find_num = int(read().strip())
        find_cards = read().split()
        print(hash_map(cards, find_cards))

if __name__ == '__main__':
    main('binary')


''' Chapter 5.11 '''

numberOfStudents = int(input("Enter number of students: "))

highScore = 0
secondHighestScore = 0

for i in range(0, numberOfStudents):
    currentScore = int(input("Enter score: "));
    if(highScore == 0):
        highScore = currentScore;
    if(currentScore > highScore):
        secondHighestScore = highScore;
        highScore = currentScore;

print("The highest score is", highScore);
print("The second highest score is", secondHighestScore);


"""
Title         : find_short.py
Source        : Module 1 Remed Purwadhika no.1

Summary       : Buatlah suatu fungsi yang mengembalikan panjang terpendek dari suatu string kata
                yang terpisahkan oleh spasi (20 Point)

Feat Req      : Note: Kembalikan panjang dari kata yang terpendek, bukan katanya yang dikembalikan

"""

def find_short(x):
    pecah = x.split()                                       # First split the strings into each element
    baru = min(len(ele) for ele in pecah)                   # Create variabel to store the value of the minimum length inside the sentence by checking each one of them with for loop
    return baru                                             # Return the value of the length.

print(find_short('Many people get up early in the morning'))


import json
import time
import psycopg
from datetime import date, timedelta
from dateutil.relativedelta import relativedelta
from pgvector.psycopg import register_vector
from chatgpt import chatgpt_api
from ny_times import times_api

connection_string = ''
start_date = date(2020, 5, 27)
end_date = date(2000, 1, 1)

def get_connection_string():
    with open('pg_connection_string.txt', 'r') as f:
        return f.read()

def get_openai_api_key():
    with open('openai_api_key.txt', 'r') as f:
        return f.read()

def get_times_api_key():
    with open('times_api_key.txt', 'r') as f:
        return f.read()

def insert_times_embedding(content,
                           headline,
                           breadcrumbs,
                           url,
                           channel,
                           subchannel,
                           intro,
                           abstract,
                           snippet,
                           embedding_vector,
                           article_id):
    with psycopg.connect(connection_string) as conn:
        register_vector(conn)
        with conn.cursor() as cur:
            cur.execute(
                "INSERT INTO " + 'times_embeddings' +
                " (content, headline, breadcrumbs, url, channel, subchannel, intro, abstract, snippet, embedding, article_id)" +
                " VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)",
                (content,
                 headline,
                 breadcrumbs,
                 url,
                 channel,
                 subchannel,
                 intro,
                 abstract,
                 snippet,
                 embedding_vector,
                 article_id
                 ))
            conn.commit()

def generate_times_embeddings(year, month):
    '''Fetches time articles and creates embeddings from them'''
    print("Doing " + str(month) + "/" + str(year))
    api = times_api(get_times_api_key())
    embedder = chatgpt_api(get_openai_api_key())
    articles = []
    try:
        articles = api.get_articles_of_date(year, month)
        print("Found: " + str(len(articles)) + " articles")
    except Exception as ex:
        print("Error while fetching articles, maybe a timeout. Retrying soon")
        print(ex)
        time.sleep(120)
        generate_times_embeddings(year, month)

    for article in articles:
        # The full text is not provided within the api. I could scrape it, but
        # chances are there will be html, other tags or missing words in it.
        # For now: lets test with just the headline, abstract and first para
        text = article['abstract'] + ' ' + article['lead_paragraph']
        if(text == ''):
            continue
        embeddings = []
        try:
            embeddings = embedder.embed(text)
        except Exception as ex:
            print("Error while fetching embedding text:")
            print(ex)
            print("Waiting a few seconds, this is probably due to timeout.")
            time.sleep(300)
            start_date -= relativedelta(months=+1)
            generate_times_embeddings(start_date.year, start_date.month)

        # Now store the relevant data in the database
        try:
            breadcrumbs = list(map(lambda k: k['value'], article['keywords']))
            insert_times_embedding(text,
                                   article['headline']['main'],
                                   breadcrumbs,
                                   article['web_url'],
                                   article['keywords'][0]['value'],
                                   article['keywords'][1]['value'],
                                   article['lead_paragraph'],
                                   article['abstract'],
                                   article['snippet'],
                                   embeddings,
                                   article['_id'])
        except Exception as ex:
            # Dont print it. There are too many.
            # print("Failed to insert one article, prolly missing channels. Skipping it.")
            # print(ex)
            pass

if __name__ == "__main__":
    connection_string = get_connection_string()
    while start_date >= end_date:
        try:
            generate_times_embeddings(start_date.year, start_date.month)
            start_date -= relativedelta(months=+1)
        except Exception as ex:
            print("Unknown error. Restarting in a bit.")
            time.sleep(60)


import pathlib
import sys
import xml.etree.ElementTree as ET
from typing import Final

NAMESPACES: Final[dict[str, str]] = {
    "": "http://www.w3.org/2000/svg",
    "xlink": "http://www.w3.org/1999/xlink",
}

for prefix, uri in NAMESPACES.items():
    ET.register_namespace(prefix, uri)

def urlize(s: str) -> str:
    return s.lower().replace(" ", "-")

def link_schemata(path: pathlib.Path) -> None:
    """Link analysis bracket texts to corresponding schemata."""
    schemata = [
        "Do-Re-Mi",
        "Fenaroli",
        "Prinner",
        "Quiescenza",
        "Romanesca",
    ]

    tree = ET.parse(path)
    root = tree.getroot()

    for schema in schemata:
        url = f"../../schemata/{urlize(schema)}/"
        for text in [schema, f"({schema})"]:
            for g in root.findall(f".//tspan[.={text!r}]/../..", NAMESPACES):
                subelements = list(g)
                for subelement in subelements:
                    g.remove(subelement)
                a = ET.SubElement(g, "a", {ET.QName(NAMESPACES["xlink"], "href"): url})
                a.extend(subelements)

    tree.write(path)

def main() -> None:
    path = pathlib.Path(sys.argv[1])

    link_schemata(path)

if __name__ == "__main__":
    main()


from collections import deque

import numpy as np

import torch

import logging
logger = logging.getLogger(__name__)

def cem(agent, params):
    """PyTorch implementation of a cross-entropy method.

    Params
    ======
        agent (object) --- the agent to train
        params (dict) --- a dictionar of parameters
    """
    n_episodes = params.get('episodes', 2000)
    maxlen = params.get('maxlen', 100)
    name = params['name']
    pop_size =  params.get('pop_size', 50)
    elite_frac = params.get('elite_frac', 0.2)
    sigma = params.get('sigma', 0.5)
    n_elite = int(pop_size*elite_frac)
    glie_policy = params.get('policy', None)
    policy = glie_policy(params.get('policy_params', None))  # initialize epsilon-greedy policy

    scores = []                           # list containing scores from each episode
    scores_window = deque(maxlen=maxlen)  # last N scores
    best_weight = sigma * np.random.randn(agent.get_weights_dim())

    for i_episode in range(1, n_episodes+1):
        weights_pop = [best_weight + (sigma * np.random.randn(agent.get_weights_dim())) for i in range(pop_size)]
        rewards = np.array([agent.evaluate(weights, policy) for weights in weights_pop])

        elite_idxs = rewards.argsort()[-n_elite:]
        elite_weights = [weights_pop[i] for i in elite_idxs]
        best_weight = np.array(elite_weights).mean(axis=0)

        reward = agent.evaluate(best_weight, policy)

        scores_window.append(reward)
        scores.append(reward)
        policy.decay()                    # decrease epsilon

        print('\rEpisode {}\tAverage Score: {:.2f}'.format(i_episode, np.mean(scores_window)), end="")
        if i_episode % 100 == 0:
            print('\rEpisode {}\tAverage Score: {:.2f}'.format(i_episode, np.mean(scores_window)))
        if np.mean(scores_window) >= 13.0:
            print('\nEnvironment solved in {:d} episodes!\tAverage Score: {:.2f}'.format(i_episode-100, np.mean(scores_window)))
            torch.save(agent.qnetwork_local.state_dict(), 'results/' + name + '_checkpoint.pth')
    return scores


'''
Problem Statement
Given an array, find the sum of all numbers between the K1’th and K2’th smallest elements of that array.

Example 1:
Input: [1, 3, 12, 5, 15, 11], and K1=3, K2=6
Output: 23

Explanation: The 3rd smallest number is 5 and 6th smallest number 15. The sum of numbers coming
between 5 and 15 is 23 (11+12).

Example 2:
Input: [3, 5, 8, 7], and K1=1, K2=4
Output: 12

Explanation: The sum of the numbers between the 1st smallest number (3) and the 4th smallest
number (8) is 12 (5+7).
'''
import heapq

def find_sum(arr, k1, k2):
    heap = []
    heapq.heapify(heap)
    running_total = 0

    for ele in arr:
        heapq.heappush(heap, ele)

    for i in range(1, len(arr)+1):
        if k1 <= i <= k2:
            running_total += heapq.heappop(heap)
    return running_total


## 다종목 스윙(해당일 종가매수 해당일 종가매도) 백테스팅 템플릿

import create_data_base
import logic
import config

import pandas as pd
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
import win32com
from datetime import datetime
import time
import sqlite3

resultdata = []
flag = 0

class Core():

    ## 파라미터 설정
    def __init__(self, stock_universe, k):

        self.stock_universe = stock_universe ## 종목 바스켓

        self.trade_fee = config.trade_fee  ## 왕복 수수료
        self.trade_tax = config.trade_tax
        self.position_size = config.position_size

    ## 종목별 포지션 설정
    def set_position(self, stock_code):

        stock_data = logic.add_technical_analyze_data(stock_code)
        position_array = logic.set_position(stock_data)

        return position_array

    ## 포지션에 따른 수익률 계산
    def calculate_profit(self, stock_code):

        position_data = self.set_position(stock_code)
        stock_data = logic.add_technical_analyze_data(stock_code)
        profit_array = [1] ## 첫날에는 매수를 하지 않기 때문에 수익률이 0%

        today = 1
        yesterday = 0

        while today < len(position_data):

            ## 매수 포지션
            ## 수익률 = 종가에 매수하였으므로 전일 수익률 * (1 - 증권 거래수수료)
            if position_data[yesterday] == 'Hold' and position_data[today] == 'Buy':
                temp_profit = 1 * (1 - (self.trade_fee/100))
                profit_array.append(temp_profit)

            ## 매수 유지 포지션
            ## 수익률 = 전일 수익률 * 전일 종가 / 금일 종가
            elif position_data[yesterday] == 'Buy' and position_data[today] == 'Buy':
                temp_profit = 1 * (stock_data.at[today, "Close"] / stock_data.at[yesterday, "Close"])
                profit_array.append(temp_profit)

            ## 매도 포지션
            ## 수익률 = 전일 수익률 * 전일 종가 / 금일 종가 * (1 - 증권 거래수수료 - 증권거래세)
            elif position_data[yesterday] == 'Buy' and position_data[today] == 'Hold':
                temp_profit = 1 * (stock_data.at[today, "Close"] / stock_data.at[yesterday, "Close"]) * (1 - (self.trade_fee/100) - (self.trade_tax/100))
                profit_array.append(temp_profit)

            ## 현금 보유 포지션
            else:
                temp_profit = 1
                profit_array.append(temp_profit)

            today += 1
            yesterday += 1

        return profit_array

    ## 각 종목별 수익률 데이터 합성
    def merge_total_trade_data(self):

        ## 총 수익 데이터 저장용 Dataframe 선언
        total_trade_data = pd.DataFrame()

        ## 종목별 수익률 로드후 데이터프레임에 저장
        for i in range(len(self.stock_universe)):
            temp_profit_data = self.calculate_profit(self.stock_universe[i])
            temp_profit_data.reverse()
            total_trade_data.insert(len(total_trade_data.columns), "%s" %self.stock_universe[i], pd.Series(temp_profit_data))
            i += 1

        ## 종목별 수익률의 평균 산출
        total_trade_data = total_trade_data.reindex(index=total_trade_data.index[::-1])
        total_trade_tata = total_trade_data.fillna(1, inplace=True)
        total_trade_data["profit_average"] = total_trade_data.mean(axis=1)

        print(total_trade_data)
        return total_trade_data

    ## 수익률에 따른 잔고 반영
    def calculate_account_data(self):

        ## 기본 잔고 = 1000
        account_data = [1000]
        profit_data = self.merge_total_trade_data()

        ## 기본 잔고 = 1000
        for i in range(len(profit_data.index)):
            temp_account_data = account_data[i] * self.position_size * profit_data.at[i, "profit_average"] + account_data[i] * (1 - self.position_size)
            account_data.append(temp_account_data)
            i += 1

        account_data_dataframe = pd.DataFrame(account_data, columns = ['Basket'])
        account_data_dataframe = pd.concat([account_data_dataframe, profit_data], axis=1)

        temp_date_data = logic.add_technical_analyze_data(self.stock_universe[0])
        account_data_dataframe = pd.concat([account_data_dataframe, temp_date_data['Date']], axis=1)

        print(account_data_dataframe)
        return account_data_dataframe


import pandas as pd
import re
import numpy as np

# функция, которая чистит текст открытого исходного файла
def clean_schedule(line, file_path):
    # создание нового файла
    file = open(file_path, 'w', encoding = "UTF-8")
    line_clean = []
    count = len(line)

    for i in range(count):
        # удаление лишних пробелов между параметрами
        line[i] = re.sub(r'\s+', ' ', line[i])

        # удаление коментарий
        position_comment = line[i].find("-")          # определение начала комментария
        if position_comment != -1:
            line[i] = line[i][:position_comment]      # удаление комментария из строки

        if len(line[i]) > 1:
            if line[i][0] == ' ':
                line[i] = line[i].replace(' ', '', 1) # удаление пробела в начале, если он есть

            if line[i][len(line[i])-1] == ' ':
                line[i] = line[i][:len(line[i])-1]     # удаленеие пробела в конце, если он есть

        # запись в файл
        if line[i].isspace() == False and position_comment != 0:
            file.write(line[i] + '\n')                 # запись без лишних переносов
            line_clean.append(str(line[i]))            # создает список без лишних переносов

    file.close()
    return line_clean

def identification_kyeword(parametrs, keyword, identificator):

    # условия для нахождения ключевого слова
    if parametrs[0] == keyword:
        identificator = 1
    if parametrs[0] == '/':
        identificator = 0

    return identificator

# Функция обнаружения параметров ключевого слова DATA
def parse_keyword_DATE_line(parametrs):
    date = parametrs[0] + ' ' + parametrs[1] + ' ' + parametrs[2]
    return date # запись дат

# Функция обнаружения параметров ключевого слова COMPDAT
def parse_keyword_COMPDAT_line(parametrs):

    parametrs.remove('/')  # удаление лишних символов
    parametrs.insert(1, np.nan)  # добавление пустого параметра
    length = len(parametrs)
    p = 0
    for k in range(length):
        if type(parametrs[k]) == str:
            length_word = len(parametrs[k])
            if parametrs[k][length_word - 1] == '*':
                p = k
                chislo = int(parametrs[k][:(length_word - 1)])
                parametrs.pop(p)
                length -= 1
                for j in range(chislo):
                    parametrs.insert(p, "DEFAULT")
                    length += 1
        compdat_list = parametrs  # запись параметров

    return compdat_list

# Функция обнаружения параметров ключевого слова COMPDATL
def parse_keyword_COMPDATL_line(parametrs):

    parametrs.remove('/')  # удаление лишних символов
    length = len(parametrs)
    p = 0
    for k in range(length):
        if type(parametrs[k]) == str:
            length_word = len(parametrs[k])
            if parametrs[k][length_word - 1] == '*':
                p = k
                chislo = int(parametrs[k][:(length_word - 1)])
                parametrs.pop(p)
                length -= 1
                for j in range(chislo):
                    parametrs.insert(p, "DEFAULT")
                    length += 1
    compdatl_list = parametrs  # запись параметров

    return compdatl_list

def finder_date(parametrs, keyword, identificator, date):
    if identification_kyeword(parametrs, keyword, identificator) == 1 and parametrs[0] != keyword:
        return parse_keyword_DATE_line(parametrs)
    else: return date

def finder_key_word(parametrs, keyword, identificator):
    if identification_kyeword(parametrs, keyword, identificator) == 1 and parametrs[0] != keyword:
        if keyword == 'COMPDAT':
            return parse_keyword_COMPDAT_line(parametrs)
        if keyword == 'COMPDATL':
            return parse_keyword_COMPDATL_line(parametrs)
    return []

# условие для присваивания значений параметров привязанных к датам
def for_date_with_parametrs(data, data_list, compdat_list, compdatl_list, result):
    if data_list != [] and (compdat_list != [] or compdatl_list != []):
        result = [data] + compdat_list + compdatl_list
    return result

# условие для присваивания значений на последнюю дату, в случае если на эту дату не были заданы параметры ранее
def for_last_date_without_parametrs(i, count, data, final_result, data_list, result):
    if data_list != []:
        if i == count - 1 and final_result[len(final_result) - 1][0] != data_list:
            result = [data] + [np.nan]
    return result

# условие для присваивания значений параметров, непривязанных к датам
def for_parametrs_without_date(data_list, compdat_list, compdatl_list, result):
    if data_list == [] and (compdat_list != [] or compdatl_list != []):
        result = [np.nan] + compdat_list + compdatl_list
    return result

# условие для присваивания на тот случай, если на определенную дату нет значений параметров
def for_date_without_parametrs(data_list, final_result):
    if len(data_list) > 1:
        if data_list[len(data_list)-2] != final_result[len(final_result) - 1][0]:
            if ([data_list[len(data_list)-2], np.nan] in final_result) == False:
                final_result.append([data_list[len(data_list)-2], np.nan])
    return final_result

# условие для дополнения списка найденной информацией
def sum_for_date_with_parametrs(result, final_result):
    if result!= [] and (result in final_result) == False :
        final_result.append(result)
    return final_result


# mod1.py

# loop comprehensions
loop = [[(num1, num2) for num2 in range(5)] for num1 in range(5)]
print(type(loop))
print(loop)

loop2 = [i for i in range(0, 50)]
print(loop2)

# loop comprehension with mixed list/tuples
movies = [("Gump", 1941), ("Terry", 2001), ("Wind", 1986), ("Gary", 1976),
          ("Tom", 1934), ("Ads", 2010), ("Grim", 2001), ("Gruff", 2019)]
gmovies = [(title, year) for (title, year) in movies if year < 2002 and title.startswith("G")]
print(gmovies)

# importing & creating modules - also see module.py

odds = [i for i in range(1, 11, 2)]
evens = [i for i in range(2, 11, 2)]
print(odds)
print(evens)
print(module.prodl(odds))
print(module.prodl(evens))
print(module.suml(odds))
print(module.suml(evens))

for path in sys.path:
    print(path)
print(iot.FunI())
print(sig.FunS())

import pygame

run = True
width = 400
height = 100
pygame.init()
screen = pygame.display.set_mode((width, height))
font = pygame.font.SysFont(None, 48)
text = font.render("Welcome to PyGame", True, (255, 255, 255))
screen.blit(text, ((width - text.get_width()) // 2, (height - text.get_height()) // 2))
pygame.display.flip()
while run:
    for event in pygame.event.get():
        if event.type == pygame.QUIT or event.type == pygame.MOUSEBUTTONUP or event.type == pygame.KEYUP:
            run = False

names = ["gary", "john", "terry", "berry", "gerry"]

for index, name in enumerate(names, start=1):
    print(index, name)

names = ["gary", "john", "terry", "berry", "gerry"]
nicks = ["carry", "con", "merry", "ferry", "very"]
list = [num for num in range(5)]

for name, nick, num in zip(names, nicks, list):         # use zip to combine sets of lists.
    print(name, nick, num)                              # stops when shortest list is exhausted


import pprint
import re  # noqa: F401

import six

from asposeslidescloud.models.fill_format import FillFormat

class PictureFill(FillFormat):

    """
    Attributes:
      swagger_types (dict): The key is attribute name
                            and the value is attribute type.
      attribute_map (dict): The key is attribute name
                            and the value is json key in definition.
    """
    swagger_types = {
        'type': 'str',
        'crop_bottom': 'float',
        'crop_left': 'float',
        'crop_right': 'float',
        'crop_top': 'float',
        'dpi': 'int',
        'image': 'ResourceUri',
        'base64_data': 'str',
        'svg_data': 'str',
        'picture_fill_mode': 'str',
        'image_transform_list': 'list[ImageTransformEffect]'
    }

    attribute_map = {
        'type': 'type',
        'crop_bottom': 'cropBottom',
        'crop_left': 'cropLeft',
        'crop_right': 'cropRight',
        'crop_top': 'cropTop',
        'dpi': 'dpi',
        'image': 'image',
        'base64_data': 'base64Data',
        'svg_data': 'svgData',
        'picture_fill_mode': 'pictureFillMode',
        'image_transform_list': 'imageTransformList'
    }

    type_determiners = {
        'type': 'Picture',
    }

    def __init__(self, type='Picture', crop_bottom=None, crop_left=None, crop_right=None, crop_top=None, dpi=None, image=None, base64_data=None, svg_data=None, picture_fill_mode=None, image_transform_list=None):  # noqa: E501
        """PictureFill - a model defined in Swagger"""  # noqa: E501
        super(PictureFill, self).__init__(type)

        self._crop_bottom = None
        self._crop_left = None
        self._crop_right = None
        self._crop_top = None
        self._dpi = None
        self._image = None
        self._base64_data = None
        self._svg_data = None
        self._picture_fill_mode = None
        self._image_transform_list = None
        self.type = 'Picture'

        self.crop_bottom = crop_bottom
        self.crop_left = crop_left
        self.crop_right = crop_right
        self.crop_top = crop_top
        self.dpi = dpi
        if image is not None:
            self.image = image
        if base64_data is not None:
            self.base64_data = base64_data
        if svg_data is not None:
            self.svg_data = svg_data
        self.picture_fill_mode = picture_fill_mode
        if image_transform_list is not None:
            self.image_transform_list = image_transform_list

    @property
    def crop_bottom(self):
        """Gets the crop_bottom of this PictureFill.  # noqa: E501

        Percentage of image height that is cropped from the bottom.  # noqa: E501

        :return: The crop_bottom of this PictureFill.  # noqa: E501
        :rtype: float
        """
        return self._crop_bottom

    @crop_bottom.setter
    def crop_bottom(self, crop_bottom):
        """Sets the crop_bottom of this PictureFill.

        Percentage of image height that is cropped from the bottom.  # noqa: E501

        :param crop_bottom: The crop_bottom of this PictureFill.  # noqa: E501
        :type: float
        """
        self._crop_bottom = crop_bottom

    @property
    def crop_left(self):
        """Gets the crop_left of this PictureFill.  # noqa: E501

        Percentage of image height that is cropped from the left.  # noqa: E501

        :return: The crop_left of this PictureFill.  # noqa: E501
        :rtype: float
        """
        return self._crop_left

    @crop_left.setter
    def crop_left(self, crop_left):
        """Sets the crop_left of this PictureFill.

        Percentage of image height that is cropped from the left.  # noqa: E501

        :param crop_left: The crop_left of this PictureFill.  # noqa: E501
        :type: float
        """
        self._crop_left = crop_left

    @property
    def crop_right(self):
        """Gets the crop_right of this PictureFill.  # noqa: E501

        Percentage of image height that is cropped from the right.  # noqa: E501

        :return: The crop_right of this PictureFill.  # noqa: E501
        :rtype: float
        """
        return self._crop_right

    @crop_right.setter
    def crop_right(self, crop_right):
        """Sets the crop_right of this PictureFill.

        Percentage of image height that is cropped from the right.  # noqa: E501

        :param crop_right: The crop_right of this PictureFill.  # noqa: E501
        :type: float
        """
        self._crop_right = crop_right

    @property
    def crop_top(self):
        """Gets the crop_top of this PictureFill.  # noqa: E501

        Percentage of image height that is cropped from the top.  # noqa: E501

        :return: The crop_top of this PictureFill.  # noqa: E501
        :rtype: float
        """
        return self._crop_top

    @crop_top.setter
    def crop_top(self, crop_top):
        """Sets the crop_top of this PictureFill.

        Percentage of image height that is cropped from the top.  # noqa: E501

        :param crop_top: The crop_top of this PictureFill.  # noqa: E501
        :type: float
        """
        self._crop_top = crop_top

    @property
    def dpi(self):
        """Gets the dpi of this PictureFill.  # noqa: E501

        Picture resolution.  # noqa: E501

        :return: The dpi of this PictureFill.  # noqa: E501
        :rtype: int
        """
        return self._dpi

    @dpi.setter
    def dpi(self, dpi):
        """Sets the dpi of this PictureFill.

        Picture resolution.  # noqa: E501

        :param dpi: The dpi of this PictureFill.  # noqa: E501
        :type: int
        """
        self._dpi = dpi

    @property
    def image(self):
        """Gets the image of this PictureFill.  # noqa: E501

        Internal image link.  # noqa: E501

        :return: The image of this PictureFill.  # noqa: E501
        :rtype: ResourceUri
        """
        return self._image

    @image.setter
    def image(self, image):
        """Sets the image of this PictureFill.

        Internal image link.  # noqa: E501

        :param image: The image of this PictureFill.  # noqa: E501
        :type: ResourceUri
        """
        self._image = image

    @property
    def base64_data(self):
        """Gets the base64_data of this PictureFill.  # noqa: E501

        Base 64 image data.  # noqa: E501

        :return: The base64_data of this PictureFill.  # noqa: E501
        :rtype: str
        """
        return self._base64_data

    @base64_data.setter
    def base64_data(self, base64_data):
        """Sets the base64_data of this PictureFill.

        Base 64 image data.  # noqa: E501

        :param base64_data: The base64_data of this PictureFill.  # noqa: E501
        :type: str
        """
        self._base64_data = base64_data

    @property
    def svg_data(self):
        """Gets the svg_data of this PictureFill.  # noqa: E501

        SVG image data.  # noqa: E501

        :return: The svg_data of this PictureFill.  # noqa: E501
        :rtype: str
        """
        return self._svg_data

    @svg_data.setter
    def svg_data(self, svg_data):
        """Sets the svg_data of this PictureFill.

        SVG image data.  # noqa: E501

        :param svg_data: The svg_data of this PictureFill.  # noqa: E501
        :type: str
        """
        self._svg_data = svg_data

    @property
    def picture_fill_mode(self):
        """Gets the picture_fill_mode of this PictureFill.  # noqa: E501

        Fill mode.  # noqa: E501

        :return: The picture_fill_mode of this PictureFill.  # noqa: E501
        :rtype: str
        """
        return self._picture_fill_mode

    @picture_fill_mode.setter
    def picture_fill_mode(self, picture_fill_mode):
        """Sets the picture_fill_mode of this PictureFill.

        Fill mode.  # noqa: E501

        :param picture_fill_mode: The picture_fill_mode of this PictureFill.  # noqa: E501
        :type: str
        """
        if picture_fill_mode is not None:
            allowed_values = ["Tile", "Stretch"]  # noqa: E501
            if picture_fill_mode.isdigit():
                int_picture_fill_mode = int(picture_fill_mode)
                if int_picture_fill_mode < 0 or int_picture_fill_mode >= len(allowed_values):
                    raise ValueError(
                        "Invalid value for `picture_fill_mode` ({0}), must be one of {1}"  # noqa: E501
                        .format(picture_fill_mode, allowed_values)
                    )
                self._picture_fill_mode = allowed_values[int_picture_fill_mode]
                return
            if picture_fill_mode not in allowed_values:
                raise ValueError(
                    "Invalid value for `picture_fill_mode` ({0}), must be one of {1}"  # noqa: E501
                    .format(picture_fill_mode, allowed_values)
                )
        self._picture_fill_mode = picture_fill_mode

    @property
    def image_transform_list(self):
        """Gets the image_transform_list of this PictureFill.  # noqa: E501

        Image transform effects.  # noqa: E501

        :return: The image_transform_list of this PictureFill.  # noqa: E501
        :rtype: list[ImageTransformEffect]
        """
        return self._image_transform_list

    @image_transform_list.setter
    def image_transform_list(self, image_transform_list):
        """Sets the image_transform_list of this PictureFill.

        Image transform effects.  # noqa: E501

        :param image_transform_list: The image_transform_list of this PictureFill.  # noqa: E501
        :type: list[ImageTransformEffect]
        """
        self._image_transform_list = image_transform_list

    def to_dict(self):
        """Returns the model properties as a dict"""
        result = {}

        for attr, _ in six.iteritems(self.swagger_types):
            value = getattr(self, attr)
            if isinstance(value, list):
                result[attr] = list(map(
                    lambda x: x.to_dict() if hasattr(x, "to_dict") else x,
                    value
                ))
            elif hasattr(value, "to_dict"):
                result[attr] = value.to_dict()
            elif isinstance(value, dict):
                result[attr] = dict(map(
                    lambda item: (item[0], item[1].to_dict())
                    if hasattr(item[1], "to_dict") else item,
                    value.items()
                ))
            else:
                result[attr] = value

        return result

    def to_str(self):
        """Returns the string representation of the model"""
        return pprint.pformat(self.to_dict())

    def __repr__(self):
        """For `print` and `pprint`"""
        return self.to_str()

    def __eq__(self, other):
        """Returns true if both objects are equal"""
        if not isinstance(other, PictureFill):
            return False

        return self.__dict__ == other.__dict__

    def __ne__(self, other):
        """Returns true if both objects are not equal"""
        return not self == other


import typing as t

# TODO: Good idea to maintain a count (length of ll) that gets updated with
#       each operation

class IndexOutOfRangeError(Exception):
    pass

class Node:
    def __init__(self, value: t.Any) -> None:
        self.value = value
        self.next = None

class LinkedList:
    def __init__(
        self,
        elements: t.Optional[t.Sequence[t.Any]] = None,
        key: t.Callable = lambda e: e,
    ) -> None:
        # TODO: Could remember the length and then update it
        self._key = key
        if not elements:
            self.head = None
        else:
            node = Node(elements[0])
            self.head = node
            for element in elements[1:]:
                new_node = Node(element)
                node.next = new_node
                node = new_node

    @property
    def length(self) -> int:
        if not self.head:
            return 0

        length = 0
        node = self.head
        while node:
            length += 1
            node = node.next
        return length

    @property
    def is_sorted(self) -> bool:
        if not self.head:
            return False
        if not self.head.next:
            return True
        node = self.head
        while node.next:
            value_current = node.value
            value_next = node.next.value
            if value_current > value_next:
                return False
            node = node.next
        return True

    def print(self, separator: str = ", ") -> None:
        if self.head:
            values = self._collect_all_values()
            print(separator.join(map(str, values)))

    def extend(self, ll: "LinkedList") -> None:
        if not ll.head:
            return
        if not self.head:
            self.head = ll.head
            return
        node = self.head
        while node.next:
            node = node.next
        node.next = ll.head

    def reverse(self) -> None:
        if not self.head:
            return
        node = self.head.next
        self.head.next = None
        while node:
            next_node = node.next
            node.next = self.head
            self.head = node
            node = next_node

    def get_index_of_value(self, value: t.Any) -> t.Optional[int]:
        if not self.head:
            return None
        node = self.head
        index = 0
        while node:
            if node.value == value:
                return index
            node = node.next
            index += 1

    def get_value_at_index(self, index: int) -> t.Optional[t.Any]:
        if not self.head:
            return None
        if index >= self.length or index < 0:
            raise IndexOutOfRangeError(
                "Wrong index value. Must be [0, len(LL) - 1]"
            )
        node = self.head
        i = 0
        while node:
            if i == index:
                return node.value
            i += 1
            node = node.next

    def prepend(self, value: t.Any) -> None:
        new_node = Node(value)
        if not self.head:
            self.head = new_node
            return
        new_node.next = self.head
        self.head = new_node

    def append(self, value: t.Any) -> None:
        new_node = Node(value)
        if not self.head:
            self.head = new_node
            return
        node = self.head
        while node.next:
            node = node.next
        node.next = new_node

    def insert_value_at(self, value: t.Any, index: int) -> None:
        new_node = Node(value)
        if not self.head:
            self.head = new_node
            return
        if index < 0:
            new_node.next = self.head
            self.head = new_node
            return
        node = self.head
        while node.next and index > 1:
            node = node.next
            index -= 1
        new_node.next = node.next
        node.next = new_node

    def delete_value(self, value: t.Any) -> bool:
        if not self.head:
            return False
        if self.head.value == value:
            if self.head.next:
                self.head = self.head.next
            else:
                self.head = None
            return True
        node = self.head
        while node.next and node.next.value != value:
            node = node.next
        if node.next:
            node.next = node.next.next
            return True
        return False

    def apply_function(self, func: t.Callable) -> None:
        """
        Modify each value of the LL
        :return:
        """
        if not self.head:
            return
        node = self.head
        while node:
            try:
                node.value = func(node.value)
            except Exception as e:
                print(
                    f"Failed while applying callable {func.__name__} to "
                    f"value {node.value}. Error: {e}"
                )
                raise e
            node = node.next

    def _collect_all_values(self) -> t.List[t.Any]:
        if not self.head:
            return []
        node = self.head
        values = []
        while node:
            values.append(node.value)
            node = node.next
        return values

    def insert_value_before(self):
        # TODO: Complete me
        pass

    def insert_value_after(self):
        # TODO: Complete me
        pass

    def insert_sorted_after(self):
        # TODO: Complete me
        pass

    def __len__(self) -> int:
        return self.length

    def __str__(self) -> str:
        if not self.head:
            return ""
        else:
            values = self._collect_all_values()
            return f"LinkedList: {' -> '.join(map(str, values))}"

if __name__ == "__main__":
    items = [4, 5, 1, 2, 7, 3]
    ll = LinkedList(items)

    print("Length:", ll.length, len(ll))

    print("\nPrinting LL:")
    ll.print("; ")
    print(ll)

    print("\nAppending item 100")
    ll.append(100)
    print(ll)

    print("\nPrepending item 228")
    ll.prepend(228)
    print(ll)

    print("\nGetting index of value 100")
    print(ll.get_index_of_value(100))

    print("\nGetting value at index 4")
    print(ll.get_value_at_index(4))

    print("\nInserting new value -10 at index 6")
    ll.insert_value_at(-10, index=6)
    print(ll)
    print("Inserting new values 0 and 1234 at -3 and 100 indices")
    ll.insert_value_at(0, index=-3)
    ll.insert_value_at(1234, index=100)
    print(ll)

    print("\nDeleting value -10", ll.delete_value(-10))
    print(ll)
    print("Deleting value 1234", ll.delete_value(1234))
    print(ll)
    print("Deleting value -1234", ll.delete_value(-1234))
    print(ll)

    print("\nApplying function x * 2 to all nodes")
    ll.apply_function(lambda e: e * 2)
    print(ll)

    print("\nIs LL sorted?", ll.is_sorted)
    new_ll = LinkedList([1, 2, 3, 4, 5])
    print(f"Is this LL: {new_ll} sorted? {new_ll.is_sorted}")

    print("\nReversing LL")
    ll.reverse()
    print(ll)


from sys import stdin

N, M = map(int, stdin.readline().rstrip().split())
li_arr = [0] * (N+1)
bool_isused = [0] * (N+1)

def test(k):
    if k == M:
        for i in range(1, M+1):
            print(li_arr[i], end=' ')
        print('\n', end='')
        return 0
    for j in range(1, N+1):
            li_arr[k+1] = j
            test(k+1)

if __name__ == '__main__':
    test(0)


import sys
import math
import string

sList = ['LOUISI', 'LOUISII', 'LOUISIII', 'LOUISIV', 'LOUISV', 'LOUISVI', 'LOUISVII', 'LOUISVIII', 'LOUISIX', 'LOUISX', 'LOUISXI', 'LOUISXII', 'LOUISXIII', 'LOUISXIV', 'LOUISXV', 'LOUISXVI']
n=16

sList = ['ONE', 'TWO', 'THREE', 'FOUR', 'FIVE', 'SIX', 'SEVEN', 'EIGHT', 'NINE', 'TEN']
n=10

sList = ['ABCHZ', 'ABDAA']
n = 2

sList = ['A', 'AA']
n = 2

sList = ['JAMES', 'JENNIFER', 'JESS', 'JESSICA', 'JOHN', 'JOSEPH']
n=6

sList = ['MN', 'MO']
n = 2

#print(string.ascii_uppercase)
sortList = sorted(sList)
one = sortList[int(n/2 -1)]
two = sortList[int(n/2)]
print(one)
print(two)

erg = ""
anzahl = 0
gleich = True
for i in range(len(one)):
    anzahl = i
    if not one[i] == two[i]:
        gleich = False
        break

if len(one) == 1 or gleich or anzahl == len(one) -1:
    erg = one
else:
    nr = string.ascii_uppercase.index(one[anzahl])
    erg = one[:anzahl] + string.ascii_uppercase[nr +1]
    if erg == two:
        erg = one

print(erg)


"""
Given the head of a singly linked list, reverse the list, and return the reversed list.

Example 1:
Input: head = [1,2,3,4,5]
Output: [5,4,3,2,1]
Example 2:
Input: head = [1,2]
Output: [2,1]
Example 3:
Input: head = []
Output: []
"""
class Solution(object):

    def reverseList(self, head):
        """
        :type head: ListNode
        :rtype: ListNode
        """
        if head == None or head.next == None:
            return head
        n = head.next
        h = self.reverseList(n)
        head.next = None
        n.next = head
        return h