'''
It reads lib data from the DB and then calls the breaking changes java code
from Laerte Xavier to calculate breaking changes between each pair of releases

The number of breaking changes and non-breaking changes are directly saved in the DB
'''
import json

from librarycomparison.models import Library
from git import Repo
import os
import shutil
import subprocess
import glob

repos_dir = "scripts/BreakingChanges/Repositories"

def clone_release(library, release):

    repo_dir = repos_dir + "/" + library.name + "-" + release.name

    if not os.path.isdir(repo_dir):
        Repo.clone_from(library.github_url, repo_dir, branch=release.name)

    return repo_dir

def count_breaking_changes(library):

    releases = list(library.releases.all().order_by('release_date'))

    for index in range(len(releases)):
        if index == 0:
            continue

        curr_release = releases[index]
        prev_release = releases[index - 1]

        if curr_release.breaking_changes != -1: #i.e., already calculated this release before
            print("Skipping release ", curr_release.name)
            continue

        print("Calculating for ", curr_release.name)

        try:
            curr_release_dir = clone_release(library, curr_release)
            prev_release_dir = clone_release(library, prev_release)

            breaking_chg_output = subprocess.check_output(["java", "-Xmx20g", "-Xms18g", "-jar", "scripts/BreakingChanges/BreakingChangesJava.jar", prev_release_dir, curr_release_dir])
        except subprocess.CalledProcessError as error:
            print("Skipping release", str(curr_release))
            print (error.output)
            continue
        except:
            print("Something went wrong while cloning. Skipping release", str(curr_release))
            continue

        changes = breaking_chg_output.decode().split(",")
        curr_release.breaking_changes = int(changes[0])
        curr_release.non_breaking_changes  = int(changes[1])
        curr_release.save()

        shutil.rmtree(prev_release_dir)

    dir_pattern = repos_dir + "/" + library.name + "-*"
    for dir_name in glob.glob(dir_pattern):
       shutil.rmtree(dir_name)

def get_breaking_changes():

    if not os.path.isdir("scripts/BreakingChanges/"):
        print ("No breaking changes scripts found... skipping backwards compatibility")
        return

    try:
        os.remove("scripts/BreakingChanges/breakingchanges.csv")
    except FileNotFoundError:
        pass

    libraries = Library.objects.all()

    try:
        os.mkdir(repos_dir)
    except FileExistsError:
        pass #ignore if dir exists

    count = 0
    for library in libraries:
        lib_name = library.name
        print ("Getting breaking changes for ", lib_name)
        lib_name = library.name
        # repo = github.get_repo(library.github_repo)

        target_loc = repos_dir + "/" + lib_name

        if not os.path.isdir(target_loc):
            Repo.clone_from(library.github_url, target_loc)

        print ("Cloned repo")
        count_breaking_changes(library)

if __name__ == "__main__":
    get_breaking_changes()


#!/usr/local/bin/python3

# coding=utf-8
"""
fortunes
"""

from __future__ import division, print_function, absolute_import, unicode_literals
from future import standard_library
import os
import sys
import pickle
import random
import portalocker
import time
from argparse import ArgumentParser
from clint.textui.progress import mill
__all__ = ['main', 'get_random_fortune', 'make_fortune_data_file']
__url__ = 'http://software.clapper.org/fortune/'
__copyright__ = '2008-2011 Brian M. Clapper'
__author__ = 'Brian M. Clapper'
__email__ = 'bmc@clapper.org'
_PICKLE_PROTOCOL = 2

__version__ = '1.0'

def _read_fortunes(fortune_file):
    """ Yield fortunes as lists of lines """
    result = []
    start = None
    pos = 0

    for line in fortune_file:
        if line == "%\n":
            if pos != 0:  # "%" at top of file. Skip it.
                yield (start, pos - start, result)
                result = []
                start = None
        else:
            if start is None:
                start = pos

            result.append(line)

        pos += len(line)

    if result:
        yield (start, pos - start, result)

def get_random_fortune(fortune_file):
    """
    @type fortune_file: str, unicode
    @return: None
    """

    with portalocker.Lock(os.path.expanduser('~/.random_fortune_lock_file'), timeout=15, fail_when_locked=False) as fh:
        fortune_index_file = fortune_file + '.dat'

        if not os.path.exists(fortune_index_file):
            raise ValueError('Can\'t find file "%s"' % fortune_index_file)

        fortune_index = open(fortune_index_file, "rb")
        data = pickle.load(fortune_index)
        fortune_index.close()
        fortune_cookie = None

        for i in range(0, 5):
            try:
                random_record = random_int(0, len(data) - 1)
                (start, length) = data[random_record]
                f = open(fortune_file, 'rt')
                f.seek(start)
                fortune_cookie = f.read(length)
                f.close()
                break
            except UnicodeDecodeError as ude:
                if i > 3:
                    print(i, ude)

        if fortune_cookie is None:
            return

        spaces = "   "
        content = fortune_cookie.strip().replace("\t", spaces)
        cnt = 0
        nc = spaces

        for c in content:
            nc += c
            cnt += 1

            if cnt > 80 and c == " ":
                nc += "\n" + spaces
                cnt = 0

        nc = nc.replace("\n" + spaces + "\n" + spaces + "--", "\n" + spaces + "--")

        if len(nc.split("--")) > 1:
            nc = spaces + nc.split("--")[0].strip() + "\n" + spaces + "-- " + nc.split("--")[1].replace("\n", "").replace(spaces, " ")

        for i in range(2, 6):
            sp = i * " "
            nc = nc.replace(sp, " ")

        ncs = nc.split("--")
        quote = nc
        author = ""

        if len(ncs) > 1:
            quote = ncs[0]
            author = "--" + ncs[1]

        return quote, author

def make_fortune_data_file(fortune_file, quiet=False):
    """
    @type fortune_file: str, unicode
    @type quiet: bool
    @return: None
    """
    fortune_index_file = fortune_file + '.dat'

    if not quiet:
        print('Updating "%s" from "%s"...' % (fortune_index_file, fortune_file))

    data = []
    shortest = sys.maxsize
    longest = 0

    for start, length, fortune in _read_fortunes(open(fortune_file, 'rt')):
        data += [(start, length)]
        shortest = min(shortest, length)
        longest = max(longest, length)

    fortune_index = open(fortune_index_file, 'wb')
    pickle.dump(data, fortune_index, _PICKLE_PROTOCOL)
    fortune_index.close()

    if not quiet:
        print('Processed %d fortunes.\nLongest: %d\nShortest %d' %
              (len(data), longest, shortest))

def random_int(start, end):
    """
    @type start: str, unicode
    @type end: str, unicode
    @return: None
    """
    return random.randint(start, end)

def search_fortune(searchquery, fortunefilep=None):
    """
    @type searchquery: str
    @type fortunefilep: str, None
    @return: None
    """
    results = {}

    for fortune_file in mill(os.listdir("."), label="- Searching quote files", every=4):
        if fortunefilep is not None:
            fortune_file = os.path.basename(fortunefilep) + ".dat"

        if fortune_file.endswith(".dat"):
            fortune_index_file = "./" + fortune_file

            if not os.path.exists(fortune_index_file):
                raise ValueError('Can\'t find file "%s"' % fortune_index_file)

            fortune_index = open(fortune_index_file, "rb")
            data = pickle.load(fortune_index)
            fortune_index.close()
            fortune_file = "./" + fortune_file
            f = open(fortune_file.replace(".dat", ""), 'rt')
            qwords = searchquery.split(" ")
            qwords = [w.lower() for w in qwords if w]
            for cnt in range(0, len(data) - 1):
                (start, length) = data[cnt]
                f.seek(start)
                fortune_cookie = f.read(length)
                spaces = "   "
                content = fortune_cookie.strip().replace("\t", spaces)
                cnt = 0
                nc = spaces

                for c in content:
                    nc += c
                    cnt += 1

                    if cnt > 80 and c == " ":
                        nc += "\n" + spaces
                        cnt = 0

                nc = nc.replace("\n" + spaces + "\n" + spaces + "--", "\n" + spaces + "--")

                if len(nc.split("--")) > 1:
                    nc = spaces + nc.split("--")[0].strip() + "\n" + spaces + "-- " + nc.split("--")[1].replace("\n", "").replace(spaces, " ")

                for i in range(2, 6):
                    sp = i * " "
                    nc = nc.replace(sp, " ")

                ncs = nc.split("--")
                quote = nc
                author = ""

                if len(ncs) > 1:
                    quote = ncs[0]
                    author = "--" + ncs[1]

                score = 0
                quotesplit = [x for x in quote.lower().split(" ") if x]
                for word in qwords:
                    if word in quotesplit:
                        score += 1

                for word in qwords:
                    if word in author.lower():
                        if score not in results:
                            results[score] = []

                        results[score].append((100, fortune_file.replace(".dat", ""), quote, author))
                    elif score > 0:
                        if score == len(quotesplit):
                            if score not in results:
                                results[score] = []

                            results[score].append((score, fortune_file.replace(".dat", ""), quote, author))

            f.close()

        if fortunefilep is not None:
            return results

    return results

def main():
    """
    Main program.
    """

    arg_parser = ArgumentParser()
    arg_parser.add_argument('-q', '--quiet', action='store_true', dest='quiet',
                            help="When updating the index file, don't emit "
                                 "messages.")

    arg_parser.add_argument('-u', '--update', action='store_true', dest='update',
                            help='Update the index file, instead of printing a '
                                 'fortune.')

    arg_parser.add_argument('-d', '--fortunefolder', dest='fortunefolder', help='Fortune basedir to use.')
    arg_parser.add_argument('-f', '--fortunefile', dest='fortunefile', help='Fortune file to use.')
    arg_parser.add_argument('-r', '--random', dest='random', help='Use random fortune file to use.', action="store_true")
    arg_parser.add_argument('-l', '--length', dest='length', help='Max length.', action="store")
    arg_parser.add_argument('-s', '--search', dest='search', help='Search a quote.', action="store")
    arg_parser.add_argument('-c', '--clean', dest='clean', help='No color', action="store_true")
    args = arg_parser.parse_args(sys.argv[1:])

    lf = []
    length = None

    try:
        if args.length is not None:
            length = int(args.length)
    except ValueError:
        pass

    if args.fortunefolder is None:
        print('no fortunefolder given')
        return

    os.chdir(os.path.expanduser(args.fortunefolder))

    if args.random is True:
        for fn in os.listdir(os.path.expanduser(args.fortunefolder)):
            if fn.endswith(".dat"):
                lf.append(fn.replace(".dat", ""))

    if len(lf) > 0:
        # lf = ['age', 'alone', 'amazing', 'anger', 'anniversary', 'architecture', 'art', 'attitude', 'beauty', 'best', 'birthday', 'brainy', 'business', 'car', 'change', 'christmas', 'communication', 'computers', 'cool', 'courage', 'dad', 'dating', 'death', 'design', 'diet', 'dreams', 'easter', 'education', 'environmental', 'equality', 'experience', 'failure', 'faith', 'family', 'famous', 'fathersday', 'fear', 'finance', 'fitness', 'food', 'forgiveness', 'freedom', 'friendship', 'funny',
        # 'future', 'gardening', 'god', 'good', 'government', 'graduation', 'great', 'happiness', 'health', 'history', 'home', 'hope', 'humor', 'imagination', 'inspirational', 'intelligence', 'jealousy', 'knowledge', 'law', 'leadership', 'learning', 'legal', 'life', 'love', 'marriage', 'medical', 'memorialday', 'men', 'mom', 'money', 'morning', 'mothersday', 'motivational', 'movies', 'movingon', 'music', 'nature', 'newyears', 'parenting', 'patience', 'patriotism', 'peace', 'pet', 'poetry',
        # 'politics', 'positive', 'power', 'relationship', 'religion', 'respect', 'romantic', 'sad', 'saintpatricksday', 'science', 'smile', 'society', 'sports', 'strength', 'success', 'sympathy', 'teacher', 'technology', 'teen', 'thankful', 'thanksgiving', 'time', 'travel', 'trust', 'truth', 'valentinesday', 'veteransday', 'war', 'wedding', 'wisdom', 'women', 'work']
        #lf = ["future", "god", "money", "freedom", "health", "women", "friendship", "respect", "business", "success", "technology", "history", "humor"]
        lf = list(set([x.replace(".dat", "") for x in os.listdir(args.fortunefolder) if x.endswith(".dat")]))

        fortune_file = lf[random.randint(0, len(lf) - 1)]
    else:
        fortune_file = args.fortunefile

    random.seed()
    time.sleep(random.random())

    fortune_title = ""
    if fortune_file is not None or args.search:
        if fortune_file:
            fortune_title = fortune_file.capitalize()
            fortune_file = os.path.join(args.fortunefolder, fortune_file)

        quote = None
        author = ""

        if args.search is not None:
            if length is None:
                length = -1

            results = search_fortune(args.search, fortune_file)

            for index in results:
                for score, fortune_file, quote, author in results[index]:
                    if score > len(args.search.split(" ")) / 3:
                        quotelen = len(quote)
                        if quotelen < length or length == -1:
                            print("\033[34m" + fortune_file.replace("./quotes/", "").capitalize() + " (" + str(score) + "):\033[0m\n\033[33m" + quote + "\033[91m" + author, "\033[0m\n")

        elif args.update:
            make_fortune_data_file(fortune_file)
        else:
            if length is None:
                quote, author = get_random_fortune(fortune_file)
            else:
                quotelen = -1

                trycnt = 0
                while (quotelen > length) or (quotelen < 0):
                    prevq = quote
                    quote, author = get_random_fortune(fortune_file)
                    quotelen = len(quote)

                    if prevq and (quotelen > len(prevq)):
                        quote = prevq
                    trycnt += 1
                    if trycnt > 10:
                        break
            if quote is None:
                print("Error: no quote found.!")
            else:
                if args.clean:
                    for _ in range(0, 10):
                        #quote = quote.replace("\n", "")
                        quote = quote.replace("  ", " ")
                    quote = quote.replace("'", "")
                    print(author.replace("--", "").strip().replace("'", "\'") + ": " + quote.strip())
                else:
                    #print("\033[34m" + fortune_title + ":\033[0m\n\033[33m" + quote + "\033[91m" + author, "\033[0m")
                    print("\033[33m" + quote.strip() + "\033[91m\n\n" + author.strip("--").strip(), "\033[0m")
    else:
        print('no file given')

standard_library.install_aliases()

if __name__ == '__main__':
    main()


from sqlalchemy import select, delete
from sqlalchemy.orm import sessionmaker

from funpay_undercutter.models import engine, Game, Server, Offer

Session = sessionmaker(engine, future=True)
sess = Session()

def check_records_filled(table: str, related: tuple = None, session: Session = sess) -> bool:
    allowed = ('game', 'server', 'offer')
    if table.lower() not in allowed:
        raise ValueError('Table', table, 'not exist')
    stmt = f'select * from {table} where {related[0]}={related[1]}' if related else f'select * from {table}'
    result = session.execute(stmt).first()
    return bool(result)

def write_bulk(type_, list_: list[dict], session: Session = sess) -> None:
    if type_ == 'game':
        objects = [Game(**el) for el in list_]
    elif type_ == 'server':
        objects = [Server(**el) for el in list_]
    elif type_ == 'offer':
        objects = [Offer(**el) for el in list_]
    else:
        raise ValueError
    session.bulk_save_objects(objects)
    session.commit()

def get_game_by_name(name: str, session: Session = sess) -> Game:
    stmt = select(Game).where(Game.name == name)
    return session.execute(stmt).scalar()

def get_server_by_name(name: str, game_id: int, session: Session = sess) -> Server:
    stmt = select(Server).filter_by(name=name, game_id=game_id)
    return session.execute(stmt).scalar()

def get_offers_by_server(server_id: int, session: Session = sess) -> list[Offer]:
    stmt = select(Offer).filter_by(server_id=server_id)
    return session.execute(stmt).scalars().all()

def get_offers_for(user_name: str, game_id: int = None, session: Session = sess) -> list[Offer]:
    if game_id:
        stmt = select(Offer).filter_by(game_id=game_id, seller_name=user_name)
    else:
        stmt = select(Offer).filter_by(seller_name=user_name)
    return session.execute(stmt).scalars().all()

def drop_old_offers_for(game_id: int, session: Session = sess) -> None:
    stmt = delete(Offer).where(Offer.game_id == game_id)
    session.execute(stmt)
    session.commit()

def get_best_offers_for(server_id: int, side_id: int, n: int = 5, session: Session = sess) -> list[Offer]:
    stmt = select(Offer).filter_by(server_id=server_id, side_id=side_id, online=1).order_by(Offer.price).limit(n)
    return session.execute(stmt).scalars().all()

def get_n_lowest_price_for(server_id: int, side_id: int, n: int = 5, session: Session = sess) -> list[int]:
    stmt = select(Offer.price).filter_by(server_id=server_id, side_id=side_id, online=1).order_by(Offer.price).limit(n)
    return session.execute(stmt).scalars().all()


from flask import Flask, render_template, flash, request
from wtforms import Form, TextField, TextAreaField, validators, StringField, SubmitField

# App config.
app = Flask(__name__)
app.config['SECRET_KEY'] = 'asdfasdfasdfasdfas'

class NameForm(Form):
   name = StringField('What is your name?')
   submit = SubmitField('Submit')

   @app.route('/', methods=['GET', 'POST'])
   def index():
      name = None
      form = NameForm()
      if form.validate_on_submit():
         name = form.name.data
         form.name.data = ''
      return render_template('index.html', form=form, name=name)

if __name__ == "__main__":
    app.run()


# from random import randint
# def f ():
#     result = {}
#     for i in range(5):
#         dict1 = {randint(1,20):'none'}
#         result.update(dict1)
#     return(result)

# print(f())

dict1 = {
  "1": [
    "Inan",
    "789",
    "castomer"
  ],
  "2": [
    "Sergey",
    "654",
    "povar"
  ]
}

print(dict1["1"][0])

def empl_data(): # сотрудники(id сотрудника, имя сотрудника, личный телефон сотрудника)
    name_empl = input('ВВедите имя сотрудника-> ')
    telephone_empl = input('введите номер телефона сотрудника-> ')
    post = input('ВВедите должность сотрудника-> ')
    data = [name_empl, telephone_empl, post]
    return data

# res = empl_data()

di1 = {}
def new_dict(di1, data):
    if len(di1) == 0:
        id = 1
    else:
        id = max(di1.keys()) + 1
    di1[id] = data

def save_data_js(directory):
    with open ('book.json', 'a', encoding='utf-8') as file:
        file.write(json.dumps(directory,ensure_ascii=False))

new_dict(di1, empl_data)
new_dict(di1, empl_data)
save_data_js(di1)

#__________________________________________
# Создать информационную систему позволяющую работать
# с сотрудниками некой компании
# структура: создать несколько таблиц для выгрузки каждой
# в отдельный файл json: ключ будет id сотрудника;
# 1. id - фио, телефон
# 2. id - отделы в компании
# 3. id - должности
# 4. id - какой сотрудник на какой должности работает
# !!!! определить в каком отделе работает сотрудник!!!!

import json

def empl_data(): # сотрудники(id сотрудника, имя сотрудника, личный телефон сотрудника)
    id = input ('введите id сотрудника -> ')
    name_empl = input('ВВедите имя сотрудника-> ')
    telephone_empl = input('введите номер телефона сотрудника-> ')
    post = input('ВВедите должность сотрудника-> ')
    data = [name_empl, telephone_empl, post]
    name_id = {}
    name_id[id] = data
    return name_id

res = empl_data()

# def department_data(): # отделы (id отдела, название отдела, должности отдела, телефон отдела)
#     id = input ('введите id отдела ->')
#     name_department = input('ВВедите название отдела-> ')
#     post_dapertment = input('введите должности отдеда -> ')
#     telephone_department = input('введите номер телефона отдела-> ')
#     data = [name_department, telephone_department]
#     name_id = {}
#     name_id[id] = data
#     return name_id

# def post_data(): # должность сотрудника (id сотрудника, должность сотрудника)
    # id = input ('введите id сотрудника -> ')
    # post = input('ВВедите должность сотрудника-> ')
    # data = [post]
    # post_id = {}
    # post_id[id] = data
    # return post_id

# def unification_data (di1, di2): #сложение словарей по ключам (при их совпадении)
#     di3 = di1
#     for key, value in di2.items():
#         if key in di1:
#             di3[key] += value
#         else:
#             # di3.update({key: value})
#             print('вы ввели неверный id сотрудника')
#     return di3

# res = unification_data(empl_data(), post_data())
# print(res)

# ________________JSON____________________
def save_data_js():
    with open ('book.json', 'a', encoding='utf-8') as empl_book:
        json.dump(res, empl_book, indent = 2, ensure_ascii=False)
        print('данные успешно сохранены')

def load_data_js():
     with open ('book.json', 'r', encoding='utf-8') as empl_book:
        book_data = json.load(empl_book)
        print (book_data)

# save_data_js()
# load_data_js()

# ________________TXT____________________
# def convert_data_txt():
#     vvod()
#     data = (telephone, comment)
#     book = {}
#     book[name] = data
#     return str(book)

# def save_data_txt():
#     with open ('book.txt', 'a', encoding='utf-8') as empl_book:
#         empl_book.write(f'{str(res)}\n')

# def load_data_txt():
#      with open ('book.txt', 'r', encoding='utf-8') as empl_book:
#         book_data = empl_book.read()
#         return(book_data)

# save_data_txt()
# print(load_data_txt())


import re
import os
import requests
from typing import Tuple
from bs4 import BeautifulSoup

from .section_scraper import SectionScraper

def get_secondary_quest_list(page_url: str) -> Tuple:
    base_url = os.path.dirname(os.path.dirname(page_url))
    soup = BeautifulSoup(requests.get(page_url).content, "html.parser")
    table_tags = soup.find_all("table")
    quest_names, quest_urls, is_unmarked, cutoff_point, levels, locations, enemies = (
        [],
        [],
        [],
        [],
        [],
        [],
        [],
    )
    for table_tag in table_tags:
        table_rows = table_tag.find_all("tr")[1:]
        table_rows = [row.find_all("td") for row in table_rows]
        for row in table_rows:
            quest_names.append(row[0].text.strip())
            quest_urls.append(base_url + row[0].find_all("a", href=True)[0]["href"])
            is_unmarked.append("Yes" in row[1].text.strip())
            cutoff_point.append(row[2].text.strip())
            levels.append(row[3].text.strip())
            locations.append(re.sub(r"(\w)([A-Z])", r"\1\n\2", row[4].text).strip().split("\n"))
            enemies.append(re.sub(r"(\w)([A-Z])", r"\1\n\2", row[4].text).strip().split("\n"))
            # locations.append(re.split(r"(\w)([A-Z])", row[4].text.strip()))
            # enemies.append(re.split(r"(\w)([A-Z])", row[5].text.strip()))
    return (
        quest_names,
        quest_urls,
        is_unmarked,
        cutoff_point,
        levels,
        locations,
        enemies,
    )


# IMPORT MODULES
import cv2
from tkinter import *
from tkinter.filedialog import askopenfilename

# VERSION, VARIABLES
ver = 0.3

# FUNCTIONS
def ResizeWithAspectRatio(image, width=None, height=None, inter=cv2.INTER_AREA):
    dim = None
    (h, w) = image.shape[:2]

    if width is None and height is None:
        return image
    if width is None:
        r = height / float(h)
        dim = (int(w * r), height)
    else:
        r = width / float(w)
        dim = (width, int(h * r))

    return cv2.resize(image, dim, interpolation=inter)

def importImage():
    # Load the cascade
    face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
    # Read the input image
    Tk().withdraw() # we don't want a full GUI, so keep the root window from appearing
    img = cv2.imread(askopenfilename())
    # Convert into grayscale
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    faces = face_cascade.detectMultiScale(gray, 1.1, 4)
    for (x, y, w, h) in faces:
        cv2.rectangle(img, (x, y), (x+w, y+h), (255, 0, 0), 2)
    # Display the output
    root.quit
    cv2.imshow('img', ResizeWithAspectRatio(img, height=1000))
    cv2.waitKey(0)

def donothing():
   filewin = Toplevel(root)
   button = Button(filewin, text="Do nothing button")
   button.pack()

def about():
    filewin = Toplevel(root)
    button = Button(filewin, text=f"Készítette: Chen Kevin\nVerzió: {ver}")
    button.pack()

# CREATE WINDOW
root = Tk()
menubar = Menu(root)

# CREATE MENUPOINTS, MENU, FILE
filemenu = Menu(menubar, tearoff=0)
filemenu.add_command(label="Open", command=importImage)

# MENU, HELP
filemenu.add_command(label="Exit", command=root.quit)
menubar.add_cascade(label="File", menu=filemenu)
helpmenu = Menu(menubar, tearoff=0)
helpmenu.add_command(label="About...", command=about)
menubar.add_cascade(label="Help", menu=helpmenu)

# FRAME ELEMENTS
frame = Label(
    root,
    text="Arc felismerő",
    font=(48)
    ).grid(
        row=0,
        column=0,
        pady=(100,10),
        padx=(140,100)
        )
Button(
    frame,
    text='Importálás',
    command=importImage
    ).grid(row=1,column=0)

# CONFIG, MAINLOOP
root.title('Program')
root.geometry('400x300')
root.resizable(False, False)
root.config(menu=menubar)
root.mainloop()


"""Inlining Training config."""

import tensorflow as tf

POLICY_DECISION_LABEL = 'inlining_decision'
POLICY_OUTPUT_SPEC = """
[
    {
        "logging_name": "inlining_decision",
        "tensor_spec": {
            "name": "StatefulPartitionedCall",
            "port": 0,
            "type": "int64_t",
            "shape": [
                1
            ]
        }
    }
]
"""

# pylint: disable=g-complex-comprehension
def get_input_signature():
  """Returns the list of features for LLVM inlining."""
  # int64 features
  inputs = [
      tf.TensorSpec(dtype=tf.int64, shape=(), name=key) for key in [
          'caller_basic_block_count',
          'caller_conditionally_executed_blocks',
          'caller_users',
          'callee_basic_block_count',
          'callee_conditionally_executed_blocks',
          'callee_users',
          'nr_ctant_params',
          'node_count',
          'edge_count',
          'callsite_height',
          'cost_estimate',
          'inlining_default',
          'sroa_savings',
          'sroa_losses',
          'load_elimination',
          'call_penalty',
          'call_argument_setup',
          'load_relative_intrinsic',
          'lowered_call_arg_setup',
          'indirect_call_penalty',
          'jump_table_penalty',
          'case_cluster_penalty',
          'switch_penalty',
          'unsimplified_common_instructions',
          'num_loops',
          'dead_blocks',
          'simplified_instructions',
          'constant_args',
          'constant_offset_ptr_args',
          'callsite_cost',
          'cold_cc_penalty',
          'last_call_to_static_bonus',
          'is_multiple_blocks',
          'nested_inlines',
          'nested_inline_cost_estimate',
          'threshold',
      ]
  ]

  # float32 features
  inputs.extend([
      tf.TensorSpec(dtype=tf.float32, shape=(), name=key)
      for key in ['discount', 'reward']
  ])

  # int32 features
  inputs.extend([
      tf.TensorSpec(dtype=tf.int32, shape=(), name=key)
      for key in ['step_type']
  ])
  return inputs

def get_output_signature():
  return POLICY_DECISION_LABEL

def get_output_spec():
  return POLICY_OUTPUT_SPEC


#!/usr/bin/env python3
"""Extract and rename iPod audio data to local drive"""

import sys
import argparse
import os
import logging
from pathlib import Path
from tinytag import TinyTag
from tqdm import tqdm

LOG = "./ipx.log"
home = os.path.expanduser("~")
extensions = [".mp3", ".m4a", ".mp4", ".m4b", ".aac", ".aiff"]
various = ["VA", "Various", "Various Artists"]

logging.basicConfig(
    filename=LOG,
    level=logging.DEBUG,
    format="%(asctime)s %(message)s",
    datefmt="%d/%m/%Y %H:%M:%S",
)

def parse_args(args):
    """Define and parse args"""
    parser = argparse.ArgumentParser(
        description="Extract and rename iPod audio data to local drive"
    )
    parser.add_argument("-i", type=str, required=True, help="path to mounted iPod")
    parser.add_argument(
        "-o",
        type=str,
        help="path to local directory for extraction (default: ~/iPod/Music)",
    )
    return parser.parse_args()

def cleanse(val):
    """Sanitize tag strings for dir/filenames"""
    illegal_chars = ['/','\\','<','>','*','?','|',':']
    for char in illegal_chars:
        if char in '/' ':':
            val = val.replace(char,"-")
        else:
            val = val.replace(char,"")
    return val

def pad_zeroes(track):
    """Pad zeros on track numbers < 10"""
    if track[0].isdigit() and track[0] != "0":
        if int(track) in range(0, 10):
            padded = f"0{track}"
            return padded
    return track

def iter_files(ipod_path):
    """Walk iPod dir path and pass files to parser"""
    for root, dirs, files in os.walk(ipod_path, topdown=False):
        for filename in tqdm(
            files, colour="green", desc=f"{os.path.basename(root)}..."
        ):
            if filename.endswith(tuple(extensions)) and not filename.startswith("._"):
                audio_file = os.path.join(root, filename)
                ext = Path(audio_file).suffix
                try:
                    tags = TinyTag.get(f"{audio_file}")
                    extract_file(audio_file, tags, ext)
                except Exception as error:
                    msg = f"Parsing `{audio_file}` failed: {error}"
                    unparsed_dump = (
                        f"{str(args.o)}/Unknown_Tags/"
                        if args.o
                        else f"{home}/iPod/Unknown_Tags/"
                    )
                    os.system(f"cp {audio_file} {unparsed_dump}")
                    tqdm.write(msg)

def extract_file(file, tags, ext):
    """Make directory for audio files, copy files into proper dirs, rename files"""
    artist = "Various" if tags.albumartist in various else cleanse(tags.artist)
    album = cleanse(tags.album)
    album_path = (
        f"{str(args.o)}/{artist}/{album}/"
        if args.o
        else f"{home}/iPod/Music/{artist}/{album}/"
    )
    new_filename = f"{pad_zeroes(tags.track)} - {cleanse(tags.artist)} - {cleanse(tags.title)}{ext}"
    try:
        os.makedirs(f"{album_path}", exist_ok=True)
        os.system(f'cp "{file}" "{album_path}"')
        os.system(
            f'mv "{album_path}/{os.path.split(file)[1]}" "{album_path}/{new_filename}"'
        )
        msg = f"Copied {file} to {album_path}{new_filename}"
        tqdm.write(msg)
        logging.info(msg)
    except Exception as error:
        msg = f"Copy {file} failed: {error}"
        tqdm.write(msg)
        logging.info(msg)

if __name__ == "__main__":

    args = parse_args(sys.argv[1:])
    ipod_path = args.i
    logging.info(f"[START] Script traversing {ipod_path}...")
    iter_files(ipod_path)
    logging.info(f"[FINISH] Run complete.\n")


import matplotlib.pyplot as plt
import seaborn as sb
import describe

houses={
	"Ravenclaw": 1,
	"Slytherin": 2,
	"Gryffindor": 3,
	"Hufflepuff": 4
}

houses_rev = {value: key for key, value in houses.items()}

if __name__ == "__main__":
	data = describe.get_data()
	data["Hogwarts House"].replace(houses, inplace=True)
	data = data.select_dtypes('number')
	data["Hogwarts House"].replace(houses_rev, inplace=True)
	data.drop('Index', axis=1, inplace=True)
	sb.pairplot(data, hue='Hogwarts House', markers='.')
	plt.show()


class Solution:
    def minDeletionSize(self, strs: List[str]) -> int:
        n = len(strs)
        COLS = len(strs[0])

        deletion = 0
        relation = [-1] * n # 1 means str[i][:j] < str[i+1][:j]; 0 means str[i][:j] == str[i+1][:j]
        for i in range(COLS):
            tmp = relation.copy()
            shouldDel = False
            for j in range(n-1):
                if tmp[j] != 1 and strs[j][i] > strs[j+1][i]:
                    deletion += 1
                    shouldDel = True
                    break
                if (tmp[j] != 1) and strs[j][i] == strs[j+1][i]:
                    tmp[j] = 0
                if strs[j][i] < strs[j+1][i]:
                    tmp[j] = 1

            if not shouldDel:
                relation = tmp
        return deletion

Greedy/955. Delete Columns to Make Sorted II/solution.py


import unittest
import re

testdata = [
  'value 5 goes to bot 2',
  'bot 2 gives low to bot 1 and high to bot 0',
  'value 3 goes to bot 1',
  'bot 1 gives low to output 1 and high to bot 0',
  'bot 0 gives low to output 2 and high to output 0',
  'value 2 goes to bot 2'
]

class TestDay10(unittest.TestCase):
  def test_parsevaluecmd(self):
    instruction = testdata[0]
    factory = Factory()
    tokens = factory.parsevaluecmd(instruction)
    self.assertEqual(tokens, { 'value': 5, 'bot': '2' })

    instruction = testdata[2]
    tokens = factory.parsevaluecmd(instruction)
    self.assertEqual(tokens, { 'value': 3, 'bot':'1' })

  def test_execvaluecmd(self):
    instruction = testdata[0]
    factory = Factory()
    factory.interpret(instruction)
    self.assertEqual(factory.bots, { '2': [5] })
    self.assertEqual(factory.bins, {})

    instruction = testdata[5]
    factory.interpret(instruction)
    self.assertEqual(factory.bots, { '2': [5, 2] })
    self.assertEqual(factory.bins, {})

  def test_parsebotcmd(self):
    instruction = testdata[1]
    factory = Factory()
    tokens = factory.parsebotcmd(instruction)
    self.assertEqual(tokens, { 'bot': '2', 'low': { 'bot': '1' }, 'high': { 'bot': '0' } })

    instruction = testdata[3]
    tokens = factory.parsebotcmd(instruction)
    self.assertEqual(tokens, { 'bot': '1', 'low': { 'output': '1' }, 'high': { 'bot': '0' } })

  def test_execbotcmd(self):
    factory = Factory()
    factory.bots = { '2': [5, 2], '1': [3] }
    tokens = { 'bot': '2', 'low': { 'bot': '1' }, 'high': { 'bot': '0' } }
    factory.execbotcmd(tokens)
    self.assertEqual(factory.bots, { '2': [], '1': [3, 2], '0': [5] })
    tokens = { 'bot': '1', 'low': { 'output': '1' }, 'high': { 'bot': '0' } }
    factory.execbotcmd(tokens)
    self.assertEqual(factory.bots, { '2': [], '1': [], '0': [5, 3] })
    self.assertEqual(factory.bins, { '1': [2] })

class Factory():
  def __init__(self):
    self.bots = {}
    self.bins = {}
    self.botcmds = {}

  def interpret(self, instruction):
    if (instruction.startswith('value')):
      tokens = self.parsevaluecmd(instruction)
      self.execvaluecmd(tokens)
    elif (instruction.startswith('bot')):
      tokens = self.parsebotcmd(instruction)
      self.execbotcmd(tokens)
    else:
      pass
    return None

  def parsevaluecmd(self, instruction):
    m = re.search(r"value (\d+) goes to bot (\d+)", instruction)
    return { "value": int(m.group(1)), "bot": m.group(2) }

  def execvaluecmd(self, tokens):
    self.bots.setdefault(tokens['bot'], [])
    self.bots[tokens['bot']].append(tokens['value'])
    self.tryexeccmd(tokens['bot'])

  def parsebotcmd(self, instruction):
    m = re.search(r"bot (\d+) gives low to (bot|output) (\d+) and high to (bot|output) (\d+)", instruction)
    return { "bot": m.group(1), "low": { m.group(2): m.group(3) }, "high": { m.group(4): m.group(5) } }

  def execbotcmd(self, tokens):
    ensurekey(self.bots, tokens['bot'], [])

    if len(self.bots[tokens['bot']]) != 2:
      self.botcmds[tokens['bot']] = tokens
      return

    values = self.bots[tokens['bot']]
    maxval = max(values)
    minval = min(values)
    high = tokens['high']
    low = tokens['low']

    print('high: ' + str(maxval) + ' low: ' + str(minval))
    if maxval == 61 and minval == 17:
      print('BOT: ' + tokens['bot'])

    groups = [ { 'receiver': high, 'val': maxval }, { 'receiver': low, 'val': minval } ]
    for group in groups:
      sender = self.bots[tokens['bot']]
      receiver = None
      if 'bot' in group['receiver']:
        ensurekey(self.bots, group['receiver']['bot'], [])
        receiver = self.bots[group['receiver']['bot']]
        self.transfervalue(sender, receiver, group['val'])
        self.tryexeccmd(group['receiver']['bot'])
      else:
        ensurekey(self.bins, group['receiver']['output'], [])
        receiver = self.bins[group['receiver']['output']]
        self.transfervalue(sender, receiver, group['val'])

  def tryexeccmd(self, bot):
    if len(self.bots[bot]) == 2 and bot in self.botcmds and self.botcmds[bot]:
      self.execbotcmd(self.botcmds[bot])
      self.botcmds[bot] = None

  def transfervalue(self, sender, receiver, value):
    sender.remove(value)
    receiver.append(value)

def runmain():
  factory = Factory()
  with open('day10.txt', 'r') as f:
    for line in f:
      factory.interpret(line)
  print(str(factory.bins['0'][0] * factory.bins['1'][0] * factory.bins['2'][0]))

def ensurekey(obj, key, default):
  if key not in obj:
    obj[key] = default

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


import sys
import os
import wget
import zipfile
import gspread
import matplotlib.pyplot as plt
from oauth2client.service_account import ServiceAccountCredentials
from sklearn.metrics import precision_score, recall_score, confusion_matrix, accuracy_score
from skimage import color, exposure, feature, io, transform

import numpy as np
import cv2
# from matplotlib import pyplot as plt

# setup_run = True
# data_base_path = 'https://ait.ethz.ch/public-data/computational_interaction2016/'

# if not os.path.exists('train'):
#     print('[INFO]: Looks like you do not have training data. Let me fetch that for you.')
#     sys.stdout.flush()
#     url_traindata = data_base_path+'train.zip'
#     filename = wget.download(url_traindata)
#     zip_ref = zipfile.ZipFile(filename, 'r')
#     zip_ref.extractall('./')
#     zip_ref.close()
#     print('[INFO]: Training data fetching completed.')
#     sys.stdout.flush()

# if not os.path.exists('./test_T30_R60'):
#     print('[INFO]: Looks like you do not have testing data. Let me fetch that for you')
#     sys.stdout.flush()
#     url_testdata = data_base_path+'test_T30_R60.zip'
#     filename = wget.download(url_testdata)
#     zip_ref = zipfile.ZipFile(filename, 'r')
#     zip_ref.extractall('./')
#     zip_ref.close()
#     print('[INFO]: Testing data fetching completed.')
#     sys.stdout.flush()

# Additionally, there's a second, more challenging dataset that you can download from
# url_testdata_hard = 'https://ait.inf.ethz.ch/teaching/courses/2016-SS-User-Interface-Engineering/downloads/exercises/test_T30_R90.zip '

# Compute accuracy, precision, recall and confusion matrix and (optionally) prints them on screen
def compute_scores(y_pred, y_true, verbose=False):

    hits = 0
    for p in range(1,len(y_true)):
        if y_pred[p] == y_true[p]:
            hits += 1

    accuracy = accuracy_score(y_true, y_pred)
    precision = precision_score(y_true, y_pred, average='macro')
    recall = recall_score(y_true, y_pred, average='macro')
    conf_mat = confusion_matrix(y_true, y_pred)

    if(verbose):
        print ("(RW) Accuracy: " + str(accuracy) + "(" + str(hits) + "/" + str(len(y_true)) + ")")
        print ("Precision: " + str(precision))
        print ("Recall: " + str(recall))
        print ("Confusion Matrix")
        print (conf_mat)
        sys.stdout.flush()

    return accuracy, precision, recall

# Extract HOG features from an image and (optionally) show the features superimposed on it
def extractHOG(inputimg, showHOG=False):

    # convert image to single-channel, grayscale
    image = color.rgb2gray(inputimg)

    #extract HOG features
    if showHOG:
        fd, hog_image = feature.hog(image, orientations=36,
                                    pixels_per_cell=(16, 16),
                                    cells_per_block=(2, 2),
                                    visualise=showHOG)
    else:
        fd = feature.hog(image, orientations=8, pixels_per_cell=(16, 16),
                         cells_per_block=(1, 1), visualise=showHOG)
    if(showHOG):
        fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(8, 4), sharex=True, sharey=True)
        ax1.axis('off')
        ax1.imshow(image, cmap=plt.cm.gray)
        ax1.set_title('Input image')
        ax1.set_adjustable('box-forced')
        # Rescale histogram for better display
        hog_image_rescaled = exposure.rescale_intensity(hog_image, in_range=(0, 0.02))
        ax2.axis('off')
        ax2.imshow(hog_image_rescaled, cmap=plt.cm.gray)
        ax2.set_title('Histogram of Oriented Gradients')
        ax1.set_adjustable('box-forced')
        plt.show()
    return fd

# Load a dataset (Data, Labels) from a folder.
# Return data (HOGs, Class) and image list (as image file ames on disk)
def load_dataset_from_folder(root_folder, rgb_folder, segmentation_folder):

    HOGs_list = []
    Cs_list = []
    image_list = []
    if os.path.exists(root_folder):
        class_folders = next(os.walk(root_folder))[1]
        class_folders.sort()
        print("[INFO] Found " + str(len(class_folders)) + " class folders")
        print(class_folders)
        sys.stdout.flush()
        tot_classes = len(class_folders)
        #used to resize the images
        image_size = (128, 128)
        class_list = range(tot_classes)
        for class_folder,this_class in zip(class_folders,class_list):
            print("\n[INFO] Processing folder " + class_folder)
            sys.stdout.flush()
            current_gesture_folder_rgb = root_folder + class_folder + "/" + rgb_folder + "/*.jpg"
            current_gesture_folder_segmentation = root_folder + class_folder + "/" + segmentation_folder + "/*.png"
            allfiles_imgs = glob.glob(current_gesture_folder_rgb)
            allfiles_masks = glob.glob(current_gesture_folder_segmentation)
            #for each image/mask pair
            line_percentage_cnt = 0
            for file_img,mask_img in zip(allfiles_imgs,allfiles_masks):
                # Print completion percentage
                sys.stdout.write('\r')
                progress_bar_msg = "[%-100s] %d%% " + str(line_percentage_cnt) + "/" + str(len(allfiles_imgs))
                update_step = int( (float(100)/float(len(allfiles_imgs))) * float(line_percentage_cnt) )
                sys.stdout.write(progress_bar_msg % ('='*update_step, update_step))
                sys.stdout.flush()
                img = io.imread(file_img)
                mask = io.imread(mask_img)
                mask = 255 - mask
                img *= mask
                # you can see the segmented image using:
                #io.imshow(img)
                #io.show()
                feat = extractHOG(transform.resize(img, image_size))
                HOGs_list.append(feat)
                Cs_list.append(this_class)
                image_list.append(file_img)
                line_percentage_cnt += 1
        print("[INFO] Loaded data in. Number of samples: "+ str(len(image_list)))
    else:
        print("[ERROR] Folder " + root_folder + " does not exist!")
        print("[ERROR] Have you run the setup cell?")
        sys.stdout.flush()
        exit()

    HOGs = np.array(HOGs_list)
    Cs = np.array(Cs_list)
    return HOGs, Cs, image_list

# Class to store parameters of an SVM
class SVMparameters:

    def __init__(self, k='rbf', c='1', g='0.1', d=1):
        self.kernel = k
        self.C = c
        self.gamma=g
        self.degree = g

    def setkernel(self, k):
        self.kernel = k

    def setgamma(self, g):
        self.gamma = g

    def setc(self, c):
        self.C = c

    def setdegree(self,d):
        self.degree = d

    def printconfig(self):
        print("Kernel: " + self.kernel)
        if self.kernel is "poly":
            print("Degree: " + str(self.degree))
        print("C: " + str(self.C))
        print("Gamma: " + str(self.gamma))
        sys.stdout.flush()

train_folders = next(os.walk("KDEF/"))[1]
train_folders.sort()
print("[INFO] Found " + str(len(train_folders)) + " class folders")
sys.stdout.flush()
tot_classes = len(train_folders)

class_list = range(tot_classes)

image_size = (128, 128)

image_list = []
HOGs_list = []
Cs_list = []

emotion_list = ['AFS.JPG', 'ANS.JPG', 'DIS.JPG', 'HAS.JPG', 'NES.JPG', 'SAS.JPG', 'SUS.JPG']

ffile = []

for class_folder,this_class in zip(train_folders,class_list):
#     print("\n[INFO] Processing folder " + class_folder)
    sys.stdout.flush()

    ffile = os.listdir('KDEF/' + class_folder)

    for i in ffile:

        for j in range(len(emotion_list)):

            if i.endswith(emotion_list[j]): #afraid

                directory = 'KDEF/train/' + emotion_list[j][0:3] + '/' + i

#                 print directory

                if not os.path.exists(directory):
                    os.makedirs(directory)

                tmp_img = io.imread("KDEF/" + class_folder + "/" + i)
                cv2.imwrite(str(directory), tmp_img)

#                 print i

#                 current_face_folder_rgb = class_folder + "/" + i

#                 print current_face_folder_rgb

#                 sys.stdout.write('\r')
#                 progress_bar_msg = "[%-100s] %d%% " + str(line_percentage_cnt) + "/" + str(len(allfiles_imgs))
#                 update_step = int( (float(100)/float(len(allfiles_imgs))) * float(line_percentage_cnt) )
#                 sys.stdout.write(progress_bar_msg % ('='*update_step, update_step))
#                 sys.stdout.flush()

#                 feat = extractHOG(transform.resize(img, image_size))
#                 HOGs_list.append(feat)
#     #             Cs_list.append(this_class)
#                 image_list.append(file_img)

#                 # img = cv2.imread("KDEF/AF01/AF01AFFL.JPG")

#                 img = cv2.imread("KDEF/AF01/AF01AFFL.JPG")
#                 gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
#                 ret, thresh = cv2.threshold(gray,0,255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)

#                 # noise removal
#                 kernel = np.ones((3,3),np.uint8)
#                 opening = cv2.morphologyEx(thresh,cv2.MORPH_OPEN,kernel, iterations = 2)

#                 # sure background area
#                 sure_bg = cv2.dilate(opening,kernel,iterations=3)

#                 # Finding sure foreground area
#                 dist_transform = cv2.distanceTransform(opening,cv2.DIST_L2,5)
#                 ret, sure_fg = cv2.threshold(dist_transform,0.7*dist_transform.max(),255,0)

#                 # Finding unknown region
#                 sure_fg = np.uint8(sure_fg)
#                 mask_img = cv2.subtract(sure_bg,sure_fg)

#                 cv2.imwrite('KDEF/test.png', mask_img)

#                 # io.imshow(mask_img)
#                 # io.show()

#                 # img = io.imread("KDEF/AF01/AF01AFFL.JPG")
#                 mask = io.imread("KDEF/test.png")
#                 mask = 255 - mask

#                 # print mask.shape
#                 # print gray.shape
#                 # (762, 562, 3)
#                 # 388 rows, 647 columns, and 3 channels (the RGB components).

#                 gray *= mask
#                 feat = extractHOG(transform.resize(img, image_size))
#                 extractHOG(img, showHOG=False)

#     current_gesture_folder_segmentation = root_folder + class_folder + "/" + segmentation_folder + "/*.png"

# #used to resize the images
# image_size = (128, 128)
# class_list = range(tot_classes)
# for class_folder,this_class in zip(class_folders,class_list):
#     print("\n[INFO] Processing folder " + class_folder)
#     sys.stdout.flush()
#     current_gesture_folder_rgb = root_folder + class_folder + "/" + rgb_folder + "/*.jpg"
#     current_gesture_folder_segmentation = root_folder + class_folder + "/" + segmentation_folder + "/*.png"


import threading
import serial
import time

class Listener(threading.Thread):
    def __init__(self,port,baud_rate=38400):
        self.port = port
        self.baud_rate = baud_rate
        self.connect()

        # super().__init__(group, target, name, args, kwargs, daemon=daemon)

    def connect(self):
        self.serial = serial.Serial(self.port,self.baud_rate)

    def read_loop(self):
        try:
            assert self.serial
        except AssertionError as err:
            print('The object has not been connected yet to a port. Waiting to connect to {port}'.format(port=self.port))

        while True:
            data = self.serial.read(9999)
            if len(data) > 0:
                print(int.from_bytes(data))
            time.sleep(0.5)
            # print("I'm running the loop")
        self.serial.close()

    def start(self):
        self.thread = threading.Thread(
            target= self.read_loop,
            daemon=True
        )
        self.thread.start()

    def listen(self,listen_time):
        self.start()
        time.sleep(listen_time)

if __name__ == '__main__':
    port = r"\\.\CNCA0"
    listener = Listener(port)
    listener.listen(100)

# while True:
#     data = ser.read(9999)
#     if len(data) > 0:
#         print('Got: {data}'.format(data=data.decode('utf-8')))

#     time.sleep(0.5)
#     # print('not blocked')

# ser.close()


# -*- coding: utf-8 -*-
"""
Created on Wed May 24 19:41:55 2017

@author: Kasia
"""

import cantera as ct
import SDToolbox as sd
import matplotlib.pyplot as plt
import numpy as np

P0=1
T0=300
mech = 'gri30.xml'

pressure_array = np.linspace(0.5,8,20)
temperature_array = np.linspace(300,1000,20)

pressure=[]
temperature=[]
speed=[]
C=[]
i=0

for P0 in pressure_array:

    P0 *= ct.one_atm
    x = 0.1065 # value of max
    a=4.76*x/(1-x)
    q ='O2:1.,N2:3.76,CH4:' + str(a)

    [cj_speed,R2] = sd.CJspeed(P0, T0, q, mech, 0)
    U1 = cj_speed  #shock speed

    gas = sd.PostShock_eq(cj_speed, P0, T0, q, mech)
    Ps = gas.P/ct.one_atm
    #print i, cj_speed
    C.append(x*100)

    pressure.append(gas.P/ct.one_atm)
    temperature.append(gas.T)
    speed.append(cj_speed)
    i=i+1

plt.plot(temperature_array,speed)
plt.xlabel('Initial Temperature [K]')
plt.ylabel('C-J Speed [m/s]')
plt.show()


import logging
from datetime import datetime, timedelta

import requests
from bs4 import BeautifulSoup
from dateutil.tz import gettz
from django.core.exceptions import ValidationError
from django.core.management.base import BaseCommand
from django.db import transaction
from django.utils.timezone import make_aware

from alert.models import AddDropPeriod, validate_add_drop_semester
from courses.models import Course
from courses.util import get_current_semester, get_or_create_add_drop_period
from PennCourses.settings.base import TIME_ZONE

def fill_in_add_drop_periods(verbose=False):
    all_semesters = set(Course.objects.values_list("semester", flat=True).distinct())
    adp_semesters = set(AddDropPeriod.objects.values_list("semester", flat=True).distinct())
    missing_semesters = set()
    for candidate in all_semesters - adp_semesters:
        try:
            validate_add_drop_semester(candidate)
            missing_semesters.add(candidate)
        except ValidationError:
            pass
    if verbose and len(missing_semesters) > 0:
        print(f"Filling in AddDropPeriod objects for semesters {missing_semesters}")
    for semester in missing_semesters:
        AddDropPeriod(semester=semester).save()
    return adp_semesters.union(missing_semesters)

def load_add_drop_dates(verbose=False):
    semester = get_current_semester()
    validate_add_drop_semester(semester)

    if verbose:
        print(f"Loading course selection period dates for semester {semester} from the Almanac")
    with transaction.atomic():
        adp = get_or_create_add_drop_period(semester)
        start_date = adp.start
        end_date = adp.end
        html = requests.get("https://almanac.upenn.edu/penn-academic-calendar").content
        soup = BeautifulSoup(html, "html.parser")
        if semester[4] == "C":
            start_sem = semester[:4] + " spring"
            end_sem = semester[:4] + " fall"
        elif semester[4] == "A":
            start_sem = str(int(semester[:4]) - 1) + " fall"
            end_sem = semester[:4] + " spring"
        else:
            raise ValueError(
                "This script currently only supports fall or spring semesters; "
                f"{semester} is invalid"
            )
        tz = gettz(TIME_ZONE)

        s_year, s_month, s_day, e_year, e_month, e_day = (None,) * 6
        start_mode = 0  # 0 if start semester hasn't been found, 1 if it has, 2 if finished sem
        end_mode = 0  # 0 if end semester hasn't been found, 1 if it has, 2 if finished sem
        all_th_parents = {el.parent for el in soup.find_all("th")}
        months = [
            "january",
            "february",
            "march",
            "april",
            "may",
            "june",
            "july",
            "august",
            "september",
            "october",
            "november",
            "december",
        ]
        for tr_el in soup.find_all("tr"):
            if tr_el in all_th_parents:
                sem_name = tr_el.th.get_text().lower()
                if start_sem in sem_name:
                    start_mode = 1
                elif start_mode == 1:
                    start_mode = 2
                if end_sem in sem_name:
                    end_mode = 1
                elif end_mode == 1:
                    end_mode = 2
            else:
                children = list(tr_el.findChildren("td", recursive=False))
                title = children[0]
                date_string = children[1].get_text()
                if title is not None and "advance registration" in title.get_text().lower():
                    if start_mode == 1:
                        dates = date_string.split("-")
                        ar_begin_month = None
                        for month in months:
                            if month in dates[0].lower():
                                ar_begin_month = month
                        ar_end_month = None
                        for month in months:
                            if month in dates[0].lower():
                                ar_end_month = month
                        if ar_end_month is None:
                            ar_end_month = ar_begin_month
                        s_year = int(start_sem[:4])
                        if ar_end_month is not None:
                            s_month = months.index(ar_end_month) + 1
                        day_candidates = [int(s) for s in dates[1].split() if s.isdigit()]
                        if len(day_candidates) > 0:
                            s_day = day_candidates[0]
                if title is not None and "course selection period ends" in title.get_text().lower():
                    if end_mode == 1:
                        course_sel_end_month = None
                        for month in months:
                            if month in date_string.lower():
                                course_sel_end_month = month
                        e_year = int(end_sem[:4])
                        if course_sel_end_month is not None:
                            e_month = months.index(course_sel_end_month) + 1
                        day_candidates = [int(s) for s in date_string.split() if s.isdigit()]
                        if len(day_candidates) > 0:
                            e_day = day_candidates[0]
        if None not in [s_year, s_month, s_day] and start_date is None:
            start_date = make_aware(
                datetime.strptime(f"{s_year}-{s_month}-{s_day} 07:00", "%Y-%m-%d %H:%M")
                + timedelta(days=1),
                timezone=tz,
            )
            if verbose:
                print(
                    "NOTE: Add/drop date start was estimated as the end of the advanced "
                    "registration period. Replace this date with the actual start of the "
                    "add/drop period through the Django admin console when it is announced "
                    "to students each semester."
                )
        if None not in [e_year, e_month, e_day]:
            end_date = make_aware(
                datetime.strptime(f"{e_year}-{e_month}-{e_day} 11:59", "%Y-%m-%d %H:%M"),
                timezone=tz,
            )
        adp.estimated_start, adp.end = start_date, end_date
        adp.save()
    if verbose:
        print("Done!")

class Command(BaseCommand):
    help = (
        "Load in the start and end date of the current semester's open registration period "
        "from the Penn Almanac. If an AddDropPeriod object from the given semester "
        "already exists and its start field is not null, this script will continue "
        "to use that same start date rather than estimating the start date based on "
        "the end of the advanced registration period. The end date will always "
        "be updated if it is found in the almanac, since the almanac explicitly posts "
        "the date for the end of the course selection period."
    )

    def handle(self, *args, **kwargs):
        root_logger = logging.getLogger("")
        root_logger.setLevel(logging.DEBUG)
        fill_in_add_drop_periods(verbose=True)
        load_add_drop_dates(verbose=True)


import argparse
import pandas as pd
import datetime
import time
from collections import OrderedDict

import gender_guesser.detector as gender_detector

import sys
sys.path.append( '../util' )
import util

pd.set_option( 'display.max_columns', 500 )
pd.set_option( 'display.width', 1000 )

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

####################
# Global constants #
####################

GD = gender_detector.Detector()
GENDER_NA = ''
GENDER_M = 'M'
GENDER_F = 'F'

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

###############
# Subroutines #
###############

def guess_gender( row ):

    if row[util.GENDER] == GENDER_NA:
        # Gender not in 2014 census.  Take a guess.

        guess = GD.get_gender( row[util.FIRST_NAME].capitalize() )

        if 'female' in guess:
            guess = GENDER_F
        elif 'male' in guess:
            guess = GENDER_M
        else:
            guess = GENDER_NA

    else:
        # Gender already known
        guess = row[util.GENDER]

    return guess

def report_gender_findings():

    vc = df_residents[util.GENDER].value_counts()
    pct_mf = int( 100 * ( vc.loc[GENDER_F] + vc.loc[GENDER_M] ) / len( df_census ) )
    print( 'Gender found for {0}% of residents'.format( pct_mf ) )

    df_voted = df_residents[ df_residents[util.VOTED] == util.YES ]
    vc = df_voted[util.GENDER].value_counts()
    pct_mf = int( 100 * ( vc.loc[GENDER_F] + vc.loc[GENDER_M] ) / len( df_voted ) )
    print( 'Gender found for {0}% of voters'.format( pct_mf ) )

def get_zoning_code( row ):

    # If zoning code not already present...
    if pd.isnull( row[util.ZONING_CODE_1] ):

        # ... Look for it in the zone lookup table, ignoring the alternate street number
        zones_row = df_zones.loc[ ( df_zones[util.NORMALIZED_STREET_NUMBER] == row[util.NORMALIZED_STREET_NUMBER] ) & ( df_zones[util.NORMALIZED_STREET_NAME] == row[util.NORMALIZED_STREET_NAME] ) ]

        # Save result of lookup
        if len( zones_row ) == 0:
            code = ''
        else:
            code = zones_row[util.ZONING_CODE_1].values[0]
    else:
        # Zoning code already known; keep it
        code = row[util.ZONING_CODE_1]

    return code

def calculate_likely_dem_score( row ):
    party_affiliation = row[util.PARTY_AFFILIATION]
    score = likely_dem_score( row[util.PARTY_VOTED_HISTORY] ) if ( party_affiliation == util.U ) else likely_dem_score( party_affiliation * len( dc_primary_dates ) )
    return score

def likely_dem_score( s_history, scale=True ):

    score = 0
    increment = 1

    for c in s_history:

        if c == util.D:
            score += increment
        elif c == util.R:
            score -= increment

        increment += 0.1

    if scale:
        score = int( 100 * ( score / max_raw_dem_score ) )

    return score

def calculate_legacy_dem_score( row ):

    score = None

    # If current resident is young, unscored family member, generate legacy score
    if ( row[util.IS_FAMILY] == 1 ) and ( row[util.LIKELY_DEM_SCORE] == 0 ) and ( row[util.AGE] >= util.VOTER_AGE_MIN ) and ( row[util.AGE] <= util.LEGACY_AGE_MAX ) :

        # Find elders of this resident
        df_elders = df_residents[ ( df_residents[util.IS_HOMEOWNER] == 1 ) & ( df_residents[util.PARCEL_ID] == row[util.PARCEL_ID] ) & ( df_residents[util.AGE] > util.LEGACY_AGE_MAX ) ]

        # If elders found, assign legacy score
        if len( df_elders ) > 0:
            score = round( df_elders[util.LIKELY_DEM_SCORE].mean(), 1 )

    return score

def describe_primary_voter( df_rid ):

    # Count R and D votes
    vc = df_rid[util.PARTY_VOTED].value_counts()
    n_d = vc[util.D] if util.D in vc else 0
    n_r = vc[util.R] if util.R in vc else 0

    # Initialize row representing current resident
    voter_row = OrderedDict()

    # Add voting data to row
    voter_row[util.D] = n_d
    voter_row[util.R] = n_r
    voter_row[util.ABSENT] = len( dc_primary_dates ) - n_d - n_r
    voter_row[util.VOTED_BOTH] = util.YES if ( ( n_d > 0 ) and ( n_r > 0 ) ) else util.NO
    party_affiliation = df_rid.iloc[0][util.PARTY_AFFILIATION]
    voter_row[util.CHANGED_AFFILIATION] = util.YES if ( ( ( party_affiliation == util.R ) and ( n_d > 0 ) ) or ( ( party_affiliation == util.D ) and ( n_r > 0 ) ) ) else util.NO

    # Save voting history for current resident
    dates = dc_primary_dates.copy()
    for index, election_row in df_rid.iterrows():
        dates[ election_row[util.ELECTION_DATE].split()[0] ] = election_row[util.PARTY_VOTED]
    voter_row[util.PARTY_VOTED_HISTORY] = ''.join( dates.values() )
    voter_row.update( dates )

    df_voter_row = pd.DataFrame( [voter_row] )

    return df_voter_row

def filter_assessed_values( row ):
    assessed_value = row[util.TOTAL_ASSESSED_VALUE] if ( row[util.IS_HOMEOWNER] or row[util.IS_FAMILY] ) else None
    return assessed_value

def addYears( d, years ):
    try:
        return d.replace( year=d.year+years )
    except ValueError:
        # Handle February 29
        return d + ( datetime.date( d.year + years, 1, 1 ) - datetime.date( d.year, 1, 1 ) )

def calculate_voter_engagement_score( row ):

    if row[util.VOTED] == util.YES:
        # This resident has voted

        # List possible dates of earliest voting eligibility

        # Consider 18th birthday
        date_format = '%Y-%m-%d %H:%M:%S'
        age_18_date = addYears( datetime.datetime.strptime( row[util.DATE_OF_BIRTH], date_format ), 18 ).strftime( date_format )

        ls_dates = [ age_18_date ]

        # Consider most recent property transfer
        if not pd.isnull( row[util.LEGAL_REFERENCE_SALE_DATE] ):
            if row[util.NAL_DESCRIPTION] not in util.NAL_IGNORE:
                ls_dates.append( row[util.LEGAL_REFERENCE_SALE_DATE] )
            else:
                # Consider previous property transfer
                if not pd.isnull( row[util.PREVIOUS_LEGAL_REFERENCE_SALE_DATE] ):
                    if row[util.PREVIOUS_NAL_DESCRIPTION] not in util.NAL_IGNORE:
                        ls_dates.append( row[util.PREVIOUS_LEGAL_REFERENCE_SALE_DATE] )

        ls_dates.sort( reverse=True )

        # Ignore property transfer date if it conflicts with actual voting record
        first_vote_date = df_elections[df_elections[util.RESIDENT_ID] == row[util.RESIDENT_ID]][util.ELECTION_DATE].iloc[0]
        if ls_dates[0] > first_vote_date:
            # Use 18th birthday
            ls_dates = [ age_18_date ]

        # Try dates in reverse order, until one produces a score within accepted range
        for s_date in ls_dates:
            df_eligible = df_election_history.loc[ df_election_history[util.ELECTION_DATE] >= s_date ]
            score = round( 100 * df_scores.loc[ row[util.RESIDENT_ID] ][util.SCORE] / df_eligible[util.SCORE].sum(), 2 )
            if score <= 100:
                break

    else:
        # This resident has not voted
        score = 0

    return score

# Mark resident participation in general elections
def mark_who_voted_when():

    global df_residents

    # Create dataframe of general elections, sorted by date
    df_general = df_e2.copy()
    df_general = df_general[ df_general[util.ELECTION_TYPE] != util.ELECTION_TYPES['LOCAL_TOWN_MEETING']]
    df_general = df_general.sort_values( by=[util.ELECTION_DATE] )

    # Iterate over general elections
    for idx, df_group in df_general.groupby( by=[util.ELECTION_DATE] ):

        # Create copy of current general election
        df_ge = df_group.copy()

        # Format label representing this election
        date = idx.split()[0]
        type = df_ge.iloc[0][util.ELECTION_TYPE].split()[0].lower()
        col = util.VOTED + '_' + type + '_' + date

        # Show who participated
        df_ge[col] = util.YES
        df_ge = df_ge[ [util.RESIDENT_ID, col] ]
        df_residents = pd.merge( df_residents, df_ge, how='left', on=[util.RESIDENT_ID] )

        # Show who didn't participate
        df_residents[col] = df_residents[col].fillna( util.NO )

def count_town_meeting_attendance():

    # Get town meeting attendance records
    df_town_meetings = df_e2[ df_e2[util.ELECTION_TYPE] == util.ELECTION_TYPES['LOCAL_TOWN_MEETING'] ]

    # Count attendance at all town meetings
    df_tm = df_town_meetings[util.RESIDENT_ID].value_counts().rename(util.TOWN_MEETINGS_ATTENDED).to_frame()
    df_tm[util.RESIDENT_ID] = df_tm.index

    # Isolate town meeting history
    df_meeting_history = df_election_history[ df_election_history[util.ELECTION_TYPE] == util.ELECTION_TYPES['LOCAL_TOWN_MEETING'] ].sort_values( by=[util.ELECTION_YEAR], ascending=[False] )

    # List recent town meeting dates, organized by year
    dc_recent_years = {}
    for idx, df_group in df_meeting_history.groupby( by=[util.ELECTION_YEAR], sort=False ):
        dc_recent_years[str(idx)] = df_group[util.ELECTION_DATE].tolist()
        if len( dc_recent_years ) >= util.RECENT_LOCAL_ELECTION_COUNT:
            break

    # Count attendance at recent town meetings
    for year in dc_recent_years.keys():
        col = util.TOWN_MEETINGS_ATTENDED + '_' + year
        df_tm_year = df_town_meetings[ df_town_meetings[util.ELECTION_DATE].isin( dc_recent_years[year] ) ]
        df_tm_year = df_tm_year[util.RESIDENT_ID].value_counts().rename(col).to_frame()
        df_tm_year[util.RESIDENT_ID] = df_tm_year.index
        df_tm = pd.merge( df_tm, df_tm_year, how='left', on=util.RESIDENT_ID )
        df_tm[col] = df_tm[col].fillna(0).astype(int)

    return df_tm

def make_gal_per_day_col_name( service_type ):
    return service_type.lower() + '_' + util.GAL_PER_DAY

# Mark resident participation in general elections
def add_water_data():

    global df_residents

    # Extract lookup rows that contain meter numbers
    df_meter_lookup = df_lookup[ df_lookup[util.METER_NUMBER] != '' ]

    # Read Water Customers table from database
    df_customers = pd.read_sql_table( 'WaterCustomers', engine )
    df_customers[util.METER_NUMBER] = df_customers[util.METER_NUMBER].astype(str)

    # Generate column names
    dc_serv_types = {}
    for serv_type in df_customers[util.SERVICE_TYPE].unique():
        dc_serv_types[serv_type] = make_gal_per_day_col_name( serv_type )

    # Iterate over residents
    for i, res_row in df_residents.iterrows():

        # Get next Resident ID
        res_id = res_row[util.RESIDENT_ID]

        # Find meters belonging to current resident
        df_meters = df_meter_lookup[ df_meter_lookup[util.RESIDENT_ID] == res_id ]

        # Process each meter
        for j, meter_row in df_meters.iterrows():

            # Get meter number
            meter_num = meter_row[util.METER_NUMBER]

            # Find water customer with this meter number
            df_customer = df_customers[ df_customers[util.METER_NUMBER] == meter_num ]

            # Save gallons-per-day measurement in corresponding column of Residents table
            if len( df_customer ) > 0:
                cust_row = df_customer.iloc[0]
                if cust_row[util.METER_STATUS] != util.METER_ANOMALY:
                    df_residents.at[ df_residents[util.RESIDENT_ID] == res_id, make_gal_per_day_col_name( cust_row[util.SERVICE_TYPE] )] = cust_row[util.GAL_PER_DAY]

                    if cust_row[util.GAL_PER_DAY] < 0:
                        print( cust_row )

    return

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

###############
# Main script #
###############

if __name__ == '__main__':

    # Retrieve and validate arguments
    parser = argparse.ArgumentParser( description='Generate table listing and describing all residents' )
    parser.add_argument( '-m', dest='master_filename',  help='Master database filename' )
    parser.add_argument( '-d', dest='debug', action='store_true', help='Include debug columns?' )
    args = parser.parse_args()

    # Open the master database
    conn, cur, engine = util.open_database( args.master_filename, False )

    # Read census table from database
    df_census = pd.read_sql_table( 'Census', engine, columns=[util.RESIDENT_ID, util.LAST_NAME, util.FIRST_NAME, util.DATE_OF_BIRTH, util.PARTY_AFFILIATION, util.OCCUPATION, util.RADDR_STREET_NUMBER_SUFFIX, util.RADDR_APARTMENT_NUMBER, util.PRECINCT_NUMBER] )
    df_census[util.FIRST_NAME] = df_census[util.FIRST_NAME].fillna( '' )
    df_census[util.PARTY_AFFILIATION] = df_census[util.PARTY_AFFILIATION].str.strip()
    df_gender = pd.read_sql_table( 'Gender_2014', engine, columns=[util.RESIDENT_ID,util.GENDER] )

    # Read election tables from database
    election_columns = [util.RESIDENT_ID, util.ELECTION_DATE, util.ELECTION_TYPE]
    df_e1 = pd.read_sql_table( 'ElectionModel_01', engine, columns=election_columns )
    df_e2 = pd.read_sql_table( 'ElectionModel_02', engine, columns=election_columns )
    df_e3 = pd.read_sql_table( 'ElectionModel_03', engine, columns=election_columns )

    # Combine all elections into one dataframe and sort on resident ID and date
    df_elections = df_e1.append( df_e2 ).append( df_e3 )
    df_elections = df_elections.sort_values( by=[util.RESIDENT_ID,util.ELECTION_DATE] )

    # Build list of all voters
    df_all_voters = df_elections.copy().drop_duplicates( subset=[util.RESIDENT_ID] )
    df_all_voters = df_all_voters.drop( columns=[util.ELECTION_DATE, util.ELECTION_TYPE] )
    df_all_voters[util.VOTED] = util.YES

    # Count primary election votes
    df_pe = df_e1
    df_pe = df_pe[util.RESIDENT_ID].value_counts().rename(util.PRIMARY_ELECTIONS_VOTED).to_frame()
    df_pe[util.RESIDENT_ID] = df_pe.index

    # Count local election votes
    df_le = df_e2[ df_e2[util.ELECTION_TYPE] == util.ELECTION_TYPES['LOCAL_ELECTION'] ]
    df_le = df_le[util.RESIDENT_ID].value_counts().rename(util.LOCAL_ELECTIONS_VOTED).to_frame()
    df_le[util.RESIDENT_ID] = df_le.index

    # Count state election votes
    df_se = df_e2[ df_e2[util.ELECTION_TYPE] == util.ELECTION_TYPES['STATE_ELECTION'] ]
    df_se = df_se[util.RESIDENT_ID].value_counts().rename(util.STATE_ELECTIONS_VOTED).to_frame()
    df_se[util.RESIDENT_ID] = df_se.index

    # Count special election votes
    df_sp = df_e2[ df_e2[util.ELECTION_TYPE] == util.ELECTION_TYPES['SPECIAL_STATE'] ]
    df_sp = df_sp[util.RESIDENT_ID].value_counts().rename(util.SPECIAL_ELECTIONS_VOTED).to_frame()
    df_sp[util.RESIDENT_ID] = df_sp.index

    # Count attendance at town meetings
    df_election_history = pd.read_sql_table( 'ElectionHistory', engine, columns=[util.ELECTION_YEAR, util.ELECTION_DATE, util.ELECTION_TYPE, util.SCORE] )
    df_tm = count_town_meeting_attendance()

    # Count early votes
    df_ev = df_e3
    df_ev = df_ev[util.RESIDENT_ID].value_counts().rename(util.EARLY_VOTES).to_frame()
    df_ev[util.RESIDENT_ID] = df_ev.index

    # Read and combine Lookup and Assessment tables
    df_lookup = pd.read_sql_table( 'Lookup', engine, columns=[util.RESIDENT_ID, util.NORMALIZED_STREET_NUMBER, util.LADDR_ALT_STREET_NUMBER, util.NORMALIZED_STREET_NAME, util.PARCEL_ID, util.IS_HOMEOWNER, util.IS_FAMILY, util.METER_NUMBER] )
    df_lookup = df_lookup.dropna( subset=[util.RESIDENT_ID] )
    df_homes = df_lookup.copy()
    df_homes = df_homes.drop( columns=[util.METER_NUMBER] )
    df_homes = df_homes.drop_duplicates( subset=[util.RESIDENT_ID] )
    df_assessment = pd.read_sql_table( 'Assessment', engine, columns=[util.PARCEL_ID, util.LEGAL_REFERENCE_SALE_DATE, util.NAL_DESCRIPTION, util.PREVIOUS_LEGAL_REFERENCE_SALE_DATE, util.PREVIOUS_NAL_DESCRIPTION, util.TOTAL_ASSESSED_VALUE] )
    df_homes = pd.merge( df_homes, df_assessment, how='left', on=[util.PARCEL_ID] )
    df_homes[util.TOTAL_ASSESSED_VALUE] = df_homes.apply( lambda row: filter_assessed_values( row ), axis=1 )

    # Merge
    df_residents = pd.merge( df_census, df_all_voters, how='left', on=util.RESIDENT_ID )
    df_residents[util.VOTED] = df_residents[util.VOTED].fillna( util.NO )
    df_residents = pd.merge( df_residents, df_gender, how='left', on=util.RESIDENT_ID )
    df_residents[util.GENDER] = df_residents[util.GENDER].fillna( GENDER_NA )
    df_residents = pd.merge( df_residents, df_homes, how='left', on=util.RESIDENT_ID )
    df_residents[util.IS_HOMEOWNER] = df_residents[util.IS_HOMEOWNER].astype(int)
    df_residents[util.IS_FAMILY] = df_residents[util.IS_FAMILY].astype(int)
    df_residents = pd.merge( df_residents, df_pe, how='left', on=util.RESIDENT_ID )
    df_residents[util.PRIMARY_ELECTIONS_VOTED] = df_residents[util.PRIMARY_ELECTIONS_VOTED].fillna(0).astype(int)
    df_residents = pd.merge( df_residents, df_le, how='left', on=util.RESIDENT_ID )
    df_residents[util.LOCAL_ELECTIONS_VOTED] = df_residents[util.LOCAL_ELECTIONS_VOTED].fillna(0).astype(int)
    df_residents = pd.merge( df_residents, df_se, how='left', on=util.RESIDENT_ID )
    df_residents[util.STATE_ELECTIONS_VOTED] = df_residents[util.STATE_ELECTIONS_VOTED].fillna(0).astype(int)
    df_residents = pd.merge( df_residents, df_sp, how='left', on=util.RESIDENT_ID )
    df_residents[util.SPECIAL_ELECTIONS_VOTED] = df_residents[util.SPECIAL_ELECTIONS_VOTED].fillna(0).astype(int)
    df_residents = pd.merge( df_residents, df_tm, how='left', on=util.RESIDENT_ID )
    tm_cols = df_tm.columns.tolist()
    tm_cols.remove( util.RESIDENT_ID )
    for col in tm_cols:
        df_residents[col] = df_residents[col].fillna(0).astype(int)
    df_residents = pd.merge( df_residents, df_ev, how='left', on=util.RESIDENT_ID )
    df_residents[util.EARLY_VOTES] = df_residents[util.EARLY_VOTES].fillna(0).astype(int)

    # Guess gender where not known
    print( '' )
    report_gender_findings()
    print( 'Guessing missing genders...' )
    df_residents[util.GENDER] = df_residents.apply( lambda row: guess_gender( row ), axis=1 )
    report_gender_findings()
    print( '' )

    # Calculate age
    df_residents[util.AGE] = df_residents[util.DATE_OF_BIRTH].apply( lambda date_of_birth: util.calculate_age( date_of_birth ) )

    # Insert zoning codes
    t = time.time()
    print( 'Inserting zoning codes, starting at {0}...'.format( time.strftime( '%H:%M:%S', time.localtime( t ) ) ) )
    df_zones = pd.read_sql_table( 'ZoneLookup', engine, columns=[util.NORMALIZED_STREET_NUMBER, util.LADDR_ALT_STREET_NUMBER, util.NORMALIZED_STREET_NAME, util.ZONING_CODE_1] )
    df_residents = pd.merge( df_residents, df_zones, how='left', on=[util.NORMALIZED_STREET_NUMBER, util.LADDR_ALT_STREET_NUMBER, util.NORMALIZED_STREET_NAME] )
    df_residents[util.ZONING_CODE_1] = df_residents.apply( lambda row: get_zoning_code( row ), axis=1 )
    util.report_elapsed_time( 'Inserted zoning codes -- ', t )
    print( '' )

    # Load primary elections dataframe
    df_primary = pd.read_sql_table( 'ElectionModel_01', engine, parse_dates=True )
    df_primary = df_primary.sort_values( by=[util.ELECTION_DATE] )
    df_primary[util.PARTY_AFFILIATION] = df_primary[util.PARTY_AFFILIATION].str.strip()
    df_primary[util.PARTY_VOTED] = df_primary[util.PARTY_VOTED].str.strip()

    # Build dictionaries of unique primary election dates and corresponding column names
    dc_primary_dates = OrderedDict()
    dc_ballot_cols = {}
    for date in df_primary[util.ELECTION_DATE].unique():
        date_name = date.split()[0]
        dc_primary_dates[date_name] = '-'
        dc_ballot_cols[date_name] = 'primary_ballot_' + date_name

    # Calculate voter engagement score
    t = time.time()
    print( 'Calculating voter engagement scores, starting at {0}...'.format( time.strftime( '%H:%M:%S', time.localtime( t ) ) ) )
    df_scores = pd.merge( df_elections, df_election_history, how='left', on=[util.ELECTION_DATE, util.ELECTION_TYPE] )
    df_scores = df_scores.groupby( by=[util.RESIDENT_ID] ).sum()
    df_residents[util.VOTER_ENGAGEMENT_SCORE] = df_residents.apply( lambda row: calculate_voter_engagement_score( row ), axis=1 )
    util.report_elapsed_time( 'Scored voters -- ', t )
    print( '' )

    # Generate descriptions of primary voters
    t = time.time()
    print( 'Characterizing primary voters, starting at {0}...'.format( time.strftime( '%H:%M:%S', time.localtime( t ) ) ) )
    df_residents[util.PARTY_AFFILIATION] = df_residents[util.PARTY_AFFILIATION].fillna( '' )
    df_primary_voters = df_primary.groupby( by=[util.RESIDENT_ID] ).apply( describe_primary_voter )
    df_primary_voters = df_primary_voters.reset_index().drop( columns=['level_1'] )
    df_primary_voters = df_primary_voters.rename( columns=dc_ballot_cols )
    df_residents = pd.merge( df_residents, df_primary_voters, how='left', on=util.RESIDENT_ID )
    df_residents[util.PARTY_VOTED_HISTORY] = df_residents[util.PARTY_VOTED_HISTORY].fillna( '' )
    util.report_elapsed_time( 'Characterized primary voters -- ', t )

    # Calculate likely Democrat and party preference scores
    max_raw_dem_score = likely_dem_score( 'D' * len( dc_primary_dates ), scale=False )
    df_residents[util.LIKELY_DEM_SCORE] = df_residents.apply( lambda row: calculate_likely_dem_score( row ), axis=1 )
    df_residents[util.LEGACY_DEM_SCORE] = df_residents.apply( lambda row: calculate_legacy_dem_score( row ), axis=1 )
    df_residents[util.PARTY_PREFERENCE_SCORE] = df_residents.apply( lambda row: util.likely_dem_to_party_preference_score( row[util.LIKELY_DEM_SCORE] ), axis=1 )
    df_residents[util.LEGACY_PREFERENCE_SCORE] = df_residents.apply( lambda row: util.likely_dem_to_party_preference_score( row[util.LEGACY_DEM_SCORE] ), axis=1 )

    # Mark participation of residents in general elections
    mark_who_voted_when()

    # Add water consumption statistics
    add_water_data()

    # Sort
    df_residents = df_residents.sort_values( by=[util.NORMALIZED_STREET_NAME, util.NORMALIZED_STREET_NUMBER] )

    # Drop columns not wanted in database
    drop_columns = [
        util.DATE_OF_BIRTH,
        util.LEGAL_REFERENCE_SALE_DATE,
        util.NAL_DESCRIPTION,
        util.PREVIOUS_LEGAL_REFERENCE_SALE_DATE,
        util.PREVIOUS_NAL_DESCRIPTION
    ]
    df_residents = df_residents.drop( columns=drop_columns )

    # Optionally drop debug columns
    if not args.debug:
        debug_columns = [
        ]
        df_residents = df_residents.drop( columns=debug_columns )

    # Save result to database
    util.create_table( 'Residents', conn, cur, df=df_residents )

    # Report elapsed time
    util.report_elapsed_time()


class Solution:
    def maximumSafenessFactor(self, grid: List[List[int]]) -> int:
        n = len(grid)
        theives = deque([])
        for i in range(n):
            for j in range(n):
                if grid[i][j]:
                    theives.append((i, j, 0))

        isValid = lambda x, y: -1 < x < n and -1 < y < n

        visited = set()
        while theives:
            x, y, safeness = theives.popleft()
            if (x, y) in visited or not isValid(x, y):
                continue
            grid[x][y] = safeness
            visited.add((x, y))
            theives.append((x + 1, y, safeness + 1))
            theives.append((x, y + 1, safeness + 1))
            theives.append((x - 1, y, safeness + 1))
            theives.append((x, y - 1, safeness + 1))

        q = [(-grid[0][0], 0, 0)]
        visited = {}
        maxSafety = 0
        while q:
            safeness, x, y = heappop(q)
            safeness *= -1
            if not isValid(x, y):
                continue
            safeness = min(safeness, grid[x][y])
            if (x, y) in visited and visited[(x, y)] >= safeness:
                continue
            visited[(x, y)] = safeness
            if (x, y) == (n - 1, n - 1):
                maxSafety = max(maxSafety, safeness)
                continue
            heappush(q, (-safeness, x + 1, y))
            heappush(q, (-safeness, x, y + 1))
            heappush(q, (-safeness, x - 1, y))
            heappush(q, (-safeness, x, y - 1))
        return maxSafety


import pandas as pd
import re
import string
import pandas as pd
import joblib
from string import digits

LR = joblib.load('LR_latest.pkl')
vectorization = joblib.load('vectoriser.pkl')

def wordopt(text):
    text = text.lower()
    text = re.sub('\[.*?\]', '', text)
    text = re.sub("\\W"," ",text)
    text = re.sub('https?://\S+|www\.\S+', '', text)
    text = re.sub('<.*?>+', '', text)
    text = re.sub('[%s]' % re.escape(string.punctuation), '', text)
    text = re.sub('\n', '', text)
    text = re.sub('\w*\d\w*', '', text)
    return text

def output_lable(n):
    if n == 1:
        return "Fake News hai Bhai"
    elif n == 0:
        return "Nahi Fake News nahi hai Bhai"

def manual_testing(news):

    remove_digits = str.maketrans('', '', digits)
    ini_string=str(news)
    news = ini_string.translate(remove_digits)
    testing_news = {"text":[news]}
    new_def_test = pd.DataFrame(testing_news)
    new_def_test["text"] = new_def_test["text"].apply(wordopt)
    new_x_test = new_def_test["text"]
    new_xv_test = vectorization.transform(new_x_test)
    pred_LR = LR.predict(new_xv_test)

    return print("\n\nLR Prediction: {}".format(output_lable(pred_LR[0])))

def main() :
    print('Batao kis news ke baare mein btaun :')
    news = str(input())
    print('Ruko Abhi Batata hun.....')
    manual_testing(news)

if __name__ == '__main__':
    main()


#Autor: guilleCM y Luis Cifre

#coding=utf-8

def resolverEquacionSegundoGrado (a, b, c):
    import math

    interiorRaiz = b**2 -(4*a*c)
    if interiorRaiz >= 0:
        resultadoRaiz = math.sqrt(interiorRaiz)
        x1 = (-b + resultadoRaiz) / 2*a
        x2 = (-b - resultadoRaiz) / 2*a
        if x1 == x2:
            x = x1
            return x
        else:
            return x1, x2
    else:
            return NONE

###CASOS TEST###
print (resolverEquacionSegundoGrado (1, -4, 4))


from frame import Frame
from helper import OBJECT_MAP, get_hypernym_path

from numpy.polynomial import polynomial
from nltk.corpus import wordnet as wn
import json
import os

class NodeFrame:
    def __init__(self, frame: Frame, p_list: list[float]) -> None:
        self.frame = frame
        self.p_list = p_list
        self.p_total = self.calculate_p_total(p_list)
        self.p_exactly = self.calculate_p_exactly(p_list)

    def calculate_p_total(self, p_list: list[float]) -> float:
        return sum(p_list)

    def calculate_p_exactly(self, p_list: list[float]) -> list[float]:
        result = [1]
        p_list = [[1 - p, p] for p in p_list]
        for p in p_list:
            result = polynomial.polymul(result, p)
        return list(result)

    def p_of(self, amount: int) -> float:
        if amount < len(self.p_exactly):
            return self.p_exactly[amount]
        else:
            return self.p_exactly[-1] * (0.1 ** (amount - len(self.p_exactly) + 1))

    def serialize(self) -> dict:
        return {
            'frame': self.frame.serialize(),
            'p_list': self.p_list,
        }

class Node:
    def __init__(self, node_frames: list[NodeFrame]) -> None:
        self.node_frames = node_frames
        self.children = {}

class Trie:
    def __init__(self) -> None:
        self.root = Node([])

    def insert(self, node_frame: NodeFrame, path: list[str]) -> None:
        node = self.root
        for word in path:
            if word not in node.children:
                node.children[word] = Node([])
            node = node.children[word]
        node.node_frames.append(node_frame)

    def search(self, path: list[str]) -> list[NodeFrame]:
        node = self.root
        for word in path:
            if word not in node.children:
                return []
            node = node.children[word]
        return self.search_all_children(node)

    def search_all_children(self, node: Node) -> list[NodeFrame]:
        result = []
        if len(node.node_frames) > 0:
            result.extend(node.node_frames)
        for child in node.children.values():
            result.extend(self.search_all_children(child))
        return result

    def load_from_dir(self, dir: str) -> None:
        for path, _, files in os.walk(dir):
            for file in files:
                if file.endswith('.json'):
                    data = json.load(open(os.path.join(path, file)))
                    video = file[:-5]
                    for frame_name, frame_data in data.items():
                        for object, p_list in frame_data.items():
                            hypernym_path = get_hypernym_path(object)
                            self.insert(NodeFrame(Frame(video=video, frame_name=frame_name), p_list), hypernym_path)

    def save_to_cache(self, cache_path: str) -> None:
        json.dump(self.serialize(), open(cache_path, 'w'))

    def load_from_cache(self, cache_path: str) -> None:
        self.deserialize(json.load(open(cache_path)))

    def serialize(self) -> dict:
        output = {}
        def dfs(node: Node, path: list[str]) -> None:
            if len(node.node_frames) > 0:
                output['/'.join(path)] = [node_frame.serialize() for node_frame in node.node_frames]
            for word, child in node.children.items():
                dfs(child, path + [word])
        dfs(self.root, [])
        return output

    def deserialize(self, input):
        for path, node_frames in input.items():
            path = path.split('/')
            for node_frame in node_frames:
                self.insert(NodeFrame(Frame(id=node_frame['frame']['id']), node_frame['p_list']), path)


from random import randrange, random

from grader.core.acronyms import QuestionAcronym
from grader.utils.printer import *

class QuestionSMART(QuestionAcronym):
	def __init__(self):
		super(QuestionSMART, self).__init__()
		self.weight = 0.5

	# returns a list of letter-description pairs of the acronym
	def define_acronym(self):
		return [
			('S', 'specific'),
			('M', 'measurable'),
			('A', 'agreed upon'),
			('R', 'realistic'),
			('T', 'time based')
		]


import numpy as np
from scipy.spatial.transform import Rotation

def pcl_trafo(pcl, trans_oldref=np.zeros(3), trans_newref=np.zeros(3),
              rot=np.zeros(3)):
    R = (Rotation.from_euler('x', rot[0]).as_dcm() @
         Rotation.from_euler('y', rot[1]).as_dcm() @
         Rotation.from_euler('z', rot[2]).as_dcm())

    pcl_new = R @ (pcl[:3,:] + trans_oldref.reshape(3,1)) + trans_newref.reshape(3,1)
    return np.vstack((pcl_new, np.ones((1, pcl_new.shape[1]))))


'''
3. Fibonacci
• O usuário informa um número e é impresso na tela qual é esse número na
série de Fibonacci (1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, ...)
• Por exemplo: se o usuário digitar 7, deve retornar o 7º número da
sequência (13)
'''
# print('FIBONACCI')
# num = int(input('Digite a posição da sequência de Fibonacci que você deseja saber:  '))

# f1 = 0
# f2 = 1
# seq = 3
# while seq < num:
#   f3 = f1 + f2
#   print(f3)
#   f1 = f2
#   f2 = f3
#   seq += 1
#   print(f1)

num = int(input('Digite o termo da sequência que você deseja saber: '))
f1 = 0
f2 = 1
for i in range(num):
  f3 = f1 + f2
  f1 = f2
  f2 = f3
print(f'O {num}º termo da sequência de Fibonacci é {f1}')


import mysql.connector
import pandas as pd
import random

mydb = mysql.connector.connect(
    host="localhost", user="root", password="")
c = mydb.cursor()
c.execute("USE fast_food")

command = "select user_id from user where user_id not in (select user_id from orders) and permissions <> 'deliver_agent';"
c.execute(command)
data = c.fetchall()
order_id = 208
total_amount = 0

for i in range(3000):
    user_id = random.choice(data)
    data.remove(user_id)
    user_id = '\'' + user_id[0] + '\''
    franchise_id = random.randint(1, 10)
    offer_id = random.randint(0,3)
    discount = 0
    date = '\'' + str(random.randint(1,30)) + '/' + str(random.randint(1, 12)) + '/' + '2011' + '\''
    final_price = 0

    command = "insert into orders values(" + str(order_id) + ',' + str(total_amount) + ',' + user_id + ',' + str(franchise_id) + ',' + str(offer_id) + ',' + str(discount) + ',' + str(final_price) + ',' + str(date) + ');'
    c.execute(command)
    order_id += 1
    # print(command)

mydb.commit()


from common.Table import Style

__author__ = 'Max'

def details_for_cat(table,rowi,category,print_fun):

    #style_time1 = xlwt.easyxf(num_format_str='D-MMM')
    #style_money=xlwt.easyxf(num_format_str='#,##0.00')
    cattitle=category.title
    p=category.parent
    while p:
            if p.title=="_root":
                break
            cattitle=p.title+"/"+cattitle
            p=p.parent

    rowi+=1
    rowi_start_of_category=rowi

    subtotal=0
    if hasattr(category, 'stories'):
        for r in category.stories:
            rowi+=1

            v=print_fun(table,rowi,r)

            subtotal+=v

    for c in category.childs:
        #rowi+=1
        rowi, childtotal=details_for_cat(table,rowi,c,print_fun)
        #rowi+=1
        subtotal+=childtotal

    category.total_sum=0
    if subtotal>0:
        rowi+=1
        table[rowi_start_of_category,0]=cattitle
        table[rowi, 2]= u"Total in"
        table[rowi, 4]= u"{0}".format(cattitle)
        table[rowi, 5]=subtotal ,Style.DetailedMoney
        category.total_sum=subtotal
        rowi+=1
    else:
        rowi-=1

    return rowi,subtotal


# Создайте программу для игры в ""Крестики-нолики"".

import random
logs = open('TicTacToeLogs.txt', 'a')

matrix = [['*', '*', '*'], ['*','*','*'], ['*', '*', '*']]

for i in range(0, len(matrix)):
    for j in range(0, len(matrix[i])):
        print(matrix[i][j], end=' ')
        if j == 2:
            logs.write(f'{matrix[i][j]}\n')
        else:
            logs.write(f'{matrix[i][j]} ')
    print()

turn = int(random.randint(0, 1))
if turn == 0:
    print('Первым ходит первый игрок! --> O')
    logs.write('First player turn! --> O\n')
elif turn == 1:
    print('Первым ходит второй игрок! --> X')
    logs.write('Second player turn! --> X\n')
print('Введите 2 числа координат через пробел от 1 до 3.')
logs.write('Enter 2 numbers using a "space" button (for 1 to 3).\n')

for i in range(0, len(matrix)):
    for j in range(0, len(matrix[i])):
        if ((matrix[0][0] == 'O' and matrix[0][1] == 'O' and matrix[0][2] == 'O') or
            (matrix[1][0] == 'O' and matrix[1][1] == 'O' and matrix[1][2] == 'O') or
            (matrix[2][0] == 'O' and matrix[2][1] == 'O' and matrix[2][2] == 'O') or
            (matrix[0][0] == 'O' and matrix[1][0] == 'O' and matrix[2][0] == 'O') or
            (matrix[0][1] == 'O' and matrix[1][1] == 'O' and matrix[2][1] == 'O') or
            (matrix[0][2] == 'O' and matrix[1][2] == 'O' and matrix[2][2] == 'O') or
            (matrix[0][0] == 'O' and matrix[1][1] == 'O' and matrix[2][2] == 'O') or
            (matrix[0][2] == 'O' and matrix[1][1] == 'O' and matrix[2][0] == 'O')):
            print('Выиграл первый игрок!!!')
            logs.write('First player win!\n')
            break
        elif ((matrix[0][0] == 'X' and matrix[0][1] == 'X' and matrix[0][2] == 'X') or
            (matrix[1][0] == 'X' and matrix[1][1] == 'X' and matrix[1][2] == 'X') or
            (matrix[2][0] == 'X' and matrix[2][1] == 'X' and matrix[2][2] == 'X') or
            (matrix[0][0] == 'X' and matrix[1][0] == 'X' and matrix[2][0] == 'X') or
            (matrix[0][1] == 'X' and matrix[1][1] == 'X' and matrix[2][1] == 'X') or
            (matrix[0][2] == 'X' and matrix[1][2] == 'X' and matrix[2][2] == 'X') or
            (matrix[0][0] == 'X' and matrix[1][1] == 'X' and matrix[2][2] == 'X') or
            (matrix[0][2] == 'X' and matrix[1][1] == 'X' and matrix[2][0] == 'X')):
            print('Выиграл второй игрок!!!')
            logs.write('Second player win!\n')
            break
        else:
            if turn == 0:
                print('Ход первого игрока! --> O')
                logs.write('First player turn! --> O\n')
                first = input().split(' ')
                logs.write(f'{first}\n')
                if (matrix[int(first[0])-1][int(first[1])-1] == 'O' or
                    matrix[int(first[0])-1][int(first[1])-1] == 'X'):
                    while (matrix[int(first[0])-1][int(first[1])-1] == 'O'
                        or matrix[int(first[0])-1][int(first[1])-1] == 'X'):
                        print('Это поле уже занято! Попробуйте снова!')
                        logs.write('Incorrect! This field is not empty!')
                        first = input().split(' ')
                        logs.write(f'{first}\n')
                matrix[int(first[0])-1][int(first[1])-1] = 'O'
                for i in range(0, len(matrix)):
                    for j in range(0, len(matrix[i])):
                        print(matrix[i][j], end=' ')
                        if j == 2:
                            logs.write(f'{matrix[i][j]}\n')
                        else:
                            logs.write(f'{matrix[i][j]} ')
                    print()
                turn = 1
            elif turn == 1:
                print('Ход второго игрока! --> X')
                logs.write('Second player turn! --> X\n')
                second = input().split(' ')
                logs.write(f'{second}\n')
                if (matrix[int(second[0])-1][int(second[1])-1] == 'O' or
                    matrix[int(second[0])-1][int(second[1])-1] == 'X'):
                    while (matrix[int(second[0])-1][int(second[1])-1] == 'O'
                        or matrix[int(second[0])-1][int(second[1])-1] == 'X'):
                        print('Это поле уже занято! Попробуйте снова!')
                        logs.write('Incorrect! This field is not empty!')
                        second = input().split(' ')
                        logs.write(f'{second}\n')
                matrix[int(second[0])-1][int(second[1])-1] = 'X'
                for i in range(0, len(matrix)):
                    for j in range(0, len(matrix[i])):
                        print(matrix[i][j], end=' ')
                        if j == 2:
                            logs.write(f'{matrix[i][j]}\n')
                        else:
                            logs.write(f'{matrix[i][j]} ')
                    print()
                turn = 0
logs.close()

# Второй вариант
# # 2(Кретиски-нолики)

# def input_position():
#     row = int(input('Введите номер строки(1-3): '))
#     while row < 1 or row > 3:
#         row = int(input('Введите номер строки(1-3): '))

#     columns = int(input('Введите номер стобца(1-3): '))
#     while columns < 1 or columns > 3:
#         columns = int(input('Введите номер строки(1-3): '))

#     return row, columns

# def check(array):
#     if array[0][0] == array[1][0] == array[2][0] != '*':
#         return f'Выиграл {array[0][0]}'
#     elif array[0][1] == array[1][1] == array[2][1] != '*':
#         return f'Выиграл {array[0][1]}'
#     elif array[0][2] == array[1][2] == array[2][2] != '*':
#         return f'Выиграл {array[0][2]}'
#     elif array[0][0] == array[0][1] == array[0][2] != '*':
#         return f'Выиграл {array[0][0]}'
#     elif array[1][0] == array[1][1] == array[1][2] != '*':
#         return f'Выиграл {array[1][0]}'
#     elif array[2][0] == array[2][1] == array[2][2] != '*':
#         return f'Выиграл {array[2][0]}'
#     elif array[0][0] == array[1][1] == array[2][2] != '*':
#         return f'Выиграл {array[0][0]}'
#     elif array[0][2] == array[1][1] == array[2][0] != '*':
#         return f'Выиграл {array[2][0]}'
#     return None

# array = [['*', '*', '*'], ['*', '*', '*'], ['*', '*', '*']]

# value = 'X'
# i = 0
# flag = True
# while i < 9 and flag:
#     print('\n'.join(['\t'.join(i) for i in array]))
#     if i % 2 == 0:
#         print('Сейчас ходят крестики')
#         value = 'X'
#     else:
#         print('Сейчас ходят нолики')
#         value = '0'
#     row, columns = input_position()

#     if array[row - 1][columns - 1] != '*':
#         print('Эта позиция занята')
#         row, columns = input_position()

#     array[row - 1][columns - 1] = value
#     result = check(array)
#     if result:
#         print(result)
#         flag = False

#     i += 1